From 53375a5a7c77b0320f5cd622f0e56fa0c177c306 Mon Sep 17 00:00:00 2001 From: Jonas Kunz Date: Thu, 30 Oct 2025 11:58:19 +0100 Subject: [PATCH 01/15] ESQL: Replace ExponentialHistogramBlock accessor with get method and scratch --- .../compute/data/BlockUtils.java | 2 +- .../compute/data/ConstantNullBlock.java | 7 +++ .../data/ExponentialHistogramArrayBlock.java | 11 +++-- .../data/ExponentialHistogramBlock.java | 14 +++++- .../ExponentialHistogramBlockAccessor.java | 48 ------------------- .../data/ExponentialHistogramScratch.java | 21 ++++++++ .../compute/test/BlockTestUtils.java | 7 ++- .../xpack/esql/action/PositionToXContent.java | 6 +-- .../esql/type/EsqlDataTypeConverter.java | 4 +- 9 files changed, 59 insertions(+), 61 deletions(-) delete mode 100644 x-pack/plugin/esql/compute/src/main/java/org/elasticsearch/compute/data/ExponentialHistogramBlockAccessor.java create mode 100644 x-pack/plugin/esql/compute/src/main/java/org/elasticsearch/compute/data/ExponentialHistogramScratch.java diff --git a/x-pack/plugin/esql/compute/src/main/java/org/elasticsearch/compute/data/BlockUtils.java b/x-pack/plugin/esql/compute/src/main/java/org/elasticsearch/compute/data/BlockUtils.java index fd036a9bc1e0d..7dfe664364e51 100644 --- a/x-pack/plugin/esql/compute/src/main/java/org/elasticsearch/compute/data/BlockUtils.java +++ b/x-pack/plugin/esql/compute/src/main/java/org/elasticsearch/compute/data/BlockUtils.java @@ -312,7 +312,7 @@ yield new AggregateMetricDoubleLiteral( } case EXPONENTIAL_HISTOGRAM -> { ExponentialHistogramBlock histoBlock = (ExponentialHistogramBlock) block; - ExponentialHistogram histogram = new ExponentialHistogramBlockAccessor(histoBlock).get(offset); + ExponentialHistogram histogram = histoBlock.getExponentialHistogram(offset, new ExponentialHistogramScratch()); // return a copy so that the returned value is not bound to the lifetime of the block yield ExponentialHistogram.builder(histogram, ExponentialHistogramCircuitBreaker.noop()).build(); } diff --git a/x-pack/plugin/esql/compute/src/main/java/org/elasticsearch/compute/data/ConstantNullBlock.java b/x-pack/plugin/esql/compute/src/main/java/org/elasticsearch/compute/data/ConstantNullBlock.java index 4586638d6ea5c..0dc4a67ab6100 100644 --- a/x-pack/plugin/esql/compute/src/main/java/org/elasticsearch/compute/data/ConstantNullBlock.java +++ b/x-pack/plugin/esql/compute/src/main/java/org/elasticsearch/compute/data/ConstantNullBlock.java @@ -12,6 +12,7 @@ import org.elasticsearch.common.io.stream.StreamOutput; import org.elasticsearch.common.unit.ByteSizeValue; import org.elasticsearch.core.ReleasableIterator; +import org.elasticsearch.exponentialhistogram.ExponentialHistogram; import java.io.IOException; @@ -293,6 +294,12 @@ public long getLong(int valueIndex) { throw new UnsupportedOperationException("null block"); } + @Override + public ExponentialHistogram getExponentialHistogram(int valueIndex, ExponentialHistogramScratch scratch) { + assert false : "null block"; + throw new UnsupportedOperationException("null block"); + } + @Override public int getTotalValueCount() { return 0; diff --git a/x-pack/plugin/esql/compute/src/main/java/org/elasticsearch/compute/data/ExponentialHistogramArrayBlock.java b/x-pack/plugin/esql/compute/src/main/java/org/elasticsearch/compute/data/ExponentialHistogramArrayBlock.java index 55a3944d09663..074813551ef4d 100644 --- a/x-pack/plugin/esql/compute/src/main/java/org/elasticsearch/compute/data/ExponentialHistogramArrayBlock.java +++ b/x-pack/plugin/esql/compute/src/main/java/org/elasticsearch/compute/data/ExponentialHistogramArrayBlock.java @@ -12,7 +12,7 @@ import org.elasticsearch.common.unit.ByteSizeValue; import org.elasticsearch.core.ReleasableIterator; import org.elasticsearch.core.Releasables; -import org.elasticsearch.exponentialhistogram.CompressedExponentialHistogram; +import org.elasticsearch.exponentialhistogram.ExponentialHistogram; import java.io.IOException; import java.util.List; @@ -78,15 +78,17 @@ private List getSubBlocks() { return List.of(sums, valueCounts, zeroThresholds, encodedHistograms, minima, maxima); } - void loadValue(int valueIndex, CompressedExponentialHistogram resultHistogram, BytesRef tempBytesRef) { - BytesRef bytes = encodedHistograms.getBytesRef(encodedHistograms.getFirstValueIndex(valueIndex), tempBytesRef); + @Override + public ExponentialHistogram getExponentialHistogram(int valueIndex, ExponentialHistogramScratch scratch) { + BytesRef bytes = encodedHistograms.getBytesRef(encodedHistograms.getFirstValueIndex(valueIndex), scratch.bytesRefScratch); double zeroThreshold = zeroThresholds.getDouble(zeroThresholds.getFirstValueIndex(valueIndex)); long valueCount = valueCounts.getLong(valueCounts.getFirstValueIndex(valueIndex)); double sum = sums.getDouble(sums.getFirstValueIndex(valueIndex)); double min = valueCount == 0 ? Double.NaN : minima.getDouble(minima.getFirstValueIndex(valueIndex)); double max = valueCount == 0 ? Double.NaN : maxima.getDouble(maxima.getFirstValueIndex(valueIndex)); try { - resultHistogram.reset(zeroThreshold, valueCount, sum, min, max, bytes); + scratch.reusedHistogram.reset(zeroThreshold, valueCount, sum, min, max, bytes); + return scratch.reusedHistogram; } catch (IOException e) { throw new IllegalStateException("error loading histogram", e); } @@ -374,4 +376,5 @@ public int hashCode() { // this ensures proper equality with null blocks and should be unique enough for practical purposes return encodedHistograms.hashCode(); } + } diff --git a/x-pack/plugin/esql/compute/src/main/java/org/elasticsearch/compute/data/ExponentialHistogramBlock.java b/x-pack/plugin/esql/compute/src/main/java/org/elasticsearch/compute/data/ExponentialHistogramBlock.java index d6da0ad7176e8..c994599548249 100644 --- a/x-pack/plugin/esql/compute/src/main/java/org/elasticsearch/compute/data/ExponentialHistogramBlock.java +++ b/x-pack/plugin/esql/compute/src/main/java/org/elasticsearch/compute/data/ExponentialHistogramBlock.java @@ -11,10 +11,22 @@ /** * A block that holds {@link ExponentialHistogram} values. - * Position access is done through {@link ExponentialHistogramBlockAccessor}. */ public sealed interface ExponentialHistogramBlock extends Block permits ConstantNullBlock, ExponentialHistogramArrayBlock { + /** + * Returns the {@link ExponentialHistogram} value at the given index. + * In order to be allocation free, this method requires a scratch object to be passed in, + * whose memory will be used to hold the state of the returned histogram. + * Therefore, the return value of this method is only valid until either the block is closed + * or the same scratch instance is passed to another call to this method on any block. + * + * @param valueIndex the index of the histogram to get + * @param scratch the scratch to use as storage for the histogram + * @return the exponential histogram at the given index + */ + ExponentialHistogram getExponentialHistogram(int valueIndex, ExponentialHistogramScratch scratch); + static boolean equals(ExponentialHistogramBlock blockA, ExponentialHistogramBlock blockB) { if (blockA == blockB) { return true; diff --git a/x-pack/plugin/esql/compute/src/main/java/org/elasticsearch/compute/data/ExponentialHistogramBlockAccessor.java b/x-pack/plugin/esql/compute/src/main/java/org/elasticsearch/compute/data/ExponentialHistogramBlockAccessor.java deleted file mode 100644 index bf1fa242f2e96..0000000000000 --- a/x-pack/plugin/esql/compute/src/main/java/org/elasticsearch/compute/data/ExponentialHistogramBlockAccessor.java +++ /dev/null @@ -1,48 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -package org.elasticsearch.compute.data; - -import org.apache.lucene.util.BytesRef; -import org.elasticsearch.exponentialhistogram.CompressedExponentialHistogram; -import org.elasticsearch.exponentialhistogram.ExponentialHistogram; - -/** - * Provides access to the values stored in an {@link ExponentialHistogramBlock} as {@link ExponentialHistogram}s. - */ -public class ExponentialHistogramBlockAccessor { - - private final ExponentialHistogramBlock block; - private BytesRef tempBytesRef; - private CompressedExponentialHistogram reusedHistogram; - - public ExponentialHistogramBlockAccessor(ExponentialHistogramBlock block) { - this.block = block; - } - - /** - * Returns the {@link ExponentialHistogram} at the given value index. - * The return value of this method is reused across invocations, so callers should - * not retain a reference to it. - * In addition, the returned histogram must not be used after the block is released. - * - * @param valueIndex, should be obtained via {@link ExponentialHistogramBlock#getFirstValueIndex(int)}. - * @return null if the the value stored in the block - */ - public ExponentialHistogram get(int valueIndex) { - assert block.isNull(valueIndex) == false; - assert block.isReleased() == false; - ExponentialHistogramArrayBlock arrayBlock = (ExponentialHistogramArrayBlock) block; - if (reusedHistogram == null) { - tempBytesRef = new BytesRef(); - reusedHistogram = new CompressedExponentialHistogram(); - } - arrayBlock.loadValue(valueIndex, reusedHistogram, tempBytesRef); - return reusedHistogram; - } - -} diff --git a/x-pack/plugin/esql/compute/src/main/java/org/elasticsearch/compute/data/ExponentialHistogramScratch.java b/x-pack/plugin/esql/compute/src/main/java/org/elasticsearch/compute/data/ExponentialHistogramScratch.java new file mode 100644 index 0000000000000..9db3dbcbc3518 --- /dev/null +++ b/x-pack/plugin/esql/compute/src/main/java/org/elasticsearch/compute/data/ExponentialHistogramScratch.java @@ -0,0 +1,21 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +package org.elasticsearch.compute.data; + +import org.apache.lucene.util.BytesRef; +import org.elasticsearch.exponentialhistogram.CompressedExponentialHistogram; + +/** + * Reusable storage to be passed to {@link ExponentialHistogramBlock#getExponentialHistogram(int, ExponentialHistogramScratch)}. + */ +public class ExponentialHistogramScratch { + + final BytesRef bytesRefScratch = new BytesRef(); + final CompressedExponentialHistogram reusedHistogram = new CompressedExponentialHistogram(); + +} diff --git a/x-pack/plugin/esql/compute/test/src/main/java/org/elasticsearch/compute/test/BlockTestUtils.java b/x-pack/plugin/esql/compute/test/src/main/java/org/elasticsearch/compute/test/BlockTestUtils.java index 0a57afa10653a..53a89c642a919 100644 --- a/x-pack/plugin/esql/compute/test/src/main/java/org/elasticsearch/compute/test/BlockTestUtils.java +++ b/x-pack/plugin/esql/compute/test/src/main/java/org/elasticsearch/compute/test/BlockTestUtils.java @@ -20,8 +20,8 @@ import org.elasticsearch.compute.data.DoubleBlock; import org.elasticsearch.compute.data.ElementType; import org.elasticsearch.compute.data.ExponentialHistogramBlock; -import org.elasticsearch.compute.data.ExponentialHistogramBlockAccessor; import org.elasticsearch.compute.data.ExponentialHistogramBlockBuilder; +import org.elasticsearch.compute.data.ExponentialHistogramScratch; import org.elasticsearch.compute.data.FloatBlock; import org.elasticsearch.compute.data.IntBlock; import org.elasticsearch.compute.data.LongBlock; @@ -313,7 +313,10 @@ public static List> valuesAtPositions(Block block, int from, int to yield literal; } - case EXPONENTIAL_HISTOGRAM -> new ExponentialHistogramBlockAccessor((ExponentialHistogramBlock) block).get(i); + case EXPONENTIAL_HISTOGRAM -> ((ExponentialHistogramBlock) block).getExponentialHistogram( + i++, + new ExponentialHistogramScratch() + ); default -> throw new IllegalArgumentException("unsupported element type [" + block.elementType() + "]"); }); } diff --git a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/action/PositionToXContent.java b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/action/PositionToXContent.java index 350012d138d22..1683c87dfa99c 100644 --- a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/action/PositionToXContent.java +++ b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/action/PositionToXContent.java @@ -16,7 +16,7 @@ import org.elasticsearch.compute.data.BytesRefBlock; import org.elasticsearch.compute.data.DoubleBlock; import org.elasticsearch.compute.data.ExponentialHistogramBlock; -import org.elasticsearch.compute.data.ExponentialHistogramBlockAccessor; +import org.elasticsearch.compute.data.ExponentialHistogramScratch; import org.elasticsearch.compute.data.FloatBlock; import org.elasticsearch.compute.data.IntBlock; import org.elasticsearch.compute.data.LongBlock; @@ -174,12 +174,12 @@ protected XContentBuilder valueToXContent(XContentBuilder builder, ToXContent.Pa }; case EXPONENTIAL_HISTOGRAM -> new PositionToXContent(block) { - ExponentialHistogramBlockAccessor accessor = new ExponentialHistogramBlockAccessor((ExponentialHistogramBlock) block); + ExponentialHistogramScratch scratch = new ExponentialHistogramScratch(); @Override protected XContentBuilder valueToXContent(XContentBuilder builder, ToXContent.Params params, int valueIndex) throws IOException { - ExponentialHistogram histogram = accessor.get(valueIndex); + ExponentialHistogram histogram = ((ExponentialHistogramBlock)block).getExponentialHistogram(valueIndex, scratch); ExponentialHistogramXContent.serialize(builder, histogram); return builder; } diff --git a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/type/EsqlDataTypeConverter.java b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/type/EsqlDataTypeConverter.java index 4437cf05c41d0..a10094dd93997 100644 --- a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/type/EsqlDataTypeConverter.java +++ b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/type/EsqlDataTypeConverter.java @@ -21,7 +21,7 @@ import org.elasticsearch.compute.data.AggregateMetricDoubleBlockBuilder.Metric; import org.elasticsearch.compute.data.DoubleBlock; import org.elasticsearch.compute.data.ExponentialHistogramBlock; -import org.elasticsearch.compute.data.ExponentialHistogramBlockAccessor; +import org.elasticsearch.compute.data.ExponentialHistogramScratch; import org.elasticsearch.compute.data.IntBlock; import org.elasticsearch.core.Booleans; import org.elasticsearch.exponentialhistogram.ExponentialHistogram; @@ -799,7 +799,7 @@ public static String exponentialHistogramToString(ExponentialHistogram histo) { } public static String exponentialHistogramBlockToString(ExponentialHistogramBlock histoBlock, int index) { - ExponentialHistogram histo = new ExponentialHistogramBlockAccessor(histoBlock).get(index); + ExponentialHistogram histo = histoBlock.getExponentialHistogram(index, new ExponentialHistogramScratch()); return exponentialHistogramToString(histo); } From a682ae462cd844f57b9a9ca0e7a2035f0077faea Mon Sep 17 00:00:00 2001 From: Jonas Kunz Date: Thu, 30 Oct 2025 12:02:09 +0100 Subject: [PATCH 02/15] slight rewording --- .../elasticsearch/compute/data/ExponentialHistogramBlock.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/x-pack/plugin/esql/compute/src/main/java/org/elasticsearch/compute/data/ExponentialHistogramBlock.java b/x-pack/plugin/esql/compute/src/main/java/org/elasticsearch/compute/data/ExponentialHistogramBlock.java index c994599548249..3aad62ce9355c 100644 --- a/x-pack/plugin/esql/compute/src/main/java/org/elasticsearch/compute/data/ExponentialHistogramBlock.java +++ b/x-pack/plugin/esql/compute/src/main/java/org/elasticsearch/compute/data/ExponentialHistogramBlock.java @@ -22,7 +22,7 @@ public sealed interface ExponentialHistogramBlock extends Block permits Constant * or the same scratch instance is passed to another call to this method on any block. * * @param valueIndex the index of the histogram to get - * @param scratch the scratch to use as storage for the histogram + * @param scratch the scratch to use as storage for the returned histogram * @return the exponential histogram at the given index */ ExponentialHistogram getExponentialHistogram(int valueIndex, ExponentialHistogramScratch scratch); From 081494ecb38affa00cbf54dd34597ea9f73c8af8 Mon Sep 17 00:00:00 2001 From: Jonas Kunz Date: Mon, 27 Oct 2025 11:02:37 +0100 Subject: [PATCH 03/15] ESQL: Implement TopN support for exponential histogram --- .../data/ExponentialHistogramArrayBlock.java | 39 ++++++++++ .../data/ExponentialHistogramBlock.java | 24 ++++++ .../ExponentialHistogramBlockBuilder.java | 24 ++++++ .../compute/operator/topn/ResultBuilder.java | 1 + .../ResultBuilderForExponentialHistogram.java | 75 +++++++++++++++++++ .../compute/operator/topn/ValueExtractor.java | 2 + ...ValueExtractorForExponentialHistogram.java | 63 ++++++++++++++++ .../compute/operator/topn/ExtractorTests.java | 5 +- .../esql/planner/LocalExecutionPlanner.java | 6 +- 9 files changed, 235 insertions(+), 4 deletions(-) create mode 100644 x-pack/plugin/esql/compute/src/main/java/org/elasticsearch/compute/operator/topn/ResultBuilderForExponentialHistogram.java create mode 100644 x-pack/plugin/esql/compute/src/main/java/org/elasticsearch/compute/operator/topn/ValueExtractorForExponentialHistogram.java diff --git a/x-pack/plugin/esql/compute/src/main/java/org/elasticsearch/compute/data/ExponentialHistogramArrayBlock.java b/x-pack/plugin/esql/compute/src/main/java/org/elasticsearch/compute/data/ExponentialHistogramArrayBlock.java index 074813551ef4d..0225fab889bae 100644 --- a/x-pack/plugin/esql/compute/src/main/java/org/elasticsearch/compute/data/ExponentialHistogramArrayBlock.java +++ b/x-pack/plugin/esql/compute/src/main/java/org/elasticsearch/compute/data/ExponentialHistogramArrayBlock.java @@ -94,6 +94,45 @@ public ExponentialHistogram getExponentialHistogram(int valueIndex, ExponentialH } } + void serializeValue(int valueIndex, SerializedOutput out, BytesRef tempBytesRef) { + long valueCount = getHistogramValueCount(valueIndex); + out.appendLong(valueCount); + out.appendDouble(getHistogramSum(valueIndex)); + out.appendDouble(getHistogramZeroThreshold(valueIndex)); + if (valueCount > 0) { + // min / max are only non-null for non-empty histograms + out.appendDouble(getHistogramMin(valueIndex)); + out.appendDouble(getHistogramMax(valueIndex)); + } + out.appendBytesRef(getEncodedHistogramBytes(valueIndex, tempBytesRef)); + } + + private double getHistogramMin(int valueIndex) { + int minimaValIndex = minima.getFirstValueIndex(valueIndex); + return minima.isNull(minimaValIndex) ? Double.NaN : minima.getDouble(minimaValIndex); + } + + private double getHistogramMax(int valueIndex) { + int maximaValIndex = maxima.getFirstValueIndex(valueIndex); + return maxima.isNull(maximaValIndex) ? Double.NaN : maxima.getDouble(maximaValIndex); + } + + private double getHistogramSum(int valueIndex) { + return sums.getDouble(sums.getFirstValueIndex(valueIndex)); + } + + private long getHistogramValueCount(int valueIndex) { + return valueCounts.getLong(valueCounts.getFirstValueIndex(valueIndex)); + } + + private double getHistogramZeroThreshold(int valueIndex) { + return zeroThresholds.getDouble(zeroThresholds.getFirstValueIndex(valueIndex)); + } + + private BytesRef getEncodedHistogramBytes(int valueIndex, BytesRef tempBytesRef) { + return encodedHistograms.getBytesRef(encodedHistograms.getFirstValueIndex(valueIndex), tempBytesRef); + } + @Override protected void closeInternal() { Releasables.close(getSubBlocks()); diff --git a/x-pack/plugin/esql/compute/src/main/java/org/elasticsearch/compute/data/ExponentialHistogramBlock.java b/x-pack/plugin/esql/compute/src/main/java/org/elasticsearch/compute/data/ExponentialHistogramBlock.java index 3aad62ce9355c..f2c95ede6fd8c 100644 --- a/x-pack/plugin/esql/compute/src/main/java/org/elasticsearch/compute/data/ExponentialHistogramBlock.java +++ b/x-pack/plugin/esql/compute/src/main/java/org/elasticsearch/compute/data/ExponentialHistogramBlock.java @@ -7,6 +7,7 @@ package org.elasticsearch.compute.data; +import org.apache.lucene.util.BytesRef; import org.elasticsearch.exponentialhistogram.ExponentialHistogram; /** @@ -14,6 +15,29 @@ */ public sealed interface ExponentialHistogramBlock extends Block permits ConstantNullBlock, ExponentialHistogramArrayBlock { + /** + * Abstraction to use for writing individual values via {@link ExponentialHistogramBlockAccessor#serializeValue(int, SerializedOutput)}. + */ + interface SerializedOutput { + void appendDouble(double value); + + void appendLong(long value); + + void appendBytesRef(BytesRef bytesRef); + } + + /** + * Abstraction to use for reading individual serialized via + * {@link ExponentialHistogramBlockBuilder#deserializeAndAppend(SerializedInput)}. + */ + interface SerializedInput { + double readDouble(); + + long readLong(); + + BytesRef readBytesRef(BytesRef tempBytesRef); + } + /** * Returns the {@link ExponentialHistogram} value at the given index. * In order to be allocation free, this method requires a scratch object to be passed in, diff --git a/x-pack/plugin/esql/compute/src/main/java/org/elasticsearch/compute/data/ExponentialHistogramBlockBuilder.java b/x-pack/plugin/esql/compute/src/main/java/org/elasticsearch/compute/data/ExponentialHistogramBlockBuilder.java index 5b7c0ceeceb4c..0128726233a11 100644 --- a/x-pack/plugin/esql/compute/src/main/java/org/elasticsearch/compute/data/ExponentialHistogramBlockBuilder.java +++ b/x-pack/plugin/esql/compute/src/main/java/org/elasticsearch/compute/data/ExponentialHistogramBlockBuilder.java @@ -7,6 +7,7 @@ package org.elasticsearch.compute.data; +import org.apache.lucene.util.BytesRef; import org.elasticsearch.common.io.stream.BytesStreamOutput; import org.elasticsearch.core.Releasables; import org.elasticsearch.exponentialhistogram.CompressedExponentialHistogram; @@ -24,6 +25,8 @@ public class ExponentialHistogramBlockBuilder implements Block.Builder { private final DoubleBlock.Builder zeroThresholdsBuilder; private final BytesRefBlock.Builder encodedHistogramsBuilder; + private final BytesRef scratch = new BytesRef(); + ExponentialHistogramBlockBuilder(int estimatedSize, BlockFactory blockFactory) { DoubleBlock.Builder minimaBuilder = null; DoubleBlock.Builder maximaBuilder = null; @@ -100,6 +103,27 @@ public ExponentialHistogramBlockBuilder append(ExponentialHistogram histogram) { return this; } + /** + * Decodes and appends a value serialized with + * {@link ExponentialHistogramBlockAccessor#serializeValue(int, ExponentialHistogramBlock.SerializedOutput)}. + * + * @param input the input to deserialize from + */ + public void deserializeAndAppend(ExponentialHistogramBlock.SerializedInput input) { + long valueCount = input.readLong(); + valueCountsBuilder.appendLong(valueCount); + sumsBuilder.appendDouble(input.readDouble()); + zeroThresholdsBuilder.appendDouble(input.readDouble()); + if (valueCount > 0) { + minimaBuilder.appendDouble(input.readDouble()); + maximaBuilder.appendDouble(input.readDouble()); + } else { + minimaBuilder.appendNull(); + maximaBuilder.appendNull(); + } + encodedHistogramsBuilder.appendBytesRef(input.readBytesRef(scratch)); + } + @Override public ExponentialHistogramBlock build() { DoubleBlock minima = null; diff --git a/x-pack/plugin/esql/compute/src/main/java/org/elasticsearch/compute/operator/topn/ResultBuilder.java b/x-pack/plugin/esql/compute/src/main/java/org/elasticsearch/compute/operator/topn/ResultBuilder.java index 6eee1383e277b..cff31535f82e0 100644 --- a/x-pack/plugin/esql/compute/src/main/java/org/elasticsearch/compute/operator/topn/ResultBuilder.java +++ b/x-pack/plugin/esql/compute/src/main/java/org/elasticsearch/compute/operator/topn/ResultBuilder.java @@ -55,6 +55,7 @@ static ResultBuilder resultBuilderFor( case NULL -> new ResultBuilderForNull(blockFactory); case DOC -> new ResultBuilderForDoc(blockFactory, (DocVectorEncoder) encoder, positions); case AGGREGATE_METRIC_DOUBLE -> new ResultBuilderForAggregateMetricDouble(blockFactory, positions); + case EXPONENTIAL_HISTOGRAM -> new ResultBuilderForExponentialHistogram(blockFactory, positions); default -> { assert false : "Result builder for [" + elementType + "]"; throw new UnsupportedOperationException("Result builder for [" + elementType + "]"); diff --git a/x-pack/plugin/esql/compute/src/main/java/org/elasticsearch/compute/operator/topn/ResultBuilderForExponentialHistogram.java b/x-pack/plugin/esql/compute/src/main/java/org/elasticsearch/compute/operator/topn/ResultBuilderForExponentialHistogram.java new file mode 100644 index 0000000000000..5cc1bd45be8f9 --- /dev/null +++ b/x-pack/plugin/esql/compute/src/main/java/org/elasticsearch/compute/operator/topn/ResultBuilderForExponentialHistogram.java @@ -0,0 +1,75 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +package org.elasticsearch.compute.operator.topn; + +import org.apache.lucene.util.BytesRef; +import org.elasticsearch.compute.data.Block; +import org.elasticsearch.compute.data.BlockFactory; +import org.elasticsearch.compute.data.ExponentialHistogramBlock; +import org.elasticsearch.compute.data.ExponentialHistogramBlockBuilder; + +public class ResultBuilderForExponentialHistogram implements ResultBuilder { + + private final ExponentialHistogramBlockBuilder builder; + private final ReusableTopNEncoderInput reusableInput = new ReusableTopNEncoderInput(); + + ResultBuilderForExponentialHistogram(BlockFactory blockFactory, int positions) { + this.builder = blockFactory.newExponentialHistogramBlockBuilder(positions); + } + + @Override + public void decodeKey(BytesRef keys) { + throw new AssertionError("ExponentialHistogramBlock can't be a key"); + } + + @Override + public void decodeValue(BytesRef values) { + int count = TopNEncoder.DEFAULT_UNSORTABLE.decodeVInt(values); + if (count == 0) { + builder.appendNull(); + return; + } + assert count == 1 : "ExponentialHistogramBlock does not support multi values"; + reusableInput.inputValues = values; + builder.deserializeAndAppend(reusableInput); + } + + @Override + public Block build() { + return builder.build(); + } + + @Override + public String toString() { + return "ResultBuilderForExponentialHistogram"; + } + + @Override + public void close() { + builder.close(); + } + + private class ReusableTopNEncoderInput implements ExponentialHistogramBlock.SerializedInput { + BytesRef inputValues; + + @Override + public double readDouble() { + return TopNEncoder.DEFAULT_UNSORTABLE.decodeDouble(inputValues); + } + + @Override + public long readLong() { + return TopNEncoder.DEFAULT_UNSORTABLE.decodeLong(inputValues); + } + + @Override + public BytesRef readBytesRef(BytesRef tempBytesRef) { + return TopNEncoder.DEFAULT_UNSORTABLE.decodeBytesRef(inputValues, tempBytesRef); + } + } +} diff --git a/x-pack/plugin/esql/compute/src/main/java/org/elasticsearch/compute/operator/topn/ValueExtractor.java b/x-pack/plugin/esql/compute/src/main/java/org/elasticsearch/compute/operator/topn/ValueExtractor.java index b6f3a1198d1ff..d5120cddcb761 100644 --- a/x-pack/plugin/esql/compute/src/main/java/org/elasticsearch/compute/operator/topn/ValueExtractor.java +++ b/x-pack/plugin/esql/compute/src/main/java/org/elasticsearch/compute/operator/topn/ValueExtractor.java @@ -14,6 +14,7 @@ import org.elasticsearch.compute.data.DocBlock; import org.elasticsearch.compute.data.DoubleBlock; import org.elasticsearch.compute.data.ElementType; +import org.elasticsearch.compute.data.ExponentialHistogramBlock; import org.elasticsearch.compute.data.FloatBlock; import org.elasticsearch.compute.data.IntBlock; import org.elasticsearch.compute.data.LongBlock; @@ -53,6 +54,7 @@ static ValueExtractor extractorFor(ElementType elementType, TopNEncoder encoder, case NULL -> new ValueExtractorForNull(); case DOC -> new ValueExtractorForDoc(encoder, ((DocBlock) block).asVector()); case AGGREGATE_METRIC_DOUBLE -> new ValueExtractorForAggregateMetricDouble(encoder, (AggregateMetricDoubleBlock) block); + case EXPONENTIAL_HISTOGRAM -> new ValueExtractorForExponentialHistogram(encoder, (ExponentialHistogramBlock) block); default -> { assert false : "No value extractor for [" + block.elementType() + "]"; throw new UnsupportedOperationException("No value extractor for [" + block.elementType() + "]"); diff --git a/x-pack/plugin/esql/compute/src/main/java/org/elasticsearch/compute/operator/topn/ValueExtractorForExponentialHistogram.java b/x-pack/plugin/esql/compute/src/main/java/org/elasticsearch/compute/operator/topn/ValueExtractorForExponentialHistogram.java new file mode 100644 index 0000000000000..ce83ea5494b65 --- /dev/null +++ b/x-pack/plugin/esql/compute/src/main/java/org/elasticsearch/compute/operator/topn/ValueExtractorForExponentialHistogram.java @@ -0,0 +1,63 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +package org.elasticsearch.compute.operator.topn; + +import org.apache.lucene.util.BytesRef; +import org.elasticsearch.compute.data.ExponentialHistogramBlock; +import org.elasticsearch.compute.data.ExponentialHistogramBlockAccessor; +import org.elasticsearch.compute.operator.BreakingBytesRefBuilder; + +public class ValueExtractorForExponentialHistogram implements ValueExtractor { + private final ExponentialHistogramBlock block; + private final ExponentialHistogramBlockAccessor accessor; + private final ReusableTopNEncoderOutput reusableOutput = new ReusableTopNEncoderOutput(); + + ValueExtractorForExponentialHistogram(TopNEncoder encoder, ExponentialHistogramBlock block) { + assert encoder == TopNEncoder.DEFAULT_UNSORTABLE; + this.block = block; + this.accessor = new ExponentialHistogramBlockAccessor(block); + } + + @Override + public void writeValue(BreakingBytesRefBuilder values, int position) { + // number of multi-values first for compatibility with ValueExtractorForNull + if (block.isNull(position)) { + TopNEncoder.DEFAULT_UNSORTABLE.encodeVInt(0, values); + } else { + assert block.getValueCount(position) == 1 : "Multi-valued ExponentialHistogram blocks are not supported in TopN"; + TopNEncoder.DEFAULT_UNSORTABLE.encodeVInt(1, values); + int valueIndex = block.getFirstValueIndex(position); + reusableOutput.target = values; + accessor.serializeValue(valueIndex, reusableOutput); + } + } + + @Override + public String toString() { + return "ValueExtractorForExponentialHistogram"; + } + + private static final class ReusableTopNEncoderOutput implements ExponentialHistogramBlock.SerializedOutput { + BreakingBytesRefBuilder target; + + @Override + public void appendDouble(double value) { + TopNEncoder.DEFAULT_UNSORTABLE.encodeDouble(value, target); + } + + @Override + public void appendLong(long value) { + TopNEncoder.DEFAULT_UNSORTABLE.encodeLong(value, target); + } + + @Override + public void appendBytesRef(BytesRef value) { + TopNEncoder.DEFAULT_UNSORTABLE.encodeBytesRef(value, target); + } + } +} diff --git a/x-pack/plugin/esql/compute/src/test/java/org/elasticsearch/compute/operator/topn/ExtractorTests.java b/x-pack/plugin/esql/compute/src/test/java/org/elasticsearch/compute/operator/topn/ExtractorTests.java index 022055a72bcbb..60b11e5a290e8 100644 --- a/x-pack/plugin/esql/compute/src/test/java/org/elasticsearch/compute/operator/topn/ExtractorTests.java +++ b/x-pack/plugin/esql/compute/src/test/java/org/elasticsearch/compute/operator/topn/ExtractorTests.java @@ -44,7 +44,7 @@ public static Iterable parameters() { case UNKNOWN -> { supportsNull = false; } - case COMPOSITE, EXPONENTIAL_HISTOGRAM -> { + case COMPOSITE -> { // TODO: add later supportsNull = false; } @@ -130,6 +130,9 @@ public static Iterable parameters() { ) } ); } + case EXPONENTIAL_HISTOGRAM -> + // multi values are not supported + cases.add(valueTestCase("single " + e, e, TopNEncoder.DEFAULT_UNSORTABLE, () -> BlockTestUtils.randomValue(e))); case NULL -> { } default -> { diff --git a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/planner/LocalExecutionPlanner.java b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/planner/LocalExecutionPlanner.java index 908193f4bcb18..7eadaa979d3c8 100644 --- a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/planner/LocalExecutionPlanner.java +++ b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/planner/LocalExecutionPlanner.java @@ -487,10 +487,10 @@ private PhysicalOperation planTopN(TopNExec topNExec, LocalExecutionPlannerConte case BOOLEAN, NULL, BYTE, SHORT, INTEGER, LONG, DOUBLE, FLOAT, HALF_FLOAT, DATETIME, DATE_NANOS, DATE_PERIOD, TIME_DURATION, OBJECT, SCALED_FLOAT, UNSIGNED_LONG, TSID_DATA_TYPE -> TopNEncoder.DEFAULT_SORTABLE; case GEO_POINT, CARTESIAN_POINT, GEO_SHAPE, CARTESIAN_SHAPE, COUNTER_LONG, COUNTER_INTEGER, COUNTER_DOUBLE, SOURCE, - AGGREGATE_METRIC_DOUBLE, DENSE_VECTOR, GEOHASH, GEOTILE, GEOHEX -> TopNEncoder.DEFAULT_UNSORTABLE; + AGGREGATE_METRIC_DOUBLE, DENSE_VECTOR, GEOHASH, GEOTILE, GEOHEX, EXPONENTIAL_HISTOGRAM -> + TopNEncoder.DEFAULT_UNSORTABLE; // unsupported fields are encoded as BytesRef, we'll use the same encoder; all values should be null at this point - // TODO(b/133393) add exponential histogram support - case PARTIAL_AGG, EXPONENTIAL_HISTOGRAM, UNSUPPORTED -> TopNEncoder.UNSUPPORTED; + case PARTIAL_AGG, UNSUPPORTED -> TopNEncoder.UNSUPPORTED; }; } List orders = topNExec.order().stream().map(order -> { From 3c75c26eb15937f7429ab236489a8599b9cb2e3a Mon Sep 17 00:00:00 2001 From: Jonas Kunz Date: Tue, 28 Oct 2025 17:17:50 +0100 Subject: [PATCH 04/15] Add CSV Tests --- .../xpack/esql/ccq/MultiClusterSpecIT.java | 8 ++++ .../xpack/esql/qa/single_node/EsqlSpecIT.java | 8 ++++ .../xpack/esql/qa/rest/EsqlSpecTestCase.java | 30 +++++++++++- .../rest/generative/GenerativeRestTest.java | 2 +- .../elasticsearch/xpack/esql/CsvAssert.java | 7 +++ .../xpack/esql/CsvTestUtils.java | 30 +++++++++--- .../xpack/esql/CsvTestsDataLoader.java | 48 ++++++++++++++++--- .../main/resources/data/exp_histo_sample.csv | 8 ++++ .../src/main/resources/enrich.csv-spec | 1 + .../resources/exponential_histogram.csv-spec | 28 +++++++++++ .../src/main/resources/lookup-join.csv-spec | 1 + .../resources/mapping-exp_histo_sample.json | 10 ++++ 12 files changed, 166 insertions(+), 15 deletions(-) create mode 100644 x-pack/plugin/esql/qa/testFixtures/src/main/resources/data/exp_histo_sample.csv create mode 100644 x-pack/plugin/esql/qa/testFixtures/src/main/resources/exponential_histogram.csv-spec create mode 100644 x-pack/plugin/esql/qa/testFixtures/src/main/resources/mapping-exp_histo_sample.json diff --git a/x-pack/plugin/esql/qa/server/multi-clusters/src/javaRestTest/java/org/elasticsearch/xpack/esql/ccq/MultiClusterSpecIT.java b/x-pack/plugin/esql/qa/server/multi-clusters/src/javaRestTest/java/org/elasticsearch/xpack/esql/ccq/MultiClusterSpecIT.java index 5f5408d7fa189..6d8ceba077778 100644 --- a/x-pack/plugin/esql/qa/server/multi-clusters/src/javaRestTest/java/org/elasticsearch/xpack/esql/ccq/MultiClusterSpecIT.java +++ b/x-pack/plugin/esql/qa/server/multi-clusters/src/javaRestTest/java/org/elasticsearch/xpack/esql/ccq/MultiClusterSpecIT.java @@ -25,7 +25,9 @@ import org.elasticsearch.xpack.esql.CsvSpecReader.CsvTestCase; import org.elasticsearch.xpack.esql.CsvTestsDataLoader; import org.elasticsearch.xpack.esql.SpecReader; +import org.elasticsearch.xpack.esql.action.EsqlCapabilities; import org.elasticsearch.xpack.esql.qa.rest.EsqlSpecTestCase; +import org.elasticsearch.xpack.esql.qa.rest.RestEsqlTestCase; import org.junit.AfterClass; import org.junit.ClassRule; import org.junit.rules.RuleChain; @@ -422,4 +424,10 @@ protected boolean supportsTook() throws IOException { // We don't read took properly in multi-cluster tests. return false; } + + @Override + protected boolean supportsExponentialHistograms() { + return RestEsqlTestCase.hasCapabilities(client(), List.of(EsqlCapabilities.Cap.EXPONENTIAL_HISTOGRAM.capabilityName())) + && RestEsqlTestCase.hasCapabilities(remoteClusterClient, List.of(EsqlCapabilities.Cap.EXPONENTIAL_HISTOGRAM.capabilityName())); + } } diff --git a/x-pack/plugin/esql/qa/server/single-node/src/javaRestTest/java/org/elasticsearch/xpack/esql/qa/single_node/EsqlSpecIT.java b/x-pack/plugin/esql/qa/server/single-node/src/javaRestTest/java/org/elasticsearch/xpack/esql/qa/single_node/EsqlSpecIT.java index dacc34167955a..83d4e869319a6 100644 --- a/x-pack/plugin/esql/qa/server/single-node/src/javaRestTest/java/org/elasticsearch/xpack/esql/qa/single_node/EsqlSpecIT.java +++ b/x-pack/plugin/esql/qa/server/single-node/src/javaRestTest/java/org/elasticsearch/xpack/esql/qa/single_node/EsqlSpecIT.java @@ -16,13 +16,16 @@ import org.elasticsearch.xcontent.XContentBuilder; import org.elasticsearch.xcontent.json.JsonXContent; import org.elasticsearch.xpack.esql.CsvSpecReader.CsvTestCase; +import org.elasticsearch.xpack.esql.action.EsqlCapabilities; import org.elasticsearch.xpack.esql.planner.PlannerSettings; import org.elasticsearch.xpack.esql.plugin.ComputeService; import org.elasticsearch.xpack.esql.qa.rest.EsqlSpecTestCase; +import org.elasticsearch.xpack.esql.qa.rest.RestEsqlTestCase; import org.junit.Before; import org.junit.ClassRule; import java.io.IOException; +import java.util.List; @ThreadLeakFilters(filters = TestClustersThreadFilter.class) public class EsqlSpecIT extends EsqlSpecTestCase { @@ -51,6 +54,11 @@ protected boolean supportsSourceFieldMapping() { return cluster.getNumNodes() == 1; } + @Override + protected boolean supportsExponentialHistograms() { + return RestEsqlTestCase.hasCapabilities(client(), List.of(EsqlCapabilities.Cap.EXPONENTIAL_HISTOGRAM.capabilityName())); + } + @Before public void configureChunks() throws IOException { assumeTrue("test clusters were broken", testClustersOk); diff --git a/x-pack/plugin/esql/qa/server/src/main/java/org/elasticsearch/xpack/esql/qa/rest/EsqlSpecTestCase.java b/x-pack/plugin/esql/qa/server/src/main/java/org/elasticsearch/xpack/esql/qa/rest/EsqlSpecTestCase.java index bee67b1486192..220807a5fb5b0 100644 --- a/x-pack/plugin/esql/qa/server/src/main/java/org/elasticsearch/xpack/esql/qa/rest/EsqlSpecTestCase.java +++ b/x-pack/plugin/esql/qa/server/src/main/java/org/elasticsearch/xpack/esql/qa/rest/EsqlSpecTestCase.java @@ -16,6 +16,8 @@ import org.elasticsearch.client.ResponseException; import org.elasticsearch.client.RestClient; import org.elasticsearch.common.xcontent.XContentHelper; +import org.elasticsearch.core.Types; +import org.elasticsearch.exponentialhistogram.ExponentialHistogramXContent; import org.elasticsearch.features.NodeFeature; import org.elasticsearch.geometry.Geometry; import org.elasticsearch.geometry.Point; @@ -26,11 +28,14 @@ import org.elasticsearch.test.MapMatcher; import org.elasticsearch.test.rest.ESRestTestCase; import org.elasticsearch.test.rest.TestFeatureService; +import org.elasticsearch.xcontent.XContentParser; +import org.elasticsearch.xcontent.XContentParserConfiguration; import org.elasticsearch.xcontent.XContentType; import org.elasticsearch.xpack.esql.CsvSpecReader.CsvTestCase; import org.elasticsearch.xpack.esql.CsvTestUtils; import org.elasticsearch.xpack.esql.EsqlTestUtils; import org.elasticsearch.xpack.esql.SpecReader; +import org.elasticsearch.xpack.esql.action.EsqlCapabilities; import org.elasticsearch.xpack.esql.plugin.EsqlFeatures; import org.elasticsearch.xpack.esql.qa.rest.RestEsqlTestCase.Mode; import org.elasticsearch.xpack.esql.qa.rest.RestEsqlTestCase.RequestObjectBuilder; @@ -173,7 +178,14 @@ public void setup() { if (supportsInferenceTestService()) { createInferenceEndpoints(adminClient()); } - loadDataSetIntoEs(client(), supportsIndexModeLookup(), supportsSourceFieldMapping(), supportsInferenceTestService()); + loadDataSetIntoEs( + client(), + supportsIndexModeLookup(), + supportsSourceFieldMapping(), + supportsInferenceTestService(), + false, + supportsExponentialHistograms() + ); return null; }); } @@ -274,6 +286,10 @@ protected boolean supportsSourceFieldMapping() throws IOException { return true; } + protected boolean supportsExponentialHistograms() { + return RestEsqlTestCase.hasCapabilities(client(), List.of(EsqlCapabilities.Cap.EXPONENTIAL_HISTOGRAM.capabilityName())); + } + protected void doTest() throws Throwable { doTest(testCase.query); } @@ -390,6 +406,18 @@ private Object valueMapper(CsvTestUtils.Type type, Object value) { value = s.replaceAll("\\\\n", "\n"); } } + if (type == CsvTestUtils.Type.EXPONENTIAL_HISTOGRAM) { + if (value instanceof Map map) { + return ExponentialHistogramXContent.parseForTesting(Types.>forciblyCast(map)); + } + if (value instanceof String json) { + try (XContentParser parser = XContentType.JSON.xContent().createParser(XContentParserConfiguration.EMPTY, json)) { + return ExponentialHistogramXContent.parseForTesting(parser); + } catch (IOException e) { + throw new RuntimeException(e); + } + } + } return value.toString(); } diff --git a/x-pack/plugin/esql/qa/server/src/main/java/org/elasticsearch/xpack/esql/qa/rest/generative/GenerativeRestTest.java b/x-pack/plugin/esql/qa/server/src/main/java/org/elasticsearch/xpack/esql/qa/rest/generative/GenerativeRestTest.java index 4b94d8ccaf72f..6e612ae2b2e81 100644 --- a/x-pack/plugin/esql/qa/server/src/main/java/org/elasticsearch/xpack/esql/qa/rest/generative/GenerativeRestTest.java +++ b/x-pack/plugin/esql/qa/server/src/main/java/org/elasticsearch/xpack/esql/qa/rest/generative/GenerativeRestTest.java @@ -262,7 +262,7 @@ private static List originalTypes(Map x) { } private List availableIndices() throws IOException { - return availableDatasetsForEs(true, supportsSourceFieldMapping(), false, requiresTimeSeries()).stream() + return availableDatasetsForEs(true, supportsSourceFieldMapping(), false, requiresTimeSeries(), false).stream() .filter(x -> x.requiresInferenceEndpoint() == false) .map(x -> x.indexName()) .toList(); diff --git a/x-pack/plugin/esql/qa/testFixtures/src/main/java/org/elasticsearch/xpack/esql/CsvAssert.java b/x-pack/plugin/esql/qa/testFixtures/src/main/java/org/elasticsearch/xpack/esql/CsvAssert.java index 05d6b08b61ff2..93f3289508a2b 100644 --- a/x-pack/plugin/esql/qa/testFixtures/src/main/java/org/elasticsearch/xpack/esql/CsvAssert.java +++ b/x-pack/plugin/esql/qa/testFixtures/src/main/java/org/elasticsearch/xpack/esql/CsvAssert.java @@ -12,6 +12,7 @@ import org.elasticsearch.common.time.DateFormatter; import org.elasticsearch.compute.data.AggregateMetricDoubleBlockBuilder; import org.elasticsearch.compute.data.Page; +import org.elasticsearch.exponentialhistogram.ExponentialHistogram; import org.elasticsearch.geometry.utils.Geohash; import org.elasticsearch.h3.H3; import org.elasticsearch.logging.Logger; @@ -46,6 +47,7 @@ import static org.elasticsearch.xpack.esql.core.util.SpatialCoordinateTypes.CARTESIAN; import static org.elasticsearch.xpack.esql.core.util.SpatialCoordinateTypes.GEO; import static org.elasticsearch.xpack.esql.type.EsqlDataTypeConverter.aggregateMetricDoubleLiteralToString; +import static org.elasticsearch.xpack.esql.type.EsqlDataTypeConverter.exponentialHistogramToString; import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.Matchers.instanceOf; import static org.junit.Assert.assertEquals; @@ -431,6 +433,11 @@ private static Object convertExpectedValue(Type expectedType, Object expectedVal AggregateMetricDoubleBlockBuilder.AggregateMetricDoubleLiteral.class, x -> aggregateMetricDoubleLiteralToString((AggregateMetricDoubleBlockBuilder.AggregateMetricDoubleLiteral) x) ); + case EXPONENTIAL_HISTOGRAM -> rebuildExpected( + expectedValue, + ExponentialHistogram.class, + x -> exponentialHistogramToString((ExponentialHistogram) x) + ); default -> expectedValue; }; } diff --git a/x-pack/plugin/esql/qa/testFixtures/src/main/java/org/elasticsearch/xpack/esql/CsvTestUtils.java b/x-pack/plugin/esql/qa/testFixtures/src/main/java/org/elasticsearch/xpack/esql/CsvTestUtils.java index a1e1931d83502..349cc8c3e6a6f 100644 --- a/x-pack/plugin/esql/qa/testFixtures/src/main/java/org/elasticsearch/xpack/esql/CsvTestUtils.java +++ b/x-pack/plugin/esql/qa/testFixtures/src/main/java/org/elasticsearch/xpack/esql/CsvTestUtils.java @@ -23,15 +23,21 @@ import org.elasticsearch.compute.data.ElementType; import org.elasticsearch.compute.data.Page; import org.elasticsearch.core.Booleans; +import org.elasticsearch.core.Nullable; import org.elasticsearch.core.Releasable; import org.elasticsearch.core.Releasables; import org.elasticsearch.core.Strings; import org.elasticsearch.core.Tuple; +import org.elasticsearch.exponentialhistogram.ExponentialHistogram; +import org.elasticsearch.exponentialhistogram.ExponentialHistogramXContent; import org.elasticsearch.geometry.utils.Geohash; import org.elasticsearch.h3.H3; import org.elasticsearch.logging.Logger; import org.elasticsearch.search.aggregations.bucket.geogrid.GeoTileUtils; import org.elasticsearch.test.VersionUtils; +import org.elasticsearch.xcontent.XContentParser; +import org.elasticsearch.xcontent.XContentParserConfiguration; +import org.elasticsearch.xcontent.json.JsonXContent; import org.elasticsearch.xpack.esql.action.ResponseValueUtils; import org.elasticsearch.xpack.esql.core.type.DataType; import org.elasticsearch.xpack.esql.core.util.StringUtils; @@ -57,7 +63,6 @@ import java.util.regex.Pattern; import java.util.stream.Stream; -import static org.elasticsearch.common.Strings.delimitedListToStringArray; import static org.elasticsearch.common.logging.LoggerMessageFormat.format; import static org.elasticsearch.xpack.esql.EsqlTestUtils.reader; import static org.elasticsearch.xpack.esql.SpecReader.shouldSkipLine; @@ -143,13 +148,14 @@ void append(String stringValue) { return; } stringValue = mvStrings[0].replace(ESCAPED_COMMA_SEQUENCE, ","); - } else if (stringValue.contains(",") && type != Type.AGGREGATE_METRIC_DOUBLE) {// multi-value field + } else if (stringValue.matches(".*" + COMMA_ESCAPING_REGEX + ".*") && type != Type.AGGREGATE_METRIC_DOUBLE) {// multi-value + // field builderWrapper().builder().beginPositionEntry(); - String[] arrayOfValues = delimitedListToStringArray(stringValue, ","); + String[] arrayOfValues = stringValue.split(COMMA_ESCAPING_REGEX, -1); List convertedValues = new ArrayList<>(arrayOfValues.length); for (String value : arrayOfValues) { - convertedValues.add(type.convert(value)); + convertedValues.add(type.convert(value.replace(ESCAPED_COMMA_SEQUENCE, ","))); } Stream convertedValuesStream = convertedValues.stream(); if (type.sortMultiValues()) { @@ -161,7 +167,7 @@ void append(String stringValue) { return; } - var converted = stringValue.length() == 0 ? null : type.convert(stringValue); + var converted = stringValue.length() == 0 ? null : type.convert(stringValue.replace(ESCAPED_COMMA_SEQUENCE, ",")); builderWrapper().append().accept(converted); } @@ -498,6 +504,7 @@ public enum Type { AggregateMetricDoubleBlockBuilder.AggregateMetricDoubleLiteral.class ), DENSE_VECTOR(Float::parseFloat, Float.class, false), + EXPONENTIAL_HISTOGRAM(CsvTestUtils::parseExponentialHistogram, ExponentialHistogram.class), UNSUPPORTED(Type::convertUnsupported, Void.class); private static Void convertUnsupported(String s) { @@ -593,7 +600,7 @@ public static Type asType(ElementType elementType, Type actualType) { case DOC -> throw new IllegalArgumentException("can't assert on doc blocks"); case COMPOSITE -> throw new IllegalArgumentException("can't assert on composite blocks"); case AGGREGATE_METRIC_DOUBLE -> AGGREGATE_METRIC_DOUBLE; - case EXPONENTIAL_HISTOGRAM -> throw new IllegalArgumentException("exponential histogram blocks not supported yet"); + case EXPONENTIAL_HISTOGRAM -> EXPONENTIAL_HISTOGRAM; case UNKNOWN -> throw new IllegalArgumentException("Unknown block types cannot be handled"); }; } @@ -699,4 +706,15 @@ private static double scaledFloat(String value, String factor) { double scalingFactor = Double.parseDouble(factor); return new BigDecimal(value).multiply(BigDecimal.valueOf(scalingFactor)).longValue() / scalingFactor; } + + private static ExponentialHistogram parseExponentialHistogram(@Nullable String json) { + if (json == null) { + return null; + } + try (XContentParser parser = JsonXContent.jsonXContent.createParser(XContentParserConfiguration.EMPTY, json)) { + return ExponentialHistogramXContent.parseForTesting(parser); + } catch (IOException e) { + throw new IllegalArgumentException(e); + } + } } diff --git a/x-pack/plugin/esql/qa/testFixtures/src/main/java/org/elasticsearch/xpack/esql/CsvTestsDataLoader.java b/x-pack/plugin/esql/qa/testFixtures/src/main/java/org/elasticsearch/xpack/esql/CsvTestsDataLoader.java index d056050f8fe97..bd42ee08ed384 100644 --- a/x-pack/plugin/esql/qa/testFixtures/src/main/java/org/elasticsearch/xpack/esql/CsvTestsDataLoader.java +++ b/x-pack/plugin/esql/qa/testFixtures/src/main/java/org/elasticsearch/xpack/esql/CsvTestsDataLoader.java @@ -172,6 +172,7 @@ public class CsvTestsDataLoader { private static final TestDataset DENSE_VECTOR = new TestDataset("dense_vector"); private static final TestDataset COLORS = new TestDataset("colors"); private static final TestDataset COLORS_CMYK_LOOKUP = new TestDataset("colors_cmyk").withSetting("lookup-settings.json"); + private static final TestDataset EXP_HISTO_SAMPLE = new TestDataset("exp_histo_sample"); public static final Map CSV_DATASET_MAP = Map.ofEntries( Map.entry(EMPLOYEES.indexName, EMPLOYEES), @@ -239,7 +240,8 @@ public class CsvTestsDataLoader { Map.entry(COLORS.indexName, COLORS), Map.entry(COLORS_CMYK_LOOKUP.indexName, COLORS_CMYK_LOOKUP), Map.entry(MULTI_COLUMN_JOINABLE.indexName, MULTI_COLUMN_JOINABLE), - Map.entry(MULTI_COLUMN_JOINABLE_LOOKUP.indexName, MULTI_COLUMN_JOINABLE_LOOKUP) + Map.entry(MULTI_COLUMN_JOINABLE_LOOKUP.indexName, MULTI_COLUMN_JOINABLE_LOOKUP), + Map.entry(EXP_HISTO_SAMPLE.indexName, EXP_HISTO_SAMPLE) ); private static final EnrichConfig LANGUAGES_ENRICH = new EnrichConfig("languages_policy", "enrich-policy-languages.json"); @@ -331,7 +333,7 @@ public static void main(String[] args) throws IOException { } try (RestClient client = builder.build()) { - loadDataSetIntoEs(client, true, true, false, false, (restClient, indexName, indexMapping, indexSettings) -> { + loadDataSetIntoEs(client, true, true, false, false, true, (restClient, indexName, indexMapping, indexSettings) -> { // don't use ESRestTestCase methods here or, if you do, test running the main method before making the change StringBuilder jsonBody = new StringBuilder("{"); if (indexSettings != null && indexSettings.isEmpty() == false) { @@ -354,7 +356,8 @@ public static Set availableDatasetsForEs( boolean supportsIndexModeLookup, boolean supportsSourceFieldMapping, boolean inferenceEnabled, - boolean requiresTimeSeries + boolean requiresTimeSeries, + boolean exponentialHistogramFieldSupported ) throws IOException { Set testDataSets = new HashSet<>(); @@ -362,7 +365,8 @@ public static Set availableDatasetsForEs( if ((inferenceEnabled || dataset.requiresInferenceEndpoint == false) && (supportsIndexModeLookup || isLookupDataset(dataset) == false) && (supportsSourceFieldMapping || isSourceMappingDataset(dataset) == false) - && (requiresTimeSeries == false || isTimeSeries(dataset))) { + && (requiresTimeSeries == false || isTimeSeries(dataset)) + && (exponentialHistogramFieldSupported || containsExponentialHistogramFields(dataset) == false)) { testDataSets.add(dataset); } } @@ -386,6 +390,27 @@ private static boolean isSourceMappingDataset(TestDataset dataset) throws IOExce return mappingNode.get("_source") != null; } + private static boolean containsExponentialHistogramFields(TestDataset dataset) throws IOException { + if (dataset.mappingFileName() == null) { + return false; + } + String mappingJsonText = readTextFile(getResource("/" + dataset.mappingFileName())); + JsonNode mappingNode = new ObjectMapper().readTree(mappingJsonText); + JsonNode properties = mappingNode.get("properties"); + if (properties != null) { + for (var fieldWithValue : properties.properties()) { + JsonNode fieldProperties = fieldWithValue.getValue(); + if (fieldProperties != null) { + JsonNode typeNode = fieldProperties.get("type"); + if (typeNode != null && typeNode.asText().equals("exponential_histogram")) { + return true; + } + } + } + } + return false; + } + private static boolean isTimeSeries(TestDataset dataset) throws IOException { Settings settings = dataset.readSettingsFile(); String mode = settings.get("index.mode"); @@ -398,7 +423,7 @@ public static void loadDataSetIntoEs( boolean supportsSourceFieldMapping, boolean inferenceEnabled ) throws IOException { - loadDataSetIntoEs(client, supportsIndexModeLookup, supportsSourceFieldMapping, inferenceEnabled, false); + loadDataSetIntoEs(client, supportsIndexModeLookup, supportsSourceFieldMapping, inferenceEnabled, false, false); } public static void loadDataSetIntoEs( @@ -406,7 +431,8 @@ public static void loadDataSetIntoEs( boolean supportsIndexModeLookup, boolean supportsSourceFieldMapping, boolean inferenceEnabled, - boolean timeSeriesOnly + boolean timeSeriesOnly, + boolean exponentialHistogramFieldSupported ) throws IOException { loadDataSetIntoEs( client, @@ -414,6 +440,7 @@ public static void loadDataSetIntoEs( supportsSourceFieldMapping, inferenceEnabled, timeSeriesOnly, + exponentialHistogramFieldSupported, (restClient, indexName, indexMapping, indexSettings) -> { ESRestTestCase.createIndex(restClient, indexName, indexSettings, indexMapping, null); } @@ -426,13 +453,20 @@ private static void loadDataSetIntoEs( boolean supportsSourceFieldMapping, boolean inferenceEnabled, boolean timeSeriesOnly, + boolean exponentialHistogramFieldSupported, IndexCreator indexCreator ) throws IOException { Logger logger = LogManager.getLogger(CsvTestsDataLoader.class); Set loadedDatasets = new HashSet<>(); logger.info("Loading test datasets"); - for (var dataset : availableDatasetsForEs(supportsIndexModeLookup, supportsSourceFieldMapping, inferenceEnabled, timeSeriesOnly)) { + for (var dataset : availableDatasetsForEs( + supportsIndexModeLookup, + supportsSourceFieldMapping, + inferenceEnabled, + timeSeriesOnly, + exponentialHistogramFieldSupported + )) { load(client, dataset, logger, indexCreator); loadedDatasets.add(dataset.indexName); } diff --git a/x-pack/plugin/esql/qa/testFixtures/src/main/resources/data/exp_histo_sample.csv b/x-pack/plugin/esql/qa/testFixtures/src/main/resources/data/exp_histo_sample.csv new file mode 100644 index 0000000000000..1ddc703245893 --- /dev/null +++ b/x-pack/plugin/esql/qa/testFixtures/src/main/resources/data/exp_histo_sample.csv @@ -0,0 +1,8 @@ +name:keyword,histo:exponential_histogram +empty,{"scale":-7} +full,{"scale":12\,"min":-456\,"max":789\,"sum":43\,"zero":{"threshold":0.123456\,"count":42}\,"positive":{"indices":[-1000000\,-10\,25\,26\,99999999]\,"counts":[2\,1\,3\,4\,5]}\,"negative":{"indices":[-1000\,123456\,-999]\,"counts":[10\,11\,20]}} +no_zero_bucket,{"scale":-10\,"min":-123\,"max":456\,"sum":42\,"positive":{"indices":[1\,2\,3\,4\,5]\,"counts":[6\,7\,8\,9\,10]}\,"negative":{"indices":[-1\,0\,1\,2\,3\,4\,5\,6\,7\,8]\,"counts":[1\,2\,3\,4\,5\,6\,7\,8\,9\,10]}} +positive_only,{"scale":0\,"min":0.1\,"max":100\,"sum":424\,"positive":{"indices":[-100\,10\,20]\,"counts":[3\,2\,1]}} +negative_only,{"scale":0\,"min":-100\,"max":-0.1\,"sum":-424\,"negative":{"indices":[-100\,10\,20]\,"counts":[3\,2\,1]}} +zero_threshold_only,{"scale":0\,"zero":{"threshold":42.7}} +zero_count_only,{"scale":2\,"min":0\,"max":0\,"zero":{"count":101}} diff --git a/x-pack/plugin/esql/qa/testFixtures/src/main/resources/enrich.csv-spec b/x-pack/plugin/esql/qa/testFixtures/src/main/resources/enrich.csv-spec index f60b876a1c7ee..4d00da8a7a811 100644 --- a/x-pack/plugin/esql/qa/testFixtures/src/main/resources/enrich.csv-spec +++ b/x-pack/plugin/esql/qa/testFixtures/src/main/resources/enrich.csv-spec @@ -651,6 +651,7 @@ fieldsInOtherIndicesBug required_capability: enrich_load required_capability: fix_replace_missing_field_with_null_duplicate_name_id_in_layout required_capability: dense_vector_agg_metric_double_if_fns +required_capability: exponential_histogram from * | keep author.keyword, book_no, scalerank, street, bytes_in, @timestamp, abbrev, city_location, distance, description, birth_date, language_code, intersects, client_ip, event_duration, version diff --git a/x-pack/plugin/esql/qa/testFixtures/src/main/resources/exponential_histogram.csv-spec b/x-pack/plugin/esql/qa/testFixtures/src/main/resources/exponential_histogram.csv-spec new file mode 100644 index 0000000000000..6231b747d2074 --- /dev/null +++ b/x-pack/plugin/esql/qa/testFixtures/src/main/resources/exponential_histogram.csv-spec @@ -0,0 +1,28 @@ +loadAll +required_capability: exponential_histogram + +FROM exp_histo_sample | KEEP name, histo +; +ignoreOrder:true + +name:keyword | histo:exponential_histogram +empty | "{""scale"":-7}" +full | "{""scale"":12,""min"":-456,""max"":789,""sum"":43,""zero"":{""threshold"":0.123456,""count"":42},""positive"":{""indices"":[-1000000,-10,25,26,99999999],""counts"":[2,1,3,4,5]},""negative"":{""indices"":[-1000,123456,-999],""counts"":[10,11,20]}}" +no_zero_bucket | "{""scale"":-10,""min"":-123,""max"":456,""sum"":42,""positive"":{""indices"":[1,2,3,4,5],""counts"":[6,7,8,9,10]},""negative"":{""indices"":[-1,0,1,2,3,4,5,6,7,8],""counts"":[1,2,3,4,5,6,7,8,9,10]}}" +positive_only | "{""scale"":0,""min"":0.1,""max"":100,""sum"":424,""positive"":{""indices"":[-100,10,20],""counts"":[3,2,1]}}" +negative_only | "{""scale"":0,""min"":-100,""max"":-0.1,""sum"":-424,""negative"":{""indices"":[-100,10,20],""counts"":[3,2,1]}}" +zero_threshold_only | "{""scale"":0,""zero"":{""threshold"":42.7}}" +zero_count_only | "{""scale"":2,""min"":0,""max"":0,""zero"":{""count"":101}}" +; + +loadFiltered +required_capability: exponential_histogram + +from exp_histo_sample | WHERE STARTS_WITH(name, "zero_") | KEEP name, histo +; +ignoreOrder:true + +name:keyword | histo:exponential_histogram +zero_threshold_only | "{""scale"":0,""zero"":{""threshold"":42.7}}" +zero_count_only | "{""scale"":2,""min"":0,""max"":0,""zero"":{""count"":101}}" +; diff --git a/x-pack/plugin/esql/qa/testFixtures/src/main/resources/lookup-join.csv-spec b/x-pack/plugin/esql/qa/testFixtures/src/main/resources/lookup-join.csv-spec index b4318ee4687da..a5c07c9a7ba28 100644 --- a/x-pack/plugin/esql/qa/testFixtures/src/main/resources/lookup-join.csv-spec +++ b/x-pack/plugin/esql/qa/testFixtures/src/main/resources/lookup-join.csv-spec @@ -1692,6 +1692,7 @@ enrichLookupStatsBug required_capability: join_lookup_v12 required_capability: fix_replace_missing_field_with_null_duplicate_name_id_in_layout required_capability: dense_vector_agg_metric_double_if_fns +required_capability: exponential_histogram from * | enrich languages_policy on cluster diff --git a/x-pack/plugin/esql/qa/testFixtures/src/main/resources/mapping-exp_histo_sample.json b/x-pack/plugin/esql/qa/testFixtures/src/main/resources/mapping-exp_histo_sample.json new file mode 100644 index 0000000000000..f5b520391f7df --- /dev/null +++ b/x-pack/plugin/esql/qa/testFixtures/src/main/resources/mapping-exp_histo_sample.json @@ -0,0 +1,10 @@ +{ + "properties": { + "name": { + "type": "keyword" + }, + "histo": { + "type": "exponential_histogram" + } + } +} From 05f06654a39b00ac3a26c13dea3a019769753ce2 Mon Sep 17 00:00:00 2001 From: Jonas Kunz Date: Wed, 29 Oct 2025 18:30:52 +0100 Subject: [PATCH 05/15] Implement HistogramPercentile function --- .../resources/exponential_histogram.csv-spec | 16 ++ .../function/EsqlFunctionRegistry.java | 3 + .../scalar/ScalarFunctionWritables.java | 2 + .../scalar/histogram/HistogramPercentile.java | 223 ++++++++++++++++++ 4 files changed, 244 insertions(+) create mode 100644 x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/histogram/HistogramPercentile.java diff --git a/x-pack/plugin/esql/qa/testFixtures/src/main/resources/exponential_histogram.csv-spec b/x-pack/plugin/esql/qa/testFixtures/src/main/resources/exponential_histogram.csv-spec index 6231b747d2074..66fc624086acb 100644 --- a/x-pack/plugin/esql/qa/testFixtures/src/main/resources/exponential_histogram.csv-spec +++ b/x-pack/plugin/esql/qa/testFixtures/src/main/resources/exponential_histogram.csv-spec @@ -26,3 +26,19 @@ name:keyword | histo:exponential_histogram zero_threshold_only | "{""scale"":0,""zero"":{""threshold"":42.7}}" zero_count_only | "{""scale"":2,""min"":0,""max"":0,""zero"":{""count"":101}}" ; + +computePercentile +required_capability: exponential_histogram + +FROM exp_histo_sample | SORT name | EVAL perc_50 = HISTOGRAM_PERCENTILE(histo, 50) | KEEP perc_50, histo +; + +perc_50:double | histo:exponential_histogram +null | "{""scale"":-7,""sum"":0.0}" +0.0 | "{""scale"":12,""sum"":43.0,""min"":-456.0,""max"":789.0,""zero"":{""count"":42,""threshold"":0.123456},""positive"":{""indices"":[-1000000,-10,25,26,99999999],""counts"":[2,1,3,4,5]},""negative"":{""indices"":[-1000,-999,123456],""counts"":[10,20,11]}}" +-50.05 | "{""scale"":0,""sum"":-424.0,""min"":-100.0,""max"":-0.1,""negative"":{""indices"":[-100,10,20],""counts"":[3,2,1]}}" +-123.0 | "{""scale"":-10,""sum"":42.0,""min"":-123.0,""max"":456.0,""positive"":{""indices"":[1,2,3,4,5],""counts"":[6,7,8,9,10]},""negative"":{""indices"":[-1,0,1,2,3,4,5,6,7,8],""counts"":[1,2,3,4,5,6,7,8,9,10]}}" +50.05 | "{""scale"":0,""sum"":424.0,""min"":0.1,""max"":100.0,""positive"":{""indices"":[-100,10,20],""counts"":[3,2,1]}}" +0.0 | "{""scale"":2,""sum"":0.0,""min"":0.0,""max"":0.0,""zero"":{""count"":101}}" +null | "{""scale"":0,""sum"":0.0,""zero"":{""threshold"":42.7}}" +; diff --git a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/EsqlFunctionRegistry.java b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/EsqlFunctionRegistry.java index ee45267c7bbf1..a93d4aba3f070 100644 --- a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/EsqlFunctionRegistry.java +++ b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/EsqlFunctionRegistry.java @@ -116,6 +116,7 @@ import org.elasticsearch.xpack.esql.expression.function.scalar.date.MonthName; import org.elasticsearch.xpack.esql.expression.function.scalar.date.Now; import org.elasticsearch.xpack.esql.expression.function.scalar.date.TRange; +import org.elasticsearch.xpack.esql.expression.function.scalar.histogram.HistogramPercentile; import org.elasticsearch.xpack.esql.expression.function.scalar.ip.CIDRMatch; import org.elasticsearch.xpack.esql.expression.function.scalar.ip.IpPrefix; import org.elasticsearch.xpack.esql.expression.function.scalar.ip.NetworkDirection; @@ -471,6 +472,8 @@ private static FunctionDefinition[][] functions() { new FunctionDefinition[] { def(CIDRMatch.class, CIDRMatch::new, "cidr_match") }, new FunctionDefinition[] { def(IpPrefix.class, IpPrefix::new, "ip_prefix") }, new FunctionDefinition[] { def(NetworkDirection.class, NetworkDirection::new, "network_direction", "netdir") }, + // histogram functions TODO: only for testing, don't forget to remove + new FunctionDefinition[] { def(HistogramPercentile.class, HistogramPercentile::new, "histogram_percentile") }, // conversion functions new FunctionDefinition[] { def(FromBase64.class, FromBase64::new, "from_base64"), diff --git a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/ScalarFunctionWritables.java b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/ScalarFunctionWritables.java index 5087b376b9649..859cad2150685 100644 --- a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/ScalarFunctionWritables.java +++ b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/ScalarFunctionWritables.java @@ -23,6 +23,7 @@ import org.elasticsearch.xpack.esql.expression.function.scalar.date.DayName; import org.elasticsearch.xpack.esql.expression.function.scalar.date.MonthName; import org.elasticsearch.xpack.esql.expression.function.scalar.date.Now; +import org.elasticsearch.xpack.esql.expression.function.scalar.histogram.HistogramPercentile; import org.elasticsearch.xpack.esql.expression.function.scalar.ip.CIDRMatch; import org.elasticsearch.xpack.esql.expression.function.scalar.ip.IpPrefix; import org.elasticsearch.xpack.esql.expression.function.scalar.ip.NetworkDirection; @@ -118,6 +119,7 @@ public static List getNamedWriteables() { entries.add(Tau.ENTRY); entries.add(ToLower.ENTRY); entries.add(ToUpper.ENTRY); + entries.add(HistogramPercentile.ENTRY); entries.addAll(GroupingWritables.getNamedWriteables()); return entries; diff --git a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/histogram/HistogramPercentile.java b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/histogram/HistogramPercentile.java new file mode 100644 index 0000000000000..e2211e4d4f92e --- /dev/null +++ b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/histogram/HistogramPercentile.java @@ -0,0 +1,223 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +package org.elasticsearch.xpack.esql.expression.function.scalar.histogram; + +import org.apache.lucene.util.RamUsageEstimator; +import org.elasticsearch.common.io.stream.NamedWriteableRegistry; +import org.elasticsearch.common.io.stream.StreamInput; +import org.elasticsearch.common.io.stream.StreamOutput; +import org.elasticsearch.compute.data.Block; +import org.elasticsearch.compute.data.DoubleBlock; +import org.elasticsearch.compute.data.ExponentialHistogramBlock; +import org.elasticsearch.compute.data.ExponentialHistogramBlockAccessor; +import org.elasticsearch.compute.data.Page; +import org.elasticsearch.compute.operator.DriverContext; +import org.elasticsearch.compute.operator.EvalOperator; +import org.elasticsearch.compute.operator.Warnings; +import org.elasticsearch.core.Releasables; +import org.elasticsearch.exponentialhistogram.ExponentialHistogram; +import org.elasticsearch.exponentialhistogram.ExponentialHistogramQuantile; +import org.elasticsearch.xpack.esql.EsqlIllegalArgumentException; +import org.elasticsearch.xpack.esql.core.expression.Expression; +import org.elasticsearch.xpack.esql.core.tree.NodeInfo; +import org.elasticsearch.xpack.esql.core.tree.Source; +import org.elasticsearch.xpack.esql.core.type.DataType; +import org.elasticsearch.xpack.esql.expression.function.FunctionInfo; +import org.elasticsearch.xpack.esql.expression.function.Param; +import org.elasticsearch.xpack.esql.expression.function.scalar.EsqlScalarFunction; +import org.elasticsearch.xpack.esql.expression.function.scalar.math.Cast; +import org.elasticsearch.xpack.esql.io.stream.PlanStreamInput; + +import java.io.IOException; +import java.util.List; + +public class HistogramPercentile extends EsqlScalarFunction { + + public static final NamedWriteableRegistry.Entry ENTRY = new NamedWriteableRegistry.Entry( + Expression.class, + "HistogramPercentile", + HistogramPercentile::new + ); + + private final Expression histogram; + private final Expression percentile; + + @FunctionInfo(returnType = { "double" }) + public HistogramPercentile(Source source, + @Param( + name = "histogram", + type = { "exponential_histogram" } + ) + Expression histogram, + @Param( + name = "percentile", + type = { "double", "integer", "long", "unsigned_long" } + ) + Expression percentile) { + super(source, List.of(histogram, percentile)); + this.histogram = histogram; + this.percentile = percentile; + } + + private HistogramPercentile(StreamInput in) throws IOException { + this(Source.readFrom((PlanStreamInput) in), in.readNamedWriteable(Expression.class), in.readNamedWriteable(Expression.class)); + } + + @Override + public DataType dataType() { + return DataType.DOUBLE; + } + + @Override + public Expression replaceChildren(List newChildren) { + return new HistogramPercentile(source(), newChildren.get(0), newChildren.get(1)); + } + + @Override + protected NodeInfo info() { + return NodeInfo.create(this, HistogramPercentile::new, histogram, percentile); + } + + @Override + public String getWriteableName() { + return ENTRY.name; + } + + @Override + public void writeTo(StreamOutput out) throws IOException { + source().writeTo(out); + out.writeNamedWriteable(histogram); + out.writeNamedWriteable(percentile); + } + + @Override + public EvalOperator.ExpressionEvaluator.Factory toEvaluator(ToEvaluator toEvaluator) { + DataType fieldDataType = histogram.dataType(); + if (fieldDataType != DataType.EXPONENTIAL_HISTOGRAM) { + throw EsqlIllegalArgumentException.illegalDataType(fieldDataType); + } + var fieldEvaluator = toEvaluator.apply(histogram); + var percentileEvaluator = Cast.cast(source(), percentile.dataType(), DataType.DOUBLE, toEvaluator.apply(percentile)); + + return new EvalOperator.ExpressionEvaluator.Factory() { + + @Override + public String toString() { + return "HistogramPercentileEvaluator[" + "field=" + fieldEvaluator + ",percentile=" + percentileEvaluator + "]"; + } + + @Override + public EvalOperator.ExpressionEvaluator get(DriverContext context) { + var histogram = fieldEvaluator.get(context); + var percentile = percentileEvaluator.get(context); + return new Evaluator(source(), context, histogram, percentile); + } + }; + } + + private static class Evaluator implements EvalOperator.ExpressionEvaluator { + + private static final long BASE_RAM_BYTES_USED = RamUsageEstimator.shallowSizeOfInstance(Evaluator.class); + + private final DriverContext driverContext; + private final EvalOperator.ExpressionEvaluator histogram; + private final EvalOperator.ExpressionEvaluator percentile; + private final Source source; + + private Warnings warnings; + + private Evaluator( + Source source, + DriverContext driverContext, + EvalOperator.ExpressionEvaluator histogram, + EvalOperator.ExpressionEvaluator percentile + ) { + this.source = source; + this.driverContext = driverContext; + this.histogram = histogram; + this.percentile = percentile; + } + + private Warnings warnings() { + if (warnings == null) { + this.warnings = Warnings.createWarnings( + driverContext.warningsMode(), + source.source().getLineNumber(), + source.source().getColumnNumber(), + source.text() + ); + } + return warnings; + } + + @Override + public Block eval(Page page) { + // TODO this is a ton of boilerplate, which will we repeated for every function + // we should adapt EvaluatorImplementer instead to deal with exponential histograms + ExponentialHistogramBlock histogramBlock = null; + DoubleBlock percentileBlock = null; + int positionCount = page.getPositionCount(); + try (DoubleBlock.Builder result = driverContext.blockFactory().newDoubleBlockBuilder(positionCount)) { + histogramBlock = (ExponentialHistogramBlock) histogram.eval(page); + percentileBlock = (DoubleBlock) percentile.eval(page); + var histogramAccessor = new ExponentialHistogramBlockAccessor(histogramBlock); + position: for (int p = 0; p < positionCount; p++) { + switch (percentileBlock.getValueCount(p)) { + case 0: + result.appendNull(); + continue position; + case 1: + break; + default: + warnings().registerException(IllegalArgumentException.class, "single-value function encountered multi-value"); + result.appendNull(); + continue position; + } + switch (histogramBlock.getValueCount(p)) { + case 0: + result.appendNull(); + continue position; + case 1: + break; + default: + warnings().registerException(IllegalArgumentException.class, "single-value function encountered multi-value"); + result.appendNull(); + continue position; + } + + ExponentialHistogram histogram = histogramAccessor.get(histogramBlock.getFirstValueIndex(p)); + double percentile = percentileBlock.getDouble(percentileBlock.getFirstValueIndex(p)); + double resultValue = ExponentialHistogramQuantile.getQuantile(histogram, percentile / 100.0); + if (Double.isNaN(resultValue)) { + result.appendNull(); + } else { + result.appendDouble(resultValue); + } + } + return result.build(); + } finally { + Releasables.close(histogramBlock, percentileBlock); + } + } + + @Override + public long baseRamBytesUsed() { + return BASE_RAM_BYTES_USED + histogram.baseRamBytesUsed() + percentile.baseRamBytesUsed(); + } + + @Override + public void close() { + Releasables.closeExpectNoException(histogram, percentile); + } + + @Override + public String toString() { + return "HistogramPercentileEvaluator[field=" + histogram + ",subfieldIndex=" + percentile + "]"; + } + } +} From 7f416b479f70f2fbf168fae0fe4d4bf7773bb7b4 Mon Sep 17 00:00:00 2001 From: Jonas Kunz Date: Thu, 30 Oct 2025 12:43:06 +0100 Subject: [PATCH 06/15] Fix top-n impl --- .../org/elasticsearch/compute/data/ConstantNullBlock.java | 6 ++++++ .../compute/data/ExponentialHistogramArrayBlock.java | 5 +++-- .../compute/data/ExponentialHistogramBlock.java | 5 ++++- .../compute/data/ExponentialHistogramBlockBuilder.java | 2 +- .../topn/ValueExtractorForExponentialHistogram.java | 8 ++++---- 5 files changed, 18 insertions(+), 8 deletions(-) diff --git a/x-pack/plugin/esql/compute/src/main/java/org/elasticsearch/compute/data/ConstantNullBlock.java b/x-pack/plugin/esql/compute/src/main/java/org/elasticsearch/compute/data/ConstantNullBlock.java index 0dc4a67ab6100..81b2b5d880d8d 100644 --- a/x-pack/plugin/esql/compute/src/main/java/org/elasticsearch/compute/data/ConstantNullBlock.java +++ b/x-pack/plugin/esql/compute/src/main/java/org/elasticsearch/compute/data/ConstantNullBlock.java @@ -300,6 +300,12 @@ public ExponentialHistogram getExponentialHistogram(int valueIndex, ExponentialH throw new UnsupportedOperationException("null block"); } + @Override + public void serializeExponentialHistogram(SerializedOutput out, int valueIndex, BytesRef scratch) { + assert false : "null block"; + throw new UnsupportedOperationException("null block"); + } + @Override public int getTotalValueCount() { return 0; diff --git a/x-pack/plugin/esql/compute/src/main/java/org/elasticsearch/compute/data/ExponentialHistogramArrayBlock.java b/x-pack/plugin/esql/compute/src/main/java/org/elasticsearch/compute/data/ExponentialHistogramArrayBlock.java index 0225fab889bae..de112132c15e8 100644 --- a/x-pack/plugin/esql/compute/src/main/java/org/elasticsearch/compute/data/ExponentialHistogramArrayBlock.java +++ b/x-pack/plugin/esql/compute/src/main/java/org/elasticsearch/compute/data/ExponentialHistogramArrayBlock.java @@ -94,7 +94,8 @@ public ExponentialHistogram getExponentialHistogram(int valueIndex, ExponentialH } } - void serializeValue(int valueIndex, SerializedOutput out, BytesRef tempBytesRef) { + @Override + public void serializeExponentialHistogram(ExponentialHistogramBlock.SerializedOutput out, int valueIndex, BytesRef scratch) { long valueCount = getHistogramValueCount(valueIndex); out.appendLong(valueCount); out.appendDouble(getHistogramSum(valueIndex)); @@ -104,7 +105,7 @@ void serializeValue(int valueIndex, SerializedOutput out, BytesRef tempBytesRef) out.appendDouble(getHistogramMin(valueIndex)); out.appendDouble(getHistogramMax(valueIndex)); } - out.appendBytesRef(getEncodedHistogramBytes(valueIndex, tempBytesRef)); + out.appendBytesRef(getEncodedHistogramBytes(valueIndex, scratch)); } private double getHistogramMin(int valueIndex) { diff --git a/x-pack/plugin/esql/compute/src/main/java/org/elasticsearch/compute/data/ExponentialHistogramBlock.java b/x-pack/plugin/esql/compute/src/main/java/org/elasticsearch/compute/data/ExponentialHistogramBlock.java index f2c95ede6fd8c..c918367dbfcf3 100644 --- a/x-pack/plugin/esql/compute/src/main/java/org/elasticsearch/compute/data/ExponentialHistogramBlock.java +++ b/x-pack/plugin/esql/compute/src/main/java/org/elasticsearch/compute/data/ExponentialHistogramBlock.java @@ -16,7 +16,8 @@ public sealed interface ExponentialHistogramBlock extends Block permits ConstantNullBlock, ExponentialHistogramArrayBlock { /** - * Abstraction to use for writing individual values via {@link ExponentialHistogramBlockAccessor#serializeValue(int, SerializedOutput)}. + * Abstraction to use for writing individual values via + * {@link ExponentialHistogramBlock#serializeExponentialHistogram(SerializedOutput, int, BytesRef)}. */ interface SerializedOutput { void appendDouble(double value); @@ -51,6 +52,8 @@ interface SerializedInput { */ ExponentialHistogram getExponentialHistogram(int valueIndex, ExponentialHistogramScratch scratch); + void serializeExponentialHistogram(ExponentialHistogramBlock.SerializedOutput out, int valueIndex, BytesRef scratch); + static boolean equals(ExponentialHistogramBlock blockA, ExponentialHistogramBlock blockB) { if (blockA == blockB) { return true; diff --git a/x-pack/plugin/esql/compute/src/main/java/org/elasticsearch/compute/data/ExponentialHistogramBlockBuilder.java b/x-pack/plugin/esql/compute/src/main/java/org/elasticsearch/compute/data/ExponentialHistogramBlockBuilder.java index 0128726233a11..18431e8510ee8 100644 --- a/x-pack/plugin/esql/compute/src/main/java/org/elasticsearch/compute/data/ExponentialHistogramBlockBuilder.java +++ b/x-pack/plugin/esql/compute/src/main/java/org/elasticsearch/compute/data/ExponentialHistogramBlockBuilder.java @@ -105,7 +105,7 @@ public ExponentialHistogramBlockBuilder append(ExponentialHistogram histogram) { /** * Decodes and appends a value serialized with - * {@link ExponentialHistogramBlockAccessor#serializeValue(int, ExponentialHistogramBlock.SerializedOutput)}. + * {@link ExponentialHistogramBlock#serializeExponentialHistogram(ExponentialHistogramBlock.SerializedOutput, int, BytesRef)} . * * @param input the input to deserialize from */ diff --git a/x-pack/plugin/esql/compute/src/main/java/org/elasticsearch/compute/operator/topn/ValueExtractorForExponentialHistogram.java b/x-pack/plugin/esql/compute/src/main/java/org/elasticsearch/compute/operator/topn/ValueExtractorForExponentialHistogram.java index ce83ea5494b65..dc981f029f7d8 100644 --- a/x-pack/plugin/esql/compute/src/main/java/org/elasticsearch/compute/operator/topn/ValueExtractorForExponentialHistogram.java +++ b/x-pack/plugin/esql/compute/src/main/java/org/elasticsearch/compute/operator/topn/ValueExtractorForExponentialHistogram.java @@ -9,18 +9,18 @@ import org.apache.lucene.util.BytesRef; import org.elasticsearch.compute.data.ExponentialHistogramBlock; -import org.elasticsearch.compute.data.ExponentialHistogramBlockAccessor; +import org.elasticsearch.compute.data.ExponentialHistogramScratch; import org.elasticsearch.compute.operator.BreakingBytesRefBuilder; public class ValueExtractorForExponentialHistogram implements ValueExtractor { private final ExponentialHistogramBlock block; - private final ExponentialHistogramBlockAccessor accessor; + private final BytesRef scratch; private final ReusableTopNEncoderOutput reusableOutput = new ReusableTopNEncoderOutput(); ValueExtractorForExponentialHistogram(TopNEncoder encoder, ExponentialHistogramBlock block) { assert encoder == TopNEncoder.DEFAULT_UNSORTABLE; this.block = block; - this.accessor = new ExponentialHistogramBlockAccessor(block); + this.scratch = new BytesRef(); } @Override @@ -33,7 +33,7 @@ public void writeValue(BreakingBytesRefBuilder values, int position) { TopNEncoder.DEFAULT_UNSORTABLE.encodeVInt(1, values); int valueIndex = block.getFirstValueIndex(position); reusableOutput.target = values; - accessor.serializeValue(valueIndex, reusableOutput); + block.serializeExponentialHistogram(reusableOutput, valueIndex, scratch); } } From 71021da8ac2bcf842271e77d5d7d99b11bd137c8 Mon Sep 17 00:00:00 2001 From: Jonas Kunz Date: Thu, 30 Oct 2025 15:12:43 +0100 Subject: [PATCH 07/15] Switch to code-generation --- .../compute/gen/EvaluatorImplementer.java | 11 +- .../elasticsearch/compute/gen/Methods.java | 3 + .../org/elasticsearch/compute/gen/Types.java | 15 +- .../compute/gen/argument/Argument.java | 16 +- .../gen/argument/StandardArgument.java | 7 +- .../HistogramPercentileEvaluator.java | 146 ++++++++++++++++++ .../scalar/histogram/HistogramPercentile.java | 138 ++--------------- 7 files changed, 198 insertions(+), 138 deletions(-) create mode 100644 x-pack/plugin/esql/src/main/generated/org/elasticsearch/xpack/esql/expression/function/scalar/histogram/HistogramPercentileEvaluator.java diff --git a/x-pack/plugin/esql/compute/gen/src/main/java/org/elasticsearch/compute/gen/EvaluatorImplementer.java b/x-pack/plugin/esql/compute/gen/src/main/java/org/elasticsearch/compute/gen/EvaluatorImplementer.java index bba578f45f5b0..7ae79a0c6ef04 100644 --- a/x-pack/plugin/esql/compute/gen/src/main/java/org/elasticsearch/compute/gen/EvaluatorImplementer.java +++ b/x-pack/plugin/esql/compute/gen/src/main/java/org/elasticsearch/compute/gen/EvaluatorImplementer.java @@ -18,6 +18,7 @@ import org.elasticsearch.compute.gen.argument.BlockArgument; import org.elasticsearch.compute.gen.argument.BuilderArgument; import org.elasticsearch.compute.gen.argument.FixedArgument; +import org.elasticsearch.compute.gen.argument.PositionArgument; import java.util.ArrayList; import java.util.List; @@ -51,6 +52,7 @@ public class EvaluatorImplementer { private final ProcessFunction processFunction; private final ClassName implementation; private final boolean processOutputsMultivalued; + private final boolean vectorsUnsupported; private final boolean allNullsIsNull; public EvaluatorImplementer( @@ -69,6 +71,11 @@ public EvaluatorImplementer( declarationType.getSimpleName() + extraName + "Evaluator" ); this.processOutputsMultivalued = this.processFunction.hasBlockType; + boolean anyParameterNotSupportingVectors = + this.processFunction.args.stream() + .filter(a -> a instanceof FixedArgument == false && a instanceof PositionArgument == false) + .anyMatch(a -> a.dataType(false) == null); + vectorsUnsupported = processOutputsMultivalued || anyParameterNotSupportingVectors; this.allNullsIsNull = allNullsIsNull; } @@ -101,7 +108,7 @@ private TypeSpec type() { builder.addMethod(eval()); builder.addMethod(processFunction.baseRamBytesUsed()); - if (processOutputsMultivalued) { + if (vectorsUnsupported) { if (processFunction.args.stream().anyMatch(x -> x instanceof FixedArgument == false)) { builder.addMethod(realEval(true)); } @@ -145,7 +152,7 @@ private MethodSpec eval() { builder.addModifiers(Modifier.PUBLIC).returns(BLOCK).addParameter(PAGE, "page"); processFunction.args.forEach(a -> a.evalToBlock(builder)); String invokeBlockEval = invokeRealEval(true); - if (processOutputsMultivalued) { + if (vectorsUnsupported) { builder.addStatement(invokeBlockEval); } else { processFunction.args.forEach(a -> a.resolveVectors(builder, invokeBlockEval)); diff --git a/x-pack/plugin/esql/compute/gen/src/main/java/org/elasticsearch/compute/gen/Methods.java b/x-pack/plugin/esql/compute/gen/src/main/java/org/elasticsearch/compute/gen/Methods.java index 15520c6ed93ab..2a06777c62d6e 100644 --- a/x-pack/plugin/esql/compute/gen/src/main/java/org/elasticsearch/compute/gen/Methods.java +++ b/x-pack/plugin/esql/compute/gen/src/main/java/org/elasticsearch/compute/gen/Methods.java @@ -314,6 +314,9 @@ public static String getMethod(TypeName elementType) { if (elementType.equals(TypeName.FLOAT)) { return "getFloat"; } + if (elementType.equals(Types.EXPONENTIAL_HISTOGRAM)) { + return "getExponentialHistogram"; + } throw new IllegalArgumentException("unknown get method for [" + elementType + "]"); } diff --git a/x-pack/plugin/esql/compute/gen/src/main/java/org/elasticsearch/compute/gen/Types.java b/x-pack/plugin/esql/compute/gen/src/main/java/org/elasticsearch/compute/gen/Types.java index 82b3450343ced..6fa321ccc487d 100644 --- a/x-pack/plugin/esql/compute/gen/src/main/java/org/elasticsearch/compute/gen/Types.java +++ b/x-pack/plugin/esql/compute/gen/src/main/java/org/elasticsearch/compute/gen/Types.java @@ -52,6 +52,8 @@ public class Types { public static final ClassName LONG_BLOCK = ClassName.get(DATA_PACKAGE, "LongBlock"); public static final ClassName DOUBLE_BLOCK = ClassName.get(DATA_PACKAGE, "DoubleBlock"); public static final ClassName FLOAT_BLOCK = ClassName.get(DATA_PACKAGE, "FloatBlock"); + public static final ClassName EXPONENTIAL_HISTOGRAM_BLOCK = ClassName.get(DATA_PACKAGE, "ExponentialHistogramBlock"); + public static final ClassName EXPONENTIAL_HISTOGRAM_SCRATCH = ClassName.get(DATA_PACKAGE, "ExponentialHistogramScratch"); static final ClassName BOOLEAN_BLOCK_BUILDER = BOOLEAN_BLOCK.nestedClass("Builder"); static final ClassName BYTES_REF_BLOCK_BUILDER = BYTES_REF_BLOCK.nestedClass("Builder"); @@ -59,6 +61,7 @@ public class Types { static final ClassName LONG_BLOCK_BUILDER = LONG_BLOCK.nestedClass("Builder"); static final ClassName DOUBLE_BLOCK_BUILDER = DOUBLE_BLOCK.nestedClass("Builder"); static final ClassName FLOAT_BLOCK_BUILDER = FLOAT_BLOCK.nestedClass("Builder"); + static final ClassName EXPONENTIAL_HISTOGRAM_BLOCK_BUILDER = ClassName.get(DATA_PACKAGE, "ExponentialHistogramBlockBuilder"); static final ClassName ELEMENT_TYPE = ClassName.get(DATA_PACKAGE, "ElementType"); @@ -133,6 +136,7 @@ public class Types { static final ClassName SOURCE = ClassName.get("org.elasticsearch.xpack.esql.core.tree", "Source"); public static final ClassName BYTES_REF = ClassName.get("org.apache.lucene.util", "BytesRef"); + public static final ClassName EXPONENTIAL_HISTOGRAM = ClassName.get("org.elasticsearch.exponentialhistogram", "ExponentialHistogram"); public static final ClassName RELEASABLE = ClassName.get("org.elasticsearch.core", "Releasable"); public static final ClassName RELEASABLES = ClassName.get("org.elasticsearch.core", "Releasables"); @@ -140,7 +144,7 @@ public class Types { private record TypeDef(TypeName type, String alias, ClassName block, ClassName vector) { public static TypeDef of(TypeName type, String alias, String block, String vector) { - return new TypeDef(type, alias, ClassName.get(DATA_PACKAGE, block), ClassName.get(DATA_PACKAGE, vector)); + return new TypeDef(type, alias, ClassName.get(DATA_PACKAGE, block), vector == null ? null: ClassName.get(DATA_PACKAGE, vector)); } } @@ -150,7 +154,8 @@ public static TypeDef of(TypeName type, String alias, String block, String vecto TypeDef.of(TypeName.LONG, "LONG", "LongBlock", "LongVector"), TypeDef.of(TypeName.FLOAT, "FLOAT", "FloatBlock", "FloatVector"), TypeDef.of(TypeName.DOUBLE, "DOUBLE", "DoubleBlock", "DoubleVector"), - TypeDef.of(BYTES_REF, "BYTES_REF", "BytesRefBlock", "BytesRefVector") + TypeDef.of(BYTES_REF, "BYTES_REF", "BytesRefBlock", "BytesRefVector"), + TypeDef.of(EXPONENTIAL_HISTOGRAM, "EXPONENTIAL_HISTOGRAM", "ExponentialHistogramBlock", null) ) .flatMap(def -> Stream.of(def.type.toString(), def.type + "[]", def.alias).map(alias -> Map.entry(alias, def))) .collect(toUnmodifiableMap(Map.Entry::getKey, Map.Entry::getValue)); @@ -220,6 +225,9 @@ static ClassName builderType(TypeName resultType) { if (resultType.equals(FLOAT_VECTOR)) { return FLOAT_VECTOR_BUILDER; } + if (resultType.equals(EXPONENTIAL_HISTOGRAM_BLOCK)) { + return EXPONENTIAL_HISTOGRAM_BLOCK_BUILDER; + } throw new IllegalArgumentException("unknown builder type for [" + resultType + "]"); } @@ -261,6 +269,9 @@ public static TypeName elementType(TypeName t) { if (t.equals(FLOAT_BLOCK) || t.equals(FLOAT_VECTOR) || t.equals(FLOAT_BLOCK_BUILDER)) { return TypeName.FLOAT; } + if (t.equals(EXPONENTIAL_HISTOGRAM_BLOCK) || t.equals(EXPONENTIAL_HISTOGRAM_BLOCK_BUILDER)) { + return EXPONENTIAL_HISTOGRAM; + } throw new IllegalArgumentException("unknown element type for [" + t + "]"); } diff --git a/x-pack/plugin/esql/compute/gen/src/main/java/org/elasticsearch/compute/gen/argument/Argument.java b/x-pack/plugin/esql/compute/gen/src/main/java/org/elasticsearch/compute/gen/argument/Argument.java index 4a2100a177e92..655ffb1e1a795 100644 --- a/x-pack/plugin/esql/compute/gen/src/main/java/org/elasticsearch/compute/gen/argument/Argument.java +++ b/x-pack/plugin/esql/compute/gen/src/main/java/org/elasticsearch/compute/gen/argument/Argument.java @@ -26,6 +26,7 @@ import static org.elasticsearch.compute.gen.Methods.getMethod; import static org.elasticsearch.compute.gen.Types.BYTES_REF; +import static org.elasticsearch.compute.gen.Types.EXPONENTIAL_HISTOGRAM; import static org.elasticsearch.compute.gen.Types.blockType; import static org.elasticsearch.compute.gen.Types.vectorType; import static org.elasticsearch.compute.gen.argument.StandardArgument.isBlockType; @@ -93,9 +94,20 @@ default String offsetName() { return name() + "Offset"; } + default ClassName scratchType() { + TypeName type = type(); + if (BYTES_REF.equals(type)) { + return Types.BYTES_REF; + } + if (EXPONENTIAL_HISTOGRAM.equals(type)) { + return Types.EXPONENTIAL_HISTOGRAM_SCRATCH; + } + return null; + } + default String scratchName() { - if (isBytesRef() == false) { - throw new IllegalStateException("can't build scratch for non-BytesRef"); + if (scratchType() != null == false) { + throw new IllegalStateException("can't build scratch for " +type()); } return name() + "Scratch"; diff --git a/x-pack/plugin/esql/compute/gen/src/main/java/org/elasticsearch/compute/gen/argument/StandardArgument.java b/x-pack/plugin/esql/compute/gen/src/main/java/org/elasticsearch/compute/gen/argument/StandardArgument.java index 981e3de3f22f4..12b8ca98165bc 100644 --- a/x-pack/plugin/esql/compute/gen/src/main/java/org/elasticsearch/compute/gen/argument/StandardArgument.java +++ b/x-pack/plugin/esql/compute/gen/src/main/java/org/elasticsearch/compute/gen/argument/StandardArgument.java @@ -17,7 +17,6 @@ import static org.elasticsearch.compute.gen.Methods.getMethod; import static org.elasticsearch.compute.gen.Types.BOOLEAN_BLOCK; -import static org.elasticsearch.compute.gen.Types.BYTES_REF; import static org.elasticsearch.compute.gen.Types.BYTES_REF_BLOCK; import static org.elasticsearch.compute.gen.Types.DOUBLE_BLOCK; import static org.elasticsearch.compute.gen.Types.EXPRESSION_EVALUATOR; @@ -93,8 +92,8 @@ public void resolveVectors(MethodSpec.Builder builder, String... invokeBlockEval @Override public void createScratch(MethodSpec.Builder builder) { - if (isBytesRef()) { - builder.addStatement("$T $LScratch = new $T()", BYTES_REF, name, BYTES_REF); + if (scratchType() != null) { + builder.addStatement("$T $LScratch = new $T()", scratchType(), name, scratchType()); } } @@ -123,7 +122,7 @@ static boolean isBlockType(TypeName type) { @Override public void read(MethodSpec.Builder builder, boolean blockStyle) { String params = blockStyle ? paramName(true) + ".getFirstValueIndex(p)" : "p"; - if (isBytesRef()) { + if (scratchType() != null) { params += ", " + scratchName(); } builder.addStatement("$T $L = $L.$L($L)", type, name, paramName(blockStyle), getMethod(type), params); diff --git a/x-pack/plugin/esql/src/main/generated/org/elasticsearch/xpack/esql/expression/function/scalar/histogram/HistogramPercentileEvaluator.java b/x-pack/plugin/esql/src/main/generated/org/elasticsearch/xpack/esql/expression/function/scalar/histogram/HistogramPercentileEvaluator.java new file mode 100644 index 0000000000000..b340409c71711 --- /dev/null +++ b/x-pack/plugin/esql/src/main/generated/org/elasticsearch/xpack/esql/expression/function/scalar/histogram/HistogramPercentileEvaluator.java @@ -0,0 +1,146 @@ +// Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one +// or more contributor license agreements. Licensed under the Elastic License +// 2.0; you may not use this file except in compliance with the Elastic License +// 2.0. +package org.elasticsearch.xpack.esql.expression.function.scalar.histogram; + +import java.lang.IllegalArgumentException; +import java.lang.Override; +import java.lang.String; +import org.apache.lucene.util.RamUsageEstimator; +import org.elasticsearch.compute.data.Block; +import org.elasticsearch.compute.data.DoubleBlock; +import org.elasticsearch.compute.data.ExponentialHistogramBlock; +import org.elasticsearch.compute.data.ExponentialHistogramScratch; +import org.elasticsearch.compute.data.Page; +import org.elasticsearch.compute.operator.DriverContext; +import org.elasticsearch.compute.operator.EvalOperator; +import org.elasticsearch.compute.operator.Warnings; +import org.elasticsearch.core.Releasables; +import org.elasticsearch.exponentialhistogram.ExponentialHistogram; +import org.elasticsearch.xpack.esql.core.tree.Source; + +/** + * {@link EvalOperator.ExpressionEvaluator} implementation for {@link HistogramPercentile}. + * This class is generated. Edit {@code EvaluatorImplementer} instead. + */ +public final class HistogramPercentileEvaluator implements EvalOperator.ExpressionEvaluator { + private static final long BASE_RAM_BYTES_USED = RamUsageEstimator.shallowSizeOfInstance(HistogramPercentileEvaluator.class); + + private final Source source; + + private final EvalOperator.ExpressionEvaluator value; + + private final EvalOperator.ExpressionEvaluator percentile; + + private final DriverContext driverContext; + + private Warnings warnings; + + public HistogramPercentileEvaluator(Source source, EvalOperator.ExpressionEvaluator value, + EvalOperator.ExpressionEvaluator percentile, DriverContext driverContext) { + this.source = source; + this.value = value; + this.percentile = percentile; + this.driverContext = driverContext; + } + + @Override + public Block eval(Page page) { + try (ExponentialHistogramBlock valueBlock = (ExponentialHistogramBlock) value.eval(page)) { + try (DoubleBlock percentileBlock = (DoubleBlock) percentile.eval(page)) { + return eval(page.getPositionCount(), valueBlock, percentileBlock); + } + } + } + + @Override + public long baseRamBytesUsed() { + long baseRamBytesUsed = BASE_RAM_BYTES_USED; + baseRamBytesUsed += value.baseRamBytesUsed(); + baseRamBytesUsed += percentile.baseRamBytesUsed(); + return baseRamBytesUsed; + } + + public DoubleBlock eval(int positionCount, ExponentialHistogramBlock valueBlock, + DoubleBlock percentileBlock) { + try(DoubleBlock.Builder result = driverContext.blockFactory().newDoubleBlockBuilder(positionCount)) { + ExponentialHistogramScratch valueScratch = new ExponentialHistogramScratch(); + position: for (int p = 0; p < positionCount; p++) { + switch (valueBlock.getValueCount(p)) { + case 0: + result.appendNull(); + continue position; + case 1: + break; + default: + warnings().registerException(new IllegalArgumentException("single-value function encountered multi-value")); + result.appendNull(); + continue position; + } + switch (percentileBlock.getValueCount(p)) { + case 0: + result.appendNull(); + continue position; + case 1: + break; + default: + warnings().registerException(new IllegalArgumentException("single-value function encountered multi-value")); + result.appendNull(); + continue position; + } + ExponentialHistogram value = valueBlock.getExponentialHistogram(valueBlock.getFirstValueIndex(p), valueScratch); + double percentile = percentileBlock.getDouble(percentileBlock.getFirstValueIndex(p)); + result.appendDouble(HistogramPercentile.process(value, percentile)); + } + return result.build(); + } + } + + @Override + public String toString() { + return "HistogramPercentileEvaluator[" + "value=" + value + ", percentile=" + percentile + "]"; + } + + @Override + public void close() { + Releasables.closeExpectNoException(value, percentile); + } + + private Warnings warnings() { + if (warnings == null) { + this.warnings = Warnings.createWarnings( + driverContext.warningsMode(), + source.source().getLineNumber(), + source.source().getColumnNumber(), + source.text() + ); + } + return warnings; + } + + static class Factory implements EvalOperator.ExpressionEvaluator.Factory { + private final Source source; + + private final EvalOperator.ExpressionEvaluator.Factory value; + + private final EvalOperator.ExpressionEvaluator.Factory percentile; + + public Factory(Source source, EvalOperator.ExpressionEvaluator.Factory value, + EvalOperator.ExpressionEvaluator.Factory percentile) { + this.source = source; + this.value = value; + this.percentile = percentile; + } + + @Override + public HistogramPercentileEvaluator get(DriverContext context) { + return new HistogramPercentileEvaluator(source, value.get(context), percentile.get(context), context); + } + + @Override + public String toString() { + return "HistogramPercentileEvaluator[" + "value=" + value + ", percentile=" + percentile + "]"; + } + } +} diff --git a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/histogram/HistogramPercentile.java b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/histogram/HistogramPercentile.java index e2211e4d4f92e..f138286b6798c 100644 --- a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/histogram/HistogramPercentile.java +++ b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/histogram/HistogramPercentile.java @@ -7,22 +7,14 @@ package org.elasticsearch.xpack.esql.expression.function.scalar.histogram; -import org.apache.lucene.util.RamUsageEstimator; +import org.apache.lucene.util.BytesRef; import org.elasticsearch.common.io.stream.NamedWriteableRegistry; import org.elasticsearch.common.io.stream.StreamInput; import org.elasticsearch.common.io.stream.StreamOutput; -import org.elasticsearch.compute.data.Block; -import org.elasticsearch.compute.data.DoubleBlock; -import org.elasticsearch.compute.data.ExponentialHistogramBlock; -import org.elasticsearch.compute.data.ExponentialHistogramBlockAccessor; -import org.elasticsearch.compute.data.Page; -import org.elasticsearch.compute.operator.DriverContext; +import org.elasticsearch.compute.ann.Evaluator; import org.elasticsearch.compute.operator.EvalOperator; -import org.elasticsearch.compute.operator.Warnings; -import org.elasticsearch.core.Releasables; import org.elasticsearch.exponentialhistogram.ExponentialHistogram; import org.elasticsearch.exponentialhistogram.ExponentialHistogramQuantile; -import org.elasticsearch.xpack.esql.EsqlIllegalArgumentException; import org.elasticsearch.xpack.esql.core.expression.Expression; import org.elasticsearch.xpack.esql.core.tree.NodeInfo; import org.elasticsearch.xpack.esql.core.tree.Source; @@ -95,129 +87,19 @@ public void writeTo(StreamOutput out) throws IOException { out.writeNamedWriteable(percentile); } + @Evaluator + static double process(ExponentialHistogram value, double percentile) { + double result = ExponentialHistogramQuantile.getQuantile(value, percentile / 100.0); + return result; + } + @Override public EvalOperator.ExpressionEvaluator.Factory toEvaluator(ToEvaluator toEvaluator) { - DataType fieldDataType = histogram.dataType(); - if (fieldDataType != DataType.EXPONENTIAL_HISTOGRAM) { - throw EsqlIllegalArgumentException.illegalDataType(fieldDataType); - } var fieldEvaluator = toEvaluator.apply(histogram); var percentileEvaluator = Cast.cast(source(), percentile.dataType(), DataType.DOUBLE, toEvaluator.apply(percentile)); - return new EvalOperator.ExpressionEvaluator.Factory() { - - @Override - public String toString() { - return "HistogramPercentileEvaluator[" + "field=" + fieldEvaluator + ",percentile=" + percentileEvaluator + "]"; - } - - @Override - public EvalOperator.ExpressionEvaluator get(DriverContext context) { - var histogram = fieldEvaluator.get(context); - var percentile = percentileEvaluator.get(context); - return new Evaluator(source(), context, histogram, percentile); - } - }; + return null; } - private static class Evaluator implements EvalOperator.ExpressionEvaluator { - - private static final long BASE_RAM_BYTES_USED = RamUsageEstimator.shallowSizeOfInstance(Evaluator.class); - - private final DriverContext driverContext; - private final EvalOperator.ExpressionEvaluator histogram; - private final EvalOperator.ExpressionEvaluator percentile; - private final Source source; - - private Warnings warnings; - - private Evaluator( - Source source, - DriverContext driverContext, - EvalOperator.ExpressionEvaluator histogram, - EvalOperator.ExpressionEvaluator percentile - ) { - this.source = source; - this.driverContext = driverContext; - this.histogram = histogram; - this.percentile = percentile; - } - - private Warnings warnings() { - if (warnings == null) { - this.warnings = Warnings.createWarnings( - driverContext.warningsMode(), - source.source().getLineNumber(), - source.source().getColumnNumber(), - source.text() - ); - } - return warnings; - } - - @Override - public Block eval(Page page) { - // TODO this is a ton of boilerplate, which will we repeated for every function - // we should adapt EvaluatorImplementer instead to deal with exponential histograms - ExponentialHistogramBlock histogramBlock = null; - DoubleBlock percentileBlock = null; - int positionCount = page.getPositionCount(); - try (DoubleBlock.Builder result = driverContext.blockFactory().newDoubleBlockBuilder(positionCount)) { - histogramBlock = (ExponentialHistogramBlock) histogram.eval(page); - percentileBlock = (DoubleBlock) percentile.eval(page); - var histogramAccessor = new ExponentialHistogramBlockAccessor(histogramBlock); - position: for (int p = 0; p < positionCount; p++) { - switch (percentileBlock.getValueCount(p)) { - case 0: - result.appendNull(); - continue position; - case 1: - break; - default: - warnings().registerException(IllegalArgumentException.class, "single-value function encountered multi-value"); - result.appendNull(); - continue position; - } - switch (histogramBlock.getValueCount(p)) { - case 0: - result.appendNull(); - continue position; - case 1: - break; - default: - warnings().registerException(IllegalArgumentException.class, "single-value function encountered multi-value"); - result.appendNull(); - continue position; - } - - ExponentialHistogram histogram = histogramAccessor.get(histogramBlock.getFirstValueIndex(p)); - double percentile = percentileBlock.getDouble(percentileBlock.getFirstValueIndex(p)); - double resultValue = ExponentialHistogramQuantile.getQuantile(histogram, percentile / 100.0); - if (Double.isNaN(resultValue)) { - result.appendNull(); - } else { - result.appendDouble(resultValue); - } - } - return result.build(); - } finally { - Releasables.close(histogramBlock, percentileBlock); - } - } - - @Override - public long baseRamBytesUsed() { - return BASE_RAM_BYTES_USED + histogram.baseRamBytesUsed() + percentile.baseRamBytesUsed(); - } - - @Override - public void close() { - Releasables.closeExpectNoException(histogram, percentile); - } - - @Override - public String toString() { - return "HistogramPercentileEvaluator[field=" + histogram + ",subfieldIndex=" + percentile + "]"; - } - } + } From 17c0c280fbece8a10ed9bfed7b0f952351b02ea9 Mon Sep 17 00:00:00 2001 From: Jonas Kunz Date: Thu, 30 Oct 2025 10:05:21 +0100 Subject: [PATCH 08/15] Add merge aggregation --- .../ExponentialHistogramMergeAggregator.java | 58 +++++++ .../ExponentialHistogramStates.java | 158 ++++++++++++++++++ .../function/aggregate/HistogramMerge.java | 127 ++++++++++++++ .../scalar/histogram/HistogramPercentile.java | 22 +++ 4 files changed, 365 insertions(+) create mode 100644 x-pack/plugin/esql/compute/src/main/generated-src/org/elasticsearch/compute/aggregation/ExponentialHistogramMergeAggregator.java create mode 100644 x-pack/plugin/esql/compute/src/main/java/org/elasticsearch/compute/aggregation/ExponentialHistogramStates.java create mode 100644 x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/aggregate/HistogramMerge.java diff --git a/x-pack/plugin/esql/compute/src/main/generated-src/org/elasticsearch/compute/aggregation/ExponentialHistogramMergeAggregator.java b/x-pack/plugin/esql/compute/src/main/generated-src/org/elasticsearch/compute/aggregation/ExponentialHistogramMergeAggregator.java new file mode 100644 index 0000000000000..2f4a1bd2b68e5 --- /dev/null +++ b/x-pack/plugin/esql/compute/src/main/generated-src/org/elasticsearch/compute/aggregation/ExponentialHistogramMergeAggregator.java @@ -0,0 +1,58 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +package org.elasticsearch.compute.aggregation; + +import org.elasticsearch.common.util.BigArrays; +import org.elasticsearch.compute.ann.Aggregator; +import org.elasticsearch.compute.ann.GroupingAggregator; +import org.elasticsearch.compute.ann.IntermediateState; +import org.elasticsearch.compute.data.Block; +import org.elasticsearch.compute.data.IntVector; +import org.elasticsearch.compute.operator.DriverContext; +import org.elasticsearch.exponentialhistogram.ExponentialHistogram; + +@Aggregator( + { + @IntermediateState(name = "value", type = "exponential_histogram") + } +) +@GroupingAggregator +public class ExponentialHistogramMergeAggregator { + + public static ExponentialHistogramStates.SingleState initSingle(DriverContext context) { + return new ExponentialHistogramStates.SingleState(context.breaker()); + } + + public static void combine(ExponentialHistogramStates.SingleState state, ExponentialHistogram value) { + state.add(value); + } + + public static void combineIntermediate(ExponentialHistogramStates.SingleState state, ExponentialHistogram value) { + state.add(value); + } + + public static Block evaluateFinal(ExponentialHistogramStates.SingleState state, DriverContext driverContext) { + return state.evaluateFinal(driverContext); + } + + public static ExponentialHistogramStates.GroupingState initGrouping(BigArrays bigArrays, DriverContext context) { + return new ExponentialHistogramStates.GroupingState(bigArrays, context.breaker()); + } + + public static void combine(ExponentialHistogramStates.GroupingState current, int groupId, ExponentialHistogram value) { + current.add(groupId, value); + } + + public static void combineIntermediate(ExponentialHistogramStates.GroupingState state, int groupId, ExponentialHistogram value) { + state.add(groupId, value); + } + + public static Block evaluateFinal(ExponentialHistogramStates.GroupingState state, IntVector selected, GroupingAggregatorEvaluationContext ctx) { + return state.evaluateFinal(selected, ctx.driverContext()); + } +} diff --git a/x-pack/plugin/esql/compute/src/main/java/org/elasticsearch/compute/aggregation/ExponentialHistogramStates.java b/x-pack/plugin/esql/compute/src/main/java/org/elasticsearch/compute/aggregation/ExponentialHistogramStates.java new file mode 100644 index 0000000000000..c94db58fe8822 --- /dev/null +++ b/x-pack/plugin/esql/compute/src/main/java/org/elasticsearch/compute/aggregation/ExponentialHistogramStates.java @@ -0,0 +1,158 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +package org.elasticsearch.compute.aggregation; + +import org.elasticsearch.common.breaker.CircuitBreaker; +import org.elasticsearch.common.util.BigArrays; +import org.elasticsearch.common.util.ObjectArray; +import org.elasticsearch.compute.data.Block; +import org.elasticsearch.compute.data.BlockFactory; +import org.elasticsearch.compute.data.DoubleBlock; +import org.elasticsearch.compute.data.IntVector; +import org.elasticsearch.compute.operator.DriverContext; +import org.elasticsearch.core.Releasables; +import org.elasticsearch.exponentialhistogram.ExponentialHistogram; +import org.elasticsearch.exponentialhistogram.ExponentialHistogramCircuitBreaker; +import org.elasticsearch.exponentialhistogram.ExponentialHistogramMerger; + +public final class ExponentialHistogramStates { + + // We currently use a hardcoded limit for the number of buckets, we might make this configurable / an aggregation parameter later + // The current default is what's also used by the OpenTelemetry SDKs + private static final int MAX_BUCKET_COUNT = 320; + + private record HistoBreaker(CircuitBreaker delegate) implements ExponentialHistogramCircuitBreaker { + @Override + public void adjustBreaker(long bytesAllocated) { + if (bytesAllocated < 0) { + delegate.addWithoutBreaking(bytesAllocated); + } else { + delegate.addEstimateBytesAndMaybeBreak(bytesAllocated, "ExponentialHistogram aggregation state"); + } + } + } + + private ExponentialHistogramStates() {} + + static final class SingleState implements AggregatorState { + + private final CircuitBreaker breaker; + // initialize lazily + private ExponentialHistogramMerger merger; + + SingleState(CircuitBreaker breaker) { + this.breaker = breaker; + } + + public void add(ExponentialHistogram histogram) { + if (histogram == null) { + return; + } + if (merger == null) { + merger = ExponentialHistogramMerger.create(MAX_BUCKET_COUNT, new HistoBreaker(breaker)); + } + merger.add(histogram); + } + + @Override + public void toIntermediate(Block[] blocks, int offset, DriverContext driverContext) { + assert blocks.length >= offset + 1; + blocks[offset] = evaluateFinal(driverContext); + } + + @Override + public void close() { + Releasables.close(merger); + merger = null; + } + + public Block evaluateFinal(DriverContext driverContext) { + BlockFactory blockFactory = driverContext.blockFactory(); + if (merger == null) { + return blockFactory.newConstantNullBlock(1); + } else { + return blockFactory.newConstantExponentialHistogramBlock(merger.get(), 1); + } + } + } + + static final class GroupingState implements GroupingAggregatorState { + + private ObjectArray states; + private final HistoBreaker breaker; + private final BigArrays bigArrays; + + GroupingState(BigArrays bigArrays, CircuitBreaker breaker) { + this.states = bigArrays.newObjectArray(1); + this.bigArrays = bigArrays; + this.breaker = new HistoBreaker(breaker); + } + + ExponentialHistogramMerger getOrNull(int position) { + if (position < states.size()) { + return states.get(position); + } else { + return null; + } + } + + public void add(int groupId, ExponentialHistogram histogram) { + if (histogram == null) { + return; + } + ensureCapacity(groupId); + var state = states.get(groupId); + if (state == null) { + state = ExponentialHistogramMerger.create(MAX_BUCKET_COUNT, breaker); + states.set(groupId, state); + } + state.add(histogram); + } + + private void ensureCapacity(int groupId) { + states = bigArrays.grow(states, groupId + 1); + } + + @Override + public void toIntermediate(Block[] blocks, int offset, IntVector selected, DriverContext driverContext) { + assert blocks.length >= offset + 1 : "blocks=" + blocks.length + ",offset=" + offset; + blocks[offset] = evaluateFinal(selected, driverContext); + } + + public Block evaluateFinal(IntVector selected, DriverContext driverContext) { + try ( + var builder = driverContext.blockFactory().newExponentialHistogramBlockBuilder(selected.getPositionCount()); + ) { + for (int i = 0; i < selected.getPositionCount(); i++) { + int groupId = selected.getInt(i); + ExponentialHistogramMerger state = getOrNull(groupId); + if (state != null) { + builder.append(state.get()); + } else { + builder.appendNull(); + } + } + return builder.build(); + } + } + + @Override + public void close() { + for (int i=0; i dt == DataType.EXPONENTIAL_HISTOGRAM, + sourceText(), + DEFAULT, + "exponential_histogram" + ); + } + + @Override + protected NodeInfo info() { + return NodeInfo.create(this, HistogramMerge::new, field(), filter()); + } + + @Override + public HistogramMerge replaceChildren(List newChildren) { + return new HistogramMerge(source(), newChildren.get(0), newChildren.get(1)); + } + + public HistogramMerge withFilter(Expression filter) { + return new HistogramMerge(source(), field(), filter); + } + + @Override + public final AggregatorFunctionSupplier supplier() { + DataType type = field().dataType(); + if (type == DataType.LONG) { + return new AggregatorFunctionSupplier() { + + @Override + public String describe() { + return "merge of exponential histograms"; + } + + @Override + public List nonGroupingIntermediateStateDesc() { + return List.of(); + } + + @Override + public List groupingIntermediateStateDesc() { + return List.of(); + } + + @Override + public AggregatorFunction aggregator(DriverContext driverContext, List channels) { + return null; + } + + @Override + public GroupingAggregatorFunction groupingAggregator(DriverContext driverContext, List channels) { + return null; + } + }; + } + throw EsqlIllegalArgumentException.illegalDataType(type); + } +} diff --git a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/histogram/HistogramPercentile.java b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/histogram/HistogramPercentile.java index f138286b6798c..de1b06cbb5474 100644 --- a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/histogram/HistogramPercentile.java +++ b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/histogram/HistogramPercentile.java @@ -28,6 +28,9 @@ import java.io.IOException; import java.util.List; +import static org.elasticsearch.xpack.esql.core.expression.TypeResolutions.ParamOrdinal.DEFAULT; +import static org.elasticsearch.xpack.esql.core.expression.TypeResolutions.isType; + public class HistogramPercentile extends EsqlScalarFunction { public static final NamedWriteableRegistry.Entry ENTRY = new NamedWriteableRegistry.Entry( @@ -60,6 +63,25 @@ private HistogramPercentile(StreamInput in) throws IOException { this(Source.readFrom((PlanStreamInput) in), in.readNamedWriteable(Expression.class), in.readNamedWriteable(Expression.class)); } + @Override + protected TypeResolution resolveType() { + return isType( + histogram, + dt -> dt == DataType.EXPONENTIAL_HISTOGRAM, + sourceText(), + DEFAULT, + "exponential_histogram" + ).and( + isType( + percentile, + DataType::isNumeric, + sourceText(), + DEFAULT, + "numeric types" + ) + ); + } + @Override public DataType dataType() { return DataType.DOUBLE; From 7f4b7c216afdeff137fe4d20e133c89a27b93652 Mon Sep 17 00:00:00 2001 From: Jonas Kunz Date: Fri, 31 Oct 2025 11:59:20 +0100 Subject: [PATCH 09/15] Implement code generation for non-grouping aggregators --- .../compute/gen/AggregatorImplementer.java | 58 +++++++++++++------ .../org/elasticsearch/compute/gen/Types.java | 32 ++++++---- .../compute/gen/argument/Argument.java | 11 +--- 3 files changed, 62 insertions(+), 39 deletions(-) diff --git a/x-pack/plugin/esql/compute/gen/src/main/java/org/elasticsearch/compute/gen/AggregatorImplementer.java b/x-pack/plugin/esql/compute/gen/src/main/java/org/elasticsearch/compute/gen/AggregatorImplementer.java index 1327db4bc0bea..af0f9f1305df7 100644 --- a/x-pack/plugin/esql/compute/gen/src/main/java/org/elasticsearch/compute/gen/AggregatorImplementer.java +++ b/x-pack/plugin/esql/compute/gen/src/main/java/org/elasticsearch/compute/gen/AggregatorImplementer.java @@ -37,6 +37,7 @@ import javax.lang.model.util.Elements; import static java.util.stream.Collectors.joining; +import static org.elasticsearch.compute.gen.Methods.getMethod; import static org.elasticsearch.compute.gen.Methods.optionalStaticMethod; import static org.elasticsearch.compute.gen.Methods.requireAnyArgs; import static org.elasticsearch.compute.gen.Methods.requireAnyType; @@ -62,6 +63,8 @@ import static org.elasticsearch.compute.gen.Types.PAGE; import static org.elasticsearch.compute.gen.Types.WARNINGS; import static org.elasticsearch.compute.gen.Types.blockType; +import static org.elasticsearch.compute.gen.Types.fromString; +import static org.elasticsearch.compute.gen.Types.scratchType; import static org.elasticsearch.compute.gen.Types.vectorType; /** @@ -85,7 +88,7 @@ public class AggregatorImplementer { private final AggregationState aggState; private final List aggParams; - private final boolean hasOnlyBlockArguments; + private final boolean attemptToUseVectors; public AggregatorImplementer( Elements elements, @@ -119,7 +122,8 @@ public AggregatorImplementer( return a; }).filter(a -> a instanceof PositionArgument == false).toList(); - this.hasOnlyBlockArguments = this.aggParams.stream().allMatch(a -> a instanceof BlockArgument); + this.attemptToUseVectors = aggParams.stream().anyMatch(a -> (a instanceof BlockArgument) == false) + && aggParams.stream().noneMatch(a -> a instanceof StandardArgument && a.dataType(false) == null); this.createParameters = init.getParameters() .stream() @@ -199,7 +203,7 @@ private TypeSpec type() { builder.addMethod(addRawInput()); builder.addMethod(addRawInputExploded(true)); builder.addMethod(addRawInputExploded(false)); - if (hasOnlyBlockArguments == false) { + if (attemptToUseVectors) { builder.addMethod(addRawVector(false)); builder.addMethod(addRawVector(true)); } @@ -340,16 +344,18 @@ private MethodSpec addRawInputExploded(boolean hasMask) { builder.addStatement("$T $L = page.getBlock(channels.get($L))", a.dataType(true), a.blockName(), i); } - for (Argument a : aggParams) { - String rawBlock = "addRawBlock(" - + aggParams.stream().map(arg -> arg.blockName()).collect(joining(", ")) - + (hasMask ? ", mask" : "") - + ")"; + if (attemptToUseVectors) { + for (Argument a : aggParams) { + String rawBlock = "addRawBlock(" + + aggParams.stream().map(arg -> arg.blockName()).collect(joining(", ")) + + (hasMask ? ", mask" : "") + + ")"; - a.resolveVectors(builder, rawBlock, "return"); + a.resolveVectors(builder, rawBlock, "return"); + } } - builder.addStatement(invokeAddRaw(hasOnlyBlockArguments, hasMask)); + builder.addStatement(invokeAddRaw(attemptToUseVectors == false, hasMask)); return builder.build(); } @@ -499,9 +505,9 @@ private MethodSpec.Builder initAddRaw(boolean blockStyle, boolean masked) { builder.addParameter(BOOLEAN_VECTOR, "mask"); } for (Argument a : aggParams) { - if (a.isBytesRef()) { - // Add bytes_ref scratch var that will be used for bytes_ref blocks/vectors - builder.addStatement("$T $L = new $T()", BYTES_REF, a.scratchName(), BYTES_REF); + if (a.scratchType() != null) { + // Add scratch var that will be used for some blocks/vectors, e.g. for bytes_ref + builder.addStatement("$T $L = new $T()", a.scratchType(), a.scratchName(), a.scratchType()); } } return builder; @@ -610,8 +616,8 @@ private MethodSpec addIntermediateInput() { ).map(Methods::requireType).toArray(TypeMatcher[]::new) ) ); - if (intermediateState.stream().map(IntermediateStateDesc::elementType).anyMatch(n -> n.equals("BYTES_REF"))) { - builder.addStatement("$T scratch = new $T()", BYTES_REF, BYTES_REF); + for (IntermediateStateDesc interState : intermediateState) { + interState.addScratchDeclaration(builder); } builder.addStatement("$T.combineIntermediate(state, " + intermediateStateRowAccess() + ")", declarationType); } @@ -706,13 +712,25 @@ public String access(String position) { if (block) { return name(); } - String s = name() + "." + vectorAccessorName(elementType()) + "(" + position; - if (elementType().equals("BYTES_REF")) { - s += ", scratch"; + String s = name() + "."; + if (vectorType(elementType) != null) { + s += vectorAccessorName(elementType()) + "(" + position; + } else { + s+= getMethod(fromString(elementType())) + "(" + name() + ".getFirstValueIndex("+position+")"; + } + if (scratchType(elementType()) != null) { + s += ", "+name()+"Scratch"; } return s + ")"; } + public void addScratchDeclaration(MethodSpec.Builder builder) { + ClassName scratchType = scratchType(elementType()); + if (scratchType != null) { + builder.addStatement("$T $L = new $T()", scratchType, name()+"Scratch", scratchType); + } + } + public void assignToVariable(MethodSpec.Builder builder, int offset) { builder.addStatement("Block $L = page.getBlock(channels.get($L))", name + "Uncast", offset); ClassName blockType = blockType(elementType()); @@ -721,17 +739,19 @@ public void assignToVariable(MethodSpec.Builder builder, int offset) { builder.addStatement("return"); builder.endControlFlow(); } - if (block) { + if (block || vectorType(elementType) == null) { builder.addStatement("$T $L = ($T) $L", blockType, name, blockType, name + "Uncast"); } else { builder.addStatement("$T $L = (($T) $L).asVector()", vectorType(elementType), name, blockType, name + "Uncast"); } } + public TypeName combineArgType() { var type = Types.fromString(elementType); return block ? blockType(type) : type; } + } /** diff --git a/x-pack/plugin/esql/compute/gen/src/main/java/org/elasticsearch/compute/gen/Types.java b/x-pack/plugin/esql/compute/gen/src/main/java/org/elasticsearch/compute/gen/Types.java index 6fa321ccc487d..058ebd0d90acb 100644 --- a/x-pack/plugin/esql/compute/gen/src/main/java/org/elasticsearch/compute/gen/Types.java +++ b/x-pack/plugin/esql/compute/gen/src/main/java/org/elasticsearch/compute/gen/Types.java @@ -141,21 +141,27 @@ public class Types { public static final ClassName RELEASABLE = ClassName.get("org.elasticsearch.core", "Releasable"); public static final ClassName RELEASABLES = ClassName.get("org.elasticsearch.core", "Releasables"); - private record TypeDef(TypeName type, String alias, ClassName block, ClassName vector) { - - public static TypeDef of(TypeName type, String alias, String block, String vector) { - return new TypeDef(type, alias, ClassName.get(DATA_PACKAGE, block), vector == null ? null: ClassName.get(DATA_PACKAGE, vector)); + private record TypeDef(TypeName type, String alias, ClassName block, ClassName vector, ClassName scratch) { + + public static TypeDef of(TypeName type, String alias, String block, String vector, ClassName scratch) { + return new TypeDef( + type, + alias, + ClassName.get(DATA_PACKAGE, block), + vector == null ? null: ClassName.get(DATA_PACKAGE, vector), + scratch + ); } } private static final Map TYPES = Stream.of( - TypeDef.of(TypeName.BOOLEAN, "BOOLEAN", "BooleanBlock", "BooleanVector"), - TypeDef.of(TypeName.INT, "INT", "IntBlock", "IntVector"), - TypeDef.of(TypeName.LONG, "LONG", "LongBlock", "LongVector"), - TypeDef.of(TypeName.FLOAT, "FLOAT", "FloatBlock", "FloatVector"), - TypeDef.of(TypeName.DOUBLE, "DOUBLE", "DoubleBlock", "DoubleVector"), - TypeDef.of(BYTES_REF, "BYTES_REF", "BytesRefBlock", "BytesRefVector"), - TypeDef.of(EXPONENTIAL_HISTOGRAM, "EXPONENTIAL_HISTOGRAM", "ExponentialHistogramBlock", null) + TypeDef.of(TypeName.BOOLEAN, "BOOLEAN", "BooleanBlock", "BooleanVector", null), + TypeDef.of(TypeName.INT, "INT", "IntBlock", "IntVector", null), + TypeDef.of(TypeName.LONG, "LONG", "LongBlock", "LongVector", null), + TypeDef.of(TypeName.FLOAT, "FLOAT", "FloatBlock", "FloatVector", null), + TypeDef.of(TypeName.DOUBLE, "DOUBLE", "DoubleBlock", "DoubleVector", null), + TypeDef.of(BYTES_REF, "BYTES_REF", "BytesRefBlock", "BytesRefVector", BYTES_REF), + TypeDef.of(EXPONENTIAL_HISTOGRAM, "EXPONENTIAL_HISTOGRAM", "ExponentialHistogramBlock", null, EXPONENTIAL_HISTOGRAM_SCRATCH) ) .flatMap(def -> Stream.of(def.type.toString(), def.type + "[]", def.alias).map(alias -> Map.entry(alias, def))) .collect(toUnmodifiableMap(Map.Entry::getKey, Map.Entry::getValue)); @@ -188,6 +194,10 @@ static ClassName vectorType(String elementType) { return findRequired(elementType, "vector").vector; } + public static ClassName scratchType(String elementType) { + return findRequired(elementType, "block").scratch; + } + static ClassName builderType(TypeName resultType) { if (resultType.equals(BOOLEAN_BLOCK)) { return BOOLEAN_BLOCK_BUILDER; diff --git a/x-pack/plugin/esql/compute/gen/src/main/java/org/elasticsearch/compute/gen/argument/Argument.java b/x-pack/plugin/esql/compute/gen/src/main/java/org/elasticsearch/compute/gen/argument/Argument.java index 655ffb1e1a795..f3600941854f6 100644 --- a/x-pack/plugin/esql/compute/gen/src/main/java/org/elasticsearch/compute/gen/argument/Argument.java +++ b/x-pack/plugin/esql/compute/gen/src/main/java/org/elasticsearch/compute/gen/argument/Argument.java @@ -95,14 +95,7 @@ default String offsetName() { } default ClassName scratchType() { - TypeName type = type(); - if (BYTES_REF.equals(type)) { - return Types.BYTES_REF; - } - if (EXPONENTIAL_HISTOGRAM.equals(type)) { - return Types.EXPONENTIAL_HISTOGRAM_SCRATCH; - } - return null; + return Types.scratchType(type().toString()); } default String scratchName() { @@ -210,7 +203,7 @@ default TypeName elementType() { */ default void read(MethodSpec.Builder builder, String accessor, String firstParam) { String params = firstParam; - if (isBytesRef()) { + if (scratchType() != null) { params += ", " + scratchName(); } builder.addStatement("$T $L = $L.$L($L)", type(), valueName(), accessor, getMethod(type()), params); From 6ceefa9051032d1868fefddf149718a1af6cbebd Mon Sep 17 00:00:00 2001 From: Jonas Kunz Date: Fri, 31 Oct 2025 12:30:36 +0100 Subject: [PATCH 10/15] Implement code generation for grouping aggregators --- .../gen/GroupingAggregatorImplementer.java | 53 ++++++++++--------- .../org/elasticsearch/compute/gen/Types.java | 6 ++- .../compute/gen/argument/ArrayArgument.java | 11 ++-- 3 files changed, 39 insertions(+), 31 deletions(-) diff --git a/x-pack/plugin/esql/compute/gen/src/main/java/org/elasticsearch/compute/gen/GroupingAggregatorImplementer.java b/x-pack/plugin/esql/compute/gen/src/main/java/org/elasticsearch/compute/gen/GroupingAggregatorImplementer.java index 399f45b5df667..439ee8d6cba08 100644 --- a/x-pack/plugin/esql/compute/gen/src/main/java/org/elasticsearch/compute/gen/GroupingAggregatorImplementer.java +++ b/x-pack/plugin/esql/compute/gen/src/main/java/org/elasticsearch/compute/gen/GroupingAggregatorImplementer.java @@ -93,6 +93,7 @@ public class GroupingAggregatorImplementer { private final AggregationState aggState; private final List aggParams; private final boolean hasOnlyBlockArguments; + private final boolean allArgumentsSupportVectors; public GroupingAggregatorImplementer( Elements elements, @@ -128,6 +129,7 @@ public GroupingAggregatorImplementer( }).filter(a -> a instanceof PositionArgument == false).toList(); this.hasOnlyBlockArguments = this.aggParams.stream().allMatch(a -> a instanceof BlockArgument); + this.allArgumentsSupportVectors = aggParams.stream().noneMatch(a -> a instanceof StandardArgument && a.dataType(false) == null); this.createParameters = init.getParameters() .stream() @@ -204,7 +206,7 @@ private TypeSpec type() { builder.addMethod(prepareProcessRawInputPage()); for (ClassName groupIdClass : GROUP_IDS_CLASSES) { builder.addMethod(addRawInputLoop(groupIdClass, false)); - if (hasOnlyBlockArguments == false) { + if (hasOnlyBlockArguments == false && allArgumentsSupportVectors) { builder.addMethod(addRawInputLoop(groupIdClass, true)); } builder.addMethod(addIntermediateInput(groupIdClass)); @@ -330,26 +332,31 @@ private MethodSpec prepareProcessRawInputPage() { builder.addStatement("$T $L = page.getBlock(channels.get($L))", a.dataType(true), a.blockName(), i); } - for (Argument a : aggParams) { - builder.addStatement( - "$T $L = $L.asVector()", - vectorType(a.elementType()), - (a instanceof BlockArgument) ? (a.name() + "Vector") : a.vectorName(), - a.blockName() - ); - builder.beginControlFlow("if ($L == null)", (a instanceof BlockArgument) ? (a.name() + "Vector") : a.vectorName()); - { + String groupIdTrackingStatement = "maybeEnableGroupIdTracking(seenGroupIds, " + + aggParams.stream().map(arg -> arg.blockName()).collect(joining(", ")) + + ")"; + + if (allArgumentsSupportVectors) { + + for (Argument a : aggParams) { builder.addStatement( - "maybeEnableGroupIdTracking(seenGroupIds, " - + aggParams.stream().map(arg -> arg.blockName()).collect(joining(", ")) - + ")" + "$T $L = $L.asVector()", + vectorType(a.elementType()), + (a instanceof BlockArgument) ? (a.name() + "Vector") : a.vectorName(), + a.blockName() ); - returnAddInput(builder, false); + builder.beginControlFlow("if ($L == null)", (a instanceof BlockArgument) ? (a.name() + "Vector") : a.vectorName()); + { + builder.addStatement( groupIdTrackingStatement); + returnAddInput(builder, false); + } + builder.endControlFlow(); } - builder.endControlFlow(); + returnAddInput(builder, true); + } else { + builder.addStatement(groupIdTrackingStatement); + returnAddInput(builder, false); } - - returnAddInput(builder, true); return builder.build(); } @@ -443,9 +450,9 @@ private MethodSpec addRawInputLoop(TypeName groupsType, boolean valuesAreVector) ); } for (Argument a : aggParams) { - if (a.isBytesRef()) { - // Add bytes_ref scratch var that will be used for bytes_ref blocks/vectors - builder.addStatement("$T $L = new $T()", BYTES_REF, a.scratchName(), BYTES_REF); + if (a.scratchType() != null) { + // Add scratch var that will be used for some blocks/vectors, e.g. for bytes_ref + builder.addStatement("$T $L = new $T()", a.scratchType(), a.scratchName(), a.scratchType()); } } @@ -645,11 +652,7 @@ private MethodSpec addIntermediateInput(TypeName groupsType) { .collect(Collectors.joining(", ")); builder.addStatement("$T.combineIntermediate(state, positionOffset, groups, " + states + ")", declarationType); } else { - if (intermediateState.stream() - .map(AggregatorImplementer.IntermediateStateDesc::elementType) - .anyMatch(n -> n.equals("BYTES_REF"))) { - builder.addStatement("$T scratch = new $T()", BYTES_REF, BYTES_REF); - } + intermediateState.forEach(state -> state.addScratchDeclaration(builder)); builder.beginControlFlow("for (int groupPosition = 0; groupPosition < groups.getPositionCount(); groupPosition++)"); { if (groupsIsBlock) { diff --git a/x-pack/plugin/esql/compute/gen/src/main/java/org/elasticsearch/compute/gen/Types.java b/x-pack/plugin/esql/compute/gen/src/main/java/org/elasticsearch/compute/gen/Types.java index 058ebd0d90acb..64118d9e576e3 100644 --- a/x-pack/plugin/esql/compute/gen/src/main/java/org/elasticsearch/compute/gen/Types.java +++ b/x-pack/plugin/esql/compute/gen/src/main/java/org/elasticsearch/compute/gen/Types.java @@ -195,7 +195,11 @@ static ClassName vectorType(String elementType) { } public static ClassName scratchType(String elementType) { - return findRequired(elementType, "block").scratch; + TypeDef typeDef = TYPES.get(elementType); + if (typeDef != null) { + return typeDef.scratch; + } + return null; } static ClassName builderType(TypeName resultType) { diff --git a/x-pack/plugin/esql/compute/gen/src/main/java/org/elasticsearch/compute/gen/argument/ArrayArgument.java b/x-pack/plugin/esql/compute/gen/src/main/java/org/elasticsearch/compute/gen/argument/ArrayArgument.java index 0ee2bf1998a74..fe6cbe25b46e4 100644 --- a/x-pack/plugin/esql/compute/gen/src/main/java/org/elasticsearch/compute/gen/argument/ArrayArgument.java +++ b/x-pack/plugin/esql/compute/gen/src/main/java/org/elasticsearch/compute/gen/argument/ArrayArgument.java @@ -8,6 +8,7 @@ package org.elasticsearch.compute.gen.argument; import com.squareup.javapoet.ArrayTypeName; +import com.squareup.javapoet.ClassName; import com.squareup.javapoet.MethodSpec; import com.squareup.javapoet.TypeName; import com.squareup.javapoet.TypeSpec; @@ -18,7 +19,6 @@ import javax.lang.model.element.Modifier; import static org.elasticsearch.compute.gen.Methods.getMethod; -import static org.elasticsearch.compute.gen.Types.BYTES_REF; import static org.elasticsearch.compute.gen.Types.EXPRESSION_EVALUATOR; import static org.elasticsearch.compute.gen.Types.EXPRESSION_EVALUATOR_FACTORY; import static org.elasticsearch.compute.gen.Types.RELEASABLE; @@ -105,10 +105,11 @@ public void resolveVectors(MethodSpec.Builder builder, String... invokeBlockEval @Override public void createScratch(MethodSpec.Builder builder) { builder.addStatement("$T[] $LValues = new $T[$L.length]", type, name, type, name); - if (isBytesRef()) { - builder.addStatement("$T[] $LScratch = new $T[$L.length]", type, name, type, name); + ClassName scratchType = scratchType(); + if (scratchType != null) { + builder.addStatement("$T[] $LScratch = new $T[$L.length]", scratchType, name, scratchType, name); builder.beginControlFlow("for (int i = 0; i < $L.length; i++)", name); - builder.addStatement("$LScratch[i] = new $T()", name, BYTES_REF); + builder.addStatement("$LScratch[i] = new $T()", name, scratchType); builder.endControlFlow(); } } @@ -136,7 +137,7 @@ public void read(MethodSpec.Builder builder, boolean blockStyle) { } else { lookupVar = "p"; } - if (isBytesRef()) { + if (scratchType() != null) { builder.addStatement("$LValues[i] = $L[i].getBytesRef($L, $LScratch[i])", name, paramName(blockStyle), lookupVar, name); } else { builder.addStatement("$LValues[i] = $L[i].$L($L)", name, paramName(blockStyle), getMethod(type), lookupVar); From 3a17f17e076ab87a6c0060b3c14729a919165087 Mon Sep 17 00:00:00 2001 From: Jonas Kunz Date: Fri, 31 Oct 2025 13:34:53 +0100 Subject: [PATCH 11/15] fix histo merge aggregator --- .../ExponentialHistogramMergeAggregator.java | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/x-pack/plugin/esql/compute/src/main/generated-src/org/elasticsearch/compute/aggregation/ExponentialHistogramMergeAggregator.java b/x-pack/plugin/esql/compute/src/main/generated-src/org/elasticsearch/compute/aggregation/ExponentialHistogramMergeAggregator.java index 2f4a1bd2b68e5..bd231afac9f32 100644 --- a/x-pack/plugin/esql/compute/src/main/generated-src/org/elasticsearch/compute/aggregation/ExponentialHistogramMergeAggregator.java +++ b/x-pack/plugin/esql/compute/src/main/generated-src/org/elasticsearch/compute/aggregation/ExponentialHistogramMergeAggregator.java @@ -18,14 +18,14 @@ @Aggregator( { - @IntermediateState(name = "value", type = "exponential_histogram") + @IntermediateState(name = "value", type = "EXPONENTIAL_HISTOGRAM"), } ) @GroupingAggregator public class ExponentialHistogramMergeAggregator { - public static ExponentialHistogramStates.SingleState initSingle(DriverContext context) { - return new ExponentialHistogramStates.SingleState(context.breaker()); + public static ExponentialHistogramStates.SingleState initSingle(DriverContext driverContext) { + return new ExponentialHistogramStates.SingleState(driverContext.breaker()); } public static void combine(ExponentialHistogramStates.SingleState state, ExponentialHistogram value) { @@ -40,8 +40,8 @@ public static Block evaluateFinal(ExponentialHistogramStates.SingleState state, return state.evaluateFinal(driverContext); } - public static ExponentialHistogramStates.GroupingState initGrouping(BigArrays bigArrays, DriverContext context) { - return new ExponentialHistogramStates.GroupingState(bigArrays, context.breaker()); + public static ExponentialHistogramStates.GroupingState initGrouping(BigArrays bigArrays, DriverContext driverContext) { + return new ExponentialHistogramStates.GroupingState(bigArrays, driverContext.breaker()); } public static void combine(ExponentialHistogramStates.GroupingState current, int groupId, ExponentialHistogram value) { From c3805935002b45f22c018e6639487fd2dfd65d5c Mon Sep 17 00:00:00 2001 From: Jonas Kunz Date: Fri, 31 Oct 2025 13:39:35 +0100 Subject: [PATCH 12/15] Generate code --- ...untDistinctBytesRefAggregatorFunction.java | 4 +- ...nctBytesRefGroupingAggregatorFunction.java | 12 +- ...CountDistinctDoubleAggregatorFunction.java | 4 +- ...tinctDoubleGroupingAggregatorFunction.java | 12 +- .../CountDistinctFloatAggregatorFunction.java | 4 +- ...stinctFloatGroupingAggregatorFunction.java | 12 +- .../CountDistinctIntAggregatorFunction.java | 4 +- ...DistinctIntGroupingAggregatorFunction.java | 12 +- .../CountDistinctLongAggregatorFunction.java | 4 +- ...istinctLongGroupingAggregatorFunction.java | 12 +- ...ntialHistogramMergeAggregatorFunction.java | 149 ++++++++++ ...togramMergeAggregatorFunctionSupplier.java | 47 ++++ ...togramMergeGroupingAggregatorFunction.java | 254 ++++++++++++++++++ ...BytesRefByTimestampAggregatorFunction.java | 4 +- ...ByTimestampGroupingAggregatorFunction.java | 6 +- ...BytesRefByTimestampAggregatorFunction.java | 4 +- ...ByTimestampGroupingAggregatorFunction.java | 6 +- .../MaxBytesRefAggregatorFunction.java | 4 +- ...MaxBytesRefGroupingAggregatorFunction.java | 12 +- .../aggregation/MaxIpAggregatorFunction.java | 4 +- .../MaxIpGroupingAggregatorFunction.java | 12 +- ...luteDeviationDoubleAggregatorFunction.java | 4 +- ...ationDoubleGroupingAggregatorFunction.java | 12 +- ...oluteDeviationFloatAggregatorFunction.java | 4 +- ...iationFloatGroupingAggregatorFunction.java | 12 +- ...bsoluteDeviationIntAggregatorFunction.java | 4 +- ...eviationIntGroupingAggregatorFunction.java | 12 +- ...soluteDeviationLongAggregatorFunction.java | 4 +- ...viationLongGroupingAggregatorFunction.java | 12 +- .../MinBytesRefAggregatorFunction.java | 4 +- ...MinBytesRefGroupingAggregatorFunction.java | 12 +- .../aggregation/MinIpAggregatorFunction.java | 4 +- .../MinIpGroupingAggregatorFunction.java | 12 +- .../PercentileDoubleAggregatorFunction.java | 4 +- ...ntileDoubleGroupingAggregatorFunction.java | 12 +- .../PercentileFloatAggregatorFunction.java | 4 +- ...entileFloatGroupingAggregatorFunction.java | 12 +- .../PercentileIntAggregatorFunction.java | 4 +- ...rcentileIntGroupingAggregatorFunction.java | 12 +- .../PercentileLongAggregatorFunction.java | 4 +- ...centileLongGroupingAggregatorFunction.java | 12 +- .../SampleBooleanAggregatorFunction.java | 2 +- ...mpleBooleanGroupingAggregatorFunction.java | 6 +- .../SampleBytesRefAggregatorFunction.java | 2 +- ...pleBytesRefGroupingAggregatorFunction.java | 6 +- .../SampleDoubleAggregatorFunction.java | 2 +- ...ampleDoubleGroupingAggregatorFunction.java | 6 +- .../SampleIntAggregatorFunction.java | 2 +- .../SampleIntGroupingAggregatorFunction.java | 6 +- .../SampleLongAggregatorFunction.java | 2 +- .../SampleLongGroupingAggregatorFunction.java | 6 +- .../TopBytesRefAggregatorFunction.java | 2 +- ...TopBytesRefGroupingAggregatorFunction.java | 6 +- .../aggregation/TopIpAggregatorFunction.java | 2 +- .../TopIpGroupingAggregatorFunction.java | 6 +- .../ValuesBytesRefAggregatorFunction.java | 2 +- 56 files changed, 625 insertions(+), 175 deletions(-) create mode 100644 x-pack/plugin/esql/compute/src/main/generated/org/elasticsearch/compute/aggregation/ExponentialHistogramMergeAggregatorFunction.java create mode 100644 x-pack/plugin/esql/compute/src/main/generated/org/elasticsearch/compute/aggregation/ExponentialHistogramMergeAggregatorFunctionSupplier.java create mode 100644 x-pack/plugin/esql/compute/src/main/generated/org/elasticsearch/compute/aggregation/ExponentialHistogramMergeGroupingAggregatorFunction.java diff --git a/x-pack/plugin/esql/compute/src/main/generated/org/elasticsearch/compute/aggregation/CountDistinctBytesRefAggregatorFunction.java b/x-pack/plugin/esql/compute/src/main/generated/org/elasticsearch/compute/aggregation/CountDistinctBytesRefAggregatorFunction.java index 71a3ec03278eb..b9737cc15976a 100644 --- a/x-pack/plugin/esql/compute/src/main/generated/org/elasticsearch/compute/aggregation/CountDistinctBytesRefAggregatorFunction.java +++ b/x-pack/plugin/esql/compute/src/main/generated/org/elasticsearch/compute/aggregation/CountDistinctBytesRefAggregatorFunction.java @@ -151,8 +151,8 @@ public void addIntermediateInput(Page page) { } BytesRefVector hll = ((BytesRefBlock) hllUncast).asVector(); assert hll.getPositionCount() == 1; - BytesRef scratch = new BytesRef(); - CountDistinctBytesRefAggregator.combineIntermediate(state, hll.getBytesRef(0, scratch)); + BytesRef hllScratch = new BytesRef(); + CountDistinctBytesRefAggregator.combineIntermediate(state, hll.getBytesRef(0, hllScratch)); } @Override diff --git a/x-pack/plugin/esql/compute/src/main/generated/org/elasticsearch/compute/aggregation/CountDistinctBytesRefGroupingAggregatorFunction.java b/x-pack/plugin/esql/compute/src/main/generated/org/elasticsearch/compute/aggregation/CountDistinctBytesRefGroupingAggregatorFunction.java index 1abea90e89ee3..8c11792fa4f4e 100644 --- a/x-pack/plugin/esql/compute/src/main/generated/org/elasticsearch/compute/aggregation/CountDistinctBytesRefGroupingAggregatorFunction.java +++ b/x-pack/plugin/esql/compute/src/main/generated/org/elasticsearch/compute/aggregation/CountDistinctBytesRefGroupingAggregatorFunction.java @@ -158,7 +158,7 @@ public void addIntermediateInput(int positionOffset, IntArrayBlock groups, Page return; } BytesRefVector hll = ((BytesRefBlock) hllUncast).asVector(); - BytesRef scratch = new BytesRef(); + BytesRef hllScratch = new BytesRef(); for (int groupPosition = 0; groupPosition < groups.getPositionCount(); groupPosition++) { if (groups.isNull(groupPosition)) { continue; @@ -168,7 +168,7 @@ public void addIntermediateInput(int positionOffset, IntArrayBlock groups, Page for (int g = groupStart; g < groupEnd; g++) { int groupId = groups.getInt(g); int valuesPosition = groupPosition + positionOffset; - CountDistinctBytesRefAggregator.combineIntermediate(state, groupId, hll.getBytesRef(valuesPosition, scratch)); + CountDistinctBytesRefAggregator.combineIntermediate(state, groupId, hll.getBytesRef(valuesPosition, hllScratch)); } } } @@ -223,7 +223,7 @@ public void addIntermediateInput(int positionOffset, IntBigArrayBlock groups, Pa return; } BytesRefVector hll = ((BytesRefBlock) hllUncast).asVector(); - BytesRef scratch = new BytesRef(); + BytesRef hllScratch = new BytesRef(); for (int groupPosition = 0; groupPosition < groups.getPositionCount(); groupPosition++) { if (groups.isNull(groupPosition)) { continue; @@ -233,7 +233,7 @@ public void addIntermediateInput(int positionOffset, IntBigArrayBlock groups, Pa for (int g = groupStart; g < groupEnd; g++) { int groupId = groups.getInt(g); int valuesPosition = groupPosition + positionOffset; - CountDistinctBytesRefAggregator.combineIntermediate(state, groupId, hll.getBytesRef(valuesPosition, scratch)); + CountDistinctBytesRefAggregator.combineIntermediate(state, groupId, hll.getBytesRef(valuesPosition, hllScratch)); } } } @@ -274,11 +274,11 @@ public void addIntermediateInput(int positionOffset, IntVector groups, Page page return; } BytesRefVector hll = ((BytesRefBlock) hllUncast).asVector(); - BytesRef scratch = new BytesRef(); + BytesRef hllScratch = new BytesRef(); for (int groupPosition = 0; groupPosition < groups.getPositionCount(); groupPosition++) { int groupId = groups.getInt(groupPosition); int valuesPosition = groupPosition + positionOffset; - CountDistinctBytesRefAggregator.combineIntermediate(state, groupId, hll.getBytesRef(valuesPosition, scratch)); + CountDistinctBytesRefAggregator.combineIntermediate(state, groupId, hll.getBytesRef(valuesPosition, hllScratch)); } } diff --git a/x-pack/plugin/esql/compute/src/main/generated/org/elasticsearch/compute/aggregation/CountDistinctDoubleAggregatorFunction.java b/x-pack/plugin/esql/compute/src/main/generated/org/elasticsearch/compute/aggregation/CountDistinctDoubleAggregatorFunction.java index 68d7270a49d0b..c791c3fd11b7a 100644 --- a/x-pack/plugin/esql/compute/src/main/generated/org/elasticsearch/compute/aggregation/CountDistinctDoubleAggregatorFunction.java +++ b/x-pack/plugin/esql/compute/src/main/generated/org/elasticsearch/compute/aggregation/CountDistinctDoubleAggregatorFunction.java @@ -149,8 +149,8 @@ public void addIntermediateInput(Page page) { } BytesRefVector hll = ((BytesRefBlock) hllUncast).asVector(); assert hll.getPositionCount() == 1; - BytesRef scratch = new BytesRef(); - CountDistinctDoubleAggregator.combineIntermediate(state, hll.getBytesRef(0, scratch)); + BytesRef hllScratch = new BytesRef(); + CountDistinctDoubleAggregator.combineIntermediate(state, hll.getBytesRef(0, hllScratch)); } @Override diff --git a/x-pack/plugin/esql/compute/src/main/generated/org/elasticsearch/compute/aggregation/CountDistinctDoubleGroupingAggregatorFunction.java b/x-pack/plugin/esql/compute/src/main/generated/org/elasticsearch/compute/aggregation/CountDistinctDoubleGroupingAggregatorFunction.java index c839f787c991f..3520b9f53f4c9 100644 --- a/x-pack/plugin/esql/compute/src/main/generated/org/elasticsearch/compute/aggregation/CountDistinctDoubleGroupingAggregatorFunction.java +++ b/x-pack/plugin/esql/compute/src/main/generated/org/elasticsearch/compute/aggregation/CountDistinctDoubleGroupingAggregatorFunction.java @@ -158,7 +158,7 @@ public void addIntermediateInput(int positionOffset, IntArrayBlock groups, Page return; } BytesRefVector hll = ((BytesRefBlock) hllUncast).asVector(); - BytesRef scratch = new BytesRef(); + BytesRef hllScratch = new BytesRef(); for (int groupPosition = 0; groupPosition < groups.getPositionCount(); groupPosition++) { if (groups.isNull(groupPosition)) { continue; @@ -168,7 +168,7 @@ public void addIntermediateInput(int positionOffset, IntArrayBlock groups, Page for (int g = groupStart; g < groupEnd; g++) { int groupId = groups.getInt(g); int valuesPosition = groupPosition + positionOffset; - CountDistinctDoubleAggregator.combineIntermediate(state, groupId, hll.getBytesRef(valuesPosition, scratch)); + CountDistinctDoubleAggregator.combineIntermediate(state, groupId, hll.getBytesRef(valuesPosition, hllScratch)); } } } @@ -221,7 +221,7 @@ public void addIntermediateInput(int positionOffset, IntBigArrayBlock groups, Pa return; } BytesRefVector hll = ((BytesRefBlock) hllUncast).asVector(); - BytesRef scratch = new BytesRef(); + BytesRef hllScratch = new BytesRef(); for (int groupPosition = 0; groupPosition < groups.getPositionCount(); groupPosition++) { if (groups.isNull(groupPosition)) { continue; @@ -231,7 +231,7 @@ public void addIntermediateInput(int positionOffset, IntBigArrayBlock groups, Pa for (int g = groupStart; g < groupEnd; g++) { int groupId = groups.getInt(g); int valuesPosition = groupPosition + positionOffset; - CountDistinctDoubleAggregator.combineIntermediate(state, groupId, hll.getBytesRef(valuesPosition, scratch)); + CountDistinctDoubleAggregator.combineIntermediate(state, groupId, hll.getBytesRef(valuesPosition, hllScratch)); } } } @@ -270,11 +270,11 @@ public void addIntermediateInput(int positionOffset, IntVector groups, Page page return; } BytesRefVector hll = ((BytesRefBlock) hllUncast).asVector(); - BytesRef scratch = new BytesRef(); + BytesRef hllScratch = new BytesRef(); for (int groupPosition = 0; groupPosition < groups.getPositionCount(); groupPosition++) { int groupId = groups.getInt(groupPosition); int valuesPosition = groupPosition + positionOffset; - CountDistinctDoubleAggregator.combineIntermediate(state, groupId, hll.getBytesRef(valuesPosition, scratch)); + CountDistinctDoubleAggregator.combineIntermediate(state, groupId, hll.getBytesRef(valuesPosition, hllScratch)); } } diff --git a/x-pack/plugin/esql/compute/src/main/generated/org/elasticsearch/compute/aggregation/CountDistinctFloatAggregatorFunction.java b/x-pack/plugin/esql/compute/src/main/generated/org/elasticsearch/compute/aggregation/CountDistinctFloatAggregatorFunction.java index c01c34887cf4e..06068bf343978 100644 --- a/x-pack/plugin/esql/compute/src/main/generated/org/elasticsearch/compute/aggregation/CountDistinctFloatAggregatorFunction.java +++ b/x-pack/plugin/esql/compute/src/main/generated/org/elasticsearch/compute/aggregation/CountDistinctFloatAggregatorFunction.java @@ -149,8 +149,8 @@ public void addIntermediateInput(Page page) { } BytesRefVector hll = ((BytesRefBlock) hllUncast).asVector(); assert hll.getPositionCount() == 1; - BytesRef scratch = new BytesRef(); - CountDistinctFloatAggregator.combineIntermediate(state, hll.getBytesRef(0, scratch)); + BytesRef hllScratch = new BytesRef(); + CountDistinctFloatAggregator.combineIntermediate(state, hll.getBytesRef(0, hllScratch)); } @Override diff --git a/x-pack/plugin/esql/compute/src/main/generated/org/elasticsearch/compute/aggregation/CountDistinctFloatGroupingAggregatorFunction.java b/x-pack/plugin/esql/compute/src/main/generated/org/elasticsearch/compute/aggregation/CountDistinctFloatGroupingAggregatorFunction.java index a8f284f7e8fdc..4a000e848c73b 100644 --- a/x-pack/plugin/esql/compute/src/main/generated/org/elasticsearch/compute/aggregation/CountDistinctFloatGroupingAggregatorFunction.java +++ b/x-pack/plugin/esql/compute/src/main/generated/org/elasticsearch/compute/aggregation/CountDistinctFloatGroupingAggregatorFunction.java @@ -158,7 +158,7 @@ public void addIntermediateInput(int positionOffset, IntArrayBlock groups, Page return; } BytesRefVector hll = ((BytesRefBlock) hllUncast).asVector(); - BytesRef scratch = new BytesRef(); + BytesRef hllScratch = new BytesRef(); for (int groupPosition = 0; groupPosition < groups.getPositionCount(); groupPosition++) { if (groups.isNull(groupPosition)) { continue; @@ -168,7 +168,7 @@ public void addIntermediateInput(int positionOffset, IntArrayBlock groups, Page for (int g = groupStart; g < groupEnd; g++) { int groupId = groups.getInt(g); int valuesPosition = groupPosition + positionOffset; - CountDistinctFloatAggregator.combineIntermediate(state, groupId, hll.getBytesRef(valuesPosition, scratch)); + CountDistinctFloatAggregator.combineIntermediate(state, groupId, hll.getBytesRef(valuesPosition, hllScratch)); } } } @@ -221,7 +221,7 @@ public void addIntermediateInput(int positionOffset, IntBigArrayBlock groups, Pa return; } BytesRefVector hll = ((BytesRefBlock) hllUncast).asVector(); - BytesRef scratch = new BytesRef(); + BytesRef hllScratch = new BytesRef(); for (int groupPosition = 0; groupPosition < groups.getPositionCount(); groupPosition++) { if (groups.isNull(groupPosition)) { continue; @@ -231,7 +231,7 @@ public void addIntermediateInput(int positionOffset, IntBigArrayBlock groups, Pa for (int g = groupStart; g < groupEnd; g++) { int groupId = groups.getInt(g); int valuesPosition = groupPosition + positionOffset; - CountDistinctFloatAggregator.combineIntermediate(state, groupId, hll.getBytesRef(valuesPosition, scratch)); + CountDistinctFloatAggregator.combineIntermediate(state, groupId, hll.getBytesRef(valuesPosition, hllScratch)); } } } @@ -270,11 +270,11 @@ public void addIntermediateInput(int positionOffset, IntVector groups, Page page return; } BytesRefVector hll = ((BytesRefBlock) hllUncast).asVector(); - BytesRef scratch = new BytesRef(); + BytesRef hllScratch = new BytesRef(); for (int groupPosition = 0; groupPosition < groups.getPositionCount(); groupPosition++) { int groupId = groups.getInt(groupPosition); int valuesPosition = groupPosition + positionOffset; - CountDistinctFloatAggregator.combineIntermediate(state, groupId, hll.getBytesRef(valuesPosition, scratch)); + CountDistinctFloatAggregator.combineIntermediate(state, groupId, hll.getBytesRef(valuesPosition, hllScratch)); } } diff --git a/x-pack/plugin/esql/compute/src/main/generated/org/elasticsearch/compute/aggregation/CountDistinctIntAggregatorFunction.java b/x-pack/plugin/esql/compute/src/main/generated/org/elasticsearch/compute/aggregation/CountDistinctIntAggregatorFunction.java index 25a82171c54e4..1d378d7d8bb06 100644 --- a/x-pack/plugin/esql/compute/src/main/generated/org/elasticsearch/compute/aggregation/CountDistinctIntAggregatorFunction.java +++ b/x-pack/plugin/esql/compute/src/main/generated/org/elasticsearch/compute/aggregation/CountDistinctIntAggregatorFunction.java @@ -149,8 +149,8 @@ public void addIntermediateInput(Page page) { } BytesRefVector hll = ((BytesRefBlock) hllUncast).asVector(); assert hll.getPositionCount() == 1; - BytesRef scratch = new BytesRef(); - CountDistinctIntAggregator.combineIntermediate(state, hll.getBytesRef(0, scratch)); + BytesRef hllScratch = new BytesRef(); + CountDistinctIntAggregator.combineIntermediate(state, hll.getBytesRef(0, hllScratch)); } @Override diff --git a/x-pack/plugin/esql/compute/src/main/generated/org/elasticsearch/compute/aggregation/CountDistinctIntGroupingAggregatorFunction.java b/x-pack/plugin/esql/compute/src/main/generated/org/elasticsearch/compute/aggregation/CountDistinctIntGroupingAggregatorFunction.java index ad7e329d8ea7d..5320bff130fa5 100644 --- a/x-pack/plugin/esql/compute/src/main/generated/org/elasticsearch/compute/aggregation/CountDistinctIntGroupingAggregatorFunction.java +++ b/x-pack/plugin/esql/compute/src/main/generated/org/elasticsearch/compute/aggregation/CountDistinctIntGroupingAggregatorFunction.java @@ -157,7 +157,7 @@ public void addIntermediateInput(int positionOffset, IntArrayBlock groups, Page return; } BytesRefVector hll = ((BytesRefBlock) hllUncast).asVector(); - BytesRef scratch = new BytesRef(); + BytesRef hllScratch = new BytesRef(); for (int groupPosition = 0; groupPosition < groups.getPositionCount(); groupPosition++) { if (groups.isNull(groupPosition)) { continue; @@ -167,7 +167,7 @@ public void addIntermediateInput(int positionOffset, IntArrayBlock groups, Page for (int g = groupStart; g < groupEnd; g++) { int groupId = groups.getInt(g); int valuesPosition = groupPosition + positionOffset; - CountDistinctIntAggregator.combineIntermediate(state, groupId, hll.getBytesRef(valuesPosition, scratch)); + CountDistinctIntAggregator.combineIntermediate(state, groupId, hll.getBytesRef(valuesPosition, hllScratch)); } } } @@ -220,7 +220,7 @@ public void addIntermediateInput(int positionOffset, IntBigArrayBlock groups, Pa return; } BytesRefVector hll = ((BytesRefBlock) hllUncast).asVector(); - BytesRef scratch = new BytesRef(); + BytesRef hllScratch = new BytesRef(); for (int groupPosition = 0; groupPosition < groups.getPositionCount(); groupPosition++) { if (groups.isNull(groupPosition)) { continue; @@ -230,7 +230,7 @@ public void addIntermediateInput(int positionOffset, IntBigArrayBlock groups, Pa for (int g = groupStart; g < groupEnd; g++) { int groupId = groups.getInt(g); int valuesPosition = groupPosition + positionOffset; - CountDistinctIntAggregator.combineIntermediate(state, groupId, hll.getBytesRef(valuesPosition, scratch)); + CountDistinctIntAggregator.combineIntermediate(state, groupId, hll.getBytesRef(valuesPosition, hllScratch)); } } } @@ -269,11 +269,11 @@ public void addIntermediateInput(int positionOffset, IntVector groups, Page page return; } BytesRefVector hll = ((BytesRefBlock) hllUncast).asVector(); - BytesRef scratch = new BytesRef(); + BytesRef hllScratch = new BytesRef(); for (int groupPosition = 0; groupPosition < groups.getPositionCount(); groupPosition++) { int groupId = groups.getInt(groupPosition); int valuesPosition = groupPosition + positionOffset; - CountDistinctIntAggregator.combineIntermediate(state, groupId, hll.getBytesRef(valuesPosition, scratch)); + CountDistinctIntAggregator.combineIntermediate(state, groupId, hll.getBytesRef(valuesPosition, hllScratch)); } } diff --git a/x-pack/plugin/esql/compute/src/main/generated/org/elasticsearch/compute/aggregation/CountDistinctLongAggregatorFunction.java b/x-pack/plugin/esql/compute/src/main/generated/org/elasticsearch/compute/aggregation/CountDistinctLongAggregatorFunction.java index 34c5b2ee2bda5..88ddb7261f378 100644 --- a/x-pack/plugin/esql/compute/src/main/generated/org/elasticsearch/compute/aggregation/CountDistinctLongAggregatorFunction.java +++ b/x-pack/plugin/esql/compute/src/main/generated/org/elasticsearch/compute/aggregation/CountDistinctLongAggregatorFunction.java @@ -149,8 +149,8 @@ public void addIntermediateInput(Page page) { } BytesRefVector hll = ((BytesRefBlock) hllUncast).asVector(); assert hll.getPositionCount() == 1; - BytesRef scratch = new BytesRef(); - CountDistinctLongAggregator.combineIntermediate(state, hll.getBytesRef(0, scratch)); + BytesRef hllScratch = new BytesRef(); + CountDistinctLongAggregator.combineIntermediate(state, hll.getBytesRef(0, hllScratch)); } @Override diff --git a/x-pack/plugin/esql/compute/src/main/generated/org/elasticsearch/compute/aggregation/CountDistinctLongGroupingAggregatorFunction.java b/x-pack/plugin/esql/compute/src/main/generated/org/elasticsearch/compute/aggregation/CountDistinctLongGroupingAggregatorFunction.java index 8bdff2e73ebb9..5a76c5440615c 100644 --- a/x-pack/plugin/esql/compute/src/main/generated/org/elasticsearch/compute/aggregation/CountDistinctLongGroupingAggregatorFunction.java +++ b/x-pack/plugin/esql/compute/src/main/generated/org/elasticsearch/compute/aggregation/CountDistinctLongGroupingAggregatorFunction.java @@ -158,7 +158,7 @@ public void addIntermediateInput(int positionOffset, IntArrayBlock groups, Page return; } BytesRefVector hll = ((BytesRefBlock) hllUncast).asVector(); - BytesRef scratch = new BytesRef(); + BytesRef hllScratch = new BytesRef(); for (int groupPosition = 0; groupPosition < groups.getPositionCount(); groupPosition++) { if (groups.isNull(groupPosition)) { continue; @@ -168,7 +168,7 @@ public void addIntermediateInput(int positionOffset, IntArrayBlock groups, Page for (int g = groupStart; g < groupEnd; g++) { int groupId = groups.getInt(g); int valuesPosition = groupPosition + positionOffset; - CountDistinctLongAggregator.combineIntermediate(state, groupId, hll.getBytesRef(valuesPosition, scratch)); + CountDistinctLongAggregator.combineIntermediate(state, groupId, hll.getBytesRef(valuesPosition, hllScratch)); } } } @@ -221,7 +221,7 @@ public void addIntermediateInput(int positionOffset, IntBigArrayBlock groups, Pa return; } BytesRefVector hll = ((BytesRefBlock) hllUncast).asVector(); - BytesRef scratch = new BytesRef(); + BytesRef hllScratch = new BytesRef(); for (int groupPosition = 0; groupPosition < groups.getPositionCount(); groupPosition++) { if (groups.isNull(groupPosition)) { continue; @@ -231,7 +231,7 @@ public void addIntermediateInput(int positionOffset, IntBigArrayBlock groups, Pa for (int g = groupStart; g < groupEnd; g++) { int groupId = groups.getInt(g); int valuesPosition = groupPosition + positionOffset; - CountDistinctLongAggregator.combineIntermediate(state, groupId, hll.getBytesRef(valuesPosition, scratch)); + CountDistinctLongAggregator.combineIntermediate(state, groupId, hll.getBytesRef(valuesPosition, hllScratch)); } } } @@ -270,11 +270,11 @@ public void addIntermediateInput(int positionOffset, IntVector groups, Page page return; } BytesRefVector hll = ((BytesRefBlock) hllUncast).asVector(); - BytesRef scratch = new BytesRef(); + BytesRef hllScratch = new BytesRef(); for (int groupPosition = 0; groupPosition < groups.getPositionCount(); groupPosition++) { int groupId = groups.getInt(groupPosition); int valuesPosition = groupPosition + positionOffset; - CountDistinctLongAggregator.combineIntermediate(state, groupId, hll.getBytesRef(valuesPosition, scratch)); + CountDistinctLongAggregator.combineIntermediate(state, groupId, hll.getBytesRef(valuesPosition, hllScratch)); } } diff --git a/x-pack/plugin/esql/compute/src/main/generated/org/elasticsearch/compute/aggregation/ExponentialHistogramMergeAggregatorFunction.java b/x-pack/plugin/esql/compute/src/main/generated/org/elasticsearch/compute/aggregation/ExponentialHistogramMergeAggregatorFunction.java new file mode 100644 index 0000000000000..f81a4263a07fb --- /dev/null +++ b/x-pack/plugin/esql/compute/src/main/generated/org/elasticsearch/compute/aggregation/ExponentialHistogramMergeAggregatorFunction.java @@ -0,0 +1,149 @@ +// Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one +// or more contributor license agreements. Licensed under the Elastic License +// 2.0; you may not use this file except in compliance with the Elastic License +// 2.0. +package org.elasticsearch.compute.aggregation; + +import java.lang.Integer; +import java.lang.Override; +import java.lang.String; +import java.lang.StringBuilder; +import java.util.List; +import org.elasticsearch.compute.data.Block; +import org.elasticsearch.compute.data.BooleanVector; +import org.elasticsearch.compute.data.ElementType; +import org.elasticsearch.compute.data.ExponentialHistogramBlock; +import org.elasticsearch.compute.data.ExponentialHistogramScratch; +import org.elasticsearch.compute.data.Page; +import org.elasticsearch.compute.operator.DriverContext; +import org.elasticsearch.exponentialhistogram.ExponentialHistogram; + +/** + * {@link AggregatorFunction} implementation for {@link ExponentialHistogramMergeAggregator}. + * This class is generated. Edit {@code AggregatorImplementer} instead. + */ +public final class ExponentialHistogramMergeAggregatorFunction implements AggregatorFunction { + private static final List INTERMEDIATE_STATE_DESC = List.of( + new IntermediateStateDesc("value", ElementType.EXPONENTIAL_HISTOGRAM) ); + + private final DriverContext driverContext; + + private final ExponentialHistogramStates.SingleState state; + + private final List channels; + + public ExponentialHistogramMergeAggregatorFunction(DriverContext driverContext, + List channels, ExponentialHistogramStates.SingleState state) { + this.driverContext = driverContext; + this.channels = channels; + this.state = state; + } + + public static ExponentialHistogramMergeAggregatorFunction create(DriverContext driverContext, + List channels) { + return new ExponentialHistogramMergeAggregatorFunction(driverContext, channels, ExponentialHistogramMergeAggregator.initSingle(driverContext)); + } + + public static List intermediateStateDesc() { + return INTERMEDIATE_STATE_DESC; + } + + @Override + public int intermediateBlockCount() { + return INTERMEDIATE_STATE_DESC.size(); + } + + @Override + public void addRawInput(Page page, BooleanVector mask) { + if (mask.allFalse()) { + // Entire page masked away + } else if (mask.allTrue()) { + addRawInputNotMasked(page); + } else { + addRawInputMasked(page, mask); + } + } + + private void addRawInputMasked(Page page, BooleanVector mask) { + ExponentialHistogramBlock valueBlock = page.getBlock(channels.get(0)); + addRawBlock(valueBlock, mask); + } + + private void addRawInputNotMasked(Page page) { + ExponentialHistogramBlock valueBlock = page.getBlock(channels.get(0)); + addRawBlock(valueBlock); + } + + private void addRawBlock(ExponentialHistogramBlock valueBlock) { + ExponentialHistogramScratch valueScratch = new ExponentialHistogramScratch(); + for (int p = 0; p < valueBlock.getPositionCount(); p++) { + int valueValueCount = valueBlock.getValueCount(p); + if (valueValueCount == 0) { + continue; + } + int valueStart = valueBlock.getFirstValueIndex(p); + int valueEnd = valueStart + valueValueCount; + for (int valueOffset = valueStart; valueOffset < valueEnd; valueOffset++) { + ExponentialHistogram valueValue = valueBlock.getExponentialHistogram(valueOffset, valueScratch); + ExponentialHistogramMergeAggregator.combine(state, valueValue); + } + } + } + + private void addRawBlock(ExponentialHistogramBlock valueBlock, BooleanVector mask) { + ExponentialHistogramScratch valueScratch = new ExponentialHistogramScratch(); + for (int p = 0; p < valueBlock.getPositionCount(); p++) { + if (mask.getBoolean(p) == false) { + continue; + } + int valueValueCount = valueBlock.getValueCount(p); + if (valueValueCount == 0) { + continue; + } + int valueStart = valueBlock.getFirstValueIndex(p); + int valueEnd = valueStart + valueValueCount; + for (int valueOffset = valueStart; valueOffset < valueEnd; valueOffset++) { + ExponentialHistogram valueValue = valueBlock.getExponentialHistogram(valueOffset, valueScratch); + ExponentialHistogramMergeAggregator.combine(state, valueValue); + } + } + } + + @Override + public void addIntermediateInput(Page page) { + assert channels.size() == intermediateBlockCount(); + assert page.getBlockCount() >= channels.get(0) + intermediateStateDesc().size(); + Block valueUncast = page.getBlock(channels.get(0)); + if (valueUncast.areAllValuesNull()) { + return; + } + ExponentialHistogramBlock value = (ExponentialHistogramBlock) valueUncast; + assert value.getPositionCount() == 1; + ExponentialHistogramScratch valueScratch = new ExponentialHistogramScratch(); + ExponentialHistogramMergeAggregator.combineIntermediate(state, value.getExponentialHistogram(value.getFirstValueIndex(0), valueScratch)); + } + + @Override + public void evaluateIntermediate(Block[] blocks, int offset, DriverContext driverContext) { + state.toIntermediate(blocks, offset, driverContext); + } + + @Override + public void evaluateFinal(Block[] blocks, int offset, DriverContext driverContext) { + blocks[offset] = ExponentialHistogramMergeAggregator.evaluateFinal(state, driverContext); + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append(getClass().getSimpleName()).append("["); + sb.append("channels=").append(channels); + sb.append("]"); + return sb.toString(); + } + + @Override + public void close() { + state.close(); + } +} diff --git a/x-pack/plugin/esql/compute/src/main/generated/org/elasticsearch/compute/aggregation/ExponentialHistogramMergeAggregatorFunctionSupplier.java b/x-pack/plugin/esql/compute/src/main/generated/org/elasticsearch/compute/aggregation/ExponentialHistogramMergeAggregatorFunctionSupplier.java new file mode 100644 index 0000000000000..c6fbb08c2eefb --- /dev/null +++ b/x-pack/plugin/esql/compute/src/main/generated/org/elasticsearch/compute/aggregation/ExponentialHistogramMergeAggregatorFunctionSupplier.java @@ -0,0 +1,47 @@ +// Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one +// or more contributor license agreements. Licensed under the Elastic License +// 2.0; you may not use this file except in compliance with the Elastic License +// 2.0. +package org.elasticsearch.compute.aggregation; + +import java.lang.Integer; +import java.lang.Override; +import java.lang.String; +import java.util.List; +import org.elasticsearch.compute.operator.DriverContext; + +/** + * {@link AggregatorFunctionSupplier} implementation for {@link ExponentialHistogramMergeAggregator}. + * This class is generated. Edit {@code AggregatorFunctionSupplierImplementer} instead. + */ +public final class ExponentialHistogramMergeAggregatorFunctionSupplier implements AggregatorFunctionSupplier { + public ExponentialHistogramMergeAggregatorFunctionSupplier() { + } + + @Override + public List nonGroupingIntermediateStateDesc() { + return ExponentialHistogramMergeAggregatorFunction.intermediateStateDesc(); + } + + @Override + public List groupingIntermediateStateDesc() { + return ExponentialHistogramMergeGroupingAggregatorFunction.intermediateStateDesc(); + } + + @Override + public ExponentialHistogramMergeAggregatorFunction aggregator(DriverContext driverContext, + List channels) { + return ExponentialHistogramMergeAggregatorFunction.create(driverContext, channels); + } + + @Override + public ExponentialHistogramMergeGroupingAggregatorFunction groupingAggregator( + DriverContext driverContext, List channels) { + return ExponentialHistogramMergeGroupingAggregatorFunction.create(channels, driverContext); + } + + @Override + public String describe() { + return "exponential_histogram of merges"; + } +} diff --git a/x-pack/plugin/esql/compute/src/main/generated/org/elasticsearch/compute/aggregation/ExponentialHistogramMergeGroupingAggregatorFunction.java b/x-pack/plugin/esql/compute/src/main/generated/org/elasticsearch/compute/aggregation/ExponentialHistogramMergeGroupingAggregatorFunction.java new file mode 100644 index 0000000000000..db62ef15ffa76 --- /dev/null +++ b/x-pack/plugin/esql/compute/src/main/generated/org/elasticsearch/compute/aggregation/ExponentialHistogramMergeGroupingAggregatorFunction.java @@ -0,0 +1,254 @@ +// Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one +// or more contributor license agreements. Licensed under the Elastic License +// 2.0; you may not use this file except in compliance with the Elastic License +// 2.0. +package org.elasticsearch.compute.aggregation; + +import java.lang.Integer; +import java.lang.Override; +import java.lang.String; +import java.lang.StringBuilder; +import java.util.List; +import org.elasticsearch.compute.data.Block; +import org.elasticsearch.compute.data.ElementType; +import org.elasticsearch.compute.data.ExponentialHistogramBlock; +import org.elasticsearch.compute.data.ExponentialHistogramScratch; +import org.elasticsearch.compute.data.IntArrayBlock; +import org.elasticsearch.compute.data.IntBigArrayBlock; +import org.elasticsearch.compute.data.IntVector; +import org.elasticsearch.compute.data.Page; +import org.elasticsearch.compute.operator.DriverContext; +import org.elasticsearch.exponentialhistogram.ExponentialHistogram; + +/** + * {@link GroupingAggregatorFunction} implementation for {@link ExponentialHistogramMergeAggregator}. + * This class is generated. Edit {@code GroupingAggregatorImplementer} instead. + */ +public final class ExponentialHistogramMergeGroupingAggregatorFunction implements GroupingAggregatorFunction { + private static final List INTERMEDIATE_STATE_DESC = List.of( + new IntermediateStateDesc("value", ElementType.EXPONENTIAL_HISTOGRAM) ); + + private final ExponentialHistogramStates.GroupingState state; + + private final List channels; + + private final DriverContext driverContext; + + public ExponentialHistogramMergeGroupingAggregatorFunction(List channels, + ExponentialHistogramStates.GroupingState state, DriverContext driverContext) { + this.channels = channels; + this.state = state; + this.driverContext = driverContext; + } + + public static ExponentialHistogramMergeGroupingAggregatorFunction create(List channels, + DriverContext driverContext) { + return new ExponentialHistogramMergeGroupingAggregatorFunction(channels, ExponentialHistogramMergeAggregator.initGrouping(driverContext.bigArrays(), driverContext), driverContext); + } + + public static List intermediateStateDesc() { + return INTERMEDIATE_STATE_DESC; + } + + @Override + public int intermediateBlockCount() { + return INTERMEDIATE_STATE_DESC.size(); + } + + @Override + public GroupingAggregatorFunction.AddInput prepareProcessRawInputPage(SeenGroupIds seenGroupIds, + Page page) { + ExponentialHistogramBlock valueBlock = page.getBlock(channels.get(0)); + maybeEnableGroupIdTracking(seenGroupIds, valueBlock); + return new GroupingAggregatorFunction.AddInput() { + @Override + public void add(int positionOffset, IntArrayBlock groupIds) { + addRawInput(positionOffset, groupIds, valueBlock); + } + + @Override + public void add(int positionOffset, IntBigArrayBlock groupIds) { + addRawInput(positionOffset, groupIds, valueBlock); + } + + @Override + public void add(int positionOffset, IntVector groupIds) { + addRawInput(positionOffset, groupIds, valueBlock); + } + + @Override + public void close() { + } + }; + } + + private void addRawInput(int positionOffset, IntArrayBlock groups, + ExponentialHistogramBlock valueBlock) { + ExponentialHistogramScratch valueScratch = new ExponentialHistogramScratch(); + for (int groupPosition = 0; groupPosition < groups.getPositionCount(); groupPosition++) { + if (groups.isNull(groupPosition)) { + continue; + } + int valuesPosition = groupPosition + positionOffset; + if (valueBlock.isNull(valuesPosition)) { + continue; + } + int groupStart = groups.getFirstValueIndex(groupPosition); + int groupEnd = groupStart + groups.getValueCount(groupPosition); + for (int g = groupStart; g < groupEnd; g++) { + int groupId = groups.getInt(g); + int valueStart = valueBlock.getFirstValueIndex(valuesPosition); + int valueEnd = valueStart + valueBlock.getValueCount(valuesPosition); + for (int valueOffset = valueStart; valueOffset < valueEnd; valueOffset++) { + ExponentialHistogram valueValue = valueBlock.getExponentialHistogram(valueOffset, valueScratch); + ExponentialHistogramMergeAggregator.combine(state, groupId, valueValue); + } + } + } + } + + @Override + public void addIntermediateInput(int positionOffset, IntArrayBlock groups, Page page) { + state.enableGroupIdTracking(new SeenGroupIds.Empty()); + assert channels.size() == intermediateBlockCount(); + Block valueUncast = page.getBlock(channels.get(0)); + if (valueUncast.areAllValuesNull()) { + return; + } + ExponentialHistogramBlock value = (ExponentialHistogramBlock) valueUncast; + ExponentialHistogramScratch valueScratch = new ExponentialHistogramScratch(); + for (int groupPosition = 0; groupPosition < groups.getPositionCount(); groupPosition++) { + if (groups.isNull(groupPosition)) { + continue; + } + int groupStart = groups.getFirstValueIndex(groupPosition); + int groupEnd = groupStart + groups.getValueCount(groupPosition); + for (int g = groupStart; g < groupEnd; g++) { + int groupId = groups.getInt(g); + int valuesPosition = groupPosition + positionOffset; + ExponentialHistogramMergeAggregator.combineIntermediate(state, groupId, value.getExponentialHistogram(value.getFirstValueIndex(valuesPosition), valueScratch)); + } + } + } + + private void addRawInput(int positionOffset, IntBigArrayBlock groups, + ExponentialHistogramBlock valueBlock) { + ExponentialHistogramScratch valueScratch = new ExponentialHistogramScratch(); + for (int groupPosition = 0; groupPosition < groups.getPositionCount(); groupPosition++) { + if (groups.isNull(groupPosition)) { + continue; + } + int valuesPosition = groupPosition + positionOffset; + if (valueBlock.isNull(valuesPosition)) { + continue; + } + int groupStart = groups.getFirstValueIndex(groupPosition); + int groupEnd = groupStart + groups.getValueCount(groupPosition); + for (int g = groupStart; g < groupEnd; g++) { + int groupId = groups.getInt(g); + int valueStart = valueBlock.getFirstValueIndex(valuesPosition); + int valueEnd = valueStart + valueBlock.getValueCount(valuesPosition); + for (int valueOffset = valueStart; valueOffset < valueEnd; valueOffset++) { + ExponentialHistogram valueValue = valueBlock.getExponentialHistogram(valueOffset, valueScratch); + ExponentialHistogramMergeAggregator.combine(state, groupId, valueValue); + } + } + } + } + + @Override + public void addIntermediateInput(int positionOffset, IntBigArrayBlock groups, Page page) { + state.enableGroupIdTracking(new SeenGroupIds.Empty()); + assert channels.size() == intermediateBlockCount(); + Block valueUncast = page.getBlock(channels.get(0)); + if (valueUncast.areAllValuesNull()) { + return; + } + ExponentialHistogramBlock value = (ExponentialHistogramBlock) valueUncast; + ExponentialHistogramScratch valueScratch = new ExponentialHistogramScratch(); + for (int groupPosition = 0; groupPosition < groups.getPositionCount(); groupPosition++) { + if (groups.isNull(groupPosition)) { + continue; + } + int groupStart = groups.getFirstValueIndex(groupPosition); + int groupEnd = groupStart + groups.getValueCount(groupPosition); + for (int g = groupStart; g < groupEnd; g++) { + int groupId = groups.getInt(g); + int valuesPosition = groupPosition + positionOffset; + ExponentialHistogramMergeAggregator.combineIntermediate(state, groupId, value.getExponentialHistogram(value.getFirstValueIndex(valuesPosition), valueScratch)); + } + } + } + + private void addRawInput(int positionOffset, IntVector groups, + ExponentialHistogramBlock valueBlock) { + ExponentialHistogramScratch valueScratch = new ExponentialHistogramScratch(); + for (int groupPosition = 0; groupPosition < groups.getPositionCount(); groupPosition++) { + int valuesPosition = groupPosition + positionOffset; + if (valueBlock.isNull(valuesPosition)) { + continue; + } + int groupId = groups.getInt(groupPosition); + int valueStart = valueBlock.getFirstValueIndex(valuesPosition); + int valueEnd = valueStart + valueBlock.getValueCount(valuesPosition); + for (int valueOffset = valueStart; valueOffset < valueEnd; valueOffset++) { + ExponentialHistogram valueValue = valueBlock.getExponentialHistogram(valueOffset, valueScratch); + ExponentialHistogramMergeAggregator.combine(state, groupId, valueValue); + } + } + } + + @Override + public void addIntermediateInput(int positionOffset, IntVector groups, Page page) { + state.enableGroupIdTracking(new SeenGroupIds.Empty()); + assert channels.size() == intermediateBlockCount(); + Block valueUncast = page.getBlock(channels.get(0)); + if (valueUncast.areAllValuesNull()) { + return; + } + ExponentialHistogramBlock value = (ExponentialHistogramBlock) valueUncast; + ExponentialHistogramScratch valueScratch = new ExponentialHistogramScratch(); + for (int groupPosition = 0; groupPosition < groups.getPositionCount(); groupPosition++) { + int groupId = groups.getInt(groupPosition); + int valuesPosition = groupPosition + positionOffset; + ExponentialHistogramMergeAggregator.combineIntermediate(state, groupId, value.getExponentialHistogram(value.getFirstValueIndex(valuesPosition), valueScratch)); + } + } + + private void maybeEnableGroupIdTracking(SeenGroupIds seenGroupIds, + ExponentialHistogramBlock valueBlock) { + if (valueBlock.mayHaveNulls()) { + state.enableGroupIdTracking(seenGroupIds); + } + } + + @Override + public void selectedMayContainUnseenGroups(SeenGroupIds seenGroupIds) { + state.enableGroupIdTracking(seenGroupIds); + } + + @Override + public void evaluateIntermediate(Block[] blocks, int offset, IntVector selected) { + state.toIntermediate(blocks, offset, selected, driverContext); + } + + @Override + public void evaluateFinal(Block[] blocks, int offset, IntVector selected, + GroupingAggregatorEvaluationContext ctx) { + blocks[offset] = ExponentialHistogramMergeAggregator.evaluateFinal(state, selected, ctx); + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append(getClass().getSimpleName()).append("["); + sb.append("channels=").append(channels); + sb.append("]"); + return sb.toString(); + } + + @Override + public void close() { + state.close(); + } +} diff --git a/x-pack/plugin/esql/compute/src/main/generated/org/elasticsearch/compute/aggregation/FirstBytesRefByTimestampAggregatorFunction.java b/x-pack/plugin/esql/compute/src/main/generated/org/elasticsearch/compute/aggregation/FirstBytesRefByTimestampAggregatorFunction.java index eb88ed39323d2..91822de9973aa 100644 --- a/x-pack/plugin/esql/compute/src/main/generated/org/elasticsearch/compute/aggregation/FirstBytesRefByTimestampAggregatorFunction.java +++ b/x-pack/plugin/esql/compute/src/main/generated/org/elasticsearch/compute/aggregation/FirstBytesRefByTimestampAggregatorFunction.java @@ -237,8 +237,8 @@ public void addIntermediateInput(Page page) { } BooleanVector seen = ((BooleanBlock) seenUncast).asVector(); assert seen.getPositionCount() == 1; - BytesRef scratch = new BytesRef(); - FirstBytesRefByTimestampAggregator.combineIntermediate(state, timestamps.getLong(0), values.getBytesRef(0, scratch), seen.getBoolean(0)); + BytesRef valuesScratch = new BytesRef(); + FirstBytesRefByTimestampAggregator.combineIntermediate(state, timestamps.getLong(0), values.getBytesRef(0, valuesScratch), seen.getBoolean(0)); } @Override diff --git a/x-pack/plugin/esql/compute/src/main/generated/org/elasticsearch/compute/aggregation/FirstBytesRefByTimestampGroupingAggregatorFunction.java b/x-pack/plugin/esql/compute/src/main/generated/org/elasticsearch/compute/aggregation/FirstBytesRefByTimestampGroupingAggregatorFunction.java index aee8d6296dc02..42b016f4580d8 100644 --- a/x-pack/plugin/esql/compute/src/main/generated/org/elasticsearch/compute/aggregation/FirstBytesRefByTimestampGroupingAggregatorFunction.java +++ b/x-pack/plugin/esql/compute/src/main/generated/org/elasticsearch/compute/aggregation/FirstBytesRefByTimestampGroupingAggregatorFunction.java @@ -200,7 +200,7 @@ public void addIntermediateInput(int positionOffset, IntArrayBlock groups, Page } BytesRefBlock values = (BytesRefBlock) valuesUncast; assert timestamps.getPositionCount() == values.getPositionCount(); - BytesRef scratch = new BytesRef(); + BytesRef valuesScratch = new BytesRef(); for (int groupPosition = 0; groupPosition < groups.getPositionCount(); groupPosition++) { if (groups.isNull(groupPosition)) { continue; @@ -282,7 +282,7 @@ public void addIntermediateInput(int positionOffset, IntBigArrayBlock groups, Pa } BytesRefBlock values = (BytesRefBlock) valuesUncast; assert timestamps.getPositionCount() == values.getPositionCount(); - BytesRef scratch = new BytesRef(); + BytesRef valuesScratch = new BytesRef(); for (int groupPosition = 0; groupPosition < groups.getPositionCount(); groupPosition++) { if (groups.isNull(groupPosition)) { continue; @@ -350,7 +350,7 @@ public void addIntermediateInput(int positionOffset, IntVector groups, Page page } BytesRefBlock values = (BytesRefBlock) valuesUncast; assert timestamps.getPositionCount() == values.getPositionCount(); - BytesRef scratch = new BytesRef(); + BytesRef valuesScratch = new BytesRef(); for (int groupPosition = 0; groupPosition < groups.getPositionCount(); groupPosition++) { int groupId = groups.getInt(groupPosition); int valuesPosition = groupPosition + positionOffset; diff --git a/x-pack/plugin/esql/compute/src/main/generated/org/elasticsearch/compute/aggregation/LastBytesRefByTimestampAggregatorFunction.java b/x-pack/plugin/esql/compute/src/main/generated/org/elasticsearch/compute/aggregation/LastBytesRefByTimestampAggregatorFunction.java index 0233a00ccd45f..70b05e5ae2910 100644 --- a/x-pack/plugin/esql/compute/src/main/generated/org/elasticsearch/compute/aggregation/LastBytesRefByTimestampAggregatorFunction.java +++ b/x-pack/plugin/esql/compute/src/main/generated/org/elasticsearch/compute/aggregation/LastBytesRefByTimestampAggregatorFunction.java @@ -237,8 +237,8 @@ public void addIntermediateInput(Page page) { } BooleanVector seen = ((BooleanBlock) seenUncast).asVector(); assert seen.getPositionCount() == 1; - BytesRef scratch = new BytesRef(); - LastBytesRefByTimestampAggregator.combineIntermediate(state, timestamps.getLong(0), values.getBytesRef(0, scratch), seen.getBoolean(0)); + BytesRef valuesScratch = new BytesRef(); + LastBytesRefByTimestampAggregator.combineIntermediate(state, timestamps.getLong(0), values.getBytesRef(0, valuesScratch), seen.getBoolean(0)); } @Override diff --git a/x-pack/plugin/esql/compute/src/main/generated/org/elasticsearch/compute/aggregation/LastBytesRefByTimestampGroupingAggregatorFunction.java b/x-pack/plugin/esql/compute/src/main/generated/org/elasticsearch/compute/aggregation/LastBytesRefByTimestampGroupingAggregatorFunction.java index c5ee2afaf04c7..4ee67fdbdb818 100644 --- a/x-pack/plugin/esql/compute/src/main/generated/org/elasticsearch/compute/aggregation/LastBytesRefByTimestampGroupingAggregatorFunction.java +++ b/x-pack/plugin/esql/compute/src/main/generated/org/elasticsearch/compute/aggregation/LastBytesRefByTimestampGroupingAggregatorFunction.java @@ -200,7 +200,7 @@ public void addIntermediateInput(int positionOffset, IntArrayBlock groups, Page } BytesRefBlock values = (BytesRefBlock) valuesUncast; assert timestamps.getPositionCount() == values.getPositionCount(); - BytesRef scratch = new BytesRef(); + BytesRef valuesScratch = new BytesRef(); for (int groupPosition = 0; groupPosition < groups.getPositionCount(); groupPosition++) { if (groups.isNull(groupPosition)) { continue; @@ -282,7 +282,7 @@ public void addIntermediateInput(int positionOffset, IntBigArrayBlock groups, Pa } BytesRefBlock values = (BytesRefBlock) valuesUncast; assert timestamps.getPositionCount() == values.getPositionCount(); - BytesRef scratch = new BytesRef(); + BytesRef valuesScratch = new BytesRef(); for (int groupPosition = 0; groupPosition < groups.getPositionCount(); groupPosition++) { if (groups.isNull(groupPosition)) { continue; @@ -350,7 +350,7 @@ public void addIntermediateInput(int positionOffset, IntVector groups, Page page } BytesRefBlock values = (BytesRefBlock) valuesUncast; assert timestamps.getPositionCount() == values.getPositionCount(); - BytesRef scratch = new BytesRef(); + BytesRef valuesScratch = new BytesRef(); for (int groupPosition = 0; groupPosition < groups.getPositionCount(); groupPosition++) { int groupId = groups.getInt(groupPosition); int valuesPosition = groupPosition + positionOffset; diff --git a/x-pack/plugin/esql/compute/src/main/generated/org/elasticsearch/compute/aggregation/MaxBytesRefAggregatorFunction.java b/x-pack/plugin/esql/compute/src/main/generated/org/elasticsearch/compute/aggregation/MaxBytesRefAggregatorFunction.java index 80810713866ce..e606864ba63f4 100644 --- a/x-pack/plugin/esql/compute/src/main/generated/org/elasticsearch/compute/aggregation/MaxBytesRefAggregatorFunction.java +++ b/x-pack/plugin/esql/compute/src/main/generated/org/elasticsearch/compute/aggregation/MaxBytesRefAggregatorFunction.java @@ -156,8 +156,8 @@ public void addIntermediateInput(Page page) { } BooleanVector seen = ((BooleanBlock) seenUncast).asVector(); assert seen.getPositionCount() == 1; - BytesRef scratch = new BytesRef(); - MaxBytesRefAggregator.combineIntermediate(state, max.getBytesRef(0, scratch), seen.getBoolean(0)); + BytesRef maxScratch = new BytesRef(); + MaxBytesRefAggregator.combineIntermediate(state, max.getBytesRef(0, maxScratch), seen.getBoolean(0)); } @Override diff --git a/x-pack/plugin/esql/compute/src/main/generated/org/elasticsearch/compute/aggregation/MaxBytesRefGroupingAggregatorFunction.java b/x-pack/plugin/esql/compute/src/main/generated/org/elasticsearch/compute/aggregation/MaxBytesRefGroupingAggregatorFunction.java index 793570db726a9..ab162190fa43d 100644 --- a/x-pack/plugin/esql/compute/src/main/generated/org/elasticsearch/compute/aggregation/MaxBytesRefGroupingAggregatorFunction.java +++ b/x-pack/plugin/esql/compute/src/main/generated/org/elasticsearch/compute/aggregation/MaxBytesRefGroupingAggregatorFunction.java @@ -164,7 +164,7 @@ public void addIntermediateInput(int positionOffset, IntArrayBlock groups, Page } BooleanVector seen = ((BooleanBlock) seenUncast).asVector(); assert max.getPositionCount() == seen.getPositionCount(); - BytesRef scratch = new BytesRef(); + BytesRef maxScratch = new BytesRef(); for (int groupPosition = 0; groupPosition < groups.getPositionCount(); groupPosition++) { if (groups.isNull(groupPosition)) { continue; @@ -174,7 +174,7 @@ public void addIntermediateInput(int positionOffset, IntArrayBlock groups, Page for (int g = groupStart; g < groupEnd; g++) { int groupId = groups.getInt(g); int valuesPosition = groupPosition + positionOffset; - MaxBytesRefAggregator.combineIntermediate(state, groupId, max.getBytesRef(valuesPosition, scratch), seen.getBoolean(valuesPosition)); + MaxBytesRefAggregator.combineIntermediate(state, groupId, max.getBytesRef(valuesPosition, maxScratch), seen.getBoolean(valuesPosition)); } } } @@ -236,7 +236,7 @@ public void addIntermediateInput(int positionOffset, IntBigArrayBlock groups, Pa } BooleanVector seen = ((BooleanBlock) seenUncast).asVector(); assert max.getPositionCount() == seen.getPositionCount(); - BytesRef scratch = new BytesRef(); + BytesRef maxScratch = new BytesRef(); for (int groupPosition = 0; groupPosition < groups.getPositionCount(); groupPosition++) { if (groups.isNull(groupPosition)) { continue; @@ -246,7 +246,7 @@ public void addIntermediateInput(int positionOffset, IntBigArrayBlock groups, Pa for (int g = groupStart; g < groupEnd; g++) { int groupId = groups.getInt(g); int valuesPosition = groupPosition + positionOffset; - MaxBytesRefAggregator.combineIntermediate(state, groupId, max.getBytesRef(valuesPosition, scratch), seen.getBoolean(valuesPosition)); + MaxBytesRefAggregator.combineIntermediate(state, groupId, max.getBytesRef(valuesPosition, maxScratch), seen.getBoolean(valuesPosition)); } } } @@ -293,11 +293,11 @@ public void addIntermediateInput(int positionOffset, IntVector groups, Page page } BooleanVector seen = ((BooleanBlock) seenUncast).asVector(); assert max.getPositionCount() == seen.getPositionCount(); - BytesRef scratch = new BytesRef(); + BytesRef maxScratch = new BytesRef(); for (int groupPosition = 0; groupPosition < groups.getPositionCount(); groupPosition++) { int groupId = groups.getInt(groupPosition); int valuesPosition = groupPosition + positionOffset; - MaxBytesRefAggregator.combineIntermediate(state, groupId, max.getBytesRef(valuesPosition, scratch), seen.getBoolean(valuesPosition)); + MaxBytesRefAggregator.combineIntermediate(state, groupId, max.getBytesRef(valuesPosition, maxScratch), seen.getBoolean(valuesPosition)); } } diff --git a/x-pack/plugin/esql/compute/src/main/generated/org/elasticsearch/compute/aggregation/MaxIpAggregatorFunction.java b/x-pack/plugin/esql/compute/src/main/generated/org/elasticsearch/compute/aggregation/MaxIpAggregatorFunction.java index d192718d14e10..119cdb5917c06 100644 --- a/x-pack/plugin/esql/compute/src/main/generated/org/elasticsearch/compute/aggregation/MaxIpAggregatorFunction.java +++ b/x-pack/plugin/esql/compute/src/main/generated/org/elasticsearch/compute/aggregation/MaxIpAggregatorFunction.java @@ -156,8 +156,8 @@ public void addIntermediateInput(Page page) { } BooleanVector seen = ((BooleanBlock) seenUncast).asVector(); assert seen.getPositionCount() == 1; - BytesRef scratch = new BytesRef(); - MaxIpAggregator.combineIntermediate(state, max.getBytesRef(0, scratch), seen.getBoolean(0)); + BytesRef maxScratch = new BytesRef(); + MaxIpAggregator.combineIntermediate(state, max.getBytesRef(0, maxScratch), seen.getBoolean(0)); } @Override diff --git a/x-pack/plugin/esql/compute/src/main/generated/org/elasticsearch/compute/aggregation/MaxIpGroupingAggregatorFunction.java b/x-pack/plugin/esql/compute/src/main/generated/org/elasticsearch/compute/aggregation/MaxIpGroupingAggregatorFunction.java index bfee9d26f3996..5de02faac858a 100644 --- a/x-pack/plugin/esql/compute/src/main/generated/org/elasticsearch/compute/aggregation/MaxIpGroupingAggregatorFunction.java +++ b/x-pack/plugin/esql/compute/src/main/generated/org/elasticsearch/compute/aggregation/MaxIpGroupingAggregatorFunction.java @@ -164,7 +164,7 @@ public void addIntermediateInput(int positionOffset, IntArrayBlock groups, Page } BooleanVector seen = ((BooleanBlock) seenUncast).asVector(); assert max.getPositionCount() == seen.getPositionCount(); - BytesRef scratch = new BytesRef(); + BytesRef maxScratch = new BytesRef(); for (int groupPosition = 0; groupPosition < groups.getPositionCount(); groupPosition++) { if (groups.isNull(groupPosition)) { continue; @@ -174,7 +174,7 @@ public void addIntermediateInput(int positionOffset, IntArrayBlock groups, Page for (int g = groupStart; g < groupEnd; g++) { int groupId = groups.getInt(g); int valuesPosition = groupPosition + positionOffset; - MaxIpAggregator.combineIntermediate(state, groupId, max.getBytesRef(valuesPosition, scratch), seen.getBoolean(valuesPosition)); + MaxIpAggregator.combineIntermediate(state, groupId, max.getBytesRef(valuesPosition, maxScratch), seen.getBoolean(valuesPosition)); } } } @@ -236,7 +236,7 @@ public void addIntermediateInput(int positionOffset, IntBigArrayBlock groups, Pa } BooleanVector seen = ((BooleanBlock) seenUncast).asVector(); assert max.getPositionCount() == seen.getPositionCount(); - BytesRef scratch = new BytesRef(); + BytesRef maxScratch = new BytesRef(); for (int groupPosition = 0; groupPosition < groups.getPositionCount(); groupPosition++) { if (groups.isNull(groupPosition)) { continue; @@ -246,7 +246,7 @@ public void addIntermediateInput(int positionOffset, IntBigArrayBlock groups, Pa for (int g = groupStart; g < groupEnd; g++) { int groupId = groups.getInt(g); int valuesPosition = groupPosition + positionOffset; - MaxIpAggregator.combineIntermediate(state, groupId, max.getBytesRef(valuesPosition, scratch), seen.getBoolean(valuesPosition)); + MaxIpAggregator.combineIntermediate(state, groupId, max.getBytesRef(valuesPosition, maxScratch), seen.getBoolean(valuesPosition)); } } } @@ -293,11 +293,11 @@ public void addIntermediateInput(int positionOffset, IntVector groups, Page page } BooleanVector seen = ((BooleanBlock) seenUncast).asVector(); assert max.getPositionCount() == seen.getPositionCount(); - BytesRef scratch = new BytesRef(); + BytesRef maxScratch = new BytesRef(); for (int groupPosition = 0; groupPosition < groups.getPositionCount(); groupPosition++) { int groupId = groups.getInt(groupPosition); int valuesPosition = groupPosition + positionOffset; - MaxIpAggregator.combineIntermediate(state, groupId, max.getBytesRef(valuesPosition, scratch), seen.getBoolean(valuesPosition)); + MaxIpAggregator.combineIntermediate(state, groupId, max.getBytesRef(valuesPosition, maxScratch), seen.getBoolean(valuesPosition)); } } diff --git a/x-pack/plugin/esql/compute/src/main/generated/org/elasticsearch/compute/aggregation/MedianAbsoluteDeviationDoubleAggregatorFunction.java b/x-pack/plugin/esql/compute/src/main/generated/org/elasticsearch/compute/aggregation/MedianAbsoluteDeviationDoubleAggregatorFunction.java index 6c50628613ae1..43b4170f68d53 100644 --- a/x-pack/plugin/esql/compute/src/main/generated/org/elasticsearch/compute/aggregation/MedianAbsoluteDeviationDoubleAggregatorFunction.java +++ b/x-pack/plugin/esql/compute/src/main/generated/org/elasticsearch/compute/aggregation/MedianAbsoluteDeviationDoubleAggregatorFunction.java @@ -146,8 +146,8 @@ public void addIntermediateInput(Page page) { } BytesRefVector quart = ((BytesRefBlock) quartUncast).asVector(); assert quart.getPositionCount() == 1; - BytesRef scratch = new BytesRef(); - MedianAbsoluteDeviationDoubleAggregator.combineIntermediate(state, quart.getBytesRef(0, scratch)); + BytesRef quartScratch = new BytesRef(); + MedianAbsoluteDeviationDoubleAggregator.combineIntermediate(state, quart.getBytesRef(0, quartScratch)); } @Override diff --git a/x-pack/plugin/esql/compute/src/main/generated/org/elasticsearch/compute/aggregation/MedianAbsoluteDeviationDoubleGroupingAggregatorFunction.java b/x-pack/plugin/esql/compute/src/main/generated/org/elasticsearch/compute/aggregation/MedianAbsoluteDeviationDoubleGroupingAggregatorFunction.java index 3fd6a54970645..27531cb01ea14 100644 --- a/x-pack/plugin/esql/compute/src/main/generated/org/elasticsearch/compute/aggregation/MedianAbsoluteDeviationDoubleGroupingAggregatorFunction.java +++ b/x-pack/plugin/esql/compute/src/main/generated/org/elasticsearch/compute/aggregation/MedianAbsoluteDeviationDoubleGroupingAggregatorFunction.java @@ -155,7 +155,7 @@ public void addIntermediateInput(int positionOffset, IntArrayBlock groups, Page return; } BytesRefVector quart = ((BytesRefBlock) quartUncast).asVector(); - BytesRef scratch = new BytesRef(); + BytesRef quartScratch = new BytesRef(); for (int groupPosition = 0; groupPosition < groups.getPositionCount(); groupPosition++) { if (groups.isNull(groupPosition)) { continue; @@ -165,7 +165,7 @@ public void addIntermediateInput(int positionOffset, IntArrayBlock groups, Page for (int g = groupStart; g < groupEnd; g++) { int groupId = groups.getInt(g); int valuesPosition = groupPosition + positionOffset; - MedianAbsoluteDeviationDoubleAggregator.combineIntermediate(state, groupId, quart.getBytesRef(valuesPosition, scratch)); + MedianAbsoluteDeviationDoubleAggregator.combineIntermediate(state, groupId, quart.getBytesRef(valuesPosition, quartScratch)); } } } @@ -218,7 +218,7 @@ public void addIntermediateInput(int positionOffset, IntBigArrayBlock groups, Pa return; } BytesRefVector quart = ((BytesRefBlock) quartUncast).asVector(); - BytesRef scratch = new BytesRef(); + BytesRef quartScratch = new BytesRef(); for (int groupPosition = 0; groupPosition < groups.getPositionCount(); groupPosition++) { if (groups.isNull(groupPosition)) { continue; @@ -228,7 +228,7 @@ public void addIntermediateInput(int positionOffset, IntBigArrayBlock groups, Pa for (int g = groupStart; g < groupEnd; g++) { int groupId = groups.getInt(g); int valuesPosition = groupPosition + positionOffset; - MedianAbsoluteDeviationDoubleAggregator.combineIntermediate(state, groupId, quart.getBytesRef(valuesPosition, scratch)); + MedianAbsoluteDeviationDoubleAggregator.combineIntermediate(state, groupId, quart.getBytesRef(valuesPosition, quartScratch)); } } } @@ -267,11 +267,11 @@ public void addIntermediateInput(int positionOffset, IntVector groups, Page page return; } BytesRefVector quart = ((BytesRefBlock) quartUncast).asVector(); - BytesRef scratch = new BytesRef(); + BytesRef quartScratch = new BytesRef(); for (int groupPosition = 0; groupPosition < groups.getPositionCount(); groupPosition++) { int groupId = groups.getInt(groupPosition); int valuesPosition = groupPosition + positionOffset; - MedianAbsoluteDeviationDoubleAggregator.combineIntermediate(state, groupId, quart.getBytesRef(valuesPosition, scratch)); + MedianAbsoluteDeviationDoubleAggregator.combineIntermediate(state, groupId, quart.getBytesRef(valuesPosition, quartScratch)); } } diff --git a/x-pack/plugin/esql/compute/src/main/generated/org/elasticsearch/compute/aggregation/MedianAbsoluteDeviationFloatAggregatorFunction.java b/x-pack/plugin/esql/compute/src/main/generated/org/elasticsearch/compute/aggregation/MedianAbsoluteDeviationFloatAggregatorFunction.java index 7efedf93a8910..27a580e1da6f7 100644 --- a/x-pack/plugin/esql/compute/src/main/generated/org/elasticsearch/compute/aggregation/MedianAbsoluteDeviationFloatAggregatorFunction.java +++ b/x-pack/plugin/esql/compute/src/main/generated/org/elasticsearch/compute/aggregation/MedianAbsoluteDeviationFloatAggregatorFunction.java @@ -146,8 +146,8 @@ public void addIntermediateInput(Page page) { } BytesRefVector quart = ((BytesRefBlock) quartUncast).asVector(); assert quart.getPositionCount() == 1; - BytesRef scratch = new BytesRef(); - MedianAbsoluteDeviationFloatAggregator.combineIntermediate(state, quart.getBytesRef(0, scratch)); + BytesRef quartScratch = new BytesRef(); + MedianAbsoluteDeviationFloatAggregator.combineIntermediate(state, quart.getBytesRef(0, quartScratch)); } @Override diff --git a/x-pack/plugin/esql/compute/src/main/generated/org/elasticsearch/compute/aggregation/MedianAbsoluteDeviationFloatGroupingAggregatorFunction.java b/x-pack/plugin/esql/compute/src/main/generated/org/elasticsearch/compute/aggregation/MedianAbsoluteDeviationFloatGroupingAggregatorFunction.java index c706d6a68b9ad..2f57442e14ea6 100644 --- a/x-pack/plugin/esql/compute/src/main/generated/org/elasticsearch/compute/aggregation/MedianAbsoluteDeviationFloatGroupingAggregatorFunction.java +++ b/x-pack/plugin/esql/compute/src/main/generated/org/elasticsearch/compute/aggregation/MedianAbsoluteDeviationFloatGroupingAggregatorFunction.java @@ -155,7 +155,7 @@ public void addIntermediateInput(int positionOffset, IntArrayBlock groups, Page return; } BytesRefVector quart = ((BytesRefBlock) quartUncast).asVector(); - BytesRef scratch = new BytesRef(); + BytesRef quartScratch = new BytesRef(); for (int groupPosition = 0; groupPosition < groups.getPositionCount(); groupPosition++) { if (groups.isNull(groupPosition)) { continue; @@ -165,7 +165,7 @@ public void addIntermediateInput(int positionOffset, IntArrayBlock groups, Page for (int g = groupStart; g < groupEnd; g++) { int groupId = groups.getInt(g); int valuesPosition = groupPosition + positionOffset; - MedianAbsoluteDeviationFloatAggregator.combineIntermediate(state, groupId, quart.getBytesRef(valuesPosition, scratch)); + MedianAbsoluteDeviationFloatAggregator.combineIntermediate(state, groupId, quart.getBytesRef(valuesPosition, quartScratch)); } } } @@ -218,7 +218,7 @@ public void addIntermediateInput(int positionOffset, IntBigArrayBlock groups, Pa return; } BytesRefVector quart = ((BytesRefBlock) quartUncast).asVector(); - BytesRef scratch = new BytesRef(); + BytesRef quartScratch = new BytesRef(); for (int groupPosition = 0; groupPosition < groups.getPositionCount(); groupPosition++) { if (groups.isNull(groupPosition)) { continue; @@ -228,7 +228,7 @@ public void addIntermediateInput(int positionOffset, IntBigArrayBlock groups, Pa for (int g = groupStart; g < groupEnd; g++) { int groupId = groups.getInt(g); int valuesPosition = groupPosition + positionOffset; - MedianAbsoluteDeviationFloatAggregator.combineIntermediate(state, groupId, quart.getBytesRef(valuesPosition, scratch)); + MedianAbsoluteDeviationFloatAggregator.combineIntermediate(state, groupId, quart.getBytesRef(valuesPosition, quartScratch)); } } } @@ -267,11 +267,11 @@ public void addIntermediateInput(int positionOffset, IntVector groups, Page page return; } BytesRefVector quart = ((BytesRefBlock) quartUncast).asVector(); - BytesRef scratch = new BytesRef(); + BytesRef quartScratch = new BytesRef(); for (int groupPosition = 0; groupPosition < groups.getPositionCount(); groupPosition++) { int groupId = groups.getInt(groupPosition); int valuesPosition = groupPosition + positionOffset; - MedianAbsoluteDeviationFloatAggregator.combineIntermediate(state, groupId, quart.getBytesRef(valuesPosition, scratch)); + MedianAbsoluteDeviationFloatAggregator.combineIntermediate(state, groupId, quart.getBytesRef(valuesPosition, quartScratch)); } } diff --git a/x-pack/plugin/esql/compute/src/main/generated/org/elasticsearch/compute/aggregation/MedianAbsoluteDeviationIntAggregatorFunction.java b/x-pack/plugin/esql/compute/src/main/generated/org/elasticsearch/compute/aggregation/MedianAbsoluteDeviationIntAggregatorFunction.java index 73756681f5c18..68c9d8ce75174 100644 --- a/x-pack/plugin/esql/compute/src/main/generated/org/elasticsearch/compute/aggregation/MedianAbsoluteDeviationIntAggregatorFunction.java +++ b/x-pack/plugin/esql/compute/src/main/generated/org/elasticsearch/compute/aggregation/MedianAbsoluteDeviationIntAggregatorFunction.java @@ -146,8 +146,8 @@ public void addIntermediateInput(Page page) { } BytesRefVector quart = ((BytesRefBlock) quartUncast).asVector(); assert quart.getPositionCount() == 1; - BytesRef scratch = new BytesRef(); - MedianAbsoluteDeviationIntAggregator.combineIntermediate(state, quart.getBytesRef(0, scratch)); + BytesRef quartScratch = new BytesRef(); + MedianAbsoluteDeviationIntAggregator.combineIntermediate(state, quart.getBytesRef(0, quartScratch)); } @Override diff --git a/x-pack/plugin/esql/compute/src/main/generated/org/elasticsearch/compute/aggregation/MedianAbsoluteDeviationIntGroupingAggregatorFunction.java b/x-pack/plugin/esql/compute/src/main/generated/org/elasticsearch/compute/aggregation/MedianAbsoluteDeviationIntGroupingAggregatorFunction.java index 171e4238f68c7..6f6e711157a80 100644 --- a/x-pack/plugin/esql/compute/src/main/generated/org/elasticsearch/compute/aggregation/MedianAbsoluteDeviationIntGroupingAggregatorFunction.java +++ b/x-pack/plugin/esql/compute/src/main/generated/org/elasticsearch/compute/aggregation/MedianAbsoluteDeviationIntGroupingAggregatorFunction.java @@ -154,7 +154,7 @@ public void addIntermediateInput(int positionOffset, IntArrayBlock groups, Page return; } BytesRefVector quart = ((BytesRefBlock) quartUncast).asVector(); - BytesRef scratch = new BytesRef(); + BytesRef quartScratch = new BytesRef(); for (int groupPosition = 0; groupPosition < groups.getPositionCount(); groupPosition++) { if (groups.isNull(groupPosition)) { continue; @@ -164,7 +164,7 @@ public void addIntermediateInput(int positionOffset, IntArrayBlock groups, Page for (int g = groupStart; g < groupEnd; g++) { int groupId = groups.getInt(g); int valuesPosition = groupPosition + positionOffset; - MedianAbsoluteDeviationIntAggregator.combineIntermediate(state, groupId, quart.getBytesRef(valuesPosition, scratch)); + MedianAbsoluteDeviationIntAggregator.combineIntermediate(state, groupId, quart.getBytesRef(valuesPosition, quartScratch)); } } } @@ -217,7 +217,7 @@ public void addIntermediateInput(int positionOffset, IntBigArrayBlock groups, Pa return; } BytesRefVector quart = ((BytesRefBlock) quartUncast).asVector(); - BytesRef scratch = new BytesRef(); + BytesRef quartScratch = new BytesRef(); for (int groupPosition = 0; groupPosition < groups.getPositionCount(); groupPosition++) { if (groups.isNull(groupPosition)) { continue; @@ -227,7 +227,7 @@ public void addIntermediateInput(int positionOffset, IntBigArrayBlock groups, Pa for (int g = groupStart; g < groupEnd; g++) { int groupId = groups.getInt(g); int valuesPosition = groupPosition + positionOffset; - MedianAbsoluteDeviationIntAggregator.combineIntermediate(state, groupId, quart.getBytesRef(valuesPosition, scratch)); + MedianAbsoluteDeviationIntAggregator.combineIntermediate(state, groupId, quart.getBytesRef(valuesPosition, quartScratch)); } } } @@ -266,11 +266,11 @@ public void addIntermediateInput(int positionOffset, IntVector groups, Page page return; } BytesRefVector quart = ((BytesRefBlock) quartUncast).asVector(); - BytesRef scratch = new BytesRef(); + BytesRef quartScratch = new BytesRef(); for (int groupPosition = 0; groupPosition < groups.getPositionCount(); groupPosition++) { int groupId = groups.getInt(groupPosition); int valuesPosition = groupPosition + positionOffset; - MedianAbsoluteDeviationIntAggregator.combineIntermediate(state, groupId, quart.getBytesRef(valuesPosition, scratch)); + MedianAbsoluteDeviationIntAggregator.combineIntermediate(state, groupId, quart.getBytesRef(valuesPosition, quartScratch)); } } diff --git a/x-pack/plugin/esql/compute/src/main/generated/org/elasticsearch/compute/aggregation/MedianAbsoluteDeviationLongAggregatorFunction.java b/x-pack/plugin/esql/compute/src/main/generated/org/elasticsearch/compute/aggregation/MedianAbsoluteDeviationLongAggregatorFunction.java index 4c6afaba77234..8f71e4cc249b9 100644 --- a/x-pack/plugin/esql/compute/src/main/generated/org/elasticsearch/compute/aggregation/MedianAbsoluteDeviationLongAggregatorFunction.java +++ b/x-pack/plugin/esql/compute/src/main/generated/org/elasticsearch/compute/aggregation/MedianAbsoluteDeviationLongAggregatorFunction.java @@ -146,8 +146,8 @@ public void addIntermediateInput(Page page) { } BytesRefVector quart = ((BytesRefBlock) quartUncast).asVector(); assert quart.getPositionCount() == 1; - BytesRef scratch = new BytesRef(); - MedianAbsoluteDeviationLongAggregator.combineIntermediate(state, quart.getBytesRef(0, scratch)); + BytesRef quartScratch = new BytesRef(); + MedianAbsoluteDeviationLongAggregator.combineIntermediate(state, quart.getBytesRef(0, quartScratch)); } @Override diff --git a/x-pack/plugin/esql/compute/src/main/generated/org/elasticsearch/compute/aggregation/MedianAbsoluteDeviationLongGroupingAggregatorFunction.java b/x-pack/plugin/esql/compute/src/main/generated/org/elasticsearch/compute/aggregation/MedianAbsoluteDeviationLongGroupingAggregatorFunction.java index 2136c8d0fd1fd..3a75aa3ba2e73 100644 --- a/x-pack/plugin/esql/compute/src/main/generated/org/elasticsearch/compute/aggregation/MedianAbsoluteDeviationLongGroupingAggregatorFunction.java +++ b/x-pack/plugin/esql/compute/src/main/generated/org/elasticsearch/compute/aggregation/MedianAbsoluteDeviationLongGroupingAggregatorFunction.java @@ -155,7 +155,7 @@ public void addIntermediateInput(int positionOffset, IntArrayBlock groups, Page return; } BytesRefVector quart = ((BytesRefBlock) quartUncast).asVector(); - BytesRef scratch = new BytesRef(); + BytesRef quartScratch = new BytesRef(); for (int groupPosition = 0; groupPosition < groups.getPositionCount(); groupPosition++) { if (groups.isNull(groupPosition)) { continue; @@ -165,7 +165,7 @@ public void addIntermediateInput(int positionOffset, IntArrayBlock groups, Page for (int g = groupStart; g < groupEnd; g++) { int groupId = groups.getInt(g); int valuesPosition = groupPosition + positionOffset; - MedianAbsoluteDeviationLongAggregator.combineIntermediate(state, groupId, quart.getBytesRef(valuesPosition, scratch)); + MedianAbsoluteDeviationLongAggregator.combineIntermediate(state, groupId, quart.getBytesRef(valuesPosition, quartScratch)); } } } @@ -218,7 +218,7 @@ public void addIntermediateInput(int positionOffset, IntBigArrayBlock groups, Pa return; } BytesRefVector quart = ((BytesRefBlock) quartUncast).asVector(); - BytesRef scratch = new BytesRef(); + BytesRef quartScratch = new BytesRef(); for (int groupPosition = 0; groupPosition < groups.getPositionCount(); groupPosition++) { if (groups.isNull(groupPosition)) { continue; @@ -228,7 +228,7 @@ public void addIntermediateInput(int positionOffset, IntBigArrayBlock groups, Pa for (int g = groupStart; g < groupEnd; g++) { int groupId = groups.getInt(g); int valuesPosition = groupPosition + positionOffset; - MedianAbsoluteDeviationLongAggregator.combineIntermediate(state, groupId, quart.getBytesRef(valuesPosition, scratch)); + MedianAbsoluteDeviationLongAggregator.combineIntermediate(state, groupId, quart.getBytesRef(valuesPosition, quartScratch)); } } } @@ -267,11 +267,11 @@ public void addIntermediateInput(int positionOffset, IntVector groups, Page page return; } BytesRefVector quart = ((BytesRefBlock) quartUncast).asVector(); - BytesRef scratch = new BytesRef(); + BytesRef quartScratch = new BytesRef(); for (int groupPosition = 0; groupPosition < groups.getPositionCount(); groupPosition++) { int groupId = groups.getInt(groupPosition); int valuesPosition = groupPosition + positionOffset; - MedianAbsoluteDeviationLongAggregator.combineIntermediate(state, groupId, quart.getBytesRef(valuesPosition, scratch)); + MedianAbsoluteDeviationLongAggregator.combineIntermediate(state, groupId, quart.getBytesRef(valuesPosition, quartScratch)); } } diff --git a/x-pack/plugin/esql/compute/src/main/generated/org/elasticsearch/compute/aggregation/MinBytesRefAggregatorFunction.java b/x-pack/plugin/esql/compute/src/main/generated/org/elasticsearch/compute/aggregation/MinBytesRefAggregatorFunction.java index 92660be1185a0..a7ab1814d670d 100644 --- a/x-pack/plugin/esql/compute/src/main/generated/org/elasticsearch/compute/aggregation/MinBytesRefAggregatorFunction.java +++ b/x-pack/plugin/esql/compute/src/main/generated/org/elasticsearch/compute/aggregation/MinBytesRefAggregatorFunction.java @@ -156,8 +156,8 @@ public void addIntermediateInput(Page page) { } BooleanVector seen = ((BooleanBlock) seenUncast).asVector(); assert seen.getPositionCount() == 1; - BytesRef scratch = new BytesRef(); - MinBytesRefAggregator.combineIntermediate(state, min.getBytesRef(0, scratch), seen.getBoolean(0)); + BytesRef minScratch = new BytesRef(); + MinBytesRefAggregator.combineIntermediate(state, min.getBytesRef(0, minScratch), seen.getBoolean(0)); } @Override diff --git a/x-pack/plugin/esql/compute/src/main/generated/org/elasticsearch/compute/aggregation/MinBytesRefGroupingAggregatorFunction.java b/x-pack/plugin/esql/compute/src/main/generated/org/elasticsearch/compute/aggregation/MinBytesRefGroupingAggregatorFunction.java index e3acfe1ab1943..03e07ad54cb1f 100644 --- a/x-pack/plugin/esql/compute/src/main/generated/org/elasticsearch/compute/aggregation/MinBytesRefGroupingAggregatorFunction.java +++ b/x-pack/plugin/esql/compute/src/main/generated/org/elasticsearch/compute/aggregation/MinBytesRefGroupingAggregatorFunction.java @@ -164,7 +164,7 @@ public void addIntermediateInput(int positionOffset, IntArrayBlock groups, Page } BooleanVector seen = ((BooleanBlock) seenUncast).asVector(); assert min.getPositionCount() == seen.getPositionCount(); - BytesRef scratch = new BytesRef(); + BytesRef minScratch = new BytesRef(); for (int groupPosition = 0; groupPosition < groups.getPositionCount(); groupPosition++) { if (groups.isNull(groupPosition)) { continue; @@ -174,7 +174,7 @@ public void addIntermediateInput(int positionOffset, IntArrayBlock groups, Page for (int g = groupStart; g < groupEnd; g++) { int groupId = groups.getInt(g); int valuesPosition = groupPosition + positionOffset; - MinBytesRefAggregator.combineIntermediate(state, groupId, min.getBytesRef(valuesPosition, scratch), seen.getBoolean(valuesPosition)); + MinBytesRefAggregator.combineIntermediate(state, groupId, min.getBytesRef(valuesPosition, minScratch), seen.getBoolean(valuesPosition)); } } } @@ -236,7 +236,7 @@ public void addIntermediateInput(int positionOffset, IntBigArrayBlock groups, Pa } BooleanVector seen = ((BooleanBlock) seenUncast).asVector(); assert min.getPositionCount() == seen.getPositionCount(); - BytesRef scratch = new BytesRef(); + BytesRef minScratch = new BytesRef(); for (int groupPosition = 0; groupPosition < groups.getPositionCount(); groupPosition++) { if (groups.isNull(groupPosition)) { continue; @@ -246,7 +246,7 @@ public void addIntermediateInput(int positionOffset, IntBigArrayBlock groups, Pa for (int g = groupStart; g < groupEnd; g++) { int groupId = groups.getInt(g); int valuesPosition = groupPosition + positionOffset; - MinBytesRefAggregator.combineIntermediate(state, groupId, min.getBytesRef(valuesPosition, scratch), seen.getBoolean(valuesPosition)); + MinBytesRefAggregator.combineIntermediate(state, groupId, min.getBytesRef(valuesPosition, minScratch), seen.getBoolean(valuesPosition)); } } } @@ -293,11 +293,11 @@ public void addIntermediateInput(int positionOffset, IntVector groups, Page page } BooleanVector seen = ((BooleanBlock) seenUncast).asVector(); assert min.getPositionCount() == seen.getPositionCount(); - BytesRef scratch = new BytesRef(); + BytesRef minScratch = new BytesRef(); for (int groupPosition = 0; groupPosition < groups.getPositionCount(); groupPosition++) { int groupId = groups.getInt(groupPosition); int valuesPosition = groupPosition + positionOffset; - MinBytesRefAggregator.combineIntermediate(state, groupId, min.getBytesRef(valuesPosition, scratch), seen.getBoolean(valuesPosition)); + MinBytesRefAggregator.combineIntermediate(state, groupId, min.getBytesRef(valuesPosition, minScratch), seen.getBoolean(valuesPosition)); } } diff --git a/x-pack/plugin/esql/compute/src/main/generated/org/elasticsearch/compute/aggregation/MinIpAggregatorFunction.java b/x-pack/plugin/esql/compute/src/main/generated/org/elasticsearch/compute/aggregation/MinIpAggregatorFunction.java index db61c405d440e..61898ca139071 100644 --- a/x-pack/plugin/esql/compute/src/main/generated/org/elasticsearch/compute/aggregation/MinIpAggregatorFunction.java +++ b/x-pack/plugin/esql/compute/src/main/generated/org/elasticsearch/compute/aggregation/MinIpAggregatorFunction.java @@ -156,8 +156,8 @@ public void addIntermediateInput(Page page) { } BooleanVector seen = ((BooleanBlock) seenUncast).asVector(); assert seen.getPositionCount() == 1; - BytesRef scratch = new BytesRef(); - MinIpAggregator.combineIntermediate(state, max.getBytesRef(0, scratch), seen.getBoolean(0)); + BytesRef maxScratch = new BytesRef(); + MinIpAggregator.combineIntermediate(state, max.getBytesRef(0, maxScratch), seen.getBoolean(0)); } @Override diff --git a/x-pack/plugin/esql/compute/src/main/generated/org/elasticsearch/compute/aggregation/MinIpGroupingAggregatorFunction.java b/x-pack/plugin/esql/compute/src/main/generated/org/elasticsearch/compute/aggregation/MinIpGroupingAggregatorFunction.java index 69b3c227a2dab..ea678434b7dbb 100644 --- a/x-pack/plugin/esql/compute/src/main/generated/org/elasticsearch/compute/aggregation/MinIpGroupingAggregatorFunction.java +++ b/x-pack/plugin/esql/compute/src/main/generated/org/elasticsearch/compute/aggregation/MinIpGroupingAggregatorFunction.java @@ -164,7 +164,7 @@ public void addIntermediateInput(int positionOffset, IntArrayBlock groups, Page } BooleanVector seen = ((BooleanBlock) seenUncast).asVector(); assert max.getPositionCount() == seen.getPositionCount(); - BytesRef scratch = new BytesRef(); + BytesRef maxScratch = new BytesRef(); for (int groupPosition = 0; groupPosition < groups.getPositionCount(); groupPosition++) { if (groups.isNull(groupPosition)) { continue; @@ -174,7 +174,7 @@ public void addIntermediateInput(int positionOffset, IntArrayBlock groups, Page for (int g = groupStart; g < groupEnd; g++) { int groupId = groups.getInt(g); int valuesPosition = groupPosition + positionOffset; - MinIpAggregator.combineIntermediate(state, groupId, max.getBytesRef(valuesPosition, scratch), seen.getBoolean(valuesPosition)); + MinIpAggregator.combineIntermediate(state, groupId, max.getBytesRef(valuesPosition, maxScratch), seen.getBoolean(valuesPosition)); } } } @@ -236,7 +236,7 @@ public void addIntermediateInput(int positionOffset, IntBigArrayBlock groups, Pa } BooleanVector seen = ((BooleanBlock) seenUncast).asVector(); assert max.getPositionCount() == seen.getPositionCount(); - BytesRef scratch = new BytesRef(); + BytesRef maxScratch = new BytesRef(); for (int groupPosition = 0; groupPosition < groups.getPositionCount(); groupPosition++) { if (groups.isNull(groupPosition)) { continue; @@ -246,7 +246,7 @@ public void addIntermediateInput(int positionOffset, IntBigArrayBlock groups, Pa for (int g = groupStart; g < groupEnd; g++) { int groupId = groups.getInt(g); int valuesPosition = groupPosition + positionOffset; - MinIpAggregator.combineIntermediate(state, groupId, max.getBytesRef(valuesPosition, scratch), seen.getBoolean(valuesPosition)); + MinIpAggregator.combineIntermediate(state, groupId, max.getBytesRef(valuesPosition, maxScratch), seen.getBoolean(valuesPosition)); } } } @@ -293,11 +293,11 @@ public void addIntermediateInput(int positionOffset, IntVector groups, Page page } BooleanVector seen = ((BooleanBlock) seenUncast).asVector(); assert max.getPositionCount() == seen.getPositionCount(); - BytesRef scratch = new BytesRef(); + BytesRef maxScratch = new BytesRef(); for (int groupPosition = 0; groupPosition < groups.getPositionCount(); groupPosition++) { int groupId = groups.getInt(groupPosition); int valuesPosition = groupPosition + positionOffset; - MinIpAggregator.combineIntermediate(state, groupId, max.getBytesRef(valuesPosition, scratch), seen.getBoolean(valuesPosition)); + MinIpAggregator.combineIntermediate(state, groupId, max.getBytesRef(valuesPosition, maxScratch), seen.getBoolean(valuesPosition)); } } diff --git a/x-pack/plugin/esql/compute/src/main/generated/org/elasticsearch/compute/aggregation/PercentileDoubleAggregatorFunction.java b/x-pack/plugin/esql/compute/src/main/generated/org/elasticsearch/compute/aggregation/PercentileDoubleAggregatorFunction.java index 7ae73ed7e1eb9..48a54247588d3 100644 --- a/x-pack/plugin/esql/compute/src/main/generated/org/elasticsearch/compute/aggregation/PercentileDoubleAggregatorFunction.java +++ b/x-pack/plugin/esql/compute/src/main/generated/org/elasticsearch/compute/aggregation/PercentileDoubleAggregatorFunction.java @@ -149,8 +149,8 @@ public void addIntermediateInput(Page page) { } BytesRefVector quart = ((BytesRefBlock) quartUncast).asVector(); assert quart.getPositionCount() == 1; - BytesRef scratch = new BytesRef(); - PercentileDoubleAggregator.combineIntermediate(state, quart.getBytesRef(0, scratch)); + BytesRef quartScratch = new BytesRef(); + PercentileDoubleAggregator.combineIntermediate(state, quart.getBytesRef(0, quartScratch)); } @Override diff --git a/x-pack/plugin/esql/compute/src/main/generated/org/elasticsearch/compute/aggregation/PercentileDoubleGroupingAggregatorFunction.java b/x-pack/plugin/esql/compute/src/main/generated/org/elasticsearch/compute/aggregation/PercentileDoubleGroupingAggregatorFunction.java index f726423df4d4d..81e2d2189e133 100644 --- a/x-pack/plugin/esql/compute/src/main/generated/org/elasticsearch/compute/aggregation/PercentileDoubleGroupingAggregatorFunction.java +++ b/x-pack/plugin/esql/compute/src/main/generated/org/elasticsearch/compute/aggregation/PercentileDoubleGroupingAggregatorFunction.java @@ -158,7 +158,7 @@ public void addIntermediateInput(int positionOffset, IntArrayBlock groups, Page return; } BytesRefVector quart = ((BytesRefBlock) quartUncast).asVector(); - BytesRef scratch = new BytesRef(); + BytesRef quartScratch = new BytesRef(); for (int groupPosition = 0; groupPosition < groups.getPositionCount(); groupPosition++) { if (groups.isNull(groupPosition)) { continue; @@ -168,7 +168,7 @@ public void addIntermediateInput(int positionOffset, IntArrayBlock groups, Page for (int g = groupStart; g < groupEnd; g++) { int groupId = groups.getInt(g); int valuesPosition = groupPosition + positionOffset; - PercentileDoubleAggregator.combineIntermediate(state, groupId, quart.getBytesRef(valuesPosition, scratch)); + PercentileDoubleAggregator.combineIntermediate(state, groupId, quart.getBytesRef(valuesPosition, quartScratch)); } } } @@ -221,7 +221,7 @@ public void addIntermediateInput(int positionOffset, IntBigArrayBlock groups, Pa return; } BytesRefVector quart = ((BytesRefBlock) quartUncast).asVector(); - BytesRef scratch = new BytesRef(); + BytesRef quartScratch = new BytesRef(); for (int groupPosition = 0; groupPosition < groups.getPositionCount(); groupPosition++) { if (groups.isNull(groupPosition)) { continue; @@ -231,7 +231,7 @@ public void addIntermediateInput(int positionOffset, IntBigArrayBlock groups, Pa for (int g = groupStart; g < groupEnd; g++) { int groupId = groups.getInt(g); int valuesPosition = groupPosition + positionOffset; - PercentileDoubleAggregator.combineIntermediate(state, groupId, quart.getBytesRef(valuesPosition, scratch)); + PercentileDoubleAggregator.combineIntermediate(state, groupId, quart.getBytesRef(valuesPosition, quartScratch)); } } } @@ -270,11 +270,11 @@ public void addIntermediateInput(int positionOffset, IntVector groups, Page page return; } BytesRefVector quart = ((BytesRefBlock) quartUncast).asVector(); - BytesRef scratch = new BytesRef(); + BytesRef quartScratch = new BytesRef(); for (int groupPosition = 0; groupPosition < groups.getPositionCount(); groupPosition++) { int groupId = groups.getInt(groupPosition); int valuesPosition = groupPosition + positionOffset; - PercentileDoubleAggregator.combineIntermediate(state, groupId, quart.getBytesRef(valuesPosition, scratch)); + PercentileDoubleAggregator.combineIntermediate(state, groupId, quart.getBytesRef(valuesPosition, quartScratch)); } } diff --git a/x-pack/plugin/esql/compute/src/main/generated/org/elasticsearch/compute/aggregation/PercentileFloatAggregatorFunction.java b/x-pack/plugin/esql/compute/src/main/generated/org/elasticsearch/compute/aggregation/PercentileFloatAggregatorFunction.java index 29acca005738d..5b172e43a7cfe 100644 --- a/x-pack/plugin/esql/compute/src/main/generated/org/elasticsearch/compute/aggregation/PercentileFloatAggregatorFunction.java +++ b/x-pack/plugin/esql/compute/src/main/generated/org/elasticsearch/compute/aggregation/PercentileFloatAggregatorFunction.java @@ -149,8 +149,8 @@ public void addIntermediateInput(Page page) { } BytesRefVector quart = ((BytesRefBlock) quartUncast).asVector(); assert quart.getPositionCount() == 1; - BytesRef scratch = new BytesRef(); - PercentileFloatAggregator.combineIntermediate(state, quart.getBytesRef(0, scratch)); + BytesRef quartScratch = new BytesRef(); + PercentileFloatAggregator.combineIntermediate(state, quart.getBytesRef(0, quartScratch)); } @Override diff --git a/x-pack/plugin/esql/compute/src/main/generated/org/elasticsearch/compute/aggregation/PercentileFloatGroupingAggregatorFunction.java b/x-pack/plugin/esql/compute/src/main/generated/org/elasticsearch/compute/aggregation/PercentileFloatGroupingAggregatorFunction.java index b5be9cc7655bd..c5cf407d86dc0 100644 --- a/x-pack/plugin/esql/compute/src/main/generated/org/elasticsearch/compute/aggregation/PercentileFloatGroupingAggregatorFunction.java +++ b/x-pack/plugin/esql/compute/src/main/generated/org/elasticsearch/compute/aggregation/PercentileFloatGroupingAggregatorFunction.java @@ -158,7 +158,7 @@ public void addIntermediateInput(int positionOffset, IntArrayBlock groups, Page return; } BytesRefVector quart = ((BytesRefBlock) quartUncast).asVector(); - BytesRef scratch = new BytesRef(); + BytesRef quartScratch = new BytesRef(); for (int groupPosition = 0; groupPosition < groups.getPositionCount(); groupPosition++) { if (groups.isNull(groupPosition)) { continue; @@ -168,7 +168,7 @@ public void addIntermediateInput(int positionOffset, IntArrayBlock groups, Page for (int g = groupStart; g < groupEnd; g++) { int groupId = groups.getInt(g); int valuesPosition = groupPosition + positionOffset; - PercentileFloatAggregator.combineIntermediate(state, groupId, quart.getBytesRef(valuesPosition, scratch)); + PercentileFloatAggregator.combineIntermediate(state, groupId, quart.getBytesRef(valuesPosition, quartScratch)); } } } @@ -221,7 +221,7 @@ public void addIntermediateInput(int positionOffset, IntBigArrayBlock groups, Pa return; } BytesRefVector quart = ((BytesRefBlock) quartUncast).asVector(); - BytesRef scratch = new BytesRef(); + BytesRef quartScratch = new BytesRef(); for (int groupPosition = 0; groupPosition < groups.getPositionCount(); groupPosition++) { if (groups.isNull(groupPosition)) { continue; @@ -231,7 +231,7 @@ public void addIntermediateInput(int positionOffset, IntBigArrayBlock groups, Pa for (int g = groupStart; g < groupEnd; g++) { int groupId = groups.getInt(g); int valuesPosition = groupPosition + positionOffset; - PercentileFloatAggregator.combineIntermediate(state, groupId, quart.getBytesRef(valuesPosition, scratch)); + PercentileFloatAggregator.combineIntermediate(state, groupId, quart.getBytesRef(valuesPosition, quartScratch)); } } } @@ -270,11 +270,11 @@ public void addIntermediateInput(int positionOffset, IntVector groups, Page page return; } BytesRefVector quart = ((BytesRefBlock) quartUncast).asVector(); - BytesRef scratch = new BytesRef(); + BytesRef quartScratch = new BytesRef(); for (int groupPosition = 0; groupPosition < groups.getPositionCount(); groupPosition++) { int groupId = groups.getInt(groupPosition); int valuesPosition = groupPosition + positionOffset; - PercentileFloatAggregator.combineIntermediate(state, groupId, quart.getBytesRef(valuesPosition, scratch)); + PercentileFloatAggregator.combineIntermediate(state, groupId, quart.getBytesRef(valuesPosition, quartScratch)); } } diff --git a/x-pack/plugin/esql/compute/src/main/generated/org/elasticsearch/compute/aggregation/PercentileIntAggregatorFunction.java b/x-pack/plugin/esql/compute/src/main/generated/org/elasticsearch/compute/aggregation/PercentileIntAggregatorFunction.java index 21784c215f3f6..081120592aebd 100644 --- a/x-pack/plugin/esql/compute/src/main/generated/org/elasticsearch/compute/aggregation/PercentileIntAggregatorFunction.java +++ b/x-pack/plugin/esql/compute/src/main/generated/org/elasticsearch/compute/aggregation/PercentileIntAggregatorFunction.java @@ -149,8 +149,8 @@ public void addIntermediateInput(Page page) { } BytesRefVector quart = ((BytesRefBlock) quartUncast).asVector(); assert quart.getPositionCount() == 1; - BytesRef scratch = new BytesRef(); - PercentileIntAggregator.combineIntermediate(state, quart.getBytesRef(0, scratch)); + BytesRef quartScratch = new BytesRef(); + PercentileIntAggregator.combineIntermediate(state, quart.getBytesRef(0, quartScratch)); } @Override diff --git a/x-pack/plugin/esql/compute/src/main/generated/org/elasticsearch/compute/aggregation/PercentileIntGroupingAggregatorFunction.java b/x-pack/plugin/esql/compute/src/main/generated/org/elasticsearch/compute/aggregation/PercentileIntGroupingAggregatorFunction.java index c94cc37109e4e..a278b28d1d317 100644 --- a/x-pack/plugin/esql/compute/src/main/generated/org/elasticsearch/compute/aggregation/PercentileIntGroupingAggregatorFunction.java +++ b/x-pack/plugin/esql/compute/src/main/generated/org/elasticsearch/compute/aggregation/PercentileIntGroupingAggregatorFunction.java @@ -157,7 +157,7 @@ public void addIntermediateInput(int positionOffset, IntArrayBlock groups, Page return; } BytesRefVector quart = ((BytesRefBlock) quartUncast).asVector(); - BytesRef scratch = new BytesRef(); + BytesRef quartScratch = new BytesRef(); for (int groupPosition = 0; groupPosition < groups.getPositionCount(); groupPosition++) { if (groups.isNull(groupPosition)) { continue; @@ -167,7 +167,7 @@ public void addIntermediateInput(int positionOffset, IntArrayBlock groups, Page for (int g = groupStart; g < groupEnd; g++) { int groupId = groups.getInt(g); int valuesPosition = groupPosition + positionOffset; - PercentileIntAggregator.combineIntermediate(state, groupId, quart.getBytesRef(valuesPosition, scratch)); + PercentileIntAggregator.combineIntermediate(state, groupId, quart.getBytesRef(valuesPosition, quartScratch)); } } } @@ -220,7 +220,7 @@ public void addIntermediateInput(int positionOffset, IntBigArrayBlock groups, Pa return; } BytesRefVector quart = ((BytesRefBlock) quartUncast).asVector(); - BytesRef scratch = new BytesRef(); + BytesRef quartScratch = new BytesRef(); for (int groupPosition = 0; groupPosition < groups.getPositionCount(); groupPosition++) { if (groups.isNull(groupPosition)) { continue; @@ -230,7 +230,7 @@ public void addIntermediateInput(int positionOffset, IntBigArrayBlock groups, Pa for (int g = groupStart; g < groupEnd; g++) { int groupId = groups.getInt(g); int valuesPosition = groupPosition + positionOffset; - PercentileIntAggregator.combineIntermediate(state, groupId, quart.getBytesRef(valuesPosition, scratch)); + PercentileIntAggregator.combineIntermediate(state, groupId, quart.getBytesRef(valuesPosition, quartScratch)); } } } @@ -269,11 +269,11 @@ public void addIntermediateInput(int positionOffset, IntVector groups, Page page return; } BytesRefVector quart = ((BytesRefBlock) quartUncast).asVector(); - BytesRef scratch = new BytesRef(); + BytesRef quartScratch = new BytesRef(); for (int groupPosition = 0; groupPosition < groups.getPositionCount(); groupPosition++) { int groupId = groups.getInt(groupPosition); int valuesPosition = groupPosition + positionOffset; - PercentileIntAggregator.combineIntermediate(state, groupId, quart.getBytesRef(valuesPosition, scratch)); + PercentileIntAggregator.combineIntermediate(state, groupId, quart.getBytesRef(valuesPosition, quartScratch)); } } diff --git a/x-pack/plugin/esql/compute/src/main/generated/org/elasticsearch/compute/aggregation/PercentileLongAggregatorFunction.java b/x-pack/plugin/esql/compute/src/main/generated/org/elasticsearch/compute/aggregation/PercentileLongAggregatorFunction.java index df49223605ec2..6d81e228ca662 100644 --- a/x-pack/plugin/esql/compute/src/main/generated/org/elasticsearch/compute/aggregation/PercentileLongAggregatorFunction.java +++ b/x-pack/plugin/esql/compute/src/main/generated/org/elasticsearch/compute/aggregation/PercentileLongAggregatorFunction.java @@ -149,8 +149,8 @@ public void addIntermediateInput(Page page) { } BytesRefVector quart = ((BytesRefBlock) quartUncast).asVector(); assert quart.getPositionCount() == 1; - BytesRef scratch = new BytesRef(); - PercentileLongAggregator.combineIntermediate(state, quart.getBytesRef(0, scratch)); + BytesRef quartScratch = new BytesRef(); + PercentileLongAggregator.combineIntermediate(state, quart.getBytesRef(0, quartScratch)); } @Override diff --git a/x-pack/plugin/esql/compute/src/main/generated/org/elasticsearch/compute/aggregation/PercentileLongGroupingAggregatorFunction.java b/x-pack/plugin/esql/compute/src/main/generated/org/elasticsearch/compute/aggregation/PercentileLongGroupingAggregatorFunction.java index d48770a77abf2..2f22604be77c4 100644 --- a/x-pack/plugin/esql/compute/src/main/generated/org/elasticsearch/compute/aggregation/PercentileLongGroupingAggregatorFunction.java +++ b/x-pack/plugin/esql/compute/src/main/generated/org/elasticsearch/compute/aggregation/PercentileLongGroupingAggregatorFunction.java @@ -158,7 +158,7 @@ public void addIntermediateInput(int positionOffset, IntArrayBlock groups, Page return; } BytesRefVector quart = ((BytesRefBlock) quartUncast).asVector(); - BytesRef scratch = new BytesRef(); + BytesRef quartScratch = new BytesRef(); for (int groupPosition = 0; groupPosition < groups.getPositionCount(); groupPosition++) { if (groups.isNull(groupPosition)) { continue; @@ -168,7 +168,7 @@ public void addIntermediateInput(int positionOffset, IntArrayBlock groups, Page for (int g = groupStart; g < groupEnd; g++) { int groupId = groups.getInt(g); int valuesPosition = groupPosition + positionOffset; - PercentileLongAggregator.combineIntermediate(state, groupId, quart.getBytesRef(valuesPosition, scratch)); + PercentileLongAggregator.combineIntermediate(state, groupId, quart.getBytesRef(valuesPosition, quartScratch)); } } } @@ -221,7 +221,7 @@ public void addIntermediateInput(int positionOffset, IntBigArrayBlock groups, Pa return; } BytesRefVector quart = ((BytesRefBlock) quartUncast).asVector(); - BytesRef scratch = new BytesRef(); + BytesRef quartScratch = new BytesRef(); for (int groupPosition = 0; groupPosition < groups.getPositionCount(); groupPosition++) { if (groups.isNull(groupPosition)) { continue; @@ -231,7 +231,7 @@ public void addIntermediateInput(int positionOffset, IntBigArrayBlock groups, Pa for (int g = groupStart; g < groupEnd; g++) { int groupId = groups.getInt(g); int valuesPosition = groupPosition + positionOffset; - PercentileLongAggregator.combineIntermediate(state, groupId, quart.getBytesRef(valuesPosition, scratch)); + PercentileLongAggregator.combineIntermediate(state, groupId, quart.getBytesRef(valuesPosition, quartScratch)); } } } @@ -270,11 +270,11 @@ public void addIntermediateInput(int positionOffset, IntVector groups, Page page return; } BytesRefVector quart = ((BytesRefBlock) quartUncast).asVector(); - BytesRef scratch = new BytesRef(); + BytesRef quartScratch = new BytesRef(); for (int groupPosition = 0; groupPosition < groups.getPositionCount(); groupPosition++) { int groupId = groups.getInt(groupPosition); int valuesPosition = groupPosition + positionOffset; - PercentileLongAggregator.combineIntermediate(state, groupId, quart.getBytesRef(valuesPosition, scratch)); + PercentileLongAggregator.combineIntermediate(state, groupId, quart.getBytesRef(valuesPosition, quartScratch)); } } diff --git a/x-pack/plugin/esql/compute/src/main/generated/org/elasticsearch/compute/aggregation/SampleBooleanAggregatorFunction.java b/x-pack/plugin/esql/compute/src/main/generated/org/elasticsearch/compute/aggregation/SampleBooleanAggregatorFunction.java index a5cfcbb1e03e2..9ce0bffb4e642 100644 --- a/x-pack/plugin/esql/compute/src/main/generated/org/elasticsearch/compute/aggregation/SampleBooleanAggregatorFunction.java +++ b/x-pack/plugin/esql/compute/src/main/generated/org/elasticsearch/compute/aggregation/SampleBooleanAggregatorFunction.java @@ -147,7 +147,7 @@ public void addIntermediateInput(Page page) { } BytesRefBlock sample = (BytesRefBlock) sampleUncast; assert sample.getPositionCount() == 1; - BytesRef scratch = new BytesRef(); + BytesRef sampleScratch = new BytesRef(); SampleBooleanAggregator.combineIntermediate(state, sample); } diff --git a/x-pack/plugin/esql/compute/src/main/generated/org/elasticsearch/compute/aggregation/SampleBooleanGroupingAggregatorFunction.java b/x-pack/plugin/esql/compute/src/main/generated/org/elasticsearch/compute/aggregation/SampleBooleanGroupingAggregatorFunction.java index c675030a16bf2..c2d86ef1a9e54 100644 --- a/x-pack/plugin/esql/compute/src/main/generated/org/elasticsearch/compute/aggregation/SampleBooleanGroupingAggregatorFunction.java +++ b/x-pack/plugin/esql/compute/src/main/generated/org/elasticsearch/compute/aggregation/SampleBooleanGroupingAggregatorFunction.java @@ -157,7 +157,7 @@ public void addIntermediateInput(int positionOffset, IntArrayBlock groups, Page return; } BytesRefBlock sample = (BytesRefBlock) sampleUncast; - BytesRef scratch = new BytesRef(); + BytesRef sampleScratch = new BytesRef(); for (int groupPosition = 0; groupPosition < groups.getPositionCount(); groupPosition++) { if (groups.isNull(groupPosition)) { continue; @@ -220,7 +220,7 @@ public void addIntermediateInput(int positionOffset, IntBigArrayBlock groups, Pa return; } BytesRefBlock sample = (BytesRefBlock) sampleUncast; - BytesRef scratch = new BytesRef(); + BytesRef sampleScratch = new BytesRef(); for (int groupPosition = 0; groupPosition < groups.getPositionCount(); groupPosition++) { if (groups.isNull(groupPosition)) { continue; @@ -269,7 +269,7 @@ public void addIntermediateInput(int positionOffset, IntVector groups, Page page return; } BytesRefBlock sample = (BytesRefBlock) sampleUncast; - BytesRef scratch = new BytesRef(); + BytesRef sampleScratch = new BytesRef(); for (int groupPosition = 0; groupPosition < groups.getPositionCount(); groupPosition++) { int groupId = groups.getInt(groupPosition); int valuesPosition = groupPosition + positionOffset; diff --git a/x-pack/plugin/esql/compute/src/main/generated/org/elasticsearch/compute/aggregation/SampleBytesRefAggregatorFunction.java b/x-pack/plugin/esql/compute/src/main/generated/org/elasticsearch/compute/aggregation/SampleBytesRefAggregatorFunction.java index 45e55a2f9a5a3..dc3af45e9bec2 100644 --- a/x-pack/plugin/esql/compute/src/main/generated/org/elasticsearch/compute/aggregation/SampleBytesRefAggregatorFunction.java +++ b/x-pack/plugin/esql/compute/src/main/generated/org/elasticsearch/compute/aggregation/SampleBytesRefAggregatorFunction.java @@ -151,7 +151,7 @@ public void addIntermediateInput(Page page) { } BytesRefBlock sample = (BytesRefBlock) sampleUncast; assert sample.getPositionCount() == 1; - BytesRef scratch = new BytesRef(); + BytesRef sampleScratch = new BytesRef(); SampleBytesRefAggregator.combineIntermediate(state, sample); } diff --git a/x-pack/plugin/esql/compute/src/main/generated/org/elasticsearch/compute/aggregation/SampleBytesRefGroupingAggregatorFunction.java b/x-pack/plugin/esql/compute/src/main/generated/org/elasticsearch/compute/aggregation/SampleBytesRefGroupingAggregatorFunction.java index db0d675499c44..ae911a74c4ca4 100644 --- a/x-pack/plugin/esql/compute/src/main/generated/org/elasticsearch/compute/aggregation/SampleBytesRefGroupingAggregatorFunction.java +++ b/x-pack/plugin/esql/compute/src/main/generated/org/elasticsearch/compute/aggregation/SampleBytesRefGroupingAggregatorFunction.java @@ -158,7 +158,7 @@ public void addIntermediateInput(int positionOffset, IntArrayBlock groups, Page return; } BytesRefBlock sample = (BytesRefBlock) sampleUncast; - BytesRef scratch = new BytesRef(); + BytesRef sampleScratch = new BytesRef(); for (int groupPosition = 0; groupPosition < groups.getPositionCount(); groupPosition++) { if (groups.isNull(groupPosition)) { continue; @@ -224,7 +224,7 @@ public void addIntermediateInput(int positionOffset, IntBigArrayBlock groups, Pa return; } BytesRefBlock sample = (BytesRefBlock) sampleUncast; - BytesRef scratch = new BytesRef(); + BytesRef sampleScratch = new BytesRef(); for (int groupPosition = 0; groupPosition < groups.getPositionCount(); groupPosition++) { if (groups.isNull(groupPosition)) { continue; @@ -275,7 +275,7 @@ public void addIntermediateInput(int positionOffset, IntVector groups, Page page return; } BytesRefBlock sample = (BytesRefBlock) sampleUncast; - BytesRef scratch = new BytesRef(); + BytesRef sampleScratch = new BytesRef(); for (int groupPosition = 0; groupPosition < groups.getPositionCount(); groupPosition++) { int groupId = groups.getInt(groupPosition); int valuesPosition = groupPosition + positionOffset; diff --git a/x-pack/plugin/esql/compute/src/main/generated/org/elasticsearch/compute/aggregation/SampleDoubleAggregatorFunction.java b/x-pack/plugin/esql/compute/src/main/generated/org/elasticsearch/compute/aggregation/SampleDoubleAggregatorFunction.java index fc5681e427572..e63c9fe414ce7 100644 --- a/x-pack/plugin/esql/compute/src/main/generated/org/elasticsearch/compute/aggregation/SampleDoubleAggregatorFunction.java +++ b/x-pack/plugin/esql/compute/src/main/generated/org/elasticsearch/compute/aggregation/SampleDoubleAggregatorFunction.java @@ -148,7 +148,7 @@ public void addIntermediateInput(Page page) { } BytesRefBlock sample = (BytesRefBlock) sampleUncast; assert sample.getPositionCount() == 1; - BytesRef scratch = new BytesRef(); + BytesRef sampleScratch = new BytesRef(); SampleDoubleAggregator.combineIntermediate(state, sample); } diff --git a/x-pack/plugin/esql/compute/src/main/generated/org/elasticsearch/compute/aggregation/SampleDoubleGroupingAggregatorFunction.java b/x-pack/plugin/esql/compute/src/main/generated/org/elasticsearch/compute/aggregation/SampleDoubleGroupingAggregatorFunction.java index b81c56db60297..f62100ee2e0ec 100644 --- a/x-pack/plugin/esql/compute/src/main/generated/org/elasticsearch/compute/aggregation/SampleDoubleGroupingAggregatorFunction.java +++ b/x-pack/plugin/esql/compute/src/main/generated/org/elasticsearch/compute/aggregation/SampleDoubleGroupingAggregatorFunction.java @@ -157,7 +157,7 @@ public void addIntermediateInput(int positionOffset, IntArrayBlock groups, Page return; } BytesRefBlock sample = (BytesRefBlock) sampleUncast; - BytesRef scratch = new BytesRef(); + BytesRef sampleScratch = new BytesRef(); for (int groupPosition = 0; groupPosition < groups.getPositionCount(); groupPosition++) { if (groups.isNull(groupPosition)) { continue; @@ -220,7 +220,7 @@ public void addIntermediateInput(int positionOffset, IntBigArrayBlock groups, Pa return; } BytesRefBlock sample = (BytesRefBlock) sampleUncast; - BytesRef scratch = new BytesRef(); + BytesRef sampleScratch = new BytesRef(); for (int groupPosition = 0; groupPosition < groups.getPositionCount(); groupPosition++) { if (groups.isNull(groupPosition)) { continue; @@ -269,7 +269,7 @@ public void addIntermediateInput(int positionOffset, IntVector groups, Page page return; } BytesRefBlock sample = (BytesRefBlock) sampleUncast; - BytesRef scratch = new BytesRef(); + BytesRef sampleScratch = new BytesRef(); for (int groupPosition = 0; groupPosition < groups.getPositionCount(); groupPosition++) { int groupId = groups.getInt(groupPosition); int valuesPosition = groupPosition + positionOffset; diff --git a/x-pack/plugin/esql/compute/src/main/generated/org/elasticsearch/compute/aggregation/SampleIntAggregatorFunction.java b/x-pack/plugin/esql/compute/src/main/generated/org/elasticsearch/compute/aggregation/SampleIntAggregatorFunction.java index 232a664854401..b4035708a567b 100644 --- a/x-pack/plugin/esql/compute/src/main/generated/org/elasticsearch/compute/aggregation/SampleIntAggregatorFunction.java +++ b/x-pack/plugin/esql/compute/src/main/generated/org/elasticsearch/compute/aggregation/SampleIntAggregatorFunction.java @@ -148,7 +148,7 @@ public void addIntermediateInput(Page page) { } BytesRefBlock sample = (BytesRefBlock) sampleUncast; assert sample.getPositionCount() == 1; - BytesRef scratch = new BytesRef(); + BytesRef sampleScratch = new BytesRef(); SampleIntAggregator.combineIntermediate(state, sample); } diff --git a/x-pack/plugin/esql/compute/src/main/generated/org/elasticsearch/compute/aggregation/SampleIntGroupingAggregatorFunction.java b/x-pack/plugin/esql/compute/src/main/generated/org/elasticsearch/compute/aggregation/SampleIntGroupingAggregatorFunction.java index 41f2f7a608e8e..199676fa2fd2d 100644 --- a/x-pack/plugin/esql/compute/src/main/generated/org/elasticsearch/compute/aggregation/SampleIntGroupingAggregatorFunction.java +++ b/x-pack/plugin/esql/compute/src/main/generated/org/elasticsearch/compute/aggregation/SampleIntGroupingAggregatorFunction.java @@ -156,7 +156,7 @@ public void addIntermediateInput(int positionOffset, IntArrayBlock groups, Page return; } BytesRefBlock sample = (BytesRefBlock) sampleUncast; - BytesRef scratch = new BytesRef(); + BytesRef sampleScratch = new BytesRef(); for (int groupPosition = 0; groupPosition < groups.getPositionCount(); groupPosition++) { if (groups.isNull(groupPosition)) { continue; @@ -219,7 +219,7 @@ public void addIntermediateInput(int positionOffset, IntBigArrayBlock groups, Pa return; } BytesRefBlock sample = (BytesRefBlock) sampleUncast; - BytesRef scratch = new BytesRef(); + BytesRef sampleScratch = new BytesRef(); for (int groupPosition = 0; groupPosition < groups.getPositionCount(); groupPosition++) { if (groups.isNull(groupPosition)) { continue; @@ -268,7 +268,7 @@ public void addIntermediateInput(int positionOffset, IntVector groups, Page page return; } BytesRefBlock sample = (BytesRefBlock) sampleUncast; - BytesRef scratch = new BytesRef(); + BytesRef sampleScratch = new BytesRef(); for (int groupPosition = 0; groupPosition < groups.getPositionCount(); groupPosition++) { int groupId = groups.getInt(groupPosition); int valuesPosition = groupPosition + positionOffset; diff --git a/x-pack/plugin/esql/compute/src/main/generated/org/elasticsearch/compute/aggregation/SampleLongAggregatorFunction.java b/x-pack/plugin/esql/compute/src/main/generated/org/elasticsearch/compute/aggregation/SampleLongAggregatorFunction.java index df885bd2292db..b78d48381ef8e 100644 --- a/x-pack/plugin/esql/compute/src/main/generated/org/elasticsearch/compute/aggregation/SampleLongAggregatorFunction.java +++ b/x-pack/plugin/esql/compute/src/main/generated/org/elasticsearch/compute/aggregation/SampleLongAggregatorFunction.java @@ -148,7 +148,7 @@ public void addIntermediateInput(Page page) { } BytesRefBlock sample = (BytesRefBlock) sampleUncast; assert sample.getPositionCount() == 1; - BytesRef scratch = new BytesRef(); + BytesRef sampleScratch = new BytesRef(); SampleLongAggregator.combineIntermediate(state, sample); } diff --git a/x-pack/plugin/esql/compute/src/main/generated/org/elasticsearch/compute/aggregation/SampleLongGroupingAggregatorFunction.java b/x-pack/plugin/esql/compute/src/main/generated/org/elasticsearch/compute/aggregation/SampleLongGroupingAggregatorFunction.java index 675827ad0caa3..4310849a9ebb7 100644 --- a/x-pack/plugin/esql/compute/src/main/generated/org/elasticsearch/compute/aggregation/SampleLongGroupingAggregatorFunction.java +++ b/x-pack/plugin/esql/compute/src/main/generated/org/elasticsearch/compute/aggregation/SampleLongGroupingAggregatorFunction.java @@ -157,7 +157,7 @@ public void addIntermediateInput(int positionOffset, IntArrayBlock groups, Page return; } BytesRefBlock sample = (BytesRefBlock) sampleUncast; - BytesRef scratch = new BytesRef(); + BytesRef sampleScratch = new BytesRef(); for (int groupPosition = 0; groupPosition < groups.getPositionCount(); groupPosition++) { if (groups.isNull(groupPosition)) { continue; @@ -220,7 +220,7 @@ public void addIntermediateInput(int positionOffset, IntBigArrayBlock groups, Pa return; } BytesRefBlock sample = (BytesRefBlock) sampleUncast; - BytesRef scratch = new BytesRef(); + BytesRef sampleScratch = new BytesRef(); for (int groupPosition = 0; groupPosition < groups.getPositionCount(); groupPosition++) { if (groups.isNull(groupPosition)) { continue; @@ -269,7 +269,7 @@ public void addIntermediateInput(int positionOffset, IntVector groups, Page page return; } BytesRefBlock sample = (BytesRefBlock) sampleUncast; - BytesRef scratch = new BytesRef(); + BytesRef sampleScratch = new BytesRef(); for (int groupPosition = 0; groupPosition < groups.getPositionCount(); groupPosition++) { int groupId = groups.getInt(groupPosition); int valuesPosition = groupPosition + positionOffset; diff --git a/x-pack/plugin/esql/compute/src/main/generated/org/elasticsearch/compute/aggregation/TopBytesRefAggregatorFunction.java b/x-pack/plugin/esql/compute/src/main/generated/org/elasticsearch/compute/aggregation/TopBytesRefAggregatorFunction.java index c9aad2f067c4c..5042ba27a83a6 100644 --- a/x-pack/plugin/esql/compute/src/main/generated/org/elasticsearch/compute/aggregation/TopBytesRefAggregatorFunction.java +++ b/x-pack/plugin/esql/compute/src/main/generated/org/elasticsearch/compute/aggregation/TopBytesRefAggregatorFunction.java @@ -154,7 +154,7 @@ public void addIntermediateInput(Page page) { } BytesRefBlock top = (BytesRefBlock) topUncast; assert top.getPositionCount() == 1; - BytesRef scratch = new BytesRef(); + BytesRef topScratch = new BytesRef(); TopBytesRefAggregator.combineIntermediate(state, top); } diff --git a/x-pack/plugin/esql/compute/src/main/generated/org/elasticsearch/compute/aggregation/TopBytesRefGroupingAggregatorFunction.java b/x-pack/plugin/esql/compute/src/main/generated/org/elasticsearch/compute/aggregation/TopBytesRefGroupingAggregatorFunction.java index dc6db83fc0f0d..676c70b480abe 100644 --- a/x-pack/plugin/esql/compute/src/main/generated/org/elasticsearch/compute/aggregation/TopBytesRefGroupingAggregatorFunction.java +++ b/x-pack/plugin/esql/compute/src/main/generated/org/elasticsearch/compute/aggregation/TopBytesRefGroupingAggregatorFunction.java @@ -162,7 +162,7 @@ public void addIntermediateInput(int positionOffset, IntArrayBlock groups, Page return; } BytesRefBlock top = (BytesRefBlock) topUncast; - BytesRef scratch = new BytesRef(); + BytesRef topScratch = new BytesRef(); for (int groupPosition = 0; groupPosition < groups.getPositionCount(); groupPosition++) { if (groups.isNull(groupPosition)) { continue; @@ -227,7 +227,7 @@ public void addIntermediateInput(int positionOffset, IntBigArrayBlock groups, Pa return; } BytesRefBlock top = (BytesRefBlock) topUncast; - BytesRef scratch = new BytesRef(); + BytesRef topScratch = new BytesRef(); for (int groupPosition = 0; groupPosition < groups.getPositionCount(); groupPosition++) { if (groups.isNull(groupPosition)) { continue; @@ -278,7 +278,7 @@ public void addIntermediateInput(int positionOffset, IntVector groups, Page page return; } BytesRefBlock top = (BytesRefBlock) topUncast; - BytesRef scratch = new BytesRef(); + BytesRef topScratch = new BytesRef(); for (int groupPosition = 0; groupPosition < groups.getPositionCount(); groupPosition++) { int groupId = groups.getInt(groupPosition); int valuesPosition = groupPosition + positionOffset; diff --git a/x-pack/plugin/esql/compute/src/main/generated/org/elasticsearch/compute/aggregation/TopIpAggregatorFunction.java b/x-pack/plugin/esql/compute/src/main/generated/org/elasticsearch/compute/aggregation/TopIpAggregatorFunction.java index f5781c44f5e65..38c6e2c88c9f5 100644 --- a/x-pack/plugin/esql/compute/src/main/generated/org/elasticsearch/compute/aggregation/TopIpAggregatorFunction.java +++ b/x-pack/plugin/esql/compute/src/main/generated/org/elasticsearch/compute/aggregation/TopIpAggregatorFunction.java @@ -154,7 +154,7 @@ public void addIntermediateInput(Page page) { } BytesRefBlock top = (BytesRefBlock) topUncast; assert top.getPositionCount() == 1; - BytesRef scratch = new BytesRef(); + BytesRef topScratch = new BytesRef(); TopIpAggregator.combineIntermediate(state, top); } diff --git a/x-pack/plugin/esql/compute/src/main/generated/org/elasticsearch/compute/aggregation/TopIpGroupingAggregatorFunction.java b/x-pack/plugin/esql/compute/src/main/generated/org/elasticsearch/compute/aggregation/TopIpGroupingAggregatorFunction.java index 18a6925ebbb34..a813402811302 100644 --- a/x-pack/plugin/esql/compute/src/main/generated/org/elasticsearch/compute/aggregation/TopIpGroupingAggregatorFunction.java +++ b/x-pack/plugin/esql/compute/src/main/generated/org/elasticsearch/compute/aggregation/TopIpGroupingAggregatorFunction.java @@ -162,7 +162,7 @@ public void addIntermediateInput(int positionOffset, IntArrayBlock groups, Page return; } BytesRefBlock top = (BytesRefBlock) topUncast; - BytesRef scratch = new BytesRef(); + BytesRef topScratch = new BytesRef(); for (int groupPosition = 0; groupPosition < groups.getPositionCount(); groupPosition++) { if (groups.isNull(groupPosition)) { continue; @@ -227,7 +227,7 @@ public void addIntermediateInput(int positionOffset, IntBigArrayBlock groups, Pa return; } BytesRefBlock top = (BytesRefBlock) topUncast; - BytesRef scratch = new BytesRef(); + BytesRef topScratch = new BytesRef(); for (int groupPosition = 0; groupPosition < groups.getPositionCount(); groupPosition++) { if (groups.isNull(groupPosition)) { continue; @@ -278,7 +278,7 @@ public void addIntermediateInput(int positionOffset, IntVector groups, Page page return; } BytesRefBlock top = (BytesRefBlock) topUncast; - BytesRef scratch = new BytesRef(); + BytesRef topScratch = new BytesRef(); for (int groupPosition = 0; groupPosition < groups.getPositionCount(); groupPosition++) { int groupId = groups.getInt(groupPosition); int valuesPosition = groupPosition + positionOffset; diff --git a/x-pack/plugin/esql/compute/src/main/generated/org/elasticsearch/compute/aggregation/ValuesBytesRefAggregatorFunction.java b/x-pack/plugin/esql/compute/src/main/generated/org/elasticsearch/compute/aggregation/ValuesBytesRefAggregatorFunction.java index 048467dddad48..d5da83e215f0c 100644 --- a/x-pack/plugin/esql/compute/src/main/generated/org/elasticsearch/compute/aggregation/ValuesBytesRefAggregatorFunction.java +++ b/x-pack/plugin/esql/compute/src/main/generated/org/elasticsearch/compute/aggregation/ValuesBytesRefAggregatorFunction.java @@ -148,7 +148,7 @@ public void addIntermediateInput(Page page) { } BytesRefBlock values = (BytesRefBlock) valuesUncast; assert values.getPositionCount() == 1; - BytesRef scratch = new BytesRef(); + BytesRef valuesScratch = new BytesRef(); ValuesBytesRefAggregator.combineIntermediate(state, values); } From 2f7adceb43cff34ee7532837f0f4716f0e3fc581 Mon Sep 17 00:00:00 2001 From: Jonas Kunz Date: Fri, 31 Oct 2025 14:13:18 +0100 Subject: [PATCH 13/15] Implement percentile aggregation --- .../ExponentialHistogramBlockBuilder.java | 2 - .../resources/exponential_histogram.csv-spec | 30 ++++++--- .../aggregate/AggregateWritables.java | 3 +- .../{HistogramMerge.java => Merge.java} | 61 +++++-------------- .../function/aggregate/Percentile.java | 9 ++- .../scalar/histogram/HistogramPercentile.java | 7 +-- .../xpack/esql/planner/AggregateMapper.java | 3 +- 7 files changed, 48 insertions(+), 67 deletions(-) rename x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/aggregate/{HistogramMerge.java => Merge.java} (50%) diff --git a/x-pack/plugin/esql/compute/src/main/java/org/elasticsearch/compute/data/ExponentialHistogramBlockBuilder.java b/x-pack/plugin/esql/compute/src/main/java/org/elasticsearch/compute/data/ExponentialHistogramBlockBuilder.java index 18431e8510ee8..01aff0a28138b 100644 --- a/x-pack/plugin/esql/compute/src/main/java/org/elasticsearch/compute/data/ExponentialHistogramBlockBuilder.java +++ b/x-pack/plugin/esql/compute/src/main/java/org/elasticsearch/compute/data/ExponentialHistogramBlockBuilder.java @@ -72,8 +72,6 @@ public ExponentialHistogramBlockBuilder append(ExponentialHistogram histogram) { // We should add a dedicated encoding when building a block from computed histograms which do not originate from doc values // That encoding should be optimized for speed and support storing the zero threshold as (scale, index) pair ZeroBucket zeroBucket = histogram.zeroBucket(); - assert zeroBucket.compareZeroThreshold(ZeroBucket.minimalEmpty()) == 0 || zeroBucket.isIndexBased() == false - : "Current encoding only supports double-based zero thresholds"; BytesStreamOutput encodedBytes = new BytesStreamOutput(); try { diff --git a/x-pack/plugin/esql/qa/testFixtures/src/main/resources/exponential_histogram.csv-spec b/x-pack/plugin/esql/qa/testFixtures/src/main/resources/exponential_histogram.csv-spec index 66fc624086acb..3993f8c01a632 100644 --- a/x-pack/plugin/esql/qa/testFixtures/src/main/resources/exponential_histogram.csv-spec +++ b/x-pack/plugin/esql/qa/testFixtures/src/main/resources/exponential_histogram.csv-spec @@ -27,18 +27,28 @@ zero_threshold_only | "{""scale"":0,""zero"":{""threshold"":42.7}}" zero_count_only | "{""scale"":2,""min"":0,""max"":0,""zero"":{""count"":101}}" ; -computePercentile +nonGroupingPercentile required_capability: exponential_histogram -FROM exp_histo_sample | SORT name | EVAL perc_50 = HISTOGRAM_PERCENTILE(histo, 50) | KEEP perc_50, histo +FROM exp_histo_sample | STATS perc_50 = PERCENTILE(histo, 50) ; -perc_50:double | histo:exponential_histogram -null | "{""scale"":-7,""sum"":0.0}" -0.0 | "{""scale"":12,""sum"":43.0,""min"":-456.0,""max"":789.0,""zero"":{""count"":42,""threshold"":0.123456},""positive"":{""indices"":[-1000000,-10,25,26,99999999],""counts"":[2,1,3,4,5]},""negative"":{""indices"":[-1000,-999,123456],""counts"":[10,20,11]}}" --50.05 | "{""scale"":0,""sum"":-424.0,""min"":-100.0,""max"":-0.1,""negative"":{""indices"":[-100,10,20],""counts"":[3,2,1]}}" --123.0 | "{""scale"":-10,""sum"":42.0,""min"":-123.0,""max"":456.0,""positive"":{""indices"":[1,2,3,4,5],""counts"":[6,7,8,9,10]},""negative"":{""indices"":[-1,0,1,2,3,4,5,6,7,8],""counts"":[1,2,3,4,5,6,7,8,9,10]}}" -50.05 | "{""scale"":0,""sum"":424.0,""min"":0.1,""max"":100.0,""positive"":{""indices"":[-100,10,20],""counts"":[3,2,1]}}" -0.0 | "{""scale"":2,""sum"":0.0,""min"":0.0,""max"":0.0,""zero"":{""count"":101}}" -null | "{""scale"":0,""sum"":0.0,""zero"":{""threshold"":42.7}}" +perc_50:double +0 +; + +groupingPercentile +required_capability: exponential_histogram + +FROM exp_histo_sample | STATS perc_50 = PERCENTILE(histo, 50) BY name | SORT name | KEEP name, perc_50 +; + +name:keyword | perc_50:double +empty | NaN +full | 0.0 +negative_only | -50.05 +no_zero_bucket | -123.0 +positive_only | 50.05 +zero_count_only | 0.0 +zero_threshold_only | NaN ; diff --git a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/aggregate/AggregateWritables.java b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/aggregate/AggregateWritables.java index 5b3bddd89d093..bb3b539c7ea53 100644 --- a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/aggregate/AggregateWritables.java +++ b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/aggregate/AggregateWritables.java @@ -51,7 +51,8 @@ public static List getNamedWriteables() { PresentOverTime.ENTRY, Absent.ENTRY, AbsentOverTime.ENTRY, - DimensionValues.ENTRY + DimensionValues.ENTRY, + Merge.ENTRY ); } } diff --git a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/aggregate/HistogramMerge.java b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/aggregate/Merge.java similarity index 50% rename from x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/aggregate/HistogramMerge.java rename to x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/aggregate/Merge.java index 18396d6e3122f..5696bbc367508 100644 --- a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/aggregate/HistogramMerge.java +++ b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/aggregate/Merge.java @@ -9,21 +9,14 @@ import org.elasticsearch.common.io.stream.NamedWriteableRegistry; import org.elasticsearch.common.io.stream.StreamInput; -import org.elasticsearch.compute.aggregation.AggregatorFunction; import org.elasticsearch.compute.aggregation.AggregatorFunctionSupplier; -import org.elasticsearch.compute.aggregation.GroupingAggregatorFunction; -import org.elasticsearch.compute.aggregation.IntermediateStateDesc; -import org.elasticsearch.compute.aggregation.StdDevDoubleAggregatorFunctionSupplier; -import org.elasticsearch.compute.aggregation.StdDevIntAggregatorFunctionSupplier; -import org.elasticsearch.compute.aggregation.StdDevLongAggregatorFunctionSupplier; -import org.elasticsearch.compute.operator.DriverContext; +import org.elasticsearch.compute.aggregation.ExponentialHistogramMergeAggregatorFunctionSupplier; import org.elasticsearch.xpack.esql.EsqlIllegalArgumentException; import org.elasticsearch.xpack.esql.core.expression.Expression; import org.elasticsearch.xpack.esql.core.expression.Literal; import org.elasticsearch.xpack.esql.core.tree.NodeInfo; import org.elasticsearch.xpack.esql.core.tree.Source; import org.elasticsearch.xpack.esql.core.type.DataType; -import org.elasticsearch.xpack.esql.expression.function.Example; import org.elasticsearch.xpack.esql.expression.function.FunctionInfo; import org.elasticsearch.xpack.esql.expression.function.FunctionType; import org.elasticsearch.xpack.esql.expression.function.Param; @@ -36,22 +29,22 @@ import static org.elasticsearch.xpack.esql.core.expression.TypeResolutions.ParamOrdinal.DEFAULT; import static org.elasticsearch.xpack.esql.core.expression.TypeResolutions.isType; -public class HistogramMerge extends AggregateFunction implements ToAggregator { - public static final NamedWriteableRegistry.Entry ENTRY = new NamedWriteableRegistry.Entry(Expression.class, "HistogramMerge", HistogramMerge::new); +public class Merge extends AggregateFunction implements ToAggregator { + public static final NamedWriteableRegistry.Entry ENTRY = new NamedWriteableRegistry.Entry(Expression.class, "Merge", Merge::new); @FunctionInfo( returnType = "exponential_histogram", type = FunctionType.AGGREGATE ) - public HistogramMerge(Source source, @Param(name = "histogram", type = { "exponential_histogram" }) Expression field) { + public Merge(Source source, @Param(name = "histogram", type = { "exponential_histogram" }) Expression field) { this(source, field, Literal.TRUE); } - public HistogramMerge(Source source, Expression field, Expression filter) { + public Merge(Source source, Expression field, Expression filter) { super(source, field, filter, emptyList()); } - private HistogramMerge(StreamInput in) throws IOException { + private Merge(StreamInput in) throws IOException { super(in); } @@ -77,50 +70,24 @@ protected TypeResolution resolveType() { } @Override - protected NodeInfo info() { - return NodeInfo.create(this, HistogramMerge::new, field(), filter()); + protected NodeInfo info() { + return NodeInfo.create(this, Merge::new, field(), filter()); } @Override - public HistogramMerge replaceChildren(List newChildren) { - return new HistogramMerge(source(), newChildren.get(0), newChildren.get(1)); + public Merge replaceChildren(List newChildren) { + return new Merge(source(), newChildren.get(0), newChildren.get(1)); } - public HistogramMerge withFilter(Expression filter) { - return new HistogramMerge(source(), field(), filter); + public Merge withFilter(Expression filter) { + return new Merge(source(), field(), filter); } @Override public final AggregatorFunctionSupplier supplier() { DataType type = field().dataType(); - if (type == DataType.LONG) { - return new AggregatorFunctionSupplier() { - - @Override - public String describe() { - return "merge of exponential histograms"; - } - - @Override - public List nonGroupingIntermediateStateDesc() { - return List.of(); - } - - @Override - public List groupingIntermediateStateDesc() { - return List.of(); - } - - @Override - public AggregatorFunction aggregator(DriverContext driverContext, List channels) { - return null; - } - - @Override - public GroupingAggregatorFunction groupingAggregator(DriverContext driverContext, List channels) { - return null; - } - }; + if (type == DataType.EXPONENTIAL_HISTOGRAM) { + return new ExponentialHistogramMergeAggregatorFunctionSupplier(); } throw EsqlIllegalArgumentException.illegalDataType(type); } diff --git a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/aggregate/Percentile.java b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/aggregate/Percentile.java index e3418aa17c3a3..e5fc695efb4ae 100644 --- a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/aggregate/Percentile.java +++ b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/aggregate/Percentile.java @@ -24,6 +24,7 @@ import org.elasticsearch.xpack.esql.expression.function.FunctionType; import org.elasticsearch.xpack.esql.expression.function.Param; import org.elasticsearch.xpack.esql.expression.function.scalar.convert.ToDouble; +import org.elasticsearch.xpack.esql.expression.function.scalar.histogram.HistogramPercentile; import org.elasticsearch.xpack.esql.expression.function.scalar.multivalue.MvPercentile; import org.elasticsearch.xpack.esql.io.stream.PlanStreamInput; @@ -75,7 +76,7 @@ public class Percentile extends NumericAggregate implements SurrogateExpression public Percentile( Source source, @Param(name = "number", type = { "double", "integer", "long" }) Expression field, - @Param(name = "percentile", type = { "double", "integer", "long" }) Expression percentile + @Param(name = "percentile", type = { "double", "integer", "long", "exponential_histogram" }) Expression percentile ) { this(source, field, Literal.TRUE, percentile); } @@ -126,7 +127,7 @@ protected TypeResolution resolveType() { TypeResolution resolution = isType( field(), - dt -> dt.isNumeric() && dt != DataType.UNSIGNED_LONG, + dt -> (dt.isNumeric() && dt != DataType.UNSIGNED_LONG) || dt == DataType.EXPONENTIAL_HISTOGRAM, sourceText(), FIRST, "numeric except unsigned_long" @@ -171,6 +172,10 @@ public Expression surrogate() { return new MvPercentile(source(), new ToDouble(source(), field), percentile()); } + if( field.dataType() == DataType.EXPONENTIAL_HISTOGRAM ) { + return new HistogramPercentile(source(), new Merge(source(), field, filter()), percentile()); + } + return null; } } diff --git a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/histogram/HistogramPercentile.java b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/histogram/HistogramPercentile.java index de1b06cbb5474..51355ff6edb1e 100644 --- a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/histogram/HistogramPercentile.java +++ b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/histogram/HistogramPercentile.java @@ -111,16 +111,15 @@ public void writeTo(StreamOutput out) throws IOException { @Evaluator static double process(ExponentialHistogram value, double percentile) { - double result = ExponentialHistogramQuantile.getQuantile(value, percentile / 100.0); - return result; + // TODO handle nans and out of bounds percentiles + return ExponentialHistogramQuantile.getQuantile(value, percentile / 100.0); } @Override public EvalOperator.ExpressionEvaluator.Factory toEvaluator(ToEvaluator toEvaluator) { var fieldEvaluator = toEvaluator.apply(histogram); var percentileEvaluator = Cast.cast(source(), percentile.dataType(), DataType.DOUBLE, toEvaluator.apply(percentile)); - - return null; + return new HistogramPercentileEvaluator.Factory(source(), fieldEvaluator, percentileEvaluator); } diff --git a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/planner/AggregateMapper.java b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/planner/AggregateMapper.java index 8d4e5ab0346dd..3981b71f316b0 100644 --- a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/planner/AggregateMapper.java +++ b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/planner/AggregateMapper.java @@ -112,7 +112,8 @@ private static DataType toDataType(ElementType elementType) { case LONG -> DataType.LONG; case DOUBLE -> DataType.DOUBLE; case DOC -> DataType.DOC_DATA_TYPE; - case FLOAT, NULL, COMPOSITE, AGGREGATE_METRIC_DOUBLE, EXPONENTIAL_HISTOGRAM, UNKNOWN -> throw new EsqlIllegalArgumentException( + case EXPONENTIAL_HISTOGRAM -> DataType.EXPONENTIAL_HISTOGRAM; + case FLOAT, NULL, COMPOSITE, AGGREGATE_METRIC_DOUBLE, UNKNOWN -> throw new EsqlIllegalArgumentException( "unsupported agg type: " + elementType ); }; From 63450b038ed6660dbc33b6ad0901ad8c211c7314 Mon Sep 17 00:00:00 2001 From: Jonas Kunz Date: Fri, 31 Oct 2025 15:24:15 +0100 Subject: [PATCH 14/15] Fix aggregator location --- .../compute/aggregation/ExponentialHistogramMergeAggregator.java | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename x-pack/plugin/esql/compute/src/main/{generated-src => java}/org/elasticsearch/compute/aggregation/ExponentialHistogramMergeAggregator.java (100%) diff --git a/x-pack/plugin/esql/compute/src/main/generated-src/org/elasticsearch/compute/aggregation/ExponentialHistogramMergeAggregator.java b/x-pack/plugin/esql/compute/src/main/java/org/elasticsearch/compute/aggregation/ExponentialHistogramMergeAggregator.java similarity index 100% rename from x-pack/plugin/esql/compute/src/main/generated-src/org/elasticsearch/compute/aggregation/ExponentialHistogramMergeAggregator.java rename to x-pack/plugin/esql/compute/src/main/java/org/elasticsearch/compute/aggregation/ExponentialHistogramMergeAggregator.java From 310f85672b944d0c1079b494c6fb7553947bd708 Mon Sep 17 00:00:00 2001 From: elasticsearchmachine Date: Fri, 31 Oct 2025 14:32:51 +0000 Subject: [PATCH 15/15] [CI] Auto commit changes from spotless --- .../compute/gen/AggregatorImplementer.java | 16 ++++----- .../compute/gen/EvaluatorImplementer.java | 7 ++-- .../gen/GroupingAggregatorImplementer.java | 9 +++-- .../org/elasticsearch/compute/gen/Types.java | 2 +- .../compute/gen/argument/Argument.java | 3 +- .../ExponentialHistogramMergeAggregator.java | 12 +++---- .../ExponentialHistogramStates.java | 7 ++-- ...ValueExtractorForExponentialHistogram.java | 1 - .../xpack/esql/action/PositionToXContent.java | 2 +- .../expression/function/aggregate/Merge.java | 13 ++----- .../function/aggregate/Percentile.java | 2 +- .../scalar/histogram/HistogramPercentile.java | 34 ++++--------------- 12 files changed, 35 insertions(+), 73 deletions(-) diff --git a/x-pack/plugin/esql/compute/gen/src/main/java/org/elasticsearch/compute/gen/AggregatorImplementer.java b/x-pack/plugin/esql/compute/gen/src/main/java/org/elasticsearch/compute/gen/AggregatorImplementer.java index af0f9f1305df7..fc485b0133837 100644 --- a/x-pack/plugin/esql/compute/gen/src/main/java/org/elasticsearch/compute/gen/AggregatorImplementer.java +++ b/x-pack/plugin/esql/compute/gen/src/main/java/org/elasticsearch/compute/gen/AggregatorImplementer.java @@ -54,7 +54,6 @@ import static org.elasticsearch.compute.gen.Types.BLOCK; import static org.elasticsearch.compute.gen.Types.BLOCK_ARRAY; import static org.elasticsearch.compute.gen.Types.BOOLEAN_VECTOR; -import static org.elasticsearch.compute.gen.Types.BYTES_REF; import static org.elasticsearch.compute.gen.Types.DRIVER_CONTEXT; import static org.elasticsearch.compute.gen.Types.ELEMENT_TYPE; import static org.elasticsearch.compute.gen.Types.INTERMEDIATE_STATE_DESC; @@ -123,7 +122,7 @@ public AggregatorImplementer( }).filter(a -> a instanceof PositionArgument == false).toList(); this.attemptToUseVectors = aggParams.stream().anyMatch(a -> (a instanceof BlockArgument) == false) - && aggParams.stream().noneMatch(a -> a instanceof StandardArgument && a.dataType(false) == null); + && aggParams.stream().noneMatch(a -> a instanceof StandardArgument && a.dataType(false) == null); this.createParameters = init.getParameters() .stream() @@ -347,9 +346,9 @@ private MethodSpec addRawInputExploded(boolean hasMask) { if (attemptToUseVectors) { for (Argument a : aggParams) { String rawBlock = "addRawBlock(" - + aggParams.stream().map(arg -> arg.blockName()).collect(joining(", ")) - + (hasMask ? ", mask" : "") - + ")"; + + aggParams.stream().map(arg -> arg.blockName()).collect(joining(", ")) + + (hasMask ? ", mask" : "") + + ")"; a.resolveVectors(builder, rawBlock, "return"); } @@ -716,10 +715,10 @@ public String access(String position) { if (vectorType(elementType) != null) { s += vectorAccessorName(elementType()) + "(" + position; } else { - s+= getMethod(fromString(elementType())) + "(" + name() + ".getFirstValueIndex("+position+")"; + s += getMethod(fromString(elementType())) + "(" + name() + ".getFirstValueIndex(" + position + ")"; } if (scratchType(elementType()) != null) { - s += ", "+name()+"Scratch"; + s += ", " + name() + "Scratch"; } return s + ")"; } @@ -727,7 +726,7 @@ public String access(String position) { public void addScratchDeclaration(MethodSpec.Builder builder) { ClassName scratchType = scratchType(elementType()); if (scratchType != null) { - builder.addStatement("$T $L = new $T()", scratchType, name()+"Scratch", scratchType); + builder.addStatement("$T $L = new $T()", scratchType, name() + "Scratch", scratchType); } } @@ -746,7 +745,6 @@ public void assignToVariable(MethodSpec.Builder builder, int offset) { } } - public TypeName combineArgType() { var type = Types.fromString(elementType); return block ? blockType(type) : type; diff --git a/x-pack/plugin/esql/compute/gen/src/main/java/org/elasticsearch/compute/gen/EvaluatorImplementer.java b/x-pack/plugin/esql/compute/gen/src/main/java/org/elasticsearch/compute/gen/EvaluatorImplementer.java index 7ae79a0c6ef04..f5d544fde7453 100644 --- a/x-pack/plugin/esql/compute/gen/src/main/java/org/elasticsearch/compute/gen/EvaluatorImplementer.java +++ b/x-pack/plugin/esql/compute/gen/src/main/java/org/elasticsearch/compute/gen/EvaluatorImplementer.java @@ -71,10 +71,9 @@ public EvaluatorImplementer( declarationType.getSimpleName() + extraName + "Evaluator" ); this.processOutputsMultivalued = this.processFunction.hasBlockType; - boolean anyParameterNotSupportingVectors = - this.processFunction.args.stream() - .filter(a -> a instanceof FixedArgument == false && a instanceof PositionArgument == false) - .anyMatch(a -> a.dataType(false) == null); + boolean anyParameterNotSupportingVectors = this.processFunction.args.stream() + .filter(a -> a instanceof FixedArgument == false && a instanceof PositionArgument == false) + .anyMatch(a -> a.dataType(false) == null); vectorsUnsupported = processOutputsMultivalued || anyParameterNotSupportingVectors; this.allNullsIsNull = allNullsIsNull; } diff --git a/x-pack/plugin/esql/compute/gen/src/main/java/org/elasticsearch/compute/gen/GroupingAggregatorImplementer.java b/x-pack/plugin/esql/compute/gen/src/main/java/org/elasticsearch/compute/gen/GroupingAggregatorImplementer.java index 439ee8d6cba08..c2ed5f463913e 100644 --- a/x-pack/plugin/esql/compute/gen/src/main/java/org/elasticsearch/compute/gen/GroupingAggregatorImplementer.java +++ b/x-pack/plugin/esql/compute/gen/src/main/java/org/elasticsearch/compute/gen/GroupingAggregatorImplementer.java @@ -51,7 +51,6 @@ import static org.elasticsearch.compute.gen.Types.BIG_ARRAYS; import static org.elasticsearch.compute.gen.Types.BLOCK; import static org.elasticsearch.compute.gen.Types.BLOCK_ARRAY; -import static org.elasticsearch.compute.gen.Types.BYTES_REF; import static org.elasticsearch.compute.gen.Types.DRIVER_CONTEXT; import static org.elasticsearch.compute.gen.Types.ELEMENT_TYPE; import static org.elasticsearch.compute.gen.Types.GROUPING_AGGREGATOR_EVALUATOR_CONTEXT; @@ -129,7 +128,7 @@ public GroupingAggregatorImplementer( }).filter(a -> a instanceof PositionArgument == false).toList(); this.hasOnlyBlockArguments = this.aggParams.stream().allMatch(a -> a instanceof BlockArgument); - this.allArgumentsSupportVectors = aggParams.stream().noneMatch(a -> a instanceof StandardArgument && a.dataType(false) == null); + this.allArgumentsSupportVectors = aggParams.stream().noneMatch(a -> a instanceof StandardArgument && a.dataType(false) == null); this.createParameters = init.getParameters() .stream() @@ -333,8 +332,8 @@ private MethodSpec prepareProcessRawInputPage() { } String groupIdTrackingStatement = "maybeEnableGroupIdTracking(seenGroupIds, " - + aggParams.stream().map(arg -> arg.blockName()).collect(joining(", ")) - + ")"; + + aggParams.stream().map(arg -> arg.blockName()).collect(joining(", ")) + + ")"; if (allArgumentsSupportVectors) { @@ -347,7 +346,7 @@ private MethodSpec prepareProcessRawInputPage() { ); builder.beginControlFlow("if ($L == null)", (a instanceof BlockArgument) ? (a.name() + "Vector") : a.vectorName()); { - builder.addStatement( groupIdTrackingStatement); + builder.addStatement(groupIdTrackingStatement); returnAddInput(builder, false); } builder.endControlFlow(); diff --git a/x-pack/plugin/esql/compute/gen/src/main/java/org/elasticsearch/compute/gen/Types.java b/x-pack/plugin/esql/compute/gen/src/main/java/org/elasticsearch/compute/gen/Types.java index 64118d9e576e3..d31679665efb5 100644 --- a/x-pack/plugin/esql/compute/gen/src/main/java/org/elasticsearch/compute/gen/Types.java +++ b/x-pack/plugin/esql/compute/gen/src/main/java/org/elasticsearch/compute/gen/Types.java @@ -148,7 +148,7 @@ public static TypeDef of(TypeName type, String alias, String block, String vecto type, alias, ClassName.get(DATA_PACKAGE, block), - vector == null ? null: ClassName.get(DATA_PACKAGE, vector), + vector == null ? null : ClassName.get(DATA_PACKAGE, vector), scratch ); } diff --git a/x-pack/plugin/esql/compute/gen/src/main/java/org/elasticsearch/compute/gen/argument/Argument.java b/x-pack/plugin/esql/compute/gen/src/main/java/org/elasticsearch/compute/gen/argument/Argument.java index f3600941854f6..c4fdfc9b1b6d2 100644 --- a/x-pack/plugin/esql/compute/gen/src/main/java/org/elasticsearch/compute/gen/argument/Argument.java +++ b/x-pack/plugin/esql/compute/gen/src/main/java/org/elasticsearch/compute/gen/argument/Argument.java @@ -26,7 +26,6 @@ import static org.elasticsearch.compute.gen.Methods.getMethod; import static org.elasticsearch.compute.gen.Types.BYTES_REF; -import static org.elasticsearch.compute.gen.Types.EXPONENTIAL_HISTOGRAM; import static org.elasticsearch.compute.gen.Types.blockType; import static org.elasticsearch.compute.gen.Types.vectorType; import static org.elasticsearch.compute.gen.argument.StandardArgument.isBlockType; @@ -100,7 +99,7 @@ default ClassName scratchType() { default String scratchName() { if (scratchType() != null == false) { - throw new IllegalStateException("can't build scratch for " +type()); + throw new IllegalStateException("can't build scratch for " + type()); } return name() + "Scratch"; diff --git a/x-pack/plugin/esql/compute/src/main/java/org/elasticsearch/compute/aggregation/ExponentialHistogramMergeAggregator.java b/x-pack/plugin/esql/compute/src/main/java/org/elasticsearch/compute/aggregation/ExponentialHistogramMergeAggregator.java index bd231afac9f32..5fcb55473aa43 100644 --- a/x-pack/plugin/esql/compute/src/main/java/org/elasticsearch/compute/aggregation/ExponentialHistogramMergeAggregator.java +++ b/x-pack/plugin/esql/compute/src/main/java/org/elasticsearch/compute/aggregation/ExponentialHistogramMergeAggregator.java @@ -16,11 +16,7 @@ import org.elasticsearch.compute.operator.DriverContext; import org.elasticsearch.exponentialhistogram.ExponentialHistogram; -@Aggregator( - { - @IntermediateState(name = "value", type = "EXPONENTIAL_HISTOGRAM"), - } -) +@Aggregator({ @IntermediateState(name = "value", type = "EXPONENTIAL_HISTOGRAM"), }) @GroupingAggregator public class ExponentialHistogramMergeAggregator { @@ -52,7 +48,11 @@ public static void combineIntermediate(ExponentialHistogramStates.GroupingState state.add(groupId, value); } - public static Block evaluateFinal(ExponentialHistogramStates.GroupingState state, IntVector selected, GroupingAggregatorEvaluationContext ctx) { + public static Block evaluateFinal( + ExponentialHistogramStates.GroupingState state, + IntVector selected, + GroupingAggregatorEvaluationContext ctx + ) { return state.evaluateFinal(selected, ctx.driverContext()); } } diff --git a/x-pack/plugin/esql/compute/src/main/java/org/elasticsearch/compute/aggregation/ExponentialHistogramStates.java b/x-pack/plugin/esql/compute/src/main/java/org/elasticsearch/compute/aggregation/ExponentialHistogramStates.java index c94db58fe8822..0b0cbb0add438 100644 --- a/x-pack/plugin/esql/compute/src/main/java/org/elasticsearch/compute/aggregation/ExponentialHistogramStates.java +++ b/x-pack/plugin/esql/compute/src/main/java/org/elasticsearch/compute/aggregation/ExponentialHistogramStates.java @@ -12,7 +12,6 @@ import org.elasticsearch.common.util.ObjectArray; import org.elasticsearch.compute.data.Block; import org.elasticsearch.compute.data.BlockFactory; -import org.elasticsearch.compute.data.DoubleBlock; import org.elasticsearch.compute.data.IntVector; import org.elasticsearch.compute.operator.DriverContext; import org.elasticsearch.core.Releasables; @@ -125,9 +124,7 @@ public void toIntermediate(Block[] blocks, int offset, IntVector selected, Drive } public Block evaluateFinal(IntVector selected, DriverContext driverContext) { - try ( - var builder = driverContext.blockFactory().newExponentialHistogramBlockBuilder(selected.getPositionCount()); - ) { + try (var builder = driverContext.blockFactory().newExponentialHistogramBlockBuilder(selected.getPositionCount());) { for (int i = 0; i < selected.getPositionCount(); i++) { int groupId = selected.getInt(i); ExponentialHistogramMerger state = getOrNull(groupId); @@ -143,7 +140,7 @@ public Block evaluateFinal(IntVector selected, DriverContext driverContext) { @Override public void close() { - for (int i=0; i dt == DataType.EXPONENTIAL_HISTOGRAM, - sourceText(), - DEFAULT, - "exponential_histogram" - ); + return isType(field(), dt -> dt == DataType.EXPONENTIAL_HISTOGRAM, sourceText(), DEFAULT, "exponential_histogram"); } @Override diff --git a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/aggregate/Percentile.java b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/aggregate/Percentile.java index e5fc695efb4ae..c372db1795864 100644 --- a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/aggregate/Percentile.java +++ b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/aggregate/Percentile.java @@ -172,7 +172,7 @@ public Expression surrogate() { return new MvPercentile(source(), new ToDouble(source(), field), percentile()); } - if( field.dataType() == DataType.EXPONENTIAL_HISTOGRAM ) { + if (field.dataType() == DataType.EXPONENTIAL_HISTOGRAM) { return new HistogramPercentile(source(), new Merge(source(), field, filter()), percentile()); } diff --git a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/histogram/HistogramPercentile.java b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/histogram/HistogramPercentile.java index 51355ff6edb1e..a5d99f67f5ef2 100644 --- a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/histogram/HistogramPercentile.java +++ b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/histogram/HistogramPercentile.java @@ -7,7 +7,6 @@ package org.elasticsearch.xpack.esql.expression.function.scalar.histogram; -import org.apache.lucene.util.BytesRef; import org.elasticsearch.common.io.stream.NamedWriteableRegistry; import org.elasticsearch.common.io.stream.StreamInput; import org.elasticsearch.common.io.stream.StreamOutput; @@ -43,17 +42,11 @@ public class HistogramPercentile extends EsqlScalarFunction { private final Expression percentile; @FunctionInfo(returnType = { "double" }) - public HistogramPercentile(Source source, - @Param( - name = "histogram", - type = { "exponential_histogram" } - ) - Expression histogram, - @Param( - name = "percentile", - type = { "double", "integer", "long", "unsigned_long" } - ) - Expression percentile) { + public HistogramPercentile( + Source source, + @Param(name = "histogram", type = { "exponential_histogram" }) Expression histogram, + @Param(name = "percentile", type = { "double", "integer", "long", "unsigned_long" }) Expression percentile + ) { super(source, List.of(histogram, percentile)); this.histogram = histogram; this.percentile = percentile; @@ -65,20 +58,8 @@ private HistogramPercentile(StreamInput in) throws IOException { @Override protected TypeResolution resolveType() { - return isType( - histogram, - dt -> dt == DataType.EXPONENTIAL_HISTOGRAM, - sourceText(), - DEFAULT, - "exponential_histogram" - ).and( - isType( - percentile, - DataType::isNumeric, - sourceText(), - DEFAULT, - "numeric types" - ) + return isType(histogram, dt -> dt == DataType.EXPONENTIAL_HISTOGRAM, sourceText(), DEFAULT, "exponential_histogram").and( + isType(percentile, DataType::isNumeric, sourceText(), DEFAULT, "numeric types") ); } @@ -122,5 +103,4 @@ public EvalOperator.ExpressionEvaluator.Factory toEvaluator(ToEvaluator toEvalua return new HistogramPercentileEvaluator.Factory(source(), fieldEvaluator, percentileEvaluator); } - }