You are viewing a plain text version of this content. The canonical link for it is here.
Posted to notifications@asterixdb.apache.org by AsterixDB Code Review <do...@asterix-gerrit.ics.uci.edu> on 2023/12/04 21:52:56 UTC

Change in asterixdb[master]: [ASTERIXDB-3324][COMP][RT] Stabilize columnar filters and projector

From Wail Alkowaileet <wa...@gmail.com>:

Wail Alkowaileet has uploaded this change for review. ( https://asterix-gerrit.ics.uci.edu/c/asterixdb/+/17993 )


Change subject: [ASTERIXDB-3324][COMP][RT] Stabilize columnar filters and projector
......................................................................

[ASTERIXDB-3324][COMP][RT] Stabilize columnar filters and projector

Details:
This patch includes multiple fixes described in ASTERIXDB-3324

Change-Id: Id8d91a207abb619b8a6a996b4446ca6e06eaaa71
---
M asterixdb/asterix-column/src/main/java/org/apache/asterix/column/filter/iterable/accessor/ColumnFilterValueAccessorEvaluatorFactory.java
M asterixdb/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/pushdown/processor/AbstractFilterPushdownProcessor.java
M asterixdb/asterix-column/src/main/java/org/apache/asterix/column/filter/NoOpColumnFilterEvaluatorFactory.java
M asterixdb/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/pushdown/PushdownContext.java
M asterixdb/asterix-column/src/main/java/org/apache/asterix/column/filter/iterable/evaluator/ColumnIterableFilterEvaluatorFactory.java
M asterixdb/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/pushdown/processor/ColumnFilterPushdownProcessor.java
M asterixdb/asterix-column/src/main/java/org/apache/asterix/column/filter/FilterAccessorProvider.java
M asterixdb/asterix-column/src/main/java/org/apache/asterix/column/operation/query/ColumnAssembler.java
A asterixdb/asterix-column/src/main/java/org/apache/asterix/column/filter/range/accessor/MissingColumnRangeFilterValueAccessor.java
M asterixdb/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/pushdown/schema/ExpectedSchemaBuilder.java
M asterixdb/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/pushdown/processor/ColumnValueAccessPushdownProcessor.java
M asterixdb/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/pushdown/visitor/ExpressionValueAccessPushdownVisitor.java
M asterixdb/asterix-column/src/main/java/org/apache/asterix/column/operation/query/QueryColumnWithMetaMetadata.java
M asterixdb/asterix-app/src/test/resources/runtimets/only_sqlpp.xml
M asterixdb/asterix-metadata/src/main/java/org/apache/asterix/metadata/utils/PushdownUtil.java
M asterixdb/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/pushdown/schema/RootExpectedSchemaNode.java
M asterixdb/asterix-column/src/main/java/org/apache/asterix/column/filter/range/accessor/NoOpColumnRangeFilterValueAccessor.java
M asterixdb/asterix-column/src/main/java/org/apache/asterix/column/filter/range/compartor/AbstractColumnFilterComparatorFactory.java
M asterixdb/asterix-column/src/main/java/org/apache/asterix/column/metadata/schema/UnionSchemaNode.java
M asterixdb/asterix-column/src/main/java/org/apache/asterix/column/metadata/schema/visitor/PathExtractorVisitor.java
M asterixdb/asterix-algebra/src/main/java/org/apache/asterix/translator/LangExpressionToPlanTranslator.java
M asterixdb/asterix-column/src/main/java/org/apache/asterix/column/assembler/AssemblerBuilderVisitor.java
M asterixdb/asterix-column/src/main/java/org/apache/asterix/column/operation/query/QueryColumnMetadata.java
M asterixdb/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/pushdown/visitor/PushdownOperatorVisitor.java
M asterixdb/asterix-column/src/main/java/org/apache/asterix/column/metadata/schema/visitor/SchemaClipperVisitor.java
M hyracks-fullstack/hyracks/hyracks-storage-am-lsm-btree-column/src/main/java/org/apache/hyracks/storage/am/lsm/btree/column/impls/btree/AbstractColumnBTreeLeafFrame.java
M asterixdb/asterix-column/src/main/java/org/apache/asterix/column/filter/iterable/IColumnIterableFilterEvaluatorFactory.java
A asterixdb/asterix-column/src/main/java/org/apache/asterix/column/filter/iterable/ColumnFilterEvaluatorContext.java
28 files changed, 531 insertions(+), 104 deletions(-)



  git pull ssh://asterix-gerrit.ics.uci.edu:29418/asterixdb refs/changes/93/17993/1

diff --git a/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/pushdown/PushdownContext.java b/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/pushdown/PushdownContext.java
index 7d1e068..51d25a4 100644
--- a/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/pushdown/PushdownContext.java
+++ b/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/pushdown/PushdownContext.java
@@ -244,7 +244,7 @@
 
     private static Set<LogicalOperatorTag> getScopeOperators() {
         return EnumSet.of(LogicalOperatorTag.INNERJOIN, LogicalOperatorTag.LEFTOUTERJOIN, LogicalOperatorTag.GROUP,
-                LogicalOperatorTag.AGGREGATE, LogicalOperatorTag.WINDOW);
+                LogicalOperatorTag.AGGREGATE, LogicalOperatorTag.WINDOW, LogicalOperatorTag.UNIONALL);
     }
 
 }
diff --git a/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/pushdown/processor/AbstractFilterPushdownProcessor.java b/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/pushdown/processor/AbstractFilterPushdownProcessor.java
index 9a88036..5b9f005 100644
--- a/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/pushdown/processor/AbstractFilterPushdownProcessor.java
+++ b/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/pushdown/processor/AbstractFilterPushdownProcessor.java
@@ -21,6 +21,7 @@
 import static org.apache.asterix.metadata.utils.PushdownUtil.getConstant;
 import static org.apache.asterix.metadata.utils.PushdownUtil.isAnd;
 import static org.apache.asterix.metadata.utils.PushdownUtil.isCompare;
+import static org.apache.asterix.metadata.utils.PushdownUtil.isCompareWithConstant;
 import static org.apache.asterix.metadata.utils.PushdownUtil.isConstant;
 import static org.apache.asterix.metadata.utils.PushdownUtil.isFilterPath;
 
@@ -159,14 +160,21 @@
 
     private boolean inlineAndPushdownFilter(UseDescriptor useDescriptor, ScanDefineDescriptor scanDefineDescriptor)
             throws AlgebricksException {
-        ILogicalOperator selectOp = useDescriptor.getOperator();
-        if (visitedOperators.contains(selectOp)) {
+        ILogicalOperator op = useDescriptor.getOperator();
+        if (visitedOperators.contains(op)) {
             // Skip and follow through to find any other selects that can be pushed down
             return false;
         }
         boolean changed = false;
         // Get a clone of the SELECT expression and inline it
         ILogicalExpression inlinedExpr = pushdownContext.cloneAndInlineExpression(useDescriptor, context);
+
+        if (op.getOperatorTag() == LogicalOperatorTag.INNERJOIN && !isCompareWithConstant(inlinedExpr)) {
+            // This early check is added to handle closed field accesses. Join type computer do not provide the
+            // appropriate input types -- yielding NullPointerException whenever we process closed field accesses.
+            return false;
+        }
+
         // Prepare for pushdown
         preparePushdown(useDescriptor);
         if (pushdownFilterExpression(inlinedExpr)) {
@@ -175,7 +183,7 @@
         }
 
         // Do not push down a select twice.
-        visitedOperators.add(selectOp);
+        visitedOperators.add(op);
         return changed;
     }
 
diff --git a/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/pushdown/processor/ColumnFilterPushdownProcessor.java b/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/pushdown/processor/ColumnFilterPushdownProcessor.java
index 417d6ca..688d0f4 100644
--- a/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/pushdown/processor/ColumnFilterPushdownProcessor.java
+++ b/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/pushdown/processor/ColumnFilterPushdownProcessor.java
@@ -30,6 +30,7 @@
 import org.apache.asterix.common.config.DatasetConfig;
 import org.apache.asterix.metadata.entities.Dataset;
 import org.apache.asterix.metadata.utils.DatasetUtil;
+import org.apache.asterix.metadata.utils.PushdownUtil;
 import org.apache.asterix.om.functions.BuiltinFunctions;
 import org.apache.asterix.om.types.ARecordType;
 import org.apache.asterix.optimizer.rules.pushdown.PushdownContext;
@@ -93,7 +94,7 @@
 
     @Override
     protected void preparePushdown(UseDescriptor useDescriptor) throws AlgebricksException {
-        exprToNodeVisitor.setTypeEnv(useDescriptor.getOperator().computeOutputTypeEnvironment(context));
+        exprToNodeVisitor.setTypeEnv(PushdownUtil.getTypeEnv(useDescriptor.getOperator(), context));
         paths.clear();
     }
 
diff --git a/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/pushdown/processor/ColumnValueAccessPushdownProcessor.java b/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/pushdown/processor/ColumnValueAccessPushdownProcessor.java
index 9378cff..7db3dd2 100644
--- a/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/pushdown/processor/ColumnValueAccessPushdownProcessor.java
+++ b/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/pushdown/processor/ColumnValueAccessPushdownProcessor.java
@@ -21,6 +21,7 @@
 import java.util.List;
 
 import org.apache.asterix.metadata.utils.DatasetUtil;
+import org.apache.asterix.metadata.utils.PushdownUtil;
 import org.apache.asterix.optimizer.rules.pushdown.PushdownContext;
 import org.apache.asterix.optimizer.rules.pushdown.descriptor.DefineDescriptor;
 import org.apache.asterix.optimizer.rules.pushdown.descriptor.ScanDefineDescriptor;
@@ -29,6 +30,7 @@
 import org.apache.asterix.optimizer.rules.pushdown.schema.RootExpectedSchemaNode;
 import org.apache.asterix.optimizer.rules.pushdown.visitor.ExpressionValueAccessPushdownVisitor;
 import org.apache.hyracks.algebricks.common.exceptions.AlgebricksException;
+import org.apache.hyracks.algebricks.core.algebra.base.ILogicalOperator;
 import org.apache.hyracks.algebricks.core.algebra.base.IOptimizationContext;
 import org.apache.hyracks.algebricks.core.algebra.base.LogicalVariable;
 import org.apache.hyracks.algebricks.core.algebra.expressions.IVariableTypeEnvironment;
@@ -81,7 +83,8 @@
         List<UseDescriptor> useDescriptors = pushdownContext.getUseDescriptors(defineDescriptor);
         for (UseDescriptor useDescriptor : useDescriptors) {
             LogicalVariable producedVariable = useDescriptor.getProducedVariable();
-            IVariableTypeEnvironment typeEnv = useDescriptor.getOperator().computeOutputTypeEnvironment(context);
+            ILogicalOperator op = useDescriptor.getOperator();
+            IVariableTypeEnvironment typeEnv = PushdownUtil.getTypeEnv(op, context);
             expressionVisitor.transform(useDescriptor.getExpression(), producedVariable, typeEnv);
         }
 
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 71be18e..6b21508 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
@@ -80,7 +80,7 @@
         AbstractComplexExpectedSchemaNode parent = node.getParent();
         if (parent == null) {
             //It is a root node. Request the entire record
-            varToNode.put(variable, RootExpectedSchemaNode.ALL_FIELDS_ROOT_NODE);
+            varToNode.put(variable, RootExpectedSchemaNode.ALL_FIELDS_ROOT_IRREPLACEABLE_NODE);
         } else {
             // If it is a nested node, replace it to a LEAF node
             AnyExpectedSchemaNode leafNode = (AnyExpectedSchemaNode) node.replaceIfNeeded(ExpectedSchemaNodeType.ANY,
diff --git a/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/pushdown/schema/RootExpectedSchemaNode.java b/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/pushdown/schema/RootExpectedSchemaNode.java
index 1a978f3..189505b 100644
--- a/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/pushdown/schema/RootExpectedSchemaNode.java
+++ b/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/pushdown/schema/RootExpectedSchemaNode.java
@@ -27,7 +27,10 @@
     private static final int ALL_FIELDS_ROOT = 1;
     //Root with custom fields
     private static final int CLIPPED_ROOT = 2;
+    private static final int ALL_FIELDS_ROOT_IRREPLACEABLE = 3;
     public static final RootExpectedSchemaNode ALL_FIELDS_ROOT_NODE = new RootExpectedSchemaNode(ALL_FIELDS_ROOT);
+    public static final RootExpectedSchemaNode ALL_FIELDS_ROOT_IRREPLACEABLE_NODE =
+            new RootExpectedSchemaNode(ALL_FIELDS_ROOT_IRREPLACEABLE);
     public static final RootExpectedSchemaNode EMPTY_ROOT_NODE = new RootExpectedSchemaNode(EMPTY_ROOT);
 
     private final int rootType;
@@ -41,10 +44,6 @@
         this.rootType = rootType;
     }
 
-    public int getRootType() {
-        return rootType;
-    }
-
     @Override
     public AbstractComplexExpectedSchemaNode replaceIfNeeded(ExpectedSchemaNodeType expectedNodeType,
             SourceLocation sourceLocation, String functionName) {
@@ -65,6 +64,6 @@
     }
 
     public boolean isAllFields() {
-        return rootType == ALL_FIELDS_ROOT;
+        return rootType == ALL_FIELDS_ROOT || rootType == ALL_FIELDS_ROOT_IRREPLACEABLE;
     }
 }
diff --git a/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/pushdown/visitor/ExpressionValueAccessPushdownVisitor.java b/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/pushdown/visitor/ExpressionValueAccessPushdownVisitor.java
index 45dfcff..a56f834 100644
--- a/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/pushdown/visitor/ExpressionValueAccessPushdownVisitor.java
+++ b/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/pushdown/visitor/ExpressionValueAccessPushdownVisitor.java
@@ -41,21 +41,8 @@
         this.builder = builder;
     }
 
-    public boolean transform(ILogicalExpression expression, LogicalVariable producedVariable,
-            IVariableTypeEnvironment typeEnv) throws AlgebricksException {
-        return pushValueAccessExpression(expression, producedVariable, typeEnv);
-    }
-
-    private boolean pushValueAccessExpression(Mutable<ILogicalExpression> exprRef, LogicalVariable producedVar,
-            IVariableTypeEnvironment typeEnv) throws AlgebricksException {
-        return pushValueAccessExpression(exprRef.getValue(), producedVar, typeEnv);
-    }
-
-    /**
-     * Pushdown field access expressions and array access expressions down
-     */
-    private boolean pushValueAccessExpression(ILogicalExpression expr, LogicalVariable producedVar,
-            IVariableTypeEnvironment typeEnv) throws AlgebricksException {
+    public boolean transform(ILogicalExpression expr, LogicalVariable producedVar, IVariableTypeEnvironment typeEnv)
+            throws AlgebricksException {
         if (skipPushdown(expr)) {
             return false;
         }
@@ -124,7 +111,7 @@
              * We need to set the produced variable as null here as the produced variable will not correspond to the
              * nested expression.
              */
-            changed |= pushValueAccessExpression(exprRef, producedVar, typeEnv);
+            changed |= transform(exprRef.getValue(), null, typeEnv);
         }
         return changed;
     }
diff --git a/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/pushdown/visitor/PushdownOperatorVisitor.java b/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/pushdown/visitor/PushdownOperatorVisitor.java
index b00f8a1..28309aa 100644
--- a/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/pushdown/visitor/PushdownOperatorVisitor.java
+++ b/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/pushdown/visitor/PushdownOperatorVisitor.java
@@ -43,6 +43,7 @@
 import org.apache.asterix.optimizer.rules.pushdown.schema.RootExpectedSchemaNode;
 import org.apache.commons.lang3.mutable.Mutable;
 import org.apache.hyracks.algebricks.common.exceptions.AlgebricksException;
+import org.apache.hyracks.algebricks.common.utils.Triple;
 import org.apache.hyracks.algebricks.core.algebra.base.ILogicalExpression;
 import org.apache.hyracks.algebricks.core.algebra.base.ILogicalOperator;
 import org.apache.hyracks.algebricks.core.algebra.base.ILogicalPlan;
@@ -51,6 +52,7 @@
 import org.apache.hyracks.algebricks.core.algebra.base.LogicalOperatorTag;
 import org.apache.hyracks.algebricks.core.algebra.base.LogicalVariable;
 import org.apache.hyracks.algebricks.core.algebra.expressions.AbstractFunctionCallExpression;
+import org.apache.hyracks.algebricks.core.algebra.expressions.VariableReferenceExpression;
 import org.apache.hyracks.algebricks.core.algebra.functions.FunctionIdentifier;
 import org.apache.hyracks.algebricks.core.algebra.operators.logical.AbstractScanOperator;
 import org.apache.hyracks.algebricks.core.algebra.operators.logical.AbstractUnnestMapOperator;
@@ -127,7 +129,18 @@
         // Enter scope for (new stage) for operators like GROUP and JOIN
         pushdownContext.enterScope(op);
         defUseComputer.init(op, producedVariables);
+
         op.acceptExpressionTransform(defUseComputer);
+        if (op.getOperatorTag() == LogicalOperatorTag.UNIONALL) {
+            // UnionAll is a special case
+            UnionAllOperator unionOp = (UnionAllOperator) op;
+            for (Triple<LogicalVariable, LogicalVariable, LogicalVariable> vars : unionOp.getVariableMappings()) {
+                VariableReferenceExpression left = new VariableReferenceExpression(vars.first);
+                pushdownContext.use(op, left, -1, null);
+                VariableReferenceExpression right = new VariableReferenceExpression(vars.second);
+                pushdownContext.use(op, right, -1, null);
+            }
+        }
     }
 
     /*
@@ -212,7 +225,8 @@
      * 2- return the actual DatasetDataSource
      */
     private DatasetDataSource getDatasetDataSourceIfApplicable(DataSource dataSource) throws AlgebricksException {
-        if (dataSource == null || dataSource.getDatasourceType() == DataSource.Type.SAMPLE) {
+        if (dataSource == null || dataSource.getDatasourceType() == DataSource.Type.SAMPLE
+                || !(dataSource instanceof DatasetDataSource)) {
             return null;
         }
 
diff --git a/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/translator/LangExpressionToPlanTranslator.java b/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/translator/LangExpressionToPlanTranslator.java
index 68cb285..08561c0 100644
--- a/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/translator/LangExpressionToPlanTranslator.java
+++ b/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/translator/LangExpressionToPlanTranslator.java
@@ -2198,6 +2198,8 @@
         NestedTupleSourceOperator ntsOp = new NestedTupleSourceOperator(new MutableObject<>(subplanOp));
         ntsOp.setSourceLocation(sourceLoc);
         SelectOperator select = new SelectOperator(selectExpr);
+        // Disable pushdowns
+        select.getAnnotations().put(OperatorAnnotations.DISALLOW_FILTER_PUSHDOWN_TO_SCAN, Boolean.TRUE);
         // The select operator cannot be moved up and down, otherwise it will cause
         // typing issues (ASTERIXDB-1203).
         OperatorPropertiesUtil.markMovable(select, false);
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/only_sqlpp.xml b/asterixdb/asterix-app/src/test/resources/runtimets/only_sqlpp.xml
index 334dd52..5f41c2d1 100644
--- a/asterixdb/asterix-app/src/test/resources/runtimets/only_sqlpp.xml
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/only_sqlpp.xml
@@ -19,5 +19,285 @@
  !-->
 <test-suite xmlns="urn:xml.testframework.asterix.apache.org" ResultOffsetPath="results" QueryOffsetPath="queries_sqlpp" QueryFileExtension=".sqlpp">
   <test-group name="failed">
+    <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="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>
+    </test-case>
+    <test-case FilePath="column">
+      <compilation-unit name="delete/004">
+        <output-dir compare="Text">delete/004</output-dir>
+      </compilation-unit>
+    </test-case>
+    <test-case FilePath="column">
+      <compilation-unit name="delete/005">
+        <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="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/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="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" 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" 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/not-in_every">
+        <output-dir compare="Text">filter/not-in_every</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="analyze-dataset">
+        <output-dir compare="Text">analyze-dataset</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-group>
 </test-suite>
diff --git a/asterixdb/asterix-column/src/main/java/org/apache/asterix/column/assembler/AssemblerBuilderVisitor.java b/asterixdb/asterix-column/src/main/java/org/apache/asterix/column/assembler/AssemblerBuilderVisitor.java
index 15e2bb9..891ec54 100644
--- a/asterixdb/asterix-column/src/main/java/org/apache/asterix/column/assembler/AssemblerBuilderVisitor.java
+++ b/asterixdb/asterix-column/src/main/java/org/apache/asterix/column/assembler/AssemblerBuilderVisitor.java
@@ -95,16 +95,18 @@
 
         BitSet declaredFields = handleDeclaredFields(objectNode, info, objectAssembler);
         IntList childrenFieldNameIndexes = objectNode.getChildrenFieldNameIndexes();
-        if (declaredFields.length() < childrenFieldNameIndexes.size()) {
-            //Open fields are requested
+        int numberOfAddedChildren = declaredFields.cardinality();
+        if (numberOfAddedChildren < childrenFieldNameIndexes.size()) {
+            // Now handle any open fields
             for (int i = 0; i < childrenFieldNameIndexes.size(); i++) {
-                int fieldNameIndex = childrenFieldNameIndexes.getInt(i);
-                AbstractSchemaNode childNode = objectNode.getChild(fieldNameIndex);
-                if (childNode.getTypeTag() != ATypeTag.MISSING && !declaredFields.get(fieldNameIndex)) {
+                int fieldNameIdx = childrenFieldNameIndexes.getInt(i);
+                AbstractSchemaNode childNode = objectNode.getChild(fieldNameIdx);
+                if (childNode.getTypeTag() != ATypeTag.MISSING && !declaredFields.get(fieldNameIdx)) {
+                    numberOfAddedChildren++;
                     IAType childType = getChildType(childNode, BuiltinType.ANY);
-                    IValueReference fieldName = columnMetadata.getFieldNamesDictionary().getFieldName(fieldNameIndex);
+                    IValueReference fieldName = columnMetadata.getFieldNamesDictionary().getFieldName(fieldNameIdx);
                     //The last child should be a delegate
-                    boolean delegate = i == childrenFieldNameIndexes.size() - 1;
+                    boolean delegate = numberOfAddedChildren == childrenFieldNameIndexes.size();
                     AssemblerInfo childInfo = new AssemblerInfo(childType, objectAssembler, delegate, fieldName);
                     childNode.accept(this, childInfo);
                 }
@@ -125,17 +127,18 @@
         String[] declaredFieldNames = declaredType.getFieldNames();
         IAType[] declaredFieldTypes = declaredType.getFieldTypes();
 
-        // The last child of a declared field can be a delegate iff all requested fields are declared
-        boolean containsDelegate = objectNode.getChildren().size() == declaredFieldTypes.length;
+        int addedChildren = 0;
+        int requestedChildren = objectNode.getChildren().size();
         for (int i = 0; i < declaredFieldTypes.length; i++) {
             String fieldName = declaredFieldNames[i];
             int fieldNameIndex = columnMetadata.getFieldNamesDictionary().getFieldNameIndex(fieldName);
             //Check if the declared field was requested
             AbstractSchemaNode childNode = objectNode.getChild(fieldNameIndex);
             if (childNode.getTypeTag() != ATypeTag.MISSING) {
+                addedChildren++;
                 IAType childType = getChildType(childNode, declaredFieldTypes[i]);
                 processedFields.set(fieldNameIndex);
-                boolean delegate = containsDelegate && i == declaredFieldTypes.length - 1;
+                boolean delegate = addedChildren == requestedChildren;
                 AssemblerInfo childInfo = new AssemblerInfo(childType, objectAssembler, delegate, i);
                 childNode.accept(this, childInfo);
             }
diff --git a/asterixdb/asterix-column/src/main/java/org/apache/asterix/column/filter/FilterAccessorProvider.java b/asterixdb/asterix-column/src/main/java/org/apache/asterix/column/filter/FilterAccessorProvider.java
index 12c0078..af64325 100644
--- a/asterixdb/asterix-column/src/main/java/org/apache/asterix/column/filter/FilterAccessorProvider.java
+++ b/asterixdb/asterix-column/src/main/java/org/apache/asterix/column/filter/FilterAccessorProvider.java
@@ -32,6 +32,7 @@
 import org.apache.asterix.column.filter.iterable.accessor.UnionColumnFilterValueAccessorEvaluator;
 import org.apache.asterix.column.filter.range.IColumnRangeFilterValueAccessor;
 import org.apache.asterix.column.filter.range.accessor.ColumnRangeFilterValueAccessor;
+import org.apache.asterix.column.filter.range.accessor.MissingColumnRangeFilterValueAccessor;
 import org.apache.asterix.column.filter.range.accessor.NoOpColumnRangeFilterValueAccessor;
 import org.apache.asterix.column.metadata.schema.AbstractSchemaNode;
 import org.apache.asterix.column.metadata.schema.ObjectSchemaNode;
@@ -48,7 +49,6 @@
 import org.apache.hyracks.api.exceptions.HyracksDataException;
 
 public class FilterAccessorProvider {
-    public static final String FILTER_ACCESSOR_PROVIDER_KEY = "filter-accessor-provider";
     private final ObjectSchemaNode root;
     private final ObjectSchemaNode metaRoot;
     private final SchemaClipperVisitor clipperVisitor;
@@ -88,9 +88,13 @@
             cachedNodes.put(path, node);
         }
 
+        if (node.isPrimaryKey()) {
+            return NoOpColumnRangeFilterValueAccessor.INSTANCE;
+        }
+
         ATypeTag typeTag = node.getTypeTag();
         if (typeTag == ATypeTag.MISSING) {
-            return NoOpColumnRangeFilterValueAccessor.INSTANCE;
+            return MissingColumnRangeFilterValueAccessor.INSTANCE;
         }
         IColumnRangeFilterValueAccessor accessor =
                 new ColumnRangeFilterValueAccessor(node.getColumnIndex(), typeTag, min);
diff --git a/asterixdb/asterix-column/src/main/java/org/apache/asterix/column/filter/NoOpColumnFilterEvaluatorFactory.java b/asterixdb/asterix-column/src/main/java/org/apache/asterix/column/filter/NoOpColumnFilterEvaluatorFactory.java
index 4c649a2..5891311 100644
--- a/asterixdb/asterix-column/src/main/java/org/apache/asterix/column/filter/NoOpColumnFilterEvaluatorFactory.java
+++ b/asterixdb/asterix-column/src/main/java/org/apache/asterix/column/filter/NoOpColumnFilterEvaluatorFactory.java
@@ -18,10 +18,10 @@
  */
 package org.apache.asterix.column.filter;
 
+import org.apache.asterix.column.filter.iterable.ColumnFilterEvaluatorContext;
 import org.apache.asterix.column.filter.iterable.IColumnIterableFilterEvaluator;
 import org.apache.asterix.column.filter.iterable.IColumnIterableFilterEvaluatorFactory;
 import org.apache.asterix.column.filter.range.IColumnRangeFilterEvaluatorFactory;
-import org.apache.hyracks.algebricks.runtime.base.IEvaluatorContext;
 import org.apache.hyracks.api.exceptions.HyracksDataException;
 
 /**
@@ -41,8 +41,7 @@
     }
 
     @Override
-    public IColumnIterableFilterEvaluator create(FilterAccessorProvider filterAccessorProvider,
-            IEvaluatorContext context) throws HyracksDataException {
+    public IColumnIterableFilterEvaluator create(ColumnFilterEvaluatorContext context) throws HyracksDataException {
         return TrueColumnFilterEvaluator.INSTANCE;
     }
 
diff --git a/asterixdb/asterix-column/src/main/java/org/apache/asterix/column/filter/iterable/ColumnFilterEvaluatorContext.java b/asterixdb/asterix-column/src/main/java/org/apache/asterix/column/filter/iterable/ColumnFilterEvaluatorContext.java
new file mode 100644
index 0000000..b16eb68
--- /dev/null
+++ b/asterixdb/asterix-column/src/main/java/org/apache/asterix/column/filter/iterable/ColumnFilterEvaluatorContext.java
@@ -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.
+ */
+package org.apache.asterix.column.filter.iterable;
+
+import org.apache.asterix.column.filter.FilterAccessorProvider;
+import org.apache.hyracks.algebricks.runtime.evaluators.EvaluatorContext;
+import org.apache.hyracks.api.context.IHyracksTaskContext;
+
+public class ColumnFilterEvaluatorContext extends EvaluatorContext {
+    private final FilterAccessorProvider filterAccessorProvider;
+
+    public ColumnFilterEvaluatorContext(IHyracksTaskContext taskContext,
+            FilterAccessorProvider filterAccessorProvider) {
+        super(taskContext);
+        this.filterAccessorProvider = filterAccessorProvider;
+    }
+
+    public FilterAccessorProvider getFilterAccessorProvider() {
+        return filterAccessorProvider;
+    }
+}
diff --git a/asterixdb/asterix-column/src/main/java/org/apache/asterix/column/filter/iterable/IColumnIterableFilterEvaluatorFactory.java b/asterixdb/asterix-column/src/main/java/org/apache/asterix/column/filter/iterable/IColumnIterableFilterEvaluatorFactory.java
index 99df077..9690622 100644
--- a/asterixdb/asterix-column/src/main/java/org/apache/asterix/column/filter/iterable/IColumnIterableFilterEvaluatorFactory.java
+++ b/asterixdb/asterix-column/src/main/java/org/apache/asterix/column/filter/iterable/IColumnIterableFilterEvaluatorFactory.java
@@ -20,11 +20,8 @@
 
 import java.io.Serializable;
 
-import org.apache.asterix.column.filter.FilterAccessorProvider;
-import org.apache.hyracks.algebricks.runtime.base.IEvaluatorContext;
 import org.apache.hyracks.api.exceptions.HyracksDataException;
 
 public interface IColumnIterableFilterEvaluatorFactory extends Serializable {
-    IColumnIterableFilterEvaluator create(FilterAccessorProvider filterAccessorProvider, IEvaluatorContext context)
-            throws HyracksDataException;
+    IColumnIterableFilterEvaluator create(ColumnFilterEvaluatorContext context) throws HyracksDataException;
 }
diff --git a/asterixdb/asterix-column/src/main/java/org/apache/asterix/column/filter/iterable/accessor/ColumnFilterValueAccessorEvaluatorFactory.java b/asterixdb/asterix-column/src/main/java/org/apache/asterix/column/filter/iterable/accessor/ColumnFilterValueAccessorEvaluatorFactory.java
index ce26d6b..28623d7 100644
--- a/asterixdb/asterix-column/src/main/java/org/apache/asterix/column/filter/iterable/accessor/ColumnFilterValueAccessorEvaluatorFactory.java
+++ b/asterixdb/asterix-column/src/main/java/org/apache/asterix/column/filter/iterable/accessor/ColumnFilterValueAccessorEvaluatorFactory.java
@@ -19,13 +19,12 @@
 package org.apache.asterix.column.filter.iterable.accessor;
 
 import org.apache.asterix.column.filter.FilterAccessorProvider;
+import org.apache.asterix.column.filter.iterable.ColumnFilterEvaluatorContext;
 import org.apache.asterix.om.types.ARecordType;
 import org.apache.hyracks.algebricks.runtime.base.IEvaluatorContext;
 import org.apache.hyracks.algebricks.runtime.base.IScalarEvaluator;
 import org.apache.hyracks.algebricks.runtime.base.IScalarEvaluatorFactory;
-import org.apache.hyracks.api.context.IHyracksTaskContext;
 import org.apache.hyracks.api.exceptions.HyracksDataException;
-import org.apache.hyracks.dataflow.common.utils.TaskUtil;
 
 public class ColumnFilterValueAccessorEvaluatorFactory implements IScalarEvaluatorFactory {
     private static final long serialVersionUID = -7871899093673316190L;
@@ -37,12 +36,8 @@
 
     @Override
     public IScalarEvaluator createScalarEvaluator(IEvaluatorContext ctx) throws HyracksDataException {
-        IHyracksTaskContext taskContext = ctx.getTaskContext();
-        FilterAccessorProvider provider =
-                TaskUtil.get(FilterAccessorProvider.FILTER_ACCESSOR_PROVIDER_KEY, taskContext);
-        if (provider == null) {
-            throw new IllegalStateException("FILTER_ACCESSOR_PROVIDER_KEY is not set");
-        }
-        return provider.createColumnAccessEvaluator(path);
+        ColumnFilterEvaluatorContext columnEvalCtx = (ColumnFilterEvaluatorContext) ctx;
+        FilterAccessorProvider filterAccessorProvider = columnEvalCtx.getFilterAccessorProvider();
+        return filterAccessorProvider.createColumnAccessEvaluator(path);
     }
 }
diff --git a/asterixdb/asterix-column/src/main/java/org/apache/asterix/column/filter/iterable/evaluator/ColumnIterableFilterEvaluatorFactory.java b/asterixdb/asterix-column/src/main/java/org/apache/asterix/column/filter/iterable/evaluator/ColumnIterableFilterEvaluatorFactory.java
index 742511b..44441dd 100644
--- a/asterixdb/asterix-column/src/main/java/org/apache/asterix/column/filter/iterable/evaluator/ColumnIterableFilterEvaluatorFactory.java
+++ b/asterixdb/asterix-column/src/main/java/org/apache/asterix/column/filter/iterable/evaluator/ColumnIterableFilterEvaluatorFactory.java
@@ -21,10 +21,10 @@
 import java.util.List;
 
 import org.apache.asterix.column.filter.FilterAccessorProvider;
+import org.apache.asterix.column.filter.iterable.ColumnFilterEvaluatorContext;
 import org.apache.asterix.column.filter.iterable.IColumnIterableFilterEvaluator;
 import org.apache.asterix.column.filter.iterable.IColumnIterableFilterEvaluatorFactory;
 import org.apache.asterix.column.values.IColumnValuesReader;
-import org.apache.hyracks.algebricks.runtime.base.IEvaluatorContext;
 import org.apache.hyracks.algebricks.runtime.base.IScalarEvaluator;
 import org.apache.hyracks.algebricks.runtime.base.IScalarEvaluatorFactory;
 import org.apache.hyracks.api.exceptions.HyracksDataException;
@@ -38,10 +38,16 @@
     }
 
     @Override
-    public IColumnIterableFilterEvaluator create(FilterAccessorProvider filterAccessorProvider,
-            IEvaluatorContext context) throws HyracksDataException {
-        List<IColumnValuesReader> readers = filterAccessorProvider.getFilterColumnReaders();
+    public IColumnIterableFilterEvaluator create(ColumnFilterEvaluatorContext context) throws HyracksDataException {
         IScalarEvaluator evaluator = evaluatorFactory.createScalarEvaluator(context);
+        FilterAccessorProvider filterAccessorProvider = context.getFilterAccessorProvider();
+        // Readers are populated by evaluatorFactory.createScalarEvaluator()
+        List<IColumnValuesReader> readers = filterAccessorProvider.getFilterColumnReaders();
+
+        if (readers.isEmpty()) {
+            throw new NullPointerException("Readers are empty");
+        }
+
         if (readers.stream().anyMatch(IColumnValuesReader::isRepeated)) {
             return new ColumnarRepeatedIterableFilterEvaluator(evaluator, readers);
         }
diff --git a/asterixdb/asterix-column/src/main/java/org/apache/asterix/column/filter/range/accessor/MissingColumnRangeFilterValueAccessor.java b/asterixdb/asterix-column/src/main/java/org/apache/asterix/column/filter/range/accessor/MissingColumnRangeFilterValueAccessor.java
new file mode 100644
index 0000000..5a0c7ff
--- /dev/null
+++ b/asterixdb/asterix-column/src/main/java/org/apache/asterix/column/filter/range/accessor/MissingColumnRangeFilterValueAccessor.java
@@ -0,0 +1,39 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.asterix.column.filter.range.accessor;
+
+import org.apache.asterix.column.filter.range.IColumnRangeFilterValueAccessor;
+import org.apache.asterix.om.types.ATypeTag;
+
+public class MissingColumnRangeFilterValueAccessor implements IColumnRangeFilterValueAccessor {
+    public static final IColumnRangeFilterValueAccessor INSTANCE = new MissingColumnRangeFilterValueAccessor();
+
+    private MissingColumnRangeFilterValueAccessor() {
+    }
+
+    @Override
+    public long getNormalizedValue() {
+        throw new IllegalStateException("should not be invoked");
+    }
+
+    @Override
+    public ATypeTag getTypeTag() {
+        return ATypeTag.MISSING;
+    }
+}
diff --git a/asterixdb/asterix-column/src/main/java/org/apache/asterix/column/filter/range/accessor/NoOpColumnRangeFilterValueAccessor.java b/asterixdb/asterix-column/src/main/java/org/apache/asterix/column/filter/range/accessor/NoOpColumnRangeFilterValueAccessor.java
index 5d538c7..2718c2d 100644
--- a/asterixdb/asterix-column/src/main/java/org/apache/asterix/column/filter/range/accessor/NoOpColumnRangeFilterValueAccessor.java
+++ b/asterixdb/asterix-column/src/main/java/org/apache/asterix/column/filter/range/accessor/NoOpColumnRangeFilterValueAccessor.java
@@ -34,6 +34,6 @@
 
     @Override
     public ATypeTag getTypeTag() {
-        return ATypeTag.MISSING;
+        return ATypeTag.ANY;
     }
 }
diff --git a/asterixdb/asterix-column/src/main/java/org/apache/asterix/column/filter/range/compartor/AbstractColumnFilterComparatorFactory.java b/asterixdb/asterix-column/src/main/java/org/apache/asterix/column/filter/range/compartor/AbstractColumnFilterComparatorFactory.java
index 0374a4d..fa9abda 100644
--- a/asterixdb/asterix-column/src/main/java/org/apache/asterix/column/filter/range/compartor/AbstractColumnFilterComparatorFactory.java
+++ b/asterixdb/asterix-column/src/main/java/org/apache/asterix/column/filter/range/compartor/AbstractColumnFilterComparatorFactory.java
@@ -25,6 +25,7 @@
 import org.apache.asterix.column.filter.range.IColumnRangeFilterEvaluatorFactory;
 import org.apache.asterix.column.filter.range.IColumnRangeFilterValueAccessor;
 import org.apache.asterix.column.filter.range.IColumnRangeFilterValueAccessorFactory;
+import org.apache.asterix.column.filter.range.accessor.NoOpColumnRangeFilterValueAccessor;
 import org.apache.asterix.om.types.ATypeTag;
 import org.apache.asterix.om.types.hierachy.ATypeHierarchy;
 import org.apache.hyracks.api.exceptions.HyracksDataException;
@@ -48,7 +49,8 @@
 
         ATypeTag leftTypeTag = leftAccessor.getTypeTag();
         ATypeTag rightTypeTag = rightAccessor.getTypeTag();
-        if (leftTypeTag != rightTypeTag && ATypeHierarchy.isCompatible(leftTypeTag, rightTypeTag)) {
+        if (isNoOp(leftAccessor, rightAccessor)
+                || leftTypeTag != rightTypeTag && ATypeHierarchy.isCompatible(leftTypeTag, rightTypeTag)) {
             // Cannot compare comparable values with different types. Bail out.
             return TrueColumnFilterEvaluator.INSTANCE;
         } else if (cannotCompare(leftTypeTag, rightTypeTag)) {
@@ -57,6 +59,12 @@
         return createComparator(leftAccessor, rightAccessor);
     }
 
+    private boolean isNoOp(IColumnRangeFilterValueAccessor leftAccessor,
+            IColumnRangeFilterValueAccessor rightAccessor) {
+        return leftAccessor == NoOpColumnRangeFilterValueAccessor.INSTANCE
+                || rightAccessor == NoOpColumnRangeFilterValueAccessor.INSTANCE;
+    }
+
     private boolean cannotCompare(ATypeTag leftTypeTag, ATypeTag rightTypeTag) {
         return rightTypeTag == ATypeTag.MISSING || leftTypeTag != rightTypeTag;
     }
diff --git a/asterixdb/asterix-column/src/main/java/org/apache/asterix/column/metadata/schema/UnionSchemaNode.java b/asterixdb/asterix-column/src/main/java/org/apache/asterix/column/metadata/schema/UnionSchemaNode.java
index eba5ac0..246171d 100644
--- a/asterixdb/asterix-column/src/main/java/org/apache/asterix/column/metadata/schema/UnionSchemaNode.java
+++ b/asterixdb/asterix-column/src/main/java/org/apache/asterix/column/metadata/schema/UnionSchemaNode.java
@@ -120,15 +120,18 @@
     }
 
     /**
-     * This would return any numeric node
+     * This would return any numeric node that has a different typeTag than the 'excludeTypeTag'
      *
+     * @param excludeTypeTag exclude child with the provided {@link ATypeTag}
      * @return first numeric node or missing node
      * @see SchemaClipperVisitor
      */
-    public AbstractSchemaNode getNumericChildOrMissing() {
-        for (AbstractSchemaNode node : children.values()) {
-            if (ATypeHierarchy.getTypeDomain(node.getTypeTag()) == ATypeHierarchy.Domain.NUMERIC) {
-                return node;
+    public AbstractSchemaNode getNumericChildOrMissing(ATypeTag excludeTypeTag) {
+        for (AbstractSchemaNode child : children.values()) {
+            ATypeTag childTypeTag = child.getTypeTag();
+            boolean numeric = ATypeHierarchy.getTypeDomain(childTypeTag) == ATypeHierarchy.Domain.NUMERIC;
+            if (numeric && childTypeTag != excludeTypeTag) {
+                return child;
             }
         }
         return MissingFieldSchemaNode.INSTANCE;
diff --git a/asterixdb/asterix-column/src/main/java/org/apache/asterix/column/metadata/schema/visitor/PathExtractorVisitor.java b/asterixdb/asterix-column/src/main/java/org/apache/asterix/column/metadata/schema/visitor/PathExtractorVisitor.java
index efff918..a838315 100644
--- a/asterixdb/asterix-column/src/main/java/org/apache/asterix/column/metadata/schema/visitor/PathExtractorVisitor.java
+++ b/asterixdb/asterix-column/src/main/java/org/apache/asterix/column/metadata/schema/visitor/PathExtractorVisitor.java
@@ -113,7 +113,6 @@
 
     @Override
     public AbstractSchemaNode visit(PrimitiveSchemaNode primitiveNode, Void arg) throws HyracksDataException {
-        //Missing column index is -1
         return primitiveNode;
     }
 
@@ -126,8 +125,9 @@
     private IColumnValuesReader createReader(PrimitiveSchemaNode primitiveNode, List<IColumnValuesReader> readers) {
         IColumnValuesReader reader;
         if (delimiters.isEmpty()) {
-            reader = readerFactory.createValueReader(primitiveNode.getTypeTag(), primitiveNode.getColumnIndex(), level,
-                    primitiveNode.isPrimaryKey());
+            int nodeLeve = primitiveNode.isPrimaryKey() ? 1 : level;
+            reader = readerFactory.createValueReader(primitiveNode.getTypeTag(), primitiveNode.getColumnIndex(),
+                    nodeLeve, primitiveNode.isPrimaryKey());
         } else {
             // array
             reader = readerFactory.createValueReader(primitiveNode.getTypeTag(), primitiveNode.getColumnIndex(), level,
diff --git a/asterixdb/asterix-column/src/main/java/org/apache/asterix/column/metadata/schema/visitor/SchemaClipperVisitor.java b/asterixdb/asterix-column/src/main/java/org/apache/asterix/column/metadata/schema/visitor/SchemaClipperVisitor.java
index 5db01f2..0606bb9 100644
--- a/asterixdb/asterix-column/src/main/java/org/apache/asterix/column/metadata/schema/visitor/SchemaClipperVisitor.java
+++ b/asterixdb/asterix-column/src/main/java/org/apache/asterix/column/metadata/schema/visitor/SchemaClipperVisitor.java
@@ -87,11 +87,11 @@
 
     @Override
     public AbstractSchemaNode visit(AbstractCollectionType collectionType, AbstractSchemaNode arg) {
-        if (isNotCompatible(collectionType, arg)) {
+        if (!arg.isCollection() && isNotCompatible(collectionType, arg)) {
             return MissingFieldSchemaNode.INSTANCE;
         }
         AbstractCollectionSchemaNode collectionNode =
-                getActualNode(arg, collectionType.getTypeTag(), AbstractCollectionSchemaNode.class);
+                getActualNode(arg, arg.getTypeTag(), AbstractCollectionSchemaNode.class);
         AbstractSchemaNode newItemNode = collectionType.getItemType().accept(this, collectionNode.getItemNode());
         AbstractCollectionSchemaNode clippedCollectionNode =
                 AbstractCollectionSchemaNode.create(collectionType.getTypeTag());
@@ -115,14 +115,12 @@
     }
 
     private AbstractSchemaNode getNonCompatibleNumericNodeIfAny(IAType flatType, AbstractSchemaNode arg) {
-        ATypeHierarchy.Domain requestedDomain = ATypeHierarchy.getTypeDomain(flatType.getTypeTag());
-        ATypeHierarchy.Domain nodeDomain = ATypeHierarchy.getTypeDomain(arg.getTypeTag());
-        if (nodeDomain == requestedDomain && nodeDomain == ATypeHierarchy.Domain.NUMERIC) {
+        if (isNumeric(flatType.getTypeTag()) && isNumeric(arg.getTypeTag())) {
             // This will be reconciled by the filter accessor
             return arg;
         } else if (arg.getTypeTag() == ATypeTag.UNION) {
             UnionSchemaNode unionNode = (UnionSchemaNode) arg;
-            return unionNode.getNumericChildOrMissing();
+            return unionNode.getNumericChildOrMissing(flatType.getTypeTag());
         }
 
         return MissingFieldSchemaNode.INSTANCE;
@@ -139,14 +137,16 @@
     }
 
     private boolean isNotCompatible(IAType requestedType, AbstractSchemaNode schemaNode) {
-        if (requestedType.getTypeTag() != schemaNode.getTypeTag()) {
+        ATypeTag requestedTypeTag = requestedType.getTypeTag();
+        if (requestedTypeTag != schemaNode.getTypeTag()) {
             if (schemaNode.getTypeTag() != ATypeTag.UNION) {
                 warn(requestedType, schemaNode);
                 return true;
             }
             // Handle union
             UnionSchemaNode unionNode = (UnionSchemaNode) schemaNode;
-            return notInUnion(requestedType, unionNode);
+            return notInUnion(requestedType, unionNode)
+                    || isNumeric(requestedTypeTag) && unionContainsMultipleNumeric(schemaNode);
         }
         return unionContainsMultipleNumeric(schemaNode);
     }
@@ -178,4 +178,8 @@
         }
         return false;
     }
+
+    private static boolean isNumeric(ATypeTag typeTag) {
+        return ATypeHierarchy.getTypeDomain(typeTag) == ATypeHierarchy.Domain.NUMERIC;
+    }
 }
diff --git a/asterixdb/asterix-column/src/main/java/org/apache/asterix/column/operation/query/ColumnAssembler.java b/asterixdb/asterix-column/src/main/java/org/apache/asterix/column/operation/query/ColumnAssembler.java
index f5a327d..835bb50 100644
--- a/asterixdb/asterix-column/src/main/java/org/apache/asterix/column/operation/query/ColumnAssembler.java
+++ b/asterixdb/asterix-column/src/main/java/org/apache/asterix/column/operation/query/ColumnAssembler.java
@@ -110,6 +110,10 @@
     }
 
     public int skip(int count) throws HyracksDataException {
+        if (numberOfTuples == 0) {
+            // Avoid advancing tupleIndex and numberOfSkips if a mega leaf node is filtered out
+            return 0;
+        }
         numberOfSkips += count;
         tupleIndex += count;
         for (int i = 0; i < assemblers.length; i++) {
diff --git a/asterixdb/asterix-column/src/main/java/org/apache/asterix/column/operation/query/QueryColumnMetadata.java b/asterixdb/asterix-column/src/main/java/org/apache/asterix/column/operation/query/QueryColumnMetadata.java
index e324609..d50af38 100644
--- a/asterixdb/asterix-column/src/main/java/org/apache/asterix/column/operation/query/QueryColumnMetadata.java
+++ b/asterixdb/asterix-column/src/main/java/org/apache/asterix/column/operation/query/QueryColumnMetadata.java
@@ -33,6 +33,7 @@
 import org.apache.asterix.column.filter.FilterAccessorProvider;
 import org.apache.asterix.column.filter.IColumnFilterEvaluator;
 import org.apache.asterix.column.filter.TrueColumnFilterEvaluator;
+import org.apache.asterix.column.filter.iterable.ColumnFilterEvaluatorContext;
 import org.apache.asterix.column.filter.iterable.IColumnIterableFilterEvaluator;
 import org.apache.asterix.column.filter.iterable.IColumnIterableFilterEvaluatorFactory;
 import org.apache.asterix.column.filter.range.IColumnRangeFilterEvaluatorFactory;
@@ -48,14 +49,11 @@
 import org.apache.asterix.column.values.reader.PrimitiveColumnValuesReader;
 import org.apache.asterix.om.types.ARecordType;
 import org.apache.asterix.runtime.projection.FunctionCallInformation;
-import org.apache.hyracks.algebricks.runtime.base.IEvaluatorContext;
-import org.apache.hyracks.algebricks.runtime.evaluators.EvaluatorContext;
 import org.apache.hyracks.api.context.IHyracksTaskContext;
 import org.apache.hyracks.api.exceptions.HyracksDataException;
 import org.apache.hyracks.api.exceptions.IWarningCollector;
 import org.apache.hyracks.data.std.api.IValueReference;
 import org.apache.hyracks.data.std.primitive.IntegerPointable;
-import org.apache.hyracks.dataflow.common.utils.TaskUtil;
 import org.apache.hyracks.storage.am.lsm.btree.column.api.AbstractColumnTupleReader;
 import org.apache.hyracks.util.LogRedactionUtil;
 import org.apache.logging.log4j.LogManager;
@@ -207,20 +205,18 @@
         List<IColumnRangeFilterValueAccessor> filterValueAccessors = Collections.emptyList();
         String jobId = null;
         if (context != null) {
-            FilterAccessorProvider filterAccessorProvider =
+            FilterAccessorProvider accessorProvider =
                     new FilterAccessorProvider(root, clipperVisitor, readerFactory, valueGetterFactory);
-            TaskUtil.put(FilterAccessorProvider.FILTER_ACCESSOR_PROVIDER_KEY, filterAccessorProvider, context);
             // Min/Max filters in page0
-            normalizedFilterEvaluator = normalizedEvaluatorFactory.create(filterAccessorProvider);
-            filterValueAccessors = filterAccessorProvider.getFilterAccessors();
-
+            normalizedFilterEvaluator = normalizedEvaluatorFactory.create(accessorProvider);
+            filterValueAccessors = accessorProvider.getFilterAccessors();
             // Filter columns (columns appeared in WHERE clause)
-            IEvaluatorContext evaluatorContext = new EvaluatorContext(context);
+            ColumnFilterEvaluatorContext evaluatorContext = new ColumnFilterEvaluatorContext(context, accessorProvider);
             // ignore atomic (or flat) types information
             clipperVisitor.setIgnoreFlatType(true);
-            filterAccessorProvider.reset();
-            columnFilterEvaluator = columnFilterEvaluatorFactory.create(filterAccessorProvider, evaluatorContext);
-            filterColumnReaders = filterAccessorProvider.getFilterColumnReaders();
+            accessorProvider.reset();
+            columnFilterEvaluator = columnFilterEvaluatorFactory.create(evaluatorContext);
+            filterColumnReaders = accessorProvider.getFilterColumnReaders();
             jobId = context.getJobletContext().getJobId().toString();
         }
         // log normalized filter
diff --git a/asterixdb/asterix-column/src/main/java/org/apache/asterix/column/operation/query/QueryColumnWithMetaMetadata.java b/asterixdb/asterix-column/src/main/java/org/apache/asterix/column/operation/query/QueryColumnWithMetaMetadata.java
index b4de820..34e40ff 100644
--- a/asterixdb/asterix-column/src/main/java/org/apache/asterix/column/operation/query/QueryColumnWithMetaMetadata.java
+++ b/asterixdb/asterix-column/src/main/java/org/apache/asterix/column/operation/query/QueryColumnWithMetaMetadata.java
@@ -30,6 +30,7 @@
 import org.apache.asterix.column.filter.FilterAccessorProvider;
 import org.apache.asterix.column.filter.IColumnFilterEvaluator;
 import org.apache.asterix.column.filter.TrueColumnFilterEvaluator;
+import org.apache.asterix.column.filter.iterable.ColumnFilterEvaluatorContext;
 import org.apache.asterix.column.filter.iterable.IColumnIterableFilterEvaluator;
 import org.apache.asterix.column.filter.iterable.IColumnIterableFilterEvaluatorFactory;
 import org.apache.asterix.column.filter.range.IColumnRangeFilterEvaluatorFactory;
@@ -44,14 +45,11 @@
 import org.apache.asterix.column.values.reader.PrimitiveColumnValuesReader;
 import org.apache.asterix.om.types.ARecordType;
 import org.apache.asterix.runtime.projection.FunctionCallInformation;
-import org.apache.hyracks.algebricks.runtime.base.IEvaluatorContext;
-import org.apache.hyracks.algebricks.runtime.evaluators.EvaluatorContext;
 import org.apache.hyracks.api.context.IHyracksTaskContext;
 import org.apache.hyracks.api.exceptions.HyracksDataException;
 import org.apache.hyracks.api.exceptions.IWarningCollector;
 import org.apache.hyracks.data.std.api.IValueReference;
 import org.apache.hyracks.data.std.primitive.IntegerPointable;
-import org.apache.hyracks.dataflow.common.utils.TaskUtil;
 import org.apache.hyracks.storage.am.lsm.btree.column.api.AbstractColumnTupleReader;
 
 /**
@@ -150,22 +148,21 @@
         IColumnIterableFilterEvaluator columnFilterEvaluator = TrueColumnFilterEvaluator.INSTANCE;
         List<IColumnValuesReader> filterColumnReaders = Collections.emptyList();
         List<IColumnRangeFilterValueAccessor> filterValueAccessors = Collections.emptyList();
-        String jobId = "";
+        String jobId = null;
         if (context != null) {
-            FilterAccessorProvider filterAccessorProvider =
+            FilterAccessorProvider accessorProvider =
                     new FilterAccessorProvider(root, clipperVisitor, readerFactory, valueGetterFactory);
-            TaskUtil.put(FilterAccessorProvider.FILTER_ACCESSOR_PROVIDER_KEY, filterAccessorProvider, context);
             // Min/Max filters in page0
-            normalizedFilterEvaluator = normalizedEvaluatorFactory.create(filterAccessorProvider);
-            filterValueAccessors = filterAccessorProvider.getFilterAccessors();
+            normalizedFilterEvaluator = normalizedEvaluatorFactory.create(accessorProvider);
+            filterValueAccessors = accessorProvider.getFilterAccessors();
 
             // Filter columns (columns appeared in WHERE clause)
-            IEvaluatorContext evaluatorContext = new EvaluatorContext(context);
+            ColumnFilterEvaluatorContext evaluatorContext = new ColumnFilterEvaluatorContext(context, accessorProvider);
             // ignore atomic (or flat) types information
             clipperVisitor.setIgnoreFlatType(true);
-            filterAccessorProvider.reset();
-            columnFilterEvaluator = columnFilterEvaluatorFactory.create(filterAccessorProvider, evaluatorContext);
-            filterColumnReaders = filterAccessorProvider.getFilterColumnReaders();
+            accessorProvider.reset();
+            columnFilterEvaluator = columnFilterEvaluatorFactory.create(evaluatorContext);
+            filterColumnReaders = accessorProvider.getFilterColumnReaders();
             jobId = context.getJobletContext().getJobId().toString();
         }
 
diff --git a/asterixdb/asterix-metadata/src/main/java/org/apache/asterix/metadata/utils/PushdownUtil.java b/asterixdb/asterix-metadata/src/main/java/org/apache/asterix/metadata/utils/PushdownUtil.java
index aaaeea1..0b8db10 100644
--- a/asterixdb/asterix-metadata/src/main/java/org/apache/asterix/metadata/utils/PushdownUtil.java
+++ b/asterixdb/asterix-metadata/src/main/java/org/apache/asterix/metadata/utils/PushdownUtil.java
@@ -37,7 +37,10 @@
 import org.apache.commons.lang3.mutable.Mutable;
 import org.apache.hyracks.algebricks.common.exceptions.AlgebricksException;
 import org.apache.hyracks.algebricks.core.algebra.base.ILogicalExpression;
+import org.apache.hyracks.algebricks.core.algebra.base.ILogicalOperator;
+import org.apache.hyracks.algebricks.core.algebra.base.IOptimizationContext;
 import org.apache.hyracks.algebricks.core.algebra.base.LogicalExpressionTag;
+import org.apache.hyracks.algebricks.core.algebra.base.LogicalOperatorTag;
 import org.apache.hyracks.algebricks.core.algebra.expressions.AbstractFunctionCallExpression;
 import org.apache.hyracks.algebricks.core.algebra.expressions.ConstantExpression;
 import org.apache.hyracks.algebricks.core.algebra.expressions.IAlgebricksConstantValue;
@@ -60,6 +63,16 @@
     private PushdownUtil() {
     }
 
+    public static IVariableTypeEnvironment getTypeEnv(ILogicalOperator operator, IOptimizationContext context)
+            throws AlgebricksException {
+        if (operator.getOperatorTag() == LogicalOperatorTag.DATASOURCESCAN) {
+            // Special case: for pushed select condition
+            return operator.computeOutputTypeEnvironment(context);
+        } else {
+            return operator.computeInputTypeEnvironment(context);
+        }
+    }
+
     public static String getFieldName(AbstractFunctionCallExpression fieldAccessExpr, IVariableTypeEnvironment typeEnv)
             throws AlgebricksException {
         if (BuiltinFunctions.FIELD_ACCESS_BY_NAME.equals(fieldAccessExpr.getFunctionIdentifier())) {
@@ -162,6 +175,21 @@
         return ((AsterixConstantValue) algebricksConstant).getObject();
     }
 
+    public static boolean isCompareWithConstant(ILogicalExpression expression) {
+        if (!isCompare(expression)) {
+            return false;
+        }
+
+        AbstractFunctionCallExpression funcExpr = (AbstractFunctionCallExpression) expression;
+        for (Mutable<ILogicalExpression> argRef : funcExpr.getArguments()) {
+            if (argRef.getValue().getExpressionTag() == LogicalExpressionTag.CONSTANT) {
+                return true;
+            }
+        }
+
+        return false;
+    }
+
     private static FunctionIdentifier getFunctionIdentifier(ILogicalExpression expression) {
         if (expression.getExpressionTag() != LogicalExpressionTag.FUNCTION_CALL) {
             return null;
diff --git a/hyracks-fullstack/hyracks/hyracks-storage-am-lsm-btree-column/src/main/java/org/apache/hyracks/storage/am/lsm/btree/column/impls/btree/AbstractColumnBTreeLeafFrame.java b/hyracks-fullstack/hyracks/hyracks-storage-am-lsm-btree-column/src/main/java/org/apache/hyracks/storage/am/lsm/btree/column/impls/btree/AbstractColumnBTreeLeafFrame.java
index 9aeafa4..6ecd59e 100644
--- a/hyracks-fullstack/hyracks/hyracks-storage-am-lsm-btree-column/src/main/java/org/apache/hyracks/storage/am/lsm/btree/column/impls/btree/AbstractColumnBTreeLeafFrame.java
+++ b/hyracks-fullstack/hyracks/hyracks-storage-am-lsm-btree-column/src/main/java/org/apache/hyracks/storage/am/lsm/btree/column/impls/btree/AbstractColumnBTreeLeafFrame.java
@@ -94,7 +94,8 @@
     @Override
     public final void setPage(ICachedPage page) {
         this.page = page;
-        this.buf = page.getBuffer();
+        // Duplicate to avoid interference when scanning the dataset twice
+        this.buf = page.getBuffer().duplicate();
         buf.clear();
         buf.position(HEADER_SIZE);
     }

-- 
To view, visit https://asterix-gerrit.ics.uci.edu/c/asterixdb/+/17993
To unsubscribe, or for help writing mail filters, visit https://asterix-gerrit.ics.uci.edu/settings

Gerrit-Project: asterixdb
Gerrit-Branch: master
Gerrit-Change-Id: Id8d91a207abb619b8a6a996b4446ca6e06eaaa71
Gerrit-Change-Number: 17993
Gerrit-PatchSet: 1
Gerrit-Owner: Wail Alkowaileet <wa...@gmail.com>
Gerrit-MessageType: newchange