1111
1212import org .apache .lucene .util .BytesRef ;
1313import org .elasticsearch .common .breaker .NoopCircuitBreaker ;
14+ import org .elasticsearch .common .settings .Settings ;
1415import org .elasticsearch .common .util .BigArrays ;
1516import org .elasticsearch .compute .data .Block ;
1617import org .elasticsearch .compute .data .BlockFactory ;
1718import org .elasticsearch .compute .data .BooleanBlock ;
1819import org .elasticsearch .compute .data .BooleanVector ;
20+ import org .elasticsearch .compute .data .BytesRefBlock ;
21+ import org .elasticsearch .compute .data .BytesRefVector ;
1922import org .elasticsearch .compute .data .DoubleBlock ;
2023import org .elasticsearch .compute .data .DoubleVector ;
2124import org .elasticsearch .compute .data .LongBlock ;
4043import org .elasticsearch .xpack .esql .expression .function .scalar .multivalue .MvMin ;
4144import org .elasticsearch .xpack .esql .expression .function .scalar .nulls .Coalesce ;
4245import org .elasticsearch .xpack .esql .expression .function .scalar .string .RLike ;
46+ import org .elasticsearch .xpack .esql .expression .function .scalar .string .ToLower ;
47+ import org .elasticsearch .xpack .esql .expression .function .scalar .string .ToUpper ;
4348import org .elasticsearch .xpack .esql .expression .predicate .operator .arithmetic .Add ;
4449import org .elasticsearch .xpack .esql .expression .predicate .operator .comparison .Equals ;
4550import org .elasticsearch .xpack .esql .planner .Layout ;
51+ import org .elasticsearch .xpack .esql .plugin .EsqlPlugin ;
52+ import org .elasticsearch .xpack .esql .session .Configuration ;
4653import org .openjdk .jmh .annotations .Benchmark ;
4754import org .openjdk .jmh .annotations .BenchmarkMode ;
4855import org .openjdk .jmh .annotations .Fork ;
5663import org .openjdk .jmh .annotations .Warmup ;
5764
5865import java .time .Duration ;
66+ import java .time .ZoneOffset ;
5967import java .util .Arrays ;
6068import java .util .List ;
69+ import java .util .Locale ;
6170import java .util .Map ;
6271import java .util .concurrent .TimeUnit ;
6372
@@ -106,7 +115,9 @@ public class EvalBenchmark {
106115 "long_equal_to_int" ,
107116 "mv_min" ,
108117 "mv_min_ascending" ,
109- "rlike" }
118+ "rlike" ,
119+ "to_lower" ,
120+ "to_upper" }
110121 )
111122 public String operation ;
112123
@@ -169,7 +180,7 @@ private static EvalOperator.ExpressionEvaluator evaluator(String operation) {
169180 new Coalesce (Source .EMPTY , lhs , List .of (f2 )),
170181 layout (f1 , f2 )
171182 ).get (driverContext );
172- String desc = operation .endsWith ("lazy" ) ? "CoalesceLazyEvaluator " : "CoalesceEagerEvaluator " ;
183+ String desc = operation .endsWith ("lazy" ) ? "CoalesceLongLazyEvaluator " : "CoalesceLongEagerEvaluator " ;
173184 if (evaluator .toString ().contains (desc ) == false ) {
174185 throw new IllegalArgumentException ("Evaluator was [" + evaluator + "] but expected one containing [" + desc + "]" );
175186 }
@@ -214,6 +225,16 @@ private static EvalOperator.ExpressionEvaluator evaluator(String operation) {
214225 RLike rlike = new RLike (Source .EMPTY , keywordField , new RLikePattern (".ar" ));
215226 yield EvalMapper .toEvaluator (FOLD_CONTEXT , rlike , layout (keywordField )).get (driverContext );
216227 }
228+ case "to_lower" -> {
229+ FieldAttribute keywordField = keywordField ();
230+ ToLower toLower = new ToLower (Source .EMPTY , keywordField , configuration ());
231+ yield EvalMapper .toEvaluator (FOLD_CONTEXT , toLower , layout (keywordField )).get (driverContext );
232+ }
233+ case "to_upper" -> {
234+ FieldAttribute keywordField = keywordField ();
235+ ToUpper toUpper = new ToUpper (Source .EMPTY , keywordField , configuration ());
236+ yield EvalMapper .toEvaluator (FOLD_CONTEXT , toUpper , layout (keywordField )).get (driverContext );
237+ }
217238 default -> throw new UnsupportedOperationException ();
218239 };
219240 }
@@ -234,6 +255,23 @@ private static FieldAttribute keywordField() {
234255 return new FieldAttribute (Source .EMPTY , "keyword" , new EsField ("keyword" , DataType .KEYWORD , Map .of (), true ));
235256 }
236257
258+ private static Configuration configuration () {
259+ return new Configuration (
260+ ZoneOffset .UTC ,
261+ Locale .ROOT ,
262+ null ,
263+ null ,
264+ null ,
265+ EsqlPlugin .QUERY_RESULT_TRUNCATION_MAX_SIZE .get (Settings .EMPTY ),
266+ EsqlPlugin .QUERY_RESULT_TRUNCATION_DEFAULT_SIZE .get (Settings .EMPTY ),
267+ null ,
268+ false ,
269+ Map .of (),
270+ 0 ,
271+ false
272+ );
273+ }
274+
237275 private static Layout layout (FieldAttribute ... fields ) {
238276 Layout .Builder layout = new Layout .Builder ();
239277 layout .append (Arrays .asList (fields ));
@@ -366,10 +404,24 @@ private static void checkExpected(String operation, Page actual) {
366404 }
367405 }
368406 }
407+ case "to_lower" -> checkBytes (operation , actual , new BytesRef [] { new BytesRef ("foo" ), new BytesRef ("bar" ) });
408+ case "to_upper" -> checkBytes (operation , actual , new BytesRef [] { new BytesRef ("FOO" ), new BytesRef ("BAR" ) });
369409 default -> throw new UnsupportedOperationException (operation );
370410 }
371411 }
372412
413+ private static void checkBytes (String operation , Page actual , BytesRef [] expectedVals ) {
414+ BytesRef scratch = new BytesRef ();
415+ BytesRefVector v = actual .<BytesRefBlock >getBlock (1 ).asVector ();
416+ for (int i = 0 ; i < BLOCK_LENGTH ; i ++) {
417+ BytesRef expected = expectedVals [i % 2 ];
418+ BytesRef b = v .getBytesRef (i , scratch );
419+ if (b .equals (expected ) == false ) {
420+ throw new AssertionError ("[" + operation + "] expected [" + expected + "] but was [" + b + "]" );
421+ }
422+ }
423+ }
424+
373425 private static Page page (String operation ) {
374426 return switch (operation ) {
375427 case "abs" , "add" , "date_trunc" , "equal_to_const" -> {
@@ -440,7 +492,7 @@ private static Page page(String operation) {
440492 }
441493 yield new Page (builder .build ());
442494 }
443- case "rlike" -> {
495+ case "rlike" , "to_lower" , "to_upper" -> {
444496 var builder = blockFactory .newBytesRefVectorBuilder (BLOCK_LENGTH );
445497 BytesRef [] values = new BytesRef [] { new BytesRef ("foo" ), new BytesRef ("bar" ) };
446498 for (int i = 0 ; i < BLOCK_LENGTH ; i ++) {
0 commit comments