-
Notifications
You must be signed in to change notification settings - Fork 25.8k
ESQL: allow sorting by expressions and not only regular fields #107158
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
6ec60c9
0beb8ff
491e7c6
09b2f0a
bf7d297
6306311
2b8affb
825b5fc
ad6a635
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,5 @@ | ||
| pr: 107158 | ||
| summary: "ESQL: allow sorting by expressions and not only regular fields" | ||
| area: ES|QL | ||
| type: feature | ||
| issues: [] |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -84,6 +84,7 @@ | |
| import static java.util.Arrays.asList; | ||
| import static java.util.Collections.singleton; | ||
| import static org.elasticsearch.xpack.esql.expression.NamedExpressions.mergeOutputExpressions; | ||
| import static org.elasticsearch.xpack.esql.optimizer.LogicalPlanOptimizer.SubstituteSurrogates.rawTemporaryName; | ||
| import static org.elasticsearch.xpack.ql.expression.Expressions.asAttributes; | ||
| import static org.elasticsearch.xpack.ql.optimizer.OptimizerRules.TransformDirection; | ||
| import static org.elasticsearch.xpack.ql.optimizer.OptimizerRules.TransformDirection.DOWN; | ||
|
|
@@ -125,7 +126,8 @@ protected static Batch<LogicalPlan> substitutions() { | |
| new ReplaceRegexMatch(), | ||
| new ReplaceAliasingEvalWithProject(), | ||
| new SkipQueryOnEmptyMappings(), | ||
| new SubstituteSpatialSurrogates() | ||
| new SubstituteSpatialSurrogates(), | ||
| new ReplaceOrderByExpressionWithEval() | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Thought: There's 4 places now that take expressions out of a plan node and turn them into evals:
I wonder if this should be consolidated into 2 opt. rules, or at least should use common helper methods. It's probably fine for now, though.
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I agree with you in that we should look into the possibility of refactoring this. But this should probably be done separately under the umbrella of "refactoring" or maybe "tech debt". |
||
| // new NormalizeAggregate(), - waits on https://github.com/elastic/elasticsearch/issues/100634 | ||
| ); | ||
| } | ||
|
|
@@ -321,6 +323,35 @@ protected SpatialRelatesFunction rule(SpatialRelatesFunction function) { | |
| } | ||
| } | ||
|
|
||
| static class ReplaceOrderByExpressionWithEval extends OptimizerRules.OptimizerRule<OrderBy> { | ||
| private static int counter = 0; | ||
|
|
||
| @Override | ||
| protected LogicalPlan rule(OrderBy orderBy) { | ||
| int size = orderBy.order().size(); | ||
| List<Alias> evals = new ArrayList<>(size); | ||
| List<Order> newOrders = new ArrayList<>(size); | ||
|
|
||
| for (int i = 0; i < size; i++) { | ||
| var order = orderBy.order().get(i); | ||
| if (order.child() instanceof Attribute == false) { | ||
| var name = rawTemporaryName("order_by", String.valueOf(i), String.valueOf(counter++)); | ||
| var eval = new Alias(order.child().source(), name, order.child()); | ||
| newOrders.add(order.replaceChildren(List.of(eval.toAttribute()))); | ||
| evals.add(eval); | ||
| } else { | ||
| newOrders.add(order); | ||
| } | ||
| } | ||
| if (evals.isEmpty()) { | ||
| return orderBy; | ||
| } else { | ||
| var newOrderBy = new OrderBy(orderBy.source(), new Eval(orderBy.source(), orderBy.child(), evals), newOrders); | ||
| return new Project(orderBy.source(), newOrderBy, orderBy.output()); | ||
| } | ||
| } | ||
| } | ||
|
|
||
| static class ConvertStringToByteRef extends OptimizerRules.OptimizerExpressionRule<Literal> { | ||
|
|
||
| ConvertStringToByteRef() { | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think a test with two subesequent sorts with expressions for their groupbys can't hurt, esp. if they use the same expressions:
This could have interesting interactions with var. shadowing and some pruning opt. rules.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nothing spectacular since both
sorts are merged and they are identified as the same, but I've added a test toLogicalPlanOptimizerTests.