1212import org .elasticsearch .compute .data .AggregateMetricDoubleBlockBuilder ;
1313import org .elasticsearch .compute .data .Block ;
1414import org .elasticsearch .compute .data .DoubleBlock ;
15+ import org .elasticsearch .compute .data .IntBlock ;
16+ import org .elasticsearch .compute .data .LongBlock ;
1517import org .elasticsearch .compute .data .Page ;
1618import org .elasticsearch .compute .operator .DriverContext ;
1719import org .elasticsearch .compute .operator .EvalOperator ;
2325import org .elasticsearch .xpack .esql .core .type .DataType ;
2426import org .elasticsearch .xpack .esql .expression .function .FunctionInfo ;
2527import org .elasticsearch .xpack .esql .expression .function .Param ;
26- import org .elasticsearch .xpack .esql .expression . function . scalar . math . Cast ;
28+ import org .elasticsearch .xpack .esql .type . EsqlDataTypeConverter ;
2729
2830import java .io .IOException ;
2931import java .util .List ;
@@ -42,9 +44,9 @@ public class ToAggregateMetricDouble extends AbstractConvertFunction {
4244 private static final Map <DataType , AbstractConvertFunction .BuildFactory > EVALUATORS = Map .ofEntries (
4345 Map .entry (AGGREGATE_METRIC_DOUBLE , (source , fieldEval ) -> fieldEval ),
4446 Map .entry (DOUBLE , DoubleFactory ::new ),
45- Map .entry (INTEGER , (( source , fieldEval ) -> new DoubleFactory ( source , Cast . cast ( source , INTEGER , DOUBLE , fieldEval ))) ),
46- Map .entry (LONG , (( source , fieldEval ) -> new DoubleFactory ( source , Cast . cast ( source , LONG , DOUBLE , fieldEval ))) ),
47- Map .entry (UNSIGNED_LONG , (( source , fieldEval ) -> new DoubleFactory ( source , Cast . cast ( source , UNSIGNED_LONG , DOUBLE , fieldEval ))) )
47+ Map .entry (INTEGER , IntFactory :: new ),
48+ Map .entry (LONG , LongFactory :: new ),
49+ Map .entry (UNSIGNED_LONG , UnsignedLongFactory :: new )
4850 );
4951
5052 public static final NamedWriteableRegistry .Entry ENTRY = new NamedWriteableRegistry .Entry (
@@ -120,7 +122,7 @@ public DoubleFactory(Source source, EvalOperator.ExpressionEvaluator.Factory fie
120122
121123 @ Override
122124 public String toString () {
123- return "ToAggregateMetricDoubleEvaluator [" + "field=" + fieldEvaluator + "]" ;
125+ return "ToAggregateMetricDoubleFromDoubleEvaluator [" + "field=" + fieldEvaluator + "]" ;
124126 }
125127
126128 @ Override
@@ -172,7 +174,217 @@ public void close() {
172174
173175 @ Override
174176 public String toString () {
175- return "ToAggregateMetricDoubleEvaluator[field=" + eval + "]" ;
177+ return "ToAggregateMetricDoubleFromDoubleEvaluator[field=" + eval + "]" ;
178+ }
179+ };
180+ }
181+ }
182+
183+ public static class IntFactory implements EvalOperator .ExpressionEvaluator .Factory {
184+ private final Source source ;
185+
186+ private final EvalOperator .ExpressionEvaluator .Factory fieldEvaluator ;
187+
188+ public IntFactory (Source source , EvalOperator .ExpressionEvaluator .Factory fieldEvaluator ) {
189+ this .fieldEvaluator = fieldEvaluator ;
190+ this .source = source ;
191+ }
192+
193+ @ Override
194+ public String toString () {
195+ return "ToAggregateMetricDoubleFromIntEvaluator[" + "field=" + fieldEvaluator + "]" ;
196+ }
197+
198+ @ Override
199+ public EvalOperator .ExpressionEvaluator get (DriverContext context ) {
200+ final EvalOperator .ExpressionEvaluator eval = fieldEvaluator .get (context );
201+
202+ return new EvalOperator .ExpressionEvaluator () {
203+ @ Override
204+ public Block eval (Page page ) {
205+ try (Block block = eval .eval (page )) {
206+ int positionCount = block .getPositionCount ();
207+ IntBlock intBlock = (IntBlock ) block ;
208+ try (
209+ AggregateMetricDoubleBlockBuilder result = context .blockFactory ()
210+ .newAggregateMetricDoubleBlockBuilder (positionCount )
211+ ) {
212+ CompensatedSum sum = new CompensatedSum ();
213+ for (int p = 0 ; p < positionCount ; p ++) {
214+ int valueCount = intBlock .getValueCount (p );
215+ int start = intBlock .getFirstValueIndex (p );
216+ int end = start + valueCount ;
217+ if (valueCount == 0 ) {
218+ result .appendNull ();
219+ continue ;
220+ }
221+ double min = Double .POSITIVE_INFINITY ;
222+ double max = Double .NEGATIVE_INFINITY ;
223+ for (int i = start ; i < end ; i ++) {
224+ double current = intBlock .getInt (i );
225+ min = Math .min (min , current );
226+ max = Math .max (max , current );
227+ sum .add (current );
228+ }
229+ result .min ().appendDouble (min );
230+ result .max ().appendDouble (max );
231+ result .sum ().appendDouble (sum .value ());
232+ result .count ().appendInt (valueCount );
233+ sum .reset (0 , 0 );
234+ }
235+ return result .build ();
236+ }
237+ }
238+ }
239+
240+ @ Override
241+ public void close () {
242+ Releasables .closeExpectNoException (eval );
243+ }
244+
245+ @ Override
246+ public String toString () {
247+ return "ToAggregateMetricDoubleFromIntEvaluator[field=" + eval + "]" ;
248+ }
249+ };
250+ }
251+ }
252+
253+ public static class LongFactory implements EvalOperator .ExpressionEvaluator .Factory {
254+ private final Source source ;
255+
256+ private final EvalOperator .ExpressionEvaluator .Factory fieldEvaluator ;
257+
258+ public LongFactory (Source source , EvalOperator .ExpressionEvaluator .Factory fieldEvaluator ) {
259+ this .fieldEvaluator = fieldEvaluator ;
260+ this .source = source ;
261+ }
262+
263+ @ Override
264+ public String toString () {
265+ return "ToAggregateMetricDoubleFromLongEvaluator[" + "field=" + fieldEvaluator + "]" ;
266+ }
267+
268+ @ Override
269+ public EvalOperator .ExpressionEvaluator get (DriverContext context ) {
270+ final EvalOperator .ExpressionEvaluator eval = fieldEvaluator .get (context );
271+
272+ return new EvalOperator .ExpressionEvaluator () {
273+ @ Override
274+ public Block eval (Page page ) {
275+ try (Block block = eval .eval (page )) {
276+ int positionCount = block .getPositionCount ();
277+ LongBlock longBlock = (LongBlock ) block ;
278+ try (
279+ AggregateMetricDoubleBlockBuilder result = context .blockFactory ()
280+ .newAggregateMetricDoubleBlockBuilder (positionCount )
281+ ) {
282+ CompensatedSum sum = new CompensatedSum ();
283+ for (int p = 0 ; p < positionCount ; p ++) {
284+ int valueCount = longBlock .getValueCount (p );
285+ int start = longBlock .getFirstValueIndex (p );
286+ int end = start + valueCount ;
287+ if (valueCount == 0 ) {
288+ result .appendNull ();
289+ continue ;
290+ }
291+ double min = Double .POSITIVE_INFINITY ;
292+ double max = Double .NEGATIVE_INFINITY ;
293+ for (int i = start ; i < end ; i ++) {
294+ double current = longBlock .getLong (i );
295+ min = Math .min (min , current );
296+ max = Math .max (max , current );
297+ sum .add (current );
298+ }
299+ result .min ().appendDouble (min );
300+ result .max ().appendDouble (max );
301+ result .sum ().appendDouble (sum .value ());
302+ result .count ().appendInt (valueCount );
303+ sum .reset (0 , 0 );
304+ }
305+ return result .build ();
306+ }
307+ }
308+ }
309+
310+ @ Override
311+ public void close () {
312+ Releasables .closeExpectNoException (eval );
313+ }
314+
315+ @ Override
316+ public String toString () {
317+ return "ToAggregateMetricDoubleFromLongEvaluator[field=" + eval + "]" ;
318+ }
319+ };
320+ }
321+ }
322+
323+ public static class UnsignedLongFactory implements EvalOperator .ExpressionEvaluator .Factory {
324+ private final Source source ;
325+
326+ private final EvalOperator .ExpressionEvaluator .Factory fieldEvaluator ;
327+
328+ public UnsignedLongFactory (Source source , EvalOperator .ExpressionEvaluator .Factory fieldEvaluator ) {
329+ this .fieldEvaluator = fieldEvaluator ;
330+ this .source = source ;
331+ }
332+
333+ @ Override
334+ public String toString () {
335+ return "ToAggregateMetricDoubleFromUnsignedLongEvaluator[" + "field=" + fieldEvaluator + "]" ;
336+ }
337+
338+ @ Override
339+ public EvalOperator .ExpressionEvaluator get (DriverContext context ) {
340+ final EvalOperator .ExpressionEvaluator eval = fieldEvaluator .get (context );
341+
342+ return new EvalOperator .ExpressionEvaluator () {
343+ @ Override
344+ public Block eval (Page page ) {
345+ try (Block block = eval .eval (page )) {
346+ int positionCount = block .getPositionCount ();
347+ LongBlock longBlock = (LongBlock ) block ;
348+ try (
349+ AggregateMetricDoubleBlockBuilder result = context .blockFactory ()
350+ .newAggregateMetricDoubleBlockBuilder (positionCount )
351+ ) {
352+ CompensatedSum sum = new CompensatedSum ();
353+ for (int p = 0 ; p < positionCount ; p ++) {
354+ int valueCount = longBlock .getValueCount (p );
355+ int start = longBlock .getFirstValueIndex (p );
356+ int end = start + valueCount ;
357+ if (valueCount == 0 ) {
358+ result .appendNull ();
359+ continue ;
360+ }
361+ double min = Double .POSITIVE_INFINITY ;
362+ double max = Double .NEGATIVE_INFINITY ;
363+ for (int i = start ; i < end ; i ++) {
364+ var current = EsqlDataTypeConverter .unsignedLongToDouble (longBlock .getLong (p ));
365+ min = Math .min (min , current );
366+ max = Math .max (max , current );
367+ sum .add (current );
368+ }
369+ result .min ().appendDouble (min );
370+ result .max ().appendDouble (max );
371+ result .sum ().appendDouble (sum .value ());
372+ result .count ().appendInt (valueCount );
373+ sum .reset (0 , 0 );
374+ }
375+ return result .build ();
376+ }
377+ }
378+ }
379+
380+ @ Override
381+ public void close () {
382+ Releasables .closeExpectNoException (eval );
383+ }
384+
385+ @ Override
386+ public String toString () {
387+ return "ToAggregateMetricDoubleFromUnsignedLongEvaluator[field=" + eval + "]" ;
176388 }
177389 };
178390 }
0 commit comments