You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@asterixdb.apache.org by bu...@apache.org on 2016/03/28 22:17:16 UTC

incubator-asterixdb-hyracks git commit: ASTERIXDB-1226: support SQL++ core group-by semantics.

Repository: incubator-asterixdb-hyracks
Updated Branches:
  refs/heads/master c92aea67c -> b2e9d0827


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

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

Change-Id: I9602681a698925bde4eca33d85df66d06b9a33dd
Reviewed-on: https://asterix-gerrit.ics.uci.edu/751
Tested-by: Jenkins <je...@fulliautomatix.ics.uci.edu>
Reviewed-by: Till Westmann <ti...@apache.org>


Project: http://git-wip-us.apache.org/repos/asf/incubator-asterixdb-hyracks/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-asterixdb-hyracks/commit/b2e9d082
Tree: http://git-wip-us.apache.org/repos/asf/incubator-asterixdb-hyracks/tree/b2e9d082
Diff: http://git-wip-us.apache.org/repos/asf/incubator-asterixdb-hyracks/diff/b2e9d082

Branch: refs/heads/master
Commit: b2e9d0827b2a075f31713f2b998ada1b68a400fc
Parents: c92aea6
Author: Yingyi Bu <yi...@couchbase.com>
Authored: Sat Mar 26 17:14:36 2016 -0700
Committer: Yingyi Bu <bu...@gmail.com>
Committed: Mon Mar 28 13:11:56 2016 -0700

----------------------------------------------------------------------
 .../AbstractFunctionCallExpression.java         | 12 -----
 .../logical/AbstractLogicalOperator.java        |  8 +++
 .../logical/NestedTupleSourceOperator.java      |  7 ++-
 ...pressionDeepCopyWithNewVariablesVisitor.java |  2 +
 ...OperatorDeepCopyWithNewVariablesVisitor.java |  8 +--
 .../visitors/OperatorDeepCopyVisitor.java       | 40 +++++++++------
 ...gatePropertiesForUsedVariablesPOperator.java | 14 +++---
 .../algebra/util/OperatorManipulationUtil.java  | 52 ++++++++++++++++----
 .../AbstractIntroduceGroupByCombinerRule.java   | 14 ++++++
 9 files changed, 110 insertions(+), 47 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-asterixdb-hyracks/blob/b2e9d082/algebricks/algebricks-core/src/main/java/org/apache/hyracks/algebricks/core/algebra/expressions/AbstractFunctionCallExpression.java
----------------------------------------------------------------------
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 @@ public abstract class AbstractFunctionCallExpression extends AbstractLogicalExpr
             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();
     }
 

http://git-wip-us.apache.org/repos/asf/incubator-asterixdb-hyracks/blob/b2e9d082/algebricks/algebricks-core/src/main/java/org/apache/hyracks/algebricks/core/algebra/operators/logical/AbstractLogicalOperator.java
----------------------------------------------------------------------
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 @@ public abstract class AbstractLogicalOperator implements ILogicalOperator {
         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;
     }

http://git-wip-us.apache.org/repos/asf/incubator-asterixdb-hyracks/blob/b2e9d082/algebricks/algebricks-core/src/main/java/org/apache/hyracks/algebricks/core/algebra/operators/logical/NestedTupleSourceOperator.java
----------------------------------------------------------------------
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 @@ public class NestedTupleSourceOperator extends AbstractLogicalOperator {
         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);
+            }
         }
     }
 

http://git-wip-us.apache.org/repos/asf/incubator-asterixdb-hyracks/blob/b2e9d082/algebricks/algebricks-core/src/main/java/org/apache/hyracks/algebricks/core/algebra/operators/logical/visitors/LogicalExpressionDeepCopyWithNewVariablesVisitor.java
----------------------------------------------------------------------
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 @@ public class LogicalExpressionDeepCopyWithNewVariablesVisitor
             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;

http://git-wip-us.apache.org/repos/asf/incubator-asterixdb-hyracks/blob/b2e9d082/algebricks/algebricks-core/src/main/java/org/apache/hyracks/algebricks/core/algebra/operators/logical/visitors/LogicalOperatorDeepCopyWithNewVariablesVisitor.java
----------------------------------------------------------------------
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 @@ public class LogicalOperatorDeepCopyWithNewVariablesVisitor
             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 @@ public class LogicalOperatorDeepCopyWithNewVariablesVisitor
             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;

http://git-wip-us.apache.org/repos/asf/incubator-asterixdb-hyracks/blob/b2e9d082/algebricks/algebricks-core/src/main/java/org/apache/hyracks/algebricks/core/algebra/operators/logical/visitors/OperatorDeepCopyVisitor.java
----------------------------------------------------------------------
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 @@ public class OperatorDeepCopyVisitor implements ILogicalOperatorVisitor<ILogical
         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)));
+        }
+        GroupByOperator gbyOp = new GroupByOperator(groupByList, decoList, newSubplans);
         for (ILogicalPlan plan : op.getNestedPlans()) {
-            newSubplans.add(OperatorManipulationUtil.deepCopy(plan));
+            newSubplans.add(OperatorManipulationUtil.deepCopy(plan, gbyOp));
         }
-        return new GroupByOperator(groupByList, decoList, newSubplans);
+        return gbyOp;
     }
 
     @Override
@@ -190,19 +193,21 @@ public class OperatorDeepCopyVisitor implements ILogicalOperatorVisitor<ILogical
     @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 @@ public class OperatorDeepCopyVisitor implements ILogicalOperatorVisitor<ILogical
 
     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;
     }
 

http://git-wip-us.apache.org/repos/asf/incubator-asterixdb-hyracks/blob/b2e9d082/algebricks/algebricks-core/src/main/java/org/apache/hyracks/algebricks/core/algebra/operators/physical/AbstractPropagatePropertiesForUsedVariablesPOperator.java
----------------------------------------------------------------------
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 @@ public abstract class AbstractPropagatePropertiesForUsedVariablesPOperator exten
         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);

http://git-wip-us.apache.org/repos/asf/incubator-asterixdb-hyracks/blob/b2e9d082/algebricks/algebricks-core/src/main/java/org/apache/hyracks/algebricks/core/algebra/util/OperatorManipulationUtil.java
----------------------------------------------------------------------
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..97aa853 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 class OperatorManipulationUtil {
         }
     }
 
-    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 {
@@ -191,6 +193,23 @@ public class OperatorManipulationUtil {
         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)
             throws AlgebricksException {
         List<Mutable<ILogicalOperator>> newRoots = new ArrayList<Mutable<ILogicalOperator>>();
@@ -225,15 +244,15 @@ public class OperatorManipulationUtil {
 
     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 @@ public class OperatorManipulationUtil {
         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>?
      *

http://git-wip-us.apache.org/repos/asf/incubator-asterixdb-hyracks/blob/b2e9d082/algebricks/algebricks-rewriter/src/main/java/org/apache/hyracks/algebricks/rewriter/rules/AbstractIntroduceGroupByCombinerRule.java
----------------------------------------------------------------------
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.NestedTupleS
 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 @@ public abstract class AbstractIntroduceGroupByCombinerRule extends AbstractIntro
         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;