|
14 | 14 | import org.elasticsearch.xpack.esql.core.expression.Alias; |
15 | 15 | import org.elasticsearch.xpack.esql.core.expression.Expression; |
16 | 16 | import org.elasticsearch.xpack.esql.core.expression.FieldAttribute; |
| 17 | +import org.elasticsearch.xpack.esql.core.expression.Literal; |
17 | 18 | import org.elasticsearch.xpack.esql.core.expression.NamedExpression; |
18 | 19 | import org.elasticsearch.xpack.esql.core.tree.NodeInfo; |
19 | 20 | import org.elasticsearch.xpack.esql.core.tree.Source; |
| 21 | +import org.elasticsearch.xpack.esql.core.type.DataType; |
20 | 22 | import org.elasticsearch.xpack.esql.expression.function.aggregate.AggregateFunction; |
21 | 23 | import org.elasticsearch.xpack.esql.expression.function.aggregate.Count; |
| 24 | +import org.elasticsearch.xpack.esql.expression.function.aggregate.LastOverTime; |
22 | 25 | import org.elasticsearch.xpack.esql.expression.function.aggregate.TimeSeriesAggregateFunction; |
23 | 26 | import org.elasticsearch.xpack.esql.expression.function.grouping.Bucket; |
24 | 27 | import org.elasticsearch.xpack.esql.plan.logical.join.LookupJoin; |
@@ -202,21 +205,23 @@ protected void checkTimeSeriesAggregates(Failures failures) { |
202 | 205 | failures.add( |
203 | 206 | fail(count, "count_star [{}] can't be used with TS command; use count on a field instead", outer.sourceText()) |
204 | 207 | ); |
205 | | - } |
206 | | - outer.forEachDown(FieldAttribute.class, fa -> { |
207 | | - if (fa.isDimension()) { |
| 208 | + // reject COUNT(keyword), but allow COUNT(numeric) |
| 209 | + } else if (outer instanceof TimeSeriesAggregateFunction == false && outer.field() instanceof AggregateFunction == false) { |
| 210 | + Expression field = outer.field(); |
| 211 | + var lastOverTime = new LastOverTime(source(), field, new Literal(source(), null, DataType.DATETIME)); |
| 212 | + if (lastOverTime.typeResolved() != Expression.TypeResolution.TYPE_RESOLVED) { |
208 | 213 | failures.add( |
209 | 214 | fail( |
210 | 215 | this, |
211 | | - "cannot use dimension field [{}] in a time-series aggregation function [{}]. " |
212 | | - + "Dimension fields can only be used for grouping in a BY clause. To aggregate " |
213 | | - + "dimension fields, use the FROM command instead of the TS command.", |
214 | | - fa.sourceText(), |
215 | | - outer.sourceText() |
| 216 | + "implicit time-series aggregation function [{}] generated from [{}] doesn't support type [{}], " |
| 217 | + + "only numeric types are supported; use the FROM command instead of the TS command", |
| 218 | + outer.sourceText().replace(field.sourceText(), "last_over_time(" + field.sourceText() + ")"), |
| 219 | + outer.sourceText(), |
| 220 | + field.dataType().typeName() |
216 | 221 | ) |
217 | 222 | ); |
218 | 223 | } |
219 | | - }); |
| 224 | + } |
220 | 225 | if (outer instanceof TimeSeriesAggregateFunction ts) { |
221 | 226 | outer.field() |
222 | 227 | .forEachDown( |
|
0 commit comments