Yingyi Bu has uploaded a new change for review.

  https://asterix-gerrit.ics.uci.edu/751

Change subject: ASTERIXDB-1226: support SQL++ core group-by semantics.
......................................................................

ASTERIXDB-1226: support SQL++ core group-by semantics.

-Fixed introduce group-by combiner rule;
-Fixed deep copy (without new variables) visitor.

Change-Id: I9602681a698925bde4eca33d85df66d06b9a33dd
---
M 
algebricks/algebricks-core/src/main/java/org/apache/hyracks/algebricks/core/algebra/expressions/AbstractFunctionCallExpression.java
M 
algebricks/algebricks-core/src/main/java/org/apache/hyracks/algebricks/core/algebra/operators/logical/AbstractLogicalOperator.java
M 
algebricks/algebricks-core/src/main/java/org/apache/hyracks/algebricks/core/algebra/operators/logical/NestedTupleSourceOperator.java
M 
algebricks/algebricks-core/src/main/java/org/apache/hyracks/algebricks/core/algebra/operators/logical/visitors/LogicalExpressionDeepCopyWithNewVariablesVisitor.java
M 
algebricks/algebricks-core/src/main/java/org/apache/hyracks/algebricks/core/algebra/operators/logical/visitors/LogicalOperatorDeepCopyWithNewVariablesVisitor.java
M 
algebricks/algebricks-core/src/main/java/org/apache/hyracks/algebricks/core/algebra/operators/logical/visitors/OperatorDeepCopyVisitor.java
M 
algebricks/algebricks-core/src/main/java/org/apache/hyracks/algebricks/core/algebra/operators/physical/AbstractPropagatePropertiesForUsedVariablesPOperator.java
M 
algebricks/algebricks-core/src/main/java/org/apache/hyracks/algebricks/core/algebra/util/OperatorManipulationUtil.java
M 
algebricks/algebricks-core/src/main/java/org/apache/hyracks/algebricks/core/rewriter/base/HeuristicOptimizer.java
M 
algebricks/algebricks-rewriter/src/main/java/org/apache/hyracks/algebricks/rewriter/rules/AbstractIntroduceGroupByCombinerRule.java
10 files changed, 133 insertions(+), 72 deletions(-)


  git pull ssh://asterix-gerrit.ics.uci.edu:29418/hyracks refs/changes/51/751/1

diff --git 
a/algebricks/algebricks-core/src/main/java/org/apache/hyracks/algebricks/core/algebra/expressions/AbstractFunctionCallExpression.java
 
b/algebricks/algebricks-core/src/main/java/org/apache/hyracks/algebricks/core/algebra/expressions/AbstractFunctionCallExpression.java
index 71c7ed0..b35f692 100644
--- 
a/algebricks/algebricks-core/src/main/java/org/apache/hyracks/algebricks/core/algebra/expressions/AbstractFunctionCallExpression.java
+++ 
b/algebricks/algebricks-core/src/main/java/org/apache/hyracks/algebricks/core/algebra/expressions/AbstractFunctionCallExpression.java
@@ -124,18 +124,6 @@
             sb.append(ref.getValue());
         }
         sb.append("]");
-        if (opaqueParameters != null) {
-            sb.append(", OpaqueArgs:[");
-            first = true;
-            for (Object param : opaqueParameters) {
-                if (first) {
-                    first = false;
-                } else {
-                    sb.append(", ");
-                }
-                sb.append(param);
-            }
-        }
         return sb.toString();
     }
 
diff --git 
a/algebricks/algebricks-core/src/main/java/org/apache/hyracks/algebricks/core/algebra/operators/logical/AbstractLogicalOperator.java
 
b/algebricks/algebricks-core/src/main/java/org/apache/hyracks/algebricks/core/algebra/operators/logical/AbstractLogicalOperator.java
index 2410ca0..61a2353 100644
--- 
a/algebricks/algebricks-core/src/main/java/org/apache/hyracks/algebricks/core/algebra/operators/logical/AbstractLogicalOperator.java
+++ 
b/algebricks/algebricks-core/src/main/java/org/apache/hyracks/algebricks/core/algebra/operators/logical/AbstractLogicalOperator.java
@@ -88,6 +88,14 @@
         return schema;
     }
 
+    public void setSchema(List<LogicalVariable> schema) {
+        if (schema == null) {
+            return;
+        }
+        this.schema = new ArrayList<>();
+        this.schema.addAll(schema);
+    }
+
     public void setPhysicalOperator(IPhysicalOperator physicalOp) {
         this.physicalOperator = physicalOp;
     }
diff --git 
a/algebricks/algebricks-core/src/main/java/org/apache/hyracks/algebricks/core/algebra/operators/logical/NestedTupleSourceOperator.java
 
b/algebricks/algebricks-core/src/main/java/org/apache/hyracks/algebricks/core/algebra/operators/logical/NestedTupleSourceOperator.java
index a3a446a..2b66e8f 100644
--- 
a/algebricks/algebricks-core/src/main/java/org/apache/hyracks/algebricks/core/algebra/operators/logical/NestedTupleSourceOperator.java
+++ 
b/algebricks/algebricks-core/src/main/java/org/apache/hyracks/algebricks/core/algebra/operators/logical/NestedTupleSourceOperator.java
@@ -19,9 +19,9 @@
 package org.apache.hyracks.algebricks.core.algebra.operators.logical;
 
 import java.util.ArrayList;
+import java.util.List;
 
 import org.apache.commons.lang3.mutable.Mutable;
-
 import org.apache.hyracks.algebricks.common.exceptions.AlgebricksException;
 import org.apache.hyracks.algebricks.core.algebra.base.ILogicalOperator;
 import org.apache.hyracks.algebricks.core.algebra.base.LogicalOperatorTag;
@@ -64,7 +64,10 @@
         schema = new ArrayList<LogicalVariable>();
         ILogicalOperator topOp = dataSourceReference.getValue();
         for (Mutable<ILogicalOperator> i : topOp.getInputs()) {
-            schema.addAll(i.getValue().getSchema());
+            List<LogicalVariable> inputSchema = i.getValue().getSchema();
+            if (inputSchema != null) {
+                schema.addAll(inputSchema);
+            }
         }
     }
 
diff --git 
a/algebricks/algebricks-core/src/main/java/org/apache/hyracks/algebricks/core/algebra/operators/logical/visitors/LogicalExpressionDeepCopyWithNewVariablesVisitor.java
 
b/algebricks/algebricks-core/src/main/java/org/apache/hyracks/algebricks/core/algebra/operators/logical/visitors/LogicalExpressionDeepCopyWithNewVariablesVisitor.java
index 36111ff..cb89a73 100644
--- 
a/algebricks/algebricks-core/src/main/java/org/apache/hyracks/algebricks/core/algebra/operators/logical/visitors/LogicalExpressionDeepCopyWithNewVariablesVisitor.java
+++ 
b/algebricks/algebricks-core/src/main/java/org/apache/hyracks/algebricks/core/algebra/operators/logical/visitors/LogicalExpressionDeepCopyWithNewVariablesVisitor.java
@@ -99,6 +99,8 @@
             throws AlgebricksException {
         AggregateFunctionCallExpression exprCopy = new 
AggregateFunctionCallExpression(expr.getFunctionInfo(),
                 expr.isTwoStep(), 
deepCopyExpressionReferenceList(expr.getArguments()));
+        exprCopy.setStepOneAggregate(expr.getStepOneAggregate());
+        exprCopy.setStepTwoAggregate(expr.getStepTwoAggregate());
         deepCopyAnnotations(expr, exprCopy);
         deepCopyOpaqueParameters(expr, exprCopy);
         return exprCopy;
diff --git 
a/algebricks/algebricks-core/src/main/java/org/apache/hyracks/algebricks/core/algebra/operators/logical/visitors/LogicalOperatorDeepCopyWithNewVariablesVisitor.java
 
b/algebricks/algebricks-core/src/main/java/org/apache/hyracks/algebricks/core/algebra/operators/logical/visitors/LogicalOperatorDeepCopyWithNewVariablesVisitor.java
index 213b2b1..b1d8610 100644
--- 
a/algebricks/algebricks-core/src/main/java/org/apache/hyracks/algebricks/core/algebra/operators/logical/visitors/LogicalOperatorDeepCopyWithNewVariablesVisitor.java
+++ 
b/algebricks/algebricks-core/src/main/java/org/apache/hyracks/algebricks/core/algebra/operators/logical/visitors/LogicalOperatorDeepCopyWithNewVariablesVisitor.java
@@ -335,8 +335,8 @@
             throws AlgebricksException {
         InnerJoinOperator opCopy = new InnerJoinOperator(
                 
exprDeepCopyVisitor.deepCopyExpressionReference(op.getCondition()),
-                deepCopyOperatorReference(op.getInputs().get(0), null),
-                deepCopyOperatorReference(op.getInputs().get(1), null));
+                deepCopyOperatorReference(op.getInputs().get(0), arg),
+                deepCopyOperatorReference(op.getInputs().get(1), arg));
         copyAnnotations(op, opCopy);
         opCopy.setExecutionMode(op.getExecutionMode());
         return opCopy;
@@ -347,8 +347,8 @@
             throws AlgebricksException {
         LeftOuterJoinOperator opCopy = new LeftOuterJoinOperator(
                 
exprDeepCopyVisitor.deepCopyExpressionReference(op.getCondition()),
-                deepCopyOperatorReference(op.getInputs().get(0), null),
-                deepCopyOperatorReference(op.getInputs().get(1), null));
+                deepCopyOperatorReference(op.getInputs().get(0), arg),
+                deepCopyOperatorReference(op.getInputs().get(1), arg));
         copyAnnotations(op, opCopy);
         opCopy.setExecutionMode(op.getExecutionMode());
         return opCopy;
diff --git 
a/algebricks/algebricks-core/src/main/java/org/apache/hyracks/algebricks/core/algebra/operators/logical/visitors/OperatorDeepCopyVisitor.java
 
b/algebricks/algebricks-core/src/main/java/org/apache/hyracks/algebricks/core/algebra/operators/logical/visitors/OperatorDeepCopyVisitor.java
index 931640e..ec024f3 100644
--- 
a/algebricks/algebricks-core/src/main/java/org/apache/hyracks/algebricks/core/algebra/operators/logical/visitors/OperatorDeepCopyVisitor.java
+++ 
b/algebricks/algebricks-core/src/main/java/org/apache/hyracks/algebricks/core/algebra/operators/logical/visitors/OperatorDeepCopyVisitor.java
@@ -102,16 +102,19 @@
         List<Pair<LogicalVariable, Mutable<ILogicalExpression>>> groupByList = 
new ArrayList<Pair<LogicalVariable, Mutable<ILogicalExpression>>>();
         List<Pair<LogicalVariable, Mutable<ILogicalExpression>>> decoList = 
new ArrayList<Pair<LogicalVariable, Mutable<ILogicalExpression>>>();
         ArrayList<ILogicalPlan> newSubplans = new ArrayList<ILogicalPlan>();
-        for (Pair<LogicalVariable, Mutable<ILogicalExpression>> pair : 
op.getGroupByList())
+        for (Pair<LogicalVariable, Mutable<ILogicalExpression>> pair : 
op.getGroupByList()) {
             groupByList.add(new Pair<LogicalVariable, 
Mutable<ILogicalExpression>>(pair.first,
                     deepCopyExpressionRef(pair.second)));
-        for (Pair<LogicalVariable, Mutable<ILogicalExpression>> pair : 
op.getDecorList())
+        }
+        for (Pair<LogicalVariable, Mutable<ILogicalExpression>> pair : 
op.getDecorList()) {
             decoList.add(new Pair<LogicalVariable, 
Mutable<ILogicalExpression>>(pair.first,
                     deepCopyExpressionRef(pair.second)));
-        for (ILogicalPlan plan : op.getNestedPlans()) {
-            newSubplans.add(OperatorManipulationUtil.deepCopy(plan));
         }
-        return new GroupByOperator(groupByList, decoList, newSubplans);
+        GroupByOperator gbyOp = new GroupByOperator(groupByList, decoList, 
newSubplans);
+        for (ILogicalPlan plan : op.getNestedPlans()) {
+            newSubplans.add(OperatorManipulationUtil.deepCopy(plan, gbyOp));
+        }
+        return gbyOp;
     }
 
     @Override
@@ -190,19 +193,21 @@
     @Override
     public ILogicalOperator visitSubplanOperator(SubplanOperator op, Void arg) 
throws AlgebricksException {
         ArrayList<ILogicalPlan> newSubplans = new ArrayList<ILogicalPlan>();
+        SubplanOperator subplanOp = new SubplanOperator(newSubplans);
         for (ILogicalPlan plan : op.getNestedPlans()) {
-            newSubplans.add(OperatorManipulationUtil.deepCopy(plan));
+            newSubplans.add(OperatorManipulationUtil.deepCopy(plan, 
subplanOp));
         }
-        return new SubplanOperator(newSubplans);
+        return subplanOp;
     }
 
     @Override
     public ILogicalOperator visitUnionOperator(UnionAllOperator op, Void arg) 
throws AlgebricksException {
         List<Triple<LogicalVariable, LogicalVariable, LogicalVariable>> 
newVarMap = new ArrayList<Triple<LogicalVariable, LogicalVariable, 
LogicalVariable>>();
         List<Triple<LogicalVariable, LogicalVariable, LogicalVariable>> varMap 
= op.getVariableMappings();
-        for (Triple<LogicalVariable, LogicalVariable, LogicalVariable> triple 
: varMap)
+        for (Triple<LogicalVariable, LogicalVariable, LogicalVariable> triple 
: varMap) {
             newVarMap.add(new Triple<LogicalVariable, LogicalVariable, 
LogicalVariable>(triple.first, triple.second,
                     triple.third));
+        }
         return new UnionAllOperator(newVarMap);
     }
 
@@ -343,34 +348,41 @@
 
     private void deepCopyExpressionRefs(List<Mutable<ILogicalExpression>> 
newExprs,
             List<Mutable<ILogicalExpression>> oldExprs) {
-        for (Mutable<ILogicalExpression> oldExpr : oldExprs)
+        for (Mutable<ILogicalExpression> oldExpr : oldExprs) {
             newExprs.add(new MutableObject<ILogicalExpression>(
                     ((AbstractLogicalExpression) 
oldExpr.getValue()).cloneExpression()));
+        }
     }
 
-    private Mutable<ILogicalExpression> 
deepCopyExpressionRef(Mutable<ILogicalExpression> oldExpr) {
-        return new MutableObject<ILogicalExpression>(
-                ((AbstractLogicalExpression) 
oldExpr.getValue()).cloneExpression());
+    private Mutable<ILogicalExpression> 
deepCopyExpressionRef(Mutable<ILogicalExpression> oldExprRef) {
+        ILogicalExpression oldExpr = oldExprRef.getValue();
+        if (oldExpr == null) {
+            return new MutableObject<ILogicalExpression>(null);
+        }
+        return new 
MutableObject<ILogicalExpression>(oldExpr.cloneExpression());
     }
 
     private List<LogicalVariable> deepCopyVars(List<LogicalVariable> newVars, 
List<LogicalVariable> oldVars) {
-        for (LogicalVariable oldVar : oldVars)
+        for (LogicalVariable oldVar : oldVars) {
             newVars.add(oldVar);
+        }
         return newVars;
     }
 
     private List<Object> deepCopyObjects(List<Object> newObjs, List<Object> 
oldObjs) {
-        for (Object oldObj : oldObjs)
+        for (Object oldObj : oldObjs) {
             newObjs.add(oldObj);
+        }
         return newObjs;
     }
 
     private List<Pair<IOrder, Mutable<ILogicalExpression>>> 
deepCopyOrderAndExpression(
             List<Pair<IOrder, Mutable<ILogicalExpression>>> ordersAndExprs) {
         List<Pair<IOrder, Mutable<ILogicalExpression>>> newOrdersAndExprs = 
new ArrayList<Pair<IOrder, Mutable<ILogicalExpression>>>();
-        for (Pair<IOrder, Mutable<ILogicalExpression>> pair : ordersAndExprs)
+        for (Pair<IOrder, Mutable<ILogicalExpression>> pair : ordersAndExprs) {
             newOrdersAndExprs
                     .add(new Pair<IOrder, 
Mutable<ILogicalExpression>>(pair.first, deepCopyExpressionRef(pair.second)));
+        }
         return newOrdersAndExprs;
     }
 
diff --git 
a/algebricks/algebricks-core/src/main/java/org/apache/hyracks/algebricks/core/algebra/operators/physical/AbstractPropagatePropertiesForUsedVariablesPOperator.java
 
b/algebricks/algebricks-core/src/main/java/org/apache/hyracks/algebricks/core/algebra/operators/physical/AbstractPropagatePropertiesForUsedVariablesPOperator.java
index ad44b65..5c83364 100644
--- 
a/algebricks/algebricks-core/src/main/java/org/apache/hyracks/algebricks/core/algebra/operators/physical/AbstractPropagatePropertiesForUsedVariablesPOperator.java
+++ 
b/algebricks/algebricks-core/src/main/java/org/apache/hyracks/algebricks/core/algebra/operators/physical/AbstractPropagatePropertiesForUsedVariablesPOperator.java
@@ -35,12 +35,14 @@
         IPartitioningProperty pp = 
op2.getDeliveredPhysicalProperties().getPartitioningProperty();
         List<ILocalStructuralProperty> downPropsLocal = 
op2.getDeliveredPhysicalProperties().getLocalProperties();
         List<ILocalStructuralProperty> propsLocal = new 
ArrayList<ILocalStructuralProperty>();
-        for (ILocalStructuralProperty lsp : downPropsLocal) {
-            LinkedList<LogicalVariable> cols = new 
LinkedList<LogicalVariable>();
-            lsp.getColumns(cols);
-            ILocalStructuralProperty propagatedProp = 
lsp.retainVariables(usedVariables);
-            if (propagatedProp != null) {
-                propsLocal.add(propagatedProp);
+        if (downPropsLocal != null) {
+            for (ILocalStructuralProperty lsp : downPropsLocal) {
+                LinkedList<LogicalVariable> cols = new 
LinkedList<LogicalVariable>();
+                lsp.getColumns(cols);
+                ILocalStructuralProperty propagatedProp = 
lsp.retainVariables(usedVariables);
+                if (propagatedProp != null) {
+                    propsLocal.add(propagatedProp);
+                }
             }
         }
         deliveredProperties = new StructuralPropertiesVector(pp, propsLocal);
diff --git 
a/algebricks/algebricks-core/src/main/java/org/apache/hyracks/algebricks/core/algebra/util/OperatorManipulationUtil.java
 
b/algebricks/algebricks-core/src/main/java/org/apache/hyracks/algebricks/core/algebra/util/OperatorManipulationUtil.java
index 4089268..ab40070 100644
--- 
a/algebricks/algebricks-core/src/main/java/org/apache/hyracks/algebricks/core/algebra/util/OperatorManipulationUtil.java
+++ 
b/algebricks/algebricks-core/src/main/java/org/apache/hyracks/algebricks/core/algebra/util/OperatorManipulationUtil.java
@@ -178,10 +178,12 @@
         }
     }
 
-    public static ILogicalPlan deepCopy(ILogicalPlan plan) throws 
AlgebricksException {
+    public static ILogicalPlan deepCopy(ILogicalPlan plan, ILogicalOperator 
dataSource) throws AlgebricksException {
         List<Mutable<ILogicalOperator>> roots = plan.getRoots();
         List<Mutable<ILogicalOperator>> newRoots = clonePipeline(roots);
-        return new ALogicalPlanImpl(newRoots);
+        ILogicalPlan newPlan = new ALogicalPlanImpl(newRoots);
+        setDataSource(newPlan, dataSource);
+        return newPlan;
     }
 
     public static ILogicalPlan deepCopy(ILogicalPlan plan, 
IOptimizationContext ctx) throws AlgebricksException {
@@ -189,6 +191,23 @@
         List<Mutable<ILogicalOperator>> newRoots = clonePipeline(roots);
         cloneTypeEnvironments(ctx, roots, newRoots);
         return new ALogicalPlanImpl(newRoots);
+    }
+
+    private static void setDataSource(ILogicalPlan plan, ILogicalOperator 
dataSource) {
+        for (Mutable<ILogicalOperator> rootRef : plan.getRoots()) {
+            setDataSource(rootRef, dataSource);
+        }
+    }
+
+    private static void setDataSource(Mutable<ILogicalOperator> opRef, 
ILogicalOperator dataSource) {
+        ILogicalOperator op = opRef.getValue();
+        if (op.getOperatorTag() == LogicalOperatorTag.NESTEDTUPLESOURCE) {
+            NestedTupleSourceOperator nts = (NestedTupleSourceOperator) op;
+            nts.setDataSourceReference(new 
MutableObject<ILogicalOperator>(dataSource));
+        }
+        for (Mutable<ILogicalOperator> childRef : op.getInputs()) {
+            setDataSource(childRef, dataSource);
+        }
     }
 
     private static List<Mutable<ILogicalOperator>> 
clonePipeline(List<Mutable<ILogicalOperator>> roots)
@@ -225,15 +244,15 @@
 
     public static ILogicalOperator deepCopy(ILogicalOperator op) throws 
AlgebricksException {
         OperatorDeepCopyVisitor visitor = new OperatorDeepCopyVisitor();
-        return op.accept(visitor, null);
+        AbstractLogicalOperator copiedOperator = (AbstractLogicalOperator) 
op.accept(visitor, null);
+        copiedOperator.setExecutionMode(op.getExecutionMode());
+        copiedOperator.getAnnotations().putAll(op.getAnnotations());
+        copiedOperator.setSchema(op.getSchema());
+        AbstractLogicalOperator sourceOp = (AbstractLogicalOperator) op;
+        copiedOperator.setPhysicalOperator(sourceOp.getPhysicalOperator());
+        return copiedOperator;
     }
 
-    public static ILogicalOperator deepCopyWithExcutionMode(ILogicalOperator 
op) throws AlgebricksException {
-        OperatorDeepCopyVisitor visitor = new OperatorDeepCopyVisitor();
-        AbstractLogicalOperator newOp = (AbstractLogicalOperator) 
op.accept(visitor, null);
-        newOp.setExecutionMode(op.getExecutionMode());
-        return newOp;
-    }
     /**
      * Compute type environment of a newly generated operator {@code op} and 
its input.
      *
@@ -259,6 +278,21 @@
         context.computeAndSetTypeEnvironmentForOperator(op);
     }
 
+    /**
+     * Computes the type environment for a logical query plan.
+     *
+     * @param plan,
+     *            the logical plan to consider.
+     * @param context
+     *            the typing context.
+     * @throws AlgebricksException
+     */
+    public static void computeTypeEnvironment(ILogicalPlan plan, 
ITypingContext context) throws AlgebricksException {
+        for (Mutable<ILogicalOperator> rootRef : plan.getRoots()) {
+            computeTypeEnvironmentBottomUp(rootRef.getValue(), context);
+        }
+    }
+
     /***
      * Is the operator <code>>op</code> an ancestor of any operators with tags 
in the set <code>tags</code>?
      *
@@ -279,4 +313,23 @@
         return false;
     }
 
+    public static void computeSchemaBottomUpForPlan(ILogicalPlan p) throws 
AlgebricksException {
+        for (Mutable<ILogicalOperator> r : p.getRoots()) {
+            computeSchemaBottomUpForOp((AbstractLogicalOperator) r.getValue());
+        }
+    }
+
+    public static void computeSchemaBottomUpForOp(AbstractLogicalOperator op) 
throws AlgebricksException {
+        for (Mutable<ILogicalOperator> i : op.getInputs()) {
+            computeSchemaBottomUpForOp((AbstractLogicalOperator) i.getValue());
+        }
+        if (op.hasNestedPlans()) {
+            AbstractOperatorWithNestedPlans a = 
(AbstractOperatorWithNestedPlans) op;
+            for (ILogicalPlan p : a.getNestedPlans()) {
+                computeSchemaBottomUpForPlan(p);
+            }
+        }
+        op.recomputeSchema();
+    }
+
 }
diff --git 
a/algebricks/algebricks-core/src/main/java/org/apache/hyracks/algebricks/core/rewriter/base/HeuristicOptimizer.java
 
b/algebricks/algebricks-core/src/main/java/org/apache/hyracks/algebricks/core/rewriter/base/HeuristicOptimizer.java
index 2a28d2e..60d5eb8 100644
--- 
a/algebricks/algebricks-core/src/main/java/org/apache/hyracks/algebricks/core/rewriter/base/HeuristicOptimizer.java
+++ 
b/algebricks/algebricks-core/src/main/java/org/apache/hyracks/algebricks/core/rewriter/base/HeuristicOptimizer.java
@@ -21,16 +21,14 @@
 import java.util.List;
 
 import org.apache.commons.lang3.mutable.Mutable;
-
 import org.apache.hyracks.algebricks.common.exceptions.AlgebricksException;
 import org.apache.hyracks.algebricks.common.utils.Pair;
 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.IOptimizationContext;
 import org.apache.hyracks.algebricks.core.algebra.base.PhysicalOperatorTag;
-import 
org.apache.hyracks.algebricks.core.algebra.operators.logical.AbstractLogicalOperator;
-import 
org.apache.hyracks.algebricks.core.algebra.operators.logical.AbstractOperatorWithNestedPlans;
 import 
org.apache.hyracks.algebricks.core.algebra.prettyprint.PlanPrettyPrinter;
+import 
org.apache.hyracks.algebricks.core.algebra.util.OperatorManipulationUtil;
 import org.apache.hyracks.algebricks.core.config.AlgebricksConfig;
 
 public class HeuristicOptimizer {
@@ -80,7 +78,7 @@
         PlanPrettyPrinter.printPlan(plan, sb, context.getPrettyPrintVisitor(), 
0);
         AlgebricksConfig.ALGEBRICKS_LOGGER.fine("Logical Plan:\n" + 
sb.toString());
         runOptimizationSets(plan, logicalRewrites);
-        computeSchemaBottomUpForPlan(plan);
+        OperatorManipulationUtil.computeSchemaBottomUpForPlan(plan);
         runPhysicalOptimizations(plan, physicalRewrites);
         StringBuilder sb2 = new StringBuilder();
         PlanPrettyPrinter.printPlan(plan, sb2, 
context.getPrettyPrintVisitor(), 0);
@@ -97,28 +95,9 @@
         }
     }
 
-    private static void computeSchemaBottomUpForPlan(ILogicalPlan p) throws 
AlgebricksException {
-        for (Mutable<ILogicalOperator> r : p.getRoots()) {
-            computeSchemaBottomUpForOp((AbstractLogicalOperator) r.getValue());
-        }
-    }
-
-    private static void computeSchemaBottomUpForOp(AbstractLogicalOperator op) 
throws AlgebricksException {
-        for (Mutable<ILogicalOperator> i : op.getInputs()) {
-            computeSchemaBottomUpForOp((AbstractLogicalOperator) i.getValue());
-        }
-        if (op.hasNestedPlans()) {
-            AbstractOperatorWithNestedPlans a = 
(AbstractOperatorWithNestedPlans) op;
-            for (ILogicalPlan p : a.getNestedPlans()) {
-                computeSchemaBottomUpForPlan(p);
-            }
-        }
-        op.recomputeSchema();
-    }
-
     private void runPhysicalOptimizations(ILogicalPlan plan,
             List<Pair<AbstractRuleController, List<IAlgebraicRewriteRule>>> 
physicalRewrites)
-            throws AlgebricksException {
+                    throws AlgebricksException {
         if (AlgebricksConfig.DEBUG) {
             AlgebricksConfig.ALGEBRICKS_LOGGER.fine("Starting physical 
optimizations.\n");
         }
diff --git 
a/algebricks/algebricks-rewriter/src/main/java/org/apache/hyracks/algebricks/rewriter/rules/AbstractIntroduceGroupByCombinerRule.java
 
b/algebricks/algebricks-rewriter/src/main/java/org/apache/hyracks/algebricks/rewriter/rules/AbstractIntroduceGroupByCombinerRule.java
index 2d2619e..4d2fc30 100644
--- 
a/algebricks/algebricks-rewriter/src/main/java/org/apache/hyracks/algebricks/rewriter/rules/AbstractIntroduceGroupByCombinerRule.java
+++ 
b/algebricks/algebricks-rewriter/src/main/java/org/apache/hyracks/algebricks/rewriter/rules/AbstractIntroduceGroupByCombinerRule.java
@@ -48,6 +48,7 @@
 import 
org.apache.hyracks.algebricks.core.algebra.operators.logical.visitors.IsomorphismUtilities;
 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;
 import org.apache.hyracks.algebricks.core.algebra.util.OperatorPropertiesUtil;
 
 public abstract class AbstractIntroduceGroupByCombinerRule extends 
AbstractIntroduceCombinerRule {
@@ -135,10 +136,23 @@
         annotations.putAll(gbyOp.getAnnotations());
 
         List<LogicalVariable> gbyVars = gbyOp.getGbyVarList();
+
+        // Backup nested plans since tryToPushSubplan(...) may mutate them.
+        List<ILogicalPlan> copiedNestedPlans = new ArrayList<>();
+        for (ILogicalPlan nestedPlan : gbyOp.getNestedPlans()) {
+            ILogicalPlan copiedNestedPlan = 
OperatorManipulationUtil.deepCopy(nestedPlan, gbyOp);
+            OperatorManipulationUtil.computeTypeEnvironment(copiedNestedPlan, 
context);
+            copiedNestedPlans.add(copiedNestedPlan);
+        }
+
         for (ILogicalPlan p : gbyOp.getNestedPlans()) {
+            // NOTE: tryToPushSubplan(...) can mutate the nested subplan p.
             Pair<Boolean, ILogicalPlan> bip = tryToPushSubplan(p, gbyOp, 
newGbyOp, bi, gbyVars, context);
             if (!bip.first) {
                 // For now, if we cannot push everything, give up.
+                // Resets the group-by operator with backup nested plans.
+                gbyOp.getNestedPlans().clear();
+                gbyOp.getNestedPlans().addAll(copiedNestedPlans);
                 return null;
             }
             ILogicalPlan pushedSubplan = bip.second;

-- 
To view, visit https://asterix-gerrit.ics.uci.edu/751
To unsubscribe, visit https://asterix-gerrit.ics.uci.edu/settings

Gerrit-MessageType: newchange
Gerrit-Change-Id: I9602681a698925bde4eca33d85df66d06b9a33dd
Gerrit-PatchSet: 1
Gerrit-Project: hyracks
Gerrit-Branch: master
Gerrit-Owner: Yingyi Bu <buyin...@gmail.com>

Reply via email to