diff --git a/x-pack/plugin/esql/compute/build.gradle b/x-pack/plugin/esql/compute/build.gradle index 435069a20f533..1405ac0999d76 100644 --- a/x-pack/plugin/esql/compute/build.gradle +++ b/x-pack/plugin/esql/compute/build.gradle @@ -86,6 +86,7 @@ def addOccurrence(props, Occurrence) { newProps["Occurrence"] = Occurrence newProps["First"] = Occurrence == "First" ? "true" : "" newProps["Last"] = Occurrence == "Last" ? "true" : "" + newProps["occurrence"] = Occurrence.toLowerCase(Locale.ROOT) return newProps } @@ -469,6 +470,27 @@ tasks.named('stringTemplates').configure { it.inputFile = stateInputFile it.outputFile = "org/elasticsearch/compute/aggregation/DoubleState.java" } + + /* + * Generates pairwise states. We generate the ones that we need at the moment, + * but add more if you need more. + */ + File twoStateInputFile = file("src/main/java/org/elasticsearch/compute/aggregation/X-2State.java.st") + [longProperties].forEach { v1 -> + [intProperties, longProperties, floatProperties, doubleProperties].forEach { v2 -> + { + var properties = [:] + v1.forEach { k, v -> properties["v1_" + k] = v} + v2.forEach { k, v -> properties["v2_" + k] = v} + template { + it.properties = properties + it.inputFile = twoStateInputFile + it.outputFile = "org/elasticsearch/compute/aggregation/${v1.Type}${v2.Type}State.java" + } + } + } + } + File fallibleStateInputFile = new File("${projectDir}/src/main/java/org/elasticsearch/compute/aggregation/X-FallibleState.java.st") template { it.properties = booleanProperties diff --git a/x-pack/plugin/esql/compute/gen/src/main/java/org/elasticsearch/compute/gen/AggregatorFunctionSupplierImplementer.java b/x-pack/plugin/esql/compute/gen/src/main/java/org/elasticsearch/compute/gen/AggregatorFunctionSupplierImplementer.java index 52e4e66f38482..52f42e0858dad 100644 --- a/x-pack/plugin/esql/compute/gen/src/main/java/org/elasticsearch/compute/gen/AggregatorFunctionSupplierImplementer.java +++ b/x-pack/plugin/esql/compute/gen/src/main/java/org/elasticsearch/compute/gen/AggregatorFunctionSupplierImplementer.java @@ -25,10 +25,15 @@ import java.util.stream.Collectors; import java.util.stream.Stream; +import javax.lang.model.element.ExecutableElement; import javax.lang.model.element.Modifier; import javax.lang.model.element.TypeElement; import javax.lang.model.util.Elements; +import static org.elasticsearch.compute.gen.Methods.optionalStaticMethod; +import static org.elasticsearch.compute.gen.Methods.requireArgs; +import static org.elasticsearch.compute.gen.Methods.requireName; +import static org.elasticsearch.compute.gen.Methods.requireType; import static org.elasticsearch.compute.gen.Types.AGGREGATOR_FUNCTION_SUPPLIER; import static org.elasticsearch.compute.gen.Types.DRIVER_CONTEXT; import static org.elasticsearch.compute.gen.Types.LIST_AGG_FUNC_DESC; @@ -210,17 +215,24 @@ private MethodSpec describe() { MethodSpec.Builder builder = MethodSpec.methodBuilder("describe").returns(String.class); builder.addAnnotation(Override.class).addModifiers(Modifier.PUBLIC); - String name = declarationType.getSimpleName().toString(); - name = name.replace("BytesRef", "Byte"); // The hack expects one word types so let's make BytesRef into Byte - String[] parts = name.split("(?=\\p{Upper})"); - if (false == parts[parts.length - 1].equals("Aggregator") || parts.length < 3) { - throw new IllegalArgumentException("Can't generate description for " + declarationType.getSimpleName()); + ExecutableElement describe = optionalStaticMethod(declarationType, requireType(STRING), requireName("describe"), requireArgs()); + if (describe == null) { + String name = declarationType.getSimpleName().toString(); + name = name.replace("BytesRef", "Byte"); // The hack expects one word types so let's make BytesRef into Byte + String[] parts = name.split("(?=\\p{Upper})"); + if (false == parts[parts.length - 1].equals("Aggregator") || parts.length < 3) { + throw new IllegalArgumentException("Can't generate description for " + declarationType.getSimpleName()); + } + + String operation = Arrays.stream(parts, 0, parts.length - 2) + .map(s -> s.toLowerCase(Locale.ROOT)) + .collect(Collectors.joining("_")); + String type = parts[parts.length - 2]; + + builder.addStatement("return $S", operation + " of " + type.toLowerCase(Locale.ROOT) + "s"); + } else { + builder.addStatement("return $T.$L()", declarationType, "describe"); } - - String operation = Arrays.stream(parts, 0, parts.length - 2).map(s -> s.toLowerCase(Locale.ROOT)).collect(Collectors.joining("_")); - String type = parts[parts.length - 2]; - - builder.addStatement("return $S", operation + " of " + type.toLowerCase(Locale.ROOT) + "s"); return builder.build(); } } 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 fe65800ce9c38..58e6402070e21 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 @@ -198,6 +198,7 @@ private TypeSpec type() { builder.addMethod(addRawInputLoop(groupIdClass, true)); builder.addMethod(addIntermediateInput(groupIdClass)); } + builder.addMethod(maybeEnableGroupIdTracking()); builder.addMethod(selectedMayContainUnseenGroups()); builder.addMethod(evaluateIntermediate()); builder.addMethod(evaluateFinal()); @@ -321,9 +322,11 @@ private MethodSpec prepareProcessRawInputPage() { builder.addStatement("$T $L = $L.asVector()", vectorType(p.type()), p.vectorName(), p.blockName()); builder.beginControlFlow("if ($L == null)", p.vectorName()); { - builder.beginControlFlow("if ($L.mayHaveNulls())", p.blockName()); - builder.addStatement("state.enableGroupIdTracking(seenGroupIds)"); - builder.endControlFlow(); + builder.addStatement( + "maybeEnableGroupIdTracking(seenGroupIds, " + + aggParams.stream().map(AggregationParameter::blockName).collect(joining(", ")) + + ")" + ); returnAddInput(builder, false); } builder.endControlFlow(); @@ -351,6 +354,23 @@ private void returnAddInput(MethodSpec.Builder builder, boolean valuesAreVector) } } + private MethodSpec maybeEnableGroupIdTracking() { + MethodSpec.Builder builder = MethodSpec.methodBuilder("maybeEnableGroupIdTracking"); + builder.addModifiers(Modifier.PRIVATE).returns(TypeName.VOID); + builder.addParameter(SEEN_GROUP_IDS, "seenGroupIds"); + for (AggregationParameter p : aggParams) { + builder.addParameter(blockType(p.type()), p.blockName()); + } + + for (AggregationParameter p : aggParams) { + builder.beginControlFlow("if ($L.mayHaveNulls())", p.blockName()); + builder.addStatement("state.enableGroupIdTracking(seenGroupIds)"); + builder.endControlFlow(); + } + + return builder.build(); + } + /** * Generate an {@code AddInput} implementation. That's a collection path optimized for the input data. */ diff --git a/x-pack/plugin/esql/compute/src/main/generated-src/org/elasticsearch/compute/aggregation/FirstDoubleByTimestampAggregator.java b/x-pack/plugin/esql/compute/src/main/generated-src/org/elasticsearch/compute/aggregation/FirstDoubleByTimestampAggregator.java index a2b6650063b3d..93142168cad93 100644 --- a/x-pack/plugin/esql/compute/src/main/generated-src/org/elasticsearch/compute/aggregation/FirstDoubleByTimestampAggregator.java +++ b/x-pack/plugin/esql/compute/src/main/generated-src/org/elasticsearch/compute/aggregation/FirstDoubleByTimestampAggregator.java @@ -27,10 +27,42 @@ * A time-series aggregation function that collects the First occurrence value of a time series in a specified interval. * This class is generated. Edit `X-ValueByTimestampAggregator.java.st` instead. */ +@Aggregator( + { + @IntermediateState(name = "timestamps", type = "LONG"), + @IntermediateState(name = "values", type = "DOUBLE"), + @IntermediateState(name = "seen", type = "BOOLEAN") } +) @GroupingAggregator( { @IntermediateState(name = "timestamps", type = "LONG_BLOCK"), @IntermediateState(name = "values", type = "DOUBLE_BLOCK") } ) public class FirstDoubleByTimestampAggregator { + public static String describe() { + return "first_double_by_timestamp"; + } + + public static LongDoubleState initSingle(DriverContext driverContext) { + return new LongDoubleState(0, 0); + } + + public static void combine(LongDoubleState current, double value, long timestamp) { + if (timestamp < current.v1()) { + current.v1(timestamp); + current.v2(value); + } + } + + public static void combineIntermediate(LongDoubleState current, long timestamp, double value, boolean seen) { + if (seen) { + current.seen(true); + combine(current, value, timestamp); + } + } + + public static Block evaluateFinal(LongDoubleState current, DriverContext ctx) { + return ctx.blockFactory().newConstantDoubleBlockWith(current.v2(), 1); + } + public static GroupingState initGrouping(DriverContext driverContext) { return new GroupingState(driverContext.bigArrays()); } @@ -76,6 +108,11 @@ public static final class GroupingState extends AbstractArrayState { timestamps = bigArrays.newLongArray(1, false); this.timestamps = timestamps; this.values = bigArrays.newDoubleArray(1, false); + /* + * Enable group id tracking because we use has hasValue in the + * collection itself to detect the when a value first arrives. + */ + enableGroupIdTracking(new SeenGroupIds.Empty()); success = true; } finally { if (success == false) { diff --git a/x-pack/plugin/esql/compute/src/main/generated-src/org/elasticsearch/compute/aggregation/FirstFloatByTimestampAggregator.java b/x-pack/plugin/esql/compute/src/main/generated-src/org/elasticsearch/compute/aggregation/FirstFloatByTimestampAggregator.java index 77b6041c3395b..c0aae974ae00a 100644 --- a/x-pack/plugin/esql/compute/src/main/generated-src/org/elasticsearch/compute/aggregation/FirstFloatByTimestampAggregator.java +++ b/x-pack/plugin/esql/compute/src/main/generated-src/org/elasticsearch/compute/aggregation/FirstFloatByTimestampAggregator.java @@ -27,10 +27,42 @@ * A time-series aggregation function that collects the First occurrence value of a time series in a specified interval. * This class is generated. Edit `X-ValueByTimestampAggregator.java.st` instead. */ +@Aggregator( + { + @IntermediateState(name = "timestamps", type = "LONG"), + @IntermediateState(name = "values", type = "FLOAT"), + @IntermediateState(name = "seen", type = "BOOLEAN") } +) @GroupingAggregator( { @IntermediateState(name = "timestamps", type = "LONG_BLOCK"), @IntermediateState(name = "values", type = "FLOAT_BLOCK") } ) public class FirstFloatByTimestampAggregator { + public static String describe() { + return "first_float_by_timestamp"; + } + + public static LongFloatState initSingle(DriverContext driverContext) { + return new LongFloatState(0, 0); + } + + public static void combine(LongFloatState current, float value, long timestamp) { + if (timestamp < current.v1()) { + current.v1(timestamp); + current.v2(value); + } + } + + public static void combineIntermediate(LongFloatState current, long timestamp, float value, boolean seen) { + if (seen) { + current.seen(true); + combine(current, value, timestamp); + } + } + + public static Block evaluateFinal(LongFloatState current, DriverContext ctx) { + return ctx.blockFactory().newConstantFloatBlockWith(current.v2(), 1); + } + public static GroupingState initGrouping(DriverContext driverContext) { return new GroupingState(driverContext.bigArrays()); } @@ -76,6 +108,11 @@ public static final class GroupingState extends AbstractArrayState { timestamps = bigArrays.newLongArray(1, false); this.timestamps = timestamps; this.values = bigArrays.newFloatArray(1, false); + /* + * Enable group id tracking because we use has hasValue in the + * collection itself to detect the when a value first arrives. + */ + enableGroupIdTracking(new SeenGroupIds.Empty()); success = true; } finally { if (success == false) { diff --git a/x-pack/plugin/esql/compute/src/main/generated-src/org/elasticsearch/compute/aggregation/FirstIntByTimestampAggregator.java b/x-pack/plugin/esql/compute/src/main/generated-src/org/elasticsearch/compute/aggregation/FirstIntByTimestampAggregator.java index 0c463b27570a0..745b72b9b1dcb 100644 --- a/x-pack/plugin/esql/compute/src/main/generated-src/org/elasticsearch/compute/aggregation/FirstIntByTimestampAggregator.java +++ b/x-pack/plugin/esql/compute/src/main/generated-src/org/elasticsearch/compute/aggregation/FirstIntByTimestampAggregator.java @@ -27,10 +27,42 @@ * A time-series aggregation function that collects the First occurrence value of a time series in a specified interval. * This class is generated. Edit `X-ValueByTimestampAggregator.java.st` instead. */ +@Aggregator( + { + @IntermediateState(name = "timestamps", type = "LONG"), + @IntermediateState(name = "values", type = "INT"), + @IntermediateState(name = "seen", type = "BOOLEAN") } +) @GroupingAggregator( { @IntermediateState(name = "timestamps", type = "LONG_BLOCK"), @IntermediateState(name = "values", type = "INT_BLOCK") } ) public class FirstIntByTimestampAggregator { + public static String describe() { + return "first_int_by_timestamp"; + } + + public static LongIntState initSingle(DriverContext driverContext) { + return new LongIntState(0, 0); + } + + public static void combine(LongIntState current, int value, long timestamp) { + if (timestamp < current.v1()) { + current.v1(timestamp); + current.v2(value); + } + } + + public static void combineIntermediate(LongIntState current, long timestamp, int value, boolean seen) { + if (seen) { + current.seen(true); + combine(current, value, timestamp); + } + } + + public static Block evaluateFinal(LongIntState current, DriverContext ctx) { + return ctx.blockFactory().newConstantIntBlockWith(current.v2(), 1); + } + public static GroupingState initGrouping(DriverContext driverContext) { return new GroupingState(driverContext.bigArrays()); } @@ -76,6 +108,11 @@ public static final class GroupingState extends AbstractArrayState { timestamps = bigArrays.newLongArray(1, false); this.timestamps = timestamps; this.values = bigArrays.newIntArray(1, false); + /* + * Enable group id tracking because we use has hasValue in the + * collection itself to detect the when a value first arrives. + */ + enableGroupIdTracking(new SeenGroupIds.Empty()); success = true; } finally { if (success == false) { diff --git a/x-pack/plugin/esql/compute/src/main/generated-src/org/elasticsearch/compute/aggregation/FirstLongByTimestampAggregator.java b/x-pack/plugin/esql/compute/src/main/generated-src/org/elasticsearch/compute/aggregation/FirstLongByTimestampAggregator.java index b213bc0e5b1fa..28a4335f6469f 100644 --- a/x-pack/plugin/esql/compute/src/main/generated-src/org/elasticsearch/compute/aggregation/FirstLongByTimestampAggregator.java +++ b/x-pack/plugin/esql/compute/src/main/generated-src/org/elasticsearch/compute/aggregation/FirstLongByTimestampAggregator.java @@ -27,10 +27,42 @@ * A time-series aggregation function that collects the First occurrence value of a time series in a specified interval. * This class is generated. Edit `X-ValueByTimestampAggregator.java.st` instead. */ +@Aggregator( + { + @IntermediateState(name = "timestamps", type = "LONG"), + @IntermediateState(name = "values", type = "LONG"), + @IntermediateState(name = "seen", type = "BOOLEAN") } +) @GroupingAggregator( { @IntermediateState(name = "timestamps", type = "LONG_BLOCK"), @IntermediateState(name = "values", type = "LONG_BLOCK") } ) public class FirstLongByTimestampAggregator { + public static String describe() { + return "first_long_by_timestamp"; + } + + public static LongLongState initSingle(DriverContext driverContext) { + return new LongLongState(0, 0); + } + + public static void combine(LongLongState current, long value, long timestamp) { + if (timestamp < current.v1()) { + current.v1(timestamp); + current.v2(value); + } + } + + public static void combineIntermediate(LongLongState current, long timestamp, long value, boolean seen) { + if (seen) { + current.seen(true); + combine(current, value, timestamp); + } + } + + public static Block evaluateFinal(LongLongState current, DriverContext ctx) { + return ctx.blockFactory().newConstantLongBlockWith(current.v2(), 1); + } + public static GroupingState initGrouping(DriverContext driverContext) { return new GroupingState(driverContext.bigArrays()); } @@ -76,6 +108,11 @@ public static final class GroupingState extends AbstractArrayState { timestamps = bigArrays.newLongArray(1, false); this.timestamps = timestamps; this.values = bigArrays.newLongArray(1, false); + /* + * Enable group id tracking because we use has hasValue in the + * collection itself to detect the when a value first arrives. + */ + enableGroupIdTracking(new SeenGroupIds.Empty()); success = true; } finally { if (success == false) { diff --git a/x-pack/plugin/esql/compute/src/main/generated-src/org/elasticsearch/compute/aggregation/LastDoubleByTimestampAggregator.java b/x-pack/plugin/esql/compute/src/main/generated-src/org/elasticsearch/compute/aggregation/LastDoubleByTimestampAggregator.java index 6bc04ec72f2b9..1e0b536e04929 100644 --- a/x-pack/plugin/esql/compute/src/main/generated-src/org/elasticsearch/compute/aggregation/LastDoubleByTimestampAggregator.java +++ b/x-pack/plugin/esql/compute/src/main/generated-src/org/elasticsearch/compute/aggregation/LastDoubleByTimestampAggregator.java @@ -27,10 +27,42 @@ * A time-series aggregation function that collects the Last occurrence value of a time series in a specified interval. * This class is generated. Edit `X-ValueByTimestampAggregator.java.st` instead. */ +@Aggregator( + { + @IntermediateState(name = "timestamps", type = "LONG"), + @IntermediateState(name = "values", type = "DOUBLE"), + @IntermediateState(name = "seen", type = "BOOLEAN") } +) @GroupingAggregator( { @IntermediateState(name = "timestamps", type = "LONG_BLOCK"), @IntermediateState(name = "values", type = "DOUBLE_BLOCK") } ) public class LastDoubleByTimestampAggregator { + public static String describe() { + return "last_double_by_timestamp"; + } + + public static LongDoubleState initSingle(DriverContext driverContext) { + return new LongDoubleState(0, 0); + } + + public static void combine(LongDoubleState current, double value, long timestamp) { + if (timestamp > current.v1()) { + current.v1(timestamp); + current.v2(value); + } + } + + public static void combineIntermediate(LongDoubleState current, long timestamp, double value, boolean seen) { + if (seen) { + current.seen(true); + combine(current, value, timestamp); + } + } + + public static Block evaluateFinal(LongDoubleState current, DriverContext ctx) { + return ctx.blockFactory().newConstantDoubleBlockWith(current.v2(), 1); + } + public static GroupingState initGrouping(DriverContext driverContext) { return new GroupingState(driverContext.bigArrays()); } @@ -76,6 +108,11 @@ public static final class GroupingState extends AbstractArrayState { timestamps = bigArrays.newLongArray(1, false); this.timestamps = timestamps; this.values = bigArrays.newDoubleArray(1, false); + /* + * Enable group id tracking because we use has hasValue in the + * collection itself to detect the when a value first arrives. + */ + enableGroupIdTracking(new SeenGroupIds.Empty()); success = true; } finally { if (success == false) { diff --git a/x-pack/plugin/esql/compute/src/main/generated-src/org/elasticsearch/compute/aggregation/LastFloatByTimestampAggregator.java b/x-pack/plugin/esql/compute/src/main/generated-src/org/elasticsearch/compute/aggregation/LastFloatByTimestampAggregator.java index 9d997027c58da..32d1c4b818376 100644 --- a/x-pack/plugin/esql/compute/src/main/generated-src/org/elasticsearch/compute/aggregation/LastFloatByTimestampAggregator.java +++ b/x-pack/plugin/esql/compute/src/main/generated-src/org/elasticsearch/compute/aggregation/LastFloatByTimestampAggregator.java @@ -27,10 +27,42 @@ * A time-series aggregation function that collects the Last occurrence value of a time series in a specified interval. * This class is generated. Edit `X-ValueByTimestampAggregator.java.st` instead. */ +@Aggregator( + { + @IntermediateState(name = "timestamps", type = "LONG"), + @IntermediateState(name = "values", type = "FLOAT"), + @IntermediateState(name = "seen", type = "BOOLEAN") } +) @GroupingAggregator( { @IntermediateState(name = "timestamps", type = "LONG_BLOCK"), @IntermediateState(name = "values", type = "FLOAT_BLOCK") } ) public class LastFloatByTimestampAggregator { + public static String describe() { + return "last_float_by_timestamp"; + } + + public static LongFloatState initSingle(DriverContext driverContext) { + return new LongFloatState(0, 0); + } + + public static void combine(LongFloatState current, float value, long timestamp) { + if (timestamp > current.v1()) { + current.v1(timestamp); + current.v2(value); + } + } + + public static void combineIntermediate(LongFloatState current, long timestamp, float value, boolean seen) { + if (seen) { + current.seen(true); + combine(current, value, timestamp); + } + } + + public static Block evaluateFinal(LongFloatState current, DriverContext ctx) { + return ctx.blockFactory().newConstantFloatBlockWith(current.v2(), 1); + } + public static GroupingState initGrouping(DriverContext driverContext) { return new GroupingState(driverContext.bigArrays()); } @@ -76,6 +108,11 @@ public static final class GroupingState extends AbstractArrayState { timestamps = bigArrays.newLongArray(1, false); this.timestamps = timestamps; this.values = bigArrays.newFloatArray(1, false); + /* + * Enable group id tracking because we use has hasValue in the + * collection itself to detect the when a value first arrives. + */ + enableGroupIdTracking(new SeenGroupIds.Empty()); success = true; } finally { if (success == false) { diff --git a/x-pack/plugin/esql/compute/src/main/generated-src/org/elasticsearch/compute/aggregation/LastIntByTimestampAggregator.java b/x-pack/plugin/esql/compute/src/main/generated-src/org/elasticsearch/compute/aggregation/LastIntByTimestampAggregator.java index 2549b26de5e40..6997b0d21bc8f 100644 --- a/x-pack/plugin/esql/compute/src/main/generated-src/org/elasticsearch/compute/aggregation/LastIntByTimestampAggregator.java +++ b/x-pack/plugin/esql/compute/src/main/generated-src/org/elasticsearch/compute/aggregation/LastIntByTimestampAggregator.java @@ -27,10 +27,42 @@ * A time-series aggregation function that collects the Last occurrence value of a time series in a specified interval. * This class is generated. Edit `X-ValueByTimestampAggregator.java.st` instead. */ +@Aggregator( + { + @IntermediateState(name = "timestamps", type = "LONG"), + @IntermediateState(name = "values", type = "INT"), + @IntermediateState(name = "seen", type = "BOOLEAN") } +) @GroupingAggregator( { @IntermediateState(name = "timestamps", type = "LONG_BLOCK"), @IntermediateState(name = "values", type = "INT_BLOCK") } ) public class LastIntByTimestampAggregator { + public static String describe() { + return "last_int_by_timestamp"; + } + + public static LongIntState initSingle(DriverContext driverContext) { + return new LongIntState(0, 0); + } + + public static void combine(LongIntState current, int value, long timestamp) { + if (timestamp > current.v1()) { + current.v1(timestamp); + current.v2(value); + } + } + + public static void combineIntermediate(LongIntState current, long timestamp, int value, boolean seen) { + if (seen) { + current.seen(true); + combine(current, value, timestamp); + } + } + + public static Block evaluateFinal(LongIntState current, DriverContext ctx) { + return ctx.blockFactory().newConstantIntBlockWith(current.v2(), 1); + } + public static GroupingState initGrouping(DriverContext driverContext) { return new GroupingState(driverContext.bigArrays()); } @@ -76,6 +108,11 @@ public static final class GroupingState extends AbstractArrayState { timestamps = bigArrays.newLongArray(1, false); this.timestamps = timestamps; this.values = bigArrays.newIntArray(1, false); + /* + * Enable group id tracking because we use has hasValue in the + * collection itself to detect the when a value first arrives. + */ + enableGroupIdTracking(new SeenGroupIds.Empty()); success = true; } finally { if (success == false) { diff --git a/x-pack/plugin/esql/compute/src/main/generated-src/org/elasticsearch/compute/aggregation/LastLongByTimestampAggregator.java b/x-pack/plugin/esql/compute/src/main/generated-src/org/elasticsearch/compute/aggregation/LastLongByTimestampAggregator.java index 4288565f6b321..cfc09c3f5670d 100644 --- a/x-pack/plugin/esql/compute/src/main/generated-src/org/elasticsearch/compute/aggregation/LastLongByTimestampAggregator.java +++ b/x-pack/plugin/esql/compute/src/main/generated-src/org/elasticsearch/compute/aggregation/LastLongByTimestampAggregator.java @@ -27,10 +27,42 @@ * A time-series aggregation function that collects the Last occurrence value of a time series in a specified interval. * This class is generated. Edit `X-ValueByTimestampAggregator.java.st` instead. */ +@Aggregator( + { + @IntermediateState(name = "timestamps", type = "LONG"), + @IntermediateState(name = "values", type = "LONG"), + @IntermediateState(name = "seen", type = "BOOLEAN") } +) @GroupingAggregator( { @IntermediateState(name = "timestamps", type = "LONG_BLOCK"), @IntermediateState(name = "values", type = "LONG_BLOCK") } ) public class LastLongByTimestampAggregator { + public static String describe() { + return "last_long_by_timestamp"; + } + + public static LongLongState initSingle(DriverContext driverContext) { + return new LongLongState(0, 0); + } + + public static void combine(LongLongState current, long value, long timestamp) { + if (timestamp > current.v1()) { + current.v1(timestamp); + current.v2(value); + } + } + + public static void combineIntermediate(LongLongState current, long timestamp, long value, boolean seen) { + if (seen) { + current.seen(true); + combine(current, value, timestamp); + } + } + + public static Block evaluateFinal(LongLongState current, DriverContext ctx) { + return ctx.blockFactory().newConstantLongBlockWith(current.v2(), 1); + } + public static GroupingState initGrouping(DriverContext driverContext) { return new GroupingState(driverContext.bigArrays()); } @@ -76,6 +108,11 @@ public static final class GroupingState extends AbstractArrayState { timestamps = bigArrays.newLongArray(1, false); this.timestamps = timestamps; this.values = bigArrays.newLongArray(1, false); + /* + * Enable group id tracking because we use has hasValue in the + * collection itself to detect the when a value first arrives. + */ + enableGroupIdTracking(new SeenGroupIds.Empty()); success = true; } finally { if (success == false) { diff --git a/x-pack/plugin/esql/compute/src/main/generated-src/org/elasticsearch/compute/aggregation/LongDoubleState.java b/x-pack/plugin/esql/compute/src/main/generated-src/org/elasticsearch/compute/aggregation/LongDoubleState.java new file mode 100644 index 0000000000000..47647d3179f47 --- /dev/null +++ b/x-pack/plugin/esql/compute/src/main/generated-src/org/elasticsearch/compute/aggregation/LongDoubleState.java @@ -0,0 +1,62 @@ +/* + * 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.compute.data.Block; +import org.elasticsearch.compute.operator.DriverContext; + +/** + * Aggregator state for a single {@code long} and a single {@code double}. + * This class is generated. Edit {@code X-2State.java.st} instead. + */ +final class LongDoubleState implements AggregatorState { + private long v1; + private double v2; + private boolean seen; + + LongDoubleState(long v1, double v2) { + this.v1 = v1; + this.v2 = v2; + } + + long v1() { + return v1; + } + + void v1(long v1) { + this.v1 = v1; + } + + double v2() { + return v2; + } + + void v2(double v2) { + this.v2 = v2; + } + + boolean seen() { + return seen; + } + + void seen(boolean seen) { + this.seen = seen; + } + + /** Extracts an intermediate view of the contents of this state. */ + @Override + public void toIntermediate(Block[] blocks, int offset, DriverContext driverContext) { + assert blocks.length >= offset + 3; + blocks[offset + 0] = driverContext.blockFactory().newConstantLongBlockWith(v1, 1); + blocks[offset + 1] = driverContext.blockFactory().newConstantDoubleBlockWith(v2, 1); + blocks[offset + 2] = driverContext.blockFactory().newConstantBooleanBlockWith(seen, 1); + } + + @Override + public void close() {} +} diff --git a/x-pack/plugin/esql/compute/src/main/generated-src/org/elasticsearch/compute/aggregation/LongFloatState.java b/x-pack/plugin/esql/compute/src/main/generated-src/org/elasticsearch/compute/aggregation/LongFloatState.java new file mode 100644 index 0000000000000..0c96f31bca7de --- /dev/null +++ b/x-pack/plugin/esql/compute/src/main/generated-src/org/elasticsearch/compute/aggregation/LongFloatState.java @@ -0,0 +1,62 @@ +/* + * 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.compute.data.Block; +import org.elasticsearch.compute.operator.DriverContext; + +/** + * Aggregator state for a single {@code long} and a single {@code float}. + * This class is generated. Edit {@code X-2State.java.st} instead. + */ +final class LongFloatState implements AggregatorState { + private long v1; + private float v2; + private boolean seen; + + LongFloatState(long v1, float v2) { + this.v1 = v1; + this.v2 = v2; + } + + long v1() { + return v1; + } + + void v1(long v1) { + this.v1 = v1; + } + + float v2() { + return v2; + } + + void v2(float v2) { + this.v2 = v2; + } + + boolean seen() { + return seen; + } + + void seen(boolean seen) { + this.seen = seen; + } + + /** Extracts an intermediate view of the contents of this state. */ + @Override + public void toIntermediate(Block[] blocks, int offset, DriverContext driverContext) { + assert blocks.length >= offset + 3; + blocks[offset + 0] = driverContext.blockFactory().newConstantLongBlockWith(v1, 1); + blocks[offset + 1] = driverContext.blockFactory().newConstantFloatBlockWith(v2, 1); + blocks[offset + 2] = driverContext.blockFactory().newConstantBooleanBlockWith(seen, 1); + } + + @Override + public void close() {} +} diff --git a/x-pack/plugin/esql/compute/src/main/generated-src/org/elasticsearch/compute/aggregation/LongIntState.java b/x-pack/plugin/esql/compute/src/main/generated-src/org/elasticsearch/compute/aggregation/LongIntState.java new file mode 100644 index 0000000000000..11ad9acc19334 --- /dev/null +++ b/x-pack/plugin/esql/compute/src/main/generated-src/org/elasticsearch/compute/aggregation/LongIntState.java @@ -0,0 +1,62 @@ +/* + * 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.compute.data.Block; +import org.elasticsearch.compute.operator.DriverContext; + +/** + * Aggregator state for a single {@code long} and a single {@code int}. + * This class is generated. Edit {@code X-2State.java.st} instead. + */ +final class LongIntState implements AggregatorState { + private long v1; + private int v2; + private boolean seen; + + LongIntState(long v1, int v2) { + this.v1 = v1; + this.v2 = v2; + } + + long v1() { + return v1; + } + + void v1(long v1) { + this.v1 = v1; + } + + int v2() { + return v2; + } + + void v2(int v2) { + this.v2 = v2; + } + + boolean seen() { + return seen; + } + + void seen(boolean seen) { + this.seen = seen; + } + + /** Extracts an intermediate view of the contents of this state. */ + @Override + public void toIntermediate(Block[] blocks, int offset, DriverContext driverContext) { + assert blocks.length >= offset + 3; + blocks[offset + 0] = driverContext.blockFactory().newConstantLongBlockWith(v1, 1); + blocks[offset + 1] = driverContext.blockFactory().newConstantIntBlockWith(v2, 1); + blocks[offset + 2] = driverContext.blockFactory().newConstantBooleanBlockWith(seen, 1); + } + + @Override + public void close() {} +} diff --git a/x-pack/plugin/esql/compute/src/main/generated-src/org/elasticsearch/compute/aggregation/LongLongState.java b/x-pack/plugin/esql/compute/src/main/generated-src/org/elasticsearch/compute/aggregation/LongLongState.java new file mode 100644 index 0000000000000..ce5867bdaa884 --- /dev/null +++ b/x-pack/plugin/esql/compute/src/main/generated-src/org/elasticsearch/compute/aggregation/LongLongState.java @@ -0,0 +1,62 @@ +/* + * 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.compute.data.Block; +import org.elasticsearch.compute.operator.DriverContext; + +/** + * Aggregator state for a single {@code long} and a single {@code long}. + * This class is generated. Edit {@code X-2State.java.st} instead. + */ +final class LongLongState implements AggregatorState { + private long v1; + private long v2; + private boolean seen; + + LongLongState(long v1, long v2) { + this.v1 = v1; + this.v2 = v2; + } + + long v1() { + return v1; + } + + void v1(long v1) { + this.v1 = v1; + } + + long v2() { + return v2; + } + + void v2(long v2) { + this.v2 = v2; + } + + boolean seen() { + return seen; + } + + void seen(boolean seen) { + this.seen = seen; + } + + /** Extracts an intermediate view of the contents of this state. */ + @Override + public void toIntermediate(Block[] blocks, int offset, DriverContext driverContext) { + assert blocks.length >= offset + 3; + blocks[offset + 0] = driverContext.blockFactory().newConstantLongBlockWith(v1, 1); + blocks[offset + 1] = driverContext.blockFactory().newConstantLongBlockWith(v2, 1); + blocks[offset + 2] = driverContext.blockFactory().newConstantBooleanBlockWith(seen, 1); + } + + @Override + public void close() {} +} diff --git a/x-pack/plugin/esql/compute/src/main/generated/org/elasticsearch/compute/aggregation/CountDistinctBooleanGroupingAggregatorFunction.java b/x-pack/plugin/esql/compute/src/main/generated/org/elasticsearch/compute/aggregation/CountDistinctBooleanGroupingAggregatorFunction.java index 2e0712ef507ca..d91a5476f60c0 100644 --- a/x-pack/plugin/esql/compute/src/main/generated/org/elasticsearch/compute/aggregation/CountDistinctBooleanGroupingAggregatorFunction.java +++ b/x-pack/plugin/esql/compute/src/main/generated/org/elasticsearch/compute/aggregation/CountDistinctBooleanGroupingAggregatorFunction.java @@ -61,9 +61,7 @@ public GroupingAggregatorFunction.AddInput prepareProcessRawInputPage(SeenGroupI BooleanBlock vBlock = page.getBlock(channels.get(0)); BooleanVector vVector = vBlock.asVector(); if (vVector == null) { - if (vBlock.mayHaveNulls()) { - state.enableGroupIdTracking(seenGroupIds); - } + maybeEnableGroupIdTracking(seenGroupIds, vBlock); return new GroupingAggregatorFunction.AddInput() { @Override public void add(int positionOffset, IntArrayBlock groupIds) { @@ -290,6 +288,12 @@ public void addIntermediateInput(int positionOffset, IntVector groups, Page page } } + private void maybeEnableGroupIdTracking(SeenGroupIds seenGroupIds, BooleanBlock vBlock) { + if (vBlock.mayHaveNulls()) { + state.enableGroupIdTracking(seenGroupIds); + } + } + @Override public void selectedMayContainUnseenGroups(SeenGroupIds seenGroupIds) { state.enableGroupIdTracking(seenGroupIds); 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 925253b43e0b1..1abea90e89ee3 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 @@ -64,9 +64,7 @@ public GroupingAggregatorFunction.AddInput prepareProcessRawInputPage(SeenGroupI BytesRefBlock vBlock = page.getBlock(channels.get(0)); BytesRefVector vVector = vBlock.asVector(); if (vVector == null) { - if (vBlock.mayHaveNulls()) { - state.enableGroupIdTracking(seenGroupIds); - } + maybeEnableGroupIdTracking(seenGroupIds, vBlock); return new GroupingAggregatorFunction.AddInput() { @Override public void add(int positionOffset, IntArrayBlock groupIds) { @@ -284,6 +282,12 @@ public void addIntermediateInput(int positionOffset, IntVector groups, Page page } } + private void maybeEnableGroupIdTracking(SeenGroupIds seenGroupIds, BytesRefBlock vBlock) { + if (vBlock.mayHaveNulls()) { + state.enableGroupIdTracking(seenGroupIds); + } + } + @Override public void selectedMayContainUnseenGroups(SeenGroupIds seenGroupIds) { state.enableGroupIdTracking(seenGroupIds); 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 e607aeafc5aab..c839f787c991f 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 @@ -66,9 +66,7 @@ public GroupingAggregatorFunction.AddInput prepareProcessRawInputPage(SeenGroupI DoubleBlock vBlock = page.getBlock(channels.get(0)); DoubleVector vVector = vBlock.asVector(); if (vVector == null) { - if (vBlock.mayHaveNulls()) { - state.enableGroupIdTracking(seenGroupIds); - } + maybeEnableGroupIdTracking(seenGroupIds, vBlock); return new GroupingAggregatorFunction.AddInput() { @Override public void add(int positionOffset, IntArrayBlock groupIds) { @@ -280,6 +278,12 @@ public void addIntermediateInput(int positionOffset, IntVector groups, Page page } } + private void maybeEnableGroupIdTracking(SeenGroupIds seenGroupIds, DoubleBlock vBlock) { + if (vBlock.mayHaveNulls()) { + state.enableGroupIdTracking(seenGroupIds); + } + } + @Override public void selectedMayContainUnseenGroups(SeenGroupIds seenGroupIds) { state.enableGroupIdTracking(seenGroupIds); 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 873f63ab3d68b..a8f284f7e8fdc 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 @@ -66,9 +66,7 @@ public GroupingAggregatorFunction.AddInput prepareProcessRawInputPage(SeenGroupI FloatBlock vBlock = page.getBlock(channels.get(0)); FloatVector vVector = vBlock.asVector(); if (vVector == null) { - if (vBlock.mayHaveNulls()) { - state.enableGroupIdTracking(seenGroupIds); - } + maybeEnableGroupIdTracking(seenGroupIds, vBlock); return new GroupingAggregatorFunction.AddInput() { @Override public void add(int positionOffset, IntArrayBlock groupIds) { @@ -280,6 +278,12 @@ public void addIntermediateInput(int positionOffset, IntVector groups, Page page } } + private void maybeEnableGroupIdTracking(SeenGroupIds seenGroupIds, FloatBlock vBlock) { + if (vBlock.mayHaveNulls()) { + state.enableGroupIdTracking(seenGroupIds); + } + } + @Override public void selectedMayContainUnseenGroups(SeenGroupIds seenGroupIds) { state.enableGroupIdTracking(seenGroupIds); 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 1b4e7f7f3fd53..ad7e329d8ea7d 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 @@ -65,9 +65,7 @@ public GroupingAggregatorFunction.AddInput prepareProcessRawInputPage(SeenGroupI IntBlock vBlock = page.getBlock(channels.get(0)); IntVector vVector = vBlock.asVector(); if (vVector == null) { - if (vBlock.mayHaveNulls()) { - state.enableGroupIdTracking(seenGroupIds); - } + maybeEnableGroupIdTracking(seenGroupIds, vBlock); return new GroupingAggregatorFunction.AddInput() { @Override public void add(int positionOffset, IntArrayBlock groupIds) { @@ -279,6 +277,12 @@ public void addIntermediateInput(int positionOffset, IntVector groups, Page page } } + private void maybeEnableGroupIdTracking(SeenGroupIds seenGroupIds, IntBlock vBlock) { + if (vBlock.mayHaveNulls()) { + state.enableGroupIdTracking(seenGroupIds); + } + } + @Override public void selectedMayContainUnseenGroups(SeenGroupIds seenGroupIds) { state.enableGroupIdTracking(seenGroupIds); 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 47608975a8f6b..8bdff2e73ebb9 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 @@ -66,9 +66,7 @@ public GroupingAggregatorFunction.AddInput prepareProcessRawInputPage(SeenGroupI LongBlock vBlock = page.getBlock(channels.get(0)); LongVector vVector = vBlock.asVector(); if (vVector == null) { - if (vBlock.mayHaveNulls()) { - state.enableGroupIdTracking(seenGroupIds); - } + maybeEnableGroupIdTracking(seenGroupIds, vBlock); return new GroupingAggregatorFunction.AddInput() { @Override public void add(int positionOffset, IntArrayBlock groupIds) { @@ -280,6 +278,12 @@ public void addIntermediateInput(int positionOffset, IntVector groups, Page page } } + private void maybeEnableGroupIdTracking(SeenGroupIds seenGroupIds, LongBlock vBlock) { + if (vBlock.mayHaveNulls()) { + state.enableGroupIdTracking(seenGroupIds); + } + } + @Override public void selectedMayContainUnseenGroups(SeenGroupIds seenGroupIds) { state.enableGroupIdTracking(seenGroupIds); diff --git a/x-pack/plugin/esql/compute/src/main/generated/org/elasticsearch/compute/aggregation/FirstDoubleByTimestampAggregatorFunction.java b/x-pack/plugin/esql/compute/src/main/generated/org/elasticsearch/compute/aggregation/FirstDoubleByTimestampAggregatorFunction.java new file mode 100644 index 0000000000000..ca12dd6f36482 --- /dev/null +++ b/x-pack/plugin/esql/compute/src/main/generated/org/elasticsearch/compute/aggregation/FirstDoubleByTimestampAggregatorFunction.java @@ -0,0 +1,226 @@ +// 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.BooleanBlock; +import org.elasticsearch.compute.data.BooleanVector; +import org.elasticsearch.compute.data.DoubleBlock; +import org.elasticsearch.compute.data.DoubleVector; +import org.elasticsearch.compute.data.ElementType; +import org.elasticsearch.compute.data.LongBlock; +import org.elasticsearch.compute.data.LongVector; +import org.elasticsearch.compute.data.Page; +import org.elasticsearch.compute.operator.DriverContext; + +/** + * {@link AggregatorFunction} implementation for {@link FirstDoubleByTimestampAggregator}. + * This class is generated. Edit {@code AggregatorImplementer} instead. + */ +public final class FirstDoubleByTimestampAggregatorFunction implements AggregatorFunction { + private static final List INTERMEDIATE_STATE_DESC = List.of( + new IntermediateStateDesc("timestamps", ElementType.LONG), + new IntermediateStateDesc("values", ElementType.DOUBLE), + new IntermediateStateDesc("seen", ElementType.BOOLEAN) ); + + private final DriverContext driverContext; + + private final LongDoubleState state; + + private final List channels; + + public FirstDoubleByTimestampAggregatorFunction(DriverContext driverContext, + List channels, LongDoubleState state) { + this.driverContext = driverContext; + this.channels = channels; + this.state = state; + } + + public static FirstDoubleByTimestampAggregatorFunction create(DriverContext driverContext, + List channels) { + return new FirstDoubleByTimestampAggregatorFunction(driverContext, channels, FirstDoubleByTimestampAggregator.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) { + DoubleBlock valueBlock = page.getBlock(channels.get(0)); + LongBlock timestampBlock = page.getBlock(channels.get(1)); + DoubleVector valueVector = valueBlock.asVector(); + if (valueVector == null) { + addRawBlock(valueBlock, timestampBlock, mask); + return; + } + LongVector timestampVector = timestampBlock.asVector(); + if (timestampVector == null) { + addRawBlock(valueBlock, timestampBlock, mask); + return; + } + addRawVector(valueVector, timestampVector, mask); + } + + private void addRawInputNotMasked(Page page) { + DoubleBlock valueBlock = page.getBlock(channels.get(0)); + LongBlock timestampBlock = page.getBlock(channels.get(1)); + DoubleVector valueVector = valueBlock.asVector(); + if (valueVector == null) { + addRawBlock(valueBlock, timestampBlock); + return; + } + LongVector timestampVector = timestampBlock.asVector(); + if (timestampVector == null) { + addRawBlock(valueBlock, timestampBlock); + return; + } + addRawVector(valueVector, timestampVector); + } + + private void addRawVector(DoubleVector valueVector, LongVector timestampVector) { + state.seen(true); + for (int valuesPosition = 0; valuesPosition < valueVector.getPositionCount(); valuesPosition++) { + double valueValue = valueVector.getDouble(valuesPosition); + long timestampValue = timestampVector.getLong(valuesPosition); + FirstDoubleByTimestampAggregator.combine(state, valueValue, timestampValue); + } + } + + private void addRawVector(DoubleVector valueVector, LongVector timestampVector, + BooleanVector mask) { + state.seen(true); + for (int valuesPosition = 0; valuesPosition < valueVector.getPositionCount(); valuesPosition++) { + if (mask.getBoolean(valuesPosition) == false) { + continue; + } + double valueValue = valueVector.getDouble(valuesPosition); + long timestampValue = timestampVector.getLong(valuesPosition); + FirstDoubleByTimestampAggregator.combine(state, valueValue, timestampValue); + } + } + + private void addRawBlock(DoubleBlock valueBlock, LongBlock timestampBlock) { + for (int p = 0; p < valueBlock.getPositionCount(); p++) { + if (valueBlock.isNull(p)) { + continue; + } + if (timestampBlock.isNull(p)) { + continue; + } + state.seen(true); + int valueStart = valueBlock.getFirstValueIndex(p); + int valueEnd = valueStart + valueBlock.getValueCount(p); + for (int valueOffset = valueStart; valueOffset < valueEnd; valueOffset++) { + double valueValue = valueBlock.getDouble(valueOffset); + int timestampStart = timestampBlock.getFirstValueIndex(p); + int timestampEnd = timestampStart + timestampBlock.getValueCount(p); + for (int timestampOffset = timestampStart; timestampOffset < timestampEnd; timestampOffset++) { + long timestampValue = timestampBlock.getLong(timestampOffset); + FirstDoubleByTimestampAggregator.combine(state, valueValue, timestampValue); + } + } + } + } + + private void addRawBlock(DoubleBlock valueBlock, LongBlock timestampBlock, BooleanVector mask) { + for (int p = 0; p < valueBlock.getPositionCount(); p++) { + if (mask.getBoolean(p) == false) { + continue; + } + if (valueBlock.isNull(p)) { + continue; + } + if (timestampBlock.isNull(p)) { + continue; + } + state.seen(true); + int valueStart = valueBlock.getFirstValueIndex(p); + int valueEnd = valueStart + valueBlock.getValueCount(p); + for (int valueOffset = valueStart; valueOffset < valueEnd; valueOffset++) { + double valueValue = valueBlock.getDouble(valueOffset); + int timestampStart = timestampBlock.getFirstValueIndex(p); + int timestampEnd = timestampStart + timestampBlock.getValueCount(p); + for (int timestampOffset = timestampStart; timestampOffset < timestampEnd; timestampOffset++) { + long timestampValue = timestampBlock.getLong(timestampOffset); + FirstDoubleByTimestampAggregator.combine(state, valueValue, timestampValue); + } + } + } + } + + @Override + public void addIntermediateInput(Page page) { + assert channels.size() == intermediateBlockCount(); + assert page.getBlockCount() >= channels.get(0) + intermediateStateDesc().size(); + Block timestampsUncast = page.getBlock(channels.get(0)); + if (timestampsUncast.areAllValuesNull()) { + return; + } + LongVector timestamps = ((LongBlock) timestampsUncast).asVector(); + assert timestamps.getPositionCount() == 1; + Block valuesUncast = page.getBlock(channels.get(1)); + if (valuesUncast.areAllValuesNull()) { + return; + } + DoubleVector values = ((DoubleBlock) valuesUncast).asVector(); + assert values.getPositionCount() == 1; + Block seenUncast = page.getBlock(channels.get(2)); + if (seenUncast.areAllValuesNull()) { + return; + } + BooleanVector seen = ((BooleanBlock) seenUncast).asVector(); + assert seen.getPositionCount() == 1; + FirstDoubleByTimestampAggregator.combineIntermediate(state, timestamps.getLong(0), values.getDouble(0), seen.getBoolean(0)); + } + + @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) { + if (state.seen() == false) { + blocks[offset] = driverContext.blockFactory().newConstantNullBlock(1); + return; + } + blocks[offset] = FirstDoubleByTimestampAggregator.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/FirstDoubleByTimestampAggregatorFunctionSupplier.java b/x-pack/plugin/esql/compute/src/main/generated/org/elasticsearch/compute/aggregation/FirstDoubleByTimestampAggregatorFunctionSupplier.java index 6ece08cd3d5bd..0b018ff150611 100644 --- a/x-pack/plugin/esql/compute/src/main/generated/org/elasticsearch/compute/aggregation/FirstDoubleByTimestampAggregatorFunctionSupplier.java +++ b/x-pack/plugin/esql/compute/src/main/generated/org/elasticsearch/compute/aggregation/FirstDoubleByTimestampAggregatorFunctionSupplier.java @@ -20,7 +20,7 @@ public FirstDoubleByTimestampAggregatorFunctionSupplier() { @Override public List nonGroupingIntermediateStateDesc() { - throw new UnsupportedOperationException("non-grouping aggregator is not supported"); + return FirstDoubleByTimestampAggregatorFunction.intermediateStateDesc(); } @Override @@ -29,8 +29,9 @@ public List groupingIntermediateStateDesc() { } @Override - public AggregatorFunction aggregator(DriverContext driverContext, List channels) { - throw new UnsupportedOperationException("non-grouping aggregator is not supported"); + public FirstDoubleByTimestampAggregatorFunction aggregator(DriverContext driverContext, + List channels) { + return FirstDoubleByTimestampAggregatorFunction.create(driverContext, channels); } @Override @@ -41,6 +42,6 @@ public FirstDoubleByTimestampGroupingAggregatorFunction groupingAggregator( @Override public String describe() { - return "first_double_by of timestamps"; + return FirstDoubleByTimestampAggregator.describe(); } } diff --git a/x-pack/plugin/esql/compute/src/main/generated/org/elasticsearch/compute/aggregation/FirstDoubleByTimestampGroupingAggregatorFunction.java b/x-pack/plugin/esql/compute/src/main/generated/org/elasticsearch/compute/aggregation/FirstDoubleByTimestampGroupingAggregatorFunction.java index aa64e2e9517b5..1071d07c173cd 100644 --- a/x-pack/plugin/esql/compute/src/main/generated/org/elasticsearch/compute/aggregation/FirstDoubleByTimestampGroupingAggregatorFunction.java +++ b/x-pack/plugin/esql/compute/src/main/generated/org/elasticsearch/compute/aggregation/FirstDoubleByTimestampGroupingAggregatorFunction.java @@ -64,9 +64,7 @@ public GroupingAggregatorFunction.AddInput prepareProcessRawInputPage(SeenGroupI LongBlock timestampBlock = page.getBlock(channels.get(1)); DoubleVector valueVector = valueBlock.asVector(); if (valueVector == null) { - if (valueBlock.mayHaveNulls()) { - state.enableGroupIdTracking(seenGroupIds); - } + maybeEnableGroupIdTracking(seenGroupIds, valueBlock, timestampBlock); return new GroupingAggregatorFunction.AddInput() { @Override public void add(int positionOffset, IntArrayBlock groupIds) { @@ -90,9 +88,7 @@ public void close() { } LongVector timestampVector = timestampBlock.asVector(); if (timestampVector == null) { - if (timestampBlock.mayHaveNulls()) { - state.enableGroupIdTracking(seenGroupIds); - } + maybeEnableGroupIdTracking(seenGroupIds, valueBlock, timestampBlock); return new GroupingAggregatorFunction.AddInput() { @Override public void add(int positionOffset, IntArrayBlock groupIds) { @@ -352,6 +348,16 @@ public void addIntermediateInput(int positionOffset, IntVector groups, Page page } } + private void maybeEnableGroupIdTracking(SeenGroupIds seenGroupIds, DoubleBlock valueBlock, + LongBlock timestampBlock) { + if (valueBlock.mayHaveNulls()) { + state.enableGroupIdTracking(seenGroupIds); + } + if (timestampBlock.mayHaveNulls()) { + state.enableGroupIdTracking(seenGroupIds); + } + } + @Override public void selectedMayContainUnseenGroups(SeenGroupIds seenGroupIds) { state.enableGroupIdTracking(seenGroupIds); diff --git a/x-pack/plugin/esql/compute/src/main/generated/org/elasticsearch/compute/aggregation/FirstFloatByTimestampAggregatorFunction.java b/x-pack/plugin/esql/compute/src/main/generated/org/elasticsearch/compute/aggregation/FirstFloatByTimestampAggregatorFunction.java new file mode 100644 index 0000000000000..a843202c3992b --- /dev/null +++ b/x-pack/plugin/esql/compute/src/main/generated/org/elasticsearch/compute/aggregation/FirstFloatByTimestampAggregatorFunction.java @@ -0,0 +1,226 @@ +// 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.BooleanBlock; +import org.elasticsearch.compute.data.BooleanVector; +import org.elasticsearch.compute.data.ElementType; +import org.elasticsearch.compute.data.FloatBlock; +import org.elasticsearch.compute.data.FloatVector; +import org.elasticsearch.compute.data.LongBlock; +import org.elasticsearch.compute.data.LongVector; +import org.elasticsearch.compute.data.Page; +import org.elasticsearch.compute.operator.DriverContext; + +/** + * {@link AggregatorFunction} implementation for {@link FirstFloatByTimestampAggregator}. + * This class is generated. Edit {@code AggregatorImplementer} instead. + */ +public final class FirstFloatByTimestampAggregatorFunction implements AggregatorFunction { + private static final List INTERMEDIATE_STATE_DESC = List.of( + new IntermediateStateDesc("timestamps", ElementType.LONG), + new IntermediateStateDesc("values", ElementType.FLOAT), + new IntermediateStateDesc("seen", ElementType.BOOLEAN) ); + + private final DriverContext driverContext; + + private final LongFloatState state; + + private final List channels; + + public FirstFloatByTimestampAggregatorFunction(DriverContext driverContext, + List channels, LongFloatState state) { + this.driverContext = driverContext; + this.channels = channels; + this.state = state; + } + + public static FirstFloatByTimestampAggregatorFunction create(DriverContext driverContext, + List channels) { + return new FirstFloatByTimestampAggregatorFunction(driverContext, channels, FirstFloatByTimestampAggregator.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) { + FloatBlock valueBlock = page.getBlock(channels.get(0)); + LongBlock timestampBlock = page.getBlock(channels.get(1)); + FloatVector valueVector = valueBlock.asVector(); + if (valueVector == null) { + addRawBlock(valueBlock, timestampBlock, mask); + return; + } + LongVector timestampVector = timestampBlock.asVector(); + if (timestampVector == null) { + addRawBlock(valueBlock, timestampBlock, mask); + return; + } + addRawVector(valueVector, timestampVector, mask); + } + + private void addRawInputNotMasked(Page page) { + FloatBlock valueBlock = page.getBlock(channels.get(0)); + LongBlock timestampBlock = page.getBlock(channels.get(1)); + FloatVector valueVector = valueBlock.asVector(); + if (valueVector == null) { + addRawBlock(valueBlock, timestampBlock); + return; + } + LongVector timestampVector = timestampBlock.asVector(); + if (timestampVector == null) { + addRawBlock(valueBlock, timestampBlock); + return; + } + addRawVector(valueVector, timestampVector); + } + + private void addRawVector(FloatVector valueVector, LongVector timestampVector) { + state.seen(true); + for (int valuesPosition = 0; valuesPosition < valueVector.getPositionCount(); valuesPosition++) { + float valueValue = valueVector.getFloat(valuesPosition); + long timestampValue = timestampVector.getLong(valuesPosition); + FirstFloatByTimestampAggregator.combine(state, valueValue, timestampValue); + } + } + + private void addRawVector(FloatVector valueVector, LongVector timestampVector, + BooleanVector mask) { + state.seen(true); + for (int valuesPosition = 0; valuesPosition < valueVector.getPositionCount(); valuesPosition++) { + if (mask.getBoolean(valuesPosition) == false) { + continue; + } + float valueValue = valueVector.getFloat(valuesPosition); + long timestampValue = timestampVector.getLong(valuesPosition); + FirstFloatByTimestampAggregator.combine(state, valueValue, timestampValue); + } + } + + private void addRawBlock(FloatBlock valueBlock, LongBlock timestampBlock) { + for (int p = 0; p < valueBlock.getPositionCount(); p++) { + if (valueBlock.isNull(p)) { + continue; + } + if (timestampBlock.isNull(p)) { + continue; + } + state.seen(true); + int valueStart = valueBlock.getFirstValueIndex(p); + int valueEnd = valueStart + valueBlock.getValueCount(p); + for (int valueOffset = valueStart; valueOffset < valueEnd; valueOffset++) { + float valueValue = valueBlock.getFloat(valueOffset); + int timestampStart = timestampBlock.getFirstValueIndex(p); + int timestampEnd = timestampStart + timestampBlock.getValueCount(p); + for (int timestampOffset = timestampStart; timestampOffset < timestampEnd; timestampOffset++) { + long timestampValue = timestampBlock.getLong(timestampOffset); + FirstFloatByTimestampAggregator.combine(state, valueValue, timestampValue); + } + } + } + } + + private void addRawBlock(FloatBlock valueBlock, LongBlock timestampBlock, BooleanVector mask) { + for (int p = 0; p < valueBlock.getPositionCount(); p++) { + if (mask.getBoolean(p) == false) { + continue; + } + if (valueBlock.isNull(p)) { + continue; + } + if (timestampBlock.isNull(p)) { + continue; + } + state.seen(true); + int valueStart = valueBlock.getFirstValueIndex(p); + int valueEnd = valueStart + valueBlock.getValueCount(p); + for (int valueOffset = valueStart; valueOffset < valueEnd; valueOffset++) { + float valueValue = valueBlock.getFloat(valueOffset); + int timestampStart = timestampBlock.getFirstValueIndex(p); + int timestampEnd = timestampStart + timestampBlock.getValueCount(p); + for (int timestampOffset = timestampStart; timestampOffset < timestampEnd; timestampOffset++) { + long timestampValue = timestampBlock.getLong(timestampOffset); + FirstFloatByTimestampAggregator.combine(state, valueValue, timestampValue); + } + } + } + } + + @Override + public void addIntermediateInput(Page page) { + assert channels.size() == intermediateBlockCount(); + assert page.getBlockCount() >= channels.get(0) + intermediateStateDesc().size(); + Block timestampsUncast = page.getBlock(channels.get(0)); + if (timestampsUncast.areAllValuesNull()) { + return; + } + LongVector timestamps = ((LongBlock) timestampsUncast).asVector(); + assert timestamps.getPositionCount() == 1; + Block valuesUncast = page.getBlock(channels.get(1)); + if (valuesUncast.areAllValuesNull()) { + return; + } + FloatVector values = ((FloatBlock) valuesUncast).asVector(); + assert values.getPositionCount() == 1; + Block seenUncast = page.getBlock(channels.get(2)); + if (seenUncast.areAllValuesNull()) { + return; + } + BooleanVector seen = ((BooleanBlock) seenUncast).asVector(); + assert seen.getPositionCount() == 1; + FirstFloatByTimestampAggregator.combineIntermediate(state, timestamps.getLong(0), values.getFloat(0), seen.getBoolean(0)); + } + + @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) { + if (state.seen() == false) { + blocks[offset] = driverContext.blockFactory().newConstantNullBlock(1); + return; + } + blocks[offset] = FirstFloatByTimestampAggregator.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/FirstFloatByTimestampAggregatorFunctionSupplier.java b/x-pack/plugin/esql/compute/src/main/generated/org/elasticsearch/compute/aggregation/FirstFloatByTimestampAggregatorFunctionSupplier.java index 046e3a5c09099..a5047c8c4795e 100644 --- a/x-pack/plugin/esql/compute/src/main/generated/org/elasticsearch/compute/aggregation/FirstFloatByTimestampAggregatorFunctionSupplier.java +++ b/x-pack/plugin/esql/compute/src/main/generated/org/elasticsearch/compute/aggregation/FirstFloatByTimestampAggregatorFunctionSupplier.java @@ -20,7 +20,7 @@ public FirstFloatByTimestampAggregatorFunctionSupplier() { @Override public List nonGroupingIntermediateStateDesc() { - throw new UnsupportedOperationException("non-grouping aggregator is not supported"); + return FirstFloatByTimestampAggregatorFunction.intermediateStateDesc(); } @Override @@ -29,8 +29,9 @@ public List groupingIntermediateStateDesc() { } @Override - public AggregatorFunction aggregator(DriverContext driverContext, List channels) { - throw new UnsupportedOperationException("non-grouping aggregator is not supported"); + public FirstFloatByTimestampAggregatorFunction aggregator(DriverContext driverContext, + List channels) { + return FirstFloatByTimestampAggregatorFunction.create(driverContext, channels); } @Override @@ -41,6 +42,6 @@ public FirstFloatByTimestampGroupingAggregatorFunction groupingAggregator( @Override public String describe() { - return "first_float_by of timestamps"; + return FirstFloatByTimestampAggregator.describe(); } } diff --git a/x-pack/plugin/esql/compute/src/main/generated/org/elasticsearch/compute/aggregation/FirstFloatByTimestampGroupingAggregatorFunction.java b/x-pack/plugin/esql/compute/src/main/generated/org/elasticsearch/compute/aggregation/FirstFloatByTimestampGroupingAggregatorFunction.java index e9780107df1c3..54ce2c9c0aa2c 100644 --- a/x-pack/plugin/esql/compute/src/main/generated/org/elasticsearch/compute/aggregation/FirstFloatByTimestampGroupingAggregatorFunction.java +++ b/x-pack/plugin/esql/compute/src/main/generated/org/elasticsearch/compute/aggregation/FirstFloatByTimestampGroupingAggregatorFunction.java @@ -64,9 +64,7 @@ public GroupingAggregatorFunction.AddInput prepareProcessRawInputPage(SeenGroupI LongBlock timestampBlock = page.getBlock(channels.get(1)); FloatVector valueVector = valueBlock.asVector(); if (valueVector == null) { - if (valueBlock.mayHaveNulls()) { - state.enableGroupIdTracking(seenGroupIds); - } + maybeEnableGroupIdTracking(seenGroupIds, valueBlock, timestampBlock); return new GroupingAggregatorFunction.AddInput() { @Override public void add(int positionOffset, IntArrayBlock groupIds) { @@ -90,9 +88,7 @@ public void close() { } LongVector timestampVector = timestampBlock.asVector(); if (timestampVector == null) { - if (timestampBlock.mayHaveNulls()) { - state.enableGroupIdTracking(seenGroupIds); - } + maybeEnableGroupIdTracking(seenGroupIds, valueBlock, timestampBlock); return new GroupingAggregatorFunction.AddInput() { @Override public void add(int positionOffset, IntArrayBlock groupIds) { @@ -352,6 +348,16 @@ public void addIntermediateInput(int positionOffset, IntVector groups, Page page } } + private void maybeEnableGroupIdTracking(SeenGroupIds seenGroupIds, FloatBlock valueBlock, + LongBlock timestampBlock) { + if (valueBlock.mayHaveNulls()) { + state.enableGroupIdTracking(seenGroupIds); + } + if (timestampBlock.mayHaveNulls()) { + state.enableGroupIdTracking(seenGroupIds); + } + } + @Override public void selectedMayContainUnseenGroups(SeenGroupIds seenGroupIds) { state.enableGroupIdTracking(seenGroupIds); diff --git a/x-pack/plugin/esql/compute/src/main/generated/org/elasticsearch/compute/aggregation/FirstIntByTimestampAggregatorFunction.java b/x-pack/plugin/esql/compute/src/main/generated/org/elasticsearch/compute/aggregation/FirstIntByTimestampAggregatorFunction.java new file mode 100644 index 0000000000000..bafe723529dd2 --- /dev/null +++ b/x-pack/plugin/esql/compute/src/main/generated/org/elasticsearch/compute/aggregation/FirstIntByTimestampAggregatorFunction.java @@ -0,0 +1,225 @@ +// 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.BooleanBlock; +import org.elasticsearch.compute.data.BooleanVector; +import org.elasticsearch.compute.data.ElementType; +import org.elasticsearch.compute.data.IntBlock; +import org.elasticsearch.compute.data.IntVector; +import org.elasticsearch.compute.data.LongBlock; +import org.elasticsearch.compute.data.LongVector; +import org.elasticsearch.compute.data.Page; +import org.elasticsearch.compute.operator.DriverContext; + +/** + * {@link AggregatorFunction} implementation for {@link FirstIntByTimestampAggregator}. + * This class is generated. Edit {@code AggregatorImplementer} instead. + */ +public final class FirstIntByTimestampAggregatorFunction implements AggregatorFunction { + private static final List INTERMEDIATE_STATE_DESC = List.of( + new IntermediateStateDesc("timestamps", ElementType.LONG), + new IntermediateStateDesc("values", ElementType.INT), + new IntermediateStateDesc("seen", ElementType.BOOLEAN) ); + + private final DriverContext driverContext; + + private final LongIntState state; + + private final List channels; + + public FirstIntByTimestampAggregatorFunction(DriverContext driverContext, List channels, + LongIntState state) { + this.driverContext = driverContext; + this.channels = channels; + this.state = state; + } + + public static FirstIntByTimestampAggregatorFunction create(DriverContext driverContext, + List channels) { + return new FirstIntByTimestampAggregatorFunction(driverContext, channels, FirstIntByTimestampAggregator.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) { + IntBlock valueBlock = page.getBlock(channels.get(0)); + LongBlock timestampBlock = page.getBlock(channels.get(1)); + IntVector valueVector = valueBlock.asVector(); + if (valueVector == null) { + addRawBlock(valueBlock, timestampBlock, mask); + return; + } + LongVector timestampVector = timestampBlock.asVector(); + if (timestampVector == null) { + addRawBlock(valueBlock, timestampBlock, mask); + return; + } + addRawVector(valueVector, timestampVector, mask); + } + + private void addRawInputNotMasked(Page page) { + IntBlock valueBlock = page.getBlock(channels.get(0)); + LongBlock timestampBlock = page.getBlock(channels.get(1)); + IntVector valueVector = valueBlock.asVector(); + if (valueVector == null) { + addRawBlock(valueBlock, timestampBlock); + return; + } + LongVector timestampVector = timestampBlock.asVector(); + if (timestampVector == null) { + addRawBlock(valueBlock, timestampBlock); + return; + } + addRawVector(valueVector, timestampVector); + } + + private void addRawVector(IntVector valueVector, LongVector timestampVector) { + state.seen(true); + for (int valuesPosition = 0; valuesPosition < valueVector.getPositionCount(); valuesPosition++) { + int valueValue = valueVector.getInt(valuesPosition); + long timestampValue = timestampVector.getLong(valuesPosition); + FirstIntByTimestampAggregator.combine(state, valueValue, timestampValue); + } + } + + private void addRawVector(IntVector valueVector, LongVector timestampVector, BooleanVector mask) { + state.seen(true); + for (int valuesPosition = 0; valuesPosition < valueVector.getPositionCount(); valuesPosition++) { + if (mask.getBoolean(valuesPosition) == false) { + continue; + } + int valueValue = valueVector.getInt(valuesPosition); + long timestampValue = timestampVector.getLong(valuesPosition); + FirstIntByTimestampAggregator.combine(state, valueValue, timestampValue); + } + } + + private void addRawBlock(IntBlock valueBlock, LongBlock timestampBlock) { + for (int p = 0; p < valueBlock.getPositionCount(); p++) { + if (valueBlock.isNull(p)) { + continue; + } + if (timestampBlock.isNull(p)) { + continue; + } + state.seen(true); + int valueStart = valueBlock.getFirstValueIndex(p); + int valueEnd = valueStart + valueBlock.getValueCount(p); + for (int valueOffset = valueStart; valueOffset < valueEnd; valueOffset++) { + int valueValue = valueBlock.getInt(valueOffset); + int timestampStart = timestampBlock.getFirstValueIndex(p); + int timestampEnd = timestampStart + timestampBlock.getValueCount(p); + for (int timestampOffset = timestampStart; timestampOffset < timestampEnd; timestampOffset++) { + long timestampValue = timestampBlock.getLong(timestampOffset); + FirstIntByTimestampAggregator.combine(state, valueValue, timestampValue); + } + } + } + } + + private void addRawBlock(IntBlock valueBlock, LongBlock timestampBlock, BooleanVector mask) { + for (int p = 0; p < valueBlock.getPositionCount(); p++) { + if (mask.getBoolean(p) == false) { + continue; + } + if (valueBlock.isNull(p)) { + continue; + } + if (timestampBlock.isNull(p)) { + continue; + } + state.seen(true); + int valueStart = valueBlock.getFirstValueIndex(p); + int valueEnd = valueStart + valueBlock.getValueCount(p); + for (int valueOffset = valueStart; valueOffset < valueEnd; valueOffset++) { + int valueValue = valueBlock.getInt(valueOffset); + int timestampStart = timestampBlock.getFirstValueIndex(p); + int timestampEnd = timestampStart + timestampBlock.getValueCount(p); + for (int timestampOffset = timestampStart; timestampOffset < timestampEnd; timestampOffset++) { + long timestampValue = timestampBlock.getLong(timestampOffset); + FirstIntByTimestampAggregator.combine(state, valueValue, timestampValue); + } + } + } + } + + @Override + public void addIntermediateInput(Page page) { + assert channels.size() == intermediateBlockCount(); + assert page.getBlockCount() >= channels.get(0) + intermediateStateDesc().size(); + Block timestampsUncast = page.getBlock(channels.get(0)); + if (timestampsUncast.areAllValuesNull()) { + return; + } + LongVector timestamps = ((LongBlock) timestampsUncast).asVector(); + assert timestamps.getPositionCount() == 1; + Block valuesUncast = page.getBlock(channels.get(1)); + if (valuesUncast.areAllValuesNull()) { + return; + } + IntVector values = ((IntBlock) valuesUncast).asVector(); + assert values.getPositionCount() == 1; + Block seenUncast = page.getBlock(channels.get(2)); + if (seenUncast.areAllValuesNull()) { + return; + } + BooleanVector seen = ((BooleanBlock) seenUncast).asVector(); + assert seen.getPositionCount() == 1; + FirstIntByTimestampAggregator.combineIntermediate(state, timestamps.getLong(0), values.getInt(0), seen.getBoolean(0)); + } + + @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) { + if (state.seen() == false) { + blocks[offset] = driverContext.blockFactory().newConstantNullBlock(1); + return; + } + blocks[offset] = FirstIntByTimestampAggregator.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/FirstIntByTimestampAggregatorFunctionSupplier.java b/x-pack/plugin/esql/compute/src/main/generated/org/elasticsearch/compute/aggregation/FirstIntByTimestampAggregatorFunctionSupplier.java index eeddcf2684324..87d995674eb3a 100644 --- a/x-pack/plugin/esql/compute/src/main/generated/org/elasticsearch/compute/aggregation/FirstIntByTimestampAggregatorFunctionSupplier.java +++ b/x-pack/plugin/esql/compute/src/main/generated/org/elasticsearch/compute/aggregation/FirstIntByTimestampAggregatorFunctionSupplier.java @@ -20,7 +20,7 @@ public FirstIntByTimestampAggregatorFunctionSupplier() { @Override public List nonGroupingIntermediateStateDesc() { - throw new UnsupportedOperationException("non-grouping aggregator is not supported"); + return FirstIntByTimestampAggregatorFunction.intermediateStateDesc(); } @Override @@ -29,8 +29,9 @@ public List groupingIntermediateStateDesc() { } @Override - public AggregatorFunction aggregator(DriverContext driverContext, List channels) { - throw new UnsupportedOperationException("non-grouping aggregator is not supported"); + public FirstIntByTimestampAggregatorFunction aggregator(DriverContext driverContext, + List channels) { + return FirstIntByTimestampAggregatorFunction.create(driverContext, channels); } @Override @@ -41,6 +42,6 @@ public FirstIntByTimestampGroupingAggregatorFunction groupingAggregator( @Override public String describe() { - return "first_int_by of timestamps"; + return FirstIntByTimestampAggregator.describe(); } } diff --git a/x-pack/plugin/esql/compute/src/main/generated/org/elasticsearch/compute/aggregation/FirstIntByTimestampGroupingAggregatorFunction.java b/x-pack/plugin/esql/compute/src/main/generated/org/elasticsearch/compute/aggregation/FirstIntByTimestampGroupingAggregatorFunction.java index f90867dcb2471..0b436fa39f621 100644 --- a/x-pack/plugin/esql/compute/src/main/generated/org/elasticsearch/compute/aggregation/FirstIntByTimestampGroupingAggregatorFunction.java +++ b/x-pack/plugin/esql/compute/src/main/generated/org/elasticsearch/compute/aggregation/FirstIntByTimestampGroupingAggregatorFunction.java @@ -63,9 +63,7 @@ public GroupingAggregatorFunction.AddInput prepareProcessRawInputPage(SeenGroupI LongBlock timestampBlock = page.getBlock(channels.get(1)); IntVector valueVector = valueBlock.asVector(); if (valueVector == null) { - if (valueBlock.mayHaveNulls()) { - state.enableGroupIdTracking(seenGroupIds); - } + maybeEnableGroupIdTracking(seenGroupIds, valueBlock, timestampBlock); return new GroupingAggregatorFunction.AddInput() { @Override public void add(int positionOffset, IntArrayBlock groupIds) { @@ -89,9 +87,7 @@ public void close() { } LongVector timestampVector = timestampBlock.asVector(); if (timestampVector == null) { - if (timestampBlock.mayHaveNulls()) { - state.enableGroupIdTracking(seenGroupIds); - } + maybeEnableGroupIdTracking(seenGroupIds, valueBlock, timestampBlock); return new GroupingAggregatorFunction.AddInput() { @Override public void add(int positionOffset, IntArrayBlock groupIds) { @@ -351,6 +347,16 @@ public void addIntermediateInput(int positionOffset, IntVector groups, Page page } } + private void maybeEnableGroupIdTracking(SeenGroupIds seenGroupIds, IntBlock valueBlock, + LongBlock timestampBlock) { + if (valueBlock.mayHaveNulls()) { + state.enableGroupIdTracking(seenGroupIds); + } + if (timestampBlock.mayHaveNulls()) { + state.enableGroupIdTracking(seenGroupIds); + } + } + @Override public void selectedMayContainUnseenGroups(SeenGroupIds seenGroupIds) { state.enableGroupIdTracking(seenGroupIds); diff --git a/x-pack/plugin/esql/compute/src/main/generated/org/elasticsearch/compute/aggregation/FirstLongByTimestampAggregatorFunction.java b/x-pack/plugin/esql/compute/src/main/generated/org/elasticsearch/compute/aggregation/FirstLongByTimestampAggregatorFunction.java new file mode 100644 index 0000000000000..2916b1582c4b8 --- /dev/null +++ b/x-pack/plugin/esql/compute/src/main/generated/org/elasticsearch/compute/aggregation/FirstLongByTimestampAggregatorFunction.java @@ -0,0 +1,224 @@ +// 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.BooleanBlock; +import org.elasticsearch.compute.data.BooleanVector; +import org.elasticsearch.compute.data.ElementType; +import org.elasticsearch.compute.data.LongBlock; +import org.elasticsearch.compute.data.LongVector; +import org.elasticsearch.compute.data.Page; +import org.elasticsearch.compute.operator.DriverContext; + +/** + * {@link AggregatorFunction} implementation for {@link FirstLongByTimestampAggregator}. + * This class is generated. Edit {@code AggregatorImplementer} instead. + */ +public final class FirstLongByTimestampAggregatorFunction implements AggregatorFunction { + private static final List INTERMEDIATE_STATE_DESC = List.of( + new IntermediateStateDesc("timestamps", ElementType.LONG), + new IntermediateStateDesc("values", ElementType.LONG), + new IntermediateStateDesc("seen", ElementType.BOOLEAN) ); + + private final DriverContext driverContext; + + private final LongLongState state; + + private final List channels; + + public FirstLongByTimestampAggregatorFunction(DriverContext driverContext, List channels, + LongLongState state) { + this.driverContext = driverContext; + this.channels = channels; + this.state = state; + } + + public static FirstLongByTimestampAggregatorFunction create(DriverContext driverContext, + List channels) { + return new FirstLongByTimestampAggregatorFunction(driverContext, channels, FirstLongByTimestampAggregator.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) { + LongBlock valueBlock = page.getBlock(channels.get(0)); + LongBlock timestampBlock = page.getBlock(channels.get(1)); + LongVector valueVector = valueBlock.asVector(); + if (valueVector == null) { + addRawBlock(valueBlock, timestampBlock, mask); + return; + } + LongVector timestampVector = timestampBlock.asVector(); + if (timestampVector == null) { + addRawBlock(valueBlock, timestampBlock, mask); + return; + } + addRawVector(valueVector, timestampVector, mask); + } + + private void addRawInputNotMasked(Page page) { + LongBlock valueBlock = page.getBlock(channels.get(0)); + LongBlock timestampBlock = page.getBlock(channels.get(1)); + LongVector valueVector = valueBlock.asVector(); + if (valueVector == null) { + addRawBlock(valueBlock, timestampBlock); + return; + } + LongVector timestampVector = timestampBlock.asVector(); + if (timestampVector == null) { + addRawBlock(valueBlock, timestampBlock); + return; + } + addRawVector(valueVector, timestampVector); + } + + private void addRawVector(LongVector valueVector, LongVector timestampVector) { + state.seen(true); + for (int valuesPosition = 0; valuesPosition < valueVector.getPositionCount(); valuesPosition++) { + long valueValue = valueVector.getLong(valuesPosition); + long timestampValue = timestampVector.getLong(valuesPosition); + FirstLongByTimestampAggregator.combine(state, valueValue, timestampValue); + } + } + + private void addRawVector(LongVector valueVector, LongVector timestampVector, + BooleanVector mask) { + state.seen(true); + for (int valuesPosition = 0; valuesPosition < valueVector.getPositionCount(); valuesPosition++) { + if (mask.getBoolean(valuesPosition) == false) { + continue; + } + long valueValue = valueVector.getLong(valuesPosition); + long timestampValue = timestampVector.getLong(valuesPosition); + FirstLongByTimestampAggregator.combine(state, valueValue, timestampValue); + } + } + + private void addRawBlock(LongBlock valueBlock, LongBlock timestampBlock) { + for (int p = 0; p < valueBlock.getPositionCount(); p++) { + if (valueBlock.isNull(p)) { + continue; + } + if (timestampBlock.isNull(p)) { + continue; + } + state.seen(true); + int valueStart = valueBlock.getFirstValueIndex(p); + int valueEnd = valueStart + valueBlock.getValueCount(p); + for (int valueOffset = valueStart; valueOffset < valueEnd; valueOffset++) { + long valueValue = valueBlock.getLong(valueOffset); + int timestampStart = timestampBlock.getFirstValueIndex(p); + int timestampEnd = timestampStart + timestampBlock.getValueCount(p); + for (int timestampOffset = timestampStart; timestampOffset < timestampEnd; timestampOffset++) { + long timestampValue = timestampBlock.getLong(timestampOffset); + FirstLongByTimestampAggregator.combine(state, valueValue, timestampValue); + } + } + } + } + + private void addRawBlock(LongBlock valueBlock, LongBlock timestampBlock, BooleanVector mask) { + for (int p = 0; p < valueBlock.getPositionCount(); p++) { + if (mask.getBoolean(p) == false) { + continue; + } + if (valueBlock.isNull(p)) { + continue; + } + if (timestampBlock.isNull(p)) { + continue; + } + state.seen(true); + int valueStart = valueBlock.getFirstValueIndex(p); + int valueEnd = valueStart + valueBlock.getValueCount(p); + for (int valueOffset = valueStart; valueOffset < valueEnd; valueOffset++) { + long valueValue = valueBlock.getLong(valueOffset); + int timestampStart = timestampBlock.getFirstValueIndex(p); + int timestampEnd = timestampStart + timestampBlock.getValueCount(p); + for (int timestampOffset = timestampStart; timestampOffset < timestampEnd; timestampOffset++) { + long timestampValue = timestampBlock.getLong(timestampOffset); + FirstLongByTimestampAggregator.combine(state, valueValue, timestampValue); + } + } + } + } + + @Override + public void addIntermediateInput(Page page) { + assert channels.size() == intermediateBlockCount(); + assert page.getBlockCount() >= channels.get(0) + intermediateStateDesc().size(); + Block timestampsUncast = page.getBlock(channels.get(0)); + if (timestampsUncast.areAllValuesNull()) { + return; + } + LongVector timestamps = ((LongBlock) timestampsUncast).asVector(); + assert timestamps.getPositionCount() == 1; + Block valuesUncast = page.getBlock(channels.get(1)); + if (valuesUncast.areAllValuesNull()) { + return; + } + LongVector values = ((LongBlock) valuesUncast).asVector(); + assert values.getPositionCount() == 1; + Block seenUncast = page.getBlock(channels.get(2)); + if (seenUncast.areAllValuesNull()) { + return; + } + BooleanVector seen = ((BooleanBlock) seenUncast).asVector(); + assert seen.getPositionCount() == 1; + FirstLongByTimestampAggregator.combineIntermediate(state, timestamps.getLong(0), values.getLong(0), seen.getBoolean(0)); + } + + @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) { + if (state.seen() == false) { + blocks[offset] = driverContext.blockFactory().newConstantNullBlock(1); + return; + } + blocks[offset] = FirstLongByTimestampAggregator.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/FirstLongByTimestampAggregatorFunctionSupplier.java b/x-pack/plugin/esql/compute/src/main/generated/org/elasticsearch/compute/aggregation/FirstLongByTimestampAggregatorFunctionSupplier.java index 9cc7f1f680ab9..fad517a21605c 100644 --- a/x-pack/plugin/esql/compute/src/main/generated/org/elasticsearch/compute/aggregation/FirstLongByTimestampAggregatorFunctionSupplier.java +++ b/x-pack/plugin/esql/compute/src/main/generated/org/elasticsearch/compute/aggregation/FirstLongByTimestampAggregatorFunctionSupplier.java @@ -20,7 +20,7 @@ public FirstLongByTimestampAggregatorFunctionSupplier() { @Override public List nonGroupingIntermediateStateDesc() { - throw new UnsupportedOperationException("non-grouping aggregator is not supported"); + return FirstLongByTimestampAggregatorFunction.intermediateStateDesc(); } @Override @@ -29,8 +29,9 @@ public List groupingIntermediateStateDesc() { } @Override - public AggregatorFunction aggregator(DriverContext driverContext, List channels) { - throw new UnsupportedOperationException("non-grouping aggregator is not supported"); + public FirstLongByTimestampAggregatorFunction aggregator(DriverContext driverContext, + List channels) { + return FirstLongByTimestampAggregatorFunction.create(driverContext, channels); } @Override @@ -41,6 +42,6 @@ public FirstLongByTimestampGroupingAggregatorFunction groupingAggregator( @Override public String describe() { - return "first_long_by of timestamps"; + return FirstLongByTimestampAggregator.describe(); } } diff --git a/x-pack/plugin/esql/compute/src/main/generated/org/elasticsearch/compute/aggregation/FirstLongByTimestampGroupingAggregatorFunction.java b/x-pack/plugin/esql/compute/src/main/generated/org/elasticsearch/compute/aggregation/FirstLongByTimestampGroupingAggregatorFunction.java index a76a2d644fbff..8e843a873f23b 100644 --- a/x-pack/plugin/esql/compute/src/main/generated/org/elasticsearch/compute/aggregation/FirstLongByTimestampGroupingAggregatorFunction.java +++ b/x-pack/plugin/esql/compute/src/main/generated/org/elasticsearch/compute/aggregation/FirstLongByTimestampGroupingAggregatorFunction.java @@ -62,9 +62,7 @@ public GroupingAggregatorFunction.AddInput prepareProcessRawInputPage(SeenGroupI LongBlock timestampBlock = page.getBlock(channels.get(1)); LongVector valueVector = valueBlock.asVector(); if (valueVector == null) { - if (valueBlock.mayHaveNulls()) { - state.enableGroupIdTracking(seenGroupIds); - } + maybeEnableGroupIdTracking(seenGroupIds, valueBlock, timestampBlock); return new GroupingAggregatorFunction.AddInput() { @Override public void add(int positionOffset, IntArrayBlock groupIds) { @@ -88,9 +86,7 @@ public void close() { } LongVector timestampVector = timestampBlock.asVector(); if (timestampVector == null) { - if (timestampBlock.mayHaveNulls()) { - state.enableGroupIdTracking(seenGroupIds); - } + maybeEnableGroupIdTracking(seenGroupIds, valueBlock, timestampBlock); return new GroupingAggregatorFunction.AddInput() { @Override public void add(int positionOffset, IntArrayBlock groupIds) { @@ -350,6 +346,16 @@ public void addIntermediateInput(int positionOffset, IntVector groups, Page page } } + private void maybeEnableGroupIdTracking(SeenGroupIds seenGroupIds, LongBlock valueBlock, + LongBlock timestampBlock) { + if (valueBlock.mayHaveNulls()) { + state.enableGroupIdTracking(seenGroupIds); + } + if (timestampBlock.mayHaveNulls()) { + state.enableGroupIdTracking(seenGroupIds); + } + } + @Override public void selectedMayContainUnseenGroups(SeenGroupIds seenGroupIds) { state.enableGroupIdTracking(seenGroupIds); diff --git a/x-pack/plugin/esql/compute/src/main/generated/org/elasticsearch/compute/aggregation/LastDoubleByTimestampAggregatorFunction.java b/x-pack/plugin/esql/compute/src/main/generated/org/elasticsearch/compute/aggregation/LastDoubleByTimestampAggregatorFunction.java new file mode 100644 index 0000000000000..f8ebe1efcbc05 --- /dev/null +++ b/x-pack/plugin/esql/compute/src/main/generated/org/elasticsearch/compute/aggregation/LastDoubleByTimestampAggregatorFunction.java @@ -0,0 +1,226 @@ +// 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.BooleanBlock; +import org.elasticsearch.compute.data.BooleanVector; +import org.elasticsearch.compute.data.DoubleBlock; +import org.elasticsearch.compute.data.DoubleVector; +import org.elasticsearch.compute.data.ElementType; +import org.elasticsearch.compute.data.LongBlock; +import org.elasticsearch.compute.data.LongVector; +import org.elasticsearch.compute.data.Page; +import org.elasticsearch.compute.operator.DriverContext; + +/** + * {@link AggregatorFunction} implementation for {@link LastDoubleByTimestampAggregator}. + * This class is generated. Edit {@code AggregatorImplementer} instead. + */ +public final class LastDoubleByTimestampAggregatorFunction implements AggregatorFunction { + private static final List INTERMEDIATE_STATE_DESC = List.of( + new IntermediateStateDesc("timestamps", ElementType.LONG), + new IntermediateStateDesc("values", ElementType.DOUBLE), + new IntermediateStateDesc("seen", ElementType.BOOLEAN) ); + + private final DriverContext driverContext; + + private final LongDoubleState state; + + private final List channels; + + public LastDoubleByTimestampAggregatorFunction(DriverContext driverContext, + List channels, LongDoubleState state) { + this.driverContext = driverContext; + this.channels = channels; + this.state = state; + } + + public static LastDoubleByTimestampAggregatorFunction create(DriverContext driverContext, + List channels) { + return new LastDoubleByTimestampAggregatorFunction(driverContext, channels, LastDoubleByTimestampAggregator.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) { + DoubleBlock valueBlock = page.getBlock(channels.get(0)); + LongBlock timestampBlock = page.getBlock(channels.get(1)); + DoubleVector valueVector = valueBlock.asVector(); + if (valueVector == null) { + addRawBlock(valueBlock, timestampBlock, mask); + return; + } + LongVector timestampVector = timestampBlock.asVector(); + if (timestampVector == null) { + addRawBlock(valueBlock, timestampBlock, mask); + return; + } + addRawVector(valueVector, timestampVector, mask); + } + + private void addRawInputNotMasked(Page page) { + DoubleBlock valueBlock = page.getBlock(channels.get(0)); + LongBlock timestampBlock = page.getBlock(channels.get(1)); + DoubleVector valueVector = valueBlock.asVector(); + if (valueVector == null) { + addRawBlock(valueBlock, timestampBlock); + return; + } + LongVector timestampVector = timestampBlock.asVector(); + if (timestampVector == null) { + addRawBlock(valueBlock, timestampBlock); + return; + } + addRawVector(valueVector, timestampVector); + } + + private void addRawVector(DoubleVector valueVector, LongVector timestampVector) { + state.seen(true); + for (int valuesPosition = 0; valuesPosition < valueVector.getPositionCount(); valuesPosition++) { + double valueValue = valueVector.getDouble(valuesPosition); + long timestampValue = timestampVector.getLong(valuesPosition); + LastDoubleByTimestampAggregator.combine(state, valueValue, timestampValue); + } + } + + private void addRawVector(DoubleVector valueVector, LongVector timestampVector, + BooleanVector mask) { + state.seen(true); + for (int valuesPosition = 0; valuesPosition < valueVector.getPositionCount(); valuesPosition++) { + if (mask.getBoolean(valuesPosition) == false) { + continue; + } + double valueValue = valueVector.getDouble(valuesPosition); + long timestampValue = timestampVector.getLong(valuesPosition); + LastDoubleByTimestampAggregator.combine(state, valueValue, timestampValue); + } + } + + private void addRawBlock(DoubleBlock valueBlock, LongBlock timestampBlock) { + for (int p = 0; p < valueBlock.getPositionCount(); p++) { + if (valueBlock.isNull(p)) { + continue; + } + if (timestampBlock.isNull(p)) { + continue; + } + state.seen(true); + int valueStart = valueBlock.getFirstValueIndex(p); + int valueEnd = valueStart + valueBlock.getValueCount(p); + for (int valueOffset = valueStart; valueOffset < valueEnd; valueOffset++) { + double valueValue = valueBlock.getDouble(valueOffset); + int timestampStart = timestampBlock.getFirstValueIndex(p); + int timestampEnd = timestampStart + timestampBlock.getValueCount(p); + for (int timestampOffset = timestampStart; timestampOffset < timestampEnd; timestampOffset++) { + long timestampValue = timestampBlock.getLong(timestampOffset); + LastDoubleByTimestampAggregator.combine(state, valueValue, timestampValue); + } + } + } + } + + private void addRawBlock(DoubleBlock valueBlock, LongBlock timestampBlock, BooleanVector mask) { + for (int p = 0; p < valueBlock.getPositionCount(); p++) { + if (mask.getBoolean(p) == false) { + continue; + } + if (valueBlock.isNull(p)) { + continue; + } + if (timestampBlock.isNull(p)) { + continue; + } + state.seen(true); + int valueStart = valueBlock.getFirstValueIndex(p); + int valueEnd = valueStart + valueBlock.getValueCount(p); + for (int valueOffset = valueStart; valueOffset < valueEnd; valueOffset++) { + double valueValue = valueBlock.getDouble(valueOffset); + int timestampStart = timestampBlock.getFirstValueIndex(p); + int timestampEnd = timestampStart + timestampBlock.getValueCount(p); + for (int timestampOffset = timestampStart; timestampOffset < timestampEnd; timestampOffset++) { + long timestampValue = timestampBlock.getLong(timestampOffset); + LastDoubleByTimestampAggregator.combine(state, valueValue, timestampValue); + } + } + } + } + + @Override + public void addIntermediateInput(Page page) { + assert channels.size() == intermediateBlockCount(); + assert page.getBlockCount() >= channels.get(0) + intermediateStateDesc().size(); + Block timestampsUncast = page.getBlock(channels.get(0)); + if (timestampsUncast.areAllValuesNull()) { + return; + } + LongVector timestamps = ((LongBlock) timestampsUncast).asVector(); + assert timestamps.getPositionCount() == 1; + Block valuesUncast = page.getBlock(channels.get(1)); + if (valuesUncast.areAllValuesNull()) { + return; + } + DoubleVector values = ((DoubleBlock) valuesUncast).asVector(); + assert values.getPositionCount() == 1; + Block seenUncast = page.getBlock(channels.get(2)); + if (seenUncast.areAllValuesNull()) { + return; + } + BooleanVector seen = ((BooleanBlock) seenUncast).asVector(); + assert seen.getPositionCount() == 1; + LastDoubleByTimestampAggregator.combineIntermediate(state, timestamps.getLong(0), values.getDouble(0), seen.getBoolean(0)); + } + + @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) { + if (state.seen() == false) { + blocks[offset] = driverContext.blockFactory().newConstantNullBlock(1); + return; + } + blocks[offset] = LastDoubleByTimestampAggregator.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/LastDoubleByTimestampAggregatorFunctionSupplier.java b/x-pack/plugin/esql/compute/src/main/generated/org/elasticsearch/compute/aggregation/LastDoubleByTimestampAggregatorFunctionSupplier.java index c0e9aa344791c..9e15921fdc85a 100644 --- a/x-pack/plugin/esql/compute/src/main/generated/org/elasticsearch/compute/aggregation/LastDoubleByTimestampAggregatorFunctionSupplier.java +++ b/x-pack/plugin/esql/compute/src/main/generated/org/elasticsearch/compute/aggregation/LastDoubleByTimestampAggregatorFunctionSupplier.java @@ -20,7 +20,7 @@ public LastDoubleByTimestampAggregatorFunctionSupplier() { @Override public List nonGroupingIntermediateStateDesc() { - throw new UnsupportedOperationException("non-grouping aggregator is not supported"); + return LastDoubleByTimestampAggregatorFunction.intermediateStateDesc(); } @Override @@ -29,8 +29,9 @@ public List groupingIntermediateStateDesc() { } @Override - public AggregatorFunction aggregator(DriverContext driverContext, List channels) { - throw new UnsupportedOperationException("non-grouping aggregator is not supported"); + public LastDoubleByTimestampAggregatorFunction aggregator(DriverContext driverContext, + List channels) { + return LastDoubleByTimestampAggregatorFunction.create(driverContext, channels); } @Override @@ -41,6 +42,6 @@ public LastDoubleByTimestampGroupingAggregatorFunction groupingAggregator( @Override public String describe() { - return "last_double_by of timestamps"; + return LastDoubleByTimestampAggregator.describe(); } } diff --git a/x-pack/plugin/esql/compute/src/main/generated/org/elasticsearch/compute/aggregation/LastDoubleByTimestampGroupingAggregatorFunction.java b/x-pack/plugin/esql/compute/src/main/generated/org/elasticsearch/compute/aggregation/LastDoubleByTimestampGroupingAggregatorFunction.java index 3bdc95c494421..195fc31ad8a94 100644 --- a/x-pack/plugin/esql/compute/src/main/generated/org/elasticsearch/compute/aggregation/LastDoubleByTimestampGroupingAggregatorFunction.java +++ b/x-pack/plugin/esql/compute/src/main/generated/org/elasticsearch/compute/aggregation/LastDoubleByTimestampGroupingAggregatorFunction.java @@ -64,9 +64,7 @@ public GroupingAggregatorFunction.AddInput prepareProcessRawInputPage(SeenGroupI LongBlock timestampBlock = page.getBlock(channels.get(1)); DoubleVector valueVector = valueBlock.asVector(); if (valueVector == null) { - if (valueBlock.mayHaveNulls()) { - state.enableGroupIdTracking(seenGroupIds); - } + maybeEnableGroupIdTracking(seenGroupIds, valueBlock, timestampBlock); return new GroupingAggregatorFunction.AddInput() { @Override public void add(int positionOffset, IntArrayBlock groupIds) { @@ -90,9 +88,7 @@ public void close() { } LongVector timestampVector = timestampBlock.asVector(); if (timestampVector == null) { - if (timestampBlock.mayHaveNulls()) { - state.enableGroupIdTracking(seenGroupIds); - } + maybeEnableGroupIdTracking(seenGroupIds, valueBlock, timestampBlock); return new GroupingAggregatorFunction.AddInput() { @Override public void add(int positionOffset, IntArrayBlock groupIds) { @@ -352,6 +348,16 @@ public void addIntermediateInput(int positionOffset, IntVector groups, Page page } } + private void maybeEnableGroupIdTracking(SeenGroupIds seenGroupIds, DoubleBlock valueBlock, + LongBlock timestampBlock) { + if (valueBlock.mayHaveNulls()) { + state.enableGroupIdTracking(seenGroupIds); + } + if (timestampBlock.mayHaveNulls()) { + state.enableGroupIdTracking(seenGroupIds); + } + } + @Override public void selectedMayContainUnseenGroups(SeenGroupIds seenGroupIds) { state.enableGroupIdTracking(seenGroupIds); diff --git a/x-pack/plugin/esql/compute/src/main/generated/org/elasticsearch/compute/aggregation/LastFloatByTimestampAggregatorFunction.java b/x-pack/plugin/esql/compute/src/main/generated/org/elasticsearch/compute/aggregation/LastFloatByTimestampAggregatorFunction.java new file mode 100644 index 0000000000000..bcee94964dd9a --- /dev/null +++ b/x-pack/plugin/esql/compute/src/main/generated/org/elasticsearch/compute/aggregation/LastFloatByTimestampAggregatorFunction.java @@ -0,0 +1,226 @@ +// 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.BooleanBlock; +import org.elasticsearch.compute.data.BooleanVector; +import org.elasticsearch.compute.data.ElementType; +import org.elasticsearch.compute.data.FloatBlock; +import org.elasticsearch.compute.data.FloatVector; +import org.elasticsearch.compute.data.LongBlock; +import org.elasticsearch.compute.data.LongVector; +import org.elasticsearch.compute.data.Page; +import org.elasticsearch.compute.operator.DriverContext; + +/** + * {@link AggregatorFunction} implementation for {@link LastFloatByTimestampAggregator}. + * This class is generated. Edit {@code AggregatorImplementer} instead. + */ +public final class LastFloatByTimestampAggregatorFunction implements AggregatorFunction { + private static final List INTERMEDIATE_STATE_DESC = List.of( + new IntermediateStateDesc("timestamps", ElementType.LONG), + new IntermediateStateDesc("values", ElementType.FLOAT), + new IntermediateStateDesc("seen", ElementType.BOOLEAN) ); + + private final DriverContext driverContext; + + private final LongFloatState state; + + private final List channels; + + public LastFloatByTimestampAggregatorFunction(DriverContext driverContext, List channels, + LongFloatState state) { + this.driverContext = driverContext; + this.channels = channels; + this.state = state; + } + + public static LastFloatByTimestampAggregatorFunction create(DriverContext driverContext, + List channels) { + return new LastFloatByTimestampAggregatorFunction(driverContext, channels, LastFloatByTimestampAggregator.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) { + FloatBlock valueBlock = page.getBlock(channels.get(0)); + LongBlock timestampBlock = page.getBlock(channels.get(1)); + FloatVector valueVector = valueBlock.asVector(); + if (valueVector == null) { + addRawBlock(valueBlock, timestampBlock, mask); + return; + } + LongVector timestampVector = timestampBlock.asVector(); + if (timestampVector == null) { + addRawBlock(valueBlock, timestampBlock, mask); + return; + } + addRawVector(valueVector, timestampVector, mask); + } + + private void addRawInputNotMasked(Page page) { + FloatBlock valueBlock = page.getBlock(channels.get(0)); + LongBlock timestampBlock = page.getBlock(channels.get(1)); + FloatVector valueVector = valueBlock.asVector(); + if (valueVector == null) { + addRawBlock(valueBlock, timestampBlock); + return; + } + LongVector timestampVector = timestampBlock.asVector(); + if (timestampVector == null) { + addRawBlock(valueBlock, timestampBlock); + return; + } + addRawVector(valueVector, timestampVector); + } + + private void addRawVector(FloatVector valueVector, LongVector timestampVector) { + state.seen(true); + for (int valuesPosition = 0; valuesPosition < valueVector.getPositionCount(); valuesPosition++) { + float valueValue = valueVector.getFloat(valuesPosition); + long timestampValue = timestampVector.getLong(valuesPosition); + LastFloatByTimestampAggregator.combine(state, valueValue, timestampValue); + } + } + + private void addRawVector(FloatVector valueVector, LongVector timestampVector, + BooleanVector mask) { + state.seen(true); + for (int valuesPosition = 0; valuesPosition < valueVector.getPositionCount(); valuesPosition++) { + if (mask.getBoolean(valuesPosition) == false) { + continue; + } + float valueValue = valueVector.getFloat(valuesPosition); + long timestampValue = timestampVector.getLong(valuesPosition); + LastFloatByTimestampAggregator.combine(state, valueValue, timestampValue); + } + } + + private void addRawBlock(FloatBlock valueBlock, LongBlock timestampBlock) { + for (int p = 0; p < valueBlock.getPositionCount(); p++) { + if (valueBlock.isNull(p)) { + continue; + } + if (timestampBlock.isNull(p)) { + continue; + } + state.seen(true); + int valueStart = valueBlock.getFirstValueIndex(p); + int valueEnd = valueStart + valueBlock.getValueCount(p); + for (int valueOffset = valueStart; valueOffset < valueEnd; valueOffset++) { + float valueValue = valueBlock.getFloat(valueOffset); + int timestampStart = timestampBlock.getFirstValueIndex(p); + int timestampEnd = timestampStart + timestampBlock.getValueCount(p); + for (int timestampOffset = timestampStart; timestampOffset < timestampEnd; timestampOffset++) { + long timestampValue = timestampBlock.getLong(timestampOffset); + LastFloatByTimestampAggregator.combine(state, valueValue, timestampValue); + } + } + } + } + + private void addRawBlock(FloatBlock valueBlock, LongBlock timestampBlock, BooleanVector mask) { + for (int p = 0; p < valueBlock.getPositionCount(); p++) { + if (mask.getBoolean(p) == false) { + continue; + } + if (valueBlock.isNull(p)) { + continue; + } + if (timestampBlock.isNull(p)) { + continue; + } + state.seen(true); + int valueStart = valueBlock.getFirstValueIndex(p); + int valueEnd = valueStart + valueBlock.getValueCount(p); + for (int valueOffset = valueStart; valueOffset < valueEnd; valueOffset++) { + float valueValue = valueBlock.getFloat(valueOffset); + int timestampStart = timestampBlock.getFirstValueIndex(p); + int timestampEnd = timestampStart + timestampBlock.getValueCount(p); + for (int timestampOffset = timestampStart; timestampOffset < timestampEnd; timestampOffset++) { + long timestampValue = timestampBlock.getLong(timestampOffset); + LastFloatByTimestampAggregator.combine(state, valueValue, timestampValue); + } + } + } + } + + @Override + public void addIntermediateInput(Page page) { + assert channels.size() == intermediateBlockCount(); + assert page.getBlockCount() >= channels.get(0) + intermediateStateDesc().size(); + Block timestampsUncast = page.getBlock(channels.get(0)); + if (timestampsUncast.areAllValuesNull()) { + return; + } + LongVector timestamps = ((LongBlock) timestampsUncast).asVector(); + assert timestamps.getPositionCount() == 1; + Block valuesUncast = page.getBlock(channels.get(1)); + if (valuesUncast.areAllValuesNull()) { + return; + } + FloatVector values = ((FloatBlock) valuesUncast).asVector(); + assert values.getPositionCount() == 1; + Block seenUncast = page.getBlock(channels.get(2)); + if (seenUncast.areAllValuesNull()) { + return; + } + BooleanVector seen = ((BooleanBlock) seenUncast).asVector(); + assert seen.getPositionCount() == 1; + LastFloatByTimestampAggregator.combineIntermediate(state, timestamps.getLong(0), values.getFloat(0), seen.getBoolean(0)); + } + + @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) { + if (state.seen() == false) { + blocks[offset] = driverContext.blockFactory().newConstantNullBlock(1); + return; + } + blocks[offset] = LastFloatByTimestampAggregator.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/LastFloatByTimestampAggregatorFunctionSupplier.java b/x-pack/plugin/esql/compute/src/main/generated/org/elasticsearch/compute/aggregation/LastFloatByTimestampAggregatorFunctionSupplier.java index 9a330782aa31d..6ea5daaeb5a6f 100644 --- a/x-pack/plugin/esql/compute/src/main/generated/org/elasticsearch/compute/aggregation/LastFloatByTimestampAggregatorFunctionSupplier.java +++ b/x-pack/plugin/esql/compute/src/main/generated/org/elasticsearch/compute/aggregation/LastFloatByTimestampAggregatorFunctionSupplier.java @@ -20,7 +20,7 @@ public LastFloatByTimestampAggregatorFunctionSupplier() { @Override public List nonGroupingIntermediateStateDesc() { - throw new UnsupportedOperationException("non-grouping aggregator is not supported"); + return LastFloatByTimestampAggregatorFunction.intermediateStateDesc(); } @Override @@ -29,8 +29,9 @@ public List groupingIntermediateStateDesc() { } @Override - public AggregatorFunction aggregator(DriverContext driverContext, List channels) { - throw new UnsupportedOperationException("non-grouping aggregator is not supported"); + public LastFloatByTimestampAggregatorFunction aggregator(DriverContext driverContext, + List channels) { + return LastFloatByTimestampAggregatorFunction.create(driverContext, channels); } @Override @@ -41,6 +42,6 @@ public LastFloatByTimestampGroupingAggregatorFunction groupingAggregator( @Override public String describe() { - return "last_float_by of timestamps"; + return LastFloatByTimestampAggregator.describe(); } } diff --git a/x-pack/plugin/esql/compute/src/main/generated/org/elasticsearch/compute/aggregation/LastFloatByTimestampGroupingAggregatorFunction.java b/x-pack/plugin/esql/compute/src/main/generated/org/elasticsearch/compute/aggregation/LastFloatByTimestampGroupingAggregatorFunction.java index a3498e50fe3c7..f3361b3468be2 100644 --- a/x-pack/plugin/esql/compute/src/main/generated/org/elasticsearch/compute/aggregation/LastFloatByTimestampGroupingAggregatorFunction.java +++ b/x-pack/plugin/esql/compute/src/main/generated/org/elasticsearch/compute/aggregation/LastFloatByTimestampGroupingAggregatorFunction.java @@ -64,9 +64,7 @@ public GroupingAggregatorFunction.AddInput prepareProcessRawInputPage(SeenGroupI LongBlock timestampBlock = page.getBlock(channels.get(1)); FloatVector valueVector = valueBlock.asVector(); if (valueVector == null) { - if (valueBlock.mayHaveNulls()) { - state.enableGroupIdTracking(seenGroupIds); - } + maybeEnableGroupIdTracking(seenGroupIds, valueBlock, timestampBlock); return new GroupingAggregatorFunction.AddInput() { @Override public void add(int positionOffset, IntArrayBlock groupIds) { @@ -90,9 +88,7 @@ public void close() { } LongVector timestampVector = timestampBlock.asVector(); if (timestampVector == null) { - if (timestampBlock.mayHaveNulls()) { - state.enableGroupIdTracking(seenGroupIds); - } + maybeEnableGroupIdTracking(seenGroupIds, valueBlock, timestampBlock); return new GroupingAggregatorFunction.AddInput() { @Override public void add(int positionOffset, IntArrayBlock groupIds) { @@ -352,6 +348,16 @@ public void addIntermediateInput(int positionOffset, IntVector groups, Page page } } + private void maybeEnableGroupIdTracking(SeenGroupIds seenGroupIds, FloatBlock valueBlock, + LongBlock timestampBlock) { + if (valueBlock.mayHaveNulls()) { + state.enableGroupIdTracking(seenGroupIds); + } + if (timestampBlock.mayHaveNulls()) { + state.enableGroupIdTracking(seenGroupIds); + } + } + @Override public void selectedMayContainUnseenGroups(SeenGroupIds seenGroupIds) { state.enableGroupIdTracking(seenGroupIds); diff --git a/x-pack/plugin/esql/compute/src/main/generated/org/elasticsearch/compute/aggregation/LastIntByTimestampAggregatorFunction.java b/x-pack/plugin/esql/compute/src/main/generated/org/elasticsearch/compute/aggregation/LastIntByTimestampAggregatorFunction.java new file mode 100644 index 0000000000000..a8bea89bc3c19 --- /dev/null +++ b/x-pack/plugin/esql/compute/src/main/generated/org/elasticsearch/compute/aggregation/LastIntByTimestampAggregatorFunction.java @@ -0,0 +1,225 @@ +// 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.BooleanBlock; +import org.elasticsearch.compute.data.BooleanVector; +import org.elasticsearch.compute.data.ElementType; +import org.elasticsearch.compute.data.IntBlock; +import org.elasticsearch.compute.data.IntVector; +import org.elasticsearch.compute.data.LongBlock; +import org.elasticsearch.compute.data.LongVector; +import org.elasticsearch.compute.data.Page; +import org.elasticsearch.compute.operator.DriverContext; + +/** + * {@link AggregatorFunction} implementation for {@link LastIntByTimestampAggregator}. + * This class is generated. Edit {@code AggregatorImplementer} instead. + */ +public final class LastIntByTimestampAggregatorFunction implements AggregatorFunction { + private static final List INTERMEDIATE_STATE_DESC = List.of( + new IntermediateStateDesc("timestamps", ElementType.LONG), + new IntermediateStateDesc("values", ElementType.INT), + new IntermediateStateDesc("seen", ElementType.BOOLEAN) ); + + private final DriverContext driverContext; + + private final LongIntState state; + + private final List channels; + + public LastIntByTimestampAggregatorFunction(DriverContext driverContext, List channels, + LongIntState state) { + this.driverContext = driverContext; + this.channels = channels; + this.state = state; + } + + public static LastIntByTimestampAggregatorFunction create(DriverContext driverContext, + List channels) { + return new LastIntByTimestampAggregatorFunction(driverContext, channels, LastIntByTimestampAggregator.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) { + IntBlock valueBlock = page.getBlock(channels.get(0)); + LongBlock timestampBlock = page.getBlock(channels.get(1)); + IntVector valueVector = valueBlock.asVector(); + if (valueVector == null) { + addRawBlock(valueBlock, timestampBlock, mask); + return; + } + LongVector timestampVector = timestampBlock.asVector(); + if (timestampVector == null) { + addRawBlock(valueBlock, timestampBlock, mask); + return; + } + addRawVector(valueVector, timestampVector, mask); + } + + private void addRawInputNotMasked(Page page) { + IntBlock valueBlock = page.getBlock(channels.get(0)); + LongBlock timestampBlock = page.getBlock(channels.get(1)); + IntVector valueVector = valueBlock.asVector(); + if (valueVector == null) { + addRawBlock(valueBlock, timestampBlock); + return; + } + LongVector timestampVector = timestampBlock.asVector(); + if (timestampVector == null) { + addRawBlock(valueBlock, timestampBlock); + return; + } + addRawVector(valueVector, timestampVector); + } + + private void addRawVector(IntVector valueVector, LongVector timestampVector) { + state.seen(true); + for (int valuesPosition = 0; valuesPosition < valueVector.getPositionCount(); valuesPosition++) { + int valueValue = valueVector.getInt(valuesPosition); + long timestampValue = timestampVector.getLong(valuesPosition); + LastIntByTimestampAggregator.combine(state, valueValue, timestampValue); + } + } + + private void addRawVector(IntVector valueVector, LongVector timestampVector, BooleanVector mask) { + state.seen(true); + for (int valuesPosition = 0; valuesPosition < valueVector.getPositionCount(); valuesPosition++) { + if (mask.getBoolean(valuesPosition) == false) { + continue; + } + int valueValue = valueVector.getInt(valuesPosition); + long timestampValue = timestampVector.getLong(valuesPosition); + LastIntByTimestampAggregator.combine(state, valueValue, timestampValue); + } + } + + private void addRawBlock(IntBlock valueBlock, LongBlock timestampBlock) { + for (int p = 0; p < valueBlock.getPositionCount(); p++) { + if (valueBlock.isNull(p)) { + continue; + } + if (timestampBlock.isNull(p)) { + continue; + } + state.seen(true); + int valueStart = valueBlock.getFirstValueIndex(p); + int valueEnd = valueStart + valueBlock.getValueCount(p); + for (int valueOffset = valueStart; valueOffset < valueEnd; valueOffset++) { + int valueValue = valueBlock.getInt(valueOffset); + int timestampStart = timestampBlock.getFirstValueIndex(p); + int timestampEnd = timestampStart + timestampBlock.getValueCount(p); + for (int timestampOffset = timestampStart; timestampOffset < timestampEnd; timestampOffset++) { + long timestampValue = timestampBlock.getLong(timestampOffset); + LastIntByTimestampAggregator.combine(state, valueValue, timestampValue); + } + } + } + } + + private void addRawBlock(IntBlock valueBlock, LongBlock timestampBlock, BooleanVector mask) { + for (int p = 0; p < valueBlock.getPositionCount(); p++) { + if (mask.getBoolean(p) == false) { + continue; + } + if (valueBlock.isNull(p)) { + continue; + } + if (timestampBlock.isNull(p)) { + continue; + } + state.seen(true); + int valueStart = valueBlock.getFirstValueIndex(p); + int valueEnd = valueStart + valueBlock.getValueCount(p); + for (int valueOffset = valueStart; valueOffset < valueEnd; valueOffset++) { + int valueValue = valueBlock.getInt(valueOffset); + int timestampStart = timestampBlock.getFirstValueIndex(p); + int timestampEnd = timestampStart + timestampBlock.getValueCount(p); + for (int timestampOffset = timestampStart; timestampOffset < timestampEnd; timestampOffset++) { + long timestampValue = timestampBlock.getLong(timestampOffset); + LastIntByTimestampAggregator.combine(state, valueValue, timestampValue); + } + } + } + } + + @Override + public void addIntermediateInput(Page page) { + assert channels.size() == intermediateBlockCount(); + assert page.getBlockCount() >= channels.get(0) + intermediateStateDesc().size(); + Block timestampsUncast = page.getBlock(channels.get(0)); + if (timestampsUncast.areAllValuesNull()) { + return; + } + LongVector timestamps = ((LongBlock) timestampsUncast).asVector(); + assert timestamps.getPositionCount() == 1; + Block valuesUncast = page.getBlock(channels.get(1)); + if (valuesUncast.areAllValuesNull()) { + return; + } + IntVector values = ((IntBlock) valuesUncast).asVector(); + assert values.getPositionCount() == 1; + Block seenUncast = page.getBlock(channels.get(2)); + if (seenUncast.areAllValuesNull()) { + return; + } + BooleanVector seen = ((BooleanBlock) seenUncast).asVector(); + assert seen.getPositionCount() == 1; + LastIntByTimestampAggregator.combineIntermediate(state, timestamps.getLong(0), values.getInt(0), seen.getBoolean(0)); + } + + @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) { + if (state.seen() == false) { + blocks[offset] = driverContext.blockFactory().newConstantNullBlock(1); + return; + } + blocks[offset] = LastIntByTimestampAggregator.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/LastIntByTimestampAggregatorFunctionSupplier.java b/x-pack/plugin/esql/compute/src/main/generated/org/elasticsearch/compute/aggregation/LastIntByTimestampAggregatorFunctionSupplier.java index 9f5f42d6fb87b..ea4e312366301 100644 --- a/x-pack/plugin/esql/compute/src/main/generated/org/elasticsearch/compute/aggregation/LastIntByTimestampAggregatorFunctionSupplier.java +++ b/x-pack/plugin/esql/compute/src/main/generated/org/elasticsearch/compute/aggregation/LastIntByTimestampAggregatorFunctionSupplier.java @@ -20,7 +20,7 @@ public LastIntByTimestampAggregatorFunctionSupplier() { @Override public List nonGroupingIntermediateStateDesc() { - throw new UnsupportedOperationException("non-grouping aggregator is not supported"); + return LastIntByTimestampAggregatorFunction.intermediateStateDesc(); } @Override @@ -29,8 +29,9 @@ public List groupingIntermediateStateDesc() { } @Override - public AggregatorFunction aggregator(DriverContext driverContext, List channels) { - throw new UnsupportedOperationException("non-grouping aggregator is not supported"); + public LastIntByTimestampAggregatorFunction aggregator(DriverContext driverContext, + List channels) { + return LastIntByTimestampAggregatorFunction.create(driverContext, channels); } @Override @@ -41,6 +42,6 @@ public LastIntByTimestampGroupingAggregatorFunction groupingAggregator( @Override public String describe() { - return "last_int_by of timestamps"; + return LastIntByTimestampAggregator.describe(); } } diff --git a/x-pack/plugin/esql/compute/src/main/generated/org/elasticsearch/compute/aggregation/LastIntByTimestampGroupingAggregatorFunction.java b/x-pack/plugin/esql/compute/src/main/generated/org/elasticsearch/compute/aggregation/LastIntByTimestampGroupingAggregatorFunction.java index 9a3dd9e1427fa..b18b8c1a2be32 100644 --- a/x-pack/plugin/esql/compute/src/main/generated/org/elasticsearch/compute/aggregation/LastIntByTimestampGroupingAggregatorFunction.java +++ b/x-pack/plugin/esql/compute/src/main/generated/org/elasticsearch/compute/aggregation/LastIntByTimestampGroupingAggregatorFunction.java @@ -63,9 +63,7 @@ public GroupingAggregatorFunction.AddInput prepareProcessRawInputPage(SeenGroupI LongBlock timestampBlock = page.getBlock(channels.get(1)); IntVector valueVector = valueBlock.asVector(); if (valueVector == null) { - if (valueBlock.mayHaveNulls()) { - state.enableGroupIdTracking(seenGroupIds); - } + maybeEnableGroupIdTracking(seenGroupIds, valueBlock, timestampBlock); return new GroupingAggregatorFunction.AddInput() { @Override public void add(int positionOffset, IntArrayBlock groupIds) { @@ -89,9 +87,7 @@ public void close() { } LongVector timestampVector = timestampBlock.asVector(); if (timestampVector == null) { - if (timestampBlock.mayHaveNulls()) { - state.enableGroupIdTracking(seenGroupIds); - } + maybeEnableGroupIdTracking(seenGroupIds, valueBlock, timestampBlock); return new GroupingAggregatorFunction.AddInput() { @Override public void add(int positionOffset, IntArrayBlock groupIds) { @@ -351,6 +347,16 @@ public void addIntermediateInput(int positionOffset, IntVector groups, Page page } } + private void maybeEnableGroupIdTracking(SeenGroupIds seenGroupIds, IntBlock valueBlock, + LongBlock timestampBlock) { + if (valueBlock.mayHaveNulls()) { + state.enableGroupIdTracking(seenGroupIds); + } + if (timestampBlock.mayHaveNulls()) { + state.enableGroupIdTracking(seenGroupIds); + } + } + @Override public void selectedMayContainUnseenGroups(SeenGroupIds seenGroupIds) { state.enableGroupIdTracking(seenGroupIds); diff --git a/x-pack/plugin/esql/compute/src/main/generated/org/elasticsearch/compute/aggregation/LastLongByTimestampAggregatorFunction.java b/x-pack/plugin/esql/compute/src/main/generated/org/elasticsearch/compute/aggregation/LastLongByTimestampAggregatorFunction.java new file mode 100644 index 0000000000000..cc7c96cca77ca --- /dev/null +++ b/x-pack/plugin/esql/compute/src/main/generated/org/elasticsearch/compute/aggregation/LastLongByTimestampAggregatorFunction.java @@ -0,0 +1,224 @@ +// 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.BooleanBlock; +import org.elasticsearch.compute.data.BooleanVector; +import org.elasticsearch.compute.data.ElementType; +import org.elasticsearch.compute.data.LongBlock; +import org.elasticsearch.compute.data.LongVector; +import org.elasticsearch.compute.data.Page; +import org.elasticsearch.compute.operator.DriverContext; + +/** + * {@link AggregatorFunction} implementation for {@link LastLongByTimestampAggregator}. + * This class is generated. Edit {@code AggregatorImplementer} instead. + */ +public final class LastLongByTimestampAggregatorFunction implements AggregatorFunction { + private static final List INTERMEDIATE_STATE_DESC = List.of( + new IntermediateStateDesc("timestamps", ElementType.LONG), + new IntermediateStateDesc("values", ElementType.LONG), + new IntermediateStateDesc("seen", ElementType.BOOLEAN) ); + + private final DriverContext driverContext; + + private final LongLongState state; + + private final List channels; + + public LastLongByTimestampAggregatorFunction(DriverContext driverContext, List channels, + LongLongState state) { + this.driverContext = driverContext; + this.channels = channels; + this.state = state; + } + + public static LastLongByTimestampAggregatorFunction create(DriverContext driverContext, + List channels) { + return new LastLongByTimestampAggregatorFunction(driverContext, channels, LastLongByTimestampAggregator.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) { + LongBlock valueBlock = page.getBlock(channels.get(0)); + LongBlock timestampBlock = page.getBlock(channels.get(1)); + LongVector valueVector = valueBlock.asVector(); + if (valueVector == null) { + addRawBlock(valueBlock, timestampBlock, mask); + return; + } + LongVector timestampVector = timestampBlock.asVector(); + if (timestampVector == null) { + addRawBlock(valueBlock, timestampBlock, mask); + return; + } + addRawVector(valueVector, timestampVector, mask); + } + + private void addRawInputNotMasked(Page page) { + LongBlock valueBlock = page.getBlock(channels.get(0)); + LongBlock timestampBlock = page.getBlock(channels.get(1)); + LongVector valueVector = valueBlock.asVector(); + if (valueVector == null) { + addRawBlock(valueBlock, timestampBlock); + return; + } + LongVector timestampVector = timestampBlock.asVector(); + if (timestampVector == null) { + addRawBlock(valueBlock, timestampBlock); + return; + } + addRawVector(valueVector, timestampVector); + } + + private void addRawVector(LongVector valueVector, LongVector timestampVector) { + state.seen(true); + for (int valuesPosition = 0; valuesPosition < valueVector.getPositionCount(); valuesPosition++) { + long valueValue = valueVector.getLong(valuesPosition); + long timestampValue = timestampVector.getLong(valuesPosition); + LastLongByTimestampAggregator.combine(state, valueValue, timestampValue); + } + } + + private void addRawVector(LongVector valueVector, LongVector timestampVector, + BooleanVector mask) { + state.seen(true); + for (int valuesPosition = 0; valuesPosition < valueVector.getPositionCount(); valuesPosition++) { + if (mask.getBoolean(valuesPosition) == false) { + continue; + } + long valueValue = valueVector.getLong(valuesPosition); + long timestampValue = timestampVector.getLong(valuesPosition); + LastLongByTimestampAggregator.combine(state, valueValue, timestampValue); + } + } + + private void addRawBlock(LongBlock valueBlock, LongBlock timestampBlock) { + for (int p = 0; p < valueBlock.getPositionCount(); p++) { + if (valueBlock.isNull(p)) { + continue; + } + if (timestampBlock.isNull(p)) { + continue; + } + state.seen(true); + int valueStart = valueBlock.getFirstValueIndex(p); + int valueEnd = valueStart + valueBlock.getValueCount(p); + for (int valueOffset = valueStart; valueOffset < valueEnd; valueOffset++) { + long valueValue = valueBlock.getLong(valueOffset); + int timestampStart = timestampBlock.getFirstValueIndex(p); + int timestampEnd = timestampStart + timestampBlock.getValueCount(p); + for (int timestampOffset = timestampStart; timestampOffset < timestampEnd; timestampOffset++) { + long timestampValue = timestampBlock.getLong(timestampOffset); + LastLongByTimestampAggregator.combine(state, valueValue, timestampValue); + } + } + } + } + + private void addRawBlock(LongBlock valueBlock, LongBlock timestampBlock, BooleanVector mask) { + for (int p = 0; p < valueBlock.getPositionCount(); p++) { + if (mask.getBoolean(p) == false) { + continue; + } + if (valueBlock.isNull(p)) { + continue; + } + if (timestampBlock.isNull(p)) { + continue; + } + state.seen(true); + int valueStart = valueBlock.getFirstValueIndex(p); + int valueEnd = valueStart + valueBlock.getValueCount(p); + for (int valueOffset = valueStart; valueOffset < valueEnd; valueOffset++) { + long valueValue = valueBlock.getLong(valueOffset); + int timestampStart = timestampBlock.getFirstValueIndex(p); + int timestampEnd = timestampStart + timestampBlock.getValueCount(p); + for (int timestampOffset = timestampStart; timestampOffset < timestampEnd; timestampOffset++) { + long timestampValue = timestampBlock.getLong(timestampOffset); + LastLongByTimestampAggregator.combine(state, valueValue, timestampValue); + } + } + } + } + + @Override + public void addIntermediateInput(Page page) { + assert channels.size() == intermediateBlockCount(); + assert page.getBlockCount() >= channels.get(0) + intermediateStateDesc().size(); + Block timestampsUncast = page.getBlock(channels.get(0)); + if (timestampsUncast.areAllValuesNull()) { + return; + } + LongVector timestamps = ((LongBlock) timestampsUncast).asVector(); + assert timestamps.getPositionCount() == 1; + Block valuesUncast = page.getBlock(channels.get(1)); + if (valuesUncast.areAllValuesNull()) { + return; + } + LongVector values = ((LongBlock) valuesUncast).asVector(); + assert values.getPositionCount() == 1; + Block seenUncast = page.getBlock(channels.get(2)); + if (seenUncast.areAllValuesNull()) { + return; + } + BooleanVector seen = ((BooleanBlock) seenUncast).asVector(); + assert seen.getPositionCount() == 1; + LastLongByTimestampAggregator.combineIntermediate(state, timestamps.getLong(0), values.getLong(0), seen.getBoolean(0)); + } + + @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) { + if (state.seen() == false) { + blocks[offset] = driverContext.blockFactory().newConstantNullBlock(1); + return; + } + blocks[offset] = LastLongByTimestampAggregator.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/LastLongByTimestampAggregatorFunctionSupplier.java b/x-pack/plugin/esql/compute/src/main/generated/org/elasticsearch/compute/aggregation/LastLongByTimestampAggregatorFunctionSupplier.java index 84948a1b9fa22..6653b82eba5f2 100644 --- a/x-pack/plugin/esql/compute/src/main/generated/org/elasticsearch/compute/aggregation/LastLongByTimestampAggregatorFunctionSupplier.java +++ b/x-pack/plugin/esql/compute/src/main/generated/org/elasticsearch/compute/aggregation/LastLongByTimestampAggregatorFunctionSupplier.java @@ -20,7 +20,7 @@ public LastLongByTimestampAggregatorFunctionSupplier() { @Override public List nonGroupingIntermediateStateDesc() { - throw new UnsupportedOperationException("non-grouping aggregator is not supported"); + return LastLongByTimestampAggregatorFunction.intermediateStateDesc(); } @Override @@ -29,8 +29,9 @@ public List groupingIntermediateStateDesc() { } @Override - public AggregatorFunction aggregator(DriverContext driverContext, List channels) { - throw new UnsupportedOperationException("non-grouping aggregator is not supported"); + public LastLongByTimestampAggregatorFunction aggregator(DriverContext driverContext, + List channels) { + return LastLongByTimestampAggregatorFunction.create(driverContext, channels); } @Override @@ -41,6 +42,6 @@ public LastLongByTimestampGroupingAggregatorFunction groupingAggregator( @Override public String describe() { - return "last_long_by of timestamps"; + return LastLongByTimestampAggregator.describe(); } } diff --git a/x-pack/plugin/esql/compute/src/main/generated/org/elasticsearch/compute/aggregation/LastLongByTimestampGroupingAggregatorFunction.java b/x-pack/plugin/esql/compute/src/main/generated/org/elasticsearch/compute/aggregation/LastLongByTimestampGroupingAggregatorFunction.java index ae484682af85b..f21bcf25772d8 100644 --- a/x-pack/plugin/esql/compute/src/main/generated/org/elasticsearch/compute/aggregation/LastLongByTimestampGroupingAggregatorFunction.java +++ b/x-pack/plugin/esql/compute/src/main/generated/org/elasticsearch/compute/aggregation/LastLongByTimestampGroupingAggregatorFunction.java @@ -62,9 +62,7 @@ public GroupingAggregatorFunction.AddInput prepareProcessRawInputPage(SeenGroupI LongBlock timestampBlock = page.getBlock(channels.get(1)); LongVector valueVector = valueBlock.asVector(); if (valueVector == null) { - if (valueBlock.mayHaveNulls()) { - state.enableGroupIdTracking(seenGroupIds); - } + maybeEnableGroupIdTracking(seenGroupIds, valueBlock, timestampBlock); return new GroupingAggregatorFunction.AddInput() { @Override public void add(int positionOffset, IntArrayBlock groupIds) { @@ -88,9 +86,7 @@ public void close() { } LongVector timestampVector = timestampBlock.asVector(); if (timestampVector == null) { - if (timestampBlock.mayHaveNulls()) { - state.enableGroupIdTracking(seenGroupIds); - } + maybeEnableGroupIdTracking(seenGroupIds, valueBlock, timestampBlock); return new GroupingAggregatorFunction.AddInput() { @Override public void add(int positionOffset, IntArrayBlock groupIds) { @@ -350,6 +346,16 @@ public void addIntermediateInput(int positionOffset, IntVector groups, Page page } } + private void maybeEnableGroupIdTracking(SeenGroupIds seenGroupIds, LongBlock valueBlock, + LongBlock timestampBlock) { + if (valueBlock.mayHaveNulls()) { + state.enableGroupIdTracking(seenGroupIds); + } + if (timestampBlock.mayHaveNulls()) { + state.enableGroupIdTracking(seenGroupIds); + } + } + @Override public void selectedMayContainUnseenGroups(SeenGroupIds seenGroupIds) { state.enableGroupIdTracking(seenGroupIds); diff --git a/x-pack/plugin/esql/compute/src/main/generated/org/elasticsearch/compute/aggregation/MaxBooleanGroupingAggregatorFunction.java b/x-pack/plugin/esql/compute/src/main/generated/org/elasticsearch/compute/aggregation/MaxBooleanGroupingAggregatorFunction.java index 4a2f0b8b40739..23d461db90fee 100644 --- a/x-pack/plugin/esql/compute/src/main/generated/org/elasticsearch/compute/aggregation/MaxBooleanGroupingAggregatorFunction.java +++ b/x-pack/plugin/esql/compute/src/main/generated/org/elasticsearch/compute/aggregation/MaxBooleanGroupingAggregatorFunction.java @@ -61,9 +61,7 @@ public GroupingAggregatorFunction.AddInput prepareProcessRawInputPage(SeenGroupI BooleanBlock vBlock = page.getBlock(channels.get(0)); BooleanVector vVector = vBlock.asVector(); if (vVector == null) { - if (vBlock.mayHaveNulls()) { - state.enableGroupIdTracking(seenGroupIds); - } + maybeEnableGroupIdTracking(seenGroupIds, vBlock); return new GroupingAggregatorFunction.AddInput() { @Override public void add(int positionOffset, IntArrayBlock groupIds) { @@ -296,6 +294,12 @@ public void addIntermediateInput(int positionOffset, IntVector groups, Page page } } + private void maybeEnableGroupIdTracking(SeenGroupIds seenGroupIds, BooleanBlock vBlock) { + if (vBlock.mayHaveNulls()) { + state.enableGroupIdTracking(seenGroupIds); + } + } + @Override public void selectedMayContainUnseenGroups(SeenGroupIds seenGroupIds) { state.enableGroupIdTracking(seenGroupIds); 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 43e5dbfb35ce8..793570db726a9 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 @@ -64,9 +64,7 @@ public GroupingAggregatorFunction.AddInput prepareProcessRawInputPage(SeenGroupI BytesRefBlock valueBlock = page.getBlock(channels.get(0)); BytesRefVector valueVector = valueBlock.asVector(); if (valueVector == null) { - if (valueBlock.mayHaveNulls()) { - state.enableGroupIdTracking(seenGroupIds); - } + maybeEnableGroupIdTracking(seenGroupIds, valueBlock); return new GroupingAggregatorFunction.AddInput() { @Override public void add(int positionOffset, IntArrayBlock groupIds) { @@ -303,6 +301,12 @@ public void addIntermediateInput(int positionOffset, IntVector groups, Page page } } + private void maybeEnableGroupIdTracking(SeenGroupIds seenGroupIds, BytesRefBlock valueBlock) { + if (valueBlock.mayHaveNulls()) { + state.enableGroupIdTracking(seenGroupIds); + } + } + @Override public void selectedMayContainUnseenGroups(SeenGroupIds seenGroupIds) { state.enableGroupIdTracking(seenGroupIds); diff --git a/x-pack/plugin/esql/compute/src/main/generated/org/elasticsearch/compute/aggregation/MaxDoubleGroupingAggregatorFunction.java b/x-pack/plugin/esql/compute/src/main/generated/org/elasticsearch/compute/aggregation/MaxDoubleGroupingAggregatorFunction.java index 2f4814848c152..0e29f1cdb45ec 100644 --- a/x-pack/plugin/esql/compute/src/main/generated/org/elasticsearch/compute/aggregation/MaxDoubleGroupingAggregatorFunction.java +++ b/x-pack/plugin/esql/compute/src/main/generated/org/elasticsearch/compute/aggregation/MaxDoubleGroupingAggregatorFunction.java @@ -63,9 +63,7 @@ public GroupingAggregatorFunction.AddInput prepareProcessRawInputPage(SeenGroupI DoubleBlock vBlock = page.getBlock(channels.get(0)); DoubleVector vVector = vBlock.asVector(); if (vVector == null) { - if (vBlock.mayHaveNulls()) { - state.enableGroupIdTracking(seenGroupIds); - } + maybeEnableGroupIdTracking(seenGroupIds, vBlock); return new GroupingAggregatorFunction.AddInput() { @Override public void add(int positionOffset, IntArrayBlock groupIds) { @@ -298,6 +296,12 @@ public void addIntermediateInput(int positionOffset, IntVector groups, Page page } } + private void maybeEnableGroupIdTracking(SeenGroupIds seenGroupIds, DoubleBlock vBlock) { + if (vBlock.mayHaveNulls()) { + state.enableGroupIdTracking(seenGroupIds); + } + } + @Override public void selectedMayContainUnseenGroups(SeenGroupIds seenGroupIds) { state.enableGroupIdTracking(seenGroupIds); diff --git a/x-pack/plugin/esql/compute/src/main/generated/org/elasticsearch/compute/aggregation/MaxFloatGroupingAggregatorFunction.java b/x-pack/plugin/esql/compute/src/main/generated/org/elasticsearch/compute/aggregation/MaxFloatGroupingAggregatorFunction.java index 5c0d700c6e874..a0f1a8664bc87 100644 --- a/x-pack/plugin/esql/compute/src/main/generated/org/elasticsearch/compute/aggregation/MaxFloatGroupingAggregatorFunction.java +++ b/x-pack/plugin/esql/compute/src/main/generated/org/elasticsearch/compute/aggregation/MaxFloatGroupingAggregatorFunction.java @@ -63,9 +63,7 @@ public GroupingAggregatorFunction.AddInput prepareProcessRawInputPage(SeenGroupI FloatBlock vBlock = page.getBlock(channels.get(0)); FloatVector vVector = vBlock.asVector(); if (vVector == null) { - if (vBlock.mayHaveNulls()) { - state.enableGroupIdTracking(seenGroupIds); - } + maybeEnableGroupIdTracking(seenGroupIds, vBlock); return new GroupingAggregatorFunction.AddInput() { @Override public void add(int positionOffset, IntArrayBlock groupIds) { @@ -298,6 +296,12 @@ public void addIntermediateInput(int positionOffset, IntVector groups, Page page } } + private void maybeEnableGroupIdTracking(SeenGroupIds seenGroupIds, FloatBlock vBlock) { + if (vBlock.mayHaveNulls()) { + state.enableGroupIdTracking(seenGroupIds); + } + } + @Override public void selectedMayContainUnseenGroups(SeenGroupIds seenGroupIds) { state.enableGroupIdTracking(seenGroupIds); diff --git a/x-pack/plugin/esql/compute/src/main/generated/org/elasticsearch/compute/aggregation/MaxIntGroupingAggregatorFunction.java b/x-pack/plugin/esql/compute/src/main/generated/org/elasticsearch/compute/aggregation/MaxIntGroupingAggregatorFunction.java index 1a8cb4b64f704..a173f02e8ece1 100644 --- a/x-pack/plugin/esql/compute/src/main/generated/org/elasticsearch/compute/aggregation/MaxIntGroupingAggregatorFunction.java +++ b/x-pack/plugin/esql/compute/src/main/generated/org/elasticsearch/compute/aggregation/MaxIntGroupingAggregatorFunction.java @@ -62,9 +62,7 @@ public GroupingAggregatorFunction.AddInput prepareProcessRawInputPage(SeenGroupI IntBlock vBlock = page.getBlock(channels.get(0)); IntVector vVector = vBlock.asVector(); if (vVector == null) { - if (vBlock.mayHaveNulls()) { - state.enableGroupIdTracking(seenGroupIds); - } + maybeEnableGroupIdTracking(seenGroupIds, vBlock); return new GroupingAggregatorFunction.AddInput() { @Override public void add(int positionOffset, IntArrayBlock groupIds) { @@ -297,6 +295,12 @@ public void addIntermediateInput(int positionOffset, IntVector groups, Page page } } + private void maybeEnableGroupIdTracking(SeenGroupIds seenGroupIds, IntBlock vBlock) { + if (vBlock.mayHaveNulls()) { + state.enableGroupIdTracking(seenGroupIds); + } + } + @Override public void selectedMayContainUnseenGroups(SeenGroupIds seenGroupIds) { state.enableGroupIdTracking(seenGroupIds); 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 cb7694d565475..bfee9d26f3996 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 @@ -64,9 +64,7 @@ public GroupingAggregatorFunction.AddInput prepareProcessRawInputPage(SeenGroupI BytesRefBlock valueBlock = page.getBlock(channels.get(0)); BytesRefVector valueVector = valueBlock.asVector(); if (valueVector == null) { - if (valueBlock.mayHaveNulls()) { - state.enableGroupIdTracking(seenGroupIds); - } + maybeEnableGroupIdTracking(seenGroupIds, valueBlock); return new GroupingAggregatorFunction.AddInput() { @Override public void add(int positionOffset, IntArrayBlock groupIds) { @@ -303,6 +301,12 @@ public void addIntermediateInput(int positionOffset, IntVector groups, Page page } } + private void maybeEnableGroupIdTracking(SeenGroupIds seenGroupIds, BytesRefBlock valueBlock) { + if (valueBlock.mayHaveNulls()) { + state.enableGroupIdTracking(seenGroupIds); + } + } + @Override public void selectedMayContainUnseenGroups(SeenGroupIds seenGroupIds) { state.enableGroupIdTracking(seenGroupIds); diff --git a/x-pack/plugin/esql/compute/src/main/generated/org/elasticsearch/compute/aggregation/MaxLongGroupingAggregatorFunction.java b/x-pack/plugin/esql/compute/src/main/generated/org/elasticsearch/compute/aggregation/MaxLongGroupingAggregatorFunction.java index 8b2203efa811b..5cd1c6fdd002e 100644 --- a/x-pack/plugin/esql/compute/src/main/generated/org/elasticsearch/compute/aggregation/MaxLongGroupingAggregatorFunction.java +++ b/x-pack/plugin/esql/compute/src/main/generated/org/elasticsearch/compute/aggregation/MaxLongGroupingAggregatorFunction.java @@ -63,9 +63,7 @@ public GroupingAggregatorFunction.AddInput prepareProcessRawInputPage(SeenGroupI LongBlock vBlock = page.getBlock(channels.get(0)); LongVector vVector = vBlock.asVector(); if (vVector == null) { - if (vBlock.mayHaveNulls()) { - state.enableGroupIdTracking(seenGroupIds); - } + maybeEnableGroupIdTracking(seenGroupIds, vBlock); return new GroupingAggregatorFunction.AddInput() { @Override public void add(int positionOffset, IntArrayBlock groupIds) { @@ -298,6 +296,12 @@ public void addIntermediateInput(int positionOffset, IntVector groups, Page page } } + private void maybeEnableGroupIdTracking(SeenGroupIds seenGroupIds, LongBlock vBlock) { + if (vBlock.mayHaveNulls()) { + state.enableGroupIdTracking(seenGroupIds); + } + } + @Override public void selectedMayContainUnseenGroups(SeenGroupIds seenGroupIds) { state.enableGroupIdTracking(seenGroupIds); 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 808a325493a80..3fd6a54970645 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 @@ -63,9 +63,7 @@ public GroupingAggregatorFunction.AddInput prepareProcessRawInputPage(SeenGroupI DoubleBlock vBlock = page.getBlock(channels.get(0)); DoubleVector vVector = vBlock.asVector(); if (vVector == null) { - if (vBlock.mayHaveNulls()) { - state.enableGroupIdTracking(seenGroupIds); - } + maybeEnableGroupIdTracking(seenGroupIds, vBlock); return new GroupingAggregatorFunction.AddInput() { @Override public void add(int positionOffset, IntArrayBlock groupIds) { @@ -277,6 +275,12 @@ public void addIntermediateInput(int positionOffset, IntVector groups, Page page } } + private void maybeEnableGroupIdTracking(SeenGroupIds seenGroupIds, DoubleBlock vBlock) { + if (vBlock.mayHaveNulls()) { + state.enableGroupIdTracking(seenGroupIds); + } + } + @Override public void selectedMayContainUnseenGroups(SeenGroupIds seenGroupIds) { state.enableGroupIdTracking(seenGroupIds); 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 78adf388821d6..c706d6a68b9ad 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 @@ -63,9 +63,7 @@ public GroupingAggregatorFunction.AddInput prepareProcessRawInputPage(SeenGroupI FloatBlock vBlock = page.getBlock(channels.get(0)); FloatVector vVector = vBlock.asVector(); if (vVector == null) { - if (vBlock.mayHaveNulls()) { - state.enableGroupIdTracking(seenGroupIds); - } + maybeEnableGroupIdTracking(seenGroupIds, vBlock); return new GroupingAggregatorFunction.AddInput() { @Override public void add(int positionOffset, IntArrayBlock groupIds) { @@ -277,6 +275,12 @@ public void addIntermediateInput(int positionOffset, IntVector groups, Page page } } + private void maybeEnableGroupIdTracking(SeenGroupIds seenGroupIds, FloatBlock vBlock) { + if (vBlock.mayHaveNulls()) { + state.enableGroupIdTracking(seenGroupIds); + } + } + @Override public void selectedMayContainUnseenGroups(SeenGroupIds seenGroupIds) { state.enableGroupIdTracking(seenGroupIds); 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 4a391939a0072..171e4238f68c7 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 @@ -62,9 +62,7 @@ public GroupingAggregatorFunction.AddInput prepareProcessRawInputPage(SeenGroupI IntBlock vBlock = page.getBlock(channels.get(0)); IntVector vVector = vBlock.asVector(); if (vVector == null) { - if (vBlock.mayHaveNulls()) { - state.enableGroupIdTracking(seenGroupIds); - } + maybeEnableGroupIdTracking(seenGroupIds, vBlock); return new GroupingAggregatorFunction.AddInput() { @Override public void add(int positionOffset, IntArrayBlock groupIds) { @@ -276,6 +274,12 @@ public void addIntermediateInput(int positionOffset, IntVector groups, Page page } } + private void maybeEnableGroupIdTracking(SeenGroupIds seenGroupIds, IntBlock vBlock) { + if (vBlock.mayHaveNulls()) { + state.enableGroupIdTracking(seenGroupIds); + } + } + @Override public void selectedMayContainUnseenGroups(SeenGroupIds seenGroupIds) { state.enableGroupIdTracking(seenGroupIds); 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 4220ba3a20007..2136c8d0fd1fd 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 @@ -63,9 +63,7 @@ public GroupingAggregatorFunction.AddInput prepareProcessRawInputPage(SeenGroupI LongBlock vBlock = page.getBlock(channels.get(0)); LongVector vVector = vBlock.asVector(); if (vVector == null) { - if (vBlock.mayHaveNulls()) { - state.enableGroupIdTracking(seenGroupIds); - } + maybeEnableGroupIdTracking(seenGroupIds, vBlock); return new GroupingAggregatorFunction.AddInput() { @Override public void add(int positionOffset, IntArrayBlock groupIds) { @@ -277,6 +275,12 @@ public void addIntermediateInput(int positionOffset, IntVector groups, Page page } } + private void maybeEnableGroupIdTracking(SeenGroupIds seenGroupIds, LongBlock vBlock) { + if (vBlock.mayHaveNulls()) { + state.enableGroupIdTracking(seenGroupIds); + } + } + @Override public void selectedMayContainUnseenGroups(SeenGroupIds seenGroupIds) { state.enableGroupIdTracking(seenGroupIds); diff --git a/x-pack/plugin/esql/compute/src/main/generated/org/elasticsearch/compute/aggregation/MinBooleanGroupingAggregatorFunction.java b/x-pack/plugin/esql/compute/src/main/generated/org/elasticsearch/compute/aggregation/MinBooleanGroupingAggregatorFunction.java index 3f0398e78f806..344a5bbd90269 100644 --- a/x-pack/plugin/esql/compute/src/main/generated/org/elasticsearch/compute/aggregation/MinBooleanGroupingAggregatorFunction.java +++ b/x-pack/plugin/esql/compute/src/main/generated/org/elasticsearch/compute/aggregation/MinBooleanGroupingAggregatorFunction.java @@ -61,9 +61,7 @@ public GroupingAggregatorFunction.AddInput prepareProcessRawInputPage(SeenGroupI BooleanBlock vBlock = page.getBlock(channels.get(0)); BooleanVector vVector = vBlock.asVector(); if (vVector == null) { - if (vBlock.mayHaveNulls()) { - state.enableGroupIdTracking(seenGroupIds); - } + maybeEnableGroupIdTracking(seenGroupIds, vBlock); return new GroupingAggregatorFunction.AddInput() { @Override public void add(int positionOffset, IntArrayBlock groupIds) { @@ -296,6 +294,12 @@ public void addIntermediateInput(int positionOffset, IntVector groups, Page page } } + private void maybeEnableGroupIdTracking(SeenGroupIds seenGroupIds, BooleanBlock vBlock) { + if (vBlock.mayHaveNulls()) { + state.enableGroupIdTracking(seenGroupIds); + } + } + @Override public void selectedMayContainUnseenGroups(SeenGroupIds seenGroupIds) { state.enableGroupIdTracking(seenGroupIds); 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 7a282440476d8..e3acfe1ab1943 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 @@ -64,9 +64,7 @@ public GroupingAggregatorFunction.AddInput prepareProcessRawInputPage(SeenGroupI BytesRefBlock valueBlock = page.getBlock(channels.get(0)); BytesRefVector valueVector = valueBlock.asVector(); if (valueVector == null) { - if (valueBlock.mayHaveNulls()) { - state.enableGroupIdTracking(seenGroupIds); - } + maybeEnableGroupIdTracking(seenGroupIds, valueBlock); return new GroupingAggregatorFunction.AddInput() { @Override public void add(int positionOffset, IntArrayBlock groupIds) { @@ -303,6 +301,12 @@ public void addIntermediateInput(int positionOffset, IntVector groups, Page page } } + private void maybeEnableGroupIdTracking(SeenGroupIds seenGroupIds, BytesRefBlock valueBlock) { + if (valueBlock.mayHaveNulls()) { + state.enableGroupIdTracking(seenGroupIds); + } + } + @Override public void selectedMayContainUnseenGroups(SeenGroupIds seenGroupIds) { state.enableGroupIdTracking(seenGroupIds); diff --git a/x-pack/plugin/esql/compute/src/main/generated/org/elasticsearch/compute/aggregation/MinDoubleGroupingAggregatorFunction.java b/x-pack/plugin/esql/compute/src/main/generated/org/elasticsearch/compute/aggregation/MinDoubleGroupingAggregatorFunction.java index 31cbc2cb5c860..e621dfe9aef38 100644 --- a/x-pack/plugin/esql/compute/src/main/generated/org/elasticsearch/compute/aggregation/MinDoubleGroupingAggregatorFunction.java +++ b/x-pack/plugin/esql/compute/src/main/generated/org/elasticsearch/compute/aggregation/MinDoubleGroupingAggregatorFunction.java @@ -63,9 +63,7 @@ public GroupingAggregatorFunction.AddInput prepareProcessRawInputPage(SeenGroupI DoubleBlock vBlock = page.getBlock(channels.get(0)); DoubleVector vVector = vBlock.asVector(); if (vVector == null) { - if (vBlock.mayHaveNulls()) { - state.enableGroupIdTracking(seenGroupIds); - } + maybeEnableGroupIdTracking(seenGroupIds, vBlock); return new GroupingAggregatorFunction.AddInput() { @Override public void add(int positionOffset, IntArrayBlock groupIds) { @@ -298,6 +296,12 @@ public void addIntermediateInput(int positionOffset, IntVector groups, Page page } } + private void maybeEnableGroupIdTracking(SeenGroupIds seenGroupIds, DoubleBlock vBlock) { + if (vBlock.mayHaveNulls()) { + state.enableGroupIdTracking(seenGroupIds); + } + } + @Override public void selectedMayContainUnseenGroups(SeenGroupIds seenGroupIds) { state.enableGroupIdTracking(seenGroupIds); diff --git a/x-pack/plugin/esql/compute/src/main/generated/org/elasticsearch/compute/aggregation/MinFloatGroupingAggregatorFunction.java b/x-pack/plugin/esql/compute/src/main/generated/org/elasticsearch/compute/aggregation/MinFloatGroupingAggregatorFunction.java index b56cfd30ad575..2a0f1e96daa74 100644 --- a/x-pack/plugin/esql/compute/src/main/generated/org/elasticsearch/compute/aggregation/MinFloatGroupingAggregatorFunction.java +++ b/x-pack/plugin/esql/compute/src/main/generated/org/elasticsearch/compute/aggregation/MinFloatGroupingAggregatorFunction.java @@ -63,9 +63,7 @@ public GroupingAggregatorFunction.AddInput prepareProcessRawInputPage(SeenGroupI FloatBlock vBlock = page.getBlock(channels.get(0)); FloatVector vVector = vBlock.asVector(); if (vVector == null) { - if (vBlock.mayHaveNulls()) { - state.enableGroupIdTracking(seenGroupIds); - } + maybeEnableGroupIdTracking(seenGroupIds, vBlock); return new GroupingAggregatorFunction.AddInput() { @Override public void add(int positionOffset, IntArrayBlock groupIds) { @@ -298,6 +296,12 @@ public void addIntermediateInput(int positionOffset, IntVector groups, Page page } } + private void maybeEnableGroupIdTracking(SeenGroupIds seenGroupIds, FloatBlock vBlock) { + if (vBlock.mayHaveNulls()) { + state.enableGroupIdTracking(seenGroupIds); + } + } + @Override public void selectedMayContainUnseenGroups(SeenGroupIds seenGroupIds) { state.enableGroupIdTracking(seenGroupIds); diff --git a/x-pack/plugin/esql/compute/src/main/generated/org/elasticsearch/compute/aggregation/MinIntGroupingAggregatorFunction.java b/x-pack/plugin/esql/compute/src/main/generated/org/elasticsearch/compute/aggregation/MinIntGroupingAggregatorFunction.java index e0792edddad89..00d254643bb48 100644 --- a/x-pack/plugin/esql/compute/src/main/generated/org/elasticsearch/compute/aggregation/MinIntGroupingAggregatorFunction.java +++ b/x-pack/plugin/esql/compute/src/main/generated/org/elasticsearch/compute/aggregation/MinIntGroupingAggregatorFunction.java @@ -62,9 +62,7 @@ public GroupingAggregatorFunction.AddInput prepareProcessRawInputPage(SeenGroupI IntBlock vBlock = page.getBlock(channels.get(0)); IntVector vVector = vBlock.asVector(); if (vVector == null) { - if (vBlock.mayHaveNulls()) { - state.enableGroupIdTracking(seenGroupIds); - } + maybeEnableGroupIdTracking(seenGroupIds, vBlock); return new GroupingAggregatorFunction.AddInput() { @Override public void add(int positionOffset, IntArrayBlock groupIds) { @@ -297,6 +295,12 @@ public void addIntermediateInput(int positionOffset, IntVector groups, Page page } } + private void maybeEnableGroupIdTracking(SeenGroupIds seenGroupIds, IntBlock vBlock) { + if (vBlock.mayHaveNulls()) { + state.enableGroupIdTracking(seenGroupIds); + } + } + @Override public void selectedMayContainUnseenGroups(SeenGroupIds seenGroupIds) { state.enableGroupIdTracking(seenGroupIds); 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 953103bff6589..69b3c227a2dab 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 @@ -64,9 +64,7 @@ public GroupingAggregatorFunction.AddInput prepareProcessRawInputPage(SeenGroupI BytesRefBlock valueBlock = page.getBlock(channels.get(0)); BytesRefVector valueVector = valueBlock.asVector(); if (valueVector == null) { - if (valueBlock.mayHaveNulls()) { - state.enableGroupIdTracking(seenGroupIds); - } + maybeEnableGroupIdTracking(seenGroupIds, valueBlock); return new GroupingAggregatorFunction.AddInput() { @Override public void add(int positionOffset, IntArrayBlock groupIds) { @@ -303,6 +301,12 @@ public void addIntermediateInput(int positionOffset, IntVector groups, Page page } } + private void maybeEnableGroupIdTracking(SeenGroupIds seenGroupIds, BytesRefBlock valueBlock) { + if (valueBlock.mayHaveNulls()) { + state.enableGroupIdTracking(seenGroupIds); + } + } + @Override public void selectedMayContainUnseenGroups(SeenGroupIds seenGroupIds) { state.enableGroupIdTracking(seenGroupIds); diff --git a/x-pack/plugin/esql/compute/src/main/generated/org/elasticsearch/compute/aggregation/MinLongGroupingAggregatorFunction.java b/x-pack/plugin/esql/compute/src/main/generated/org/elasticsearch/compute/aggregation/MinLongGroupingAggregatorFunction.java index b723d4b7e98cb..a248ad8b70fdb 100644 --- a/x-pack/plugin/esql/compute/src/main/generated/org/elasticsearch/compute/aggregation/MinLongGroupingAggregatorFunction.java +++ b/x-pack/plugin/esql/compute/src/main/generated/org/elasticsearch/compute/aggregation/MinLongGroupingAggregatorFunction.java @@ -63,9 +63,7 @@ public GroupingAggregatorFunction.AddInput prepareProcessRawInputPage(SeenGroupI LongBlock vBlock = page.getBlock(channels.get(0)); LongVector vVector = vBlock.asVector(); if (vVector == null) { - if (vBlock.mayHaveNulls()) { - state.enableGroupIdTracking(seenGroupIds); - } + maybeEnableGroupIdTracking(seenGroupIds, vBlock); return new GroupingAggregatorFunction.AddInput() { @Override public void add(int positionOffset, IntArrayBlock groupIds) { @@ -298,6 +296,12 @@ public void addIntermediateInput(int positionOffset, IntVector groups, Page page } } + private void maybeEnableGroupIdTracking(SeenGroupIds seenGroupIds, LongBlock vBlock) { + if (vBlock.mayHaveNulls()) { + state.enableGroupIdTracking(seenGroupIds); + } + } + @Override public void selectedMayContainUnseenGroups(SeenGroupIds seenGroupIds) { state.enableGroupIdTracking(seenGroupIds); 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 b9f780dd8a5db..f726423df4d4d 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 @@ -66,9 +66,7 @@ public GroupingAggregatorFunction.AddInput prepareProcessRawInputPage(SeenGroupI DoubleBlock vBlock = page.getBlock(channels.get(0)); DoubleVector vVector = vBlock.asVector(); if (vVector == null) { - if (vBlock.mayHaveNulls()) { - state.enableGroupIdTracking(seenGroupIds); - } + maybeEnableGroupIdTracking(seenGroupIds, vBlock); return new GroupingAggregatorFunction.AddInput() { @Override public void add(int positionOffset, IntArrayBlock groupIds) { @@ -280,6 +278,12 @@ public void addIntermediateInput(int positionOffset, IntVector groups, Page page } } + private void maybeEnableGroupIdTracking(SeenGroupIds seenGroupIds, DoubleBlock vBlock) { + if (vBlock.mayHaveNulls()) { + state.enableGroupIdTracking(seenGroupIds); + } + } + @Override public void selectedMayContainUnseenGroups(SeenGroupIds seenGroupIds) { state.enableGroupIdTracking(seenGroupIds); 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 e3165404615c4..b5be9cc7655bd 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 @@ -66,9 +66,7 @@ public GroupingAggregatorFunction.AddInput prepareProcessRawInputPage(SeenGroupI FloatBlock vBlock = page.getBlock(channels.get(0)); FloatVector vVector = vBlock.asVector(); if (vVector == null) { - if (vBlock.mayHaveNulls()) { - state.enableGroupIdTracking(seenGroupIds); - } + maybeEnableGroupIdTracking(seenGroupIds, vBlock); return new GroupingAggregatorFunction.AddInput() { @Override public void add(int positionOffset, IntArrayBlock groupIds) { @@ -280,6 +278,12 @@ public void addIntermediateInput(int positionOffset, IntVector groups, Page page } } + private void maybeEnableGroupIdTracking(SeenGroupIds seenGroupIds, FloatBlock vBlock) { + if (vBlock.mayHaveNulls()) { + state.enableGroupIdTracking(seenGroupIds); + } + } + @Override public void selectedMayContainUnseenGroups(SeenGroupIds seenGroupIds) { state.enableGroupIdTracking(seenGroupIds); 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 e12705eeb6eb0..c94cc37109e4e 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 @@ -65,9 +65,7 @@ public GroupingAggregatorFunction.AddInput prepareProcessRawInputPage(SeenGroupI IntBlock vBlock = page.getBlock(channels.get(0)); IntVector vVector = vBlock.asVector(); if (vVector == null) { - if (vBlock.mayHaveNulls()) { - state.enableGroupIdTracking(seenGroupIds); - } + maybeEnableGroupIdTracking(seenGroupIds, vBlock); return new GroupingAggregatorFunction.AddInput() { @Override public void add(int positionOffset, IntArrayBlock groupIds) { @@ -279,6 +277,12 @@ public void addIntermediateInput(int positionOffset, IntVector groups, Page page } } + private void maybeEnableGroupIdTracking(SeenGroupIds seenGroupIds, IntBlock vBlock) { + if (vBlock.mayHaveNulls()) { + state.enableGroupIdTracking(seenGroupIds); + } + } + @Override public void selectedMayContainUnseenGroups(SeenGroupIds seenGroupIds) { state.enableGroupIdTracking(seenGroupIds); 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 069f614a2132d..d48770a77abf2 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 @@ -66,9 +66,7 @@ public GroupingAggregatorFunction.AddInput prepareProcessRawInputPage(SeenGroupI LongBlock vBlock = page.getBlock(channels.get(0)); LongVector vVector = vBlock.asVector(); if (vVector == null) { - if (vBlock.mayHaveNulls()) { - state.enableGroupIdTracking(seenGroupIds); - } + maybeEnableGroupIdTracking(seenGroupIds, vBlock); return new GroupingAggregatorFunction.AddInput() { @Override public void add(int positionOffset, IntArrayBlock groupIds) { @@ -280,6 +278,12 @@ public void addIntermediateInput(int positionOffset, IntVector groups, Page page } } + private void maybeEnableGroupIdTracking(SeenGroupIds seenGroupIds, LongBlock vBlock) { + if (vBlock.mayHaveNulls()) { + state.enableGroupIdTracking(seenGroupIds); + } + } + @Override public void selectedMayContainUnseenGroups(SeenGroupIds seenGroupIds) { state.enableGroupIdTracking(seenGroupIds); diff --git a/x-pack/plugin/esql/compute/src/main/generated/org/elasticsearch/compute/aggregation/RateDoubleGroupingAggregatorFunction.java b/x-pack/plugin/esql/compute/src/main/generated/org/elasticsearch/compute/aggregation/RateDoubleGroupingAggregatorFunction.java index f630949449fff..58c540c6135fe 100644 --- a/x-pack/plugin/esql/compute/src/main/generated/org/elasticsearch/compute/aggregation/RateDoubleGroupingAggregatorFunction.java +++ b/x-pack/plugin/esql/compute/src/main/generated/org/elasticsearch/compute/aggregation/RateDoubleGroupingAggregatorFunction.java @@ -67,9 +67,7 @@ public GroupingAggregatorFunction.AddInput prepareProcessRawInputPage(SeenGroupI LongBlock timestampBlock = page.getBlock(channels.get(1)); DoubleVector valueVector = valueBlock.asVector(); if (valueVector == null) { - if (valueBlock.mayHaveNulls()) { - state.enableGroupIdTracking(seenGroupIds); - } + maybeEnableGroupIdTracking(seenGroupIds, valueBlock, timestampBlock); return new GroupingAggregatorFunction.AddInput() { @Override public void add(int positionOffset, IntArrayBlock groupIds) { @@ -93,9 +91,7 @@ public void close() { } LongVector timestampVector = timestampBlock.asVector(); if (timestampVector == null) { - if (timestampBlock.mayHaveNulls()) { - state.enableGroupIdTracking(seenGroupIds); - } + maybeEnableGroupIdTracking(seenGroupIds, valueBlock, timestampBlock); return new GroupingAggregatorFunction.AddInput() { @Override public void add(int positionOffset, IntArrayBlock groupIds) { @@ -385,6 +381,16 @@ public void addIntermediateInput(int positionOffset, IntVector groups, Page page } } + private void maybeEnableGroupIdTracking(SeenGroupIds seenGroupIds, DoubleBlock valueBlock, + LongBlock timestampBlock) { + if (valueBlock.mayHaveNulls()) { + state.enableGroupIdTracking(seenGroupIds); + } + if (timestampBlock.mayHaveNulls()) { + state.enableGroupIdTracking(seenGroupIds); + } + } + @Override public void selectedMayContainUnseenGroups(SeenGroupIds seenGroupIds) { state.enableGroupIdTracking(seenGroupIds); diff --git a/x-pack/plugin/esql/compute/src/main/generated/org/elasticsearch/compute/aggregation/RateFloatGroupingAggregatorFunction.java b/x-pack/plugin/esql/compute/src/main/generated/org/elasticsearch/compute/aggregation/RateFloatGroupingAggregatorFunction.java index e7a5fb44994c3..9f73e964b1d36 100644 --- a/x-pack/plugin/esql/compute/src/main/generated/org/elasticsearch/compute/aggregation/RateFloatGroupingAggregatorFunction.java +++ b/x-pack/plugin/esql/compute/src/main/generated/org/elasticsearch/compute/aggregation/RateFloatGroupingAggregatorFunction.java @@ -69,9 +69,7 @@ public GroupingAggregatorFunction.AddInput prepareProcessRawInputPage(SeenGroupI LongBlock timestampBlock = page.getBlock(channels.get(1)); FloatVector valueVector = valueBlock.asVector(); if (valueVector == null) { - if (valueBlock.mayHaveNulls()) { - state.enableGroupIdTracking(seenGroupIds); - } + maybeEnableGroupIdTracking(seenGroupIds, valueBlock, timestampBlock); return new GroupingAggregatorFunction.AddInput() { @Override public void add(int positionOffset, IntArrayBlock groupIds) { @@ -95,9 +93,7 @@ public void close() { } LongVector timestampVector = timestampBlock.asVector(); if (timestampVector == null) { - if (timestampBlock.mayHaveNulls()) { - state.enableGroupIdTracking(seenGroupIds); - } + maybeEnableGroupIdTracking(seenGroupIds, valueBlock, timestampBlock); return new GroupingAggregatorFunction.AddInput() { @Override public void add(int positionOffset, IntArrayBlock groupIds) { @@ -387,6 +383,16 @@ public void addIntermediateInput(int positionOffset, IntVector groups, Page page } } + private void maybeEnableGroupIdTracking(SeenGroupIds seenGroupIds, FloatBlock valueBlock, + LongBlock timestampBlock) { + if (valueBlock.mayHaveNulls()) { + state.enableGroupIdTracking(seenGroupIds); + } + if (timestampBlock.mayHaveNulls()) { + state.enableGroupIdTracking(seenGroupIds); + } + } + @Override public void selectedMayContainUnseenGroups(SeenGroupIds seenGroupIds) { state.enableGroupIdTracking(seenGroupIds); diff --git a/x-pack/plugin/esql/compute/src/main/generated/org/elasticsearch/compute/aggregation/RateIntGroupingAggregatorFunction.java b/x-pack/plugin/esql/compute/src/main/generated/org/elasticsearch/compute/aggregation/RateIntGroupingAggregatorFunction.java index 1fa1f450ad60f..1da0d4df35bae 100644 --- a/x-pack/plugin/esql/compute/src/main/generated/org/elasticsearch/compute/aggregation/RateIntGroupingAggregatorFunction.java +++ b/x-pack/plugin/esql/compute/src/main/generated/org/elasticsearch/compute/aggregation/RateIntGroupingAggregatorFunction.java @@ -67,9 +67,7 @@ public GroupingAggregatorFunction.AddInput prepareProcessRawInputPage(SeenGroupI LongBlock timestampBlock = page.getBlock(channels.get(1)); IntVector valueVector = valueBlock.asVector(); if (valueVector == null) { - if (valueBlock.mayHaveNulls()) { - state.enableGroupIdTracking(seenGroupIds); - } + maybeEnableGroupIdTracking(seenGroupIds, valueBlock, timestampBlock); return new GroupingAggregatorFunction.AddInput() { @Override public void add(int positionOffset, IntArrayBlock groupIds) { @@ -93,9 +91,7 @@ public void close() { } LongVector timestampVector = timestampBlock.asVector(); if (timestampVector == null) { - if (timestampBlock.mayHaveNulls()) { - state.enableGroupIdTracking(seenGroupIds); - } + maybeEnableGroupIdTracking(seenGroupIds, valueBlock, timestampBlock); return new GroupingAggregatorFunction.AddInput() { @Override public void add(int positionOffset, IntArrayBlock groupIds) { @@ -385,6 +381,16 @@ public void addIntermediateInput(int positionOffset, IntVector groups, Page page } } + private void maybeEnableGroupIdTracking(SeenGroupIds seenGroupIds, IntBlock valueBlock, + LongBlock timestampBlock) { + if (valueBlock.mayHaveNulls()) { + state.enableGroupIdTracking(seenGroupIds); + } + if (timestampBlock.mayHaveNulls()) { + state.enableGroupIdTracking(seenGroupIds); + } + } + @Override public void selectedMayContainUnseenGroups(SeenGroupIds seenGroupIds) { state.enableGroupIdTracking(seenGroupIds); diff --git a/x-pack/plugin/esql/compute/src/main/generated/org/elasticsearch/compute/aggregation/RateLongGroupingAggregatorFunction.java b/x-pack/plugin/esql/compute/src/main/generated/org/elasticsearch/compute/aggregation/RateLongGroupingAggregatorFunction.java index 498a1340d4bee..f1bfccb9dd848 100644 --- a/x-pack/plugin/esql/compute/src/main/generated/org/elasticsearch/compute/aggregation/RateLongGroupingAggregatorFunction.java +++ b/x-pack/plugin/esql/compute/src/main/generated/org/elasticsearch/compute/aggregation/RateLongGroupingAggregatorFunction.java @@ -67,9 +67,7 @@ public GroupingAggregatorFunction.AddInput prepareProcessRawInputPage(SeenGroupI LongBlock timestampBlock = page.getBlock(channels.get(1)); LongVector valueVector = valueBlock.asVector(); if (valueVector == null) { - if (valueBlock.mayHaveNulls()) { - state.enableGroupIdTracking(seenGroupIds); - } + maybeEnableGroupIdTracking(seenGroupIds, valueBlock, timestampBlock); return new GroupingAggregatorFunction.AddInput() { @Override public void add(int positionOffset, IntArrayBlock groupIds) { @@ -93,9 +91,7 @@ public void close() { } LongVector timestampVector = timestampBlock.asVector(); if (timestampVector == null) { - if (timestampBlock.mayHaveNulls()) { - state.enableGroupIdTracking(seenGroupIds); - } + maybeEnableGroupIdTracking(seenGroupIds, valueBlock, timestampBlock); return new GroupingAggregatorFunction.AddInput() { @Override public void add(int positionOffset, IntArrayBlock groupIds) { @@ -385,6 +381,16 @@ public void addIntermediateInput(int positionOffset, IntVector groups, Page page } } + private void maybeEnableGroupIdTracking(SeenGroupIds seenGroupIds, LongBlock valueBlock, + LongBlock timestampBlock) { + if (valueBlock.mayHaveNulls()) { + state.enableGroupIdTracking(seenGroupIds); + } + if (timestampBlock.mayHaveNulls()) { + state.enableGroupIdTracking(seenGroupIds); + } + } + @Override public void selectedMayContainUnseenGroups(SeenGroupIds seenGroupIds) { state.enableGroupIdTracking(seenGroupIds); 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 3225bab1e5f15..c675030a16bf2 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 @@ -65,9 +65,7 @@ public GroupingAggregatorFunction.AddInput prepareProcessRawInputPage(SeenGroupI BooleanBlock valueBlock = page.getBlock(channels.get(0)); BooleanVector valueVector = valueBlock.asVector(); if (valueVector == null) { - if (valueBlock.mayHaveNulls()) { - state.enableGroupIdTracking(seenGroupIds); - } + maybeEnableGroupIdTracking(seenGroupIds, valueBlock); return new GroupingAggregatorFunction.AddInput() { @Override public void add(int positionOffset, IntArrayBlock groupIds) { @@ -279,6 +277,12 @@ public void addIntermediateInput(int positionOffset, IntVector groups, Page page } } + private void maybeEnableGroupIdTracking(SeenGroupIds seenGroupIds, BooleanBlock valueBlock) { + if (valueBlock.mayHaveNulls()) { + state.enableGroupIdTracking(seenGroupIds); + } + } + @Override public void selectedMayContainUnseenGroups(SeenGroupIds seenGroupIds) { state.enableGroupIdTracking(seenGroupIds); 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 c9e0b99c732ab..db0d675499c44 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 @@ -64,9 +64,7 @@ public GroupingAggregatorFunction.AddInput prepareProcessRawInputPage(SeenGroupI BytesRefBlock valueBlock = page.getBlock(channels.get(0)); BytesRefVector valueVector = valueBlock.asVector(); if (valueVector == null) { - if (valueBlock.mayHaveNulls()) { - state.enableGroupIdTracking(seenGroupIds); - } + maybeEnableGroupIdTracking(seenGroupIds, valueBlock); return new GroupingAggregatorFunction.AddInput() { @Override public void add(int positionOffset, IntArrayBlock groupIds) { @@ -285,6 +283,12 @@ public void addIntermediateInput(int positionOffset, IntVector groups, Page page } } + private void maybeEnableGroupIdTracking(SeenGroupIds seenGroupIds, BytesRefBlock valueBlock) { + if (valueBlock.mayHaveNulls()) { + state.enableGroupIdTracking(seenGroupIds); + } + } + @Override public void selectedMayContainUnseenGroups(SeenGroupIds seenGroupIds) { state.enableGroupIdTracking(seenGroupIds); 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 68daf96c54a32..b81c56db60297 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 @@ -65,9 +65,7 @@ public GroupingAggregatorFunction.AddInput prepareProcessRawInputPage(SeenGroupI DoubleBlock valueBlock = page.getBlock(channels.get(0)); DoubleVector valueVector = valueBlock.asVector(); if (valueVector == null) { - if (valueBlock.mayHaveNulls()) { - state.enableGroupIdTracking(seenGroupIds); - } + maybeEnableGroupIdTracking(seenGroupIds, valueBlock); return new GroupingAggregatorFunction.AddInput() { @Override public void add(int positionOffset, IntArrayBlock groupIds) { @@ -279,6 +277,12 @@ public void addIntermediateInput(int positionOffset, IntVector groups, Page page } } + private void maybeEnableGroupIdTracking(SeenGroupIds seenGroupIds, DoubleBlock valueBlock) { + if (valueBlock.mayHaveNulls()) { + state.enableGroupIdTracking(seenGroupIds); + } + } + @Override public void selectedMayContainUnseenGroups(SeenGroupIds seenGroupIds) { state.enableGroupIdTracking(seenGroupIds); 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 01ff1f3cc7ade..41f2f7a608e8e 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 @@ -64,9 +64,7 @@ public GroupingAggregatorFunction.AddInput prepareProcessRawInputPage(SeenGroupI IntBlock valueBlock = page.getBlock(channels.get(0)); IntVector valueVector = valueBlock.asVector(); if (valueVector == null) { - if (valueBlock.mayHaveNulls()) { - state.enableGroupIdTracking(seenGroupIds); - } + maybeEnableGroupIdTracking(seenGroupIds, valueBlock); return new GroupingAggregatorFunction.AddInput() { @Override public void add(int positionOffset, IntArrayBlock groupIds) { @@ -278,6 +276,12 @@ public void addIntermediateInput(int positionOffset, IntVector groups, Page page } } + private void maybeEnableGroupIdTracking(SeenGroupIds seenGroupIds, IntBlock valueBlock) { + if (valueBlock.mayHaveNulls()) { + state.enableGroupIdTracking(seenGroupIds); + } + } + @Override public void selectedMayContainUnseenGroups(SeenGroupIds seenGroupIds) { state.enableGroupIdTracking(seenGroupIds); 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 327118fca0b18..675827ad0caa3 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 @@ -65,9 +65,7 @@ public GroupingAggregatorFunction.AddInput prepareProcessRawInputPage(SeenGroupI LongBlock valueBlock = page.getBlock(channels.get(0)); LongVector valueVector = valueBlock.asVector(); if (valueVector == null) { - if (valueBlock.mayHaveNulls()) { - state.enableGroupIdTracking(seenGroupIds); - } + maybeEnableGroupIdTracking(seenGroupIds, valueBlock); return new GroupingAggregatorFunction.AddInput() { @Override public void add(int positionOffset, IntArrayBlock groupIds) { @@ -279,6 +277,12 @@ public void addIntermediateInput(int positionOffset, IntVector groups, Page page } } + private void maybeEnableGroupIdTracking(SeenGroupIds seenGroupIds, LongBlock valueBlock) { + if (valueBlock.mayHaveNulls()) { + state.enableGroupIdTracking(seenGroupIds); + } + } + @Override public void selectedMayContainUnseenGroups(SeenGroupIds seenGroupIds) { state.enableGroupIdTracking(seenGroupIds); diff --git a/x-pack/plugin/esql/compute/src/main/generated/org/elasticsearch/compute/aggregation/StdDevDoubleGroupingAggregatorFunction.java b/x-pack/plugin/esql/compute/src/main/generated/org/elasticsearch/compute/aggregation/StdDevDoubleGroupingAggregatorFunction.java index fe2e49da0a805..b4337f1030adb 100644 --- a/x-pack/plugin/esql/compute/src/main/generated/org/elasticsearch/compute/aggregation/StdDevDoubleGroupingAggregatorFunction.java +++ b/x-pack/plugin/esql/compute/src/main/generated/org/elasticsearch/compute/aggregation/StdDevDoubleGroupingAggregatorFunction.java @@ -64,9 +64,7 @@ public GroupingAggregatorFunction.AddInput prepareProcessRawInputPage(SeenGroupI DoubleBlock valueBlock = page.getBlock(channels.get(0)); DoubleVector valueVector = valueBlock.asVector(); if (valueVector == null) { - if (valueBlock.mayHaveNulls()) { - state.enableGroupIdTracking(seenGroupIds); - } + maybeEnableGroupIdTracking(seenGroupIds, valueBlock); return new GroupingAggregatorFunction.AddInput() { @Override public void add(int positionOffset, IntArrayBlock groupIds) { @@ -308,6 +306,12 @@ public void addIntermediateInput(int positionOffset, IntVector groups, Page page } } + private void maybeEnableGroupIdTracking(SeenGroupIds seenGroupIds, DoubleBlock valueBlock) { + if (valueBlock.mayHaveNulls()) { + state.enableGroupIdTracking(seenGroupIds); + } + } + @Override public void selectedMayContainUnseenGroups(SeenGroupIds seenGroupIds) { state.enableGroupIdTracking(seenGroupIds); diff --git a/x-pack/plugin/esql/compute/src/main/generated/org/elasticsearch/compute/aggregation/StdDevFloatGroupingAggregatorFunction.java b/x-pack/plugin/esql/compute/src/main/generated/org/elasticsearch/compute/aggregation/StdDevFloatGroupingAggregatorFunction.java index b72d98a947227..7e513e1f9dc35 100644 --- a/x-pack/plugin/esql/compute/src/main/generated/org/elasticsearch/compute/aggregation/StdDevFloatGroupingAggregatorFunction.java +++ b/x-pack/plugin/esql/compute/src/main/generated/org/elasticsearch/compute/aggregation/StdDevFloatGroupingAggregatorFunction.java @@ -66,9 +66,7 @@ public GroupingAggregatorFunction.AddInput prepareProcessRawInputPage(SeenGroupI FloatBlock valueBlock = page.getBlock(channels.get(0)); FloatVector valueVector = valueBlock.asVector(); if (valueVector == null) { - if (valueBlock.mayHaveNulls()) { - state.enableGroupIdTracking(seenGroupIds); - } + maybeEnableGroupIdTracking(seenGroupIds, valueBlock); return new GroupingAggregatorFunction.AddInput() { @Override public void add(int positionOffset, IntArrayBlock groupIds) { @@ -310,6 +308,12 @@ public void addIntermediateInput(int positionOffset, IntVector groups, Page page } } + private void maybeEnableGroupIdTracking(SeenGroupIds seenGroupIds, FloatBlock valueBlock) { + if (valueBlock.mayHaveNulls()) { + state.enableGroupIdTracking(seenGroupIds); + } + } + @Override public void selectedMayContainUnseenGroups(SeenGroupIds seenGroupIds) { state.enableGroupIdTracking(seenGroupIds); diff --git a/x-pack/plugin/esql/compute/src/main/generated/org/elasticsearch/compute/aggregation/StdDevIntGroupingAggregatorFunction.java b/x-pack/plugin/esql/compute/src/main/generated/org/elasticsearch/compute/aggregation/StdDevIntGroupingAggregatorFunction.java index f3a6acbcbb014..1145ccfd4bce3 100644 --- a/x-pack/plugin/esql/compute/src/main/generated/org/elasticsearch/compute/aggregation/StdDevIntGroupingAggregatorFunction.java +++ b/x-pack/plugin/esql/compute/src/main/generated/org/elasticsearch/compute/aggregation/StdDevIntGroupingAggregatorFunction.java @@ -65,9 +65,7 @@ public GroupingAggregatorFunction.AddInput prepareProcessRawInputPage(SeenGroupI IntBlock valueBlock = page.getBlock(channels.get(0)); IntVector valueVector = valueBlock.asVector(); if (valueVector == null) { - if (valueBlock.mayHaveNulls()) { - state.enableGroupIdTracking(seenGroupIds); - } + maybeEnableGroupIdTracking(seenGroupIds, valueBlock); return new GroupingAggregatorFunction.AddInput() { @Override public void add(int positionOffset, IntArrayBlock groupIds) { @@ -309,6 +307,12 @@ public void addIntermediateInput(int positionOffset, IntVector groups, Page page } } + private void maybeEnableGroupIdTracking(SeenGroupIds seenGroupIds, IntBlock valueBlock) { + if (valueBlock.mayHaveNulls()) { + state.enableGroupIdTracking(seenGroupIds); + } + } + @Override public void selectedMayContainUnseenGroups(SeenGroupIds seenGroupIds) { state.enableGroupIdTracking(seenGroupIds); diff --git a/x-pack/plugin/esql/compute/src/main/generated/org/elasticsearch/compute/aggregation/StdDevLongGroupingAggregatorFunction.java b/x-pack/plugin/esql/compute/src/main/generated/org/elasticsearch/compute/aggregation/StdDevLongGroupingAggregatorFunction.java index 79dc47b387484..5e2dde7ea1fde 100644 --- a/x-pack/plugin/esql/compute/src/main/generated/org/elasticsearch/compute/aggregation/StdDevLongGroupingAggregatorFunction.java +++ b/x-pack/plugin/esql/compute/src/main/generated/org/elasticsearch/compute/aggregation/StdDevLongGroupingAggregatorFunction.java @@ -64,9 +64,7 @@ public GroupingAggregatorFunction.AddInput prepareProcessRawInputPage(SeenGroupI LongBlock valueBlock = page.getBlock(channels.get(0)); LongVector valueVector = valueBlock.asVector(); if (valueVector == null) { - if (valueBlock.mayHaveNulls()) { - state.enableGroupIdTracking(seenGroupIds); - } + maybeEnableGroupIdTracking(seenGroupIds, valueBlock); return new GroupingAggregatorFunction.AddInput() { @Override public void add(int positionOffset, IntArrayBlock groupIds) { @@ -308,6 +306,12 @@ public void addIntermediateInput(int positionOffset, IntVector groups, Page page } } + private void maybeEnableGroupIdTracking(SeenGroupIds seenGroupIds, LongBlock valueBlock) { + if (valueBlock.mayHaveNulls()) { + state.enableGroupIdTracking(seenGroupIds); + } + } + @Override public void selectedMayContainUnseenGroups(SeenGroupIds seenGroupIds) { state.enableGroupIdTracking(seenGroupIds); diff --git a/x-pack/plugin/esql/compute/src/main/generated/org/elasticsearch/compute/aggregation/SumDoubleGroupingAggregatorFunction.java b/x-pack/plugin/esql/compute/src/main/generated/org/elasticsearch/compute/aggregation/SumDoubleGroupingAggregatorFunction.java index d252140fe8fbd..70dbdcc6b28bc 100644 --- a/x-pack/plugin/esql/compute/src/main/generated/org/elasticsearch/compute/aggregation/SumDoubleGroupingAggregatorFunction.java +++ b/x-pack/plugin/esql/compute/src/main/generated/org/elasticsearch/compute/aggregation/SumDoubleGroupingAggregatorFunction.java @@ -64,9 +64,7 @@ public GroupingAggregatorFunction.AddInput prepareProcessRawInputPage(SeenGroupI DoubleBlock vBlock = page.getBlock(channels.get(0)); DoubleVector vVector = vBlock.asVector(); if (vVector == null) { - if (vBlock.mayHaveNulls()) { - state.enableGroupIdTracking(seenGroupIds); - } + maybeEnableGroupIdTracking(seenGroupIds, vBlock); return new GroupingAggregatorFunction.AddInput() { @Override public void add(int positionOffset, IntArrayBlock groupIds) { @@ -308,6 +306,12 @@ public void addIntermediateInput(int positionOffset, IntVector groups, Page page } } + private void maybeEnableGroupIdTracking(SeenGroupIds seenGroupIds, DoubleBlock vBlock) { + if (vBlock.mayHaveNulls()) { + state.enableGroupIdTracking(seenGroupIds); + } + } + @Override public void selectedMayContainUnseenGroups(SeenGroupIds seenGroupIds) { state.enableGroupIdTracking(seenGroupIds); diff --git a/x-pack/plugin/esql/compute/src/main/generated/org/elasticsearch/compute/aggregation/SumFloatGroupingAggregatorFunction.java b/x-pack/plugin/esql/compute/src/main/generated/org/elasticsearch/compute/aggregation/SumFloatGroupingAggregatorFunction.java index 3403533f5c6ae..f7417e546ab8e 100644 --- a/x-pack/plugin/esql/compute/src/main/generated/org/elasticsearch/compute/aggregation/SumFloatGroupingAggregatorFunction.java +++ b/x-pack/plugin/esql/compute/src/main/generated/org/elasticsearch/compute/aggregation/SumFloatGroupingAggregatorFunction.java @@ -66,9 +66,7 @@ public GroupingAggregatorFunction.AddInput prepareProcessRawInputPage(SeenGroupI FloatBlock vBlock = page.getBlock(channels.get(0)); FloatVector vVector = vBlock.asVector(); if (vVector == null) { - if (vBlock.mayHaveNulls()) { - state.enableGroupIdTracking(seenGroupIds); - } + maybeEnableGroupIdTracking(seenGroupIds, vBlock); return new GroupingAggregatorFunction.AddInput() { @Override public void add(int positionOffset, IntArrayBlock groupIds) { @@ -310,6 +308,12 @@ public void addIntermediateInput(int positionOffset, IntVector groups, Page page } } + private void maybeEnableGroupIdTracking(SeenGroupIds seenGroupIds, FloatBlock vBlock) { + if (vBlock.mayHaveNulls()) { + state.enableGroupIdTracking(seenGroupIds); + } + } + @Override public void selectedMayContainUnseenGroups(SeenGroupIds seenGroupIds) { state.enableGroupIdTracking(seenGroupIds); diff --git a/x-pack/plugin/esql/compute/src/main/generated/org/elasticsearch/compute/aggregation/SumIntGroupingAggregatorFunction.java b/x-pack/plugin/esql/compute/src/main/generated/org/elasticsearch/compute/aggregation/SumIntGroupingAggregatorFunction.java index 2b74ba2220233..fe19f3be0c557 100644 --- a/x-pack/plugin/esql/compute/src/main/generated/org/elasticsearch/compute/aggregation/SumIntGroupingAggregatorFunction.java +++ b/x-pack/plugin/esql/compute/src/main/generated/org/elasticsearch/compute/aggregation/SumIntGroupingAggregatorFunction.java @@ -64,9 +64,7 @@ public GroupingAggregatorFunction.AddInput prepareProcessRawInputPage(SeenGroupI IntBlock vBlock = page.getBlock(channels.get(0)); IntVector vVector = vBlock.asVector(); if (vVector == null) { - if (vBlock.mayHaveNulls()) { - state.enableGroupIdTracking(seenGroupIds); - } + maybeEnableGroupIdTracking(seenGroupIds, vBlock); return new GroupingAggregatorFunction.AddInput() { @Override public void add(int positionOffset, IntArrayBlock groupIds) { @@ -299,6 +297,12 @@ public void addIntermediateInput(int positionOffset, IntVector groups, Page page } } + private void maybeEnableGroupIdTracking(SeenGroupIds seenGroupIds, IntBlock vBlock) { + if (vBlock.mayHaveNulls()) { + state.enableGroupIdTracking(seenGroupIds); + } + } + @Override public void selectedMayContainUnseenGroups(SeenGroupIds seenGroupIds) { state.enableGroupIdTracking(seenGroupIds); diff --git a/x-pack/plugin/esql/compute/src/main/generated/org/elasticsearch/compute/aggregation/SumLongGroupingAggregatorFunction.java b/x-pack/plugin/esql/compute/src/main/generated/org/elasticsearch/compute/aggregation/SumLongGroupingAggregatorFunction.java index 33570326aa300..ab2f02c4f44d4 100644 --- a/x-pack/plugin/esql/compute/src/main/generated/org/elasticsearch/compute/aggregation/SumLongGroupingAggregatorFunction.java +++ b/x-pack/plugin/esql/compute/src/main/generated/org/elasticsearch/compute/aggregation/SumLongGroupingAggregatorFunction.java @@ -63,9 +63,7 @@ public GroupingAggregatorFunction.AddInput prepareProcessRawInputPage(SeenGroupI LongBlock vBlock = page.getBlock(channels.get(0)); LongVector vVector = vBlock.asVector(); if (vVector == null) { - if (vBlock.mayHaveNulls()) { - state.enableGroupIdTracking(seenGroupIds); - } + maybeEnableGroupIdTracking(seenGroupIds, vBlock); return new GroupingAggregatorFunction.AddInput() { @Override public void add(int positionOffset, IntArrayBlock groupIds) { @@ -298,6 +296,12 @@ public void addIntermediateInput(int positionOffset, IntVector groups, Page page } } + private void maybeEnableGroupIdTracking(SeenGroupIds seenGroupIds, LongBlock vBlock) { + if (vBlock.mayHaveNulls()) { + state.enableGroupIdTracking(seenGroupIds); + } + } + @Override public void selectedMayContainUnseenGroups(SeenGroupIds seenGroupIds) { state.enableGroupIdTracking(seenGroupIds); diff --git a/x-pack/plugin/esql/compute/src/main/generated/org/elasticsearch/compute/aggregation/TopBooleanGroupingAggregatorFunction.java b/x-pack/plugin/esql/compute/src/main/generated/org/elasticsearch/compute/aggregation/TopBooleanGroupingAggregatorFunction.java index 94aa1d20f2df5..d5a480ceafb96 100644 --- a/x-pack/plugin/esql/compute/src/main/generated/org/elasticsearch/compute/aggregation/TopBooleanGroupingAggregatorFunction.java +++ b/x-pack/plugin/esql/compute/src/main/generated/org/elasticsearch/compute/aggregation/TopBooleanGroupingAggregatorFunction.java @@ -67,9 +67,7 @@ public GroupingAggregatorFunction.AddInput prepareProcessRawInputPage(SeenGroupI BooleanBlock vBlock = page.getBlock(channels.get(0)); BooleanVector vVector = vBlock.asVector(); if (vVector == null) { - if (vBlock.mayHaveNulls()) { - state.enableGroupIdTracking(seenGroupIds); - } + maybeEnableGroupIdTracking(seenGroupIds, vBlock); return new GroupingAggregatorFunction.AddInput() { @Override public void add(int positionOffset, IntArrayBlock groupIds) { @@ -278,6 +276,12 @@ public void addIntermediateInput(int positionOffset, IntVector groups, Page page } } + private void maybeEnableGroupIdTracking(SeenGroupIds seenGroupIds, BooleanBlock vBlock) { + if (vBlock.mayHaveNulls()) { + state.enableGroupIdTracking(seenGroupIds); + } + } + @Override public void selectedMayContainUnseenGroups(SeenGroupIds seenGroupIds) { state.enableGroupIdTracking(seenGroupIds); 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 a4b83a742c97a..dc6db83fc0f0d 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 @@ -68,9 +68,7 @@ public GroupingAggregatorFunction.AddInput prepareProcessRawInputPage(SeenGroupI BytesRefBlock vBlock = page.getBlock(channels.get(0)); BytesRefVector vVector = vBlock.asVector(); if (vVector == null) { - if (vBlock.mayHaveNulls()) { - state.enableGroupIdTracking(seenGroupIds); - } + maybeEnableGroupIdTracking(seenGroupIds, vBlock); return new GroupingAggregatorFunction.AddInput() { @Override public void add(int positionOffset, IntArrayBlock groupIds) { @@ -288,6 +286,12 @@ public void addIntermediateInput(int positionOffset, IntVector groups, Page page } } + private void maybeEnableGroupIdTracking(SeenGroupIds seenGroupIds, BytesRefBlock vBlock) { + if (vBlock.mayHaveNulls()) { + state.enableGroupIdTracking(seenGroupIds); + } + } + @Override public void selectedMayContainUnseenGroups(SeenGroupIds seenGroupIds) { state.enableGroupIdTracking(seenGroupIds); diff --git a/x-pack/plugin/esql/compute/src/main/generated/org/elasticsearch/compute/aggregation/TopDoubleGroupingAggregatorFunction.java b/x-pack/plugin/esql/compute/src/main/generated/org/elasticsearch/compute/aggregation/TopDoubleGroupingAggregatorFunction.java index f9892c35fe878..5fead1076f185 100644 --- a/x-pack/plugin/esql/compute/src/main/generated/org/elasticsearch/compute/aggregation/TopDoubleGroupingAggregatorFunction.java +++ b/x-pack/plugin/esql/compute/src/main/generated/org/elasticsearch/compute/aggregation/TopDoubleGroupingAggregatorFunction.java @@ -67,9 +67,7 @@ public GroupingAggregatorFunction.AddInput prepareProcessRawInputPage(SeenGroupI DoubleBlock vBlock = page.getBlock(channels.get(0)); DoubleVector vVector = vBlock.asVector(); if (vVector == null) { - if (vBlock.mayHaveNulls()) { - state.enableGroupIdTracking(seenGroupIds); - } + maybeEnableGroupIdTracking(seenGroupIds, vBlock); return new GroupingAggregatorFunction.AddInput() { @Override public void add(int positionOffset, IntArrayBlock groupIds) { @@ -278,6 +276,12 @@ public void addIntermediateInput(int positionOffset, IntVector groups, Page page } } + private void maybeEnableGroupIdTracking(SeenGroupIds seenGroupIds, DoubleBlock vBlock) { + if (vBlock.mayHaveNulls()) { + state.enableGroupIdTracking(seenGroupIds); + } + } + @Override public void selectedMayContainUnseenGroups(SeenGroupIds seenGroupIds) { state.enableGroupIdTracking(seenGroupIds); diff --git a/x-pack/plugin/esql/compute/src/main/generated/org/elasticsearch/compute/aggregation/TopFloatGroupingAggregatorFunction.java b/x-pack/plugin/esql/compute/src/main/generated/org/elasticsearch/compute/aggregation/TopFloatGroupingAggregatorFunction.java index 313377cb313ff..f4f39420cde0a 100644 --- a/x-pack/plugin/esql/compute/src/main/generated/org/elasticsearch/compute/aggregation/TopFloatGroupingAggregatorFunction.java +++ b/x-pack/plugin/esql/compute/src/main/generated/org/elasticsearch/compute/aggregation/TopFloatGroupingAggregatorFunction.java @@ -67,9 +67,7 @@ public GroupingAggregatorFunction.AddInput prepareProcessRawInputPage(SeenGroupI FloatBlock vBlock = page.getBlock(channels.get(0)); FloatVector vVector = vBlock.asVector(); if (vVector == null) { - if (vBlock.mayHaveNulls()) { - state.enableGroupIdTracking(seenGroupIds); - } + maybeEnableGroupIdTracking(seenGroupIds, vBlock); return new GroupingAggregatorFunction.AddInput() { @Override public void add(int positionOffset, IntArrayBlock groupIds) { @@ -278,6 +276,12 @@ public void addIntermediateInput(int positionOffset, IntVector groups, Page page } } + private void maybeEnableGroupIdTracking(SeenGroupIds seenGroupIds, FloatBlock vBlock) { + if (vBlock.mayHaveNulls()) { + state.enableGroupIdTracking(seenGroupIds); + } + } + @Override public void selectedMayContainUnseenGroups(SeenGroupIds seenGroupIds) { state.enableGroupIdTracking(seenGroupIds); diff --git a/x-pack/plugin/esql/compute/src/main/generated/org/elasticsearch/compute/aggregation/TopIntGroupingAggregatorFunction.java b/x-pack/plugin/esql/compute/src/main/generated/org/elasticsearch/compute/aggregation/TopIntGroupingAggregatorFunction.java index 363ff8da73368..b03d077cf8f73 100644 --- a/x-pack/plugin/esql/compute/src/main/generated/org/elasticsearch/compute/aggregation/TopIntGroupingAggregatorFunction.java +++ b/x-pack/plugin/esql/compute/src/main/generated/org/elasticsearch/compute/aggregation/TopIntGroupingAggregatorFunction.java @@ -66,9 +66,7 @@ public GroupingAggregatorFunction.AddInput prepareProcessRawInputPage(SeenGroupI IntBlock vBlock = page.getBlock(channels.get(0)); IntVector vVector = vBlock.asVector(); if (vVector == null) { - if (vBlock.mayHaveNulls()) { - state.enableGroupIdTracking(seenGroupIds); - } + maybeEnableGroupIdTracking(seenGroupIds, vBlock); return new GroupingAggregatorFunction.AddInput() { @Override public void add(int positionOffset, IntArrayBlock groupIds) { @@ -277,6 +275,12 @@ public void addIntermediateInput(int positionOffset, IntVector groups, Page page } } + private void maybeEnableGroupIdTracking(SeenGroupIds seenGroupIds, IntBlock vBlock) { + if (vBlock.mayHaveNulls()) { + state.enableGroupIdTracking(seenGroupIds); + } + } + @Override public void selectedMayContainUnseenGroups(SeenGroupIds seenGroupIds) { state.enableGroupIdTracking(seenGroupIds); 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 2527c25b4daec..18a6925ebbb34 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 @@ -68,9 +68,7 @@ public GroupingAggregatorFunction.AddInput prepareProcessRawInputPage(SeenGroupI BytesRefBlock vBlock = page.getBlock(channels.get(0)); BytesRefVector vVector = vBlock.asVector(); if (vVector == null) { - if (vBlock.mayHaveNulls()) { - state.enableGroupIdTracking(seenGroupIds); - } + maybeEnableGroupIdTracking(seenGroupIds, vBlock); return new GroupingAggregatorFunction.AddInput() { @Override public void add(int positionOffset, IntArrayBlock groupIds) { @@ -288,6 +286,12 @@ public void addIntermediateInput(int positionOffset, IntVector groups, Page page } } + private void maybeEnableGroupIdTracking(SeenGroupIds seenGroupIds, BytesRefBlock vBlock) { + if (vBlock.mayHaveNulls()) { + state.enableGroupIdTracking(seenGroupIds); + } + } + @Override public void selectedMayContainUnseenGroups(SeenGroupIds seenGroupIds) { state.enableGroupIdTracking(seenGroupIds); diff --git a/x-pack/plugin/esql/compute/src/main/generated/org/elasticsearch/compute/aggregation/TopLongGroupingAggregatorFunction.java b/x-pack/plugin/esql/compute/src/main/generated/org/elasticsearch/compute/aggregation/TopLongGroupingAggregatorFunction.java index 0d637b46fd833..1907521e73ad5 100644 --- a/x-pack/plugin/esql/compute/src/main/generated/org/elasticsearch/compute/aggregation/TopLongGroupingAggregatorFunction.java +++ b/x-pack/plugin/esql/compute/src/main/generated/org/elasticsearch/compute/aggregation/TopLongGroupingAggregatorFunction.java @@ -67,9 +67,7 @@ public GroupingAggregatorFunction.AddInput prepareProcessRawInputPage(SeenGroupI LongBlock vBlock = page.getBlock(channels.get(0)); LongVector vVector = vBlock.asVector(); if (vVector == null) { - if (vBlock.mayHaveNulls()) { - state.enableGroupIdTracking(seenGroupIds); - } + maybeEnableGroupIdTracking(seenGroupIds, vBlock); return new GroupingAggregatorFunction.AddInput() { @Override public void add(int positionOffset, IntArrayBlock groupIds) { @@ -278,6 +276,12 @@ public void addIntermediateInput(int positionOffset, IntVector groups, Page page } } + private void maybeEnableGroupIdTracking(SeenGroupIds seenGroupIds, LongBlock vBlock) { + if (vBlock.mayHaveNulls()) { + state.enableGroupIdTracking(seenGroupIds); + } + } + @Override public void selectedMayContainUnseenGroups(SeenGroupIds seenGroupIds) { state.enableGroupIdTracking(seenGroupIds); diff --git a/x-pack/plugin/esql/compute/src/main/generated/org/elasticsearch/compute/aggregation/ValuesBooleanGroupingAggregatorFunction.java b/x-pack/plugin/esql/compute/src/main/generated/org/elasticsearch/compute/aggregation/ValuesBooleanGroupingAggregatorFunction.java index 1852a678576e5..5dab69a92bb0a 100644 --- a/x-pack/plugin/esql/compute/src/main/generated/org/elasticsearch/compute/aggregation/ValuesBooleanGroupingAggregatorFunction.java +++ b/x-pack/plugin/esql/compute/src/main/generated/org/elasticsearch/compute/aggregation/ValuesBooleanGroupingAggregatorFunction.java @@ -60,9 +60,7 @@ public GroupingAggregatorFunction.AddInput prepareProcessRawInputPage(SeenGroupI BooleanBlock vBlock = page.getBlock(channels.get(0)); BooleanVector vVector = vBlock.asVector(); if (vVector == null) { - if (vBlock.mayHaveNulls()) { - state.enableGroupIdTracking(seenGroupIds); - } + maybeEnableGroupIdTracking(seenGroupIds, vBlock); return new GroupingAggregatorFunction.AddInput() { @Override public void add(int positionOffset, IntArrayBlock groupIds) { @@ -271,6 +269,12 @@ public void addIntermediateInput(int positionOffset, IntVector groups, Page page } } + private void maybeEnableGroupIdTracking(SeenGroupIds seenGroupIds, BooleanBlock vBlock) { + if (vBlock.mayHaveNulls()) { + state.enableGroupIdTracking(seenGroupIds); + } + } + @Override public void selectedMayContainUnseenGroups(SeenGroupIds seenGroupIds) { state.enableGroupIdTracking(seenGroupIds); diff --git a/x-pack/plugin/esql/compute/src/main/generated/org/elasticsearch/compute/aggregation/ValuesBytesRefGroupingAggregatorFunction.java b/x-pack/plugin/esql/compute/src/main/generated/org/elasticsearch/compute/aggregation/ValuesBytesRefGroupingAggregatorFunction.java index 60d8e5d53ddcd..a467d7de08151 100644 --- a/x-pack/plugin/esql/compute/src/main/generated/org/elasticsearch/compute/aggregation/ValuesBytesRefGroupingAggregatorFunction.java +++ b/x-pack/plugin/esql/compute/src/main/generated/org/elasticsearch/compute/aggregation/ValuesBytesRefGroupingAggregatorFunction.java @@ -61,9 +61,7 @@ public GroupingAggregatorFunction.AddInput prepareProcessRawInputPage(SeenGroupI BytesRefBlock vBlock = page.getBlock(channels.get(0)); BytesRefVector vVector = vBlock.asVector(); if (vVector == null) { - if (vBlock.mayHaveNulls()) { - state.enableGroupIdTracking(seenGroupIds); - } + maybeEnableGroupIdTracking(seenGroupIds, vBlock); var addInput = new GroupingAggregatorFunction.AddInput() { @Override public void add(int positionOffset, IntArrayBlock groupIds) { @@ -254,6 +252,12 @@ public void addIntermediateInput(int positionOffset, IntVector groups, Page page ValuesBytesRefAggregator.combineIntermediate(state, positionOffset, groups, values); } + private void maybeEnableGroupIdTracking(SeenGroupIds seenGroupIds, BytesRefBlock vBlock) { + if (vBlock.mayHaveNulls()) { + state.enableGroupIdTracking(seenGroupIds); + } + } + @Override public void selectedMayContainUnseenGroups(SeenGroupIds seenGroupIds) { state.enableGroupIdTracking(seenGroupIds); diff --git a/x-pack/plugin/esql/compute/src/main/generated/org/elasticsearch/compute/aggregation/ValuesDoubleGroupingAggregatorFunction.java b/x-pack/plugin/esql/compute/src/main/generated/org/elasticsearch/compute/aggregation/ValuesDoubleGroupingAggregatorFunction.java index 27e6fc53f2ba5..6f1450624a010 100644 --- a/x-pack/plugin/esql/compute/src/main/generated/org/elasticsearch/compute/aggregation/ValuesDoubleGroupingAggregatorFunction.java +++ b/x-pack/plugin/esql/compute/src/main/generated/org/elasticsearch/compute/aggregation/ValuesDoubleGroupingAggregatorFunction.java @@ -60,9 +60,7 @@ public GroupingAggregatorFunction.AddInput prepareProcessRawInputPage(SeenGroupI DoubleBlock vBlock = page.getBlock(channels.get(0)); DoubleVector vVector = vBlock.asVector(); if (vVector == null) { - if (vBlock.mayHaveNulls()) { - state.enableGroupIdTracking(seenGroupIds); - } + maybeEnableGroupIdTracking(seenGroupIds, vBlock); return new GroupingAggregatorFunction.AddInput() { @Override public void add(int positionOffset, IntArrayBlock groupIds) { @@ -271,6 +269,12 @@ public void addIntermediateInput(int positionOffset, IntVector groups, Page page } } + private void maybeEnableGroupIdTracking(SeenGroupIds seenGroupIds, DoubleBlock vBlock) { + if (vBlock.mayHaveNulls()) { + state.enableGroupIdTracking(seenGroupIds); + } + } + @Override public void selectedMayContainUnseenGroups(SeenGroupIds seenGroupIds) { state.enableGroupIdTracking(seenGroupIds); diff --git a/x-pack/plugin/esql/compute/src/main/generated/org/elasticsearch/compute/aggregation/ValuesFloatGroupingAggregatorFunction.java b/x-pack/plugin/esql/compute/src/main/generated/org/elasticsearch/compute/aggregation/ValuesFloatGroupingAggregatorFunction.java index f9b8418735b07..df973c71bf89e 100644 --- a/x-pack/plugin/esql/compute/src/main/generated/org/elasticsearch/compute/aggregation/ValuesFloatGroupingAggregatorFunction.java +++ b/x-pack/plugin/esql/compute/src/main/generated/org/elasticsearch/compute/aggregation/ValuesFloatGroupingAggregatorFunction.java @@ -60,9 +60,7 @@ public GroupingAggregatorFunction.AddInput prepareProcessRawInputPage(SeenGroupI FloatBlock vBlock = page.getBlock(channels.get(0)); FloatVector vVector = vBlock.asVector(); if (vVector == null) { - if (vBlock.mayHaveNulls()) { - state.enableGroupIdTracking(seenGroupIds); - } + maybeEnableGroupIdTracking(seenGroupIds, vBlock); return new GroupingAggregatorFunction.AddInput() { @Override public void add(int positionOffset, IntArrayBlock groupIds) { @@ -271,6 +269,12 @@ public void addIntermediateInput(int positionOffset, IntVector groups, Page page } } + private void maybeEnableGroupIdTracking(SeenGroupIds seenGroupIds, FloatBlock vBlock) { + if (vBlock.mayHaveNulls()) { + state.enableGroupIdTracking(seenGroupIds); + } + } + @Override public void selectedMayContainUnseenGroups(SeenGroupIds seenGroupIds) { state.enableGroupIdTracking(seenGroupIds); diff --git a/x-pack/plugin/esql/compute/src/main/generated/org/elasticsearch/compute/aggregation/ValuesIntGroupingAggregatorFunction.java b/x-pack/plugin/esql/compute/src/main/generated/org/elasticsearch/compute/aggregation/ValuesIntGroupingAggregatorFunction.java index beb87dd6e4ff5..328f0fa5fd559 100644 --- a/x-pack/plugin/esql/compute/src/main/generated/org/elasticsearch/compute/aggregation/ValuesIntGroupingAggregatorFunction.java +++ b/x-pack/plugin/esql/compute/src/main/generated/org/elasticsearch/compute/aggregation/ValuesIntGroupingAggregatorFunction.java @@ -59,9 +59,7 @@ public GroupingAggregatorFunction.AddInput prepareProcessRawInputPage(SeenGroupI IntBlock vBlock = page.getBlock(channels.get(0)); IntVector vVector = vBlock.asVector(); if (vVector == null) { - if (vBlock.mayHaveNulls()) { - state.enableGroupIdTracking(seenGroupIds); - } + maybeEnableGroupIdTracking(seenGroupIds, vBlock); return new GroupingAggregatorFunction.AddInput() { @Override public void add(int positionOffset, IntArrayBlock groupIds) { @@ -270,6 +268,12 @@ public void addIntermediateInput(int positionOffset, IntVector groups, Page page } } + private void maybeEnableGroupIdTracking(SeenGroupIds seenGroupIds, IntBlock vBlock) { + if (vBlock.mayHaveNulls()) { + state.enableGroupIdTracking(seenGroupIds); + } + } + @Override public void selectedMayContainUnseenGroups(SeenGroupIds seenGroupIds) { state.enableGroupIdTracking(seenGroupIds); diff --git a/x-pack/plugin/esql/compute/src/main/generated/org/elasticsearch/compute/aggregation/ValuesLongGroupingAggregatorFunction.java b/x-pack/plugin/esql/compute/src/main/generated/org/elasticsearch/compute/aggregation/ValuesLongGroupingAggregatorFunction.java index 1e6b1d56110b3..4ac719478ceae 100644 --- a/x-pack/plugin/esql/compute/src/main/generated/org/elasticsearch/compute/aggregation/ValuesLongGroupingAggregatorFunction.java +++ b/x-pack/plugin/esql/compute/src/main/generated/org/elasticsearch/compute/aggregation/ValuesLongGroupingAggregatorFunction.java @@ -60,9 +60,7 @@ public GroupingAggregatorFunction.AddInput prepareProcessRawInputPage(SeenGroupI LongBlock vBlock = page.getBlock(channels.get(0)); LongVector vVector = vBlock.asVector(); if (vVector == null) { - if (vBlock.mayHaveNulls()) { - state.enableGroupIdTracking(seenGroupIds); - } + maybeEnableGroupIdTracking(seenGroupIds, vBlock); return new GroupingAggregatorFunction.AddInput() { @Override public void add(int positionOffset, IntArrayBlock groupIds) { @@ -271,6 +269,12 @@ public void addIntermediateInput(int positionOffset, IntVector groups, Page page } } + private void maybeEnableGroupIdTracking(SeenGroupIds seenGroupIds, LongBlock vBlock) { + if (vBlock.mayHaveNulls()) { + state.enableGroupIdTracking(seenGroupIds); + } + } + @Override public void selectedMayContainUnseenGroups(SeenGroupIds seenGroupIds) { state.enableGroupIdTracking(seenGroupIds); diff --git a/x-pack/plugin/esql/compute/src/main/generated/org/elasticsearch/compute/aggregation/spatial/SpatialCentroidCartesianPointDocValuesGroupingAggregatorFunction.java b/x-pack/plugin/esql/compute/src/main/generated/org/elasticsearch/compute/aggregation/spatial/SpatialCentroidCartesianPointDocValuesGroupingAggregatorFunction.java index 3e7bebbf58d81..135631ede261d 100644 --- a/x-pack/plugin/esql/compute/src/main/generated/org/elasticsearch/compute/aggregation/spatial/SpatialCentroidCartesianPointDocValuesGroupingAggregatorFunction.java +++ b/x-pack/plugin/esql/compute/src/main/generated/org/elasticsearch/compute/aggregation/spatial/SpatialCentroidCartesianPointDocValuesGroupingAggregatorFunction.java @@ -70,9 +70,7 @@ public GroupingAggregatorFunction.AddInput prepareProcessRawInputPage(SeenGroupI LongBlock encodedBlock = page.getBlock(channels.get(0)); LongVector encodedVector = encodedBlock.asVector(); if (encodedVector == null) { - if (encodedBlock.mayHaveNulls()) { - state.enableGroupIdTracking(seenGroupIds); - } + maybeEnableGroupIdTracking(seenGroupIds, encodedBlock); return new GroupingAggregatorFunction.AddInput() { @Override public void add(int positionOffset, IntArrayBlock groupIds) { @@ -344,6 +342,12 @@ public void addIntermediateInput(int positionOffset, IntVector groups, Page page } } + private void maybeEnableGroupIdTracking(SeenGroupIds seenGroupIds, LongBlock encodedBlock) { + if (encodedBlock.mayHaveNulls()) { + state.enableGroupIdTracking(seenGroupIds); + } + } + @Override public void selectedMayContainUnseenGroups(SeenGroupIds seenGroupIds) { state.enableGroupIdTracking(seenGroupIds); diff --git a/x-pack/plugin/esql/compute/src/main/generated/org/elasticsearch/compute/aggregation/spatial/SpatialCentroidCartesianPointSourceValuesGroupingAggregatorFunction.java b/x-pack/plugin/esql/compute/src/main/generated/org/elasticsearch/compute/aggregation/spatial/SpatialCentroidCartesianPointSourceValuesGroupingAggregatorFunction.java index b2e4db514acba..fddc57813ae69 100644 --- a/x-pack/plugin/esql/compute/src/main/generated/org/elasticsearch/compute/aggregation/spatial/SpatialCentroidCartesianPointSourceValuesGroupingAggregatorFunction.java +++ b/x-pack/plugin/esql/compute/src/main/generated/org/elasticsearch/compute/aggregation/spatial/SpatialCentroidCartesianPointSourceValuesGroupingAggregatorFunction.java @@ -73,9 +73,7 @@ public GroupingAggregatorFunction.AddInput prepareProcessRawInputPage(SeenGroupI BytesRefBlock wkbBlock = page.getBlock(channels.get(0)); BytesRefVector wkbVector = wkbBlock.asVector(); if (wkbVector == null) { - if (wkbBlock.mayHaveNulls()) { - state.enableGroupIdTracking(seenGroupIds); - } + maybeEnableGroupIdTracking(seenGroupIds, wkbBlock); return new GroupingAggregatorFunction.AddInput() { @Override public void add(int positionOffset, IntArrayBlock groupIds) { @@ -353,6 +351,12 @@ public void addIntermediateInput(int positionOffset, IntVector groups, Page page } } + private void maybeEnableGroupIdTracking(SeenGroupIds seenGroupIds, BytesRefBlock wkbBlock) { + if (wkbBlock.mayHaveNulls()) { + state.enableGroupIdTracking(seenGroupIds); + } + } + @Override public void selectedMayContainUnseenGroups(SeenGroupIds seenGroupIds) { state.enableGroupIdTracking(seenGroupIds); diff --git a/x-pack/plugin/esql/compute/src/main/generated/org/elasticsearch/compute/aggregation/spatial/SpatialCentroidGeoPointDocValuesGroupingAggregatorFunction.java b/x-pack/plugin/esql/compute/src/main/generated/org/elasticsearch/compute/aggregation/spatial/SpatialCentroidGeoPointDocValuesGroupingAggregatorFunction.java index 2c0835fe0a740..0f603afa77347 100644 --- a/x-pack/plugin/esql/compute/src/main/generated/org/elasticsearch/compute/aggregation/spatial/SpatialCentroidGeoPointDocValuesGroupingAggregatorFunction.java +++ b/x-pack/plugin/esql/compute/src/main/generated/org/elasticsearch/compute/aggregation/spatial/SpatialCentroidGeoPointDocValuesGroupingAggregatorFunction.java @@ -70,9 +70,7 @@ public GroupingAggregatorFunction.AddInput prepareProcessRawInputPage(SeenGroupI LongBlock encodedBlock = page.getBlock(channels.get(0)); LongVector encodedVector = encodedBlock.asVector(); if (encodedVector == null) { - if (encodedBlock.mayHaveNulls()) { - state.enableGroupIdTracking(seenGroupIds); - } + maybeEnableGroupIdTracking(seenGroupIds, encodedBlock); return new GroupingAggregatorFunction.AddInput() { @Override public void add(int positionOffset, IntArrayBlock groupIds) { @@ -344,6 +342,12 @@ public void addIntermediateInput(int positionOffset, IntVector groups, Page page } } + private void maybeEnableGroupIdTracking(SeenGroupIds seenGroupIds, LongBlock encodedBlock) { + if (encodedBlock.mayHaveNulls()) { + state.enableGroupIdTracking(seenGroupIds); + } + } + @Override public void selectedMayContainUnseenGroups(SeenGroupIds seenGroupIds) { state.enableGroupIdTracking(seenGroupIds); diff --git a/x-pack/plugin/esql/compute/src/main/generated/org/elasticsearch/compute/aggregation/spatial/SpatialCentroidGeoPointSourceValuesGroupingAggregatorFunction.java b/x-pack/plugin/esql/compute/src/main/generated/org/elasticsearch/compute/aggregation/spatial/SpatialCentroidGeoPointSourceValuesGroupingAggregatorFunction.java index 5cc8c1501038a..2f6d0d111367a 100644 --- a/x-pack/plugin/esql/compute/src/main/generated/org/elasticsearch/compute/aggregation/spatial/SpatialCentroidGeoPointSourceValuesGroupingAggregatorFunction.java +++ b/x-pack/plugin/esql/compute/src/main/generated/org/elasticsearch/compute/aggregation/spatial/SpatialCentroidGeoPointSourceValuesGroupingAggregatorFunction.java @@ -73,9 +73,7 @@ public GroupingAggregatorFunction.AddInput prepareProcessRawInputPage(SeenGroupI BytesRefBlock wkbBlock = page.getBlock(channels.get(0)); BytesRefVector wkbVector = wkbBlock.asVector(); if (wkbVector == null) { - if (wkbBlock.mayHaveNulls()) { - state.enableGroupIdTracking(seenGroupIds); - } + maybeEnableGroupIdTracking(seenGroupIds, wkbBlock); return new GroupingAggregatorFunction.AddInput() { @Override public void add(int positionOffset, IntArrayBlock groupIds) { @@ -353,6 +351,12 @@ public void addIntermediateInput(int positionOffset, IntVector groups, Page page } } + private void maybeEnableGroupIdTracking(SeenGroupIds seenGroupIds, BytesRefBlock wkbBlock) { + if (wkbBlock.mayHaveNulls()) { + state.enableGroupIdTracking(seenGroupIds); + } + } + @Override public void selectedMayContainUnseenGroups(SeenGroupIds seenGroupIds) { state.enableGroupIdTracking(seenGroupIds); diff --git a/x-pack/plugin/esql/compute/src/main/generated/org/elasticsearch/compute/aggregation/spatial/SpatialExtentCartesianPointDocValuesGroupingAggregatorFunction.java b/x-pack/plugin/esql/compute/src/main/generated/org/elasticsearch/compute/aggregation/spatial/SpatialExtentCartesianPointDocValuesGroupingAggregatorFunction.java index a1ec8a11079d7..0187cb05a2945 100644 --- a/x-pack/plugin/esql/compute/src/main/generated/org/elasticsearch/compute/aggregation/spatial/SpatialExtentCartesianPointDocValuesGroupingAggregatorFunction.java +++ b/x-pack/plugin/esql/compute/src/main/generated/org/elasticsearch/compute/aggregation/spatial/SpatialExtentCartesianPointDocValuesGroupingAggregatorFunction.java @@ -68,9 +68,7 @@ public GroupingAggregatorFunction.AddInput prepareProcessRawInputPage(SeenGroupI LongBlock vBlock = page.getBlock(channels.get(0)); LongVector vVector = vBlock.asVector(); if (vVector == null) { - if (vBlock.mayHaveNulls()) { - state.enableGroupIdTracking(seenGroupIds); - } + maybeEnableGroupIdTracking(seenGroupIds, vBlock); return new GroupingAggregatorFunction.AddInput() { @Override public void add(int positionOffset, IntArrayBlock groupIds) { @@ -327,6 +325,12 @@ public void addIntermediateInput(int positionOffset, IntVector groups, Page page } } + private void maybeEnableGroupIdTracking(SeenGroupIds seenGroupIds, LongBlock vBlock) { + if (vBlock.mayHaveNulls()) { + state.enableGroupIdTracking(seenGroupIds); + } + } + @Override public void selectedMayContainUnseenGroups(SeenGroupIds seenGroupIds) { state.enableGroupIdTracking(seenGroupIds); diff --git a/x-pack/plugin/esql/compute/src/main/generated/org/elasticsearch/compute/aggregation/spatial/SpatialExtentCartesianPointSourceValuesGroupingAggregatorFunction.java b/x-pack/plugin/esql/compute/src/main/generated/org/elasticsearch/compute/aggregation/spatial/SpatialExtentCartesianPointSourceValuesGroupingAggregatorFunction.java index c68996d317deb..6470b601bbc72 100644 --- a/x-pack/plugin/esql/compute/src/main/generated/org/elasticsearch/compute/aggregation/spatial/SpatialExtentCartesianPointSourceValuesGroupingAggregatorFunction.java +++ b/x-pack/plugin/esql/compute/src/main/generated/org/elasticsearch/compute/aggregation/spatial/SpatialExtentCartesianPointSourceValuesGroupingAggregatorFunction.java @@ -69,9 +69,7 @@ public GroupingAggregatorFunction.AddInput prepareProcessRawInputPage(SeenGroupI BytesRefBlock bytesBlock = page.getBlock(channels.get(0)); BytesRefVector bytesVector = bytesBlock.asVector(); if (bytesVector == null) { - if (bytesBlock.mayHaveNulls()) { - state.enableGroupIdTracking(seenGroupIds); - } + maybeEnableGroupIdTracking(seenGroupIds, bytesBlock); return new GroupingAggregatorFunction.AddInput() { @Override public void add(int positionOffset, IntArrayBlock groupIds) { @@ -335,6 +333,12 @@ public void addIntermediateInput(int positionOffset, IntVector groups, Page page } } + private void maybeEnableGroupIdTracking(SeenGroupIds seenGroupIds, BytesRefBlock bytesBlock) { + if (bytesBlock.mayHaveNulls()) { + state.enableGroupIdTracking(seenGroupIds); + } + } + @Override public void selectedMayContainUnseenGroups(SeenGroupIds seenGroupIds) { state.enableGroupIdTracking(seenGroupIds); diff --git a/x-pack/plugin/esql/compute/src/main/generated/org/elasticsearch/compute/aggregation/spatial/SpatialExtentCartesianShapeDocValuesGroupingAggregatorFunction.java b/x-pack/plugin/esql/compute/src/main/generated/org/elasticsearch/compute/aggregation/spatial/SpatialExtentCartesianShapeDocValuesGroupingAggregatorFunction.java index 8607ff009fc1d..3d4be828e3132 100644 --- a/x-pack/plugin/esql/compute/src/main/generated/org/elasticsearch/compute/aggregation/spatial/SpatialExtentCartesianShapeDocValuesGroupingAggregatorFunction.java +++ b/x-pack/plugin/esql/compute/src/main/generated/org/elasticsearch/compute/aggregation/spatial/SpatialExtentCartesianShapeDocValuesGroupingAggregatorFunction.java @@ -66,9 +66,7 @@ public GroupingAggregatorFunction.AddInput prepareProcessRawInputPage(SeenGroupI IntBlock valuesBlock = page.getBlock(channels.get(0)); IntVector valuesVector = valuesBlock.asVector(); if (valuesVector == null) { - if (valuesBlock.mayHaveNulls()) { - state.enableGroupIdTracking(seenGroupIds); - } + maybeEnableGroupIdTracking(seenGroupIds, valuesBlock); return new GroupingAggregatorFunction.AddInput() { @Override public void add(int positionOffset, IntArrayBlock groupIds) { @@ -299,6 +297,12 @@ public void addIntermediateInput(int positionOffset, IntVector groups, Page page } } + private void maybeEnableGroupIdTracking(SeenGroupIds seenGroupIds, IntBlock valuesBlock) { + if (valuesBlock.mayHaveNulls()) { + state.enableGroupIdTracking(seenGroupIds); + } + } + @Override public void selectedMayContainUnseenGroups(SeenGroupIds seenGroupIds) { state.enableGroupIdTracking(seenGroupIds); diff --git a/x-pack/plugin/esql/compute/src/main/generated/org/elasticsearch/compute/aggregation/spatial/SpatialExtentCartesianShapeSourceValuesGroupingAggregatorFunction.java b/x-pack/plugin/esql/compute/src/main/generated/org/elasticsearch/compute/aggregation/spatial/SpatialExtentCartesianShapeSourceValuesGroupingAggregatorFunction.java index ae017576d641d..f1c4dcd3d3044 100644 --- a/x-pack/plugin/esql/compute/src/main/generated/org/elasticsearch/compute/aggregation/spatial/SpatialExtentCartesianShapeSourceValuesGroupingAggregatorFunction.java +++ b/x-pack/plugin/esql/compute/src/main/generated/org/elasticsearch/compute/aggregation/spatial/SpatialExtentCartesianShapeSourceValuesGroupingAggregatorFunction.java @@ -69,9 +69,7 @@ public GroupingAggregatorFunction.AddInput prepareProcessRawInputPage(SeenGroupI BytesRefBlock bytesBlock = page.getBlock(channels.get(0)); BytesRefVector bytesVector = bytesBlock.asVector(); if (bytesVector == null) { - if (bytesBlock.mayHaveNulls()) { - state.enableGroupIdTracking(seenGroupIds); - } + maybeEnableGroupIdTracking(seenGroupIds, bytesBlock); return new GroupingAggregatorFunction.AddInput() { @Override public void add(int positionOffset, IntArrayBlock groupIds) { @@ -335,6 +333,12 @@ public void addIntermediateInput(int positionOffset, IntVector groups, Page page } } + private void maybeEnableGroupIdTracking(SeenGroupIds seenGroupIds, BytesRefBlock bytesBlock) { + if (bytesBlock.mayHaveNulls()) { + state.enableGroupIdTracking(seenGroupIds); + } + } + @Override public void selectedMayContainUnseenGroups(SeenGroupIds seenGroupIds) { state.enableGroupIdTracking(seenGroupIds); diff --git a/x-pack/plugin/esql/compute/src/main/generated/org/elasticsearch/compute/aggregation/spatial/SpatialExtentGeoPointDocValuesGroupingAggregatorFunction.java b/x-pack/plugin/esql/compute/src/main/generated/org/elasticsearch/compute/aggregation/spatial/SpatialExtentGeoPointDocValuesGroupingAggregatorFunction.java index aa386bf3f2bdb..9f4fe85ba05a3 100644 --- a/x-pack/plugin/esql/compute/src/main/generated/org/elasticsearch/compute/aggregation/spatial/SpatialExtentGeoPointDocValuesGroupingAggregatorFunction.java +++ b/x-pack/plugin/esql/compute/src/main/generated/org/elasticsearch/compute/aggregation/spatial/SpatialExtentGeoPointDocValuesGroupingAggregatorFunction.java @@ -70,9 +70,7 @@ public GroupingAggregatorFunction.AddInput prepareProcessRawInputPage(SeenGroupI LongBlock encodedBlock = page.getBlock(channels.get(0)); LongVector encodedVector = encodedBlock.asVector(); if (encodedVector == null) { - if (encodedBlock.mayHaveNulls()) { - state.enableGroupIdTracking(seenGroupIds); - } + maybeEnableGroupIdTracking(seenGroupIds, encodedBlock); return new GroupingAggregatorFunction.AddInput() { @Override public void add(int positionOffset, IntArrayBlock groupIds) { @@ -359,6 +357,12 @@ public void addIntermediateInput(int positionOffset, IntVector groups, Page page } } + private void maybeEnableGroupIdTracking(SeenGroupIds seenGroupIds, LongBlock encodedBlock) { + if (encodedBlock.mayHaveNulls()) { + state.enableGroupIdTracking(seenGroupIds); + } + } + @Override public void selectedMayContainUnseenGroups(SeenGroupIds seenGroupIds) { state.enableGroupIdTracking(seenGroupIds); diff --git a/x-pack/plugin/esql/compute/src/main/generated/org/elasticsearch/compute/aggregation/spatial/SpatialExtentGeoPointSourceValuesGroupingAggregatorFunction.java b/x-pack/plugin/esql/compute/src/main/generated/org/elasticsearch/compute/aggregation/spatial/SpatialExtentGeoPointSourceValuesGroupingAggregatorFunction.java index 057aae8e5af88..f4830e03cf457 100644 --- a/x-pack/plugin/esql/compute/src/main/generated/org/elasticsearch/compute/aggregation/spatial/SpatialExtentGeoPointSourceValuesGroupingAggregatorFunction.java +++ b/x-pack/plugin/esql/compute/src/main/generated/org/elasticsearch/compute/aggregation/spatial/SpatialExtentGeoPointSourceValuesGroupingAggregatorFunction.java @@ -71,9 +71,7 @@ public GroupingAggregatorFunction.AddInput prepareProcessRawInputPage(SeenGroupI BytesRefBlock bytesBlock = page.getBlock(channels.get(0)); BytesRefVector bytesVector = bytesBlock.asVector(); if (bytesVector == null) { - if (bytesBlock.mayHaveNulls()) { - state.enableGroupIdTracking(seenGroupIds); - } + maybeEnableGroupIdTracking(seenGroupIds, bytesBlock); return new GroupingAggregatorFunction.AddInput() { @Override public void add(int positionOffset, IntArrayBlock groupIds) { @@ -367,6 +365,12 @@ public void addIntermediateInput(int positionOffset, IntVector groups, Page page } } + private void maybeEnableGroupIdTracking(SeenGroupIds seenGroupIds, BytesRefBlock bytesBlock) { + if (bytesBlock.mayHaveNulls()) { + state.enableGroupIdTracking(seenGroupIds); + } + } + @Override public void selectedMayContainUnseenGroups(SeenGroupIds seenGroupIds) { state.enableGroupIdTracking(seenGroupIds); diff --git a/x-pack/plugin/esql/compute/src/main/generated/org/elasticsearch/compute/aggregation/spatial/SpatialExtentGeoShapeDocValuesGroupingAggregatorFunction.java b/x-pack/plugin/esql/compute/src/main/generated/org/elasticsearch/compute/aggregation/spatial/SpatialExtentGeoShapeDocValuesGroupingAggregatorFunction.java index c118e9315b6ff..0cf7a3b7ae910 100644 --- a/x-pack/plugin/esql/compute/src/main/generated/org/elasticsearch/compute/aggregation/spatial/SpatialExtentGeoShapeDocValuesGroupingAggregatorFunction.java +++ b/x-pack/plugin/esql/compute/src/main/generated/org/elasticsearch/compute/aggregation/spatial/SpatialExtentGeoShapeDocValuesGroupingAggregatorFunction.java @@ -68,9 +68,7 @@ public GroupingAggregatorFunction.AddInput prepareProcessRawInputPage(SeenGroupI IntBlock valuesBlock = page.getBlock(channels.get(0)); IntVector valuesVector = valuesBlock.asVector(); if (valuesVector == null) { - if (valuesBlock.mayHaveNulls()) { - state.enableGroupIdTracking(seenGroupIds); - } + maybeEnableGroupIdTracking(seenGroupIds, valuesBlock); return new GroupingAggregatorFunction.AddInput() { @Override public void add(int positionOffset, IntArrayBlock groupIds) { @@ -331,6 +329,12 @@ public void addIntermediateInput(int positionOffset, IntVector groups, Page page } } + private void maybeEnableGroupIdTracking(SeenGroupIds seenGroupIds, IntBlock valuesBlock) { + if (valuesBlock.mayHaveNulls()) { + state.enableGroupIdTracking(seenGroupIds); + } + } + @Override public void selectedMayContainUnseenGroups(SeenGroupIds seenGroupIds) { state.enableGroupIdTracking(seenGroupIds); diff --git a/x-pack/plugin/esql/compute/src/main/generated/org/elasticsearch/compute/aggregation/spatial/SpatialExtentGeoShapeSourceValuesGroupingAggregatorFunction.java b/x-pack/plugin/esql/compute/src/main/generated/org/elasticsearch/compute/aggregation/spatial/SpatialExtentGeoShapeSourceValuesGroupingAggregatorFunction.java index 37024a3df6cd4..820429d6a2d4a 100644 --- a/x-pack/plugin/esql/compute/src/main/generated/org/elasticsearch/compute/aggregation/spatial/SpatialExtentGeoShapeSourceValuesGroupingAggregatorFunction.java +++ b/x-pack/plugin/esql/compute/src/main/generated/org/elasticsearch/compute/aggregation/spatial/SpatialExtentGeoShapeSourceValuesGroupingAggregatorFunction.java @@ -71,9 +71,7 @@ public GroupingAggregatorFunction.AddInput prepareProcessRawInputPage(SeenGroupI BytesRefBlock bytesBlock = page.getBlock(channels.get(0)); BytesRefVector bytesVector = bytesBlock.asVector(); if (bytesVector == null) { - if (bytesBlock.mayHaveNulls()) { - state.enableGroupIdTracking(seenGroupIds); - } + maybeEnableGroupIdTracking(seenGroupIds, bytesBlock); return new GroupingAggregatorFunction.AddInput() { @Override public void add(int positionOffset, IntArrayBlock groupIds) { @@ -367,6 +365,12 @@ public void addIntermediateInput(int positionOffset, IntVector groups, Page page } } + private void maybeEnableGroupIdTracking(SeenGroupIds seenGroupIds, BytesRefBlock bytesBlock) { + if (bytesBlock.mayHaveNulls()) { + state.enableGroupIdTracking(seenGroupIds); + } + } + @Override public void selectedMayContainUnseenGroups(SeenGroupIds seenGroupIds) { state.enableGroupIdTracking(seenGroupIds); diff --git a/x-pack/plugin/esql/compute/src/main/java/org/elasticsearch/compute/aggregation/X-2State.java.st b/x-pack/plugin/esql/compute/src/main/java/org/elasticsearch/compute/aggregation/X-2State.java.st new file mode 100644 index 0000000000000..87cd4db893eec --- /dev/null +++ b/x-pack/plugin/esql/compute/src/main/java/org/elasticsearch/compute/aggregation/X-2State.java.st @@ -0,0 +1,62 @@ +/* + * 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.compute.data.Block; +import org.elasticsearch.compute.operator.DriverContext; + +/** + * Aggregator state for a single {@code $v1_type$} and a single {@code $v2_type$}. + * This class is generated. Edit {@code X-2State.java.st} instead. + */ +final class $v1_Type$$v2_Type$State implements AggregatorState { + private $v1_type$ v1; + private $v2_type$ v2; + private boolean seen; + + $v1_Type$$v2_Type$State($v1_type$ v1, $v2_type$ v2) { + this.v1 = v1; + this.v2 = v2; + } + + $v1_type$ v1() { + return v1; + } + + void v1($v1_type$ v1) { + this.v1 = v1; + } + + $v2_type$ v2() { + return v2; + } + + void v2($v2_type$ v2) { + this.v2 = v2; + } + + boolean seen() { + return seen; + } + + void seen(boolean seen) { + this.seen = seen; + } + + /** Extracts an intermediate view of the contents of this state. */ + @Override + public void toIntermediate(Block[] blocks, int offset, DriverContext driverContext) { + assert blocks.length >= offset + 3; + blocks[offset + 0] = driverContext.blockFactory().newConstant$v1_Type$BlockWith(v1, 1); + blocks[offset + 1] = driverContext.blockFactory().newConstant$v2_Type$BlockWith(v2, 1); + blocks[offset + 2] = driverContext.blockFactory().newConstantBooleanBlockWith(seen, 1); + } + + @Override + public void close() {} +} diff --git a/x-pack/plugin/esql/compute/src/main/java/org/elasticsearch/compute/aggregation/X-ValueByTimestampAggregator.java.st b/x-pack/plugin/esql/compute/src/main/java/org/elasticsearch/compute/aggregation/X-ValueByTimestampAggregator.java.st index 7d5248abeaabe..ad1e383f4e482 100644 --- a/x-pack/plugin/esql/compute/src/main/java/org/elasticsearch/compute/aggregation/X-ValueByTimestampAggregator.java.st +++ b/x-pack/plugin/esql/compute/src/main/java/org/elasticsearch/compute/aggregation/X-ValueByTimestampAggregator.java.st @@ -27,10 +27,42 @@ import org.elasticsearch.core.Releasables; * A time-series aggregation function that collects the $Occurrence$ occurrence value of a time series in a specified interval. * This class is generated. Edit `X-ValueByTimestampAggregator.java.st` instead. */ +@Aggregator( + { + @IntermediateState(name = "timestamps", type = "LONG"), + @IntermediateState(name = "values", type = "$TYPE$"), + @IntermediateState(name = "seen", type = "BOOLEAN") } +) @GroupingAggregator( { @IntermediateState(name = "timestamps", type = "LONG_BLOCK"), @IntermediateState(name = "values", type = "$TYPE$_BLOCK") } ) public class $Occurrence$$Type$ByTimestampAggregator { + public static String describe() { + return "$occurrence$_$type$_by_timestamp"; + } + + public static Long$Type$State initSingle(DriverContext driverContext) { + return new Long$Type$State(0, 0); + } + + public static void combine(Long$Type$State current, $type$ value, long timestamp) { + if (timestamp $if(First)$<$else$>$endif$ current.v1()) { + current.v1(timestamp); + current.v2(value); + } + } + + public static void combineIntermediate(Long$Type$State current, long timestamp, $type$ value, boolean seen) { + if (seen) { + current.seen(true); + combine(current, value, timestamp); + } + } + + public static Block evaluateFinal(Long$Type$State current, DriverContext ctx) { + return ctx.blockFactory().newConstant$Type$BlockWith(current.v2(), 1); + } + public static GroupingState initGrouping(DriverContext driverContext) { return new GroupingState(driverContext.bigArrays()); } @@ -76,6 +108,11 @@ public class $Occurrence$$Type$ByTimestampAggregator { timestamps = bigArrays.newLongArray(1, false); this.timestamps = timestamps; this.values = bigArrays.new$Type$Array(1, false); + /* + * Enable group id tracking because we use has hasValue in the + * collection itself to detect the when a value first arrives. + */ + enableGroupIdTracking(new SeenGroupIds.Empty()); success = true; } finally { if (success == false) { diff --git a/x-pack/plugin/esql/compute/src/test/java/org/elasticsearch/compute/aggregation/AggregatorFunctionTestCase.java b/x-pack/plugin/esql/compute/src/test/java/org/elasticsearch/compute/aggregation/AggregatorFunctionTestCase.java index c1916b0df3304..c6f0efe4bb7b3 100644 --- a/x-pack/plugin/esql/compute/src/test/java/org/elasticsearch/compute/aggregation/AggregatorFunctionTestCase.java +++ b/x-pack/plugin/esql/compute/src/test/java/org/elasticsearch/compute/aggregation/AggregatorFunctionTestCase.java @@ -74,12 +74,18 @@ private Operator.OperatorFactory simpleWithMode( AggregatorMode mode, Function wrap ) { - List channels = mode.isInputPartial() ? range(0, aggregatorIntermediateBlockCount()).boxed().toList() : List.of(0); + List channels = mode.isInputPartial() + ? range(0, aggregatorIntermediateBlockCount()).boxed().toList() + : IntStream.range(0, inputCount()).boxed().toList(); AggregatorFunctionSupplier supplier = aggregatorFunction(); Aggregator.Factory factory = wrap.apply(supplier).aggregatorFactory(mode, channels); return new AggregationOperator.AggregationOperatorFactory(List.of(factory), mode); } + protected int inputCount() { + return 1; + } + @Override protected final Matcher expectedDescriptionOfSimple() { return equalTo("AggregationOperator[mode = SINGLE, aggs = " + expectedDescriptionOfAggregator() + "]"); @@ -94,7 +100,7 @@ protected final Matcher expectedToStringOfSimple() { protected String expectedToStringOfSimpleAggregator() { String type = getClass().getSimpleName().replace("Tests", ""); - return type + "[channels=[0]]"; + return type + "[channels=" + IntStream.range(0, inputCount()).boxed().toList() + "]"; } @Override diff --git a/x-pack/plugin/esql/compute/src/test/java/org/elasticsearch/compute/aggregation/FirstDoubleByTimestampAggregatorFunctionTests.java b/x-pack/plugin/esql/compute/src/test/java/org/elasticsearch/compute/aggregation/FirstDoubleByTimestampAggregatorFunctionTests.java new file mode 100644 index 0000000000000..8f8d965aba8d3 --- /dev/null +++ b/x-pack/plugin/esql/compute/src/test/java/org/elasticsearch/compute/aggregation/FirstDoubleByTimestampAggregatorFunctionTests.java @@ -0,0 +1,71 @@ +/* + * 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.compute.aggregation.FirstLongByTimestampGroupingAggregatorFunctionTests.ExpectedWork; +import org.elasticsearch.compute.data.Block; +import org.elasticsearch.compute.data.BlockFactory; +import org.elasticsearch.compute.data.BlockUtils; +import org.elasticsearch.compute.data.DoubleBlock; +import org.elasticsearch.compute.data.ElementType; +import org.elasticsearch.compute.data.LongBlock; +import org.elasticsearch.compute.data.Page; +import org.elasticsearch.compute.operator.ListRowsBlockSourceOperator; +import org.elasticsearch.compute.operator.SourceOperator; + +import java.util.List; +import java.util.stream.IntStream; + +public class FirstDoubleByTimestampAggregatorFunctionTests extends AggregatorFunctionTestCase { + @Override + protected SourceOperator simpleInput(BlockFactory blockFactory, int size) { + return new ListRowsBlockSourceOperator( + blockFactory, + List.of(ElementType.DOUBLE, ElementType.LONG), + IntStream.range(0, size).mapToObj(l -> List.of(randomDouble(), randomLong())).toList() + ); + } + + @Override + protected AggregatorFunctionSupplier aggregatorFunction() { + return new FirstDoubleByTimestampAggregatorFunctionSupplier(); + } + + @Override + protected int inputCount() { + return 2; + } + + @Override + protected String expectedDescriptionOfAggregator() { + return "first_double_by_timestamp"; + } + + @Override + public void assertSimpleOutput(List input, Block result) { + ExpectedWork work = new ExpectedWork(true); + for (Page page : input) { + DoubleBlock values = page.getBlock(0); + LongBlock timestamps = page.getBlock(1); + for (int p = 0; p < page.getPositionCount(); p++) { + int tsStart = timestamps.getFirstValueIndex(p); + int tsEnd = tsStart + timestamps.getValueCount(p); + for (int tsOffset = tsStart; tsOffset < tsEnd; tsOffset++) { + long timestamp = timestamps.getLong(tsOffset); + int vStart = values.getFirstValueIndex(p); + int vEnd = vStart + values.getValueCount(p); + for (int vOffset = vStart; vOffset < vEnd; vOffset++) { + double value = values.getDouble(vOffset); + work.add(timestamp, value); + } + } + } + } + work.check(BlockUtils.toJavaObject(result, 0)); + } +} diff --git a/x-pack/plugin/esql/compute/src/test/java/org/elasticsearch/compute/aggregation/FirstDoubleByTimestampGroupingAggregatorFunctionTests.java b/x-pack/plugin/esql/compute/src/test/java/org/elasticsearch/compute/aggregation/FirstDoubleByTimestampGroupingAggregatorFunctionTests.java new file mode 100644 index 0000000000000..b084c166d1d86 --- /dev/null +++ b/x-pack/plugin/esql/compute/src/test/java/org/elasticsearch/compute/aggregation/FirstDoubleByTimestampGroupingAggregatorFunctionTests.java @@ -0,0 +1,71 @@ +/* + * 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.compute.aggregation.FirstLongByTimestampGroupingAggregatorFunctionTests.ExpectedWork; +import org.elasticsearch.compute.data.Block; +import org.elasticsearch.compute.data.BlockFactory; +import org.elasticsearch.compute.data.BlockUtils; +import org.elasticsearch.compute.data.DoubleBlock; +import org.elasticsearch.compute.data.ElementType; +import org.elasticsearch.compute.data.LongBlock; +import org.elasticsearch.compute.data.Page; +import org.elasticsearch.compute.operator.ListRowsBlockSourceOperator; +import org.elasticsearch.compute.operator.SourceOperator; + +import java.util.List; +import java.util.stream.IntStream; + +public class FirstDoubleByTimestampGroupingAggregatorFunctionTests extends GroupingAggregatorFunctionTestCase { + @Override + protected SourceOperator simpleInput(BlockFactory blockFactory, int size) { + return new ListRowsBlockSourceOperator( + blockFactory, + List.of(ElementType.LONG, ElementType.DOUBLE, ElementType.LONG), + IntStream.range(0, size).mapToObj(l -> List.of(randomLongBetween(0, 4), randomDouble(), randomLong())).toList() + ); + } + + @Override + protected int inputCount() { + return 2; + } + + @Override + protected AggregatorFunctionSupplier aggregatorFunction() { + return new FirstDoubleByTimestampAggregatorFunctionSupplier(); + } + + @Override + protected String expectedDescriptionOfAggregator() { + return "first_double_by_timestamp"; + } + + @Override + protected void assertSimpleGroup(List input, Block result, int position, Long group) { + ExpectedWork work = new ExpectedWork(true); + for (Page page : input) { + matchingGroups(page, group).forEach(p -> { + DoubleBlock values = page.getBlock(1); + LongBlock timestamps = page.getBlock(2); + int tsStart = timestamps.getFirstValueIndex(p); + int tsEnd = tsStart + timestamps.getValueCount(p); + for (int tsOffset = tsStart; tsOffset < tsEnd; tsOffset++) { + long timestamp = timestamps.getLong(tsOffset); + int vStart = values.getFirstValueIndex(p); + int vEnd = vStart + values.getValueCount(p); + for (int vOffset = vStart; vOffset < vEnd; vOffset++) { + double value = values.getDouble(vOffset); + work.add(timestamp, value); + } + } + }); + } + work.check(BlockUtils.toJavaObject(result, position)); + } +} diff --git a/x-pack/plugin/esql/compute/src/test/java/org/elasticsearch/compute/aggregation/FirstFloatByTimestampAggregatorFunctionTests.java b/x-pack/plugin/esql/compute/src/test/java/org/elasticsearch/compute/aggregation/FirstFloatByTimestampAggregatorFunctionTests.java new file mode 100644 index 0000000000000..4a2148d7ebf0e --- /dev/null +++ b/x-pack/plugin/esql/compute/src/test/java/org/elasticsearch/compute/aggregation/FirstFloatByTimestampAggregatorFunctionTests.java @@ -0,0 +1,71 @@ +/* + * 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.compute.aggregation.FirstLongByTimestampGroupingAggregatorFunctionTests.ExpectedWork; +import org.elasticsearch.compute.data.Block; +import org.elasticsearch.compute.data.BlockFactory; +import org.elasticsearch.compute.data.BlockUtils; +import org.elasticsearch.compute.data.ElementType; +import org.elasticsearch.compute.data.FloatBlock; +import org.elasticsearch.compute.data.LongBlock; +import org.elasticsearch.compute.data.Page; +import org.elasticsearch.compute.operator.ListRowsBlockSourceOperator; +import org.elasticsearch.compute.operator.SourceOperator; + +import java.util.List; +import java.util.stream.IntStream; + +public class FirstFloatByTimestampAggregatorFunctionTests extends AggregatorFunctionTestCase { + @Override + protected SourceOperator simpleInput(BlockFactory blockFactory, int size) { + return new ListRowsBlockSourceOperator( + blockFactory, + List.of(ElementType.FLOAT, ElementType.LONG), + IntStream.range(0, size).mapToObj(l -> List.of(randomInt(), randomLong())).toList() + ); + } + + @Override + protected AggregatorFunctionSupplier aggregatorFunction() { + return new FirstFloatByTimestampAggregatorFunctionSupplier(); + } + + @Override + protected int inputCount() { + return 2; + } + + @Override + protected String expectedDescriptionOfAggregator() { + return "first_float_by_timestamp"; + } + + @Override + public void assertSimpleOutput(List input, Block result) { + ExpectedWork work = new ExpectedWork(true); + for (Page page : input) { + FloatBlock values = page.getBlock(0); + LongBlock timestamps = page.getBlock(1); + for (int p = 0; p < page.getPositionCount(); p++) { + int tsStart = timestamps.getFirstValueIndex(p); + int tsEnd = tsStart + timestamps.getValueCount(p); + for (int tsOffset = tsStart; tsOffset < tsEnd; tsOffset++) { + long timestamp = timestamps.getLong(tsOffset); + int vStart = values.getFirstValueIndex(p); + int vEnd = vStart + values.getValueCount(p); + for (int vOffset = vStart; vOffset < vEnd; vOffset++) { + float value = values.getFloat(vOffset); + work.add(timestamp, value); + } + } + } + } + work.check(BlockUtils.toJavaObject(result, 0)); + } +} diff --git a/x-pack/plugin/esql/compute/src/test/java/org/elasticsearch/compute/aggregation/FirstFloatByTimestampGroupingAggregatorFunctionTests.java b/x-pack/plugin/esql/compute/src/test/java/org/elasticsearch/compute/aggregation/FirstFloatByTimestampGroupingAggregatorFunctionTests.java new file mode 100644 index 0000000000000..8d2027ae57fd2 --- /dev/null +++ b/x-pack/plugin/esql/compute/src/test/java/org/elasticsearch/compute/aggregation/FirstFloatByTimestampGroupingAggregatorFunctionTests.java @@ -0,0 +1,71 @@ +/* + * 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.compute.aggregation.FirstLongByTimestampGroupingAggregatorFunctionTests.ExpectedWork; +import org.elasticsearch.compute.data.Block; +import org.elasticsearch.compute.data.BlockFactory; +import org.elasticsearch.compute.data.BlockUtils; +import org.elasticsearch.compute.data.ElementType; +import org.elasticsearch.compute.data.FloatBlock; +import org.elasticsearch.compute.data.LongBlock; +import org.elasticsearch.compute.data.Page; +import org.elasticsearch.compute.operator.ListRowsBlockSourceOperator; +import org.elasticsearch.compute.operator.SourceOperator; + +import java.util.List; +import java.util.stream.IntStream; + +public class FirstFloatByTimestampGroupingAggregatorFunctionTests extends GroupingAggregatorFunctionTestCase { + @Override + protected SourceOperator simpleInput(BlockFactory blockFactory, int size) { + return new ListRowsBlockSourceOperator( + blockFactory, + List.of(ElementType.LONG, ElementType.FLOAT, ElementType.LONG), + IntStream.range(0, size).mapToObj(l -> List.of(randomLongBetween(0, 4), randomFloat(), randomLong())).toList() + ); + } + + @Override + protected int inputCount() { + return 2; + } + + @Override + protected AggregatorFunctionSupplier aggregatorFunction() { + return new FirstFloatByTimestampAggregatorFunctionSupplier(); + } + + @Override + protected String expectedDescriptionOfAggregator() { + return "first_float_by_timestamp"; + } + + @Override + protected void assertSimpleGroup(List input, Block result, int position, Long group) { + ExpectedWork work = new ExpectedWork(true); + for (Page page : input) { + matchingGroups(page, group).forEach(p -> { + FloatBlock values = page.getBlock(1); + LongBlock timestamps = page.getBlock(2); + int tsStart = timestamps.getFirstValueIndex(p); + int tsEnd = tsStart + timestamps.getValueCount(p); + for (int tsOffset = tsStart; tsOffset < tsEnd; tsOffset++) { + long timestamp = timestamps.getLong(tsOffset); + int vStart = values.getFirstValueIndex(p); + int vEnd = vStart + values.getValueCount(p); + for (int vOffset = vStart; vOffset < vEnd; vOffset++) { + float value = values.getFloat(vOffset); + work.add(timestamp, value); + } + } + }); + } + work.check(BlockUtils.toJavaObject(result, position)); + } +} diff --git a/x-pack/plugin/esql/compute/src/test/java/org/elasticsearch/compute/aggregation/FirstIntByTimestampAggregatorFunctionTests.java b/x-pack/plugin/esql/compute/src/test/java/org/elasticsearch/compute/aggregation/FirstIntByTimestampAggregatorFunctionTests.java new file mode 100644 index 0000000000000..383bab213cf19 --- /dev/null +++ b/x-pack/plugin/esql/compute/src/test/java/org/elasticsearch/compute/aggregation/FirstIntByTimestampAggregatorFunctionTests.java @@ -0,0 +1,71 @@ +/* + * 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.compute.aggregation.FirstLongByTimestampGroupingAggregatorFunctionTests.ExpectedWork; +import org.elasticsearch.compute.data.Block; +import org.elasticsearch.compute.data.BlockFactory; +import org.elasticsearch.compute.data.BlockUtils; +import org.elasticsearch.compute.data.ElementType; +import org.elasticsearch.compute.data.IntBlock; +import org.elasticsearch.compute.data.LongBlock; +import org.elasticsearch.compute.data.Page; +import org.elasticsearch.compute.operator.ListRowsBlockSourceOperator; +import org.elasticsearch.compute.operator.SourceOperator; + +import java.util.List; +import java.util.stream.IntStream; + +public class FirstIntByTimestampAggregatorFunctionTests extends AggregatorFunctionTestCase { + @Override + protected SourceOperator simpleInput(BlockFactory blockFactory, int size) { + return new ListRowsBlockSourceOperator( + blockFactory, + List.of(ElementType.INT, ElementType.LONG), + IntStream.range(0, size).mapToObj(l -> List.of(randomInt(), randomLong())).toList() + ); + } + + @Override + protected AggregatorFunctionSupplier aggregatorFunction() { + return new FirstIntByTimestampAggregatorFunctionSupplier(); + } + + @Override + protected int inputCount() { + return 2; + } + + @Override + protected String expectedDescriptionOfAggregator() { + return "first_int_by_timestamp"; + } + + @Override + public void assertSimpleOutput(List input, Block result) { + ExpectedWork work = new ExpectedWork(true); + for (Page page : input) { + IntBlock values = page.getBlock(0); + LongBlock timestamps = page.getBlock(1); + for (int p = 0; p < page.getPositionCount(); p++) { + int tsStart = timestamps.getFirstValueIndex(p); + int tsEnd = tsStart + timestamps.getValueCount(p); + for (int tsOffset = tsStart; tsOffset < tsEnd; tsOffset++) { + long timestamp = timestamps.getLong(tsOffset); + int vStart = values.getFirstValueIndex(p); + int vEnd = vStart + values.getValueCount(p); + for (int vOffset = vStart; vOffset < vEnd; vOffset++) { + int value = values.getInt(vOffset); + work.add(timestamp, value); + } + } + } + } + work.check(BlockUtils.toJavaObject(result, 0)); + } +} diff --git a/x-pack/plugin/esql/compute/src/test/java/org/elasticsearch/compute/aggregation/FirstIntByTimestampGroupingAggregatorFunctionTests.java b/x-pack/plugin/esql/compute/src/test/java/org/elasticsearch/compute/aggregation/FirstIntByTimestampGroupingAggregatorFunctionTests.java new file mode 100644 index 0000000000000..b6952cb50e615 --- /dev/null +++ b/x-pack/plugin/esql/compute/src/test/java/org/elasticsearch/compute/aggregation/FirstIntByTimestampGroupingAggregatorFunctionTests.java @@ -0,0 +1,71 @@ +/* + * 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.compute.aggregation.FirstLongByTimestampGroupingAggregatorFunctionTests.ExpectedWork; +import org.elasticsearch.compute.data.Block; +import org.elasticsearch.compute.data.BlockFactory; +import org.elasticsearch.compute.data.BlockUtils; +import org.elasticsearch.compute.data.ElementType; +import org.elasticsearch.compute.data.IntBlock; +import org.elasticsearch.compute.data.LongBlock; +import org.elasticsearch.compute.data.Page; +import org.elasticsearch.compute.operator.ListRowsBlockSourceOperator; +import org.elasticsearch.compute.operator.SourceOperator; + +import java.util.List; +import java.util.stream.IntStream; + +public class FirstIntByTimestampGroupingAggregatorFunctionTests extends GroupingAggregatorFunctionTestCase { + @Override + protected SourceOperator simpleInput(BlockFactory blockFactory, int size) { + return new ListRowsBlockSourceOperator( + blockFactory, + List.of(ElementType.LONG, ElementType.INT, ElementType.LONG), + IntStream.range(0, size).mapToObj(l -> List.of(randomLongBetween(0, 4), randomInt(), randomLong())).toList() + ); + } + + @Override + protected int inputCount() { + return 2; + } + + @Override + protected AggregatorFunctionSupplier aggregatorFunction() { + return new FirstIntByTimestampAggregatorFunctionSupplier(); + } + + @Override + protected String expectedDescriptionOfAggregator() { + return "first_int_by_timestamp"; + } + + @Override + protected void assertSimpleGroup(List input, Block result, int position, Long group) { + ExpectedWork work = new ExpectedWork(true); + for (Page page : input) { + matchingGroups(page, group).forEach(p -> { + IntBlock values = page.getBlock(1); + LongBlock timestamps = page.getBlock(2); + int tsStart = timestamps.getFirstValueIndex(p); + int tsEnd = tsStart + timestamps.getValueCount(p); + for (int tsOffset = tsStart; tsOffset < tsEnd; tsOffset++) { + long timestamp = timestamps.getLong(tsOffset); + int vStart = values.getFirstValueIndex(p); + int vEnd = vStart + values.getValueCount(p); + for (int vOffset = vStart; vOffset < vEnd; vOffset++) { + int value = values.getInt(vOffset); + work.add(timestamp, value); + } + } + }); + } + work.check(BlockUtils.toJavaObject(result, position)); + } +} diff --git a/x-pack/plugin/esql/compute/src/test/java/org/elasticsearch/compute/aggregation/FirstLongByTimestampAggregatorFunctionTests.java b/x-pack/plugin/esql/compute/src/test/java/org/elasticsearch/compute/aggregation/FirstLongByTimestampAggregatorFunctionTests.java new file mode 100644 index 0000000000000..a77ad857b9ef9 --- /dev/null +++ b/x-pack/plugin/esql/compute/src/test/java/org/elasticsearch/compute/aggregation/FirstLongByTimestampAggregatorFunctionTests.java @@ -0,0 +1,69 @@ +/* + * 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.compute.aggregation.FirstLongByTimestampGroupingAggregatorFunctionTests.ExpectedWork; +import org.elasticsearch.compute.data.Block; +import org.elasticsearch.compute.data.BlockFactory; +import org.elasticsearch.compute.data.BlockUtils; +import org.elasticsearch.compute.data.LongBlock; +import org.elasticsearch.compute.data.Page; +import org.elasticsearch.compute.operator.SourceOperator; +import org.elasticsearch.compute.operator.TupleLongLongBlockSourceOperator; +import org.elasticsearch.core.Tuple; + +import java.util.List; +import java.util.stream.IntStream; + +public class FirstLongByTimestampAggregatorFunctionTests extends AggregatorFunctionTestCase { + @Override + protected SourceOperator simpleInput(BlockFactory blockFactory, int size) { + return new TupleLongLongBlockSourceOperator( + blockFactory, + IntStream.range(0, size).mapToObj(l -> Tuple.tuple(randomLong(), randomLong())) + ); + } + + @Override + protected AggregatorFunctionSupplier aggregatorFunction() { + return new FirstLongByTimestampAggregatorFunctionSupplier(); + } + + @Override + protected int inputCount() { + return 2; + } + + @Override + protected String expectedDescriptionOfAggregator() { + return "first_long_by_timestamp"; + } + + @Override + public void assertSimpleOutput(List input, Block result) { + ExpectedWork work = new ExpectedWork(true); + for (Page page : input) { + LongBlock values = page.getBlock(0); + LongBlock timestamps = page.getBlock(1); + for (int p = 0; p < page.getPositionCount(); p++) { + int tsStart = timestamps.getFirstValueIndex(p); + int tsEnd = tsStart + timestamps.getValueCount(p); + for (int tsOffset = tsStart; tsOffset < tsEnd; tsOffset++) { + long timestamp = timestamps.getLong(tsOffset); + int vStart = values.getFirstValueIndex(p); + int vEnd = vStart + values.getValueCount(p); + for (int vOffset = vStart; vOffset < vEnd; vOffset++) { + long value = values.getLong(vOffset); + work.add(timestamp, value); + } + } + } + } + work.check(BlockUtils.toJavaObject(result, 0)); + } +} diff --git a/x-pack/plugin/esql/compute/src/test/java/org/elasticsearch/compute/aggregation/FirstLongByTimestampGroupingAggregatorFunctionTests.java b/x-pack/plugin/esql/compute/src/test/java/org/elasticsearch/compute/aggregation/FirstLongByTimestampGroupingAggregatorFunctionTests.java new file mode 100644 index 0000000000000..6f4f609b61420 --- /dev/null +++ b/x-pack/plugin/esql/compute/src/test/java/org/elasticsearch/compute/aggregation/FirstLongByTimestampGroupingAggregatorFunctionTests.java @@ -0,0 +1,109 @@ +/* + * 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.compute.data.Block; +import org.elasticsearch.compute.data.BlockFactory; +import org.elasticsearch.compute.data.BlockUtils; +import org.elasticsearch.compute.data.ElementType; +import org.elasticsearch.compute.data.LongBlock; +import org.elasticsearch.compute.data.Page; +import org.elasticsearch.compute.operator.ListRowsBlockSourceOperator; +import org.elasticsearch.compute.operator.SourceOperator; + +import java.util.HashSet; +import java.util.List; +import java.util.Set; +import java.util.stream.IntStream; + +public class FirstLongByTimestampGroupingAggregatorFunctionTests extends GroupingAggregatorFunctionTestCase { + @Override + protected SourceOperator simpleInput(BlockFactory blockFactory, int size) { + return new ListRowsBlockSourceOperator( + blockFactory, + List.of(ElementType.LONG, ElementType.LONG, ElementType.LONG), + IntStream.range(0, size).mapToObj(l -> List.of(randomLongBetween(0, 4), randomLong(), randomLong())).toList() + ); + } + + @Override + protected int inputCount() { + return 2; + } + + @Override + protected AggregatorFunctionSupplier aggregatorFunction() { + return new FirstLongByTimestampAggregatorFunctionSupplier(); + } + + @Override + protected String expectedDescriptionOfAggregator() { + return "first_long_by_timestamp"; + } + + @Override + protected void assertSimpleGroup(List input, Block result, int position, Long group) { + ExpectedWork work = new ExpectedWork(true); + for (Page page : input) { + matchingGroups(page, group).forEach(p -> { + LongBlock values = page.getBlock(1); + LongBlock timestamps = page.getBlock(2); + int tsStart = timestamps.getFirstValueIndex(p); + int tsEnd = tsStart + timestamps.getValueCount(p); + for (int tsOffset = tsStart; tsOffset < tsEnd; tsOffset++) { + long timestamp = timestamps.getLong(tsOffset); + int vStart = values.getFirstValueIndex(p); + int vEnd = vStart + values.getValueCount(p); + for (int vOffset = vStart; vOffset < vEnd; vOffset++) { + long value = values.getLong(vOffset); + work.add(timestamp, value); + } + } + }); + } + work.check(BlockUtils.toJavaObject(result, position)); + } + + static class ExpectedWork { + private final Set expected = new HashSet<>(); + private final boolean first; + private long expectedTimestamp = 0; + + ExpectedWork(boolean first) { + this.first = first; + } + + void add(long timestamp, Object value) { + if (expected.isEmpty()) { + expectedTimestamp = timestamp; + expected.add(value); + } else if (first ? timestamp < expectedTimestamp : timestamp > expectedTimestamp) { + expectedTimestamp = timestamp; + expected.clear(); + expected.add(value); + } else if (timestamp == expectedTimestamp) { + expected.add(value); + } + } + + void check(Object v) { + if (expected.isEmpty()) { + if (v != null) { + throw new AssertionError("expected null but was " + v); + } + } else { + if (expected.contains(v) == false) { + String expectedMessage = expected.size() == 1 + ? "expected " + expected.iterator().next() + : "expected one of " + expected.stream().sorted().toList(); + throw new AssertionError(expectedMessage + " but was " + v); + } + } + } + } +} diff --git a/x-pack/plugin/esql/compute/src/test/java/org/elasticsearch/compute/aggregation/GroupingAggregatorFunctionTestCase.java b/x-pack/plugin/esql/compute/src/test/java/org/elasticsearch/compute/aggregation/GroupingAggregatorFunctionTestCase.java index dda9671b3b242..917cde8004568 100644 --- a/x-pack/plugin/esql/compute/src/test/java/org/elasticsearch/compute/aggregation/GroupingAggregatorFunctionTestCase.java +++ b/x-pack/plugin/esql/compute/src/test/java/org/elasticsearch/compute/aggregation/GroupingAggregatorFunctionTestCase.java @@ -61,6 +61,7 @@ import static org.elasticsearch.compute.test.BlockTestUtils.append; import static org.hamcrest.Matchers.equalTo; import static org.hamcrest.Matchers.hasSize; +import static org.hamcrest.Matchers.in; /** * Shared tests for testing grouped aggregations. @@ -96,7 +97,13 @@ protected final Operator.OperatorFactory simpleWithMode(SimpleOptions options, A } protected List channels(AggregatorMode mode) { - return mode.isInputPartial() ? range(1, 1 + aggregatorIntermediateBlockCount()).boxed().toList() : List.of(1); + return mode.isInputPartial() + ? range(1, 1 + aggregatorIntermediateBlockCount()).boxed().toList() + : range(1, inputCount() + 1).boxed().toList(); + } + + protected int inputCount() { + return 1; } private Operator.OperatorFactory simpleWithMode( @@ -149,7 +156,7 @@ protected final Matcher expectedToStringOfSimple() { protected String expectedToStringOfSimpleAggregator() { String type = getClass().getSimpleName().replace("Tests", ""); - return type + "[channels=[1]]"; + return type + "[channels=" + IntStream.range(1, inputCount() + 1).boxed().toList() + "]"; } private SeenGroups seenGroups(List input) { @@ -479,7 +486,12 @@ private void assertNullOnly(List operators, DriverContext driverContex } else { groupBuilder.appendNull(); } - List source = List.of(new Page(groupBuilder.build(), blockFactory.newConstantNullBlock(1))); + Block[] blocks = new Block[1 + inputCount()]; + blocks[0] = groupBuilder.build(); + for (int i = 1; i < blocks.length; i++) { + blocks[i] = blockFactory.newConstantNullBlock(1); + } + List source = List.of(new Page(blocks)); List results = drive(operators, source.iterator(), driverContext); assertThat(results, hasSize(1)); @@ -524,17 +536,25 @@ private void assertNullSome(DriverContext driverContext, List operator List source = new ArrayList<>(inputData.size()); for (Page page : inputData) { LongVector groups = page.getBlock(0).asVector(); - Block values = page.getBlock(1); - Block.Builder copiedValues = values.elementType().newBlockBuilder(page.getPositionCount(), driverContext.blockFactory()); + Block[] values = new Block[inputCount()]; + Block.Builder[] copiedValues = new Block.Builder[inputCount()]; + for (int b = 0; b < values.length; b++) { + values[b] = page.getBlock(1 + b); + copiedValues[b] = values[b].elementType().newBlockBuilder(page.getPositionCount(), driverContext.blockFactory()); + } for (int p = 0; p < page.getPositionCount(); p++) { if (groups.getLong(p) == nullGroup) { - copiedValues.appendNull(); + for (int b = 0; b < values.length; b++) { + copiedValues[b].appendNull(); + } } else { - copiedValues.copyFrom(values, p, p + 1); + for (int b = 0; b < values.length; b++) { + copiedValues[b].copyFrom(values[b], p, p + 1); + } } } Releasables.closeWhileHandlingException(values); - source.add(new Page(groups.asBlock(), copiedValues.build())); + source.add(new Page(groups.asBlock()).appendBlocks(Block.Builder.buildAll(copiedValues))); } List results = drive(operators, source.iterator(), driverContext); @@ -589,31 +609,32 @@ protected Block merge(int blockIndex, Block block) { }; } - protected static IntStream allValueOffsets(Page page, Long group) { - Block groupBlock = page.getBlock(0); - Block valueBlock = page.getBlock(1); + protected static IntStream matchingGroups(Page page, Long group) { + LongBlock groupBlock = page.getBlock(0); return IntStream.range(0, page.getPositionCount()).flatMap(p -> { - if (valueBlock.isNull(p)) { - return IntStream.of(); - } if (group == null) { - if (false == groupBlock.isNull(p)) { - return IntStream.of(); - } - } else { - int groupStart = groupBlock.getFirstValueIndex(p); - int groupEnd = groupStart + groupBlock.getValueCount(p); - boolean matched = false; - for (int i = groupStart; i < groupEnd; i++) { - if (((LongBlock) groupBlock).getLong(i) == group) { - matched = true; - break; - } + if (groupBlock.isNull(p)) { + return IntStream.of(p); } - if (matched == false) { - return IntStream.of(); + return IntStream.of(); + } + int groupStart = groupBlock.getFirstValueIndex(p); + int groupEnd = groupStart + groupBlock.getValueCount(p); + for (int i = groupStart; i < groupEnd; i++) { + if (groupBlock.getLong(i) == group) { + return IntStream.of(p); } } + return IntStream.of(); + }); + } + + protected static IntStream allValueOffsets(Page page, Long group) { + Block valueBlock = page.getBlock(1); + return matchingGroups(page, group).flatMap(p -> { + if (valueBlock.isNull(p)) { + return IntStream.of(); + } int start = valueBlock.getFirstValueIndex(p); int end = start + valueBlock.getValueCount(p); return IntStream.range(start, end); diff --git a/x-pack/plugin/esql/compute/src/test/java/org/elasticsearch/compute/aggregation/LastDoubleByTimestampAggregatorFunctionTests.java b/x-pack/plugin/esql/compute/src/test/java/org/elasticsearch/compute/aggregation/LastDoubleByTimestampAggregatorFunctionTests.java new file mode 100644 index 0000000000000..51c82c9bc165c --- /dev/null +++ b/x-pack/plugin/esql/compute/src/test/java/org/elasticsearch/compute/aggregation/LastDoubleByTimestampAggregatorFunctionTests.java @@ -0,0 +1,71 @@ +/* + * 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.compute.aggregation.FirstLongByTimestampGroupingAggregatorFunctionTests.ExpectedWork; +import org.elasticsearch.compute.data.Block; +import org.elasticsearch.compute.data.BlockFactory; +import org.elasticsearch.compute.data.BlockUtils; +import org.elasticsearch.compute.data.DoubleBlock; +import org.elasticsearch.compute.data.ElementType; +import org.elasticsearch.compute.data.LongBlock; +import org.elasticsearch.compute.data.Page; +import org.elasticsearch.compute.operator.ListRowsBlockSourceOperator; +import org.elasticsearch.compute.operator.SourceOperator; + +import java.util.List; +import java.util.stream.IntStream; + +public class LastDoubleByTimestampAggregatorFunctionTests extends AggregatorFunctionTestCase { + @Override + protected SourceOperator simpleInput(BlockFactory blockFactory, int size) { + return new ListRowsBlockSourceOperator( + blockFactory, + List.of(ElementType.DOUBLE, ElementType.LONG), + IntStream.range(0, size).mapToObj(l -> List.of(randomDouble(), randomLong())).toList() + ); + } + + @Override + protected AggregatorFunctionSupplier aggregatorFunction() { + return new LastDoubleByTimestampAggregatorFunctionSupplier(); + } + + @Override + protected int inputCount() { + return 2; + } + + @Override + protected String expectedDescriptionOfAggregator() { + return "last_double_by_timestamp"; + } + + @Override + public void assertSimpleOutput(List input, Block result) { + ExpectedWork work = new ExpectedWork(false); + for (Page page : input) { + DoubleBlock values = page.getBlock(0); + LongBlock timestamps = page.getBlock(1); + for (int p = 0; p < page.getPositionCount(); p++) { + int tsStart = timestamps.getFirstValueIndex(p); + int tsEnd = tsStart + timestamps.getValueCount(p); + for (int tsOffset = tsStart; tsOffset < tsEnd; tsOffset++) { + long timestamp = timestamps.getLong(tsOffset); + int vStart = values.getFirstValueIndex(p); + int vEnd = vStart + values.getValueCount(p); + for (int vOffset = vStart; vOffset < vEnd; vOffset++) { + double value = values.getDouble(vOffset); + work.add(timestamp, value); + } + } + } + } + work.check(BlockUtils.toJavaObject(result, 0)); + } +} diff --git a/x-pack/plugin/esql/compute/src/test/java/org/elasticsearch/compute/aggregation/LastDoubleByTimestampGroupingAggregatorFunctionTests.java b/x-pack/plugin/esql/compute/src/test/java/org/elasticsearch/compute/aggregation/LastDoubleByTimestampGroupingAggregatorFunctionTests.java new file mode 100644 index 0000000000000..b83244b253a2e --- /dev/null +++ b/x-pack/plugin/esql/compute/src/test/java/org/elasticsearch/compute/aggregation/LastDoubleByTimestampGroupingAggregatorFunctionTests.java @@ -0,0 +1,71 @@ +/* + * 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.compute.aggregation.FirstLongByTimestampGroupingAggregatorFunctionTests.ExpectedWork; +import org.elasticsearch.compute.data.Block; +import org.elasticsearch.compute.data.BlockFactory; +import org.elasticsearch.compute.data.BlockUtils; +import org.elasticsearch.compute.data.DoubleBlock; +import org.elasticsearch.compute.data.ElementType; +import org.elasticsearch.compute.data.LongBlock; +import org.elasticsearch.compute.data.Page; +import org.elasticsearch.compute.operator.ListRowsBlockSourceOperator; +import org.elasticsearch.compute.operator.SourceOperator; + +import java.util.List; +import java.util.stream.IntStream; + +public class LastDoubleByTimestampGroupingAggregatorFunctionTests extends GroupingAggregatorFunctionTestCase { + @Override + protected SourceOperator simpleInput(BlockFactory blockFactory, int size) { + return new ListRowsBlockSourceOperator( + blockFactory, + List.of(ElementType.LONG, ElementType.DOUBLE, ElementType.LONG), + IntStream.range(0, size).mapToObj(l -> List.of(randomLongBetween(0, 4), randomDouble(), randomLong())).toList() + ); + } + + @Override + protected int inputCount() { + return 2; + } + + @Override + protected AggregatorFunctionSupplier aggregatorFunction() { + return new LastDoubleByTimestampAggregatorFunctionSupplier(); + } + + @Override + protected String expectedDescriptionOfAggregator() { + return "last_double_by_timestamp"; + } + + @Override + protected void assertSimpleGroup(List input, Block result, int position, Long group) { + ExpectedWork work = new ExpectedWork(false); + for (Page page : input) { + matchingGroups(page, group).forEach(p -> { + DoubleBlock values = page.getBlock(1); + LongBlock timestamps = page.getBlock(2); + int tsStart = timestamps.getFirstValueIndex(p); + int tsEnd = tsStart + timestamps.getValueCount(p); + for (int tsOffset = tsStart; tsOffset < tsEnd; tsOffset++) { + long timestamp = timestamps.getLong(tsOffset); + int vStart = values.getFirstValueIndex(p); + int vEnd = vStart + values.getValueCount(p); + for (int vOffset = vStart; vOffset < vEnd; vOffset++) { + double value = values.getDouble(vOffset); + work.add(timestamp, value); + } + } + }); + } + work.check(BlockUtils.toJavaObject(result, position)); + } +} diff --git a/x-pack/plugin/esql/compute/src/test/java/org/elasticsearch/compute/aggregation/LastFloatByTimestampAggregatorFunctionTests.java b/x-pack/plugin/esql/compute/src/test/java/org/elasticsearch/compute/aggregation/LastFloatByTimestampAggregatorFunctionTests.java new file mode 100644 index 0000000000000..8dac984842a36 --- /dev/null +++ b/x-pack/plugin/esql/compute/src/test/java/org/elasticsearch/compute/aggregation/LastFloatByTimestampAggregatorFunctionTests.java @@ -0,0 +1,71 @@ +/* + * 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.compute.aggregation.FirstLongByTimestampGroupingAggregatorFunctionTests.ExpectedWork; +import org.elasticsearch.compute.data.Block; +import org.elasticsearch.compute.data.BlockFactory; +import org.elasticsearch.compute.data.BlockUtils; +import org.elasticsearch.compute.data.ElementType; +import org.elasticsearch.compute.data.FloatBlock; +import org.elasticsearch.compute.data.LongBlock; +import org.elasticsearch.compute.data.Page; +import org.elasticsearch.compute.operator.ListRowsBlockSourceOperator; +import org.elasticsearch.compute.operator.SourceOperator; + +import java.util.List; +import java.util.stream.IntStream; + +public class LastFloatByTimestampAggregatorFunctionTests extends AggregatorFunctionTestCase { + @Override + protected SourceOperator simpleInput(BlockFactory blockFactory, int size) { + return new ListRowsBlockSourceOperator( + blockFactory, + List.of(ElementType.FLOAT, ElementType.LONG), + IntStream.range(0, size).mapToObj(l -> List.of(randomInt(), randomLong())).toList() + ); + } + + @Override + protected AggregatorFunctionSupplier aggregatorFunction() { + return new LastFloatByTimestampAggregatorFunctionSupplier(); + } + + @Override + protected int inputCount() { + return 2; + } + + @Override + protected String expectedDescriptionOfAggregator() { + return "last_float_by_timestamp"; + } + + @Override + public void assertSimpleOutput(List input, Block result) { + ExpectedWork work = new ExpectedWork(false); + for (Page page : input) { + FloatBlock values = page.getBlock(0); + LongBlock timestamps = page.getBlock(1); + for (int p = 0; p < page.getPositionCount(); p++) { + int tsStart = timestamps.getFirstValueIndex(p); + int tsEnd = tsStart + timestamps.getValueCount(p); + for (int tsOffset = tsStart; tsOffset < tsEnd; tsOffset++) { + long timestamp = timestamps.getLong(tsOffset); + int vStart = values.getFirstValueIndex(p); + int vEnd = vStart + values.getValueCount(p); + for (int vOffset = vStart; vOffset < vEnd; vOffset++) { + float value = values.getFloat(vOffset); + work.add(timestamp, value); + } + } + } + } + work.check(BlockUtils.toJavaObject(result, 0)); + } +} diff --git a/x-pack/plugin/esql/compute/src/test/java/org/elasticsearch/compute/aggregation/LastFloatByTimestampGroupingAggregatorFunctionTests.java b/x-pack/plugin/esql/compute/src/test/java/org/elasticsearch/compute/aggregation/LastFloatByTimestampGroupingAggregatorFunctionTests.java new file mode 100644 index 0000000000000..7e9e44968e586 --- /dev/null +++ b/x-pack/plugin/esql/compute/src/test/java/org/elasticsearch/compute/aggregation/LastFloatByTimestampGroupingAggregatorFunctionTests.java @@ -0,0 +1,71 @@ +/* + * 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.compute.aggregation.FirstLongByTimestampGroupingAggregatorFunctionTests.ExpectedWork; +import org.elasticsearch.compute.data.Block; +import org.elasticsearch.compute.data.BlockFactory; +import org.elasticsearch.compute.data.BlockUtils; +import org.elasticsearch.compute.data.ElementType; +import org.elasticsearch.compute.data.FloatBlock; +import org.elasticsearch.compute.data.LongBlock; +import org.elasticsearch.compute.data.Page; +import org.elasticsearch.compute.operator.ListRowsBlockSourceOperator; +import org.elasticsearch.compute.operator.SourceOperator; + +import java.util.List; +import java.util.stream.IntStream; + +public class LastFloatByTimestampGroupingAggregatorFunctionTests extends GroupingAggregatorFunctionTestCase { + @Override + protected SourceOperator simpleInput(BlockFactory blockFactory, int size) { + return new ListRowsBlockSourceOperator( + blockFactory, + List.of(ElementType.LONG, ElementType.FLOAT, ElementType.LONG), + IntStream.range(0, size).mapToObj(l -> List.of(randomLongBetween(0, 4), randomFloat(), randomLong())).toList() + ); + } + + @Override + protected int inputCount() { + return 2; + } + + @Override + protected AggregatorFunctionSupplier aggregatorFunction() { + return new LastFloatByTimestampAggregatorFunctionSupplier(); + } + + @Override + protected String expectedDescriptionOfAggregator() { + return "last_float_by_timestamp"; + } + + @Override + protected void assertSimpleGroup(List input, Block result, int position, Long group) { + ExpectedWork work = new ExpectedWork(false); + for (Page page : input) { + matchingGroups(page, group).forEach(p -> { + FloatBlock values = page.getBlock(1); + LongBlock timestamps = page.getBlock(2); + int tsStart = timestamps.getFirstValueIndex(p); + int tsEnd = tsStart + timestamps.getValueCount(p); + for (int tsOffset = tsStart; tsOffset < tsEnd; tsOffset++) { + long timestamp = timestamps.getLong(tsOffset); + int vStart = values.getFirstValueIndex(p); + int vEnd = vStart + values.getValueCount(p); + for (int vOffset = vStart; vOffset < vEnd; vOffset++) { + float value = values.getFloat(vOffset); + work.add(timestamp, value); + } + } + }); + } + work.check(BlockUtils.toJavaObject(result, position)); + } +} diff --git a/x-pack/plugin/esql/compute/src/test/java/org/elasticsearch/compute/aggregation/LastIntByTimestampAggregatorFunctionTests.java b/x-pack/plugin/esql/compute/src/test/java/org/elasticsearch/compute/aggregation/LastIntByTimestampAggregatorFunctionTests.java new file mode 100644 index 0000000000000..52eead78c7fc4 --- /dev/null +++ b/x-pack/plugin/esql/compute/src/test/java/org/elasticsearch/compute/aggregation/LastIntByTimestampAggregatorFunctionTests.java @@ -0,0 +1,71 @@ +/* + * 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.compute.aggregation.FirstLongByTimestampGroupingAggregatorFunctionTests.ExpectedWork; +import org.elasticsearch.compute.data.Block; +import org.elasticsearch.compute.data.BlockFactory; +import org.elasticsearch.compute.data.BlockUtils; +import org.elasticsearch.compute.data.ElementType; +import org.elasticsearch.compute.data.IntBlock; +import org.elasticsearch.compute.data.LongBlock; +import org.elasticsearch.compute.data.Page; +import org.elasticsearch.compute.operator.ListRowsBlockSourceOperator; +import org.elasticsearch.compute.operator.SourceOperator; + +import java.util.List; +import java.util.stream.IntStream; + +public class LastIntByTimestampAggregatorFunctionTests extends AggregatorFunctionTestCase { + @Override + protected SourceOperator simpleInput(BlockFactory blockFactory, int size) { + return new ListRowsBlockSourceOperator( + blockFactory, + List.of(ElementType.INT, ElementType.LONG), + IntStream.range(0, size).mapToObj(l -> List.of(randomInt(), randomLong())).toList() + ); + } + + @Override + protected AggregatorFunctionSupplier aggregatorFunction() { + return new LastIntByTimestampAggregatorFunctionSupplier(); + } + + @Override + protected int inputCount() { + return 2; + } + + @Override + protected String expectedDescriptionOfAggregator() { + return "last_int_by_timestamp"; + } + + @Override + public void assertSimpleOutput(List input, Block result) { + ExpectedWork work = new ExpectedWork(false); + for (Page page : input) { + IntBlock values = page.getBlock(0); + LongBlock timestamps = page.getBlock(1); + for (int p = 0; p < page.getPositionCount(); p++) { + int tsStart = timestamps.getFirstValueIndex(p); + int tsEnd = tsStart + timestamps.getValueCount(p); + for (int tsOffset = tsStart; tsOffset < tsEnd; tsOffset++) { + long timestamp = timestamps.getLong(tsOffset); + int vStart = values.getFirstValueIndex(p); + int vEnd = vStart + values.getValueCount(p); + for (int vOffset = vStart; vOffset < vEnd; vOffset++) { + int value = values.getInt(vOffset); + work.add(timestamp, value); + } + } + } + } + work.check(BlockUtils.toJavaObject(result, 0)); + } +} diff --git a/x-pack/plugin/esql/compute/src/test/java/org/elasticsearch/compute/aggregation/LastIntByTimestampGroupingAggregatorFunctionTests.java b/x-pack/plugin/esql/compute/src/test/java/org/elasticsearch/compute/aggregation/LastIntByTimestampGroupingAggregatorFunctionTests.java new file mode 100644 index 0000000000000..125f9c33c9bff --- /dev/null +++ b/x-pack/plugin/esql/compute/src/test/java/org/elasticsearch/compute/aggregation/LastIntByTimestampGroupingAggregatorFunctionTests.java @@ -0,0 +1,71 @@ +/* + * 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.compute.aggregation.FirstLongByTimestampGroupingAggregatorFunctionTests.ExpectedWork; +import org.elasticsearch.compute.data.Block; +import org.elasticsearch.compute.data.BlockFactory; +import org.elasticsearch.compute.data.BlockUtils; +import org.elasticsearch.compute.data.ElementType; +import org.elasticsearch.compute.data.IntBlock; +import org.elasticsearch.compute.data.LongBlock; +import org.elasticsearch.compute.data.Page; +import org.elasticsearch.compute.operator.ListRowsBlockSourceOperator; +import org.elasticsearch.compute.operator.SourceOperator; + +import java.util.List; +import java.util.stream.IntStream; + +public class LastIntByTimestampGroupingAggregatorFunctionTests extends GroupingAggregatorFunctionTestCase { + @Override + protected SourceOperator simpleInput(BlockFactory blockFactory, int size) { + return new ListRowsBlockSourceOperator( + blockFactory, + List.of(ElementType.LONG, ElementType.INT, ElementType.LONG), + IntStream.range(0, size).mapToObj(l -> List.of(randomLongBetween(0, 4), randomInt(), randomLong())).toList() + ); + } + + @Override + protected int inputCount() { + return 2; + } + + @Override + protected AggregatorFunctionSupplier aggregatorFunction() { + return new LastIntByTimestampAggregatorFunctionSupplier(); + } + + @Override + protected String expectedDescriptionOfAggregator() { + return "last_int_by_timestamp"; + } + + @Override + protected void assertSimpleGroup(List input, Block result, int position, Long group) { + ExpectedWork work = new ExpectedWork(false); + for (Page page : input) { + matchingGroups(page, group).forEach(p -> { + IntBlock values = page.getBlock(1); + LongBlock timestamps = page.getBlock(2); + int tsStart = timestamps.getFirstValueIndex(p); + int tsEnd = tsStart + timestamps.getValueCount(p); + for (int tsOffset = tsStart; tsOffset < tsEnd; tsOffset++) { + long timestamp = timestamps.getLong(tsOffset); + int vStart = values.getFirstValueIndex(p); + int vEnd = vStart + values.getValueCount(p); + for (int vOffset = vStart; vOffset < vEnd; vOffset++) { + int value = values.getInt(vOffset); + work.add(timestamp, value); + } + } + }); + } + work.check(BlockUtils.toJavaObject(result, position)); + } +} diff --git a/x-pack/plugin/esql/compute/src/test/java/org/elasticsearch/compute/aggregation/LastLongByTimestampAggregatorFunctionTests.java b/x-pack/plugin/esql/compute/src/test/java/org/elasticsearch/compute/aggregation/LastLongByTimestampAggregatorFunctionTests.java new file mode 100644 index 0000000000000..3207cb533d0aa --- /dev/null +++ b/x-pack/plugin/esql/compute/src/test/java/org/elasticsearch/compute/aggregation/LastLongByTimestampAggregatorFunctionTests.java @@ -0,0 +1,69 @@ +/* + * 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.compute.aggregation.FirstLongByTimestampGroupingAggregatorFunctionTests.ExpectedWork; +import org.elasticsearch.compute.data.Block; +import org.elasticsearch.compute.data.BlockFactory; +import org.elasticsearch.compute.data.BlockUtils; +import org.elasticsearch.compute.data.LongBlock; +import org.elasticsearch.compute.data.Page; +import org.elasticsearch.compute.operator.SourceOperator; +import org.elasticsearch.compute.operator.TupleLongLongBlockSourceOperator; +import org.elasticsearch.core.Tuple; + +import java.util.List; +import java.util.stream.IntStream; + +public class LastLongByTimestampAggregatorFunctionTests extends AggregatorFunctionTestCase { + @Override + protected SourceOperator simpleInput(BlockFactory blockFactory, int size) { + return new TupleLongLongBlockSourceOperator( + blockFactory, + IntStream.range(0, size).mapToObj(l -> Tuple.tuple(randomLong(), randomLong())) + ); + } + + @Override + protected AggregatorFunctionSupplier aggregatorFunction() { + return new LastLongByTimestampAggregatorFunctionSupplier(); + } + + @Override + protected int inputCount() { + return 2; + } + + @Override + protected String expectedDescriptionOfAggregator() { + return "last_long_by_timestamp"; + } + + @Override + public void assertSimpleOutput(List input, Block result) { + ExpectedWork work = new ExpectedWork(false); + for (Page page : input) { + LongBlock values = page.getBlock(0); + LongBlock timestamps = page.getBlock(1); + for (int p = 0; p < page.getPositionCount(); p++) { + int tsStart = timestamps.getFirstValueIndex(p); + int tsEnd = tsStart + timestamps.getValueCount(p); + for (int tsOffset = tsStart; tsOffset < tsEnd; tsOffset++) { + long timestamp = timestamps.getLong(tsOffset); + int vStart = values.getFirstValueIndex(p); + int vEnd = vStart + values.getValueCount(p); + for (int vOffset = vStart; vOffset < vEnd; vOffset++) { + long value = values.getLong(vOffset); + work.add(timestamp, value); + } + } + } + } + work.check(BlockUtils.toJavaObject(result, 0)); + } +} diff --git a/x-pack/plugin/esql/compute/src/test/java/org/elasticsearch/compute/aggregation/LastLongByTimestampGroupingAggregatorFunctionTests.java b/x-pack/plugin/esql/compute/src/test/java/org/elasticsearch/compute/aggregation/LastLongByTimestampGroupingAggregatorFunctionTests.java new file mode 100644 index 0000000000000..9ae8ecbeede11 --- /dev/null +++ b/x-pack/plugin/esql/compute/src/test/java/org/elasticsearch/compute/aggregation/LastLongByTimestampGroupingAggregatorFunctionTests.java @@ -0,0 +1,109 @@ +/* + * 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.compute.data.Block; +import org.elasticsearch.compute.data.BlockFactory; +import org.elasticsearch.compute.data.BlockUtils; +import org.elasticsearch.compute.data.ElementType; +import org.elasticsearch.compute.data.LongBlock; +import org.elasticsearch.compute.data.Page; +import org.elasticsearch.compute.operator.ListRowsBlockSourceOperator; +import org.elasticsearch.compute.operator.SourceOperator; + +import java.util.HashSet; +import java.util.List; +import java.util.Set; +import java.util.stream.IntStream; + +public class LastLongByTimestampGroupingAggregatorFunctionTests extends GroupingAggregatorFunctionTestCase { + @Override + protected SourceOperator simpleInput(BlockFactory blockFactory, int size) { + return new ListRowsBlockSourceOperator( + blockFactory, + List.of(ElementType.LONG, ElementType.LONG, ElementType.LONG), + IntStream.range(0, size).mapToObj(l -> List.of(randomLongBetween(0, 4), randomLong(), randomLong())).toList() + ); + } + + @Override + protected int inputCount() { + return 2; + } + + @Override + protected AggregatorFunctionSupplier aggregatorFunction() { + return new LastLongByTimestampAggregatorFunctionSupplier(); + } + + @Override + protected String expectedDescriptionOfAggregator() { + return "last_long_by_timestamp"; + } + + @Override + protected void assertSimpleGroup(List input, Block result, int position, Long group) { + ExpectedWork work = new ExpectedWork(false); + for (Page page : input) { + matchingGroups(page, group).forEach(p -> { + LongBlock values = page.getBlock(1); + LongBlock timestamps = page.getBlock(2); + int tsStart = timestamps.getFirstValueIndex(p); + int tsEnd = tsStart + timestamps.getValueCount(p); + for (int tsOffset = tsStart; tsOffset < tsEnd; tsOffset++) { + long timestamp = timestamps.getLong(tsOffset); + int vStart = values.getFirstValueIndex(p); + int vEnd = vStart + values.getValueCount(p); + for (int vOffset = vStart; vOffset < vEnd; vOffset++) { + long value = values.getLong(vOffset); + work.add(timestamp, value); + } + } + }); + } + work.check(BlockUtils.toJavaObject(result, position)); + } + + static class ExpectedWork { + private final Set expected = new HashSet<>(); + private final boolean first; + private long expectedTimestamp = 0; + + ExpectedWork(boolean first) { + this.first = first; + } + + void add(long timestamp, Object value) { + if (expected.isEmpty()) { + expectedTimestamp = timestamp; + expected.add(value); + } else if (first ? timestamp < expectedTimestamp : timestamp > expectedTimestamp) { + expectedTimestamp = timestamp; + expected.clear(); + expected.add(value); + } else if (timestamp == expectedTimestamp) { + expected.add(value); + } + } + + void check(Object v) { + if (expected.isEmpty()) { + if (v != null) { + throw new AssertionError("expected null but was " + v); + } + } else { + if (expected.contains(v) == false) { + String expectedMessage = expected.size() == 1 + ? "expected " + expected.iterator().next() + : "expected one of " + expected.stream().sorted().toList(); + throw new AssertionError(expectedMessage + " but was " + v); + } + } + } + } +} diff --git a/x-pack/plugin/esql/compute/src/test/java/org/elasticsearch/compute/operator/ListRowsBlockSourceOperator.java b/x-pack/plugin/esql/compute/src/test/java/org/elasticsearch/compute/operator/ListRowsBlockSourceOperator.java new file mode 100644 index 0000000000000..d4a0d619aa27e --- /dev/null +++ b/x-pack/plugin/esql/compute/src/test/java/org/elasticsearch/compute/operator/ListRowsBlockSourceOperator.java @@ -0,0 +1,81 @@ +/* + * 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; + +import org.elasticsearch.compute.data.Block; +import org.elasticsearch.compute.data.BlockFactory; +import org.elasticsearch.compute.data.ElementType; +import org.elasticsearch.compute.data.Page; +import org.elasticsearch.compute.test.AbstractBlockSourceOperator; +import org.elasticsearch.compute.test.TestBlockBuilder; +import org.elasticsearch.core.Releasables; + +import java.util.List; + +import static org.elasticsearch.test.ESTestCase.assertThat; +import static org.hamcrest.Matchers.hasSize; + +/** + * A source operator whose output is rows specified as a list {@link List} values. + */ +public class ListRowsBlockSourceOperator extends AbstractBlockSourceOperator { + private static final int DEFAULT_MAX_PAGE_POSITIONS = 8 * 1024; + + private final List types; + private final List> rows; + + public ListRowsBlockSourceOperator(BlockFactory blockFactory, List types, List> rows) { + super(blockFactory, DEFAULT_MAX_PAGE_POSITIONS); + this.types = types; + this.rows = rows; + } + + @Override + protected Page createPage(int positionOffset, int length) { + TestBlockBuilder[] blocks = new TestBlockBuilder[types.size()]; + try { + for (int b = 0; b < blocks.length; b++) { + blocks[b] = TestBlockBuilder.builderOf(blockFactory, types.get(b)); + } + for (int i = 0; i < length; i++) { + List row = rows.get(positionOffset + i); + assertThat(row, hasSize(types.size())); + for (int b = 0; b < blocks.length; b++) { + Object v = row.get(b); + if (v == null) { + blocks[b].appendNull(); + continue; + } + if (v instanceof List l) { + blocks[b].beginPositionEntry(); + for (Object listValue : l) { + blocks[b].appendObject(listValue); + } + blocks[b].endPositionEntry(); + continue; + } + blocks[b].appendObject(v); + } + } + Page page = new Page(Block.Builder.buildAll(blocks)); + currentPosition += page.getPositionCount(); + return page; + } finally { + Releasables.close(blocks); + } + } + + @Override + protected int remaining() { + return rows.size() - currentPosition; + } + + public List elementTypes() { + return types; + } +} diff --git a/x-pack/plugin/esql/compute/test/src/main/java/org/elasticsearch/compute/test/TestBlockBuilder.java b/x-pack/plugin/esql/compute/test/src/main/java/org/elasticsearch/compute/test/TestBlockBuilder.java index b51de1e477ee0..6ec930fec9433 100644 --- a/x-pack/plugin/esql/compute/test/src/main/java/org/elasticsearch/compute/test/TestBlockBuilder.java +++ b/x-pack/plugin/esql/compute/test/src/main/java/org/elasticsearch/compute/test/TestBlockBuilder.java @@ -67,7 +67,7 @@ public static Block blockFromSingleValues(List blockValues, ElementType return builder.build(); } - static TestBlockBuilder builderOf(BlockFactory blockFactory, ElementType type) { + public static TestBlockBuilder builderOf(BlockFactory blockFactory, ElementType type) { return switch (type) { case INT -> new TestIntBlockBuilder(blockFactory, 0); case LONG -> new TestLongBlockBuilder(blockFactory, 0);