diff --git a/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/core/convert/QueryMapper.java b/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/core/convert/QueryMapper.java index 1d3ce3095e..8f4b98b4da 100644 --- a/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/core/convert/QueryMapper.java +++ b/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/core/convert/QueryMapper.java @@ -89,23 +89,29 @@ public List getMappedSort(Table table, Sort sort, @Nullable Relati SqlSort.validate(order); - OrderByField simpleOrderByField = createSimpleOrderByField(table, entity, order); - OrderByField orderBy = simpleOrderByField.withNullHandling(order.getNullHandling()); - mappedOrder.add(order.isAscending() ? orderBy.asc() : orderBy.desc()); + if (order instanceof SqlSort.SqlOrder sqlOrder && sqlOrder.isUnsafe()) { + mappedOrder.add(OrderByField.from(Expressions.just(sqlOrder.getProperty()))); + continue; + } + + Field field = createField(entity, order); + + OrderByField orderByField = OrderByField.from( // + table.column(field.getMappedColumnName()), // + order.isAscending() ? Sort.Direction.ASC : Sort.Direction.DESC, // + order.getNullHandling(), // + order.isIgnoreCase() // + ); + + mappedOrder.add(orderByField); } return mappedOrder; } - private OrderByField createSimpleOrderByField(Table table, RelationalPersistentEntity entity, Sort.Order order) { - - if (order instanceof SqlSort.SqlOrder sqlOrder && sqlOrder.isUnsafe()) { - return OrderByField.from(Expressions.just(sqlOrder.getProperty())); - } - - Field field = createPropertyField(entity, SqlIdentifier.unquoted(order.getProperty()), this.mappingContext); - return OrderByField.from(table.column(field.getMappedColumnName())); + private Field createField(RelationalPersistentEntity entity, Sort.Order order) { + return createPropertyField(entity, SqlIdentifier.unquoted(order.getProperty()), this.mappingContext); } /** diff --git a/spring-data-relational/src/main/java/org/springframework/data/relational/core/dialect/OrderByNullPrecedence.java b/spring-data-relational/src/main/java/org/springframework/data/relational/core/dialect/OrderByNullPrecedence.java index 768a6916df..2d37afcce0 100644 --- a/spring-data-relational/src/main/java/org/springframework/data/relational/core/dialect/OrderByNullPrecedence.java +++ b/spring-data-relational/src/main/java/org/springframework/data/relational/core/dialect/OrderByNullPrecedence.java @@ -59,14 +59,11 @@ class SqlStandardOrderByNullPrecedence implements OrderByNullPrecedence { @Override public String evaluate(Sort.NullHandling nullHandling) { - - switch (nullHandling) { - case NULLS_FIRST: return NULLS_FIRST; - case NULLS_LAST: return NULLS_LAST; - case NATIVE: return UNSPECIFIED; - default: - throw new UnsupportedOperationException("Sort.NullHandling " + nullHandling + " not supported"); - } + return switch (nullHandling) { + case NULLS_FIRST -> NULLS_FIRST; + case NULLS_LAST -> NULLS_LAST; + case NATIVE -> UNSPECIFIED; + }; } } } diff --git a/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/OrderByField.java b/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/OrderByField.java index 2044366440..427bad1135 100644 --- a/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/OrderByField.java +++ b/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/OrderByField.java @@ -26,6 +26,7 @@ * * @author Mark Paluch * @author Milan Milanov + * @author Mikhail Polivakha * @since 1.1 */ public class OrderByField extends AbstractSegment { @@ -33,8 +34,9 @@ public class OrderByField extends AbstractSegment { private final Expression expression; private final @Nullable Sort.Direction direction; private final Sort.NullHandling nullHandling; + private final boolean caseInsensitive; - private OrderByField(Expression expression, @Nullable Direction direction, NullHandling nullHandling) { + private OrderByField(Expression expression, @Nullable Direction direction, NullHandling nullHandling, boolean caseInsensitive) { super(expression); Assert.notNull(expression, "Order by expression must not be null"); @@ -42,6 +44,7 @@ private OrderByField(Expression expression, @Nullable Direction direction, NullH this.expression = expression; this.direction = direction; + this.caseInsensitive = caseInsensitive; this.nullHandling = nullHandling; } @@ -52,38 +55,51 @@ private OrderByField(Expression expression, @Nullable Direction direction, NullH * @return the {@link OrderByField}. */ public static OrderByField from(Expression expression) { - return new OrderByField(expression, null, NullHandling.NATIVE); + return new OrderByField(expression, null, NullHandling.NATIVE, false); } /** * Creates a new {@link OrderByField} from an {@link Expression} applying a given ordering. * * @param expression must not be {@literal null}. - * @param direction order direction + * @param direction order direction. * @return the {@link OrderByField}. */ public static OrderByField from(Expression expression, Direction direction) { - return new OrderByField(expression, direction, NullHandling.NATIVE); + return new OrderByField(expression, direction, NullHandling.NATIVE, false); } /** - * Creates a new {@link OrderByField} from a the current one using ascending sorting. + * Creates a new {@link OrderByField} from an {@link Expression} applying a given ordering and {@link NullHandling}. + * + * @param expression must not be {@literal null}. + * @param direction order direction. + * @param nullHandling the null handling strategy. + * @param caseInsensitive whether the ordering is case-insensitive. + * @return the {@link OrderByField}. + */ + public static OrderByField from(Expression expression, Direction direction, NullHandling nullHandling, boolean caseInsensitive) { + return new OrderByField(expression, direction, nullHandling, caseInsensitive); + } + + /** + * Creates a new {@link OrderByField} from a current one using ascending sorting. * * @return the new {@link OrderByField} with ascending sorting. * @see #desc() */ public OrderByField asc() { - return new OrderByField(expression, Direction.ASC, nullHandling); + return new OrderByField(expression, Direction.ASC, nullHandling, caseInsensitive); } /** - * Creates a new {@link OrderByField} from a the current one using descending sorting. + * Creates a new {@link OrderByField} from a current one using descending sorting. * * @return the new {@link OrderByField} with descending sorting. * @see #asc() */ public OrderByField desc() { - return new OrderByField(expression, Direction.DESC, nullHandling); + return new OrderByField(expression, Direction.DESC, nullHandling, caseInsensitive); } /** @@ -93,7 +109,7 @@ public OrderByField desc() { * @return the new {@link OrderByField} with {@link NullHandling} applied. */ public OrderByField withNullHandling(NullHandling nullHandling) { - return new OrderByField(expression, direction, nullHandling); + return new OrderByField(expression, direction, nullHandling, caseInsensitive); } public Expression getExpression() { diff --git a/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/render/NameRenderer.java b/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/render/NameRenderer.java index 66bdb808c6..ebe651744f 100644 --- a/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/render/NameRenderer.java +++ b/spring-data-relational/src/main/java/org/springframework/data/relational/core/sql/render/NameRenderer.java @@ -91,8 +91,13 @@ static CharSequence fullyQualifiedReference(RenderContext context, Column column return render(context, namingStrategy.getReferenceName(column)); } - return render(context, SqlIdentifier.from(namingStrategy.getReferenceName(column.getTable()), - namingStrategy.getReferenceName(column))); + return render( // + context, // + SqlIdentifier.from( // + namingStrategy.getReferenceName(column.getTable()), // + namingStrategy.getReferenceName(column) // + ) + ); } /**