ASTERIXDB-1005, ASTERIXDB-1263: Clean up subplan flattening:
1. Inline NestedTupleSource and remove SubplanOperator for special cases that
   join operators inside the SubplanOperator can be re-targeted for
   correlations;
2. Blindly inline NestedTupleSource and remove SubplanOperator for general cases
   where the condition of the special case is not met.

Change-Id: I4dd130a25f3c81272cc23f844ea20e376e990612
Reviewed-on: https://asterix-gerrit.ics.uci.edu/579
Tested-by: Jenkins <jenkins@fulliautomatix.ics.uci.edu>
Reviewed-by: Till Westmann <tillw@apache.org>
diff --git a/asterix-algebra/src/main/java/org/apache/asterix/optimizer/base/RuleCollections.java b/asterix-algebra/src/main/java/org/apache/asterix/optimizer/base/RuleCollections.java
index 260fb3c..4187059 100644
--- a/asterix-algebra/src/main/java/org/apache/asterix/optimizer/base/RuleCollections.java
+++ b/asterix-algebra/src/main/java/org/apache/asterix/optimizer/base/RuleCollections.java
@@ -118,8 +118,6 @@
 import org.apache.hyracks.algebricks.rewriter.rules.SimpleUnnestToProductRule;
 import org.apache.hyracks.algebricks.rewriter.rules.subplan.EliminateSubplanRule;
 import org.apache.hyracks.algebricks.rewriter.rules.subplan.EliminateSubplanWithInputCardinalityOneRule;
-import org.apache.hyracks.algebricks.rewriter.rules.subplan.IntroduceGroupByForSubplanRule;
-import org.apache.hyracks.algebricks.rewriter.rules.subplan.IntroduceLeftOuterJoinForSubplanRule;
 import org.apache.hyracks.algebricks.rewriter.rules.subplan.NestedSubplanToJoinRule;
 import org.apache.hyracks.algebricks.rewriter.rules.subplan.PushSubplanIntoGroupByRule;
 import org.apache.hyracks.algebricks.rewriter.rules.subplan.SubplanOutOfGroupRule;
@@ -190,9 +188,7 @@
         condPushDownAndJoinInference.add(new IntroJoinInsideSubplanRule());
         condPushDownAndJoinInference.add(new PushMapOperatorDownThroughProductRule());
         condPushDownAndJoinInference.add(new PushSubplanWithAggregateDownThroughProductRule());
-        condPushDownAndJoinInference.add(new IntroduceGroupByForSubplanRule());
         condPushDownAndJoinInference.add(new SubplanOutOfGroupRule());
-        condPushDownAndJoinInference.add(new IntroduceLeftOuterJoinForSubplanRule());
         condPushDownAndJoinInference.add(new AsterixExtractFunctionsFromJoinConditionRule());
 
         condPushDownAndJoinInference.add(new RemoveRedundantVariablesRule());
diff --git a/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/CancelUnnestWithNestedListifyRule.java b/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/CancelUnnestWithNestedListifyRule.java
index 558fa88..2de6bc4 100644
--- a/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/CancelUnnestWithNestedListifyRule.java
+++ b/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/CancelUnnestWithNestedListifyRule.java
@@ -49,8 +49,11 @@
 import org.apache.hyracks.algebricks.core.algebra.operators.logical.visitors.VariableUtilities;
 import org.apache.hyracks.algebricks.core.algebra.operators.physical.RunningAggregatePOperator;
 import org.apache.hyracks.algebricks.core.algebra.properties.UnpartitionedPropertyComputer;
+import org.apache.hyracks.algebricks.core.algebra.util.OperatorManipulationUtil;
 import org.apache.hyracks.algebricks.core.rewriter.base.IAlgebraicRewriteRule;
 
+import com.google.common.collect.ImmutableSet;
+
 /**
  * This rule cancels the unnest with the nested listify. Formally, the following plan<br/>
  *
@@ -195,6 +198,11 @@
             return false;
         }
 
+        if (OperatorManipulationUtil.ancestorOfOperators(agg, ImmutableSet.of(LogicalOperatorTag.LIMIT,
+                LogicalOperatorTag.ORDER, LogicalOperatorTag.GROUP, LogicalOperatorTag.DISTINCT))) {
+            return false;
+        }
+
         LogicalVariable aggVar = agg.getVariables().get(0);
         ILogicalExpression aggFun = agg.getExpressions().get(0).getValue();
         if (!aggVar.equals(unnestedVar)
diff --git a/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/subplan/InlineAllNtsInSubplanVisitor.java b/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/subplan/InlineAllNtsInSubplanVisitor.java
new file mode 100644
index 0000000..3489982
--- /dev/null
+++ b/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/subplan/InlineAllNtsInSubplanVisitor.java
@@ -0,0 +1,705 @@
+/*
+ * 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.
+ */
+package org.apache.asterix.optimizer.rules.subplan;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import org.apache.asterix.lang.common.util.FunctionUtil;
+import org.apache.asterix.om.base.AString;
+import org.apache.asterix.om.constants.AsterixConstantValue;
+import org.apache.asterix.om.functions.AsterixBuiltinFunctions;
+import org.apache.asterix.optimizer.rules.util.EquivalenceClassUtils;
+import org.apache.commons.lang3.mutable.Mutable;
+import org.apache.commons.lang3.mutable.MutableObject;
+import org.apache.hyracks.algebricks.common.exceptions.AlgebricksException;
+import org.apache.hyracks.algebricks.common.utils.Pair;
+import org.apache.hyracks.algebricks.common.utils.Triple;
+import org.apache.hyracks.algebricks.core.algebra.base.ILogicalExpression;
+import org.apache.hyracks.algebricks.core.algebra.base.ILogicalOperator;
+import org.apache.hyracks.algebricks.core.algebra.base.ILogicalPlan;
+import org.apache.hyracks.algebricks.core.algebra.base.IOptimizationContext;
+import org.apache.hyracks.algebricks.core.algebra.base.LogicalExpressionTag;
+import org.apache.hyracks.algebricks.core.algebra.base.LogicalVariable;
+import org.apache.hyracks.algebricks.core.algebra.expressions.AggregateFunctionCallExpression;
+import org.apache.hyracks.algebricks.core.algebra.expressions.ConstantExpression;
+import org.apache.hyracks.algebricks.core.algebra.expressions.ScalarFunctionCallExpression;
+import org.apache.hyracks.algebricks.core.algebra.expressions.UnnestingFunctionCallExpression;
+import org.apache.hyracks.algebricks.core.algebra.expressions.VariableReferenceExpression;
+import org.apache.hyracks.algebricks.core.algebra.operators.logical.AggregateOperator;
+import org.apache.hyracks.algebricks.core.algebra.operators.logical.AssignOperator;
+import org.apache.hyracks.algebricks.core.algebra.operators.logical.DataSourceScanOperator;
+import org.apache.hyracks.algebricks.core.algebra.operators.logical.DistinctOperator;
+import org.apache.hyracks.algebricks.core.algebra.operators.logical.EmptyTupleSourceOperator;
+import org.apache.hyracks.algebricks.core.algebra.operators.logical.ExchangeOperator;
+import org.apache.hyracks.algebricks.core.algebra.operators.logical.ExtensionOperator;
+import org.apache.hyracks.algebricks.core.algebra.operators.logical.ExternalDataLookupOperator;
+import org.apache.hyracks.algebricks.core.algebra.operators.logical.GroupByOperator;
+import org.apache.hyracks.algebricks.core.algebra.operators.logical.InnerJoinOperator;
+import org.apache.hyracks.algebricks.core.algebra.operators.logical.LeftOuterJoinOperator;
+import org.apache.hyracks.algebricks.core.algebra.operators.logical.LimitOperator;
+import org.apache.hyracks.algebricks.core.algebra.operators.logical.MaterializeOperator;
+import org.apache.hyracks.algebricks.core.algebra.operators.logical.NestedTupleSourceOperator;
+import org.apache.hyracks.algebricks.core.algebra.operators.logical.OrderOperator;
+import org.apache.hyracks.algebricks.core.algebra.operators.logical.OrderOperator.IOrder;
+import org.apache.hyracks.algebricks.core.algebra.operators.logical.OuterUnnestOperator;
+import org.apache.hyracks.algebricks.core.algebra.operators.logical.PartitioningSplitOperator;
+import org.apache.hyracks.algebricks.core.algebra.operators.logical.ProjectOperator;
+import org.apache.hyracks.algebricks.core.algebra.operators.logical.ReplicateOperator;
+import org.apache.hyracks.algebricks.core.algebra.operators.logical.RunningAggregateOperator;
+import org.apache.hyracks.algebricks.core.algebra.operators.logical.ScriptOperator;
+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.TokenizeOperator;
+import org.apache.hyracks.algebricks.core.algebra.operators.logical.UnionAllOperator;
+import org.apache.hyracks.algebricks.core.algebra.operators.logical.UnnestMapOperator;
+import org.apache.hyracks.algebricks.core.algebra.operators.logical.UnnestOperator;
+import org.apache.hyracks.algebricks.core.algebra.operators.logical.visitors.LogicalOperatorDeepCopyWithNewVariablesVisitor;
+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.visitors.IQueryOperatorVisitor;
+
+/*
+    This visitor inlines all nested tuple source operators in the query
+    plan rooted at the operator being visited, with a deep copy of the query
+    plan rooted at the input <code>subplanInputOperator</code>.
+
+    The visitor ensures that the variables used to correlate between the
+    query plan rooted at <code>subplanInputOperator</code> are propagated
+    to the operator being visited.
+
+    ----------------------------------
+    Here is an abstract example.
+    The original query plan:
+    --Op1
+      --Subplan{
+        --AggregateOp
+          --NestedOp
+            .....
+              --Nested-Tuple-Source
+        }
+        --InputOp
+          .....
+
+    After we call NestedOp.accept(....) with this visitor. We will get an
+    intermediate plan that looks like:
+    --Op1
+      --Subplan{
+        --AggregateOp
+          --NestedOp
+            .....
+              --InputOp'
+                ....
+        }
+        --InputOp
+          .....
+     The plan rooted at InputOp' is a deep copy of the plan rooted at InputOp
+     with a different set of variables.
+
+ */
+class InlineAllNtsInSubplanVisitor implements IQueryOperatorVisitor<ILogicalOperator, Void> {
+    // The optimization context.
+    private final IOptimizationContext context;
+
+    // The target SubplanOperator.
+    private final ILogicalOperator subplanOperator;
+
+    // The input operator to the subplan.
+    private final ILogicalOperator subplanInputOperator;
+
+    // Maps live variables at <code>subplanInputOperator</code> to variables in the flattened nested plan.
+    private final Map<LogicalVariable, LogicalVariable> subplanInputVarToCurrentVarMap = new HashMap<>();
+
+    // Maps variables in the flattened nested plan to live variables at <code>subplannputOperator</code>.
+    private final Map<LogicalVariable, LogicalVariable> currentVarToSubplanInputVarMap = new HashMap<>();
+
+    // The set of key variables at the current operator that is being visited.
+    private final Set<LogicalVariable> correlatedKeyVars = new HashSet<>();
+
+    // The list of variables determining the ordering.
+    private final List<Pair<IOrder, Mutable<ILogicalExpression>>> orderingExprs = new ArrayList<>();
+
+    // Maps variables in the flattened nested plan to live variables at <code>subplannputOperator</code>.
+    private final List<Pair<LogicalVariable, LogicalVariable>> varMapIntroducedByRewriting = new ArrayList<>();
+
+    /**
+     * @param context
+     *            the optimization context
+     * @param subplanInputOperator
+     *            the input operator to the target subplan operator, which is to be inlined.
+     * @throws AlgebricksException
+     */
+    public InlineAllNtsInSubplanVisitor(IOptimizationContext context, ILogicalOperator subplanOperator)
+            throws AlgebricksException {
+        this.context = context;
+        this.subplanOperator = subplanOperator;
+        this.subplanInputOperator = subplanOperator.getInputs().get(0).getValue();
+    }
+
+    public Map<LogicalVariable, LogicalVariable> getInputVariableToOutputVariableMap() {
+        return subplanInputVarToCurrentVarMap;
+    }
+
+    public List<Pair<LogicalVariable, LogicalVariable>> getVariableMapHistory() {
+        return varMapIntroducedByRewriting;
+    }
+
+    public List<Pair<IOrder, Mutable<ILogicalExpression>>> getOrderingExpressions() {
+        return orderingExprs;
+    }
+
+    @Override
+    public ILogicalOperator visitAggregateOperator(AggregateOperator op, Void arg) throws AlgebricksException {
+        return visitAggregateOperator(op);
+    }
+
+    @Override
+    public ILogicalOperator visitRunningAggregateOperator(RunningAggregateOperator op, Void arg)
+            throws AlgebricksException {
+        return visitAggregateOperator(op);
+    }
+
+    @Override
+    public ILogicalOperator visitEmptyTupleSourceOperator(EmptyTupleSourceOperator op, Void arg)
+            throws AlgebricksException {
+        return visitSingleInputOperator(op);
+    }
+
+    @Override
+    public ILogicalOperator visitGroupByOperator(GroupByOperator op, Void arg) throws AlgebricksException {
+        visitSingleInputOperator(op);
+        Set<LogicalVariable> groupKeyVars = new HashSet<>();
+        // Maps group by key variables if the corresponding expressions are VariableReferenceExpressions.
+        for (Pair<LogicalVariable, Mutable<ILogicalExpression>> keyVarExprRef : op.getGroupByList()) {
+            ILogicalExpression expr = keyVarExprRef.second.getValue();
+            if (expr.getExpressionTag() == LogicalExpressionTag.VARIABLE) {
+                VariableReferenceExpression varExpr = (VariableReferenceExpression) expr;
+                LogicalVariable sourceVar = varExpr.getVariableReference();
+                updateInputToOutputVarMapping(sourceVar, keyVarExprRef.first, false);
+                groupKeyVars.add(keyVarExprRef.first);
+            }
+        }
+
+        // Add correlated key variables into group-by keys.
+        Map<LogicalVariable, LogicalVariable> addedGroupKeyMapping = new HashMap<>();
+        for (LogicalVariable keyVar : correlatedKeyVars) {
+            if (!groupKeyVars.contains(keyVar)) {
+                LogicalVariable newVar = context.newVar();
+                op.getGroupByList().add(new Pair<LogicalVariable, Mutable<ILogicalExpression>>(newVar,
+                        new MutableObject<ILogicalExpression>(new VariableReferenceExpression(keyVar))));
+                addedGroupKeyMapping.put(keyVar, newVar);
+            }
+        }
+
+        // Updates decor list.
+        Iterator<Pair<LogicalVariable, Mutable<ILogicalExpression>>> decorExprIter = op.getDecorList().iterator();
+        while (decorExprIter.hasNext()) {
+            ILogicalExpression expr = decorExprIter.next().second.getValue();
+            if (expr.getExpressionTag() == LogicalExpressionTag.VARIABLE) {
+                VariableReferenceExpression varExpr = (VariableReferenceExpression) expr;
+                if (correlatedKeyVars.contains(varExpr.getVariableReference())) {
+                    decorExprIter.remove();
+                }
+            }
+        }
+
+        // Updates the var mapping for added group-by keys.
+        for (Map.Entry<LogicalVariable, LogicalVariable> entry : addedGroupKeyMapping.entrySet()) {
+            updateInputToOutputVarMapping(entry.getKey(), entry.getValue(), false);
+        }
+        return op;
+    }
+
+    @Override
+    public ILogicalOperator visitLimitOperator(LimitOperator op, Void arg) throws AlgebricksException {
+        // Processes its input operator.
+        visitSingleInputOperator(op);
+        if (correlatedKeyVars.isEmpty()) {
+            return op;
+        }
+
+        // Get live variables before limit.
+        Set<LogicalVariable> inputLiveVars = new HashSet<LogicalVariable>();
+        VariableUtilities.getSubplanLocalLiveVariables(op.getInputs().get(0).getValue(), inputLiveVars);
+
+        // Creates a record construction assign operator.
+        Pair<ILogicalOperator, LogicalVariable> assignOpAndRecordVar = createRecordConstructorAssignOp(inputLiveVars);
+        ILogicalOperator assignOp = assignOpAndRecordVar.first;
+        LogicalVariable recordVar = assignOpAndRecordVar.second;
+        ILogicalOperator inputOp = op.getInputs().get(0).getValue();
+        assignOp.getInputs().add(new MutableObject<ILogicalOperator>(inputOp));
+
+        // Rewrites limit to a group-by with limit as its nested operator.
+        Pair<ILogicalOperator, LogicalVariable> gbyOpAndAggVar = wrapLimitInGroupBy(op, recordVar, inputLiveVars);
+        ILogicalOperator gbyOp = gbyOpAndAggVar.first;
+        LogicalVariable aggVar = gbyOpAndAggVar.second;
+        gbyOp.getInputs().add(new MutableObject<ILogicalOperator>(assignOp));
+
+        // Adds an unnest operators on top of the group-by operator.
+        Pair<ILogicalOperator, LogicalVariable> unnestOpAndUnnestVar = createUnnestForAggregatedList(aggVar);
+        ILogicalOperator unnestOp = unnestOpAndUnnestVar.first;
+        LogicalVariable unnestVar = unnestOpAndUnnestVar.second;
+        unnestOp.getInputs().add(new MutableObject<ILogicalOperator>(gbyOp));
+
+        // Adds field accesses to recover input live variables.
+        ILogicalOperator fieldAccessAssignOp = createFieldAccessAssignOperator(unnestVar, inputLiveVars);
+        fieldAccessAssignOp.getInputs().add(new MutableObject<ILogicalOperator>(unnestOp));
+
+        OperatorManipulationUtil.computeTypeEnvironmentBottomUp(fieldAccessAssignOp, context);
+        return fieldAccessAssignOp;
+    }
+
+    private Pair<ILogicalOperator, LogicalVariable> createRecordConstructorAssignOp(
+            Set<LogicalVariable> inputLiveVars) {
+        // Creates a nested record.
+        List<Mutable<ILogicalExpression>> recordConstructorArgs = new ArrayList<>();
+        for (LogicalVariable inputLiveVar : inputLiveVars) {
+            if (!correlatedKeyVars.contains(inputLiveVar)) {
+                recordConstructorArgs.add(new MutableObject<ILogicalExpression>(new ConstantExpression(
+                        new AsterixConstantValue(new AString(Integer.toString(inputLiveVar.getId()))))));
+                recordConstructorArgs
+                        .add(new MutableObject<ILogicalExpression>(new VariableReferenceExpression(inputLiveVar)));
+            }
+        }
+        LogicalVariable recordVar = context.newVar();
+        Mutable<ILogicalExpression> recordExprRef = new MutableObject<ILogicalExpression>(
+                new ScalarFunctionCallExpression(
+                        FunctionUtil.getFunctionInfo(AsterixBuiltinFunctions.OPEN_RECORD_CONSTRUCTOR),
+                        recordConstructorArgs));
+        AssignOperator assignOp = new AssignOperator(recordVar, recordExprRef);
+        return new Pair<ILogicalOperator, LogicalVariable>(assignOp, recordVar);
+    }
+
+    private Pair<ILogicalOperator, LogicalVariable> wrapLimitInGroupBy(ILogicalOperator op, LogicalVariable recordVar,
+            Set<LogicalVariable> inputLiveVars) throws AlgebricksException {
+        GroupByOperator gbyOp = new GroupByOperator();
+        List<Pair<LogicalVariable, LogicalVariable>> keyVarNewVarPairs = new ArrayList<>();
+        for (LogicalVariable keyVar : correlatedKeyVars) {
+            // This limits the visitor can only be applied to a nested logical plan inside a Subplan operator,
+            // where the keyVarsToEnforce forms a candidate key which can uniquely identify a tuple out of the nested-tuple-source.
+            LogicalVariable newVar = context.newVar();
+            gbyOp.getGroupByList().add(new Pair<LogicalVariable, Mutable<ILogicalExpression>>(newVar,
+                    new MutableObject<ILogicalExpression>(new VariableReferenceExpression(keyVar))));
+            keyVarNewVarPairs.add(new Pair<LogicalVariable, LogicalVariable>(keyVar, newVar));
+        }
+
+        // Creates an aggregate operator doing LISTIFY, as the root of the nested plan of the added group-by operator.
+        List<LogicalVariable> aggVarList = new ArrayList<LogicalVariable>();
+        List<Mutable<ILogicalExpression>> aggExprList = new ArrayList<Mutable<ILogicalExpression>>();
+        LogicalVariable aggVar = context.newVar();
+        List<Mutable<ILogicalExpression>> aggArgList = new ArrayList<>();
+        aggVarList.add(aggVar);
+        // Creates an aggregation function expression.
+        aggArgList.add(new MutableObject<ILogicalExpression>(new VariableReferenceExpression(recordVar)));
+        ILogicalExpression aggExpr = new AggregateFunctionCallExpression(
+                FunctionUtil.getFunctionInfo(AsterixBuiltinFunctions.LISTIFY), false, aggArgList);
+        aggExprList.add(new MutableObject<ILogicalExpression>(aggExpr));
+        AggregateOperator aggOp = new AggregateOperator(aggVarList, aggExprList);
+
+        // Adds the original limit operator as the input operator to the added aggregate operator.
+        aggOp.getInputs().add(new MutableObject<ILogicalOperator>(op));
+        op.getInputs().clear();
+        ILogicalOperator currentOp = op;
+        if (!orderingExprs.isEmpty()) {
+            OrderOperator orderOp = new OrderOperator(cloneOrderingExpression(orderingExprs));
+            op.getInputs().add(new MutableObject<ILogicalOperator>(orderOp));
+            currentOp = orderOp;
+        }
+
+        // Adds a nested tuple source operator as the input operator to the limit operator.
+        NestedTupleSourceOperator nts = new NestedTupleSourceOperator(new MutableObject<ILogicalOperator>(gbyOp));
+        currentOp.getInputs().add(new MutableObject<ILogicalOperator>(nts));
+
+        // Sets the root of the added nested plan to the aggregate operator.
+        ILogicalPlan nestedPlan = new ALogicalPlanImpl();
+        nestedPlan.getRoots().add(new MutableObject<ILogicalOperator>(aggOp));
+
+        // Sets the nested plan for the added group-by operator.
+        gbyOp.getNestedPlans().add(nestedPlan);
+
+        // Updates variable mapping for ancestor operators.
+        for (Pair<LogicalVariable, LogicalVariable> keyVarNewVar : keyVarNewVarPairs) {
+            updateInputToOutputVarMapping(keyVarNewVar.first, keyVarNewVar.second, false);
+        }
+        return new Pair<ILogicalOperator, LogicalVariable>(gbyOp, aggVar);
+    }
+
+    private Pair<ILogicalOperator, LogicalVariable> createUnnestForAggregatedList(LogicalVariable aggVar) {
+        LogicalVariable unnestVar = context.newVar();
+        // Creates an unnest function expression.
+        Mutable<ILogicalExpression> unnestArg = new MutableObject<ILogicalExpression>(
+                new VariableReferenceExpression(aggVar));
+        List<Mutable<ILogicalExpression>> unnestArgList = new ArrayList<Mutable<ILogicalExpression>>();
+        unnestArgList.add(unnestArg);
+        Mutable<ILogicalExpression> unnestExpr = new MutableObject<ILogicalExpression>(
+                new UnnestingFunctionCallExpression(
+                        FunctionUtil.getFunctionInfo(AsterixBuiltinFunctions.SCAN_COLLECTION), unnestArgList));
+        ILogicalOperator unnestOp = new UnnestOperator(unnestVar, unnestExpr);
+        return new Pair<ILogicalOperator, LogicalVariable>(unnestOp, unnestVar);
+    }
+
+    private ILogicalOperator createFieldAccessAssignOperator(LogicalVariable recordVar,
+            Set<LogicalVariable> inputLiveVars) {
+        List<LogicalVariable> fieldAccessVars = new ArrayList<>();
+        List<Mutable<ILogicalExpression>> fieldAccessExprs = new ArrayList<>();
+        //Adds field access by name.
+        for (LogicalVariable inputLiveVar : inputLiveVars) {
+            if (!correlatedKeyVars.contains(inputLiveVar)) {
+                // field Var
+                LogicalVariable newVar = context.newVar();
+                fieldAccessVars.add(newVar);
+                // fieldAcess expr
+                List<Mutable<ILogicalExpression>> argRefs = new ArrayList<>();
+                argRefs.add(new MutableObject<ILogicalExpression>(new VariableReferenceExpression(recordVar)));
+                argRefs.add(new MutableObject<ILogicalExpression>(new ConstantExpression(
+                        new AsterixConstantValue(new AString(Integer.toString(inputLiveVar.getId()))))));
+                fieldAccessExprs.add(new MutableObject<ILogicalExpression>(new ScalarFunctionCallExpression(
+                        FunctionUtil.getFunctionInfo(AsterixBuiltinFunctions.FIELD_ACCESS_BY_NAME), argRefs)));
+                // Updates variable mapping for ancestor operators.
+                updateInputToOutputVarMapping(inputLiveVar, newVar, false);
+            }
+        }
+        AssignOperator fieldAccessAssignOp = new AssignOperator(fieldAccessVars, fieldAccessExprs);
+        return fieldAccessAssignOp;
+    }
+
+    @Override
+    public ILogicalOperator visitInnerJoinOperator(InnerJoinOperator op, Void arg) throws AlgebricksException {
+        return visitMultiInputOperator(op);
+    }
+
+    @Override
+    public ILogicalOperator visitLeftOuterJoinOperator(LeftOuterJoinOperator op, Void arg) throws AlgebricksException {
+        return visitMultiInputOperator(op);
+    }
+
+    @Override
+    public ILogicalOperator visitNestedTupleSourceOperator(NestedTupleSourceOperator op, Void arg)
+            throws AlgebricksException {
+        if (op.getDataSourceReference().getValue() != subplanOperator) {
+            return op;
+        }
+        LogicalOperatorDeepCopyWithNewVariablesVisitor deepCopyVisitor = new LogicalOperatorDeepCopyWithNewVariablesVisitor(
+                context);
+        ILogicalOperator copiedInputOperator = deepCopyVisitor.deepCopy(subplanInputOperator, null);
+
+        // Updates the primary key info in the copied plan segment.
+        Map<LogicalVariable, LogicalVariable> varMap = deepCopyVisitor.getInputToOutputVariableMapping();
+        context.updatePrimaryKeys(varMap);
+
+        correlatedKeyVars.clear();
+        correlatedKeyVars.addAll(EquivalenceClassUtils.findFDHeaderVariables(context, subplanInputOperator));
+        // Update key variables and input-output-var mapping.
+        for (Map.Entry<LogicalVariable, LogicalVariable> entry : varMap.entrySet()) {
+            LogicalVariable oldVar = entry.getKey();
+            LogicalVariable newVar = entry.getValue();
+            if (correlatedKeyVars.contains(oldVar)) {
+                correlatedKeyVars.remove(oldVar);
+                correlatedKeyVars.add(newVar);
+            }
+            updateInputToOutputVarMapping(oldVar, newVar, true);
+        }
+        return copiedInputOperator;
+    }
+
+    @Override
+    public ILogicalOperator visitOrderOperator(OrderOperator op, Void arg) throws AlgebricksException {
+        visitSingleInputOperator(op);
+        if (correlatedKeyVars.isEmpty()) {
+            return op;
+        }
+
+        orderingExprs.clear();
+        orderingExprs.addAll(cloneOrderingExpression(op.getOrderExpressions()));
+
+        List<Pair<IOrder, Mutable<ILogicalExpression>>> orderExprList = new ArrayList<>();
+        // Adds keyVars to the prefix of sorting columns.
+        for (LogicalVariable keyVar : correlatedKeyVars) {
+            orderExprList.add(new Pair<IOrder, Mutable<ILogicalExpression>>(OrderOperator.ASC_ORDER,
+                    new MutableObject<ILogicalExpression>(new VariableReferenceExpression(keyVar))));
+        }
+        orderExprList.addAll(op.getOrderExpressions());
+
+        // Creates an order operator with the new expression list.
+        OrderOperator orderOp = new OrderOperator(orderExprList);
+        orderOp.getInputs().addAll(op.getInputs());
+        context.computeAndSetTypeEnvironmentForOperator(orderOp);
+        return orderOp;
+    }
+
+    @Override
+    public ILogicalOperator visitAssignOperator(AssignOperator op, Void arg) throws AlgebricksException {
+        visitSingleInputOperator(op);
+        List<Mutable<ILogicalExpression>> assignedExprRefs = op.getExpressions();
+        List<LogicalVariable> assignedVars = op.getVariables();
+        // Maps assigning variables if assignment expressions are VariableReferenceExpressions.
+        for (int index = 0; index < assignedVars.size(); ++index) {
+            ILogicalExpression expr = assignedExprRefs.get(index).getValue();
+            if (expr.getExpressionTag() == LogicalExpressionTag.VARIABLE) {
+                VariableReferenceExpression varExpr = (VariableReferenceExpression) expr;
+                LogicalVariable sourceVar = varExpr.getVariableReference();
+                updateInputToOutputVarMapping(sourceVar, assignedVars.get(index), false);
+            }
+        }
+        return op;
+    }
+
+    @Override
+    public ILogicalOperator visitSelectOperator(SelectOperator op, Void arg) throws AlgebricksException {
+        return visitSingleInputOperator(op);
+    }
+
+    @Override
+    public ILogicalOperator visitExtensionOperator(ExtensionOperator op, Void arg) throws AlgebricksException {
+        return visitSingleInputOperator(op);
+    }
+
+    @Override
+    public ILogicalOperator visitProjectOperator(ProjectOperator op, Void arg) throws AlgebricksException {
+        visitSingleInputOperator(op);
+        // Adds all missing variables that should propagates up.
+        for (LogicalVariable keyVar : correlatedKeyVars) {
+            if (!op.getVariables().contains(keyVar)) {
+                op.getVariables().add(keyVar);
+            }
+        }
+        return op;
+
+    }
+
+    @Override
+    public ILogicalOperator visitPartitioningSplitOperator(PartitioningSplitOperator op, Void arg)
+            throws AlgebricksException {
+        return visitSingleInputOperator(op);
+    }
+
+    @Override
+    public ILogicalOperator visitReplicateOperator(ReplicateOperator op, Void arg) throws AlgebricksException {
+        return visitSingleInputOperator(op);
+    }
+
+    @Override
+    public ILogicalOperator visitMaterializeOperator(MaterializeOperator op, Void arg) throws AlgebricksException {
+        return visitSingleInputOperator(op);
+    }
+
+    @Override
+    public ILogicalOperator visitScriptOperator(ScriptOperator op, Void arg) throws AlgebricksException {
+        throw new UnsupportedOperationException("Script operators in a subplan are not supported!");
+    }
+
+    @Override
+    public ILogicalOperator visitSubplanOperator(SubplanOperator op, Void arg) throws AlgebricksException {
+        return visitSingleInputOperator(op);
+    }
+
+    @Override
+    public ILogicalOperator visitUnionOperator(UnionAllOperator op, Void arg) throws AlgebricksException {
+        visitMultiInputOperator(op);
+        // Update the variable mappings
+        List<Triple<LogicalVariable, LogicalVariable, LogicalVariable>> varTriples = op.getVariableMappings();
+        for (Triple<LogicalVariable, LogicalVariable, LogicalVariable> triple : varTriples) {
+            updateInputToOutputVarMapping(triple.third, triple.first, false);
+            updateInputToOutputVarMapping(triple.second, triple.first, false);
+        }
+        return op;
+    }
+
+    @Override
+    public ILogicalOperator visitUnnestOperator(UnnestOperator op, Void arg) throws AlgebricksException {
+        return visitSingleInputOperator(op);
+    }
+
+    @Override
+    public ILogicalOperator visitOuterUnnestOperator(OuterUnnestOperator op, Void arg) throws AlgebricksException {
+        return visitSingleInputOperator(op);
+    }
+
+    @Override
+    public ILogicalOperator visitUnnestMapOperator(UnnestMapOperator op, Void arg) throws AlgebricksException {
+        visitSingleInputOperator(op);
+        Set<LogicalVariable> liveVars = new HashSet<>();
+        VariableUtilities.getLiveVariables(op, liveVars);
+        if (!liveVars.containsAll(correlatedKeyVars)) {
+            op.setPropagatesInput(true);
+        }
+        return op;
+    }
+
+    @Override
+    public ILogicalOperator visitDataScanOperator(DataSourceScanOperator op, Void arg) throws AlgebricksException {
+        return visitSingleInputOperator(op);
+    }
+
+    @Override
+    public ILogicalOperator visitDistinctOperator(DistinctOperator op, Void arg) throws AlgebricksException {
+        visitSingleInputOperator(op);
+        List<LogicalVariable> distinctVarList = op.getDistinctByVarList();
+        for (LogicalVariable keyVar : correlatedKeyVars) {
+            if (!distinctVarList.contains(keyVar)) {
+                distinctVarList.add(keyVar);
+            }
+        }
+        context.computeAndSetTypeEnvironmentForOperator(op);
+        return op;
+    }
+
+    @Override
+    public ILogicalOperator visitExchangeOperator(ExchangeOperator op, Void arg) throws AlgebricksException {
+        return visitSingleInputOperator(op);
+    }
+
+    @Override
+    public ILogicalOperator visitExternalDataLookupOperator(ExternalDataLookupOperator op, Void arg)
+            throws AlgebricksException {
+        visitSingleInputOperator(op);
+        Set<LogicalVariable> liveVars = new HashSet<>();
+        VariableUtilities.getLiveVariables(op, liveVars);
+        if (!liveVars.containsAll(correlatedKeyVars)) {
+            op.setPropagateInput(true);
+        }
+        context.computeAndSetTypeEnvironmentForOperator(op);
+        return op;
+    }
+
+    @Override
+    public ILogicalOperator visitTokenizeOperator(TokenizeOperator op, Void arg) throws AlgebricksException {
+        return visitSingleInputOperator(op);
+    }
+
+    /**
+     * Wraps an AggregateOperator or RunningAggregateOperator with a group-by operator where
+     * the group-by keys are variables in keyVarsToEnforce.
+     * Note that the function here prevents this visitor being used to rewrite arbitrary query plans.
+     * Instead, it could only be used for rewriting a nested plan within a subplan operator.
+     *
+     * @param op
+     *            the logical operator for aggregate or running aggregate.
+     * @param keyVarsToEnforce
+     *            the set of variables that needs to preserve.
+     * @return the wrapped group-by operator if {@code keyVarsToEnforce} is not empty, and {@code op} otherwise.
+     * @throws AlgebricksException
+     */
+    private ILogicalOperator visitAggregateOperator(ILogicalOperator op) throws AlgebricksException {
+        visitSingleInputOperator(op);
+        if (correlatedKeyVars.isEmpty()) {
+            return op;
+        }
+        GroupByOperator gbyOp = new GroupByOperator();
+        for (LogicalVariable keyVar : correlatedKeyVars) {
+            // This limits the visitor can only be applied to a nested logical plan inside a Subplan operator,
+            // where the keyVarsToEnforce forms a candidate key which can uniquely identify a tuple out of the nested-tuple-source.
+            LogicalVariable newVar = context.newVar();
+            gbyOp.getGroupByList().add(new Pair<LogicalVariable, Mutable<ILogicalExpression>>(newVar,
+                    new MutableObject<ILogicalExpression>(new VariableReferenceExpression(keyVar))));
+            updateInputToOutputVarMapping(keyVar, newVar, false);
+        }
+
+        ILogicalOperator inputOp = op.getInputs().get(0).getValue();
+        gbyOp.getInputs().add(new MutableObject<ILogicalOperator>(inputOp));
+
+        NestedTupleSourceOperator nts = new NestedTupleSourceOperator(new MutableObject<ILogicalOperator>(gbyOp));
+        op.getInputs().clear();
+        op.getInputs().add(new MutableObject<ILogicalOperator>(nts));
+
+        ILogicalPlan nestedPlan = new ALogicalPlanImpl();
+        nestedPlan.getRoots().add(new MutableObject<ILogicalOperator>(op));
+        gbyOp.getNestedPlans().add(nestedPlan);
+
+        OperatorManipulationUtil.computeTypeEnvironmentBottomUp(gbyOp, context);
+        return op;
+    }
+
+    private ILogicalOperator visitMultiInputOperator(ILogicalOperator op) throws AlgebricksException {
+        orderingExprs.clear();
+        Set<LogicalVariable> keyVarsForCurrentBranch = new HashSet<LogicalVariable>();
+        for (int i = op.getInputs().size() - 1; i >= 0; --i) {
+            // Stores key variables for the previous branch.
+            keyVarsForCurrentBranch.addAll(correlatedKeyVars);
+            correlatedKeyVars.clear();
+
+            // Deals with single input operators.
+            ILogicalOperator newChild = op.getInputs().get(i).getValue().accept(this, null);
+            op.getInputs().get(i).setValue(newChild);
+
+            if (correlatedKeyVars.isEmpty()) {
+                correlatedKeyVars.addAll(keyVarsForCurrentBranch);
+            }
+            keyVarsForCurrentBranch.clear();
+        }
+        subtituteVariables(op);
+        return op;
+    }
+
+    private ILogicalOperator visitSingleInputOperator(ILogicalOperator op) throws AlgebricksException {
+        if (op.getInputs().size() == 1) {
+            // Deals with single input operators.
+            ILogicalOperator newChild = op.getInputs().get(0).getValue().accept(this, null);
+            op.getInputs().get(0).setValue(newChild);
+        }
+        subtituteVariables(op);
+        return op;
+    }
+
+    private void subtituteVariables(ILogicalOperator op) throws AlgebricksException {
+        VariableUtilities.substituteVariables(op, subplanInputVarToCurrentVarMap, context);
+        for (Pair<LogicalVariable, LogicalVariable> pair : varMapIntroducedByRewriting) {
+            VariableUtilities.substituteVariables(op, pair.first, pair.second, context);
+        }
+    }
+
+    private void updateInputToOutputVarMapping(LogicalVariable oldVar, LogicalVariable newVar, boolean inNts) {
+        if (correlatedKeyVars.contains(oldVar)) {
+            correlatedKeyVars.remove(oldVar);
+            correlatedKeyVars.add(newVar);
+        }
+
+        for (Pair<IOrder, Mutable<ILogicalExpression>> orderExpr : orderingExprs) {
+            orderExpr.second.getValue().substituteVar(oldVar, newVar);
+        }
+
+        if (currentVarToSubplanInputVarMap.containsKey(oldVar)) {
+            // Find the original mapped var.
+            oldVar = currentVarToSubplanInputVarMap.get(oldVar);
+        }
+        if (subplanInputVarToCurrentVarMap.containsKey(oldVar) || inNts) {
+            subplanInputVarToCurrentVarMap.put(oldVar, newVar);
+            currentVarToSubplanInputVarMap.put(newVar, oldVar);
+        } else {
+            varMapIntroducedByRewriting.add(new Pair<LogicalVariable, LogicalVariable>(oldVar, newVar));
+        }
+    }
+
+    private List<Pair<IOrder, Mutable<ILogicalExpression>>> cloneOrderingExpression(
+            List<Pair<IOrder, Mutable<ILogicalExpression>>> orderExprs) {
+        List<Pair<IOrder, Mutable<ILogicalExpression>>> clonedOrderExprs = new ArrayList<>();
+        for (Pair<IOrder, Mutable<ILogicalExpression>> orderExpr : orderExprs) {
+            clonedOrderExprs.add(new Pair<IOrder, Mutable<ILogicalExpression>>(orderExpr.first,
+                    new MutableObject<ILogicalExpression>(orderExpr.second.getValue().cloneExpression())));
+        }
+        return clonedOrderExprs;
+    }
+
+}
diff --git a/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/subplan/InlineLeftNtsInSubplanJoinFlatteningVisitor.java b/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/subplan/InlineLeftNtsInSubplanJoinFlatteningVisitor.java
new file mode 100644
index 0000000..191a2f9
--- /dev/null
+++ b/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/subplan/InlineLeftNtsInSubplanJoinFlatteningVisitor.java
@@ -0,0 +1,413 @@
+/*
+ * 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.
+ */
+package org.apache.asterix.optimizer.rules.subplan;
+
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
+import org.apache.commons.lang3.mutable.Mutable;
+import org.apache.commons.lang3.mutable.MutableObject;
+import org.apache.hyracks.algebricks.common.exceptions.AlgebricksException;
+import org.apache.hyracks.algebricks.common.utils.Pair;
+import org.apache.hyracks.algebricks.core.algebra.base.ILogicalExpression;
+import org.apache.hyracks.algebricks.core.algebra.base.ILogicalOperator;
+import org.apache.hyracks.algebricks.core.algebra.base.IOptimizationContext;
+import org.apache.hyracks.algebricks.core.algebra.base.LogicalOperatorTag;
+import org.apache.hyracks.algebricks.core.algebra.base.LogicalVariable;
+import org.apache.hyracks.algebricks.core.algebra.expressions.ConstantExpression;
+import org.apache.hyracks.algebricks.core.algebra.expressions.VariableReferenceExpression;
+import org.apache.hyracks.algebricks.core.algebra.operators.logical.AbstractBinaryJoinOperator;
+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.DataSourceScanOperator;
+import org.apache.hyracks.algebricks.core.algebra.operators.logical.DistinctOperator;
+import org.apache.hyracks.algebricks.core.algebra.operators.logical.EmptyTupleSourceOperator;
+import org.apache.hyracks.algebricks.core.algebra.operators.logical.ExchangeOperator;
+import org.apache.hyracks.algebricks.core.algebra.operators.logical.ExtensionOperator;
+import org.apache.hyracks.algebricks.core.algebra.operators.logical.ExternalDataLookupOperator;
+import org.apache.hyracks.algebricks.core.algebra.operators.logical.GroupByOperator;
+import org.apache.hyracks.algebricks.core.algebra.operators.logical.InnerJoinOperator;
+import org.apache.hyracks.algebricks.core.algebra.operators.logical.LeftOuterJoinOperator;
+import org.apache.hyracks.algebricks.core.algebra.operators.logical.LimitOperator;
+import org.apache.hyracks.algebricks.core.algebra.operators.logical.MaterializeOperator;
+import org.apache.hyracks.algebricks.core.algebra.operators.logical.NestedTupleSourceOperator;
+import org.apache.hyracks.algebricks.core.algebra.operators.logical.OrderOperator;
+import org.apache.hyracks.algebricks.core.algebra.operators.logical.OrderOperator.IOrder;
+import org.apache.hyracks.algebricks.core.algebra.operators.logical.OuterUnnestOperator;
+import org.apache.hyracks.algebricks.core.algebra.operators.logical.PartitioningSplitOperator;
+import org.apache.hyracks.algebricks.core.algebra.operators.logical.ProjectOperator;
+import org.apache.hyracks.algebricks.core.algebra.operators.logical.ReplicateOperator;
+import org.apache.hyracks.algebricks.core.algebra.operators.logical.RunningAggregateOperator;
+import org.apache.hyracks.algebricks.core.algebra.operators.logical.ScriptOperator;
+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.TokenizeOperator;
+import org.apache.hyracks.algebricks.core.algebra.operators.logical.UnionAllOperator;
+import org.apache.hyracks.algebricks.core.algebra.operators.logical.UnnestMapOperator;
+import org.apache.hyracks.algebricks.core.algebra.operators.logical.UnnestOperator;
+import org.apache.hyracks.algebricks.core.algebra.operators.logical.visitors.VariableUtilities;
+import org.apache.hyracks.algebricks.core.algebra.visitors.IQueryOperatorVisitor;
+
+/*
+    This visitor inlines the input <code>nts</code> in the query plan rooted
+    at the operator being visited, with the query plan rooted at the input
+    <code>subplanInputOperator</code>.
+
+    The visitor ensures that:
+    1. live variables at <code>subplanInputOperator</code> are
+    propagated to the top-most join operator in the query plan rooted
+    at the operator being visited;
+    2. no available tuple at <code>subplanInputOperator</code> get lost along the
+    pipeline to the top-most join operator in the query plan rooted
+    at the operator being visited.
+*/
+class InlineLeftNtsInSubplanJoinFlatteningVisitor implements IQueryOperatorVisitor<ILogicalOperator, Void> {
+    // The optimization context.
+    private final IOptimizationContext context;
+
+    // The input operator to the subplan.
+    private final ILogicalOperator subplanInputOperator;
+
+    // The target Nts operator.
+    private final ILogicalOperator targetNts;
+
+    // The live variables in <code>subplanInputOperator</code> to enforce.
+    private final Set<LogicalVariable> liveVarsFromSubplanInput = new HashSet<>();
+
+    // The state indicate if the operator tree rooted at the current operator is rewritten.
+    private boolean rewritten = false;
+
+    // The state indicate if the operator tree rooted at the current operator contains a rewritten join.
+    private boolean hasJoinAncestor = false;
+
+    // A set of variables that are needed for not-null checks in the final group-by operator.
+    private Set<LogicalVariable> nullCheckVars = new HashSet<LogicalVariable>();
+
+    // The top join reference.
+    private Mutable<ILogicalOperator> topJoinRef;
+
+    /***
+     * @param context
+     *            the optimization context
+     * @param subplanInputOperator
+     *            the input operator to the target SubplanOperator
+     * @param nts
+     *            the NestedTupleSourceOperator to be replaced by <code>subplanInputOperator</code>
+     * @throws AlgebricksException
+     */
+    public InlineLeftNtsInSubplanJoinFlatteningVisitor(IOptimizationContext context,
+            ILogicalOperator subplanInputOperator, ILogicalOperator nts) throws AlgebricksException {
+        this.context = context;
+        this.subplanInputOperator = subplanInputOperator;
+        this.targetNts = nts;
+        VariableUtilities.getSubplanLocalLiveVariables(subplanInputOperator, liveVarsFromSubplanInput);
+    }
+
+    /**
+     * @return a set of variables indicating whether a tuple from the right
+     *         branch of a left-outer join is a non-match.
+     */
+    public Set<LogicalVariable> getNullCheckVariables() {
+        return nullCheckVars;
+    }
+
+    /**
+     * @return the top-most join operator after visiting the query plan rooted
+     *         at the operator being visited.
+     */
+    public Mutable<ILogicalOperator> getTopJoinReference() {
+        return topJoinRef;
+    }
+
+    @Override
+    public ILogicalOperator visitAggregateOperator(AggregateOperator op, Void arg) throws AlgebricksException {
+        return visitSingleInputOperator(op);
+    }
+
+    @Override
+    public ILogicalOperator visitRunningAggregateOperator(RunningAggregateOperator op, Void arg)
+            throws AlgebricksException {
+        return visitSingleInputOperator(op);
+    }
+
+    @Override
+    public ILogicalOperator visitEmptyTupleSourceOperator(EmptyTupleSourceOperator op, Void arg)
+            throws AlgebricksException {
+        return visitSingleInputOperator(op);
+    }
+
+    @Override
+    public ILogicalOperator visitGroupByOperator(GroupByOperator op, Void arg) throws AlgebricksException {
+        return visitSingleInputOperator(op);
+    }
+
+    @Override
+    public ILogicalOperator visitLimitOperator(LimitOperator op, Void arg) throws AlgebricksException {
+        return visitSingleInputOperator(op);
+    }
+
+    @Override
+    public ILogicalOperator visitInnerJoinOperator(InnerJoinOperator op, Void arg) throws AlgebricksException {
+        hasJoinAncestor = true;
+        boolean needToSwitch = false;
+        for (int i = 0; i < op.getInputs().size(); ++i) {
+            // Deals with single input operators.
+            ILogicalOperator newChild = op.getInputs().get(i).getValue().accept(this, null);
+            op.getInputs().get(i).setValue(newChild);
+            if (i == 1) {
+                needToSwitch = true;
+            }
+            if (rewritten) {
+                break;
+            }
+        }
+
+        // Checks whether there is a need to switch two join branches.
+        if (rewritten && needToSwitch) {
+            Mutable<ILogicalOperator> leftBranch = op.getInputs().get(0);
+            Mutable<ILogicalOperator> rightBranch = op.getInputs().get(1);
+            op.getInputs().set(0, rightBranch);
+            op.getInputs().set(1, leftBranch);
+        }
+        AbstractBinaryJoinOperator returnOp = op;
+        // After rewriting, the original inner join should become an left outer join.
+        if (rewritten) {
+            returnOp = new LeftOuterJoinOperator(op.getCondition());
+            returnOp.getInputs().addAll(op.getInputs());
+            injectNullCheckVars(returnOp);
+        }
+        return returnOp;
+    }
+
+    @Override
+    public ILogicalOperator visitLeftOuterJoinOperator(LeftOuterJoinOperator op, Void arg) throws AlgebricksException {
+        hasJoinAncestor = true;
+        // Only rewrites the left child.
+        ILogicalOperator newChild = op.getInputs().get(0).getValue().accept(this, null);
+        op.getInputs().get(0).setValue(newChild);
+        return op;
+    }
+
+    @Override
+    public ILogicalOperator visitNestedTupleSourceOperator(NestedTupleSourceOperator op, Void arg)
+            throws AlgebricksException {
+        if (op == targetNts) {
+            // Inlines the actual <code>subplanInputOperator</code>.
+            rewritten = true;
+            return subplanInputOperator;
+        } else {
+            return op;
+        }
+    }
+
+    @Override
+    public ILogicalOperator visitOrderOperator(OrderOperator op, Void arg) throws AlgebricksException {
+        boolean underJoin = hasJoinAncestor;
+        visitSingleInputOperator(op);
+        if (!rewritten || !underJoin) {
+            return op;
+        }
+
+        // Adjust the ordering if its input operator pipeline has been rewritten.
+        List<Pair<IOrder, Mutable<ILogicalExpression>>> orderExprList = new ArrayList<>();
+        // Adds keyVars to the prefix of sorting columns.
+        for (LogicalVariable liveVar : liveVarsFromSubplanInput) {
+            orderExprList.add(new Pair<IOrder, Mutable<ILogicalExpression>>(OrderOperator.ASC_ORDER,
+                    new MutableObject<ILogicalExpression>(new VariableReferenceExpression(liveVar))));
+        }
+        orderExprList.addAll(op.getOrderExpressions());
+
+        // Creates an order operator with the new expression list.
+        OrderOperator orderOp = new OrderOperator(orderExprList);
+        orderOp.getInputs().addAll(op.getInputs());
+        context.computeAndSetTypeEnvironmentForOperator(orderOp);
+        return orderOp;
+    }
+
+    @Override
+    public ILogicalOperator visitAssignOperator(AssignOperator op, Void arg) throws AlgebricksException {
+        visitSingleInputOperator(op);
+        return op;
+    }
+
+    @Override
+    public ILogicalOperator visitSelectOperator(SelectOperator op, Void arg) throws AlgebricksException {
+        return visitSingleInputOperator(op);
+    }
+
+    @Override
+    public ILogicalOperator visitExtensionOperator(ExtensionOperator op, Void arg) throws AlgebricksException {
+        return visitSingleInputOperator(op);
+    }
+
+    @Override
+    public ILogicalOperator visitProjectOperator(ProjectOperator op, Void arg) throws AlgebricksException {
+        boolean underJoin = hasJoinAncestor;
+        visitSingleInputOperator(op);
+        if (!rewritten || !underJoin) {
+            return op;
+        }
+        // Adds all missing variables that should propagates up.
+        for (LogicalVariable keyVar : liveVarsFromSubplanInput) {
+            if (!op.getVariables().contains(keyVar)) {
+                op.getVariables().add(keyVar);
+            }
+        }
+        return op;
+    }
+
+    @Override
+    public ILogicalOperator visitPartitioningSplitOperator(PartitioningSplitOperator op, Void arg)
+            throws AlgebricksException {
+        return visitSingleInputOperator(op);
+    }
+
+    @Override
+    public ILogicalOperator visitReplicateOperator(ReplicateOperator op, Void arg) throws AlgebricksException {
+        return visitSingleInputOperator(op);
+    }
+
+    @Override
+    public ILogicalOperator visitMaterializeOperator(MaterializeOperator op, Void arg) throws AlgebricksException {
+        return visitSingleInputOperator(op);
+    }
+
+    @Override
+    public ILogicalOperator visitScriptOperator(ScriptOperator op, Void arg) throws AlgebricksException {
+        throw new UnsupportedOperationException("Script operators in a subplan are not supported!");
+    }
+
+    @Override
+    public ILogicalOperator visitSubplanOperator(SubplanOperator op, Void arg) throws AlgebricksException {
+        return visitSingleInputOperator(op);
+    }
+
+    @Override
+    public ILogicalOperator visitUnionOperator(UnionAllOperator op, Void arg) throws AlgebricksException {
+        throw new UnsupportedOperationException(
+                "Nested subplans with a union operator should have been disqualified for this rewriting!");
+    }
+
+    @Override
+    public ILogicalOperator visitUnnestOperator(UnnestOperator op, Void arg) throws AlgebricksException {
+        return visitSingleInputOperator(op);
+    }
+
+    @Override
+    public ILogicalOperator visitOuterUnnestOperator(OuterUnnestOperator op, Void arg) throws AlgebricksException {
+        return visitSingleInputOperator(op);
+    }
+
+    @Override
+    public ILogicalOperator visitUnnestMapOperator(UnnestMapOperator op, Void arg) throws AlgebricksException {
+        visitSingleInputOperator(op);
+        if (!rewritten) {
+            return op;
+        }
+        Set<LogicalVariable> liveVars = new HashSet<>();
+        VariableUtilities.getLiveVariables(op, liveVars);
+        if (!liveVars.containsAll(liveVarsFromSubplanInput)) {
+            op.setPropagatesInput(true);
+        }
+        return op;
+    }
+
+    @Override
+    public ILogicalOperator visitDataScanOperator(DataSourceScanOperator op, Void arg) throws AlgebricksException {
+        return visitSingleInputOperator(op);
+    }
+
+    @Override
+    public ILogicalOperator visitDistinctOperator(DistinctOperator op, Void arg) throws AlgebricksException {
+        boolean underJoin = hasJoinAncestor;
+        visitSingleInputOperator(op);
+        if (!rewritten || !underJoin) {
+            return op;
+        }
+        List<LogicalVariable> distinctVarList = op.getDistinctByVarList();
+        for (LogicalVariable keyVar : liveVarsFromSubplanInput) {
+            if (!distinctVarList.contains(keyVar)) {
+                distinctVarList.add(keyVar);
+            }
+        }
+        context.computeAndSetTypeEnvironmentForOperator(op);
+        return op;
+    }
+
+    @Override
+    public ILogicalOperator visitExchangeOperator(ExchangeOperator op, Void arg) throws AlgebricksException {
+        return visitSingleInputOperator(op);
+    }
+
+    @Override
+    public ILogicalOperator visitExternalDataLookupOperator(ExternalDataLookupOperator op, Void arg)
+            throws AlgebricksException {
+        visitSingleInputOperator(op);
+        if (!rewritten) {
+            return op;
+        }
+        Set<LogicalVariable> liveVars = new HashSet<>();
+        VariableUtilities.getLiveVariables(op, liveVars);
+        if (!liveVars.containsAll(liveVarsFromSubplanInput)) {
+            op.setPropagateInput(true);
+        }
+        context.computeAndSetTypeEnvironmentForOperator(op);
+        return op;
+    }
+
+    @Override
+    public ILogicalOperator visitTokenizeOperator(TokenizeOperator op, Void arg) throws AlgebricksException {
+        return visitSingleInputOperator(op);
+    }
+
+    private ILogicalOperator visitSingleInputOperator(ILogicalOperator op) throws AlgebricksException {
+        if (op.getInputs().size() == 1) {
+            // Deals with single input operators.
+            Mutable<ILogicalOperator> childRef = op.getInputs().get(0);
+            ILogicalOperator newChild = childRef.getValue().accept(this, null);
+            if (topJoinRef == null) {
+                LogicalOperatorTag childOpTag = newChild.getOperatorTag();
+                if (childOpTag == LogicalOperatorTag.INNERJOIN || childOpTag == LogicalOperatorTag.LEFTOUTERJOIN) {
+                    topJoinRef = childRef;
+                }
+            }
+            op.getInputs().get(0).setValue(newChild);
+        }
+        return op;
+    }
+
+    /**
+     * Inject varaibles to indicate non-matches for the right branch of
+     * a left-outer join.
+     *
+     * @param joinOp
+     *            the leftouter join operator.
+     */
+    private void injectNullCheckVars(AbstractBinaryJoinOperator joinOp) {
+        LogicalVariable assignVar = context.newVar();
+        ILogicalOperator assignOp = new AssignOperator(assignVar,
+                new MutableObject<ILogicalExpression>(ConstantExpression.TRUE));
+        assignOp.getInputs().add(joinOp.getInputs().get(1));
+        joinOp.getInputs().set(1, new MutableObject<ILogicalOperator>(assignOp));
+        nullCheckVars.add(assignVar);
+    }
+
+}
diff --git a/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/subplan/InlineSubplanInputForNestedTupleSourceRule.java b/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/subplan/InlineSubplanInputForNestedTupleSourceRule.java
index c5e99b2..d88b69f 100644
--- a/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/subplan/InlineSubplanInputForNestedTupleSourceRule.java
+++ b/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/subplan/InlineSubplanInputForNestedTupleSourceRule.java
@@ -27,6 +27,7 @@
 
 import org.apache.asterix.lang.common.util.FunctionUtil;
 import org.apache.asterix.om.functions.AsterixBuiltinFunctions;
+import org.apache.asterix.optimizer.rules.util.EquivalenceClassUtils;
 import org.apache.commons.lang3.mutable.Mutable;
 import org.apache.commons.lang3.mutable.MutableObject;
 import org.apache.hyracks.algebricks.common.exceptions.AlgebricksException;
@@ -46,28 +47,33 @@
 import org.apache.hyracks.algebricks.core.algebra.operators.logical.GroupByOperator;
 import org.apache.hyracks.algebricks.core.algebra.operators.logical.LeftOuterJoinOperator;
 import org.apache.hyracks.algebricks.core.algebra.operators.logical.NestedTupleSourceOperator;
+import org.apache.hyracks.algebricks.core.algebra.operators.logical.OrderOperator;
+import org.apache.hyracks.algebricks.core.algebra.operators.logical.OrderOperator.IOrder;
 import org.apache.hyracks.algebricks.core.algebra.operators.logical.SelectOperator;
 import org.apache.hyracks.algebricks.core.algebra.operators.logical.SubplanOperator;
-import org.apache.hyracks.algebricks.core.algebra.operators.logical.visitors.LogicalOperatorDeepCopyWithNewVariablesVisitor;
 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.properties.FunctionalDependency;
 import org.apache.hyracks.algebricks.core.algebra.util.OperatorManipulationUtil;
 import org.apache.hyracks.algebricks.core.rewriter.base.IAlgebraicRewriteRule;
-import org.apache.hyracks.algebricks.rewriter.util.PhysicalOptimizationsUtil;
 
-/***
- * This rule inlines (deep copies) a SubplanOperator's input query plan to
- * replace its NestedTupleSources.
- * Then, the SubplanOperator is replaced by:
- * 1. a LeftOuterOperatorJoin between the SubplanOperator's input operator and the
- * SubplanOperator's root operator's input.
- * 2. and on top of the LeftOuterJoinOperator, a GroupByOperaptor in which the
- * nested plan consists of the SubplanOperator's root operator.
- */
+import com.google.common.collect.ImmutableSet;
+
 /*
-This is an abstract example for this rule:
+This rule  is to remove SubplanOperators containing DataScan, InnerJoin, LeftOuterJoin, UnionAll or Distinct. Given a qualified Subplan operator called S1,
+Let's call its input operator O1.
 
+General Cases
+We have the following rewritings for general cases:
+R1. Replace all NestedTupleSourceOperators in S1 with deep-copies (with new variables) of the query plan rooted at O1;
+R2. Add a LeftOuterOperatorJoinOperator (let's call it LJ) between O1 and the SubplanOperator's root operator's input (let's call it SO1),
+    where O1 is the left branch and SO1 is the right branch;
+R3. The deep copy of the primary key variables in O1 should be preserved from an inlined NestedTupleSourceOperator to SO1.
+    The join condition of LJ is the equality between the primary key variables in O1 and its deep copied version at SO1;
+R4. A variable v indicating non-match tuples is assigned to TRUE between LJ and SO1;
+R5. On top of the LJ, add a GroupByOperaptor in which the nested plan consists of the S1's root operator, i.e., an aggregate operator.
+    Below the aggregate, there is a not-null-filter on variable v. The group key is the primary key variables in O1.
+
+This is an abstract example for the rewriting mechanism described above:
 Before rewriting:
 --Op1
   --Subplan{
@@ -96,190 +102,157 @@
              .....
                --Deepcopy_The_Plan_Rooted_At_InputOp_With_New_Variables(InputOp)
 
-In the plan, v_lc_1, ..., v_lc_n are live "covering" variables at InputOp,
-while v_rc_1, ..., v_rc_n are their corresponding variables populated from the deepcopy of InputOp.
-("Covering" variables form a set of variables that can imply all live variables.)
-v_l1, ....v_ln in the decoration part of the added group-by operator are all
-live variables at InputOp except the covering variables v_lc_1, ..., v_lc_n.
+In the plan, v_lc_1, ..., v_lc_n are live "covering" variables at InputOp, while v_rc_1, ..., v_rc_n are their corresponding variables populated from the deepcopy of InputOp.
+"Covering" variables form a set of variables that can imply all live variables. v_l1, ....v_ln in the decoration part of the added group-by operator are all live variables
+at InputOp except the covering variables v_lc_1, ..., v_lc_n.  In the current implementation, we use "covering" variables as primary key variables. In the next version, we
+will use the real primary key variables, which will fix ASTERIXDB-1168.
 
-TODO(buyingyi): the rewritten plan is wrong when there are duplicate tuples from InputOp: ASTERIXDB-1168.
-
-Here are two concrete examples. (The top child of a join operator is the outer branch.)
----------- Example 1 -----------
-FINE: >>>> Before plan
-distribute result [%0->$$27] -- |UNPARTITIONED|
-  project ([$$27]) -- |UNPARTITIONED|
-    assign [$$27] <- [function-call: asterix:open-record-constructor, Args:[AString: {subscription-id}, %0->$$37, AString: {execution-time}, function-call: asterix:current-datetime, Args:[], AString: {result}, %0->$$6]] -- |UNPARTITIONED|
-      unnest $$6 <- function-call: asterix:scan-collection, Args:[%0->$$26] -- |UNPARTITIONED|
-        subplan {
-                  aggregate [$$26] <- [function-call: asterix:listify, Args:[%0->$$22]] -- |UNPARTITIONED|
-                    join (TRUE) -- |UNPARTITIONED|
-                      select (%0->$$21) -- |UNPARTITIONED|
-                        group by ([$$30 := %0->$$35]) decor ([%0->$$5; %0->$$7; %0->$$8; %0->$$31]) {
-                                  aggregate [$$21] <- [function-call: asterix:non-empty-stream, Args:[]] -- |UNPARTITIONED|
-                                    select (function-call: algebricks:not, Args:[function-call: algebricks:is-null, Args:[%0->$$34]]) -- |UNPARTITIONED|
-                                      nested tuple source -- |UNPARTITIONED|
-                               } -- |UNPARTITIONED|
-                          left outer join (function-call: algebricks:eq, Args:[%0->$$36, %0->$$7]) -- |UNPARTITIONED|
-                            data-scan []<-[$$31, $$8] <- emergencyTest:CHPReports -- |UNPARTITIONED|
-                              nested tuple source -- |UNPARTITIONED|
-                            assign [$$34] <- [TRUE] -- |UNPARTITIONED|
-                              assign [$$36] <- [function-call: asterix:field-access-by-index, Args:[%0->$$10, AInt32: {1}]] -- |UNPARTITIONED|
-                                data-scan []<-[$$32, $$10] <- emergencyTest:userLocations -- |UNPARTITIONED|
-                                  empty-tuple-source -- |UNPARTITIONED|
-                      assign [$$22] <- [function-call: asterix:open-record-constructor, Args:[AString: {shelter locations}, %0->$$25]] -- |UNPARTITIONED|
-                        aggregate [$$25] <- [function-call: asterix:listify, Args:[%0->$$24]] -- |UNPARTITIONED|
-                          assign [$$24] <- [function-call: asterix:field-access-by-index, Args:[%0->$$11, AInt32: {1}]] -- |UNPARTITIONED|
-                            data-scan []<-[$$33, $$11] <- emergencyTest:tornadoShelters -- |UNPARTITIONED|
-                              empty-tuple-source -- |UNPARTITIONED|
-               } -- |UNPARTITIONED|
-          assign [$$7] <- [function-call: asterix:field-access-by-index, Args:[%0->$$5, AInt32: {1}]] -- |UNPARTITIONED|
-            assign [$$37] <- [function-call: asterix:field-access-by-name, Args:[%0->$$5, AString: {subscription-id}]] -- |UNPARTITIONED|
-              data-scan []<-[$$35, $$5] <- emergencyTest:NearbySheltersDuringTornadoDangerChannelSubscriptions -- |UNPARTITIONED|
-                empty-tuple-source -- |UNPARTITIONED|
-
-
-Dec 22, 2015 4:39:22 PM org.apache.hyracks.algebricks.core.rewriter.base.AbstractRuleController printRuleApplication
-FINE: >>>> After plan
-distribute result [%0->$$27] -- |UNPARTITIONED|
-  project ([$$27]) -- |UNPARTITIONED|
-    assign [$$27] <- [function-call: asterix:open-record-constructor, Args:[AString: {subscription-id}, %0->$$37, AString: {execution-time}, function-call: asterix:current-datetime, Args:[], AString: {result}, %0->$$6]] -- |UNPARTITIONED|
-      unnest $$6 <- function-call: asterix:scan-collection, Args:[%0->$$26] -- |UNPARTITIONED|
-        group by ([$$43 := %0->$$35]) decor ([%0->$$5; %0->$$37; %0->$$7]) {
-                  aggregate [$$26] <- [function-call: asterix:listify, Args:[%0->$$22]] -- |UNPARTITIONED|
-                    select (function-call: algebricks:not-null, Args:[%0->$$42]) -- |UNPARTITIONED|
-                      nested tuple source -- |UNPARTITIONED|
-               } -- |UNPARTITIONED|
-          left outer join (function-call: algebricks:eq, Args:[%0->$$35, %0->$$30]) -- |UNPARTITIONED|
-            assign [$$7] <- [function-call: asterix:field-access-by-index, Args:[%0->$$5, AInt32: {1}]] -- |UNPARTITIONED|
-              assign [$$37] <- [function-call: asterix:field-access-by-name, Args:[%0->$$5, AString: {subscription-id}]] -- |UNPARTITIONED|
-                data-scan []<-[$$35, $$5] <- emergencyTest:NearbySheltersDuringTornadoDangerChannelSubscriptions -- |UNPARTITIONED|
-                  empty-tuple-source -- |UNPARTITIONED|
-            assign [$$42] <- [TRUE] -- |UNPARTITIONED|
-              join (TRUE) -- |UNPARTITIONED|
-                select (%0->$$21) -- |UNPARTITIONED|
-                  group by ([$$30 := %0->$$41]) decor ([%0->$$39; %0->$$38; %0->$$8; %0->$$31]) {
-                            aggregate [$$21] <- [function-call: asterix:non-empty-stream, Args:[]] -- |UNPARTITIONED|
-                              select (function-call: algebricks:not, Args:[function-call: algebricks:is-null, Args:[%0->$$34]]) -- |UNPARTITIONED|
-                                nested tuple source -- |UNPARTITIONED|
-                         } -- |UNPARTITIONED|
-                    left outer join (function-call: algebricks:eq, Args:[%0->$$36, %0->$$38]) -- |UNPARTITIONED|
-                      data-scan []<-[$$31, $$8] <- emergencyTest:CHPReports -- |UNPARTITIONED|
-                        assign [$$38] <- [function-call: asterix:field-access-by-index, Args:[%0->$$39, AInt32: {1}]] -- |UNPARTITIONED|
-                          assign [$$40] <- [function-call: asterix:field-access-by-name, Args:[%0->$$39, AString: {subscription-id}]] -- |UNPARTITIONED|
-                            data-scan []<-[$$41, $$39] <- emergencyTest:NearbySheltersDuringTornadoDangerChannelSubscriptions -- |UNPARTITIONED|
-                              empty-tuple-source -- |UNPARTITIONED|
-                      assign [$$34] <- [TRUE] -- |UNPARTITIONED|
-                        assign [$$36] <- [function-call: asterix:field-access-by-index, Args:[%0->$$10, AInt32: {1}]] -- |UNPARTITIONED|
-                          data-scan []<-[$$32, $$10] <- emergencyTest:userLocations -- |UNPARTITIONED|
-                            empty-tuple-source -- |UNPARTITIONED|
-                assign [$$22] <- [function-call: asterix:open-record-constructor, Args:[AString: {shelter locations}, %0->$$25]] -- |UNPARTITIONED|
-                  aggregate [$$25] <- [function-call: asterix:listify, Args:[%0->$$24]] -- |UNPARTITIONED|
-                    assign [$$24] <- [function-call: asterix:field-access-by-index, Args:[%0->$$11, AInt32: {1}]] -- |UNPARTITIONED|
-                      data-scan []<-[$$33, $$11] <- emergencyTest:tornadoShelters -- |UNPARTITIONED|
-                        empty-tuple-source -- |UNPARTITIONED|
---------------------------------
-
----------- Example 2 -----------
-FINE: >>>> Before plan
-distribute result [%0->$$8] -- |UNPARTITIONED|
-  project ([$$8]) -- |UNPARTITIONED|
-    unnest $$8 <- function-call: asterix:scan-collection, Args:[%0->$$41] -- |UNPARTITIONED|
+Here is a concrete example of the general case rewriting (optimizerts/queries/nested_loj4.aql).
+Before plan:
+distribute result [%0->$$13] -- |UNPARTITIONED|
+  project ([$$13]) -- |UNPARTITIONED|
+    assign [$$13] <- [function-call: asterix:open-record-constructor, Args:[AString: {cust}, %0->$$0, AString: {orders}, %0->$$12]] -- |UNPARTITIONED|
       subplan {
-                aggregate [$$41] <- [function-call: asterix:listify, Args:[%0->$$38]] -- |UNPARTITIONED|
-                  assign [$$38] <- [function-call: asterix:open-record-constructor, Args:[AString: {subscription-id}, %0->$$54, AString: {execution-time}, function-call: asterix:current-datetime, Args:[], AString: {result}, %0->$$19]] -- |UNPARTITIONED|
-                    unnest $$19 <- function-call: asterix:scan-collection, Args:[%0->$$37] -- |UNPARTITIONED|
-                      subplan {
-                                aggregate [$$37] <- [function-call: asterix:listify, Args:[%0->$$33]] -- |UNPARTITIONED|
-                                  join (TRUE) -- |UNPARTITIONED|
-                                    select (%0->$$32) -- |UNPARTITIONED|
-                                      group by ([$$16 := %0->$$47; $$43 := %0->$$48; $$15 := %0->$$49]) decor ([%0->$$7; %0->$$42; %0->$$14]) {
-                                                aggregate [$$32] <- [function-call: asterix:non-empty-stream, Args:[]] -- |UNPARTITIONED|
-                                                  select (function-call: algebricks:not, Args:[function-call: algebricks:is-null, Args:[%0->$$46]]) -- |UNPARTITIONED|
-                                                    nested tuple source -- |UNPARTITIONED|
-                                             } -- |UNPARTITIONED|
-                                        left outer join (function-call: algebricks:and, Args:[function-call: algebricks:eq, Args:[%0->$$50, %0->$$14], function-call: asterix:spatial-intersect, Args:[%0->$$47, %0->$$53]]) -- |UNPARTITIONED|
-                                          assign [$$47] <- [function-call: asterix:create-circle, Args:[%0->$$51, %0->$$52]] -- |UNPARTITIONED|
-                                            assign [$$51] <- [function-call: asterix:field-access-by-index, Args:[%0->$$49, AInt32: {1}]] -- |UNPARTITIONED|
-                                              assign [$$52] <- [function-call: asterix:field-access-by-index, Args:[%0->$$49, AInt32: {2}]] -- |UNPARTITIONED|
-                                                data-scan []<-[$$48, $$49] <- emergencyTest:CHPReports -- |UNPARTITIONED|
-                                                  nested tuple source -- |UNPARTITIONED|
-                                          assign [$$46] <- [TRUE] -- |UNPARTITIONED|
-                                            assign [$$50] <- [function-call: asterix:field-access-by-index, Args:[%0->$$17, AInt32: {1}]] -- |UNPARTITIONED|
-                                              assign [$$53] <- [function-call: asterix:field-access-by-index, Args:[%0->$$17, AInt32: {2}]] -- |UNPARTITIONED|
-                                                data-scan []<-[$$44, $$17] <- emergencyTest:userLocations -- |UNPARTITIONED|
-                                                  empty-tuple-source -- |UNPARTITIONED|
-                                    assign [$$33] <- [function-call: asterix:open-record-constructor, Args:[AString: {shelter locations}, %0->$$36]] -- |UNPARTITIONED|
-                                      aggregate [$$36] <- [function-call: asterix:listify, Args:[%0->$$35]] -- |UNPARTITIONED|
-                                        assign [$$35] <- [function-call: asterix:field-access-by-index, Args:[%0->$$18, AInt32: {1}]] -- |UNPARTITIONED|
-                                          data-scan []<-[$$45, $$18] <- emergencyTest:tornadoShelters -- |UNPARTITIONED|
-                                            empty-tuple-source -- |UNPARTITIONED|
-                             } -- |UNPARTITIONED|
-                        nested tuple source -- |UNPARTITIONED|
+                aggregate [$$12] <- [function-call: asterix:listify, Args:[%0->$$1]] -- |UNPARTITIONED|
+                  join (function-call: algebricks:eq, Args:[%0->$$16, %0->$$14]) -- |UNPARTITIONED|
+                    select (function-call: algebricks:eq, Args:[%0->$$18, AInt64: {5}]) -- |UNPARTITIONED|
+                      nested tuple source -- |UNPARTITIONED|
+                    assign [$$16] <- [function-call: asterix:field-access-by-name, Args:[%0->$$19, AString: {o_custkey}]] -- |UNPARTITIONED|
+                      assign [$$19] <- [function-call: asterix:field-access-by-name, Args:[%0->$$1, AString: {o_$o}]] -- |UNPARTITIONED|
+                        data-scan []<-[$$15, $$1] <- tpch:Orders -- |UNPARTITIONED|
+                          empty-tuple-source -- |UNPARTITIONED|
              } -- |UNPARTITIONED|
-        assign [$$14] <- [function-call: asterix:field-access-by-index, Args:[%0->$$7, AInt32: {1}]] -- |UNPARTITIONED|
-          assign [$$54] <- [function-call: asterix:field-access-by-name, Args:[%0->$$7, AString: {subscription-id}]] -- |UNPARTITIONED|
-            data-scan []<-[$$42, $$7] <- emergencyTest:NearbySheltersDuringTornadoDangerChannelSubscriptions -- |UNPARTITIONED|
-              empty-tuple-source -- |UNPARTITIONED|
+        assign [$$18] <- [function-call: asterix:field-access-by-index, Args:[%0->$$0, AInt32: {3}]] -- |UNPARTITIONED|
+          data-scan []<-[$$14, $$0] <- tpch:Customers -- |UNPARTITIONED|
+            empty-tuple-source -- |UNPARTITIONED|
 
-
-Dec 28, 2015 12:48:30 PM org.apache.hyracks.algebricks.core.rewriter.base.AbstractRuleController printRuleApplication
-FINE: >>>> After plan
-distribute result [%0->$$8] -- |UNPARTITIONED|
-  project ([$$8]) -- |UNPARTITIONED|
-    unnest $$8 <- function-call: asterix:scan-collection, Args:[%0->$$41] -- |UNPARTITIONED|
-      group by ([$$60 := %0->$$42]) decor ([%0->$$54; %0->$$7; %0->$$14]) {
-                aggregate [$$41] <- [function-call: asterix:listify, Args:[%0->$$38]] -- |UNPARTITIONED|
-                  select (function-call: algebricks:not-null, Args:[%0->$$59]) -- |UNPARTITIONED|
+ After plan:
+distribute result [%0->$$13] -- |UNPARTITIONED|
+  project ([$$13]) -- |UNPARTITIONED|
+    assign [$$13] <- [function-call: asterix:open-record-constructor, Args:[AString: {cust}, %0->$$0, AString: {orders}, %0->$$12]] -- |UNPARTITIONED|
+      group by ([$$24 := %0->$$14]) decor ([%0->$$0; %0->$$18]) {
+                aggregate [$$12] <- [function-call: asterix:listify, Args:[%0->$$1]] -- |UNPARTITIONED|
+                  select (function-call: algebricks:not, Args:[function-call: algebricks:is-null, Args:[%0->$$23]]) -- |UNPARTITIONED|
                     nested tuple source -- |UNPARTITIONED|
              } -- |UNPARTITIONED|
-        left outer join (function-call: algebricks:eq, Args:[%0->$$42, %0->$$58]) -- |UNPARTITIONED|
-          assign [$$14] <- [function-call: asterix:field-access-by-index, Args:[%0->$$7, AInt32: {1}]] -- |UNPARTITIONED|
-            assign [$$54] <- [function-call: asterix:field-access-by-name, Args:[%0->$$7, AString: {subscription-id}]] -- |UNPARTITIONED|
-              data-scan []<-[$$42, $$7] <- emergencyTest:NearbySheltersDuringTornadoDangerChannelSubscriptions -- |UNPARTITIONED|
+        left outer join (function-call: algebricks:eq, Args:[%0->$$14, %0->$$22]) -- |UNPARTITIONED|
+          assign [$$18] <- [function-call: asterix:field-access-by-index, Args:[%0->$$0, AInt32: {3}]] -- |UNPARTITIONED|
+            data-scan []<-[$$14, $$0] <- tpch:Customers -- |UNPARTITIONED|
+              empty-tuple-source -- |UNPARTITIONED|
+          assign [$$23] <- [TRUE] -- |UNPARTITIONED|
+            join (function-call: algebricks:eq, Args:[%0->$$16, %0->$$22]) -- |UNPARTITIONED|
+              select (function-call: algebricks:eq, Args:[%0->$$20, AInt64: {5}]) -- |UNPARTITIONED|
+                assign [$$20] <- [function-call: asterix:field-access-by-index, Args:[%0->$$21, AInt32: {3}]] -- |UNPARTITIONED|
+                  data-scan []<-[$$22, $$21] <- tpch:Customers -- |UNPARTITIONED|
+                    empty-tuple-source -- |UNPARTITIONED|
+              assign [$$16] <- [function-call: asterix:field-access-by-name, Args:[%0->$$19, AString: {o_custkey}]] -- |UNPARTITIONED|
+                assign [$$19] <- [function-call: asterix:field-access-by-name, Args:[%0->$$1, AString: {o_$o}]] -- |UNPARTITIONED|
+                  data-scan []<-[$$15, $$1] <- tpch:Orders -- |UNPARTITIONED|
+                    empty-tuple-source -- |UNPARTITIONED|
+
+Special Cases
+For special cases where:
+a. there is a join (let's call it J1.) in the nested plan,
+b. if J1 is an inner join, one input pipeline of J1 has a NestedTupleSource descendant (let's call it N1),
+c. if J1 is a left outer join, the left branch of J1 has a NestedTupleSource descendant (let's call it N1),
+d. there is no tuple dropping from N1 to J1
+
+Rewriting R2 is not necessary since before J1, all tuples from N1 are preserved. But the following rewritings are needed:
+R1'. Replace N1 by the O1 (no additional deep copy);
+R2'. All inner joins on the path from N1 to J1 (including J1) become left-outer joins with the same join conditions;
+R3'. If N1 resides in the right branch of an inner join (let's call it J2) in the path from N1 to J1, switch the left and right branches of J2;
+R4'. For every left join from N1 to J1 transformed from an inner join, a variable vi indicating non-match tuples is assigned to TRUE in its right branch;
+R5'. On top of J1, a GroupByOperaptor G1 is added where the group-by key is the primary key of O1 and the nested query plan for aggregation is the nested pipeline
+     on top of J1 with an added not-null-filter to check all vi are not null.
+R6'. All other NestedTupleSourceOperators in the subplan is inlined with deep copies (with new variables) of the query plan rooted at O1.
+
+This is an abstract example for the special rewriting mechanism described above:
+Before rewriting:
+--Op1
+  --Subplan{
+    --AggregateOp
+      --NestedOp
+        – Inner Join (J1)
+          – (Right branch) ..... (L1)
+          – (Left branch) ..... (R1)
+                    --Nested-Tuple-Source
+    }
+    --InputOp
+      .....
+(Note that pipeline R1 must satisfy the condition that it does not drop any tuples.)
+After rewriting:
+-- Op1
+  – GroupBy v_lc_1, ..., v_lc_n Decor v_l1, ....v_ln {
+            – AggregateOp
+               – NestedOp
+                 – Select v_new!=NULL
+                   – Nested-Tuple-Source
+          }
+     --LeftOuterJoin (J1)
+       (left branch)
+              –  ......  (R1)
+                 – InputOp
+                   .....
+       (right branch)
+             – Assign v_new=TRUE
+                – ..... (L1)
+
+In the plan, v_lc_1, ..., v_lc_n are live "covering" variables at InputOp and v_l1, ....v_ln in the decoration part of the added group-by operator are all live variables
+at InputOp except the covering variables v_lc_1, ..., v_lc_n.  In the current implementation, we use "covering" variables as primary key variables. In the next version,
+we will use the real primary key variables, which will fix ASTERIXDB-1168.
+
+Here is a concrete example (optimizerts/queries/nested_loj2.aql). .
+Before plan:
+distribute result [%0->$$17] -- |UNPARTITIONED|
+  project ([$$17]) -- |UNPARTITIONED|
+    assign [$$17] <- [function-call: asterix:open-record-constructor, Args:[AString: {cust}, %0->$$0, AString: {orders}, %0->$$16]] -- |UNPARTITIONED|
+      subplan {
+                aggregate [$$16] <- [function-call: asterix:listify, Args:[%0->$$15]] -- |UNPARTITIONED|
+                  assign [$$15] <- [function-call: asterix:open-record-constructor, Args:[AString: {order}, %0->$$1, AString: {items}, %0->$$14]] -- |UNPARTITIONED|
+                    subplan {
+                              aggregate [$$14] <- [function-call: asterix:listify, Args:[%0->$$2]] -- |UNPARTITIONED|
+                                join (function-call: algebricks:eq, Args:[%0->$$20, %0->$$19]) -- |UNPARTITIONED|
+                                  nested tuple source -- |UNPARTITIONED|
+                                  data-scan []<-[$$20, $$21, $$2] <- tpch:LineItems -- |UNPARTITIONED|
+                                    empty-tuple-source -- |UNPARTITIONED|
+                           } -- |UNPARTITIONED|
+                      join (function-call: algebricks:eq, Args:[%0->$$22, %0->$$18]) -- |UNPARTITIONED|
+                        nested tuple source -- |UNPARTITIONED|
+                        assign [$$22] <- [function-call: asterix:field-access-by-index, Args:[%0->$$1, AInt32: {1}]] -- |UNPARTITIONED|
+                          data-scan []<-[$$19, $$1] <- tpch:Orders -- |UNPARTITIONED|
+                            empty-tuple-source -- |UNPARTITIONED|
+             } -- |UNPARTITIONED|
+        data-scan []<-[$$18, $$0] <- tpch:Customers -- |UNPARTITIONED|
+          empty-tuple-source -- |UNPARTITIONED|
+
+After plan:
+distribute result [%0->$$17] -- |UNPARTITIONED|
+  project ([$$17]) -- |UNPARTITIONED|
+    assign [$$17] <- [function-call: asterix:open-record-constructor, Args:[AString: {cust}, %0->$$0, AString: {orders}, %0->$$16]] -- |UNPARTITIONED|
+      group by ([$$30 := %0->$$18]) decor ([%0->$$0]) {
+                aggregate [$$16] <- [function-call: asterix:listify, Args:[%0->$$15]] -- |UNPARTITIONED|
+                  assign [$$15] <- [function-call: asterix:open-record-constructor, Args:[AString: {order}, %0->$$1, AString: {items}, %0->$$14]] -- |UNPARTITIONED|
+                    group by ([$$27 := %0->$$19]) decor ([%0->$$0; %0->$$1; %0->$$18; %0->$$22]) {
+                              aggregate [$$14] <- [function-call: asterix:listify, Args:[%0->$$2]] -- |UNPARTITIONED|
+                                select (function-call: algebricks:not, Args:[function-call: algebricks:is-null, Args:[%0->$$26]]) -- |UNPARTITIONED|
+                                  nested tuple source -- |UNPARTITIONED|
+                           } -- |UNPARTITIONED|
+                      select (function-call: algebricks:and, Args:[function-call: algebricks:not, Args:[function-call: algebricks:is-null, Args:[%0->$$28]], function-call: algebricks:not, Args:[function-call: algebricks:is-null, Args:[%0->$$29]]]) -- |UNPARTITIONED|
+                        nested tuple source -- |UNPARTITIONED|
+             } -- |UNPARTITIONED|
+        left outer join (function-call: algebricks:eq, Args:[%0->$$20, %0->$$19]) -- |UNPARTITIONED|
+          left outer join (function-call: algebricks:eq, Args:[%0->$$22, %0->$$18]) -- |UNPARTITIONED|
+            data-scan []<-[$$18, $$0] <- tpch:Customers -- |UNPARTITIONED|
+              empty-tuple-source -- |UNPARTITIONED|
+            assign [$$28] <- [TRUE] -- |UNPARTITIONED|
+              assign [$$22] <- [function-call: asterix:field-access-by-index, Args:[%0->$$1, AInt32: {1}]] -- |UNPARTITIONED|
+                data-scan []<-[$$19, $$1] <- tpch:Orders -- |UNPARTITIONED|
+                  empty-tuple-source -- |UNPARTITIONED|
+          assign [$$29] <- [TRUE] -- |UNPARTITIONED|
+            assign [$$26] <- [TRUE] -- |UNPARTITIONED|
+              data-scan []<-[$$20, $$21, $$2] <- tpch:LineItems -- |UNPARTITIONED|
                 empty-tuple-source -- |UNPARTITIONED|
-          assign [$$59] <- [TRUE] -- |UNPARTITIONED|
-            assign [$$38] <- [function-call: asterix:open-record-constructor, Args:[AString: {subscription-id}, %0->$$57, AString: {execution-time}, function-call: asterix:current-datetime, Args:[], AString: {result}, %0->$$19]] -- |UNPARTITIONED|
-              unnest $$19 <- function-call: asterix:scan-collection, Args:[%0->$$37] -- |UNPARTITIONED|
-                group by ([$$66 := %0->$$58]) decor ([%0->$$55; %0->$$56; %0->$$57]) {
-                          aggregate [$$37] <- [function-call: asterix:listify, Args:[%0->$$33]] -- |UNPARTITIONED|
-                            select (function-call: algebricks:not-null, Args:[%0->$$65]) -- |UNPARTITIONED|
-                              nested tuple source -- |UNPARTITIONED|
-                       } -- |UNPARTITIONED|
-                  left outer join (function-call: algebricks:eq, Args:[%0->$$58, %0->$$64]) -- |UNPARTITIONED|
-                    assign [$$55] <- [function-call: asterix:field-access-by-index, Args:[%0->$$56, AInt32: {1}]] -- |UNPARTITIONED|
-                      assign [$$57] <- [function-call: asterix:field-access-by-name, Args:[%0->$$56, AString: {subscription-id}]] -- |UNPARTITIONED|
-                        data-scan []<-[$$58, $$56] <- emergencyTest:NearbySheltersDuringTornadoDangerChannelSubscriptions -- |UNPARTITIONED|
-                          empty-tuple-source -- |UNPARTITIONED|
-                    assign [$$65] <- [TRUE] -- |UNPARTITIONED|
-                      join (TRUE) -- |UNPARTITIONED|
-                        select (%0->$$32) -- |UNPARTITIONED|
-                          group by ([$$16 := %0->$$47; $$43 := %0->$$48; $$15 := %0->$$49]) decor ([%0->$$62; %0->$$64; %0->$$61]) {
-                                    aggregate [$$32] <- [function-call: asterix:non-empty-stream, Args:[]] -- |UNPARTITIONED|
-                                      select (function-call: algebricks:not, Args:[function-call: algebricks:is-null, Args:[%0->$$46]]) -- |UNPARTITIONED|
-                                        nested tuple source -- |UNPARTITIONED|
-                                 } -- |UNPARTITIONED|
-                            left outer join (function-call: algebricks:and, Args:[function-call: algebricks:eq, Args:[%0->$$50, %0->$$61], function-call: asterix:spatial-intersect, Args:[%0->$$47, %0->$$53]]) -- |UNPARTITIONED|
-                              assign [$$47] <- [function-call: asterix:create-circle, Args:[%0->$$51, %0->$$52]] -- |UNPARTITIONED|
-                                assign [$$51] <- [function-call: asterix:field-access-by-index, Args:[%0->$$49, AInt32: {1}]] -- |UNPARTITIONED|
-                                  assign [$$52] <- [function-call: asterix:field-access-by-index, Args:[%0->$$49, AInt32: {2}]] -- |UNPARTITIONED|
-                                    data-scan []<-[$$48, $$49] <- emergencyTest:CHPReports -- |UNPARTITIONED|
-                                      assign [$$61] <- [function-call: asterix:field-access-by-index, Args:[%0->$$62, AInt32: {1}]] -- |UNPARTITIONED|
-                                        assign [$$63] <- [function-call: asterix:field-access-by-name, Args:[%0->$$62, AString: {subscription-id}]] -- |UNPARTITIONED|
-                                          data-scan []<-[$$64, $$62] <- emergencyTest:NearbySheltersDuringTornadoDangerChannelSubscriptions -- |UNPARTITIONED|
-                                            empty-tuple-source -- |UNPARTITIONED|
-                              assign [$$46] <- [TRUE] -- |UNPARTITIONED|
-                                assign [$$50] <- [function-call: asterix:field-access-by-index, Args:[%0->$$17, AInt32: {1}]] -- |UNPARTITIONED|
-                                  assign [$$53] <- [function-call: asterix:field-access-by-index, Args:[%0->$$17, AInt32: {2}]] -- |UNPARTITIONED|
-                                    data-scan []<-[$$44, $$17] <- emergencyTest:userLocations -- |UNPARTITIONED|
-                                      empty-tuple-source -- |UNPARTITIONED|
-                        assign [$$33] <- [function-call: asterix:open-record-constructor, Args:[AString: {shelter locations}, %0->$$36]] -- |UNPARTITIONED|
-                          aggregate [$$36] <- [function-call: asterix:listify, Args:[%0->$$35]] -- |UNPARTITIONED|
-                            assign [$$35] <- [function-call: asterix:field-access-by-index, Args:[%0->$$18, AInt32: {1}]] -- |UNPARTITIONED|
-                              data-scan []<-[$$45, $$18] <- emergencyTest:tornadoShelters -- |UNPARTITIONED|
-                                empty-tuple-source -- |UNPARTITIONED|
----------------------------------
- */
+*/
 public class InlineSubplanInputForNestedTupleSourceRule implements IAlgebraicRewriteRule {
 
     // To make sure the rule only runs once.
@@ -306,54 +279,82 @@
             // Traverses non-subplan operators.
             return traverseNonSubplanOperator(op, context);
         }
-
-        SubplanOperator subplanOp = (SubplanOperator) op;
-        if (!containsDataSourceScan(subplanOp)) {
-            // Traverses the operator as if it is not a subplan.
-            return traverseNonSubplanOperator(op, context);
+        /**
+         * Apply the special join-based rewriting.
+         */
+        Pair<Boolean, Map<LogicalVariable, LogicalVariable>> result = applySpecialFlattening(opRef, context);
+        if (!result.first) {
+            /**
+             * If the special join-based rewriting does not apply, apply the general
+             * rewriting which blindly inlines all NTSs.
+             */
+            result = applyGeneralFlattening(opRef, context);
         }
+        return result;
+    }
 
-        Mutable<ILogicalOperator> inputOpRef = op.getInputs().get(0);
+    /***
+     * Deals with operators that are not SubplanOperator.
+     *
+     * @param op
+     *            the operator to consider
+     * @param context
+     * @return
+     * @throws AlgebricksException
+     */
+    private Pair<Boolean, Map<LogicalVariable, LogicalVariable>> traverseNonSubplanOperator(ILogicalOperator op,
+            IOptimizationContext context) throws AlgebricksException {
+        Set<LogicalVariable> liveVars = new HashSet<>();
+        VariableUtilities.getLiveVariables(op, liveVars);
+        Map<LogicalVariable, LogicalVariable> replacedVarMap = new HashMap<LogicalVariable, LogicalVariable>();
+        Map<LogicalVariable, LogicalVariable> replacedVarMapForAncestor = new HashMap<LogicalVariable, LogicalVariable>();
+        boolean changed = false;
+        for (Mutable<ILogicalOperator> childrenRef : op.getInputs()) {
+            Pair<Boolean, Map<LogicalVariable, LogicalVariable>> resultFromChild = rewriteSubplanOperator(childrenRef,
+                    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());
+                }
+            }
+            replacedVarMap.putAll(resultFromChild.second);
+        }
+        VariableUtilities.substituteVariables(op, replacedVarMap, context);
+        context.computeAndSetTypeEnvironmentForOperator(op);
+        return new Pair<Boolean, Map<LogicalVariable, LogicalVariable>>(changed, replacedVarMapForAncestor);
+    }
+
+    private Pair<Boolean, Map<LogicalVariable, LogicalVariable>> applyGeneralFlattening(Mutable<ILogicalOperator> opRef,
+            IOptimizationContext context) throws AlgebricksException {
+        SubplanOperator subplanOp = (SubplanOperator) opRef.getValue();
+        if (!SubplanFlatteningUtil.containsOperators(subplanOp,
+                ImmutableSet.of(LogicalOperatorTag.DATASOURCESCAN, LogicalOperatorTag.INNERJOIN,
+                        // We don't have nested runtime for union-all and distinct hence we have to include them here.
+                        LogicalOperatorTag.LEFTOUTERJOIN, LogicalOperatorTag.UNIONALL, LogicalOperatorTag.DISTINCT))) {
+            // Traverses the operator as if it is not a subplan.
+            return traverseNonSubplanOperator(subplanOp, context);
+        }
+        Mutable<ILogicalOperator> inputOpRef = subplanOp.getInputs().get(0);
         ILogicalOperator inputOp = inputOpRef.getValue();
-        Map<LogicalVariable, LogicalVariable> varMap = inlineNestedTupleSource(subplanOp, inputOp, context);
+        Pair<Map<LogicalVariable, LogicalVariable>, List<Pair<IOrder, Mutable<ILogicalExpression>>>> varMapAndOrderExprs = SubplanFlatteningUtil
+                .inlineAllNestedTupleSource(subplanOp, context);
+        Map<LogicalVariable, LogicalVariable> varMap = varMapAndOrderExprs.first;
+        if (varMap == null) {
+            // Traverses the operator as if it is not a subplan.
+            return traverseNonSubplanOperator(subplanOp, context);
+        }
 
         // Creates parameters for the left outer join operator.
         Set<LogicalVariable> inputLiveVars = new HashSet<LogicalVariable>();
         VariableUtilities.getLiveVariables(inputOp, inputLiveVars);
-        PhysicalOptimizationsUtil.computeFDsAndEquivalenceClasses((AbstractLogicalOperator) inputOp, context);
-        List<FunctionalDependency> fds = context.getFDList(inputOp);
-        Set<LogicalVariable> fdCoveringVars = findFDHeaderVariables(fds, inputLiveVars);
+        Set<LogicalVariable> fdCoveringVars = EquivalenceClassUtils.findFDHeaderVariables(context, inputOp);
 
         Mutable<ILogicalOperator> rightInputOpRef = subplanOp.getNestedPlans().get(0).getRoots().get(0).getValue()
                 .getInputs().get(0);
         ILogicalOperator rightInputOp = rightInputOpRef.getValue();
 
-        Set<LogicalVariable> rightInputLiveVars = new HashSet<LogicalVariable>();
-        VariableUtilities.getLiveVariables(rightInputOp, rightInputLiveVars);
-        Set<LogicalVariable> rightMissingCoveringVars = new HashSet<>();
-        Set<LogicalVariable> varsToEnforce = new HashSet<>();
-        for (LogicalVariable liveVar : fdCoveringVars) {
-            LogicalVariable rightVar = varMap.get(liveVar);
-            if (!rightInputLiveVars.contains(rightVar)) {
-                // Some correlated variables killed in the subplan, therefore needs to be preserved in the subplan.
-                varsToEnforce.add(rightVar);
-                rightMissingCoveringVars.add(liveVar);
-            }
-        }
-        // Recovers killed-variables in leftVars in the query plan rooted at rightInputOp.
-        if (!varsToEnforce.isEmpty()) {
-            Map<LogicalVariable, LogicalVariable> map = VariableUtilities
-                    .enforceVariablesInDescendantsAndSelf(rightInputOpRef, varsToEnforce, context);
-            // Re-maps variables in the left input branch to the variables in the right input branch
-            for (LogicalVariable var : rightMissingCoveringVars) {
-                LogicalVariable rightVar = varMap.get(var);
-                LogicalVariable newVar = map.get(rightVar);
-                if (newVar != null) {
-                    varMap.put(var, newVar);
-                }
-            }
-        }
-
         // Creates a variable to indicate whether a left input tuple is killed in the plan rooted at rightInputOp.
         LogicalVariable assignVar = context.newVar();
         ILogicalOperator assignOp = new AssignOperator(assignVar,
@@ -390,10 +391,8 @@
         GroupByOperator groupbyOp = new GroupByOperator(groupByList, groupByDecorList, nestedPlans);
 
         Map<LogicalVariable, LogicalVariable> replacedVarMap = new HashMap<>();
-        Map<LogicalVariable, LogicalVariable> gbyVarMap = new HashMap<LogicalVariable, LogicalVariable>();
         for (LogicalVariable liveVar : fdCoveringVars) {
             LogicalVariable newVar = context.newVar();
-            gbyVarMap.put(liveVar, newVar);
             groupByList.add(new Pair<LogicalVariable, Mutable<ILogicalExpression>>(newVar,
                     new MutableObject<ILogicalExpression>(new VariableReferenceExpression(liveVar))));
             // Adds variables for replacements in ancestors.
@@ -411,6 +410,15 @@
         Mutable<ILogicalOperator> aggOpRef = subplanOp.getNestedPlans().get(0).getRoots().get(0);
         aggOpRef.getValue().getInputs().clear();
 
+        Mutable<ILogicalOperator> currentOpRef = aggOpRef;
+        // Adds an optional order operator.
+        List<Pair<IOrder, Mutable<ILogicalExpression>>> orderExprs = varMapAndOrderExprs.second;
+        if (!orderExprs.isEmpty()) {
+            OrderOperator orderOp = new OrderOperator(orderExprs);
+            currentOpRef = new MutableObject<ILogicalOperator>(orderOp);
+            aggOpRef.getValue().getInputs().add(currentOpRef);
+        }
+
         // Adds a select operator into the nested plan for group-by to remove tuples with NULL on {@code assignVar}, i.e.,
         // subplan input tuples that are filtered out within a subplan.
         Mutable<ILogicalExpression> filterVarExpr = new MutableObject<ILogicalExpression>(
@@ -424,7 +432,7 @@
                 new MutableObject<ILogicalExpression>(new ScalarFunctionCallExpression(
                         FunctionUtil.getFunctionInfo(AsterixBuiltinFunctions.NOT), argsForNotFunction)),
                 false, null);
-        aggOpRef.getValue().getInputs().add(new MutableObject<ILogicalOperator>(selectOp));
+        currentOpRef.getValue().getInputs().add(new MutableObject<ILogicalOperator>(selectOp));
 
         selectOp.getInputs().add(new MutableObject<ILogicalOperator>(
                 new NestedTupleSourceOperator(new MutableObject<ILogicalOperator>(groupbyOp))));
@@ -432,181 +440,97 @@
         nestedRoots.add(aggOpRef);
         nestedPlans.add(new ALogicalPlanImpl(nestedRoots));
         groupbyOp.getInputs().add(new MutableObject<ILogicalOperator>(leftOuterJoinOp));
-        OperatorManipulationUtil.computeTypeEnvironmentBottomUp(aggOpRef.getValue(), context);
 
         // Replaces subplan with the group-by operator.
         opRef.setValue(groupbyOp);
-        context.computeAndSetTypeEnvironmentForOperator(groupbyOp);
+        OperatorManipulationUtil.computeTypeEnvironmentBottomUp(groupbyOp, context);
 
         // Recursively applys this rule to the nested plan of the subplan operator,
         // for the case where there are nested subplan operators within {@code subplanOp}.
-        // Note that we do not need to use the resulting variable map to further replace variables,
-        // because rightInputOp must be an aggregate operator which kills all incoming variables.
-        traverseNonSubplanOperator(rightInputOp, context);
+        Pair<Boolean, Map<LogicalVariable, LogicalVariable>> result = rewriteSubplanOperator(rightInputOpRef, context);
+        VariableUtilities.substituteVariables(leftOuterJoinOp, result.second, context);
+        VariableUtilities.substituteVariables(groupbyOp, result.second, context);
+
+        // No var mapping from the right input operator should be populated up.
         return new Pair<Boolean, Map<LogicalVariable, LogicalVariable>>(true, replacedVarMap);
     }
 
-    /**
-     * @param subplanOp
-     *            a SubplanOperator
-     * @return whether there is a data source scan in the nested logical plans of {@code subplanOp}.
-     */
-    private boolean containsDataSourceScan(SubplanOperator subplanOp) {
-        List<ILogicalPlan> nestedPlans = subplanOp.getNestedPlans();
-        for (ILogicalPlan nestedPlan : nestedPlans) {
-            for (Mutable<ILogicalOperator> opRef : nestedPlan.getRoots()) {
-                if (containsDataScanInDescendantsAndSelf(opRef.getValue())) {
-                    return true;
-                }
-            }
-        }
-        return false;
-    }
-
-    /**
-     * Whether the query plan rooted {@code currentOp} contains a data source scan operator,
-     * with considering nested subplans.
-     *
-     * @param currentOp
-     *            the current operator
-     * @return true if {@code currentOp} contains a data source scan operator; false otherwise.
-     */
-    private boolean containsDataScanInDescendantsAndSelf(ILogicalOperator currentOp) {
-        if (currentOp.getOperatorTag() == LogicalOperatorTag.DATASOURCESCAN) {
-            return true;
-        }
-        if (currentOp.getOperatorTag() == LogicalOperatorTag.SUBPLAN) {
-            if (containsDataSourceScan((SubplanOperator) currentOp)) {
-                return true;
-            }
-        }
-        for (Mutable<ILogicalOperator> childRef : currentOp.getInputs()) {
-            if (containsDataScanInDescendantsAndSelf(childRef.getValue())) {
-                return true;
-            }
-        }
-        return false;
-    }
-
-    /**
-     * Find the header variables that can imply all the variables in {@code liveVars}
-     *
-     * @param fds,
-     *            a list of functional dependencies
-     * @param liveVars,
-     *            a set of live variables
-     * @return a set of covering variables that can imply all live variables.
-     */
-    private Set<LogicalVariable> findFDHeaderVariables(List<FunctionalDependency> fds, Set<LogicalVariable> liveVars) {
-        Set<LogicalVariable> key = new HashSet<>();
-        Set<LogicalVariable> cover = new HashSet<>();
-        for (FunctionalDependency fd : fds) {
-            key.addAll(fd.getHead());
-            cover.addAll(fd.getTail());
-        }
-        if (cover.equals(liveVars)) {
-            return key;
-        } else {
-            return liveVars;
-        }
-    }
-
-    /***
-     * Deals with operators that are not SubplanOperator.
-     *
-     * @param op
-     *            the operator to consider
-     * @param context
-     * @return
-     * @throws AlgebricksException
-     */
-    private Pair<Boolean, Map<LogicalVariable, LogicalVariable>> traverseNonSubplanOperator(ILogicalOperator op,
+    private Pair<Boolean, Map<LogicalVariable, LogicalVariable>> applySpecialFlattening(Mutable<ILogicalOperator> opRef,
             IOptimizationContext context) throws AlgebricksException {
+        SubplanOperator subplanOp = (SubplanOperator) opRef.getValue();
+        ILogicalOperator inputOp = subplanOp.getInputs().get(0).getValue();
+        Map<LogicalVariable, LogicalVariable> replacedVarMap = new HashMap<>();
+
+        // Recursively applies this rule to the nested plan of the subplan operator,
+        // for the case where there are nested subplan operators within {@code subplanOp}.
+        Pair<Boolean, Map<LogicalVariable, LogicalVariable>> result = rewriteSubplanOperator(
+                subplanOp.getNestedPlans().get(0).getRoots().get(0), context);
+
+        Pair<Set<LogicalVariable>, Mutable<ILogicalOperator>> notNullVarsAndTopJoinRef = SubplanFlatteningUtil
+                .inlineLeftNtsInSubplanJoin(subplanOp, context);
+        if (notNullVarsAndTopJoinRef.first == null) {
+            return new Pair<Boolean, Map<LogicalVariable, LogicalVariable>>(false, replacedVarMap);
+        }
+
+        Set<LogicalVariable> notNullVars = notNullVarsAndTopJoinRef.first;
+        Mutable<ILogicalOperator> topJoinRef = notNullVarsAndTopJoinRef.second;
+
+        // Gets live variables and covering variables from the subplan's input operator.
+        Set<LogicalVariable> fdCoveringVars = EquivalenceClassUtils.findFDHeaderVariables(context, inputOp);
         Set<LogicalVariable> liveVars = new HashSet<>();
-        VariableUtilities.getLiveVariables(op, liveVars);
-        Map<LogicalVariable, LogicalVariable> replacedVarMap = new HashMap<LogicalVariable, LogicalVariable>();
-        Map<LogicalVariable, LogicalVariable> replacedVarMapForAncestor = new HashMap<LogicalVariable, LogicalVariable>();
-        boolean changed = false;
-        for (Mutable<ILogicalOperator> childrenRef : op.getInputs()) {
-            Pair<Boolean, Map<LogicalVariable, LogicalVariable>> resultFromChild = rewriteSubplanOperator(childrenRef,
-                    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());
-                }
+        VariableUtilities.getLiveVariables(inputOp, liveVars);
+
+        // Creates a group-by operator.
+        List<Pair<LogicalVariable, Mutable<ILogicalExpression>>> groupByList = new ArrayList<Pair<LogicalVariable, Mutable<ILogicalExpression>>>();
+        List<Pair<LogicalVariable, Mutable<ILogicalExpression>>> groupByDecorList = new ArrayList<Pair<LogicalVariable, Mutable<ILogicalExpression>>>();
+        GroupByOperator groupbyOp = new GroupByOperator(groupByList, groupByDecorList, subplanOp.getNestedPlans());
+
+        Map<LogicalVariable, LogicalVariable> gbyVarMap = new HashMap<LogicalVariable, LogicalVariable>();
+        for (LogicalVariable coverVar : fdCoveringVars) {
+            LogicalVariable newVar = context.newVar();
+            gbyVarMap.put(coverVar, newVar);
+            groupByList.add(new Pair<LogicalVariable, Mutable<ILogicalExpression>>(newVar,
+                    new MutableObject<ILogicalExpression>(new VariableReferenceExpression(coverVar))));
+            // Adds variables for replacements in ancestors.
+            replacedVarMap.put(coverVar, newVar);
+        }
+        for (LogicalVariable liveVar : liveVars) {
+            if (fdCoveringVars.contains(liveVar)) {
+                continue;
             }
-            replacedVarMap.putAll(resultFromChild.second);
+            groupByDecorList.add(new Pair<LogicalVariable, Mutable<ILogicalExpression>>(null,
+                    new MutableObject<ILogicalExpression>(new VariableReferenceExpression(liveVar))));
         }
-        for (Map.Entry<LogicalVariable, LogicalVariable> entry : replacedVarMap.entrySet()) {
-            VariableUtilities.substituteVariables(op, entry.getKey(), entry.getValue(), context);
-        }
-        context.computeAndSetTypeEnvironmentForOperator(op);
-        return new Pair<Boolean, Map<LogicalVariable, LogicalVariable>>(changed, replacedVarMapForAncestor);
-    }
+        groupbyOp.getInputs().add(new MutableObject<ILogicalOperator>(topJoinRef.getValue()));
 
-    /**
-     * Inline a subplan's input to replace the NTSs.
-     *
-     * @param subplanOp
-     *            the subplan operator
-     * @param inputOperator
-     *            the input operator to the subplan
-     * @param context
-     *            the optimization context
-     * @return a map that maps from the variables propagated in {@code inputOperator} to the variables
-     *         defined in the deeply copied query plan.
-     * @throws AlgebricksException
-     */
-    private Map<LogicalVariable, LogicalVariable> inlineNestedTupleSource(SubplanOperator subplanOp,
-            ILogicalOperator inputOperator, IOptimizationContext context) throws AlgebricksException {
-        List<ILogicalPlan> nestedPlans = subplanOp.getNestedPlans();
-        Map<LogicalVariable, LogicalVariable> varMap = new HashMap<LogicalVariable, LogicalVariable>();
-        for (ILogicalPlan plan : nestedPlans) {
-            List<Mutable<ILogicalOperator>> roots = plan.getRoots();
-            for (Mutable<ILogicalOperator> root : roots) {
-                varMap.putAll(replaceNestedTupleSource(root, inputOperator, context));
-            }
+        // Adds a select operator into the nested plan for group-by to remove tuples with NULL on {@code assignVar}, i.e.,
+        // subplan input tuples that are filtered out within a subplan.
+        List<Mutable<ILogicalExpression>> nullCheckExprRefs = new ArrayList<>();
+        for (LogicalVariable notNullVar : notNullVars) {
+            Mutable<ILogicalExpression> filterVarExpr = new MutableObject<ILogicalExpression>(
+                    new VariableReferenceExpression(notNullVar));
+            List<Mutable<ILogicalExpression>> args = new ArrayList<Mutable<ILogicalExpression>>();
+            args.add(filterVarExpr);
+            List<Mutable<ILogicalExpression>> argsForNotFunction = new ArrayList<Mutable<ILogicalExpression>>();
+            argsForNotFunction.add(new MutableObject<ILogicalExpression>(new ScalarFunctionCallExpression(
+                    FunctionUtil.getFunctionInfo(AsterixBuiltinFunctions.IS_NULL), args)));
+            nullCheckExprRefs.add(new MutableObject<ILogicalExpression>(new ScalarFunctionCallExpression(
+                    FunctionUtil.getFunctionInfo(AsterixBuiltinFunctions.NOT), argsForNotFunction)));
         }
-        return varMap;
-    }
+        Mutable<ILogicalExpression> selectExprRef = nullCheckExprRefs.size() > 1
+                ? new MutableObject<ILogicalExpression>(new ScalarFunctionCallExpression(
+                        FunctionUtil.getFunctionInfo(AsterixBuiltinFunctions.AND), nullCheckExprRefs))
+                : nullCheckExprRefs.get(0);
+        SelectOperator selectOp = new SelectOperator(selectExprRef, false, null);
+        topJoinRef.setValue(selectOp);
+        selectOp.getInputs().add(new MutableObject<ILogicalOperator>(
+                new NestedTupleSourceOperator(new MutableObject<ILogicalOperator>(groupbyOp))));
 
-    /**
-     * Deep copy the query plan rooted at {@code inputOperator} and replace NTS with the copied plan.
-     *
-     * @param currentInputOpRef,
-     *            the current operator within a subplan
-     * @param inputOperator,
-     *            the input operator to the subplan
-     * @param context
-     *            the optimization context
-     * @return a map that maps from the variables propagated in {@code inputOperator} to the variables
-     *         defined in the deeply copied query plan.
-     * @throws AlgebricksException
-     */
-    private Map<LogicalVariable, LogicalVariable> replaceNestedTupleSource(Mutable<ILogicalOperator> currentInputOpRef,
-            ILogicalOperator inputOperator, IOptimizationContext context) throws AlgebricksException {
-        AbstractLogicalOperator currentOp = (AbstractLogicalOperator) currentInputOpRef.getValue();
-        if (currentOp.getOperatorTag() == LogicalOperatorTag.NESTEDTUPLESOURCE) {
-            LogicalOperatorDeepCopyWithNewVariablesVisitor deepCopyVisitor = new LogicalOperatorDeepCopyWithNewVariablesVisitor(
-                    context);
-            ILogicalOperator copiedInputOperator = deepCopyVisitor.deepCopy(inputOperator, inputOperator);
-            // Updates the primary key info in the copied plan segment.
-            context.updatePrimaryKeys(deepCopyVisitor.getInputToOutputVariableMapping());
-            currentInputOpRef.setValue(copiedInputOperator);
-            return deepCopyVisitor.getInputToOutputVariableMapping();
-        }
-        // Obtains the variable mapping from child.
-        Map<LogicalVariable, LogicalVariable> varMap = new HashMap<LogicalVariable, LogicalVariable>();
-        for (Mutable<ILogicalOperator> child : currentOp.getInputs()) {
-            varMap.putAll(replaceNestedTupleSource(child, inputOperator, context));
-        }
-        // Substitutes variables in the query plan rooted at currentOp.
-        for (Map.Entry<LogicalVariable, LogicalVariable> entry : varMap.entrySet()) {
-            VariableUtilities.substituteVariables(currentOp, entry.getKey(), entry.getValue(), context);
-        }
-        return varMap;
-    }
+        opRef.setValue(groupbyOp);
+        OperatorManipulationUtil.computeTypeEnvironmentBottomUp(groupbyOp, context);
 
+        VariableUtilities.substituteVariables(groupbyOp, result.second, context);
+        replacedVarMap.putAll(result.second);
+        return new Pair<Boolean, Map<LogicalVariable, LogicalVariable>>(true, replacedVarMap);
+    }
 }
diff --git a/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/subplan/SubplanFlatteningUtil.java b/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/subplan/SubplanFlatteningUtil.java
new file mode 100644
index 0000000..6d91923
--- /dev/null
+++ b/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/subplan/SubplanFlatteningUtil.java
@@ -0,0 +1,203 @@
+/*
+ * 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.
+ */
+package org.apache.asterix.optimizer.rules.subplan;
+
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import org.apache.commons.lang3.mutable.Mutable;
+import org.apache.hyracks.algebricks.common.exceptions.AlgebricksException;
+import org.apache.hyracks.algebricks.common.utils.Pair;
+import org.apache.hyracks.algebricks.core.algebra.base.ILogicalExpression;
+import org.apache.hyracks.algebricks.core.algebra.base.ILogicalOperator;
+import org.apache.hyracks.algebricks.core.algebra.base.ILogicalPlan;
+import org.apache.hyracks.algebricks.core.algebra.base.IOptimizationContext;
+import org.apache.hyracks.algebricks.core.algebra.base.LogicalOperatorTag;
+import org.apache.hyracks.algebricks.core.algebra.base.LogicalVariable;
+import org.apache.hyracks.algebricks.core.algebra.operators.logical.OrderOperator.IOrder;
+import org.apache.hyracks.algebricks.core.algebra.operators.logical.SubplanOperator;
+import org.apache.hyracks.algebricks.core.algebra.operators.logical.visitors.VariableUtilities;
+import org.apache.hyracks.algebricks.core.algebra.util.OperatorManipulationUtil;
+
+import com.google.common.collect.ImmutableSet;
+
+class SubplanFlatteningUtil {
+
+    /**
+     * Blindly inline all NTS's in a Subplan operator.
+     *
+     * @param subplanOp,
+     *            the subplan operator
+     * @param context
+     * @return a map that maps primary key variables in the subplan's input to its deep copies
+     *         in the nested pipeline; the ordering that needs to be maintained for the final
+     *         aggregation in the added group-by operator.
+     * @throws AlgebricksException
+     */
+    public static Pair<Map<LogicalVariable, LogicalVariable>, List<Pair<IOrder, Mutable<ILogicalExpression>>>> inlineAllNestedTupleSource(
+            SubplanOperator subplanOp, IOptimizationContext context) throws AlgebricksException {
+        // For nested subplan, we do not continue for the general inlining.
+        if (OperatorManipulationUtil.ancestorOfOperators(subplanOp,
+                ImmutableSet.of(LogicalOperatorTag.NESTEDTUPLESOURCE))) {
+            return new Pair<Map<LogicalVariable, LogicalVariable>, List<Pair<IOrder, Mutable<ILogicalExpression>>>>(
+                    null, null);
+        }
+        InlineAllNtsInSubplanVisitor visitor = new InlineAllNtsInSubplanVisitor(context, subplanOp);
+
+        // Rewrites the query plan.
+        ILogicalOperator topOp = subplanOp.getNestedPlans().get(0).getRoots().get(0).getValue();
+        ILogicalOperator opToVisit = topOp.getInputs().get(0).getValue();
+        ILogicalOperator result = opToVisit.accept(visitor, null);
+        topOp.getInputs().get(0).setValue(result);
+
+        // Substitute variables in topOp if necessary.
+        VariableUtilities.substituteVariables(topOp, visitor.getVariableMapHistory(), context);
+
+        // Gets ordering variables.
+        List<Pair<IOrder, Mutable<ILogicalExpression>>> orderVars = visitor.getOrderingExpressions();
+        return new Pair<Map<LogicalVariable, LogicalVariable>, List<Pair<IOrder, Mutable<ILogicalExpression>>>>(
+                visitor.getInputVariableToOutputVariableMap(), orderVars);
+    }
+
+    /**
+     * Inline the left NTS in a subplan that satisfies a special condition indicated
+     * by canFlattenSubplanJoinRuleFire(...).
+     *
+     * @param subplanOp
+     *            the SubplanOperator
+     * @param context
+     *            the optimization context
+     * @return A set of variables used for further null-checks, i.e., variables indicating
+     *         whether a tuple produced by a transformed left outer join is a non-match;
+     *         a reference to the top join operator in the nested subplan.
+     * @throws AlgebricksException
+     */
+    public static Pair<Set<LogicalVariable>, Mutable<ILogicalOperator>> inlineLeftNtsInSubplanJoin(
+            SubplanOperator subplanOp, IOptimizationContext context) throws AlgebricksException {
+        Pair<Boolean, ILogicalOperator> applicableAndNtsToRewrite = SubplanFlatteningUtil
+                .isQualifiedForSpecialFlattening(subplanOp);
+        if (!applicableAndNtsToRewrite.first) {
+            return new Pair<Set<LogicalVariable>, Mutable<ILogicalOperator>>(null, null);
+        }
+
+        ILogicalOperator qualifiedNts = applicableAndNtsToRewrite.second;
+        ILogicalOperator subplanInputOp = subplanOp.getInputs().get(0).getValue();
+        InlineLeftNtsInSubplanJoinFlatteningVisitor specialVisitor = new InlineLeftNtsInSubplanJoinFlatteningVisitor(
+                context, subplanInputOp, qualifiedNts);
+
+        // Rewrites the query plan.
+        Mutable<ILogicalOperator> topRef = subplanOp.getNestedPlans().get(0).getRoots().get(0);
+        ILogicalOperator result = topRef.getValue().accept(specialVisitor, null); // The special visitor doesn't replace any input or local variables.
+        Mutable<ILogicalOperator> topJoinRef = specialVisitor.getTopJoinReference();
+        topRef.setValue(result);
+
+        // Inline the rest Nts's as general cases.
+        InlineAllNtsInSubplanVisitor generalVisitor = new InlineAllNtsInSubplanVisitor(context, subplanOp);
+        ILogicalOperator opToVisit = topJoinRef.getValue();
+        result = opToVisit.accept(generalVisitor, null);
+        topJoinRef.setValue(result);
+
+        // Substitute variables in nested pipeline above the top join operator in the nested pipeline if necessary.
+        List<Pair<LogicalVariable, LogicalVariable>> subplanLocalVarMap = generalVisitor.getVariableMapHistory();
+        ILogicalOperator currentOp = topRef.getValue();
+        while (currentOp != result) {
+            VariableUtilities.substituteVariables(currentOp, subplanLocalVarMap, context);
+            currentOp = currentOp.getInputs().get(0).getValue();
+        }
+        return new Pair<Set<LogicalVariable>, Mutable<ILogicalOperator>>(specialVisitor.getNullCheckVariables(),
+                topJoinRef);
+    }
+
+    /**
+     * @param subplanOp
+     *            a SubplanOperator
+     * @return whether there is a data source scan in the nested logical plans of {@code subplanOp}.
+     */
+    public static boolean containsOperators(SubplanOperator subplanOp, Set<LogicalOperatorTag> interestedOperatorTags) {
+        List<ILogicalPlan> nestedPlans = subplanOp.getNestedPlans();
+        for (ILogicalPlan nestedPlan : nestedPlans) {
+            for (Mutable<ILogicalOperator> opRef : nestedPlan.getRoots()) {
+                if (containsOperatorsInternal(opRef.getValue(), interestedOperatorTags)) {
+                    return true;
+                }
+            }
+        }
+        return false;
+    }
+
+    /**
+     * Determine whether a subplan could be rewritten as a join-related special case.
+     * The conditions include:
+     * a. there is a join (let's call it J1.) in the nested plan,
+     * b. if J1 is an inner join, one input pipeline of J1 has a NestedTupleSource descendant (let's call it N1),
+     * c. if J1 is a left outer join, the left branch of J1 has a NestedTupleSource descendant (let's call it N1),
+     * d. there is no tuple dropping from N1 to J1.
+     *
+     * @param subplanOp,
+     *            the SubplanOperator to consider
+     * @return TRUE if the rewriting is applicable; FALSE otherwise.
+     * @throws AlgebricksException
+     */
+    private static Pair<Boolean, ILogicalOperator> isQualifiedForSpecialFlattening(SubplanOperator subplanOp)
+            throws AlgebricksException {
+        if (!OperatorManipulationUtil.ancestorOfOperators(
+                subplanOp.getNestedPlans().get(0).getRoots().get(0).getValue(),
+                // we don't need to check recursively for this special rewriting.
+                ImmutableSet.of(LogicalOperatorTag.INNERJOIN, LogicalOperatorTag.LEFTOUTERJOIN))) {
+            return new Pair<Boolean, ILogicalOperator>(false, null);
+        }
+        SubplanSpecialFlatteningCheckVisitor visitor = new SubplanSpecialFlatteningCheckVisitor();
+        for (ILogicalPlan plan : subplanOp.getNestedPlans()) {
+            for (Mutable<ILogicalOperator> opRef : plan.getRoots()) {
+                if (!opRef.getValue().accept(visitor, null)) {
+                    return new Pair<Boolean, ILogicalOperator>(false, null);
+                }
+            }
+        }
+        return new Pair<Boolean, ILogicalOperator>(true, visitor.getQualifiedNts());
+    }
+
+    /**
+     * Whether the query plan rooted {@code currentOp} contains a data source scan operator,
+     * with considering nested subplans.
+     *
+     * @param currentOp
+     *            the current operator
+     * @return true if {@code currentOp} contains a data source scan operator; false otherwise.
+     */
+    private static boolean containsOperatorsInternal(ILogicalOperator currentOp,
+            Set<LogicalOperatorTag> interestedOperatorTags) {
+        if (interestedOperatorTags.contains(currentOp.getOperatorTag())) {
+            return true;
+        }
+        if (currentOp.getOperatorTag() == LogicalOperatorTag.SUBPLAN) {
+            if (containsOperators((SubplanOperator) currentOp, interestedOperatorTags)) {
+                return true;
+            }
+        }
+        for (Mutable<ILogicalOperator> childRef : currentOp.getInputs()) {
+            if (containsOperatorsInternal(childRef.getValue(), interestedOperatorTags)) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+}
diff --git a/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/subplan/SubplanSpecialFlatteningCheckVisitor.java b/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/subplan/SubplanSpecialFlatteningCheckVisitor.java
new file mode 100644
index 0000000..1a2e8bb
--- /dev/null
+++ b/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/subplan/SubplanSpecialFlatteningCheckVisitor.java
@@ -0,0 +1,269 @@
+/*
+ * 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.
+ */
+package org.apache.asterix.optimizer.rules.subplan;
+
+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.operators.logical.AggregateOperator;
+import org.apache.hyracks.algebricks.core.algebra.operators.logical.AssignOperator;
+import org.apache.hyracks.algebricks.core.algebra.operators.logical.DataSourceScanOperator;
+import org.apache.hyracks.algebricks.core.algebra.operators.logical.DistinctOperator;
+import org.apache.hyracks.algebricks.core.algebra.operators.logical.EmptyTupleSourceOperator;
+import org.apache.hyracks.algebricks.core.algebra.operators.logical.ExchangeOperator;
+import org.apache.hyracks.algebricks.core.algebra.operators.logical.ExtensionOperator;
+import org.apache.hyracks.algebricks.core.algebra.operators.logical.ExternalDataLookupOperator;
+import org.apache.hyracks.algebricks.core.algebra.operators.logical.GroupByOperator;
+import org.apache.hyracks.algebricks.core.algebra.operators.logical.InnerJoinOperator;
+import org.apache.hyracks.algebricks.core.algebra.operators.logical.LeftOuterJoinOperator;
+import org.apache.hyracks.algebricks.core.algebra.operators.logical.LimitOperator;
+import org.apache.hyracks.algebricks.core.algebra.operators.logical.MaterializeOperator;
+import org.apache.hyracks.algebricks.core.algebra.operators.logical.NestedTupleSourceOperator;
+import org.apache.hyracks.algebricks.core.algebra.operators.logical.OrderOperator;
+import org.apache.hyracks.algebricks.core.algebra.operators.logical.OuterUnnestOperator;
+import org.apache.hyracks.algebricks.core.algebra.operators.logical.PartitioningSplitOperator;
+import org.apache.hyracks.algebricks.core.algebra.operators.logical.ProjectOperator;
+import org.apache.hyracks.algebricks.core.algebra.operators.logical.ReplicateOperator;
+import org.apache.hyracks.algebricks.core.algebra.operators.logical.RunningAggregateOperator;
+import org.apache.hyracks.algebricks.core.algebra.operators.logical.ScriptOperator;
+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.TokenizeOperator;
+import org.apache.hyracks.algebricks.core.algebra.operators.logical.UnionAllOperator;
+import org.apache.hyracks.algebricks.core.algebra.operators.logical.UnnestMapOperator;
+import org.apache.hyracks.algebricks.core.algebra.operators.logical.UnnestOperator;
+import org.apache.hyracks.algebricks.core.algebra.visitors.IQueryOperatorVisitor;
+
+/**
+ * This visitor determines whether a nested subplan in a SubplanOperator could be rewritten as
+ * a join-related special case.
+ * The conditions include:
+ * a. there is a join (let's call it J1.) in the nested plan,
+ * b. if J1 is an inner join, one input pipeline of J1 has a NestedTupleSource descendant (let's call it N1),
+ * c. if J1 is a left outer join, the left branch of J1 has a NestedTupleSource descendant (let's call it N1),
+ * d. there is no tuple dropping from N1 to J1.
+ */
+class SubplanSpecialFlatteningCheckVisitor implements IQueryOperatorVisitor<Boolean, Void> {
+    // Accept with an assumption that there doesn't exist an ancestor operator like J1 of the visiting
+    // tuple discarding or cardinality reducing operator.
+    // That is, a tuple discarding or cardinality operator like SelectOperator could not be
+    // on the path from N1 to J1, but could be on top of J1.
+    // For instance, during the post order visiting, if we hit a SelectOperator, we set rejectPending
+    // bit to be true, and later if we backtrack to J1 which is an ancestor of N1, we think the path
+    // from N1 to J1 is not valid because condition d is not met.
+    // Then we reset rejectPending to false and traverse another child of J1.
+    private boolean rejectPending = false;
+
+    // The qualified NTS to be replaced.
+    private ILogicalOperator qualifiedNtsOp;
+
+    public ILogicalOperator getQualifiedNts() {
+        return qualifiedNtsOp;
+    }
+
+    @Override
+    public Boolean visitAggregateOperator(AggregateOperator op, Void arg) throws AlgebricksException {
+        return visitCardinalityReduceOperator(op);
+    }
+
+    @Override
+    public Boolean visitRunningAggregateOperator(RunningAggregateOperator op, Void arg) throws AlgebricksException {
+        return visitCardinalityReduceOperator(op);
+    }
+
+    @Override
+    public Boolean visitEmptyTupleSourceOperator(EmptyTupleSourceOperator op, Void arg) throws AlgebricksException {
+        return false;
+    }
+
+    @Override
+    public Boolean visitGroupByOperator(GroupByOperator op, Void arg) throws AlgebricksException {
+        return visitCardinalityReduceOperator(op);
+    }
+
+    @Override
+    public Boolean visitLimitOperator(LimitOperator op, Void arg) throws AlgebricksException {
+        return visitTupleDiscardingOperator(op);
+    }
+
+    @Override
+    public Boolean visitInnerJoinOperator(InnerJoinOperator op, Void arg) throws AlgebricksException {
+        for (Mutable<ILogicalOperator> childRef : op.getInputs()) {
+            if (childRef.getValue().accept(this, null) && !rejectPending) {
+                return true;
+            }
+            rejectPending = false;
+        }
+        return false;
+    }
+
+    @Override
+    public Boolean visitLeftOuterJoinOperator(LeftOuterJoinOperator op, Void arg) throws AlgebricksException {
+        // Check whether the left branch is a qualified branch.
+        boolean isLeftBranchQualified = op.getInputs().get(0).getValue().accept(this, null);
+        return !rejectPending && isLeftBranchQualified;
+    }
+
+    @Override
+    public Boolean visitNestedTupleSourceOperator(NestedTupleSourceOperator op, Void arg) throws AlgebricksException {
+        qualifiedNtsOp = op;
+        return true;
+    }
+
+    @Override
+    public Boolean visitOrderOperator(OrderOperator op, Void arg) throws AlgebricksException {
+        return visitInputs(op);
+    }
+
+    @Override
+    public Boolean visitAssignOperator(AssignOperator op, Void arg) throws AlgebricksException {
+        return visitInputs(op);
+    }
+
+    @Override
+    public Boolean visitSelectOperator(SelectOperator op, Void arg) throws AlgebricksException {
+        return visitTupleDiscardingOperator(op);
+    }
+
+    @Override
+    public Boolean visitExtensionOperator(ExtensionOperator op, Void arg) throws AlgebricksException {
+        return false;
+    }
+
+    @Override
+    public Boolean visitProjectOperator(ProjectOperator op, Void arg) throws AlgebricksException {
+        return visitInputs(op);
+    }
+
+    @Override
+    public Boolean visitPartitioningSplitOperator(PartitioningSplitOperator op, Void arg) throws AlgebricksException {
+        return false;
+    }
+
+    @Override
+    public Boolean visitReplicateOperator(ReplicateOperator op, Void arg) throws AlgebricksException {
+        return visitInputs(op);
+    }
+
+    @Override
+    public Boolean visitMaterializeOperator(MaterializeOperator op, Void arg) throws AlgebricksException {
+        return visitInputs(op);
+    }
+
+    @Override
+    public Boolean visitScriptOperator(ScriptOperator op, Void arg) throws AlgebricksException {
+        return false;
+    }
+
+    @Override
+    public Boolean visitSubplanOperator(SubplanOperator op, Void arg) throws AlgebricksException {
+        return visitInputs(op);
+    }
+
+    @Override
+    public Boolean visitUnionOperator(UnionAllOperator op, Void arg) throws AlgebricksException {
+        // Flattening with an Union Operator in the pipeline will perturb the query semantics,
+        // e.g., the result cardinality can change.
+        return false;
+    }
+
+    @Override
+    public Boolean visitUnnestOperator(UnnestOperator op, Void arg) throws AlgebricksException {
+        return visitInputs(op);
+    }
+
+    @Override
+    public Boolean visitOuterUnnestOperator(OuterUnnestOperator op, Void arg) throws AlgebricksException {
+        return visitInputs(op);
+    }
+
+    @Override
+    public Boolean visitUnnestMapOperator(UnnestMapOperator op, Void arg) throws AlgebricksException {
+        return false;
+    }
+
+    @Override
+    public Boolean visitDataScanOperator(DataSourceScanOperator op, Void arg) throws AlgebricksException {
+        return false;
+    }
+
+    @Override
+    public Boolean visitDistinctOperator(DistinctOperator op, Void arg) throws AlgebricksException {
+        return visitInputs(op);
+    }
+
+    @Override
+    public Boolean visitExchangeOperator(ExchangeOperator op, Void arg) throws AlgebricksException {
+        return visitInputs(op);
+    }
+
+    @Override
+    public Boolean visitExternalDataLookupOperator(ExternalDataLookupOperator op, Void arg) throws AlgebricksException {
+        return visitInputs(op);
+    }
+
+    @Override
+    public Boolean visitTokenizeOperator(TokenizeOperator op, Void arg) throws AlgebricksException {
+        return visitInputs(op);
+    }
+
+    private boolean visitInputs(ILogicalOperator op) throws AlgebricksException {
+        for (Mutable<ILogicalOperator> childRef : op.getInputs()) {
+            if (childRef.getValue().accept(this, null)) {
+                // One input is qualified.
+                return true;
+            }
+        }
+        // All inputs are disqualified.
+        return false;
+    }
+
+    /**
+     * If an operator reduces its input cardinality, the operator should not be a descendant
+     * of a join operator.
+     *
+     * @param op,
+     *            the operator to consider
+     * @return FALSE if it is certainly disqualified; TRUE otherwise.
+     * @throws AlgebricksException
+     */
+    private Boolean visitCardinalityReduceOperator(ILogicalOperator op) throws AlgebricksException {
+        return visitTupleDiscardingOrCardinalityReduceOperator(op);
+    }
+
+    /**
+     * If an operator discard tuples variables before the join, the query's
+     * semantics cannot be preserved after applying the <code>FlatternSubplanJoinRule</code> rule.
+     *
+     * @param op,
+     *            the operator to consider
+     * @return FALSE if it is certainly disqualified; TRUE otherwise.
+     * @throws AlgebricksException
+     */
+    private Boolean visitTupleDiscardingOperator(ILogicalOperator op) throws AlgebricksException {
+        return visitTupleDiscardingOrCardinalityReduceOperator(op);
+    }
+
+    private boolean visitTupleDiscardingOrCardinalityReduceOperator(ILogicalOperator op) throws AlgebricksException {
+        boolean result = visitInputs(op);
+        rejectPending = true;
+        return result;
+    }
+
+}
diff --git a/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/util/EquivalenceClassUtils.java b/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/util/EquivalenceClassUtils.java
index 7b29ba3..9f98da0 100644
--- a/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/util/EquivalenceClassUtils.java
+++ b/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/util/EquivalenceClassUtils.java
@@ -20,8 +20,10 @@
 package org.apache.asterix.optimizer.rules.util;
 
 import java.util.HashMap;
+import java.util.HashSet;
 import java.util.List;
 import java.util.Map;
+import java.util.Set;
 
 import org.apache.asterix.common.config.DatasetConfig.DatasetType;
 import org.apache.asterix.lang.common.util.FunctionUtil;
@@ -31,6 +33,8 @@
 import org.apache.asterix.om.constants.AsterixConstantValue;
 import org.apache.asterix.om.functions.AsterixBuiltinFunctions;
 import org.apache.asterix.om.types.ARecordType;
+import org.apache.asterix.om.types.ATypeTag;
+import org.apache.asterix.om.types.IAType;
 import org.apache.commons.lang3.mutable.MutableObject;
 import org.apache.hyracks.algebricks.common.exceptions.AlgebricksException;
 import org.apache.hyracks.algebricks.core.algebra.base.EquivalenceClass;
@@ -39,8 +43,13 @@
 import org.apache.hyracks.algebricks.core.algebra.base.IOptimizationContext;
 import org.apache.hyracks.algebricks.core.algebra.base.LogicalVariable;
 import org.apache.hyracks.algebricks.core.algebra.expressions.ConstantExpression;
+import org.apache.hyracks.algebricks.core.algebra.expressions.IVariableTypeEnvironment;
 import org.apache.hyracks.algebricks.core.algebra.expressions.ScalarFunctionCallExpression;
 import org.apache.hyracks.algebricks.core.algebra.expressions.VariableReferenceExpression;
+import org.apache.hyracks.algebricks.core.algebra.operators.logical.AbstractLogicalOperator;
+import org.apache.hyracks.algebricks.core.algebra.operators.logical.visitors.VariableUtilities;
+import org.apache.hyracks.algebricks.core.algebra.properties.FunctionalDependency;
+import org.apache.hyracks.algebricks.rewriter.util.PhysicalOptimizationsUtil;
 import org.mortbay.util.SingletonList;
 
 public class EquivalenceClassUtils {
@@ -99,4 +108,51 @@
         }
     }
 
+    /**
+     * Find the header variables that can imply all subplan-local live variables at <code>operator</code>.
+     *
+     * @param context
+     *            the optimization context.
+     * @param operator
+     *            the operator of interest.
+     * @return a set of covering variables that can imply all subplan-local live variables at <code>operator</code>.
+     * @throws AlgebricksException
+     */
+    public static Set<LogicalVariable> findFDHeaderVariables(IOptimizationContext context, ILogicalOperator operator)
+            throws AlgebricksException {
+        PhysicalOptimizationsUtil.computeFDsAndEquivalenceClasses((AbstractLogicalOperator) operator, context);
+        List<FunctionalDependency> fds = context.getFDList(operator);
+        context.clearAllFDAndEquivalenceClasses();
+
+        Set<LogicalVariable> liveVars = new HashSet<>();
+        VariableUtilities.getSubplanLocalLiveVariables(operator, liveVars);
+
+        Set<LogicalVariable> key = new HashSet<>();
+        Set<LogicalVariable> cover = new HashSet<>();
+        for (FunctionalDependency fd : fds) {
+            List<LogicalVariable> head = fd.getHead();
+            head.retainAll(liveVars);
+            key.addAll(head);
+            cover.addAll(fd.getTail());
+            if (cover.containsAll(liveVars)) {
+                return key;
+            }
+        }
+        if (cover.containsAll(liveVars)) {
+            return key;
+        } else {
+            IVariableTypeEnvironment env = context.getOutputTypeEnvironment(operator);
+            Set<LogicalVariable> keyVars = new HashSet<>();
+            for (LogicalVariable var : liveVars) {
+                IAType type = (IAType) env.getVarType(var);
+                ATypeTag typeTag = type.getTypeTag();
+                if (typeTag == ATypeTag.RECORD || typeTag == ATypeTag.ORDEREDLIST
+                        || typeTag == ATypeTag.UNORDEREDLIST) {
+                    continue;
+                }
+                keyVars.add(var);
+            }
+            return keyVars;
+        }
+    }
 }
diff --git a/asterix-app/data/restaurants/restaurants.adm b/asterix-app/data/restaurants/restaurants.adm
new file mode 100644
index 0000000..b78b1eb
--- /dev/null
+++ b/asterix-app/data/restaurants/restaurants.adm
@@ -0,0 +1,30 @@
+{"restr_id":1,"name":"Pat Urban Seoul","address":"82750 Alton Pkwy, Irvine, CA, 926069","bank_account":{"bank_account_number":"32950130","bank_account_routing_number":"65924556"},"last_bank_transaction_datetime":datetime("2015-01-01T01:11:01"),"cuisine": {{"American","Mexican"}},"dish":{{{"name":"japchae mari","price":6.5,"spiciness":"mild"},{"name":"kalbi burger","price":7.95,"spiciness":"medium"},{"name":"tacos","price":7.5,"spiciness":"spicy"}}}}
+{"restr_id":2,"name":"Dan Urban Plates","address":"993972 Barranca Pkwy, Irvine, CA, 926059","bank_account":{"bank_account_number":"17516590","bank_account_routing_number":"30884916"},"last_bank_transaction_datetime":datetime("2015-01-02T02:22:02"),"cuisine": {{"Asian","Indian","Mexican"}},"dish":{{{"name":"grilled free range chicken","price":10.5,"spiciness":"mild"},{"name":"grilled steak","price":10.5,"spiciness":"mild"},{"name":"oven baked salmon","price":12.5,"spiciness":"medium"}}}}
+{"restr_id":3,"name":"Ken Fish Grill","address":"953988 Barranca Pkwy, Irvine, CA, 926078","bank_account":{"bank_account_number":"9388590","bank_account_routing_number":"56145494"},"last_bank_transaction_datetime":datetime("2015-01-03T03:33:03"),"cuisine": {{"Italian","Mexican"}},"dish":{{{"name":"salmon","price":13,"spiciness":"mild"},{"name":"skewered shrimp","price":10.99,"spiciness":"spicy"},{"name":"swordfish","price":11.5,"spiciness":"hot"}}}}
+{"restr_id":4,"name":"Ric Miyabi Shabu Shabu Grill","address":"9815435 Jeffrey Rd, Irvine, CA, 926187","bank_account":{"bank_account_number":"56327360","bank_account_routing_number":"61424929"},"last_bank_transaction_datetime":datetime("2015-01-04T04:04:04"),"cuisine": {{"French","Greek"}},"dish":{{{"name":"seafood salad","price":12,"spiciness":"spicy"},{"name":"surf and turf","price":23.99,"spiciness":"hot"},{"name":"wafu steak","price":14,"spiciness":"medium"}}}}
+{"restr_id":5,"name":"Sar Tang 190","address":"194218 Jeffrey Rd, Irvine, CA, 926549","bank_account":{"bank_account_number":"87322850","bank_account_routing_number":"44025237"},"last_bank_transaction_datetime":datetime("2015-01-05T05:55:05"),"cuisine": {{"French","Greek","Italian"}},"dish":{{{"name":"galbitang","price":16,"spiciness":"mild"},{"name":"samgyetang","price":29.99,"spiciness":"mild"},{"name":"yukgejang","price":12.99,"spiciness":"hot"}}}}
+{"restr_id":6,"name":"Ann Falasophy","address":"541923 Construction Circle, Irvine, CA, 926732","bank_account":{"bank_account_number":"35467220","bank_account_routing_number":"23185287"},"last_bank_transaction_datetime":datetime("2015-01-06T06:06:06"),"cuisine": {{"American"}},"dish":{{{"name":"hummus","price":13.99,"spiciness":"medium"},{"name":"the burger combo","price":32.99,"spiciness":"mild"},{"name":"the karma burger","price":18,"spiciness":"hot"}}}}
+{"restr_id":7,"name":"Nat Sandwich Plus","address":"435216 Technology Dr, Irvine, CA, 926431","bank_account":{"bank_account_number":"65395040","bank_account_routing_number":"50065148"},"last_bank_transaction_datetime":datetime("2015-01-07T07:07:07"),"cuisine": {{"American","French"}},"dish":{{{"name":"fresh lemonade","price":12.99,"spiciness":"mild"},{"name":"sandwich","price":16.99,"spiciness":"medium"},{"name":"the thai wrap","price":13,"spiciness":"spicy"}}}}
+{"restr_id":8,"name":"Rom Del Sushi","address":"994243 Campus Dr, Irvine, CA, 924325","bank_account":{"bank_account_number":"60621020","bank_account_routing_number":"61365342"},"last_bank_transaction_datetime":datetime("2015-01-08T08:08:08"),"cuisine": {{"Asian"}},"dish":{{{"name":"alioi spanish","price":19,"spiciness":"mild"},{"name":"bacon relish","price":35.5,"spiciness":"mild"},{"name":"burger","price":11.99,"spiciness":"medium"}}}}
+{"restr_id":9,"name":"Kri Dhaba","address":"952231 Michelson Dr, Irvine, CA, 926652","bank_account":{"bank_account_number":"89295710","bank_account_routing_number":"39904539"},"last_bank_transaction_datetime":datetime("2015-01-09T09:09:09"),"cuisine": {{"Indian"}},"dish":{{{"name":"seafood salad","price":17.99,"spiciness":"mild"},{"name":"sesame chicken","price":11,"spiciness":"medium"},{"name":"tempura","price":31.5,"spiciness":"mild"}}}}
+{"restr_id":10,"name":"Nor Kingchops","address":"914463 Culver Dr, Irvine, CA, 924553","bank_account":{"bank_account_number":"79909840","bank_account_routing_number":"68885206"},"last_bank_transaction_datetime":datetime("2015-01-10T10:10:10"),"cuisine": {{"Italian"}},"dish":{{{"name":"grilled steak","price":49,"spiciness":"mild"},{"name":"king prawn","price":97.1,"spiciness":"spicy"},{"name":"wafu steak","price":19.99,"spiciness":"mild"}}}}
+{"restr_id":11,"name":"Der Houstons","address":"1592603 Main Street, Ste. 500, Irvine, CA, 92614-426199","bank_account":{"bank_account_number":"92426610","bank_account_routing_number":"9075440"},"last_bank_transaction_datetime":datetime("2015-01-11T11:11:11"),"cuisine": {{"American","Greek"}},"dish":{{{"name":"sausage parmigiana","price":12.99,"spiciness":"spicy"}}}}
+{"restr_id":12,"name":"Ker Bistango","address":"15926131 Marguerite Parkway, Ste. D, Mission Viejo, CA, 92692-316199","bank_account":{"bank_account_number":"1959940","bank_account_routing_number":"58385183"},"last_bank_transaction_datetime":datetime("2015-01-12T12:12:12"),"cuisine": {{"American"}},"dish":{{{"name":"new york sub","price":7.99,"spiciness":"medium"}}}}
+{"restr_id":13,"name":"Ley Cucina","address":"15927261 Las Ramblas, Ste. 100, Mission Viejo, CA, 92691-646999","bank_account":{"bank_account_number":"33804760","bank_account_routing_number":"29614916"},"last_bank_transaction_datetime":datetime("2015-01-13T13:13:13"),"cuisine": {{"Italian"}},"dish":{{{"name":"steak sub","price":9.99,"spiciness":"mild"}}}}
+{"restr_id":14,"name":"Rno Fukad","address":"15927405 Puerta Real, Ste. 300, Mission Viejo, CA, 92691-637299","bank_account":{"bank_account_number":"68611710","bank_account_routing_number":"92495517"},"last_bank_transaction_datetime":datetime("2015-01-14T14:14:14"),"cuisine": {{"Italian"}},"dish":{{{"name":"reuben rye sandwich","price":15,"spiciness":"hot"}}}}
+{"restr_id":15,"name":"Ith Javie","address":"15931 Creek Road, Irvine, CA, 92604-479399","bank_account":{"bank_account_number":"31211090","bank_account_routing_number":"46484716"},"last_bank_transaction_datetime":datetime("2015-01-15T15:15:15"),"cuisine": {{"Italian"}},"dish":{{{"name":"hamburger with bacon","price":16.99,"spiciness":"mild"}}}}
+{"restr_id":16,"name":"Ano Argio","address":"15999 Creek Road, Irvine, CA, 92604-479999","bank_account":{"bank_account_number":"18498880","bank_account_routing_number":"23744539"},"last_bank_transaction_datetime":datetime("2015-01-16T16:16:16"),"cuisine": {{"American","Italian"}},"dish":{{{"name":"spaghetti with meat sauce","price":12.56,"spiciness":"medium"}}}}
+{"restr_id":17,"name":"Lly taik","address":"15932565 Golden Lantern St., Dana Point, CA, 9262999","bank_account":{"bank_account_number":"56305920","bank_account_routing_number":"47715504"},"last_bank_transaction_datetime":datetime("2015-01-17T17:17:17"),"cuisine": {{"Italian"}},"dish":{{{"name":"lasagna","price":16.99,"spiciness":"medium"}}}}
+{"restr_id":18,"name":"Man Opaq","address":"15937654 Savi Ranch Pkwy, Ste 997, Yorba Linda, CA, 92887-465667","bank_account":{"bank_account_number":"44661670","bank_account_routing_number":"63635569"},"last_bank_transaction_datetime":datetime("2015-01-18T18:18:18"),"cuisine": {{"Greek"}},"dish":{{{"name":"original greek Salad","price":13.2,"spiciness":"medium"}}}}
+{"restr_id":19,"name":"Aig craspe","address":"1592301 Dupont Dr., Suite 100, Irvine, CA, 9261899","bank_account":{"bank_account_number":"99783460","bank_account_routing_number":"49415430"},"last_bank_transaction_datetime":datetime("2015-01-19T19:19:19"),"cuisine": {{"Italian"}},"dish":{{{"name":"french fries","price":8.99,"spiciness":"medium"}}}}
+{"restr_id":20,"name":"Ise stonefire","address":"15923046 Avenida De La Carlota, Ste. 700, Laguna Hills, CA, 92653-153799","bank_account":{"bank_account_number":"7548730","bank_account_routing_number":"90615152"},"last_bank_transaction_datetime":datetime("2015-01-20T20:20:20"),"cuisine": {{"French"}},"dish":{{{"name":"onion rings","price":9.99,"spiciness":"mild"}}}}
+{"restr_id":21,"name":"Ble Tok tab","address":"15923282 Mill Creek Drive, Ste. 320, Laguna Hills, CA, 92653-793499","bank_account":{"bank_account_number":"87847330","bank_account_routing_number":"65094485"},"last_bank_transaction_datetime":datetime("2015-01-21T21:21:21"),"cuisine": {{"American","Asian"}},"dish":{{{"name":"new york cheesecake","price":25.99,"spiciness":"mild"}}}}
+{"restr_id":22,"name":"Bam Tha","address":"15923726 Birtcher Drive, Lake Forest, CA, 92630-177199","bank_account":{"bank_account_number":"86375230","bank_account_routing_number":"67315334"},"last_bank_transaction_datetime":datetime("2015-01-22T22:22:22"),"cuisine": {{"Asian"}},"dish":{{{"name":"bagel with butter","price":8.99,"spiciness":"mild"}}}}
+{"restr_id":23,"name":"Nye Boilin","address":"15925 Christamon West, Irvine, CA, 92620-183699","bank_account":{"bank_account_number":"86131150","bank_account_routing_number":"62284556"},"last_bank_transaction_datetime":datetime("2015-01-23T23:23:23"),"cuisine": {{"Italian"}},"dish":{{{"name":"bacon egg sandwich","price":17.99,"spiciness":"mild"}}}}
+{"restr_id":24,"name":"Ate Diplo","address":"4181 Spectrum Pointe Drive, Ste. 320, Lake Forest, CA, 92630-228899","bank_account":{"bank_account_number":"22531750","bank_account_routing_number":"74935196"},"last_bank_transaction_datetime":datetime("2015-01-24T23:24:24"),"cuisine": {{"American"}},"dish":{{{"name":"cheese omelette","price":19.99,"spiciness":"medium"}}}}
+{"restr_id":25,"name":"Afo Seafood","address":"4181 Watermarke Place, Irvine, CA, 92612-168199","bank_account":{"bank_account_number":"51669650","bank_account_routing_number":"42245203"},"last_bank_transaction_datetime":datetime("2015-01-25T01:01:01"),"cuisine": {{"American","Italian"}},"dish":{{{"name":"pancake","price":9.99,"spiciness":"mild"}}}}
+{"restr_id":26,"name":"Cit Spicy","address":"4181290 North Hancock Street, Ste. 103, Anaheim, CA, 92807-198299","bank_account":{"bank_account_number":"9201320","bank_account_routing_number":"504716"},"last_bank_transaction_datetime":datetime("2015-01-26T02:02:02"),"cuisine": {{"Italian"}},"dish":{{{"name":"chicken panini","price":17.99,"spiciness":"medium"}}}}
+{"restr_id":27,"name":"Las Dishes","address":"41814780 Pipeline Avenue, Chino Hills, CA, 91709-602999","bank_account":{"bank_account_number":"62914740","bank_account_routing_number":"73125298"},"last_bank_transaction_datetime":datetime("2015-01-27T03:03:03"),"cuisine": {{"Greek"}},"dish":{{{"name":"steak burrito","price":8.99,"spiciness":"mild"}}}}
+{"restr_id":28,"name":"Gar Chiden","address":"41814851 Jeffrey Road, Spc. 187, Irvine, CA, 92618-818799","bank_account":{"bank_account_number":"27611090","bank_account_routing_number":"70924532"},"last_bank_transaction_datetime":datetime("2015-01-28T04:04:04"),"cuisine": {{"Italian"}},"dish":{{{"name":"cheese steak","price":25.99,"spiciness":"mild"}}}}
+{"restr_id":29,"name":"55 Done","address":"41815241 Laguna Canyon Road, Irvine, CA, 9261899","bank_account":{"bank_account_number":"58660700","bank_account_routing_number":"8695163"},"last_bank_transaction_datetime":datetime("2015-01-29T05:05:05"),"cuisine": {{"American"}},"dish":{{{"name":"vegetable burger","price":12.99,"spiciness":"mild"}}}}
+{"restr_id":30,"name":"Grill Park","address":"4181536 East Warner Avenue, Ste. A, Santa Ana, CA, 92705-547499","bank_account":{"bank_account_number":"32345240","bank_account_routing_number":"15765455"},"last_bank_transaction_datetime":datetime("2015-01-30T06:06:06"),"cuisine": {{"French"}},"dish":{{{"name":"bibim bap","price":15.99,"spiciness":"spicy"}}}}
\ No newline at end of file
diff --git a/asterix-app/src/test/resources/optimizerts/queries/nested_loj2.aql b/asterix-app/src/test/resources/optimizerts/queries/nested_loj2.aql
index 43c2722..f7504ad 100644
--- a/asterix-app/src/test/resources/optimizerts/queries/nested_loj2.aql
+++ b/asterix-app/src/test/resources/optimizerts/queries/nested_loj2.aql
@@ -88,4 +88,4 @@
 return {
   "cust": $c,
   "orders": $orders
-}  
+}
diff --git a/asterix-app/src/test/resources/optimizerts/queries/nested_loj3.aql b/asterix-app/src/test/resources/optimizerts/queries/nested_loj3.aql
index b9494a0..2deac67 100644
--- a/asterix-app/src/test/resources/optimizerts/queries/nested_loj3.aql
+++ b/asterix-app/src/test/resources/optimizerts/queries/nested_loj3.aql
@@ -107,4 +107,4 @@
 return {
   "cust": $c,
   "orders": $orders
-}  
+}
diff --git a/asterix-app/src/test/resources/optimizerts/queries/nested_loj4.aql b/asterix-app/src/test/resources/optimizerts/queries/nested_loj4.aql
new file mode 100644
index 0000000..7b6c014
--- /dev/null
+++ b/asterix-app/src/test/resources/optimizerts/queries/nested_loj4.aql
@@ -0,0 +1,79 @@
+/*
+ * 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 tpch if exists;
+create dataverse tpch;
+use dataverse tpch;
+
+create type LineItemType as closed {
+  l_orderkey: int32,
+  l_partkey: int32,
+  l_suppkey: int32,
+  l_linenumber: int32,
+  l_quantity: double,
+  l_extendedprice: double,
+  l_discount: double,
+  l_tax: double,
+  l_returnflag: string,
+  l_linestatus: string,
+  l_shipdate: string,
+  l_commitdate: string,
+  l_receiptdate: string,
+  l_shipinstruct: string,
+  l_shipmode: string,
+  l_comment: string
+}
+
+create type OrderType as closed {
+  o_orderkey: int32,
+  o_custkey: int32,
+  o_orderstatus: string,
+  o_totalprice: double,
+  o_orderdate: string,
+  o_orderpriority: string,
+  o_clerk: string,
+  o_shippriority: int32,
+  o_comment: string
+}
+
+create type CustomerType as closed {
+  c_custkey: int32,
+  c_name: string,
+  c_address: string,
+  c_nationkey: int32,
+  c_phone: string,
+  c_acctbal: double,
+  c_mktsegment: string,
+  c_comment: string
+}
+
+create dataset Orders(OrderType)
+  primary key o_orderkey;
+create dataset Customers(CustomerType)
+  primary key c_custkey;
+
+for $c in dataset('Customers')
+let $orders :=
+  for $o in dataset('Orders')
+  where $c.c_nationkey = 5 and $o.o_$o.o_custkey = $c.c_custkey
+  return $o
+return {
+  "cust": $c,
+  "orders": $orders
+}
diff --git a/asterix-app/src/test/resources/optimizerts/queries/query-ASTERIXDB-1005.aql b/asterix-app/src/test/resources/optimizerts/queries/query-ASTERIXDB-1005.aql
new file mode 100644
index 0000000..98cd634
--- /dev/null
+++ b/asterix-app/src/test/resources/optimizerts/queries/query-ASTERIXDB-1005.aql
@@ -0,0 +1,59 @@
+/*
+ * 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.
+ */
+/*
+ * Description     : This test case is to verify the fix for ASTERIXDB-1005
+ * https://issues.apache.org/jira/browse/ASTERIXDB-1005
+ * Expected Result : Success
+ * Date            : 10th January 2016
+ */
+
+drop dataverse deliber if exists;
+create dataverse deliber;
+use dataverse deliber;
+
+// Dish served by a restaurant
+create type DishesType as open
+{ name: string, price: double }
+
+// Bank account type
+create type BankAccountType as open{
+ bank_account_number: string,
+ bank_account_routing_number: string
+}
+
+// Restaurant's information
+create type RestaurantsType as open {
+restr_id: int64,
+name: string,
+address: string,
+bank_account: BankAccountType,
+last_bank_transaction_datetime: datetime,
+cuisine: {{ string }},
+dish: {{ DishesType }}
+}
+
+// Creating datasets for Users, Restaurants, and Orders
+create dataset Restaurants(RestaurantsType)
+primary key restr_id;
+
+for $r in dataset Restaurants
+where some $c in $r.cuisine satisfies $c = "Mexican" or $c = "Italian"
+order by $r.name
+return
+{"name":$r.name, "cuisines":$r.cuisine}
\ No newline at end of file
diff --git a/asterix-app/src/test/resources/optimizerts/queries/query-ASTERIXDB-1263.aql b/asterix-app/src/test/resources/optimizerts/queries/query-ASTERIXDB-1263.aql
new file mode 100644
index 0000000..c3cb9bf
--- /dev/null
+++ b/asterix-app/src/test/resources/optimizerts/queries/query-ASTERIXDB-1263.aql
@@ -0,0 +1,53 @@
+/*
+ * 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 TinySocial if exists;
+create dataverse TinySocial;
+use dataverse TinySocial;
+
+create type TwitterUserType as open {
+        screen-name: string,
+        lang: string,
+        friends_count: int64,
+        statuses_count: int64,
+        name: string,
+        followers_count: int64
+}
+
+create type TweetMessageType as closed {
+        tweetid: string,
+        user: TwitterUserType,
+        sender-location: point?,
+        send-time: datetime,
+        referred-topics: {{ string }},
+        message-text: string
+}
+
+create dataset TweetMessages(TweetMessageType)
+primary key tweetid;
+
+for $t in dataset TweetMessages
+group by $d:= get-hour($t.send-time) with $t
+return { "hour": $d,
+         "count": count($t),
+         "finer":  for $k in $t
+                   group by $min:= get-minute($k.create_at) with $k
+                   order by $min
+                   return {  "minute": $min, "sum": count($k)}
+}
diff --git a/asterix-app/src/test/resources/optimizerts/results/btree-index-join/leftouterjoin-probe-pidx-with-join-btree-sidx_01.plan b/asterix-app/src/test/resources/optimizerts/results/btree-index-join/leftouterjoin-probe-pidx-with-join-btree-sidx_01.plan
index 2baebd4..b96830c 100644
--- a/asterix-app/src/test/resources/optimizerts/results/btree-index-join/leftouterjoin-probe-pidx-with-join-btree-sidx_01.plan
+++ b/asterix-app/src/test/resources/optimizerts/results/btree-index-join/leftouterjoin-probe-pidx-with-join-btree-sidx_01.plan
@@ -2,36 +2,33 @@
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
     -- STREAM_PROJECT  |PARTITIONED|
       -- ASSIGN  |PARTITIONED|
-        -- STREAM_PROJECT  |PARTITIONED|
-          -- SORT_MERGE_EXCHANGE [$$28(ASC) ]  |PARTITIONED|
-            -- STABLE_SORT [$$28(ASC)]  |PARTITIONED|
-              -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                -- PRE_CLUSTERED_GROUP_BY[$$24]  |PARTITIONED|
-                        {
-                          -- AGGREGATE  |LOCAL|
-                            -- STREAM_SELECT  |LOCAL|
-                              -- NESTED_TUPLE_SOURCE  |LOCAL|
-                        }
-                  -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                    -- STABLE_SORT [$$24(ASC), $$21(ASC)]  |PARTITIONED|
-                      -- HASH_PARTITION_EXCHANGE [$$24]  |PARTITIONED|
-                        -- STREAM_SELECT  |PARTITIONED|
-                          -- STREAM_PROJECT  |PARTITIONED|
-                            -- ASSIGN  |PARTITIONED|
-                              -- STREAM_PROJECT  |PARTITIONED|
-                                -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                  -- BTREE_SEARCH  |PARTITIONED|
-                                    -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                      -- STABLE_SORT [$$36(ASC)]  |PARTITIONED|
-                                        -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                          -- STREAM_PROJECT  |PARTITIONED|
-                                            -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                              -- BTREE_SEARCH  |PARTITIONED|
-                                                -- BROADCAST_EXCHANGE  |PARTITIONED|
-                                                  -- STREAM_PROJECT  |PARTITIONED|
-                                                    -- ASSIGN  |PARTITIONED|
-                                                      -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                        -- BTREE_SEARCH  |PARTITIONED|
-                                                          -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                            -- ASSIGN  |PARTITIONED|
-                                                              -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+        -- SORT_MERGE_EXCHANGE [$$29(ASC) ]  |PARTITIONED|
+          -- PRE_CLUSTERED_GROUP_BY[$$20]  |PARTITIONED|
+                  {
+                    -- AGGREGATE  |LOCAL|
+                      -- STREAM_SELECT  |LOCAL|
+                        -- NESTED_TUPLE_SOURCE  |LOCAL|
+                  }
+            -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+              -- STABLE_SORT [$$20(ASC), $$21(ASC)]  |PARTITIONED|
+                -- HASH_PARTITION_EXCHANGE [$$20]  |PARTITIONED|
+                  -- STREAM_SELECT  |PARTITIONED|
+                    -- STREAM_PROJECT  |PARTITIONED|
+                      -- ASSIGN  |PARTITIONED|
+                        -- STREAM_PROJECT  |PARTITIONED|
+                          -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                            -- BTREE_SEARCH  |PARTITIONED|
+                              -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                -- STABLE_SORT [$$34(ASC)]  |PARTITIONED|
+                                  -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                    -- STREAM_PROJECT  |PARTITIONED|
+                                      -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                        -- BTREE_SEARCH  |PARTITIONED|
+                                          -- BROADCAST_EXCHANGE  |PARTITIONED|
+                                            -- STREAM_PROJECT  |PARTITIONED|
+                                              -- ASSIGN  |PARTITIONED|
+                                                -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                  -- BTREE_SEARCH  |PARTITIONED|
+                                                    -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                      -- ASSIGN  |PARTITIONED|
+                                                        -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterix-app/src/test/resources/optimizerts/results/btree-index-join/leftouterjoin-probe-pidx-with-join-btree-sidx_02.plan b/asterix-app/src/test/resources/optimizerts/results/btree-index-join/leftouterjoin-probe-pidx-with-join-btree-sidx_02.plan
index 84619bc..07fde95 100644
--- a/asterix-app/src/test/resources/optimizerts/results/btree-index-join/leftouterjoin-probe-pidx-with-join-btree-sidx_02.plan
+++ b/asterix-app/src/test/resources/optimizerts/results/btree-index-join/leftouterjoin-probe-pidx-with-join-btree-sidx_02.plan
@@ -2,36 +2,33 @@
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
     -- STREAM_PROJECT  |PARTITIONED|
       -- ASSIGN  |PARTITIONED|
-        -- STREAM_PROJECT  |PARTITIONED|
-          -- SORT_MERGE_EXCHANGE [$$33(ASC) ]  |PARTITIONED|
-            -- STABLE_SORT [$$33(ASC)]  |PARTITIONED|
-              -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                -- PRE_CLUSTERED_GROUP_BY[$$29]  |PARTITIONED|
-                        {
-                          -- AGGREGATE  |LOCAL|
-                            -- STREAM_SELECT  |LOCAL|
-                              -- NESTED_TUPLE_SOURCE  |LOCAL|
-                        }
-                  -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                    -- STABLE_SORT [$$29(ASC), $$25(ASC)]  |PARTITIONED|
-                      -- HASH_PARTITION_EXCHANGE [$$29]  |PARTITIONED|
-                        -- STREAM_SELECT  |PARTITIONED|
-                          -- STREAM_PROJECT  |PARTITIONED|
-                            -- ASSIGN  |PARTITIONED|
-                              -- STREAM_PROJECT  |PARTITIONED|
-                                -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                  -- BTREE_SEARCH  |PARTITIONED|
-                                    -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                      -- STABLE_SORT [$$41(ASC)]  |PARTITIONED|
-                                        -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                          -- STREAM_PROJECT  |PARTITIONED|
-                                            -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                              -- BTREE_SEARCH  |PARTITIONED|
-                                                -- BROADCAST_EXCHANGE  |PARTITIONED|
-                                                  -- STREAM_PROJECT  |PARTITIONED|
-                                                    -- ASSIGN  |PARTITIONED|
-                                                      -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                        -- BTREE_SEARCH  |PARTITIONED|
-                                                          -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                            -- ASSIGN  |PARTITIONED|
-                                                              -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+        -- SORT_MERGE_EXCHANGE [$$34(ASC) ]  |PARTITIONED|
+          -- PRE_CLUSTERED_GROUP_BY[$$24]  |PARTITIONED|
+                  {
+                    -- AGGREGATE  |LOCAL|
+                      -- STREAM_SELECT  |LOCAL|
+                        -- NESTED_TUPLE_SOURCE  |LOCAL|
+                  }
+            -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+              -- STABLE_SORT [$$24(ASC), $$25(ASC)]  |PARTITIONED|
+                -- HASH_PARTITION_EXCHANGE [$$24]  |PARTITIONED|
+                  -- STREAM_SELECT  |PARTITIONED|
+                    -- STREAM_PROJECT  |PARTITIONED|
+                      -- ASSIGN  |PARTITIONED|
+                        -- STREAM_PROJECT  |PARTITIONED|
+                          -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                            -- BTREE_SEARCH  |PARTITIONED|
+                              -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                -- STABLE_SORT [$$39(ASC)]  |PARTITIONED|
+                                  -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                    -- STREAM_PROJECT  |PARTITIONED|
+                                      -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                        -- BTREE_SEARCH  |PARTITIONED|
+                                          -- BROADCAST_EXCHANGE  |PARTITIONED|
+                                            -- STREAM_PROJECT  |PARTITIONED|
+                                              -- ASSIGN  |PARTITIONED|
+                                                -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                  -- BTREE_SEARCH  |PARTITIONED|
+                                                    -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                      -- ASSIGN  |PARTITIONED|
+                                                        -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterix-app/src/test/resources/optimizerts/results/fj-phase1.plan b/asterix-app/src/test/resources/optimizerts/results/fj-phase1.plan
index c5511fd..64c0b06 100644
--- a/asterix-app/src/test/resources/optimizerts/results/fj-phase1.plan
+++ b/asterix-app/src/test/resources/optimizerts/results/fj-phase1.plan
@@ -2,34 +2,34 @@
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
     -- STREAM_PROJECT  |PARTITIONED|
       -- ASSIGN  |PARTITIONED|
-        -- STREAM_PROJECT  |PARTITIONED|
-          -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-            -- PRE_CLUSTERED_GROUP_BY[$$23]  |PARTITIONED|
-                    {
-                      -- AGGREGATE  |LOCAL|
-                        -- STREAM_SELECT  |LOCAL|
-                          -- NESTED_TUPLE_SOURCE  |LOCAL|
-                    }
-              -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                -- STABLE_SORT [$$23(ASC), $$4(ASC)]  |PARTITIONED|
-                  -- HASH_PARTITION_EXCHANGE [$$23]  |PARTITIONED|
-                    -- STREAM_PROJECT  |PARTITIONED|
-                      -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                        -- HYBRID_HASH_JOIN [$$1][$$4]  |PARTITIONED|
-                          -- HASH_PARTITION_EXCHANGE [$$1]  |PARTITIONED|
-                            -- STREAM_PROJECT  |PARTITIONED|
-                              -- UNNEST  |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 [$$4]  |PARTITIONED|
+        -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+          -- PRE_CLUSTERED_GROUP_BY[$$21]  |PARTITIONED|
+                  {
+                    -- AGGREGATE  |LOCAL|
+                      -- STREAM_SELECT  |LOCAL|
+                        -- NESTED_TUPLE_SOURCE  |LOCAL|
+                  }
+            -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+              -- STABLE_SORT [$$21(ASC), $$4(ASC)]  |PARTITIONED|
+                -- HASH_PARTITION_EXCHANGE [$$21]  |PARTITIONED|
+                  -- STREAM_PROJECT  |PARTITIONED|
+                    -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                      -- HYBRID_HASH_JOIN [$$1][$$4]  |PARTITIONED|
+                        -- HASH_PARTITION_EXCHANGE [$$1]  |PARTITIONED|
+                          -- STREAM_PROJECT  |PARTITIONED|
+                            -- UNNEST  |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 [$$4]  |PARTITIONED|
+                          -- ASSIGN  |PARTITIONED|
                             -- RUNNING_AGGREGATE  |PARTITIONED|
                               -- STREAM_PROJECT  |PARTITIONED|
-                                -- SORT_MERGE_EXCHANGE [$$24(DESC) ]  |PARTITIONED|
-                                  -- STABLE_SORT [$$24(DESC)]  |PARTITIONED|
+                                -- SORT_MERGE_EXCHANGE [$$23(DESC) ]  |PARTITIONED|
+                                  -- STABLE_SORT [$$23(DESC)]  |PARTITIONED|
                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
                                       -- PRE_CLUSTERED_GROUP_BY[$$30]  |PARTITIONED|
                                               {
diff --git a/asterix-app/src/test/resources/optimizerts/results/inverted-index-join/issue741.plan b/asterix-app/src/test/resources/optimizerts/results/inverted-index-join/issue741.plan
index 55a81d2..5b08bf5 100644
--- a/asterix-app/src/test/resources/optimizerts/results/inverted-index-join/issue741.plan
+++ b/asterix-app/src/test/resources/optimizerts/results/inverted-index-join/issue741.plan
@@ -2,45 +2,44 @@
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
     -- STREAM_PROJECT  |PARTITIONED|
       -- ASSIGN  |PARTITIONED|
-        -- STREAM_PROJECT  |PARTITIONED|
-          -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-            -- PRE_CLUSTERED_GROUP_BY[$$29]  |PARTITIONED|
-                    {
-                      -- AGGREGATE  |LOCAL|
-                        -- STREAM_SELECT  |LOCAL|
-                          -- NESTED_TUPLE_SOURCE  |LOCAL|
-                    }
-              -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                -- STABLE_SORT [$$29(ASC)]  |PARTITIONED|
-                  -- HASH_PARTITION_EXCHANGE [$$29]  |PARTITIONED|
-                    -- STREAM_PROJECT  |PARTITIONED|
-                      -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                        -- HYBRID_HASH_JOIN [$$37][$$29]  |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 [$$29]  |PARTITIONED|
-                            -- STREAM_PROJECT  |PARTITIONED|
-                              -- STREAM_SELECT  |PARTITIONED|
-                                -- STREAM_PROJECT  |PARTITIONED|
+        -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+          -- PRE_CLUSTERED_GROUP_BY[$$25]  |PARTITIONED|
+                  {
+                    -- AGGREGATE  |LOCAL|
+                      -- STREAM_SELECT  |LOCAL|
+                        -- NESTED_TUPLE_SOURCE  |LOCAL|
+                  }
+            -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+              -- STABLE_SORT [$$25(ASC)]  |PARTITIONED|
+                -- HASH_PARTITION_EXCHANGE [$$25]  |PARTITIONED|
+                  -- STREAM_PROJECT  |PARTITIONED|
+                    -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                      -- HYBRID_HASH_JOIN [$$36][$$25]  |PARTITIONED|
+                        -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                          -- STREAM_PROJECT  |PARTITIONED|
+                            -- STREAM_SELECT  |PARTITIONED|
+                              -- STREAM_PROJECT  |PARTITIONED|
+                                -- ASSIGN  |PARTITIONED|
                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                    -- BTREE_SEARCH  |PARTITIONED|
+                                    -- DATASOURCE_SCAN  |PARTITIONED|
                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                        -- STABLE_SORT [$$40(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|
\ No newline at end of file
+                                        -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                        -- HASH_PARTITION_EXCHANGE [$$25]  |PARTITIONED|
+                          -- STREAM_PROJECT  |PARTITIONED|
+                            -- STREAM_SELECT  |PARTITIONED|
+                              -- STREAM_PROJECT  |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|
diff --git a/asterix-app/src/test/resources/optimizerts/results/inverted-index-join/leftouterjoin-probe-pidx-with-join-edit-distance-check-idx_01.plan b/asterix-app/src/test/resources/optimizerts/results/inverted-index-join/leftouterjoin-probe-pidx-with-join-edit-distance-check-idx_01.plan
index bd49b19..e7eff62 100644
--- a/asterix-app/src/test/resources/optimizerts/results/inverted-index-join/leftouterjoin-probe-pidx-with-join-edit-distance-check-idx_01.plan
+++ b/asterix-app/src/test/resources/optimizerts/results/inverted-index-join/leftouterjoin-probe-pidx-with-join-edit-distance-check-idx_01.plan
@@ -2,82 +2,79 @@
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
     -- STREAM_PROJECT  |PARTITIONED|
       -- ASSIGN  |PARTITIONED|
-        -- STREAM_PROJECT  |PARTITIONED|
-          -- SORT_MERGE_EXCHANGE [$$36(ASC) ]  |PARTITIONED|
-            -- STABLE_SORT [$$36(ASC)]  |PARTITIONED|
-              -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                -- PRE_CLUSTERED_GROUP_BY[$$32]  |PARTITIONED|
-                        {
-                          -- AGGREGATE  |LOCAL|
-                            -- STREAM_SELECT  |LOCAL|
-                              -- NESTED_TUPLE_SOURCE  |LOCAL|
-                        }
-                  -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                    -- STABLE_SORT [$$32(ASC), $$28(ASC)]  |PARTITIONED|
-                      -- HASH_PARTITION_EXCHANGE [$$32]  |PARTITIONED|
-                        -- STREAM_PROJECT  |PARTITIONED|
-                          -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                            -- HYBRID_HASH_JOIN [$$45][$$32]  |PARTITIONED|
+        -- SORT_MERGE_EXCHANGE [$$37(ASC) ]  |PARTITIONED|
+          -- PRE_CLUSTERED_GROUP_BY[$$27]  |PARTITIONED|
+                  {
+                    -- AGGREGATE  |LOCAL|
+                      -- STREAM_SELECT  |LOCAL|
+                        -- NESTED_TUPLE_SOURCE  |LOCAL|
+                  }
+            -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+              -- STABLE_SORT [$$27(ASC), $$28(ASC)]  |PARTITIONED|
+                -- HASH_PARTITION_EXCHANGE [$$27]  |PARTITIONED|
+                  -- STREAM_PROJECT  |PARTITIONED|
+                    -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                      -- HYBRID_HASH_JOIN [$$43][$$27]  |PARTITIONED|
+                        -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                          -- STREAM_PROJECT  |PARTITIONED|
+                            -- ASSIGN  |PARTITIONED|
                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                -- STREAM_PROJECT  |PARTITIONED|
-                                  -- ASSIGN  |PARTITIONED|
-                                    -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                      -- SPLIT  |PARTITIONED|
+                                -- SPLIT  |PARTITIONED|
+                                  -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                    -- BTREE_SEARCH  |PARTITIONED|
+                                      -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                        -- ASSIGN  |PARTITIONED|
+                                          -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                        -- HASH_PARTITION_EXCHANGE [$$27]  |PARTITIONED|
+                          -- UNION_ALL  |PARTITIONED|
+                            -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                              -- STREAM_PROJECT  |PARTITIONED|
+                                -- STREAM_SELECT  |PARTITIONED|
+                                  -- STREAM_PROJECT  |PARTITIONED|
+                                    -- ASSIGN  |PARTITIONED|
+                                      -- STREAM_PROJECT  |PARTITIONED|
                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
                                           -- BTREE_SEARCH  |PARTITIONED|
                                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                              -- ASSIGN  |PARTITIONED|
-                                                -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
-                              -- HASH_PARTITION_EXCHANGE [$$32]  |PARTITIONED|
-                                -- UNION_ALL  |PARTITIONED|
-                                  -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                    -- STREAM_PROJECT  |PARTITIONED|
-                                      -- STREAM_SELECT  |PARTITIONED|
-                                        -- STREAM_PROJECT  |PARTITIONED|
-                                          -- ASSIGN  |PARTITIONED|
-                                            -- STREAM_PROJECT  |PARTITIONED|
-                                              -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                -- BTREE_SEARCH  |PARTITIONED|
-                                                  -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                    -- STABLE_SORT [$$53(ASC)]  |PARTITIONED|
-                                                      -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                        -- LENGTH_PARTITIONED_INVERTED_INDEX_SEARCH  |PARTITIONED|
-                                                          -- BROADCAST_EXCHANGE  |PARTITIONED|
-                                                            -- STREAM_SELECT  |PARTITIONED|
-                                                              -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                                -- SPLIT  |PARTITIONED|
-                                                                  -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                                    -- STREAM_PROJECT  |PARTITIONED|
-                                                                      -- ASSIGN  |PARTITIONED|
-                                                                        -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                                          -- SPLIT  |PARTITIONED|
-                                                                            -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                                              -- BTREE_SEARCH  |PARTITIONED|
-                                                                                -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                                                  -- ASSIGN  |PARTITIONED|
-                                                                                    -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
-                                  -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                    -- STREAM_PROJECT  |PARTITIONED|
-                                      -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                        -- NESTED_LOOP  |PARTITIONED|
-                                          -- BROADCAST_EXCHANGE  |PARTITIONED|
-                                            -- STREAM_PROJECT  |PARTITIONED|
-                                              -- ASSIGN  |PARTITIONED|
+                                              -- STABLE_SORT [$$51(ASC)]  |PARTITIONED|
                                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                  -- DATASOURCE_SCAN  |PARTITIONED|
-                                                    -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                      -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
-                                          -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                            -- STREAM_SELECT  |PARTITIONED|
-                                              -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                -- SPLIT  |PARTITIONED|
-                                                  -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                    -- STREAM_PROJECT  |PARTITIONED|
-                                                      -- ASSIGN  |PARTITIONED|
+                                                  -- LENGTH_PARTITIONED_INVERTED_INDEX_SEARCH  |PARTITIONED|
+                                                    -- BROADCAST_EXCHANGE  |PARTITIONED|
+                                                      -- STREAM_SELECT  |PARTITIONED|
                                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
                                                           -- SPLIT  |PARTITIONED|
                                                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                              -- BTREE_SEARCH  |PARTITIONED|
-                                                                -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                                  -- ASSIGN  |PARTITIONED|
-                                                                    -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                                                              -- STREAM_PROJECT  |PARTITIONED|
+                                                                -- ASSIGN  |PARTITIONED|
+                                                                  -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                    -- SPLIT  |PARTITIONED|
+                                                                      -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                        -- BTREE_SEARCH  |PARTITIONED|
+                                                                          -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                            -- ASSIGN  |PARTITIONED|
+                                                                              -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                            -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                              -- STREAM_PROJECT  |PARTITIONED|
+                                -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                  -- NESTED_LOOP  |PARTITIONED|
+                                    -- BROADCAST_EXCHANGE  |PARTITIONED|
+                                      -- STREAM_PROJECT  |PARTITIONED|
+                                        -- ASSIGN  |PARTITIONED|
+                                          -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                            -- DATASOURCE_SCAN  |PARTITIONED|
+                                              -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                                    -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                      -- STREAM_SELECT  |PARTITIONED|
+                                        -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                          -- SPLIT  |PARTITIONED|
+                                            -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                              -- STREAM_PROJECT  |PARTITIONED|
+                                                -- ASSIGN  |PARTITIONED|
+                                                  -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                    -- SPLIT  |PARTITIONED|
+                                                      -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                        -- BTREE_SEARCH  |PARTITIONED|
+                                                          -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                            -- ASSIGN  |PARTITIONED|
+                                                              -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterix-app/src/test/resources/optimizerts/results/inverted-index-join/leftouterjoin-probe-pidx-with-join-jaccard-check-idx_01.plan b/asterix-app/src/test/resources/optimizerts/results/inverted-index-join/leftouterjoin-probe-pidx-with-join-jaccard-check-idx_01.plan
index 89d6924..bdc564e 100644
--- a/asterix-app/src/test/resources/optimizerts/results/inverted-index-join/leftouterjoin-probe-pidx-with-join-jaccard-check-idx_01.plan
+++ b/asterix-app/src/test/resources/optimizerts/results/inverted-index-join/leftouterjoin-probe-pidx-with-join-jaccard-check-idx_01.plan
@@ -2,50 +2,47 @@
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
     -- STREAM_PROJECT  |PARTITIONED|
       -- ASSIGN  |PARTITIONED|
-        -- STREAM_PROJECT  |PARTITIONED|
-          -- SORT_MERGE_EXCHANGE [$$36(ASC) ]  |PARTITIONED|
-            -- STABLE_SORT [$$36(ASC)]  |PARTITIONED|
-              -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                -- PRE_CLUSTERED_GROUP_BY[$$32]  |PARTITIONED|
-                        {
-                          -- AGGREGATE  |LOCAL|
-                            -- STREAM_SELECT  |LOCAL|
-                              -- NESTED_TUPLE_SOURCE  |LOCAL|
-                        }
-                  -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                    -- STABLE_SORT [$$32(ASC), $$28(ASC)]  |PARTITIONED|
-                      -- HASH_PARTITION_EXCHANGE [$$32]  |PARTITIONED|
-                        -- STREAM_PROJECT  |PARTITIONED|
-                          -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                            -- HYBRID_HASH_JOIN [$$45][$$32]  |PARTITIONED|
+        -- SORT_MERGE_EXCHANGE [$$37(ASC) ]  |PARTITIONED|
+          -- PRE_CLUSTERED_GROUP_BY[$$27]  |PARTITIONED|
+                  {
+                    -- AGGREGATE  |LOCAL|
+                      -- STREAM_SELECT  |LOCAL|
+                        -- NESTED_TUPLE_SOURCE  |LOCAL|
+                  }
+            -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+              -- STABLE_SORT [$$27(ASC), $$28(ASC)]  |PARTITIONED|
+                -- HASH_PARTITION_EXCHANGE [$$27]  |PARTITIONED|
+                  -- STREAM_PROJECT  |PARTITIONED|
+                    -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                      -- HYBRID_HASH_JOIN [$$43][$$27]  |PARTITIONED|
+                        -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                          -- STREAM_PROJECT  |PARTITIONED|
+                            -- ASSIGN  |PARTITIONED|
                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                -- SPLIT  |PARTITIONED|
+                                  -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                    -- BTREE_SEARCH  |PARTITIONED|
+                                      -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                        -- ASSIGN  |PARTITIONED|
+                                          -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                        -- HASH_PARTITION_EXCHANGE [$$27]  |PARTITIONED|
+                          -- STREAM_SELECT  |PARTITIONED|
+                            -- STREAM_PROJECT  |PARTITIONED|
+                              -- ASSIGN  |PARTITIONED|
                                 -- STREAM_PROJECT  |PARTITIONED|
-                                  -- ASSIGN  |PARTITIONED|
-                                    -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                      -- SPLIT  |PARTITIONED|
-                                        -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                          -- BTREE_SEARCH  |PARTITIONED|
-                                            -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                              -- ASSIGN  |PARTITIONED|
-                                                -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
-                              -- HASH_PARTITION_EXCHANGE [$$32]  |PARTITIONED|
-                                -- STREAM_SELECT  |PARTITIONED|
-                                  -- STREAM_PROJECT  |PARTITIONED|
-                                    -- ASSIGN  |PARTITIONED|
-                                      -- STREAM_PROJECT  |PARTITIONED|
-                                        -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                          -- BTREE_SEARCH  |PARTITIONED|
-                                            -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                              -- STABLE_SORT [$$49(ASC)]  |PARTITIONED|
-                                                -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                  -- LENGTH_PARTITIONED_INVERTED_INDEX_SEARCH  |PARTITIONED|
-                                                    -- BROADCAST_EXCHANGE  |PARTITIONED|
-                                                      -- STREAM_PROJECT  |PARTITIONED|
-                                                        -- ASSIGN  |PARTITIONED|
-                                                          -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                            -- SPLIT  |PARTITIONED|
-                                                              -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                                -- BTREE_SEARCH  |PARTITIONED|
-                                                                  -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                                    -- ASSIGN  |PARTITIONED|
-                                                                      -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                                  -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                    -- BTREE_SEARCH  |PARTITIONED|
+                                      -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                        -- STABLE_SORT [$$47(ASC)]  |PARTITIONED|
+                                          -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                            -- LENGTH_PARTITIONED_INVERTED_INDEX_SEARCH  |PARTITIONED|
+                                              -- BROADCAST_EXCHANGE  |PARTITIONED|
+                                                -- STREAM_PROJECT  |PARTITIONED|
+                                                  -- ASSIGN  |PARTITIONED|
+                                                    -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                      -- SPLIT  |PARTITIONED|
+                                                        -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                          -- BTREE_SEARCH  |PARTITIONED|
+                                                            -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                              -- ASSIGN  |PARTITIONED|
+                                                                -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterix-app/src/test/resources/optimizerts/results/loj-super-key_01.plan b/asterix-app/src/test/resources/optimizerts/results/loj-super-key_01.plan
index dfcda62..d79e1f2 100644
--- a/asterix-app/src/test/resources/optimizerts/results/loj-super-key_01.plan
+++ b/asterix-app/src/test/resources/optimizerts/results/loj-super-key_01.plan
@@ -4,19 +4,19 @@
       -- ASSIGN  |PARTITIONED|
         -- STREAM_PROJECT  |PARTITIONED|
           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-            -- PRE_CLUSTERED_GROUP_BY[$$22, $$23]  |PARTITIONED|
+            -- PRE_CLUSTERED_GROUP_BY[$$17, $$18]  |PARTITIONED|
                     {
                       -- AGGREGATE  |LOCAL|
                         -- STREAM_SELECT  |LOCAL|
                           -- NESTED_TUPLE_SOURCE  |LOCAL|
                     }
               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                -- STABLE_SORT [$$22(ASC), $$23(ASC)]  |PARTITIONED|
-                  -- HASH_PARTITION_EXCHANGE [$$22, $$23]  |PARTITIONED|
+                -- STABLE_SORT [$$17(ASC), $$18(ASC)]  |PARTITIONED|
+                  -- HASH_PARTITION_EXCHANGE [$$17, $$18]  |PARTITIONED|
                     -- STREAM_PROJECT  |PARTITIONED|
                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                        -- HYBRID_HASH_JOIN [$$24, $$22, $$28][$$25, $$19, $$20]  |PARTITIONED|
-                          -- HASH_PARTITION_EXCHANGE [$$22, $$28]  |PARTITIONED|
+                        -- HYBRID_HASH_JOIN [$$21, $$17, $$25][$$22, $$19, $$20]  |PARTITIONED|
+                          -- HASH_PARTITION_EXCHANGE [$$17, $$25]  |PARTITIONED|
                             -- ASSIGN  |PARTITIONED|
                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
                                 -- DATASOURCE_SCAN  |PARTITIONED|
diff --git a/asterix-app/src/test/resources/optimizerts/results/loj-super-key_02.plan b/asterix-app/src/test/resources/optimizerts/results/loj-super-key_02.plan
index 78159b2..c1cd283 100644
--- a/asterix-app/src/test/resources/optimizerts/results/loj-super-key_02.plan
+++ b/asterix-app/src/test/resources/optimizerts/results/loj-super-key_02.plan
@@ -4,25 +4,25 @@
       -- ASSIGN  |PARTITIONED|
         -- STREAM_PROJECT  |PARTITIONED|
           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-            -- PRE_CLUSTERED_GROUP_BY[$$22, $$23]  |PARTITIONED|
+            -- PRE_CLUSTERED_GROUP_BY[$$17, $$18]  |PARTITIONED|
                     {
                       -- AGGREGATE  |LOCAL|
                         -- STREAM_SELECT  |LOCAL|
                           -- NESTED_TUPLE_SOURCE  |LOCAL|
                     }
               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                -- STABLE_SORT [$$22(ASC), $$23(ASC)]  |PARTITIONED|
+                -- STABLE_SORT [$$17(ASC), $$18(ASC)]  |PARTITIONED|
                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
                     -- STREAM_PROJECT  |PARTITIONED|
                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                        -- HYBRID_HASH_JOIN [$$25, $$22, $$23][$$24, $$19, $$28]  |PARTITIONED|
+                        -- HYBRID_HASH_JOIN [$$22, $$17, $$18][$$21, $$19, $$25]  |PARTITIONED|
                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
                             -- ASSIGN  |PARTITIONED|
                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
                                 -- DATASOURCE_SCAN  |PARTITIONED|
                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
                                     -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
-                          -- HASH_PARTITION_EXCHANGE [$$19, $$28]  |PARTITIONED|
+                          -- HASH_PARTITION_EXCHANGE [$$19, $$25]  |PARTITIONED|
                             -- ASSIGN  |PARTITIONED|
                               -- STREAM_PROJECT  |PARTITIONED|
                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
diff --git a/asterix-app/src/test/resources/optimizerts/results/nest_aggregate.plan b/asterix-app/src/test/resources/optimizerts/results/nest_aggregate.plan
index f3c1040..41b07d9 100644
--- a/asterix-app/src/test/resources/optimizerts/results/nest_aggregate.plan
+++ b/asterix-app/src/test/resources/optimizerts/results/nest_aggregate.plan
@@ -2,67 +2,66 @@
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
     -- STREAM_PROJECT  |PARTITIONED|
       -- ASSIGN  |PARTITIONED|
-        -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-          -- PRE_CLUSTERED_GROUP_BY[$$49]  |PARTITIONED|
-                  {
-                    -- AGGREGATE  |LOCAL|
-                      -- STREAM_LIMIT  |LOCAL|
-                        -- IN_MEMORY_STABLE_SORT [$$43(ASC)]  |LOCAL|
-                          -- MICRO_PRE_CLUSTERED_GROUP_BY[$$50]  |LOCAL|
-                                  {
-                                    -- AGGREGATE  |LOCAL|
-                                      -- NESTED_TUPLE_SOURCE  |LOCAL|
-                                  }
-                            -- STREAM_SELECT  |LOCAL|
-                              -- NESTED_TUPLE_SOURCE  |LOCAL|
-                  }
-            -- HASH_PARTITION_MERGE_EXCHANGE MERGE:[$$49(ASC), $$50(ASC)] HASH:[$$49]  |PARTITIONED|
-              -- PRE_CLUSTERED_GROUP_BY[$$39, $$32]  |PARTITIONED|
-                      {
-                        -- AGGREGATE  |LOCAL|
-                          -- STREAM_SELECT  |LOCAL|
-                            -- NESTED_TUPLE_SOURCE  |LOCAL|
-                      }
-                -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                  -- STABLE_SORT [$$39(ASC), $$32(ASC)]  |PARTITIONED|
-                    -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                      -- STREAM_PROJECT  |PARTITIONED|
-                        -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                          -- HYBRID_HASH_JOIN [$$39][$$41]  |PARTITIONED|
-                            -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                              -- STREAM_PROJECT  |PARTITIONED|
-                                -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                  -- HYBRID_HASH_JOIN [$$39][$$35]  |PARTITIONED|
-                                    -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                      -- STREAM_PROJECT  |PARTITIONED|
-                                        -- ASSIGN  |PARTITIONED|
-                                          -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                            -- DATASOURCE_SCAN  |PARTITIONED|
-                                              -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
-                                    -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                      -- STREAM_PROJECT  |PARTITIONED|
+        -- STREAM_PROJECT  |PARTITIONED|
+          -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+            -- PRE_CLUSTERED_GROUP_BY[$$49, $$50]  |PARTITIONED|
+                    {
+                      -- AGGREGATE  |LOCAL|
+                        -- STREAM_LIMIT  |LOCAL|
+                          -- IN_MEMORY_STABLE_SORT [$$41(ASC)]  |LOCAL|
+                            -- MICRO_PRE_CLUSTERED_GROUP_BY[$$51]  |LOCAL|
+                                    {
+                                      -- AGGREGATE  |LOCAL|
+                                        -- NESTED_TUPLE_SOURCE  |LOCAL|
+                                    }
+                              -- IN_MEMORY_STABLE_SORT [$$51(ASC)]  |LOCAL|
+                                -- STREAM_SELECT  |LOCAL|
+                                  -- NESTED_TUPLE_SOURCE  |LOCAL|
+                    }
+              -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                -- STABLE_SORT [$$49(ASC), $$50(ASC)]  |PARTITIONED|
+                  -- HASH_PARTITION_EXCHANGE [$$49, $$50]  |PARTITIONED|
+                    -- SORT_GROUP_BY[$$34, $$35, $$32, $$45]  |PARTITIONED|
+                            {
+                              -- AGGREGATE  |LOCAL|
+                                -- NESTED_TUPLE_SOURCE  |LOCAL|
+                            }
+                      -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                        -- STREAM_PROJECT  |PARTITIONED|
+                          -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                            -- HYBRID_HASH_JOIN [$$34][$$39]  |PARTITIONED|
+                              -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                -- HYBRID_HASH_JOIN [$$34][$$35]  |PARTITIONED|
+                                  -- ONE_TO_ONE_EXCHANGE  |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 [$$41]  |PARTITIONED|
-                              -- ASSIGN  |PARTITIONED|
-                                -- STREAM_PROJECT  |PARTITIONED|
                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                    -- HYBRID_HASH_JOIN [$$44][$$37]  |PARTITIONED|
-                                      -- HASH_PARTITION_EXCHANGE [$$44]  |PARTITIONED|
-                                        -- STREAM_PROJECT  |PARTITIONED|
-                                          -- ASSIGN  |PARTITIONED|
-                                            -- STREAM_PROJECT  |PARTITIONED|
+                                    -- STREAM_PROJECT  |PARTITIONED|
+                                      -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                        -- DATASOURCE_SCAN  |PARTITIONED|
+                                          -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                            -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                              -- HASH_PARTITION_EXCHANGE [$$39]  |PARTITIONED|
+                                -- ASSIGN  |PARTITIONED|
+                                  -- STREAM_PROJECT  |PARTITIONED|
+                                    -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                      -- HYBRID_HASH_JOIN [$$42][$$37]  |PARTITIONED|
+                                        -- HASH_PARTITION_EXCHANGE [$$42]  |PARTITIONED|
+                                          -- STREAM_PROJECT  |PARTITIONED|
+                                            -- ASSIGN  |PARTITIONED|
+                                              -- STREAM_PROJECT  |PARTITIONED|
+                                                -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                  -- DATASOURCE_SCAN  |PARTITIONED|
+                                                    -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                      -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                                        -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                          -- STREAM_PROJECT  |PARTITIONED|
+                                            -- ASSIGN  |PARTITIONED|
                                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
                                                 -- DATASOURCE_SCAN  |PARTITIONED|
                                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
                                                     -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
-                                      -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                        -- STREAM_PROJECT  |PARTITIONED|
-                                          -- ASSIGN  |PARTITIONED|
-                                            -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                              -- DATASOURCE_SCAN  |PARTITIONED|
-                                                -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                  -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterix-app/src/test/resources/optimizerts/results/nested-index/btree-index-join/leftouterjoin-probe-pidx-with-join-btree-sidx_01.plan b/asterix-app/src/test/resources/optimizerts/results/nested-index/btree-index-join/leftouterjoin-probe-pidx-with-join-btree-sidx_01.plan
index 9fc1275..e108f8b 100644
--- a/asterix-app/src/test/resources/optimizerts/results/nested-index/btree-index-join/leftouterjoin-probe-pidx-with-join-btree-sidx_01.plan
+++ b/asterix-app/src/test/resources/optimizerts/results/nested-index/btree-index-join/leftouterjoin-probe-pidx-with-join-btree-sidx_01.plan
@@ -2,42 +2,41 @@
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
     -- STREAM_PROJECT  |PARTITIONED|
       -- ASSIGN  |PARTITIONED|
-        -- STREAM_PROJECT  |PARTITIONED|
-          -- SORT_MERGE_EXCHANGE [$$41(ASC) ]  |PARTITIONED|
-            -- STABLE_SORT [$$41(ASC)]  |PARTITIONED|
-              -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                -- STREAM_PROJECT  |PARTITIONED|
-                  -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                    -- PRE_CLUSTERED_GROUP_BY[$$35]  |PARTITIONED|
-                            {
-                              -- AGGREGATE  |LOCAL|
-                                -- STREAM_SELECT  |LOCAL|
-                                  -- NESTED_TUPLE_SOURCE  |LOCAL|
-                            }
-                      -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                        -- STABLE_SORT [$$35(ASC), $$38(ASC)]  |PARTITIONED|
-                          -- HASH_PARTITION_EXCHANGE [$$35]  |PARTITIONED|
-                            -- STREAM_SELECT  |PARTITIONED|
-                              -- STREAM_PROJECT  |PARTITIONED|
-                                -- ASSIGN  |PARTITIONED|
-                                  -- STREAM_PROJECT  |PARTITIONED|
-                                    -- ASSIGN  |PARTITIONED|
-                                      -- STREAM_PROJECT  |PARTITIONED|
-                                        -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                          -- BTREE_SEARCH  |PARTITIONED|
-                                            -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                              -- STABLE_SORT [$$52(ASC)]  |PARTITIONED|
-                                                -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                  -- STREAM_PROJECT  |PARTITIONED|
-                                                    -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                      -- BTREE_SEARCH  |PARTITIONED|
-                                                        -- BROADCAST_EXCHANGE  |PARTITIONED|
-                                                          -- STREAM_PROJECT  |PARTITIONED|
-                                                            -- ASSIGN  |PARTITIONED|
-                                                              -- STREAM_PROJECT  |PARTITIONED|
-                                                                -- ASSIGN  |PARTITIONED|
-                                                                  -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                                    -- BTREE_SEARCH  |PARTITIONED|
-                                                                      -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                                        -- ASSIGN  |PARTITIONED|
-                                                                          -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
\ No newline at end of file
+        -- SORT_MERGE_EXCHANGE [$$39(ASC) ]  |PARTITIONED|
+          -- STABLE_SORT [$$39(ASC)]  |PARTITIONED|
+            -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+              -- STREAM_PROJECT  |PARTITIONED|
+                -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                  -- PRE_CLUSTERED_GROUP_BY[$$30]  |PARTITIONED|
+                          {
+                            -- AGGREGATE  |LOCAL|
+                              -- STREAM_SELECT  |LOCAL|
+                                -- NESTED_TUPLE_SOURCE  |LOCAL|
+                          }
+                    -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                      -- STABLE_SORT [$$30(ASC), $$36(ASC)]  |PARTITIONED|
+                        -- HASH_PARTITION_EXCHANGE [$$30]  |PARTITIONED|
+                          -- STREAM_SELECT  |PARTITIONED|
+                            -- STREAM_PROJECT  |PARTITIONED|
+                              -- ASSIGN  |PARTITIONED|
+                                -- STREAM_PROJECT  |PARTITIONED|
+                                  -- ASSIGN  |PARTITIONED|
+                                    -- STREAM_PROJECT  |PARTITIONED|
+                                      -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                        -- BTREE_SEARCH  |PARTITIONED|
+                                          -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                            -- STABLE_SORT [$$50(ASC)]  |PARTITIONED|
+                                              -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                -- STREAM_PROJECT  |PARTITIONED|
+                                                  -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                    -- BTREE_SEARCH  |PARTITIONED|
+                                                      -- BROADCAST_EXCHANGE  |PARTITIONED|
+                                                        -- STREAM_PROJECT  |PARTITIONED|
+                                                          -- ASSIGN  |PARTITIONED|
+                                                            -- STREAM_PROJECT  |PARTITIONED|
+                                                              -- ASSIGN  |PARTITIONED|
+                                                                -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                  -- BTREE_SEARCH  |PARTITIONED|
+                                                                    -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                      -- ASSIGN  |PARTITIONED|
+                                                                        -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterix-app/src/test/resources/optimizerts/results/nested-index/btree-index-join/leftouterjoin-probe-pidx-with-join-btree-sidx_02.plan b/asterix-app/src/test/resources/optimizerts/results/nested-index/btree-index-join/leftouterjoin-probe-pidx-with-join-btree-sidx_02.plan
index 1b3bdd8..2a4e565 100644
--- a/asterix-app/src/test/resources/optimizerts/results/nested-index/btree-index-join/leftouterjoin-probe-pidx-with-join-btree-sidx_02.plan
+++ b/asterix-app/src/test/resources/optimizerts/results/nested-index/btree-index-join/leftouterjoin-probe-pidx-with-join-btree-sidx_02.plan
@@ -2,42 +2,41 @@
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
     -- STREAM_PROJECT  |PARTITIONED|
       -- ASSIGN  |PARTITIONED|
-        -- STREAM_PROJECT  |PARTITIONED|
-          -- SORT_MERGE_EXCHANGE [$$50(ASC) ]  |PARTITIONED|
-            -- STABLE_SORT [$$50(ASC)]  |PARTITIONED|
-              -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                -- STREAM_PROJECT  |PARTITIONED|
-                  -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                    -- PRE_CLUSTERED_GROUP_BY[$$42]  |PARTITIONED|
-                            {
-                              -- AGGREGATE  |LOCAL|
-                                -- STREAM_SELECT  |LOCAL|
-                                  -- NESTED_TUPLE_SOURCE  |LOCAL|
-                            }
-                      -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                        -- STABLE_SORT [$$42(ASC), $$47(ASC)]  |PARTITIONED|
-                          -- HASH_PARTITION_EXCHANGE [$$42]  |PARTITIONED|
-                            -- STREAM_SELECT  |PARTITIONED|
-                              -- STREAM_PROJECT  |PARTITIONED|
-                                -- ASSIGN  |PARTITIONED|
-                                  -- STREAM_PROJECT  |PARTITIONED|
-                                    -- ASSIGN  |PARTITIONED|
-                                      -- STREAM_PROJECT  |PARTITIONED|
-                                        -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                          -- BTREE_SEARCH  |PARTITIONED|
-                                            -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                              -- STABLE_SORT [$$60(ASC)]  |PARTITIONED|
-                                                -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                  -- STREAM_PROJECT  |PARTITIONED|
-                                                    -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                      -- BTREE_SEARCH  |PARTITIONED|
-                                                        -- BROADCAST_EXCHANGE  |PARTITIONED|
-                                                          -- STREAM_PROJECT  |PARTITIONED|
-                                                            -- ASSIGN  |PARTITIONED|
-                                                              -- STREAM_PROJECT  |PARTITIONED|
-                                                                -- ASSIGN  |PARTITIONED|
-                                                                  -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                                    -- BTREE_SEARCH  |PARTITIONED|
-                                                                      -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                                        -- ASSIGN  |PARTITIONED|
-                                                                          -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
\ No newline at end of file
+        -- SORT_MERGE_EXCHANGE [$$48(ASC) ]  |PARTITIONED|
+          -- STABLE_SORT [$$48(ASC)]  |PARTITIONED|
+            -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+              -- STREAM_PROJECT  |PARTITIONED|
+                -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                  -- PRE_CLUSTERED_GROUP_BY[$$36]  |PARTITIONED|
+                          {
+                            -- AGGREGATE  |LOCAL|
+                              -- STREAM_SELECT  |LOCAL|
+                                -- NESTED_TUPLE_SOURCE  |LOCAL|
+                          }
+                    -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                      -- STABLE_SORT [$$36(ASC), $$45(ASC)]  |PARTITIONED|
+                        -- HASH_PARTITION_EXCHANGE [$$36]  |PARTITIONED|
+                          -- STREAM_SELECT  |PARTITIONED|
+                            -- STREAM_PROJECT  |PARTITIONED|
+                              -- ASSIGN  |PARTITIONED|
+                                -- STREAM_PROJECT  |PARTITIONED|
+                                  -- ASSIGN  |PARTITIONED|
+                                    -- STREAM_PROJECT  |PARTITIONED|
+                                      -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                        -- BTREE_SEARCH  |PARTITIONED|
+                                          -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                            -- STABLE_SORT [$$58(ASC)]  |PARTITIONED|
+                                              -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                -- STREAM_PROJECT  |PARTITIONED|
+                                                  -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                    -- BTREE_SEARCH  |PARTITIONED|
+                                                      -- BROADCAST_EXCHANGE  |PARTITIONED|
+                                                        -- STREAM_PROJECT  |PARTITIONED|
+                                                          -- ASSIGN  |PARTITIONED|
+                                                            -- STREAM_PROJECT  |PARTITIONED|
+                                                              -- ASSIGN  |PARTITIONED|
+                                                                -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                  -- BTREE_SEARCH  |PARTITIONED|
+                                                                    -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                      -- ASSIGN  |PARTITIONED|
+                                                                        -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterix-app/src/test/resources/optimizerts/results/nested-index/inverted-index-join/leftouterjoin-probe-pidx-with-join-edit-distance-check-idx_01.plan b/asterix-app/src/test/resources/optimizerts/results/nested-index/inverted-index-join/leftouterjoin-probe-pidx-with-join-edit-distance-check-idx_01.plan
index f2122aa..5d46f46 100644
--- a/asterix-app/src/test/resources/optimizerts/results/nested-index/inverted-index-join/leftouterjoin-probe-pidx-with-join-edit-distance-check-idx_01.plan
+++ b/asterix-app/src/test/resources/optimizerts/results/nested-index/inverted-index-join/leftouterjoin-probe-pidx-with-join-edit-distance-check-idx_01.plan
@@ -2,94 +2,93 @@
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
     -- STREAM_PROJECT  |PARTITIONED|
       -- ASSIGN  |PARTITIONED|
-        -- STREAM_PROJECT  |PARTITIONED|
-          -- SORT_MERGE_EXCHANGE [$$53(ASC) ]  |PARTITIONED|
-            -- STABLE_SORT [$$53(ASC)]  |PARTITIONED|
-              -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                -- STREAM_PROJECT  |PARTITIONED|
-                  -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                    -- PRE_CLUSTERED_GROUP_BY[$$45]  |PARTITIONED|
-                            {
-                              -- AGGREGATE  |LOCAL|
-                                -- STREAM_SELECT  |LOCAL|
-                                  -- NESTED_TUPLE_SOURCE  |LOCAL|
-                            }
-                      -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                        -- STABLE_SORT [$$45(ASC), $$50(ASC)]  |PARTITIONED|
-                          -- HASH_PARTITION_EXCHANGE [$$45]  |PARTITIONED|
-                            -- STREAM_PROJECT  |PARTITIONED|
-                              -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                -- HYBRID_HASH_JOIN [$$64][$$45]  |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|
-                                                  -- BTREE_SEARCH  |PARTITIONED|
-                                                    -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                      -- ASSIGN  |PARTITIONED|
-                                                        -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
-                                  -- HASH_PARTITION_EXCHANGE [$$45]  |PARTITIONED|
-                                    -- UNION_ALL  |PARTITIONED|
-                                      -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                        -- STREAM_PROJECT  |PARTITIONED|
-                                          -- STREAM_SELECT  |PARTITIONED|
-                                            -- STREAM_PROJECT  |PARTITIONED|
-                                              -- ASSIGN  |PARTITIONED|
-                                                -- STREAM_PROJECT  |PARTITIONED|
-                                                  -- ASSIGN  |PARTITIONED|
-                                                    -- STREAM_PROJECT  |PARTITIONED|
-                                                      -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                        -- BTREE_SEARCH  |PARTITIONED|
-                                                          -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                            -- STABLE_SORT [$$76(ASC)]  |PARTITIONED|
-                                                              -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                                -- LENGTH_PARTITIONED_INVERTED_INDEX_SEARCH  |PARTITIONED|
-                                                                  -- BROADCAST_EXCHANGE  |PARTITIONED|
-                                                                    -- STREAM_SELECT  |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|
-                                                                                          -- BTREE_SEARCH  |PARTITIONED|
-                                                                                            -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                                                              -- ASSIGN  |PARTITIONED|
-                                                                                                -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
-                                      -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                        -- STREAM_PROJECT  |PARTITIONED|
+        -- SORT_MERGE_EXCHANGE [$$51(ASC) ]  |PARTITIONED|
+          -- STABLE_SORT [$$51(ASC)]  |PARTITIONED|
+            -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+              -- STREAM_PROJECT  |PARTITIONED|
+                -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                  -- PRE_CLUSTERED_GROUP_BY[$$39]  |PARTITIONED|
+                          {
+                            -- AGGREGATE  |LOCAL|
+                              -- STREAM_SELECT  |LOCAL|
+                                -- NESTED_TUPLE_SOURCE  |LOCAL|
+                          }
+                    -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                      -- STABLE_SORT [$$39(ASC), $$48(ASC)]  |PARTITIONED|
+                        -- HASH_PARTITION_EXCHANGE [$$39]  |PARTITIONED|
+                          -- STREAM_PROJECT  |PARTITIONED|
+                            -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                              -- HYBRID_HASH_JOIN [$$62][$$39]  |PARTITIONED|
+                                -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                  -- STREAM_PROJECT  |PARTITIONED|
+                                    -- ASSIGN  |PARTITIONED|
+                                      -- STREAM_PROJECT  |PARTITIONED|
+                                        -- ASSIGN  |PARTITIONED|
                                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                            -- NESTED_LOOP  |PARTITIONED|
-                                              -- BROADCAST_EXCHANGE  |PARTITIONED|
-                                                -- STREAM_PROJECT  |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|
+                                            -- SPLIT  |PARTITIONED|
                                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                -- STREAM_SELECT  |PARTITIONED|
+                                                -- BTREE_SEARCH  |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|
+                                                    -- ASSIGN  |PARTITIONED|
+                                                      -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                                -- HASH_PARTITION_EXCHANGE [$$39]  |PARTITIONED|
+                                  -- UNION_ALL  |PARTITIONED|
+                                    -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                      -- STREAM_PROJECT  |PARTITIONED|
+                                        -- STREAM_SELECT  |PARTITIONED|
+                                          -- STREAM_PROJECT  |PARTITIONED|
+                                            -- ASSIGN  |PARTITIONED|
+                                              -- STREAM_PROJECT  |PARTITIONED|
+                                                -- ASSIGN  |PARTITIONED|
+                                                  -- STREAM_PROJECT  |PARTITIONED|
+                                                    -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                      -- BTREE_SEARCH  |PARTITIONED|
+                                                        -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                          -- STABLE_SORT [$$74(ASC)]  |PARTITIONED|
+                                                            -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                              -- LENGTH_PARTITIONED_INVERTED_INDEX_SEARCH  |PARTITIONED|
+                                                                -- BROADCAST_EXCHANGE  |PARTITIONED|
+                                                                  -- STREAM_SELECT  |PARTITIONED|
                                                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                                      -- BTREE_SEARCH  |PARTITIONED|
+                                                                      -- SPLIT  |PARTITIONED|
                                                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                                          -- ASSIGN  |PARTITIONED|
-                                                                            -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
\ No newline at end of file
+                                                                          -- STREAM_PROJECT  |PARTITIONED|
+                                                                            -- ASSIGN  |PARTITIONED|
+                                                                              -- STREAM_PROJECT  |PARTITIONED|
+                                                                                -- ASSIGN  |PARTITIONED|
+                                                                                  -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                    -- SPLIT  |PARTITIONED|
+                                                                                      -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                        -- BTREE_SEARCH  |PARTITIONED|
+                                                                                          -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                            -- ASSIGN  |PARTITIONED|
+                                                                                              -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                                    -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                      -- STREAM_PROJECT  |PARTITIONED|
+                                        -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                          -- NESTED_LOOP  |PARTITIONED|
+                                            -- BROADCAST_EXCHANGE  |PARTITIONED|
+                                              -- STREAM_PROJECT  |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|
+                                            -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                              -- STREAM_SELECT  |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|
+                                                                    -- BTREE_SEARCH  |PARTITIONED|
+                                                                      -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                        -- ASSIGN  |PARTITIONED|
+                                                                          -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterix-app/src/test/resources/optimizerts/results/nested-index/inverted-index-join/leftouterjoin-probe-pidx-with-join-jaccard-check-idx_01.plan b/asterix-app/src/test/resources/optimizerts/results/nested-index/inverted-index-join/leftouterjoin-probe-pidx-with-join-jaccard-check-idx_01.plan
index 411a70b..c5bc9eb 100644
--- a/asterix-app/src/test/resources/optimizerts/results/nested-index/inverted-index-join/leftouterjoin-probe-pidx-with-join-jaccard-check-idx_01.plan
+++ b/asterix-app/src/test/resources/optimizerts/results/nested-index/inverted-index-join/leftouterjoin-probe-pidx-with-join-jaccard-check-idx_01.plan
@@ -2,59 +2,58 @@
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
     -- STREAM_PROJECT  |PARTITIONED|
       -- ASSIGN  |PARTITIONED|
-        -- STREAM_PROJECT  |PARTITIONED|
-          -- SORT_MERGE_EXCHANGE [$$53(ASC) ]  |PARTITIONED|
-            -- STABLE_SORT [$$53(ASC)]  |PARTITIONED|
-              -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                -- STREAM_PROJECT  |PARTITIONED|
-                  -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                    -- PRE_CLUSTERED_GROUP_BY[$$45]  |PARTITIONED|
-                            {
-                              -- AGGREGATE  |LOCAL|
-                                -- STREAM_SELECT  |LOCAL|
-                                  -- NESTED_TUPLE_SOURCE  |LOCAL|
-                            }
-                      -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                        -- STABLE_SORT [$$45(ASC), $$50(ASC)]  |PARTITIONED|
-                          -- HASH_PARTITION_EXCHANGE [$$45]  |PARTITIONED|
-                            -- STREAM_PROJECT  |PARTITIONED|
-                              -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                -- HYBRID_HASH_JOIN [$$64][$$45]  |PARTITIONED|
-                                  -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                    -- STREAM_PROJECT  |PARTITIONED|
-                                      -- ASSIGN  |PARTITIONED|
-                                        -- STREAM_PROJECT  |PARTITIONED|
-                                          -- ASSIGN  |PARTITIONED|
-                                            -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                              -- SPLIT  |PARTITIONED|
+        -- SORT_MERGE_EXCHANGE [$$51(ASC) ]  |PARTITIONED|
+          -- STABLE_SORT [$$51(ASC)]  |PARTITIONED|
+            -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+              -- STREAM_PROJECT  |PARTITIONED|
+                -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                  -- PRE_CLUSTERED_GROUP_BY[$$39]  |PARTITIONED|
+                          {
+                            -- AGGREGATE  |LOCAL|
+                              -- STREAM_SELECT  |LOCAL|
+                                -- NESTED_TUPLE_SOURCE  |LOCAL|
+                          }
+                    -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                      -- STABLE_SORT [$$39(ASC), $$48(ASC)]  |PARTITIONED|
+                        -- HASH_PARTITION_EXCHANGE [$$39]  |PARTITIONED|
+                          -- STREAM_PROJECT  |PARTITIONED|
+                            -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                              -- HYBRID_HASH_JOIN [$$62][$$39]  |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|
+                                                -- BTREE_SEARCH  |PARTITIONED|
+                                                  -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                    -- ASSIGN  |PARTITIONED|
+                                                      -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                                -- HASH_PARTITION_EXCHANGE [$$39]  |PARTITIONED|
+                                  -- STREAM_PROJECT  |PARTITIONED|
+                                    -- STREAM_SELECT  |PARTITIONED|
+                                      -- STREAM_PROJECT  |PARTITIONED|
+                                        -- ASSIGN  |PARTITIONED|
+                                          -- STREAM_PROJECT  |PARTITIONED|
+                                            -- ASSIGN  |PARTITIONED|
+                                              -- STREAM_PROJECT  |PARTITIONED|
                                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
                                                   -- BTREE_SEARCH  |PARTITIONED|
                                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                      -- ASSIGN  |PARTITIONED|
-                                                        -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
-                                  -- HASH_PARTITION_EXCHANGE [$$45]  |PARTITIONED|
-                                    -- STREAM_PROJECT  |PARTITIONED|
-                                      -- STREAM_SELECT  |PARTITIONED|
-                                        -- STREAM_PROJECT  |PARTITIONED|
-                                          -- ASSIGN  |PARTITIONED|
-                                            -- STREAM_PROJECT  |PARTITIONED|
-                                              -- ASSIGN  |PARTITIONED|
-                                                -- STREAM_PROJECT  |PARTITIONED|
-                                                  -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                    -- BTREE_SEARCH  |PARTITIONED|
-                                                      -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                        -- STABLE_SORT [$$70(ASC)]  |PARTITIONED|
-                                                          -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                            -- LENGTH_PARTITIONED_INVERTED_INDEX_SEARCH  |PARTITIONED|
-                                                              -- BROADCAST_EXCHANGE  |PARTITIONED|
-                                                                -- STREAM_PROJECT  |PARTITIONED|
-                                                                  -- ASSIGN  |PARTITIONED|
-                                                                    -- STREAM_PROJECT  |PARTITIONED|
-                                                                      -- ASSIGN  |PARTITIONED|
-                                                                        -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                                          -- SPLIT  |PARTITIONED|
-                                                                            -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                                              -- BTREE_SEARCH  |PARTITIONED|
-                                                                                -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                                                  -- ASSIGN  |PARTITIONED|
-                                                                                    -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
\ No newline at end of file
+                                                      -- STABLE_SORT [$$68(ASC)]  |PARTITIONED|
+                                                        -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                          -- LENGTH_PARTITIONED_INVERTED_INDEX_SEARCH  |PARTITIONED|
+                                                            -- BROADCAST_EXCHANGE  |PARTITIONED|
+                                                              -- STREAM_PROJECT  |PARTITIONED|
+                                                                -- ASSIGN  |PARTITIONED|
+                                                                  -- STREAM_PROJECT  |PARTITIONED|
+                                                                    -- ASSIGN  |PARTITIONED|
+                                                                      -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                        -- SPLIT  |PARTITIONED|
+                                                                          -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                            -- BTREE_SEARCH  |PARTITIONED|
+                                                                              -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                -- ASSIGN  |PARTITIONED|
+                                                                                  -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterix-app/src/test/resources/optimizerts/results/nested-index/rtree-index-join/leftouterjoin-probe-pidx-with-join-rtree-sidx_01.plan b/asterix-app/src/test/resources/optimizerts/results/nested-index/rtree-index-join/leftouterjoin-probe-pidx-with-join-rtree-sidx_01.plan
index d3596ca..abb7519 100644
--- a/asterix-app/src/test/resources/optimizerts/results/nested-index/rtree-index-join/leftouterjoin-probe-pidx-with-join-rtree-sidx_01.plan
+++ b/asterix-app/src/test/resources/optimizerts/results/nested-index/rtree-index-join/leftouterjoin-probe-pidx-with-join-rtree-sidx_01.plan
@@ -2,20 +2,20 @@
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
     -- STREAM_PROJECT  |PARTITIONED|
       -- ASSIGN  |PARTITIONED|
-        -- SORT_MERGE_EXCHANGE [$$41(ASC) ]  |PARTITIONED|
-          -- STABLE_SORT [$$41(ASC)]  |PARTITIONED|
+        -- SORT_MERGE_EXCHANGE [$$39(ASC) ]  |PARTITIONED|
+          -- STABLE_SORT [$$39(ASC)]  |PARTITIONED|
             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
               -- STREAM_PROJECT  |PARTITIONED|
                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                  -- PRE_CLUSTERED_GROUP_BY[$$34]  |PARTITIONED|
+                  -- PRE_CLUSTERED_GROUP_BY[$$30]  |PARTITIONED|
                           {
                             -- AGGREGATE  |LOCAL|
                               -- STREAM_SELECT  |LOCAL|
                                 -- NESTED_TUPLE_SOURCE  |LOCAL|
                           }
                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                      -- STABLE_SORT [$$34(ASC), $$38(ASC)]  |PARTITIONED|
-                        -- HASH_PARTITION_EXCHANGE [$$34]  |PARTITIONED|
+                      -- STABLE_SORT [$$30(ASC), $$36(ASC)]  |PARTITIONED|
+                        -- HASH_PARTITION_EXCHANGE [$$30]  |PARTITIONED|
                           -- STREAM_PROJECT  |PARTITIONED|
                             -- STREAM_SELECT  |PARTITIONED|
                               -- STREAM_PROJECT  |PARTITIONED|
@@ -25,7 +25,7 @@
                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
                                         -- BTREE_SEARCH  |PARTITIONED|
                                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                            -- STABLE_SORT [$$59(ASC)]  |PARTITIONED|
+                                            -- STABLE_SORT [$$56(ASC)]  |PARTITIONED|
                                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
                                                 -- STREAM_PROJECT  |PARTITIONED|
                                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
@@ -41,4 +41,4 @@
                                                                       -- BTREE_SEARCH  |PARTITIONED|
                                                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
                                                                           -- ASSIGN  |PARTITIONED|
-                                                                            -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
\ No newline at end of file
+                                                                            -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterix-app/src/test/resources/optimizerts/results/nested-index/rtree-index-join/leftouterjoin-probe-pidx-with-join-rtree-sidx_02.plan b/asterix-app/src/test/resources/optimizerts/results/nested-index/rtree-index-join/leftouterjoin-probe-pidx-with-join-rtree-sidx_02.plan
index 972233e..08bd165 100644
--- a/asterix-app/src/test/resources/optimizerts/results/nested-index/rtree-index-join/leftouterjoin-probe-pidx-with-join-rtree-sidx_02.plan
+++ b/asterix-app/src/test/resources/optimizerts/results/nested-index/rtree-index-join/leftouterjoin-probe-pidx-with-join-rtree-sidx_02.plan
@@ -2,20 +2,20 @@
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
     -- STREAM_PROJECT  |PARTITIONED|
       -- ASSIGN  |PARTITIONED|
-        -- SORT_MERGE_EXCHANGE [$$50(ASC) ]  |PARTITIONED|
-          -- STABLE_SORT [$$50(ASC)]  |PARTITIONED|
+        -- SORT_MERGE_EXCHANGE [$$40(ASC) ]  |PARTITIONED|
+          -- STABLE_SORT [$$40(ASC)]  |PARTITIONED|
             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
               -- STREAM_PROJECT  |PARTITIONED|
                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                  -- PRE_CLUSTERED_GROUP_BY[$$41]  |PARTITIONED|
+                  -- PRE_CLUSTERED_GROUP_BY[$$37]  |PARTITIONED|
                           {
                             -- AGGREGATE  |LOCAL|
                               -- STREAM_SELECT  |LOCAL|
                                 -- NESTED_TUPLE_SOURCE  |LOCAL|
                           }
                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                      -- STABLE_SORT [$$41(ASC), $$47(ASC)]  |PARTITIONED|
-                        -- HASH_PARTITION_EXCHANGE [$$41]  |PARTITIONED|
+                      -- STABLE_SORT [$$37(ASC), $$45(ASC)]  |PARTITIONED|
+                        -- HASH_PARTITION_EXCHANGE [$$37]  |PARTITIONED|
                           -- STREAM_PROJECT  |PARTITIONED|
                             -- STREAM_SELECT  |PARTITIONED|
                               -- STREAM_PROJECT  |PARTITIONED|
@@ -26,7 +26,7 @@
                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
                                           -- BTREE_SEARCH  |PARTITIONED|
                                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                              -- STABLE_SORT [$$69(ASC)]  |PARTITIONED|
+                                              -- STABLE_SORT [$$66(ASC)]  |PARTITIONED|
                                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
                                                   -- STREAM_PROJECT  |PARTITIONED|
                                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
@@ -42,4 +42,4 @@
                                                                         -- BTREE_SEARCH  |PARTITIONED|
                                                                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
                                                                             -- ASSIGN  |PARTITIONED|
-                                                                              -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
\ No newline at end of file
+                                                                              -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterix-app/src/test/resources/optimizerts/results/nested-open-index/btree-index-join/leftouterjoin-probe-pidx-with-join-btree-sidx_01_1.plan b/asterix-app/src/test/resources/optimizerts/results/nested-open-index/btree-index-join/leftouterjoin-probe-pidx-with-join-btree-sidx_01_1.plan
index 9fc1275..e108f8b 100644
--- a/asterix-app/src/test/resources/optimizerts/results/nested-open-index/btree-index-join/leftouterjoin-probe-pidx-with-join-btree-sidx_01_1.plan
+++ b/asterix-app/src/test/resources/optimizerts/results/nested-open-index/btree-index-join/leftouterjoin-probe-pidx-with-join-btree-sidx_01_1.plan
@@ -2,42 +2,41 @@
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
     -- STREAM_PROJECT  |PARTITIONED|
       -- ASSIGN  |PARTITIONED|
-        -- STREAM_PROJECT  |PARTITIONED|
-          -- SORT_MERGE_EXCHANGE [$$41(ASC) ]  |PARTITIONED|
-            -- STABLE_SORT [$$41(ASC)]  |PARTITIONED|
-              -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                -- STREAM_PROJECT  |PARTITIONED|
-                  -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                    -- PRE_CLUSTERED_GROUP_BY[$$35]  |PARTITIONED|
-                            {
-                              -- AGGREGATE  |LOCAL|
-                                -- STREAM_SELECT  |LOCAL|
-                                  -- NESTED_TUPLE_SOURCE  |LOCAL|
-                            }
-                      -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                        -- STABLE_SORT [$$35(ASC), $$38(ASC)]  |PARTITIONED|
-                          -- HASH_PARTITION_EXCHANGE [$$35]  |PARTITIONED|
-                            -- STREAM_SELECT  |PARTITIONED|
-                              -- STREAM_PROJECT  |PARTITIONED|
-                                -- ASSIGN  |PARTITIONED|
-                                  -- STREAM_PROJECT  |PARTITIONED|
-                                    -- ASSIGN  |PARTITIONED|
-                                      -- STREAM_PROJECT  |PARTITIONED|
-                                        -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                          -- BTREE_SEARCH  |PARTITIONED|
-                                            -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                              -- STABLE_SORT [$$52(ASC)]  |PARTITIONED|
-                                                -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                  -- STREAM_PROJECT  |PARTITIONED|
-                                                    -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                      -- BTREE_SEARCH  |PARTITIONED|
-                                                        -- BROADCAST_EXCHANGE  |PARTITIONED|
-                                                          -- STREAM_PROJECT  |PARTITIONED|
-                                                            -- ASSIGN  |PARTITIONED|
-                                                              -- STREAM_PROJECT  |PARTITIONED|
-                                                                -- ASSIGN  |PARTITIONED|
-                                                                  -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                                    -- BTREE_SEARCH  |PARTITIONED|
-                                                                      -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                                        -- ASSIGN  |PARTITIONED|
-                                                                          -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
\ No newline at end of file
+        -- SORT_MERGE_EXCHANGE [$$39(ASC) ]  |PARTITIONED|
+          -- STABLE_SORT [$$39(ASC)]  |PARTITIONED|
+            -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+              -- STREAM_PROJECT  |PARTITIONED|
+                -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                  -- PRE_CLUSTERED_GROUP_BY[$$30]  |PARTITIONED|
+                          {
+                            -- AGGREGATE  |LOCAL|
+                              -- STREAM_SELECT  |LOCAL|
+                                -- NESTED_TUPLE_SOURCE  |LOCAL|
+                          }
+                    -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                      -- STABLE_SORT [$$30(ASC), $$36(ASC)]  |PARTITIONED|
+                        -- HASH_PARTITION_EXCHANGE [$$30]  |PARTITIONED|
+                          -- STREAM_SELECT  |PARTITIONED|
+                            -- STREAM_PROJECT  |PARTITIONED|
+                              -- ASSIGN  |PARTITIONED|
+                                -- STREAM_PROJECT  |PARTITIONED|
+                                  -- ASSIGN  |PARTITIONED|
+                                    -- STREAM_PROJECT  |PARTITIONED|
+                                      -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                        -- BTREE_SEARCH  |PARTITIONED|
+                                          -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                            -- STABLE_SORT [$$50(ASC)]  |PARTITIONED|
+                                              -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                -- STREAM_PROJECT  |PARTITIONED|
+                                                  -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                    -- BTREE_SEARCH  |PARTITIONED|
+                                                      -- BROADCAST_EXCHANGE  |PARTITIONED|
+                                                        -- STREAM_PROJECT  |PARTITIONED|
+                                                          -- ASSIGN  |PARTITIONED|
+                                                            -- STREAM_PROJECT  |PARTITIONED|
+                                                              -- ASSIGN  |PARTITIONED|
+                                                                -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                  -- BTREE_SEARCH  |PARTITIONED|
+                                                                    -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                      -- ASSIGN  |PARTITIONED|
+                                                                        -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterix-app/src/test/resources/optimizerts/results/nested-open-index/btree-index-join/leftouterjoin-probe-pidx-with-join-btree-sidx_01_2.plan b/asterix-app/src/test/resources/optimizerts/results/nested-open-index/btree-index-join/leftouterjoin-probe-pidx-with-join-btree-sidx_01_2.plan
index 9fc1275..e108f8b 100644
--- a/asterix-app/src/test/resources/optimizerts/results/nested-open-index/btree-index-join/leftouterjoin-probe-pidx-with-join-btree-sidx_01_2.plan
+++ b/asterix-app/src/test/resources/optimizerts/results/nested-open-index/btree-index-join/leftouterjoin-probe-pidx-with-join-btree-sidx_01_2.plan
@@ -2,42 +2,41 @@
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
     -- STREAM_PROJECT  |PARTITIONED|
       -- ASSIGN  |PARTITIONED|
-        -- STREAM_PROJECT  |PARTITIONED|
-          -- SORT_MERGE_EXCHANGE [$$41(ASC) ]  |PARTITIONED|
-            -- STABLE_SORT [$$41(ASC)]  |PARTITIONED|
-              -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                -- STREAM_PROJECT  |PARTITIONED|
-                  -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                    -- PRE_CLUSTERED_GROUP_BY[$$35]  |PARTITIONED|
-                            {
-                              -- AGGREGATE  |LOCAL|
-                                -- STREAM_SELECT  |LOCAL|
-                                  -- NESTED_TUPLE_SOURCE  |LOCAL|
-                            }
-                      -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                        -- STABLE_SORT [$$35(ASC), $$38(ASC)]  |PARTITIONED|
-                          -- HASH_PARTITION_EXCHANGE [$$35]  |PARTITIONED|
-                            -- STREAM_SELECT  |PARTITIONED|
-                              -- STREAM_PROJECT  |PARTITIONED|
-                                -- ASSIGN  |PARTITIONED|
-                                  -- STREAM_PROJECT  |PARTITIONED|
-                                    -- ASSIGN  |PARTITIONED|
-                                      -- STREAM_PROJECT  |PARTITIONED|
-                                        -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                          -- BTREE_SEARCH  |PARTITIONED|
-                                            -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                              -- STABLE_SORT [$$52(ASC)]  |PARTITIONED|
-                                                -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                  -- STREAM_PROJECT  |PARTITIONED|
-                                                    -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                      -- BTREE_SEARCH  |PARTITIONED|
-                                                        -- BROADCAST_EXCHANGE  |PARTITIONED|
-                                                          -- STREAM_PROJECT  |PARTITIONED|
-                                                            -- ASSIGN  |PARTITIONED|
-                                                              -- STREAM_PROJECT  |PARTITIONED|
-                                                                -- ASSIGN  |PARTITIONED|
-                                                                  -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                                    -- BTREE_SEARCH  |PARTITIONED|
-                                                                      -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                                        -- ASSIGN  |PARTITIONED|
-                                                                          -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
\ No newline at end of file
+        -- SORT_MERGE_EXCHANGE [$$39(ASC) ]  |PARTITIONED|
+          -- STABLE_SORT [$$39(ASC)]  |PARTITIONED|
+            -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+              -- STREAM_PROJECT  |PARTITIONED|
+                -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                  -- PRE_CLUSTERED_GROUP_BY[$$30]  |PARTITIONED|
+                          {
+                            -- AGGREGATE  |LOCAL|
+                              -- STREAM_SELECT  |LOCAL|
+                                -- NESTED_TUPLE_SOURCE  |LOCAL|
+                          }
+                    -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                      -- STABLE_SORT [$$30(ASC), $$36(ASC)]  |PARTITIONED|
+                        -- HASH_PARTITION_EXCHANGE [$$30]  |PARTITIONED|
+                          -- STREAM_SELECT  |PARTITIONED|
+                            -- STREAM_PROJECT  |PARTITIONED|
+                              -- ASSIGN  |PARTITIONED|
+                                -- STREAM_PROJECT  |PARTITIONED|
+                                  -- ASSIGN  |PARTITIONED|
+                                    -- STREAM_PROJECT  |PARTITIONED|
+                                      -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                        -- BTREE_SEARCH  |PARTITIONED|
+                                          -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                            -- STABLE_SORT [$$50(ASC)]  |PARTITIONED|
+                                              -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                -- STREAM_PROJECT  |PARTITIONED|
+                                                  -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                    -- BTREE_SEARCH  |PARTITIONED|
+                                                      -- BROADCAST_EXCHANGE  |PARTITIONED|
+                                                        -- STREAM_PROJECT  |PARTITIONED|
+                                                          -- ASSIGN  |PARTITIONED|
+                                                            -- STREAM_PROJECT  |PARTITIONED|
+                                                              -- ASSIGN  |PARTITIONED|
+                                                                -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                  -- BTREE_SEARCH  |PARTITIONED|
+                                                                    -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                      -- ASSIGN  |PARTITIONED|
+                                                                        -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterix-app/src/test/resources/optimizerts/results/nested-open-index/btree-index-join/leftouterjoin-probe-pidx-with-join-btree-sidx_02_1.plan b/asterix-app/src/test/resources/optimizerts/results/nested-open-index/btree-index-join/leftouterjoin-probe-pidx-with-join-btree-sidx_02_1.plan
index 1b3bdd8..2a4e565 100644
--- a/asterix-app/src/test/resources/optimizerts/results/nested-open-index/btree-index-join/leftouterjoin-probe-pidx-with-join-btree-sidx_02_1.plan
+++ b/asterix-app/src/test/resources/optimizerts/results/nested-open-index/btree-index-join/leftouterjoin-probe-pidx-with-join-btree-sidx_02_1.plan
@@ -2,42 +2,41 @@
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
     -- STREAM_PROJECT  |PARTITIONED|
       -- ASSIGN  |PARTITIONED|
-        -- STREAM_PROJECT  |PARTITIONED|
-          -- SORT_MERGE_EXCHANGE [$$50(ASC) ]  |PARTITIONED|
-            -- STABLE_SORT [$$50(ASC)]  |PARTITIONED|
-              -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                -- STREAM_PROJECT  |PARTITIONED|
-                  -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                    -- PRE_CLUSTERED_GROUP_BY[$$42]  |PARTITIONED|
-                            {
-                              -- AGGREGATE  |LOCAL|
-                                -- STREAM_SELECT  |LOCAL|
-                                  -- NESTED_TUPLE_SOURCE  |LOCAL|
-                            }
-                      -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                        -- STABLE_SORT [$$42(ASC), $$47(ASC)]  |PARTITIONED|
-                          -- HASH_PARTITION_EXCHANGE [$$42]  |PARTITIONED|
-                            -- STREAM_SELECT  |PARTITIONED|
-                              -- STREAM_PROJECT  |PARTITIONED|
-                                -- ASSIGN  |PARTITIONED|
-                                  -- STREAM_PROJECT  |PARTITIONED|
-                                    -- ASSIGN  |PARTITIONED|
-                                      -- STREAM_PROJECT  |PARTITIONED|
-                                        -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                          -- BTREE_SEARCH  |PARTITIONED|
-                                            -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                              -- STABLE_SORT [$$60(ASC)]  |PARTITIONED|
-                                                -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                  -- STREAM_PROJECT  |PARTITIONED|
-                                                    -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                      -- BTREE_SEARCH  |PARTITIONED|
-                                                        -- BROADCAST_EXCHANGE  |PARTITIONED|
-                                                          -- STREAM_PROJECT  |PARTITIONED|
-                                                            -- ASSIGN  |PARTITIONED|
-                                                              -- STREAM_PROJECT  |PARTITIONED|
-                                                                -- ASSIGN  |PARTITIONED|
-                                                                  -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                                    -- BTREE_SEARCH  |PARTITIONED|
-                                                                      -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                                        -- ASSIGN  |PARTITIONED|
-                                                                          -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
\ No newline at end of file
+        -- SORT_MERGE_EXCHANGE [$$48(ASC) ]  |PARTITIONED|
+          -- STABLE_SORT [$$48(ASC)]  |PARTITIONED|
+            -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+              -- STREAM_PROJECT  |PARTITIONED|
+                -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                  -- PRE_CLUSTERED_GROUP_BY[$$36]  |PARTITIONED|
+                          {
+                            -- AGGREGATE  |LOCAL|
+                              -- STREAM_SELECT  |LOCAL|
+                                -- NESTED_TUPLE_SOURCE  |LOCAL|
+                          }
+                    -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                      -- STABLE_SORT [$$36(ASC), $$45(ASC)]  |PARTITIONED|
+                        -- HASH_PARTITION_EXCHANGE [$$36]  |PARTITIONED|
+                          -- STREAM_SELECT  |PARTITIONED|
+                            -- STREAM_PROJECT  |PARTITIONED|
+                              -- ASSIGN  |PARTITIONED|
+                                -- STREAM_PROJECT  |PARTITIONED|
+                                  -- ASSIGN  |PARTITIONED|
+                                    -- STREAM_PROJECT  |PARTITIONED|
+                                      -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                        -- BTREE_SEARCH  |PARTITIONED|
+                                          -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                            -- STABLE_SORT [$$58(ASC)]  |PARTITIONED|
+                                              -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                -- STREAM_PROJECT  |PARTITIONED|
+                                                  -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                    -- BTREE_SEARCH  |PARTITIONED|
+                                                      -- BROADCAST_EXCHANGE  |PARTITIONED|
+                                                        -- STREAM_PROJECT  |PARTITIONED|
+                                                          -- ASSIGN  |PARTITIONED|
+                                                            -- STREAM_PROJECT  |PARTITIONED|
+                                                              -- ASSIGN  |PARTITIONED|
+                                                                -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                  -- BTREE_SEARCH  |PARTITIONED|
+                                                                    -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                      -- ASSIGN  |PARTITIONED|
+                                                                        -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterix-app/src/test/resources/optimizerts/results/nested-open-index/btree-index-join/leftouterjoin-probe-pidx-with-join-btree-sidx_02_2.plan b/asterix-app/src/test/resources/optimizerts/results/nested-open-index/btree-index-join/leftouterjoin-probe-pidx-with-join-btree-sidx_02_2.plan
index 1b3bdd8..2a4e565 100644
--- a/asterix-app/src/test/resources/optimizerts/results/nested-open-index/btree-index-join/leftouterjoin-probe-pidx-with-join-btree-sidx_02_2.plan
+++ b/asterix-app/src/test/resources/optimizerts/results/nested-open-index/btree-index-join/leftouterjoin-probe-pidx-with-join-btree-sidx_02_2.plan
@@ -2,42 +2,41 @@
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
     -- STREAM_PROJECT  |PARTITIONED|
       -- ASSIGN  |PARTITIONED|
-        -- STREAM_PROJECT  |PARTITIONED|
-          -- SORT_MERGE_EXCHANGE [$$50(ASC) ]  |PARTITIONED|
-            -- STABLE_SORT [$$50(ASC)]  |PARTITIONED|
-              -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                -- STREAM_PROJECT  |PARTITIONED|
-                  -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                    -- PRE_CLUSTERED_GROUP_BY[$$42]  |PARTITIONED|
-                            {
-                              -- AGGREGATE  |LOCAL|
-                                -- STREAM_SELECT  |LOCAL|
-                                  -- NESTED_TUPLE_SOURCE  |LOCAL|
-                            }
-                      -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                        -- STABLE_SORT [$$42(ASC), $$47(ASC)]  |PARTITIONED|
-                          -- HASH_PARTITION_EXCHANGE [$$42]  |PARTITIONED|
-                            -- STREAM_SELECT  |PARTITIONED|
-                              -- STREAM_PROJECT  |PARTITIONED|
-                                -- ASSIGN  |PARTITIONED|
-                                  -- STREAM_PROJECT  |PARTITIONED|
-                                    -- ASSIGN  |PARTITIONED|
-                                      -- STREAM_PROJECT  |PARTITIONED|
-                                        -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                          -- BTREE_SEARCH  |PARTITIONED|
-                                            -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                              -- STABLE_SORT [$$60(ASC)]  |PARTITIONED|
-                                                -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                  -- STREAM_PROJECT  |PARTITIONED|
-                                                    -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                      -- BTREE_SEARCH  |PARTITIONED|
-                                                        -- BROADCAST_EXCHANGE  |PARTITIONED|
-                                                          -- STREAM_PROJECT  |PARTITIONED|
-                                                            -- ASSIGN  |PARTITIONED|
-                                                              -- STREAM_PROJECT  |PARTITIONED|
-                                                                -- ASSIGN  |PARTITIONED|
-                                                                  -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                                    -- BTREE_SEARCH  |PARTITIONED|
-                                                                      -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                                        -- ASSIGN  |PARTITIONED|
-                                                                          -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
\ No newline at end of file
+        -- SORT_MERGE_EXCHANGE [$$48(ASC) ]  |PARTITIONED|
+          -- STABLE_SORT [$$48(ASC)]  |PARTITIONED|
+            -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+              -- STREAM_PROJECT  |PARTITIONED|
+                -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                  -- PRE_CLUSTERED_GROUP_BY[$$36]  |PARTITIONED|
+                          {
+                            -- AGGREGATE  |LOCAL|
+                              -- STREAM_SELECT  |LOCAL|
+                                -- NESTED_TUPLE_SOURCE  |LOCAL|
+                          }
+                    -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                      -- STABLE_SORT [$$36(ASC), $$45(ASC)]  |PARTITIONED|
+                        -- HASH_PARTITION_EXCHANGE [$$36]  |PARTITIONED|
+                          -- STREAM_SELECT  |PARTITIONED|
+                            -- STREAM_PROJECT  |PARTITIONED|
+                              -- ASSIGN  |PARTITIONED|
+                                -- STREAM_PROJECT  |PARTITIONED|
+                                  -- ASSIGN  |PARTITIONED|
+                                    -- STREAM_PROJECT  |PARTITIONED|
+                                      -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                        -- BTREE_SEARCH  |PARTITIONED|
+                                          -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                            -- STABLE_SORT [$$58(ASC)]  |PARTITIONED|
+                                              -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                -- STREAM_PROJECT  |PARTITIONED|
+                                                  -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                    -- BTREE_SEARCH  |PARTITIONED|
+                                                      -- BROADCAST_EXCHANGE  |PARTITIONED|
+                                                        -- STREAM_PROJECT  |PARTITIONED|
+                                                          -- ASSIGN  |PARTITIONED|
+                                                            -- STREAM_PROJECT  |PARTITIONED|
+                                                              -- ASSIGN  |PARTITIONED|
+                                                                -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                  -- BTREE_SEARCH  |PARTITIONED|
+                                                                    -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                      -- ASSIGN  |PARTITIONED|
+                                                                        -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterix-app/src/test/resources/optimizerts/results/nested-open-index/inverted-index-join/leftouterjoin-probe-pidx-with-join-edit-distance-check-idx_01.plan b/asterix-app/src/test/resources/optimizerts/results/nested-open-index/inverted-index-join/leftouterjoin-probe-pidx-with-join-edit-distance-check-idx_01.plan
index f2122aa..5d46f46 100644
--- a/asterix-app/src/test/resources/optimizerts/results/nested-open-index/inverted-index-join/leftouterjoin-probe-pidx-with-join-edit-distance-check-idx_01.plan
+++ b/asterix-app/src/test/resources/optimizerts/results/nested-open-index/inverted-index-join/leftouterjoin-probe-pidx-with-join-edit-distance-check-idx_01.plan
@@ -2,94 +2,93 @@
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
     -- STREAM_PROJECT  |PARTITIONED|
       -- ASSIGN  |PARTITIONED|
-        -- STREAM_PROJECT  |PARTITIONED|
-          -- SORT_MERGE_EXCHANGE [$$53(ASC) ]  |PARTITIONED|
-            -- STABLE_SORT [$$53(ASC)]  |PARTITIONED|
-              -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                -- STREAM_PROJECT  |PARTITIONED|
-                  -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                    -- PRE_CLUSTERED_GROUP_BY[$$45]  |PARTITIONED|
-                            {
-                              -- AGGREGATE  |LOCAL|
-                                -- STREAM_SELECT  |LOCAL|
-                                  -- NESTED_TUPLE_SOURCE  |LOCAL|
-                            }
-                      -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                        -- STABLE_SORT [$$45(ASC), $$50(ASC)]  |PARTITIONED|
-                          -- HASH_PARTITION_EXCHANGE [$$45]  |PARTITIONED|
-                            -- STREAM_PROJECT  |PARTITIONED|
-                              -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                -- HYBRID_HASH_JOIN [$$64][$$45]  |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|
-                                                  -- BTREE_SEARCH  |PARTITIONED|
-                                                    -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                      -- ASSIGN  |PARTITIONED|
-                                                        -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
-                                  -- HASH_PARTITION_EXCHANGE [$$45]  |PARTITIONED|
-                                    -- UNION_ALL  |PARTITIONED|
-                                      -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                        -- STREAM_PROJECT  |PARTITIONED|
-                                          -- STREAM_SELECT  |PARTITIONED|
-                                            -- STREAM_PROJECT  |PARTITIONED|
-                                              -- ASSIGN  |PARTITIONED|
-                                                -- STREAM_PROJECT  |PARTITIONED|
-                                                  -- ASSIGN  |PARTITIONED|
-                                                    -- STREAM_PROJECT  |PARTITIONED|
-                                                      -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                        -- BTREE_SEARCH  |PARTITIONED|
-                                                          -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                            -- STABLE_SORT [$$76(ASC)]  |PARTITIONED|
-                                                              -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                                -- LENGTH_PARTITIONED_INVERTED_INDEX_SEARCH  |PARTITIONED|
-                                                                  -- BROADCAST_EXCHANGE  |PARTITIONED|
-                                                                    -- STREAM_SELECT  |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|
-                                                                                          -- BTREE_SEARCH  |PARTITIONED|
-                                                                                            -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                                                              -- ASSIGN  |PARTITIONED|
-                                                                                                -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
-                                      -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                        -- STREAM_PROJECT  |PARTITIONED|
+        -- SORT_MERGE_EXCHANGE [$$51(ASC) ]  |PARTITIONED|
+          -- STABLE_SORT [$$51(ASC)]  |PARTITIONED|
+            -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+              -- STREAM_PROJECT  |PARTITIONED|
+                -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                  -- PRE_CLUSTERED_GROUP_BY[$$39]  |PARTITIONED|
+                          {
+                            -- AGGREGATE  |LOCAL|
+                              -- STREAM_SELECT  |LOCAL|
+                                -- NESTED_TUPLE_SOURCE  |LOCAL|
+                          }
+                    -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                      -- STABLE_SORT [$$39(ASC), $$48(ASC)]  |PARTITIONED|
+                        -- HASH_PARTITION_EXCHANGE [$$39]  |PARTITIONED|
+                          -- STREAM_PROJECT  |PARTITIONED|
+                            -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                              -- HYBRID_HASH_JOIN [$$62][$$39]  |PARTITIONED|
+                                -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                  -- STREAM_PROJECT  |PARTITIONED|
+                                    -- ASSIGN  |PARTITIONED|
+                                      -- STREAM_PROJECT  |PARTITIONED|
+                                        -- ASSIGN  |PARTITIONED|
                                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                            -- NESTED_LOOP  |PARTITIONED|
-                                              -- BROADCAST_EXCHANGE  |PARTITIONED|
-                                                -- STREAM_PROJECT  |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|
+                                            -- SPLIT  |PARTITIONED|
                                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                -- STREAM_SELECT  |PARTITIONED|
+                                                -- BTREE_SEARCH  |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|
+                                                    -- ASSIGN  |PARTITIONED|
+                                                      -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                                -- HASH_PARTITION_EXCHANGE [$$39]  |PARTITIONED|
+                                  -- UNION_ALL  |PARTITIONED|
+                                    -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                      -- STREAM_PROJECT  |PARTITIONED|
+                                        -- STREAM_SELECT  |PARTITIONED|
+                                          -- STREAM_PROJECT  |PARTITIONED|
+                                            -- ASSIGN  |PARTITIONED|
+                                              -- STREAM_PROJECT  |PARTITIONED|
+                                                -- ASSIGN  |PARTITIONED|
+                                                  -- STREAM_PROJECT  |PARTITIONED|
+                                                    -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                      -- BTREE_SEARCH  |PARTITIONED|
+                                                        -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                          -- STABLE_SORT [$$74(ASC)]  |PARTITIONED|
+                                                            -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                              -- LENGTH_PARTITIONED_INVERTED_INDEX_SEARCH  |PARTITIONED|
+                                                                -- BROADCAST_EXCHANGE  |PARTITIONED|
+                                                                  -- STREAM_SELECT  |PARTITIONED|
                                                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                                      -- BTREE_SEARCH  |PARTITIONED|
+                                                                      -- SPLIT  |PARTITIONED|
                                                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                                          -- ASSIGN  |PARTITIONED|
-                                                                            -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
\ No newline at end of file
+                                                                          -- STREAM_PROJECT  |PARTITIONED|
+                                                                            -- ASSIGN  |PARTITIONED|
+                                                                              -- STREAM_PROJECT  |PARTITIONED|
+                                                                                -- ASSIGN  |PARTITIONED|
+                                                                                  -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                    -- SPLIT  |PARTITIONED|
+                                                                                      -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                        -- BTREE_SEARCH  |PARTITIONED|
+                                                                                          -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                            -- ASSIGN  |PARTITIONED|
+                                                                                              -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                                    -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                      -- STREAM_PROJECT  |PARTITIONED|
+                                        -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                          -- NESTED_LOOP  |PARTITIONED|
+                                            -- BROADCAST_EXCHANGE  |PARTITIONED|
+                                              -- STREAM_PROJECT  |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|
+                                            -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                              -- STREAM_SELECT  |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|
+                                                                    -- BTREE_SEARCH  |PARTITIONED|
+                                                                      -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                        -- ASSIGN  |PARTITIONED|
+                                                                          -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterix-app/src/test/resources/optimizerts/results/nested-open-index/rtree-index-join/leftouterjoin-probe-pidx-with-join-rtree-sidx_01.plan b/asterix-app/src/test/resources/optimizerts/results/nested-open-index/rtree-index-join/leftouterjoin-probe-pidx-with-join-rtree-sidx_01.plan
index d3596ca..abb7519 100644
--- a/asterix-app/src/test/resources/optimizerts/results/nested-open-index/rtree-index-join/leftouterjoin-probe-pidx-with-join-rtree-sidx_01.plan
+++ b/asterix-app/src/test/resources/optimizerts/results/nested-open-index/rtree-index-join/leftouterjoin-probe-pidx-with-join-rtree-sidx_01.plan
@@ -2,20 +2,20 @@
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
     -- STREAM_PROJECT  |PARTITIONED|
       -- ASSIGN  |PARTITIONED|
-        -- SORT_MERGE_EXCHANGE [$$41(ASC) ]  |PARTITIONED|
-          -- STABLE_SORT [$$41(ASC)]  |PARTITIONED|
+        -- SORT_MERGE_EXCHANGE [$$39(ASC) ]  |PARTITIONED|
+          -- STABLE_SORT [$$39(ASC)]  |PARTITIONED|
             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
               -- STREAM_PROJECT  |PARTITIONED|
                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                  -- PRE_CLUSTERED_GROUP_BY[$$34]  |PARTITIONED|
+                  -- PRE_CLUSTERED_GROUP_BY[$$30]  |PARTITIONED|
                           {
                             -- AGGREGATE  |LOCAL|
                               -- STREAM_SELECT  |LOCAL|
                                 -- NESTED_TUPLE_SOURCE  |LOCAL|
                           }
                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                      -- STABLE_SORT [$$34(ASC), $$38(ASC)]  |PARTITIONED|
-                        -- HASH_PARTITION_EXCHANGE [$$34]  |PARTITIONED|
+                      -- STABLE_SORT [$$30(ASC), $$36(ASC)]  |PARTITIONED|
+                        -- HASH_PARTITION_EXCHANGE [$$30]  |PARTITIONED|
                           -- STREAM_PROJECT  |PARTITIONED|
                             -- STREAM_SELECT  |PARTITIONED|
                               -- STREAM_PROJECT  |PARTITIONED|
@@ -25,7 +25,7 @@
                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
                                         -- BTREE_SEARCH  |PARTITIONED|
                                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                            -- STABLE_SORT [$$59(ASC)]  |PARTITIONED|
+                                            -- STABLE_SORT [$$56(ASC)]  |PARTITIONED|
                                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
                                                 -- STREAM_PROJECT  |PARTITIONED|
                                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
@@ -41,4 +41,4 @@
                                                                       -- BTREE_SEARCH  |PARTITIONED|
                                                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
                                                                           -- ASSIGN  |PARTITIONED|
-                                                                            -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
\ No newline at end of file
+                                                                            -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterix-app/src/test/resources/optimizerts/results/nested-open-index/rtree-index-join/leftouterjoin-probe-pidx-with-join-rtree-sidx_02.plan b/asterix-app/src/test/resources/optimizerts/results/nested-open-index/rtree-index-join/leftouterjoin-probe-pidx-with-join-rtree-sidx_02.plan
index 972233e..08bd165 100644
--- a/asterix-app/src/test/resources/optimizerts/results/nested-open-index/rtree-index-join/leftouterjoin-probe-pidx-with-join-rtree-sidx_02.plan
+++ b/asterix-app/src/test/resources/optimizerts/results/nested-open-index/rtree-index-join/leftouterjoin-probe-pidx-with-join-rtree-sidx_02.plan
@@ -2,20 +2,20 @@
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
     -- STREAM_PROJECT  |PARTITIONED|
       -- ASSIGN  |PARTITIONED|
-        -- SORT_MERGE_EXCHANGE [$$50(ASC) ]  |PARTITIONED|
-          -- STABLE_SORT [$$50(ASC)]  |PARTITIONED|
+        -- SORT_MERGE_EXCHANGE [$$40(ASC) ]  |PARTITIONED|
+          -- STABLE_SORT [$$40(ASC)]  |PARTITIONED|
             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
               -- STREAM_PROJECT  |PARTITIONED|
                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                  -- PRE_CLUSTERED_GROUP_BY[$$41]  |PARTITIONED|
+                  -- PRE_CLUSTERED_GROUP_BY[$$37]  |PARTITIONED|
                           {
                             -- AGGREGATE  |LOCAL|
                               -- STREAM_SELECT  |LOCAL|
                                 -- NESTED_TUPLE_SOURCE  |LOCAL|
                           }
                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                      -- STABLE_SORT [$$41(ASC), $$47(ASC)]  |PARTITIONED|
-                        -- HASH_PARTITION_EXCHANGE [$$41]  |PARTITIONED|
+                      -- STABLE_SORT [$$37(ASC), $$45(ASC)]  |PARTITIONED|
+                        -- HASH_PARTITION_EXCHANGE [$$37]  |PARTITIONED|
                           -- STREAM_PROJECT  |PARTITIONED|
                             -- STREAM_SELECT  |PARTITIONED|
                               -- STREAM_PROJECT  |PARTITIONED|
@@ -26,7 +26,7 @@
                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
                                           -- BTREE_SEARCH  |PARTITIONED|
                                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                              -- STABLE_SORT [$$69(ASC)]  |PARTITIONED|
+                                              -- STABLE_SORT [$$66(ASC)]  |PARTITIONED|
                                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
                                                   -- STREAM_PROJECT  |PARTITIONED|
                                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
@@ -42,4 +42,4 @@
                                                                         -- BTREE_SEARCH  |PARTITIONED|
                                                                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
                                                                             -- ASSIGN  |PARTITIONED|
-                                                                              -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
\ No newline at end of file
+                                                                              -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterix-app/src/test/resources/optimizerts/results/nested_loj2.plan b/asterix-app/src/test/resources/optimizerts/results/nested_loj2.plan
index 41ae699..08b156e 100644
--- a/asterix-app/src/test/resources/optimizerts/results/nested_loj2.plan
+++ b/asterix-app/src/test/resources/optimizerts/results/nested_loj2.plan
@@ -4,10 +4,10 @@
       -- ASSIGN  |PARTITIONED|
         -- STREAM_PROJECT  |PARTITIONED|
           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-            -- PRE_CLUSTERED_GROUP_BY[$$25]  |PARTITIONED|
+            -- PRE_CLUSTERED_GROUP_BY[$$18]  |PARTITIONED|
                     {
                       -- AGGREGATE  |LOCAL|
-                        -- MICRO_PRE_CLUSTERED_GROUP_BY[$$23]  |LOCAL|
+                        -- MICRO_PRE_CLUSTERED_GROUP_BY[$$19]  |LOCAL|
                                 {
                                   -- AGGREGATE  |LOCAL|
                                     -- STREAM_SELECT  |LOCAL|
@@ -17,25 +17,23 @@
                             -- NESTED_TUPLE_SOURCE  |LOCAL|
                     }
               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                -- STABLE_SORT [$$25(ASC), $$23(ASC)]  |PARTITIONED|
-                  -- HASH_PARTITION_EXCHANGE [$$25]  |PARTITIONED|
+                -- STABLE_SORT [$$18(ASC), $$19(ASC)]  |PARTITIONED|
+                  -- HASH_PARTITION_EXCHANGE [$$18]  |PARTITIONED|
                     -- STREAM_PROJECT  |PARTITIONED|
                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                        -- HYBRID_HASH_JOIN [$$23][$$20]  |PARTITIONED|
-                          -- HASH_PARTITION_EXCHANGE [$$23]  |PARTITIONED|
-                            -- STREAM_PROJECT  |PARTITIONED|
+                        -- HYBRID_HASH_JOIN [$$19][$$20]  |PARTITIONED|
+                          -- HASH_PARTITION_EXCHANGE [$$19]  |PARTITIONED|
+                            -- HYBRID_HASH_JOIN [$$18][$$22]  |PARTITIONED|
                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                -- HYBRID_HASH_JOIN [$$25][$$26]  |PARTITIONED|
+                                -- DATASOURCE_SCAN  |PARTITIONED|
+                                  -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                    -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                              -- HASH_PARTITION_EXCHANGE [$$22]  |PARTITIONED|
+                                -- ASSIGN  |PARTITIONED|
                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
                                     -- DATASOURCE_SCAN  |PARTITIONED|
                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
                                         -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
-                                  -- HASH_PARTITION_EXCHANGE [$$26]  |PARTITIONED|
-                                    -- ASSIGN  |PARTITIONED|
-                                      -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                        -- DATASOURCE_SCAN  |PARTITIONED|
-                                          -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                            -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
                           -- HASH_PARTITION_EXCHANGE [$$20]  |PARTITIONED|
                             -- ASSIGN  |PARTITIONED|
                               -- STREAM_PROJECT  |PARTITIONED|
diff --git a/asterix-app/src/test/resources/optimizerts/results/nested_loj3.plan b/asterix-app/src/test/resources/optimizerts/results/nested_loj3.plan
index fbb0422..957a2ee 100644
--- a/asterix-app/src/test/resources/optimizerts/results/nested_loj3.plan
+++ b/asterix-app/src/test/resources/optimizerts/results/nested_loj3.plan
@@ -4,13 +4,13 @@
       -- ASSIGN  |PARTITIONED|
         -- STREAM_PROJECT  |PARTITIONED|
           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-            -- PRE_CLUSTERED_GROUP_BY[$$42]  |PARTITIONED|
+            -- PRE_CLUSTERED_GROUP_BY[$$30]  |PARTITIONED|
                     {
                       -- AGGREGATE  |LOCAL|
-                        -- MICRO_PRE_CLUSTERED_GROUP_BY[$$40]  |LOCAL|
+                        -- MICRO_PRE_CLUSTERED_GROUP_BY[$$31]  |LOCAL|
                                 {
                                   -- AGGREGATE  |LOCAL|
-                                    -- MICRO_PRE_CLUSTERED_GROUP_BY[$$37, $$38]  |LOCAL|
+                                    -- MICRO_PRE_CLUSTERED_GROUP_BY[$$32, $$33]  |LOCAL|
                                             {
                                               -- AGGREGATE  |LOCAL|
                                                 -- STREAM_SELECT  |LOCAL|
@@ -19,33 +19,31 @@
                                       -- STREAM_SELECT  |LOCAL|
                                         -- NESTED_TUPLE_SOURCE  |LOCAL|
                                 }
-                          -- IN_MEMORY_STABLE_SORT [$$40(ASC), $$37(ASC), $$38(ASC)]  |LOCAL|
+                          -- IN_MEMORY_STABLE_SORT [$$31(ASC), $$32(ASC), $$33(ASC)]  |LOCAL|
                             -- STREAM_SELECT  |LOCAL|
                               -- NESTED_TUPLE_SOURCE  |LOCAL|
                     }
               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                -- STABLE_SORT [$$42(ASC), $$40(ASC)]  |PARTITIONED|
-                  -- HASH_PARTITION_EXCHANGE [$$42]  |PARTITIONED|
+                -- STABLE_SORT [$$30(ASC), $$31(ASC)]  |PARTITIONED|
+                  -- HASH_PARTITION_EXCHANGE [$$30]  |PARTITIONED|
                     -- STREAM_PROJECT  |PARTITIONED|
                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                        -- HYBRID_HASH_JOIN [$$48, $$50][$$34, $$35]  |PARTITIONED|
-                          -- HASH_PARTITION_EXCHANGE [$$48, $$50]  |PARTITIONED|
-                            -- HYBRID_HASH_JOIN [$$40][$$37]  |PARTITIONED|
-                              -- HASH_PARTITION_EXCHANGE [$$40]  |PARTITIONED|
-                                -- STREAM_PROJECT  |PARTITIONED|
+                        -- HYBRID_HASH_JOIN [$$41, $$43][$$34, $$35]  |PARTITIONED|
+                          -- HASH_PARTITION_EXCHANGE [$$41, $$43]  |PARTITIONED|
+                            -- HYBRID_HASH_JOIN [$$31][$$32]  |PARTITIONED|
+                              -- HASH_PARTITION_EXCHANGE [$$31]  |PARTITIONED|
+                                -- HYBRID_HASH_JOIN [$$30][$$36]  |PARTITIONED|
                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                    -- HYBRID_HASH_JOIN [$$42][$$43]  |PARTITIONED|
+                                    -- DATASOURCE_SCAN  |PARTITIONED|
+                                      -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                        -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                                  -- HASH_PARTITION_EXCHANGE [$$36]  |PARTITIONED|
+                                    -- ASSIGN  |PARTITIONED|
                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
                                         -- DATASOURCE_SCAN  |PARTITIONED|
                                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
                                             -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
-                                      -- HASH_PARTITION_EXCHANGE [$$43]  |PARTITIONED|
-                                        -- ASSIGN  |PARTITIONED|
-                                          -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                            -- DATASOURCE_SCAN  |PARTITIONED|
-                                              -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
-                              -- HASH_PARTITION_EXCHANGE [$$37]  |PARTITIONED|
+                              -- HASH_PARTITION_EXCHANGE [$$32]  |PARTITIONED|
                                 -- ASSIGN  |PARTITIONED|
                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
                                     -- DATASOURCE_SCAN  |PARTITIONED|
diff --git a/asterix-app/src/test/resources/optimizerts/results/nested_loj4.plan b/asterix-app/src/test/resources/optimizerts/results/nested_loj4.plan
new file mode 100644
index 0000000..340b115
--- /dev/null
+++ b/asterix-app/src/test/resources/optimizerts/results/nested_loj4.plan
@@ -0,0 +1,39 @@
+-- DISTRIBUTE_RESULT  |PARTITIONED|
+  -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    -- STREAM_PROJECT  |PARTITIONED|
+      -- ASSIGN  |PARTITIONED|
+        -- STREAM_PROJECT  |PARTITIONED|
+          -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+            -- PRE_CLUSTERED_GROUP_BY[$$14]  |PARTITIONED|
+                    {
+                      -- AGGREGATE  |LOCAL|
+                        -- STREAM_SELECT  |LOCAL|
+                          -- NESTED_TUPLE_SOURCE  |LOCAL|
+                    }
+              -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                -- STREAM_PROJECT  |PARTITIONED|
+                  -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                    -- HYBRID_HASH_JOIN [$$14][$$22]  |PARTITIONED|
+                      -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                        -- DATASOURCE_SCAN  |PARTITIONED|
+                          -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                            -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                      -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                        -- ASSIGN  |PARTITIONED|
+                          -- STREAM_PROJECT  |PARTITIONED|
+                            -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                              -- HYBRID_HASH_JOIN [$$22][$$16]  |PARTITIONED|
+                                -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                  -- STREAM_PROJECT  |PARTITIONED|
+                                    -- STREAM_SELECT  |PARTITIONED|
+                                      -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                        -- DATASOURCE_SCAN  |PARTITIONED|
+                                          -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                            -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                                -- HASH_PARTITION_EXCHANGE [$$16]  |PARTITIONED|
+                                  -- ASSIGN  |PARTITIONED|
+                                    -- STREAM_PROJECT  |PARTITIONED|
+                                      -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                        -- DATASOURCE_SCAN  |PARTITIONED|
+                                          -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                            -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterix-app/src/test/resources/optimizerts/results/open-index-enforced/btree-index-join/leftouterjoin-probe-pidx-with-join-btree-sidx_01_1.plan b/asterix-app/src/test/resources/optimizerts/results/open-index-enforced/btree-index-join/leftouterjoin-probe-pidx-with-join-btree-sidx_01_1.plan
index e3e7f39..b96830c 100644
--- a/asterix-app/src/test/resources/optimizerts/results/open-index-enforced/btree-index-join/leftouterjoin-probe-pidx-with-join-btree-sidx_01_1.plan
+++ b/asterix-app/src/test/resources/optimizerts/results/open-index-enforced/btree-index-join/leftouterjoin-probe-pidx-with-join-btree-sidx_01_1.plan
@@ -2,36 +2,33 @@
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
     -- STREAM_PROJECT  |PARTITIONED|
       -- ASSIGN  |PARTITIONED|
-        -- STREAM_PROJECT  |PARTITIONED|
-          -- SORT_MERGE_EXCHANGE [$$28(ASC) ]  |PARTITIONED|
-            -- STABLE_SORT [$$28(ASC)]  |PARTITIONED|
-              -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                -- PRE_CLUSTERED_GROUP_BY[$$24]  |PARTITIONED|
-                        {
-                          -- AGGREGATE  |LOCAL|
-                            -- STREAM_SELECT  |LOCAL|
-                              -- NESTED_TUPLE_SOURCE  |LOCAL|
-                        }
-                  -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                    -- STABLE_SORT [$$24(ASC), $$21(ASC)]  |PARTITIONED|
-                      -- HASH_PARTITION_EXCHANGE [$$24]  |PARTITIONED|
-                        -- STREAM_SELECT  |PARTITIONED|
-                          -- STREAM_PROJECT  |PARTITIONED|
-                            -- ASSIGN  |PARTITIONED|
-                              -- STREAM_PROJECT  |PARTITIONED|
-                                -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                  -- BTREE_SEARCH  |PARTITIONED|
-                                    -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                      -- STABLE_SORT [$$36(ASC)]  |PARTITIONED|
-                                        -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                          -- STREAM_PROJECT  |PARTITIONED|
-                                            -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                              -- BTREE_SEARCH  |PARTITIONED|
-                                                -- BROADCAST_EXCHANGE  |PARTITIONED|
-                                                  -- STREAM_PROJECT  |PARTITIONED|
-                                                    -- ASSIGN  |PARTITIONED|
-                                                      -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                        -- BTREE_SEARCH  |PARTITIONED|
-                                                          -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                            -- ASSIGN  |PARTITIONED|
-                                                              -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
\ No newline at end of file
+        -- SORT_MERGE_EXCHANGE [$$29(ASC) ]  |PARTITIONED|
+          -- PRE_CLUSTERED_GROUP_BY[$$20]  |PARTITIONED|
+                  {
+                    -- AGGREGATE  |LOCAL|
+                      -- STREAM_SELECT  |LOCAL|
+                        -- NESTED_TUPLE_SOURCE  |LOCAL|
+                  }
+            -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+              -- STABLE_SORT [$$20(ASC), $$21(ASC)]  |PARTITIONED|
+                -- HASH_PARTITION_EXCHANGE [$$20]  |PARTITIONED|
+                  -- STREAM_SELECT  |PARTITIONED|
+                    -- STREAM_PROJECT  |PARTITIONED|
+                      -- ASSIGN  |PARTITIONED|
+                        -- STREAM_PROJECT  |PARTITIONED|
+                          -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                            -- BTREE_SEARCH  |PARTITIONED|
+                              -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                -- STABLE_SORT [$$34(ASC)]  |PARTITIONED|
+                                  -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                    -- STREAM_PROJECT  |PARTITIONED|
+                                      -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                        -- BTREE_SEARCH  |PARTITIONED|
+                                          -- BROADCAST_EXCHANGE  |PARTITIONED|
+                                            -- STREAM_PROJECT  |PARTITIONED|
+                                              -- ASSIGN  |PARTITIONED|
+                                                -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                  -- BTREE_SEARCH  |PARTITIONED|
+                                                    -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                      -- ASSIGN  |PARTITIONED|
+                                                        -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterix-app/src/test/resources/optimizerts/results/open-index-enforced/btree-index-join/leftouterjoin-probe-pidx-with-join-btree-sidx_01_2.plan b/asterix-app/src/test/resources/optimizerts/results/open-index-enforced/btree-index-join/leftouterjoin-probe-pidx-with-join-btree-sidx_01_2.plan
index e3e7f39..b96830c 100644
--- a/asterix-app/src/test/resources/optimizerts/results/open-index-enforced/btree-index-join/leftouterjoin-probe-pidx-with-join-btree-sidx_01_2.plan
+++ b/asterix-app/src/test/resources/optimizerts/results/open-index-enforced/btree-index-join/leftouterjoin-probe-pidx-with-join-btree-sidx_01_2.plan
@@ -2,36 +2,33 @@
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
     -- STREAM_PROJECT  |PARTITIONED|
       -- ASSIGN  |PARTITIONED|
-        -- STREAM_PROJECT  |PARTITIONED|
-          -- SORT_MERGE_EXCHANGE [$$28(ASC) ]  |PARTITIONED|
-            -- STABLE_SORT [$$28(ASC)]  |PARTITIONED|
-              -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                -- PRE_CLUSTERED_GROUP_BY[$$24]  |PARTITIONED|
-                        {
-                          -- AGGREGATE  |LOCAL|
-                            -- STREAM_SELECT  |LOCAL|
-                              -- NESTED_TUPLE_SOURCE  |LOCAL|
-                        }
-                  -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                    -- STABLE_SORT [$$24(ASC), $$21(ASC)]  |PARTITIONED|
-                      -- HASH_PARTITION_EXCHANGE [$$24]  |PARTITIONED|
-                        -- STREAM_SELECT  |PARTITIONED|
-                          -- STREAM_PROJECT  |PARTITIONED|
-                            -- ASSIGN  |PARTITIONED|
-                              -- STREAM_PROJECT  |PARTITIONED|
-                                -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                  -- BTREE_SEARCH  |PARTITIONED|
-                                    -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                      -- STABLE_SORT [$$36(ASC)]  |PARTITIONED|
-                                        -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                          -- STREAM_PROJECT  |PARTITIONED|
-                                            -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                              -- BTREE_SEARCH  |PARTITIONED|
-                                                -- BROADCAST_EXCHANGE  |PARTITIONED|
-                                                  -- STREAM_PROJECT  |PARTITIONED|
-                                                    -- ASSIGN  |PARTITIONED|
-                                                      -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                        -- BTREE_SEARCH  |PARTITIONED|
-                                                          -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                            -- ASSIGN  |PARTITIONED|
-                                                              -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
\ No newline at end of file
+        -- SORT_MERGE_EXCHANGE [$$29(ASC) ]  |PARTITIONED|
+          -- PRE_CLUSTERED_GROUP_BY[$$20]  |PARTITIONED|
+                  {
+                    -- AGGREGATE  |LOCAL|
+                      -- STREAM_SELECT  |LOCAL|
+                        -- NESTED_TUPLE_SOURCE  |LOCAL|
+                  }
+            -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+              -- STABLE_SORT [$$20(ASC), $$21(ASC)]  |PARTITIONED|
+                -- HASH_PARTITION_EXCHANGE [$$20]  |PARTITIONED|
+                  -- STREAM_SELECT  |PARTITIONED|
+                    -- STREAM_PROJECT  |PARTITIONED|
+                      -- ASSIGN  |PARTITIONED|
+                        -- STREAM_PROJECT  |PARTITIONED|
+                          -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                            -- BTREE_SEARCH  |PARTITIONED|
+                              -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                -- STABLE_SORT [$$34(ASC)]  |PARTITIONED|
+                                  -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                    -- STREAM_PROJECT  |PARTITIONED|
+                                      -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                        -- BTREE_SEARCH  |PARTITIONED|
+                                          -- BROADCAST_EXCHANGE  |PARTITIONED|
+                                            -- STREAM_PROJECT  |PARTITIONED|
+                                              -- ASSIGN  |PARTITIONED|
+                                                -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                  -- BTREE_SEARCH  |PARTITIONED|
+                                                    -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                      -- ASSIGN  |PARTITIONED|
+                                                        -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterix-app/src/test/resources/optimizerts/results/open-index-enforced/btree-index-join/leftouterjoin-probe-pidx-with-join-btree-sidx_02_1.plan b/asterix-app/src/test/resources/optimizerts/results/open-index-enforced/btree-index-join/leftouterjoin-probe-pidx-with-join-btree-sidx_02_1.plan
index 34c8f98..07fde95 100644
--- a/asterix-app/src/test/resources/optimizerts/results/open-index-enforced/btree-index-join/leftouterjoin-probe-pidx-with-join-btree-sidx_02_1.plan
+++ b/asterix-app/src/test/resources/optimizerts/results/open-index-enforced/btree-index-join/leftouterjoin-probe-pidx-with-join-btree-sidx_02_1.plan
@@ -2,36 +2,33 @@
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
     -- STREAM_PROJECT  |PARTITIONED|
       -- ASSIGN  |PARTITIONED|
-        -- STREAM_PROJECT  |PARTITIONED|
-          -- SORT_MERGE_EXCHANGE [$$33(ASC) ]  |PARTITIONED|
-            -- STABLE_SORT [$$33(ASC)]  |PARTITIONED|
-              -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                -- PRE_CLUSTERED_GROUP_BY[$$29]  |PARTITIONED|
-                        {
-                          -- AGGREGATE  |LOCAL|
-                            -- STREAM_SELECT  |LOCAL|
-                              -- NESTED_TUPLE_SOURCE  |LOCAL|
-                        }
-                  -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                    -- STABLE_SORT [$$29(ASC), $$25(ASC)]  |PARTITIONED|
-                      -- HASH_PARTITION_EXCHANGE [$$29]  |PARTITIONED|
-                        -- STREAM_SELECT  |PARTITIONED|
-                          -- STREAM_PROJECT  |PARTITIONED|
-                            -- ASSIGN  |PARTITIONED|
-                              -- STREAM_PROJECT  |PARTITIONED|
-                                -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                  -- BTREE_SEARCH  |PARTITIONED|
-                                    -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                      -- STABLE_SORT [$$41(ASC)]  |PARTITIONED|
-                                        -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                          -- STREAM_PROJECT  |PARTITIONED|
-                                            -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                              -- BTREE_SEARCH  |PARTITIONED|
-                                                -- BROADCAST_EXCHANGE  |PARTITIONED|
-                                                  -- STREAM_PROJECT  |PARTITIONED|
-                                                    -- ASSIGN  |PARTITIONED|
-                                                      -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                        -- BTREE_SEARCH  |PARTITIONED|
-                                                          -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                            -- ASSIGN  |PARTITIONED|
-                                                              -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
\ No newline at end of file
+        -- SORT_MERGE_EXCHANGE [$$34(ASC) ]  |PARTITIONED|
+          -- PRE_CLUSTERED_GROUP_BY[$$24]  |PARTITIONED|
+                  {
+                    -- AGGREGATE  |LOCAL|
+                      -- STREAM_SELECT  |LOCAL|
+                        -- NESTED_TUPLE_SOURCE  |LOCAL|
+                  }
+            -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+              -- STABLE_SORT [$$24(ASC), $$25(ASC)]  |PARTITIONED|
+                -- HASH_PARTITION_EXCHANGE [$$24]  |PARTITIONED|
+                  -- STREAM_SELECT  |PARTITIONED|
+                    -- STREAM_PROJECT  |PARTITIONED|
+                      -- ASSIGN  |PARTITIONED|
+                        -- STREAM_PROJECT  |PARTITIONED|
+                          -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                            -- BTREE_SEARCH  |PARTITIONED|
+                              -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                -- STABLE_SORT [$$39(ASC)]  |PARTITIONED|
+                                  -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                    -- STREAM_PROJECT  |PARTITIONED|
+                                      -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                        -- BTREE_SEARCH  |PARTITIONED|
+                                          -- BROADCAST_EXCHANGE  |PARTITIONED|
+                                            -- STREAM_PROJECT  |PARTITIONED|
+                                              -- ASSIGN  |PARTITIONED|
+                                                -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                  -- BTREE_SEARCH  |PARTITIONED|
+                                                    -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                      -- ASSIGN  |PARTITIONED|
+                                                        -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterix-app/src/test/resources/optimizerts/results/open-index-enforced/btree-index-join/leftouterjoin-probe-pidx-with-join-btree-sidx_02_2.plan b/asterix-app/src/test/resources/optimizerts/results/open-index-enforced/btree-index-join/leftouterjoin-probe-pidx-with-join-btree-sidx_02_2.plan
index 34c8f98..07fde95 100644
--- a/asterix-app/src/test/resources/optimizerts/results/open-index-enforced/btree-index-join/leftouterjoin-probe-pidx-with-join-btree-sidx_02_2.plan
+++ b/asterix-app/src/test/resources/optimizerts/results/open-index-enforced/btree-index-join/leftouterjoin-probe-pidx-with-join-btree-sidx_02_2.plan
@@ -2,36 +2,33 @@
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
     -- STREAM_PROJECT  |PARTITIONED|
       -- ASSIGN  |PARTITIONED|
-        -- STREAM_PROJECT  |PARTITIONED|
-          -- SORT_MERGE_EXCHANGE [$$33(ASC) ]  |PARTITIONED|
-            -- STABLE_SORT [$$33(ASC)]  |PARTITIONED|
-              -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                -- PRE_CLUSTERED_GROUP_BY[$$29]  |PARTITIONED|
-                        {
-                          -- AGGREGATE  |LOCAL|
-                            -- STREAM_SELECT  |LOCAL|
-                              -- NESTED_TUPLE_SOURCE  |LOCAL|
-                        }
-                  -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                    -- STABLE_SORT [$$29(ASC), $$25(ASC)]  |PARTITIONED|
-                      -- HASH_PARTITION_EXCHANGE [$$29]  |PARTITIONED|
-                        -- STREAM_SELECT  |PARTITIONED|
-                          -- STREAM_PROJECT  |PARTITIONED|
-                            -- ASSIGN  |PARTITIONED|
-                              -- STREAM_PROJECT  |PARTITIONED|
-                                -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                  -- BTREE_SEARCH  |PARTITIONED|
-                                    -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                      -- STABLE_SORT [$$41(ASC)]  |PARTITIONED|
-                                        -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                          -- STREAM_PROJECT  |PARTITIONED|
-                                            -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                              -- BTREE_SEARCH  |PARTITIONED|
-                                                -- BROADCAST_EXCHANGE  |PARTITIONED|
-                                                  -- STREAM_PROJECT  |PARTITIONED|
-                                                    -- ASSIGN  |PARTITIONED|
-                                                      -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                        -- BTREE_SEARCH  |PARTITIONED|
-                                                          -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                            -- ASSIGN  |PARTITIONED|
-                                                              -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
\ No newline at end of file
+        -- SORT_MERGE_EXCHANGE [$$34(ASC) ]  |PARTITIONED|
+          -- PRE_CLUSTERED_GROUP_BY[$$24]  |PARTITIONED|
+                  {
+                    -- AGGREGATE  |LOCAL|
+                      -- STREAM_SELECT  |LOCAL|
+                        -- NESTED_TUPLE_SOURCE  |LOCAL|
+                  }
+            -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+              -- STABLE_SORT [$$24(ASC), $$25(ASC)]  |PARTITIONED|
+                -- HASH_PARTITION_EXCHANGE [$$24]  |PARTITIONED|
+                  -- STREAM_SELECT  |PARTITIONED|
+                    -- STREAM_PROJECT  |PARTITIONED|
+                      -- ASSIGN  |PARTITIONED|
+                        -- STREAM_PROJECT  |PARTITIONED|
+                          -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                            -- BTREE_SEARCH  |PARTITIONED|
+                              -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                -- STABLE_SORT [$$39(ASC)]  |PARTITIONED|
+                                  -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                    -- STREAM_PROJECT  |PARTITIONED|
+                                      -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                        -- BTREE_SEARCH  |PARTITIONED|
+                                          -- BROADCAST_EXCHANGE  |PARTITIONED|
+                                            -- STREAM_PROJECT  |PARTITIONED|
+                                              -- ASSIGN  |PARTITIONED|
+                                                -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                  -- BTREE_SEARCH  |PARTITIONED|
+                                                    -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                      -- ASSIGN  |PARTITIONED|
+                                                        -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterix-app/src/test/resources/optimizerts/results/open-index-enforced/inverted-index-join/leftouterjoin-probe-pidx-with-join-edit-distance-check-idx_01.plan b/asterix-app/src/test/resources/optimizerts/results/open-index-enforced/inverted-index-join/leftouterjoin-probe-pidx-with-join-edit-distance-check-idx_01.plan
index 61fabb2..e7eff62 100644
--- a/asterix-app/src/test/resources/optimizerts/results/open-index-enforced/inverted-index-join/leftouterjoin-probe-pidx-with-join-edit-distance-check-idx_01.plan
+++ b/asterix-app/src/test/resources/optimizerts/results/open-index-enforced/inverted-index-join/leftouterjoin-probe-pidx-with-join-edit-distance-check-idx_01.plan
@@ -2,82 +2,79 @@
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
     -- STREAM_PROJECT  |PARTITIONED|
       -- ASSIGN  |PARTITIONED|
-        -- STREAM_PROJECT  |PARTITIONED|
-          -- SORT_MERGE_EXCHANGE [$$36(ASC) ]  |PARTITIONED|
-            -- STABLE_SORT [$$36(ASC)]  |PARTITIONED|
-              -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                -- PRE_CLUSTERED_GROUP_BY[$$32]  |PARTITIONED|
-                        {
-                          -- AGGREGATE  |LOCAL|
-                            -- STREAM_SELECT  |LOCAL|
-                              -- NESTED_TUPLE_SOURCE  |LOCAL|
-                        }
-                  -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                    -- STABLE_SORT [$$32(ASC), $$28(ASC)]  |PARTITIONED|
-                      -- HASH_PARTITION_EXCHANGE [$$32]  |PARTITIONED|
-                        -- STREAM_PROJECT  |PARTITIONED|
-                          -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                            -- HYBRID_HASH_JOIN [$$45][$$32]  |PARTITIONED|
+        -- SORT_MERGE_EXCHANGE [$$37(ASC) ]  |PARTITIONED|
+          -- PRE_CLUSTERED_GROUP_BY[$$27]  |PARTITIONED|
+                  {
+                    -- AGGREGATE  |LOCAL|
+                      -- STREAM_SELECT  |LOCAL|
+                        -- NESTED_TUPLE_SOURCE  |LOCAL|
+                  }
+            -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+              -- STABLE_SORT [$$27(ASC), $$28(ASC)]  |PARTITIONED|
+                -- HASH_PARTITION_EXCHANGE [$$27]  |PARTITIONED|
+                  -- STREAM_PROJECT  |PARTITIONED|
+                    -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                      -- HYBRID_HASH_JOIN [$$43][$$27]  |PARTITIONED|
+                        -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                          -- STREAM_PROJECT  |PARTITIONED|
+                            -- ASSIGN  |PARTITIONED|
                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                -- STREAM_PROJECT  |PARTITIONED|
-                                  -- ASSIGN  |PARTITIONED|
-                                    -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                      -- SPLIT  |PARTITIONED|
+                                -- SPLIT  |PARTITIONED|
+                                  -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                    -- BTREE_SEARCH  |PARTITIONED|
+                                      -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                        -- ASSIGN  |PARTITIONED|
+                                          -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                        -- HASH_PARTITION_EXCHANGE [$$27]  |PARTITIONED|
+                          -- UNION_ALL  |PARTITIONED|
+                            -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                              -- STREAM_PROJECT  |PARTITIONED|
+                                -- STREAM_SELECT  |PARTITIONED|
+                                  -- STREAM_PROJECT  |PARTITIONED|
+                                    -- ASSIGN  |PARTITIONED|
+                                      -- STREAM_PROJECT  |PARTITIONED|
                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
                                           -- BTREE_SEARCH  |PARTITIONED|
                                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                              -- ASSIGN  |PARTITIONED|
-                                                -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
-                              -- HASH_PARTITION_EXCHANGE [$$32]  |PARTITIONED|
-                                -- UNION_ALL  |PARTITIONED|
-                                  -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                    -- STREAM_PROJECT  |PARTITIONED|
-                                      -- STREAM_SELECT  |PARTITIONED|
-                                        -- STREAM_PROJECT  |PARTITIONED|
-                                          -- ASSIGN  |PARTITIONED|
-                                            -- STREAM_PROJECT  |PARTITIONED|
-                                              -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                -- BTREE_SEARCH  |PARTITIONED|
-                                                  -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                    -- STABLE_SORT [$$53(ASC)]  |PARTITIONED|
-                                                      -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                        -- LENGTH_PARTITIONED_INVERTED_INDEX_SEARCH  |PARTITIONED|
-                                                          -- BROADCAST_EXCHANGE  |PARTITIONED|
-                                                            -- STREAM_SELECT  |PARTITIONED|
-                                                              -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                                -- SPLIT  |PARTITIONED|
-                                                                  -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                                    -- STREAM_PROJECT  |PARTITIONED|
-                                                                      -- ASSIGN  |PARTITIONED|
-                                                                        -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                                          -- SPLIT  |PARTITIONED|
-                                                                            -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                                              -- BTREE_SEARCH  |PARTITIONED|
-                                                                                -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                                                  -- ASSIGN  |PARTITIONED|
-                                                                                    -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
-                                  -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                    -- STREAM_PROJECT  |PARTITIONED|
-                                      -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                        -- NESTED_LOOP  |PARTITIONED|
-                                          -- BROADCAST_EXCHANGE  |PARTITIONED|
-                                            -- STREAM_PROJECT  |PARTITIONED|
-                                              -- ASSIGN  |PARTITIONED|
+                                              -- STABLE_SORT [$$51(ASC)]  |PARTITIONED|
                                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                  -- DATASOURCE_SCAN  |PARTITIONED|
-                                                    -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                      -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
-                                          -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                            -- STREAM_SELECT  |PARTITIONED|
-                                              -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                -- SPLIT  |PARTITIONED|
-                                                  -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                    -- STREAM_PROJECT  |PARTITIONED|
-                                                      -- ASSIGN  |PARTITIONED|
+                                                  -- LENGTH_PARTITIONED_INVERTED_INDEX_SEARCH  |PARTITIONED|
+                                                    -- BROADCAST_EXCHANGE  |PARTITIONED|
+                                                      -- STREAM_SELECT  |PARTITIONED|
                                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
                                                           -- SPLIT  |PARTITIONED|
                                                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                              -- BTREE_SEARCH  |PARTITIONED|
-                                                                -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                                  -- ASSIGN  |PARTITIONED|
-                                                                    -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
\ No newline at end of file
+                                                              -- STREAM_PROJECT  |PARTITIONED|
+                                                                -- ASSIGN  |PARTITIONED|
+                                                                  -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                    -- SPLIT  |PARTITIONED|
+                                                                      -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                        -- BTREE_SEARCH  |PARTITIONED|
+                                                                          -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                            -- ASSIGN  |PARTITIONED|
+                                                                              -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                            -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                              -- STREAM_PROJECT  |PARTITIONED|
+                                -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                  -- NESTED_LOOP  |PARTITIONED|
+                                    -- BROADCAST_EXCHANGE  |PARTITIONED|
+                                      -- STREAM_PROJECT  |PARTITIONED|
+                                        -- ASSIGN  |PARTITIONED|
+                                          -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                            -- DATASOURCE_SCAN  |PARTITIONED|
+                                              -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                                    -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                      -- STREAM_SELECT  |PARTITIONED|
+                                        -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                          -- SPLIT  |PARTITIONED|
+                                            -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                              -- STREAM_PROJECT  |PARTITIONED|
+                                                -- ASSIGN  |PARTITIONED|
+                                                  -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                    -- SPLIT  |PARTITIONED|
+                                                      -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                        -- BTREE_SEARCH  |PARTITIONED|
+                                                          -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                            -- ASSIGN  |PARTITIONED|
+                                                              -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterix-app/src/test/resources/optimizerts/results/open-index-enforced/rtree-index-join/leftouterjoin-probe-pidx-with-join-rtree-sidx_01.plan b/asterix-app/src/test/resources/optimizerts/results/open-index-enforced/rtree-index-join/leftouterjoin-probe-pidx-with-join-rtree-sidx_01.plan
index d871ebe..98a35ca 100644
--- a/asterix-app/src/test/resources/optimizerts/results/open-index-enforced/rtree-index-join/leftouterjoin-probe-pidx-with-join-rtree-sidx_01.plan
+++ b/asterix-app/src/test/resources/optimizerts/results/open-index-enforced/rtree-index-join/leftouterjoin-probe-pidx-with-join-rtree-sidx_01.plan
@@ -2,39 +2,36 @@
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
     -- STREAM_PROJECT  |PARTITIONED|
       -- ASSIGN  |PARTITIONED|
-        -- STREAM_PROJECT  |PARTITIONED|
-          -- SORT_MERGE_EXCHANGE [$$30(ASC) ]  |PARTITIONED|
-            -- STABLE_SORT [$$30(ASC)]  |PARTITIONED|
-              -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                -- PRE_CLUSTERED_GROUP_BY[$$27]  |PARTITIONED|
-                        {
-                          -- AGGREGATE  |LOCAL|
-                            -- STREAM_SELECT  |LOCAL|
-                              -- NESTED_TUPLE_SOURCE  |LOCAL|
-                        }
-                  -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                    -- STABLE_SORT [$$27(ASC), $$24(ASC)]  |PARTITIONED|
-                      -- HASH_PARTITION_EXCHANGE [$$27]  |PARTITIONED|
-                        -- STREAM_PROJECT  |PARTITIONED|
-                          -- STREAM_SELECT  |PARTITIONED|
-                            -- STREAM_PROJECT  |PARTITIONED|
-                              -- ASSIGN  |PARTITIONED|
-                                -- STREAM_PROJECT  |PARTITIONED|
-                                  -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                    -- BTREE_SEARCH  |PARTITIONED|
-                                      -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                        -- STABLE_SORT [$$43(ASC)]  |PARTITIONED|
-                                          -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                            -- STREAM_PROJECT  |PARTITIONED|
-                                              -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                -- RTREE_SEARCH  |PARTITIONED|
-                                                  -- BROADCAST_EXCHANGE  |PARTITIONED|
+        -- SORT_MERGE_EXCHANGE [$$30(ASC) ]  |PARTITIONED|
+          -- PRE_CLUSTERED_GROUP_BY[$$23]  |PARTITIONED|
+                  {
+                    -- AGGREGATE  |LOCAL|
+                      -- STREAM_SELECT  |LOCAL|
+                        -- NESTED_TUPLE_SOURCE  |LOCAL|
+                  }
+            -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+              -- STABLE_SORT [$$23(ASC), $$24(ASC)]  |PARTITIONED|
+                -- HASH_PARTITION_EXCHANGE [$$23]  |PARTITIONED|
+                  -- STREAM_PROJECT  |PARTITIONED|
+                    -- STREAM_SELECT  |PARTITIONED|
+                      -- STREAM_PROJECT  |PARTITIONED|
+                        -- ASSIGN  |PARTITIONED|
+                          -- STREAM_PROJECT  |PARTITIONED|
+                            -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                              -- BTREE_SEARCH  |PARTITIONED|
+                                -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                  -- STABLE_SORT [$$42(ASC)]  |PARTITIONED|
+                                    -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                      -- STREAM_PROJECT  |PARTITIONED|
+                                        -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                          -- RTREE_SEARCH  |PARTITIONED|
+                                            -- BROADCAST_EXCHANGE  |PARTITIONED|
+                                              -- ASSIGN  |PARTITIONED|
+                                                -- ASSIGN  |PARTITIONED|
+                                                  -- STREAM_PROJECT  |PARTITIONED|
                                                     -- ASSIGN  |PARTITIONED|
-                                                      -- ASSIGN  |PARTITIONED|
-                                                        -- STREAM_PROJECT  |PARTITIONED|
-                                                          -- ASSIGN  |PARTITIONED|
-                                                            -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                              -- BTREE_SEARCH  |PARTITIONED|
-                                                                -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                                  -- ASSIGN  |PARTITIONED|
-                                                                    -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
\ No newline at end of file
+                                                      -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                        -- BTREE_SEARCH  |PARTITIONED|
+                                                          -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                            -- ASSIGN  |PARTITIONED|
+                                                              -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterix-app/src/test/resources/optimizerts/results/open-index-enforced/rtree-index-join/leftouterjoin-probe-pidx-with-join-rtree-sidx_02.plan b/asterix-app/src/test/resources/optimizerts/results/open-index-enforced/rtree-index-join/leftouterjoin-probe-pidx-with-join-rtree-sidx_02.plan
index b162100..3bc6933 100644
--- a/asterix-app/src/test/resources/optimizerts/results/open-index-enforced/rtree-index-join/leftouterjoin-probe-pidx-with-join-rtree-sidx_02.plan
+++ b/asterix-app/src/test/resources/optimizerts/results/open-index-enforced/rtree-index-join/leftouterjoin-probe-pidx-with-join-rtree-sidx_02.plan
@@ -2,39 +2,36 @@
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
     -- STREAM_PROJECT  |PARTITIONED|
       -- ASSIGN  |PARTITIONED|
-        -- STREAM_PROJECT  |PARTITIONED|
-          -- SORT_MERGE_EXCHANGE [$$35(ASC) ]  |PARTITIONED|
-            -- STABLE_SORT [$$35(ASC)]  |PARTITIONED|
-              -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                -- PRE_CLUSTERED_GROUP_BY[$$32]  |PARTITIONED|
-                        {
-                          -- AGGREGATE  |LOCAL|
-                            -- STREAM_SELECT  |LOCAL|
-                              -- NESTED_TUPLE_SOURCE  |LOCAL|
-                        }
-                  -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                    -- STABLE_SORT [$$32(ASC), $$28(ASC)]  |PARTITIONED|
-                      -- HASH_PARTITION_EXCHANGE [$$32]  |PARTITIONED|
-                        -- STREAM_PROJECT  |PARTITIONED|
-                          -- STREAM_SELECT  |PARTITIONED|
-                            -- STREAM_PROJECT  |PARTITIONED|
-                              -- ASSIGN  |PARTITIONED|
-                                -- STREAM_PROJECT  |PARTITIONED|
-                                  -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                    -- BTREE_SEARCH  |PARTITIONED|
-                                      -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                        -- STABLE_SORT [$$48(ASC)]  |PARTITIONED|
-                                          -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                            -- STREAM_PROJECT  |PARTITIONED|
-                                              -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                -- RTREE_SEARCH  |PARTITIONED|
-                                                  -- BROADCAST_EXCHANGE  |PARTITIONED|
+        -- SORT_MERGE_EXCHANGE [$$35(ASC) ]  |PARTITIONED|
+          -- PRE_CLUSTERED_GROUP_BY[$$27]  |PARTITIONED|
+                  {
+                    -- AGGREGATE  |LOCAL|
+                      -- STREAM_SELECT  |LOCAL|
+                        -- NESTED_TUPLE_SOURCE  |LOCAL|
+                  }
+            -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+              -- STABLE_SORT [$$27(ASC), $$28(ASC)]  |PARTITIONED|
+                -- HASH_PARTITION_EXCHANGE [$$27]  |PARTITIONED|
+                  -- STREAM_PROJECT  |PARTITIONED|
+                    -- STREAM_SELECT  |PARTITIONED|
+                      -- STREAM_PROJECT  |PARTITIONED|
+                        -- ASSIGN  |PARTITIONED|
+                          -- STREAM_PROJECT  |PARTITIONED|
+                            -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                              -- BTREE_SEARCH  |PARTITIONED|
+                                -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                  -- STABLE_SORT [$$47(ASC)]  |PARTITIONED|
+                                    -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                      -- STREAM_PROJECT  |PARTITIONED|
+                                        -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                          -- RTREE_SEARCH  |PARTITIONED|
+                                            -- BROADCAST_EXCHANGE  |PARTITIONED|
+                                              -- ASSIGN  |PARTITIONED|
+                                                -- ASSIGN  |PARTITIONED|
+                                                  -- STREAM_PROJECT  |PARTITIONED|
                                                     -- ASSIGN  |PARTITIONED|
-                                                      -- ASSIGN  |PARTITIONED|
-                                                        -- STREAM_PROJECT  |PARTITIONED|
-                                                          -- ASSIGN  |PARTITIONED|
-                                                            -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                              -- BTREE_SEARCH  |PARTITIONED|
-                                                                -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                                  -- ASSIGN  |PARTITIONED|
-                                                                    -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
\ No newline at end of file
+                                                      -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                        -- BTREE_SEARCH  |PARTITIONED|
+                                                          -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                            -- ASSIGN  |PARTITIONED|
+                                                              -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterix-app/src/test/resources/optimizerts/results/push-project-through-group.plan b/asterix-app/src/test/resources/optimizerts/results/push-project-through-group.plan
index 86bcdac..3cc71e0 100644
--- a/asterix-app/src/test/resources/optimizerts/results/push-project-through-group.plan
+++ b/asterix-app/src/test/resources/optimizerts/results/push-project-through-group.plan
@@ -2,32 +2,31 @@
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
     -- STREAM_PROJECT  |PARTITIONED|
       -- ASSIGN  |PARTITIONED|
-        -- STREAM_PROJECT  |PARTITIONED|
-          -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-            -- PRE_CLUSTERED_GROUP_BY[$$15]  |PARTITIONED|
-                    {
-                      -- AGGREGATE  |LOCAL|
-                        -- STREAM_SELECT  |LOCAL|
-                          -- NESTED_TUPLE_SOURCE  |LOCAL|
-                    }
-              -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                -- STABLE_SORT [$$15(ASC)]  |PARTITIONED|
-                  -- HASH_PARTITION_EXCHANGE [$$15]  |PARTITIONED|
-                    -- STREAM_PROJECT  |PARTITIONED|
-                      -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                        -- HYBRID_HASH_JOIN [$$17][$$16]  |PARTITIONED|
-                          -- HASH_PARTITION_EXCHANGE [$$17]  |PARTITIONED|
-                            -- STREAM_PROJECT  |PARTITIONED|
-                              -- ASSIGN  |PARTITIONED|
+        -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+          -- PRE_CLUSTERED_GROUP_BY[$$12]  |PARTITIONED|
+                  {
+                    -- AGGREGATE  |LOCAL|
+                      -- STREAM_SELECT  |LOCAL|
+                        -- NESTED_TUPLE_SOURCE  |LOCAL|
+                  }
+            -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+              -- STABLE_SORT [$$12(ASC)]  |PARTITIONED|
+                -- HASH_PARTITION_EXCHANGE [$$12]  |PARTITIONED|
+                  -- STREAM_PROJECT  |PARTITIONED|
+                    -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                      -- HYBRID_HASH_JOIN [$$15][$$14]  |PARTITIONED|
+                        -- HASH_PARTITION_EXCHANGE [$$15]  |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 [$$14]  |PARTITIONED|
+                          -- STREAM_PROJECT  |PARTITIONED|
+                            -- ASSIGN  |PARTITIONED|
+                              -- STREAM_PROJECT  |PARTITIONED|
                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
                                   -- DATASOURCE_SCAN  |PARTITIONED|
                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
                                       -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
-                          -- HASH_PARTITION_EXCHANGE [$$16]  |PARTITIONED|
-                            -- STREAM_PROJECT  |PARTITIONED|
-                              -- ASSIGN  |PARTITIONED|
-                                -- STREAM_PROJECT  |PARTITIONED|
-                                  -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                    -- DATASOURCE_SCAN  |PARTITIONED|
-                                      -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                        -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterix-app/src/test/resources/optimizerts/results/q08_group_by.plan b/asterix-app/src/test/resources/optimizerts/results/q08_group_by.plan
index 0b3cd8f..601091e 100644
--- a/asterix-app/src/test/resources/optimizerts/results/q08_group_by.plan
+++ b/asterix-app/src/test/resources/optimizerts/results/q08_group_by.plan
@@ -4,7 +4,7 @@
       -- ASSIGN  |PARTITIONED|
         -- STREAM_PROJECT  |PARTITIONED|
           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-            -- HYBRID_HASH_JOIN [$$78][$$107]  |PARTITIONED|
+            -- HYBRID_HASH_JOIN [$$78][$$106]  |PARTITIONED|
               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
                 -- STREAM_PROJECT  |PARTITIONED|
                   -- ASSIGN  |PARTITIONED|
@@ -12,11 +12,11 @@
                       -- DATASOURCE_SCAN  |PARTITIONED|
                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
                           -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
-              -- HASH_PARTITION_EXCHANGE [$$107]  |PARTITIONED|
+              -- HASH_PARTITION_EXCHANGE [$$106]  |PARTITIONED|
                 -- STREAM_PROJECT  |PARTITIONED|
                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                    -- HYBRID_HASH_JOIN [$$104][$$85]  |PARTITIONED|
-                      -- HASH_PARTITION_EXCHANGE [$$104]  |PARTITIONED|
+                    -- HYBRID_HASH_JOIN [$$103][$$85]  |PARTITIONED|
+                      -- HASH_PARTITION_EXCHANGE [$$103]  |PARTITIONED|
                         -- STREAM_PROJECT  |PARTITIONED|
                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
                             -- HYBRID_HASH_JOIN [$$79][$$81]  |PARTITIONED|
@@ -31,8 +31,8 @@
                               -- HASH_PARTITION_EXCHANGE [$$81]  |PARTITIONED|
                                 -- STREAM_PROJECT  |PARTITIONED|
                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                    -- HYBRID_HASH_JOIN [$$93][$$82]  |PARTITIONED|
-                                      -- HASH_PARTITION_EXCHANGE [$$93]  |PARTITIONED|
+                                    -- HYBRID_HASH_JOIN [$$92][$$82]  |PARTITIONED|
+                                      -- HASH_PARTITION_EXCHANGE [$$92]  |PARTITIONED|
                                         -- STREAM_SELECT  |PARTITIONED|
                                           -- STREAM_PROJECT  |PARTITIONED|
                                             -- ASSIGN  |PARTITIONED|
@@ -43,8 +43,8 @@
                                       -- HASH_PARTITION_EXCHANGE [$$82]  |PARTITIONED|
                                         -- STREAM_PROJECT  |PARTITIONED|
                                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                            -- HYBRID_HASH_JOIN [$$90][$$83]  |PARTITIONED|
-                                              -- HASH_PARTITION_EXCHANGE [$$90]  |PARTITIONED|
+                                            -- HYBRID_HASH_JOIN [$$89][$$83]  |PARTITIONED|
+                                              -- HASH_PARTITION_EXCHANGE [$$89]  |PARTITIONED|
                                                 -- STREAM_PROJECT  |PARTITIONED|
                                                   -- ASSIGN  |PARTITIONED|
                                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
@@ -54,8 +54,8 @@
                                               -- HASH_PARTITION_EXCHANGE [$$83]  |PARTITIONED|
                                                 -- STREAM_PROJECT  |PARTITIONED|
                                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                    -- HYBRID_HASH_JOIN [$$88][$$84]  |PARTITIONED|
-                                                      -- HASH_PARTITION_EXCHANGE [$$88]  |PARTITIONED|
+                                                    -- HYBRID_HASH_JOIN [$$87][$$84]  |PARTITIONED|
+                                                      -- HASH_PARTITION_EXCHANGE [$$87]  |PARTITIONED|
                                                         -- STREAM_PROJECT  |PARTITIONED|
                                                           -- ASSIGN  |PARTITIONED|
                                                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
diff --git a/asterix-app/src/test/resources/optimizerts/results/query-ASTERIXDB-1005.plan b/asterix-app/src/test/resources/optimizerts/results/query-ASTERIXDB-1005.plan
new file mode 100644
index 0000000..de339c0
--- /dev/null
+++ b/asterix-app/src/test/resources/optimizerts/results/query-ASTERIXDB-1005.plan
@@ -0,0 +1,35 @@
+-- DISTRIBUTE_RESULT  |PARTITIONED|
+  -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    -- STREAM_PROJECT  |PARTITIONED|
+      -- ASSIGN  |PARTITIONED|
+        -- SORT_MERGE_EXCHANGE [$$15(ASC) ]  |PARTITIONED|
+          -- STABLE_SORT [$$15(ASC)]  |PARTITIONED|
+            -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+              -- STREAM_PROJECT  |PARTITIONED|
+                -- STREAM_SELECT  |PARTITIONED|
+                  -- STREAM_PROJECT  |PARTITIONED|
+                    -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                      -- PRE_CLUSTERED_GROUP_BY[$$12]  |PARTITIONED|
+                              {
+                                -- AGGREGATE  |LOCAL|
+                                  -- STREAM_SELECT  |LOCAL|
+                                    -- NESTED_TUPLE_SOURCE  |LOCAL|
+                              }
+                        -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                          -- STABLE_SORT [$$12(ASC)]  |PARTITIONED|
+                            -- HASH_PARTITION_EXCHANGE [$$12]  |PARTITIONED|
+                              -- STREAM_PROJECT  |PARTITIONED|
+                                -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                  -- HYBRID_HASH_JOIN [$$1][$$13]  |PARTITIONED|
+                                    -- HASH_PARTITION_EXCHANGE [$$1]  |PARTITIONED|
+                                      -- UNNEST  |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 [$$13]  |PARTITIONED|
+                                      -- ASSIGN  |UNPARTITIONED|
+                                        -- UNNEST  |UNPARTITIONED|
+                                          -- EMPTY_TUPLE_SOURCE  |UNPARTITIONED|
diff --git a/asterix-app/src/test/resources/optimizerts/results/query-ASTERIXDB-1263.plan b/asterix-app/src/test/resources/optimizerts/results/query-ASTERIXDB-1263.plan
new file mode 100644
index 0000000..8532218
--- /dev/null
+++ b/asterix-app/src/test/resources/optimizerts/results/query-ASTERIXDB-1263.plan
@@ -0,0 +1,35 @@
+-- DISTRIBUTE_RESULT  |PARTITIONED|
+  -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    -- STREAM_PROJECT  |PARTITIONED|
+      -- ASSIGN  |PARTITIONED|
+        -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+          -- PRE_CLUSTERED_GROUP_BY[$$27]  |PARTITIONED|
+                  {
+                    -- AGGREGATE  |LOCAL|
+                      -- NESTED_TUPLE_SOURCE  |LOCAL|
+                  }
+                  {
+                    -- AGGREGATE  |LOCAL|
+                      -- MICRO_PRE_CLUSTERED_GROUP_BY[$$19]  |LOCAL|
+                              {
+                                -- AGGREGATE  |LOCAL|
+                                  -- NESTED_TUPLE_SOURCE  |LOCAL|
+                              }
+                        -- IN_MEMORY_STABLE_SORT [$$19(ASC)]  |LOCAL|
+                          -- ASSIGN  |LOCAL|
+                            -- NESTED_TUPLE_SOURCE  |LOCAL|
+                  }
+            -- HASH_PARTITION_MERGE_EXCHANGE MERGE:[$$27(ASC), $$28(ASC)] HASH:[$$27]  |PARTITIONED|
+              -- SORT_GROUP_BY[$$18, $$24]  |PARTITIONED|
+                      {
+                        -- AGGREGATE  |LOCAL|
+                          -- NESTED_TUPLE_SOURCE  |LOCAL|
+                      }
+                -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                  -- STREAM_PROJECT  |PARTITIONED|
+                    -- ASSIGN  |PARTITIONED|
+                      -- STREAM_PROJECT  |PARTITIONED|
+                        -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                          -- DATASOURCE_SCAN  |PARTITIONED|
+                            -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                              -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterix-app/src/test/resources/optimizerts/results/query-issue562.plan b/asterix-app/src/test/resources/optimizerts/results/query-issue562.plan
index 992ce13..5062719 100644
--- a/asterix-app/src/test/resources/optimizerts/results/query-issue562.plan
+++ b/asterix-app/src/test/resources/optimizerts/results/query-issue562.plan
@@ -3,12 +3,12 @@
     -- STREAM_PROJECT  |PARTITIONED|
       -- ASSIGN  |PARTITIONED|
         -- SORT_MERGE_EXCHANGE [$$7(ASC) ]  |PARTITIONED|
-          -- PRE_CLUSTERED_GROUP_BY[$$91]  |PARTITIONED|
+          -- PRE_CLUSTERED_GROUP_BY[$$89]  |PARTITIONED|
                   {
                     -- AGGREGATE  |LOCAL|
                       -- NESTED_TUPLE_SOURCE  |LOCAL|
                   }
-            -- HASH_PARTITION_MERGE_EXCHANGE MERGE:[$$91(ASC)] HASH:[$$91]  |PARTITIONED|
+            -- HASH_PARTITION_MERGE_EXCHANGE MERGE:[$$89(ASC)] HASH:[$$89]  |PARTITIONED|
               -- SORT_GROUP_BY[$$59]  |PARTITIONED|
                       {
                         -- AGGREGATE  |LOCAL|
@@ -16,48 +16,51 @@
                       }
                 -- 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[$$88]  |PARTITIONED|
-                                  {
-                                    -- AGGREGATE  |LOCAL|
-                                      -- NESTED_TUPLE_SOURCE  |LOCAL|
-                                  }
-                            -- HASH_PARTITION_MERGE_EXCHANGE MERGE:[$$88(ASC)] HASH:[$$88]  |PARTITIONED|
-                              -- PRE_CLUSTERED_GROUP_BY[$$68]  |PARTITIONED|
+                        -- STREAM_SELECT  |PARTITIONED|
+                          -- STREAM_PROJECT  |PARTITIONED|
+                            -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                              -- PRE_CLUSTERED_GROUP_BY[$$86]  |PARTITIONED|
                                       {
                                         -- AGGREGATE  |LOCAL|
-                                          -- STREAM_SELECT  |LOCAL|
-                                            -- NESTED_TUPLE_SOURCE  |LOCAL|
+                                          -- NESTED_TUPLE_SOURCE  |LOCAL|
                                       }
-                                -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                  -- STABLE_SORT [$$68(ASC)]  |PARTITIONED|
+                                -- HASH_PARTITION_MERGE_EXCHANGE MERGE:[$$86(ASC)] HASH:[$$86]  |PARTITIONED|
+                                  -- PRE_CLUSTERED_GROUP_BY[$$62]  |PARTITIONED|
+                                          {
+                                            -- AGGREGATE  |LOCAL|
+                                              -- STREAM_SELECT  |LOCAL|
+                                                -- NESTED_TUPLE_SOURCE  |LOCAL|
+                                          }
                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                      -- STREAM_PROJECT  |PARTITIONED|
+                                      -- STABLE_SORT [$$62(ASC)]  |PARTITIONED|
                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                          -- HYBRID_HASH_JOIN [$$68][$$70]  |PARTITIONED|
-                                            -- HASH_PARTITION_EXCHANGE [$$68]  |PARTITIONED|
-                                              -- ASSIGN  |PARTITIONED|
-                                                -- STREAM_PROJECT  |PARTITIONED|
+                                          -- STREAM_PROJECT  |PARTITIONED|
+                                            -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                              -- HYBRID_HASH_JOIN [$$67][$$68]  |PARTITIONED|
+                                                -- HASH_PARTITION_EXCHANGE [$$67]  |PARTITIONED|
+                                                  -- ASSIGN  |PARTITIONED|
+                                                    -- STREAM_PROJECT  |PARTITIONED|
+                                                      -- ASSIGN  |PARTITIONED|
+                                                        -- STREAM_PROJECT  |PARTITIONED|
+                                                          -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                            -- HYBRID_HASH_JOIN [$$83][$$82]  |PARTITIONED|
+                                                              -- HASH_PARTITION_EXCHANGE [$$83]  |PARTITIONED|
+                                                                -- UNNEST  |UNPARTITIONED|
+                                                                  -- EMPTY_TUPLE_SOURCE  |UNPARTITIONED|
+                                                              -- HASH_PARTITION_EXCHANGE [$$82]  |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 [$$68]  |PARTITIONED|
                                                   -- ASSIGN  |PARTITIONED|
                                                     -- STREAM_PROJECT  |PARTITIONED|
                                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                        -- HYBRID_HASH_JOIN [$$86][$$85]  |PARTITIONED|
-                                                          -- HASH_PARTITION_EXCHANGE [$$86]  |PARTITIONED|
-                                                            -- UNNEST  |UNPARTITIONED|
-                                                              -- EMPTY_TUPLE_SOURCE  |UNPARTITIONED|
-                                                          -- HASH_PARTITION_EXCHANGE [$$85]  |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|
-                                                    -- DATASOURCE_SCAN  |PARTITIONED|
-                                                      -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                        -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                                                        -- DATASOURCE_SCAN  |PARTITIONED|
+                                                          -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                            -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterix-app/src/test/resources/optimizerts/results/query_issue849-2.plan b/asterix-app/src/test/resources/optimizerts/results/query_issue849-2.plan
index df5d477..8908448 100644
--- a/asterix-app/src/test/resources/optimizerts/results/query_issue849-2.plan
+++ b/asterix-app/src/test/resources/optimizerts/results/query_issue849-2.plan
@@ -20,14 +20,13 @@
       -- ASSIGN  |PARTITIONED|
         -- STREAM_PROJECT  |PARTITIONED|
           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-            -- HYBRID_HASH_JOIN [$$15][$$17]  |PARTITIONED|
+            -- HYBRID_HASH_JOIN [$$14][$$16]  |PARTITIONED|
               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
                 -- DATASOURCE_SCAN  |PARTITIONED|
                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
                     -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
-              -- HASH_PARTITION_EXCHANGE [$$17]  |PARTITIONED|
+              -- HASH_PARTITION_EXCHANGE [$$16]  |PARTITIONED|
                 -- STREAM_PROJECT  |UNPARTITIONED|
                   -- ASSIGN  |UNPARTITIONED|
-                    -- STREAM_SELECT  |UNPARTITIONED|
-                      -- UNNEST  |UNPARTITIONED|
-                        -- EMPTY_TUPLE_SOURCE  |UNPARTITIONED|
+                    -- UNNEST  |UNPARTITIONED|
+                      -- EMPTY_TUPLE_SOURCE  |UNPARTITIONED|
diff --git a/asterix-app/src/test/resources/optimizerts/results/query_issue849.plan b/asterix-app/src/test/resources/optimizerts/results/query_issue849.plan
index db12ea3..dd7b473 100644
--- a/asterix-app/src/test/resources/optimizerts/results/query_issue849.plan
+++ b/asterix-app/src/test/resources/optimizerts/results/query_issue849.plan
@@ -20,8 +20,8 @@
       -- ASSIGN  |PARTITIONED|
         -- STREAM_PROJECT  |PARTITIONED|
           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-            -- HYBRID_HASH_JOIN [$$17][$$14]  |PARTITIONED|
-              -- HASH_PARTITION_EXCHANGE [$$17]  |PARTITIONED|
+            -- HYBRID_HASH_JOIN [$$15][$$14]  |PARTITIONED|
+              -- HASH_PARTITION_EXCHANGE [$$15]  |PARTITIONED|
                 -- ASSIGN  |UNPARTITIONED|
                   -- UNNEST  |UNPARTITIONED|
                     -- EMPTY_TUPLE_SOURCE  |UNPARTITIONED|
diff --git a/asterix-app/src/test/resources/optimizerts/results/rtree-index-join/issue730.plan b/asterix-app/src/test/resources/optimizerts/results/rtree-index-join/issue730.plan
index 40582f1..44f21ac 100644
--- a/asterix-app/src/test/resources/optimizerts/results/rtree-index-join/issue730.plan
+++ b/asterix-app/src/test/resources/optimizerts/results/rtree-index-join/issue730.plan
@@ -2,36 +2,35 @@
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
     -- STREAM_PROJECT  |PARTITIONED|
       -- ASSIGN  |PARTITIONED|
-        -- STREAM_PROJECT  |PARTITIONED|
-          -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-            -- PRE_CLUSTERED_GROUP_BY[$$24]  |PARTITIONED|
-                    {
-                      -- AGGREGATE  |LOCAL|
-                        -- STREAM_SELECT  |LOCAL|
-                          -- NESTED_TUPLE_SOURCE  |LOCAL|
-                    }
-              -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                -- STABLE_SORT [$$24(ASC)]  |PARTITIONED|
-                  -- HASH_PARTITION_EXCHANGE [$$24]  |PARTITIONED|
-                    -- STREAM_PROJECT  |PARTITIONED|
-                      -- STREAM_SELECT  |PARTITIONED|
-                        -- STREAM_PROJECT  |PARTITIONED|
-                          -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                            -- BTREE_SEARCH  |PARTITIONED|
-                              -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                -- STABLE_SORT [$$37(ASC)]  |PARTITIONED|
-                                  -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                    -- STREAM_PROJECT  |PARTITIONED|
-                                      -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                        -- RTREE_SEARCH  |PARTITIONED|
-                                          -- BROADCAST_EXCHANGE  |PARTITIONED|
-                                            -- ASSIGN  |PARTITIONED|
-                                              -- STREAM_PROJECT  |PARTITIONED|
-                                                -- ASSIGN  |PARTITIONED|
-                                                  -- STREAM_PROJECT  |PARTITIONED|
-                                                    -- STREAM_SELECT  |PARTITIONED|
-                                                      -- ASSIGN  |PARTITIONED|
-                                                        -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                          -- DATASOURCE_SCAN  |PARTITIONED|
-                                                            -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                              -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
\ No newline at end of file
+        -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+          -- PRE_CLUSTERED_GROUP_BY[$$21]  |PARTITIONED|
+                  {
+                    -- AGGREGATE  |LOCAL|
+                      -- STREAM_SELECT  |LOCAL|
+                        -- NESTED_TUPLE_SOURCE  |LOCAL|
+                  }
+            -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+              -- STABLE_SORT [$$21(ASC)]  |PARTITIONED|
+                -- HASH_PARTITION_EXCHANGE [$$21]  |PARTITIONED|
+                  -- STREAM_PROJECT  |PARTITIONED|
+                    -- STREAM_SELECT  |PARTITIONED|
+                      -- STREAM_PROJECT  |PARTITIONED|
+                        -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                          -- BTREE_SEARCH  |PARTITIONED|
+                            -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                              -- STABLE_SORT [$$36(ASC)]  |PARTITIONED|
+                                -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                  -- STREAM_PROJECT  |PARTITIONED|
+                                    -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                      -- RTREE_SEARCH  |PARTITIONED|
+                                        -- BROADCAST_EXCHANGE  |PARTITIONED|
+                                          -- ASSIGN  |PARTITIONED|
+                                            -- STREAM_PROJECT  |PARTITIONED|
+                                              -- ASSIGN  |PARTITIONED|
+                                                -- STREAM_PROJECT  |PARTITIONED|
+                                                  -- STREAM_SELECT  |PARTITIONED|
+                                                    -- ASSIGN  |PARTITIONED|
+                                                      -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                        -- DATASOURCE_SCAN  |PARTITIONED|
+                                                          -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                            -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterix-app/src/test/resources/optimizerts/results/rtree-index-join/leftouterjoin-probe-pidx-with-join-rtree-sidx_01.plan b/asterix-app/src/test/resources/optimizerts/results/rtree-index-join/leftouterjoin-probe-pidx-with-join-rtree-sidx_01.plan
index 3cb87ff..98a35ca 100644
--- a/asterix-app/src/test/resources/optimizerts/results/rtree-index-join/leftouterjoin-probe-pidx-with-join-rtree-sidx_01.plan
+++ b/asterix-app/src/test/resources/optimizerts/results/rtree-index-join/leftouterjoin-probe-pidx-with-join-rtree-sidx_01.plan
@@ -2,39 +2,36 @@
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
     -- STREAM_PROJECT  |PARTITIONED|
       -- ASSIGN  |PARTITIONED|
-        -- STREAM_PROJECT  |PARTITIONED|
-          -- SORT_MERGE_EXCHANGE [$$30(ASC) ]  |PARTITIONED|
-            -- STABLE_SORT [$$30(ASC)]  |PARTITIONED|
-              -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                -- PRE_CLUSTERED_GROUP_BY[$$27]  |PARTITIONED|
-                        {
-                          -- AGGREGATE  |LOCAL|
-                            -- STREAM_SELECT  |LOCAL|
-                              -- NESTED_TUPLE_SOURCE  |LOCAL|
-                        }
-                  -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                    -- STABLE_SORT [$$27(ASC), $$24(ASC)]  |PARTITIONED|
-                      -- HASH_PARTITION_EXCHANGE [$$27]  |PARTITIONED|
-                        -- STREAM_PROJECT  |PARTITIONED|
-                          -- STREAM_SELECT  |PARTITIONED|
-                            -- STREAM_PROJECT  |PARTITIONED|
-                              -- ASSIGN  |PARTITIONED|
-                                -- STREAM_PROJECT  |PARTITIONED|
-                                  -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                    -- BTREE_SEARCH  |PARTITIONED|
-                                      -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                        -- STABLE_SORT [$$43(ASC)]  |PARTITIONED|
-                                          -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                            -- STREAM_PROJECT  |PARTITIONED|
-                                              -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                -- RTREE_SEARCH  |PARTITIONED|
-                                                  -- BROADCAST_EXCHANGE  |PARTITIONED|
+        -- SORT_MERGE_EXCHANGE [$$30(ASC) ]  |PARTITIONED|
+          -- PRE_CLUSTERED_GROUP_BY[$$23]  |PARTITIONED|
+                  {
+                    -- AGGREGATE  |LOCAL|
+                      -- STREAM_SELECT  |LOCAL|
+                        -- NESTED_TUPLE_SOURCE  |LOCAL|
+                  }
+            -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+              -- STABLE_SORT [$$23(ASC), $$24(ASC)]  |PARTITIONED|
+                -- HASH_PARTITION_EXCHANGE [$$23]  |PARTITIONED|
+                  -- STREAM_PROJECT  |PARTITIONED|
+                    -- STREAM_SELECT  |PARTITIONED|
+                      -- STREAM_PROJECT  |PARTITIONED|
+                        -- ASSIGN  |PARTITIONED|
+                          -- STREAM_PROJECT  |PARTITIONED|
+                            -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                              -- BTREE_SEARCH  |PARTITIONED|
+                                -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                  -- STABLE_SORT [$$42(ASC)]  |PARTITIONED|
+                                    -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                      -- STREAM_PROJECT  |PARTITIONED|
+                                        -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                          -- RTREE_SEARCH  |PARTITIONED|
+                                            -- BROADCAST_EXCHANGE  |PARTITIONED|
+                                              -- ASSIGN  |PARTITIONED|
+                                                -- ASSIGN  |PARTITIONED|
+                                                  -- STREAM_PROJECT  |PARTITIONED|
                                                     -- ASSIGN  |PARTITIONED|
-                                                      -- ASSIGN  |PARTITIONED|
-                                                        -- STREAM_PROJECT  |PARTITIONED|
-                                                          -- ASSIGN  |PARTITIONED|
-                                                            -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                              -- BTREE_SEARCH  |PARTITIONED|
-                                                                -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                                  -- ASSIGN  |PARTITIONED|
-                                                                    -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                                                      -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                        -- BTREE_SEARCH  |PARTITIONED|
+                                                          -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                            -- ASSIGN  |PARTITIONED|
+                                                              -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterix-app/src/test/resources/optimizerts/results/rtree-index-join/leftouterjoin-probe-pidx-with-join-rtree-sidx_02.plan b/asterix-app/src/test/resources/optimizerts/results/rtree-index-join/leftouterjoin-probe-pidx-with-join-rtree-sidx_02.plan
index d62a691..3bc6933 100644
--- a/asterix-app/src/test/resources/optimizerts/results/rtree-index-join/leftouterjoin-probe-pidx-with-join-rtree-sidx_02.plan
+++ b/asterix-app/src/test/resources/optimizerts/results/rtree-index-join/leftouterjoin-probe-pidx-with-join-rtree-sidx_02.plan
@@ -2,39 +2,36 @@
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
     -- STREAM_PROJECT  |PARTITIONED|
       -- ASSIGN  |PARTITIONED|
-        -- STREAM_PROJECT  |PARTITIONED|
-          -- SORT_MERGE_EXCHANGE [$$35(ASC) ]  |PARTITIONED|
-            -- STABLE_SORT [$$35(ASC)]  |PARTITIONED|
-              -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                -- PRE_CLUSTERED_GROUP_BY[$$32]  |PARTITIONED|
-                        {
-                          -- AGGREGATE  |LOCAL|
-                            -- STREAM_SELECT  |LOCAL|
-                              -- NESTED_TUPLE_SOURCE  |LOCAL|
-                        }
-                  -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                    -- STABLE_SORT [$$32(ASC), $$28(ASC)]  |PARTITIONED|
-                      -- HASH_PARTITION_EXCHANGE [$$32]  |PARTITIONED|
-                        -- STREAM_PROJECT  |PARTITIONED|
-                          -- STREAM_SELECT  |PARTITIONED|
-                            -- STREAM_PROJECT  |PARTITIONED|
-                              -- ASSIGN  |PARTITIONED|
-                                -- STREAM_PROJECT  |PARTITIONED|
-                                  -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                    -- BTREE_SEARCH  |PARTITIONED|
-                                      -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                        -- STABLE_SORT [$$48(ASC)]  |PARTITIONED|
-                                          -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                            -- STREAM_PROJECT  |PARTITIONED|
-                                              -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                -- RTREE_SEARCH  |PARTITIONED|
-                                                  -- BROADCAST_EXCHANGE  |PARTITIONED|
+        -- SORT_MERGE_EXCHANGE [$$35(ASC) ]  |PARTITIONED|
+          -- PRE_CLUSTERED_GROUP_BY[$$27]  |PARTITIONED|
+                  {
+                    -- AGGREGATE  |LOCAL|
+                      -- STREAM_SELECT  |LOCAL|
+                        -- NESTED_TUPLE_SOURCE  |LOCAL|
+                  }
+            -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+              -- STABLE_SORT [$$27(ASC), $$28(ASC)]  |PARTITIONED|
+                -- HASH_PARTITION_EXCHANGE [$$27]  |PARTITIONED|
+                  -- STREAM_PROJECT  |PARTITIONED|
+                    -- STREAM_SELECT  |PARTITIONED|
+                      -- STREAM_PROJECT  |PARTITIONED|
+                        -- ASSIGN  |PARTITIONED|
+                          -- STREAM_PROJECT  |PARTITIONED|
+                            -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                              -- BTREE_SEARCH  |PARTITIONED|
+                                -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                  -- STABLE_SORT [$$47(ASC)]  |PARTITIONED|
+                                    -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                      -- STREAM_PROJECT  |PARTITIONED|
+                                        -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                          -- RTREE_SEARCH  |PARTITIONED|
+                                            -- BROADCAST_EXCHANGE  |PARTITIONED|
+                                              -- ASSIGN  |PARTITIONED|
+                                                -- ASSIGN  |PARTITIONED|
+                                                  -- STREAM_PROJECT  |PARTITIONED|
                                                     -- ASSIGN  |PARTITIONED|
-                                                      -- ASSIGN  |PARTITIONED|
-                                                        -- STREAM_PROJECT  |PARTITIONED|
-                                                          -- ASSIGN  |PARTITIONED|
-                                                            -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                              -- BTREE_SEARCH  |PARTITIONED|
-                                                                -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                                  -- ASSIGN  |PARTITIONED|
-                                                                    -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                                                      -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                        -- BTREE_SEARCH  |PARTITIONED|
+                                                          -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                            -- ASSIGN  |PARTITIONED|
+                                                              -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterix-app/src/test/resources/optimizerts/results/split-materialization-above-join.plan b/asterix-app/src/test/resources/optimizerts/results/split-materialization-above-join.plan
index be634f3..19eaf25 100644
--- a/asterix-app/src/test/resources/optimizerts/results/split-materialization-above-join.plan
+++ b/asterix-app/src/test/resources/optimizerts/results/split-materialization-above-join.plan
@@ -25,135 +25,134 @@
                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
                                           -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
                       -- HASH_PARTITION_EXCHANGE [$$26]  |PARTITIONED|
-                        -- PRE_CLUSTERED_GROUP_BY[$$91, $$92]  |PARTITIONED|
+                        -- PRE_CLUSTERED_GROUP_BY[$$122, $$124]  |PARTITIONED|
                                 {
                                   -- AGGREGATE  |LOCAL|
                                     -- NESTED_TUPLE_SOURCE  |LOCAL|
                                 }
                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                            -- STABLE_SORT [$$91(ASC), $$92(ASC)]  |PARTITIONED|
-                              -- HASH_PARTITION_EXCHANGE [$$91, $$92]  |PARTITIONED|
-                                -- STREAM_SELECT  |PARTITIONED|
-                                  -- STREAM_PROJECT  |PARTITIONED|
-                                    -- ASSIGN  |PARTITIONED|
-                                      -- STREAM_SELECT  |PARTITIONED|
-                                        -- STREAM_PROJECT  |PARTITIONED|
-                                          -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                            -- HYBRID_HASH_JOIN [$$12][$$23]  |PARTITIONED|
-                                              -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                -- STREAM_PROJECT  |PARTITIONED|
-                                                  -- ASSIGN  |PARTITIONED|
-                                                    -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                      -- SPLIT  |PARTITIONED|
-                                                        -- HASH_PARTITION_EXCHANGE [$$23]  |PARTITIONED|
-                                                          -- STREAM_PROJECT  |PARTITIONED|
-                                                            -- UNNEST  |PARTITIONED|
-                                                              -- STREAM_PROJECT  |PARTITIONED|
-                                                                -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                                  -- PRE_CLUSTERED_GROUP_BY[$$105]  |PARTITIONED|
-                                                                          {
-                                                                            -- AGGREGATE  |LOCAL|
-                                                                              -- STREAM_SELECT  |LOCAL|
-                                                                                -- NESTED_TUPLE_SOURCE  |LOCAL|
-                                                                          }
-                                                                    -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                                      -- STABLE_SORT [$$105(ASC), $$21(ASC)]  |PARTITIONED|
-                                                                        -- HASH_PARTITION_EXCHANGE [$$105]  |PARTITIONED|
-                                                                          -- STREAM_PROJECT  |PARTITIONED|
-                                                                            -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                                              -- HYBRID_HASH_JOIN [$$15][$$18]  |PARTITIONED|
-                                                                                -- HASH_PARTITION_EXCHANGE [$$15]  |PARTITIONED|
-                                                                                  -- UNNEST  |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 [$$18]  |PARTITIONED|
-                                                                                  -- RUNNING_AGGREGATE  |PARTITIONED|
-                                                                                    -- STREAM_PROJECT  |PARTITIONED|
-                                                                                      -- SORT_MERGE_EXCHANGE [$$107(ASC), $$18(ASC) ]  |PARTITIONED|
-                                                                                        -- STABLE_SORT [$$107(ASC), $$18(ASC)]  |PARTITIONED|
-                                                                                          -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                                                            -- PRE_CLUSTERED_GROUP_BY[$$135]  |PARTITIONED|
-                                                                                                    {
-                                                                                                      -- AGGREGATE  |LOCAL|
-                                                                                                        -- NESTED_TUPLE_SOURCE  |LOCAL|
-                                                                                                    }
-                                                                                              -- HASH_PARTITION_MERGE_EXCHANGE MERGE:[$$135(ASC)] HASH:[$$135]  |PARTITIONED|
-                                                                                                -- SORT_GROUP_BY[$$17]  |PARTITIONED|
-                                                                                                        {
-                                                                                                          -- AGGREGATE  |LOCAL|
-                                                                                                            -- NESTED_TUPLE_SOURCE  |LOCAL|
-                                                                                                        }
-                                                                                                  -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                                                                    -- STREAM_PROJECT  |PARTITIONED|
-                                                                                                      -- UNNEST  |PARTITIONED|
-                                                                                                        -- STREAM_PROJECT  |PARTITIONED|
-                                                                                                          -- ASSIGN  |PARTITIONED|
-                                                                                                            -- STREAM_PROJECT  |PARTITIONED|
-                                                                                                              -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                                                                                -- SPLIT  |PARTITIONED|
-                                                                                                                  -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                                                                                    -- DATASOURCE_SCAN  |PARTITIONED|
-                                                                                                                      -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                                                                                        -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
-                                              -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                -- SPLIT  |PARTITIONED|
-                                                  -- HASH_PARTITION_EXCHANGE [$$23]  |PARTITIONED|
-                                                    -- STREAM_PROJECT  |PARTITIONED|
-                                                      -- UNNEST  |PARTITIONED|
-                                                        -- STREAM_PROJECT  |PARTITIONED|
+                            -- STABLE_SORT [$$122(ASC), $$124(ASC)]  |PARTITIONED|
+                              -- HASH_PARTITION_EXCHANGE [$$122, $$124]  |PARTITIONED|
+                                -- STREAM_PROJECT  |PARTITIONED|
+                                  -- ASSIGN  |PARTITIONED|
+                                    -- STREAM_SELECT  |PARTITIONED|
+                                      -- STREAM_PROJECT  |PARTITIONED|
+                                        -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                          -- HYBRID_HASH_JOIN [$$12][$$23]  |PARTITIONED|
+                                            -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                              -- STREAM_PROJECT  |PARTITIONED|
+                                                -- ASSIGN  |PARTITIONED|
+                                                  -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                    -- SPLIT  |PARTITIONED|
+                                                      -- HASH_PARTITION_EXCHANGE [$$23]  |PARTITIONED|
+                                                        -- UNNEST  |PARTITIONED|
                                                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                            -- PRE_CLUSTERED_GROUP_BY[$$105]  |PARTITIONED|
+                                                            -- PRE_CLUSTERED_GROUP_BY[$$97]  |PARTITIONED|
                                                                     {
                                                                       -- AGGREGATE  |LOCAL|
                                                                         -- STREAM_SELECT  |LOCAL|
                                                                           -- NESTED_TUPLE_SOURCE  |LOCAL|
                                                                     }
                                                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                                -- STABLE_SORT [$$105(ASC), $$21(ASC)]  |PARTITIONED|
-                                                                  -- HASH_PARTITION_EXCHANGE [$$105]  |PARTITIONED|
+                                                                -- STABLE_SORT [$$97(ASC), $$21(ASC)]  |PARTITIONED|
+                                                                  -- HASH_PARTITION_EXCHANGE [$$97]  |PARTITIONED|
                                                                     -- STREAM_PROJECT  |PARTITIONED|
                                                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
                                                                         -- HYBRID_HASH_JOIN [$$15][$$18]  |PARTITIONED|
                                                                           -- HASH_PARTITION_EXCHANGE [$$15]  |PARTITIONED|
-                                                                            -- UNNEST  |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|
+                                                                            -- STREAM_PROJECT  |PARTITIONED|
+                                                                              -- UNNEST  |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 [$$18]  |PARTITIONED|
-                                                                            -- RUNNING_AGGREGATE  |PARTITIONED|
-                                                                              -- STREAM_PROJECT  |PARTITIONED|
-                                                                                -- SORT_MERGE_EXCHANGE [$$107(ASC), $$18(ASC) ]  |PARTITIONED|
-                                                                                  -- STABLE_SORT [$$107(ASC), $$18(ASC)]  |PARTITIONED|
+                                                                            -- ASSIGN  |PARTITIONED|
+                                                                              -- RUNNING_AGGREGATE  |PARTITIONED|
+                                                                                -- STREAM_PROJECT  |PARTITIONED|
+                                                                                  -- SORT_MERGE_EXCHANGE [$$105(ASC), $$18(ASC) ]  |PARTITIONED|
+                                                                                    -- STABLE_SORT [$$105(ASC), $$18(ASC)]  |PARTITIONED|
+                                                                                      -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                        -- PRE_CLUSTERED_GROUP_BY[$$130]  |PARTITIONED|
+                                                                                                {
+                                                                                                  -- AGGREGATE  |LOCAL|
+                                                                                                    -- NESTED_TUPLE_SOURCE  |LOCAL|
+                                                                                                }
+                                                                                          -- HASH_PARTITION_MERGE_EXCHANGE MERGE:[$$130(ASC)] HASH:[$$130]  |PARTITIONED|
+                                                                                            -- SORT_GROUP_BY[$$17]  |PARTITIONED|
+                                                                                                    {
+                                                                                                      -- AGGREGATE  |LOCAL|
+                                                                                                        -- NESTED_TUPLE_SOURCE  |LOCAL|
+                                                                                                    }
+                                                                                              -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                -- STREAM_PROJECT  |PARTITIONED|
+                                                                                                  -- UNNEST  |PARTITIONED|
+                                                                                                    -- STREAM_PROJECT  |PARTITIONED|
+                                                                                                      -- ASSIGN  |PARTITIONED|
+                                                                                                        -- STREAM_PROJECT  |PARTITIONED|
+                                                                                                          -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                            -- SPLIT  |PARTITIONED|
+                                                                                                              -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                                -- DATASOURCE_SCAN  |PARTITIONED|
+                                                                                                                  -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                                    -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                                            -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                              -- SPLIT  |PARTITIONED|
+                                                -- HASH_PARTITION_EXCHANGE [$$23]  |PARTITIONED|
+                                                  -- UNNEST  |PARTITIONED|
+                                                    -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                      -- PRE_CLUSTERED_GROUP_BY[$$97]  |PARTITIONED|
+                                                              {
+                                                                -- AGGREGATE  |LOCAL|
+                                                                  -- STREAM_SELECT  |LOCAL|
+                                                                    -- NESTED_TUPLE_SOURCE  |LOCAL|
+                                                              }
+                                                        -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                          -- STABLE_SORT [$$97(ASC), $$21(ASC)]  |PARTITIONED|
+                                                            -- HASH_PARTITION_EXCHANGE [$$97]  |PARTITIONED|
+                                                              -- STREAM_PROJECT  |PARTITIONED|
+                                                                -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                  -- HYBRID_HASH_JOIN [$$15][$$18]  |PARTITIONED|
+                                                                    -- HASH_PARTITION_EXCHANGE [$$15]  |PARTITIONED|
+                                                                      -- STREAM_PROJECT  |PARTITIONED|
+                                                                        -- UNNEST  |PARTITIONED|
+                                                                          -- ASSIGN  |PARTITIONED|
+                                                                            -- STREAM_PROJECT  |PARTITIONED|
+                                                                              -- ASSIGN  |PARTITIONED|
+                                                                                -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                  -- DATASOURCE_SCAN  |PARTITIONED|
                                                                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                                                      -- PRE_CLUSTERED_GROUP_BY[$$135]  |PARTITIONED|
+                                                                                      -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                                                                    -- HASH_PARTITION_EXCHANGE [$$18]  |PARTITIONED|
+                                                                      -- ASSIGN  |PARTITIONED|
+                                                                        -- RUNNING_AGGREGATE  |PARTITIONED|
+                                                                          -- STREAM_PROJECT  |PARTITIONED|
+                                                                            -- SORT_MERGE_EXCHANGE [$$105(ASC), $$18(ASC) ]  |PARTITIONED|
+                                                                              -- STABLE_SORT [$$105(ASC), $$18(ASC)]  |PARTITIONED|
+                                                                                -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                  -- PRE_CLUSTERED_GROUP_BY[$$130]  |PARTITIONED|
+                                                                                          {
+                                                                                            -- AGGREGATE  |LOCAL|
+                                                                                              -- NESTED_TUPLE_SOURCE  |LOCAL|
+                                                                                          }
+                                                                                    -- HASH_PARTITION_MERGE_EXCHANGE MERGE:[$$130(ASC)] HASH:[$$130]  |PARTITIONED|
+                                                                                      -- SORT_GROUP_BY[$$17]  |PARTITIONED|
                                                                                               {
                                                                                                 -- AGGREGATE  |LOCAL|
                                                                                                   -- NESTED_TUPLE_SOURCE  |LOCAL|
                                                                                               }
-                                                                                        -- HASH_PARTITION_MERGE_EXCHANGE MERGE:[$$135(ASC)] HASH:[$$135]  |PARTITIONED|
-                                                                                          -- SORT_GROUP_BY[$$17]  |PARTITIONED|
-                                                                                                  {
-                                                                                                    -- AGGREGATE  |LOCAL|
-                                                                                                      -- NESTED_TUPLE_SOURCE  |LOCAL|
-                                                                                                  }
-                                                                                            -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                        -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                          -- STREAM_PROJECT  |PARTITIONED|
+                                                                                            -- UNNEST  |PARTITIONED|
                                                                                               -- STREAM_PROJECT  |PARTITIONED|
-                                                                                                -- UNNEST  |PARTITIONED|
+                                                                                                -- ASSIGN  |PARTITIONED|
                                                                                                   -- STREAM_PROJECT  |PARTITIONED|
-                                                                                                    -- ASSIGN  |PARTITIONED|
-                                                                                                      -- STREAM_PROJECT  |PARTITIONED|
+                                                                                                    -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                      -- SPLIT  |PARTITIONED|
                                                                                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                                                                          -- SPLIT  |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|
diff --git a/asterix-app/src/test/resources/optimizerts/results/udfs/query-ASTERIXDB-1017-2.plan b/asterix-app/src/test/resources/optimizerts/results/udfs/query-ASTERIXDB-1017-2.plan
index 1ddb0d3..ac63dd0 100644
--- a/asterix-app/src/test/resources/optimizerts/results/udfs/query-ASTERIXDB-1017-2.plan
+++ b/asterix-app/src/test/resources/optimizerts/results/udfs/query-ASTERIXDB-1017-2.plan
@@ -4,7 +4,7 @@
       -- ASSIGN  |PARTITIONED|
         -- STREAM_PROJECT  |PARTITIONED|
           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-            -- HYBRID_HASH_JOIN [$$33][$$49]  |PARTITIONED|
+            -- HYBRID_HASH_JOIN [$$33][$$48]  |PARTITIONED|
               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
                 -- STREAM_PROJECT  |PARTITIONED|
                   -- ASSIGN  |PARTITIONED|
@@ -12,49 +12,49 @@
                       -- DATASOURCE_SCAN  |PARTITIONED|
                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
                           -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
-              -- HASH_PARTITION_EXCHANGE [$$49]  |PARTITIONED|
+              -- HASH_PARTITION_EXCHANGE [$$48]  |PARTITIONED|
                 -- NESTED_LOOP  |PARTITIONED|
                   -- BROADCAST_EXCHANGE  |PARTITIONED|
                     -- STREAM_PROJECT  |PARTITIONED|
                       -- STREAM_SELECT  |PARTITIONED|
                         -- STREAM_PROJECT  |PARTITIONED|
                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                            -- PRE_CLUSTERED_GROUP_BY[$$38]  |PARTITIONED|
+                            -- PRE_CLUSTERED_GROUP_BY[$$34, $$47]  |PARTITIONED|
                                     {
                                       -- AGGREGATE  |LOCAL|
                                         -- STREAM_SELECT  |LOCAL|
                                           -- NESTED_TUPLE_SOURCE  |LOCAL|
                                     }
                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                -- STABLE_SORT [$$38(ASC)]  |PARTITIONED|
-                                  -- HASH_PARTITION_EXCHANGE [$$38]  |PARTITIONED|
+                                -- STABLE_SORT [$$34(ASC), $$47(ASC)]  |PARTITIONED|
+                                  -- HASH_PARTITION_EXCHANGE [$$34, $$47]  |PARTITIONED|
                                     -- STREAM_PROJECT  |PARTITIONED|
-                                      -- STREAM_PROJECT  |PARTITIONED|
-                                        -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                          -- NESTED_LOOP  |PARTITIONED|
-                                            -- BROADCAST_EXCHANGE  |PARTITIONED|
-                                              -- NESTED_LOOP  |PARTITIONED|
-                                                -- BROADCAST_EXCHANGE  |PARTITIONED|
-                                                  -- STREAM_PROJECT  |PARTITIONED|
-                                                    -- ASSIGN  |PARTITIONED|
-                                                      -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                        -- DATASOURCE_SCAN  |PARTITIONED|
-                                                          -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                            -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
-                                                -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                      -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                        -- NESTED_LOOP  |PARTITIONED|
+                                          -- BROADCAST_EXCHANGE  |PARTITIONED|
+                                            -- NESTED_LOOP  |PARTITIONED|
+                                              -- BROADCAST_EXCHANGE  |PARTITIONED|
+                                                -- STREAM_PROJECT  |PARTITIONED|
                                                   -- ASSIGN  |PARTITIONED|
                                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
                                                       -- DATASOURCE_SCAN  |PARTITIONED|
                                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
                                                           -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
-                                            -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                              -- STREAM_PROJECT  |PARTITIONED|
-                                                -- ASSIGN  |PARTITIONED|
-                                                  -- STREAM_PROJECT  |PARTITIONED|
+                                              -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                -- STREAM_PROJECT  |PARTITIONED|
+                                                  -- ASSIGN  |PARTITIONED|
                                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
                                                       -- DATASOURCE_SCAN  |PARTITIONED|
                                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
                                                           -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                                          -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                            -- STREAM_PROJECT  |PARTITIONED|
+                                              -- ASSIGN  |PARTITIONED|
+                                                -- STREAM_PROJECT  |PARTITIONED|
+                                                  -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                    -- DATASOURCE_SCAN  |PARTITIONED|
+                                                      -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                        -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
                   -- ONE_TO_ONE_EXCHANGE  |UNPARTITIONED|
                     -- STREAM_PROJECT  |UNPARTITIONED|
                       -- ASSIGN  |UNPARTITIONED|
diff --git a/asterix-app/src/test/resources/optimizerts/results/udfs/query-ASTERIXDB-1017-recursive-2.plan b/asterix-app/src/test/resources/optimizerts/results/udfs/query-ASTERIXDB-1017-recursive-2.plan
index 676aee1..541e146 100644
--- a/asterix-app/src/test/resources/optimizerts/results/udfs/query-ASTERIXDB-1017-recursive-2.plan
+++ b/asterix-app/src/test/resources/optimizerts/results/udfs/query-ASTERIXDB-1017-recursive-2.plan
@@ -4,7 +4,7 @@
       -- ASSIGN  |PARTITIONED|
         -- STREAM_PROJECT  |PARTITIONED|
           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-            -- HYBRID_HASH_JOIN [$$58][$$64]  |PARTITIONED|
+            -- HYBRID_HASH_JOIN [$$56][$$63]  |PARTITIONED|
               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
                 -- STREAM_PROJECT  |PARTITIONED|
                   -- ASSIGN  |PARTITIONED|
@@ -12,49 +12,49 @@
                       -- DATASOURCE_SCAN  |PARTITIONED|
                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
                           -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
-              -- HASH_PARTITION_EXCHANGE [$$64]  |PARTITIONED|
+              -- HASH_PARTITION_EXCHANGE [$$63]  |PARTITIONED|
                 -- NESTED_LOOP  |PARTITIONED|
                   -- BROADCAST_EXCHANGE  |PARTITIONED|
                     -- STREAM_PROJECT  |PARTITIONED|
                       -- STREAM_SELECT  |PARTITIONED|
                         -- STREAM_PROJECT  |PARTITIONED|
                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                            -- PRE_CLUSTERED_GROUP_BY[$$48]  |PARTITIONED|
+                            -- PRE_CLUSTERED_GROUP_BY[$$43, $$62]  |PARTITIONED|
                                     {
                                       -- AGGREGATE  |LOCAL|
                                         -- STREAM_SELECT  |LOCAL|
                                           -- NESTED_TUPLE_SOURCE  |LOCAL|
                                     }
                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                -- STABLE_SORT [$$48(ASC)]  |PARTITIONED|
-                                  -- HASH_PARTITION_EXCHANGE [$$48]  |PARTITIONED|
+                                -- STABLE_SORT [$$43(ASC), $$62(ASC)]  |PARTITIONED|
+                                  -- HASH_PARTITION_EXCHANGE [$$43, $$62]  |PARTITIONED|
                                     -- STREAM_PROJECT  |PARTITIONED|
-                                      -- STREAM_PROJECT  |PARTITIONED|
-                                        -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                          -- NESTED_LOOP  |PARTITIONED|
-                                            -- BROADCAST_EXCHANGE  |PARTITIONED|
-                                              -- NESTED_LOOP  |PARTITIONED|
-                                                -- BROADCAST_EXCHANGE  |PARTITIONED|
-                                                  -- STREAM_PROJECT  |PARTITIONED|
-                                                    -- ASSIGN  |PARTITIONED|
-                                                      -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                        -- DATASOURCE_SCAN  |PARTITIONED|
-                                                          -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                            -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
-                                                -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                      -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                        -- NESTED_LOOP  |PARTITIONED|
+                                          -- BROADCAST_EXCHANGE  |PARTITIONED|
+                                            -- NESTED_LOOP  |PARTITIONED|
+                                              -- BROADCAST_EXCHANGE  |PARTITIONED|
+                                                -- STREAM_PROJECT  |PARTITIONED|
                                                   -- ASSIGN  |PARTITIONED|
                                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
                                                       -- DATASOURCE_SCAN  |PARTITIONED|
                                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
                                                           -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
-                                            -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                              -- STREAM_PROJECT  |PARTITIONED|
-                                                -- ASSIGN  |PARTITIONED|
-                                                  -- STREAM_PROJECT  |PARTITIONED|
+                                              -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                -- STREAM_PROJECT  |PARTITIONED|
+                                                  -- ASSIGN  |PARTITIONED|
                                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
                                                       -- DATASOURCE_SCAN  |PARTITIONED|
                                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
                                                           -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                                          -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                            -- STREAM_PROJECT  |PARTITIONED|
+                                              -- ASSIGN  |PARTITIONED|
+                                                -- STREAM_PROJECT  |PARTITIONED|
+                                                  -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                    -- DATASOURCE_SCAN  |PARTITIONED|
+                                                      -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                        -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
                   -- ONE_TO_ONE_EXCHANGE  |UNPARTITIONED|
                     -- STREAM_PROJECT  |UNPARTITIONED|
                       -- ASSIGN  |UNPARTITIONED|
diff --git a/asterix-app/src/test/resources/optimizerts/results/udfs/query-ASTERIXDB-1017-recursive.plan b/asterix-app/src/test/resources/optimizerts/results/udfs/query-ASTERIXDB-1017-recursive.plan
index 555050c..2d964a8 100644
--- a/asterix-app/src/test/resources/optimizerts/results/udfs/query-ASTERIXDB-1017-recursive.plan
+++ b/asterix-app/src/test/resources/optimizerts/results/udfs/query-ASTERIXDB-1017-recursive.plan
@@ -4,7 +4,7 @@
       -- ASSIGN  |PARTITIONED|
         -- STREAM_PROJECT  |PARTITIONED|
           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-            -- HYBRID_HASH_JOIN [$$54][$$59]  |PARTITIONED|
+            -- HYBRID_HASH_JOIN [$$52][$$58]  |PARTITIONED|
               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
                 -- STREAM_PROJECT  |PARTITIONED|
                   -- ASSIGN  |PARTITIONED|
@@ -17,51 +17,51 @@
                                 -- DATASOURCE_SCAN  |PARTITIONED|
                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
                                     -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
-              -- HASH_PARTITION_EXCHANGE [$$59]  |PARTITIONED|
+              -- HASH_PARTITION_EXCHANGE [$$58]  |PARTITIONED|
                 -- NESTED_LOOP  |PARTITIONED|
                   -- BROADCAST_EXCHANGE  |PARTITIONED|
                     -- STREAM_PROJECT  |PARTITIONED|
                       -- STREAM_SELECT  |PARTITIONED|
                         -- STREAM_PROJECT  |PARTITIONED|
                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                            -- PRE_CLUSTERED_GROUP_BY[$$45]  |PARTITIONED|
+                            -- PRE_CLUSTERED_GROUP_BY[$$41, $$57]  |PARTITIONED|
                                     {
                                       -- AGGREGATE  |LOCAL|
                                         -- STREAM_SELECT  |LOCAL|
                                           -- NESTED_TUPLE_SOURCE  |LOCAL|
                                     }
                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                -- STABLE_SORT [$$45(ASC)]  |PARTITIONED|
-                                  -- HASH_PARTITION_EXCHANGE [$$45]  |PARTITIONED|
+                                -- STABLE_SORT [$$41(ASC), $$57(ASC)]  |PARTITIONED|
+                                  -- HASH_PARTITION_EXCHANGE [$$41, $$57]  |PARTITIONED|
                                     -- STREAM_PROJECT  |PARTITIONED|
-                                      -- STREAM_PROJECT  |PARTITIONED|
-                                        -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                          -- NESTED_LOOP  |PARTITIONED|
-                                            -- BROADCAST_EXCHANGE  |PARTITIONED|
-                                              -- NESTED_LOOP  |PARTITIONED|
-                                                -- BROADCAST_EXCHANGE  |PARTITIONED|
-                                                  -- SPLIT  |PARTITIONED|
-                                                    -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                      -- STREAM_PROJECT  |PARTITIONED|
-                                                        -- ASSIGN  |PARTITIONED|
-                                                          -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                            -- DATASOURCE_SCAN  |PARTITIONED|
-                                                              -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                                -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
-                                                -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                      -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                        -- NESTED_LOOP  |PARTITIONED|
+                                          -- BROADCAST_EXCHANGE  |PARTITIONED|
+                                            -- NESTED_LOOP  |PARTITIONED|
+                                              -- BROADCAST_EXCHANGE  |PARTITIONED|
+                                                -- SPLIT  |PARTITIONED|
+                                                  -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                    -- STREAM_PROJECT  |PARTITIONED|
+                                                      -- ASSIGN  |PARTITIONED|
+                                                        -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                          -- DATASOURCE_SCAN  |PARTITIONED|
+                                                            -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                              -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                                              -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                -- STREAM_PROJECT  |PARTITIONED|
                                                   -- ASSIGN  |PARTITIONED|
                                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
                                                       -- DATASOURCE_SCAN  |PARTITIONED|
                                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
                                                           -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
-                                            -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                              -- STREAM_PROJECT  |PARTITIONED|
-                                                -- ASSIGN  |PARTITIONED|
-                                                  -- STREAM_PROJECT  |PARTITIONED|
-                                                    -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                      -- DATASOURCE_SCAN  |PARTITIONED|
-                                                        -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                          -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                                          -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                            -- STREAM_PROJECT  |PARTITIONED|
+                                              -- ASSIGN  |PARTITIONED|
+                                                -- STREAM_PROJECT  |PARTITIONED|
+                                                  -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                    -- DATASOURCE_SCAN  |PARTITIONED|
+                                                      -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                        -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
                   -- ONE_TO_ONE_EXCHANGE  |UNPARTITIONED|
                     -- STREAM_PROJECT  |UNPARTITIONED|
                       -- ASSIGN  |UNPARTITIONED|
diff --git a/asterix-app/src/test/resources/optimizerts/results/udfs/query-ASTERIXDB-1017.plan b/asterix-app/src/test/resources/optimizerts/results/udfs/query-ASTERIXDB-1017.plan
index 911c1f3..7b1e829 100644
--- a/asterix-app/src/test/resources/optimizerts/results/udfs/query-ASTERIXDB-1017.plan
+++ b/asterix-app/src/test/resources/optimizerts/results/udfs/query-ASTERIXDB-1017.plan
@@ -4,7 +4,7 @@
       -- ASSIGN  |PARTITIONED|
         -- STREAM_PROJECT  |PARTITIONED|
           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-            -- HYBRID_HASH_JOIN [$$35][$$30]  |PARTITIONED|
+            -- HYBRID_HASH_JOIN [$$30][$$42]  |PARTITIONED|
               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
                 -- STREAM_PROJECT  |PARTITIONED|
                   -- ASSIGN  |PARTITIONED|
@@ -12,47 +12,48 @@
                       -- DATASOURCE_SCAN  |PARTITIONED|
                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
                           -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
-              -- HASH_PARTITION_EXCHANGE [$$30]  |PARTITIONED|
+              -- HASH_PARTITION_EXCHANGE [$$42]  |PARTITIONED|
                 -- NESTED_LOOP  |PARTITIONED|
                   -- BROADCAST_EXCHANGE  |PARTITIONED|
                     -- STREAM_PROJECT  |PARTITIONED|
                       -- STREAM_SELECT  |PARTITIONED|
-                        -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                          -- PRE_CLUSTERED_GROUP_BY[$$41]  |PARTITIONED|
-                                  {
-                                    -- AGGREGATE  |LOCAL|
-                                      -- STREAM_SELECT  |LOCAL|
-                                        -- NESTED_TUPLE_SOURCE  |LOCAL|
-                                  }
-                            -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                              -- STABLE_SORT [$$41(ASC)]  |PARTITIONED|
-                                -- HASH_PARTITION_EXCHANGE [$$41]  |PARTITIONED|
-                                  -- STREAM_PROJECT  |PARTITIONED|
-                                    -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                      -- HYBRID_HASH_JOIN [$$38][$$36]  |PARTITIONED|
-                                        -- HASH_PARTITION_EXCHANGE [$$38]  |PARTITIONED|
-                                          -- NESTED_LOOP  |PARTITIONED|
-                                            -- BROADCAST_EXCHANGE  |PARTITIONED|
-                                              -- STREAM_PROJECT  |PARTITIONED|
-                                                -- ASSIGN  |PARTITIONED|
+                        -- STREAM_PROJECT  |PARTITIONED|
+                          -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                            -- PRE_CLUSTERED_GROUP_BY[$$31, $$41]  |PARTITIONED|
+                                    {
+                                      -- AGGREGATE  |LOCAL|
+                                        -- STREAM_SELECT  |LOCAL|
+                                          -- NESTED_TUPLE_SOURCE  |LOCAL|
+                                    }
+                              -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                -- STABLE_SORT [$$31(ASC), $$41(ASC)]  |PARTITIONED|
+                                  -- HASH_PARTITION_EXCHANGE [$$31, $$41]  |PARTITIONED|
+                                    -- STREAM_PROJECT  |PARTITIONED|
+                                      -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                        -- HYBRID_HASH_JOIN [$$38][$$34]  |PARTITIONED|
+                                          -- HASH_PARTITION_EXCHANGE [$$38]  |PARTITIONED|
+                                            -- NESTED_LOOP  |PARTITIONED|
+                                              -- BROADCAST_EXCHANGE  |PARTITIONED|
+                                                -- STREAM_PROJECT  |PARTITIONED|
+                                                  -- ASSIGN  |PARTITIONED|
+                                                    -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                      -- DATASOURCE_SCAN  |PARTITIONED|
+                                                        -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                          -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                                              -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                -- STREAM_PROJECT  |PARTITIONED|
                                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
                                                     -- DATASOURCE_SCAN  |PARTITIONED|
                                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
                                                         -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
-                                            -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                              -- STREAM_PROJECT  |PARTITIONED|
-                                                -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                  -- DATASOURCE_SCAN  |PARTITIONED|
-                                                    -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                      -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
-                                        -- HASH_PARTITION_EXCHANGE [$$36]  |PARTITIONED|
-                                          -- STREAM_PROJECT  |PARTITIONED|
-                                            -- ASSIGN  |PARTITIONED|
-                                              -- STREAM_PROJECT  |PARTITIONED|
-                                                -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                  -- DATASOURCE_SCAN  |PARTITIONED|
-                                                    -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                      -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                                          -- HASH_PARTITION_EXCHANGE [$$34]  |PARTITIONED|
+                                            -- STREAM_PROJECT  |PARTITIONED|
+                                              -- ASSIGN  |PARTITIONED|
+                                                -- STREAM_PROJECT  |PARTITIONED|
+                                                  -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                    -- DATASOURCE_SCAN  |PARTITIONED|
+                                                      -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                        -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
                   -- ONE_TO_ONE_EXCHANGE  |UNPARTITIONED|
                     -- STREAM_PROJECT  |UNPARTITIONED|
                       -- ASSIGN  |UNPARTITIONED|
diff --git a/asterix-app/src/test/resources/optimizerts/results/udfs/query-ASTERIXDB-1018.plan b/asterix-app/src/test/resources/optimizerts/results/udfs/query-ASTERIXDB-1018.plan
index 7c4a8c2..1e7e505 100644
--- a/asterix-app/src/test/resources/optimizerts/results/udfs/query-ASTERIXDB-1018.plan
+++ b/asterix-app/src/test/resources/optimizerts/results/udfs/query-ASTERIXDB-1018.plan
@@ -4,75 +4,76 @@
       -- ASSIGN  |PARTITIONED|
         -- STREAM_PROJECT  |PARTITIONED|
           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-            -- HYBRID_HASH_JOIN [$$39][$$34]  |PARTITIONED|
+            -- HYBRID_HASH_JOIN [$$34][$$50]  |PARTITIONED|
               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
                 -- STREAM_PROJECT  |PARTITIONED|
                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
                     -- DATASOURCE_SCAN  |PARTITIONED|
                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
                         -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
-              -- HASH_PARTITION_EXCHANGE [$$34]  |PARTITIONED|
+              -- HASH_PARTITION_EXCHANGE [$$50]  |PARTITIONED|
                 -- STREAM_PROJECT  |PARTITIONED|
                   -- ASSIGN  |PARTITIONED|
-                    -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                      -- PRE_CLUSTERED_GROUP_BY[$$41]  |PARTITIONED|
-                              {
-                                -- AGGREGATE  |LOCAL|
-                                  -- STREAM_SELECT  |LOCAL|
-                                    -- NESTED_TUPLE_SOURCE  |LOCAL|
-                              }
-                        -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                          -- STABLE_SORT [$$41(ASC)]  |PARTITIONED|
-                            -- HASH_PARTITION_EXCHANGE [$$41]  |PARTITIONED|
-                              -- STREAM_PROJECT  |PARTITIONED|
-                                -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                  -- NESTED_LOOP  |PARTITIONED|
-                                    -- BROADCAST_EXCHANGE  |PARTITIONED|
-                                      -- STREAM_PROJECT  |PARTITIONED|
-                                        -- STREAM_SELECT  |PARTITIONED|
-                                          -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                            -- PRE_CLUSTERED_GROUP_BY[$$47]  |PARTITIONED|
-                                                    {
-                                                      -- AGGREGATE  |LOCAL|
-                                                        -- STREAM_SELECT  |LOCAL|
-                                                          -- NESTED_TUPLE_SOURCE  |LOCAL|
-                                                    }
-                                              -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                -- STABLE_SORT [$$47(ASC)]  |PARTITIONED|
-                                                  -- HASH_PARTITION_EXCHANGE [$$47]  |PARTITIONED|
-                                                    -- STREAM_PROJECT  |PARTITIONED|
-                                                      -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                        -- HYBRID_HASH_JOIN [$$45][$$42]  |PARTITIONED|
-                                                          -- HASH_PARTITION_EXCHANGE [$$45]  |PARTITIONED|
-                                                            -- NESTED_LOOP  |PARTITIONED|
-                                                              -- BROADCAST_EXCHANGE  |PARTITIONED|
-                                                                -- STREAM_PROJECT  |PARTITIONED|
-                                                                  -- ASSIGN  |PARTITIONED|
-                                                                    -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                                      -- DATASOURCE_SCAN  |PARTITIONED|
-                                                                        -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                                          -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
-                                                              -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                                -- STREAM_PROJECT  |PARTITIONED|
-                                                                  -- ASSIGN  |PARTITIONED|
-                                                                    -- STREAM_PROJECT  |PARTITIONED|
+                    -- STREAM_PROJECT  |PARTITIONED|
+                      -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                        -- PRE_CLUSTERED_GROUP_BY[$$55, $$24, $$54]  |PARTITIONED|
+                                {
+                                  -- AGGREGATE  |LOCAL|
+                                    -- STREAM_SELECT  |LOCAL|
+                                      -- NESTED_TUPLE_SOURCE  |LOCAL|
+                                }
+                          -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                            -- STABLE_SORT [$$55(ASC), $$24(ASC), $$54(ASC)]  |PARTITIONED|
+                              -- HASH_PARTITION_EXCHANGE [$$55, $$24, $$54]  |PARTITIONED|
+                                -- STREAM_PROJECT  |PARTITIONED|
+                                  -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                    -- NESTED_LOOP  |PARTITIONED|
+                                      -- BROADCAST_EXCHANGE  |PARTITIONED|
+                                        -- STREAM_PROJECT  |PARTITIONED|
+                                          -- STREAM_SELECT  |PARTITIONED|
+                                            -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                              -- PRE_CLUSTERED_GROUP_BY[$$49, $$35]  |PARTITIONED|
+                                                      {
+                                                        -- AGGREGATE  |LOCAL|
+                                                          -- STREAM_SELECT  |LOCAL|
+                                                            -- NESTED_TUPLE_SOURCE  |LOCAL|
+                                                      }
+                                                -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                  -- STABLE_SORT [$$49(ASC), $$35(ASC)]  |PARTITIONED|
+                                                    -- HASH_PARTITION_EXCHANGE [$$49, $$35]  |PARTITIONED|
+                                                      -- STREAM_PROJECT  |PARTITIONED|
+                                                        -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                          -- HYBRID_HASH_JOIN [$$47][$$38]  |PARTITIONED|
+                                                            -- HASH_PARTITION_EXCHANGE [$$47]  |PARTITIONED|
+                                                              -- NESTED_LOOP  |PARTITIONED|
+                                                                -- BROADCAST_EXCHANGE  |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 [$$42]  |PARTITIONED|
-                                                            -- STREAM_PROJECT  |PARTITIONED|
-                                                              -- ASSIGN  |PARTITIONED|
-                                                                -- STREAM_PROJECT  |PARTITIONED|
-                                                                  -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                                    -- DATASOURCE_SCAN  |PARTITIONED|
-                                                                      -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                                        -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
-                                    -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                      -- STREAM_PROJECT  |PARTITIONED|
-                                        -- ASSIGN  |PARTITIONED|
-                                          -- STREAM_PROJECT  |PARTITIONED|
-                                            -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                              -- DATASOURCE_SCAN  |PARTITIONED|
-                                                -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                  -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                                                                -- 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|
+                                                            -- HASH_PARTITION_EXCHANGE [$$38]  |PARTITIONED|
+                                                              -- STREAM_PROJECT  |PARTITIONED|
+                                                                -- ASSIGN  |PARTITIONED|
+                                                                  -- STREAM_PROJECT  |PARTITIONED|
+                                                                    -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                      -- DATASOURCE_SCAN  |PARTITIONED|
+                                                                        -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                          -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                                      -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                        -- STREAM_PROJECT  |PARTITIONED|
+                                          -- ASSIGN  |PARTITIONED|
+                                            -- STREAM_PROJECT  |PARTITIONED|
+                                              -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                -- DATASOURCE_SCAN  |PARTITIONED|
+                                                  -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                    -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterix-app/src/test/resources/optimizerts/results/udfs/query-ASTERIXDB-1019.plan b/asterix-app/src/test/resources/optimizerts/results/udfs/query-ASTERIXDB-1019.plan
index 0124285..3bf96d9 100644
--- a/asterix-app/src/test/resources/optimizerts/results/udfs/query-ASTERIXDB-1019.plan
+++ b/asterix-app/src/test/resources/optimizerts/results/udfs/query-ASTERIXDB-1019.plan
@@ -12,75 +12,76 @@
                       -- ASSIGN  |PARTITIONED|
                         -- STREAM_PROJECT  |PARTITIONED|
                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                            -- HYBRID_HASH_JOIN [$$43][$$38]  |PARTITIONED|
+                            -- HYBRID_HASH_JOIN [$$38][$$54]  |PARTITIONED|
                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
                                 -- STREAM_PROJECT  |PARTITIONED|
                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
                                     -- DATASOURCE_SCAN  |PARTITIONED|
                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
                                         -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
-                              -- HASH_PARTITION_EXCHANGE [$$38]  |PARTITIONED|
+                              -- HASH_PARTITION_EXCHANGE [$$54]  |PARTITIONED|
                                 -- STREAM_PROJECT  |PARTITIONED|
                                   -- ASSIGN  |PARTITIONED|
-                                    -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                      -- PRE_CLUSTERED_GROUP_BY[$$45]  |PARTITIONED|
-                                              {
-                                                -- AGGREGATE  |LOCAL|
-                                                  -- STREAM_SELECT  |LOCAL|
-                                                    -- NESTED_TUPLE_SOURCE  |LOCAL|
-                                              }
-                                        -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                          -- STABLE_SORT [$$45(ASC)]  |PARTITIONED|
-                                            -- HASH_PARTITION_EXCHANGE [$$45]  |PARTITIONED|
-                                              -- STREAM_PROJECT  |PARTITIONED|
-                                                -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                  -- NESTED_LOOP  |PARTITIONED|
-                                                    -- BROADCAST_EXCHANGE  |PARTITIONED|
-                                                      -- STREAM_PROJECT  |PARTITIONED|
-                                                        -- STREAM_SELECT  |PARTITIONED|
-                                                          -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                            -- PRE_CLUSTERED_GROUP_BY[$$51]  |PARTITIONED|
-                                                                    {
-                                                                      -- AGGREGATE  |LOCAL|
-                                                                        -- STREAM_SELECT  |LOCAL|
-                                                                          -- NESTED_TUPLE_SOURCE  |LOCAL|
-                                                                    }
-                                                              -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                                -- STABLE_SORT [$$51(ASC)]  |PARTITIONED|
-                                                                  -- HASH_PARTITION_EXCHANGE [$$51]  |PARTITIONED|
-                                                                    -- STREAM_PROJECT  |PARTITIONED|
-                                                                      -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                                        -- HYBRID_HASH_JOIN [$$49][$$46]  |PARTITIONED|
-                                                                          -- HASH_PARTITION_EXCHANGE [$$49]  |PARTITIONED|
-                                                                            -- NESTED_LOOP  |PARTITIONED|
-                                                                              -- BROADCAST_EXCHANGE  |PARTITIONED|
-                                                                                -- STREAM_PROJECT  |PARTITIONED|
-                                                                                  -- ASSIGN  |PARTITIONED|
-                                                                                    -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                                                      -- DATASOURCE_SCAN  |PARTITIONED|
-                                                                                        -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                                                          -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
-                                                                              -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                                                -- STREAM_PROJECT  |PARTITIONED|
-                                                                                  -- ASSIGN  |PARTITIONED|
-                                                                                    -- STREAM_PROJECT  |PARTITIONED|
+                                    -- STREAM_PROJECT  |PARTITIONED|
+                                      -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                        -- PRE_CLUSTERED_GROUP_BY[$$59, $$24, $$58]  |PARTITIONED|
+                                                {
+                                                  -- AGGREGATE  |LOCAL|
+                                                    -- STREAM_SELECT  |LOCAL|
+                                                      -- NESTED_TUPLE_SOURCE  |LOCAL|
+                                                }
+                                          -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                            -- STABLE_SORT [$$59(ASC), $$24(ASC), $$58(ASC)]  |PARTITIONED|
+                                              -- HASH_PARTITION_EXCHANGE [$$59, $$24, $$58]  |PARTITIONED|
+                                                -- STREAM_PROJECT  |PARTITIONED|
+                                                  -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                    -- NESTED_LOOP  |PARTITIONED|
+                                                      -- BROADCAST_EXCHANGE  |PARTITIONED|
+                                                        -- STREAM_PROJECT  |PARTITIONED|
+                                                          -- STREAM_SELECT  |PARTITIONED|
+                                                            -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                              -- PRE_CLUSTERED_GROUP_BY[$$53, $$39]  |PARTITIONED|
+                                                                      {
+                                                                        -- AGGREGATE  |LOCAL|
+                                                                          -- STREAM_SELECT  |LOCAL|
+                                                                            -- NESTED_TUPLE_SOURCE  |LOCAL|
+                                                                      }
+                                                                -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                  -- STABLE_SORT [$$53(ASC), $$39(ASC)]  |PARTITIONED|
+                                                                    -- HASH_PARTITION_EXCHANGE [$$53, $$39]  |PARTITIONED|
+                                                                      -- STREAM_PROJECT  |PARTITIONED|
+                                                                        -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                          -- HYBRID_HASH_JOIN [$$51][$$42]  |PARTITIONED|
+                                                                            -- HASH_PARTITION_EXCHANGE [$$51]  |PARTITIONED|
+                                                                              -- NESTED_LOOP  |PARTITIONED|
+                                                                                -- BROADCAST_EXCHANGE  |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 [$$46]  |PARTITIONED|
-                                                                            -- STREAM_PROJECT  |PARTITIONED|
-                                                                              -- ASSIGN  |PARTITIONED|
-                                                                                -- STREAM_PROJECT  |PARTITIONED|
-                                                                                  -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                                                    -- DATASOURCE_SCAN  |PARTITIONED|
-                                                                                      -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                                                        -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
-                                                    -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                      -- STREAM_PROJECT  |PARTITIONED|
-                                                        -- ASSIGN  |PARTITIONED|
-                                                          -- STREAM_PROJECT  |PARTITIONED|
-                                                            -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                              -- DATASOURCE_SCAN  |PARTITIONED|
-                                                                -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                                  -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                                                                                -- 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|
+                                                                            -- HASH_PARTITION_EXCHANGE [$$42]  |PARTITIONED|
+                                                                              -- STREAM_PROJECT  |PARTITIONED|
+                                                                                -- ASSIGN  |PARTITIONED|
+                                                                                  -- STREAM_PROJECT  |PARTITIONED|
+                                                                                    -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                      -- DATASOURCE_SCAN  |PARTITIONED|
+                                                                                        -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                          -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                                                      -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                        -- STREAM_PROJECT  |PARTITIONED|
+                                                          -- ASSIGN  |PARTITIONED|
+                                                            -- STREAM_PROJECT  |PARTITIONED|
+                                                              -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                -- DATASOURCE_SCAN  |PARTITIONED|
+                                                                  -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                    -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterix-app/src/test/resources/optimizerts/results/udfs/query-ASTERIXDB-1020.plan b/asterix-app/src/test/resources/optimizerts/results/udfs/query-ASTERIXDB-1020.plan
index 73e10b4..7cf5bc4 100644
--- a/asterix-app/src/test/resources/optimizerts/results/udfs/query-ASTERIXDB-1020.plan
+++ b/asterix-app/src/test/resources/optimizerts/results/udfs/query-ASTERIXDB-1020.plan
@@ -1,46 +1,63 @@
 -- DISTRIBUTE_RESULT  |PARTITIONED|
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-    -- NESTED_LOOP  |PARTITIONED|
-      -- BROADCAST_EXCHANGE  |PARTITIONED|
+    -- STREAM_PROJECT  |PARTITIONED|
+      -- ASSIGN  |PARTITIONED|
         -- STREAM_PROJECT  |PARTITIONED|
           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-            -- DATASOURCE_SCAN  |PARTITIONED|
+            -- HYBRID_HASH_JOIN [$$26][$$38]  |PARTITIONED|
               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
-      -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-        -- STREAM_PROJECT  |PARTITIONED|
-          -- ASSIGN  |PARTITIONED|
-            -- STREAM_PROJECT  |PARTITIONED|
-              -- STREAM_SELECT  |PARTITIONED|
-                -- STREAM_PROJECT  |PARTITIONED|
-                  -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                    -- PRE_CLUSTERED_GROUP_BY[$$30]  |PARTITIONED|
-                            {
-                              -- AGGREGATE  |LOCAL|
-                                -- STREAM_SELECT  |LOCAL|
-                                  -- NESTED_TUPLE_SOURCE  |LOCAL|
-                            }
+                -- ASSIGN  |PARTITIONED|
+                  -- STREAM_PROJECT  |PARTITIONED|
+                    -- ASSIGN  |PARTITIONED|
                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                        -- STABLE_SORT [$$30(ASC)]  |PARTITIONED|
-                          -- HASH_PARTITION_EXCHANGE [$$30]  |PARTITIONED|
+                        -- SPLIT  |PARTITIONED|
+                          -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
                             -- STREAM_PROJECT  |PARTITIONED|
                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                -- DATASOURCE_SCAN  |PARTITIONED|
+                                  -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                    -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+              -- HASH_PARTITION_EXCHANGE [$$38]  |PARTITIONED|
+                -- STREAM_PROJECT  |PARTITIONED|
+                  -- STREAM_SELECT  |PARTITIONED|
+                    -- STREAM_PROJECT  |PARTITIONED|
+                      -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                        -- PRE_CLUSTERED_GROUP_BY[$$27, $$36]  |PARTITIONED|
+                                {
+                                  -- AGGREGATE  |LOCAL|
+                                    -- STREAM_SELECT  |LOCAL|
+                                      -- NESTED_TUPLE_SOURCE  |LOCAL|
+                                }
+                          -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                            -- STABLE_SORT [$$27(ASC), $$36(ASC)]  |PARTITIONED|
+                              -- HASH_PARTITION_EXCHANGE [$$27, $$36]  |PARTITIONED|
                                 -- NESTED_LOOP  |PARTITIONED|
                                   -- BROADCAST_EXCHANGE  |PARTITIONED|
-                                    -- STREAM_PROJECT  |PARTITIONED|
-                                      -- ASSIGN  |PARTITIONED|
-                                        -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                          -- DATASOURCE_SCAN  |PARTITIONED|
-                                            -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                              -- ASSIGN  |PARTITIONED|
+                                    -- SPLIT  |PARTITIONED|
+                                      -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                        -- STREAM_PROJECT  |PARTITIONED|
+                                          -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                            -- DATASOURCE_SCAN  |PARTITIONED|
+                                              -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
                                                 -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                    -- ASSIGN  |PARTITIONED|
-                                      -- STREAM_PROJECT  |PARTITIONED|
-                                        -- STREAM_SELECT  |PARTITIONED|
-                                          -- ASSIGN  |PARTITIONED|
+                                    -- STREAM_PROJECT  |PARTITIONED|
+                                      -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                        -- NESTED_LOOP  |PARTITIONED|
+                                          -- BROADCAST_EXCHANGE  |PARTITIONED|
                                             -- STREAM_PROJECT  |PARTITIONED|
-                                              -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                -- DATASOURCE_SCAN  |PARTITIONED|
-                                                  -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                    -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                                              -- ASSIGN  |PARTITIONED|
+                                                -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                  -- DATASOURCE_SCAN  |PARTITIONED|
+                                                    -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                      -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                                          -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                            -- ASSIGN  |PARTITIONED|
+                                              -- STREAM_PROJECT  |PARTITIONED|
+                                                -- STREAM_SELECT  |PARTITIONED|
+                                                  -- ASSIGN  |PARTITIONED|
+                                                    -- STREAM_PROJECT  |PARTITIONED|
+                                                      -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                        -- DATASOURCE_SCAN  |PARTITIONED|
+                                                          -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                            -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git a/asterix-app/src/test/resources/optimizerts/results/udfs/query-ASTERIXDB-1029.plan b/asterix-app/src/test/resources/optimizerts/results/udfs/query-ASTERIXDB-1029.plan
index dd73dc1..2e66169 100644
--- a/asterix-app/src/test/resources/optimizerts/results/udfs/query-ASTERIXDB-1029.plan
+++ b/asterix-app/src/test/resources/optimizerts/results/udfs/query-ASTERIXDB-1029.plan
@@ -6,63 +6,64 @@
           -- NESTED_LOOP  |PARTITIONED|
             -- BROADCAST_EXCHANGE  |PARTITIONED|
               -- STREAM_PROJECT  |PARTITIONED|
-                -- ASSIGN  |PARTITIONED|
+                -- STREAM_SELECT  |PARTITIONED|
                   -- STREAM_PROJECT  |PARTITIONED|
-                    -- STREAM_SELECT  |PARTITIONED|
-                      -- STREAM_PROJECT  |PARTITIONED|
+                    -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                      -- PRE_CLUSTERED_GROUP_BY[$$36, $$37]  |PARTITIONED|
+                              {
+                                -- AGGREGATE  |LOCAL|
+                                  -- STREAM_SELECT  |LOCAL|
+                                    -- NESTED_TUPLE_SOURCE  |LOCAL|
+                              }
                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                          -- PRE_CLUSTERED_GROUP_BY[$$42, $$43, $$44, $$45]  |PARTITIONED|
-                                  {
-                                    -- AGGREGATE  |LOCAL|
-                                      -- STREAM_SELECT  |LOCAL|
-                                        -- NESTED_TUPLE_SOURCE  |LOCAL|
-                                  }
-                            -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                              -- STABLE_SORT [$$42(ASC), $$43(ASC), $$44(ASC), $$45(ASC)]  |PARTITIONED|
-                                -- HASH_PARTITION_EXCHANGE [$$42, $$43, $$44, $$45]  |PARTITIONED|
-                                  -- STREAM_PROJECT  |PARTITIONED|
-                                    -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                          -- STABLE_SORT [$$36(ASC), $$37(ASC)]  |PARTITIONED|
+                            -- HASH_PARTITION_EXCHANGE [$$36, $$37]  |PARTITIONED|
+                              -- STREAM_PROJECT  |PARTITIONED|
+                                -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                  -- NESTED_LOOP  |PARTITIONED|
+                                    -- BROADCAST_EXCHANGE  |PARTITIONED|
                                       -- NESTED_LOOP  |PARTITIONED|
                                         -- BROADCAST_EXCHANGE  |PARTITIONED|
-                                          -- NESTED_LOOP  |PARTITIONED|
-                                            -- BROADCAST_EXCHANGE  |PARTITIONED|
-                                              -- ASSIGN  |PARTITIONED|
-                                                -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                  -- DATASOURCE_SCAN  |PARTITIONED|
-                                                    -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                      -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
-                                            -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                              -- ASSIGN  |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|
+                                        -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                          -- STREAM_PROJECT  |PARTITIONED|
+                                            -- ASSIGN  |PARTITIONED|
+                                              -- STREAM_SELECT  |PARTITIONED|
+                                                -- ASSIGN  |PARTITIONED|
                                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
                                                     -- BTREE_SEARCH  |PARTITIONED|
                                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                        -- STABLE_SORT [$$58(ASC)]  |PARTITIONED|
+                                                        -- STABLE_SORT [$$55(ASC)]  |PARTITIONED|
                                                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
                                                             -- STREAM_PROJECT  |PARTITIONED|
                                                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
                                                                 -- BTREE_SEARCH  |PARTITIONED|
-                                                                  -- STREAM_PROJECT  |PARTITIONED|
-                                                                    -- ASSIGN  |PARTITIONED|
+                                                                  -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                    -- SPLIT  |PARTITIONED|
                                                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                                        -- SPLIT  |PARTITIONED|
-                                                                          -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                                            -- ASSIGN  |PARTITIONED|
-                                                                              -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
-                                        -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                          -- ASSIGN  |PARTITIONED|
-                                            -- STREAM_PROJECT  |PARTITIONED|
-                                              -- STREAM_SELECT  |PARTITIONED|
-                                                -- ASSIGN  |PARTITIONED|
-                                                  -- STREAM_PROJECT  |PARTITIONED|
+                                                                        -- ASSIGN  |PARTITIONED|
+                                                                          -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                                    -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                      -- ASSIGN  |PARTITIONED|
+                                        -- STREAM_PROJECT  |PARTITIONED|
+                                          -- STREAM_SELECT  |PARTITIONED|
+                                            -- ASSIGN  |PARTITIONED|
+                                              -- STREAM_PROJECT  |PARTITIONED|
+                                                -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                  -- BTREE_SEARCH  |PARTITIONED|
                                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                      -- BTREE_SEARCH  |PARTITIONED|
+                                                      -- STABLE_SORT [$$58(ASC)]  |PARTITIONED|
                                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                          -- STABLE_SORT [$$61(ASC)]  |PARTITIONED|
+                                                          -- STREAM_PROJECT  |PARTITIONED|
                                                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                              -- STREAM_PROJECT  |PARTITIONED|
-                                                                -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                                  -- BTREE_SEARCH  |PARTITIONED|
+                                                              -- BTREE_SEARCH  |PARTITIONED|
+                                                                -- STREAM_PROJECT  |PARTITIONED|
+                                                                  -- ASSIGN  |PARTITIONED|
                                                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
                                                                       -- SPLIT  |PARTITIONED|
                                                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
diff --git a/asterix-app/src/test/resources/optimizerts/results/udfs/query-ASTERIXDB-1029_2.plan b/asterix-app/src/test/resources/optimizerts/results/udfs/query-ASTERIXDB-1029_2.plan
index dd73dc1..2e66169 100644
--- a/asterix-app/src/test/resources/optimizerts/results/udfs/query-ASTERIXDB-1029_2.plan
+++ b/asterix-app/src/test/resources/optimizerts/results/udfs/query-ASTERIXDB-1029_2.plan
@@ -6,63 +6,64 @@
           -- NESTED_LOOP  |PARTITIONED|
             -- BROADCAST_EXCHANGE  |PARTITIONED|
               -- STREAM_PROJECT  |PARTITIONED|
-                -- ASSIGN  |PARTITIONED|
+                -- STREAM_SELECT  |PARTITIONED|
                   -- STREAM_PROJECT  |PARTITIONED|
-                    -- STREAM_SELECT  |PARTITIONED|
-                      -- STREAM_PROJECT  |PARTITIONED|
+                    -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                      -- PRE_CLUSTERED_GROUP_BY[$$36, $$37]  |PARTITIONED|
+                              {
+                                -- AGGREGATE  |LOCAL|
+                                  -- STREAM_SELECT  |LOCAL|
+                                    -- NESTED_TUPLE_SOURCE  |LOCAL|
+                              }
                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                          -- PRE_CLUSTERED_GROUP_BY[$$42, $$43, $$44, $$45]  |PARTITIONED|
-                                  {
-                                    -- AGGREGATE  |LOCAL|
-                                      -- STREAM_SELECT  |LOCAL|
-                                        -- NESTED_TUPLE_SOURCE  |LOCAL|
-                                  }
-                            -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                              -- STABLE_SORT [$$42(ASC), $$43(ASC), $$44(ASC), $$45(ASC)]  |PARTITIONED|
-                                -- HASH_PARTITION_EXCHANGE [$$42, $$43, $$44, $$45]  |PARTITIONED|
-                                  -- STREAM_PROJECT  |PARTITIONED|
-                                    -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                          -- STABLE_SORT [$$36(ASC), $$37(ASC)]  |PARTITIONED|
+                            -- HASH_PARTITION_EXCHANGE [$$36, $$37]  |PARTITIONED|
+                              -- STREAM_PROJECT  |PARTITIONED|
+                                -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                  -- NESTED_LOOP  |PARTITIONED|
+                                    -- BROADCAST_EXCHANGE  |PARTITIONED|
                                       -- NESTED_LOOP  |PARTITIONED|
                                         -- BROADCAST_EXCHANGE  |PARTITIONED|
-                                          -- NESTED_LOOP  |PARTITIONED|
-                                            -- BROADCAST_EXCHANGE  |PARTITIONED|
-                                              -- ASSIGN  |PARTITIONED|
-                                                -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                  -- DATASOURCE_SCAN  |PARTITIONED|
-                                                    -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                      -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
-                                            -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                              -- ASSIGN  |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|
+                                        -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                          -- STREAM_PROJECT  |PARTITIONED|
+                                            -- ASSIGN  |PARTITIONED|
+                                              -- STREAM_SELECT  |PARTITIONED|
+                                                -- ASSIGN  |PARTITIONED|
                                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
                                                     -- BTREE_SEARCH  |PARTITIONED|
                                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                        -- STABLE_SORT [$$58(ASC)]  |PARTITIONED|
+                                                        -- STABLE_SORT [$$55(ASC)]  |PARTITIONED|
                                                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
                                                             -- STREAM_PROJECT  |PARTITIONED|
                                                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
                                                                 -- BTREE_SEARCH  |PARTITIONED|
-                                                                  -- STREAM_PROJECT  |PARTITIONED|
-                                                                    -- ASSIGN  |PARTITIONED|
+                                                                  -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                    -- SPLIT  |PARTITIONED|
                                                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                                        -- SPLIT  |PARTITIONED|
-                                                                          -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                                            -- ASSIGN  |PARTITIONED|
-                                                                              -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
-                                        -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                          -- ASSIGN  |PARTITIONED|
-                                            -- STREAM_PROJECT  |PARTITIONED|
-                                              -- STREAM_SELECT  |PARTITIONED|
-                                                -- ASSIGN  |PARTITIONED|
-                                                  -- STREAM_PROJECT  |PARTITIONED|
+                                                                        -- ASSIGN  |PARTITIONED|
+                                                                          -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                                    -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                      -- ASSIGN  |PARTITIONED|
+                                        -- STREAM_PROJECT  |PARTITIONED|
+                                          -- STREAM_SELECT  |PARTITIONED|
+                                            -- ASSIGN  |PARTITIONED|
+                                              -- STREAM_PROJECT  |PARTITIONED|
+                                                -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                  -- BTREE_SEARCH  |PARTITIONED|
                                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                      -- BTREE_SEARCH  |PARTITIONED|
+                                                      -- STABLE_SORT [$$58(ASC)]  |PARTITIONED|
                                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                          -- STABLE_SORT [$$61(ASC)]  |PARTITIONED|
+                                                          -- STREAM_PROJECT  |PARTITIONED|
                                                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                              -- STREAM_PROJECT  |PARTITIONED|
-                                                                -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                                  -- BTREE_SEARCH  |PARTITIONED|
+                                                              -- BTREE_SEARCH  |PARTITIONED|
+                                                                -- STREAM_PROJECT  |PARTITIONED|
+                                                                  -- ASSIGN  |PARTITIONED|
                                                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
                                                                       -- SPLIT  |PARTITIONED|
                                                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
diff --git a/asterix-app/src/test/resources/runtimets/queries/tinysocial/tinysocial-suite/query-ASTERIXDB-1063.23.query.aql b/asterix-app/src/test/resources/runtimets/queries/tinysocial/tinysocial-suite/query-ASTERIXDB-1063.23.query.aql
new file mode 100644
index 0000000..7fe6baa
--- /dev/null
+++ b/asterix-app/src/test/resources/runtimets/queries/tinysocial/tinysocial-suite/query-ASTERIXDB-1063.23.query.aql
@@ -0,0 +1,29 @@
+/*
+ * 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.
+ */
+use dataverse TinySocial;
+
+for $t in dataset TweetMessages
+group by $d:= get-hour($t.send-time) with $t
+return { "hour": $d,
+         "count": count($t),
+         "finer":  for $k in $t
+                   group by $min:= get-minute($k.send-time) with $k
+                   order by $min
+                   return {  "minute": $min, "sum": count($k)}
+}
diff --git a/asterix-app/src/test/resources/runtimets/queries/tpch/nest_aggregate2/nest_aggregate2.1.ddl.aql b/asterix-app/src/test/resources/runtimets/queries/tpch/nest_aggregate2/nest_aggregate2.1.ddl.aql
new file mode 100644
index 0000000..14ccb1b
--- /dev/null
+++ b/asterix-app/src/test/resources/runtimets/queries/tpch/nest_aggregate2/nest_aggregate2.1.ddl.aql
@@ -0,0 +1,88 @@
+/*
+ * 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.
+ */
+/*
+ * Description  : This test case is to verify the fix for issue782
+ * https://code.google.com/p/asterixdb/issues/detail?id=782
+ * Expected Res : SUCCESS
+ * Date         : 2nd Jun 2014
+ */
+
+drop dataverse tpch if exists;
+create dataverse tpch;
+
+use dataverse tpch;
+
+create type OrderType as closed {
+  o_orderkey: int64,
+  o_custkey: int64,
+  o_orderstatus: string,
+  o_totalprice: double,
+  o_orderdate: string,
+  o_orderpriority: string,
+  o_clerk: string,
+  o_shippriority: int64,
+  o_comment: string
+}
+
+create type CustomerType as closed {
+  c_custkey: int64,
+  c_name: string,
+  c_address: string,
+  c_nationkey: int64,
+  c_phone: string,
+  c_acctbal: double,
+  c_mktsegment: string,
+  c_comment: string
+}
+
+create type SupplierType as closed {
+  s_suppkey: int64,
+  s_name: string,
+  s_address: string,
+  s_nationkey: int64,
+  s_phone: string,
+  s_acctbal: double,
+  s_comment: string
+}
+
+create type NationType as closed {
+  n_nationkey: int64,
+  n_name: string,
+  n_regionkey: int64,
+  n_comment: string
+}
+
+create type RegionType as closed {
+  r_regionkey: int64,
+  r_name: string,
+  r_comment: string
+}
+
+create dataset Orders(OrderType)
+  primary key o_orderkey;
+create dataset Supplier(SupplierType)
+  primary key s_suppkey;
+create dataset Region(RegionType)
+  primary key r_regionkey;
+create dataset Nation(NationType)
+  primary key n_nationkey;
+create dataset Customer(CustomerType)
+  primary key c_custkey;
+create dataset SelectedNation(NationType)
+  primary key n_nationkey;
diff --git a/asterix-app/src/test/resources/runtimets/queries/tpch/nest_aggregate2/nest_aggregate2.2.update.aql b/asterix-app/src/test/resources/runtimets/queries/tpch/nest_aggregate2/nest_aggregate2.2.update.aql
new file mode 100644
index 0000000..5faabc5
--- /dev/null
+++ b/asterix-app/src/test/resources/runtimets/queries/tpch/nest_aggregate2/nest_aggregate2.2.update.aql
@@ -0,0 +1,50 @@
+/*
+ * 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.
+ */
+/*
+ * Description  : This test case is to verify the fix for issue782
+ * https://code.google.com/p/asterixdb/issues/detail?id=782
+ * Expected Res : SUCCESS
+ * Date         : 2nd Jun 2014
+ */
+
+use dataverse tpch;
+
+load dataset Orders
+using "org.apache.asterix.external.dataset.adapter.NCFileSystemAdapter"
+(("path"="asterix_nc1://data/tpch0.001/orders.tbl"),("format"="delimited-text"),("delimiter"="|"));
+
+load dataset Supplier
+using "org.apache.asterix.external.dataset.adapter.NCFileSystemAdapter"
+(("path"="asterix_nc1://data/tpch0.001/supplier.tbl"),("format"="delimited-text"),("delimiter"="|"));
+
+load dataset Region
+using "org.apache.asterix.external.dataset.adapter.NCFileSystemAdapter"
+(("path"="asterix_nc1://data/tpch0.001/region.tbl"),("format"="delimited-text"),("delimiter"="|"));
+
+load dataset Nation
+using "org.apache.asterix.external.dataset.adapter.NCFileSystemAdapter"
+(("path"="asterix_nc1://data/tpch0.001/nation.tbl"),("format"="delimited-text"),("delimiter"="|"));
+
+load dataset Customer
+using "org.apache.asterix.external.dataset.adapter.NCFileSystemAdapter"
+(("path"="asterix_nc1://data/tpch0.001/customer.tbl"),("format"="delimited-text"),("delimiter"="|"));
+
+load dataset SelectedNation
+using "org.apache.asterix.external.dataset.adapter.NCFileSystemAdapter"
+(("path"="asterix_nc1://data/tpch0.001/selectednation.tbl"),("format"="delimited-text"),("delimiter"="|"));
diff --git a/asterix-app/src/test/resources/runtimets/queries/tpch/nest_aggregate2/nest_aggregate2.3.query.aql b/asterix-app/src/test/resources/runtimets/queries/tpch/nest_aggregate2/nest_aggregate2.3.query.aql
new file mode 100644
index 0000000..96cebcf
--- /dev/null
+++ b/asterix-app/src/test/resources/runtimets/queries/tpch/nest_aggregate2/nest_aggregate2.3.query.aql
@@ -0,0 +1,45 @@
+/*
+ * 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.
+ */
+/*
+ * Description  : This test case is to verify the fix for issue782
+ * https://code.google.com/p/asterixdb/issues/detail?id=782
+ * Expected Res : SUCCESS
+ * Date         : 2nd Jun 2014
+ */
+
+use dataverse tpch;
+
+for $nation in dataset Nation
+for $sn in dataset SelectedNation
+where $nation.n_nationkey /*+ indexnl */ = $sn.n_nationkey
+order by $nation.n_nationkey
+return {
+  "nation_key": $nation.n_nationkey,
+  "name": $nation.n_name,
+  "aggregates":
+                for $order in dataset Orders
+                for $customer in dataset Customer
+                where $order.o_custkey = $customer.c_custkey
+                and  $customer.c_nationkey = $nation.n_nationkey
+                group by $orderdate := $order.o_orderdate with $order
+                let $sum := sum(for $o in $order return $o.o_totalprice)
+                order by $sum
+                limit 3
+                return $orderdate
+}
diff --git a/asterix-app/src/test/resources/runtimets/queries_sqlpp/quantifiers/query-ASTERIXDB-1005/query-ASTERIXDB-1005.1.ddl.sqlpp b/asterix-app/src/test/resources/runtimets/queries_sqlpp/quantifiers/query-ASTERIXDB-1005/query-ASTERIXDB-1005.1.ddl.sqlpp
new file mode 100644
index 0000000..f7b7de9
--- /dev/null
+++ b/asterix-app/src/test/resources/runtimets/queries_sqlpp/quantifiers/query-ASTERIXDB-1005/query-ASTERIXDB-1005.1.ddl.sqlpp
@@ -0,0 +1,53 @@
+/*
+ * 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.
+ */
+/*
+ * Description     : This test case is to verify the fix for ASTERIXDB-1005
+ * https://issues.apache.org/jira/browse/ASTERIXDB-1005
+ * Expected Result : Success
+ * Date            : 10th January 2016
+ */
+
+drop database deliber if exists;
+create database deliber;
+use deliber;
+
+// Dish served by a restaurant
+create type DishesType as open
+{ name: string, price: double }
+
+// Bank account type
+create type BankAccountType as open{
+ bank_account_number: string,
+ bank_account_routing_number: string
+}
+
+// Restaurant's information
+create type RestaurantsType as open {
+restr_id: int64,
+name: string,
+address: string,
+bank_account: BankAccountType,
+last_bank_transaction_datetime: datetime,
+cuisine: {{ string }},
+dish: {{ DishesType }}
+}
+
+// Creating datasets for Users, Restaurants, and Orders
+create table Restaurants(RestaurantsType)
+primary key restr_id;
diff --git a/asterix-app/src/test/resources/runtimets/queries_sqlpp/quantifiers/query-ASTERIXDB-1005/query-ASTERIXDB-1005.2.update.sqlpp b/asterix-app/src/test/resources/runtimets/queries_sqlpp/quantifiers/query-ASTERIXDB-1005/query-ASTERIXDB-1005.2.update.sqlpp
new file mode 100644
index 0000000..89eff78
--- /dev/null
+++ b/asterix-app/src/test/resources/runtimets/queries_sqlpp/quantifiers/query-ASTERIXDB-1005/query-ASTERIXDB-1005.2.update.sqlpp
@@ -0,0 +1,31 @@
+/*
+ * 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.
+ */
+/*
+ * Description     : This test case is to verify the fix for ASTERIXDB-1005
+ * https://issues.apache.org/jira/browse/ASTERIXDB-1005
+ * Expected Result : Success
+ * Date            : 10th January 2016
+ */
+
+use deliber;
+
+
+load  table Restaurants using
+"org.apache.asterix.external.dataset.adapter.NCFileSystemAdapter"
+(("path"="asterix_nc1://data/restaurants/restaurants.adm"),("format"="adm"));
diff --git a/asterix-app/src/test/resources/runtimets/queries_sqlpp/quantifiers/query-ASTERIXDB-1005/query-ASTERIXDB-1005.3.query.sqlpp b/asterix-app/src/test/resources/runtimets/queries_sqlpp/quantifiers/query-ASTERIXDB-1005/query-ASTERIXDB-1005.3.query.sqlpp
new file mode 100644
index 0000000..a0f3345
--- /dev/null
+++ b/asterix-app/src/test/resources/runtimets/queries_sqlpp/quantifiers/query-ASTERIXDB-1005/query-ASTERIXDB-1005.3.query.sqlpp
@@ -0,0 +1,31 @@
+/*
+ * 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.
+ */
+/*
+ * Description     : This test case is to verify the fix for ASTERIXDB-1005
+ * https://issues.apache.org/jira/browse/ASTERIXDB-1005
+ * Expected Result : Success
+ * Date            : 10th January 2016
+ */
+
+use deliber;
+
+select r.name as name, r.cuisine as cuisines
+from Restaurants as r
+where some c in r.cuisine satisfies c = 'Mexican' or c = 'Italian'
+order by r.name;
diff --git a/asterix-app/src/test/resources/runtimets/queries_sqlpp/tinysocial/tinysocial-suite/query-ASTERIXDB-1063.23.query.sqlpp b/asterix-app/src/test/resources/runtimets/queries_sqlpp/tinysocial/tinysocial-suite/query-ASTERIXDB-1063.23.query.sqlpp
new file mode 100644
index 0000000..f5139e1
--- /dev/null
+++ b/asterix-app/src/test/resources/runtimets/queries_sqlpp/tinysocial/tinysocial-suite/query-ASTERIXDB-1063.23.query.sqlpp
@@ -0,0 +1,30 @@
+/*
+ * 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.
+ */
+use TinySocial;
+
+select h as "hour",
+       count(t) as "count",
+       (
+         select min as "minute", count(k) as "sum"
+         from t as k
+         group by "get-minute"(k."send-time") as min
+         order by min
+       ) as "finer"
+from TweetMessages as t
+group by "get-hour"(t."send-time") as h;
diff --git a/asterix-app/src/test/resources/runtimets/queries_sqlpp/tpch/nest_aggregate2/nest_aggregate2.1.ddl.sqlpp b/asterix-app/src/test/resources/runtimets/queries_sqlpp/tpch/nest_aggregate2/nest_aggregate2.1.ddl.sqlpp
new file mode 100644
index 0000000..3b070de
--- /dev/null
+++ b/asterix-app/src/test/resources/runtimets/queries_sqlpp/tpch/nest_aggregate2/nest_aggregate2.1.ddl.sqlpp
@@ -0,0 +1,94 @@
+/*
+ * 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.
+ */
+/*
+ * Description  : This test case is to verify the fix for issue782
+ * https://code.google.com/p/asterixdb/issues/detail?id=782
+ * Expected Res : SUCCESS
+ * Date         : 2nd Jun 2014
+ */
+
+drop  database tpch if exists;
+create  database tpch;
+
+use tpch;
+
+
+create type tpch.OrderType as
+ closed {
+  o_orderkey : int64,
+  o_custkey : int64,
+  o_orderstatus : string,
+  o_totalprice : double,
+  o_orderdate : string,
+  o_orderpriority : string,
+  o_clerk : string,
+  o_shippriority : int64,
+  o_comment : string
+}
+
+create type tpch.CustomerType as
+ closed {
+  c_custkey : int64,
+  c_name : string,
+  c_address : string,
+  c_nationkey : int64,
+  c_phone : string,
+  c_acctbal : double,
+  c_mktsegment : string,
+  c_comment : string
+}
+
+create type tpch.SupplierType as
+ closed {
+  s_suppkey : int64,
+  s_name : string,
+  s_address : string,
+  s_nationkey : int64,
+  s_phone : string,
+  s_acctbal : double,
+  s_comment : string
+}
+
+create type tpch.NationType as
+ closed {
+  n_nationkey : int64,
+  n_name : string,
+  n_regionkey : int64,
+  n_comment : string
+}
+
+create type tpch.RegionType as
+ closed {
+  r_regionkey : int64,
+  r_name : string,
+  r_comment : string
+}
+
+create  table Orders(OrderType) primary key o_orderkey;
+
+create  table Supplier(SupplierType) primary key s_suppkey;
+
+create  table Region(RegionType) primary key r_regionkey;
+
+create  table Nation(NationType) primary key n_nationkey;
+
+create  table Customer(CustomerType) primary key c_custkey;
+
+create  table SelectedNation(NationType) primary key n_nationkey;
+
diff --git a/asterix-app/src/test/resources/runtimets/queries_sqlpp/tpch/nest_aggregate2/nest_aggregate2.2.update.sqlpp b/asterix-app/src/test/resources/runtimets/queries_sqlpp/tpch/nest_aggregate2/nest_aggregate2.2.update.sqlpp
new file mode 100644
index 0000000..24ff26a
--- /dev/null
+++ b/asterix-app/src/test/resources/runtimets/queries_sqlpp/tpch/nest_aggregate2/nest_aggregate2.2.update.sqlpp
@@ -0,0 +1,40 @@
+/*
+ * 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.
+ */
+/*
+ * Description  : This test case is to verify the fix for issue782
+ * https://code.google.com/p/asterixdb/issues/detail?id=782
+ * Expected Res : SUCCESS
+ * Date         : 2nd Jun 2014
+ */
+
+use tpch;
+
+
+load  table Orders using "org.apache.asterix.external.dataset.adapter.NCFileSystemAdapter" (("path"="asterix_nc1://data/tpch0.001/orders.tbl"),("format"="delimited-text"),("delimiter"="|"));
+
+load  table Supplier using "org.apache.asterix.external.dataset.adapter.NCFileSystemAdapter" (("path"="asterix_nc1://data/tpch0.001/supplier.tbl"),("format"="delimited-text"),("delimiter"="|"));
+
+load  table Region using "org.apache.asterix.external.dataset.adapter.NCFileSystemAdapter" (("path"="asterix_nc1://data/tpch0.001/region.tbl"),("format"="delimited-text"),("delimiter"="|"));
+
+load  table Nation using "org.apache.asterix.external.dataset.adapter.NCFileSystemAdapter" (("path"="asterix_nc1://data/tpch0.001/nation.tbl"),("format"="delimited-text"),("delimiter"="|"));
+
+load  table Customer using "org.apache.asterix.external.dataset.adapter.NCFileSystemAdapter" (("path"="asterix_nc1://data/tpch0.001/customer.tbl"),("format"="delimited-text"),("delimiter"="|"));
+
+load  table SelectedNation using "org.apache.asterix.external.dataset.adapter.NCFileSystemAdapter" (("path"="asterix_nc1://data/tpch0.001/selectednation.tbl"),("format"="delimited-text"),("delimiter"="|"));
+
diff --git a/asterix-app/src/test/resources/runtimets/queries_sqlpp/tpch/nest_aggregate2/nest_aggregate2.3.query.sqlpp b/asterix-app/src/test/resources/runtimets/queries_sqlpp/tpch/nest_aggregate2/nest_aggregate2.3.query.sqlpp
new file mode 100644
index 0000000..1aa687c
--- /dev/null
+++ b/asterix-app/src/test/resources/runtimets/queries_sqlpp/tpch/nest_aggregate2/nest_aggregate2.3.query.sqlpp
@@ -0,0 +1,46 @@
+/*
+ * 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.
+ */
+/*
+ * Description  : This test case is to verify the fix for issue782
+ * https://code.google.com/p/asterixdb/issues/detail?id=782
+ * Expected Res : SUCCESS
+ * Date         : 2nd Jun 2014
+ */
+
+use tpch;
+
+
+select element {'nation_key':nation.n_nationkey,'name':nation.n_name,'aggregates':(
+        select element orderdate
+        from  Orders as orders,
+              Customer as customer
+        where ((orders.o_custkey = customer.c_custkey) and (customer.c_nationkey = nation.n_nationkey))
+        group by orders.o_orderdate as orderdate
+        with  sum as tpch.sum((
+              select element o.o_totalprice
+              from  orders as o
+          ))
+        order by sum
+        limit 3
+    )}
+from  Nation as nation,
+      SelectedNation as sn
+where (nation.n_nationkey /*+ indexnl */ = sn.n_nationkey)
+order by nation.n_nationkey
+;
diff --git a/asterix-app/src/test/resources/runtimets/results/quantifiers/query-ASTERIXDB-1005/query-ASTERIXDB-1005.1.adm b/asterix-app/src/test/resources/runtimets/results/quantifiers/query-ASTERIXDB-1005/query-ASTERIXDB-1005.1.adm
new file mode 100644
index 0000000..fbf67d7
--- /dev/null
+++ b/asterix-app/src/test/resources/runtimets/results/quantifiers/query-ASTERIXDB-1005/query-ASTERIXDB-1005.1.adm
@@ -0,0 +1,15 @@
+{ "name": "Afo Seafood", "cuisines": {{ "American", "Italian" }} }
+{ "name": "Aig craspe", "cuisines": {{ "Italian" }} }
+{ "name": "Ano Argio", "cuisines": {{ "American", "Italian" }} }
+{ "name": "Cit Spicy", "cuisines": {{ "Italian" }} }
+{ "name": "Dan Urban Plates", "cuisines": {{ "Asian", "Indian", "Mexican" }} }
+{ "name": "Gar Chiden", "cuisines": {{ "Italian" }} }
+{ "name": "Ith Javie", "cuisines": {{ "Italian" }} }
+{ "name": "Ken Fish Grill", "cuisines": {{ "Italian", "Mexican" }} }
+{ "name": "Ley Cucina", "cuisines": {{ "Italian" }} }
+{ "name": "Lly taik", "cuisines": {{ "Italian" }} }
+{ "name": "Nor Kingchops", "cuisines": {{ "Italian" }} }
+{ "name": "Nye Boilin", "cuisines": {{ "Italian" }} }
+{ "name": "Pat Urban Seoul", "cuisines": {{ "American", "Mexican" }} }
+{ "name": "Rno Fukad", "cuisines": {{ "Italian" }} }
+{ "name": "Sar Tang 190", "cuisines": {{ "French", "Greek", "Italian" }} }
\ No newline at end of file
diff --git a/asterix-app/src/test/resources/runtimets/results/temporal/overlap_bins_gby_3/overlap_bins_gby_3.1.adm b/asterix-app/src/test/resources/runtimets/results/temporal/overlap_bins_gby_3/overlap_bins_gby_3.1.adm
index 8e166b9..c1ffd9b 100644
--- a/asterix-app/src/test/resources/runtimets/results/temporal/overlap_bins_gby_3/overlap_bins_gby_3.1.adm
+++ b/asterix-app/src/test/resources/runtimets/results/temporal/overlap_bins_gby_3/overlap_bins_gby_3.1.adm
@@ -1,42 +1,42 @@
-{ "timebin": interval-time("10:27:00.000Z, 10:28:00.000Z"), "subgroups": [ { "subgid": null, "item_count": 0 }, { "subgid": "Email", "item_count": 2 }, { "subgid": "Facebook", "item_count": 2 } ] } 
-{ "timebin": interval-time("10:28:00.000Z, 10:29:00.000Z"), "subgroups": [ { "subgid": null, "item_count": 0 }, { "subgid": "Facebook", "item_count": 1 } ] }
-{ "timebin": interval-time("10:29:00.000Z, 10:30:00.000Z"), "subgroups": [ { "subgid": null, "item_count": 0 }, { "subgid": "Email", "item_count": 1 }, { "subgid": "Facebook", "item_count": 2 } ] }
-{ "timebin": interval-time("10:30:00.000Z, 10:31:00.000Z"), "subgroups": [ { "subgid": null, "item_count": 0 } ] }
-{ "timebin": interval-time("10:31:00.000Z, 10:32:00.000Z"), "subgroups": [ { "subgid": null, "item_count": 0 } ] }
-{ "timebin": interval-time("10:32:00.000Z, 10:33:00.000Z"), "subgroups": [ { "subgid": null, "item_count": 0 } ] }
-{ "timebin": interval-time("10:33:00.000Z, 10:34:00.000Z"), "subgroups": [ { "subgid": null, "item_count": 0 } ] }
-{ "timebin": interval-time("10:34:00.000Z, 10:35:00.000Z"), "subgroups": [ { "subgid": null, "item_count": 0 } ] }
-{ "timebin": interval-time("10:35:00.000Z, 10:36:00.000Z"), "subgroups": [ { "subgid": null, "item_count": 0 } ] }
-{ "timebin": interval-time("10:36:00.000Z, 10:37:00.000Z"), "subgroups": [ { "subgid": null, "item_count": 0 } ] }
-{ "timebin": interval-time("10:37:00.000Z, 10:38:00.000Z"), "subgroups": [ { "subgid": null, "item_count": 0 } ] }
-{ "timebin": interval-time("10:38:00.000Z, 10:39:00.000Z"), "subgroups": [ { "subgid": null, "item_count": 0 } ] }
-{ "timebin": interval-time("10:39:00.000Z, 10:40:00.000Z"), "subgroups": [ { "subgid": null, "item_count": 0 } ] }
-{ "timebin": interval-time("10:40:00.000Z, 10:41:00.000Z"), "subgroups": [ { "subgid": null, "item_count": 0 } ] }
-{ "timebin": interval-time("10:41:00.000Z, 10:42:00.000Z"), "subgroups": [ { "subgid": null, "item_count": 0 } ] }
-{ "timebin": interval-time("10:42:00.000Z, 10:43:00.000Z"), "subgroups": [ { "subgid": null, "item_count": 0 } ] }
-{ "timebin": interval-time("10:43:00.000Z, 10:44:00.000Z"), "subgroups": [ { "subgid": null, "item_count": 0 } ] }
-{ "timebin": interval-time("10:44:00.000Z, 10:45:00.000Z"), "subgroups": [ { "subgid": null, "item_count": 0 } ] }
-{ "timebin": interval-time("10:45:00.000Z, 10:46:00.000Z"), "subgroups": [ { "subgid": null, "item_count": 0 } ] }
-{ "timebin": interval-time("10:46:00.000Z, 10:47:00.000Z"), "subgroups": [ { "subgid": null, "item_count": 0 } ] }
-{ "timebin": interval-time("10:47:00.000Z, 10:48:00.000Z"), "subgroups": [ { "subgid": null, "item_count": 0 } ] }
-{ "timebin": interval-time("10:48:00.000Z, 10:49:00.000Z"), "subgroups": [ { "subgid": null, "item_count": 0 } ] }
-{ "timebin": interval-time("10:49:00.000Z, 10:50:00.000Z"), "subgroups": [ { "subgid": null, "item_count": 0 } ] }
-{ "timebin": interval-time("10:50:00.000Z, 10:51:00.000Z"), "subgroups": [ { "subgid": null, "item_count": 0 } ] }
-{ "timebin": interval-time("10:51:00.000Z, 10:52:00.000Z"), "subgroups": [ { "subgid": null, "item_count": 0 } ] }
-{ "timebin": interval-time("10:52:00.000Z, 10:53:00.000Z"), "subgroups": [ { "subgid": null, "item_count": 0 } ] }
-{ "timebin": interval-time("10:53:00.000Z, 10:54:00.000Z"), "subgroups": [ { "subgid": null, "item_count": 0 } ] }
-{ "timebin": interval-time("10:54:00.000Z, 10:55:00.000Z"), "subgroups": [ { "subgid": null, "item_count": 0 } ] }
-{ "timebin": interval-time("10:55:00.000Z, 10:56:00.000Z"), "subgroups": [ { "subgid": null, "item_count": 0 } ] }
-{ "timebin": interval-time("10:56:00.000Z, 10:57:00.000Z"), "subgroups": [ { "subgid": null, "item_count": 0 } ] }
-{ "timebin": interval-time("10:57:00.000Z, 10:58:00.000Z"), "subgroups": [ { "subgid": null, "item_count": 0 } ] }
-{ "timebin": interval-time("10:58:00.000Z, 10:59:00.000Z"), "subgroups": [ { "subgid": null, "item_count": 0 } ] }
-{ "timebin": interval-time("10:59:00.000Z, 11:00:00.000Z"), "subgroups": [ { "subgid": null, "item_count": 0 } ] }
-{ "timebin": interval-time("11:00:00.000Z, 11:01:00.000Z"), "subgroups": [ { "subgid": null, "item_count": 0 } ] }
-{ "timebin": interval-time("11:01:00.000Z, 11:02:00.000Z"), "subgroups": [ { "subgid": null, "item_count": 0 } ] }
-{ "timebin": interval-time("11:02:00.000Z, 11:03:00.000Z"), "subgroups": [ { "subgid": null, "item_count": 0 } ] }
-{ "timebin": interval-time("11:03:00.000Z, 11:04:00.000Z"), "subgroups": [ { "subgid": null, "item_count": 0 } ] }
-{ "timebin": interval-time("11:04:00.000Z, 11:05:00.000Z"), "subgroups": [ { "subgid": null, "item_count": 0 } ] }
-{ "timebin": interval-time("11:05:00.000Z, 11:06:00.000Z"), "subgroups": [ { "subgid": null, "item_count": 0 } ] }
-{ "timebin": interval-time("11:06:00.000Z, 11:07:00.000Z"), "subgroups": [ { "subgid": null, "item_count": 0 } ] }
-{ "timebin": interval-time("11:07:00.000Z, 11:08:00.000Z"), "subgroups": [ { "subgid": null, "item_count": 0 }, { "subgid": "Email", "item_count": 2 } ] }
-{ "timebin": interval-time("11:08:00.000Z, 11:09:00.000Z"), "subgroups": [ { "subgid": null, "item_count": 0 } ] }
+{ "timebin": interval-time("10:27:00.000Z, 10:28:00.000Z"), "subgroups": [ { "subgid": "Email", "item_count": 2 }, { "subgid": "Facebook", "item_count": 2 } ] }
+{ "timebin": interval-time("10:28:00.000Z, 10:29:00.000Z"), "subgroups": [ { "subgid": "Facebook", "item_count": 1 } ] }
+{ "timebin": interval-time("10:29:00.000Z, 10:30:00.000Z"), "subgroups": [ { "subgid": "Email", "item_count": 1 }, { "subgid": "Facebook", "item_count": 2 } ] }
+{ "timebin": interval-time("10:30:00.000Z, 10:31:00.000Z"), "subgroups": [  ] }
+{ "timebin": interval-time("10:31:00.000Z, 10:32:00.000Z"), "subgroups": [  ] }
+{ "timebin": interval-time("10:32:00.000Z, 10:33:00.000Z"), "subgroups": [  ] }
+{ "timebin": interval-time("10:33:00.000Z, 10:34:00.000Z"), "subgroups": [  ] }
+{ "timebin": interval-time("10:34:00.000Z, 10:35:00.000Z"), "subgroups": [  ] }
+{ "timebin": interval-time("10:35:00.000Z, 10:36:00.000Z"), "subgroups": [  ] }
+{ "timebin": interval-time("10:36:00.000Z, 10:37:00.000Z"), "subgroups": [  ] }
+{ "timebin": interval-time("10:37:00.000Z, 10:38:00.000Z"), "subgroups": [  ] }
+{ "timebin": interval-time("10:38:00.000Z, 10:39:00.000Z"), "subgroups": [  ] }
+{ "timebin": interval-time("10:39:00.000Z, 10:40:00.000Z"), "subgroups": [  ] }
+{ "timebin": interval-time("10:40:00.000Z, 10:41:00.000Z"), "subgroups": [  ] }
+{ "timebin": interval-time("10:41:00.000Z, 10:42:00.000Z"), "subgroups": [  ] }
+{ "timebin": interval-time("10:42:00.000Z, 10:43:00.000Z"), "subgroups": [  ] }
+{ "timebin": interval-time("10:43:00.000Z, 10:44:00.000Z"), "subgroups": [  ] }
+{ "timebin": interval-time("10:44:00.000Z, 10:45:00.000Z"), "subgroups": [  ] }
+{ "timebin": interval-time("10:45:00.000Z, 10:46:00.000Z"), "subgroups": [  ] }
+{ "timebin": interval-time("10:46:00.000Z, 10:47:00.000Z"), "subgroups": [  ] }
+{ "timebin": interval-time("10:47:00.000Z, 10:48:00.000Z"), "subgroups": [  ] }
+{ "timebin": interval-time("10:48:00.000Z, 10:49:00.000Z"), "subgroups": [  ] }
+{ "timebin": interval-time("10:49:00.000Z, 10:50:00.000Z"), "subgroups": [  ] }
+{ "timebin": interval-time("10:50:00.000Z, 10:51:00.000Z"), "subgroups": [  ] }
+{ "timebin": interval-time("10:51:00.000Z, 10:52:00.000Z"), "subgroups": [  ] }
+{ "timebin": interval-time("10:52:00.000Z, 10:53:00.000Z"), "subgroups": [  ] }
+{ "timebin": interval-time("10:53:00.000Z, 10:54:00.000Z"), "subgroups": [  ] }
+{ "timebin": interval-time("10:54:00.000Z, 10:55:00.000Z"), "subgroups": [  ] }
+{ "timebin": interval-time("10:55:00.000Z, 10:56:00.000Z"), "subgroups": [  ] }
+{ "timebin": interval-time("10:56:00.000Z, 10:57:00.000Z"), "subgroups": [  ] }
+{ "timebin": interval-time("10:57:00.000Z, 10:58:00.000Z"), "subgroups": [  ] }
+{ "timebin": interval-time("10:58:00.000Z, 10:59:00.000Z"), "subgroups": [  ] }
+{ "timebin": interval-time("10:59:00.000Z, 11:00:00.000Z"), "subgroups": [  ] }
+{ "timebin": interval-time("11:00:00.000Z, 11:01:00.000Z"), "subgroups": [  ] }
+{ "timebin": interval-time("11:01:00.000Z, 11:02:00.000Z"), "subgroups": [  ] }
+{ "timebin": interval-time("11:02:00.000Z, 11:03:00.000Z"), "subgroups": [  ] }
+{ "timebin": interval-time("11:03:00.000Z, 11:04:00.000Z"), "subgroups": [  ] }
+{ "timebin": interval-time("11:04:00.000Z, 11:05:00.000Z"), "subgroups": [  ] }
+{ "timebin": interval-time("11:05:00.000Z, 11:06:00.000Z"), "subgroups": [  ] }
+{ "timebin": interval-time("11:06:00.000Z, 11:07:00.000Z"), "subgroups": [  ] }
+{ "timebin": interval-time("11:07:00.000Z, 11:08:00.000Z"), "subgroups": [ { "subgid": "Email", "item_count": 2 } ] }
+{ "timebin": interval-time("11:08:00.000Z, 11:09:00.000Z"), "subgroups": [  ] }
diff --git a/asterix-app/src/test/resources/runtimets/results/tinysocial/tinysocial-suite/tinysocial-suite.23.adm b/asterix-app/src/test/resources/runtimets/results/tinysocial/tinysocial-suite/tinysocial-suite.23.adm
new file mode 100644
index 0000000..e073ee2
--- /dev/null
+++ b/asterix-app/src/test/resources/runtimets/results/tinysocial/tinysocial-suite/tinysocial-suite.23.adm
@@ -0,0 +1 @@
+{ "hour": 10, "count": 12, "finer": [ { "minute": 10, "sum": 12 } ] }
diff --git a/asterix-app/src/test/resources/runtimets/results/tpch/nest_aggregate2/nest_aggregate2.1.adm b/asterix-app/src/test/resources/runtimets/results/tpch/nest_aggregate2/nest_aggregate2.1.adm
new file mode 100644
index 0000000..3834939
--- /dev/null
+++ b/asterix-app/src/test/resources/runtimets/results/tpch/nest_aggregate2/nest_aggregate2.1.adm
@@ -0,0 +1,11 @@
+{ "nation_key": 0, "name": "ALGERIA", "aggregates": [ "1994-05-27", "1994-05-08", "1993-08-27" ] }
+{ "nation_key": 1, "name": "ARGENTINA", "aggregates": [ "1997-08-14", "1997-11-26", "1998-04-20" ] }
+{ "nation_key": 2, "name": "BRAZIL", "aggregates": [ "1993-03-05", "1994-08-31", "1997-05-04" ] }
+{ "nation_key": 3, "name": "CANADA", "aggregates": [ "1992-02-22", "1992-11-28", "1995-02-17" ] }
+{ "nation_key": 4, "name": "EGYPT", "aggregates": [ "1998-04-19", "1996-03-12", "1997-07-25" ] }
+{ "nation_key": 19, "name": "ROMANIA", "aggregates": [ "1994-07-05", "1994-11-17", "1997-02-07" ] }
+{ "nation_key": 20, "name": "SAUDI ARABIA", "aggregates": [ "1994-04-30", "1992-05-10", "1994-01-31" ] }
+{ "nation_key": 21, "name": "VIETNAM", "aggregates": [ "1994-02-17", "1995-08-05", "1994-06-01" ] }
+{ "nation_key": 22, "name": "RUSSIA", "aggregates": [ "1993-11-16", "1996-01-11", "1995-07-15" ] }
+{ "nation_key": 23, "name": "UNITED KINGDOM", "aggregates": [ "1997-12-18", "1995-05-26", "1997-05-13" ] }
+{ "nation_key": 24, "name": "UNITED STATES", "aggregates": [  ] }
diff --git a/asterix-app/src/test/resources/runtimets/results_parser_sqlpp/tinysocial/tinysocial-suite/query-ASTERIXDB-1263.23.ast b/asterix-app/src/test/resources/runtimets/results_parser_sqlpp/tinysocial/tinysocial-suite/query-ASTERIXDB-1263.23.ast
new file mode 100644
index 0000000..59998f2
--- /dev/null
+++ b/asterix-app/src/test/resources/runtimets/results_parser_sqlpp/tinysocial/tinysocial-suite/query-ASTERIXDB-1263.23.ast
@@ -0,0 +1,61 @@
+DataverseUse TinySocial
+Query:
+SELECT [
+Variable [ Name=h ]
+hour
+FunctionCall TinySocial.count@1[
+  Variable [ Name=t ]
+]
+count
+(
+  SELECT [
+  Variable [ Name=min ]
+  minute
+  FunctionCall TinySocial.count@1[
+    Variable [ Name=k ]
+  ]
+  sum
+  ]
+  FROM [    Variable [ Name=t ]
+    AS
+    Variable [ Name=k ]
+  ]
+  Groupby
+    Variable [ Name=min ]
+    :=
+    FunctionCall TinySocial.get-minute@1[
+      FieldAccessor [
+        Variable [ Name=k ]
+        Field=send-time
+      ]
+    ]
+    With
+    Variable [ Name=k ]
+    Variable [ Name=t ]
+    Variable [ Name=h ]
+
+  Orderby
+    Variable [ Name=min ]
+    ASC
+
+)
+finer
+]
+FROM [  FunctionCall Metadata.dataset@1[
+    LiteralExpr [STRING] [TweetMessages]
+  ]
+  AS
+  Variable [ Name=t ]
+]
+Groupby
+  Variable [ Name=h ]
+  :=
+  FunctionCall TinySocial.get-hour@1[
+    FieldAccessor [
+      Variable [ Name=t ]
+      Field=send-time
+    ]
+  ]
+  With
+  Variable [ Name=t ]
+
diff --git a/asterix-app/src/test/resources/runtimets/testsuite.xml b/asterix-app/src/test/resources/runtimets/testsuite.xml
index a20dc15..5d55f2d 100644
--- a/asterix-app/src/test/resources/runtimets/testsuite.xml
+++ b/asterix-app/src/test/resources/runtimets/testsuite.xml
@@ -5220,6 +5220,11 @@
             </compilation-unit>
         </test-case>
         <test-case FilePath="tpch">
+            <compilation-unit name="nest_aggregate2">
+                <output-dir compare="Text">nest_aggregate2</output-dir>
+            </compilation-unit>
+        </test-case>
+        <test-case FilePath="tpch">
             <compilation-unit name="query-issue638">
                 <output-dir compare="Text">query-issue638</output-dir>
             </compilation-unit>
diff --git a/asterix-app/src/test/resources/runtimets/testsuite_sqlpp.xml b/asterix-app/src/test/resources/runtimets/testsuite_sqlpp.xml
index 58d9323..d56cdad 100644
--- a/asterix-app/src/test/resources/runtimets/testsuite_sqlpp.xml
+++ b/asterix-app/src/test/resources/runtimets/testsuite_sqlpp.xml
@@ -4077,6 +4077,11 @@
                 <output-dir compare="Text">everysat_01</output-dir>
             </compilation-unit>
         </test-case>
+        <test-case FilePath="quantifiers">
+            <compilation-unit name="query-ASTERIXDB-1005">
+                <output-dir compare="Text">query-ASTERIXDB-1005</output-dir>
+            </compilation-unit>
+        </test-case>
         <!--
         <test-case FilePath="quantifiers">
           <compilation-unit name="everysat_02">
@@ -5047,6 +5052,11 @@
             </compilation-unit>
         </test-case>
         <test-case FilePath="tpch">
+            <compilation-unit name="nest_aggregate2">
+                <output-dir compare="Text">nest_aggregate2</output-dir>
+            </compilation-unit>
+        </test-case>
+        <test-case FilePath="tpch">
             <compilation-unit name="query-issue638">
                 <output-dir compare="Text">query-issue638</output-dir>
             </compilation-unit>
diff --git a/asterix-metadata/src/main/java/org/apache/asterix/metadata/feeds/FeedMetadataUtil.java b/asterix-metadata/src/main/java/org/apache/asterix/metadata/feeds/FeedMetadataUtil.java
index 5b5f19f..769b883 100644
--- a/asterix-metadata/src/main/java/org/apache/asterix/metadata/feeds/FeedMetadataUtil.java
+++ b/asterix-metadata/src/main/java/org/apache/asterix/metadata/feeds/FeedMetadataUtil.java
@@ -363,7 +363,7 @@
         spec.getConnectorMap().remove(connDesc.getConnectorId());
         connectorOpMap.remove(connDesc.getConnectorId());
 
-        ITuplePartitionComputerFactory tpcf = new RandomPartitionComputerFactory(requiredCardinality);
+        ITuplePartitionComputerFactory tpcf = new RandomPartitionComputerFactory();
         MToNPartitioningConnectorDescriptor newConnector = new MToNPartitioningConnectorDescriptor(spec, tpcf);
         spec.getConnectorMap().put(newConnector.getConnectorId(), newConnector);
         spec.connect(newConnector, sourceOp, 0, targetOp, 0);