Skip to content

Commit 227de7d

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

File tree

2 files changed

+268
-6
lines changed

2 files changed

+268
-6
lines changed

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

Lines changed: 218 additions & 6 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;
@@ -23,7 +25,7 @@
2325
import org.elasticsearch.xpack.esql.core.type.DataType;
2426
import org.elasticsearch.xpack.esql.expression.function.FunctionInfo;
2527
import 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

2830
import java.io.IOException;
2931
import 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
}

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)