@@ -1401,6 +1401,84 @@ public void testKnnOptionsPushDown() {
14011401 assertEquals (expectedQuery .toString (), planStr .get ());
14021402 }
14031403
1404+ public void testKnnUsesLimitForK () {
1405+ assumeTrue ("dense_vector capability not available" , EsqlCapabilities .Cap .DENSE_VECTOR_FIELD_TYPE .isEnabled ());
1406+ assumeTrue ("knn capability not available" , EsqlCapabilities .Cap .KNN_FUNCTION_V4 .isEnabled ());
1407+
1408+ String query = """
1409+ from test
1410+ | where KNN(dense_vector, [0.1, 0.2, 0.3])
1411+ | limit 10
1412+ """ ;
1413+ var analyzer = makeAnalyzer ("mapping-all-types.json" );
1414+ var plan = plannerOptimizer .plan (query , IS_SV_STATS , analyzer );
1415+
1416+ AtomicReference <String > planStr = new AtomicReference <>();
1417+ plan .forEachDown (EsQueryExec .class , result -> planStr .set (result .query ().toString ()));
1418+
1419+ var expectedQuery = new KnnVectorQueryBuilder (
1420+ "dense_vector" ,
1421+ new float [] { 0.1f , 0.2f , 0.3f },
1422+ 10 ,
1423+ null ,
1424+ null ,
1425+ null
1426+ );
1427+ assertEquals (expectedQuery .toString (), planStr .get ());
1428+ }
1429+
1430+ public void testKnnKAndMinCandidatesLowerK () {
1431+ assumeTrue ("dense_vector capability not available" , EsqlCapabilities .Cap .DENSE_VECTOR_FIELD_TYPE .isEnabled ());
1432+ assumeTrue ("knn capability not available" , EsqlCapabilities .Cap .KNN_FUNCTION_V4 .isEnabled ());
1433+
1434+ String query = """
1435+ from test
1436+ | where KNN(dense_vector, [0.1, 0.2, 0.3], {"min_candidates": 50})
1437+ | limit 10
1438+ """ ;
1439+ var analyzer = makeAnalyzer ("mapping-all-types.json" );
1440+ var plan = plannerOptimizer .plan (query , IS_SV_STATS , analyzer );
1441+
1442+ AtomicReference <String > planStr = new AtomicReference <>();
1443+ plan .forEachDown (EsQueryExec .class , result -> planStr .set (result .query ().toString ()));
1444+
1445+ var expectedQuery = new KnnVectorQueryBuilder (
1446+ "dense_vector" ,
1447+ new float [] { 0.1f , 0.2f , 0.3f },
1448+ 50 ,
1449+ 50 ,
1450+ null ,
1451+ null
1452+ );
1453+ assertEquals (expectedQuery .toString (), planStr .get ());
1454+ }
1455+
1456+ public void testKnnKAndMinCandidatesHigherK () {
1457+ assumeTrue ("dense_vector capability not available" , EsqlCapabilities .Cap .DENSE_VECTOR_FIELD_TYPE .isEnabled ());
1458+ assumeTrue ("knn capability not available" , EsqlCapabilities .Cap .KNN_FUNCTION_V4 .isEnabled ());
1459+
1460+ String query = """
1461+ from test
1462+ | where KNN(dense_vector, [0.1, 0.2, 0.3], {"min_candidates": 10})
1463+ | limit 50
1464+ """ ;
1465+ var analyzer = makeAnalyzer ("mapping-all-types.json" );
1466+ var plan = plannerOptimizer .plan (query , IS_SV_STATS , analyzer );
1467+
1468+ AtomicReference <String > planStr = new AtomicReference <>();
1469+ plan .forEachDown (EsQueryExec .class , result -> planStr .set (result .query ().toString ()));
1470+
1471+ var expectedQuery = new KnnVectorQueryBuilder (
1472+ "dense_vector" ,
1473+ new float [] { 0.1f , 0.2f , 0.3f },
1474+ 50 ,
1475+ 50 ,
1476+ null ,
1477+ null
1478+ );
1479+ assertEquals (expectedQuery .toString (), planStr .get ());
1480+ }
1481+
14041482 /**
14051483 * Expecting
14061484 * LimitExec[1000[INTEGER]]
0 commit comments