3737import org .elasticsearch .xpack .esql .expression .function .scalar .nulls .Coalesce ;
3838import org .elasticsearch .xpack .esql .expression .function .scalar .string .StartsWith ;
3939import org .elasticsearch .xpack .esql .expression .function .scalar .string .regex .RLike ;
40+ import org .elasticsearch .xpack .esql .expression .function .scalar .string .regex .RLikeList ;
4041import org .elasticsearch .xpack .esql .expression .function .scalar .string .regex .WildcardLike ;
42+ import org .elasticsearch .xpack .esql .expression .function .scalar .string .regex .WildcardLikeList ;
4143import org .elasticsearch .xpack .esql .expression .predicate .logical .And ;
4244import org .elasticsearch .xpack .esql .expression .predicate .nulls .IsNotNull ;
4345import org .elasticsearch .xpack .esql .expression .predicate .operator .arithmetic .Add ;
@@ -665,6 +667,26 @@ public void testReplaceUpperStringCasinqgWithInsensitiveRLike() {
665667 var source = as (filter .child (), EsRelation .class );
666668 }
667669
670+ /*
671+ *Limit[1000[INTEGER],false]
672+ * \_Filter[RLikeList(first_name{f}#4, "("VALÜ*", "VALÜAA*")", true)]
673+ * \_EsRelation[test][_meta_field{f}#9, emp_no{f}#3, first_name{f}#4, gen..]
674+ */
675+ public void testReplaceUpperStringCasinqWithInsensitiveRLikeList () {
676+ var plan = localPlan ("FROM test | WHERE TO_UPPER(TO_LOWER(TO_UPPER(first_name))) RLIKE (\" VALÜ*\" , \" TEST*\" )" );
677+
678+ var limit = as (plan , Limit .class );
679+ var filter = as (limit .child (), Filter .class );
680+ var rLikeList = as (filter .condition (), RLikeList .class );
681+ var field = as (rLikeList .field (), FieldAttribute .class );
682+ assertThat (field .fieldName ().string (), is ("first_name" ));
683+ assertEquals (2 , rLikeList .pattern ().patternList ().size ());
684+ assertThat (rLikeList .pattern ().patternList ().get (0 ).pattern (), is ("VALÜ*" ));
685+ assertThat (rLikeList .pattern ().patternList ().get (1 ).pattern (), is ("TEST*" ));
686+ assertThat (rLikeList .caseInsensitive (), is (true ));
687+ var source = as (filter .child (), EsRelation .class );
688+ }
689+
668690 // same plan as above, but lower case pattern
669691 public void testReplaceLowerStringCasingWithInsensitiveRLike () {
670692 var plan = localPlan ("FROM test | WHERE TO_LOWER(TO_UPPER(first_name)) RLIKE \" valü*\" " );
@@ -679,6 +701,35 @@ public void testReplaceLowerStringCasingWithInsensitiveRLike() {
679701 var source = as (filter .child (), EsRelation .class );
680702 }
681703
704+ // same plan as above, but lower case pattern and list of patterns
705+ public void testReplaceLowerStringCasingWithInsensitiveRLikeList () {
706+ var plan = localPlan ("FROM test | WHERE TO_LOWER(TO_UPPER(first_name)) RLIKE (\" valü*\" , \" test*\" )" );
707+ var limit = as (plan , Limit .class );
708+ var filter = as (limit .child (), Filter .class );
709+ var rLikeList = as (filter .condition (), RLikeList .class );
710+ var field = as (rLikeList .field (), FieldAttribute .class );
711+ assertThat (field .fieldName ().string (), is ("first_name" ));
712+ assertEquals (2 , rLikeList .pattern ().patternList ().size ());
713+ assertThat (rLikeList .pattern ().patternList ().get (0 ).pattern (), is ("valü*" ));
714+ assertThat (rLikeList .pattern ().patternList ().get (1 ).pattern (), is ("test*" ));
715+ assertThat (rLikeList .caseInsensitive (), is (true ));
716+ var source = as (filter .child (), EsRelation .class );
717+ }
718+
719+ // same plan as above, but lower case pattern and list of patterns, one of which is upper case
720+ public void testReplaceLowerStringCasingWithMixedCaseRLikeList () {
721+ var plan = localPlan ("FROM test | WHERE TO_LOWER(TO_UPPER(first_name)) RLIKE (\" valü*\" , \" TEST*\" )" );
722+ var limit = as (plan , Limit .class );
723+ var filter = as (limit .child (), Filter .class );
724+ var rLikeList = as (filter .condition (), RLikeList .class );
725+ var field = as (rLikeList .field (), FieldAttribute .class );
726+ assertThat (field .fieldName ().string (), is ("first_name" ));
727+ assertEquals (1 , rLikeList .pattern ().patternList ().size ());
728+ assertThat (rLikeList .pattern ().patternList ().get (0 ).pattern (), is ("valü*" ));
729+ assertThat (rLikeList .caseInsensitive (), is (true ));
730+ var source = as (filter .child (), EsRelation .class );
731+ }
732+
682733 /**
683734 * LocalRelation[[_meta_field{f}#9, emp_no{f}#3, first_name{f}#4, gender{f}#5, hire_date{f}#10, job{f}#11, job.raw{f}#12, langu
684735 * ages{f}#6, last_name{f}#7, long_noidx{f}#13, salary{f}#8],EMPTY]
@@ -704,6 +755,37 @@ public void testReplaceUpperStringCasingWithInsensitiveLike() {
704755 var source = as (filter .child (), EsRelation .class );
705756 }
706757
758+ // same plan as in testReplaceUpperStringCasingWithInsensitiveRLikeList, but with LIKE instead of RLIKE
759+ public void testReplaceUpperStringCasingWithInsensitiveLikeList () {
760+ var plan = localPlan ("FROM test | WHERE TO_UPPER(TO_LOWER(TO_UPPER(first_name))) LIKE (\" VALÜ*\" , \" TEST*\" )" );
761+
762+ var limit = as (plan , Limit .class );
763+ var filter = as (limit .child (), Filter .class );
764+ var likeList = as (filter .condition (), WildcardLikeList .class );
765+ var field = as (likeList .field (), FieldAttribute .class );
766+ assertThat (field .fieldName ().string (), is ("first_name" ));
767+ assertEquals (2 , likeList .pattern ().patternList ().size ());
768+ assertThat (likeList .pattern ().patternList ().get (0 ).pattern (), is ("VALÜ*" ));
769+ assertThat (likeList .pattern ().patternList ().get (1 ).pattern (), is ("TEST*" ));
770+ assertThat (likeList .caseInsensitive (), is (true ));
771+ var source = as (filter .child (), EsRelation .class );
772+ }
773+
774+ // same plan as above, but mixed case pattern and list of patterns
775+ public void testReplaceLowerStringCasingWithMixedCaseLikeList () {
776+ var plan = localPlan ("FROM test | WHERE TO_LOWER(TO_UPPER(first_name)) RLIKE (\" TEST*\" , \" valü*\" , \" vaLü*\" )" );
777+ var limit = as (plan , Limit .class );
778+ var filter = as (limit .child (), Filter .class );
779+ var rLikeList = as (filter .condition (), RLikeList .class );
780+ var field = as (rLikeList .field (), FieldAttribute .class );
781+ assertThat (field .fieldName ().string (), is ("first_name" ));
782+ // only the all lowercase pattern is kept, the mixed case and all uppercase patterns are ignored
783+ assertEquals (1 , rLikeList .pattern ().patternList ().size ());
784+ assertThat (rLikeList .pattern ().patternList ().get (0 ).pattern (), is ("valü*" ));
785+ assertThat (rLikeList .caseInsensitive (), is (true ));
786+ var source = as (filter .child (), EsRelation .class );
787+ }
788+
707789 // same plan as above, but lower case pattern
708790 public void testReplaceLowerStringCasingWithInsensitiveLike () {
709791 var plan = localPlan ("FROM test | WHERE TO_LOWER(TO_UPPER(first_name)) LIKE \" valü*\" " );
@@ -729,6 +811,17 @@ public void testReplaceStringCasingAndLikeWithLocalRelation() {
729811 assertThat (local .supplier (), equalTo (EmptyLocalSupplier .EMPTY ));
730812 }
731813
814+ /**
815+ * LocalRelation[[_meta_field{f}#9, emp_no{f}#3, first_name{f}#4, gender{f}#5, hire_date{f}#10, job{f}#11, job.raw{f}#12, langu
816+ * ages{f}#6, last_name{f}#7, long_noidx{f}#13, salary{f}#8],EMPTY]
817+ */
818+ public void testReplaceStringCasingAndLikeListWithLocalRelation () {
819+ var plan = localPlan ("FROM test | WHERE TO_LOWER(TO_UPPER(first_name)) LIKE (\" VALÜ*\" , \" TEST*\" )" );
820+
821+ var local = as (plan , LocalRelation .class );
822+ assertThat (local .supplier (), equalTo (EmptyLocalSupplier .EMPTY ));
823+ }
824+
732825 /**
733826 * Limit[1000[INTEGER],false]
734827 * \_Aggregate[[],[SUM($$integer_long_field$converted_to$long{f$}#5,true[BOOLEAN]) AS sum(integer_long_field::long)#3]]
0 commit comments