address the case where there are multiple query plans inside a subplan operator
diff --git a/asterix-algebra/src/main/java/edu/uci/ics/asterix/optimizer/base/RuleCollections.java b/asterix-algebra/src/main/java/edu/uci/ics/asterix/optimizer/base/RuleCollections.java
index 587cbc5..d5169c7 100644
--- a/asterix-algebra/src/main/java/edu/uci/ics/asterix/optimizer/base/RuleCollections.java
+++ b/asterix-algebra/src/main/java/edu/uci/ics/asterix/optimizer/base/RuleCollections.java
@@ -164,7 +164,6 @@
public final static List<IAlgebraicRewriteRule> buildLoadFieldsRuleCollection() {
List<IAlgebraicRewriteRule> fieldLoads = new LinkedList<IAlgebraicRewriteRule>();
fieldLoads.add(new LoadRecordFieldsRule());
- fieldLoads.add(new NestedSubplanToJoinRule());
fieldLoads.add(new PushFieldAccessRule());
// fieldLoads.add(new ByNameToByHandleFieldAccessRule()); -- disabled
fieldLoads.add(new ByNameToByIndexFieldAccessRule());
diff --git a/asterix-algebra/src/main/java/edu/uci/ics/asterix/optimizer/rules/NestedSubplanToJoinRule.java b/asterix-algebra/src/main/java/edu/uci/ics/asterix/optimizer/rules/NestedSubplanToJoinRule.java
index 2e5d358..c5d415e 100644
--- a/asterix-algebra/src/main/java/edu/uci/ics/asterix/optimizer/rules/NestedSubplanToJoinRule.java
+++ b/asterix-algebra/src/main/java/edu/uci/ics/asterix/optimizer/rules/NestedSubplanToJoinRule.java
@@ -15,6 +15,7 @@
package edu.uci.ics.asterix.optimizer.rules;
+import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
@@ -73,23 +74,33 @@
Set<LogicalVariable> freeVars = new HashSet<LogicalVariable>();
OperatorPropertiesUtil.getFreeVariablesInSubplans(subplan, freeVars);
if (!freeVars.isEmpty()) {
+ /**
+ * the subplan is correlated with the outer plan, other rules can deal with it
+ */
continue;
}
- //we only deals with the first subplan for now
- //TODO: not clear when there are multiple subplans inside one subplan operator
+ /** get the input operator of the subplan operator */
ILogicalOperator subplanInput = subplan.getInputs().get(0).getValue();
- List<ILogicalPlan> nestedPlans = subplan.getNestedPlans();
- ILogicalPlan nestedPlan = nestedPlans.get(0);
- List<Mutable<ILogicalOperator>> nestedRoots = nestedPlan.getRoots();
- //expend the input and roots into a DAG of nested loop joins
+ /** get all nested top operators */
+ List<ILogicalPlan> nestedPlans = subplan.getNestedPlans();
+ List<Mutable<ILogicalOperator>> nestedRoots = new ArrayList<Mutable<ILogicalOperator>>();
+ for (ILogicalPlan nestedPlan : nestedPlans) {
+ nestedRoots.addAll(nestedPlan.getRoots());
+ }
+ if (nestedRoots.size() == 0) {
+ /** there is no nested top operators */
+ return false;
+ }
+
+ /** expend the input and roots into a DAG of nested loop joins */
Mutable<ILogicalExpression> expr = new MutableObject<ILogicalExpression>(ConstantExpression.TRUE);
Mutable<ILogicalOperator> nestedRootRef = nestedRoots.get(0);
ILogicalOperator join = new LeftOuterJoinOperator(expr, new MutableObject<ILogicalOperator>(subplanInput),
nestedRootRef);
- //rewrite the nested tuple source to be empty tuple source
+ /** rewrite the nested tuple source to be empty tuple source */
rewriteNestedTupleSource(nestedRootRef);
for (int i = 1; i < nestedRoots.size(); i++) {