diff --git a/x-pack/plugin/esql/qa/server/multi-clusters/src/javaRestTest/java/org/elasticsearch/xpack/esql/ccq/MultiClusterSpecIT.java b/x-pack/plugin/esql/qa/server/multi-clusters/src/javaRestTest/java/org/elasticsearch/xpack/esql/ccq/MultiClusterSpecIT.java index 9e1ed7417efe6..4b90aa1a69c80 100644 --- a/x-pack/plugin/esql/qa/server/multi-clusters/src/javaRestTest/java/org/elasticsearch/xpack/esql/ccq/MultiClusterSpecIT.java +++ b/x-pack/plugin/esql/qa/server/multi-clusters/src/javaRestTest/java/org/elasticsearch/xpack/esql/ccq/MultiClusterSpecIT.java @@ -51,7 +51,7 @@ import static org.elasticsearch.xpack.esql.action.EsqlCapabilities.Cap.ENABLE_LOOKUP_JOIN_ON_REMOTE; import static org.elasticsearch.xpack.esql.action.EsqlCapabilities.Cap.FORK_V9; import static org.elasticsearch.xpack.esql.action.EsqlCapabilities.Cap.INLINESTATS; -import static org.elasticsearch.xpack.esql.action.EsqlCapabilities.Cap.INLINESTATS_V10; +import static org.elasticsearch.xpack.esql.action.EsqlCapabilities.Cap.INLINESTATS_V11; import static org.elasticsearch.xpack.esql.action.EsqlCapabilities.Cap.JOIN_LOOKUP_V12; import static org.elasticsearch.xpack.esql.action.EsqlCapabilities.Cap.JOIN_PLANNING_V1; import static org.elasticsearch.xpack.esql.action.EsqlCapabilities.Cap.METADATA_FIELDS_REMOTE_TEST; @@ -137,7 +137,7 @@ protected void shouldSkipTest(String testName) throws IOException { assumeTrue("Test " + testName + " is skipped on " + oldVersion, isEnabled(testName, instructions, oldVersion)); assumeFalse("INLINESTATS not yet supported in CCS", testCase.requiredCapabilities.contains(INLINESTATS.capabilityName())); assumeFalse("INLINESTATS not yet supported in CCS", testCase.requiredCapabilities.contains(JOIN_PLANNING_V1.capabilityName())); - assumeFalse("INLINESTATS not yet supported in CCS", testCase.requiredCapabilities.contains(INLINESTATS_V10.capabilityName())); + assumeFalse("INLINESTATS not yet supported in CCS", testCase.requiredCapabilities.contains(INLINESTATS_V11.capabilityName())); if (testCase.requiredCapabilities.contains(JOIN_LOOKUP_V12.capabilityName())) { assumeTrue( "LOOKUP JOIN not yet supported in CCS", diff --git a/x-pack/plugin/esql/qa/testFixtures/src/main/resources/inlinestats.csv-spec b/x-pack/plugin/esql/qa/testFixtures/src/main/resources/inlinestats.csv-spec index bc7732cae4c5f..f226ed5fd36ae 100644 --- a/x-pack/plugin/esql/qa/testFixtures/src/main/resources/inlinestats.csv-spec +++ b/x-pack/plugin/esql/qa/testFixtures/src/main/resources/inlinestats.csv-spec @@ -1,5 +1,5 @@ allFieldsReturned -required_capability: inlinestats_v10 +required_capability: inlinestats_v11 FROM hosts METADATA _index | INLINESTATS c = COUNT(*) BY host_group @@ -12,7 +12,7 @@ eth0 |epsilon gw instance|epsilon |[fe80::cae2:65ff:fece:feb9, ; maxOfInt -required_capability: inlinestats_v10 +required_capability: inlinestats_v11 // tag::max-languages[] FROM employees | KEEP emp_no, languages @@ -34,7 +34,7 @@ emp_no:integer | languages:integer | max_lang:integer ; maxOfIntByKeyword -required_capability: inlinestats_v10 +required_capability: inlinestats_v11 FROM employees | KEEP emp_no, languages, gender @@ -51,8 +51,37 @@ emp_no:integer | languages:integer | max_lang:integer | gender:keyword 10014 | 5 | 5 | null ; +// check that the `LIMIT 1` isn't pushed into the INLINESTATS's source +maxOfIntByKeywordLimit1Aggd +required_capability: inlinestats_v11 + +FROM employees +| KEEP emp_no, languages, gender +// | SORT emp_no +| INLINESTATS max_lang = MAX(languages) BY gender +| LIMIT 1 +| STATS v = VALUES(max_lang) +; + +v:integer +5 +; + +simpleAvg +required_capability: inlinestats_v11 + +FROM employees +| INLINESTATS a = AVG(salary) +| LIMIT 2 +| KEEP a; + +a:double +48248.55 +48248.55 +; + maxOfLongByKeyword -required_capability: inlinestats_v10 +required_capability: inlinestats_v11 FROM employees | KEEP emp_no, avg_worked_seconds, gender @@ -67,7 +96,7 @@ emp_no:integer | avg_worked_seconds:long | max_avg_worked_seconds:long | gender: ; maxOfLong -required_capability: inlinestats_v10 +required_capability: inlinestats_v11 FROM employees | KEEP emp_no, avg_worked_seconds, gender @@ -80,7 +109,7 @@ emp_no:integer | avg_worked_seconds:long | gender:keyword | max_avg_worked_secon ; maxOfLongByCalculatedKeyword -required_capability: inlinestats_v10 +required_capability: inlinestats_v11 // tag::longest-tenured-by-first[] FROM employees @@ -103,7 +132,7 @@ emp_no:integer | avg_worked_seconds:long | last_name:keyword | max_avg_worked_se ; maxOfLongByCalculatedNamedKeyword -required_capability: inlinestats_v10 +required_capability: inlinestats_v11 FROM employees | KEEP emp_no, avg_worked_seconds, last_name @@ -122,7 +151,7 @@ emp_no:integer | avg_worked_seconds:long | last_name:keyword | max_avg_worked_se ; maxOfLongByCalculatedDroppedKeyword -required_capability: inlinestats_v10 +required_capability: inlinestats_v11 FROM employees | INLINESTATS max_avg_worked_seconds = MAX(avg_worked_seconds) BY l = SUBSTRING(last_name, 0, 1) @@ -141,7 +170,7 @@ emp_no:integer | avg_worked_seconds:long | last_name:keyword | max_avg_worked_se ; maxOfLongByEvaledKeyword -required_capability: inlinestats_v10 +required_capability: inlinestats_v11 FROM employees | EVAL l = SUBSTRING(last_name, 0, 1) @@ -161,7 +190,7 @@ emp_no:integer | avg_worked_seconds:long | max_avg_worked_seconds:long | l:keywo ; maxOfLongByInt -required_capability: inlinestats_v10 +required_capability: inlinestats_v11 FROM employees | KEEP emp_no, avg_worked_seconds, languages @@ -179,7 +208,7 @@ emp_no:integer | avg_worked_seconds:long | max_avg_worked_seconds:long | languag ; maxOfLongByIntDouble -required_capability: inlinestats_v10 +required_capability: inlinestats_v11 FROM employees | KEEP emp_no, avg_worked_seconds, languages, height @@ -197,7 +226,7 @@ emp_no:integer | avg_worked_seconds:long | max_avg_worked_seconds:long | languag ; two -required_capability: inlinestats_v10 +required_capability: inlinestats_v11 FROM employees | KEEP emp_no, languages, avg_worked_seconds, gender @@ -221,7 +250,7 @@ emp_no:integer |avg_worked_seconds:long|avg_avg_worked_seconds:double|languages: ; three -required_capability: inlinestats_v10 +required_capability: inlinestats_v11 FROM employees | KEEP emp_no, languages, avg_worked_seconds, gender @@ -247,8 +276,9 @@ emp_no:integer |avg_worked_seconds:long|avg_avg_worked_seconds:double|languages: ; // TODO: INLINESTATS unit test needed for this one -pushDownSort_To_LeftSideOnly -required_capability: inlinestats_v10 +// https://github.com/elastic/elasticsearch/issues/113727 +pushDownSort_To_LeftSideOnly-Ignore +required_capability: inlinestats_v11 from employees | sort emp_no @@ -266,7 +296,7 @@ from employees ; byMultivaluedSimple -required_capability: inlinestats_v10 +required_capability: inlinestats_v11 // tag::mv-group[] FROM airports @@ -284,7 +314,7 @@ abbrev:keyword | type:keyword | scalerank:integer | min_scalerank:integer ; byMultivaluedMvExpand -required_capability: inlinestats_v10 +required_capability: inlinestats_v11 // tag::mv-expand[] FROM airports @@ -304,7 +334,7 @@ GWL |9 |4 |military ; byMvExpand -required_capability: inlinestats_v10 +required_capability: inlinestats_v11 // tag::extreme-airports[] FROM airports @@ -333,7 +363,7 @@ FROM airports ; mvMinMvExpand -required_capability: inlinestats_v10 +required_capability: inlinestats_v11 FROM airports | EVAL original_type = type @@ -356,7 +386,7 @@ ZAR |Zaria |POINT (7.7 11.0667) |Nigeria |POINT ( ; afterStats -required_capability: inlinestats_v10 +required_capability: inlinestats_v11 FROM airports | STATS count=COUNT(*) BY country @@ -379,7 +409,7 @@ count:long | country:keyword | avg:double ; afterWhere -required_capability: inlinestats_v10 +required_capability: inlinestats_v11 FROM airports | WHERE country != "United States" @@ -397,7 +427,7 @@ abbrev:keyword | country:keyword | count:long ; afterLookup -required_capability: inlinestats_v10 +required_capability: inlinestats_v11 required_capability: join_lookup_v12 FROM airports @@ -421,7 +451,7 @@ ZNZ |4 |German ; afterEnrich -required_capability: inlinestats_v10 +required_capability: inlinestats_v11 required_capability: enrich_load FROM airports @@ -442,7 +472,7 @@ abbrev:keyword | city:keyword | "COUNT(*)":long | region:text ; beforeStats -required_capability: inlinestats_v10 +required_capability: inlinestats_v11 FROM airports | EVAL lat = ST_Y(location) @@ -455,7 +485,7 @@ northern:long | southern:long ; beforeKeepSort -required_capability: inlinestats_v10 +required_capability: inlinestats_v11 FROM employees | INLINESTATS max_salary = MAX(salary) by languages @@ -470,7 +500,7 @@ emp_no:integer | languages:integer | max_salary:integer ; beforeKeepWhere -required_capability: inlinestats_v10 +required_capability: inlinestats_v11 FROM employees | INLINESTATS max_salary = MAX(salary) by languages @@ -483,7 +513,7 @@ emp_no:integer | languages:integer | max_salary:integer ; beforeEnrich -required_capability: inlinestats_v10 +required_capability: inlinestats_v11 required_capability: enrich_load FROM airports @@ -502,7 +532,7 @@ ACA |Acapulco de Juárez|385 |major |Acapulco de ; beforeAndAfterEnrich -required_capability: inlinestats_v10 +required_capability: inlinestats_v11 required_capability: enrich_load FROM airports @@ -525,7 +555,7 @@ ALL |Albenga |499 |mid |1 ; shadowing -required_capability: inlinestats_v10 +required_capability: inlinestats_v11 ROW left = "left", client_ip = "172.21.0.5", env = "env", right = "right" | INLINESTATS env = VALUES(right) BY client_ip @@ -536,7 +566,7 @@ left | right | right | 172.21.0.5 ; shadowingMulti -required_capability: inlinestats_v10 +required_capability: inlinestats_v11 ROW left = "left", airport = "Zurich Airport ZRH", city = "Zürich", middle = "middle", region = "North-East Switzerland", right = "right" | INLINESTATS airport=VALUES(left), region=VALUES(left), city_boundary=VALUES(left) BY city @@ -547,7 +577,7 @@ left | middle | right | left | left ; shadowingSelf -required_capability: inlinestats_v10 +required_capability: inlinestats_v11 ROW city = "Raleigh" | INLINESTATS city = COUNT(city) @@ -558,7 +588,7 @@ city:long ; shadowingSelfBySelf -required_capability: inlinestats_v10 +required_capability: inlinestats_v11 ROW city = "Raleigh" | INLINESTATS city = COUNT(city) BY city @@ -570,7 +600,7 @@ Raleigh ; shadowingInternal -required_capability: inlinestats_v10 +required_capability: inlinestats_v11 ROW city = "Zürich" | INLINESTATS x = VALUES(city), x = VALUES(city) @@ -582,7 +612,7 @@ Zürich | Zürich ; multiInlinestatsWithRow -required_capability: inlinestats_v10 +required_capability: inlinestats_v11 row x = 1 | inlinestats x = max(x) + min(x) @@ -596,7 +626,7 @@ row x = 1 ; ignoreUnusedEvaledValue_AndInlineStats -required_capability: inlinestats_v10 +required_capability: inlinestats_v11 ROW x = 1 | INLINESTATS max(x) @@ -609,7 +639,7 @@ x:integer ; ignoreUnusedEvaledValue_AndInlineStats2 -required_capability: inlinestats_v10 +required_capability: inlinestats_v11 ROW x = 1, z = 2 | INLINESTATS max(x) @@ -622,7 +652,7 @@ x:integer | z:integer ; ignoreUnusedEvaledValue_AndInlineStats3 -required_capability: inlinestats_v10 +required_capability: inlinestats_v11 from employees | inlinestats max(salary) @@ -637,7 +667,7 @@ from employees ; ignoreUnusedEvaledValue_AndInlineStats4 -required_capability: inlinestats_v10 +required_capability: inlinestats_v11 from employees | inlinestats max(salary), m = min(salary) by gender @@ -652,7 +682,7 @@ emp_no:integer ; ignoreUnusedEvaledValue_AndInlineStats5 -required_capability: inlinestats_v10 +required_capability: inlinestats_v11 from employees | inlinestats max(salary), m = min(salary) by gender @@ -667,7 +697,7 @@ emp_no:integer ; shadowEntireInlinestats -required_capability: inlinestats_v10 +required_capability: inlinestats_v11 FROM employees | INLINESTATS x = avg(salary), y = min(salary) BY emp_no @@ -682,7 +712,7 @@ x:integer |y:integer |emp_no:integer ; byConstant -required_capability: inlinestats_v10 +required_capability: inlinestats_v11 FROM employees | KEEP emp_no, languages @@ -701,7 +731,7 @@ emp_no:integer | languages:integer | max_lang:integer | y:integer ; aggConstant -required_capability: inlinestats_v10 +required_capability: inlinestats_v11 FROM employees | KEEP emp_no @@ -719,7 +749,7 @@ one:integer | emp_no:integer ; percentile -required_capability: inlinestats_v10 +required_capability: inlinestats_v11 FROM employees | KEEP emp_no, salary @@ -738,7 +768,7 @@ emp_no:integer | salary:integer | ninety_fifth_salary:double ; byTwoCalculated -required_capability: inlinestats_v10 +required_capability: inlinestats_v11 FROM airports | WHERE abbrev IS NOT NULL @@ -758,7 +788,7 @@ abbrev:keyword | scalerank:integer | location:geo_point byTwoCalculatedSecondOverwrites required_capability: stats_alias_collision_warnings -required_capability: inlinestats_v10 +required_capability: inlinestats_v11 FROM airports | WHERE abbrev IS NOT NULL @@ -779,7 +809,7 @@ abbrev:keyword | scalerank:integer | location:geo_point byTwoCalculatedSecondOverwritesReferencingFirst required_capability: stats_alias_collision_warnings -required_capability: inlinestats_v10 +required_capability: inlinestats_v11 FROM airports | WHERE abbrev IS NOT NULL @@ -802,7 +832,7 @@ abbrev:keyword | scalerank:integer | location:geo_point groupShadowsAgg required_capability: stats_alias_collision_warnings -required_capability: inlinestats_v10 +required_capability: inlinestats_v11 FROM airports | WHERE abbrev IS NOT NULL @@ -822,7 +852,7 @@ abbrev:keyword | scalerank:integer | location:geo_point ; groupShadowsField -required_capability: inlinestats_v10 +required_capability: inlinestats_v11 FROM employees | KEEP emp_no, salary, hire_date @@ -841,7 +871,7 @@ emp_no:integer | salary:integer | avg_salary:double | hire_date:datetime ; groupByExpression_And_ExistentField -required_capability: inlinestats_v10 +required_capability: inlinestats_v11 FROM employees | KEEP emp_no, languages, gender | EVAL x = "ABC" @@ -859,7 +889,7 @@ emp_no:integer | languages:integer | x:keyword | max_lang:integer | y:keyword | ; groupByRenamedColumn -required_capability: inlinestats_v10 +required_capability: inlinestats_v11 FROM employees | KEEP emp_no, languages, gender | INLINESTATS max_lang = MAX(languages) BY y = gender @@ -877,7 +907,7 @@ emp_no:integer | languages:integer | gender:keyword | max_lang:integer | y:keywo ; groupByMultipleRenamedColumns_AndOneExpression_Last -required_capability: inlinestats_v10 +required_capability: inlinestats_v11 FROM employees | KEEP emp_no, languages, gender, first_name @@ -900,7 +930,7 @@ emp_no:integer | languages:integer | gender:keyword|first_name:keyword|max_lang: ; groupByMultipleRenamedColumns_AndTwoExpressions -required_capability: inlinestats_v10 +required_capability: inlinestats_v11 FROM employees | KEEP emp_no, languages, gender, first_name @@ -923,7 +953,7 @@ emp_no:integer | languages:integer | gender:keyword|first_name:keyword|max_lang: ; groupByMultipleRenamedColumns_AndMultipleRenames -required_capability: inlinestats_v10 +required_capability: inlinestats_v11 FROM employees | KEEP emp_no, languages, gender, first_name @@ -947,7 +977,7 @@ emp_no:integer | languages:integer | gender:keyword| f:keyword |max_lang: ; groupByMultipleRenamedColumns_AndSameNameExpressionGroupingOverride -required_capability: inlinestats_v10 +required_capability: inlinestats_v11 FROM employees | KEEP emp_no, languages, gender, first_name @@ -971,7 +1001,7 @@ emp_no:integer | languages:integer | gender:keyword|max_lang:integer| y:keyword ; twoAggregatesGroupedBy_AField_And_AnExpression -required_capability: inlinestats_v10 +required_capability: inlinestats_v11 FROM employees | KEEP emp_no, languages, gender, last_name @@ -993,7 +1023,7 @@ emp_no:integer |languages:integer|last_name:keyword|max_lang:integer|min_lang:in ; groupByMultipleRenamedColumns_InversedOrder -required_capability: inlinestats_v10 +required_capability: inlinestats_v11 FROM employees | KEEP emp_no, languages, still_hired, gender @@ -1011,7 +1041,7 @@ emp_no:integer |languages:integer|still_hired:boolean| gender:keyword|max_lang:i ; groupByMultipleRenamedColumns_InversedOrder_ComplexEval -required_capability: inlinestats_v10 +required_capability: inlinestats_v11 FROM employees | KEEP emp_no, languages, still_hired, gender @@ -1030,7 +1060,7 @@ emp_no:integer |languages:integer|still_hired:boolean| gender:keyword|multilingu ; groupByMultipleRenamedColumns_AndComplexEval -required_capability: inlinestats_v10 +required_capability: inlinestats_v11 FROM employees | KEEP emp_no, languages, still_hired, gender @@ -1049,7 +1079,7 @@ emp_no:integer |languages:integer|still_hired:boolean| gender:keyword|multilingu ; groupByMultipleRenamedColumns_AndConstantValue -required_capability: inlinestats_v10 +required_capability: inlinestats_v11 FROM employees | KEEP emp_no, languages, gender, first_name @@ -1073,7 +1103,7 @@ emp_no:integer |languages:integer|gender:keyword |first_name:keyword | x:keyw ; groupByRenamedExpression -required_capability: inlinestats_v10 +required_capability: inlinestats_v11 FROM employees | KEEP emp_no, languages, gender, last_name @@ -1095,7 +1125,7 @@ emp_no:integer |languages:integer|last_name:keyword|max_lang:integer|min_lang:in ; doubleFilterOnLeftAndRight_InlineStats_Sides -required_capability: inlinestats_v10 +required_capability: inlinestats_v11 FROM employees | INLINESTATS max_salary = MAX(salary), min_salary = MIN(salary) by languages @@ -1116,7 +1146,7 @@ emp_no:integer |languages:integer|salary:integer |max_salary:integer|min_salary: ; filterOnInlineStatsAggs -required_capability: inlinestats_v10 +required_capability: inlinestats_v11 FROM employees | INLINESTATS max_salary = MAX(salary), min_salary = MIN(salary) by languages @@ -1135,7 +1165,7 @@ emp_no:integer |languages:integer|salary:integer |max_salary:integer|min_salary: ; filterOnInlineStatsAggsValues_And_Groupings -required_capability: inlinestats_v10 +required_capability: inlinestats_v11 FROM employees | INLINESTATS max_salary = MAX(salary), min_salary = MIN(salary) by languages @@ -1154,7 +1184,7 @@ emp_no:integer |languages:integer|salary:integer |max_salary:integer|min_salary: ; inlineStatsOverrideEVALed_FieldWithSameName -required_capability: inlinestats_v10 +required_capability: inlinestats_v11 FROM hosts METADATA _index | EVAL x = ip1 @@ -1168,7 +1198,7 @@ beta k8s server |beta |127.0.0.1 |hosts |127.0.0.2|2 ; doubleShadowing -required_capability: inlinestats_v10 +required_capability: inlinestats_v11 FROM employees | INLINESTATS salary = min(salary) BY gender @@ -1187,7 +1217,7 @@ salary:integer |gender:keyword ; doubleShadowing_WithIntertwinedFilters -required_capability: inlinestats_v10 +required_capability: inlinestats_v11 FROM employees | WHERE salary > 30000 @@ -1212,7 +1242,7 @@ salary:integer |gender:keyword ; shadowingAggregateByNextGrouping -required_capability: inlinestats_v10 +required_capability: inlinestats_v11 FROM employees | KEEP gender, languages, emp_no, salary @@ -1229,7 +1259,7 @@ emp_no:integer |salary:integer |languages:integer|avg(salary):double|gender:long ; doubleShadowingWithEval -required_capability: inlinestats_v10 +required_capability: inlinestats_v11 from employees | eval salary = salary/100 @@ -1249,7 +1279,7 @@ salary:integer|gender:keyword ; doubleShadowingWithDoubleStats -required_capability: inlinestats_v10 +required_capability: inlinestats_v11 from employees | stats salary=min(salary) by gender @@ -1266,7 +1296,7 @@ M |25324 ; renamingGroupingWithItself -required_capability: inlinestats_v10 +required_capability: inlinestats_v11 FROM employees | EVAL x = gender @@ -1285,7 +1315,7 @@ salary:integer |x:keyword|gender:keyword |min_sl:integer |emp_no:integer ; overridingGroupings -required_capability: inlinestats_v10 +required_capability: inlinestats_v11 FROM employees | INLINESTATS min_sl = MIN(salary) BY x = gender, x = languages @@ -1304,7 +1334,7 @@ salary:integer |x:integer |gender:keyword |min_sl:integer |emp_no:integer ; overridingExpressionGroupings -required_capability: inlinestats_v10 +required_capability: inlinestats_v11 FROM employees | INLINESTATS min_sl = MIN(salary) BY x = TO_LOWER(gender), x = CONCAT(gender, gender) @@ -1323,7 +1353,7 @@ salary:integer |x:keyword |gender:keyword |min_sl:integer |emp_no:integer ; reusingEvalExpressions_UsedInGroupings -required_capability: inlinestats_v10 +required_capability: inlinestats_v11 FROM employees | KEEP salary, gender, emp_no @@ -1342,7 +1372,7 @@ salary:integer |gender:keyword |emp_no:integer |min_sl:integer | x:keyword ; statsBeforeInlinestatsWithTopAndBucket1 -required_capability: inlinestats_v10 +required_capability: inlinestats_v11 FROM books | STATS avg_rating = AVG(ratings) BY decade = BUCKET(year, 10) @@ -1362,7 +1392,7 @@ avg_rating:double | decade:double | decades:double ; statsBeforeInlinestatsWithTopAndBucket2 -required_capability: inlinestats_v10 +required_capability: inlinestats_v11 FROM sample_data | STATS total_duration = SUM(event_duration) BY day = BUCKET(@timestamp, 1 HOUR) @@ -1377,7 +1407,7 @@ total_duration:long | day:date | days:date ; evalBeforeDoubleInlinestats1 -required_capability: inlinestats_v10 +required_capability: inlinestats_v11 FROM employees | EVAL salaryK = salary/1000 @@ -1397,7 +1427,7 @@ emp_no:integer |still_hired:boolean|count:long ; evalBeforeDoubleInlinestats2 -required_capability: inlinestats_v10 +required_capability: inlinestats_v11 FROM employees | EVAL jobs = MV_COUNT(job_positions) @@ -1417,7 +1447,7 @@ emp_no:integer |jobs:integer|count:long|min:integer ; evalBeforeInlinestatsAndKeepAfter1 -required_capability: inlinestats_v10 +required_capability: inlinestats_v11 FROM employees | WHERE still_hired == false @@ -1437,7 +1467,7 @@ emp_no:integer |still_hired:boolean|totalK:long|count:long ; evalBeforeInlinestatsAndKeepAfter2 -required_capability: inlinestats_v10 +required_capability: inlinestats_v11 FROM employees | EVAL salaryK = salary/1000 @@ -1457,7 +1487,7 @@ emp_no:integer |still_hired:boolean|total:long|count:long ; evalBeforeInlinestatsAndKeepAfter3 -required_capability: inlinestats_v10 +required_capability: inlinestats_v11 FROM employees | EVAL salaryK = salary/1000 @@ -1476,7 +1506,7 @@ emp_no:integer |still_hired:boolean|total:long ; evalBeforeInlinestatsAndKeepAfter4 -required_capability: inlinestats_v10 +required_capability: inlinestats_v11 FROM employees | EVAL salaryK = salary/1000 @@ -1495,7 +1525,7 @@ emp_no:integer |still_hired:boolean|count:long ; evalBeforeInlinestatsAndKeepAfter5 -required_capability: inlinestats_v10 +required_capability: inlinestats_v11 ROW salary = 12300, emp_no = 5, gender = "F" | EVAL salaryK = salary/1000 @@ -1511,7 +1541,7 @@ emp_no:integer /////////////////////////// doubleFilterOnInlineStats -required_capability: inlinestats_v10 +required_capability: inlinestats_v11 from employees | keep salary, gender @@ -1537,7 +1567,7 @@ salary:integer | max1:integer | max2:integer | max3:integer | gender:keyword ; inlinestatsWithFiltering -required_capability: inlinestats_v10 +required_capability: inlinestats_v11 from employees | inlinestats max = max(salary), max_f = max(salary) where salary < 50000, max_a = max(salary) where salary > 100, min = min(salary), min_f = min(salary) where salary > 50000, min_a = min(salary) where salary > 100 @@ -1553,7 +1583,7 @@ max:integer |max_f:integer |max_a:integer | min:integer | min_f:integer | min_a: ; inlinestatsWithEverythingFiltered -required_capability: inlinestats_v10 +required_capability: inlinestats_v11 from employees | inlinestats max = max(salary), max_a = max(salary) where salary < 100, min = min(salary), min_a = min(salary) where salary > 99999 @@ -1571,7 +1601,7 @@ max:integer |max_a:integer|min:integer | min_a:integer | emp_no:integer|salary:i ; inlinestatsWithNullFilter -required_capability: inlinestats_v10 +required_capability: inlinestats_v11 from employees | inlinestats max = max(salary), max_a = max(salary) where null, min = min(salary), min_a = min(salary) where to_string(null) == "abc" @@ -1587,7 +1617,7 @@ max:integer |max_a:integer|min:integer | min_a:integer | emp_no:integer ; inlinestatsWithAllFiltersFalse -required_capability: inlinestats_v10 +required_capability: inlinestats_v11 from employees | inlinestats max = max(height.float) where false, min = min(height.float) where to_string(null) == "abc", @@ -1605,7 +1635,7 @@ emp_no:integer|salary:integer| max:double |min:double |count:long |count_distinc ; inlinestatsWithAllFiltersFalse_GroupByOneField -required_capability: inlinestats_v10 +required_capability: inlinestats_v11 from employees | inlinestats max = max(height.float) where false, min = min(height.float) where to_string(null) == "abc", @@ -1625,7 +1655,7 @@ from employees ; inlinestatsWithAllFiltersFalse_GroupByTwoFields -required_capability: inlinestats_v10 +required_capability: inlinestats_v11 from employees | inlinestats max = max(height.float) where false, min = min(height.float) where to_string(null) == "abc", @@ -1645,7 +1675,7 @@ from employees ; prunedInlinestatsFollowedByInlinestats_GroupByOneFieldEach_DifferentFields -required_capability: inlinestats_v10 +required_capability: inlinestats_v11 from employees | eval my_length = length(concat(first_name, null)) | inlinestats count = count(my_length) where false, @@ -1663,7 +1693,7 @@ from employees ; prunedInlinestatsFollowedByInlinestats_GroupByOneFieldEach_SameFields -required_capability: inlinestats_v10 +required_capability: inlinestats_v11 from employees | eval my_length = length(concat(first_name, null)) | inlinestats count = count(my_length) where false, @@ -1682,7 +1712,7 @@ from employees prunedInlinestatsFollowedByInlinestats_GroupByOneFieldOnSecondInlinestats-Ignore // values doesn't end up as null -required_capability: inlinestats_v10 +required_capability: inlinestats_v11 from employees | eval my_length = length(concat(first_name, null)) | inlinestats count = count(my_length) where false, @@ -1700,7 +1730,7 @@ from employees ; partial_PrunedInlinestatsFollowedByInlinestats_GroupByOneFieldOnFirstInlinestats -required_capability: inlinestats_v10 +required_capability: inlinestats_v11 from employees | eval my_length = length(concat(first_name, null)) | inlinestats count = count(is_rehired) where true, @@ -1726,7 +1756,7 @@ from employees partial_PrunedInlinestatsFollowedByInlinestats_GroupByOneFieldOnFirstInlinestats2 -required_capability: inlinestats_v10 +required_capability: inlinestats_v11 from employees | eval my_length = length(concat(first_name, null)) | inlinestats count = count(is_rehired) where true, @@ -1753,7 +1783,7 @@ from employees inlinestatsWithExpressionsAllFiltersFalse -required_capability: inlinestats_v10 +required_capability: inlinestats_v11 from employees | keep height.f*, emp_no | sort emp_no desc @@ -1771,7 +1801,7 @@ from employees ; inlinestatsWithFalseFilterAndGroup -required_capability: inlinestats_v10 +required_capability: inlinestats_v11 from employees | inlinestats max = max(height.float + 1) where null, count = count(height.float) + 2 where false @@ -1789,7 +1819,7 @@ from employees ; inlinestatsWithFalseFiltersAndGroups -required_capability: inlinestats_v10 +required_capability: inlinestats_v11 from employees | eval my_length = length(concat(first_name, null)) | inlinestats count_distinct = count_distinct(height.float + 1) where null, @@ -1815,7 +1845,7 @@ from employees ; inlinestatsWithFalseFiltersAndGroups_DropEvaledValue -required_capability: inlinestats_v10 +required_capability: inlinestats_v11 from employees | eval my_length = length(concat(first_name, null)) | inlinestats count_distinct = count_distinct(height.float + 1) where null, @@ -1842,7 +1872,7 @@ from employees ; inlinestatsWithMixedFiltersAndGroup -required_capability: inlinestats_v10 +required_capability: inlinestats_v11 from employees | eval my_length = length(concat(first_name, null)) | inlinestats count = count(my_length) where false, @@ -1862,7 +1892,7 @@ null |[0, 0, 0, 0] |[Berni, Chirstian, Amabile, Berni, Bojan, Chir prunedInlinestatsFollowedByinlinestats-Ignore // values doesn't end up as null -required_capability: inlinestats_v10 +required_capability: inlinestats_v11 from employees | eval my_length = length(concat(first_name, null)) | inlinestats count = count(my_length) where false, @@ -1885,7 +1915,7 @@ inlinestatsWithFalseFiltersFromRow // null |2 // null |3 // null |4 -required_capability: inlinestats_v10 +required_capability: inlinestats_v11 row x = null, a = 1, b = [2,3,4] | inlinestats c=max(a) where x by b @@ -1896,7 +1926,7 @@ null |1 |null |[2, 3, 4] ; inlinestatsWithBasicExpressionFiltered -required_capability: inlinestats_v10 +required_capability: inlinestats_v11 from employees | inlinestats max = max(salary), max_f = max(salary) where salary < 50000, min = min(salary), min_f = min(salary) where salary > 50000, @@ -1912,7 +1942,7 @@ from employees ; inlinestatsWithExpressionOverFilters -required_capability: inlinestats_v10 +required_capability: inlinestats_v11 from employees | inlinestats max = max(salary), max_f = max(salary) where salary < 50000, min = min(salary), min_f = min(salary) where salary > 50000, @@ -1931,7 +1961,7 @@ from employees inlinestatsWithExpressionOfExpressionsOverFilters -required_capability: inlinestats_v10 +required_capability: inlinestats_v11 from employees | inlinestats max = max(salary + 1), max_f = max(salary + 2) where salary < 50000, min = min(salary - 1), min_f = min(salary - 2) where salary > 50000, @@ -1949,7 +1979,7 @@ from employees ; inlinestatsWithSubstitutedExpressionOverFilters -required_capability: inlinestats_v10 +required_capability: inlinestats_v11 from employees | inlinestats sum = sum(salary), s_l = sum(salary) where salary < 50000, s_u = sum(salary) where salary > 50000, count = count(salary), c_l = count(salary) where salary < 50000, c_u = count(salary) where salary > 50000, @@ -1967,7 +1997,7 @@ from employees inlinestatsWithFilterAndGroupBy -required_capability: inlinestats_v10 +required_capability: inlinestats_v11 from employees | keep height, gender, is_rehired, emp_no | inlinestats m = max(height), m_f = max(height + 1) where gender == "M" OR is_rehired is null BY gender, is_rehired @@ -1991,7 +2021,7 @@ from employees inlinestatsWithFilterOnGroupBy -required_capability: inlinestats_v10 +required_capability: inlinestats_v11 from employees | inlinestats m_f = max(height) where gender == "M" BY gender | sort emp_no @@ -2013,7 +2043,7 @@ null |null ; inlinestatsWithGroupByLiteral -required_capability: inlinestats_v10 +required_capability: inlinestats_v11 from employees | inlinestats m = max(languages) by salary = 2 | sort salary @@ -2029,7 +2059,7 @@ from employees inlinestatsWithFilterOnSameColumn -required_capability: inlinestats_v10 +required_capability: inlinestats_v11 from employees | inlinestats m = max(languages), m_f = max(languages) where salary > 50000 by salary = 2 | sort salary @@ -2044,7 +2074,7 @@ from employees ; inlinestatsWithFilteringAndGrouping -required_capability: inlinestats_v10 +required_capability: inlinestats_v11 from employees | inlinestats c = count(), c_f = count(languages) where l > 1, m_f = max(height) where salary > 50000 @@ -2069,7 +2099,7 @@ from employees multiinlinestatsWithFiltering -required_capability: inlinestats_v10 +required_capability: inlinestats_v11 from employees | inlinestats c = count(), c_f = count(languages) where l > 1, m_f = max(height) where salary > 50000 @@ -2096,7 +2126,7 @@ from employees simpleCountOnFieldWithFilteringAndNoGrouping -required_capability: inlinestats_v10 +required_capability: inlinestats_v11 from employees | inlinestats c1 = count(emp_no) where emp_no < 10042 | keep emp_no, c1 @@ -2111,7 +2141,7 @@ emp_no:integer | c1:long ; simpleCountOnFieldWithFilteringOnDifferentFieldAndNoGrouping -required_capability: inlinestats_v10 +required_capability: inlinestats_v11 from employees | inlinestats c1 = count(hire_date) where emp_no < 10042 | keep emp_no, c1 @@ -2126,7 +2156,7 @@ emp_no:integer | c1:long ; simpleCountOnStarWithFilteringAndNoGrouping -required_capability: inlinestats_v10 +required_capability: inlinestats_v11 from employees | inlinestats c1 = count(*) where emp_no < 10042 | keep emp_no, c1 @@ -2141,7 +2171,7 @@ emp_no:integer | c1:long ; simpleCountWithFilteringAndNoGroupingOnFieldWithNulls -required_capability: inlinestats_v10 +required_capability: inlinestats_v11 from employees | inlinestats c1 = count(birth_date) where emp_no <= 10050 | keep emp_no, c1 @@ -2157,7 +2187,7 @@ emp_no:integer | c1:long simpleCountWithFilteringAndNoGroupingOnFieldWithMultivalues -required_capability: inlinestats_v10 +required_capability: inlinestats_v11 from employees | inlinestats c1 = count(job_positions) where emp_no <= 10003 | keep emp_no, c1 @@ -2172,7 +2202,7 @@ from employees ; commonFilterExtractionWithAliasing -required_capability: inlinestats_v10 +required_capability: inlinestats_v11 from employees | eval eno = emp_no | drop emp_no @@ -2190,7 +2220,7 @@ from employees ; commonFilterExtractionWithAliasAndOriginal -required_capability: inlinestats_v10 +required_capability: inlinestats_v11 from employees | eval eno = emp_no | inlinestats min_sal = min(salary) where eno <= 10010, @@ -2208,7 +2238,7 @@ from employees commonFilterExtractionWithAliasAndOriginalNeedingNormalization -required_capability: inlinestats_v10 +required_capability: inlinestats_v11 from employees | eval eno = emp_no | inlinestats min_sal = min(salary) where eno <= 10010, @@ -2228,7 +2258,7 @@ from employees ; commonFilterExtractionWithAliasAndOriginalNeedingNormalizationAndSimplification -required_capability: inlinestats_v10 +required_capability: inlinestats_v11 from employees | eval eno = emp_no | inlinestats min_sal = min(salary) where eno <= 10010, @@ -2248,7 +2278,7 @@ from employees ; filterIsAlwaysTrue -required_capability: inlinestats_v10 +required_capability: inlinestats_v11 FROM employees | inlinestats max = max(salary) WHERE salary > 0 | keep max, salary, emp_no @@ -2263,7 +2293,7 @@ FROM employees ; filterIsAlwaysFalse -required_capability: inlinestats_v10 +required_capability: inlinestats_v11 FROM employees | inlinestats max = max(salary) WHERE first_name == "" | sort emp_no @@ -2286,7 +2316,7 @@ null |Duangkaew filterSometimesMatches -required_capability: inlinestats_v10 +required_capability: inlinestats_v11 FROM employees | inlinestats max = max(salary) WHERE first_name IS NULL | sort emp_no @@ -2308,7 +2338,7 @@ FROM employees ; groupingFilterIsAlwaysTrue -required_capability: inlinestats_v10 +required_capability: inlinestats_v11 FROM employees | MV_EXPAND job_positions | inlinestats max = max(salary) WHERE salary > 0 BY job_positions = SUBSTRING(job_positions, 1, 1) @@ -2326,7 +2356,7 @@ FROM employees groupingFilterIsAlwaysFalse -required_capability: inlinestats_v10 +required_capability: inlinestats_v11 FROM employees | MV_EXPAND job_positions | inlinestats max = max(salary) WHERE first_name == "" BY job_positions = SUBSTRING(job_positions, 1, 1) @@ -2344,7 +2374,7 @@ null |48942 |Patricio |A |10012 groupingFilterSometimesMatches -required_capability: inlinestats_v10 +required_capability: inlinestats_v11 FROM employees | MV_EXPAND job_positions | inlinestats max = max(salary) WHERE first_name IS NULL BY job_positions = SUBSTRING(job_positions, 1, 1) @@ -2361,7 +2391,7 @@ FROM employees ; groupingByOrdinalsFilterIsAlwaysTrue -required_capability: inlinestats_v10 +required_capability: inlinestats_v11 FROM employees | inlinestats max = max(salary) WHERE salary > 0 BY job_positions | SORT job_positions ASC, salary DESC @@ -2377,7 +2407,7 @@ FROM employees ; groupingByOrdinalsFilterIsAlwaysFalse -required_capability: inlinestats_v10 +required_capability: inlinestats_v11 FROM employees | inlinestats max = max(salary) WHERE first_name == "" BY job_positions @@ -2394,7 +2424,7 @@ Mary |31120 |10011 |[Architect, Reporting Analyst, S ; groupingByOrdinalsFilterSometimesMatches -required_capability: inlinestats_v10 +required_capability: inlinestats_v11 FROM employees | keep salary, first_name, job_positions, emp_no @@ -2411,7 +2441,7 @@ FROM employees ; stdDevFilter -required_capability: inlinestats_v10 +required_capability: inlinestats_v11 FROM employees | inlinestats greater_than = STD_DEV(salary_change) WHERE languages > 3 , less_than = STD_DEV(salary_change) WHERE languages <= 3 @@ -2436,7 +2466,7 @@ FROM employees ; twoConsecutiveInlinestatsWithFalseFilters -required_capability: inlinestats_v10 +required_capability: inlinestats_v11 from employees | keep emp_no | sort emp_no diff --git a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/action/EsqlCapabilities.java b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/action/EsqlCapabilities.java index c3c4121b095f4..600e92ae70bac 100644 --- a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/action/EsqlCapabilities.java +++ b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/action/EsqlCapabilities.java @@ -972,7 +972,7 @@ public enum Cap { * Fixes a series of issues with inlinestats which had an incomplete implementation after lookup and inlinestats * were refactored. */ - INLINESTATS_V10(EsqlPlugin.INLINESTATS_FEATURE_FLAG), + INLINESTATS_V11(EsqlPlugin.INLINESTATS_FEATURE_FLAG), /** * Support partial_results diff --git a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/optimizer/rules/logical/PushDownAndCombineLimits.java b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/optimizer/rules/logical/PushDownAndCombineLimits.java index 7bad50abd46de..834f360f7ff05 100644 --- a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/optimizer/rules/logical/PushDownAndCombineLimits.java +++ b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/optimizer/rules/logical/PushDownAndCombineLimits.java @@ -18,6 +18,7 @@ import org.elasticsearch.xpack.esql.plan.logical.RegexExtract; import org.elasticsearch.xpack.esql.plan.logical.UnaryPlan; import org.elasticsearch.xpack.esql.plan.logical.inference.InferencePlan; +import org.elasticsearch.xpack.esql.plan.logical.join.InlineJoin; import org.elasticsearch.xpack.esql.plan.logical.join.Join; import org.elasticsearch.xpack.esql.plan.logical.join.JoinTypes; @@ -64,9 +65,11 @@ public LogicalPlan rule(Limit limit, LogicalOptimizerContext ctx) { } } } - } else if (limit.child() instanceof Join join && join.config().type() == JoinTypes.LEFT) { + } else if (limit.child() instanceof Join join && join.config().type() == JoinTypes.LEFT && join instanceof InlineJoin == false) { // Left joins increase the number of rows if any join key has multiple matches from the right hand side. // Therefore, we cannot simply push down the limit - but we can add another limit before the join. + // The InlineJoin is currently excluded, as its right-hand side uses as data source a StubRelation that points to the entire + // left-hand side, so adding a limit in there would lead to the right-hand side work on incomplete data. // To avoid repeating this infinitely, we have to set duplicated = true. return duplicateLimitAsFirstGrandchild(limit); } diff --git a/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/analysis/AnalyzerTests.java b/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/analysis/AnalyzerTests.java index 52ea22dee1d6b..4367851c8caae 100644 --- a/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/analysis/AnalyzerTests.java +++ b/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/analysis/AnalyzerTests.java @@ -4268,7 +4268,7 @@ public void testGroupingOverridesInStats() { } public void testGroupingOverridesInInlinestats() { - assumeTrue("INLINESTATS required", EsqlCapabilities.Cap.INLINESTATS_V10.isEnabled()); + assumeTrue("INLINESTATS required", EsqlCapabilities.Cap.INLINESTATS_V11.isEnabled()); verifyUnsupported(""" from test | inlinestats MIN(salary) BY x = languages, x = x + 1 diff --git a/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/optimizer/LogicalPlanOptimizerTests.java b/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/optimizer/LogicalPlanOptimizerTests.java index c8a64f779ab4a..67bb40214cb7b 100644 --- a/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/optimizer/LogicalPlanOptimizerTests.java +++ b/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/optimizer/LogicalPlanOptimizerTests.java @@ -1044,10 +1044,11 @@ public void testPushdownLimitsPastLeftJoin() { var optimizedPlan = rule.apply(limit, logicalOptimizerCtx); - assertEquals( - new Limit(limit.source(), limit.limit(), join.replaceChildren(limit.replaceChild(join.left()), join.right()), true), - optimizedPlan - ); + var expectedPlan = join instanceof InlineJoin + ? new Limit(limit.source(), limit.limit(), join, false) + : new Limit(limit.source(), limit.limit(), join.replaceChildren(limit.replaceChild(join.left()), join.right()), true); + + assertEquals(expectedPlan, optimizedPlan); var optimizedTwice = rule.apply(optimizedPlan, logicalOptimizerCtx); // We mustn't create the limit after the JOIN multiple times when the rule is applied multiple times, that'd lead to infinite loops. @@ -5714,17 +5715,14 @@ public void testReplaceSortByExpressionsWithStats() { as(aggregate.child(), EsRelation.class); } - /** - *
{@code
-     * Limit[1000[INTEGER],true]
+    /*
+     * Limit[1000[INTEGER],false]
      * \_InlineJoin[LEFT,[emp_no % 2{r}#6],[emp_no % 2{r}#6],[emp_no % 2{r}#6]]
      *   |_Eval[[emp_no{f}#7 % 2[INTEGER] AS emp_no % 2#6]]
-     *   | \_Limit[1000[INTEGER],false]  <-- TODO: this needs to go
-     *   |   \_EsRelation[test][_meta_field{f}#13, emp_no{f}#7, first_name{f}#8, ge..]
+     *   | \_EsRelation[test][_meta_field{f}#13, emp_no{f}#7, first_name{f}#8, ge..]
      *   \_Aggregate[[emp_no % 2{r}#6],[COUNT(salary{f}#12,true[BOOLEAN]) AS c#4, emp_no % 2{r}#6]]
      *     \_StubRelation[[_meta_field{f}#13, emp_no{f}#7, first_name{f}#8, gender{f}#9, hire_date{f}#14, job{f}#15, job.raw{f}#16, lang
      *          uages{f}#10, last_name{f}#11, long_noidx{f}#17, salary{f}#12, emp_no % 2{r}#6]]
-     * }
*/ public void testInlinestatsNestedExpressionsInGroups() { var query = """ @@ -5739,7 +5737,7 @@ public void testInlinestatsNestedExpressionsInGroups() { var inline = as(limit.child(), InlineJoin.class); var eval = as(inline.left(), Eval.class); assertThat(Expressions.names(eval.fields()), is(List.of("emp_no % 2"))); - limit = asLimit(eval.child(), 1000, false); + var relation = as(eval.child(), EsRelation.class); var agg = as(inline.right(), Aggregate.class); var groupings = agg.groupings(); var ref = as(groupings.get(0), ReferenceAttribute.class); @@ -5863,10 +5861,9 @@ public void testDoubleInlinestatsGetsPrunedEntirely() { /* * Project[[emp_no{f}#15 AS x#11, a{r}#7, emp_no{f}#15]] - * \_Limit[1[INTEGER],true] + * \_Limit[1[INTEGER],false] * \_InlineJoin[LEFT,[emp_no{f}#15],[emp_no{f}#15],[emp_no{r}#15]] - * |_Limit[1[INTEGER],false] <-- TODO: this needs to go - * | \_EsRelation[test][_meta_field{f}#21, emp_no{f}#15, first_name{f}#16, ..] + * |_EsRelation[test][_meta_field{f}#21, emp_no{f}#15, first_name{f}#16, ..] * \_Aggregate[[emp_no{f}#15],[COUNTDISTINCT(languages{f}#18,true[BOOLEAN]) AS a#7, emp_no{f}#15]] * \_StubRelation[[_meta_field{f}#21, emp_no{f}#15, first_name{f}#16, gender{f}#17, hire_date{f}#22, job{f}#23, job.raw{f}#24, l * anguages{f}#18, last_name{f}#19, long_noidx{f}#25, salary{f}#20]] @@ -5886,13 +5883,11 @@ public void testInlinestatsGetsPrunedPartially() { var project = as(plan, Project.class); assertThat(Expressions.names(project.projections()), is(List.of("x", "a", "emp_no"))); - var upperLimit = asLimit(project.child(), 1, true); + var upperLimit = asLimit(project.child(), 1, false); var inlineJoin = as(upperLimit.child(), InlineJoin.class); assertThat(Expressions.names(inlineJoin.config().matchFields()), is(List.of("emp_no"))); // Left - var limit = as(inlineJoin.left(), Limit.class); // TODO: this needs to go - assertThat(limit.limit().fold(FoldContext.small()), equalTo(1)); - var relation = as(limit.child(), EsRelation.class); + var relation = as(inlineJoin.left(), EsRelation.class); // Right var agg = as(inlineJoin.right(), Aggregate.class); assertMap(Expressions.names(agg.output()), is(List.of("a", "emp_no"))); @@ -5917,13 +5912,11 @@ public void testTripleInlinestatsGetsPrunedPartially() { var project = as(plan, Project.class); assertThat(Expressions.names(project.projections()), is(List.of("x", "a", "emp_no"))); - var upperLimit = asLimit(project.child(), 1, true); + var upperLimit = asLimit(project.child(), 1, false); var inlineJoin = as(upperLimit.child(), InlineJoin.class); assertThat(Expressions.names(inlineJoin.config().matchFields()), is(List.of("emp_no"))); // Left - var limit = as(inlineJoin.left(), Limit.class); - assertThat(limit.limit().fold(FoldContext.small()), equalTo(1)); - var relation = as(limit.child(), EsRelation.class); + var relation = as(inlineJoin.left(), EsRelation.class); // Right var agg = as(inlineJoin.right(), Aggregate.class); assertMap(Expressions.names(agg.output()), is(List.of("a", "emp_no"))); @@ -6134,12 +6127,11 @@ public void testInlineStatsWithAggGetsPrunedEntirely() { * \_InlineJoin[LEFT,[],[],[]] * |_Project[[avg{r}#1053, decades{r}#1049, idecades{r}#1056]] * | \_Eval[[$$SUM$avg$0{r$}#1073 / $$COUNT$avg$1{r$}#1074 AS avg#1053, decades{r}#1049 / 2[INTEGER] AS idecades#1056]] - * | \_Limit[1000[INTEGER],false] - * | \_Aggregate[[decades{r}#1049],[SUM(salary{f}#1072,true[BOOLEAN],compensated[KEYWORD]) AS $$SUM$avg$0#1073, + * | \_Aggregate[[decades{r}#1049],[SUM(salary{f}#1072,true[BOOLEAN],compensated[KEYWORD]) AS $$SUM$avg$0#1073, * COUNT(salary{f}#1072,true[BOOLEAN]) AS $$COUNT$avg$1#1074, decades{r}#1049]] - * | \_Eval[[DATEDIFF(years[KEYWORD],birth_date{f}#1071,1755626308505[DATETIME]) AS age#1043, age{r}#1043 / 10[INTEGER] AS + * | \_Eval[[DATEDIFF(years[KEYWORD],birth_date{f}#1071,1755626308505[DATETIME]) AS age#1043, age{r}#1043 / 10[INTEGER] AS * decades#1046, decades{r}#1046 * 10[INTEGER] AS decades#1049]] - * | \_EsRelation[employees][birth_date{f}#1071, salary{f}#1072] + * | \_EsRelation[employees][birth_date{f}#1071, salary{f}#1072] * \_Project[[avgavg{r}#1063]] * \_Eval[[$$SUM$avgavg$0{r$}#1077 / $$COUNT$avgavg$1{r$}#1078 AS avgavg#1063]] * \_Aggregate[[],[SUM(avg{r}#1053,true[BOOLEAN],compensated[KEYWORD]) AS $$SUM$avgavg$0#1077, @@ -6165,15 +6157,14 @@ public void testInlineStatsWithAggAndInlineStatsGetsPruned() { var project = as(plan, EsqlProject.class); assertThat(Expressions.names(project.projections()), is(List.of("avg", "decades", "avgavg"))); - var limit = asLimit(project.child(), 1000, true); + var limit = asLimit(project.child(), 1000, false); var inlineJoin = as(limit.child(), InlineJoin.class); // Left branch: Project with avg, decades, idecades var leftProject = as(inlineJoin.left(), Project.class); assertThat(Expressions.names(leftProject.projections()), is(List.of("avg", "decades", "idecades"))); var leftEval = as(leftProject.child(), Eval.class); - var leftLimit = asLimit(leftEval.child(), 1000, false); - var leftAggregate = as(leftLimit.child(), Aggregate.class); + var leftAggregate = as(leftEval.child(), Aggregate.class); assertThat(Expressions.names(leftAggregate.output()), is(List.of("$$SUM$avg$0", "$$COUNT$avg$1", "decades"))); var leftEval2 = as(leftAggregate.child(), Eval.class); var leftRelation = as(leftEval2.child(), EsRelation.class); @@ -6232,10 +6223,9 @@ public void testInlinestatsWithLookupJoin() { /* * EsqlProject[[avg{r}#4, emp_no{f}#9, first_name{f}#10]] - * \_Limit[10[INTEGER],true] + * \_Limit[10[INTEGER],false] * \_InlineJoin[LEFT,[emp_no{f}#9],[emp_no{f}#9],[emp_no{r}#9]] - * |_Limit[10[INTEGER],false] <-- TODO: this needs to go - * | \_EsRelation[test][_meta_field{f}#15, emp_no{f}#9, first_name{f}#10, g..] + * |_EsRelation[test][_meta_field{f}#15, emp_no{f}#9, first_name{f}#10, g..] * \_Project[[avg{r}#4, emp_no{f}#9]] * \_Eval[[$$SUM$avg$0{r$}#20 / $$COUNT$avg$1{r$}#21 AS avg#4]] * \_Aggregate[[emp_no{f}#9],[SUM(salary{f}#14,true[BOOLEAN]) AS $$SUM$avg$0#20, COUNT(salary{f}#14,true[BOOLEAN]) AS $$COUNT$ @@ -6257,12 +6247,11 @@ public void testInlinestatsWithAvg() { var esqlProject = as(plan, EsqlProject.class); assertThat(Expressions.names(esqlProject.projections()), is(List.of("avg", "emp_no", "first_name"))); - var upperLimit = asLimit(esqlProject.child(), 10, true); + var upperLimit = asLimit(esqlProject.child(), 10, false); var inlineJoin = as(upperLimit.child(), InlineJoin.class); assertThat(Expressions.names(inlineJoin.config().matchFields()), is(List.of("emp_no"))); // Left - var limit = asLimit(inlineJoin.left(), 10, false); // TODO: this needs to go - var relation = as(limit.child(), EsRelation.class); + var relation = as(inlineJoin.left(), EsRelation.class); // Right var project = as(inlineJoin.right(), Project.class); assertThat(Expressions.names(project.projections()), contains("avg", "emp_no")); @@ -6305,6 +6294,81 @@ public void testInlinestatsWithRow() { ); } + /* + * EsqlProject[[a{r}#4]] + * \_Limit[2[INTEGER],false] + * \_InlineJoin[LEFT,[],[],[]] + * |_EsRelation[test][_meta_field{f}#12, emp_no{f}#6, first_name{f}#7, ge..] + * \_Project[[a{r}#4]] + * \_Eval[[$$SUM$a$0{r$}#17 / $$COUNT$a$1{r$}#18 AS a#4]] + * \_Aggregate[[],[SUM(salary{f}#11,true[BOOLEAN],compensated[KEYWORD]) AS $$SUM$a$0#17, + * COUNT(salary{f}#11,true[BOOLEAN]) AS $$COUNT$a$1#18]] + * \_StubRelation[[_meta_field{f}#12, emp_no{f}#6, first_name{f}#7, gender{f}#8, hire_date{f}#13, job{f}#14, job.raw{f}#15, + * languages{f}#9, last_name{f}#10, long_noidx{f}#16, salary{f}#11]] + */ + public void testInlinestatsWithLimit() { + var query = """ + FROM employees + | INLINESTATS a = AVG(salary) + | LIMIT 2 + | KEEP a + """; + if (releaseBuildForInlinestats(query)) { + return; + } + var plan = optimizedPlan(query); + + var project = as(plan, EsqlProject.class); + assertThat(Expressions.names(project.projections()), is(List.of("a"))); + var limit = asLimit(project.child(), 2, false); + var inlineJoin = as(limit.child(), InlineJoin.class); + // Left + var relation = as(inlineJoin.left(), EsRelation.class); + // Right + var rightProject = as(inlineJoin.right(), Project.class); + assertThat(Expressions.names(rightProject.projections()), contains("a")); + var eval = as(rightProject.child(), Eval.class); + assertThat(Expressions.names(eval.fields()), is(List.of("a"))); + var agg = as(eval.child(), Aggregate.class); + var stub = as(agg.child(), StubRelation.class); + } + + /* + * Limit[10000[INTEGER],false] + * \_Aggregate[[],[VALUES(max_lang{r}#7,true[BOOLEAN]) AS v#11]] + * \_Limit[1[INTEGER],false] + * \_InlineJoin[LEFT,[gender{f}#14],[gender{f}#14],[gender{r}#14]] + * |_EsqlProject[[emp_no{f}#12, languages{f}#15, gender{f}#14]] + * | \_EsRelation[test][_meta_field{f}#18, emp_no{f}#12, first_name{f}#13, ..] + * \_Aggregate[[gender{f}#14],[MAX(languages{f}#15,true[BOOLEAN]) AS max_lang#7, gender{f}#14]] + * \_StubRelation[[emp_no{f}#12, languages{f}#15, gender{f}#14]] + */ + public void testInlinestatsWithLimitAndAgg() { + var query = """ + FROM employees + | KEEP emp_no, languages, gender + | INLINESTATS max_lang = MAX(languages) BY gender + | LIMIT 1 + | STATS v = VALUES(max_lang) + """; + if (releaseBuildForInlinestats(query)) { + return; + } + var plan = optimizedPlan(query); + + var limit = asLimit(plan, 10000, false); + var aggregate = as(limit.child(), Aggregate.class); + assertThat(Expressions.names(aggregate.aggregates()), is(List.of("v"))); + var innerLimit = asLimit(aggregate.child(), 1, false); + var inlineJoin = as(innerLimit.child(), InlineJoin.class); + // Left + var project = as(inlineJoin.left(), EsqlProject.class); + var relation = as(project.child(), EsRelation.class); + // Right + var agg = as(inlineJoin.right(), Aggregate.class); + var stub = as(agg.child(), StubRelation.class); + } + /** * Expects * diff --git a/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/optimizer/rules/logical/PropagateInlineEvalsTests.java b/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/optimizer/rules/logical/PropagateInlineEvalsTests.java index b9a469edae907..662ca51ab564d 100644 --- a/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/optimizer/rules/logical/PropagateInlineEvalsTests.java +++ b/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/optimizer/rules/logical/PropagateInlineEvalsTests.java @@ -83,7 +83,7 @@ public static void init() { * \_StubRelation[[emp_no{f}#11, languages{f}#14, gender{f}#13, y{r}#10]] */ public void testGroupingAliasingMoved_To_LeftSideOfJoin() { - assumeTrue("Requires INLINESTATS", EsqlCapabilities.Cap.INLINESTATS_V10.isEnabled()); + assumeTrue("Requires INLINESTATS", EsqlCapabilities.Cap.INLINESTATS_V11.isEnabled()); var plan = plan(""" from test | keep emp_no, languages, gender @@ -126,7 +126,7 @@ public void testGroupingAliasingMoved_To_LeftSideOfJoin() { * {r}#21]] */ public void testGroupingAliasingMoved_To_LeftSideOfJoin_WithExpression() { - assumeTrue("Requires INLINESTATS", EsqlCapabilities.Cap.INLINESTATS_V10.isEnabled()); + assumeTrue("Requires INLINESTATS", EsqlCapabilities.Cap.INLINESTATS_V11.isEnabled()); var plan = plan(""" from test | keep emp_no, languages, gender, last_name, first_name diff --git a/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/optimizer/rules/logical/ReplaceStatsFilteredAggWithEvalTests.java b/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/optimizer/rules/logical/ReplaceStatsFilteredAggWithEvalTests.java index d6519bb0703f0..92d5cd6fbdc5d 100644 --- a/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/optimizer/rules/logical/ReplaceStatsFilteredAggWithEvalTests.java +++ b/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/optimizer/rules/logical/ReplaceStatsFilteredAggWithEvalTests.java @@ -470,12 +470,11 @@ public void testReplaceInlinestatsFilteredAggWithEvalSingleAggWithExpression() { as(limit.child(), EsRelation.class); } - /** - * Limit[1000[INTEGER],true] + /* + * Limit[1000[INTEGER],false] * \_InlineJoin[LEFT,[emp_no{f}#9],[emp_no{f}#9],[emp_no{r}#9]] * |_EsqlProject[[salary{f}#14, emp_no{f}#9]] - * | \_Limit[1000[INTEGER],false] - * | \_EsRelation[test][_meta_field{f}#15, emp_no{f}#9, first_name{f}#10, g..] + * | \_EsRelation[test][_meta_field{f}#15, emp_no{f}#9, first_name{f}#10, g..] * \_Project[[sum(salary) 1 where false{r}#5, sum(salary) 2{r}#7, emp_no{f}#9]] * \_Eval[[null[LONG] AS sum(salary) 1 where false#5, $$SUM$sum(salary)_ _2$1{r$}#21 2[INTEGER] AS sum(salary) 2#7]] * \_Aggregate[[emp_no{f}#9],[SUM(salary{f}#14,true[BOOLEAN],compensated[KEYWORD]) AS $$SUM$sum(salary)_ _2$1#21, emp_no{f}#9]] @@ -497,8 +496,7 @@ public void testReplaceInlinestatsFilteredAggWithEvalMixedFilterAndNoFilter() { var ij = as(limit.child(), InlineJoin.class); var left = as(ij.left(), EsqlProject.class); assertThat(Expressions.names(left.projections()), contains("salary", "emp_no")); - limit = as(left.child(), Limit.class); - as(limit.child(), EsRelation.class); + var relation = as(left.child(), EsRelation.class); var right = as(ij.right(), Project.class); assertMap( Expressions.names(right.projections()).stream().map(Object::toString).toList(), @@ -615,12 +613,11 @@ public void testReplaceInlinestatsFilteredAggWithEvalNotTrue() { as(limit.child(), EsRelation.class); } - /** + /* * Limit[1000[INTEGER],true] * \_InlineJoin[LEFT,[],[],[]] * |_EsqlProject[[emp_no{f}#8, salary{f}#13, gender{f}#10]] - * | \_Limit[1000[INTEGER],false] - * | \_EsRelation[test][_meta_field{f}#14, emp_no{f}#8, first_name{f}#9, ge..] + * | \_EsRelation[test][_meta_field{f}#14, emp_no{f}#8, first_name{f}#9, ge..] * \_Aggregate[[],[COUNT(salary{f}#13,true[BOOLEAN]) AS m1#7]] * \_StubRelation[[emp_no{f}#8, salary{f}#13, gender{f}#10]] */ @@ -639,8 +636,7 @@ public void testReplaceInlinestatsFilteredAggWithEvalNotFalse() { var left = as(ij.left(), EsqlProject.class); assertThat(Expressions.names(left.projections()), contains("emp_no", "salary", "gender")); - var leftLimit = as(left.child(), Limit.class); - as(leftLimit.child(), EsRelation.class); + var relation = as(left.child(), EsRelation.class); var right = as(ij.right(), Aggregate.class); assertThat(Expressions.names(right.aggregates()), contains("m1")); @@ -716,8 +712,7 @@ public void testReplaceInlinestatsFilteredAggWithEvalCountDistinctInExpression() * Limit[1000[INTEGER],true] * \_InlineJoin[LEFT,[emp_no{f}#17],[emp_no{f}#17],[emp_no{r}#17]] * |_EsqlProject[[emp_no{f}#17, salary{f}#22]] - * | \_Limit[1000[INTEGER],false] - * | \_EsRelation[test][_meta_field{f}#23, emp_no{f}#17, first_name{f}#18, ..] + * | \_EsRelation[test][_meta_field{f}#23, emp_no{f}#17, first_name{f}#18, ..] * \_Project[[max{r}#6, max_a{r}#9, min{r}#12, min_a{r}#15, emp_no{f}#17]] * \_Eval[[null[INTEGER] AS max_a#9, null[INTEGER] AS min_a#15]] * \_Aggregate[[emp_no{f}#17],[MAX(salary{f}#22,true[BOOLEAN]) AS max#6, MIN(salary{f}#22,true[BOOLEAN]) AS min#12, emp_no{f}#17]] @@ -741,8 +736,7 @@ public void testReplaceInlinestatsFilteredAggWithEvalSameAggWithAndWithoutFilter var left = as(ij.left(), EsqlProject.class); assertThat(Expressions.names(left.projections()), contains("emp_no", "salary")); - var leftLimit = as(left.child(), Limit.class); - as(leftLimit.child(), EsRelation.class); + var relation = as(left.child(), EsRelation.class); var right = as(ij.right(), Project.class); assertThat(Expressions.names(right.projections()), contains("max", "max_a", "min", "min_a", "emp_no")); diff --git a/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/session/FieldNameUtilsTests.java b/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/session/FieldNameUtilsTests.java index 734d14337175a..10cde6f9297ec 100644 --- a/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/session/FieldNameUtilsTests.java +++ b/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/session/FieldNameUtilsTests.java @@ -34,7 +34,7 @@ public void testBasicFromCommand() { } public void testBasicFromCommandWithInlinestats() { - assumeTrue("INLINESTATS required", EsqlCapabilities.Cap.INLINESTATS_V10.isEnabled()); + assumeTrue("INLINESTATS required", EsqlCapabilities.Cap.INLINESTATS_V11.isEnabled()); assertFieldNames("from test | inlinestats max(salary) by gender", ALL_FIELDS); } @@ -43,7 +43,7 @@ public void testBasicFromCommandWithMetadata() { } public void testBasicFromCommandWithMetadata_AndInlinestats() { - assumeTrue("INLINESTATS required", EsqlCapabilities.Cap.INLINESTATS_V10.isEnabled()); + assumeTrue("INLINESTATS required", EsqlCapabilities.Cap.INLINESTATS_V11.isEnabled()); assertFieldNames("from test metadata _index, _id, _version | inlinestats max(salary)", ALL_FIELDS); } @@ -320,7 +320,7 @@ public void testLimitZero() { } public void testLimitZero_WithInlinestats() { - assumeTrue("INLINESTATS required", EsqlCapabilities.Cap.INLINESTATS_V10.isEnabled()); + assumeTrue("INLINESTATS required", EsqlCapabilities.Cap.INLINESTATS_V11.isEnabled()); assertFieldNames(""" FROM employees | INLINESTATS COUNT(*), MAX(salary) BY gender @@ -335,7 +335,7 @@ public void testDocsDropHeight() { } public void testDocsDropHeight_WithInlinestats() { - assumeTrue("INLINESTATS required", EsqlCapabilities.Cap.INLINESTATS_V10.isEnabled()); + assumeTrue("INLINESTATS required", EsqlCapabilities.Cap.INLINESTATS_V11.isEnabled()); assertFieldNames(""" FROM employees | DROP height @@ -351,7 +351,7 @@ public void testDocsDropHeightWithWildcard() { } public void testDocsDropHeightWithWildcard_AndInlinestats() { - assumeTrue("INLINESTATS required", EsqlCapabilities.Cap.INLINESTATS_V10.isEnabled()); + assumeTrue("INLINESTATS required", EsqlCapabilities.Cap.INLINESTATS_V11.isEnabled()); assertFieldNames(""" FROM employees | INLINESTATS MAX(salary) BY gender @@ -518,7 +518,7 @@ public void testSortWithLimitOne_DropHeight() { } public void testSortWithLimitOne_DropHeight_WithInlinestats() { - assumeTrue("INLINESTATS required", EsqlCapabilities.Cap.INLINESTATS_V10.isEnabled()); + assumeTrue("INLINESTATS required", EsqlCapabilities.Cap.INLINESTATS_V11.isEnabled()); assertFieldNames("from employees | inlinestats avg(salary) by languages | sort languages | limit 1 | drop height*", ALL_FIELDS); } @@ -818,7 +818,7 @@ public void testFilterById() { } public void testFilterById_WithInlinestats() { - assumeTrue("INLINESTATS required", EsqlCapabilities.Cap.INLINESTATS_V10.isEnabled()); + assumeTrue("INLINESTATS required", EsqlCapabilities.Cap.INLINESTATS_V11.isEnabled()); assertFieldNames("FROM apps metadata _id | INLINESTATS max(rate) | WHERE _id == \"4\"", ALL_FIELDS); } @@ -1289,7 +1289,7 @@ public void testProjectDropPattern() { } public void testProjectDropPattern_WithInlinestats() { - assumeTrue("INLINESTATS required", EsqlCapabilities.Cap.INLINESTATS_V10.isEnabled()); + assumeTrue("INLINESTATS required", EsqlCapabilities.Cap.INLINESTATS_V11.isEnabled()); assertFieldNames(""" from test | inlinestats max(foo) by bar @@ -1372,7 +1372,7 @@ public void testCountAllAndOtherStatGrouped() { } public void testCountAllAndOtherStatGrouped_WithInlinestats() { - assumeTrue("INLINESTATS required", EsqlCapabilities.Cap.INLINESTATS_V10.isEnabled()); + assumeTrue("INLINESTATS required", EsqlCapabilities.Cap.INLINESTATS_V11.isEnabled()); assertFieldNames(""" from test | inlinestats c = count(*), min = min(emp_no) by languages @@ -1411,7 +1411,7 @@ public void testCountAllWithEval() { } public void testCountAllWithEval_AndInlinestats() { - assumeTrue("INLINESTATS required", EsqlCapabilities.Cap.INLINESTATS_V10.isEnabled()); + assumeTrue("INLINESTATS required", EsqlCapabilities.Cap.INLINESTATS_V11.isEnabled()); assertFieldNames(""" from test | rename languages as l @@ -1424,7 +1424,7 @@ public void testCountAllWithEval_AndInlinestats() { } public void testKeepAfterEval_AndInlinestats() { - assumeTrue("INLINESTATS required", EsqlCapabilities.Cap.INLINESTATS_V10.isEnabled()); + assumeTrue("INLINESTATS required", EsqlCapabilities.Cap.INLINESTATS_V11.isEnabled()); assertFieldNames(""" from test | rename languages as l @@ -1437,7 +1437,7 @@ public void testKeepAfterEval_AndInlinestats() { } public void testKeepBeforeEval_AndInlinestats() { - assumeTrue("INLINESTATS required", EsqlCapabilities.Cap.INLINESTATS_V10.isEnabled()); + assumeTrue("INLINESTATS required", EsqlCapabilities.Cap.INLINESTATS_V11.isEnabled()); assertFieldNames(""" from test | rename languages as l @@ -1450,7 +1450,7 @@ public void testKeepBeforeEval_AndInlinestats() { } public void testStatsBeforeEval_AndInlinestats() { - assumeTrue("INLINESTATS required", EsqlCapabilities.Cap.INLINESTATS_V10.isEnabled()); + assumeTrue("INLINESTATS required", EsqlCapabilities.Cap.INLINESTATS_V11.isEnabled()); assertFieldNames(""" from test | rename languages as l @@ -1462,7 +1462,7 @@ public void testStatsBeforeEval_AndInlinestats() { } public void testStatsBeforeInlinestats() { - assumeTrue("INLINESTATS required", EsqlCapabilities.Cap.INLINESTATS_V10.isEnabled()); + assumeTrue("INLINESTATS required", EsqlCapabilities.Cap.INLINESTATS_V11.isEnabled()); assertFieldNames(""" from test | stats min = min(salary) by languages @@ -1471,7 +1471,7 @@ public void testStatsBeforeInlinestats() { } public void testKeepBeforeInlinestats() { - assumeTrue("INLINESTATS required", EsqlCapabilities.Cap.INLINESTATS_V10.isEnabled()); + assumeTrue("INLINESTATS required", EsqlCapabilities.Cap.INLINESTATS_V11.isEnabled()); assertFieldNames(""" from test | keep languages, salary @@ -2845,7 +2845,7 @@ public void testForkAfterMvExpand() { } public void testForkBeforeInlineStatsIgnore() { - assumeTrue("INLINESTATS required", EsqlCapabilities.Cap.INLINESTATS_V10.isEnabled()); + assumeTrue("INLINESTATS required", EsqlCapabilities.Cap.INLINESTATS_V11.isEnabled()); assertTrue("FORK required", EsqlCapabilities.Cap.FORK_V9.isEnabled()); assertFieldNames(""" FROM employees @@ -2858,7 +2858,7 @@ public void testForkBeforeInlineStatsIgnore() { } public void testForkBranchWithInlineStatsIgnore() { - assumeTrue("INLINESTATS required", EsqlCapabilities.Cap.INLINESTATS_V10.isEnabled()); + assumeTrue("INLINESTATS required", EsqlCapabilities.Cap.INLINESTATS_V11.isEnabled()); assertTrue("FORK required", EsqlCapabilities.Cap.FORK_V9.isEnabled()); assertFieldNames(""" FROM employees @@ -2872,7 +2872,7 @@ public void testForkBranchWithInlineStatsIgnore() { } public void testForkAfterInlineStatsIgnore() { - assumeTrue("INLINESTATS required", EsqlCapabilities.Cap.INLINESTATS_V10.isEnabled()); + assumeTrue("INLINESTATS required", EsqlCapabilities.Cap.INLINESTATS_V11.isEnabled()); assertTrue("FORK required", EsqlCapabilities.Cap.FORK_V9.isEnabled()); assertFieldNames(""" FROM employees