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/09/11 05:04:24 UTC

[3/3] asterixdb git commit: ASTERIXDB-1572 and ASTERIXDB-1591: fix and regression tests.

ASTERIXDB-1572 and ASTERIXDB-1591: fix and regression tests.

- push aggregates into subplans;
- fix recursive variable mapping in subquery decorrelation.

Change-Id: I7092dd2fa7c9193ff919b27464854936f48261b0
Reviewed-on: https://asterix-gerrit.ics.uci.edu/1161
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/834e1731
Tree: http://git-wip-us.apache.org/repos/asf/asterixdb/tree/834e1731
Diff: http://git-wip-us.apache.org/repos/asf/asterixdb/diff/834e1731

Branch: refs/heads/master
Commit: 834e17314ae8ecb12fce43c59cc6f613f2dee124
Parents: b4a9a89
Author: Yingyi Bu <yi...@couchbase.com>
Authored: Fri Sep 9 20:25:49 2016 -0700
Committer: Yingyi Bu <bu...@gmail.com>
Committed: Sat Sep 10 22:03:21 2016 -0700

----------------------------------------------------------------------
 .../PushAggregateIntoNestedSubplanRule.java     | 362 +++++++++----------
 ...ineSubplanInputForNestedTupleSourceRule.java |  14 +-
 .../asterix-app/data/tpcds/catalog_sales.csv    |   8 +-
 asterixdb/asterix-app/data/tpcds/date_dim.csv   |   2 +-
 .../asterix-app/data/tpcds/store_sales.csv      |  16 +-
 .../queries/subquery/query-ASTERIXDB-1572.sqlpp |  41 +++
 .../queries/tpcds/query-ASTERIXDB-1591.sqlpp    | 306 ++++++++++++++++
 .../results/inverted-index-join/issue741.plan   |  43 +--
 .../results/query-ASTERIXDB-159-3.plan          |  50 ++-
 .../optimizerts/results/query-issue562.plan     |  78 ++--
 .../optimizerts/results/subquery/exists.plan    |  31 +-
 .../results/subquery/not_exists.plan            |  31 +-
 .../results/subquery/query-ASTERIXDB-1572.plan  |  78 ++++
 .../tpcds/query-ASTERIXDB-1581-correlated.plan  |  70 ++--
 .../results/tpcds/query-ASTERIXDB-1581.plan     |  26 +-
 .../results/tpcds/query-ASTERIXDB-1591.plan     | 151 ++++++++
 .../results/udfs/query-ASTERIXDB-1020.plan      |   2 +-
 .../results/udfs/query-ASTERIXDB-1308-1.plan    |  44 +--
 .../query-ASTERIXDB-1572.1.ddl.sqlpp            |  31 ++
 .../query-ASTERIXDB-1572.2.update.sqlpp         |  23 ++
 .../query-ASTERIXDB-1572.3.query.sqlpp          |  29 ++
 .../query-ASTERIXDB-1591.1.ddl.sqlpp            | 270 ++++++++++++++
 .../query-ASTERIXDB-1591.2.update.sqlpp         |  41 +++
 .../query-ASTERIXDB-1591.3.query.sqlpp          |  52 +++
 .../query-ASTERIXDB-1572.1.adm                  |   0
 .../query-ASTERIXDB-1591.1.adm                  |   1 +
 .../query-ASTERIXDB-1596.1.adm                  |   8 +-
 .../resources/runtimets/testsuite_sqlpp.xml     |  10 +
 .../algebra/util/OperatorManipulationUtil.java  |  10 +-
 .../RemoveUnusedAssignAndAggregateRule.java     |  24 +-
 .../rewriter/rules/SetExecutionModeRule.java    |  25 +-
 31 files changed, 1450 insertions(+), 427 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/asterixdb/blob/834e1731/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/PushAggregateIntoNestedSubplanRule.java
----------------------------------------------------------------------
diff --git a/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/PushAggregateIntoNestedSubplanRule.java b/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/PushAggregateIntoNestedSubplanRule.java
index b346417..aeb527d 100644
--- a/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/PushAggregateIntoNestedSubplanRule.java
+++ b/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/PushAggregateIntoNestedSubplanRule.java
@@ -19,6 +19,7 @@
 package org.apache.asterix.optimizer.rules;
 
 import java.util.ArrayList;
+import java.util.Collections;
 import java.util.HashMap;
 import java.util.HashSet;
 import java.util.List;
@@ -38,14 +39,13 @@ import org.apache.hyracks.algebricks.core.algebra.base.LogicalExpressionTag;
 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.expressions.AbstractFunctionCallExpression;
-import org.apache.hyracks.algebricks.core.algebra.expressions.AbstractLogicalExpression;
 import org.apache.hyracks.algebricks.core.algebra.expressions.AggregateFunctionCallExpression;
 import org.apache.hyracks.algebricks.core.algebra.expressions.VariableReferenceExpression;
 import org.apache.hyracks.algebricks.core.algebra.functions.FunctionIdentifier;
 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.operators.logical.AggregateOperator;
 import org.apache.hyracks.algebricks.core.algebra.operators.logical.AssignOperator;
-import org.apache.hyracks.algebricks.core.algebra.operators.logical.GroupByOperator;
 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.UnnestOperator;
@@ -57,37 +57,32 @@ import org.apache.hyracks.algebricks.core.rewriter.base.IAlgebraicRewriteRule;
 public class PushAggregateIntoNestedSubplanRule implements IAlgebraicRewriteRule {
 
     @Override
-    public boolean rewritePost(Mutable<ILogicalOperator> opRef, IOptimizationContext context) {
-        return false;
-    }
-
-    @Override
     public boolean rewritePre(Mutable<ILogicalOperator> opRef, IOptimizationContext context)
             throws AlgebricksException {
-        Map<LogicalVariable, Integer> gbyAggVars = new HashMap<LogicalVariable, Integer>();
-        Map<LogicalVariable, Integer> gbyAggVarToPlanIndex = new HashMap<LogicalVariable, Integer>();
-        Map<LogicalVariable, GroupByOperator> gbyWithAgg = new HashMap<LogicalVariable, GroupByOperator>();
-        Map<ILogicalExpression, ILogicalExpression> aggExprToVarExpr = new HashMap<ILogicalExpression, ILogicalExpression>();
+        Map<LogicalVariable, Integer> nspAggVars = new HashMap<>();
+        Map<LogicalVariable, Integer> nspAggVarToPlanIndex = new HashMap<>();
+        Map<LogicalVariable, AbstractOperatorWithNestedPlans> nspWithAgg = new HashMap<>();
+        Map<ILogicalExpression, ILogicalExpression> aggExprToVarExpr = new HashMap<>();
         // first collect vars. referring to listified sequences
-        boolean changed = collectVarsBottomUp(opRef, context, gbyAggVars, gbyWithAgg, gbyAggVarToPlanIndex,
+        boolean changed = collectVarsBottomUp(opRef, context, nspAggVars, nspWithAgg, nspAggVarToPlanIndex,
                 aggExprToVarExpr);
         if (changed) {
-            removeRedundantListifies(opRef, context, gbyAggVars, gbyWithAgg, gbyAggVarToPlanIndex);
+            removeRedundantListifies(nspAggVars, nspWithAgg, nspAggVarToPlanIndex);
         }
         return changed;
     }
 
-    private void removeRedundantListifies(Mutable<ILogicalOperator> opRef, IOptimizationContext context,
-            Map<LogicalVariable, Integer> gbyAggVars, Map<LogicalVariable, GroupByOperator> gbyWithAgg,
-            Map<LogicalVariable, Integer> gbyAggVarToPlanIndex) throws AlgebricksException {
-        List<Pair<GroupByOperator, Integer>> removeList = new ArrayList<>();
-        for (Map.Entry<LogicalVariable, Integer> aggVarEntry : gbyAggVars.entrySet()) {
+    private void removeRedundantListifies(Map<LogicalVariable, Integer> nspAggVars,
+            Map<LogicalVariable, AbstractOperatorWithNestedPlans> nspWithAgg,
+            Map<LogicalVariable, Integer> nspAggVarToPlanIndex) throws AlgebricksException {
+        List<Pair<AbstractOperatorWithNestedPlans, Integer>> removeList = new ArrayList<>();
+        for (Map.Entry<LogicalVariable, Integer> aggVarEntry : nspAggVars.entrySet()) {
             LogicalVariable aggVar = aggVarEntry.getKey();
             int occurs = aggVarEntry.getValue();
             if (occurs == 0) {
-                GroupByOperator gbyOp = gbyWithAgg.get(aggVar);
-                AggregateOperator aggOp = (AggregateOperator) gbyOp.getNestedPlans()
-                        .get(gbyAggVarToPlanIndex.get(aggVar)).getRoots().get(0).getValue();
+                AbstractOperatorWithNestedPlans nspOp = nspWithAgg.get(aggVar);
+                AggregateOperator aggOp = (AggregateOperator) nspOp.getNestedPlans()
+                        .get(nspAggVarToPlanIndex.get(aggVar)).getRoots().get(0).getValue();
                 int pos = aggOp.getVariables().indexOf(aggVar);
                 if (pos >= 0) {
                     aggOp.getVariables().remove(pos);
@@ -95,41 +90,42 @@ public class PushAggregateIntoNestedSubplanRule implements IAlgebraicRewriteRule
                     List<LogicalVariable> producedVarsAtAgg = new ArrayList<>();
                     VariableUtilities.getProducedVariablesInDescendantsAndSelf(aggOp, producedVarsAtAgg);
                     if (producedVarsAtAgg.isEmpty()) {
-                        removeList.add(new Pair<>(gbyOp, gbyAggVarToPlanIndex.get(aggVar)));
+                        removeList.add(new Pair<>(nspOp, nspAggVarToPlanIndex.get(aggVar)));
                     }
                 }
             }
         }
 
         // Collects subplans that is to be removed.
-        Map<GroupByOperator, List<ILogicalPlan>> gbyToSubplanListMap = new HashMap<>();
-        for (Pair<GroupByOperator, Integer> remove : removeList) {
-            GroupByOperator groupByOperator = remove.first;
+        Map<AbstractOperatorWithNestedPlans, List<ILogicalPlan>> nspToSubplanListMap = new HashMap<>();
+        for (Pair<AbstractOperatorWithNestedPlans, Integer> remove : removeList) {
+            AbstractOperatorWithNestedPlans groupByOperator = remove.first;
             ILogicalPlan subplan = remove.first.getNestedPlans().get(remove.second);
-            if(gbyToSubplanListMap.containsKey(groupByOperator)) {
-                List<ILogicalPlan> subplans =  gbyToSubplanListMap.get(groupByOperator);
+            if (nspToSubplanListMap.containsKey(groupByOperator)) {
+                List<ILogicalPlan> subplans = nspToSubplanListMap.get(groupByOperator);
                 subplans.add(subplan);
             } else {
                 List<ILogicalPlan> subplans = new ArrayList<>();
                 subplans.add(subplan);
-                gbyToSubplanListMap.put(groupByOperator, subplans);
+                nspToSubplanListMap.put(groupByOperator, subplans);
             }
         }
         // Removes subplans.
-        for(Map.Entry<GroupByOperator, List<ILogicalPlan>> entry: gbyToSubplanListMap.entrySet()){
+        for (Map.Entry<AbstractOperatorWithNestedPlans, List<ILogicalPlan>> entry : nspToSubplanListMap.entrySet()) {
             entry.getKey().getNestedPlans().removeAll(entry.getValue());
         }
     }
 
     private boolean collectVarsBottomUp(Mutable<ILogicalOperator> opRef, IOptimizationContext context,
-            Map<LogicalVariable, Integer> gbyListifyVarsCount, Map<LogicalVariable, GroupByOperator> gbyWithAgg,
-            Map<LogicalVariable, Integer> gbyAggVarToPlanIndex,
+            Map<LogicalVariable, Integer> nspListifyVarsCount,
+            Map<LogicalVariable, AbstractOperatorWithNestedPlans> nspWithAgg,
+            Map<LogicalVariable, Integer> nspAggVarToPlanIndex,
             Map<ILogicalExpression, ILogicalExpression> aggregateExprToVarExpr) throws AlgebricksException {
         AbstractLogicalOperator op1 = (AbstractLogicalOperator) opRef.getValue();
         context.addToDontApplySet(this, op1);
         boolean change = false;
         for (Mutable<ILogicalOperator> child : op1.getInputs()) {
-            if (collectVarsBottomUp(child, context, gbyListifyVarsCount, gbyWithAgg, gbyAggVarToPlanIndex,
+            if (collectVarsBottomUp(child, context, nspListifyVarsCount, nspWithAgg, nspAggVarToPlanIndex,
                     aggregateExprToVarExpr)) {
                 change = true;
             }
@@ -138,98 +134,108 @@ public class PushAggregateIntoNestedSubplanRule implements IAlgebraicRewriteRule
         VariableUtilities.getUsedVariables(op1, used);
         switch (op1.getOperatorTag()) {
             case ASSIGN:
-            case SELECT: {
+            case SELECT:
                 boolean found = false;
-                // Do some prefiltering: check if the Assign uses any gby vars.
+                // Do some prefiltering: check if the Assign uses any nsp vars.
                 for (LogicalVariable v : used) {
-                    if (gbyListifyVarsCount.get(v) != null) {
+                    if (nspListifyVarsCount.get(v) != null) {
                         found = true;
                         break;
                     }
                 }
-                if (found) {
-                    if (op1.getOperatorTag() == LogicalOperatorTag.ASSIGN) {
-                        AssignOperator assign = (AssignOperator) op1;
-                        for (Mutable<ILogicalExpression> exprRef : assign.getExpressions()) {
-                            Pair<Boolean, ILogicalExpression> p = extractAggFunctionsFromExpression(exprRef, gbyWithAgg,
-                                    aggregateExprToVarExpr, context);
-                            if (p.first) {
-                                change = true;
-                                exprRef.setValue(p.second);
-                            }
-                        }
-                    }
-                    if (op1.getOperatorTag() == LogicalOperatorTag.SELECT) {
-                        SelectOperator select = (SelectOperator) op1;
-                        Mutable<ILogicalExpression> exprRef = select.getCondition();
-                        Pair<Boolean, ILogicalExpression> p = extractAggFunctionsFromExpression(exprRef, gbyWithAgg,
+                if (!found) {
+                    break;
+                }
+                if (op1.getOperatorTag() == LogicalOperatorTag.ASSIGN) {
+                    AssignOperator assign = (AssignOperator) op1;
+                    for (Mutable<ILogicalExpression> exprRef : assign.getExpressions()) {
+                        Pair<Boolean, ILogicalExpression> p = extractAggFunctionsFromExpression(exprRef, nspWithAgg,
                                 aggregateExprToVarExpr, context);
                         if (p.first) {
                             change = true;
                             exprRef.setValue(p.second);
                         }
                     }
-                    used.clear();
-                    VariableUtilities.getUsedVariables(op1, used);
-                    // increment the count for the ones which are still used
-                    for (LogicalVariable v : used) {
-                        Integer m = gbyListifyVarsCount.get(v);
-                        if (m != null) {
-                            gbyListifyVarsCount.put(v, m + 1);
-                        }
+                }
+                if (op1.getOperatorTag() == LogicalOperatorTag.SELECT) {
+                    SelectOperator select = (SelectOperator) op1;
+                    Mutable<ILogicalExpression> exprRef = select.getCondition();
+                    Pair<Boolean, ILogicalExpression> p = extractAggFunctionsFromExpression(exprRef, nspWithAgg,
+                            aggregateExprToVarExpr, context);
+                    if (p.first) {
+                        change = true;
+                        exprRef.setValue(p.second);
+                    }
+                }
+                used.clear();
+                VariableUtilities.getUsedVariables(op1, used);
+                // increment the count for the ones which are still used
+                for (LogicalVariable v : used) {
+                    Integer m = nspListifyVarsCount.get(v);
+                    if (m != null) {
+                        nspListifyVarsCount.put(v, m + 1);
                     }
                 }
                 break;
-            }
-            case SUBPLAN: {
+            case SUBPLAN:
+                // Try to push the subplan into a group-by operator if possible.
                 for (LogicalVariable v : used) {
-                    Integer m = gbyListifyVarsCount.get(v);
+                    Integer m = nspListifyVarsCount.get(v);
                     if (m != null) {
-                        GroupByOperator gbyOp = gbyWithAgg.get(v);
-                        if (pushSubplanAsAggIntoGby(opRef, gbyOp, v, gbyListifyVarsCount, gbyWithAgg,
-                                gbyAggVarToPlanIndex, context)) {
+                        AbstractOperatorWithNestedPlans nspOp = nspWithAgg.get(v);
+                        if (pushSubplanAsAggIntoNestedSubplan(opRef, nspOp, v, nspListifyVarsCount, nspWithAgg,
+                                nspAggVarToPlanIndex, context)) {
                             change = true;
                         } else {
-                            gbyListifyVarsCount.put(v, m + 1);
+                            nspListifyVarsCount.put(v, m + 1);
                         }
                     }
                 }
-                break;
-            }
-            case GROUP: {
-                List<LogicalVariable> vars = collectOneVarPerAggFromGroupOp((GroupByOperator) op1);
-                if (vars != null) {
-                    for (int i = 0; i < vars.size(); i++) {
-                        LogicalVariable v = vars.get(i);
-                        if (v != null) {
-                            gbyListifyVarsCount.put(v, 0);
-                            gbyAggVarToPlanIndex.put(v, i);
-                            gbyWithAgg.put(v, (GroupByOperator) op1);
-                        }
-                    }
+                if (!change) {
+                    // Collect aggregate variables for pushing aggregates into the subplan (if possible).
+                    collectAggregateVars(nspListifyVarsCount, nspWithAgg, nspAggVarToPlanIndex,
+                            (AbstractOperatorWithNestedPlans) op1);
                 }
                 break;
-            }
-            default: {
+            case GROUP:
+                // Collect aggregate variables for pushing aggregates into the nested subplan
+                // of the group by operator (if possible).
+                collectAggregateVars(nspListifyVarsCount, nspWithAgg, nspAggVarToPlanIndex,
+                        (AbstractOperatorWithNestedPlans) op1);
+                break;
+            default:
                 for (LogicalVariable v : used) {
-                    Integer m = gbyListifyVarsCount.get(v);
+                    Integer m = nspListifyVarsCount.get(v);
                     if (m != null) {
-                        gbyListifyVarsCount.put(v, m + 1);
+                        nspListifyVarsCount.put(v, m + 1);
                     }
                 }
-            }
         }
         return change;
     }
 
-    private List<LogicalVariable> collectOneVarPerAggFromGroupOp(GroupByOperator group) {
-        List<ILogicalPlan> nPlans = group.getNestedPlans();
-        if (nPlans == null || nPlans.size() < 1) {
-            return null;
+    private void collectAggregateVars(Map<LogicalVariable, Integer> nspListifyVarsCount,
+            Map<LogicalVariable, AbstractOperatorWithNestedPlans> nspWithAgg,
+            Map<LogicalVariable, Integer> nspAggVarToPlanIndex, AbstractOperatorWithNestedPlans op) {
+        List<LogicalVariable> vars = collectOneVarPerAggFromOpWithNestedPlans(op);
+        for (int i = 0; i < vars.size(); i++) {
+            LogicalVariable v = vars.get(i);
+            if (v != null) {
+                nspListifyVarsCount.put(v, 0);
+                nspAggVarToPlanIndex.put(v, i);
+                nspWithAgg.put(v, op);
+            }
+        }
+    }
+
+    private List<LogicalVariable> collectOneVarPerAggFromOpWithNestedPlans(AbstractOperatorWithNestedPlans op) {
+        List<ILogicalPlan> nPlans = op.getNestedPlans();
+        if (nPlans == null || nPlans.isEmpty()) {
+            return Collections.emptyList();
         }
 
-        List<LogicalVariable> aggVars = new ArrayList<LogicalVariable>();
-        // test that the group-by computes a "listify" aggregate
+        List<LogicalVariable> aggVars = new ArrayList<>();
+        // test that the operator computes a "listify" aggregate
         for (int i = 0; i < nPlans.size(); i++) {
             AbstractLogicalOperator topOp = (AbstractLogicalOperator) nPlans.get(i).getRoots().get(0).getValue();
             if (topOp.getOperatorTag() != LogicalOperatorTag.AGGREGATE) {
@@ -240,7 +246,7 @@ public class PushAggregateIntoNestedSubplanRule implements IAlgebraicRewriteRule
                 continue;
             }
             ILogicalExpression expr = agg.getExpressions().get(0).getValue();
-            if (((AbstractLogicalExpression) expr).getExpressionTag() != LogicalExpressionTag.FUNCTION_CALL) {
+            if (expr.getExpressionTag() != LogicalExpressionTag.FUNCTION_CALL) {
                 continue;
             }
             AbstractFunctionCallExpression fceAgg = (AbstractFunctionCallExpression) expr;
@@ -253,9 +259,8 @@ public class PushAggregateIntoNestedSubplanRule implements IAlgebraicRewriteRule
     }
 
     /**
-     * @param expr
-     * @param aggVars
-     * @param gbyWithAgg
+     * @param exprRef
+     * @param nspWithAgg
      * @param context
      * @return a pair whose first member is a boolean which is true iff
      *         something was changed in the expression tree rooted at expr. The
@@ -263,32 +268,32 @@ public class PushAggregateIntoNestedSubplanRule implements IAlgebraicRewriteRule
      * @throws AlgebricksException
      */
     private Pair<Boolean, ILogicalExpression> extractAggFunctionsFromExpression(Mutable<ILogicalExpression> exprRef,
-            Map<LogicalVariable, GroupByOperator> gbyWithAgg,
+            Map<LogicalVariable, AbstractOperatorWithNestedPlans> nspWithAgg,
             Map<ILogicalExpression, ILogicalExpression> aggregateExprToVarExpr, IOptimizationContext context)
-                    throws AlgebricksException {
+            throws AlgebricksException {
         ILogicalExpression expr = exprRef.getValue();
         switch (expr.getExpressionTag()) {
-            case FUNCTION_CALL: {
+            case FUNCTION_CALL:
                 AbstractFunctionCallExpression fce = (AbstractFunctionCallExpression) expr;
                 FunctionIdentifier fi = AsterixBuiltinFunctions.getAggregateFunction(fce.getFunctionIdentifier());
                 if (fi != null) {
                     ILogicalExpression a1 = fce.getArguments().get(0).getValue();
                     if (a1.getExpressionTag() == LogicalExpressionTag.VARIABLE) {
                         LogicalVariable argVar = ((VariableReferenceExpression) a1).getVariableReference();
-                        GroupByOperator gbyOp = gbyWithAgg.get(argVar);
+                        AbstractOperatorWithNestedPlans nspOp = nspWithAgg.get(argVar);
 
-                        if (gbyOp != null) {
+                        if (nspOp != null) {
                             if (!aggregateExprToVarExpr.containsKey(expr)) {
                                 LogicalVariable newVar = context.newVar();
                                 AggregateFunctionCallExpression aggFun = AsterixBuiltinFunctions
                                         .makeAggregateFunctionExpression(fi, fce.getArguments());
-                                rewriteGroupByAggregate(argVar, gbyOp, aggFun, newVar, context);
+                                rewriteAggregateInNestedSubplan(argVar, nspOp, aggFun, newVar, context);
                                 ILogicalExpression newVarExpr = new VariableReferenceExpression(newVar);
                                 aggregateExprToVarExpr.put(expr, newVarExpr);
-                                return new Pair<Boolean, ILogicalExpression>(Boolean.TRUE, newVarExpr);
+                                return new Pair<>(Boolean.TRUE, newVarExpr);
                             } else {
                                 ILogicalExpression varExpr = aggregateExprToVarExpr.get(expr);
-                                return new Pair<Boolean, ILogicalExpression>(Boolean.TRUE, varExpr);
+                                return new Pair<>(Boolean.TRUE, varExpr);
                             }
                         }
                     }
@@ -296,44 +301,41 @@ public class PushAggregateIntoNestedSubplanRule implements IAlgebraicRewriteRule
 
                 boolean change = false;
                 for (Mutable<ILogicalExpression> a : fce.getArguments()) {
-                    Pair<Boolean, ILogicalExpression> aggArg = extractAggFunctionsFromExpression(a, gbyWithAgg,
+                    Pair<Boolean, ILogicalExpression> aggArg = extractAggFunctionsFromExpression(a, nspWithAgg,
                             aggregateExprToVarExpr, context);
                     if (aggArg.first.booleanValue()) {
                         a.setValue(aggArg.second);
                         change = true;
                     }
                 }
-                return new Pair<Boolean, ILogicalExpression>(change, fce);
-            }
+                return new Pair<>(change, fce);
             case VARIABLE:
-            case CONSTANT: {
-                return new Pair<Boolean, ILogicalExpression>(Boolean.FALSE, expr);
-            }
-            default: {
+            case CONSTANT:
+                return new Pair<>(Boolean.FALSE, expr);
+            default:
                 throw new IllegalArgumentException();
-            }
         }
     }
 
-    private void rewriteGroupByAggregate(LogicalVariable oldAggVar, GroupByOperator gbyOp,
+    private void rewriteAggregateInNestedSubplan(LogicalVariable oldAggVar, AbstractOperatorWithNestedPlans nspOp,
             AggregateFunctionCallExpression aggFun, LogicalVariable newAggVar, IOptimizationContext context)
-                    throws AlgebricksException {
-        for (int j = 0; j < gbyOp.getNestedPlans().size(); j++) {
-            AggregateOperator aggOp = (AggregateOperator) gbyOp.getNestedPlans().get(j).getRoots().get(0).getValue();
+            throws AlgebricksException {
+        for (int j = 0; j < nspOp.getNestedPlans().size(); j++) {
+            AggregateOperator aggOp = (AggregateOperator) nspOp.getNestedPlans().get(j).getRoots().get(0).getValue();
             int n = aggOp.getVariables().size();
             for (int i = 0; i < n; i++) {
                 LogicalVariable v = aggOp.getVariables().get(i);
                 if (v.equals(oldAggVar)) {
                     AbstractFunctionCallExpression oldAggExpr = (AbstractFunctionCallExpression) aggOp.getExpressions()
                             .get(i).getValue();
-                    AggregateFunctionCallExpression newAggFun = AsterixBuiltinFunctions.makeAggregateFunctionExpression(
-                            aggFun.getFunctionIdentifier(), new ArrayList<Mutable<ILogicalExpression>>());
+                    AggregateFunctionCallExpression newAggFun = AsterixBuiltinFunctions
+                            .makeAggregateFunctionExpression(aggFun.getFunctionIdentifier(), new ArrayList<>());
                     for (Mutable<ILogicalExpression> arg : oldAggExpr.getArguments()) {
-                        ILogicalExpression cloned = ((AbstractLogicalExpression) arg.getValue()).cloneExpression();
-                        newAggFun.getArguments().add(new MutableObject<ILogicalExpression>(cloned));
+                        ILogicalExpression cloned = arg.getValue().cloneExpression();
+                        newAggFun.getArguments().add(new MutableObject<>(cloned));
                     }
                     aggOp.getVariables().add(newAggVar);
-                    aggOp.getExpressions().add(new MutableObject<ILogicalExpression>(newAggFun));
+                    aggOp.getExpressions().add(new MutableObject<>(newAggFun));
                     context.computeAndSetTypeEnvironmentForOperator(aggOp);
                     break;
                 }
@@ -341,16 +343,17 @@ public class PushAggregateIntoNestedSubplanRule implements IAlgebraicRewriteRule
         }
     }
 
-    private boolean pushSubplanAsAggIntoGby(Mutable<ILogicalOperator> subplanOpRef, GroupByOperator gbyOp,
-            LogicalVariable varFromGroupAgg, Map<LogicalVariable, Integer> gbyAggVars,
-            Map<LogicalVariable, GroupByOperator> gbyWithAgg, Map<LogicalVariable, Integer> gbyAggVarToPlanIndex,
-            IOptimizationContext context) throws AlgebricksException {
+    private boolean pushSubplanAsAggIntoNestedSubplan(Mutable<ILogicalOperator> subplanOpRef,
+            AbstractOperatorWithNestedPlans nspOp, LogicalVariable varFromNestedAgg,
+            Map<LogicalVariable, Integer> nspAggVars, Map<LogicalVariable, AbstractOperatorWithNestedPlans> nspWithAgg,
+            Map<LogicalVariable, Integer> nspAggVarToPlanIndex, IOptimizationContext context)
+            throws AlgebricksException {
         SubplanOperator subplan = (SubplanOperator) subplanOpRef.getValue();
-        // only free var can be varFromGroupAgg
-        HashSet<LogicalVariable> freeVars = new HashSet<LogicalVariable>();
+        // only free var can be varFromNestedAgg
+        HashSet<LogicalVariable> freeVars = new HashSet<>();
         OperatorPropertiesUtil.getFreeVariablesInSubplans(subplan, freeVars);
         for (LogicalVariable vFree : freeVars) {
-            if (!vFree.equals(varFromGroupAgg)) {
+            if (!vFree.equals(varFromNestedAgg)) {
                 return false;
             }
         }
@@ -375,10 +378,9 @@ public class PushAggregateIntoNestedSubplanRule implements IAlgebraicRewriteRule
             opRef = op.getInputs().get(0);
             op = (AbstractLogicalOperator) opRef.getValue();
             switch (op.getOperatorTag()) {
-                case ASSIGN: {
+                case ASSIGN:
                     break;
-                }
-                case UNNEST: {
+                case UNNEST:
                     UnnestOperator unnest = (UnnestOperator) op;
                     if (unnest.getPositionalVariable() != null) {
                         // TODO currently subplan with both accumulating and running aggregate is not supported.
@@ -397,7 +399,7 @@ public class PushAggregateIntoNestedSubplanRule implements IAlgebraicRewriteRule
                         return false;
                     }
                     VariableReferenceExpression varExpr = (VariableReferenceExpression) arg0;
-                    if (!varExpr.getVariableReference().equals(varFromGroupAgg)) {
+                    if (!varExpr.getVariableReference().equals(varFromNestedAgg)) {
                         return false;
                     }
                     opRef = op.getInputs().get(0);
@@ -408,73 +410,71 @@ public class PushAggregateIntoNestedSubplanRule implements IAlgebraicRewriteRule
                     pushableNestedSubplan = true;
                     unnestVar = unnest.getVariable();
                     break;
-                }
-                default: {
+                default:
                     return false;
-                }
             }
         }
-        if (pushableNestedSubplan) {
-            for (int i = 0; i < gbyOp.getNestedPlans().size(); i++) {
-                Mutable<ILogicalOperator> gbyAggRef = gbyOp.getNestedPlans().get(i).getRoots().get(0);
-                AggregateOperator gbyAgg = (AggregateOperator) gbyAggRef.getValue();
-                Mutable<ILogicalOperator> gbyAggChildRef = gbyAgg.getInputs().get(0);
-                LogicalVariable listifyVar = findListifiedVariable(gbyAgg, varFromGroupAgg);
-                if (listifyVar == null) {
+        if (!pushableNestedSubplan) {
+            return false;
+        }
+
+        for (int i = 0; i < nspOp.getNestedPlans().size(); i++) {
+            Mutable<ILogicalOperator> nspAggRef = nspOp.getNestedPlans().get(i).getRoots().get(0);
+            AggregateOperator nspAgg = (AggregateOperator) nspAggRef.getValue();
+            Mutable<ILogicalOperator> nspAggChildRef = nspAgg.getInputs().get(0);
+            LogicalVariable listifyVar = findListifiedVariable(nspAgg, varFromNestedAgg);
+            if (listifyVar == null) {
                     continue;
-                }
-                OperatorManipulationUtil.substituteVarRec(aggInSubplanOp, unnestVar, listifyVar, true, context);
-                gbyAgg.getVariables().addAll(aggInSubplanOp.getVariables());
-                gbyAgg.getExpressions().addAll(aggInSubplanOp.getExpressions());
-                for (LogicalVariable v : aggInSubplanOp.getVariables()) {
-                    gbyWithAgg.put(v, gbyOp);
-                    gbyAggVars.put(v, 0);
-                    gbyAggVarToPlanIndex.put(v, i);
-                }
+            }
+            OperatorManipulationUtil.substituteVarRec(aggInSubplanOp, unnestVar, listifyVar, true, context);
+            nspAgg.getVariables().addAll(aggInSubplanOp.getVariables());
+            nspAgg.getExpressions().addAll(aggInSubplanOp.getExpressions());
+            for (LogicalVariable v : aggInSubplanOp.getVariables()) {
+                nspWithAgg.put(v, nspOp);
+                nspAggVars.put(v, 0);
+                nspAggVarToPlanIndex.put(v, i);
+            }
 
-                Mutable<ILogicalOperator> opRef1InSubplan = aggInSubplanOp.getInputs().get(0);
-                if (opRef1InSubplan.getValue().getInputs().size() > 0) {
-                    Mutable<ILogicalOperator> opRef2InSubplan = opRef1InSubplan.getValue().getInputs().get(0);
-                    AbstractLogicalOperator op2InSubplan = (AbstractLogicalOperator) opRef2InSubplan.getValue();
-                    if (op2InSubplan.getOperatorTag() != LogicalOperatorTag.NESTEDTUPLESOURCE) {
-                        List<Mutable<ILogicalOperator>> gbyInpList = gbyAgg.getInputs();
-                        gbyInpList.clear();
-                        gbyInpList.add(opRef1InSubplan);
-                        while (true) {
-                            opRef2InSubplan = opRef1InSubplan.getValue().getInputs().get(0);
-                            op2InSubplan = (AbstractLogicalOperator) opRef2InSubplan.getValue();
-                            if (op2InSubplan.getOperatorTag() == LogicalOperatorTag.UNNEST) {
-                                List<Mutable<ILogicalOperator>> opInpList = opRef1InSubplan.getValue().getInputs();
-                                opInpList.clear();
-                                opInpList.add(gbyAggChildRef);
-                                break;
-                            }
-                            opRef1InSubplan = opRef2InSubplan;
-                            if (opRef1InSubplan.getValue().getInputs().size() == 0) {
-                                throw new IllegalStateException("PushAggregateIntoNestedSubplanRule: could not find UNNEST.");
-                            }
+            Mutable<ILogicalOperator> opRef1InSubplan = aggInSubplanOp.getInputs().get(0);
+            if (!opRef1InSubplan.getValue().getInputs().isEmpty()) {
+                Mutable<ILogicalOperator> opRef2InSubplan = opRef1InSubplan.getValue().getInputs().get(0);
+                AbstractLogicalOperator op2InSubplan = (AbstractLogicalOperator) opRef2InSubplan.getValue();
+                if (op2InSubplan.getOperatorTag() != LogicalOperatorTag.NESTEDTUPLESOURCE) {
+                    List<Mutable<ILogicalOperator>> nspInpList = nspAgg.getInputs();
+                    nspInpList.clear();
+                    nspInpList.add(opRef1InSubplan);
+                    while (true) {
+                        opRef2InSubplan = opRef1InSubplan.getValue().getInputs().get(0);
+                        op2InSubplan = (AbstractLogicalOperator) opRef2InSubplan.getValue();
+                        if (op2InSubplan.getOperatorTag() == LogicalOperatorTag.UNNEST) {
+                            List<Mutable<ILogicalOperator>> opInpList = opRef1InSubplan.getValue().getInputs();
+                            opInpList.clear();
+                            opInpList.add(nspAggChildRef);
+                            break;
+                        }
+                        opRef1InSubplan = opRef2InSubplan;
+                        if (opRef1InSubplan.getValue().getInputs().isEmpty()) {
+                            throw new IllegalStateException(
+                                        "PushAggregateIntoNestedSubplanRule: could not find UNNEST.");
                         }
                     }
                 }
-                subplanOpRef.setValue(subplan.getInputs().get(0).getValue());
-                OperatorPropertiesUtil.typeOpRec(gbyAggRef, context);
             }
-            return true;
-        } else {
-            return false;
+            subplanOpRef.setValue(subplan.getInputs().get(0).getValue());
+            OperatorPropertiesUtil.typeOpRec(nspAggRef, context);
         }
+        return true;
     }
 
-    private LogicalVariable findListifiedVariable(AggregateOperator gbyAgg, LogicalVariable varFromGroupAgg) {
-        int n = gbyAgg.getVariables().size();
-
+    private LogicalVariable findListifiedVariable(AggregateOperator nspAgg, LogicalVariable varFromNestedAgg) {
+        int n = nspAgg.getVariables().size();
         for (int i = 0; i < n; i++) {
-            if (gbyAgg.getVariables().get(i).equals(varFromGroupAgg)) {
-                AbstractFunctionCallExpression fce = (AbstractFunctionCallExpression) gbyAgg.getExpressions().get(i)
+            if (nspAgg.getVariables().get(i).equals(varFromNestedAgg)) {
+                AbstractFunctionCallExpression fce = (AbstractFunctionCallExpression) nspAgg.getExpressions().get(i)
                         .getValue();
                 if (fce.getFunctionIdentifier().equals(AsterixBuiltinFunctions.LISTIFY)) {
                     ILogicalExpression argExpr = fce.getArguments().get(0).getValue();
-                    if (((AbstractLogicalExpression) argExpr).getExpressionTag() == LogicalExpressionTag.VARIABLE) {
+                    if (argExpr.getExpressionTag() == LogicalExpressionTag.VARIABLE) {
                         return ((VariableReferenceExpression) argExpr).getVariableReference();
                     }
                 }

http://git-wip-us.apache.org/repos/asf/asterixdb/blob/834e1731/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 2e368c0..9f28515 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
@@ -325,9 +325,17 @@ public class InlineSubplanInputForNestedTupleSourceRule implements IAlgebraicRew
                     context);
             changed = changed || resultFromChild.first;
             for (Map.Entry<LogicalVariable, LogicalVariable> entry : resultFromChild.second.entrySet()) {
-                if (liveVars.contains(entry.getKey())) {
-                    // Only needs to map live variables for its ancestors.
-                    replacedVarMapForAncestor.put(entry.getKey(), entry.getValue());
+                LogicalVariable oldVar = entry.getKey();
+                LogicalVariable newVar = entry.getValue();
+                if (liveVars.contains(oldVar)) {
+                    // Maps live variables for its ancestors.
+                    replacedVarMapForAncestor.put(oldVar, newVar);
+                    // Recursively maps live variables for its ancestors.
+                    oldVar = newVar;
+                    while ((newVar = resultFromChild.second.get(newVar)) != null) {
+                        replacedVarMapForAncestor.put(oldVar, newVar);
+                        oldVar = newVar;
+                    }
                 }
             }
             replacedVarMap.putAll(resultFromChild.second);

http://git-wip-us.apache.org/repos/asf/asterixdb/blob/834e1731/asterixdb/asterix-app/data/tpcds/catalog_sales.csv
----------------------------------------------------------------------
diff --git a/asterixdb/asterix-app/data/tpcds/catalog_sales.csv b/asterixdb/asterix-app/data/tpcds/catalog_sales.csv
index 100f191..6ae0773 100644
--- a/asterixdb/asterix-app/data/tpcds/catalog_sales.csv
+++ b/asterixdb/asterix-app/data/tpcds/catalog_sales.csv
@@ -1,7 +1,7 @@
-2450815|38212|2450886|62153|1822764|5775|19986|62153|1822764|5775|19986|4|62|3|4|1|196|1|47|27.70|44.32|42.99|62.51|2020.53|1301.90|2083.04|101.02|0.00|1041.52|2020.53|2121.55|3062.05|3163.07|718.63|
-2450815|38212|2450846|62153|1822764|5775|19986|62153|1822764|5775|19986|4|31|8|2|2|270|1|20|87.55|260.89|153.92|2139.40|3078.40|1751.00|5217.80|71.41|1292.92|1356.60|1785.48|1856.89|3142.08|3213.49|34.48|
-2450815|38212|2450868|62153|1822764|5775|19986|62153|1822764|5775|19986|4|76|2|2|3|97|1|19|69.86|88.72|29.27|1129.55|556.13|1327.34|1685.68|33.36|0.00|168.53|556.13|589.49|724.66|758.02|-771.21|
-2450815|38212|2450851|62153|1822764|5775|19986|62153|1822764|5775|19986|4|89|15|2|2|284|2|50|70.00|205.10|188.69|820.50|9434.50|3500.00|10255.00|377.38|0.00|4307.00|9434.50|9811.88|13741.50|14118.88|5934.50|
+2450815|38212|2450886|1|1822764|5775|19986|1|1822764|5775|19986|4|62|3|4|1|196|1|47|27.70|44.32|42.99|62.51|2020.53|1301.90|2083.04|101.02|0.00|1041.52|2020.53|2121.55|3062.05|3163.07|718.63|
+2450815|38212|2450846|1|1822764|5775|19986|1|1822764|5775|19986|4|31|8|2|2|270|1|20|87.55|260.89|153.92|2139.40|3078.40|1751.00|5217.80|71.41|1292.92|1356.60|1785.48|1856.89|3142.08|3213.49|34.48|
+2450815|38212|2450868|1|1822764|5775|19986|1|1822764|5775|19986|4|76|2|2|3|97|1|19|69.86|88.72|29.27|1129.55|556.13|1327.34|1685.68|33.36|0.00|168.53|556.13|589.49|724.66|758.02|-771.21|
+2450815|38212|2450851|1|1822764|5775|19986|1|1822764|5775|19986|4|89|15|2|2|284|2|50|70.00|205.10|188.69|820.50|9434.50|3500.00|10255.00|377.38|0.00|4307.00|9434.50|9811.88|13741.50|14118.88|5934.50|
 2450815|29485|2450904|14601|797995|6189|9583|14601|797995|6189|9583|1|64|18|3|4|176|2|56|67.54|166.82|18.35|8314.32|1027.60|3782.24|9341.92|0.00|0.00|3736.32|1027.60|1027.60|4763.92|4763.92|-2754.64|
 2450815|29485|2450890|14601|797995|6189|9583|14601|797995|6189|9583|1|75|8|1|5|278|2|88|20.08|60.03|20.41|3486.56|1796.08|1767.04|5282.64|13.82|1598.51|1056.00|197.57|211.39|1253.57|1267.39|-1569.47|
 2450815|29485|2450849|14601|797995|6189|9583|14601|797995|6189|9583|1|39|4|3|6|207|2|31|40.88|51.91|6.22|1416.39|192.82|1267.28|1609.21|11.56|0.00|321.78|192.82|204.38|514.60|526.16|-1074.46|

http://git-wip-us.apache.org/repos/asf/asterixdb/blob/834e1731/asterixdb/asterix-app/data/tpcds/date_dim.csv
----------------------------------------------------------------------
diff --git a/asterixdb/asterix-app/data/tpcds/date_dim.csv b/asterixdb/asterix-app/data/tpcds/date_dim.csv
index 3aa8a8f..5300c68 100644
--- a/asterixdb/asterix-app/data/tpcds/date_dim.csv
+++ b/asterixdb/asterix-app/data/tpcds/date_dim.csv
@@ -1,4 +1,4 @@
-2415022|AAAAAAAAOKJNECAA|1900-01-02|0|1|1|1900|1|1|2|1|1900|1|1|Monday|1900Q1|N|N|Y|2415021|2415020|2414657|2414930|N|N|N|N|N|
+2450815|AAAAAAAAOKJNECAA|1900-01-02|0|1|1|1900|1|1|2|1|1900|1|1|Monday|1900Q1|N|N|Y|2415021|2415020|2414657|2414930|N|N|N|N|N|
 2415023|AAAAAAAAPKJNECAA|1900-01-03|0|1|1|1900|2|1|3|1|1900|1|1|Tuesday|1900Q1|N|N|N|2415021|2415020|2414658|2414931|N|N|N|N|N|
 2415024|AAAAAAAAALJNECAA|1900-01-04|0|1|1|1900|3|1|4|1|1900|1|1|Wednesday|1900Q1|N|N|N|2415021|2415020|2414659|2414932|N|N|N|N|N|
 2415025|AAAAAAAABLJNECAA|1900-01-05|0|1|1|1900|4|1|5|1|1900|1|1|Thursday|1900Q1|N|N|N|2415021|2415020|2414660|2414933|N|N|N|N|N|

http://git-wip-us.apache.org/repos/asf/asterixdb/blob/834e1731/asterixdb/asterix-app/data/tpcds/store_sales.csv
----------------------------------------------------------------------
diff --git a/asterixdb/asterix-app/data/tpcds/store_sales.csv b/asterixdb/asterix-app/data/tpcds/store_sales.csv
index 29a1f05..7d94449 100644
--- a/asterixdb/asterix-app/data/tpcds/store_sales.csv
+++ b/asterixdb/asterix-app/data/tpcds/store_sales.csv
@@ -1,11 +1,11 @@
-2451293|43503|1|1|518725|1359|31593|8|39|239999|20|61.65|61.65|16.64|0.00|332.80|1233.00|1233.00|0.00|0.00|332.80|332.80|-900.20|
-2451293|43503|3|1|518725|1359|31593|8|104|239999|98|55.42|110.84|70.93|0.00|6951.14|5431.16|10862.32|139.02|0.00|6951.14|7090.16|1519.98|
-2451293|43503|5|1|518725|1359|31593|8|294|239999|22|20.66|24.58|9.34|16.43|205.48|454.52|540.76|1.89|16.43|189.05|190.94|-265.47|
-2451293|43503|7|1|518725|1359|31593|8|137|239999|42|12.62|18.29|1.09|0.00|45.78|530.04|768.18|2.28|0.00|45.78|48.06|-484.26|
-2451293||9||518725|||||239999|76||23.04||0.00||1260.08|||0.00|297.16|303.10||
-2451293|43503|11|1|518725|1359|31593|8|256|239999|13|23.87|39.62|5.54|12.96|72.02|310.31|515.06|1.77|12.96|59.06|60.83|-251.25|
-2451293|43503|13|1|518725|1359|31593|8|128|239999|2|88.60|151.50|133.32|0.00|266.64|177.20|303.00|13.33|0.00|266.64|279.97|89.44|
-2451293|43503|15|1|518725|1359|31593|8|266|239999|13|60.52|95.62|13.38|0.00|173.94|786.76|1243.06|12.17|0.00|173.94|186.11|-612.82|
+2450815|43503|1|1|518725|1359|31593|8|39|239999|20|61.65|61.65|16.64|0.00|332.80|1233.00|1233.00|0.00|0.00|332.80|332.80|-900.20|
+2450815|43503|3|1|518725|1359|31593|8|104|239999|98|55.42|110.84|70.93|0.00|6951.14|5431.16|10862.32|139.02|0.00|6951.14|7090.16|1519.98|
+2450815|43503|5|1|518725|1359|31593|8|294|239999|22|20.66|24.58|9.34|16.43|205.48|454.52|540.76|1.89|16.43|189.05|190.94|-265.47|
+2450815|43503|7|1|518725|1359|31593|8|137|239999|42|12.62|18.29|1.09|0.00|45.78|530.04|768.18|2.28|0.00|45.78|48.06|-484.26|
+2450815||9||518725|||||239999|76||23.04||0.00||1260.08|||0.00|297.16|303.10||
+2450815|43503|11|1|518725|1359|31593|8|256|239999|13|23.87|39.62|5.54|12.96|72.02|310.31|515.06|1.77|12.96|59.06|60.83|-251.25|
+2450815|43503|13|1|518725|1359|31593|8|128|239999|2|88.60|151.50|133.32|0.00|266.64|177.20|303.00|13.33|0.00|266.64|279.97|89.44|
+2450815|43503|15|1|518725|1359|31593|8|266|239999|13|60.52|95.62|13.38|0.00|173.94|786.76|1243.06|12.17|0.00|173.94|186.11|-612.82|
 2451293|43503|17|1|518725|1359|31593|8|179|239999|45|93.14|95.00|4.75|0.00|213.75|4191.30|4275.00|19.23|0.00|213.75|232.98|-3977.55|
 2451176|47181|2|10|1873544|2153|1962|10|92|240000|30|67.43|84.96|37.38|583.12|1121.40|2022.90|2548.80|5.38|583.12|538.28|543.66|-1484.62|
 2451176|47181|4|10|1873544|2153|1962|10|143|240000|14|51.64|66.61|8.65|0.00|121.10|722.96|932.54|8.47|0.00|121.10|129.57|-601.86|

http://git-wip-us.apache.org/repos/asf/asterixdb/blob/834e1731/asterixdb/asterix-app/src/test/resources/optimizerts/queries/subquery/query-ASTERIXDB-1572.sqlpp
----------------------------------------------------------------------
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/queries/subquery/query-ASTERIXDB-1572.sqlpp b/asterixdb/asterix-app/src/test/resources/optimizerts/queries/subquery/query-ASTERIXDB-1572.sqlpp
new file mode 100644
index 0000000..1bafb45
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/queries/subquery/query-ASTERIXDB-1572.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 sampdb if exists;
+create dataverse sampdb;
+use sampdb;
+
+drop dataset samptable if exists;
+drop type samptabletype if exists;
+
+create type samptabletype as closed {
+  id: int64
+};
+
+create dataset samptable(samptabletype) primary key id;
+
+select *
+from
+(
+  select id from samptable
+  where (id in [0] and id in [1])
+        or (id in [1] and id in [2])
+) st1;
+
+drop dataverse sampdb;

http://git-wip-us.apache.org/repos/asf/asterixdb/blob/834e1731/asterixdb/asterix-app/src/test/resources/optimizerts/queries/tpcds/query-ASTERIXDB-1591.sqlpp
----------------------------------------------------------------------
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/queries/tpcds/query-ASTERIXDB-1591.sqlpp b/asterixdb/asterix-app/src/test/resources/optimizerts/queries/tpcds/query-ASTERIXDB-1591.sqlpp
new file mode 100644
index 0000000..42b9462
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/queries/tpcds/query-ASTERIXDB-1591.sqlpp
@@ -0,0 +1,306 @@
+/*
+ * 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 customer_address_type as closed {
+    ca_address_sk:              int64,
+    ca_address_id:              string,
+    ca_street_number:           string?,
+    ca_street_name:             string?,
+    ca_street_type:             string?,
+    ca_suite_number:            string?,
+    ca_city:                    string?,
+    ca_county:                  string?,
+    ca_state:                   string?,
+    ca_zip:                     string?,
+    ca_country:                 string?,
+    ca_gmt_offset:              double?,
+    ca_location_type:           string?
+}
+
+create type customer_type as closed {
+    c_customer_sk:             int64,
+    c_customer_id:             string,
+    c_current_cdemo_sk:        int64?,
+    c_current_hdemo_sk:        int64?,
+    c_current_addr_sk:         int64?,
+    c_first_shipto_date_sk:    int64?,
+    c_first_sales_date_sk:     int64?,
+    c_salutation:              string?,
+    c_first_name:              string?,
+    c_last_name:               string?,
+    c_preferred_cust_flag:     string?,
+    c_birth_day:               int64?,
+    c_birth_month:             int64?,
+    c_birth_year:              int64?,
+    c_birth_country:           string?,
+    c_login:                   string?,
+    c_email_address:           string?,
+    c_last_review_date:        string?
+}
+
+create type 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 catalog_sales_type as closed {
+    cs_sold_date_sk:           int64?,
+    cs_sold_time_sk:           int64?,
+    cs_ship_date_sk:           int64?,
+    cs_bill_customer_sk:       int64?,
+    cs_bill_cdemo_sk:          int64?,
+    cs_bill_hdemo_sk:          int64?,
+    cs_bill_addr_sk:           int64?,
+    cs_ship_customer_sk:       int64?,
+    cs_ship_cdemo_sk:          int64?,
+    cs_ship_hdemo_sk:          int64?,
+    cs_ship_addr_sk:           int64?,
+    cs_call_center_sk:         int64?,
+    cs_catalog_page_sk:        int64?,
+    cs_ship_mode_sk:           int64?,
+    cs_warehouse_sk:           int64?,
+    cs_item_sk:                int64,
+    cs_promo_sk:               int64?,
+    cs_order_number:           int64,
+    cs_quantity:               int64?,
+    cs_wholesale_cost:         double?,
+    cs_list_price:             double?,
+    cs_sales_price:            double?,
+    cs_ext_discount_amt:       double?,
+    cs_ext_sales_price:        double?,
+    cs_ext_wholesale_cost:     double?,
+    cs_ext_list_price:         double?,
+    cs_ext_tax:                double?,
+    cs_coupon_amt:             double?,
+    cs_ext_ship_cost:          double?,
+    cs_net_paid:               double?,
+    cs_net_paid_inc_tax:       double?,
+    cs_net_paid_inc_ship:      double?,
+    cs_net_paid_inc_ship_tax:  double?,
+    cs_net_profit:             double?
+}
+
+create type catalog_returns_type as closed {
+    cr_returned_date_sk:       int64?,
+    cr_returned_time_sk:       int64?,
+    cr_item_sk:                int64,
+    cr_refunded_customer_sk:   int64?,
+    cr_refunded_cdemo_sk:      int64?,
+    cr_refunded_hdemo_sk:      int64?,
+    cr_refunded_addr_sk:       int64?,
+    cr_returning_customer_sk:  int64?,
+    cr_returning_cdemo_sk:     int64?,
+    cr_returning_hdemo_sk:     int64?,
+    cr_returning_addr_sk:      int64?,
+    cr_call_center_sk:         int64?,
+    cr_catalog_page_sk:        int64?,
+    cr_ship_mode_sk:           int64?,
+    cr_warehouse_sk:           int64?,
+    cr_reason_sk:              int64?,
+    cr_order_number:           int64,
+    cr_return_quantity:        int64?,
+    cr_return_amount:          double?,
+    cr_return_tax:             double?,
+    cr_return_amt_inc_tax:     double?,
+    cr_fee:                    double?,
+    cr_return_ship_cost:       double?,
+    cr_refunded_cash:          double?,
+    cr_reversed_charge:        double?,
+    cr_store_credit:           double?,
+    cr_net_loss:               double?
+}
+
+create type tpcds.date_dim_type as closed {
+    d_date_sk:                 int64,
+    d_date_id:                 string,
+    d_date:                    string? ,
+    d_month_seq:               int64?,
+    d_week_seq:                int64?,
+    d_quarter_seq:             int64?,
+    d_year:                    int64?,
+    d_dow:                     int64?,
+    d_moy:                     int64?,
+    d_dom:                     int64?,
+    d_qoy:                     int64?,
+    d_fy_year:                 int64?,
+    d_fy_quarter_seq:          int64?,
+    d_fy_week_seq:             int64?,
+    d_day_name:                string?,
+    d_quarter_name:            string?,
+    d_holiday:                 string?,
+    d_weekend:                 string?,
+    d_following_holiday:       string?,
+    d_first_dom:               int64?,
+    d_last_dom:                int64?,
+    d_same_day_ly:             int64?,
+    d_same_day_lq:             int64?,
+    d_current_day:             string?,
+    d_current_week:            string?,
+    d_current_month:           string?,
+    d_current_quarter:         string?,
+    d_current_year:            string?
+}
+
+create type 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 type web_sales_type as closed {
+    ws_sold_date_sk:           int64?,
+    ws_sold_time_sk:           int64?,
+    ws_ship_date_sk:           int64?,
+    ws_item_sk:                int64,
+    ws_bill_customer_sk:       int64?,
+    ws_bill_cdemo_sk:          int64?,
+    ws_bill_hdemo_sk:          int64?,
+    ws_bill_addr_sk:           int64?,
+    ws_ship_customer_sk:       int64?,
+    ws_ship_cdemo_sk:          int64?,
+    ws_ship_hdemo_sk:          int64?,
+    ws_ship_addr_sk:           int64?,
+    ws_web_page_sk:            int64?,
+    ws_web_site_sk:            int64?,
+    ws_ship_mode_sk:           int64?,
+    ws_warehouse_sk:           int64?,
+    ws_promo_sk:               int64?,
+    ws_order_number:           int64,
+    ws_quantity:               int64?,
+    ws_wholesale_cost:         double?,
+    ws_list_price:             double?,
+    ws_sales_price:            double?,
+    ws_ext_discount_amt:       double?,
+    ws_ext_sales_price:        double?,
+    ws_ext_wholesale_cost:     double?,
+    ws_ext_list_price:         double?,
+    ws_ext_tax:                double?,
+    ws_coupon_amt:             double?,
+    ws_ext_ship_cost:          double?,
+    ws_net_paid:               double?,
+    ws_net_paid_inc_tax:       double?,
+    ws_net_paid_inc_ship:      double?,
+    ws_net_paid_inc_ship_tax:  double?,
+    ws_net_profit:             double?
+}
+
+create dataset customer (customer_type)
+primary key c_customer_sk;
+
+create dataset store_sales (store_sales_type)
+primary key ss_item_sk, ss_ticket_number;
+
+create dataset customer_address(customer_address_type)
+primary key ca_address_sk;
+
+create dataset catalog_sales (catalog_sales_type)
+primary key cs_item_sk, cs_order_number;
+
+create dataset catalog_returns (catalog_returns_type)
+primary key cr_item_sk, cr_order_number;
+
+create dataset item (item_type)
+primary key i_item_sk;
+
+create dataset date_dim(date_dim_type)
+primary key d_date_sk;
+
+create dataset web_sales (web_sales_type)
+primary key ws_item_sk, ws_order_number;
+
+select *
+from
+  customer c,customer_address ca
+where
+  c.c_current_addr_sk = ca.ca_address_sk and
+  exists (select *
+          from store_sales ss1,date_dim dd1
+          where c.c_customer_sk = ss1.ss_customer_sk and
+                ss1.ss_sold_date_sk = dd1.d_date_sk and
+                dd1.d_year = 1900 and
+                dd1.d_qoy < 4)
+                and
+                (
+                  exists (select *
+                          from web_sales ws1,date_dim dd1
+                          where c.c_customer_sk = ws1.ws_bill_customer_sk and
+                                ws1.ws_sold_date_sk = dd1.d_date_sk and
+                                dd1.d_year = 1900 and
+                                dd1.d_qoy < 4
+                         )
+                  or
+                  exists (select *
+                          from catalog_sales cs1,date_dim dd1
+                          where c.c_customer_sk = cs1.cs_ship_customer_sk and
+                                cs1.cs_sold_date_sk = dd1.d_date_sk and
+                                dd1.d_year = 1900 and
+                                dd1.d_qoy < 4
+                         )
+                 )
+order by c.c_customer_sk
+limit 100;
+
+drop dataverse tpcds;

http://git-wip-us.apache.org/repos/asf/asterixdb/blob/834e1731/asterixdb/asterix-app/src/test/resources/optimizerts/results/inverted-index-join/issue741.plan
----------------------------------------------------------------------
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/inverted-index-join/issue741.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/inverted-index-join/issue741.plan
index 5b08bf5..4e40dd2 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/inverted-index-join/issue741.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/inverted-index-join/issue741.plan
@@ -13,33 +13,20 @@
               -- STABLE_SORT [$$25(ASC)]  |PARTITIONED|
                 -- HASH_PARTITION_EXCHANGE [$$25]  |PARTITIONED|
                   -- STREAM_PROJECT  |PARTITIONED|
-                    -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                      -- HYBRID_HASH_JOIN [$$36][$$25]  |PARTITIONED|
+                    -- STREAM_SELECT  |PARTITIONED|
+                      -- STREAM_PROJECT  |PARTITIONED|
                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                          -- STREAM_PROJECT  |PARTITIONED|
-                            -- STREAM_SELECT  |PARTITIONED|
-                              -- STREAM_PROJECT  |PARTITIONED|
-                                -- ASSIGN  |PARTITIONED|
-                                  -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                    -- DATASOURCE_SCAN  |PARTITIONED|
-                                      -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                        -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
-                        -- HASH_PARTITION_EXCHANGE [$$25]  |PARTITIONED|
-                          -- STREAM_PROJECT  |PARTITIONED|
-                            -- STREAM_SELECT  |PARTITIONED|
-                              -- STREAM_PROJECT  |PARTITIONED|
+                          -- BTREE_SEARCH  |PARTITIONED|
+                            -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                              -- STABLE_SORT [$$39(ASC)]  |PARTITIONED|
                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                  -- BTREE_SEARCH  |PARTITIONED|
-                                    -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                      -- STABLE_SORT [$$39(ASC)]  |PARTITIONED|
-                                        -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                          -- LENGTH_PARTITIONED_INVERTED_INDEX_SEARCH  |PARTITIONED|
-                                            -- BROADCAST_EXCHANGE  |PARTITIONED|
-                                              -- STREAM_PROJECT  |PARTITIONED|
-                                                -- STREAM_SELECT  |PARTITIONED|
-                                                  -- STREAM_PROJECT  |PARTITIONED|
-                                                    -- ASSIGN  |PARTITIONED|
-                                                      -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                        -- DATASOURCE_SCAN  |PARTITIONED|
-                                                          -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                            -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                                  -- LENGTH_PARTITIONED_INVERTED_INDEX_SEARCH  |PARTITIONED|
+                                    -- BROADCAST_EXCHANGE  |PARTITIONED|
+                                      -- STREAM_PROJECT  |PARTITIONED|
+                                        -- STREAM_SELECT  |PARTITIONED|
+                                          -- STREAM_PROJECT  |PARTITIONED|
+                                            -- ASSIGN  |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/834e1731/asterixdb/asterix-app/src/test/resources/optimizerts/results/query-ASTERIXDB-159-3.plan
----------------------------------------------------------------------
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/query-ASTERIXDB-159-3.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/query-ASTERIXDB-159-3.plan
index 7699b8e..60de69a 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/query-ASTERIXDB-159-3.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/query-ASTERIXDB-159-3.plan
@@ -10,7 +10,7 @@
                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
                     -- STREAM_PROJECT  |PARTITIONED|
                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                        -- HYBRID_HASH_JOIN [$$29][$$37]  |PARTITIONED|
+                        -- HYBRID_HASH_JOIN [$$29][$$38]  |PARTITIONED|
                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
                             -- STREAM_PROJECT  |PARTITIONED|
                               -- ASSIGN  |PARTITIONED|
@@ -27,37 +27,35 @@
                                                     -- DATASOURCE_SCAN  |PARTITIONED|
                                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
                                                         -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
-                          -- HASH_PARTITION_EXCHANGE [$$37]  |PARTITIONED|
+                          -- HASH_PARTITION_EXCHANGE [$$38]  |PARTITIONED|
                             -- STREAM_PROJECT  |PARTITIONED|
                               -- STREAM_SELECT  |PARTITIONED|
-                                -- STREAM_PROJECT  |PARTITIONED|
-                                  -- ASSIGN  |PARTITIONED|
-                                    -- SUBPLAN  |PARTITIONED|
-                                            {
-                                              -- AGGREGATE  |LOCAL|
-                                                -- UNNEST  |LOCAL|
-                                                  -- NESTED_TUPLE_SOURCE  |LOCAL|
-                                            }
+                                -- SUBPLAN  |PARTITIONED|
+                                        {
+                                          -- AGGREGATE  |LOCAL|
+                                            -- UNNEST  |LOCAL|
+                                              -- NESTED_TUPLE_SOURCE  |LOCAL|
+                                        }
+                                  -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                    -- NESTED_LOOP  |PARTITIONED|
                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                        -- NESTED_LOOP  |PARTITIONED|
+                                        -- SPLIT  |PARTITIONED|
                                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                            -- SPLIT  |PARTITIONED|
-                                              -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                -- STREAM_PROJECT  |PARTITIONED|
-                                                  -- ASSIGN  |PARTITIONED|
+                                            -- STREAM_PROJECT  |PARTITIONED|
+                                              -- ASSIGN  |PARTITIONED|
+                                                -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                  -- SPLIT  |PARTITIONED|
                                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                      -- SPLIT  |PARTITIONED|
+                                                      -- STREAM_PROJECT  |PARTITIONED|
                                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                          -- STREAM_PROJECT  |PARTITIONED|
+                                                          -- DATASOURCE_SCAN  |PARTITIONED|
                                                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                              -- DATASOURCE_SCAN  |PARTITIONED|
-                                                                -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                                  -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
-                                          -- BROADCAST_EXCHANGE  |PARTITIONED|
-                                            -- SPLIT  |PARTITIONED|
+                                                              -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                                      -- BROADCAST_EXCHANGE  |PARTITIONED|
+                                        -- SPLIT  |PARTITIONED|
+                                          -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                            -- STREAM_PROJECT  |PARTITIONED|
                                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                -- STREAM_PROJECT  |PARTITIONED|
+                                                -- DATASOURCE_SCAN  |PARTITIONED|
                                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                    -- DATASOURCE_SCAN  |PARTITIONED|
-                                                      -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                        -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                                                    -- EMPTY_TUPLE_SOURCE  |PARTITIONED|

http://git-wip-us.apache.org/repos/asf/asterixdb/blob/834e1731/asterixdb/asterix-app/src/test/resources/optimizerts/results/query-issue562.plan
----------------------------------------------------------------------
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/query-issue562.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/query-issue562.plan
index 008339a..366d67c 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/query-issue562.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/query-issue562.plan
@@ -9,53 +9,57 @@
                       -- NESTED_TUPLE_SOURCE  |LOCAL|
                   }
             -- HASH_PARTITION_MERGE_EXCHANGE MERGE:[$$83(ASC)] HASH:[$$83]  |PARTITIONED|
-              -- SORT_GROUP_BY[$$11]  |PARTITIONED|
+              -- SORT_GROUP_BY[$$58]  |PARTITIONED|
                       {
                         -- AGGREGATE  |LOCAL|
                           -- NESTED_TUPLE_SOURCE  |LOCAL|
                       }
                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
                   -- STREAM_PROJECT  |PARTITIONED|
-                    -- STREAM_SELECT  |PARTITIONED|
+                    -- ASSIGN  |PARTITIONED|
                       -- STREAM_PROJECT  |PARTITIONED|
-                        -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                          -- PRE_CLUSTERED_GROUP_BY[$$80]  |PARTITIONED|
-                                  {
-                                    -- AGGREGATE  |LOCAL|
-                                      -- NESTED_TUPLE_SOURCE  |LOCAL|
-                                  }
-                            -- HASH_PARTITION_MERGE_EXCHANGE MERGE:[$$80(ASC)] HASH:[$$80]  |PARTITIONED|
-                              -- PRE_CLUSTERED_GROUP_BY[$$75]  |PARTITIONED|
+                        -- STREAM_SELECT  |PARTITIONED|
+                          -- STREAM_PROJECT  |PARTITIONED|
+                            -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                              -- PRE_CLUSTERED_GROUP_BY[$$80]  |PARTITIONED|
                                       {
                                         -- AGGREGATE  |LOCAL|
-                                          -- STREAM_SELECT  |LOCAL|
-                                            -- NESTED_TUPLE_SOURCE  |LOCAL|
+                                          -- NESTED_TUPLE_SOURCE  |LOCAL|
                                       }
-                                -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                  -- STABLE_SORT [$$75(ASC)]  |PARTITIONED|
+                                -- HASH_PARTITION_MERGE_EXCHANGE MERGE:[$$80(ASC)] HASH:[$$80]  |PARTITIONED|
+                                  -- PRE_CLUSTERED_GROUP_BY[$$76]  |PARTITIONED|
+                                          {
+                                            -- AGGREGATE  |LOCAL|
+                                              -- STREAM_SELECT  |LOCAL|
+                                                -- NESTED_TUPLE_SOURCE  |LOCAL|
+                                          }
                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                      -- STREAM_PROJECT  |PARTITIONED|
+                                      -- STABLE_SORT [$$76(ASC)]  |PARTITIONED|
                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                          -- HYBRID_HASH_JOIN [$$62][$$69]  |PARTITIONED|
-                                            -- HASH_PARTITION_EXCHANGE [$$62]  |PARTITIONED|
-                                              -- ASSIGN  |PARTITIONED|
-                                                -- STREAM_PROJECT  |PARTITIONED|
-                                                  -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                    -- HYBRID_HASH_JOIN [$$65][$$11]  |PARTITIONED|
-                                                      -- HASH_PARTITION_EXCHANGE [$$65]  |PARTITIONED|
-                                                        -- UNNEST  |UNPARTITIONED|
-                                                          -- EMPTY_TUPLE_SOURCE  |UNPARTITIONED|
-                                                      -- HASH_PARTITION_EXCHANGE [$$11]  |PARTITIONED|
-                                                        -- STREAM_PROJECT  |PARTITIONED|
-                                                          -- ASSIGN  |PARTITIONED|
-                                                            -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                              -- DATASOURCE_SCAN  |PARTITIONED|
-                                                                -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                                  -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
-                                            -- HASH_PARTITION_EXCHANGE [$$69]  |PARTITIONED|
-                                              -- ASSIGN  |PARTITIONED|
-                                                -- STREAM_PROJECT  |PARTITIONED|
-                                                  -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                    -- DATASOURCE_SCAN  |PARTITIONED|
+                                          -- STREAM_PROJECT  |PARTITIONED|
+                                            -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                              -- HYBRID_HASH_JOIN [$$62][$$70]  |PARTITIONED|
+                                                -- HASH_PARTITION_EXCHANGE [$$62]  |PARTITIONED|
+                                                  -- STREAM_PROJECT  |PARTITIONED|
+                                                    -- ASSIGN  |PARTITIONED|
+                                                      -- STREAM_PROJECT  |PARTITIONED|
+                                                        -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                          -- HYBRID_HASH_JOIN [$$65][$$11]  |PARTITIONED|
+                                                            -- HASH_PARTITION_EXCHANGE [$$65]  |PARTITIONED|
+                                                              -- UNNEST  |UNPARTITIONED|
+                                                                -- EMPTY_TUPLE_SOURCE  |UNPARTITIONED|
+                                                            -- HASH_PARTITION_EXCHANGE [$$11]  |PARTITIONED|
+                                                              -- ASSIGN  |PARTITIONED|
+                                                                -- STREAM_PROJECT  |PARTITIONED|
+                                                                  -- ASSIGN  |PARTITIONED|
+                                                                    -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                      -- DATASOURCE_SCAN  |PARTITIONED|
+                                                                        -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                          -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                                                -- HASH_PARTITION_EXCHANGE [$$70]  |PARTITIONED|
+                                                  -- ASSIGN  |PARTITIONED|
+                                                    -- STREAM_PROJECT  |PARTITIONED|
                                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                        -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                                                        -- DATASOURCE_SCAN  |PARTITIONED|
+                                                          -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                            -- EMPTY_TUPLE_SOURCE  |PARTITIONED|

http://git-wip-us.apache.org/repos/asf/asterixdb/blob/834e1731/asterixdb/asterix-app/src/test/resources/optimizerts/results/subquery/exists.plan
----------------------------------------------------------------------
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/subquery/exists.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/subquery/exists.plan
index 54716d3..fcb9d0d 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/subquery/exists.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/subquery/exists.plan
@@ -3,12 +3,12 @@
     -- STREAM_PROJECT  |PARTITIONED|
       -- ASSIGN  |PARTITIONED|
         -- SORT_MERGE_EXCHANGE [$$31(ASC) ]  |PARTITIONED|
-          -- PRE_CLUSTERED_GROUP_BY[$$104]  |PARTITIONED|
+          -- PRE_CLUSTERED_GROUP_BY[$$105]  |PARTITIONED|
                   {
                     -- AGGREGATE  |LOCAL|
                       -- NESTED_TUPLE_SOURCE  |LOCAL|
                   }
-            -- HASH_PARTITION_MERGE_EXCHANGE MERGE:[$$104(ASC)] HASH:[$$104]  |PARTITIONED|
+            -- HASH_PARTITION_MERGE_EXCHANGE MERGE:[$$105(ASC)] HASH:[$$105]  |PARTITIONED|
               -- SORT_GROUP_BY[$$81]  |PARTITIONED|
                       {
                         -- AGGREGATE  |LOCAL|
@@ -21,37 +21,38 @@
                         -- STREAM_SELECT  |PARTITIONED|
                           -- STREAM_PROJECT  |PARTITIONED|
                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                              -- PRE_CLUSTERED_GROUP_BY[$$101]  |PARTITIONED|
+                              -- PRE_CLUSTERED_GROUP_BY[$$102]  |PARTITIONED|
                                       {
                                         -- AGGREGATE  |LOCAL|
                                           -- NESTED_TUPLE_SOURCE  |LOCAL|
                                       }
-                                -- HASH_PARTITION_MERGE_EXCHANGE MERGE:[$$101(ASC)] HASH:[$$101]  |PARTITIONED|
-                                  -- PRE_CLUSTERED_GROUP_BY[$$94]  |PARTITIONED|
+                                -- HASH_PARTITION_MERGE_EXCHANGE MERGE:[$$102(ASC)] HASH:[$$102]  |PARTITIONED|
+                                  -- PRE_CLUSTERED_GROUP_BY[$$95]  |PARTITIONED|
                                           {
                                             -- AGGREGATE  |LOCAL|
                                               -- STREAM_SELECT  |LOCAL|
                                                 -- NESTED_TUPLE_SOURCE  |LOCAL|
                                           }
                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                      -- STABLE_SORT [$$94(ASC)]  |PARTITIONED|
+                                      -- STABLE_SORT [$$95(ASC)]  |PARTITIONED|
                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
                                           -- STREAM_PROJECT  |PARTITIONED|
                                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                              -- HYBRID_HASH_JOIN [$$89][$$86]  |PARTITIONED|
-                                                -- HASH_PARTITION_EXCHANGE [$$89]  |PARTITIONED|
+                                              -- HYBRID_HASH_JOIN [$$90][$$87]  |PARTITIONED|
+                                                -- HASH_PARTITION_EXCHANGE [$$90]  |PARTITIONED|
                                                   -- ASSIGN  |PARTITIONED|
                                                     -- STREAM_PROJECT  |PARTITIONED|
                                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
                                                         -- NESTED_LOOP  |PARTITIONED|
                                                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
                                                             -- ASSIGN  |PARTITIONED|
-                                                              -- STREAM_PROJECT  |PARTITIONED|
-                                                                -- ASSIGN  |PARTITIONED|
-                                                                  -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                                    -- DATASOURCE_SCAN  |PARTITIONED|
-                                                                      -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                                        -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                                                              -- ASSIGN  |PARTITIONED|
+                                                                -- STREAM_PROJECT  |PARTITIONED|
+                                                                  -- ASSIGN  |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|
@@ -66,7 +67,7 @@
                                                                                 -- DATASOURCE_SCAN  |PARTITIONED|
                                                                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
                                                                                     -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
-                                                -- HASH_PARTITION_EXCHANGE [$$86]  |PARTITIONED|
+                                                -- HASH_PARTITION_EXCHANGE [$$87]  |PARTITIONED|
                                                   -- ASSIGN  |PARTITIONED|
                                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
                                                       -- DATASOURCE_SCAN  |PARTITIONED|