Skip to content

Commit 87ac9d6

Browse files
committed
except undo cast because it doesn't cooperate with multivalue
1 parent a65a1d3 commit 87ac9d6

File tree

2 files changed

+268
-5
lines changed

2 files changed

+268
-5
lines changed

x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/convert/ToAggregateMetricDouble.java

Lines changed: 218 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,8 @@
1212
import org.elasticsearch.compute.data.AggregateMetricDoubleBlockBuilder;
1313
import org.elasticsearch.compute.data.Block;
1414
import org.elasticsearch.compute.data.DoubleBlock;
15+
import org.elasticsearch.compute.data.IntBlock;
16+
import org.elasticsearch.compute.data.LongBlock;
1517
import org.elasticsearch.compute.data.Page;
1618
import org.elasticsearch.compute.operator.DriverContext;
1719
import org.elasticsearch.compute.operator.EvalOperator;
@@ -24,6 +26,7 @@
2426
import org.elasticsearch.xpack.esql.expression.function.FunctionInfo;
2527
import org.elasticsearch.xpack.esql.expression.function.Param;
2628
import org.elasticsearch.xpack.esql.expression.function.scalar.math.Cast;
29+
import org.elasticsearch.xpack.esql.type.EsqlDataTypeConverter;
2730

2831
import java.io.IOException;
2932
import 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
}

x-pack/plugin/src/yamlRestTest/resources/rest-api-spec/test/esql/40_tsdb.yml

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -609,3 +609,53 @@ _source:
609609
rx: 530600088
610610
tx: 1434577921
611611
uid: df3145b3-0563-4d3b-a0f7-897eb2876ea9
612+
613+
---
614+
to_aggregate_metric_double with multi_values:
615+
- requires:
616+
test_runner_features: [ capabilities ]
617+
capabilities:
618+
- method: POST
619+
path: /_query
620+
parameters: [ ]
621+
capabilities: [ aggregate_metric_double_convert_to ]
622+
reason: "Support for to_aggregate_metric_double function"
623+
624+
- do:
625+
indices.create:
626+
index: convert_test
627+
body:
628+
mappings:
629+
properties:
630+
"some_long_field":
631+
type: long
632+
"some_double_field":
633+
type: double
634+
"some_int_field":
635+
type: integer
636+
"some_unsigned_long_field":
637+
type: unsigned_long
638+
- do:
639+
bulk:
640+
refresh: true
641+
index: new_test
642+
body:
643+
- {"index": {}}
644+
- {"some_long_field": [20385, 182941, -10958], "some_double_field": [195.1, 102.444], "some_int_field": [64, 121, 498, 1456], "some_unsigned_long_field": [13985, 19418924, 123]}
645+
- do:
646+
esql.query:
647+
body:
648+
query: 'FROM new_test | EVAL from_long=TO_AGGREGATE_METRIC_DOUBLE(some_long_field), from_double=TO_AGGREGATE_METRIC_DOUBLE(some_double_field), from_int=TO_AGGREGATE_METRIC_DOUBLE(some_int_field), from_ulong=TO_AGGREGATE_METRIC_DOUBLE(some_unsigned_long_field) | KEEP from_long, from_double, from_int, from_ulong | LIMIT 1'
649+
650+
- match: {columns.0.name: "from_long"}
651+
- match: {columns.0.type: "aggregate_metric_double"}
652+
- match: {columns.1.name: "from_double"}
653+
- match: {columns.1.type: "aggregate_metric_double"}
654+
- match: {columns.2.name: "from_int"}
655+
- match: {columns.2.type: "aggregate_metric_double"}
656+
- match: {columns.3.name: "from_ulong"}
657+
- match: {columns.3.type: "aggregate_metric_double"}
658+
- match: {values.0.0: '{"min":-10958.0,"max":182941.0,"sum":192368.0,"value_count":3}'}
659+
- match: {values.0.1: '{"min":102.44400024414062,"max":195.10000610351562,"sum":297.54400634765625,"value_count":2}'}
660+
- match: {values.0.2: '{"min":64.0,"max":1456.0,"sum":2139.0,"value_count":4}'}
661+
- match: {values.0.3: '{"min":123.0,"max":1.9418924E7,"sum":1.9433032E7,"value_count":3}'}

0 commit comments

Comments
 (0)