2929import org .elasticsearch .xpack .esql .core .type .DataType ;
3030import org .elasticsearch .xpack .esql .core .type .EsField ;
3131import org .elasticsearch .xpack .esql .expression .function .EsqlFunctionRegistry ;
32+ import org .elasticsearch .xpack .esql .expression .function .scalar .conditional .Case ;
3233import org .elasticsearch .xpack .esql .expression .function .scalar .nulls .Coalesce ;
3334import org .elasticsearch .xpack .esql .expression .function .scalar .string .StartsWith ;
3435import org .elasticsearch .xpack .esql .expression .predicate .operator .arithmetic .Add ;
5859
5960import static java .util .Collections .emptyMap ;
6061import static org .elasticsearch .xpack .esql .EsqlTestUtils .L ;
62+ import static org .elasticsearch .xpack .esql .EsqlTestUtils .ONE ;
6163import static org .elasticsearch .xpack .esql .EsqlTestUtils .TEST_SEARCH_STATS ;
6264import static org .elasticsearch .xpack .esql .EsqlTestUtils .TEST_VERIFIER ;
65+ import static org .elasticsearch .xpack .esql .EsqlTestUtils .THREE ;
66+ import static org .elasticsearch .xpack .esql .EsqlTestUtils .TWO ;
6367import static org .elasticsearch .xpack .esql .EsqlTestUtils .as ;
6468import static org .elasticsearch .xpack .esql .EsqlTestUtils .getFieldAttribute ;
6569import static org .elasticsearch .xpack .esql .EsqlTestUtils .greaterThanOf ;
@@ -81,10 +85,6 @@ public class LocalLogicalPlanOptimizerTests extends ESTestCase {
8185 private static LogicalPlanOptimizer logicalOptimizer ;
8286 private static Map <String , EsField > mapping ;
8387
84- private static final Literal ONE = L (1 );
85- private static final Literal TWO = L (2 );
86- private static final Literal THREE = L (3 );
87-
8888 @ BeforeClass
8989 public static void init () {
9090 parser = new EsqlParser ();
@@ -386,38 +386,6 @@ public void testMissingFieldInFilterNoProjection() {
386386 );
387387 }
388388
389- public void testIsNotNullOnCoalesce () {
390- var plan = localPlan ("""
391- from test
392- | where coalesce(emp_no, salary) is not null
393- """ );
394-
395- var limit = as (plan , Limit .class );
396- var filter = as (limit .child (), Filter .class );
397- var inn = as (filter .condition (), IsNotNull .class );
398- var coalesce = as (inn .children ().get (0 ), Coalesce .class );
399- assertThat (Expressions .names (coalesce .children ()), contains ("emp_no" , "salary" ));
400- var source = as (filter .child (), EsRelation .class );
401- }
402-
403- public void testIsNotNullOnExpression () {
404- var plan = localPlan ("""
405- from test
406- | eval x = emp_no + 1
407- | where x is not null
408- """ );
409-
410- var limit = as (plan , Limit .class );
411- var filter = as (limit .child (), Filter .class );
412- var inn = as (filter .condition (), IsNotNull .class );
413- assertThat (Expressions .names (inn .children ()), contains ("x" ));
414- var eval = as (filter .child (), Eval .class );
415- filter = as (eval .child (), Filter .class );
416- inn = as (filter .condition (), IsNotNull .class );
417- assertThat (Expressions .names (inn .children ()), contains ("emp_no" ));
418- var source = as (filter .child (), EsRelation .class );
419- }
420-
421389 public void testSparseDocument () throws Exception {
422390 var query = """
423391 from large
@@ -516,6 +484,66 @@ public void testIsNotNullOnFunctionWithTwoFields() {
516484 assertEquals (expected , new InferIsNotNull ().apply (f ));
517485 }
518486
487+ public void testIsNotNullOnCoalesce () {
488+ var plan = localPlan ("""
489+ from test
490+ | where coalesce(emp_no, salary) is not null
491+ """ );
492+
493+ var limit = as (plan , Limit .class );
494+ var filter = as (limit .child (), Filter .class );
495+ var inn = as (filter .condition (), IsNotNull .class );
496+ var coalesce = as (inn .children ().get (0 ), Coalesce .class );
497+ assertThat (Expressions .names (coalesce .children ()), contains ("emp_no" , "salary" ));
498+ var source = as (filter .child (), EsRelation .class );
499+ }
500+
501+ public void testIsNotNullOnExpression () {
502+ var plan = localPlan ("""
503+ from test
504+ | eval x = emp_no + 1
505+ | where x is not null
506+ """ );
507+
508+ var limit = as (plan , Limit .class );
509+ var filter = as (limit .child (), Filter .class );
510+ var inn = as (filter .condition (), IsNotNull .class );
511+ assertThat (Expressions .names (inn .children ()), contains ("x" ));
512+ var eval = as (filter .child (), Eval .class );
513+ filter = as (eval .child (), Filter .class );
514+ inn = as (filter .condition (), IsNotNull .class );
515+ assertThat (Expressions .names (inn .children ()), contains ("emp_no" ));
516+ var source = as (filter .child (), EsRelation .class );
517+ }
518+
519+ public void testIsNotNullOnCase () {
520+ var plan = localPlan ("""
521+ from test
522+ | where case(emp_no > 10000, "1", salary < 50000, "2", first_name) is not null
523+ """ );
524+
525+ var limit = as (plan , Limit .class );
526+ var filter = as (limit .child (), Filter .class );
527+ var inn = as (filter .condition (), IsNotNull .class );
528+ var caseF = as (inn .children ().get (0 ), Case .class );
529+ assertThat (Expressions .names (caseF .children ()), contains ("emp_no > 10000" , "\" 1\" " , "salary < 50000" , "\" 2\" " , "first_name" ));
530+ var source = as (filter .child (), EsRelation .class );
531+ }
532+
533+ public void testIsNotNullOnCase_With_IS_NULL () {
534+ var plan = localPlan ("""
535+ from test
536+ | where case(emp_no IS NULL, "1", salary IS NOT NULL, "2", first_name) is not null
537+ """ );
538+
539+ var limit = as (plan , Limit .class );
540+ var filter = as (limit .child (), Filter .class );
541+ var inn = as (filter .condition (), IsNotNull .class );
542+ var caseF = as (inn .children ().get (0 ), Case .class );
543+ assertThat (Expressions .names (caseF .children ()), contains ("emp_no IS NULL" , "\" 1\" " , "salary IS NOT NULL" , "\" 2\" " , "first_name" ));
544+ var source = as (filter .child (), EsRelation .class );
545+ }
546+
519547 private IsNotNull isNotNull (Expression field ) {
520548 return new IsNotNull (EMPTY , field );
521549 }
0 commit comments