diff --git a/docs/reference/query-languages/esql/kibana/definition/inline_cast.json b/docs/reference/query-languages/esql/kibana/definition/inline_cast.json
index 7b76b37367f44..e16d6a6ab5991 100644
--- a/docs/reference/query-languages/esql/kibana/definition/inline_cast.json
+++ b/docs/reference/query-languages/esql/kibana/definition/inline_cast.json
@@ -7,6 +7,7 @@
"date" : "to_datetime",
"date_nanos" : "to_date_nanos",
"date_period" : "to_dateperiod",
+ "date_range" : "to_date_range",
"datetime" : "to_datetime",
"dense_vector" : "to_dense_vector",
"double" : "to_double",
diff --git a/x-pack/plugin/esql/compute/gen/build.gradle b/x-pack/plugin/esql/compute/gen/build.gradle
index c9f2e8c3632bf..0e7a32a628d77 100644
--- a/x-pack/plugin/esql/compute/gen/build.gradle
+++ b/x-pack/plugin/esql/compute/gen/build.gradle
@@ -2,6 +2,7 @@ apply plugin: 'elasticsearch.build'
dependencies {
api project(':x-pack:plugin:esql:compute:ann')
+ implementation project(':libs:core')
api 'com.squareup:javapoet:1.13.0'
}
diff --git a/x-pack/plugin/esql/compute/gen/src/main/java/module-info.java b/x-pack/plugin/esql/compute/gen/src/main/java/module-info.java
index 3e4dbac0d3c96..468bab3df1791 100644
--- a/x-pack/plugin/esql/compute/gen/src/main/java/module-info.java
+++ b/x-pack/plugin/esql/compute/gen/src/main/java/module-info.java
@@ -13,6 +13,7 @@
requires com.squareup.javapoet;
requires org.elasticsearch.compute.ann;
requires java.compiler;
+ requires org.elasticsearch.base;
exports org.elasticsearch.compute.gen;
exports org.elasticsearch.compute.gen.argument;
diff --git a/x-pack/plugin/esql/compute/gen/src/main/java/org/elasticsearch/compute/gen/MarkerAnnotationProcessor.java b/x-pack/plugin/esql/compute/gen/src/main/java/org/elasticsearch/compute/gen/MarkerAnnotationProcessor.java
new file mode 100644
index 0000000000000..181ad5e5be5da
--- /dev/null
+++ b/x-pack/plugin/esql/compute/gen/src/main/java/org/elasticsearch/compute/gen/MarkerAnnotationProcessor.java
@@ -0,0 +1,67 @@
+/*
+ * 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.gen;
+
+import org.elasticsearch.core.UpdateForV10;
+
+import java.util.Set;
+
+import javax.annotation.processing.Completion;
+import javax.annotation.processing.ProcessingEnvironment;
+import javax.annotation.processing.Processor;
+import javax.annotation.processing.RoundEnvironment;
+import javax.lang.model.SourceVersion;
+import javax.lang.model.element.AnnotationMirror;
+import javax.lang.model.element.Element;
+import javax.lang.model.element.ExecutableElement;
+import javax.lang.model.element.TypeElement;
+
+/**
+ * A no-op annotation processor that claims marker annotations like {@code @UpdateForV10}.
+ *
+ * These annotations are documentation-only markers (with {@code @Retention(SOURCE)}) used to
+ * track code that needs cleanup in future versions. Since the ESQL module uses annotation
+ * processors for code generation, the compiler warns about unclaimed annotations. This
+ * processor claims them to suppress those warnings.
+ */
+public class MarkerAnnotationProcessor implements Processor {
+
+ @Override
+ public Set getSupportedOptions() {
+ return Set.of();
+ }
+
+ @Override
+ public Set getSupportedAnnotationTypes() {
+ // Marker annotations that are documentation-only and don't require processing.
+ return Set.of(UpdateForV10.class.getCanonicalName());
+ }
+
+ @Override
+ public SourceVersion getSupportedSourceVersion() {
+ return SourceVersion.RELEASE_21;
+ }
+
+ @Override
+ public void init(ProcessingEnvironment processingEnvironment) {}
+
+ @Override
+ public Iterable extends Completion> getCompletions(
+ Element element,
+ AnnotationMirror annotationMirror,
+ ExecutableElement executableElement,
+ String s
+ ) {
+ return Set.of();
+ }
+
+ @Override
+ public boolean process(Set extends TypeElement> annotations, RoundEnvironment roundEnvironment) {
+ return true;
+ }
+}
diff --git a/x-pack/plugin/esql/compute/gen/src/main/resources/META-INF/services/javax.annotation.processing.Processor b/x-pack/plugin/esql/compute/gen/src/main/resources/META-INF/services/javax.annotation.processing.Processor
index 51700a418a02b..769712450ff51 100644
--- a/x-pack/plugin/esql/compute/gen/src/main/resources/META-INF/services/javax.annotation.processing.Processor
+++ b/x-pack/plugin/esql/compute/gen/src/main/resources/META-INF/services/javax.annotation.processing.Processor
@@ -1,3 +1,4 @@
org.elasticsearch.compute.gen.AggregatorProcessor
org.elasticsearch.compute.gen.ConsumeProcessor
org.elasticsearch.compute.gen.EvaluatorProcessor
+org.elasticsearch.compute.gen.MarkerAnnotationProcessor
diff --git a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/analysis/Analyzer.java b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/analysis/Analyzer.java
index 412d80593c215..2b90e8597c9c2 100644
--- a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/analysis/Analyzer.java
+++ b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/analysis/Analyzer.java
@@ -143,7 +143,6 @@
import org.elasticsearch.xpack.esql.plan.logical.join.JoinType;
import org.elasticsearch.xpack.esql.plan.logical.join.JoinTypes;
import org.elasticsearch.xpack.esql.plan.logical.join.LookupJoin;
-import org.elasticsearch.xpack.esql.plan.logical.local.EsqlProject;
import org.elasticsearch.xpack.esql.plan.logical.local.LocalRelation;
import org.elasticsearch.xpack.esql.plan.logical.local.LocalSupplier;
import org.elasticsearch.xpack.esql.plan.logical.promql.PromqlCommand;
@@ -908,7 +907,7 @@ private LogicalPlan resolveFork(Fork fork, AnalyzerContext context) {
}
List subPlanColumns = logicalPlan.output().stream().map(Attribute::name).toList();
- // We need to add an explicit EsqlProject to align the outputs.
+ // We need to add an explicit Project to align the outputs.
if (logicalPlan instanceof Project == false || subPlanColumns.equals(forkColumns) == false) {
changed = true;
List newOutput = new ArrayList<>();
@@ -1264,7 +1263,7 @@ private LogicalPlan resolveKeep(Project p, List childOutput) {
resolvedProjections = new ArrayList<>(priorities.keySet());
}
- return new EsqlProject(p.source(), p.child(), resolvedProjections);
+ return new Project(p.source(), p.child(), resolvedProjections);
}
private LogicalPlan resolveDrop(Drop drop, List childOutput) {
@@ -1294,13 +1293,13 @@ private LogicalPlan resolveDrop(Drop drop, List childOutput) {
});
}
- return new EsqlProject(drop.source(), drop.child(), resolvedProjections);
+ return new Project(drop.source(), drop.child(), resolvedProjections);
}
private LogicalPlan resolveRename(Rename rename, List childrenOutput) {
List projections = projectionsForRename(rename, childrenOutput, log);
- return new EsqlProject(rename.source(), rename.child(), projections);
+ return new Project(rename.source(), rename.child(), projections);
}
/**
@@ -2591,12 +2590,12 @@ private static Map> collectConvertFunctions
* Push down the conversion functions into the child plan by adding an Eval with the new aliases on top of the child plan.
*/
private static LogicalPlan maybePushDownConvertFunctionsToChild(LogicalPlan child, List aliases, List output) {
- // Fork/UnionAll adds an EsqlProject on top of each child plan during resolveFork, check this pattern before pushing down
+ // Fork/UnionAll adds an Project on top of each child plan during resolveFork, check this pattern before pushing down
// If the pattern doesn't match, something unexpected happened, just return the child as is
- if (aliases.isEmpty() == false && child instanceof EsqlProject esqlProject) {
- LogicalPlan childOfProject = esqlProject.child();
+ if (aliases.isEmpty() == false && child instanceof Project project) {
+ LogicalPlan childOfProject = project.child();
Eval eval = new Eval(childOfProject.source(), childOfProject, aliases);
- return new EsqlProject(esqlProject.source(), eval, output);
+ return new Project(project.source(), eval, output);
}
return child;
}
@@ -2736,7 +2735,7 @@ private static LogicalPlan implicitCastingUnionAllOutput(
outputChanged = true;
}
}
- // create a new eval for the casting expressions, and push it down under the EsqlProject
+ // create a new eval for the casting expressions, and push it down under the Project
newChildren.add(maybePushDownConvertFunctionsToChild(child, newAliases, newChildOutput));
}
diff --git a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/analysis/Verifier.java b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/analysis/Verifier.java
index 2816b3fe89cc3..81c4c46ee878c 100644
--- a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/analysis/Verifier.java
+++ b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/analysis/Verifier.java
@@ -114,6 +114,7 @@ Collection verify(LogicalPlan plan, BitSet partialMetrics) {
checkOperationsOnUnsignedLong(p, failures);
checkBinaryComparison(p, failures);
+ checkUnsupportedAttributeRenaming(p, failures);
checkInsist(p, failures);
checkLimitBeforeInlineStats(p, failures);
});
@@ -152,14 +153,10 @@ else if (p.resolved()) {
}
e.forEachUp(ae -> {
- // Special handling for Project and unsupported/union types: disallow renaming them but pass them through otherwise.
- if (p instanceof Project || p instanceof Insist) {
- if (ae instanceof Alias as && as.child() instanceof UnsupportedAttribute ua) {
- failures.add(fail(ae, ua.unresolvedMessage()));
- }
- if (ae instanceof UnsupportedAttribute) {
- return;
- }
+ // UnsupportedAttribute can pass through Project/Insist unchanged.
+ // Renaming is checked separately in #checkUnsupportedAttributeRenaming.
+ if ((p instanceof Project || p instanceof Insist) && ae instanceof UnsupportedAttribute) {
+ return;
}
// Do not fail multiple times in case the children are already unresolved.
@@ -275,6 +272,22 @@ private static void checkInsist(LogicalPlan p, Failures failures) {
}
}
+ /**
+ * Check that UnsupportedAttribute is not renamed via Alias in Project or Insist.
+ * UnsupportedAttribute can pass through these plans unchanged, but renaming is not allowed.
+ * This check runs unconditionally (not gated by {@link LogicalPlan#resolved()}) because
+ * {@link Project#expressionsResolved()} treats UnsupportedAttribute as resolved to allow pass-through.
+ */
+ private static void checkUnsupportedAttributeRenaming(LogicalPlan p, Failures failures) {
+ if (p instanceof Project || p instanceof Insist) {
+ p.forEachExpression(Alias.class, alias -> {
+ if (alias.child() instanceof UnsupportedAttribute ua) {
+ failures.add(fail(alias, ua.unresolvedMessage()));
+ }
+ });
+ }
+ }
+
/*
* This is a rudimentary check to prevent INLINE STATS after LIMIT. A LIMIT command can be added by other commands by default,
* the best example being FORK. A more robust solution would be to track the commands that add LIMIT and prevent them from doing so
diff --git a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/optimizer/rules/logical/PushDownFilterAndLimitIntoUnionAll.java b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/optimizer/rules/logical/PushDownFilterAndLimitIntoUnionAll.java
index b598e283cc1d6..76e329531cc15 100644
--- a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/optimizer/rules/logical/PushDownFilterAndLimitIntoUnionAll.java
+++ b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/optimizer/rules/logical/PushDownFilterAndLimitIntoUnionAll.java
@@ -40,23 +40,23 @@
* to {@code Limit} optimization can be applied.
*
* This rule applies for certain patterns of {@code UnionAll} branches. The branches of a {@code UnionAll}/{@code Fork} plan has a similar
- * pattern, as {@code Fork} adds {@code EsqlProject}, an optional {@code Eval} and {@code Limit} on top of its actual children. In case
+ * pattern, as {@code Fork} adds {@code Project}, an optional {@code Eval} and {@code Limit} on top of its actual children. In case
* there is mismatched data types on the same field across different {@code UnionAll} branches, a {@code ConvertFunction} could also be
* added in the optional {@code Eval}.
*
* If the patterns of the {@code UnionAll} branches do not match the following expected patterns, the rule is not applied.
*
- * EsqlProject
+ * Project
* Eval (optional) - added when the output of each UnionAll branch are not exactly the same
* Limit
* EsRelation
* or
- * EsqlProject
+ * Project
* Eval (optional)
* Limit
* Subquery
* or
- * Limit - CombineProjections may remove the EsqlProject on top of the limit
+ * Limit - CombineProjections may remove the Project on top of the limit
* Subquery
*/
public final class PushDownFilterAndLimitIntoUnionAll extends Rule {
diff --git a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/optimizer/rules/logical/local/PushExpressionsToFieldLoad.java b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/optimizer/rules/logical/local/PushExpressionsToFieldLoad.java
index f02e1d733447e..e538b9ded443a 100644
--- a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/optimizer/rules/logical/local/PushExpressionsToFieldLoad.java
+++ b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/optimizer/rules/logical/local/PushExpressionsToFieldLoad.java
@@ -26,7 +26,6 @@
import org.elasticsearch.xpack.esql.plan.logical.Project;
import org.elasticsearch.xpack.esql.plan.logical.Row;
import org.elasticsearch.xpack.esql.plan.logical.join.StubRelation;
-import org.elasticsearch.xpack.esql.plan.logical.local.EsqlProject;
import org.elasticsearch.xpack.esql.rule.ParameterizedRule;
import java.util.ArrayList;
@@ -203,7 +202,7 @@ private LogicalPlan transformPotentialInvocation(LogicalPlan plan) {
return plan;
}
// Found a new pushable attribute, discard it *after* use so we don't modify the output.
- return new EsqlProject(Source.EMPTY, transformedPlan, transformedPlan.output());
+ return new Project(Source.EMPTY, transformedPlan, transformedPlan.output());
}
private Expression transformExpression(LogicalPlan nodeWithExpression, Expression e, BlockLoaderExpression ble) {
diff --git a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/plan/PlanWritables.java b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/plan/PlanWritables.java
index 52da0691d336e..765bf177f2250 100644
--- a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/plan/PlanWritables.java
+++ b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/plan/PlanWritables.java
@@ -31,7 +31,6 @@
import org.elasticsearch.xpack.esql.plan.logical.join.Join;
import org.elasticsearch.xpack.esql.plan.logical.local.CopyingLocalSupplier;
import org.elasticsearch.xpack.esql.plan.logical.local.EmptyLocalSupplier;
-import org.elasticsearch.xpack.esql.plan.logical.local.EsqlProject;
import org.elasticsearch.xpack.esql.plan.logical.local.ImmediateLocalSupplier;
import org.elasticsearch.xpack.esql.plan.logical.local.LocalRelation;
import org.elasticsearch.xpack.esql.plan.physical.AggregateExec;
@@ -79,7 +78,6 @@ public static List logical() {
Dissect.ENTRY,
Enrich.ENTRY,
EsRelation.ENTRY,
- EsqlProject.ENTRY,
Eval.ENTRY,
Filter.ENTRY,
Grok.ENTRY,
@@ -92,6 +90,7 @@ public static List logical() {
MvExpand.ENTRY,
OrderBy.ENTRY,
Project.ENTRY,
+ Project.V9_ENTRY, // Backward compatibility for reading old "EsqlProject" type
Rerank.ENTRY,
Sample.ENTRY,
Subquery.ENTRY,
diff --git a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/plan/logical/Insist.java b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/plan/logical/Insist.java
index 63ca4e1099a5f..a1a8aeecd40bf 100644
--- a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/plan/logical/Insist.java
+++ b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/plan/logical/Insist.java
@@ -46,7 +46,7 @@ public Insist replaceChild(LogicalPlan newChild) {
@Override
public boolean expressionsResolved() {
- // Like EsqlProject, we allow unsupported attributes to flow through the engine.
+ // Like Project, we allow unsupported attributes to flow through the engine.
return insistedAttributes().stream().allMatch(a -> a.resolved() || a instanceof UnsupportedAttribute);
}
diff --git a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/plan/logical/Project.java b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/plan/logical/Project.java
index 2a51d72c4b17b..fef3f84c0faaf 100644
--- a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/plan/logical/Project.java
+++ b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/plan/logical/Project.java
@@ -9,7 +9,7 @@
import org.elasticsearch.common.io.stream.NamedWriteableRegistry;
import org.elasticsearch.common.io.stream.StreamInput;
import org.elasticsearch.common.io.stream.StreamOutput;
-import org.elasticsearch.xpack.esql.core.capabilities.Resolvables;
+import org.elasticsearch.core.UpdateForV10;
import org.elasticsearch.xpack.esql.core.expression.Alias;
import org.elasticsearch.xpack.esql.core.expression.Attribute;
import org.elasticsearch.xpack.esql.core.expression.Expressions;
@@ -18,6 +18,7 @@
import org.elasticsearch.xpack.esql.core.tree.NodeInfo;
import org.elasticsearch.xpack.esql.core.tree.Source;
import org.elasticsearch.xpack.esql.expression.function.Functions;
+import org.elasticsearch.xpack.esql.expression.function.UnsupportedAttribute;
import org.elasticsearch.xpack.esql.io.stream.PlanStreamInput;
import java.io.IOException;
@@ -30,11 +31,42 @@
public class Project extends UnaryPlan implements Streaming, SortAgnostic, SortPreserving {
public static final NamedWriteableRegistry.Entry ENTRY = new NamedWriteableRegistry.Entry(LogicalPlan.class, "Project", Project::new);
+ /**
+ * Backward compatibility entry + name for reading the consolidated `EsqlProject` plans from pre-9.4.0 nodes.
+ */
+ private static final String LEGACY_PROJECT_NAME = "EsqlProject";
+
+ @UpdateForV10(owner = UpdateForV10.Owner.SEARCH_ANALYTICS)
+ public static final NamedWriteableRegistry.Entry V9_ENTRY = new NamedWriteableRegistry.Entry(
+ LogicalPlan.class,
+ LEGACY_PROJECT_NAME,
+ Project::readLegacyEsqlProject
+ );
+
+ private static Project readLegacyEsqlProject(StreamInput in) throws IOException {
+ return new Project(
+ Source.readFrom((PlanStreamInput) in),
+ in.readNamedWriteable(LogicalPlan.class),
+ in.readNamedWriteableCollectionAsList(NamedExpression.class),
+ V9_ENTRY.name
+ );
+ }
+
private final List extends NamedExpression> projections;
+ private final String writeableName;
public Project(Source source, LogicalPlan child, List extends NamedExpression> projections) {
+ this(source, child, projections, ENTRY.name);
+ }
+
+ /**
+ * Constructor that allows specifying a custom writeable name for backward compatibility.
+ * Used when deserializing legacy "EsqlProject" plans from older cluster versions.
+ */
+ private Project(Source source, LogicalPlan child, List extends NamedExpression> projections, String writeableName) {
super(source, child);
this.projections = projections;
+ this.writeableName = writeableName;
assert validateProjections(projections);
}
@@ -55,7 +87,8 @@ private Project(StreamInput in) throws IOException {
this(
Source.readFrom((PlanStreamInput) in),
in.readNamedWriteable(LogicalPlan.class),
- in.readNamedWriteableCollectionAsList(NamedExpression.class)
+ in.readNamedWriteableCollectionAsList(NamedExpression.class),
+ ENTRY.name
);
}
@@ -68,7 +101,7 @@ public void writeTo(StreamOutput out) throws IOException {
@Override
public String getWriteableName() {
- return ENTRY.name;
+ return writeableName;
}
@Override
@@ -96,7 +129,13 @@ public boolean resolved() {
@Override
public boolean expressionsResolved() {
- return Resolvables.resolved(projections);
+ for (NamedExpression projection : projections) {
+ // don't call dataType() - it will fail on UnresolvedAttribute
+ if (projection.resolved() == false && projection instanceof UnsupportedAttribute == false) {
+ return false;
+ }
+ }
+ return true;
}
@Override
diff --git a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/plan/logical/local/EsqlProject.java b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/plan/logical/local/EsqlProject.java
deleted file mode 100644
index 5fb36cf1ebdb1..0000000000000
--- a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/plan/logical/local/EsqlProject.java
+++ /dev/null
@@ -1,85 +0,0 @@
-/*
- * 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.xpack.esql.plan.logical.local;
-
-import org.elasticsearch.common.io.stream.NamedWriteableRegistry;
-import org.elasticsearch.common.io.stream.StreamInput;
-import org.elasticsearch.common.io.stream.StreamOutput;
-import org.elasticsearch.xpack.esql.core.expression.NamedExpression;
-import org.elasticsearch.xpack.esql.core.tree.NodeInfo;
-import org.elasticsearch.xpack.esql.core.tree.Source;
-import org.elasticsearch.xpack.esql.expression.function.UnsupportedAttribute;
-import org.elasticsearch.xpack.esql.io.stream.PlanStreamInput;
-import org.elasticsearch.xpack.esql.plan.logical.LogicalPlan;
-import org.elasticsearch.xpack.esql.plan.logical.Project;
-
-import java.io.IOException;
-import java.util.List;
-
-/**
- * A projection when first parsed, i.e. obtained from {@code KEEP, DROP, RENAME}. After the analysis step, we use {@link Project}.
- */
-// TODO: Consolidate with Project. We don't need the pre-/post-analysis distinction for other logical plans.
-// https://github.com/elastic/elasticsearch/issues/109195
-public class EsqlProject extends Project {
- public static final NamedWriteableRegistry.Entry ENTRY = new NamedWriteableRegistry.Entry(
- LogicalPlan.class,
- "EsqlProject",
- EsqlProject::new
- );
-
- public EsqlProject(Source source, LogicalPlan child, List extends NamedExpression> projections) {
- super(source, child, projections);
- }
-
- public EsqlProject(StreamInput in) throws IOException {
- this(
- Source.readFrom((PlanStreamInput) in),
- in.readNamedWriteable(LogicalPlan.class),
- in.readNamedWriteableCollectionAsList(NamedExpression.class)
- );
- }
-
- @Override
- public void writeTo(StreamOutput out) throws IOException {
- Source.EMPTY.writeTo(out);
- out.writeNamedWriteable(child());
- out.writeNamedWriteableCollection(projections());
- }
-
- @Override
- public String getWriteableName() {
- return ENTRY.name;
- }
-
- @Override
- protected NodeInfo info() {
- return NodeInfo.create(this, EsqlProject::new, child(), projections());
- }
-
- @Override
- public EsqlProject replaceChild(LogicalPlan newChild) {
- return new EsqlProject(source(), newChild, projections());
- }
-
- @Override
- public boolean expressionsResolved() {
- for (NamedExpression projection : projections()) {
- // don't call dataType() - it will fail on UnresolvedAttribute
- if (projection.resolved() == false && projection instanceof UnsupportedAttribute == false) {
- return false;
- }
- }
- return true;
- }
-
- @Override
- public Project withProjections(List extends NamedExpression> projections) {
- return new EsqlProject(source(), child(), projections);
- }
-}
diff --git a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/telemetry/FeatureMetric.java b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/telemetry/FeatureMetric.java
index 13537a977ee31..77ff2ab9d4626 100644
--- a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/telemetry/FeatureMetric.java
+++ b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/telemetry/FeatureMetric.java
@@ -39,7 +39,6 @@
import org.elasticsearch.xpack.esql.plan.logical.inference.Completion;
import org.elasticsearch.xpack.esql.plan.logical.inference.Rerank;
import org.elasticsearch.xpack.esql.plan.logical.join.LookupJoin;
-import org.elasticsearch.xpack.esql.plan.logical.local.EsqlProject;
import org.elasticsearch.xpack.esql.plan.logical.promql.PromqlCommand;
import org.elasticsearch.xpack.esql.plan.logical.show.ShowInfo;
@@ -86,7 +85,6 @@ public enum FeatureMetric {
*/
private static final List> excluded = List.of(
UnresolvedRelation.class,
- EsqlProject.class,
Project.class,
Limit.class, // LIMIT is managed in another way, see above
FuseScoreEval.class,
diff --git a/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/analysis/AnalyzerTests.java b/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/analysis/AnalyzerTests.java
index 00f3c21689803..862bf4aef2386 100644
--- a/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/analysis/AnalyzerTests.java
+++ b/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/analysis/AnalyzerTests.java
@@ -111,7 +111,6 @@
import org.elasticsearch.xpack.esql.plan.logical.inference.Completion;
import org.elasticsearch.xpack.esql.plan.logical.inference.Rerank;
import org.elasticsearch.xpack.esql.plan.logical.join.LookupJoin;
-import org.elasticsearch.xpack.esql.plan.logical.local.EsqlProject;
import org.elasticsearch.xpack.esql.session.Configuration;
import org.elasticsearch.xpack.esql.session.IndexResolver;
@@ -1548,7 +1547,7 @@ public void testEmptyEsRelationOnConstantEvalAndKeep() throws IOException {
var limit = as(plan, Limit.class);
limit = as(limit.child(), Limit.class);
assertThat(as(limit.limit(), Literal.class).value(), equalTo(2));
- var project = as(limit.child(), EsqlProject.class);
+ var project = as(limit.child(), Project.class);
var eval = as(project.child(), Eval.class);
assertEmptyEsRelation(eval.child());
}
@@ -2184,7 +2183,7 @@ public void testLookup() {
matchesList().item(startsWith("int{f}")).item(startsWith("name{f}"))
);
- var project = as(lookup.child(), EsqlProject.class);
+ var project = as(lookup.child(), Project.class);
assertThat(project.projections().stream().map(Object::toString).toList(), hasItem(matchesRegex("languages\\{f}#\\d+ AS int#\\d+")));
var esRelation = as(project.child(), EsRelation.class);
@@ -2644,8 +2643,8 @@ public void testConditionalFunctionsWithMixedNumericTypes() {
private void validateConditionalFunctions(LogicalPlan plan) {
var limit = as(plan, Limit.class);
- var esqlProject = as(limit.child(), EsqlProject.class);
- List> projections = esqlProject.projections();
+ var project = as(limit.child(), Project.class);
+ List> projections = project.projections();
var projection = as(projections.get(0), ReferenceAttribute.class);
assertEquals(projection.name(), "x");
assertEquals(projection.dataType(), DataType.DOUBLE);
@@ -3406,7 +3405,7 @@ public void testBasicFork() {
// fork branch 1
limit = as(subPlans.get(0), Limit.class);
assertThat(as(limit.limit(), Literal.class).value(), equalTo(DEFAULT_LIMIT));
- EsqlProject project = as(limit.child(), EsqlProject.class);
+ Project project = as(limit.child(), Project.class);
List projectColumns = project.expressions().stream().map(exp -> as(exp, Attribute.class).name()).toList();
assertThat(projectColumns, equalTo(expectedOutput));
Eval eval = as(project.child(), Eval.class);
@@ -3416,14 +3415,14 @@ public void testBasicFork() {
filter = as(filter.child(), Filter.class);
assertThat(as(filter.condition(), Equals.class).right(), equalTo(string("Chris")));
- project = as(filter.child(), EsqlProject.class);
+ project = as(filter.child(), Project.class);
var esRelation = as(project.child(), EsRelation.class);
assertThat(esRelation.indexPattern(), equalTo("test"));
// fork branch 2
limit = as(subPlans.get(1), Limit.class);
assertThat(as(limit.limit(), Literal.class).value(), equalTo(DEFAULT_LIMIT));
- project = as(limit.child(), EsqlProject.class);
+ project = as(limit.child(), Project.class);
projectColumns = project.expressions().stream().map(exp -> as(exp, Attribute.class).name()).toList();
assertThat(projectColumns, equalTo(expectedOutput));
eval = as(project.child(), Eval.class);
@@ -3433,14 +3432,14 @@ public void testBasicFork() {
filter = as(filter.child(), Filter.class);
assertThat(as(filter.condition(), Equals.class).right(), equalTo(string("Chris")));
- project = as(filter.child(), EsqlProject.class);
+ project = as(filter.child(), Project.class);
esRelation = as(project.child(), EsRelation.class);
assertThat(esRelation.indexPattern(), equalTo("test"));
// fork branch 3
limit = as(subPlans.get(2), Limit.class);
assertThat(as(limit.limit(), Literal.class).value(), equalTo(MAX_LIMIT));
- project = as(limit.child(), EsqlProject.class);
+ project = as(limit.child(), Project.class);
projectColumns = project.expressions().stream().map(exp -> as(exp, Attribute.class).name()).toList();
assertThat(projectColumns, equalTo(expectedOutput));
eval = as(project.child(), Eval.class);
@@ -3452,14 +3451,14 @@ public void testBasicFork() {
assertThat(as(filter.condition(), GreaterThan.class).right(), equalTo(literal(3)));
filter = as(filter.child(), Filter.class);
assertThat(as(filter.condition(), Equals.class).right(), equalTo(string("Chris")));
- project = as(filter.child(), EsqlProject.class);
+ project = as(filter.child(), Project.class);
esRelation = as(project.child(), EsRelation.class);
assertThat(esRelation.indexPattern(), equalTo("test"));
// fork branch 4
limit = as(subPlans.get(3), Limit.class);
assertThat(as(limit.limit(), Literal.class).value(), equalTo(DEFAULT_LIMIT));
- project = as(limit.child(), EsqlProject.class);
+ project = as(limit.child(), Project.class);
projectColumns = project.expressions().stream().map(exp -> as(exp, Attribute.class).name()).toList();
assertThat(projectColumns, equalTo(expectedOutput));
eval = as(project.child(), Eval.class);
@@ -3467,14 +3466,14 @@ public void testBasicFork() {
orderBy = as(eval.child(), OrderBy.class);
filter = as(orderBy.child(), Filter.class);
assertThat(as(filter.condition(), Equals.class).right(), equalTo(string("Chris")));
- project = as(filter.child(), EsqlProject.class);
+ project = as(filter.child(), Project.class);
esRelation = as(project.child(), EsRelation.class);
assertThat(esRelation.indexPattern(), equalTo("test"));
// fork branch 5
limit = as(subPlans.get(4), Limit.class);
assertThat(as(limit.limit(), Literal.class).value(), equalTo(MAX_LIMIT));
- project = as(limit.child(), EsqlProject.class);
+ project = as(limit.child(), Project.class);
projectColumns = project.expressions().stream().map(exp -> as(exp, Attribute.class).name()).toList();
assertThat(projectColumns, equalTo(expectedOutput));
eval = as(project.child(), Eval.class);
@@ -3483,7 +3482,7 @@ public void testBasicFork() {
assertThat(as(limit.limit(), Literal.class).value(), equalTo(9));
filter = as(limit.child(), Filter.class);
assertThat(as(filter.condition(), Equals.class).right(), equalTo(string("Chris")));
- project = as(filter.child(), EsqlProject.class);
+ project = as(filter.child(), Project.class);
esRelation = as(project.child(), EsRelation.class);
assertThat(esRelation.indexPattern(), equalTo("test"));
}
@@ -3509,7 +3508,7 @@ public void testForkBranchesWithDifferentSchemas() {
// fork branch 1
limit = as(subPlans.get(0), Limit.class);
assertThat(as(limit.limit(), Literal.class).value(), equalTo(MAX_LIMIT));
- EsqlProject project = as(limit.child(), EsqlProject.class);
+ Project project = as(limit.child(), Project.class);
List projectColumns = project.expressions().stream().map(exp -> as(exp, Attribute.class).name()).toList();
assertThat(projectColumns, equalTo(expectedOutput));
@@ -3531,7 +3530,7 @@ public void testForkBranchesWithDifferentSchemas() {
Filter filter = as(orderBy.child(), Filter.class);
assertThat(as(filter.condition(), GreaterThan.class).right(), equalTo(literal(3)));
- project = as(filter.child(), EsqlProject.class);
+ project = as(filter.child(), Project.class);
filter = as(project.child(), Filter.class);
assertThat(as(filter.condition(), Equals.class).right(), equalTo(string("Chris")));
var esRelation = as(filter.child(), EsRelation.class);
@@ -3540,7 +3539,7 @@ public void testForkBranchesWithDifferentSchemas() {
// fork branch 2
limit = as(subPlans.get(1), Limit.class);
assertThat(as(limit.limit(), Literal.class).value(), equalTo(DEFAULT_LIMIT));
- project = as(limit.child(), EsqlProject.class);
+ project = as(limit.child(), Project.class);
projectColumns = project.expressions().stream().map(exp -> as(exp, Attribute.class).name()).toList();
assertThat(projectColumns, equalTo(expectedOutput));
eval = as(project.child(), Eval.class);
@@ -3561,7 +3560,7 @@ public void testForkBranchesWithDifferentSchemas() {
filter = as(eval.child(), Filter.class);
assertThat(as(filter.condition(), GreaterThan.class).right(), equalTo(literal(2)));
- project = as(filter.child(), EsqlProject.class);
+ project = as(filter.child(), Project.class);
filter = as(project.child(), Filter.class);
assertThat(as(filter.condition(), Equals.class).right(), equalTo(string("Chris")));
esRelation = as(filter.child(), EsRelation.class);
@@ -3570,7 +3569,7 @@ public void testForkBranchesWithDifferentSchemas() {
// fork branch 3
limit = as(subPlans.get(2), Limit.class);
assertThat(as(limit.limit(), Literal.class).value(), equalTo(DEFAULT_LIMIT));
- project = as(limit.child(), EsqlProject.class);
+ project = as(limit.child(), Project.class);
projectColumns = project.expressions().stream().map(exp -> as(exp, Attribute.class).name()).toList();
assertThat(projectColumns, equalTo(expectedOutput));
eval = as(project.child(), Eval.class);
@@ -3606,7 +3605,7 @@ public void testForkBranchesWithDifferentSchemas() {
assertThat(dissect.parser().pattern(), equalTo("%{d} %{e} %{f}"));
assertThat(as(dissect.input(), FieldAttribute.class).name(), equalTo("first_name"));
- project = as(dissect.child(), EsqlProject.class);
+ project = as(dissect.child(), Project.class);
filter = as(project.child(), Filter.class);
assertThat(as(filter.condition(), Equals.class).right(), equalTo(string("Chris")));
esRelation = as(filter.child(), EsRelation.class);
@@ -3988,8 +3987,8 @@ public void testResolveRerankFields() {
Limit limit = as(plan, Limit.class); // Implicit limit added by AddImplicitLimit rule.
Rerank rerank = as(limit.child(), Rerank.class);
- EsqlProject keep = as(rerank.child(), EsqlProject.class);
- EsqlProject drop = as(keep.child(), EsqlProject.class);
+ Project keep = as(rerank.child(), Project.class);
+ Project drop = as(keep.child(), Project.class);
Filter filter = as(drop.child(), Filter.class);
EsRelation relation = as(filter.child(), EsRelation.class);
@@ -4773,7 +4772,7 @@ public void testSubqueryInFrom() {
Limit subqueryLimit = as(unionAll.children().get(0), Limit.class);
Literal limitLiteral = as(subqueryLimit.limit(), Literal.class);
assertEquals(1000, limitLiteral.value());
- EsqlProject subqueryProject = as(subqueryLimit.child(), EsqlProject.class);
+ Project subqueryProject = as(subqueryLimit.child(), Project.class);
List extends NamedExpression> projections = subqueryProject.projections();
assertEquals(13, projections.size()); // all fields from the two indices
Eval subqueryEval = as(subqueryProject.child(), Eval.class);
@@ -4793,7 +4792,7 @@ public void testSubqueryInFrom() {
subqueryLimit = as(unionAll.children().get(1), Limit.class);
limitLiteral = as(subqueryLimit.limit(), Literal.class);
assertEquals(1000, limitLiteral.value());
- subqueryProject = as(subqueryLimit.child(), EsqlProject.class);
+ subqueryProject = as(subqueryLimit.child(), Project.class);
projections = subqueryProject.projections();
assertEquals(13, projections.size()); // all fields from the two indices
subqueryEval = as(subqueryProject.child(), Eval.class);
@@ -4849,7 +4848,7 @@ public void testMultipleSubqueriesInFrom() {
assertEquals("languageCode", mvExpandTarget.name());
ReferenceAttribute mvExpandExpanded = as(mvExpand.expanded(), ReferenceAttribute.class);
assertEquals("languageCode", mvExpandExpanded.name());
- EsqlProject rename = as(mvExpand.child(), EsqlProject.class);
+ Project rename = as(mvExpand.child(), Project.class);
List extends NamedExpression> projections = rename.projections();
assertEquals(3, projections.size());
Alias a = as(projections.get(1), Alias.class);
@@ -4883,7 +4882,7 @@ public void testMultipleSubqueriesInFrom() {
Limit subqueryLimit = as(unionAll.children().get(0), Limit.class);
Literal limitLiteral = as(subqueryLimit.limit(), Literal.class);
assertEquals(1000, limitLiteral.value());
- EsqlProject subqueryProject = as(subqueryLimit.child(), EsqlProject.class);
+ Project subqueryProject = as(subqueryLimit.child(), Project.class);
projections = subqueryProject.projections();
assertEquals(15, projections.size()); // all fields from the other legs
Eval subqueryEval = as(subqueryProject.child(), Eval.class);
@@ -4893,14 +4892,14 @@ public void testMultipleSubqueriesInFrom() {
assertEquals("test", subqueryIndex.indexPattern());
subqueryLimit = as(unionAll.children().get(1), Limit.class);
- subqueryProject = as(subqueryLimit.child(), EsqlProject.class);
+ subqueryProject = as(subqueryLimit.child(), Project.class);
projections = subqueryProject.projections();
assertEquals(15, projections.size()); // all fields from the other legs
subqueryEval = as(subqueryProject.child(), Eval.class);
aliases = subqueryEval.fields(); // nullEvals from the other legs
assertEquals(13, aliases.size());
Subquery subquery = as(subqueryEval.child(), Subquery.class);
- rename = as(subquery.child(), EsqlProject.class);
+ rename = as(subquery.child(), Project.class);
List extends NamedExpression> renameProjections = rename.projections();
assertEquals(2, renameProjections.size());
FieldAttribute language_code = as(renameProjections.get(0), FieldAttribute.class);
@@ -4919,7 +4918,7 @@ public void testMultipleSubqueriesInFrom() {
assertEquals("languages", subqueryIndex.indexPattern());
subqueryLimit = as(unionAll.children().get(2), Limit.class);
- subqueryProject = as(subqueryLimit.child(), EsqlProject.class);
+ subqueryProject = as(subqueryLimit.child(), Project.class);
projections = subqueryProject.projections();
assertEquals(15, projections.size()); // all fields from the other legs
subqueryEval = as(subqueryProject.child(), Eval.class);
@@ -4931,7 +4930,7 @@ public void testMultipleSubqueriesInFrom() {
assertEquals("sample_data", subqueryIndex.indexPattern());
subqueryLimit = as(unionAll.children().get(3), Limit.class);
- subqueryProject = as(subqueryLimit.child(), EsqlProject.class);
+ subqueryProject = as(subqueryLimit.child(), Project.class);
projections = subqueryProject.projections();
assertEquals(15, projections.size()); // all fields from the other legs
subqueryEval = as(subqueryProject.child(), Eval.class);
@@ -4964,7 +4963,7 @@ public void testMultipleSubqueryInFromWithoutMainIndexPattern() {
assertEquals("languageCode", mvExpandTarget.name());
ReferenceAttribute mvExpandExpanded = as(mvExpand.expanded(), ReferenceAttribute.class);
assertEquals("languageCode", mvExpandExpanded.name());
- EsqlProject rename = as(mvExpand.child(), EsqlProject.class);
+ Project rename = as(mvExpand.child(), Project.class);
List extends NamedExpression> projections = rename.projections();
assertEquals(3, projections.size());
Alias a = as(projections.get(1), Alias.class);
@@ -4996,7 +4995,7 @@ public void testMultipleSubqueryInFromWithoutMainIndexPattern() {
assertEquals(3, unionAll.children().size());
Limit subqueryLimit = as(unionAll.children().get(0), Limit.class);
- EsqlProject subqueryProject = as(subqueryLimit.child(), EsqlProject.class);
+ Project subqueryProject = as(subqueryLimit.child(), Project.class);
projections = subqueryProject.projections();
assertEquals(15, projections.size()); // all fields from the other legs
Eval subqueryEval = as(subqueryProject.child(), Eval.class);
@@ -5011,14 +5010,14 @@ public void testMultipleSubqueryInFromWithoutMainIndexPattern() {
assertEquals("test", subqueryIndex.indexPattern());
subqueryLimit = as(unionAll.children().get(1), Limit.class);
- subqueryProject = as(subqueryLimit.child(), EsqlProject.class);
+ subqueryProject = as(subqueryLimit.child(), Project.class);
projections = subqueryProject.projections();
assertEquals(15, projections.size()); // all fields from the other legs
subqueryEval = as(subqueryProject.child(), Eval.class);
aliases = subqueryEval.fields(); // nullEvals from the other legs
assertEquals(13, aliases.size());
subquery = as(subqueryEval.child(), Subquery.class);
- rename = as(subquery.child(), EsqlProject.class);
+ rename = as(subquery.child(), Project.class);
List extends NamedExpression> renameProjections = rename.projections();
assertEquals(2, renameProjections.size());
FieldAttribute language_code = as(renameProjections.get(0), FieldAttribute.class);
@@ -5037,7 +5036,7 @@ public void testMultipleSubqueryInFromWithoutMainIndexPattern() {
assertEquals("languages", subqueryIndex.indexPattern());
subqueryLimit = as(unionAll.children().get(2), Limit.class);
- subqueryProject = as(subqueryLimit.child(), EsqlProject.class);
+ subqueryProject = as(subqueryLimit.child(), Project.class);
projections = subqueryProject.projections();
assertEquals(15, projections.size()); // all fields from the other legs
subqueryEval = as(subqueryProject.child(), Eval.class);
@@ -5065,12 +5064,12 @@ public void testNestedSubqueryInFrom() {
assertEquals(2, unionAll.children().size());
Limit subqueryLimit = as(unionAll.children().get(0), Limit.class);
- EsqlProject subqueryProject = as(subqueryLimit.child(), EsqlProject.class);
+ Project subqueryProject = as(subqueryLimit.child(), Project.class);
Eval subqueryEval = as(subqueryProject.child(), Eval.class);
EsRelation subqueryIndex = as(subqueryEval.child(), EsRelation.class);
assertEquals("test", subqueryIndex.indexPattern());
subqueryLimit = as(unionAll.children().get(1), Limit.class);
- subqueryProject = as(subqueryLimit.child(), EsqlProject.class);
+ subqueryProject = as(subqueryLimit.child(), Project.class);
subqueryEval = as(subqueryProject.child(), Eval.class);
Subquery subquery = as(subqueryEval.child(), Subquery.class);
Filter subqueryFilter = as(subquery.child(), Filter.class);
@@ -5078,13 +5077,13 @@ public void testNestedSubqueryInFrom() {
assertEquals(2, unionAll.children().size());
subqueryLimit = as(unionAll.children().get(0), Limit.class);
- subqueryProject = as(subqueryLimit.child(), EsqlProject.class);
+ subqueryProject = as(subqueryLimit.child(), Project.class);
subqueryEval = as(subqueryProject.child(), Eval.class);
subqueryIndex = as(subqueryEval.child(), EsRelation.class);
assertEquals("languages", subqueryIndex.indexPattern());
subqueryLimit = as(unionAll.children().get(1), Limit.class);
- subqueryProject = as(subqueryLimit.child(), EsqlProject.class);
+ subqueryProject = as(subqueryLimit.child(), Project.class);
subqueryEval = as(subqueryProject.child(), Eval.class);
subquery = as(subqueryEval.child(), Subquery.class);
Aggregate subqueryAggregate = as(subquery.child(), Aggregate.class);
@@ -5107,7 +5106,7 @@ public void testNestedSubqueryInFromWithMetadata() {
assertEquals(2, unionAll.children().size());
Limit subqueryLimit = as(unionAll.children().get(0), Limit.class);
- EsqlProject subqueryProject = as(subqueryLimit.child(), EsqlProject.class);
+ Project subqueryProject = as(subqueryLimit.child(), Project.class);
Eval subqueryEval = as(subqueryProject.child(), Eval.class);
EsRelation subqueryIndex = as(subqueryEval.child(), EsRelation.class);
assertEquals("test", subqueryIndex.indexPattern());
@@ -5117,7 +5116,7 @@ public void testNestedSubqueryInFromWithMetadata() {
assertEquals("_index", metadataAttribute.name());
subqueryLimit = as(unionAll.children().get(1), Limit.class);
- subqueryProject = as(subqueryLimit.child(), EsqlProject.class);
+ subqueryProject = as(subqueryLimit.child(), Project.class);
subqueryEval = as(subqueryProject.child(), Eval.class);
Subquery subquery = as(subqueryEval.child(), Subquery.class);
Filter subqueryFilter = as(subquery.child(), Filter.class);
@@ -5125,7 +5124,7 @@ public void testNestedSubqueryInFromWithMetadata() {
assertEquals(2, unionAll.children().size());
subqueryLimit = as(unionAll.children().get(0), Limit.class);
- subqueryProject = as(subqueryLimit.child(), EsqlProject.class);
+ subqueryProject = as(subqueryLimit.child(), Project.class);
subqueryEval = as(subqueryProject.child(), Eval.class);
subqueryIndex = as(subqueryEval.child(), EsRelation.class);
assertEquals("languages", subqueryIndex.indexPattern());
@@ -5133,7 +5132,7 @@ public void testNestedSubqueryInFromWithMetadata() {
assertEquals(2, output.size());
subqueryLimit = as(unionAll.children().get(1), Limit.class);
- subqueryProject = as(subqueryLimit.child(), EsqlProject.class);
+ subqueryProject = as(subqueryLimit.child(), Project.class);
subqueryEval = as(subqueryProject.child(), Eval.class);
subquery = as(subqueryEval.child(), Subquery.class);
Aggregate subqueryAggregate = as(subquery.child(), Aggregate.class);
@@ -5171,13 +5170,13 @@ public void testNestedSubqueriesInFromWithoutMainIndexPattern() {
assertEquals(2, unionAll.children().size());
Limit subqueryLimit = as(unionAll.children().get(0), Limit.class);
- EsqlProject subqueryProject = as(subqueryLimit.child(), EsqlProject.class);
+ Project subqueryProject = as(subqueryLimit.child(), Project.class);
Eval subqueryEval = as(subqueryProject.child(), Eval.class);
EsRelation subqueryIndex = as(subqueryEval.child(), EsRelation.class);
assertEquals("test", subqueryIndex.indexPattern());
subqueryLimit = as(unionAll.children().get(1), Limit.class);
- subqueryProject = as(subqueryLimit.child(), EsqlProject.class);
+ subqueryProject = as(subqueryLimit.child(), Project.class);
subqueryEval = as(subqueryProject.child(), Eval.class);
Subquery subquery = as(subqueryEval.child(), Subquery.class);
Aggregate subqueryAggregate = as(subquery.child(), Aggregate.class);
@@ -5218,7 +5217,7 @@ public void testMixedDataTypesInSubquery() {
assertEquals(2, unionAll.children().size());
Limit subqueryLimit = as(unionAll.children().get(0), Limit.class);
- EsqlProject subqueryProject = as(subqueryLimit.child(), EsqlProject.class);
+ Project subqueryProject = as(subqueryLimit.child(), Project.class);
Eval implicitCastingEval = as(subqueryProject.child(), Eval.class);
assertEquals(10, implicitCastingEval.fields().size());
Eval explicitCastingEval = as(implicitCastingEval.child(), Eval.class);
@@ -5229,7 +5228,7 @@ public void testMixedDataTypesInSubquery() {
assertEquals("test", subqueryIndex.indexPattern());
subqueryLimit = as(unionAll.children().get(1), Limit.class);
- subqueryProject = as(subqueryLimit.child(), EsqlProject.class);
+ subqueryProject = as(subqueryLimit.child(), Project.class);
implicitCastingEval = as(subqueryProject.child(), Eval.class);
assertEquals(9, implicitCastingEval.fields().size());
explicitCastingEval = as(implicitCastingEval.child(), Eval.class);
@@ -5289,7 +5288,7 @@ public void testMixedDataTypesWithExplicitCastingInSubquery() {
assertEquals(2, unionAll.children().size());
Limit subqueryLimit = as(unionAll.children().get(0), Limit.class);
- EsqlProject subqueryProject = as(subqueryLimit.child(), EsqlProject.class);
+ Project subqueryProject = as(subqueryLimit.child(), Project.class);
Eval implicitCastingEval = as(subqueryProject.child(), Eval.class);
assertEquals(10, implicitCastingEval.fields().size());
Eval explicitCastingEval = as(implicitCastingEval.child(), Eval.class);
@@ -5300,7 +5299,7 @@ public void testMixedDataTypesWithExplicitCastingInSubquery() {
assertEquals("test", subqueryIndex.indexPattern());
subqueryLimit = as(unionAll.children().get(1), Limit.class);
- subqueryProject = as(subqueryLimit.child(), EsqlProject.class);
+ subqueryProject = as(subqueryLimit.child(), Project.class);
implicitCastingEval = as(subqueryProject.child(), Eval.class);
assertEquals(9, implicitCastingEval.fields().size());
explicitCastingEval = as(implicitCastingEval.child(), Eval.class);
@@ -5372,7 +5371,7 @@ public void testMixedDataTypesWithMultipleExplicitCastingInSubquery() {
assertEquals(2, unionAll.children().size());
Limit subqueryLimit = as(unionAll.children().get(0), Limit.class);
- EsqlProject subqueryProject = as(subqueryLimit.child(), EsqlProject.class);
+ Project subqueryProject = as(subqueryLimit.child(), Project.class);
Eval implicitCastingEval = as(subqueryProject.child(), Eval.class);
assertEquals(10, implicitCastingEval.fields().size());
Eval explicitCastingEval = as(implicitCastingEval.child(), Eval.class);
@@ -5383,7 +5382,7 @@ public void testMixedDataTypesWithMultipleExplicitCastingInSubquery() {
assertEquals("test", subqueryIndex.indexPattern());
subqueryLimit = as(unionAll.children().get(1), Limit.class);
- subqueryProject = as(subqueryLimit.child(), EsqlProject.class);
+ subqueryProject = as(subqueryLimit.child(), Project.class);
implicitCastingEval = as(subqueryProject.child(), Eval.class);
assertEquals(9, implicitCastingEval.fields().size());
explicitCastingEval = as(implicitCastingEval.child(), Eval.class);
@@ -5436,7 +5435,7 @@ public void testSubqueryWithUnionAllOutputOverwritten() {
assertEquals(2, unionAll.children().size());
Limit subqueryLimit = as(unionAll.children().get(0), Limit.class);
- EsqlProject subqueryProject = as(subqueryLimit.child(), EsqlProject.class);
+ Project subqueryProject = as(subqueryLimit.child(), Project.class);
Eval implicitCastingEval = as(subqueryProject.child(), Eval.class);
Eval explicitCastingEval = as(implicitCastingEval.child(), Eval.class);
Eval missingFieldEval = as(explicitCastingEval.child(), Eval.class);
@@ -5444,7 +5443,7 @@ public void testSubqueryWithUnionAllOutputOverwritten() {
assertEquals("test", subqueryIndex.indexPattern());
subqueryLimit = as(unionAll.children().get(1), Limit.class);
- subqueryProject = as(subqueryLimit.child(), EsqlProject.class);
+ subqueryProject = as(subqueryLimit.child(), Project.class);
implicitCastingEval = as(subqueryProject.child(), Eval.class);
explicitCastingEval = as(implicitCastingEval.child(), Eval.class);
missingFieldEval = as(explicitCastingEval.child(), Eval.class);
@@ -5475,24 +5474,24 @@ public void testSubqueryWithTimeSeriesIndexInMainQuery() {
assertEquals(3, unionAll.children().size());
limit = as(unionAll.children().get(0), Limit.class);
- EsqlProject esqlProject = as(limit.child(), EsqlProject.class);
- Eval eval = as(esqlProject.child(), Eval.class);
+ Project project = as(limit.child(), Project.class);
+ Eval eval = as(project.child(), Eval.class);
eval = as(eval.child(), Eval.class);
EsRelation relation = as(eval.child(), EsRelation.class);
assertEquals("k8s", relation.indexPattern());
assertEquals(IndexMode.STANDARD, relation.indexMode());
limit = as(unionAll.children().get(1), Limit.class);
- esqlProject = as(limit.child(), EsqlProject.class);
- eval = as(esqlProject.child(), Eval.class);
+ project = as(limit.child(), Project.class);
+ eval = as(project.child(), Eval.class);
Subquery subquery = as(eval.child(), Subquery.class);
relation = as(subquery.child(), EsRelation.class);
assertEquals("sample_data", relation.indexPattern());
assertEquals(IndexMode.STANDARD, relation.indexMode());
limit = as(unionAll.children().get(2), Limit.class);
- esqlProject = as(limit.child(), EsqlProject.class);
- eval = as(esqlProject.child(), Eval.class);
+ project = as(limit.child(), Project.class);
+ eval = as(project.child(), Eval.class);
subquery = as(eval.child(), Subquery.class);
filter = as(subquery.child(), Filter.class);
relation = as(filter.child(), EsRelation.class);
@@ -5517,15 +5516,15 @@ public void testSubqueryWithTimeSeriesIndexInSubquery() {
assertEquals(3, unionAll.children().size());
limit = as(unionAll.children().get(0), Limit.class);
- EsqlProject esqlProject = as(limit.child(), EsqlProject.class);
- Eval eval = as(esqlProject.child(), Eval.class);
+ Project project = as(limit.child(), Project.class);
+ Eval eval = as(project.child(), Eval.class);
EsRelation relation = as(eval.child(), EsRelation.class);
assertEquals("sample_data", relation.indexPattern());
assertEquals(IndexMode.STANDARD, relation.indexMode());
limit = as(unionAll.children().get(1), Limit.class);
- esqlProject = as(limit.child(), EsqlProject.class);
- eval = as(esqlProject.child(), Eval.class);
+ project = as(limit.child(), Project.class);
+ eval = as(project.child(), Eval.class);
eval = as(eval.child(), Eval.class);
Subquery subquery = as(eval.child(), Subquery.class);
InlineStats inlineStats = as(subquery.child(), InlineStats.class);
@@ -5536,8 +5535,8 @@ public void testSubqueryWithTimeSeriesIndexInSubquery() {
assertEquals(IndexMode.STANDARD, relation.indexMode());
limit = as(unionAll.children().get(2), Limit.class);
- esqlProject = as(limit.child(), EsqlProject.class);
- eval = as(esqlProject.child(), Eval.class);
+ project = as(limit.child(), Project.class);
+ eval = as(project.child(), Eval.class);
subquery = as(eval.child(), Subquery.class);
filter = as(subquery.child(), Filter.class);
relation = as(filter.child(), EsRelation.class);
@@ -5562,16 +5561,16 @@ public void testSubqueryWithTimeSeriesIndexInMainQueryAndSubquery() {
assertEquals(3, unionAll.children().size());
limit = as(unionAll.children().get(0), Limit.class);
- EsqlProject esqlProject = as(limit.child(), EsqlProject.class);
- Eval eval = as(esqlProject.child(), Eval.class);
+ Project project = as(limit.child(), Project.class);
+ Eval eval = as(project.child(), Eval.class);
eval = as(eval.child(), Eval.class);
EsRelation relation = as(eval.child(), EsRelation.class);
assertEquals("k8s", relation.indexPattern());
assertEquals(IndexMode.STANDARD, relation.indexMode());
limit = as(unionAll.children().get(1), Limit.class);
- esqlProject = as(limit.child(), EsqlProject.class);
- eval = as(esqlProject.child(), Eval.class);
+ project = as(limit.child(), Project.class);
+ eval = as(project.child(), Eval.class);
eval = as(eval.child(), Eval.class);
Subquery subquery = as(eval.child(), Subquery.class);
InlineStats inlineStats = as(subquery.child(), InlineStats.class);
@@ -5582,8 +5581,8 @@ public void testSubqueryWithTimeSeriesIndexInMainQueryAndSubquery() {
assertEquals(IndexMode.STANDARD, relation.indexMode());
limit = as(unionAll.children().get(2), Limit.class);
- esqlProject = as(limit.child(), EsqlProject.class);
- eval = as(esqlProject.child(), Eval.class);
+ project = as(limit.child(), Project.class);
+ eval = as(project.child(), Eval.class);
subquery = as(eval.child(), Subquery.class);
filter = as(subquery.child(), Filter.class);
relation = as(filter.child(), EsRelation.class);
@@ -5612,12 +5611,12 @@ public void testSubqueryWithFullTextFunctionInMainQuery() {
assertEquals(2, unionAll.children().size());
Limit subqueryLimit = as(unionAll.children().get(0), Limit.class);
- EsqlProject subqueryProject = as(subqueryLimit.child(), EsqlProject.class);
+ Project subqueryProject = as(subqueryLimit.child(), Project.class);
EsRelation subqueryIndex = as(subqueryProject.child(), EsRelation.class);
assertEquals("sample_data", subqueryIndex.indexPattern());
subqueryLimit = as(unionAll.children().get(1), Limit.class);
- subqueryProject = as(subqueryLimit.child(), EsqlProject.class);
+ subqueryProject = as(subqueryLimit.child(), Project.class);
Subquery subquery = as(subqueryProject.child(), Subquery.class);
Filter subqueryFilter = as(subquery.child(), Filter.class);
MatchOperator matchOperator = as(subqueryFilter.condition(), MatchOperator.class);
@@ -5647,12 +5646,12 @@ public void testPruneEmptySubquery() {
// the subquery with remote:missingIndex is pruned, validate PruneEmptyUnionAllBranch
assertEquals(2, unionAll.children().size());
Limit subqueryLimit = as(unionAll.children().get(0), Limit.class);
- EsqlProject subqueryProject = as(subqueryLimit.child(), EsqlProject.class);
+ Project subqueryProject = as(subqueryLimit.child(), Project.class);
Eval subqueryEval = as(subqueryProject.child(), Eval.class);
EsRelation subqueryIndex = as(subqueryEval.child(), EsRelation.class);
assertEquals("test", subqueryIndex.indexPattern());
subqueryLimit = as(unionAll.children().get(1), Limit.class);
- subqueryProject = as(subqueryLimit.child(), EsqlProject.class);
+ subqueryProject = as(subqueryLimit.child(), Project.class);
subqueryEval = as(subqueryProject.child(), Eval.class);
Subquery subquery = as(subqueryEval.child(), Subquery.class);
subqueryIndex = as(subquery.child(), EsRelation.class);
@@ -5675,7 +5674,7 @@ public void testLookupJoinOnFieldNotAnywhereElse() {
assertThat(limit.limit(), instanceOf(Literal.class));
assertEquals(1000, as(limit.limit(), Literal.class).value());
- EsqlProject project = as(limit.child(), EsqlProject.class);
+ Project project = as(limit.child(), Project.class);
assertEquals(1, project.projections().size());
LookupJoin lookupJoin = as(project.child(), LookupJoin.class);
diff --git a/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/analysis/VerifierTests.java b/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/analysis/VerifierTests.java
index d745a9662d2c2..4f3cb4f464b93 100644
--- a/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/analysis/VerifierTests.java
+++ b/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/analysis/VerifierTests.java
@@ -293,6 +293,24 @@ public void testUnsupportedAndMultiTypedFields() {
error("from test* | rename multi_typed as x", analyzer)
);
+ // Verify that UnsupportedAttribute can pass through KEEP (Project) unchanged without error.
+ // This is valid because the field is just being projected, not used in operations.
+ query("from test* | keep unsupported", analyzer);
+ query("from test* | keep multi_typed", analyzer);
+
+ // Verify that renaming UnsupportedAttribute fails even after passing through KEEP.
+ // This validates the fix for EsqlProject consolidation: the rename check runs unconditionally,
+ // not gated by Project.expressionsResolved() which treats UnsupportedAttribute as resolved.
+ assertEquals(
+ "1:40: Cannot use field [unsupported] with unsupported type [flattened]",
+ error("from test* | keep unsupported | rename unsupported as x", analyzer)
+ );
+ assertEquals(
+ "1:40: Cannot use field [multi_typed] due to ambiguities being mapped as [2] incompatible types:"
+ + " [ip] in [test1, test2, test3] and [2] other indices, [keyword] in [test6]",
+ error("from test* | keep multi_typed | rename multi_typed as x", analyzer)
+ );
+
assertEquals(
"1:19: Cannot use field [unsupported] with unsupported type [flattened]",
error("from test* | sort unsupported asc", analyzer)
diff --git a/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/optimizer/HoistOrderByBeforeInlineJoinOptimizerTests.java b/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/optimizer/HoistOrderByBeforeInlineJoinOptimizerTests.java
index 68e1a1109e525..837a49930bdb4 100644
--- a/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/optimizer/HoistOrderByBeforeInlineJoinOptimizerTests.java
+++ b/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/optimizer/HoistOrderByBeforeInlineJoinOptimizerTests.java
@@ -30,7 +30,6 @@
import org.elasticsearch.xpack.esql.plan.logical.join.Join;
import org.elasticsearch.xpack.esql.plan.logical.join.JoinTypes;
import org.elasticsearch.xpack.esql.plan.logical.join.StubRelation;
-import org.elasticsearch.xpack.esql.plan.logical.local.EsqlProject;
import java.util.List;
import java.util.Set;
@@ -50,7 +49,7 @@
public class HoistOrderByBeforeInlineJoinOptimizerTests extends AbstractLogicalPlanOptimizerTests {
/*
- * EsqlProject[[emp_no{f}#12, avg{r}#6, languages{f}#15, gender{f}#14]]
+ * Project[[emp_no{f}#12, avg{r}#6, languages{f}#15, gender{f}#14]]
* \_TopN[[Order[emp_no{f}#12,ASC,LAST]],5[INTEGER],false]
* \_InlineJoin[LEFT,[languages{f}#15],[languages{r}#15]]
* |_EsRelation[employees][_meta_field{f}#18, emp_no{f}#12, first_name{f}#13, ..]
@@ -74,9 +73,9 @@ public void testInlineStatsAfterSortAndBeforeLimit() {
}
var plan = optimizedPlan(query);
- var esqlProject = as(plan, EsqlProject.class);
+ var project = as(plan, Project.class);
- var topN = as(esqlProject.child(), TopN.class);
+ var topN = as(project.child(), TopN.class);
assertThat(topN.order().size(), is(1));
var order = as(topN.order().get(0), Order.class);
assertThat(order.direction(), equalTo(Order.OrderDirection.ASC));
@@ -90,7 +89,7 @@ public void testInlineStatsAfterSortAndBeforeLimit() {
var relation = as(inlineJoin.left(), EsRelation.class);
assertThat(relation.concreteQualifiedIndices(), is(Set.of("employees")));
// Right
- var project = as(inlineJoin.right(), Project.class);
+ project = as(inlineJoin.right(), Project.class);
assertThat(Expressions.names(project.projections()), is(List.of("avg", "languages")));
var eval = as(project.child(), Eval.class);
assertThat(Expressions.names(eval.fields()), is(List.of("avg")));
@@ -155,7 +154,7 @@ public void testInlineStatsAfterSort() {
/*
* TopN[[Order[emp_no{f}#17,DESC,FIRST]],1000[INTEGER],false]
* \_InlineJoin[LEFT,[emp_no{f}#17],[emp_no{r}#17]]
- * |_EsqlProject[[_meta_field{f}#23, emp_no{f}#17, first_name{f}#18, gender{f}#19, hire_date{f}#24, job{f}#25, job.raw{f}#26,
+ * |_Project[[_meta_field{f}#23, emp_no{f}#17, first_name{f}#18, gender{f}#19, hire_date{f}#24, job{f}#25, job.raw{f}#26,
* languages{f}#20, last_name{f}#21 AS lName#11, long_noidx{f}#27, salary{f}#22, msg{r}#4, salaryK{r}#8]]
* | \_Eval[[salary{f}#22 / 1000[INTEGER] AS salaryK#8]]
* | \_Dissect[first_name{f}#18,Parser[pattern=%{msg}, appendSeparator=, parser=org.elasticsearch.dissect.DissectParser@3f4941c9],
@@ -199,8 +198,8 @@ public void testInlineStatsAfterSortAndSortAgnostic() {
assertThat(Expressions.names(inlineJoin.config().rightFields()), is(List.of("emp_no")));
// Left side of the join
- var esqlProject = as(inlineJoin.left(), EsqlProject.class);
- var eval = as(esqlProject.child(), Eval.class);
+ var project = as(inlineJoin.left(), Project.class);
+ var eval = as(project.child(), Eval.class);
assertThat(Expressions.names(eval.fields()), is(List.of("salaryK")));
var dissect = as(eval.child(), Dissect.class);
assertThat(dissect.parser().pattern(), is("%{msg}"));
@@ -215,7 +214,7 @@ public void testInlineStatsAfterSortAndSortAgnostic() {
assertThat(esRelation.concreteQualifiedIndices(), is(Set.of("employees")));
// Right side of the join
- var project = as(inlineJoin.right(), Project.class);
+ project = as(inlineJoin.right(), Project.class);
assertThat(Expressions.names(project.projections()), is(List.of("avg", "emp_no")));
var rightEval = as(project.child(), Eval.class);
assertThat(Expressions.names(rightEval.fields()), is(List.of("avg")));
@@ -468,7 +467,7 @@ public void testInlineStatsAfterTriSortPartlyShaddowed() {
* languages{f}#15, last_name{f}#16, long_noidx{f}#22, salary{f}#17, cd{r}#11]]
* \_TopN[[Order[$$s1$temp_name$23{r}#24,ASC,LAST]],1000[INTEGER],false]
* \_InlineJoin[LEFT,[],[]]
- * |_EsqlProject[[_meta_field{f}#18, emp_no{f}#12, first_name{f}#13, gender{f}#14, hire_date{f}#19, job{f}#20, job.raw{f}#21,
+ * |_Project[[_meta_field{f}#18, emp_no{f}#12, first_name{f}#13, gender{f}#14, hire_date{f}#19, job{f}#20, job.raw{f}#21,
* languages{f}#15, last_name{f}#16, long_noidx{f}#22, salary{f}#17, $$s1$temp_name$23{r}#24]]
* | \_Eval[[s1{r}#5 AS $$s1$temp_name$23#24]]
* | \_Filter[s1{r}#5 > 50000[INTEGER]]
@@ -509,7 +508,7 @@ public void testInlineStatsAfterSortDropped() {
assertThat(inlineJoin.config().rightFields(), empty());
// Left side of the join
- var leftProject = as(inlineJoin.left(), EsqlProject.class);
+ var leftProject = as(inlineJoin.left(), Project.class);
var leftEval = as(leftProject.child(), Eval.class);
assertThat(Expressions.names(leftEval.fields()), contains(startsWith("$$s1$temp_name$")));
var leftFilter = as(leftEval.child(), Filter.class);
@@ -535,7 +534,7 @@ public void testInlineStatsAfterSortDropped() {
* Project[[salary{r}#7, emp_no{f}#9]]
* \_TopN[[Order[$$salary$temp_name$20{r}#21,ASC,LAST]],1000[INTEGER],false]
* \_InlineJoin[LEFT,[emp_no{f}#9],[emp_no{r}#9]]
- * |_EsqlProject[[salary{f}#14, emp_no{f}#9, $$salary$temp_name$20{r}#21]]
+ * |_Project[[salary{f}#14, emp_no{f}#9, $$salary$temp_name$20{r}#21]]
* | \_Eval[[salary{f}#14 AS $$salary$temp_name$20#21]]
* | \_EsRelation[employees][_meta_field{f}#15, emp_no{f}#9, first_name{f}#10, g..]
* \_Aggregate[[emp_no{f}#9],[COUNT(*[KEYWORD],true[BOOLEAN],PT0S[TIME_DURATION]) AS salary#7, emp_no{f}#9]]
@@ -570,7 +569,7 @@ public void testShadowingInlineStatsAfterSort() {
assertThat(Expressions.names(inlineJoin.config().rightFields()), is(List.of("emp_no")));
// Left side of the join
- var leftProject = as(inlineJoin.left(), EsqlProject.class);
+ var leftProject = as(inlineJoin.left(), Project.class);
var leftEval = as(leftProject.child(), Eval.class);
assertThat(Expressions.names(leftEval.fields()), contains(startsWith("$$salary$temp_name$")));
var relation = as(leftEval.child(), EsRelation.class);
@@ -590,7 +589,7 @@ public void testShadowingInlineStatsAfterSort() {
* Project[[salary{r}#8, emp_no{f}#10]]
* \_TopN[[Order[$$salary$temp_name$21{r}#22,ASC,LAST], Order[emp_no{f}#10,ASC,LAST]],1000[INTEGER],false]
* \_InlineJoin[LEFT,[emp_no{f}#10],[emp_no{r}#10]]
- * |_EsqlProject[[salary{f}#15, emp_no{f}#10, $$salary$temp_name$21{r}#22]]
+ * |_Project[[salary{f}#15, emp_no{f}#10, $$salary$temp_name$21{r}#22]]
* | \_Eval[[salary{f}#15 AS $$salary$temp_name$21#22]]
* | \_EsRelation[employees][_meta_field{f}#16, emp_no{f}#10, first_name{f}#11, ..]
* \_Aggregate[[emp_no{f}#10],[COUNT(*[KEYWORD],true[BOOLEAN],PT0S[TIME_DURATION]) AS salary#8, emp_no{f}#10]]
@@ -631,7 +630,7 @@ public void testMixedShadowingInlineStatsAfterSort() {
assertThat(Expressions.names(inlineJoin.config().rightFields()), is(List.of("emp_no")));
// Left side of the join
- var leftProject = as(inlineJoin.left(), EsqlProject.class);
+ var leftProject = as(inlineJoin.left(), Project.class);
var leftEval = as(leftProject.child(), Eval.class);
assertThat(Expressions.names(leftEval.fields()), contains(startsWith("$$salary$temp_name$")));
var relation = as(leftEval.child(), EsRelation.class);
@@ -651,7 +650,7 @@ public void testMixedShadowingInlineStatsAfterSort() {
* Project[[salary{r}#12, emp_no{f}#14]]
* \_TopN[[Order[$$salary$temp_name$25{r}#26,ASC,LAST], Order[$$s1$temp_name$27{r}#28,ASC,LAST]],1000[INTEGER],false]
* \_InlineJoin[LEFT,[emp_no{f}#14],[emp_no{r}#14]]
- * |_EsqlProject[[salary{f}#19, emp_no{f}#14, $$salary$temp_name$25{r}#26, $$s1$temp_name$27{r}#28]]
+ * |_Project[[salary{f}#19, emp_no{f}#14, $$salary$temp_name$25{r}#26, $$s1$temp_name$27{r}#28]]
* | \_Eval[[salary{f}#19 + 1[INTEGER] AS s1#7, salary{f}#19 AS $$salary$temp_name$25#26, s1{r}#7 AS $$s1$temp_name$27#28]]
* | \_EsRelation[employees][_meta_field{f}#20, emp_no{f}#14, first_name{f}#15, ..]
* \_Aggregate[[emp_no{f}#14],[COUNT(*[KEYWORD],true[BOOLEAN],PT0S[TIME_DURATION]) AS salary#12, emp_no{f}#14]]
@@ -694,7 +693,7 @@ public void testShadowingInlineStatsAfterSortAndDrop() {
assertThat(Expressions.names(inlineJoin.config().rightFields()), is(List.of("emp_no")));
// Left side of the join
- var leftProject = as(inlineJoin.left(), EsqlProject.class);
+ var leftProject = as(inlineJoin.left(), Project.class);
var leftEval = as(leftProject.child(), Eval.class);
assertThat(
Expressions.names(leftEval.fields()),
@@ -717,7 +716,7 @@ public void testShadowingInlineStatsAfterSortAndDrop() {
* Project[[emp_idx{r}#9, salary{f}#20, sum{r}#13, languages{f}#18]]
* \_TopN[[Order[$$emp_no$temp_name$27{r}#28,ASC,LAST]],1000[INTEGER],false]
* \_InlineJoin[LEFT,[languages{f}#18],[languages{r}#18]]
- * |_EsqlProject[[emp_no{f}#15 AS emp_idx#9, salary{f}#20, languages{f}#18, $$emp_no$temp_name$27{r}#28]]
+ * |_Project[[emp_no{f}#15 AS emp_idx#9, salary{f}#20, languages{f}#18, $$emp_no$temp_name$27{r}#28]]
* | \_Eval[[emp_no{f}#15 AS $$emp_no$temp_name$27#28]]
* | \_EsRelation[employees][_meta_field{f}#21, emp_no{f}#15, first_name{f}#16, ..]
* \_Project[[sum{r}#13, languages{f}#18]]
@@ -756,7 +755,7 @@ public void testInlineStatsWithAggExpressionAfterSortAndRename() {
assertThat(Expressions.names(inlineJoin.config().rightFields()), is(List.of("languages")));
// Left side of the join
- var leftProject = as(inlineJoin.left(), EsqlProject.class);
+ var leftProject = as(inlineJoin.left(), Project.class);
var leftEval = as(leftProject.child(), Eval.class);
assertThat(Expressions.names(leftEval.fields()), contains(startsWith("$$emp_no$temp_name$")));
var relation = as(leftEval.child(), EsRelation.class);
@@ -957,7 +956,7 @@ public void testInlineStatsAfterEvalAndSortAndStats() {
* Project[[emp_no{f}#22, first_name{f}#23, sal{r}#17, id{r}#13, language_code{r}#36, language_name{r}#37, cd{r}#20, languages{f}#25]]
* \_TopN[[Order[$$language_name$temp_name$38$temp_name$40{r}#41,ASC,LAST]],1000[INTEGER],false]
* \_InlineJoin[LEFT,[languages{f}#25],[languages{r}#25]]
- * |_EsqlProject[[emp_no{f}#22, first_name{f}#23, salary{f}#27 AS sal#17, languages{f}#25, id{r}#13, language_code{r}#36,
+ * |_Project[[emp_no{f}#22, first_name{f}#23, salary{f}#27 AS sal#17, languages{f}#25, id{r}#13, language_code{r}#36,
* language_name{r}#37, $$language_name$temp_name$38$temp_name$40{r}#41]]
* | \_Eval[[$$language_name$temp_name$38{r$}#39 AS $$language_name$temp_name$38$temp_name$40#41]]
* | \_Enrich[ANY,languages_idx[KEYWORD],id{r}#13,{"match":{"indices":[],"match_field":"id",
@@ -1004,7 +1003,7 @@ public void testInlineStatsAfterEnrichAndSort() {
assertThat(Expressions.names(inlineJoin.config().rightFields()), is(List.of("languages")));
// Left side of the join
- var leftProject = as(inlineJoin.left(), EsqlProject.class);
+ var leftProject = as(inlineJoin.left(), Project.class);
var leftEval = as(leftProject.child(), Eval.class);
assertThat(Expressions.names(leftEval.fields()), contains(startsWith("$$language_name$temp_name$")));
var enrich = as(leftEval.child(), Enrich.class);
diff --git a/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/optimizer/LocalLogicalPlanOptimizerTests.java b/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/optimizer/LocalLogicalPlanOptimizerTests.java
index 2d3e7a331e443..8cd5fb7a8518d 100644
--- a/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/optimizer/LocalLogicalPlanOptimizerTests.java
+++ b/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/optimizer/LocalLogicalPlanOptimizerTests.java
@@ -86,7 +86,6 @@
import org.elasticsearch.xpack.esql.plan.logical.join.JoinTypes;
import org.elasticsearch.xpack.esql.plan.logical.join.StubRelation;
import org.elasticsearch.xpack.esql.plan.logical.local.EmptyLocalSupplier;
-import org.elasticsearch.xpack.esql.plan.logical.local.EsqlProject;
import org.elasticsearch.xpack.esql.plan.logical.local.LocalRelation;
import org.elasticsearch.xpack.esql.plan.physical.EsSourceExec;
import org.elasticsearch.xpack.esql.plan.physical.EvalExec;
@@ -252,7 +251,7 @@ public void testReassignedMissingFieldInProject() {
/**
* Expects
- * EsqlProject[[first_name{f}#4]]
+ * Project[[first_name{f}#4]]
* \_Limit[10000[INTEGER]]
* \_EsRelation[test][_meta_field{f}#9, emp_no{f}#3, first_name{f}#4, !ge..]
*/
@@ -277,7 +276,7 @@ public void testMissingFieldInSort() {
/**
* Expects
- * EsqlProject[[first_name{f}#7, last_name{r}#17]]
+ * Project[[first_name{f}#7, last_name{r}#17]]
* \_Limit[1000[INTEGER],true]
* \_MvExpand[last_name{f}#10,last_name{r}#17]
* \_Project[[_meta_field{f}#12, emp_no{f}#6, first_name{f}#7, gender{f}#8, hire_date{f}#13, job{f}#14, job.raw{f}#15, lang
@@ -298,7 +297,7 @@ public void testMissingFieldInMvExpand() {
// It'd be much better if this project was pushed down past the MvExpand, because MvExpand's cost scales with the number of
// involved attributes/columns.
- var project = as(localPlan, EsqlProject.class);
+ var project = as(localPlan, Project.class);
var projections = project.projections();
assertThat(Expressions.names(projections), contains("first_name", "last_name"));
@@ -405,7 +404,7 @@ public void testMissingFieldInNewCommand() {
/**
* Expects
- * EsqlProject[[x{r}#3]]
+ * Project[[x{r}#3]]
* \_Eval[[null[INTEGER] AS x]]
* \_Limit[10000[INTEGER]]
* \_EsRelation[test][_meta_field{f}#11, emp_no{f}#5, first_name{f}#6, !g..]
@@ -1084,7 +1083,7 @@ public void testPruneLeftJoinOnNullMatchingFieldAndShadowingAttributes() {
/**
* Expected:
- * EsqlProject[[!alias_integer, boolean{f}#7, byte{f}#8, constant_keyword-foo{f}#9, date{f}#10, date_nanos{f}#11, dense_vector
+ * Project[[!alias_integer, boolean{f}#7, byte{f}#8, constant_keyword-foo{f}#9, date{f}#10, date_nanos{f}#11, dense_vector
* {f}#26, double{f}#12, float{f}#13, half_float{f}#14, integer{f}#16, ip{f}#17, keyword{f}#18, long{f}#19, scaled_float{f}#15,
* semantic_text{f}#25, short{f}#21, text{f}#22, unsigned_long{f}#20, version{f}#23, wildcard{f}#24, s{r}#5]]
* \_Eval[[$$dense_vector$V_DOT_PRODUCT$27{f}#27 AS s#5]]
@@ -1100,8 +1099,8 @@ public void testVectorFunctionsReplaced() {
LogicalPlan plan = localPlan(plan(query, allTypesAnalyzer), TEST_SEARCH_STATS);
- // EsqlProject[[!alias_integer, boolean{f}#7, byte{f}#8, ... s{r}#5]]
- var project = as(plan, EsqlProject.class);
+ // Project[[!alias_integer, boolean{f}#7, byte{f}#8, ... s{r}#5]]
+ var project = as(plan, Project.class);
// Does not contain the extracted field
assertFalse(Expressions.names(project.projections()).stream().anyMatch(s -> s.startsWith(testCase.toFieldAttrName())));
@@ -1131,7 +1130,7 @@ public void testVectorFunctionsReplaced() {
/**
* Expected:
- * EsqlProject[[s{r}#4]]
+ * Project[[s{r}#4]]
* \_TopN[[Order[s{r}#4,DESC,FIRST]],1[INTEGER]]
* \_Eval[[$$dense_vector$replaced$28{t}#28 AS s#4]]
* \_EsRelation[types][$$dense_vector$replaced$28{t}#28, !alias_integer, b..]
@@ -1148,8 +1147,8 @@ public void testVectorFunctionsReplacedWithTopN() {
LogicalPlan plan = localPlan(plan(query, allTypesAnalyzer), TEST_SEARCH_STATS);
- // EsqlProject[[s{r}#4]]
- var project = as(plan, EsqlProject.class);
+ // Project[[s{r}#4]]
+ var project = as(plan, Project.class);
assertThat(Expressions.names(project.projections()), contains("s"));
// TopN[[Order[s{r}#4,DESC,FIRST]],1[INTEGER]]
@@ -1198,8 +1197,8 @@ public boolean isIndexed(FieldAttribute.FieldName field) {
}
});
- // EsqlProject[[s{r}#4]]
- var project = as(plan, EsqlProject.class);
+ // Project[[s{r}#4]]
+ var project = as(plan, Project.class);
assertThat(Expressions.names(project.projections()), contains("s"));
// TopN[[Order[s{r}#4,DESC,FIRST]],1[INTEGER]]
@@ -1386,7 +1385,7 @@ public void testAggregateMetricDoubleInlineStats() {
LogicalPlan plan = localPlan(plan(query, tsAnalyzer), new EsqlTestUtils.TestSearchStats());
- // EsqlProject[[@timestamp{f}#972, cluster{f}#973, pod{f}#974, network.eth0.tx{f}#991, tx_max{r}#962]]
+ // Project[[@timestamp{f}#972, cluster{f}#973, pod{f}#974, network.eth0.tx{f}#991, tx_max{r}#962]]
var project = as(plan, Project.class);
assertThat(Expressions.names(project.projections()), contains("@timestamp", "cluster", "pod", "network.eth0.tx", "tx_max"));
// TopN[[Order[@timestamp{f}#972,ASC,LAST], Order[cluster{f}#973,ASC,LAST], Order[pod{f}#974,ASC,LAST]],9[INTEGER],false]
@@ -1469,8 +1468,8 @@ public void testVectorFunctionsInWhere() {
LogicalPlan plan = localPlan(plan(query, allTypesAnalyzer), TEST_SEARCH_STATS);
- // EsqlProject[[dense_vector{f}#25]]
- var project = as(plan, EsqlProject.class);
+ // Project[[dense_vector{f}#25]]
+ var project = as(plan, Project.class);
assertThat(Expressions.names(project.projections()), contains("dense_vector"));
var limit = as(project.child(), Limit.class);
@@ -1557,8 +1556,8 @@ public void testVectorFunctionsUpdateIntermediateProjections() {
LogicalPlan plan = localPlan(plan(query, allTypesAnalyzer), TEST_SEARCH_STATS);
- // EsqlProject with all fields including similarity and keyword
- var project = as(plan, EsqlProject.class);
+ // Project with all fields including similarity and keyword
+ var project = as(plan, Project.class);
assertTrue(Expressions.names(project.projections()).contains("similarity"));
assertTrue(Expressions.names(project.projections()).contains("keyword"));
@@ -1582,8 +1581,8 @@ public void testVectorFunctionsUpdateIntermediateProjections() {
var mvExpand = as(eval.child(), MvExpand.class);
assertThat(Expressions.name(mvExpand.target()), equalTo("keyword"));
- // Inner EsqlProject with the pushed down function
- var innerProject = as(mvExpand.child(), EsqlProject.class);
+ // Inner Project with the pushed down function
+ var innerProject = as(mvExpand.child(), Project.class);
assertTrue(Expressions.names(innerProject.projections()).contains("keyword"));
assertTrue(
innerProject.projections()
@@ -1624,8 +1623,8 @@ public void testVectorFunctionsWithDuplicateFunctions() {
LogicalPlan plan = localPlan(plan(query, allTypesAnalyzer), TEST_SEARCH_STATS);
- // EsqlProject[[s1{r}#5, s2{r}#8, r2{r}#14]]
- var project = as(plan, EsqlProject.class);
+ // Project[[s1{r}#5, s2{r}#8, r2{r}#14]]
+ var project = as(plan, Project.class);
assertThat(Expressions.names(project.projections()), contains("s1", "s2", "r2"));
// Eval with s1, s2, r2
@@ -1736,7 +1735,7 @@ public void testLengthInEval() {
""";
LogicalPlan plan = localPlan(plan(query, analyzer), TEST_SEARCH_STATS);
- var project = as(plan, EsqlProject.class);
+ var project = as(plan, Project.class);
assertThat(Expressions.names(project.projections()), contains("l"));
var eval = as(project.child(), Eval.class);
Attribute lAttr = assertLengthPushdown(as(eval.fields().getFirst(), Alias.class).child(), "last_name");
@@ -1752,7 +1751,7 @@ public void testLengthInWhere() {
""";
LogicalPlan plan = localPlan(plan(query, analyzer), TEST_SEARCH_STATS);
- var project = as(plan, EsqlProject.class);
+ var project = as(plan, Project.class);
var limit = as(project.child(), Limit.class);
var filter = as(limit.child(), Filter.class);
Attribute lAttr = assertLengthPushdown(as(filter.condition(), GreaterThan.class).left(), "last_name");
@@ -1788,7 +1787,7 @@ public void testLengthInEvalAfterManyRenames() {
""";
LogicalPlan plan = localPlan(plan(query, analyzer), TEST_SEARCH_STATS);
- var project = as(plan, EsqlProject.class);
+ var project = as(plan, Project.class);
assertThat(Expressions.names(project.projections()), contains("l"));
var eval = as(project.child(), Eval.class);
Attribute lAttr = assertLengthPushdown(as(eval.fields().getFirst(), Alias.class).child(), "last_name");
@@ -1805,7 +1804,7 @@ public void testLengthInWhereAndEval() {
""";
LogicalPlan plan = localPlan(plan(query, analyzer), TEST_SEARCH_STATS);
- var project = as(plan, EsqlProject.class);
+ var project = as(plan, Project.class);
var eval = as(project.child(), Eval.class);
Attribute lAttr = assertLengthPushdown(as(eval.fields().getFirst(), Alias.class).child(), "last_name");
var limit = as(eval.child(), Limit.class);
@@ -2053,8 +2052,8 @@ public void testReductionPlanForTopNWithPushedDownFunctions() {
var logicalPlan = localPlan(plan(query, allTypesAnalyzer), TEST_SEARCH_STATS);
// Verify the logical plan structure:
- // EsqlProject[[text{f}#1105, score{r}#1085]]
- var project = as(logicalPlan, EsqlProject.class);
+ // Project[[text{f}#1105, score{r}#1085]]
+ var project = as(logicalPlan, Project.class);
assertThat(Expressions.names(project.projections()), contains("text", "score"));
// TopN[[Order[integer{f}#1099,DESC,FIRST]],10[INTEGER],false]
@@ -2187,7 +2186,7 @@ public void testPushableFunctionsInFork() {
assertTrue(relation1.output().contains(sFieldAttr));
// Second branch: (eval t = v_dot_product(dense_vector, [1, 2, 3]) | keep t, u, keyword)
- // EsqlProject[[s{r}#55, _fork{r}#4, t{r}#11]]
+ // Project[[s{r}#55, _fork{r}#4, t{r}#11]]
var project2 = as(fork.children().get(1), Project.class);
assertThat(Expressions.names(project2.projections()), containsInAnyOrder("s", "_fork", "t", "u", "keyword"));
@@ -2232,8 +2231,8 @@ public void testPushableFunctionsInSubqueries() {
""";
var localPlan = localPlan(plan(query, allTypesAnalyzer), TEST_SEARCH_STATS);
- // EsqlProject[[s{r}#97, t{r}#9]]
- var project = as(localPlan, EsqlProject.class);
+ // Project[[s{r}#97, t{r}#9]]
+ var project = as(localPlan, Project.class);
assertThat(Expressions.names(project.projections()), contains("s", "t"));
// Eval[[DOTPRODUCT(dense_vector{r}#82,[1.0, 2.0, 3.0][DENSE_VECTOR]) AS t#9]]
@@ -2256,14 +2255,14 @@ public void testPushableFunctionsInSubqueries() {
assertThat(unionAll.children(), hasSize(2));
// Second branch of UnionAll - contains the subquery
- // EsqlProject[[alias_integer{r}#99, boolean{r}#56, ...]]
- var project2 = as(unionAll.children().get(1), EsqlProject.class);
+ // Project[[alias_integer{r}#99, boolean{r}#56, ...]]
+ var project2 = as(unionAll.children().get(1), Project.class);
// Eval[[null[KEYWORD] AS alias_integer#55, null[BOOLEAN] AS boolean#56, ...]]
var eval2 = as(project2.child(), Eval.class);
var subquery = as(eval2.child(), Subquery.class);
- var subqueryProject = as(subquery.child(), EsqlProject.class);
+ var subqueryProject = as(subquery.child(), Project.class);
assertThat(Expressions.names(subqueryProject.projections()), contains("s"));
var subqueryEval = as(subqueryProject.child(), Eval.class);
assertThat(subqueryEval.fields(), hasSize(1));
diff --git a/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/optimizer/LogicalPlanOptimizerTests.java b/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/optimizer/LogicalPlanOptimizerTests.java
index e9b8eeb59419a..1fd1924140dc2 100644
--- a/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/optimizer/LogicalPlanOptimizerTests.java
+++ b/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/optimizer/LogicalPlanOptimizerTests.java
@@ -150,7 +150,6 @@
import org.elasticsearch.xpack.esql.plan.logical.join.LookupJoin;
import org.elasticsearch.xpack.esql.plan.logical.join.StubRelation;
import org.elasticsearch.xpack.esql.plan.logical.local.EmptyLocalSupplier;
-import org.elasticsearch.xpack.esql.plan.logical.local.EsqlProject;
import org.elasticsearch.xpack.esql.plan.logical.local.LocalRelation;
import org.elasticsearch.xpack.esql.plan.logical.local.LocalSupplier;
import org.elasticsearch.xpack.esql.rule.RuleExecutor;
@@ -270,7 +269,7 @@ public void testEmptyProjections() {
| drop salary
""");
- var project = as(plan, EsqlProject.class);
+ var project = as(plan, Project.class);
assertThat(project.expressions(), is(empty()));
var limit = as(project.child(), Limit.class);
as(limit.child(), EsRelation.class);
@@ -294,7 +293,7 @@ public void testEmptyProjectionInStat() {
* Expects
*
* {@code
- * EsqlProject[[x{r}#6]]
+ * Project[[x{r}#6]]
* \_Eval[[1[INTEGER] AS x]]
* \_Limit[1000[INTEGER]]
* \_LocalRelation[[{e}#18],[ConstantNullBlock[positions=1]]]
@@ -327,7 +326,7 @@ public void testEmptyProjectInStatWithEval() {
/**
* Expects
* {@code
- * EsqlProject[[x{r}#8]]
+ * Project[[x{r}#8]]
* \_Eval[[1[INTEGER] AS x]]
* \_Limit[1000[INTEGER]]
* \_Aggregate[[emp_no{f}#15],[emp_no{f}#15]]
@@ -1033,7 +1032,7 @@ public void testCombineProjectionWithAggregationFirstAndAliasedGroupingUnused()
/**
* Expects
* {@code
- * EsqlProject[[x{r}#3, y{r}#6]]
+ * Project[[x{r}#3, y{r}#6]]
* \_Eval[[emp_no{f}#9 + 2[INTEGER] AS x, salary{f}#14 + 3[INTEGER] AS y]]
* \_Limit[10000[INTEGER]]
* \_EsRelation[test][_meta_field{f}#15, emp_no{f}#9, first_name{f}#10, g..]
@@ -1615,7 +1614,7 @@ public void testDontCombineOrderByThroughMvExpand() {
* {@code
* Limit[1000[INTEGER],true]
* \_MvExpand[x{r}#4,x{r}#19]
- * \_EsqlProject[[first_name{f}#9 AS x]]
+ * \_Project[[first_name{f}#9 AS x]]
* \_Limit[1000[INTEGER],false]
* \_EsRelation[test][_meta_field{f}#14, emp_no{f}#8, first_name{f}#9, ge..]
* }
@@ -1630,7 +1629,7 @@ public void testCopyDefaultLimitPastMvExpand() {
var limit = asLimit(plan, 1000, true);
var mvExpand = as(limit.child(), MvExpand.class);
- var keep = as(mvExpand.child(), EsqlProject.class);
+ var keep = as(mvExpand.child(), Project.class);
var limitPastMvExpand = asLimit(keep.child(), 1000, false);
as(limitPastMvExpand.child(), EsRelation.class);
}
@@ -1666,7 +1665,7 @@ public void testCopyDefaultLimitPastLookupJoin() {
* {@code
* Limit[10[INTEGER],true]
* \_MvExpand[first_name{f}#7,first_name{r}#17]
- * \_EsqlProject[[first_name{f}#7, last_name{f}#10]]
+ * \_Project[[first_name{f}#7, last_name{f}#10]]
* \_Limit[1[INTEGER],false]
* \_EsRelation[test][_meta_field{f}#12, emp_no{f}#6, first_name{f}#7, ge..]
* }
@@ -1682,7 +1681,7 @@ public void testDontPushDownLimitPastMvExpand() {
var limit = asLimit(plan, 10, true);
var mvExpand = as(limit.child(), MvExpand.class);
- var project = as(mvExpand.child(), EsqlProject.class);
+ var project = as(mvExpand.child(), Project.class);
var limit2 = asLimit(project.child(), 1, false);
as(limit2.child(), EsRelation.class);
}
@@ -1718,7 +1717,7 @@ public void testDontPushDownLimitPastLookupJoin() {
/**
* Expected
* {@code
- * EsqlProject[[emp_no{f}#19, first_name{r}#30, languages{f}#22, lll{r}#9, salary{r}#31]]
+ * Project[[emp_no{f}#19, first_name{r}#30, languages{f}#22, lll{r}#9, salary{r}#31]]
* \_TopN[[Order[salary{r}#31,DESC,FIRST]],5[INTEGER]]
* \_Limit[5[INTEGER],true]
* \_MvExpand[salary{f}#24,salary{r}#31]
@@ -1748,7 +1747,7 @@ public void testMultipleMvExpandWithSortAndLimit() {
| sort salary desc
""");
- var keep = as(plan, EsqlProject.class);
+ var keep = as(plan, Project.class);
var topN = as(keep.child(), TopN.class);
assertThat(topN.limit().fold(FoldContext.small()), equalTo(5));
assertThat(orderNames(topN), contains("salary"));
@@ -1823,7 +1822,7 @@ public void testMultipleLookupJoinWithSortAndLimit() {
/**
* {@code
- * EsqlProject[[emp_no{f}#10, first_name{r}#21, salary{f}#15]]
+ * Project[[emp_no{f}#10, first_name{r}#21, salary{f}#15]]
* \_TopN[[Order[salary{f}#15,ASC,LAST], Order[first_name{r}#21,ASC,LAST]],5[INTEGER]]
* \_MvExpand[first_name{f}#11,first_name{r}#21,null]
* \_EsRelation[test][_meta_field{f}#16, emp_no{f}#10, first_name{f}#11, ..]
@@ -1838,7 +1837,7 @@ public void testPushDownLimitThroughMultipleSort_AfterMvExpand() {
| sort salary, first_name
| limit 5""");
- var keep = as(plan, EsqlProject.class);
+ var keep = as(plan, Project.class);
var topN = as(keep.child(), TopN.class);
assertThat(topN.limit().fold(FoldContext.small()), equalTo(5));
assertThat(orderNames(topN), contains("salary", "first_name"));
@@ -1849,7 +1848,7 @@ public void testPushDownLimitThroughMultipleSort_AfterMvExpand() {
/**
* Expected
* {@code
- * EsqlProject[[emp_no{f}#2560, first_name{r}#2571, salary{f}#2565]]
+ * Project[[emp_no{f}#2560, first_name{r}#2571, salary{f}#2565]]
* \_TopN[[Order[first_name{r}#2571,ASC,LAST]],5[INTEGER]]
* \_TopN[[Order[salary{f}#2565,ASC,LAST]],5[INTEGER]]
* \_MvExpand[first_name{f}#2561,first_name{r}#2571,null]
@@ -1866,7 +1865,7 @@ public void testPushDownLimitThroughMultipleSort_AfterMvExpand2() {
| limit 5
| sort first_name""");
- var keep = as(plan, EsqlProject.class);
+ var keep = as(plan, Project.class);
var topN = as(keep.child(), TopN.class);
assertThat(topN.limit().fold(FoldContext.small()), equalTo(5));
assertThat(orderNames(topN), contains("first_name"));
@@ -1983,7 +1982,7 @@ public void testPushDown_TheRightLimit_PastLookupJoin() {
/**
* Expected
* {@code
- * EsqlProject[[first_name{f}#11, emp_no{f}#10, salary{f}#12, b{r}#4]]
+ * Project[[first_name{f}#11, emp_no{f}#10, salary{f}#12, b{r}#4]]
* \_TopN[[Order[salary{f}#12,ASC,LAST]],5[INTEGER]]
* \_Eval[[100[INTEGER] AS b]]
* \_MvExpand[first_name{f}#11]
@@ -2000,7 +1999,7 @@ public void testPushDownLimit_PastEvalAndMvExpand() {
| limit 5
| keep first_name, emp_no, salary, b""");
- var keep = as(plan, EsqlProject.class);
+ var keep = as(plan, Project.class);
var topN = as(keep.child(), TopN.class);
assertThat(topN.limit().fold(FoldContext.small()), equalTo(5));
assertThat(orderNames(topN), contains("salary"));
@@ -2012,7 +2011,7 @@ public void testPushDownLimit_PastEvalAndMvExpand() {
/**
* Expected
* {@code
- * EsqlProject[[emp_no{f}#5885, first_name{r}#5896, salary{f}#5890]]
+ * Project[[emp_no{f}#5885, first_name{r}#5896, salary{f}#5890]]
* \_TopN[[Order[salary{f}#5890,ASC,LAST], Order[first_name{r}#5896,ASC,LAST]],1000[INTEGER]]
* \_Filter[gender{f}#5887 == [46][KEYWORD] AND WILDCARDLIKE(first_name{r}#5896)]
* \_MvExpand[first_name{f}#5886,first_name{r}#5896,null]
@@ -2029,7 +2028,7 @@ public void testRedundantSort_BeforeMvExpand_WithFilterOnExpandedField_ResultTru
| keep emp_no, first_name, salary
| sort salary, first_name""");
- var keep = as(plan, EsqlProject.class);
+ var keep = as(plan, Project.class);
var topN = as(keep.child(), TopN.class);
assertThat(topN.limit().fold(FoldContext.small()), equalTo(1000));
assertThat(orderNames(topN), contains("salary", "first_name"));
@@ -2135,7 +2134,7 @@ public void testMultiMvExpand_SortDownBelow() {
* {@code
* Limit[10000[INTEGER],true]
* \_MvExpand[c{r}#7,c{r}#16]
- * \_EsqlProject[[c{r}#7, a{r}#3]]
+ * \_Project[[c{r}#7, a{r}#3]]
* \_TopN[[Order[a{r}#3,ASC,FIRST]],7300[INTEGER]]
* \_Limit[7300[INTEGER],true]
* \_MvExpand[b{r}#5,b{r}#15]
@@ -2156,7 +2155,7 @@ public void testLimitThenSortBeforeMvExpand() {
var limit10kBefore = asLimit(plan, 10000, true);
var mvExpand = as(limit10kBefore.child(), MvExpand.class);
- var project = as(mvExpand.child(), EsqlProject.class);
+ var project = as(mvExpand.child(), Project.class);
var topN = as(project.child(), TopN.class);
assertThat(topN.limit().fold(FoldContext.small()), equalTo(7300));
assertThat(orderNames(topN), contains("a"));
@@ -2233,7 +2232,7 @@ public void testRemoveUnusedSortBeforeMvExpand_DefaultLimit10000() {
/**
* Expected
* {@code
- * EsqlProject[[emp_no{f}#3517, first_name{r}#3528, salary{f}#3522]]
+ * Project[[emp_no{f}#3517, first_name{r}#3528, salary{f}#3522]]
* \_TopN[[Order[salary{f}#3522,ASC,LAST], Order[first_name{r}#3528,ASC,LAST]],15[INTEGER]]
* \_Filter[gender{f}#3519 == [46][KEYWORD] AND WILDCARDLIKE(first_name{r}#3528)]
* \_MvExpand[first_name{f}#3518,first_name{r}#3528,null]
@@ -2251,7 +2250,7 @@ public void testRedundantSort_BeforeMvExpand_WithFilterOnExpandedField() {
| sort salary, first_name
| limit 15""");
- var keep = as(plan, EsqlProject.class);
+ var keep = as(plan, Project.class);
var topN = as(keep.child(), TopN.class);
assertThat(topN.limit().fold(FoldContext.small()), equalTo(15));
assertThat(orderNames(topN), contains("salary", "first_name"));
@@ -2264,7 +2263,7 @@ public void testRedundantSort_BeforeMvExpand_WithFilterOnExpandedField() {
/**
* Expected
* {@code
- * EsqlProject[[emp_no{f}#3421, first_name{r}#3432, salary{f}#3426]]
+ * Project[[emp_no{f}#3421, first_name{r}#3432, salary{f}#3426]]
* \_TopN[[Order[salary{f}#3426,ASC,LAST], Order[first_name{r}#3432,ASC,LAST]],15[INTEGER]]
* \_Filter[gender{f}#3423 == [46][KEYWORD] AND salary{f}#3426 > 60000[INTEGER]]
* \_MvExpand[first_name{f}#3422,first_name{r}#3432,null]
@@ -2282,7 +2281,7 @@ public void testRedundantSort_BeforeMvExpand_WithFilter_NOT_OnExpandedField() {
| sort salary, first_name
| limit 15""");
- var keep = as(plan, EsqlProject.class);
+ var keep = as(plan, Project.class);
var topN = as(keep.child(), TopN.class);
assertThat(topN.limit().fold(FoldContext.small()), equalTo(15));
assertThat(orderNames(topN), contains("salary", "first_name"));
@@ -2295,7 +2294,7 @@ public void testRedundantSort_BeforeMvExpand_WithFilter_NOT_OnExpandedField() {
/**
* Expected
* {@code
- * EsqlProject[[emp_no{f}#2085, first_name{r}#2096 AS x, salary{f}#2090]]
+ * Project[[emp_no{f}#2085, first_name{r}#2096 AS x, salary{f}#2090]]
* \_TopN[[Order[salary{f}#2090,ASC,LAST], Order[first_name{r}#2096,ASC,LAST]],15[INTEGER]]
* \_Filter[gender{f}#2087 == [46][KEYWORD] AND WILDCARDLIKE(first_name{r}#2096)]
* \_MvExpand[first_name{f}#2086,first_name{r}#2096,null]
@@ -2529,7 +2528,7 @@ public void testDescendantLimitLookupJoin() {
/**
* {@code
- * EsqlProject[[emp_no{f}#9, first_name{f}#10, languages{f}#12, language_code{r}#3, language_name{r}#22]]
+ * Project[[emp_no{f}#9, first_name{f}#10, languages{f}#12, language_code{r}#3, language_name{r}#22]]
* \_Eval[[null[INTEGER] AS language_code#3, null[KEYWORD] AS language_name#22]]
* \_Limit[1000[INTEGER],false]
* \_EsRelation[test][_meta_field{f}#15, emp_no{f}#9, first_name{f}#10, g..]
@@ -3150,7 +3149,7 @@ public void testEnrichNotNullFilter() {
/**
* Expects
* {@code
- * EsqlProject[[a{r}#3, last_name{f}#9]]
+ * Project[[a{r}#3, last_name{f}#9]]
* \_Eval[[__a_SUM_123{r}#12 / __a_COUNT_150{r}#13 AS a]]
* \_Limit[10000[INTEGER]]
* \_Aggregate[[last_name{f}#9],[SUM(salary{f}#10) AS __a_SUM_123, COUNT(salary{f}#10) AS __a_COUNT_150, last_nam
@@ -3187,7 +3186,7 @@ public void testSimpleAvgReplacement() {
/**
* Expects
* {@code
- * EsqlProject[[a{r}#3, c{r}#6, s{r}#9, last_name{f}#15]]
+ * Project[[a{r}#3, c{r}#6, s{r}#9, last_name{f}#15]]
* \_Eval[[s{r}#9 / c{r}#6 AS a]]
* \_Limit[10000[INTEGER]]
* \_Aggregate[[last_name{f}#15],[COUNT(salary{f}#16) AS c, SUM(salary{f}#16) AS s, last_name{f}#15]]
@@ -3215,7 +3214,7 @@ public void testClashingAggAvgReplacement() {
/**
* Expects
* {@code
- * EsqlProject[[a{r}#3, c{r}#6, s{r}#9, last_name{f}#15]]
+ * Project[[a{r}#3, c{r}#6, s{r}#9, last_name{f}#15]]
* \_Eval[[s{r}#9 / __a_COUNT@xxx{r}#18 AS a]]
* \_Limit[10000[INTEGER]]
* \_Aggregate[[last_name{f}#15],[COUNT(salary{f}#16) AS __a_COUNT@xxx, COUNT(languages{f}#14) AS c, SUM(salary{f}#16) AS
@@ -4743,7 +4742,7 @@ public void testStatsWithCanonicalAggregate() throws Exception {
*
* {@code
* Limit[1000[INTEGER]]
- * \_EsqlProject[[s{r}#3, s_expr{r}#5, s_null{r}#7, w{r}#10]]
+ * \_Project[[s{r}#3, s_expr{r}#5, s_null{r}#7, w{r}#10]]
* \_Project[[s{r}#3, s_expr{r}#5, s_null{r}#7, w{r}#10]]
* \_Eval[[COALESCE(MVCOUNT([1, 2][INTEGER]),0[INTEGER]) * $$COUNT$s$0{r}#26 AS s, COALESCE(MVCOUNT(314.0[DOUBLE] / 100[
* INTEGER]),0[INTEGER]) * $$COUNT$s$0{r}#26 AS s_expr, COALESCE(MVCOUNT(null[NULL]),0[INTEGER]) * $$COUNT$s$0{r}#26 AS s_null]]
@@ -4763,8 +4762,8 @@ public void testCountOfLiteral() {
""", new TestSubstitutionOnlyOptimizer());
var limit = as(plan, Limit.class);
- var esqlProject = as(limit.child(), EsqlProject.class);
- var project = as(esqlProject.child(), Project.class);
+ var topProject = as(limit.child(), Project.class);
+ var project = as(topProject.child(), Project.class);
var eval = as(project.child(), Eval.class);
var agg = as(eval.child(), Aggregate.class);
@@ -4815,7 +4814,7 @@ public void testCountOfLiteral() {
*
* {@code
* Limit[1000[INTEGER]]
- * \_EsqlProject[[s{r}#3, s_expr{r}#5, s_null{r}#7, w{r}#10]]
+ * \_Project[[s{r}#3, s_expr{r}#5, s_null{r}#7, w{r}#10]]
* \_Project[[s{r}#3, s_expr{r}#5, s_null{r}#7, w{r}#10]]
* \_Eval[[MVSUM([1, 2][INTEGER]) * $$COUNT$s$0{r}#25 AS s, MVSUM(314.0[DOUBLE] / 100[INTEGER]) * $$COUNT$s$0{r}#25 AS s
* _expr, MVSUM(null[NULL]) * $$COUNT$s$0{r}#25 AS s_null]]
@@ -4835,8 +4834,8 @@ public void testSumOfLiteral() {
""", new TestSubstitutionOnlyOptimizer());
var limit = as(plan, Limit.class);
- var esqlProject = as(limit.child(), EsqlProject.class);
- var project = as(esqlProject.child(), Project.class);
+ var topProject = as(limit.child(), Project.class);
+ var project = as(topProject.child(), Project.class);
var eval = as(project.child(), Eval.class);
var agg = as(eval.child(), Aggregate.class);
@@ -4915,7 +4914,7 @@ private record AggOfLiteralTestCase(
*
* {@code
* Limit[1000[INTEGER]]
- * \_EsqlProject[[s{r}#3, s_expr{r}#5, s_null{r}#7]]
+ * \_Project[[s{r}#3, s_expr{r}#5, s_null{r}#7]]
* \_Project[[s{r}#3, s_expr{r}#5, s_null{r}#7]]
* \_Eval[[MVAVG([1, 2][INTEGER]) AS s, MVAVG(314.0[DOUBLE] / 100[INTEGER]) AS s_expr, MVAVG(null[NULL]) AS s_null]]
* \_LocalRelation[[{e}#21],[ConstantNullBlock[positions=1]]]
@@ -4942,8 +4941,8 @@ public void testAggOfLiteral() {
var plan = plan(query, new TestSubstitutionOnlyOptimizer());
var limit = as(plan, Limit.class);
- var esqlProject = as(limit.child(), EsqlProject.class);
- var project = as(esqlProject.child(), Project.class);
+ var topProject = as(limit.child(), Project.class);
+ var project = as(topProject.child(), Project.class);
var eval = as(project.child(), Eval.class);
var singleRowRelation = as(eval.child(), LocalRelation.class);
var singleRow = singleRowRelation.supplier().get();
@@ -4961,7 +4960,7 @@ public void testAggOfLiteral() {
*
* {@code
* Limit[1000[INTEGER]]
- * \_EsqlProject[[s{r}#3, s_expr{r}#5, s_null{r}#7, emp_no{f}#13]]
+ * \_Project[[s{r}#3, s_expr{r}#5, s_null{r}#7, emp_no{f}#13]]
* \_Project[[s{r}#3, s_expr{r}#5, s_null{r}#7, emp_no{f}#13]]
* \_Eval[[MVAVG([1, 2][INTEGER]) AS s, MVAVG(314.0[DOUBLE] / 100[INTEGER]) AS s_expr, MVAVG(null[NULL]) AS s_null]]
* \_Aggregate[[emp_no{f}#13],[emp_no{f}#13]]
@@ -4990,8 +4989,8 @@ public void testAggOfLiteralGrouped() {
var plan = plan(query, new TestSubstitutionOnlyOptimizer());
var limit = as(plan, Limit.class);
- var esqlProject = as(limit.child(), EsqlProject.class);
- var project = as(esqlProject.child(), Project.class);
+ var topProject = as(limit.child(), Project.class);
+ var project = as(topProject.child(), Project.class);
var eval = as(project.child(), Eval.class);
var agg = as(eval.child(), Aggregate.class);
assertThat(agg.child(), instanceOf(EsRelation.class));
@@ -5740,7 +5739,7 @@ public void testInlinestatsGetsPrunedEntirely() {
}
/*
- * EsqlProject[[emp_no{f}#16, count{r}#7]]
+ * Project[[emp_no{f}#16, count{r}#7]]
* \_TopN[[Order[emp_no{f}#16,ASC,LAST]],5[INTEGER]]
* \_InlineJoin[LEFT,[salaryK{r}#5],[salaryK{r}#5],[salaryK{r}#5]]
* |_Eval[[salary{f}#21 / 1000[INTEGER] AS salaryK#5]]
@@ -5880,10 +5879,10 @@ public void testTripleInlineStatsGetsPrunedPartially() {
}
/*
- * EsqlProject[[emp_no{f}#26, salaryK{r}#4, count{r}#6, min{r}#19]]
+ * Project[[emp_no{f}#26, salaryK{r}#4, count{r}#6, min{r}#19]]
* \_TopN[[Order[emp_no{f}#26,ASC,LAST]],5[INTEGER]]
* \_InlineJoin[LEFT,[salaryK{r}#4],[salaryK{r}#4]]
- * |_EsqlProject[[_meta_field{f}#32, emp_no{f}#26, first_name{f}#27, gender{f}#28, hire_date{f}#33, job{f}#34, job.raw{f}#35,
+ * |_Project[[_meta_field{f}#32, emp_no{f}#26, first_name{f}#27, gender{f}#28, hire_date{f}#33, job{f}#34, job.raw{f}#35,
* languages{f}#29, last_name{f}#30, long_noidx{f}#36, salary{f}#31, count{r}#6, salaryK{r}#4, hire_date_string{r}#10,
* date{r}#15]]
* | \_Dissect[hire_date_string{r}#10,Parser[pattern=%{date}, appendSeparator=,
@@ -5964,7 +5963,7 @@ public void testTripleInlineStatsMultipleAssignmentsGetsPrunedPartially() {
}
/*
- * EsqlProject[[emp_no{f}#917]]
+ * Project[[emp_no{f}#917]]
* \_TopN[[Order[emp_no{f}#917,ASC,LAST]],5[INTEGER]]
* \_Dissect[hire_date_string{r}#898,Parser[pattern=%{date}, appendSeparator=,
* parser=org.elasticsearch.dissect.DissectParser@46132aa7],[date{r}#903]] <-- TODO: Dissect & Eval could/should be dropped
@@ -6083,7 +6082,7 @@ public void testInlineStatsWithAggGetsPrunedEntirely() {
}
/*
- * EsqlProject[[avg{r}#1053, decades{r}#1049, avgavg{r}#1063]]
+ * Project[[avg{r}#1053, decades{r}#1049, avgavg{r}#1063]]
* \_Limit[1000[INTEGER],true]
* \_InlineJoin[LEFT,[],[],[]]
* |_Project[[avg{r}#1053, decades{r}#1049, idecades{r}#1056]]
@@ -6116,7 +6115,7 @@ public void testInlineStatsWithAggAndInlineStatsGetsPruned() {
}
var plan = optimizedPlan(query);
- var project = as(plan, EsqlProject.class);
+ var project = as(plan, Project.class);
assertThat(Expressions.names(project.projections()), is(List.of("avg", "decades", "avgavg")));
var limit = asLimit(project.child(), 1000, false);
var inlineJoin = as(limit.child(), InlineJoin.class);
@@ -6182,7 +6181,7 @@ public void testInlineStatsWithLookupJoin() {
}
/*
- * EsqlProject[[avg{r}#4, emp_no{f}#9, first_name{f}#10]]
+ * Project[[avg{r}#4, emp_no{f}#9, first_name{f}#10]]
* \_Limit[10[INTEGER],false]
* \_InlineJoin[LEFT,[emp_no{f}#9],[emp_no{f}#9],[emp_no{r}#9]]
* |_EsRelation[test][_meta_field{f}#15, emp_no{f}#9, first_name{f}#10, g..]
@@ -6205,15 +6204,15 @@ public void testInlineStatsWithAvg() {
}
var plan = optimizedPlan(query);
- var esqlProject = as(plan, EsqlProject.class);
- assertThat(Expressions.names(esqlProject.projections()), is(List.of("avg", "emp_no", "first_name")));
- var upperLimit = asLimit(esqlProject.child(), 10, false);
+ var project = as(plan, Project.class);
+ assertThat(Expressions.names(project.projections()), is(List.of("avg", "emp_no", "first_name")));
+ var upperLimit = asLimit(project.child(), 10, false);
var inlineJoin = as(upperLimit.child(), InlineJoin.class);
assertThat(Expressions.names(inlineJoin.config().leftFields()), is(List.of("emp_no")));
// Left
var relation = as(inlineJoin.left(), EsRelation.class);
// Right
- var project = as(inlineJoin.right(), Project.class);
+ project = as(inlineJoin.right(), Project.class);
assertThat(Expressions.names(project.projections()), contains("avg", "emp_no"));
var eval = as(project.child(), Eval.class);
assertThat(Expressions.names(eval.fields()), is(List.of("avg")));
@@ -6223,7 +6222,7 @@ public void testInlineStatsWithAvg() {
}
/*
- * EsqlProject[[emp_no{r}#5]]
+ * Project[[emp_no{r}#5]]
* \_Limit[1000[INTEGER],false]
* \_LocalRelation[[salary{r}#3, emp_no{r}#5, gender{r}#7],
* org.elasticsearch.xpack.esql.plan.logical.local.CopyingLocalSupplier@9d5b596d]
@@ -6240,9 +6239,9 @@ public void testInlineStatsWithRow() {
}
var plan = optimizedPlan(query);
- var esqlProject = as(plan, Project.class);
- assertThat(Expressions.names(esqlProject.projections()), is(List.of("emp_no")));
- var limit = asLimit(esqlProject.child(), 1000, false);
+ var project = as(plan, Project.class);
+ assertThat(Expressions.names(project.projections()), is(List.of("emp_no")));
+ var limit = asLimit(project.child(), 1000, false);
var localRelation = as(limit.child(), LocalRelation.class);
assertThat(
localRelation.output(),
@@ -6255,7 +6254,7 @@ public void testInlineStatsWithRow() {
}
/*
- * EsqlProject[[a{r}#4]]
+ * Project[[a{r}#4]]
* \_Limit[2[INTEGER],false]
* \_InlineJoin[LEFT,[],[],[]]
* |_EsRelation[test][_meta_field{f}#12, emp_no{f}#6, first_name{f}#7, ge..]
@@ -6278,7 +6277,7 @@ public void testInlineStatsWithLimit() {
}
var plan = optimizedPlan(query);
- var project = as(plan, EsqlProject.class);
+ var project = as(plan, Project.class);
assertThat(Expressions.names(project.projections()), is(List.of("a")));
var limit = asLimit(project.child(), 2, false);
var inlineJoin = as(limit.child(), InlineJoin.class);
@@ -6298,7 +6297,7 @@ public void testInlineStatsWithLimit() {
* \_Aggregate[[],[VALUES(max_lang{r}#7,true[BOOLEAN]) AS v#11]]
* \_Limit[1[INTEGER],false]
* \_InlineJoin[LEFT,[gender{f}#14],[gender{f}#14],[gender{r}#14]]
- * |_EsqlProject[[emp_no{f}#12, languages{f}#15, gender{f}#14]]
+ * |_Project[[emp_no{f}#12, languages{f}#15, gender{f}#14]]
* | \_EsRelation[test][_meta_field{f}#18, emp_no{f}#12, first_name{f}#13, ..]
* \_Aggregate[[gender{f}#14],[MAX(languages{f}#15,true[BOOLEAN]) AS max_lang#7, gender{f}#14]]
* \_StubRelation[[emp_no{f}#12, languages{f}#15, gender{f}#14]]
@@ -6322,7 +6321,7 @@ public void testInlineStatsWithLimitAndAgg() {
var innerLimit = asLimit(aggregate.child(), 1, false);
var inlineJoin = as(innerLimit.child(), InlineJoin.class);
// Left
- var project = as(inlineJoin.left(), EsqlProject.class);
+ var project = as(inlineJoin.left(), Project.class);
var relation = as(project.child(), EsRelation.class);
// Right
var agg = as(inlineJoin.right(), Aggregate.class);
@@ -6330,7 +6329,7 @@ public void testInlineStatsWithLimitAndAgg() {
}
/*
- * EsqlProject[[c{r}#7, b{r}#5, a{r}#14]]
+ * Project[[c{r}#7, b{r}#5, a{r}#14]]
* \_Eval[[[KEYWORD] AS a#14]]
* \_Limit[1000[INTEGER],false]
* \_LocalRelation[[a{r}#3, b{r}#5, c{r}#7],Page{blocks=[ConstantNullBlock[positions=1], IntVectorBlock[vector=ConstantIntVector[p
@@ -6789,7 +6788,7 @@ protected List filteredWarnings() {
* Expects
* {@code
* Join[JoinConfig[type=LEFT OUTER, matchFields=[int{r}#4], conditions=[LOOKUP int_number_names ON int]]]
- * |_EsqlProject[[_meta_field{f}#12, emp_no{f}#6, first_name{f}#7, gender{f}#8, job{f}#13, job.raw{f}#14, languages{f}#9 AS int
+ * |_Project[[_meta_field{f}#12, emp_no{f}#6, first_name{f}#7, gender{f}#8, job{f}#13, job.raw{f}#14, languages{f}#9 AS int
* , last_name{f}#10, long_noidx{f}#15, salary{f}#11]]
* | \_Limit[1000[INTEGER]]
* | \_EsRelation[test][_meta_field{f}#12, emp_no{f}#6, first_name{f}#7, ge..]
@@ -6819,7 +6818,7 @@ public void testLookupSimple() {
);
// Left is the rest of the query
- var left = as(join.left(), EsqlProject.class);
+ var left = as(join.left(), Project.class);
assertThat(left.output().toString(), containsString("int{r}"));
var limit = as(left.child(), Limit.class);
assertThat(limit.limit().fold(FoldContext.small()), equalTo(1000));
@@ -6870,7 +6869,7 @@ public void testLookupSimple() {
* Limit[1000[INTEGER]]
* \_Aggregate[[name{r}#20],[MIN(emp_no{f}#9) AS MIN(emp_no), name{r}#20]]
* \_Join[JoinConfig[type=LEFT OUTER, matchFields=[int{r}#4], conditions=[LOOKUP int_number_names ON int]]]
- * |_EsqlProject[[_meta_field{f}#15, emp_no{f}#9, first_name{f}#10, gender{f}#11, job{f}#16, job.raw{f}#17, languages{f}#12 AS
+ * |_Project[[_meta_field{f}#15, emp_no{f}#9, first_name{f}#10, gender{f}#11, job{f}#16, job.raw{f}#17, languages{f}#12 AS
* int, last_name{f}#13, long_noidx{f}#18, salary{f}#14]]
* | \_EsRelation[test][_meta_field{f}#15, emp_no{f}#9, first_name{f}#10, g..]
* \_LocalRelation[[int{f}#19, name{f}#20],[IntVectorBlock[vector=IntArrayVector[positions=10, values=[0, 1, 2, 3, 4, 5, 6, 7, 8,
@@ -6909,7 +6908,7 @@ public void testLookupStats() {
);
// Left is the rest of the query
- var left = as(join.left(), EsqlProject.class);
+ var left = as(join.left(), Project.class);
assertThat(left.output().toString(), containsString("int{r}"));
as(left.child(), EsRelation.class);
@@ -7284,7 +7283,7 @@ public void testLookupJoinPushDownDisabledForDisjunctionBetweenLeftAndRightField
*
* Expects
*
{@code
- * EsqlProject[[languages{f}#21]]
+ * Project[[languages{f}#21]]
* \_Limit[1000[INTEGER],true]
* \_Join[LEFT,[language_code{r}#4],[language_code{r}#4],[language_code{f}#29]]
* |_Project[[_meta_field{f}#24, emp_no{f}#18, first_name{f}#19, gender{f}#20, hire_date{f}#25, job{f}#26, job.raw{f}#27, l
@@ -9565,7 +9564,7 @@ public void LookupJoinSemanticFilterDeupPushdown() {
}
/**
- * EsqlProject[[@timestamp{r}#3]]
+ * Project[[@timestamp{r}#3]]
* \_Eval[[1715300259000[DATETIME] AS @timestamp#3]]
* \_Limit[1000[INTEGER],false]
* \_EsRelation[k8s][@timestamp{f}#5, client.ip{f}#9, cluster{f}#6, ...]
@@ -9644,7 +9643,7 @@ public void testTranslateTRangeFoldsToLocalRelation() {
/**
* {@code
- * EsqlProject[[to_long{r}#2754, to_integer{r}#2757]]
+ * Project[[to_long{r}#2754, to_integer{r}#2757]]
* \_Eval[[TOLONG(string{f}#2761) AS to_long#2754, TOINTEGER(string{f}#2761) AS to_integer#2757]]
* ^ ^
* one argument to_long(value) is rewritten to ToLong
@@ -9680,7 +9679,7 @@ public void testToLongAndToIntegerSurrogateFoldsToLongAndToInteger() {
/**
* {@code
- * EsqlProject[[to_long{r}#2445, to_integer{r}#2449]]
+ * Project[[to_long{r}#2445, to_integer{r}#2449]]
* \_Eval[[TOLONGBASE(string{f}#2453,base{f}#2454) AS to_long#2445, TOINTEGERBASE(string{f}#2453,base{f}#2454) AS to_integer#2449]]
* ^ ^
* two argument to_long(string, base) is rewritten to ToLongBase
@@ -9716,7 +9715,7 @@ public void testToLongAndToIntegerSurrogateFoldsToLongBaseAndToIntegerBase() {
/**
* {@code
- * EsqlProject[[ubase{r}#1871, to_long{r}#1875, to_integer{r}#1879]]
+ * Project[[ubase{r}#1871, to_long{r}#1875, to_integer{r}#1879]]
* \_Eval[[TOUNSIGNEDLONG(base{f}#1885) AS ubase#1871,
* TOLONGBASE(string{f}#1884,TOINTEGER(ubase{r}#1871)) AS to_long#1875,
* TOINTEGERBASE(string{f}#1884,TOINTEGER(ubase{r}#1871)) AS to_integer#1879]]
@@ -9885,7 +9884,7 @@ STATS std_dev(network.eth0.currently_connected_clients)
}
/**
- * EsqlProject[[first_name{r}#32]]
+ * Project[[first_name{r}#32]]
* \_Limit[1000[INTEGER],false,false]
* \_Filter[_fork{r}#33 == fork1[KEYWORD]]
* \_Fork[[first_name{r}#32, _fork{r}#33]]
@@ -9911,7 +9910,7 @@ public void testPruneColumnsInForkBranchesSimpleEvalOutsideBranches() {
| DROP _fork
""";
var plan = optimizedPlan(query);
- var project = as(plan, EsqlProject.class);
+ var project = as(plan, Project.class);
assertThat(project.projections().size(), equalTo(1));
assertThat(Expressions.names(project.projections()), contains("first_name"));
var limit = as(project.child(), Limit.class);
@@ -9933,7 +9932,7 @@ public void testPruneColumnsInForkBranchesSimpleEvalOutsideBranches() {
}
/**
- * EsqlProject[[_fork{r}#76, emp_no{r}#62, x{r}#73, y{r}#74, z{r}#75]]
+ * Project[[_fork{r}#76, emp_no{r}#62, x{r}#73, y{r}#74, z{r}#75]]
* \_TopN[[Order[_fork{r}#76,ASC,LAST], Order[emp_no{r}#62,ASC,LAST]],1000[INTEGER],false]
* \_Fork[[emp_no{r}#62, x{r}#73, y{r}#74, z{r}#75, _fork{r}#76]]
* |_Project[[emp_no{f}#37, x{r}#15, y{r}#16, z{r}#17, _fork{r}#5]]
@@ -9967,7 +9966,7 @@ public void testPruneColumnsInForkBranchesDropNestedEvalsFromOutputIfNotNeeded()
| SORT _fork, emp_no
""";
var plan = optimizedPlan(query);
- var project = as(plan, EsqlProject.class);
+ var project = as(plan, Project.class);
assertThat(project.projections().size(), equalTo(5));
assertThat(Expressions.names(project.projections()), containsInAnyOrder("_fork", "emp_no", "x", "y", "z"));
var topN = as(project.child(), TopN.class);
@@ -10108,7 +10107,7 @@ public void testPruneColumnsInForkBranchesPruneIfAggregation() {
}
/**
- * EsqlProject[[languages{r}#33]]
+ * Project[[languages{r}#33]]
* \_Limit[10000[INTEGER],false,false]
* \_Filter[_fork{r}#34 == fork1[KEYWORD]]
* \_Fork[[languages{r}#33, _fork{r}#34]]
@@ -10135,7 +10134,7 @@ public void testPruneColumnsInForkBranchesShouldRespectOuterAlias() {
| drop _fork
""";
var plan = optimizedPlan(query);
- var project = as(plan, EsqlProject.class);
+ var project = as(plan, Project.class);
assertThat(project.projections().size(), equalTo(1));
assertThat(Expressions.names(project.projections()), contains("languages"));
var limit = as(project.child(), Limit.class);
@@ -10161,7 +10160,7 @@ public void testPruneColumnsInForkBranchesShouldRespectOuterAlias() {
}
/**
- * EsqlProject[[languages{r}#55]]
+ * Project[[languages{r}#55]]
* \_Limit[1000[INTEGER],false,false]
* \_Filter[_fork{r}#57 == fork1[KEYWORD]]
* \_Fork[[languages{r}#55, _fork{r}#57]]
@@ -10186,7 +10185,7 @@ public void testPruneColumnsInForkBranchesShouldKeepAliasWithSameNameAsColumn()
| keep languages
""";
var plan = optimizedPlan(query);
- var project = as(plan, EsqlProject.class);
+ var project = as(plan, Project.class);
assertThat(project.projections().size(), equalTo(1));
assertThat(Expressions.names(project.projections()), contains("languages"));
var limit = as(project.child(), Limit.class);
@@ -10228,7 +10227,7 @@ public void testPruneColumnsInForkBranchesShouldKeepAliasWithSameNameAsColumn()
}
/**
- * EsqlProject[[_meta_field{r}#48, emp_no{r}#49, first_name{r}#50, gender{r}#51, hire_date{r}#52, job{r}#53, job.raw{r}#54, l
+ * Project[[_meta_field{r}#48, emp_no{r}#49, first_name{r}#50, gender{r}#51, hire_date{r}#52, job{r}#53, job.raw{r}#54, l
* ast_name{r}#55, long_noidx{r}#56, salary{r}#57]]
* \_Limit[1000[INTEGER],false,false]
* \_Filter[_fork{r}#59 == fork1[KEYWORD]]
@@ -10259,7 +10258,7 @@ public void testPruneColumnsInForkBranchesShouldPruneNestedEvalsIfColumnIsDroppe
| drop languages
""";
var plan = optimizedPlan(query);
- var project = as(plan, EsqlProject.class);
+ var project = as(plan, Project.class);
assertThat(project.projections().size(), equalTo(10));
var limit = as(project.child(), Limit.class);
var filter = as(limit.child(), Filter.class);
@@ -10314,7 +10313,7 @@ public void testPruneColumnsInForkBranchesShouldPruneNestedEvalsIfColumnIsDroppe
}
/**
- * EsqlProject[[a{r}#45]]
+ * Project[[a{r}#45]]
* \_Limit[1000[INTEGER],false,false]
* \_Fork[[a{r}#45]]
* |_Project[[a{r}#5]]
@@ -10334,7 +10333,7 @@ public void testPruneColumnsInForkBranchesKeepOnlyNeededAggs() {
| KEEP a
""";
var plan = optimizedPlan(query);
- var project = as(plan, EsqlProject.class);
+ var project = as(plan, Project.class);
assertThat(project.projections().size(), equalTo(1));
assertThat(Expressions.names(project.projections()), contains("a"));
var limit = as(project.child(), Limit.class);
@@ -10703,7 +10702,7 @@ public void testPushDownLimitInForkPastEvalAndMvExpand() {
* Optimized plan:
* Limit[1000[INTEGER],false,false]
* \_InlineJoin[LEFT,[],[]]
- * |_EsqlProject[[salary{f}#23, languages1{r}#7, languages{f}#21]]
+ * |_Project[[salary{f}#23, languages1{r}#7, languages{f}#21]]
* | \_Eval[[MVAVG(languages{f}#21) AS languages1#7]]
* | \_EsRelation[employees][_meta_field{f}#24, emp_no{f}#18, first_name{f}#19, ..]
* \_Project[[languages2{r}#14, avg{r}#17]]
@@ -10716,7 +10715,7 @@ public void testPushDownLimitInForkPastEvalAndMvExpand() {
* Final plan execution:
* Limit[1000[INTEGER],false,false]
* \_Eval[[5.5[DOUBLE] AS languages2#14, 1[DOUBLE] AS avg#17]]
- * \_EsqlProject[[salary{f}#23, languages1{r}#7, languages{f}#21]]
+ * \_Project[[salary{f}#23, languages1{r}#7, languages{f}#21]]
* \_Eval[[MVAVG(languages{f}#21) AS languages1#7]]
* \_EsRelation[employees][_meta_field{f}#24, emp_no{f}#18, first_name{f}#19, ..]
*/
@@ -10735,7 +10734,7 @@ public void testDoubleInlineStatsPrunning_With_MV_Functions() {
var p = as(plan, Limit.class);
var join = as(p.child(), InlineJoin.class);
// Left
- var leftProject = as(join.left(), EsqlProject.class);
+ var leftProject = as(join.left(), Project.class);
assertMap(Expressions.names(leftProject.projections()), is(List.of("salary", "languages1", "languages")));
var leftEval = as(leftProject.child(), Eval.class);
var leftRelation = as(leftEval.child(), EsRelation.class);
@@ -10766,7 +10765,7 @@ public void testDoubleInlineStatsPrunning_With_MV_Functions() {
p = as(newMainPlan, Limit.class);
var eval = as(p.child(), Eval.class);
assertMap(Expressions.names(eval.fields()), is(List.of("languages2", "avg")));
- leftProject = as(eval.child(), EsqlProject.class);
+ leftProject = as(eval.child(), Project.class);
assertMap(Expressions.names(leftProject.projections()), is(List.of("salary", "languages1", "languages")));
var mvAvgEval = as(leftProject.child(), Eval.class);
assertMap(Expressions.names(mvAvgEval.fields()), is(List.of("languages1")));
diff --git a/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/optimizer/PhysicalPlanOptimizerTests.java b/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/optimizer/PhysicalPlanOptimizerTests.java
index 4d328f9385c2e..9907d2596ba61 100644
--- a/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/optimizer/PhysicalPlanOptimizerTests.java
+++ b/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/optimizer/PhysicalPlanOptimizerTests.java
@@ -8422,7 +8422,7 @@ public void testLookupThenProject() {
* {@code
* TopN[[Order[name{r}#25,ASC,LAST], Order[emp_no{f}#14,ASC,LAST]],1000[INTEGER]]
* \_Join[JoinConfig[type=LEFT OUTER, unionFields=[int{r}#4]]]
- * |_EsqlProject[[..., long_noidx{f}#23, salary{f}#19]]
+ * |_Project[[..., long_noidx{f}#23, salary{f}#19]]
* | \_EsRelation[test][_meta_field{f}#20, emp_no{f}#14, first_name{f}#15, ..]
* \_LocalRelation[[int{f}#24, name{f}#25],[...]]
* }
diff --git a/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/optimizer/rules/logical/DeduplicateAggsTests.java b/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/optimizer/rules/logical/DeduplicateAggsTests.java
index e656cc364691a..bbe4e13fb3a22 100644
--- a/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/optimizer/rules/logical/DeduplicateAggsTests.java
+++ b/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/optimizer/rules/logical/DeduplicateAggsTests.java
@@ -311,7 +311,7 @@ public void testEliminateDuplicateRenamedGroupings() {
/**
* Expects
* {@code
- * EsqlProject[[a{r}#5, c{r}#8]]
+ * Project[[a{r}#5, c{r}#8]]
* \_Eval[[null[INTEGER] AS x]]
* \_EsRelation[test][_meta_field{f}#15, emp_no{f}#9, first_name{f}#10, g..]
* }
diff --git a/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/optimizer/rules/logical/PropagateInlineEvalsTests.java b/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/optimizer/rules/logical/PropagateInlineEvalsTests.java
index e5a2300f4689f..7061ff5f8150b 100644
--- a/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/optimizer/rules/logical/PropagateInlineEvalsTests.java
+++ b/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/optimizer/rules/logical/PropagateInlineEvalsTests.java
@@ -27,9 +27,9 @@
import org.elasticsearch.xpack.esql.plan.logical.Eval;
import org.elasticsearch.xpack.esql.plan.logical.Limit;
import org.elasticsearch.xpack.esql.plan.logical.LogicalPlan;
+import org.elasticsearch.xpack.esql.plan.logical.Project;
import org.elasticsearch.xpack.esql.plan.logical.join.InlineJoin;
import org.elasticsearch.xpack.esql.plan.logical.join.StubRelation;
-import org.elasticsearch.xpack.esql.plan.logical.local.EsqlProject;
import org.junit.BeforeClass;
import java.util.List;
@@ -75,7 +75,7 @@ public static void init() {
* Limit[1000[INTEGER],false]
* \_InlineJoin[LEFT,[y{r}#10],[y{r}#10],[y{r}#10]]
* |_Eval[[gender{f}#13 AS y]]
- * | \_EsqlProject[[emp_no{f}#11, languages{f}#14, gender{f}#13]]
+ * | \_Project[[emp_no{f}#11, languages{f}#14, gender{f}#13]]
* | \_EsRelation[test][_meta_field{f}#17, emp_no{f}#11, first_name{f}#12, ..]
* \_Aggregate[STANDARD,[y{r}#10],[MAX(languages{f}#14,true[BOOLEAN]) AS max_lang, y{r}#10]]
* \_StubRelation[[emp_no{f}#11, languages{f}#14, gender{f}#13, y{r}#10]]
@@ -91,7 +91,7 @@ public void testGroupingAliasingMoved_To_LeftSideOfJoin() {
var limit = as(plan, Limit.class);
var inline = as(limit.child(), InlineJoin.class);
var leftEval = as(inline.left(), Eval.class);
- var project = as(leftEval.child(), EsqlProject.class);
+ var project = as(leftEval.child(), Project.class);
assertThat(Expressions.names(project.projections()), contains("emp_no", "languages", "gender"));
@@ -116,7 +116,7 @@ public void testGroupingAliasingMoved_To_LeftSideOfJoin() {
* r}#9]]
* |_Eval[[LEFT(last_name{f}#27,1[INTEGER]) AS f, gender{f}#25 AS g]]
* | \_Eval[[LEFT(first_name{f}#24,1[INTEGER]) AS first_name_l]]
- * | \_EsqlProject[[emp_no{f}#23, languages{f}#26, gender{f}#25, last_name{f}#27, first_name{f}#24]]
+ * | \_Project[[emp_no{f}#23, languages{f}#26, gender{f}#25, last_name{f}#27, first_name{f}#24]]
* | \_EsRelation[test][_meta_field{f}#29, emp_no{f}#23, first_name{f}#24, ..]
* \_Aggregate[STANDARD,[f{r}#18, g{r}#21, first_name_l{r}#9],[MAX(languages{f}#26,true[BOOLEAN]) AS max_lang, MIN(languages{f}
* #26,true[BOOLEAN]) AS min_lang, f{r}#18, g{r}#21, first_name_l{r}#9]]
@@ -136,7 +136,7 @@ public void testGroupingAliasingMoved_To_LeftSideOfJoin_WithExpression() {
var inline = as(limit.child(), InlineJoin.class);
var leftEval1 = as(inline.left(), Eval.class);
var leftEval2 = as(leftEval1.child(), Eval.class);
- var project = as(leftEval2.child(), EsqlProject.class);
+ var project = as(leftEval2.child(), Project.class);
assertThat(Expressions.names(project.projections()), contains("emp_no", "languages", "gender", "last_name", "first_name"));
diff --git a/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/optimizer/rules/logical/PushDownAndCombineFiltersTests.java b/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/optimizer/rules/logical/PushDownAndCombineFiltersTests.java
index db73c173e2590..51482c314330e 100644
--- a/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/optimizer/rules/logical/PushDownAndCombineFiltersTests.java
+++ b/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/optimizer/rules/logical/PushDownAndCombineFiltersTests.java
@@ -59,7 +59,6 @@
import org.elasticsearch.xpack.esql.plan.logical.join.JoinConfig;
import org.elasticsearch.xpack.esql.plan.logical.join.JoinTypes;
import org.elasticsearch.xpack.esql.plan.logical.join.StubRelation;
-import org.elasticsearch.xpack.esql.plan.logical.local.EsqlProject;
import org.elasticsearch.xpack.esql.plan.logical.local.LocalRelation;
import org.elasticsearch.xpack.esql.plan.logical.local.LocalSupplier;
@@ -136,11 +135,11 @@ public void testPushDownFilter() {
Filter fa = new Filter(EMPTY, relation, conditionA);
List projections = singletonList(getFieldAttribute("b"));
- EsqlProject keep = new EsqlProject(EMPTY, fa, projections);
+ Project keep = new Project(EMPTY, fa, projections);
Filter fb = new Filter(EMPTY, keep, conditionB);
Filter combinedFilter = new Filter(EMPTY, relation, new And(EMPTY, conditionA, conditionB));
- assertEquals(new EsqlProject(EMPTY, combinedFilter, projections), new PushDownAndCombineFilters().apply(fb, optimizerContext));
+ assertEquals(new Project(EMPTY, combinedFilter, projections), new PushDownAndCombineFilters().apply(fb, optimizerContext));
}
public void testPushDownFilterPastRenamingProject() {
@@ -259,11 +258,11 @@ public void testPushDownLikeRlikeFilter() {
Filter fa = new Filter(EMPTY, relation, conditionA);
List projections = singletonList(getFieldAttribute("b"));
- EsqlProject keep = new EsqlProject(EMPTY, fa, projections);
+ Project keep = new Project(EMPTY, fa, projections);
Filter fb = new Filter(EMPTY, keep, conditionB);
Filter combinedFilter = new Filter(EMPTY, relation, new And(EMPTY, conditionA, conditionB));
- assertEquals(new EsqlProject(EMPTY, combinedFilter, projections), new PushDownAndCombineFilters().apply(fb, optimizerContext));
+ assertEquals(new Project(EMPTY, combinedFilter, projections), new PushDownAndCombineFilters().apply(fb, optimizerContext));
}
// from ... | where a > 1 | stats count(1) by b | where count(1) >= 3 and b < 2
@@ -1036,7 +1035,7 @@ public void testPushDownLookupJoinExpressionMultipleWhere() {
* did its job of pushing down the filter (by copying the correct part of the left hand side to the right hand side to also include
* the aforementioned filter).
*
- * EsqlProject[[avg{r}#5, languages{f}#15, salary{f}#17, emp_no{f}#12]]
+ * Project[[avg{r}#5, languages{f}#15, salary{f}#17, emp_no{f}#12]]
* \_Limit[1000[INTEGER],false,false]
* \_InlineJoin[LEFT,[languages{f}#15],[languages{r}#15]]
* |_Filter[languages{f}#15 > 2[INTEGER]]
@@ -1068,7 +1067,7 @@ public void testPushDown_OneGroupingFilter_PastInlineJoin() {
var subPlansResults = new HashSet();
var firstSubPlan = InlineJoin.firstSubPlan(plan, subPlansResults).stubReplacedSubPlan();
- var project = as(plan, EsqlProject.class);
+ var project = as(plan, Project.class);
var limit = as(project.child(), Limit.class);
// InlineJoin left side
@@ -1102,7 +1101,7 @@ public void testPushDown_OneGroupingFilter_PastInlineJoin() {
}
/*
- * EsqlProject[[avg{r}#5, languages{f}#18, gender{f}#17, emp_no{f}#15]]
+ * Project[[avg{r}#5, languages{f}#18, gender{f}#17, emp_no{f}#15]]
* \_Limit[1000[INTEGER],false,false]
* \_Filter[emp_no{f}#15 > 10050[INTEGER]]
* \_InlineJoin[LEFT,[languages{f}#18, gender{f}#17],[languages{r}#18, gender{r}#17]]
@@ -1134,7 +1133,7 @@ public void testPushDown_SelectiveGroupingAndFilters_PastInlineJoin() {
var subPlansResults = new HashSet();
var firstSubPlan = InlineJoin.firstSubPlan(plan, subPlansResults).stubReplacedSubPlan();
- var project = as(plan, EsqlProject.class);
+ var project = as(plan, Project.class);
var limit = as(project.child(), Limit.class);
// common filter, above InlineJoin
@@ -1181,7 +1180,7 @@ public void testPushDown_SelectiveGroupingAndFilters_PastInlineJoin() {
}
/*
- * EsqlProject[[avg{r}#5, languages{f}#18, gender{f}#17, emp_no{f}#15]]
+ * Project[[avg{r}#5, languages{f}#18, gender{f}#17, emp_no{f}#15]]
* \_Limit[1000[INTEGER],false,false]
* \_Filter[ISNOTNULL(gender{f}#17) OR emp_no{f}#15 > 10050[INTEGER]]
* \_InlineJoin[LEFT,[languages{f}#18, gender{f}#17],[languages{r}#18, gender{r}#17]]
@@ -1213,7 +1212,7 @@ public void testPushDown_SelectiveGroupingOrFilters_PastInlineJoin() {
var subPlansResults = new HashSet();
var firstSubPlan = InlineJoin.firstSubPlan(plan, subPlansResults).stubReplacedSubPlan();
- var project = as(plan, EsqlProject.class);
+ var project = as(plan, Project.class);
var limit = as(project.child(), Limit.class);
// common filter, above InlineJoin
@@ -1263,7 +1262,7 @@ public void testPushDown_SelectiveGroupingOrFilters_PastInlineJoin() {
}
/*
- * EsqlProject[[avg{r}#7, languages{f}#21, gender{f}#20, emp_no{f}#18]]
+ * Project[[avg{r}#7, languages{f}#21, gender{f}#20, emp_no{f}#18]]
* \_Limit[1000[INTEGER],false,false]
* \_Filter[ISNOTNULL(gender{f}#20) OR emp_no{f}#18 > 10050[INTEGER] AND salary{f}#23 > 5000[INTEGER]]
* \_InlineJoin[LEFT,[languages{f}#21, gender{f}#20],[languages{r}#21, gender{r}#20]]
@@ -1296,7 +1295,7 @@ public void testPushDown_ComplexFiltering_CombinedWithLeftFiltering_PastInlineJo
var subPlansResults = new HashSet();
var firstSubPlan = InlineJoin.firstSubPlan(plan, subPlansResults).stubReplacedSubPlan();
- var project = as(plan, EsqlProject.class);
+ var project = as(plan, Project.class);
var limit = as(project.child(), Limit.class);
// common filter, above InlineJoin
@@ -1371,7 +1370,7 @@ public void testPushDown_ComplexFiltering_CombinedWithLeftFiltering_PastInlineJo
}
/*
- * EsqlProject[[salary{f}#16, emp_no{f}#11]]
+ * Project[[salary{f}#16, emp_no{f}#11]]
* \_Limit[1000[INTEGER],false,false]
* \_InlineJoin[LEFT,[salary{f}#16],[salary{r}#16]]
* |_Filter[salary{f}#16 < 10000[INTEGER] AND salary{f}#16 > 10000[INTEGER]]
@@ -1396,7 +1395,7 @@ public void testPushDown_ImpossibleFilter_PastInlineJoin() {
var subPlansResults = new HashSet();
var firstSubPlan = InlineJoin.firstSubPlan(plan, subPlansResults).stubReplacedSubPlan();
- var project = as(plan, EsqlProject.class);
+ var project = as(plan, Project.class);
var limit = as(project.child(), Limit.class);
// InlineJoin
var ij = as(limit.child(), InlineJoin.class);
@@ -1432,7 +1431,7 @@ public void testPushDown_ImpossibleFilter_PastInlineJoin() {
}
/*
- * EsqlProject[[languages{f}#14, a{r}#5, gender{f}#13]]
+ * Project[[languages{f}#14, a{r}#5, gender{f}#13]]
* \_Limit[1000[INTEGER],false,false]
* \_Filter[languages{f}#14 > 2[INTEGER]]
* \_InlineJoin[LEFT,[gender{f}#13],[gender{r}#13]]
@@ -1462,7 +1461,7 @@ public void testDontPushDown_A_SimpleFilter_PastInlineJoin() {
var subPlansResults = new HashSet();
var firstSubPlan = InlineJoin.firstSubPlan(plan, subPlansResults).stubReplacedSubPlan();
- var project = as(plan, EsqlProject.class);
+ var project = as(plan, Project.class);
var limit = as(project.child(), Limit.class);
// common filter, above InlineJoin
var commonFilter = as(limit.child(), Filter.class);
@@ -1495,7 +1494,7 @@ public void testDontPushDown_A_SimpleFilter_PastInlineJoin() {
}
/*
- * EsqlProject[[avgByL{r}#5, avgByG{r}#9, languages{f}#20, gender{f}#19, emp_no{f}#17]]
+ * Project[[avgByL{r}#5, avgByG{r}#9, languages{f}#20, gender{f}#19, emp_no{f}#17]]
* \_Limit[1000[INTEGER],false,false]
* \_Filter[languages{f}#20 > 2[INTEGER]]
* \_InlineJoin[LEFT,[gender{f}#19],[gender{r}#19]]
@@ -1554,7 +1553,7 @@ public void testPartiallyPushDown_GroupingFilters_PastTwoInlineJoins1() {
var subPlans = InlineJoin.firstSubPlan(plan, subPlansResults);
var firstSubPlan = subPlans.stubReplacedSubPlan();
- var project = as(plan, EsqlProject.class);
+ var project = as(plan, Project.class);
var limit = as(project.child(), Limit.class);
// common filter, above first InlineJoin (inline stats ... by gender)
@@ -1632,7 +1631,7 @@ public void testPartiallyPushDown_GroupingFilters_PastTwoInlineJoins1() {
}
/*
- * EsqlProject[[avgByL{r}#5, avgByG{r}#9, languages{f}#22, gender{f}#21, emp_no{f}#19]]
+ * Project[[avgByL{r}#5, avgByG{r}#9, languages{f}#22, gender{f}#21, emp_no{f}#19]]
* \_Limit[1000[INTEGER],false,false]
* \_Filter[emp_no{f}#19 > 10050[INTEGER]]
* \_InlineJoin[LEFT,[gender{f}#21, languages{f}#22],[gender{r}#21, languages{r}#22]]
@@ -1695,7 +1694,7 @@ public void testPartiallyPushDown_GroupingFilters_PastTwoInlineJoins2() {
var subPlans = InlineJoin.firstSubPlan(plan, subPlansResults);
var firstSubPlan = subPlans.stubReplacedSubPlan();
- var project = as(plan, EsqlProject.class);
+ var project = as(plan, Project.class);
var limit = as(project.child(), Limit.class);
// common filter, above first InlineJoin (inline stats ... by gender, languages)
@@ -1790,7 +1789,7 @@ public void testPartiallyPushDown_GroupingFilters_PastTwoInlineJoins2() {
}
/*
- * EsqlProject[[avgByL{r}#5, avgByG{r}#9, languages{f}#22, gender{f}#21, emp_no{f}#19]]
+ * Project[[avgByL{r}#5, avgByG{r}#9, languages{f}#22, gender{f}#21, emp_no{f}#19]]
* \_Limit[1000[INTEGER],false,false]
* \_Filter[avgByL{r}#5 > 40000[INTEGER]]
* \_InlineJoin[LEFT,[gender{f}#21, languages{f}#22],[gender{r}#21, languages{r}#22]]
@@ -1853,7 +1852,7 @@ public void testPartiallyPushDown_GroupingFilters_PastTwoInlineJoins_ExcludeAggF
var subPlans = InlineJoin.firstSubPlan(plan, subPlansResults);
var firstSubPlan = subPlans.stubReplacedSubPlan();
- var project = as(plan, EsqlProject.class);
+ var project = as(plan, Project.class);
var limit = as(project.child(), Limit.class);
// common filter, above first InlineJoin (inline stats ... by gender, languages)
@@ -1948,14 +1947,14 @@ public void testPartiallyPushDown_GroupingFilters_PastTwoInlineJoins_ExcludeAggF
}
/*
- * EsqlProject[[avgByL{r}#9, avgByG{r}#16, lang{r}#13, gender{f}#28, emp_no{f}#26]]
+ * Project[[avgByL{r}#9, avgByG{r}#16, lang{r}#13, gender{f}#28, emp_no{f}#26]]
* \_Limit[1000[INTEGER],false,false]
* \_Filter[emp_no{f}#26 > 10050[INTEGER]]
* \_InlineJoin[LEFT,[gender{f}#28, lang{r}#13],[gender{r}#28, lang{r}#13]]
- * |_EsqlProject[[salary{f}#31, gender{f}#28, emp_no{f}#26, avgByL{r}#9, languages{f}#29 AS lang#13]]
+ * |_Project[[salary{f}#31, gender{f}#28, emp_no{f}#26, avgByL{r}#9, languages{f}#29 AS lang#13]]
* | \_Filter[ISNOTNULL(gender{f}#28)]
* | \_InlineJoin[LEFT,[languages{f}#29],[languages{r}#29]]
- * | |_EsqlProject[[languages{f}#29, salary{f}#31, gender{f}#28, emp_no{f}#26]]
+ * | |_Project[[languages{f}#29, salary{f}#31, gender{f}#28, emp_no{f}#26]]
* | | \_Filter[languages{f}#29 > 3[INTEGER]]
* | | \_EsRelation[employees][_meta_field{f}#32, emp_no{f}#26, first_name{f}#27, ..]
* | \_Project[[avgByL{r}#9, languages{f}#29]]
@@ -1974,7 +1973,7 @@ public void testPartiallyPushDown_GroupingFilters_PastTwoInlineJoins_ExcludeAggF
* \_Eval[[$$SUM$avgByL$0{r$}#38 / $$COUNT$avgByL$1{r$}#39 AS avgByL#9]]
* \_Aggregate[[languages{f}#29],[SUM(salary{f}#31,true[BOOLEAN],PT0S[TIME_DURATION],compensated[KEYWORD]) AS
* $$SUM$avgByL$0#38, COUNT(salary{f}#31,true[BOOLEAN],PT0S[TIME_DURATION]) AS $$COUNT$avgByL$1#39, languages{f}#29]]
- * \_EsqlProject[[languages{f}#29, salary{f}#31, gender{f}#28, emp_no{f}#26]]
+ * \_Project[[languages{f}#29, salary{f}#31, gender{f}#28, emp_no{f}#26]]
* \_Filter[languages{f}#29 > 3[INTEGER]]
* \_EsRelation[employees][_meta_field{f}#32, emp_no{f}#26, first_name{f}#27, ..]
*
@@ -1982,10 +1981,10 @@ public void testPartiallyPushDown_GroupingFilters_PastTwoInlineJoins_ExcludeAggF
* \_Eval[[$$SUM$avgByG$0{r$}#40 / $$COUNT$avgByG$1{r$}#41 AS avgByG#16]]
* \_Aggregate[[gender{f}#28, lang{r}#13],[SUM(salary{f}#31,true[BOOLEAN],PT0S[TIME_DURATION],compensated[KEYWORD]) AS $$SUM$a
* vgByG$0#40, COUNT(salary{f}#31,true[BOOLEAN],PT0S[TIME_DURATION]) AS $$COUNT$avgByG$1#41, gender{f}#28, lang{r}#13]]
- * \_EsqlProject[[salary{f}#31, gender{f}#28, emp_no{f}#26, avgByL{r}#9, languages{f}#29 AS lang#13]]
+ * \_Project[[salary{f}#31, gender{f}#28, emp_no{f}#26, avgByL{r}#9, languages{f}#29 AS lang#13]]
* \_Filter[ISNOTNULL(gender{f}#28)]
* \_InlineJoin[LEFT,[languages{f}#29],[languages{r}#29]]
- * |_EsqlProject[[languages{f}#29, salary{f}#31, gender{f}#28, emp_no{f}#26]]
+ * |_Project[[languages{f}#29, salary{f}#31, gender{f}#28, emp_no{f}#26]]
* | \_Filter[languages{f}#29 > 3[INTEGER]]
* | \_EsRelation[employees][_meta_field{f}#32, emp_no{f}#26, first_name{f}#27, ..]
* \_LocalRelation[[avgByL{r}#9, languages{f}#29],org.elasticsearch.xpack.esql.plan.logical.local.CopyingLocalSupplier]
@@ -2015,7 +2014,7 @@ public void testPartiallyPushDown_RenamedGroupingFilters_PastTwoInlineJoins() {
var subPlans = InlineJoin.firstSubPlan(plan, subPlansResults);
var firstSubPlan = subPlans.stubReplacedSubPlan();
- var project = as(plan, EsqlProject.class);
+ var project = as(plan, Project.class);
var limit = as(project.child(), Limit.class);
// common filter, above first InlineJoin (inline stats ... by gender, languages)
@@ -2030,7 +2029,7 @@ public void testPartiallyPushDown_RenamedGroupingFilters_PastTwoInlineJoins() {
// first InlineJoin left side
var ij = as(commonFilter.child(), InlineJoin.class);
// this is the projection that renames languages AS lang
- var left = as(ij.left(), EsqlProject.class);
+ var left = as(ij.left(), Project.class);
var projections = left.projections();
assertThat(Expressions.names(projections), contains("salary", "gender", "emp_no", "avgByL", "lang"));
var langRename = as(projections.get(4), Alias.class);
@@ -2047,7 +2046,7 @@ public void testPartiallyPushDown_RenamedGroupingFilters_PastTwoInlineJoins() {
// second InlineJoin left side
var innerIj = as(leftFilter.child(), InlineJoin.class);
- var innerLeft = as(innerIj.left(), EsqlProject.class);
+ var innerLeft = as(innerIj.left(), Project.class);
var innerProjections = innerLeft.projections();
assertThat(Expressions.names(innerProjections), contains("languages", "salary", "gender", "emp_no"));
@@ -2073,7 +2072,7 @@ public void testPartiallyPushDown_RenamedGroupingFilters_PastTwoInlineJoins() {
assertEquals(innerAggregate.groupings(), firstSubPlanInnerAggregate.groupings());
assertEquals(innerAggregate.aggregates(), firstSubPlanInnerAggregate.aggregates());
- var firstSubPlanInnerRelation = as(firstSubPlanInnerAggregate.child(), EsqlProject.class);
+ var firstSubPlanInnerRelation = as(firstSubPlanInnerAggregate.child(), Project.class);
var firstSubPlanInnerProjections = firstSubPlanInnerRelation.projections();
assertThat(Expressions.names(firstSubPlanInnerProjections), contains("languages", "salary", "gender", "emp_no"));
@@ -2122,7 +2121,7 @@ public void testPartiallyPushDown_RenamedGroupingFilters_PastTwoInlineJoins() {
assertEquals(aggregate.groupings(), firstSubPlanAggregate.groupings());
assertEquals(aggregate.aggregates(), firstSubPlanAggregate.aggregates());
- var firstSubPlanProjection = as(ij.left(), EsqlProject.class);
+ var firstSubPlanProjection = as(ij.left(), Project.class);
projections = firstSubPlanProjection.projections();
assertThat(Expressions.names(projections), contains("salary", "gender", "emp_no", "avgByL", "lang"));
langRename = as(projections.get(4), Alias.class);
@@ -2135,7 +2134,7 @@ public void testPartiallyPushDown_RenamedGroupingFilters_PastTwoInlineJoins() {
}
/*
- * EsqlProject[[a{r}#5, gender{f}#12]]
+ * Project[[a{r}#5, gender{f}#12]]
* \_Limit[1000[INTEGER],false,false]
* \_Filter[a{r}#5 > 55000[INTEGER]]
* \_InlineJoin[LEFT,[gender{f}#12],[gender{r}#12]]
@@ -2156,7 +2155,7 @@ public void testDontPushDown_OnRightSideOf_InlineStats() {
| KEEP a, gender
""");
- var project = as(plan, EsqlProject.class);
+ var project = as(plan, Project.class);
var limit = as(project.child(), Limit.class);
// common filter, above InlineJoin
var commonFilter = as(limit.child(), Filter.class);
@@ -2179,7 +2178,7 @@ public void testDontPushDown_OnRightSideOf_InlineStats() {
}
/*
- * EsqlProject[[avgByL{r}#5, avgByG{r}#9, languages{f}#22, gender{f}#21, emp_no{f}#19]]
+ * Project[[avgByL{r}#5, avgByG{r}#9, languages{f}#22, gender{f}#21, emp_no{f}#19]]
* \_Limit[1000[INTEGER],false,false]
* \_Filter[languages{f}#22 > 3[INTEGER] AND avgByL{r}#5 > 40000[INTEGER] AND avgByG{r}#9 < 50000[INTEGER]]
* \_InlineJoin[LEFT,[gender{f}#21],[gender{r}#21]]
@@ -2238,7 +2237,7 @@ public void testPartiallyPushDown_GroupingFilters_PastTwoInlineJoins_ExcludeComp
var subPlans = InlineJoin.firstSubPlan(plan, subPlansResults);
var firstSubPlan = subPlans.stubReplacedSubPlan();
- var project = as(plan, EsqlProject.class);
+ var project = as(plan, Project.class);
var limit = as(project.child(), Limit.class);
// common filter, above first InlineJoin (inline stats ... by languages)
@@ -2331,7 +2330,7 @@ public void testPartiallyPushDown_GroupingFilters_PastTwoInlineJoins_ExcludeComp
}
/*
- * EsqlProject[[sum{r}#5, languages{f}#15, salary{f}#17]]
+ * Project[[sum{r}#5, languages{f}#15, salary{f}#17]]
* \_Limit[1000[INTEGER],false,false]
* \_InlineJoin[LEFT,[languages{f}#15],[languages{r}#15]]
* |_Filter[languages{f}#15 > 2[INTEGER]]
@@ -2358,7 +2357,7 @@ public void testPushDown_OneGroupingFilter_PastInlineJoinWithInnerFilter() {
var subPlansResults = new HashSet();
var firstSubPlan = InlineJoin.firstSubPlan(plan, subPlansResults).stubReplacedSubPlan();
- var project = as(plan, EsqlProject.class);
+ var project = as(plan, Project.class);
var limit = as(project.child(), Limit.class);
// InlineJoin left side
diff --git a/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/optimizer/rules/logical/PushDownFilterAndLimitIntoUnionAllTests.java b/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/optimizer/rules/logical/PushDownFilterAndLimitIntoUnionAllTests.java
index f306527723b16..ab1a55d7c77f7 100644
--- a/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/optimizer/rules/logical/PushDownFilterAndLimitIntoUnionAllTests.java
+++ b/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/optimizer/rules/logical/PushDownFilterAndLimitIntoUnionAllTests.java
@@ -37,7 +37,6 @@
import org.elasticsearch.xpack.esql.plan.logical.TopN;
import org.elasticsearch.xpack.esql.plan.logical.UnionAll;
import org.elasticsearch.xpack.esql.plan.logical.join.Join;
-import org.elasticsearch.xpack.esql.plan.logical.local.EsqlProject;
import org.elasticsearch.xpack.esql.plan.logical.local.LocalRelation;
import org.junit.Before;
@@ -57,14 +56,14 @@ public void checkSubqueryInFromCommandSupport() {
*Limit[1000[INTEGER],false,false]
* \_UnionAll[[_meta_field{r}#45, emp_no{r}#46, first_name{r}#47, gender{r}#48, hire_date{r}#49, job{r}#50, job.raw{r}#51,
* languages{r}#52, last_name{r}#53, long_noidx{r}#54, salary{r}#55, language_code{r}#56, language_name{r}#57]]
- * |_EsqlProject[[_meta_field{f}#12, emp_no{f}#6, first_name{f}#7, gender{f}#8, hire_date{f}#13, job{f}#14, job.raw{f}#15,
+ * |_Project[[_meta_field{f}#12, emp_no{f}#6, first_name{f}#7, gender{f}#8, hire_date{f}#13, job{f}#14, job.raw{f}#15,
* languages{f}#9, last_name{f}#10, long_noidx{f}#16, salary{f}#11, language_code{r}#30,
* language_name{r}#31]]
* | \_Eval[[null[INTEGER] AS language_code#30, null[KEYWORD] AS language_name#31]]
* | \_Limit[1000[INTEGER],false,false]
* | \_Filter[emp_no{f}#6 > 10000[INTEGER]]
* | \_EsRelation[test][_meta_field{f}#12, emp_no{f}#6, first_name{f}#7, ge..]
- * |_EsqlProject[[_meta_field{f}#23, emp_no{f}#17, first_name{f}#18, gender{f}#19, hire_date{f}#24, job{f}#25, job.raw{f}#26,
+ * |_Project[[_meta_field{f}#23, emp_no{f}#17, first_name{f}#18, gender{f}#19, hire_date{f}#24, job{f}#25, job.raw{f}#26,
* languages{f}#20, last_name{f}#21, long_noidx{f}#27, salary{f}#22, language_code{r}#32,
* language_name{r}#33]]
* | \_Eval[[null[INTEGER] AS language_code#32, null[KEYWORD] AS language_name#33]]
@@ -86,7 +85,7 @@ public void testPushDownSimpleFilterPastUnionAll() {
UnionAll unionAll = as(limit.child(), UnionAll.class);
assertEquals(3, unionAll.children().size());
- EsqlProject child1 = as(unionAll.children().get(0), EsqlProject.class);
+ Project child1 = as(unionAll.children().get(0), Project.class);
Eval eval = as(child1.child(), Eval.class);
Limit childLimit = as(eval.child(), Limit.class);
Filter childFilter = as(childLimit.child(), Filter.class);
@@ -98,7 +97,7 @@ public void testPushDownSimpleFilterPastUnionAll() {
EsRelation relation = as(childFilter.child(), EsRelation.class);
assertEquals("test", relation.indexPattern());
- EsqlProject child2 = as(unionAll.children().get(1), EsqlProject.class);
+ Project child2 = as(unionAll.children().get(1), Project.class);
eval = as(child2.child(), Eval.class);
Subquery subquery = as(eval.child(), Subquery.class);
childLimit = as(subquery.child(), Limit.class);
@@ -124,11 +123,11 @@ public void testPushDownSimpleFilterPastUnionAll() {
*Limit[1000[INTEGER],false,false]
* \_UnionAll[[_meta_field{r}#27, emp_no{r}#28, first_name{r}#29, gender{r}#30, hire_date{r}#31, job{r}#32, job.raw{r}#33,
* languages{r}#34, last_name{r}#35, long_noidx{r}#36, salary{r}#37]]
- * |_EsqlProject[[_meta_field{f}#11, emp_no{f}#5, first_name{f}#6, gender{f}#7, hire_date{f}#12, job{f}#13, job.raw{f}#14,
+ * |_Project[[_meta_field{f}#11, emp_no{f}#5, first_name{f}#6, gender{f}#7, hire_date{f}#12, job{f}#13, job.raw{f}#14,
* languages{f}#8, last_name{f}#9, long_noidx{f}#15, salary{f}#10]]
* | \_Limit[1000[INTEGER],false,false]
* | \_EsRelation[test][_meta_field{f}#11, emp_no{f}#5, first_name{f}#6, ge..]
- * \_EsqlProject[[_meta_field{f}#22, emp_no{f}#16, first_name{f}#17, gender{f}#18, hire_date{f}#23, job{f}#24, job.raw{f}#25,
+ * \_Project[[_meta_field{f}#22, emp_no{f}#16, first_name{f}#17, gender{f}#18, hire_date{f}#23, job{f}#24, job.raw{f}#25,
* languages{f}#19, last_name{f}#20, long_noidx{f}#26, salary{f}#21]]
* \_Subquery[]
* \_TopN[[Order[emp_no{f}#16,ASC,LAST]],1000[INTEGER],false]
@@ -144,12 +143,12 @@ public void testPushDownLimitPastSubqueryWithSort() {
UnionAll unionAll = as(limit.child(), UnionAll.class);
assertEquals(2, unionAll.children().size());
- EsqlProject child1 = as(unionAll.children().get(0), EsqlProject.class);
+ Project child1 = as(unionAll.children().get(0), Project.class);
Limit childLimit = as(child1.child(), Limit.class);
EsRelation relation = as(childLimit.child(), EsRelation.class);
assertEquals("test", relation.indexPattern());
- EsqlProject child2 = as(unionAll.children().get(1), EsqlProject.class);
+ Project child2 = as(unionAll.children().get(1), Project.class);
Subquery subquery = as(child2.child(), Subquery.class);
TopN topN = as(subquery.child(), TopN.class);
Filter childFilter = as(topN.child(), Filter.class);
@@ -166,12 +165,12 @@ public void testPushDownLimitPastSubqueryWithSort() {
*Limit[1000[INTEGER],false,false]
* \_UnionAll[[_meta_field{r}#28, emp_no{r}#29, first_name{r}#30, gender{r}#31, hire_date{r}#32, job{r}#33, job.raw{r}#34,
* languages{r}#35, last_name{r}#36, long_noidx{r}#37, salary{r}#38]]
- * |_EsqlProject[[_meta_field{f}#12, emp_no{f}#6, first_name{f}#7, gender{f}#8, hire_date{f}#13, job{f}#14, job.raw{f}#15,
+ * |_Project[[_meta_field{f}#12, emp_no{f}#6, first_name{f}#7, gender{f}#8, hire_date{f}#13, job{f}#14, job.raw{f}#15,
* languages{f}#9, last_name{f}#10, long_noidx{f}#16, salary{f}#11]]
* | \_Limit[1000[INTEGER],false,false]
* | \_Filter[emp_no{f}#6 > 10000[INTEGER]]
* | \_EsRelation[test][_meta_field{f}#12, emp_no{f}#6, first_name{f}#7, ge..]
- * \_EsqlProject[[_meta_field{f}#23, emp_no{f}#17, first_name{f}#18, gender{f}#19, hire_date{f}#24, job{f}#25, job.raw{f}#26,
+ * \_Project[[_meta_field{f}#23, emp_no{f}#17, first_name{f}#18, gender{f}#19, hire_date{f}#24, job{f}#25, job.raw{f}#26,
* languages{f}#20, last_name{f}#21, long_noidx{f}#27, salary{f}#22]]
* \_Subquery[]
* \_TopN[[Order[emp_no{f}#17,ASC,LAST]],1000[INTEGER],false]
@@ -188,7 +187,7 @@ public void testPushDownFilterAndLimitPastSubqueryWithSort() {
UnionAll unionAll = as(limit.child(), UnionAll.class);
assertEquals(2, unionAll.children().size());
- EsqlProject child1 = as(unionAll.children().get(0), EsqlProject.class);
+ Project child1 = as(unionAll.children().get(0), Project.class);
Limit childLimit = as(child1.child(), Limit.class);
Filter childFilter = as(childLimit.child(), Filter.class);
GreaterThan greaterThan = as(childFilter.condition(), GreaterThan.class);
@@ -199,7 +198,7 @@ public void testPushDownFilterAndLimitPastSubqueryWithSort() {
EsRelation relation = as(childFilter.child(), EsRelation.class);
assertEquals("test", relation.indexPattern());
- EsqlProject child2 = as(unionAll.children().get(1), EsqlProject.class);
+ Project child2 = as(unionAll.children().get(1), Project.class);
Subquery subquery = as(child2.child(), Subquery.class);
TopN topN = as(subquery.child(), TopN.class);
childFilter = as(topN.child(), Filter.class);
@@ -222,14 +221,14 @@ public void testPushDownFilterAndLimitPastSubqueryWithSort() {
*Limit[1000[INTEGER],false,false]
* \_UnionAll[[_meta_field{r}#46, emp_no{r}#47, first_name{r}#48, gender{r}#49, hire_date{r}#50, job{r}#51, job.raw{r}#52,
* languages{r}#53, last_name{r}#54, long_noidx{r}#55, salary{r}#56, language_code{r}#57, language_name{r}#58]]
- * |_EsqlProject[[_meta_field{f}#13, emp_no{f}#7, first_name{f}#8, gender{f}#9, hire_date{f}#14, job{f}#15, job.raw{f}#16,
+ * |_Project[[_meta_field{f}#13, emp_no{f}#7, first_name{f}#8, gender{f}#9, hire_date{f}#14, job{f}#15, job.raw{f}#16,
* languages{f}#10, last_name{f}#11, long_noidx{f}#17, salary{f}#12, language_code{r}#31,
* language_name{r}#32]]
* | \_Eval[[null[INTEGER] AS language_code#31, null[KEYWORD] AS language_name#32]]
* | \_Limit[1000[INTEGER],false,false]
* | \_Filter[emp_no{f}#7 > 10000[INTEGER] AND salary{f}#12 > 50000[INTEGER]]
* | \_EsRelation[test][_meta_field{f}#13, emp_no{f}#7, first_name{f}#8, ge..]
- * |_EsqlProject[[_meta_field{f}#24, emp_no{f}#18, first_name{f}#19, gender{f}#20, hire_date{f}#25, job{f}#26, job.raw{f}#27,
+ * |_Project[[_meta_field{f}#24, emp_no{f}#18, first_name{f}#19, gender{f}#20, hire_date{f}#25, job{f}#26, job.raw{f}#27,
* languages{f}#21, last_name{f}#22, long_noidx{f}#28, salary{f}#23, language_code{r}#33,
* language_name{r}#34]]
* | \_Eval[[null[INTEGER] AS language_code#33, null[KEYWORD] AS language_name#34]]
@@ -251,7 +250,7 @@ public void testPushDownConjunctiveFilterPastUnionAll() {
UnionAll unionAll = as(limit.child(), UnionAll.class);
assertEquals(3, unionAll.children().size());
- EsqlProject child1 = as(unionAll.children().get(0), EsqlProject.class);
+ Project child1 = as(unionAll.children().get(0), Project.class);
Eval eval = as(child1.child(), Eval.class);
Limit childLimit = as(eval.child(), Limit.class);
Filter childFilter = as(childLimit.child(), Filter.class);
@@ -269,7 +268,7 @@ public void testPushDownConjunctiveFilterPastUnionAll() {
EsRelation relation = as(childFilter.child(), EsRelation.class);
assertEquals("test", relation.indexPattern());
- EsqlProject child2 = as(unionAll.children().get(1), EsqlProject.class);
+ Project child2 = as(unionAll.children().get(1), Project.class);
eval = as(child2.child(), Eval.class);
Subquery subquery = as(eval.child(), Subquery.class);
childLimit = as(subquery.child(), Limit.class);
@@ -301,14 +300,14 @@ public void testPushDownConjunctiveFilterPastUnionAll() {
*Limit[1000[INTEGER],false,false]
* \_UnionAll[[_meta_field{r}#46, emp_no{r}#47, first_name{r}#48, gender{r}#49, hire_date{r}#50, job{r}#51, job.raw{r}#52,
* languages{r}#53, last_name{r}#54, long_noidx{r}#55, salary{r}#56, language_code{r}#57, language_name{r}#58]]
- * |_EsqlProject[[_meta_field{f}#13, emp_no{f}#7, first_name{f}#8, gender{f}#9, hire_date{f}#14, job{f}#15, job.raw{f}#16,
+ * |_Project[[_meta_field{f}#13, emp_no{f}#7, first_name{f}#8, gender{f}#9, hire_date{f}#14, job{f}#15, job.raw{f}#16,
* languages{f}#10, last_name{f}#11, long_noidx{f}#17, salary{f}#12, language_code{r}#31,
* language_name{r}#32]]
* | \_Eval[[null[INTEGER] AS language_code#31, null[KEYWORD] AS language_name#32]]
* | \_Limit[1000[INTEGER],false,false]
* | \_Filter[emp_no{f}#7 > 10000[INTEGER] OR salary{f}#12 > 50000[INTEGER]]
* | \_EsRelation[test][_meta_field{f}#13, emp_no{f}#7, first_name{f}#8, ge..]
- * |_EsqlProject[[_meta_field{f}#24, emp_no{f}#18, first_name{f}#19, gender{f}#20, hire_date{f}#25, job{f}#26, job.raw{f}#27,
+ * |_Project[[_meta_field{f}#24, emp_no{f}#18, first_name{f}#19, gender{f}#20, hire_date{f}#25, job{f}#26, job.raw{f}#27,
* languages{f}#21, last_name{f}#22, long_noidx{f}#28, salary{f}#23, language_code{r}#33,
* language_name{r}#34]]
* | \_Eval[[null[INTEGER] AS language_code#33, null[KEYWORD] AS language_name#34]]
@@ -330,7 +329,7 @@ public void testPushDownDisjunctiveFilterPastUnionAll() {
UnionAll unionAll = as(limit.child(), UnionAll.class);
assertEquals(3, unionAll.children().size());
- EsqlProject child1 = as(unionAll.children().get(0), EsqlProject.class);
+ Project child1 = as(unionAll.children().get(0), Project.class);
Eval eval = as(child1.child(), Eval.class);
Limit childLimit = as(eval.child(), Limit.class);
Filter childFilter = as(childLimit.child(), Filter.class);
@@ -348,7 +347,7 @@ public void testPushDownDisjunctiveFilterPastUnionAll() {
EsRelation relation = as(childFilter.child(), EsRelation.class);
assertEquals("test", relation.indexPattern());
- EsqlProject child2 = as(unionAll.children().get(1), EsqlProject.class);
+ Project child2 = as(unionAll.children().get(1), Project.class);
eval = as(child2.child(), Eval.class);
Subquery subquery = as(eval.child(), Subquery.class);
childLimit = as(subquery.child(), Limit.class);
@@ -380,14 +379,14 @@ public void testPushDownDisjunctiveFilterPastUnionAll() {
*Limit[1000[INTEGER],false,false]
* \_UnionAll[[_meta_field{r}#46, emp_no{r}#47, first_name{r}#48, gender{r}#49, hire_date{r}#50, job{r}#51, job.raw{r}#52,
* languages{r}#53, last_name{r}#54, long_noidx{r}#55, salary{r}#56, language_code{r}#57, language_name{r}#58]]
- * |_EsqlProject[[_meta_field{f}#13, emp_no{f}#7, first_name{f}#8, gender{f}#9, hire_date{f}#14, job{f}#15, job.raw{f}#16,
+ * |_Project[[_meta_field{f}#13, emp_no{f}#7, first_name{f}#8, gender{f}#9, hire_date{f}#14, job{f}#15, job.raw{f}#16,
* languages{f}#10, last_name{f}#11, long_noidx{f}#17, salary{f}#12, language_code{r}#31,
* language_name{r}#32]]
* | \_Eval[[null[INTEGER] AS language_code#31, null[KEYWORD] AS language_name#32]]
* | \_Limit[1000[INTEGER],false,false]
* | \_Filter[emp_no{f}#7 > 10000[INTEGER] AND salary{f}#12 < 50000[INTEGER]]
* | \_EsRelation[test][_meta_field{f}#13, emp_no{f}#7, first_name{f}#8, ge..]
- * |_EsqlProject[[_meta_field{f}#24, emp_no{f}#18, first_name{f}#19, gender{f}#20, hire_date{f}#25, job{f}#26, job.raw{f}#27,
+ * |_Project[[_meta_field{f}#24, emp_no{f}#18, first_name{f}#19, gender{f}#20, hire_date{f}#25, job{f}#26, job.raw{f}#27,
* languages{f}#21, last_name{f}#22, long_noidx{f}#28, salary{f}#23, language_code{r}#33,
* language_name{r}#34]]
* | \_Eval[[null[INTEGER] AS language_code#33, null[KEYWORD] AS language_name#34]]
@@ -409,7 +408,7 @@ public void testPushDownFilterPastUnionAllAndCombineWithFilterInSubquery() {
UnionAll unionAll = as(limit.child(), UnionAll.class);
assertEquals(3, unionAll.children().size());
- EsqlProject child1 = as(unionAll.children().get(0), EsqlProject.class);
+ Project child1 = as(unionAll.children().get(0), Project.class);
Eval eval = as(child1.child(), Eval.class);
Limit childLimit = as(eval.child(), Limit.class);
Filter childFilter = as(childLimit.child(), Filter.class);
@@ -427,7 +426,7 @@ public void testPushDownFilterPastUnionAllAndCombineWithFilterInSubquery() {
EsRelation relation = as(childFilter.child(), EsRelation.class);
assertEquals("test", relation.indexPattern());
- EsqlProject child2 = as(unionAll.children().get(1), EsqlProject.class);
+ Project child2 = as(unionAll.children().get(1), Project.class);
eval = as(child2.child(), Eval.class);
Subquery subquery = as(eval.child(), Subquery.class);
childLimit = as(subquery.child(), Limit.class);
@@ -461,7 +460,7 @@ public void testPushDownFilterPastUnionAllAndCombineWithFilterInSubquery() {
* languages{f}#48, last_name{f}#49, long_noidx{f}#55, salary{f}#50, x{r}#82,
* $$x$converted_to$long{r}#117, y{r}#127, $$y$converted_to$long{r}#118, z{r}#84,
* language_name{r}#85],EMPTY]
- * |_EsqlProject[[_meta_field{f}#62, emp_no{f}#56, first_name{f}#57, gender{f}#58, hire_date{f}#63, job{f}#64, job.raw{f}#65,
+ * |_Project[[_meta_field{f}#62, emp_no{f}#56, first_name{f}#57, gender{f}#58, hire_date{f}#63, job{f}#64, job.raw{f}#65,
* languages{f}#59, last_name{f}#60, long_noidx{f}#66, salary{f}#61, x{r}#5, $$x$converted_to$long{r}#119,
* y{r}#128, $$y$converted_to$long{r}#120, z{r}#11, language_name{r}#86]]
* | \_Filter[ISNOTNULL($$y$converted_to$long{r}#120)]
@@ -475,7 +474,7 @@ public void testPushDownFilterPastUnionAllAndCombineWithFilterInSubquery() {
* | \_Eval[[1[INTEGER] AS x#5, emp_no{f}#56 + 1[INTEGER] AS z#11]]
* | \_Filter[salary{f}#61 < 100000[INTEGER]]
* | \_EsRelation[test][_meta_field{f}#62, emp_no{f}#56, first_name{f}#57, ..]
- * |_EsqlProject[[_meta_field{r}#87, emp_no{r}#88, first_name{r}#89, gender{r}#90, hire_date{r}#91, job{r}#92, job.raw{r}#93,
+ * |_Project[[_meta_field{r}#87, emp_no{r}#88, first_name{r}#89, gender{r}#90, hire_date{r}#91, job{r}#92, job.raw{r}#93,
* languages{r}#94, last_name{r}#95, long_noidx{r}#96, salary{r}#97, x{r}#22, $$x$converted_to$long{r}#121,
* y{r}#129, $$y$converted_to$long{r}#122, z{r}#17, language_name{r}#98]]
* | \_Filter[ISNOTNULL($$y$converted_to$long{r}#122)]
@@ -490,7 +489,7 @@ public void testPushDownFilterPastUnionAllAndCombineWithFilterInSubquery() {
* | \_Filter[z{r}#17 > 0[INTEGER]]
* | \_Aggregate[[language_code{f}#67],[COUNT(*[KEYWORD],true[BOOLEAN]) AS y#20, language_code{f}#67 AS z#17]]
* | \_EsRelation[languages][language_code{f}#67, language_name{f}#68]
- * \_EsqlProject[[_meta_field{f}#75, emp_no{r}#99, first_name{f}#70, gender{f}#71, hire_date{f}#76, job{f}#77, job.raw{f}#78,
+ * \_Project[[_meta_field{f}#75, emp_no{r}#99, first_name{f}#70, gender{f}#71, hire_date{f}#76, job{f}#77, job.raw{f}#78,
* languages{r}#100, last_name{f}#73, long_noidx{f}#79, salary{r}#101, x{r}#29,
* $$x$converted_to$long{r}#123, y{r}#130, $$y$converted_to$long{r}#124, z{r}#35, language_name{f}#81]]
* \_Filter[ISNOTNULL($$x$converted_to$long{r}#123) AND ISNOTNULL($$y$converted_to$long{r}#124)]
@@ -535,7 +534,7 @@ public void testPushDownFilterOnReferenceAttributesPastUnionAll() {
LocalRelation child1 = as(unionAll.children().get(0), LocalRelation.class);
- EsqlProject child2 = as(unionAll.children().get(1), EsqlProject.class);
+ Project child2 = as(unionAll.children().get(1), Project.class);
Filter filter = as(child2.child(), Filter.class);
IsNotNull isNotNull = as(filter.condition(), IsNotNull.class);
ReferenceAttribute y = as(isNotNull.field(), ReferenceAttribute.class);
@@ -574,7 +573,7 @@ public void testPushDownFilterOnReferenceAttributesPastUnionAll() {
EsRelation relation = as(childFilter.child(), EsRelation.class);
assertEquals("test", relation.indexPattern());
- EsqlProject child3 = as(unionAll.children().get(2), EsqlProject.class);
+ Project child3 = as(unionAll.children().get(2), Project.class);
filter = as(child3.child(), Filter.class);
isNotNull = as(filter.condition(), IsNotNull.class);
y = as(isNotNull.field(), ReferenceAttribute.class);
@@ -601,7 +600,7 @@ public void testPushDownFilterOnReferenceAttributesPastUnionAll() {
relation = as(aggregate.child(), EsRelation.class);
assertEquals("languages", relation.indexPattern());
- EsqlProject child4 = as(unionAll.children().get(3), EsqlProject.class);
+ Project child4 = as(unionAll.children().get(3), Project.class);
filter = as(child4.child(), Filter.class);
And and = as(filter.condition(), And.class);
isNotNull = as(and.left(), IsNotNull.class);
@@ -636,7 +635,7 @@ public void testPushDownFilterOnReferenceAttributesPastUnionAll() {
* languages{r}#43, last_name{r}#44, long_noidx{r}#45, salary{r}#46, x{r}#47, y{r}#48]]
* |_LocalRelation[[_meta_field{f}#18, emp_no{f}#12, first_name{f}#13, gender{f}#14, hire_date{f}#19, job{f}#20, job.raw{f}#21,
* languages{f}#15, last_name{f}#16, long_noidx{f}#22, salary{f}#17, x{r}#34, y{r}#35],EMPTY]
- * \_EsqlProject[[_meta_field{f}#29, emp_no{f}#23, first_name{f}#24, gender{f}#25, hire_date{f}#30, job{f}#31, job.raw{f}#32,
+ * \_Project[[_meta_field{f}#29, emp_no{f}#23, first_name{f}#24, gender{f}#25, hire_date{f}#30, job{f}#31, job.raw{f}#32,
* languages{f}#26, last_name{f}#27, long_noidx{f}#33, salary{f}#28, x{r}#5, y{r}#8]]
* \_Subquery[]
* \_Limit[1000[INTEGER],false,false]
@@ -657,7 +656,7 @@ public void testPushDownFilterOnReferenceAttributesAndFieldAttributesPastUnionAl
LocalRelation child1 = as(unionAll.children().get(0), LocalRelation.class);
- EsqlProject child2 = as(unionAll.children().get(1), EsqlProject.class);
+ Project child2 = as(unionAll.children().get(1), Project.class);
Subquery subquery = as(child2.child(), Subquery.class);
Limit childLimit = as(subquery.child(), Limit.class);
Filter childFilter = as(childLimit.child(), Filter.class);
@@ -707,7 +706,7 @@ public void testPushDownFilterOnReferenceAttributesAndFieldAttributesPastUnionAl
* birth_date{r}#79, height{r}#80, height.double{r}#81, height.half_float{r}#82, height.scaled_float{r}#83,
* is_rehired{r}#84, job_positions{r}#85, languages.int{r}#86, languages.long{r}#87, languages.short{r}#88,
* salary_change{r}#89, still_hired{r}#90]]
- * |_EsqlProject[[_meta_field{f}#25, emp_no{r}#100, $$emp_no$converted_to$double{r}#91, $$emp_no$converted_to$long{r}#92,
+ * |_Project[[_meta_field{f}#25, emp_no{r}#100, $$emp_no$converted_to$double{r}#91, $$emp_no$converted_to$long{r}#92,
* first_name{r}#101, gender{f}#21, $$gender$converted_to$keyword{r}#93, hire_date{r}#102, job{f}#27,
* job.raw{f}#28, languages{f}#22, last_name{r}#103, long_noidx{f}#29, salary{r}#104,
* avg_worked_seconds{r}#50, birth_date{r}#51, height{r}#52, height.double{r}#53,
@@ -771,7 +770,7 @@ public void testFilterOnMixedDataTypesFields() {
UnionAll unionAll = as(filter.child(), UnionAll.class);
assertEquals(2, unionAll.children().size());
- EsqlProject child1 = as(unionAll.children().get(0), EsqlProject.class);
+ Project child1 = as(unionAll.children().get(0), Project.class);
Eval eval = as(child1.child(), Eval.class);
limit = as(eval.child(), Limit.class);
EsRelation relation = as(limit.child(), EsRelation.class);
@@ -795,12 +794,12 @@ public void testFilterOnMixedDataTypesFields() {
* Limit[1000[INTEGER],false,false]
* \_UnionAll[[_meta_field{r}#27, emp_no{r}#28, first_name{r}#29, gender{r}#30, hire_date{r}#31, job{r}#32, job.raw{r}#33,
* languages{r}#34, last_name{r}#35, long_noidx{r}#36, salary{r}#37]]
- * |_EsqlProject[[_meta_field{f}#11, emp_no{f}#5, first_name{f}#6, gender{f}#7, hire_date{f}#12, job{f}#13, job.raw{f}#14,
+ * |_Project[[_meta_field{f}#11, emp_no{f}#5, first_name{f}#6, gender{f}#7, hire_date{f}#12, job{f}#13, job.raw{f}#14,
* languages{f}#8, last_name{f}#9, long_noidx{f}#15, salary{f}#10]]
* | \_Limit[1000[INTEGER],false,false]
* | \_Filter[:(first_name{f}#6,first[KEYWORD])]
* | \_EsRelation[test][_meta_field{f}#11, emp_no{f}#5, first_name{f}#6, ge..]
- * \_EsqlProject[[_meta_field{f}#22, emp_no{f}#16, first_name{f}#17, gender{f}#18, hire_date{f}#23, job{f}#24, job.raw{f}#25,
+ * \_Project[[_meta_field{f}#22, emp_no{f}#16, first_name{f}#17, gender{f}#18, hire_date{f}#23, job{f}#24, job.raw{f}#25,
* languages{f}#19, last_name{f}#20, long_noidx{f}#26, salary{f}#21]]
* \_Subquery[]
* \_Limit[1000[INTEGER],false,false]
@@ -817,7 +816,7 @@ public void testPushDownSingleFullTextFunctionPastUnionAll() {
UnionAll unionAll = as(limit.child(), UnionAll.class);
assertEquals(2, unionAll.children().size());
- EsqlProject child1 = as(unionAll.children().get(0), EsqlProject.class);
+ Project child1 = as(unionAll.children().get(0), Project.class);
Limit childLimit = as(child1.child(), Limit.class);
Filter childFilter = as(childLimit.child(), Filter.class);
MatchOperator match = as(childFilter.condition(), MatchOperator.class);
@@ -828,7 +827,7 @@ public void testPushDownSingleFullTextFunctionPastUnionAll() {
EsRelation relation = as(childFilter.child(), EsRelation.class);
assertEquals("test", relation.indexPattern());
- EsqlProject child2 = as(unionAll.children().get(1), EsqlProject.class);
+ Project child2 = as(unionAll.children().get(1), Project.class);
Subquery subquery = as(child2.child(), Subquery.class);
childLimit = as(subquery.child(), Limit.class);
childFilter = as(childLimit.child(), Filter.class);
@@ -851,12 +850,12 @@ public void testPushDownSingleFullTextFunctionPastUnionAll() {
* Limit[1000[INTEGER],false,false]
* \_UnionAll[[_meta_field{r}#26, emp_no{r}#27, first_name{r}#28, gender{r}#29, hire_date{r}#30, job{r}#31, job.raw{r}#32,
* languages{r}#33, last_name{r}#34, long_noidx{r}#35, salary{r}#36]]
- * |_EsqlProject[[_meta_field{f}#10, emp_no{f}#4, first_name{f}#5, gender{f}#6, hire_date{f}#11, job{f}#12, job.raw{f}#13,
+ * |_Project[[_meta_field{f}#10, emp_no{f}#4, first_name{f}#5, gender{f}#6, hire_date{f}#11, job{f}#12, job.raw{f}#13,
* languages{f}#7, last_name{f}#8, long_noidx{f}#14, salary{f}#9]]
* | \_Limit[1000[INTEGER],false,false]
* | \_Filter[QSTR(first_name:first[KEYWORD]) AND KQL(last_name:last[KEYWORD])]
* | \_EsRelation[test][_meta_field{f}#10, emp_no{f}#4, first_name{f}#5, ge..]
- * \_EsqlProject[[_meta_field{f}#21, emp_no{f}#15, first_name{f}#16, gender{f}#17, hire_date{f}#22, job{f}#23, job.raw{f}#24,
+ * \_Project[[_meta_field{f}#21, emp_no{f}#15, first_name{f}#16, gender{f}#17, hire_date{f}#22, job{f}#23, job.raw{f}#24,
* languages{f}#18, last_name{f}#19, long_noidx{f}#25, salary{f}#20]]
* \_Subquery[]
* \_Limit[1000[INTEGER],false,false]
@@ -874,7 +873,7 @@ public void testPushDownFullTextFunctionNoFieldRequiredPastUnionAll() {
UnionAll unionAll = as(limit.child(), UnionAll.class);
assertEquals(2, unionAll.children().size());
- EsqlProject child1 = as(unionAll.children().get(0), EsqlProject.class);
+ Project child1 = as(unionAll.children().get(0), Project.class);
Limit childLimit = as(child1.child(), Limit.class);
Filter childFilter = as(childLimit.child(), Filter.class);
And and = as(childFilter.condition(), And.class);
@@ -888,7 +887,7 @@ public void testPushDownFullTextFunctionNoFieldRequiredPastUnionAll() {
EsRelation relation = as(childFilter.child(), EsRelation.class);
assertEquals("test", relation.indexPattern());
- EsqlProject child2 = as(unionAll.children().get(1), EsqlProject.class);
+ Project child2 = as(unionAll.children().get(1), Project.class);
Subquery subquery = as(child2.child(), Subquery.class);
childLimit = as(subquery.child(), Limit.class);
childFilter = as(childLimit.child(), Filter.class);
@@ -918,12 +917,12 @@ public void testPushDownFullTextFunctionNoFieldRequiredPastUnionAll() {
* Limit[1000[INTEGER],false,false]
* \_UnionAll[[_meta_field{r}#28, emp_no{r}#29, first_name{r}#30, gender{r}#31, hire_date{r}#32, job{r}#33, job.raw{r}#34,
* languages{r}#35, last_name{r}#36, long_noidx{r}#37, salary{r}#38]]
- * |_EsqlProject[[_meta_field{f}#12, emp_no{f}#6, first_name{f}#7, gender{f}#8, hire_date{f}#13, job{f}#14, job.raw{f}#15,
+ * |_Project[[_meta_field{f}#12, emp_no{f}#6, first_name{f}#7, gender{f}#8, hire_date{f}#13, job{f}#14, job.raw{f}#15,
* languages{f}#9, last_name{f}#10, long_noidx{f}#16, salary{f}#11]]
* | \_Limit[1000[INTEGER],false,false]
* | \_Filter[:(first_name{f}#7,first[KEYWORD]) AND MATCH(last_name{f}#10,last[KEYWORD]) AND QSTR(gender:female[KEYWORD])]
* | \_EsRelation[test][_meta_field{f}#12, emp_no{f}#6, first_name{f}#7, ge..]
- * \_EsqlProject[[_meta_field{f}#23, emp_no{f}#17, first_name{f}#18, gender{f}#19, hire_date{f}#24, job{f}#25, job.raw{f}#26,
+ * \_Project[[_meta_field{f}#23, emp_no{f}#17, first_name{f}#18, gender{f}#19, hire_date{f}#24, job{f}#25, job.raw{f}#26,
* languages{f}#20, last_name{f}#21, long_noidx{f}#27, salary{f}#22]]
* \_Subquery[]
* \_Limit[1000[INTEGER],false,false]
@@ -941,7 +940,7 @@ public void testPushDownConjunctiveFullTextFunctionPastUnionAll() {
UnionAll unionAll = as(limit.child(), UnionAll.class);
assertEquals(2, unionAll.children().size());
- EsqlProject child1 = as(unionAll.children().get(0), EsqlProject.class);
+ Project child1 = as(unionAll.children().get(0), Project.class);
Limit childLimit = as(child1.child(), Limit.class);
Filter childFilter = as(childLimit.child(), Filter.class);
And and = as(childFilter.condition(), And.class);
@@ -962,7 +961,7 @@ public void testPushDownConjunctiveFullTextFunctionPastUnionAll() {
EsRelation relation = as(childFilter.child(), EsRelation.class);
assertEquals("test", relation.indexPattern());
- EsqlProject child2 = as(unionAll.children().get(1), EsqlProject.class);
+ Project child2 = as(unionAll.children().get(1), Project.class);
Subquery subquery = as(child2.child(), Subquery.class);
childLimit = as(subquery.child(), Limit.class);
childFilter = as(childLimit.child(), Filter.class);
@@ -995,12 +994,12 @@ public void testPushDownConjunctiveFullTextFunctionPastUnionAll() {
* Limit[1000[INTEGER],false,false]
* \_UnionAll[[_meta_field{r}#29, emp_no{r}#30, first_name{r}#31, gender{r}#32, hire_date{r}#33, job{r}#34, job.raw{r}#35,
* languages{r}#36, last_name{r}#37, long_noidx{r}#38, salary{r}#39]]
- * |_EsqlProject[[_meta_field{f}#13, emp_no{f}#7, first_name{f}#8, gender{f}#9, hire_date{f}#14, job{f}#15, job.raw{f}#16,
+ * |_Project[[_meta_field{f}#13, emp_no{f}#7, first_name{f}#8, gender{f}#9, hire_date{f}#14, job{f}#15, job.raw{f}#16,
* languages{f}#10, last_name{f}#11, long_noidx{f}#17, salary{f}#12]]
* | \_Limit[1000[INTEGER],false,false]
* | \_Filter[:(first_name{f}#8,first[KEYWORD]) OR MatchPhrase(last_name{f}#11,last[KEYWORD]) OR KQL(gender:female[KEYWORD])]
* | \_EsRelation[test][_meta_field{f}#13, emp_no{f}#7, first_name{f}#8, ge..]
- * \_EsqlProject[[_meta_field{f}#24, emp_no{f}#18, first_name{f}#19, gender{f}#20, hire_date{f}#25, job{f}#26, job.raw{f}#27,
+ * \_Project[[_meta_field{f}#24, emp_no{f}#18, first_name{f}#19, gender{f}#20, hire_date{f}#25, job{f}#26, job.raw{f}#27,
* languages{f}#21, last_name{f}#22, long_noidx{f}#28, salary{f}#23]]
* \_Subquery[]
* \_Limit[1000[INTEGER],false,false]
@@ -1018,7 +1017,7 @@ public void testPushDownDisjunctiveFullTextFunctionPastUnionAll() {
UnionAll unionAll = as(limit.child(), UnionAll.class);
assertEquals(2, unionAll.children().size());
- EsqlProject child1 = as(unionAll.children().get(0), EsqlProject.class);
+ Project child1 = as(unionAll.children().get(0), Project.class);
Limit childLimit = as(child1.child(), Limit.class);
Filter childFilter = as(childLimit.child(), Filter.class);
Or or = as(childFilter.condition(), Or.class);
@@ -1039,7 +1038,7 @@ public void testPushDownDisjunctiveFullTextFunctionPastUnionAll() {
EsRelation relation = as(childFilter.child(), EsRelation.class);
assertEquals("test", relation.indexPattern());
- EsqlProject child2 = as(unionAll.children().get(1), EsqlProject.class);
+ Project child2 = as(unionAll.children().get(1), Project.class);
Subquery subquery = as(child2.child(), Subquery.class);
childLimit = as(subquery.child(), Limit.class);
childFilter = as(childLimit.child(), Filter.class);
@@ -1093,7 +1092,7 @@ public void testFullTextFunctionCanBePushedDownPastUnionAll() {
LocalRelation child1 = as(unionAll.children().get(0), LocalRelation.class);
// Second child: languages subquery with MATCH filter pushed down
- EsqlProject child2 = as(unionAll.children().get(1), EsqlProject.class);
+ Project child2 = as(unionAll.children().get(1), Project.class);
Eval eval2 = as(child2.child(), Eval.class);
List aliases = eval2.fields();
assertEquals(11, aliases.size());
diff --git a/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/optimizer/rules/logical/ReplaceAliasingEvalWithProjectTests.java b/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/optimizer/rules/logical/ReplaceAliasingEvalWithProjectTests.java
index 0c204a4687a7b..e6736bcacff03 100644
--- a/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/optimizer/rules/logical/ReplaceAliasingEvalWithProjectTests.java
+++ b/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/optimizer/rules/logical/ReplaceAliasingEvalWithProjectTests.java
@@ -29,7 +29,7 @@
public class ReplaceAliasingEvalWithProjectTests extends AbstractLogicalPlanOptimizerTests {
/**
* {@code
- * EsqlProject[[emp_no{f}#18, salary{f}#23, emp_no{f}#18 AS emp_no2#7, salary2{r}#10, emp_no{f}#18 AS emp_no3#13, salary3{r}#16]]
+ * Project[[emp_no{f}#18, salary{f}#23, emp_no{f}#18 AS emp_no2#7, salary2{r}#10, emp_no{f}#18 AS emp_no3#13, salary3{r}#16]]
* \_Eval[[salary{f}#23 * 2[INTEGER] AS salary2#10, salary2{r}#10 * 3[INTEGER] AS salary3#16]]
* \_Limit[1000[INTEGER],false,false]
* \_EsRelation[test][_meta_field{f}#24, emp_no{f}#18, first_name{f}#19, ..]
@@ -76,7 +76,7 @@ public void testSimple() {
/**
* {@code
- * EsqlProject[[emp_no{f}#19, salary{f}#35, emp_no{f}#19 AS emp_no2#8, salary2{r}#11, emp_no{f}#19 AS emp_no3#14, salary3{r}#17]]
+ * Project[[emp_no{f}#19, salary{f}#35, emp_no{f}#19 AS emp_no2#8, salary2{r}#11, emp_no{f}#19 AS emp_no3#14, salary3{r}#17]]
* \_Eval[[salary{f}#35 * 2[INTEGER] AS salary2#11, salary2{r}#11 * 3[INTEGER] AS salary3#17]]
* \_Limit[1000[INTEGER],true,false]
* \_Join[LEFT,[emp_no{f}#19],[emp_no{f}#30],null]
@@ -127,7 +127,7 @@ public void testSimpleFieldFromLookup() {
/**
* {@code
- * EsqlProject[[emp_no{f}#24 AS emp_no2#7, salary{f}#29 AS salary2#10, emp_no{f}#24 AS emp_no3#13, emp_no{f}#24 AS salary#16,
+ * Project[[emp_no{f}#24 AS emp_no2#7, salary{f}#29 AS salary2#10, emp_no{f}#24 AS emp_no3#13, emp_no{f}#24 AS salary#16,
* salary{f}#29 AS salary3#19, salary{f}#29 AS emp_no#22]]
* \_Limit[1000[INTEGER],false,false]
* \_EsRelation[test][_meta_field{f}#30, emp_no{f}#24, first_name{f}#25, ..]
@@ -160,7 +160,7 @@ public void testOnlyAliases() {
/**
* {@code
- * EsqlProject[[emp_no{f}#26 AS b#21, emp_no{f}#26 AS a#24]]
+ * Project[[emp_no{f}#26 AS b#21, emp_no{f}#26 AS a#24]]
* \_Limit[1000[INTEGER],false,false]
* \_EsRelation[test][_meta_field{f}#32, emp_no{f}#26, first_name{f}#27, ..]
* }
@@ -188,7 +188,7 @@ public void testAliasLoopTwoVars() {
/**
* {@code
- * EsqlProject[[emp_no{f}#17 AS b#9, emp_no{f}#17 AS c#12, emp_no{f}#17 AS a#15]]
+ * Project[[emp_no{f}#17 AS b#9, emp_no{f}#17 AS c#12, emp_no{f}#17 AS a#15]]
* \_Limit[1000[INTEGER],false,false]
* \_EsRelation[test][_meta_field{f}#23, emp_no{f}#17, first_name{f}#18, ..]
* }
@@ -217,7 +217,7 @@ public void testAliasLoopThreeVars() {
/**
* {@code
- * EsqlProject[[salary{f}#23, emp_no{f}#18 AS emp_no2#7, $$emp_no$temp_name$29{r}#30 AS emp_no#10,
+ * Project[[salary{f}#23, emp_no{f}#18 AS emp_no2#7, $$emp_no$temp_name$29{r}#30 AS emp_no#10,
* emp_no{f}#18 AS emp_no3#13, salary3{r}#16]]
* \_Eval[[salary{f}#23 * 2[INTEGER] AS $$emp_no$temp_name$29#30, $$emp_no$temp_name$29{r$}#30 * 2[INTEGER] AS salary3#16]]
* \_Limit[1000[INTEGER],false,false]
@@ -303,7 +303,7 @@ public void testNonAliasShadowingAliasedAttributeWithAgg() {
/**
* {@code
- * EsqlProject[[salary{f}#35, emp_no{f}#30 AS emp_no2#22, $$id$temp_name$41{r$}#42 AS emp_no#25, emp_no{f}#30 AS emp_no3#28,
+ * Project[[salary{f}#35, emp_no{f}#30 AS emp_no2#22, $$id$temp_name$41{r$}#42 AS emp_no#25, emp_no{f}#30 AS emp_no3#28,
* salary3{r}#19]]
* \_Eval[[salary{f}#35 * 2[INTEGER] AS $$id$temp_name$41#42, $$id$temp_name$41{r$}#42 * 2[INTEGER] AS salary3#19]]
* \_Limit[1000[INTEGER],false,false]
@@ -349,7 +349,7 @@ public void testNonAliasShadowingAliasedAttributeWithRename() {
/**
* {@code
- * EsqlProject[[emp_no{f}#18, salary{f}#23, emp_no{f}#18 AS emp_no3#10, emp_no2{r}#13, salary3{r}#16]]
+ * Project[[emp_no{f}#18, salary{f}#23, emp_no{f}#18 AS emp_no3#10, emp_no2{r}#13, salary3{r}#16]]
* \_Eval[[salary{f}#23 * 2[INTEGER] AS emp_no2#13, emp_no2{r}#13 * 3[INTEGER] AS salary3#16]]
* \_Limit[1000[INTEGER],false,false]
* \_EsRelation[test][_meta_field{f}#24, emp_no{f}#18, first_name{f}#19, ..]
@@ -385,7 +385,7 @@ public void testNonAliasShadowingAliasOfAliasedAttribute() {
/**
* {@code
- * EsqlProject[[emp_no{f}#24, salary{f}#29, emp_no{f}#24 AS emp_no3#13, salary{f}#29 AS salary3#16,
+ * Project[[emp_no{f}#24, salary{f}#29, emp_no{f}#24 AS emp_no3#13, salary{f}#29 AS salary3#16,
* salary{f}#29 AS emp_no2#19, emp_no{f}#24 AS salary2#22]]
* \_Limit[1000[INTEGER],false,false]
* \_EsRelation[test][_meta_field{f}#30, emp_no{f}#24, first_name{f}#25, ..]
@@ -417,7 +417,7 @@ public void testAliasShadowingOtherAlias() {
/**
* {@code
- * EsqlProject[[salary{f}#22, salary2{r}#6, salary2{r}#6 AS aliased_salary2#9, salary3{r}#12, salary2{r}#6 AS twice_aliased_salary2#15]]
+ * Project[[salary{f}#22, salary2{r}#6, salary2{r}#6 AS aliased_salary2#9, salary3{r}#12, salary2{r}#6 AS twice_aliased_salary2#15]]
* \_Eval[[salary{f}#22 * 2[INTEGER] AS salary2#6, salary2{r}#6 * 3[INTEGER] AS salary3#12]]
* \_Limit[1000[INTEGER],false,false]
* \_EsRelation[test][_meta_field{f}#23, emp_no{f}#17, first_name{f}#18, ..]
@@ -452,7 +452,7 @@ public void testAliasForNonAlias() {
/**
* {@code
- * EsqlProject[[salary{f}#25, salary2{r}#6 AS aliased_salary2#9, $$salary2$temp_name$31{r$}#32 AS salary2#12, salary3{r}#15,
+ * Project[[salary{f}#25, salary2{r}#6 AS aliased_salary2#9, $$salary2$temp_name$31{r$}#32 AS salary2#12, salary3{r}#15,
* salary3{r}#15 AS salary4#18]]
* \_Eval[[salary{f}#25 * 2[INTEGER] AS salary2#6, salary2{r}#6 * 3[INTEGER] AS $$salary2$temp_name$31#32,
* $$salary2$temp_name$31{r$}#32 * 4[INTEGER] AS salary3#15]]
diff --git a/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/optimizer/rules/logical/ReplaceStatsFilteredAggWithEvalTests.java b/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/optimizer/rules/logical/ReplaceStatsFilteredAggWithEvalTests.java
index c6ff818246e38..dac060dca0617 100644
--- a/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/optimizer/rules/logical/ReplaceStatsFilteredAggWithEvalTests.java
+++ b/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/optimizer/rules/logical/ReplaceStatsFilteredAggWithEvalTests.java
@@ -24,7 +24,6 @@
import org.elasticsearch.xpack.esql.plan.logical.TopN;
import org.elasticsearch.xpack.esql.plan.logical.join.InlineJoin;
import org.elasticsearch.xpack.esql.plan.logical.join.StubRelation;
-import org.elasticsearch.xpack.esql.plan.logical.local.EsqlProject;
import org.elasticsearch.xpack.esql.plan.logical.local.LocalRelation;
import static org.elasticsearch.test.ListMatcher.matchesList;
@@ -473,7 +472,7 @@ public void testReplaceInlineStatsFilteredAggWithEvalSingleAggWithExpression() {
/*
* Limit[1000[INTEGER],false]
* \_InlineJoin[LEFT,[emp_no{f}#9],[emp_no{f}#9],[emp_no{r}#9]]
- * |_EsqlProject[[salary{f}#14, emp_no{f}#9]]
+ * |_Project[[salary{f}#14, emp_no{f}#9]]
* | \_EsRelation[test][_meta_field{f}#15, emp_no{f}#9, first_name{f}#10, g..]
* \_Project[[sum(salary) 1 where false{r}#5, sum(salary) 2{r}#7, emp_no{f}#9]]
* \_Eval[[null[LONG] AS sum(salary) 1 where false#5, $$SUM$sum(salary)_ _2$1{r$}#21 2[INTEGER] AS sum(salary) 2#7]]
@@ -494,7 +493,7 @@ public void testReplaceInlineStatsFilteredAggWithEvalMixedFilterAndNoFilter() {
var plan = plan(query);
var limit = as(plan, Limit.class);
var ij = as(limit.child(), InlineJoin.class);
- var left = as(ij.left(), EsqlProject.class);
+ var left = as(ij.left(), Project.class);
assertThat(Expressions.names(left.projections()), contains("salary", "emp_no"));
var relation = as(left.child(), EsRelation.class);
var right = as(ij.right(), Project.class);
@@ -525,7 +524,7 @@ public void testReplaceInlineStatsFilteredAggWithEvalMixedFilterAndNoFilter() {
/**
* Limit[1000[INTEGER],true]
* \_InlineJoin[LEFT,[],[],[]]
- * |_EsqlProject[[salary{f}#16]]
+ * |_Project[[salary{f}#16]]
* | \_Limit[1000[INTEGER],false]
* | \_EsRelation[test][_meta_field{f}#17, emp_no{f}#11, first_name{f}#12, ..]
* \_Project[[sum(salary) 1 where false{r}#4, sum(salary) 3{r}#6, sum(salary) 2 where null{r}#8, sum(salary) 4 wher
@@ -584,7 +583,7 @@ public void testReplaceInlineStatsFilteredAggWithEvalFilterFalseAndNull() {
}
/**
- * EsqlProject[[emp_no{f}#6, salary{f}#11, count(salary) where not true{r}#5]]
+ * Project[[emp_no{f}#6, salary{f}#11, count(salary) where not true{r}#5]]
* \_Eval[[0[LONG] AS count(salary) where not true#5]]
* \_Limit[1000[INTEGER],false]
* \_EsRelation[test][_meta_field{f}#12, emp_no{f}#6, first_name{f}#7, ge..]
@@ -599,7 +598,7 @@ public void testReplaceInlineStatsFilteredAggWithEvalNotTrue() {
return;
}
var plan = plan(query);
- var project = as(plan, EsqlProject.class);
+ var project = as(plan, Project.class);
assertThat(Expressions.names(project.projections()), contains("emp_no", "salary", "count(salary) where not true"));
var eval = as(project.child(), Eval.class);
@@ -616,7 +615,7 @@ public void testReplaceInlineStatsFilteredAggWithEvalNotTrue() {
/*
* Limit[1000[INTEGER],true]
* \_InlineJoin[LEFT,[],[],[]]
- * |_EsqlProject[[emp_no{f}#8, salary{f}#13, gender{f}#10]]
+ * |_Project[[emp_no{f}#8, salary{f}#13, gender{f}#10]]
* | \_EsRelation[test][_meta_field{f}#14, emp_no{f}#8, first_name{f}#9, ge..]
* \_Aggregate[[],[COUNT(salary{f}#13,true[BOOLEAN]) AS m1#7]]
* \_StubRelation[[emp_no{f}#8, salary{f}#13, gender{f}#10]]
@@ -634,7 +633,7 @@ public void testReplaceInlineStatsFilteredAggWithEvalNotFalse() {
var limit = as(plan, Limit.class);
var ij = as(limit.child(), InlineJoin.class);
- var left = as(ij.left(), EsqlProject.class);
+ var left = as(ij.left(), Project.class);
assertThat(Expressions.names(left.projections()), contains("emp_no", "salary", "gender"));
var relation = as(left.child(), EsRelation.class);
@@ -649,7 +648,7 @@ public void testReplaceInlineStatsFilteredAggWithEvalNotFalse() {
}
/**
- * EsqlProject[[salary{f}#10, count(salary) where false{r}#4]]
+ * Project[[salary{f}#10, count(salary) where false{r}#4]]
* \_Eval[[0[LONG] AS count(salary) where false#4]]
* \_Limit[1000[INTEGER],false]
* \_EsRelation[test][_meta_field{f}#11, emp_no{f}#5, first_name{f}#6, ge..]
@@ -664,7 +663,7 @@ public void testReplaceInlineStatsFilteredAggWithEvalCount() {
return;
}
var plan = plan(query);
- var project = as(plan, EsqlProject.class);
+ var project = as(plan, Project.class);
assertThat(Expressions.names(project.projections()), contains("salary", "count(salary) where false"));
var eval = as(project.child(), Eval.class);
@@ -679,7 +678,7 @@ public void testReplaceInlineStatsFilteredAggWithEvalCount() {
}
/**
- * EsqlProject[[salary{f}#10, count_distinct(salary 2) 3 where false{r}#4]]
+ * Project[[salary{f}#10, count_distinct(salary 2) 3 where false{r}#4]]
* \_Eval[[3[LONG] AS count_distinct(salary 2) 3 where false#4]]
* \_Limit[1000[INTEGER],false]
* \_EsRelation[test][_meta_field{f}#11, emp_no{f}#5, first_name{f}#6, ge..]
@@ -694,7 +693,7 @@ public void testReplaceInlineStatsFilteredAggWithEvalCountDistinctInExpression()
return;
}
var plan = plan(query);
- var project = as(plan, EsqlProject.class);
+ var project = as(plan, Project.class);
assertThat(Expressions.names(project.projections()), contains("salary", "count_distinct(salary + 2) + 3 where false"));
var eval = as(project.child(), Eval.class);
@@ -711,7 +710,7 @@ public void testReplaceInlineStatsFilteredAggWithEvalCountDistinctInExpression()
/*
* Limit[1000[INTEGER],true]
* \_InlineJoin[LEFT,[emp_no{f}#17],[emp_no{f}#17],[emp_no{r}#17]]
- * |_EsqlProject[[emp_no{f}#17, salary{f}#22]]
+ * |_Project[[emp_no{f}#17, salary{f}#22]]
* | \_EsRelation[test][_meta_field{f}#23, emp_no{f}#17, first_name{f}#18, ..]
* \_Project[[max{r}#6, max_a{r}#9, min{r}#12, min_a{r}#15, emp_no{f}#17]]
* \_Eval[[null[INTEGER] AS max_a#9, null[INTEGER] AS min_a#15]]
@@ -734,7 +733,7 @@ public void testReplaceInlineStatsFilteredAggWithEvalSameAggWithAndWithoutFilter
var limit = as(plan, Limit.class);
var ij = as(limit.child(), InlineJoin.class);
- var left = as(ij.left(), EsqlProject.class);
+ var left = as(ij.left(), Project.class);
assertThat(Expressions.names(left.projections()), contains("emp_no", "salary"));
var relation = as(left.child(), EsRelation.class);
@@ -764,7 +763,7 @@ public void testReplaceInlineStatsFilteredAggWithEvalSameAggWithAndWithoutFilter
}
/*
- * EsqlProject[[emp_no{f}#9, count{r}#5, cc{r}#8]]
+ * Project[[emp_no{f}#9, count{r}#5, cc{r}#8]]
* \_TopN[[Order[emp_no{f}#9,ASC,LAST]],3[INTEGER]]
* \_Eval[[0[LONG] AS count#5, 0[LONG] AS cc#8]]
* \_EsRelation[test][_meta_field{f}#15, emp_no{f}#9, first_name{f}#10, g..]
@@ -782,7 +781,7 @@ public void testReplaceTwoConsecutiveInlineStats_WithFalseFilters() {
return;
}
var plan = plan(query);
- var project = as(plan, EsqlProject.class);
+ var project = as(plan, Project.class);
assertThat(Expressions.names(project.projections()), contains("emp_no", "count", "cc"));
var topN = as(project.child(), TopN.class);
diff --git a/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/plan/logical/local/EsqlProjectSerializationTests.java b/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/plan/logical/local/EsqlProjectSerializationTests.java
deleted file mode 100644
index 7e5e368fff77f..0000000000000
--- a/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/plan/logical/local/EsqlProjectSerializationTests.java
+++ /dev/null
@@ -1,42 +0,0 @@
-/*
- * 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.xpack.esql.plan.logical.local;
-
-import org.elasticsearch.xpack.esql.core.expression.Attribute;
-import org.elasticsearch.xpack.esql.core.expression.NamedExpression;
-import org.elasticsearch.xpack.esql.plan.logical.AbstractLogicalPlanSerializationTests;
-import org.elasticsearch.xpack.esql.plan.logical.LogicalPlan;
-
-import java.io.IOException;
-import java.util.List;
-
-public class EsqlProjectSerializationTests extends AbstractLogicalPlanSerializationTests {
- @Override
- protected EsqlProject createTestInstance() {
- LogicalPlan child = randomChild(0);
- List projections = randomFieldAttributes(1, 10, false);
- return new EsqlProject(randomSource(), child, projections);
- }
-
- @Override
- protected EsqlProject mutateInstance(EsqlProject instance) throws IOException {
- LogicalPlan child = instance.child();
- List extends NamedExpression> projections = instance.projections();
- if (randomBoolean()) {
- child = randomValueOtherThan(child, () -> randomChild(0));
- } else {
- projections = randomValueOtherThan(projections, () -> randomFieldAttributes(1, 10, false));
- }
- return new EsqlProject(instance.source(), child, projections);
- }
-
- @Override
- protected boolean alwaysEmptySource() {
- return true;
- }
-}