Skip to content

Commit a6562f8

Browse files
committed
Include push down limits past sorting
1 parent ac0d231 commit a6562f8

File tree

2 files changed

+51
-0
lines changed

2 files changed

+51
-0
lines changed

x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/optimizer/rules/logical/PushDownAndCombineLimits.java

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
import org.elasticsearch.xpack.esql.plan.logical.Limit;
1818
import org.elasticsearch.xpack.esql.plan.logical.LogicalPlan;
1919
import org.elasticsearch.xpack.esql.plan.logical.MvExpand;
20+
import org.elasticsearch.xpack.esql.plan.logical.OrderBy;
2021
import org.elasticsearch.xpack.esql.plan.logical.Project;
2122
import org.elasticsearch.xpack.esql.plan.logical.RegexExtract;
2223
import org.elasticsearch.xpack.esql.plan.logical.UnaryPlan;
@@ -73,6 +74,17 @@ public LogicalPlan rule(Limit limit, LogicalOptimizerContext ctx) {
7374
return limit.replaceChild(filter.with(limitAppliedExpression));
7475
}
7576
}
77+
else if (unary instanceof OrderBy orderBy) {
78+
return limit.replaceChild(orderBy.transformDown(lp -> {
79+
if (lp instanceof Filter filter) {
80+
Expression limitAppliedExpression = limitFilterExpressions(filter.condition(), limit, ctx);
81+
if (limitAppliedExpression.equals(filter.condition()) == false) {
82+
return filter.with(limitAppliedExpression);
83+
}
84+
}
85+
return lp;
86+
}));
87+
}
7688
} else if (limit.child() instanceof Join join && join.config().type() == JoinTypes.LEFT) {
7789
// Left joins increase the number of rows if any join key has multiple matches from the right hand side.
7890
// Therefore, we cannot simply push down the limit - but we can add another limit before the join.

x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/optimizer/LocalPhysicalPlanOptimizerTests.java

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2073,6 +2073,45 @@ public void testKnnWithoutExplicitLimit() {
20732073
assertThat(knnQuery.k(), is(config.resultTruncationDefaultSize()));
20742074
}
20752075

2076+
public void testKnnWithoutExplicitLimitSorted() {
2077+
var query = """
2078+
from test metadata _score
2079+
| where knn(dense_vector, [0, 1, 2])
2080+
| sort _score desc
2081+
""";
2082+
var analyzer = makeAnalyzer("mapping-all-types.json");
2083+
var plan = plannerOptimizer.plan(query, IS_SV_STATS, analyzer);
2084+
var topNExec = as(plan, TopNExec.class);
2085+
assertThat(topNExec.limit().fold(FoldContext.small()), is(config.resultTruncationDefaultSize()));
2086+
var exchangeExec = as(topNExec.child(), ExchangeExec.class);
2087+
var projectExec = as(exchangeExec.child(), ProjectExec.class);
2088+
var fieldExtractExec = as(projectExec.child(), FieldExtractExec.class);
2089+
var queryExec = as(fieldExtractExec.child(), EsQueryExec.class);
2090+
assertThat(queryExec.limit().fold(FoldContext.small()), is(config.resultTruncationDefaultSize()));
2091+
var knnQuery = as(queryExec.query(), KnnVectorQueryBuilder.class);
2092+
assertThat(knnQuery.k(), is(config.resultTruncationDefaultSize()));
2093+
}
2094+
2095+
public void testKnnWithoExplicitLimitSorted() {
2096+
var query = """
2097+
from test metadata _score
2098+
| where knn(dense_vector, [0, 1, 2])
2099+
| sort _score desc
2100+
| limit 10
2101+
""";
2102+
var analyzer = makeAnalyzer("mapping-all-types.json");
2103+
var plan = plannerOptimizer.plan(query, IS_SV_STATS, analyzer);
2104+
var topNExec = as(plan, TopNExec.class);
2105+
assertThat(topNExec.limit().fold(FoldContext.small()), is(10));
2106+
var exchangeExec = as(topNExec.child(), ExchangeExec.class);
2107+
var projectExec = as(exchangeExec.child(), ProjectExec.class);
2108+
var fieldExtractExec = as(projectExec.child(), FieldExtractExec.class);
2109+
var queryExec = as(fieldExtractExec.child(), EsQueryExec.class);
2110+
assertThat(queryExec.limit().fold(FoldContext.small()), is(10));
2111+
var knnQuery = as(queryExec.query(), KnnVectorQueryBuilder.class);
2112+
assertThat(knnQuery.k(), is(10));
2113+
}
2114+
20762115
public void testKnnWithExplicitLimit() {
20772116
var query = """
20782117
from test

0 commit comments

Comments
 (0)