Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,6 @@
import org.elasticsearch.xpack.esql.rule.ParameterizedRule;
import org.elasticsearch.xpack.esql.rule.ParameterizedRuleExecutor;
import org.elasticsearch.xpack.esql.rule.Rule;
import org.elasticsearch.xpack.esql.rule.RuleExecutor;
import org.elasticsearch.xpack.esql.session.Configuration;
import org.elasticsearch.xpack.esql.telemetry.FeatureMetric;
import org.elasticsearch.xpack.esql.type.EsqlDataTypeConverter;
Expand Down Expand Up @@ -153,19 +152,18 @@ public class Analyzer extends ParameterizedRuleExecutor<LogicalPlan, AnalyzerCon
public static final List<Attribute> NO_FIELDS = List.of(
new ReferenceAttribute(Source.EMPTY, "<no-fields>", DataType.NULL, Nullability.TRUE, null, true)
);
private static final Iterable<RuleExecutor.Batch<LogicalPlan>> rules;

static {
var init = new Batch<>(
private static final List<Batch<LogicalPlan>> RULES = List.of(
new Batch<>(
"Initialize",
Limiter.ONCE,
new ResolveTable(),
new ResolveEnrich(),
new ResolveLookupTables(),
new ResolveFunctions(),
new ResolveForkFunctions()
);
var resolution = new Batch<>(
),
new Batch<>(
"Resolution",
/*
* ImplicitCasting must be before ResolveRefs. Because a reference is created for a Bucket in Aggregate's aggregates,
Expand All @@ -176,16 +174,9 @@ public class Analyzer extends ParameterizedRuleExecutor<LogicalPlan, AnalyzerCon
new ImplicitForkCasting(),
new ResolveRefs(),
new ResolveUnionTypes() // Must be after ResolveRefs, so union types can be found
);
var finish = new Batch<>(
"Finish Analysis",
Limiter.ONCE,
new AddImplicitLimit(),
new AddImplicitForkLimit(),
new UnionTypesCleanup()
);
rules = List.of(init, resolution, finish);
}
),
new Batch<>("Finish Analysis", Limiter.ONCE, new AddImplicitLimit(), new AddImplicitForkLimit(), new UnionTypesCleanup())
);

private final Verifier verifier;

Expand All @@ -208,8 +199,8 @@ public LogicalPlan verify(LogicalPlan plan, BitSet partialMetrics) {
}

@Override
protected Iterable<RuleExecutor.Batch<LogicalPlan>> batches() {
return rules;
protected List<Batch<LogicalPlan>> batches() {
return RULES;
}

private static class ResolveTable extends ParameterizedAnalyzerRule<UnresolvedRelation, AnalyzerContext> {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@
import java.util.ArrayList;
import java.util.List;

import static java.util.Arrays.asList;
import static org.elasticsearch.common.util.CollectionUtils.arrayAsArrayList;
import static org.elasticsearch.xpack.esql.optimizer.LogicalPlanOptimizer.cleanup;
import static org.elasticsearch.xpack.esql.optimizer.LogicalPlanOptimizer.operators;

Expand All @@ -33,30 +33,32 @@
*/
public class LocalLogicalPlanOptimizer extends ParameterizedRuleExecutor<LogicalPlan, LocalLogicalOptimizerContext> {

private static final List<Batch<LogicalPlan>> RULES = replaceRules(
arrayAsArrayList(
new Batch<>(
"Local rewrite",
Limiter.ONCE,
new ReplaceTopNWithLimitAndSort(),
new ReplaceMissingFieldWithNull(),
new InferIsNotNull(),
new InferNonNullAggConstraint()
),
operators(),
cleanup()
)
);

public LocalLogicalPlanOptimizer(LocalLogicalOptimizerContext localLogicalOptimizerContext) {
super(localLogicalOptimizerContext);
}

@Override
protected List<Batch<LogicalPlan>> batches() {
var local = new Batch<>(
"Local rewrite",
Limiter.ONCE,
new ReplaceTopNWithLimitAndSort(),
new ReplaceMissingFieldWithNull(),
new InferIsNotNull(),
new InferNonNullAggConstraint()
);

var rules = new ArrayList<Batch<LogicalPlan>>();
rules.add(local);
// TODO: if the local rules haven't touched the tree, the rest of the rules can be skipped
rules.addAll(asList(operators(), cleanup()));
return replaceRules(rules);
return RULES;
}

@SuppressWarnings("unchecked")
private List<Batch<LogicalPlan>> replaceRules(List<Batch<LogicalPlan>> listOfRules) {
private static List<Batch<LogicalPlan>> replaceRules(List<Batch<LogicalPlan>> listOfRules) {
List<Batch<LogicalPlan>> newBatches = new ArrayList<>(listOfRules.size());
for (var batch : listOfRules) {
var rules = batch.rules();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,14 +26,14 @@
import java.util.Collection;
import java.util.List;

import static java.util.Arrays.asList;

/**
* Manages field extraction and pushing parts of the query into Lucene. (Query elements that are not pushed into Lucene are executed via
* the compute engine)
*/
public class LocalPhysicalPlanOptimizer extends ParameterizedRuleExecutor<PhysicalPlan, LocalPhysicalOptimizerContext> {

private static final List<Batch<PhysicalPlan>> RULES = rules(true);

private final PhysicalVerifier verifier = PhysicalVerifier.INSTANCE;

public LocalPhysicalPlanOptimizer(LocalPhysicalOptimizerContext context) {
Expand All @@ -54,13 +54,12 @@ PhysicalPlan verify(PhysicalPlan plan) {

@Override
protected List<Batch<PhysicalPlan>> batches() {
return rules(true);
return RULES;
}

protected List<Batch<PhysicalPlan>> rules(boolean optimizeForEsSource) {
protected static List<Batch<PhysicalPlan>> rules(boolean optimizeForEsSource) {
List<Rule<?, PhysicalPlan>> esSourceRules = new ArrayList<>(6);
esSourceRules.add(new ReplaceSourceAttributes());

if (optimizeForEsSource) {
esSourceRules.add(new PushTopNToSource());
esSourceRules.add(new PushLimitToSource());
Expand All @@ -81,7 +80,6 @@ protected List<Batch<PhysicalPlan>> rules(boolean optimizeForEsSource) {
new SpatialDocValuesExtraction(),
new SpatialShapeBoundsExtraction()
);
return asList(pushdown, fieldExtraction);
return List.of(pushdown, fieldExtraction);
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -64,11 +64,10 @@
import org.elasticsearch.xpack.esql.optimizer.rules.logical.TranslateMetricsAggregate;
import org.elasticsearch.xpack.esql.plan.logical.LogicalPlan;
import org.elasticsearch.xpack.esql.rule.ParameterizedRuleExecutor;
import org.elasticsearch.xpack.esql.rule.RuleExecutor;

import java.util.List;

import static java.util.Arrays.asList;

/**
* <p>This class is part of the planner</p>
* <p>Global optimizations based strictly on the structure of the query (i.e. not factoring in information about the backing indices).
Expand All @@ -93,6 +92,14 @@
*/
public class LogicalPlanOptimizer extends ParameterizedRuleExecutor<LogicalPlan, LogicalOptimizerContext> {

private static final List<RuleExecutor.Batch<LogicalPlan>> RULES = List.of(
substitutions(),
operators(),
new Batch<>("Skip Compute", new SkipQueryOnLimitZero()),
cleanup(),
new Batch<>("Set as Optimized", Limiter.ONCE, new SetAsOptimized())
);

private final LogicalVerifier verifier = LogicalVerifier.INSTANCE;

public LogicalPlanOptimizer(LogicalOptimizerContext optimizerContext) {
Expand All @@ -112,14 +119,7 @@ public LogicalPlan optimize(LogicalPlan verified) {

@Override
protected List<Batch<LogicalPlan>> batches() {
return rules();
}

protected static List<Batch<LogicalPlan>> rules() {
var skip = new Batch<>("Skip Compute", new SkipQueryOnLimitZero());
var label = new Batch<>("Set as Optimized", Limiter.ONCE, new SetAsOptimized());

return asList(substitutions(), operators(), skip, cleanup(), label);
return RULES;
}

protected static Batch<LogicalPlan> substitutions() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,14 +18,15 @@
import java.util.Collection;
import java.util.List;

import static java.util.Arrays.asList;

/**
* This class is part of the planner. Performs global (coordinator) optimization of the physical plan. Local (data-node) optimizations
* occur later by operating just on a plan {@link FragmentExec} (subplan).
*/
public class PhysicalPlanOptimizer extends ParameterizedRuleExecutor<PhysicalPlan, PhysicalOptimizerContext> {
private static final Iterable<RuleExecutor.Batch<PhysicalPlan>> rules = initializeRules(true);

private static final List<RuleExecutor.Batch<PhysicalPlan>> RULES = List.of(
new Batch<>("Plan Boundary", Limiter.ONCE, new ProjectAwayColumns())
);

private final PhysicalVerifier verifier = PhysicalVerifier.INSTANCE;

Expand All @@ -45,13 +46,8 @@ PhysicalPlan verify(PhysicalPlan plan) {
return plan;
}

static List<RuleExecutor.Batch<PhysicalPlan>> initializeRules(boolean isOptimizedForEsSource) {
var boundary = new Batch<>("Plan Boundary", Limiter.ONCE, new ProjectAwayColumns());
return asList(boundary);
}

@Override
protected Iterable<RuleExecutor.Batch<PhysicalPlan>> batches() {
return rules;
protected List<RuleExecutor.Batch<PhysicalPlan>> batches() {
return RULES;
}
}

This file was deleted.