asterixdb-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From buyin...@apache.org
Subject [1/4] asterixdb git commit: Support CASE expression in SQL++.
Date Tue, 26 Jul 2016 21:23:21 GMT
Repository: asterixdb
Updated Branches:
  refs/heads/master f23d86e98 -> c8c067c58


http://git-wip-us.apache.org/repos/asf/asterixdb/blob/c8c067c5/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/visitor/SqlppSubstituteExpressionsVisitor.java
----------------------------------------------------------------------
diff --git a/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/visitor/SqlppSubstituteExpressionsVisitor.java b/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/visitor/SqlppSubstituteExpressionsVisitor.java
index af160bf..d9b2698 100644
--- a/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/visitor/SqlppSubstituteExpressionsVisitor.java
+++ b/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/visitor/SqlppSubstituteExpressionsVisitor.java
@@ -41,6 +41,7 @@ import org.apache.asterix.lang.sqlpp.clause.SelectElement;
 import org.apache.asterix.lang.sqlpp.clause.SelectRegular;
 import org.apache.asterix.lang.sqlpp.clause.SelectSetOperation;
 import org.apache.asterix.lang.sqlpp.clause.UnnestClause;
+import org.apache.asterix.lang.sqlpp.expression.CaseExpression;
 import org.apache.asterix.lang.sqlpp.expression.IndependentSubquery;
 import org.apache.asterix.lang.sqlpp.expression.SelectExpression;
 import org.apache.asterix.lang.sqlpp.struct.SetOperationRight;
@@ -269,4 +270,18 @@ public class SqlppSubstituteExpressionsVisitor extends SubstituteExpressionVisit
         return null;
     }
 
+    @Override
+    public Expression visit(CaseExpression caseExpr, ExpressionSubstitutionEnvironment env) throws AsterixException {
+        Expression newCaseExpr = env.findSubstitution(caseExpr, deepCopier);
+        if (newCaseExpr == caseExpr) {
+            caseExpr.setConditionExpr(caseExpr.getConditionExpr().accept(this, env));
+            caseExpr.setWhenExprs(rewriteExpressionList(caseExpr.getWhenExprs(), env));
+            caseExpr.setThenExprs(rewriteExpressionList(caseExpr.getThenExprs(), env));
+            caseExpr.setElseExpr(caseExpr.getElseExpr().accept(this, env));
+            return caseExpr;
+        } else {
+            return newCaseExpr.accept(this, env);
+        }
+    }
+
 }

http://git-wip-us.apache.org/repos/asf/asterixdb/blob/c8c067c5/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/visitor/base/AbstractSqlppAstVisitor.java
----------------------------------------------------------------------
diff --git a/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/visitor/base/AbstractSqlppAstVisitor.java b/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/visitor/base/AbstractSqlppAstVisitor.java
index e5bf513..c0947f3 100644
--- a/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/visitor/base/AbstractSqlppAstVisitor.java
+++ b/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/visitor/base/AbstractSqlppAstVisitor.java
@@ -32,6 +32,7 @@ import org.apache.asterix.lang.sqlpp.clause.SelectElement;
 import org.apache.asterix.lang.sqlpp.clause.SelectRegular;
 import org.apache.asterix.lang.sqlpp.clause.SelectSetOperation;
 import org.apache.asterix.lang.sqlpp.clause.UnnestClause;
+import org.apache.asterix.lang.sqlpp.expression.CaseExpression;
 import org.apache.asterix.lang.sqlpp.expression.IndependentSubquery;
 import org.apache.asterix.lang.sqlpp.expression.SelectExpression;
 
@@ -110,4 +111,9 @@ public abstract class AbstractSqlppAstVisitor<R, T> extends AbstractAstVisitor<R
         return null;
     }
 
+    @Override
+    public R visit(CaseExpression caseExpr, T arg) throws AsterixException {
+        return null;
+    }
+
 }

http://git-wip-us.apache.org/repos/asf/asterixdb/blob/c8c067c5/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/visitor/base/AbstractSqlppSimpleExpressionVisitor.java
----------------------------------------------------------------------
diff --git a/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/visitor/base/AbstractSqlppSimpleExpressionVisitor.java b/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/visitor/base/AbstractSqlppSimpleExpressionVisitor.java
index 9fd5a6e..423eb40 100644
--- a/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/visitor/base/AbstractSqlppSimpleExpressionVisitor.java
+++ b/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/visitor/base/AbstractSqlppSimpleExpressionVisitor.java
@@ -58,6 +58,7 @@ import org.apache.asterix.lang.sqlpp.clause.SelectElement;
 import org.apache.asterix.lang.sqlpp.clause.SelectRegular;
 import org.apache.asterix.lang.sqlpp.clause.SelectSetOperation;
 import org.apache.asterix.lang.sqlpp.clause.UnnestClause;
+import org.apache.asterix.lang.sqlpp.expression.CaseExpression;
 import org.apache.asterix.lang.sqlpp.expression.IndependentSubquery;
 import org.apache.asterix.lang.sqlpp.expression.SelectExpression;
 import org.apache.asterix.lang.sqlpp.struct.SetOperationRight;
@@ -267,11 +268,7 @@ public class AbstractSqlppSimpleExpressionVisitor
 
     @Override
     public Expression visit(ListConstructor lc, ILangExpression arg) throws AsterixException {
-        List<Expression> newExprList = new ArrayList<>();
-        for (Expression expr : lc.getExprList()) {
-            newExprList.add(expr.accept(this, lc));
-        }
-        lc.setExprList(newExprList);
+        lc.setExprList(visit(lc.getExprList(), arg));
         return lc;
     }
 
@@ -286,11 +283,7 @@ public class AbstractSqlppSimpleExpressionVisitor
 
     @Override
     public Expression visit(OperatorExpr operatorExpr, ILangExpression arg) throws AsterixException {
-        List<Expression> newExprList = new ArrayList<>();
-        for (Expression expr : operatorExpr.getExprList()) {
-            newExprList.add(expr.accept(this, operatorExpr));
-        }
-        operatorExpr.setExprList(newExprList);
+        operatorExpr.setExprList(visit(operatorExpr.getExprList(), arg));
         return operatorExpr;
     }
 
@@ -353,4 +346,21 @@ public class AbstractSqlppSimpleExpressionVisitor
         return independentSubquery;
     }
 
+    @Override
+    public Expression visit(CaseExpression caseExpr, ILangExpression arg) throws AsterixException {
+        caseExpr.setConditionExpr(caseExpr.getConditionExpr().accept(this, arg));
+        caseExpr.setWhenExprs(visit(caseExpr.getWhenExprs(), arg));
+        caseExpr.setThenExprs(visit(caseExpr.getThenExprs(), arg));
+        caseExpr.setElseExpr(caseExpr.getElseExpr().accept(this, arg));
+        return caseExpr;
+    }
+
+    private List<Expression> visit(List<Expression> exprs, ILangExpression arg) throws AsterixException {
+        List<Expression> newExprList = new ArrayList<>();
+        for (Expression expr : exprs) {
+            newExprList.add(expr.accept(this, arg));
+        }
+        return newExprList;
+    }
+
 }

http://git-wip-us.apache.org/repos/asf/asterixdb/blob/c8c067c5/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/visitor/base/ISqlppVisitor.java
----------------------------------------------------------------------
diff --git a/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/visitor/base/ISqlppVisitor.java b/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/visitor/base/ISqlppVisitor.java
index 4e5e58d..2827e37 100644
--- a/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/visitor/base/ISqlppVisitor.java
+++ b/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/visitor/base/ISqlppVisitor.java
@@ -32,6 +32,7 @@ import org.apache.asterix.lang.sqlpp.clause.SelectElement;
 import org.apache.asterix.lang.sqlpp.clause.SelectRegular;
 import org.apache.asterix.lang.sqlpp.clause.SelectSetOperation;
 import org.apache.asterix.lang.sqlpp.clause.UnnestClause;
+import org.apache.asterix.lang.sqlpp.expression.CaseExpression;
 import org.apache.asterix.lang.sqlpp.expression.IndependentSubquery;
 import org.apache.asterix.lang.sqlpp.expression.SelectExpression;
 
@@ -64,4 +65,6 @@ public interface ISqlppVisitor<R, T> extends ILangVisitor<R, T> {
     R visit(HavingClause havingClause, T arg) throws AsterixException;
 
     R visit(IndependentSubquery independentSubquery, T arg) throws AsterixException;
+
+    R visit(CaseExpression caseExpression, T arg) throws AsterixException;
 }

http://git-wip-us.apache.org/repos/asf/asterixdb/blob/c8c067c5/asterixdb/asterix-lang-sqlpp/src/main/javacc/SQLPP.html
----------------------------------------------------------------------
diff --git a/asterixdb/asterix-lang-sqlpp/src/main/javacc/SQLPP.html b/asterixdb/asterix-lang-sqlpp/src/main/javacc/SQLPP.html
index 8d093d9..7b37ab4 100644
--- a/asterixdb/asterix-lang-sqlpp/src/main/javacc/SQLPP.html
+++ b/asterixdb/asterix-lang-sqlpp/src/main/javacc/SQLPP.html
@@ -42,6 +42,7 @@
 | &lt;ELEMENT: "element"&gt;
 | &lt;ELSE: "else"&gt;
 | &lt;ENFORCED: "enforced"&gt;
+| &lt;END: "end"&gt;
 | &lt;EVERY: "every"&gt;
 | &lt;EXCEPT: "except"&gt;
 | &lt;EXISTS: "exists"&gt;
@@ -674,7 +675,7 @@
 <TR>
 <TD ALIGN=RIGHT VALIGN=BASELINE><A NAME="prod44">Expression</A></TD>
 <TD ALIGN=CENTER VALIGN=BASELINE>::=</TD>
-<TD ALIGN=LEFT VALIGN=BASELINE>( <A HREF="#prod63">OperatorExpr</A> | <A HREF="#prod64">IfThenElse</A> | <A HREF="#prod65">QuantifiedExpression</A> )</TD>
+<TD ALIGN=LEFT VALIGN=BASELINE>( <A HREF="#prod63">OperatorExpr</A> | <A HREF="#prod64">CaseExpr</A> | <A HREF="#prod65">QuantifiedExpression</A> )</TD>
 </TR>
 <TR>
 <TD ALIGN=RIGHT VALIGN=BASELINE><A NAME="prod63">OperatorExpr</A></TD>
@@ -797,9 +798,9 @@
 <TD ALIGN=LEFT VALIGN=BASELINE>( &lt;LEFTPAREN&gt; <A HREF="#prod44">Expression</A> &lt;RIGHTPAREN&gt; | <A HREF="#prod88">Subquery</A> )</TD>
 </TR>
 <TR>
-<TD ALIGN=RIGHT VALIGN=BASELINE><A NAME="prod64">IfThenElse</A></TD>
+<TD ALIGN=RIGHT VALIGN=BASELINE><A NAME="prod64">CaseExpr</A></TD>
 <TD ALIGN=CENTER VALIGN=BASELINE>::=</TD>
-<TD ALIGN=LEFT VALIGN=BASELINE>&lt;IF&gt; &lt;LEFTPAREN&gt; <A HREF="#prod44">Expression</A> &lt;RIGHTPAREN&gt; &lt;THEN&gt; <A HREF="#prod44">Expression</A> &lt;ELSE&gt; <A HREF="#prod44">Expression</A></TD>
+<TD ALIGN=LEFT VALIGN=BASELINE>&lt;CASE&gt; ( <A HREF="#prod44">Expression</A> )? ( &lt;WHEN&gt; <A HREF="#prod44">Expression</A> &lt;THEN&gt; <A HREF="#prod44">Expression</A> )* ( &lt;ELSE&gt; <A HREF="#prod44">Expression</A> )? &lt;END&gt;</TD>
 </TR>
 <TR>
 <TD ALIGN=RIGHT VALIGN=BASELINE><A NAME="prod62">SelectExpression</A></TD>

http://git-wip-us.apache.org/repos/asf/asterixdb/blob/c8c067c5/asterixdb/asterix-lang-sqlpp/src/main/javacc/SQLPP.jj
----------------------------------------------------------------------
diff --git a/asterixdb/asterix-lang-sqlpp/src/main/javacc/SQLPP.jj b/asterixdb/asterix-lang-sqlpp/src/main/javacc/SQLPP.jj
index 99b875a..d496027 100644
--- a/asterixdb/asterix-lang-sqlpp/src/main/javacc/SQLPP.jj
+++ b/asterixdb/asterix-lang-sqlpp/src/main/javacc/SQLPP.jj
@@ -136,6 +136,7 @@ import org.apache.asterix.lang.sqlpp.clause.SelectElement;
 import org.apache.asterix.lang.sqlpp.clause.SelectRegular;
 import org.apache.asterix.lang.sqlpp.clause.SelectSetOperation;
 import org.apache.asterix.lang.sqlpp.clause.UnnestClause;
+import org.apache.asterix.lang.sqlpp.expression.CaseExpression;
 import org.apache.asterix.lang.sqlpp.expression.SelectExpression;
 import org.apache.asterix.lang.sqlpp.optype.JoinType;
 import org.apache.asterix.lang.sqlpp.optype.SetOpType;
@@ -1591,7 +1592,7 @@ Expression Expression():
 (
     LOOKAHEAD(2)
     expr = OperatorExpr()
-    | expr = IfThenElse()
+    | expr = CaseExpr()
     | expr = QuantifiedExpression()
 )
     {
@@ -2212,22 +2213,34 @@ Expression ParenthesizedExpression() throws ParseException:
     }
 }
 
-Expression IfThenElse() throws ParseException:
+
+Expression CaseExpr() throws ParseException:
 {
-  Expression condExpr;
-  Expression thenExpr;
-  Expression elseExpr;
-  IfExpr ifExpr = new IfExpr();
+   Expression conditionExpr = new LiteralExpr(TrueLiteral.INSTANCE);
+   List<Expression> whenExprs = new ArrayList<Expression>();
+   List<Expression> thenExprs = new ArrayList<Expression>();
+   Expression elseExpr = null;
+   
+   Expression whenExpr = null;
+   Expression thenExpr = null;
 }
 {
-    <IF> <LEFTPAREN> condExpr = Expression() <RIGHTPAREN> <THEN> thenExpr = Expression() <ELSE> elseExpr = Expression()
-
-    {
-      ifExpr.setCondExpr(condExpr);
-      ifExpr.setThenExpr(thenExpr);
-      ifExpr.setElseExpr(elseExpr);
-      return ifExpr;
-    }
+   <CASE> (  conditionExpr = Expression() )?
+   (
+     <WHEN> whenExpr = Expression()
+     {
+        whenExprs.add(whenExpr);
+     }
+     <THEN> thenExpr = Expression()
+     {
+        thenExprs.add(thenExpr);
+     }
+   )*
+   (<ELSE> elseExpr = Expression() )?
+   <END>
+   {
+     return new CaseExpression(conditionExpr, whenExprs, thenExprs, elseExpr);
+   }
 }
 
 SelectExpression SelectExpression(boolean subquery) throws ParseException: {
@@ -2821,6 +2834,7 @@ TOKEN [IGNORE_CASE]:
   | <ELEMENT : "element">
   | <ELSE : "else">
   | <ENFORCED : "enforced">
+  | <END : "end">
   | <EVERY : "every">
   | <EXCEPT : "except">
   | <EXISTS : "exists">

http://git-wip-us.apache.org/repos/asf/asterixdb/blob/c8c067c5/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/functions/AsterixBuiltinFunctions.java
----------------------------------------------------------------------
diff --git a/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/functions/AsterixBuiltinFunctions.java b/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/functions/AsterixBuiltinFunctions.java
index e5950e3..e303d97 100644
--- a/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/functions/AsterixBuiltinFunctions.java
+++ b/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/functions/AsterixBuiltinFunctions.java
@@ -55,8 +55,7 @@ import org.apache.asterix.om.typecomputer.impl.AYearMonthDurationTypeComputer;
 import org.apache.asterix.om.typecomputer.impl.AnyTypeComputer;
 import org.apache.asterix.om.typecomputer.impl.BooleanFunctionTypeComputer;
 import org.apache.asterix.om.typecomputer.impl.BooleanOnlyTypeComputer;
-import org.apache.asterix.om.typecomputer.impl.CastListResultTypeComputer;
-import org.apache.asterix.om.typecomputer.impl.CastRecordResultTypeComputer;
+import org.apache.asterix.om.typecomputer.impl.CastTypeComputer;
 import org.apache.asterix.om.typecomputer.impl.ClosedRecordConstructorResultType;
 import org.apache.asterix.om.typecomputer.impl.CollectionMemberResultType;
 import org.apache.asterix.om.typecomputer.impl.CollectionToSequenceTypeComputer;
@@ -584,12 +583,10 @@ public class AsterixBuiltinFunctions {
 
     public static final FunctionIdentifier INJECT_FAILURE = new FunctionIdentifier(FunctionConstants.ASTERIX_NS,
             "inject-failure", 2);
-    public static final FunctionIdentifier CAST_RECORD = new FunctionIdentifier(FunctionConstants.ASTERIX_NS,
-            "cast-record", 1);
     public static final FunctionIdentifier FLOW_RECORD = new FunctionIdentifier(FunctionConstants.ASTERIX_NS,
             "flow-record", 1);
-    public static final FunctionIdentifier CAST_LIST = new FunctionIdentifier(FunctionConstants.ASTERIX_NS, "cast-list",
-            1);
+    public static final FunctionIdentifier CAST_TYPE = new FunctionIdentifier(FunctionConstants.ASTERIX_NS,
+            "cast", 1);
 
     public static final FunctionIdentifier CREATE_UUID = new FunctionIdentifier(FunctionConstants.ASTERIX_NS,
             "create-uuid", 0);
@@ -942,8 +939,7 @@ public class AsterixBuiltinFunctions {
         addFunction(SWITCH_CASE, SwitchCaseComputer.INSTANCE, true);
         addPrivateFunction(REG_EXP, ABooleanTypeComputer.INSTANCE, true);
         addPrivateFunction(INJECT_FAILURE, InjectFailureTypeComputer.INSTANCE, true);
-        addPrivateFunction(CAST_RECORD, CastRecordResultTypeComputer.INSTANCE, true);
-        addPrivateFunction(CAST_LIST, CastListResultTypeComputer.INSTANCE, true);
+        addPrivateFunction(CAST_TYPE, CastTypeComputer.INSTANCE, true);
 
         addFunction(TID, AInt64TypeComputer.INSTANCE, true);
         addFunction(TIME_CONSTRUCTOR, ATimeTypeComputer.INSTANCE, true);
@@ -1416,4 +1412,4 @@ public class AsterixBuiltinFunctions {
         return similarityFunctions.contains(getAsterixFunctionInfo(fi));
     }
 
-}
\ No newline at end of file
+}

http://git-wip-us.apache.org/repos/asf/asterixdb/blob/c8c067c5/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/typecomputer/impl/CastListResultTypeComputer.java
----------------------------------------------------------------------
diff --git a/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/typecomputer/impl/CastListResultTypeComputer.java b/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/typecomputer/impl/CastListResultTypeComputer.java
deleted file mode 100644
index fc4242d..0000000
--- a/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/typecomputer/impl/CastListResultTypeComputer.java
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
- * 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.om.typecomputer.impl;
-
-import org.apache.asterix.om.typecomputer.base.IResultTypeComputer;
-import org.apache.asterix.om.typecomputer.base.TypeCastUtils;
-import org.apache.asterix.om.types.IAType;
-import org.apache.hyracks.algebricks.common.exceptions.AlgebricksException;
-import org.apache.hyracks.algebricks.core.algebra.base.ILogicalExpression;
-import org.apache.hyracks.algebricks.core.algebra.expressions.IVariableTypeEnvironment;
-import org.apache.hyracks.algebricks.core.algebra.expressions.ScalarFunctionCallExpression;
-import org.apache.hyracks.algebricks.core.algebra.metadata.IMetadataProvider;
-
-/**
- * The type computer for the cast-list function
- *
- * @author yingyib
- */
-public class CastListResultTypeComputer implements IResultTypeComputer {
-
-    public static final CastListResultTypeComputer INSTANCE = new CastListResultTypeComputer();
-
-    @Override
-    public IAType computeType(ILogicalExpression expression, IVariableTypeEnvironment env,
-            IMetadataProvider<?, ?> metadataProvider) throws AlgebricksException {
-        ScalarFunctionCallExpression funcExpr = (ScalarFunctionCallExpression) expression;
-        return TypeCastUtils.getRequiredType(funcExpr);
-    }
-}

http://git-wip-us.apache.org/repos/asf/asterixdb/blob/c8c067c5/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/typecomputer/impl/CastRecordResultTypeComputer.java
----------------------------------------------------------------------
diff --git a/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/typecomputer/impl/CastRecordResultTypeComputer.java b/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/typecomputer/impl/CastRecordResultTypeComputer.java
deleted file mode 100644
index e95571b..0000000
--- a/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/typecomputer/impl/CastRecordResultTypeComputer.java
+++ /dev/null
@@ -1,40 +0,0 @@
-/*
- * 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.om.typecomputer.impl;
-
-import org.apache.asterix.om.typecomputer.base.IResultTypeComputer;
-import org.apache.asterix.om.typecomputer.base.TypeCastUtils;
-import org.apache.asterix.om.types.IAType;
-import org.apache.hyracks.algebricks.common.exceptions.AlgebricksException;
-import org.apache.hyracks.algebricks.core.algebra.base.ILogicalExpression;
-import org.apache.hyracks.algebricks.core.algebra.expressions.IVariableTypeEnvironment;
-import org.apache.hyracks.algebricks.core.algebra.expressions.ScalarFunctionCallExpression;
-import org.apache.hyracks.algebricks.core.algebra.metadata.IMetadataProvider;
-
-public class CastRecordResultTypeComputer implements IResultTypeComputer {
-
-    public static final CastRecordResultTypeComputer INSTANCE = new CastRecordResultTypeComputer();
-
-    @Override
-    public IAType computeType(ILogicalExpression expression, IVariableTypeEnvironment env,
-            IMetadataProvider<?, ?> metadataProvider) throws AlgebricksException {
-        ScalarFunctionCallExpression funcExpr = (ScalarFunctionCallExpression) expression;
-        return TypeCastUtils.getRequiredType(funcExpr);
-    }
-}

http://git-wip-us.apache.org/repos/asf/asterixdb/blob/c8c067c5/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/typecomputer/impl/CastTypeComputer.java
----------------------------------------------------------------------
diff --git a/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/typecomputer/impl/CastTypeComputer.java b/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/typecomputer/impl/CastTypeComputer.java
new file mode 100644
index 0000000..64f85cb
--- /dev/null
+++ b/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/typecomputer/impl/CastTypeComputer.java
@@ -0,0 +1,46 @@
+/*
+ * 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.om.typecomputer.impl;
+
+import org.apache.asterix.om.typecomputer.base.IResultTypeComputer;
+import org.apache.asterix.om.typecomputer.base.TypeCastUtils;
+import org.apache.asterix.om.types.IAType;
+import org.apache.hyracks.algebricks.common.exceptions.AlgebricksException;
+import org.apache.hyracks.algebricks.core.algebra.base.ILogicalExpression;
+import org.apache.hyracks.algebricks.core.algebra.expressions.IVariableTypeEnvironment;
+import org.apache.hyracks.algebricks.core.algebra.expressions.ScalarFunctionCallExpression;
+import org.apache.hyracks.algebricks.core.algebra.metadata.IMetadataProvider;
+
+/**
+ * The type computer for the cast-list function
+ *
+ * @author yingyib
+ */
+public class CastTypeComputer implements IResultTypeComputer {
+
+    public static final CastTypeComputer INSTANCE = new CastTypeComputer();
+
+    @Override
+    public IAType computeType(ILogicalExpression expression, IVariableTypeEnvironment env,
+            IMetadataProvider<?, ?> metadataProvider) throws AlgebricksException {
+        ScalarFunctionCallExpression funcExpr = (ScalarFunctionCallExpression) expression;
+        return TypeCastUtils.getRequiredType(funcExpr);
+    }
+}

http://git-wip-us.apache.org/repos/asf/asterixdb/blob/c8c067c5/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/typecomputer/impl/SwitchCaseComputer.java
----------------------------------------------------------------------
diff --git a/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/typecomputer/impl/SwitchCaseComputer.java b/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/typecomputer/impl/SwitchCaseComputer.java
index 167cb44..0eb60cb 100644
--- a/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/typecomputer/impl/SwitchCaseComputer.java
+++ b/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/typecomputer/impl/SwitchCaseComputer.java
@@ -48,19 +48,28 @@ public class SwitchCaseComputer implements IResultTypeComputer {
 
         IAType currentType = null;
         boolean any = false;
-        boolean missable = false;
-        for (int i = 2; i < fce.getArguments().size(); i += 2) {
-            IAType type = (IAType) env.getType(fce.getArguments().get(i).getValue());
-            if (type.getTypeTag() == ATypeTag.UNION) {
-                type = ((AUnionType) type).getActualType();
-                missable = true;
+        boolean unknownable = false;
+        int argSize = fce.getArguments().size();
+        // Checks return types of different branches' return types.
+        // The last return expression is from the ELSE branch and it is optional.
+        for (int argIndex = 2; argIndex < argSize; argIndex += (argIndex + 2 == argSize) ? 1 : 2) {
+            IAType type = (IAType) env.getType(fce.getArguments().get(argIndex).getValue());
+            ATypeTag typeTag = type.getTypeTag();
+            if (typeTag == ATypeTag.NULL || typeTag == ATypeTag.MISSING) {
+                unknownable = true;
+            } else {
+                if (typeTag == ATypeTag.UNION) {
+                    type = ((AUnionType) type).getActualType();
+                    unknownable = true;
+                }
+                if (currentType != null && !type.equals(currentType)) {
+                    any = true;
+                    break;
+                }
+                currentType = type;
             }
-            if (currentType != null && !type.equals(currentType)) {
-                any = true;
-                break;
-            }
-            currentType = type;
         }
-        return any ? BuiltinType.ANY : missable ? AUnionType.createMissableType(currentType) : currentType;
+        currentType = currentType == null ? BuiltinType.ANULL : currentType;
+        return any ? BuiltinType.ANY : unknownable ? AUnionType.createUnknownableType(currentType) : currentType;
     }
 }

http://git-wip-us.apache.org/repos/asf/asterixdb/blob/c8c067c5/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/common/AbstractTypeCheckEvaluator.java
----------------------------------------------------------------------
diff --git a/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/common/AbstractTypeCheckEvaluator.java b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/common/AbstractTypeCheckEvaluator.java
index 800afd7..2866f7b 100644
--- a/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/common/AbstractTypeCheckEvaluator.java
+++ b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/common/AbstractTypeCheckEvaluator.java
@@ -23,6 +23,7 @@ import java.io.DataOutput;
 
 import org.apache.asterix.dataflow.data.nontagged.serde.AObjectSerializerDeserializer;
 import org.apache.asterix.om.base.ABoolean;
+import org.apache.asterix.om.types.ATypeTag;
 import org.apache.hyracks.algebricks.common.exceptions.AlgebricksException;
 import org.apache.hyracks.algebricks.runtime.base.IScalarEvaluator;
 import org.apache.hyracks.api.exceptions.HyracksDataException;
@@ -33,6 +34,13 @@ import org.apache.hyracks.dataflow.common.data.accessors.IFrameTupleReference;
 
 public abstract class AbstractTypeCheckEvaluator implements IScalarEvaluator {
 
+    protected enum Value {
+        TRUE,
+        FALSE,
+        MISSING
+    }
+
+    private static final byte[] MISSING_BYTES = new byte[] { ATypeTag.SERIALIZED_MISSING_TYPE_TAG };
     private final ArrayBackedValueStorage resultStorage = new ArrayBackedValueStorage();
     private final DataOutput out = resultStorage.getDataOutput();
     private final IPointable argPtr = new VoidPointable();
@@ -46,8 +54,12 @@ public abstract class AbstractTypeCheckEvaluator implements IScalarEvaluator {
     @Override
     public void evaluate(IFrameTupleReference tuple, IPointable result) throws AlgebricksException {
         eval.evaluate(tuple, argPtr);
-        boolean match = isMatch(argPtr.getByteArray()[argPtr.getStartOffset()]);
-        ABoolean res = match ? ABoolean.TRUE : ABoolean.FALSE;
+        Value match = isMatch(argPtr.getByteArray()[argPtr.getStartOffset()]);
+        if (match == Value.MISSING) {
+            result.set(MISSING_BYTES, 0, MISSING_BYTES.length);
+            return;
+        }
+        ABoolean res = match == Value.TRUE ? ABoolean.TRUE : ABoolean.FALSE;
         try {
             resultStorage.reset();
             aObjSerDer.serialize(res, out);
@@ -57,6 +69,6 @@ public abstract class AbstractTypeCheckEvaluator implements IScalarEvaluator {
         }
     }
 
-    protected abstract boolean isMatch(byte typeTag);
+    protected abstract Value isMatch(byte typeTag);
 
 }

http://git-wip-us.apache.org/repos/asf/asterixdb/blob/c8c067c5/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/CastListDescriptor.java
----------------------------------------------------------------------
diff --git a/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/CastListDescriptor.java b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/CastListDescriptor.java
deleted file mode 100644
index f776d1d..0000000
--- a/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/CastListDescriptor.java
+++ /dev/null
@@ -1,105 +0,0 @@
-/*
- * 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.runtime.evaluators.functions;
-
-import org.apache.asterix.om.functions.AsterixBuiltinFunctions;
-import org.apache.asterix.om.functions.IFunctionDescriptor;
-import org.apache.asterix.om.functions.IFunctionDescriptorFactory;
-import org.apache.asterix.om.pointables.PointableAllocator;
-import org.apache.asterix.om.pointables.base.IVisitablePointable;
-import org.apache.asterix.om.pointables.cast.ACastVisitor;
-import org.apache.asterix.om.types.AbstractCollectionType;
-import org.apache.asterix.om.types.IAType;
-import org.apache.asterix.runtime.evaluators.base.AbstractScalarFunctionDynamicDescriptor;
-import org.apache.hyracks.algebricks.common.exceptions.AlgebricksException;
-import org.apache.hyracks.algebricks.common.utils.Triple;
-import org.apache.hyracks.algebricks.core.algebra.functions.FunctionIdentifier;
-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.data.std.api.IPointable;
-import org.apache.hyracks.data.std.primitive.VoidPointable;
-import org.apache.hyracks.dataflow.common.data.accessors.IFrameTupleReference;
-
-/**
- * The runtime function for casting a list(unordered list or ordered list)
- *
- * @author yingyib
- */
-public class CastListDescriptor extends AbstractScalarFunctionDynamicDescriptor {
-
-    public static final IFunctionDescriptorFactory FACTORY = new IFunctionDescriptorFactory() {
-        @Override
-        public IFunctionDescriptor createFunctionDescriptor() {
-            return new CastListDescriptor();
-        }
-    };
-
-    private static final long serialVersionUID = 1L;
-    private AbstractCollectionType reqType;
-    private AbstractCollectionType inputType;
-
-    public void reset(AbstractCollectionType reqType, AbstractCollectionType inputType) {
-        this.reqType = reqType;
-        this.inputType = inputType;
-    }
-
-    @Override
-    public FunctionIdentifier getIdentifier() {
-        return AsterixBuiltinFunctions.CAST_LIST;
-    }
-
-    @Override
-    public IScalarEvaluatorFactory createEvaluatorFactory(final IScalarEvaluatorFactory[] args) {
-        final IScalarEvaluatorFactory recordEvalFactory = args[0];
-
-        return new IScalarEvaluatorFactory() {
-            private static final long serialVersionUID = 1L;
-
-            @Override
-            public IScalarEvaluator createScalarEvaluator(IHyracksTaskContext ctx) throws AlgebricksException {
-                final IPointable recordPtr = new VoidPointable();
-                final IScalarEvaluator recEvaluator = recordEvalFactory.createScalarEvaluator(ctx);
-
-                return new IScalarEvaluator() {
-                    // pointable allocator
-                    private PointableAllocator allocator = new PointableAllocator();
-                    final IVisitablePointable recAccessor = allocator.allocateListValue(inputType);
-                    final IVisitablePointable resultAccessor = allocator.allocateListValue(reqType);
-                    final ACastVisitor castVisitor = new ACastVisitor();
-                    final Triple<IVisitablePointable, IAType, Boolean> arg = new Triple<IVisitablePointable, IAType, Boolean>(
-                            resultAccessor, reqType, Boolean.FALSE);
-
-                    @Override
-                    public void evaluate(IFrameTupleReference tuple, IPointable result) throws AlgebricksException {
-                        try {
-                            recEvaluator.evaluate(tuple, recordPtr);
-                            recAccessor.set(recordPtr);
-                            recAccessor.accept(castVisitor, arg);
-                            result.set(resultAccessor);
-                        } catch (Exception ioe) {
-                            throw new AlgebricksException(ioe);
-                        }
-                    }
-                };
-            }
-        };
-    }
-}

http://git-wip-us.apache.org/repos/asf/asterixdb/blob/c8c067c5/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/CastRecordDescriptor.java
----------------------------------------------------------------------
diff --git a/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/CastRecordDescriptor.java b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/CastRecordDescriptor.java
deleted file mode 100644
index 81e132a..0000000
--- a/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/CastRecordDescriptor.java
+++ /dev/null
@@ -1,102 +0,0 @@
-/*
- * 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.runtime.evaluators.functions;
-
-import org.apache.asterix.om.functions.AsterixBuiltinFunctions;
-import org.apache.asterix.om.functions.IFunctionDescriptor;
-import org.apache.asterix.om.functions.IFunctionDescriptorFactory;
-import org.apache.asterix.om.pointables.PointableAllocator;
-import org.apache.asterix.om.pointables.base.IVisitablePointable;
-import org.apache.asterix.om.pointables.cast.ACastVisitor;
-import org.apache.asterix.om.types.ARecordType;
-import org.apache.asterix.om.types.IAType;
-import org.apache.asterix.runtime.evaluators.base.AbstractScalarFunctionDynamicDescriptor;
-import org.apache.hyracks.algebricks.common.exceptions.AlgebricksException;
-import org.apache.hyracks.algebricks.common.utils.Triple;
-import org.apache.hyracks.algebricks.core.algebra.functions.FunctionIdentifier;
-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.data.std.api.IPointable;
-import org.apache.hyracks.data.std.primitive.VoidPointable;
-import org.apache.hyracks.dataflow.common.data.accessors.IFrameTupleReference;
-
-public class CastRecordDescriptor extends AbstractScalarFunctionDynamicDescriptor {
-
-    private CastRecordDescriptor() {
-    }
-
-    public static final IFunctionDescriptorFactory FACTORY = new IFunctionDescriptorFactory() {
-        @Override
-        public IFunctionDescriptor createFunctionDescriptor() {
-            return new CastRecordDescriptor();
-        }
-    };
-
-    private static final long serialVersionUID = 1L;
-    private ARecordType reqType;
-    private ARecordType inputType;
-
-    public void reset(ARecordType reqType, ARecordType inputType) {
-        this.reqType = reqType;
-        this.inputType = inputType;
-    }
-
-    @Override
-    public FunctionIdentifier getIdentifier() {
-        return AsterixBuiltinFunctions.CAST_RECORD;
-    }
-
-    @Override
-    public IScalarEvaluatorFactory createEvaluatorFactory(final IScalarEvaluatorFactory[] args) {
-        final IScalarEvaluatorFactory recordEvalFactory = args[0];
-
-        return new IScalarEvaluatorFactory() {
-            private static final long serialVersionUID = 1L;
-
-            @Override
-            public IScalarEvaluator createScalarEvaluator(IHyracksTaskContext ctx) throws AlgebricksException {
-                final IPointable recordPtr = new VoidPointable();
-                final IScalarEvaluator recEvaluator = recordEvalFactory.createScalarEvaluator(ctx);
-
-                return new IScalarEvaluator() {
-                    // pointable allocator
-                    private PointableAllocator allocator = new PointableAllocator();
-                    final IVisitablePointable recAccessor = allocator.allocateRecordValue(inputType);
-                    final IVisitablePointable resultAccessor = allocator.allocateRecordValue(reqType);
-                    final ACastVisitor castVisitor = new ACastVisitor();
-                    final Triple<IVisitablePointable, IAType, Boolean> arg = new Triple<>(resultAccessor, reqType,
-                            Boolean.FALSE);
-
-                    @Override
-                    public void evaluate(IFrameTupleReference tuple, IPointable result) throws AlgebricksException {
-                        try {
-                            recEvaluator.evaluate(tuple, recordPtr);
-                            recAccessor.set(recordPtr);
-                            recAccessor.accept(castVisitor, arg);
-                            result.set(resultAccessor);
-                        } catch (Exception ioe) {
-                            throw new AlgebricksException(ioe);
-                        }
-                    }
-                };
-            }
-        };
-    }
-}

http://git-wip-us.apache.org/repos/asf/asterixdb/blob/c8c067c5/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/CastTypeDescriptor.java
----------------------------------------------------------------------
diff --git a/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/CastTypeDescriptor.java b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/CastTypeDescriptor.java
new file mode 100644
index 0000000..5c754cf
--- /dev/null
+++ b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/CastTypeDescriptor.java
@@ -0,0 +1,154 @@
+/*
+ * 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.runtime.evaluators.functions;
+
+import org.apache.asterix.common.exceptions.AsterixException;
+import org.apache.asterix.om.functions.AsterixBuiltinFunctions;
+import org.apache.asterix.om.functions.IFunctionDescriptor;
+import org.apache.asterix.om.functions.IFunctionDescriptorFactory;
+import org.apache.asterix.om.pointables.PointableAllocator;
+import org.apache.asterix.om.pointables.base.DefaultOpenFieldType;
+import org.apache.asterix.om.pointables.base.IVisitablePointable;
+import org.apache.asterix.om.pointables.cast.ACastVisitor;
+import org.apache.asterix.om.types.ATypeTag;
+import org.apache.asterix.om.types.BuiltinType;
+import org.apache.asterix.om.types.IAType;
+import org.apache.asterix.runtime.evaluators.base.AbstractScalarFunctionDynamicDescriptor;
+import org.apache.hyracks.algebricks.common.exceptions.AlgebricksException;
+import org.apache.hyracks.algebricks.common.utils.Triple;
+import org.apache.hyracks.algebricks.core.algebra.functions.FunctionIdentifier;
+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.data.std.api.IPointable;
+import org.apache.hyracks.data.std.primitive.VoidPointable;
+import org.apache.hyracks.dataflow.common.data.accessors.IFrameTupleReference;
+
+/**
+ * This runtime function casts an input ADM instance of a certain type into the form
+ * that confirms a required type.
+ */
+public class CastTypeDescriptor extends AbstractScalarFunctionDynamicDescriptor {
+
+    public static final IFunctionDescriptorFactory FACTORY = new IFunctionDescriptorFactory() {
+
+        @Override
+        public IFunctionDescriptor createFunctionDescriptor() {
+            return new CastTypeDescriptor();
+        }
+    };
+
+    private static final long serialVersionUID = 1L;
+    private IAType reqType;
+    private IAType inputType;
+
+    private CastTypeDescriptor() {
+    }
+
+    public void reset(IAType reqType, IAType inputType) {
+        // If reqType or inputType is null, or they are the same, it indicates there is a bug in the compiler.
+        if (reqType == null || inputType == null || reqType.equals(inputType)) {
+            throw new IllegalStateException(
+                    "Invalid types for casting, required type " + reqType + ", input type " + inputType);
+        }
+        this.reqType = reqType;
+        this.inputType = inputType;
+    }
+
+    @Override
+    public FunctionIdentifier getIdentifier() {
+        return AsterixBuiltinFunctions.CAST_TYPE;
+    }
+
+    @Override
+    public IScalarEvaluatorFactory createEvaluatorFactory(final IScalarEvaluatorFactory[] args) {
+        final IScalarEvaluatorFactory recordEvalFactory = args[0];
+
+        return new IScalarEvaluatorFactory() {
+            private static final long serialVersionUID = 1L;
+
+            @Override
+            public IScalarEvaluator createScalarEvaluator(IHyracksTaskContext ctx) throws AlgebricksException {
+                return new CastTypeEvaluator(reqType, inputType, recordEvalFactory.createScalarEvaluator(ctx));
+            }
+        };
+    }
+}
+
+class CastTypeEvaluator implements IScalarEvaluator {
+
+    private final IScalarEvaluator argEvaluator;
+    private final IPointable argPointable = new VoidPointable();
+
+    private final PointableAllocator allocator = new PointableAllocator();
+    private final IVisitablePointable inputPointable;
+    private final IVisitablePointable resultPointable;
+
+    private final ACastVisitor castVisitor = new ACastVisitor();
+    private final Triple<IVisitablePointable, IAType, Boolean> arg;
+
+    public CastTypeEvaluator(IAType reqType, IAType inputType, IScalarEvaluator argEvaluator)
+            throws AlgebricksException {
+        try {
+            this.argEvaluator = argEvaluator;
+            this.inputPointable = allocateResultPointable(inputType, reqType);
+            this.resultPointable = allocateResultPointable(reqType, inputType);
+            this.arg = new Triple<>(resultPointable, reqType, Boolean.FALSE);
+        } catch (AsterixException e) {
+            throw new AlgebricksException(e);
+        }
+    }
+
+    @Override
+    public void evaluate(IFrameTupleReference tuple, IPointable result) throws AlgebricksException {
+        try {
+            argEvaluator.evaluate(tuple, argPointable);
+            inputPointable.set(argPointable);
+            inputPointable.accept(castVisitor, arg);
+            result.set(resultPointable);
+        } catch (Exception ioe) {
+            throw new AlgebricksException(ioe);
+        }
+    }
+
+    // Allocates the result pointable.
+    private final IVisitablePointable allocateResultPointable(IAType typeForPointable, IAType typeForOtherSide)
+            throws AsterixException {
+        if (!typeForPointable.equals(BuiltinType.ANY)) {
+            return allocator.allocateFieldValue(typeForPointable);
+        }
+        return allocatePointableForAny(typeForOtherSide);
+    }
+
+    // Allocates an input or result pointable if the input or required type is ANY.
+    private IVisitablePointable allocatePointableForAny(IAType type) {
+        ATypeTag tag = type.getTypeTag();
+        switch (tag) {
+            case RECORD:
+                return allocator.allocateFieldValue(DefaultOpenFieldType.NESTED_OPEN_RECORD_TYPE);
+            case ORDEREDLIST:
+                return allocator.allocateFieldValue(DefaultOpenFieldType.NESTED_OPEN_AORDERED_LIST_TYPE);
+            case UNORDEREDLIST:
+                return allocator.allocateFieldValue(DefaultOpenFieldType.NESTED_OPEN_AUNORDERED_LIST_TYPE);
+            default:
+                return allocator.allocateFieldValue(null);
+        }
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/asterixdb/blob/c8c067c5/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/IsMissingDescriptor.java
----------------------------------------------------------------------
diff --git a/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/IsMissingDescriptor.java b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/IsMissingDescriptor.java
index 45c3f6d..a3bdb30 100644
--- a/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/IsMissingDescriptor.java
+++ b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/IsMissingDescriptor.java
@@ -51,8 +51,8 @@ public class IsMissingDescriptor extends AbstractScalarFunctionDynamicDescriptor
                 return new AbstractTypeCheckEvaluator(eval) {
 
                     @Override
-                    protected boolean isMatch(byte typeTag) {
-                        return typeTag == ATypeTag.SERIALIZED_MISSING_TYPE_TAG;
+                    protected Value isMatch(byte typeTag) {
+                        return typeTag == ATypeTag.SERIALIZED_MISSING_TYPE_TAG ? Value.TRUE : Value.FALSE;
                     }
                 };
             }

http://git-wip-us.apache.org/repos/asf/asterixdb/blob/c8c067c5/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/IsNullDescriptor.java
----------------------------------------------------------------------
diff --git a/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/IsNullDescriptor.java b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/IsNullDescriptor.java
index 3ae3bd9..33db8f3 100644
--- a/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/IsNullDescriptor.java
+++ b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/IsNullDescriptor.java
@@ -51,8 +51,11 @@ public class IsNullDescriptor extends AbstractScalarFunctionDynamicDescriptor {
                 return new AbstractTypeCheckEvaluator(eval) {
 
                     @Override
-                    protected boolean isMatch(byte typeTag) {
-                        return typeTag == ATypeTag.SERIALIZED_NULL_TYPE_TAG;
+                    protected Value isMatch(byte typeTag) {
+                        if (typeTag == ATypeTag.SERIALIZED_MISSING_TYPE_TAG) {
+                            return Value.MISSING;
+                        }
+                        return typeTag == ATypeTag.SERIALIZED_NULL_TYPE_TAG ? Value.TRUE : Value.FALSE;
                     }
                 };
             }

http://git-wip-us.apache.org/repos/asf/asterixdb/blob/c8c067c5/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/IsUnknownDescriptor.java
----------------------------------------------------------------------
diff --git a/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/IsUnknownDescriptor.java b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/IsUnknownDescriptor.java
index be04c86..ef5f42c 100644
--- a/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/IsUnknownDescriptor.java
+++ b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/IsUnknownDescriptor.java
@@ -51,9 +51,9 @@ public class IsUnknownDescriptor extends AbstractScalarFunctionDynamicDescriptor
                 return new AbstractTypeCheckEvaluator(eval) {
 
                     @Override
-                    protected boolean isMatch(byte typeTag) {
-                        return typeTag == ATypeTag.SERIALIZED_NULL_TYPE_TAG
-                                || typeTag == ATypeTag.SERIALIZED_MISSING_TYPE_TAG;
+                    protected Value isMatch(byte typeTag) {
+                        return (typeTag == ATypeTag.SERIALIZED_NULL_TYPE_TAG
+                                || typeTag == ATypeTag.SERIALIZED_MISSING_TYPE_TAG) ? Value.TRUE : Value.FALSE;
                     }
                 };
             }

http://git-wip-us.apache.org/repos/asf/asterixdb/blob/c8c067c5/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/SwitchCaseDescriptor.java
----------------------------------------------------------------------
diff --git a/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/SwitchCaseDescriptor.java b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/SwitchCaseDescriptor.java
index df0b973..9e14bff 100644
--- a/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/SwitchCaseDescriptor.java
+++ b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/SwitchCaseDescriptor.java
@@ -93,13 +93,14 @@ public class SwitchCaseDescriptor extends AbstractScalarFunctionDynamicDescripto
                     }
 
                     private boolean equals(IPointable out1, IPointable out2) {
-                        if (out1.getStartOffset() != out2.getStartOffset() || out1.getLength() != out2.getLength()) {
+                        if (out1.getLength() != out2.getLength()) {
                             return false;
                         }
                         byte[] data1 = out1.getByteArray();
                         byte[] data2 = out2.getByteArray();
-                        for (int i = out1.getStartOffset(); i < out1.getLength(); i++) {
-                            if (data1[i] != data2[i]) {
+                        for (int i = out1.getStartOffset(), j = out2.getStartOffset(), k = 0; k < out1
+                                .getLength(); ++i, ++j, ++k) {
+                            if (data1[i] != data2[j]) {
                                 return false;
                             }
                         }

http://git-wip-us.apache.org/repos/asf/asterixdb/blob/c8c067c5/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/formats/NonTaggedDataFormat.java
----------------------------------------------------------------------
diff --git a/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/formats/NonTaggedDataFormat.java b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/formats/NonTaggedDataFormat.java
index 64735ff..8737360 100644
--- a/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/formats/NonTaggedDataFormat.java
+++ b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/formats/NonTaggedDataFormat.java
@@ -60,15 +60,12 @@ import org.apache.asterix.om.types.ARecordType;
 import org.apache.asterix.om.types.ATypeTag;
 import org.apache.asterix.om.types.AUnionType;
 import org.apache.asterix.om.types.AUnorderedListType;
-import org.apache.asterix.om.types.AbstractCollectionType;
 import org.apache.asterix.om.types.IAType;
 import org.apache.asterix.runtime.aggregates.collections.ListifyAggregateDescriptor;
 import org.apache.asterix.runtime.evaluators.common.CreateMBREvalFactory;
 import org.apache.asterix.runtime.evaluators.common.FunctionManagerImpl;
 import org.apache.asterix.runtime.evaluators.constructors.ClosedRecordConstructorDescriptor;
 import org.apache.asterix.runtime.evaluators.constructors.OpenRecordConstructorDescriptor;
-import org.apache.asterix.runtime.evaluators.functions.CastListDescriptor;
-import org.apache.asterix.runtime.evaluators.functions.CastRecordDescriptor;
 import org.apache.asterix.runtime.evaluators.functions.OrderedListConstructorDescriptor;
 import org.apache.asterix.runtime.evaluators.functions.UnorderedListConstructorDescriptor;
 import org.apache.asterix.runtime.evaluators.functions.records.FieldAccessByIndexEvalFactory;
@@ -210,8 +207,8 @@ public class NonTaggedDataFormat implements IDataFormat {
                     } catch (HyracksDataException e) {
                         throw new AlgebricksException(e);
                     }
-                    IScalarEvaluatorFactory fldIndexEvalFactory = new ConstantEvalFactory(
-                            Arrays.copyOf(abvs.getByteArray(), abvs.getLength()));
+                    IScalarEvaluatorFactory fldIndexEvalFactory =
+                            new ConstantEvalFactory(Arrays.copyOf(abvs.getByteArray(), abvs.getLength()));
 
                     evalFactory = new FieldAccessByIndexEvalFactory(recordEvalFactory, fldIndexEvalFactory, recType);
                     return evalFactory;
@@ -256,8 +253,8 @@ public class NonTaggedDataFormat implements IDataFormat {
             int dimension, List<String> filterFieldName) throws AlgebricksException {
         IScalarEvaluatorFactory evalFactory = getFieldAccessEvaluatorFactory(recType, fldName, recordColumn);
         int numOfFields = dimension * 2;
-        IScalarEvaluatorFactory[] evalFactories = new IScalarEvaluatorFactory[numOfFields
-                + (filterFieldName == null ? 0 : 1)];
+        IScalarEvaluatorFactory[] evalFactories =
+                new IScalarEvaluatorFactory[numOfFields + (filterFieldName == null ? 0 : 1)];
 
         ArrayBackedValueStorage abvs1 = new ArrayBackedValueStorage();
         DataOutput dos1 = abvs1.getDataOutput();
@@ -267,8 +264,8 @@ public class NonTaggedDataFormat implements IDataFormat {
         } catch (HyracksDataException e) {
             throw new AlgebricksException(e);
         }
-        IScalarEvaluatorFactory dimensionEvalFactory = new ConstantEvalFactory(
-                Arrays.copyOf(abvs1.getByteArray(), abvs1.getLength()));
+        IScalarEvaluatorFactory dimensionEvalFactory =
+                new ConstantEvalFactory(Arrays.copyOf(abvs1.getByteArray(), abvs1.getLength()));
 
         for (int i = 0; i < numOfFields; i++) {
             ArrayBackedValueStorage abvs2 = new ArrayBackedValueStorage();
@@ -279,8 +276,8 @@ public class NonTaggedDataFormat implements IDataFormat {
             } catch (HyracksDataException e) {
                 throw new AlgebricksException(e);
             }
-            IScalarEvaluatorFactory coordinateEvalFactory = new ConstantEvalFactory(
-                    Arrays.copyOf(abvs2.getByteArray(), abvs2.getLength()));
+            IScalarEvaluatorFactory coordinateEvalFactory =
+                    new ConstantEvalFactory(Arrays.copyOf(abvs2.getByteArray(), abvs2.getLength()));
 
             evalFactories[i] = new CreateMBREvalFactory(evalFactory, dimensionEvalFactory, coordinateEvalFactory);
         }
@@ -299,8 +296,8 @@ public class NonTaggedDataFormat implements IDataFormat {
         if (fldName.size() > 1) {
             for (int i = 0; i < n; i++) {
                 if (names[i].equals(fldName.get(0))) {
-                    IScalarEvaluatorFactory recordEvalFactory = new ColumnAccessEvalFactory(
-                            GlobalConfig.DEFAULT_INPUT_DATA_COLUMN);
+                    IScalarEvaluatorFactory recordEvalFactory =
+                            new ColumnAccessEvalFactory(GlobalConfig.DEFAULT_INPUT_DATA_COLUMN);
                     ArrayBackedValueStorage abvs = new ArrayBackedValueStorage();
                     DataOutput dos = abvs.getDataOutput();
                     try {
@@ -310,10 +307,10 @@ public class NonTaggedDataFormat implements IDataFormat {
                     } catch (HyracksDataException e) {
                         throw new AlgebricksException(e);
                     }
-                    IScalarEvaluatorFactory fldIndexEvalFactory = new ConstantEvalFactory(
-                            Arrays.copyOf(abvs.getByteArray(), abvs.getLength()));
-                    IScalarEvaluatorFactory evalFactory = new FieldAccessByIndexEvalFactory(recordEvalFactory,
-                            fldIndexEvalFactory, recType);
+                    IScalarEvaluatorFactory fldIndexEvalFactory =
+                            new ConstantEvalFactory(Arrays.copyOf(abvs.getByteArray(), abvs.getLength()));
+                    IScalarEvaluatorFactory evalFactory =
+                            new FieldAccessByIndexEvalFactory(recordEvalFactory, fldIndexEvalFactory, recType);
                     IFunctionInfo finfoAccess = AsterixBuiltinFunctions
                             .getAsterixFunctionInfo(AsterixBuiltinFunctions.FIELD_ACCESS_BY_INDEX);
 
@@ -326,8 +323,8 @@ public class NonTaggedDataFormat implements IDataFormat {
                 }
             }
         } else {
-            IScalarEvaluatorFactory recordEvalFactory = new ColumnAccessEvalFactory(
-                    GlobalConfig.DEFAULT_INPUT_DATA_COLUMN);
+            IScalarEvaluatorFactory recordEvalFactory =
+                    new ColumnAccessEvalFactory(GlobalConfig.DEFAULT_INPUT_DATA_COLUMN);
             ArrayBackedValueStorage abvs = new ArrayBackedValueStorage();
             DataOutput dos = abvs.getDataOutput();
             AOrderedList as = new AOrderedList(fldName);
@@ -337,8 +334,8 @@ public class NonTaggedDataFormat implements IDataFormat {
                 throw new AlgebricksException(e);
             }
             IScalarEvaluatorFactory evalFactory = new FieldAccessNestedEvalFactory(recordEvalFactory, recType, fldName);
-            IFunctionInfo finfoAccess = AsterixBuiltinFunctions
-                    .getAsterixFunctionInfo(AsterixBuiltinFunctions.FIELD_ACCESS_NESTED);
+            IFunctionInfo finfoAccess =
+                    AsterixBuiltinFunctions.getAsterixFunctionInfo(AsterixBuiltinFunctions.FIELD_ACCESS_NESTED);
 
             ScalarFunctionCallExpression partitionFun = new ScalarFunctionCallExpression(finfoAccess,
                     new MutableObject<ILogicalExpression>(new VariableReferenceExpression(METADATA_DUMMY_VAR)),
@@ -445,31 +442,15 @@ public class NonTaggedDataFormat implements IDataFormat {
                         + " org.apache.asterix.om.types.IAType)", outType, type0, type1);
             }
         });
-
-        functionTypeInferers.put(AsterixBuiltinFunctions.CAST_RECORD, new FunctionTypeInferer() {
-            @Override
-            public void infer(ILogicalExpression expr, IFunctionDescriptor fd, IVariableTypeEnvironment context)
-                    throws AlgebricksException {
-                AbstractFunctionCallExpression funcExpr = (AbstractFunctionCallExpression) expr;
-                ARecordType rt = (ARecordType) TypeCastUtils.getRequiredType(funcExpr);
-                IAType it = (IAType) context.getType(funcExpr.getArguments().get(0).getValue());
-                if (it.getTypeTag().equals(ATypeTag.ANY)) {
-                    it = DefaultOpenFieldType.NESTED_OPEN_RECORD_TYPE;
-                }
-                ((CastRecordDescriptor) fd).reset(rt, (ARecordType) it);
-            }
-        });
-        functionTypeInferers.put(AsterixBuiltinFunctions.CAST_LIST, new FunctionTypeInferer() {
+        functionTypeInferers.put(AsterixBuiltinFunctions.CAST_TYPE, new FunctionTypeInferer() {
             @Override
             public void infer(ILogicalExpression expr, IFunctionDescriptor fd, IVariableTypeEnvironment context)
                     throws AlgebricksException {
                 AbstractFunctionCallExpression funcExpr = (AbstractFunctionCallExpression) expr;
-                AbstractCollectionType rt = (AbstractCollectionType) TypeCastUtils.getRequiredType(funcExpr);
+                IAType rt = TypeCastUtils.getRequiredType(funcExpr);
                 IAType it = (IAType) context.getType(funcExpr.getArguments().get(0).getValue());
-                if (it.getTypeTag().equals(ATypeTag.ANY)) {
-                    it = DefaultOpenFieldType.NESTED_OPEN_AORDERED_LIST_TYPE;
-                }
-                ((CastListDescriptor) fd).reset(rt, (AbstractCollectionType) it);
+                PA.invokeMethod(fd, "reset(org.apache.asterix.om.types.IAType, org.apache.asterix.om.types.IAType)", rt,
+                        it);
             }
         });
         functionTypeInferers.put(AsterixBuiltinFunctions.OPEN_RECORD_CONSTRUCTOR, new FunctionTypeInferer() {
@@ -488,8 +469,9 @@ public class NonTaggedDataFormat implements IDataFormat {
                     Mutable<ILogicalExpression> argRef = expr.getArguments().get(2 * i);
                     ILogicalExpression arg = argRef.getValue();
                     if (arg.getExpressionTag() == LogicalExpressionTag.CONSTANT) {
-                        String fn = ((AString) ((AsterixConstantValue) ((ConstantExpression) arg).getValue())
-                                .getObject()).getStringValue();
+                        String fn =
+                                ((AString) ((AsterixConstantValue) ((ConstantExpression) arg).getValue()).getObject())
+                                        .getStringValue();
                         open[i] = true;
                         for (String s : recType.getFieldNames()) {
                             if (s.equals(fn)) {


Mime
View raw message