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