This is an automated email from the ASF dual-hosted git repository.

alsuliman pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/asterixdb.git


The following commit(s) were added to refs/heads/master by this push:
     new ded5f56  [NO ISSUE][FUN] Make default-null functions type computers 
always nullable
ded5f56 is described below

commit ded5f56d3b00356354dbf65dea7df79248c0eb75
Author: Ali Alsuliman <[email protected]>
AuthorDate: Tue Nov 16 12:34:04 2021 -0800

    [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 <[email protected]>
    Tested-by: Jenkins <[email protected]>
    Reviewed-by: Ali Alsuliman <[email protected]>
    Reviewed-by: Dmitry Lychagin <[email protected]>
---
 .../optimizer/rules/am/BTreeAccessMethod.java      | 11 ++--
 .../test/runtime/NullMissingExceptionTest.java     |  3 +-
 .../asterix/test/runtime/NullMissingTest.java      | 21 +++---
 .../annotations/MissingNullInOutFunction.java      | 12 +++-
 .../asterix/om/functions/BuiltinFunctions.java     | 39 +++++------
 .../om/typecomputer/impl/NullableTypeComputer.java | 77 ++++++++++++++++++++++
 ...se64StringDefaultNullConstructorDescriptor.java |  4 +-
 .../ABooleanDefaultNullConstructorDescriptor.java  |  5 +-
 .../ADateDefaultNullConstructorDescriptor.java     |  4 +-
 ...DefaultNullConstructorWithFormatDescriptor.java |  9 ++-
 .../ADateTimeDefaultNullConstructorDescriptor.java |  4 +-
 ...DefaultNullConstructorWithFormatDescriptor.java |  9 +--
 ...meDurationDefaultNullConstructorDescriptor.java |  3 +-
 .../ADoubleDefaultNullConstructorDescriptor.java   |  4 +-
 .../ADurationDefaultNullConstructorDescriptor.java |  4 +-
 .../AFloatDefaultNullConstructorDescriptor.java    |  4 +-
 .../AInt16DefaultNullConstructorDescriptor.java    |  4 +-
 .../AInt32DefaultNullConstructorDescriptor.java    |  4 +-
 .../AInt64DefaultNullConstructorDescriptor.java    |  4 +-
 .../AInt8DefaultNullConstructorDescriptor.java     |  4 +-
 .../AStringDefaultNullConstructorDescriptor.java   |  4 +-
 .../ATimeDefaultNullConstructorDescriptor.java     |  4 +-
 ...DefaultNullConstructorWithFormatDescriptor.java |  9 +--
 ...FromStringDefaultNullConstructorDescriptor.java |  4 +-
 ...thDurationDefaultNullConstructorDescriptor.java |  4 +-
 ...AbstractDateConstructorWithFormatEvaluator.java |  2 +-
 ...ractDateTimeConstructorWithFormatEvaluator.java |  2 +-
 ...AbstractTimeWithFormatConstructorEvaluator.java |  2 +-
 .../evaluators/functions/PointableHelper.java      | 15 +++++
 29 files changed, 207 insertions(+), 68 deletions(-)

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 @@ public class BTreeAccessMethod implements IAccessMethod 
{
         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 @@ public class NullMissingExceptionTest {
                 // 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.common.annotations.MissingNullInOutFunction;
 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 @@ public class NullMissingTest {
                 // 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 @@ public class NullMissingTest {
         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 @@ public class NullMissingTest {
 
             // 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 @@ public class NullMissingTest {
                     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.RetentionPolicy;
 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.NonTaggedGetItemResultType;
 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 @@ public class BuiltinFunctions {
         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.algebricks.runtime.base.IScalarEvaluatorFactory;
 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.algebricks.runtime.base.IScalarEvaluatorFactory;
 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.algebricks.runtime.base.IScalarEvaluatorFactory;
 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.algebricks.runtime.base.IScalarEvaluatorFactory;
 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 @@ public class ADateDefaultNullConstructorWithFormatDescriptor 
extends AbstractSca
 
                     @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.algebricks.runtime.base.IScalarEvaluatorFactory;
 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.algebricks.runtime.base.IScalarEvaluatorFactory;
 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 @@ public class 
ADateTimeDefaultNullConstructorWithFormatDescriptor extends Abstrac
 
                     @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.algebricks.runtime.base.IScalarEvaluatorFactory;
 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 @@ public class ADayTimeDurationDefaultNullConstructorDescriptor 
extends AbstractSc
     @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.algebricks.runtime.base.IScalarEvaluatorFactory;
 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.algebricks.runtime.base.IScalarEvaluatorFactory;
 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.algebricks.runtime.base.IScalarEvaluatorFactory;
 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.algebricks.runtime.base.IScalarEvaluatorFactory;
 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.algebricks.runtime.base.IScalarEvaluatorFactory;
 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.algebricks.runtime.base.IScalarEvaluatorFactory;
 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.algebricks.runtime.base.IScalarEvaluatorFactory;
 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.algebricks.runtime.base.IScalarEvaluatorFactory;
 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 @@ public class AStringDefaultNullConstructorDescriptor 
extends AbstractScalarFunct
     @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.algebricks.runtime.base.IScalarEvaluatorFactory;
 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.algebricks.runtime.base.IScalarEvaluatorFactory;
 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 @@ public class ATimeDefaultNullConstructorWithFormatDescriptor 
extends AbstractSca
 
                     @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 @@ import org.apache.hyracks.data.std.api.IPointable;
  * 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.algebricks.runtime.base.IScalarEvaluatorFactory;
 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 @@ import 
org.apache.hyracks.dataflow.common.data.accessors.IFrameTupleReference;
 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 @@ import 
org.apache.hyracks.dataflow.common.data.accessors.IFrameTupleReference;
 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 @@ import 
org.apache.hyracks.dataflow.common.data.accessors.IFrameTupleReference;
 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 @@ public class PointableHelper {
     }
 
     /**
+     * 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

Reply via email to