[ASTERIXDB-2689][FUN] Make arithmetic functions return NULL on invalid arguments

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

Details:
Make arithmetic functions return NULL on invalid arguments:
Functions are for: +, -, *, /, DIV, %, ^

Change-Id: I6a822e59c91d06506505597927fab93e403385d8
Reviewed-on: https://asterix-gerrit.ics.uci.edu/c/asterixdb/+/4723
Contrib: Jenkins <jenkins@fulliautomatix.ics.uci.edu>
Tested-by: Jenkins <jenkins@fulliautomatix.ics.uci.edu>
Integration-Tests: 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-app/src/test/resources/runtimets/queries_sqlpp/fun_return_null/numeric_fun/numeric_fun_003/numeric_fun_003.01.ddl.sqlpp b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/fun_return_null/numeric_fun/numeric_fun_003/numeric_fun_003.01.ddl.sqlpp
new file mode 100644
index 0000000..75f47b4
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/fun_return_null/numeric_fun/numeric_fun_003/numeric_fun_003.01.ddl.sqlpp
@@ -0,0 +1,35 @@
+/*
+ * 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.
+ */
+
+drop dataverse test if exists;
+create dataverse test;
+use test;
+
+create type t1 as {
+id : int,
+str1 : string,
+d1 : date,
+t1 : time,
+dt1 : datetime,
+dur1 : duration,
+ymd1 : `year_month_duration`,
+dtd1 : `day_time_duration`
+};
+
+create dataset ds1(t1) primary key id;
\ No newline at end of file
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/fun_return_null/numeric_fun/numeric_fun_003/numeric_fun_003.02.update.sqlpp b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/fun_return_null/numeric_fun/numeric_fun_003/numeric_fun_003.02.update.sqlpp
new file mode 100644
index 0000000..82baa7a
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/fun_return_null/numeric_fun/numeric_fun_003/numeric_fun_003.02.update.sqlpp
@@ -0,0 +1,32 @@
+/*
+ * 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.
+ */
+
+use test;
+
+insert into ds1([
+{
+"id": 1, "str1": "text", "str2": "text",
+"d1": date("2013-05-05"), "d2": date("2013-05-05"),
+"t1": time("12:12:12.039Z"), "t2": time("12:12:12.039Z"),
+"dt1": datetime("2012-08-20T10:10:00"), "dt2": datetime("2012-08-20T10:10:00"),
+"dur1": duration("P100Y12MT12M"), "dur1": duration("P100Y12MT12M"),
+"ymd1": year_month_duration("P2Y1M"), "ymd2": year_month_duration("P2Y1M"),
+"dtd1": `day_time_duration`('PT5M'), "dtd2": `day_time_duration`('PT5M')
+}
+]);
\ No newline at end of file
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/fun_return_null/numeric_fun/numeric_fun_003/numeric_fun_003.03.query.sqlpp b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/fun_return_null/numeric_fun/numeric_fun_003/numeric_fun_003.03.query.sqlpp
new file mode 100644
index 0000000..33281b2
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/fun_return_null/numeric_fun/numeric_fun_003/numeric_fun_003.03.query.sqlpp
@@ -0,0 +1,45 @@
+/*
+ * 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.
+ */
+
+/*
+ *  Description: tests reporting invalid argument type for numeric functions
+ */
+// requesttype=application/json
+// param max-warnings:json=1000
+
+use test;
+
+set `import-private-functions` "true";
+
+from ds1 as ds1
+select
+id + str1 as f1, str2 + id as f2, id + "text" as f3,
+id - str1 as f4, str2 - id as f5, id - "text" as f6,
+id * str1 as f7, str2 * id as f8, id * "text" as f9,
+id / str1 as f10, str2 / id as f11, id / "text" as f12,
+id DIV str1 as f13, str2 DIV id as f14, id DIV "text" as f15,
+id % str1 as f16, str2 % id as f17, id % "text" as f18,
+id ^ str1 as f19, str2 ^ id as f20, id ^ "text" as f21,
+
+d1 + str1 as f22, str2 - d2 as f23, d1 * "text" as f24,
+t1 + str1 as f25, str2 - t2 as f26, t1 / "text" as f27,
+dt1 + str1 as f28, str2 - dt2 as f29, dt1 DIV "text" as f30,
+dur1 + str1 as f31, str2 - dur2 as f32, dur1 % "text" as f33,
+ymd1 + str1 as f34, str2 - ymd2 as f35, ymd1 ^ "text" as f36,
+dtd1 + str1 as f37, str2 - dtd2 as f38, dtd1 * "text" as f39;
\ No newline at end of file
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/fun_return_null/numeric_fun/numeric_fun_003/numeric_fun_003.04.ddl.sqlpp b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/fun_return_null/numeric_fun/numeric_fun_003/numeric_fun_003.04.ddl.sqlpp
new file mode 100644
index 0000000..548e632
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/fun_return_null/numeric_fun/numeric_fun_003/numeric_fun_003.04.ddl.sqlpp
@@ -0,0 +1,20 @@
+/*
+ * 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.
+ */
+
+drop dataverse test if exists;
\ No newline at end of file
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/results/fun_return_null/numeric_fun/numeric_fun_003/numeric_fun_003.03.adm b/asterixdb/asterix-app/src/test/resources/runtimets/results/fun_return_null/numeric_fun/numeric_fun_003/numeric_fun_003.03.adm
new file mode 100644
index 0000000..91f6744
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/results/fun_return_null/numeric_fun/numeric_fun_003/numeric_fun_003.03.adm
@@ -0,0 +1 @@
+{ "f1": null, "f3": null, "f4": null, "f6": null, "f7": null, "f9": null, "f10": null, "f12": null, "f13": null, "f15": null, "f16": null, "f18": null, "f19": null, "f21": null, "f22": null, "f24": null, "f25": null, "f27": null, "f28": null, "f30": null, "f31": null, "f33": null, "f34": null, "f36": null, "f37": null, "f39": null, "f2": null, "f5": null, "f8": null, "f11": null, "f14": null, "f17": null, "f20": null, "f23": null, "f26": null, "f29": null, "f35": null, "f38": null }
\ No newline at end of file
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/testsuite_sqlpp.xml b/asterixdb/asterix-app/src/test/resources/runtimets/testsuite_sqlpp.xml
index c4c5e8f..3d3a98f 100644
--- a/asterixdb/asterix-app/src/test/resources/runtimets/testsuite_sqlpp.xml
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/testsuite_sqlpp.xml
@@ -13845,5 +13845,49 @@
         <source-location>false</source-location>
       </compilation-unit>
     </test-case>
+    <test-case FilePath="fun_return_null/numeric_fun" check-warnings="true">
+      <compilation-unit name="numeric_fun_003">
+        <output-dir compare="Text">numeric_fun_003</output-dir>
+        <expected-warn>Type mismatch: function numeric-add expects its 2nd input parameter to be of type tinyint, smallint, integer, bigint, float, double, date, time, datetime, duration, yearmonthduration or daytimeduration, but the actual input type is string</expected-warn>
+        <expected-warn>Type mismatch: function numeric-divide expects its 2nd input parameter to be of type tinyint, smallint, integer, bigint, float, double, date, time, datetime, duration, yearmonthduration or daytimeduration, but the actual input type is string</expected-warn>
+        <expected-warn>Type incompatibility: function numeric-multiply gets incompatible input values: daytimeduration and string</expected-warn>
+        <expected-warn>Type mismatch: function numeric-add expects its 1st input parameter to be of type tinyint, smallint, integer, bigint, float, double, date, time, datetime, duration, yearmonthduration or daytimeduration, but the actual input type is string</expected-warn>
+        <expected-warn>Type mismatch: function numeric-subtract expects its 1st input parameter to be of type tinyint, smallint, integer, bigint, float, double, date, time, datetime, duration, yearmonthduration or daytimeduration, but the actual input type is string</expected-warn>
+        <expected-warn>Type incompatibility: function numeric-divide gets incompatible input values: time and string</expected-warn>
+        <expected-warn>Type incompatibility: function numeric-add gets incompatible input values: yearmonthduration and string</expected-warn>
+        <expected-warn>Type mismatch: function numeric-subtract expects its 1st input parameter to be of type tinyint, smallint, integer, bigint, float, double, date, time, datetime, duration, yearmonthduration or daytimeduration, but the actual input type is string</expected-warn>
+        <expected-warn>Type mismatch: function numeric-multiply expects its 2nd input parameter to be of type tinyint, smallint, integer, bigint, float, double, date, time, datetime, duration, yearmonthduration or daytimeduration, but the actual input type is string</expected-warn>
+        <expected-warn>Type incompatibility: function numeric-add gets incompatible input values: daytimeduration and string</expected-warn>
+        <expected-warn>Type mismatch: function numeric-div expects its 2nd input parameter to be of type tinyint, smallint, integer, bigint, float, double, date, time, datetime, duration, yearmonthduration or daytimeduration, but the actual input type is string</expected-warn>
+        <expected-warn>Type mismatch: function numeric-subtract expects its 2nd input parameter to be of type tinyint, smallint, integer, bigint, float, double, date, time, datetime, duration, yearmonthduration or daytimeduration, but the actual input type is string</expected-warn>
+        <expected-warn>Type mismatch: function power expects its 2nd input parameter to be of type tinyint, smallint, integer, bigint, float, double, date, time, datetime, duration, yearmonthduration or daytimeduration, but the actual input type is string</expected-warn>
+        <expected-warn>Type mismatch: function numeric-mod expects its 2nd input parameter to be of type tinyint, smallint, integer, bigint, float, double, date, time, datetime, duration, yearmonthduration or daytimeduration, but the actual input type is string</expected-warn>
+        <expected-warn>Type incompatibility: function numeric-add gets incompatible input values: time and string</expected-warn>
+        <expected-warn>Type incompatibility: function power gets incompatible input values: yearmonthduration and string</expected-warn>
+        <expected-warn>Type mismatch: function numeric-multiply expects its 1st input parameter to be of type tinyint, smallint, integer, bigint, float, double, date, time, datetime, duration, yearmonthduration or daytimeduration, but the actual input type is string</expected-warn>
+        <expected-warn>Type mismatch: function numeric-multiply expects its 2nd input parameter to be of type tinyint, smallint, integer, bigint, float, double, date, time, datetime, duration, yearmonthduration or daytimeduration, but the actual input type is string</expected-warn>
+        <expected-warn>Type mismatch: function numeric-mod expects its 2nd input parameter to be of type tinyint, smallint, integer, bigint, float, double, date, time, datetime, duration, yearmonthduration or daytimeduration, but the actual input type is string</expected-warn>
+        <expected-warn>Type mismatch: function numeric-divide expects its 1st input parameter to be of type tinyint, smallint, integer, bigint, float, double, date, time, datetime, duration, yearmonthduration or daytimeduration, but the actual input type is string</expected-warn>
+        <expected-warn>Type mismatch: function numeric-div expects its 1st input parameter to be of type tinyint, smallint, integer, bigint, float, double, date, time, datetime, duration, yearmonthduration or daytimeduration, but the actual input type is string</expected-warn>
+        <expected-warn>Type incompatibility: function numeric-multiply gets incompatible input values: date and string</expected-warn>
+        <expected-warn>Type mismatch: function numeric-add expects its 2nd input parameter to be of type tinyint, smallint, integer, bigint, float, double, date, time, datetime, duration, yearmonthduration or daytimeduration, but the actual input type is string</expected-warn>
+        <expected-warn>Type incompatibility: function numeric-add gets incompatible input values: duration and string</expected-warn>
+        <expected-warn>Type incompatibility: function numeric-div gets incompatible input values: datetime and string</expected-warn>
+        <expected-warn>Type mismatch: function numeric-mod expects its 1st input parameter to be of type tinyint, smallint, integer, bigint, float, double, date, time, datetime, duration, yearmonthduration or daytimeduration, but the actual input type is string</expected-warn>
+        <expected-warn>Type mismatch: function power expects its 2nd input parameter to be of type tinyint, smallint, integer, bigint, float, double, date, time, datetime, duration, yearmonthduration or daytimeduration, but the actual input type is string</expected-warn>
+        <expected-warn>Type incompatibility: function numeric-add gets incompatible input values: date and string</expected-warn>
+        <expected-warn>Type incompatibility: function numeric-mod gets incompatible input values: duration and string</expected-warn>
+        <expected-warn>Type mismatch: function numeric-subtract expects its 2nd input parameter to be of type tinyint, smallint, integer, bigint, float, double, date, time, datetime, duration, yearmonthduration or daytimeduration, but the actual input type is string</expected-warn>
+        <expected-warn>Type mismatch: function numeric-subtract expects its 1st input parameter to be of type tinyint, smallint, integer, bigint, float, double, date, time, datetime, duration, yearmonthduration or daytimeduration, but the actual input type is string</expected-warn>
+        <expected-warn>Type mismatch: function numeric-divide expects its 2nd input parameter to be of type tinyint, smallint, integer, bigint, float, double, date, time, datetime, duration, yearmonthduration or daytimeduration, but the actual input type is string</expected-warn>
+        <expected-warn>Type mismatch: function numeric-subtract expects its 1st input parameter to be of type tinyint, smallint, integer, bigint, float, double, date, time, datetime, duration, yearmonthduration or daytimeduration, but the actual input type is string</expected-warn>
+        <expected-warn>Type mismatch: function numeric-subtract expects its 1st input parameter to be of type tinyint, smallint, integer, bigint, float, double, date, time, datetime, duration, yearmonthduration or daytimeduration, but the actual input type is string</expected-warn>
+        <expected-warn>Type mismatch: function numeric-div expects its 2nd input parameter to be of type tinyint, smallint, integer, bigint, float, double, date, time, datetime, duration, yearmonthduration or daytimeduration, but the actual input type is string</expected-warn>
+        <expected-warn>Type mismatch: function numeric-subtract expects its 1st input parameter to be of type tinyint, smallint, integer, bigint, float, double, date, time, datetime, duration, yearmonthduration or daytimeduration, but the actual input type is string</expected-warn>
+        <expected-warn>Type incompatibility: function numeric-add gets incompatible input values: datetime and string</expected-warn>
+        <expected-warn>Type mismatch: function power expects its 1st input parameter to be of type tinyint, smallint, integer, bigint, float, double, date, time, datetime, duration, yearmonthduration or daytimeduration, but the actual input type is string</expected-warn>
+        <source-location>false</source-location>
+      </compilation-unit>
+    </test-case>
   </test-group>
 </test-suite>
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 64d44bd..46a1268 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
@@ -1594,7 +1594,7 @@
         addPrivateFunction(AND, BooleanFunctionTypeComputer.INSTANCE, true);
         addPrivateFunction(NEQ, BooleanFunctionTypeComputer.INSTANCE, true);
         addPrivateFunction(OR, BooleanFunctionTypeComputer.INSTANCE, true);
-        addPrivateFunction(NUMERIC_ADD, NumericAddSubMulDivTypeComputer.INSTANCE, true);
+        addPrivateFunction(NUMERIC_ADD, NumericAddSubMulDivTypeComputer.INSTANCE_ADD, true);
 
         // deep equality
         addFunction(DEEP_EQUAL, BooleanFunctionTypeComputer.INSTANCE, true);
@@ -1652,11 +1652,11 @@
         addPrivateFunction(MAKE_FIELD_NAME_HANDLE, null, true);
 
         addPrivateFunction(NUMERIC_UNARY_MINUS, NumericUnaryTypeComputer.INSTANCE, true);
-        addPrivateFunction(NUMERIC_SUBTRACT, NumericAddSubMulDivTypeComputer.INSTANCE, true);
-        addPrivateFunction(NUMERIC_MULTIPLY, NumericAddSubMulDivTypeComputer.INSTANCE, true);
+        addPrivateFunction(NUMERIC_SUBTRACT, NumericAddSubMulDivTypeComputer.INSTANCE_SUB, true);
+        addPrivateFunction(NUMERIC_MULTIPLY, NumericAddSubMulDivTypeComputer.INSTANCE_MUL_POW, true);
         addPrivateFunction(NUMERIC_DIVIDE, NumericDivideTypeComputer.INSTANCE, true);
-        addPrivateFunction(NUMERIC_MOD, NumericAddSubMulDivTypeComputer.INSTANCE_NULLABLE, true);
-        addPrivateFunction(NUMERIC_DIV, NumericAddSubMulDivTypeComputer.INSTANCE_NULLABLE, true);
+        addPrivateFunction(NUMERIC_MOD, NumericAddSubMulDivTypeComputer.INSTANCE_DIV_MOD, true);
+        addPrivateFunction(NUMERIC_DIV, NumericAddSubMulDivTypeComputer.INSTANCE_DIV_MOD, true);
         addFunction(NUMERIC_ABS, NumericUnaryTypeComputer.INSTANCE, true);
         addFunction(NUMERIC_ACOS, NumericUnaryTypeComputer.INSTANCE_DOUBLE, true);
         addFunction(NUMERIC_ASIN, NumericUnaryTypeComputer.INSTANCE_DOUBLE, true);
@@ -1675,7 +1675,7 @@
         addFunction(NUMERIC_LN, NumericUnaryTypeComputer.INSTANCE_DOUBLE, true);
         addFunction(NUMERIC_LOG, NumericUnaryTypeComputer.INSTANCE_DOUBLE, true);
         addFunction(NUMERIC_PI, ADoubleTypeComputer.INSTANCE, true);
-        addFunction(NUMERIC_POWER, NumericAddSubMulDivTypeComputer.INSTANCE, true);
+        addFunction(NUMERIC_POWER, NumericAddSubMulDivTypeComputer.INSTANCE_MUL_POW, true);
         addFunction(NUMERIC_SQRT, NumericUnaryTypeComputer.INSTANCE_DOUBLE, true);
         addFunction(NUMERIC_SIGN, NumericUnaryTypeComputer.INSTANCE_INT8, true);
         addFunction(NUMERIC_CEILING, NumericUnaryTypeComputer.INSTANCE, true);
diff --git a/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/typecomputer/impl/NumericAddSubMulDivTypeComputer.java b/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/typecomputer/impl/NumericAddSubMulDivTypeComputer.java
index 81cf905..ee78393 100644
--- a/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/typecomputer/impl/NumericAddSubMulDivTypeComputer.java
+++ b/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/typecomputer/impl/NumericAddSubMulDivTypeComputer.java
@@ -18,7 +18,6 @@
  */
 package org.apache.asterix.om.typecomputer.impl;
 
-import org.apache.asterix.om.exceptions.IncompatibleTypeException;
 import org.apache.asterix.om.typecomputer.base.AbstractResultTypeComputer;
 import org.apache.asterix.om.types.ATypeTag;
 import org.apache.asterix.om.types.AUnionType;
@@ -26,30 +25,39 @@
 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.AbstractFunctionCallExpression;
-import org.apache.hyracks.algebricks.core.algebra.functions.FunctionIdentifier;
 
 public class NumericAddSubMulDivTypeComputer extends AbstractResultTypeComputer {
     /**
      * For those functions that do not return NULL if both arguments are not NULL
      */
-    public static final NumericAddSubMulDivTypeComputer INSTANCE = new NumericAddSubMulDivTypeComputer(false);
+    public static final NumericAddSubMulDivTypeComputer INSTANCE_MUL_POW =
+            new NumericAddSubMulDivTypeComputer(false, false, false);
 
     /**
      * For those functions that may return NULL even if both arguments are not NULL (e.g. division by zero)
      */
-    public static final NumericAddSubMulDivTypeComputer INSTANCE_NULLABLE = new NumericAddSubMulDivTypeComputer(true);
+    public static final NumericAddSubMulDivTypeComputer INSTANCE_DIV_MOD =
+            new NumericAddSubMulDivTypeComputer(true, false, false);
+
+    public static final NumericAddSubMulDivTypeComputer INSTANCE_ADD =
+            new NumericAddSubMulDivTypeComputer(false, true, false);
+
+    public static final NumericAddSubMulDivTypeComputer INSTANCE_SUB =
+            new NumericAddSubMulDivTypeComputer(false, true, true);
 
     private final boolean nullable;
+    private final boolean isMixedTemporalAllowed;
+    private final boolean isSameTemporalAllowed;
 
-    private NumericAddSubMulDivTypeComputer(boolean nullable) {
+    private NumericAddSubMulDivTypeComputer(boolean nullable, boolean isMixedTemporalAllowed,
+            boolean isSameTemporalAllowed) {
         this.nullable = nullable;
+        this.isMixedTemporalAllowed = isMixedTemporalAllowed;
+        this.isSameTemporalAllowed = isSameTemporalAllowed;
     }
 
     @Override
     protected IAType getResultType(ILogicalExpression expr, IAType... strippedInputTypes) throws AlgebricksException {
-        AbstractFunctionCallExpression funcExpr = (AbstractFunctionCallExpression) expr;
-        FunctionIdentifier funcId = funcExpr.getFunctionIdentifier();
         IAType t1 = strippedInputTypes[0];
         IAType t2 = strippedInputTypes[1];
         ATypeTag tag1 = t1.getTypeTag();
@@ -71,7 +79,7 @@
                         type = BuiltinType.ANY;
                         break;
                     default:
-                        throw new IncompatibleTypeException(funcExpr.getSourceLocation(), funcId, tag1, tag2);
+                        return BuiltinType.ANULL;
                 }
                 break;
             case FLOAT:
@@ -90,7 +98,7 @@
                         type = BuiltinType.ANY;
                         break;
                     default:
-                        throw new IncompatibleTypeException(funcExpr.getSourceLocation(), funcId, tag1, tag2);
+                        return BuiltinType.ANULL;
                 }
                 break;
             case BIGINT:
@@ -111,7 +119,7 @@
                         type = BuiltinType.ANY;
                         break;
                     default:
-                        throw new IncompatibleTypeException(funcExpr.getSourceLocation(), funcId, tag1, tag2);
+                        return BuiltinType.ANULL;
                 }
                 break;
             case INTEGER:
@@ -134,7 +142,7 @@
                         type = BuiltinType.ANY;
                         break;
                     default:
-                        throw new IncompatibleTypeException(funcExpr.getSourceLocation(), funcId, tag1, tag2);
+                        return BuiltinType.ANULL;
                 }
                 break;
             case SMALLINT:
@@ -159,7 +167,7 @@
                         type = BuiltinType.ANY;
                         break;
                     default:
-                        throw new IncompatibleTypeException(funcExpr.getSourceLocation(), funcId, tag1, tag2);
+                        return BuiltinType.ANULL;
                 }
                 break;
             case TINYINT:
@@ -186,7 +194,7 @@
                         type = BuiltinType.ANY;
                         break;
                     default:
-                        throw new IncompatibleTypeException(funcExpr.getSourceLocation(), funcId, tag1, tag2);
+                        return BuiltinType.ANULL;
                 }
                 break;
             case ANY:
@@ -207,119 +215,173 @@
                         type = BuiltinType.ANY;
                         break;
                     default:
-                        throw new IncompatibleTypeException(funcExpr.getSourceLocation(), funcId, tag1, tag2);
+                        return BuiltinType.ANULL;
                 }
                 break;
             case DATE:
                 switch (tag2) {
                     case DATE:
+                        if (!isSameTemporalAllowed) {
+                            return BuiltinType.ANULL;
+                        }
                         type = BuiltinType.ADURATION;
                         break;
                     case YEARMONTHDURATION:
                     case DAYTIMEDURATION:
                     case DURATION:
+                        if (!isMixedTemporalAllowed) {
+                            return BuiltinType.ANULL;
+                        }
                         type = BuiltinType.ADATE;
                         break;
                     case ANY:
                         type = BuiltinType.ANY;
                         break;
                     default:
-                        throw new IncompatibleTypeException(funcExpr.getSourceLocation(), funcId, tag1, tag2);
+                        return BuiltinType.ANULL;
                 }
                 break;
             case TIME:
                 switch (tag2) {
                     case TIME:
+                        if (!isSameTemporalAllowed) {
+                            return BuiltinType.ANULL;
+                        }
                         type = BuiltinType.ADURATION;
                         break;
                     case YEARMONTHDURATION:
+                        return BuiltinType.ANULL;
                     case DAYTIMEDURATION:
                     case DURATION:
+                        if (!isMixedTemporalAllowed) {
+                            return BuiltinType.ANULL;
+                        }
+                        // TODO(ali): check the runtime consistency of DURATION op TIME vs. TIME op DURATION
                         type = BuiltinType.ATIME;
                         break;
                     case ANY:
                         type = BuiltinType.ANY;
                         break;
                     default:
-                        throw new IncompatibleTypeException(funcExpr.getSourceLocation(), funcId, tag1, tag2);
+                        return BuiltinType.ANULL;
                 }
                 break;
             case DATETIME:
                 switch (tag2) {
                     case DATETIME:
+                        if (!isSameTemporalAllowed) {
+                            return BuiltinType.ANULL;
+                        }
                         type = BuiltinType.ADURATION;
                         break;
                     case YEARMONTHDURATION:
                     case DAYTIMEDURATION:
                     case DURATION:
-                        type = BuiltinType.ADATETIME;
-                        break;
-                    default:
-                        throw new IncompatibleTypeException(funcExpr.getSourceLocation(), funcId, tag1, tag2);
-                }
-                break;
-            case DURATION:
-                switch (tag2) {
-                    case DATE:
-                        type = BuiltinType.ADATE;
-                        break;
-                    case TIME:
-                        type = BuiltinType.ATIME;
-                        break;
-                    case DATETIME:
+                        if (!isMixedTemporalAllowed) {
+                            return BuiltinType.ANULL;
+                        }
                         type = BuiltinType.ADATETIME;
                         break;
                     case ANY:
                         type = BuiltinType.ANY;
                         break;
                     default:
-                        throw new IncompatibleTypeException(funcExpr.getSourceLocation(), funcId, tag1, tag2);
+                        return BuiltinType.ANULL;
+                }
+                break;
+            case DURATION:
+                switch (tag2) {
+                    case DATE:
+                        if (!isMixedTemporalAllowed) {
+                            return BuiltinType.ANULL;
+                        }
+                        type = BuiltinType.ADATE;
+                        break;
+                    case TIME:
+                        if (!isMixedTemporalAllowed) {
+                            return BuiltinType.ANULL;
+                        }
+                        // TODO(ali): check the runtime consistency of DURATION op TIME and TIME op DURATION
+                        // depending on the runtime values the operation might be invalid and produce NULL
+                        type = AUnionType.createNullableType(BuiltinType.ATIME);
+                        break;
+                    case DATETIME:
+                        if (!isMixedTemporalAllowed) {
+                            return BuiltinType.ANULL;
+                        }
+                        type = BuiltinType.ADATETIME;
+                        break;
+                    case ANY:
+                        type = BuiltinType.ANY;
+                        break;
+                    default:
+                        return BuiltinType.ANULL;
                 }
                 break;
             case YEARMONTHDURATION:
                 switch (tag2) {
                     case DATE:
+                        if (!isMixedTemporalAllowed) {
+                            return BuiltinType.ANULL;
+                        }
                         type = BuiltinType.ADATE;
                         break;
                     case TIME:
-                        type = BuiltinType.ATIME;
-                        break;
+                        return BuiltinType.ANULL;
                     case DATETIME:
+                        if (!isMixedTemporalAllowed) {
+                            return BuiltinType.ANULL;
+                        }
                         type = BuiltinType.ADATETIME;
                         break;
                     case YEARMONTHDURATION:
+                        if (!isSameTemporalAllowed) {
+                            return BuiltinType.ANULL;
+                        }
                         type = BuiltinType.AYEARMONTHDURATION;
                         break;
                     case ANY:
                         type = BuiltinType.ANY;
                         break;
                     default:
-                        throw new IncompatibleTypeException(funcExpr.getSourceLocation(), funcId, tag1, tag2);
+                        return BuiltinType.ANULL;
                 }
                 break;
             case DAYTIMEDURATION:
                 switch (tag2) {
                     case DATE:
+                        if (!isMixedTemporalAllowed) {
+                            return BuiltinType.ANULL;
+                        }
                         type = BuiltinType.ADATE;
                         break;
                     case TIME:
+                        if (!isMixedTemporalAllowed) {
+                            return BuiltinType.ANULL;
+                        }
                         type = BuiltinType.ATIME;
                         break;
                     case DATETIME:
+                        if (!isMixedTemporalAllowed) {
+                            return BuiltinType.ANULL;
+                        }
                         type = BuiltinType.ADATETIME;
                         break;
                     case DAYTIMEDURATION:
+                        if (!isSameTemporalAllowed) {
+                            return BuiltinType.ANULL;
+                        }
                         type = BuiltinType.ADAYTIMEDURATION;
                         break;
                     case ANY:
                         type = BuiltinType.ANY;
                         break;
                     default:
-                        throw new IncompatibleTypeException(funcExpr.getSourceLocation(), funcId, tag1, tag2);
+                        return BuiltinType.ANULL;
                 }
                 break;
             default:
-                throw new IncompatibleTypeException(funcExpr.getSourceLocation(), funcId, tag1, tag2);
+                return BuiltinType.ANULL;
         }
 
         if (nullable && type.getTypeTag() != ATypeTag.ANY) {
diff --git a/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/typecomputer/impl/NumericDivideTypeComputer.java b/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/typecomputer/impl/NumericDivideTypeComputer.java
index 0a130f0..775f0ed 100644
--- a/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/typecomputer/impl/NumericDivideTypeComputer.java
+++ b/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/typecomputer/impl/NumericDivideTypeComputer.java
@@ -19,7 +19,6 @@
 
 package org.apache.asterix.om.typecomputer.impl;
 
-import org.apache.asterix.om.exceptions.IncompatibleTypeException;
 import org.apache.asterix.om.typecomputer.base.AbstractResultTypeComputer;
 import org.apache.asterix.om.types.ATypeTag;
 import org.apache.asterix.om.types.AUnionType;
@@ -27,8 +26,6 @@
 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.AbstractFunctionCallExpression;
-import org.apache.hyracks.algebricks.core.algebra.functions.FunctionIdentifier;
 
 /**
  * Returns double if both operands are integers
@@ -41,8 +38,6 @@
 
     @Override
     protected IAType getResultType(ILogicalExpression expr, IAType... strippedInputTypes) throws AlgebricksException {
-        AbstractFunctionCallExpression funcExpr = (AbstractFunctionCallExpression) expr;
-        FunctionIdentifier funcId = funcExpr.getFunctionIdentifier();
         IAType t1 = strippedInputTypes[0];
         IAType t2 = strippedInputTypes[1];
         ATypeTag tag1 = t1.getTypeTag();
@@ -64,7 +59,7 @@
                         type = BuiltinType.ANY;
                         break;
                     default:
-                        throw new IncompatibleTypeException(funcExpr.getSourceLocation(), funcId, tag1, tag2);
+                        return BuiltinType.ANULL;
                 }
                 break;
             case FLOAT:
@@ -83,7 +78,7 @@
                         type = BuiltinType.ANY;
                         break;
                     default:
-                        throw new IncompatibleTypeException(funcExpr.getSourceLocation(), funcId, tag1, tag2);
+                        return BuiltinType.ANULL;
                 }
                 break;
             case BIGINT:
@@ -105,7 +100,7 @@
                         type = BuiltinType.ANY;
                         break;
                     default:
-                        throw new IncompatibleTypeException(funcExpr.getSourceLocation(), funcId, tag1, tag2);
+                        return BuiltinType.ANULL;
                 }
                 break;
             case ANY:
@@ -120,119 +115,11 @@
                         type = BuiltinType.ANY;
                         break;
                     default:
-                        throw new IncompatibleTypeException(funcExpr.getSourceLocation(), funcId, tag1, tag2);
-                }
-                break;
-            case DATE:
-                switch (tag2) {
-                    case DATE:
-                        type = BuiltinType.ADURATION;
-                        break;
-                    case YEARMONTHDURATION:
-                    case DAYTIMEDURATION:
-                    case DURATION:
-                        type = BuiltinType.ADATE;
-                        break;
-                    case ANY:
-                        type = BuiltinType.ANY;
-                        break;
-                    default:
-                        throw new IncompatibleTypeException(funcExpr.getSourceLocation(), funcId, tag1, tag2);
-                }
-                break;
-            case TIME:
-                switch (tag2) {
-                    case TIME:
-                        type = BuiltinType.ADURATION;
-                        break;
-                    case YEARMONTHDURATION:
-                    case DAYTIMEDURATION:
-                    case DURATION:
-                        type = BuiltinType.ATIME;
-                        break;
-                    case ANY:
-                        type = BuiltinType.ANY;
-                        break;
-                    default:
-                        throw new IncompatibleTypeException(funcExpr.getSourceLocation(), funcId, tag1, tag2);
-                }
-                break;
-            case DATETIME:
-                switch (tag2) {
-                    case DATETIME:
-                        type = BuiltinType.ADURATION;
-                        break;
-                    case YEARMONTHDURATION:
-                    case DAYTIMEDURATION:
-                    case DURATION:
-                        type = BuiltinType.ADATETIME;
-                        break;
-                    default:
-                        throw new IncompatibleTypeException(funcExpr.getSourceLocation(), funcId, tag1, tag2);
-                }
-                break;
-            case DURATION:
-                switch (tag2) {
-                    case DATE:
-                        type = BuiltinType.ADATE;
-                        break;
-                    case TIME:
-                        type = BuiltinType.ATIME;
-                        break;
-                    case DATETIME:
-                        type = BuiltinType.ADATETIME;
-                        break;
-                    case ANY:
-                        type = BuiltinType.ANY;
-                        break;
-                    default:
-                        throw new IncompatibleTypeException(funcExpr.getSourceLocation(), funcId, tag1, tag2);
-                }
-                break;
-            case YEARMONTHDURATION:
-                switch (tag2) {
-                    case DATE:
-                        type = BuiltinType.ADATE;
-                        break;
-                    case TIME:
-                        type = BuiltinType.ATIME;
-                        break;
-                    case DATETIME:
-                        type = BuiltinType.ADATETIME;
-                        break;
-                    case YEARMONTHDURATION:
-                        type = BuiltinType.AYEARMONTHDURATION;
-                        break;
-                    case ANY:
-                        type = BuiltinType.ANY;
-                        break;
-                    default:
-                        throw new IncompatibleTypeException(funcExpr.getSourceLocation(), funcId, tag1, tag2);
-                }
-                break;
-            case DAYTIMEDURATION:
-                switch (tag2) {
-                    case DATE:
-                        type = BuiltinType.ADATE;
-                        break;
-                    case TIME:
-                        type = BuiltinType.ATIME;
-                        break;
-                    case DATETIME:
-                        type = BuiltinType.ADATETIME;
-                        break;
-                    case DAYTIMEDURATION:
-                        type = BuiltinType.ADAYTIMEDURATION;
-                        break;
-                    case ANY:
-                        type = BuiltinType.ANY;
-                        break;
-                    default:
-                        throw new IncompatibleTypeException(funcExpr.getSourceLocation(), funcId, tag1, tag2);
+                        return BuiltinType.ANULL;
                 }
                 break;
             default:
-                throw new IncompatibleTypeException(funcExpr.getSourceLocation(), funcId, tag1, tag2);
+                return BuiltinType.ANULL;
         }
 
         if (type.getTypeTag() != ATypeTag.ANY) {
diff --git a/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/AbstractNumericArithmeticEval.java b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/AbstractNumericArithmeticEval.java
index 78a5696..3392706 100644
--- a/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/AbstractNumericArithmeticEval.java
+++ b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/AbstractNumericArithmeticEval.java
@@ -45,15 +45,14 @@
 import org.apache.asterix.om.base.AMutableTime;
 import org.apache.asterix.om.base.ANull;
 import org.apache.asterix.om.base.temporal.GregorianCalendarSystem;
+import org.apache.asterix.om.exceptions.ExceptionUtil;
 import org.apache.asterix.om.types.ATypeTag;
 import org.apache.asterix.om.types.BuiltinType;
 import org.apache.asterix.om.types.EnumDeserializer;
 import org.apache.asterix.runtime.evaluators.base.AbstractScalarFunctionDynamicDescriptor;
-import org.apache.asterix.runtime.exceptions.IncompatibleTypeException;
 import org.apache.asterix.runtime.exceptions.OverflowException;
-import org.apache.asterix.runtime.exceptions.TypeMismatchException;
 import org.apache.asterix.runtime.exceptions.UnderflowException;
-import org.apache.asterix.runtime.exceptions.UnsupportedTypeException;
+import org.apache.hyracks.algebricks.core.algebra.functions.FunctionIdentifier;
 import org.apache.hyracks.algebricks.runtime.base.IEvaluatorContext;
 import org.apache.hyracks.algebricks.runtime.base.IScalarEvaluator;
 import org.apache.hyracks.algebricks.runtime.base.IScalarEvaluatorFactory;
@@ -75,7 +74,7 @@
      * @param result result holder
      * @return {@code false} if the result is {@code NULL}, otherwise {@code true}
      */
-    abstract protected boolean evaluateInteger(long lhs, long rhs, AMutableInt64 result) throws HyracksDataException;
+    protected abstract boolean evaluateInteger(long lhs, long rhs, AMutableInt64 result) throws HyracksDataException;
 
     /**
      * abstract method for arithmetic operation between two floating point values
@@ -85,7 +84,7 @@
      * @param result result holder
      * @return {@code false} if the result is {@code NULL}, otherwise {@code true}
      */
-    abstract protected boolean evaluateDouble(double lhs, double rhs, AMutableDouble result)
+    protected abstract boolean evaluateDouble(double lhs, double rhs, AMutableDouble result)
             throws HyracksDataException;
 
     /**
@@ -96,10 +95,11 @@
      * @param yearMonth year-month component of the second operand
      * @param dayTime day-time component of the second operand
      * @param result result holder
+     * @param ctx evaluator context
      * @return {@code false} if the result is {@code NULL}, otherwise {@code true}
      */
-    abstract protected boolean evaluateTimeDurationArithmetic(long chronon, int yearMonth, long dayTime,
-            boolean isTimeOnly, AMutableInt64 result) throws HyracksDataException;
+    protected abstract boolean evaluateTimeDurationArithmetic(long chronon, int yearMonth, long dayTime,
+            boolean isTimeOnly, AMutableInt64 result, IEvaluatorContext ctx) throws HyracksDataException;
 
     /**
      * abstract method for arithmetic operation between two time instances (date/time/datetime)
@@ -107,10 +107,11 @@
      * @param chronon0 first operand
      * @param chronon1 second operand
      * @param result result holder
+     * @param ctx evaluator context
      * @return {@code false} if the result is {@code NULL}, otherwise {@code true}
      */
-    abstract protected boolean evaluateTimeInstanceArithmetic(long chronon0, long chronon1, AMutableInt64 result)
-            throws HyracksDataException;
+    protected abstract boolean evaluateTimeInstanceArithmetic(long chronon0, long chronon1, AMutableInt64 result,
+            IEvaluatorContext ctx) throws HyracksDataException;
 
     @Override
     public IScalarEvaluatorFactory createEvaluatorFactory(final IScalarEvaluatorFactory[] args) {
@@ -142,6 +143,8 @@
                     private final AMutableTime aTime = new AMutableTime(0);
                     private final AMutableDateTime aDatetime = new AMutableDateTime(0);
 
+                    private final FunctionIdentifier funID = getIdentifier();
+
                     @SuppressWarnings("rawtypes")
                     private final ISerializerDeserializer int8Serde =
                             SerializerDeserializerProvider.INSTANCE.getSerializerDeserializer(BuiltinType.AINT8);
@@ -176,6 +179,14 @@
                     private final ISerializerDeserializer nullSerde =
                             SerializerDeserializerProvider.INSTANCE.getSerializerDeserializer(BuiltinType.ANULL);
 
+                    private final byte[] EXP_TYPES = new byte[] { ATypeTag.SERIALIZED_INT8_TYPE_TAG,
+                            ATypeTag.SERIALIZED_INT16_TYPE_TAG, ATypeTag.SERIALIZED_INT32_TYPE_TAG,
+                            ATypeTag.SERIALIZED_INT64_TYPE_TAG, ATypeTag.SERIALIZED_FLOAT_TYPE_TAG,
+                            ATypeTag.SERIALIZED_DOUBLE_TYPE_TAG, ATypeTag.SERIALIZED_DATE_TYPE_TAG,
+                            ATypeTag.SERIALIZED_TIME_TYPE_TAG, ATypeTag.SERIALIZED_DATETIME_TYPE_TAG,
+                            ATypeTag.SERIALIZED_DURATION_TYPE_TAG, ATypeTag.SERIALIZED_YEAR_MONTH_DURATION_TYPE_TAG,
+                            ATypeTag.SERIALIZED_DAY_TIME_DURATION_TYPE_TAG };
+
                     @Override
                     @SuppressWarnings("unchecked")
                     public void evaluate(IFrameTupleReference tuple, IPointable result) throws HyracksDataException {
@@ -232,19 +243,13 @@
                                 case DURATION:
                                 case YEARMONTHDURATION:
                                 case DAYTIMEDURATION:
-                                    evaluateTemporalArithmeticOperation(typeTag);
+                                    evaluateTemporalArithmeticOperation();
                                     result.set(resultStorage);
                                     return;
                                 default:
-                                    throw new TypeMismatchException(sourceLoc, getIdentifier(), i, bytes[offset],
-                                            ATypeTag.SERIALIZED_INT8_TYPE_TAG, ATypeTag.SERIALIZED_INT16_TYPE_TAG,
-                                            ATypeTag.SERIALIZED_INT32_TYPE_TAG, ATypeTag.SERIALIZED_INT64_TYPE_TAG,
-                                            ATypeTag.SERIALIZED_FLOAT_TYPE_TAG, ATypeTag.SERIALIZED_DOUBLE_TYPE_TAG,
-                                            ATypeTag.SERIALIZED_DATE_TYPE_TAG, ATypeTag.SERIALIZED_TIME_TYPE_TAG,
-                                            ATypeTag.SERIALIZED_DATETIME_TYPE_TAG,
-                                            ATypeTag.SERIALIZED_DURATION_TYPE_TAG,
-                                            ATypeTag.SERIALIZED_YEAR_MONTH_DURATION_TYPE_TAG,
-                                            ATypeTag.SERIALIZED_DAY_TIME_DURATION_TYPE_TAG);
+                                    ExceptionUtil.warnTypeMismatch(ctx, sourceLoc, funID, bytes[offset], i, EXP_TYPES);
+                                    PointableHelper.setNull(result);
+                                    return;
                             }
 
                             if (i == 0 || currentType.ordinal() > argTypeMax.ordinal()) {
@@ -338,12 +343,13 @@
                     }
 
                     @SuppressWarnings("unchecked")
-                    private void evaluateTemporalArithmeticOperation(ATypeTag leftType) throws HyracksDataException {
+                    private void evaluateTemporalArithmeticOperation() throws HyracksDataException {
                         byte[] bytes1 = argPtr1.getByteArray();
                         int offset1 = argPtr1.getStartOffset();
                         ATypeTag rightType = EnumDeserializer.ATYPETAGDESERIALIZER.deserialize(bytes1[offset1]);
                         byte[] bytes0 = argPtr0.getByteArray();
                         int offset0 = argPtr0.getStartOffset();
+                        ATypeTag leftType = EnumDeserializer.ATYPETAGDESERIALIZER.deserialize(bytes0[offset0]);
 
                         if (rightType == leftType) {
                             long leftChronon = 0, rightChronon = 0, dayTime = 0;
@@ -369,7 +375,7 @@
                                     if (evaluateTimeInstanceArithmetic(
                                             AYearMonthDurationSerializerDeserializer.getYearMonth(bytes0, offset0 + 1),
                                             AYearMonthDurationSerializerDeserializer.getYearMonth(bytes1, offset1 + 1),
-                                            aInt64)) {
+                                            aInt64, ctx)) {
                                         yearMonth = (int) aInt64.getLongValue();
                                     } else {
                                         yearMonthIsNull = true;
@@ -382,10 +388,12 @@
                                             ADayTimeDurationSerializerDeserializer.getDayTime(bytes1, offset1 + 1);
                                     break;
                                 default:
-                                    throw new UnsupportedTypeException(sourceLoc, getIdentifier(), bytes1[offset1]);
+                                    ExceptionUtil.warnUnsupportedType(ctx, sourceLoc, funID.getName(), rightType);
+                                    nullSerde.serialize(ANull.NULL, out);
+                                    return;
                             }
 
-                            if (evaluateTimeInstanceArithmetic(leftChronon, rightChronon, aInt64)) {
+                            if (evaluateTimeInstanceArithmetic(leftChronon, rightChronon, aInt64, ctx)) {
                                 dayTime = aInt64.getLongValue();
                             } else {
                                 dayTimeIsNull = true;
@@ -423,8 +431,10 @@
                                                     ADurationSerializerDeserializer.getYearMonth(bytes1, offset1 + 1);
                                             break;
                                         default:
-                                            throw new IncompatibleTypeException(sourceLoc, getIdentifier(),
-                                                    bytes0[offset0], bytes1[offset1]);
+                                            ExceptionUtil.warnIncompatibleType(ctx, sourceLoc, funID.getName(),
+                                                    leftType, rightType);
+                                            nullSerde.serialize(ANull.NULL, out);
+                                            return;
                                     }
                                     break;
                                 case DATE:
@@ -453,8 +463,10 @@
                                                     offset1 + 1);
                                             break;
                                         default:
-                                            throw new IncompatibleTypeException(sourceLoc, getIdentifier(),
-                                                    bytes0[offset0], bytes1[offset1]);
+                                            ExceptionUtil.warnIncompatibleType(ctx, sourceLoc, funID.getName(),
+                                                    leftType, rightType);
+                                            nullSerde.serialize(ANull.NULL, out);
+                                            return;
                                     }
                                     break;
                                 case YEARMONTHDURATION:
@@ -473,8 +485,10 @@
                                                     * GregorianCalendarSystem.CHRONON_OF_DAY;
                                             break;
                                         default:
-                                            throw new IncompatibleTypeException(sourceLoc, getIdentifier(),
-                                                    bytes0[offset0], bytes1[offset1]);
+                                            ExceptionUtil.warnIncompatibleType(ctx, sourceLoc, funID.getName(),
+                                                    leftType, rightType);
+                                            nullSerde.serialize(ANull.NULL, out);
+                                            return;
                                     }
                                     break;
                                 case DURATION:
@@ -506,16 +520,20 @@
                                                 break;
                                             }
                                         default:
-                                            throw new IncompatibleTypeException(sourceLoc, getIdentifier(),
-                                                    bytes0[offset0], bytes1[offset1]);
+                                            ExceptionUtil.warnIncompatibleType(ctx, sourceLoc, funID.getName(),
+                                                    leftType, rightType);
+                                            nullSerde.serialize(ANull.NULL, out);
+                                            return;
                                     }
                                     break;
                                 default:
-                                    throw new IncompatibleTypeException(sourceLoc, getIdentifier(), bytes0[offset0],
-                                            bytes1[offset1]);
+                                    ExceptionUtil.warnIncompatibleType(ctx, sourceLoc, funID.getName(), leftType,
+                                            rightType);
+                                    nullSerde.serialize(ANull.NULL, out);
+                                    return;
                             }
 
-                            if (evaluateTimeDurationArithmetic(chronon, yearMonth, dayTime, isTimeOnly, aInt64)) {
+                            if (evaluateTimeDurationArithmetic(chronon, yearMonth, dayTime, isTimeOnly, aInt64, ctx)) {
                                 chronon = aInt64.getLongValue();
                                 switch (resultType) {
                                     case DATE:
@@ -536,8 +554,10 @@
                                         serde.serialize(aDatetime, out);
                                         break;
                                     default:
-                                        throw new IncompatibleTypeException(sourceLoc, getIdentifier(), bytes0[offset0],
-                                                bytes1[offset1]);
+                                        ExceptionUtil.warnIncompatibleType(ctx, sourceLoc, funID.getName(), leftType,
+                                                rightType);
+                                        nullSerde.serialize(ANull.NULL, out);
+                                        return;
                                 }
                             } else {
                                 nullSerde.serialize(ANull.NULL, out);
diff --git a/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/NumericAddDescriptor.java b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/NumericAddDescriptor.java
index 1ffebe8..f82cb7c 100644
--- a/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/NumericAddDescriptor.java
+++ b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/NumericAddDescriptor.java
@@ -22,13 +22,14 @@
 import org.apache.asterix.om.base.AMutableDouble;
 import org.apache.asterix.om.base.AMutableInt64;
 import org.apache.asterix.om.base.temporal.DurationArithmeticOperations;
+import org.apache.asterix.om.exceptions.ExceptionUtil;
 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.runtime.exceptions.OverflowException;
-import org.apache.asterix.runtime.exceptions.UnsupportedTypeException;
 import org.apache.hyracks.algebricks.core.algebra.functions.FunctionIdentifier;
+import org.apache.hyracks.algebricks.runtime.base.IEvaluatorContext;
 import org.apache.hyracks.api.exceptions.HyracksDataException;
 
 @MissingNullInOutFunction
@@ -66,15 +67,16 @@
 
     @Override
     protected boolean evaluateTimeDurationArithmetic(long chronon, int yearMonth, long dayTime, boolean isTimeOnly,
-            AMutableInt64 result) throws HyracksDataException {
+            AMutableInt64 result, IEvaluatorContext ctx) throws HyracksDataException {
         long res = DurationArithmeticOperations.addDuration(chronon, yearMonth, dayTime, isTimeOnly);
         result.setValue(res);
         return true;
     }
 
     @Override
-    protected boolean evaluateTimeInstanceArithmetic(long chronon0, long chronon1, AMutableInt64 result)
-            throws HyracksDataException {
-        throw new UnsupportedTypeException(sourceLoc, getIdentifier(), ATypeTag.SERIALIZED_TIME_TYPE_TAG);
+    protected boolean evaluateTimeInstanceArithmetic(long chronon0, long chronon1, AMutableInt64 result,
+            IEvaluatorContext ctx) throws HyracksDataException {
+        ExceptionUtil.warnUnsupportedType(ctx, sourceLoc, getIdentifier().getName(), ATypeTag.TIME);
+        return false;
     }
 }
diff --git a/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/NumericDivDescriptor.java b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/NumericDivDescriptor.java
index 745f6ef..dbd5251 100644
--- a/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/NumericDivDescriptor.java
+++ b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/NumericDivDescriptor.java
@@ -22,14 +22,14 @@
 import org.apache.asterix.common.annotations.MissingNullInOutFunction;
 import org.apache.asterix.om.base.AMutableDouble;
 import org.apache.asterix.om.base.AMutableInt64;
+import org.apache.asterix.om.exceptions.ExceptionUtil;
 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.runtime.exceptions.OverflowException;
-import org.apache.asterix.runtime.exceptions.UnsupportedTypeException;
-import org.apache.hyracks.algebricks.common.exceptions.NotImplementedException;
 import org.apache.hyracks.algebricks.core.algebra.functions.FunctionIdentifier;
+import org.apache.hyracks.algebricks.runtime.base.IEvaluatorContext;
 import org.apache.hyracks.api.exceptions.HyracksDataException;
 
 @MissingNullInOutFunction
@@ -72,13 +72,15 @@
 
     @Override
     protected boolean evaluateTimeDurationArithmetic(long chronon, int yearMonth, long dayTime, boolean isTimeOnly,
-            AMutableInt64 result) {
-        throw new NotImplementedException("Divide operation is not defined for temporal types");
+            AMutableInt64 result, IEvaluatorContext ctx) throws HyracksDataException {
+        ExceptionUtil.warnUnsupportedType(ctx, sourceLoc, getIdentifier().getName(), ATypeTag.DURATION);
+        return false;
     }
 
     @Override
-    protected boolean evaluateTimeInstanceArithmetic(long chronon0, long chronon1, AMutableInt64 result)
-            throws HyracksDataException {
-        throw new UnsupportedTypeException(sourceLoc, getIdentifier(), ATypeTag.SERIALIZED_TIME_TYPE_TAG);
+    protected boolean evaluateTimeInstanceArithmetic(long chronon0, long chronon1, AMutableInt64 result,
+            IEvaluatorContext ctx) throws HyracksDataException {
+        ExceptionUtil.warnUnsupportedType(ctx, sourceLoc, getIdentifier().getName(), ATypeTag.TIME);
+        return false;
     }
 }
diff --git a/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/NumericDivideDescriptor.java b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/NumericDivideDescriptor.java
index 1c405b3..b23c2ac 100644
--- a/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/NumericDivideDescriptor.java
+++ b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/NumericDivideDescriptor.java
@@ -21,13 +21,13 @@
 import org.apache.asterix.common.annotations.MissingNullInOutFunction;
 import org.apache.asterix.om.base.AMutableDouble;
 import org.apache.asterix.om.base.AMutableInt64;
+import org.apache.asterix.om.exceptions.ExceptionUtil;
 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.runtime.exceptions.UnsupportedTypeException;
-import org.apache.hyracks.algebricks.common.exceptions.NotImplementedException;
 import org.apache.hyracks.algebricks.core.algebra.functions.FunctionIdentifier;
+import org.apache.hyracks.algebricks.runtime.base.IEvaluatorContext;
 import org.apache.hyracks.api.exceptions.HyracksDataException;
 
 @MissingNullInOutFunction
@@ -67,13 +67,15 @@
 
     @Override
     protected boolean evaluateTimeDurationArithmetic(long chronon, int yearMonth, long dayTime, boolean isTimeOnly,
-            AMutableInt64 result) {
-        throw new NotImplementedException("Divide operation is not defined for temporal types");
+            AMutableInt64 result, IEvaluatorContext ctx) throws HyracksDataException {
+        ExceptionUtil.warnUnsupportedType(ctx, sourceLoc, getIdentifier().getName(), ATypeTag.DURATION);
+        return false;
     }
 
     @Override
-    protected boolean evaluateTimeInstanceArithmetic(long chronon0, long chronon1, AMutableInt64 result)
-            throws HyracksDataException {
-        throw new UnsupportedTypeException(sourceLoc, getIdentifier(), ATypeTag.SERIALIZED_TIME_TYPE_TAG);
+    protected boolean evaluateTimeInstanceArithmetic(long chronon0, long chronon1, AMutableInt64 result,
+            IEvaluatorContext ctx) throws HyracksDataException {
+        ExceptionUtil.warnUnsupportedType(ctx, sourceLoc, getIdentifier().getName(), ATypeTag.TIME);
+        return false;
     }
 }
diff --git a/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/NumericModuloDescriptor.java b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/NumericModuloDescriptor.java
index ce34b11..3932eda 100644
--- a/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/NumericModuloDescriptor.java
+++ b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/NumericModuloDescriptor.java
@@ -21,12 +21,13 @@
 import org.apache.asterix.common.annotations.MissingNullInOutFunction;
 import org.apache.asterix.om.base.AMutableDouble;
 import org.apache.asterix.om.base.AMutableInt64;
+import org.apache.asterix.om.exceptions.ExceptionUtil;
 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.runtime.exceptions.UnsupportedTypeException;
 import org.apache.hyracks.algebricks.core.algebra.functions.FunctionIdentifier;
+import org.apache.hyracks.algebricks.runtime.base.IEvaluatorContext;
 import org.apache.hyracks.api.exceptions.HyracksDataException;
 
 @MissingNullInOutFunction
@@ -68,13 +69,15 @@
 
     @Override
     protected boolean evaluateTimeDurationArithmetic(long chronon, int yearMonth, long dayTime, boolean isTimeOnly,
-            AMutableInt64 result) throws HyracksDataException {
-        throw new UnsupportedTypeException(sourceLoc, getIdentifier(), ATypeTag.SERIALIZED_DURATION_TYPE_TAG);
+            AMutableInt64 result, IEvaluatorContext ctx) throws HyracksDataException {
+        ExceptionUtil.warnUnsupportedType(ctx, sourceLoc, getIdentifier().getName(), ATypeTag.DURATION);
+        return false;
     }
 
     @Override
-    protected boolean evaluateTimeInstanceArithmetic(long chronon0, long chronon1, AMutableInt64 result)
-            throws HyracksDataException {
-        throw new UnsupportedTypeException(sourceLoc, getIdentifier(), ATypeTag.SERIALIZED_TIME_TYPE_TAG);
+    protected boolean evaluateTimeInstanceArithmetic(long chronon0, long chronon1, AMutableInt64 result,
+            IEvaluatorContext ctx) throws HyracksDataException {
+        ExceptionUtil.warnUnsupportedType(ctx, sourceLoc, getIdentifier().getName(), ATypeTag.TIME);
+        return false;
     }
 }
diff --git a/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/NumericMultiplyDescriptor.java b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/NumericMultiplyDescriptor.java
index 3a4fc20..7bfb983 100644
--- a/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/NumericMultiplyDescriptor.java
+++ b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/NumericMultiplyDescriptor.java
@@ -21,13 +21,14 @@
 import org.apache.asterix.common.annotations.MissingNullInOutFunction;
 import org.apache.asterix.om.base.AMutableDouble;
 import org.apache.asterix.om.base.AMutableInt64;
+import org.apache.asterix.om.exceptions.ExceptionUtil;
 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.runtime.exceptions.OverflowException;
-import org.apache.asterix.runtime.exceptions.UnsupportedTypeException;
 import org.apache.hyracks.algebricks.core.algebra.functions.FunctionIdentifier;
+import org.apache.hyracks.algebricks.runtime.base.IEvaluatorContext;
 import org.apache.hyracks.api.exceptions.HyracksDataException;
 
 @MissingNullInOutFunction
@@ -65,13 +66,15 @@
 
     @Override
     protected boolean evaluateTimeDurationArithmetic(long chronon, int yearMonth, long dayTime, boolean isTimeOnly,
-            AMutableInt64 result) throws HyracksDataException {
-        throw new UnsupportedTypeException(sourceLoc, getIdentifier(), ATypeTag.SERIALIZED_DURATION_TYPE_TAG);
+            AMutableInt64 result, IEvaluatorContext ctx) throws HyracksDataException {
+        ExceptionUtil.warnUnsupportedType(ctx, sourceLoc, getIdentifier().getName(), ATypeTag.DURATION);
+        return false;
     }
 
     @Override
-    protected boolean evaluateTimeInstanceArithmetic(long chronon0, long chronon1, AMutableInt64 result)
-            throws HyracksDataException {
-        throw new UnsupportedTypeException(sourceLoc, getIdentifier(), ATypeTag.SERIALIZED_TIME_TYPE_TAG);
+    protected boolean evaluateTimeInstanceArithmetic(long chronon0, long chronon1, AMutableInt64 result,
+            IEvaluatorContext ctx) throws HyracksDataException {
+        ExceptionUtil.warnUnsupportedType(ctx, sourceLoc, getIdentifier().getName(), ATypeTag.TIME);
+        return false;
     }
 }
diff --git a/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/NumericPowerDescriptor.java b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/NumericPowerDescriptor.java
index dbccd65..be97a65 100644
--- a/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/NumericPowerDescriptor.java
+++ b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/NumericPowerDescriptor.java
@@ -21,13 +21,14 @@
 import org.apache.asterix.common.annotations.MissingNullInOutFunction;
 import org.apache.asterix.om.base.AMutableDouble;
 import org.apache.asterix.om.base.AMutableInt64;
+import org.apache.asterix.om.exceptions.ExceptionUtil;
 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.runtime.exceptions.OverflowException;
-import org.apache.asterix.runtime.exceptions.UnsupportedTypeException;
 import org.apache.hyracks.algebricks.core.algebra.functions.FunctionIdentifier;
+import org.apache.hyracks.algebricks.runtime.base.IEvaluatorContext;
 import org.apache.hyracks.api.exceptions.HyracksDataException;
 
 import com.google.common.math.LongMath;
@@ -80,13 +81,15 @@
 
     @Override
     protected boolean evaluateTimeDurationArithmetic(long chronon, int yearMonth, long dayTime, boolean isTimeOnly,
-            AMutableInt64 result) throws HyracksDataException {
-        throw new UnsupportedTypeException(sourceLoc, getIdentifier().getName(), ATypeTag.SERIALIZED_DURATION_TYPE_TAG);
+            AMutableInt64 result, IEvaluatorContext ctx) throws HyracksDataException {
+        ExceptionUtil.warnUnsupportedType(ctx, sourceLoc, getIdentifier().getName(), ATypeTag.DURATION);
+        return false;
     }
 
     @Override
-    protected boolean evaluateTimeInstanceArithmetic(long chronon0, long chronon1, AMutableInt64 result)
-            throws HyracksDataException {
-        throw new UnsupportedTypeException(sourceLoc, getIdentifier().getName(), ATypeTag.SERIALIZED_TIME_TYPE_TAG);
+    protected boolean evaluateTimeInstanceArithmetic(long chronon0, long chronon1, AMutableInt64 result,
+            IEvaluatorContext ctx) throws HyracksDataException {
+        ExceptionUtil.warnUnsupportedType(ctx, sourceLoc, getIdentifier().getName(), ATypeTag.TIME);
+        return false;
     }
 }
diff --git a/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/NumericSubDescriptor.java b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/NumericSubDescriptor.java
index d1aaf77..6305074 100644
--- a/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/NumericSubDescriptor.java
+++ b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/NumericSubDescriptor.java
@@ -27,6 +27,7 @@
 import org.apache.asterix.om.functions.IFunctionDescriptorFactory;
 import org.apache.asterix.runtime.exceptions.OverflowException;
 import org.apache.hyracks.algebricks.core.algebra.functions.FunctionIdentifier;
+import org.apache.hyracks.algebricks.runtime.base.IEvaluatorContext;
 import org.apache.hyracks.api.exceptions.HyracksDataException;
 
 @MissingNullInOutFunction
@@ -73,7 +74,7 @@
      */
     @Override
     protected boolean evaluateTimeDurationArithmetic(long chronon, int yearMonth, long dayTime, boolean isTimeOnly,
-            AMutableInt64 result) throws HyracksDataException {
+            AMutableInt64 result, IEvaluatorContext ctx) throws HyracksDataException {
         long res = DurationArithmeticOperations.addDuration(chronon, -1 * yearMonth, -1 * dayTime, isTimeOnly);
         result.setValue(res);
         return true;
@@ -83,8 +84,8 @@
      * @see org.apache.asterix.runtime.evaluators.functions.AbstractNumericArithmeticEval#evaluateTimeInstanceArithmetic(long, long)
      */
     @Override
-    protected boolean evaluateTimeInstanceArithmetic(long chronon0, long chronon1, AMutableInt64 result)
-            throws HyracksDataException {
+    protected boolean evaluateTimeInstanceArithmetic(long chronon0, long chronon1, AMutableInt64 result,
+            IEvaluatorContext ctx) throws HyracksDataException {
         return evaluateInteger(chronon0, chronon1, result);
     }
 }