[ASTERIXDB-3181][RT] Support sampling columnar datasets

- user model changes: no
- storage format changes: no
- interface changes: yes

Details:
This patch adds the support for creating samples of
columnar datasets.

Change-Id: I4a895cd22160c7a053df96898050d511879013fb
Reviewed-on: https://asterix-gerrit.ics.uci.edu/c/asterixdb/+/17523
Reviewed-by: Murtadha Hubail <mhubail@apache.org>
Tested-by: Murtadha Hubail <mhubail@apache.org>
Integration-Tests: Murtadha Hubail <mhubail@apache.org>
diff --git a/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/pushdown/OperatorValueAccessPushdownVisitor.java b/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/pushdown/OperatorValueAccessPushdownVisitor.java
index ae7b919..ce1fe68 100644
--- a/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/pushdown/OperatorValueAccessPushdownVisitor.java
+++ b/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/pushdown/OperatorValueAccessPushdownVisitor.java
@@ -260,7 +260,7 @@
      * 2- return the actual DatasetDataSource
      */
     private DatasetDataSource getDatasetDataSourceIfApplicable(DataSource dataSource) throws AlgebricksException {
-        if (dataSource == null) {
+        if (dataSource == null || dataSource.getDatasourceType() == DataSource.Type.SAMPLE) {
             return null;
         }
 
diff --git a/asterixdb/asterix-app/src/test/java/org/apache/asterix/test/runtime/SqlppAnalyzedExecutionTest.java b/asterixdb/asterix-app/src/test/java/org/apache/asterix/test/runtime/SqlppAnalyzedExecutionTest.java
index a6fb0d4..10a22b4 100644
--- a/asterixdb/asterix-app/src/test/java/org/apache/asterix/test/runtime/SqlppAnalyzedExecutionTest.java
+++ b/asterixdb/asterix-app/src/test/java/org/apache/asterix/test/runtime/SqlppAnalyzedExecutionTest.java
@@ -44,8 +44,8 @@
 public class SqlppAnalyzedExecutionTest {
     protected static final String TEST_CONFIG_FILE_NAME = "src/test/resources/cc-analyze.conf";
     private final String[] denyList = { "synonym: synonym-01", "ddl: analyze-dataset-1", "misc: dump_index",
-            "array-index: composite-index-queries", "filters: upsert", "column: ", "ddl: analyze-dataset-with-indexes",
-            "warnings: cardinality-hint-warning" };
+            "array-index: composite-index-queries", "filters: upsert", "column: analyze-dataset",
+            "ddl: analyze-dataset-with-indexes", "warnings: cardinality-hint-warning" };
 
     @BeforeClass
     public static void setUp() throws Exception {
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/column/analyze-dataset/analyze-dataset.001.ddl.sqlpp b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/column/analyze-dataset/analyze-dataset.001.ddl.sqlpp
new file mode 100644
index 0000000..d90ca4b
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/column/analyze-dataset/analyze-dataset.001.ddl.sqlpp
@@ -0,0 +1,33 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+SET `import-private-functions` `true`;
+
+DROP DATAVERSE test IF EXISTS;
+CREATE DATAVERSE test;
+USE test;
+
+CREATE TYPE t1 AS OPEN {
+  id : bigint
+};
+
+CREATE DATASET ds1(t1)
+PRIMARY KEY id WITH {
+    "storage-format": {"format" : "column"}
+};
\ No newline at end of file
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/column/analyze-dataset/analyze-dataset.002.update.sqlpp b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/column/analyze-dataset/analyze-dataset.002.update.sqlpp
new file mode 100644
index 0000000..39e577a
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/column/analyze-dataset/analyze-dataset.002.update.sqlpp
@@ -0,0 +1,24 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+USE test;
+
+INSERT INTO ds1
+SELECT VALUE {'id':x, 'x':-x }
+FROM range(1, 2000) x;
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/column/analyze-dataset/analyze-dataset.003.get.http b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/column/analyze-dataset/analyze-dataset.003.get.http
new file mode 100644
index 0000000..788866c
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/column/analyze-dataset/analyze-dataset.003.get.http
@@ -0,0 +1,19 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+/connector?dataverseName=test&datasetName=ds1
\ No newline at end of file
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/column/analyze-dataset/analyze-dataset.004.ddl.sqlpp b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/column/analyze-dataset/analyze-dataset.004.ddl.sqlpp
new file mode 100644
index 0000000..e771c7e
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/column/analyze-dataset/analyze-dataset.004.ddl.sqlpp
@@ -0,0 +1,22 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+USE test;
+
+ANALYZE DATASET ds1 WITH { "sample": "low", "sample-seed": 123 };
\ No newline at end of file
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/column/analyze-dataset/analyze-dataset.005.query.sqlpp b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/column/analyze-dataset/analyze-dataset.005.query.sqlpp
new file mode 100644
index 0000000..347abed
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/column/analyze-dataset/analyze-dataset.005.query.sqlpp
@@ -0,0 +1,25 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+SET `import-private-functions` `true`;
+
+USE test;
+
+SELECT VALUE COUNT(*)
+FROM dump_index("test", "ds1", "sample_idx_1_ds1") as s
\ No newline at end of file
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/column/analyze-dataset/analyze-dataset.006.query.sqlpp b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/column/analyze-dataset/analyze-dataset.006.query.sqlpp
new file mode 100644
index 0000000..a54b029
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/column/analyze-dataset/analyze-dataset.006.query.sqlpp
@@ -0,0 +1,25 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+SET `import-private-functions` `true`;
+
+USE test;
+
+SELECT VALUE SUM(CASE WHEN s.values[1].id = -s.values[1].x THEN 1 ELSE 0 END)
+FROM dump_index("test", "ds1", "sample_idx_1_ds1") as s
\ No newline at end of file
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/results/column/analyze-dataset/analyze-dataset.003.regexadm b/asterixdb/asterix-app/src/test/resources/runtimets/results/column/analyze-dataset/analyze-dataset.003.regexadm
new file mode 100644
index 0000000..52c0081
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/results/column/analyze-dataset/analyze-dataset.003.regexadm
@@ -0,0 +1 @@
+\Q{"keys":"id","type":{"type":"org.apache.asterix.om.types.ARecordType","name":"t1","open":true,"fields":[{"id":{"type":"AInt64"}}]},"splits":[\E.*\Q]}\E
\ No newline at end of file
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/results/column/analyze-dataset/analyze-dataset.005.adm b/asterixdb/asterix-app/src/test/resources/runtimets/results/column/analyze-dataset/analyze-dataset.005.adm
new file mode 100644
index 0000000..e4b9b2c
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/results/column/analyze-dataset/analyze-dataset.005.adm
@@ -0,0 +1 @@
+1064
\ No newline at end of file
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/results/column/analyze-dataset/analyze-dataset.006.adm b/asterixdb/asterix-app/src/test/resources/runtimets/results/column/analyze-dataset/analyze-dataset.006.adm
new file mode 100644
index 0000000..e4b9b2c
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/results/column/analyze-dataset/analyze-dataset.006.adm
@@ -0,0 +1 @@
+1064
\ No newline at end of file
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/results_cbo/column/filter/001/001.007.plan b/asterixdb/asterix-app/src/test/resources/runtimets/results_cbo/column/filter/001/001.007.plan
new file mode 100644
index 0000000..57b0572
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/results_cbo/column/filter/001/001.007.plan
@@ -0,0 +1,26 @@
+distribute result [$$d] [cardinality: 1.0, op-cost: 0.0, total-cost: 1.0]
+-- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange [cardinality: 1.0, op-cost: 0.0, total-cost: 1.0]
+  -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    project ([$$d]) [cardinality: 1.0, op-cost: 0.0, total-cost: 1.0]
+    -- STREAM_PROJECT  |PARTITIONED|
+      exchange [cardinality: 1.0, op-cost: 0.0, total-cost: 1.0]
+      -- SORT_MERGE_EXCHANGE [$$20(ASC) ]  |PARTITIONED|
+        order (ASC, $$20) [cardinality: 1.0, op-cost: 0.0, total-cost: 1.0]
+        -- STABLE_SORT [$$20(ASC)]  |PARTITIONED|
+          exchange [cardinality: 1.0, op-cost: 0.0, total-cost: 1.0]
+          -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+            project ([$$d, $$20]) [cardinality: 1.0, op-cost: 0.0, total-cost: 1.0]
+            -- STREAM_PROJECT  |PARTITIONED|
+              select (and(gt($$19, "1"), lt($$19, "3"))) [cardinality: 1.0, op-cost: 0.0, total-cost: 1.0]
+              -- STREAM_SELECT  |PARTITIONED|
+                assign [$$19] <- [$$d.getField("a")] [cardinality: 6.0, op-cost: 0.0, total-cost: 1.0]
+                -- ASSIGN  |PARTITIONED|
+                  exchange [cardinality: 6.0, op-cost: 0.0, total-cost: 1.0]
+                  -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                    data-scan []<-[$$20, $$d] <- test.ColumnDataset filter on (and(gt($$19, "1"), lt($$19, "3"))) [cardinality: 6.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|
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/results_cbo/column/filter/001/001.009.plan b/asterixdb/asterix-app/src/test/resources/runtimets/results_cbo/column/filter/001/001.009.plan
new file mode 100644
index 0000000..1ed6e29
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/results_cbo/column/filter/001/001.009.plan
@@ -0,0 +1,26 @@
+distribute result [$$d] [cardinality: 0.11, op-cost: 0.0, total-cost: 0.11]
+-- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange [cardinality: 0.11, op-cost: 0.0, total-cost: 0.11]
+  -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    project ([$$d]) [cardinality: 0.11, op-cost: 0.0, total-cost: 0.11]
+    -- STREAM_PROJECT  |PARTITIONED|
+      exchange [cardinality: 0.11, op-cost: 0.0, total-cost: 0.11]
+      -- SORT_MERGE_EXCHANGE [$$20(ASC) ]  |PARTITIONED|
+        order (ASC, $$20) [cardinality: 0.11, op-cost: 0.0, total-cost: 0.11]
+        -- STABLE_SORT [$$20(ASC)]  |PARTITIONED|
+          exchange [cardinality: 0.11, op-cost: 0.0, total-cost: 0.11]
+          -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+            project ([$$d, $$20]) [cardinality: 0.11, op-cost: 0.0, total-cost: 0.11]
+            -- STREAM_PROJECT  |PARTITIONED|
+              select (and(gt($$19, 1), lt($$19, 3))) [cardinality: 0.11, op-cost: 0.0, total-cost: 0.11]
+              -- STREAM_SELECT  |PARTITIONED|
+                assign [$$19] <- [$$d.getField("a")] [cardinality: 6.0, op-cost: 0.0, total-cost: 0.11]
+                -- ASSIGN  |PARTITIONED|
+                  exchange [cardinality: 6.0, op-cost: 0.0, total-cost: 0.11]
+                  -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                    data-scan []<-[$$20, $$d] <- test.ColumnDataset filter on (and(gt($$19, 1), lt($$19, 3))) [cardinality: 6.0, op-cost: 0.11, total-cost: 0.11]
+                    -- 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|
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/results_cbo/column/filter/001/001.011.plan b/asterixdb/asterix-app/src/test/resources/runtimets/results_cbo/column/filter/001/001.011.plan
new file mode 100644
index 0000000..642b823
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/results_cbo/column/filter/001/001.011.plan
@@ -0,0 +1,39 @@
+distribute result [$$d] [cardinality: 0.11, op-cost: 0.0, total-cost: 0.11]
+-- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange [cardinality: 0.11, op-cost: 0.0, total-cost: 0.11]
+  -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    project ([$$d]) [cardinality: 0.11, op-cost: 0.0, total-cost: 0.11]
+    -- STREAM_PROJECT  |PARTITIONED|
+      exchange [cardinality: 0.11, op-cost: 0.0, total-cost: 0.11]
+      -- SORT_MERGE_EXCHANGE [$$28(ASC) ]  |PARTITIONED|
+        order (ASC, $$28) [cardinality: 0.11, op-cost: 0.0, total-cost: 0.11]
+        -- STABLE_SORT [$$28(ASC)]  |PARTITIONED|
+          exchange [cardinality: 0.11, op-cost: 0.0, total-cost: 0.11]
+          -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+            project ([$$d, $$28]) [cardinality: 0.11, op-cost: 0.0, total-cost: 0.11]
+            -- STREAM_PROJECT  |PARTITIONED|
+              select ($$26) [cardinality: 0.11, op-cost: 0.0, total-cost: 0.11]
+              -- STREAM_SELECT  |PARTITIONED|
+                project ([$$28, $$d, $$26]) [cardinality: 6.0, op-cost: 0.0, total-cost: 0.11]
+                -- STREAM_PROJECT  |PARTITIONED|
+                  subplan {
+                            aggregate [$$26] <- [non-empty-stream()] [cardinality: 0.0, op-cost: 0.0, total-cost: 0.0]
+                            -- AGGREGATE  |LOCAL|
+                              select (lt($$a, "100")) [cardinality: 0.0, op-cost: 0.0, total-cost: 0.0]
+                              -- STREAM_SELECT  |LOCAL|
+                                unnest $$a <- scan-collection($$29) [cardinality: 0.0, op-cost: 0.0, total-cost: 0.0]
+                                -- UNNEST  |LOCAL|
+                                  nested tuple source [cardinality: 0.0, op-cost: 0.0, total-cost: 0.0]
+                                  -- NESTED_TUPLE_SOURCE  |LOCAL|
+                         } [cardinality: 6.0, op-cost: 0.0, total-cost: 0.11]
+                  -- SUBPLAN  |PARTITIONED|
+                    assign [$$29] <- [$$d.getField("array")] [cardinality: 6.0, op-cost: 0.0, total-cost: 0.11]
+                    -- ASSIGN  |PARTITIONED|
+                      exchange [cardinality: 6.0, op-cost: 0.0, total-cost: 0.11]
+                      -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                        data-scan []<-[$$28, $$d] <- test.ColumnDataset filter on (lt($$a, "100")) [cardinality: 6.0, op-cost: 0.11, total-cost: 0.11]
+                        -- 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|
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/results_cbo/column/filter/001/001.013.plan b/asterixdb/asterix-app/src/test/resources/runtimets/results_cbo/column/filter/001/001.013.plan
new file mode 100644
index 0000000..3252e98
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/results_cbo/column/filter/001/001.013.plan
@@ -0,0 +1,39 @@
+distribute result [$$d] [cardinality: 3.0, op-cost: 0.0, total-cost: 3.0]
+-- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange [cardinality: 3.0, op-cost: 0.0, total-cost: 3.0]
+  -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    project ([$$d]) [cardinality: 3.0, op-cost: 0.0, total-cost: 3.0]
+    -- STREAM_PROJECT  |PARTITIONED|
+      exchange [cardinality: 3.0, op-cost: 0.0, total-cost: 3.0]
+      -- SORT_MERGE_EXCHANGE [$$28(ASC) ]  |PARTITIONED|
+        order (ASC, $$28) [cardinality: 3.0, op-cost: 0.0, total-cost: 3.0]
+        -- STABLE_SORT [$$28(ASC)]  |PARTITIONED|
+          exchange [cardinality: 3.0, op-cost: 0.0, total-cost: 3.0]
+          -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+            project ([$$d, $$28]) [cardinality: 3.0, op-cost: 0.0, total-cost: 3.0]
+            -- STREAM_PROJECT  |PARTITIONED|
+              select ($$26) [cardinality: 3.0, op-cost: 0.0, total-cost: 3.0]
+              -- STREAM_SELECT  |PARTITIONED|
+                project ([$$28, $$d, $$26]) [cardinality: 6.0, op-cost: 0.0, total-cost: 3.0]
+                -- STREAM_PROJECT  |PARTITIONED|
+                  subplan {
+                            aggregate [$$26] <- [non-empty-stream()] [cardinality: 0.0, op-cost: 0.0, total-cost: 0.0]
+                            -- AGGREGATE  |LOCAL|
+                              select (lt($$a, 100)) [cardinality: 0.0, op-cost: 0.0, total-cost: 0.0]
+                              -- STREAM_SELECT  |LOCAL|
+                                unnest $$a <- scan-collection($$29) [cardinality: 0.0, op-cost: 0.0, total-cost: 0.0]
+                                -- UNNEST  |LOCAL|
+                                  nested tuple source [cardinality: 0.0, op-cost: 0.0, total-cost: 0.0]
+                                  -- NESTED_TUPLE_SOURCE  |LOCAL|
+                         } [cardinality: 6.0, op-cost: 0.0, total-cost: 3.0]
+                  -- SUBPLAN  |PARTITIONED|
+                    assign [$$29] <- [$$d.getField("array")] [cardinality: 6.0, op-cost: 0.0, total-cost: 3.0]
+                    -- ASSIGN  |PARTITIONED|
+                      exchange [cardinality: 6.0, op-cost: 0.0, total-cost: 3.0]
+                      -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                        data-scan []<-[$$28, $$d] <- test.ColumnDataset filter on (lt($$a, 100)) [cardinality: 6.0, op-cost: 3.0, total-cost: 3.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|
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/results_cbo/column/filter/001/001.015.plan b/asterixdb/asterix-app/src/test/resources/runtimets/results_cbo/column/filter/001/001.015.plan
new file mode 100644
index 0000000..8659d34
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/results_cbo/column/filter/001/001.015.plan
@@ -0,0 +1,39 @@
+distribute result [$$d] [cardinality: 1.0, op-cost: 0.0, total-cost: 1.0]
+-- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange [cardinality: 1.0, op-cost: 0.0, total-cost: 1.0]
+  -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    project ([$$d]) [cardinality: 1.0, op-cost: 0.0, total-cost: 1.0]
+    -- STREAM_PROJECT  |PARTITIONED|
+      exchange [cardinality: 1.0, op-cost: 0.0, total-cost: 1.0]
+      -- SORT_MERGE_EXCHANGE [$$28(ASC) ]  |PARTITIONED|
+        order (ASC, $$28) [cardinality: 1.0, op-cost: 0.0, total-cost: 1.0]
+        -- STABLE_SORT [$$28(ASC)]  |PARTITIONED|
+          exchange [cardinality: 1.0, op-cost: 0.0, total-cost: 1.0]
+          -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+            project ([$$d, $$28]) [cardinality: 1.0, op-cost: 0.0, total-cost: 1.0]
+            -- STREAM_PROJECT  |PARTITIONED|
+              select ($$26) [cardinality: 1.0, op-cost: 0.0, total-cost: 1.0]
+              -- STREAM_SELECT  |PARTITIONED|
+                project ([$$28, $$d, $$26]) [cardinality: 6.0, op-cost: 0.0, total-cost: 1.0]
+                -- STREAM_PROJECT  |PARTITIONED|
+                  subplan {
+                            aggregate [$$26] <- [non-empty-stream()] [cardinality: 0.0, op-cost: 0.0, total-cost: 0.0]
+                            -- AGGREGATE  |LOCAL|
+                              select (eq($$a, 100)) [cardinality: 0.0, op-cost: 0.0, total-cost: 0.0]
+                              -- STREAM_SELECT  |LOCAL|
+                                unnest $$a <- scan-collection($$29) [cardinality: 0.0, op-cost: 0.0, total-cost: 0.0]
+                                -- UNNEST  |LOCAL|
+                                  nested tuple source [cardinality: 0.0, op-cost: 0.0, total-cost: 0.0]
+                                  -- NESTED_TUPLE_SOURCE  |LOCAL|
+                         } [cardinality: 6.0, op-cost: 0.0, total-cost: 1.0]
+                  -- SUBPLAN  |PARTITIONED|
+                    assign [$$29] <- [$$d.getField("array")] [cardinality: 6.0, op-cost: 0.0, total-cost: 1.0]
+                    -- ASSIGN  |PARTITIONED|
+                      exchange [cardinality: 6.0, op-cost: 0.0, total-cost: 1.0]
+                      -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                        data-scan []<-[$$28, $$d] <- test.ColumnDataset filter on (eq($$a, 100)) [cardinality: 6.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|
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/results_cbo/column/filter/001/001.017.plan b/asterixdb/asterix-app/src/test/resources/runtimets/results_cbo/column/filter/001/001.017.plan
new file mode 100644
index 0000000..17622bb
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/results_cbo/column/filter/001/001.017.plan
@@ -0,0 +1,39 @@
+distribute result [$$d] [cardinality: 4.0, op-cost: 0.0, total-cost: 4.0]
+-- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange [cardinality: 4.0, op-cost: 0.0, total-cost: 4.0]
+  -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    project ([$$d]) [cardinality: 4.0, op-cost: 0.0, total-cost: 4.0]
+    -- STREAM_PROJECT  |PARTITIONED|
+      exchange [cardinality: 4.0, op-cost: 0.0, total-cost: 4.0]
+      -- SORT_MERGE_EXCHANGE [$$28(ASC) ]  |PARTITIONED|
+        order (ASC, $$28) [cardinality: 4.0, op-cost: 0.0, total-cost: 4.0]
+        -- STABLE_SORT [$$28(ASC)]  |PARTITIONED|
+          exchange [cardinality: 4.0, op-cost: 0.0, total-cost: 4.0]
+          -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+            project ([$$d, $$28]) [cardinality: 4.0, op-cost: 0.0, total-cost: 4.0]
+            -- STREAM_PROJECT  |PARTITIONED|
+              select ($$26) [cardinality: 4.0, op-cost: 0.0, total-cost: 4.0]
+              -- STREAM_SELECT  |PARTITIONED|
+                project ([$$28, $$d, $$26]) [cardinality: 6.0, op-cost: 0.0, total-cost: 4.0]
+                -- STREAM_PROJECT  |PARTITIONED|
+                  subplan {
+                            aggregate [$$26] <- [non-empty-stream()] [cardinality: 0.0, op-cost: 0.0, total-cost: 0.0]
+                            -- AGGREGATE  |LOCAL|
+                              select (lt($$a, 100.1)) [cardinality: 0.0, op-cost: 0.0, total-cost: 0.0]
+                              -- STREAM_SELECT  |LOCAL|
+                                unnest $$a <- scan-collection($$29) [cardinality: 0.0, op-cost: 0.0, total-cost: 0.0]
+                                -- UNNEST  |LOCAL|
+                                  nested tuple source [cardinality: 0.0, op-cost: 0.0, total-cost: 0.0]
+                                  -- NESTED_TUPLE_SOURCE  |LOCAL|
+                         } [cardinality: 6.0, op-cost: 0.0, total-cost: 4.0]
+                  -- SUBPLAN  |PARTITIONED|
+                    assign [$$29] <- [$$d.getField("array")] [cardinality: 6.0, op-cost: 0.0, total-cost: 4.0]
+                    -- ASSIGN  |PARTITIONED|
+                      exchange [cardinality: 6.0, op-cost: 0.0, total-cost: 4.0]
+                      -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                        data-scan []<-[$$28, $$d] <- test.ColumnDataset filter on (lt($$a, 100.1)) [cardinality: 6.0, op-cost: 4.0, total-cost: 4.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|
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
new file mode 100644
index 0000000..ee14cae
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/results_cbo/column/filter/001/001.019.plan
@@ -0,0 +1,30 @@
+distribute result [$$item] [cardinality: 3.0, op-cost: 0.0, total-cost: 3.0]
+-- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange [cardinality: 3.0, op-cost: 0.0, total-cost: 3.0]
+  -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    project ([$$item]) [cardinality: 3.0, op-cost: 0.0, total-cost: 3.0]
+    -- STREAM_PROJECT  |PARTITIONED|
+      exchange [cardinality: 3.0, op-cost: 0.0, total-cost: 3.0]
+      -- SORT_MERGE_EXCHANGE [$$29(ASC), $$item(ASC) ]  |PARTITIONED|
+        order (ASC, $$29) (ASC, $$item) [cardinality: 3.0, op-cost: 0.0, total-cost: 3.0]
+        -- STABLE_SORT [$$29(ASC), $$item(ASC)]  |PARTITIONED|
+          exchange [cardinality: 3.0, op-cost: 0.0, total-cost: 3.0]
+          -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+            select (and(gt($$item, 60), lt($$item, 100))) [cardinality: 3.0, op-cost: 0.0, total-cost: 3.0]
+            -- STREAM_SELECT  |PARTITIONED|
+              project ([$$29, $$item]) [cardinality: 6.0, op-cost: 0.0, total-cost: 3.0]
+              -- STREAM_PROJECT  |PARTITIONED|
+                unnest $$item <- scan-collection($$30) [cardinality: 6.0, op-cost: 0.0, total-cost: 3.0]
+                -- UNNEST  |PARTITIONED|
+                  project ([$$29, $$30]) [cardinality: 6.0, op-cost: 0.0, total-cost: 3.0]
+                  -- STREAM_PROJECT  |PARTITIONED|
+                    assign [$$30] <- [$$d.getField("array")] [cardinality: 6.0, op-cost: 0.0, total-cost: 3.0]
+                    -- ASSIGN  |PARTITIONED|
+                      exchange [cardinality: 6.0, op-cost: 0.0, total-cost: 3.0]
+                      -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                        data-scan []<-[$$29, $$d] <- test.ColumnDataset project ({array:[any]}) filter on (and(gt($$item, 60), lt($$item, 100))) [cardinality: 6.0, op-cost: 3.0, total-cost: 3.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|
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
new file mode 100644
index 0000000..3eb5d69
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/results_cbo/column/filter/001/001.021.plan
@@ -0,0 +1,30 @@
+distribute result [$$item] [cardinality: 1.0, op-cost: 0.0, total-cost: 1.0]
+-- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange [cardinality: 1.0, op-cost: 0.0, total-cost: 1.0]
+  -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    project ([$$item]) [cardinality: 1.0, op-cost: 0.0, total-cost: 1.0]
+    -- STREAM_PROJECT  |PARTITIONED|
+      exchange [cardinality: 1.0, op-cost: 0.0, total-cost: 1.0]
+      -- SORT_MERGE_EXCHANGE [$$27(ASC), $$item(ASC) ]  |PARTITIONED|
+        order (ASC, $$27) (ASC, $$item) [cardinality: 1.0, op-cost: 0.0, total-cost: 1.0]
+        -- STABLE_SORT [$$27(ASC), $$item(ASC)]  |PARTITIONED|
+          exchange [cardinality: 1.0, op-cost: 0.0, total-cost: 1.0]
+          -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+            select (eq($$item, 100)) [cardinality: 1.0, op-cost: 0.0, total-cost: 1.0]
+            -- STREAM_SELECT  |PARTITIONED|
+              project ([$$27, $$item]) [cardinality: 6.0, op-cost: 0.0, total-cost: 1.0]
+              -- STREAM_PROJECT  |PARTITIONED|
+                unnest $$item <- scan-collection($$28) [cardinality: 6.0, op-cost: 0.0, total-cost: 1.0]
+                -- UNNEST  |PARTITIONED|
+                  project ([$$27, $$28]) [cardinality: 6.0, op-cost: 0.0, total-cost: 1.0]
+                  -- STREAM_PROJECT  |PARTITIONED|
+                    assign [$$28] <- [$$d.getField("array")] [cardinality: 6.0, op-cost: 0.0, total-cost: 1.0]
+                    -- ASSIGN  |PARTITIONED|
+                      exchange [cardinality: 6.0, op-cost: 0.0, total-cost: 1.0]
+                      -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                        data-scan []<-[$$27, $$d] <- test.ColumnDataset project ({array:[any]}) filter on (eq($$item, 100)) [cardinality: 6.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|
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
new file mode 100644
index 0000000..1db3103
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/results_cbo/column/filter/001/001.023.plan
@@ -0,0 +1,30 @@
+distribute result [$$item] [cardinality: 0.11, op-cost: 0.0, total-cost: 0.11]
+-- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange [cardinality: 0.11, op-cost: 0.0, total-cost: 0.11]
+  -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    project ([$$item]) [cardinality: 0.11, op-cost: 0.0, total-cost: 0.11]
+    -- STREAM_PROJECT  |PARTITIONED|
+      exchange [cardinality: 0.11, op-cost: 0.0, total-cost: 0.11]
+      -- SORT_MERGE_EXCHANGE [$$27(ASC), $$item(ASC) ]  |PARTITIONED|
+        order (ASC, $$27) (ASC, $$item) [cardinality: 0.11, op-cost: 0.0, total-cost: 0.11]
+        -- STABLE_SORT [$$27(ASC), $$item(ASC)]  |PARTITIONED|
+          exchange [cardinality: 0.11, op-cost: 0.0, total-cost: 0.11]
+          -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+            select (gt($$item, 10000)) [cardinality: 0.11, op-cost: 0.0, total-cost: 0.11]
+            -- STREAM_SELECT  |PARTITIONED|
+              project ([$$27, $$item]) [cardinality: 6.0, op-cost: 0.0, total-cost: 0.11]
+              -- STREAM_PROJECT  |PARTITIONED|
+                unnest $$item <- scan-collection($$28) [cardinality: 6.0, op-cost: 0.0, total-cost: 0.11]
+                -- UNNEST  |PARTITIONED|
+                  project ([$$27, $$28]) [cardinality: 6.0, op-cost: 0.0, total-cost: 0.11]
+                  -- STREAM_PROJECT  |PARTITIONED|
+                    assign [$$28] <- [$$d.getField("array")] [cardinality: 6.0, op-cost: 0.0, total-cost: 0.11]
+                    -- ASSIGN  |PARTITIONED|
+                      exchange [cardinality: 6.0, op-cost: 0.0, total-cost: 0.11]
+                      -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                        data-scan []<-[$$27, $$d] <- test.ColumnDataset project ({array:[any]}) filter on (gt($$item, 10000)) [cardinality: 6.0, op-cost: 0.11, total-cost: 0.11]
+                        -- 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|
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/results_cbo/column/pushdown/array-access-pushdown/array-access-pushdown.004.plan b/asterixdb/asterix-app/src/test/resources/runtimets/results_cbo/column/pushdown/array-access-pushdown/array-access-pushdown.004.plan
new file mode 100644
index 0000000..afa9eea
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/results_cbo/column/pushdown/array-access-pushdown/array-access-pushdown.004.plan
@@ -0,0 +1,28 @@
+distribute result [$$18] [cardinality: 2.0, op-cost: 0.0, total-cost: 2.1]
+-- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange [cardinality: 2.0, op-cost: 0.0, total-cost: 2.1]
+  -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    project ([$$18]) [cardinality: 2.0, op-cost: 0.0, total-cost: 2.1]
+    -- STREAM_PROJECT  |PARTITIONED|
+      assign [$$18] <- [{"display_url": $$22}] [cardinality: 2.0, op-cost: 0.0, total-cost: 2.1]
+      -- ASSIGN  |PARTITIONED|
+        project ([$$22]) [cardinality: 2.0, op-cost: 0.0, total-cost: 2.1]
+        -- STREAM_PROJECT  |PARTITIONED|
+          exchange [cardinality: 2.0, op-cost: 0.0, total-cost: 2.1]
+          -- SORT_MERGE_EXCHANGE [$$20(ASC) ]  |PARTITIONED|
+            order (ASC, $$20) [cardinality: 2.0, op-cost: 0.0, total-cost: 2.1]
+            -- STABLE_SORT [$$20(ASC)]  |PARTITIONED|
+              exchange [cardinality: 2.0, op-cost: 0.0, total-cost: 2.1]
+              -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                project ([$$22, $$20]) [cardinality: 2.0, op-cost: 0.0, total-cost: 2.1]
+                -- STREAM_PROJECT  |PARTITIONED|
+                  assign [$$22] <- [get-item($$p.getField("entities").getField("urls"), 0).getField("display_url")] [cardinality: 2.0, op-cost: 0.0, total-cost: 2.1]
+                  -- ASSIGN  |PARTITIONED|
+                    exchange [cardinality: 2.0, op-cost: 0.0, total-cost: 2.1]
+                    -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                      data-scan []<-[$$20, $$p] <- test.ColumnDataset project ({entities:{urls:[{display_url:any}]}}) [cardinality: 2.0, op-cost: 2.1, total-cost: 2.1]
+                      -- 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|
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/results_cbo/column/pushdown/array-access-pushdown/array-access-pushdown.006.plan b/asterixdb/asterix-app/src/test/resources/runtimets/results_cbo/column/pushdown/array-access-pushdown/array-access-pushdown.006.plan
new file mode 100644
index 0000000..342dfc1
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/results_cbo/column/pushdown/array-access-pushdown/array-access-pushdown.006.plan
@@ -0,0 +1,34 @@
+distribute result [$$22] [cardinality: 2.1, op-cost: 0.0, total-cost: 2.1]
+-- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange [cardinality: 2.1, op-cost: 0.0, total-cost: 2.1]
+  -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    project ([$$22]) [cardinality: 2.1, op-cost: 0.0, total-cost: 2.1]
+    -- STREAM_PROJECT  |PARTITIONED|
+      assign [$$22] <- [{"display_url": $$27}] [cardinality: 2.1, op-cost: 0.0, total-cost: 2.1]
+      -- ASSIGN  |PARTITIONED|
+        project ([$$27]) [cardinality: 2.1, op-cost: 0.0, total-cost: 2.1]
+        -- STREAM_PROJECT  |PARTITIONED|
+          exchange [cardinality: 2.1, op-cost: 0.0, total-cost: 2.1]
+          -- SORT_MERGE_EXCHANGE [$$25(ASC) ]  |PARTITIONED|
+            order (ASC, $$25) [cardinality: 2.1, op-cost: 0.0, total-cost: 2.1]
+            -- STABLE_SORT [$$25(ASC)]  |PARTITIONED|
+              exchange [cardinality: 2.1, op-cost: 0.0, total-cost: 2.1]
+              -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                project ([$$27, $$25]) [cardinality: 2.1, op-cost: 0.0, total-cost: 2.1]
+                -- STREAM_PROJECT  |PARTITIONED|
+                  assign [$$27] <- [array-star($$24).getField("display_url")] [cardinality: 2.1, op-cost: 0.0, total-cost: 2.1]
+                  -- ASSIGN  |PARTITIONED|
+                    select (not(is-missing($$24))) [cardinality: 2.1, op-cost: 0.0, total-cost: 2.1]
+                    -- STREAM_SELECT  |PARTITIONED|
+                      project ([$$25, $$24]) [cardinality: 2.0, op-cost: 0.0, total-cost: 2.1]
+                      -- STREAM_PROJECT  |PARTITIONED|
+                        assign [$$24] <- [$$p.getField("entities").getField("urls")] [cardinality: 2.0, op-cost: 0.0, total-cost: 2.1]
+                        -- ASSIGN  |PARTITIONED|
+                          exchange [cardinality: 2.0, op-cost: 0.0, total-cost: 2.1]
+                          -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                            data-scan []<-[$$25, $$p] <- test.ColumnDataset project ({entities:{urls:[{display_url:any}]}}) [cardinality: 2.0, op-cost: 2.1, total-cost: 2.1]
+                            -- 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|
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
new file mode 100644
index 0000000..40c755a
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/results_cbo/column/pushdown/array-access-pushdown/array-access-pushdown.008.plan
@@ -0,0 +1,32 @@
+distribute result [$$28] [cardinality: 2.0, op-cost: 0.0, total-cost: 2.1]
+-- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange [cardinality: 2.0, op-cost: 0.0, total-cost: 2.1]
+  -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    project ([$$28]) [cardinality: 2.0, op-cost: 0.0, total-cost: 2.1]
+    -- STREAM_PROJECT  |PARTITIONED|
+      assign [$$28] <- [{"display_url": $$urls.getField("display_url")}] [cardinality: 2.0, op-cost: 0.0, total-cost: 2.1]
+      -- ASSIGN  |PARTITIONED|
+        project ([$$urls]) [cardinality: 2.0, op-cost: 0.0, total-cost: 2.1]
+        -- STREAM_PROJECT  |PARTITIONED|
+          exchange [cardinality: 2.0, op-cost: 0.0, total-cost: 2.1]
+          -- SORT_MERGE_EXCHANGE [$$30(ASC) ]  |PARTITIONED|
+            order (ASC, $$30) [cardinality: 2.0, op-cost: 0.0, total-cost: 2.1]
+            -- STABLE_SORT [$$30(ASC)]  |PARTITIONED|
+              exchange [cardinality: 2.0, op-cost: 0.0, total-cost: 2.1]
+              -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                project ([$$urls, $$30]) [cardinality: 2.0, op-cost: 0.0, total-cost: 2.1]
+                -- STREAM_PROJECT  |PARTITIONED|
+                  unnest $$urls <- scan-collection($$31) [cardinality: 2.0, op-cost: 0.0, total-cost: 2.1]
+                  -- UNNEST  |PARTITIONED|
+                    project ([$$30, $$31]) [cardinality: 2.0, op-cost: 0.0, total-cost: 2.1]
+                    -- STREAM_PROJECT  |PARTITIONED|
+                      assign [$$31] <- [$$p.getField("entities").getField("urls")] [cardinality: 2.0, op-cost: 0.0, total-cost: 2.1]
+                      -- ASSIGN  |PARTITIONED|
+                        exchange [cardinality: 2.0, op-cost: 0.0, total-cost: 2.1]
+                        -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                          data-scan []<-[$$30, $$p] <- test.ColumnDataset project ({entities:{urls:[{display_url:any}]}}) [cardinality: 2.0, op-cost: 2.1, total-cost: 2.1]
+                          -- 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|
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/results_cbo/column/pushdown/array-access-pushdown/array-access-pushdown.010.plan b/asterixdb/asterix-app/src/test/resources/runtimets/results_cbo/column/pushdown/array-access-pushdown/array-access-pushdown.010.plan
new file mode 100644
index 0000000..d0bf0f0
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/results_cbo/column/pushdown/array-access-pushdown/array-access-pushdown.010.plan
@@ -0,0 +1,41 @@
+distribute result [$$50] [cardinality: 2.1, op-cost: 0.0, total-cost: 2.1]
+-- DISTRIBUTE_RESULT  |UNPARTITIONED|
+  exchange [cardinality: 2.1, op-cost: 0.0, total-cost: 2.1]
+  -- ONE_TO_ONE_EXCHANGE  |UNPARTITIONED|
+    aggregate [$$50] <- [agg-sql-sum($$54)] [cardinality: 2.1, op-cost: 0.0, total-cost: 2.1]
+    -- AGGREGATE  |UNPARTITIONED|
+      exchange [cardinality: 2.1, op-cost: 0.0, total-cost: 2.1]
+      -- RANDOM_MERGE_EXCHANGE  |PARTITIONED|
+        aggregate [$$54] <- [agg-sql-count(1)] [cardinality: 2.1, op-cost: 0.0, total-cost: 2.1]
+        -- AGGREGATE  |PARTITIONED|
+          select ($$42) [cardinality: 2.1, op-cost: 0.0, total-cost: 2.1]
+          -- STREAM_SELECT  |PARTITIONED|
+            project ([$$42]) [cardinality: 2.0, op-cost: 0.0, total-cost: 2.1]
+            -- STREAM_PROJECT  |PARTITIONED|
+              subplan {
+                        aggregate [$$42] <- [empty-stream()] [cardinality: 0.0, op-cost: 0.0, total-cost: 0.0]
+                        -- AGGREGATE  |LOCAL|
+                          select (not(if-missing-or-null(eq($$52, "string"), false))) [cardinality: 0.0, op-cost: 0.0, total-cost: 0.0]
+                          -- STREAM_SELECT  |LOCAL|
+                            assign [$$52] <- [$$ht.getField("display_url")] [cardinality: 0.0, op-cost: 0.0, total-cost: 0.0]
+                            -- ASSIGN  |LOCAL|
+                              unnest $$ht <- scan-collection($$51) [cardinality: 0.0, op-cost: 0.0, total-cost: 0.0]
+                              -- UNNEST  |LOCAL|
+                                nested tuple source [cardinality: 0.0, op-cost: 0.0, total-cost: 0.0]
+                                -- NESTED_TUPLE_SOURCE  |LOCAL|
+                     } [cardinality: 2.0, op-cost: 0.0, total-cost: 2.1]
+              -- SUBPLAN  |PARTITIONED|
+                project ([$$51]) [cardinality: 2.0, op-cost: 0.0, total-cost: 2.1]
+                -- STREAM_PROJECT  |PARTITIONED|
+                  assign [$$51] <- [$$p.getField("entities").getField("urls")] [cardinality: 2.0, op-cost: 0.0, total-cost: 2.1]
+                  -- ASSIGN  |PARTITIONED|
+                    project ([$$p]) [cardinality: 2.0, op-cost: 0.0, total-cost: 2.1]
+                    -- STREAM_PROJECT  |PARTITIONED|
+                      exchange [cardinality: 2.0, op-cost: 0.0, total-cost: 2.1]
+                      -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                        data-scan []<-[$$49, $$p] <- test.ColumnDataset project ({entities:{urls:[{display_url:any}]}}) [cardinality: 2.0, op-cost: 2.1, total-cost: 2.1]
+                        -- 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|
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/results_cbo/column/pushdown/array-access-pushdown/array-access-pushdown.012.plan b/asterixdb/asterix-app/src/test/resources/runtimets/results_cbo/column/pushdown/array-access-pushdown/array-access-pushdown.012.plan
new file mode 100644
index 0000000..3157c17
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/results_cbo/column/pushdown/array-access-pushdown/array-access-pushdown.012.plan
@@ -0,0 +1,28 @@
+distribute result [$$19] [cardinality: 2.0, op-cost: 0.0, total-cost: 2.1]
+-- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange [cardinality: 2.0, op-cost: 0.0, total-cost: 2.1]
+  -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    project ([$$19]) [cardinality: 2.0, op-cost: 0.0, total-cost: 2.1]
+    -- STREAM_PROJECT  |PARTITIONED|
+      assign [$$19] <- [get-item(get-item(get-item($$25.getField("coordinates"), 0), 0), 0)] [cardinality: 2.0, op-cost: 0.0, total-cost: 2.1]
+      -- ASSIGN  |PARTITIONED|
+        project ([$$25]) [cardinality: 2.0, op-cost: 0.0, total-cost: 2.1]
+        -- STREAM_PROJECT  |PARTITIONED|
+          exchange [cardinality: 2.0, op-cost: 0.0, total-cost: 2.1]
+          -- SORT_MERGE_EXCHANGE [$$21(ASC) ]  |PARTITIONED|
+            order (ASC, $$21) [cardinality: 2.0, op-cost: 0.0, total-cost: 2.1]
+            -- STABLE_SORT [$$21(ASC)]  |PARTITIONED|
+              exchange [cardinality: 2.0, op-cost: 0.0, total-cost: 2.1]
+              -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                project ([$$25, $$21]) [cardinality: 2.0, op-cost: 0.0, total-cost: 2.1]
+                -- STREAM_PROJECT  |PARTITIONED|
+                  assign [$$25] <- [$$p.getField("place").getField("bounding_box")] [cardinality: 2.0, op-cost: 0.0, total-cost: 2.1]
+                  -- ASSIGN  |PARTITIONED|
+                    exchange [cardinality: 2.0, op-cost: 0.0, total-cost: 2.1]
+                    -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                      data-scan []<-[$$21, $$p] <- test.ColumnDataset project ({place:{bounding_box:{coordinates:[[[any]]]}}}) [cardinality: 2.0, op-cost: 2.1, total-cost: 2.1]
+                      -- 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|
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/results_cbo/column/pushdown/field-access-pushdown/field-access-pushdown.004.plan b/asterixdb/asterix-app/src/test/resources/runtimets/results_cbo/column/pushdown/field-access-pushdown/field-access-pushdown.004.plan
new file mode 100644
index 0000000..f14ae25
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/results_cbo/column/pushdown/field-access-pushdown/field-access-pushdown.004.plan
@@ -0,0 +1,18 @@
+distribute result [$$p] [cardinality: 7.0, op-cost: 0.0, total-cost: 7.0]
+-- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange [cardinality: 7.0, op-cost: 0.0, total-cost: 7.0]
+  -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    project ([$$p]) [cardinality: 7.0, op-cost: 0.0, total-cost: 7.0]
+    -- STREAM_PROJECT  |PARTITIONED|
+      exchange [cardinality: 7.0, op-cost: 0.0, total-cost: 7.0]
+      -- SORT_MERGE_EXCHANGE [$$14(ASC) ]  |PARTITIONED|
+        order (ASC, $$14) [cardinality: 7.0, op-cost: 0.0, total-cost: 7.0]
+        -- STABLE_SORT [$$14(ASC)]  |PARTITIONED|
+          exchange [cardinality: 7.0, op-cost: 0.0, total-cost: 7.0]
+          -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+            data-scan []<-[$$14, $$p] <- test.ColumnDataset1 [cardinality: 7.0, op-cost: 7.0, total-cost: 7.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|
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/results_cbo/column/pushdown/field-access-pushdown/field-access-pushdown.006.plan b/asterixdb/asterix-app/src/test/resources/runtimets/results_cbo/column/pushdown/field-access-pushdown/field-access-pushdown.006.plan
new file mode 100644
index 0000000..5b8ddf3
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/results_cbo/column/pushdown/field-access-pushdown/field-access-pushdown.006.plan
@@ -0,0 +1,40 @@
+distribute result [$$30] [cardinality: 7.0, op-cost: 0.0, total-cost: 42.0]
+-- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange [cardinality: 7.0, op-cost: 0.0, total-cost: 42.0]
+  -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    project ([$$30]) [cardinality: 7.0, op-cost: 0.0, total-cost: 42.0]
+    -- STREAM_PROJECT  |PARTITIONED|
+      assign [$$30] <- [{"p1": $$p1, "id": $$34}] [cardinality: 7.0, op-cost: 0.0, total-cost: 42.0]
+      -- ASSIGN  |PARTITIONED|
+        exchange [cardinality: 7.0, op-cost: 0.0, total-cost: 42.0]
+        -- SORT_MERGE_EXCHANGE [$$34(ASC) ]  |PARTITIONED|
+          order (ASC, $$34) [cardinality: 7.0, op-cost: 0.0, total-cost: 42.0]
+          -- STABLE_SORT [$$34(ASC)]  |PARTITIONED|
+            exchange [cardinality: 7.0, op-cost: 0.0, total-cost: 42.0]
+            -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+              project ([$$p1, $$34]) [cardinality: 7.0, op-cost: 0.0, total-cost: 42.0]
+              -- STREAM_PROJECT  |PARTITIONED|
+                exchange [cardinality: 7.0, op-cost: 0.0, total-cost: 42.0]
+                -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                  join (eq($$33, $$34)) [cardinality: 7.0, op-cost: 14.0, total-cost: 42.0]
+                  -- HYBRID_HASH_JOIN [$$33][$$34]  |PARTITIONED|
+                    exchange [cardinality: 7.0, op-cost: 7.0, total-cost: 14.0]
+                    -- HASH_PARTITION_EXCHANGE [$$33]  |PARTITIONED|
+                      data-scan []<-[$$33, $$p1] <- test.ColumnDataset1 [cardinality: 7.0, op-cost: 7.0, total-cost: 7.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: 7.0, op-cost: 7.0, total-cost: 14.0]
+                    -- HASH_PARTITION_EXCHANGE [$$34]  |PARTITIONED|
+                      project ([$$34]) [cardinality: 7.0, op-cost: 0.0, total-cost: 7.0]
+                      -- STREAM_PROJECT  |PARTITIONED|
+                        exchange [cardinality: 7.0, op-cost: 7.0, total-cost: 14.0]
+                        -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                          data-scan []<-[$$34, $$p2] <- test.ColumnDataset2 project ({}) [cardinality: 7.0, op-cost: 7.0, total-cost: 7.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|
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/results_cbo/column/pushdown/field-access-pushdown/field-access-pushdown.008.plan b/asterixdb/asterix-app/src/test/resources/runtimets/results_cbo/column/pushdown/field-access-pushdown/field-access-pushdown.008.plan
new file mode 100644
index 0000000..acf9d3b
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/results_cbo/column/pushdown/field-access-pushdown/field-access-pushdown.008.plan
@@ -0,0 +1,44 @@
+distribute result [$$31] [cardinality: 8.0, op-cost: 0.0, total-cost: 8.0]
+-- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange [cardinality: 8.0, op-cost: 0.0, total-cost: 8.0]
+  -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    project ([$$31]) [cardinality: 8.0, op-cost: 0.0, total-cost: 8.0]
+    -- STREAM_PROJECT  |PARTITIONED|
+      assign [$$31] <- [{"age": $$38, "name": $$39}] [cardinality: 8.0, op-cost: 0.0, total-cost: 8.0]
+      -- ASSIGN  |PARTITIONED|
+        project ([$$38, $$39]) [cardinality: 8.0, op-cost: 0.0, total-cost: 8.0]
+        -- STREAM_PROJECT  |PARTITIONED|
+          exchange [cardinality: 8.0, op-cost: 0.0, total-cost: 8.0]
+          -- SORT_MERGE_EXCHANGE [$$34(ASC) ]  |PARTITIONED|
+            order (ASC, $$34) [cardinality: 8.0, op-cost: 0.0, total-cost: 8.0]
+            -- STABLE_SORT [$$34(ASC)]  |PARTITIONED|
+              exchange [cardinality: 8.0, op-cost: 0.0, total-cost: 8.0]
+              -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                project ([$$38, $$39, $$34]) [cardinality: 8.0, op-cost: 0.0, total-cost: 8.0]
+                -- STREAM_PROJECT  |PARTITIONED|
+                  assign [$$39] <- [$$p2.getField("name")] [cardinality: 8.0, op-cost: 0.0, total-cost: 8.0]
+                  -- ASSIGN  |PARTITIONED|
+                    project ([$$38, $$34, $$p2]) [cardinality: 8.0, op-cost: 0.0, total-cost: 8.0]
+                    -- STREAM_PROJECT  |PARTITIONED|
+                      exchange [cardinality: 8.0, op-cost: 0.0, total-cost: 8.0]
+                      -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                        unnest-map [$$34, $$p2] <- index-search("ColumnDataset3", 0, "test", "ColumnDataset3", true, true, 1, $$33, 1, $$33, true, true, true) project ({name:any}) [cardinality: 8.0, op-cost: 8.0, total-cost: 8.0]
+                        -- BTREE_SEARCH  |PARTITIONED|
+                          exchange [cardinality: 0.0, op-cost: 0.0, total-cost: 0.0]
+                          -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                            order (ASC, $$33) [cardinality: 0.0, op-cost: 0.0, total-cost: 0.0]
+                            -- STABLE_SORT [$$33(ASC)]  |PARTITIONED|
+                              exchange [cardinality: 0.0, op-cost: 0.0, total-cost: 0.0]
+                              -- HASH_PARTITION_EXCHANGE [$$33]  |PARTITIONED|
+                                project ([$$33, $$38]) [cardinality: 0.0, op-cost: 0.0, total-cost: 0.0]
+                                -- STREAM_PROJECT  |PARTITIONED|
+                                  assign [$$38] <- [$$p1.getField("age")] [cardinality: 0.0, op-cost: 0.0, total-cost: 0.0]
+                                  -- ASSIGN  |PARTITIONED|
+                                    exchange [cardinality: 0.0, op-cost: 0.0, total-cost: 0.0]
+                                    -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                      data-scan []<-[$$33, $$p1] <- test.ColumnDataset1 project ({age:any}) [cardinality: 7.0, op-cost: 7.0, total-cost: 7.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|
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/results_cbo/column/pushdown/field-access-pushdown/field-access-pushdown.010.plan b/asterixdb/asterix-app/src/test/resources/runtimets/results_cbo/column/pushdown/field-access-pushdown/field-access-pushdown.010.plan
new file mode 100644
index 0000000..6b9b1d8
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/results_cbo/column/pushdown/field-access-pushdown/field-access-pushdown.010.plan
@@ -0,0 +1,26 @@
+distribute result [$$18] [cardinality: 2.0, op-cost: 0.0, total-cost: 2.1]
+-- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange [cardinality: 2.0, op-cost: 0.0, total-cost: 2.1]
+  -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    project ([$$18]) [cardinality: 2.0, op-cost: 0.0, total-cost: 2.1]
+    -- STREAM_PROJECT  |PARTITIONED|
+      assign [$$18] <- [{"id": $$20.getField("id"), "name": $$20.getField("name")}] [cardinality: 2.0, op-cost: 0.0, total-cost: 2.1]
+      -- ASSIGN  |PARTITIONED|
+        project ([$$20]) [cardinality: 2.0, op-cost: 0.0, total-cost: 2.1]
+        -- STREAM_PROJECT  |PARTITIONED|
+          assign [$$20] <- [$$p.getField("user")] [cardinality: 2.0, op-cost: 0.0, total-cost: 2.1]
+          -- ASSIGN  |PARTITIONED|
+            project ([$$p]) [cardinality: 2.0, op-cost: 0.0, total-cost: 2.1]
+            -- STREAM_PROJECT  |PARTITIONED|
+              exchange [cardinality: 2.0, op-cost: 0.0, total-cost: 2.1]
+              -- SORT_MERGE_EXCHANGE [$$21(ASC) ]  |PARTITIONED|
+                order (ASC, $$21) [cardinality: 2.0, op-cost: 0.0, total-cost: 2.1]
+                -- STABLE_SORT [$$21(ASC)]  |PARTITIONED|
+                  exchange [cardinality: 2.0, op-cost: 0.0, total-cost: 2.1]
+                  -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                    data-scan []<-[$$21, $$p] <- test.ColumnDataset4 project ({user:{name:any,id:any}}) [cardinality: 2.0, op-cost: 2.1, total-cost: 2.1]
+                    -- 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|
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/results_cbo/column/pushdown/field-access-pushdown/field-access-pushdown.012.plan b/asterixdb/asterix-app/src/test/resources/runtimets/results_cbo/column/pushdown/field-access-pushdown/field-access-pushdown.012.plan
new file mode 100644
index 0000000..92b7106
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/results_cbo/column/pushdown/field-access-pushdown/field-access-pushdown.012.plan
@@ -0,0 +1,18 @@
+distribute result [$$34] [cardinality: 2.0, op-cost: 0.0, total-cost: 2.1]
+-- DISTRIBUTE_RESULT  |UNPARTITIONED|
+  exchange [cardinality: 2.0, op-cost: 0.0, total-cost: 2.1]
+  -- ONE_TO_ONE_EXCHANGE  |UNPARTITIONED|
+    aggregate [$$34] <- [agg-sql-sum($$35)] [cardinality: 2.0, op-cost: 0.0, total-cost: 2.1]
+    -- AGGREGATE  |UNPARTITIONED|
+      exchange [cardinality: 2.0, op-cost: 0.0, total-cost: 2.1]
+      -- RANDOM_MERGE_EXCHANGE  |PARTITIONED|
+        aggregate [$$35] <- [agg-sql-count(1)] [cardinality: 2.0, op-cost: 0.0, total-cost: 2.1]
+        -- AGGREGATE  |PARTITIONED|
+          exchange [cardinality: 2.0, op-cost: 0.0, total-cost: 2.1]
+          -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+            data-scan []<-[$$33, $$p] <- test.ColumnDataset4 project ({}) [cardinality: 2.0, op-cost: 2.1, total-cost: 2.1]
+            -- 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|
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/results_cbo/column/pushdown/heterogeneous-access-pushdown/heterogeneous-access-pushdown.004.plan b/asterixdb/asterix-app/src/test/resources/runtimets/results_cbo/column/pushdown/heterogeneous-access-pushdown/heterogeneous-access-pushdown.004.plan
new file mode 100644
index 0000000..f399157
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/results_cbo/column/pushdown/heterogeneous-access-pushdown/heterogeneous-access-pushdown.004.plan
@@ -0,0 +1,26 @@
+distribute result [$$21] [cardinality: 6.0, op-cost: 0.0, total-cost: 6.0]
+-- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange [cardinality: 6.0, op-cost: 0.0, total-cost: 6.0]
+  -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    project ([$$21]) [cardinality: 6.0, op-cost: 0.0, total-cost: 6.0]
+    -- STREAM_PROJECT  |PARTITIONED|
+      assign [$$21] <- [switch-case(true, is-array($$23), array-star($$23).getField("text"), $$23.getField("text"))] [cardinality: 6.0, op-cost: 0.0, total-cost: 6.0]
+      -- ASSIGN  |PARTITIONED|
+        project ([$$23]) [cardinality: 6.0, op-cost: 0.0, total-cost: 6.0]
+        -- STREAM_PROJECT  |PARTITIONED|
+          assign [$$23] <- [$$p.getField("arrayOrObject")] [cardinality: 6.0, op-cost: 0.0, total-cost: 6.0]
+          -- ASSIGN  |PARTITIONED|
+            project ([$$p]) [cardinality: 6.0, op-cost: 0.0, total-cost: 6.0]
+            -- STREAM_PROJECT  |PARTITIONED|
+              exchange [cardinality: 6.0, op-cost: 0.0, total-cost: 6.0]
+              -- SORT_MERGE_EXCHANGE [$$24(ASC) ]  |PARTITIONED|
+                order (ASC, $$24) [cardinality: 6.0, op-cost: 0.0, total-cost: 6.0]
+                -- STABLE_SORT [$$24(ASC)]  |PARTITIONED|
+                  exchange [cardinality: 6.0, op-cost: 0.0, total-cost: 6.0]
+                  -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                    data-scan []<-[$$24, $$p] <- test.ColumnDataset project ({arrayOrObject:<[{text:any}],{text:any}>}) [cardinality: 6.0, op-cost: 6.0, total-cost: 6.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|
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/results_cbo/column/pushdown/other-pushdowns/other-pushdowns.004.plan b/asterixdb/asterix-app/src/test/resources/runtimets/results_cbo/column/pushdown/other-pushdowns/other-pushdowns.004.plan
new file mode 100644
index 0000000..e957155
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/results_cbo/column/pushdown/other-pushdowns/other-pushdowns.004.plan
@@ -0,0 +1,36 @@
+distribute result [$$61] [cardinality: 2.21, op-cost: 0.0, total-cost: 12.6]
+-- DISTRIBUTE_RESULT  |UNPARTITIONED|
+  exchange [cardinality: 2.21, op-cost: 0.0, total-cost: 12.6]
+  -- ONE_TO_ONE_EXCHANGE  |UNPARTITIONED|
+    project ([$$61]) [cardinality: 2.21, op-cost: 0.0, total-cost: 12.6]
+    -- STREAM_PROJECT  |UNPARTITIONED|
+      assign [$$61] <- [{"$1": $$66, "$2": $$67}] [cardinality: 2.21, op-cost: 0.0, total-cost: 12.6]
+      -- ASSIGN  |UNPARTITIONED|
+        aggregate [$$66, $$67] <- [agg-global-sql-sum($$70), agg-global-sql-sum($$71)] [cardinality: 2.21, op-cost: 0.0, total-cost: 12.6]
+        -- AGGREGATE  |UNPARTITIONED|
+          exchange [cardinality: 2.21, op-cost: 0.0, total-cost: 12.6]
+          -- RANDOM_MERGE_EXCHANGE  |PARTITIONED|
+            aggregate [$$70, $$71] <- [agg-local-sql-sum($$54), agg-local-sql-sum($$59)] [cardinality: 2.21, op-cost: 0.0, total-cost: 12.6]
+            -- AGGREGATE  |PARTITIONED|
+              project ([$$54, $$59]) [cardinality: 2.21, op-cost: 0.0, total-cost: 12.6]
+              -- STREAM_PROJECT  |PARTITIONED|
+                assign [$$59, $$54] <- [object-length($$p2), object-length($$p1)] [cardinality: 2.21, op-cost: 0.0, total-cost: 12.6]
+                -- ASSIGN  |PARTITIONED|
+                  project ([$$p1, $$p2]) [cardinality: 2.21, op-cost: 0.0, total-cost: 12.6]
+                  -- STREAM_PROJECT  |PARTITIONED|
+                    exchange [cardinality: 2.21, op-cost: 0.0, total-cost: 12.6]
+                    -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                      unnest-map [$$63, $$p2] <- index-search("RowDataset", 0, "test", "RowDataset", true, true, 1, $$62, 1, $$62, true, true, true) [cardinality: 2.21, op-cost: 2.1, total-cost: 12.6]
+                      -- BTREE_SEARCH  |PARTITIONED|
+                        exchange [cardinality: 0.0, op-cost: 0.0, total-cost: 0.0]
+                        -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                          order (ASC, $$62) [cardinality: 0.0, op-cost: 0.0, total-cost: 0.0]
+                          -- STABLE_SORT [$$62(ASC)]  |PARTITIONED|
+                            exchange [cardinality: 0.0, op-cost: 0.0, total-cost: 0.0]
+                            -- HASH_PARTITION_EXCHANGE [$$62]  |PARTITIONED|
+                              data-scan []<-[$$62, $$p1] <- test.ColumnDataset [cardinality: 2.0, op-cost: 2.1, total-cost: 2.1]
+                              -- 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|
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/results_cbo/column/pushdown/other-pushdowns/other-pushdowns.006.plan b/asterixdb/asterix-app/src/test/resources/runtimets/results_cbo/column/pushdown/other-pushdowns/other-pushdowns.006.plan
new file mode 100644
index 0000000..ab6b6cb
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/results_cbo/column/pushdown/other-pushdowns/other-pushdowns.006.plan
@@ -0,0 +1,30 @@
+distribute result [$$p1] [cardinality: 2.1, op-cost: 0.0, total-cost: 2.1]
+-- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange [cardinality: 2.1, op-cost: 0.0, total-cost: 2.1]
+  -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    project ([$$p1]) [cardinality: 2.1, op-cost: 0.0, total-cost: 2.1]
+    -- STREAM_PROJECT  |PARTITIONED|
+      exchange [cardinality: 2.1, op-cost: 0.0, total-cost: 2.1]
+      -- SORT_MERGE_EXCHANGE [$$16(ASC) ]  |PARTITIONED|
+        order (ASC, $$16) [cardinality: 2.1, op-cost: 0.0, total-cost: 2.1]
+        -- STABLE_SORT [$$16(ASC)]  |PARTITIONED|
+          exchange [cardinality: 2.1, op-cost: 0.0, total-cost: 2.1]
+          -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+            distinct ([$$p1]) [cardinality: 2.1, op-cost: 0.0, total-cost: 2.1]
+            -- PRE_SORTED_DISTINCT_BY  |PARTITIONED|
+              exchange [cardinality: 2.1, op-cost: 0.0, total-cost: 2.1]
+              -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                order (ASC, $$p1) [cardinality: 2.1, op-cost: 0.0, total-cost: 2.1]
+                -- STABLE_SORT [$$p1(ASC)]  |PARTITIONED|
+                  exchange [cardinality: 2.1, op-cost: 0.0, total-cost: 2.1]
+                  -- HASH_PARTITION_EXCHANGE [$$p1]  |PARTITIONED|
+                    select (neq($$16, "0")) [cardinality: 2.1, op-cost: 0.0, total-cost: 2.1]
+                    -- STREAM_SELECT  |PARTITIONED|
+                      exchange [cardinality: 2.0, op-cost: 0.0, total-cost: 2.1]
+                      -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                        data-scan []<-[$$16, $$p1] <- test.ColumnDataset [cardinality: 2.0, op-cost: 2.1, total-cost: 2.1]
+                        -- 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|
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
new file mode 100644
index 0000000..224298e
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/results_cbo/column/pushdown/other-pushdowns/other-pushdowns.008.plan
@@ -0,0 +1,52 @@
+distribute result [$$69] [cardinality: 2.1, op-cost: 0.0, total-cost: 2.1]
+-- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange [cardinality: 2.1, op-cost: 0.0, total-cost: 2.1]
+  -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    project ([$$69]) [cardinality: 2.1, op-cost: 0.0, total-cost: 2.1]
+    -- STREAM_PROJECT  |PARTITIONED|
+      assign [$$69] <- [{"text": $$text, "$1": $$73}] [cardinality: 2.1, op-cost: 0.0, total-cost: 2.1]
+      -- ASSIGN  |PARTITIONED|
+        exchange [cardinality: 2.1, op-cost: 0.0, total-cost: 2.1]
+        -- 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: 2.1, op-cost: 0.0, total-cost: 2.1]
+          -- SORT_GROUP_BY[$$81]  |PARTITIONED|
+            exchange [cardinality: 2.1, op-cost: 0.0, total-cost: 2.1]
+            -- 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: 2.1, op-cost: 0.0, total-cost: 2.1]
+              -- SORT_GROUP_BY[$$71]  |PARTITIONED|
+                exchange [cardinality: 2.1, op-cost: 0.0, total-cost: 2.1]
+                -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                  select (eq(lowercase($$71), "string")) [cardinality: 2.1, op-cost: 0.0, total-cost: 2.1]
+                  -- STREAM_SELECT  |PARTITIONED|
+                    project ([$$75, $$71]) [cardinality: 2.0, op-cost: 0.0, total-cost: 2.1]
+                    -- STREAM_PROJECT  |PARTITIONED|
+                      assign [$$71] <- [$$ht.getField("display_url")] [cardinality: 2.0, op-cost: 0.0, total-cost: 2.1]
+                      -- ASSIGN  |PARTITIONED|
+                        unnest $$ht <- scan-collection($$75) [cardinality: 2.0, op-cost: 0.0, total-cost: 2.1]
+                        -- UNNEST  |PARTITIONED|
+                          project ([$$75]) [cardinality: 2.0, op-cost: 0.0, total-cost: 2.1]
+                          -- STREAM_PROJECT  |PARTITIONED|
+                            assign [$$75] <- [$$p1.getField("entities").getField("urls")] [cardinality: 2.0, op-cost: 0.0, total-cost: 2.1]
+                            -- ASSIGN  |PARTITIONED|
+                              project ([$$p1]) [cardinality: 2.0, op-cost: 0.0, total-cost: 2.1]
+                              -- 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.1]
+                                  -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                    data-scan []<-[$$72, $$p1] <- test.ColumnDataset project ({entities:{urls:[{display_url:any}]}}) [cardinality: 2.0, op-cost: 2.1, total-cost: 2.1]
+                                    -- 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|
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
new file mode 100644
index 0000000..0bf5e31
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/results_cbo/column/pushdown/other-pushdowns/other-pushdowns.010.plan
@@ -0,0 +1,54 @@
+distribute result [$$68] [cardinality: 2.1, op-cost: 0.0, total-cost: 2.1]
+-- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange [cardinality: 2.1, op-cost: 0.0, total-cost: 2.1]
+  -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    project ([$$68]) [cardinality: 2.1, op-cost: 0.0, total-cost: 2.1]
+    -- STREAM_PROJECT  |PARTITIONED|
+      assign [$$68] <- [{"text": $$text, "$1": $$72}] [cardinality: 2.1, op-cost: 0.0, total-cost: 2.1]
+      -- ASSIGN  |PARTITIONED|
+        exchange [cardinality: 2.1, op-cost: 0.0, total-cost: 2.1]
+        -- 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: 2.1, op-cost: 0.0, total-cost: 2.1]
+          -- SORT_GROUP_BY[$$79]  |PARTITIONED|
+            exchange [cardinality: 2.1, op-cost: 0.0, total-cost: 2.1]
+            -- 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: 2.1, op-cost: 0.0, total-cost: 2.1]
+              -- SORT_GROUP_BY[$$70]  |PARTITIONED|
+                exchange [cardinality: 2.1, op-cost: 0.0, total-cost: 2.1]
+                -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                  select (eq(lowercase($$70), "string")) [cardinality: 2.1, op-cost: 0.0, total-cost: 2.1]
+                  -- STREAM_SELECT  |PARTITIONED|
+                    project ([$$75, $$70]) [cardinality: 2.0, op-cost: 0.0, total-cost: 2.1]
+                    -- STREAM_PROJECT  |PARTITIONED|
+                      assign [$$75, $$70] <- [$$ht.getField("indices"), $$ht.getField("display_url")] [cardinality: 2.0, op-cost: 0.0, total-cost: 2.1]
+                      -- ASSIGN  |PARTITIONED|
+                        project ([$$ht]) [cardinality: 2.0, op-cost: 0.0, total-cost: 2.1]
+                        -- STREAM_PROJECT  |PARTITIONED|
+                          unnest $$ht <- scan-collection($$74) [cardinality: 2.0, op-cost: 0.0, total-cost: 2.1]
+                          -- UNNEST  |PARTITIONED|
+                            project ([$$74]) [cardinality: 2.0, op-cost: 0.0, total-cost: 2.1]
+                            -- STREAM_PROJECT  |PARTITIONED|
+                              assign [$$74] <- [$$p1.getField("entities").getField("urls")] [cardinality: 2.0, op-cost: 0.0, total-cost: 2.1]
+                              -- ASSIGN  |PARTITIONED|
+                                project ([$$p1]) [cardinality: 2.0, op-cost: 0.0, total-cost: 2.1]
+                                -- 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.1]
+                                    -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                      data-scan []<-[$$71, $$p1] <- test.ColumnDataset project ({entities:{urls:[{display_url:any,indices:any}]}}) [cardinality: 2.0, op-cost: 2.1, total-cost: 2.1]
+                                      -- 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|
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/results_cbo/column/pushdown/other-pushdowns/other-pushdowns.012.plan b/asterixdb/asterix-app/src/test/resources/runtimets/results_cbo/column/pushdown/other-pushdowns/other-pushdowns.012.plan
new file mode 100644
index 0000000..16f1d72
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/results_cbo/column/pushdown/other-pushdowns/other-pushdowns.012.plan
@@ -0,0 +1,34 @@
+distribute result [$$22] [cardinality: 2.1, op-cost: 0.0, total-cost: 2.1]
+-- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange [cardinality: 2.1, op-cost: 0.0, total-cost: 2.1]
+  -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    project ([$$22]) [cardinality: 2.1, op-cost: 0.0, total-cost: 2.1]
+    -- STREAM_PROJECT  |PARTITIONED|
+      assign [$$22] <- [{"display_url": $$27}] [cardinality: 2.1, op-cost: 0.0, total-cost: 2.1]
+      -- ASSIGN  |PARTITIONED|
+        project ([$$27]) [cardinality: 2.1, op-cost: 0.0, total-cost: 2.1]
+        -- STREAM_PROJECT  |PARTITIONED|
+          exchange [cardinality: 2.1, op-cost: 0.0, total-cost: 2.1]
+          -- SORT_MERGE_EXCHANGE [$$25(ASC) ]  |PARTITIONED|
+            order (ASC, $$25) [cardinality: 2.1, op-cost: 0.0, total-cost: 2.1]
+            -- STABLE_SORT [$$25(ASC)]  |PARTITIONED|
+              exchange [cardinality: 2.1, op-cost: 0.0, total-cost: 2.1]
+              -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                project ([$$27, $$25]) [cardinality: 2.1, op-cost: 0.0, total-cost: 2.1]
+                -- STREAM_PROJECT  |PARTITIONED|
+                  assign [$$27] <- [get-item($$24, 0).getField("display_url")] [cardinality: 2.1, op-cost: 0.0, total-cost: 2.1]
+                  -- ASSIGN  |PARTITIONED|
+                    select (eq(sql-count($$24), 1)) [cardinality: 2.1, op-cost: 0.0, total-cost: 2.1]
+                    -- STREAM_SELECT  |PARTITIONED|
+                      project ([$$25, $$24]) [cardinality: 2.0, op-cost: 0.0, total-cost: 2.1]
+                      -- STREAM_PROJECT  |PARTITIONED|
+                        assign [$$24] <- [$$p.getField("entities").getField("urls")] [cardinality: 2.0, op-cost: 0.0, total-cost: 2.1]
+                        -- ASSIGN  |PARTITIONED|
+                          exchange [cardinality: 2.0, op-cost: 0.0, total-cost: 2.1]
+                          -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                            data-scan []<-[$$25, $$p] <- test.ColumnDataset project ({entities:{urls:[{display_url:any}]}}) [cardinality: 2.0, op-cost: 2.1, total-cost: 2.1]
+                            -- 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|
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/testsuite_sqlpp.xml b/asterixdb/asterix-app/src/test/resources/runtimets/testsuite_sqlpp.xml
index ce4c1bd..d468836 100644
--- a/asterixdb/asterix-app/src/test/resources/runtimets/testsuite_sqlpp.xml
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/testsuite_sqlpp.xml
@@ -16295,6 +16295,11 @@
         <output-dir compare="Text">secondary-index/create-index/after-upsert-with-meta</output-dir>
       </compilation-unit>
     </test-case>
+    <test-case FilePath="column">
+      <compilation-unit name="analyze-dataset">
+        <output-dir compare="Text">analyze-dataset</output-dir>
+      </compilation-unit>
+    </test-case>
   </test-group>
   <test-group name="copy">
     <test-case FilePath="copy">
diff --git a/asterixdb/asterix-metadata/src/main/java/org/apache/asterix/metadata/utils/SampleOperationsHelper.java b/asterixdb/asterix-metadata/src/main/java/org/apache/asterix/metadata/utils/SampleOperationsHelper.java
index 030895b..6b88960 100644
--- a/asterixdb/asterix-metadata/src/main/java/org/apache/asterix/metadata/utils/SampleOperationsHelper.java
+++ b/asterixdb/asterix-metadata/src/main/java/org/apache/asterix/metadata/utils/SampleOperationsHelper.java
@@ -40,6 +40,7 @@
 import org.apache.asterix.runtime.evaluators.comparisons.GreaterThanDescriptor;
 import org.apache.asterix.runtime.operators.DatasetStreamStatsOperatorDescriptor;
 import org.apache.asterix.runtime.operators.LSMIndexBulkLoadOperatorDescriptor;
+import org.apache.asterix.runtime.projection.DataProjectionFiltrationInfo;
 import org.apache.asterix.runtime.runningaggregates.std.SampleSlotRunningAggregateFunctionFactory;
 import org.apache.asterix.runtime.runningaggregates.std.TidRunningAggregateDescriptor;
 import org.apache.asterix.runtime.utils.RuntimeUtils;
@@ -88,6 +89,7 @@
 import org.apache.hyracks.storage.am.lsm.common.api.ILSMMergePolicyFactory;
 import org.apache.hyracks.storage.common.IResourceFactory;
 import org.apache.hyracks.storage.common.IStorageManager;
+import org.apache.hyracks.storage.common.projection.ITupleProjectorFactory;
 
 /**
  * Utility class for sampling operations.
@@ -188,9 +190,15 @@
         // job spec:
         IndexUtil.bindJobEventListener(spec, metadataProvider);
 
+        // if format == column. Bring the entire record as we are sampling
+        ITupleProjectorFactory projectorFactory = IndexUtil.createPrimaryIndexScanTupleProjectorFactory(
+                dataset.getDatasetFormatInfo(), DataProjectionFiltrationInfo.ALL_FIELDS_TYPE, itemType, metaType,
+                dataset.getPrimaryKeys().size());
+
         // dummy key provider ----> primary index scan
         IOperatorDescriptor sourceOp = DatasetUtil.createDummyKeyProviderOp(spec, dataset, metadataProvider);
-        IOperatorDescriptor targetOp = DatasetUtil.createPrimaryIndexScanOp(spec, metadataProvider, dataset);
+        IOperatorDescriptor targetOp =
+                DatasetUtil.createPrimaryIndexScanOp(spec, metadataProvider, dataset, projectorFactory);
         spec.connect(new OneToOneConnectorDescriptor(spec), sourceOp, 0, targetOp, 0);
         sourceOp = targetOp;
 
@@ -327,9 +335,7 @@
             int[] fieldPermutation, IIndexDataflowHelperFactory dataflowHelperFactory, float fillFactor,
             long numElementHint) throws AlgebricksException {
         int[] pkFields = new int[dataset.getPrimaryKeys().size()];
-        for (int i = 0; i < pkFields.length; i++) {
-            pkFields[i] = fieldPermutation[i];
-        }
+        System.arraycopy(fieldPermutation, 0, pkFields, 0, pkFields.length);
         IBinaryHashFunctionFactory[] pkHashFunFactories = dataset.getPrimaryHashFunctionFactories(metadataProvider);
         ITuplePartitionerFactory partitionerFactory =
                 new FieldHashPartitionerFactory(pkFields, pkHashFunFactories, numPartitions);