Skip to content

Commit 6cff9fb

Browse files
committed
Assert no TimeSeriesAggregate is converted, and fix logical optimizer tests
1 parent 187dc92 commit 6cff9fb

File tree

2 files changed

+27
-21
lines changed

2 files changed

+27
-21
lines changed

x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/optimizer/rules/logical/ReplaceTopNAndAggregateWithTopNAggregate.java

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99

1010
import org.elasticsearch.xpack.esql.plan.logical.Aggregate;
1111
import org.elasticsearch.xpack.esql.plan.logical.LogicalPlan;
12+
import org.elasticsearch.xpack.esql.plan.logical.TimeSeriesAggregate;
1213
import org.elasticsearch.xpack.esql.plan.logical.TopN;
1314
import org.elasticsearch.xpack.esql.plan.logical.TopNAggregate;
1415
import org.elasticsearch.xpack.esql.rule.Rule;
@@ -29,8 +30,10 @@ public LogicalPlan apply(LogicalPlan plan) {
2930
}
3031

3132
private LogicalPlan applyRule(TopN topN) {
32-
// TODO: Handle TimeSeriesAggregate
3333
if (topN.child() instanceof Aggregate aggregate) {
34+
// TimeSeriesAggregate shouldn't appear after a TopN when this rule is executed
35+
assert aggregate instanceof TimeSeriesAggregate == false : "TimeSeriesAggregate should not be replaced with TopNAggregate";
36+
3437
return new TopNAggregate(
3538
aggregate.source(),
3639
aggregate.child(),

x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/optimizer/LogicalPlanOptimizerTests.java

Lines changed: 23 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -125,6 +125,7 @@
125125
import org.elasticsearch.xpack.esql.plan.logical.Sample;
126126
import org.elasticsearch.xpack.esql.plan.logical.TimeSeriesAggregate;
127127
import org.elasticsearch.xpack.esql.plan.logical.TopN;
128+
import org.elasticsearch.xpack.esql.plan.logical.TopNAggregate;
128129
import org.elasticsearch.xpack.esql.plan.logical.UnaryPlan;
129130
import org.elasticsearch.xpack.esql.plan.logical.inference.Completion;
130131
import org.elasticsearch.xpack.esql.plan.logical.join.InlineJoin;
@@ -562,9 +563,8 @@ public void testCombineProjectionWithAggregationAndEval() {
562563

563564
/**
564565
* Expects
565-
* TopN[[Order[x{r}#10,ASC,LAST]],1000[INTEGER]]
566-
* \_Aggregate[[languages{f}#16],[MAX(emp_no{f}#13) AS x, languages{f}#16]]
567-
* \_EsRelation[test][_meta_field{f}#19, emp_no{f}#13, first_name{f}#14, ..]
566+
* TopNAggregate[[languages{f}#16],[MAX(emp_no{f}#13) AS x, languages{f}#16], [Order[x{r}#10,ASC,LAST]],1000[INTEGER]]
567+
* \_EsRelation[test][_meta_field{f}#19, emp_no{f}#13, first_name{f}#14, ..]
568568
*/
569569
public void testRemoveOverridesInAggregate() throws Exception {
570570
var plan = plan("""
@@ -573,9 +573,8 @@ public void testRemoveOverridesInAggregate() throws Exception {
573573
| sort x
574574
""");
575575

576-
var topN = as(plan, TopN.class);
577-
var agg = as(topN.child(), Aggregate.class);
578-
var aggregates = agg.aggregates();
576+
var topNAgg = as(plan, TopNAggregate.class);
577+
var aggregates = topNAgg.aggregates();
579578
assertThat(aggregates, hasSize(2));
580579
assertThat(Expressions.names(aggregates), contains("x", "languages"));
581580
var alias = as(aggregates.get(0), Alias.class);
@@ -592,9 +591,8 @@ public void testRemoveOverridesInAggregate() throws Exception {
592591

593592
/**
594593
* Expects
595-
* TopN[[Order[b{r}#10,ASC,LAST]],1000[INTEGER]]
596-
* \_Aggregate[[b{r}#10],[languages{f}#16 AS b]]
597-
* \_EsRelation[test][_meta_field{f}#19, emp_no{f}#13, first_name{f}#14, ..]
594+
* TopNAggregate[[b{r}#10],[languages{f}#16 AS b],[Order[b{r}#10,ASC,LAST]],1000[INTEGER]]
595+
* \_EsRelation[test][_meta_field{f}#19, emp_no{f}#13, first_name{f}#14, ..]
598596
*/
599597
public void testAggsWithOverridingInputAndGrouping() throws Exception {
600598
var plan = plan("""
@@ -603,9 +601,8 @@ public void testAggsWithOverridingInputAndGrouping() throws Exception {
603601
| sort b
604602
""");
605603

606-
var topN = as(plan, TopN.class);
607-
var agg = as(topN.child(), Aggregate.class);
608-
var aggregates = agg.aggregates();
604+
var topNAgg = as(plan, TopNAggregate.class);
605+
var aggregates = topNAgg.aggregates();
609606
assertThat(aggregates, hasSize(1));
610607
assertThat(Expressions.names(aggregates), contains("b"));
611608
assertWarnings(
@@ -6934,24 +6931,30 @@ public void testTranslateMixedAggsWithMathWithoutGrouping() {
69346931
assertThat(add.right().fold(FoldContext.small()), equalTo(0.2));
69356932
}
69366933

6934+
/**
6935+
* TopNAggregate[[cluster{r}#7563],[SUM(sum(rate(network.total_bytes_in)){r}#7574,true[BOOLEAN]) AS sum(rate(network.total_bytes
6936+
* _in))#7560, cluster{r}#7563],[Order[cluster{f}#7563,ASC,LAST]],10[INTEGER]]
6937+
* \_TimeSeriesAggregate[[_tsid{m}#7575],[RATE(network.total_bytes_in{f}#7570,true[BOOLEAN],@timestamp{f}#7562) AS sum(rate(network.tota
6938+
* l_bytes_in))#7574, VALUES(cluster{f}#7563,true[BOOLEAN]) AS cluster#7563],null]
6939+
* \_EsRelation[k8s][TIME_SERIES][@timestamp{f}#7562, client.ip{f}#7566, cluster{f}#7..]
6940+
*/
69376941
public void testTranslateMetricsGroupedByOneDimension() {
69386942
assumeTrue("requires snapshot builds", Build.current().isSnapshot());
69396943
var query = "TS k8s | STATS sum(rate(network.total_bytes_in)) BY cluster | SORT cluster | LIMIT 10";
69406944
var plan = logicalOptimizer.optimize(metricsAnalyzer.analyze(parser.createStatement(query)));
6941-
TopN topN = as(plan, TopN.class);
6942-
Aggregate aggsByCluster = as(topN.child(), Aggregate.class);
6943-
assertThat(aggsByCluster, not(instanceOf(TimeSeriesAggregate.class)));
6944-
assertThat(aggsByCluster.aggregates(), hasSize(2));
6945-
TimeSeriesAggregate aggsByTsid = as(aggsByCluster.child(), TimeSeriesAggregate.class);
6945+
TopNAggregate topNAggsByCluster = as(plan, TopNAggregate.class);
6946+
assertThat(topNAggsByCluster, not(instanceOf(TimeSeriesAggregate.class)));
6947+
assertThat(topNAggsByCluster.aggregates(), hasSize(2));
6948+
TimeSeriesAggregate aggsByTsid = as(topNAggsByCluster.child(), TimeSeriesAggregate.class);
69466949
assertThat(aggsByTsid.aggregates(), hasSize(2)); // _tsid is dropped
69476950
assertNull(aggsByTsid.timeBucket());
69486951
EsRelation relation = as(aggsByTsid.child(), EsRelation.class);
69496952
assertThat(relation.indexMode(), equalTo(IndexMode.TIME_SERIES));
69506953

6951-
Sum sum = as(Alias.unwrap(aggsByCluster.aggregates().get(0)), Sum.class);
6954+
Sum sum = as(Alias.unwrap(topNAggsByCluster.aggregates().get(0)), Sum.class);
69526955
assertThat(Expressions.attribute(sum.field()).id(), equalTo(aggsByTsid.aggregates().get(0).id()));
6953-
assertThat(aggsByCluster.groupings(), hasSize(1));
6954-
assertThat(Expressions.attribute(aggsByCluster.groupings().get(0)).id(), equalTo(aggsByTsid.aggregates().get(1).id()));
6956+
assertThat(topNAggsByCluster.groupings(), hasSize(1));
6957+
assertThat(Expressions.attribute(topNAggsByCluster.groupings().get(0)).id(), equalTo(aggsByTsid.aggregates().get(1).id()));
69556958

69566959
Rate rate = as(Alias.unwrap(aggsByTsid.aggregates().get(0)), Rate.class);
69576960
assertThat(Expressions.attribute(rate.field()).name(), equalTo("network.total_bytes_in"));

0 commit comments

Comments
 (0)