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 ;
1715import org .elasticsearch .compute .data .Page ;
1816import org .elasticsearch .compute .operator .DriverContext ;
1917import org .elasticsearch .compute .operator .EvalOperator ;
2018import org .elasticsearch .core .Releasables ;
19+ import org .elasticsearch .search .aggregations .metrics .CompensatedSum ;
2120import org .elasticsearch .xpack .esql .core .expression .Expression ;
2221import org .elasticsearch .xpack .esql .core .tree .NodeInfo ;
2322import org .elasticsearch .xpack .esql .core .tree .Source ;
2423import org .elasticsearch .xpack .esql .core .type .DataType ;
2524import org .elasticsearch .xpack .esql .expression .function .FunctionInfo ;
2625import org .elasticsearch .xpack .esql .expression .function .Param ;
27- import org .elasticsearch .xpack .esql .type . EsqlDataTypeConverter ;
26+ import org .elasticsearch .xpack .esql .expression . function . scalar . math . Cast ;
2827
2928import java .io .IOException ;
3029import java .util .List ;
@@ -43,9 +42,9 @@ public class ToAggregateMetricDouble extends AbstractConvertFunction {
4342 private static final Map <DataType , AbstractConvertFunction .BuildFactory > EVALUATORS = Map .ofEntries (
4443 Map .entry (AGGREGATE_METRIC_DOUBLE , (source , fieldEval ) -> fieldEval ),
4544 Map .entry (DOUBLE , DoubleFactory ::new ),
46- Map .entry (INTEGER , IntFactory :: new ),
47- Map .entry (LONG , LongFactory :: new ),
48- Map .entry (UNSIGNED_LONG , UnsignedLongFactory :: 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 ))) )
4948 );
5049
5150 public static final NamedWriteableRegistry .Entry ENTRY = new NamedWriteableRegistry .Entry (
@@ -121,7 +120,7 @@ public DoubleFactory(Source source, EvalOperator.ExpressionEvaluator.Factory fie
121120
122121 @ Override
123122 public String toString () {
124- return "ToAggregateMetricDoubleFromDoubleEvaluator [" + "field=" + fieldEvaluator + "]" ;
123+ return "ToAggregateMetricDoubleEvaluator [" + "field=" + fieldEvaluator + "]" ;
125124 }
126125
127126 @ Override
@@ -131,228 +130,38 @@ public EvalOperator.ExpressionEvaluator get(DriverContext context) {
131130 return new EvalOperator .ExpressionEvaluator () {
132131 @ Override
133132 public Block eval (Page page ) {
134- Block block = eval .eval (page );
135- int positionCount = page .getPositionCount ();
136- try {
133+ try (Block block = eval .eval (page )) {
134+ int positionCount = block .getPositionCount ();
137135 DoubleBlock doubleBlock = (DoubleBlock ) block ;
138136 try (
139137 AggregateMetricDoubleBlockBuilder result = context .blockFactory ()
140138 .newAggregateMetricDoubleBlockBuilder (positionCount )
141139 ) {
140+ CompensatedSum sum = new CompensatedSum ();
142141 for (int p = 0 ; p < positionCount ; p ++) {
143- try {
144- if (doubleBlock .isNull (p )) {
145- result .appendNull ();
146- continue ;
147- }
148- var val = doubleBlock .getDouble (p );
149- result .min ().appendDouble (val );
150- result .max ().appendDouble (val );
151- result .sum ().appendDouble (val );
152- result .count ().appendInt (1 );
153- } catch (Exception e ) {
142+ int valueCount = doubleBlock .getValueCount (p );
143+ int start = doubleBlock .getFirstValueIndex (p );
144+ int end = start + valueCount ;
145+ if (valueCount == 0 ) {
154146 result .appendNull ();
147+ continue ;
155148 }
156- }
157- return result .build ();
158- }
159- } finally {
160- block .close ();
161- }
162- }
163-
164- @ Override
165- public void close () {
166- Releasables .closeExpectNoException (eval );
167- }
168-
169- @ Override
170- public String toString () {
171- return "ToAggregateMetricDoubleFromDoubleEvaluator[field=" + eval + "]" ;
172- }
173- };
174- }
175- }
176-
177- public static class LongFactory implements EvalOperator .ExpressionEvaluator .Factory {
178- private final Source source ;
179-
180- private final EvalOperator .ExpressionEvaluator .Factory fieldEvaluator ;
181-
182- public LongFactory (Source source , EvalOperator .ExpressionEvaluator .Factory fieldEvaluator ) {
183- this .fieldEvaluator = fieldEvaluator ;
184- this .source = source ;
185- }
186-
187- @ Override
188- public String toString () {
189- return "ToAggregateMetricDoubleFromLongEvaluator[" + "field=" + fieldEvaluator + "]" ;
190- }
191-
192- @ Override
193- public EvalOperator .ExpressionEvaluator get (DriverContext context ) {
194- final EvalOperator .ExpressionEvaluator eval = fieldEvaluator .get (context );
195-
196- return new EvalOperator .ExpressionEvaluator () {
197- @ Override
198- public Block eval (Page page ) {
199- Block block = eval .eval (page );
200- int positionCount = page .getPositionCount ();
201- try {
202- LongBlock longBlock = (LongBlock ) block ;
203- try (
204- AggregateMetricDoubleBlockBuilder result = context .blockFactory ()
205- .newAggregateMetricDoubleBlockBuilder (positionCount )
206- ) {
207- for (int p = 0 ; p < positionCount ; p ++) {
208- try {
209- if (longBlock .isNull (p )) {
210- result .appendNull ();
211- continue ;
212- }
213- var val = longBlock .getLong (p );
214- result .min ().appendDouble (val );
215- result .max ().appendDouble (val );
216- result .sum ().appendDouble (val );
217- result .count ().appendInt (1 );
218- } catch (Exception e ) {
219- result .appendNull ();
220- }
221- }
222- return result .build ();
223- }
224- } finally {
225- block .close ();
226- }
227- }
228-
229- @ Override
230- public void close () {
231- Releasables .closeExpectNoException (eval );
232- }
233-
234- @ Override
235- public String toString () {
236- return "ToAggregateMetricDoubleFromLongEvaluator[field=" + eval + "]" ;
237- }
238- };
239- }
240- }
241-
242- public static class UnsignedLongFactory implements EvalOperator .ExpressionEvaluator .Factory {
243- private final Source source ;
244-
245- private final EvalOperator .ExpressionEvaluator .Factory fieldEvaluator ;
246-
247- public UnsignedLongFactory (Source source , EvalOperator .ExpressionEvaluator .Factory fieldEvaluator ) {
248- this .fieldEvaluator = fieldEvaluator ;
249- this .source = source ;
250- }
251-
252- @ Override
253- public String toString () {
254- return "ToAggregateMetricDoubleFromUnsignedLongEvaluator[" + "field=" + fieldEvaluator + "]" ;
255- }
256-
257- @ Override
258- public EvalOperator .ExpressionEvaluator get (DriverContext context ) {
259- final EvalOperator .ExpressionEvaluator eval = fieldEvaluator .get (context );
260-
261- return new EvalOperator .ExpressionEvaluator () {
262- @ Override
263- public Block eval (Page page ) {
264- Block block = eval .eval (page );
265- int positionCount = page .getPositionCount ();
266- try {
267- LongBlock longBlock = (LongBlock ) block ;
268- try (
269- AggregateMetricDoubleBlockBuilder result = context .blockFactory ()
270- .newAggregateMetricDoubleBlockBuilder (positionCount )
271- ) {
272- for (int p = 0 ; p < positionCount ; p ++) {
273- try {
274- if (longBlock .isNull (p )) {
275- result .appendNull ();
276- continue ;
277- }
278- var val = EsqlDataTypeConverter .unsignedLongToDouble (longBlock .getLong (p ));
279- result .min ().appendDouble (val );
280- result .max ().appendDouble (val );
281- result .sum ().appendDouble (val );
282- result .count ().appendInt (1 );
283- } catch (Exception e ) {
284- result .appendNull ();
285- }
286- }
287- return result .build ();
288- }
289- } finally {
290- block .close ();
291- }
292- }
293-
294- @ Override
295- public void close () {
296- Releasables .closeExpectNoException (eval );
297- }
298-
299- @ Override
300- public String toString () {
301- return "ToAggregateMetricDoubleFromUnsignedLongEvaluator[field=" + eval + "]" ;
302- }
303- };
304- }
305- }
306-
307- public static class IntFactory implements EvalOperator .ExpressionEvaluator .Factory {
308- private final Source source ;
309-
310- private final EvalOperator .ExpressionEvaluator .Factory fieldEvaluator ;
311-
312- public IntFactory (Source source , EvalOperator .ExpressionEvaluator .Factory fieldEvaluator ) {
313- this .fieldEvaluator = fieldEvaluator ;
314- this .source = source ;
315- }
316-
317- @ Override
318- public String toString () {
319- return "ToAggregateMetricDoubleFromIntEvaluator[" + "field=" + fieldEvaluator + "]" ;
320- }
321-
322- @ Override
323- public EvalOperator .ExpressionEvaluator get (DriverContext context ) {
324- final EvalOperator .ExpressionEvaluator eval = fieldEvaluator .get (context );
325-
326- return new EvalOperator .ExpressionEvaluator () {
327- @ Override
328- public Block eval (Page page ) {
329- Block block = eval .eval (page );
330- int positionCount = page .getPositionCount ();
331- try {
332- IntBlock intBlock = (IntBlock ) block ;
333- try (
334- AggregateMetricDoubleBlockBuilder result = context .blockFactory ()
335- .newAggregateMetricDoubleBlockBuilder (positionCount )
336- ) {
337- for (int p = 0 ; p < positionCount ; p ++) {
338- try {
339- if (intBlock .isNull (p )) {
340- result .appendNull ();
341- continue ;
342- }
343- var val = intBlock .getInt (p );
344- result .min ().appendDouble (val );
345- result .max ().appendDouble (val );
346- result .sum ().appendDouble (val );
347- result .count ().appendInt (1 );
348- } catch (Exception e ) {
349- result .appendNull ();
149+ double min = Double .POSITIVE_INFINITY ;
150+ double max = Double .NEGATIVE_INFINITY ;
151+ for (int i = start ; i < end ; i ++) {
152+ double current = doubleBlock .getDouble (i );
153+ min = Math .min (min , current );
154+ max = Math .max (max , current );
155+ sum .add (current );
350156 }
157+ result .min ().appendDouble (min );
158+ result .max ().appendDouble (max );
159+ result .sum ().appendDouble (sum .value ());
160+ result .count ().appendInt (valueCount );
161+ sum .reset (0 , 0 );
351162 }
352163 return result .build ();
353164 }
354- } finally {
355- block .close ();
356165 }
357166 }
358167
@@ -363,7 +172,7 @@ public void close() {
363172
364173 @ Override
365174 public String toString () {
366- return "ToAggregateMetricDoubleFromIntEvaluator [field=" + eval + "]" ;
175+ return "ToAggregateMetricDoubleEvaluator [field=" + eval + "]" ;
367176 }
368177 };
369178 }
0 commit comments