Support SimpleFunction and SimpleExpression in order by expression.
This allows ordering by functions like:
ORDER BY GREATEST(table1.created_at, table2.created_at) ASC
or by arbitrary SQL snippets
orderBy(OrderByField.from(Expressions.just("1")).asc()) => ORDER BY 1 ASC
Original pull request #1348
This commit is contained in:
@@ -16,8 +16,11 @@
|
||||
package org.springframework.data.relational.core.sql.render;
|
||||
|
||||
import org.springframework.data.relational.core.sql.Column;
|
||||
import org.springframework.data.relational.core.sql.Expressions;
|
||||
import org.springframework.data.relational.core.sql.OrderByField;
|
||||
import org.springframework.data.relational.core.sql.SimpleFunction;
|
||||
import org.springframework.data.relational.core.sql.Visitable;
|
||||
import org.springframework.lang.Nullable;
|
||||
|
||||
/**
|
||||
* {@link PartRenderer} for {@link OrderByField}s.
|
||||
@@ -25,6 +28,7 @@ import org.springframework.data.relational.core.sql.Visitable;
|
||||
* @author Mark Paluch
|
||||
* @author Jens Schauder
|
||||
* @author Chirag Tailor
|
||||
* @author Koen Punt
|
||||
* @since 1.1
|
||||
*/
|
||||
class OrderByClauseVisitor extends TypedSubtreeVisitor<OrderByField> implements PartRenderer {
|
||||
@@ -32,6 +36,9 @@ class OrderByClauseVisitor extends TypedSubtreeVisitor<OrderByField> implements
|
||||
private final RenderContext context;
|
||||
|
||||
private final StringBuilder builder = new StringBuilder();
|
||||
|
||||
@Nullable private PartRenderer delegate;
|
||||
|
||||
private boolean first = true;
|
||||
|
||||
OrderByClauseVisitor(RenderContext context) {
|
||||
@@ -68,8 +75,32 @@ class OrderByClauseVisitor extends TypedSubtreeVisitor<OrderByField> implements
|
||||
return Delegation.leave();
|
||||
}
|
||||
|
||||
@Override
|
||||
Delegation enterNested(Visitable segment) {
|
||||
if (segment instanceof SimpleFunction) {
|
||||
delegate = new SimpleFunctionVisitor(context);
|
||||
return Delegation.delegateTo((SimpleFunctionVisitor)delegate);
|
||||
}
|
||||
|
||||
if (segment instanceof Expressions.SimpleExpression) {
|
||||
delegate = new ExpressionVisitor(context);
|
||||
return Delegation.delegateTo((ExpressionVisitor)delegate);
|
||||
}
|
||||
|
||||
return super.enterNested(segment);
|
||||
}
|
||||
|
||||
@Override
|
||||
Delegation leaveNested(Visitable segment) {
|
||||
if (delegate instanceof SimpleFunctionVisitor) {
|
||||
builder.append(delegate.getRenderedPart());
|
||||
delegate = null;
|
||||
}
|
||||
|
||||
if (delegate instanceof ExpressionVisitor) {
|
||||
builder.append(delegate.getRenderedPart());
|
||||
delegate = null;
|
||||
}
|
||||
|
||||
if (segment instanceof Column) {
|
||||
builder.append(NameRenderer.fullyQualifiedReference(context, (Column) segment));
|
||||
|
||||
@@ -19,16 +19,23 @@ import static org.assertj.core.api.Assertions.*;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.springframework.data.relational.core.sql.Column;
|
||||
import org.springframework.data.relational.core.sql.Expression;
|
||||
import org.springframework.data.relational.core.sql.Expressions;
|
||||
import org.springframework.data.relational.core.sql.OrderByField;
|
||||
import org.springframework.data.relational.core.sql.SQL;
|
||||
import org.springframework.data.relational.core.sql.Select;
|
||||
import org.springframework.data.relational.core.sql.SimpleFunction;
|
||||
import org.springframework.data.relational.core.sql.Table;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Unit tests for {@link OrderByClauseVisitor}.
|
||||
*
|
||||
* @author Mark Paluch
|
||||
* @author Jens Schauder
|
||||
* @author Koen Punt
|
||||
*/
|
||||
class OrderByClauseVisitorUnitTests {
|
||||
|
||||
@@ -88,4 +95,38 @@ class OrderByClauseVisitorUnitTests {
|
||||
assertThat(visitor.getRenderedPart().toString()).isEqualTo("emp.name ASC");
|
||||
}
|
||||
|
||||
@Test // GH-1348
|
||||
void shouldRenderOrderBySimpleFunction() {
|
||||
|
||||
Table employee = SQL.table("employee").as("emp");
|
||||
Column column = employee.column("name");
|
||||
List<Expression> columns = Arrays.asList(employee.column("id"), column);
|
||||
|
||||
SimpleFunction simpleFunction = SimpleFunction.create("GREATEST", columns);
|
||||
|
||||
Select select = Select.builder().select(column).from(employee)
|
||||
.orderBy(OrderByField.from(simpleFunction).asc(), OrderByField.from(column).asc()).build();
|
||||
|
||||
OrderByClauseVisitor visitor = new OrderByClauseVisitor(new SimpleRenderContext(NamingStrategies.asIs()));
|
||||
select.visit(visitor);
|
||||
|
||||
assertThat(visitor.getRenderedPart().toString()).isEqualTo("GREATEST(emp.id, emp.name) ASC, emp.name ASC");
|
||||
}
|
||||
|
||||
@Test // GH-1348
|
||||
void shouldRenderOrderBySimpleExpression() {
|
||||
|
||||
Table employee = SQL.table("employee").as("emp");
|
||||
Column column = employee.column("name");
|
||||
|
||||
Expression simpleExpression = Expressions.just("1");
|
||||
|
||||
Select select = Select.builder().select(column).from(employee).orderBy(OrderByField.from(simpleExpression).asc())
|
||||
.build();
|
||||
|
||||
OrderByClauseVisitor visitor = new OrderByClauseVisitor(new SimpleRenderContext(NamingStrategies.asIs()));
|
||||
select.visit(visitor);
|
||||
|
||||
assertThat(visitor.getRenderedPart().toString()).isEqualTo("1 ASC");
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user