Yingyi Bu has submitted this change and it was merged. Change subject: [ASTERIXDB-2044][COMP] Eliminate listify for complex group-by ......................................................................
[ASTERIXDB-2044][COMP] Eliminate listify for complex group-by - user model changes: no - storage format changes: no - interface changes: no Details: - Fix EliminateSubplanWithInputCardinalityOneRule to handle recursive subplans; - Fix various places that assumes the nested plans inside a group-by operator cannot be empty; - Added regression tests. Change-Id: Ida9aa8d89a89f90256e54c8c1806af9b4a162d21 Reviewed-on: https://asterix-gerrit.ics.uci.edu/1946 Integration-Tests: Jenkins <jenk...@fulliautomatix.ics.uci.edu> Tested-by: Jenkins <jenk...@fulliautomatix.ics.uci.edu> Contrib: Jenkins <jenk...@fulliautomatix.ics.uci.edu> Reviewed-by: Yingyi Bu <buyin...@gmail.com> --- A asterixdb/asterix-app/src/test/resources/optimizerts/queries/query-ASTERIXDB-810-2.sqlpp A asterixdb/asterix-app/src/test/resources/optimizerts/queries/query-ASTERIXDB-810.sqlpp A asterixdb/asterix-app/src/test/resources/optimizerts/results/query-ASTERIXDB-810-2.plan A asterixdb/asterix-app/src/test/resources/optimizerts/results/query-ASTERIXDB-810.plan M asterixdb/asterix-app/src/test/resources/optimizerts/results/udfs/query-ASTERIXDB-1308-1.plan M hyracks-fullstack/algebricks/algebricks-core/src/main/java/org/apache/hyracks/algebricks/core/algebra/operators/physical/PreclusteredGroupByPOperator.java M hyracks-fullstack/algebricks/algebricks-core/src/main/java/org/apache/hyracks/algebricks/core/algebra/typing/AbstractTypeEnvironment.java M hyracks-fullstack/algebricks/algebricks-rewriter/src/main/java/org/apache/hyracks/algebricks/rewriter/rules/AbstractIntroduceGroupByCombinerRule.java M hyracks-fullstack/algebricks/algebricks-rewriter/src/main/java/org/apache/hyracks/algebricks/rewriter/rules/PushNestedOrderByUnderPreSortedGroupByRule.java M hyracks-fullstack/algebricks/algebricks-rewriter/src/main/java/org/apache/hyracks/algebricks/rewriter/rules/subplan/EliminateSubplanWithInputCardinalityOneRule.java 10 files changed, 277 insertions(+), 46 deletions(-) Approvals: Yingyi Bu: Looks good to me, approved Anon. E. Moose #1000171: Jenkins: Verified; ; Verified Objections: Jenkins: Violations found diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/queries/query-ASTERIXDB-810-2.sqlpp b/asterixdb/asterix-app/src/test/resources/optimizerts/queries/query-ASTERIXDB-810-2.sqlpp new file mode 100644 index 0000000..b6f6159 --- /dev/null +++ b/asterixdb/asterix-app/src/test/resources/optimizerts/queries/query-ASTERIXDB-810-2.sqlpp @@ -0,0 +1,73 @@ +/* + * 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 : This test case is to verify the fix for issue810 + * https://code.google.com/p/asterixdb/issues/detail?id=810 + * Expected Res : SUCCESS + * Date : 16th Nov. 2014 + */ + +DROP DATAVERSE tpch IF EXISTS; +CREATE dataverse tpch; + +USE tpch; + + +CREATE TYPE LineItemType AS CLOSED { + l_orderkey : integer, + l_partkey : integer, + l_suppkey : integer, + l_linenumber : integer, + l_quantity : double, + l_extendedprice : double, + l_discount : double, + l_tax : double, + l_returnflag : string, + l_linestatus : string, + l_shipdate : string, + l_commitdate : string, + l_receiptdate : string, + l_shipinstruct : string, + l_shipmode : string, + l_comment : string +} + +CREATE DATASET LineItem(LineItemType) PRIMARY KEY l_orderkey,l_linenumber; + + +SELECT l_returnflag AS l_returnflag, + l_linestatus AS l_linestatus, + coll_count(cheap) AS count_cheaps, + coll_count(expensive) AS count_expensives +FROM LineItem AS l +/* +hash */ +GROUP BY l.l_returnflag AS l_returnflag,l.l_linestatus AS l_linestatus +GROUP AS g +LET cheap = ( + SELECT ELEMENT g.l + FROM g + WHERE g.l.l_discount > 0.05 +), +expensive = ( + SELECT ELEMENT g.l + FROM g + WHERE g.l.l_discount <= 0.05 +) +ORDER BY l_returnflag,l_linestatus +; diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/queries/query-ASTERIXDB-810.sqlpp b/asterixdb/asterix-app/src/test/resources/optimizerts/queries/query-ASTERIXDB-810.sqlpp new file mode 100644 index 0000000..451f163 --- /dev/null +++ b/asterixdb/asterix-app/src/test/resources/optimizerts/queries/query-ASTERIXDB-810.sqlpp @@ -0,0 +1,73 @@ +/* + * 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 : This test case is to verify the fix for issue810 + * https://code.google.com/p/asterixdb/issues/detail?id=810 + * Expected Res : SUCCESS + * Date : 16th Nov. 2014 + */ + +DROP DATAVERSE tpch IF EXISTS; +CREATE dataverse tpch; + +USE tpch; + + +CREATE TYPE LineItemType AS CLOSED { + l_orderkey : integer, + l_partkey : integer, + l_suppkey : integer, + l_linenumber : integer, + l_quantity : double, + l_extendedprice : double, + l_discount : double, + l_tax : double, + l_returnflag : string, + l_linestatus : string, + l_shipdate : string, + l_commitdate : string, + l_receiptdate : string, + l_shipinstruct : string, + l_shipmode : string, + l_comment : string +} + +CREATE DATASET LineItem(LineItemType) PRIMARY KEY l_orderkey,l_linenumber; + + +SELECT l_returnflag AS l_returnflag, + l_linestatus AS l_linestatus, + coll_count(cheap) AS count_cheaps, + coll_count(expensive) AS count_expensives +FROM LineItem AS l +/* +hash */ +GROUP BY l.l_returnflag AS l_returnflag,l.l_linestatus AS l_linestatus +GROUP AS g +LET cheap = ( + SELECT ELEMENT m + FROM (FROM g SELECT VALUE l) AS m + WHERE m.l_discount > 0.05 +), +expensive = ( + SELECT ELEMENT m + FROM (FROM g SELECT VALUE l) AS m + WHERE m.l_discount <= 0.05 +) +ORDER BY l_returnflag,l_linestatus +; diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/query-ASTERIXDB-810-2.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/query-ASTERIXDB-810-2.plan new file mode 100644 index 0000000..cad2fbb --- /dev/null +++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/query-ASTERIXDB-810-2.plan @@ -0,0 +1,37 @@ +-- DISTRIBUTE_RESULT |PARTITIONED| + -- ONE_TO_ONE_EXCHANGE |PARTITIONED| + -- STREAM_PROJECT |PARTITIONED| + -- ASSIGN |PARTITIONED| + -- SORT_MERGE_EXCHANGE [$$l_returnflag(ASC), $$l_linestatus(ASC) ] |PARTITIONED| + -- PRE_CLUSTERED_GROUP_BY[$$42, $$43] |PARTITIONED| + { + -- AGGREGATE |LOCAL| + -- NESTED_TUPLE_SOURCE |LOCAL| + } + { + -- AGGREGATE |LOCAL| + -- NESTED_TUPLE_SOURCE |LOCAL| + } + -- ONE_TO_ONE_EXCHANGE |PARTITIONED| + -- STABLE_SORT [$$42(ASC), $$43(ASC)] |PARTITIONED| + -- HASH_PARTITION_EXCHANGE [$$42, $$43] |PARTITIONED| + -- PRE_CLUSTERED_GROUP_BY[$$30, $$31] |PARTITIONED| + { + -- AGGREGATE |LOCAL| + -- STREAM_SELECT |LOCAL| + -- NESTED_TUPLE_SOURCE |LOCAL| + } + { + -- AGGREGATE |LOCAL| + -- STREAM_SELECT |LOCAL| + -- NESTED_TUPLE_SOURCE |LOCAL| + } + -- ONE_TO_ONE_EXCHANGE |PARTITIONED| + -- STABLE_SORT [$$30(ASC), $$31(ASC)] |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-app/src/test/resources/optimizerts/results/query-ASTERIXDB-810.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/query-ASTERIXDB-810.plan new file mode 100644 index 0000000..1c56f1c --- /dev/null +++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/query-ASTERIXDB-810.plan @@ -0,0 +1,39 @@ +-- DISTRIBUTE_RESULT |PARTITIONED| + -- ONE_TO_ONE_EXCHANGE |PARTITIONED| + -- STREAM_PROJECT |PARTITIONED| + -- ASSIGN |PARTITIONED| + -- SORT_MERGE_EXCHANGE [$$l_returnflag(ASC), $$l_linestatus(ASC) ] |PARTITIONED| + -- PRE_CLUSTERED_GROUP_BY[$$42, $$43] |PARTITIONED| + { + -- AGGREGATE |LOCAL| + -- NESTED_TUPLE_SOURCE |LOCAL| + } + { + -- AGGREGATE |LOCAL| + -- NESTED_TUPLE_SOURCE |LOCAL| + } + -- ONE_TO_ONE_EXCHANGE |PARTITIONED| + -- STABLE_SORT [$$42(ASC), $$43(ASC)] |PARTITIONED| + -- HASH_PARTITION_EXCHANGE [$$42, $$43] |PARTITIONED| + -- PRE_CLUSTERED_GROUP_BY[$$32, $$33] |PARTITIONED| + { + -- AGGREGATE |LOCAL| + -- STREAM_SELECT |LOCAL| + -- NESTED_TUPLE_SOURCE |LOCAL| + } + { + -- AGGREGATE |LOCAL| + -- STREAM_SELECT |LOCAL| + -- NESTED_TUPLE_SOURCE |LOCAL| + } + -- ONE_TO_ONE_EXCHANGE |PARTITIONED| + -- STABLE_SORT [$$32(ASC), $$33(ASC)] |PARTITIONED| + -- ONE_TO_ONE_EXCHANGE |PARTITIONED| + -- ASSIGN |PARTITIONED| + -- STREAM_PROJECT |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-app/src/test/resources/optimizerts/results/udfs/query-ASTERIXDB-1308-1.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/udfs/query-ASTERIXDB-1308-1.plan index 1e60aed..f86825e 100644 --- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/udfs/query-ASTERIXDB-1308-1.plan +++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/udfs/query-ASTERIXDB-1308-1.plan @@ -27,15 +27,10 @@ -- AGGREGATE |LOCAL| -- AGGREGATE |LOCAL| -- STREAM_SELECT |UNPARTITIONED| - -- UNNEST |UNPARTITIONED| - -- SUBPLAN |UNPARTITIONED| - { - -- AGGREGATE |UNPARTITIONED| - -- IN_MEMORY_STABLE_SORT [$$j(ASC)] |UNPARTITIONED| - -- UNNEST |UNPARTITIONED| - -- NESTED_TUPLE_SOURCE |UNPARTITIONED| - } - -- NESTED_TUPLE_SOURCE |UNPARTITIONED| + -- RUNNING_AGGREGATE |UNPARTITIONED| + -- IN_MEMORY_STABLE_SORT [$$j(ASC)] |UNPARTITIONED| + -- UNNEST |UNPARTITIONED| + -- NESTED_TUPLE_SOURCE |UNPARTITIONED| } -- ASSIGN |UNPARTITIONED| -- EMPTY_TUPLE_SOURCE |UNPARTITIONED| diff --git a/hyracks-fullstack/algebricks/algebricks-core/src/main/java/org/apache/hyracks/algebricks/core/algebra/operators/physical/PreclusteredGroupByPOperator.java b/hyracks-fullstack/algebricks/algebricks-core/src/main/java/org/apache/hyracks/algebricks/core/algebra/operators/physical/PreclusteredGroupByPOperator.java index a636d10..5a465f7 100644 --- a/hyracks-fullstack/algebricks/algebricks-core/src/main/java/org/apache/hyracks/algebricks/core/algebra/operators/physical/PreclusteredGroupByPOperator.java +++ b/hyracks-fullstack/algebricks/algebricks-core/src/main/java/org/apache/hyracks/algebricks/core/algebra/operators/physical/PreclusteredGroupByPOperator.java @@ -23,6 +23,7 @@ import org.apache.hyracks.algebricks.common.exceptions.AlgebricksException; import org.apache.hyracks.algebricks.core.algebra.base.IHyracksJobBuilder; import org.apache.hyracks.algebricks.core.algebra.base.ILogicalOperator; +import org.apache.hyracks.algebricks.core.algebra.base.ILogicalPlan; import org.apache.hyracks.algebricks.core.algebra.base.LogicalOperatorTag; import org.apache.hyracks.algebricks.core.algebra.base.LogicalVariable; import org.apache.hyracks.algebricks.core.algebra.base.PhysicalOperatorTag; @@ -70,7 +71,8 @@ AlgebricksPipeline[] subplans = compileSubplans(inputSchemas[0], gby, opSchema, context); IAggregatorDescriptorFactory aggregatorFactory; - if (gby.getNestedPlans().get(0).getRoots().get(0).getValue() + List<ILogicalPlan> nestedPlans = gby.getNestedPlans(); + if (!nestedPlans.isEmpty() && nestedPlans.get(0).getRoots().get(0).getValue() .getOperatorTag() == LogicalOperatorTag.RUNNINGAGGREGATE) { aggregatorFactory = new NestedPlansRunningAggregatorFactory(subplans, keys, fdColumns); } else { diff --git a/hyracks-fullstack/algebricks/algebricks-core/src/main/java/org/apache/hyracks/algebricks/core/algebra/typing/AbstractTypeEnvironment.java b/hyracks-fullstack/algebricks/algebricks-core/src/main/java/org/apache/hyracks/algebricks/core/algebra/typing/AbstractTypeEnvironment.java index c4ff55b..f530820 100644 --- a/hyracks-fullstack/algebricks/algebricks-core/src/main/java/org/apache/hyracks/algebricks/core/algebra/typing/AbstractTypeEnvironment.java +++ b/hyracks-fullstack/algebricks/algebricks-core/src/main/java/org/apache/hyracks/algebricks/core/algebra/typing/AbstractTypeEnvironment.java @@ -52,11 +52,10 @@ @Override public boolean substituteProducedVariable(LogicalVariable v1, LogicalVariable v2) throws AlgebricksException { - Object t = varTypeMap.get(v1); + Object t = varTypeMap.remove(v1); if (t == null) { return false; } - varTypeMap.put(v1, null); varTypeMap.put(v2, t); return true; } diff --git a/hyracks-fullstack/algebricks/algebricks-rewriter/src/main/java/org/apache/hyracks/algebricks/rewriter/rules/AbstractIntroduceGroupByCombinerRule.java b/hyracks-fullstack/algebricks/algebricks-rewriter/src/main/java/org/apache/hyracks/algebricks/rewriter/rules/AbstractIntroduceGroupByCombinerRule.java index 4ef1cd5..e73f2a5 100644 --- a/hyracks-fullstack/algebricks/algebricks-rewriter/src/main/java/org/apache/hyracks/algebricks/rewriter/rules/AbstractIntroduceGroupByCombinerRule.java +++ b/hyracks-fullstack/algebricks/algebricks-rewriter/src/main/java/org/apache/hyracks/algebricks/rewriter/rules/AbstractIntroduceGroupByCombinerRule.java @@ -163,6 +163,11 @@ } } + // Nothing is pushed. + if (bi.modifyGbyMap.isEmpty()) { + return null; + } + ArrayList<LogicalVariable> newOpGbyList = new ArrayList<LogicalVariable>(); ArrayList<LogicalVariable> replGbyList = new ArrayList<LogicalVariable>(); // Find maximal sequence of variable. diff --git a/hyracks-fullstack/algebricks/algebricks-rewriter/src/main/java/org/apache/hyracks/algebricks/rewriter/rules/PushNestedOrderByUnderPreSortedGroupByRule.java b/hyracks-fullstack/algebricks/algebricks-rewriter/src/main/java/org/apache/hyracks/algebricks/rewriter/rules/PushNestedOrderByUnderPreSortedGroupByRule.java index bdab689..fc7b98e 100644 --- a/hyracks-fullstack/algebricks/algebricks-rewriter/src/main/java/org/apache/hyracks/algebricks/rewriter/rules/PushNestedOrderByUnderPreSortedGroupByRule.java +++ b/hyracks-fullstack/algebricks/algebricks-rewriter/src/main/java/org/apache/hyracks/algebricks/rewriter/rules/PushNestedOrderByUnderPreSortedGroupByRule.java @@ -64,6 +64,9 @@ return false; } GroupByOperator gby = (GroupByOperator) op; + if (gby.getNestedPlans().isEmpty()) { + return false; + } ILogicalPlan plan = gby.getNestedPlans().get(0); AbstractLogicalOperator op1 = (AbstractLogicalOperator) plan.getRoots().get(0).getValue(); if (op1.getOperatorTag() != LogicalOperatorTag.AGGREGATE) { diff --git a/hyracks-fullstack/algebricks/algebricks-rewriter/src/main/java/org/apache/hyracks/algebricks/rewriter/rules/subplan/EliminateSubplanWithInputCardinalityOneRule.java b/hyracks-fullstack/algebricks/algebricks-rewriter/src/main/java/org/apache/hyracks/algebricks/rewriter/rules/subplan/EliminateSubplanWithInputCardinalityOneRule.java index 2cd857a..607ea1f 100644 --- a/hyracks-fullstack/algebricks/algebricks-rewriter/src/main/java/org/apache/hyracks/algebricks/rewriter/rules/subplan/EliminateSubplanWithInputCardinalityOneRule.java +++ b/hyracks-fullstack/algebricks/algebricks-rewriter/src/main/java/org/apache/hyracks/algebricks/rewriter/rules/subplan/EliminateSubplanWithInputCardinalityOneRule.java @@ -65,27 +65,39 @@ rootRef = opRef; invoked = true; } + return rewriteForOperator(rootRef, opRef, context); + } + + private boolean rewriteForOperator(Mutable<ILogicalOperator> rootRef, Mutable<ILogicalOperator> opRef, + IOptimizationContext context) throws AlgebricksException { AbstractLogicalOperator op = (AbstractLogicalOperator) opRef.getValue(); if (op.getInputs().size() <= 0) { return false; } boolean changed = false; - for (Mutable<ILogicalOperator> subplanRef : op.getInputs()) { - AbstractLogicalOperator op1 = (AbstractLogicalOperator) subplanRef.getValue(); + + for (Mutable<ILogicalOperator> currentOpRef : op.getInputs()) { + AbstractLogicalOperator op1 = (AbstractLogicalOperator) currentOpRef.getValue(); if (op1.getOperatorTag() != LogicalOperatorTag.SUBPLAN) { + changed |= rewriteForOperator(rootRef, currentOpRef, context); continue; } SubplanOperator subplan = (SubplanOperator) op1; - Set<LogicalVariable> usedVarsUp = new ListSet<LogicalVariable>(); + Set<LogicalVariable> usedVarsUp = new ListSet<>(); OperatorPropertiesUtil.getFreeVariablesInPath(rootRef.getValue(), subplan, usedVarsUp); // TODO(buyingyi): figure out the rewriting for subplan operators with multiple subplans. if (subplan.getNestedPlans().size() != 1) { continue; } + // Recursively rewrites the pipelines inside a nested subplan. + for (Mutable<ILogicalOperator> nestedRootRef : subplan.getNestedPlans().get(0).getRoots()) { + changed |= this.rewriteForOperator(nestedRootRef, nestedRootRef, context); + } + ILogicalOperator subplanInputOperator = subplan.getInputs().get(0).getValue(); - Set<LogicalVariable> subplanInputVars = new ListSet<LogicalVariable>(); + Set<LogicalVariable> subplanInputVars = new ListSet<>(); VariableUtilities.getLiveVariables(subplanInputOperator, subplanInputVars); int subplanInputVarSize = subplanInputVars.size(); subplanInputVars.removeAll(usedVarsUp); @@ -93,31 +105,31 @@ if (subplanInputVars.size() < subplanInputVarSize) { continue; } - Set<LogicalVariable> freeVars = new ListSet<LogicalVariable>(); + Set<LogicalVariable> freeVars = new ListSet<>(); OperatorPropertiesUtil.getFreeVariablesInSubplans(subplan, freeVars); boolean cardinalityOne = isCardinalityOne(subplan.getInputs().get(0), freeVars); - if (cardinalityOne) { - /** If the cardinality of freeVars in the subplan is one, the subplan can be removed. */ - ILogicalPlan plan = subplan.getNestedPlans().get(0); - - List<Mutable<ILogicalOperator>> rootRefs = plan.getRoots(); - // TODO(buyingyi): investigate the case of multi-root plans. - if (rootRefs.size() != 1) { - continue; - } - - // Replaces all Nts' in the nested plan with the Subplan input operator or its deep copy. - ILogicalOperator topOperator = rootRefs.get(0).getValue(); - ReplaceNtsWithSubplanInputOperatorVisitor visitor = new ReplaceNtsWithSubplanInputOperatorVisitor( - context, subplan); - ILogicalOperator newTopOperator = topOperator.accept(visitor, null); - subplanRef.setValue(newTopOperator); - OperatorManipulationUtil.computeTypeEnvironmentBottomUp(newTopOperator, context); - changed = true; - } else { + if (!cardinalityOne) { continue; } + /** If the cardinality of freeVars in the subplan is one, the subplan can be removed. */ + ILogicalPlan plan = subplan.getNestedPlans().get(0); + + List<Mutable<ILogicalOperator>> rootRefs = plan.getRoots(); + // TODO(buyingyi): investigate the case of multi-root plans. + if (rootRefs.size() != 1) { + continue; + } + + // Replaces all Nts' in the nested plan with the Subplan input operator or its deep copy. + ILogicalOperator topOperator = rootRefs.get(0).getValue(); + ReplaceNtsWithSubplanInputOperatorVisitor visitor = new ReplaceNtsWithSubplanInputOperatorVisitor(context, + subplan); + ILogicalOperator newTopOperator = topOperator.accept(visitor, null); + currentOpRef.setValue(newTopOperator); + OperatorManipulationUtil.computeTypeEnvironmentBottomUp(newTopOperator, context); + changed = true; } + return changed; } @@ -133,8 +145,8 @@ */ private boolean isCardinalityOne(Mutable<ILogicalOperator> opRef, Set<LogicalVariable> freeVars) throws AlgebricksException { - Set<LogicalVariable> varsWithCardinalityOne = new ListSet<LogicalVariable>(); - Set<LogicalVariable> varsLiveAtUnnestAndJoin = new ListSet<LogicalVariable>(); + Set<LogicalVariable> varsWithCardinalityOne = new ListSet<>(); + Set<LogicalVariable> varsLiveAtUnnestAndJoin = new ListSet<>(); isCardinalityOne(opRef, freeVars, varsWithCardinalityOne, varsLiveAtUnnestAndJoin); varsWithCardinalityOne.removeAll(varsLiveAtUnnestAndJoin); return varsWithCardinalityOne.equals(freeVars); @@ -158,7 +170,7 @@ Set<LogicalVariable> varsWithCardinalityOne, Set<LogicalVariable> varsLiveAtUnnestAndJoin) throws AlgebricksException { AbstractLogicalOperator operator = (AbstractLogicalOperator) opRef.getValue(); - List<LogicalVariable> liveVars = new ArrayList<LogicalVariable>(); + List<LogicalVariable> liveVars = new ArrayList<>(); VariableUtilities.getLiveVariables(operator, liveVars); if (OperatorPropertiesUtil.isCardinalityZeroOrOne(operator)) { @@ -175,13 +187,6 @@ || operator.getOperatorTag() == LogicalOperatorTag.LEFTOUTERJOIN) { VariableUtilities.getLiveVariables(operator, varsLiveAtUnnestAndJoin); } - } - - if (varsWithCardinalityOne.size() == freeVars.size()) { - return; - } - for (Mutable<ILogicalOperator> childRef : operator.getInputs()) { - isCardinalityOne(childRef, freeVars, varsWithCardinalityOne, varsLiveAtUnnestAndJoin); } } -- To view, visit https://asterix-gerrit.ics.uci.edu/1946 To unsubscribe, visit https://asterix-gerrit.ics.uci.edu/settings Gerrit-MessageType: merged Gerrit-Change-Id: Ida9aa8d89a89f90256e54c8c1806af9b4a162d21 Gerrit-PatchSet: 6 Gerrit-Project: asterixdb Gerrit-Branch: master Gerrit-Owner: Yingyi Bu <buyin...@gmail.com> Gerrit-Reviewer: Anon. E. Moose #1000171 Gerrit-Reviewer: Dmitry Lychagin <dmitry.lycha...@couchbase.com> Gerrit-Reviewer: Jenkins <jenk...@fulliautomatix.ics.uci.edu> Gerrit-Reviewer: Till Westmann <ti...@apache.org> Gerrit-Reviewer: Yingyi Bu <buyin...@gmail.com>