Merge branch 'gerrit/stabilization-1cffa2bc98' into 'gerrit/goldfish'

Ext-ref: MB-64561
Change-Id: I5bf1f7bd24a4af26211a3014655b8b712f50db32
diff --git a/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/pushdown/schema/ExpectedSchemaBuilder.java b/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/pushdown/schema/ExpectedSchemaBuilder.java
index 23da417..f4b6cb0 100644
--- a/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/pushdown/schema/ExpectedSchemaBuilder.java
+++ b/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/pushdown/schema/ExpectedSchemaBuilder.java
@@ -56,10 +56,10 @@
 
     public boolean setSchemaFromExpression(AbstractFunctionCallExpression expr, LogicalVariable producedVar,
             IVariableTypeEnvironment typeEnv) throws AlgebricksException {
-        return buildExpectedSchemaNodes(expr, producedVar, typeEnv);
+        return buildExpectedSchemaNodes(expr, typeEnv, producedVar);
     }
 
-    public boolean setSchemaFromCalculatedExpression(AbstractFunctionCallExpression expr, LogicalVariable producedVar,
+    private boolean setSchemaFromCalculatedExpression(AbstractFunctionCallExpression expr, LogicalVariable producedVar,
             IVariableTypeEnvironment typeEnv) throws AlgebricksException {
         //Parent always nested
         AbstractComplexExpectedSchemaNode parent = (AbstractComplexExpectedSchemaNode) buildNestedNode(expr, typeEnv);
@@ -109,26 +109,29 @@
         return varToNode.get(variable);
     }
 
-    private boolean buildExpectedSchemaNodes(ILogicalExpression expr, LogicalVariable producedVar,
-            IVariableTypeEnvironment typeEnv) throws AlgebricksException {
-        return buildNestedNodes(expr, producedVar, typeEnv);
+    private boolean buildExpectedSchemaNodes(ILogicalExpression expr, IVariableTypeEnvironment typeEnv,
+            LogicalVariable producedVar) throws AlgebricksException {
+        return buildNestedNodes(expr, typeEnv, producedVar);
     }
 
-    private boolean buildNestedNodes(ILogicalExpression expr, LogicalVariable producedVar,
-            IVariableTypeEnvironment typeEnv) throws AlgebricksException {
+    private boolean buildNestedNodes(ILogicalExpression expr, IVariableTypeEnvironment typeEnv,
+            LogicalVariable producedVar) throws AlgebricksException {
         //The current node expression
         boolean changed = false;
         if (expr.getExpressionTag() != LogicalExpressionTag.FUNCTION_CALL) {
             return false;
         }
+
         AbstractFunctionCallExpression myExpr = (AbstractFunctionCallExpression) expr;
         if (!SUPPORTED_FUNCTIONS.contains(myExpr.getFunctionIdentifier()) || noArgsOrFirstArgIsConstant(myExpr)) {
             // Check if the function consists of the Supported Functions
             for (Mutable<ILogicalExpression> arg : myExpr.getArguments()) {
-                changed |= buildNestedNodes(arg.getValue(), producedVar, typeEnv);
+                changed |= buildNestedNodes(arg.getValue(), typeEnv, producedVar);
             }
+
             return changed;
         }
+
         // if the child is not a function expression, then just one node.
         if (BuiltinFunctions.ARRAY_STAR.equals(myExpr.getFunctionIdentifier())
                 || BuiltinFunctions.SCAN_COLLECTION.equals(myExpr.getFunctionIdentifier())) {
@@ -153,6 +156,7 @@
                 // evaluated at this stage of compilation.
                 // eg: field-access(t.r.p, substring("name",2,4))
                 // this will be evaluated to field-access(t.r.p, "me") at compile time itself.
+
                 // since the execution reached this branch, this means the childExpr
                 // need to be evaluated at runtime, hence the childExpr should also be checked
                 // for possible pushdown.
@@ -163,17 +167,12 @@
                     changed |= setSchemaFromCalculatedExpression((AbstractFunctionCallExpression) parentExpr,
                             producedVar, typeEnv);
                 }
-                changed |= buildNestedNodes(childExpr, producedVar, typeEnv);
+                changed |= buildNestedNodes(childExpr, typeEnv, producedVar);
             }
         }
         return changed;
     }
 
-    private boolean noArgsOrFirstArgIsConstant(AbstractFunctionCallExpression myExpr) {
-        List<Mutable<ILogicalExpression>> args = myExpr.getArguments();
-        return args.isEmpty() || args.get(0).getValue().getExpressionTag() == LogicalExpressionTag.CONSTANT;
-    }
-
     private IExpectedSchemaNode buildNestedNode(ILogicalExpression expr, IVariableTypeEnvironment typeEnv)
             throws AlgebricksException {
         //The current node expression
@@ -212,6 +211,11 @@
         return null;
     }
 
+    private boolean noArgsOrFirstArgIsConstant(AbstractFunctionCallExpression myExpr) {
+        List<Mutable<ILogicalExpression>> args = myExpr.getArguments();
+        return args.isEmpty() || args.get(0).getValue().getExpressionTag() == LogicalExpressionTag.CONSTANT;
+    }
+
     private IExpectedSchemaNode changeNodeForVariable(LogicalVariable sourceVar,
             AbstractFunctionCallExpression parentExpression, ILogicalExpression expression) {
         //Get the associated node with the sourceVar (if any)
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/column/assembly/ASTERIXDB-3539/ASTERIXDB-3539.001.ddl.sqlpp b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/column/assembly/ASTERIXDB-3539/ASTERIXDB-3539.001.ddl.sqlpp
new file mode 100644
index 0000000..d151eb1
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/column/assembly/ASTERIXDB-3539/ASTERIXDB-3539.001.ddl.sqlpp
@@ -0,0 +1,28 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+ DROP DATAVERSE test IF EXISTS;
+ CREATE DATAVERSE test;
+
+ USE test;
+
+ CREATE DATASET ColumnDataset
+ PRIMARY KEY (uid:int) WITH {
+     "storage-format": {"format": "column"}
+ };
\ No newline at end of file
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/column/assembly/ASTERIXDB-3539/ASTERIXDB-3539.002.update.sqlpp b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/column/assembly/ASTERIXDB-3539/ASTERIXDB-3539.002.update.sqlpp
new file mode 100644
index 0000000..7828d12
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/column/assembly/ASTERIXDB-3539/ASTERIXDB-3539.002.update.sqlpp
@@ -0,0 +1,30 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+
+USE test;
+UPSERT INTO ColumnDataset(
+    {"uid": 1, "a": [{"x": "aaaaaaaaaazzzz"}, {"x": "aaaaaaaaaaabzzzz"}, {"x": "aaaaaaaaaaaaabzzzzzzzz"}]},
+    {"uid": 2, "a": [{"x": "aaaaaaaaaazzzzextra"}, {"x": "aaaaaaaaaaabzzzzextra"}, {"x": "aaaaaaaaaaaaabzzzzzzzzextra"}]},
+    {"uid": 3, "a": [{"x": "aaaaaaaaaazzzzextra"}, {"x": "aaaaaaaaaaabzzzzextra"}, {"x": "aaaaaaaaaaaaabzzzzzzzzextra"}]},
+    {"uid": 4, "a": [{"x": "aaaaaaaaaazzzzextra"}, {"x": "aaaaaaaaaaabzzzzextra"}, {"x": "aaaaaaaaaaaaabzzzzzzzzextra"}]},
+    {"uid": 5, "a": [{"x": "aaaaaaaaaazzzzextra"}, {"x": "aaaaaaaaaaabzzzzextra"}, {"x": "aaaaaaaaaaaaabzzzzzzzzextra"}]},
+    {"uid": 6, "a": [{"x": "aaaaaaaaaazzzzextra"}, {"x": "aaaaaaaaaaabzzzzextra"}, {"x": "aaaaaaaaaaaaabzzzzzzzzextra"}]},
+    {"uid": 7, "a": [{"x": "aaaaaaaaaazzzzextra"}, {"x": "aaaaaaaaaaabzzzzextra"}, {"x": "aaaaaaaaaaaaabzzzzzzzz"}]}
+);
\ No newline at end of file
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/column/assembly/ASTERIXDB-3539/ASTERIXDB-3539.003.update.sqlpp b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/column/assembly/ASTERIXDB-3539/ASTERIXDB-3539.003.update.sqlpp
new file mode 100644
index 0000000..5337d9b
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/column/assembly/ASTERIXDB-3539/ASTERIXDB-3539.003.update.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;
+DELETE FROM ColumnDataset
+WHERE uid >= 2 AND uid <= 6;
\ No newline at end of file
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/column/assembly/ASTERIXDB-3539/ASTERIXDB-3539.004.query.sqlpp b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/column/assembly/ASTERIXDB-3539/ASTERIXDB-3539.004.query.sqlpp
new file mode 100644
index 0000000..b7fac3c
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/column/assembly/ASTERIXDB-3539/ASTERIXDB-3539.004.query.sqlpp
@@ -0,0 +1,23 @@
+/*
+ * 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;
+ SELECT VALUE a.x
+ FROM ColumnDataset c, c.a a
+ WHERE a.x = "aaaaaaaaaazzzzextra";
\ No newline at end of file
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/column/pushdown/ASTERIXDB-3540/ASTERIXDB-3540.001.ddl.sqlpp b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/column/pushdown/ASTERIXDB-3540/ASTERIXDB-3540.001.ddl.sqlpp
new file mode 100644
index 0000000..8a95edc
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/column/pushdown/ASTERIXDB-3540/ASTERIXDB-3540.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.
+ */
+
+DROP DATAVERSE test IF EXISTS;
+CREATE DATAVERSE test;
+
+USE test;
+
+CREATE TYPE ColumnType AS {
+    id: string
+};
+
+
+CREATE DATASET ColumnDataset(ColumnType)
+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/pushdown/ASTERIXDB-3540/ASTERIXDB-3540.002.update.sqlpp b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/column/pushdown/ASTERIXDB-3540/ASTERIXDB-3540.002.update.sqlpp
new file mode 100644
index 0000000..9bf4aad
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/column/pushdown/ASTERIXDB-3540/ASTERIXDB-3540.002.update.sqlpp
@@ -0,0 +1,37 @@
+/*
+ * 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;
+ UPSERT INTO ColumnDataset(
+ {
+   "id": "1",
+   "name": "Monica",
+   "x": {
+     "y": {
+       "age_field": "age"
+     }
+   },
+   "t": {
+     "r": {
+       "p": {
+         "age": "26"
+       }
+     }
+   }
+ });
\ No newline at end of file
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/column/pushdown/ASTERIXDB-3540/ASTERIXDB-3540.003.query.sqlpp b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/column/pushdown/ASTERIXDB-3540/ASTERIXDB-3540.003.query.sqlpp
new file mode 100644
index 0000000..93ab4cd
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/column/pushdown/ASTERIXDB-3540/ASTERIXDB-3540.003.query.sqlpp
@@ -0,0 +1,23 @@
+/*
+ * 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;
+
+EXPLAIN SELECT t.r.g, `field-access-by-name`(t.r.p, x.y.age_field)
+FROM ColumnDataset;
\ No newline at end of file
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/column/pushdown/ASTERIXDB-3540/ASTERIXDB-3540.004.query.sqlpp b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/column/pushdown/ASTERIXDB-3540/ASTERIXDB-3540.004.query.sqlpp
new file mode 100644
index 0000000..75c0167
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/column/pushdown/ASTERIXDB-3540/ASTERIXDB-3540.004.query.sqlpp
@@ -0,0 +1,23 @@
+/*
+ * 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;
+
+EXPLAIN SELECT t.r.g, `field-access-by-name`(t.r.p, substring(x.y.age_field, 0, 4))
+FROM ColumnDataset;
\ No newline at end of file
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/column/pushdown/ASTERIXDB-3540/ASTERIXDB-3540.005.query.sqlpp b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/column/pushdown/ASTERIXDB-3540/ASTERIXDB-3540.005.query.sqlpp
new file mode 100644
index 0000000..4ce0ec5
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/column/pushdown/ASTERIXDB-3540/ASTERIXDB-3540.005.query.sqlpp
@@ -0,0 +1,23 @@
+/*
+ * 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;
+
+SELECT t.r.g, `field-access-by-name`(t.r.p, x.y.age_field)
+FROM ColumnDataset;
\ No newline at end of file
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/column/pushdown/ASTERIXDB-3540/ASTERIXDB-3540.006.query.sqlpp b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/column/pushdown/ASTERIXDB-3540/ASTERIXDB-3540.006.query.sqlpp
new file mode 100644
index 0000000..e0fbee0
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/column/pushdown/ASTERIXDB-3540/ASTERIXDB-3540.006.query.sqlpp
@@ -0,0 +1,23 @@
+/*
+ * 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;
+
+SELECT t.r.g, `field-access-by-name`(t.r.p, substring(x.y.age_field, 0, 4))
+FROM ColumnDataset;
\ No newline at end of file
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/results/column/assembly/ASTERIXDB-3539/ASTERIXDB-3539.003.adm b/asterixdb/asterix-app/src/test/resources/runtimets/results/column/assembly/ASTERIXDB-3539/ASTERIXDB-3539.003.adm
new file mode 100644
index 0000000..7328549
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/results/column/assembly/ASTERIXDB-3539/ASTERIXDB-3539.003.adm
@@ -0,0 +1 @@
+"aaaaaaaaaazzzzextra"
\ No newline at end of file
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/results/column/pushdown/ASTERIXDB-3540/ASTERIXDB-3540.003.plan b/asterixdb/asterix-app/src/test/resources/runtimets/results/column/pushdown/ASTERIXDB-3540/ASTERIXDB-3540.003.plan
new file mode 100644
index 0000000..40cfb00
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/results/column/pushdown/ASTERIXDB-3540/ASTERIXDB-3540.003.plan
@@ -0,0 +1,20 @@
+distribute result [$$25] [cardinality: 0.0, op-cost: 0.0, total-cost: 0.0]
+-- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange [cardinality: 0.0, op-cost: 0.0, total-cost: 0.0]
+  -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    project ([$$25]) [cardinality: 0.0, op-cost: 0.0, total-cost: 0.0]
+    -- STREAM_PROJECT  |PARTITIONED|
+      assign [$$25] <- [{"g": $$26.getField("g"), "$1": $$26.getField("p").getField("$$ColumnDataset.getField("x").getField("y").getField("age_field")")}] [cardinality: 0.0, op-cost: 0.0, total-cost: 0.0]
+      -- ASSIGN  |PARTITIONED|
+        assign [$$26] <- [$$ColumnDataset.getField("t").getField("r")] [cardinality: 0.0, op-cost: 0.0, total-cost: 0.0]
+        -- ASSIGN  |PARTITIONED|
+          project ([$$ColumnDataset]) [cardinality: 0.0, op-cost: 0.0, total-cost: 0.0]
+          -- STREAM_PROJECT  |PARTITIONED|
+            exchange [cardinality: 0.0, op-cost: 0.0, total-cost: 0.0]
+            -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+              data-scan []<-[$$27, $$ColumnDataset] <- test.ColumnDataset project ({t:{r:{p:any,g:any}},x:{y:{age_field:any}}}) [cardinality: 0.0, op-cost: 0.0, total-cost: 0.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|
\ No newline at end of file
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/results/column/pushdown/ASTERIXDB-3540/ASTERIXDB-3540.004.plan b/asterixdb/asterix-app/src/test/resources/runtimets/results/column/pushdown/ASTERIXDB-3540/ASTERIXDB-3540.004.plan
new file mode 100644
index 0000000..7e0e444
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/results/column/pushdown/ASTERIXDB-3540/ASTERIXDB-3540.004.plan
@@ -0,0 +1,20 @@
+distribute result [$$26] [cardinality: 0.0, op-cost: 0.0, total-cost: 0.0]
+-- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange [cardinality: 0.0, op-cost: 0.0, total-cost: 0.0]
+  -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    project ([$$26]) [cardinality: 0.0, op-cost: 0.0, total-cost: 0.0]
+    -- STREAM_PROJECT  |PARTITIONED|
+      assign [$$26] <- [{"g": $$27.getField("g"), "$1": $$27.getField("p").getField("substring($$ColumnDataset.getField("x").getField("y").getField("age_field"), 0, 4)")}] [cardinality: 0.0, op-cost: 0.0, total-cost: 0.0]
+      -- ASSIGN  |PARTITIONED|
+        assign [$$27] <- [$$ColumnDataset.getField("t").getField("r")] [cardinality: 0.0, op-cost: 0.0, total-cost: 0.0]
+        -- ASSIGN  |PARTITIONED|
+          project ([$$ColumnDataset]) [cardinality: 0.0, op-cost: 0.0, total-cost: 0.0]
+          -- STREAM_PROJECT  |PARTITIONED|
+            exchange [cardinality: 0.0, op-cost: 0.0, total-cost: 0.0]
+            -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+              data-scan []<-[$$28, $$ColumnDataset] <- test.ColumnDataset project ({t:{r:{p:any,g:any}},x:{y:{age_field:any}}}) [cardinality: 0.0, op-cost: 0.0, total-cost: 0.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|
\ No newline at end of file
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/results/column/pushdown/ASTERIXDB-3540/ASTERIXDB-3540.005.adm b/asterixdb/asterix-app/src/test/resources/runtimets/results/column/pushdown/ASTERIXDB-3540/ASTERIXDB-3540.005.adm
new file mode 100644
index 0000000..2246335
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/results/column/pushdown/ASTERIXDB-3540/ASTERIXDB-3540.005.adm
@@ -0,0 +1 @@
+{ "$1": "26" }
\ No newline at end of file
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/results/column/pushdown/ASTERIXDB-3540/ASTERIXDB-3540.006.adm b/asterixdb/asterix-app/src/test/resources/runtimets/results/column/pushdown/ASTERIXDB-3540/ASTERIXDB-3540.006.adm
new file mode 100644
index 0000000..2246335
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/results/column/pushdown/ASTERIXDB-3540/ASTERIXDB-3540.006.adm
@@ -0,0 +1 @@
+{ "$1": "26" }
\ No newline at end of file
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/sqlpp_queries.xml b/asterixdb/asterix-app/src/test/resources/runtimets/sqlpp_queries.xml
index add376a..d86a5a2 100644
--- a/asterixdb/asterix-app/src/test/resources/runtimets/sqlpp_queries.xml
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/sqlpp_queries.xml
@@ -16374,6 +16374,11 @@
       </compilation-unit>
     </test-case>
     <test-case FilePath="column">
+      <compilation-unit name="assembly/ASTERIXDB-3539">
+        <output-dir compare="Text">assembly/ASTERIXDB-3539</output-dir>
+      </compilation-unit>
+    </test-case>
+    <test-case FilePath="column">
       <compilation-unit name="filter/ASTERIXDB-3499">
         <output-dir compare="Text">filter/ASTERIXDB-3499</output-dir>
       </compilation-unit>
@@ -16494,6 +16499,11 @@
       </compilation-unit>
     </test-case>
     <test-case FilePath="column">
+      <compilation-unit name="pushdown/ASTERIXDB-3540">
+        <output-dir compare="Text">pushdown/ASTERIXDB-3540</output-dir>
+      </compilation-unit>
+    </test-case>
+    <test-case FilePath="column">
       <compilation-unit name="pushdown/field-access-pushdown">
         <output-dir compare="Text">pushdown/field-access-pushdown</output-dir>
       </compilation-unit>
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/testsuite_single_partition_sqlpp.xml b/asterixdb/asterix-app/src/test/resources/runtimets/testsuite_single_partition_sqlpp.xml
index 3dcfe8d..dc35948 100644
--- a/asterixdb/asterix-app/src/test/resources/runtimets/testsuite_single_partition_sqlpp.xml
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/testsuite_single_partition_sqlpp.xml
@@ -20,6 +20,91 @@
 <test-suite xmlns="urn:xml.testframework.asterix.apache.org" ResultOffsetPath="results" QueryOffsetPath="queries_sqlpp" QueryFileExtension=".sqlpp">
   <test-group name="column">
     <test-case FilePath="column">
+      <compilation-unit name="assembly/001">
+        <output-dir compare="Text">assembly/001</output-dir>
+      </compilation-unit>
+    </test-case>
+    <test-case FilePath="column">
+      <compilation-unit name="assembly/002">
+        <output-dir compare="Text">assembly/002</output-dir>
+      </compilation-unit>
+    </test-case>
+    <test-case FilePath="column">
+      <compilation-unit name="assembly/003">
+        <output-dir compare="Text">assembly/003</output-dir>
+      </compilation-unit>
+    </test-case>
+    <test-case FilePath="column">
+      <compilation-unit name="assembly/004">
+        <output-dir compare="Text">assembly/004</output-dir>
+      </compilation-unit>
+    </test-case>
+    <test-case FilePath="column">
+      <compilation-unit name="assembly/ASTERIXDB-3491">
+        <output-dir compare="Text">assembly/ASTERIXDB-3491</output-dir>
+      </compilation-unit>
+    </test-case>
+    <test-case FilePath="column">
+      <compilation-unit name="assembly/ASTERIXDB-3504">
+        <output-dir compare="Text">assembly/ASTERIXDB-3504</output-dir>
+      </compilation-unit>
+    </test-case>
+    <test-case FilePath="column">
+      <compilation-unit name="assembly/ASTERIXDB-3491-2">
+        <output-dir compare="Text">assembly/ASTERIXDB-3491-2</output-dir>
+      </compilation-unit>
+    </test-case>
+    <test-case FilePath="column">
+      <compilation-unit name="assembly/ASTERIXDB-3491-3">
+        <output-dir compare="Text">assembly/ASTERIXDB-3491-3</output-dir>
+      </compilation-unit>
+    </test-case>
+    <test-case FilePath="column">
+      <compilation-unit name="assembly/ASTERIXDB-3491-4">
+        <output-dir compare="Text">assembly/ASTERIXDB-3491-4</output-dir>
+      </compilation-unit>
+    </test-case>
+    <test-case FilePath="column">
+      <compilation-unit name="assembly/ASTERIXDB-3491-5">
+        <output-dir compare="Text">assembly/ASTERIXDB-3491-5</output-dir>
+      </compilation-unit>
+    </test-case>
+    <test-case FilePath="column">
+      <compilation-unit name="assembly/ASTERIXDB-3491-6">
+        <output-dir compare="Text">assembly/ASTERIXDB-3491-6</output-dir>
+      </compilation-unit>
+    </test-case>
+    <test-case FilePath="column">
+      <compilation-unit name="assembly/ASTERIXDB-3491-7">
+        <output-dir compare="Text">assembly/ASTERIXDB-3491-7</output-dir>
+      </compilation-unit>
+    </test-case>
+    <test-case FilePath="column">
+      <compilation-unit name="assembly/ASTERIXDB-3539">
+        <output-dir compare="Text">assembly/ASTERIXDB-3539</output-dir>
+      </compilation-unit>
+    </test-case>
+    <test-case FilePath="column">
+      <compilation-unit name="filter/ASTERIXDB-3499">
+        <output-dir compare="Text">filter/ASTERIXDB-3499</output-dir>
+      </compilation-unit>
+    </test-case>
+    <test-case FilePath="column">
+      <compilation-unit name="filter/ASTERIXDB-3502">
+        <output-dir compare="Text">filter/ASTERIXDB-3502</output-dir>
+      </compilation-unit>
+    </test-case>
+    <test-case FilePath="column">
+      <compilation-unit name="delete/001">
+        <output-dir compare="Text">delete/001</output-dir>
+      </compilation-unit>
+    </test-case>
+    <test-case FilePath="column">
+      <compilation-unit name="delete/002">
+        <output-dir compare="Text">delete/002</output-dir>
+      </compilation-unit>
+    </test-case>
+    <test-case FilePath="column">
       <compilation-unit name="delete/003">
         <output-dir compare="Text">delete/003</output-dir>
       </compilation-unit>
@@ -34,5 +119,307 @@
         <output-dir compare="Text">delete/005</output-dir>
       </compilation-unit>
     </test-case>
+    <test-case FilePath="column">
+      <compilation-unit name="nested-pk">
+        <output-dir compare="Text">nested-pk</output-dir>
+      </compilation-unit>
+    </test-case>
+    <test-case FilePath="column">
+      <compilation-unit name="composite-pks">
+        <output-dir compare="Text">composite-pks</output-dir>
+      </compilation-unit>
+    </test-case>
+    <test-case FilePath="column">
+      <compilation-unit name="meta/meta_after_gby">
+        <output-dir compare="Text">meta/meta_after_gby</output-dir>
+      </compilation-unit>
+    </test-case>
+    <test-case FilePath="column">
+      <compilation-unit name="meta/meta_in_with_clause">
+        <output-dir compare="Text">meta/meta_in_with_clause</output-dir>
+      </compilation-unit>
+    </test-case>
+    <test-case FilePath="column">
+      <compilation-unit name="meta/resolving_pk_with_meta">
+        <output-dir compare="Text">meta/resolving_pk_with_meta</output-dir>
+      </compilation-unit>
+    </test-case>
+    <test-case FilePath="column">
+      <compilation-unit name="missing-null-values/001">
+        <output-dir compare="Text">missing-null-values/001</output-dir>
+      </compilation-unit>
+    </test-case>
+    <test-case FilePath="column">
+      <compilation-unit name="missing-null-values/002">
+        <output-dir compare="Text">missing-null-values/002</output-dir>
+      </compilation-unit>
+    </test-case>
+    <test-case FilePath="column">
+      <compilation-unit name="missing-null-values/003">
+        <output-dir compare="Text">missing-null-values/003</output-dir>
+      </compilation-unit>
+    </test-case>
+    <test-case FilePath="column">
+      <compilation-unit name="missing-null-values/003">
+        <output-dir compare="Text">missing-null-values/003</output-dir>
+      </compilation-unit>
+    </test-case>
+    <test-case FilePath="column">
+      <compilation-unit name="missing-null-values/005">
+        <output-dir compare="Text">missing-null-values/005</output-dir>
+      </compilation-unit>
+    </test-case>
+    <test-case FilePath="column">
+      <compilation-unit name="missing-null-values/006">
+        <output-dir compare="Text">missing-null-values/006</output-dir>
+      </compilation-unit>
+    </test-case>
+    <test-case FilePath="column">
+      <compilation-unit name="missing-null-values/007">
+        <output-dir compare="Text">missing-null-values/007</output-dir>
+      </compilation-unit>
+    </test-case>
+    <test-case FilePath="column">
+      <compilation-unit name="missing-null-values/008">
+        <output-dir compare="Text">missing-null-values/008</output-dir>
+      </compilation-unit>
+    </test-case>
+    <test-case FilePath="column">
+      <compilation-unit name="empty-array/001">
+        <output-dir compare="Text">empty-array/001</output-dir>
+      </compilation-unit>
+    </test-case>
+    <test-case FilePath="column">
+      <compilation-unit name="empty-array/002">
+        <output-dir compare="Text">empty-array/002</output-dir>
+      </compilation-unit>
+    </test-case>
+    <test-case FilePath="column">
+      <compilation-unit name="empty-array/003">
+        <output-dir compare="Text">empty-array/003</output-dir>
+      </compilation-unit>
+    </test-case>
+    <test-case FilePath="column">
+      <compilation-unit name="pushdown/array-access-pushdown">
+        <output-dir compare="Text">pushdown/array-access-pushdown</output-dir>
+      </compilation-unit>
+    </test-case>
+    <test-case FilePath="column">
+      <compilation-unit name="pushdown/field-access-pushdown">
+        <output-dir compare="Text">pushdown/field-access-pushdown</output-dir>
+      </compilation-unit>
+    </test-case>
+    <test-case FilePath="column">
+      <compilation-unit name="pushdown/ASTERIXDB-3540">
+        <output-dir compare="Text">pushdown/ASTERIXDB-3540</output-dir>
+      </compilation-unit>
+    </test-case>
+    <test-case FilePath="column">
+      <compilation-unit name="pushdown/heterogeneous-access-pushdown">
+        <output-dir compare="Text">pushdown/heterogeneous-access-pushdown</output-dir>
+      </compilation-unit>
+    </test-case>
+    <test-case FilePath="column">
+      <compilation-unit name="pushdown/join/condition-pushdown">
+        <output-dir compare="Text">pushdown/join/condition-pushdown</output-dir>
+      </compilation-unit>
+    </test-case>
+    <test-case FilePath="column">
+      <compilation-unit name="pushdown/join/left-outer">
+        <output-dir compare="Text">pushdown/join/left-outer</output-dir>
+      </compilation-unit>
+    </test-case>
+    <test-case FilePath="column">
+      <compilation-unit name="pushdown/other-pushdowns">
+        <output-dir compare="Text">pushdown/other-pushdowns</output-dir>
+      </compilation-unit>
+    </test-case>
+    <test-case FilePath="column">
+      <compilation-unit name="pushdown/replicate">
+        <output-dir compare="Text">pushdown/replicate</output-dir>
+      </compilation-unit>
+    </test-case>
+    <test-case FilePath="column">
+      <compilation-unit name="select-count-one-field">
+        <output-dir compare="Text">select-count-one-field</output-dir>
+      </compilation-unit>
+    </test-case>
+    <test-case FilePath="column">
+      <compilation-unit name="upsert/001">
+        <output-dir compare="Text">upsert/001</output-dir>
+      </compilation-unit>
+    </test-case>
+    <test-case FilePath="column">
+      <compilation-unit name="upsert/002">
+        <output-dir compare="Text">upsert/002</output-dir>
+      </compilation-unit>
+    </test-case>
+    <test-case FilePath="column">
+      <compilation-unit name="upsert/003">
+        <output-dir compare="Text">upsert/003</output-dir>
+      </compilation-unit>
+    </test-case>
+    <test-case FilePath="column" check-warnings="true">
+      <compilation-unit name="filter/001">
+        <output-dir compare="Text">filter/001</output-dir>
+        <expected-warn>ASX0051: Incomparable input types: string and bigint (in line 30, at column 23)</expected-warn>
+        <expected-warn>ASX0051: Incomparable input types: bigint and string (in line 29, at column 38)</expected-warn>
+        <expected-warn>ASX0051: Incomparable input types: array and bigint (in line 28, at column 15)</expected-warn>
+      </compilation-unit>
+    </test-case>
+    <test-case FilePath="column" check-warnings="true">
+      <compilation-unit name="filter/002">
+        <output-dir compare="Text">filter/002</output-dir>
+        <expected-warn>ASX0051: Incomparable input types: string and bigint (in line 29, at column 23)</expected-warn>
+      </compilation-unit>
+    </test-case>
+    <test-case FilePath="column">
+      <compilation-unit name="filter/003">
+        <output-dir compare="Text">filter/003</output-dir>
+      </compilation-unit>
+    </test-case>
+    <test-case FilePath="column">
+      <compilation-unit name="filter/004">
+        <output-dir compare="Text">filter/004</output-dir>
+      </compilation-unit>
+    </test-case>
+    <test-case FilePath="column">
+      <compilation-unit name="filter/005">
+        <output-dir compare="Text">filter/005</output-dir>
+      </compilation-unit>
+    </test-case>
+    <test-case FilePath="column">
+      <compilation-unit name="filter/006">
+        <output-dir compare="Text">filter/006</output-dir>
+      </compilation-unit>
+    </test-case>
+    <test-case FilePath="column">
+      <compilation-unit name="filter/007">
+        <output-dir compare="Text">filter/007</output-dir>
+      </compilation-unit>
+    </test-case>
+    <test-case FilePath="column">
+      <compilation-unit name="filter/008">
+        <output-dir compare="Text">filter/008</output-dir>
+      </compilation-unit>
+    </test-case>
+    <test-case FilePath="column" check-warnings="true">
+      <compilation-unit name="filter/boolean">
+        <output-dir compare="Text">filter/boolean</output-dir>
+        <expected-warn>ASX0051: Incomparable input types: array and boolean (in line 27, at column 8)</expected-warn>
+      </compilation-unit>
+    </test-case>
+    <test-case FilePath="column">
+      <compilation-unit name="filter/delete">
+        <output-dir compare="Text">filter/delete</output-dir>
+      </compilation-unit>
+    </test-case>
+    <test-case FilePath="column">
+      <compilation-unit name="filter/not-in_every">
+        <output-dir compare="Text">filter/not-in_every</output-dir>
+      </compilation-unit>
+    </test-case>
+    <test-case FilePath="column" check-warnings="true">
+      <compilation-unit name="filter/non-existing-fields">
+        <output-dir compare="Text">filter/non-existing-fields</output-dir>
+      </compilation-unit>
+    </test-case>
+    <test-case FilePath="column">
+      <compilation-unit name="filter/sql-compat">
+        <output-dir compare="Text">filter/sql-compat</output-dir>
+      </compilation-unit>
+    </test-case>
+    <test-case FilePath="column">
+      <compilation-unit name="filter/subplan">
+        <output-dir compare="Text">filter/subplan</output-dir>
+      </compilation-unit>
+    </test-case>
+    <test-case FilePath="column">
+      <compilation-unit name="big-object">
+        <output-dir compare="Text">big-object</output-dir>
+      </compilation-unit>
+    </test-case>
+    <test-case FilePath="column">
+      <compilation-unit name="secondary-index/array-index/use-case-1">
+        <output-dir compare="Text">secondary-index/array-index/use-case-1</output-dir>
+      </compilation-unit>
+    </test-case>
+    <test-case FilePath="column">
+      <compilation-unit name="secondary-index/array-index/use-case-2">
+        <output-dir compare="Text">secondary-index/array-index/use-case-2</output-dir>
+      </compilation-unit>
+    </test-case>
+    <test-case FilePath="column">
+      <compilation-unit name="secondary-index/array-index/use-case-3">
+        <output-dir compare="Text">secondary-index/array-index/use-case-3</output-dir>
+      </compilation-unit>
+    </test-case>
+    <test-case FilePath="column">
+      <compilation-unit name="secondary-index/array-index/use-case-4">
+        <output-dir compare="Text">secondary-index/array-index/use-case-4</output-dir>
+      </compilation-unit>
+    </test-case>
+    <test-case FilePath="column">
+      <compilation-unit name="secondary-index/array-index/with-additional-atomic-index">
+        <output-dir compare="Text">secondary-index/array-index/with-additional-atomic-index</output-dir>
+      </compilation-unit>
+    </test-case>
+    <test-case FilePath="column">
+      <compilation-unit name="secondary-index/array-index/with-composite-sk">
+        <output-dir compare="Text">secondary-index/array-index/with-composite-sk</output-dir>
+      </compilation-unit>
+    </test-case>
+    <test-case FilePath="column">
+      <compilation-unit name="secondary-index/index-with-meta">
+        <output-dir compare="Text">secondary-index/index-with-meta</output-dir>
+      </compilation-unit>
+    </test-case>
+    <test-case FilePath="column">
+      <compilation-unit name="secondary-index/create-index/after-bulkload">
+        <output-dir compare="Text">secondary-index/create-index/after-bulkload</output-dir>
+      </compilation-unit>
+    </test-case>
+    <test-case FilePath="column">
+      <compilation-unit name="secondary-index/create-index/after-insert">
+        <output-dir compare="Text">secondary-index/create-index/after-insert</output-dir>
+      </compilation-unit>
+    </test-case>
+    <test-case FilePath="column">
+      <compilation-unit name="secondary-index/create-index/after-upsert-with-meta">
+        <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="secondary-index/outer-join">
+        <output-dir compare="Text">secondary-index/outer-join</output-dir>
+      </compilation-unit>
+    </test-case>
+    <test-case FilePath="column">
+      <compilation-unit name="metadata">
+        <output-dir compare="Text">metadata</output-dir>
+      </compilation-unit>
+    </test-case>
+    <test-case FilePath="column">
+      <compilation-unit name="supported-types">
+        <output-dir compare="Text">supported-types</output-dir>
+        <expected-error>ASX0067: Type(s) '[datetime]' are not supported in columnar storage format. Supported types are [bigint, float, double, string, boolean, uuid]</expected-error>
+        <expected-error>ASX0067: Type(s) '[datetime, date, time, duration]' are not supported in columnar storage format. Supported types are [bigint, float, double, string, boolean, uuid]</expected-error>
+        <expected-error>ASX0067: Type(s) '[datetime]' are not supported in columnar storage format. Supported types are [bigint, float, double, string, boolean, uuid]</expected-error>
+        <expected-error>ASX0067: Type(s) '[datetime]' are not supported in columnar storage format. Supported types are [bigint, float, double, string, boolean, uuid]</expected-error>
+        <source-location>false</source-location>
+      </compilation-unit>
+    </test-case>
+    <test-case FilePath="column">
+      <compilation-unit name="validation">
+        <output-dir compare="Text">validation</output-dir>
+        <expected-error>ASX1191: Merge policy 'correlated-prefix' is not supported with columnar storage format</expected-error>
+        <expected-error>ASX1192: Filters are not supported with columnar storage format</expected-error>
+        <expected-error>ASX1193: Unknown storage format 'col'</expected-error>
+        <expected-error>ASX1194: Index type 'RTREE' is not supported with columnar storage format</expected-error>
+        <expected-error>ASX1194: Index type 'LENGTH_PARTITIONED_NGRAM_INVIX' is not supported with columnar storage format</expected-error>
+        <expected-error>ASX1194: Index type 'LENGTH_PARTITIONED_WORD_INVIX' is not supported with columnar storage format</expected-error>
+        <source-location>false</source-location>
+      </compilation-unit>
+    </test-case>
   </test-group>
 </test-suite>
diff --git a/asterixdb/asterix-column/src/main/java/org/apache/asterix/column/tuple/QueryColumnTupleReference.java b/asterixdb/asterix-column/src/main/java/org/apache/asterix/column/tuple/QueryColumnTupleReference.java
index e1dddf1..64ac0a2 100644
--- a/asterixdb/asterix-column/src/main/java/org/apache/asterix/column/tuple/QueryColumnTupleReference.java
+++ b/asterixdb/asterix-column/src/main/java/org/apache/asterix/column/tuple/QueryColumnTupleReference.java
@@ -162,11 +162,14 @@
         // index == -1 if the normalized filter indicated that a mega leaf node
         // is filtered
         if (index == tupleIndex) {
+            antimatterGap = 0;
             // setAt in the assembler expect the value index (i.e., tupleCount - antiMatterCount)
             assembler.setAt(columnFilterEvaluator.getValueIndex());
             // set the next tuple index that satisfies the filter
             columnFilterEvaluator.evaluate();
             return assembler.nextValue();
+        } else {
+            antimatterGap++;
         }
         return MissingValueGetter.MISSING;
     }
diff --git a/asterixdb/asterix-column/src/main/java/org/apache/asterix/column/tuple/QueryColumnWithMetaTupleReference.java b/asterixdb/asterix-column/src/main/java/org/apache/asterix/column/tuple/QueryColumnWithMetaTupleReference.java
index e7402c3..4202f47 100644
--- a/asterixdb/asterix-column/src/main/java/org/apache/asterix/column/tuple/QueryColumnWithMetaTupleReference.java
+++ b/asterixdb/asterix-column/src/main/java/org/apache/asterix/column/tuple/QueryColumnWithMetaTupleReference.java
@@ -186,12 +186,15 @@
         // index == -1 if the normalized filter indicated that a mega leaf node is filtered
         if (index == tupleIndex) {
             // setAt in the assembler expect the value index (i.e., tupleCount - antiMatterCount)
+            antimatterGap = 0;
             int valueIndex = columnFilterEvaluator.getValueIndex();
             assembler.setAt(valueIndex);
             metaAssembler.setAt(valueIndex);
             // set the next tuple index that satisfies the filter
             columnFilterEvaluator.evaluate();
             return assembler.nextValue();
+        } else {
+            antimatterGap++;
         }
 
         return MissingValueGetter.MISSING;
diff --git a/hyracks-fullstack/hyracks/hyracks-storage-am-lsm-btree-column/src/main/java/org/apache/hyracks/storage/am/lsm/btree/column/api/IColumnTupleIterator.java b/hyracks-fullstack/hyracks/hyracks-storage-am-lsm-btree-column/src/main/java/org/apache/hyracks/storage/am/lsm/btree/column/api/IColumnTupleIterator.java
index 4034906..4b9cc99 100644
--- a/hyracks-fullstack/hyracks/hyracks-storage-am-lsm-btree-column/src/main/java/org/apache/hyracks/storage/am/lsm/btree/column/api/IColumnTupleIterator.java
+++ b/hyracks-fullstack/hyracks/hyracks-storage-am-lsm-btree-column/src/main/java/org/apache/hyracks/storage/am/lsm/btree/column/api/IColumnTupleIterator.java
@@ -108,4 +108,11 @@
     void unpinColumnsPages() throws HyracksDataException;
 
     void close();
+
+    /**
+     * @return the gap between the lastAssembledTuple index and the current antimatter tuple index
+     */
+    int getAntimatterGap();
+
+    void resetAntimatterGap();
 }
diff --git a/hyracks-fullstack/hyracks/hyracks-storage-am-lsm-btree-column/src/main/java/org/apache/hyracks/storage/am/lsm/btree/column/impls/lsm/LSMColumnBTreeRangeSearchCursor.java b/hyracks-fullstack/hyracks/hyracks-storage-am-lsm-btree-column/src/main/java/org/apache/hyracks/storage/am/lsm/btree/column/impls/lsm/LSMColumnBTreeRangeSearchCursor.java
index 41126e2..cee77edd 100644
--- a/hyracks-fullstack/hyracks/hyracks-storage-am-lsm-btree-column/src/main/java/org/apache/hyracks/storage/am/lsm/btree/column/impls/lsm/LSMColumnBTreeRangeSearchCursor.java
+++ b/hyracks-fullstack/hyracks/hyracks-storage-am-lsm-btree-column/src/main/java/org/apache/hyracks/storage/am/lsm/btree/column/impls/lsm/LSMColumnBTreeRangeSearchCursor.java
@@ -86,7 +86,9 @@
         IColumnTupleIterator columnTuple = (IColumnTupleIterator) e.getTuple();
         if (!columnTuple.isAntimatter()) {
             // Skip non-key columns
-            columnTuple.skip(1);
+            int antiMatterGap = columnTuple.getAntimatterGap();
+            columnTuple.skip(antiMatterGap + 1);
+            columnTuple.resetAntimatterGap();
         }
     }
 
diff --git a/hyracks-fullstack/hyracks/hyracks-storage-am-lsm-btree-column/src/main/java/org/apache/hyracks/storage/am/lsm/btree/column/impls/lsm/tuples/AbstractColumnTupleReference.java b/hyracks-fullstack/hyracks/hyracks-storage-am-lsm-btree-column/src/main/java/org/apache/hyracks/storage/am/lsm/btree/column/impls/lsm/tuples/AbstractColumnTupleReference.java
index f30007d..1937ffc 100644
--- a/hyracks-fullstack/hyracks/hyracks-storage-am-lsm-btree-column/src/main/java/org/apache/hyracks/storage/am/lsm/btree/column/impls/lsm/tuples/AbstractColumnTupleReference.java
+++ b/hyracks-fullstack/hyracks/hyracks-storage-am-lsm-btree-column/src/main/java/org/apache/hyracks/storage/am/lsm/btree/column/impls/lsm/tuples/AbstractColumnTupleReference.java
@@ -46,6 +46,7 @@
     private final int numberOfPrimaryKeys;
     private int endIndex;
     protected int tupleIndex;
+    protected int antimatterGap;
 
     // For logging
     private final LongSet pinnedPages;
@@ -102,6 +103,7 @@
     @Override
     public final void newPage() throws HyracksDataException {
         tupleIndex = 0;
+        antimatterGap = 0;
         ByteBuffer pageZero = frame.getBuffer();
         pageZero.clear();
         pageZero.position(HEADER_SIZE);
@@ -119,6 +121,7 @@
     @Override
     public final void reset(int startIndex, int endIndex) throws HyracksDataException {
         tupleIndex = startIndex;
+        antimatterGap = 0;
         this.endIndex = endIndex;
         ByteBuffer pageZero = frame.getBuffer();
         int numberOfTuples = frame.getTupleCount();
@@ -293,4 +296,14 @@
     public final void resetByTupleIndex(ITreeIndexFrame frame, int tupleIndex) {
         throw new UnsupportedOperationException(UNSUPPORTED_OPERATION_MSG);
     }
+
+    @Override
+    public int getAntimatterGap() {
+        return antimatterGap;
+    }
+
+    @Override
+    public void resetAntimatterGap() {
+        antimatterGap = 0;
+    }
 }