Skip to content

Commit f244912

Browse files
authored
[8.19] [ES|QL] Support avg on aggregate metric double (#130421) (#130499)
Other major aggregations (min, max, sum, count) are available but avg was not. This commit adds it in.
1 parent 7379ad5 commit f244912

File tree

7 files changed

+64
-12
lines changed

7 files changed

+64
-12
lines changed

docs/changelog/130421.yaml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
pr: 130421
2+
summary: Support avg on aggregate metric double
3+
area: ES|QL
4+
type: bug
5+
issues: []

x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/action/EsqlCapabilities.java

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -999,7 +999,12 @@ public enum Cap {
999999
*
10001000
* https://github.com/elastic/elasticsearch/issues/129322
10011001
*/
1002-
NO_PLAIN_STRINGS_IN_LITERALS;
1002+
NO_PLAIN_STRINGS_IN_LITERALS,
1003+
1004+
/**
1005+
* Support avg with aggregate metric doubles
1006+
*/
1007+
AGGREGATE_METRIC_DOUBLE_AVG(AGGREGATE_METRIC_DOUBLE_FEATURE_FLAG);
10031008

10041009
private final boolean enabled;
10051010

x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/aggregate/Avg.java

Lines changed: 18 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727
import static java.util.Collections.emptyList;
2828
import static org.elasticsearch.xpack.esql.core.expression.TypeResolutions.ParamOrdinal.DEFAULT;
2929
import static org.elasticsearch.xpack.esql.core.expression.TypeResolutions.isType;
30+
import static org.elasticsearch.xpack.esql.core.type.DataType.AGGREGATE_METRIC_DOUBLE;
3031

3132
public class Avg extends AggregateFunction implements SurrogateExpression {
3233
public static final NamedWriteableRegistry.Entry ENTRY = new NamedWriteableRegistry.Entry(Expression.class, "Avg", Avg::new);
@@ -45,7 +46,14 @@ public class Avg extends AggregateFunction implements SurrogateExpression {
4546
tag = "docsStatsAvgNestedExpression"
4647
) }
4748
)
48-
public Avg(Source source, @Param(name = "number", type = { "double", "integer", "long" }) Expression field) {
49+
public Avg(
50+
Source source,
51+
@Param(
52+
name = "number",
53+
type = { "aggregate_metric_double", "double", "integer", "long" },
54+
description = "Expression that outputs values to average."
55+
) Expression field
56+
) {
4957
this(source, field, Literal.TRUE);
5058
}
5159

@@ -57,10 +65,10 @@ public Avg(Source source, Expression field, Expression filter) {
5765
protected Expression.TypeResolution resolveType() {
5866
return isType(
5967
field(),
60-
dt -> dt.isNumeric() && dt != DataType.UNSIGNED_LONG,
68+
dt -> dt.isNumeric() && dt != DataType.UNSIGNED_LONG || dt == AGGREGATE_METRIC_DOUBLE,
6169
sourceText(),
6270
DEFAULT,
63-
"numeric except unsigned_long or counter types"
71+
"aggregate_metric_double or numeric except unsigned_long or counter types"
6472
);
6573
}
6674

@@ -97,9 +105,12 @@ public Avg withFilter(Expression filter) {
97105
public Expression surrogate() {
98106
var s = source();
99107
var field = field();
100-
101-
return field().foldable()
102-
? new MvAvg(s, field)
103-
: new Div(s, new Sum(s, field, filter()), new Count(s, field, filter()), dataType());
108+
if (field.foldable()) {
109+
return new MvAvg(s, field);
110+
}
111+
if (field.dataType() == AGGREGATE_METRIC_DOUBLE) {
112+
return new Div(s, new Sum(s, field, filter()).surrogate(), new Count(s, field, filter()).surrogate());
113+
}
114+
return new Div(s, new Sum(s, field, filter()), new Count(s, field, filter()), dataType());
104115
}
105116
}

x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/analysis/AnalyzerTests.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2000,7 +2000,7 @@ public void testUnsupportedTypesInStats() {
20002000
| stats avg(x), count_distinct(x), max(x), median(x), median_absolute_deviation(x), min(x), percentile(x, 10), sum(x)
20012001
""", """
20022002
Found 8 problems
2003-
line 2:12: argument of [avg(x)] must be [numeric except unsigned_long or counter types],\
2003+
line 2:12: argument of [avg(x)] must be [aggregate_metric_double or numeric except unsigned_long or counter types],\
20042004
found value [x] type [unsigned_long]
20052005
line 2:20: argument of [count_distinct(x)] must be [any exact type except unsigned_long, _source, or counter types],\
20062006
found value [x] type [unsigned_long]
@@ -2022,7 +2022,7 @@ public void testUnsupportedTypesInStats() {
20222022
| stats avg(x), median(x), median_absolute_deviation(x), percentile(x, 10), sum(x)
20232023
""", """
20242024
Found 5 problems
2025-
line 2:10: argument of [avg(x)] must be [numeric except unsigned_long or counter types],\
2025+
line 2:10: argument of [avg(x)] must be [aggregate_metric_double or numeric except unsigned_long or counter types],\
20262026
found value [x] type [version]
20272027
line 2:18: argument of [median(x)] must be [numeric except unsigned_long or counter types],\
20282028
found value [x] type [version]

x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/analysis/VerifierTests.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -358,7 +358,7 @@ public void testAggsExpressionsInStatsAggs() {
358358
error("from test | stats max(max(salary)) by first_name")
359359
);
360360
assertEquals(
361-
"1:25: argument of [avg(first_name)] must be [numeric except unsigned_long or counter types],"
361+
"1:25: argument of [avg(first_name)] must be [aggregate_metric_double or numeric except unsigned_long or counter types],"
362362
+ " found value [first_name] type [keyword]",
363363
error("from test | stats count(avg(first_name)) by first_name")
364364
);

x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/aggregate/AvgErrorTests.java

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,13 @@ protected Expression build(Source source, List<Expression> args) {
3232

3333
@Override
3434
protected Matcher<String> expectedTypeErrorMatcher(List<Set<DataType>> validPerPosition, List<DataType> signature) {
35-
return equalTo(typeErrorMessage(false, validPerPosition, signature, (v, p) -> "numeric except unsigned_long or counter types"));
35+
return equalTo(
36+
typeErrorMessage(
37+
false,
38+
validPerPosition,
39+
signature,
40+
(v, p) -> "aggregate_metric_double or numeric except unsigned_long or counter types"
41+
)
42+
);
3643
}
3744
}

x-pack/plugin/src/yamlRestTest/resources/rest-api-spec/test/esql/40_tsdb.yml

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -709,3 +709,27 @@ to_aggregate_metric_double with multi_values:
709709
- match: {values.0.1: '{"min":102.44400024414062,"max":195.10000610351562,"sum":297.54400634765625,"value_count":2}'}
710710
- match: {values.0.2: '{"min":64.0,"max":1456.0,"sum":2139.0,"value_count":4}'}
711711
- match: {values.0.3: '{"min":123.0,"max":1.9418924E7,"sum":1.9433032E7,"value_count":3}'}
712+
713+
---
714+
avg of aggregate_metric_double:
715+
- requires:
716+
test_runner_features: [capabilities]
717+
capabilities:
718+
- method: POST
719+
path: /_query
720+
parameters: []
721+
capabilities: [aggregate_metric_double_avg]
722+
reason: "support avg aggregations with aggregate metric double"
723+
724+
- do:
725+
allowed_warnings_regex:
726+
- "No limit defined, adding default limit of \\[.*\\]"
727+
esql.query:
728+
body:
729+
query: 'FROM test2 | STATS avg = avg(agg_metric) | KEEP avg'
730+
731+
- length: {values: 1}
732+
- length: {values.0: 1}
733+
- match: {columns.0.name: "avg"}
734+
- match: {columns.0.type: "double"}
735+
- match: {values.0.0: 4.904761904761905}

0 commit comments

Comments
 (0)