You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@asterixdb.apache.org by ti...@apache.org on 2016/09/07 04:39:25 UTC
[4/4] asterixdb git commit: ASTERIXDB-1581: fix subquery
decorrelation.
ASTERIXDB-1581: fix subquery decorrelation.
- fix concurrent modification exception;
- fix variable substitution ordering;
- fix required partitioning property for DataSourceScan;
- fix partitioning property enforcer for nested operators;
- fix recursive subplan decorrelation;
- fix CardinalityInferenceVisitor;
- add a rule to switch inner join branches;
- fix SimpleUnnestToProductRule;
- add test cases which are variants of ASTERIXDB-1581.
Change-Id: Ia2fa4b5b836eafee1975bd1164ae7c22199a4af0
Reviewed-on: https://asterix-gerrit.ics.uci.edu/1125
Tested-by: Jenkins <je...@fulliautomatix.ics.uci.edu>
Integration-Tests: Jenkins <je...@fulliautomatix.ics.uci.edu>
Reviewed-by: Till Westmann <ti...@apache.org>
Project: http://git-wip-us.apache.org/repos/asf/asterixdb/repo
Commit: http://git-wip-us.apache.org/repos/asf/asterixdb/commit/c89d668f
Tree: http://git-wip-us.apache.org/repos/asf/asterixdb/tree/c89d668f
Diff: http://git-wip-us.apache.org/repos/asf/asterixdb/diff/c89d668f
Branch: refs/heads/master
Commit: c89d668f68e5430a6ba4455daf8f9cd6f7040dd8
Parents: ae2fbc6
Author: Yingyi Bu <yi...@couchbase.com>
Authored: Tue Sep 6 18:29:23 2016 -0700
Committer: Till Westmann <ti...@apache.org>
Committed: Tue Sep 6 21:38:37 2016 -0700
----------------------------------------------------------------------
.../asterix/optimizer/base/RuleCollections.java | 2 +
.../rules/am/InvertedIndexAccessMethod.java | 7 +-
.../subplan/InlineAllNtsInSubplanVisitor.java | 16 +-
...ineSubplanInputForNestedTupleSourceRule.java | 154 +++++-----
.../rules/subplan/SubplanFlatteningUtil.java | 78 +++--
.../LangExpressionToPlanTranslator.java | 29 +-
.../queries/join-singletonbranch-2.sqlpp | 43 +++
.../queries/join-singletonbranch-3.sqlpp | 42 +++
.../queries/join-singletonbranch.sqlpp | 41 +++
.../tpcds/query-ASTERIXDB-1581-correlated.sqlpp | 96 +++++++
.../queries/tpcds/query-ASTERIXDB-1581.sqlpp | 96 +++++++
.../optimizerts/results/filter-nested.plan | 4 +-
.../results/join-singletonbranch-2.plan | 28 ++
.../results/join-singletonbranch-3.plan | 23 ++
.../results/join-singletonbranch.plan | 28 ++
.../optimizerts/results/nest_aggregate.plan | 6 +-
.../tpcds/query-ASTERIXDB-1581-correlated.plan | 281 +++++++++++++++++++
.../results/tpcds/query-ASTERIXDB-1581.plan | 180 ++++++++++++
.../results/udfs/query-ASTERIXDB-1018.plan | 79 +++---
.../results/udfs/query-ASTERIXDB-1019.plan | 79 +++---
.../aggregate_join/aggregate_join.1.ddl.sqlpp | 31 ++
.../aggregate_join.2.update.sqlpp | 23 ++
.../aggregate_join/aggregate_join.3.query.sqlpp | 26 ++
.../aggregate_join_external.1.ddl.sqlpp | 55 ++++
.../aggregate_join_external.3.query.sqlpp | 27 ++
.../query-ASTERIXDB-1581-2.1.ddl.sqlpp | 82 ++++++
.../query-ASTERIXDB-1581-2.2.update.sqlpp | 26 ++
.../query-ASTERIXDB-1581-2.3.query.sqlpp | 33 +++
.../query-ASTERIXDB-1581-3.1.ddl.sqlpp | 82 ++++++
.../query-ASTERIXDB-1581-3.2.update.sqlpp | 26 ++
.../query-ASTERIXDB-1581-3.3.query.sqlpp | 32 +++
.../query-ASTERIXDB-1581-4.1.ddl.sqlpp | 82 ++++++
.../query-ASTERIXDB-1581-4.2.update.sqlpp | 26 ++
.../query-ASTERIXDB-1581-4.3.query.sqlpp | 32 +++
.../query-ASTERIXDB-1581-5.1.ddl.sqlpp | 82 ++++++
.../query-ASTERIXDB-1581-5.2.update.sqlpp | 26 ++
.../query-ASTERIXDB-1581-5.3.query.sqlpp | 32 +++
.../query-ASTERIXDB-1581-6.1.ddl.sqlpp | 82 ++++++
.../query-ASTERIXDB-1581-6.2.update.sqlpp | 26 ++
.../query-ASTERIXDB-1581-6.3.query.sqlpp | 35 +++
...uery-ASTERIXDB-1581-correlated-2.1.ddl.sqlpp | 82 ++++++
...y-ASTERIXDB-1581-correlated-2.2.update.sqlpp | 26 ++
...ry-ASTERIXDB-1581-correlated-2.3.query.sqlpp | 34 +++
.../query-ASTERIXDB-1581-correlated.1.ddl.sqlpp | 82 ++++++
...ery-ASTERIXDB-1581-correlated.2.update.sqlpp | 26 ++
...uery-ASTERIXDB-1581-correlated.3.query.sqlpp | 34 +++
.../query-ASTERIXDB-1581.1.ddl.sqlpp | 82 ++++++
.../query-ASTERIXDB-1581.2.update.sqlpp | 26 ++
.../query-ASTERIXDB-1581.3.query.sqlpp | 29 ++
.../aggregate_join/aggregate_join.1.adm | 1 +
.../aggregate_join_external.1.adm | 5 +
.../query-ASTERIXDB-1581-2.1.adm | 1 +
.../query-ASTERIXDB-1581-4.1.adm | 1 +
.../query-ASTERIXDB-1581-6.1.adm | 1 +
.../query-ASTERIXDB-1581-correlated.1.adm | 1 +
.../query-ASTERIXDB-1581.1.adm | 1 +
.../resources/runtimets/testsuite_sqlpp.xml | 50 ++++
.../metadata/declared/AqlDataSource.java | 1 +
.../core/algebra/metadata/IDataSource.java | 3 +
.../visitors/CardinalityInferenceVisitor.java | 162 +++++++++--
.../IsomorphismVariableMappingVisitor.java | 29 +-
...OperatorDeepCopyWithNewVariablesVisitor.java | 34 ++-
.../logical/visitors/VariableUtilities.java | 23 +-
.../physical/DataSourceScanPOperator.java | 25 ++
.../physical/EmptyTupleSourcePOperator.java | 4 +-
.../algebra/util/OperatorManipulationUtil.java | 3 +-
.../algebra/util/OperatorPropertiesUtil.java | 7 +-
.../piglet/metadata/PigletFileDataSource.java | 7 +
.../rules/EnforceStructuralPropertiesRule.java | 13 +-
...moveCartesianProductWithEmptyBranchRule.java | 6 +-
.../rules/SimpleUnnestToProductRule.java | 74 +++--
.../rules/SwitchInnerJoinBranchRule.java | 61 ++++
...inateSubplanWithInputCardinalityOneRule.java | 2 +-
...placeNtsWithSubplanInputOperatorVisitor.java | 3 +-
74 files changed, 2823 insertions(+), 294 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/asterixdb/blob/c89d668f/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/optimizer/base/RuleCollections.java
----------------------------------------------------------------------
diff --git a/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/optimizer/base/RuleCollections.java b/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/optimizer/base/RuleCollections.java
index cf36c05..582cac9 100644
--- a/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/optimizer/base/RuleCollections.java
+++ b/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/optimizer/base/RuleCollections.java
@@ -122,6 +122,7 @@ import org.apache.hyracks.algebricks.rewriter.rules.RemoveUnusedAssignAndAggrega
import org.apache.hyracks.algebricks.rewriter.rules.SetAlgebricksPhysicalOperatorsRule;
import org.apache.hyracks.algebricks.rewriter.rules.SetExecutionModeRule;
import org.apache.hyracks.algebricks.rewriter.rules.SimpleUnnestToProductRule;
+import org.apache.hyracks.algebricks.rewriter.rules.SwitchInnerJoinBranchRule;
import org.apache.hyracks.algebricks.rewriter.rules.subplan.EliminateSubplanRule;
import org.apache.hyracks.algebricks.rewriter.rules.subplan.EliminateSubplanWithInputCardinalityOneRule;
import org.apache.hyracks.algebricks.rewriter.rules.subplan.NestedSubplanToJoinRule;
@@ -282,6 +283,7 @@ public final class RuleCollections {
public static final List<IAlgebraicRewriteRule> buildPlanCleanupRuleCollection() {
List<IAlgebraicRewriteRule> planCleanupRules = new LinkedList<>();
+ planCleanupRules.add(new SwitchInnerJoinBranchRule());
planCleanupRules.add(new PushAssignBelowUnionAllRule());
planCleanupRules.add(new ExtractCommonExpressionsRule());
planCleanupRules.add(new RemoveRedundantVariablesRule());
http://git-wip-us.apache.org/repos/asf/asterixdb/blob/c89d668f/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/am/InvertedIndexAccessMethod.java
----------------------------------------------------------------------
diff --git a/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/am/InvertedIndexAccessMethod.java b/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/am/InvertedIndexAccessMethod.java
index 1052a72..0bc5e78 100644
--- a/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/am/InvertedIndexAccessMethod.java
+++ b/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/am/InvertedIndexAccessMethod.java
@@ -21,6 +21,7 @@ package org.apache.asterix.optimizer.rules.am;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
+import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
@@ -64,7 +65,6 @@ import org.apache.hyracks.algebricks.core.algebra.functions.AlgebricksBuiltinFun
import org.apache.hyracks.algebricks.core.algebra.functions.FunctionIdentifier;
import org.apache.hyracks.algebricks.core.algebra.operators.logical.AbstractBinaryJoinOperator;
import org.apache.hyracks.algebricks.core.algebra.operators.logical.AbstractLogicalOperator;
-import org.apache.hyracks.algebricks.core.algebra.operators.logical.AbstractLogicalOperator.ExecutionMode;
import org.apache.hyracks.algebricks.core.algebra.operators.logical.AbstractUnnestMapOperator;
import org.apache.hyracks.algebricks.core.algebra.operators.logical.AssignOperator;
import org.apache.hyracks.algebricks.core.algebra.operators.logical.DataSourceScanOperator;
@@ -73,6 +73,7 @@ import org.apache.hyracks.algebricks.core.algebra.operators.logical.ReplicateOpe
import org.apache.hyracks.algebricks.core.algebra.operators.logical.SelectOperator;
import org.apache.hyracks.algebricks.core.algebra.operators.logical.UnionAllOperator;
import org.apache.hyracks.algebricks.core.algebra.operators.logical.UnnestOperator;
+import org.apache.hyracks.algebricks.core.algebra.operators.logical.AbstractLogicalOperator.ExecutionMode;
import org.apache.hyracks.algebricks.core.algebra.operators.logical.visitors.LogicalOperatorDeepCopyWithNewVariablesVisitor;
import org.apache.hyracks.algebricks.core.algebra.operators.logical.visitors.VariableUtilities;
import org.apache.hyracks.algebricks.core.algebra.util.OperatorManipulationUtil;
@@ -589,9 +590,9 @@ public class InvertedIndexAccessMethod implements IAccessMethod {
// will have all primary-key and secondary-search keys replaced, but retains all other original variables.
// Variable replacement map for the first copy.
- Map<LogicalVariable, LogicalVariable> newProbeSubTreeVarMap = new HashMap<LogicalVariable, LogicalVariable>();
+ LinkedHashMap<LogicalVariable, LogicalVariable> newProbeSubTreeVarMap = new LinkedHashMap<>();
// Variable replacement map for the second copy.
- Map<LogicalVariable, LogicalVariable> joinInputSubTreeVarMap = new HashMap<LogicalVariable, LogicalVariable>();
+ LinkedHashMap<LogicalVariable, LogicalVariable> joinInputSubTreeVarMap = new LinkedHashMap<>();
// Init with all live vars.
List<LogicalVariable> liveVars = new ArrayList<LogicalVariable>();
VariableUtilities.getLiveVariables(probeSubTree.getRoot(), liveVars);
http://git-wip-us.apache.org/repos/asf/asterixdb/blob/c89d668f/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/subplan/InlineAllNtsInSubplanVisitor.java
----------------------------------------------------------------------
diff --git a/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/subplan/InlineAllNtsInSubplanVisitor.java b/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/subplan/InlineAllNtsInSubplanVisitor.java
index b061066..8e5fa79 100644
--- a/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/subplan/InlineAllNtsInSubplanVisitor.java
+++ b/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/subplan/InlineAllNtsInSubplanVisitor.java
@@ -23,10 +23,11 @@ import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
+import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
-import java.util.Map.Entry;
import java.util.Set;
+import java.util.Map.Entry;
import org.apache.asterix.lang.common.util.FunctionUtil;
import org.apache.asterix.om.base.AString;
@@ -66,7 +67,6 @@ import org.apache.hyracks.algebricks.core.algebra.operators.logical.LimitOperato
import org.apache.hyracks.algebricks.core.algebra.operators.logical.MaterializeOperator;
import org.apache.hyracks.algebricks.core.algebra.operators.logical.NestedTupleSourceOperator;
import org.apache.hyracks.algebricks.core.algebra.operators.logical.OrderOperator;
-import org.apache.hyracks.algebricks.core.algebra.operators.logical.OrderOperator.IOrder;
import org.apache.hyracks.algebricks.core.algebra.operators.logical.PartitioningSplitOperator;
import org.apache.hyracks.algebricks.core.algebra.operators.logical.ProjectOperator;
import org.apache.hyracks.algebricks.core.algebra.operators.logical.ReplicateOperator;
@@ -78,6 +78,7 @@ import org.apache.hyracks.algebricks.core.algebra.operators.logical.TokenizeOper
import org.apache.hyracks.algebricks.core.algebra.operators.logical.UnionAllOperator;
import org.apache.hyracks.algebricks.core.algebra.operators.logical.UnnestMapOperator;
import org.apache.hyracks.algebricks.core.algebra.operators.logical.UnnestOperator;
+import org.apache.hyracks.algebricks.core.algebra.operators.logical.OrderOperator.IOrder;
import org.apache.hyracks.algebricks.core.algebra.operators.logical.visitors.LogicalOperatorDeepCopyWithNewVariablesVisitor;
import org.apache.hyracks.algebricks.core.algebra.operators.logical.visitors.VariableUtilities;
import org.apache.hyracks.algebricks.core.algebra.plan.ALogicalPlanImpl;
@@ -135,7 +136,8 @@ class InlineAllNtsInSubplanVisitor implements IQueryOperatorVisitor<ILogicalOper
// Maps live variables at <code>subplanInputOperator</code> to variables in
// the flattened nested plan.
- private final Map<LogicalVariable, LogicalVariable> subplanInputVarToCurrentVarMap = new HashMap<>();
+ private final LinkedHashMap<LogicalVariable, LogicalVariable> subplanInputVarToCurrentVarMap = new
+ LinkedHashMap<>();
// Maps variables in the flattened nested plan to live variables at
// <code>subplannputOperator</code>.
@@ -154,7 +156,7 @@ class InlineAllNtsInSubplanVisitor implements IQueryOperatorVisitor<ILogicalOper
/**
* @param context
* the optimization context
- * @param subplanInputOperator
+ * @param subplanOperator
* the input operator to the target subplan operator, which is to
* be inlined.
* @throws AlgebricksException
@@ -625,8 +627,6 @@ class InlineAllNtsInSubplanVisitor implements IQueryOperatorVisitor<ILogicalOper
*
* @param op
* the logical operator for aggregate or running aggregate.
- * @param keyVarsToEnforce
- * the set of variables that needs to preserve.
* @return the wrapped group-by operator if {@code keyVarsToEnforce} is not
* empty, and {@code op} otherwise.
* @throws AlgebricksException
@@ -637,7 +637,9 @@ class InlineAllNtsInSubplanVisitor implements IQueryOperatorVisitor<ILogicalOper
return op;
}
GroupByOperator gbyOp = new GroupByOperator();
- for (LogicalVariable keyVar : correlatedKeyVars) {
+ // Creates a copy of correlatedKeyVars, to fix the ConcurrentModificationExcetpion in ASTERIXDB-1581.
+ List<LogicalVariable> copyOfCorrelatedKeyVars = new ArrayList<>(correlatedKeyVars);
+ for (LogicalVariable keyVar : copyOfCorrelatedKeyVars) {
// This limits the visitor can only be applied to a nested logical
// plan inside a Subplan operator,
// where the keyVarsToEnforce forms a candidate key which can
http://git-wip-us.apache.org/repos/asf/asterixdb/blob/c89d668f/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/subplan/InlineSubplanInputForNestedTupleSourceRule.java
----------------------------------------------------------------------
diff --git a/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/subplan/InlineSubplanInputForNestedTupleSourceRule.java b/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/subplan/InlineSubplanInputForNestedTupleSourceRule.java
index 1881461..2e368c0 100644
--- a/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/subplan/InlineSubplanInputForNestedTupleSourceRule.java
+++ b/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/subplan/InlineSubplanInputForNestedTupleSourceRule.java
@@ -19,8 +19,8 @@
package org.apache.asterix.optimizer.rules.subplan;
import java.util.ArrayList;
-import java.util.HashMap;
import java.util.HashSet;
+import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
@@ -48,9 +48,9 @@ import org.apache.hyracks.algebricks.core.algebra.operators.logical.GroupByOpera
import org.apache.hyracks.algebricks.core.algebra.operators.logical.LeftOuterJoinOperator;
import org.apache.hyracks.algebricks.core.algebra.operators.logical.NestedTupleSourceOperator;
import org.apache.hyracks.algebricks.core.algebra.operators.logical.OrderOperator;
-import org.apache.hyracks.algebricks.core.algebra.operators.logical.OrderOperator.IOrder;
import org.apache.hyracks.algebricks.core.algebra.operators.logical.SelectOperator;
import org.apache.hyracks.algebricks.core.algebra.operators.logical.SubplanOperator;
+import org.apache.hyracks.algebricks.core.algebra.operators.logical.OrderOperator.IOrder;
import org.apache.hyracks.algebricks.core.algebra.operators.logical.visitors.VariableUtilities;
import org.apache.hyracks.algebricks.core.algebra.plan.ALogicalPlanImpl;
import org.apache.hyracks.algebricks.core.algebra.util.OperatorManipulationUtil;
@@ -267,22 +267,26 @@ public class InlineSubplanInputForNestedTupleSourceRule implements IAlgebraicRew
if (context.checkIfInDontApplySet(this, opRef.getValue())) {
return false;
}
- Pair<Boolean, Map<LogicalVariable, LogicalVariable>> result = rewriteSubplanOperator(opRef, context);
+ Pair<Boolean, LinkedHashMap<LogicalVariable, LogicalVariable>> result = rewriteSubplanOperator(opRef, context);
hasRun = true;
return result.first;
}
- private Pair<Boolean, Map<LogicalVariable, LogicalVariable>> rewriteSubplanOperator(Mutable<ILogicalOperator> opRef,
+ private Pair<Boolean, LinkedHashMap<LogicalVariable, LogicalVariable>> rewriteSubplanOperator(
+ Mutable<ILogicalOperator> opRef,
IOptimizationContext context) throws AlgebricksException {
AbstractLogicalOperator op = (AbstractLogicalOperator) opRef.getValue();
+ // Recursively traverses input operators as if the current operator before rewriting the current operator.
+ Pair<Boolean, LinkedHashMap<LogicalVariable, LogicalVariable>> changedAndVarMap = traverseNonSubplanOperator(op,
+ context);
if (op.getOperatorTag() != LogicalOperatorTag.SUBPLAN) {
- // Traverses non-subplan operators.
- return traverseNonSubplanOperator(op, context);
+ return changedAndVarMap;
}
+
/**
* Apply the special join-based rewriting.
*/
- Pair<Boolean, Map<LogicalVariable, LogicalVariable>> result = applySpecialFlattening(opRef, context);
+ Pair<Boolean, LinkedHashMap<LogicalVariable, LogicalVariable>> result = applySpecialFlattening(opRef, context);
if (!result.first) {
/**
* If the special join-based rewriting does not apply, apply the general
@@ -290,7 +294,12 @@ public class InlineSubplanInputForNestedTupleSourceRule implements IAlgebraicRew
*/
result = applyGeneralFlattening(opRef, context);
}
- return result;
+ LinkedHashMap<LogicalVariable, LogicalVariable> returnedMap = new LinkedHashMap<>();
+ // Adds variable mappings from input operators.
+ returnedMap.putAll(changedAndVarMap.second);
+ // Adds variable mappings resulting from the rewriting of the current operator.
+ returnedMap.putAll(result.second);
+ return new Pair<>(result.first || changedAndVarMap.first, returnedMap);
}
/***
@@ -302,15 +311,17 @@ public class InlineSubplanInputForNestedTupleSourceRule implements IAlgebraicRew
* @return
* @throws AlgebricksException
*/
- private Pair<Boolean, Map<LogicalVariable, LogicalVariable>> traverseNonSubplanOperator(ILogicalOperator op,
+ private Pair<Boolean, LinkedHashMap<LogicalVariable, LogicalVariable>> traverseNonSubplanOperator(
+ ILogicalOperator op,
IOptimizationContext context) throws AlgebricksException {
Set<LogicalVariable> liveVars = new HashSet<>();
VariableUtilities.getLiveVariables(op, liveVars);
- Map<LogicalVariable, LogicalVariable> replacedVarMap = new HashMap<LogicalVariable, LogicalVariable>();
- Map<LogicalVariable, LogicalVariable> replacedVarMapForAncestor = new HashMap<LogicalVariable, LogicalVariable>();
+ LinkedHashMap<LogicalVariable, LogicalVariable> replacedVarMap = new LinkedHashMap<>();
+ LinkedHashMap<LogicalVariable, LogicalVariable> replacedVarMapForAncestor = new LinkedHashMap<>();
boolean changed = false;
for (Mutable<ILogicalOperator> childrenRef : op.getInputs()) {
- Pair<Boolean, Map<LogicalVariable, LogicalVariable>> resultFromChild = rewriteSubplanOperator(childrenRef,
+ Pair<Boolean, LinkedHashMap<LogicalVariable, LogicalVariable>> resultFromChild = rewriteSubplanOperator(
+ childrenRef,
context);
changed = changed || resultFromChild.first;
for (Map.Entry<LogicalVariable, LogicalVariable> entry : resultFromChild.second.entrySet()) {
@@ -323,18 +334,18 @@ public class InlineSubplanInputForNestedTupleSourceRule implements IAlgebraicRew
}
VariableUtilities.substituteVariables(op, replacedVarMap, context);
context.computeAndSetTypeEnvironmentForOperator(op);
- return new Pair<Boolean, Map<LogicalVariable, LogicalVariable>>(changed, replacedVarMapForAncestor);
+ return new Pair<>(changed, replacedVarMapForAncestor);
}
- private Pair<Boolean, Map<LogicalVariable, LogicalVariable>> applyGeneralFlattening(Mutable<ILogicalOperator> opRef,
+ private Pair<Boolean, LinkedHashMap<LogicalVariable, LogicalVariable>> applyGeneralFlattening(
+ Mutable<ILogicalOperator> opRef,
IOptimizationContext context) throws AlgebricksException {
SubplanOperator subplanOp = (SubplanOperator) opRef.getValue();
if (!SubplanFlatteningUtil.containsOperators(subplanOp,
ImmutableSet.of(LogicalOperatorTag.DATASOURCESCAN, LogicalOperatorTag.INNERJOIN,
// We don't have nested runtime for union-all and distinct hence we have to include them here.
LogicalOperatorTag.LEFTOUTERJOIN, LogicalOperatorTag.UNIONALL, LogicalOperatorTag.DISTINCT))) {
- // Traverses the operator as if it is not a subplan.
- return traverseNonSubplanOperator(subplanOp, context);
+ return new Pair<>(false, new LinkedHashMap<>());
}
Mutable<ILogicalOperator> inputOpRef = subplanOp.getInputs().get(0);
ILogicalOperator inputOpBackup = inputOpRef.getValue();
@@ -344,7 +355,7 @@ public class InlineSubplanInputForNestedTupleSourceRule implements IAlgebraicRew
ILogicalOperator inputOp = primaryOpAndVars.first;
Set<LogicalVariable> primaryKeyVars = primaryOpAndVars.second;
inputOpRef.setValue(inputOp);
- Set<LogicalVariable> inputLiveVars = new HashSet<LogicalVariable>();
+ Set<LogicalVariable> inputLiveVars = new HashSet<>();
VariableUtilities.getLiveVariables(inputOp, inputLiveVars);
Pair<Map<LogicalVariable, LogicalVariable>, List<Pair<IOrder, Mutable<ILogicalExpression>>>> varMapAndOrderExprs = SubplanFlatteningUtil
@@ -352,32 +363,31 @@ public class InlineSubplanInputForNestedTupleSourceRule implements IAlgebraicRew
Map<LogicalVariable, LogicalVariable> varMap = varMapAndOrderExprs.first;
if (varMap == null) {
inputOpRef.setValue(inputOpBackup);
- // Traverses the operator as if it is not a subplan.
- return traverseNonSubplanOperator(subplanOp, context);
+ return new Pair<>(false, new LinkedHashMap<>());
}
- Mutable<ILogicalOperator> rightInputOpRef = subplanOp.getNestedPlans().get(0).getRoots().get(0).getValue()
- .getInputs().get(0);
+ Mutable<ILogicalOperator> lowestAggregateRefInSubplan = SubplanFlatteningUtil
+ .findLowestAggregate(subplanOp.getNestedPlans().get(0).getRoots().get(0));
+ Mutable<ILogicalOperator> rightInputOpRef = lowestAggregateRefInSubplan.getValue().getInputs().get(0);
ILogicalOperator rightInputOp = rightInputOpRef.getValue();
// Creates a variable to indicate whether a left input tuple is killed in the plan rooted at rightInputOp.
LogicalVariable assignVar = context.newVar();
- ILogicalOperator assignOp = new AssignOperator(assignVar,
- new MutableObject<ILogicalExpression>(ConstantExpression.TRUE));
+ ILogicalOperator assignOp = new AssignOperator(assignVar, new MutableObject<>(ConstantExpression.TRUE));
assignOp.getInputs().add(rightInputOpRef);
context.computeAndSetTypeEnvironmentForOperator(assignOp);
- rightInputOpRef = new MutableObject<ILogicalOperator>(assignOp);
+ rightInputOpRef = new MutableObject<>(assignOp);
// Constructs the join predicate for the leftOuter join.
- List<Mutable<ILogicalExpression>> joinPredicates = new ArrayList<Mutable<ILogicalExpression>>();
+ List<Mutable<ILogicalExpression>> joinPredicates = new ArrayList<>();
for (LogicalVariable liveVar : primaryKeyVars) {
- List<Mutable<ILogicalExpression>> arguments = new ArrayList<Mutable<ILogicalExpression>>();
- arguments.add(new MutableObject<ILogicalExpression>(new VariableReferenceExpression(liveVar)));
+ List<Mutable<ILogicalExpression>> arguments = new ArrayList<>();
+ arguments.add(new MutableObject<>(new VariableReferenceExpression(liveVar)));
LogicalVariable rightVar = varMap.get(liveVar);
- arguments.add(new MutableObject<ILogicalExpression>(new VariableReferenceExpression(rightVar)));
+ arguments.add(new MutableObject<>(new VariableReferenceExpression(rightVar)));
ILogicalExpression expr = new ScalarFunctionCallExpression(
FunctionUtil.getFunctionInfo(AlgebricksBuiltinFunctions.EQ), arguments);
- joinPredicates.add(new MutableObject<ILogicalExpression>(expr));
+ joinPredicates.add(new MutableObject<>(expr));
}
ILogicalExpression joinExpr = joinPredicates.size() > 1
@@ -385,21 +395,20 @@ public class InlineSubplanInputForNestedTupleSourceRule implements IAlgebraicRew
joinPredicates)
: joinPredicates.size() > 0 ? joinPredicates.get(0).getValue() : ConstantExpression.TRUE;
LeftOuterJoinOperator leftOuterJoinOp = new LeftOuterJoinOperator(
- new MutableObject<ILogicalExpression>(joinExpr), inputOpRef, rightInputOpRef);
+ new MutableObject<>(joinExpr), inputOpRef, rightInputOpRef);
OperatorManipulationUtil.computeTypeEnvironmentBottomUp(rightInputOp, context);
context.computeAndSetTypeEnvironmentForOperator(leftOuterJoinOp);
// Creates group-by operator.
List<Pair<LogicalVariable, Mutable<ILogicalExpression>>> groupByList = new ArrayList<Pair<LogicalVariable, Mutable<ILogicalExpression>>>();
List<Pair<LogicalVariable, Mutable<ILogicalExpression>>> groupByDecorList = new ArrayList<Pair<LogicalVariable, Mutable<ILogicalExpression>>>();
- List<ILogicalPlan> nestedPlans = new ArrayList<ILogicalPlan>();
+ List<ILogicalPlan> nestedPlans = new ArrayList<>();
GroupByOperator groupbyOp = new GroupByOperator(groupByList, groupByDecorList, nestedPlans);
- Map<LogicalVariable, LogicalVariable> replacedVarMap = new HashMap<>();
+ LinkedHashMap<LogicalVariable, LogicalVariable> replacedVarMap = new LinkedHashMap<>();
for (LogicalVariable liveVar : primaryKeyVars) {
LogicalVariable newVar = context.newVar();
- groupByList.add(new Pair<LogicalVariable, Mutable<ILogicalExpression>>(newVar,
- new MutableObject<ILogicalExpression>(new VariableReferenceExpression(liveVar))));
+ groupByList.add(new Pair<>(newVar, new MutableObject<>(new VariableReferenceExpression(liveVar))));
// Adds variables for replacements in ancestors.
replacedVarMap.put(liveVar, newVar);
}
@@ -407,44 +416,41 @@ public class InlineSubplanInputForNestedTupleSourceRule implements IAlgebraicRew
if (primaryKeyVars.contains(liveVar)) {
continue;
}
- groupByDecorList.add(new Pair<LogicalVariable, Mutable<ILogicalExpression>>(null,
- new MutableObject<ILogicalExpression>(new VariableReferenceExpression(liveVar))));
+ groupByDecorList.add(new Pair<>(null, new MutableObject<>(new VariableReferenceExpression(liveVar))));
}
// Sets up the nested plan for the groupby operator.
Mutable<ILogicalOperator> aggOpRef = subplanOp.getNestedPlans().get(0).getRoots().get(0);
- aggOpRef.getValue().getInputs().clear();
-
- Mutable<ILogicalOperator> currentOpRef = aggOpRef;
+ lowestAggregateRefInSubplan.getValue().getInputs().clear(); // Clears the input of the lowest aggregate.
+ Mutable<ILogicalOperator> currentOpRef = lowestAggregateRefInSubplan;
// Adds an optional order operator.
List<Pair<IOrder, Mutable<ILogicalExpression>>> orderExprs = varMapAndOrderExprs.second;
if (!orderExprs.isEmpty()) {
OrderOperator orderOp = new OrderOperator(orderExprs);
- currentOpRef = new MutableObject<ILogicalOperator>(orderOp);
- aggOpRef.getValue().getInputs().add(currentOpRef);
+ currentOpRef = new MutableObject<>(orderOp);
+ lowestAggregateRefInSubplan.getValue().getInputs().add(currentOpRef);
}
// Adds a select operator into the nested plan for group-by to remove tuples with NULL on {@code assignVar}, i.e.,
// subplan input tuples that are filtered out within a subplan.
- Mutable<ILogicalExpression> filterVarExpr = new MutableObject<ILogicalExpression>(
+ Mutable<ILogicalExpression> filterVarExpr = new MutableObject<>(
new VariableReferenceExpression(assignVar));
- List<Mutable<ILogicalExpression>> args = new ArrayList<Mutable<ILogicalExpression>>();
+ List<Mutable<ILogicalExpression>> args = new ArrayList<>();
args.add(filterVarExpr);
- List<Mutable<ILogicalExpression>> argsForNotFunction = new ArrayList<Mutable<ILogicalExpression>>();
- argsForNotFunction.add(new MutableObject<ILogicalExpression>(new ScalarFunctionCallExpression(
+ List<Mutable<ILogicalExpression>> argsForNotFunction = new ArrayList<>();
+ argsForNotFunction.add(new MutableObject<>(new ScalarFunctionCallExpression(
FunctionUtil.getFunctionInfo(AsterixBuiltinFunctions.IS_MISSING), args)));
SelectOperator selectOp = new SelectOperator(
- new MutableObject<ILogicalExpression>(new ScalarFunctionCallExpression(
+ new MutableObject<>(new ScalarFunctionCallExpression(
FunctionUtil.getFunctionInfo(AsterixBuiltinFunctions.NOT), argsForNotFunction)),
false, null);
- currentOpRef.getValue().getInputs().add(new MutableObject<ILogicalOperator>(selectOp));
+ currentOpRef.getValue().getInputs().add(new MutableObject<>(selectOp));
- selectOp.getInputs().add(new MutableObject<ILogicalOperator>(
- new NestedTupleSourceOperator(new MutableObject<ILogicalOperator>(groupbyOp))));
- List<Mutable<ILogicalOperator>> nestedRoots = new ArrayList<Mutable<ILogicalOperator>>();
+ selectOp.getInputs().add(new MutableObject<>(new NestedTupleSourceOperator(new MutableObject<>(groupbyOp))));
+ List<Mutable<ILogicalOperator>> nestedRoots = new ArrayList<>();
nestedRoots.add(aggOpRef);
nestedPlans.add(new ALogicalPlanImpl(nestedRoots));
- groupbyOp.getInputs().add(new MutableObject<ILogicalOperator>(leftOuterJoinOp));
+ groupbyOp.getInputs().add(new MutableObject<>(leftOuterJoinOp));
// Replaces subplan with the group-by operator.
opRef.setValue(groupbyOp);
@@ -452,23 +458,25 @@ public class InlineSubplanInputForNestedTupleSourceRule implements IAlgebraicRew
// Recursively applys this rule to the nested plan of the subplan operator,
// for the case where there are nested subplan operators within {@code subplanOp}.
- Pair<Boolean, Map<LogicalVariable, LogicalVariable>> result = rewriteSubplanOperator(rightInputOpRef, context);
+ Pair<Boolean, LinkedHashMap<LogicalVariable, LogicalVariable>> result = rewriteSubplanOperator(rightInputOpRef,
+ context);
VariableUtilities.substituteVariables(leftOuterJoinOp, result.second, context);
VariableUtilities.substituteVariables(groupbyOp, result.second, context);
// No var mapping from the right input operator should be populated up.
- return new Pair<Boolean, Map<LogicalVariable, LogicalVariable>>(true, replacedVarMap);
+ return new Pair<>(true, replacedVarMap);
}
- private Pair<Boolean, Map<LogicalVariable, LogicalVariable>> applySpecialFlattening(Mutable<ILogicalOperator> opRef,
+ private Pair<Boolean, LinkedHashMap<LogicalVariable, LogicalVariable>> applySpecialFlattening(
+ Mutable<ILogicalOperator> opRef,
IOptimizationContext context) throws AlgebricksException {
SubplanOperator subplanOp = (SubplanOperator) opRef.getValue();
Mutable<ILogicalOperator> inputOpRef = subplanOp.getInputs().get(0);
- Map<LogicalVariable, LogicalVariable> replacedVarMap = new HashMap<>();
+ LinkedHashMap<LogicalVariable, LogicalVariable> replacedVarMap = new LinkedHashMap<>();
// Recursively applies this rule to the nested plan of the subplan operator,
// for the case where there are nested subplan operators within {@code subplanOp}.
- Pair<Boolean, Map<LogicalVariable, LogicalVariable>> result = rewriteSubplanOperator(
+ Pair<Boolean, LinkedHashMap<LogicalVariable, LogicalVariable>> result = rewriteSubplanOperator(
subplanOp.getNestedPlans().get(0).getRoots().get(0), context);
ILogicalOperator inputOpBackup = inputOpRef.getValue();
@@ -485,7 +493,7 @@ public class InlineSubplanInputForNestedTupleSourceRule implements IAlgebraicRew
.inlineLeftNtsInSubplanJoin(subplanOp, context);
if (notNullVarsAndTopJoinRef.first == null) {
inputOpRef.setValue(inputOpBackup);
- return new Pair<Boolean, Map<LogicalVariable, LogicalVariable>>(false, replacedVarMap);
+ return new Pair<>(false, replacedVarMap);
}
Set<LogicalVariable> notNullVars = notNullVarsAndTopJoinRef.first;
@@ -496,12 +504,9 @@ public class InlineSubplanInputForNestedTupleSourceRule implements IAlgebraicRew
List<Pair<LogicalVariable, Mutable<ILogicalExpression>>> groupByDecorList = new ArrayList<Pair<LogicalVariable, Mutable<ILogicalExpression>>>();
GroupByOperator groupbyOp = new GroupByOperator(groupByList, groupByDecorList, subplanOp.getNestedPlans());
- Map<LogicalVariable, LogicalVariable> gbyVarMap = new HashMap<LogicalVariable, LogicalVariable>();
for (LogicalVariable coverVar : primaryKeyVars) {
LogicalVariable newVar = context.newVar();
- gbyVarMap.put(coverVar, newVar);
- groupByList.add(new Pair<LogicalVariable, Mutable<ILogicalExpression>>(newVar,
- new MutableObject<ILogicalExpression>(new VariableReferenceExpression(coverVar))));
+ groupByList.add(new Pair<>(newVar, new MutableObject<>(new VariableReferenceExpression(coverVar))));
// Adds variables for replacements in ancestors.
replacedVarMap.put(coverVar, newVar);
}
@@ -509,44 +514,43 @@ public class InlineSubplanInputForNestedTupleSourceRule implements IAlgebraicRew
if (primaryKeyVars.contains(liveVar)) {
continue;
}
- groupByDecorList.add(new Pair<LogicalVariable, Mutable<ILogicalExpression>>(null,
- new MutableObject<ILogicalExpression>(new VariableReferenceExpression(liveVar))));
+ groupByDecorList.add(new Pair<>(null, new MutableObject<>(new VariableReferenceExpression(liveVar))));
}
- groupbyOp.getInputs().add(new MutableObject<ILogicalOperator>(topJoinRef.getValue()));
+ groupbyOp.getInputs().add(new MutableObject<>(topJoinRef.getValue()));
- if (notNullVars.size() > 0) {
+ if (!notNullVars.isEmpty()) {
// Adds a select operator into the nested plan for group-by to remove tuples with NULL on {@code assignVar}, i.e.,
// subplan input tuples that are filtered out within a subplan.
List<Mutable<ILogicalExpression>> nullCheckExprRefs = new ArrayList<>();
for (LogicalVariable notNullVar : notNullVars) {
- Mutable<ILogicalExpression> filterVarExpr = new MutableObject<ILogicalExpression>(
+ Mutable<ILogicalExpression> filterVarExpr = new MutableObject<>(
new VariableReferenceExpression(notNullVar));
- List<Mutable<ILogicalExpression>> args = new ArrayList<Mutable<ILogicalExpression>>();
+ List<Mutable<ILogicalExpression>> args = new ArrayList<>();
args.add(filterVarExpr);
- List<Mutable<ILogicalExpression>> argsForNotFunction = new ArrayList<Mutable<ILogicalExpression>>();
- argsForNotFunction.add(new MutableObject<ILogicalExpression>(new ScalarFunctionCallExpression(
+ List<Mutable<ILogicalExpression>> argsForNotFunction = new ArrayList<>();
+ argsForNotFunction.add(new MutableObject<>(new ScalarFunctionCallExpression(
FunctionUtil.getFunctionInfo(AsterixBuiltinFunctions.IS_MISSING), args)));
- nullCheckExprRefs.add(new MutableObject<ILogicalExpression>(new ScalarFunctionCallExpression(
+ nullCheckExprRefs.add(new MutableObject<>(new ScalarFunctionCallExpression(
FunctionUtil.getFunctionInfo(AsterixBuiltinFunctions.NOT), argsForNotFunction)));
}
Mutable<ILogicalExpression> selectExprRef = nullCheckExprRefs.size() > 1
- ? new MutableObject<ILogicalExpression>(new ScalarFunctionCallExpression(
+ ? new MutableObject<>(new ScalarFunctionCallExpression(
FunctionUtil.getFunctionInfo(AsterixBuiltinFunctions.AND), nullCheckExprRefs))
: nullCheckExprRefs.get(0);
SelectOperator selectOp = new SelectOperator(selectExprRef, false, null);
topJoinRef.setValue(selectOp);
- selectOp.getInputs().add(new MutableObject<ILogicalOperator>(
- new NestedTupleSourceOperator(new MutableObject<ILogicalOperator>(groupbyOp))));
+ selectOp.getInputs()
+ .add(new MutableObject<>(new NestedTupleSourceOperator(new MutableObject<>(groupbyOp))));
} else {
// The original join operator in the Subplan is a left-outer join.
// Therefore, no null-check variable is injected and no SelectOperator needs to be added.
- topJoinRef.setValue(new NestedTupleSourceOperator(new MutableObject<ILogicalOperator>(groupbyOp)));
+ topJoinRef.setValue(new NestedTupleSourceOperator(new MutableObject<>(groupbyOp)));
}
opRef.setValue(groupbyOp);
OperatorManipulationUtil.computeTypeEnvironmentBottomUp(groupbyOp, context);
VariableUtilities.substituteVariables(groupbyOp, result.second, context);
replacedVarMap.putAll(result.second);
- return new Pair<Boolean, Map<LogicalVariable, LogicalVariable>>(true, replacedVarMap);
+ return new Pair<>(true, replacedVarMap);
}
}
http://git-wip-us.apache.org/repos/asf/asterixdb/blob/c89d668f/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/subplan/SubplanFlatteningUtil.java
----------------------------------------------------------------------
diff --git a/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/subplan/SubplanFlatteningUtil.java b/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/subplan/SubplanFlatteningUtil.java
index 6d91923..377e96d 100644
--- a/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/subplan/SubplanFlatteningUtil.java
+++ b/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/subplan/SubplanFlatteningUtil.java
@@ -31,8 +31,8 @@ import org.apache.hyracks.algebricks.core.algebra.base.ILogicalPlan;
import org.apache.hyracks.algebricks.core.algebra.base.IOptimizationContext;
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.operators.logical.OrderOperator.IOrder;
import org.apache.hyracks.algebricks.core.algebra.operators.logical.SubplanOperator;
+import org.apache.hyracks.algebricks.core.algebra.operators.logical.OrderOperator.IOrder;
import org.apache.hyracks.algebricks.core.algebra.operators.logical.visitors.VariableUtilities;
import org.apache.hyracks.algebricks.core.algebra.util.OperatorManipulationUtil;
@@ -62,7 +62,7 @@ class SubplanFlatteningUtil {
InlineAllNtsInSubplanVisitor visitor = new InlineAllNtsInSubplanVisitor(context, subplanOp);
// Rewrites the query plan.
- ILogicalOperator topOp = subplanOp.getNestedPlans().get(0).getRoots().get(0).getValue();
+ ILogicalOperator topOp = findLowestAggregate(subplanOp.getNestedPlans().get(0).getRoots().get(0)).getValue();
ILogicalOperator opToVisit = topOp.getInputs().get(0).getValue();
ILogicalOperator result = opToVisit.accept(visitor, null);
topOp.getInputs().get(0).setValue(result);
@@ -143,6 +143,54 @@ class SubplanFlatteningUtil {
}
/**
+ * Whether the query plan rooted {@code currentOp} contains a data source scan operator,
+ * with considering nested subplans.
+ *
+ * @param currentOp
+ * the current operator
+ * @return true if {@code currentOp} contains a data source scan operator; false otherwise.
+ */
+ public static boolean containsOperatorsInternal(ILogicalOperator currentOp,
+ Set<LogicalOperatorTag> interestedOperatorTags) {
+ if (interestedOperatorTags.contains(currentOp.getOperatorTag())) {
+ return true;
+ }
+ if (currentOp.getOperatorTag() == LogicalOperatorTag.SUBPLAN
+ && containsOperators((SubplanOperator) currentOp, interestedOperatorTags)) {
+ return true;
+ }
+ for (Mutable<ILogicalOperator> childRef : currentOp.getInputs()) {
+ if (containsOperatorsInternal(childRef.getValue(), interestedOperatorTags)) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ /**
+ * Finds the lowest aggregate operator that should be put into a nested aggregation pipeline within a group-by
+ * operator.
+ * <p/>
+ * Note that neither binary input operators nor data scan can be put into a group by operator.
+ *
+ * @param currentOpRef,
+ * the current root operator reference to look at.
+ * @return the operator reference of the lowest qualified aggregate operator.
+ */
+ public static Mutable<ILogicalOperator> findLowestAggregate(Mutable<ILogicalOperator> currentOpRef) {
+ ILogicalOperator currentOp = currentOpRef.getValue();
+ // Neither binary input operators nor data scan can be put into a group by operator.
+ if (currentOp.getInputs().size() != 1 || currentOp.getOperatorTag() == LogicalOperatorTag.DATASOURCESCAN) {
+ return null;
+ }
+ Mutable<ILogicalOperator> childReturn = findLowestAggregate(currentOp.getInputs().get(0));
+ if (childReturn == null) {
+ return currentOp.getOperatorTag() == LogicalOperatorTag.AGGREGATE ? currentOpRef : null;
+ }
+ return childReturn;
+ }
+
+ /**
* Determine whether a subplan could be rewritten as a join-related special case.
* The conditions include:
* a. there is a join (let's call it J1.) in the nested plan,
@@ -174,30 +222,4 @@ class SubplanFlatteningUtil {
return new Pair<Boolean, ILogicalOperator>(true, visitor.getQualifiedNts());
}
- /**
- * Whether the query plan rooted {@code currentOp} contains a data source scan operator,
- * with considering nested subplans.
- *
- * @param currentOp
- * the current operator
- * @return true if {@code currentOp} contains a data source scan operator; false otherwise.
- */
- private static boolean containsOperatorsInternal(ILogicalOperator currentOp,
- Set<LogicalOperatorTag> interestedOperatorTags) {
- if (interestedOperatorTags.contains(currentOp.getOperatorTag())) {
- return true;
- }
- if (currentOp.getOperatorTag() == LogicalOperatorTag.SUBPLAN) {
- if (containsOperators((SubplanOperator) currentOp, interestedOperatorTags)) {
- return true;
- }
- }
- for (Mutable<ILogicalOperator> childRef : currentOp.getInputs()) {
- if (containsOperatorsInternal(childRef.getValue(), interestedOperatorTags)) {
- return true;
- }
- }
- return false;
- }
-
}
http://git-wip-us.apache.org/repos/asf/asterixdb/blob/c89d668f/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/translator/LangExpressionToPlanTranslator.java
----------------------------------------------------------------------
diff --git a/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/translator/LangExpressionToPlanTranslator.java b/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/translator/LangExpressionToPlanTranslator.java
index 56a5a57..b73ef82 100644
--- a/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/translator/LangExpressionToPlanTranslator.java
+++ b/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/translator/LangExpressionToPlanTranslator.java
@@ -22,13 +22,13 @@ import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collections;
-import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
+import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
-import java.util.Map.Entry;
import java.util.Set;
+import java.util.Map.Entry;
import java.util.concurrent.atomic.AtomicLong;
import org.apache.asterix.algebra.base.ILangExpressionToPlanTranslator;
@@ -39,15 +39,15 @@ import org.apache.asterix.common.functions.FunctionConstants;
import org.apache.asterix.common.functions.FunctionSignature;
import org.apache.asterix.lang.aql.util.RangeMapBuilder;
import org.apache.asterix.lang.common.base.Expression;
-import org.apache.asterix.lang.common.base.Expression.Kind;
import org.apache.asterix.lang.common.base.ILangExpression;
import org.apache.asterix.lang.common.base.Statement;
+import org.apache.asterix.lang.common.base.Expression.Kind;
import org.apache.asterix.lang.common.clause.GroupbyClause;
import org.apache.asterix.lang.common.clause.LetClause;
import org.apache.asterix.lang.common.clause.LimitClause;
import org.apache.asterix.lang.common.clause.OrderbyClause;
-import org.apache.asterix.lang.common.clause.OrderbyClause.OrderModifier;
import org.apache.asterix.lang.common.clause.WhereClause;
+import org.apache.asterix.lang.common.clause.OrderbyClause.OrderModifier;
import org.apache.asterix.lang.common.expression.CallExpr;
import org.apache.asterix.lang.common.expression.FieldAccessor;
import org.apache.asterix.lang.common.expression.FieldBinding;
@@ -55,14 +55,14 @@ import org.apache.asterix.lang.common.expression.GbyVariableExpressionPair;
import org.apache.asterix.lang.common.expression.IfExpr;
import org.apache.asterix.lang.common.expression.IndexAccessor;
import org.apache.asterix.lang.common.expression.ListConstructor;
-import org.apache.asterix.lang.common.expression.ListConstructor.Type;
import org.apache.asterix.lang.common.expression.LiteralExpr;
import org.apache.asterix.lang.common.expression.OperatorExpr;
import org.apache.asterix.lang.common.expression.QuantifiedExpression;
-import org.apache.asterix.lang.common.expression.QuantifiedExpression.Quantifier;
import org.apache.asterix.lang.common.expression.RecordConstructor;
import org.apache.asterix.lang.common.expression.UnaryExpr;
import org.apache.asterix.lang.common.expression.VariableExpr;
+import org.apache.asterix.lang.common.expression.ListConstructor.Type;
+import org.apache.asterix.lang.common.expression.QuantifiedExpression.Quantifier;
import org.apache.asterix.lang.common.literal.StringLiteral;
import org.apache.asterix.lang.common.statement.FunctionDecl;
import org.apache.asterix.lang.common.statement.Query;
@@ -73,13 +73,13 @@ import org.apache.asterix.lang.common.util.FunctionUtil;
import org.apache.asterix.lang.common.visitor.base.AbstractQueryExpressionVisitor;
import org.apache.asterix.metadata.MetadataException;
import org.apache.asterix.metadata.MetadataManager;
-import org.apache.asterix.metadata.declared.AqlDataSource.AqlDataSourceType;
import org.apache.asterix.metadata.declared.AqlMetadataProvider;
import org.apache.asterix.metadata.declared.AqlSourceId;
import org.apache.asterix.metadata.declared.DatasetDataSource;
import org.apache.asterix.metadata.declared.LoadableDataSource;
import org.apache.asterix.metadata.declared.ResultSetDataSink;
import org.apache.asterix.metadata.declared.ResultSetSinkId;
+import org.apache.asterix.metadata.declared.AqlDataSource.AqlDataSourceType;
import org.apache.asterix.metadata.entities.Dataset;
import org.apache.asterix.metadata.entities.Function;
import org.apache.asterix.metadata.entities.InternalDatasetDetails;
@@ -115,15 +115,15 @@ 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.OperatorAnnotations;
import org.apache.hyracks.algebricks.core.algebra.expressions.AbstractFunctionCallExpression;
-import org.apache.hyracks.algebricks.core.algebra.expressions.AbstractFunctionCallExpression.FunctionKind;
import org.apache.hyracks.algebricks.core.algebra.expressions.AggregateFunctionCallExpression;
import org.apache.hyracks.algebricks.core.algebra.expressions.BroadcastExpressionAnnotation;
-import org.apache.hyracks.algebricks.core.algebra.expressions.BroadcastExpressionAnnotation.BroadcastSide;
import org.apache.hyracks.algebricks.core.algebra.expressions.ConstantExpression;
import org.apache.hyracks.algebricks.core.algebra.expressions.IExpressionAnnotation;
import org.apache.hyracks.algebricks.core.algebra.expressions.ScalarFunctionCallExpression;
import org.apache.hyracks.algebricks.core.algebra.expressions.UnnestingFunctionCallExpression;
import org.apache.hyracks.algebricks.core.algebra.expressions.VariableReferenceExpression;
+import org.apache.hyracks.algebricks.core.algebra.expressions.AbstractFunctionCallExpression.FunctionKind;
+import org.apache.hyracks.algebricks.core.algebra.expressions.BroadcastExpressionAnnotation.BroadcastSide;
import org.apache.hyracks.algebricks.core.algebra.functions.AlgebricksBuiltinFunctions;
import org.apache.hyracks.algebricks.core.algebra.functions.FunctionIdentifier;
import org.apache.hyracks.algebricks.core.algebra.functions.IFunctionInfo;
@@ -139,13 +139,13 @@ import org.apache.hyracks.algebricks.core.algebra.operators.logical.InsertDelete
import org.apache.hyracks.algebricks.core.algebra.operators.logical.LimitOperator;
import org.apache.hyracks.algebricks.core.algebra.operators.logical.NestedTupleSourceOperator;
import org.apache.hyracks.algebricks.core.algebra.operators.logical.OrderOperator;
-import org.apache.hyracks.algebricks.core.algebra.operators.logical.OrderOperator.IOrder.OrderKind;
import org.apache.hyracks.algebricks.core.algebra.operators.logical.ProjectOperator;
import org.apache.hyracks.algebricks.core.algebra.operators.logical.SelectOperator;
import org.apache.hyracks.algebricks.core.algebra.operators.logical.SinkOperator;
import org.apache.hyracks.algebricks.core.algebra.operators.logical.SubplanOperator;
import org.apache.hyracks.algebricks.core.algebra.operators.logical.UnionAllOperator;
import org.apache.hyracks.algebricks.core.algebra.operators.logical.UnnestOperator;
+import org.apache.hyracks.algebricks.core.algebra.operators.logical.OrderOperator.IOrder.OrderKind;
import org.apache.hyracks.algebricks.core.algebra.operators.logical.visitors.LogicalOperatorDeepCopyWithNewVariablesVisitor;
import org.apache.hyracks.algebricks.core.algebra.operators.logical.visitors.VariableUtilities;
import org.apache.hyracks.algebricks.core.algebra.plan.ALogicalPlanImpl;
@@ -1526,7 +1526,7 @@ class LangExpressionToPlanTranslator
* <code>currentOpRef</code> to replace variables properly.
* @throws AsterixException
*/
- private Map<LogicalVariable, LogicalVariable> eliminateSharedOperatorReference(
+ private LinkedHashMap<LogicalVariable, LogicalVariable> eliminateSharedOperatorReference(
Mutable<ILogicalOperator> currentOpRef, Set<Mutable<ILogicalOperator>> opRefSet) throws AsterixException {
try {
opRefSet.add(currentOpRef);
@@ -1547,7 +1547,7 @@ class LangExpressionToPlanTranslator
}
int childIndex = 0;
- Map<LogicalVariable, LogicalVariable> varMap = new HashMap<>();
+ LinkedHashMap<LogicalVariable, LogicalVariable> varMap = new LinkedHashMap<>();
for (Mutable<ILogicalOperator> childRef : currentOperator.getInputs()) {
if (opRefSet.contains(childRef)) {
// There is a shared operator reference in the query plan.
@@ -1555,7 +1555,8 @@ class LangExpressionToPlanTranslator
LogicalOperatorDeepCopyWithNewVariablesVisitor visitor =
new LogicalOperatorDeepCopyWithNewVariablesVisitor(context, null);
ILogicalOperator newChild = childRef.getValue().accept(visitor, null);
- Map<LogicalVariable, LogicalVariable> cloneVarMap = visitor.getInputToOutputVariableMapping();
+ LinkedHashMap<LogicalVariable, LogicalVariable> cloneVarMap = visitor
+ .getInputToOutputVariableMapping();
// Substitute variables according to the deep copy which generates new variables.
VariableUtilities.substituteVariables(currentOperator, cloneVarMap, null);
@@ -1568,7 +1569,7 @@ class LangExpressionToPlanTranslator
// Recursively eliminate shared operator reference for the operator subtree,
// even if it is a deep copy of some other one.
- Map<LogicalVariable, LogicalVariable> childVarMap = eliminateSharedOperatorReference(childRef,
+ LinkedHashMap<LogicalVariable, LogicalVariable> childVarMap = eliminateSharedOperatorReference(childRef,
opRefSet);
// Substitute variables according to the new subtree.
VariableUtilities.substituteVariables(currentOperator, childVarMap, null);
http://git-wip-us.apache.org/repos/asf/asterixdb/blob/c89d668f/asterixdb/asterix-app/src/test/resources/optimizerts/queries/join-singletonbranch-2.sqlpp
----------------------------------------------------------------------
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/queries/join-singletonbranch-2.sqlpp b/asterixdb/asterix-app/src/test/resources/optimizerts/queries/join-singletonbranch-2.sqlpp
new file mode 100644
index 0000000..6a85b6a
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/queries/join-singletonbranch-2.sqlpp
@@ -0,0 +1,43 @@
+/*
+ * 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.
+ */
+
+drop dataverse test if exists;
+
+create dataverse test;
+
+use test;
+
+create type FooType as {
+ fid: int32
+}
+
+create type BarType as {
+ bid: int32
+}
+
+create dataset Foo(FooType) primary key fid;
+
+create dataset Bar(BarType) primary key bid;
+
+SELECT *
+FROM (SELECT AVG(f.fee) foo_avg FROM Foo f) f
+JOIN Bar b
+ON b.fee < f.avg;
+
+drop dataverse test;
http://git-wip-us.apache.org/repos/asf/asterixdb/blob/c89d668f/asterixdb/asterix-app/src/test/resources/optimizerts/queries/join-singletonbranch-3.sqlpp
----------------------------------------------------------------------
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/queries/join-singletonbranch-3.sqlpp b/asterixdb/asterix-app/src/test/resources/optimizerts/queries/join-singletonbranch-3.sqlpp
new file mode 100644
index 0000000..e555352
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/queries/join-singletonbranch-3.sqlpp
@@ -0,0 +1,42 @@
+/*
+ * 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.
+ */
+
+drop dataverse test if exists;
+
+create dataverse test;
+
+use test;
+
+create type FooType as {
+ fid: int32
+}
+
+create type BarType as {
+ bid: int32
+}
+
+create dataset Foo(FooType) primary key fid;
+
+create dataset Bar(BarType) primary key bid;
+
+SELECT *
+FROM (SELECT AVG(f.fee) foo_avg FROM Foo f) f, Bar b
+WHERE b.fee < f.avg;
+
+drop dataverse test;
http://git-wip-us.apache.org/repos/asf/asterixdb/blob/c89d668f/asterixdb/asterix-app/src/test/resources/optimizerts/queries/join-singletonbranch.sqlpp
----------------------------------------------------------------------
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/queries/join-singletonbranch.sqlpp b/asterixdb/asterix-app/src/test/resources/optimizerts/queries/join-singletonbranch.sqlpp
new file mode 100644
index 0000000..2b92d97
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/queries/join-singletonbranch.sqlpp
@@ -0,0 +1,41 @@
+/*
+ * 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.
+ */
+
+drop dataverse test if exists;
+
+create dataverse test;
+
+use test;
+
+create type FooType as {
+ fid: int32
+}
+
+create type BarType as {
+ bid: int32
+}
+
+create dataset Foo(FooType) primary key fid;
+
+create dataset Bar(BarType) primary key bid;
+
+SELECT * FROM Bar b
+WHERE b.fee < (SELECT VALUE AVG(f.fee) FROM Foo f)[0];
+
+drop dataverse test;
http://git-wip-us.apache.org/repos/asf/asterixdb/blob/c89d668f/asterixdb/asterix-app/src/test/resources/optimizerts/queries/tpcds/query-ASTERIXDB-1581-correlated.sqlpp
----------------------------------------------------------------------
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/queries/tpcds/query-ASTERIXDB-1581-correlated.sqlpp b/asterixdb/asterix-app/src/test/resources/optimizerts/queries/tpcds/query-ASTERIXDB-1581-correlated.sqlpp
new file mode 100644
index 0000000..9f96f9b
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/queries/tpcds/query-ASTERIXDB-1581-correlated.sqlpp
@@ -0,0 +1,96 @@
+/*
+ * 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.
+ */
+
+drop dataverse tpcds if exists;
+create dataverse tpcds;
+
+use tpcds;
+
+create type tpcds.store_sales_type as closed {
+ ss_sold_date_sk: int64?,
+ ss_sold_time_sk: int64?,
+ ss_item_sk: int64,
+ ss_customer_sk: int64?,
+ ss_cdemo_sk: int64?,
+ ss_hdemo_sk: int64?,
+ ss_addr_sk: int64?,
+ ss_store_sk: int64?,
+ ss_promo_sk: int64?,
+ ss_ticket_number: int64,
+ ss_quantity: int64?,
+ ss_wholesale_cost: double?,
+ ss_list_price: double?,
+ ss_sales_price: double?,
+ ss_ext_discount_amt: double?,
+ ss_ext_sales_price: double?,
+ ss_ext_wholesale_cost: double?,
+ ss_ext_list_price: double?,
+ ss_ext_tax: double?,
+ ss_coupon_amt: double?,
+ ss_net_paid: double?,
+ ss_net_paid_inc_tax: double?,
+ ss_net_profit: double?
+}
+
+
+create type tpcds.item_type as closed {
+ i_item_sk: int64,
+ i_item_id: string,
+ i_rec_start_date: string?,
+ i_rec_end_date: string?,
+ i_item_desc: string?,
+ i_current_price: double?,
+ i_wholesale_cost: double?,
+ i_brand_id: int64? ,
+ i_brand: string?,
+ i_class_id: int64? ,
+ i_class: string?,
+ i_category_id: int64? ,
+ i_category: string?,
+ i_manufact_id: int64? ,
+ i_manufact: string?,
+ i_size: string?,
+ i_formulation: string?,
+ i_color: string?,
+ i_units: string?,
+ i_container: string?,
+ i_manager_id: int64?,
+ i_product_name: string?
+}
+
+create dataset store_sales (store_sales_type)
+primary key ss_item_sk, ss_ticket_number;
+
+create dataset item (item_type)
+primary key i_item_sk;
+
+select case when (select value count(ss)
+ from store_sales ss
+ where ss_quantity = item.i_item_sk)[0] < 25437
+ then (select avg(ss_ext_discount_amt)
+ from store_sales
+ where ss_quantity = item.i_item_sk)
+ else (select avg(ss_net_profit)
+ from store_sales
+ where ss_quantity = item.i_item_sk)
+ end bucket1
+from item
+where i_item_sk = 1;
+
+drop dataverse tpcds;
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/asterixdb/blob/c89d668f/asterixdb/asterix-app/src/test/resources/optimizerts/queries/tpcds/query-ASTERIXDB-1581.sqlpp
----------------------------------------------------------------------
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/queries/tpcds/query-ASTERIXDB-1581.sqlpp b/asterixdb/asterix-app/src/test/resources/optimizerts/queries/tpcds/query-ASTERIXDB-1581.sqlpp
new file mode 100644
index 0000000..1fecc6c
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/queries/tpcds/query-ASTERIXDB-1581.sqlpp
@@ -0,0 +1,96 @@
+/*
+ * 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.
+ */
+
+drop dataverse tpcds if exists;
+create dataverse tpcds;
+
+use tpcds;
+
+create type tpcds.store_sales_type as closed {
+ ss_sold_date_sk: int64?,
+ ss_sold_time_sk: int64?,
+ ss_item_sk: int64,
+ ss_customer_sk: int64?,
+ ss_cdemo_sk: int64?,
+ ss_hdemo_sk: int64?,
+ ss_addr_sk: int64?,
+ ss_store_sk: int64?,
+ ss_promo_sk: int64?,
+ ss_ticket_number: int64,
+ ss_quantity: int64?,
+ ss_wholesale_cost: double?,
+ ss_list_price: double?,
+ ss_sales_price: double?,
+ ss_ext_discount_amt: double?,
+ ss_ext_sales_price: double?,
+ ss_ext_wholesale_cost: double?,
+ ss_ext_list_price: double?,
+ ss_ext_tax: double?,
+ ss_coupon_amt: double?,
+ ss_net_paid: double?,
+ ss_net_paid_inc_tax: double?,
+ ss_net_profit: double?
+}
+
+
+create type tpcds.item_type as closed {
+ i_item_sk: int64,
+ i_item_id: string,
+ i_rec_start_date: string?,
+ i_rec_end_date: string?,
+ i_item_desc: string?,
+ i_current_price: double?,
+ i_wholesale_cost: double?,
+ i_brand_id: int64? ,
+ i_brand: string?,
+ i_class_id: int64? ,
+ i_class: string?,
+ i_category_id: int64? ,
+ i_category: string?,
+ i_manufact_id: int64? ,
+ i_manufact: string?,
+ i_size: string?,
+ i_formulation: string?,
+ i_color: string?,
+ i_units: string?,
+ i_container: string?,
+ i_manager_id: int64?,
+ i_product_name: string?
+}
+
+create dataset store_sales (store_sales_type)
+primary key ss_item_sk, ss_ticket_number;
+
+create dataset item (item_type)
+primary key i_item_sk;
+
+select case when (select value count(ss)
+ from store_sales ss
+ where ss_quantity >= 1 and ss_quantity <= 20)[0] < 25437
+ then (select avg(ss_ext_discount_amt)
+ from store_sales
+ where ss_quantity >= 1 and ss_quantity <= 20)
+ else (select avg(ss_net_profit)
+ from store_sales
+ where ss_quantity >= 1 and ss_quantity <= 20)
+ end bucket1
+from item
+where i_item_sk = 1;
+
+drop dataverse tpcds;
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/asterixdb/blob/c89d668f/asterixdb/asterix-app/src/test/resources/optimizerts/results/filter-nested.plan
----------------------------------------------------------------------
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/filter-nested.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/filter-nested.plan
index 7448380..3ed2b6f 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/filter-nested.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/filter-nested.plan
@@ -6,6 +6,6 @@
-- STREAM_PROJECT |PARTITIONED|
-- ONE_TO_ONE_EXCHANGE |PARTITIONED|
-- DATASOURCE_SCAN |PARTITIONED|
- -- ONE_TO_ONE_EXCHANGE |PARTITIONED|
+ -- BROADCAST_EXCHANGE |PARTITIONED|
-- ASSIGN |PARTITIONED|
- -- EMPTY_TUPLE_SOURCE |PARTITIONED|
\ No newline at end of file
+ -- EMPTY_TUPLE_SOURCE |PARTITIONED|
http://git-wip-us.apache.org/repos/asf/asterixdb/blob/c89d668f/asterixdb/asterix-app/src/test/resources/optimizerts/results/join-singletonbranch-2.plan
----------------------------------------------------------------------
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/join-singletonbranch-2.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/join-singletonbranch-2.plan
new file mode 100644
index 0000000..3bb60f3
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/join-singletonbranch-2.plan
@@ -0,0 +1,28 @@
+-- DISTRIBUTE_RESULT |PARTITIONED|
+ -- ONE_TO_ONE_EXCHANGE |PARTITIONED|
+ -- STREAM_PROJECT |PARTITIONED|
+ -- ASSIGN |PARTITIONED|
+ -- STREAM_PROJECT |PARTITIONED|
+ -- ONE_TO_ONE_EXCHANGE |PARTITIONED|
+ -- NESTED_LOOP |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|
+ -- BROADCAST_EXCHANGE |PARTITIONED|
+ -- ASSIGN |UNPARTITIONED|
+ -- STREAM_PROJECT |UNPARTITIONED|
+ -- ASSIGN |UNPARTITIONED|
+ -- AGGREGATE |UNPARTITIONED|
+ -- RANDOM_MERGE_EXCHANGE |PARTITIONED|
+ -- AGGREGATE |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|
http://git-wip-us.apache.org/repos/asf/asterixdb/blob/c89d668f/asterixdb/asterix-app/src/test/resources/optimizerts/results/join-singletonbranch-3.plan
----------------------------------------------------------------------
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/join-singletonbranch-3.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/join-singletonbranch-3.plan
new file mode 100644
index 0000000..7b5a4ee
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/join-singletonbranch-3.plan
@@ -0,0 +1,23 @@
+-- DISTRIBUTE_RESULT |PARTITIONED|
+ -- ONE_TO_ONE_EXCHANGE |PARTITIONED|
+ -- STREAM_PROJECT |PARTITIONED|
+ -- ASSIGN |PARTITIONED|
+ -- STREAM_PROJECT |PARTITIONED|
+ -- STREAM_SELECT |PARTITIONED|
+ -- STREAM_PROJECT |PARTITIONED|
+ -- ONE_TO_ONE_EXCHANGE |PARTITIONED|
+ -- DATASOURCE_SCAN |PARTITIONED|
+ -- BROADCAST_EXCHANGE |PARTITIONED|
+ -- ASSIGN |UNPARTITIONED|
+ -- STREAM_PROJECT |UNPARTITIONED|
+ -- ASSIGN |UNPARTITIONED|
+ -- AGGREGATE |UNPARTITIONED|
+ -- RANDOM_MERGE_EXCHANGE |PARTITIONED|
+ -- AGGREGATE |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|
http://git-wip-us.apache.org/repos/asf/asterixdb/blob/c89d668f/asterixdb/asterix-app/src/test/resources/optimizerts/results/join-singletonbranch.plan
----------------------------------------------------------------------
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/join-singletonbranch.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/join-singletonbranch.plan
new file mode 100644
index 0000000..c072812
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/join-singletonbranch.plan
@@ -0,0 +1,28 @@
+-- DISTRIBUTE_RESULT |PARTITIONED|
+ -- ONE_TO_ONE_EXCHANGE |PARTITIONED|
+ -- STREAM_PROJECT |PARTITIONED|
+ -- ASSIGN |PARTITIONED|
+ -- STREAM_PROJECT |PARTITIONED|
+ -- ONE_TO_ONE_EXCHANGE |PARTITIONED|
+ -- NESTED_LOOP |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|
+ -- BROADCAST_EXCHANGE |PARTITIONED|
+ -- STREAM_PROJECT |UNPARTITIONED|
+ -- ASSIGN |UNPARTITIONED|
+ -- AGGREGATE |UNPARTITIONED|
+ -- AGGREGATE |UNPARTITIONED|
+ -- RANDOM_MERGE_EXCHANGE |PARTITIONED|
+ -- AGGREGATE |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|
http://git-wip-us.apache.org/repos/asf/asterixdb/blob/c89d668f/asterixdb/asterix-app/src/test/resources/optimizerts/results/nest_aggregate.plan
----------------------------------------------------------------------
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/nest_aggregate.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/nest_aggregate.plan
index 41b07d9..d4cdff4 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/nest_aggregate.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/nest_aggregate.plan
@@ -8,7 +8,7 @@
{
-- AGGREGATE |LOCAL|
-- STREAM_LIMIT |LOCAL|
- -- IN_MEMORY_STABLE_SORT [$$41(ASC)] |LOCAL|
+ -- IN_MEMORY_STABLE_SORT [$$39(ASC)] |LOCAL|
-- MICRO_PRE_CLUSTERED_GROUP_BY[$$51] |LOCAL|
{
-- AGGREGATE |LOCAL|
@@ -29,7 +29,7 @@
-- ONE_TO_ONE_EXCHANGE |PARTITIONED|
-- STREAM_PROJECT |PARTITIONED|
-- ONE_TO_ONE_EXCHANGE |PARTITIONED|
- -- HYBRID_HASH_JOIN [$$34][$$39] |PARTITIONED|
+ -- HYBRID_HASH_JOIN [$$34][$$40] |PARTITIONED|
-- ONE_TO_ONE_EXCHANGE |PARTITIONED|
-- HYBRID_HASH_JOIN [$$34][$$35] |PARTITIONED|
-- ONE_TO_ONE_EXCHANGE |PARTITIONED|
@@ -45,7 +45,7 @@
-- DATASOURCE_SCAN |PARTITIONED|
-- ONE_TO_ONE_EXCHANGE |PARTITIONED|
-- EMPTY_TUPLE_SOURCE |PARTITIONED|
- -- HASH_PARTITION_EXCHANGE [$$39] |PARTITIONED|
+ -- HASH_PARTITION_EXCHANGE [$$40] |PARTITIONED|
-- ASSIGN |PARTITIONED|
-- STREAM_PROJECT |PARTITIONED|
-- ONE_TO_ONE_EXCHANGE |PARTITIONED|