Skip to content

Commit a65a1d3

Browse files
committed
multi-values and Cast.cast
1 parent 61c3fef commit a65a1d3

File tree

2 files changed

+39
-224
lines changed

2 files changed

+39
-224
lines changed

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

Lines changed: 27 additions & 218 deletions
Original file line numberDiff line numberDiff line change
@@ -12,19 +12,18 @@
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;
1715
import org.elasticsearch.compute.data.Page;
1816
import org.elasticsearch.compute.operator.DriverContext;
1917
import org.elasticsearch.compute.operator.EvalOperator;
2018
import org.elasticsearch.core.Releasables;
19+
import org.elasticsearch.search.aggregations.metrics.CompensatedSum;
2120
import org.elasticsearch.xpack.esql.core.expression.Expression;
2221
import org.elasticsearch.xpack.esql.core.tree.NodeInfo;
2322
import org.elasticsearch.xpack.esql.core.tree.Source;
2423
import org.elasticsearch.xpack.esql.core.type.DataType;
2524
import org.elasticsearch.xpack.esql.expression.function.FunctionInfo;
2625
import 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

2928
import java.io.IOException;
3029
import 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
}

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

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -41,12 +41,13 @@ protected Expression build(Source source, List<Expression> args) {
4141

4242
@ParametersFactory
4343
public static Iterable<Object[]> parameters() {
44-
final String read = "Attribute[channel=0]";
44+
final String evaluatorStringLeft = "ToAggregateMetricDoubleEvaluator[field=Cast";
45+
final String evaluatorStringRight = "ToDoubleEvaluator[v=Attribute[channel=0]]]";
4546
final List<TestCaseSupplier> suppliers = new ArrayList<>();
4647

4748
TestCaseSupplier.forUnaryInt(
4849
suppliers,
49-
"ToAggregateMetricDoubleFromIntEvaluator[field=" + read + "]",
50+
evaluatorStringLeft + "Int" + evaluatorStringRight,
5051
DataType.AGGREGATE_METRIC_DOUBLE,
5152
i -> new AggregateMetricDoubleBlockBuilder.AggregateMetricDoubleLiteral((double) i, (double) i, (double) i, 1),
5253
Integer.MIN_VALUE,
@@ -55,7 +56,7 @@ public static Iterable<Object[]> parameters() {
5556
);
5657
TestCaseSupplier.forUnaryLong(
5758
suppliers,
58-
"ToAggregateMetricDoubleFromLongEvaluator[field=" + read + "]",
59+
evaluatorStringLeft + "Long" + evaluatorStringRight,
5960
DataType.AGGREGATE_METRIC_DOUBLE,
6061
l -> new AggregateMetricDoubleBlockBuilder.AggregateMetricDoubleLiteral((double) l, (double) l, (double) l, 1),
6162
Long.MIN_VALUE,
@@ -64,7 +65,7 @@ public static Iterable<Object[]> parameters() {
6465
);
6566
TestCaseSupplier.forUnaryUnsignedLong(
6667
suppliers,
67-
"ToAggregateMetricDoubleFromUnsignedLongEvaluator[field=" + read + "]",
68+
evaluatorStringLeft + "UnsignedLong" + evaluatorStringRight,
6869
DataType.AGGREGATE_METRIC_DOUBLE,
6970
ul -> {
7071
var newVal = ul.doubleValue();
@@ -76,9 +77,14 @@ public static Iterable<Object[]> parameters() {
7677
);
7778
TestCaseSupplier.forUnaryDouble(
7879
suppliers,
79-
"ToAggregateMetricDoubleFromDoubleEvaluator[field=" + read + "]",
80+
"ToAggregateMetricDoubleEvaluator[field=Attribute[channel=0]]",
8081
DataType.AGGREGATE_METRIC_DOUBLE,
81-
d -> new AggregateMetricDoubleBlockBuilder.AggregateMetricDoubleLiteral(d, d, d, 1),
82+
d -> {
83+
if (d == -0.0) {
84+
return new AggregateMetricDoubleBlockBuilder.AggregateMetricDoubleLiteral(d, d, 0.0, 1);
85+
}
86+
return new AggregateMetricDoubleBlockBuilder.AggregateMetricDoubleLiteral(d, d, d, 1);
87+
},
8288
Double.NEGATIVE_INFINITY,
8389
Double.POSITIVE_INFINITY,
8490
emptyList()

0 commit comments

Comments
 (0)