Skip to content

Commit 616b725

Browse files
committed
Add test for not pushing down knn when there are non-pushable prefilters
1 parent ef12ee5 commit 616b725

File tree

1 file changed

+35
-0
lines changed

1 file changed

+35
-0
lines changed

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

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,7 @@
6161
import org.elasticsearch.xpack.esql.expression.function.fulltext.MatchOperator;
6262
import org.elasticsearch.xpack.esql.expression.function.fulltext.QueryString;
6363
import org.elasticsearch.xpack.esql.expression.function.vector.Knn;
64+
import org.elasticsearch.xpack.esql.expression.predicate.logical.And;
6465
import org.elasticsearch.xpack.esql.expression.predicate.logical.Or;
6566
import org.elasticsearch.xpack.esql.expression.predicate.operator.comparison.GreaterThan;
6667
import org.elasticsearch.xpack.esql.expression.predicate.operator.comparison.GreaterThanOrEqual;
@@ -1928,6 +1929,40 @@ public void testNotPushDownDisjunctionsToKnnPrefilter() {
19281929
assertEquals(expectedQuery.toString(), queryExec.query().toString());
19291930
}
19301931

1932+
public void testNotPushDownKnnWithNonPushablePrefilters() {
1933+
assumeTrue("knn must be enabled", EsqlCapabilities.Cap.KNN_FUNCTION_V3.isEnabled());
1934+
1935+
String query = """
1936+
from test
1937+
| where ((knn(dense_vector, [0, 1, 2], 10) AND integer > 10) and ((keyword == "test") or length(text) > 10))
1938+
""";
1939+
var plan = plannerOptimizer.plan(query, IS_SV_STATS, makeAnalyzer("mapping-all-types.json"));
1940+
1941+
var limit = as(plan, LimitExec.class);
1942+
var exchange = as(limit.child(), ExchangeExec.class);
1943+
var project = as(exchange.child(), ProjectExec.class);
1944+
var field = as(project.child(), FieldExtractExec.class);
1945+
var secondLimit = as(field.child(), LimitExec.class);
1946+
var filter = as(secondLimit.child(), FilterExec.class);
1947+
var and = as(filter.condition(), And.class);
1948+
var knn = as(and.left(), Knn.class);
1949+
assertEquals("(keyword == \"test\") or length(text) > 10", knn.filterExpressions().get(0).toString());
1950+
assertEquals("integer > 10", knn.filterExpressions().get(1).toString());
1951+
1952+
var fieldExtract = as(filter.child(), FieldExtractExec.class);
1953+
var queryExec = as(fieldExtract.child(), EsQueryExec.class);
1954+
1955+
// The query should only contain the pushable condition
1956+
QueryBuilder integerGtQuery = wrapWithSingleQuery(
1957+
query,
1958+
unscore(rangeQuery("integer").gt(10)),
1959+
"integer",
1960+
new Source(2, 47, "integer > 10")
1961+
);
1962+
1963+
assertEquals(integerGtQuery.toString(), queryExec.query().toString());
1964+
}
1965+
19311966
public void testMultipleKnnQueriesInPrefilters() {
19321967
assumeTrue("knn must be enabled", EsqlCapabilities.Cap.KNN_FUNCTION_V3.isEnabled());
19331968

0 commit comments

Comments
 (0)