[ASTERIXDB-3427][COMP] CBO not picking array index

Change-Id: Ic47a22556a6fb9468e46244062d281bea7eb5fa1
Reviewed-on: https://asterix-gerrit.ics.uci.edu/c/asterixdb/+/18365
Integration-Tests: Jenkins <jenkins@fulliautomatix.ics.uci.edu>
Tested-by: Jenkins <jenkins@fulliautomatix.ics.uci.edu>
Reviewed-by: <murali.krishna@couchbase.com>
Reviewed-by: Vijay Sarathy <vijay.sarathy@couchbase.com>
diff --git a/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/cbo/JoinNode.java b/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/cbo/JoinNode.java
index e868fa3..9fb0e72 100644
--- a/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/cbo/JoinNode.java
+++ b/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/cbo/JoinNode.java
@@ -92,6 +92,7 @@
     protected double origCardinality; // without any selections
     protected double cardinality;
     protected double size; // avg size of whole document; available from the sample
+    protected double unnestFactor;
     protected double diskProjectionSize; // what is coming out of the disk; in case of row format, it is the entire document
                                          // in case of columnar we need to add sizes of individual fields.
     protected double projectionSizeAfterScan; // excludes fields only used for selections
@@ -168,6 +169,10 @@
         return size;
     }
 
+    public double getUnnestFactor() {
+        return unnestFactor;
+    }
+
     public void setLimitVal(int val) {
         limitVal = val;
     }
@@ -247,30 +252,19 @@
     public void setCardsAndSizes(Index.SampleIndexDetails idxDetails, ILogicalOperator leafInput)
             throws AlgebricksException {
 
-        double origDatasetCard, finalDatasetCard;
-        finalDatasetCard = origDatasetCard = idxDetails.getSourceCardinality();
+        double origDatasetCard, finalDatasetCard, sampleCard;
+        unnestFactor = 1.0;
 
         DataSourceScanOperator scanOp = joinEnum.findDataSourceScanOperator(leafInput);
         if (scanOp == null) {
             return; // what happens to the cards and sizes then? this may happen in case of in lists
         }
 
-        double sampleCard = Math.min(idxDetails.getSampleCardinalityTarget(), origDatasetCard);
-        if (sampleCard == 0) { // should not happen unless the original dataset is empty
-            sampleCard = 1; // we may have to make some adjustments to costs when the sample returns very rows.
-
-            IWarningCollector warningCollector = joinEnum.optCtx.getWarningCollector();
-            if (warningCollector.shouldWarn()) {
-                warningCollector.warn(Warning.of(scanOp.getSourceLocation(),
-                        org.apache.asterix.common.exceptions.ErrorCode.SAMPLE_HAS_ZERO_ROWS));
-            }
-        }
-
         List<List<IAObject>> result;
-        SelectOperator selop = (SelectOperator) joinEnum.findASelectOp(leafInput);
-        if (selop == null) { // add a SelectOperator with TRUE condition. The code below becomes simpler with a select operator.
-            selop = new SelectOperator(new MutableObject<>(ConstantExpression.TRUE));
-            ILogicalOperator op = selop;
+        SelectOperator selOp = (SelectOperator) joinEnum.findASelectOp(leafInput);
+        if (selOp == null) { // add a SelectOperator with TRUE condition. The code below becomes simpler with a select operator.
+            selOp = new SelectOperator(new MutableObject<>(ConstantExpression.TRUE));
+            ILogicalOperator op = selOp;
             op.getInputs().add(new MutableObject<>(leafInput));
             leafInput = op;
         }
@@ -300,9 +294,31 @@
         } else {
             primaryKey = deepCopyofScan.getVariables().get(0);
         }
+
         // if there is only one conjunct, I do not have to call the sampling query during index selection!
         // insert this in place of the scandatasourceOp.
         parent.getInputs().get(0).setValue(deepCopyofScan);
+        finalDatasetCard = origDatasetCard = idxDetails.getSourceCardinality();
+        sampleCard = Math.min(idxDetails.getSampleCardinalityTarget(), origDatasetCard);
+        boolean unnest = joinEnum.findUnnestOp(selOp);
+        if (unnest) {
+            ILogicalExpression saveExpr = selOp.getCondition().getValue();
+            double unnestSampleCard = joinEnum.stats.computeUnnestedOriginalCardinality(selOp);
+            selOp.getCondition().setValue(saveExpr); // restore the expression
+            unnestFactor = unnestSampleCard / sampleCard;
+            sampleCard = unnestSampleCard;
+            finalDatasetCard = origDatasetCard = origDatasetCard * unnestFactor;
+        }
+        if (sampleCard == 0) { // should not happen unless the original dataset is empty
+            sampleCard = 1; // we may have to make some adjustments to costs when the sample returns very rows.
+
+            IWarningCollector warningCollector = joinEnum.optCtx.getWarningCollector();
+            if (warningCollector.shouldWarn()) {
+                warningCollector.warn(Warning.of(scanOp.getSourceLocation(),
+                        org.apache.asterix.common.exceptions.ErrorCode.SAMPLE_HAS_ZERO_ROWS));
+            }
+        }
+
         // There are predicates here. So skip the predicates and get the original dataset card.
         // Now apply all the predicates and get the card after all predicates are applied.
         result = joinEnum.getStatsHandle().runSamplingQueryProjection(joinEnum.optCtx, leafInput, jnArrayIndex,
@@ -316,8 +332,8 @@
             sizeVarsFromDisk = joinEnum.getStatsHandle().findSizeVarsFromDisk(result, getNumVarsFromDisk());
             sizeVarsAfterScan = joinEnum.getStatsHandle().findSizeVarsAfterScan(result, getNumVarsFromDisk());
         } else { // in case we did not get any tuples from the sample, get the size by setting the predicate to true.
-            ILogicalExpression saveExpr = selop.getCondition().getValue();
-            selop.getCondition().setValue(ConstantExpression.TRUE);
+            ILogicalExpression saveExpr = selOp.getCondition().getValue();
+            selOp.getCondition().setValue(ConstantExpression.TRUE);
             result = joinEnum.getStatsHandle().runSamplingQueryProjection(joinEnum.optCtx, leafInput, jnArrayIndex,
                     primaryKey);
             double x = joinEnum.getStatsHandle().findPredicateCardinality(result, true);
@@ -329,7 +345,7 @@
                 sizeVarsFromDisk = joinEnum.getStatsHandle().findSizeVarsFromDisk(result, getNumVarsFromDisk());
                 sizeVarsAfterScan = joinEnum.getStatsHandle().findSizeVarsAfterScan(result, getNumVarsFromDisk());
             }
-            selop.getCondition().setValue(saveExpr); // restore the expression
+            selOp.getCondition().setValue(saveExpr); // restore the expression
         }
 
         // Adjust for zero predicate cardinality from the sample.
@@ -350,6 +366,7 @@
             // is small), no need to assign any artificial min. cardinality as the sample is accurate.
             setCardinality(finalDatasetCard, scaleUp);
         }
+        setOrigCardinality(origDatasetCard, false);
 
         setSizeVarsFromDisk(sizeVarsFromDisk);
         setSizeVarsAfterScan(sizeVarsAfterScan);
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 4a57a00..aa2f40f 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
@@ -512,13 +512,7 @@
             // SELECT count(*) as revenue
             // FROM   orders o, o.o_orderline ol
             // WHERE  TRUE;
-
-            // Replace ALL SELECTS with TRUE
-            List<ILogicalExpression> selExprs;
-            selExprs = storeSelectConditionsAndMakeThemTrue(selOp, null); // all these will be marked true and will be resorted later.
-            result = runSamplingQuery(optCtx, selOp);
-            restoreAllSelectConditions(selOp, selExprs, null);
-            sampleCard = findPredicateCardinality(result, false);
+            sampleCard = computeUnnestedOriginalCardinality(selOp);
         }
         // switch  the scanOp back
         parent.getInputs().get(0).setValue(scanOp);
@@ -543,6 +537,14 @@
         return record.numberOfFields();
     }
 
+    public double computeUnnestedOriginalCardinality(SelectOperator selOp) throws AlgebricksException {
+        // Replace ALL SELECTS with TRUE, restore them after running the sampling query.
+        List<ILogicalExpression> selExprs = storeSelectConditionsAndMakeThemTrue(selOp, null);
+        List<List<IAObject>> result = runSamplingQuery(optCtx, selOp);
+        restoreAllSelectConditions(selOp, selExprs, null);
+        return findPredicateCardinality(result, false);
+    }
+
     public double findSizeVarsFromDisk(List<List<IAObject>> result, int numDiskVars) {
         ARecord record = (ARecord) (((IAObject) ((List<IAObject>) (result.get(0))).get(0)));
         // Now figure out the projected size
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/results_cbo/column/filter/001/001.019.plan b/asterixdb/asterix-app/src/test/resources/runtimets/results_cbo/column/filter/001/001.019.plan
index 2b899b4..374eccc 100644
--- a/asterixdb/asterix-app/src/test/resources/runtimets/results_cbo/column/filter/001/001.019.plan
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/results_cbo/column/filter/001/001.019.plan
@@ -1,28 +1,28 @@
-distribute result [$$item] [cardinality: 3.0, op-cost: 0.0, total-cost: 10.75]
+distribute result [$$item] [cardinality: 3.0, op-cost: 0.0, total-cost: 22.75]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
-  exchange [cardinality: 3.0, op-cost: 0.0, total-cost: 10.75]
+  exchange [cardinality: 3.0, op-cost: 0.0, total-cost: 22.75]
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-    project ([$$item]) [cardinality: 3.0, op-cost: 0.0, total-cost: 10.75]
+    project ([$$item]) [cardinality: 3.0, op-cost: 0.0, total-cost: 22.75]
     -- STREAM_PROJECT  |PARTITIONED|
-      exchange [cardinality: 3.0, op-cost: 0.0, total-cost: 10.75]
+      exchange [cardinality: 3.0, op-cost: 0.0, total-cost: 22.75]
       -- SORT_MERGE_EXCHANGE [$$29(ASC), $$item(ASC) ]  |PARTITIONED|
-        order (ASC, $$29) (ASC, $$item) [cardinality: 3.0, op-cost: 4.75, total-cost: 10.75]
+        order (ASC, $$29) (ASC, $$item) [cardinality: 3.0, op-cost: 4.75, total-cost: 22.75]
         -- STABLE_SORT [$$29(ASC), $$item(ASC)]  |PARTITIONED|
-          exchange [cardinality: 3.0, op-cost: 0.0, total-cost: 6.0]
+          exchange [cardinality: 3.0, op-cost: 0.0, total-cost: 18.0]
           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-            select (and(gt($$item, 60), lt($$item, 100))) [cardinality: 3.0, op-cost: 0.0, total-cost: 6.0]
+            select (and(gt($$item, 60), lt($$item, 100))) [cardinality: 3.0, op-cost: 0.0, total-cost: 18.0]
             -- STREAM_SELECT  |PARTITIONED|
-              project ([$$29, $$item]) [cardinality: 6.0, op-cost: 0.0, total-cost: 6.0]
+              project ([$$29, $$item]) [cardinality: 18.0, op-cost: 0.0, total-cost: 18.0]
               -- STREAM_PROJECT  |PARTITIONED|
-                unnest $$item <- scan-collection($$30) [cardinality: 6.0, op-cost: 0.0, total-cost: 6.0]
+                unnest $$item <- scan-collection($$30) [cardinality: 18.0, op-cost: 0.0, total-cost: 18.0]
                 -- UNNEST  |PARTITIONED|
-                  project ([$$29, $$30]) [cardinality: 6.0, op-cost: 0.0, total-cost: 6.0]
+                  project ([$$29, $$30]) [cardinality: 18.0, op-cost: 0.0, total-cost: 18.0]
                   -- STREAM_PROJECT  |PARTITIONED|
-                    assign [$$30] <- [$$d.getField("array")] [cardinality: 6.0, op-cost: 0.0, total-cost: 6.0]
+                    assign [$$30] <- [$$d.getField("array")] [cardinality: 18.0, op-cost: 0.0, total-cost: 18.0]
                     -- ASSIGN  |PARTITIONED|
-                      exchange [cardinality: 6.0, op-cost: 0.0, total-cost: 6.0]
+                      exchange [cardinality: 18.0, op-cost: 0.0, total-cost: 18.0]
                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                        data-scan []<-[$$29, $$d] <- test.ColumnDataset project ({array:[any]}) filter on: and(gt(scan-collection($$d.getField("array")), 60), lt(scan-collection($$d.getField("array")), 100)) range-filter on: and(gt(scan-collection($$d.getField("array")), 60), lt(scan-collection($$d.getField("array")), 100)) [cardinality: 6.0, op-cost: 6.0, total-cost: 6.0]
+                        data-scan []<-[$$29, $$d] <- test.ColumnDataset project ({array:[any]}) filter on: and(gt(scan-collection($$d.getField("array")), 60), lt(scan-collection($$d.getField("array")), 100)) range-filter on: and(gt(scan-collection($$d.getField("array")), 60), lt(scan-collection($$d.getField("array")), 100)) [cardinality: 18.0, op-cost: 18.0, total-cost: 18.0]
                         -- DATASOURCE_SCAN  |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/column/filter/001/001.021.plan b/asterixdb/asterix-app/src/test/resources/runtimets/results_cbo/column/filter/001/001.021.plan
index b21c699..d767732 100644
--- a/asterixdb/asterix-app/src/test/resources/runtimets/results_cbo/column/filter/001/001.021.plan
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/results_cbo/column/filter/001/001.021.plan
@@ -1,28 +1,28 @@
-distribute result [$$item] [cardinality: 1.0, op-cost: 0.0, total-cost: 6.0]
+distribute result [$$item] [cardinality: 1.0, op-cost: 0.0, total-cost: 18.0]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
-  exchange [cardinality: 1.0, op-cost: 0.0, total-cost: 6.0]
+  exchange [cardinality: 1.0, op-cost: 0.0, total-cost: 18.0]
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-    project ([$$item]) [cardinality: 1.0, op-cost: 0.0, total-cost: 6.0]
+    project ([$$item]) [cardinality: 1.0, op-cost: 0.0, total-cost: 18.0]
     -- STREAM_PROJECT  |PARTITIONED|
-      exchange [cardinality: 1.0, op-cost: 0.0, total-cost: 6.0]
+      exchange [cardinality: 1.0, op-cost: 0.0, total-cost: 18.0]
       -- SORT_MERGE_EXCHANGE [$$27(ASC), $$item(ASC) ]  |PARTITIONED|
-        order (ASC, $$27) (ASC, $$item) [cardinality: 1.0, op-cost: 0.0, total-cost: 6.0]
+        order (ASC, $$27) (ASC, $$item) [cardinality: 1.0, op-cost: 0.0, total-cost: 18.0]
         -- STABLE_SORT [$$27(ASC), $$item(ASC)]  |PARTITIONED|
-          exchange [cardinality: 1.0, op-cost: 0.0, total-cost: 6.0]
+          exchange [cardinality: 1.0, op-cost: 0.0, total-cost: 18.0]
           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-            select (eq($$item, 100)) [cardinality: 1.0, op-cost: 0.0, total-cost: 6.0]
+            select (eq($$item, 100)) [cardinality: 1.0, op-cost: 0.0, total-cost: 18.0]
             -- STREAM_SELECT  |PARTITIONED|
-              project ([$$27, $$item]) [cardinality: 6.0, op-cost: 0.0, total-cost: 6.0]
+              project ([$$27, $$item]) [cardinality: 18.0, op-cost: 0.0, total-cost: 18.0]
               -- STREAM_PROJECT  |PARTITIONED|
-                unnest $$item <- scan-collection($$28) [cardinality: 6.0, op-cost: 0.0, total-cost: 6.0]
+                unnest $$item <- scan-collection($$28) [cardinality: 18.0, op-cost: 0.0, total-cost: 18.0]
                 -- UNNEST  |PARTITIONED|
-                  project ([$$27, $$28]) [cardinality: 6.0, op-cost: 0.0, total-cost: 6.0]
+                  project ([$$27, $$28]) [cardinality: 18.0, op-cost: 0.0, total-cost: 18.0]
                   -- STREAM_PROJECT  |PARTITIONED|
-                    assign [$$28] <- [$$d.getField("array")] [cardinality: 6.0, op-cost: 0.0, total-cost: 6.0]
+                    assign [$$28] <- [$$d.getField("array")] [cardinality: 18.0, op-cost: 0.0, total-cost: 18.0]
                     -- ASSIGN  |PARTITIONED|
-                      exchange [cardinality: 6.0, op-cost: 0.0, total-cost: 6.0]
+                      exchange [cardinality: 18.0, op-cost: 0.0, total-cost: 18.0]
                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                        data-scan []<-[$$27, $$d] <- test.ColumnDataset project ({array:[any]}) filter on: eq(scan-collection($$d.getField("array")), 100) range-filter on: eq(scan-collection($$d.getField("array")), 100) [cardinality: 6.0, op-cost: 6.0, total-cost: 6.0]
+                        data-scan []<-[$$27, $$d] <- test.ColumnDataset project ({array:[any]}) filter on: eq(scan-collection($$d.getField("array")), 100) range-filter on: eq(scan-collection($$d.getField("array")), 100) [cardinality: 18.0, op-cost: 18.0, total-cost: 18.0]
                         -- DATASOURCE_SCAN  |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/column/filter/001/001.023.plan b/asterixdb/asterix-app/src/test/resources/runtimets/results_cbo/column/filter/001/001.023.plan
index 8bc1c8c..7ab796d 100644
--- a/asterixdb/asterix-app/src/test/resources/runtimets/results_cbo/column/filter/001/001.023.plan
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/results_cbo/column/filter/001/001.023.plan
@@ -1,28 +1,28 @@
-distribute result [$$item] [cardinality: 0.0, op-cost: 0.0, total-cost: 6.0]
+distribute result [$$item] [cardinality: 0.0, op-cost: 0.0, total-cost: 18.0]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
-  exchange [cardinality: 0.0, op-cost: 0.0, total-cost: 6.0]
+  exchange [cardinality: 0.0, op-cost: 0.0, total-cost: 18.0]
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-    project ([$$item]) [cardinality: 0.0, op-cost: 0.0, total-cost: 6.0]
+    project ([$$item]) [cardinality: 0.0, op-cost: 0.0, total-cost: 18.0]
     -- STREAM_PROJECT  |PARTITIONED|
-      exchange [cardinality: 0.0, op-cost: 0.0, total-cost: 6.0]
+      exchange [cardinality: 0.0, op-cost: 0.0, total-cost: 18.0]
       -- SORT_MERGE_EXCHANGE [$$27(ASC), $$item(ASC) ]  |PARTITIONED|
-        order (ASC, $$27) (ASC, $$item) [cardinality: 0.0, op-cost: 0.0, total-cost: 6.0]
+        order (ASC, $$27) (ASC, $$item) [cardinality: 0.0, op-cost: 0.0, total-cost: 18.0]
         -- STABLE_SORT [$$27(ASC), $$item(ASC)]  |PARTITIONED|
-          exchange [cardinality: 0.0, op-cost: 0.0, total-cost: 6.0]
+          exchange [cardinality: 0.0, op-cost: 0.0, total-cost: 18.0]
           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-            select (gt($$item, 10000)) [cardinality: 0.0, op-cost: 0.0, total-cost: 6.0]
+            select (gt($$item, 10000)) [cardinality: 0.0, op-cost: 0.0, total-cost: 18.0]
             -- STREAM_SELECT  |PARTITIONED|
-              project ([$$27, $$item]) [cardinality: 6.0, op-cost: 0.0, total-cost: 6.0]
+              project ([$$27, $$item]) [cardinality: 18.0, op-cost: 0.0, total-cost: 18.0]
               -- STREAM_PROJECT  |PARTITIONED|
-                unnest $$item <- scan-collection($$28) [cardinality: 6.0, op-cost: 0.0, total-cost: 6.0]
+                unnest $$item <- scan-collection($$28) [cardinality: 18.0, op-cost: 0.0, total-cost: 18.0]
                 -- UNNEST  |PARTITIONED|
-                  project ([$$27, $$28]) [cardinality: 6.0, op-cost: 0.0, total-cost: 6.0]
+                  project ([$$27, $$28]) [cardinality: 18.0, op-cost: 0.0, total-cost: 18.0]
                   -- STREAM_PROJECT  |PARTITIONED|
-                    assign [$$28] <- [$$d.getField("array")] [cardinality: 6.0, op-cost: 0.0, total-cost: 6.0]
+                    assign [$$28] <- [$$d.getField("array")] [cardinality: 18.0, op-cost: 0.0, total-cost: 18.0]
                     -- ASSIGN  |PARTITIONED|
-                      exchange [cardinality: 6.0, op-cost: 0.0, total-cost: 6.0]
+                      exchange [cardinality: 18.0, op-cost: 0.0, total-cost: 18.0]
                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                        data-scan []<-[$$27, $$d] <- test.ColumnDataset project ({array:[any]}) filter on: gt(scan-collection($$d.getField("array")), 10000) range-filter on: gt(scan-collection($$d.getField("array")), 10000) [cardinality: 6.0, op-cost: 6.0, total-cost: 6.0]
+                        data-scan []<-[$$27, $$d] <- test.ColumnDataset project ({array:[any]}) filter on: gt(scan-collection($$d.getField("array")), 10000) range-filter on: gt(scan-collection($$d.getField("array")), 10000) [cardinality: 18.0, op-cost: 18.0, total-cost: 18.0]
                         -- DATASOURCE_SCAN  |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/column/filter/001/001.025.plan b/asterixdb/asterix-app/src/test/resources/runtimets/results_cbo/column/filter/001/001.025.plan
index d8a8cd0..a62c529 100644
--- a/asterixdb/asterix-app/src/test/resources/runtimets/results_cbo/column/filter/001/001.025.plan
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/results_cbo/column/filter/001/001.025.plan
@@ -1,34 +1,34 @@
-distribute result [$$31] [cardinality: 2.0, op-cost: 0.0, total-cost: 8.0]
+distribute result [$$31] [cardinality: 2.0, op-cost: 0.0, total-cost: 20.0]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
-  exchange [cardinality: 2.0, op-cost: 0.0, total-cost: 8.0]
+  exchange [cardinality: 2.0, op-cost: 0.0, total-cost: 20.0]
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-    project ([$$31]) [cardinality: 2.0, op-cost: 0.0, total-cost: 8.0]
+    project ([$$31]) [cardinality: 2.0, op-cost: 0.0, total-cost: 20.0]
     -- STREAM_PROJECT  |PARTITIONED|
-      assign [$$31] <- [{"a": $$34, "item": $$item}] [cardinality: 2.0, op-cost: 0.0, total-cost: 8.0]
+      assign [$$31] <- [{"a": $$34, "item": $$item}] [cardinality: 2.0, op-cost: 0.0, total-cost: 20.0]
       -- ASSIGN  |PARTITIONED|
-        project ([$$34, $$item]) [cardinality: 2.0, op-cost: 0.0, total-cost: 8.0]
+        project ([$$34, $$item]) [cardinality: 2.0, op-cost: 0.0, total-cost: 20.0]
         -- STREAM_PROJECT  |PARTITIONED|
-          exchange [cardinality: 2.0, op-cost: 0.0, total-cost: 8.0]
+          exchange [cardinality: 2.0, op-cost: 0.0, total-cost: 20.0]
           -- SORT_MERGE_EXCHANGE [$$35(ASC), $$34(ASC), $$item(ASC) ]  |PARTITIONED|
-            order (ASC, $$35) (ASC, $$34) (ASC, $$item) [cardinality: 2.0, op-cost: 2.0, total-cost: 8.0]
+            order (ASC, $$35) (ASC, $$34) (ASC, $$item) [cardinality: 2.0, op-cost: 2.0, total-cost: 20.0]
             -- STABLE_SORT [$$35(ASC), $$34(ASC), $$item(ASC)]  |PARTITIONED|
-              exchange [cardinality: 2.0, op-cost: 0.0, total-cost: 6.0]
+              exchange [cardinality: 2.0, op-cost: 0.0, total-cost: 18.0]
               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                select (gt($$item, 10)) [cardinality: 2.0, op-cost: 0.0, total-cost: 6.0]
+                select (gt($$item, 10)) [cardinality: 2.0, op-cost: 0.0, total-cost: 18.0]
                 -- STREAM_SELECT  |PARTITIONED|
-                  project ([$$35, $$34, $$item]) [cardinality: 6.0, op-cost: 0.0, total-cost: 6.0]
+                  project ([$$35, $$34, $$item]) [cardinality: 18.0, op-cost: 0.0, total-cost: 18.0]
                   -- STREAM_PROJECT  |PARTITIONED|
-                    unnest $$item <- scan-collection($$36) [cardinality: 6.0, op-cost: 0.0, total-cost: 6.0]
+                    unnest $$item <- scan-collection($$36) [cardinality: 18.0, op-cost: 0.0, total-cost: 18.0]
                     -- UNNEST  |PARTITIONED|
                       select (eq($$34, "1")) [cardinality: 0.0, op-cost: 0.0, total-cost: 0.0]
                       -- STREAM_SELECT  |PARTITIONED|
-                        project ([$$35, $$34, $$36]) [cardinality: 6.0, op-cost: 0.0, total-cost: 6.0]
+                        project ([$$35, $$34, $$36]) [cardinality: 18.0, op-cost: 0.0, total-cost: 18.0]
                         -- STREAM_PROJECT  |PARTITIONED|
-                          assign [$$34, $$36] <- [$$d.getField("a"), $$d.getField("array")] [cardinality: 6.0, op-cost: 0.0, total-cost: 6.0]
+                          assign [$$34, $$36] <- [$$d.getField("a"), $$d.getField("array")] [cardinality: 18.0, op-cost: 0.0, total-cost: 18.0]
                           -- ASSIGN  |PARTITIONED|
-                            exchange [cardinality: 6.0, op-cost: 0.0, total-cost: 6.0]
+                            exchange [cardinality: 18.0, op-cost: 0.0, total-cost: 18.0]
                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                              data-scan []<-[$$35, $$d] <- test.ColumnDataset project ({a:any,array:[any]}) filter on: and(eq($$d.getField("a"), "1"), gt(scan-collection($$d.getField("array")), 10)) range-filter on: and(eq($$d.getField("a"), "1"), gt(scan-collection($$d.getField("array")), 10)) [cardinality: 6.0, op-cost: 6.0, total-cost: 6.0]
+                              data-scan []<-[$$35, $$d] <- test.ColumnDataset project ({a:any,array:[any]}) filter on: and(eq($$d.getField("a"), "1"), gt(scan-collection($$d.getField("array")), 10)) range-filter on: and(eq($$d.getField("a"), "1"), gt(scan-collection($$d.getField("array")), 10)) [cardinality: 18.0, op-cost: 18.0, total-cost: 18.0]
                               -- DATASOURCE_SCAN  |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/column/filter/004/004.006.plan b/asterixdb/asterix-app/src/test/resources/runtimets/results_cbo/column/filter/004/004.006.plan
index 8071306..11bdf61 100644
--- a/asterixdb/asterix-app/src/test/resources/runtimets/results_cbo/column/filter/004/004.006.plan
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/results_cbo/column/filter/004/004.006.plan
@@ -1,32 +1,32 @@
-distribute result [$$47] [cardinality: 99.0, op-cost: 0.0, total-cost: 30.0]
+distribute result [$$47] [cardinality: 99.0, op-cost: 0.0, total-cost: 99.0]
 -- DISTRIBUTE_RESULT  |UNPARTITIONED|
-  exchange [cardinality: 99.0, op-cost: 0.0, total-cost: 30.0]
+  exchange [cardinality: 99.0, op-cost: 0.0, total-cost: 99.0]
   -- ONE_TO_ONE_EXCHANGE  |UNPARTITIONED|
-    project ([$$47]) [cardinality: 99.0, op-cost: 0.0, total-cost: 30.0]
+    project ([$$47]) [cardinality: 99.0, op-cost: 0.0, total-cost: 99.0]
     -- STREAM_PROJECT  |UNPARTITIONED|
-      assign [$$47] <- [{"$1": $$49}] [cardinality: 99.0, op-cost: 0.0, total-cost: 30.0]
+      assign [$$47] <- [{"$1": $$49}] [cardinality: 99.0, op-cost: 0.0, total-cost: 99.0]
       -- ASSIGN  |UNPARTITIONED|
-        aggregate [$$49] <- [agg-sql-sum($$51)] [cardinality: 99.0, op-cost: 0.0, total-cost: 30.0]
+        aggregate [$$49] <- [agg-sql-sum($$51)] [cardinality: 99.0, op-cost: 0.0, total-cost: 99.0]
         -- AGGREGATE  |UNPARTITIONED|
-          exchange [cardinality: 99.0, op-cost: 0.0, total-cost: 30.0]
+          exchange [cardinality: 99.0, op-cost: 0.0, total-cost: 99.0]
           -- RANDOM_MERGE_EXCHANGE  |PARTITIONED|
-            aggregate [$$51] <- [agg-sql-count(1)] [cardinality: 99.0, op-cost: 0.0, total-cost: 30.0]
+            aggregate [$$51] <- [agg-sql-count(1)] [cardinality: 99.0, op-cost: 0.0, total-cost: 99.0]
             -- AGGREGATE  |PARTITIONED|
-              select (gt($$D, " ")) [cardinality: 99.0, op-cost: 0.0, total-cost: 30.0]
+              select (gt($$D, " ")) [cardinality: 99.0, op-cost: 0.0, total-cost: 99.0]
               -- STREAM_SELECT  |PARTITIONED|
-                project ([$$D]) [cardinality: 30.0, op-cost: 0.0, total-cost: 30.0]
+                project ([$$D]) [cardinality: 99.0, op-cost: 0.0, total-cost: 99.0]
                 -- STREAM_PROJECT  |PARTITIONED|
-                  unnest $$D <- scan-collection($$50) [cardinality: 30.0, op-cost: 0.0, total-cost: 30.0]
+                  unnest $$D <- scan-collection($$50) [cardinality: 99.0, op-cost: 0.0, total-cost: 99.0]
                   -- UNNEST  |PARTITIONED|
-                    project ([$$50]) [cardinality: 30.0, op-cost: 0.0, total-cost: 30.0]
+                    project ([$$50]) [cardinality: 99.0, op-cost: 0.0, total-cost: 99.0]
                     -- STREAM_PROJECT  |PARTITIONED|
-                      assign [$$50] <- [$$C.getField("dates")] [cardinality: 30.0, op-cost: 0.0, total-cost: 30.0]
+                      assign [$$50] <- [$$C.getField("dates")] [cardinality: 99.0, op-cost: 0.0, total-cost: 99.0]
                       -- ASSIGN  |PARTITIONED|
-                        project ([$$C]) [cardinality: 30.0, op-cost: 0.0, total-cost: 30.0]
+                        project ([$$C]) [cardinality: 99.0, op-cost: 0.0, total-cost: 99.0]
                         -- STREAM_PROJECT  |PARTITIONED|
-                          exchange [cardinality: 30.0, op-cost: 0.0, total-cost: 30.0]
+                          exchange [cardinality: 99.0, op-cost: 0.0, total-cost: 99.0]
                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                            data-scan []<-[$$48, $$C] <- TestYelp.YelpCheckin project ({dates:[any]}) filter on: gt(scan-collection($$C.getField("dates")), " ") range-filter on: gt(scan-collection($$C.getField("dates")), " ") [cardinality: 30.0, op-cost: 30.0, total-cost: 30.0]
+                            data-scan []<-[$$48, $$C] <- TestYelp.YelpCheckin project ({dates:[any]}) filter on: gt(scan-collection($$C.getField("dates")), " ") range-filter on: gt(scan-collection($$C.getField("dates")), " ") [cardinality: 99.0, op-cost: 99.0, total-cost: 99.0]
                             -- DATASOURCE_SCAN  |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/column/filter/004/004.102.plan b/asterixdb/asterix-app/src/test/resources/runtimets/results_cbo/column/filter/004/004.102.plan
index ffd904f..59da462 100644
--- a/asterixdb/asterix-app/src/test/resources/runtimets/results_cbo/column/filter/004/004.102.plan
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/results_cbo/column/filter/004/004.102.plan
@@ -1,32 +1,32 @@
-distribute result [$$48] [cardinality: 6.0, op-cost: 0.0, total-cost: 30.0]
+distribute result [$$48] [cardinality: 6.0, op-cost: 0.0, total-cost: 101.0]
 -- DISTRIBUTE_RESULT  |UNPARTITIONED|
-  exchange [cardinality: 6.0, op-cost: 0.0, total-cost: 30.0]
+  exchange [cardinality: 6.0, op-cost: 0.0, total-cost: 101.0]
   -- ONE_TO_ONE_EXCHANGE  |UNPARTITIONED|
-    project ([$$48]) [cardinality: 6.0, op-cost: 0.0, total-cost: 30.0]
+    project ([$$48]) [cardinality: 6.0, op-cost: 0.0, total-cost: 101.0]
     -- STREAM_PROJECT  |UNPARTITIONED|
-      assign [$$48] <- [{"$1": $$50}] [cardinality: 6.0, op-cost: 0.0, total-cost: 30.0]
+      assign [$$48] <- [{"$1": $$50}] [cardinality: 6.0, op-cost: 0.0, total-cost: 101.0]
       -- ASSIGN  |UNPARTITIONED|
-        aggregate [$$50] <- [agg-sql-sum($$52)] [cardinality: 6.0, op-cost: 0.0, total-cost: 30.0]
+        aggregate [$$50] <- [agg-sql-sum($$52)] [cardinality: 6.0, op-cost: 0.0, total-cost: 101.0]
         -- AGGREGATE  |UNPARTITIONED|
-          exchange [cardinality: 6.0, op-cost: 0.0, total-cost: 30.0]
+          exchange [cardinality: 6.0, op-cost: 0.0, total-cost: 101.0]
           -- RANDOM_MERGE_EXCHANGE  |PARTITIONED|
-            aggregate [$$52] <- [agg-sql-count(1)] [cardinality: 6.0, op-cost: 0.0, total-cost: 30.0]
+            aggregate [$$52] <- [agg-sql-count(1)] [cardinality: 6.0, op-cost: 0.0, total-cost: 101.0]
             -- AGGREGATE  |PARTITIONED|
-              select (eq(substring($$D, 0, 4), "2011")) [cardinality: 6.0, op-cost: 0.0, total-cost: 30.0]
+              select (eq(substring($$D, 0, 4), "2011")) [cardinality: 6.0, op-cost: 0.0, total-cost: 101.0]
               -- STREAM_SELECT  |PARTITIONED|
-                project ([$$D]) [cardinality: 30.0, op-cost: 0.0, total-cost: 30.0]
+                project ([$$D]) [cardinality: 101.0, op-cost: 0.0, total-cost: 101.0]
                 -- STREAM_PROJECT  |PARTITIONED|
-                  unnest $$D <- scan-collection($$51) [cardinality: 30.0, op-cost: 0.0, total-cost: 30.0]
+                  unnest $$D <- scan-collection($$51) [cardinality: 101.0, op-cost: 0.0, total-cost: 101.0]
                   -- UNNEST  |PARTITIONED|
-                    project ([$$51]) [cardinality: 30.0, op-cost: 0.0, total-cost: 30.0]
+                    project ([$$51]) [cardinality: 101.0, op-cost: 0.0, total-cost: 101.0]
                     -- STREAM_PROJECT  |PARTITIONED|
-                      assign [$$51] <- [$$C.getField("dates")] [cardinality: 30.0, op-cost: 0.0, total-cost: 30.0]
+                      assign [$$51] <- [$$C.getField("dates")] [cardinality: 101.0, op-cost: 0.0, total-cost: 101.0]
                       -- ASSIGN  |PARTITIONED|
-                        project ([$$C]) [cardinality: 30.0, op-cost: 0.0, total-cost: 30.0]
+                        project ([$$C]) [cardinality: 101.0, op-cost: 0.0, total-cost: 101.0]
                         -- STREAM_PROJECT  |PARTITIONED|
-                          exchange [cardinality: 30.0, op-cost: 0.0, total-cost: 30.0]
+                          exchange [cardinality: 101.0, op-cost: 0.0, total-cost: 101.0]
                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                            data-scan []<-[$$49, $$C] <- TestYelp.YelpCheckin project ({dates:[any]}) filter on: eq(substring(scan-collection($$C.getField("dates")), 0, 4), "2011") [cardinality: 30.0, op-cost: 30.0, total-cost: 30.0]
+                            data-scan []<-[$$49, $$C] <- TestYelp.YelpCheckin project ({dates:[any]}) filter on: eq(substring(scan-collection($$C.getField("dates")), 0, 4), "2011") [cardinality: 101.0, op-cost: 101.0, total-cost: 101.0]
                             -- DATASOURCE_SCAN  |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/column/filter/004/004.105.plan b/asterixdb/asterix-app/src/test/resources/runtimets/results_cbo/column/filter/004/004.105.plan
index b59f329..971b8d9 100644
--- a/asterixdb/asterix-app/src/test/resources/runtimets/results_cbo/column/filter/004/004.105.plan
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/results_cbo/column/filter/004/004.105.plan
@@ -1,36 +1,36 @@
-distribute result [$$51] [cardinality: 20.0, op-cost: 0.0, total-cost: 30.0]
+distribute result [$$51] [cardinality: 20.0, op-cost: 0.0, total-cost: 101.0]
 -- DISTRIBUTE_RESULT  |UNPARTITIONED|
-  exchange [cardinality: 20.0, op-cost: 0.0, total-cost: 30.0]
+  exchange [cardinality: 20.0, op-cost: 0.0, total-cost: 101.0]
   -- ONE_TO_ONE_EXCHANGE  |UNPARTITIONED|
-    project ([$$51]) [cardinality: 20.0, op-cost: 0.0, total-cost: 30.0]
+    project ([$$51]) [cardinality: 20.0, op-cost: 0.0, total-cost: 101.0]
     -- STREAM_PROJECT  |UNPARTITIONED|
-      assign [$$51] <- [{"$1": $$54}] [cardinality: 20.0, op-cost: 0.0, total-cost: 30.0]
+      assign [$$51] <- [{"$1": $$54}] [cardinality: 20.0, op-cost: 0.0, total-cost: 101.0]
       -- ASSIGN  |UNPARTITIONED|
-        aggregate [$$54] <- [agg-sql-sum($$57)] [cardinality: 20.0, op-cost: 0.0, total-cost: 30.0]
+        aggregate [$$54] <- [agg-sql-sum($$57)] [cardinality: 20.0, op-cost: 0.0, total-cost: 101.0]
         -- AGGREGATE  |UNPARTITIONED|
-          exchange [cardinality: 20.0, op-cost: 0.0, total-cost: 30.0]
+          exchange [cardinality: 20.0, op-cost: 0.0, total-cost: 101.0]
           -- RANDOM_MERGE_EXCHANGE  |PARTITIONED|
-            aggregate [$$57] <- [agg-sql-count(1)] [cardinality: 20.0, op-cost: 0.0, total-cost: 30.0]
+            aggregate [$$57] <- [agg-sql-count(1)] [cardinality: 20.0, op-cost: 0.0, total-cost: 101.0]
             -- AGGREGATE  |PARTITIONED|
-              select (or(eq($$58, "2011"), eq($$58, "2016"))) [cardinality: 20.0, op-cost: 0.0, total-cost: 30.0]
+              select (or(eq($$58, "2011"), eq($$58, "2016"))) [cardinality: 20.0, op-cost: 0.0, total-cost: 101.0]
               -- STREAM_SELECT  |PARTITIONED|
-                project ([$$58]) [cardinality: 30.0, op-cost: 0.0, total-cost: 30.0]
+                project ([$$58]) [cardinality: 101.0, op-cost: 0.0, total-cost: 101.0]
                 -- STREAM_PROJECT  |PARTITIONED|
-                  assign [$$58] <- [substring($$D, 0, 4)] [cardinality: 30.0, op-cost: 0.0, total-cost: 30.0]
+                  assign [$$58] <- [substring($$D, 0, 4)] [cardinality: 101.0, op-cost: 0.0, total-cost: 101.0]
                   -- ASSIGN  |PARTITIONED|
-                    project ([$$D]) [cardinality: 30.0, op-cost: 0.0, total-cost: 30.0]
+                    project ([$$D]) [cardinality: 101.0, op-cost: 0.0, total-cost: 101.0]
                     -- STREAM_PROJECT  |PARTITIONED|
-                      unnest $$D <- scan-collection($$55) [cardinality: 30.0, op-cost: 0.0, total-cost: 30.0]
+                      unnest $$D <- scan-collection($$55) [cardinality: 101.0, op-cost: 0.0, total-cost: 101.0]
                       -- UNNEST  |PARTITIONED|
-                        project ([$$55]) [cardinality: 30.0, op-cost: 0.0, total-cost: 30.0]
+                        project ([$$55]) [cardinality: 101.0, op-cost: 0.0, total-cost: 101.0]
                         -- STREAM_PROJECT  |PARTITIONED|
-                          assign [$$55] <- [$$C.getField("dates")] [cardinality: 30.0, op-cost: 0.0, total-cost: 30.0]
+                          assign [$$55] <- [$$C.getField("dates")] [cardinality: 101.0, op-cost: 0.0, total-cost: 101.0]
                           -- ASSIGN  |PARTITIONED|
-                            project ([$$C]) [cardinality: 30.0, op-cost: 0.0, total-cost: 30.0]
+                            project ([$$C]) [cardinality: 101.0, op-cost: 0.0, total-cost: 101.0]
                             -- STREAM_PROJECT  |PARTITIONED|
-                              exchange [cardinality: 30.0, op-cost: 0.0, total-cost: 30.0]
+                              exchange [cardinality: 101.0, op-cost: 0.0, total-cost: 101.0]
                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                data-scan []<-[$$53, $$C] <- TestYelp.YelpCheckin project ({dates:[any]}) filter on: or(eq(substring(scan-collection($$C.getField("dates")), 0, 4), "2011"), eq(substring(scan-collection($$C.getField("dates")), 0, 4), "2016")) [cardinality: 30.0, op-cost: 30.0, total-cost: 30.0]
+                                data-scan []<-[$$53, $$C] <- TestYelp.YelpCheckin project ({dates:[any]}) filter on: or(eq(substring(scan-collection($$C.getField("dates")), 0, 4), "2011"), eq(substring(scan-collection($$C.getField("dates")), 0, 4), "2016")) [cardinality: 101.0, op-cost: 101.0, total-cost: 101.0]
                                 -- DATASOURCE_SCAN  |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/column/filter/004/004.113.plan b/asterixdb/asterix-app/src/test/resources/runtimets/results_cbo/column/filter/004/004.113.plan
index 11fa99a..5254584 100644
--- a/asterixdb/asterix-app/src/test/resources/runtimets/results_cbo/column/filter/004/004.113.plan
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/results_cbo/column/filter/004/004.113.plan
@@ -1,38 +1,38 @@
-distribute result [$$54] [cardinality: 7.0, op-cost: 0.0, total-cost: 30.0]
+distribute result [$$54] [cardinality: 7.0, op-cost: 0.0, total-cost: 101.0]
 -- DISTRIBUTE_RESULT  |UNPARTITIONED|
-  exchange [cardinality: 7.0, op-cost: 0.0, total-cost: 30.0]
+  exchange [cardinality: 7.0, op-cost: 0.0, total-cost: 101.0]
   -- ONE_TO_ONE_EXCHANGE  |UNPARTITIONED|
-    project ([$$54]) [cardinality: 7.0, op-cost: 0.0, total-cost: 30.0]
+    project ([$$54]) [cardinality: 7.0, op-cost: 0.0, total-cost: 101.0]
     -- STREAM_PROJECT  |UNPARTITIONED|
-      assign [$$54] <- [{"$1": $$57}] [cardinality: 7.0, op-cost: 0.0, total-cost: 30.0]
+      assign [$$54] <- [{"$1": $$57}] [cardinality: 7.0, op-cost: 0.0, total-cost: 101.0]
       -- ASSIGN  |UNPARTITIONED|
-        aggregate [$$57] <- [agg-sql-sum($$61)] [cardinality: 7.0, op-cost: 0.0, total-cost: 30.0]
+        aggregate [$$57] <- [agg-sql-sum($$61)] [cardinality: 7.0, op-cost: 0.0, total-cost: 101.0]
         -- AGGREGATE  |UNPARTITIONED|
-          exchange [cardinality: 7.0, op-cost: 0.0, total-cost: 30.0]
+          exchange [cardinality: 7.0, op-cost: 0.0, total-cost: 101.0]
           -- RANDOM_MERGE_EXCHANGE  |PARTITIONED|
-            aggregate [$$61] <- [agg-sql-count(1)] [cardinality: 7.0, op-cost: 0.0, total-cost: 30.0]
+            aggregate [$$61] <- [agg-sql-count(1)] [cardinality: 7.0, op-cost: 0.0, total-cost: 101.0]
             -- AGGREGATE  |PARTITIONED|
-              select (or(eq($$62, "2011"), eq($$62, "2016"))) [cardinality: 7.0, op-cost: 0.0, total-cost: 30.0]
+              select (or(eq($$62, "2011"), eq($$62, "2016"))) [cardinality: 7.0, op-cost: 0.0, total-cost: 101.0]
               -- STREAM_SELECT  |PARTITIONED|
-                project ([$$62]) [cardinality: 30.0, op-cost: 0.0, total-cost: 30.0]
+                project ([$$62]) [cardinality: 101.0, op-cost: 0.0, total-cost: 101.0]
                 -- STREAM_PROJECT  |PARTITIONED|
-                  assign [$$62] <- [substring($$D, 0, 4)] [cardinality: 30.0, op-cost: 0.0, total-cost: 30.0]
+                  assign [$$62] <- [substring($$D, 0, 4)] [cardinality: 101.0, op-cost: 0.0, total-cost: 101.0]
                   -- ASSIGN  |PARTITIONED|
-                    project ([$$D]) [cardinality: 30.0, op-cost: 0.0, total-cost: 30.0]
+                    project ([$$D]) [cardinality: 101.0, op-cost: 0.0, total-cost: 101.0]
                     -- STREAM_PROJECT  |PARTITIONED|
-                      unnest $$D <- scan-collection($$59) [cardinality: 30.0, op-cost: 0.0, total-cost: 30.0]
+                      unnest $$D <- scan-collection($$59) [cardinality: 101.0, op-cost: 0.0, total-cost: 101.0]
                       -- UNNEST  |PARTITIONED|
-                        project ([$$59]) [cardinality: 30.0, op-cost: 0.0, total-cost: 30.0]
+                        project ([$$59]) [cardinality: 101.0, op-cost: 0.0, total-cost: 101.0]
                         -- STREAM_PROJECT  |PARTITIONED|
                           select (starts-with($$C.getField("business_id"), "-0")) [cardinality: 0.0, op-cost: 0.0, total-cost: 0.0]
                           -- STREAM_SELECT  |PARTITIONED|
-                            assign [$$59] <- [$$C.getField("dates")] [cardinality: 30.0, op-cost: 0.0, total-cost: 30.0]
+                            assign [$$59] <- [$$C.getField("dates")] [cardinality: 101.0, op-cost: 0.0, total-cost: 101.0]
                             -- ASSIGN  |PARTITIONED|
-                              project ([$$C]) [cardinality: 30.0, op-cost: 0.0, total-cost: 30.0]
+                              project ([$$C]) [cardinality: 101.0, op-cost: 0.0, total-cost: 101.0]
                               -- STREAM_PROJECT  |PARTITIONED|
-                                exchange [cardinality: 30.0, op-cost: 0.0, total-cost: 30.0]
+                                exchange [cardinality: 101.0, op-cost: 0.0, total-cost: 101.0]
                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                  data-scan []<-[$$56, $$C] <- TestYelp.YelpCheckin project ({dates:[any],business_id:any}) filter on: and(starts-with($$C.getField("business_id"), "-0"), or(eq(substring(scan-collection($$C.getField("dates")), 0, 4), "2011"), eq(substring(scan-collection($$C.getField("dates")), 0, 4), "2016"))) [cardinality: 30.0, op-cost: 30.0, total-cost: 30.0]
+                                  data-scan []<-[$$56, $$C] <- TestYelp.YelpCheckin project ({dates:[any],business_id:any}) filter on: and(starts-with($$C.getField("business_id"), "-0"), or(eq(substring(scan-collection($$C.getField("dates")), 0, 4), "2011"), eq(substring(scan-collection($$C.getField("dates")), 0, 4), "2016"))) [cardinality: 101.0, op-cost: 101.0, total-cost: 101.0]
                                   -- DATASOURCE_SCAN  |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/column/filter/005/005.008.plan b/asterixdb/asterix-app/src/test/resources/runtimets/results_cbo/column/filter/005/005.008.plan
index 3be0e8f..95dc1df 100644
--- a/asterixdb/asterix-app/src/test/resources/runtimets/results_cbo/column/filter/005/005.008.plan
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/results_cbo/column/filter/005/005.008.plan
@@ -1,32 +1,32 @@
-distribute result [$$48] [cardinality: 2.0, op-cost: 0.0, total-cost: 30.0]
+distribute result [$$48] [cardinality: 2.0, op-cost: 0.0, total-cost: 99.0]
 -- DISTRIBUTE_RESULT  |UNPARTITIONED|
-  exchange [cardinality: 2.0, op-cost: 0.0, total-cost: 30.0]
+  exchange [cardinality: 2.0, op-cost: 0.0, total-cost: 99.0]
   -- ONE_TO_ONE_EXCHANGE  |UNPARTITIONED|
-    project ([$$48]) [cardinality: 2.0, op-cost: 0.0, total-cost: 30.0]
+    project ([$$48]) [cardinality: 2.0, op-cost: 0.0, total-cost: 99.0]
     -- STREAM_PROJECT  |UNPARTITIONED|
-      assign [$$48] <- [{"$1": $$50}] [cardinality: 2.0, op-cost: 0.0, total-cost: 30.0]
+      assign [$$48] <- [{"$1": $$50}] [cardinality: 2.0, op-cost: 0.0, total-cost: 99.0]
       -- ASSIGN  |UNPARTITIONED|
-        aggregate [$$50] <- [agg-sql-sum($$52)] [cardinality: 2.0, op-cost: 0.0, total-cost: 30.0]
+        aggregate [$$50] <- [agg-sql-sum($$52)] [cardinality: 2.0, op-cost: 0.0, total-cost: 99.0]
         -- AGGREGATE  |UNPARTITIONED|
-          exchange [cardinality: 2.0, op-cost: 0.0, total-cost: 30.0]
+          exchange [cardinality: 2.0, op-cost: 0.0, total-cost: 99.0]
           -- RANDOM_MERGE_EXCHANGE  |PARTITIONED|
-            aggregate [$$52] <- [agg-sql-count(1)] [cardinality: 2.0, op-cost: 0.0, total-cost: 30.0]
+            aggregate [$$52] <- [agg-sql-count(1)] [cardinality: 2.0, op-cost: 0.0, total-cost: 99.0]
             -- AGGREGATE  |PARTITIONED|
-              select (gt(numeric-add($$D, 1), 2018)) [cardinality: 2.0, op-cost: 0.0, total-cost: 30.0]
+              select (gt(numeric-add($$D, 1), 2018)) [cardinality: 2.0, op-cost: 0.0, total-cost: 99.0]
               -- STREAM_SELECT  |PARTITIONED|
-                project ([$$D]) [cardinality: 30.0, op-cost: 0.0, total-cost: 30.0]
+                project ([$$D]) [cardinality: 99.0, op-cost: 0.0, total-cost: 99.0]
                 -- STREAM_PROJECT  |PARTITIONED|
-                  unnest $$D <- scan-collection($$51) [cardinality: 30.0, op-cost: 0.0, total-cost: 30.0]
+                  unnest $$D <- scan-collection($$51) [cardinality: 99.0, op-cost: 0.0, total-cost: 99.0]
                   -- UNNEST  |PARTITIONED|
-                    project ([$$51]) [cardinality: 30.0, op-cost: 0.0, total-cost: 30.0]
+                    project ([$$51]) [cardinality: 99.0, op-cost: 0.0, total-cost: 99.0]
                     -- STREAM_PROJECT  |PARTITIONED|
-                      assign [$$51] <- [$$C.getField("dates")] [cardinality: 30.0, op-cost: 0.0, total-cost: 30.0]
+                      assign [$$51] <- [$$C.getField("dates")] [cardinality: 99.0, op-cost: 0.0, total-cost: 99.0]
                       -- ASSIGN  |PARTITIONED|
-                        project ([$$C]) [cardinality: 30.0, op-cost: 0.0, total-cost: 30.0]
+                        project ([$$C]) [cardinality: 99.0, op-cost: 0.0, total-cost: 99.0]
                         -- STREAM_PROJECT  |PARTITIONED|
-                          exchange [cardinality: 30.0, op-cost: 0.0, total-cost: 30.0]
+                          exchange [cardinality: 99.0, op-cost: 0.0, total-cost: 99.0]
                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                            data-scan []<-[$$49, $$C] <- TestYelp.YelpCheckin project ({dates:[any]}) filter on: gt(numeric-add(scan-collection($$C.getField("dates")), 1), 2018) [cardinality: 30.0, op-cost: 30.0, total-cost: 30.0]
+                            data-scan []<-[$$49, $$C] <- TestYelp.YelpCheckin project ({dates:[any]}) filter on: gt(numeric-add(scan-collection($$C.getField("dates")), 1), 2018) [cardinality: 99.0, op-cost: 99.0, total-cost: 99.0]
                             -- DATASOURCE_SCAN  |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/column/filter/005/005.011.plan b/asterixdb/asterix-app/src/test/resources/runtimets/results_cbo/column/filter/005/005.011.plan
index 1930f1c..40ac636 100644
--- a/asterixdb/asterix-app/src/test/resources/runtimets/results_cbo/column/filter/005/005.011.plan
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/results_cbo/column/filter/005/005.011.plan
@@ -1,32 +1,32 @@
-distribute result [$$51] [cardinality: 8.0, op-cost: 0.0, total-cost: 30.0]
+distribute result [$$51] [cardinality: 8.0, op-cost: 0.0, total-cost: 99.0]
 -- DISTRIBUTE_RESULT  |UNPARTITIONED|
-  exchange [cardinality: 8.0, op-cost: 0.0, total-cost: 30.0]
+  exchange [cardinality: 8.0, op-cost: 0.0, total-cost: 99.0]
   -- ONE_TO_ONE_EXCHANGE  |UNPARTITIONED|
-    project ([$$51]) [cardinality: 8.0, op-cost: 0.0, total-cost: 30.0]
+    project ([$$51]) [cardinality: 8.0, op-cost: 0.0, total-cost: 99.0]
     -- STREAM_PROJECT  |UNPARTITIONED|
-      assign [$$51] <- [{"$1": $$53}] [cardinality: 8.0, op-cost: 0.0, total-cost: 30.0]
+      assign [$$51] <- [{"$1": $$53}] [cardinality: 8.0, op-cost: 0.0, total-cost: 99.0]
       -- ASSIGN  |UNPARTITIONED|
-        aggregate [$$53] <- [agg-sql-sum($$55)] [cardinality: 8.0, op-cost: 0.0, total-cost: 30.0]
+        aggregate [$$53] <- [agg-sql-sum($$55)] [cardinality: 8.0, op-cost: 0.0, total-cost: 99.0]
         -- AGGREGATE  |UNPARTITIONED|
-          exchange [cardinality: 8.0, op-cost: 0.0, total-cost: 30.0]
+          exchange [cardinality: 8.0, op-cost: 0.0, total-cost: 99.0]
           -- RANDOM_MERGE_EXCHANGE  |PARTITIONED|
-            aggregate [$$55] <- [agg-sql-count(1)] [cardinality: 8.0, op-cost: 0.0, total-cost: 30.0]
+            aggregate [$$55] <- [agg-sql-count(1)] [cardinality: 8.0, op-cost: 0.0, total-cost: 99.0]
             -- AGGREGATE  |PARTITIONED|
-              select (or(gt(numeric-add($$D, 1), 2018), eq(substring($$D, 0, 4), "2011"))) [cardinality: 8.0, op-cost: 0.0, total-cost: 30.0]
+              select (or(gt(numeric-add($$D, 1), 2018), eq(substring($$D, 0, 4), "2011"))) [cardinality: 8.0, op-cost: 0.0, total-cost: 99.0]
               -- STREAM_SELECT  |PARTITIONED|
-                project ([$$D]) [cardinality: 30.0, op-cost: 0.0, total-cost: 30.0]
+                project ([$$D]) [cardinality: 99.0, op-cost: 0.0, total-cost: 99.0]
                 -- STREAM_PROJECT  |PARTITIONED|
-                  unnest $$D <- scan-collection($$54) [cardinality: 30.0, op-cost: 0.0, total-cost: 30.0]
+                  unnest $$D <- scan-collection($$54) [cardinality: 99.0, op-cost: 0.0, total-cost: 99.0]
                   -- UNNEST  |PARTITIONED|
-                    project ([$$54]) [cardinality: 30.0, op-cost: 0.0, total-cost: 30.0]
+                    project ([$$54]) [cardinality: 99.0, op-cost: 0.0, total-cost: 99.0]
                     -- STREAM_PROJECT  |PARTITIONED|
-                      assign [$$54] <- [$$C.getField("dates")] [cardinality: 30.0, op-cost: 0.0, total-cost: 30.0]
+                      assign [$$54] <- [$$C.getField("dates")] [cardinality: 99.0, op-cost: 0.0, total-cost: 99.0]
                       -- ASSIGN  |PARTITIONED|
-                        project ([$$C]) [cardinality: 30.0, op-cost: 0.0, total-cost: 30.0]
+                        project ([$$C]) [cardinality: 99.0, op-cost: 0.0, total-cost: 99.0]
                         -- STREAM_PROJECT  |PARTITIONED|
-                          exchange [cardinality: 30.0, op-cost: 0.0, total-cost: 30.0]
+                          exchange [cardinality: 99.0, op-cost: 0.0, total-cost: 99.0]
                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                            data-scan []<-[$$52, $$C] <- TestYelp.YelpCheckin project ({dates:[any]}) filter on: or(gt(numeric-add(scan-collection($$C.getField("dates")), 1), 2018), eq(substring(scan-collection($$C.getField("dates")), 0, 4), "2011")) [cardinality: 30.0, op-cost: 30.0, total-cost: 30.0]
+                            data-scan []<-[$$52, $$C] <- TestYelp.YelpCheckin project ({dates:[any]}) filter on: or(gt(numeric-add(scan-collection($$C.getField("dates")), 1), 2018), eq(substring(scan-collection($$C.getField("dates")), 0, 4), "2011")) [cardinality: 99.0, op-cost: 99.0, total-cost: 99.0]
                             -- DATASOURCE_SCAN  |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/column/filter/subplan/subplan.032.plan b/asterixdb/asterix-app/src/test/resources/runtimets/results_cbo/column/filter/subplan/subplan.032.plan
index c51972e..41ca4c2 100644
--- a/asterixdb/asterix-app/src/test/resources/runtimets/results_cbo/column/filter/subplan/subplan.032.plan
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/results_cbo/column/filter/subplan/subplan.032.plan
@@ -1,16 +1,16 @@
-distribute result [$$70] [cardinality: 2.1, op-cost: 0.0, total-cost: 17.0]
+distribute result [$$70] [cardinality: 2.1, op-cost: 0.0, total-cost: 12.0]
 -- DISTRIBUTE_RESULT  |UNPARTITIONED|
-  exchange [cardinality: 2.1, op-cost: 0.0, total-cost: 17.0]
+  exchange [cardinality: 2.1, op-cost: 0.0, total-cost: 12.0]
   -- ONE_TO_ONE_EXCHANGE  |UNPARTITIONED|
-    aggregate [$$70] <- [agg-sql-sum($$76)] [cardinality: 2.1, op-cost: 0.0, total-cost: 17.0]
+    aggregate [$$70] <- [agg-sql-sum($$76)] [cardinality: 2.1, op-cost: 0.0, total-cost: 12.0]
     -- AGGREGATE  |UNPARTITIONED|
-      exchange [cardinality: 2.1, op-cost: 0.0, total-cost: 17.0]
+      exchange [cardinality: 2.1, op-cost: 0.0, total-cost: 12.0]
       -- RANDOM_MERGE_EXCHANGE  |PARTITIONED|
-        aggregate [$$76] <- [agg-sql-count(1)] [cardinality: 2.1, op-cost: 0.0, total-cost: 17.0]
+        aggregate [$$76] <- [agg-sql-count(1)] [cardinality: 2.1, op-cost: 0.0, total-cost: 12.0]
         -- AGGREGATE  |PARTITIONED|
-          exchange [cardinality: 2.1, op-cost: 0.0, total-cost: 17.0]
+          exchange [cardinality: 2.1, op-cost: 0.0, total-cost: 12.0]
           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-            join (true) [cardinality: 2.1, op-cost: 1.0, total-cost: 17.0]
+            join (true) [cardinality: 2.1, op-cost: 1.0, total-cost: 12.0]
             -- NESTED_LOOP  |PARTITIONED|
               exchange [cardinality: 1.0, op-cost: 0.0, total-cost: 6.0]
               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
@@ -18,59 +18,59 @@
                 -- STREAM_PROJECT  |PARTITIONED|
                   select (eq($$p.getField("arrayOrObject").getField("text"), "7")) [cardinality: 1.0, op-cost: 0.0, total-cost: 6.0]
                   -- STREAM_SELECT  |PARTITIONED|
-                    project ([$$p]) [cardinality: 6.0, op-cost: 0.0, total-cost: 6.0]
+                    project ([$$p]) [cardinality: 1.0, op-cost: 0.0, total-cost: 1.0]
                     -- STREAM_PROJECT  |PARTITIONED|
-                      assign [$$p] <- [$$b2] [cardinality: 6.0, op-cost: 0.0, total-cost: 6.0]
+                      assign [$$p] <- [$$b2] [cardinality: 1.0, op-cost: 0.0, total-cost: 1.0]
                       -- ASSIGN  |PARTITIONED|
-                        exchange [cardinality: 6.0, op-cost: 0.0, total-cost: 6.0]
+                        exchange [cardinality: 1.0, op-cost: 0.0, total-cost: 1.0]
                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                          replicate [cardinality: 6.0, op-cost: 0.0, total-cost: 6.0]
+                          replicate [cardinality: 1.0, op-cost: 0.0, total-cost: 1.0]
                           -- REPLICATE  |PARTITIONED|
-                            exchange [cardinality: 6.0, op-cost: 4.0, total-cost: 10.0]
+                            exchange [cardinality: 1.0, op-cost: 4.0, total-cost: 5.0]
                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                              project ([$$b2]) [cardinality: 6.0, op-cost: 0.0, total-cost: 6.0]
+                              project ([$$b2]) [cardinality: 1.0, op-cost: 0.0, total-cost: 1.0]
                               -- STREAM_PROJECT  |PARTITIONED|
-                                exchange [cardinality: 6.0, op-cost: 4.0, total-cost: 10.0]
+                                exchange [cardinality: 1.0, op-cost: 4.0, total-cost: 5.0]
                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                  data-scan []<-[$$68, $$b2] <- test.ColumnDataset project ({arrayOrObject:<[{text:any}],{text:any}>}) filter on: or(eq($$b2.getField("arrayOrObject").getField("text"), "7"), eq(scan-collection($$b2.getField("arrayOrObject")).getField("text"), "1")) range-filter on: or(eq($$b2.getField("arrayOrObject").getField("text"), "7"), eq(scan-collection($$b2.getField("arrayOrObject")).getField("text"), "1")) [cardinality: 6.0, op-cost: 6.0, total-cost: 6.0]
+                                  data-scan []<-[$$68, $$b2] <- test.ColumnDataset project ({arrayOrObject:<[{text:any}],{text:any}>}) filter on: or(eq($$b2.getField("arrayOrObject").getField("text"), "7"), eq(scan-collection($$b2.getField("arrayOrObject")).getField("text"), "1")) range-filter on: or(eq($$b2.getField("arrayOrObject").getField("text"), "7"), eq(scan-collection($$b2.getField("arrayOrObject")).getField("text"), "1")) [cardinality: 1.0, op-cost: 1.0, total-cost: 1.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: 10.0]
+              exchange [cardinality: 1.0, op-cost: 4.0, total-cost: 5.0]
               -- BROADCAST_EXCHANGE  |PARTITIONED|
-                project ([]) [cardinality: 1.0, op-cost: 0.0, total-cost: 6.0]
+                project ([]) [cardinality: 1.0, op-cost: 0.0, total-cost: 1.0]
                 -- STREAM_PROJECT  |UNPARTITIONED|
-                  select (neq($$69, 0)) [cardinality: 1.0, op-cost: 0.0, total-cost: 6.0]
+                  select (neq($$69, 0)) [cardinality: 1.0, op-cost: 0.0, total-cost: 1.0]
                   -- STREAM_SELECT  |UNPARTITIONED|
-                    aggregate [$$69] <- [agg-sum($$75)] [cardinality: 6.0, op-cost: 0.0, total-cost: 6.0]
+                    aggregate [$$69] <- [agg-sum($$75)] [cardinality: 1.0, op-cost: 0.0, total-cost: 1.0]
                     -- AGGREGATE  |UNPARTITIONED|
-                      exchange [cardinality: 6.0, op-cost: 4.0, total-cost: 10.0]
+                      exchange [cardinality: 1.0, op-cost: 4.0, total-cost: 5.0]
                       -- RANDOM_MERGE_EXCHANGE  |PARTITIONED|
-                        aggregate [$$75] <- [agg-count(1)] [cardinality: 6.0, op-cost: 0.0, total-cost: 6.0]
+                        aggregate [$$75] <- [agg-count(1)] [cardinality: 1.0, op-cost: 0.0, total-cost: 1.0]
                         -- AGGREGATE  |PARTITIONED|
                           select (eq($$ao.getField("text"), "1")) [cardinality: 0.0, op-cost: 0.0, total-cost: 0.0]
                           -- STREAM_SELECT  |PARTITIONED|
-                            project ([$$ao]) [cardinality: 6.0, op-cost: 0.0, total-cost: 6.0]
+                            project ([$$ao]) [cardinality: 1.0, op-cost: 0.0, total-cost: 1.0]
                             -- STREAM_PROJECT  |PARTITIONED|
-                              unnest $$ao <- scan-collection($$72) [cardinality: 6.0, op-cost: 0.0, total-cost: 6.0]
+                              unnest $$ao <- scan-collection($$72) [cardinality: 1.0, op-cost: 0.0, total-cost: 1.0]
                               -- UNNEST  |PARTITIONED|
-                                project ([$$72]) [cardinality: 6.0, op-cost: 0.0, total-cost: 6.0]
+                                project ([$$72]) [cardinality: 1.0, op-cost: 0.0, total-cost: 1.0]
                                 -- STREAM_PROJECT  |PARTITIONED|
-                                  assign [$$72] <- [$$b2.getField("arrayOrObject")] [cardinality: 6.0, op-cost: 0.0, total-cost: 6.0]
+                                  assign [$$72] <- [$$b2.getField("arrayOrObject")] [cardinality: 1.0, op-cost: 0.0, total-cost: 1.0]
                                   -- ASSIGN  |PARTITIONED|
-                                    exchange [cardinality: 6.0, op-cost: 4.0, total-cost: 10.0]
+                                    exchange [cardinality: 1.0, op-cost: 4.0, total-cost: 5.0]
                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                      replicate [cardinality: 6.0, op-cost: 0.0, total-cost: 6.0]
+                                      replicate [cardinality: 1.0, op-cost: 0.0, total-cost: 1.0]
                                       -- REPLICATE  |PARTITIONED|
-                                        exchange [cardinality: 6.0, op-cost: 4.0, total-cost: 10.0]
+                                        exchange [cardinality: 1.0, op-cost: 4.0, total-cost: 5.0]
                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                          project ([$$b2]) [cardinality: 6.0, op-cost: 0.0, total-cost: 6.0]
+                                          project ([$$b2]) [cardinality: 1.0, op-cost: 0.0, total-cost: 1.0]
                                           -- STREAM_PROJECT  |PARTITIONED|
-                                            exchange [cardinality: 6.0, op-cost: 4.0, total-cost: 10.0]
+                                            exchange [cardinality: 1.0, op-cost: 4.0, total-cost: 5.0]
                                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                              data-scan []<-[$$68, $$b2] <- test.ColumnDataset project ({arrayOrObject:<[{text:any}],{text:any}>}) filter on: or(eq($$b2.getField("arrayOrObject").getField("text"), "7"), eq(scan-collection($$b2.getField("arrayOrObject")).getField("text"), "1")) range-filter on: or(eq($$b2.getField("arrayOrObject").getField("text"), "7"), eq(scan-collection($$b2.getField("arrayOrObject")).getField("text"), "1")) [cardinality: 6.0, op-cost: 6.0, total-cost: 6.0]
+                                              data-scan []<-[$$68, $$b2] <- test.ColumnDataset project ({arrayOrObject:<[{text:any}],{text:any}>}) filter on: or(eq($$b2.getField("arrayOrObject").getField("text"), "7"), eq(scan-collection($$b2.getField("arrayOrObject")).getField("text"), "1")) range-filter on: or(eq($$b2.getField("arrayOrObject").getField("text"), "7"), eq(scan-collection($$b2.getField("arrayOrObject")).getField("text"), "1")) [cardinality: 1.0, op-cost: 1.0, total-cost: 1.0]
                                               -- DATASOURCE_SCAN  |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/column/pushdown/array-access-pushdown/array-access-pushdown.008.plan b/asterixdb/asterix-app/src/test/resources/runtimets/results_cbo/column/pushdown/array-access-pushdown/array-access-pushdown.008.plan
index 491db48..95d96c1 100644
--- a/asterixdb/asterix-app/src/test/resources/runtimets/results_cbo/column/pushdown/array-access-pushdown/array-access-pushdown.008.plan
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/results_cbo/column/pushdown/array-access-pushdown/array-access-pushdown.008.plan
@@ -1,30 +1,30 @@
-distribute result [$$28] [cardinality: 2.0, op-cost: 0.0, total-cost: 2.0]
+distribute result [$$28] [cardinality: 1.0, op-cost: 0.0, total-cost: 1.0]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
-  exchange [cardinality: 2.0, op-cost: 0.0, total-cost: 2.0]
+  exchange [cardinality: 1.0, op-cost: 0.0, total-cost: 1.0]
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-    project ([$$28]) [cardinality: 2.0, op-cost: 0.0, total-cost: 2.0]
+    project ([$$28]) [cardinality: 1.0, op-cost: 0.0, total-cost: 1.0]
     -- STREAM_PROJECT  |PARTITIONED|
-      assign [$$28] <- [{"display_url": $$urls.getField("display_url")}] [cardinality: 2.0, op-cost: 0.0, total-cost: 2.0]
+      assign [$$28] <- [{"display_url": $$urls.getField("display_url")}] [cardinality: 1.0, op-cost: 0.0, total-cost: 1.0]
       -- ASSIGN  |PARTITIONED|
-        project ([$$urls]) [cardinality: 2.0, op-cost: 0.0, total-cost: 2.0]
+        project ([$$urls]) [cardinality: 1.0, op-cost: 0.0, total-cost: 1.0]
         -- STREAM_PROJECT  |PARTITIONED|
-          exchange [cardinality: 2.0, op-cost: 0.0, total-cost: 2.0]
+          exchange [cardinality: 1.0, op-cost: 0.0, total-cost: 1.0]
           -- SORT_MERGE_EXCHANGE [$$30(ASC) ]  |PARTITIONED|
-            order (ASC, $$30) [cardinality: 2.0, op-cost: 0.0, total-cost: 2.0]
+            order (ASC, $$30) [cardinality: 1.0, op-cost: 0.0, total-cost: 1.0]
             -- STABLE_SORT [$$30(ASC)]  |PARTITIONED|
-              exchange [cardinality: 2.0, op-cost: 0.0, total-cost: 2.0]
+              exchange [cardinality: 1.0, op-cost: 0.0, total-cost: 1.0]
               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                project ([$$urls, $$30]) [cardinality: 2.0, op-cost: 0.0, total-cost: 2.0]
+                project ([$$urls, $$30]) [cardinality: 1.0, op-cost: 0.0, total-cost: 1.0]
                 -- STREAM_PROJECT  |PARTITIONED|
-                  unnest $$urls <- scan-collection($$31) [cardinality: 2.0, op-cost: 0.0, total-cost: 2.0]
+                  unnest $$urls <- scan-collection($$31) [cardinality: 1.0, op-cost: 0.0, total-cost: 1.0]
                   -- UNNEST  |PARTITIONED|
-                    project ([$$30, $$31]) [cardinality: 2.0, op-cost: 0.0, total-cost: 2.0]
+                    project ([$$30, $$31]) [cardinality: 1.0, op-cost: 0.0, total-cost: 1.0]
                     -- STREAM_PROJECT  |PARTITIONED|
-                      assign [$$31] <- [$$p.getField("entities").getField("urls")] [cardinality: 2.0, op-cost: 0.0, total-cost: 2.0]
+                      assign [$$31] <- [$$p.getField("entities").getField("urls")] [cardinality: 1.0, op-cost: 0.0, total-cost: 1.0]
                       -- ASSIGN  |PARTITIONED|
-                        exchange [cardinality: 2.0, op-cost: 0.0, total-cost: 2.0]
+                        exchange [cardinality: 1.0, op-cost: 0.0, total-cost: 1.0]
                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                          data-scan []<-[$$30, $$p] <- test.ColumnDataset project ({entities:{urls:[{display_url:any}]}}) [cardinality: 2.0, op-cost: 2.0, total-cost: 2.0]
+                          data-scan []<-[$$30, $$p] <- test.ColumnDataset project ({entities:{urls:[{display_url:any}]}}) [cardinality: 1.0, op-cost: 1.0, total-cost: 1.0]
                           -- DATASOURCE_SCAN  |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/column/pushdown/other-pushdowns/other-pushdowns.008.plan b/asterixdb/asterix-app/src/test/resources/runtimets/results_cbo/column/pushdown/other-pushdowns/other-pushdowns.008.plan
index e95038f..95a0f82 100644
--- a/asterixdb/asterix-app/src/test/resources/runtimets/results_cbo/column/pushdown/other-pushdowns/other-pushdowns.008.plan
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/results_cbo/column/pushdown/other-pushdowns/other-pushdowns.008.plan
@@ -1,50 +1,50 @@
-distribute result [$$69] [cardinality: 1.0, op-cost: 0.0, total-cost: 2.0]
+distribute result [$$69] [cardinality: 1.0, op-cost: 0.0, total-cost: 1.0]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
-  exchange [cardinality: 1.0, op-cost: 0.0, total-cost: 2.0]
+  exchange [cardinality: 1.0, op-cost: 0.0, total-cost: 1.0]
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-    project ([$$69]) [cardinality: 1.0, op-cost: 0.0, total-cost: 2.0]
+    project ([$$69]) [cardinality: 1.0, op-cost: 0.0, total-cost: 1.0]
     -- STREAM_PROJECT  |PARTITIONED|
-      assign [$$69] <- [{"text": $$text, "$1": $$73}] [cardinality: 1.0, op-cost: 0.0, total-cost: 2.0]
+      assign [$$69] <- [{"text": $$text, "$1": $$73}] [cardinality: 1.0, op-cost: 0.0, total-cost: 1.0]
       -- ASSIGN  |PARTITIONED|
-        exchange [cardinality: 1.0, op-cost: 0.0, total-cost: 2.0]
+        exchange [cardinality: 1.0, op-cost: 0.0, total-cost: 1.0]
         -- SORT_MERGE_EXCHANGE [$$text(ASC) ]  |PARTITIONED|
           group by ([$$text := $$81]) decor ([]) {
                     aggregate [$$73] <- [agg-global-sql-sum($$80)] [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: 1.0, op-cost: 0.0, total-cost: 2.0]
+                 } [cardinality: 1.0, op-cost: 0.0, total-cost: 1.0]
           -- SORT_GROUP_BY[$$81]  |PARTITIONED|
-            exchange [cardinality: 1.0, op-cost: 0.0, total-cost: 2.0]
+            exchange [cardinality: 1.0, op-cost: 0.0, total-cost: 1.0]
             -- HASH_PARTITION_EXCHANGE [$$81]  |PARTITIONED|
               group by ([$$81 := $$71]) decor ([]) {
                         aggregate [$$80] <- [agg-local-sql-sum(sql-count($$75))] [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: 1.0, op-cost: 0.0, total-cost: 2.0]
+                     } [cardinality: 1.0, op-cost: 0.0, total-cost: 1.0]
               -- SORT_GROUP_BY[$$71]  |PARTITIONED|
-                exchange [cardinality: 1.0, op-cost: 0.0, total-cost: 2.0]
+                exchange [cardinality: 1.0, op-cost: 0.0, total-cost: 1.0]
                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                  select (eq(lowercase($$71), "string")) [cardinality: 1.0, op-cost: 0.0, total-cost: 2.0]
+                  select (eq(lowercase($$71), "string")) [cardinality: 1.0, op-cost: 0.0, total-cost: 1.0]
                   -- STREAM_SELECT  |PARTITIONED|
-                    project ([$$75, $$71]) [cardinality: 2.0, op-cost: 0.0, total-cost: 2.0]
+                    project ([$$75, $$71]) [cardinality: 1.0, op-cost: 0.0, total-cost: 1.0]
                     -- STREAM_PROJECT  |PARTITIONED|
-                      assign [$$71] <- [$$ht.getField("display_url")] [cardinality: 2.0, op-cost: 0.0, total-cost: 2.0]
+                      assign [$$71] <- [$$ht.getField("display_url")] [cardinality: 1.0, op-cost: 0.0, total-cost: 1.0]
                       -- ASSIGN  |PARTITIONED|
-                        unnest $$ht <- scan-collection($$75) [cardinality: 2.0, op-cost: 0.0, total-cost: 2.0]
+                        unnest $$ht <- scan-collection($$75) [cardinality: 1.0, op-cost: 0.0, total-cost: 1.0]
                         -- UNNEST  |PARTITIONED|
-                          project ([$$75]) [cardinality: 2.0, op-cost: 0.0, total-cost: 2.0]
+                          project ([$$75]) [cardinality: 1.0, op-cost: 0.0, total-cost: 1.0]
                           -- STREAM_PROJECT  |PARTITIONED|
-                            assign [$$75] <- [$$p1.getField("entities").getField("urls")] [cardinality: 2.0, op-cost: 0.0, total-cost: 2.0]
+                            assign [$$75] <- [$$p1.getField("entities").getField("urls")] [cardinality: 1.0, op-cost: 0.0, total-cost: 1.0]
                             -- ASSIGN  |PARTITIONED|
-                              project ([$$p1]) [cardinality: 2.0, op-cost: 0.0, total-cost: 2.0]
+                              project ([$$p1]) [cardinality: 1.0, op-cost: 0.0, total-cost: 1.0]
                               -- STREAM_PROJECT  |PARTITIONED|
                                 select (neq($$72, "0")) [cardinality: 0.0, op-cost: 0.0, total-cost: 0.0]
                                 -- STREAM_SELECT  |PARTITIONED|
-                                  exchange [cardinality: 2.0, op-cost: 0.0, total-cost: 2.0]
+                                  exchange [cardinality: 1.0, op-cost: 0.0, total-cost: 1.0]
                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                    data-scan []<-[$$72, $$p1] <- test.ColumnDataset project ({entities:{urls:[{display_url:any}]}}) filter on: eq(lowercase(scan-collection($$p1.getField("entities").getField("urls")).getField("display_url")), "string") [cardinality: 2.0, op-cost: 2.0, total-cost: 2.0]
+                                    data-scan []<-[$$72, $$p1] <- test.ColumnDataset project ({entities:{urls:[{display_url:any}]}}) filter on: eq(lowercase(scan-collection($$p1.getField("entities").getField("urls")).getField("display_url")), "string") [cardinality: 1.0, op-cost: 1.0, total-cost: 1.0]
                                     -- DATASOURCE_SCAN  |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/column/pushdown/other-pushdowns/other-pushdowns.010.plan b/asterixdb/asterix-app/src/test/resources/runtimets/results_cbo/column/pushdown/other-pushdowns/other-pushdowns.010.plan
index 625c281..e5795d56 100644
--- a/asterixdb/asterix-app/src/test/resources/runtimets/results_cbo/column/pushdown/other-pushdowns/other-pushdowns.010.plan
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/results_cbo/column/pushdown/other-pushdowns/other-pushdowns.010.plan
@@ -1,52 +1,52 @@
-distribute result [$$68] [cardinality: 1.0, op-cost: 0.0, total-cost: 2.0]
+distribute result [$$68] [cardinality: 1.0, op-cost: 0.0, total-cost: 1.0]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
-  exchange [cardinality: 1.0, op-cost: 0.0, total-cost: 2.0]
+  exchange [cardinality: 1.0, op-cost: 0.0, total-cost: 1.0]
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-    project ([$$68]) [cardinality: 1.0, op-cost: 0.0, total-cost: 2.0]
+    project ([$$68]) [cardinality: 1.0, op-cost: 0.0, total-cost: 1.0]
     -- STREAM_PROJECT  |PARTITIONED|
-      assign [$$68] <- [{"text": $$text, "$1": $$72}] [cardinality: 1.0, op-cost: 0.0, total-cost: 2.0]
+      assign [$$68] <- [{"text": $$text, "$1": $$72}] [cardinality: 1.0, op-cost: 0.0, total-cost: 1.0]
       -- ASSIGN  |PARTITIONED|
-        exchange [cardinality: 1.0, op-cost: 0.0, total-cost: 2.0]
+        exchange [cardinality: 1.0, op-cost: 0.0, total-cost: 1.0]
         -- SORT_MERGE_EXCHANGE [$$text(ASC) ]  |PARTITIONED|
           group by ([$$text := $$79]) decor ([]) {
                     aggregate [$$72] <- [agg-global-sql-sum($$78)] [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: 1.0, op-cost: 0.0, total-cost: 2.0]
+                 } [cardinality: 1.0, op-cost: 0.0, total-cost: 1.0]
           -- SORT_GROUP_BY[$$79]  |PARTITIONED|
-            exchange [cardinality: 1.0, op-cost: 0.0, total-cost: 2.0]
+            exchange [cardinality: 1.0, op-cost: 0.0, total-cost: 1.0]
             -- HASH_PARTITION_EXCHANGE [$$79]  |PARTITIONED|
               group by ([$$79 := $$70]) decor ([]) {
                         aggregate [$$78] <- [agg-local-sql-sum(sql-sum($$75))] [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: 1.0, op-cost: 0.0, total-cost: 2.0]
+                     } [cardinality: 1.0, op-cost: 0.0, total-cost: 1.0]
               -- SORT_GROUP_BY[$$70]  |PARTITIONED|
-                exchange [cardinality: 1.0, op-cost: 0.0, total-cost: 2.0]
+                exchange [cardinality: 1.0, op-cost: 0.0, total-cost: 1.0]
                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                  select (eq(lowercase($$70), "string")) [cardinality: 1.0, op-cost: 0.0, total-cost: 2.0]
+                  select (eq(lowercase($$70), "string")) [cardinality: 1.0, op-cost: 0.0, total-cost: 1.0]
                   -- STREAM_SELECT  |PARTITIONED|
-                    project ([$$75, $$70]) [cardinality: 2.0, op-cost: 0.0, total-cost: 2.0]
+                    project ([$$75, $$70]) [cardinality: 1.0, op-cost: 0.0, total-cost: 1.0]
                     -- STREAM_PROJECT  |PARTITIONED|
-                      assign [$$75, $$70] <- [$$ht.getField("indices"), $$ht.getField("display_url")] [cardinality: 2.0, op-cost: 0.0, total-cost: 2.0]
+                      assign [$$75, $$70] <- [$$ht.getField("indices"), $$ht.getField("display_url")] [cardinality: 1.0, op-cost: 0.0, total-cost: 1.0]
                       -- ASSIGN  |PARTITIONED|
-                        project ([$$ht]) [cardinality: 2.0, op-cost: 0.0, total-cost: 2.0]
+                        project ([$$ht]) [cardinality: 1.0, op-cost: 0.0, total-cost: 1.0]
                         -- STREAM_PROJECT  |PARTITIONED|
-                          unnest $$ht <- scan-collection($$74) [cardinality: 2.0, op-cost: 0.0, total-cost: 2.0]
+                          unnest $$ht <- scan-collection($$74) [cardinality: 1.0, op-cost: 0.0, total-cost: 1.0]
                           -- UNNEST  |PARTITIONED|
-                            project ([$$74]) [cardinality: 2.0, op-cost: 0.0, total-cost: 2.0]
+                            project ([$$74]) [cardinality: 1.0, op-cost: 0.0, total-cost: 1.0]
                             -- STREAM_PROJECT  |PARTITIONED|
-                              assign [$$74] <- [$$p1.getField("entities").getField("urls")] [cardinality: 2.0, op-cost: 0.0, total-cost: 2.0]
+                              assign [$$74] <- [$$p1.getField("entities").getField("urls")] [cardinality: 1.0, op-cost: 0.0, total-cost: 1.0]
                               -- ASSIGN  |PARTITIONED|
-                                project ([$$p1]) [cardinality: 2.0, op-cost: 0.0, total-cost: 2.0]
+                                project ([$$p1]) [cardinality: 1.0, op-cost: 0.0, total-cost: 1.0]
                                 -- STREAM_PROJECT  |PARTITIONED|
                                   select (neq($$71, "0")) [cardinality: 0.0, op-cost: 0.0, total-cost: 0.0]
                                   -- STREAM_SELECT  |PARTITIONED|
-                                    exchange [cardinality: 2.0, op-cost: 0.0, total-cost: 2.0]
+                                    exchange [cardinality: 1.0, op-cost: 0.0, total-cost: 1.0]
                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                      data-scan []<-[$$71, $$p1] <- test.ColumnDataset project ({entities:{urls:[{display_url:any,indices:any}]}}) filter on: eq(lowercase(scan-collection($$p1.getField("entities").getField("urls")).getField("display_url")), "string") [cardinality: 2.0, op-cost: 2.0, total-cost: 2.0]
+                                      data-scan []<-[$$71, $$p1] <- test.ColumnDataset project ({entities:{urls:[{display_url:any,indices:any}]}}) filter on: eq(lowercase(scan-collection($$p1.getField("entities").getField("urls")).getField("display_url")), "string") [cardinality: 1.0, op-cost: 1.0, total-cost: 1.0]
                                       -- DATASOURCE_SCAN  |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/column/pushdown/other-pushdowns/other-pushdowns.014.plan b/asterixdb/asterix-app/src/test/resources/runtimets/results_cbo/column/pushdown/other-pushdowns/other-pushdowns.014.plan
index 2182bcc..4ec8540 100644
--- a/asterixdb/asterix-app/src/test/resources/runtimets/results_cbo/column/pushdown/other-pushdowns/other-pushdowns.014.plan
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/results_cbo/column/pushdown/other-pushdowns/other-pushdowns.014.plan
@@ -1,42 +1,42 @@
-distribute result [$$101] [cardinality: 0.0, op-cost: 0.0, total-cost: 6.5]
+distribute result [$$101] [cardinality: 0.0, op-cost: 0.0, total-cost: 5.5]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
-  exchange [cardinality: 0.0, op-cost: 0.0, total-cost: 6.5]
+  exchange [cardinality: 0.0, op-cost: 0.0, total-cost: 5.5]
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-    project ([$$101]) [cardinality: 0.0, op-cost: 0.0, total-cost: 6.5]
+    project ([$$101]) [cardinality: 0.0, op-cost: 0.0, total-cost: 5.5]
     -- STREAM_PROJECT  |PARTITIONED|
-      assign [$$101] <- [{"uname": $$uname, "cnt": $$105}] [cardinality: 0.0, op-cost: 0.0, total-cost: 6.5]
+      assign [$$101] <- [{"uname": $$uname, "cnt": $$105}] [cardinality: 0.0, op-cost: 0.0, total-cost: 5.5]
       -- ASSIGN  |PARTITIONED|
-        exchange [cardinality: 0.0, op-cost: 0.0, total-cost: 6.5]
+        exchange [cardinality: 0.0, op-cost: 0.0, total-cost: 5.5]
         -- SORT_MERGE_EXCHANGE [$$105(DESC), $$uname(ASC) ]  |PARTITIONED|
-          order (DESC, $$105) (ASC, $$uname) [cardinality: 0.0, op-cost: 0.0, total-cost: 6.5]
+          order (DESC, $$105) (ASC, $$uname) [cardinality: 0.0, op-cost: 0.0, total-cost: 5.5]
           -- STABLE_SORT [$$105(DESC), $$uname(ASC)]  |PARTITIONED|
-            exchange [cardinality: 0.0, op-cost: 0.0, total-cost: 6.5]
+            exchange [cardinality: 0.0, op-cost: 0.0, total-cost: 5.5]
             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
               group by ([$$uname := $$116]) decor ([]) {
                         aggregate [$$105] <- [agg-sql-sum($$115)] [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: 6.5]
+                     } [cardinality: 0.0, op-cost: 0.0, total-cost: 5.5]
               -- SORT_GROUP_BY[$$116]  |PARTITIONED|
-                exchange [cardinality: 0.0, op-cost: 0.0, total-cost: 6.5]
+                exchange [cardinality: 0.0, op-cost: 0.0, total-cost: 5.5]
                 -- HASH_PARTITION_EXCHANGE [$$116]  |PARTITIONED|
                   group by ([$$116 := $$102]) decor ([]) {
                             aggregate [$$115] <- [agg-sql-count(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: 0.0, op-cost: 0.0, total-cost: 6.5]
+                         } [cardinality: 0.0, op-cost: 0.0, total-cost: 5.5]
                   -- SORT_GROUP_BY[$$102]  |PARTITIONED|
-                    exchange [cardinality: 0.0, op-cost: 0.0, total-cost: 6.5]
+                    exchange [cardinality: 0.0, op-cost: 0.0, total-cost: 5.5]
                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                      project ([$$102]) [cardinality: 0.0, op-cost: 0.0, total-cost: 6.5]
+                      project ([$$102]) [cardinality: 0.0, op-cost: 0.0, total-cost: 5.5]
                       -- STREAM_PROJECT  |PARTITIONED|
                         select ($$92) [cardinality: 0.0, op-cost: 0.0, total-cost: 0.0]
                         -- STREAM_SELECT  |PARTITIONED|
-                          project ([$$92, $$102]) [cardinality: 0.0, op-cost: 0.0, total-cost: 6.5]
+                          project ([$$92, $$102]) [cardinality: 0.0, op-cost: 0.0, total-cost: 5.5]
                           -- STREAM_PROJECT  |PARTITIONED|
-                            exchange [cardinality: 0.0, op-cost: 0.0, total-cost: 6.5]
+                            exchange [cardinality: 0.0, op-cost: 0.0, total-cost: 5.5]
                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
                               group by ([$$114 := $$112]) decor ([$$102]) {
                                         aggregate [$$92] <- [non-empty-stream()] [cardinality: 0.0, op-cost: 0.0, total-cost: 0.0]
@@ -45,41 +45,41 @@
                                           -- 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: 2.25, total-cost: 6.5]
+                                     } [cardinality: 0.0, op-cost: 2.25, total-cost: 5.5]
                               -- PRE_CLUSTERED_GROUP_BY[$$112]  |PARTITIONED|
-                                exchange [cardinality: 2.0, op-cost: 0.0, total-cost: 4.25]
+                                exchange [cardinality: 1.0, op-cost: 0.0, total-cost: 3.25]
                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                  order (ASC, $$112) [cardinality: 2.0, op-cost: 2.25, total-cost: 4.25]
+                                  order (ASC, $$112) [cardinality: 1.0, op-cost: 2.25, total-cost: 3.25]
                                   -- STABLE_SORT [$$112(ASC)]  |PARTITIONED|
-                                    exchange [cardinality: 2.0, op-cost: 0.0, total-cost: 2.0]
+                                    exchange [cardinality: 1.0, op-cost: 0.0, total-cost: 1.0]
                                     -- HASH_PARTITION_EXCHANGE [$$112]  |PARTITIONED|
-                                      project ([$$102, $$113, $$112]) [cardinality: 2.0, op-cost: 0.0, total-cost: 2.0]
+                                      project ([$$102, $$113, $$112]) [cardinality: 1.0, op-cost: 0.0, total-cost: 1.0]
                                       -- STREAM_PROJECT  |PARTITIONED|
-                                        exchange [cardinality: 2.0, op-cost: 0.0, total-cost: 2.0]
+                                        exchange [cardinality: 1.0, op-cost: 0.0, total-cost: 1.0]
                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                          left outer join (eq($$106, $$88)) [cardinality: 2.1, op-cost: 2.0, total-cost: 8.0]
+                                          left outer join (eq($$106, $$88)) [cardinality: 2.1, op-cost: 2.0, total-cost: 6.0]
                                           -- HYBRID_HASH_JOIN [$$106][$$88]  |PARTITIONED|
-                                            exchange [cardinality: 2.0, op-cost: 0.0, total-cost: 2.0]
+                                            exchange [cardinality: 1.0, op-cost: 0.0, total-cost: 1.0]
                                             -- HASH_PARTITION_EXCHANGE [$$106]  |PARTITIONED|
-                                              running-aggregate [$$112] <- [create-query-uid()] [cardinality: 2.0, op-cost: 0.0, total-cost: 2.0]
+                                              running-aggregate [$$112] <- [create-query-uid()] [cardinality: 1.0, op-cost: 0.0, total-cost: 1.0]
                                               -- RUNNING_AGGREGATE  |PARTITIONED|
-                                                project ([$$102, $$106]) [cardinality: 2.0, op-cost: 0.0, total-cost: 2.0]
+                                                project ([$$102, $$106]) [cardinality: 1.0, op-cost: 0.0, total-cost: 1.0]
                                                 -- STREAM_PROJECT  |PARTITIONED|
-                                                  assign [$$106] <- [$$ht1.getField("display_url")] [cardinality: 2.0, op-cost: 0.0, total-cost: 2.0]
+                                                  assign [$$106] <- [$$ht1.getField("display_url")] [cardinality: 1.0, op-cost: 0.0, total-cost: 1.0]
                                                   -- ASSIGN  |PARTITIONED|
-                                                    project ([$$102, $$ht1]) [cardinality: 2.0, op-cost: 0.0, total-cost: 2.0]
+                                                    project ([$$102, $$ht1]) [cardinality: 1.0, op-cost: 0.0, total-cost: 1.0]
                                                     -- STREAM_PROJECT  |PARTITIONED|
-                                                      unnest $$ht1 <- scan-collection($$107) [cardinality: 2.0, op-cost: 0.0, total-cost: 2.0]
+                                                      unnest $$ht1 <- scan-collection($$107) [cardinality: 1.0, op-cost: 0.0, total-cost: 1.0]
                                                       -- UNNEST  |PARTITIONED|
-                                                        project ([$$107, $$102]) [cardinality: 2.0, op-cost: 0.0, total-cost: 2.0]
+                                                        project ([$$107, $$102]) [cardinality: 1.0, op-cost: 0.0, total-cost: 1.0]
                                                         -- STREAM_PROJECT  |PARTITIONED|
-                                                          assign [$$107, $$102] <- [$$p1.getField("entities").getField("urls"), $$p1.getField("user").getField("name")] [cardinality: 2.0, op-cost: 0.0, total-cost: 2.0]
+                                                          assign [$$107, $$102] <- [$$p1.getField("entities").getField("urls"), $$p1.getField("user").getField("name")] [cardinality: 1.0, op-cost: 0.0, total-cost: 1.0]
                                                           -- ASSIGN  |PARTITIONED|
-                                                            project ([$$p1]) [cardinality: 2.0, op-cost: 0.0, total-cost: 2.0]
+                                                            project ([$$p1]) [cardinality: 1.0, op-cost: 0.0, total-cost: 1.0]
                                                             -- STREAM_PROJECT  |PARTITIONED|
-                                                              exchange [cardinality: 2.0, op-cost: 0.0, total-cost: 2.0]
+                                                              exchange [cardinality: 1.0, op-cost: 0.0, total-cost: 1.0]
                                                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                                data-scan []<-[$$103, $$p1] <- test.ColumnDataset project ({entities:{urls:[{display_url:any}]},user:{name:any}}) [cardinality: 2.0, op-cost: 2.0, total-cost: 2.0]
+                                                                data-scan []<-[$$103, $$p1] <- test.ColumnDataset project ({entities:{urls:[{display_url:any}]},user:{name:any}}) [cardinality: 1.0, op-cost: 1.0, total-cost: 1.0]
                                                                 -- DATASOURCE_SCAN  |PARTITIONED|
                                                                   exchange [cardinality: 0.0, op-cost: 0.0, total-cost: 0.0]
                                                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
@@ -93,7 +93,7 @@
                                                 -- ASSIGN  |PARTITIONED|
                                                   project ([$$ht2]) [cardinality: 0.0, op-cost: 0.0, total-cost: 0.0]
                                                   -- STREAM_PROJECT  |PARTITIONED|
-                                                    unnest $$ht2 <- scan-collection($$108) [cardinality: 1.0, op-cost: 2.0, total-cost: 2.0]
+                                                    unnest $$ht2 <- scan-collection($$108) [cardinality: 1.0, op-cost: 1.0, total-cost: 1.0]
                                                     -- UNNEST  |PARTITIONED|
                                                       project ([$$108]) [cardinality: 0.0, op-cost: 0.0, total-cost: 0.0]
                                                       -- STREAM_PROJECT  |PARTITIONED|
@@ -103,7 +103,7 @@
                                                           -- STREAM_PROJECT  |PARTITIONED|
                                                             exchange [cardinality: 0.0, op-cost: 0.0, total-cost: 0.0]
                                                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                              data-scan []<-[$$104, $$p2] <- test.RowDataset [cardinality: 2.0, op-cost: 2.0, total-cost: 2.0]
+                                                              data-scan []<-[$$104, $$p2] <- test.RowDataset [cardinality: 1.0, op-cost: 1.0, total-cost: 1.0]
                                                               -- DATASOURCE_SCAN  |PARTITIONED|
                                                                 exchange [cardinality: 0.0, op-cost: 0.0, total-cost: 0.0]
                                                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|