-
Notifications
You must be signed in to change notification settings - Fork 25.7k
[ES|QL] Support some stats on aggregate_metric_double #120343
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 19 commits
ae16694
a5be73b
80b317a
a2a6092
9094f62
b3b27aa
5acb5a8
71a05b2
648e0af
83612ec
38659b9
bfe84c1
022eebe
769e924
6dd6e36
5dd5ad9
af0e242
1838a82
335fe3b
5608bce
c417b3c
b5837f3
fba979f
827eaf3
fbdb24d
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,6 @@ | ||
| pr: 120343 | ||
| summary: Support some stats on aggregate_metric_double | ||
| area: "ES|QL" | ||
| type: enhancement | ||
| issues: | ||
| - 110649 |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,157 @@ | ||
| /* | ||
| * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one | ||
| * or more contributor license agreements. Licensed under the Elastic License | ||
| * 2.0; you may not use this file except in compliance with the Elastic License | ||
| * 2.0. | ||
| */ | ||
|
|
||
| package org.elasticsearch.compute.data; | ||
|
|
||
| import org.elasticsearch.core.Releasables; | ||
| import org.elasticsearch.index.mapper.BlockLoader; | ||
|
|
||
| public class AggregateMetricDoubleBlockBuilder extends AbstractBlockBuilder implements BlockLoader.AggregateMetricDoubleBuilder { | ||
|
|
||
| private DoubleBlockBuilder minBuilder; | ||
| private DoubleBlockBuilder maxBuilder; | ||
| private DoubleBlockBuilder sumBuilder; | ||
| private IntBlockBuilder countBuilder; | ||
|
|
||
| public AggregateMetricDoubleBlockBuilder(int estimatedSize, BlockFactory blockFactory) { | ||
| super(blockFactory); | ||
| minBuilder = null; | ||
| maxBuilder = null; | ||
| sumBuilder = null; | ||
| countBuilder = null; | ||
| try { | ||
| minBuilder = new DoubleBlockBuilder(estimatedSize, blockFactory); | ||
| maxBuilder = new DoubleBlockBuilder(estimatedSize, blockFactory); | ||
| sumBuilder = new DoubleBlockBuilder(estimatedSize, blockFactory); | ||
| countBuilder = new IntBlockBuilder(estimatedSize, blockFactory); | ||
| } finally { | ||
| if (countBuilder == null) { | ||
| Releasables.closeWhileHandlingException(minBuilder, maxBuilder, sumBuilder, countBuilder); | ||
| } | ||
| } | ||
| } | ||
|
|
||
| @Override | ||
| protected int valuesLength() { | ||
| throw new UnsupportedOperationException("Not available on aggregate_metric_double"); | ||
| } | ||
|
|
||
| @Override | ||
| protected void growValuesArray(int newSize) { | ||
| throw new UnsupportedOperationException("Not available on aggregate_metric_double"); | ||
| } | ||
|
|
||
| @Override | ||
| protected int elementSize() { | ||
| throw new UnsupportedOperationException("Not available on aggregate_metric_double"); | ||
| } | ||
|
|
||
| @Override | ||
| public Block.Builder copyFrom(Block block, int beginInclusive, int endExclusive) { | ||
| Block minBlock; | ||
| Block maxBlock; | ||
| Block sumBlock; | ||
| Block countBlock; | ||
| if (block.areAllValuesNull()) { | ||
| minBlock = block; | ||
| maxBlock = block; | ||
| sumBlock = block; | ||
| countBlock = block; | ||
| } else { | ||
| CompositeBlock composite = (CompositeBlock) block; | ||
| minBlock = composite.getBlock(Metric.MIN.getIndex()); | ||
| maxBlock = composite.getBlock(Metric.MAX.getIndex()); | ||
| sumBlock = composite.getBlock(Metric.SUM.getIndex()); | ||
| countBlock = composite.getBlock(Metric.COUNT.getIndex()); | ||
| } | ||
| minBuilder.copyFrom(minBlock, beginInclusive, endExclusive); | ||
| maxBuilder.copyFrom(maxBlock, beginInclusive, endExclusive); | ||
| sumBuilder.copyFrom(sumBlock, beginInclusive, endExclusive); | ||
| countBuilder.copyFrom(countBlock, beginInclusive, endExclusive); | ||
| return this; | ||
| } | ||
|
|
||
| @Override | ||
| public AbstractBlockBuilder appendNull() { | ||
| minBuilder.appendNull(); | ||
| maxBuilder.appendNull(); | ||
| sumBuilder.appendNull(); | ||
| countBuilder.appendNull(); | ||
| return this; | ||
| } | ||
|
|
||
| @Override | ||
| public Block.Builder mvOrdering(Block.MvOrdering mvOrdering) { | ||
| minBuilder.mvOrdering(mvOrdering); | ||
| maxBuilder.mvOrdering(mvOrdering); | ||
| sumBuilder.mvOrdering(mvOrdering); | ||
| countBuilder.mvOrdering(mvOrdering); | ||
| return this; | ||
| } | ||
|
|
||
| @Override | ||
| public Block build() { | ||
| Block[] blocks = new Block[4]; | ||
| boolean success = false; | ||
| try { | ||
| finish(); | ||
| blocks[Metric.MIN.getIndex()] = minBuilder.build(); | ||
| blocks[Metric.MAX.getIndex()] = maxBuilder.build(); | ||
| blocks[Metric.SUM.getIndex()] = sumBuilder.build(); | ||
| blocks[Metric.COUNT.getIndex()] = countBuilder.build(); | ||
| CompositeBlock block = new CompositeBlock(blocks); | ||
| success = true; | ||
| return block; | ||
| } finally { | ||
| if (success == false) { | ||
| Releasables.closeExpectNoException(blocks); | ||
| } | ||
| } | ||
| } | ||
|
|
||
| @Override | ||
| protected void extraClose() { | ||
| Releasables.closeExpectNoException(minBuilder, maxBuilder, sumBuilder, countBuilder); | ||
| } | ||
|
|
||
| @Override | ||
| public BlockLoader.DoubleBuilder min() { | ||
| return minBuilder; | ||
| } | ||
|
|
||
| @Override | ||
| public BlockLoader.DoubleBuilder max() { | ||
| return maxBuilder; | ||
| } | ||
|
|
||
| @Override | ||
| public BlockLoader.DoubleBuilder sum() { | ||
| return sumBuilder; | ||
| } | ||
|
|
||
| @Override | ||
| public BlockLoader.IntBuilder count() { | ||
| return countBuilder; | ||
| } | ||
|
|
||
| public enum Metric { | ||
| MIN(0), | ||
| MAX(1), | ||
| SUM(2), | ||
| COUNT(3); | ||
|
|
||
| private final int index; | ||
|
|
||
| Metric(int index) { | ||
| this.index = index; | ||
| } | ||
|
|
||
| public int getIndex() { | ||
| return index; | ||
| } | ||
| } | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,54 @@ | ||
| /* | ||
| * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one | ||
| * or more contributor license agreements. Licensed under the Elastic License | ||
| * 2.0; you may not use this file except in compliance with the Elastic License | ||
| * 2.0. | ||
| */ | ||
|
|
||
| package org.elasticsearch.compute.data; | ||
|
|
||
| import java.util.Objects; | ||
|
|
||
| public class AggregateMetricDoubleLiteral { | ||
|
||
| private final Double min; | ||
| private final Double max; | ||
| private final Double sum; | ||
| private final Integer count; | ||
|
|
||
| public AggregateMetricDoubleLiteral(Double min, Double max, Double sum, Integer count) { | ||
|
||
| this.min = min.isNaN() ? null : min; | ||
| this.max = max.isNaN() ? null : max; | ||
| this.sum = sum.isNaN() ? null : sum; | ||
| this.count = count; | ||
| } | ||
|
|
||
| public Double getMax() { | ||
| return max; | ||
| } | ||
|
|
||
| public Double getMin() { | ||
| return min; | ||
| } | ||
|
|
||
| public Double getSum() { | ||
| return sum; | ||
| } | ||
|
|
||
| public Integer getCount() { | ||
| return count; | ||
| } | ||
limotova marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
|
|
||
| @Override | ||
| public boolean equals(Object obj) { | ||
| if (obj == null || obj.getClass() != this.getClass()) { | ||
| return false; | ||
| } | ||
| var aggMetric = (AggregateMetricDoubleLiteral) obj; | ||
| return min.equals(aggMetric.min) && max.equals(aggMetric.max) && sum.equals(aggMetric.sum) && count.equals(aggMetric.count); | ||
| } | ||
|
|
||
| @Override | ||
| public int hashCode() { | ||
| return Objects.hash(max, min, sum, count); | ||
| } | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -233,6 +233,32 @@ private static Block constantBlock(BlockFactory blockFactory, ElementType type, | |
| case BYTES_REF -> blockFactory.newConstantBytesRefBlockWith(toBytesRef(val), size); | ||
| case DOUBLE -> blockFactory.newConstantDoubleBlockWith((double) val, size); | ||
| case BOOLEAN -> blockFactory.newConstantBooleanBlockWith((boolean) val, size); | ||
| case COMPOSITE -> { | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Hmm, a composite type can be more than aggregated_metric_double? Can we just leave it unsupported here?
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I had to add this to be able to support the unit tests and wasn't really sure of a way to work around it
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. If composite can be more than just
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'm not sure it really needs it's own type. Maybe there's something funny around constants though?
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Maybe we |
||
| try (AggregateMetricDoubleBlockBuilder builder = blockFactory.newAggregateMetricDoubleBlockBuilder(size)) { | ||
| var aggregate_metric_double = (AggregateMetricDoubleLiteral) val; | ||
| if (aggregate_metric_double.getMin() != null) { | ||
| builder.min().appendDouble(aggregate_metric_double.getMin()); | ||
| } else { | ||
| builder.min().appendNull(); | ||
| } | ||
| if (aggregate_metric_double.getMax() != null) { | ||
| builder.max().appendDouble(aggregate_metric_double.getMax()); | ||
| } else { | ||
| builder.max().appendNull(); | ||
| } | ||
| if (aggregate_metric_double.getSum() != null) { | ||
| builder.sum().appendDouble(aggregate_metric_double.getSum()); | ||
| } else { | ||
| builder.sum().appendNull(); | ||
| } | ||
| if (aggregate_metric_double.getCount() != null) { | ||
| builder.count().appendInt(aggregate_metric_double.getCount()); | ||
| } else { | ||
| builder.count().appendNull(); | ||
| } | ||
| yield builder.build(); | ||
| } | ||
| } | ||
| default -> throw new UnsupportedOperationException("unsupported element type [" + type + "]"); | ||
| }; | ||
| } | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Interesting! This is not something in
serverbut we have to add it here for this. Huh. I suppose that's ok.