Skip to content

Commit f03d347

Browse files
authored
ESQL: drop RowExec (#117133) (#117343)
Drop `RowExec` physical node: `Row` is now optimised away into a `LocalRelation`, which has its own physical mapping. `Row` is kept around as a container for the logical optimisations/folding of the expressions supported by the `ROW` command (which makes it in fact a source _plus_ `EVAL`), `LocalRelation` only being a container for the schema and end results (it doesn't actually go through transformations). Fixes #104960
1 parent 881b42e commit f03d347

File tree

10 files changed

+38
-293
lines changed

10 files changed

+38
-293
lines changed

x-pack/plugin/esql/compute/src/main/java/org/elasticsearch/compute/operator/RowOperator.java

Lines changed: 0 additions & 47 deletions
This file was deleted.

x-pack/plugin/esql/compute/src/test/java/org/elasticsearch/compute/operator/RowOperatorTests.java

Lines changed: 0 additions & 81 deletions
This file was deleted.

x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/optimizer/LogicalPlanOptimizer.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@
4747
import org.elasticsearch.xpack.esql.optimizer.rules.logical.ReplaceLimitAndSortAsTopN;
4848
import org.elasticsearch.xpack.esql.optimizer.rules.logical.ReplaceOrderByExpressionWithEval;
4949
import org.elasticsearch.xpack.esql.optimizer.rules.logical.ReplaceRegexMatch;
50+
import org.elasticsearch.xpack.esql.optimizer.rules.logical.ReplaceRowAsLocalRelation;
5051
import org.elasticsearch.xpack.esql.optimizer.rules.logical.ReplaceStatsFilteredAggWithEval;
5152
import org.elasticsearch.xpack.esql.optimizer.rules.logical.ReplaceTrivialTypeConversions;
5253
import org.elasticsearch.xpack.esql.optimizer.rules.logical.SetAsOptimized;
@@ -192,6 +193,6 @@ protected static Batch<LogicalPlan> operators() {
192193
}
193194

194195
protected static Batch<LogicalPlan> cleanup() {
195-
return new Batch<>("Clean Up", new ReplaceLimitAndSortAsTopN());
196+
return new Batch<>("Clean Up", new ReplaceLimitAndSortAsTopN(), new ReplaceRowAsLocalRelation());
196197
}
197198
}
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
/*
2+
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
3+
* or more contributor license agreements. Licensed under the Elastic License
4+
* 2.0; you may not use this file except in compliance with the Elastic License
5+
* 2.0.
6+
*/
7+
8+
package org.elasticsearch.xpack.esql.optimizer.rules.logical;
9+
10+
import org.elasticsearch.compute.data.BlockUtils;
11+
import org.elasticsearch.xpack.esql.plan.logical.LogicalPlan;
12+
import org.elasticsearch.xpack.esql.plan.logical.Row;
13+
import org.elasticsearch.xpack.esql.plan.logical.local.LocalRelation;
14+
import org.elasticsearch.xpack.esql.plan.logical.local.LocalSupplier;
15+
import org.elasticsearch.xpack.esql.planner.PlannerUtils;
16+
17+
import java.util.ArrayList;
18+
import java.util.List;
19+
20+
public final class ReplaceRowAsLocalRelation extends OptimizerRules.OptimizerRule<Row> {
21+
22+
@Override
23+
protected LogicalPlan rule(Row row) {
24+
var fields = row.fields();
25+
List<Object> values = new ArrayList<>(fields.size());
26+
fields.forEach(f -> values.add(f.child().fold()));
27+
var blocks = BlockUtils.fromListRow(PlannerUtils.NON_BREAKING_BLOCK_FACTORY, values);
28+
return new LocalRelation(row.source(), row.output(), LocalSupplier.of(blocks));
29+
}
30+
}

x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/plan/PlanWritables.java

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,6 @@
4545
import org.elasticsearch.xpack.esql.plan.physical.MvExpandExec;
4646
import org.elasticsearch.xpack.esql.plan.physical.OrderExec;
4747
import org.elasticsearch.xpack.esql.plan.physical.ProjectExec;
48-
import org.elasticsearch.xpack.esql.plan.physical.RowExec;
4948
import org.elasticsearch.xpack.esql.plan.physical.ShowExec;
5049
import org.elasticsearch.xpack.esql.plan.physical.SubqueryExec;
5150
import org.elasticsearch.xpack.esql.plan.physical.TopNExec;
@@ -106,7 +105,6 @@ public static List<NamedWriteableRegistry.Entry> phsyical() {
106105
MvExpandExec.ENTRY,
107106
OrderExec.ENTRY,
108107
ProjectExec.ENTRY,
109-
RowExec.ENTRY,
110108
ShowExec.ENTRY,
111109
SubqueryExec.ENTRY,
112110
TopNExec.ENTRY

x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/plan/physical/RowExec.java

Lines changed: 0 additions & 75 deletions
This file was deleted.

x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/planner/LocalExecutionPlanner.java

Lines changed: 0 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,6 @@
3131
import org.elasticsearch.compute.operator.Operator.OperatorFactory;
3232
import org.elasticsearch.compute.operator.OutputOperator.OutputOperatorFactory;
3333
import org.elasticsearch.compute.operator.RowInTableLookupOperator;
34-
import org.elasticsearch.compute.operator.RowOperator.RowOperatorFactory;
3534
import org.elasticsearch.compute.operator.ShowOperator;
3635
import org.elasticsearch.compute.operator.SinkOperator;
3736
import org.elasticsearch.compute.operator.SinkOperator.SinkOperatorFactory;
@@ -89,7 +88,6 @@
8988
import org.elasticsearch.xpack.esql.plan.physical.OutputExec;
9089
import org.elasticsearch.xpack.esql.plan.physical.PhysicalPlan;
9190
import org.elasticsearch.xpack.esql.plan.physical.ProjectExec;
92-
import org.elasticsearch.xpack.esql.plan.physical.RowExec;
9391
import org.elasticsearch.xpack.esql.plan.physical.ShowExec;
9492
import org.elasticsearch.xpack.esql.plan.physical.TopNExec;
9593
import org.elasticsearch.xpack.esql.plugin.QueryPragmas;
@@ -220,8 +218,6 @@ else if (node instanceof EsQueryExec esQuery) {
220218
return planEsQueryNode(esQuery, context);
221219
} else if (node instanceof EsStatsQueryExec statsQuery) {
222220
return planEsStats(statsQuery, context);
223-
} else if (node instanceof RowExec row) {
224-
return planRow(row, context);
225221
} else if (node instanceof LocalSourceExec localSource) {
226222
return planLocal(localSource, context);
227223
} else if (node instanceof ShowExec show) {
@@ -620,13 +616,6 @@ private ExpressionEvaluator.Factory toEvaluator(Expression exp, Layout layout) {
620616
return EvalMapper.toEvaluator(exp, layout);
621617
}
622618

623-
private PhysicalOperation planRow(RowExec row, LocalExecutionPlannerContext context) {
624-
List<Object> obj = row.fields().stream().map(f -> f.child().fold()).toList();
625-
Layout.Builder layout = new Layout.Builder();
626-
layout.append(row.output());
627-
return PhysicalOperation.fromSource(new RowOperatorFactory(obj), layout.build());
628-
}
629-
630619
private PhysicalOperation planLocal(LocalSourceExec localSourceExec, LocalExecutionPlannerContext context) {
631620
Layout.Builder layout = new Layout.Builder();
632621
layout.append(localSourceExec.output());

x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/planner/mapper/MapperUtils.java

Lines changed: 0 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -9,10 +9,7 @@
99

1010
import org.elasticsearch.common.lucene.BytesRefs;
1111
import org.elasticsearch.compute.aggregation.AggregatorMode;
12-
import org.elasticsearch.compute.data.Block;
13-
import org.elasticsearch.compute.data.BlockUtils;
1412
import org.elasticsearch.xpack.esql.EsqlIllegalArgumentException;
15-
import org.elasticsearch.xpack.esql.core.expression.Alias;
1613
import org.elasticsearch.xpack.esql.core.expression.Attribute;
1714
import org.elasticsearch.xpack.esql.core.expression.Literal;
1815
import org.elasticsearch.xpack.esql.core.tree.Source;
@@ -27,10 +24,8 @@
2724
import org.elasticsearch.xpack.esql.plan.logical.LogicalPlan;
2825
import org.elasticsearch.xpack.esql.plan.logical.MvExpand;
2926
import org.elasticsearch.xpack.esql.plan.logical.Project;
30-
import org.elasticsearch.xpack.esql.plan.logical.Row;
3127
import org.elasticsearch.xpack.esql.plan.logical.UnaryPlan;
3228
import org.elasticsearch.xpack.esql.plan.logical.local.LocalRelation;
33-
import org.elasticsearch.xpack.esql.plan.logical.local.LocalSupplier;
3429
import org.elasticsearch.xpack.esql.plan.logical.show.ShowInfo;
3530
import org.elasticsearch.xpack.esql.plan.physical.AggregateExec;
3631
import org.elasticsearch.xpack.esql.plan.physical.DissectExec;
@@ -45,9 +40,7 @@
4540
import org.elasticsearch.xpack.esql.plan.physical.ProjectExec;
4641
import org.elasticsearch.xpack.esql.plan.physical.ShowExec;
4742
import org.elasticsearch.xpack.esql.planner.AbstractPhysicalOperationProviders;
48-
import org.elasticsearch.xpack.esql.planner.PlannerUtils;
4943

50-
import java.util.ArrayList;
5144
import java.util.List;
5245

5346
/**
@@ -57,18 +50,6 @@ class MapperUtils {
5750
private MapperUtils() {}
5851

5952
static PhysicalPlan mapLeaf(LeafPlan p) {
60-
if (p instanceof Row row) {
61-
// return new RowExec(row.source(), row.fields());
62-
// convert row into local relation
63-
List<Alias> fields = row.fields();
64-
List<Object> values = new ArrayList<>(fields.size());
65-
for (Alias field : fields) {
66-
values.add(field.child().fold());
67-
}
68-
Block[] blocks = BlockUtils.fromListRow(PlannerUtils.NON_BREAKING_BLOCK_FACTORY, values);
69-
p = new LocalRelation(row.source(), row.output(), LocalSupplier.of(blocks));
70-
}
71-
7253
if (p instanceof LocalRelation local) {
7354
return new LocalSourceExec(local.source(), local.output(), local.supplier());
7455
}

0 commit comments

Comments
 (0)