1717import org .elasticsearch .xpack .esql .core .expression .FoldContext ;
1818import org .elasticsearch .xpack .esql .core .expression .Literal ;
1919import org .elasticsearch .xpack .esql .core .expression .MetadataAttribute ;
20+ import org .elasticsearch .xpack .esql .core .expression .NamedExpression ;
2021import org .elasticsearch .xpack .esql .core .expression .ReferenceAttribute ;
2122import org .elasticsearch .xpack .esql .core .tree .Source ;
2223import org .elasticsearch .xpack .esql .core .type .DataType ;
@@ -1231,18 +1232,38 @@ public void testPushDownFilterPastUnionAllAndCombineWithFilterInSubquery() {
12311232 public void testPushDownFilterOnReferenceAttributesPastUnionAllDebug () {
12321233 assumeTrue ("Requires subquery in FROM command support" , EsqlCapabilities .Cap .SUBQUERY_IN_FROM_COMMAND .isEnabled ());
12331234 var plan = planSubquery ("""
1234- FROM test, (FROM test1 | where salary < 100000 | EVAL x = 1, y = emp_no, z = emp_no + 1)
1235+ FROM test
1236+ , (FROM test1
1237+ | where salary < 100000
1238+ | EVAL x = 1, y = emp_no, z = emp_no + 1)
1239+ , (FROM languages
1240+ | STATS cnt = COUNT(*) by language_code
1241+ | RENAME language_code AS z, cnt AS y
1242+ | EVAL x = 1)
1243+ , (FROM test1
1244+ | RENAME languages AS language_code
1245+ | LOOKUP JOIN languages_lookup ON language_code
1246+ | RENAME emp_no AS x, salary AS y, language_code AS z)
12351247 | WHERE x is not null and y is not null and z > 0
12361248 """ );
12371249
12381250 Limit limit = as (plan , Limit .class );
12391251 UnionAll unionAll = as (limit .child (), UnionAll .class );
1240- assertEquals (2 , unionAll .children ().size ());
1252+ assertEquals (4 , unionAll .children ().size ());
12411253
12421254 LocalRelation child1 = as (unionAll .children ().get (0 ), LocalRelation .class );
12431255
12441256 EsqlProject child2 = as (unionAll .children ().get (1 ), EsqlProject .class );
1245- Limit childLimit = as (child2 .child (), Limit .class );
1257+ Filter filter = as (child2 .child (), Filter .class );
1258+ IsNotNull isNotNull = as (filter .condition (), IsNotNull .class );
1259+ ReferenceAttribute y = as (isNotNull .field (), ReferenceAttribute .class );
1260+ assertEquals ("y" , y .name ());
1261+ Eval eval = as (filter .child (), Eval .class );
1262+ List <Alias > aliases = eval .fields ();
1263+ assertEquals (2 , aliases .size ());
1264+ assertEquals ("language_name" , aliases .get (0 ).name ());
1265+ assertEquals ("y" , aliases .get (1 ).name ());
1266+ Limit childLimit = as (eval .child (), Limit .class );
12461267 Subquery subquery = as (childLimit .child (), Subquery .class );
12471268 Project project = as (subquery .child (), Project .class );
12481269 Filter childFilter = as (project .child (), Filter .class );
@@ -1251,8 +1272,8 @@ public void testPushDownFilterOnReferenceAttributesPastUnionAllDebug() {
12511272 assertEquals ("z" , z .name ());
12521273 Literal right = as (greaterThan .right (), Literal .class );
12531274 assertEquals (0 , right .value ());
1254- Eval eval = as (childFilter .child (), Eval .class );
1255- List < Alias > aliases = eval .fields ();
1275+ eval = as (childFilter .child (), Eval .class );
1276+ aliases = eval .fields ();
12561277 assertEquals (2 , aliases .size ());
12571278 Alias aliasX = aliases .get (0 );
12581279 assertEquals ("x" , aliasX .name ());
@@ -1261,17 +1282,67 @@ public void testPushDownFilterOnReferenceAttributesPastUnionAllDebug() {
12611282 Alias aliasZ = aliases .get (1 );
12621283 assertEquals ("z" , aliasZ .name ());
12631284 childFilter = as (eval .child (), Filter .class );
1264- And and = as (childFilter .condition (), And .class );
1265- IsNotNull isNotNull = as (and .right (), IsNotNull .class );
1266- FieldAttribute emp_no = as (isNotNull .field (), FieldAttribute .class );
1267- assertEquals ("emp_no" , emp_no .name ());
1268- LessThan lessThan = as (and .left (), LessThan .class );
1285+ LessThan lessThan = as (childFilter .condition (), LessThan .class );
12691286 FieldAttribute salaryField = as (lessThan .left (), FieldAttribute .class );
12701287 assertEquals ("salary" , salaryField .name ());
12711288 Literal literal = as (lessThan .right (), Literal .class );
12721289 assertEquals (100000 , literal .value ());
12731290 EsRelation relation = as (childFilter .child (), EsRelation .class );
12741291 assertEquals ("test1" , relation .indexPattern ());
1292+
1293+ EsqlProject child3 = as (unionAll .children ().get (2 ), EsqlProject .class );
1294+ eval = as (child3 .child (), Eval .class );
1295+ limit = as (eval .child (), Limit .class );
1296+ subquery = as (limit .child (), Subquery .class );
1297+ eval = as (subquery .child (), Eval .class );
1298+ filter = as (eval .child (), Filter .class );
1299+ And and = as (filter .condition (), And .class );
1300+ isNotNull = as (and .left (), IsNotNull .class );
1301+ y = as (isNotNull .field (), ReferenceAttribute .class );
1302+ assertEquals ("y" , y .name ());
1303+ greaterThan = as (and .right (), GreaterThan .class );
1304+ z = as (greaterThan .left (), ReferenceAttribute .class );
1305+ assertEquals ("z" , z .name ());
1306+ right = as (greaterThan .right (), Literal .class );
1307+ assertEquals (0 , right .value ());
1308+ Aggregate aggregate = as (filter .child (), Aggregate .class );
1309+ List <Expression > groupings = aggregate .groupings ();
1310+ assertEquals (1 , groupings .size ());
1311+ FieldAttribute language_code = as (groupings .get (0 ), FieldAttribute .class );
1312+ assertEquals ("language_code" , language_code .name ());
1313+ List <? extends NamedExpression > aggregates = aggregate .aggregates ();
1314+ assertEquals (2 , aggregates .size ());
1315+ assertEquals ("y" , aggregates .get (0 ).name ());
1316+ assertEquals ("z" , aggregates .get (1 ).name ());
1317+ relation = as (aggregate .child (), EsRelation .class );
1318+ assertEquals ("languages" , relation .indexPattern ());
1319+
1320+ EsqlProject child4 = as (unionAll .children ().get (3 ), EsqlProject .class );
1321+ filter = as (child4 .child (), Filter .class );
1322+ isNotNull = as (filter .condition (), IsNotNull .class );
1323+ ReferenceAttribute x = as (isNotNull .field (), ReferenceAttribute .class );
1324+ assertEquals ("y" , x .name ());
1325+ eval = as (filter .child (), Eval .class );
1326+ aliases = eval .fields ();
1327+ assertEquals (4 , aliases .size ());
1328+ limit = as (eval .child (), Limit .class );
1329+ subquery = as (limit .child (), Subquery .class );
1330+ project = as (subquery .child (), Project .class );
1331+ Join lookupJoin = as (project .child (), Join .class );
1332+ Filter leftFilter = as (lookupJoin .left (), Filter .class );
1333+ and = as (leftFilter .condition (), And .class );
1334+ isNotNull = as (and .left (), IsNotNull .class );
1335+ FieldAttribute emp_no = as (isNotNull .field (), FieldAttribute .class );
1336+ assertEquals ("emp_no" , emp_no .name ());
1337+ greaterThan = as (and .right (), GreaterThan .class );
1338+ language_code = as (greaterThan .left (), FieldAttribute .class );
1339+ assertEquals ("languages" , language_code .name ());
1340+ right = as (greaterThan .right (), Literal .class );
1341+ assertEquals (0 , right .value ());
1342+ relation = as (leftFilter .child (), EsRelation .class );
1343+ assertEquals ("test1" , relation .indexPattern ());
1344+ relation = as (lookupJoin .right (), EsRelation .class );
1345+ assertEquals ("languages_lookup" , relation .indexPattern ());
12751346 }
12761347
12771348 public void testPushDownFilterOnReferenceAttributesAndFieldAttributesPastUnionAllDebug () {
0 commit comments