1212import org .elasticsearch .common .io .stream .StreamInput ;
1313import org .elasticsearch .common .io .stream .StreamOutput ;
1414import org .elasticsearch .compute .ann .Evaluator ;
15+ import org .elasticsearch .compute .operator .EvalOperator ;
1516import org .elasticsearch .compute .operator .EvalOperator .ExpressionEvaluator ;
1617import org .elasticsearch .xpack .esql .EsqlIllegalArgumentException ;
1718import org .elasticsearch .xpack .esql .core .expression .Expression ;
3031
3132import java .io .IOException ;
3233import java .util .List ;
34+ import java .util .Map ;
35+ import java .util .Set ;
36+ import java .util .function .BiFunction ;
37+ import java .util .function .Function ;
3338import java .util .stream .Stream ;
3439
3540import static org .elasticsearch .xpack .esql .core .type .DataType .NULL ;
@@ -42,6 +47,17 @@ public class Least extends EsqlScalarFunction implements OptionalArgument {
4247
4348 private DataType dataType ;
4449
50+ private static final Map <DataType , Function <ExpressionEvaluator .Factory [], ExpressionEvaluator .Factory >> EVALUATOR_MAP = Map .of (
51+ DataType .BOOLEAN , factories -> new LeastBooleanEvaluator .Factory (Source .EMPTY , factories ),
52+ DataType .DOUBLE , factories -> new LeastDoubleEvaluator .Factory (Source .EMPTY , factories ),
53+ DataType .INTEGER , factories -> new LeastIntEvaluator .Factory (Source .EMPTY , factories ),
54+ DataType .LONG , factories -> new LeastLongEvaluator .Factory (Source .EMPTY , factories ),
55+ DataType .DATETIME , factories -> new LeastLongEvaluator .Factory (Source .EMPTY , factories ),
56+ DataType .DATE_NANOS , factories -> new LeastLongEvaluator .Factory (Source .EMPTY , factories ),
57+ DataType .IP , factories -> new LeastBytesRefEvaluator .Factory (Source .EMPTY , factories ),
58+ DataType .VERSION , factories -> new LeastBytesRefEvaluator .Factory (Source .EMPTY , factories )
59+ );
60+
4561 @ FunctionInfo (
4662 returnType = { "boolean" , "date" , "date_nanos" , "double" , "integer" , "ip" , "keyword" , "long" , "version" },
4763 description = "Returns the minimum value from multiple columns. "
@@ -116,6 +132,11 @@ protected TypeResolution resolveType() {
116132 return resolution ;
117133 }
118134 }
135+
136+ if (dataType != NULL && !EVALUATOR_MAP .containsKey (dataType ) && !DataType .isString (dataType )) {
137+ return new TypeResolution ("Cannot use [" + dataType .typeName () + "] with function [" + getWriteableName () + "]" );
138+ }
139+
119140 return TypeResolution .TYPE_RESOLVED ;
120141 }
121142
@@ -138,27 +159,24 @@ public boolean foldable() {
138159 public ExpressionEvaluator .Factory toEvaluator (ToEvaluator toEvaluator ) {
139160 // force datatype initialization
140161 var dataType = dataType ();
162+ if (dataType == DataType .NULL ) {
163+ throw EsqlIllegalArgumentException .illegalDataType (dataType );
164+ }
141165
142166 ExpressionEvaluator .Factory [] factories = children ().stream ()
143167 .map (e -> toEvaluator .apply (new MvMin (e .source (), e )))
144168 .toArray (ExpressionEvaluator .Factory []::new );
145- if (dataType == DataType .BOOLEAN ) {
146- return new LeastBooleanEvaluator .Factory (source (), factories );
147- }
148- if (dataType == DataType .DOUBLE ) {
149- return new LeastDoubleEvaluator .Factory (source (), factories );
150- }
151- if (dataType == DataType .INTEGER ) {
152- return new LeastIntEvaluator .Factory (source (), factories );
153- }
154- if (dataType == DataType .LONG || dataType == DataType .DATETIME || dataType == DataType .DATE_NANOS ) {
155- return new LeastLongEvaluator .Factory (source (), factories );
156- }
157- if (DataType .isString (dataType ) || dataType == DataType .IP || dataType == DataType .VERSION || dataType == DataType .UNSUPPORTED ) {
158169
170+ if (DataType .isString (dataType )) {
159171 return new LeastBytesRefEvaluator .Factory (source (), factories );
160172 }
161- throw EsqlIllegalArgumentException .illegalDataType (dataType );
173+
174+ var evaluatorFactory = EVALUATOR_MAP .get (dataType );
175+ if (evaluatorFactory == null ) {
176+ throw EsqlIllegalArgumentException .illegalDataType (dataType );
177+ }
178+
179+ return evaluatorFactory .apply (factories );
162180 }
163181
164182 @ Evaluator (extraName = "Boolean" )
0 commit comments