[NO ISSUE][FUN] Make default-null functions type computers always nullable

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

Change-Id: I8060c98e992d6c8e8dbb15173e35b3c3b58a2a3a
Reviewed-on: https://asterix-gerrit.ics.uci.edu/c/asterixdb/+/14084
Integration-Tests: Jenkins <jenkins@fulliautomatix.ics.uci.edu>
Tested-by: Jenkins <jenkins@fulliautomatix.ics.uci.edu>
Reviewed-by: Ali Alsuliman <ali.al.solaiman@gmail.com>
Reviewed-by: Dmitry Lychagin <dmitry.lychagin@couchbase.com>
diff --git a/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/am/BTreeAccessMethod.java b/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/am/BTreeAccessMethod.java
index 02557fe..a43f0f9 100644
--- a/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/am/BTreeAccessMethod.java
+++ b/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/am/BTreeAccessMethod.java
@@ -1046,15 +1046,16 @@
         if (!finalStep) {
             return AccessMethodUtils.isFieldAccess(funId);
         }
-        if (AccessMethodUtils.isFieldAccess(funId)) {
-            return !defaultNull;
-        } else if (defaultNull && CAST_NULL_TYPE_CONSTRUCTORS.contains(funId)) {
+        if (defaultNull) {
+            if (!CAST_NULL_TYPE_CONSTRUCTORS.contains(funId)) {
+                return false;
+            }
             IAType nonNullableType = Index.getNonNullableType(indexedFieldType).first;
             FunctionIdentifier indexedFieldConstructor = TypeUtil.getTypeConstructorDefaultNull(nonNullableType);
-            // index should have CAST (DEFAULT NULL) and the applied function should be the same as the indexed field
+            // index has CAST (DEFAULT NULL); the applied function should be the same as the indexed field function
             return funId.equals(indexedFieldConstructor);
         } else {
-            return false;
+            return AccessMethodUtils.isFieldAccess(funId);
         }
     }
 
diff --git a/asterixdb/asterix-app/src/test/java/org/apache/asterix/test/runtime/NullMissingExceptionTest.java b/asterixdb/asterix-app/src/test/java/org/apache/asterix/test/runtime/NullMissingExceptionTest.java
index 5b8924f..034dd22 100644
--- a/asterixdb/asterix-app/src/test/java/org/apache/asterix/test/runtime/NullMissingExceptionTest.java
+++ b/asterixdb/asterix-app/src/test/java/org/apache/asterix/test/runtime/NullMissingExceptionTest.java
@@ -78,8 +78,7 @@
                 // We test all functions except record and cast functions, which requires type settings (we test them
                 // in runtime tests).
                 // TODO(ali): ASTERIXDB-2982 do it in a proper way so that it does not exclude classes inadvertently
-                if (!className.contains("record") && !className.contains("Cast")
-                        && !className.contains("DefaultNull")) {
+                if (!className.contains("record") && !className.contains("Cast")) {
                     tests.add(new Object[] { getTestName(functionDescriptor.getClass()), functionDescriptor });
                 } else {
                     LOGGER.log(Level.INFO, "Excluding " + className);
diff --git a/asterixdb/asterix-app/src/test/java/org/apache/asterix/test/runtime/NullMissingTest.java b/asterixdb/asterix-app/src/test/java/org/apache/asterix/test/runtime/NullMissingTest.java
index 9d9a10f..30cb6bd 100644
--- a/asterixdb/asterix-app/src/test/java/org/apache/asterix/test/runtime/NullMissingTest.java
+++ b/asterixdb/asterix-app/src/test/java/org/apache/asterix/test/runtime/NullMissingTest.java
@@ -20,6 +20,10 @@
 
 package org.apache.asterix.test.runtime;
 
+import static org.apache.asterix.common.annotations.MissingNullInOutFunction.MissingNullType.MISSING;
+import static org.apache.asterix.common.annotations.MissingNullInOutFunction.MissingNullType.NULL;
+import static org.apache.asterix.om.types.ATypeTag.SERIALIZED_MISSING_TYPE_TAG;
+import static org.apache.asterix.om.types.ATypeTag.SERIALIZED_NULL_TYPE_TAG;
 import static org.mockito.Mockito.mock;
 
 import java.util.ArrayList;
@@ -33,7 +37,6 @@
 import org.apache.asterix.om.functions.BuiltinFunctions;
 import org.apache.asterix.om.functions.IFunctionDescriptor;
 import org.apache.asterix.om.functions.IFunctionDescriptorFactory;
-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;
@@ -91,7 +94,7 @@
                 // Instead, we test them in runtime tests.
                 // TODO(ali): ASTERIXDB-2982 do it in a proper way so that it does not exclude classes inadvertently
                 if (!className.contains("record") && !className.contains("Cast")
-                        && !className.contains("FullTextContains") && !className.contains("DefaultNull")) {
+                        && !className.contains("FullTextContains")) {
                     tests.add(new Object[] { getTestName(functionDescriptor.getClass()), functionDescriptor });
                 } else {
                     LOGGER.log(Level.INFO, "Excluding " + className);
@@ -129,6 +132,9 @@
         int inputArity = funcDesc.getIdentifier().getArity();
         Iterator<Pair<IScalarEvaluatorFactory[], IAType[]>> argEvalFactoryIterator = getArgCombinations(inputArity);
         int index = 0;
+        MissingNullInOutFunction annot = functionDescriptor.getClass().getAnnotation(MissingNullInOutFunction.class);
+        byte missingOut = annot.onMissing() == MISSING ? SERIALIZED_MISSING_TYPE_TAG : SERIALIZED_NULL_TYPE_TAG;
+        byte nullOut = annot.onNull() == NULL ? SERIALIZED_NULL_TYPE_TAG : SERIALIZED_MISSING_TYPE_TAG;
 
         // Test is happening here
         while (argEvalFactoryIterator.hasNext()) {
@@ -148,11 +154,9 @@
 
             // Result checks
             if (index != 0) {
-                Assert.assertEquals(ATypeTag.SERIALIZED_MISSING_TYPE_TAG,
-                        resultPointable.getByteArray()[resultPointable.getStartOffset()]);
+                Assert.assertEquals(missingOut, resultPointable.getByteArray()[resultPointable.getStartOffset()]);
             } else {
-                Assert.assertEquals(ATypeTag.SERIALIZED_NULL_TYPE_TAG,
-                        resultPointable.getByteArray()[resultPointable.getStartOffset()]);
+                Assert.assertEquals(nullOut, resultPointable.getByteArray()[resultPointable.getStartOffset()]);
             }
             ++index;
         }
@@ -179,11 +183,10 @@
                     if ((index & (1 << j)) != 0) {
                         argumentTypes[j] = BuiltinType.AMISSING;
                         scalarEvaluatorFactories[j] =
-                                new ConstantEvalFactory(new byte[] { ATypeTag.SERIALIZED_MISSING_TYPE_TAG });
+                                new ConstantEvalFactory(new byte[] { SERIALIZED_MISSING_TYPE_TAG });
                     } else {
                         argumentTypes[j] = BuiltinType.ANULL;
-                        scalarEvaluatorFactories[j] =
-                                new ConstantEvalFactory(new byte[] { ATypeTag.SERIALIZED_NULL_TYPE_TAG });
+                        scalarEvaluatorFactories[j] = new ConstantEvalFactory(new byte[] { SERIALIZED_NULL_TYPE_TAG });
                     }
                 }
                 ++index;
diff --git a/asterixdb/asterix-common/src/main/java/org/apache/asterix/common/annotations/MissingNullInOutFunction.java b/asterixdb/asterix-common/src/main/java/org/apache/asterix/common/annotations/MissingNullInOutFunction.java
index 04be957..c2e4ce3 100644
--- a/asterixdb/asterix-common/src/main/java/org/apache/asterix/common/annotations/MissingNullInOutFunction.java
+++ b/asterixdb/asterix-common/src/main/java/org/apache/asterix/common/annotations/MissingNullInOutFunction.java
@@ -25,10 +25,20 @@
 import java.lang.annotation.Target;
 
 /**
- * The functions to which this annotation is applied, respect the missing/null in -> missing/null out behaviour
+ * The functions to which this annotation is applied, specify what {@link MissingNullType} to return on MISSING or NULL
+ * input, and their runtimes respect the specification.
  */
 @Documented
 @Target(ElementType.TYPE)
 @Retention(RetentionPolicy.RUNTIME)
 public @interface MissingNullInOutFunction {
+
+    enum MissingNullType {
+        MISSING,
+        NULL
+    }
+
+    MissingNullType onMissing() default MissingNullType.MISSING;
+
+    MissingNullType onNull() default MissingNullType.NULL;
 }
diff --git a/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/functions/BuiltinFunctions.java b/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/functions/BuiltinFunctions.java
index 24d8cdf..d50a1e5 100644
--- a/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/functions/BuiltinFunctions.java
+++ b/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/functions/BuiltinFunctions.java
@@ -102,6 +102,7 @@
 import org.apache.asterix.om.typecomputer.impl.NotUnknownTypeComputer;
 import org.apache.asterix.om.typecomputer.impl.NullIfTypeComputer;
 import org.apache.asterix.om.typecomputer.impl.NullableDoubleTypeComputer;
+import org.apache.asterix.om.typecomputer.impl.NullableTypeComputer;
 import org.apache.asterix.om.typecomputer.impl.NumericAddSubMulDivTypeComputer;
 import org.apache.asterix.om.typecomputer.impl.NumericBinaryToDoubleTypeComputer;
 import org.apache.asterix.om.typecomputer.impl.NumericDivideTypeComputer;
@@ -1794,28 +1795,28 @@
         addPrivateFunction(MAKE_FIELD_NAME_HANDLE, AnyTypeComputer.INSTANCE, true);
 
         // cast null type constructors
-        addPrivateFunction(BOOLEAN_DEFAULT_NULL_CONSTRUCTOR, ABooleanTypeComputer.INSTANCE_NULLABLE, true);
-        addPrivateFunction(INT8_DEFAULT_NULL_CONSTRUCTOR, AInt8TypeComputer.INSTANCE_NULLABLE, true);
-        addPrivateFunction(INT16_DEFAULT_NULL_CONSTRUCTOR, AInt16TypeComputer.INSTANCE_NULLABLE, true);
-        addPrivateFunction(INT32_DEFAULT_NULL_CONSTRUCTOR, AInt32TypeComputer.INSTANCE_NULLABLE, true);
-        addPrivateFunction(INT64_DEFAULT_NULL_CONSTRUCTOR, AInt64TypeComputer.INSTANCE_NULLABLE, true);
-        addPrivateFunction(FLOAT_DEFAULT_NULL_CONSTRUCTOR, AFloatTypeComputer.INSTANCE_NULLABLE, true);
-        addPrivateFunction(DOUBLE_DEFAULT_NULL_CONSTRUCTOR, ADoubleTypeComputer.INSTANCE_NULLABLE, true);
-        addPrivateFunction(STRING_DEFAULT_NULL_CONSTRUCTOR, AStringTypeComputer.INSTANCE_NULLABLE, true);
-        addPrivateFunction(DATE_DEFAULT_NULL_CONSTRUCTOR, ADateTypeComputer.INSTANCE_NULLABLE, true);
-        addPrivateFunction(DATE_DEFAULT_NULL_CONSTRUCTOR_WITH_FORMAT, ADateTypeComputer.INSTANCE_NULLABLE, true);
-        addPrivateFunction(TIME_DEFAULT_NULL_CONSTRUCTOR, ATimeTypeComputer.INSTANCE_NULLABLE, true);
-        addPrivateFunction(TIME_DEFAULT_NULL_CONSTRUCTOR_WITH_FORMAT, ATimeTypeComputer.INSTANCE_NULLABLE, true);
-        addPrivateFunction(DATETIME_DEFAULT_NULL_CONSTRUCTOR, ADateTimeTypeComputer.INSTANCE_NULLABLE, true);
-        addPrivateFunction(DATETIME_DEFAULT_NULL_CONSTRUCTOR_WITH_FORMAT, ADateTimeTypeComputer.INSTANCE_NULLABLE,
+        addPrivateFunction(BOOLEAN_DEFAULT_NULL_CONSTRUCTOR, NullableTypeComputer.INSTANCE_BOOLEAN, true);
+        addPrivateFunction(INT8_DEFAULT_NULL_CONSTRUCTOR, NullableTypeComputer.INSTANCE_INT8, true);
+        addPrivateFunction(INT16_DEFAULT_NULL_CONSTRUCTOR, NullableTypeComputer.INSTANCE_INT16, true);
+        addPrivateFunction(INT32_DEFAULT_NULL_CONSTRUCTOR, NullableTypeComputer.INSTANCE_INT32, true);
+        addPrivateFunction(INT64_DEFAULT_NULL_CONSTRUCTOR, NullableTypeComputer.INSTANCE_INT64, true);
+        addPrivateFunction(FLOAT_DEFAULT_NULL_CONSTRUCTOR, NullableTypeComputer.INSTANCE_FLOAT, true);
+        addPrivateFunction(DOUBLE_DEFAULT_NULL_CONSTRUCTOR, NullableTypeComputer.INSTANCE_DOUBLE, true);
+        addPrivateFunction(STRING_DEFAULT_NULL_CONSTRUCTOR, NullableTypeComputer.INSTANCE_STRING, true);
+        addPrivateFunction(DATE_DEFAULT_NULL_CONSTRUCTOR, NullableTypeComputer.INSTANCE_DATE, true);
+        addPrivateFunction(DATE_DEFAULT_NULL_CONSTRUCTOR_WITH_FORMAT, NullableTypeComputer.INSTANCE_DATE, true);
+        addPrivateFunction(TIME_DEFAULT_NULL_CONSTRUCTOR, NullableTypeComputer.INSTANCE_TIME, true);
+        addPrivateFunction(TIME_DEFAULT_NULL_CONSTRUCTOR_WITH_FORMAT, NullableTypeComputer.INSTANCE_TIME, true);
+        addPrivateFunction(DATETIME_DEFAULT_NULL_CONSTRUCTOR, NullableTypeComputer.INSTANCE_DATE_TIME, true);
+        addPrivateFunction(DATETIME_DEFAULT_NULL_CONSTRUCTOR_WITH_FORMAT, NullableTypeComputer.INSTANCE_DATE_TIME,
                 true);
-        addPrivateFunction(DURATION_DEFAULT_NULL_CONSTRUCTOR, ADurationTypeComputer.INSTANCE_NULLABLE, true);
-        addPrivateFunction(DAY_TIME_DURATION_DEFAULT_NULL_CONSTRUCTOR, ADayTimeDurationTypeComputer.INSTANCE_NULLABLE,
+        addPrivateFunction(DURATION_DEFAULT_NULL_CONSTRUCTOR, NullableTypeComputer.INSTANCE_DURATION, true);
+        addPrivateFunction(DAY_TIME_DURATION_DEFAULT_NULL_CONSTRUCTOR, NullableTypeComputer.INSTANCE_DAY_TIME_DURATION,
                 true);
         addPrivateFunction(YEAR_MONTH_DURATION_DEFAULT_NULL_CONSTRUCTOR,
-                AYearMonthDurationTypeComputer.INSTANCE_NULLABLE, true);
-        addPrivateFunction(UUID_DEFAULT_NULL_CONSTRUCTOR, AUUIDTypeComputer.INSTANCE_NULLABLE, true);
-        addPrivateFunction(BINARY_BASE64_DEFAULT_NULL_CONSTRUCTOR, ABinaryTypeComputer.INSTANCE_NULLABLE, true);
+                NullableTypeComputer.INSTANCE_YEAR_MONTH_DURATION, true);
+        addPrivateFunction(UUID_DEFAULT_NULL_CONSTRUCTOR, NullableTypeComputer.INSTANCE_UUID, true);
+        addPrivateFunction(BINARY_BASE64_DEFAULT_NULL_CONSTRUCTOR, NullableTypeComputer.INSTANCE_BINARY, true);
 
         addPrivateFunction(NUMERIC_UNARY_MINUS, NumericUnaryTypeComputer.INSTANCE, true);
         addPrivateFunction(NUMERIC_SUBTRACT, NumericAddSubMulDivTypeComputer.INSTANCE_SUB, true);
diff --git a/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/typecomputer/impl/NullableTypeComputer.java b/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/typecomputer/impl/NullableTypeComputer.java
new file mode 100644
index 0000000..eaa15c7
--- /dev/null
+++ b/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/typecomputer/impl/NullableTypeComputer.java
@@ -0,0 +1,77 @@
+/*
+ * 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 static org.apache.asterix.om.types.BuiltinType.ABINARY;
+import static org.apache.asterix.om.types.BuiltinType.ABOOLEAN;
+import static org.apache.asterix.om.types.BuiltinType.ADATE;
+import static org.apache.asterix.om.types.BuiltinType.ADATETIME;
+import static org.apache.asterix.om.types.BuiltinType.ADAYTIMEDURATION;
+import static org.apache.asterix.om.types.BuiltinType.ADOUBLE;
+import static org.apache.asterix.om.types.BuiltinType.ADURATION;
+import static org.apache.asterix.om.types.BuiltinType.AFLOAT;
+import static org.apache.asterix.om.types.BuiltinType.AINT16;
+import static org.apache.asterix.om.types.BuiltinType.AINT32;
+import static org.apache.asterix.om.types.BuiltinType.AINT64;
+import static org.apache.asterix.om.types.BuiltinType.AINT8;
+import static org.apache.asterix.om.types.BuiltinType.ASTRING;
+import static org.apache.asterix.om.types.BuiltinType.ATIME;
+import static org.apache.asterix.om.types.BuiltinType.AUUID;
+import static org.apache.asterix.om.types.BuiltinType.AYEARMONTHDURATION;
+
+import org.apache.asterix.om.typecomputer.base.IResultTypeComputer;
+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.core.algebra.base.ILogicalExpression;
+import org.apache.hyracks.algebricks.core.algebra.expressions.IVariableTypeEnvironment;
+import org.apache.hyracks.algebricks.core.algebra.metadata.IMetadataProvider;
+
+public class NullableTypeComputer implements IResultTypeComputer {
+
+    public static final NullableTypeComputer INSTANCE_INT8 = new NullableTypeComputer(AINT8);
+    public static final NullableTypeComputer INSTANCE_INT16 = new NullableTypeComputer(AINT16);
+    public static final NullableTypeComputer INSTANCE_INT32 = new NullableTypeComputer(AINT32);
+    public static final NullableTypeComputer INSTANCE_INT64 = new NullableTypeComputer(AINT64);
+    public static final NullableTypeComputer INSTANCE_FLOAT = new NullableTypeComputer(AFLOAT);
+    public static final NullableTypeComputer INSTANCE_DOUBLE = new NullableTypeComputer(ADOUBLE);
+    public static final NullableTypeComputer INSTANCE_BOOLEAN = new NullableTypeComputer(ABOOLEAN);
+    public static final NullableTypeComputer INSTANCE_STRING = new NullableTypeComputer(ASTRING);
+    public static final NullableTypeComputer INSTANCE_DATE = new NullableTypeComputer(ADATE);
+    public static final NullableTypeComputer INSTANCE_TIME = new NullableTypeComputer(ATIME);
+    public static final NullableTypeComputer INSTANCE_DATE_TIME = new NullableTypeComputer(ADATETIME);
+    public static final NullableTypeComputer INSTANCE_DURATION = new NullableTypeComputer(ADURATION);
+    public static final NullableTypeComputer INSTANCE_DAY_TIME_DURATION = new NullableTypeComputer(ADAYTIMEDURATION);
+    public static final NullableTypeComputer INSTANCE_YEAR_MONTH_DURATION =
+            new NullableTypeComputer(AYEARMONTHDURATION);
+    public static final NullableTypeComputer INSTANCE_UUID = new NullableTypeComputer(AUUID);
+    public static final NullableTypeComputer INSTANCE_BINARY = new NullableTypeComputer(ABINARY);
+
+    private final IAType nullablePrimeType;
+
+    private NullableTypeComputer(IAType primeType) {
+        this.nullablePrimeType = AUnionType.createNullableType(primeType);
+    }
+
+    @Override
+    public IAType computeType(ILogicalExpression expression, IVariableTypeEnvironment env,
+            IMetadataProvider<?, ?> metadataProvider) throws AlgebricksException {
+        return nullablePrimeType;
+    }
+}
diff --git a/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/constructors/ABinaryBase64StringDefaultNullConstructorDescriptor.java b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/constructors/ABinaryBase64StringDefaultNullConstructorDescriptor.java
index 7b51e90..02a03d3 100644
--- a/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/constructors/ABinaryBase64StringDefaultNullConstructorDescriptor.java
+++ b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/constructors/ABinaryBase64StringDefaultNullConstructorDescriptor.java
@@ -30,14 +30,16 @@
 import org.apache.hyracks.api.exceptions.HyracksDataException;
 import org.apache.hyracks.data.std.api.IPointable;
 
-@MissingNullInOutFunction
+@MissingNullInOutFunction(onMissing = MissingNullInOutFunction.MissingNullType.NULL)
 public class ABinaryBase64StringDefaultNullConstructorDescriptor extends AbstractScalarFunctionDynamicDescriptor {
+
     private static final long serialVersionUID = 1L;
     public static final IFunctionDescriptorFactory FACTORY = ABinaryBase64StringDefaultNullConstructorDescriptor::new;
 
     @Override
     public IScalarEvaluatorFactory createEvaluatorFactory(final IScalarEvaluatorFactory[] args) {
         return new IScalarEvaluatorFactory() {
+
             private static final long serialVersionUID = 1L;
 
             @Override
diff --git a/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/constructors/ABooleanDefaultNullConstructorDescriptor.java b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/constructors/ABooleanDefaultNullConstructorDescriptor.java
index ecc3896..1bec6a7 100644
--- a/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/constructors/ABooleanDefaultNullConstructorDescriptor.java
+++ b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/constructors/ABooleanDefaultNullConstructorDescriptor.java
@@ -30,19 +30,22 @@
 import org.apache.hyracks.api.exceptions.HyracksDataException;
 import org.apache.hyracks.data.std.api.IPointable;
 
-@MissingNullInOutFunction
+@MissingNullInOutFunction(onMissing = MissingNullInOutFunction.MissingNullType.NULL)
 public class ABooleanDefaultNullConstructorDescriptor extends AbstractScalarFunctionDynamicDescriptor {
+
     private static final long serialVersionUID = 1L;
     public static final IFunctionDescriptorFactory FACTORY = ABooleanDefaultNullConstructorDescriptor::new;
 
     @Override
     public IScalarEvaluatorFactory createEvaluatorFactory(final IScalarEvaluatorFactory[] args) {
         return new IScalarEvaluatorFactory() {
+
             private static final long serialVersionUID = 1L;
 
             @Override
             public IScalarEvaluator createScalarEvaluator(IEvaluatorContext ctx) throws HyracksDataException {
                 return new AbstractBooleanConstructorEvaluator(ctx, args[0].createScalarEvaluator(ctx), sourceLoc) {
+
                     @Override
                     protected FunctionIdentifier getIdentifier() {
                         return ABooleanDefaultNullConstructorDescriptor.this.getIdentifier();
diff --git a/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/constructors/ADateDefaultNullConstructorDescriptor.java b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/constructors/ADateDefaultNullConstructorDescriptor.java
index 4508e9a..da7db6b 100644
--- a/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/constructors/ADateDefaultNullConstructorDescriptor.java
+++ b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/constructors/ADateDefaultNullConstructorDescriptor.java
@@ -30,14 +30,16 @@
 import org.apache.hyracks.api.exceptions.HyracksDataException;
 import org.apache.hyracks.data.std.api.IPointable;
 
-@MissingNullInOutFunction
+@MissingNullInOutFunction(onMissing = MissingNullInOutFunction.MissingNullType.NULL)
 public class ADateDefaultNullConstructorDescriptor extends AbstractScalarFunctionDynamicDescriptor {
+
     private static final long serialVersionUID = 1L;
     public static final IFunctionDescriptorFactory FACTORY = ADateDefaultNullConstructorDescriptor::new;
 
     @Override
     public IScalarEvaluatorFactory createEvaluatorFactory(final IScalarEvaluatorFactory[] args) {
         return new IScalarEvaluatorFactory() {
+
             private static final long serialVersionUID = 1L;
 
             @Override
diff --git a/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/constructors/ADateDefaultNullConstructorWithFormatDescriptor.java b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/constructors/ADateDefaultNullConstructorWithFormatDescriptor.java
index ad67677..e1ac605 100644
--- a/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/constructors/ADateDefaultNullConstructorWithFormatDescriptor.java
+++ b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/constructors/ADateDefaultNullConstructorWithFormatDescriptor.java
@@ -31,14 +31,16 @@
 import org.apache.hyracks.api.exceptions.HyracksDataException;
 import org.apache.hyracks.data.std.api.IPointable;
 
-@MissingNullInOutFunction
+@MissingNullInOutFunction(onMissing = MissingNullInOutFunction.MissingNullType.NULL)
 public class ADateDefaultNullConstructorWithFormatDescriptor extends AbstractScalarFunctionDynamicDescriptor {
+
     private static final long serialVersionUID = 1L;
     public static final IFunctionDescriptorFactory FACTORY = ADateDefaultNullConstructorWithFormatDescriptor::new;
 
     @Override
     public IScalarEvaluatorFactory createEvaluatorFactory(final IScalarEvaluatorFactory[] args) {
         return new IScalarEvaluatorFactory() {
+
             private static final long serialVersionUID = 1L;
 
             @Override
@@ -52,10 +54,7 @@
 
                     @Override
                     protected boolean checkAndSetMissingOrNull(IPointable result) throws HyracksDataException {
-                        if (PointableHelper.checkAndSetNull(result, inputArg)) {
-                            return true;
-                        }
-                        return super.checkAndSetMissingOrNull(result);
+                        return PointableHelper.checkAndSetNull(result, inputArg, formatArg);
                     }
                 };
             }
diff --git a/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/constructors/ADateTimeDefaultNullConstructorDescriptor.java b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/constructors/ADateTimeDefaultNullConstructorDescriptor.java
index 92c0a78..fd3ac96 100644
--- a/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/constructors/ADateTimeDefaultNullConstructorDescriptor.java
+++ b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/constructors/ADateTimeDefaultNullConstructorDescriptor.java
@@ -30,14 +30,16 @@
 import org.apache.hyracks.api.exceptions.HyracksDataException;
 import org.apache.hyracks.data.std.api.IPointable;
 
-@MissingNullInOutFunction
+@MissingNullInOutFunction(onMissing = MissingNullInOutFunction.MissingNullType.NULL)
 public class ADateTimeDefaultNullConstructorDescriptor extends AbstractScalarFunctionDynamicDescriptor {
+
     private static final long serialVersionUID = 1L;
     public static final IFunctionDescriptorFactory FACTORY = ADateTimeDefaultNullConstructorDescriptor::new;
 
     @Override
     public IScalarEvaluatorFactory createEvaluatorFactory(final IScalarEvaluatorFactory[] args) {
         return new IScalarEvaluatorFactory() {
+
             private static final long serialVersionUID = 1L;
 
             @Override
diff --git a/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/constructors/ADateTimeDefaultNullConstructorWithFormatDescriptor.java b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/constructors/ADateTimeDefaultNullConstructorWithFormatDescriptor.java
index 8b2269b..04810f6 100644
--- a/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/constructors/ADateTimeDefaultNullConstructorWithFormatDescriptor.java
+++ b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/constructors/ADateTimeDefaultNullConstructorWithFormatDescriptor.java
@@ -19,6 +19,7 @@
 
 package org.apache.asterix.runtime.evaluators.constructors;
 
+import org.apache.asterix.common.annotations.MissingNullInOutFunction;
 import org.apache.asterix.om.functions.BuiltinFunctions;
 import org.apache.asterix.om.functions.IFunctionDescriptorFactory;
 import org.apache.asterix.runtime.evaluators.base.AbstractScalarFunctionDynamicDescriptor;
@@ -30,13 +31,16 @@
 import org.apache.hyracks.api.exceptions.HyracksDataException;
 import org.apache.hyracks.data.std.api.IPointable;
 
+@MissingNullInOutFunction(onMissing = MissingNullInOutFunction.MissingNullType.NULL)
 public class ADateTimeDefaultNullConstructorWithFormatDescriptor extends AbstractScalarFunctionDynamicDescriptor {
+
     private static final long serialVersionUID = 1L;
     public static final IFunctionDescriptorFactory FACTORY = ADateTimeDefaultNullConstructorWithFormatDescriptor::new;
 
     @Override
     public IScalarEvaluatorFactory createEvaluatorFactory(final IScalarEvaluatorFactory[] args) {
         return new IScalarEvaluatorFactory() {
+
             private static final long serialVersionUID = 1L;
 
             @Override
@@ -50,10 +54,7 @@
 
                     @Override
                     protected boolean checkAndSetMissingOrNull(IPointable result) throws HyracksDataException {
-                        if (PointableHelper.checkAndSetNull(result, inputArg)) {
-                            return true;
-                        }
-                        return super.checkAndSetMissingOrNull(result);
+                        return PointableHelper.checkAndSetNull(result, inputArg, formatArg);
                     }
                 };
             }
diff --git a/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/constructors/ADayTimeDurationDefaultNullConstructorDescriptor.java b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/constructors/ADayTimeDurationDefaultNullConstructorDescriptor.java
index 97c41f3..d17c80b 100644
--- a/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/constructors/ADayTimeDurationDefaultNullConstructorDescriptor.java
+++ b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/constructors/ADayTimeDurationDefaultNullConstructorDescriptor.java
@@ -30,7 +30,7 @@
 import org.apache.hyracks.api.exceptions.HyracksDataException;
 import org.apache.hyracks.data.std.api.IPointable;
 
-@MissingNullInOutFunction
+@MissingNullInOutFunction(onMissing = MissingNullInOutFunction.MissingNullType.NULL)
 public class ADayTimeDurationDefaultNullConstructorDescriptor extends AbstractScalarFunctionDynamicDescriptor {
 
     private static final long serialVersionUID = 1L;
@@ -39,6 +39,7 @@
     @Override
     public IScalarEvaluatorFactory createEvaluatorFactory(final IScalarEvaluatorFactory[] args) {
         return new IScalarEvaluatorFactory() {
+
             private static final long serialVersionUID = 1L;
 
             @Override
diff --git a/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/constructors/ADoubleDefaultNullConstructorDescriptor.java b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/constructors/ADoubleDefaultNullConstructorDescriptor.java
index 92be7de..578be20 100644
--- a/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/constructors/ADoubleDefaultNullConstructorDescriptor.java
+++ b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/constructors/ADoubleDefaultNullConstructorDescriptor.java
@@ -30,14 +30,16 @@
 import org.apache.hyracks.api.exceptions.HyracksDataException;
 import org.apache.hyracks.data.std.api.IPointable;
 
-@MissingNullInOutFunction
+@MissingNullInOutFunction(onMissing = MissingNullInOutFunction.MissingNullType.NULL)
 public class ADoubleDefaultNullConstructorDescriptor extends AbstractScalarFunctionDynamicDescriptor {
+
     private static final long serialVersionUID = 1L;
     public static final IFunctionDescriptorFactory FACTORY = ADoubleDefaultNullConstructorDescriptor::new;
 
     @Override
     public IScalarEvaluatorFactory createEvaluatorFactory(final IScalarEvaluatorFactory[] args) {
         return new IScalarEvaluatorFactory() {
+
             private static final long serialVersionUID = 1L;
 
             @Override
diff --git a/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/constructors/ADurationDefaultNullConstructorDescriptor.java b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/constructors/ADurationDefaultNullConstructorDescriptor.java
index 3a0ccf1..429fa0a 100644
--- a/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/constructors/ADurationDefaultNullConstructorDescriptor.java
+++ b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/constructors/ADurationDefaultNullConstructorDescriptor.java
@@ -30,14 +30,16 @@
 import org.apache.hyracks.api.exceptions.HyracksDataException;
 import org.apache.hyracks.data.std.api.IPointable;
 
-@MissingNullInOutFunction
+@MissingNullInOutFunction(onMissing = MissingNullInOutFunction.MissingNullType.NULL)
 public class ADurationDefaultNullConstructorDescriptor extends AbstractScalarFunctionDynamicDescriptor {
+
     private static final long serialVersionUID = 1L;
     public static final IFunctionDescriptorFactory FACTORY = ADurationDefaultNullConstructorDescriptor::new;
 
     @Override
     public IScalarEvaluatorFactory createEvaluatorFactory(final IScalarEvaluatorFactory[] args) {
         return new IScalarEvaluatorFactory() {
+
             private static final long serialVersionUID = 1L;
 
             @Override
diff --git a/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/constructors/AFloatDefaultNullConstructorDescriptor.java b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/constructors/AFloatDefaultNullConstructorDescriptor.java
index c1abb94..09a1e5a 100644
--- a/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/constructors/AFloatDefaultNullConstructorDescriptor.java
+++ b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/constructors/AFloatDefaultNullConstructorDescriptor.java
@@ -30,14 +30,16 @@
 import org.apache.hyracks.api.exceptions.HyracksDataException;
 import org.apache.hyracks.data.std.api.IPointable;
 
-@MissingNullInOutFunction
+@MissingNullInOutFunction(onMissing = MissingNullInOutFunction.MissingNullType.NULL)
 public class AFloatDefaultNullConstructorDescriptor extends AbstractScalarFunctionDynamicDescriptor {
+
     private static final long serialVersionUID = 1L;
     public static final IFunctionDescriptorFactory FACTORY = AFloatDefaultNullConstructorDescriptor::new;
 
     @Override
     public IScalarEvaluatorFactory createEvaluatorFactory(final IScalarEvaluatorFactory[] args) {
         return new IScalarEvaluatorFactory() {
+
             private static final long serialVersionUID = 1L;
 
             @Override
diff --git a/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/constructors/AInt16DefaultNullConstructorDescriptor.java b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/constructors/AInt16DefaultNullConstructorDescriptor.java
index 0ebb7b2..d7ae6b8 100644
--- a/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/constructors/AInt16DefaultNullConstructorDescriptor.java
+++ b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/constructors/AInt16DefaultNullConstructorDescriptor.java
@@ -30,14 +30,16 @@
 import org.apache.hyracks.api.exceptions.HyracksDataException;
 import org.apache.hyracks.data.std.api.IPointable;
 
-@MissingNullInOutFunction
+@MissingNullInOutFunction(onMissing = MissingNullInOutFunction.MissingNullType.NULL)
 public class AInt16DefaultNullConstructorDescriptor extends AbstractScalarFunctionDynamicDescriptor {
+
     private static final long serialVersionUID = 1L;
     public static final IFunctionDescriptorFactory FACTORY = AInt16DefaultNullConstructorDescriptor::new;
 
     @Override
     public IScalarEvaluatorFactory createEvaluatorFactory(final IScalarEvaluatorFactory[] args) {
         return new IScalarEvaluatorFactory() {
+
             private static final long serialVersionUID = 1L;
 
             @Override
diff --git a/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/constructors/AInt32DefaultNullConstructorDescriptor.java b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/constructors/AInt32DefaultNullConstructorDescriptor.java
index 2f64596..bebf803 100644
--- a/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/constructors/AInt32DefaultNullConstructorDescriptor.java
+++ b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/constructors/AInt32DefaultNullConstructorDescriptor.java
@@ -30,14 +30,16 @@
 import org.apache.hyracks.api.exceptions.HyracksDataException;
 import org.apache.hyracks.data.std.api.IPointable;
 
-@MissingNullInOutFunction
+@MissingNullInOutFunction(onMissing = MissingNullInOutFunction.MissingNullType.NULL)
 public class AInt32DefaultNullConstructorDescriptor extends AbstractScalarFunctionDynamicDescriptor {
+
     private static final long serialVersionUID = 1L;
     public static final IFunctionDescriptorFactory FACTORY = AInt32DefaultNullConstructorDescriptor::new;
 
     @Override
     public IScalarEvaluatorFactory createEvaluatorFactory(final IScalarEvaluatorFactory[] args) {
         return new IScalarEvaluatorFactory() {
+
             private static final long serialVersionUID = 1L;
 
             @Override
diff --git a/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/constructors/AInt64DefaultNullConstructorDescriptor.java b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/constructors/AInt64DefaultNullConstructorDescriptor.java
index 5e833b3..0b851fe 100644
--- a/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/constructors/AInt64DefaultNullConstructorDescriptor.java
+++ b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/constructors/AInt64DefaultNullConstructorDescriptor.java
@@ -30,14 +30,16 @@
 import org.apache.hyracks.api.exceptions.HyracksDataException;
 import org.apache.hyracks.data.std.api.IPointable;
 
-@MissingNullInOutFunction
+@MissingNullInOutFunction(onMissing = MissingNullInOutFunction.MissingNullType.NULL)
 public class AInt64DefaultNullConstructorDescriptor extends AbstractScalarFunctionDynamicDescriptor {
+
     private static final long serialVersionUID = 1L;
     public static final IFunctionDescriptorFactory FACTORY = AInt64DefaultNullConstructorDescriptor::new;
 
     @Override
     public IScalarEvaluatorFactory createEvaluatorFactory(final IScalarEvaluatorFactory[] args) {
         return new IScalarEvaluatorFactory() {
+
             private static final long serialVersionUID = 1L;
 
             @Override
diff --git a/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/constructors/AInt8DefaultNullConstructorDescriptor.java b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/constructors/AInt8DefaultNullConstructorDescriptor.java
index f1435f0..5b38574 100644
--- a/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/constructors/AInt8DefaultNullConstructorDescriptor.java
+++ b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/constructors/AInt8DefaultNullConstructorDescriptor.java
@@ -30,14 +30,16 @@
 import org.apache.hyracks.api.exceptions.HyracksDataException;
 import org.apache.hyracks.data.std.api.IPointable;
 
-@MissingNullInOutFunction
+@MissingNullInOutFunction(onMissing = MissingNullInOutFunction.MissingNullType.NULL)
 public class AInt8DefaultNullConstructorDescriptor extends AbstractScalarFunctionDynamicDescriptor {
+
     private static final long serialVersionUID = 1L;
     public static final IFunctionDescriptorFactory FACTORY = AInt8DefaultNullConstructorDescriptor::new;
 
     @Override
     public IScalarEvaluatorFactory createEvaluatorFactory(final IScalarEvaluatorFactory[] args) {
         return new IScalarEvaluatorFactory() {
+
             private static final long serialVersionUID = 1L;
 
             @Override
diff --git a/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/constructors/AStringDefaultNullConstructorDescriptor.java b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/constructors/AStringDefaultNullConstructorDescriptor.java
index 0f12359..64aed11 100644
--- a/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/constructors/AStringDefaultNullConstructorDescriptor.java
+++ b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/constructors/AStringDefaultNullConstructorDescriptor.java
@@ -30,7 +30,7 @@
 import org.apache.hyracks.api.exceptions.HyracksDataException;
 import org.apache.hyracks.data.std.api.IPointable;
 
-@MissingNullInOutFunction
+@MissingNullInOutFunction(onMissing = MissingNullInOutFunction.MissingNullType.NULL)
 public class AStringDefaultNullConstructorDescriptor extends AbstractScalarFunctionDynamicDescriptor {
 
     private static final long serialVersionUID = 1L;
@@ -39,11 +39,13 @@
     @Override
     public IScalarEvaluatorFactory createEvaluatorFactory(final IScalarEvaluatorFactory[] args) {
         return new IScalarEvaluatorFactory() {
+
             private static final long serialVersionUID = 1L;
 
             @Override
             public IScalarEvaluator createScalarEvaluator(IEvaluatorContext ctx) throws HyracksDataException {
                 return new AbstractStringConstructorEvaluator(ctx, args[0].createScalarEvaluator(ctx), sourceLoc) {
+
                     @Override
                     protected FunctionIdentifier getIdentifier() {
                         return AStringDefaultNullConstructorDescriptor.this.getIdentifier();
diff --git a/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/constructors/ATimeDefaultNullConstructorDescriptor.java b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/constructors/ATimeDefaultNullConstructorDescriptor.java
index 859591c..930b048 100644
--- a/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/constructors/ATimeDefaultNullConstructorDescriptor.java
+++ b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/constructors/ATimeDefaultNullConstructorDescriptor.java
@@ -30,14 +30,16 @@
 import org.apache.hyracks.api.exceptions.HyracksDataException;
 import org.apache.hyracks.data.std.api.IPointable;
 
-@MissingNullInOutFunction
+@MissingNullInOutFunction(onMissing = MissingNullInOutFunction.MissingNullType.NULL)
 public class ATimeDefaultNullConstructorDescriptor extends AbstractScalarFunctionDynamicDescriptor {
+
     private static final long serialVersionUID = 1L;
     public static final IFunctionDescriptorFactory FACTORY = ATimeDefaultNullConstructorDescriptor::new;
 
     @Override
     public IScalarEvaluatorFactory createEvaluatorFactory(final IScalarEvaluatorFactory[] args) {
         return new IScalarEvaluatorFactory() {
+
             private static final long serialVersionUID = 1L;
 
             @Override
diff --git a/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/constructors/ATimeDefaultNullConstructorWithFormatDescriptor.java b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/constructors/ATimeDefaultNullConstructorWithFormatDescriptor.java
index cc1ef88..5200ea6 100644
--- a/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/constructors/ATimeDefaultNullConstructorWithFormatDescriptor.java
+++ b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/constructors/ATimeDefaultNullConstructorWithFormatDescriptor.java
@@ -19,6 +19,7 @@
 
 package org.apache.asterix.runtime.evaluators.constructors;
 
+import org.apache.asterix.common.annotations.MissingNullInOutFunction;
 import org.apache.asterix.om.functions.BuiltinFunctions;
 import org.apache.asterix.om.functions.IFunctionDescriptorFactory;
 import org.apache.asterix.runtime.evaluators.base.AbstractScalarFunctionDynamicDescriptor;
@@ -30,13 +31,16 @@
 import org.apache.hyracks.api.exceptions.HyracksDataException;
 import org.apache.hyracks.data.std.api.IPointable;
 
+@MissingNullInOutFunction(onMissing = MissingNullInOutFunction.MissingNullType.NULL)
 public class ATimeDefaultNullConstructorWithFormatDescriptor extends AbstractScalarFunctionDynamicDescriptor {
+
     private static final long serialVersionUID = 1L;
     public static final IFunctionDescriptorFactory FACTORY = ATimeDefaultNullConstructorWithFormatDescriptor::new;
 
     @Override
     public IScalarEvaluatorFactory createEvaluatorFactory(final IScalarEvaluatorFactory[] args) {
         return new IScalarEvaluatorFactory() {
+
             private static final long serialVersionUID = 1L;
 
             @Override
@@ -50,10 +54,7 @@
 
                     @Override
                     protected boolean checkAndSetMissingOrNull(IPointable result) throws HyracksDataException {
-                        if (PointableHelper.checkAndSetNull(result, inputArg)) {
-                            return true;
-                        }
-                        return super.checkAndSetMissingOrNull(result);
+                        return PointableHelper.checkAndSetNull(result, inputArg, formatArg);
                     }
                 };
             }
diff --git a/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/constructors/AUUIDFromStringDefaultNullConstructorDescriptor.java b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/constructors/AUUIDFromStringDefaultNullConstructorDescriptor.java
index ac64e81..f982037 100644
--- a/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/constructors/AUUIDFromStringDefaultNullConstructorDescriptor.java
+++ b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/constructors/AUUIDFromStringDefaultNullConstructorDescriptor.java
@@ -36,14 +36,16 @@
  * uuid("02a199ca-bf58-412e-bd9f-60a0c975a8ac"))
  */
 
-@MissingNullInOutFunction
+@MissingNullInOutFunction(onMissing = MissingNullInOutFunction.MissingNullType.NULL)
 public class AUUIDFromStringDefaultNullConstructorDescriptor extends AbstractScalarFunctionDynamicDescriptor {
+
     private static final long serialVersionUID = 1L;
     public static final IFunctionDescriptorFactory FACTORY = AUUIDFromStringDefaultNullConstructorDescriptor::new;
 
     @Override
     public IScalarEvaluatorFactory createEvaluatorFactory(final IScalarEvaluatorFactory[] args) {
         return new IScalarEvaluatorFactory() {
+
             private static final long serialVersionUID = 1L;
 
             @Override
diff --git a/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/constructors/AYearMonthDurationDefaultNullConstructorDescriptor.java b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/constructors/AYearMonthDurationDefaultNullConstructorDescriptor.java
index 529306a..4360f0b 100644
--- a/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/constructors/AYearMonthDurationDefaultNullConstructorDescriptor.java
+++ b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/constructors/AYearMonthDurationDefaultNullConstructorDescriptor.java
@@ -30,14 +30,16 @@
 import org.apache.hyracks.api.exceptions.HyracksDataException;
 import org.apache.hyracks.data.std.api.IPointable;
 
-@MissingNullInOutFunction
+@MissingNullInOutFunction(onMissing = MissingNullInOutFunction.MissingNullType.NULL)
 public class AYearMonthDurationDefaultNullConstructorDescriptor extends AbstractScalarFunctionDynamicDescriptor {
+
     private static final long serialVersionUID = 1L;
     public static final IFunctionDescriptorFactory FACTORY = AYearMonthDurationDefaultNullConstructorDescriptor::new;
 
     @Override
     public IScalarEvaluatorFactory createEvaluatorFactory(final IScalarEvaluatorFactory[] args) {
         return new IScalarEvaluatorFactory() {
+
             private static final long serialVersionUID = 1L;
 
             @Override
diff --git a/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/constructors/AbstractDateConstructorWithFormatEvaluator.java b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/constructors/AbstractDateConstructorWithFormatEvaluator.java
index f02ddec..7e9a6b3 100644
--- a/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/constructors/AbstractDateConstructorWithFormatEvaluator.java
+++ b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/constructors/AbstractDateConstructorWithFormatEvaluator.java
@@ -39,7 +39,7 @@
 public abstract class AbstractDateConstructorWithFormatEvaluator extends AbstractDateConstructorEvaluator {
 
     private final IScalarEvaluator formatEval;
-    private final IPointable formatArg = new VoidPointable();
+    protected final IPointable formatArg = new VoidPointable();
     private final UTF8StringPointable formatTextPtr = new UTF8StringPointable();
     private final AMutableInt64 aInt64 = new AMutableInt64(0);
 
diff --git a/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/constructors/AbstractDateTimeConstructorWithFormatEvaluator.java b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/constructors/AbstractDateTimeConstructorWithFormatEvaluator.java
index 899e7e6..8c8da2e 100644
--- a/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/constructors/AbstractDateTimeConstructorWithFormatEvaluator.java
+++ b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/constructors/AbstractDateTimeConstructorWithFormatEvaluator.java
@@ -38,7 +38,7 @@
 public abstract class AbstractDateTimeConstructorWithFormatEvaluator extends AbstractDateTimeConstructorEvaluator {
 
     private final IScalarEvaluator formatEval;
-    private final IPointable formatArg = new VoidPointable();
+    protected final IPointable formatArg = new VoidPointable();
     private final UTF8StringPointable formatTextPtr = new UTF8StringPointable();
     private final AMutableInt64 aInt64 = new AMutableInt64(0);
 
diff --git a/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/constructors/AbstractTimeWithFormatConstructorEvaluator.java b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/constructors/AbstractTimeWithFormatConstructorEvaluator.java
index d70e3bb..f6e945c 100644
--- a/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/constructors/AbstractTimeWithFormatConstructorEvaluator.java
+++ b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/constructors/AbstractTimeWithFormatConstructorEvaluator.java
@@ -38,7 +38,7 @@
 public abstract class AbstractTimeWithFormatConstructorEvaluator extends AbstractTimeConstructorEvaluator {
 
     private final IScalarEvaluator formatEval;
-    private final IPointable formatArg = new VoidPointable();
+    protected final IPointable formatArg = new VoidPointable();
     private final UTF8StringPointable formatTextPtr = new UTF8StringPointable();
     private final AMutableInt64 aInt64 = new AMutableInt64(0);
 
diff --git a/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/PointableHelper.java b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/PointableHelper.java
index e0fbe5c..7a017bd 100644
--- a/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/PointableHelper.java
+++ b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/PointableHelper.java
@@ -328,6 +328,21 @@
     }
 
     /**
+     * Checks whether any pointable argument is null or missing, and if true, assigns null to the
+     * {@param result}.
+     *
+     * @param result the result pointable that will hold the null value
+     * @param pointable1 the pointable to be checked
+     * @param pointable2 the pointable to be checked
+     *
+     * @return {@code true} if any pointable is missing or null, {@code false} otherwise.
+     */
+    public static boolean checkAndSetNull(IPointable result, IPointable pointable1, IPointable pointable2)
+            throws HyracksDataException {
+        return checkAndSetNull(result, pointable1) || checkAndSetNull(result, pointable2);
+    }
+
+    /**
      * This method checks and returns the pointable value state.
      *
      * If a ListAccessor is passed to this function, it will check if the passed pointable is a list, and if so, it