@@ -1014,6 +1014,27 @@ public void testPushDownLookupJoinExpressionMultipleWhere() {
10141014 assertEquals (expectedPushedFilters , actualPushedFilters );
10151015 }
10161016
1017+ /**
1018+ * Limit[1000[INTEGER],false]
1019+ * \_UnionAll[[_meta_field{r}#44, emp_no{r}#45, first_name{r}#46, gender{r}#47, hire_date{r}#48, job{r}#49, job.raw{r}#50, l
1020+ * anguages{r}#51, last_name{r}#52, long_noidx{r}#53, salary{r}#54, language_code{r}#55, language_name{r}#56]]
1021+ * |_EsqlProject[[_meta_field{f}#11, emp_no{f}#5, first_name{f}#6, gender{f}#7, hire_date{f}#12, job{f}#13, job.raw{f}#14, lang
1022+ * uages{f}#8, last_name{f}#9, long_noidx{f}#15, salary{f}#10, language_code{r}#29, language_name{r}#30]]
1023+ * | \_Eval[[null[INTEGER] AS language_code#29, null[KEYWORD] AS language_name#30]]
1024+ * | \_Limit[1000[INTEGER],false]
1025+ * | \_Filter[emp_no{f}#5 > 10000[INTEGER]]
1026+ * | \_EsRelation[test][_meta_field{f}#11, emp_no{f}#5, first_name{f}#6, ge..]
1027+ * |_EsqlProject[[_meta_field{f}#22, emp_no{f}#16, first_name{f}#17, gender{f}#18, hire_date{f}#23, job{f}#24, job.raw{f}#25, l
1028+ * anguages{f}#19, last_name{f}#20, long_noidx{f}#26, salary{f}#21, language_code{r}#31, language_name{r}#32]]
1029+ * | \_Eval[[null[INTEGER] AS language_code#31, null[KEYWORD] AS language_name#32]]
1030+ * | \_Limit[1000[INTEGER],false]
1031+ * | \_Subquery[]
1032+ * | \_Filter[languages{f}#19 > 0[INTEGER] AND emp_no{f}#16 > 10000[INTEGER]]
1033+ * | \_EsRelation[test1][_meta_field{f}#22, emp_no{f}#16, first_name{f}#17, ..]
1034+ * \_LocalRelation[[_meta_field{r}#33, emp_no{r}#34, first_name{r}#35, gender{r}#36, hire_date{r}#37, job{r}#38, job.raw{r}#39, l
1035+ * anguages{r}#40, last_name{r}#41, long_noidx{r}#42, salary{r}#43, language_code{f}#27, language_name{f}#28],EMPT
1036+ * Y]
1037+ */
10171038 public void testPushDownSimpleFilterPastUnionAll () {
10181039 assumeTrue ("Requires subquery in FROM command support" , EsqlCapabilities .Cap .SUBQUERY_IN_FROM_COMMAND .isEnabled ());
10191040 var plan = planSubquery ("""
@@ -1059,6 +1080,27 @@ public void testPushDownSimpleFilterPastUnionAll() {
10591080 LocalRelation localRelation = as (unionAll .children ().get (2 ), LocalRelation .class );
10601081 }
10611082
1083+ /**
1084+ * Limit[1000[INTEGER],false]
1085+ * \_UnionAll[[_meta_field{r}#45, emp_no{r}#46, first_name{r}#47, gender{r}#48, hire_date{r}#49, job{r}#50, job.raw{r}#51, l
1086+ * anguages{r}#52, last_name{r}#53, long_noidx{r}#54, salary{r}#55, language_code{r}#56, language_name{r}#57]]
1087+ * |_EsqlProject[[_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, lang
1088+ * uages{f}#9, last_name{f}#10, long_noidx{f}#16, salary{f}#11, language_code{r}#30, language_name{r}#31]]
1089+ * | \_Eval[[null[INTEGER] AS language_code#30, null[KEYWORD] AS language_name#31]]
1090+ * | \_Limit[1000[INTEGER],false]
1091+ * | \_Filter[emp_no{f}#6 > 10000[INTEGER] AND salary{f}#11 > 50000[INTEGER]]
1092+ * | \_EsRelation[test][_meta_field{f}#12, emp_no{f}#6, first_name{f}#7, ge..]
1093+ * |_EsqlProject[[_meta_field{f}#23, emp_no{f}#17, first_name{f}#18, gender{f}#19, hire_date{f}#24, job{f}#25, job.raw{f}#26, l
1094+ * anguages{f}#20, last_name{f}#21, long_noidx{f}#27, salary{f}#22, language_code{r}#32, language_name{r}#33]]
1095+ * | \_Eval[[null[INTEGER] AS language_code#32, null[KEYWORD] AS language_name#33]]
1096+ * | \_Limit[1000[INTEGER],false]
1097+ * | \_Subquery[]
1098+ * | \_Filter[languages{f}#20 > 0[INTEGER] AND emp_no{f}#17 > 10000[INTEGER] AND salary{f}#22 > 50000[INTEGER]]
1099+ * | \_EsRelation[test1][_meta_field{f}#23, emp_no{f}#17, first_name{f}#18, ..]
1100+ * \_LocalRelation[[_meta_field{r}#34, emp_no{r}#35, first_name{r}#36, gender{r}#37, hire_date{r}#38, job{r}#39, job.raw{r}#40, l
1101+ * anguages{r}#41, last_name{r}#42, long_noidx{r}#43, salary{r}#44, language_code{f}#28, language_name{f}#29],EMPT
1102+ * Y]
1103+ */
10621104 public void testPushDownConjunctiveFilterPastUnionAll () {
10631105 assumeTrue ("Requires subquery in FROM command support" , EsqlCapabilities .Cap .SUBQUERY_IN_FROM_COMMAND .isEnabled ());
10641106 var plan = planSubquery ("""
@@ -1116,6 +1158,27 @@ public void testPushDownConjunctiveFilterPastUnionAll() {
11161158 LocalRelation localRelation = as (unionAll .children ().get (2 ), LocalRelation .class );
11171159 }
11181160
1161+ /**
1162+ * Limit[1000[INTEGER],false]
1163+ * \_UnionAll[[_meta_field{r}#45, emp_no{r}#46, first_name{r}#47, gender{r}#48, hire_date{r}#49, job{r}#50, job.raw{r}#51, l
1164+ * anguages{r}#52, last_name{r}#53, long_noidx{r}#54, salary{r}#55, language_code{r}#56, language_name{r}#57]]
1165+ * |_EsqlProject[[_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, lang
1166+ * uages{f}#9, last_name{f}#10, long_noidx{f}#16, salary{f}#11, language_code{r}#30, language_name{r}#31]]
1167+ * | \_Eval[[null[INTEGER] AS language_code#30, null[KEYWORD] AS language_name#31]]
1168+ * | \_Limit[1000[INTEGER],false]
1169+ * | \_Filter[emp_no{f}#6 > 10000[INTEGER] OR salary{f}#11 > 50000[INTEGER]]
1170+ * | \_EsRelation[test][_meta_field{f}#12, emp_no{f}#6, first_name{f}#7, ge..]
1171+ * |_EsqlProject[[_meta_field{f}#23, emp_no{f}#17, first_name{f}#18, gender{f}#19, hire_date{f}#24, job{f}#25, job.raw{f}#26, l
1172+ * anguages{f}#20, last_name{f}#21, long_noidx{f}#27, salary{f}#22, language_code{r}#32, language_name{r}#33]]
1173+ * | \_Eval[[null[INTEGER] AS language_code#32, null[KEYWORD] AS language_name#33]]
1174+ * | \_Limit[1000[INTEGER],false]
1175+ * | \_Subquery[]
1176+ * | \_Filter[languages{f}#20 > 0[INTEGER] AND emp_no{f}#17 > 10000[INTEGER] OR salary{f}#22 > 50000[INTEGER]]
1177+ * | \_EsRelation[test1][_meta_field{f}#23, emp_no{f}#17, first_name{f}#18, ..]
1178+ * \_LocalRelation[[_meta_field{r}#34, emp_no{r}#35, first_name{r}#36, gender{r}#37, hire_date{r}#38, job{r}#39, job.raw{r}#40, l
1179+ * anguages{r}#41, last_name{r}#42, long_noidx{r}#43, salary{r}#44, language_code{f}#28, language_name{f}#29],EMPT
1180+ * Y]
1181+ */
11191182 public void testPushDownDisjunctiveFilterPastUnionAll () {
11201183 assumeTrue ("Requires subquery in FROM command support" , EsqlCapabilities .Cap .SUBQUERY_IN_FROM_COMMAND .isEnabled ());
11211184 var plan = planSubquery ("""
@@ -1173,16 +1236,38 @@ public void testPushDownDisjunctiveFilterPastUnionAll() {
11731236 LocalRelation localRelation = as (unionAll .children ().get (2 ), LocalRelation .class );
11741237 }
11751238
1239+ /**
1240+ * Limit[1000[INTEGER],false]
1241+ * \_UnionAll[[_meta_field{r}#45, emp_no{r}#46, first_name{r}#47, gender{r}#48, hire_date{r}#49, job{r}#50, job.raw{r}#51, l
1242+ * anguages{r}#52, last_name{r}#53, long_noidx{r}#54, salary{r}#55, language_code{r}#56, language_name{r}#57]]
1243+ * |_EsqlProject[[_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, lang
1244+ * uages{f}#9, last_name{f}#10, long_noidx{f}#16, salary{f}#11, language_code{r}#30, language_name{r}#31]]
1245+ * | \_Eval[[null[INTEGER] AS language_code#30, null[KEYWORD] AS language_name#31]]
1246+ * | \_Limit[1000[INTEGER],false]
1247+ * | \_Filter[emp_no{f}#6 > 10000[INTEGER] AND salary{f}#11 < 50000[INTEGER]]
1248+ * | \_EsRelation[test][_meta_field{f}#12, emp_no{f}#6, first_name{f}#7, ge..]
1249+ * |_EsqlProject[[_meta_field{f}#23, emp_no{f}#17, first_name{f}#18, gender{f}#19, hire_date{f}#24, job{f}#25, job.raw{f}#26, l
1250+ * anguages{f}#20, last_name{f}#21, long_noidx{f}#27, salary{f}#22, language_code{r}#32, language_name{r}#33]]
1251+ * | \_Eval[[null[INTEGER] AS language_code#32, null[KEYWORD] AS language_name#33]]
1252+ * | \_Limit[1000[INTEGER],false]
1253+ * | \_Subquery[]
1254+ * | \_Filter[salary{f}#22 < 50000[INTEGER] AND emp_no{f}#17 > 10000[INTEGER]]
1255+ * | \_EsRelation[test1][_meta_field{f}#23, emp_no{f}#17, first_name{f}#18, ..]
1256+ * \_LocalRelation[[_meta_field{r}#34, emp_no{r}#35, first_name{r}#36, gender{r}#37, hire_date{r}#38, job{r}#39, job.raw{r}#40, l
1257+ * anguages{r}#41, last_name{r}#42, long_noidx{r}#43, salary{r}#44, language_code{f}#28, language_name{f}#29],EMPT
1258+ * Y]
1259+ */
11761260 public void testPushDownFilterPastUnionAllAndCombineWithFilterInSubquery () {
11771261 assumeTrue ("Requires subquery in FROM command support" , EsqlCapabilities .Cap .SUBQUERY_IN_FROM_COMMAND .isEnabled ());
11781262 var plan = planSubquery ("""
11791263 FROM test, (FROM test1 | where salary < 100000), (FROM languages | WHERE language_code > 0)
1180- | WHERE emp_no > 10000 and salary > 50000
1264+ | WHERE emp_no > 10000 and salary < 50000
11811265 """ );
11821266
11831267 Limit limit = as (plan , Limit .class );
11841268 UnionAll unionAll = as (limit .child (), UnionAll .class );
11851269 assertEquals (3 , unionAll .children ().size ());
1270+
11861271 EsqlProject child1 = as (unionAll .children ().get (0 ), EsqlProject .class );
11871272 Eval eval = as (child1 .child (), Eval .class );
11881273 Limit childLimit = as (eval .child (), Limit .class );
@@ -1193,7 +1278,7 @@ public void testPushDownFilterPastUnionAllAndCombineWithFilterInSubquery() {
11931278 assertEquals ("emp_no" , empNo .name ());
11941279 Literal right = as (emp_no .right (), Literal .class );
11951280 assertEquals (10000 , right .value ());
1196- GreaterThan salary = as (and .right (), GreaterThan .class );
1281+ LessThan salary = as (and .right (), LessThan .class );
11971282 FieldAttribute salaryField = as (salary .left (), FieldAttribute .class );
11981283 assertEquals ("salary" , salaryField .name ());
11991284 right = as (salary .right (), Literal .class );
@@ -1207,29 +1292,67 @@ public void testPushDownFilterPastUnionAllAndCombineWithFilterInSubquery() {
12071292 Subquery subquery = as (childLimit .child (), Subquery .class );
12081293 childFilter = as (subquery .child (), Filter .class );
12091294 and = as (childFilter .condition (), And .class );
1210- And empNoAndSalary = as (and .right (), And .class );
1211- emp_no = as (empNoAndSalary .left (), GreaterThan .class );
1295+ emp_no = as (and .right (), GreaterThan .class );
12121296 empNo = as (emp_no .left (), FieldAttribute .class );
12131297 assertEquals ("emp_no" , empNo .name ());
12141298 right = as (emp_no .right (), Literal .class );
12151299 assertEquals (10000 , right .value ());
1216- salary = as (empNoAndSalary . right (), GreaterThan .class );
1300+ salary = as (and . left (), LessThan .class );
12171301 salaryField = as (salary .left (), FieldAttribute .class );
12181302 assertEquals ("salary" , salaryField .name ());
12191303 right = as (salary .right (), Literal .class );
12201304 assertEquals (50000 , right .value ());
1221- LessThan lessThan = as (and .left (), LessThan .class );
1222- salaryField = as (lessThan .left (), FieldAttribute .class );
1223- assertEquals ("salary" , salaryField .name ());
1224- right = as (lessThan .right (), Literal .class );
1225- assertEquals (100000 , right .value ());
12261305 relation = as (childFilter .child (), EsRelation .class );
12271306 assertEquals ("test1" , relation .indexPattern ());
12281307
12291308 LocalRelation localRelation = as (unionAll .children ().get (2 ), LocalRelation .class );
12301309 }
12311310
1232- public void testPushDownFilterOnReferenceAttributesPastUnionAllDebug () {
1311+ /**
1312+ * Limit[1000[INTEGER],false]
1313+ * \_UnionAll[[_meta_field{r}#95, emp_no{r}#96, first_name{r}#97, gender{r}#98, hire_date{r}#99, job{r}#100, job.raw{r}#101,
1314+ * languages{r}#102, last_name{r}#103, long_noidx{r}#104, salary{r}#105, x{r}#106, y{r}#107, z{r}#108, language_name{r}#109]]
1315+ * |_LocalRelation[[_meta_field{f}#44, emp_no{f}#38, first_name{f}#39, gender{f}#40, hire_date{f}#45, job{f}#46, job.raw{f}#47, l
1316+ * anguages{f}#41, last_name{f}#42, long_noidx{f}#48, salary{f}#43, x{r}#75, y{r}#110, z{r}#77, language_name{r}#78],
1317+ * EMPTY]
1318+ * |_EsqlProject[[_meta_field{f}#55, emp_no{f}#49, first_name{f}#50, gender{f}#51, hire_date{f}#56, job{f}#57, job.raw{f}#58, l
1319+ * anguages{f}#52, last_name{f}#53, long_noidx{f}#59, salary{f}#54, x{r}#4, y{r}#111, z{r}#10, language_name{r}#79]]
1320+ * | \_Filter[ISNOTNULL(y{r}#111)]
1321+ * | \_Eval[[null[KEYWORD] AS language_name#79, TOLONG(y{r}#7) AS y#111]]
1322+ * | \_Limit[1000[INTEGER],false]
1323+ * | \_Subquery[]
1324+ * | \_Project[[_meta_field{f}#55, emp_no{f}#49, first_name{f}#50, gender{f}#51, hire_date{f}#56, job{f}#57, job.raw{f}#58, l
1325+ * anguages{f}#52, last_name{f}#53, long_noidx{f}#59, salary{f}#54, x{r}#4, emp_no{f}#49 AS y#7, z{r}#10]]
1326+ * | \_Filter[z{r}#10 > 0[INTEGER]]
1327+ * | \_Eval[[1[INTEGER] AS x#4, emp_no{f}#49 + 1[INTEGER] AS z#10]]
1328+ * | \_Filter[salary{f}#54 < 100000[INTEGER]]
1329+ * | \_EsRelation[test1][_meta_field{f}#55, emp_no{f}#49, first_name{f}#50, ..]
1330+ * |_EsqlProject[[_meta_field{r}#80, emp_no{r}#81, first_name{r}#82, gender{r}#83, hire_date{r}#84, job{r}#85, job.raw{r}#86, l
1331+ * anguages{r}#87, last_name{r}#88, long_noidx{r}#89, salary{r}#90, x{r}#21, y{r}#19, z{r}#16, language_name{r}#91]]
1332+ * | \_Eval[[null[KEYWORD] AS _meta_field#80, null[INTEGER] AS emp_no#81, null[KEYWORD] AS first_name#82, null[TEXT] AS ge
1333+ * nder#83, null[DATETIME] AS hire_date#84, null[TEXT] AS job#85, null[KEYWORD] AS job.raw#86, null[INTEGER] AS languages#87,
1334+ * null[KEYWORD] AS last_name#88, null[LONG] AS long_noidx#89, null[INTEGER] AS salary#90, null[KEYWORD] AS language_name#91]]
1335+ * | \_Limit[1000[INTEGER],false]
1336+ * | \_Subquery[]
1337+ * | \_Eval[[1[INTEGER] AS x#21]]
1338+ * | \_Filter[ISNOTNULL(y{r}#19) AND z{r}#16 > 0[INTEGER]]
1339+ * | \_Aggregate[[language_code{f}#60],[COUNT(*[KEYWORD],true[BOOLEAN]) AS y#19, language_code{f}#60 AS z#16]]
1340+ * | \_EsRelation[languages][language_code{f}#60, language_name{f}#61]
1341+ * \_EsqlProject[[_meta_field{f}#68, emp_no{r}#92, first_name{f}#63, gender{f}#64, hire_date{f}#69, job{f}#70, job.raw{f}#71, l
1342+ * anguages{r}#93, last_name{f}#66, long_noidx{f}#72, salary{r}#94, x{r}#28, y{r}#112, z{r}#34, language_name{f}#74]]
1343+ * \_Filter[ISNOTNULL(y{r}#112)]
1344+ * \_Eval[[null[INTEGER] AS emp_no#92, null[INTEGER] AS languages#93, null[INTEGER] AS salary#94, TOLONG(y{r}#31) AS y#1
1345+ * 12]]
1346+ * \_Limit[1000[INTEGER],false]
1347+ * \_Subquery[]
1348+ * \_Project[[_meta_field{f}#68, emp_no{f}#62 AS x#28, first_name{f}#63, gender{f}#64, hire_date{f}#69, job{f}#70, job.raw{
1349+ * f}#71, languages{f}#65 AS z#34, last_name{f}#66, long_noidx{f}#72, salary{f}#67 AS y#31, language_name{f}#74]]
1350+ * \_Join[LEFT,[languages{f}#65],[language_code{f}#73],null]
1351+ * |_Filter[ISNOTNULL(emp_no{f}#62) AND languages{f}#65 > 0[INTEGER]]
1352+ * | \_EsRelation[test1][_meta_field{f}#68, emp_no{f}#62, first_name{f}#63, ..]
1353+ * \_EsRelation[languages_lookup][LOOKUP][language_code{f}#73, language_name{f}#74]
1354+ */
1355+ public void testPushDownFilterOnReferenceAttributesPastUnionAll () {
12331356 assumeTrue ("Requires subquery in FROM command support" , EsqlCapabilities .Cap .SUBQUERY_IN_FROM_COMMAND .isEnabled ());
12341357 var plan = planSubquery ("""
12351358 FROM test
@@ -1345,7 +1468,22 @@ public void testPushDownFilterOnReferenceAttributesPastUnionAllDebug() {
13451468 assertEquals ("languages_lookup" , relation .indexPattern ());
13461469 }
13471470
1348- public void testPushDownFilterOnReferenceAttributesAndFieldAttributesPastUnionAllDebug () {
1471+ /**
1472+ * Limit[1000[INTEGER],false]
1473+ * \_UnionAll[[_meta_field{r}#35, emp_no{r}#36, first_name{r}#37, gender{r}#38, hire_date{r}#39, job{r}#40, job.raw{r}#41, l
1474+ * anguages{r}#42, last_name{r}#43, long_noidx{r}#44, salary{r}#45, x{r}#46, y{r}#47]]
1475+ * |_LocalRelation[[_meta_field{f}#17, emp_no{f}#11, first_name{f}#12, gender{f}#13, hire_date{f}#18, job{f}#19, job.raw{f}#20, l
1476+ * anguages{f}#14, last_name{f}#15, long_noidx{f}#21, salary{f}#16, x{r}#33, y{r}#34],EMPTY]
1477+ * \_EsqlProject[[_meta_field{f}#28, emp_no{f}#22, first_name{f}#23, gender{f}#24, hire_date{f}#29, job{f}#30, job.raw{f}#31, l
1478+ * anguages{f}#25, last_name{f}#26, long_noidx{f}#32, salary{f}#27, x{r}#4, y{r}#7]]
1479+ * \_Limit[1000[INTEGER],false]
1480+ * \_Subquery[]
1481+ * \_Filter[y{r}#7 > 0[INTEGER]]
1482+ * \_Eval[[1[INTEGER] AS x#4, emp_no{f}#22 + 1[INTEGER] AS y#7]]
1483+ * \_Filter[salary{f}#27 < 100000[INTEGER] AND emp_no{f}#22 > 0[INTEGER]]
1484+ * \_EsRelation[test1][_meta_field{f}#28, emp_no{f}#22, first_name{f}#23, ..]
1485+ */
1486+ public void testPushDownFilterOnReferenceAttributesAndFieldAttributesPastUnionAll () {
13491487 assumeTrue ("Requires subquery in FROM command support" , EsqlCapabilities .Cap .SUBQUERY_IN_FROM_COMMAND .isEnabled ());
13501488 var plan = planSubquery ("""
13511489 FROM test, (FROM test1 | where salary < 100000 | EVAL x = 1, y = emp_no + 1)
0 commit comments