3333import org .elasticsearch .xpack .esql .core .type .DataType ;
3434import org .elasticsearch .xpack .esql .core .type .EsField ;
3535import org .elasticsearch .xpack .esql .expression .function .EsqlFunctionRegistry ;
36+ import org .elasticsearch .xpack .esql .expression .function .scalar .conditional .Case ;
3637import org .elasticsearch .xpack .esql .expression .function .scalar .nulls .Coalesce ;
3738import org .elasticsearch .xpack .esql .expression .function .scalar .string .StartsWith ;
3839import org .elasticsearch .xpack .esql .expression .predicate .operator .arithmetic .Add ;
5657
5758import static java .util .Collections .emptyMap ;
5859import static org .elasticsearch .xpack .esql .EsqlTestUtils .L ;
60+ import static org .elasticsearch .xpack .esql .EsqlTestUtils .ONE ;
5961import static org .elasticsearch .xpack .esql .EsqlTestUtils .TEST_SEARCH_STATS ;
6062import static org .elasticsearch .xpack .esql .EsqlTestUtils .TEST_VERIFIER ;
63+ import static org .elasticsearch .xpack .esql .EsqlTestUtils .THREE ;
64+ import static org .elasticsearch .xpack .esql .EsqlTestUtils .TWO ;
6165import static org .elasticsearch .xpack .esql .EsqlTestUtils .as ;
6266import static org .elasticsearch .xpack .esql .EsqlTestUtils .getFieldAttribute ;
6367import static org .elasticsearch .xpack .esql .EsqlTestUtils .loadMapping ;
@@ -79,10 +83,6 @@ public class LocalLogicalPlanOptimizerTests extends ESTestCase {
7983 private static LogicalPlanOptimizer logicalOptimizer ;
8084 private static Map <String , EsField > mapping ;
8185
82- private static final Literal ONE = L (1 );
83- private static final Literal TWO = L (2 );
84- private static final Literal THREE = L (3 );
85-
8686 @ BeforeClass
8787 public static void init () {
8888 parser = new EsqlParser ();
@@ -365,38 +365,6 @@ public void testMissingFieldInFilterNoProjection() {
365365 );
366366 }
367367
368- public void testIsNotNullOnCoalesce () {
369- var plan = localPlan ("""
370- from test
371- | where coalesce(emp_no, salary) is not null
372- """ );
373-
374- var limit = as (plan , Limit .class );
375- var filter = as (limit .child (), Filter .class );
376- var inn = as (filter .condition (), IsNotNull .class );
377- var coalesce = as (inn .children ().get (0 ), Coalesce .class );
378- assertThat (Expressions .names (coalesce .children ()), contains ("emp_no" , "salary" ));
379- var source = as (filter .child (), EsRelation .class );
380- }
381-
382- public void testIsNotNullOnExpression () {
383- var plan = localPlan ("""
384- from test
385- | eval x = emp_no + 1
386- | where x is not null
387- """ );
388-
389- var limit = as (plan , Limit .class );
390- var filter = as (limit .child (), Filter .class );
391- var inn = as (filter .condition (), IsNotNull .class );
392- assertThat (Expressions .names (inn .children ()), contains ("x" ));
393- var eval = as (filter .child (), Eval .class );
394- filter = as (eval .child (), Filter .class );
395- inn = as (filter .condition (), IsNotNull .class );
396- assertThat (Expressions .names (inn .children ()), contains ("emp_no" ));
397- var source = as (filter .child (), EsRelation .class );
398- }
399-
400368 public void testSparseDocument () throws Exception {
401369 var query = """
402370 from large
@@ -495,6 +463,66 @@ public void testIsNotNullOnFunctionWithTwoFields() {
495463 assertEquals (expected , new LocalLogicalPlanOptimizer .InferIsNotNull ().apply (f ));
496464 }
497465
466+ public void testIsNotNullOnCoalesce () {
467+ var plan = localPlan ("""
468+ from test
469+ | where coalesce(emp_no, salary) is not null
470+ """ );
471+
472+ var limit = as (plan , Limit .class );
473+ var filter = as (limit .child (), Filter .class );
474+ var inn = as (filter .condition (), IsNotNull .class );
475+ var coalesce = as (inn .children ().get (0 ), Coalesce .class );
476+ assertThat (Expressions .names (coalesce .children ()), contains ("emp_no" , "salary" ));
477+ var source = as (filter .child (), EsRelation .class );
478+ }
479+
480+ public void testIsNotNullOnExpression () {
481+ var plan = localPlan ("""
482+ from test
483+ | eval x = emp_no + 1
484+ | where x is not null
485+ """ );
486+
487+ var limit = as (plan , Limit .class );
488+ var filter = as (limit .child (), Filter .class );
489+ var inn = as (filter .condition (), IsNotNull .class );
490+ assertThat (Expressions .names (inn .children ()), contains ("x" ));
491+ var eval = as (filter .child (), Eval .class );
492+ filter = as (eval .child (), Filter .class );
493+ inn = as (filter .condition (), IsNotNull .class );
494+ assertThat (Expressions .names (inn .children ()), contains ("emp_no" ));
495+ var source = as (filter .child (), EsRelation .class );
496+ }
497+
498+ public void testIsNotNullOnCase () {
499+ var plan = localPlan ("""
500+ from test
501+ | where case(emp_no > 10000, "1", salary < 50000, "2", first_name) is not null
502+ """ );
503+
504+ var limit = as (plan , Limit .class );
505+ var filter = as (limit .child (), Filter .class );
506+ var inn = as (filter .condition (), IsNotNull .class );
507+ var caseF = as (inn .children ().get (0 ), Case .class );
508+ assertThat (Expressions .names (caseF .children ()), contains ("emp_no > 10000" , "\" 1\" " , "salary < 50000" , "\" 2\" " , "first_name" ));
509+ var source = as (filter .child (), EsRelation .class );
510+ }
511+
512+ public void testIsNotNullOnCase_With_IS_NULL () {
513+ var plan = localPlan ("""
514+ from test
515+ | where case(emp_no IS NULL, "1", salary IS NOT NULL, "2", first_name) is not null
516+ """ );
517+
518+ var limit = as (plan , Limit .class );
519+ var filter = as (limit .child (), Filter .class );
520+ var inn = as (filter .condition (), IsNotNull .class );
521+ var caseF = as (inn .children ().get (0 ), Case .class );
522+ assertThat (Expressions .names (caseF .children ()), contains ("emp_no IS NULL" , "\" 1\" " , "salary IS NOT NULL" , "\" 2\" " , "first_name" ));
523+ var source = as (filter .child (), EsRelation .class );
524+ }
525+
498526 private IsNotNull isNotNull (Expression field ) {
499527 return new IsNotNull (EMPTY , field );
500528 }
0 commit comments