[ASTERIXDB-3546][COMP] Use actual distinct estimate from sample if table size is small

Details:

When the number of distincts obtained from the sample is small, then
we do not need to call the estimator.
Also refactored some code.

Ext-ref: MB-64886


Change-Id: I64cf90fb32fc5d1d2353352fee5240949bc96be9
Reviewed-on: https://asterix-gerrit.ics.uci.edu/c/asterixdb/+/19311
Tested-by: Vijay Sarathy <vijay.sarathy@couchbase.com>
Integration-Tests: Jenkins <jenkins@fulliautomatix.ics.uci.edu>
Reviewed-by: Vijay Sarathy <vijay.sarathy@couchbase.com>
Reviewed-by: <murali.krishna@couchbase.com>
diff --git a/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/cbo/Stats.java b/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/cbo/Stats.java
index 66f0ad5..1cc643a 100644
--- a/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/cbo/Stats.java
+++ b/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/cbo/Stats.java
@@ -195,8 +195,28 @@
             }
 
             double estDistinctCardinalityFromSample = findPredicateCardinality(result, true);
-            double numDistincts = distinctEstimator2(estDistinctCardinalityFromSample, index);
-            return 1.0 / numDistincts; // this is the expected selectivity for joins.
+            if (estDistinctCardinalityFromSample == 0) {
+                estDistinctCardinalityFromSample = 1; // just in case
+            }
+            Index.SampleIndexDetails details = (Index.SampleIndexDetails) index.getIndexDetails();
+            double numDistincts;
+            // if the table is smaller than the sample size, there is no need to use the estimator
+            //                                            getSampleCardinalityTarget() equals 1063 or 4252 or 17008
+            if (details.getSourceCardinality() <= details.getSampleCardinalityTarget()) {
+                numDistincts = estDistinctCardinalityFromSample;
+            } else { // when the number of distincts is smaller than approx 25% of the sample size, then we do not
+                         // then we do not need to call the estimator. This is a good heuristic. This was obtained by looking at the graph
+                     // of d = D ( 1 - e^(-getSampleCardinalityTarget/D) ; d = estDistinctCardinalityFromSample; D = actual number of distincts
+                if (estDistinctCardinalityFromSample <= 0.25 * details.getSampleCardinalityTarget()) {
+                    numDistincts = estDistinctCardinalityFromSample;
+                } else {
+                    numDistincts = secondDistinctEstimator(estDistinctCardinalityFromSample, index);
+                }
+            }
+            if (numDistincts > details.getSourceCardinality()) {
+                numDistincts = details.getSourceCardinality(); // cannot exceed table cardinality
+            }
+            return 1.0 / numDistincts; // this is the expected selectivity for joins for Fk-PK and Fk-Fk joins
         }
     }
 
@@ -424,6 +444,17 @@
         }
     }
 
+    protected void issueWarning(double sampleCard, DataSourceScanOperator scanOp) {
+        if (sampleCard == 0) {
+            sampleCard = 1;
+            IWarningCollector warningCollector = optCtx.getWarningCollector();
+            if (warningCollector.shouldWarn()) {
+                warningCollector.warn(Warning.of(scanOp.getSourceLocation(),
+                        org.apache.asterix.common.exceptions.ErrorCode.SAMPLE_HAS_ZERO_ROWS));
+            }
+        }
+    }
+
     protected double findSelectivityForThisPredicate(SelectOperator selOp, AbstractFunctionCallExpression exp,
             boolean arrayIndex) throws AlgebricksException {
         // replace the SelOp.condition with the new exp and replace it at the end
@@ -444,14 +475,7 @@
         Index.SampleIndexDetails idxDetails = (Index.SampleIndexDetails) index.getIndexDetails();
         double origDatasetCard = idxDetails.getSourceCardinality();
         double sampleCard = Math.min(idxDetails.getSampleCardinalityTarget(), origDatasetCard);
-        if (sampleCard == 0) {
-            sampleCard = 1;
-            IWarningCollector warningCollector = optCtx.getWarningCollector();
-            if (warningCollector.shouldWarn()) {
-                warningCollector.warn(Warning.of(scanOp.getSourceLocation(),
-                        org.apache.asterix.common.exceptions.ErrorCode.SAMPLE_HAS_ZERO_ROWS));
-            }
-        }
+        issueWarning(sampleCard, scanOp);
 
         // replace the dataScanSourceOperator with the sampling source
         SampleDataSource sampledatasource = joinEnum.getSampleDataSource(scanOp);
@@ -655,8 +679,41 @@
         }
         return index;
     }
-    // plan we need to generate in this routine.
 
+    // creates assign [$$79] <- [{"$1": $$73, "$2": $$74, "$3": $$75, "$4": $$76, "$5": $$77, "$6": $$78}] and calls sampling query
+    protected List<List<IAObject>> helperFunction(IOptimizationContext newCtx, AggregateOperator newAggOp)
+            throws AlgebricksException {
+
+        Mutable<ILogicalOperator> newAggOpRef = new MutableObject<>(newAggOp);
+        OperatorPropertiesUtil.typeOpRec(newAggOpRef, newCtx); // is this really needed??
+
+        List<MutableObject> arr = createMutableObjectArray(newAggOp.getVariables());
+        AbstractFunctionCallExpression f = new ScalarFunctionCallExpression(
+                FunctionUtil.getFunctionInfo(BuiltinFunctions.OPEN_RECORD_CONSTRUCTOR));
+        for (int i = 0; i < arr.size(); i++) {
+            f.getArguments().add(arr.get(i));
+        }
+
+        LogicalVariable newVar = newCtx.newVar();
+        AssignOperator assignOp = new AssignOperator(newVar, new MutableObject<>(f));
+        assignOp.getInputs().add(new MutableObject<>(newAggOp));
+        ProjectOperator pOp = new ProjectOperator(newVar);
+        pOp.getInputs().add(new MutableObject<>(assignOp));
+
+        Mutable<ILogicalOperator> newpOpRef = new MutableObject<>(pOp);
+
+        OperatorPropertiesUtil.typeOpRec(newpOpRef, newCtx);
+
+        if (LOGGER.isTraceEnabled()) {
+            String viewInPlan = new ALogicalPlanImpl(newpOpRef).toString(); //useful when debugging
+            LOGGER.trace("viewInPlan");
+            LOGGER.trace(viewInPlan);
+        }
+        LOGGER.info("*** calling sample query***");
+        return AnalysisUtil.runQuery(newpOpRef, Arrays.asList(newVar), newCtx, IRuleSetFactory.RuleSetKind.SAMPLING);
+    }
+
+    // plan we need to generate in this routine.
     //  project ([$$36])                                 add here
     //    assign [$$36] <- [{"$1": $$39}]                add here
     //      aggregate [$$39] <- [agg-sql-count($$34)]    add here
@@ -688,14 +745,7 @@
         Index.SampleIndexDetails idxDetails = (Index.SampleIndexDetails) index.getIndexDetails();
         double origDatasetCard = idxDetails.getSourceCardinality();
         double sampleCard = Math.min(idxDetails.getSampleCardinalityTarget(), origDatasetCard);
-        if (sampleCard == 0) {
-            sampleCard = 1;
-            IWarningCollector warningCollector = optCtx.getWarningCollector();
-            if (warningCollector.shouldWarn()) {
-                warningCollector.warn(Warning.of(scanOp.getSourceLocation(),
-                        org.apache.asterix.common.exceptions.ErrorCode.SAMPLE_HAS_ZERO_ROWS));
-            }
-        }
+        issueWarning(sampleCard, scanOp);
 
         // replace the dataScanSourceOperator with the sampling source
         SampleDataSource sampledatasource = joinEnum.getSampleDataSource(scanOp);
@@ -740,35 +790,8 @@
         AggregateOperator newAggOp = new AggregateOperator(aggVarList, aggExprList);
         newAggOp.getInputs().add(new MutableObject<>(distOp));
 
-        // now add assign [$$36] <- [{"$1": $$39}]   on top of newAggOp
-        Mutable<ILogicalOperator> newAggOpRef = new MutableObject<>(newAggOp);
-        OperatorPropertiesUtil.typeOpRec(newAggOpRef, newCtx); // is this really needed??
-
-        List<MutableObject> arr = createMutableObjectArray(newAggOp.getVariables());
-        AbstractFunctionCallExpression f = new ScalarFunctionCallExpression(
-                FunctionUtil.getFunctionInfo(BuiltinFunctions.OPEN_RECORD_CONSTRUCTOR));
-        for (int i = 0; i < arr.size(); i++) {
-            f.getArguments().add(arr.get(i));
-        }
-
-        LogicalVariable newVar = newCtx.newVar();
-        AssignOperator assignOp = new AssignOperator(newVar, new MutableObject<>(f));
-        assignOp.getInputs().add(new MutableObject<>(newAggOp));
-        ProjectOperator pOp = new ProjectOperator(newVar);
-        pOp.getInputs().add(new MutableObject<>(assignOp));
-
-        Mutable<ILogicalOperator> newpOpRef = new MutableObject<>(pOp);
-
-        OperatorPropertiesUtil.typeOpRec(newpOpRef, newCtx);
-
-        LOGGER.info("***returning from sample query***");
-
-        if (LOGGER.isTraceEnabled()) {
-            String viewInPlan = new ALogicalPlanImpl(newpOpRef).toString(); //useful when debugging
-            LOGGER.trace("viewInPlan");
-            LOGGER.trace(viewInPlan);
-        }
-        return AnalysisUtil.runQuery(newpOpRef, Arrays.asList(newVar), newCtx, IRuleSetFactory.RuleSetKind.SAMPLING);
+        // now add assign [$$36] <- [{"$1": $$39}]   on top of newAggOp; use the HelperFunction and call Sampling query
+        return helperFunction(newCtx, newAggOp);
     }
 
     // This one gets the cardinality and also projection sizes
@@ -857,32 +880,7 @@
         // add assign [$$79] <- [{"$1": $$73, "$2": $$74, "$3": $$75, "$4": $$76, "$5": $$77, "$6": $$78}]
         AggregateOperator newAggOp = new AggregateOperator(newVars2, aggExprList);
         newAggOp.getInputs().add(new MutableObject<>(assignOp));
-        Mutable<ILogicalOperator> newAggOpRef = new MutableObject<>(newAggOp);
-        OperatorPropertiesUtil.typeOpRec(newAggOpRef, newCtx); // is this really needed??
-        List<MutableObject> arr = createMutableObjectArray(newAggOp.getVariables());
-        AbstractFunctionCallExpression f = new ScalarFunctionCallExpression(
-                FunctionUtil.getFunctionInfo(BuiltinFunctions.OPEN_RECORD_CONSTRUCTOR));
-        for (int i = 0; i < arr.size(); i++) {
-            f.getArguments().add(arr.get(i));
-        }
-
-        newVar = newCtx.newVar();
-        assignOp = new AssignOperator(newVar, new MutableObject<>(f));
-        assignOp.getInputs().add(new MutableObject<>(newAggOp));
-        ProjectOperator pOp = new ProjectOperator(newVar);
-        pOp.getInputs().add(new MutableObject<>(assignOp));
-
-        Mutable<ILogicalOperator> Ref = new MutableObject<>(pOp);
-
-        OperatorPropertiesUtil.typeOpRec(Ref, newCtx);
-        if (LOGGER.isTraceEnabled()) {
-            String viewInPlan = new ALogicalPlanImpl(Ref).toString(); //useful when debugging
-            LOGGER.trace("sampling query before calling runQuery");
-            LOGGER.trace(viewInPlan);
-        }
-
-        LOGGER.info("***returning from projection sample query***");
-        return AnalysisUtil.runQuery(Ref, Arrays.asList(newVar), newCtx, IRuleSetFactory.RuleSetKind.SAMPLING);
+        return helperFunction(newCtx, newAggOp);
     }
 
     private List<MutableObject> createMutableObjectArray(List<LogicalVariable> vars) {
@@ -984,7 +982,10 @@
         return x;
     }
 
-    private double distinctEstimator2(double estDistinctCardinalityFromSample, Index index) throws AlgebricksException {
+    // This estimator use the fact that the equation d = D (1 - e^n/D) is a 1-1 functions. So given d, it can find D using a
+    // binary search, thus avoiding the Newton Raphson iteration which is more complex.
+    private double secondDistinctEstimator(double estDistinctCardinalityFromSample, Index index)
+            throws AlgebricksException {
 
         Index.SampleIndexDetails idxDetails = (Index.SampleIndexDetails) index.getIndexDetails();
         double origDatasetCardinality = idxDetails.getSourceCardinality();
@@ -1005,6 +1006,9 @@
             else
                 Dmax = D - 1;
         }
+        if (D == 0.0) { // just in case!
+            D = 1.0;
+        }
         return D;
     }
 
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/results_cbo/cardinality-estimation/join-queries/join-queries.5.plan b/asterixdb/asterix-app/src/test/resources/runtimets/results_cbo/cardinality-estimation/join-queries/join-queries.5.plan
index 95a3075..4d11aca 100644
--- a/asterixdb/asterix-app/src/test/resources/runtimets/results_cbo/cardinality-estimation/join-queries/join-queries.5.plan
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/results_cbo/cardinality-estimation/join-queries/join-queries.5.plan
@@ -1,28 +1,28 @@
-distribute result [$$101] [cardinality: 1004.25, op-cost: 0.0, total-cost: 18055.78]
+distribute result [$$101] [cardinality: 1003.05, op-cost: 0.0, total-cost: 18041.34]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
-  exchange [cardinality: 1004.25, op-cost: 0.0, total-cost: 18055.78]
+  exchange [cardinality: 1003.05, op-cost: 0.0, total-cost: 18041.34]
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-    assign [$$101] <- [{"$1": $$111}] project: [$$101] [cardinality: 1004.25, op-cost: 0.0, total-cost: 18055.78]
+    assign [$$101] <- [{"$1": $$111}] project: [$$101] [cardinality: 1003.05, op-cost: 0.0, total-cost: 18041.34]
     -- ASSIGN  |PARTITIONED|
-      project ([$$111]) [cardinality: 1004.25, op-cost: 0.0, total-cost: 18055.78]
+      project ([$$111]) [cardinality: 1003.05, op-cost: 0.0, total-cost: 18041.34]
       -- STREAM_PROJECT  |PARTITIONED|
-        exchange [cardinality: 1004.25, op-cost: 0.0, total-cost: 18055.78]
+        exchange [cardinality: 1003.05, op-cost: 0.0, total-cost: 18041.34]
         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
           group by ([$$l_partkey := $$115; $$o_orderstatus := $$116; $$c_nationkey := $$117]) decor ([]) {
                     aggregate [$$111] <- [sql-sum-serial($$114)] [cardinality: 0.0, op-cost: 0.0, total-cost: 0.0]
                     -- AGGREGATE  |LOCAL|
                       nested tuple source [cardinality: 0.0, op-cost: 0.0, total-cost: 0.0]
                       -- NESTED_TUPLE_SOURCE  |LOCAL|
-                 } [cardinality: 1004.25, op-cost: 6025.39, total-cost: 18055.78]
+                 } [cardinality: 1003.05, op-cost: 6018.17, total-cost: 18041.34]
           -- EXTERNAL_GROUP_BY[$$115, $$116, $$117]  |PARTITIONED|
-            exchange [cardinality: 1004.25, op-cost: 0.0, total-cost: 12030.39]
+            exchange [cardinality: 1003.05, op-cost: 0.0, total-cost: 12023.17]
             -- HASH_PARTITION_EXCHANGE [$$115, $$116, $$117]  |PARTITIONED|
               group by ([$$115 := $$102; $$116 := $$103; $$117 := $$104]) decor ([]) {
                         aggregate [$$114] <- [sql-count-serial(1)] [cardinality: 0.0, op-cost: 0.0, total-cost: 0.0]
                         -- AGGREGATE  |LOCAL|
                           nested tuple source [cardinality: 0.0, op-cost: 0.0, total-cost: 0.0]
                           -- NESTED_TUPLE_SOURCE  |LOCAL|
-                     } [cardinality: 1004.25, op-cost: 6025.39, total-cost: 12030.39]
+                     } [cardinality: 1003.05, op-cost: 6018.17, total-cost: 12023.17]
               -- EXTERNAL_GROUP_BY[$$102, $$103, $$104]  |PARTITIONED|
                 exchange [cardinality: 6010.65, op-cost: 0.0, total-cost: 6005.0]
                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
@@ -40,7 +40,7 @@
                             -- STREAM_PROJECT  |PARTITIONED|
                               exchange [cardinality: 0.0, op-cost: 0.0, total-cost: 0.0]
                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                join (eq($$109, $$108)) [cardinality: 1503.21, op-cost: 2101.41, total-cost: 4351.41]
+                                join (eq($$109, $$108)) [cardinality: 1501.41, op-cost: 2101.41, total-cost: 4351.41]
                                 -- HYBRID_HASH_JOIN [$$109][$$108]  |PARTITIONED|
                                   exchange [cardinality: 0.0, op-cost: 0.0, total-cost: 0.0]
                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/results_cbo/cardinality-estimation/join-queries/join-queries.6.plan b/asterixdb/asterix-app/src/test/resources/runtimets/results_cbo/cardinality-estimation/join-queries/join-queries.6.plan
index a7a3bb7..743ec55 100644
--- a/asterixdb/asterix-app/src/test/resources/runtimets/results_cbo/cardinality-estimation/join-queries/join-queries.6.plan
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/results_cbo/cardinality-estimation/join-queries/join-queries.6.plan
@@ -1,36 +1,36 @@
-distribute result [$$101] [cardinality: 1004.25, op-cost: 0.0, total-cost: 34447.61]
+distribute result [$$101] [cardinality: 1003.05, op-cost: 0.0, total-cost: 34411.56]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
-  exchange [cardinality: 1004.25, op-cost: 0.0, total-cost: 34447.61]
+  exchange [cardinality: 1003.05, op-cost: 0.0, total-cost: 34411.56]
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-    assign [$$101] <- [{"$1": $$111}] project: [$$101] [cardinality: 1004.25, op-cost: 0.0, total-cost: 34447.61]
+    assign [$$101] <- [{"$1": $$111}] project: [$$101] [cardinality: 1003.05, op-cost: 0.0, total-cost: 34411.56]
     -- ASSIGN  |PARTITIONED|
-      project ([$$111]) [cardinality: 1004.25, op-cost: 0.0, total-cost: 34447.61]
+      project ([$$111]) [cardinality: 1003.05, op-cost: 0.0, total-cost: 34411.56]
       -- STREAM_PROJECT  |PARTITIONED|
-        exchange [cardinality: 1004.25, op-cost: 0.0, total-cost: 34447.61]
+        exchange [cardinality: 1003.05, op-cost: 0.0, total-cost: 34411.56]
         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
           group by ([$$l_linenumber := $$115; $$o_orderstatus := $$116; $$c_nationkey := $$117]) decor ([]) {
                     aggregate [$$111] <- [sql-sum-serial($$114)] [cardinality: 0.0, op-cost: 0.0, total-cost: 0.0]
                     -- AGGREGATE  |LOCAL|
                       nested tuple source [cardinality: 0.0, op-cost: 0.0, total-cost: 0.0]
                       -- NESTED_TUPLE_SOURCE  |LOCAL|
-                 } [cardinality: 1004.25, op-cost: 6025.39, total-cost: 34447.61]
+                 } [cardinality: 1003.05, op-cost: 6018.17, total-cost: 34411.56]
           -- EXTERNAL_GROUP_BY[$$115, $$116, $$117]  |PARTITIONED|
-            exchange [cardinality: 1004.25, op-cost: 0.0, total-cost: 28422.22]
+            exchange [cardinality: 1003.05, op-cost: 0.0, total-cost: 28393.39]
             -- HASH_PARTITION_EXCHANGE [$$115, $$116, $$117]  |PARTITIONED|
               group by ([$$115 := $$106; $$116 := $$103; $$117 := $$104]) decor ([]) {
                         aggregate [$$114] <- [sql-count-serial(1)] [cardinality: 0.0, op-cost: 0.0, total-cost: 0.0]
                         -- AGGREGATE  |LOCAL|
                           nested tuple source [cardinality: 0.0, op-cost: 0.0, total-cost: 0.0]
                           -- NESTED_TUPLE_SOURCE  |LOCAL|
-                     } [cardinality: 1004.25, op-cost: 6025.39, total-cost: 28422.22]
+                     } [cardinality: 1003.05, op-cost: 6018.17, total-cost: 28393.39]
               -- EXTERNAL_GROUP_BY[$$106, $$103, $$104]  |PARTITIONED|
-                exchange [cardinality: 6025.39, op-cost: 0.0, total-cost: 22396.83]
+                exchange [cardinality: 6018.17, op-cost: 0.0, total-cost: 22375.22]
                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                  project ([$$106, $$103, $$104]) [cardinality: 6025.39, op-cost: 0.0, total-cost: 22396.83]
+                  project ([$$106, $$103, $$104]) [cardinality: 6018.17, op-cost: 0.0, total-cost: 22375.22]
                   -- STREAM_PROJECT  |PARTITIONED|
-                    exchange [cardinality: 6025.39, op-cost: 0.0, total-cost: 22396.83]
+                    exchange [cardinality: 6018.17, op-cost: 0.0, total-cost: 22375.22]
                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                      unnest-map [$$105, $$106, $$l] <- index-search("LineItem", 0, "Default", "tpch", "LineItem", true, true, 1, $$107, 1, $$107, true, true, true) [cardinality: 6025.39, op-cost: 12032.57, total-cost: 22396.83]
+                      unnest-map [$$105, $$106, $$l] <- index-search("LineItem", 0, "Default", "tpch", "LineItem", true, true, 1, $$107, 1, $$107, true, true, true) [cardinality: 6018.17, op-cost: 12018.16, total-cost: 22375.22]
                       -- BTREE_SEARCH  |PARTITIONED|
                         exchange [cardinality: 0.0, op-cost: 0.0, total-cost: 0.0]
                         -- BROADCAST_EXCHANGE  |PARTITIONED|
@@ -38,7 +38,7 @@
                           -- STREAM_PROJECT  |PARTITIONED|
                             exchange [cardinality: 0.0, op-cost: 0.0, total-cost: 0.0]
                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                              join (eq($$109, $$108)) [cardinality: 1503.21, op-cost: 2101.41, total-cost: 4351.41]
+                              join (eq($$109, $$108)) [cardinality: 1501.41, op-cost: 2101.41, total-cost: 4351.41]
                               -- HYBRID_HASH_JOIN [$$109][$$108]  |PARTITIONED|
                                 exchange [cardinality: 0.0, op-cost: 0.0, total-cost: 0.0]
                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/results_cbo/cardinality-estimation/join-queries/join-queries.7.plan b/asterixdb/asterix-app/src/test/resources/runtimets/results_cbo/cardinality-estimation/join-queries/join-queries.7.plan
index 01e531d..9e4eff7 100644
--- a/asterixdb/asterix-app/src/test/resources/runtimets/results_cbo/cardinality-estimation/join-queries/join-queries.7.plan
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/results_cbo/cardinality-estimation/join-queries/join-queries.7.plan
@@ -1,36 +1,36 @@
-distribute result [$$101] [cardinality: 1004.25, op-cost: 0.0, total-cost: 34447.61]
+distribute result [$$101] [cardinality: 1003.05, op-cost: 0.0, total-cost: 34411.56]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
-  exchange [cardinality: 1004.25, op-cost: 0.0, total-cost: 34447.61]
+  exchange [cardinality: 1003.05, op-cost: 0.0, total-cost: 34411.56]
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-    assign [$$101] <- [{"$1": $$111}] project: [$$101] [cardinality: 1004.25, op-cost: 0.0, total-cost: 34447.61]
+    assign [$$101] <- [{"$1": $$111}] project: [$$101] [cardinality: 1003.05, op-cost: 0.0, total-cost: 34411.56]
     -- ASSIGN  |PARTITIONED|
-      project ([$$111]) [cardinality: 1004.25, op-cost: 0.0, total-cost: 34447.61]
+      project ([$$111]) [cardinality: 1003.05, op-cost: 0.0, total-cost: 34411.56]
       -- STREAM_PROJECT  |PARTITIONED|
-        exchange [cardinality: 1004.25, op-cost: 0.0, total-cost: 34447.61]
+        exchange [cardinality: 1003.05, op-cost: 0.0, total-cost: 34411.56]
         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
           group by ([$$l_linenumber := $$115; $$c_nationkey := $$116; $$o_orderstatus := $$117]) decor ([]) {
                     aggregate [$$111] <- [sql-sum-serial($$114)] [cardinality: 0.0, op-cost: 0.0, total-cost: 0.0]
                     -- AGGREGATE  |LOCAL|
                       nested tuple source [cardinality: 0.0, op-cost: 0.0, total-cost: 0.0]
                       -- NESTED_TUPLE_SOURCE  |LOCAL|
-                 } [cardinality: 1004.25, op-cost: 6025.39, total-cost: 34447.61]
+                 } [cardinality: 1003.05, op-cost: 6018.17, total-cost: 34411.56]
           -- EXTERNAL_GROUP_BY[$$115, $$116, $$117]  |PARTITIONED|
-            exchange [cardinality: 1004.25, op-cost: 0.0, total-cost: 28422.22]
+            exchange [cardinality: 1003.05, op-cost: 0.0, total-cost: 28393.39]
             -- HASH_PARTITION_EXCHANGE [$$115, $$116, $$117]  |PARTITIONED|
               group by ([$$115 := $$106; $$116 := $$103; $$117 := $$104]) decor ([]) {
                         aggregate [$$114] <- [sql-count-serial(1)] [cardinality: 0.0, op-cost: 0.0, total-cost: 0.0]
                         -- AGGREGATE  |LOCAL|
                           nested tuple source [cardinality: 0.0, op-cost: 0.0, total-cost: 0.0]
                           -- NESTED_TUPLE_SOURCE  |LOCAL|
-                     } [cardinality: 1004.25, op-cost: 6025.39, total-cost: 28422.22]
+                     } [cardinality: 1003.05, op-cost: 6018.17, total-cost: 28393.39]
               -- EXTERNAL_GROUP_BY[$$106, $$103, $$104]  |PARTITIONED|
-                exchange [cardinality: 6025.39, op-cost: 0.0, total-cost: 22396.83]
+                exchange [cardinality: 6018.17, op-cost: 0.0, total-cost: 22375.22]
                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                  project ([$$106, $$103, $$104]) [cardinality: 6025.39, op-cost: 0.0, total-cost: 22396.83]
+                  project ([$$106, $$103, $$104]) [cardinality: 6018.17, op-cost: 0.0, total-cost: 22375.22]
                   -- STREAM_PROJECT  |PARTITIONED|
-                    exchange [cardinality: 6025.39, op-cost: 0.0, total-cost: 22396.83]
+                    exchange [cardinality: 6018.17, op-cost: 0.0, total-cost: 22375.22]
                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                      unnest-map [$$105, $$106, $$l] <- index-search("LineItem", 0, "Default", "tpch", "LineItem", true, true, 1, $$107, 1, $$107, true, true, true) [cardinality: 6025.39, op-cost: 12032.57, total-cost: 22396.83]
+                      unnest-map [$$105, $$106, $$l] <- index-search("LineItem", 0, "Default", "tpch", "LineItem", true, true, 1, $$107, 1, $$107, true, true, true) [cardinality: 6018.17, op-cost: 12018.16, total-cost: 22375.22]
                       -- BTREE_SEARCH  |PARTITIONED|
                         exchange [cardinality: 0.0, op-cost: 0.0, total-cost: 0.0]
                         -- BROADCAST_EXCHANGE  |PARTITIONED|
@@ -38,7 +38,7 @@
                           -- STREAM_PROJECT  |PARTITIONED|
                             exchange [cardinality: 0.0, op-cost: 0.0, total-cost: 0.0]
                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                              join (eq($$109, $$108)) [cardinality: 1503.21, op-cost: 2101.41, total-cost: 4351.41]
+                              join (eq($$109, $$108)) [cardinality: 1501.41, op-cost: 2101.41, total-cost: 4351.41]
                               -- HYBRID_HASH_JOIN [$$109][$$108]  |PARTITIONED|
                                 exchange [cardinality: 0.0, op-cost: 0.0, total-cost: 0.0]
                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/results_cbo/cardinality-estimation/join-queries/join-queries.8.plan b/asterixdb/asterix-app/src/test/resources/runtimets/results_cbo/cardinality-estimation/join-queries/join-queries.8.plan
index e50b704..baa6c88 100644
--- a/asterixdb/asterix-app/src/test/resources/runtimets/results_cbo/cardinality-estimation/join-queries/join-queries.8.plan
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/results_cbo/cardinality-estimation/join-queries/join-queries.8.plan
@@ -1,34 +1,34 @@
-distribute result [$$119] [cardinality: 25.0, op-cost: 0.0, total-cost: 7223.81]
+distribute result [$$119] [cardinality: 25.0, op-cost: 0.0, total-cost: 7109.8]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
-  exchange [cardinality: 25.0, op-cost: 0.0, total-cost: 7223.81]
+  exchange [cardinality: 25.0, op-cost: 0.0, total-cost: 7109.8]
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-    assign [$$119] <- [{"n_name": $$n_name, "revenue": $$132}] project: [$$119] [cardinality: 25.0, op-cost: 0.0, total-cost: 7223.81]
+    assign [$$119] <- [{"n_name": $$n_name, "revenue": $$132}] project: [$$119] [cardinality: 25.0, op-cost: 0.0, total-cost: 7109.8]
     -- ASSIGN  |PARTITIONED|
-      exchange [cardinality: 25.0, op-cost: 0.0, total-cost: 7223.81]
+      exchange [cardinality: 25.0, op-cost: 0.0, total-cost: 7109.8]
       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
         group by ([$$n_name := $$142]) decor ([]) {
                   aggregate [$$132] <- [global-sql-sum-serial($$141)] [cardinality: 0.0, op-cost: 0.0, total-cost: 0.0]
                   -- AGGREGATE  |LOCAL|
                     nested tuple source [cardinality: 0.0, op-cost: 0.0, total-cost: 0.0]
                     -- NESTED_TUPLE_SOURCE  |LOCAL|
-               } [cardinality: 25.0, op-cost: 110.34, total-cost: 7223.81]
+               } [cardinality: 25.0, op-cost: 110.61, total-cost: 7109.8]
         -- EXTERNAL_GROUP_BY[$$142]  |PARTITIONED|
-          exchange [cardinality: 25.0, op-cost: 0.0, total-cost: 7113.47]
+          exchange [cardinality: 25.0, op-cost: 0.0, total-cost: 6999.19]
           -- HASH_PARTITION_EXCHANGE [$$142]  |PARTITIONED|
             group by ([$$142 := $$120]) decor ([]) {
                       aggregate [$$141] <- [local-sql-sum-serial(numeric-multiply($$139, numeric-subtract(1, $$140)))] [cardinality: 0.0, op-cost: 0.0, total-cost: 0.0]
                       -- AGGREGATE  |LOCAL|
                         nested tuple source [cardinality: 0.0, op-cost: 0.0, total-cost: 0.0]
                         -- NESTED_TUPLE_SOURCE  |LOCAL|
-                   } [cardinality: 25.0, op-cost: 110.34, total-cost: 7113.47]
+                   } [cardinality: 25.0, op-cost: 110.61, total-cost: 6999.19]
             -- EXTERNAL_GROUP_BY[$$120]  |PARTITIONED|
-              exchange [cardinality: 110.34, op-cost: 0.0, total-cost: 7003.13]
+              exchange [cardinality: 110.61, op-cost: 0.0, total-cost: 6888.58]
               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                project ([$$139, $$140, $$120]) [cardinality: 110.34, op-cost: 0.0, total-cost: 7003.13]
+                project ([$$139, $$140, $$120]) [cardinality: 110.61, op-cost: 0.0, total-cost: 6888.58]
                 -- STREAM_PROJECT  |PARTITIONED|
-                  exchange [cardinality: 110.34, op-cost: 0.0, total-cost: 7003.13]
+                  exchange [cardinality: 110.61, op-cost: 0.0, total-cost: 6888.58]
                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                    join (and(eq($$130, $$128), eq($$133, $$127))) [cardinality: 110.34, op-cost: 1062.24, total-cost: 7003.13]
+                    join (and(eq($$130, $$128), eq($$133, $$127))) [cardinality: 110.61, op-cost: 1035.49, total-cost: 6888.58]
                     -- HYBRID_HASH_JOIN [$$128, $$133][$$130, $$127]  |PARTITIONED|
                       exchange [cardinality: 6010.65, op-cost: 0.0, total-cost: 6005.0]
                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
@@ -46,7 +46,7 @@
                                   -- STREAM_PROJECT  |PARTITIONED|
                                     exchange [cardinality: 0.0, op-cost: 0.0, total-cost: 0.0]
                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                      join (eq($$123, $$136)) [cardinality: 255.03, op-cost: 402.2, total-cost: 2829.4]
+                                      join (eq($$123, $$136)) [cardinality: 248.35, op-cost: 398.35, total-cost: 2821.71]
                                       -- HYBRID_HASH_JOIN [$$123][$$136]  |PARTITIONED|
                                         exchange [cardinality: 0.0, op-cost: 0.0, total-cost: 0.0]
                                         -- HASH_PARTITION_EXCHANGE [$$123]  |PARTITIONED|
@@ -54,7 +54,7 @@
                                           -- STREAM_PROJECT  |PARTITIONED|
                                             exchange [cardinality: 0.0, op-cost: 0.0, total-cost: 0.0]
                                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                              join (eq($$131, $$128)) [cardinality: 153.85, op-cost: 175.0, total-cost: 525.0]
+                                              join (eq($$131, $$128)) [cardinality: 150.0, op-cost: 175.0, total-cost: 525.0]
                                               -- HYBRID_HASH_JOIN [$$131][$$128]  |PARTITIONED|
                                                 exchange [cardinality: 0.0, op-cost: 0.0, total-cost: 0.0]
                                                 -- HASH_PARTITION_EXCHANGE [$$131]  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/results_cbo/column/pushdown/field-access-pushdown/field-access-pushdown.006.plan b/asterixdb/asterix-app/src/test/resources/runtimets/results_cbo/column/pushdown/field-access-pushdown/field-access-pushdown.006.plan
index 6292f9e..3d196fc 100644
--- a/asterixdb/asterix-app/src/test/resources/runtimets/results_cbo/column/pushdown/field-access-pushdown/field-access-pushdown.006.plan
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/results_cbo/column/pushdown/field-access-pushdown/field-access-pushdown.006.plan
@@ -1,20 +1,20 @@
-distribute result [$$30] [cardinality: 8.17, op-cost: 0.0, total-cost: 66.76]
+distribute result [$$30] [cardinality: 7.0, op-cost: 0.0, total-cost: 61.65]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
-  exchange [cardinality: 8.17, op-cost: 0.0, total-cost: 66.76]
+  exchange [cardinality: 7.0, op-cost: 0.0, total-cost: 61.65]
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-    assign [$$30] <- [{"p1": $$p1, "id": $$34}] project: [$$30] [cardinality: 8.17, op-cost: 0.0, total-cost: 66.76]
+    assign [$$30] <- [{"p1": $$p1, "id": $$34}] project: [$$30] [cardinality: 7.0, op-cost: 0.0, total-cost: 61.65]
     -- ASSIGN  |PARTITIONED|
-      exchange [cardinality: 8.17, op-cost: 0.0, total-cost: 66.76]
+      exchange [cardinality: 7.0, op-cost: 0.0, total-cost: 61.65]
       -- SORT_MERGE_EXCHANGE [$$34(ASC) ]  |PARTITIONED|
-        order (ASC, $$34) [cardinality: 8.17, op-cost: 24.76, total-cost: 66.76]
+        order (ASC, $$34) [cardinality: 7.0, op-cost: 19.65, total-cost: 61.65]
         -- STABLE_SORT [$$34(ASC)]  |PARTITIONED|
-          exchange [cardinality: 8.17, op-cost: 0.0, total-cost: 42.0]
+          exchange [cardinality: 7.0, op-cost: 0.0, total-cost: 42.0]
           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-            project ([$$p1, $$34]) [cardinality: 8.17, op-cost: 0.0, total-cost: 42.0]
+            project ([$$p1, $$34]) [cardinality: 7.0, op-cost: 0.0, total-cost: 42.0]
             -- STREAM_PROJECT  |PARTITIONED|
-              exchange [cardinality: 8.17, op-cost: 0.0, total-cost: 42.0]
+              exchange [cardinality: 7.0, op-cost: 0.0, total-cost: 42.0]
               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                join (eq($$33, $$34)) [cardinality: 8.17, op-cost: 14.0, total-cost: 42.0]
+                join (eq($$33, $$34)) [cardinality: 7.0, op-cost: 14.0, total-cost: 42.0]
                 -- HYBRID_HASH_JOIN [$$33][$$34]  |PARTITIONED|
                   exchange [cardinality: 7.0, op-cost: 7.0, total-cost: 14.0]
                   -- HASH_PARTITION_EXCHANGE [$$33]  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/results_cbo/column/pushdown/field-access-pushdown/field-access-pushdown.008.plan b/asterixdb/asterix-app/src/test/resources/runtimets/results_cbo/column/pushdown/field-access-pushdown/field-access-pushdown.008.plan
index ae5dd2b..f7797b0 100644
--- a/asterixdb/asterix-app/src/test/resources/runtimets/results_cbo/column/pushdown/field-access-pushdown/field-access-pushdown.008.plan
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/results_cbo/column/pushdown/field-access-pushdown/field-access-pushdown.008.plan
@@ -1,22 +1,22 @@
-distribute result [$$31] [cardinality: 9.33, op-cost: 0.0, total-cost: 75.06]
+distribute result [$$31] [cardinality: 8.0, op-cost: 0.0, total-cost: 69.0]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
-  exchange [cardinality: 9.33, op-cost: 0.0, total-cost: 75.06]
+  exchange [cardinality: 8.0, op-cost: 0.0, total-cost: 69.0]
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-    assign [$$31] <- [{"age": $$38, "name": $$39}] project: [$$31] [cardinality: 9.33, op-cost: 0.0, total-cost: 75.06]
+    assign [$$31] <- [{"age": $$38, "name": $$39}] project: [$$31] [cardinality: 8.0, op-cost: 0.0, total-cost: 69.0]
     -- ASSIGN  |PARTITIONED|
-      project ([$$38, $$39]) [cardinality: 9.33, op-cost: 0.0, total-cost: 75.06]
+      project ([$$38, $$39]) [cardinality: 8.0, op-cost: 0.0, total-cost: 69.0]
       -- STREAM_PROJECT  |PARTITIONED|
-        exchange [cardinality: 9.33, op-cost: 0.0, total-cost: 75.06]
+        exchange [cardinality: 8.0, op-cost: 0.0, total-cost: 69.0]
         -- SORT_MERGE_EXCHANGE [$$34(ASC) ]  |PARTITIONED|
-          order (ASC, $$34) [cardinality: 9.33, op-cost: 30.06, total-cost: 75.06]
+          order (ASC, $$34) [cardinality: 8.0, op-cost: 24.0, total-cost: 69.0]
           -- STABLE_SORT [$$34(ASC)]  |PARTITIONED|
-            exchange [cardinality: 9.33, op-cost: 0.0, total-cost: 45.0]
+            exchange [cardinality: 8.0, op-cost: 0.0, total-cost: 45.0]
             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-              project ([$$38, $$39, $$34]) [cardinality: 9.33, op-cost: 0.0, total-cost: 45.0]
+              project ([$$38, $$39, $$34]) [cardinality: 8.0, op-cost: 0.0, total-cost: 45.0]
               -- STREAM_PROJECT  |PARTITIONED|
-                exchange [cardinality: 9.33, op-cost: 0.0, total-cost: 45.0]
+                exchange [cardinality: 8.0, op-cost: 0.0, total-cost: 45.0]
                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                  join (eq($$33, $$34)) [cardinality: 9.33, op-cost: 15.0, total-cost: 45.0]
+                  join (eq($$33, $$34)) [cardinality: 8.0, op-cost: 15.0, total-cost: 45.0]
                   -- HYBRID_HASH_JOIN [$$34][$$33]  |PARTITIONED|
                     exchange [cardinality: 8.0, op-cost: 8.0, total-cost: 16.0]
                     -- HASH_PARTITION_EXCHANGE [$$34]  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/results_cbo/column/pushdown/other-pushdowns/other-pushdowns.004.plan b/asterixdb/asterix-app/src/test/resources/runtimets/results_cbo/column/pushdown/other-pushdowns/other-pushdowns.004.plan
index 0bb05d0..90cfae5 100644
--- a/asterixdb/asterix-app/src/test/resources/runtimets/results_cbo/column/pushdown/other-pushdowns/other-pushdowns.004.plan
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/results_cbo/column/pushdown/other-pushdowns/other-pushdowns.004.plan
@@ -1,22 +1,22 @@
-distribute result [$$61] [cardinality: 2.67, op-cost: 0.0, total-cost: 12.0]
+distribute result [$$61] [cardinality: 2.1, op-cost: 0.0, total-cost: 12.0]
 -- DISTRIBUTE_RESULT  |UNPARTITIONED|
-  exchange [cardinality: 2.67, op-cost: 0.0, total-cost: 12.0]
+  exchange [cardinality: 2.1, op-cost: 0.0, total-cost: 12.0]
   -- ONE_TO_ONE_EXCHANGE  |UNPARTITIONED|
-    assign [$$61] <- [{"$1": $$66, "$2": $$67}] project: [$$61] [cardinality: 2.67, op-cost: 0.0, total-cost: 12.0]
+    assign [$$61] <- [{"$1": $$66, "$2": $$67}] project: [$$61] [cardinality: 2.1, op-cost: 0.0, total-cost: 12.0]
     -- ASSIGN  |UNPARTITIONED|
-      aggregate [$$66, $$67] <- [agg-global-sql-sum($$70), agg-global-sql-sum($$71)] [cardinality: 2.67, op-cost: 0.0, total-cost: 12.0]
+      aggregate [$$66, $$67] <- [agg-global-sql-sum($$70), agg-global-sql-sum($$71)] [cardinality: 2.1, op-cost: 0.0, total-cost: 12.0]
       -- AGGREGATE  |UNPARTITIONED|
-        exchange [cardinality: 2.67, op-cost: 0.0, total-cost: 12.0]
+        exchange [cardinality: 2.1, op-cost: 0.0, total-cost: 12.0]
         -- RANDOM_MERGE_EXCHANGE  |PARTITIONED|
-          aggregate [$$70, $$71] <- [agg-local-sql-sum($$54), agg-local-sql-sum($$59)] [cardinality: 2.67, op-cost: 0.0, total-cost: 12.0]
+          aggregate [$$70, $$71] <- [agg-local-sql-sum($$54), agg-local-sql-sum($$59)] [cardinality: 2.1, op-cost: 0.0, total-cost: 12.0]
           -- AGGREGATE  |PARTITIONED|
-            assign [$$59, $$54] <- [object-length($$p2), object-length($$p1)] project: [$$54, $$59] [cardinality: 2.67, op-cost: 0.0, total-cost: 12.0]
+            assign [$$59, $$54] <- [object-length($$p2), object-length($$p1)] project: [$$54, $$59] [cardinality: 2.1, op-cost: 0.0, total-cost: 12.0]
             -- ASSIGN  |PARTITIONED|
-              project ([$$p1, $$p2]) [cardinality: 2.67, op-cost: 0.0, total-cost: 12.0]
+              project ([$$p1, $$p2]) [cardinality: 2.1, op-cost: 0.0, total-cost: 12.0]
               -- STREAM_PROJECT  |PARTITIONED|
-                exchange [cardinality: 2.67, op-cost: 0.0, total-cost: 12.0]
+                exchange [cardinality: 2.1, op-cost: 0.0, total-cost: 12.0]
                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                  join (eq($$63, $$62)) [cardinality: 2.67, op-cost: 4.0, total-cost: 12.0]
+                  join (eq($$63, $$62)) [cardinality: 2.1, op-cost: 4.0, total-cost: 12.0]
                   -- HYBRID_HASH_JOIN [$$62][$$63]  |PARTITIONED|
                     exchange [cardinality: 2.0, op-cost: 2.0, total-cost: 4.0]
                     -- HASH_PARTITION_EXCHANGE [$$62]  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/results_cbo/column/pushdown/other-pushdowns/other-pushdowns.015.plan b/asterixdb/asterix-app/src/test/resources/runtimets/results_cbo/column/pushdown/other-pushdowns/other-pushdowns.015.plan
index d71189b..1111ccc 100644
--- a/asterixdb/asterix-app/src/test/resources/runtimets/results_cbo/column/pushdown/other-pushdowns/other-pushdowns.015.plan
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/results_cbo/column/pushdown/other-pushdowns/other-pushdowns.015.plan
@@ -1,20 +1,20 @@
-distribute result [$$52] [cardinality: 2.67, op-cost: 0.0, total-cost: 12.0]
+distribute result [$$52] [cardinality: 4.0, op-cost: 0.0, total-cost: 12.0]
 -- DISTRIBUTE_RESULT  |UNPARTITIONED|
-  exchange [cardinality: 2.67, op-cost: 0.0, total-cost: 12.0]
+  exchange [cardinality: 4.0, op-cost: 0.0, total-cost: 12.0]
   -- ONE_TO_ONE_EXCHANGE  |UNPARTITIONED|
-    assign [$$52] <- [{"$1": $$57}] project: [$$52] [cardinality: 2.67, op-cost: 0.0, total-cost: 12.0]
+    assign [$$52] <- [{"$1": $$57}] project: [$$52] [cardinality: 4.0, op-cost: 0.0, total-cost: 12.0]
     -- ASSIGN  |UNPARTITIONED|
-      aggregate [$$57] <- [agg-sql-sum($$60)] [cardinality: 2.67, op-cost: 0.0, total-cost: 12.0]
+      aggregate [$$57] <- [agg-sql-sum($$60)] [cardinality: 4.0, op-cost: 0.0, total-cost: 12.0]
       -- AGGREGATE  |UNPARTITIONED|
-        exchange [cardinality: 2.67, op-cost: 0.0, total-cost: 12.0]
+        exchange [cardinality: 4.0, op-cost: 0.0, total-cost: 12.0]
         -- RANDOM_MERGE_EXCHANGE  |PARTITIONED|
-          aggregate [$$60] <- [agg-sql-count($$50)] [cardinality: 2.67, op-cost: 0.0, total-cost: 12.0]
+          aggregate [$$60] <- [agg-sql-count($$50)] [cardinality: 4.0, op-cost: 0.0, total-cost: 12.0]
           -- AGGREGATE  |PARTITIONED|
-            project ([$$50]) [cardinality: 2.67, op-cost: 0.0, total-cost: 12.0]
+            project ([$$50]) [cardinality: 4.0, op-cost: 0.0, total-cost: 12.0]
             -- STREAM_PROJECT  |PARTITIONED|
-              exchange [cardinality: 2.67, op-cost: 0.0, total-cost: 12.0]
+              exchange [cardinality: 4.0, op-cost: 0.0, total-cost: 12.0]
               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                join (eq($$55, $$56)) [cardinality: 2.67, op-cost: 4.0, total-cost: 12.0]
+                join (eq($$55, $$56)) [cardinality: 4.0, op-cost: 4.0, total-cost: 12.0]
                 -- HYBRID_HASH_JOIN [$$55][$$56]  |PARTITIONED|
                   exchange [cardinality: 2.0, op-cost: 2.0, total-cost: 4.0]
                   -- HASH_PARTITION_EXCHANGE [$$55]  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/results_cbo/join/hash-join-with-redundant-variable/hash-join-with-redundant-variable.04.plan b/asterixdb/asterix-app/src/test/resources/runtimets/results_cbo/join/hash-join-with-redundant-variable/hash-join-with-redundant-variable.04.plan
index 54201b4..b5e1560 100644
--- a/asterixdb/asterix-app/src/test/resources/runtimets/results_cbo/join/hash-join-with-redundant-variable/hash-join-with-redundant-variable.04.plan
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/results_cbo/join/hash-join-with-redundant-variable/hash-join-with-redundant-variable.04.plan
@@ -1,16 +1,16 @@
-distribute result [$$51] [cardinality: 159.84, op-cost: 0.0, total-cost: 1777.06]
+distribute result [$$51] [cardinality: 166.67, op-cost: 0.0, total-cost: 1840.73]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
-  exchange [cardinality: 159.84, op-cost: 0.0, total-cost: 1777.06]
+  exchange [cardinality: 166.67, op-cost: 0.0, total-cost: 1840.73]
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-    assign [$$51] <- [{"n_nationkey": $$58, "s_nationkey": $$56, "c_nationkey": $$55}] project: [$$51] [cardinality: 159.84, op-cost: 0.0, total-cost: 1777.06]
+    assign [$$51] <- [{"n_nationkey": $$58, "s_nationkey": $$56, "c_nationkey": $$55}] project: [$$51] [cardinality: 166.67, op-cost: 0.0, total-cost: 1840.73]
     -- ASSIGN  |PARTITIONED|
-      exchange [cardinality: 159.84, op-cost: 0.0, total-cost: 1777.06]
+      exchange [cardinality: 166.67, op-cost: 0.0, total-cost: 1840.73]
       -- SORT_MERGE_EXCHANGE [$$58(ASC), $$56(ASC), $$55(ASC) ]  |PARTITIONED|
-        order (ASC, $$58) (ASC, $$56) (ASC, $$55) [cardinality: 159.84, op-cost: 1170.11, total-cost: 1777.06]
+        order (ASC, $$58) (ASC, $$56) (ASC, $$55) [cardinality: 166.67, op-cost: 1230.17, total-cost: 1840.73]
         -- STABLE_SORT [$$58(ASC), $$56(ASC), $$55(ASC)]  |PARTITIONED|
-          exchange [cardinality: 159.84, op-cost: 0.0, total-cost: 606.95]
+          exchange [cardinality: 166.67, op-cost: 0.0, total-cost: 610.56]
           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-            join (eq($$55, $$58)) [cardinality: 159.84, op-cost: 175.97, total-cost: 606.95]
+            join (eq($$55, $$58)) [cardinality: 166.67, op-cost: 177.78, total-cost: 610.56]
             -- HYBRID_HASH_JOIN [$$55][$$58]  |PARTITIONED|
               exchange [cardinality: 150.0, op-cost: 150.0, total-cost: 300.0]
               -- HASH_PARTITION_EXCHANGE [$$55]  |PARTITIONED|
@@ -26,9 +26,9 @@
                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
                           empty-tuple-source [cardinality: 0.0, op-cost: 0.0, total-cost: 0.0]
                           -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
-              exchange [cardinality: 25.97, op-cost: 25.97, total-cost: 130.97]
+              exchange [cardinality: 27.78, op-cost: 27.78, total-cost: 132.78]
               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                join (eq($$56, $$58)) [cardinality: 25.97, op-cost: 35.0, total-cost: 105.0]
+                join (eq($$56, $$58)) [cardinality: 27.78, op-cost: 35.0, total-cost: 105.0]
                 -- HYBRID_HASH_JOIN [$$58][$$56]  |PARTITIONED|
                   exchange [cardinality: 25.0, op-cost: 25.0, total-cost: 50.0]
                   -- HASH_PARTITION_EXCHANGE [$$58]  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/results_cbo/join/hash-join-with-redundant-variable/hash-join-with-redundant-variable.10.plan b/asterixdb/asterix-app/src/test/resources/runtimets/results_cbo/join/hash-join-with-redundant-variable/hash-join-with-redundant-variable.10.plan
index a0a9109..1bc2627 100644
--- a/asterixdb/asterix-app/src/test/resources/runtimets/results_cbo/join/hash-join-with-redundant-variable/hash-join-with-redundant-variable.10.plan
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/results_cbo/join/hash-join-with-redundant-variable/hash-join-with-redundant-variable.10.plan
@@ -1,16 +1,16 @@
-distribute result [$$51] [cardinality: 159.84, op-cost: 0.0, total-cost: 1730.95]
+distribute result [$$51] [cardinality: 166.67, op-cost: 0.0, total-cost: 1801.84]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
-  exchange [cardinality: 159.84, op-cost: 0.0, total-cost: 1730.95]
+  exchange [cardinality: 166.67, op-cost: 0.0, total-cost: 1801.84]
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-    assign [$$51] <- [{"n_nationkey": $$58, "s_nationkey": $$56, "c_nationkey": $$55}] project: [$$51] [cardinality: 159.84, op-cost: 0.0, total-cost: 1730.95]
+    assign [$$51] <- [{"n_nationkey": $$58, "s_nationkey": $$56, "c_nationkey": $$55}] project: [$$51] [cardinality: 166.67, op-cost: 0.0, total-cost: 1801.84]
     -- ASSIGN  |PARTITIONED|
-      exchange [cardinality: 159.84, op-cost: 0.0, total-cost: 1730.95]
+      exchange [cardinality: 166.67, op-cost: 0.0, total-cost: 1801.84]
       -- SORT_MERGE_EXCHANGE [$$58(ASC), $$56(ASC), $$55(ASC) ]  |PARTITIONED|
-        order (ASC, $$58) (ASC, $$56) (ASC, $$55) [cardinality: 159.84, op-cost: 1170.11, total-cost: 1730.95]
+        order (ASC, $$58) (ASC, $$56) (ASC, $$55) [cardinality: 166.67, op-cost: 1230.17, total-cost: 1801.84]
         -- STABLE_SORT [$$58(ASC), $$56(ASC), $$55(ASC)]  |PARTITIONED|
-          exchange [cardinality: 159.84, op-cost: 0.0, total-cost: 560.84]
+          exchange [cardinality: 166.67, op-cost: 0.0, total-cost: 571.67]
           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-            join (eq($$55, $$58)) [cardinality: 159.84, op-cost: 227.92, total-cost: 560.84]
+            join (eq($$55, $$58)) [cardinality: 166.67, op-cost: 233.33, total-cost: 571.67]
             -- HYBRID_HASH_JOIN [$$55][$$58]  |PARTITIONED|
               exchange [cardinality: 150.0, op-cost: 0.0, total-cost: 150.0]
               -- RANDOM_PARTITION_EXCHANGE  |PARTITIONED|
@@ -26,9 +26,9 @@
                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
                           empty-tuple-source [cardinality: 0.0, op-cost: 0.0, total-cost: 0.0]
                           -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
-              exchange [cardinality: 25.97, op-cost: 77.92, total-cost: 182.92]
+              exchange [cardinality: 27.78, op-cost: 83.33, total-cost: 188.33]
               -- BROADCAST_EXCHANGE  |PARTITIONED|
-                join (eq($$56, $$58)) [cardinality: 25.97, op-cost: 35.0, total-cost: 105.0]
+                join (eq($$56, $$58)) [cardinality: 27.78, op-cost: 35.0, total-cost: 105.0]
                 -- HYBRID_HASH_JOIN [$$58][$$56]  |PARTITIONED|
                   exchange [cardinality: 25.0, op-cost: 25.0, total-cost: 50.0]
                   -- HASH_PARTITION_EXCHANGE [$$58]  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/results_cbo/join/hash-join-with-redundant-variable/hash-join-with-redundant-variable.12.plan b/asterixdb/asterix-app/src/test/resources/runtimets/results_cbo/join/hash-join-with-redundant-variable/hash-join-with-redundant-variable.12.plan
index 4febca2..d1d77bd 100644
--- a/asterixdb/asterix-app/src/test/resources/runtimets/results_cbo/join/hash-join-with-redundant-variable/hash-join-with-redundant-variable.12.plan
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/results_cbo/join/hash-join-with-redundant-variable/hash-join-with-redundant-variable.12.plan
@@ -1,20 +1,20 @@
-distribute result [$$51] [cardinality: 159.84, op-cost: 0.0, total-cost: 1777.06]
+distribute result [$$51] [cardinality: 166.67, op-cost: 0.0, total-cost: 1840.73]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
-  exchange [cardinality: 159.84, op-cost: 0.0, total-cost: 1777.06]
+  exchange [cardinality: 166.67, op-cost: 0.0, total-cost: 1840.73]
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-    assign [$$51] <- [{"n_nationkey": $$58, "s_nationkey": $$56, "c_nationkey": $$55}] project: [$$51] [cardinality: 159.84, op-cost: 0.0, total-cost: 1777.06]
+    assign [$$51] <- [{"n_nationkey": $$58, "s_nationkey": $$56, "c_nationkey": $$55}] project: [$$51] [cardinality: 166.67, op-cost: 0.0, total-cost: 1840.73]
     -- ASSIGN  |PARTITIONED|
-      exchange [cardinality: 159.84, op-cost: 0.0, total-cost: 1777.06]
+      exchange [cardinality: 166.67, op-cost: 0.0, total-cost: 1840.73]
       -- SORT_MERGE_EXCHANGE [$$58(ASC), $$56(ASC), $$55(ASC) ]  |PARTITIONED|
-        order (ASC, $$58) (ASC, $$56) (ASC, $$55) [cardinality: 159.84, op-cost: 1170.11, total-cost: 1777.06]
+        order (ASC, $$58) (ASC, $$56) (ASC, $$55) [cardinality: 166.67, op-cost: 1230.17, total-cost: 1840.73]
         -- STABLE_SORT [$$58(ASC), $$56(ASC), $$55(ASC)]  |PARTITIONED|
-          exchange [cardinality: 159.84, op-cost: 0.0, total-cost: 606.95]
+          exchange [cardinality: 166.67, op-cost: 0.0, total-cost: 610.56]
           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-            join (eq($$55, $$58)) [cardinality: 159.84, op-cost: 175.97, total-cost: 606.95]
+            join (eq($$55, $$58)) [cardinality: 166.67, op-cost: 177.78, total-cost: 610.56]
             -- HYBRID_HASH_JOIN [$$58][$$55]  |PARTITIONED|
-              exchange [cardinality: 25.97, op-cost: 25.97, total-cost: 130.97]
+              exchange [cardinality: 27.78, op-cost: 27.78, total-cost: 132.78]
               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                join (eq($$56, $$58)) [cardinality: 25.97, op-cost: 35.0, total-cost: 105.0]
+                join (eq($$56, $$58)) [cardinality: 27.78, op-cost: 35.0, total-cost: 105.0]
                 -- HYBRID_HASH_JOIN [$$58][$$56]  |PARTITIONED|
                   exchange [cardinality: 25.0, op-cost: 25.0, total-cost: 50.0]
                   -- HASH_PARTITION_EXCHANGE [$$58]  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/results_cbo/join/hash-join-with-redundant-variable/hash-join-with-redundant-variable.14.plan b/asterixdb/asterix-app/src/test/resources/runtimets/results_cbo/join/hash-join-with-redundant-variable/hash-join-with-redundant-variable.14.plan
index 7a5c207..aef155b 100644
--- a/asterixdb/asterix-app/src/test/resources/runtimets/results_cbo/join/hash-join-with-redundant-variable/hash-join-with-redundant-variable.14.plan
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/results_cbo/join/hash-join-with-redundant-variable/hash-join-with-redundant-variable.14.plan
@@ -1,20 +1,20 @@
-distribute result [$$51] [cardinality: 159.84, op-cost: 0.0, total-cost: 1788.03]
+distribute result [$$51] [cardinality: 166.67, op-cost: 0.0, total-cost: 1853.5]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
-  exchange [cardinality: 159.84, op-cost: 0.0, total-cost: 1788.03]
+  exchange [cardinality: 166.67, op-cost: 0.0, total-cost: 1853.5]
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-    assign [$$51] <- [{"n_nationkey": $$59, "s_nationkey": $$56, "c_nationkey": $$55}] project: [$$51] [cardinality: 159.84, op-cost: 0.0, total-cost: 1788.03]
+    assign [$$51] <- [{"n_nationkey": $$59, "s_nationkey": $$56, "c_nationkey": $$55}] project: [$$51] [cardinality: 166.67, op-cost: 0.0, total-cost: 1853.5]
     -- ASSIGN  |PARTITIONED|
-      exchange [cardinality: 159.84, op-cost: 0.0, total-cost: 1788.03]
+      exchange [cardinality: 166.67, op-cost: 0.0, total-cost: 1853.5]
       -- SORT_MERGE_EXCHANGE [$$59(ASC), $$56(ASC), $$55(ASC) ]  |PARTITIONED|
-        order (ASC, $$59) (ASC, $$56) (ASC, $$55) [cardinality: 159.84, op-cost: 1170.11, total-cost: 1788.03]
+        order (ASC, $$59) (ASC, $$56) (ASC, $$55) [cardinality: 166.67, op-cost: 1230.17, total-cost: 1853.5]
         -- STABLE_SORT [$$59(ASC), $$56(ASC), $$55(ASC)]  |PARTITIONED|
-          exchange [cardinality: 159.84, op-cost: 0.0, total-cost: 617.92]
+          exchange [cardinality: 166.67, op-cost: 0.0, total-cost: 623.33]
           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-            project ([$$59, $$56, $$55]) [cardinality: 159.84, op-cost: 0.0, total-cost: 617.92]
+            project ([$$59, $$56, $$55]) [cardinality: 166.67, op-cost: 0.0, total-cost: 623.33]
             -- STREAM_PROJECT  |PARTITIONED|
-              exchange [cardinality: 159.84, op-cost: 0.0, total-cost: 617.92]
+              exchange [cardinality: 166.67, op-cost: 0.0, total-cost: 623.33]
               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                join (and(eq($$55, $$59), eq($$56, $$66))) [cardinality: 159.84, op-cost: 175.97, total-cost: 617.92]
+                join (and(eq($$55, $$59), eq($$56, $$66))) [cardinality: 166.67, op-cost: 177.78, total-cost: 623.33]
                 -- HYBRID_HASH_JOIN [$$55, $$66][$$59, $$56]  |PARTITIONED|
                   exchange [cardinality: 150.0, op-cost: 150.0, total-cost: 300.0]
                   -- HASH_PARTITION_EXCHANGE [$$55, $$66]  |PARTITIONED|
@@ -32,17 +32,17 @@
                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
                                 empty-tuple-source [cardinality: 0.0, op-cost: 0.0, total-cost: 0.0]
                                 -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
-                  exchange [cardinality: 25.97, op-cost: 25.97, total-cost: 141.94]
+                  exchange [cardinality: 27.78, op-cost: 27.78, total-cost: 145.56]
                   -- HASH_PARTITION_EXCHANGE [$$59, $$56]  |PARTITIONED|
-                    project ([$$56, $$59]) [cardinality: 25.97, op-cost: 0.0, total-cost: 115.97]
+                    project ([$$56, $$59]) [cardinality: 27.78, op-cost: 0.0, total-cost: 117.78]
                     -- STREAM_PROJECT  |PARTITIONED|
-                      exchange [cardinality: 25.97, op-cost: 25.97, total-cost: 141.94]
+                      exchange [cardinality: 27.78, op-cost: 27.78, total-cost: 145.56]
                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                        unnest-map [$$59, $$n] <- index-search("Nation", 0, "Default", "tpch", "Nation", true, true, 1, $$56, 1, $$56, true, true, true) [cardinality: 25.97, op-cost: 65.97, total-cost: 115.97]
+                        unnest-map [$$59, $$n] <- index-search("Nation", 0, "Default", "tpch", "Nation", true, true, 1, $$56, 1, $$56, true, true, true) [cardinality: 27.78, op-cost: 67.78, total-cost: 117.78]
                         -- BTREE_SEARCH  |PARTITIONED|
                           exchange [cardinality: 0.0, op-cost: 0.0, total-cost: 0.0]
                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                            order (ASC, $$56) [cardinality: 25.97, op-cost: 65.97, total-cost: 115.97]
+                            order (ASC, $$56) [cardinality: 27.78, op-cost: 67.78, total-cost: 117.78]
                             -- STABLE_SORT [$$56(ASC)]  |PARTITIONED|
                               exchange [cardinality: 0.0, op-cost: 0.0, total-cost: 0.0]
                               -- HASH_PARTITION_EXCHANGE [$$56]  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/results_cbo/join/hash-join-with-redundant-variable/hash-join-with-redundant-variable.16.plan b/asterixdb/asterix-app/src/test/resources/runtimets/results_cbo/join/hash-join-with-redundant-variable/hash-join-with-redundant-variable.16.plan
index 32f5d18..8a4aa88 100644
--- a/asterixdb/asterix-app/src/test/resources/runtimets/results_cbo/join/hash-join-with-redundant-variable/hash-join-with-redundant-variable.16.plan
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/results_cbo/join/hash-join-with-redundant-variable/hash-join-with-redundant-variable.16.plan
@@ -1,20 +1,20 @@
-distribute result [$$51] [cardinality: 159.84, op-cost: 0.0, total-cost: 1731.93]
+distribute result [$$51] [cardinality: 166.67, op-cost: 0.0, total-cost: 1804.61]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
-  exchange [cardinality: 159.84, op-cost: 0.0, total-cost: 1731.93]
+  exchange [cardinality: 166.67, op-cost: 0.0, total-cost: 1804.61]
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-    assign [$$51] <- [{"n_nationkey": $$59, "s_nationkey": $$56, "c_nationkey": $$55}] project: [$$51] [cardinality: 159.84, op-cost: 0.0, total-cost: 1731.93]
+    assign [$$51] <- [{"n_nationkey": $$59, "s_nationkey": $$56, "c_nationkey": $$55}] project: [$$51] [cardinality: 166.67, op-cost: 0.0, total-cost: 1804.61]
     -- ASSIGN  |PARTITIONED|
-      exchange [cardinality: 159.84, op-cost: 0.0, total-cost: 1731.93]
+      exchange [cardinality: 166.67, op-cost: 0.0, total-cost: 1804.61]
       -- SORT_MERGE_EXCHANGE [$$59(ASC), $$56(ASC), $$55(ASC) ]  |PARTITIONED|
-        order (ASC, $$59) (ASC, $$56) (ASC, $$55) [cardinality: 159.84, op-cost: 1170.11, total-cost: 1731.93]
+        order (ASC, $$59) (ASC, $$56) (ASC, $$55) [cardinality: 166.67, op-cost: 1230.17, total-cost: 1804.61]
         -- STABLE_SORT [$$59(ASC), $$56(ASC), $$55(ASC)]  |PARTITIONED|
-          exchange [cardinality: 159.84, op-cost: 0.0, total-cost: 561.82]
+          exchange [cardinality: 166.67, op-cost: 0.0, total-cost: 574.44]
           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-            project ([$$59, $$56, $$55]) [cardinality: 159.84, op-cost: 0.0, total-cost: 561.82]
+            project ([$$59, $$56, $$55]) [cardinality: 166.67, op-cost: 0.0, total-cost: 574.44]
             -- STREAM_PROJECT  |PARTITIONED|
-              exchange [cardinality: 159.84, op-cost: 0.0, total-cost: 561.82]
+              exchange [cardinality: 166.67, op-cost: 0.0, total-cost: 574.44]
               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                join (and(eq($$55, $$59), eq($$56, $$66))) [cardinality: 159.84, op-cost: 227.92, total-cost: 561.82]
+                join (and(eq($$55, $$59), eq($$56, $$66))) [cardinality: 166.67, op-cost: 233.33, total-cost: 574.44]
                 -- HYBRID_HASH_JOIN [$$55, $$66][$$59, $$56]  |PARTITIONED|
                   exchange [cardinality: 150.0, op-cost: 0.0, total-cost: 150.0]
                   -- RANDOM_PARTITION_EXCHANGE  |PARTITIONED|
@@ -32,17 +32,17 @@
                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
                                 empty-tuple-source [cardinality: 0.0, op-cost: 0.0, total-cost: 0.0]
                                 -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
-                  exchange [cardinality: 25.97, op-cost: 77.92, total-cost: 183.89]
+                  exchange [cardinality: 27.78, op-cost: 83.33, total-cost: 191.11]
                   -- BROADCAST_EXCHANGE  |PARTITIONED|
-                    project ([$$56, $$59]) [cardinality: 25.97, op-cost: 0.0, total-cost: 105.97]
+                    project ([$$56, $$59]) [cardinality: 27.78, op-cost: 0.0, total-cost: 107.78]
                     -- STREAM_PROJECT  |PARTITIONED|
-                      exchange [cardinality: 25.97, op-cost: 77.92, total-cost: 183.89]
+                      exchange [cardinality: 27.78, op-cost: 83.33, total-cost: 191.11]
                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                        unnest-map [$$59, $$n] <- index-search("Nation", 0, "Default", "tpch", "Nation", true, true, 1, $$56, 1, $$56, true, true, true) [cardinality: 25.97, op-cost: 65.97, total-cost: 105.97]
+                        unnest-map [$$59, $$n] <- index-search("Nation", 0, "Default", "tpch", "Nation", true, true, 1, $$56, 1, $$56, true, true, true) [cardinality: 27.78, op-cost: 67.78, total-cost: 107.78]
                         -- BTREE_SEARCH  |PARTITIONED|
                           exchange [cardinality: 0.0, op-cost: 0.0, total-cost: 0.0]
                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                            order (ASC, $$56) [cardinality: 25.97, op-cost: 65.97, total-cost: 105.97]
+                            order (ASC, $$56) [cardinality: 27.78, op-cost: 67.78, total-cost: 107.78]
                             -- STABLE_SORT [$$56(ASC)]  |PARTITIONED|
                               exchange [cardinality: 0.0, op-cost: 0.0, total-cost: 0.0]
                               -- HASH_PARTITION_EXCHANGE [$$56]  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/results_cbo/leftouterjoin/index-only-leftouterjoin/index-only-leftouterjoin.007.plan b/asterixdb/asterix-app/src/test/resources/runtimets/results_cbo/leftouterjoin/index-only-leftouterjoin/index-only-leftouterjoin.007.plan
index 3cdb964..160636d 100644
--- a/asterixdb/asterix-app/src/test/resources/runtimets/results_cbo/leftouterjoin/index-only-leftouterjoin/index-only-leftouterjoin.007.plan
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/results_cbo/leftouterjoin/index-only-leftouterjoin/index-only-leftouterjoin.007.plan
@@ -1,16 +1,16 @@
-distribute result [$$52] [cardinality: 4.0, op-cost: 0.0, total-cost: 30.0]
+distribute result [$$52] [cardinality: 6.0, op-cost: 0.0, total-cost: 39.51]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
-  exchange [cardinality: 4.0, op-cost: 0.0, total-cost: 30.0]
+  exchange [cardinality: 6.0, op-cost: 0.0, total-cost: 39.51]
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-    assign [$$52] <- [{"t1_id": $$53, "t2_id": $$54}] project: [$$52] [cardinality: 4.0, op-cost: 0.0, total-cost: 30.0]
+    assign [$$52] <- [{"t1_id": $$53, "t2_id": $$54}] project: [$$52] [cardinality: 6.0, op-cost: 0.0, total-cost: 39.51]
     -- ASSIGN  |PARTITIONED|
-      exchange [cardinality: 4.0, op-cost: 0.0, total-cost: 30.0]
+      exchange [cardinality: 6.0, op-cost: 0.0, total-cost: 39.51]
       -- SORT_MERGE_EXCHANGE [$$53(ASC), $$54(ASC) ]  |PARTITIONED|
-        order (ASC, $$53) (ASC, $$54) [cardinality: 4.0, op-cost: 8.0, total-cost: 30.0]
+        order (ASC, $$53) (ASC, $$54) [cardinality: 6.0, op-cost: 15.51, total-cost: 39.51]
         -- STABLE_SORT [$$53(ASC), $$54(ASC)]  |PARTITIONED|
-          exchange [cardinality: 4.0, op-cost: 0.0, total-cost: 22.0]
+          exchange [cardinality: 6.0, op-cost: 0.0, total-cost: 24.0]
           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-            select ($$62) project: [$$53, $$54] [cardinality: 4.0, op-cost: 12.0, total-cost: 22.0]
+            select ($$62) project: [$$53, $$54] [cardinality: 6.0, op-cost: 14.0, total-cost: 24.0]
             -- STREAM_SELECT  |PARTITIONED|
               window-aggregate [$$62] <- [win-mark-first-missing-impl($$54)] partition [$$53] order (DESC, $$54) [cardinality: 2.0, op-cost: 0.0, total-cost: 2.0]
               -- WINDOW_STREAM  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/results_cbo/leftouterjoin/index-only-leftouterjoin/index-only-leftouterjoin.008.plan b/asterixdb/asterix-app/src/test/resources/runtimets/results_cbo/leftouterjoin/index-only-leftouterjoin/index-only-leftouterjoin.008.plan
index a1ce543..5efb1b8 100644
--- a/asterixdb/asterix-app/src/test/resources/runtimets/results_cbo/leftouterjoin/index-only-leftouterjoin/index-only-leftouterjoin.008.plan
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/results_cbo/leftouterjoin/index-only-leftouterjoin/index-only-leftouterjoin.008.plan
@@ -1,16 +1,16 @@
-distribute result [$$52] [cardinality: 4.0, op-cost: 0.0, total-cost: 30.0]
+distribute result [$$52] [cardinality: 6.0, op-cost: 0.0, total-cost: 39.51]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
-  exchange [cardinality: 4.0, op-cost: 0.0, total-cost: 30.0]
+  exchange [cardinality: 6.0, op-cost: 0.0, total-cost: 39.51]
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-    assign [$$52] <- [{"t1_id": $$73, "t2_id": $$54}] project: [$$52] [cardinality: 4.0, op-cost: 0.0, total-cost: 30.0]
+    assign [$$52] <- [{"t1_id": $$73, "t2_id": $$54}] project: [$$52] [cardinality: 6.0, op-cost: 0.0, total-cost: 39.51]
     -- ASSIGN  |PARTITIONED|
-      exchange [cardinality: 4.0, op-cost: 0.0, total-cost: 30.0]
+      exchange [cardinality: 6.0, op-cost: 0.0, total-cost: 39.51]
       -- SORT_MERGE_EXCHANGE [$$73(ASC), $$54(ASC) ]  |PARTITIONED|
-        order (ASC, $$73) (ASC, $$54) [cardinality: 4.0, op-cost: 8.0, total-cost: 30.0]
+        order (ASC, $$73) (ASC, $$54) [cardinality: 6.0, op-cost: 15.51, total-cost: 39.51]
         -- STABLE_SORT [$$73(ASC), $$54(ASC)]  |PARTITIONED|
-          exchange [cardinality: 4.0, op-cost: 0.0, total-cost: 22.0]
+          exchange [cardinality: 6.0, op-cost: 0.0, total-cost: 24.0]
           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-            select ($$74) project: [$$73, $$54] [cardinality: 4.0, op-cost: 12.0, total-cost: 22.0]
+            select ($$74) project: [$$73, $$54] [cardinality: 6.0, op-cost: 14.0, total-cost: 24.0]
             -- STREAM_SELECT  |PARTITIONED|
               window-aggregate [$$74] <- [win-mark-first-missing-impl($$54)] partition [$$73] order (DESC, $$54) [cardinality: 2.0, op-cost: 0.0, total-cost: 2.0]
               -- WINDOW_STREAM  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/results_cbo/leftouterjoin/index-only-leftouterjoin/index-only-leftouterjoin.009.plan b/asterixdb/asterix-app/src/test/resources/runtimets/results_cbo/leftouterjoin/index-only-leftouterjoin/index-only-leftouterjoin.009.plan
index cb47744..76995db 100644
--- a/asterixdb/asterix-app/src/test/resources/runtimets/results_cbo/leftouterjoin/index-only-leftouterjoin/index-only-leftouterjoin.009.plan
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/results_cbo/leftouterjoin/index-only-leftouterjoin/index-only-leftouterjoin.009.plan
@@ -1,16 +1,16 @@
-distribute result [$$52] [cardinality: 4.0, op-cost: 0.0, total-cost: 30.0]
+distribute result [$$52] [cardinality: 6.0, op-cost: 0.0, total-cost: 39.51]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
-  exchange [cardinality: 4.0, op-cost: 0.0, total-cost: 30.0]
+  exchange [cardinality: 6.0, op-cost: 0.0, total-cost: 39.51]
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-    assign [$$52] <- [{"t1_id": $$53, "t2_id": $$54}] project: [$$52] [cardinality: 4.0, op-cost: 0.0, total-cost: 30.0]
+    assign [$$52] <- [{"t1_id": $$53, "t2_id": $$54}] project: [$$52] [cardinality: 6.0, op-cost: 0.0, total-cost: 39.51]
     -- ASSIGN  |PARTITIONED|
-      exchange [cardinality: 4.0, op-cost: 0.0, total-cost: 30.0]
+      exchange [cardinality: 6.0, op-cost: 0.0, total-cost: 39.51]
       -- SORT_MERGE_EXCHANGE [$$53(ASC), $$54(ASC) ]  |PARTITIONED|
-        order (ASC, $$53) (ASC, $$54) [cardinality: 4.0, op-cost: 8.0, total-cost: 30.0]
+        order (ASC, $$53) (ASC, $$54) [cardinality: 6.0, op-cost: 15.51, total-cost: 39.51]
         -- STABLE_SORT [$$53(ASC), $$54(ASC)]  |PARTITIONED|
-          exchange [cardinality: 4.0, op-cost: 0.0, total-cost: 22.0]
+          exchange [cardinality: 6.0, op-cost: 0.0, total-cost: 24.0]
           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-            select ($$62) project: [$$53, $$54] [cardinality: 4.0, op-cost: 12.0, total-cost: 22.0]
+            select ($$62) project: [$$53, $$54] [cardinality: 6.0, op-cost: 14.0, total-cost: 24.0]
             -- STREAM_SELECT  |PARTITIONED|
               window-aggregate [$$62] <- [win-mark-first-missing-impl($$54)] partition [$$53] order (DESC, $$54) [cardinality: 2.0, op-cost: 0.0, total-cost: 2.0]
               -- WINDOW_STREAM  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/results_cbo/leftouterjoin/index-only-leftouterjoin/index-only-leftouterjoin.010.plan b/asterixdb/asterix-app/src/test/resources/runtimets/results_cbo/leftouterjoin/index-only-leftouterjoin/index-only-leftouterjoin.010.plan
index 7c03799..567ccef 100644
--- a/asterixdb/asterix-app/src/test/resources/runtimets/results_cbo/leftouterjoin/index-only-leftouterjoin/index-only-leftouterjoin.010.plan
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/results_cbo/leftouterjoin/index-only-leftouterjoin/index-only-leftouterjoin.010.plan
@@ -1,16 +1,16 @@
-distribute result [$$52] [cardinality: 4.0, op-cost: 0.0, total-cost: 30.0]
+distribute result [$$52] [cardinality: 6.0, op-cost: 0.0, total-cost: 39.51]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
-  exchange [cardinality: 4.0, op-cost: 0.0, total-cost: 30.0]
+  exchange [cardinality: 6.0, op-cost: 0.0, total-cost: 39.51]
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-    assign [$$52] <- [{"t1_id": $$73, "t2_id": $$54}] project: [$$52] [cardinality: 4.0, op-cost: 0.0, total-cost: 30.0]
+    assign [$$52] <- [{"t1_id": $$73, "t2_id": $$54}] project: [$$52] [cardinality: 6.0, op-cost: 0.0, total-cost: 39.51]
     -- ASSIGN  |PARTITIONED|
-      exchange [cardinality: 4.0, op-cost: 0.0, total-cost: 30.0]
+      exchange [cardinality: 6.0, op-cost: 0.0, total-cost: 39.51]
       -- SORT_MERGE_EXCHANGE [$$73(ASC), $$54(ASC) ]  |PARTITIONED|
-        order (ASC, $$73) (ASC, $$54) [cardinality: 4.0, op-cost: 8.0, total-cost: 30.0]
+        order (ASC, $$73) (ASC, $$54) [cardinality: 6.0, op-cost: 15.51, total-cost: 39.51]
         -- STABLE_SORT [$$73(ASC), $$54(ASC)]  |PARTITIONED|
-          exchange [cardinality: 4.0, op-cost: 0.0, total-cost: 22.0]
+          exchange [cardinality: 6.0, op-cost: 0.0, total-cost: 24.0]
           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-            select ($$74) project: [$$73, $$54] [cardinality: 4.0, op-cost: 12.0, total-cost: 22.0]
+            select ($$74) project: [$$73, $$54] [cardinality: 6.0, op-cost: 14.0, total-cost: 24.0]
             -- STREAM_SELECT  |PARTITIONED|
               window-aggregate [$$74] <- [win-mark-first-missing-impl($$54)] partition [$$73] order (DESC, $$54) [cardinality: 2.0, op-cost: 0.0, total-cost: 2.0]
               -- WINDOW_STREAM  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/results_cbo/limit/push-limit-to-primary-scan-select/push-limit-to-primary-scan-select.5.plan b/asterixdb/asterix-app/src/test/resources/runtimets/results_cbo/limit/push-limit-to-primary-scan-select/push-limit-to-primary-scan-select.5.plan
index 381096d..abe93b6 100644
--- a/asterixdb/asterix-app/src/test/resources/runtimets/results_cbo/limit/push-limit-to-primary-scan-select/push-limit-to-primary-scan-select.5.plan
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/results_cbo/limit/push-limit-to-primary-scan-select/push-limit-to-primary-scan-select.5.plan
@@ -1,20 +1,20 @@
-distribute result [$$37] [cardinality: 63.37, op-cost: 0.0, total-cost: 308.0]
+distribute result [$$37] [cardinality: 100.0, op-cost: 0.0, total-cost: 308.0]
 -- DISTRIBUTE_RESULT  |UNPARTITIONED|
-  exchange [cardinality: 63.37, op-cost: 0.0, total-cost: 308.0]
+  exchange [cardinality: 100.0, op-cost: 0.0, total-cost: 308.0]
   -- ONE_TO_ONE_EXCHANGE  |UNPARTITIONED|
-    limit 2 [cardinality: 63.37, op-cost: 0.0, total-cost: 308.0]
+    limit 2 [cardinality: 100.0, op-cost: 0.0, total-cost: 308.0]
     -- STREAM_LIMIT  |UNPARTITIONED|
-      exchange [cardinality: 63.37, op-cost: 0.0, total-cost: 308.0]
+      exchange [cardinality: 100.0, op-cost: 0.0, total-cost: 308.0]
       -- RANDOM_MERGE_EXCHANGE  |PARTITIONED|
-        assign [$$37] <- [{"dblpid": $$38}] project: [$$37] [cardinality: 63.37, op-cost: 0.0, total-cost: 308.0]
+        assign [$$37] <- [{"dblpid": $$38}] project: [$$37] [cardinality: 100.0, op-cost: 0.0, total-cost: 308.0]
         -- ASSIGN  |PARTITIONED|
-          limit 2 [cardinality: 63.37, op-cost: 0.0, total-cost: 308.0]
+          limit 2 [cardinality: 100.0, op-cost: 0.0, total-cost: 308.0]
           -- STREAM_LIMIT  |PARTITIONED|
-            project ([$$38]) [cardinality: 63.37, op-cost: 0.0, total-cost: 308.0]
+            project ([$$38]) [cardinality: 100.0, op-cost: 0.0, total-cost: 308.0]
             -- STREAM_PROJECT  |PARTITIONED|
-              exchange [cardinality: 63.37, op-cost: 0.0, total-cost: 308.0]
+              exchange [cardinality: 100.0, op-cost: 0.0, total-cost: 308.0]
               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                join (eq($$38, $$41)) [cardinality: 63.37, op-cost: 104.0, total-cost: 308.0]
+                join (eq($$38, $$41)) [cardinality: 100.0, op-cost: 104.0, total-cost: 308.0]
                 -- HYBRID_HASH_JOIN [$$38][$$41]  |PARTITIONED|
                   exchange [cardinality: 100.0, op-cost: 0.0, total-cost: 100.0]
                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/results_cbo/tpch/query-plans/query-plans.04.plan b/asterixdb/asterix-app/src/test/resources/runtimets/results_cbo/tpch/query-plans/query-plans.04.plan
index 8b8c184..66fe341 100644
--- a/asterixdb/asterix-app/src/test/resources/runtimets/results_cbo/tpch/query-plans/query-plans.04.plan
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/results_cbo/tpch/query-plans/query-plans.04.plan
@@ -38,166 +38,170 @@
                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
                                       join (and(eq($$250, $$203), eq($$202, $$231))) [cardinality: 0.0, op-cost: 0.0, total-cost: 0.0]
                                       -- HYBRID_HASH_JOIN [$$250, $$231][$$203, $$202]  |PARTITIONED|
-                                        exchange [cardinality: 33.96, op-cost: 0.0, total-cost: 402536.81]
+                                        exchange [cardinality: 37.63, op-cost: 0.0, total-cost: 20000.0]
                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                          assign [$$231] <- [get-item($$181, 0)] project: [$$250, $$244, $$231] [cardinality: 33.96, op-cost: 0.0, total-cost: 402536.81]
+                                          assign [$$231] <- [get-item($$181, 0)] project: [$$250, $$244, $$231] [cardinality: 37.63, op-cost: 0.0, total-cost: 20000.0]
                                           -- ASSIGN  |PARTITIONED|
-                                            exchange [cardinality: 33.96, op-cost: 0.0, total-cost: 402536.81]
+                                            exchange [cardinality: 37.63, op-cost: 0.0, total-cost: 20000.0]
                                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
                                               group by ([$$250 := $$200]) decor ([$$244]) {
                                                         aggregate [$$181] <- [listify($$215)] [cardinality: 0.0, op-cost: 0.0, total-cost: 0.0]
                                                         -- AGGREGATE  |LOCAL|
                                                           aggregate [$$215] <- [agg-sql-min($$208)] [cardinality: 0.0, op-cost: 0.0, total-cost: 0.0]
                                                           -- AGGREGATE  |LOCAL|
-                                                            nested tuple source [cardinality: 0.0, op-cost: 0.0, total-cost: 0.0]
-                                                            -- NESTED_TUPLE_SOURCE  |LOCAL|
-                                                     } [cardinality: 0.0, op-cost: 0.0, total-cost: 402536.81]
+                                                            select (not(is-missing($$249))) [cardinality: 0.0, op-cost: 0.0, total-cost: 0.0]
+                                                            -- STREAM_SELECT  |LOCAL|
+                                                              nested tuple source [cardinality: 0.0, op-cost: 0.0, total-cost: 0.0]
+                                                              -- NESTED_TUPLE_SOURCE  |LOCAL|
+                                                     } [cardinality: 0.0, op-cost: 0.0, total-cost: 20000.0]
                                               -- PRE_CLUSTERED_GROUP_BY[$$200]  |PARTITIONED|
-                                                exchange [cardinality: 33.96, op-cost: 0.0, total-cost: 402536.81]
+                                                exchange [cardinality: 37.63, op-cost: 0.0, total-cost: 20000.0]
                                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                  order (ASC, $$200) [cardinality: 33.96, op-cost: 0.0, total-cost: 402536.81]
+                                                  order (ASC, $$200) [cardinality: 37.63, op-cost: 0.0, total-cost: 20000.0]
                                                   -- STABLE_SORT [$$200(ASC)]  |PARTITIONED|
-                                                    exchange [cardinality: 33.96, op-cost: 0.0, total-cost: 402536.81]
-                                                    -- HASH_PARTITION_EXCHANGE [$$200]  |PARTITIONED|
-                                                      project ([$$244, $$208, $$200]) [cardinality: 33.96, op-cost: 0.0, total-cost: 402536.81]
+                                                    exchange [cardinality: 37.63, op-cost: 0.0, total-cost: 20000.0]
+                                                    -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                      project ([$$244, $$208, $$249, $$200]) [cardinality: 37.63, op-cost: 0.0, total-cost: 20000.0]
                                                       -- STREAM_PROJECT  |PARTITIONED|
-                                                        exchange [cardinality: 33.96, op-cost: 0.0, total-cost: 402536.81]
+                                                        exchange [cardinality: 37.63, op-cost: 0.0, total-cost: 20000.0]
                                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                          join (eq($$218, $$213)) [cardinality: 33.96, op-cost: 156.81, total-cost: 402536.81]
-                                                          -- HYBRID_HASH_JOIN [$$218][$$213]  |PARTITIONED|
-                                                            exchange [cardinality: 152.81, op-cost: 0.0, total-cost: 402371.01]
-                                                            -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                              project ([$$244, $$208, $$200, $$218]) [cardinality: 152.81, op-cost: 0.0, total-cost: 402371.01]
+                                                          left outer join (eq($$207, $$200)) [cardinality: 30.16, op-cost: 16067.92, total-cost: 394475.1]
+                                                          -- HYBRID_HASH_JOIN [$$200][$$207]  |PARTITIONED|
+                                                            exchange [cardinality: 37.63, op-cost: 0.0, total-cost: 20000.0]
+                                                            -- HASH_PARTITION_EXCHANGE [$$200]  |PARTITIONED|
+                                                              select (and(eq($$p.getField(5), 37), like($$p.getField(4), "%COPPER"))) project: [$$244, $$200] [cardinality: 37.63, op-cost: 0.0, total-cost: 20000.0]
+                                                              -- STREAM_SELECT  |PARTITIONED|
+                                                                assign [$$244] <- [$$p.getField(2)] [cardinality: 20000.0, op-cost: 0.0, total-cost: 20000.0]
+                                                                -- ASSIGN  |PARTITIONED|
+                                                                  exchange [cardinality: 20000.0, op-cost: 0.0, total-cost: 20000.0]
+                                                                  -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                    data-scan []<-[$$200, $$p] <- tpch.part [cardinality: 20000.0, op-cost: 20000.0, total-cost: 20000.0]
+                                                                    -- DATASOURCE_SCAN  |PARTITIONED|
+                                                                      exchange [cardinality: 0.0, op-cost: 0.0, total-cost: 0.0]
+                                                                      -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                        empty-tuple-source [cardinality: 0.0, op-cost: 0.0, total-cost: 0.0]
+                                                                        -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                                                            exchange [cardinality: 0.0, op-cost: 0.0, total-cost: 0.0]
+                                                            -- HASH_PARTITION_EXCHANGE [$$207]  |PARTITIONED|
+                                                              project ([$$208, $$249, $$207]) [cardinality: 0.0, op-cost: 0.0, total-cost: 0.0]
                                                               -- STREAM_PROJECT  |PARTITIONED|
-                                                                exchange [cardinality: 152.81, op-cost: 0.0, total-cost: 402371.01]
+                                                                exchange [cardinality: 0.0, op-cost: 0.0, total-cost: 0.0]
                                                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                                  join (eq($$223, $$212)) [cardinality: 152.81, op-cost: 173.99, total-cost: 402371.01]
-                                                                  -- HYBRID_HASH_JOIN [$$223][$$212]  |PARTITIONED|
-                                                                    exchange [cardinality: 987.0, op-cost: 148.99, total-cost: 1148.99]
-                                                                    -- HASH_PARTITION_EXCHANGE [$$223]  |PARTITIONED|
-                                                                      assign [$$223] <- [$$s2.getField(3)] project: [$$244, $$208, $$200, $$223] [cardinality: 987.0, op-cost: 0.0, total-cost: 1000.0]
+                                                                  join (eq($$207, $$209)) [cardinality: 16030.29, op-cost: 36033.87, total-cost: 342339.25]
+                                                                  -- HYBRID_HASH_JOIN [$$209][$$207]  |PARTITIONED|
+                                                                    exchange [cardinality: 0.0, op-cost: 0.0, total-cost: 0.0]
+                                                                    -- HASH_PARTITION_EXCHANGE [$$209]  |PARTITIONED|
+                                                                      assign [$$249] <- [true] [cardinality: 0.0, op-cost: 0.0, total-cost: 0.0]
                                                                       -- ASSIGN  |PARTITIONED|
-                                                                        project ([$$208, $$244, $$200, $$s2]) [cardinality: 987.0, op-cost: 0.0, total-cost: 1000.0]
+                                                                        project ([$$208, $$209]) [cardinality: 0.0, op-cost: 0.0, total-cost: 0.0]
                                                                         -- STREAM_PROJECT  |PARTITIONED|
-                                                                          exchange [cardinality: 987.0, op-cost: 148.99, total-cost: 1148.99]
+                                                                          exchange [cardinality: 0.0, op-cost: 0.0, total-cost: 0.0]
                                                                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                                            unnest-map [$$211, $$s2] <- index-search("supplier", 0, "Default", "tpch", "supplier", true, true, 1, $$210, 1, $$210, true, true, true) [cardinality: 987.0, op-cost: 1000.0, total-cost: 1000.0]
-                                                                            -- BTREE_SEARCH  |PARTITIONED|
+                                                                            join (eq($$218, $$213)) [cardinality: 16015.05, op-cost: 80079.26, total-cost: 250271.52]
+                                                                            -- HYBRID_HASH_JOIN [$$218][$$213]  |PARTITIONED|
                                                                               exchange [cardinality: 0.0, op-cost: 0.0, total-cost: 0.0]
                                                                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                                                order (ASC, $$210) [cardinality: 987.0, op-cost: 1000.0, total-cost: 1000.0]
-                                                                                -- STABLE_SORT [$$210(ASC)]  |PARTITIONED|
+                                                                                project ([$$208, $$209, $$218]) [cardinality: 0.0, op-cost: 0.0, total-cost: 0.0]
+                                                                                -- STREAM_PROJECT  |PARTITIONED|
                                                                                   exchange [cardinality: 0.0, op-cost: 0.0, total-cost: 0.0]
-                                                                                  -- HASH_PARTITION_EXCHANGE [$$210]  |PARTITIONED|
-                                                                                    project ([$$208, $$210, $$244, $$200]) [cardinality: 0.0, op-cost: 0.0, total-cost: 0.0]
-                                                                                    -- STREAM_PROJECT  |PARTITIONED|
+                                                                                  -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                    join (eq($$211, $$210)) [cardinality: 80075.26, op-cost: 84023.26, total-cost: 170183.26]
+                                                                                    -- HYBRID_HASH_JOIN [$$210][$$211]  |PARTITIONED|
                                                                                       exchange [cardinality: 0.0, op-cost: 0.0, total-cost: 0.0]
                                                                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                                                        left outer join (eq($$207, $$200)) [cardinality: 150.8, op-cost: 80301.99, total-cost: 400640.65]
-                                                                                        -- HYBRID_HASH_JOIN [$$207][$$200]  |PARTITIONED|
+                                                                                        replicate [cardinality: 80000.0, op-cost: 0.0, total-cost: 80000.0]
+                                                                                        -- REPLICATE  |PARTITIONED|
+                                                                                          exchange [cardinality: 80000.0, op-cost: 0.0, total-cost: 80000.0]
+                                                                                          -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                            project ([$$208, $$209, $$210]) [cardinality: 80000.0, op-cost: 0.0, total-cost: 80000.0]
+                                                                                            -- STREAM_PROJECT  |PARTITIONED|
+                                                                                              exchange [cardinality: 80000.0, op-cost: 0.0, total-cost: 80000.0]
+                                                                                              -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                data-scan []<-[$$208, $$209, $$210, $$ps2] <- tpch.partsupp [cardinality: 80000.0, op-cost: 80000.0, total-cost: 80000.0]
+                                                                                                -- DATASOURCE_SCAN  |PARTITIONED|
+                                                                                                  exchange [cardinality: 0.0, op-cost: 0.0, total-cost: 0.0]
+                                                                                                  -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                    empty-tuple-source [cardinality: 0.0, op-cost: 0.0, total-cost: 0.0]
+                                                                                                    -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                                                                                      exchange [cardinality: 0.0, op-cost: 0.0, total-cost: 0.0]
+                                                                                      -- BROADCAST_EXCHANGE  |PARTITIONED|
+                                                                                        project ([$$218, $$211]) [cardinality: 0.0, op-cost: 0.0, total-cost: 0.0]
+                                                                                        -- STREAM_PROJECT  |PARTITIONED|
                                                                                           exchange [cardinality: 0.0, op-cost: 0.0, total-cost: 0.0]
                                                                                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                                                            project ([$$208, $$210, $$207]) [cardinality: 0.0, op-cost: 0.0, total-cost: 0.0]
-                                                                                            -- STREAM_PROJECT  |PARTITIONED|
+                                                                                            join (eq($$223, $$212)) [cardinality: 987.0, op-cost: 1087.0, total-cost: 2212.0]
+                                                                                            -- HYBRID_HASH_JOIN [$$223][$$212]  |PARTITIONED|
                                                                                               exchange [cardinality: 0.0, op-cost: 0.0, total-cost: 0.0]
                                                                                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                                                                join (eq($$207, $$209)) [cardinality: 80151.47, op-cost: 100094.07, total-cost: 300188.15]
-                                                                                                -- HYBRID_HASH_JOIN [$$209][$$207]  |PARTITIONED|
-                                                                                                  exchange [cardinality: 0.0, op-cost: 0.0, total-cost: 0.0]
-                                                                                                  -- HASH_PARTITION_EXCHANGE [$$209]  |PARTITIONED|
-                                                                                                    replicate [cardinality: 80000.0, op-cost: 0.0, total-cost: 80000.0]
-                                                                                                    -- REPLICATE  |PARTITIONED|
-                                                                                                      exchange [cardinality: 80000.0, op-cost: 0.0, total-cost: 80000.0]
-                                                                                                      -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                                                                        project ([$$208, $$210, $$209]) [cardinality: 80000.0, op-cost: 0.0, total-cost: 80000.0]
-                                                                                                        -- STREAM_PROJECT  |PARTITIONED|
-                                                                                                          exchange [cardinality: 80000.0, op-cost: 0.0, total-cost: 80000.0]
-                                                                                                          -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                                                                            data-scan []<-[$$208, $$209, $$210, $$ps2] <- tpch.partsupp [cardinality: 80000.0, op-cost: 80000.0, total-cost: 80000.0]
-                                                                                                            -- DATASOURCE_SCAN  |PARTITIONED|
-                                                                                                              exchange [cardinality: 0.0, op-cost: 0.0, total-cost: 0.0]
-                                                                                                              -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                                                                                empty-tuple-source [cardinality: 0.0, op-cost: 0.0, total-cost: 0.0]
-                                                                                                                -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
-                                                                                                  exchange [cardinality: 0.0, op-cost: 0.0, total-cost: 0.0]
-                                                                                                  -- HASH_PARTITION_EXCHANGE [$$207]  |PARTITIONED|
-                                                                                                    project ([$$207]) [cardinality: 0.0, op-cost: 0.0, total-cost: 0.0]
-                                                                                                    -- STREAM_PROJECT  |PARTITIONED|
-                                                                                                      exchange [cardinality: 0.0, op-cost: 0.0, total-cost: 0.0]
-                                                                                                      -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                                                                        replicate [cardinality: 0.0, op-cost: 0.0, total-cost: 0.0]
-                                                                                                        -- REPLICATE  |PARTITIONED|
-                                                                                                          exchange [cardinality: 0.0, op-cost: 0.0, total-cost: 0.0]
-                                                                                                          -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                                                                            data-scan []<-[$$207, $$p2] <- tpch.part [cardinality: 20000.0, op-cost: 20000.0, total-cost: 20000.0]
-                                                                                                            -- DATASOURCE_SCAN  |PARTITIONED|
-                                                                                                              exchange [cardinality: 0.0, op-cost: 0.0, total-cost: 0.0]
-                                                                                                              -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                                                                                empty-tuple-source [cardinality: 0.0, op-cost: 0.0, total-cost: 0.0]
-                                                                                                                -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
-                                                                                          exchange [cardinality: 0.0, op-cost: 0.0, total-cost: 0.0]
-                                                                                          -- BROADCAST_EXCHANGE  |PARTITIONED|
-                                                                                            select (and(eq($$p.getField(5), 37), like($$p.getField(4), "%COPPER"))) project: [$$244, $$200] [cardinality: 37.63, op-cost: 0.0, total-cost: 20000.0]
-                                                                                            -- STREAM_SELECT  |PARTITIONED|
-                                                                                              assign [$$244] <- [$$p.getField(2)] [cardinality: 0.0, op-cost: 0.0, total-cost: 0.0]
-                                                                                              -- ASSIGN  |PARTITIONED|
-                                                                                                assign [$$200, $$p] <- [$$207, $$p2] project: [$$200, $$p] [cardinality: 0.0, op-cost: 0.0, total-cost: 0.0]
+                                                                                                assign [$$223] <- [$$s2.getField(3)] project: [$$211, $$223] [cardinality: 0.0, op-cost: 0.0, total-cost: 0.0]
                                                                                                 -- ASSIGN  |PARTITIONED|
                                                                                                   exchange [cardinality: 0.0, op-cost: 0.0, total-cost: 0.0]
                                                                                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                                                                    replicate [cardinality: 0.0, op-cost: 0.0, total-cost: 0.0]
+                                                                                                    replicate [cardinality: 1000.0, op-cost: 0.0, total-cost: 1000.0]
                                                                                                     -- REPLICATE  |PARTITIONED|
-                                                                                                      exchange [cardinality: 0.0, op-cost: 0.0, total-cost: 0.0]
+                                                                                                      exchange [cardinality: 1000.0, op-cost: 3948.0, total-cost: 4948.0]
                                                                                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                                                                        data-scan []<-[$$207, $$p2] <- tpch.part [cardinality: 20000.0, op-cost: 20000.0, total-cost: 20000.0]
+                                                                                                        data-scan []<-[$$211, $$s2] <- tpch.supplier [cardinality: 1000.0, op-cost: 1000.0, total-cost: 1000.0]
                                                                                                         -- DATASOURCE_SCAN  |PARTITIONED|
                                                                                                           exchange [cardinality: 0.0, op-cost: 0.0, total-cost: 0.0]
                                                                                                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
                                                                                                             empty-tuple-source [cardinality: 0.0, op-cost: 0.0, total-cost: 0.0]
                                                                                                             -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
-                                                                    exchange [cardinality: 25.0, op-cost: 25.0, total-cost: 50.0]
-                                                                    -- HASH_PARTITION_EXCHANGE [$$212]  |PARTITIONED|
-                                                                      assign [$$218] <- [$$n2.getField(2)] project: [$$218, $$212] [cardinality: 25.0, op-cost: 0.0, total-cost: 25.0]
-                                                                      -- ASSIGN  |PARTITIONED|
-                                                                        exchange [cardinality: 25.0, op-cost: 25.0, total-cost: 50.0]
-                                                                        -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                                          replicate [cardinality: 25.0, op-cost: 0.0, total-cost: 25.0]
-                                                                          -- REPLICATE  |PARTITIONED|
-                                                                            exchange [cardinality: 25.0, op-cost: 0.0, total-cost: 25.0]
-                                                                            -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                                              data-scan []<-[$$212, $$n2] <- tpch.nation [cardinality: 25.0, op-cost: 25.0, total-cost: 25.0]
-                                                                              -- DATASOURCE_SCAN  |PARTITIONED|
-                                                                                exchange [cardinality: 0.0, op-cost: 0.0, total-cost: 0.0]
-                                                                                -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                                                  empty-tuple-source [cardinality: 0.0, op-cost: 0.0, total-cost: 0.0]
-                                                                                  -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
-                                                            exchange [cardinality: 1.0, op-cost: 4.0, total-cost: 9.0]
-                                                            -- BROADCAST_EXCHANGE  |PARTITIONED|
-                                                              replicate [cardinality: 1.0, op-cost: 0.0, total-cost: 5.0]
-                                                              -- REPLICATE  |PARTITIONED|
-                                                                exchange [cardinality: 1.0, op-cost: 0.0, total-cost: 5.0]
-                                                                -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                                  select (eq($$r2.getField(1), "EUROPE")) project: [$$213] [cardinality: 1.0, op-cost: 0.0, total-cost: 5.0]
-                                                                  -- STREAM_SELECT  |PARTITIONED|
-                                                                    exchange [cardinality: 5.0, op-cost: 0.0, total-cost: 5.0]
-                                                                    -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                                      data-scan []<-[$$213, $$r2] <- tpch.region [cardinality: 5.0, op-cost: 5.0, total-cost: 5.0]
-                                                                      -- DATASOURCE_SCAN  |PARTITIONED|
+                                                                                              exchange [cardinality: 0.0, op-cost: 0.0, total-cost: 0.0]
+                                                                                              -- BROADCAST_EXCHANGE  |PARTITIONED|
+                                                                                                assign [$$218] <- [$$n2.getField(2)] project: [$$218, $$212] [cardinality: 0.0, op-cost: 0.0, total-cost: 0.0]
+                                                                                                -- ASSIGN  |PARTITIONED|
+                                                                                                  exchange [cardinality: 0.0, op-cost: 0.0, total-cost: 0.0]
+                                                                                                  -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                    replicate [cardinality: 25.0, op-cost: 0.0, total-cost: 25.0]
+                                                                                                    -- REPLICATE  |PARTITIONED|
+                                                                                                      exchange [cardinality: 25.0, op-cost: 0.0, total-cost: 25.0]
+                                                                                                      -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                        data-scan []<-[$$212, $$n2] <- tpch.nation [cardinality: 25.0, op-cost: 25.0, total-cost: 25.0]
+                                                                                                        -- DATASOURCE_SCAN  |PARTITIONED|
+                                                                                                          exchange [cardinality: 0.0, op-cost: 0.0, total-cost: 0.0]
+                                                                                                          -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                                            empty-tuple-source [cardinality: 0.0, op-cost: 0.0, total-cost: 0.0]
+                                                                                                            -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                                                                              exchange [cardinality: 0.0, op-cost: 0.0, total-cost: 0.0]
+                                                                              -- BROADCAST_EXCHANGE  |PARTITIONED|
+                                                                                replicate [cardinality: 1.0, op-cost: 0.0, total-cost: 5.0]
+                                                                                -- REPLICATE  |PARTITIONED|
+                                                                                  exchange [cardinality: 1.0, op-cost: 0.0, total-cost: 5.0]
+                                                                                  -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                    select (eq($$r2.getField(1), "EUROPE")) project: [$$213] [cardinality: 1.0, op-cost: 0.0, total-cost: 5.0]
+                                                                                    -- STREAM_SELECT  |PARTITIONED|
+                                                                                      exchange [cardinality: 5.0, op-cost: 0.0, total-cost: 5.0]
+                                                                                      -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                        data-scan []<-[$$213, $$r2] <- tpch.region [cardinality: 5.0, op-cost: 5.0, total-cost: 5.0]
+                                                                                        -- DATASOURCE_SCAN  |PARTITIONED|
+                                                                                          exchange [cardinality: 0.0, op-cost: 0.0, total-cost: 0.0]
+                                                                                          -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                                            empty-tuple-source [cardinality: 0.0, op-cost: 0.0, total-cost: 0.0]
+                                                                                            -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                                                                    exchange [cardinality: 0.0, op-cost: 0.0, total-cost: 0.0]
+                                                                    -- HASH_PARTITION_EXCHANGE [$$207]  |PARTITIONED|
+                                                                      project ([$$207]) [cardinality: 0.0, op-cost: 0.0, total-cost: 0.0]
+                                                                      -- STREAM_PROJECT  |PARTITIONED|
                                                                         exchange [cardinality: 0.0, op-cost: 0.0, total-cost: 0.0]
                                                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                                          empty-tuple-source [cardinality: 0.0, op-cost: 0.0, total-cost: 0.0]
-                                                                          -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
-                                        exchange [cardinality: 79109.84, op-cost: 0.0, total-cost: 168971.26]
+                                                                          data-scan []<-[$$207, $$p2] <- tpch.part [cardinality: 20000.0, op-cost: 20000.0, total-cost: 20000.0]
+                                                                          -- DATASOURCE_SCAN  |PARTITIONED|
+                                                                            exchange [cardinality: 0.0, op-cost: 0.0, total-cost: 0.0]
+                                                                            -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                              empty-tuple-source [cardinality: 0.0, op-cost: 0.0, total-cost: 0.0]
+                                                                              -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                                        exchange [cardinality: 80075.26, op-cost: 0.0, total-cost: 168971.26]
                                         -- HASH_PARTITION_EXCHANGE [$$203]  |PARTITIONED|
-                                          project ([$$237, $$239, $$245, $$246, $$247, $$225, $$203, $$202]) [cardinality: 79109.84, op-cost: 0.0, total-cost: 168971.26]
+                                          project ([$$237, $$239, $$245, $$246, $$247, $$225, $$203, $$202]) [cardinality: 80075.26, op-cost: 0.0, total-cost: 168971.26]
                                           -- STREAM_PROJECT  |PARTITIONED|
-                                            exchange [cardinality: 79109.84, op-cost: 0.0, total-cost: 168971.26]
+                                            exchange [cardinality: 80075.26, op-cost: 0.0, total-cost: 168971.26]
                                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                              join (eq($$201, $$204)) [cardinality: 79109.84, op-cost: 84023.26, total-cost: 168971.26]
+                                              join (eq($$201, $$204)) [cardinality: 80075.26, op-cost: 84023.26, total-cost: 168971.26]
                                               -- HYBRID_HASH_JOIN [$$204][$$201]  |PARTITIONED|
                                                 exchange [cardinality: 80000.0, op-cost: 0.0, total-cost: 80000.0]
                                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                  assign [$$202, $$204, $$203] <- [$$208, $$210, $$209] project: [$$202, $$204, $$203] [cardinality: 80000.0, op-cost: 0.0, total-cost: 80000.0]
+                                                  assign [$$202, $$203, $$204] <- [$$208, $$209, $$210] project: [$$202, $$203, $$204] [cardinality: 80000.0, op-cost: 0.0, total-cost: 80000.0]
                                                   -- ASSIGN  |PARTITIONED|
                                                     exchange [cardinality: 80000.0, op-cost: 0.0, total-cost: 80000.0]
                                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
@@ -205,7 +209,7 @@
                                                       -- REPLICATE  |PARTITIONED|
                                                         exchange [cardinality: 80000.0, op-cost: 0.0, total-cost: 80000.0]
                                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                          project ([$$208, $$210, $$209]) [cardinality: 80000.0, op-cost: 0.0, total-cost: 80000.0]
+                                                          project ([$$208, $$209, $$210]) [cardinality: 80000.0, op-cost: 0.0, total-cost: 80000.0]
                                                           -- STREAM_PROJECT  |PARTITIONED|
                                                             exchange [cardinality: 80000.0, op-cost: 0.0, total-cost: 80000.0]
                                                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
@@ -219,14 +223,20 @@
                                                 -- BROADCAST_EXCHANGE  |PARTITIONED|
                                                   assign [$$247, $$246, $$245, $$237, $$239, $$225] <- [$$s.getField(6), $$s.getField(4), $$s.getField(2), $$s.getField(5), $$s.getField(1), $$s.getField(3)] project: [$$237, $$239, $$245, $$246, $$247, $$225, $$201] [cardinality: 1000.0, op-cost: 0.0, total-cost: 1000.0]
                                                   -- ASSIGN  |PARTITIONED|
-                                                    exchange [cardinality: 1000.0, op-cost: 3948.0, total-cost: 4948.0]
-                                                    -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                      data-scan []<-[$$201, $$s] <- tpch.supplier [cardinality: 1000.0, op-cost: 1000.0, total-cost: 1000.0]
-                                                      -- DATASOURCE_SCAN  |PARTITIONED|
-                                                        exchange [cardinality: 0.0, op-cost: 0.0, total-cost: 0.0]
-                                                        -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                          empty-tuple-source [cardinality: 0.0, op-cost: 0.0, total-cost: 0.0]
-                                                          -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                                                    assign [$$201, $$s] <- [$$211, $$s2] project: [$$201, $$s] [cardinality: 1000.0, op-cost: 0.0, total-cost: 1000.0]
+                                                    -- ASSIGN  |PARTITIONED|
+                                                      exchange [cardinality: 1000.0, op-cost: 3948.0, total-cost: 4948.0]
+                                                      -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                        replicate [cardinality: 1000.0, op-cost: 0.0, total-cost: 1000.0]
+                                                        -- REPLICATE  |PARTITIONED|
+                                                          exchange [cardinality: 1000.0, op-cost: 3948.0, total-cost: 4948.0]
+                                                          -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                            data-scan []<-[$$211, $$s2] <- tpch.supplier [cardinality: 1000.0, op-cost: 1000.0, total-cost: 1000.0]
+                                                            -- DATASOURCE_SCAN  |PARTITIONED|
+                                                              exchange [cardinality: 0.0, op-cost: 0.0, total-cost: 0.0]
+                                                              -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                                empty-tuple-source [cardinality: 0.0, op-cost: 0.0, total-cost: 0.0]
+                                                                -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
                                 exchange [cardinality: 25.0, op-cost: 0.0, total-cost: 25.0]
                                 -- HASH_PARTITION_EXCHANGE [$$205]  |PARTITIONED|
                                   assign [$$238, $$221] <- [$$n.getField(1), $$n.getField(2)] project: [$$238, $$221, $$205] [cardinality: 25.0, op-cost: 0.0, total-cost: 25.0]
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/results_cbo/tpch/query-plans/query-plans.07.plan b/asterixdb/asterix-app/src/test/resources/runtimets/results_cbo/tpch/query-plans/query-plans.07.plan
index b86afb4..91cea89 100644
--- a/asterixdb/asterix-app/src/test/resources/runtimets/results_cbo/tpch/query-plans/query-plans.07.plan
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/results_cbo/tpch/query-plans/query-plans.07.plan
@@ -1,46 +1,46 @@
-distribute result [$$149] [cardinality: 25.0, op-cost: 0.0, total-cost: 1574886.92]
+distribute result [$$149] [cardinality: 25.0, op-cost: 0.0, total-cost: 1555771.69]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
-  exchange [cardinality: 25.0, op-cost: 0.0, total-cost: 1574886.92]
+  exchange [cardinality: 25.0, op-cost: 0.0, total-cost: 1555771.69]
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-    assign [$$149] <- [{"$1": 5, "n_name": $$n_name, "revenue": $$165}] project: [$$149] [cardinality: 25.0, op-cost: 0.0, total-cost: 1574886.92]
+    assign [$$149] <- [{"$1": 5, "n_name": $$n_name, "revenue": $$165}] project: [$$149] [cardinality: 25.0, op-cost: 0.0, total-cost: 1555771.69]
     -- ASSIGN  |PARTITIONED|
-      exchange [cardinality: 25.0, op-cost: 0.0, total-cost: 1574886.92]
+      exchange [cardinality: 25.0, op-cost: 0.0, total-cost: 1555771.69]
       -- SORT_MERGE_EXCHANGE [$$165(DESC) ]  |PARTITIONED|
-        order (DESC, $$165) [cardinality: 25.0, op-cost: 116.1, total-cost: 1574886.92]
+        order (DESC, $$165) [cardinality: 25.0, op-cost: 116.1, total-cost: 1555771.69]
         -- STABLE_SORT [$$165(DESC)]  |PARTITIONED|
-          exchange [cardinality: 25.0, op-cost: 0.0, total-cost: 1574770.82]
+          exchange [cardinality: 25.0, op-cost: 0.0, total-cost: 1555655.59]
           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
             group by ([$$n_name := $$176]) decor ([]) {
                       aggregate [$$165] <- [global-sql-sum-serial($$175)] [cardinality: 0.0, op-cost: 0.0, total-cost: 0.0]
                       -- AGGREGATE  |LOCAL|
                         nested tuple source [cardinality: 0.0, op-cost: 0.0, total-cost: 0.0]
                         -- NESTED_TUPLE_SOURCE  |LOCAL|
-                   } [cardinality: 25.0, op-cost: 38494.17, total-cost: 1574770.82]
+                   } [cardinality: 25.0, op-cost: 34190.86, total-cost: 1555655.59]
             -- EXTERNAL_GROUP_BY[$$176]  |PARTITIONED|
-              exchange [cardinality: 25.0, op-cost: 0.0, total-cost: 1536276.65]
+              exchange [cardinality: 25.0, op-cost: 0.0, total-cost: 1521464.73]
               -- HASH_PARTITION_EXCHANGE [$$176]  |PARTITIONED|
                 group by ([$$176 := $$150]) decor ([]) {
                           aggregate [$$175] <- [local-sql-sum-serial(numeric-multiply($$173, numeric-subtract(1, $$174)))] [cardinality: 0.0, op-cost: 0.0, total-cost: 0.0]
                           -- AGGREGATE  |LOCAL|
                             nested tuple source [cardinality: 0.0, op-cost: 0.0, total-cost: 0.0]
                             -- NESTED_TUPLE_SOURCE  |LOCAL|
-                       } [cardinality: 25.0, op-cost: 38494.17, total-cost: 1536276.65]
+                       } [cardinality: 25.0, op-cost: 34190.86, total-cost: 1521464.73]
                 -- EXTERNAL_GROUP_BY[$$150]  |PARTITIONED|
-                  exchange [cardinality: 38494.17, op-cost: 0.0, total-cost: 1497782.48]
+                  exchange [cardinality: 34190.86, op-cost: 0.0, total-cost: 1487273.87]
                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                    project ([$$173, $$174, $$150]) [cardinality: 38494.17, op-cost: 0.0, total-cost: 1497782.48]
+                    project ([$$173, $$174, $$150]) [cardinality: 34190.86, op-cost: 0.0, total-cost: 1487273.87]
                     -- STREAM_PROJECT  |PARTITIONED|
-                      exchange [cardinality: 38494.17, op-cost: 0.0, total-cost: 1497782.48]
+                      exchange [cardinality: 34190.86, op-cost: 0.0, total-cost: 1487273.87]
                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                        join (and(eq($$154, $$160), eq($$170, $$159))) [cardinality: 38494.17, op-cost: 23429.97, total-cost: 1497782.48]
+                        join (and(eq($$154, $$160), eq($$170, $$159))) [cardinality: 34190.86, op-cost: 21043.43, total-cost: 1487273.87]
                         -- HYBRID_HASH_JOIN [$$160, $$170][$$154, $$159]  |PARTITIONED|
-                          exchange [cardinality: 19481.97, op-cost: 0.0, total-cost: 1469404.52]
+                          exchange [cardinality: 17095.43, op-cost: 0.0, total-cost: 1461282.44]
                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                            project ([$$173, $$174, $$150, $$160, $$170]) [cardinality: 19481.97, op-cost: 0.0, total-cost: 1469404.52]
+                            project ([$$173, $$174, $$150, $$160, $$170]) [cardinality: 17095.43, op-cost: 0.0, total-cost: 1461282.44]
                             -- STREAM_PROJECT  |PARTITIONED|
-                              exchange [cardinality: 19481.97, op-cost: 0.0, total-cost: 1469404.52]
+                              exchange [cardinality: 17095.43, op-cost: 0.0, total-cost: 1461282.44]
                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                join (eq($$158, $$156)) [cardinality: 19481.97, op-cost: 620582.08, total-cost: 1469404.52]
+                                join (eq($$158, $$156)) [cardinality: 17095.43, op-cost: 618200.06, total-cost: 1461282.44]
                                 -- HYBRID_HASH_JOIN [$$158][$$156]  |PARTITIONED|
                                   exchange [cardinality: 600572.0, op-cost: 0.0, total-cost: 600572.0]
                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
@@ -56,13 +56,13 @@
                                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
                                               empty-tuple-source [cardinality: 0.0, op-cost: 0.0, total-cost: 0.0]
                                               -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
-                                  exchange [cardinality: 4861.28, op-cost: 19445.1, total-cost: 248250.43]
+                                  exchange [cardinality: 4265.77, op-cost: 17063.08, total-cost: 242510.39]
                                   -- BROADCAST_EXCHANGE  |PARTITIONED|
-                                    project ([$$150, $$160, $$156]) [cardinality: 4861.28, op-cost: 0.0, total-cost: 228805.33]
+                                    project ([$$150, $$160, $$156]) [cardinality: 4265.77, op-cost: 0.0, total-cost: 225447.31]
                                     -- STREAM_PROJECT  |PARTITIONED|
-                                      exchange [cardinality: 4861.28, op-cost: 19445.1, total-cost: 248250.43]
+                                      exchange [cardinality: 4265.77, op-cost: 17063.08, total-cost: 242510.39]
                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                        join (eq($$155, $$167)) [cardinality: 4861.28, op-cost: 34995.7, total-cost: 228805.33]
+                                        join (eq($$155, $$167)) [cardinality: 4265.77, op-cost: 33318.91, total-cost: 225447.31]
                                         -- HYBRID_HASH_JOIN [$$167][$$155]  |PARTITIONED|
                                           exchange [cardinality: 21307.62, op-cost: 0.0, total-cost: 150000.0]
                                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
@@ -78,13 +78,13 @@
                                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
                                                       empty-tuple-source [cardinality: 0.0, op-cost: 0.0, total-cost: 0.0]
                                                       -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
-                                          exchange [cardinality: 3422.02, op-cost: 13688.08, total-cost: 43809.64]
+                                          exchange [cardinality: 3002.82, op-cost: 12011.29, total-cost: 42128.4]
                                           -- BROADCAST_EXCHANGE  |PARTITIONED|
-                                            project ([$$150, $$160, $$155]) [cardinality: 3422.02, op-cost: 0.0, total-cost: 30121.56]
+                                            project ([$$150, $$160, $$155]) [cardinality: 3002.82, op-cost: 0.0, total-cost: 30117.11]
                                             -- STREAM_PROJECT  |PARTITIONED|
-                                              exchange [cardinality: 3422.02, op-cost: 13688.08, total-cost: 43809.64]
+                                              exchange [cardinality: 3002.82, op-cost: 12011.29, total-cost: 42128.4]
                                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                join (eq($$153, $$160)) [cardinality: 3422.02, op-cost: 15036.33, total-cost: 30121.56]
+                                                join (eq($$153, $$160)) [cardinality: 3002.82, op-cost: 15034.11, total-cost: 30117.11]
                                                 -- HYBRID_HASH_JOIN [$$153][$$160]  |PARTITIONED|
                                                   exchange [cardinality: 15000.0, op-cost: 0.0, total-cost: 15000.0]
                                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
@@ -98,13 +98,13 @@
                                                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
                                                             empty-tuple-source [cardinality: 0.0, op-cost: 0.0, total-cost: 0.0]
                                                             -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
-                                                  exchange [cardinality: 5.56, op-cost: 22.22, total-cost: 85.22]
+                                                  exchange [cardinality: 5.0, op-cost: 20.0, total-cost: 83.0]
                                                   -- BROADCAST_EXCHANGE  |PARTITIONED|
-                                                    project ([$$150, $$160]) [cardinality: 5.56, op-cost: 0.0, total-cost: 63.0]
+                                                    project ([$$150, $$160]) [cardinality: 5.0, op-cost: 0.0, total-cost: 63.0]
                                                     -- STREAM_PROJECT  |PARTITIONED|
-                                                      exchange [cardinality: 5.56, op-cost: 22.22, total-cost: 85.22]
+                                                      exchange [cardinality: 5.0, op-cost: 20.0, total-cost: 83.0]
                                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                        join (eq($$163, $$161)) [cardinality: 5.56, op-cost: 29.0, total-cost: 63.0]
+                                                        join (eq($$163, $$161)) [cardinality: 5.0, op-cost: 29.0, total-cost: 63.0]
                                                         -- HYBRID_HASH_JOIN [$$163][$$161]  |PARTITIONED|
                                                           exchange [cardinality: 25.0, op-cost: 0.0, total-cost: 25.0]
                                                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/results_cbo/tpch/query-plans/query-plans.08.plan b/asterixdb/asterix-app/src/test/resources/runtimets/results_cbo/tpch/query-plans/query-plans.08.plan
index 4ec058a..1a2110b 100644
--- a/asterixdb/asterix-app/src/test/resources/runtimets/results_cbo/tpch/query-plans/query-plans.08.plan
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/results_cbo/tpch/query-plans/query-plans.08.plan
@@ -1,48 +1,48 @@
-distribute result [$$186] [cardinality: 2.52, op-cost: 0.0, total-cost: 991063.1]
+distribute result [$$186] [cardinality: 2.52, op-cost: 0.0, total-cost: 988897.43]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
-  exchange [cardinality: 2.52, op-cost: 0.0, total-cost: 991063.1]
+  exchange [cardinality: 2.52, op-cost: 0.0, total-cost: 988897.43]
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-    assign [$$186] <- [{"$1": 7, "supp_nation": $$supp_nation, "cust_nation": $$cust_nation, "l_year": $$l_year, "revenue": $$200}] project: [$$186] [cardinality: 2.52, op-cost: 0.0, total-cost: 991063.1]
+    assign [$$186] <- [{"$1": 7, "supp_nation": $$supp_nation, "cust_nation": $$cust_nation, "l_year": $$l_year, "revenue": $$200}] project: [$$186] [cardinality: 2.52, op-cost: 0.0, total-cost: 988897.43]
     -- ASSIGN  |PARTITIONED|
-      exchange [cardinality: 2.52, op-cost: 0.0, total-cost: 991063.1]
+      exchange [cardinality: 2.52, op-cost: 0.0, total-cost: 988897.43]
       -- SORT_MERGE_EXCHANGE [$$supp_nation(ASC), $$cust_nation(ASC), $$l_year(ASC) ]  |PARTITIONED|
-        order (ASC, $$supp_nation) (ASC, $$cust_nation) (ASC, $$l_year) [cardinality: 2.52, op-cost: 3.36, total-cost: 991063.1]
+        order (ASC, $$supp_nation) (ASC, $$cust_nation) (ASC, $$l_year) [cardinality: 2.52, op-cost: 3.36, total-cost: 988897.43]
         -- STABLE_SORT [$$supp_nation(ASC), $$cust_nation(ASC), $$l_year(ASC)]  |PARTITIONED|
-          exchange [cardinality: 2.52, op-cost: 0.0, total-cost: 991059.74]
+          exchange [cardinality: 2.52, op-cost: 0.0, total-cost: 988894.07]
           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
             group by ([$$supp_nation := $$217; $$cust_nation := $$218; $$l_year := $$219]) decor ([]) {
                       aggregate [$$200] <- [global-sql-sum-serial($$216)] [cardinality: 0.0, op-cost: 0.0, total-cost: 0.0]
                       -- AGGREGATE  |LOCAL|
                         nested tuple source [cardinality: 0.0, op-cost: 0.0, total-cost: 0.0]
                         -- NESTED_TUPLE_SOURCE  |LOCAL|
-                   } [cardinality: 2.52, op-cost: 600.05, total-cost: 991059.74]
+                   } [cardinality: 2.52, op-cost: 577.39, total-cost: 988894.07]
             -- EXTERNAL_GROUP_BY[$$217, $$218, $$219]  |PARTITIONED|
-              exchange [cardinality: 2.52, op-cost: 0.0, total-cost: 990459.69]
+              exchange [cardinality: 2.52, op-cost: 0.0, total-cost: 988316.68]
               -- HASH_PARTITION_EXCHANGE [$$217, $$218, $$219]  |PARTITIONED|
                 group by ([$$217 := $$191; $$218 := $$192; $$219 := $$214]) decor ([]) {
                           aggregate [$$216] <- [local-sql-sum-serial($$184)] [cardinality: 0.0, op-cost: 0.0, total-cost: 0.0]
                           -- AGGREGATE  |LOCAL|
                             nested tuple source [cardinality: 0.0, op-cost: 0.0, total-cost: 0.0]
                             -- NESTED_TUPLE_SOURCE  |LOCAL|
-                       } [cardinality: 2.52, op-cost: 600.05, total-cost: 990459.69]
+                       } [cardinality: 2.52, op-cost: 577.39, total-cost: 988316.68]
                 -- EXTERNAL_GROUP_BY[$$191, $$192, $$214]  |PARTITIONED|
-                  exchange [cardinality: 600.05, op-cost: 0.0, total-cost: 989859.64]
+                  exchange [cardinality: 577.39, op-cost: 0.0, total-cost: 987739.29]
                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                    assign [$$184, $$214] <- [numeric-multiply($$211, numeric-subtract(1, $$212)), get-year(date($$190))] project: [$$184, $$191, $$192, $$214] [cardinality: 600.05, op-cost: 0.0, total-cost: 989859.64]
+                    assign [$$184, $$214] <- [numeric-multiply($$211, numeric-subtract(1, $$212)), get-year(date($$190))] project: [$$184, $$191, $$192, $$214] [cardinality: 577.39, op-cost: 0.0, total-cost: 987739.29]
                     -- ASSIGN  |PARTITIONED|
-                      project ([$$191, $$192, $$211, $$212, $$190]) [cardinality: 600.05, op-cost: 0.0, total-cost: 989859.64]
+                      project ([$$191, $$192, $$211, $$212, $$190]) [cardinality: 577.39, op-cost: 0.0, total-cost: 987739.29]
                       -- STREAM_PROJECT  |PARTITIONED|
-                        exchange [cardinality: 600.05, op-cost: 0.0, total-cost: 989859.64]
+                        exchange [cardinality: 577.39, op-cost: 0.0, total-cost: 987739.29]
                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                          join (and(eq($$201, $$199), eq($$197, $$210))) [cardinality: 600.05, op-cost: 29625.83, total-cost: 989859.64]
+                          join (and(eq($$201, $$199), eq($$197, $$210))) [cardinality: 577.39, op-cost: 29434.39, total-cost: 987739.29]
                           -- HYBRID_HASH_JOIN [$$199, $$210][$$201, $$197]  |PARTITIONED|
-                            exchange [cardinality: 150141.11, op-cost: 14611.72, total-cost: 164611.72]
+                            exchange [cardinality: 150141.11, op-cost: 14420.28, total-cost: 164420.28]
                             -- HASH_PARTITION_EXCHANGE [$$199, $$210]  |PARTITIONED|
                               assign [$$210] <- [$$o.getField(1)] project: [$$191, $$192, $$211, $$212, $$190, $$199, $$210] [cardinality: 150141.11, op-cost: 0.0, total-cost: 150000.0]
                               -- ASSIGN  |PARTITIONED|
                                 project ([$$212, $$211, $$190, $$191, $$192, $$199, $$o]) [cardinality: 150141.11, op-cost: 0.0, total-cost: 150000.0]
                                 -- STREAM_PROJECT  |PARTITIONED|
-                                  exchange [cardinality: 150141.11, op-cost: 14611.72, total-cost: 164611.72]
+                                  exchange [cardinality: 150141.11, op-cost: 14420.28, total-cost: 164420.28]
                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
                                     unnest-map [$$196, $$o] <- index-search("orders", 0, "Default", "tpch", "orders", true, true, 1, $$195, 1, $$195, true, true, true) [cardinality: 150141.11, op-cost: 150000.0, total-cost: 150000.0]
                                     -- BTREE_SEARCH  |PARTITIONED|
@@ -56,7 +56,7 @@
                                             -- STREAM_PROJECT  |PARTITIONED|
                                               exchange [cardinality: 0.0, op-cost: 0.0, total-cost: 0.0]
                                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                join (eq($$193, $$204)) [cardinality: 14597.97, op-cost: 180551.78, total-cost: 784226.26]
+                                                join (eq($$193, $$204)) [cardinality: 14406.71, op-cost: 180543.69, total-cost: 784210.07]
                                                 -- HYBRID_HASH_JOIN [$$204][$$193]  |PARTITIONED|
                                                   exchange [cardinality: 0.0, op-cost: 0.0, total-cost: 0.0]
                                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
@@ -80,7 +80,7 @@
                                                     -- STREAM_PROJECT  |PARTITIONED|
                                                       exchange [cardinality: 0.0, op-cost: 0.0, total-cost: 0.0]
                                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                        join (eq($$205, $$198)) [cardinality: 80.92, op-cost: 995.4, total-cost: 2778.8]
+                                                        join (eq($$205, $$198)) [cardinality: 78.9, op-cost: 995.4, total-cost: 2778.8]
                                                         -- HYBRID_HASH_JOIN [$$205][$$198]  |PARTITIONED|
                                                           exchange [cardinality: 0.0, op-cost: 0.0, total-cost: 0.0]
                                                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/results_cbo/tpch/query-plans/query-plans.09.plan b/asterixdb/asterix-app/src/test/resources/runtimets/results_cbo/tpch/query-plans/query-plans.09.plan
index 7251329..a22503e 100644
--- a/asterixdb/asterix-app/src/test/resources/runtimets/results_cbo/tpch/query-plans/query-plans.09.plan
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/results_cbo/tpch/query-plans/query-plans.09.plan
@@ -1,36 +1,36 @@
-distribute result [$$199] [cardinality: 2.0, op-cost: 0.0, total-cost: 1259243.16]
+distribute result [$$199] [cardinality: 2.0, op-cost: 0.0, total-cost: 1258961.42]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
-  exchange [cardinality: 2.0, op-cost: 0.0, total-cost: 1259243.16]
+  exchange [cardinality: 2.0, op-cost: 0.0, total-cost: 1258961.42]
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-    assign [$$199] <- [{"$1": 8, "o_year": $$o_year, "mkt_share": numeric-divide($$214, $$215)}] project: [$$199] [cardinality: 2.0, op-cost: 0.0, total-cost: 1259243.16]
+    assign [$$199] <- [{"$1": 8, "o_year": $$o_year, "mkt_share": numeric-divide($$214, $$215)}] project: [$$199] [cardinality: 2.0, op-cost: 0.0, total-cost: 1258961.42]
     -- ASSIGN  |PARTITIONED|
-      exchange [cardinality: 2.0, op-cost: 0.0, total-cost: 1259243.16]
+      exchange [cardinality: 2.0, op-cost: 0.0, total-cost: 1258961.42]
       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
         group by ([$$o_year := $$238]) decor ([]) {
                   aggregate [$$214, $$215] <- [global-sql-sum-serial($$236), global-sql-sum-serial($$237)] [cardinality: 0.0, op-cost: 0.0, total-cost: 0.0]
                   -- AGGREGATE  |LOCAL|
                     nested tuple source [cardinality: 0.0, op-cost: 0.0, total-cost: 0.0]
                     -- NESTED_TUPLE_SOURCE  |LOCAL|
-               } [cardinality: 2.0, op-cost: 193.7, total-cost: 1259243.16]
+               } [cardinality: 2.0, op-cost: 167.75, total-cost: 1258961.42]
         -- EXTERNAL_GROUP_BY[$$238]  |PARTITIONED|
-          exchange [cardinality: 2.0, op-cost: 0.0, total-cost: 1259049.46]
+          exchange [cardinality: 2.0, op-cost: 0.0, total-cost: 1258793.67]
           -- HASH_PARTITION_EXCHANGE [$$238]  |PARTITIONED|
             group by ([$$238 := $$200]) decor ([]) {
                       aggregate [$$236, $$237] <- [local-sql-sum-serial(switch-case(true, eq($$232, "PERU"), numeric-multiply($$230, numeric-subtract(1, $$231)), 0)), local-sql-sum-serial(numeric-multiply($$230, numeric-subtract(1, $$231)))] [cardinality: 0.0, op-cost: 0.0, total-cost: 0.0]
                       -- AGGREGATE  |LOCAL|
                         nested tuple source [cardinality: 0.0, op-cost: 0.0, total-cost: 0.0]
                         -- NESTED_TUPLE_SOURCE  |LOCAL|
-                   } [cardinality: 2.0, op-cost: 193.7, total-cost: 1259049.46]
+                   } [cardinality: 2.0, op-cost: 167.75, total-cost: 1258793.67]
             -- EXTERNAL_GROUP_BY[$$200]  |PARTITIONED|
-              exchange [cardinality: 193.7, op-cost: 0.0, total-cost: 1258855.76]
+              exchange [cardinality: 167.75, op-cost: 0.0, total-cost: 1258625.92]
               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                assign [$$200] <- [get-year(date($$201))] project: [$$232, $$230, $$231, $$200] [cardinality: 193.7, op-cost: 0.0, total-cost: 1258855.76]
+                assign [$$200] <- [get-year(date($$201))] project: [$$232, $$230, $$231, $$200] [cardinality: 167.75, op-cost: 0.0, total-cost: 1258625.92]
                 -- ASSIGN  |PARTITIONED|
-                  project ([$$230, $$231, $$201, $$232]) [cardinality: 193.7, op-cost: 0.0, total-cost: 1258855.76]
+                  project ([$$230, $$231, $$201, $$232]) [cardinality: 167.75, op-cost: 0.0, total-cost: 1258625.92]
                   -- STREAM_PROJECT  |PARTITIONED|
-                    exchange [cardinality: 193.7, op-cost: 0.0, total-cost: 1258855.76]
+                    exchange [cardinality: 167.75, op-cost: 0.0, total-cost: 1258625.92]
                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                      join (eq($$216, $$209)) [cardinality: 193.7, op-cost: 288.86, total-cost: 1258855.76]
+                      join (eq($$216, $$209)) [cardinality: 167.75, op-cost: 267.75, total-cost: 1258625.92]
                       -- HYBRID_HASH_JOIN [$$216][$$209]  |PARTITIONED|
                         exchange [cardinality: 987.0, op-cost: 0.0, total-cost: 1000.0]
                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
@@ -52,7 +52,7 @@
                                         -- STREAM_PROJECT  |PARTITIONED|
                                           exchange [cardinality: 0.0, op-cost: 0.0, total-cost: 0.0]
                                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                            join (and(eq($$212, $$210), eq($$218, $$208))) [cardinality: 191.16, op-cost: 938.74, total-cost: 1256721.24]
+                                            join (and(eq($$212, $$210), eq($$218, $$208))) [cardinality: 167.75, op-cost: 938.74, total-cost: 1256721.24]
                                             -- HYBRID_HASH_JOIN [$$210, $$218][$$212, $$208]  |PARTITIONED|
                                               exchange [cardinality: 0.0, op-cost: 0.0, total-cost: 0.0]
                                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/results_cbo/tpch/query-plans/query-plans.10.plan b/asterixdb/asterix-app/src/test/resources/runtimets/results_cbo/tpch/query-plans/query-plans.10.plan
index a8f99fa..ca1e816 100644
--- a/asterixdb/asterix-app/src/test/resources/runtimets/results_cbo/tpch/query-plans/query-plans.10.plan
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/results_cbo/tpch/query-plans/query-plans.10.plan
@@ -1,22 +1,22 @@
-distribute result [$$122] [cardinality: 26982.83, op-cost: 0.0, total-cost: 1673953.69]
+distribute result [$$122] [cardinality: 26629.31, op-cost: 0.0, total-cost: 1670441.71]
 -- DISTRIBUTE_RESULT  |UNPARTITIONED|
-  exchange [cardinality: 26982.83, op-cost: 0.0, total-cost: 1673953.69]
+  exchange [cardinality: 26629.31, op-cost: 0.0, total-cost: 1670441.71]
   -- ONE_TO_ONE_EXCHANGE  |UNPARTITIONED|
-    assign [$$122] <- [{"$1": 9, "$2": $$140}] project: [$$122] [cardinality: 26982.83, op-cost: 0.0, total-cost: 1673953.69]
+    assign [$$122] <- [{"$1": 9, "$2": $$140}] project: [$$122] [cardinality: 26629.31, op-cost: 0.0, total-cost: 1670441.71]
     -- ASSIGN  |UNPARTITIONED|
-      aggregate [$$140] <- [agg-sql-sum($$144)] [cardinality: 26982.83, op-cost: 0.0, total-cost: 1673953.69]
+      aggregate [$$140] <- [agg-sql-sum($$144)] [cardinality: 26629.31, op-cost: 0.0, total-cost: 1670441.71]
       -- AGGREGATE  |UNPARTITIONED|
-        exchange [cardinality: 26982.83, op-cost: 0.0, total-cost: 1673953.69]
+        exchange [cardinality: 26629.31, op-cost: 0.0, total-cost: 1670441.71]
         -- RANDOM_MERGE_EXCHANGE  |PARTITIONED|
-          aggregate [$$144] <- [agg-sql-count(1)] [cardinality: 26982.83, op-cost: 0.0, total-cost: 1673953.69]
+          aggregate [$$144] <- [agg-sql-count(1)] [cardinality: 26629.31, op-cost: 0.0, total-cost: 1670441.71]
           -- AGGREGATE  |PARTITIONED|
-            exchange [cardinality: 26982.83, op-cost: 0.0, total-cost: 1673953.69]
+            exchange [cardinality: 26629.31, op-cost: 0.0, total-cost: 1670441.71]
             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-              unnest-map [$$136, $$o] <- index-search("orders", 0, "Default", "tpch", "orders", true, true, 1, $$132, 1, $$132, true, true, true) [cardinality: 26982.83, op-cost: 134787.25, total-cost: 1673953.69]
+              unnest-map [$$136, $$o] <- index-search("orders", 0, "Default", "tpch", "orders", true, true, 1, $$132, 1, $$132, true, true, true) [cardinality: 26629.31, op-cost: 133021.33, total-cost: 1670441.71]
               -- BTREE_SEARCH  |PARTITIONED|
                 exchange [cardinality: 0.0, op-cost: 0.0, total-cost: 0.0]
                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                  order (ASC, $$132) [cardinality: 26982.83, op-cost: 134787.25, total-cost: 1673953.69]
+                  order (ASC, $$132) [cardinality: 26629.31, op-cost: 133021.33, total-cost: 1670441.71]
                   -- STABLE_SORT [$$132(ASC)]  |PARTITIONED|
                     exchange [cardinality: 0.0, op-cost: 0.0, total-cost: 0.0]
                     -- HASH_PARTITION_EXCHANGE [$$132]  |PARTITIONED|
@@ -24,7 +24,7 @@
                       -- STREAM_PROJECT  |PARTITIONED|
                         exchange [cardinality: 0.0, op-cost: 0.0, total-cost: 0.0]
                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                          join (and(eq($$135, $$128), eq($$134, $$125))) [cardinality: 26957.44, op-cost: 615487.09, total-cost: 1431336.67]
+                          join (and(eq($$135, $$128), eq($$134, $$125))) [cardinality: 26604.26, op-cost: 615299.08, total-cost: 1431003.34]
                           -- HYBRID_HASH_JOIN [$$128, $$125][$$135, $$134]  |PARTITIONED|
                             exchange [cardinality: 0.0, op-cost: 0.0, total-cost: 0.0]
                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
@@ -46,7 +46,7 @@
                               -- STREAM_PROJECT  |PARTITIONED|
                                 exchange [cardinality: 0.0, op-cost: 0.0, total-cost: 0.0]
                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                  join (eq($$138, $$137)) [cardinality: 3587.53, op-cost: 3597.84, total-cost: 200927.47]
+                                  join (eq($$138, $$137)) [cardinality: 3540.53, op-cost: 3640.53, total-cost: 200970.15]
                                   -- HYBRID_HASH_JOIN [$$138][$$137]  |PARTITIONED|
                                     exchange [cardinality: 0.0, op-cost: 0.0, total-cost: 0.0]
                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
@@ -54,7 +54,7 @@
                                       -- STREAM_PROJECT  |PARTITIONED|
                                         exchange [cardinality: 0.0, op-cost: 0.0, total-cost: 0.0]
                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                          join (eq($$130, $$135)) [cardinality: 3497.84, op-cost: 4527.53, total-cost: 197204.63]
+                                          join (eq($$130, $$135)) [cardinality: 3540.53, op-cost: 4527.53, total-cost: 197204.63]
                                           -- HYBRID_HASH_JOIN [$$135][$$130]  |PARTITIONED|
                                             exchange [cardinality: 0.0, op-cost: 0.0, total-cost: 0.0]
                                             -- HASH_PARTITION_EXCHANGE [$$135]  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/results_cbo/tpch/query-plans/query-plans.11.plan b/asterixdb/asterix-app/src/test/resources/runtimets/results_cbo/tpch/query-plans/query-plans.11.plan
index 8afb202..ca45dac 100644
--- a/asterixdb/asterix-app/src/test/resources/runtimets/results_cbo/tpch/query-plans/query-plans.11.plan
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/results_cbo/tpch/query-plans/query-plans.11.plan
@@ -1,76 +1,76 @@
-distribute result [$$185] [cardinality: 4550.31, op-cost: 0.0, total-cost: 990713.46]
+distribute result [$$185] [cardinality: 4436.55, op-cost: 0.0, total-cost: 990428.16]
 -- DISTRIBUTE_RESULT  |UNPARTITIONED|
-  exchange [cardinality: 4550.31, op-cost: 0.0, total-cost: 990713.46]
+  exchange [cardinality: 4436.55, op-cost: 0.0, total-cost: 990428.16]
   -- ONE_TO_ONE_EXCHANGE  |UNPARTITIONED|
-    limit 20 [cardinality: 4550.31, op-cost: 0.0, total-cost: 990713.46]
+    limit 20 [cardinality: 4436.55, op-cost: 0.0, total-cost: 990428.16]
     -- STREAM_LIMIT  |UNPARTITIONED|
-      assign [$$185] <- [{"$1": 10, "c_custkey": $$c_custkey, "c_name": $$c_name, "revenue": $$203, "c_acctbal": $$c_acctbal, "n_name": $$n_name, "c_address": $$c_address, "c_phone": $$c_phone, "c_comment": $$c_comment}] project: [$$185] [cardinality: 4550.31, op-cost: 0.0, total-cost: 990713.46]
+      assign [$$185] <- [{"$1": 10, "c_custkey": $$c_custkey, "c_name": $$c_name, "revenue": $$203, "c_acctbal": $$c_acctbal, "n_name": $$n_name, "c_address": $$c_address, "c_phone": $$c_phone, "c_comment": $$c_comment}] project: [$$185] [cardinality: 4436.55, op-cost: 0.0, total-cost: 990428.16]
       -- ASSIGN  |PARTITIONED|
-        exchange [cardinality: 4550.31, op-cost: 0.0, total-cost: 990713.46]
+        exchange [cardinality: 4436.55, op-cost: 0.0, total-cost: 990428.16]
         -- SORT_MERGE_EXCHANGE [$$203(DESC) ]  |PARTITIONED|
-          limit 20 [cardinality: 4550.31, op-cost: 0.0, total-cost: 990713.46]
+          limit 20 [cardinality: 4436.55, op-cost: 0.0, total-cost: 990428.16]
           -- STREAM_LIMIT  |PARTITIONED|
-            exchange [cardinality: 4550.31, op-cost: 0.0, total-cost: 990713.46]
+            exchange [cardinality: 4436.55, op-cost: 0.0, total-cost: 990428.16]
             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-              order (topK: 20) (DESC, $$203) [cardinality: 4550.31, op-cost: 0.0, total-cost: 990713.46]
+              order (topK: 20) (DESC, $$203) [cardinality: 4436.55, op-cost: 0.0, total-cost: 990428.16]
               -- STABLE_SORT [topK: 20] [$$203(DESC)]  |PARTITIONED|
-                exchange [cardinality: 4550.31, op-cost: 0.0, total-cost: 990713.46]
+                exchange [cardinality: 4436.55, op-cost: 0.0, total-cost: 990428.16]
                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
                   group by ([$$c_custkey := $$211; $$c_name := $$212; $$c_acctbal := $$213; $$c_phone := $$214; $$n_name := $$215; $$c_address := $$216; $$c_comment := $$217]) decor ([]) {
                             aggregate [$$203] <- [global-sql-sum-serial($$210)] [cardinality: 0.0, op-cost: 0.0, total-cost: 0.0]
                             -- AGGREGATE  |LOCAL|
                               nested tuple source [cardinality: 0.0, op-cost: 0.0, total-cost: 0.0]
                               -- NESTED_TUPLE_SOURCE  |LOCAL|
-                         } [cardinality: 4550.31, op-cost: 4550.31, total-cost: 990713.46]
+                         } [cardinality: 4436.55, op-cost: 4436.55, total-cost: 990428.16]
                   -- EXTERNAL_GROUP_BY[$$211, $$212, $$213, $$214, $$215, $$216, $$217]  |PARTITIONED|
-                    exchange [cardinality: 4550.31, op-cost: 0.0, total-cost: 986163.15]
+                    exchange [cardinality: 4436.55, op-cost: 0.0, total-cost: 985991.61]
                     -- HASH_PARTITION_EXCHANGE [$$211, $$212, $$213, $$214, $$215, $$216, $$217]  |PARTITIONED|
                       group by ([$$211 := $$195; $$212 := $$187; $$213 := $$188; $$214 := $$189; $$215 := $$190; $$216 := $$191; $$217 := $$192]) decor ([]) {
                                 aggregate [$$210] <- [local-sql-sum-serial(numeric-multiply($$208, numeric-subtract(1, $$209)))] [cardinality: 0.0, op-cost: 0.0, total-cost: 0.0]
                                 -- AGGREGATE  |LOCAL|
                                   nested tuple source [cardinality: 0.0, op-cost: 0.0, total-cost: 0.0]
                                   -- NESTED_TUPLE_SOURCE  |LOCAL|
-                             } [cardinality: 4550.31, op-cost: 4550.31, total-cost: 986163.15]
+                             } [cardinality: 4436.55, op-cost: 4436.55, total-cost: 985991.61]
                       -- EXTERNAL_GROUP_BY[$$195, $$187, $$188, $$189, $$190, $$191, $$192]  |PARTITIONED|
-                        exchange [cardinality: 4550.31, op-cost: 0.0, total-cost: 981612.84]
+                        exchange [cardinality: 4436.55, op-cost: 0.0, total-cost: 981555.06]
                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                          project ([$$208, $$209, $$195, $$187, $$188, $$189, $$190, $$191, $$192]) [cardinality: 4550.31, op-cost: 0.0, total-cost: 981612.84]
+                          project ([$$208, $$209, $$195, $$187, $$188, $$189, $$190, $$191, $$192]) [cardinality: 4436.55, op-cost: 0.0, total-cost: 981555.06]
                           -- STREAM_PROJECT  |PARTITIONED|
-                            exchange [cardinality: 4550.31, op-cost: 0.0, total-cost: 981612.84]
+                            exchange [cardinality: 4436.55, op-cost: 0.0, total-cost: 981555.06]
                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                              join (eq($$201, $$199)) [cardinality: 4550.31, op-cost: 4536.55, total-cost: 981612.84]
-                              -- HYBRID_HASH_JOIN [$$201][$$199]  |PARTITIONED|
-                                exchange [cardinality: 4436.55, op-cost: 0.0, total-cost: 976951.29]
+                              join (eq($$198, $$196)) [cardinality: 4436.55, op-cost: 169494.26, total-cost: 981555.06]
+                              -- HYBRID_HASH_JOIN [$$198][$$196]  |PARTITIONED|
+                                exchange [cardinality: 151979.18, op-cost: 0.0, total-cost: 600572.0]
                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                  project ([$$208, $$209, $$195, $$187, $$188, $$189, $$191, $$192, $$201]) [cardinality: 4436.55, op-cost: 0.0, total-cost: 976951.29]
-                                  -- STREAM_PROJECT  |PARTITIONED|
-                                    exchange [cardinality: 4436.55, op-cost: 0.0, total-cost: 976951.29]
-                                    -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                      join (eq($$198, $$196)) [cardinality: 4436.55, op-cost: 169494.26, total-cost: 976951.29]
-                                      -- HYBRID_HASH_JOIN [$$198][$$196]  |PARTITIONED|
-                                        exchange [cardinality: 151979.18, op-cost: 0.0, total-cost: 600572.0]
+                                  select (eq($$l.getField(8), "R")) project: [$$208, $$209, $$198] [cardinality: 151979.18, op-cost: 0.0, total-cost: 600572.0]
+                                  -- STREAM_SELECT  |PARTITIONED|
+                                    assign [$$209, $$208] <- [$$l.getField(6), $$l.getField(5)] [cardinality: 600572.0, op-cost: 0.0, total-cost: 600572.0]
+                                    -- ASSIGN  |PARTITIONED|
+                                      project ([$$198, $$l]) [cardinality: 600572.0, op-cost: 0.0, total-cost: 600572.0]
+                                      -- STREAM_PROJECT  |PARTITIONED|
+                                        exchange [cardinality: 600572.0, op-cost: 0.0, total-cost: 600572.0]
                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                          select (eq($$l.getField(8), "R")) project: [$$208, $$209, $$198] [cardinality: 151979.18, op-cost: 0.0, total-cost: 600572.0]
-                                          -- STREAM_SELECT  |PARTITIONED|
-                                            assign [$$209, $$208] <- [$$l.getField(6), $$l.getField(5)] [cardinality: 600572.0, op-cost: 0.0, total-cost: 600572.0]
-                                            -- ASSIGN  |PARTITIONED|
-                                              project ([$$198, $$l]) [cardinality: 600572.0, op-cost: 0.0, total-cost: 600572.0]
-                                              -- STREAM_PROJECT  |PARTITIONED|
-                                                exchange [cardinality: 600572.0, op-cost: 0.0, total-cost: 600572.0]
-                                                -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                  data-scan []<-[$$197, $$198, $$l] <- tpch.lineitem [cardinality: 600572.0, op-cost: 600572.0, total-cost: 600572.0]
-                                                  -- DATASOURCE_SCAN  |PARTITIONED|
-                                                    exchange [cardinality: 0.0, op-cost: 0.0, total-cost: 0.0]
-                                                    -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                      empty-tuple-source [cardinality: 0.0, op-cost: 0.0, total-cost: 0.0]
-                                                      -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
-                                        exchange [cardinality: 15014.11, op-cost: 17515.08, total-cost: 32515.08]
-                                        -- BROADCAST_EXCHANGE  |PARTITIONED|
-                                          assign [$$192, $$191, $$189, $$188, $$187, $$201] <- [$$c.getField(7), $$c.getField(2), $$c.getField(4), $$c.getField(5), $$c.getField(1), $$c.getField(3)] project: [$$195, $$187, $$188, $$189, $$191, $$192, $$201, $$196] [cardinality: 15014.11, op-cost: 0.0, total-cost: 15000.0]
+                                          data-scan []<-[$$197, $$198, $$l] <- tpch.lineitem [cardinality: 600572.0, op-cost: 600572.0, total-cost: 600572.0]
+                                          -- DATASOURCE_SCAN  |PARTITIONED|
+                                            exchange [cardinality: 0.0, op-cost: 0.0, total-cost: 0.0]
+                                            -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                              empty-tuple-source [cardinality: 0.0, op-cost: 0.0, total-cost: 0.0]
+                                              -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                                exchange [cardinality: 4378.77, op-cost: 17515.08, total-cost: 211488.8]
+                                -- BROADCAST_EXCHANGE  |PARTITIONED|
+                                  project ([$$195, $$187, $$188, $$189, $$190, $$191, $$192, $$196]) [cardinality: 4378.77, op-cost: 0.0, total-cost: 193973.72]
+                                  -- STREAM_PROJECT  |PARTITIONED|
+                                    exchange [cardinality: 4378.77, op-cost: 17515.08, total-cost: 211488.8]
+                                    -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                      join (eq($$201, $$199)) [cardinality: 4378.77, op-cost: 4478.77, total-cost: 193973.72]
+                                      -- HYBRID_HASH_JOIN [$$201][$$199]  |PARTITIONED|
+                                        exchange [cardinality: 15014.11, op-cost: 0.0, total-cost: 15000.0]
+                                        -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                          assign [$$192, $$191, $$189, $$188, $$187, $$201] <- [$$c.getField(7), $$c.getField(2), $$c.getField(4), $$c.getField(5), $$c.getField(1), $$c.getField(3)] project: [$$195, $$187, $$188, $$189, $$191, $$192, $$196, $$201] [cardinality: 15014.11, op-cost: 0.0, total-cost: 15000.0]
                                           -- ASSIGN  |PARTITIONED|
                                             project ([$$196, $$195, $$c]) [cardinality: 15014.11, op-cost: 0.0, total-cost: 15000.0]
                                             -- STREAM_PROJECT  |PARTITIONED|
-                                              exchange [cardinality: 15014.11, op-cost: 17515.08, total-cost: 32515.08]
+                                              exchange [cardinality: 15014.11, op-cost: 0.0, total-cost: 15000.0]
                                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
                                                 unnest-map [$$195, $$c] <- index-search("customer", 0, "Default", "tpch", "customer", true, true, 1, $$206, 1, $$206, true, true, true) [cardinality: 15014.11, op-cost: 15000.0, total-cost: 15000.0]
                                                 -- BTREE_SEARCH  |PARTITIONED|
@@ -92,15 +92,15 @@
                                                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
                                                                   empty-tuple-source [cardinality: 0.0, op-cost: 0.0, total-cost: 0.0]
                                                                   -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
-                                exchange [cardinality: 25.0, op-cost: 100.0, total-cost: 125.0]
-                                -- BROADCAST_EXCHANGE  |PARTITIONED|
-                                  assign [$$190] <- [$$n.getField(1)] project: [$$190, $$199] [cardinality: 25.0, op-cost: 0.0, total-cost: 25.0]
-                                  -- ASSIGN  |PARTITIONED|
-                                    exchange [cardinality: 25.0, op-cost: 100.0, total-cost: 125.0]
-                                    -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                      data-scan []<-[$$199, $$n] <- tpch.nation [cardinality: 25.0, op-cost: 25.0, total-cost: 25.0]
-                                      -- DATASOURCE_SCAN  |PARTITIONED|
-                                        exchange [cardinality: 0.0, op-cost: 0.0, total-cost: 0.0]
-                                        -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                          empty-tuple-source [cardinality: 0.0, op-cost: 0.0, total-cost: 0.0]
-                                          -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                                        exchange [cardinality: 25.0, op-cost: 100.0, total-cost: 125.0]
+                                        -- BROADCAST_EXCHANGE  |PARTITIONED|
+                                          assign [$$190] <- [$$n.getField(1)] project: [$$190, $$199] [cardinality: 25.0, op-cost: 0.0, total-cost: 25.0]
+                                          -- ASSIGN  |PARTITIONED|
+                                            exchange [cardinality: 25.0, op-cost: 100.0, total-cost: 125.0]
+                                            -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                              data-scan []<-[$$199, $$n] <- tpch.nation [cardinality: 25.0, op-cost: 25.0, total-cost: 25.0]
+                                              -- DATASOURCE_SCAN  |PARTITIONED|
+                                                exchange [cardinality: 0.0, op-cost: 0.0, total-cost: 0.0]
+                                                -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                                  empty-tuple-source [cardinality: 0.0, op-cost: 0.0, total-cost: 0.0]
+                                                  -- EMPTY_TUPLE_SOURCE  |PARTITIONED|