This is an automated email from the ASF dual-hosted git repository. dlych pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/asterixdb.git
commit 9b39f07e53ab454bc137df7b3d5e616b6cc13066 Author: Dmitry Lychagin <[email protected]> AuthorDate: Tue Nov 10 18:11:02 2020 -0800 [NO ISSUE][COMP] Keep constant assigns in subplans - user model changes: no - storage format changes: no - interface changes: no Details: - Do not move constant assigns out of subplans - Fix PushSubplanIntoGroupByRule handling of right branches of binary operators Change-Id: Ic0e892f71d464babdcc45e975b6425ff2555aaa6 Reviewed-on: https://asterix-gerrit.ics.uci.edu/c/asterixdb/+/8823 Integration-Tests: Jenkins <[email protected]> Tested-by: Jenkins <[email protected]> Reviewed-by: Ali Alsuliman <[email protected]> --- ...ixMoveFreeVariableOperatorOutOfSubplanRule.java | 11 +- .../queries/leftouterjoin/loj-03-no-listify.sqlpp | 49 ++++++++ .../results/leftouterjoin/loj-03-no-listify.plan | 127 +++++++++++++++++++++ .../loj-03-no-listify.1.ddl.sqlpp} | 17 ++- .../loj-03-no-listify.2.update.sqlpp} | 26 +++-- .../loj-03-no-listify.3.query.sqlpp} | 28 +++-- .../loj-03-no-listify/loj-03-no-listify.3.adm | 2 + .../test/resources/runtimets/testsuite_sqlpp.xml | 5 + .../MoveFreeVariableOperatorOutOfSubplanRule.java | 22 ++-- .../rules/subplan/PushSubplanIntoGroupByRule.java | 33 ++++-- 10 files changed, 272 insertions(+), 48 deletions(-) diff --git a/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/subplan/AsterixMoveFreeVariableOperatorOutOfSubplanRule.java b/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/subplan/AsterixMoveFreeVariableOperatorOutOfSubplanRule.java index 4d6b4bb..66dcc83 100644 --- a/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/subplan/AsterixMoveFreeVariableOperatorOutOfSubplanRule.java +++ b/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/subplan/AsterixMoveFreeVariableOperatorOutOfSubplanRule.java @@ -18,13 +18,22 @@ */ package org.apache.asterix.optimizer.rules.subplan; +import java.util.Set; + +import org.apache.hyracks.algebricks.core.algebra.base.ILogicalOperator; import org.apache.hyracks.algebricks.core.algebra.base.LogicalOperatorTag; +import org.apache.hyracks.algebricks.core.algebra.base.LogicalVariable; import org.apache.hyracks.algebricks.rewriter.rules.subplan.MoveFreeVariableOperatorOutOfSubplanRule; public class AsterixMoveFreeVariableOperatorOutOfSubplanRule extends MoveFreeVariableOperatorOutOfSubplanRule { @Override - protected boolean movableOperator(LogicalOperatorTag operatorTag) { + protected boolean movableOperatorKind(LogicalOperatorTag operatorTag) { return (operatorTag == LogicalOperatorTag.ASSIGN); } + + @Override + protected boolean movableIndependentOperator(ILogicalOperator op, Set<LogicalVariable> usedVars) { + return !usedVars.isEmpty(); + } } diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/queries/leftouterjoin/loj-03-no-listify.sqlpp b/asterixdb/asterix-app/src/test/resources/optimizerts/queries/leftouterjoin/loj-03-no-listify.sqlpp new file mode 100644 index 0000000..510e26c --- /dev/null +++ b/asterixdb/asterix-app/src/test/resources/optimizerts/queries/leftouterjoin/loj-03-no-listify.sqlpp @@ -0,0 +1,49 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +/* + * Description: Test that listify() is eliminated + * on the right side of an outer join + */ + +DROP DATAVERSE test IF EXISTS; +CREATE DATAVERSE test; + +USE test; + +CREATE TYPE tasksType AS { + id : integer +}; + +CREATE DATASET tasks(tasksType) PRIMARY KEY id; + +SELECT t0.taskId, t0.cnt_all, t1.cnt_x, t2.cnt_y, t3.cnt_z +FROM ( + SELECT taskId, COUNT(1) AS cnt_all FROM tasks GROUP BY taskId ORDER BY taskId +) AS t0 +LEFT OUTER JOIN ( + SELECT taskId, COUNT(1) AS cnt_x FROM tasks WHERE status="x" GROUP BY taskId +) AS t1 ON t0.taskId = t1.taskId +LEFT OUTER JOIN ( + SELECT taskId, COUNT(1) AS cnt_y FROM tasks WHERE status="y" GROUP BY taskId +) AS t2 ON t0.taskId = t2.taskId +LEFT OUTER JOIN ( + SELECT taskId, COUNT(1) AS cnt_z FROM tasks WHERE status="z" GROUP BY taskId +) AS t3 ON t0.taskId = t3.taskId +ORDER BY t0.taskId; diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/leftouterjoin/loj-03-no-listify.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/leftouterjoin/loj-03-no-listify.plan new file mode 100644 index 0000000..5184b51 --- /dev/null +++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/leftouterjoin/loj-03-no-listify.plan @@ -0,0 +1,127 @@ +-- DISTRIBUTE_RESULT |PARTITIONED| + -- ONE_TO_ONE_EXCHANGE |PARTITIONED| + -- STREAM_PROJECT |PARTITIONED| + -- ASSIGN |PARTITIONED| + -- SORT_MERGE_EXCHANGE [$$taskId(ASC) ] |PARTITIONED| + -- STABLE_SORT [$$taskId(ASC)] |PARTITIONED| + -- ONE_TO_ONE_EXCHANGE |PARTITIONED| + -- STREAM_PROJECT |PARTITIONED| + -- ONE_TO_ONE_EXCHANGE |PARTITIONED| + -- HYBRID_HASH_JOIN [$$taskId][$$taskId] |PARTITIONED| + -- ONE_TO_ONE_EXCHANGE |PARTITIONED| + -- STREAM_PROJECT |PARTITIONED| + -- ONE_TO_ONE_EXCHANGE |PARTITIONED| + -- HYBRID_HASH_JOIN [$$taskId][$$taskId] |PARTITIONED| + -- ONE_TO_ONE_EXCHANGE |PARTITIONED| + -- STREAM_PROJECT |PARTITIONED| + -- ONE_TO_ONE_EXCHANGE |PARTITIONED| + -- HYBRID_HASH_JOIN [$$taskId][$$taskId] |PARTITIONED| + -- HASH_PARTITION_MERGE_EXCHANGE MERGE:[$$taskId(ASC)] HASH:[$$taskId] |PARTITIONED| + -- SORT_GROUP_BY[$$263] |PARTITIONED| + { + -- AGGREGATE |LOCAL| + -- NESTED_TUPLE_SOURCE |LOCAL| + } + -- HASH_PARTITION_EXCHANGE [$$263] |PARTITIONED| + -- SORT_GROUP_BY[$$226] |PARTITIONED| + { + -- AGGREGATE |LOCAL| + -- NESTED_TUPLE_SOURCE |LOCAL| + } + -- ONE_TO_ONE_EXCHANGE |PARTITIONED| + -- STREAM_PROJECT |PARTITIONED| + -- ASSIGN |PARTITIONED| + -- ONE_TO_ONE_EXCHANGE |PARTITIONED| + -- REPLICATE |PARTITIONED| + -- ONE_TO_ONE_EXCHANGE |PARTITIONED| + -- ASSIGN |PARTITIONED| + -- STREAM_PROJECT |PARTITIONED| + -- ONE_TO_ONE_EXCHANGE |PARTITIONED| + -- DATASOURCE_SCAN |PARTITIONED| + -- ONE_TO_ONE_EXCHANGE |PARTITIONED| + -- EMPTY_TUPLE_SOURCE |PARTITIONED| + -- ONE_TO_ONE_EXCHANGE |PARTITIONED| + -- STREAM_PROJECT |PARTITIONED| + -- ASSIGN |PARTITIONED| + -- ONE_TO_ONE_EXCHANGE |PARTITIONED| + -- SORT_GROUP_BY[$$265] |PARTITIONED| + { + -- AGGREGATE |LOCAL| + -- NESTED_TUPLE_SOURCE |LOCAL| + } + -- HASH_PARTITION_EXCHANGE [$$265] |PARTITIONED| + -- SORT_GROUP_BY[$$227] |PARTITIONED| + { + -- AGGREGATE |LOCAL| + -- NESTED_TUPLE_SOURCE |LOCAL| + } + -- ONE_TO_ONE_EXCHANGE |PARTITIONED| + -- STREAM_PROJECT |PARTITIONED| + -- STREAM_SELECT |PARTITIONED| + -- ONE_TO_ONE_EXCHANGE |PARTITIONED| + -- REPLICATE |PARTITIONED| + -- ONE_TO_ONE_EXCHANGE |PARTITIONED| + -- ASSIGN |PARTITIONED| + -- STREAM_PROJECT |PARTITIONED| + -- ONE_TO_ONE_EXCHANGE |PARTITIONED| + -- DATASOURCE_SCAN |PARTITIONED| + -- ONE_TO_ONE_EXCHANGE |PARTITIONED| + -- EMPTY_TUPLE_SOURCE |PARTITIONED| + -- ONE_TO_ONE_EXCHANGE |PARTITIONED| + -- STREAM_PROJECT |PARTITIONED| + -- ASSIGN |PARTITIONED| + -- ONE_TO_ONE_EXCHANGE |PARTITIONED| + -- SORT_GROUP_BY[$$267] |PARTITIONED| + { + -- AGGREGATE |LOCAL| + -- NESTED_TUPLE_SOURCE |LOCAL| + } + -- HASH_PARTITION_EXCHANGE [$$267] |PARTITIONED| + -- SORT_GROUP_BY[$$228] |PARTITIONED| + { + -- AGGREGATE |LOCAL| + -- NESTED_TUPLE_SOURCE |LOCAL| + } + -- ONE_TO_ONE_EXCHANGE |PARTITIONED| + -- STREAM_PROJECT |PARTITIONED| + -- STREAM_SELECT |PARTITIONED| + -- STREAM_PROJECT |PARTITIONED| + -- ASSIGN |PARTITIONED| + -- ONE_TO_ONE_EXCHANGE |PARTITIONED| + -- REPLICATE |PARTITIONED| + -- ONE_TO_ONE_EXCHANGE |PARTITIONED| + -- ASSIGN |PARTITIONED| + -- STREAM_PROJECT |PARTITIONED| + -- ONE_TO_ONE_EXCHANGE |PARTITIONED| + -- DATASOURCE_SCAN |PARTITIONED| + -- ONE_TO_ONE_EXCHANGE |PARTITIONED| + -- EMPTY_TUPLE_SOURCE |PARTITIONED| + -- ONE_TO_ONE_EXCHANGE |PARTITIONED| + -- STREAM_PROJECT |PARTITIONED| + -- ASSIGN |PARTITIONED| + -- ONE_TO_ONE_EXCHANGE |PARTITIONED| + -- SORT_GROUP_BY[$$269] |PARTITIONED| + { + -- AGGREGATE |LOCAL| + -- NESTED_TUPLE_SOURCE |LOCAL| + } + -- HASH_PARTITION_EXCHANGE [$$269] |PARTITIONED| + -- SORT_GROUP_BY[$$229] |PARTITIONED| + { + -- AGGREGATE |LOCAL| + -- NESTED_TUPLE_SOURCE |LOCAL| + } + -- ONE_TO_ONE_EXCHANGE |PARTITIONED| + -- STREAM_PROJECT |PARTITIONED| + -- STREAM_SELECT |PARTITIONED| + -- STREAM_PROJECT |PARTITIONED| + -- ASSIGN |PARTITIONED| + -- ONE_TO_ONE_EXCHANGE |PARTITIONED| + -- REPLICATE |PARTITIONED| + -- ONE_TO_ONE_EXCHANGE |PARTITIONED| + -- ASSIGN |PARTITIONED| + -- STREAM_PROJECT |PARTITIONED| + -- ONE_TO_ONE_EXCHANGE |PARTITIONED| + -- DATASOURCE_SCAN |PARTITIONED| + -- ONE_TO_ONE_EXCHANGE |PARTITIONED| + -- EMPTY_TUPLE_SOURCE |PARTITIONED| diff --git a/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/subplan/AsterixMoveFreeVariableOperatorOutOfSubplanRule.java b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/leftouterjoin/loj-03-no-listify/loj-03-no-listify.1.ddl.sqlpp similarity index 62% copy from asterixdb/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/subplan/AsterixMoveFreeVariableOperatorOutOfSubplanRule.java copy to asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/leftouterjoin/loj-03-no-listify/loj-03-no-listify.1.ddl.sqlpp index 4d6b4bb..bc81bff 100644 --- a/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/subplan/AsterixMoveFreeVariableOperatorOutOfSubplanRule.java +++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/leftouterjoin/loj-03-no-listify/loj-03-no-listify.1.ddl.sqlpp @@ -16,15 +16,14 @@ * specific language governing permissions and limitations * under the License. */ -package org.apache.asterix.optimizer.rules.subplan; -import org.apache.hyracks.algebricks.core.algebra.base.LogicalOperatorTag; -import org.apache.hyracks.algebricks.rewriter.rules.subplan.MoveFreeVariableOperatorOutOfSubplanRule; +DROP DATAVERSE test IF EXISTS; +CREATE DATAVERSE test; -public class AsterixMoveFreeVariableOperatorOutOfSubplanRule extends MoveFreeVariableOperatorOutOfSubplanRule { +USE test; - @Override - protected boolean movableOperator(LogicalOperatorTag operatorTag) { - return (operatorTag == LogicalOperatorTag.ASSIGN); - } -} +CREATE TYPE tasksType AS { + id : integer +}; + +CREATE DATASET tasks(tasksType) PRIMARY KEY id; diff --git a/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/subplan/AsterixMoveFreeVariableOperatorOutOfSubplanRule.java b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/leftouterjoin/loj-03-no-listify/loj-03-no-listify.2.update.sqlpp similarity index 61% copy from asterixdb/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/subplan/AsterixMoveFreeVariableOperatorOutOfSubplanRule.java copy to asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/leftouterjoin/loj-03-no-listify/loj-03-no-listify.2.update.sqlpp index 4d6b4bb..061d357 100644 --- a/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/subplan/AsterixMoveFreeVariableOperatorOutOfSubplanRule.java +++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/leftouterjoin/loj-03-no-listify/loj-03-no-listify.2.update.sqlpp @@ -16,15 +16,21 @@ * specific language governing permissions and limitations * under the License. */ -package org.apache.asterix.optimizer.rules.subplan; -import org.apache.hyracks.algebricks.core.algebra.base.LogicalOperatorTag; -import org.apache.hyracks.algebricks.rewriter.rules.subplan.MoveFreeVariableOperatorOutOfSubplanRule; +USE test; -public class AsterixMoveFreeVariableOperatorOutOfSubplanRule extends MoveFreeVariableOperatorOutOfSubplanRule { - - @Override - protected boolean movableOperator(LogicalOperatorTag operatorTag) { - return (operatorTag == LogicalOperatorTag.ASSIGN); - } -} +INSERT INTO tasks +([ + {"id": 1, "taskId":1, "status":"x"}, + {"id": 2, "taskId":1, "status":"x"}, + {"id": 3, "taskId":1, "status":"y"}, + {"id": 4, "taskId":1, "status":"y"}, + {"id": 5, "taskId":1, "status":"z"}, + {"id": 6, "taskId":1, "status":"z"}, + {"id": 7, "taskId":2, "status":"x"}, + {"id": 8, "taskId":2, "status":"x"}, + {"id": 9, "taskId":2, "status":"y"}, + {"id": 10, "taskId":2, "status":"y"}, + {"id": 11, "taskId":2, "status":"z"}, + {"id": 12, "taskId":2, "status":"z"} +]); diff --git a/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/subplan/AsterixMoveFreeVariableOperatorOutOfSubplanRule.java b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/leftouterjoin/loj-03-no-listify/loj-03-no-listify.3.query.sqlpp similarity index 54% copy from asterixdb/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/subplan/AsterixMoveFreeVariableOperatorOutOfSubplanRule.java copy to asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/leftouterjoin/loj-03-no-listify/loj-03-no-listify.3.query.sqlpp index 4d6b4bb..d64e711 100644 --- a/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/subplan/AsterixMoveFreeVariableOperatorOutOfSubplanRule.java +++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/leftouterjoin/loj-03-no-listify/loj-03-no-listify.3.query.sqlpp @@ -16,15 +16,25 @@ * specific language governing permissions and limitations * under the License. */ -package org.apache.asterix.optimizer.rules.subplan; -import org.apache.hyracks.algebricks.core.algebra.base.LogicalOperatorTag; -import org.apache.hyracks.algebricks.rewriter.rules.subplan.MoveFreeVariableOperatorOutOfSubplanRule; +/* + * Description: Test that listify() is eliminated + * on the right side of an outer join + */ -public class AsterixMoveFreeVariableOperatorOutOfSubplanRule extends MoveFreeVariableOperatorOutOfSubplanRule { +USE test; - @Override - protected boolean movableOperator(LogicalOperatorTag operatorTag) { - return (operatorTag == LogicalOperatorTag.ASSIGN); - } -} +SELECT t0.taskId, t0.cnt_all, t1.cnt_x, t2.cnt_y, t3.cnt_z +FROM ( + SELECT taskId, COUNT(1) AS cnt_all FROM tasks GROUP BY taskId ORDER BY taskId +) AS t0 +LEFT OUTER JOIN ( + SELECT taskId, COUNT(1) AS cnt_x FROM tasks WHERE status="x" GROUP BY taskId +) AS t1 ON t0.taskId = t1.taskId +LEFT OUTER JOIN ( + SELECT taskId, COUNT(1) AS cnt_y FROM tasks WHERE status="y" GROUP BY taskId +) AS t2 ON t0.taskId = t2.taskId +LEFT OUTER JOIN ( + SELECT taskId, COUNT(1) AS cnt_z FROM tasks WHERE status="z" GROUP BY taskId +) AS t3 ON t0.taskId = t3.taskId +ORDER BY t0.taskId; diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/results/leftouterjoin/loj-03-no-listify/loj-03-no-listify.3.adm b/asterixdb/asterix-app/src/test/resources/runtimets/results/leftouterjoin/loj-03-no-listify/loj-03-no-listify.3.adm new file mode 100644 index 0000000..466b846 --- /dev/null +++ b/asterixdb/asterix-app/src/test/resources/runtimets/results/leftouterjoin/loj-03-no-listify/loj-03-no-listify.3.adm @@ -0,0 +1,2 @@ +{ "cnt_all": 6, "cnt_x": 2, "cnt_y": 2, "cnt_z": 2, "taskId": 1 } +{ "cnt_all": 6, "cnt_x": 2, "cnt_y": 2, "cnt_z": 2, "taskId": 2 } \ No newline at end of file diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/testsuite_sqlpp.xml b/asterixdb/asterix-app/src/test/resources/runtimets/testsuite_sqlpp.xml index 032097a..ff37ac5 100644 --- a/asterixdb/asterix-app/src/test/resources/runtimets/testsuite_sqlpp.xml +++ b/asterixdb/asterix-app/src/test/resources/runtimets/testsuite_sqlpp.xml @@ -11847,6 +11847,11 @@ </compilation-unit> </test-case> <test-case FilePath="leftouterjoin"> + <compilation-unit name="loj-03-no-listify"> + <output-dir compare="Text">loj-03-no-listify</output-dir> + </compilation-unit> + </test-case> + <test-case FilePath="leftouterjoin"> <compilation-unit name="query_issue658"> <output-dir compare="Text">query_issue658</output-dir> </compilation-unit> diff --git a/hyracks-fullstack/algebricks/algebricks-rewriter/src/main/java/org/apache/hyracks/algebricks/rewriter/rules/subplan/MoveFreeVariableOperatorOutOfSubplanRule.java b/hyracks-fullstack/algebricks/algebricks-rewriter/src/main/java/org/apache/hyracks/algebricks/rewriter/rules/subplan/MoveFreeVariableOperatorOutOfSubplanRule.java index 94cae74..66ee3a4 100644 --- a/hyracks-fullstack/algebricks/algebricks-rewriter/src/main/java/org/apache/hyracks/algebricks/rewriter/rules/subplan/MoveFreeVariableOperatorOutOfSubplanRule.java +++ b/hyracks-fullstack/algebricks/algebricks-rewriter/src/main/java/org/apache/hyracks/algebricks/rewriter/rules/subplan/MoveFreeVariableOperatorOutOfSubplanRule.java @@ -92,8 +92,7 @@ public class MoveFreeVariableOperatorOutOfSubplanRule extends AbstractDecorrelat ILogicalOperator childOp = childOpRef.getValue(); // Try to move operators that only uses free variables out of the subplan. - if (movableOperator(currentOp.getOperatorTag()) - && independentOperator(currentOp, liveVarsBeforeSubplan) + if (movableOperator(currentOp, liveVarsBeforeSubplan) && producedVariablesCanbePropagated(currentOp)) { extractOperator(subplanOp, inputOp, currentOpRef); inputOp = currentOp; @@ -109,12 +108,17 @@ public class MoveFreeVariableOperatorOutOfSubplanRule extends AbstractDecorrelat return changed; } - // Checks whether the current operator is independent of the nested input pipeline in the subplan. - private boolean independentOperator(ILogicalOperator op, Set<LogicalVariable> liveVarsBeforeSubplan) + private boolean movableOperator(ILogicalOperator op, Set<LogicalVariable> liveVarsBeforeSubplan) throws AlgebricksException { + if (!movableOperatorKind(op.getOperatorTag())) { + return false; + } + + // Checks whether the current operator is independent of the nested input pipeline in the subplan. Set<LogicalVariable> usedVars = new HashSet<>(); VariableUtilities.getUsedVariables(op, usedVars); - return liveVarsBeforeSubplan.containsAll(usedVars); + boolean independent = liveVarsBeforeSubplan.containsAll(usedVars); + return independent && movableIndependentOperator(op, usedVars); } // Checks whether there is a variable killing operator in the nested pipeline @@ -152,7 +156,11 @@ public class MoveFreeVariableOperatorOutOfSubplanRule extends AbstractDecorrelat currentOp.getInputs().get(0).setValue(inputOp); } - protected boolean movableOperator(LogicalOperatorTag operatorTag) { - return (operatorTag == LogicalOperatorTag.ASSIGN || operatorTag == LogicalOperatorTag.SUBPLAN); + protected boolean movableOperatorKind(LogicalOperatorTag operatorTag) { + return operatorTag == LogicalOperatorTag.ASSIGN || operatorTag == LogicalOperatorTag.SUBPLAN; + } + + protected boolean movableIndependentOperator(ILogicalOperator op, Set<LogicalVariable> usedVars) { + return true; } } diff --git a/hyracks-fullstack/algebricks/algebricks-rewriter/src/main/java/org/apache/hyracks/algebricks/rewriter/rules/subplan/PushSubplanIntoGroupByRule.java b/hyracks-fullstack/algebricks/algebricks-rewriter/src/main/java/org/apache/hyracks/algebricks/rewriter/rules/subplan/PushSubplanIntoGroupByRule.java index 6d5d67d..420bf12 100644 --- a/hyracks-fullstack/algebricks/algebricks-rewriter/src/main/java/org/apache/hyracks/algebricks/rewriter/rules/subplan/PushSubplanIntoGroupByRule.java +++ b/hyracks-fullstack/algebricks/algebricks-rewriter/src/main/java/org/apache/hyracks/algebricks/rewriter/rules/subplan/PushSubplanIntoGroupByRule.java @@ -70,29 +70,30 @@ public class PushSubplanIntoGroupByRule implements IAlgebraicRewriteRule { rootRef = opRef; invoked = true; } - return rewriteForOperator(rootRef, opRef, context); + return rewriteForOperator(rootRef, opRef.getValue(), context); } // The core rewriting function for an operator. - private boolean rewriteForOperator(Mutable<ILogicalOperator> rootRef, Mutable<ILogicalOperator> opRef, + private boolean rewriteForOperator(Mutable<ILogicalOperator> rootRef, ILogicalOperator parentOperator, IOptimizationContext context) throws AlgebricksException { boolean changed = false; - ILogicalOperator parentOperator = opRef.getValue(); - for (Mutable<ILogicalOperator> ref : parentOperator.getInputs()) { + List<Mutable<ILogicalOperator>> parentInputs = parentOperator.getInputs(); + for (int i = 0, n = parentInputs.size(); i < n; i++) { + Mutable<ILogicalOperator> ref = parentInputs.get(i); ILogicalOperator op = ref.getValue(); // Only processes subplan operator. - Deque<SubplanOperator> subplans = new ArrayDeque<>(); if (op.getOperatorTag() != LogicalOperatorTag.SUBPLAN) { // Recursively rewrites the child plan. - changed |= rewriteForOperator(rootRef, ref, context); + changed |= rewriteForOperator(rootRef, op, context); continue; } + Deque<SubplanOperator> subplans = new ArrayDeque<>(); while (op.getOperatorTag() == LogicalOperatorTag.SUBPLAN) { SubplanOperator currentSubplan = (SubplanOperator) op; // Recursively rewrites the pipelines inside a nested subplan. for (ILogicalPlan subplan : currentSubplan.getNestedPlans()) { for (Mutable<ILogicalOperator> nestedRootRef : subplan.getRoots()) { - changed |= rewriteForOperator(nestedRootRef, nestedRootRef, context); + changed |= rewriteForOperator(nestedRootRef, nestedRootRef.getValue(), context); } } subplans.addFirst(currentSubplan); @@ -106,17 +107,17 @@ public class PushSubplanIntoGroupByRule implements IAlgebraicRewriteRule { // Recursively rewrites the pipelines inside a nested subplan. for (ILogicalPlan subplan : gby.getNestedPlans()) { for (Mutable<ILogicalOperator> nestedRootRef : subplan.getRoots()) { - changed |= rewriteForOperator(nestedRootRef, nestedRootRef, context); + changed |= rewriteForOperator(nestedRootRef, nestedRootRef.getValue(), context); } } - changed |= pushSubplansIntoGroupBy(rootRef, parentOperator, subplans, gby, context); + changed |= pushSubplansIntoGroupBy(rootRef, parentOperator, i, subplans, gby, context); } return changed; } // Pushes subplans into the group by operator. private boolean pushSubplansIntoGroupBy(Mutable<ILogicalOperator> currentRootRef, ILogicalOperator parentOperator, - Deque<SubplanOperator> subplans, GroupByOperator gby, IOptimizationContext context) + int parentChildIdx, Deque<SubplanOperator> subplans, GroupByOperator gby, IOptimizationContext context) throws AlgebricksException { boolean changed = false; List<ILogicalPlan> newGbyNestedPlans = new ArrayList<>(); @@ -226,8 +227,16 @@ public class PushSubplanIntoGroupByRule implements IAlgebraicRewriteRule { gby.getNestedPlans().addAll(newGbyNestedPlans); // Connects the group-by operator with its parent operator. - ILogicalOperator parent = !subplans.isEmpty() ? subplans.getFirst() : parentOperator; - parent.getInputs().get(0).setValue(gby); + ILogicalOperator parent; + int childIdx; + if (!subplans.isEmpty()) { + parent = subplans.getFirst(); + childIdx = 0; + } else { + parent = parentOperator; + childIdx = parentChildIdx; + } + parent.getInputs().get(childIdx).setValue(gby); // Removes unnecessary pipelines inside the group by operator. changed |= cleanup(currentRootRef.getValue(), gby);
