|
61 | 61 | import org.elasticsearch.xpack.esql.expression.function.fulltext.MatchOperator; |
62 | 62 | import org.elasticsearch.xpack.esql.expression.function.fulltext.QueryString; |
63 | 63 | import org.elasticsearch.xpack.esql.expression.function.vector.Knn; |
| 64 | +import org.elasticsearch.xpack.esql.expression.predicate.logical.And; |
64 | 65 | import org.elasticsearch.xpack.esql.expression.predicate.logical.Or; |
65 | 66 | import org.elasticsearch.xpack.esql.expression.predicate.operator.comparison.GreaterThan; |
66 | 67 | import org.elasticsearch.xpack.esql.expression.predicate.operator.comparison.GreaterThanOrEqual; |
@@ -1928,6 +1929,40 @@ public void testNotPushDownDisjunctionsToKnnPrefilter() { |
1928 | 1929 | assertEquals(expectedQuery.toString(), queryExec.query().toString()); |
1929 | 1930 | } |
1930 | 1931 |
|
| 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 | + |
1931 | 1966 | public void testMultipleKnnQueriesInPrefilters() { |
1932 | 1967 | assumeTrue("knn must be enabled", EsqlCapabilities.Cap.KNN_FUNCTION_V3.isEnabled()); |
1933 | 1968 |
|
|
0 commit comments