You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@asterixdb.apache.org by bu...@apache.org on 2016/05/24 01:31:37 UTC

[19/22] incubator-asterixdb git commit: ASTERIXDB-1228: Add MISSING into the data model.

http://git-wip-us.apache.org/repos/asf/incubator-asterixdb/blob/535d86b5/asterixdb/asterix-external-data/src/test/java/org/apache/asterix/external/library/ClassAdParser.java
----------------------------------------------------------------------
diff --git a/asterixdb/asterix-external-data/src/test/java/org/apache/asterix/external/library/ClassAdParser.java b/asterixdb/asterix-external-data/src/test/java/org/apache/asterix/external/library/ClassAdParser.java
index 3c22241..923163f 100644
--- a/asterixdb/asterix-external-data/src/test/java/org/apache/asterix/external/library/ClassAdParser.java
+++ b/asterixdb/asterix-external-data/src/test/java/org/apache/asterix/external/library/ClassAdParser.java
@@ -339,11 +339,11 @@ public class ClassAdParser extends AbstractDataParser implements IRecordDataPars
             // add field value to value buffer
             writeFieldValueToBuffer(fieldType, fieldValueBuffer.getDataOutput(), fldName, entry.getValue(), pAd);
             if (openRecordField) {
-                if (fieldValueBuffer.getByteArray()[0] != ATypeTag.NULL.serialize()) {
+                if (fieldValueBuffer.getByteArray()[0] != ATypeTag.MISSING.serialize()) {
                     recBuilder.addField(fieldNameBuffer, fieldValueBuffer);
                 }
             } else if (NonTaggedFormatUtil.isOptional(fieldType)) {
-                if (fieldValueBuffer.getByteArray()[0] != ATypeTag.NULL.serialize()) {
+                if (fieldValueBuffer.getByteArray()[0] != ATypeTag.MISSING.serialize()) {
                     recBuilder.addField(fieldId, fieldValueBuffer);
                 }
             } else {
@@ -387,7 +387,7 @@ public class ClassAdParser extends AbstractDataParser implements IRecordDataPars
 
         if (fieldType != null) {
             if (NonTaggedFormatUtil.isOptional(fieldType)) {
-                fieldType = ((AUnionType) fieldType).getNullableType();
+                fieldType = ((AUnionType) fieldType).getActualType();
             }
         }
         switch (val.getValueType()) {
@@ -622,23 +622,16 @@ public class ClassAdParser extends AbstractDataParser implements IRecordDataPars
     }
 
     public static int checkNullConstraints(ARecordType recType, BitSet nulls) {
-        boolean isNull = false;
         for (int i = 0; i < recType.getFieldTypes().length; i++) {
             if (nulls.get(i) == false) {
                 IAType type = recType.getFieldTypes()[i];
-                if (type.getTypeTag() != ATypeTag.NULL && type.getTypeTag() != ATypeTag.UNION) {
+                if (type.getTypeTag() != ATypeTag.MISSING && type.getTypeTag() != ATypeTag.UNION) {
                     return i;
                 }
 
                 if (type.getTypeTag() == ATypeTag.UNION) { // union
-                    List<IAType> unionList = ((AUnionType) type).getUnionList();
-                    for (int j = 0; j < unionList.size(); j++) {
-                        if (unionList.get(j).getTypeTag() == ATypeTag.NULL) {
-                            isNull = true;
-                            break;
-                        }
-                    }
-                    if (!isNull) {
+                    AUnionType unionType = (AUnionType) type;
+                    if (!unionType.isNullableType()) {
                         return i;
                     }
                 }
@@ -685,7 +678,7 @@ public class ClassAdParser extends AbstractDataParser implements IRecordDataPars
             case SLIST_VALUE:
                 return ATypeTag.UNORDEREDLIST;
             case NULL_VALUE:
-                return ATypeTag.NULL;
+                return ATypeTag.MISSING;
             case REAL_VALUE:
                 return ATypeTag.DOUBLE;
             case RELATIVE_TIME_VALUE:

http://git-wip-us.apache.org/repos/asf/incubator-asterixdb/blob/535d86b5/asterixdb/asterix-lang-aql/src/main/javacc/AQL.jj
----------------------------------------------------------------------
diff --git a/asterixdb/asterix-lang-aql/src/main/javacc/AQL.jj b/asterixdb/asterix-lang-aql/src/main/javacc/AQL.jj
index 8205021..63b066e 100644
--- a/asterixdb/asterix-lang-aql/src/main/javacc/AQL.jj
+++ b/asterixdb/asterix-lang-aql/src/main/javacc/AQL.jj
@@ -88,6 +88,7 @@ import org.apache.asterix.lang.common.literal.DoubleLiteral;
 import org.apache.asterix.lang.common.literal.FalseLiteral;
 import org.apache.asterix.lang.common.literal.FloatLiteral;
 import org.apache.asterix.lang.common.literal.LongIntegerLiteral;
+import org.apache.asterix.lang.common.literal.MissingLiteral;
 import org.apache.asterix.lang.common.literal.NullLiteral;
 import org.apache.asterix.lang.common.literal.StringLiteral;
 import org.apache.asterix.lang.common.literal.TrueLiteral;
@@ -1907,6 +1908,10 @@ Expression Literal() throws ParseException:
     {
       lit.setValue(new DoubleLiteral(new Double(token.image)));
     }
+  | <MISSING>
+    {
+      lit.setValue(MissingLiteral.INSTANCE);
+    }
   | <NULL>
     {
       lit.setValue(NullLiteral.INSTANCE);
@@ -2609,7 +2614,8 @@ TOKEN :
 <DEFAULT,IN_DBL_BRACE>
 TOKEN :
 {
-    <NULL : "null">
+  < MISSING : "missing">
+  | <NULL : "null">
   | <TRUE : "true">
   | <FALSE : "false">
 }

http://git-wip-us.apache.org/repos/asf/incubator-asterixdb/blob/535d86b5/asterixdb/asterix-lang-common/src/main/java/org/apache/asterix/lang/common/base/Literal.java
----------------------------------------------------------------------
diff --git a/asterixdb/asterix-lang-common/src/main/java/org/apache/asterix/lang/common/base/Literal.java b/asterixdb/asterix-lang-common/src/main/java/org/apache/asterix/lang/common/base/Literal.java
index 34e1363..1ca8ac4 100644
--- a/asterixdb/asterix-lang-common/src/main/java/org/apache/asterix/lang/common/base/Literal.java
+++ b/asterixdb/asterix-lang-common/src/main/java/org/apache/asterix/lang/common/base/Literal.java
@@ -29,6 +29,7 @@ public abstract class Literal implements Serializable {
     public enum Type {
         STRING,
         INTEGER,
+        MISSING,
         NULL,
         TRUE,
         FALSE,

http://git-wip-us.apache.org/repos/asf/incubator-asterixdb/blob/535d86b5/asterixdb/asterix-lang-common/src/main/java/org/apache/asterix/lang/common/literal/MissingLiteral.java
----------------------------------------------------------------------
diff --git a/asterixdb/asterix-lang-common/src/main/java/org/apache/asterix/lang/common/literal/MissingLiteral.java b/asterixdb/asterix-lang-common/src/main/java/org/apache/asterix/lang/common/literal/MissingLiteral.java
new file mode 100644
index 0000000..2c2fa8e
--- /dev/null
+++ b/asterixdb/asterix-lang-common/src/main/java/org/apache/asterix/lang/common/literal/MissingLiteral.java
@@ -0,0 +1,55 @@
+/*
+ * 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.lang.common.literal;
+
+import org.apache.asterix.lang.common.base.Literal;
+
+public class MissingLiteral extends Literal {
+    private static final long serialVersionUID = 1L;
+
+    private MissingLiteral() {
+    }
+
+    public final static MissingLiteral INSTANCE = new MissingLiteral();
+
+    @Override
+    public Type getLiteralType() {
+        return Type.MISSING;
+    }
+
+    @Override
+    public String getStringValue() {
+        return "missing";
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        return obj == INSTANCE;
+    }
+
+    @Override
+    public int hashCode() {
+        return (int) serialVersionUID;
+    }
+
+    @Override
+    public Object getValue() {
+        return null;
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-asterixdb/blob/535d86b5/asterixdb/asterix-lang-common/src/main/java/org/apache/asterix/lang/common/visitor/FormatPrintVisitor.java
----------------------------------------------------------------------
diff --git a/asterixdb/asterix-lang-common/src/main/java/org/apache/asterix/lang/common/visitor/FormatPrintVisitor.java b/asterixdb/asterix-lang-common/src/main/java/org/apache/asterix/lang/common/visitor/FormatPrintVisitor.java
index a1e6363..b332df3 100644
--- a/asterixdb/asterix-lang-common/src/main/java/org/apache/asterix/lang/common/visitor/FormatPrintVisitor.java
+++ b/asterixdb/asterix-lang-common/src/main/java/org/apache/asterix/lang/common/visitor/FormatPrintVisitor.java
@@ -27,9 +27,9 @@ import java.util.List;
 import java.util.Map;
 import java.util.Set;
 
-import org.apache.asterix.common.config.MetadataConstants;
 import org.apache.asterix.common.config.DatasetConfig.DatasetType;
 import org.apache.asterix.common.config.DatasetConfig.IndexType;
+import org.apache.asterix.common.config.MetadataConstants;
 import org.apache.asterix.common.exceptions.AsterixException;
 import org.apache.asterix.common.functions.FunctionSignature;
 import org.apache.asterix.lang.common.base.Expression;
@@ -158,7 +158,7 @@ public class FormatPrintVisitor implements ILangVisitor<Void, Integer> {
     public Void visit(LiteralExpr l, Integer step) {
         Literal lc = l.getValue();
         if (lc.getLiteralType().equals(Literal.Type.TRUE) || lc.getLiteralType().equals(Literal.Type.FALSE)
-                || lc.getLiteralType().equals(Literal.Type.NULL)) {
+                || lc.getLiteralType().equals(Literal.Type.NULL) || lc.getLiteralType().equals(Literal.Type.MISSING)) {
             out.print(lc.getLiteralType().toString().toLowerCase());
         } else if (lc.getLiteralType().equals(Literal.Type.STRING)) {
             out.print(revertStringToLiteral(lc.getStringValue()));
@@ -455,7 +455,8 @@ public class FormatPrintVisitor implements ILangVisitor<Void, Integer> {
         if (dd.getDatasetType() == DatasetType.INTERNAL) {
             String temp = dd.getDatasetDetailsDecl().isTemp() ? "temporary" : "";
             out.print(skip(step) + "create " + temp + datasetSymbol + generateFullName(dd.getDataverse(), dd.getName())
-                    + generateIfNotExists(dd.getIfNotExists()) + "(" + dd.getQualifiedTypeName() + ")" + " primary key ");
+                    + generateIfNotExists(dd.getIfNotExists()) + "(" + dd.getQualifiedTypeName() + ")"
+                    + " primary key ");
             printDelimitedKeys(((InternalDetailsDecl) dd.getDatasetDetailsDecl()).getPartitioningExprs(), ",");
             if (((InternalDetailsDecl) dd.getDatasetDetailsDecl()).isAutogenerated()) {
                 out.print(" autogenerated ");

http://git-wip-us.apache.org/repos/asf/incubator-asterixdb/blob/535d86b5/asterixdb/asterix-lang-common/src/main/java/org/apache/asterix/lang/common/visitor/QueryPrintVisitor.java
----------------------------------------------------------------------
diff --git a/asterixdb/asterix-lang-common/src/main/java/org/apache/asterix/lang/common/visitor/QueryPrintVisitor.java b/asterixdb/asterix-lang-common/src/main/java/org/apache/asterix/lang/common/visitor/QueryPrintVisitor.java
index c635403..ceb45bb 100644
--- a/asterixdb/asterix-lang-common/src/main/java/org/apache/asterix/lang/common/visitor/QueryPrintVisitor.java
+++ b/asterixdb/asterix-lang-common/src/main/java/org/apache/asterix/lang/common/visitor/QueryPrintVisitor.java
@@ -98,7 +98,7 @@ public class QueryPrintVisitor extends AbstractQueryExpressionVisitor<Void, Inte
     public Void visit(LiteralExpr l, Integer step) {
         Literal lc = l.getValue();
         if (lc.getLiteralType().equals(Literal.Type.TRUE) || lc.getLiteralType().equals(Literal.Type.FALSE)
-                || lc.getLiteralType().equals(Literal.Type.NULL)) {
+                || lc.getLiteralType().equals(Literal.Type.NULL) || lc.getLiteralType().equals(Literal.Type.MISSING)) {
             out.println(skip(step) + "LiteralExpr [" + l.getValue().getLiteralType() + "]");
         } else {
             out.println(skip(step) + "LiteralExpr [" + l.getValue().getLiteralType() + "] ["

http://git-wip-us.apache.org/repos/asf/incubator-asterixdb/blob/535d86b5/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 3c81cff..c26edc1 100644
--- a/asterixdb/asterix-lang-sqlpp/src/main/javacc/SQLPP.jj
+++ b/asterixdb/asterix-lang-sqlpp/src/main/javacc/SQLPP.jj
@@ -83,6 +83,7 @@ import org.apache.asterix.lang.common.literal.DoubleLiteral;
 import org.apache.asterix.lang.common.literal.FalseLiteral;
 import org.apache.asterix.lang.common.literal.FloatLiteral;
 import org.apache.asterix.lang.common.literal.LongIntegerLiteral;
+import org.apache.asterix.lang.common.literal.MissingLiteral;
 import org.apache.asterix.lang.common.literal.NullLiteral;
 import org.apache.asterix.lang.common.literal.StringLiteral;
 import org.apache.asterix.lang.common.literal.TrueLiteral;
@@ -1896,6 +1897,10 @@ Expression Literal() throws ParseException:
     {
       lit.setValue(new DoubleLiteral(new Double(token.image)));
     }
+  | <MISSING>
+    {
+      lit.setValue(MissingLiteral.INSTANCE);
+    }
   | <NULL>
     {
       lit.setValue(NullLiteral.INSTANCE);
@@ -2854,7 +2859,8 @@ TOKEN :
 <DEFAULT,IN_DBL_BRACE>
 TOKEN :
 {
-    <NULL : "null">
+  <MISSING : "missing">
+  |  <NULL : "null">
   | <TRUE : "true">
   | <FALSE : "false">
 }

http://git-wip-us.apache.org/repos/asf/incubator-asterixdb/blob/535d86b5/asterixdb/asterix-maven-plugins/asterix-evaluator-generator-maven-plugin/src/main/java/org/apache/asterix/runtime/evaluators/plugin/EvaluatorGeneratorMojo.java
----------------------------------------------------------------------
diff --git a/asterixdb/asterix-maven-plugins/asterix-evaluator-generator-maven-plugin/src/main/java/org/apache/asterix/runtime/evaluators/plugin/EvaluatorGeneratorMojo.java b/asterixdb/asterix-maven-plugins/asterix-evaluator-generator-maven-plugin/src/main/java/org/apache/asterix/runtime/evaluators/plugin/EvaluatorGeneratorMojo.java
index d001bb0..888df55 100644
--- a/asterixdb/asterix-maven-plugins/asterix-evaluator-generator-maven-plugin/src/main/java/org/apache/asterix/runtime/evaluators/plugin/EvaluatorGeneratorMojo.java
+++ b/asterixdb/asterix-maven-plugins/asterix-evaluator-generator-maven-plugin/src/main/java/org/apache/asterix/runtime/evaluators/plugin/EvaluatorGeneratorMojo.java
@@ -90,4 +90,5 @@ public class EvaluatorGeneratorMojo extends AbstractMojo {
             outputStream.write(classDefinitionBinary, 0, classDefinitionBinary.length);
         }
     }
+
 }

http://git-wip-us.apache.org/repos/asf/incubator-asterixdb/blob/535d86b5/asterixdb/asterix-metadata/src/main/java/org/apache/asterix/metadata/bootstrap/MetadataRecordTypes.java
----------------------------------------------------------------------
diff --git a/asterixdb/asterix-metadata/src/main/java/org/apache/asterix/metadata/bootstrap/MetadataRecordTypes.java b/asterixdb/asterix-metadata/src/main/java/org/apache/asterix/metadata/bootstrap/MetadataRecordTypes.java
index 55a5f3d..620461b 100644
--- a/asterixdb/asterix-metadata/src/main/java/org/apache/asterix/metadata/bootstrap/MetadataRecordTypes.java
+++ b/asterixdb/asterix-metadata/src/main/java/org/apache/asterix/metadata/bootstrap/MetadataRecordTypes.java
@@ -227,7 +227,7 @@ public final class MetadataRecordTypes {
                 "DatasourceAdapter", "Properties", "Function", "Status", "CompactionPolicy",
                 "CompactionPolicyProperties" };
 
-        AUnionType feedFunctionUnion = AUnionType.createNullableType(BuiltinType.ASTRING);
+        IAType feedFunctionUnion = AUnionType.createNullableType(BuiltinType.ASTRING);
 
         IAType[] fieldTypes = { BuiltinType.ASTRING, BuiltinType.ASTRING, orderedListType, orderedListType,
                 BuiltinType.ASTRING, BuiltinType.ASTRING, orderedListOfPropertiesType, feedFunctionUnion,
@@ -257,8 +257,8 @@ public final class MetadataRecordTypes {
                 "GroupName", "CompactionPolicy", "CompactionPolicyProperties", "InternalDetails", "ExternalDetails",
                 "Hints", "Timestamp", "DatasetId", "PendingOp" };
 
-        AUnionType internalRecordUnion = AUnionType.createNullableType(INTERNAL_DETAILS_RECORDTYPE);
-        AUnionType externalRecordUnion = AUnionType.createNullableType(EXTERNAL_DETAILS_RECORDTYPE);
+        IAType internalRecordUnion = AUnionType.createNullableType(INTERNAL_DETAILS_RECORDTYPE);
+        IAType externalRecordUnion = AUnionType.createNullableType(EXTERNAL_DETAILS_RECORDTYPE);
         AOrderedListType compactionPolicyPropertyListType = new AOrderedListType(
                 COMPACTION_POLICY_PROPERTIES_RECORDTYPE, null);
 
@@ -305,8 +305,8 @@ public final class MetadataRecordTypes {
 
     private static final ARecordType createDerivedTypeRecordType() throws AsterixException {
         String[] fieldNames = { "Tag", "IsAnonymous", "Record", "UnorderedList", "OrderedList" };
-        AUnionType recordUnion = AUnionType.createNullableType(RECORD_RECORDTYPE);
-        AUnionType collectionUnion = AUnionType.createNullableType(BuiltinType.ASTRING);
+        IAType recordUnion = AUnionType.createNullableType(RECORD_RECORDTYPE);
+        IAType collectionUnion = AUnionType.createNullableType(BuiltinType.ASTRING);
 
         IAType[] fieldTypes = { BuiltinType.ASTRING, BuiltinType.ABOOLEAN, recordUnion, collectionUnion,
                 collectionUnion };
@@ -322,7 +322,7 @@ public final class MetadataRecordTypes {
 
     private static final ARecordType createDatatypeRecordType() throws AsterixException {
         String[] fieldNames = { "DataverseName", "DatatypeName", "Derived", "Timestamp" };
-        AUnionType recordUnion = AUnionType.createNullableType(DERIVEDTYPE_RECORDTYPE);
+        IAType recordUnion = AUnionType.createNullableType(DERIVEDTYPE_RECORDTYPE);
         IAType[] fieldTypes = { BuiltinType.ASTRING, BuiltinType.ASTRING, recordUnion, BuiltinType.ASTRING };
         return new ARecordType("DatatypeRecordType", fieldNames, fieldTypes, true);
     };
@@ -435,9 +435,9 @@ public final class MetadataRecordTypes {
 
     private static ARecordType createFeedRecordType() throws AsterixException, HyracksDataException {
 
-        AUnionType feedFunctionUnion = AUnionType.createNullableType(BuiltinType.ASTRING);
-        AUnionType primaryRecordUnion = AUnionType.createNullableType(PRIMARY_FEED_DETAILS_RECORDTYPE);
-        AUnionType secondaryRecordUnion = AUnionType.createNullableType(SECONDARY_FEED_DETAILS_RECORDTYPE);
+        IAType feedFunctionUnion = AUnionType.createNullableType(BuiltinType.ASTRING);
+        IAType primaryRecordUnion = AUnionType.createNullableType(PRIMARY_FEED_DETAILS_RECORDTYPE);
+        IAType secondaryRecordUnion = AUnionType.createNullableType(SECONDARY_FEED_DETAILS_RECORDTYPE);
 
         String[] fieldNames = { "DataverseName", "FeedName", "Function", "FeedType", "PrimaryTypeDetails",
                 "SecondaryTypeDetails", "Timestamp" };

http://git-wip-us.apache.org/repos/asf/incubator-asterixdb/blob/535d86b5/asterixdb/asterix-metadata/src/main/java/org/apache/asterix/metadata/entities/AsterixBuiltinTypeMap.java
----------------------------------------------------------------------
diff --git a/asterixdb/asterix-metadata/src/main/java/org/apache/asterix/metadata/entities/AsterixBuiltinTypeMap.java b/asterixdb/asterix-metadata/src/main/java/org/apache/asterix/metadata/entities/AsterixBuiltinTypeMap.java
index 7bb212c..8cd3d05 100644
--- a/asterixdb/asterix-metadata/src/main/java/org/apache/asterix/metadata/entities/AsterixBuiltinTypeMap.java
+++ b/asterixdb/asterix-metadata/src/main/java/org/apache/asterix/metadata/entities/AsterixBuiltinTypeMap.java
@@ -60,6 +60,7 @@ public class AsterixBuiltinTypeMap {
         _builtinTypeMap.put("polygon", BuiltinType.APOLYGON);
         _builtinTypeMap.put("circle", BuiltinType.ACIRCLE);
         _builtinTypeMap.put("rectangle", BuiltinType.ARECTANGLE);
+        _builtinTypeMap.put("missing", BuiltinType.AMISSING);
         _builtinTypeMap.put("null", BuiltinType.ANULL);
         _builtinTypeMap.put("uuid", BuiltinType.AUUID);
         _builtinTypeMap.put("shortwithouttypeinfo", BuiltinType.SHORTWITHOUTTYPEINFO);
@@ -80,8 +81,9 @@ public class AsterixBuiltinTypeMap {
                 throw new MetadataException(e);
             }
         }
-        if (isNullable)
+        if (isNullable) {
             type = AUnionType.createNullableType(type);
+        }
         return type;
     }
 }

http://git-wip-us.apache.org/repos/asf/incubator-asterixdb/blob/535d86b5/asterixdb/asterix-metadata/src/main/java/org/apache/asterix/metadata/entities/Index.java
----------------------------------------------------------------------
diff --git a/asterixdb/asterix-metadata/src/main/java/org/apache/asterix/metadata/entities/Index.java b/asterixdb/asterix-metadata/src/main/java/org/apache/asterix/metadata/entities/Index.java
index 3ff9a57..949e6ca 100644
--- a/asterixdb/asterix-metadata/src/main/java/org/apache/asterix/metadata/entities/Index.java
+++ b/asterixdb/asterix-metadata/src/main/java/org/apache/asterix/metadata/entities/Index.java
@@ -131,11 +131,12 @@ public class Index implements IMetadataEntity<Index>, Comparable<Index> {
 
     public static Pair<IAType, Boolean> getNonNullableType(IAType keyType) throws AsterixException {
         boolean nullable = false;
+        IAType actualKeyType = keyType;
         if (NonTaggedFormatUtil.isOptional(keyType)) {
-            keyType = ((AUnionType) keyType).getNullableType();
+            actualKeyType = ((AUnionType) keyType).getActualType();
             nullable = true;
         }
-        return new Pair<IAType, Boolean>(keyType, nullable);
+        return new Pair<>(actualKeyType, nullable);
     }
 
     public static Pair<IAType, Boolean> getNonNullableOpenFieldType(IAType fieldType, List<String> fieldName,

http://git-wip-us.apache.org/repos/asf/incubator-asterixdb/blob/535d86b5/asterixdb/asterix-metadata/src/main/java/org/apache/asterix/metadata/entitytupletranslators/DatatypeTupleTranslator.java
----------------------------------------------------------------------
diff --git a/asterixdb/asterix-metadata/src/main/java/org/apache/asterix/metadata/entitytupletranslators/DatatypeTupleTranslator.java b/asterixdb/asterix-metadata/src/main/java/org/apache/asterix/metadata/entitytupletranslators/DatatypeTupleTranslator.java
index a1b23d6..0604fff 100644
--- a/asterixdb/asterix-metadata/src/main/java/org/apache/asterix/metadata/entitytupletranslators/DatatypeTupleTranslator.java
+++ b/asterixdb/asterix-metadata/src/main/java/org/apache/asterix/metadata/entitytupletranslators/DatatypeTupleTranslator.java
@@ -201,7 +201,7 @@ public class DatatypeTupleTranslator extends AbstractTupleTranslator<Datatype> {
         IAType fieldType = dataType.getDatatype();
         //unwrap nullable type out of the union
         if (fieldType.getTypeTag() == ATypeTag.UNION) {
-            fieldType = ((AUnionType) dataType.getDatatype()).getNullableType();
+            fieldType = ((AUnionType) dataType.getDatatype()).getActualType();
         }
 
         // write field 3
@@ -310,11 +310,12 @@ public class DatatypeTupleTranslator extends AbstractTupleTranslator<Datatype> {
             boolean fieldIsNullable = false;
             if (NonTaggedFormatUtil.isOptional(fieldType)) {
                 fieldIsNullable = true;
-                fieldType = ((AUnionType) fieldType).getNullableType();
+                fieldType = ((AUnionType) fieldType).getActualType();
             }
-            if (fieldType.getTypeTag().isDerivedType())
+            if (fieldType.getTypeTag().isDerivedType()) {
                 handleNestedDerivedType(fieldType.getTypeName(), (AbstractComplexType) fieldType, instance,
                         instance.getDataverseName(), instance.getDatatypeName());
+            }
 
             itemValue.reset();
             fieldRecordBuilder.reset(MetadataRecordTypes.FIELD_RECORDTYPE);

http://git-wip-us.apache.org/repos/asf/incubator-asterixdb/blob/535d86b5/asterixdb/asterix-om/src/main/java/org/apache/asterix/builders/AbstractListBuilder.java
----------------------------------------------------------------------
diff --git a/asterixdb/asterix-om/src/main/java/org/apache/asterix/builders/AbstractListBuilder.java b/asterixdb/asterix-om/src/main/java/org/apache/asterix/builders/AbstractListBuilder.java
index 59e669a..a2b16dd 100644
--- a/asterixdb/asterix-om/src/main/java/org/apache/asterix/builders/AbstractListBuilder.java
+++ b/asterixdb/asterix-om/src/main/java/org/apache/asterix/builders/AbstractListBuilder.java
@@ -71,23 +71,35 @@ public abstract class AbstractListBuilder implements IAsterixListBuilder {
         }
         headerSize = 2;
         metadataInfoSize = 8;
-        // 8 = 4 (# of items) + 4 (the size of the list)
+        if (itemTypeTag == ATypeTag.MISSING) {
+            itemTypeTag = ATypeTag.NULL;
+        }
     }
 
     @Override
     public void addItem(IValueReference item) throws HyracksDataException {
         try {
-            if (!fixedSize && (item.getByteArray()[item.getStartOffset()] != ATypeTag.SERIALIZED_NULL_TYPE_TAG
-                    || itemTypeTag == ATypeTag.ANY)) {
+            byte[] data = item.getByteArray();
+            int start = item.getStartOffset();
+            int len = item.getLength();
+
+            byte serializedTypeTag = data[start];
+            if (serializedTypeTag == ATypeTag.SERIALIZED_MISSING_TYPE_TAG) {
+                // NULL in a list is MISSING.
+                serializedTypeTag = ATypeTag.SERIALIZED_NULL_TYPE_TAG;
+            }
+
+            if (!fixedSize && (serializedTypeTag != ATypeTag.SERIALIZED_NULL_TYPE_TAG || itemTypeTag == ATypeTag.ANY)) {
                 this.offsets.add(outputStorage.getLength());
             }
-            if (itemTypeTag == ATypeTag.ANY || (itemTypeTag == ATypeTag.NULL
-                    && item.getByteArray()[item.getStartOffset()] == ATypeTag.SERIALIZED_NULL_TYPE_TAG)) {
+            if (itemTypeTag == ATypeTag.ANY
+                    || (itemTypeTag == ATypeTag.NULL && serializedTypeTag == ATypeTag.SERIALIZED_NULL_TYPE_TAG)) {
                 this.numberOfItems++;
-                this.outputStream.write(item.getByteArray(), item.getStartOffset(), item.getLength());
-            } else if (item.getByteArray()[item.getStartOffset()] != ATypeTag.SERIALIZED_NULL_TYPE_TAG) {
+                this.outputStream.write(serializedTypeTag);
+                this.outputStream.write(data, start + 1, len - 1);
+            } else if (serializedTypeTag != ATypeTag.SERIALIZED_NULL_TYPE_TAG) {
                 this.numberOfItems++;
-                this.outputStream.write(item.getByteArray(), item.getStartOffset() + 1, item.getLength() - 1);
+                this.outputStream.write(data, start + 1, len - 1);
             }
         } catch (IOException e) {
             throw new HyracksDataException(e);

http://git-wip-us.apache.org/repos/asf/incubator-asterixdb/blob/535d86b5/asterixdb/asterix-om/src/main/java/org/apache/asterix/builders/RecordBuilder.java
----------------------------------------------------------------------
diff --git a/asterixdb/asterix-om/src/main/java/org/apache/asterix/builders/RecordBuilder.java b/asterixdb/asterix-om/src/main/java/org/apache/asterix/builders/RecordBuilder.java
index 65caf40..bfe08da 100644
--- a/asterixdb/asterix-om/src/main/java/org/apache/asterix/builders/RecordBuilder.java
+++ b/asterixdb/asterix-om/src/main/java/org/apache/asterix/builders/RecordBuilder.java
@@ -131,22 +131,25 @@ public class RecordBuilder implements IARecordBuilder {
         headerSize = 5;
         // this is the record tag (1) + record size (4)
 
-        if (isOpen)
+        if (isOpen) {
             // to tell whether the record has an open part or not.
             headerSize += 1;
+        }
 
         if (numberOfSchemaFields > 0) {
             // there is a schema associated with the record.
 
             headerSize += 4;
             // 4 = four bytes to store the number of closed fields.
-            if (closedPartOffsets == null || closedPartOffsets.length < numberOfSchemaFields)
+            if (closedPartOffsets == null || closedPartOffsets.length < numberOfSchemaFields) {
                 closedPartOffsets = new int[numberOfSchemaFields];
+            }
 
             if (isNullable) {
                 nullBitMapSize = (int) Math.ceil(numberOfSchemaFields / 8.0);
-                if (nullBitMap == null || nullBitMap.length < nullBitMapSize)
+                if (nullBitMap == null || nullBitMap.length < nullBitMapSize) {
                     this.nullBitMap = new byte[nullBitMapSize];
+                }
                 Arrays.fill(nullBitMap, 0, nullBitMapSize, (byte) 0);
                 headerSize += nullBitMap.length;
             }
@@ -183,11 +186,10 @@ public class RecordBuilder implements IARecordBuilder {
                     openFieldNameLengths.length + DEFAULT_NUM_OPEN_FIELDS);
         }
         int fieldNameHashCode = utf8HashFunction.hash(name.getByteArray(), name.getStartOffset() + 1,
-                    name.getLength() - 1);
+                name.getLength() - 1);
         if (recType != null) {
             int cFieldPos;
-                cFieldPos = recTypeInfo.getFieldIndex(name.getByteArray(), name.getStartOffset() + 1,
-                        name.getLength() - 1);
+            cFieldPos = recTypeInfo.getFieldIndex(name.getByteArray(), name.getStartOffset() + 1, name.getLength() - 1);
             if (cFieldPos >= 0) {
                 throw new HyracksDataException("Open field \"" + recType.getFieldNames()[cFieldPos]
                         + "\" has the same field name as closed field at index " + cFieldPos);
@@ -210,8 +212,9 @@ public class RecordBuilder implements IARecordBuilder {
             h += 4;
             // 4 = four bytes to store the offset to the open part.
             openPartOffsetArraySize = numberOfOpenFields * 8;
-            if (openPartOffsetArray == null || openPartOffsetArray.length < openPartOffsetArraySize)
+            if (openPartOffsetArray == null || openPartOffsetArray.length < openPartOffsetArraySize) {
                 openPartOffsetArray = new byte[openPartOffsetArraySize];
+            }
 
             Arrays.sort(this.openPartOffsets, 0, numberOfOpenFields);
             if (numberOfOpenFields > 1) {
@@ -256,17 +259,20 @@ public class RecordBuilder implements IARecordBuilder {
                 if (this.numberOfOpenFields > 0) {
                     out.writeBoolean(true);
                     out.writeInt(openPartOffset);
-                } else
+                } else {
                     out.writeBoolean(false);
+                }
             }
 
             // write the closed part
             if (numberOfSchemaFields > 0) {
                 out.writeInt(numberOfClosedFields);
-                if (isNullable)
+                if (isNullable) {
                     out.write(nullBitMap, 0, nullBitMapSize);
-                for (int i = 0; i < numberOfSchemaFields; i++)
+                }
+                for (int i = 0; i < numberOfSchemaFields; i++) {
                     out.writeInt(closedPartOffsets[i] + headerSize + (numberOfSchemaFields * 4));
+                }
                 out.write(closedPartOutputStream.toByteArray());
             }
 
@@ -284,8 +290,9 @@ public class RecordBuilder implements IARecordBuilder {
     @Override
     public int getFieldId(String fieldName) {
         for (int i = 0; i < recType.getFieldNames().length; i++) {
-            if (recType.getFieldNames()[i].equals(fieldName))
+            if (recType.getFieldNames()[i].equals(fieldName)) {
                 return i;
+            }
         }
         return -1;
     }

http://git-wip-us.apache.org/repos/asf/incubator-asterixdb/blob/535d86b5/asterixdb/asterix-om/src/main/java/org/apache/asterix/dataflow/data/common/AqlExpressionTypeComputer.java
----------------------------------------------------------------------
diff --git a/asterixdb/asterix-om/src/main/java/org/apache/asterix/dataflow/data/common/AqlExpressionTypeComputer.java b/asterixdb/asterix-om/src/main/java/org/apache/asterix/dataflow/data/common/AqlExpressionTypeComputer.java
index 66008f4..4cd3015 100644
--- a/asterixdb/asterix-om/src/main/java/org/apache/asterix/dataflow/data/common/AqlExpressionTypeComputer.java
+++ b/asterixdb/asterix-om/src/main/java/org/apache/asterix/dataflow/data/common/AqlExpressionTypeComputer.java
@@ -70,7 +70,7 @@ public class AqlExpressionTypeComputer implements IExpressionTypeComputer {
         FunctionIdentifier fi = expr.getFunctionIdentifier();
         ComparisonKind ck = AlgebricksBuiltinFunctions.getComparisonType(fi);
         if (ck != null) {
-            return AUnionType.createNullableType(BuiltinType.ABOOLEAN, "OptionalBoolean");
+            return AUnionType.createUnknownableType(BuiltinType.ABOOLEAN, "OptionalBoolean");
         }
         // Note: built-in functions + udfs
         IResultTypeComputer rtc = null;
@@ -90,6 +90,8 @@ public class AqlExpressionTypeComputer implements IExpressionTypeComputer {
         IAlgebricksConstantValue acv = expr.getValue();
         if (acv.isFalse() || acv.isTrue()) {
             return BuiltinType.ABOOLEAN;
+        } else if (acv.isMissing()) {
+            return BuiltinType.AMISSING;
         } else if (acv.isNull()) {
             return BuiltinType.ANULL;
         } else {

http://git-wip-us.apache.org/repos/asf/incubator-asterixdb/blob/535d86b5/asterixdb/asterix-om/src/main/java/org/apache/asterix/dataflow/data/common/AqlMissableTypeComputer.java
----------------------------------------------------------------------
diff --git a/asterixdb/asterix-om/src/main/java/org/apache/asterix/dataflow/data/common/AqlMissableTypeComputer.java b/asterixdb/asterix-om/src/main/java/org/apache/asterix/dataflow/data/common/AqlMissableTypeComputer.java
new file mode 100644
index 0000000..aa88ec9
--- /dev/null
+++ b/asterixdb/asterix-om/src/main/java/org/apache/asterix/dataflow/data/common/AqlMissableTypeComputer.java
@@ -0,0 +1,52 @@
+/*
+ * 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.dataflow.data.common;
+
+import org.apache.asterix.om.typecomputer.impl.TypeComputeUtils;
+import org.apache.asterix.om.types.AUnionType;
+import org.apache.asterix.om.types.IAType;
+import org.apache.asterix.om.types.TypeHelper;
+import org.apache.hyracks.algebricks.common.exceptions.AlgebricksException;
+import org.apache.hyracks.algebricks.core.algebra.expressions.IMissableTypeComputer;
+
+public class AqlMissableTypeComputer implements IMissableTypeComputer {
+
+    public static final AqlMissableTypeComputer INSTANCE = new AqlMissableTypeComputer();
+
+    private AqlMissableTypeComputer() {
+    }
+
+    @Override
+    public IAType makeMissableType(Object type) throws AlgebricksException {
+        IAType t = (IAType) type;
+        return AUnionType.createMissableType(t);
+    }
+
+    @Override
+    public boolean canBeMissing(Object type) {
+        IAType t = (IAType) type;
+        return TypeHelper.canBeMissing(t);
+    }
+
+    @Override
+    public Object getNonOptionalType(Object type) {
+        IAType t = (IAType) type;
+        return TypeComputeUtils.getActualType(t);
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-asterixdb/blob/535d86b5/asterixdb/asterix-om/src/main/java/org/apache/asterix/dataflow/data/common/AqlNullableTypeComputer.java
----------------------------------------------------------------------
diff --git a/asterixdb/asterix-om/src/main/java/org/apache/asterix/dataflow/data/common/AqlNullableTypeComputer.java b/asterixdb/asterix-om/src/main/java/org/apache/asterix/dataflow/data/common/AqlNullableTypeComputer.java
deleted file mode 100644
index ab5119b..0000000
--- a/asterixdb/asterix-om/src/main/java/org/apache/asterix/dataflow/data/common/AqlNullableTypeComputer.java
+++ /dev/null
@@ -1,55 +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.dataflow.data.common;
-
-import org.apache.asterix.om.types.AUnionType;
-import org.apache.asterix.om.types.IAType;
-import org.apache.asterix.om.types.TypeHelper;
-import org.apache.hyracks.algebricks.common.exceptions.AlgebricksException;
-import org.apache.hyracks.algebricks.core.algebra.expressions.INullableTypeComputer;
-
-public class AqlNullableTypeComputer implements INullableTypeComputer {
-
-    public static final AqlNullableTypeComputer INSTANCE = new AqlNullableTypeComputer();
-
-    private AqlNullableTypeComputer() {
-    }
-
-    @Override
-    public IAType makeNullableType(Object type) throws AlgebricksException {
-        IAType t = (IAType) type;
-        if (TypeHelper.canBeNull(t)) {
-            return t;
-        } else {
-            return AUnionType.createNullableType(t);
-        }
-    }
-
-    @Override
-    public boolean canBeNull(Object type) {
-        IAType t = (IAType) type;
-        return TypeHelper.canBeNull(t);
-    }
-
-    @Override
-    public Object getNonOptionalType(Object type) {
-        IAType t = (IAType) type;
-        return TypeHelper.getNonOptionalType(t);
-    }
-}

http://git-wip-us.apache.org/repos/asf/incubator-asterixdb/blob/535d86b5/asterixdb/asterix-om/src/main/java/org/apache/asterix/dataflow/data/common/AqlPartialAggregationTypeComputer.java
----------------------------------------------------------------------
diff --git a/asterixdb/asterix-om/src/main/java/org/apache/asterix/dataflow/data/common/AqlPartialAggregationTypeComputer.java b/asterixdb/asterix-om/src/main/java/org/apache/asterix/dataflow/data/common/AqlPartialAggregationTypeComputer.java
index 3913588..fe5a3e0 100644
--- a/asterixdb/asterix-om/src/main/java/org/apache/asterix/dataflow/data/common/AqlPartialAggregationTypeComputer.java
+++ b/asterixdb/asterix-om/src/main/java/org/apache/asterix/dataflow/data/common/AqlPartialAggregationTypeComputer.java
@@ -19,16 +19,12 @@
 package org.apache.asterix.dataflow.data.common;
 
 import org.apache.asterix.om.functions.AsterixBuiltinFunctions;
-import org.apache.asterix.om.types.AUnionType;
-import org.apache.asterix.om.types.BuiltinType;
 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.AbstractFunctionCallExpression;
 import org.apache.hyracks.algebricks.core.algebra.expressions.AggregateFunctionCallExpression;
 import org.apache.hyracks.algebricks.core.algebra.expressions.IPartialAggregationTypeComputer;
 import org.apache.hyracks.algebricks.core.algebra.expressions.IVariableTypeEnvironment;
-import org.apache.hyracks.algebricks.core.algebra.functions.AlgebricksBuiltinFunctions;
-import org.apache.hyracks.algebricks.core.algebra.functions.AlgebricksBuiltinFunctions.ComparisonKind;
 import org.apache.hyracks.algebricks.core.algebra.functions.FunctionIdentifier;
 import org.apache.hyracks.algebricks.core.algebra.metadata.IMetadataProvider;
 
@@ -42,18 +38,14 @@ public class AqlPartialAggregationTypeComputer implements IPartialAggregationTyp
         if (partialFid.equals(AsterixBuiltinFunctions.SERIAL_GLOBAL_AVG)) {
             partialFid = AsterixBuiltinFunctions.SERIAL_LOCAL_AVG;
         }
-        AggregateFunctionCallExpression partialAgg = AsterixBuiltinFunctions.makeAggregateFunctionExpression(
-                partialFid, agg.getArguments());
-        return getTypeForFunction((AbstractFunctionCallExpression) partialAgg, env, metadataProvider);
+        AggregateFunctionCallExpression partialAgg = AsterixBuiltinFunctions.makeAggregateFunctionExpression(partialFid,
+                agg.getArguments());
+        return getTypeForFunction(partialAgg, env, metadataProvider);
     }
 
     private Object getTypeForFunction(AbstractFunctionCallExpression expr, IVariableTypeEnvironment env,
             IMetadataProvider<?, ?> metadataProvider) throws AlgebricksException {
-        FunctionIdentifier fi = expr.getFunctionIdentifier();
-        ComparisonKind ck = AlgebricksBuiltinFunctions.getComparisonType(fi);
-        if (ck != null) {
-            return AUnionType.createNullableType(BuiltinType.ABOOLEAN, "OptionalBoolean");
-        }
-        return AsterixBuiltinFunctions.getResultTypeComputer(fi).computeType(expr, env, metadataProvider);
+        return AsterixBuiltinFunctions.getResultTypeComputer(expr.getFunctionIdentifier()).computeType(expr, env,
+                metadataProvider);
     }
 }

http://git-wip-us.apache.org/repos/asf/incubator-asterixdb/blob/535d86b5/asterixdb/asterix-om/src/main/java/org/apache/asterix/dataflow/data/nontagged/AqlMissingWriterFactory.java
----------------------------------------------------------------------
diff --git a/asterixdb/asterix-om/src/main/java/org/apache/asterix/dataflow/data/nontagged/AqlMissingWriterFactory.java b/asterixdb/asterix-om/src/main/java/org/apache/asterix/dataflow/data/nontagged/AqlMissingWriterFactory.java
new file mode 100644
index 0000000..313f821
--- /dev/null
+++ b/asterixdb/asterix-om/src/main/java/org/apache/asterix/dataflow/data/nontagged/AqlMissingWriterFactory.java
@@ -0,0 +1,50 @@
+/*
+ * 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.dataflow.data.nontagged;
+
+import java.io.DataOutput;
+import java.io.IOException;
+
+import org.apache.asterix.om.types.ATypeTag;
+import org.apache.hyracks.api.dataflow.value.IMissingWriter;
+import org.apache.hyracks.api.dataflow.value.IMissingWriterFactory;
+import org.apache.hyracks.api.exceptions.HyracksDataException;
+
+public class AqlMissingWriterFactory implements IMissingWriterFactory {
+
+    private static final long serialVersionUID = 1L;
+    public static final AqlMissingWriterFactory INSTANCE = new AqlMissingWriterFactory();
+
+    private AqlMissingWriterFactory() {
+    }
+
+    @Override
+    public IMissingWriter createMissingWriter() {
+        return out -> writeMissing(out);
+    }
+
+    private static void writeMissing(DataOutput out) throws HyracksDataException {
+        try {
+            out.writeByte(ATypeTag.SERIALIZED_MISSING_TYPE_TAG);
+        } catch (IOException e) {
+            throw new HyracksDataException(e);
+        }
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-asterixdb/blob/535d86b5/asterixdb/asterix-om/src/main/java/org/apache/asterix/dataflow/data/nontagged/AqlNullWriterFactory.java
----------------------------------------------------------------------
diff --git a/asterixdb/asterix-om/src/main/java/org/apache/asterix/dataflow/data/nontagged/AqlNullWriterFactory.java b/asterixdb/asterix-om/src/main/java/org/apache/asterix/dataflow/data/nontagged/AqlNullWriterFactory.java
deleted file mode 100644
index 8fa881a..0000000
--- a/asterixdb/asterix-om/src/main/java/org/apache/asterix/dataflow/data/nontagged/AqlNullWriterFactory.java
+++ /dev/null
@@ -1,53 +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.dataflow.data.nontagged;
-
-import java.io.DataOutput;
-import java.io.IOException;
-
-import org.apache.asterix.om.types.ATypeTag;
-import org.apache.hyracks.api.dataflow.value.INullWriter;
-import org.apache.hyracks.api.dataflow.value.INullWriterFactory;
-import org.apache.hyracks.api.exceptions.HyracksDataException;
-
-public class AqlNullWriterFactory implements INullWriterFactory {
-
-    private static final long serialVersionUID = 1L;
-    public static final AqlNullWriterFactory INSTANCE = new AqlNullWriterFactory();
-
-    private AqlNullWriterFactory() {
-    }
-
-    @Override
-    public INullWriter createNullWriter() {
-
-        return new INullWriter() {
-
-            @Override
-            public void writeNull(DataOutput out) throws HyracksDataException {
-                try {
-                    out.writeByte(ATypeTag.SERIALIZED_NULL_TYPE_TAG);
-                } catch (IOException e) {
-                    throw new HyracksDataException(e);
-                }
-            }
-        };
-    }
-
-}

http://git-wip-us.apache.org/repos/asf/incubator-asterixdb/blob/535d86b5/asterixdb/asterix-om/src/main/java/org/apache/asterix/dataflow/data/nontagged/comparators/ABinaryComparator.java
----------------------------------------------------------------------
diff --git a/asterixdb/asterix-om/src/main/java/org/apache/asterix/dataflow/data/nontagged/comparators/ABinaryComparator.java b/asterixdb/asterix-om/src/main/java/org/apache/asterix/dataflow/data/nontagged/comparators/ABinaryComparator.java
index 05ffb3a..6afc9d8 100644
--- a/asterixdb/asterix-om/src/main/java/org/apache/asterix/dataflow/data/nontagged/comparators/ABinaryComparator.java
+++ b/asterixdb/asterix-om/src/main/java/org/apache/asterix/dataflow/data/nontagged/comparators/ABinaryComparator.java
@@ -18,10 +18,6 @@
  */
 package org.apache.asterix.dataflow.data.nontagged.comparators;
 
-import org.apache.asterix.om.types.ATypeTag;
-import org.apache.asterix.om.types.EnumDeserializer;
-import org.apache.asterix.om.types.hierachy.ATypeHierarchy;
-import org.apache.hyracks.api.dataflow.value.BinaryComparatorConstant.ComparableResultCode;
 import org.apache.hyracks.api.dataflow.value.IBinaryComparator;
 import org.apache.hyracks.api.exceptions.HyracksDataException;
 
@@ -30,26 +26,6 @@ import org.apache.hyracks.api.exceptions.HyracksDataException;
  */
 public abstract class ABinaryComparator implements IBinaryComparator {
 
-    public static ComparableResultCode isComparable(byte tag1,byte tag2) {
-        // NULL Check. If one type is NULL, then we return NULL
-        if (tag1 == ATypeTag.SERIALIZED_NULL_TYPE_TAG || tag2 == ATypeTag.SERIALIZED_NULL_TYPE_TAG || tag1 == 0
-                || tag2 == 0) {
-            return ComparableResultCode.UNKNOWN;
-        }
-
-        // Checks whether two types are comparable or not
-        ATypeTag typeTag1 = EnumDeserializer.ATYPETAGDESERIALIZER.deserialize(tag1);
-        ATypeTag typeTag2 = EnumDeserializer.ATYPETAGDESERIALIZER.deserialize(tag2);
-
-        // Are two types compatible, meaning that they can be compared? (e.g., compare between numeric types
-        if (ATypeHierarchy.isCompatible(typeTag1, typeTag2)) {
-            return ComparableResultCode.TRUE;
-        } else {
-            return ComparableResultCode.FALSE;
-        }
-
-    }
-
     @Override
     public abstract int compare(byte[] b1, int s1, int l1, byte[] b2, int s2, int l2) throws HyracksDataException;
 

http://git-wip-us.apache.org/repos/asf/incubator-asterixdb/blob/535d86b5/asterixdb/asterix-om/src/main/java/org/apache/asterix/dataflow/data/nontagged/comparators/AObjectAscBinaryComparatorFactory.java
----------------------------------------------------------------------
diff --git a/asterixdb/asterix-om/src/main/java/org/apache/asterix/dataflow/data/nontagged/comparators/AObjectAscBinaryComparatorFactory.java b/asterixdb/asterix-om/src/main/java/org/apache/asterix/dataflow/data/nontagged/comparators/AObjectAscBinaryComparatorFactory.java
index 4ce9617..e7a6b77 100644
--- a/asterixdb/asterix-om/src/main/java/org/apache/asterix/dataflow/data/nontagged/comparators/AObjectAscBinaryComparatorFactory.java
+++ b/asterixdb/asterix-om/src/main/java/org/apache/asterix/dataflow/data/nontagged/comparators/AObjectAscBinaryComparatorFactory.java
@@ -110,17 +110,26 @@ public class AObjectAscBinaryComparatorFactory implements IBinaryComparatorFacto
             @Override
             public int compare(byte[] b1, int s1, int l1, byte[] b2, int s2, int l2) throws HyracksDataException {
 
-                // Normally, comparing between NULL and non-NULL values should return UNKNOWN as the result.
-                // However, at this point, we assume that NULL check between two types is already done.
+                // Normally, comparing between MISSING and non-MISSING values should return MISSING as the result.
+                // However, this comparator is used by order-by/group-by/distinct-by.
+                // Therefore, inside this method, we return an order between two values even if one value is MISSING.
+                if (b1[s1] == ATypeTag.SERIALIZED_MISSING_TYPE_TAG) {
+                    return b2[s2] == ATypeTag.SERIALIZED_MISSING_TYPE_TAG ? 0 : -1;
+                } else {
+                    if (b2[s2] == ATypeTag.SERIALIZED_MISSING_TYPE_TAG) {
+                        return 1;
+                    }
+                }
+
+                // Normally, comparing between NULL and non-NULL/MISSING values should return NULL as the result.
+                // However, this comparator is used by order-by/group-by/distinct-by.
                 // Therefore, inside this method, we return an order between two values even if one value is NULL.
                 if (b1[s1] == ATypeTag.SERIALIZED_NULL_TYPE_TAG) {
-                    if (b2[s2] == ATypeTag.SERIALIZED_NULL_TYPE_TAG)
-                        return 0;
-                    else
-                        return -1;
+                    return b2[s2] == ATypeTag.SERIALIZED_NULL_TYPE_TAG ? 0 : -1;
                 } else {
-                    if (b2[s2] == ATypeTag.SERIALIZED_NULL_TYPE_TAG)
+                    if (b2[s2] == ATypeTag.SERIALIZED_NULL_TYPE_TAG) {
                         return 1;
+                    }
                 }
 
                 ATypeTag tag1 = EnumDeserializer.ATYPETAGDESERIALIZER.deserialize(b1[s1]);

http://git-wip-us.apache.org/repos/asf/incubator-asterixdb/blob/535d86b5/asterixdb/asterix-om/src/main/java/org/apache/asterix/dataflow/data/nontagged/comparators/ListItemBinaryComparatorFactory.java
----------------------------------------------------------------------
diff --git a/asterixdb/asterix-om/src/main/java/org/apache/asterix/dataflow/data/nontagged/comparators/ListItemBinaryComparatorFactory.java b/asterixdb/asterix-om/src/main/java/org/apache/asterix/dataflow/data/nontagged/comparators/ListItemBinaryComparatorFactory.java
index 8907bca..c4a82ee 100644
--- a/asterixdb/asterix-om/src/main/java/org/apache/asterix/dataflow/data/nontagged/comparators/ListItemBinaryComparatorFactory.java
+++ b/asterixdb/asterix-om/src/main/java/org/apache/asterix/dataflow/data/nontagged/comparators/ListItemBinaryComparatorFactory.java
@@ -43,7 +43,7 @@ public class ListItemBinaryComparatorFactory implements IBinaryComparatorFactory
 
     @Override
     public IBinaryComparator createBinaryComparator() {
-        return createBinaryComparator(ATypeTag.NULL, ATypeTag.NULL, false);
+        return createBinaryComparator(ATypeTag.MISSING, ATypeTag.MISSING, false);
     }
 
     public IBinaryComparator createBinaryComparator(final ATypeTag firstItemTypeTag, final ATypeTag secondItemTypeTag,
@@ -83,15 +83,17 @@ public class ListItemBinaryComparatorFactory implements IBinaryComparatorFactory
 
             @Override
             public int compare(byte[] b1, int s1, int l1, byte[] b2, int s2, int l2) throws HyracksDataException {
-
+                //  A list item cannot be MISSING.
                 if (b1[s1] == ATypeTag.SERIALIZED_NULL_TYPE_TAG) {
-                    if (b2[s2] == ATypeTag.SERIALIZED_NULL_TYPE_TAG)
+                    if (b2[s2] == ATypeTag.SERIALIZED_NULL_TYPE_TAG) {
                         return 0;
-                    else
+                    } else {
                         return -1;
+                    }
                 } else {
-                    if (b2[s2] == ATypeTag.SERIALIZED_NULL_TYPE_TAG)
+                    if (b2[s2] == ATypeTag.SERIALIZED_NULL_TYPE_TAG) {
                         return 1;
+                    }
                 }
 
                 ATypeTag tag1 = firstItemTypeTag;

http://git-wip-us.apache.org/repos/asf/incubator-asterixdb/blob/535d86b5/asterixdb/asterix-om/src/main/java/org/apache/asterix/dataflow/data/nontagged/printers/adm/ANullableFieldPrinterFactory.java
----------------------------------------------------------------------
diff --git a/asterixdb/asterix-om/src/main/java/org/apache/asterix/dataflow/data/nontagged/printers/adm/ANullableFieldPrinterFactory.java b/asterixdb/asterix-om/src/main/java/org/apache/asterix/dataflow/data/nontagged/printers/adm/ANullableFieldPrinterFactory.java
index f063d82..010e968 100644
--- a/asterixdb/asterix-om/src/main/java/org/apache/asterix/dataflow/data/nontagged/printers/adm/ANullableFieldPrinterFactory.java
+++ b/asterixdb/asterix-om/src/main/java/org/apache/asterix/dataflow/data/nontagged/printers/adm/ANullableFieldPrinterFactory.java
@@ -48,14 +48,14 @@ public class ANullableFieldPrinterFactory implements IPrinterFactory {
             public void init() throws HyracksDataException {
                 nullPrinter = (AqlADMPrinterFactoryProvider.INSTANCE.getPrinterFactory(BuiltinType.ANULL))
                         .createPrinter();
-                fieldPrinter = (AqlADMPrinterFactoryProvider.INSTANCE.getPrinterFactory(unionType.getNullableType()))
+                fieldPrinter = (AqlADMPrinterFactoryProvider.INSTANCE.getPrinterFactory(unionType.getActualType()))
                         .createPrinter();
             }
 
             @Override
             public void print(byte[] b, int s, int l, PrintStream ps) throws HyracksDataException {
                 fieldPrinter.init();
-                if (b[s] == ATypeTag.NULL.serialize()) {
+                if (b[s] == ATypeTag.SERIALIZED_NULL_TYPE_TAG) {
                     nullPrinter.print(b, s, l, ps);
                 } else {
                     fieldPrinter.print(b, s, l, ps);

http://git-wip-us.apache.org/repos/asf/incubator-asterixdb/blob/535d86b5/asterixdb/asterix-om/src/main/java/org/apache/asterix/dataflow/data/nontagged/printers/adm/AObjectPrinter.java
----------------------------------------------------------------------
diff --git a/asterixdb/asterix-om/src/main/java/org/apache/asterix/dataflow/data/nontagged/printers/adm/AObjectPrinter.java b/asterixdb/asterix-om/src/main/java/org/apache/asterix/dataflow/data/nontagged/printers/adm/AObjectPrinter.java
index 6527032..27aa754 100644
--- a/asterixdb/asterix-om/src/main/java/org/apache/asterix/dataflow/data/nontagged/printers/adm/AObjectPrinter.java
+++ b/asterixdb/asterix-om/src/main/java/org/apache/asterix/dataflow/data/nontagged/printers/adm/AObjectPrinter.java
@@ -58,6 +58,7 @@ public class AObjectPrinter implements IPrinter {
                 AInt64Printer.INSTANCE.print(b, s, l, ps);
                 break;
             }
+            case MISSING:
             case NULL: {
                 ANullPrinter.INSTANCE.print(b, s, l, ps);
                 break;

http://git-wip-us.apache.org/repos/asf/incubator-asterixdb/blob/535d86b5/asterixdb/asterix-om/src/main/java/org/apache/asterix/dataflow/data/nontagged/printers/csv/ANullableFieldPrinterFactory.java
----------------------------------------------------------------------
diff --git a/asterixdb/asterix-om/src/main/java/org/apache/asterix/dataflow/data/nontagged/printers/csv/ANullableFieldPrinterFactory.java b/asterixdb/asterix-om/src/main/java/org/apache/asterix/dataflow/data/nontagged/printers/csv/ANullableFieldPrinterFactory.java
index 3d76087..f920080 100644
--- a/asterixdb/asterix-om/src/main/java/org/apache/asterix/dataflow/data/nontagged/printers/csv/ANullableFieldPrinterFactory.java
+++ b/asterixdb/asterix-om/src/main/java/org/apache/asterix/dataflow/data/nontagged/printers/csv/ANullableFieldPrinterFactory.java
@@ -46,16 +46,16 @@ public class ANullableFieldPrinterFactory implements IPrinterFactory {
 
             @Override
             public void init() throws HyracksDataException {
-                nullPrinter = (AqlCSVPrinterFactoryProvider.INSTANCE.getPrinterFactory(BuiltinType.ANULL))
+                nullPrinter = (AqlCSVPrinterFactoryProvider.INSTANCE.getPrinterFactory(BuiltinType.AMISSING))
                         .createPrinter();
-                fieldPrinter = (AqlCSVPrinterFactoryProvider.INSTANCE.getPrinterFactory(unionType.getNullableType()))
+                fieldPrinter = (AqlCSVPrinterFactoryProvider.INSTANCE.getPrinterFactory(unionType.getActualType()))
                         .createPrinter();
             }
 
             @Override
             public void print(byte[] b, int s, int l, PrintStream ps) throws HyracksDataException {
                 fieldPrinter.init();
-                if (b[s] == ATypeTag.NULL.serialize()) {
+                if (b[s] == ATypeTag.MISSING.serialize()) {
                     nullPrinter.print(b, s, l, ps);
                 } else {
                     fieldPrinter.print(b, s, l, ps);

http://git-wip-us.apache.org/repos/asf/incubator-asterixdb/blob/535d86b5/asterixdb/asterix-om/src/main/java/org/apache/asterix/dataflow/data/nontagged/printers/csv/AObjectPrinter.java
----------------------------------------------------------------------
diff --git a/asterixdb/asterix-om/src/main/java/org/apache/asterix/dataflow/data/nontagged/printers/csv/AObjectPrinter.java b/asterixdb/asterix-om/src/main/java/org/apache/asterix/dataflow/data/nontagged/printers/csv/AObjectPrinter.java
index 6587d52..09cd5ac 100644
--- a/asterixdb/asterix-om/src/main/java/org/apache/asterix/dataflow/data/nontagged/printers/csv/AObjectPrinter.java
+++ b/asterixdb/asterix-om/src/main/java/org/apache/asterix/dataflow/data/nontagged/printers/csv/AObjectPrinter.java
@@ -56,6 +56,7 @@ public class AObjectPrinter implements IPrinter {
                 AInt64Printer.INSTANCE.print(b, s, l, ps);
                 break;
             }
+            case MISSING:
             case NULL: {
                 ANullPrinter.INSTANCE.print(b, s, l, ps);
                 break;

http://git-wip-us.apache.org/repos/asf/incubator-asterixdb/blob/535d86b5/asterixdb/asterix-om/src/main/java/org/apache/asterix/dataflow/data/nontagged/printers/json/clean/ANullableFieldPrinterFactory.java
----------------------------------------------------------------------
diff --git a/asterixdb/asterix-om/src/main/java/org/apache/asterix/dataflow/data/nontagged/printers/json/clean/ANullableFieldPrinterFactory.java b/asterixdb/asterix-om/src/main/java/org/apache/asterix/dataflow/data/nontagged/printers/json/clean/ANullableFieldPrinterFactory.java
index b1319c8..24c8903 100644
--- a/asterixdb/asterix-om/src/main/java/org/apache/asterix/dataflow/data/nontagged/printers/json/clean/ANullableFieldPrinterFactory.java
+++ b/asterixdb/asterix-om/src/main/java/org/apache/asterix/dataflow/data/nontagged/printers/json/clean/ANullableFieldPrinterFactory.java
@@ -46,16 +46,16 @@ public class ANullableFieldPrinterFactory implements IPrinterFactory {
 
             @Override
             public void init() throws HyracksDataException {
-                nullPrinter = (AqlCleanJSONPrinterFactoryProvider.INSTANCE.getPrinterFactory(BuiltinType.ANULL))
+                nullPrinter = (AqlCleanJSONPrinterFactoryProvider.INSTANCE.getPrinterFactory(BuiltinType.AMISSING))
                         .createPrinter();
                 fieldPrinter = (AqlCleanJSONPrinterFactoryProvider.INSTANCE
-                        .getPrinterFactory(unionType.getNullableType())).createPrinter();
+                        .getPrinterFactory(unionType.getActualType())).createPrinter();
             }
 
             @Override
             public void print(byte[] b, int s, int l, PrintStream ps) throws HyracksDataException {
                 fieldPrinter.init();
-                if (b[s] == ATypeTag.NULL.serialize()) {
+                if (b[s] == ATypeTag.MISSING.serialize()) {
                     nullPrinter.print(b, s, l, ps);
                 } else {
                     fieldPrinter.print(b, s, l, ps);

http://git-wip-us.apache.org/repos/asf/incubator-asterixdb/blob/535d86b5/asterixdb/asterix-om/src/main/java/org/apache/asterix/dataflow/data/nontagged/printers/json/clean/AObjectPrinter.java
----------------------------------------------------------------------
diff --git a/asterixdb/asterix-om/src/main/java/org/apache/asterix/dataflow/data/nontagged/printers/json/clean/AObjectPrinter.java b/asterixdb/asterix-om/src/main/java/org/apache/asterix/dataflow/data/nontagged/printers/json/clean/AObjectPrinter.java
index d4183f6..ee94187 100644
--- a/asterixdb/asterix-om/src/main/java/org/apache/asterix/dataflow/data/nontagged/printers/json/clean/AObjectPrinter.java
+++ b/asterixdb/asterix-om/src/main/java/org/apache/asterix/dataflow/data/nontagged/printers/json/clean/AObjectPrinter.java
@@ -58,6 +58,7 @@ public class AObjectPrinter implements IPrinter {
                 AInt64Printer.INSTANCE.print(b, s, l, ps);
                 break;
             }
+            case MISSING:
             case NULL: {
                 ANullPrinter.INSTANCE.print(b, s, l, ps);
                 break;

http://git-wip-us.apache.org/repos/asf/incubator-asterixdb/blob/535d86b5/asterixdb/asterix-om/src/main/java/org/apache/asterix/dataflow/data/nontagged/printers/json/lossless/ANullableFieldPrinterFactory.java
----------------------------------------------------------------------
diff --git a/asterixdb/asterix-om/src/main/java/org/apache/asterix/dataflow/data/nontagged/printers/json/lossless/ANullableFieldPrinterFactory.java b/asterixdb/asterix-om/src/main/java/org/apache/asterix/dataflow/data/nontagged/printers/json/lossless/ANullableFieldPrinterFactory.java
index 1d495b1..a4f4200 100644
--- a/asterixdb/asterix-om/src/main/java/org/apache/asterix/dataflow/data/nontagged/printers/json/lossless/ANullableFieldPrinterFactory.java
+++ b/asterixdb/asterix-om/src/main/java/org/apache/asterix/dataflow/data/nontagged/printers/json/lossless/ANullableFieldPrinterFactory.java
@@ -46,16 +46,16 @@ public class ANullableFieldPrinterFactory implements IPrinterFactory {
 
             @Override
             public void init() throws HyracksDataException {
-                nullPrinter = (AqlLosslessJSONPrinterFactoryProvider.INSTANCE.getPrinterFactory(BuiltinType.ANULL))
+                nullPrinter = (AqlLosslessJSONPrinterFactoryProvider.INSTANCE.getPrinterFactory(BuiltinType.AMISSING))
                         .createPrinter();
                 fieldPrinter = (AqlLosslessJSONPrinterFactoryProvider.INSTANCE
-                        .getPrinterFactory(unionType.getNullableType())).createPrinter();
+                        .getPrinterFactory(unionType.getActualType())).createPrinter();
             }
 
             @Override
             public void print(byte[] b, int s, int l, PrintStream ps) throws HyracksDataException {
                 fieldPrinter.init();
-                if (b[s] == ATypeTag.NULL.serialize()) {
+                if (b[s] == ATypeTag.MISSING.serialize()) {
                     nullPrinter.print(b, s, l, ps);
                 } else {
                     fieldPrinter.print(b, s, l, ps);

http://git-wip-us.apache.org/repos/asf/incubator-asterixdb/blob/535d86b5/asterixdb/asterix-om/src/main/java/org/apache/asterix/dataflow/data/nontagged/printers/json/lossless/AObjectPrinter.java
----------------------------------------------------------------------
diff --git a/asterixdb/asterix-om/src/main/java/org/apache/asterix/dataflow/data/nontagged/printers/json/lossless/AObjectPrinter.java b/asterixdb/asterix-om/src/main/java/org/apache/asterix/dataflow/data/nontagged/printers/json/lossless/AObjectPrinter.java
index 534a95a..1acbc06 100644
--- a/asterixdb/asterix-om/src/main/java/org/apache/asterix/dataflow/data/nontagged/printers/json/lossless/AObjectPrinter.java
+++ b/asterixdb/asterix-om/src/main/java/org/apache/asterix/dataflow/data/nontagged/printers/json/lossless/AObjectPrinter.java
@@ -58,6 +58,7 @@ public class AObjectPrinter implements IPrinter {
                 AInt64Printer.INSTANCE.print(b, s, l, ps);
                 break;
             }
+            case MISSING:
             case NULL: {
                 ANullPrinter.INSTANCE.print(b, s, l, ps);
                 break;

http://git-wip-us.apache.org/repos/asf/incubator-asterixdb/blob/535d86b5/asterixdb/asterix-om/src/main/java/org/apache/asterix/dataflow/data/nontagged/serde/AMissingSerializerDeserializer.java
----------------------------------------------------------------------
diff --git a/asterixdb/asterix-om/src/main/java/org/apache/asterix/dataflow/data/nontagged/serde/AMissingSerializerDeserializer.java b/asterixdb/asterix-om/src/main/java/org/apache/asterix/dataflow/data/nontagged/serde/AMissingSerializerDeserializer.java
new file mode 100644
index 0000000..3ffc7a1
--- /dev/null
+++ b/asterixdb/asterix-om/src/main/java/org/apache/asterix/dataflow/data/nontagged/serde/AMissingSerializerDeserializer.java
@@ -0,0 +1,47 @@
+/*
+ * 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.dataflow.data.nontagged.serde;
+
+import java.io.DataInput;
+import java.io.DataOutput;
+
+import org.apache.asterix.om.base.AMissing;
+import org.apache.hyracks.api.dataflow.value.ISerializerDeserializer;
+import org.apache.hyracks.api.exceptions.HyracksDataException;
+
+public class AMissingSerializerDeserializer implements ISerializerDeserializer<AMissing> {
+
+    private static final long serialVersionUID = 1L;
+
+    public static final AMissingSerializerDeserializer INSTANCE = new AMissingSerializerDeserializer();
+
+    private AMissingSerializerDeserializer() {
+    }
+
+    @Override
+    public AMissing deserialize(DataInput in) throws HyracksDataException {
+        return AMissing.MISSING;
+    }
+
+    @Override
+    public void serialize(AMissing instance, DataOutput out) throws HyracksDataException {
+        // A missing value only has a typetag in its serialized form.
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-asterixdb/blob/535d86b5/asterixdb/asterix-om/src/main/java/org/apache/asterix/dataflow/data/nontagged/serde/ANullSerializerDeserializer.java
----------------------------------------------------------------------
diff --git a/asterixdb/asterix-om/src/main/java/org/apache/asterix/dataflow/data/nontagged/serde/ANullSerializerDeserializer.java b/asterixdb/asterix-om/src/main/java/org/apache/asterix/dataflow/data/nontagged/serde/ANullSerializerDeserializer.java
index fb387a8..738284f 100644
--- a/asterixdb/asterix-om/src/main/java/org/apache/asterix/dataflow/data/nontagged/serde/ANullSerializerDeserializer.java
+++ b/asterixdb/asterix-om/src/main/java/org/apache/asterix/dataflow/data/nontagged/serde/ANullSerializerDeserializer.java
@@ -22,10 +22,11 @@ import java.io.DataInput;
 import java.io.DataOutput;
 
 import org.apache.asterix.om.base.ANull;
+import org.apache.asterix.om.base.IAObject;
 import org.apache.hyracks.api.dataflow.value.ISerializerDeserializer;
 import org.apache.hyracks.api.exceptions.HyracksDataException;
 
-public class ANullSerializerDeserializer implements ISerializerDeserializer<ANull> {
+public class ANullSerializerDeserializer implements ISerializerDeserializer<IAObject> {
 
     private static final long serialVersionUID = 1L;
 
@@ -40,7 +41,8 @@ public class ANullSerializerDeserializer implements ISerializerDeserializer<ANul
     }
 
     @Override
-    public void serialize(ANull instance, DataOutput out) throws HyracksDataException {
+    public void serialize(IAObject instance, DataOutput out) throws HyracksDataException {
+        // A null value only has a typetag in its serialized form.
     }
 
 }

http://git-wip-us.apache.org/repos/asf/incubator-asterixdb/blob/535d86b5/asterixdb/asterix-om/src/main/java/org/apache/asterix/dataflow/data/nontagged/serde/AObjectSerializerDeserializer.java
----------------------------------------------------------------------
diff --git a/asterixdb/asterix-om/src/main/java/org/apache/asterix/dataflow/data/nontagged/serde/AObjectSerializerDeserializer.java b/asterixdb/asterix-om/src/main/java/org/apache/asterix/dataflow/data/nontagged/serde/AObjectSerializerDeserializer.java
index 6c754f1..3994d6d 100644
--- a/asterixdb/asterix-om/src/main/java/org/apache/asterix/dataflow/data/nontagged/serde/AObjectSerializerDeserializer.java
+++ b/asterixdb/asterix-om/src/main/java/org/apache/asterix/dataflow/data/nontagged/serde/AObjectSerializerDeserializer.java
@@ -36,7 +36,7 @@ import org.apache.asterix.om.base.AInt64;
 import org.apache.asterix.om.base.AInt8;
 import org.apache.asterix.om.base.AInterval;
 import org.apache.asterix.om.base.ALine;
-import org.apache.asterix.om.base.ANull;
+import org.apache.asterix.om.base.AMissing;
 import org.apache.asterix.om.base.AOrderedList;
 import org.apache.asterix.om.base.APoint;
 import org.apache.asterix.om.base.APoint3D;
@@ -66,6 +66,8 @@ public class AObjectSerializerDeserializer implements ISerializerDeserializer<IA
     public IAObject deserialize(DataInput in) throws HyracksDataException {
         ATypeTag typeTag = SerializerDeserializerUtil.deserializeTag(in);
         switch (typeTag) {
+            case MISSING:
+                return AMissingSerializerDeserializer.INSTANCE.deserialize(in);
             case NULL:
                 return ANullSerializerDeserializer.INSTANCE.deserialize(in);
             case BOOLEAN:
@@ -133,8 +135,11 @@ public class AObjectSerializerDeserializer implements ISerializerDeserializer<IA
             throw new HyracksDataException(e);
         }
         switch (tag) {
+            case MISSING:
+                AMissingSerializerDeserializer.INSTANCE.serialize((AMissing) instance, out);
+                break;
             case NULL:
-                ANullSerializerDeserializer.INSTANCE.serialize((ANull) instance, out);
+                ANullSerializerDeserializer.INSTANCE.serialize(instance, out);
                 break;
             case BOOLEAN:
                 ABooleanSerializerDeserializer.INSTANCE.serialize((ABoolean) instance, out);

http://git-wip-us.apache.org/repos/asf/incubator-asterixdb/blob/535d86b5/asterixdb/asterix-om/src/main/java/org/apache/asterix/dataflow/data/nontagged/serde/ARecordSerializerDeserializer.java
----------------------------------------------------------------------
diff --git a/asterixdb/asterix-om/src/main/java/org/apache/asterix/dataflow/data/nontagged/serde/ARecordSerializerDeserializer.java b/asterixdb/asterix-om/src/main/java/org/apache/asterix/dataflow/data/nontagged/serde/ARecordSerializerDeserializer.java
index d49ad29..0312ec0 100644
--- a/asterixdb/asterix-om/src/main/java/org/apache/asterix/dataflow/data/nontagged/serde/ARecordSerializerDeserializer.java
+++ b/asterixdb/asterix-om/src/main/java/org/apache/asterix/dataflow/data/nontagged/serde/ARecordSerializerDeserializer.java
@@ -72,14 +72,7 @@ public class ARecordSerializerDeserializer implements ISerializerDeserializer<AR
                 IAType t = recordType.getFieldTypes()[i];
                 IAType t2;
                 if (t.getTypeTag() == ATypeTag.UNION) {
-                    if (((AUnionType) t).isNullableType()) {
-                        t2 = ((AUnionType) recordType.getFieldTypes()[i]).getNullableType();
-                        serializers[i] = AqlSerializerDeserializerProvider.INSTANCE.getSerializerDeserializer(
-                                ((AUnionType) recordType.getFieldTypes()[i]).getNullableType());
-                    } else {
-                        // union .. the general case
-                        throw new NotImplementedException();
-                    }
+                    t2 = ((AUnionType) t).getActualType();
                 } else {
                     t2 = t;
                 }

http://git-wip-us.apache.org/repos/asf/incubator-asterixdb/blob/535d86b5/asterixdb/asterix-om/src/main/java/org/apache/asterix/formats/base/IDataFormat.java
----------------------------------------------------------------------
diff --git a/asterixdb/asterix-om/src/main/java/org/apache/asterix/formats/base/IDataFormat.java b/asterixdb/asterix-om/src/main/java/org/apache/asterix/formats/base/IDataFormat.java
index f87681f..3c31f00 100644
--- a/asterixdb/asterix-om/src/main/java/org/apache/asterix/formats/base/IDataFormat.java
+++ b/asterixdb/asterix-om/src/main/java/org/apache/asterix/formats/base/IDataFormat.java
@@ -41,7 +41,7 @@ import org.apache.hyracks.algebricks.data.IPrinterFactoryProvider;
 import org.apache.hyracks.algebricks.data.ISerializerDeserializerProvider;
 import org.apache.hyracks.algebricks.data.ITypeTraitProvider;
 import org.apache.hyracks.algebricks.runtime.base.IScalarEvaluatorFactory;
-import org.apache.hyracks.api.dataflow.value.INullWriterFactory;
+import org.apache.hyracks.api.dataflow.value.IMissingWriterFactory;
 import org.apache.hyracks.api.dataflow.value.IPredicateEvaluatorFactoryProvider;
 
 public interface IDataFormat {
@@ -68,7 +68,7 @@ public interface IDataFormat {
 
     public IPrinterFactoryProvider getCleanJSONPrinterFactoryProvider();
 
-    public INullWriterFactory getNullWriterFactory();
+    public IMissingWriterFactory getMissingWriterFactory();
 
     public Triple<IScalarEvaluatorFactory, ScalarFunctionCallExpression, IAType> partitioningEvaluatorFactory(
             ARecordType recType, List<String> fldName) throws AlgebricksException;

http://git-wip-us.apache.org/repos/asf/incubator-asterixdb/blob/535d86b5/asterixdb/asterix-om/src/main/java/org/apache/asterix/formats/nontagged/AqlADMPrinterFactoryProvider.java
----------------------------------------------------------------------
diff --git a/asterixdb/asterix-om/src/main/java/org/apache/asterix/formats/nontagged/AqlADMPrinterFactoryProvider.java b/asterixdb/asterix-om/src/main/java/org/apache/asterix/formats/nontagged/AqlADMPrinterFactoryProvider.java
index c29e18f..d9db6de 100644
--- a/asterixdb/asterix-om/src/main/java/org/apache/asterix/formats/nontagged/AqlADMPrinterFactoryProvider.java
+++ b/asterixdb/asterix-om/src/main/java/org/apache/asterix/formats/nontagged/AqlADMPrinterFactoryProvider.java
@@ -54,7 +54,6 @@ import org.apache.asterix.om.types.ARecordType;
 import org.apache.asterix.om.types.AUnionType;
 import org.apache.asterix.om.types.AUnorderedListType;
 import org.apache.asterix.om.types.IAType;
-import org.apache.hyracks.algebricks.common.exceptions.AlgebricksException;
 import org.apache.hyracks.algebricks.data.IPrinterFactory;
 import org.apache.hyracks.algebricks.data.IPrinterFactoryProvider;
 
@@ -79,6 +78,7 @@ public class AqlADMPrinterFactoryProvider implements IPrinterFactoryProvider {
                     return AInt32PrinterFactory.INSTANCE;
                 case INT64:
                     return AInt64PrinterFactory.INSTANCE;
+                case MISSING:
                 case NULL:
                     return ANullPrinterFactory.INSTANCE;
                 case BOOLEAN:
@@ -124,10 +124,11 @@ public class AqlADMPrinterFactoryProvider implements IPrinterFactoryProvider {
                 case UNORDEREDLIST:
                     return new AUnorderedlistPrinterFactory((AUnorderedListType) aqlType);
                 case UNION: {
-                    if (((AUnionType) aqlType).isNullableType())
+                    if (((AUnionType) aqlType).isUnknownableType()) {
                         return new ANullableFieldPrinterFactory((AUnionType) aqlType);
-                    else
+                    } else {
                         return new AUnionPrinterFactory((AUnionType) aqlType);
+                    }
                 }
                 case UUID: {
                     return AUUIDPrinterFactory.INSTANCE;

http://git-wip-us.apache.org/repos/asf/incubator-asterixdb/blob/535d86b5/asterixdb/asterix-om/src/main/java/org/apache/asterix/formats/nontagged/AqlBinaryBooleanInspectorImpl.java
----------------------------------------------------------------------
diff --git a/asterixdb/asterix-om/src/main/java/org/apache/asterix/formats/nontagged/AqlBinaryBooleanInspectorImpl.java b/asterixdb/asterix-om/src/main/java/org/apache/asterix/formats/nontagged/AqlBinaryBooleanInspectorImpl.java
index 247e6fd..6729a28 100644
--- a/asterixdb/asterix-om/src/main/java/org/apache/asterix/formats/nontagged/AqlBinaryBooleanInspectorImpl.java
+++ b/asterixdb/asterix-om/src/main/java/org/apache/asterix/formats/nontagged/AqlBinaryBooleanInspectorImpl.java
@@ -39,10 +39,13 @@ public class AqlBinaryBooleanInspectorImpl implements IBinaryBooleanInspector {
 
     @Override
     public boolean getBooleanValue(byte[] bytes, int offset, int length) {
-        if (bytes[offset] == ATypeTag.SERIALIZED_NULL_TYPE_TAG)
+        byte serializedTypeTag = bytes[offset];
+        if (serializedTypeTag == ATypeTag.SERIALIZED_MISSING_TYPE_TAG
+                || serializedTypeTag == ATypeTag.SERIALIZED_NULL_TYPE_TAG) {
             return false;
+        }
         /** check if the runtime type is boolean */
-        ATypeTag typeTag = EnumDeserializer.ATYPETAGDESERIALIZER.deserialize(bytes[offset]);
+        ATypeTag typeTag = EnumDeserializer.ATYPETAGDESERIALIZER.deserialize(serializedTypeTag);
         if (typeTag != ATypeTag.BOOLEAN) {
             throw new IllegalStateException("Runtime error: the select condition should be of the boolean type!");
         }

http://git-wip-us.apache.org/repos/asf/incubator-asterixdb/blob/535d86b5/asterixdb/asterix-om/src/main/java/org/apache/asterix/formats/nontagged/AqlBinaryComparatorFactoryProvider.java
----------------------------------------------------------------------
diff --git a/asterixdb/asterix-om/src/main/java/org/apache/asterix/formats/nontagged/AqlBinaryComparatorFactoryProvider.java b/asterixdb/asterix-om/src/main/java/org/apache/asterix/formats/nontagged/AqlBinaryComparatorFactoryProvider.java
index 44851e3..feb3228 100644
--- a/asterixdb/asterix-om/src/main/java/org/apache/asterix/formats/nontagged/AqlBinaryComparatorFactoryProvider.java
+++ b/asterixdb/asterix-om/src/main/java/org/apache/asterix/formats/nontagged/AqlBinaryComparatorFactoryProvider.java
@@ -105,7 +105,8 @@ public class AqlBinaryComparatorFactoryProvider implements IBinaryComparatorFact
             case UNION: { // we could do smth better for nullable fields
                 return anyBinaryComparatorFactory(ascending);
             }
-            case NULL: {
+            case NULL:
+            case MISSING:
                 return new IBinaryComparatorFactory() {
 
                     private static final long serialVersionUID = 1L;
@@ -121,7 +122,6 @@ public class AqlBinaryComparatorFactoryProvider implements IBinaryComparatorFact
                         };
                     }
                 };
-            }
             case BOOLEAN: {
                 return addOffset(BooleanBinaryComparatorFactory.INSTANCE, ascending);
             }

http://git-wip-us.apache.org/repos/asf/incubator-asterixdb/blob/535d86b5/asterixdb/asterix-om/src/main/java/org/apache/asterix/formats/nontagged/AqlCSVPrinterFactoryProvider.java
----------------------------------------------------------------------
diff --git a/asterixdb/asterix-om/src/main/java/org/apache/asterix/formats/nontagged/AqlCSVPrinterFactoryProvider.java b/asterixdb/asterix-om/src/main/java/org/apache/asterix/formats/nontagged/AqlCSVPrinterFactoryProvider.java
index d57445b..d197e52 100644
--- a/asterixdb/asterix-om/src/main/java/org/apache/asterix/formats/nontagged/AqlCSVPrinterFactoryProvider.java
+++ b/asterixdb/asterix-om/src/main/java/org/apache/asterix/formats/nontagged/AqlCSVPrinterFactoryProvider.java
@@ -49,7 +49,6 @@ import org.apache.asterix.dataflow.data.nontagged.printers.csv.AYearMonthDuratio
 import org.apache.asterix.om.types.ARecordType;
 import org.apache.asterix.om.types.AUnionType;
 import org.apache.asterix.om.types.IAType;
-import org.apache.hyracks.algebricks.common.exceptions.AlgebricksException;
 import org.apache.hyracks.algebricks.common.exceptions.NotImplementedException;
 import org.apache.hyracks.algebricks.data.IPrinterFactory;
 import org.apache.hyracks.algebricks.data.IPrinterFactoryProvider;
@@ -75,6 +74,7 @@ public class AqlCSVPrinterFactoryProvider implements IPrinterFactoryProvider {
                     return AInt32PrinterFactory.INSTANCE;
                 case INT64:
                     return AInt64PrinterFactory.INSTANCE;
+                case MISSING:
                 case NULL:
                     return ANullPrinterFactory.INSTANCE;
                 case BOOLEAN:
@@ -118,10 +118,11 @@ public class AqlCSVPrinterFactoryProvider implements IPrinterFactoryProvider {
                 case UNORDEREDLIST:
                     throw new NotImplementedException("'Unorderedlist' type unsupported for CSV output");
                 case UNION: {
-                    if (((AUnionType) aqlType).isNullableType())
+                    if (((AUnionType) aqlType).isUnknownableType()) {
                         return new ANullableFieldPrinterFactory((AUnionType) aqlType);
-                    else
+                    } else {
                         return new AUnionPrinterFactory((AUnionType) aqlType);
+                    }
                 }
                 case UUID: {
                     return AUUIDPrinterFactory.INSTANCE;

http://git-wip-us.apache.org/repos/asf/incubator-asterixdb/blob/535d86b5/asterixdb/asterix-om/src/main/java/org/apache/asterix/formats/nontagged/AqlCleanJSONPrinterFactoryProvider.java
----------------------------------------------------------------------
diff --git a/asterixdb/asterix-om/src/main/java/org/apache/asterix/formats/nontagged/AqlCleanJSONPrinterFactoryProvider.java b/asterixdb/asterix-om/src/main/java/org/apache/asterix/formats/nontagged/AqlCleanJSONPrinterFactoryProvider.java
index c1eb434..6220dde 100644
--- a/asterixdb/asterix-om/src/main/java/org/apache/asterix/formats/nontagged/AqlCleanJSONPrinterFactoryProvider.java
+++ b/asterixdb/asterix-om/src/main/java/org/apache/asterix/formats/nontagged/AqlCleanJSONPrinterFactoryProvider.java
@@ -54,7 +54,6 @@ import org.apache.asterix.om.types.ARecordType;
 import org.apache.asterix.om.types.AUnionType;
 import org.apache.asterix.om.types.AUnorderedListType;
 import org.apache.asterix.om.types.IAType;
-import org.apache.hyracks.algebricks.common.exceptions.AlgebricksException;
 import org.apache.hyracks.algebricks.data.IPrinterFactory;
 import org.apache.hyracks.algebricks.data.IPrinterFactoryProvider;
 
@@ -79,6 +78,7 @@ public class AqlCleanJSONPrinterFactoryProvider implements IPrinterFactoryProvid
                     return AInt32PrinterFactory.INSTANCE;
                 case INT64:
                     return AInt64PrinterFactory.INSTANCE;
+                case MISSING:
                 case NULL:
                     return ANullPrinterFactory.INSTANCE;
                 case BOOLEAN:
@@ -124,10 +124,11 @@ public class AqlCleanJSONPrinterFactoryProvider implements IPrinterFactoryProvid
                 case UNORDEREDLIST:
                     return new AUnorderedlistPrinterFactory((AUnorderedListType) aqlType);
                 case UNION: {
-                    if (((AUnionType) aqlType).isNullableType())
+                    if (((AUnionType) aqlType).isUnknownableType()) {
                         return new ANullableFieldPrinterFactory((AUnionType) aqlType);
-                    else
+                    } else {
                         return new AUnionPrinterFactory((AUnionType) aqlType);
+                    }
                 }
                 case UUID: {
                     return AUUIDPrinterFactory.INSTANCE;