You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@asterixdb.apache.org by al...@apache.org on 2019/09/13 23:04:58 UTC

[asterixdb] branch master updated: [ASTERIXDB-2634][COMP][RT] String functions to return NULL on mismatch

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 d080314  [ASTERIXDB-2634][COMP][RT] String functions to return NULL on mismatch
d080314 is described below

commit d080314640aea94014c3aae9cb4985e243dced41
Author: Ali Alsuliman <al...@gmail.com>
AuthorDate: Thu Sep 12 23:15:56 2019 -0700

    [ASTERIXDB-2634][COMP][RT] String functions to return NULL on mismatch
    
    - user model changes: no
    - storage format changes: no
    - interface changes: no
    
    Details:
    Make string functions return NULL on mismatch instead of raising
    an exception and issue a warning.
    
    - consolitated ExceptionUtil from org.apache.asterix.runtime.exceptions
    into org.apache.asterix.om.exceptions.
    - AbstractStringTypeComputer does not check arguments type now
      and does not throw mismatch exception.
    
    Change-Id: I51db8ae6ba301757c45c41cfd02bd2b083436970
    Reviewed-on: https://asterix-gerrit.ics.uci.edu/3562
    Tested-by: Jenkins <je...@fulliautomatix.ics.uci.edu>
    Integration-Tests: Jenkins <je...@fulliautomatix.ics.uci.edu>
    Reviewed-by: Till Westmann <ti...@apache.org>
---
 .../apache/asterix/test/common/TestExecutor.java   |   6 +-
 .../fun_return_null_01.01.ddl.sqlpp}               |  33 ++---
 .../fun_return_null_01.02.update.sqlpp}            |  24 ++--
 .../fun_return_null_01.03.query.sqlpp}             |  39 +++---
 .../fun_return_null_01.04.query.sqlpp}             |  39 +++---
 .../fun_return_null_01.05.query.sqlpp}             |  39 +++---
 .../fun_return_null_01.06.query.sqlpp}             |  38 +++---
 .../fun_return_null_01.07.query.sqlpp}             |  38 +++---
 .../fun_return_null_01.08.query.sqlpp}             |  38 +++---
 .../fun_return_null_01.09.ddl.sqlpp}               |  19 +--
 .../fun_return_null_02.01.query.sqlpp              |  59 +++++++++
 .../fun_return_null_01/fun_return_null_01.03.adm   |   2 +
 .../fun_return_null_01/fun_return_null_01.04.adm   |   2 +
 .../fun_return_null_01/fun_return_null_01.05.adm   |   2 +
 .../fun_return_null_01/fun_return_null_01.06.adm   |   2 +
 .../fun_return_null_01/fun_return_null_01.07.adm   |   2 +
 .../fun_return_null_01/fun_return_null_01.08.adm   |   2 +
 .../fun_return_null_02/fun_return_null_02.01.adm   |  30 +++++
 .../test/resources/runtimets/testsuite_sqlpp.xml   | 137 +++++++++++++++++++++
 .../asterix/om/exceptions/ExceptionUtil.java       |  61 +++++++++
 .../asterix/om/functions/BuiltinFunctions.java     |  19 +--
 .../impl/AbstractStringTypeComputer.java           |  28 ++---
 .../impl/StringBooleanTypeComputer.java            |   5 +-
 .../typecomputer/impl/StringInt32TypeComputer.java |   5 +-
 .../impl/StringStringTypeComputer.java             |   6 +-
 .../impl/StringToInt64ListTypeComputer.java        |   5 +-
 .../impl/StringToStringListTypeComputer.java       |   7 +-
 .../impl/UnaryStringInt64TypeComputer.java         |  21 +---
 .../std/AbstractMinMaxAggregateFunction.java       |  18 +--
 .../functions/AbstractBinaryStringEval.java        |  24 ++--
 .../evaluators/functions/AbstractScalarEval.java   |  28 -----
 .../functions/AbstractTripleStringEval.java        |  16 ++-
 .../functions/AbstractUnaryStringStringEval.java   |   9 +-
 .../functions/StringLengthDescriptor.java          |  18 +--
 .../functions/StringSplitDescriptor.java           |  15 ++-
 .../functions/StringToCodePointDescriptor.java     |  42 +++----
 .../functions/SubstringAfterDescriptor.java        |  15 ++-
 .../functions/SubstringBeforeDescriptor.java       |  15 ++-
 .../AbstractBitMultipleValuesEvaluator.java        |   7 +-
 .../bitwise/AbstractBitSingleValueEvaluator.java   |   4 +-
 .../bitwise/AbstractBitValuePositionEvaluator.java |  11 +-
 .../bitwise/BitValueCountFlagEvaluator.java        |  10 +-
 .../bitwise/BitValuePositionFlagEvaluator.java     |  14 ++-
 .../asterix/runtime/exceptions/ExceptionUtil.java  |  64 ----------
 .../runtime/exceptions/TypeMismatchException.java  |   4 +-
 45 files changed, 652 insertions(+), 370 deletions(-)

diff --git a/asterixdb/asterix-app/src/test/java/org/apache/asterix/test/common/TestExecutor.java b/asterixdb/asterix-app/src/test/java/org/apache/asterix/test/common/TestExecutor.java
index 7319ab5..eb71bb6 100644
--- a/asterixdb/asterix-app/src/test/java/org/apache/asterix/test/common/TestExecutor.java
+++ b/asterixdb/asterix-app/src/test/java/org/apache/asterix/test/common/TestExecutor.java
@@ -2120,9 +2120,6 @@ public class TestExecutor {
 
     private void validateWarnings(List<String> actualWarnings, List<String> expectedWarn, MutableInt actualWarnCount,
             boolean expectedSourceLoc) throws Exception {
-        if (actualWarnCount.getValue() > expectedWarn.size()) {
-            throw new Exception("returned warnings exceeded expected warnings");
-        }
         if (actualWarnings != null) {
             for (String actualWarn : actualWarnings) {
                 if (expectedWarn.stream().noneMatch(actualWarn::contains)) {
@@ -2134,6 +2131,9 @@ public class TestExecutor {
                             ERR_MSG_SRC_LOC_LINE_REGEX, ERR_MSG_SRC_LOC_COLUMN_REGEX, actualWarn));
                 }
                 actualWarnCount.increment();
+                if (actualWarnCount.getValue() > expectedWarn.size()) {
+                    throw new Exception("returned warnings exceeded expected warnings");
+                }
             }
         }
     }
diff --git a/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/typecomputer/impl/StringInt32TypeComputer.java b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/fun_return_null/fun_return_null_01/fun_return_null_01.01.ddl.sqlpp
similarity index 55%
copy from asterixdb/asterix-om/src/main/java/org/apache/asterix/om/typecomputer/impl/StringInt32TypeComputer.java
copy to asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/fun_return_null/fun_return_null_01/fun_return_null_01.01.ddl.sqlpp
index 22b3246..ca6fa19 100644
--- a/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/typecomputer/impl/StringInt32TypeComputer.java
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/fun_return_null/fun_return_null_01/fun_return_null_01.01.ddl.sqlpp
@@ -17,21 +17,24 @@
  * under the License.
  */
 
-package org.apache.asterix.om.typecomputer.impl;
+drop dataverse test if exists;
+create dataverse test;
+use test;
 
-import org.apache.asterix.om.types.BuiltinType;
-import org.apache.asterix.om.types.IAType;
-import org.apache.hyracks.algebricks.common.exceptions.AlgebricksException;
-import org.apache.hyracks.algebricks.core.algebra.base.ILogicalExpression;
+create type closedType as {
+id:   int,
+i8:   int8,
+i16:  int16,
+i32:  int32,
+i64:  int64,
+f:    float,
+d:    double,
+str1: string
+};
 
-public class StringInt32TypeComputer extends AbstractStringTypeComputer {
-    public static final StringInt32TypeComputer INSTANCE = new StringInt32TypeComputer();
+create type openType as {
+id: int
+};
 
-    private StringInt32TypeComputer() {
-    }
-
-    @Override
-    public IAType getResultType(ILogicalExpression expr, IAType... types) throws AlgebricksException {
-        return BuiltinType.AINT32;
-    }
-}
+create dataset closedDS(closedType) primary key id;
+create dataset openDS(openType) primary key id;
\ No newline at end of file
diff --git a/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/typecomputer/impl/StringBooleanTypeComputer.java b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/fun_return_null/fun_return_null_01/fun_return_null_01.02.update.sqlpp
similarity index 54%
copy from asterixdb/asterix-om/src/main/java/org/apache/asterix/om/typecomputer/impl/StringBooleanTypeComputer.java
copy to asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/fun_return_null/fun_return_null_01/fun_return_null_01.02.update.sqlpp
index 6c1d62e..b0caa32 100644
--- a/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/typecomputer/impl/StringBooleanTypeComputer.java
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/fun_return_null/fun_return_null_01/fun_return_null_01.02.update.sqlpp
@@ -16,21 +16,15 @@
  * specific language governing permissions and limitations
  * under the License.
  */
-package org.apache.asterix.om.typecomputer.impl;
 
-import org.apache.asterix.om.types.BuiltinType;
-import org.apache.asterix.om.types.IAType;
-import org.apache.hyracks.algebricks.common.exceptions.AlgebricksException;
-import org.apache.hyracks.algebricks.core.algebra.base.ILogicalExpression;
+use test;
 
-public class StringBooleanTypeComputer extends AbstractStringTypeComputer {
-    public static final StringBooleanTypeComputer INSTANCE = new StringBooleanTypeComputer();
+insert into closedDS([
+{"id": 1, "i8": int8("2"), "i16": int16("10"), "i32": int32("21"), "i64": int64("87"), "f": float("4.2"), "d": double("5.3"), "str1": "foo", "mixed": 7},
+{"id": 2, "i8": int8("2"), "i16": int16("10"), "i32": int32("21"), "i64": int64("87"), "f": float("4.2"), "d": double("5.3"), "str1": "foo", "mixed": "m"}
+]);
 
-    private StringBooleanTypeComputer() {
-    }
-
-    @Override
-    public IAType getResultType(ILogicalExpression expr, IAType... types) throws AlgebricksException {
-        return BuiltinType.ABOOLEAN;
-    }
-}
+insert into openDS([
+{"id": 1, "i8": int8("2"), "i16": int16("10"), "i32": int32("21"), "i64": int64("87"), "f": float("4.2"), "d": double("5.3"), "str1": "foo", "mixed": 7},
+{"id": 2, "i8": int8("2"), "i16": int16("10"), "i32": int32("21"), "i64": int64("87"), "f": float("4.2"), "d": double("5.3"), "str1": "foo", "mixed": "m"}
+]);
\ No newline at end of file
diff --git a/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/typecomputer/impl/StringInt32TypeComputer.java b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/fun_return_null/fun_return_null_01/fun_return_null_01.03.query.sqlpp
similarity index 55%
copy from asterixdb/asterix-om/src/main/java/org/apache/asterix/om/typecomputer/impl/StringInt32TypeComputer.java
copy to asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/fun_return_null/fun_return_null_01/fun_return_null_01.03.query.sqlpp
index 22b3246..2528045 100644
--- a/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/typecomputer/impl/StringInt32TypeComputer.java
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/fun_return_null/fun_return_null_01/fun_return_null_01.03.query.sqlpp
@@ -17,21 +17,30 @@
  * under the License.
  */
 
-package org.apache.asterix.om.typecomputer.impl;
-
-import org.apache.asterix.om.types.BuiltinType;
-import org.apache.asterix.om.types.IAType;
-import org.apache.hyracks.algebricks.common.exceptions.AlgebricksException;
-import org.apache.hyracks.algebricks.core.algebra.base.ILogicalExpression;
+/*
+ *  Description: tests reporting type mismatch for string functions
+ */
 
-public class StringInt32TypeComputer extends AbstractStringTypeComputer {
-    public static final StringInt32TypeComputer INSTANCE = new StringInt32TypeComputer();
+use test;
 
-    private StringInt32TypeComputer() {
-    }
+set `import-private-functions` "true";
+set `compiler.runtime.warnings` "10000";
 
-    @Override
-    public IAType getResultType(ILogicalExpression expr, IAType... types) throws AlgebricksException {
-        return BuiltinType.AINT32;
-    }
-}
+from closedDS as ds
+select
+`LIKE`(ds.str1, ds.i8),
+`LIKE`(ds.i8, ds.str1),
+contains(ds.str1, ds.i8),
+string_to_codepoint(ds.i64),
+length(ds.i32),
+lowercase(ds.i16),
+uppercase(ds.i16),
+initcap(ds.i64),
+trim(ds.i32),
+trim(ds.i64, ds.str1),
+ltrim(ds.i16),
+ltrim(ds.str1, ds.i8),
+rtrim(ds.i32),
+rtrim(ds.i64, ds.str1),
+position(ds.i8, ds.str1)
+order by ds.id;
\ No newline at end of file
diff --git a/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/typecomputer/impl/StringInt32TypeComputer.java b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/fun_return_null/fun_return_null_01/fun_return_null_01.04.query.sqlpp
similarity index 55%
copy from asterixdb/asterix-om/src/main/java/org/apache/asterix/om/typecomputer/impl/StringInt32TypeComputer.java
copy to asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/fun_return_null/fun_return_null_01/fun_return_null_01.04.query.sqlpp
index 22b3246..882f465 100644
--- a/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/typecomputer/impl/StringInt32TypeComputer.java
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/fun_return_null/fun_return_null_01/fun_return_null_01.04.query.sqlpp
@@ -17,21 +17,30 @@
  * under the License.
  */
 
-package org.apache.asterix.om.typecomputer.impl;
-
-import org.apache.asterix.om.types.BuiltinType;
-import org.apache.asterix.om.types.IAType;
-import org.apache.hyracks.algebricks.common.exceptions.AlgebricksException;
-import org.apache.hyracks.algebricks.core.algebra.base.ILogicalExpression;
+/*
+ *  Description: tests reporting type mismatch for string functions
+ */
 
-public class StringInt32TypeComputer extends AbstractStringTypeComputer {
-    public static final StringInt32TypeComputer INSTANCE = new StringInt32TypeComputer();
+use test;
 
-    private StringInt32TypeComputer() {
-    }
+set `import-private-functions` "true";
+set `compiler.runtime.warnings` "10000";
 
-    @Override
-    public IAType getResultType(ILogicalExpression expr, IAType... types) throws AlgebricksException {
-        return BuiltinType.AINT32;
-    }
-}
+from openDS as ds
+select
+`LIKE`(ds.str1, ds.i8),
+`LIKE`(ds.i8, ds.str1),
+contains(ds.str1, ds.i8),
+string_to_codepoint(ds.i64),
+length(ds.i32),
+lowercase(ds.i16),
+uppercase(ds.i16),
+initcap(ds.i64),
+trim(ds.i32),
+trim(ds.i64, ds.str1),
+ltrim(ds.i16),
+ltrim(ds.str1, ds.i8),
+rtrim(ds.i32),
+rtrim(ds.i64, ds.str1),
+position(ds.i8, ds.str1)
+order by ds.id;
\ No newline at end of file
diff --git a/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/typecomputer/impl/StringInt32TypeComputer.java b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/fun_return_null/fun_return_null_01/fun_return_null_01.05.query.sqlpp
similarity index 55%
copy from asterixdb/asterix-om/src/main/java/org/apache/asterix/om/typecomputer/impl/StringInt32TypeComputer.java
copy to asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/fun_return_null/fun_return_null_01/fun_return_null_01.05.query.sqlpp
index 22b3246..145b429 100644
--- a/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/typecomputer/impl/StringInt32TypeComputer.java
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/fun_return_null/fun_return_null_01/fun_return_null_01.05.query.sqlpp
@@ -17,21 +17,30 @@
  * under the License.
  */
 
-package org.apache.asterix.om.typecomputer.impl;
-
-import org.apache.asterix.om.types.BuiltinType;
-import org.apache.asterix.om.types.IAType;
-import org.apache.hyracks.algebricks.common.exceptions.AlgebricksException;
-import org.apache.hyracks.algebricks.core.algebra.base.ILogicalExpression;
+/*
+ *  Description: tests reporting type mismatch for string functions
+ */
 
-public class StringInt32TypeComputer extends AbstractStringTypeComputer {
-    public static final StringInt32TypeComputer INSTANCE = new StringInt32TypeComputer();
+use test;
 
-    private StringInt32TypeComputer() {
-    }
+set `import-private-functions` "true";
+set `compiler.runtime.warnings` "10000";
 
-    @Override
-    public IAType getResultType(ILogicalExpression expr, IAType... types) throws AlgebricksException {
-        return BuiltinType.AINT32;
-    }
-}
+from openDS as ds
+select
+`LIKE`(ds.mixed, ds.str1),
+`LIKE`(ds.str1, ds.mixed),
+contains(ds.mixed, ds.str1),
+string_to_codepoint(ds.mixed),
+length(ds.mixed),
+lowercase(ds.mixed),
+uppercase(ds.mixed),
+initcap(ds.mixed),
+trim(ds.mixed),
+trim(ds.mixed, ds.str1),
+ltrim(ds.mixed),
+ltrim(ds.str1, ds.mixed),
+rtrim(ds.mixed),
+rtrim(ds.mixed, ds.str1),
+position(ds.mixed, ds.str1)
+order by ds.id;
\ No newline at end of file
diff --git a/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/typecomputer/impl/StringBooleanTypeComputer.java b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/fun_return_null/fun_return_null_01/fun_return_null_01.06.query.sqlpp
similarity index 54%
copy from asterixdb/asterix-om/src/main/java/org/apache/asterix/om/typecomputer/impl/StringBooleanTypeComputer.java
copy to asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/fun_return_null/fun_return_null_01/fun_return_null_01.06.query.sqlpp
index 6c1d62e..1c5d037 100644
--- a/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/typecomputer/impl/StringBooleanTypeComputer.java
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/fun_return_null/fun_return_null_01/fun_return_null_01.06.query.sqlpp
@@ -16,21 +16,31 @@
  * specific language governing permissions and limitations
  * under the License.
  */
-package org.apache.asterix.om.typecomputer.impl;
 
-import org.apache.asterix.om.types.BuiltinType;
-import org.apache.asterix.om.types.IAType;
-import org.apache.hyracks.algebricks.common.exceptions.AlgebricksException;
-import org.apache.hyracks.algebricks.core.algebra.base.ILogicalExpression;
+/*
+ *  Description: tests reporting type mismatch for string functions
+ */
 
-public class StringBooleanTypeComputer extends AbstractStringTypeComputer {
-    public static final StringBooleanTypeComputer INSTANCE = new StringBooleanTypeComputer();
+use test;
 
-    private StringBooleanTypeComputer() {
-    }
+set `import-private-functions` "true";
+set `compiler.runtime.warnings` "10000";
 
-    @Override
-    public IAType getResultType(ILogicalExpression expr, IAType... types) throws AlgebricksException {
-        return BuiltinType.ABOOLEAN;
-    }
-}
+from closedDS as ds
+select
+starts_with(ds.str1, ds.i64),
+ends_with(ds.i16, ds.str1),
+matches(ds.str1, ds.i32),
+matches(ds.str1, ds.str1, ds.i8),
+regexp_like(ds.i64, ds.str1),
+regexp_like(ds.str1, ds.str1, ds.i8),
+regexp_position(ds.i32, ds.str1),
+regexp_position(ds.str1, ds.str1, ds.i8),
+regexp_replace(ds.str1, ds.i64, ds.str1),
+`string-equal`(ds.str1, ds.i8),
+replace(ds.i16, ds.str1, ds.str1),
+reverse(ds.i32),
+`substring-after`(ds.str1, ds.i64),
+`substring-before`(ds.i8, ds.str1),
+split(ds.str1, ds.i8)
+order by ds.id;
\ No newline at end of file
diff --git a/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/typecomputer/impl/StringBooleanTypeComputer.java b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/fun_return_null/fun_return_null_01/fun_return_null_01.07.query.sqlpp
similarity index 54%
copy from asterixdb/asterix-om/src/main/java/org/apache/asterix/om/typecomputer/impl/StringBooleanTypeComputer.java
copy to asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/fun_return_null/fun_return_null_01/fun_return_null_01.07.query.sqlpp
index 6c1d62e..09a952d 100644
--- a/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/typecomputer/impl/StringBooleanTypeComputer.java
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/fun_return_null/fun_return_null_01/fun_return_null_01.07.query.sqlpp
@@ -16,21 +16,31 @@
  * specific language governing permissions and limitations
  * under the License.
  */
-package org.apache.asterix.om.typecomputer.impl;
 
-import org.apache.asterix.om.types.BuiltinType;
-import org.apache.asterix.om.types.IAType;
-import org.apache.hyracks.algebricks.common.exceptions.AlgebricksException;
-import org.apache.hyracks.algebricks.core.algebra.base.ILogicalExpression;
+/*
+ *  Description: tests reporting type mismatch for string functions
+ */
 
-public class StringBooleanTypeComputer extends AbstractStringTypeComputer {
-    public static final StringBooleanTypeComputer INSTANCE = new StringBooleanTypeComputer();
+use test;
 
-    private StringBooleanTypeComputer() {
-    }
+set `import-private-functions` "true";
+set `compiler.runtime.warnings` "10000";
 
-    @Override
-    public IAType getResultType(ILogicalExpression expr, IAType... types) throws AlgebricksException {
-        return BuiltinType.ABOOLEAN;
-    }
-}
+from openDS as ds
+select
+starts_with(ds.str1, ds.i64),
+ends_with(ds.i16, ds.str1),
+matches(ds.str1, ds.i32),
+matches(ds.str1, ds.str1, ds.i8),
+regexp_like(ds.i64, ds.str1),
+regexp_like(ds.str1, ds.str1, ds.i8),
+regexp_position(ds.i32, ds.str1),
+regexp_position(ds.str1, ds.str1, ds.i8),
+regexp_replace(ds.str1, ds.i64, ds.str1),
+`string-equal`(ds.str1, ds.i8),
+replace(ds.i16, ds.str1, ds.str1),
+reverse(ds.i32),
+`substring-after`(ds.str1, ds.i64),
+`substring-before`(ds.i8, ds.str1),
+split(ds.str1, ds.i8)
+order by ds.id;
\ No newline at end of file
diff --git a/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/typecomputer/impl/StringBooleanTypeComputer.java b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/fun_return_null/fun_return_null_01/fun_return_null_01.08.query.sqlpp
similarity index 52%
copy from asterixdb/asterix-om/src/main/java/org/apache/asterix/om/typecomputer/impl/StringBooleanTypeComputer.java
copy to asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/fun_return_null/fun_return_null_01/fun_return_null_01.08.query.sqlpp
index 6c1d62e..138bce5 100644
--- a/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/typecomputer/impl/StringBooleanTypeComputer.java
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/fun_return_null/fun_return_null_01/fun_return_null_01.08.query.sqlpp
@@ -16,21 +16,31 @@
  * specific language governing permissions and limitations
  * under the License.
  */
-package org.apache.asterix.om.typecomputer.impl;
 
-import org.apache.asterix.om.types.BuiltinType;
-import org.apache.asterix.om.types.IAType;
-import org.apache.hyracks.algebricks.common.exceptions.AlgebricksException;
-import org.apache.hyracks.algebricks.core.algebra.base.ILogicalExpression;
+/*
+ *  Description: tests reporting type mismatch for string functions
+ */
 
-public class StringBooleanTypeComputer extends AbstractStringTypeComputer {
-    public static final StringBooleanTypeComputer INSTANCE = new StringBooleanTypeComputer();
+use test;
 
-    private StringBooleanTypeComputer() {
-    }
+set `import-private-functions` "true";
+set `compiler.runtime.warnings` "10000";
 
-    @Override
-    public IAType getResultType(ILogicalExpression expr, IAType... types) throws AlgebricksException {
-        return BuiltinType.ABOOLEAN;
-    }
-}
+from openDS as ds
+select
+starts_with(ds.str1, ds.mixed),
+ends_with(ds.mixed, ds.str1),
+matches(ds.str1, ds.mixed),
+matches(ds.str1, ds.str1, ds.mixed),
+regexp_like(ds.mixed, ds.str1),
+regexp_like(ds.str1, ds.str1, ds.mixed),
+regexp_position(ds.mixed, ds.str1),
+regexp_position(ds.str1, ds.str1, ds.mixed),
+regexp_replace(ds.str1, ds.mixed, ds.str1),
+`string-equal`(ds.str1, ds.mixed),
+replace(ds.mixed, ds.str1, ds.str1),
+reverse(ds.mixed),
+`substring-after`(ds.str1, ds.mixed),
+`substring-before`(ds.mixed, ds.str1),
+split(ds.str1, ds.mixed)
+order by ds.id;
\ No newline at end of file
diff --git a/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/typecomputer/impl/StringInt32TypeComputer.java b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/fun_return_null/fun_return_null_01/fun_return_null_01.09.ddl.sqlpp
similarity index 54%
copy from asterixdb/asterix-om/src/main/java/org/apache/asterix/om/typecomputer/impl/StringInt32TypeComputer.java
copy to asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/fun_return_null/fun_return_null_01/fun_return_null_01.09.ddl.sqlpp
index 22b3246..548e632 100644
--- a/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/typecomputer/impl/StringInt32TypeComputer.java
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/fun_return_null/fun_return_null_01/fun_return_null_01.09.ddl.sqlpp
@@ -17,21 +17,4 @@
  * under the License.
  */
 
-package org.apache.asterix.om.typecomputer.impl;
-
-import org.apache.asterix.om.types.BuiltinType;
-import org.apache.asterix.om.types.IAType;
-import org.apache.hyracks.algebricks.common.exceptions.AlgebricksException;
-import org.apache.hyracks.algebricks.core.algebra.base.ILogicalExpression;
-
-public class StringInt32TypeComputer extends AbstractStringTypeComputer {
-    public static final StringInt32TypeComputer INSTANCE = new StringInt32TypeComputer();
-
-    private StringInt32TypeComputer() {
-    }
-
-    @Override
-    public IAType getResultType(ILogicalExpression expr, IAType... types) throws AlgebricksException {
-        return BuiltinType.AINT32;
-    }
-}
+drop dataverse test if exists;
\ No newline at end of file
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/fun_return_null/fun_return_null_02/fun_return_null_02.01.query.sqlpp b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/fun_return_null/fun_return_null_02/fun_return_null_02.01.query.sqlpp
new file mode 100644
index 0000000..c504df6
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/fun_return_null/fun_return_null_02/fun_return_null_02.01.query.sqlpp
@@ -0,0 +1,59 @@
+/*
+ * 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 type mismatch for string functions
+ */
+
+set `import-private-functions` "true";
+set `compiler.runtime.warnings` "10000";
+
+FROM[
+`LIKE`("aa", int8("8")),
+`LIKE`(int8("8"), "aa"),
+contains("aa", int8("8")),
+string_to_codepoint(int64("64")),
+length(int32("32")),
+lowercase(int16("16")),
+uppercase(int16("16")),
+initcap(int64("64")),
+trim(int32("32")),
+trim(int64("64"), "aa"),
+ltrim(int16("16")),
+ltrim("aa", int8("8")),
+rtrim(int32("32")),
+rtrim(int64("64"), "aa"),
+position(int8("8"), "aa"),
+starts_with("aa", int64("64")),
+ends_with(int16("16"), "aa"),
+matches("aa", int32("32")),
+matches("aa", "aa", int8("8")),
+regexp_like(int64("64"), "aa"),
+regexp_like("aa", "aa", int8("8")),
+regexp_position(int32("32"), "aa"),
+regexp_position("aa", "aa", int8("8")),
+regexp_replace("aa", int64("64"), "aa"),
+`string-equal`("aa", int8("8")),
+replace(int16("16"), "aa", "aa"),
+reverse(int32("32")),
+`substring-after`("aa", int64("64")),
+`substring-before`(int8("8"), "aa"),
+split("aa", int8("8"))] AS t
+SELECT t
+;
\ No newline at end of file
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/results/fun_return_null/fun_return_null_01/fun_return_null_01.03.adm b/asterixdb/asterix-app/src/test/resources/runtimets/results/fun_return_null/fun_return_null_01/fun_return_null_01.03.adm
new file mode 100644
index 0000000..a354672
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/results/fun_return_null/fun_return_null_01/fun_return_null_01.03.adm
@@ -0,0 +1,2 @@
+{ "$1": null, "$2": null, "$3": null, "$4": null, "$5": null, "$6": null, "$7": null, "$8": null, "$9": null, "$10": null, "$11": null, "$12": null, "$13": null, "$14": null, "$15": null }
+{ "$1": null, "$2": null, "$3": null, "$4": null, "$5": null, "$6": null, "$7": null, "$8": null, "$9": null, "$10": null, "$11": null, "$12": null, "$13": null, "$14": null, "$15": null }
\ No newline at end of file
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/results/fun_return_null/fun_return_null_01/fun_return_null_01.04.adm b/asterixdb/asterix-app/src/test/resources/runtimets/results/fun_return_null/fun_return_null_01/fun_return_null_01.04.adm
new file mode 100644
index 0000000..a354672
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/results/fun_return_null/fun_return_null_01/fun_return_null_01.04.adm
@@ -0,0 +1,2 @@
+{ "$1": null, "$2": null, "$3": null, "$4": null, "$5": null, "$6": null, "$7": null, "$8": null, "$9": null, "$10": null, "$11": null, "$12": null, "$13": null, "$14": null, "$15": null }
+{ "$1": null, "$2": null, "$3": null, "$4": null, "$5": null, "$6": null, "$7": null, "$8": null, "$9": null, "$10": null, "$11": null, "$12": null, "$13": null, "$14": null, "$15": null }
\ No newline at end of file
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/results/fun_return_null/fun_return_null_01/fun_return_null_01.05.adm b/asterixdb/asterix-app/src/test/resources/runtimets/results/fun_return_null/fun_return_null_01/fun_return_null_01.05.adm
new file mode 100644
index 0000000..cc3a2f4
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/results/fun_return_null/fun_return_null_01/fun_return_null_01.05.adm
@@ -0,0 +1,2 @@
+{ "$1": null, "$2": null, "$3": null, "$4": null, "$5": null, "$6": null, "$7": null, "$8": null, "$9": null, "$10": null, "$11": null, "$12": null, "$13": null, "$14": null, "$15": null }
+{ "$1": false, "$2": false, "$3": false, "$4": [ 109 ], "$5": 1, "$6": "m", "$7": "M", "$8": "M", "$9": "m", "$10": "m", "$11": "m", "$12": "foo", "$13": "m", "$14": "m", "$15": -1 }
\ No newline at end of file
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/results/fun_return_null/fun_return_null_01/fun_return_null_01.06.adm b/asterixdb/asterix-app/src/test/resources/runtimets/results/fun_return_null/fun_return_null_01/fun_return_null_01.06.adm
new file mode 100644
index 0000000..a354672
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/results/fun_return_null/fun_return_null_01/fun_return_null_01.06.adm
@@ -0,0 +1,2 @@
+{ "$1": null, "$2": null, "$3": null, "$4": null, "$5": null, "$6": null, "$7": null, "$8": null, "$9": null, "$10": null, "$11": null, "$12": null, "$13": null, "$14": null, "$15": null }
+{ "$1": null, "$2": null, "$3": null, "$4": null, "$5": null, "$6": null, "$7": null, "$8": null, "$9": null, "$10": null, "$11": null, "$12": null, "$13": null, "$14": null, "$15": null }
\ No newline at end of file
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/results/fun_return_null/fun_return_null_01/fun_return_null_01.07.adm b/asterixdb/asterix-app/src/test/resources/runtimets/results/fun_return_null/fun_return_null_01/fun_return_null_01.07.adm
new file mode 100644
index 0000000..a354672
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/results/fun_return_null/fun_return_null_01/fun_return_null_01.07.adm
@@ -0,0 +1,2 @@
+{ "$1": null, "$2": null, "$3": null, "$4": null, "$5": null, "$6": null, "$7": null, "$8": null, "$9": null, "$10": null, "$11": null, "$12": null, "$13": null, "$14": null, "$15": null }
+{ "$1": null, "$2": null, "$3": null, "$4": null, "$5": null, "$6": null, "$7": null, "$8": null, "$9": null, "$10": null, "$11": null, "$12": null, "$13": null, "$14": null, "$15": null }
\ No newline at end of file
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/results/fun_return_null/fun_return_null_01/fun_return_null_01.08.adm b/asterixdb/asterix-app/src/test/resources/runtimets/results/fun_return_null/fun_return_null_01/fun_return_null_01.08.adm
new file mode 100644
index 0000000..86d9de2
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/results/fun_return_null/fun_return_null_01/fun_return_null_01.08.adm
@@ -0,0 +1,2 @@
+{ "$1": null, "$2": null, "$3": null, "$4": null, "$5": null, "$6": null, "$7": null, "$8": null, "$9": null, "$10": null, "$11": null, "$12": null, "$13": null, "$14": null, "$15": null }
+{ "$1": false, "$2": false, "$3": false, "$4": true, "$5": false, "$6": true, "$7": -1, "$8": 0, "$9": "foo", "$10": false, "$11": "m", "$12": "m", "$13": "", "$14": "", "$15": [ "foo" ] }
\ No newline at end of file
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/results/fun_return_null/fun_return_null_02/fun_return_null_02.01.adm b/asterixdb/asterix-app/src/test/resources/runtimets/results/fun_return_null/fun_return_null_02/fun_return_null_02.01.adm
new file mode 100644
index 0000000..11c1efc
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/results/fun_return_null/fun_return_null_02/fun_return_null_02.01.adm
@@ -0,0 +1,30 @@
+{ "t": null }
+{ "t": null }
+{ "t": null }
+{ "t": null }
+{ "t": null }
+{ "t": null }
+{ "t": null }
+{ "t": null }
+{ "t": null }
+{ "t": null }
+{ "t": null }
+{ "t": null }
+{ "t": null }
+{ "t": null }
+{ "t": null }
+{ "t": null }
+{ "t": null }
+{ "t": null }
+{ "t": null }
+{ "t": null }
+{ "t": null }
+{ "t": null }
+{ "t": null }
+{ "t": null }
+{ "t": null }
+{ "t": null }
+{ "t": null }
+{ "t": null }
+{ "t": null }
+{ "t": 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 c6146f9..a7bade2 100644
--- a/asterixdb/asterix-app/src/test/resources/runtimets/testsuite_sqlpp.xml
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/testsuite_sqlpp.xml
@@ -12508,4 +12508,141 @@
       </compilation-unit>
     </test-case>
   </test-group>
+  <test-group name="fun_return_null">
+    <test-case FilePath="fun_return_null" check-warnings="true">
+      <compilation-unit name="fun_return_null_01">
+        <output-dir compare="Text">fun_return_null_01</output-dir>
+        <expected-warn>Type mismatch: function trim expects its 1st input parameter to be of type string, but the actual input type is bigint (in line 40, at column 1)</expected-warn>
+        <expected-warn>Type mismatch: function like expects its 2nd input parameter to be of type string, but the actual input type is tinyint (in line 31, at column 1)</expected-warn>
+        <expected-warn>Type mismatch: function uppercase expects its 1st input parameter to be of type string, but the actual input type is smallint (in line 37, at column 1)</expected-warn>
+        <expected-warn>Type mismatch: function ltrim expects its 1st input parameter to be of type string, but the actual input type is smallint (in line 41, at column 1)</expected-warn>
+        <expected-warn>Type mismatch: function like expects its 1st input parameter to be of type string, but the actual input type is tinyint (in line 32, at column 1)</expected-warn>
+        <expected-warn>Type mismatch: function string-length expects its 1st input parameter to be of type string, but the actual input type is integer (in line 35, at column 1)</expected-warn>
+        <expected-warn>Type mismatch: function trim expects its 1st input parameter to be of type string, but the actual input type is integer (in line 39, at column 1)</expected-warn>
+        <expected-warn>Type mismatch: function lowercase expects its 1st input parameter to be of type string, but the actual input type is smallint (in line 36, at column 1)</expected-warn>
+        <expected-warn>Type mismatch: function rtrim expects its 1st input parameter to be of type string, but the actual input type is bigint (in line 44, at column 1)</expected-warn>
+        <expected-warn>Type mismatch: function contains expects its 2nd input parameter to be of type string, but the actual input type is tinyint (in line 33, at column 1)</expected-warn>
+        <expected-warn>Type mismatch: function ltrim expects its 2nd input parameter to be of type string, but the actual input type is tinyint (in line 42, at column 1)</expected-warn>
+        <expected-warn>Type mismatch: function position expects its 1st input parameter to be of type string, but the actual input type is tinyint (in line 45, at column 1)</expected-warn>
+        <expected-warn>Type mismatch: function string-to-codepoint expects its 1st input parameter to be of type string, but the actual input type is bigint (in line 34, at column 1)</expected-warn>
+        <expected-warn>Type mismatch: function initcap expects its 1st input parameter to be of type string, but the actual input type is bigint (in line 38, at column 1)</expected-warn>
+        <expected-warn>Type mismatch: function rtrim expects its 1st input parameter to be of type string, but the actual input type is integer (in line 43, at column 1)</expected-warn>
+
+        <expected-warn>Type mismatch: function trim expects its 1st input parameter to be of type string, but the actual input type is bigint (in line 40, at column 1)</expected-warn>
+        <expected-warn>Type mismatch: function like expects its 2nd input parameter to be of type string, but the actual input type is tinyint (in line 31, at column 1)</expected-warn>
+        <expected-warn>Type mismatch: function uppercase expects its 1st input parameter to be of type string, but the actual input type is smallint (in line 37, at column 1)</expected-warn>
+        <expected-warn>Type mismatch: function ltrim expects its 1st input parameter to be of type string, but the actual input type is smallint (in line 41, at column 1)</expected-warn>
+        <expected-warn>Type mismatch: function like expects its 1st input parameter to be of type string, but the actual input type is tinyint (in line 32, at column 1)</expected-warn>
+        <expected-warn>Type mismatch: function string-length expects its 1st input parameter to be of type string, but the actual input type is integer (in line 35, at column 1)</expected-warn>
+        <expected-warn>Type mismatch: function trim expects its 1st input parameter to be of type string, but the actual input type is integer (in line 39, at column 1)</expected-warn>
+        <expected-warn>Type mismatch: function lowercase expects its 1st input parameter to be of type string, but the actual input type is smallint (in line 36, at column 1)</expected-warn>
+        <expected-warn>Type mismatch: function rtrim expects its 1st input parameter to be of type string, but the actual input type is bigint (in line 44, at column 1)</expected-warn>
+        <expected-warn>Type mismatch: function contains expects its 2nd input parameter to be of type string, but the actual input type is tinyint (in line 33, at column 1)</expected-warn>
+        <expected-warn>Type mismatch: function ltrim expects its 2nd input parameter to be of type string, but the actual input type is tinyint (in line 42, at column 1)</expected-warn>
+        <expected-warn>Type mismatch: function position expects its 1st input parameter to be of type string, but the actual input type is tinyint (in line 45, at column 1)</expected-warn>
+        <expected-warn>Type mismatch: function string-to-codepoint expects its 1st input parameter to be of type string, but the actual input type is bigint (in line 34, at column 1)</expected-warn>
+        <expected-warn>Type mismatch: function initcap expects its 1st input parameter to be of type string, but the actual input type is bigint (in line 38, at column 1)</expected-warn>
+        <expected-warn>Type mismatch: function rtrim expects its 1st input parameter to be of type string, but the actual input type is integer (in line 43, at column 1)</expected-warn>
+
+        <expected-warn>Type mismatch: function trim expects its 1st input parameter to be of type string, but the actual input type is bigint (in line 40, at column 1)</expected-warn>
+        <expected-warn>Type mismatch: function like expects its 1st input parameter to be of type string, but the actual input type is bigint (in line 31, at column 1)</expected-warn>
+        <expected-warn>Type mismatch: function uppercase expects its 1st input parameter to be of type string, but the actual input type is bigint (in line 37, at column 1)</expected-warn>
+        <expected-warn>Type mismatch: function ltrim expects its 1st input parameter to be of type string, but the actual input type is bigint (in line 41, at column 1)</expected-warn>
+        <expected-warn>Type mismatch: function like expects its 2nd input parameter to be of type string, but the actual input type is bigint (in line 32, at column 1)</expected-warn>
+        <expected-warn>Type mismatch: function string-length expects its 1st input parameter to be of type string, but the actual input type is bigint (in line 35, at column 1)</expected-warn>
+        <expected-warn>Type mismatch: function trim expects its 1st input parameter to be of type string, but the actual input type is bigint (in line 39, at column 1)</expected-warn>
+        <expected-warn>Type mismatch: function lowercase expects its 1st input parameter to be of type string, but the actual input type is bigint (in line 36, at column 1)</expected-warn>
+        <expected-warn>Type mismatch: function rtrim expects its 1st input parameter to be of type string, but the actual input type is bigint (in line 44, at column 1)</expected-warn>
+        <expected-warn>Type mismatch: function contains expects its 1st input parameter to be of type string, but the actual input type is bigint (in line 33, at column 1)</expected-warn>
+        <expected-warn>Type mismatch: function ltrim expects its 2nd input parameter to be of type string, but the actual input type is bigint (in line 42, at column 1)</expected-warn>
+        <expected-warn>Type mismatch: function position expects its 1st input parameter to be of type string, but the actual input type is bigint (in line 45, at column 1)</expected-warn>
+        <expected-warn>Type mismatch: function string-to-codepoint expects its 1st input parameter to be of type string, but the actual input type is bigint (in line 34, at column 1)</expected-warn>
+        <expected-warn>Type mismatch: function initcap expects its 1st input parameter to be of type string, but the actual input type is bigint (in line 38, at column 1)</expected-warn>
+        <expected-warn>Type mismatch: function rtrim expects its 1st input parameter to be of type string, but the actual input type is bigint (in line 43, at column 1)</expected-warn>
+
+        <expected-warn>Type mismatch: function regexp-position expects its 1st input parameter to be of type string, but the actual input type is integer (in line 37, at column 1)</expected-warn>
+        <expected-warn>Type mismatch: function replace expects its 1st input parameter to be of type string, but the actual input type is smallint (in line 41, at column 1)</expected-warn>
+        <expected-warn>Type mismatch: function starts-with expects its 2nd input parameter to be of type string, but the actual input type is bigint (in line 31, at column 1)</expected-warn>
+        <expected-warn>Type mismatch: function reverse expects its 1st input parameter to be of type string, but the actual input type is integer (in line 42, at column 1)</expected-warn>
+        <expected-warn>Type mismatch: function regexp-like expects its 3rd input parameter to be of type string, but the actual input type is tinyint (in line 36, at column 1)</expected-warn>
+        <expected-warn>Type mismatch: function string-equal expects its 2nd input parameter to be of type string, but the actual input type is tinyint (in line 40, at column 1)</expected-warn>
+        <expected-warn>Type mismatch: function substring-after expects its 2nd input parameter to be of type string, but the actual input type is bigint (in line 43, at column 1)</expected-warn>
+        <expected-warn>Type mismatch: function matches expects its 2nd input parameter to be of type string, but the actual input type is integer (in line 33, at column 1)</expected-warn>
+        <expected-warn>Type mismatch: function regexp-like expects its 1st input parameter to be of type string, but the actual input type is bigint (in line 35, at column 1)</expected-warn>
+        <expected-warn>Type mismatch: function regexp-position expects its 3rd input parameter to be of type string, but the actual input type is tinyint (in line 38, at column 1)</expected-warn>
+        <expected-warn>Type mismatch: function substring-before expects its 1st input parameter to be of type string, but the actual input type is tinyint (in line 44, at column 1)</expected-warn>
+        <expected-warn>Type mismatch: function regexp-replace expects its 2nd input parameter to be of type string, but the actual input type is bigint (in line 39, at column 1)</expected-warn>
+        <expected-warn>Type mismatch: function matches expects its 3rd input parameter to be of type string, but the actual input type is tinyint (in line 34, at column 1)</expected-warn>
+        <expected-warn>Type mismatch: function split expects its 2nd input parameter to be of type string, but the actual input type is tinyint (in line 45, at column 1)</expected-warn>
+        <expected-warn>Type mismatch: function ends-with expects its 1st input parameter to be of type string, but the actual input type is smallint (in line 32, at column 1)</expected-warn>
+
+        <expected-warn>Type mismatch: function regexp-position expects its 1st input parameter to be of type string, but the actual input type is integer (in line 37, at column 1)</expected-warn>
+        <expected-warn>Type mismatch: function replace expects its 1st input parameter to be of type string, but the actual input type is smallint (in line 41, at column 1)</expected-warn>
+        <expected-warn>Type mismatch: function starts-with expects its 2nd input parameter to be of type string, but the actual input type is bigint (in line 31, at column 1)</expected-warn>
+        <expected-warn>Type mismatch: function reverse expects its 1st input parameter to be of type string, but the actual input type is integer (in line 42, at column 1)</expected-warn>
+        <expected-warn>Type mismatch: function regexp-like expects its 3rd input parameter to be of type string, but the actual input type is tinyint (in line 36, at column 1)</expected-warn>
+        <expected-warn>Type mismatch: function string-equal expects its 2nd input parameter to be of type string, but the actual input type is tinyint (in line 40, at column 1)</expected-warn>
+        <expected-warn>Type mismatch: function substring-after expects its 2nd input parameter to be of type string, but the actual input type is bigint (in line 43, at column 1)</expected-warn>
+        <expected-warn>Type mismatch: function matches expects its 2nd input parameter to be of type string, but the actual input type is integer (in line 33, at column 1)</expected-warn>
+        <expected-warn>Type mismatch: function regexp-like expects its 1st input parameter to be of type string, but the actual input type is bigint (in line 35, at column 1)</expected-warn>
+        <expected-warn>Type mismatch: function regexp-position expects its 3rd input parameter to be of type string, but the actual input type is tinyint (in line 38, at column 1)</expected-warn>
+        <expected-warn>Type mismatch: function substring-before expects its 1st input parameter to be of type string, but the actual input type is tinyint (in line 44, at column 1)</expected-warn>
+        <expected-warn>Type mismatch: function regexp-replace expects its 2nd input parameter to be of type string, but the actual input type is bigint (in line 39, at column 1)</expected-warn>
+        <expected-warn>Type mismatch: function matches expects its 3rd input parameter to be of type string, but the actual input type is tinyint (in line 34, at column 1)</expected-warn>
+        <expected-warn>Type mismatch: function split expects its 2nd input parameter to be of type string, but the actual input type is tinyint (in line 45, at column 1)</expected-warn>
+        <expected-warn>Type mismatch: function ends-with expects its 1st input parameter to be of type string, but the actual input type is smallint (in line 32, at column 1)</expected-warn>
+
+        <expected-warn>Type mismatch: function regexp-position expects its 1st input parameter to be of type string, but the actual input type is bigint (in line 37, at column 1)</expected-warn>
+        <expected-warn>Type mismatch: function replace expects its 1st input parameter to be of type string, but the actual input type is bigint (in line 41, at column 1)</expected-warn>
+        <expected-warn>Type mismatch: function starts-with expects its 2nd input parameter to be of type string, but the actual input type is bigint (in line 31, at column 1)</expected-warn>
+        <expected-warn>Type mismatch: function reverse expects its 1st input parameter to be of type string, but the actual input type is bigint (in line 42, at column 1)</expected-warn>
+        <expected-warn>Type mismatch: function regexp-like expects its 3rd input parameter to be of type string, but the actual input type is bigint (in line 36, at column 1)</expected-warn>
+        <expected-warn>Type mismatch: function string-equal expects its 2nd input parameter to be of type string, but the actual input type is bigint (in line 40, at column 1)</expected-warn>
+        <expected-warn>Type mismatch: function substring-after expects its 2nd input parameter to be of type string, but the actual input type is bigint (in line 43, at column 1)</expected-warn>
+        <expected-warn>Type mismatch: function matches expects its 2nd input parameter to be of type string, but the actual input type is bigint (in line 33, at column 1)</expected-warn>
+        <expected-warn>Type mismatch: function regexp-like expects its 1st input parameter to be of type string, but the actual input type is bigint (in line 35, at column 1)</expected-warn>
+        <expected-warn>Type mismatch: function regexp-position expects its 3rd input parameter to be of type string, but the actual input type is bigint (in line 38, at column 1)</expected-warn>
+        <expected-warn>Type mismatch: function substring-before expects its 1st input parameter to be of type string, but the actual input type is bigint (in line 44, at column 1)</expected-warn>
+        <expected-warn>Type mismatch: function regexp-replace expects its 2nd input parameter to be of type string, but the actual input type is bigint (in line 39, at column 1)</expected-warn>
+        <expected-warn>Type mismatch: function matches expects its 3rd input parameter to be of type string, but the actual input type is bigint (in line 34, at column 1)</expected-warn>
+        <expected-warn>Type mismatch: function split expects its 2nd input parameter to be of type string, but the actual input type is bigint (in line 45, at column 1)</expected-warn>
+        <expected-warn>Type mismatch: function ends-with expects its 1st input parameter to be of type string, but the actual input type is bigint (in line 32, at column 1)</expected-warn>
+      </compilation-unit>
+    </test-case>
+    <test-case FilePath="fun_return_null" check-warnings="true">
+      <compilation-unit name="fun_return_null_02">
+        <output-dir compare="Text">fun_return_null_02</output-dir>
+        <expected-warn>Type mismatch: function rtrim expects its 1st input parameter to be of type string, but the actual input type is bigint (in line 41, at column 1)</expected-warn>
+        <expected-warn>Type mismatch: function regexp-replace expects its 2nd input parameter to be of type string, but the actual input type is bigint (in line 51, at column 1)</expected-warn>
+        <expected-warn>Type mismatch: function regexp-like expects its 1st input parameter to be of type string, but the actual input type is bigint (in line 47, at column 1)</expected-warn>
+        <expected-warn>Type mismatch: function position expects its 1st input parameter to be of type string, but the actual input type is tinyint (in line 42, at column 1)</expected-warn>
+        <expected-warn>Type mismatch: function matches expects its 2nd input parameter to be of type string, but the actual input type is integer (in line 45, at column 1)</expected-warn>
+        <expected-warn>Type mismatch: function replace expects its 1st input parameter to be of type string, but the actual input type is smallint (in line 53, at column 1)</expected-warn>
+        <expected-warn>Type mismatch: function starts-with expects its 2nd input parameter to be of type string, but the actual input type is bigint (in line 43, at column 1)</expected-warn>
+        <expected-warn>Type mismatch: function regexp-position expects its 3rd input parameter to be of type string, but the actual input type is tinyint (in line 50, at column 1)</expected-warn>
+        <expected-warn>Type mismatch: function rtrim expects its 1st input parameter to be of type string, but the actual input type is integer (in line 40, at column 1)</expected-warn>
+        <expected-warn>Type mismatch: function substring-after expects its 2nd input parameter to be of type string, but the actual input type is bigint (in line 55, at column 1)</expected-warn>
+        <expected-warn>Type mismatch: function substring-before expects its 1st input parameter to be of type string, but the actual input type is tinyint (in line 56, at column 1)</expected-warn>
+        <expected-warn>Type mismatch: function lowercase expects its 1st input parameter to be of type string, but the actual input type is smallint (in line 33, at column 1)</expected-warn>
+        <expected-warn>Type mismatch: function ends-with expects its 1st input parameter to be of type string, but the actual input type is smallint (in line 44, at column 1)</expected-warn>
+        <expected-warn>Type mismatch: function trim expects its 1st input parameter to be of type string, but the actual input type is bigint (in line 37, at column 1)</expected-warn>
+        <expected-warn>Type mismatch: function uppercase expects its 1st input parameter to be of type string, but the actual input type is smallint (in line 34, at column 1)</expected-warn>
+        <expected-warn>Type mismatch: function regexp-like expects its 3rd input parameter to be of type string, but the actual input type is tinyint (in line 48, at column 1)</expected-warn>
+        <expected-warn>Type mismatch: function matches expects its 3rd input parameter to be of type string, but the actual input type is tinyint (in line 46, at column 1)</expected-warn>
+        <expected-warn>Type mismatch: function string-equal expects its 2nd input parameter to be of type string, but the actual input type is tinyint (in line 52, at column 1)</expected-warn>
+        <expected-warn>Type mismatch: function split expects its 2nd input parameter to be of type string, but the actual input type is tinyint (in line 57, at column 1)</expected-warn>
+        <expected-warn>Type mismatch: function string-to-codepoint expects its 1st input parameter to be of type string, but the actual input type is bigint (in line 31, at column 1)</expected-warn>
+        <expected-warn>Type mismatch: function trim expects its 1st input parameter to be of type string, but the actual input type is integer (in line 36, at column 1)</expected-warn>
+        <expected-warn>Type mismatch: function reverse expects its 1st input parameter to be of type string, but the actual input type is integer (in line 54, at column 1)</expected-warn>
+        <expected-warn>Type mismatch: function like expects its 2nd input parameter to be of type string, but the actual input type is tinyint (in line 28, at column 1)</expected-warn>
+        <expected-warn>Type mismatch: function contains expects its 2nd input parameter to be of type string, but the actual input type is tinyint (in line 30, at column 1)</expected-warn>
+        <expected-warn>Type mismatch: function ltrim expects its 1st input parameter to be of type string, but the actual input type is smallint (in line 38, at column 1)</expected-warn>
+        <expected-warn>Type mismatch: function initcap expects its 1st input parameter to be of type string, but the actual input type is bigint (in line 35, at column 1)</expected-warn>
+        <expected-warn>Type mismatch: function ltrim expects its 2nd input parameter to be of type string, but the actual input type is tinyint (in line 39, at column 1)</expected-warn>
+        <expected-warn>Type mismatch: function string-length expects its 1st input parameter to be of type string, but the actual input type is integer (in line 32, at column 1)</expected-warn>
+        <expected-warn>Type mismatch: function like expects its 1st input parameter to be of type string, but the actual input type is tinyint (in line 29, at column 1)</expected-warn>
+        <expected-warn>Type mismatch: function regexp-position expects its 1st input parameter to be of type string, but the actual input type is integer (in line 49, at column 1)</expected-warn>
+      </compilation-unit>
+    </test-case>
+  </test-group>
 </test-suite>
diff --git a/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/exceptions/ExceptionUtil.java b/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/exceptions/ExceptionUtil.java
index bdcb201..6c92673 100644
--- a/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/exceptions/ExceptionUtil.java
+++ b/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/exceptions/ExceptionUtil.java
@@ -19,6 +19,15 @@
 
 package org.apache.asterix.om.exceptions;
 
+import org.apache.asterix.common.exceptions.ErrorCode;
+import org.apache.asterix.common.exceptions.WarningUtil;
+import org.apache.asterix.om.types.ATypeTag;
+import org.apache.asterix.om.types.EnumDeserializer;
+import org.apache.hyracks.algebricks.core.algebra.functions.FunctionIdentifier;
+import org.apache.hyracks.algebricks.runtime.base.IEvaluatorContext;
+import org.apache.hyracks.api.exceptions.IWarningCollector;
+import org.apache.hyracks.api.exceptions.SourceLocation;
+
 public class ExceptionUtil {
 
     private ExceptionUtil() {
@@ -40,6 +49,22 @@ public class ExceptionUtil {
         return expectedTypes.toString();
     }
 
+    public static String toExpectedTypeString(byte... expectedTypeTags) {
+        StringBuilder expectedTypes = new StringBuilder();
+        int numCandidateTypes = expectedTypeTags.length;
+        for (int index = 0; index < numCandidateTypes; ++index) {
+            if (index > 0) {
+                if (index == numCandidateTypes - 1) {
+                    expectedTypes.append(" or ");
+                } else {
+                    expectedTypes.append(", ");
+                }
+            }
+            expectedTypes.append(EnumDeserializer.ATYPETAGDESERIALIZER.deserialize(expectedTypeTags[index]));
+        }
+        return expectedTypes.toString();
+    }
+
     public static String indexToPosition(int index) {
         int i = index + 1;
         switch (i % 100) {
@@ -60,4 +85,40 @@ public class ExceptionUtil {
                 }
         }
     }
+
+    public static void warnTypeMismatch(IEvaluatorContext ctx, SourceLocation srcLoc, FunctionIdentifier fid,
+            int argIdx, byte actualType, ATypeTag expectedType) {
+        IWarningCollector warningCollector = ctx.getWarningCollector();
+        if (warningCollector.shouldWarn()) {
+            warningCollector.warn(WarningUtil.forAsterix(srcLoc, ErrorCode.TYPE_MISMATCH_FUNCTION, fid.getName(),
+                    indexToPosition(argIdx), expectedType,
+                    EnumDeserializer.ATYPETAGDESERIALIZER.deserialize(actualType)));
+        }
+    }
+
+    public static void warnTypeMismatch(IEvaluatorContext ctx, SourceLocation srcLoc, FunctionIdentifier fid,
+            byte actualType, int argIdx, byte... expectedTypes) {
+        IWarningCollector warningCollector = ctx.getWarningCollector();
+        if (warningCollector.shouldWarn()) {
+            warningCollector.warn(WarningUtil.forAsterix(srcLoc, ErrorCode.TYPE_MISMATCH_FUNCTION, fid.getName(),
+                    indexToPosition(argIdx), toExpectedTypeString(expectedTypes),
+                    EnumDeserializer.ATYPETAGDESERIALIZER.deserialize(actualType)));
+        }
+    }
+
+    public static void warnIncompatibleType(IEvaluatorContext ctx, SourceLocation srcLoc, String funName,
+            ATypeTag type1, ATypeTag type2) {
+        IWarningCollector warningCollector = ctx.getWarningCollector();
+        if (warningCollector.shouldWarn()) {
+            warningCollector.warn(WarningUtil.forAsterix(srcLoc, ErrorCode.TYPE_INCOMPATIBLE, funName, type1, type2));
+        }
+    }
+
+    public static void warnUnsupportedType(IEvaluatorContext ctx, SourceLocation srcLoc, String funName,
+            ATypeTag unsupportedType) {
+        IWarningCollector warningCollector = ctx.getWarningCollector();
+        if (warningCollector.shouldWarn()) {
+            warningCollector.warn(WarningUtil.forAsterix(srcLoc, ErrorCode.TYPE_UNSUPPORTED, funName, unsupportedType));
+        }
+    }
 }
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 e96d455..417fa13 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
@@ -1695,13 +1695,14 @@ public class BuiltinFunctions {
         addFunction(IS_BIT_SET_WITHOUT_ALL_FLAG, BitValuePositionFlagTypeComputer.INSTANCE_TEST_WITHOUT_FLAG, true);
         addFunction(IS_BIT_SET_WITH_ALL_FLAG, BitValuePositionFlagTypeComputer.INSTANCE_TEST_WITH_FLAG, true);
 
-        addFunction(STRING_CONSTRUCTOR, AStringTypeComputer.INSTANCE, true);
+        // string functions
+        addFunction(STRING_CONSTRUCTOR, AStringTypeComputer.INSTANCE, true); // TODO
         addFunction(STRING_LIKE, BooleanFunctionTypeComputer.INSTANCE, true);
-        addFunction(STRING_CONTAINS, ABooleanTypeComputer.INSTANCE, true);
+        addFunction(STRING_CONTAINS, StringBooleanTypeComputer.INSTANCE, true);
         addFunction(STRING_TO_CODEPOINT, StringToInt64ListTypeComputer.INSTANCE, true);
-        addFunction(CODEPOINT_TO_STRING, AStringTypeComputer.INSTANCE, true);
-        addFunction(STRING_CONCAT, ConcatTypeComputer.INSTANCE_STRING, true);
-        addFunction(SUBSTRING2, StringIntToStringTypeComputer.INSTANCE_NULLABLE, true);
+        addFunction(CODEPOINT_TO_STRING, AStringTypeComputer.INSTANCE, true); // TODO
+        addFunction(STRING_CONCAT, ConcatTypeComputer.INSTANCE_STRING, true); // TODO
+        addFunction(SUBSTRING2, StringIntToStringTypeComputer.INSTANCE_NULLABLE, true); // TODO
         addFunction(STRING_LENGTH, UnaryStringInt64TypeComputer.INSTANCE, true);
         addFunction(STRING_LOWERCASE, StringStringTypeComputer.INSTANCE, true);
         addFunction(STRING_UPPERCASE, StringStringTypeComputer.INSTANCE, true);
@@ -1723,15 +1724,15 @@ public class BuiltinFunctions {
         addFunction(STRING_REGEXP_POSITION_WITH_FLAG, StringInt32TypeComputer.INSTANCE, true);
         addFunction(STRING_REGEXP_REPLACE, StringStringTypeComputer.INSTANCE, true);
         addFunction(STRING_REGEXP_REPLACE_WITH_FLAG,
-                StringIntToStringTypeComputer.INSTANCE_STRING_REGEXP_REPLACE_WITH_FLAG, true);
+                StringIntToStringTypeComputer.INSTANCE_STRING_REGEXP_REPLACE_WITH_FLAG, true); // TODO
         addFunction(STRING_REPLACE, StringStringTypeComputer.INSTANCE, true);
-        addFunction(STRING_REPLACE_WITH_LIMIT, StringIntToStringTypeComputer.INSTANCE_TRIPLE_STRING, true);
+        addFunction(STRING_REPLACE_WITH_LIMIT, StringIntToStringTypeComputer.INSTANCE_TRIPLE_STRING, true); // TODO
         addFunction(STRING_REVERSE, StringStringTypeComputer.INSTANCE, true);
         addFunction(SUBSTRING_BEFORE, StringStringTypeComputer.INSTANCE, true);
         addFunction(SUBSTRING_AFTER, StringStringTypeComputer.INSTANCE, true);
         addPrivateFunction(STRING_EQUAL, StringBooleanTypeComputer.INSTANCE, true);
-        addFunction(STRING_JOIN, AStringTypeComputer.INSTANCE, true);
-        addFunction(STRING_REPEAT, StringIntToStringTypeComputer.INSTANCE, true);
+        addFunction(STRING_JOIN, AStringTypeComputer.INSTANCE, true); // TODO
+        addFunction(STRING_REPEAT, StringIntToStringTypeComputer.INSTANCE, true); // TODO
         addFunction(STRING_SPLIT, StringToStringListTypeComputer.INSTANCE, true);
 
         addPrivateFunction(ORDERED_LIST_CONSTRUCTOR, OrderedListConstructorTypeComputer.INSTANCE, true);
diff --git a/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/typecomputer/impl/AbstractStringTypeComputer.java b/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/typecomputer/impl/AbstractStringTypeComputer.java
index b24fab5..d888958 100644
--- a/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/typecomputer/impl/AbstractStringTypeComputer.java
+++ b/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/typecomputer/impl/AbstractStringTypeComputer.java
@@ -18,27 +18,27 @@
  */
 package org.apache.asterix.om.typecomputer.impl;
 
-import org.apache.asterix.om.exceptions.TypeMismatchException;
 import org.apache.asterix.om.typecomputer.base.AbstractResultTypeComputer;
 import org.apache.asterix.om.types.ATypeTag;
+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.functions.FunctionIdentifier;
-import org.apache.hyracks.api.exceptions.SourceLocation;
 
 abstract public class AbstractStringTypeComputer extends AbstractResultTypeComputer {
 
-    @Override
-    protected void checkArgType(FunctionIdentifier funcId, int argIndex, IAType type, SourceLocation sourceLoc)
-            throws AlgebricksException {
-        ATypeTag actualTypeTag = type.getTypeTag();
-        if (actualTypeTag != ATypeTag.STRING) {
-            throw new TypeMismatchException(sourceLoc, funcId, argIndex, actualTypeTag, ATypeTag.STRING);
+    protected IAType getType(IAType returnType, IAType... argsTypes) {
+        // all args are expected to be strings. If any arg is not string (ANY or mismatched-type), return nullable
+        for (IAType actualType : argsTypes) {
+            if (actualType.getTypeTag() != ATypeTag.STRING) {
+                return AUnionType.createNullableType(returnType);
+            }
         }
+        return returnType;
     }
 
-    @Override
-    protected abstract IAType getResultType(ILogicalExpression expr, IAType... strippedInputTypes)
-            throws AlgebricksException;
+    protected IAType getType(IAType returnType, IAType argType) {
+        if (argType.getTypeTag() != ATypeTag.STRING) {
+            return AUnionType.createNullableType(returnType);
+        }
+        return returnType;
+    }
 }
diff --git a/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/typecomputer/impl/StringBooleanTypeComputer.java b/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/typecomputer/impl/StringBooleanTypeComputer.java
index 6c1d62e..032b7be 100644
--- a/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/typecomputer/impl/StringBooleanTypeComputer.java
+++ b/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/typecomputer/impl/StringBooleanTypeComputer.java
@@ -23,6 +23,9 @@ import org.apache.asterix.om.types.IAType;
 import org.apache.hyracks.algebricks.common.exceptions.AlgebricksException;
 import org.apache.hyracks.algebricks.core.algebra.base.ILogicalExpression;
 
+/**
+ * For function signature: nullable_boolean fun(string...)
+ */
 public class StringBooleanTypeComputer extends AbstractStringTypeComputer {
     public static final StringBooleanTypeComputer INSTANCE = new StringBooleanTypeComputer();
 
@@ -31,6 +34,6 @@ public class StringBooleanTypeComputer extends AbstractStringTypeComputer {
 
     @Override
     public IAType getResultType(ILogicalExpression expr, IAType... types) throws AlgebricksException {
-        return BuiltinType.ABOOLEAN;
+        return getType(BuiltinType.ABOOLEAN, types);
     }
 }
diff --git a/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/typecomputer/impl/StringInt32TypeComputer.java b/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/typecomputer/impl/StringInt32TypeComputer.java
index 22b3246..8f888e2 100644
--- a/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/typecomputer/impl/StringInt32TypeComputer.java
+++ b/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/typecomputer/impl/StringInt32TypeComputer.java
@@ -24,6 +24,9 @@ import org.apache.asterix.om.types.IAType;
 import org.apache.hyracks.algebricks.common.exceptions.AlgebricksException;
 import org.apache.hyracks.algebricks.core.algebra.base.ILogicalExpression;
 
+/**
+ * For function signature: nullable_int32 fun(string...)
+ */
 public class StringInt32TypeComputer extends AbstractStringTypeComputer {
     public static final StringInt32TypeComputer INSTANCE = new StringInt32TypeComputer();
 
@@ -32,6 +35,6 @@ public class StringInt32TypeComputer extends AbstractStringTypeComputer {
 
     @Override
     public IAType getResultType(ILogicalExpression expr, IAType... types) throws AlgebricksException {
-        return BuiltinType.AINT32;
+        return getType(BuiltinType.AINT32, types);
     }
 }
diff --git a/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/typecomputer/impl/StringStringTypeComputer.java b/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/typecomputer/impl/StringStringTypeComputer.java
index 5e81d7f..cb9ec8e 100644
--- a/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/typecomputer/impl/StringStringTypeComputer.java
+++ b/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/typecomputer/impl/StringStringTypeComputer.java
@@ -23,6 +23,9 @@ import org.apache.asterix.om.types.IAType;
 import org.apache.hyracks.algebricks.common.exceptions.AlgebricksException;
 import org.apache.hyracks.algebricks.core.algebra.base.ILogicalExpression;
 
+/**
+ * For function signature: nullable_string fun(string...)
+ */
 public class StringStringTypeComputer extends AbstractStringTypeComputer {
     public static final StringStringTypeComputer INSTANCE = new StringStringTypeComputer();
 
@@ -31,7 +34,6 @@ public class StringStringTypeComputer extends AbstractStringTypeComputer {
 
     @Override
     public IAType getResultType(ILogicalExpression expr, IAType... inputTypes) throws AlgebricksException {
-        return BuiltinType.ASTRING;
+        return getType(BuiltinType.ASTRING, inputTypes);
     }
-
 }
diff --git a/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/typecomputer/impl/StringToInt64ListTypeComputer.java b/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/typecomputer/impl/StringToInt64ListTypeComputer.java
index b01ac71..e138d44 100644
--- a/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/typecomputer/impl/StringToInt64ListTypeComputer.java
+++ b/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/typecomputer/impl/StringToInt64ListTypeComputer.java
@@ -25,6 +25,9 @@ import org.apache.asterix.om.types.IAType;
 import org.apache.hyracks.algebricks.common.exceptions.AlgebricksException;
 import org.apache.hyracks.algebricks.core.algebra.base.ILogicalExpression;
 
+/**
+ * For function signature: nullable[int64] fun(string...)
+ */
 public class StringToInt64ListTypeComputer extends AbstractStringTypeComputer {
 
     public static final StringToInt64ListTypeComputer INSTANCE = new StringToInt64ListTypeComputer();
@@ -34,6 +37,6 @@ public class StringToInt64ListTypeComputer extends AbstractStringTypeComputer {
 
     @Override
     protected IAType getResultType(ILogicalExpression expr, IAType... strippedInputTypes) throws AlgebricksException {
-        return new AOrderedListType(BuiltinType.AINT64, null);
+        return getType(new AOrderedListType(BuiltinType.AINT64, null), strippedInputTypes);
     }
 }
\ No newline at end of file
diff --git a/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/typecomputer/impl/StringToStringListTypeComputer.java b/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/typecomputer/impl/StringToStringListTypeComputer.java
index 4891330..66dfe09 100644
--- a/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/typecomputer/impl/StringToStringListTypeComputer.java
+++ b/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/typecomputer/impl/StringToStringListTypeComputer.java
@@ -25,6 +25,9 @@ import org.apache.asterix.om.types.IAType;
 import org.apache.hyracks.algebricks.common.exceptions.AlgebricksException;
 import org.apache.hyracks.algebricks.core.algebra.base.ILogicalExpression;
 
+/**
+ * For function signature: nullable[string] fun(string...)
+ */
 public class StringToStringListTypeComputer extends AbstractStringTypeComputer {
 
     public static final StringToStringListTypeComputer INSTANCE = new StringToStringListTypeComputer();
@@ -34,6 +37,6 @@ public class StringToStringListTypeComputer extends AbstractStringTypeComputer {
 
     @Override
     protected IAType getResultType(ILogicalExpression expr, IAType... strippedInputTypes) throws AlgebricksException {
-        return new AOrderedListType(BuiltinType.ASTRING, null);
+        return getType(new AOrderedListType(BuiltinType.ASTRING, null), strippedInputTypes);
     }
-}
\ No newline at end of file
+}
diff --git a/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/typecomputer/impl/UnaryStringInt64TypeComputer.java b/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/typecomputer/impl/UnaryStringInt64TypeComputer.java
index 344da43..37c2230 100644
--- a/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/typecomputer/impl/UnaryStringInt64TypeComputer.java
+++ b/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/typecomputer/impl/UnaryStringInt64TypeComputer.java
@@ -18,17 +18,15 @@
  */
 package org.apache.asterix.om.typecomputer.impl;
 
-import org.apache.asterix.om.exceptions.TypeMismatchException;
-import org.apache.asterix.om.typecomputer.base.AbstractResultTypeComputer;
-import org.apache.asterix.om.types.ATypeTag;
 import org.apache.asterix.om.types.BuiltinType;
 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.functions.FunctionIdentifier;
-import org.apache.hyracks.api.exceptions.SourceLocation;
 
-public class UnaryStringInt64TypeComputer extends AbstractResultTypeComputer {
+/**
+ * For function signature: nullable_int64 fun(string)
+ */
+public class UnaryStringInt64TypeComputer extends AbstractStringTypeComputer {
 
     public static final UnaryStringInt64TypeComputer INSTANCE = new UnaryStringInt64TypeComputer();
 
@@ -36,16 +34,7 @@ public class UnaryStringInt64TypeComputer extends AbstractResultTypeComputer {
     }
 
     @Override
-    public void checkArgType(FunctionIdentifier funcId, int argIndex, IAType type, SourceLocation sourceLoc)
-            throws AlgebricksException {
-        ATypeTag tag = type.getTypeTag();
-        if (tag != ATypeTag.STRING) {
-            throw new TypeMismatchException(sourceLoc, funcId, argIndex, tag, ATypeTag.STRING);
-        }
-    }
-
-    @Override
     public IAType getResultType(ILogicalExpression expr, IAType... types) throws AlgebricksException {
-        return BuiltinType.AINT64;
+        return getType(BuiltinType.AINT64, types[0]);
     }
 }
diff --git a/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/aggregates/std/AbstractMinMaxAggregateFunction.java b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/aggregates/std/AbstractMinMaxAggregateFunction.java
index ce7e3c8..022e0f5 100644
--- a/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/aggregates/std/AbstractMinMaxAggregateFunction.java
+++ b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/aggregates/std/AbstractMinMaxAggregateFunction.java
@@ -22,11 +22,10 @@ import static org.apache.asterix.om.types.ATypeTag.VALUE_TYPE_MAPPING;
 
 import java.io.IOException;
 
-import org.apache.asterix.common.exceptions.ErrorCode;
-import org.apache.asterix.common.exceptions.WarningUtil;
 import org.apache.asterix.dataflow.data.common.ILogicalBinaryComparator;
 import org.apache.asterix.dataflow.data.common.TaggedValueReference;
 import org.apache.asterix.dataflow.data.nontagged.comparators.ComparatorUtil;
+import org.apache.asterix.om.exceptions.ExceptionUtil;
 import org.apache.asterix.om.types.ATypeTag;
 import org.apache.asterix.om.types.EnumDeserializer;
 import org.apache.asterix.om.types.IAType;
@@ -37,7 +36,6 @@ import org.apache.hyracks.algebricks.runtime.base.IEvaluatorContext;
 import org.apache.hyracks.algebricks.runtime.base.IScalarEvaluator;
 import org.apache.hyracks.algebricks.runtime.base.IScalarEvaluatorFactory;
 import org.apache.hyracks.api.exceptions.HyracksDataException;
-import org.apache.hyracks.api.exceptions.IWarningCollector;
 import org.apache.hyracks.api.exceptions.SourceLocation;
 import org.apache.hyracks.data.std.api.IPointable;
 import org.apache.hyracks.data.std.primitive.VoidPointable;
@@ -45,6 +43,7 @@ import org.apache.hyracks.data.std.util.ArrayBackedValueStorage;
 import org.apache.hyracks.dataflow.common.data.accessors.IFrameTupleReference;
 
 public abstract class AbstractMinMaxAggregateFunction extends AbstractAggregateFunction {
+    private final String FUN_NAME = "min/max";
     private final ArrayBackedValueStorage resultStorage = new ArrayBackedValueStorage();
     private final IPointable inputVal = new VoidPointable();
     private final ArrayBackedValueStorage outputVal = new ArrayBackedValueStorage();
@@ -88,7 +87,7 @@ public abstract class AbstractMinMaxAggregateFunction extends AbstractAggregateF
         } else if (typeTag == ATypeTag.SYSTEM_NULL) {
             // if a system_null is encountered locally, it would be an error; otherwise it is ignored
             if (type == Type.LOCAL) {
-                throw new UnsupportedItemTypeException(sourceLoc, "min/max", ATypeTag.SERIALIZED_SYSTEM_NULL_TYPE_TAG);
+                throw new UnsupportedItemTypeException(sourceLoc, FUN_NAME, ATypeTag.SERIALIZED_SYSTEM_NULL_TYPE_TAG);
             }
         } else if (aggType == ATypeTag.SYSTEM_NULL) {
             // First value encountered. Set type, comparator, and initial value.
@@ -162,19 +161,12 @@ public abstract class AbstractMinMaxAggregateFunction extends AbstractAggregateF
     }
 
     private void handleIncompatibleInput(ATypeTag typeTag) {
-        IWarningCollector warningCollector = context.getWarningCollector();
-        if (warningCollector.shouldWarn()) {
-            warningCollector
-                    .warn(WarningUtil.forAsterix(sourceLoc, ErrorCode.TYPE_INCOMPATIBLE, "min/max", aggType, typeTag));
-        }
+        ExceptionUtil.warnIncompatibleType(context, sourceLoc, FUN_NAME, aggType, typeTag);
         this.aggType = ATypeTag.NULL;
     }
 
     private void handleUnsupportedInput(ATypeTag typeTag) {
-        IWarningCollector warningCollector = context.getWarningCollector();
-        if (warningCollector.shouldWarn()) {
-            warningCollector.warn(WarningUtil.forAsterix(sourceLoc, ErrorCode.TYPE_UNSUPPORTED, "min/max", typeTag));
-        }
+        ExceptionUtil.warnUnsupportedType(context, sourceLoc, FUN_NAME, typeTag);
         this.aggType = ATypeTag.NULL;
     }
 
diff --git a/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/AbstractBinaryStringEval.java b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/AbstractBinaryStringEval.java
index 293d14a..808239d 100644
--- a/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/AbstractBinaryStringEval.java
+++ b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/AbstractBinaryStringEval.java
@@ -22,8 +22,8 @@ package org.apache.asterix.runtime.evaluators.functions;
 import java.io.DataOutput;
 import java.io.IOException;
 
+import org.apache.asterix.om.exceptions.ExceptionUtil;
 import org.apache.asterix.om.types.ATypeTag;
-import org.apache.asterix.runtime.exceptions.TypeMismatchException;
 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;
@@ -38,19 +38,20 @@ import org.apache.hyracks.dataflow.common.data.accessors.IFrameTupleReference;
 
 public abstract class AbstractBinaryStringEval implements IScalarEvaluator {
 
+    private final IEvaluatorContext ctx;
     // Argument evaluators.
-    private IScalarEvaluator evalLeft;
-    private IScalarEvaluator evalRight;
+    private final IScalarEvaluator evalLeft;
+    private final IScalarEvaluator evalRight;
 
     // Argument pointables.
-    private IPointable argPtrLeft = new VoidPointable();
-    private IPointable argPtrSecond = new VoidPointable();
+    private final IPointable argPtrLeft = new VoidPointable();
+    private final IPointable argPtrSecond = new VoidPointable();
     private final UTF8StringPointable leftPtr = new UTF8StringPointable();
     private final UTF8StringPointable rightPtr = new UTF8StringPointable();
 
     // For results.
-    protected ArrayBackedValueStorage resultStorage = new ArrayBackedValueStorage();
-    protected DataOutput dataOutput = resultStorage.getDataOutput();
+    protected final ArrayBackedValueStorage resultStorage = new ArrayBackedValueStorage();
+    protected final DataOutput dataOutput = resultStorage.getDataOutput();
 
     // Function ID, for error reporting.
     private final FunctionIdentifier funcID;
@@ -63,6 +64,7 @@ public abstract class AbstractBinaryStringEval implements IScalarEvaluator {
         this.evalLeft = evalLeftFactory.createScalarEvaluator(context);
         this.evalRight = evalRightFactory.createScalarEvaluator(context);
         this.funcID = funcID;
+        this.ctx = context;
     }
 
     @SuppressWarnings("unchecked")
@@ -87,10 +89,14 @@ public abstract class AbstractBinaryStringEval implements IScalarEvaluator {
 
         // Type check.
         if (bytes0[offset0] != ATypeTag.SERIALIZED_STRING_TYPE_TAG) {
-            throw new TypeMismatchException(sourceLoc, funcID, 0, bytes0[offset0], ATypeTag.SERIALIZED_STRING_TYPE_TAG);
+            PointableHelper.setNull(resultPointable);
+            ExceptionUtil.warnTypeMismatch(ctx, sourceLoc, funcID, 0, bytes0[offset0], ATypeTag.STRING);
+            return;
         }
         if (bytes1[offset1] != ATypeTag.SERIALIZED_STRING_TYPE_TAG) {
-            throw new TypeMismatchException(sourceLoc, funcID, 1, bytes1[offset1], ATypeTag.SERIALIZED_STRING_TYPE_TAG);
+            PointableHelper.setNull(resultPointable);
+            ExceptionUtil.warnTypeMismatch(ctx, sourceLoc, funcID, 1, bytes1[offset1], ATypeTag.STRING);
+            return;
         }
 
         // Sets StringUTF8Pointables.
diff --git a/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/AbstractScalarEval.java b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/AbstractScalarEval.java
index 72d4bdc..6cb3666 100644
--- a/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/AbstractScalarEval.java
+++ b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/AbstractScalarEval.java
@@ -19,15 +19,8 @@
 
 package org.apache.asterix.runtime.evaluators.functions;
 
-import org.apache.asterix.common.exceptions.ErrorCode;
-import org.apache.asterix.common.exceptions.WarningUtil;
-import org.apache.asterix.om.types.ATypeTag;
-import org.apache.asterix.om.types.EnumDeserializer;
-import org.apache.asterix.runtime.exceptions.ExceptionUtil;
 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.api.exceptions.IWarningCollector;
 import org.apache.hyracks.api.exceptions.SourceLocation;
 
 public abstract class AbstractScalarEval implements IScalarEvaluator {
@@ -38,25 +31,4 @@ public abstract class AbstractScalarEval implements IScalarEvaluator {
         this.sourceLoc = sourceLoc;
         this.functionIdentifier = functionIdentifier;
     }
-
-    protected void handleTypeMismatchInput(IEvaluatorContext context, int inputPosition, ATypeTag expected,
-            byte[] actualTypeBytes, int startOffset) {
-        IWarningCollector warningCollector = context.getWarningCollector();
-        if (warningCollector.shouldWarn()) {
-            ATypeTag actual = EnumDeserializer.ATYPETAGDESERIALIZER.deserialize(actualTypeBytes[startOffset]);
-            warningCollector.warn(WarningUtil.forAsterix(sourceLoc, ErrorCode.TYPE_MISMATCH_FUNCTION,
-                    functionIdentifier, ExceptionUtil.indexToPosition(inputPosition), expected, actual));
-        }
-    }
-
-    protected void handleTypeMismatchInput(IEvaluatorContext context, int inputPosition, byte[] expected,
-            byte[] actualTypeBytes, int startOffset) {
-        IWarningCollector warningCollector = context.getWarningCollector();
-        if (warningCollector.shouldWarn()) {
-            ATypeTag actual = EnumDeserializer.ATYPETAGDESERIALIZER.deserialize(actualTypeBytes[startOffset]);
-            warningCollector.warn(WarningUtil.forAsterix(sourceLoc, ErrorCode.TYPE_MISMATCH_FUNCTION,
-                    functionIdentifier, ExceptionUtil.indexToPosition(inputPosition),
-                    ExceptionUtil.toExpectedTypeString(expected), actual));
-        }
-    }
 }
diff --git a/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/AbstractTripleStringEval.java b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/AbstractTripleStringEval.java
index 4d7b871..24abd09 100644
--- a/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/AbstractTripleStringEval.java
+++ b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/AbstractTripleStringEval.java
@@ -21,8 +21,8 @@ package org.apache.asterix.runtime.evaluators.functions;
 
 import java.io.DataOutput;
 
+import org.apache.asterix.om.exceptions.ExceptionUtil;
 import org.apache.asterix.om.types.ATypeTag;
-import org.apache.asterix.runtime.exceptions.TypeMismatchException;
 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;
@@ -37,6 +37,7 @@ import org.apache.hyracks.dataflow.common.data.accessors.IFrameTupleReference;
 
 abstract class AbstractTripleStringEval implements IScalarEvaluator {
 
+    private final IEvaluatorContext ctx;
     // Argument evaluators.
     private IScalarEvaluator eval0;
     private IScalarEvaluator eval1;
@@ -66,6 +67,7 @@ abstract class AbstractTripleStringEval implements IScalarEvaluator {
         this.eval2 = eval2.createScalarEvaluator(context);
         this.funcID = funcID;
         this.sourceLoc = sourceLoc;
+        this.ctx = context;
     }
 
     @SuppressWarnings("unchecked")
@@ -93,13 +95,19 @@ abstract class AbstractTripleStringEval implements IScalarEvaluator {
 
         // Type check.
         if (bytes0[start0] != ATypeTag.SERIALIZED_STRING_TYPE_TAG) {
-            throw new TypeMismatchException(sourceLoc, funcID, 0, bytes0[start0], ATypeTag.SERIALIZED_STRING_TYPE_TAG);
+            PointableHelper.setNull(result);
+            ExceptionUtil.warnTypeMismatch(ctx, sourceLoc, funcID, 0, bytes0[start0], ATypeTag.STRING);
+            return;
         }
         if (bytes1[start1] != ATypeTag.SERIALIZED_STRING_TYPE_TAG) {
-            throw new TypeMismatchException(sourceLoc, funcID, 1, bytes1[start1], ATypeTag.SERIALIZED_STRING_TYPE_TAG);
+            PointableHelper.setNull(result);
+            ExceptionUtil.warnTypeMismatch(ctx, sourceLoc, funcID, 1, bytes1[start1], ATypeTag.STRING);
+            return;
         }
         if (bytes2[start2] != ATypeTag.SERIALIZED_STRING_TYPE_TAG) {
-            throw new TypeMismatchException(sourceLoc, funcID, 2, bytes2[start2], ATypeTag.SERIALIZED_STRING_TYPE_TAG);
+            PointableHelper.setNull(result);
+            ExceptionUtil.warnTypeMismatch(ctx, sourceLoc, funcID, 2, bytes2[start2], ATypeTag.STRING);
+            return;
         }
 
         // Sets argument UTF8Pointables.
diff --git a/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/AbstractUnaryStringStringEval.java b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/AbstractUnaryStringStringEval.java
index 93de219..d8f9132 100644
--- a/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/AbstractUnaryStringStringEval.java
+++ b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/AbstractUnaryStringStringEval.java
@@ -22,8 +22,8 @@ package org.apache.asterix.runtime.evaluators.functions;
 import java.io.DataOutput;
 import java.io.IOException;
 
+import org.apache.asterix.om.exceptions.ExceptionUtil;
 import org.apache.asterix.om.types.ATypeTag;
-import org.apache.asterix.runtime.exceptions.TypeMismatchException;
 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;
@@ -40,6 +40,7 @@ import org.apache.hyracks.dataflow.common.data.accessors.IFrameTupleReference;
 
 abstract class AbstractUnaryStringStringEval implements IScalarEvaluator {
 
+    private final IEvaluatorContext ctx;
     // For the argument.
     private final IScalarEvaluator argEval;
     private final VoidPointable argPtr = new VoidPointable();
@@ -58,6 +59,7 @@ abstract class AbstractUnaryStringStringEval implements IScalarEvaluator {
         this.argEval = argEvalFactory.createScalarEvaluator(context);
         this.funcID = funcID;
         this.sourceLoc = sourceLoc;
+        this.ctx = context;
     }
 
     @Override
@@ -73,8 +75,9 @@ abstract class AbstractUnaryStringStringEval implements IScalarEvaluator {
         int offset = argPtr.getStartOffset();
         byte inputTypeTag = argBytes[offset];
         if (inputTypeTag != ATypeTag.SERIALIZED_STRING_TYPE_TAG) {
-            throw new TypeMismatchException(sourceLoc, funcID, 0, argBytes[offset],
-                    ATypeTag.SERIALIZED_STRING_TYPE_TAG);
+            PointableHelper.setNull(resultPointable);
+            ExceptionUtil.warnTypeMismatch(ctx, sourceLoc, funcID, 0, argBytes[offset], ATypeTag.STRING);
+            return;
         }
         stringPtr.set(argBytes, offset + 1, argPtr.getLength() - 1);
         resultArray.reset();
diff --git a/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/StringLengthDescriptor.java b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/StringLengthDescriptor.java
index 68995af..ed6d270 100644
--- a/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/StringLengthDescriptor.java
+++ b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/StringLengthDescriptor.java
@@ -25,13 +25,13 @@ import org.apache.asterix.common.annotations.MissingNullInOutFunction;
 import org.apache.asterix.formats.nontagged.SerializerDeserializerProvider;
 import org.apache.asterix.om.base.AInt64;
 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.om.types.BuiltinType;
 import org.apache.asterix.runtime.evaluators.base.AbstractScalarFunctionDynamicDescriptor;
-import org.apache.asterix.runtime.exceptions.TypeMismatchException;
 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;
@@ -85,14 +85,15 @@ public class StringLengthDescriptor extends AbstractScalarFunctionDynamicDescrip
                             byte[] serString = inputArg.getByteArray();
                             int offset = inputArg.getStartOffset();
 
-                            if (serString[offset] == ATypeTag.SERIALIZED_STRING_TYPE_TAG) {
-                                int len = UTF8StringUtil.getUTFLength(serString, offset + 1);
-                                result.setValue(len);
-                                int64Serde.serialize(result, out);
-                            } else {
-                                throw new TypeMismatchException(sourceLoc, getIdentifier(), 0, serString[offset],
-                                        ATypeTag.SERIALIZED_STRING_TYPE_TAG);
+                            if (serString[offset] != ATypeTag.SERIALIZED_STRING_TYPE_TAG) {
+                                PointableHelper.setNull(resultPointable);
+                                ExceptionUtil.warnTypeMismatch(ctx, sourceLoc, getIdentifier(), 0, serString[offset],
+                                        ATypeTag.STRING);
+                                return;
                             }
+                            int len = UTF8StringUtil.getUTFLength(serString, offset + 1);
+                            result.setValue(len);
+                            int64Serde.serialize(result, out);
                             resultPointable.set(resultStorage);
                         } catch (IOException e1) {
                             throw HyracksDataException.create(e1);
@@ -107,5 +108,4 @@ public class StringLengthDescriptor extends AbstractScalarFunctionDynamicDescrip
     public FunctionIdentifier getIdentifier() {
         return BuiltinFunctions.STRING_LENGTH;
     }
-
 }
diff --git a/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/StringSplitDescriptor.java b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/StringSplitDescriptor.java
index 7b07b88..69ddbd3 100644
--- a/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/StringSplitDescriptor.java
+++ b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/StringSplitDescriptor.java
@@ -24,6 +24,7 @@ import java.io.IOException;
 
 import org.apache.asterix.builders.OrderedListBuilder;
 import org.apache.asterix.common.annotations.MissingNullInOutFunction;
+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;
@@ -31,7 +32,6 @@ import org.apache.asterix.om.types.AOrderedListType;
 import org.apache.asterix.om.types.ATypeTag;
 import org.apache.asterix.om.types.BuiltinType;
 import org.apache.asterix.runtime.evaluators.base.AbstractScalarFunctionDynamicDescriptor;
-import org.apache.asterix.runtime.exceptions.TypeMismatchException;
 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;
@@ -103,8 +103,10 @@ public class StringSplitDescriptor extends AbstractScalarFunctionDynamicDescript
                             int srcLen = argString.getLength();
                             // Type check for the first argument.
                             if (srcString[srcOffset] != ATypeTag.SERIALIZED_STRING_TYPE_TAG) {
-                                throw new TypeMismatchException(sourceLoc, getIdentifier(), 0, srcString[srcOffset],
-                                        ATypeTag.SERIALIZED_STRING_TYPE_TAG);
+                                PointableHelper.setNull(result);
+                                ExceptionUtil.warnTypeMismatch(ctx, sourceLoc, getIdentifier(), 0, srcString[srcOffset],
+                                        ATypeTag.STRING);
+                                return;
                             }
 
                             // Gets the bytes of the pattern string.
@@ -113,8 +115,10 @@ public class StringSplitDescriptor extends AbstractScalarFunctionDynamicDescript
                             int patternLen = argPattern.getLength();
                             // Type check for the second argument.
                             if (patternString[patternOffset] != ATypeTag.SERIALIZED_STRING_TYPE_TAG) {
-                                throw new TypeMismatchException(sourceLoc, getIdentifier(), 1,
-                                        patternString[patternOffset], ATypeTag.SERIALIZED_STRING_TYPE_TAG);
+                                PointableHelper.setNull(result);
+                                ExceptionUtil.warnTypeMismatch(ctx, sourceLoc, getIdentifier(), 1,
+                                        patternString[patternOffset], ATypeTag.STRING);
+                                return;
                             }
 
                             // Sets the UTF8 String pointables.
@@ -172,5 +176,4 @@ public class StringSplitDescriptor extends AbstractScalarFunctionDynamicDescript
     public FunctionIdentifier getIdentifier() {
         return BuiltinFunctions.STRING_SPLIT;
     }
-
 }
diff --git a/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/StringToCodePointDescriptor.java b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/StringToCodePointDescriptor.java
index 4b0b2b5..38ad408 100644
--- a/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/StringToCodePointDescriptor.java
+++ b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/StringToCodePointDescriptor.java
@@ -26,6 +26,7 @@ import org.apache.asterix.common.annotations.MissingNullInOutFunction;
 import org.apache.asterix.formats.nontagged.SerializerDeserializerProvider;
 import org.apache.asterix.om.base.AInt64;
 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;
@@ -33,7 +34,6 @@ import org.apache.asterix.om.types.AOrderedListType;
 import org.apache.asterix.om.types.ATypeTag;
 import org.apache.asterix.om.types.BuiltinType;
 import org.apache.asterix.runtime.evaluators.base.AbstractScalarFunctionDynamicDescriptor;
-import org.apache.asterix.runtime.exceptions.TypeMismatchException;
 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;
@@ -93,26 +93,27 @@ public class StringToCodePointDescriptor extends AbstractScalarFunctionDynamicDe
                             byte[] serString = argPtr.getByteArray();
                             int offset = argPtr.getStartOffset();
 
-                            if (serString[offset] == ATypeTag.SERIALIZED_STRING_TYPE_TAG) {
-                                int len = UTF8StringUtil.getUTFLength(serString, offset + 1);
-
-                                int start = offset + 1 + UTF8StringUtil.getNumBytesToStoreLength(len);
-                                int pos = 0;
-                                listBuilder.reset(intListType);
-                                while (pos < len) {
-                                    int codePoint = UTF8StringUtil.UTF8ToCodePoint(serString, start + pos);
-                                    pos += UTF8StringUtil.charSize(serString, start + pos);
-
-                                    inputVal.reset();
-                                    aInt64.setValue(codePoint);
-                                    int64Serde.serialize(aInt64, inputVal.getDataOutput());
-                                    listBuilder.addItem(inputVal);
-                                }
-                                listBuilder.write(out, true);
-                            } else {
-                                throw new TypeMismatchException(sourceLoc, getIdentifier(), 0, serString[offset],
-                                        ATypeTag.SERIALIZED_STRING_TYPE_TAG);
+                            if (serString[offset] != ATypeTag.SERIALIZED_STRING_TYPE_TAG) {
+                                PointableHelper.setNull(result);
+                                ExceptionUtil.warnTypeMismatch(ctx, sourceLoc, getIdentifier(), 0, serString[offset],
+                                        ATypeTag.STRING);
+                                return;
+                            }
+                            int len = UTF8StringUtil.getUTFLength(serString, offset + 1);
+
+                            int start = offset + 1 + UTF8StringUtil.getNumBytesToStoreLength(len);
+                            int pos = 0;
+                            listBuilder.reset(intListType);
+                            while (pos < len) {
+                                int codePoint = UTF8StringUtil.UTF8ToCodePoint(serString, start + pos);
+                                pos += UTF8StringUtil.charSize(serString, start + pos);
+
+                                inputVal.reset();
+                                aInt64.setValue(codePoint);
+                                int64Serde.serialize(aInt64, inputVal.getDataOutput());
+                                listBuilder.addItem(inputVal);
                             }
+                            listBuilder.write(out, true);
                             result.set(resultStorage);
                         } catch (IOException e1) {
                             throw HyracksDataException.create(e1);
@@ -127,5 +128,4 @@ public class StringToCodePointDescriptor extends AbstractScalarFunctionDynamicDe
     public FunctionIdentifier getIdentifier() {
         return BuiltinFunctions.STRING_TO_CODEPOINT;
     }
-
 }
diff --git a/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/SubstringAfterDescriptor.java b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/SubstringAfterDescriptor.java
index fe15631..e725aa9 100644
--- a/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/SubstringAfterDescriptor.java
+++ b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/SubstringAfterDescriptor.java
@@ -22,12 +22,12 @@ import java.io.DataOutput;
 import java.io.IOException;
 
 import org.apache.asterix.common.annotations.MissingNullInOutFunction;
+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.evaluators.base.AbstractScalarFunctionDynamicDescriptor;
-import org.apache.asterix.runtime.exceptions.TypeMismatchException;
 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;
@@ -88,12 +88,16 @@ public class SubstringAfterDescriptor extends AbstractScalarFunctionDynamicDescr
                         int patternLen = array1.getLength();
 
                         if (src[srcOffset] != ATypeTag.SERIALIZED_STRING_TYPE_TAG) {
-                            throw new TypeMismatchException(sourceLoc, getIdentifier(), 0, src[srcOffset],
-                                    ATypeTag.SERIALIZED_STRING_TYPE_TAG);
+                            PointableHelper.setNull(result);
+                            ExceptionUtil.warnTypeMismatch(ctx, sourceLoc, getIdentifier(), 0, src[srcOffset],
+                                    ATypeTag.STRING);
+                            return;
                         }
                         if (pattern[patternOffset] != ATypeTag.SERIALIZED_STRING_TYPE_TAG) {
-                            throw new TypeMismatchException(sourceLoc, getIdentifier(), 1, pattern[patternOffset],
-                                    ATypeTag.SERIALIZED_STRING_TYPE_TAG);
+                            PointableHelper.setNull(result);
+                            ExceptionUtil.warnTypeMismatch(ctx, sourceLoc, getIdentifier(), 1, pattern[patternOffset],
+                                    ATypeTag.STRING);
+                            return;
                         }
 
                         try {
@@ -122,5 +126,4 @@ public class SubstringAfterDescriptor extends AbstractScalarFunctionDynamicDescr
     public FunctionIdentifier getIdentifier() {
         return BuiltinFunctions.SUBSTRING_AFTER;
     }
-
 }
diff --git a/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/SubstringBeforeDescriptor.java b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/SubstringBeforeDescriptor.java
index a7ab043..1802407 100644
--- a/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/SubstringBeforeDescriptor.java
+++ b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/SubstringBeforeDescriptor.java
@@ -22,12 +22,12 @@ import java.io.DataOutput;
 import java.io.IOException;
 
 import org.apache.asterix.common.annotations.MissingNullInOutFunction;
+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.evaluators.base.AbstractScalarFunctionDynamicDescriptor;
-import org.apache.asterix.runtime.exceptions.TypeMismatchException;
 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;
@@ -89,12 +89,16 @@ public class SubstringBeforeDescriptor extends AbstractScalarFunctionDynamicDesc
                         int patternLen = array1.getLength();
 
                         if (src[srcOffset] != ATypeTag.SERIALIZED_STRING_TYPE_TAG) {
-                            throw new TypeMismatchException(sourceLoc, getIdentifier(), 0, src[srcOffset],
-                                    ATypeTag.SERIALIZED_STRING_TYPE_TAG);
+                            PointableHelper.setNull(result);
+                            ExceptionUtil.warnTypeMismatch(ctx, sourceLoc, getIdentifier(), 0, src[srcOffset],
+                                    ATypeTag.STRING);
+                            return;
                         }
                         if (pattern[patternOffset] != ATypeTag.SERIALIZED_STRING_TYPE_TAG) {
-                            throw new TypeMismatchException(sourceLoc, getIdentifier(), 1, pattern[patternOffset],
-                                    ATypeTag.SERIALIZED_STRING_TYPE_TAG);
+                            PointableHelper.setNull(result);
+                            ExceptionUtil.warnTypeMismatch(ctx, sourceLoc, getIdentifier(), 1, pattern[patternOffset],
+                                    ATypeTag.STRING);
+                            return;
                         }
 
                         try {
@@ -118,5 +122,4 @@ public class SubstringBeforeDescriptor extends AbstractScalarFunctionDynamicDesc
     public FunctionIdentifier getIdentifier() {
         return BuiltinFunctions.SUBSTRING_BEFORE;
     }
-
 }
diff --git a/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/bitwise/AbstractBitMultipleValuesEvaluator.java b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/bitwise/AbstractBitMultipleValuesEvaluator.java
index a72de56..c242a4b 100644
--- a/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/bitwise/AbstractBitMultipleValuesEvaluator.java
+++ b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/bitwise/AbstractBitMultipleValuesEvaluator.java
@@ -21,6 +21,7 @@ package org.apache.asterix.runtime.evaluators.functions.bitwise;
 
 import org.apache.asterix.formats.nontagged.SerializerDeserializerProvider;
 import org.apache.asterix.om.base.AMutableInt64;
+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.hierachy.ATypeHierarchy;
@@ -115,7 +116,8 @@ abstract class AbstractBitMultipleValuesEvaluator extends AbstractScalarEval {
 
         // Type and value validity check
         if (!PointableHelper.isValidLongValue(bytes, startOffset, true)) {
-            handleTypeMismatchInput(context, 0, ATypeTag.BIGINT, bytes, startOffset);
+            ExceptionUtil.warnTypeMismatch(context, sourceLoc, functionIdentifier, 0, bytes[startOffset],
+                    ATypeTag.BIGINT);
             PointableHelper.setNull(result);
             return;
         }
@@ -130,7 +132,8 @@ abstract class AbstractBitMultipleValuesEvaluator extends AbstractScalarEval {
 
             // Type and value validity check
             if (!PointableHelper.isValidLongValue(bytes, startOffset, true)) {
-                handleTypeMismatchInput(context, i, ATypeTag.BIGINT, bytes, startOffset);
+                ExceptionUtil.warnTypeMismatch(context, sourceLoc, functionIdentifier, i, bytes[startOffset],
+                        ATypeTag.BIGINT);
                 PointableHelper.setNull(result);
                 return;
             }
diff --git a/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/bitwise/AbstractBitSingleValueEvaluator.java b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/bitwise/AbstractBitSingleValueEvaluator.java
index c21bbe0..1525b76 100644
--- a/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/bitwise/AbstractBitSingleValueEvaluator.java
+++ b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/bitwise/AbstractBitSingleValueEvaluator.java
@@ -19,6 +19,7 @@
 
 package org.apache.asterix.runtime.evaluators.functions.bitwise;
 
+import org.apache.asterix.om.exceptions.ExceptionUtil;
 import org.apache.asterix.om.types.ATypeTag;
 import org.apache.asterix.om.types.hierachy.ATypeHierarchy;
 import org.apache.asterix.runtime.evaluators.functions.AbstractScalarEval;
@@ -84,7 +85,8 @@ abstract class AbstractBitSingleValueEvaluator extends AbstractScalarEval {
 
         // Validity check
         if (!PointableHelper.isValidLongValue(bytes, startOffset, true)) {
-            handleTypeMismatchInput(context, 0, ATypeTag.BIGINT, bytes, startOffset);
+            ExceptionUtil.warnTypeMismatch(context, sourceLoc, functionIdentifier, 0, bytes[startOffset],
+                    ATypeTag.BIGINT);
             PointableHelper.setNull(result);
             return;
         }
diff --git a/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/bitwise/AbstractBitValuePositionEvaluator.java b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/bitwise/AbstractBitValuePositionEvaluator.java
index d9d5382..759e821 100644
--- a/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/bitwise/AbstractBitValuePositionEvaluator.java
+++ b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/bitwise/AbstractBitValuePositionEvaluator.java
@@ -25,6 +25,7 @@ import org.apache.asterix.common.exceptions.ErrorCode;
 import org.apache.asterix.common.exceptions.WarningUtil;
 import org.apache.asterix.formats.nontagged.SerializerDeserializerProvider;
 import org.apache.asterix.om.base.AMutableInt64;
+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;
@@ -32,7 +33,6 @@ import org.apache.asterix.om.types.hierachy.ATypeHierarchy;
 import org.apache.asterix.runtime.evaluators.common.ListAccessor;
 import org.apache.asterix.runtime.evaluators.functions.AbstractScalarEval;
 import org.apache.asterix.runtime.evaluators.functions.PointableHelper;
-import org.apache.asterix.runtime.exceptions.ExceptionUtil;
 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;
@@ -126,7 +126,8 @@ abstract class AbstractBitValuePositionEvaluator extends AbstractScalarEval {
 
         // Type and value validity check
         if (!PointableHelper.isValidLongValue(valueBytes, valueStartOffset, true)) {
-            handleTypeMismatchInput(context, 0, ATypeTag.BIGINT, valueBytes, valueStartOffset);
+            ExceptionUtil.warnTypeMismatch(context, sourceLoc, functionIdentifier, 0, valueBytes[valueStartOffset],
+                    ATypeTag.BIGINT);
             PointableHelper.setNull(result);
             return;
         }
@@ -139,7 +140,8 @@ abstract class AbstractBitValuePositionEvaluator extends AbstractScalarEval {
 
         // Type validity check (for position argument, array is a valid type as well)
         if (!ATypeHierarchy.canPromote(positionTypeTag, ATypeTag.DOUBLE) && positionTypeTag != ATypeTag.ARRAY) {
-            handleTypeMismatchInput(context, 1, secondArgumentExpectedTypes, positionBytes, positionStartOffset);
+            ExceptionUtil.warnTypeMismatch(context, sourceLoc, functionIdentifier, positionBytes[positionStartOffset],
+                    1, secondArgumentExpectedTypes);
             PointableHelper.setNull(result);
             return;
         }
@@ -220,7 +222,8 @@ abstract class AbstractBitValuePositionEvaluator extends AbstractScalarEval {
 
         // Value validity check
         if (!PointableHelper.isValidLongValue(bytes, startOffset, true)) {
-            handleTypeMismatchInput(context, 1, ATypeTag.BIGINT, bytes, startOffset);
+            ExceptionUtil.warnTypeMismatch(context, sourceLoc, functionIdentifier, 1, bytes[startOffset],
+                    ATypeTag.BIGINT);
             return false;
         }
 
diff --git a/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/bitwise/BitValueCountFlagEvaluator.java b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/bitwise/BitValueCountFlagEvaluator.java
index fccefe8..6e3c280 100644
--- a/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/bitwise/BitValueCountFlagEvaluator.java
+++ b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/bitwise/BitValueCountFlagEvaluator.java
@@ -22,6 +22,7 @@ package org.apache.asterix.runtime.evaluators.functions.bitwise;
 import org.apache.asterix.dataflow.data.nontagged.serde.ABooleanSerializerDeserializer;
 import org.apache.asterix.formats.nontagged.SerializerDeserializerProvider;
 import org.apache.asterix.om.base.AMutableInt64;
+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;
@@ -115,7 +116,8 @@ class BitValueCountFlagEvaluator extends AbstractScalarEval {
 
         // Type and value validity check
         if (!PointableHelper.isValidLongValue(valueBytes, valueStartOffset, true)) {
-            handleTypeMismatchInput(context, 0, ATypeTag.BIGINT, valueBytes, valueStartOffset);
+            ExceptionUtil.warnTypeMismatch(context, sourceLoc, functionIdentifier, 0, valueBytes[valueStartOffset],
+                    ATypeTag.BIGINT);
             PointableHelper.setNull(result);
             return;
         }
@@ -126,7 +128,8 @@ class BitValueCountFlagEvaluator extends AbstractScalarEval {
 
         // Type and Value validity check
         if (!PointableHelper.isValidLongValue(countBytes, countStartOffset, true)) {
-            handleTypeMismatchInput(context, 1, ATypeTag.BIGINT, countBytes, countStartOffset);
+            ExceptionUtil.warnTypeMismatch(context, sourceLoc, functionIdentifier, 1, countBytes[countStartOffset],
+                    ATypeTag.BIGINT);
             PointableHelper.setNull(result);
             return;
         }
@@ -139,7 +142,8 @@ class BitValueCountFlagEvaluator extends AbstractScalarEval {
             ATypeTag flagTypeTag = EnumDeserializer.ATYPETAGDESERIALIZER.deserialize(flagBytes[flagStartOffset]);
 
             if (flagTypeTag != ATypeTag.BOOLEAN) {
-                handleTypeMismatchInput(context, 2, ATypeTag.BOOLEAN, flagBytes, flagStartOffset);
+                ExceptionUtil.warnTypeMismatch(context, sourceLoc, functionIdentifier, 2, flagBytes[flagStartOffset],
+                        ATypeTag.BOOLEAN);
                 PointableHelper.setNull(result);
                 return;
             }
diff --git a/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/bitwise/BitValuePositionFlagEvaluator.java b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/bitwise/BitValuePositionFlagEvaluator.java
index 7e5045e..e579237 100644
--- a/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/bitwise/BitValuePositionFlagEvaluator.java
+++ b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/bitwise/BitValuePositionFlagEvaluator.java
@@ -26,6 +26,7 @@ import org.apache.asterix.common.exceptions.WarningUtil;
 import org.apache.asterix.dataflow.data.nontagged.serde.ABooleanSerializerDeserializer;
 import org.apache.asterix.formats.nontagged.SerializerDeserializerProvider;
 import org.apache.asterix.om.base.ABoolean;
+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;
@@ -33,7 +34,6 @@ import org.apache.asterix.om.types.hierachy.ATypeHierarchy;
 import org.apache.asterix.runtime.evaluators.common.ListAccessor;
 import org.apache.asterix.runtime.evaluators.functions.AbstractScalarEval;
 import org.apache.asterix.runtime.evaluators.functions.PointableHelper;
-import org.apache.asterix.runtime.exceptions.ExceptionUtil;
 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;
@@ -148,7 +148,8 @@ class BitValuePositionFlagEvaluator extends AbstractScalarEval {
 
         // Type and value validity check
         if (!PointableHelper.isValidLongValue(valueBytes, valueStartOffset, true)) {
-            handleTypeMismatchInput(context, 0, ATypeTag.BIGINT, valueBytes, valueStartOffset);
+            ExceptionUtil.warnTypeMismatch(context, sourceLoc, functionIdentifier, 0, valueBytes[valueStartOffset],
+                    ATypeTag.BIGINT);
             PointableHelper.setNull(result);
             return;
         }
@@ -161,7 +162,8 @@ class BitValuePositionFlagEvaluator extends AbstractScalarEval {
 
         // Type validity check (for position argument, array is a valid type as well)
         if (!ATypeHierarchy.canPromote(positionTypeTag, ATypeTag.DOUBLE) && positionTypeTag != ATypeTag.ARRAY) {
-            handleTypeMismatchInput(context, 1, secondArgumentExpectedTypes, positionBytes, positionStartOffset);
+            ExceptionUtil.warnTypeMismatch(context, sourceLoc, functionIdentifier, positionBytes[positionStartOffset],
+                    1, secondArgumentExpectedTypes);
             PointableHelper.setNull(result);
             return;
         }
@@ -175,7 +177,8 @@ class BitValuePositionFlagEvaluator extends AbstractScalarEval {
             ATypeTag flagTypeTag = EnumDeserializer.ATYPETAGDESERIALIZER.deserialize(flagBytes[flagStartOffset]);
 
             if (flagTypeTag != ATypeTag.BOOLEAN) {
-                handleTypeMismatchInput(context, 2, ATypeTag.BOOLEAN, flagBytes, flagStartOffset);
+                ExceptionUtil.warnTypeMismatch(context, sourceLoc, functionIdentifier, 2, flagBytes[flagStartOffset],
+                        ATypeTag.BOOLEAN);
                 PointableHelper.setNull(result);
                 return;
             }
@@ -268,7 +271,8 @@ class BitValuePositionFlagEvaluator extends AbstractScalarEval {
 
         // Value validity check
         if (!PointableHelper.isValidLongValue(bytes, startOffset, true)) {
-            handleTypeMismatchInput(context, 1, ATypeTag.BIGINT, bytes, startOffset);
+            ExceptionUtil.warnTypeMismatch(context, sourceLoc, functionIdentifier, 1, bytes[startOffset],
+                    ATypeTag.BIGINT);
             return false;
         }
 
diff --git a/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/exceptions/ExceptionUtil.java b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/exceptions/ExceptionUtil.java
deleted file mode 100644
index b1e64dc..0000000
--- a/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/exceptions/ExceptionUtil.java
+++ /dev/null
@@ -1,64 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one
- *  or more contributor license agreements.  See the NOTICE file
- *  distributed with this work for additional information
- *  regarding copyright ownership.  The ASF licenses this file
- *  to you under the Apache License, Version 2.0 (the
- *  "License"); you may not use this file except in compliance
- *  with the License.  You may obtain a copy of the License at
- *
- *    http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing,
- *  software distributed under the License is distributed on an
- *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- *  KIND, either express or implied.  See the License for the
- *  specific language governing permissions and limitations
- *  under the License.
- */
-
-package org.apache.asterix.runtime.exceptions;
-
-import org.apache.asterix.om.types.EnumDeserializer;
-
-public class ExceptionUtil {
-    private ExceptionUtil() {
-    }
-
-    public static String toExpectedTypeString(byte... expectedTypeTags) {
-        StringBuilder expectedTypes = new StringBuilder();
-        int numCandidateTypes = expectedTypeTags.length;
-        for (int index = 0; index < numCandidateTypes; ++index) {
-            if (index > 0) {
-                if (index == numCandidateTypes - 1) {
-                    expectedTypes.append(" or ");
-                } else {
-                    expectedTypes.append(", ");
-                }
-            }
-            expectedTypes.append(EnumDeserializer.ATYPETAGDESERIALIZER.deserialize(expectedTypeTags[index]));
-        }
-        return expectedTypes.toString();
-    }
-
-    public static String indexToPosition(int index) {
-        int i = index + 1;
-        switch (i % 100) {
-            case 11:
-            case 12:
-            case 13:
-                return i + "th";
-            default:
-                switch (i % 10) {
-                    case 1:
-                        return i + "st";
-                    case 2:
-                        return i + "nd";
-                    case 3:
-                        return i + "rd";
-                    default:
-                        return i + "th";
-                }
-        }
-    }
-}
diff --git a/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/exceptions/TypeMismatchException.java b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/exceptions/TypeMismatchException.java
index 5e1087e..e510fba 100644
--- a/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/exceptions/TypeMismatchException.java
+++ b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/exceptions/TypeMismatchException.java
@@ -19,8 +19,8 @@
 
 package org.apache.asterix.runtime.exceptions;
 
-import static org.apache.asterix.runtime.exceptions.ExceptionUtil.indexToPosition;
-import static org.apache.asterix.runtime.exceptions.ExceptionUtil.toExpectedTypeString;
+import static org.apache.asterix.om.exceptions.ExceptionUtil.indexToPosition;
+import static org.apache.asterix.om.exceptions.ExceptionUtil.toExpectedTypeString;
 
 import org.apache.asterix.common.exceptions.ErrorCode;
 import org.apache.asterix.common.exceptions.RuntimeDataException;