diff --git a/core/src/main/java/org/opensearch/sql/executor/QueryService.java b/core/src/main/java/org/opensearch/sql/executor/QueryService.java index 94e7081920..b4b71227cd 100644 --- a/core/src/main/java/org/opensearch/sql/executor/QueryService.java +++ b/core/src/main/java/org/opensearch/sql/executor/QueryService.java @@ -9,6 +9,7 @@ package org.opensearch.sql.executor; import lombok.RequiredArgsConstructor; +import lombok.Setter; import org.opensearch.sql.analysis.AnalysisContext; import org.opensearch.sql.analysis.Analyzer; import org.opensearch.sql.ast.tree.UnresolvedPlan; @@ -28,7 +29,8 @@ public class QueryService { private final ExecutionEngine executionEngine; - private final Planner planner; + @Setter + private Planner planner; /** * Execute the {@link UnresolvedPlan}, using {@link ResponseListener} to get response. diff --git a/core/src/main/java/org/opensearch/sql/executor/execution/QueryPlanFactory.java b/core/src/main/java/org/opensearch/sql/executor/execution/QueryPlanFactory.java index 3273eb3c18..8646156c9f 100644 --- a/core/src/main/java/org/opensearch/sql/executor/execution/QueryPlanFactory.java +++ b/core/src/main/java/org/opensearch/sql/executor/execution/QueryPlanFactory.java @@ -26,6 +26,7 @@ import org.opensearch.sql.executor.QueryId; import org.opensearch.sql.executor.QueryService; import org.opensearch.sql.executor.pagination.CanPaginateVisitor; +import org.opensearch.sql.planner.Planner; /** * QueryExecution Factory. @@ -43,6 +44,10 @@ public class QueryPlanFactory */ private final QueryService queryService; + public void setPlanner(Planner planner) { + queryService.setPlanner(planner); + } + /** * NO_CONSUMER_RESPONSE_LISTENER should never be called. It is only used as constructor * parameter of {@link QueryPlan}. diff --git a/core/src/main/java/org/opensearch/sql/planner/optimizer/LogicalPlanOptimizer.java b/core/src/main/java/org/opensearch/sql/planner/optimizer/LogicalPlanOptimizer.java index a4d649f171..e206f2defe 100644 --- a/core/src/main/java/org/opensearch/sql/planner/optimizer/LogicalPlanOptimizer.java +++ b/core/src/main/java/org/opensearch/sql/planner/optimizer/LogicalPlanOptimizer.java @@ -6,7 +6,11 @@ package org.opensearch.sql.planner.optimizer; +import static com.facebook.presto.matching.DefaultMatcher.DEFAULT_MATCHER; + +import com.facebook.presto.matching.Match; import java.util.List; +import java.util.stream.Collectors; import lombok.RequiredArgsConstructor; import org.opensearch.sql.planner.logical.LogicalPlan; import org.opensearch.sql.planner.optimizer.rule.read.CreateTableScanBuilder; @@ -19,14 +23,24 @@ * 1> Optimize the current node with all the rules. * 2> Optimize the all the child nodes with all the rules. * 3) In case the child node could change, Optimize the current node again. + * TODO update comment ^ */ @RequiredArgsConstructor public class LogicalPlanOptimizer { private final List> rules; + private final OptimizingMode optimizingMode; + + // TODO comment + public enum OptimizingMode { + PRESERVE_TREE_ORDER, + PRESERVE_RULE_ORDER + } + /** * Create {@link LogicalPlanOptimizer} with pre-defined rules. + * TODO comment */ public static LogicalPlanOptimizer create() { return new LogicalPlanOptimizer(List.of( @@ -35,22 +49,99 @@ public static LogicalPlanOptimizer create() { */ new CreateTableScanBuilder(), TableScanPushDown.PUSH_DOWN_PAGE_SIZE, + TableScanPushDown.PUSH_DOWN_FILTER_DEEP, + TableScanPushDown.PUSH_DOWN_AGGREGATION_DEEP, + TableScanPushDown.PUSH_DOWN_FILTER_DEEP, + TableScanPushDown.PUSH_DOWN_SORT_DEEP, + TableScanPushDown.PUSH_DOWN_HIGHLIGHT, + TableScanPushDown.PUSH_DOWN_NESTED, + TableScanPushDown.PUSH_DOWN_PROJECT_DEEP, + TableScanPushDown.PUSH_DOWN_LIMIT_DEEP, + new CreateTableWriteBuilder() + ), OptimizingMode.PRESERVE_RULE_ORDER); + } + + /** + * TODO comment + * TODO rename + */ + public static LogicalPlanOptimizer create2() { + return new LogicalPlanOptimizer(List.of( + new CreateTableScanBuilder(), + TableScanPushDown.PUSH_DOWN_PAGE_SIZE, TableScanPushDown.PUSH_DOWN_FILTER, TableScanPushDown.PUSH_DOWN_AGGREGATION, - TableScanPushDown.PUSH_DOWN_FILTER, TableScanPushDown.PUSH_DOWN_SORT, + TableScanPushDown.PUSH_DOWN_LIMIT, TableScanPushDown.PUSH_DOWN_HIGHLIGHT, TableScanPushDown.PUSH_DOWN_NESTED, TableScanPushDown.PUSH_DOWN_PROJECT, - TableScanPushDown.PUSH_DOWN_LIMIT, new CreateTableWriteBuilder() - )); + ), OptimizingMode.PRESERVE_TREE_ORDER); } /** * Optimize {@link LogicalPlan}. */ public LogicalPlan optimize(LogicalPlan plan) { - return new LogicalPlanOptimizerVisitor(rules).optimize(plan); + log(plan); + var optimized = plan; + if (optimizingMode == OptimizingMode.PRESERVE_RULE_ORDER) { + optimized = new LogicalPlanOptimizerVisitor(rules).optimize(plan); + } else { //PRESERVE_TREE_ORDER + optimized = optimize2(plan); + } + log(optimized); + return optimized; + } + + + // TODO remove debugging + public void log(LogicalPlan plan) { + var node = plan; + System.out.println("=============="); + System.out.println(node.getClass().getSimpleName()); + while (node.getChild().size() > 0) { + node = node.getChild().get(0); + System.out.println(" |"); + System.out.println(node.getClass().getSimpleName()); + } + System.out.println("=============="); + } + + // TODO merge classes, reuse code and make rename functions + + /** + * Optimize {@link LogicalPlan}. + */ + public LogicalPlan optimize2(LogicalPlan plan) { + LogicalPlan optimized = internalOptimize(plan); + optimized.replaceChildPlans( + optimized.getChild().stream().map(this::optimize2).collect( + Collectors.toList())); + return internalOptimize(optimized); + } + + private LogicalPlan internalOptimize(LogicalPlan plan) { + LogicalPlan node = plan; + boolean done = false; + while (!done) { + done = true; + for (Rule rule : rules) { + Match match = DEFAULT_MATCHER.match(rule.pattern(), node); + if (match.isPresent()) { + node = rule.apply(match.value(), match.captures()); + + // For new TableScanPushDown impl, pattern match doesn't necessarily cause + // push down to happen. So reiterate all rules against the node only if the node + // is actually replaced by any rule. + // TODO: may need to introduce fixed point or maximum iteration limit in future + if (node != match.value()) { + done = false; + } + } + } + } + return node; } } diff --git a/core/src/main/java/org/opensearch/sql/planner/optimizer/LogicalPlanOptimizerVisitor.java b/core/src/main/java/org/opensearch/sql/planner/optimizer/LogicalPlanOptimizerVisitor.java index d1a6e50de6..8c9850373e 100644 --- a/core/src/main/java/org/opensearch/sql/planner/optimizer/LogicalPlanOptimizerVisitor.java +++ b/core/src/main/java/org/opensearch/sql/planner/optimizer/LogicalPlanOptimizerVisitor.java @@ -30,7 +30,6 @@ public LogicalPlanOptimizerVisitor(List> rules) { } public LogicalPlan optimize(LogicalPlan planTree) { - log(planTree); var node = planTree; for (int i = 0; i < rules.size(); i++) { // TODO how to avoid unchecked cast @@ -43,23 +42,9 @@ public LogicalPlan optimize(LogicalPlan planTree) { i--; } } - log(node); return node; } - // TODO remove debugging - public void log(LogicalPlan plan) { - var node = plan; - System.out.println("=============="); - System.out.println(node.getClass().getSimpleName()); - while (node.getChild().size() > 0) { - node = node.getChild().get(0); - System.out.println(" |"); - System.out.println(node.getClass().getSimpleName()); - } - System.out.println("=============="); - } - private boolean isCurrentRuleAppliedToNode(LogicalPlan node) { for (var logEntry : log) { // A rule could be applied to the exactly equal, but not same tree node diff --git a/core/src/main/java/org/opensearch/sql/planner/optimizer/PushDownRule.java b/core/src/main/java/org/opensearch/sql/planner/optimizer/PushDownRule.java index 16e5c4899b..2634334ae2 100644 --- a/core/src/main/java/org/opensearch/sql/planner/optimizer/PushDownRule.java +++ b/core/src/main/java/org/opensearch/sql/planner/optimizer/PushDownRule.java @@ -8,6 +8,8 @@ import com.facebook.presto.matching.Captures; import com.facebook.presto.matching.Pattern; import java.util.ArrayDeque; +import java.util.ArrayList; +import java.util.Arrays; import java.util.Deque; import java.util.List; import java.util.Optional; @@ -37,26 +39,34 @@ public class PushDownRule extends Rule { private final Class clazz; - private final BiFunction pushDownFunction; - private final List> exceptions; + private BiFunction pushDownFunction; + private List> exceptions; + private boolean deepTreeTraverse; - public PushDownRule(Class clazz, - boolean canBeAppliedMultipleTimes, - BiFunction pushDownFunction, - Function exception) { - super(canBeAppliedMultipleTimes); + public PushDownRule(Class clazz) { this.clazz = clazz; + } + + @SafeVarargs + public final PushDownRule configureDeepTraverseRule( + boolean canBeAppliedMultipleTimes, + BiFunction pushDownFunction, + Function... exceptions) { + this.canBeAppliedMultipleTimes = canBeAppliedMultipleTimes; + this.deepTreeTraverse = true; this.pushDownFunction = pushDownFunction; - this.exceptions = List.of(exception, getDefaultException()); + this.exceptions = new ArrayList<>(Arrays.asList(exceptions)); + this.exceptions.add(0, getDefaultException()); + return this; } - public PushDownRule(Class clazz, - boolean canBeAppliedMultipleTimes, - BiFunction pushDownFunction) { - super(canBeAppliedMultipleTimes); - this.clazz = clazz; + public final PushDownRule configureRegularRule( + BiFunction pushDownFunction) { + this.canBeAppliedMultipleTimes = true; + this.deepTreeTraverse = false; this.pushDownFunction = pushDownFunction; - this.exceptions = List.of(getDefaultException()); + this.exceptions = List.of(); + return this; } /** @@ -99,7 +109,9 @@ private Optional findTableScanBuilder(LogicalPlan node) { } return Optional.of((TableScanBuilder) children.get(0)); } - plans.addAll(children); + if (deepTreeTraverse) { + plans.addAll(children); + } } while (!plans.isEmpty()); return Optional.empty(); } diff --git a/core/src/main/java/org/opensearch/sql/planner/optimizer/Rule.java b/core/src/main/java/org/opensearch/sql/planner/optimizer/Rule.java index f73a5c75ff..c55e87ffc9 100644 --- a/core/src/main/java/org/opensearch/sql/planner/optimizer/Rule.java +++ b/core/src/main/java/org/opensearch/sql/planner/optimizer/Rule.java @@ -9,7 +9,6 @@ import com.facebook.presto.matching.Captures; import com.facebook.presto.matching.Pattern; import lombok.Getter; -import lombok.RequiredArgsConstructor; import lombok.experimental.Accessors; import org.opensearch.sql.planner.logical.LogicalPlan; @@ -17,16 +16,11 @@ * Optimization Rule. * @param LogicalPlan. */ -@RequiredArgsConstructor public abstract class Rule { @Accessors(fluent = true) @Getter - protected final boolean canBeAppliedMultipleTimes; - - public Rule() { - this.canBeAppliedMultipleTimes = false; - } + protected boolean canBeAppliedMultipleTimes; /** * Get the {@link Pattern}. diff --git a/core/src/main/java/org/opensearch/sql/planner/optimizer/rule/read/TableScanPushDown.java b/core/src/main/java/org/opensearch/sql/planner/optimizer/rule/read/TableScanPushDown.java index 48957f7a19..a5b051b12a 100644 --- a/core/src/main/java/org/opensearch/sql/planner/optimizer/rule/read/TableScanPushDown.java +++ b/core/src/main/java/org/opensearch/sql/planner/optimizer/rule/read/TableScanPushDown.java @@ -29,48 +29,65 @@ public class TableScanPushDown { /** Push down optimize rule for filtering condition. */ - public static final Rule PUSH_DOWN_FILTER = - new PushDownRule<>(LogicalFilter.class, true, + public static final Rule PUSH_DOWN_FILTER_DEEP = + new PushDownRule<>(LogicalFilter.class).configureDeepTraverseRule(true, (filter, scanBuilder) -> scanBuilder.pushDownFilter(filter), - (plan) -> plan instanceof LogicalAggregation || plan instanceof LogicalProject); + (plan) -> plan instanceof LogicalAggregation, + (plan) -> plan instanceof LogicalProject); + public static final Rule PUSH_DOWN_FILTER = + new PushDownRule<>(LogicalFilter.class).configureRegularRule( + (filter, scanBuilder) -> scanBuilder.pushDownFilter(filter)); /** Push down optimize rule for aggregate operator. */ - public static final Rule PUSH_DOWN_AGGREGATION = - new PushDownRule<>(LogicalAggregation.class, false, + public static final Rule PUSH_DOWN_AGGREGATION_DEEP = + new PushDownRule<>(LogicalAggregation.class).configureDeepTraverseRule(true, (agg, scanBuilder) -> scanBuilder.pushDownAggregation(agg), (plan) -> plan instanceof LogicalProject); + public static final Rule PUSH_DOWN_AGGREGATION = + new PushDownRule<>(LogicalAggregation.class).configureRegularRule( + (agg, scanBuilder) -> scanBuilder.pushDownAggregation(agg)); /** Push down optimize rule for sort operator. */ - public static final Rule PUSH_DOWN_SORT = - new PushDownRule<>(LogicalSort.class, true, + public static final Rule PUSH_DOWN_SORT_DEEP = + new PushDownRule<>(LogicalSort.class).configureDeepTraverseRule(true, (sort, scanBuilder) -> scanBuilder.pushDownSort(sort), (plan) -> plan instanceof LogicalProject); + public static final Rule PUSH_DOWN_SORT = + new PushDownRule<>(LogicalSort.class).configureRegularRule( + (sort, scanBuilder) -> scanBuilder.pushDownSort(sort)); /** Push down optimize rule for limit operator. */ - public static final Rule PUSH_DOWN_LIMIT = - new PushDownRule<>(LogicalLimit.class, false, + public static final Rule PUSH_DOWN_LIMIT_DEEP = + new PushDownRule<>(LogicalLimit.class).configureDeepTraverseRule(false, (limit, scanBuilder) -> scanBuilder.pushDownLimit(limit), - (plan) -> plan instanceof LogicalSort || plan instanceof LogicalFilter - || plan instanceof LogicalProject); + (plan) -> plan instanceof LogicalSort, + (plan) -> plan instanceof LogicalFilter, + (plan) -> plan instanceof LogicalProject); + public static final Rule PUSH_DOWN_LIMIT = + new PushDownRule<>(LogicalLimit.class).configureRegularRule( + (limit, scanBuilder) -> scanBuilder.pushDownLimit(limit)); /** Push down optimize rule for Project operator. */ - public static final Rule PUSH_DOWN_PROJECT = - new PushDownRule<>(LogicalProject.class, false, + public static final Rule PUSH_DOWN_PROJECT_DEEP = + new PushDownRule<>(LogicalProject.class).configureDeepTraverseRule(false, (project, scanBuilder) -> scanBuilder.pushDownProject(project), - (plan) -> plan instanceof LogicalEval || plan instanceof LogicalWindow); + (plan) -> plan instanceof LogicalWindow); + public static final Rule PUSH_DOWN_PROJECT = + new PushDownRule<>(LogicalProject.class).configureRegularRule( + (project, scanBuilder) -> scanBuilder.pushDownProject(project)); /** Push down optimize rule for highlight operator. */ public static final Rule PUSH_DOWN_HIGHLIGHT = - new PushDownRule<>(LogicalHighlight.class, true, + new PushDownRule<>(LogicalHighlight.class).configureDeepTraverseRule(true, (highlight, scanBuilder) -> scanBuilder.pushDownHighlight(highlight)); /** Push down optimize rule for nested operator. */ public static final Rule PUSH_DOWN_NESTED = - new PushDownRule<>(LogicalNested.class, false, + new PushDownRule<>(LogicalNested.class).configureDeepTraverseRule(false, (nested, scanBuilder) -> scanBuilder.pushDownNested(nested)); /** Push down optimize rule for paginate operator. */ public static final Rule PUSH_DOWN_PAGE_SIZE = - new PushDownRule<>(LogicalPaginate.class, false, + new PushDownRule<>(LogicalPaginate.class).configureDeepTraverseRule(false, (paginate, scanBuilder) -> scanBuilder.pushDownPageSize(paginate)); } diff --git a/integ-test/src/test/java/org/opensearch/sql/ppl/StandaloneIT.java b/integ-test/src/test/java/org/opensearch/sql/ppl/StandaloneIT.java index b1fcbf7d1b..4e889f0327 100644 --- a/integ-test/src/test/java/org/opensearch/sql/ppl/StandaloneIT.java +++ b/integ-test/src/test/java/org/opensearch/sql/ppl/StandaloneIT.java @@ -218,15 +218,17 @@ public QueryManager queryManager() { return new ExecuteOnCallerThreadQueryManager(); } - @Provides - public PPLService pplService(QueryManager queryManager, QueryPlanFactory queryPlanFactory) { - return new PPLService(new PPLSyntaxParser(), queryManager, queryPlanFactory); - } + @Provides + public PPLService pplService(QueryManager queryManager, QueryPlanFactory queryPlanFactory) { + Planner planner = new Planner(LogicalPlanOptimizer.create2()); + return new PPLService(new PPLSyntaxParser(), queryManager, queryPlanFactory, planner); + } - @Provides - public SQLService sqlService(QueryManager queryManager, QueryPlanFactory queryPlanFactory) { - return new SQLService(new SQLSyntaxParser(), queryManager, queryPlanFactory); - } + @Provides + public SQLService sqlService(QueryManager queryManager, QueryPlanFactory queryPlanFactory) { + Planner planner = new Planner(LogicalPlanOptimizer.create()); + return new SQLService(new SQLSyntaxParser(), queryManager, queryPlanFactory, planner); + } @Provides public PlanSerializer planSerializer(StorageEngine storageEngine) { @@ -235,11 +237,9 @@ public PlanSerializer planSerializer(StorageEngine storageEngine) { @Provides public QueryPlanFactory queryPlanFactory(ExecutionEngine executionEngine) { - Analyzer analyzer = - new Analyzer( - new ExpressionAnalyzer(functionRepository), dataSourceService, functionRepository); - Planner planner = new Planner(LogicalPlanOptimizer.create()); - QueryService queryService = new QueryService(analyzer, executionEngine, planner); + Analyzer analyzer = new Analyzer( + new ExpressionAnalyzer(functionRepository), dataSourceService, functionRepository); + QueryService queryService = new QueryService(analyzer, executionEngine); return new QueryPlanFactory(queryService); } } diff --git a/integ-test/src/test/java/org/opensearch/sql/sql/StandalonePaginationIT.java b/integ-test/src/test/java/org/opensearch/sql/sql/StandalonePaginationIT.java index aad39c4074..c1a81a1572 100644 --- a/integ-test/src/test/java/org/opensearch/sql/sql/StandalonePaginationIT.java +++ b/integ-test/src/test/java/org/opensearch/sql/sql/StandalonePaginationIT.java @@ -43,10 +43,12 @@ import org.opensearch.sql.opensearch.storage.OpenSearchDataSourceFactory; import org.opensearch.sql.opensearch.storage.OpenSearchIndex; import org.opensearch.sql.planner.PlanContext; +import org.opensearch.sql.planner.Planner; import org.opensearch.sql.planner.logical.LogicalPaginate; import org.opensearch.sql.planner.logical.LogicalPlan; import org.opensearch.sql.planner.logical.LogicalProject; import org.opensearch.sql.planner.logical.LogicalRelation; +import org.opensearch.sql.planner.optimizer.LogicalPlanOptimizer; import org.opensearch.sql.planner.physical.PhysicalPlan; import org.opensearch.sql.storage.DataSourceFactory; import org.opensearch.sql.util.InternalRestHighLevelClient; @@ -80,6 +82,7 @@ public void init() { Injector injector = modules.createInjector(); queryService = injector.getInstance(QueryService.class); + queryService.setPlanner(new Planner(LogicalPlanOptimizer.create())); planSerializer = injector.getInstance(PlanSerializer.class); } diff --git a/integ-test/src/test/java/org/opensearch/sql/util/StandaloneModule.java b/integ-test/src/test/java/org/opensearch/sql/util/StandaloneModule.java index c347ea5244..0c0a80f253 100644 --- a/integ-test/src/test/java/org/opensearch/sql/util/StandaloneModule.java +++ b/integ-test/src/test/java/org/opensearch/sql/util/StandaloneModule.java @@ -90,12 +90,14 @@ public QueryManager queryManager() { @Provides public PPLService pplService(QueryManager queryManager, QueryPlanFactory queryPlanFactory) { - return new PPLService(new PPLSyntaxParser(), queryManager, queryPlanFactory); + Planner planner = new Planner(LogicalPlanOptimizer.create2()); + return new PPLService(new PPLSyntaxParser(), queryManager, queryPlanFactory, planner); } @Provides public SQLService sqlService(QueryManager queryManager, QueryPlanFactory queryPlanFactory) { - return new SQLService(new SQLSyntaxParser(), queryManager, queryPlanFactory); + Planner planner = new Planner(LogicalPlanOptimizer.create()); + return new SQLService(new SQLSyntaxParser(), queryManager, queryPlanFactory, planner); } @Provides @@ -111,10 +113,8 @@ public QueryPlanFactory queryPlanFactory(QueryService qs) { @Provides public QueryService queryService(ExecutionEngine executionEngine) { - Analyzer analyzer = - new Analyzer( - new ExpressionAnalyzer(functionRepository), dataSourceService, functionRepository); - Planner planner = new Planner(LogicalPlanOptimizer.create()); - return new QueryService(analyzer, executionEngine, planner); + Analyzer analyzer = new Analyzer( + new ExpressionAnalyzer(functionRepository), dataSourceService, functionRepository); + return new QueryService(analyzer, executionEngine); } } diff --git a/opensearch/src/main/java/org/opensearch/sql/opensearch/client/OpenSearchNodeClient.java b/opensearch/src/main/java/org/opensearch/sql/opensearch/client/OpenSearchNodeClient.java index b6ca5471e5..c6d44e2c23 100644 --- a/opensearch/src/main/java/org/opensearch/sql/opensearch/client/OpenSearchNodeClient.java +++ b/opensearch/src/main/java/org/opensearch/sql/opensearch/client/OpenSearchNodeClient.java @@ -6,7 +6,6 @@ package org.opensearch.sql.opensearch.client; -import com.carrotsearch.hppc.cursors.ObjectObjectCursor; import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableMap; import java.util.Arrays; diff --git a/plugin/src/main/java/org/opensearch/sql/plugin/config/OpenSearchPluginModule.java b/plugin/src/main/java/org/opensearch/sql/plugin/config/OpenSearchPluginModule.java index f301a242fb..dcc6e32e8c 100644 --- a/plugin/src/main/java/org/opensearch/sql/plugin/config/OpenSearchPluginModule.java +++ b/plugin/src/main/java/org/opensearch/sql/plugin/config/OpenSearchPluginModule.java @@ -87,12 +87,14 @@ public QueryManager queryManager(NodeClient nodeClient) { @Provides public PPLService pplService(QueryManager queryManager, QueryPlanFactory queryPlanFactory) { - return new PPLService(new PPLSyntaxParser(), queryManager, queryPlanFactory); + Planner planner = new Planner(LogicalPlanOptimizer.create2()); + return new PPLService(new PPLSyntaxParser(), queryManager, queryPlanFactory, planner); } @Provides public SQLService sqlService(QueryManager queryManager, QueryPlanFactory queryPlanFactory) { - return new SQLService(new SQLSyntaxParser(), queryManager, queryPlanFactory); + Planner planner = new Planner(LogicalPlanOptimizer.create()); + return new SQLService(new SQLSyntaxParser(), queryManager, queryPlanFactory, planner); } /** @@ -101,12 +103,10 @@ public SQLService sqlService(QueryManager queryManager, QueryPlanFactory queryPl @Provides public QueryPlanFactory queryPlanFactory(DataSourceService dataSourceService, ExecutionEngine executionEngine) { - Analyzer analyzer = - new Analyzer( - new ExpressionAnalyzer(functionRepository), dataSourceService, functionRepository); - Planner planner = new Planner(LogicalPlanOptimizer.create()); - QueryService queryService = new QueryService( - analyzer, executionEngine, planner); + Analyzer analyzer = new Analyzer( + new ExpressionAnalyzer(functionRepository), dataSourceService, functionRepository); + + QueryService queryService = new QueryService(analyzer, executionEngine); return new QueryPlanFactory(queryService); } } diff --git a/ppl/src/main/java/org/opensearch/sql/ppl/PPLService.java b/ppl/src/main/java/org/opensearch/sql/ppl/PPLService.java index 40a7a85f78..3d1930acde 100644 --- a/ppl/src/main/java/org/opensearch/sql/ppl/PPLService.java +++ b/ppl/src/main/java/org/opensearch/sql/ppl/PPLService.java @@ -9,7 +9,6 @@ import static org.opensearch.sql.executor.ExecutionEngine.QueryResponse; import java.util.Optional; -import lombok.RequiredArgsConstructor; import org.antlr.v4.runtime.tree.ParseTree; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; @@ -20,6 +19,7 @@ import org.opensearch.sql.executor.QueryManager; import org.opensearch.sql.executor.execution.AbstractPlan; import org.opensearch.sql.executor.execution.QueryPlanFactory; +import org.opensearch.sql.planner.Planner; import org.opensearch.sql.ppl.antlr.PPLSyntaxParser; import org.opensearch.sql.ppl.domain.PPLQueryRequest; import org.opensearch.sql.ppl.parser.AstBuilder; @@ -30,7 +30,6 @@ /** * PPLService. */ -@RequiredArgsConstructor public class PPLService { private final PPLSyntaxParser parser; @@ -42,6 +41,16 @@ public class PPLService { private static final Logger LOG = LogManager.getLogger(); + public PPLService(PPLSyntaxParser parser, + QueryManager queryManager, + QueryPlanFactory queryExecutionFactory, + Planner planner) { + this.parser = parser; + this.queryManager = queryManager; + this.queryExecutionFactory = queryExecutionFactory; + queryExecutionFactory.setPlanner(planner); + } + /** * Execute the {@link PPLQueryRequest}, using {@link ResponseListener} to get response. * diff --git a/prometheus/src/main/java/org/opensearch/sql/prometheus/planner/logical/PrometheusLogicalPlanOptimizerFactory.java b/prometheus/src/main/java/org/opensearch/sql/prometheus/planner/logical/PrometheusLogicalPlanOptimizerFactory.java index 255f58d6f2..1729284794 100644 --- a/prometheus/src/main/java/org/opensearch/sql/prometheus/planner/logical/PrometheusLogicalPlanOptimizerFactory.java +++ b/prometheus/src/main/java/org/opensearch/sql/prometheus/planner/logical/PrometheusLogicalPlanOptimizerFactory.java @@ -27,6 +27,6 @@ public static LogicalPlanOptimizer create() { new MergeFilterAndRelation(), new MergeAggAndIndexScan(), new MergeAggAndRelation() - )); + ), LogicalPlanOptimizer.OptimizingMode.PRESERVE_TREE_ORDER); } } diff --git a/sql/src/main/java/org/opensearch/sql/sql/SQLService.java b/sql/src/main/java/org/opensearch/sql/sql/SQLService.java index 91ec00cdd5..a4c7d81173 100644 --- a/sql/src/main/java/org/opensearch/sql/sql/SQLService.java +++ b/sql/src/main/java/org/opensearch/sql/sql/SQLService.java @@ -7,7 +7,6 @@ package org.opensearch.sql.sql; import java.util.Optional; -import lombok.RequiredArgsConstructor; import org.antlr.v4.runtime.tree.ParseTree; import org.opensearch.sql.ast.statement.Statement; import org.opensearch.sql.common.response.ResponseListener; @@ -16,6 +15,7 @@ import org.opensearch.sql.executor.QueryManager; import org.opensearch.sql.executor.execution.AbstractPlan; import org.opensearch.sql.executor.execution.QueryPlanFactory; +import org.opensearch.sql.planner.Planner; import org.opensearch.sql.sql.antlr.SQLSyntaxParser; import org.opensearch.sql.sql.domain.SQLQueryRequest; import org.opensearch.sql.sql.parser.AstBuilder; @@ -24,7 +24,6 @@ /** * SQL service. */ -@RequiredArgsConstructor public class SQLService { private final SQLSyntaxParser parser; @@ -33,6 +32,16 @@ public class SQLService { private final QueryPlanFactory queryExecutionFactory; + public SQLService(SQLSyntaxParser parser, + QueryManager queryManager, + QueryPlanFactory queryExecutionFactory, + Planner planner) { + this.parser = parser; + this.queryManager = queryManager; + this.queryExecutionFactory = queryExecutionFactory; + queryExecutionFactory.setPlanner(planner); + } + /** * Given {@link SQLQueryRequest}, execute it. Using listener to listen result. *