Merge branch 'gerrit/cheshire-cat'

Change-Id: I4b02eef9f85192de5ac52ce3a455789e18334c55
diff --git a/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/ConstantFoldingRule.java b/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/ConstantFoldingRule.java
index 4c227fa..e99817d 100644
--- a/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/ConstantFoldingRule.java
+++ b/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/ConstantFoldingRule.java
@@ -31,7 +31,6 @@
 import org.apache.asterix.common.exceptions.ErrorCode;
 import org.apache.asterix.common.exceptions.NoOpWarningCollector;
 import org.apache.asterix.common.exceptions.WarningCollector;
-import org.apache.asterix.common.exceptions.WarningUtil;
 import org.apache.asterix.dataflow.data.common.ExpressionTypeComputer;
 import org.apache.asterix.dataflow.data.nontagged.MissingWriterFactory;
 import org.apache.asterix.formats.nontagged.ADMPrinterFactoryProvider;
@@ -94,6 +93,7 @@
 import org.apache.hyracks.api.dataflow.value.ISerializerDeserializer;
 import org.apache.hyracks.api.exceptions.HyracksDataException;
 import org.apache.hyracks.api.exceptions.IWarningCollector;
+import org.apache.hyracks.api.exceptions.Warning;
 import org.apache.hyracks.data.std.api.IPointable;
 import org.apache.hyracks.data.std.primitive.VoidPointable;
 import org.apache.hyracks.dataflow.common.comm.util.ByteBufferInputStream;
@@ -332,7 +332,7 @@
                     if (isDuplicate) {
                         IWarningCollector warningCollector = optContext.getWarningCollector();
                         if (warningCollector.shouldWarn()) {
-                            warningCollector.warn(WarningUtil.forAsterix(fieldNameExpr.second.getSourceLocation(),
+                            warningCollector.warn(Warning.of(fieldNameExpr.second.getSourceLocation(),
                                     ErrorCode.COMPILATION_DUPLICATE_FIELD_NAME, fieldName));
                         }
                         iterator.remove();
diff --git a/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/RemoveDuplicateFieldsRule.java b/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/RemoveDuplicateFieldsRule.java
index 0a3b9c4..6c4f8c6 100644
--- a/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/RemoveDuplicateFieldsRule.java
+++ b/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/RemoveDuplicateFieldsRule.java
@@ -26,7 +26,6 @@
 import org.apache.asterix.builders.RecordBuilder;
 import org.apache.asterix.common.exceptions.CompilationException;
 import org.apache.asterix.common.exceptions.ErrorCode;
-import org.apache.asterix.common.exceptions.WarningUtil;
 import org.apache.asterix.om.functions.BuiltinFunctions;
 import org.apache.asterix.om.typecomputer.impl.ClosedRecordConstructorResultType;
 import org.apache.asterix.om.typecomputer.impl.OpenRecordConstructorResultType;
@@ -41,6 +40,7 @@
 import org.apache.hyracks.algebricks.core.algebra.operators.logical.AbstractLogicalOperator;
 import org.apache.hyracks.algebricks.core.rewriter.base.IAlgebraicRewriteRule;
 import org.apache.hyracks.api.exceptions.IWarningCollector;
+import org.apache.hyracks.api.exceptions.Warning;
 
 /**
  * <pre>
@@ -115,7 +115,7 @@
                 if (fieldName != null && !fieldNames.add(fieldName)) {
                     IWarningCollector warningCollector = context.getWarningCollector();
                     if (warningCollector.shouldWarn()) {
-                        warningCollector.warn(WarningUtil.forAsterix(fieldNameExpr.getSourceLocation(),
+                        warningCollector.warn(Warning.of(fieldNameExpr.getSourceLocation(),
                                 ErrorCode.COMPILATION_DUPLICATE_FIELD_NAME, fieldName));
                     }
                     iterator.remove();
diff --git a/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/util/AsterixJoinUtils.java b/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/util/AsterixJoinUtils.java
index bc2c860..672cb25 100644
--- a/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/util/AsterixJoinUtils.java
+++ b/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/util/AsterixJoinUtils.java
@@ -73,7 +73,7 @@
                 && rangeMap.getTag(0, 0) != ATypeTag.TIME.serialize()) {
             IWarningCollector warningCollector = context.getWarningCollector();
             if (warningCollector.shouldWarn()) {
-                warningCollector.warn(Warning.forHyracks(op.getSourceLocation(), ErrorCode.INAPPLICABLE_HINT,
+                warningCollector.warn(Warning.of(op.getSourceLocation(), ErrorCode.INAPPLICABLE_HINT,
                         "Date, DateTime, and Time are only range hints types supported for interval joins"));
             }
             return;
diff --git a/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/translator/AbstractLangTranslator.java b/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/translator/AbstractLangTranslator.java
index 8777f66..58bdaca 100644
--- a/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/translator/AbstractLangTranslator.java
+++ b/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/translator/AbstractLangTranslator.java
@@ -34,14 +34,26 @@
 import org.apache.asterix.common.exceptions.CompilationException;
 import org.apache.asterix.common.exceptions.ErrorCode;
 import org.apache.asterix.common.functions.FunctionConstants;
+import org.apache.asterix.common.functions.FunctionSignature;
 import org.apache.asterix.common.metadata.DataverseName;
 import org.apache.asterix.lang.common.base.Statement;
+import org.apache.asterix.lang.common.statement.CreateAdapterStatement;
 import org.apache.asterix.lang.common.statement.CreateDataverseStatement;
+import org.apache.asterix.lang.common.statement.CreateFeedStatement;
+import org.apache.asterix.lang.common.statement.CreateFunctionStatement;
+import org.apache.asterix.lang.common.statement.CreateLibraryStatement;
+import org.apache.asterix.lang.common.statement.CreateSynonymStatement;
 import org.apache.asterix.lang.common.statement.DatasetDecl;
 import org.apache.asterix.lang.common.statement.DataverseDropStatement;
 import org.apache.asterix.lang.common.statement.DeleteStatement;
 import org.apache.asterix.lang.common.statement.DropDatasetStatement;
+import org.apache.asterix.lang.common.statement.FunctionDecl;
+import org.apache.asterix.lang.common.statement.IndexDropStatement;
 import org.apache.asterix.lang.common.statement.InsertStatement;
+import org.apache.asterix.lang.common.statement.LoadStatement;
+import org.apache.asterix.lang.common.statement.TypeDecl;
+import org.apache.asterix.lang.common.statement.TypeDropStatement;
+import org.apache.asterix.lang.common.statement.UpsertStatement;
 import org.apache.asterix.metadata.dataset.hints.DatasetHints;
 import org.apache.asterix.metadata.entities.Dataverse;
 import org.apache.asterix.metadata.utils.MetadataConstants;
@@ -59,6 +71,14 @@
 
     private static final Logger LOGGER = LogManager.getLogger();
 
+    protected static final String INVALID_OPERATION_MESSAGE = "Invalid operation - %s";
+
+    protected static final String BAD_DATAVERSE_DML_MESSAGE = "%s operation is not permitted in dataverse %s";
+
+    protected static final String BAD_DATAVERSE_DDL_MESSAGE = "Cannot %s dataverse: %s";
+
+    protected static final String BAD_DATAVERSE_OBJECT_DDL_MESSAGE = "Cannot %s a %s belonging to the dataverse: %s";
+
     public void validateOperation(ICcApplicationContext appCtx, Dataverse defaultDataverse, Statement stmt)
             throws AlgebricksException {
 
@@ -120,15 +140,36 @@
         String message = null;
         DataverseName dataverseName = defaultDataverse != null ? defaultDataverse.getDataverseName() : null;
         switch (stmt.getKind()) {
+            case LOAD:
+                LoadStatement loadStmt = (LoadStatement) stmt;
+                if (loadStmt.getDataverseName() != null) {
+                    dataverseName = loadStmt.getDataverseName();
+                }
+                invalidOperation = isMetadataDataverse(dataverseName);
+                if (invalidOperation) {
+                    message = String.format(BAD_DATAVERSE_DML_MESSAGE, "Load", dataverseName);
+                }
+                break;
+
             case INSERT:
                 InsertStatement insertStmt = (InsertStatement) stmt;
                 if (insertStmt.getDataverseName() != null) {
                     dataverseName = insertStmt.getDataverseName();
                 }
-                invalidOperation = MetadataConstants.METADATA_DATAVERSE_NAME.equals(dataverseName);
+                invalidOperation = isMetadataDataverse(dataverseName);
                 if (invalidOperation) {
-                    message = "Insert operation is not permitted in dataverse "
-                            + MetadataConstants.METADATA_DATAVERSE_NAME;
+                    message = String.format(BAD_DATAVERSE_DML_MESSAGE, "Insert", dataverseName);
+                }
+                break;
+
+            case UPSERT:
+                UpsertStatement upsertStmt = (UpsertStatement) stmt;
+                if (upsertStmt.getDataverseName() != null) {
+                    dataverseName = upsertStmt.getDataverseName();
+                }
+                invalidOperation = isMetadataDataverse(dataverseName);
+                if (invalidOperation) {
+                    message = String.format(BAD_DATAVERSE_DML_MESSAGE, "Upsert", dataverseName);
                 }
                 break;
 
@@ -137,10 +178,9 @@
                 if (deleteStmt.getDataverseName() != null) {
                     dataverseName = deleteStmt.getDataverseName();
                 }
-                invalidOperation = MetadataConstants.METADATA_DATAVERSE_NAME.equals(dataverseName);
+                invalidOperation = isMetadataDataverse(dataverseName);
                 if (invalidOperation) {
-                    message = "Delete operation is not permitted in dataverse "
-                            + MetadataConstants.METADATA_DATAVERSE_NAME;
+                    message = String.format(BAD_DATAVERSE_DML_MESSAGE, "Delete", dataverseName);
                 }
                 break;
 
@@ -150,57 +190,179 @@
                 invalidOperation = FunctionConstants.ASTERIX_DV.equals(dataverseName)
                         || FunctionConstants.ALGEBRICKS_DV.equals(dataverseName);
                 if (invalidOperation) {
-                    message = "Cannot create dataverse: " + dataverseName;
+                    message = String.format(BAD_DATAVERSE_DDL_MESSAGE, "create", dataverseName);
                 }
                 break;
 
             case DATAVERSE_DROP:
                 DataverseDropStatement dvDropStmt = (DataverseDropStatement) stmt;
                 dataverseName = dvDropStmt.getDataverseName();
-                invalidOperation = MetadataConstants.METADATA_DATAVERSE_NAME.equals(dataverseName);
+                invalidOperation = isMetadataDataverse(dataverseName);
                 if (invalidOperation) {
-                    message = "Cannot drop dataverse: " + dataverseName;
-                }
-                break;
-
-            case DATASET_DROP:
-                DropDatasetStatement dropStmt = (DropDatasetStatement) stmt;
-                if (dropStmt.getDataverseName() != null) {
-                    dataverseName = dropStmt.getDataverseName();
-                }
-                invalidOperation = MetadataConstants.METADATA_DATAVERSE_NAME.equals(dataverseName);
-                if (invalidOperation) {
-                    message = "Cannot drop a dataset belonging to the dataverse: "
-                            + MetadataConstants.METADATA_DATAVERSE_NAME;
+                    message = String.format(BAD_DATAVERSE_DDL_MESSAGE, "drop", dataverseName);
                 }
                 break;
 
             case DATASET_DECL:
-                DatasetDecl datasetStmt = (DatasetDecl) stmt;
-                Map<String, String> hints = datasetStmt.getHints();
-                if (hints != null && !hints.isEmpty()) {
-                    StringBuilder errorMsgBuffer = new StringBuilder();
-                    for (Entry<String, String> hint : hints.entrySet()) {
-                        Pair<Boolean, String> validationResult =
-                                DatasetHints.validate(appCtx, hint.getKey(), hint.getValue());
-                        if (!validationResult.first) {
-                            errorMsgBuffer.append("Dataset: ").append(datasetStmt.getName().getValue())
-                                    .append(" error in processing hint: ").append(hint.getKey()).append(" ")
-                                    .append(validationResult.second);
-                            errorMsgBuffer.append(" \n");
+                DatasetDecl dsCreateStmt = (DatasetDecl) stmt;
+                if (dsCreateStmt.getDataverse() != null) {
+                    dataverseName = dsCreateStmt.getDataverse();
+                }
+                invalidOperation = isMetadataDataverse(dataverseName);
+                if (invalidOperation) {
+                    message = String.format(BAD_DATAVERSE_OBJECT_DDL_MESSAGE, "create", "dataset", dataverseName);
+                }
+
+                if (!invalidOperation) {
+                    Map<String, String> hints = dsCreateStmt.getHints();
+                    if (hints != null && !hints.isEmpty()) {
+                        StringBuilder errorMsgBuffer = new StringBuilder();
+                        for (Entry<String, String> hint : hints.entrySet()) {
+                            Pair<Boolean, String> validationResult =
+                                    DatasetHints.validate(appCtx, hint.getKey(), hint.getValue());
+                            if (!validationResult.first) {
+                                errorMsgBuffer.append("Dataset: ").append(dsCreateStmt.getName().getValue())
+                                        .append(" error in processing hint: ").append(hint.getKey()).append(" ")
+                                        .append(validationResult.second);
+                                errorMsgBuffer.append(" \n");
+                            }
+                        }
+                        invalidOperation = errorMsgBuffer.length() > 0;
+                        if (invalidOperation) {
+                            message = errorMsgBuffer.toString();
                         }
                     }
-                    invalidOperation = errorMsgBuffer.length() > 0;
-                    if (invalidOperation) {
-                        message = errorMsgBuffer.toString();
-                    }
+                }
+                break;
+
+            case DATASET_DROP:
+                DropDatasetStatement dsDropStmt = (DropDatasetStatement) stmt;
+                if (dsDropStmt.getDataverseName() != null) {
+                    dataverseName = dsDropStmt.getDataverseName();
+                }
+                invalidOperation = isMetadataDataverse(dataverseName);
+                if (invalidOperation) {
+                    message = String.format(BAD_DATAVERSE_OBJECT_DDL_MESSAGE, "drop", "dataset", dataverseName);
+                }
+                break;
+
+            case INDEX_DROP:
+                IndexDropStatement idxDropStmt = (IndexDropStatement) stmt;
+                if (idxDropStmt.getDataverseName() != null) {
+                    dataverseName = idxDropStmt.getDataverseName();
+                }
+                invalidOperation = isMetadataDataverse(dataverseName);
+                if (invalidOperation) {
+                    message = String.format(BAD_DATAVERSE_OBJECT_DDL_MESSAGE, "drop", "index", dataverseName);
+                }
+                break;
+
+            case TYPE_DECL:
+                TypeDecl typeCreateStmt = (TypeDecl) stmt;
+                if (typeCreateStmt.getDataverseName() != null) {
+                    dataverseName = typeCreateStmt.getDataverseName();
+                }
+                invalidOperation = isMetadataDataverse(dataverseName);
+                if (invalidOperation) {
+                    message = String.format(BAD_DATAVERSE_OBJECT_DDL_MESSAGE, "create", "type", dataverseName);
+                }
+                break;
+
+            case TYPE_DROP:
+                TypeDropStatement typeDropStmt = (TypeDropStatement) stmt;
+                if (typeDropStmt.getDataverseName() != null) {
+                    dataverseName = typeDropStmt.getDataverseName();
+                }
+                invalidOperation = isMetadataDataverse(dataverseName);
+                if (invalidOperation) {
+                    message = String.format(BAD_DATAVERSE_OBJECT_DDL_MESSAGE, "drop", "type", dataverseName);
+                }
+                break;
+
+            case CREATE_SYNONYM:
+                CreateSynonymStatement synCreateStmt = (CreateSynonymStatement) stmt;
+                if (synCreateStmt.getDataverseName() != null) {
+                    dataverseName = synCreateStmt.getDataverseName();
+                }
+                invalidOperation = isMetadataDataverse(dataverseName);
+                if (invalidOperation) {
+                    message = String.format(BAD_DATAVERSE_OBJECT_DDL_MESSAGE, "create", "synonym", dataverseName);
+                }
+                break;
+
+            case FUNCTION_DECL:
+                FunctionDecl fnDeclStmt = (FunctionDecl) stmt;
+                FunctionSignature fnDeclSignature = fnDeclStmt.getSignature();
+                if (fnDeclSignature.getDataverseName() != null) {
+                    dataverseName = fnDeclSignature.getDataverseName();
+                }
+                invalidOperation = isMetadataDataverse(dataverseName);
+                if (invalidOperation) {
+                    message = String.format(BAD_DATAVERSE_OBJECT_DDL_MESSAGE, "declare", "function", dataverseName);
+                }
+                break;
+
+            case CREATE_FUNCTION:
+                CreateFunctionStatement fnCreateStmt = (CreateFunctionStatement) stmt;
+                FunctionSignature fnCreateSignature = fnCreateStmt.getFunctionSignature();
+                if (fnCreateSignature.getDataverseName() != null) {
+                    dataverseName = fnCreateSignature.getDataverseName();
+                }
+                invalidOperation = isMetadataDataverse(dataverseName);
+                if (invalidOperation) {
+                    message = String.format(BAD_DATAVERSE_OBJECT_DDL_MESSAGE, "create", "function", dataverseName);
+                }
+                break;
+
+            case CREATE_LIBRARY:
+                CreateLibraryStatement libCreateStmt = (CreateLibraryStatement) stmt;
+                if (libCreateStmt.getDataverseName() != null) {
+                    dataverseName = libCreateStmt.getDataverseName();
+                }
+                invalidOperation = isMetadataDataverse(dataverseName);
+                if (invalidOperation) {
+                    message = String.format(BAD_DATAVERSE_OBJECT_DDL_MESSAGE, "create", "library", dataverseName);
+                }
+                break;
+
+            case CREATE_ADAPTER:
+                CreateAdapterStatement adCreateStmt = (CreateAdapterStatement) stmt;
+                if (adCreateStmt.getDataverseName() != null) {
+                    dataverseName = adCreateStmt.getDataverseName();
+                }
+                invalidOperation = isMetadataDataverse(dataverseName);
+                if (invalidOperation) {
+                    message = String.format(BAD_DATAVERSE_OBJECT_DDL_MESSAGE, "create", "adapter", dataverseName);
+                }
+                break;
+
+            case CREATE_FEED:
+                CreateFeedStatement feedCreateStmt = (CreateFeedStatement) stmt;
+                if (feedCreateStmt.getDataverseName() != null) {
+                    dataverseName = feedCreateStmt.getDataverseName();
+                }
+                invalidOperation = isMetadataDataverse(dataverseName);
+                if (invalidOperation) {
+                    message = String.format(BAD_DATAVERSE_OBJECT_DDL_MESSAGE, "create", "feed", dataverseName);
+                }
+                break;
+
+            case CREATE_FEED_POLICY:
+                invalidOperation = isMetadataDataverse(dataverseName);
+                if (invalidOperation) {
+                    message = String.format(BAD_DATAVERSE_OBJECT_DDL_MESSAGE, "create", "ingestion policy",
+                            dataverseName);
                 }
                 break;
         }
 
         if (invalidOperation) {
             throw new CompilationException(ErrorCode.COMPILATION_ERROR, stmt.getSourceLocation(),
-                    "Invalid operation - " + message);
+                    String.format(INVALID_OPERATION_MESSAGE, message));
         }
     }
+
+    protected static boolean isMetadataDataverse(DataverseName dataverseName) {
+        return MetadataConstants.METADATA_DATAVERSE_NAME.equals(dataverseName);
+    }
 }
diff --git a/asterixdb/asterix-app/src/main/java/org/apache/asterix/api/http/server/AbstractNCUdfServlet.java b/asterixdb/asterix-app/src/main/java/org/apache/asterix/api/http/server/AbstractNCUdfServlet.java
index ced9b40..54e972e 100644
--- a/asterixdb/asterix-app/src/main/java/org/apache/asterix/api/http/server/AbstractNCUdfServlet.java
+++ b/asterixdb/asterix-app/src/main/java/org/apache/asterix/api/http/server/AbstractNCUdfServlet.java
@@ -39,6 +39,7 @@
 import org.apache.asterix.common.metadata.DataverseName;
 import org.apache.commons.io.IOUtils;
 import org.apache.commons.lang3.StringUtils;
+import org.apache.hyracks.algebricks.common.exceptions.AlgebricksException;
 import org.apache.hyracks.algebricks.common.utils.Pair;
 import org.apache.hyracks.api.application.INCServiceContext;
 import org.apache.hyracks.api.client.IHyracksClientConnection;
@@ -138,15 +139,11 @@
     }
 
     HttpResponseStatus toHttpErrorStatus(Exception e) {
-        if (e instanceof IFormattedException) {
-            IFormattedException fe = (IFormattedException) e;
-            if (ErrorCode.ASTERIX.equals(fe.getComponent())) {
-                switch (fe.getErrorCode()) {
-                    case ErrorCode.UNKNOWN_DATAVERSE:
-                    case ErrorCode.UNKNOWN_LIBRARY:
-                        return HttpResponseStatus.NOT_FOUND;
-                }
-            }
+        if (IFormattedException.matchesAny(e, ErrorCode.UNKNOWN_DATAVERSE, ErrorCode.UNKNOWN_LIBRARY)) {
+            return HttpResponseStatus.NOT_FOUND;
+        }
+        if (e instanceof AlgebricksException) {
+            return HttpResponseStatus.BAD_REQUEST;
         }
         return HttpResponseStatus.INTERNAL_SERVER_ERROR;
     }
diff --git a/asterixdb/asterix-app/src/main/java/org/apache/asterix/api/http/server/NCUdfApiServlet.java b/asterixdb/asterix-app/src/main/java/org/apache/asterix/api/http/server/NCUdfApiServlet.java
index fc08f49..0645870 100644
--- a/asterixdb/asterix-app/src/main/java/org/apache/asterix/api/http/server/NCUdfApiServlet.java
+++ b/asterixdb/asterix-app/src/main/java/org/apache/asterix/api/http/server/NCUdfApiServlet.java
@@ -146,7 +146,6 @@
         try {
             ncMb.sendMessageToPrimaryCC(requestMessage);
             responseMsg = (InternalRequestResponse) responseFuture.get(120000, TimeUnit.MILLISECONDS);
-
         } finally {
             ncMb.deregisterMessageFuture(responseFuture.getFutureId());
         }
diff --git a/asterixdb/asterix-app/src/main/java/org/apache/asterix/api/http/server/QueryResultApiServlet.java b/asterixdb/asterix-app/src/main/java/org/apache/asterix/api/http/server/QueryResultApiServlet.java
index 5acdf3b..f705b89 100644
--- a/asterixdb/asterix-app/src/main/java/org/apache/asterix/api/http/server/QueryResultApiServlet.java
+++ b/asterixdb/asterix-app/src/main/java/org/apache/asterix/api/http/server/QueryResultApiServlet.java
@@ -112,8 +112,7 @@
                 ResultUtil.printResults(appCtx, resultReader, sessionOutput, new Stats(), null);
             }
         } catch (HyracksDataException e) {
-            final int errorCode = e.getErrorCode();
-            if (ErrorCode.NO_RESULT_SET == errorCode) {
+            if (e.matches(ErrorCode.NO_RESULT_SET)) {
                 LOGGER.log(Level.INFO, "No results for: \"" + strHandle + "\"");
                 response.setStatus(HttpResponseStatus.NOT_FOUND);
                 return;
diff --git a/asterixdb/asterix-app/src/main/java/org/apache/asterix/api/http/server/QueryServiceServlet.java b/asterixdb/asterix-app/src/main/java/org/apache/asterix/api/http/server/QueryServiceServlet.java
index f394794..fcc6993 100644
--- a/asterixdb/asterix-app/src/main/java/org/apache/asterix/api/http/server/QueryServiceServlet.java
+++ b/asterixdb/asterix-app/src/main/java/org/apache/asterix/api/http/server/QueryServiceServlet.java
@@ -18,14 +18,12 @@
  */
 package org.apache.asterix.api.http.server;
 
-import static org.apache.asterix.common.exceptions.ErrorCode.ASTERIX;
 import static org.apache.asterix.common.exceptions.ErrorCode.INVALID_REQ_JSON_VAL;
 import static org.apache.asterix.common.exceptions.ErrorCode.INVALID_REQ_PARAM_VAL;
 import static org.apache.asterix.common.exceptions.ErrorCode.NO_STATEMENT_PROVIDED;
 import static org.apache.asterix.common.exceptions.ErrorCode.REJECT_BAD_CLUSTER_STATE;
 import static org.apache.asterix.common.exceptions.ErrorCode.REJECT_NODE_UNREGISTERED;
 import static org.apache.asterix.common.exceptions.ErrorCode.REQUEST_TIMEOUT;
-import static org.apache.hyracks.api.exceptions.ErrorCode.HYRACKS;
 import static org.apache.hyracks.api.exceptions.ErrorCode.JOB_REQUIREMENTS_EXCEED_CAPACITY;
 
 import java.io.IOException;
@@ -434,29 +432,22 @@
             executionState.setStatus(ResultStatus.FATAL, HttpResponseStatus.BAD_REQUEST);
         } else if (t instanceof HyracksException) {
             HyracksException he = (HyracksException) t;
-            switch (he.getComponent() + he.getErrorCode()) {
-                case ASTERIX + REQUEST_TIMEOUT:
-                    LOGGER.info(() -> "handleException: request execution timed out: "
-                            + LogRedactionUtil.userData(param.toString()));
-                    executionState.setStatus(ResultStatus.TIMEOUT, HttpResponseStatus.OK);
-                    break;
-                case ASTERIX + REJECT_BAD_CLUSTER_STATE:
-                case ASTERIX + REJECT_NODE_UNREGISTERED:
-                    LOGGER.warn(() -> "handleException: " + he.getMessage() + ": "
-                            + LogRedactionUtil.userData(param.toString()));
-                    executionState.setStatus(ResultStatus.FATAL, HttpResponseStatus.SERVICE_UNAVAILABLE);
-                    break;
-                case ASTERIX + INVALID_REQ_PARAM_VAL:
-                case ASTERIX + INVALID_REQ_JSON_VAL:
-                case ASTERIX + NO_STATEMENT_PROVIDED:
-                case HYRACKS + JOB_REQUIREMENTS_EXCEED_CAPACITY:
-                    executionState.setStatus(ResultStatus.FATAL, HttpResponseStatus.BAD_REQUEST);
-                    break;
-                default:
-                    LOGGER.warn(() -> "handleException: unexpected exception " + he.getMessage() + ": "
-                            + LogRedactionUtil.userData(param.toString()), he);
-                    executionState.setStatus(ResultStatus.FATAL, HttpResponseStatus.INTERNAL_SERVER_ERROR);
-                    break;
+            // TODO(mblow): reconsolidate
+            if (he.matchesAny(INVALID_REQ_PARAM_VAL, INVALID_REQ_JSON_VAL, NO_STATEMENT_PROVIDED,
+                    JOB_REQUIREMENTS_EXCEED_CAPACITY)) {
+                executionState.setStatus(ResultStatus.FATAL, HttpResponseStatus.BAD_REQUEST);
+            } else if (he.matches(REQUEST_TIMEOUT)) {
+                LOGGER.info(() -> "handleException: request execution timed out: "
+                        + LogRedactionUtil.userData(param.toString()));
+                executionState.setStatus(ResultStatus.TIMEOUT, HttpResponseStatus.OK);
+            } else if (he.matchesAny(REJECT_BAD_CLUSTER_STATE, REJECT_NODE_UNREGISTERED)) {
+                LOGGER.warn(() -> "handleException: " + he.getMessage() + ": "
+                        + LogRedactionUtil.userData(param.toString()));
+                executionState.setStatus(ResultStatus.FATAL, HttpResponseStatus.SERVICE_UNAVAILABLE);
+            } else {
+                LOGGER.warn(() -> "handleException: unexpected exception " + he.getMessage() + ": "
+                        + LogRedactionUtil.userData(param.toString()), he);
+                executionState.setStatus(ResultStatus.FATAL, HttpResponseStatus.INTERNAL_SERVER_ERROR);
             }
         } else {
             LOGGER.warn(() -> "handleException: unexpected exception: " + LogRedactionUtil.userData(param.toString()),
diff --git a/asterixdb/asterix-app/src/main/java/org/apache/asterix/api/http/server/ResultUtil.java b/asterixdb/asterix-app/src/main/java/org/apache/asterix/api/http/server/ResultUtil.java
index 63da9ce..045d64c 100644
--- a/asterixdb/asterix-app/src/main/java/org/apache/asterix/api/http/server/ResultUtil.java
+++ b/asterixdb/asterix-app/src/main/java/org/apache/asterix/api/http/server/ResultUtil.java
@@ -48,6 +48,7 @@
 import org.apache.hyracks.algebricks.common.exceptions.AlgebricksException;
 import org.apache.hyracks.algebricks.core.algebra.prettyprint.AlgebricksAppendable;
 import org.apache.hyracks.api.exceptions.HyracksDataException;
+import org.apache.hyracks.api.exceptions.IFormattedException;
 import org.apache.logging.log4j.LogManager;
 import org.apache.logging.log4j.Logger;
 
@@ -190,12 +191,16 @@
 
     public static Throwable getRootCause(Throwable cause) {
         Throwable currentCause = cause;
+        Throwable rootFormattedEx = cause instanceof IFormattedException ? cause : null;
         Throwable nextCause = cause.getCause();
         while (nextCause != null && nextCause != currentCause) {
             currentCause = nextCause;
+            if (currentCause instanceof IFormattedException) {
+                rootFormattedEx = currentCause;
+            }
             nextCause = nextCause.getCause();
         }
-        return currentCause;
+        return rootFormattedEx != null ? rootFormattedEx : currentCause;
     }
 
     /**
diff --git a/asterixdb/asterix-app/src/main/java/org/apache/asterix/app/nc/RecoveryManager.java b/asterixdb/asterix-app/src/main/java/org/apache/asterix/app/nc/RecoveryManager.java
index 3fce4d8..1461ef4 100644
--- a/asterixdb/asterix-app/src/main/java/org/apache/asterix/app/nc/RecoveryManager.java
+++ b/asterixdb/asterix-app/src/main/java/org/apache/asterix/app/nc/RecoveryManager.java
@@ -787,7 +787,7 @@
             } catch (HyracksDataException hde) {
                 // Since we're undoing according the write-ahead log, the actual upserting tuple
                 // might not have been written to memory yet.
-                if (hde.getErrorCode() != ErrorCode.UPDATE_OR_DELETE_NON_EXISTENT_KEY) {
+                if (!hde.matches(ErrorCode.UPDATE_OR_DELETE_NON_EXISTENT_KEY)) {
                     throw hde;
                 }
             }
diff --git a/asterixdb/asterix-app/src/main/java/org/apache/asterix/app/translator/QueryTranslator.java b/asterixdb/asterix-app/src/main/java/org/apache/asterix/app/translator/QueryTranslator.java
index 10a4d75..8251241 100644
--- a/asterixdb/asterix-app/src/main/java/org/apache/asterix/app/translator/QueryTranslator.java
+++ b/asterixdb/asterix-app/src/main/java/org/apache/asterix/app/translator/QueryTranslator.java
@@ -1832,8 +1832,7 @@
             if (dv == null) {
                 if (ifExists) {
                     if (warningCollector.shouldWarn()) {
-                        warningCollector
-                                .warn(WarningUtil.forAsterix(sourceLoc, ErrorCode.UNKNOWN_DATAVERSE, dataverseName));
+                        warningCollector.warn(Warning.of(sourceLoc, ErrorCode.UNKNOWN_DATAVERSE, dataverseName));
                     }
                     MetadataManager.INSTANCE.commitTransaction(mdTxnCtx.getValue());
                     return false;
@@ -2190,8 +2189,7 @@
             if (dv == null) {
                 if (stmtTypeDrop.getIfExists()) {
                     if (warningCollector.shouldWarn()) {
-                        warningCollector
-                                .warn(WarningUtil.forAsterix(sourceLoc, ErrorCode.UNKNOWN_DATAVERSE, dataverseName));
+                        warningCollector.warn(Warning.of(sourceLoc, ErrorCode.UNKNOWN_DATAVERSE, dataverseName));
                     }
                     MetadataManager.INSTANCE.commitTransaction(mdTxnCtx);
                     return;
diff --git a/asterixdb/asterix-app/src/main/java/org/apache/asterix/utils/RebalanceUtil.java b/asterixdb/asterix-app/src/main/java/org/apache/asterix/utils/RebalanceUtil.java
index 7ad90ad..429cda9 100644
--- a/asterixdb/asterix-app/src/main/java/org/apache/asterix/utils/RebalanceUtil.java
+++ b/asterixdb/asterix-app/src/main/java/org/apache/asterix/utils/RebalanceUtil.java
@@ -419,7 +419,7 @@
             // drop dataset entry from metadata
             runMetadataTransaction(metadataProvider,
                     () -> MetadataManager.INSTANCE.dropDataset(metadataProvider.getMetadataTxnContext(),
-                            dataset.getDataverseName(), dataset.getDatasetName(), false));
+                            dataset.getDataverseName(), dataset.getDatasetName(), true));
             MetadataManager.INSTANCE.commitTransaction(metadataProvider.getMetadataTxnContext());
             // try to drop the dataset's node group
             runMetadataTransaction(metadataProvider, () -> tryDropDatasetNodegroup(dataset, metadataProvider));
diff --git a/asterixdb/asterix-app/src/test/java/org/apache/asterix/app/external/ExternalUDFLibrarian.java b/asterixdb/asterix-app/src/test/java/org/apache/asterix/app/external/ExternalUDFLibrarian.java
index c2b576a..81e35a0 100644
--- a/asterixdb/asterix-app/src/test/java/org/apache/asterix/app/external/ExternalUDFLibrarian.java
+++ b/asterixdb/asterix-app/src/test/java/org/apache/asterix/app/external/ExternalUDFLibrarian.java
@@ -55,41 +55,40 @@
 
     @Override
     public void install(URI path, String libPath, Pair<String, String> credentials) throws Exception {
-        HttpHost h = new HttpHost(path.getHost(), path.getPort(), "http");
+        HttpClientContext hcCtx = createHttpClientContext(path, credentials);
         HttpPost post = new HttpPost(path);
-        CredentialsProvider cp = new BasicCredentialsProvider();
-        cp.setCredentials(AuthScope.ANY, new UsernamePasswordCredentials(credentials.first, credentials.second));
-        HttpClientContext hcCtx = HttpClientContext.create();
-        hcCtx.setCredentialsProvider(cp);
-        AuthCache ac = new BasicAuthCache();
-        ac.put(h, new BasicScheme());
-        hcCtx.setAuthCache(ac);
         File lib = new File(libPath);
         HttpEntity file = MultipartEntityBuilder.create().setMode(HttpMultipartMode.STRICT)
                 .addBinaryBody("lib", lib, ContentType.DEFAULT_BINARY, lib.getName()).build();
         post.setEntity(file);
         HttpResponse response = hc.execute(post, hcCtx);
-        response.getEntity().consumeContent();
-        if (response.getStatusLine().getStatusCode() != 200) {
-            throw new AsterixException(response.getStatusLine().toString());
-        }
+        handleResponse(response);
     }
 
     @Override
     public void uninstall(URI path, Pair<String, String> credentials) throws IOException, AsterixException {
+        HttpClientContext hcCtx = createHttpClientContext(path, credentials);
+        HttpDelete del = new HttpDelete(path);
+        HttpResponse response = hc.execute(del, hcCtx);
+        handleResponse(response);
+    }
+
+    private HttpClientContext createHttpClientContext(URI path, Pair<String, String> credentials) {
+        HttpClientContext hcCtx = HttpClientContext.create();
+        HttpHost h = new HttpHost(path.getHost(), path.getPort(), "http");
         CredentialsProvider cp = new BasicCredentialsProvider();
         cp.setCredentials(AuthScope.ANY, new UsernamePasswordCredentials(credentials.first, credentials.second));
-        HttpClientContext hcCtx = HttpClientContext.create();
         hcCtx.setCredentialsProvider(cp);
-        HttpHost h = new HttpHost(path.getHost(), path.getPort(), "http");
         AuthCache ac = new BasicAuthCache();
         ac.put(h, new BasicScheme());
         hcCtx.setAuthCache(ac);
-        HttpDelete del = new HttpDelete(path);
-        HttpResponse response = hc.execute(del, hcCtx);
+        return hcCtx;
+    }
+
+    private void handleResponse(HttpResponse response) throws IOException, AsterixException {
         String resp = null;
         int respCode = response.getStatusLine().getStatusCode();
-        if (respCode == 500) {
+        if (respCode == 500 || respCode == 400) {
             resp = IOUtils.toString(response.getEntity().getContent());
         }
         response.getEntity().consumeContent();
@@ -100,5 +99,4 @@
             throw new AsterixException(resp);
         }
     }
-
 }
diff --git a/asterixdb/asterix-app/src/test/java/org/apache/asterix/test/active/ActiveEventsListenerTest.java b/asterixdb/asterix-app/src/test/java/org/apache/asterix/test/active/ActiveEventsListenerTest.java
index ded5393..3bfea56 100644
--- a/asterixdb/asterix-app/src/test/java/org/apache/asterix/test/active/ActiveEventsListenerTest.java
+++ b/asterixdb/asterix-app/src/test/java/org/apache/asterix/test/active/ActiveEventsListenerTest.java
@@ -14,10 +14,12 @@
  * "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.
+ * under the License
  */
 package org.apache.asterix.test.active;
 
+import static org.apache.hyracks.api.exceptions.HyracksException.UNKNOWN;
+
 import java.util.ArrayList;
 import java.util.Collections;
 import java.util.EnumSet;
@@ -61,6 +63,7 @@
 import org.apache.hyracks.api.client.IHyracksClientConnection;
 import org.apache.hyracks.api.control.CcId;
 import org.apache.hyracks.api.exceptions.HyracksDataException;
+import org.apache.hyracks.api.exceptions.IError;
 import org.apache.hyracks.api.job.JobIdFactory;
 import org.apache.hyracks.api.job.JobStatus;
 import org.apache.hyracks.control.cc.ClusterControllerService;
@@ -187,7 +190,7 @@
         listener.onStart(Behavior.FAIL_COMPILE);
         Action action = users[0].startActivity(listener);
         action.sync();
-        assertFailure(action, 0);
+        assertUnknownFailure(action);
         Assert.assertEquals(ActivityState.STOPPED, listener.getState());
     }
 
@@ -197,7 +200,7 @@
         listener.onStart(Behavior.FAIL_RUNTIME);
         Action action = users[0].startActivity(listener);
         action.sync();
-        assertFailure(action, 0);
+        assertUnknownFailure(action);
         Assert.assertEquals(ActivityState.STOPPED, listener.getState());
     }
 
@@ -217,7 +220,7 @@
         listener.onStart(Behavior.FAIL_START_TIMEOUT_STUCK);
         Action action = users[0].startActivity(listener);
         action.sync();
-        assertFailure(action, 0);
+        assertUnknownFailure(action);
         Assert.assertEquals(ActivityState.STOPPED, listener.getState());
     }
 
@@ -1560,17 +1563,28 @@
         assertSuccess(addDataset);
     }
 
-    private void assertFailure(Action action, int errorCode) throws Exception {
+    private void assertFailure(Action action, IError errorCode) throws Exception {
         HyracksDataException exception = action.getFailure();
         try {
             Assert.assertTrue(action.hasFailed());
             Assert.assertNotNull(exception);
-            Assert.assertEquals(errorCode, exception.getErrorCode());
+            Assert.assertTrue(exception.matches(errorCode));
         } catch (Exception e) {
             throw new Exception("Expected failure: " + errorCode + ". Found failure: " + exception);
         }
     }
 
+    private void assertUnknownFailure(Action action) throws Exception {
+        HyracksDataException exception = action.getFailure();
+        try {
+            Assert.assertTrue(action.hasFailed());
+            Assert.assertNotNull(exception);
+            Assert.assertEquals(UNKNOWN, exception.getErrorCode());
+        } catch (Exception e) {
+            throw new Exception("Expected failure: " + UNKNOWN + ". Found failure: " + exception);
+        }
+    }
+
     private void assertSuccess(Action action) throws Exception {
         if (action.hasFailed()) {
             System.err.println("Action failed while it was expected to succeed");
diff --git a/asterixdb/asterix-app/src/test/java/org/apache/asterix/test/active/ActiveStatsTest.java b/asterixdb/asterix-app/src/test/java/org/apache/asterix/test/active/ActiveStatsTest.java
index 963e227..c51fd95 100644
--- a/asterixdb/asterix-app/src/test/java/org/apache/asterix/test/active/ActiveStatsTest.java
+++ b/asterixdb/asterix-app/src/test/java/org/apache/asterix/test/active/ActiveStatsTest.java
@@ -20,7 +20,6 @@
 package org.apache.asterix.test.active;
 
 import static org.apache.asterix.common.exceptions.ErrorCode.ACTIVE_ENTITY_NOT_RUNNING;
-import static org.apache.asterix.common.exceptions.ErrorCode.ASTERIX;
 
 import java.io.IOException;
 import java.util.ArrayList;
@@ -64,8 +63,8 @@
 public class ActiveStatsTest {
 
     protected boolean cleanUp = true;
-    private static String EXPECTED_STATS = "\"Mock stats\"";
-    private static String CONF_PATH = "src/main/resources/cc.conf";
+    private static final String EXPECTED_STATS = "\"Mock stats\"";
+    private static final String CONF_PATH = "src/main/resources/cc.conf";
 
     @Before
     public void setUp() throws Exception {
@@ -126,7 +125,7 @@
             Assert.fail("expected exception on refresh stats on not-started job");
         } catch (HyracksDataException e) {
             Assert.assertTrue("incorrect exception thrown (expected: ACTIVE_ENTITY_NOT_RUNNING, was: " + e,
-                    e.matches(ASTERIX, ACTIVE_ENTITY_NOT_RUNNING));
+                    e.matches(ACTIVE_ENTITY_NOT_RUNNING));
         }
         requestedStats = eventsListener.getStats();
         Assert.assertTrue(requestedStats.contains("N/A"));
@@ -142,7 +141,7 @@
             eventsListener.refreshStats(1000);
         } catch (HyracksDataException e) {
             Assert.assertTrue("incorrect exception thrown (expected: ACTIVE_ENTITY_NOT_RUNNING, was: " + e,
-                    e.matches(ASTERIX, ACTIVE_ENTITY_NOT_RUNNING));
+                    e.matches(ACTIVE_ENTITY_NOT_RUNNING));
         }
         Assert.assertTrue(requestedStats.contains("N/A"));
         // Fake partition message and notify eventListener
@@ -174,7 +173,7 @@
             expectedException = e;
         }
         Assert.assertNotNull(expectedException);
-        Assert.assertEquals(ErrorCode.ACTIVE_MANAGER_INVALID_RUNTIME, expectedException.getErrorCode());
+        Assert.assertTrue(expectedException.matches(ErrorCode.ACTIVE_MANAGER_INVALID_RUNTIME));
     }
 
 }
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 44038cc..b8524c0 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
@@ -294,7 +294,11 @@
                 boolean compareUnorderedArray = statement != null && getCompareUnorderedArray(statement);
                 runScriptAndCompareWithResultRegexJson(scriptFile, readerExpected, readerActual, compareUnorderedArray);
                 return;
+            } else if (actualFile.toString().endsWith(".unorderedtxt")) {
+                runScriptAndCompareWithResultUnorderedLinesText(scriptFile, readerExpected, readerActual);
+                return;
             }
+
             String lineExpected, lineActual;
             int num = 1;
             while ((lineExpected = readerExpected.readLine()) != null) {
@@ -358,6 +362,16 @@
                 + ":\nexpected < " + truncateIfLong(lineExpected) + "\nactual   > " + truncateIfLong(lineActual));
     }
 
+    private ComparisonException createLineNotFoundException(File scriptFile, String lineExpected) {
+        return new ComparisonException(
+                "Result for " + canonicalize(scriptFile) + " expected line not found: " + truncateIfLong(lineExpected));
+    }
+
+    private ComparisonException createExpectedLinesNotReturnedException(File scriptFile, List<String> expectedLines) {
+        return new ComparisonException("Result for " + canonicalize(scriptFile) + " expected lines not returned:\n"
+                + String.join("\n", expectedLines));
+    }
+
     private String truncateIfLong(String string) {
         if (string.length() < TRUNCATE_THRESHOLD) {
             return string;
@@ -555,6 +569,24 @@
         }
     }
 
+    public void runScriptAndCompareWithResultUnorderedLinesText(File scriptFile, BufferedReader readerExpected,
+            BufferedReader readerActual) throws Exception {
+        // Using Lists to allow duplicate lines in the result
+        List<String> expectedLines = readerExpected.lines().collect(Collectors.toList());
+        List<String> actualLines = readerActual.lines().collect(Collectors.toList());
+
+        for (String line : actualLines) {
+            if (!expectedLines.remove(line)) {
+                throw createLineNotFoundException(scriptFile, line);
+            }
+        }
+
+        // number of expect > actual
+        if (expectedLines.size() > 0) {
+            throw createExpectedLinesNotReturnedException(scriptFile, expectedLines);
+        }
+    }
+
     // For tests where you simply want the byte-for-byte output.
     private static void writeOutputToFile(File actualFile, InputStream resultStream) throws Exception {
         final File parentDir = actualFile.getParentFile();
diff --git a/asterixdb/asterix-app/src/test/java/org/apache/asterix/test/metadata/MetadataManagerTest.java b/asterixdb/asterix-app/src/test/java/org/apache/asterix/test/metadata/MetadataManagerTest.java
index 164ea7f..39e2ece 100644
--- a/asterixdb/asterix-app/src/test/java/org/apache/asterix/test/metadata/MetadataManagerTest.java
+++ b/asterixdb/asterix-app/src/test/java/org/apache/asterix/test/metadata/MetadataManagerTest.java
@@ -147,7 +147,7 @@
                                 Collections.nCopies(MetadataConstants.DATAVERSE_NAME_TOTAL_LENGTH_LIMIT_UTF8 / 2 + 1,
                                         String.valueOf(iuml))));
 
-        String invalidNameErrCode = ErrorCode.ASTERIX + ErrorCode.INVALID_DATABASE_OBJECT_NAME;
+        ErrorCode invalidNameErrCode = ErrorCode.INVALID_DATABASE_OBJECT_NAME;
         for (DataverseName dvNameErr : dvNameErrList) {
             String sql = String.format("create dataverse %s;", dvNameErr);
             try {
@@ -156,7 +156,7 @@
             } catch (Exception e) {
 
                 Assert.assertTrue("Unexpected error message: " + e.getMessage(),
-                        e.getMessage().contains(invalidNameErrCode));
+                        e.getMessage().contains(invalidNameErrCode.errorCode()));
             }
         }
     }
diff --git a/asterixdb/asterix-app/src/test/java/org/apache/asterix/test/storage/IndexDropOperatorNodePushableTest.java b/asterixdb/asterix-app/src/test/java/org/apache/asterix/test/storage/IndexDropOperatorNodePushableTest.java
index d08a960..5bacd41 100644
--- a/asterixdb/asterix-app/src/test/java/org/apache/asterix/test/storage/IndexDropOperatorNodePushableTest.java
+++ b/asterixdb/asterix-app/src/test/java/org/apache/asterix/test/storage/IndexDropOperatorNodePushableTest.java
@@ -179,7 +179,7 @@
             dropInUseOp.initialize();
         } catch (HyracksDataException e) {
             e.printStackTrace();
-            Assert.assertEquals(ErrorCode.CANNOT_DROP_IN_USE_INDEX, e.getErrorCode());
+            Assert.assertTrue(e.matches(ErrorCode.CANNOT_DROP_IN_USE_INDEX));
             dropFailed.set(true);
         }
         Assert.assertTrue(dropFailed.get());
@@ -219,7 +219,7 @@
             dropNonExistingOp.initialize();
         } catch (HyracksDataException e) {
             e.printStackTrace();
-            Assert.assertEquals(ErrorCode.INDEX_DOES_NOT_EXIST, e.getErrorCode());
+            Assert.assertTrue(e.matches(ErrorCode.INDEX_DOES_NOT_EXIST));
             dropFailed.set(true);
         }
         Assert.assertTrue(dropFailed.get());
diff --git a/asterixdb/asterix-app/src/test/resources/metadata/queries/exception/exception_create_system_dataset/exception_create_system_dataset.1.ddl.sqlpp b/asterixdb/asterix-app/src/test/resources/metadata/queries/exception/exception_create_system_dataset/exception_create_system_dataset.1.ddl.sqlpp
new file mode 100644
index 0000000..3b186dd
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/metadata/queries/exception/exception_create_system_dataset/exception_create_system_dataset.1.ddl.sqlpp
@@ -0,0 +1,21 @@
+/*
+ * 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.
+ */
+
+create dataset Metadata.NewMetaDataset(id uuid not unknown)
+  open type primary key id autogenerated;
\ No newline at end of file
diff --git a/asterixdb/asterix-app/src/test/resources/metadata/queries/exception/exception_create_system_feed/exception_create_system_feed.1.ddl.sqlpp b/asterixdb/asterix-app/src/test/resources/metadata/queries/exception/exception_create_system_feed/exception_create_system_feed.1.ddl.sqlpp
new file mode 100644
index 0000000..5b0ffa7
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/metadata/queries/exception/exception_create_system_feed/exception_create_system_feed.1.ddl.sqlpp
@@ -0,0 +1,26 @@
+/*
+ * 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.
+ */
+
+create feed Metadata.NewMetaFeed with {
+  "adapter-name" : "http_adapter",
+  "addresses" : "asterix_nc2:10002,asterix_nc1:10001",
+  "address-type" : "NC",
+  "type-name" : "DatasetRecordType",
+  "format" : "adm"
+};
diff --git a/asterixdb/asterix-app/src/test/resources/metadata/queries/exception/exception_create_system_feed_policy/exception_create_system_feed_policy.1.ddl.sqlpp b/asterixdb/asterix-app/src/test/resources/metadata/queries/exception/exception_create_system_feed_policy/exception_create_system_feed_policy.1.ddl.sqlpp
new file mode 100644
index 0000000..b9709cb
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/metadata/queries/exception/exception_create_system_feed_policy/exception_create_system_feed_policy.1.ddl.sqlpp
@@ -0,0 +1,24 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+use Metadata;
+
+create ingestion policy NewMetaPolicy
+  from path 'data/feed-policy/policy.properties'
+  definition 'someString';
\ No newline at end of file
diff --git a/asterixdb/asterix-app/src/test/resources/metadata/queries/exception/exception_create_system_function/exception_create_system_function.1.ddl.sqlpp b/asterixdb/asterix-app/src/test/resources/metadata/queries/exception/exception_create_system_function/exception_create_system_function.1.ddl.sqlpp
new file mode 100644
index 0000000..196870c
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/metadata/queries/exception/exception_create_system_function/exception_create_system_function.1.ddl.sqlpp
@@ -0,0 +1,22 @@
+/*
+ * 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.
+ */
+
+create function Metadata.MyMetaFunction() {
+  1
+};
diff --git a/asterixdb/asterix-app/src/test/resources/metadata/queries/exception/exception_create_system_synonym/exception_create_system_synonym.1.ddl.sqlpp b/asterixdb/asterix-app/src/test/resources/metadata/queries/exception/exception_create_system_synonym/exception_create_system_synonym.1.ddl.sqlpp
new file mode 100644
index 0000000..0e6f7ed
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/metadata/queries/exception/exception_create_system_synonym/exception_create_system_synonym.1.ddl.sqlpp
@@ -0,0 +1,20 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+create synonym Metadata.NewMetaSynonym for Metadata.`Dataset`;
diff --git a/asterixdb/asterix-app/src/test/resources/metadata/queries/exception/exception_create_system_type/exception_create_system_type.1.ddl.sqlpp b/asterixdb/asterix-app/src/test/resources/metadata/queries/exception/exception_create_system_type/exception_create_system_type.1.ddl.sqlpp
new file mode 100644
index 0000000..1222af6
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/metadata/queries/exception/exception_create_system_type/exception_create_system_type.1.ddl.sqlpp
@@ -0,0 +1,22 @@
+/*
+ * 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.
+ */
+
+create type Metadata.NewMetaType as open {
+  id : string
+};
diff --git a/asterixdb/asterix-app/src/test/resources/metadata/queries/exception/exception_declare_system_function/exception_declare_system_function.1.query.sqlpp b/asterixdb/asterix-app/src/test/resources/metadata/queries/exception/exception_declare_system_function/exception_declare_system_function.1.query.sqlpp
new file mode 100644
index 0000000..fe3f250
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/metadata/queries/exception/exception_declare_system_function/exception_declare_system_function.1.query.sqlpp
@@ -0,0 +1,26 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+use Metadata;
+
+declare function MyMetaFunction() {
+  1
+};
+
+MyMetaFunction();
diff --git a/asterixdb/asterix-app/src/test/resources/metadata/queries/exception/exception_drop_system_index/exception_drop_system_index.1.ddl.sqlpp b/asterixdb/asterix-app/src/test/resources/metadata/queries/exception/exception_drop_system_index/exception_drop_system_index.1.ddl.sqlpp
new file mode 100644
index 0000000..02d32c9
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/metadata/queries/exception/exception_drop_system_index/exception_drop_system_index.1.ddl.sqlpp
@@ -0,0 +1,20 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+drop index Metadata.`Dataset`.`Dataset`;
\ No newline at end of file
diff --git a/asterixdb/asterix-app/src/test/resources/metadata/queries/exception/exception_drop_system_type/exception_drop_system_type.1.ddl.sqlpp b/asterixdb/asterix-app/src/test/resources/metadata/queries/exception/exception_drop_system_type/exception_drop_system_type.1.ddl.sqlpp
new file mode 100644
index 0000000..e109d56
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/metadata/queries/exception/exception_drop_system_type/exception_drop_system_type.1.ddl.sqlpp
@@ -0,0 +1,20 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+drop type Metadata.DatasetRecordType;
\ No newline at end of file
diff --git a/asterixdb/asterix-app/src/test/resources/metadata/testsuite.xml b/asterixdb/asterix-app/src/test/resources/metadata/testsuite.xml
index 62db526..8af4c67 100644
--- a/asterixdb/asterix-app/src/test/resources/metadata/testsuite.xml
+++ b/asterixdb/asterix-app/src/test/resources/metadata/testsuite.xml
@@ -327,6 +327,48 @@
   </test-group>
   <test-group name="exception">
     <test-case FilePath="exception">
+      <compilation-unit name="exception_create_system_dataset">
+        <output-dir compare="Text">none</output-dir>
+        <expected-error>ASX1079: Compilation error: Invalid operation - Cannot create a dataset belonging to the dataverse: Metadata (in line 20, at column 1)</expected-error>
+      </compilation-unit>
+    </test-case>
+    <test-case FilePath="exception">
+      <compilation-unit name="exception_create_system_feed">
+        <output-dir compare="Text">none</output-dir>
+        <expected-error>ASX1079: Compilation error: Invalid operation - Cannot create a feed belonging to the dataverse: Metadata (in line 20, at column 1)</expected-error>
+      </compilation-unit>
+    </test-case>
+    <test-case FilePath="exception">
+      <compilation-unit name="exception_create_system_feed_policy">
+        <output-dir compare="Text">none</output-dir>
+        <expected-error>ASX1079: Compilation error: Invalid operation - Cannot create a ingestion policy belonging to the dataverse: Metadata (in line 22, at column 1)</expected-error>
+      </compilation-unit>
+    </test-case>
+    <test-case FilePath="exception">
+      <compilation-unit name="exception_create_system_function">
+        <output-dir compare="Text">none</output-dir>
+        <expected-error>ASX1079: Compilation error: Invalid operation - Cannot create a function belonging to the dataverse: Metadata (in line 20, at column 1)</expected-error>
+      </compilation-unit>
+    </test-case>
+    <test-case FilePath="exception">
+      <compilation-unit name="exception_create_system_synonym">
+        <output-dir compare="Text">none</output-dir>
+        <expected-error>ASX1079: Compilation error: Invalid operation - Cannot create a synonym belonging to the dataverse: Metadata (in line 20, at column 1)</expected-error>
+      </compilation-unit>
+    </test-case>
+    <test-case FilePath="exception">
+      <compilation-unit name="exception_create_system_type">
+        <output-dir compare="Text">none</output-dir>
+        <expected-error>ASX1079: Compilation error: Invalid operation - Cannot create a type belonging to the dataverse: Metadata (in line 20, at column 1)</expected-error>
+      </compilation-unit>
+    </test-case>
+    <test-case FilePath="exception">
+      <compilation-unit name="exception_declare_system_function">
+        <output-dir compare="Text">none</output-dir>
+        <expected-error>ASX1079: Compilation error: Invalid operation - Cannot declare a function belonging to the dataverse: Metadata (in line 22, at column 1)</expected-error>
+      </compilation-unit>
+    </test-case>
+    <test-case FilePath="exception">
       <compilation-unit name="exception_drop_dataset">
         <output-dir compare="Text">none</output-dir>
         <expected-error>ASX1050: Cannot find dataset with name UnknownDataset in dataverse Default (in line 19, at column 1)</expected-error>
@@ -351,6 +393,12 @@
       </compilation-unit>
     </test-case>
     <test-case FilePath="exception">
+      <compilation-unit name="exception_drop_system_index">
+        <output-dir compare="Text">none</output-dir>
+        <expected-error>ASX1079: Compilation error: Invalid operation - Cannot drop a index belonging to the dataverse: Metadata (in line 20, at column 1)</expected-error>
+      </compilation-unit>
+    </test-case>
+    <test-case FilePath="exception">
       <compilation-unit name="exception_drop_nodegroup">
         <output-dir compare="Text">none</output-dir>
         <expected-error>ASX1080: Cannot find node group with name UnknownNodeGroup (in line 19, at column 1)</expected-error>
@@ -363,6 +411,12 @@
       </compilation-unit>
     </test-case>
     <test-case FilePath="exception">
+      <compilation-unit name="exception_drop_system_type">
+        <output-dir compare="Text">none</output-dir>
+        <expected-error>ASX1079: Compilation error: Invalid operation - Cannot drop a type belonging to the dataverse: Metadata (in line 20, at column 1)</expected-error>
+      </compilation-unit>
+    </test-case>
+    <test-case FilePath="exception">
       <compilation-unit name="issue_239_drop_system_dataset_1">
         <output-dir compare="Text">none</output-dir>
         <expected-error>ASX1079: Compilation error: Invalid operation - Cannot drop a dataset belonging to the dataverse: Metadata (in line 26, at column 1)</expected-error>
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/external-library/exception_create_system_library/exception_create_system_library.1.lib.sqlpp b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/external-library/exception_create_system_library/exception_create_system_library.1.lib.sqlpp
new file mode 100644
index 0000000..ac3d3d0
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/external-library/exception_create_system_library/exception_create_system_library.1.lib.sqlpp
@@ -0,0 +1,19 @@
+/*
+ * 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.
+ */
+install Metadata testlib admin admin target/data/externallib/asterix-external-data-testlib.zip
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/feeds/exception_create_system_adapter/exception_create_system_adapter.0.ddl.sqlpp b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/feeds/exception_create_system_adapter/exception_create_system_adapter.0.ddl.sqlpp
new file mode 100644
index 0000000..fd5eb07
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/feeds/exception_create_system_adapter/exception_create_system_adapter.0.ddl.sqlpp
@@ -0,0 +1,25 @@
+/*
+ * 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  : Cannot create adapter in Metadata dataverse
+ * Expected Res : Success
+ */
+
+drop dataverse externallibtest if exists;
+create dataverse externallibtest;
\ No newline at end of file
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/feeds/exception_create_system_adapter/exception_create_system_adapter.1.lib.sqlpp b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/feeds/exception_create_system_adapter/exception_create_system_adapter.1.lib.sqlpp
new file mode 100644
index 0000000..45cdfd1
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/feeds/exception_create_system_adapter/exception_create_system_adapter.1.lib.sqlpp
@@ -0,0 +1,24 @@
+/*
+ * 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  : Cannot create adapter in Metadata dataverse
+ * Expected Res : Success
+ */
+
+install externallibtest testlib admin admin target/data/externallib/asterix-external-data-testlib.zip
\ No newline at end of file
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/feeds/exception_create_system_adapter/exception_create_system_adapter.2.ddl.sqlpp b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/feeds/exception_create_system_adapter/exception_create_system_adapter.2.ddl.sqlpp
new file mode 100644
index 0000000..7fb6235
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/feeds/exception_create_system_adapter/exception_create_system_adapter.2.ddl.sqlpp
@@ -0,0 +1,25 @@
+/*
+ * 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  : Cannot create adapter in Metadata dataverse
+ * Expected Res : Success
+ */
+
+create adapter Metadata.NewMetaAdapter
+  as "org.apache.asterix.external.library.adapter.TestTypedAdapterFactory" at externallibtest.testlib;
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/testsuite_it_sqlpp.xml b/asterixdb/asterix-app/src/test/resources/runtimets/testsuite_it_sqlpp.xml
index cf5b1a7..954252c 100644
--- a/asterixdb/asterix-app/src/test/resources/runtimets/testsuite_it_sqlpp.xml
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/testsuite_it_sqlpp.xml
@@ -35,6 +35,12 @@
       </compilation-unit>
     </test-case>
     <test-case FilePath="external-library">
+      <compilation-unit name="exception_create_system_library">
+        <output-dir compare="Text">none</output-dir>
+        <expected-error>ASX1079: Compilation error: Invalid operation - Cannot create a library belonging to the dataverse: Metadata</expected-error>
+      </compilation-unit>
+    </test-case>
+    <test-case FilePath="external-library">
       <compilation-unit name="type_validation">
         <output-dir compare="Text">type_validation</output-dir>
       </compilation-unit>
@@ -104,6 +110,12 @@
   </test-group>
   <test-group name="feeds">
     <test-case FilePath="feeds">
+      <compilation-unit name="exception_create_system_adapter">
+        <output-dir compare="Text">none</output-dir>
+        <expected-error>ASX1079: Compilation error: Invalid operation - Cannot create a adapter belonging to the dataverse: Metadata (in line 24, at column 1)</expected-error>
+      </compilation-unit>
+    </test-case>
+    <test-case FilePath="feeds">
       <compilation-unit name="feed-with-external-function">
         <output-dir compare="Text">feed-with-external-function</output-dir>
       </compilation-unit>
diff --git a/asterixdb/asterix-common/src/main/java/org/apache/asterix/common/dataflow/LSMInsertDeleteOperatorNodePushable.java b/asterixdb/asterix-common/src/main/java/org/apache/asterix/common/dataflow/LSMInsertDeleteOperatorNodePushable.java
index 2ad2f7a..ab0732b 100644
--- a/asterixdb/asterix-common/src/main/java/org/apache/asterix/common/dataflow/LSMInsertDeleteOperatorNodePushable.java
+++ b/asterixdb/asterix-common/src/main/java/org/apache/asterix/common/dataflow/LSMInsertDeleteOperatorNodePushable.java
@@ -147,7 +147,7 @@
                 }
             }
         } catch (HyracksDataException e) {
-            if (e.getErrorCode() == ErrorCode.INVALID_OPERATOR_OPERATION) {
+            if (e.matches(ErrorCode.INVALID_OPERATOR_OPERATION)) {
                 throw e;
             } else {
                 throw HyracksDataException.create(ErrorCode.ERROR_PROCESSING_TUPLE, e, sourceLoc, i);
diff --git a/asterixdb/asterix-common/src/main/java/org/apache/asterix/common/exceptions/AsterixException.java b/asterixdb/asterix-common/src/main/java/org/apache/asterix/common/exceptions/AsterixException.java
index a834a06..92714b3 100644
--- a/asterixdb/asterix-common/src/main/java/org/apache/asterix/common/exceptions/AsterixException.java
+++ b/asterixdb/asterix-common/src/main/java/org/apache/asterix/common/exceptions/AsterixException.java
@@ -26,54 +26,51 @@
 public class AsterixException extends AlgebricksException {
     private static final long serialVersionUID = 1L;
 
+    public AsterixException(ErrorCode error, Throwable cause, SourceLocation sourceLoc, Serializable... params) {
+        super(error, cause, sourceLoc, params);
+    }
+
+    public AsterixException(ErrorCode error, SourceLocation sourceLoc, Serializable... params) {
+        this(error, null, sourceLoc, params);
+    }
+
+    public AsterixException(ErrorCode error, Serializable... params) {
+        super(error, null, null, params);
+    }
+
+    public AsterixException(ErrorCode error, Throwable cause, Serializable... params) {
+        super(error, cause, null, params);
+    }
+
     /**
-     * @deprecated Instead, use a constructor with error code
+     * @deprecated Instead, use a constructor with {@link ErrorCode}
      */
     @Deprecated
     public AsterixException(String message) {
         super(message);
     }
 
-    public AsterixException(int errorCode, SourceLocation sourceLoc, Serializable... params) {
-        super(ErrorCode.ASTERIX, errorCode, ErrorCode.getErrorMessage(errorCode), sourceLoc, params);
-    }
-
-    public AsterixException(int errorCode, Serializable... params) {
-        super(ErrorCode.ASTERIX, errorCode, ErrorCode.getErrorMessage(errorCode), params);
-    }
-
     /**
-     * @deprecated When creating a constructor with cause,
-     *             create AlgebricksException using AlgebricksException.create(Throwable th);
+     * @deprecated Instead, use a constructor with {@link ErrorCode}
      */
     @Deprecated
     public AsterixException(Throwable cause) {
         super(cause);
     }
 
-    public AsterixException(int errorCode, Throwable cause, SourceLocation sourceLoc, Serializable... params) {
-        super(ErrorCode.ASTERIX, errorCode, ErrorCode.getErrorMessage(errorCode), sourceLoc, params);
-        addSuppressed(cause);
-    }
-
-    public AsterixException(int errorCode, Throwable cause, Serializable... params) {
-        super(ErrorCode.ASTERIX, errorCode, ErrorCode.getErrorMessage(errorCode), params);
-        addSuppressed(cause);
-    }
-
     /**
-     * @deprecated Instead, use a constructor with error code
+     * @deprecated Instead, use a constructor with {@link ErrorCode}
      */
     @Deprecated
     public AsterixException(String message, Throwable cause) {
         super(message, cause);
     }
 
-    public static AsterixException create(int errorCode, SourceLocation sourceLoc, Serializable... params) {
-        return new AsterixException(errorCode, sourceLoc, params);
+    public static AsterixException create(ErrorCode error, SourceLocation sourceLoc, Serializable... params) {
+        return new AsterixException(error, sourceLoc, params);
     }
 
-    public static AsterixException create(int errorCode, Serializable... params) {
-        return new AsterixException(errorCode, params);
+    public static AsterixException create(ErrorCode error, Serializable... params) {
+        return new AsterixException(error, params);
     }
 }
diff --git a/asterixdb/asterix-common/src/main/java/org/apache/asterix/common/exceptions/CompilationException.java b/asterixdb/asterix-common/src/main/java/org/apache/asterix/common/exceptions/CompilationException.java
index 0de6b72..75fb18d 100644
--- a/asterixdb/asterix-common/src/main/java/org/apache/asterix/common/exceptions/CompilationException.java
+++ b/asterixdb/asterix-common/src/main/java/org/apache/asterix/common/exceptions/CompilationException.java
@@ -27,20 +27,28 @@
 public class CompilationException extends AlgebricksException {
     private static final long serialVersionUID = 1L;
 
-    public CompilationException(int errorCode, SourceLocation sourceLoc, Serializable... params) {
-        super(ErrorCode.ASTERIX, errorCode, ErrorCode.getErrorMessage(errorCode), sourceLoc, params);
+    public static CompilationException create(ErrorCode error, SourceLocation sourceLoc, Serializable... params) {
+        return new CompilationException(error, sourceLoc, params);
     }
 
-    public CompilationException(int errorCode, Serializable... params) {
-        super(ErrorCode.ASTERIX, errorCode, ErrorCode.getErrorMessage(errorCode), params);
+    public static CompilationException create(ErrorCode error, Serializable... params) {
+        return create(error, null, params);
     }
 
-    public CompilationException(int errorCode, Throwable cause, SourceLocation sourceLoc, Serializable... params) {
-        super(ErrorCode.ASTERIX, errorCode, ErrorCode.getErrorMessage(errorCode), cause, sourceLoc, params);
+    public CompilationException(ErrorCode error, Throwable cause, SourceLocation sourceLoc, Serializable... params) {
+        super(error, cause, sourceLoc, params);
     }
 
-    public CompilationException(int errorCode, Throwable cause, Serializable... params) {
-        super(ErrorCode.ASTERIX, errorCode, ErrorCode.getErrorMessage(errorCode), cause, params);
+    public CompilationException(ErrorCode error, SourceLocation sourceLoc, Serializable... params) {
+        this(error, null, sourceLoc, params);
+    }
+
+    public CompilationException(ErrorCode error, Serializable... params) {
+        this(error, null, null, params);
+    }
+
+    public CompilationException(ErrorCode errorCode, Throwable cause, Serializable... params) {
+        this(errorCode, cause, null, params);
     }
 
     /**
@@ -56,7 +64,7 @@
     /**
      * @deprecated (Don't use this and provide an error code. This exists for the current exceptions and
      *             those exceptions need to adopt error code as well.)
-     * @param message
+     * @param cause
      */
     @Deprecated
     public CompilationException(Throwable cause) {
diff --git a/asterixdb/asterix-common/src/main/java/org/apache/asterix/common/exceptions/ErrorCode.java b/asterixdb/asterix-common/src/main/java/org/apache/asterix/common/exceptions/ErrorCode.java
index 77c6b8d..90a1f8b 100644
--- a/asterixdb/asterix-common/src/main/java/org/apache/asterix/common/exceptions/ErrorCode.java
+++ b/asterixdb/asterix-common/src/main/java/org/apache/asterix/common/exceptions/ErrorCode.java
@@ -18,9 +18,7 @@
  */
 package org.apache.asterix.common.exceptions;
 
-import java.io.InputStream;
-import java.util.Map;
-
+import org.apache.hyracks.api.exceptions.IError;
 import org.apache.hyracks.api.util.ErrorMessageUtil;
 
 // Error code:
@@ -29,357 +27,359 @@
 // 2000 ---- 2999: storage errors
 // 3000 ---- 3999: feed errors
 // 4000 ---- 4999: lifecycle management errors
-public class ErrorCode {
-    private static final String RESOURCE_PATH = "asx_errormsg/en.properties";
-    public static final String ASTERIX = "ASX";
-
+public enum ErrorCode implements IError {
     // Runtime errors
-    public static final int CASTING_FIELD = 1;
-    public static final int TYPE_MISMATCH_FUNCTION = 2;
-    public static final int TYPE_INCOMPATIBLE = 3;
-    public static final int TYPE_UNSUPPORTED = 4;
-    public static final int TYPE_ITEM = 5;
-    public static final int INVALID_FORMAT = 6;
-    public static final int OVERFLOW = 7;
-    public static final int UNDERFLOW = 8;
-    public static final int INJECTED_FAILURE = 9;
-    public static final int NEGATIVE_VALUE = 10;
-    public static final int OUT_OF_BOUND = 11;
-    public static final int COERCION = 12;
-    public static final int DUPLICATE_FIELD_NAME = 13;
-    public static final int PROPERTY_NOT_SET = 14;
-    public static final int ROOT_LOCAL_RESOURCE_EXISTS = 15;
-    public static final int ROOT_LOCAL_RESOURCE_COULD_NOT_BE_CREATED = 16;
-    public static final int UNKNOWN_EXTERNAL_FILE_PENDING_OP = 17;
-    public static final int TYPE_CONVERT = 18;
-    public static final int TYPE_CONVERT_INTEGER_SOURCE = 19;
-    public static final int TYPE_CONVERT_INTEGER_TARGET = 20;
-    public static final int TYPE_CONVERT_OUT_OF_BOUND = 21;
-    public static final int FIELD_SHOULD_BE_TYPED = 22;
-    public static final int NC_REQUEST_TIMEOUT = 23;
-    public static final int POLYGON_INVALID_COORDINATE = 24;
-    public static final int POLYGON_3_POINTS = 25;
-    public static final int POLYGON_INVALID = 26;
-    public static final int OPERATION_NOT_SUPPORTED = 27;
-    public static final int INVALID_DURATION = 28;
-    public static final int UNKNOWN_DURATION_UNIT = 29;
-    public static final int REQUEST_TIMEOUT = 30;
-    public static final int INVALID_TYPE_CASTING_MATH_FUNCTION = 31;
-    public static final int REJECT_BAD_CLUSTER_STATE = 32;
-    public static final int REJECT_NODE_UNREGISTERED = 33;
-    public static final int UNSUPPORTED_MULTIPLE_STATEMENTS = 35;
-    public static final int CANNOT_COMPARE_COMPLEX = 36;
-    public static final int TYPE_MISMATCH_GENERIC = 37;
-    public static final int DIFFERENT_LIST_TYPE_ARGS = 38;
-    public static final int INTEGER_VALUE_EXPECTED = 39;
-    public static final int NO_STATEMENT_PROVIDED = 40;
-    public static final int REQUEST_CANCELLED = 41;
-    public static final int TPCDS_INVALID_TABLE_NAME = 42;
-    public static final int VALUE_OUT_OF_RANGE = 43;
-    public static final int PROHIBITED_STATEMENT_CATEGORY = 44;
-    public static final int INTEGER_VALUE_EXPECTED_FUNCTION = 45;
-    public static final int INVALID_LIKE_PATTERN = 46;
-    public static final int INVALID_REQ_PARAM_VAL = 47;
-    public static final int INVALID_REQ_JSON_VAL = 48;
-    public static final int PARAMETERS_REQUIRED = 49;
-    public static final int INVALID_PARAM = 50;
-    public static final int INCOMPARABLE_TYPES = 51;
-    public static final int ILLEGAL_STATE = 52;
+    CASTING_FIELD(1),
+    TYPE_MISMATCH_FUNCTION(2),
+    TYPE_INCOMPATIBLE(3),
+    TYPE_UNSUPPORTED(4),
+    TYPE_ITEM(5),
+    INVALID_FORMAT(6),
+    OVERFLOW(7),
+    UNDERFLOW(8),
+    INJECTED_FAILURE(9),
+    NEGATIVE_VALUE(10),
+    OUT_OF_BOUND(11),
+    COERCION(12),
+    DUPLICATE_FIELD_NAME(13),
+    PROPERTY_NOT_SET(14),
+    ROOT_LOCAL_RESOURCE_EXISTS(15),
+    ROOT_LOCAL_RESOURCE_COULD_NOT_BE_CREATED(16),
+    UNKNOWN_EXTERNAL_FILE_PENDING_OP(17),
+    TYPE_CONVERT(18),
+    TYPE_CONVERT_INTEGER_SOURCE(19),
+    TYPE_CONVERT_INTEGER_TARGET(20),
+    TYPE_CONVERT_OUT_OF_BOUND(21),
+    FIELD_SHOULD_BE_TYPED(22),
+    NC_REQUEST_TIMEOUT(23),
+    POLYGON_INVALID_COORDINATE(24),
+    POLYGON_3_POINTS(25),
+    POLYGON_INVALID(26),
+    OPERATION_NOT_SUPPORTED(27),
+    INVALID_DURATION(28),
+    UNKNOWN_DURATION_UNIT(29),
+    REQUEST_TIMEOUT(30),
+    INVALID_TYPE_CASTING_MATH_FUNCTION(31),
+    REJECT_BAD_CLUSTER_STATE(32),
+    REJECT_NODE_UNREGISTERED(33),
+    UNSUPPORTED_MULTIPLE_STATEMENTS(35),
+    CANNOT_COMPARE_COMPLEX(36),
+    TYPE_MISMATCH_GENERIC(37),
+    DIFFERENT_LIST_TYPE_ARGS(38),
+    INTEGER_VALUE_EXPECTED(39),
+    NO_STATEMENT_PROVIDED(40),
+    REQUEST_CANCELLED(41),
+    TPCDS_INVALID_TABLE_NAME(42),
+    VALUE_OUT_OF_RANGE(43),
+    PROHIBITED_STATEMENT_CATEGORY(44),
+    INTEGER_VALUE_EXPECTED_FUNCTION(45),
+    INVALID_LIKE_PATTERN(46),
+    INVALID_REQ_PARAM_VAL(47),
+    INVALID_REQ_JSON_VAL(48),
+    PARAMETERS_REQUIRED(49),
+    INVALID_PARAM(50),
+    INCOMPARABLE_TYPES(51),
+    ILLEGAL_STATE(52),
 
-    public static final int UNSUPPORTED_JRE = 100;
+    UNSUPPORTED_JRE(100),
 
-    public static final int EXTERNAL_UDF_RESULT_TYPE_ERROR = 200;
-    public static final int EXTERNAL_UDF_EXCEPTION = 201;
+    EXTERNAL_UDF_RESULT_TYPE_ERROR(200),
+    EXTERNAL_UDF_EXCEPTION(201),
 
     // Compilation errors
-    public static final int PARSE_ERROR = 1001;
-    public static final int COMPILATION_TYPE_MISMATCH_FUNCTION = 1002;
-    public static final int COMPILATION_TYPE_INCOMPATIBLE = 1003;
-    public static final int COMPILATION_TYPE_UNSUPPORTED = 1004;
-    public static final int COMPILATION_TYPE_ITEM = 1005;
-    public static final int COMPILATION_DUPLICATE_FIELD_NAME = 1006;
-    public static final int COMPILATION_INVALID_EXPRESSION = 1007;
-    public static final int COMPILATION_INVALID_PARAMETER_NUMBER = 1008;
-    public static final int COMPILATION_INVALID_RETURNING_EXPRESSION = 1009;
-    public static final int COMPILATION_FULLTEXT_PHRASE_FOUND = 1010;
-    public static final int COMPILATION_UNKNOWN_DATASET_TYPE = 1011;
-    public static final int COMPILATION_UNKNOWN_INDEX_TYPE = 1012;
-    public static final int COMPILATION_ILLEGAL_INDEX_NUM_OF_FIELD = 1013;
-    public static final int COMPILATION_FIELD_NOT_FOUND = 1014;
-    public static final int COMPILATION_ILLEGAL_INDEX_FOR_DATASET_WITH_COMPOSITE_PRIMARY_INDEX = 1015;
-    public static final int COMPILATION_INDEX_TYPE_NOT_SUPPORTED_FOR_DATASET_TYPE = 1016;
-    public static final int COMPILATION_FILTER_CANNOT_BE_NULLABLE = 1017;
-    public static final int COMPILATION_ILLEGAL_FILTER_TYPE = 1018;
-    public static final int COMPILATION_CANNOT_AUTOGENERATE_COMPOSITE_PRIMARY_KEY = 1019;
-    public static final int COMPILATION_ILLEGAL_AUTOGENERATED_TYPE = 1020;
-    public static final int COMPILATION_PRIMARY_KEY_CANNOT_BE_NULLABLE = 1021;
-    public static final int COMPILATION_ILLEGAL_PRIMARY_KEY_TYPE = 1022;
-    public static final int COMPILATION_CANT_DROP_ACTIVE_DATASET = 1023;
-    public static final int COMPILATION_FUNC_EXPRESSION_CANNOT_UTILIZE_INDEX = 1026;
-    public static final int COMPILATION_DATASET_TYPE_DOES_NOT_HAVE_PRIMARY_INDEX = 1027;
-    public static final int COMPILATION_UNSUPPORTED_QUERY_PARAMETER = 1028;
-    public static final int NO_METADATA_FOR_DATASET = 1029;
-    public static final int SUBTREE_HAS_NO_DATA_SOURCE = 1030;
-    public static final int SUBTREE_HAS_NO_ADDTIONAL_DATA_SOURCE = 1031;
-    public static final int NO_INDEX_FIELD_NAME_FOR_GIVEN_FUNC_EXPR = 1032;
-    public static final int NO_SUPPORTED_TYPE = 1033;
-    public static final int NO_TOKENIZER_FOR_TYPE = 1034;
-    public static final int INCOMPATIBLE_SEARCH_MODIFIER = 1035;
-    public static final int UNKNOWN_SEARCH_MODIFIER = 1036;
-    public static final int COMPILATION_BAD_QUERY_PARAMETER_VALUE = 1037;
-    public static final int COMPILATION_ILLEGAL_STATE = 1038;
-    public static final int COMPILATION_TWO_PHASE_LOCKING_VIOLATION = 1039;
-    public static final int DATASET_ID_EXHAUSTED = 1040;
-    public static final int INDEX_ILLEGAL_ENFORCED_NON_OPTIONAL = 1041;
-    public static final int INDEX_ILLEGAL_NON_ENFORCED_TYPED = 1042;
-    public static final int INDEX_RTREE_MULTIPLE_FIELDS_NOT_ALLOWED = 1043;
-    public static final int REMOTE_EXCEPTION_WHEN_CALLING_METADATA_NODE = 1044;
-    public static final int ILLEGAL_LOCK_UPGRADE_OPERATION = 1045;
-    public static final int ILLEGAL_LOCK_DOWNGRADE_OPERATION = 1046;
-    public static final int UPGRADE_FAILED_LOCK_WAS_NOT_ACQUIRED = 1047;
-    public static final int DOWNGRADE_FAILED_LOCK_WAS_NOT_ACQUIRED = 1048;
-    public static final int LOCK_WAS_ACQUIRED_DIFFERENT_OPERATION = 1049;
-    public static final int UNKNOWN_DATASET_IN_DATAVERSE = 1050;
-    public static final int INDEX_ILLEGAL_ENFORCED_ON_CLOSED_FIELD = 1051;
-    public static final int INDEX_ILLEGAL_REPETITIVE_FIELD = 1052;
-    public static final int CANNOT_CREATE_SEC_PRIMARY_IDX_ON_EXT_DATASET = 1053;
-    public static final int COMPILATION_FAILED_DUE_TO_REPLICATE_OP = 1054;
-    public static final int COMPILATION_INCOMPATIBLE_FUNCTION_LANGUAGE = 1055;
-    public static final int TOO_MANY_OPTIONS_FOR_FUNCTION = 1056;
-    public static final int EXPRESSION_NOT_SUPPORTED_IN_CONSTANT_RECORD = 1057;
-    public static final int LITERAL_TYPE_NOT_SUPPORTED_IN_CONSTANT_RECORD = 1058;
-    public static final int UNSUPPORTED_WITH_FIELD = 1059;
-    public static final int WITH_FIELD_MUST_BE_OF_TYPE = 1060;
-    public static final int WITH_FIELD_MUST_CONTAIN_SUB_FIELD = 1061;
-    public static final int CONFIGURATION_PARAMETER_INVALID_TYPE = 1062;
-    public static final int UNKNOWN_DATAVERSE = 1063;
-    public static final int ERROR_OCCURRED_BETWEEN_TWO_TYPES_CONVERSION = 1064;
-    public static final int CHOSEN_INDEX_COUNT_SHOULD_BE_GREATER_THAN_ONE = 1065;
-    public static final int CANNOT_SERIALIZE_A_VALUE = 1066;
-    public static final int CANNOT_FIND_NON_MISSING_SELECT_OPERATOR = 1067;
-    public static final int CANNOT_GET_CONDITIONAL_SPLIT_KEY_VARIABLE = 1068;
-    public static final int CANNOT_DROP_INDEX = 1069;
-    public static final int METADATA_ERROR = 1070;
-    public static final int DATAVERSE_EXISTS = 1071;
-    public static final int DATASET_EXISTS = 1072;
-    public static final int UNDEFINED_IDENTIFIER = 1073;
-    public static final int AMBIGUOUS_IDENTIFIER = 1074;
-    public static final int FORBIDDEN_SCOPE = 1075;
-    public static final int NAME_RESOLVE_UNKNOWN_DATASET = 1076;
-    public static final int NAME_RESOLVE_UNKNOWN_DATASET_IN_DATAVERSE = 1077;
-    public static final int COMPILATION_UNEXPECTED_OPERATOR = 1078;
-    public static final int COMPILATION_ERROR = 1079;
-    public static final int UNKNOWN_NODEGROUP = 1080;
-    public static final int UNKNOWN_FUNCTION = 1081;
-    public static final int UNKNOWN_TYPE = 1082;
-    public static final int UNKNOWN_INDEX = 1083;
-    public static final int INDEX_EXISTS = 1084;
-    public static final int TYPE_EXISTS = 1085;
-    public static final int PARAMETER_NO_VALUE = 1086;
-    public static final int COMPILATION_INVALID_NUM_OF_ARGS = 1087;
-    public static final int FIELD_NOT_FOUND = 1088;
-    public static final int FIELD_NOT_OF_TYPE = 1089;
-    public static final int ARRAY_FIELD_ELEMENTS_MUST_BE_OF_TYPE = 1090;
-    public static final int COMPILATION_TYPE_MISMATCH_GENERIC = 1091;
-    public static final int ILLEGAL_SET_PARAMETER = 1092;
-    public static final int COMPILATION_TRANSLATION_ERROR = 1093;
-    public static final int RANGE_MAP_ERROR = 1094;
-    public static final int COMPILATION_EXPECTED_FUNCTION_CALL = 1095;
-    public static final int UNKNOWN_COMPRESSION_SCHEME = 1096;
-    public static final int UNSUPPORTED_WITH_SUBFIELD = 1097;
-    public static final int COMPILATION_INVALID_WINDOW_FRAME = 1098;
-    public static final int COMPILATION_UNEXPECTED_WINDOW_FRAME = 1099;
-    public static final int COMPILATION_UNEXPECTED_WINDOW_EXPRESSION = 1100;
-    public static final int COMPILATION_UNEXPECTED_WINDOW_ORDERBY = 1101;
-    public static final int COMPILATION_EXPECTED_WINDOW_FUNCTION = 1102;
-    public static final int COMPILATION_ILLEGAL_USE_OF_IDENTIFIER = 1103;
-    public static final int INVALID_FUNCTION_MODIFIER = 1104;
-    public static final int OPERATION_NOT_SUPPORTED_ON_PRIMARY_INDEX = 1105;
-    public static final int EXPECTED_CONSTANT_VALUE = 1106;
-    public static final int UNEXPECTED_HINT = 1107;
-    public static final int EXTERNAL_SOURCE_ERROR = 1108;
-    public static final int EXTERNAL_SOURCE_CONTAINER_NOT_FOUND = 1109;
-    public static final int PARAMETERS_NOT_ALLOWED_AT_SAME_TIME = 1110;
-    public static final int PROPERTY_INVALID_VALUE_TYPE = 1111;
-    public static final int INVALID_PROPERTY_FORMAT = 1112;
-    public static final int INVALID_REGEX_PATTERN = 1113;
-    public static final int EXTERNAL_SOURCE_CONFIGURATION_RETURNED_NO_FILES = 1114;
-    public static final int INVALID_DATABASE_OBJECT_NAME = 1115;
-    public static final int UNKNOWN_SYNONYM = 1116;
-    public static final int UNKNOWN_LIBRARY = 1117;
-    public static final int COMPILATION_GROUPING_SETS_OVERFLOW = 1118;
-    public static final int COMPILATION_GROUPING_OPERATION_INVALID_ARG = 1119;
-    public static final int COMPILATION_UNEXPECTED_ALIAS = 1120;
-    public static final int COMPILATION_ILLEGAL_USE_OF_FILTER_CLAUSE = 1121;
-    public static final int COMPILATION_BAD_FUNCTION_DEFINITION = 1122;
-    public static final int FUNCTION_EXISTS = 1123;
-    public static final int ADAPTER_EXISTS = 1124;
-    public static final int UNKNOWN_ADAPTER = 1125;
-    public static final int INVALID_EXTERNAL_IDENTIFIER_SIZE = 1126;
-    public static final int UNSUPPORTED_ADAPTER_LANGUAGE = 1127;
-    public static final int INCONSISTENT_FILTER_INDICATOR = 1128;
-    public static final int UNSUPPORTED_GBY_OBY_SELECT_COMBO = 1129;
-    public static final int ILLEGAL_RIGHT_OUTER_JOIN = 1130;
-    public static final int SYNONYM_EXISTS = 1131;
-    public static final int INVALID_HINT = 1132;
-    public static final int FULL_TEXT_FILTER_NOT_FOUND = 1133;
-    public static final int FULL_TEXT_DEFAULT_CONFIG_CANNOT_BE_DELETED_OR_CREATED = 1134;
-    public static final int FULL_TEXT_CONFIG_ALREADY_EXISTS = 1135;
-    public static final int FULL_TEXT_FILTER_ALREADY_EXISTS = 1136;
-    public static final int FULL_TEXT_CONFIG_NOT_FOUND = 1137;
-    public static final int ONLY_SINGLE_AUTHENTICATION_IS_ALLOWED = 1138;
-    public static final int NO_AUTH_METHOD_PROVIDED = 1139;
+    PARSE_ERROR(1001),
+    COMPILATION_TYPE_MISMATCH_FUNCTION(1002),
+    COMPILATION_TYPE_INCOMPATIBLE(1003),
+    COMPILATION_TYPE_UNSUPPORTED(1004),
+    COMPILATION_TYPE_ITEM(1005),
+    COMPILATION_DUPLICATE_FIELD_NAME(1006),
+    COMPILATION_INVALID_EXPRESSION(1007),
+    COMPILATION_INVALID_PARAMETER_NUMBER(1008),
+    COMPILATION_INVALID_RETURNING_EXPRESSION(1009),
+    COMPILATION_FULLTEXT_PHRASE_FOUND(1010),
+    COMPILATION_UNKNOWN_DATASET_TYPE(1011),
+    COMPILATION_UNKNOWN_INDEX_TYPE(1012),
+    COMPILATION_ILLEGAL_INDEX_NUM_OF_FIELD(1013),
+    COMPILATION_FIELD_NOT_FOUND(1014),
+    COMPILATION_ILLEGAL_INDEX_FOR_DATASET_WITH_COMPOSITE_PRIMARY_INDEX(1015),
+    COMPILATION_INDEX_TYPE_NOT_SUPPORTED_FOR_DATASET_TYPE(1016),
+    COMPILATION_FILTER_CANNOT_BE_NULLABLE(1017),
+    COMPILATION_ILLEGAL_FILTER_TYPE(1018),
+    COMPILATION_CANNOT_AUTOGENERATE_COMPOSITE_PRIMARY_KEY(1019),
+    COMPILATION_ILLEGAL_AUTOGENERATED_TYPE(1020),
+    COMPILATION_PRIMARY_KEY_CANNOT_BE_NULLABLE(1021),
+    COMPILATION_ILLEGAL_PRIMARY_KEY_TYPE(1022),
+    COMPILATION_CANT_DROP_ACTIVE_DATASET(1023),
+    COMPILATION_FUNC_EXPRESSION_CANNOT_UTILIZE_INDEX(1026),
+    COMPILATION_DATASET_TYPE_DOES_NOT_HAVE_PRIMARY_INDEX(1027),
+    COMPILATION_UNSUPPORTED_QUERY_PARAMETER(1028),
+    NO_METADATA_FOR_DATASET(1029),
+    SUBTREE_HAS_NO_DATA_SOURCE(1030),
+    SUBTREE_HAS_NO_ADDTIONAL_DATA_SOURCE(1031),
+    NO_INDEX_FIELD_NAME_FOR_GIVEN_FUNC_EXPR(1032),
+    NO_SUPPORTED_TYPE(1033),
+    NO_TOKENIZER_FOR_TYPE(1034),
+    INCOMPATIBLE_SEARCH_MODIFIER(1035),
+    UNKNOWN_SEARCH_MODIFIER(1036),
+    COMPILATION_BAD_QUERY_PARAMETER_VALUE(1037),
+    COMPILATION_ILLEGAL_STATE(1038),
+    COMPILATION_TWO_PHASE_LOCKING_VIOLATION(1039),
+    DATASET_ID_EXHAUSTED(1040),
+    INDEX_ILLEGAL_ENFORCED_NON_OPTIONAL(1041),
+    INDEX_ILLEGAL_NON_ENFORCED_TYPED(1042),
+    INDEX_RTREE_MULTIPLE_FIELDS_NOT_ALLOWED(1043),
+    REMOTE_EXCEPTION_WHEN_CALLING_METADATA_NODE(1044),
+    ILLEGAL_LOCK_UPGRADE_OPERATION(1045),
+    ILLEGAL_LOCK_DOWNGRADE_OPERATION(1046),
+    UPGRADE_FAILED_LOCK_WAS_NOT_ACQUIRED(1047),
+    DOWNGRADE_FAILED_LOCK_WAS_NOT_ACQUIRED(1048),
+    LOCK_WAS_ACQUIRED_DIFFERENT_OPERATION(1049),
+    UNKNOWN_DATASET_IN_DATAVERSE(1050),
+    INDEX_ILLEGAL_ENFORCED_ON_CLOSED_FIELD(1051),
+    INDEX_ILLEGAL_REPETITIVE_FIELD(1052),
+    CANNOT_CREATE_SEC_PRIMARY_IDX_ON_EXT_DATASET(1053),
+    COMPILATION_FAILED_DUE_TO_REPLICATE_OP(1054),
+    COMPILATION_INCOMPATIBLE_FUNCTION_LANGUAGE(1055),
+    TOO_MANY_OPTIONS_FOR_FUNCTION(1056),
+    EXPRESSION_NOT_SUPPORTED_IN_CONSTANT_RECORD(1057),
+    LITERAL_TYPE_NOT_SUPPORTED_IN_CONSTANT_RECORD(1058),
+    UNSUPPORTED_WITH_FIELD(1059),
+    WITH_FIELD_MUST_BE_OF_TYPE(1060),
+    WITH_FIELD_MUST_CONTAIN_SUB_FIELD(1061),
+    CONFIGURATION_PARAMETER_INVALID_TYPE(1062),
+    UNKNOWN_DATAVERSE(1063),
+    ERROR_OCCURRED_BETWEEN_TWO_TYPES_CONVERSION(1064),
+    CHOSEN_INDEX_COUNT_SHOULD_BE_GREATER_THAN_ONE(1065),
+    CANNOT_SERIALIZE_A_VALUE(1066),
+    CANNOT_FIND_NON_MISSING_SELECT_OPERATOR(1067),
+    CANNOT_GET_CONDITIONAL_SPLIT_KEY_VARIABLE(1068),
+    CANNOT_DROP_INDEX(1069),
+    METADATA_ERROR(1070),
+    DATAVERSE_EXISTS(1071),
+    DATASET_EXISTS(1072),
+    UNDEFINED_IDENTIFIER(1073),
+    AMBIGUOUS_IDENTIFIER(1074),
+    FORBIDDEN_SCOPE(1075),
+    NAME_RESOLVE_UNKNOWN_DATASET(1076),
+    NAME_RESOLVE_UNKNOWN_DATASET_IN_DATAVERSE(1077),
+    COMPILATION_UNEXPECTED_OPERATOR(1078),
+    COMPILATION_ERROR(1079),
+    UNKNOWN_NODEGROUP(1080),
+    UNKNOWN_FUNCTION(1081),
+    UNKNOWN_TYPE(1082),
+    UNKNOWN_INDEX(1083),
+    INDEX_EXISTS(1084),
+    TYPE_EXISTS(1085),
+    PARAMETER_NO_VALUE(1086),
+    COMPILATION_INVALID_NUM_OF_ARGS(1087),
+    FIELD_NOT_FOUND(1088),
+    FIELD_NOT_OF_TYPE(1089),
+    ARRAY_FIELD_ELEMENTS_MUST_BE_OF_TYPE(1090),
+    COMPILATION_TYPE_MISMATCH_GENERIC(1091),
+    ILLEGAL_SET_PARAMETER(1092),
+    COMPILATION_TRANSLATION_ERROR(1093),
+    RANGE_MAP_ERROR(1094),
+    COMPILATION_EXPECTED_FUNCTION_CALL(1095),
+    UNKNOWN_COMPRESSION_SCHEME(1096),
+    UNSUPPORTED_WITH_SUBFIELD(1097),
+    COMPILATION_INVALID_WINDOW_FRAME(1098),
+    COMPILATION_UNEXPECTED_WINDOW_FRAME(1099),
+    COMPILATION_UNEXPECTED_WINDOW_EXPRESSION(1100),
+    COMPILATION_UNEXPECTED_WINDOW_ORDERBY(1101),
+    COMPILATION_EXPECTED_WINDOW_FUNCTION(1102),
+    COMPILATION_ILLEGAL_USE_OF_IDENTIFIER(1103),
+    INVALID_FUNCTION_MODIFIER(1104),
+    OPERATION_NOT_SUPPORTED_ON_PRIMARY_INDEX(1105),
+    EXPECTED_CONSTANT_VALUE(1106),
+    UNEXPECTED_HINT(1107),
+    EXTERNAL_SOURCE_ERROR(1108),
+    EXTERNAL_SOURCE_CONTAINER_NOT_FOUND(1109),
+    PARAMETERS_NOT_ALLOWED_AT_SAME_TIME(1110),
+    PROPERTY_INVALID_VALUE_TYPE(1111),
+    INVALID_PROPERTY_FORMAT(1112),
+    INVALID_REGEX_PATTERN(1113),
+    EXTERNAL_SOURCE_CONFIGURATION_RETURNED_NO_FILES(1114),
+    INVALID_DATABASE_OBJECT_NAME(1115),
+    UNKNOWN_SYNONYM(1116),
+    UNKNOWN_LIBRARY(1117),
+    COMPILATION_GROUPING_SETS_OVERFLOW(1118),
+    COMPILATION_GROUPING_OPERATION_INVALID_ARG(1119),
+    COMPILATION_UNEXPECTED_ALIAS(1120),
+    COMPILATION_ILLEGAL_USE_OF_FILTER_CLAUSE(1121),
+    COMPILATION_BAD_FUNCTION_DEFINITION(1122),
+    FUNCTION_EXISTS(1123),
+    ADAPTER_EXISTS(1124),
+    UNKNOWN_ADAPTER(1125),
+    INVALID_EXTERNAL_IDENTIFIER_SIZE(1126),
+    UNSUPPORTED_ADAPTER_LANGUAGE(1127),
+    INCONSISTENT_FILTER_INDICATOR(1128),
+    UNSUPPORTED_GBY_OBY_SELECT_COMBO(1129),
+    ILLEGAL_RIGHT_OUTER_JOIN(1130),
+    SYNONYM_EXISTS(1131),
+    INVALID_HINT(1132),
+    ONLY_SINGLE_AUTHENTICATION_IS_ALLOWED(1133),
+    NO_AUTH_METHOD_PROVIDED(1134),
+    FULL_TEXT_CONFIG_ALREADY_EXISTS(1135),
+    FULL_TEXT_FILTER_ALREADY_EXISTS(1136),
+    FULL_TEXT_CONFIG_NOT_FOUND(1137),
+    FULL_TEXT_FILTER_NOT_FOUND(1138),
+    FULL_TEXT_DEFAULT_CONFIG_CANNOT_BE_DELETED_OR_CREATED(1139),
 
     // Feed errors
-    public static final int DATAFLOW_ILLEGAL_STATE = 3001;
-    public static final int UTIL_DATAFLOW_UTILS_TUPLE_TOO_LARGE = 3002;
-    public static final int UTIL_DATAFLOW_UTILS_UNKNOWN_FORWARD_POLICY = 3003;
-    public static final int OPERATORS_FEED_INTAKE_OPERATOR_DESCRIPTOR_CLASSLOADER_NOT_CONFIGURED = 3004;
-    public static final int PARSER_DELIMITED_NONOPTIONAL_NULL = 3005;
-    public static final int PARSER_DELIMITED_ILLEGAL_FIELD = 3006;
-    public static final int ADAPTER_TWITTER_TWITTER4J_LIB_NOT_FOUND = 3007;
-    public static final int OPERATORS_FEED_INTAKE_OPERATOR_NODE_PUSHABLE_FAIL_AT_INGESTION = 3008;
-    public static final int FEED_CREATE_FEED_DATATYPE_ERROR = 3009;
-    public static final int PARSER_HIVE_NON_PRIMITIVE_LIST_NOT_SUPPORT = 3010;
-    public static final int PARSER_HIVE_FIELD_TYPE = 3011;
-    public static final int PARSER_HIVE_GET_COLUMNS = 3012;
-    public static final int PARSER_HIVE_NO_CLOSED_COLUMNS = 3013;
-    public static final int PARSER_HIVE_NOT_SUPPORT_NON_OP_UNION = 3014;
-    public static final int PARSER_HIVE_MISSING_FIELD_TYPE_INFO = 3015;
-    public static final int PARSER_HIVE_NULL_FIELD = 3016;
-    public static final int PARSER_HIVE_NULL_VALUE_IN_LIST = 3017;
-    public static final int INPUT_RECORD_RECORD_WITH_METADATA_AND_PK_NULL_IN_NON_OPTIONAL = 3018;
-    public static final int INPUT_RECORD_RECORD_WITH_METADATA_AND_PK_CANNT_GET_PKEY = 3019;
-    public static final int FEED_CHANGE_FEED_CONNECTIVITY_ON_ALIVE_FEED = 3020;
-    public static final int RECORD_READER_MALFORMED_INPUT_STREAM = 3021;
-    public static final int PROVIDER_DATAFLOW_CONTROLLER_UNKNOWN_DATA_SOURCE = 3022;
-    public static final int PROVIDER_DATASOURCE_FACTORY_UNKNOWN_INPUT_STREAM_FACTORY = 3023;
-    public static final int UTIL_EXTERNAL_DATA_UTILS_FAIL_CREATE_STREAM_FACTORY = 3024;
-    public static final int UNKNOWN_RECORD_READER_FACTORY = 3025;
-    public static final int PROVIDER_STREAM_RECORD_READER_UNKNOWN_FORMAT = 3026;
-    public static final int UNKNOWN_RECORD_FORMAT_FOR_META_PARSER = 3027;
-    public static final int LIBRARY_JAVA_JOBJECTS_FIELD_ALREADY_DEFINED = 3028;
-    public static final int LIBRARY_JAVA_JOBJECTS_UNKNOWN_FIELD = 3029;
-    public static final int NODE_RESOLVER_NO_NODE_CONTROLLERS = 3031;
-    public static final int NODE_RESOLVER_UNABLE_RESOLVE_HOST = 3032;
-    public static final int INPUT_RECORD_CONVERTER_DCP_MSG_TO_RECORD_CONVERTER_UNKNOWN_DCP_REQUEST = 3033;
-    public static final int FEED_DATAFLOW_FRAME_DISTR_REGISTER_FAILED_DATA_PROVIDER = 3034;
-    public static final int INPUT_RECORD_READER_CHAR_ARRAY_RECORD_TOO_LARGE = 3038;
-    public static final int LIBRARY_JOBJECT_ACCESSOR_CANNOT_PARSE_TYPE = 3039;
-    public static final int LIBRARY_JOBJECT_UTIL_ILLEGAL_ARGU_TYPE = 3040;
-    public static final int LIBRARY_EXTERNAL_FUNCTION_UNABLE_TO_LOAD_CLASS = 3041;
-    public static final int LIBRARY_EXTERNAL_FUNCTION_UNSUPPORTED_KIND = 3042;
-    public static final int LIBRARY_EXTERNAL_FUNCTION_UNKNOWN_KIND = 3043;
-    public static final int LIBRARY_EXTERNAL_LIBRARY_CLASS_REGISTERED = 3044;
-    public static final int LIBRARY_JAVA_FUNCTION_HELPER_CANNOT_HANDLE_ARGU_TYPE = 3045;
-    public static final int LIBRARY_JAVA_FUNCTION_HELPER_OBJ_TYPE_NOT_SUPPORTED = 3046;
-    public static final int LIBRARY_EXTERNAL_FUNCTION_UNSUPPORTED_NAME = 3047;
-    public static final int OPERATORS_FEED_META_OPERATOR_DESCRIPTOR_INVALID_RUNTIME = 3048;
-    public static final int INVALID_DELIMITER = 3049;
-    public static final int INVALID_CHAR_LENGTH = 3050;
-    public static final int QUOTE_DELIMITER_MISMATCH = 3051;
-    public static final int INDEXING_EXTERNAL_FILE_INDEX_ACCESSOR_UNABLE_TO_FIND_FILE_INDEX = 3052;
-    public static final int PARSER_ADM_DATA_PARSER_FIELD_NOT_NULL = 3053;
-    public static final int PARSER_ADM_DATA_PARSER_TYPE_MISMATCH = 3054;
-    public static final int PARSER_ADM_DATA_PARSER_UNEXPECTED_TOKEN_KIND = 3055;
-    public static final int PARSER_ADM_DATA_PARSER_ILLEGAL_ESCAPE = 3056;
-    public static final int PARSER_ADM_DATA_PARSER_RECORD_END_UNEXPECTED = 3057;
-    public static final int PARSER_ADM_DATA_PARSER_EXTRA_FIELD_IN_CLOSED_RECORD = 3058;
-    public static final int PARSER_ADM_DATA_PARSER_UNEXPECTED_TOKEN_WHEN_EXPECT_COMMA = 3059;
-    public static final int PARSER_ADM_DATA_PARSER_FOUND_COMMA_WHEN = 3060;
-    public static final int PARSER_ADM_DATA_PARSER_UNSUPPORTED_INTERVAL_TYPE = 3061;
-    public static final int PARSER_ADM_DATA_PARSER_INTERVAL_NOT_CLOSED = 3062;
-    public static final int PARSER_ADM_DATA_PARSER_INTERVAL_BEGIN_END_POINT_MISMATCH = 3063;
-    public static final int PARSER_ADM_DATA_PARSER_INTERVAL_MISSING_COMMA = 3064;
-    public static final int PARSER_ADM_DATA_PARSER_INTERVAL_INVALID_DATETIME = 3065;
-    public static final int PARSER_ADM_DATA_PARSER_INTERVAL_UNSUPPORTED_TYPE = 3066;
-    public static final int PARSER_ADM_DATA_PARSER_INTERVAL_INTERVAL_ARGUMENT_ERROR = 3067;
-    public static final int PARSER_ADM_DATA_PARSER_LIST_FOUND_END_COLLECTION = 3068;
-    public static final int PARSER_ADM_DATA_PARSER_LIST_FOUND_COMMA_BEFORE_LIST = 3069;
-    public static final int PARSER_ADM_DATA_PARSER_LIST_FOUND_COMMA_EXPECTING_ITEM = 3070;
-    public static final int PARSER_ADM_DATA_PARSER_LIST_FOUND_END_RECOD = 3071;
-    public static final int PARSER_ADM_DATA_PARSER_CAST_ERROR = 3072;
-    public static final int PARSER_ADM_DATA_PARSER_CONSTRUCTOR_MISSING_DESERIALIZER = 3073;
-    public static final int PARSER_ADM_DATA_PARSER_WRONG_INSTANCE = 3074;
-    public static final int PARSER_TWEET_PARSER_CLOSED_FIELD_NULL = 3075;
-    public static final int UTIL_FILE_SYSTEM_WATCHER_NO_FILES_FOUND = 3076;
-    public static final int UTIL_LOCAL_FILE_SYSTEM_UTILS_PATH_NOT_FOUND = 3077;
-    public static final int UTIL_HDFS_UTILS_CANNOT_OBTAIN_HDFS_SCHEDULER = 3078;
-    public static final int ACTIVE_MANAGER_SHUTDOWN = 3079;
-    public static final int FEED_METADATA_UTIL_UNEXPECTED_FEED_DATATYPE = 3080;
-    public static final int FEED_METADATA_SOCKET_ADAPTOR_SOCKET_NOT_PROPERLY_CONFIGURED = 3081;
-    public static final int FEED_METADATA_SOCKET_ADAPTOR_SOCKET_INVALID_HOST_NC = 3082;
-    public static final int PROVIDER_DATASOURCE_FACTORY_DUPLICATE_FORMAT_MAPPING = 3083;
-    public static final int CANNOT_SUBSCRIBE_TO_FAILED_ACTIVE_ENTITY = 3084;
-    public static final int FEED_UNKNOWN_ADAPTER_NAME = 3085;
-    public static final int PROVIDER_STREAM_RECORD_READER_WRONG_CONFIGURATION = 3086;
-    public static final int FEED_CONNECT_FEED_APPLIED_INVALID_FUNCTION = 3087;
-    public static final int ACTIVE_MANAGER_INVALID_RUNTIME = 3088;
-    public static final int ACTIVE_ENTITY_ALREADY_STARTED = 3089;
-    public static final int ACTIVE_ENTITY_CANNOT_BE_STOPPED = 3090;
-    public static final int CANNOT_ADD_DATASET_TO_ACTIVE_ENTITY = 3091;
-    public static final int CANNOT_REMOVE_DATASET_FROM_ACTIVE_ENTITY = 3092;
-    public static final int ACTIVE_ENTITY_IS_ALREADY_REGISTERED = 3093;
-    public static final int CANNOT_ADD_INDEX_TO_DATASET_CONNECTED_TO_ACTIVE_ENTITY = 3094;
-    public static final int CANNOT_REMOVE_INDEX_FROM_DATASET_CONNECTED_TO_ACTIVE_ENTITY = 3095;
-    public static final int ACTIVE_NOTIFICATION_HANDLER_IS_SUSPENDED = 3096;
-    public static final int ACTIVE_ENTITY_LISTENER_IS_NOT_REGISTERED = 3097;
-    public static final int CANNOT_DERIGESTER_ACTIVE_ENTITY_LISTENER = 3098;
-    public static final int DOUBLE_INITIALIZATION_OF_ACTIVE_NOTIFICATION_HANDLER = 3099;
-    public static final int DOUBLE_RECOVERY_ATTEMPTS = 3101;
-    public static final int UNREPORTED_TASK_FAILURE_EXCEPTION = 3102;
-    public static final int ACTIVE_ENTITY_ALREADY_SUSPENDED = 3103;
-    public static final int ACTIVE_ENTITY_CANNOT_RESUME_FROM_STATE = 3104;
-    public static final int ACTIVE_RUNTIME_IS_ALREADY_REGISTERED = 3105;
-    public static final int ACTIVE_RUNTIME_IS_NOT_REGISTERED = 3106;
-    public static final int ACTIVE_EVENT_HANDLER_ALREADY_SUSPENDED = 3107;
-    public static final int FEED_FAILED_WHILE_GETTING_A_NEW_RECORD = 3110;
-    public static final int FEED_START_FEED_WITHOUT_CONNECTION = 3111;
-    public static final int PARSER_COLLECTION_ITEM_CANNOT_BE_NULL = 3112;
-    public static final int FAILED_TO_PARSE_RECORD = 3113;
-    public static final int FAILED_TO_PARSE_RECORD_CONTENT = 3114;
-    public static final int FAILED_TO_PARSE_METADATA = 3115;
-    public static final int INPUT_DECODE_FAILURE = 3116;
-    public static final int FAILED_TO_PARSE_MALFORMED_LOG_RECORD = 3117;
-    public static final int ACTIVE_ENTITY_NOT_RUNNING = 3118;
+    DATAFLOW_ILLEGAL_STATE(3001),
+    UTIL_DATAFLOW_UTILS_TUPLE_TOO_LARGE(3002),
+    UTIL_DATAFLOW_UTILS_UNKNOWN_FORWARD_POLICY(3003),
+    OPERATORS_FEED_INTAKE_OPERATOR_DESCRIPTOR_CLASSLOADER_NOT_CONFIGURED(3004),
+    PARSER_DELIMITED_NONOPTIONAL_NULL(3005),
+    PARSER_DELIMITED_ILLEGAL_FIELD(3006),
+    ADAPTER_TWITTER_TWITTER4J_LIB_NOT_FOUND(3007),
+    OPERATORS_FEED_INTAKE_OPERATOR_NODE_PUSHABLE_FAIL_AT_INGESTION(3008),
+    FEED_CREATE_FEED_DATATYPE_ERROR(3009),
+    PARSER_HIVE_NON_PRIMITIVE_LIST_NOT_SUPPORT(3010),
+    PARSER_HIVE_FIELD_TYPE(3011),
+    PARSER_HIVE_GET_COLUMNS(3012),
+    PARSER_HIVE_NO_CLOSED_COLUMNS(3013),
+    PARSER_HIVE_NOT_SUPPORT_NON_OP_UNION(3014),
+    PARSER_HIVE_MISSING_FIELD_TYPE_INFO(3015),
+    PARSER_HIVE_NULL_FIELD(3016),
+    PARSER_HIVE_NULL_VALUE_IN_LIST(3017),
+    INPUT_RECORD_RECORD_WITH_METADATA_AND_PK_NULL_IN_NON_OPTIONAL(3018),
+    INPUT_RECORD_RECORD_WITH_METADATA_AND_PK_CANNT_GET_PKEY(3019),
+    FEED_CHANGE_FEED_CONNECTIVITY_ON_ALIVE_FEED(3020),
+    RECORD_READER_MALFORMED_INPUT_STREAM(3021),
+    PROVIDER_DATAFLOW_CONTROLLER_UNKNOWN_DATA_SOURCE(3022),
+    PROVIDER_DATASOURCE_FACTORY_UNKNOWN_INPUT_STREAM_FACTORY(3023),
+    UTIL_EXTERNAL_DATA_UTILS_FAIL_CREATE_STREAM_FACTORY(3024),
+    UNKNOWN_RECORD_READER_FACTORY(3025),
+    PROVIDER_STREAM_RECORD_READER_UNKNOWN_FORMAT(3026),
+    UNKNOWN_RECORD_FORMAT_FOR_META_PARSER(3027),
+    LIBRARY_JAVA_JOBJECTS_FIELD_ALREADY_DEFINED(3028),
+    LIBRARY_JAVA_JOBJECTS_UNKNOWN_FIELD(3029),
+    NODE_RESOLVER_NO_NODE_CONTROLLERS(3031),
+    NODE_RESOLVER_UNABLE_RESOLVE_HOST(3032),
+    INPUT_RECORD_CONVERTER_DCP_MSG_TO_RECORD_CONVERTER_UNKNOWN_DCP_REQUEST(3033),
+    FEED_DATAFLOW_FRAME_DISTR_REGISTER_FAILED_DATA_PROVIDER(3034),
+    INPUT_RECORD_READER_CHAR_ARRAY_RECORD_TOO_LARGE(3038),
+    LIBRARY_JOBJECT_ACCESSOR_CANNOT_PARSE_TYPE(3039),
+    LIBRARY_JOBJECT_UTIL_ILLEGAL_ARGU_TYPE(3040),
+    LIBRARY_EXTERNAL_FUNCTION_UNABLE_TO_LOAD_CLASS(3041),
+    LIBRARY_EXTERNAL_FUNCTION_UNSUPPORTED_KIND(3042),
+    LIBRARY_EXTERNAL_FUNCTION_UNKNOWN_KIND(3043),
+    LIBRARY_EXTERNAL_LIBRARY_CLASS_REGISTERED(3044),
+    LIBRARY_JAVA_FUNCTION_HELPER_CANNOT_HANDLE_ARGU_TYPE(3045),
+    LIBRARY_JAVA_FUNCTION_HELPER_OBJ_TYPE_NOT_SUPPORTED(3046),
+    LIBRARY_EXTERNAL_FUNCTION_UNSUPPORTED_NAME(3047),
+    OPERATORS_FEED_META_OPERATOR_DESCRIPTOR_INVALID_RUNTIME(3048),
+    INVALID_DELIMITER(3049),
+    INVALID_CHAR_LENGTH(3050),
+    QUOTE_DELIMITER_MISMATCH(3051),
+    INDEXING_EXTERNAL_FILE_INDEX_ACCESSOR_UNABLE_TO_FIND_FILE_INDEX(3052),
+    PARSER_ADM_DATA_PARSER_FIELD_NOT_NULL(3053),
+    PARSER_ADM_DATA_PARSER_TYPE_MISMATCH(3054),
+    PARSER_ADM_DATA_PARSER_UNEXPECTED_TOKEN_KIND(3055),
+    PARSER_ADM_DATA_PARSER_ILLEGAL_ESCAPE(3056),
+    PARSER_ADM_DATA_PARSER_RECORD_END_UNEXPECTED(3057),
+    PARSER_ADM_DATA_PARSER_EXTRA_FIELD_IN_CLOSED_RECORD(3058),
+    PARSER_ADM_DATA_PARSER_UNEXPECTED_TOKEN_WHEN_EXPECT_COMMA(3059),
+    PARSER_ADM_DATA_PARSER_FOUND_COMMA_WHEN(3060),
+    PARSER_ADM_DATA_PARSER_UNSUPPORTED_INTERVAL_TYPE(3061),
+    PARSER_ADM_DATA_PARSER_INTERVAL_NOT_CLOSED(3062),
+    PARSER_ADM_DATA_PARSER_INTERVAL_BEGIN_END_POINT_MISMATCH(3063),
+    PARSER_ADM_DATA_PARSER_INTERVAL_MISSING_COMMA(3064),
+    PARSER_ADM_DATA_PARSER_INTERVAL_INVALID_DATETIME(3065),
+    PARSER_ADM_DATA_PARSER_INTERVAL_UNSUPPORTED_TYPE(3066),
+    PARSER_ADM_DATA_PARSER_INTERVAL_INTERVAL_ARGUMENT_ERROR(3067),
+    PARSER_ADM_DATA_PARSER_LIST_FOUND_END_COLLECTION(3068),
+    PARSER_ADM_DATA_PARSER_LIST_FOUND_COMMA_BEFORE_LIST(3069),
+    PARSER_ADM_DATA_PARSER_LIST_FOUND_COMMA_EXPECTING_ITEM(3070),
+    PARSER_ADM_DATA_PARSER_LIST_FOUND_END_RECOD(3071),
+    PARSER_ADM_DATA_PARSER_CAST_ERROR(3072),
+    PARSER_ADM_DATA_PARSER_CONSTRUCTOR_MISSING_DESERIALIZER(3073),
+    PARSER_ADM_DATA_PARSER_WRONG_INSTANCE(3074),
+    PARSER_TWEET_PARSER_CLOSED_FIELD_NULL(3075),
+    UTIL_FILE_SYSTEM_WATCHER_NO_FILES_FOUND(3076),
+    UTIL_LOCAL_FILE_SYSTEM_UTILS_PATH_NOT_FOUND(3077),
+    UTIL_HDFS_UTILS_CANNOT_OBTAIN_HDFS_SCHEDULER(3078),
+    ACTIVE_MANAGER_SHUTDOWN(3079),
+    FEED_METADATA_UTIL_UNEXPECTED_FEED_DATATYPE(3080),
+    FEED_METADATA_SOCKET_ADAPTOR_SOCKET_NOT_PROPERLY_CONFIGURED(3081),
+    FEED_METADATA_SOCKET_ADAPTOR_SOCKET_INVALID_HOST_NC(3082),
+    PROVIDER_DATASOURCE_FACTORY_DUPLICATE_FORMAT_MAPPING(3083),
+    CANNOT_SUBSCRIBE_TO_FAILED_ACTIVE_ENTITY(3084),
+    FEED_UNKNOWN_ADAPTER_NAME(3085),
+    PROVIDER_STREAM_RECORD_READER_WRONG_CONFIGURATION(3086),
+    FEED_CONNECT_FEED_APPLIED_INVALID_FUNCTION(3087),
+    ACTIVE_MANAGER_INVALID_RUNTIME(3088),
+    ACTIVE_ENTITY_ALREADY_STARTED(3089),
+    ACTIVE_ENTITY_CANNOT_BE_STOPPED(3090),
+    CANNOT_ADD_DATASET_TO_ACTIVE_ENTITY(3091),
+    CANNOT_REMOVE_DATASET_FROM_ACTIVE_ENTITY(3092),
+    ACTIVE_ENTITY_IS_ALREADY_REGISTERED(3093),
+    CANNOT_ADD_INDEX_TO_DATASET_CONNECTED_TO_ACTIVE_ENTITY(3094),
+    CANNOT_REMOVE_INDEX_FROM_DATASET_CONNECTED_TO_ACTIVE_ENTITY(3095),
+    ACTIVE_NOTIFICATION_HANDLER_IS_SUSPENDED(3096),
+    ACTIVE_ENTITY_LISTENER_IS_NOT_REGISTERED(3097),
+    CANNOT_DERIGESTER_ACTIVE_ENTITY_LISTENER(3098),
+    DOUBLE_INITIALIZATION_OF_ACTIVE_NOTIFICATION_HANDLER(3099),
+    DOUBLE_RECOVERY_ATTEMPTS(3101),
+    UNREPORTED_TASK_FAILURE_EXCEPTION(3102),
+    ACTIVE_ENTITY_ALREADY_SUSPENDED(3103),
+    ACTIVE_ENTITY_CANNOT_RESUME_FROM_STATE(3104),
+    ACTIVE_RUNTIME_IS_ALREADY_REGISTERED(3105),
+    ACTIVE_RUNTIME_IS_NOT_REGISTERED(3106),
+    ACTIVE_EVENT_HANDLER_ALREADY_SUSPENDED(3107),
+    FEED_FAILED_WHILE_GETTING_A_NEW_RECORD(3110),
+    FEED_START_FEED_WITHOUT_CONNECTION(3111),
+    PARSER_COLLECTION_ITEM_CANNOT_BE_NULL(3112),
+    FAILED_TO_PARSE_RECORD(3113),
+    FAILED_TO_PARSE_RECORD_CONTENT(3114),
+    FAILED_TO_PARSE_METADATA(3115),
+    INPUT_DECODE_FAILURE(3116),
+    FAILED_TO_PARSE_MALFORMED_LOG_RECORD(3117),
+    ACTIVE_ENTITY_NOT_RUNNING(3118),
 
     // Lifecycle management errors
-    public static final int DUPLICATE_PARTITION_ID = 4000;
+    DUPLICATE_PARTITION_ID(4000),
 
     // Extension errors
-    public static final int EXTENSION_ID_CONFLICT = 4001;
-    public static final int EXTENSION_COMPONENT_CONFLICT = 4002;
-    public static final int UNSUPPORTED_MESSAGE_TYPE = 4003;
-    public static final int INVALID_CONFIGURATION = 4004;
-    public static final int UNSUPPORTED_REPLICATION_STRATEGY = 4005;
+    EXTENSION_ID_CONFLICT(4001),
+    EXTENSION_COMPONENT_CONFLICT(4002),
+    UNSUPPORTED_MESSAGE_TYPE(4003),
+    INVALID_CONFIGURATION(4004),
+    UNSUPPORTED_REPLICATION_STRATEGY(4005),
 
     // Lifecycle management errors pt.2
-    public static final int CLUSTER_STATE_UNUSABLE = 4006;
+    CLUSTER_STATE_UNUSABLE(4006);
 
-    private ErrorCode() {
+    private static final String RESOURCE_PATH = "asx_errormsg/en.properties";
+    public static final String ASTERIX = "ASX";
+    private final int intValue;
+
+    ErrorCode(int intValue) {
+        this.intValue = intValue;
     }
 
-    private static class Holder {
-        private static final Map<Integer, String> errorMessageMap;
-
-        static {
-            // Loads the map that maps error codes to error message templates.
-            try (InputStream resourceStream = ErrorCode.class.getClassLoader().getResourceAsStream(RESOURCE_PATH)) {
-                errorMessageMap = ErrorMessageUtil.loadErrorMap(resourceStream);
-            } catch (Exception e) {
-                throw new IllegalStateException(e);
-            }
-        }
-
-        private Holder() {
-        }
+    @Override
+    public String component() {
+        return ASTERIX;
     }
 
-    public static String getErrorMessage(int errorCode) {
-        String msg = Holder.errorMessageMap.get(errorCode);
-        if (msg == null) {
-            throw new IllegalStateException("Undefined error code: " + errorCode);
+    @Override
+    public int intValue() {
+        return intValue;
+    }
+
+    @Override
+    public String errorMessage() {
+        return ErrorMessageMapHolder.get(this);
+    }
+
+    private static class ErrorMessageMapHolder {
+        private static final String[] enumMessages =
+                ErrorMessageUtil.defineMessageEnumOrdinalMap(values(), RESOURCE_PATH);
+
+        private static String get(ErrorCode errorCode) {
+            return enumMessages[errorCode.ordinal()];
         }
-        return msg;
     }
 }
diff --git a/asterixdb/asterix-common/src/main/java/org/apache/asterix/common/exceptions/ExceptionUtils.java b/asterixdb/asterix-common/src/main/java/org/apache/asterix/common/exceptions/ExceptionUtils.java
index 1f42771..f73848f 100644
--- a/asterixdb/asterix-common/src/main/java/org/apache/asterix/common/exceptions/ExceptionUtils.java
+++ b/asterixdb/asterix-common/src/main/java/org/apache/asterix/common/exceptions/ExceptionUtils.java
@@ -20,7 +20,6 @@
 
 import java.util.function.Predicate;
 
-import org.apache.hyracks.api.exceptions.HyracksDataException;
 import org.apache.hyracks.api.exceptions.IFormattedException;
 
 public class ExceptionUtils {
@@ -54,22 +53,6 @@
         return current;
     }
 
-    public static Throwable getCause(Throwable e, String component, int code) {
-        Throwable current = e;
-        Throwable expected =
-                (current instanceof HyracksDataException && ((HyracksDataException) current).getErrorCode() == code
-                        && ((HyracksDataException) current).getComponent().equals(component)) ? current : null;
-        Throwable cause = e.getCause();
-        while (cause != null && cause != current) {
-            current = cause;
-            expected =
-                    (current instanceof HyracksDataException && ((HyracksDataException) current).getErrorCode() == code
-                            && ((HyracksDataException) current).getComponent().equals(component)) ? current : expected;
-            cause = current.getCause();
-        }
-        return expected == null ? current : expected;
-    }
-
     /**
      * Determines whether supplied exception contains a matching cause in its hierarchy, or is itself a match
      */
diff --git a/asterixdb/asterix-common/src/main/java/org/apache/asterix/common/exceptions/MetadataException.java b/asterixdb/asterix-common/src/main/java/org/apache/asterix/common/exceptions/MetadataException.java
index a735c81..13a006d 100644
--- a/asterixdb/asterix-common/src/main/java/org/apache/asterix/common/exceptions/MetadataException.java
+++ b/asterixdb/asterix-common/src/main/java/org/apache/asterix/common/exceptions/MetadataException.java
@@ -30,51 +30,51 @@
     private static final long serialVersionUID = 1L;
     private static final Logger LOGGER = LogManager.getLogger();
 
-    @Deprecated
     /**
-     * @Deprecated Instead, use a constructor with error code
+     * @deprecated Instead, use a constructor with error code
      * @param message
      */
+    @Deprecated
     public MetadataException(String message) {
         super(message);
     }
 
-    @Deprecated
     /**
-     * @Deprecated When creating a constructor with cause,
+     * @deprecated When creating a constructor with cause,
      *             create AlgebricksException using AlgebricksException.create(Throwable th);
      * @param cause
      */
+    @Deprecated
     public MetadataException(Throwable cause) {
         super(cause);
     }
 
-    @Deprecated
     /**
-     * @Deprecated When creating a constructor with cause,
+     * @deprecated When creating a constructor with cause,
      *             create AlgebricksException using AlgebricksException.create(Throwable th);
      * @param cause
      */
+    @Deprecated
     public MetadataException(String message, Throwable cause) {
         super(message, cause);
     }
 
-    public MetadataException(int errorCode, Serializable... params) {
-        super(errorCode, params);
-    }
-
-    public MetadataException(int errorCode, SourceLocation sourceLoc, Serializable... params) {
-        super(errorCode, sourceLoc, params);
-    }
-
-    public MetadataException(int errorCode, Throwable cause, Serializable... params) {
-        super(errorCode, cause, params);
-    }
-
-    public MetadataException(int errorCode, Throwable cause, SourceLocation sourceLoc, Serializable... params) {
+    public MetadataException(ErrorCode errorCode, Throwable cause, SourceLocation sourceLoc, Serializable... params) {
         super(errorCode, cause, sourceLoc, params);
     }
 
+    public MetadataException(ErrorCode errorCode, SourceLocation sourceLoc, Serializable... params) {
+        this(errorCode, null, sourceLoc, params);
+    }
+
+    public MetadataException(ErrorCode errorCode, Throwable cause, Serializable... params) {
+        this(errorCode, cause, null, params);
+    }
+
+    public MetadataException(ErrorCode errorCode, Serializable... params) {
+        this(errorCode, null, null, params);
+    }
+
     public static MetadataException create(Throwable cause) {
         if (cause instanceof MetadataException || cause == null) {
             return (MetadataException) cause;
diff --git a/asterixdb/asterix-common/src/main/java/org/apache/asterix/common/exceptions/RuntimeDataException.java b/asterixdb/asterix-common/src/main/java/org/apache/asterix/common/exceptions/RuntimeDataException.java
index 1c6763f..1a0a61f 100644
--- a/asterixdb/asterix-common/src/main/java/org/apache/asterix/common/exceptions/RuntimeDataException.java
+++ b/asterixdb/asterix-common/src/main/java/org/apache/asterix/common/exceptions/RuntimeDataException.java
@@ -27,19 +27,25 @@
 public class RuntimeDataException extends HyracksDataException {
     private static final long serialVersionUID = 1L;
 
-    public RuntimeDataException(int errorCode, Serializable... params) {
-        super(ErrorCode.ASTERIX, errorCode, ErrorCode.getErrorMessage(errorCode), params);
+    public static RuntimeDataException create(ErrorCode error, Serializable... params) {
+        return new RuntimeDataException(error, params);
     }
 
-    public RuntimeDataException(int errorCode, SourceLocation sourceLoc, Serializable... params) {
-        super(ErrorCode.ASTERIX, errorCode, ErrorCode.getErrorMessage(errorCode), null, sourceLoc, params);
+    public RuntimeDataException(ErrorCode errorCode, Throwable cause, SourceLocation sourceLoc,
+            Serializable... params) {
+        super(errorCode, cause, sourceLoc, params);
     }
 
-    public RuntimeDataException(int errorCode, Throwable cause, Serializable... params) {
-        super(ErrorCode.ASTERIX, errorCode, ErrorCode.getErrorMessage(errorCode), cause, params);
+    public RuntimeDataException(ErrorCode errorCode, Serializable... params) {
+        this(errorCode, null, null, params);
     }
 
-    public RuntimeDataException(int errorCode, Throwable cause, SourceLocation sourceLoc, Serializable... params) {
-        super(ErrorCode.ASTERIX, errorCode, ErrorCode.getErrorMessage(errorCode), cause, sourceLoc, params);
+    public RuntimeDataException(ErrorCode errorCode, SourceLocation sourceLoc, Serializable... params) {
+        this(errorCode, null, sourceLoc, params);
     }
+
+    public RuntimeDataException(ErrorCode errorCode, Throwable cause, Serializable... params) {
+        this(errorCode, cause, null, params);
+    }
+
 }
diff --git a/asterixdb/asterix-common/src/main/java/org/apache/asterix/common/exceptions/WarningUtil.java b/asterixdb/asterix-common/src/main/java/org/apache/asterix/common/exceptions/WarningUtil.java
index 6a369ef..9dffa94 100644
--- a/asterixdb/asterix-common/src/main/java/org/apache/asterix/common/exceptions/WarningUtil.java
+++ b/asterixdb/asterix-common/src/main/java/org/apache/asterix/common/exceptions/WarningUtil.java
@@ -18,24 +18,16 @@
  */
 package org.apache.asterix.common.exceptions;
 
-import java.io.Serializable;
 import java.util.Collection;
 
 import org.apache.hyracks.api.exceptions.IWarningCollector;
-import org.apache.hyracks.api.exceptions.SourceLocation;
 import org.apache.hyracks.api.exceptions.Warning;
-import org.apache.hyracks.api.util.ErrorMessageUtil;
 
 public class WarningUtil {
 
     private WarningUtil() {
     }
 
-    public static Warning forAsterix(SourceLocation srcLocation, int code, Serializable... params) {
-        return Warning.of(ErrorCode.ASTERIX, srcLocation, code, ErrorMessageUtil.formatMessage(ErrorCode.ASTERIX, code,
-                ErrorCode.getErrorMessage(code), srcLocation, params));
-    }
-
     /** Merges the warnings from the collection argument into the warning collector argument. */
     public static void mergeWarnings(Collection<Warning> warnings, IWarningCollector warningsCollector) {
         for (Warning warning : warnings) {
diff --git a/asterixdb/asterix-common/src/main/java/org/apache/asterix/common/transactions/IResourceIdManager.java b/asterixdb/asterix-common/src/main/java/org/apache/asterix/common/transactions/IResourceIdManager.java
index d36d383..1301dea 100644
--- a/asterixdb/asterix-common/src/main/java/org/apache/asterix/common/transactions/IResourceIdManager.java
+++ b/asterixdb/asterix-common/src/main/java/org/apache/asterix/common/transactions/IResourceIdManager.java
@@ -20,10 +20,19 @@
 
 public interface IResourceIdManager {
 
+    /**
+     * @return the created resource id, or <code>-1</code> if a resource cannot be created
+     */
     long createResourceId();
 
     boolean reported(String nodeId);
 
     void report(String nodeId, long maxResourceId);
 
+    /**
+     * @param blockSize the size of resource id block to create
+     * @return the starting id of contiguous block of resource ids, or <code>-1</code> if
+     *         the resource block cannot be created
+     */
+    long createResourceIdBlock(int blockSize);
 }
diff --git a/asterixdb/asterix-doc/pom.xml b/asterixdb/asterix-doc/pom.xml
index 7c21486..c58d983 100644
--- a/asterixdb/asterix-doc/pom.xml
+++ b/asterixdb/asterix-doc/pom.xml
@@ -55,10 +55,10 @@
                   <filelist dir="${project.basedir}/src/main/markdown/sqlpp" files="0_toc.md,1_intro.md,2_expr_title.md,2_expr.md,3_query_title.md,3_query.md,4_windowfunctions_title.md,4_windowfunctions.md,5_error_title.md,5_error.md,6_sql_diff_title.md,6_sql_diff.md,7_ddl_head.md,7_ddl_dml.md,appendix_1_title.md,appendix_1_keywords.md,appendix_2_title.md,appendix_2_parameters.md,appendix_2_parallel_sort.md,appendix_2_index_only.md,appendix_2_hints.md,appendix_3_title.md,appendix_3_resolution.md,appendix_4_title.md,appendix_4_manual_data.md" />
                 </concat>
                 <concat destfile="${project.build.directory}/generated-site/markdown/sqlpp/builtins.md">
-                  <filelist dir="${project.basedir}/src/main/markdown/builtins" files="0_toc.md,0_toc_sqlpp.md,0_toc_common.md,1_numeric_common.md,1_numeric_delta.md,2_string_common.md,2_string_delta.md,3_binary.md,4_spatial.md,5_similarity.md,6_tokenizing.md,7_temporal.md,7_allens.md,8_record.md,9_aggregate_sql.md,10_comparison.md,11_type.md,13_conditional.md,12_misc.md,15_bitwise.md,14_window.md" />
+                  <filelist dir="${project.basedir}/src/main/markdown/builtins" files="0_toc.md,0_toc_sqlpp.md,0_toc_common.md,1_numeric_common.md,1_numeric_delta.md,2_string_common.md,2_string_delta.md,3_binary.md,4_spatial.md,5_similarity.md,6_tokenizing.md,7_temporal.md,7_allens.md,8_record.md,9_aggregate_sql.md,10_comparison.md,11_type_common.md,11_type_delta.md,11_type_conversion.md,13_conditional.md,12_misc.md,15_bitwise.md,14_window.md" />
                 </concat>
                 <concat destfile="${project.build.directory}/generated-site/markdown/aql/builtins.md">
-                  <filelist dir="${project.basedir}/src/main/markdown/builtins" files="0_toc.md,0_toc_aql.md,0_toc_common.md,1_numeric_common.md,1_numeric_delta.md,2_string_common.md,2_string_delta.md,3_binary.md,4_spatial.md,5_similarity.md,6_tokenizing.md,7_temporal.md,7_allens.md,8_record.md,9_aggregate_sql.md,10_comparison.md,11_type.md,13_conditional.md,12_misc.md" />
+                  <filelist dir="${project.basedir}/src/main/markdown/builtins" files="0_toc.md,0_toc_aql.md,0_toc_common.md,1_numeric_common.md,1_numeric_delta.md,2_string_common.md,2_string_delta.md,3_binary.md,4_spatial.md,5_similarity.md,6_tokenizing.md,7_temporal.md,7_allens.md,8_record.md,9_aggregate_sql.md,10_comparison.md,11_type_common.md,11_type_delta.md,11_type_conversion.md,13_conditional.md,12_misc.md" />
                 </concat>
                 <concat destfile="${project.build.directory}/generated-site/markdown/datamodel.md">
                   <filelist dir="${project.basedir}/src/main/markdown/datamodel" files="datamodel_header.md,datamodel_primitive_common.md,datamodel_primitive_delta.md,datamodel_incomplete.md,datamodel_composite.md" />
diff --git a/asterixdb/asterix-doc/src/main/markdown/builtins/11_type.md b/asterixdb/asterix-doc/src/main/markdown/builtins/11_type.md
deleted file mode 100644
index 72291a6..0000000
--- a/asterixdb/asterix-doc/src/main/markdown/builtins/11_type.md
+++ /dev/null
@@ -1,1110 +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.
- !-->
-
-## <a id="TypeFunctions">Type Functions</a> ##
-
-### get_type ###
- * Syntax:
-
-        get_type(expr)
-
- * Returns a string describing the type of the given `expr`. This includes incomplete information types (i.e. `missing` and `null`).
- * Arguments:
-    * `expr` : an expression (any type is allowed).
-
- * Example:
-
-        {
-          "a": get_type(true),
-          "b": get_type(false),
-          "c": get_type(null),
-          "d": get_type(missing),
-          "e": get_type("d"),
-          "f": gettype(4.0),
-          "g": gettype(5),
-          "h": gettype(["1", 2]),
-          "i": gettype({"a":1})
-        };
-
-
- * The expected result is:
-
-        { "a": "boolean", "b": "boolean", "c": "null", "d": "missing", "e": "string", "f": "double", "g": "bigint", "h": "array", "i": "object" }
-        
- The function has an alias `gettype`.
-
-### is_array ###
- * Syntax:
-
-        is_array(expr)
-
- * Checks whether the given expression is evaluated to be an `array` value.
- * Arguments:
-    * `expr` : an expression (any type is allowed).
- * Return Value:
-    * a `boolean` on whether the argument is an `array` value or not,
-    * a `missing` if the argument is a `missing` value,
-    * a `null` if the argument is a `null` value.
-
- * Example:
-
-        {
-          "a": is_array(true),
-          "b": is_array(false),
-          "c": isarray(null),
-          "d": isarray(missing),
-          "e": isarray("d"),
-          "f": isarray(4.0),
-          "g": isarray(5),
-          "h": isarray(["1", 2]),
-          "i": isarray({"a":1})
-        };
-
-
- * The expected result is:
-
-        { "a": false, "b": false, "c": null, "e": false, "f": false, "g": false, "h": true, "i": false }
-
- The function has an alias `isarray`.
-
-### is_multiset ###
- * Syntax:
-
-        is_multiset(expr)
-
- * Checks whether the given expression is evaluated to be an `multiset` value.
- * Arguments:
-    * `expr` : an expression (any type is allowed).
- * Return Value:
-    * a `boolean` on whether the argument is an `multiset` value or not,
-    * a `missing` if the argument is a `missing` value,
-    * a `null` if the argument is a `null` value.
-
- * Example:
-
-        {
-          "a": is_multiset(true),
-          "b": is_multiset(false),
-          "c": is_multiset(null),
-          "d": is_multiset(missing),
-          "e": is_multiset("d"),
-          "f": ismultiset(4.0),
-          "g": ismultiset(["1", 2]),
-          "h": ismultiset({"a":1}),
-          "i": ismultiset({{"hello", 9328, "world", [1, 2, null]}})
-        };
-
-
- * The expected result is:
-
-        { "a": false, "b": false, "c": null, "e": false, "f": false, "g": false, "h": false, "i": true }
-
- The function has an alias `ismultiset`.
-
-### is_atomic (is_atom) ###
- * Syntax:
-
-        is_atomic(expr)
-
- * Checks whether the given expression is evaluated to be a value of a [primitive](../datamodel.html#PrimitiveTypes) type.
- * Arguments:
-    * `expr` : an expression (any type is allowed).
- * Return Value:
-    * a `boolean` on whether the argument is a primitive type or not,
-    * a `missing` if the argument is a `missing` value,
-    * a `null` if the argument is a `null` value.
-
- * Example:
-
-        {
-          "a": is_atomic(true),
-          "b": is_atomic(false),
-          "c": isatomic(null),
-          "d": isatomic(missing),
-          "e": isatomic("d"),
-          "f": isatom(4.0),
-          "g": isatom(5),
-          "h": isatom(["1", 2]),
-          "i": isatom({"a":1})
-        };
-
-* The expected result is:
-
-        { "a": true, "b": true, "c": null, "e": true, "f": true, "g": true, "h": false, "i": false }
-
- The function has three aliases: `isatomic`, `is_atom`, and `isatom`.
-
-### is_boolean (is_bool) ###
- * Syntax:
-
-        is_boolean(expr)
-
- * Checks whether the given expression is evaluated to be a `boolean` value.
- * Arguments:
-    * `expr` : an expression (any type is allowed).
- * Return Value:
-    * a `boolean` on whether the argument is a `boolean` value or not,
-    * a `missing` if the argument is a `missing` value,
-    * a `null` if the argument is a `null` value.
-
- * Example:
-
-        {
-          "a": isboolean(true),
-          "b": isboolean(false),
-          "c": is_boolean(null),
-          "d": is_boolean(missing),
-          "e": isbool("d"),
-          "f": isbool(4.0),
-          "g": isbool(5),
-          "h": isbool(["1", 2]),
-          "i": isbool({"a":1})
-        };
-
-
- * The expected result is:
-
-        { "a": true, "b": true, "c": null, "e": false, "f": false, "g": false, "h": false, "i": false }
-
- The function has three aliases: `isboolean`, `is_bool`, and `isbool`.
-
-
-### is_binary (is_bin) ###
- * Syntax:
-
-        is_binary(expr)
-
- * Checks whether the given expression is evaluated to be a `binary` value.
- * Arguments:
-    * `expr` : an expression (any type is allowed).
- * Return Value:
-    * a `boolean` on whether the argument is a `binary` value or not,
-    * a `missing` if the argument is a `missing` value,
-    * a `null` if the argument is a `null` value.
-
- * Example:
-
-        {
-          "a": is_binary(true),
-          "b": is_binary(false),
-          "c": isbinary(null),
-          "d": isbinary(missing),
-          "e": isbin(point("1,2")),
-          "f": isbin(hex("ABCDEF0123456789")),
-          "g": is_bin(sub_binary(hex("AABBCCDD"), 4)),
-          "h": is_bin(2),
-          "i": is_bin({"a":1})
-        };
-
-
- * The expected result is:
-
-        { "a": false, "b": false, "c": null, "e": false, "f": true, "g": true, "h": false, "i": false }
-
- The function has three aliases: `isbinary`, `is_bin`, and `isbin`.
-
-### is_number (is_num) ###
- * Syntax:
-
-        is_number(expr)
-
- * Checks whether the given expression is evaluated to be a numeric value.
- * Arguments:
-    * `expr` : an expression (any type is allowed).
- * Return Value:
-    * a `boolean` on whether the argument is a `smallint`/`tinyint`/`integer`/`bigint`/`float`/`double`
-      value or not,
-    * a `missing` if the argument is a `missing` value,
-    * a `null` if the argument is a `null` value.
-
- * Example:
-
-        {
-          "a": is_number(true),
-          "b": is_number(false),
-          "c": isnumber(null),
-          "d": isnumber(missing),
-          "e": isnumber("d"),
-          "f": isnum(4.0),
-          "g": isnum(5),
-          "h": isnum(["1", 2]),
-          "i": isnum({"a":1})
-        };
-
-
- * The expected result is:
-
-        { "a": false, "b": false, "c": null, "e": false, "f": true, "g": true, "h": false, "i": false }
-
- The function has three aliases: `isnumber`, `is_num`, and `isnum`.
-
-### is_point ###
- * Syntax:
-
-        is_point(expr)
-
- * Checks whether the given expression is evaluated to be a `point` value.
- * Arguments:
-    * `expr` : an expression (any type is allowed).
- * Return Value:
-    * a `boolean` on whether the argument is a `point` value or not,
-    * a `missing` if the argument is a `missing` value,
-    * a `null` if the argument is a `null` value.
-
- * Example:
-
-        {
-          "a": is_point(true),
-          "b": is_point(false),
-          "c": is_point(null),
-          "d": is_point(missing),
-          "e": is_point(point("1,2")),
-          "f": ispoint(line("30.0,70.0 50.0,90.0")),
-          "g": ispoint(rectangle("30.0,70.0 50.0,90.0")),
-          "h": ispoint(circle("30.0,70.0 5.0")),
-          "i": ispoint(polygon("1.0,1.0 2.0,2.0 3.0,3.0 4.0,4.0")),
-          "j": ispoint(3)
-        };
-
-
- * The expected result is:
-
-        { "a": false, "b": false, "c": null, "e": true, "f": false, "g": false, "h": false, "i": false, "j": false }
-
- The function has an alias `ispoint`.
-
-### is_line ###
- * Syntax:
-
-        is_line(expr)
-
- * Checks whether the given expression is evaluated to be a `line` value.
- * Arguments:
-    * `expr` : an expression (any type is allowed).
- * Return Value:
-    * a `boolean` on whether the argument is a `line` value or not,
-    * a `missing` if the argument is a `missing` value,
-    * a `null` if the argument is a `null` value.
-
- * Example:
-
-        {
-          "a": is_line(true),
-          "b": is_line(false),
-          "c": is_line(null),
-          "d": is_line(missing),
-          "e": is_line(point("1,2")),
-          "f": isline(line("30.0,70.0 50.0,90.0")),
-          "g": isline(rectangle("30.0,70.0 50.0,90.0")),
-          "h": isline(circle("30.0,70.0 5.0")),
-          "i": isline(polygon("1.0,1.0 2.0,2.0 3.0,3.0 4.0,4.0")),
-          "j": isline(3)
-        };
-
-
- * The expected result is:
-
-        { "a": false, "b": false, "c": null, "e": false, "f": true, "g": false, "h": false, "i": false, "j": false }
-
- The function has an alias `isline`.
- 
-### is_rectangle ###
- * Syntax:
-
-        is_rectangle(expr)
-
- * Checks whether the given expression is evaluated to be a `rectangle` value.
- * Arguments:
-    * `expr` : an expression (any type is allowed).
- * Return Value:
-    * a `boolean` on whether the argument is a `rectangle` value or not,
-    * a `missing` if the argument is a `missing` value,
-    * a `null` if the argument is a `null` value.
-
- * Example:
-
-        {
-          "a": is_rectangle(true),
-          "b": is_rectangle(false),
-          "c": is_rectangle(null),
-          "d": is_rectangle(missing),
-          "e": is_rectangle(point("1,2")),
-          "f": isrectangle(line("30.0,70.0 50.0,90.0")),
-          "g": isrectangle(rectangle("30.0,70.0 50.0,90.0")),
-          "h": isrectangle(circle("30.0,70.0 5.0")),
-          "i": isrectangle(polygon("1.0,1.0 2.0,2.0 3.0,3.0 4.0,4.0")),
-          "j": isrectangle(3)
-        };
-
-
- * The expected result is:
-
-        { "a": false, "b": false, "c": null, "e": false, "f": false, "g": true, "h": false, "i": false, "j": false }
-
- The function has an alias `isrectangle`.
- 
-### is_circle ###
- * Syntax:
-
-        is_circle(expr)
-
- * Checks whether the given expression is evaluated to be a `circle` value.
- * Arguments:
-    * `expr` : an expression (any type is allowed).
- * Return Value:
-    * a `boolean` on whether the argument is a `circle` value or not,
-    * a `missing` if the argument is a `missing` value,
-    * a `null` if the argument is a `null` value.
-
- * Example:
-
-        {
-          "a": is_circle(true),
-          "b": is_circle(false),
-          "c": is_circle(null),
-          "d": is_circle(missing),
-          "e": is_circle(point("1,2")),
-          "f": iscircle(line("30.0,70.0 50.0,90.0")),
-          "g": iscircle(rectangle("30.0,70.0 50.0,90.0")),
-          "h": iscircle(circle("30.0,70.0 5.0")),
-          "i": iscircle(polygon("1.0,1.0 2.0,2.0 3.0,3.0 4.0,4.0")),
-          "j": iscircle(3)
-        };
-
-
- * The expected result is:
-
-        { "a": false, "b": false, "c": null, "e": false, "f": false, "g": false, "h": true, "i": false, "j": false }
-
- The function has an alias `iscircle`.
- 
-### is_polygon ###
- * Syntax:
-
-        is_polygon(expr)
-
- * Checks whether the given expression is evaluated to be a `polygon` value.
- * Arguments:
-    * `expr` : an expression (any type is allowed).
- * Return Value:
-    * a `boolean` on whether the argument is a `polygon` value or not,
-    * a `missing` if the argument is a `missing` value,
-    * a `null` if the argument is a `null` value.
-
- * Example:
-
-        {
-          "a": is_polygon(true),
-          "b": is_polygon(false),
-          "c": is_polygon(null),
-          "d": is_polygon(missing),
-          "e": is_polygon(point("1,2")),
-          "f": ispolygon(line("30.0,70.0 50.0,90.0")),
-          "g": ispolygon(rectangle("30.0,70.0 50.0,90.0")),
-          "h": ispolygon(circle("30.0,70.0 5.0")),
-          "i": ispolygon(polygon("1.0,1.0 2.0,2.0 3.0,3.0 4.0,4.0")),
-          "j": ispolygon(3)
-        };
-
-
- * The expected result is:
-
-        { "a": false, "b": false, "c": null, "e": false, "f": false, "g": false, "h": false, "i": true, "j": false }
-
- The function has an alias `ispolygon`.
- 
-### is_spatial ###
- * Syntax:
-
-        is_spatial(expr)
-
- * Checks whether the given expression is evaluated to be a spatial value.
- * Arguments:
-    * `expr` : an expression (any type is allowed).
- * Return Value:
-    * a `boolean` on whether the argument is a `point`/`line`/`rectangle`/`circle`/`polygon` value or not,
-    * a `missing` if the argument is a `missing` value,
-    * a `null` if the argument is a `null` value.
-
- * Example:
-
-        {
-          "a": is_spatial(true),
-          "b": is_spatial(false),
-          "c": is_spatial(null),
-          "d": is_spatial(missing),
-          "e": is_spatial(point("1,2")),
-          "f": isspatial(line("30.0,70.0 50.0,90.0")),
-          "g": isspatial(rectangle("30.0,70.0 50.0,90.0")),
-          "h": isspatial(circle("30.0,70.0 5.0")),
-          "i": isspatial(polygon("1.0,1.0 2.0,2.0 3.0,3.0 4.0,4.0")),
-          "j": isspatial(3)
-        };
-
-
- * The expected result is:
-
-        { "a": false, "b": false, "c": null, "e": true, "f": true, "g": true, "h": true, "i": true, "j": false }
-
- The function has an alias `isspatial`.
- 
-### is_date ###
- * Syntax:
-
-        is_date(expr)
-
- * Checks whether the given expression is evaluated to be a `date` value.
- * Arguments:
-    * `expr` : an expression (any type is allowed).
- * Return Value:
-    * a `boolean` on whether the argument is a `date` value or not,
-    * a `missing` if the argument is a `missing` value,
-    * a `null` if the argument is a `null` value.
-
- * Example:
-
-        {
-          "a": is_date(true),
-          "b": is_date(false),
-          "c": is_date(null),
-          "d": is_date(missing),
-          "e": is_date(date("-19700101")),
-          "f": isdate(date("2013-01-01")),
-          "g": isdate(time("12:12:12.039Z")),
-          "h": isdate(datetime("2013-01-01T12:12:12.039Z")),
-          "i": isdate(duration("P100Y12MT12M")),
-          "j": isdate(interval(date("2013-01-01"), date("20130505"))),
-          "k": isdate(3)
-        };
-
-
- * The expected result is:
-
-        { "a": false, "b": false, "c": null, "e": true, "f": true, "g": false, "h": false, "i": false, "j": false, "k": false }
-
- The function has an alias `isdate`.
- 
-### is_datetime (is_timestamp) ###
- * Syntax:
-
-        is_datetime(expr)
-
- * Checks whether the given expression is evaluated to be a `datetime` value.
- * Arguments:
-    * `expr` : an expression (any type is allowed).
- * Return Value:
-    * a `boolean` on whether the argument is a `datetime` value or not,
-    * a `missing` if the argument is a `missing` value,
-    * a `null` if the argument is a `null` value.
-
- * Example:
-
-        {
-          "a": is_datetime(true),
-          "b": is_datetime(false),
-          "c": is_datetime(null),
-          "d": is_datetime(missing),
-          "e": is_datetime(datetime("2016-02-02T12:09:22.023Z")),
-          "f": isdatetime(datetime("2011-03-03T12:10:42.011Z")),
-          "g": isdatetime(time("12:12:12.039Z")),
-          "h": is_timestamp(datetime("2013-01-01T12:12:12.039Z")),
-          "i": is_timestamp(duration("P100Y12MT12M")),
-          "j": istimestamp(interval(date("2013-01-01"), date("20130505"))),
-          "k": istimestamp(3)
-        };
-
-
- * The expected result is:
-
-        { "a": false, "b": false, "c": null, "e": true, "f": true, "g": false, "h": true, "i": false, "j": false, "k": false }
-
- The function has three aliases: `isdatetime`, `is_timestamp`, and `istimestamp`.
- 
-### is_time ###
- * Syntax:
-
-        is_time(expr)
-
- * Checks whether the given expression is evaluated to be a `time` value.
- * Arguments:
-    * `expr` : an expression (any type is allowed).
- * Return Value:
-    * a `boolean` on whether the argument is a `time` value or not,
-    * a `missing` if the argument is a `missing` value,
-    * a `null` if the argument is a `null` value.
-
- * Example:
-
-         {
-          "a": is_time(true),
-          "b": is_time(false),
-          "c": is_time(null),
-          "d": is_time(missing),
-          "e": is_time(time("08:00:00.000Z")),
-          "f": istime(date("2013-01-01")),
-          "g": istime(time("12:12:12.039Z")),
-          "h": istime(datetime("2013-01-01T12:12:12.039Z")),
-          "i": istime(duration("P100Y12MT12M")),
-          "j": istime(interval(date("2013-01-01"), date("20130505"))),
-          "k": istime(3)
-        };
-
-
- * The expected result is:
-
-        { "a": false, "b": false, "c": null, "e": true, "f": false, "g": true, "h": false, "i": false, "j": false, "k": false }
-
- The function has an alias `istime`.
- 
-### is_duration ###
- * Syntax:
-
-        is_duration(expr)
-
- * Checks whether the given expression is evaluated to be a duration value.
- * Arguments:
-    * `expr` : an expression (any type is allowed).
- * Return Value:
-    * a `boolean` on whether the argument is a `duration/year_month_duration/day_time_duration` value or not,
-    * a `missing` if the argument is a `missing` value,
-    * a `null` if the argument is a `null` value.
-
- * Example:
-
-         {
-          "a": is_duration(true),
-          "b": is_duration(false),
-          "c": is_duration(null),
-          "d": is_duration(missing),
-          "e": is_duration(duration("-PT20.943S")),
-          "f": isduration(date("2013-01-01")),
-          "g": isduration(time("12:12:12.039Z")),
-          "h": isduration(datetime("2013-01-01T12:12:12.039Z")),
-          "i": isduration(duration("P100Y12MT12M")),
-          "j": isduration(interval(date("2013-01-01"), date("20130505"))),
-          "k": isduration(3)
-        };
-
-
- * The expected result is:
-
-        { "a": false, "b": false, "c": null, "e": true, "f": false, "g": false, "h": false, "i": true, "j": false, "k": false }
-
- The function has an alias `isduration`.
- 
-### is_interval ###
- * Syntax:
-
-        is_interval(expr)
-
- * Checks whether the given expression is evaluated to be a `interval` value.
- * Arguments:
-    * `expr` : an expression (any type is allowed).
- * Return Value:
-    * a `boolean` on whether the argument is a `interval` value or not,
-    * a `missing` if the argument is a `missing` value,
-    * a `null` if the argument is a `null` value.
-
- * Example:
-
-         {
-          "a": is_interval(true),
-          "b": is_interval(false),
-          "c": is_interval(null),
-          "d": is_interval(missing),
-          "e": is_interval(interval(datetime("2013-01-01T00:01:01.000Z"), datetime("2013-05-05T13:39:01.049Z"))),
-          "f": isinterval(date("2013-01-01")),
-          "g": isinterval(time("12:12:12.039Z")),
-          "h": isinterval(datetime("2013-01-01T12:12:12.039Z")),
-          "i": isinterval(duration("P100Y12MT12M")),
-          "j": isinterval(interval(date("2013-01-01"), date("20130505"))),
-          "k": isinterval(3)
-        };
-
-
- * The expected result is:
-
-        { "a": false, "b": false, "c": null, "e": true, "f": false, "g": false, "h": false, "i": false, "j": true, "k": false }
-
- The function has an alias `isinterval`.
- 
-### is_temporal ###
- * Syntax:
-
-        is_temporal(expr)
-
- * Checks whether the given expression is evaluated to be a temporal value.
- * Arguments:
-    * `expr` : an expression (any type is allowed).
- * Return Value:
-    * a `boolean` on whether the argument is a `date/datetime/time/duration/year_month_duration/day_time_duration/interval` value or not,
-    * a `missing` if the argument is a `missing` value,
-    * a `null` if the argument is a `null` value.
-
- * Example:
-
-         {
-          "a": is_temporal(true),
-          "b": is_temporal(false),
-          "c": is_temporal(null),
-          "d": is_temporal(missing),
-          "e": is_temporal(duration("-PT20.943S")),
-          "f": istemporal(date("2013-01-01")),
-          "g": istemporal(time("12:12:12.039Z")),
-          "h": istemporal(datetime("2013-01-01T12:12:12.039Z")),
-          "i": istemporal(duration("P100Y12MT12M")),
-          "j": istemporal(interval(date("2013-01-01"), date("20130505"))),
-          "k": istemporal(3)
-        };
-
-
- * The expected result is:
-
-        { "a": false, "b": false, "c": null, "e": true, "f": true, "g": true, "h": true, "i": true, "j": true, "k": false }
-
- The function has an alias `istemporal`.
- 
-### is_object (is_obj) ###
- * Syntax:
-
-        is_object(expr)
-
- * Checks whether the given expression is evaluated to be a `object` value.
- * Arguments:
-    * `expr` : an expression (any type is allowed).
- * Return Value:
-    * a `boolean` on whether the argument is a `object` value or not,
-    * a `missing` if the argument is a `missing` value,
-    * a `null` if the argument is a `null` value.
-
- * Example:
-
-        {
-          "a": is_object(true),
-          "b": is_object(false),
-          "c": isobject(null),
-          "d": isobject(missing),
-          "e": isobj("d"),
-          "f": isobj(4.0),
-          "g": isobj(5),
-          "h": isobj(["1", 2]),
-          "i": isobj({"a":1})
-        };
-
-
- * The expected result is:
-
-       { "a": false, "b": false, "c": null, "e": false, "f": false, "g": false, "h": false, "i": true }
-
- The function has three aliases: `isobject`, `is_obj`, and `isobj`.
-
-
-### is_string (is_str) ###
- * Syntax:
-
-        is_string(expr)
-
- * Checks whether the given expression is evaluated to be a `string` value.
- * Arguments:
-    * `expr` : an expression (any type is allowed).
- * Return Value:
-    * a `boolean` on whether the argument is a `string` value or not,
-    * a `missing` if the argument is a `missing` value,
-    * a `null` if the argument is a `null` value.
-
- * Example:
-
-        {
-          "a": is_string(true),
-          "b": isstring(false),
-          "c": isstring(null),
-          "d": isstr(missing),
-          "e": isstr("d"),
-          "f": isstr(4.0),
-          "g": isstr(5),
-          "h": isstr(["1", 2]),
-          "i": isstr({"a":1})
-        };
-
-
- * The expected result is:
-
-        { "a": false, "b": false, "c": null, "e": true, "f": false, "g": false, "h": false, "i": false }
-
- The function has three aliases: `isstring`, `is_str`, and `isstr`.
-
-### is_uuid ###
- * Syntax:
-
-        is_uuid(expr)
-
- * Checks whether the given expression is evaluated to be a `uuid` value.
- * Arguments:
-    * `expr` : an expression (any type is allowed).
- * Return Value:
-    * a `boolean` on whether the argument is a `uuid` value or not,
-    * a `missing` if the argument is a `missing` value,
-    * a `null` if the argument is a `null` value.
-
- * Example:
-
-         {
-          "a": is_uuid(true),
-          "b": is_uuid(false),
-          "c": is_uuid(null),
-          "d": is_uuid(missing),
-          "e": isuuid(4.0),
-          "f": isuuid(date("2013-01-01")),
-          "g": isuuid(uuid("5c848e5c-6b6a-498f-8452-8847a2957421"))
-        };
-
-
- * The expected result is:
-
-        { "a": false, "b": false, "c": null, "e": false, "f": false, "g": true }
-
- The function has an alias `isuuid`.
-
-
-### is_null ###
- * Syntax:
-
-        is_null(expr)
-
- * Checks whether the given expression is evaluated to be a `null` value.
- * Arguments:
-    * `expr` : an expression (any type is allowed).
- * Return Value:
-    * a `boolean` on whether the variable is a `null` or not,
-    * a `missing` if the input is `missing`.
-
- * Example:
-
-        { "v1": is_null(null), "v2": is_null(1), "v3": is_null(missing) };
-
-
- * The expected result is:
-
-        { "v1": true, "v2": false }
-
- The function has an alias `isnull`.
-
-### is_missing ###
- * Syntax:
-
-        is_missing(expr)
-
- * Checks whether the given expression is evaluated to be a `missing` value.
- * Arguments:
-    * `expr` : an expression (any type is allowed).
- * Return Value:
-    * a `boolean` on whether the variable is a `missing` or not.
-
- * Example:
-
-        { "v1": is_missing(null), "v2": is_missing(1), "v3": is_missing(missing) };
-
-
- * The expected result is:
-
-        { "v1": false, "v2": false, "v3": true }
-
- The function has an alias `ismissing`.
-
-### is_unknown ###
- * Syntax:
-
-        is_unknown(expr)
-
- * Checks whether the given variable is a `null` value or a `missing` value.
- * Arguments:
-    * `expr` : an expression (any type is allowed).
- * Return Value:
-    * a `boolean` on whether the variable is a `null`/``missing` value (`true`) or not (`false`).
-
- * Example:
-
-        { "v1": is_unknown(null), "v2": is_unknown(1), "v3": is_unknown(missing) };
-
-
- * The expected result is:
-
-        { "v1": true, "v2": false, "v3": true }
-
- The function has an alias `isunknown`.
-
-### to_array ###
-  * Syntax:
-
-        to_array(expr)
-
-  * Converts input value to an `array` value
-  * Arguments:
-     * `expr` : an expression
-  * Return Value:
-     * if the argument is `missing` then `missing` is returned
-     * if the argument is `null` then `null` is returned
-     * if the argument is of `array` type then it is returned as is
-     * if the argument is of `multiset` type then it is returned as an `array` with elements in an undefined order
-     * otherwise an `array` containing the input expression as its single item is returned
-
- * Example:
-
-        {
-          "v1": to_array("asterix"),
-          "v2": to_array(["asterix"]),
-        };
-
- * The expected result is:
-
-        { "v1": ["asterix"], "v2": ["asterix"] }
-
- The function has an alias `toarray`.
-
-### to_atomic (to_atom) ###
-  * Syntax:
-
-        to_atomic(expr)
-
-  * Converts input value to a [primitive](../datamodel.html#PrimitiveTypes) value
-  * Arguments:
-     * `expr` : an expression
-  * Return Value:
-     * if the argument is `missing` then `missing` is returned
-     * if the argument is `null` then `null` is returned
-     * if the argument is of primitive type then it is returned as is
-     * if the argument is of `array` or `multiset` type and has only one element then the result of invoking
-       to_atomic() on that element is returned
-     * if the argument is of `object` type and has only one field then the result of invoking to_atomic() on the
-       value of that field is returned
-     * otherwise `null` is returned
-
- * Example:
-
-        {
-          "v1": to_atomic("asterix"),
-          "v2": to_atomic(["asterix"]),
-          "v3": to_atomic([0, 1]),
-          "v4": to_atomic({"value": "asterix"}),
-          "v5": to_number({"x": 1, "y": 2})
-        };
-
- * The expected result is:
-
-        { "v1": "asterix", "v2": "asterix", "v3": null, "v4": "asterix", "v5": null }
-
- The function has three aliases: `toatomic`, `to_atom`, and `toatom`.
-
-### to_boolean (to_bool) ###
-  * Syntax:
-
-        to_boolean(expr)
-
-  * Converts input value to a `boolean` value
-  * Arguments:
-     * `expr` : an expression
-  * Return Value:
-     * if the argument is `missing` then `missing` is returned
-     * if the argument is `null` then `null` is returned
-     * if the argument is of `boolean` type then it is returned as is
-     * if the argument is of numeric type then `false` is returned if it is `0` or `NaN`, otherwise `true`
-     * if the argument is of `string` type then `false` is returned if it's empty, otherwise `true`
-     * if the argument is of `array` or `multiset` type then `false` is returned if it's size is `0`, otherwise `true`
-     * if the argument is of `object` type then `false` is returned if it has no fields, otherwise `true`
-     * type error is raised for all other input types
-
- * Example:
-
-        {
-          "v1": to_boolean(0),
-          "v2": to_boolean(1),
-          "v3": to_boolean(""),
-          "v4": to_boolean("asterix")
-        };
-
- * The expected result is:
-
-        { "v1": false, "v2": true, "v3": false, "v4": true }
-
- The function has three aliases: `toboolean`, `to_bool`, and `tobool`.
-
-### to_bigint ###
-  * Syntax:
-
-        to_bigint(expr)
-
-  * Converts input value to an integer value
-  * Arguments:
-     * `expr` : an expression
-  * Return Value:
-     * if the argument is `missing` then `missing` is returned
-     * if the argument is `null` then `null` is returned
-     * if the argument is of `boolean` type then `1` is returned if it is `true`, `0` if it is `false`
-     * if the argument is of numeric integer type then it is returned as the same value of `bigint` type
-     * if the argument is of numeric `float`/`double` type then it is converted to `bigint` type
-     * if the argument is of `string` type and can be parsed as integer then that integer value is returned,
-       otherwise `null` is returned
-     * if the argument is of `array`/`multiset`/`object` type then `null` is returned
-     * type error is raised for all other input types
-
- * Example:
-
-        {
-          "v1": to_bigint(false),
-          "v2": to_bigint(true),
-          "v3": to_bigint(10),
-          "v4": to_bigint(float("1e100")),
-          "v5": to_bigint(double("1e1000")),
-          "v6": to_bigint("20")
-        };
-
- * The expected result is:
-
-        { "v1": 0, "v2": 1, "v3": 10, "v4": 9223372036854775807, "v5": 9223372036854775807, "v6": 20 }
-
- The function has an alias `tobigint`.
-
-### to_double ###
-  * Syntax:
-
-        to_double(expr)
-
-  * Converts input value to a `double` value
-  * Arguments:
-     * `expr` : an expression
-  * Return Value:
-     * if the argument is `missing` then `missing` is returned
-     * if the argument is `null` then `null` is returned
-     * if the argument is of `boolean` type then `1.0` is returned if it is `true`, `0.0` if it is `false`
-     * if the argument is of numeric type then it is returned as the value of `double` type
-     * if the argument is of `string` type and can be parsed as `double` then that `double` value is returned,
-       otherwise `null` is returned
-     * if the argument is of `array`/`multiset`/`object` type then `null` is returned
-     * type error is raised for all other input types
-
- * Example:
-
-        {
-          "v1": to_double(false),
-          "v2": to_double(true),
-          "v3": to_double(10),
-          "v4": to_double(11.5),
-          "v5": to_double("12.5")
-        };
-
- * The expected result is:
-
-        { "v1": 0.0, "v2": 1.0, "v3": 10.0, "v4": 11.5, "v5": 12.5 }
-
- The function has an alias `todouble`.
-
-### to_number (to_num) ###
-  * Syntax:
-
-        to_number(expr)
-
-  * Converts input value to a numeric value
-  * Arguments:
-     * `expr` : an expression
-  * Return Value:
-     * if the argument is `missing` then `missing` is returned
-     * if the argument is `null` then `null` is returned
-     * if the argument is of numeric type then it is returned as is
-     * if the argument is of `boolean` type then `1` is returned if it is `true`, `0` if it is `false`
-     * if the argument is of `string` type and can be parsed as `bigint` then that `bigint` value is returned,
-       otherwise if it can be parsed as `double` then that `double` value is returned,
-       otherwise `null` is returned
-     * if the argument is of `array`/`multiset`/`object` type then `null` is returned
-     * type error is raised for all other input types
-
- * Example:
-
-        {
-          "v1": to_number(false),
-          "v2": to_number(true),
-          "v3": to_number(10),
-          "v4": to_number(11.5),
-          "v5": to_number("12.5")
-        };
-
- * The expected result is:
-
-        { "v1": 0, "v2": 1, "v3": 10, "v4": 11.5, "v5": 12.5 }
-
- The function has three aliases: `tonumber`, `to_num`, and `tonum`.
-
-### to_object (to_obj) ###
-  * Syntax:
-
-        to_object(expr)
-
-  * Converts input value to an `object` value
-  * Arguments:
-     * `expr` : an expression
-  * Return Value:
-     * if the argument is `missing` then `missing` is returned
-     * if the argument is `null` then `null` is returned
-     * if the argument is of `object` type then it is returned as is
-     * otherwise an empty `object` is returned
-
- * Example:
-
-        {
-          "v1": to_object({"value": "asterix"}),
-          "v2": to_object("asterix")
-        };
-
- * The expected result is:
-
-        { "v1": {"value": "asterix"}, "v2": {} }
-
- The function has three aliases: `toobject`, `to_obj`, and `toobj`.
-
-### to_string (to_str) ###
-  * Syntax:
-
-        to_string(expr)
-
-  * Converts input value to a string value
-  * Arguments:
-     * `expr` : an expression
-  * Return Value:
-     * if the argument is `missing` then `missing` is returned
-     * if the argument is `null` then `null` is returned
-     * if the argument is of `boolean` type then `"true"` is returned if it is `true`, `"false"` if it is `false`
-     * if the argument is of numeric type then its string representation is returned
-     * if the argument is of `string` type then it is returned as is
-     * if the argument is of `array`/`multiset`/`object` type then `null` is returned
-     * type error is raised for all other input types
-
- * Example:
-
-        {
-          "v1": to_string(false),
-          "v2": to_string(true),
-          "v3": to_string(10),
-          "v4": to_string(11.5),
-          "v5": to_string("asterix")
-        };
-
- * The expected result is:
-
-        { "v1": "false", "v2": "true", "v3": "10", "v4": "11.5", "v5": "asterix" }
-
- The function has three aliases: `tostring`, `to_str`, and `tostr`.
diff --git a/asterixdb/asterix-doc/src/main/markdown/builtins/11_type_common.md b/asterixdb/asterix-doc/src/main/markdown/builtins/11_type_common.md
new file mode 100644
index 0000000..5cbef2c
--- /dev/null
+++ b/asterixdb/asterix-doc/src/main/markdown/builtins/11_type_common.md
@@ -0,0 +1,328 @@
+<!--
+ ! 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.
+ !-->
+
+## <a id="TypeFunctions">Type Functions</a> ##
+
+### is_array ###
+ * Syntax:
+
+        is_array(expr)
+
+ * Checks whether the given expression is evaluated to be an `array` value.
+ * Arguments:
+    * `expr` : an expression (any type is allowed).
+ * Return Value:
+    * a `boolean` on whether the argument is an `array` value or not,
+    * a `missing` if the argument is a `missing` value,
+    * a `null` if the argument is a `null` value.
+
+ * Example:
+
+        {
+          "a": is_array(true),
+          "b": is_array(false),
+          "c": isarray(null),
+          "d": isarray(missing),
+          "e": isarray("d"),
+          "f": isarray(4.0),
+          "g": isarray(5),
+          "h": isarray(["1", 2]),
+          "i": isarray({"a":1})
+        };
+
+
+ * The expected result is:
+
+        { "a": false, "b": false, "c": null, "e": false, "f": false, "g": false, "h": true, "i": false }
+
+ The function has an alias `isarray`.
+
+### is_multiset ###
+ * Syntax:
+
+        is_multiset(expr)
+
+ * Checks whether the given expression is evaluated to be an `multiset` value.
+ * Arguments:
+    * `expr` : an expression (any type is allowed).
+ * Return Value:
+    * a `boolean` on whether the argument is an `multiset` value or not,
+    * a `missing` if the argument is a `missing` value,
+    * a `null` if the argument is a `null` value.
+
+ * Example:
+
+        {
+          "a": is_multiset(true),
+          "b": is_multiset(false),
+          "c": is_multiset(null),
+          "d": is_multiset(missing),
+          "e": is_multiset("d"),
+          "f": ismultiset(4.0),
+          "g": ismultiset(["1", 2]),
+          "h": ismultiset({"a":1}),
+          "i": ismultiset({{"hello", 9328, "world", [1, 2, null]}})
+        };
+
+
+ * The expected result is:
+
+        { "a": false, "b": false, "c": null, "e": false, "f": false, "g": false, "h": false, "i": true }
+
+ The function has an alias `ismultiset`.
+
+### is_atomic (is_atom) ###
+ * Syntax:
+
+        is_atomic(expr)
+
+ * Checks whether the given expression is evaluated to be a value of a [primitive](../datamodel.html#PrimitiveTypes) type.
+ * Arguments:
+    * `expr` : an expression (any type is allowed).
+ * Return Value:
+    * a `boolean` on whether the argument is a primitive type or not,
+    * a `missing` if the argument is a `missing` value,
+    * a `null` if the argument is a `null` value.
+
+ * Example:
+
+        {
+          "a": is_atomic(true),
+          "b": is_atomic(false),
+          "c": isatomic(null),
+          "d": isatomic(missing),
+          "e": isatomic("d"),
+          "f": isatom(4.0),
+          "g": isatom(5),
+          "h": isatom(["1", 2]),
+          "i": isatom({"a":1})
+        };
+
+* The expected result is:
+
+        { "a": true, "b": true, "c": null, "e": true, "f": true, "g": true, "h": false, "i": false }
+
+ The function has three aliases: `isatomic`, `is_atom`, and `isatom`.
+
+### is_boolean (is_bool) ###
+ * Syntax:
+
+        is_boolean(expr)
+
+ * Checks whether the given expression is evaluated to be a `boolean` value.
+ * Arguments:
+    * `expr` : an expression (any type is allowed).
+ * Return Value:
+    * a `boolean` on whether the argument is a `boolean` value or not,
+    * a `missing` if the argument is a `missing` value,
+    * a `null` if the argument is a `null` value.
+
+ * Example:
+
+        {
+          "a": isboolean(true),
+          "b": isboolean(false),
+          "c": is_boolean(null),
+          "d": is_boolean(missing),
+          "e": isbool("d"),
+          "f": isbool(4.0),
+          "g": isbool(5),
+          "h": isbool(["1", 2]),
+          "i": isbool({"a":1})
+        };
+
+
+ * The expected result is:
+
+        { "a": true, "b": true, "c": null, "e": false, "f": false, "g": false, "h": false, "i": false }
+
+ The function has three aliases: `isboolean`, `is_bool`, and `isbool`.
+
+
+### is_number (is_num) ###
+ * Syntax:
+
+        is_number(expr)
+
+ * Checks whether the given expression is evaluated to be a numeric value.
+ * Arguments:
+    * `expr` : an expression (any type is allowed).
+ * Return Value:
+    * a `boolean` on whether the argument is a `smallint`/`tinyint`/`integer`/`bigint`/`float`/`double`
+      value or not,
+    * a `missing` if the argument is a `missing` value,
+    * a `null` if the argument is a `null` value.
+
+ * Example:
+
+        {
+          "a": is_number(true),
+          "b": is_number(false),
+          "c": isnumber(null),
+          "d": isnumber(missing),
+          "e": isnumber("d"),
+          "f": isnum(4.0),
+          "g": isnum(5),
+          "h": isnum(["1", 2]),
+          "i": isnum({"a":1})
+        };
+
+
+ * The expected result is:
+
+        { "a": false, "b": false, "c": null, "e": false, "f": true, "g": true, "h": false, "i": false }
+
+ The function has three aliases: `isnumber`, `is_num`, and `isnum`.
+
+### is_object (is_obj) ###
+ * Syntax:
+
+        is_object(expr)
+
+ * Checks whether the given expression is evaluated to be a `object` value.
+ * Arguments:
+    * `expr` : an expression (any type is allowed).
+ * Return Value:
+    * a `boolean` on whether the argument is a `object` value or not,
+    * a `missing` if the argument is a `missing` value,
+    * a `null` if the argument is a `null` value.
+
+ * Example:
+
+        {
+          "a": is_object(true),
+          "b": is_object(false),
+          "c": isobject(null),
+          "d": isobject(missing),
+          "e": isobj("d"),
+          "f": isobj(4.0),
+          "g": isobj(5),
+          "h": isobj(["1", 2]),
+          "i": isobj({"a":1})
+        };
+
+
+ * The expected result is:
+
+       { "a": false, "b": false, "c": null, "e": false, "f": false, "g": false, "h": false, "i": true }
+
+ The function has three aliases: `isobject`, `is_obj`, and `isobj`.
+
+
+### is_string (is_str) ###
+ * Syntax:
+
+        is_string(expr)
+
+ * Checks whether the given expression is evaluated to be a `string` value.
+ * Arguments:
+    * `expr` : an expression (any type is allowed).
+ * Return Value:
+    * a `boolean` on whether the argument is a `string` value or not,
+    * a `missing` if the argument is a `missing` value,
+    * a `null` if the argument is a `null` value.
+
+ * Example:
+
+        {
+          "a": is_string(true),
+          "b": isstring(false),
+          "c": isstring(null),
+          "d": isstr(missing),
+          "e": isstr("d"),
+          "f": isstr(4.0),
+          "g": isstr(5),
+          "h": isstr(["1", 2]),
+          "i": isstr({"a":1})
+        };
+
+
+ * The expected result is:
+
+        { "a": false, "b": false, "c": null, "e": true, "f": false, "g": false, "h": false, "i": false }
+
+ The function has three aliases: `isstring`, `is_str`, and `isstr`.
+
+### is_null ###
+ * Syntax:
+
+        is_null(expr)
+
+ * Checks whether the given expression is evaluated to be a `null` value.
+ * Arguments:
+    * `expr` : an expression (any type is allowed).
+ * Return Value:
+    * a `boolean` on whether the variable is a `null` or not,
+    * a `missing` if the input is `missing`.
+
+ * Example:
+
+        { "v1": is_null(null), "v2": is_null(1), "v3": is_null(missing) };
+
+
+ * The expected result is:
+
+        { "v1": true, "v2": false }
+
+ The function has an alias `isnull`.
+
+### is_missing ###
+ * Syntax:
+
+        is_missing(expr)
+
+ * Checks whether the given expression is evaluated to be a `missing` value.
+ * Arguments:
+    * `expr` : an expression (any type is allowed).
+ * Return Value:
+    * a `boolean` on whether the variable is a `missing` or not.
+
+ * Example:
+
+        { "v1": is_missing(null), "v2": is_missing(1), "v3": is_missing(missing) };
+
+
+ * The expected result is:
+
+        { "v1": false, "v2": false, "v3": true }
+
+ The function has an alias `ismissing`.
+
+### is_unknown ###
+ * Syntax:
+
+        is_unknown(expr)
+
+ * Checks whether the given variable is a `null` value or a `missing` value.
+ * Arguments:
+    * `expr` : an expression (any type is allowed).
+ * Return Value:
+    * a `boolean` on whether the variable is a `null`/``missing` value (`true`) or not (`false`).
+
+ * Example:
+
+        { "v1": is_unknown(null), "v2": is_unknown(1), "v3": is_unknown(missing) };
+
+
+ * The expected result is:
+
+        { "v1": true, "v2": false, "v3": true }
+
+ The function has an alias `isunknown`.
+
diff --git a/asterixdb/asterix-doc/src/main/markdown/builtins/11_type_conversion.md b/asterixdb/asterix-doc/src/main/markdown/builtins/11_type_conversion.md
new file mode 100644
index 0000000..70195ec
--- /dev/null
+++ b/asterixdb/asterix-doc/src/main/markdown/builtins/11_type_conversion.md
@@ -0,0 +1,279 @@
+<!--
+ ! 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.
+ !-->
+
+### to_array ###
+  * Syntax:
+
+        to_array(expr)
+
+  * Converts input value to an `array` value
+  * Arguments:
+     * `expr` : an expression
+  * Return Value:
+     * if the argument is `missing` then `missing` is returned
+     * if the argument is `null` then `null` is returned
+     * if the argument is of `array` type then it is returned as is
+     * if the argument is of `multiset` type then it is returned as an `array` with elements in an undefined order
+     * otherwise an `array` containing the input expression as its single item is returned
+
+ * Example:
+
+        {
+          "v1": to_array("asterix"),
+          "v2": to_array(["asterix"]),
+        };
+
+ * The expected result is:
+
+        { "v1": ["asterix"], "v2": ["asterix"] }
+
+ The function has an alias `toarray`.
+
+### to_atomic (to_atom) ###
+  * Syntax:
+
+        to_atomic(expr)
+
+  * Converts input value to a [primitive](../datamodel.html#PrimitiveTypes) value
+  * Arguments:
+     * `expr` : an expression
+  * Return Value:
+     * if the argument is `missing` then `missing` is returned
+     * if the argument is `null` then `null` is returned
+     * if the argument is of primitive type then it is returned as is
+     * if the argument is of `array` or `multiset` type and has only one element then the result of invoking
+       to_atomic() on that element is returned
+     * if the argument is of `object` type and has only one field then the result of invoking to_atomic() on the
+       value of that field is returned
+     * otherwise `null` is returned
+
+ * Example:
+
+        {
+          "v1": to_atomic("asterix"),
+          "v2": to_atomic(["asterix"]),
+          "v3": to_atomic([0, 1]),
+          "v4": to_atomic({"value": "asterix"}),
+          "v5": to_number({"x": 1, "y": 2})
+        };
+
+ * The expected result is:
+
+        { "v1": "asterix", "v2": "asterix", "v3": null, "v4": "asterix", "v5": null }
+
+ The function has three aliases: `toatomic`, `to_atom`, and `toatom`.
+
+### to_boolean (to_bool) ###
+  * Syntax:
+
+        to_boolean(expr)
+
+  * Converts input value to a `boolean` value
+  * Arguments:
+     * `expr` : an expression
+  * Return Value:
+     * if the argument is `missing` then `missing` is returned
+     * if the argument is `null` then `null` is returned
+     * if the argument is of `boolean` type then it is returned as is
+     * if the argument is of numeric type then `false` is returned if it is `0` or `NaN`, otherwise `true`
+     * if the argument is of `string` type then `false` is returned if it's empty, otherwise `true`
+     * if the argument is of `array` or `multiset` type then `false` is returned if it's size is `0`, otherwise `true`
+     * if the argument is of `object` type then `false` is returned if it has no fields, otherwise `true`
+     * type error is raised for all other input types
+
+ * Example:
+
+        {
+          "v1": to_boolean(0),
+          "v2": to_boolean(1),
+          "v3": to_boolean(""),
+          "v4": to_boolean("asterix")
+        };
+
+ * The expected result is:
+
+        { "v1": false, "v2": true, "v3": false, "v4": true }
+
+ The function has three aliases: `toboolean`, `to_bool`, and `tobool`.
+
+### to_bigint ###
+  * Syntax:
+
+        to_bigint(expr)
+
+  * Converts input value to an integer value
+  * Arguments:
+     * `expr` : an expression
+  * Return Value:
+     * if the argument is `missing` then `missing` is returned
+     * if the argument is `null` then `null` is returned
+     * if the argument is of `boolean` type then `1` is returned if it is `true`, `0` if it is `false`
+     * if the argument is of numeric integer type then it is returned as the same value of `bigint` type
+     * if the argument is of numeric `float`/`double` type then it is converted to `bigint` type
+     * if the argument is of `string` type and can be parsed as integer then that integer value is returned,
+       otherwise `null` is returned
+     * if the argument is of `array`/`multiset`/`object` type then `null` is returned
+     * type error is raised for all other input types
+
+ * Example:
+
+        {
+          "v1": to_bigint(false),
+          "v2": to_bigint(true),
+          "v3": to_bigint(10),
+          "v4": to_bigint(float("1e100")),
+          "v5": to_bigint(double("1e1000")),
+          "v6": to_bigint("20")
+        };
+
+ * The expected result is:
+
+        { "v1": 0, "v2": 1, "v3": 10, "v4": 9223372036854775807, "v5": 9223372036854775807, "v6": 20 }
+
+ The function has an alias `tobigint`.
+
+### to_double ###
+  * Syntax:
+
+        to_double(expr)
+
+  * Converts input value to a `double` value
+  * Arguments:
+     * `expr` : an expression
+  * Return Value:
+     * if the argument is `missing` then `missing` is returned
+     * if the argument is `null` then `null` is returned
+     * if the argument is of `boolean` type then `1.0` is returned if it is `true`, `0.0` if it is `false`
+     * if the argument is of numeric type then it is returned as the value of `double` type
+     * if the argument is of `string` type and can be parsed as `double` then that `double` value is returned,
+       otherwise `null` is returned
+     * if the argument is of `array`/`multiset`/`object` type then `null` is returned
+     * type error is raised for all other input types
+
+ * Example:
+
+        {
+          "v1": to_double(false),
+          "v2": to_double(true),
+          "v3": to_double(10),
+          "v4": to_double(11.5),
+          "v5": to_double("12.5")
+        };
+
+ * The expected result is:
+
+        { "v1": 0.0, "v2": 1.0, "v3": 10.0, "v4": 11.5, "v5": 12.5 }
+
+ The function has an alias `todouble`.
+
+### to_number (to_num) ###
+  * Syntax:
+
+        to_number(expr)
+
+  * Converts input value to a numeric value
+  * Arguments:
+     * `expr` : an expression
+  * Return Value:
+     * if the argument is `missing` then `missing` is returned
+     * if the argument is `null` then `null` is returned
+     * if the argument is of numeric type then it is returned as is
+     * if the argument is of `boolean` type then `1` is returned if it is `true`, `0` if it is `false`
+     * if the argument is of `string` type and can be parsed as `bigint` then that `bigint` value is returned,
+       otherwise if it can be parsed as `double` then that `double` value is returned,
+       otherwise `null` is returned
+     * if the argument is of `array`/`multiset`/`object` type then `null` is returned
+     * type error is raised for all other input types
+
+ * Example:
+
+        {
+          "v1": to_number(false),
+          "v2": to_number(true),
+          "v3": to_number(10),
+          "v4": to_number(11.5),
+          "v5": to_number("12.5")
+        };
+
+ * The expected result is:
+
+        { "v1": 0, "v2": 1, "v3": 10, "v4": 11.5, "v5": 12.5 }
+
+ The function has three aliases: `tonumber`, `to_num`, and `tonum`.
+
+### to_object (to_obj) ###
+  * Syntax:
+
+        to_object(expr)
+
+  * Converts input value to an `object` value
+  * Arguments:
+     * `expr` : an expression
+  * Return Value:
+     * if the argument is `missing` then `missing` is returned
+     * if the argument is `null` then `null` is returned
+     * if the argument is of `object` type then it is returned as is
+     * otherwise an empty `object` is returned
+
+ * Example:
+
+        {
+          "v1": to_object({"value": "asterix"}),
+          "v2": to_object("asterix")
+        };
+
+ * The expected result is:
+
+        { "v1": {"value": "asterix"}, "v2": {} }
+
+ The function has three aliases: `toobject`, `to_obj`, and `toobj`.
+
+### to_string (to_str) ###
+  * Syntax:
+
+        to_string(expr)
+
+  * Converts input value to a string value
+  * Arguments:
+     * `expr` : an expression
+  * Return Value:
+     * if the argument is `missing` then `missing` is returned
+     * if the argument is `null` then `null` is returned
+     * if the argument is of `boolean` type then `"true"` is returned if it is `true`, `"false"` if it is `false`
+     * if the argument is of numeric type then its string representation is returned
+     * if the argument is of `string` type then it is returned as is
+     * if the argument is of `array`/`multiset`/`object` type then `null` is returned
+     * type error is raised for all other input types
+
+ * Example:
+
+        {
+          "v1": to_string(false),
+          "v2": to_string(true),
+          "v3": to_string(10),
+          "v4": to_string(11.5),
+          "v5": to_string("asterix")
+        };
+
+ * The expected result is:
+
+        { "v1": "false", "v2": "true", "v3": "10", "v4": "11.5", "v5": "asterix" }
+
+ The function has three aliases: `tostring`, `to_str`, and `tostr`.
+
diff --git a/asterixdb/asterix-doc/src/main/markdown/builtins/11_type_delta.md b/asterixdb/asterix-doc/src/main/markdown/builtins/11_type_delta.md
new file mode 100644
index 0000000..e9b89f8
--- /dev/null
+++ b/asterixdb/asterix-doc/src/main/markdown/builtins/11_type_delta.md
@@ -0,0 +1,541 @@
+<!--
+ ! 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.
+ !-->
+
+### is_binary (is_bin) ###
+ * Syntax:
+
+        is_binary(expr)
+
+ * Checks whether the given expression is evaluated to be a `binary` value.
+ * Arguments:
+    * `expr` : an expression (any type is allowed).
+ * Return Value:
+    * a `boolean` on whether the argument is a `binary` value or not,
+    * a `missing` if the argument is a `missing` value,
+    * a `null` if the argument is a `null` value.
+
+ * Example:
+
+        {
+          "a": is_binary(true),
+          "b": is_binary(false),
+          "c": isbinary(null),
+          "d": isbinary(missing),
+          "e": isbin(point("1,2")),
+          "f": isbin(hex("ABCDEF0123456789")),
+          "g": is_bin(sub_binary(hex("AABBCCDD"), 4)),
+          "h": is_bin(2),
+          "i": is_bin({"a":1})
+        };
+
+
+ * The expected result is:
+
+        { "a": false, "b": false, "c": null, "e": false, "f": true, "g": true, "h": false, "i": false }
+
+ The function has three aliases: `isbinary`, `is_bin`, and `isbin`.
+
+### is_uuid ###
+ * Syntax:
+
+        is_uuid(expr)
+
+ * Checks whether the given expression is evaluated to be a `uuid` value.
+ * Arguments:
+    * `expr` : an expression (any type is allowed).
+ * Return Value:
+    * a `boolean` on whether the argument is a `uuid` value or not,
+    * a `missing` if the argument is a `missing` value,
+    * a `null` if the argument is a `null` value.
+
+ * Example:
+
+         {
+          "a": is_uuid(true),
+          "b": is_uuid(false),
+          "c": is_uuid(null),
+          "d": is_uuid(missing),
+          "e": isuuid(4.0),
+          "f": isuuid(date("2013-01-01")),
+          "g": isuuid(uuid("5c848e5c-6b6a-498f-8452-8847a2957421"))
+        };
+
+
+ * The expected result is:
+
+        { "a": false, "b": false, "c": null, "e": false, "f": false, "g": true }
+
+ The function has an alias `isuuid`.
+
+### is_point ###
+ * Syntax:
+
+        is_point(expr)
+
+ * Checks whether the given expression is evaluated to be a `point` value.
+ * Arguments:
+    * `expr` : an expression (any type is allowed).
+ * Return Value:
+    * a `boolean` on whether the argument is a `point` value or not,
+    * a `missing` if the argument is a `missing` value,
+    * a `null` if the argument is a `null` value.
+
+ * Example:
+
+        {
+          "a": is_point(true),
+          "b": is_point(false),
+          "c": is_point(null),
+          "d": is_point(missing),
+          "e": is_point(point("1,2")),
+          "f": ispoint(line("30.0,70.0 50.0,90.0")),
+          "g": ispoint(rectangle("30.0,70.0 50.0,90.0")),
+          "h": ispoint(circle("30.0,70.0 5.0")),
+          "i": ispoint(polygon("1.0,1.0 2.0,2.0 3.0,3.0 4.0,4.0")),
+          "j": ispoint(3)
+        };
+
+
+ * The expected result is:
+
+        { "a": false, "b": false, "c": null, "e": true, "f": false, "g": false, "h": false, "i": false, "j": false }
+
+ The function has an alias `ispoint`.
+
+### is_line ###
+ * Syntax:
+
+        is_line(expr)
+
+ * Checks whether the given expression is evaluated to be a `line` value.
+ * Arguments:
+    * `expr` : an expression (any type is allowed).
+ * Return Value:
+    * a `boolean` on whether the argument is a `line` value or not,
+    * a `missing` if the argument is a `missing` value,
+    * a `null` if the argument is a `null` value.
+
+ * Example:
+
+        {
+          "a": is_line(true),
+          "b": is_line(false),
+          "c": is_line(null),
+          "d": is_line(missing),
+          "e": is_line(point("1,2")),
+          "f": isline(line("30.0,70.0 50.0,90.0")),
+          "g": isline(rectangle("30.0,70.0 50.0,90.0")),
+          "h": isline(circle("30.0,70.0 5.0")),
+          "i": isline(polygon("1.0,1.0 2.0,2.0 3.0,3.0 4.0,4.0")),
+          "j": isline(3)
+        };
+
+
+ * The expected result is:
+
+        { "a": false, "b": false, "c": null, "e": false, "f": true, "g": false, "h": false, "i": false, "j": false }
+
+ The function has an alias `isline`.
+ 
+### is_rectangle ###
+ * Syntax:
+
+        is_rectangle(expr)
+
+ * Checks whether the given expression is evaluated to be a `rectangle` value.
+ * Arguments:
+    * `expr` : an expression (any type is allowed).
+ * Return Value:
+    * a `boolean` on whether the argument is a `rectangle` value or not,
+    * a `missing` if the argument is a `missing` value,
+    * a `null` if the argument is a `null` value.
+
+ * Example:
+
+        {
+          "a": is_rectangle(true),
+          "b": is_rectangle(false),
+          "c": is_rectangle(null),
+          "d": is_rectangle(missing),
+          "e": is_rectangle(point("1,2")),
+          "f": isrectangle(line("30.0,70.0 50.0,90.0")),
+          "g": isrectangle(rectangle("30.0,70.0 50.0,90.0")),
+          "h": isrectangle(circle("30.0,70.0 5.0")),
+          "i": isrectangle(polygon("1.0,1.0 2.0,2.0 3.0,3.0 4.0,4.0")),
+          "j": isrectangle(3)
+        };
+
+
+ * The expected result is:
+
+        { "a": false, "b": false, "c": null, "e": false, "f": false, "g": true, "h": false, "i": false, "j": false }
+
+ The function has an alias `isrectangle`.
+ 
+### is_circle ###
+ * Syntax:
+
+        is_circle(expr)
+
+ * Checks whether the given expression is evaluated to be a `circle` value.
+ * Arguments:
+    * `expr` : an expression (any type is allowed).
+ * Return Value:
+    * a `boolean` on whether the argument is a `circle` value or not,
+    * a `missing` if the argument is a `missing` value,
+    * a `null` if the argument is a `null` value.
+
+ * Example:
+
+        {
+          "a": is_circle(true),
+          "b": is_circle(false),
+          "c": is_circle(null),
+          "d": is_circle(missing),
+          "e": is_circle(point("1,2")),
+          "f": iscircle(line("30.0,70.0 50.0,90.0")),
+          "g": iscircle(rectangle("30.0,70.0 50.0,90.0")),
+          "h": iscircle(circle("30.0,70.0 5.0")),
+          "i": iscircle(polygon("1.0,1.0 2.0,2.0 3.0,3.0 4.0,4.0")),
+          "j": iscircle(3)
+        };
+
+
+ * The expected result is:
+
+        { "a": false, "b": false, "c": null, "e": false, "f": false, "g": false, "h": true, "i": false, "j": false }
+
+ The function has an alias `iscircle`.
+ 
+### is_polygon ###
+ * Syntax:
+
+        is_polygon(expr)
+
+ * Checks whether the given expression is evaluated to be a `polygon` value.
+ * Arguments:
+    * `expr` : an expression (any type is allowed).
+ * Return Value:
+    * a `boolean` on whether the argument is a `polygon` value or not,
+    * a `missing` if the argument is a `missing` value,
+    * a `null` if the argument is a `null` value.
+
+ * Example:
+
+        {
+          "a": is_polygon(true),
+          "b": is_polygon(false),
+          "c": is_polygon(null),
+          "d": is_polygon(missing),
+          "e": is_polygon(point("1,2")),
+          "f": ispolygon(line("30.0,70.0 50.0,90.0")),
+          "g": ispolygon(rectangle("30.0,70.0 50.0,90.0")),
+          "h": ispolygon(circle("30.0,70.0 5.0")),
+          "i": ispolygon(polygon("1.0,1.0 2.0,2.0 3.0,3.0 4.0,4.0")),
+          "j": ispolygon(3)
+        };
+
+
+ * The expected result is:
+
+        { "a": false, "b": false, "c": null, "e": false, "f": false, "g": false, "h": false, "i": true, "j": false }
+
+ The function has an alias `ispolygon`.
+ 
+### is_spatial ###
+ * Syntax:
+
+        is_spatial(expr)
+
+ * Checks whether the given expression is evaluated to be a spatial value.
+ * Arguments:
+    * `expr` : an expression (any type is allowed).
+ * Return Value:
+    * a `boolean` on whether the argument is a `point`/`line`/`rectangle`/`circle`/`polygon` value or not,
+    * a `missing` if the argument is a `missing` value,
+    * a `null` if the argument is a `null` value.
+
+ * Example:
+
+        {
+          "a": is_spatial(true),
+          "b": is_spatial(false),
+          "c": is_spatial(null),
+          "d": is_spatial(missing),
+          "e": is_spatial(point("1,2")),
+          "f": isspatial(line("30.0,70.0 50.0,90.0")),
+          "g": isspatial(rectangle("30.0,70.0 50.0,90.0")),
+          "h": isspatial(circle("30.0,70.0 5.0")),
+          "i": isspatial(polygon("1.0,1.0 2.0,2.0 3.0,3.0 4.0,4.0")),
+          "j": isspatial(3)
+        };
+
+
+ * The expected result is:
+
+        { "a": false, "b": false, "c": null, "e": true, "f": true, "g": true, "h": true, "i": true, "j": false }
+
+ The function has an alias `isspatial`.
+
+### is_date ###
+ * Syntax:
+
+        is_date(expr)
+
+ * Checks whether the given expression is evaluated to be a `date` value.
+ * Arguments:
+    * `expr` : an expression (any type is allowed).
+ * Return Value:
+    * a `boolean` on whether the argument is a `date` value or not,
+    * a `missing` if the argument is a `missing` value,
+    * a `null` if the argument is a `null` value.
+
+ * Example:
+
+        {
+          "a": is_date(true),
+          "b": is_date(false),
+          "c": is_date(null),
+          "d": is_date(missing),
+          "e": is_date(date("-19700101")),
+          "f": isdate(date("2013-01-01")),
+          "g": isdate(time("12:12:12.039Z")),
+          "h": isdate(datetime("2013-01-01T12:12:12.039Z")),
+          "i": isdate(duration("P100Y12MT12M")),
+          "j": isdate(interval(date("2013-01-01"), date("20130505"))),
+          "k": isdate(3)
+        };
+
+
+ * The expected result is:
+
+        { "a": false, "b": false, "c": null, "e": true, "f": true, "g": false, "h": false, "i": false, "j": false, "k": false }
+
+ The function has an alias `isdate`.
+ 
+### is_datetime (is_timestamp) ###
+ * Syntax:
+
+        is_datetime(expr)
+
+ * Checks whether the given expression is evaluated to be a `datetime` value.
+ * Arguments:
+    * `expr` : an expression (any type is allowed).
+ * Return Value:
+    * a `boolean` on whether the argument is a `datetime` value or not,
+    * a `missing` if the argument is a `missing` value,
+    * a `null` if the argument is a `null` value.
+
+ * Example:
+
+        {
+          "a": is_datetime(true),
+          "b": is_datetime(false),
+          "c": is_datetime(null),
+          "d": is_datetime(missing),
+          "e": is_datetime(datetime("2016-02-02T12:09:22.023Z")),
+          "f": isdatetime(datetime("2011-03-03T12:10:42.011Z")),
+          "g": isdatetime(time("12:12:12.039Z")),
+          "h": is_timestamp(datetime("2013-01-01T12:12:12.039Z")),
+          "i": is_timestamp(duration("P100Y12MT12M")),
+          "j": istimestamp(interval(date("2013-01-01"), date("20130505"))),
+          "k": istimestamp(3)
+        };
+
+
+ * The expected result is:
+
+        { "a": false, "b": false, "c": null, "e": true, "f": true, "g": false, "h": true, "i": false, "j": false, "k": false }
+
+ The function has three aliases: `isdatetime`, `is_timestamp`, and `istimestamp`.
+ 
+### is_time ###
+ * Syntax:
+
+        is_time(expr)
+
+ * Checks whether the given expression is evaluated to be a `time` value.
+ * Arguments:
+    * `expr` : an expression (any type is allowed).
+ * Return Value:
+    * a `boolean` on whether the argument is a `time` value or not,
+    * a `missing` if the argument is a `missing` value,
+    * a `null` if the argument is a `null` value.
+
+ * Example:
+
+         {
+          "a": is_time(true),
+          "b": is_time(false),
+          "c": is_time(null),
+          "d": is_time(missing),
+          "e": is_time(time("08:00:00.000Z")),
+          "f": istime(date("2013-01-01")),
+          "g": istime(time("12:12:12.039Z")),
+          "h": istime(datetime("2013-01-01T12:12:12.039Z")),
+          "i": istime(duration("P100Y12MT12M")),
+          "j": istime(interval(date("2013-01-01"), date("20130505"))),
+          "k": istime(3)
+        };
+
+
+ * The expected result is:
+
+        { "a": false, "b": false, "c": null, "e": true, "f": false, "g": true, "h": false, "i": false, "j": false, "k": false }
+
+ The function has an alias `istime`.
+ 
+### is_duration ###
+ * Syntax:
+
+        is_duration(expr)
+
+ * Checks whether the given expression is evaluated to be a duration value.
+ * Arguments:
+    * `expr` : an expression (any type is allowed).
+ * Return Value:
+    * a `boolean` on whether the argument is a `duration/year_month_duration/day_time_duration` value or not,
+    * a `missing` if the argument is a `missing` value,
+    * a `null` if the argument is a `null` value.
+
+ * Example:
+
+         {
+          "a": is_duration(true),
+          "b": is_duration(false),
+          "c": is_duration(null),
+          "d": is_duration(missing),
+          "e": is_duration(duration("-PT20.943S")),
+          "f": isduration(date("2013-01-01")),
+          "g": isduration(time("12:12:12.039Z")),
+          "h": isduration(datetime("2013-01-01T12:12:12.039Z")),
+          "i": isduration(duration("P100Y12MT12M")),
+          "j": isduration(interval(date("2013-01-01"), date("20130505"))),
+          "k": isduration(3)
+        };
+
+
+ * The expected result is:
+
+        { "a": false, "b": false, "c": null, "e": true, "f": false, "g": false, "h": false, "i": true, "j": false, "k": false }
+
+ The function has an alias `isduration`.
+ 
+### is_interval ###
+ * Syntax:
+
+        is_interval(expr)
+
+ * Checks whether the given expression is evaluated to be a `interval` value.
+ * Arguments:
+    * `expr` : an expression (any type is allowed).
+ * Return Value:
+    * a `boolean` on whether the argument is a `interval` value or not,
+    * a `missing` if the argument is a `missing` value,
+    * a `null` if the argument is a `null` value.
+
+ * Example:
+
+         {
+          "a": is_interval(true),
+          "b": is_interval(false),
+          "c": is_interval(null),
+          "d": is_interval(missing),
+          "e": is_interval(interval(datetime("2013-01-01T00:01:01.000Z"), datetime("2013-05-05T13:39:01.049Z"))),
+          "f": isinterval(date("2013-01-01")),
+          "g": isinterval(time("12:12:12.039Z")),
+          "h": isinterval(datetime("2013-01-01T12:12:12.039Z")),
+          "i": isinterval(duration("P100Y12MT12M")),
+          "j": isinterval(interval(date("2013-01-01"), date("20130505"))),
+          "k": isinterval(3)
+        };
+
+
+ * The expected result is:
+
+        { "a": false, "b": false, "c": null, "e": true, "f": false, "g": false, "h": false, "i": false, "j": true, "k": false }
+
+ The function has an alias `isinterval`.
+ 
+### is_temporal ###
+ * Syntax:
+
+        is_temporal(expr)
+
+ * Checks whether the given expression is evaluated to be a temporal value.
+ * Arguments:
+    * `expr` : an expression (any type is allowed).
+ * Return Value:
+    * a `boolean` on whether the argument is a `date/datetime/time/duration/year_month_duration/day_time_duration/interval` value or not,
+    * a `missing` if the argument is a `missing` value,
+    * a `null` if the argument is a `null` value.
+
+ * Example:
+
+         {
+          "a": is_temporal(true),
+          "b": is_temporal(false),
+          "c": is_temporal(null),
+          "d": is_temporal(missing),
+          "e": is_temporal(duration("-PT20.943S")),
+          "f": istemporal(date("2013-01-01")),
+          "g": istemporal(time("12:12:12.039Z")),
+          "h": istemporal(datetime("2013-01-01T12:12:12.039Z")),
+          "i": istemporal(duration("P100Y12MT12M")),
+          "j": istemporal(interval(date("2013-01-01"), date("20130505"))),
+          "k": istemporal(3)
+        };
+
+
+ * The expected result is:
+
+        { "a": false, "b": false, "c": null, "e": true, "f": true, "g": true, "h": true, "i": true, "j": true, "k": false }
+
+ The function has an alias `istemporal`.
+
+### get_type ###
+ * Syntax:
+
+        get_type(expr)
+
+ * Returns a string describing the type of the given `expr`. This includes incomplete information types (i.e. `missing` and `null`).
+ * Arguments:
+    * `expr` : an expression (any type is allowed).
+
+ * Example:
+
+        {
+          "a": get_type(true),
+          "b": get_type(false),
+          "c": get_type(null),
+          "d": get_type(missing),
+          "e": get_type("d"),
+          "f": gettype(4.0),
+          "g": gettype(5),
+          "h": gettype(["1", 2]),
+          "i": gettype({"a":1})
+        };
+
+
+ * The expected result is:
+
+        { "a": "boolean", "b": "boolean", "c": "null", "d": "missing", "e": "string", "f": "double", "g": "bigint", "h": "array", "i": "object" }
+        
+ The function has an alias `gettype`.
+
diff --git a/asterixdb/asterix-external-data/src/main/java/org/apache/asterix/external/dataflow/FeedRecordDataFlowController.java b/asterixdb/asterix-external-data/src/main/java/org/apache/asterix/external/dataflow/FeedRecordDataFlowController.java
index efb0f13..3fb7db7 100644
--- a/asterixdb/asterix-external-data/src/main/java/org/apache/asterix/external/dataflow/FeedRecordDataFlowController.java
+++ b/asterixdb/asterix-external-data/src/main/java/org/apache/asterix/external/dataflow/FeedRecordDataFlowController.java
@@ -98,8 +98,7 @@
             }
         } catch (HyracksDataException e) {
             LOGGER.log(Level.WARN, "Exception during ingestion", e);
-            if (e.getComponent() == ErrorCode.ASTERIX
-                    && (e.getErrorCode() == ErrorCode.FEED_FAILED_WHILE_GETTING_A_NEW_RECORD)) {
+            if (e.matches(ErrorCode.FEED_FAILED_WHILE_GETTING_A_NEW_RECORD)) {
                 // Failure but we know we can for sure push the previously parsed records safely
                 failure = e;
                 try {
diff --git a/asterixdb/asterix-external-data/src/main/java/org/apache/asterix/external/feed/dataflow/FeedExceptionHandler.java b/asterixdb/asterix-external-data/src/main/java/org/apache/asterix/external/feed/dataflow/FeedExceptionHandler.java
index 2fda99f..a836ef9 100644
--- a/asterixdb/asterix-external-data/src/main/java/org/apache/asterix/external/feed/dataflow/FeedExceptionHandler.java
+++ b/asterixdb/asterix-external-data/src/main/java/org/apache/asterix/external/feed/dataflow/FeedExceptionHandler.java
@@ -46,7 +46,7 @@
     @Override
     public ByteBuffer handle(HyracksDataException th, ByteBuffer frame) {
         try {
-            if (th.getErrorCode() == ErrorCode.ERROR_PROCESSING_TUPLE) {
+            if (th.matches(ErrorCode.ERROR_PROCESSING_TUPLE)) {
                 // TODO(amoudi): add check for cause. cause should be either cast or duplicate key
                 fta.reset(frame);
                 int tupleIndex = (int) (th.getParams()[0]);
diff --git a/asterixdb/asterix-external-data/src/main/java/org/apache/asterix/external/input/record/reader/aws/AwsS3InputStreamFactory.java b/asterixdb/asterix-external-data/src/main/java/org/apache/asterix/external/input/record/reader/aws/AwsS3InputStreamFactory.java
index 9f0f05c..5bab888 100644
--- a/asterixdb/asterix-external-data/src/main/java/org/apache/asterix/external/input/record/reader/aws/AwsS3InputStreamFactory.java
+++ b/asterixdb/asterix-external-data/src/main/java/org/apache/asterix/external/input/record/reader/aws/AwsS3InputStreamFactory.java
@@ -29,7 +29,6 @@
 import org.apache.asterix.common.dataflow.ICcApplicationContext;
 import org.apache.asterix.common.exceptions.CompilationException;
 import org.apache.asterix.common.exceptions.ErrorCode;
-import org.apache.asterix.common.exceptions.WarningUtil;
 import org.apache.asterix.external.api.AsterixInputStream;
 import org.apache.asterix.external.input.record.reader.abstracts.AbstractExternalInputStreamFactory;
 import org.apache.asterix.external.util.ExternalDataUtils;
@@ -98,7 +97,7 @@
 
         // Warn if no files are returned
         if (filesOnly.isEmpty() && warningCollector.shouldWarn()) {
-            Warning warning = WarningUtil.forAsterix(null, ErrorCode.EXTERNAL_SOURCE_CONFIGURATION_RETURNED_NO_FILES);
+            Warning warning = Warning.of(null, ErrorCode.EXTERNAL_SOURCE_CONFIGURATION_RETURNED_NO_FILES);
             warningCollector.warn(warning);
         }
 
diff --git a/asterixdb/asterix-external-data/src/main/java/org/apache/asterix/external/input/record/reader/azure/AzureBlobInputStreamFactory.java b/asterixdb/asterix-external-data/src/main/java/org/apache/asterix/external/input/record/reader/azure/AzureBlobInputStreamFactory.java
index 9b41b08..167e22a 100644
--- a/asterixdb/asterix-external-data/src/main/java/org/apache/asterix/external/input/record/reader/azure/AzureBlobInputStreamFactory.java
+++ b/asterixdb/asterix-external-data/src/main/java/org/apache/asterix/external/input/record/reader/azure/AzureBlobInputStreamFactory.java
@@ -29,7 +29,6 @@
 import org.apache.asterix.common.dataflow.ICcApplicationContext;
 import org.apache.asterix.common.exceptions.CompilationException;
 import org.apache.asterix.common.exceptions.ErrorCode;
-import org.apache.asterix.common.exceptions.WarningUtil;
 import org.apache.asterix.external.api.AsterixInputStream;
 import org.apache.asterix.external.input.record.reader.abstracts.AbstractExternalInputStreamFactory;
 import org.apache.asterix.external.util.ExternalDataUtils;
@@ -84,8 +83,7 @@
 
             // Warn if no files are returned
             if (filesOnly.isEmpty() && warningCollector.shouldWarn()) {
-                Warning warning =
-                        WarningUtil.forAsterix(null, ErrorCode.EXTERNAL_SOURCE_CONFIGURATION_RETURNED_NO_FILES);
+                Warning warning = Warning.of(null, ErrorCode.EXTERNAL_SOURCE_CONFIGURATION_RETURNED_NO_FILES);
                 warningCollector.warn(warning);
             }
 
diff --git a/asterixdb/asterix-external-data/src/main/java/org/apache/asterix/external/input/stream/LocalFSInputStream.java b/asterixdb/asterix-external-data/src/main/java/org/apache/asterix/external/input/stream/LocalFSInputStream.java
index be6a331..f9eade5 100644
--- a/asterixdb/asterix-external-data/src/main/java/org/apache/asterix/external/input/stream/LocalFSInputStream.java
+++ b/asterixdb/asterix-external-data/src/main/java/org/apache/asterix/external/input/stream/LocalFSInputStream.java
@@ -18,10 +18,8 @@
  */
 package org.apache.asterix.external.input.stream;
 
-import static org.apache.asterix.common.exceptions.ErrorCode.ASTERIX;
 import static org.apache.asterix.common.exceptions.ErrorCode.INPUT_RECORD_READER_CHAR_ARRAY_RECORD_TOO_LARGE;
 import static org.apache.asterix.common.exceptions.ErrorCode.RECORD_READER_MALFORMED_INPUT_STREAM;
-import static org.apache.hyracks.api.exceptions.ErrorCode.HYRACKS;
 import static org.apache.hyracks.api.exceptions.ErrorCode.PARSING_ERROR;
 
 import java.io.File;
@@ -134,22 +132,12 @@
         Throwable root = ExceptionUtils.getRootCause(th);
         if (root instanceof HyracksDataException) {
             HyracksDataException r = (HyracksDataException) root;
-            String component = r.getComponent();
             boolean advance = false;
-            int errorCode = r.getErrorCode();
-            if (ASTERIX.equals(component)) {
-                switch (errorCode) {
-                    case RECORD_READER_MALFORMED_INPUT_STREAM:
-                        logCorruptedInput();
-                    case INPUT_RECORD_READER_CHAR_ARRAY_RECORD_TOO_LARGE:
-                        advance = true;
-                        break;
-                    default:
-                        break;
-                }
-            } else if (HYRACKS.equals(component) && errorCode == PARSING_ERROR) {
+            if (r.matchesAny(RECORD_READER_MALFORMED_INPUT_STREAM, PARSING_ERROR)) {
                 logCorruptedInput();
                 advance = true;
+            } else if (r.matches(INPUT_RECORD_READER_CHAR_ARRAY_RECORD_TOO_LARGE)) {
+                advance = true;
             }
             if (advance) {
                 try {
diff --git a/asterixdb/asterix-external-data/src/main/java/org/apache/asterix/external/library/ExternalScalarFunctionEvaluatorFactory.java b/asterixdb/asterix-external-data/src/main/java/org/apache/asterix/external/library/ExternalScalarFunctionEvaluatorFactory.java
index de75f7a..8139027 100755
--- a/asterixdb/asterix-external-data/src/main/java/org/apache/asterix/external/library/ExternalScalarFunctionEvaluatorFactory.java
+++ b/asterixdb/asterix-external-data/src/main/java/org/apache/asterix/external/library/ExternalScalarFunctionEvaluatorFactory.java
@@ -19,6 +19,7 @@
 package org.apache.asterix.external.library;
 
 import org.apache.asterix.common.exceptions.ErrorCode;
+import org.apache.asterix.common.exceptions.RuntimeDataException;
 import org.apache.asterix.om.functions.IExternalFunctionInfo;
 import org.apache.asterix.om.types.IAType;
 import org.apache.hyracks.algebricks.runtime.base.IEvaluatorContext;
@@ -51,7 +52,7 @@
             case PYTHON:
                 return new ExternalScalarPythonFunctionEvaluator(finfo, args, argTypes, ctx, sourceLoc);
             default:
-                throw new HyracksDataException(ErrorCode.ASTERIX, ErrorCode.LIBRARY_EXTERNAL_FUNCTION_UNSUPPORTED_KIND,
+                throw new RuntimeDataException(ErrorCode.LIBRARY_EXTERNAL_FUNCTION_UNSUPPORTED_KIND,
                         finfo.getLanguage());
         }
     }
diff --git a/asterixdb/asterix-external-data/src/main/java/org/apache/asterix/external/library/ExternalScalarPythonFunctionEvaluator.java b/asterixdb/asterix-external-data/src/main/java/org/apache/asterix/external/library/ExternalScalarPythonFunctionEvaluator.java
index 2353c6d..f9d30b1 100644
--- a/asterixdb/asterix-external-data/src/main/java/org/apache/asterix/external/library/ExternalScalarPythonFunctionEvaluator.java
+++ b/asterixdb/asterix-external-data/src/main/java/org/apache/asterix/external/library/ExternalScalarPythonFunctionEvaluator.java
@@ -32,7 +32,6 @@
 
 import org.apache.asterix.common.exceptions.AsterixException;
 import org.apache.asterix.common.exceptions.ErrorCode;
-import org.apache.asterix.common.exceptions.WarningUtil;
 import org.apache.asterix.common.library.ILibraryManager;
 import org.apache.asterix.common.metadata.DataverseName;
 import org.apache.asterix.external.ipc.ExternalFunctionResultRouter;
@@ -52,6 +51,7 @@
 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.api.exceptions.Warning;
 import org.apache.hyracks.api.job.JobId;
 import org.apache.hyracks.api.resources.IDeallocatable;
 import org.apache.hyracks.control.common.controllers.NCConfig;
@@ -223,8 +223,7 @@
             try {
                 ret = proto.call(arguments, numArgs);
             } catch (AsterixException e) {
-                warningCollector
-                        .warn(WarningUtil.forAsterix(sourceLoc, ErrorCode.EXTERNAL_UDF_EXCEPTION, e.getMessage()));
+                warningCollector.warn(Warning.of(sourceLoc, ErrorCode.EXTERNAL_UDF_EXCEPTION, e.getMessage()));
             }
             return ret;
         }
diff --git a/asterixdb/asterix-external-data/src/main/java/org/apache/asterix/external/operators/ExternalFilesIndexModificationOperatorDescriptor.java b/asterixdb/asterix-external-data/src/main/java/org/apache/asterix/external/operators/ExternalFilesIndexModificationOperatorDescriptor.java
index ea99993..477f0fe 100644
--- a/asterixdb/asterix-external-data/src/main/java/org/apache/asterix/external/operators/ExternalFilesIndexModificationOperatorDescriptor.java
+++ b/asterixdb/asterix-external-data/src/main/java/org/apache/asterix/external/operators/ExternalFilesIndexModificationOperatorDescriptor.java
@@ -23,6 +23,7 @@
 import java.util.Map;
 
 import org.apache.asterix.common.exceptions.ErrorCode;
+import org.apache.asterix.common.exceptions.RuntimeDataException;
 import org.apache.asterix.external.indexing.ExternalFile;
 import org.apache.asterix.external.indexing.FileIndexTupleTranslator;
 import org.apache.hyracks.api.comm.IFrameWriter;
@@ -89,7 +90,7 @@
                             case NO_OP:
                                 break;
                             default:
-                                throw HyracksDataException.create(ErrorCode.UNKNOWN_EXTERNAL_FILE_PENDING_OP, sourceLoc,
+                                throw RuntimeDataException.create(ErrorCode.UNKNOWN_EXTERNAL_FILE_PENDING_OP, sourceLoc,
                                         file.getPendingOp());
                         }
                     }
diff --git a/asterixdb/asterix-external-data/src/main/java/org/apache/asterix/external/operators/FeedIntakeOperatorNodePushable.java b/asterixdb/asterix-external-data/src/main/java/org/apache/asterix/external/operators/FeedIntakeOperatorNodePushable.java
index 7002a23..e1ba399 100644
--- a/asterixdb/asterix-external-data/src/main/java/org/apache/asterix/external/operators/FeedIntakeOperatorNodePushable.java
+++ b/asterixdb/asterix-external-data/src/main/java/org/apache/asterix/external/operators/FeedIntakeOperatorNodePushable.java
@@ -135,7 +135,7 @@
                     taskThread.interrupt();
                 }
             } catch (HyracksDataException hde) {
-                if (hde.getComponent() == ErrorCode.HYRACKS && hde.getErrorCode() == ErrorCode.TIMEOUT) {
+                if (hde.matches(ErrorCode.TIMEOUT)) {
                     LOGGER.log(Level.WARN, runtimeId + " stop adapter timed out. interrupting the thread...", hde);
                     taskThread.interrupt();
                 } else {
diff --git a/asterixdb/asterix-external-data/src/main/java/org/apache/asterix/external/parser/JSONDataParser.java b/asterixdb/asterix-external-data/src/main/java/org/apache/asterix/external/parser/JSONDataParser.java
index 8c518c4..b2036c0 100644
--- a/asterixdb/asterix-external-data/src/main/java/org/apache/asterix/external/parser/JSONDataParser.java
+++ b/asterixdb/asterix-external-data/src/main/java/org/apache/asterix/external/parser/JSONDataParser.java
@@ -486,7 +486,7 @@
                 msg = ExceptionUtils.getRootCause(e).getMessage();
             }
             if (msg == null) {
-                msg = ErrorCode.getErrorMessage(ErrorCode.RECORD_READER_MALFORMED_INPUT_STREAM);
+                msg = ErrorCode.RECORD_READER_MALFORMED_INPUT_STREAM.errorMessage();
             }
             long lineNum = lineNumber.getAsLong() + jsonParser.getCurrentLocation().getLineNr() - 1;
             JsonStreamContext parsingContext = jsonParser.getParsingContext();
diff --git a/asterixdb/asterix-external-data/src/main/java/org/apache/asterix/external/parser/ParseException.java b/asterixdb/asterix-external-data/src/main/java/org/apache/asterix/external/parser/ParseException.java
index 5ccb7a3..e9f93c9 100644
--- a/asterixdb/asterix-external-data/src/main/java/org/apache/asterix/external/parser/ParseException.java
+++ b/asterixdb/asterix-external-data/src/main/java/org/apache/asterix/external/parser/ParseException.java
@@ -22,6 +22,7 @@
 
 import org.apache.asterix.common.exceptions.ErrorCode;
 import org.apache.hyracks.api.exceptions.HyracksDataException;
+import org.apache.hyracks.api.exceptions.IError;
 
 public class ParseException extends HyracksDataException {
     private static final long serialVersionUID = 1L;
@@ -33,23 +34,31 @@
         super(message);
     }
 
-    public ParseException(int errorCode, Serializable... param) {
-        super(ErrorCode.ASTERIX, errorCode, ErrorCode.getErrorMessage(errorCode), param);
+    public ParseException(ErrorCode error, Throwable e, Serializable... param) {
+        super(error, e, null, param);
     }
 
-    public ParseException(int errorCode, Throwable e, Serializable... param) {
-        super(ErrorCode.ASTERIX, errorCode, e, ErrorCode.getErrorMessage(errorCode), param);
-        addSuppressed(e);
+    public ParseException(ErrorCode error, Serializable... param) {
+        this(error, null, param);
     }
 
+    /**
+     * @deprecated use {@link IError} ctors when possible
+     */
     public ParseException(Throwable cause) {
         super(cause);
     }
 
+    /**
+     * @deprecated use {@link IError} ctors when possible
+     */
     public ParseException(String message, Throwable cause) {
         super(message, cause);
     }
 
+    /**
+     * @deprecated use {@link IError} ctors when possible
+     */
     public ParseException(Throwable cause, String filename, int line, int column) {
         super(cause);
         setLocation(filename, line, column);
diff --git a/asterixdb/asterix-external-data/src/main/java/org/apache/asterix/external/parser/factory/RecordWithMetadataParserFactory.java b/asterixdb/asterix-external-data/src/main/java/org/apache/asterix/external/parser/factory/RecordWithMetadataParserFactory.java
index f940f3d..3ae9b82 100644
--- a/asterixdb/asterix-external-data/src/main/java/org/apache/asterix/external/parser/factory/RecordWithMetadataParserFactory.java
+++ b/asterixdb/asterix-external-data/src/main/java/org/apache/asterix/external/parser/factory/RecordWithMetadataParserFactory.java
@@ -23,6 +23,7 @@
 import java.util.List;
 import java.util.Map;
 
+import org.apache.asterix.common.exceptions.CompilationException;
 import org.apache.asterix.common.exceptions.ErrorCode;
 import org.apache.asterix.external.api.IRecordDataParser;
 import org.apache.asterix.external.api.IRecordDataParserFactory;
@@ -54,12 +55,12 @@
         // validate first
         String recordFormat = configuration.get(ExternalDataConstants.KEY_RECORD_FORMAT);
         if (recordFormat == null) {
-            throw AlgebricksException.create(ErrorCode.UNKNOWN_RECORD_FORMAT_FOR_META_PARSER,
+            throw CompilationException.create(ErrorCode.UNKNOWN_RECORD_FORMAT_FOR_META_PARSER,
                     ExternalDataConstants.KEY_RECORD_FORMAT);
         }
         String format = configuration.get(ExternalDataConstants.KEY_FORMAT);
         if (format == null) {
-            throw AlgebricksException.create(ErrorCode.UNKNOWN_RECORD_FORMAT_FOR_META_PARSER,
+            throw CompilationException.create(ErrorCode.UNKNOWN_RECORD_FORMAT_FOR_META_PARSER,
                     ExternalDataConstants.KEY_FORMAT);
         }
         // Create Parser Factory
diff --git a/asterixdb/asterix-external-data/src/main/java/org/apache/asterix/external/util/ExternalDataUtils.java b/asterixdb/asterix-external-data/src/main/java/org/apache/asterix/external/util/ExternalDataUtils.java
index ec5798f..3ac1116 100644
--- a/asterixdb/asterix-external-data/src/main/java/org/apache/asterix/external/util/ExternalDataUtils.java
+++ b/asterixdb/asterix-external-data/src/main/java/org/apache/asterix/external/util/ExternalDataUtils.java
@@ -49,7 +49,6 @@
 import org.apache.asterix.common.exceptions.CompilationException;
 import org.apache.asterix.common.exceptions.ErrorCode;
 import org.apache.asterix.common.exceptions.RuntimeDataException;
-import org.apache.asterix.common.exceptions.WarningUtil;
 import org.apache.asterix.common.functions.ExternalFunctionLanguage;
 import org.apache.asterix.common.library.ILibrary;
 import org.apache.asterix.common.library.ILibraryManager;
@@ -806,8 +805,7 @@
             boolean isEmpty = useOldApi ? ((ListObjectsResponse) response).contents().isEmpty()
                     : ((ListObjectsV2Response) response).contents().isEmpty();
             if (isEmpty && collector.shouldWarn()) {
-                Warning warning =
-                        WarningUtil.forAsterix(srcLoc, ErrorCode.EXTERNAL_SOURCE_CONFIGURATION_RETURNED_NO_FILES);
+                Warning warning = Warning.of(srcLoc, ErrorCode.EXTERNAL_SOURCE_CONFIGURATION_RETURNED_NO_FILES);
                 collector.warn(warning);
             }
 
@@ -955,8 +953,7 @@
                 Iterable<BlobItem> blobItems = blobContainer.listBlobs(listBlobsOptions, null);
 
                 if (!blobItems.iterator().hasNext() && collector.shouldWarn()) {
-                    Warning warning =
-                            WarningUtil.forAsterix(srcLoc, ErrorCode.EXTERNAL_SOURCE_CONFIGURATION_RETURNED_NO_FILES);
+                    Warning warning = Warning.of(srcLoc, ErrorCode.EXTERNAL_SOURCE_CONFIGURATION_RETURNED_NO_FILES);
                     collector.warn(warning);
                 }
             } catch (CompilationException ex) {
diff --git a/asterixdb/asterix-external-data/src/main/java/org/apache/asterix/external/util/ParseUtil.java b/asterixdb/asterix-external-data/src/main/java/org/apache/asterix/external/util/ParseUtil.java
index 7afc592..5a46af7 100644
--- a/asterixdb/asterix-external-data/src/main/java/org/apache/asterix/external/util/ParseUtil.java
+++ b/asterixdb/asterix-external-data/src/main/java/org/apache/asterix/external/util/ParseUtil.java
@@ -29,7 +29,7 @@
 
     public static void warn(IWarningCollector warningCollector, String dataSourceName, long lineNum, int fieldNum,
             String warnMessage) {
-        warningCollector.warn(
-                Warning.forHyracks(null, ErrorCode.PARSING_ERROR, dataSourceName, lineNum, fieldNum, warnMessage));
+        warningCollector
+                .warn(Warning.of(null, ErrorCode.PARSING_ERROR, dataSourceName, lineNum, fieldNum, warnMessage));
     }
 }
diff --git a/asterixdb/asterix-lang-common/src/main/java/org/apache/asterix/lang/common/util/LangRecordParseUtil.java b/asterixdb/asterix-lang-common/src/main/java/org/apache/asterix/lang/common/util/LangRecordParseUtil.java
index 6a34f65..28639c1 100644
--- a/asterixdb/asterix-lang-common/src/main/java/org/apache/asterix/lang/common/util/LangRecordParseUtil.java
+++ b/asterixdb/asterix-lang-common/src/main/java/org/apache/asterix/lang/common/util/LangRecordParseUtil.java
@@ -25,6 +25,7 @@
 
 import org.apache.asterix.common.exceptions.CompilationException;
 import org.apache.asterix.common.exceptions.ErrorCode;
+import org.apache.asterix.common.exceptions.RuntimeDataException;
 import org.apache.asterix.lang.common.base.Expression;
 import org.apache.asterix.lang.common.base.Literal;
 import org.apache.asterix.lang.common.expression.FieldBinding;
@@ -69,8 +70,8 @@
             case LIST_CONSTRUCTOR_EXPRESSION:
                 return parseList((ListConstructor) expr);
             default:
-                throw new HyracksDataException(ErrorCode.ASTERIX, ErrorCode.PARSE_ERROR,
-                        NOT_ALLOWED_EXPRESSIONS_ERROR_MESSAGE, Expression.Kind.LITERAL_EXPRESSION.toString(),
+                throw new RuntimeDataException(ErrorCode.PARSE_ERROR, NOT_ALLOWED_EXPRESSIONS_ERROR_MESSAGE,
+                        Expression.Kind.LITERAL_EXPRESSION.toString(),
                         Expression.Kind.RECORD_CONSTRUCTOR_EXPRESSION.toString(),
                         Expression.Kind.LIST_CONSTRUCTOR_EXPRESSION.toString());
         }
@@ -110,7 +111,7 @@
 
     private static AdmArrayNode parseList(ListConstructor valueExpr) throws CompilationException, HyracksDataException {
         if (valueExpr.getType() != ListConstructor.Type.ORDERED_LIST_CONSTRUCTOR) {
-            throw new HyracksDataException(ErrorCode.ASTERIX, ErrorCode.PARSE_ERROR, "JSON List can't be of type %1$s",
+            throw new RuntimeDataException(ErrorCode.PARSE_ERROR, "JSON List can't be of type %1$s",
                     valueExpr.getType());
         }
         List<Expression> exprs = valueExpr.getExprList();
@@ -140,7 +141,7 @@
             case STRING:
                 return new AdmStringNode((String) value.getValue());
             default:
-                throw new HyracksDataException(ErrorCode.ASTERIX, ErrorCode.PARSE_ERROR, "Unknown Literal Type %1$s",
+                throw new RuntimeDataException(ErrorCode.PARSE_ERROR, "Unknown Literal Type %1$s",
                         value.getLiteralType());
         }
     }
diff --git a/asterixdb/asterix-lang-sqlpp/src/main/javacc/SQLPP.jj b/asterixdb/asterix-lang-sqlpp/src/main/javacc/SQLPP.jj
index dc2434e..a923551 100644
--- a/asterixdb/asterix-lang-sqlpp/src/main/javacc/SQLPP.jj
+++ b/asterixdb/asterix-lang-sqlpp/src/main/javacc/SQLPP.jj
@@ -70,7 +70,6 @@
 import org.apache.asterix.common.exceptions.CompilationException;
 import org.apache.asterix.common.exceptions.ErrorCode;
 import org.apache.asterix.common.exceptions.WarningCollector;
-import org.apache.asterix.common.exceptions.WarningUtil;
 import org.apache.asterix.common.functions.FunctionConstants;
 import org.apache.asterix.common.functions.FunctionSignature;
 import org.apache.asterix.common.metadata.DataverseName;
@@ -590,7 +589,7 @@
 
     private void warnUnexpectedHint(String actualHint, SourceLocation sourceLoc, String expectedHints) {
         if (warningCollector.shouldWarn()) {
-            warningCollector.warn(WarningUtil.forAsterix(sourceLoc, ErrorCode.UNEXPECTED_HINT, actualHint, expectedHints));
+            warningCollector.warn(Warning.of(sourceLoc, ErrorCode.UNEXPECTED_HINT, actualHint, expectedHints));
         }
     }
 
@@ -635,13 +634,13 @@
         }
       } catch (SqlppParseException e) {
         if (warningCollector.shouldWarn()) {
-            warningCollector.warn(WarningUtil.forAsterix(getSourceLocation(hintToken), ErrorCode.INVALID_HINT,
+            warningCollector.warn(Warning.of(getSourceLocation(hintToken), ErrorCode.INVALID_HINT,
               hintToken.hint.toString(), e.getMessage()));
         }
         return onParseErrorReturn;
       } catch (CompilationException e) {
         if (warningCollector.shouldWarn()) {
-            warningCollector.warn(WarningUtil.forAsterix(getSourceLocation(hintToken), ErrorCode.INVALID_HINT,
+            warningCollector.warn(Warning.of(getSourceLocation(hintToken), ErrorCode.INVALID_HINT,
               hintToken.hint.toString(), e.getMessage()));
         }
         return onParseErrorReturn;
diff --git a/asterixdb/asterix-lang-sqlpp/src/test/java/org/apache/asterix/lang/sqlpp/parser/SqlppGroupingSetsParserTest.java b/asterixdb/asterix-lang-sqlpp/src/test/java/org/apache/asterix/lang/sqlpp/parser/SqlppGroupingSetsParserTest.java
index f597c6b..42ba8bc 100644
--- a/asterixdb/asterix-lang-sqlpp/src/test/java/org/apache/asterix/lang/sqlpp/parser/SqlppGroupingSetsParserTest.java
+++ b/asterixdb/asterix-lang-sqlpp/src/test/java/org/apache/asterix/lang/sqlpp/parser/SqlppGroupingSetsParserTest.java
@@ -39,6 +39,7 @@
 import org.apache.asterix.lang.sqlpp.util.SqlppVariableUtil;
 import org.apache.asterix.lang.sqlpp.visitor.SqlppFormatPrintVisitor;
 import org.apache.asterix.lang.sqlpp.visitor.base.AbstractSqlppSimpleExpressionVisitor;
+import org.apache.hyracks.api.exceptions.IError;
 import org.apache.hyracks.util.MathUtil;
 import org.junit.Assert;
 import org.junit.Test;
@@ -57,13 +58,11 @@
 
     private static final int GROUPING_SETS_LIMIT_SQRT = (int) Math.ceil(Math.sqrt(GROUPING_SETS_LIMIT));
 
-    private static final String ERR_PREFIX = "ASX";
+    private static final ErrorCode ERR_SYNTAX = ErrorCode.PARSE_ERROR;
 
-    private static final String ERR_SYNTAX = ERR_PREFIX + ErrorCode.PARSE_ERROR;
+    private static final ErrorCode ERR_OVERFLOW = ErrorCode.COMPILATION_GROUPING_SETS_OVERFLOW;
 
-    private static final String ERR_OVERFLOW = ERR_PREFIX + ErrorCode.COMPILATION_GROUPING_SETS_OVERFLOW;
-
-    private static final String ERR_ALIAS = ERR_PREFIX + ErrorCode.COMPILATION_UNEXPECTED_ALIAS;
+    private static final ErrorCode ERR_ALIAS = ErrorCode.COMPILATION_UNEXPECTED_ALIAS;
 
     @Parameterized.Parameters(name = "{index}: GROUP BY {0}")
     public static Collection<Object[]> data() {
@@ -205,15 +204,15 @@
 
     private final String expectedGroupingSets;
 
-    private final String expectedErrorCode;
+    private final IError expectedErrorCode;
 
-    public SqlppGroupingSetsParserTest(String groupbyInput, String expectedResult) {
+    public SqlppGroupingSetsParserTest(String groupbyInput, Object expectedResult) {
         this.groupbyInput = groupbyInput;
-        if (expectedResult.startsWith(ERR_PREFIX)) {
+        if (expectedResult instanceof IError) {
             this.expectedGroupingSets = null;
-            this.expectedErrorCode = expectedResult;
+            this.expectedErrorCode = (IError) expectedResult;
         } else {
-            this.expectedGroupingSets = expectedResult;
+            this.expectedGroupingSets = (String) expectedResult;
             this.expectedErrorCode = null;
         }
     }
@@ -231,7 +230,7 @@
         } catch (CompilationException e) {
             if (expectedErrorCode == null) {
                 throw e;
-            } else if (e.getMessage().contains(expectedErrorCode)) {
+            } else if (e.getMessage().contains(expectedErrorCode.errorCode())) {
                 return; // Found expected error code. SUCCESS
             } else {
                 Assert.fail(String.format("Unable to find expected error code %s in error message: %s",
diff --git a/asterixdb/asterix-metadata/src/main/java/org/apache/asterix/metadata/MetadataNode.java b/asterixdb/asterix-metadata/src/main/java/org/apache/asterix/metadata/MetadataNode.java
index 449e8d2..a52fe1c 100644
--- a/asterixdb/asterix-metadata/src/main/java/org/apache/asterix/metadata/MetadataNode.java
+++ b/asterixdb/asterix-metadata/src/main/java/org/apache/asterix/metadata/MetadataNode.java
@@ -340,7 +340,7 @@
             ITupleReference tuple = tupleReaderWriter.getTupleFromMetadataEntity(dataverse);
             insertTupleIntoIndex(txnId, MetadataPrimaryIndexes.DATAVERSE_DATASET, tuple);
         } catch (HyracksDataException e) {
-            if (e.getComponent().equals(ErrorCode.HYRACKS) && e.getErrorCode() == ErrorCode.DUPLICATE_KEY) {
+            if (e.matches(ErrorCode.DUPLICATE_KEY)) {
                 throw new AlgebricksException(
                         "A dataverse with this name " + dataverse.getDataverseName() + " already exists.", e);
             } else {
@@ -366,7 +366,7 @@
                 addIndex(txnId, primaryIndex);
             }
         } catch (HyracksDataException e) {
-            if (e.getComponent().equals(ErrorCode.HYRACKS) && e.getErrorCode() == ErrorCode.DUPLICATE_KEY) {
+            if (e.matches(ErrorCode.DUPLICATE_KEY)) {
                 throw new AlgebricksException("A dataset with this name " + dataset.getDatasetName()
                         + " already exists in dataverse '" + dataset.getDataverseName() + "'.", e);
             } else {
@@ -382,7 +382,7 @@
             ITupleReference tuple = tupleWriter.getTupleFromMetadataEntity(index);
             insertTupleIntoIndex(txnId, MetadataPrimaryIndexes.INDEX_DATASET, tuple);
         } catch (HyracksDataException e) {
-            if (e.getComponent().equals(ErrorCode.HYRACKS) && e.getErrorCode() == ErrorCode.DUPLICATE_KEY) {
+            if (e.matches(ErrorCode.DUPLICATE_KEY)) {
                 throw new AlgebricksException("An index with name '" + index.getIndexName() + "' already exists.", e);
             } else {
                 throw new AlgebricksException(e);
@@ -397,7 +397,7 @@
             ITupleReference tuple = tupleReaderWriter.getTupleFromMetadataEntity(node);
             insertTupleIntoIndex(txnId, MetadataPrimaryIndexes.NODE_DATASET, tuple);
         } catch (HyracksDataException e) {
-            if (e.getComponent().equals(ErrorCode.HYRACKS) && e.getErrorCode() == ErrorCode.DUPLICATE_KEY) {
+            if (e.matches(ErrorCode.DUPLICATE_KEY)) {
                 throw new AlgebricksException("A node with name '" + node.getNodeName() + "' already exists.", e);
             } else {
                 throw new AlgebricksException(e);
@@ -412,7 +412,7 @@
             ITupleReference tuple = tupleReaderWriter.getTupleFromMetadataEntity(nodeGroup);
             modifyMetadataIndex(modificationOp, txnId, MetadataPrimaryIndexes.NODEGROUP_DATASET, tuple);
         } catch (HyracksDataException e) {
-            if (e.getComponent().equals(ErrorCode.HYRACKS) && e.getErrorCode() == ErrorCode.DUPLICATE_KEY) {
+            if (e.matches(ErrorCode.DUPLICATE_KEY)) {
                 throw new AlgebricksException(
                         "A nodegroup with name '" + nodeGroup.getNodeGroupName() + "' already exists.", e);
             } else {
@@ -429,7 +429,7 @@
             ITupleReference tuple = tupleReaderWriter.getTupleFromMetadataEntity(datatype);
             insertTupleIntoIndex(txnId, MetadataPrimaryIndexes.DATATYPE_DATASET, tuple);
         } catch (HyracksDataException e) {
-            if (e.getComponent().equals(ErrorCode.HYRACKS) && e.getErrorCode() == ErrorCode.DUPLICATE_KEY) {
+            if (e.matches(ErrorCode.DUPLICATE_KEY)) {
                 throw new AlgebricksException(
                         "A datatype with name '" + datatype.getDatatypeName() + "' already exists.", e);
             } else {
@@ -447,7 +447,7 @@
             ITupleReference functionTuple = tupleReaderWriter.getTupleFromMetadataEntity(function);
             insertTupleIntoIndex(txnId, MetadataPrimaryIndexes.FUNCTION_DATASET, functionTuple);
         } catch (HyracksDataException e) {
-            if (e.getComponent().equals(ErrorCode.HYRACKS) && e.getErrorCode() == ErrorCode.DUPLICATE_KEY) {
+            if (e.matches(ErrorCode.DUPLICATE_KEY)) {
                 throw new AlgebricksException("A function with this name " + function.getSignature()
                         + " already exists in dataverse '" + function.getDataverseName() + "'.", e);
             } else {
@@ -740,8 +740,7 @@
             ITupleReference tuple = getTupleToBeDeleted(txnId, MetadataPrimaryIndexes.DATAVERSE_DATASET, searchKey);
             deleteTupleFromIndex(txnId, MetadataPrimaryIndexes.DATAVERSE_DATASET, tuple);
         } catch (HyracksDataException e) {
-            if (e.getComponent().equals(ErrorCode.HYRACKS)
-                    && e.getErrorCode() == ErrorCode.UPDATE_OR_DELETE_NON_EXISTENT_KEY) {
+            if (e.matches(ErrorCode.UPDATE_OR_DELETE_NON_EXISTENT_KEY)) {
                 throw new AlgebricksException("Cannot drop dataverse '" + dataverseName + "' because it doesn't exist.",
                         e);
             } else {
@@ -807,8 +806,7 @@
             } catch (HyracksDataException hde) {
                 // ignore this exception and continue deleting all relevant
                 // artifacts.
-                if (!hde.getComponent().equals(ErrorCode.HYRACKS)
-                        || hde.getErrorCode() != ErrorCode.UPDATE_OR_DELETE_NON_EXISTENT_KEY) {
+                if (!hde.matches(ErrorCode.UPDATE_OR_DELETE_NON_EXISTENT_KEY)) {
                     throw new AlgebricksException(hde);
                 }
             } finally {
@@ -829,8 +827,7 @@
             ITupleReference tuple = getTupleToBeDeleted(txnId, MetadataPrimaryIndexes.INDEX_DATASET, searchKey);
             deleteTupleFromIndex(txnId, MetadataPrimaryIndexes.INDEX_DATASET, tuple);
         } catch (HyracksDataException e) {
-            if (e.getComponent().equals(ErrorCode.HYRACKS)
-                    && e.getErrorCode() == ErrorCode.UPDATE_OR_DELETE_NON_EXISTENT_KEY) {
+            if (e.matches(ErrorCode.UPDATE_OR_DELETE_NON_EXISTENT_KEY)) {
                 throw new AlgebricksException(
                         "Cannot drop index '" + datasetName + "." + indexName + "' because it doesn't exist.", e);
             } else {
@@ -862,8 +859,7 @@
             deleteTupleFromIndex(txnId, MetadataPrimaryIndexes.NODEGROUP_DATASET, tuple);
             return true;
         } catch (HyracksDataException e) {
-            if (e.getComponent().equals(ErrorCode.HYRACKS)
-                    && e.getErrorCode() == ErrorCode.UPDATE_OR_DELETE_NON_EXISTENT_KEY) {
+            if (e.matches(ErrorCode.UPDATE_OR_DELETE_NON_EXISTENT_KEY)) {
                 throw new AlgebricksException("Cannot drop nodegroup '" + nodeGroupName + "' because it doesn't exist",
                         e);
             } else {
@@ -898,8 +894,7 @@
                 }
             }
         } catch (HyracksDataException e) {
-            if (e.getComponent().equals(ErrorCode.HYRACKS)
-                    && e.getErrorCode() == ErrorCode.UPDATE_OR_DELETE_NON_EXISTENT_KEY) {
+            if (e.matches(ErrorCode.UPDATE_OR_DELETE_NON_EXISTENT_KEY)) {
                 throw new AlgebricksException("Cannot drop type '" + datatypeName + "' because it doesn't exist", e);
             } else {
                 throw new AlgebricksException(e);
@@ -916,8 +911,7 @@
             ITupleReference tuple = getTupleToBeDeleted(txnId, MetadataPrimaryIndexes.DATATYPE_DATASET, searchKey);
             deleteTupleFromIndex(txnId, MetadataPrimaryIndexes.DATATYPE_DATASET, tuple);
         } catch (HyracksDataException e) {
-            if (e.getComponent().equals(ErrorCode.HYRACKS)
-                    && e.getErrorCode() == ErrorCode.UPDATE_OR_DELETE_NON_EXISTENT_KEY) {
+            if (e.matches(ErrorCode.UPDATE_OR_DELETE_NON_EXISTENT_KEY)) {
                 throw new AlgebricksException("Cannot drop type '" + datatypeName + "' because it doesn't exist", e);
             } else {
                 throw new AlgebricksException(e);
@@ -1515,8 +1509,7 @@
                     getTupleToBeDeleted(txnId, MetadataPrimaryIndexes.FUNCTION_DATASET, searchKey);
             deleteTupleFromIndex(txnId, MetadataPrimaryIndexes.FUNCTION_DATASET, functionTuple);
         } catch (HyracksDataException e) {
-            if (e.getComponent().equals(ErrorCode.HYRACKS)
-                    && e.getErrorCode() == ErrorCode.UPDATE_OR_DELETE_NON_EXISTENT_KEY) {
+            if (e.matches(ErrorCode.UPDATE_OR_DELETE_NON_EXISTENT_KEY)) {
                 throw new AlgebricksException(
                         "Cannot drop function '" + functionSignature + "' because it doesn't exist", e);
             } else {
@@ -1753,7 +1746,7 @@
             ITupleReference adapterTuple = tupleReaderWriter.getTupleFromMetadataEntity(adapter);
             insertTupleIntoIndex(txnId, MetadataPrimaryIndexes.DATASOURCE_ADAPTER_DATASET, adapterTuple);
         } catch (HyracksDataException e) {
-            if (e.getComponent().equals(ErrorCode.HYRACKS) && e.getErrorCode() == ErrorCode.DUPLICATE_KEY) {
+            if (e.matches(ErrorCode.DUPLICATE_KEY)) {
                 throw new AlgebricksException("A adapter with this name " + adapter.getAdapterIdentifier().getName()
                         + " already exists in dataverse '" + adapter.getAdapterIdentifier().getDataverseName() + "'.",
                         e);
@@ -1778,8 +1771,7 @@
                     getTupleToBeDeleted(txnId, MetadataPrimaryIndexes.DATASOURCE_ADAPTER_DATASET, searchKey);
             deleteTupleFromIndex(txnId, MetadataPrimaryIndexes.DATASOURCE_ADAPTER_DATASET, datasetTuple);
         } catch (HyracksDataException e) {
-            if (e.getComponent().equals(ErrorCode.HYRACKS)
-                    && e.getErrorCode() == ErrorCode.UPDATE_OR_DELETE_NON_EXISTENT_KEY) {
+            if (e.matches(ErrorCode.UPDATE_OR_DELETE_NON_EXISTENT_KEY)) {
                 throw new AlgebricksException("Cannot drop adapter '" + adapterName + " since it doesn't exist", e);
             } else {
                 throw new AlgebricksException(e);
@@ -1815,8 +1807,8 @@
             ITupleReference compactionPolicyTuple = tupleReaderWriter.getTupleFromMetadataEntity(compactionPolicy);
             insertTupleIntoIndex(txnId, MetadataPrimaryIndexes.COMPACTION_POLICY_DATASET, compactionPolicyTuple);
         } catch (HyracksDataException e) {
-            if (e.getComponent().equals(ErrorCode.HYRACKS) && e.getErrorCode() == ErrorCode.DUPLICATE_KEY) {
-                throw new AlgebricksException("A compcation policy with this name " + compactionPolicy.getPolicyName()
+            if (e.matches(ErrorCode.DUPLICATE_KEY)) {
+                throw new AlgebricksException("A compaction policy with this name " + compactionPolicy.getPolicyName()
                         + " already exists in dataverse '" + compactionPolicy.getPolicyName() + "'.", e);
             } else {
                 throw new AlgebricksException(e);
@@ -1867,7 +1859,7 @@
             ITupleReference libraryTuple = tupleReaderWriter.getTupleFromMetadataEntity(library);
             insertTupleIntoIndex(txnId, MetadataPrimaryIndexes.LIBRARY_DATASET, libraryTuple);
         } catch (HyracksDataException e) {
-            if (e.getComponent().equals(ErrorCode.HYRACKS) && e.getErrorCode() == ErrorCode.DUPLICATE_KEY) {
+            if (e.matches(ErrorCode.DUPLICATE_KEY)) {
                 throw new AlgebricksException("A library with this name " + library.getDataverseName()
                         + " already exists in dataverse '" + library.getDataverseName() + "'.", e);
             } else {
@@ -1894,8 +1886,7 @@
                     getTupleToBeDeleted(txnId, MetadataPrimaryIndexes.LIBRARY_DATASET, searchKey);
             deleteTupleFromIndex(txnId, MetadataPrimaryIndexes.LIBRARY_DATASET, datasetTuple);
         } catch (HyracksDataException e) {
-            if (e.getComponent().equals(ErrorCode.HYRACKS)
-                    && e.getErrorCode() == ErrorCode.UPDATE_OR_DELETE_NON_EXISTENT_KEY) {
+            if (e.matches(ErrorCode.UPDATE_OR_DELETE_NON_EXISTENT_KEY)) {
                 throw new AlgebricksException("Cannot drop library '" + libraryName + "' because it doesn't exist", e);
             } else {
                 throw new AlgebricksException(e);
@@ -1933,7 +1924,7 @@
             ITupleReference feedPolicyTuple = tupleReaderWriter.getTupleFromMetadataEntity(feedPolicy);
             insertTupleIntoIndex(txnId, MetadataPrimaryIndexes.FEED_POLICY_DATASET, feedPolicyTuple);
         } catch (HyracksDataException e) {
-            if (e.getComponent().equals(ErrorCode.HYRACKS) && e.getErrorCode() == ErrorCode.DUPLICATE_KEY) {
+            if (e.matches(ErrorCode.DUPLICATE_KEY)) {
                 throw new AlgebricksException("A feed policy with this name " + feedPolicy.getPolicyName()
                         + " already exists in dataverse '" + feedPolicy.getPolicyName() + "'.", e);
             } else {
@@ -2028,7 +2019,7 @@
             ITupleReference feedTuple = tupleReaderWriter.getTupleFromMetadataEntity(feed);
             insertTupleIntoIndex(txnId, MetadataPrimaryIndexes.FEED_DATASET, feedTuple);
         } catch (HyracksDataException e) {
-            if (e.getComponent().equals(ErrorCode.HYRACKS) && e.getErrorCode() == ErrorCode.DUPLICATE_KEY) {
+            if (e.matches(ErrorCode.DUPLICATE_KEY)) {
                 throw new AlgebricksException("A feed with this name " + feed.getFeedName()
                         + " already exists in dataverse '" + feed.getDataverseName() + "'.", e);
             } else {
@@ -2077,8 +2068,7 @@
             ITupleReference tuple = getTupleToBeDeleted(txnId, MetadataPrimaryIndexes.FEED_DATASET, searchKey);
             deleteTupleFromIndex(txnId, MetadataPrimaryIndexes.FEED_DATASET, tuple);
         } catch (HyracksDataException e) {
-            if (e.getComponent().equals(ErrorCode.HYRACKS)
-                    && e.getErrorCode() == ErrorCode.UPDATE_OR_DELETE_NON_EXISTENT_KEY) {
+            if (e.matches(ErrorCode.UPDATE_OR_DELETE_NON_EXISTENT_KEY)) {
                 throw new AlgebricksException("Cannot drop feed '" + feedName + "' because it doesn't exist", e);
             } else {
                 throw new AlgebricksException(e);
@@ -2093,8 +2083,7 @@
             ITupleReference tuple = getTupleToBeDeleted(txnId, MetadataPrimaryIndexes.FEED_POLICY_DATASET, searchKey);
             deleteTupleFromIndex(txnId, MetadataPrimaryIndexes.FEED_POLICY_DATASET, tuple);
         } catch (HyracksDataException e) {
-            if (e.getComponent().equals(ErrorCode.HYRACKS)
-                    && e.getErrorCode() == ErrorCode.UPDATE_OR_DELETE_NON_EXISTENT_KEY) {
+            if (e.matches(ErrorCode.UPDATE_OR_DELETE_NON_EXISTENT_KEY)) {
                 throw new AlgebricksException("Unknown feed policy " + policyName, e);
             } else {
                 throw new AlgebricksException(e);
@@ -2126,7 +2115,7 @@
             ITupleReference externalFileTuple = tupleReaderWriter.getTupleFromMetadataEntity(externalFile);
             insertTupleIntoIndex(txnId, MetadataPrimaryIndexes.EXTERNAL_FILE_DATASET, externalFileTuple);
         } catch (HyracksDataException e) {
-            if (e.getComponent().equals(ErrorCode.HYRACKS) && e.getErrorCode() == ErrorCode.DUPLICATE_KEY) {
+            if (e.matches(ErrorCode.DUPLICATE_KEY)) {
                 throw new AlgebricksException("An externalFile with this number " + externalFile.getFileNumber()
                         + " already exists in dataset '" + externalFile.getDatasetName() + "' in dataverse '"
                         + externalFile.getDataverseName() + "'.", e);
@@ -2163,8 +2152,7 @@
                     getTupleToBeDeleted(txnId, MetadataPrimaryIndexes.EXTERNAL_FILE_DATASET, searchKey);
             deleteTupleFromIndex(txnId, MetadataPrimaryIndexes.EXTERNAL_FILE_DATASET, datasetTuple);
         } catch (HyracksDataException e) {
-            if (e.getComponent().equals(ErrorCode.HYRACKS)
-                    && e.getErrorCode() == ErrorCode.UPDATE_OR_DELETE_NON_EXISTENT_KEY) {
+            if (e.matches(ErrorCode.UPDATE_OR_DELETE_NON_EXISTENT_KEY)) {
                 throw new AlgebricksException("Couldn't drop externalFile.", e);
             } else {
                 throw new AlgebricksException(e);
@@ -2240,7 +2228,7 @@
             ITupleReference synonymTuple = tupleReaderWriter.getTupleFromMetadataEntity(synonym);
             insertTupleIntoIndex(txnId, MetadataPrimaryIndexes.SYNONYM_DATASET, synonymTuple);
         } catch (HyracksDataException e) {
-            if (e.getComponent().equals(ErrorCode.HYRACKS) && e.getErrorCode() == ErrorCode.DUPLICATE_KEY) {
+            if (e.matches(ErrorCode.DUPLICATE_KEY)) {
                 throw new AlgebricksException("A synonym with name '" + synonym.getSynonymName() + "' already exists.",
                         e);
             } else {
@@ -2264,8 +2252,7 @@
                     getTupleToBeDeleted(txnId, MetadataPrimaryIndexes.SYNONYM_DATASET, searchKey);
             deleteTupleFromIndex(txnId, MetadataPrimaryIndexes.SYNONYM_DATASET, synonymTuple);
         } catch (HyracksDataException e) {
-            if (e.getComponent().equals(ErrorCode.HYRACKS)
-                    && e.getErrorCode() == ErrorCode.UPDATE_OR_DELETE_NON_EXISTENT_KEY) {
+            if (e.matches(ErrorCode.UPDATE_OR_DELETE_NON_EXISTENT_KEY)) {
                 throw new AlgebricksException("Cannot drop synonym '" + synonymName, e);
             } else {
                 throw new AlgebricksException(e);
@@ -2319,8 +2306,7 @@
             datasetTuple = tupleReaderWriter.getTupleFromMetadataEntity(dataset);
             insertTupleIntoIndex(txnId, MetadataPrimaryIndexes.DATASET_DATASET, datasetTuple);
         } catch (HyracksDataException e) {
-            if (e.getComponent().equals(ErrorCode.HYRACKS)
-                    && e.getErrorCode() == ErrorCode.UPDATE_OR_DELETE_NON_EXISTENT_KEY) {
+            if (e.matches(ErrorCode.UPDATE_OR_DELETE_NON_EXISTENT_KEY)) {
                 throw new AlgebricksException(
                         "Cannot drop dataset '" + dataset.getDatasetName() + "' because it doesn't exist");
             } else {
diff --git a/asterixdb/asterix-metadata/src/main/java/org/apache/asterix/metadata/entitytupletranslators/AbstractDatatypeTupleTranslator.java b/asterixdb/asterix-metadata/src/main/java/org/apache/asterix/metadata/entitytupletranslators/AbstractDatatypeTupleTranslator.java
index 60bd2c2..e663798 100644
--- a/asterixdb/asterix-metadata/src/main/java/org/apache/asterix/metadata/entitytupletranslators/AbstractDatatypeTupleTranslator.java
+++ b/asterixdb/asterix-metadata/src/main/java/org/apache/asterix/metadata/entitytupletranslators/AbstractDatatypeTupleTranslator.java
@@ -217,7 +217,7 @@
                 throw HyracksDataException.create(e);
             } else {
                 HyracksDataException hde = (HyracksDataException) e.getCause();
-                if (!hde.getComponent().equals(ErrorCode.HYRACKS) || hde.getErrorCode() != ErrorCode.DUPLICATE_KEY) {
+                if (!hde.matches(ErrorCode.DUPLICATE_KEY)) {
                     throw hde;
                 }
             }
diff --git a/asterixdb/asterix-om/src/main/java/org/apache/asterix/dataflow/data/nontagged/serde/AGeometrySerializerDeserializer.java b/asterixdb/asterix-om/src/main/java/org/apache/asterix/dataflow/data/nontagged/serde/AGeometrySerializerDeserializer.java
index 65ce9ba..38a4c46 100644
--- a/asterixdb/asterix-om/src/main/java/org/apache/asterix/dataflow/data/nontagged/serde/AGeometrySerializerDeserializer.java
+++ b/asterixdb/asterix-om/src/main/java/org/apache/asterix/dataflow/data/nontagged/serde/AGeometrySerializerDeserializer.java
@@ -25,6 +25,7 @@
 import java.util.Arrays;
 
 import org.apache.asterix.common.exceptions.ErrorCode;
+import org.apache.asterix.common.exceptions.RuntimeDataException;
 import org.apache.asterix.om.base.AGeometry;
 import org.apache.hyracks.api.dataflow.value.ISerializerDeserializer;
 import org.apache.hyracks.api.exceptions.HyracksDataException;
@@ -86,7 +87,8 @@
         int size = AInt32SerializerDeserializer.getInt(bytes, startOffset);
 
         if (bytes.length < startOffset + size + 4)
-            throw HyracksDataException.create(ErrorCode.VALUE_OUT_OF_RANGE);
+            // TODO(mmahin): this error code takes 5 parameters, and this is passing none, so I suspect this isn't right
+            throw RuntimeDataException.create(ErrorCode.VALUE_OUT_OF_RANGE);
 
         // Skip the size of the geometry in first 4 bytes
         byte[] bytes1 = Arrays.copyOfRange(bytes, startOffset + 4, startOffset + size + 4);
diff --git a/asterixdb/asterix-om/src/main/java/org/apache/asterix/dataflow/data/nontagged/serde/APolygonSerializerDeserializer.java b/asterixdb/asterix-om/src/main/java/org/apache/asterix/dataflow/data/nontagged/serde/APolygonSerializerDeserializer.java
index cfbeb64..3259d59 100644
--- a/asterixdb/asterix-om/src/main/java/org/apache/asterix/dataflow/data/nontagged/serde/APolygonSerializerDeserializer.java
+++ b/asterixdb/asterix-om/src/main/java/org/apache/asterix/dataflow/data/nontagged/serde/APolygonSerializerDeserializer.java
@@ -23,6 +23,7 @@
 import java.io.IOException;
 
 import org.apache.asterix.common.exceptions.ErrorCode;
+import org.apache.asterix.common.exceptions.RuntimeDataException;
 import org.apache.asterix.dataflow.data.nontagged.Coordinate;
 import org.apache.asterix.om.base.APoint;
 import org.apache.asterix.om.base.APolygon;
@@ -70,7 +71,7 @@
             case Y:
                 return 10 + (pointId * 16);
             default:
-                throw HyracksDataException.create(ErrorCode.POLYGON_INVALID_COORDINATE);
+                throw new RuntimeDataException(ErrorCode.POLYGON_INVALID_COORDINATE);
         }
     }
 
@@ -78,7 +79,7 @@
         try {
             String[] points = polygon.split(" ");
             if (points.length < 3) {
-                throw HyracksDataException.create(ErrorCode.POLYGON_3_POINTS);
+                throw new RuntimeDataException(ErrorCode.POLYGON_3_POINTS);
             }
             out.writeByte(ATypeTag.POLYGON.serialize());
             out.writeShort(points.length);
@@ -87,7 +88,7 @@
                 APointSerializerDeserializer.serialize(Double.parseDouble(split[0]), Double.parseDouble(split[1]), out);
             }
         } catch (IOException e) {
-            throw HyracksDataException.create(ErrorCode.POLYGON_INVALID, e, polygon);
+            throw new RuntimeDataException(ErrorCode.POLYGON_INVALID, e, polygon);
         }
     }
 }
diff --git a/asterixdb/asterix-om/src/main/java/org/apache/asterix/dataflow/data/nontagged/serde/SerializerDeserializerUtil.java b/asterixdb/asterix-om/src/main/java/org/apache/asterix/dataflow/data/nontagged/serde/SerializerDeserializerUtil.java
index 952ffb4..664eb28 100644
--- a/asterixdb/asterix-om/src/main/java/org/apache/asterix/dataflow/data/nontagged/serde/SerializerDeserializerUtil.java
+++ b/asterixdb/asterix-om/src/main/java/org/apache/asterix/dataflow/data/nontagged/serde/SerializerDeserializerUtil.java
@@ -37,6 +37,10 @@
 
 public final class SerializerDeserializerUtil {
 
+    private SerializerDeserializerUtil() {
+        throw new AssertionError("do not instantiate");
+    }
+
     public static void writeIntToByteArray(byte[] array, int value, int offset) {
         array[offset] = (byte) (0xff & (value >> 24));
         array[offset + 1] = (byte) (0xff & (value >> 16));
diff --git a/asterixdb/asterix-om/src/main/java/org/apache/asterix/object/base/AdmObjectNode.java b/asterixdb/asterix-om/src/main/java/org/apache/asterix/object/base/AdmObjectNode.java
index 26024b4..294f48b 100644
--- a/asterixdb/asterix-om/src/main/java/org/apache/asterix/object/base/AdmObjectNode.java
+++ b/asterixdb/asterix-om/src/main/java/org/apache/asterix/object/base/AdmObjectNode.java
@@ -28,6 +28,7 @@
 
 import org.apache.asterix.builders.RecordBuilder;
 import org.apache.asterix.common.exceptions.ErrorCode;
+import org.apache.asterix.common.exceptions.RuntimeDataException;
 import org.apache.asterix.formats.nontagged.SerializerDeserializerProvider;
 import org.apache.asterix.om.base.AString;
 import org.apache.asterix.om.types.ATypeTag;
@@ -164,9 +165,9 @@
     public static String getString(AdmObjectNode openFields, String field) throws HyracksDataException {
         IAdmNode node = openFields.get(field);
         if (node == null) {
-            throw HyracksDataException.create(ErrorCode.FIELD_NOT_FOUND, field);
+            throw new RuntimeDataException(ErrorCode.FIELD_NOT_FOUND, field);
         } else if (node.getType() != ATypeTag.STRING) {
-            throw HyracksDataException.create(ErrorCode.FIELD_NOT_OF_TYPE, field, ATypeTag.STRING, node.getType());
+            throw new RuntimeDataException(ErrorCode.FIELD_NOT_OF_TYPE, field, ATypeTag.STRING, node.getType());
         }
         return ((AdmStringNode) node).get();
     }
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 ec844ce..ccb3a8d 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
@@ -22,13 +22,13 @@
 import java.util.function.Supplier;
 
 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;
+import org.apache.hyracks.api.exceptions.Warning;
 
 public final class ExceptionUtil {
 
@@ -102,9 +102,9 @@
             byte actualType, int argIdx, Supplier<String> expectedTypesString) {
         IWarningCollector warningCollector = ctx.getWarningCollector();
         if (warningCollector.shouldWarn()) {
-            warningCollector.warn(WarningUtil.forAsterix(srcLoc, ErrorCode.TYPE_MISMATCH_FUNCTION, fid.getName(),
-                    indexToPosition(argIdx), expectedTypesString.get(),
-                    EnumDeserializer.ATYPETAGDESERIALIZER.deserialize(actualType)));
+            warningCollector
+                    .warn(Warning.of(srcLoc, ErrorCode.TYPE_MISMATCH_FUNCTION, fid.getName(), indexToPosition(argIdx),
+                            expectedTypesString.get(), EnumDeserializer.ATYPETAGDESERIALIZER.deserialize(actualType)));
         }
     }
 
@@ -112,7 +112,7 @@
             ATypeTag type1, ATypeTag type2) {
         IWarningCollector warningCollector = ctx.getWarningCollector();
         if (warningCollector.shouldWarn()) {
-            warningCollector.warn(WarningUtil.forAsterix(srcLoc, ErrorCode.TYPE_INCOMPATIBLE, funName, type1, type2));
+            warningCollector.warn(Warning.of(srcLoc, ErrorCode.TYPE_INCOMPATIBLE, funName, type1, type2));
         }
     }
 
@@ -120,7 +120,7 @@
             ATypeTag unsupportedType) {
         IWarningCollector warningCollector = ctx.getWarningCollector();
         if (warningCollector.shouldWarn()) {
-            warningCollector.warn(WarningUtil.forAsterix(srcLoc, ErrorCode.TYPE_UNSUPPORTED, funName, unsupportedType));
+            warningCollector.warn(Warning.of(srcLoc, ErrorCode.TYPE_UNSUPPORTED, funName, unsupportedType));
         }
     }
 
@@ -128,7 +128,7 @@
             ATypeTag type2) {
         IWarningCollector warningCollector = ctx.getWarningCollector();
         if (warningCollector.shouldWarn()) {
-            warningCollector.warn(WarningUtil.forAsterix(srcLoc, ErrorCode.INCOMPARABLE_TYPES, type1, type2));
+            warningCollector.warn(Warning.of(srcLoc, ErrorCode.INCOMPARABLE_TYPES, type1, type2));
         }
     }
 
@@ -144,11 +144,11 @@
     }
 
     private static void warnInvalidValue(IEvaluatorContext ctx, SourceLocation srcLoc, FunctionIdentifier fid,
-            int argIdx, double argValue, int errorCode) {
+            int argIdx, double argValue, ErrorCode errorCode) {
         IWarningCollector warningCollector = ctx.getWarningCollector();
         if (warningCollector.shouldWarn()) {
-            warningCollector.warn(WarningUtil.forAsterix(srcLoc, errorCode, fid.getName(), indexToPosition(argIdx),
-                    Double.toString(argValue)));
+            warningCollector.warn(
+                    Warning.of(srcLoc, errorCode, fid.getName(), indexToPosition(argIdx), Double.toString(argValue)));
         }
     }
 }
diff --git a/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/exceptions/TypeMismatchException.java b/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/exceptions/TypeMismatchException.java
index e155b94..3b8602b 100644
--- a/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/exceptions/TypeMismatchException.java
+++ b/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/exceptions/TypeMismatchException.java
@@ -32,14 +32,13 @@
     private static final long serialVersionUID = -3069967719104299912L;
 
     // Function parameter type mismatch.
-    public TypeMismatchException(FunctionIdentifier fid, Integer i, ATypeTag actualTypeTag,
-            ATypeTag... expectedTypeTags) {
+    public TypeMismatchException(FunctionIdentifier fid, int i, ATypeTag actualTypeTag, ATypeTag... expectedTypeTags) {
         super(ErrorCode.COMPILATION_TYPE_MISMATCH_FUNCTION, fid.getName(), indexToPosition(i),
                 toExpectedTypeString(expectedTypeTags), actualTypeTag);
     }
 
     // Function parameter type mismatch.
-    public TypeMismatchException(SourceLocation sourceLoc, FunctionIdentifier fid, Integer i, ATypeTag actualTypeTag,
+    public TypeMismatchException(SourceLocation sourceLoc, FunctionIdentifier fid, int i, ATypeTag actualTypeTag,
             ATypeTag... expectedTypeTags) {
         super(ErrorCode.COMPILATION_TYPE_MISMATCH_FUNCTION, sourceLoc, fid.getName(), indexToPosition(i),
                 toExpectedTypeString(expectedTypeTags), actualTypeTag);
@@ -47,14 +46,14 @@
 
     // Function parameter type mismatch.
     @Deprecated
-    public TypeMismatchException(String functionName, Integer i, ATypeTag actualTypeTag, ATypeTag... expectedTypeTags) {
+    public TypeMismatchException(String functionName, int i, ATypeTag actualTypeTag, ATypeTag... expectedTypeTags) {
         super(ErrorCode.COMPILATION_TYPE_MISMATCH_FUNCTION, functionName, indexToPosition(i),
                 toExpectedTypeString(expectedTypeTags), actualTypeTag);
     }
 
     // Function parameter type mismatch.
     @Deprecated
-    public TypeMismatchException(SourceLocation sourceLoc, String functionName, Integer i, ATypeTag actualTypeTag,
+    public TypeMismatchException(SourceLocation sourceLoc, String functionName, int i, ATypeTag actualTypeTag,
             ATypeTag... expectedTypeTags) {
         super(ErrorCode.COMPILATION_TYPE_MISMATCH_FUNCTION, sourceLoc, functionName, indexToPosition(i),
                 toExpectedTypeString(expectedTypeTags), actualTypeTag);
diff --git a/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/utils/NonTaggedFormatUtil.java b/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/utils/NonTaggedFormatUtil.java
index 4f7d7e7..75bcb12 100644
--- a/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/utils/NonTaggedFormatUtil.java
+++ b/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/utils/NonTaggedFormatUtil.java
@@ -20,6 +20,7 @@
 
 import org.apache.asterix.common.config.DatasetConfig.IndexType;
 import org.apache.asterix.common.exceptions.ErrorCode;
+import org.apache.asterix.common.exceptions.RuntimeDataException;
 import org.apache.asterix.dataflow.data.nontagged.serde.AInt16SerializerDeserializer;
 import org.apache.asterix.dataflow.data.nontagged.serde.AInt32SerializerDeserializer;
 import org.apache.asterix.dataflow.data.nontagged.serde.AIntervalSerializerDeserializer;
@@ -114,7 +115,7 @@
             case ANY:
                 ATypeTag tag = EnumDeserializer.ATYPETAGDESERIALIZER.deserialize(serNonTaggedAObject[offset]);
                 if (tag == ATypeTag.ANY) {
-                    throw HyracksDataException.create(ErrorCode.FIELD_SHOULD_BE_TYPED);
+                    throw new RuntimeDataException(ErrorCode.FIELD_SHOULD_BE_TYPED);
                 }
                 return getFieldValueLength(serNonTaggedAObject, offset, tag, true) + 1;
             case MISSING:
diff --git a/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/common/FullTextContainsFunctionEvaluator.java b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/common/FullTextContainsFunctionEvaluator.java
index 3ffce9b..fce2061 100644
--- a/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/common/FullTextContainsFunctionEvaluator.java
+++ b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/common/FullTextContainsFunctionEvaluator.java
@@ -199,7 +199,7 @@
             ABoolean b = fullTextContainsWithArg(typeTag2, argLeft, argRight) ? ABoolean.TRUE : ABoolean.FALSE;
             serde.serialize(b, out);
         } catch (AlgebricksException e) {
-            throw new HyracksDataException(e, ErrorCode.ERROR_PROCESSING_TUPLE);
+            throw new HyracksDataException(ErrorCode.ERROR_PROCESSING_TUPLE, e);
         }
 
         result.set(resultStorage);
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 031445d..15d19e2 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
@@ -22,7 +22,6 @@
 import java.io.IOException;
 
 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;
@@ -41,6 +40,7 @@
 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.api.exceptions.Warning;
 import org.apache.hyracks.data.std.api.IPointable;
 import org.apache.hyracks.data.std.primitive.VoidPointable;
 import org.apache.hyracks.data.std.util.ArrayBackedValueStorage;
@@ -241,7 +241,7 @@
     private void handleOutOfRangeInput(int inputPosition, int startLimit, int endLimit, long actual) {
         IWarningCollector warningCollector = context.getWarningCollector();
         if (warningCollector.shouldWarn()) {
-            warningCollector.warn(WarningUtil.forAsterix(srcLoc, ErrorCode.VALUE_OUT_OF_RANGE, funID,
+            warningCollector.warn(Warning.of(srcLoc, ErrorCode.VALUE_OUT_OF_RANGE, funID,
                     ExceptionUtil.indexToPosition(inputPosition), startLimit, endLimit, actual));
         }
     }
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 379d70f..12e22e5 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
@@ -22,7 +22,6 @@
 import java.io.IOException;
 
 import org.apache.asterix.common.exceptions.ErrorCode;
-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;
@@ -42,6 +41,7 @@
 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.api.exceptions.Warning;
 import org.apache.hyracks.data.std.api.IPointable;
 import org.apache.hyracks.data.std.primitive.VoidPointable;
 import org.apache.hyracks.data.std.util.ArrayBackedValueStorage;
@@ -292,7 +292,7 @@
     private void handleOutOfRangeInput(int inputPosition, int startLimit, int endLimit, long actual) {
         IWarningCollector warningCollector = context.getWarningCollector();
         if (warningCollector.shouldWarn()) {
-            warningCollector.warn(WarningUtil.forAsterix(srcLoc, ErrorCode.VALUE_OUT_OF_RANGE, funID,
+            warningCollector.warn(Warning.of(srcLoc, ErrorCode.VALUE_OUT_OF_RANGE, funID,
                     ExceptionUtil.indexToPosition(inputPosition), startLimit, endLimit, actual));
         }
     }
diff --git a/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/exceptions/InvalidDataFormatException.java b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/exceptions/InvalidDataFormatException.java
index bb94ca6..ba713e3 100644
--- a/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/exceptions/InvalidDataFormatException.java
+++ b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/exceptions/InvalidDataFormatException.java
@@ -28,19 +28,17 @@
 public class InvalidDataFormatException extends RuntimeDataException {
     private static final long serialVersionUID = 7927137063741221011L;
 
-    public InvalidDataFormatException(SourceLocation sourceLoc, FunctionIdentifier fid, byte expectedTypeTag) {
-        super(ErrorCode.INVALID_FORMAT, sourceLoc, fid.getName(),
+    public InvalidDataFormatException(SourceLocation sourceLoc, FunctionIdentifier fid, Throwable cause,
+            byte expectedTypeTag) {
+        super(ErrorCode.INVALID_FORMAT, cause, sourceLoc, fid.getName(),
                 EnumDeserializer.ATYPETAGDESERIALIZER.deserialize(expectedTypeTag));
     }
 
+    public InvalidDataFormatException(SourceLocation sourceLoc, FunctionIdentifier fid, byte expectedTypeTag) {
+        this(sourceLoc, fid, null, expectedTypeTag);
+    }
+
     public InvalidDataFormatException(SourceLocation sourceLoc, FunctionIdentifier fid, String expectedType) {
         super(ErrorCode.INVALID_FORMAT, sourceLoc, fid.getName(), expectedType);
     }
-
-    public InvalidDataFormatException(SourceLocation sourceLoc, FunctionIdentifier fid, Throwable cause,
-            byte expectedTypeTag) {
-        super(ErrorCode.INVALID_FORMAT, sourceLoc, fid.getName(), cause, expectedTypeTag);
-        addSuppressed(cause);
-    }
-
 }
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 e510fba..f51c305 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
@@ -32,14 +32,14 @@
     private static final long serialVersionUID = -668005043013338591L;
 
     // Function parameter type mismatch.
-    public TypeMismatchException(FunctionIdentifier fid, Integer i, byte actualTypeTag, byte... expectedTypeTags) {
+    public TypeMismatchException(FunctionIdentifier fid, int i, byte actualTypeTag, byte... expectedTypeTags) {
         super(ErrorCode.TYPE_MISMATCH_FUNCTION, fid.getName(), indexToPosition(i),
                 toExpectedTypeString(expectedTypeTags),
                 EnumDeserializer.ATYPETAGDESERIALIZER.deserialize(actualTypeTag));
     }
 
     // Function parameter type mismatch.
-    public TypeMismatchException(SourceLocation sourceLoc, FunctionIdentifier fid, Integer i, byte actualTypeTag,
+    public TypeMismatchException(SourceLocation sourceLoc, FunctionIdentifier fid, int i, byte actualTypeTag,
             byte... expectedTypeTags) {
         super(ErrorCode.TYPE_MISMATCH_FUNCTION, sourceLoc, fid.getName(), indexToPosition(i),
                 toExpectedTypeString(expectedTypeTags),
@@ -47,7 +47,7 @@
     }
 
     // Function parameter type mismatch.
-    public TypeMismatchException(SourceLocation sourceLoc, FunctionIdentifier fid, Integer i, byte actualTypeTag,
+    public TypeMismatchException(SourceLocation sourceLoc, FunctionIdentifier fid, int i, byte actualTypeTag,
             String expectedType) {
         super(ErrorCode.TYPE_MISMATCH_FUNCTION, sourceLoc, fid.getName(), indexToPosition(i), expectedType,
                 EnumDeserializer.ATYPETAGDESERIALIZER.deserialize(actualTypeTag));
@@ -55,7 +55,7 @@
 
     // Function parameter type mismatch.
     @Deprecated
-    public TypeMismatchException(String functionName, Integer i, byte actualTypeTag, byte... expectedTypeTags) {
+    public TypeMismatchException(String functionName, int i, byte actualTypeTag, byte... expectedTypeTags) {
         super(ErrorCode.TYPE_MISMATCH_FUNCTION, functionName, indexToPosition(i),
                 toExpectedTypeString(expectedTypeTags),
                 EnumDeserializer.ATYPETAGDESERIALIZER.deserialize(actualTypeTag));
@@ -63,7 +63,7 @@
 
     // Function parameter type mismatch.
     @Deprecated
-    public TypeMismatchException(SourceLocation sourceLoc, String functionName, Integer i, byte actualTypeTag,
+    public TypeMismatchException(SourceLocation sourceLoc, String functionName, int i, byte actualTypeTag,
             byte... expectedTypeTags) {
         super(ErrorCode.TYPE_MISMATCH_FUNCTION, sourceLoc, functionName, indexToPosition(i),
                 toExpectedTypeString(expectedTypeTags),
diff --git a/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/message/ResourceIdRequestMessage.java b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/message/ResourceIdRequestMessage.java
index fbfca55..6198acc 100644
--- a/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/message/ResourceIdRequestMessage.java
+++ b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/message/ResourceIdRequestMessage.java
@@ -26,11 +26,13 @@
 import org.apache.hyracks.api.exceptions.HyracksDataException;
 
 public class ResourceIdRequestMessage implements ICcAddressedMessage {
-    private static final long serialVersionUID = 1L;
+    private static final long serialVersionUID = 2L;
     private final String src;
+    private final int blockSize;
 
-    public ResourceIdRequestMessage(String src) {
+    public ResourceIdRequestMessage(String src, int blockSize) {
         this.src = src;
+        this.blockSize = blockSize;
     }
 
     @Override
@@ -40,11 +42,11 @@
             ResourceIdRequestResponseMessage response = new ResourceIdRequestResponseMessage();
             IClusterStateManager clusterStateManager = appCtx.getClusterStateManager();
             IResourceIdManager resourceIdManager = appCtx.getResourceIdManager();
-            response.setResourceId(resourceIdManager.createResourceId());
+            response.setResourceIdBlock(resourceIdManager.createResourceIdBlock(blockSize), blockSize);
             if (response.getResourceId() < 0) {
                 if (!(clusterStateManager.isClusterActive())) {
                     response.setException(
-                            new Exception("Cannot generate global resource id when cluster is not active."));
+                            new Exception("Cannot generate global resource id(s) when cluster is not active."));
                 } else {
                     response.setException(new Exception("One or more nodes has not reported max resource id."));
                 }
diff --git a/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/message/ResourceIdRequestResponseMessage.java b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/message/ResourceIdRequestResponseMessage.java
index 6a9ed35..05e6b12 100644
--- a/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/message/ResourceIdRequestResponseMessage.java
+++ b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/message/ResourceIdRequestResponseMessage.java
@@ -24,19 +24,30 @@
 import org.apache.hyracks.api.exceptions.HyracksDataException;
 
 public class ResourceIdRequestResponseMessage implements INcAddressedMessage {
-    private static final long serialVersionUID = 1L;
+    private static final long serialVersionUID = 2L;
 
     private long resourceId;
+    private int blockSize = 1;
+
     private Exception exception;
 
     public long getResourceId() {
         return resourceId;
     }
 
+    public int getBlockSize() {
+        return blockSize;
+    }
+
     public void setResourceId(long resourceId) {
         this.resourceId = resourceId;
     }
 
+    public void setResourceIdBlock(long resourceId, int blockSize) {
+        this.resourceId = resourceId;
+        this.blockSize = blockSize;
+    }
+
     public Exception getException() {
         return exception;
     }
@@ -52,6 +63,7 @@
 
     @Override
     public String toString() {
-        return ResourceIdRequestResponseMessage.class.getSimpleName();
+        return "ResourceIdRequestResponseMessage{" + "resourceId=" + resourceId + ", blockSize=" + blockSize
+                + ", exception=" + exception + '}';
     }
 }
diff --git a/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/transaction/GlobalResourceIdFactory.java b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/transaction/GlobalResourceIdFactory.java
index 78b1f17..2bd4f81 100644
--- a/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/transaction/GlobalResourceIdFactory.java
+++ b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/transaction/GlobalResourceIdFactory.java
@@ -18,6 +18,7 @@
  */
 package org.apache.asterix.runtime.transaction;
 
+import java.util.NoSuchElementException;
 import java.util.concurrent.LinkedBlockingQueue;
 
 import org.apache.asterix.common.messaging.api.INCMessageBroker;
@@ -26,6 +27,12 @@
 import org.apache.hyracks.api.application.INCServiceContext;
 import org.apache.hyracks.api.exceptions.HyracksDataException;
 import org.apache.hyracks.storage.common.file.IResourceIdFactory;
+import org.apache.logging.log4j.LogManager;
+import org.apache.logging.log4j.Logger;
+
+import it.unimi.dsi.fastutil.longs.LongArrayFIFOQueue;
+import it.unimi.dsi.fastutil.longs.LongPriorityQueue;
+import it.unimi.dsi.fastutil.longs.LongPriorityQueues;
 
 /**
  * A resource id factory that generates unique resource ids across all NCs by requesting
@@ -33,7 +40,11 @@
  */
 public class GlobalResourceIdFactory implements IResourceIdFactory {
 
+    private static final Logger LOGGER = LogManager.getLogger();
+    private static final int RESOURCE_ID_BLOCK_SIZE = 25;
     private final INCServiceContext serviceCtx;
+    private final LongPriorityQueue resourceIds =
+            LongPriorityQueues.synchronize(new LongArrayFIFOQueue(RESOURCE_ID_BLOCK_SIZE));
     private final LinkedBlockingQueue<ResourceIdRequestResponseMessage> resourceIdResponseQ;
     private final String nodeId;
 
@@ -44,33 +55,51 @@
     }
 
     public void addNewIds(ResourceIdRequestResponseMessage resourceIdResponse) throws InterruptedException {
+        LOGGER.debug("rec'd block of ids: {}", resourceIdResponse);
         resourceIdResponseQ.put(resourceIdResponse);
     }
 
     @Override
     public long createId() throws HyracksDataException {
         try {
-            ResourceIdRequestResponseMessage reponse = null;
-            //if there already exists a response, use it
-            if (!resourceIdResponseQ.isEmpty()) {
-                synchronized (resourceIdResponseQ) {
-                    if (!resourceIdResponseQ.isEmpty()) {
-                        reponse = resourceIdResponseQ.take();
+            final long resourceId = resourceIds.dequeueLong();
+            if (resourceIds.isEmpty()) {
+                serviceCtx.getControllerService().getExecutor().submit(() -> {
+                    try {
+                        requestNewBlock();
+                    } catch (Exception e) {
+                        LOGGER.warn("failed on preemptive block request", e);
                     }
-                }
+                });
             }
-            //if no response available or it has an exception, request a new one
-            if (reponse == null || reponse.getException() != null) {
-                ResourceIdRequestMessage msg = new ResourceIdRequestMessage(nodeId);
-                ((INCMessageBroker) serviceCtx.getMessageBroker()).sendMessageToPrimaryCC(msg);
-                reponse = resourceIdResponseQ.take();
-                if (reponse.getException() != null) {
-                    throw HyracksDataException.create(reponse.getException());
-                }
+            return resourceId;
+        } catch (NoSuchElementException e) {
+            // fallthrough
+        }
+        try {
+            // if there already exists a response, use it
+            ResourceIdRequestResponseMessage response = resourceIdResponseQ.poll();
+            if (response == null) {
+                requestNewBlock();
+                response = resourceIdResponseQ.take();
             }
-            return reponse.getResourceId();
+            if (response.getException() != null) {
+                throw HyracksDataException.create(response.getException());
+            }
+            // take the first id, queue the rest
+            final long startingId = response.getResourceId();
+            for (int i = 1; i < response.getBlockSize(); i++) {
+                resourceIds.enqueue(startingId + i);
+            }
+            return startingId;
         } catch (Exception e) {
             throw HyracksDataException.create(e);
         }
     }
+
+    protected void requestNewBlock() throws Exception {
+        // queue is empty; request a new block
+        ResourceIdRequestMessage msg = new ResourceIdRequestMessage(nodeId, RESOURCE_ID_BLOCK_SIZE);
+        ((INCMessageBroker) serviceCtx.getMessageBroker()).sendMessageToPrimaryCC(msg);
+    }
 }
diff --git a/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/transaction/ResourceIdManager.java b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/transaction/ResourceIdManager.java
index 5bcd5aa..8b4fd68 100644
--- a/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/transaction/ResourceIdManager.java
+++ b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/transaction/ResourceIdManager.java
@@ -37,8 +37,11 @@
 
     @Override
     public long createResourceId() {
-        return csm.isClusterActive() || reportedNodes.containsAll(csm.getParticipantNodes(true))
-                ? globalResourceId.incrementAndGet() : -1;
+        return readyState() ? globalResourceId.incrementAndGet() : -1;
+    }
+
+    protected boolean readyState() {
+        return csm.isClusterActive() || reportedNodes.containsAll(csm.getParticipantNodes(true));
     }
 
     @Override
@@ -51,4 +54,9 @@
         globalResourceId.updateAndGet(prev -> Math.max(maxResourceId, prev));
         reportedNodes.add(nodeId);
     }
+
+    @Override
+    public long createResourceIdBlock(int blockSize) {
+        return readyState() ? globalResourceId.getAndAdd(blockSize) + 1 : -1;
+    }
 }
diff --git a/asterixdb/asterix-runtime/src/test/java/org/apache/asterix/runtime/job/resource/JobCapacityControllerTest.java b/asterixdb/asterix-runtime/src/test/java/org/apache/asterix/runtime/job/resource/JobCapacityControllerTest.java
index 4a63885..48c61b4 100644
--- a/asterixdb/asterix-runtime/src/test/java/org/apache/asterix/runtime/job/resource/JobCapacityControllerTest.java
+++ b/asterixdb/asterix-runtime/src/test/java/org/apache/asterix/runtime/job/resource/JobCapacityControllerTest.java
@@ -53,7 +53,7 @@
         try {
             capacityController.allocate(makeJobWithRequiredCapacity(2147483648L, 64));
         } catch (HyracksException e) {
-            exceedCapacity = e.getErrorCode() == ErrorCode.JOB_REQUIREMENTS_EXCEED_CAPACITY;
+            exceedCapacity = e.matches(ErrorCode.JOB_REQUIREMENTS_EXCEED_CAPACITY);
         }
         Assert.assertTrue(exceedCapacity);
         Assert.assertTrue(capacityController.allocate(
@@ -62,7 +62,7 @@
         try {
             capacityController.allocate(makeJobWithRequiredCapacity(4294967297L, 33));
         } catch (HyracksException e) {
-            exceedCapacity = e.getErrorCode() == ErrorCode.JOB_REQUIREMENTS_EXCEED_CAPACITY;
+            exceedCapacity = e.matches(ErrorCode.JOB_REQUIREMENTS_EXCEED_CAPACITY);
         }
         Assert.assertTrue(exceedCapacity);
 
diff --git a/asterixdb/asterix-server/pom.xml b/asterixdb/asterix-server/pom.xml
index 459f370..faf5780 100644
--- a/asterixdb/asterix-server/pom.xml
+++ b/asterixdb/asterix-server/pom.xml
@@ -858,5 +858,13 @@
       <groupId>org.apache.httpcomponents</groupId>
       <artifactId>httpmime</artifactId>
     </dependency>
+    <dependency>
+      <groupId>org.apache.hyracks</groupId>
+      <artifactId>algebricks-core</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.hyracks</groupId>
+      <artifactId>hyracks-api</artifactId>
+    </dependency>
   </dependencies>
 </project>
diff --git a/asterixdb/asterix-server/src/test/java/org/apache/asterix/test/server/FormattedExceptionInstanceTest.java b/asterixdb/asterix-server/src/test/java/org/apache/asterix/test/server/FormattedExceptionInstanceTest.java
new file mode 100644
index 0000000..ab53023
--- /dev/null
+++ b/asterixdb/asterix-server/src/test/java/org/apache/asterix/test/server/FormattedExceptionInstanceTest.java
@@ -0,0 +1,56 @@
+/*
+ * 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.test.server;
+
+import java.lang.reflect.Executable;
+
+import org.apache.asterix.common.exceptions.ErrorCode;
+import org.apache.hyracks.algebricks.core.algebra.functions.FunctionIdentifier;
+import org.apache.hyracks.api.exceptions.IFormattedException;
+import org.apache.hyracks.test.support.FormattedExceptionTestBase;
+import org.junit.runners.Parameterized;
+
+public class FormattedExceptionInstanceTest extends FormattedExceptionTestBase {
+    private static final ErrorCode ASK_ERROR_CODE = random(ErrorCode.values());
+    private static final FunctionIdentifier FUNCTION_IDENTIFIER = new FunctionIdentifier("fake", "fake", 0);
+    static {
+        classSelector = classname -> classname.matches("^org\\.apache\\.(asterix|hyracks)\\..*");
+    }
+
+    public FormattedExceptionInstanceTest(String desc, Executable action, Class<? extends IFormattedException> root) {
+        super(desc, action, root);
+    }
+
+    @Parameterized.Parameters(name = "{index}: {0}")
+    public static Iterable<Object[]> data() throws ClassNotFoundException {
+        return defineParameters();
+    }
+
+    @Override
+    protected Object defaultValue(Class type) {
+        switch (type.getName()) {
+            case "org.apache.hyracks.algebricks.core.algebra.functions.FunctionIdentifier":
+                return FUNCTION_IDENTIFIER;
+            case "org.apache.asterix.common.exceptions.ErrorCode":
+                return ASK_ERROR_CODE;
+            default:
+                return super.defaultValue(type);
+        }
+    }
+}
diff --git a/hyracks-fullstack/algebricks/algebricks-common/src/main/java/org/apache/hyracks/algebricks/common/exceptions/AlgebricksException.java b/hyracks-fullstack/algebricks/algebricks-common/src/main/java/org/apache/hyracks/algebricks/common/exceptions/AlgebricksException.java
index ac22b60..f00161c 100644
--- a/hyracks-fullstack/algebricks/algebricks-common/src/main/java/org/apache/hyracks/algebricks/common/exceptions/AlgebricksException.java
+++ b/hyracks-fullstack/algebricks/algebricks-common/src/main/java/org/apache/hyracks/algebricks/common/exceptions/AlgebricksException.java
@@ -19,8 +19,10 @@
 package org.apache.hyracks.algebricks.common.exceptions;
 
 import java.io.Serializable;
+import java.util.Optional;
 
 import org.apache.hyracks.api.exceptions.ErrorCode;
+import org.apache.hyracks.api.exceptions.IError;
 import org.apache.hyracks.api.exceptions.IFormattedException;
 import org.apache.hyracks.api.exceptions.SourceLocation;
 import org.apache.hyracks.api.util.ErrorMessageUtil;
@@ -34,13 +36,23 @@
     private final Serializable[] params;
     private final String nodeId;
     private final SourceLocation sourceLoc;
+    protected final transient IError error;
 
     @SuppressWarnings("squid:S1165") // exception class not final
-    private transient CachedMessage msgCache;
+    private transient volatile String msgCache;
 
-    public AlgebricksException(String component, int errorCode, String message, Throwable cause,
+    public static AlgebricksException create(ErrorCode error, SourceLocation sourceLoc, Serializable... params) {
+        return new AlgebricksException(error, sourceLoc, params);
+    }
+
+    public static AlgebricksException create(ErrorCode error, Serializable... params) {
+        return create(error, null, params);
+    }
+
+    protected AlgebricksException(IError error, String component, int errorCode, String message, Throwable cause,
             SourceLocation sourceLoc, String nodeId, Serializable... params) {
         super(message, cause);
+        this.error = error;
         this.component = component;
         this.errorCode = errorCode;
         this.sourceLoc = sourceLoc;
@@ -53,7 +65,7 @@
      */
     @Deprecated
     public AlgebricksException(String message) {
-        this(ErrorMessageUtil.NONE, UNKNOWN, message, null, null, (Serializable[]) null);
+        this((IError) null, ErrorMessageUtil.NONE, UNKNOWN, message, null, null, null);
     }
 
     /**
@@ -61,7 +73,7 @@
      */
     @Deprecated
     public AlgebricksException(Throwable cause) {
-        this(ErrorMessageUtil.NONE, UNKNOWN, cause.getMessage(), cause, (Serializable[]) null);
+        this(String.valueOf(cause), cause);
     }
 
     /**
@@ -69,60 +81,23 @@
      */
     @Deprecated
     public AlgebricksException(String message, Throwable cause) {
-        this(ErrorMessageUtil.NONE, UNKNOWN, message, cause, null, (Serializable[]) null);
+        this((IError) null, ErrorMessageUtil.NONE, UNKNOWN, message, cause, null, null);
     }
 
-    public AlgebricksException(String component, int errorCode, SourceLocation sourceLoc, Serializable... params) {
-        this(component, errorCode, null, null, sourceLoc, null, params);
+    public AlgebricksException(Throwable cause, ErrorCode error, Serializable... params) {
+        this(error, error.component(), error.intValue(), error.errorMessage(), cause, null, null, params);
     }
 
-    public AlgebricksException(String component, int errorCode, Serializable... params) {
-        this(component, errorCode, null, null, null, null, params);
+    public AlgebricksException(ErrorCode error, SourceLocation sourceLoc, Serializable... params) {
+        this(error, error.component(), error.intValue(), error.errorMessage(), null, sourceLoc, null, params);
     }
 
-    public AlgebricksException(Throwable cause, int errorCode, SourceLocation sourceLoc, Serializable... params) {
-        this(ErrorMessageUtil.NONE, errorCode, cause.getMessage(), cause, sourceLoc, null, params);
+    public AlgebricksException(ErrorCode error, Serializable... params) {
+        this(error, null, params);
     }
 
-    public AlgebricksException(Throwable cause, int errorCode, Serializable... params) {
-        this(ErrorMessageUtil.NONE, errorCode, cause.getMessage(), cause, null, null, params);
-    }
-
-    public AlgebricksException(String component, int errorCode, String message, SourceLocation sourceLoc,
-            Serializable... params) {
-        this(component, errorCode, message, null, sourceLoc, null, params);
-    }
-
-    public AlgebricksException(String component, int errorCode, String message, Serializable... params) {
-        this(component, errorCode, message, null, null, null, params);
-    }
-
-    public AlgebricksException(String component, int errorCode, Throwable cause, SourceLocation sourceLoc,
-            Serializable... params) {
-        this(component, errorCode, cause.getMessage(), cause, sourceLoc, null, params);
-    }
-
-    public AlgebricksException(String component, int errorCode, Throwable cause, Serializable... params) {
-        this(component, errorCode, cause.getMessage(), cause, null, null, params);
-    }
-
-    public AlgebricksException(String component, int errorCode, String message, Throwable cause,
-            SourceLocation sourceLoc, Serializable... params) {
-        this(component, errorCode, message, cause, sourceLoc, null, params);
-    }
-
-    public AlgebricksException(String component, int errorCode, String message, Throwable cause,
-            Serializable... params) {
-        this(component, errorCode, message, cause, null, null, params);
-    }
-
-    public static AlgebricksException create(int errorCode, SourceLocation sourceLoc, Serializable... params) {
-        return new AlgebricksException(ErrorCode.HYRACKS, errorCode, ErrorCode.getErrorMessage(errorCode), sourceLoc,
-                params);
-    }
-
-    public static AlgebricksException create(int errorCode, Serializable... params) {
-        return create(errorCode, null, params);
+    protected AlgebricksException(IError error, Throwable cause, SourceLocation sourceLoc, Serializable... params) {
+        this(error, error.component(), error.intValue(), error.errorMessage(), cause, sourceLoc, null, params);
     }
 
     @Override
@@ -148,19 +123,15 @@
     }
 
     @Override
-    public String getMessage() {
-        if (msgCache == null) {
-            msgCache = new CachedMessage(
-                    ErrorMessageUtil.formatMessage(component, errorCode, super.getMessage(), sourceLoc, params));
-        }
-        return msgCache.message;
+    public Optional<IError> getError() {
+        return Optional.ofNullable(error);
     }
 
-    private static class CachedMessage {
-        private final String message;
-
-        private CachedMessage(String message) {
-            this.message = message;
+    @Override
+    public String getMessage() {
+        if (msgCache == null) {
+            msgCache = ErrorMessageUtil.formatMessage(component, errorCode, super.getMessage(), sourceLoc, params);
         }
+        return msgCache;
     }
 }
diff --git a/hyracks-fullstack/algebricks/algebricks-core/src/main/java/org/apache/hyracks/algebricks/core/algebra/operators/physical/AbstractWindowPOperator.java b/hyracks-fullstack/algebricks/algebricks-core/src/main/java/org/apache/hyracks/algebricks/core/algebra/operators/physical/AbstractWindowPOperator.java
index 0b3a79c..560435e 100644
--- a/hyracks-fullstack/algebricks/algebricks-core/src/main/java/org/apache/hyracks/algebricks/core/algebra/operators/physical/AbstractWindowPOperator.java
+++ b/hyracks-fullstack/algebricks/algebricks-core/src/main/java/org/apache/hyracks/algebricks/core/algebra/operators/physical/AbstractWindowPOperator.java
@@ -102,8 +102,8 @@
             OrderColumn oc = orderColumns.get(oIdx);
             LogicalVariable ocVar = oc.getColumn();
             if (!pcVars.remove(ocVar) && containsAny(orderColumns, oIdx + 1, pcVars)) {
-                throw new AlgebricksException(ErrorCode.HYRACKS, ErrorCode.UNSUPPORTED_WINDOW_SPEC,
-                        op.getSourceLocation(), String.valueOf(partitionColumns), String.valueOf(orderColumns));
+                throw AlgebricksException.create(ErrorCode.UNSUPPORTED_WINDOW_SPEC, op.getSourceLocation(),
+                        String.valueOf(partitionColumns), String.valueOf(orderColumns));
             }
             lopColumns.add(new OrderColumn(oc.getColumn(), oc.getOrder()));
         }
diff --git a/hyracks-fullstack/algebricks/algebricks-core/src/main/java/org/apache/hyracks/algebricks/core/algebra/prettyprint/LogicalOperatorPrettyPrintVisitorJson.java b/hyracks-fullstack/algebricks/algebricks-core/src/main/java/org/apache/hyracks/algebricks/core/algebra/prettyprint/LogicalOperatorPrettyPrintVisitorJson.java
index 4548537..f404058 100644
--- a/hyracks-fullstack/algebricks/algebricks-core/src/main/java/org/apache/hyracks/algebricks/core/algebra/prettyprint/LogicalOperatorPrettyPrintVisitorJson.java
+++ b/hyracks-fullstack/algebricks/algebricks-core/src/main/java/org/apache/hyracks/algebricks/core/algebra/prettyprint/LogicalOperatorPrettyPrintVisitorJson.java
@@ -180,7 +180,7 @@
                 jsonGenerator.writeEndArray();
             }
         } catch (IOException e) {
-            throw new AlgebricksException(e, ErrorCode.ERROR_PRINTING_PLAN);
+            throw AlgebricksException.create(ErrorCode.ERROR_PRINTING_PLAN, e, String.valueOf(e));
         }
     }
 
@@ -203,7 +203,7 @@
             }
             jsonGenerator.writeEndObject();
         } catch (IOException e) {
-            throw new AlgebricksException(e, ErrorCode.ERROR_PRINTING_PLAN);
+            throw AlgebricksException.create(ErrorCode.ERROR_PRINTING_PLAN, e, String.valueOf(e));
         }
     }
 
@@ -224,7 +224,7 @@
             writeVariablesAndExpressions(op.getVariables(), op.getExpressions(), indent);
             return null;
         } catch (IOException e) {
-            throw new AlgebricksException(e, ErrorCode.ERROR_PRINTING_PLAN);
+            throw AlgebricksException.create(ErrorCode.ERROR_PRINTING_PLAN, e, String.valueOf(e));
         }
     }
 
@@ -235,7 +235,7 @@
             writeVariablesAndExpressions(op.getVariables(), op.getExpressions(), indent);
             return null;
         } catch (IOException e) {
-            throw new AlgebricksException(e, ErrorCode.ERROR_PRINTING_PLAN);
+            throw AlgebricksException.create(ErrorCode.ERROR_PRINTING_PLAN, e, String.valueOf(e));
         }
     }
 
@@ -245,7 +245,7 @@
             jsonGenerator.writeStringField(OPERATOR_FIELD, "empty-tuple-source");
             return null;
         } catch (IOException e) {
-            throw new AlgebricksException(e, ErrorCode.ERROR_PRINTING_PLAN);
+            throw AlgebricksException.create(ErrorCode.ERROR_PRINTING_PLAN, e, String.valueOf(e));
         }
     }
 
@@ -267,7 +267,7 @@
             }
             return null;
         } catch (IOException e) {
-            throw new AlgebricksException(e, ErrorCode.ERROR_PRINTING_PLAN);
+            throw AlgebricksException.create(ErrorCode.ERROR_PRINTING_PLAN, e, String.valueOf(e));
         }
     }
 
@@ -281,7 +281,7 @@
             }
             return null;
         } catch (IOException e) {
-            throw new AlgebricksException(e, ErrorCode.ERROR_PRINTING_PLAN);
+            throw AlgebricksException.create(ErrorCode.ERROR_PRINTING_PLAN, e, String.valueOf(e));
         }
     }
 
@@ -292,7 +292,7 @@
             writeStringFieldExpression(CONDITION_FIELD, op.getCondition(), indent);
             return null;
         } catch (IOException e) {
-            throw new AlgebricksException(e, ErrorCode.ERROR_PRINTING_PLAN);
+            throw AlgebricksException.create(ErrorCode.ERROR_PRINTING_PLAN, e, String.valueOf(e));
         }
     }
 
@@ -303,7 +303,7 @@
             writeStringFieldExpression(CONDITION_FIELD, op.getCondition(), indent);
             return null;
         } catch (IOException e) {
-            throw new AlgebricksException(e, ErrorCode.ERROR_PRINTING_PLAN);
+            throw AlgebricksException.create(ErrorCode.ERROR_PRINTING_PLAN, e, String.valueOf(e));
         }
     }
 
@@ -313,7 +313,7 @@
             jsonGenerator.writeStringField(OPERATOR_FIELD, "nested-tuple-source");
             return null;
         } catch (IOException e) {
-            throw new AlgebricksException(e, ErrorCode.ERROR_PRINTING_PLAN);
+            throw AlgebricksException.create(ErrorCode.ERROR_PRINTING_PLAN, e, String.valueOf(e));
         }
     }
 
@@ -328,7 +328,7 @@
             writeArrayFieldOfOrderExprList("order-by-list", op.getOrderExpressions(), indent);
             return null;
         } catch (IOException e) {
-            throw new AlgebricksException(e, ErrorCode.ERROR_PRINTING_PLAN);
+            throw AlgebricksException.create(ErrorCode.ERROR_PRINTING_PLAN, e, String.valueOf(e));
         }
     }
 
@@ -339,7 +339,7 @@
             writeVariablesAndExpressions(op.getVariables(), op.getExpressions(), indent);
             return null;
         } catch (IOException e) {
-            throw new AlgebricksException(e, ErrorCode.ERROR_PRINTING_PLAN);
+            throw AlgebricksException.create(ErrorCode.ERROR_PRINTING_PLAN, e, String.valueOf(e));
         }
     }
 
@@ -353,7 +353,7 @@
             }
             return null;
         } catch (IOException e) {
-            throw new AlgebricksException(e, ErrorCode.ERROR_PRINTING_PLAN);
+            throw AlgebricksException.create(ErrorCode.ERROR_PRINTING_PLAN, e, String.valueOf(e));
         }
     }
 
@@ -367,7 +367,7 @@
             }
             return null;
         } catch (IOException e) {
-            throw new AlgebricksException(e, ErrorCode.ERROR_PRINTING_PLAN);
+            throw AlgebricksException.create(ErrorCode.ERROR_PRINTING_PLAN, e, String.valueOf(e));
         }
     }
 
@@ -380,7 +380,7 @@
             writeObjectFieldWithExpressions("partitioned-by", op.getKeyExpressions(), indent);
             return null;
         } catch (IOException e) {
-            throw new AlgebricksException(e, ErrorCode.ERROR_PRINTING_PLAN);
+            throw AlgebricksException.create(ErrorCode.ERROR_PRINTING_PLAN, e, String.valueOf(e));
         }
     }
 
@@ -391,7 +391,7 @@
             writeStringFieldExpression(CONDITION_FIELD, op.getCondition(), indent);
             return null;
         } catch (IOException e) {
-            throw new AlgebricksException(e, ErrorCode.ERROR_PRINTING_PLAN);
+            throw AlgebricksException.create(ErrorCode.ERROR_PRINTING_PLAN, e, String.valueOf(e));
         }
     }
 
@@ -405,7 +405,7 @@
             }
             return null;
         } catch (IOException e) {
-            throw new AlgebricksException(e, ErrorCode.ERROR_PRINTING_PLAN);
+            throw AlgebricksException.create(ErrorCode.ERROR_PRINTING_PLAN, e, String.valueOf(e));
         }
     }
 
@@ -432,7 +432,7 @@
             jsonGenerator.writeEndArray();
             return null;
         } catch (IOException e) {
-            throw new AlgebricksException(e, ErrorCode.ERROR_PRINTING_PLAN);
+            throw AlgebricksException.create(ErrorCode.ERROR_PRINTING_PLAN, e, String.valueOf(e));
         }
     }
 
@@ -450,7 +450,7 @@
             }
             return null;
         } catch (IOException e) {
-            throw new AlgebricksException(e, ErrorCode.ERROR_PRINTING_PLAN);
+            throw AlgebricksException.create(ErrorCode.ERROR_PRINTING_PLAN, e, String.valueOf(e));
         }
     }
 
@@ -473,7 +473,7 @@
             writeSelectLimitInformation(op.getSelectCondition(), op.getOutputLimit(), indent);
             return null;
         } catch (IOException e) {
-            throw new AlgebricksException(e, ErrorCode.ERROR_PRINTING_PLAN);
+            throw AlgebricksException.create(ErrorCode.ERROR_PRINTING_PLAN, e, String.valueOf(e));
         }
     }
 
@@ -503,7 +503,7 @@
             writeProjectInformation(op.getProjectionInfo());
             return null;
         } catch (IOException e) {
-            throw new AlgebricksException(e, ErrorCode.ERROR_PRINTING_PLAN);
+            throw AlgebricksException.create(ErrorCode.ERROR_PRINTING_PLAN, e, String.valueOf(e));
         }
     }
 
@@ -519,7 +519,7 @@
             }
             return null;
         } catch (IOException e) {
-            throw new AlgebricksException(e, ErrorCode.ERROR_PRINTING_PLAN);
+            throw AlgebricksException.create(ErrorCode.ERROR_PRINTING_PLAN, e, String.valueOf(e));
         }
     }
 
@@ -529,7 +529,7 @@
             jsonGenerator.writeStringField(OPERATOR_FIELD, "exchange");
             return null;
         } catch (IOException e) {
-            throw new AlgebricksException(e, ErrorCode.ERROR_PRINTING_PLAN);
+            throw AlgebricksException.create(ErrorCode.ERROR_PRINTING_PLAN, e, String.valueOf(e));
         }
     }
 
@@ -547,7 +547,7 @@
             }
             return null;
         } catch (IOException e) {
-            throw new AlgebricksException(e, ErrorCode.ERROR_PRINTING_PLAN);
+            throw AlgebricksException.create(ErrorCode.ERROR_PRINTING_PLAN, e, String.valueOf(e));
         }
     }
 
@@ -557,7 +557,7 @@
             jsonGenerator.writeStringField(OPERATOR_FIELD, "replicate");
             return null;
         } catch (IOException e) {
-            throw new AlgebricksException(e, ErrorCode.ERROR_PRINTING_PLAN);
+            throw AlgebricksException.create(ErrorCode.ERROR_PRINTING_PLAN, e, String.valueOf(e));
         }
     }
 
@@ -568,7 +568,7 @@
             writeStringFieldExpression(EXPRESSION_FIELD, op.getBranchingExpression(), indent);
             return null;
         } catch (IOException e) {
-            throw new AlgebricksException(e, ErrorCode.ERROR_PRINTING_PLAN);
+            throw AlgebricksException.create(ErrorCode.ERROR_PRINTING_PLAN, e, String.valueOf(e));
         }
     }
 
@@ -578,7 +578,7 @@
             jsonGenerator.writeStringField(OPERATOR_FIELD, "materialize");
             return null;
         } catch (IOException e) {
-            throw new AlgebricksException(e, ErrorCode.ERROR_PRINTING_PLAN);
+            throw AlgebricksException.create(ErrorCode.ERROR_PRINTING_PLAN, e, String.valueOf(e));
         }
     }
 
@@ -606,7 +606,7 @@
             }
             return null;
         } catch (IOException e) {
-            throw new AlgebricksException(e, ErrorCode.ERROR_PRINTING_PLAN);
+            throw AlgebricksException.create(ErrorCode.ERROR_PRINTING_PLAN, e, String.valueOf(e));
         }
     }
 
@@ -630,7 +630,7 @@
             }
             return null;
         } catch (IOException e) {
-            throw new AlgebricksException(e, ErrorCode.ERROR_PRINTING_PLAN);
+            throw AlgebricksException.create(ErrorCode.ERROR_PRINTING_PLAN, e, String.valueOf(e));
         }
     }
 
@@ -641,7 +641,7 @@
             writeVariablesAndExpressions(op.getTokenizeVars(), op.getSecondaryKeyExpressions(), indent);
             return null;
         } catch (IOException e) {
-            throw new AlgebricksException(e, ErrorCode.ERROR_PRINTING_PLAN);
+            throw AlgebricksException.create(ErrorCode.ERROR_PRINTING_PLAN, e, String.valueOf(e));
         }
     }
 
@@ -652,7 +652,7 @@
             writeStringFieldExpression(EXPRESSION_FIELD, op.getSideDataExpression(), indent);
             return null;
         } catch (IOException e) {
-            throw new AlgebricksException(e, ErrorCode.ERROR_PRINTING_PLAN);
+            throw AlgebricksException.create(ErrorCode.ERROR_PRINTING_PLAN, e, String.valueOf(e));
         }
     }
 
@@ -662,7 +662,7 @@
             jsonGenerator.writeStringField(OPERATOR_FIELD, "sink");
             return null;
         } catch (IOException e) {
-            throw new AlgebricksException(e, ErrorCode.ERROR_PRINTING_PLAN);
+            throw AlgebricksException.create(ErrorCode.ERROR_PRINTING_PLAN, e, String.valueOf(e));
         }
     }
 
@@ -672,7 +672,7 @@
             jsonGenerator.writeStringField(OPERATOR_FIELD, op.toString());
             return null;
         } catch (IOException e) {
-            throw new AlgebricksException(e, ErrorCode.ERROR_PRINTING_PLAN);
+            throw AlgebricksException.create(ErrorCode.ERROR_PRINTING_PLAN, e, String.valueOf(e));
         }
     }
 
@@ -734,7 +734,7 @@
             }
             return null;
         } catch (IOException e) {
-            throw new AlgebricksException(e, ErrorCode.ERROR_PRINTING_PLAN);
+            throw AlgebricksException.create(ErrorCode.ERROR_PRINTING_PLAN, e, String.valueOf(e));
         }
     }
 
@@ -749,7 +749,7 @@
             jsonGenerator.writeEndArray();
             idCounter.previousPrefix();
         } catch (IOException e) {
-            throw new AlgebricksException(e, ErrorCode.ERROR_PRINTING_PLAN);
+            throw AlgebricksException.create(ErrorCode.ERROR_PRINTING_PLAN, e, String.valueOf(e));
         }
     }
 
@@ -767,7 +767,7 @@
             }
             writeArrayFieldOfExpression(EXPRESSIONS_FIELD, op.getExpressionRef(), indent);
         } catch (IOException e) {
-            throw new AlgebricksException(e, ErrorCode.ERROR_PRINTING_PLAN);
+            throw AlgebricksException.create(ErrorCode.ERROR_PRINTING_PLAN, e, String.valueOf(e));
         }
     }
 
@@ -782,7 +782,7 @@
             writeArrayFieldOfExpression(EXPRESSIONS_FIELD, op.getExpressionRef(), indent);
             writeFilterInformation(op.getMinFilterVars(), op.getMaxFilterVars());
         } catch (IOException e) {
-            throw new AlgebricksException(e, ErrorCode.ERROR_PRINTING_PLAN);
+            throw AlgebricksException.create(ErrorCode.ERROR_PRINTING_PLAN, e, String.valueOf(e));
         }
     }
 
@@ -800,7 +800,7 @@
                 jsonGenerator.writeEndObject();
             }
         } catch (IOException e) {
-            throw new AlgebricksException(e, ErrorCode.ERROR_PRINTING_PLAN);
+            throw AlgebricksException.create(ErrorCode.ERROR_PRINTING_PLAN, e, String.valueOf(e));
         }
     }
 
@@ -956,7 +956,7 @@
         try {
             jsonGenerator.flush();
         } catch (IOException e) {
-            throw new AlgebricksException(e, ErrorCode.ERROR_PRINTING_PLAN);
+            throw AlgebricksException.create(ErrorCode.ERROR_PRINTING_PLAN, e, String.valueOf(e));
         }
     }
 }
diff --git a/hyracks-fullstack/algebricks/algebricks-rewriter/src/main/java/org/apache/hyracks/algebricks/rewriter/rules/SetAlgebricksPhysicalOperatorsRule.java b/hyracks-fullstack/algebricks/algebricks-rewriter/src/main/java/org/apache/hyracks/algebricks/rewriter/rules/SetAlgebricksPhysicalOperatorsRule.java
index 42f9aba..7243827 100644
--- a/hyracks-fullstack/algebricks/algebricks-rewriter/src/main/java/org/apache/hyracks/algebricks/rewriter/rules/SetAlgebricksPhysicalOperatorsRule.java
+++ b/hyracks-fullstack/algebricks/algebricks-rewriter/src/main/java/org/apache/hyracks/algebricks/rewriter/rules/SetAlgebricksPhysicalOperatorsRule.java
@@ -223,8 +223,8 @@
                     } else if (gby.getSourceLocation() != null) {
                         IWarningCollector warningCollector = context.getWarningCollector();
                         if (warningCollector.shouldWarn()) {
-                            warningCollector.warn(Warning.forHyracks(gby.getSourceLocation(),
-                                    ErrorCode.INAPPLICABLE_HINT, "Group By", "hash"));
+                            warningCollector.warn(Warning.of(gby.getSourceLocation(), ErrorCode.INAPPLICABLE_HINT,
+                                    "Group By", "hash"));
                         }
                     }
                 }
diff --git a/hyracks-fullstack/algebricks/algebricks-rewriter/src/main/java/org/apache/hyracks/algebricks/rewriter/util/JoinUtils.java b/hyracks-fullstack/algebricks/algebricks-rewriter/src/main/java/org/apache/hyracks/algebricks/rewriter/util/JoinUtils.java
index eccb6c0..1ac7614 100644
--- a/hyracks-fullstack/algebricks/algebricks-rewriter/src/main/java/org/apache/hyracks/algebricks/rewriter/util/JoinUtils.java
+++ b/hyracks-fullstack/algebricks/algebricks-rewriter/src/main/java/org/apache/hyracks/algebricks/rewriter/util/JoinUtils.java
@@ -219,7 +219,7 @@
         if (OperatorPropertiesUtil.isAlwaysTrueCond(conditionExpr) && sourceLoc != null) {
             IWarningCollector warningCollector = context.getWarningCollector();
             if (warningCollector.shouldWarn()) {
-                warningCollector.warn(Warning.forHyracks(sourceLoc, ErrorCode.CROSS_PRODUCT_JOIN));
+                warningCollector.warn(Warning.of(sourceLoc, ErrorCode.CROSS_PRODUCT_JOIN));
             }
         }
     }
diff --git a/hyracks-fullstack/hyracks/hyracks-api/src/main/java/org/apache/hyracks/api/exceptions/ErrorCode.java b/hyracks-fullstack/hyracks/hyracks-api/src/main/java/org/apache/hyracks/api/exceptions/ErrorCode.java
index db60f1a..7291473 100644
--- a/hyracks-fullstack/hyracks/hyracks-api/src/main/java/org/apache/hyracks/api/exceptions/ErrorCode.java
+++ b/hyracks-fullstack/hyracks/hyracks-api/src/main/java/org/apache/hyracks/api/exceptions/ErrorCode.java
@@ -18,9 +18,6 @@
  */
 package org.apache.hyracks.api.exceptions;
 
-import java.io.InputStream;
-import java.util.Map;
-
 import org.apache.hyracks.api.util.ErrorMessageUtil;
 
 /**
@@ -29,173 +26,175 @@
  * 0 --- 9999: runtime errors
  * 10000 ---- 19999: compilation errors
  */
-public class ErrorCode {
-    private static final String RESOURCE_PATH = "errormsg/en.properties";
-    public static final String HYRACKS = "HYR";
-
+public enum ErrorCode implements IError {
     // Runtime error codes.
-    public static final int INVALID_OPERATOR_OPERATION = 1;
-    public static final int ERROR_PROCESSING_TUPLE = 2;
-    public static final int FAILURE_ON_NODE = 3;
-    public static final int FILE_WITH_ABSOULTE_PATH_NOT_WITHIN_ANY_IO_DEVICE = 4;
-    public static final int FULLTEXT_PHRASE_FOUND = 5;
-    public static final int JOB_QUEUE_FULL = 6;
-    public static final int INVALID_NETWORK_ADDRESS = 7;
-    public static final int INVALID_INPUT_PARAMETER = 8;
-    public static final int JOB_REQUIREMENTS_EXCEED_CAPACITY = 9;
-    public static final int NO_SUCH_NODE = 10;
-    public static final int CLASS_LOADING_ISSUE = 11;
-    public static final int ILLEGAL_WRITE_AFTER_FLUSH_ATTEMPT = 12;
-    public static final int DUPLICATE_IODEVICE = 13;
-    public static final int NESTED_IODEVICES = 14;
-    public static final int MORE_THAN_ONE_RESULT = 15;
-    public static final int RESULT_FAILURE_EXCEPTION = 16;
-    public static final int RESULT_FAILURE_NO_EXCEPTION = 17;
-    public static final int INCONSISTENT_RESULT_METADATA = 18;
-    public static final int CANNOT_DELETE_FILE = 19;
-    public static final int NOT_A_JOBID = 20;
-    public static final int ERROR_FINDING_DEPLOYED_JOB = 21;
-    public static final int DUPLICATE_DEPLOYED_JOB = 22;
-    public static final int DEPLOYED_JOB_FAILURE = 23;
-    public static final int NO_RESULT_SET = 24;
-    public static final int JOB_CANCELED = 25;
-    public static final int NODE_FAILED = 26;
-    public static final int FILE_IS_NOT_DIRECTORY = 27;
-    public static final int CANNOT_READ_FILE = 28;
-    public static final int UNIDENTIFIED_IO_ERROR_READING_FILE = 29;
-    public static final int FILE_DOES_NOT_EXIST = 30;
-    public static final int UNIDENTIFIED_IO_ERROR_DELETING_DIR = 31;
-    public static final int RESULT_NO_RECORD = 32;
-    public static final int DUPLICATE_KEY = 33;
-    public static final int LOAD_NON_EMPTY_INDEX = 34;
-    public static final int MODIFY_NOT_SUPPORTED_IN_EXTERNAL_INDEX = 35;
-    public static final int FLUSH_NOT_SUPPORTED_IN_EXTERNAL_INDEX = 36;
-    public static final int UPDATE_OR_DELETE_NON_EXISTENT_KEY = 37;
-    public static final int INDEX_NOT_UPDATABLE = 38;
-    public static final int OCCURRENCE_THRESHOLD_PANIC_EXCEPTION = 39;
-    public static final int UNKNOWN_INVERTED_INDEX_TYPE = 40;
-    public static final int CANNOT_PROPOSE_LINEARIZER_DIFF_DIMENSIONS = 41;
-    public static final int CANNOT_PROPOSE_LINEARIZER_FOR_TYPE = 42;
-    public static final int RECORD_IS_TOO_LARGE = 43;
-    public static final int FAILED_TO_RE_FIND_PARENT = 44;
-    public static final int FAILED_TO_FIND_TUPLE = 45;
-    public static final int UNSORTED_LOAD_INPUT = 46;
-    public static final int OPERATION_EXCEEDED_MAX_RESTARTS = 47;
-    public static final int DUPLICATE_LOAD_INPUT = 48;
-    public static final int CANNOT_CREATE_ACTIVE_INDEX = 49;
-    public static final int CANNOT_ACTIVATE_ACTIVE_INDEX = 50;
-    public static final int CANNOT_DEACTIVATE_INACTIVE_INDEX = 51;
-    public static final int CANNOT_DESTROY_ACTIVE_INDEX = 52;
-    public static final int CANNOT_CLEAR_INACTIVE_INDEX = 53;
-    public static final int CANNOT_ALLOCATE_MEMORY_FOR_INACTIVE_INDEX = 54;
-    public static final int RESOURCE_DOES_NOT_EXIST = 55;
-    public static final int DISK_COMPONENT_SCAN_NOT_ALLOWED_FOR_SECONDARY_INDEX = 56;
-    public static final int CANNOT_FIND_MATTER_TUPLE_FOR_ANTI_MATTER_TUPLE = 57;
-    public static final int TASK_ABORTED = 58;
-    public static final int OPEN_ON_OPEN_WRITER = 59;
-    public static final int OPEN_ON_FAILED_WRITER = 60;
-    public static final int NEXT_FRAME_ON_FAILED_WRITER = 61;
-    public static final int NEXT_FRAME_ON_CLOSED_WRITER = 62;
-    public static final int FLUSH_ON_FAILED_WRITER = 63;
-    public static final int FLUSH_ON_CLOSED_WRITER = 64;
-    public static final int FAIL_ON_FAILED_WRITER = 65;
-    public static final int MISSED_FAIL_CALL = 66;
-    public static final int CANNOT_CREATE_FILE = 67;
-    public static final int NO_MAPPING_FOR_FILE_ID = 68;
-    public static final int NO_MAPPING_FOR_FILENAME = 69;
-    public static final int CANNOT_GET_NUMBER_OF_ELEMENT_FROM_INACTIVE_FILTER = 70;
-    public static final int CANNOT_CREATE_BLOOM_FILTER_BUILDER_FOR_INACTIVE_FILTER = 71;
-    public static final int CANNOT_CREATE_BLOOM_FILTER_WITH_NUMBER_OF_PAGES = 72;
-    public static final int CANNOT_ADD_TUPLES_TO_DUMMY_BLOOM_FILTER = 73;
-    public static final int CANNOT_CREATE_ACTIVE_BLOOM_FILTER = 74;
-    public static final int CANNOT_DEACTIVATE_INACTIVE_BLOOM_FILTER = 75;
-    public static final int CANNOT_DESTROY_ACTIVE_BLOOM_FILTER = 76;
-    public static final int CANNOT_PURGE_ACTIVE_INDEX = 77;
-    public static final int CANNOT_PURGE_ACTIVE_BLOOM_FILTER = 78;
-    public static final int CANNOT_BULK_LOAD_NON_EMPTY_TREE = 79;
-    public static final int CANNOT_CREATE_EXISTING_INDEX = 80;
-    public static final int FILE_ALREADY_MAPPED = 81;
-    public static final int FILE_ALREADY_EXISTS = 82;
-    public static final int NO_INDEX_FOUND_WITH_RESOURCE_ID = 83;
-    public static final int FOUND_OVERLAPPING_LSM_FILES = 84;
-    public static final int FOUND_MULTIPLE_TRANSACTIONS = 85;
-    public static final int UNRECOGNIZED_INDEX_COMPONENT_FILE = 86;
-    public static final int UNEQUAL_NUM_FILTERS_TREES = 87;
-    public static final int INDEX_NOT_MODIFIABLE = 88;
-    public static final int GROUP_BY_MEMORY_BUDGET_EXCEEDS = 89;
-    public static final int ILLEGAL_MEMORY_BUDGET = 90;
-    public static final int TIMEOUT = 91;
-    public static final int JOB_HAS_BEEN_CLEARED_FROM_HISTORY = 92;
-    public static final int FAILED_TO_READ_RESULT = 93;
-    public static final int CANNOT_READ_CLOSED_FILE = 94;
-    public static final int TUPLE_CANNOT_FIT_INTO_EMPTY_FRAME = 95;
-    public static final int ILLEGAL_ATTEMPT_TO_ENTER_EMPTY_COMPONENT = 96;
-    public static final int ILLEGAL_ATTEMPT_TO_EXIT_EMPTY_COMPONENT = 97;
-    public static final int A_FLUSH_OPERATION_HAS_FAILED = 98;
-    public static final int A_MERGE_OPERATION_HAS_FAILED = 99;
-    public static final int FAILED_TO_SHUTDOWN_EVENT_PROCESSOR = 100;
-    public static final int PAGE_DOES_NOT_EXIST_IN_FILE = 101;
-    public static final int VBC_ALREADY_OPEN = 102;
-    public static final int VBC_ALREADY_CLOSED = 103;
-    public static final int INDEX_DOES_NOT_EXIST = 104;
-    public static final int CANNOT_DROP_IN_USE_INDEX = 105;
-    public static final int CANNOT_DEACTIVATE_PINNED_BLOOM_FILTER = 106;
-    public static final int PREDICATE_CANNOT_BE_NULL = 107;
-    public static final int FULLTEXT_ONLY_EXECUTABLE_FOR_STRING_OR_LIST = 108;
-    public static final int NOT_ENOUGH_BUDGET_FOR_TEXTSEARCH = 109;
-    public static final int CANNOT_CONTINUE_TEXT_SEARCH_HYRACKS_TASK_IS_NULL = 110;
-    public static final int CANNOT_CONTINUE_TEXT_SEARCH_BUFFER_MANAGER_IS_NULL = 111;
-    public static final int CANNOT_ADD_ELEMENT_TO_INVERTED_INDEX_SEARCH_RESULT = 112;
-    public static final int UNDEFINED_INVERTED_LIST_MERGE_TYPE = 113;
-    public static final int NODE_IS_NOT_ACTIVE = 114;
-    public static final int LOCAL_NETWORK_ERROR = 115;
-    public static final int ONE_TUPLE_RANGEMAP_EXPECTED = 116;
-    public static final int NO_RANGEMAP_PRODUCED = 117;
-    public static final int RANGEMAP_NOT_FOUND = 118;
-    public static final int UNSUPPORTED_WINDOW_SPEC = 119;
-    public static final int EOF = 120;
-    public static final int NUMERIC_PROMOTION_ERROR = 121;
-    public static final int ERROR_PRINTING_PLAN = 122;
-    public static final int INSUFFICIENT_MEMORY = 123;
-    public static final int PARSING_ERROR = 124;
-    public static final int INVALID_INVERTED_LIST_TYPE_TRAITS = 125;
-    public static final int ILLEGAL_STATE = 126;
+    INVALID_OPERATOR_OPERATION(1),
+    ERROR_PROCESSING_TUPLE(2),
+    FAILURE_ON_NODE(3),
+    FILE_WITH_ABSOULTE_PATH_NOT_WITHIN_ANY_IO_DEVICE(4),
+    FULLTEXT_PHRASE_FOUND(5),
+    JOB_QUEUE_FULL(6),
+    INVALID_NETWORK_ADDRESS(7),
+    INVALID_INPUT_PARAMETER(8),
+    JOB_REQUIREMENTS_EXCEED_CAPACITY(9),
+    NO_SUCH_NODE(10),
+    CLASS_LOADING_ISSUE(11),
+    ILLEGAL_WRITE_AFTER_FLUSH_ATTEMPT(12),
+    DUPLICATE_IODEVICE(13),
+    NESTED_IODEVICES(14),
+    MORE_THAN_ONE_RESULT(15),
+    RESULT_FAILURE_EXCEPTION(16),
+    RESULT_FAILURE_NO_EXCEPTION(17),
+    INCONSISTENT_RESULT_METADATA(18),
+    CANNOT_DELETE_FILE(19),
+    NOT_A_JOBID(20),
+    ERROR_FINDING_DEPLOYED_JOB(21),
+    DUPLICATE_DEPLOYED_JOB(22),
+    DEPLOYED_JOB_FAILURE(23),
+    NO_RESULT_SET(24),
+    JOB_CANCELED(25),
+    NODE_FAILED(26),
+    FILE_IS_NOT_DIRECTORY(27),
+    CANNOT_READ_FILE(28),
+    UNIDENTIFIED_IO_ERROR_READING_FILE(29),
+    FILE_DOES_NOT_EXIST(30),
+    UNIDENTIFIED_IO_ERROR_DELETING_DIR(31),
+    RESULT_NO_RECORD(32),
+    DUPLICATE_KEY(33),
+    LOAD_NON_EMPTY_INDEX(34),
+    MODIFY_NOT_SUPPORTED_IN_EXTERNAL_INDEX(35),
+    FLUSH_NOT_SUPPORTED_IN_EXTERNAL_INDEX(36),
+    UPDATE_OR_DELETE_NON_EXISTENT_KEY(37),
+    INDEX_NOT_UPDATABLE(38),
+    OCCURRENCE_THRESHOLD_PANIC_EXCEPTION(39),
+    UNKNOWN_INVERTED_INDEX_TYPE(40),
+    CANNOT_PROPOSE_LINEARIZER_DIFF_DIMENSIONS(41),
+    CANNOT_PROPOSE_LINEARIZER_FOR_TYPE(42),
+    RECORD_IS_TOO_LARGE(43),
+    FAILED_TO_RE_FIND_PARENT(44),
+    FAILED_TO_FIND_TUPLE(45),
+    UNSORTED_LOAD_INPUT(46),
+    OPERATION_EXCEEDED_MAX_RESTARTS(47),
+    DUPLICATE_LOAD_INPUT(48),
+    CANNOT_CREATE_ACTIVE_INDEX(49),
+    CANNOT_ACTIVATE_ACTIVE_INDEX(50),
+    CANNOT_DEACTIVATE_INACTIVE_INDEX(51),
+    CANNOT_DESTROY_ACTIVE_INDEX(52),
+    CANNOT_CLEAR_INACTIVE_INDEX(53),
+    CANNOT_ALLOCATE_MEMORY_FOR_INACTIVE_INDEX(54),
+    RESOURCE_DOES_NOT_EXIST(55),
+    DISK_COMPONENT_SCAN_NOT_ALLOWED_FOR_SECONDARY_INDEX(56),
+    CANNOT_FIND_MATTER_TUPLE_FOR_ANTI_MATTER_TUPLE(57),
+    TASK_ABORTED(58),
+    OPEN_ON_OPEN_WRITER(59),
+    OPEN_ON_FAILED_WRITER(60),
+    NEXT_FRAME_ON_FAILED_WRITER(61),
+    NEXT_FRAME_ON_CLOSED_WRITER(62),
+    FLUSH_ON_FAILED_WRITER(63),
+    FLUSH_ON_CLOSED_WRITER(64),
+    FAIL_ON_FAILED_WRITER(65),
+    MISSED_FAIL_CALL(66),
+    CANNOT_CREATE_FILE(67),
+    NO_MAPPING_FOR_FILE_ID(68),
+    NO_MAPPING_FOR_FILENAME(69),
+    CANNOT_GET_NUMBER_OF_ELEMENT_FROM_INACTIVE_FILTER(70),
+    CANNOT_CREATE_BLOOM_FILTER_BUILDER_FOR_INACTIVE_FILTER(71),
+    CANNOT_CREATE_BLOOM_FILTER_WITH_NUMBER_OF_PAGES(72),
+    CANNOT_ADD_TUPLES_TO_DUMMY_BLOOM_FILTER(73),
+    CANNOT_CREATE_ACTIVE_BLOOM_FILTER(74),
+    CANNOT_DEACTIVATE_INACTIVE_BLOOM_FILTER(75),
+    CANNOT_DESTROY_ACTIVE_BLOOM_FILTER(76),
+    CANNOT_PURGE_ACTIVE_INDEX(77),
+    CANNOT_PURGE_ACTIVE_BLOOM_FILTER(78),
+    CANNOT_BULK_LOAD_NON_EMPTY_TREE(79),
+    CANNOT_CREATE_EXISTING_INDEX(80),
+    FILE_ALREADY_MAPPED(81),
+    FILE_ALREADY_EXISTS(82),
+    NO_INDEX_FOUND_WITH_RESOURCE_ID(83),
+    FOUND_OVERLAPPING_LSM_FILES(84),
+    FOUND_MULTIPLE_TRANSACTIONS(85),
+    UNRECOGNIZED_INDEX_COMPONENT_FILE(86),
+    UNEQUAL_NUM_FILTERS_TREES(87),
+    INDEX_NOT_MODIFIABLE(88),
+    GROUP_BY_MEMORY_BUDGET_EXCEEDS(89),
+    ILLEGAL_MEMORY_BUDGET(90),
+    TIMEOUT(91),
+    JOB_HAS_BEEN_CLEARED_FROM_HISTORY(92),
+    FAILED_TO_READ_RESULT(93),
+    CANNOT_READ_CLOSED_FILE(94),
+    TUPLE_CANNOT_FIT_INTO_EMPTY_FRAME(95),
+    ILLEGAL_ATTEMPT_TO_ENTER_EMPTY_COMPONENT(96),
+    ILLEGAL_ATTEMPT_TO_EXIT_EMPTY_COMPONENT(97),
+    A_FLUSH_OPERATION_HAS_FAILED(98),
+    A_MERGE_OPERATION_HAS_FAILED(99),
+    FAILED_TO_SHUTDOWN_EVENT_PROCESSOR(100),
+    PAGE_DOES_NOT_EXIST_IN_FILE(101),
+    VBC_ALREADY_OPEN(102),
+    VBC_ALREADY_CLOSED(103),
+    INDEX_DOES_NOT_EXIST(104),
+    CANNOT_DROP_IN_USE_INDEX(105),
+    CANNOT_DEACTIVATE_PINNED_BLOOM_FILTER(106),
+    PREDICATE_CANNOT_BE_NULL(107),
+    FULLTEXT_ONLY_EXECUTABLE_FOR_STRING_OR_LIST(108),
+    NOT_ENOUGH_BUDGET_FOR_TEXTSEARCH(109),
+    CANNOT_CONTINUE_TEXT_SEARCH_HYRACKS_TASK_IS_NULL(110),
+    CANNOT_CONTINUE_TEXT_SEARCH_BUFFER_MANAGER_IS_NULL(111),
+    CANNOT_ADD_ELEMENT_TO_INVERTED_INDEX_SEARCH_RESULT(112),
+    UNDEFINED_INVERTED_LIST_MERGE_TYPE(113),
+    NODE_IS_NOT_ACTIVE(114),
+    LOCAL_NETWORK_ERROR(115),
+    ONE_TUPLE_RANGEMAP_EXPECTED(116),
+    NO_RANGEMAP_PRODUCED(117),
+    RANGEMAP_NOT_FOUND(118),
+    UNSUPPORTED_WINDOW_SPEC(119),
+    EOF(120),
+    NUMERIC_PROMOTION_ERROR(121),
+    ERROR_PRINTING_PLAN(122),
+    INSUFFICIENT_MEMORY(123),
+    PARSING_ERROR(124),
+    INVALID_INVERTED_LIST_TYPE_TRAITS(125),
+    ILLEGAL_STATE(126),
 
     // Compilation error codes.
-    public static final int RULECOLLECTION_NOT_INSTANCE_OF_LIST = 10000;
-    public static final int CANNOT_COMPOSE_PART_CONSTRAINTS = 10001;
-    public static final int PHYS_OPERATOR_NOT_SET = 10002;
-    public static final int DESCRIPTOR_GENERATION_ERROR = 10003;
-    public static final int EXPR_NOT_NORMALIZED = 10004;
-    public static final int OPERATOR_NOT_IMPLEMENTED = 10005;
-    public static final int INAPPLICABLE_HINT = 10006;
-    public static final int CROSS_PRODUCT_JOIN = 10007;
-    public static final int GROUP_ALL_DECOR = 10008;
+    RULECOLLECTION_NOT_INSTANCE_OF_LIST(10000),
+    CANNOT_COMPOSE_PART_CONSTRAINTS(10001),
+    PHYS_OPERATOR_NOT_SET(10002),
+    DESCRIPTOR_GENERATION_ERROR(10003),
+    EXPR_NOT_NORMALIZED(10004),
+    OPERATOR_NOT_IMPLEMENTED(10005),
+    INAPPLICABLE_HINT(10006),
+    CROSS_PRODUCT_JOIN(10007),
+    GROUP_ALL_DECOR(10008);
 
-    private static class Holder {
-        private static final Map<Integer, String> errorMessageMap;
+    private static final String RESOURCE_PATH = "errormsg/en.properties";
+    public static final String HYRACKS = "HYR";
+    private final int intValue;
 
-        static {
-            // Loads the map that maps error codes to error message templates.
-            try (InputStream resourceStream = ErrorCode.class.getClassLoader().getResourceAsStream(RESOURCE_PATH)) {
-                errorMessageMap = ErrorMessageUtil.loadErrorMap(resourceStream);
-            } catch (Exception e) {
-                throw new IllegalStateException(e);
-            }
-        }
-
-        private Holder() {
-        }
+    ErrorCode(int intValue) {
+        this.intValue = intValue;
     }
 
-    private ErrorCode() {
+    @Override
+    public String component() {
+        return HYRACKS;
     }
 
-    public static String getErrorMessage(int errorCode) {
-        String msg = Holder.errorMessageMap.get(errorCode);
-        if (msg == null) {
-            throw new IllegalStateException("Undefined error code: " + errorCode);
+    @Override
+    public int intValue() {
+        return intValue;
+    }
+
+    @Override
+    public String errorMessage() {
+        return ErrorMessageMapHolder.get(this);
+    }
+
+    private static class ErrorMessageMapHolder {
+        private static final String[] enumMessages =
+                ErrorMessageUtil.defineMessageEnumOrdinalMap(values(), RESOURCE_PATH);
+
+        private static String get(ErrorCode errorCode) {
+            return enumMessages[errorCode.ordinal()];
         }
-        return msg;
     }
 }
diff --git a/hyracks-fullstack/hyracks/hyracks-api/src/main/java/org/apache/hyracks/api/exceptions/HyracksDataException.java b/hyracks-fullstack/hyracks/hyracks-api/src/main/java/org/apache/hyracks/api/exceptions/HyracksDataException.java
index 54e4eaf..6deff8d 100644
--- a/hyracks-fullstack/hyracks/hyracks-api/src/main/java/org/apache/hyracks/api/exceptions/HyracksDataException.java
+++ b/hyracks-fullstack/hyracks/hyracks-api/src/main/java/org/apache/hyracks/api/exceptions/HyracksDataException.java
@@ -21,8 +21,6 @@
 
 import java.io.Serializable;
 
-import org.apache.hyracks.api.util.ErrorMessageUtil;
-
 /**
  * The main execution time exception type for runtime errors in a hyracks environment
  */
@@ -51,34 +49,25 @@
         return new HyracksDataException(cause);
     }
 
-    public static HyracksDataException create(int code, SourceLocation sourceLoc, Serializable... params) {
-        return new HyracksDataException(ErrorCode.HYRACKS, code, ErrorCode.getErrorMessage(code), null, sourceLoc,
-                params);
+    public static HyracksDataException create(ErrorCode code, SourceLocation sourceLoc, Serializable... params) {
+        return new HyracksDataException(code, sourceLoc, params);
     }
 
-    public static HyracksDataException create(int code, Serializable... params) {
-        return new HyracksDataException(ErrorCode.HYRACKS, code, ErrorCode.getErrorMessage(code), params);
+    public static HyracksDataException create(ErrorCode code, Serializable... params) {
+        return new HyracksDataException(code, params);
     }
 
-    public static HyracksDataException create(int code, Throwable cause, SourceLocation sourceLoc,
+    public static HyracksDataException create(ErrorCode code, Throwable cause, SourceLocation sourceLoc,
             Serializable... params) {
-        return new HyracksDataException(ErrorCode.HYRACKS, code, ErrorCode.getErrorMessage(code), cause, sourceLoc,
-                params);
+        return new HyracksDataException(code, cause, sourceLoc, params);
     }
 
-    public static HyracksDataException create(int code, Throwable cause, Serializable... params) {
-        return new HyracksDataException(ErrorCode.HYRACKS, code, ErrorCode.getErrorMessage(code), cause, params);
+    public static HyracksDataException create(ErrorCode code, Throwable cause, Serializable... params) {
+        return new HyracksDataException(code, cause, null, params);
     }
 
-    public HyracksDataException(String component, int errorCode, String message, Throwable cause, String nodeId,
-            Serializable... params) {
-        super(component, errorCode, message, cause, nodeId, params);
-    }
-
-    public HyracksDataException(String component, int errorCode, String message, Throwable cause, String nodeId,
-            StackTraceElement[] stackTrace, Serializable... params) {
-        super(component, errorCode, message, cause, nodeId, params);
-        setStackTrace(stackTrace);
+    public static HyracksDataException create(HyracksDataException e, String nodeId) {
+        return new HyracksDataException(e, nodeId);
     }
 
     /**
@@ -101,34 +90,24 @@
         super(message, cause);
     }
 
-    public HyracksDataException(String component, int errorCode, Serializable... params) {
-        super(component, errorCode, null, null, null, params);
+    public HyracksDataException(ErrorCode code, Serializable... params) {
+        this(code, null, params);
     }
 
-    public HyracksDataException(Throwable cause, int errorCode, Serializable... params) {
-        super(ErrorMessageUtil.NONE, errorCode, cause.getMessage(), cause, null, params);
+    public HyracksDataException(ErrorCode code, SourceLocation sourceLoc, Serializable... params) {
+        this(code, null, sourceLoc, params);
     }
 
-    public HyracksDataException(String component, int errorCode, String message, Serializable... params) {
-        super(component, errorCode, message, null, null, params);
+    public HyracksDataException(ErrorCode code, Throwable cause, SourceLocation sourceLoc, Serializable... params) {
+        super(code, code.component(), code.intValue(), code.errorMessage(), cause, sourceLoc, null, params);
     }
 
-    public HyracksDataException(String component, int errorCode, Throwable cause, Serializable... params) {
-        super(component, errorCode, cause, params);
+    private HyracksDataException(HyracksDataException hde, String nodeId) {
+        super(hde.getError().orElse(null), hde.getComponent(), hde.getErrorCode(), hde.getMessage(), hde.getCause(),
+                hde.getSourceLocation(), nodeId, hde.getStackTrace(), hde.getParams());
     }
 
-    public HyracksDataException(String component, int errorCode, String message, Throwable cause,
-            Serializable... params) {
-        super(component, errorCode, message, cause, null, params);
-    }
-
-    public HyracksDataException(String component, int errorCode, String message, Throwable cause,
-            SourceLocation sourceLoc, Serializable... params) {
-        super(component, errorCode, message, cause, sourceLoc, null, params);
-    }
-
-    public static HyracksDataException create(HyracksDataException e, String nodeId) {
-        return new HyracksDataException(e.getComponent(), e.getErrorCode(), e.getMessage(), e.getCause(), nodeId,
-                e.getStackTrace(), e.getParams());
+    protected HyracksDataException(IError error, Throwable cause, SourceLocation sourceLoc, Serializable... params) {
+        super(error, error.component(), error.intValue(), error.errorMessage(), cause, sourceLoc, null, params);
     }
 }
diff --git a/hyracks-fullstack/hyracks/hyracks-api/src/main/java/org/apache/hyracks/api/exceptions/HyracksException.java b/hyracks-fullstack/hyracks/hyracks-api/src/main/java/org/apache/hyracks/api/exceptions/HyracksException.java
index 7b9f632..d6085f6 100644
--- a/hyracks-fullstack/hyracks/hyracks-api/src/main/java/org/apache/hyracks/api/exceptions/HyracksException.java
+++ b/hyracks-fullstack/hyracks/hyracks-api/src/main/java/org/apache/hyracks/api/exceptions/HyracksException.java
@@ -20,6 +20,7 @@
 
 import java.io.IOException;
 import java.io.Serializable;
+import java.util.Optional;
 
 import org.apache.hyracks.api.util.ErrorMessageUtil;
 
@@ -31,6 +32,7 @@
     private final int errorCode;
     private final Serializable[] params;
     private final String nodeId;
+    protected transient final IError error;
     private SourceLocation sourceLoc;
     private transient volatile String msgCache;
 
@@ -52,22 +54,12 @@
         return new HyracksException(cause);
     }
 
-    public static HyracksException create(int code, Serializable... params) {
-        return new HyracksException(ErrorCode.HYRACKS, code, ErrorCode.getErrorMessage(code), params);
+    public static HyracksException create(ErrorCode code, Serializable... params) {
+        return new HyracksException(code, params);
     }
 
-    public static HyracksException create(int code, Throwable cause, Serializable... params) {
-        return new HyracksException(ErrorCode.HYRACKS, code, ErrorCode.getErrorMessage(code), cause, params);
-    }
-
-    public HyracksException(String component, int errorCode, String message, Throwable cause, SourceLocation sourceLoc,
-            String nodeId, Serializable... params) {
-        super(message, cause);
-        this.sourceLoc = sourceLoc;
-        this.component = component;
-        this.errorCode = errorCode;
-        this.nodeId = nodeId;
-        this.params = params;
+    public static HyracksException create(ErrorCode code, Throwable cause, Serializable... params) {
+        return new HyracksException(code, cause, params);
     }
 
     /**
@@ -75,7 +67,24 @@
      */
     @Deprecated
     public HyracksException(String message) {
-        this(ErrorMessageUtil.NONE, UNKNOWN, message, null, null, (Serializable[]) null);
+        this(message, null);
+    }
+
+    protected HyracksException(IError error, String component, int intCode, String message, Throwable cause,
+            SourceLocation sourceLoc, String nodeId, Serializable... params) {
+        super(message, cause);
+        this.error = error;
+        this.sourceLoc = sourceLoc;
+        this.component = component;
+        this.errorCode = intCode;
+        this.nodeId = nodeId;
+        this.params = params;
+    }
+
+    protected HyracksException(IError errorCode, Throwable cause, SourceLocation sourceLoc, String nodeId,
+            Serializable... params) {
+        this(errorCode, errorCode.component(), errorCode.intValue(), errorCode.errorMessage(), cause, sourceLoc, nodeId,
+                params);
     }
 
     /**
@@ -83,7 +92,7 @@
      */
     @Deprecated
     protected HyracksException(Throwable cause) {
-        this(ErrorMessageUtil.NONE, UNKNOWN, ErrorMessageUtil.getCauseMessage(cause), cause, (Serializable[]) null);
+        this(String.valueOf(cause), cause);
     }
 
     /**
@@ -91,32 +100,24 @@
      */
     @Deprecated
     protected HyracksException(String message, Throwable cause) {
-        this(ErrorMessageUtil.NONE, UNKNOWN, message, cause, (String) null);
+        this(ErrorMessageUtil.NONE, UNKNOWN, message, cause);
     }
 
-    public HyracksException(String component, int errorCode, Serializable... params) {
-        this(component, errorCode, null, null, null, params);
+    public HyracksException(ErrorCode errorCode, Throwable cause, Serializable... params) {
+        this(errorCode.component(), errorCode.intValue(), errorCode.errorMessage(), cause, null, params);
     }
 
-    public HyracksException(Throwable cause, int errorCode, Serializable... params) {
-        this(ErrorMessageUtil.NONE, errorCode, ErrorMessageUtil.getCauseMessage(cause), cause, null, params);
+    public HyracksException(ErrorCode errorCode, Serializable... params) {
+        this(errorCode.component(), errorCode.intValue(), errorCode.errorMessage(), null, null, params);
     }
 
-    public HyracksException(String component, int errorCode, String message, Serializable... params) {
-        this(component, errorCode, message, null, null, params);
-    }
-
-    public HyracksException(String component, int errorCode, Throwable cause, Serializable... params) {
-        this(component, errorCode, ErrorMessageUtil.getCauseMessage(cause), cause, null, params);
-    }
-
-    public HyracksException(String component, int errorCode, String message, Throwable cause, Serializable... params) {
+    private HyracksException(String component, int errorCode, String message, Throwable cause, Serializable... params) {
         this(component, errorCode, message, cause, null, params);
     }
 
-    public HyracksException(String component, int errorCode, String message, Throwable cause, String nodeId,
+    private HyracksException(String component, int errorCode, String message, Throwable cause, String nodeId,
             Serializable... params) {
-        this(component, errorCode, message, cause, null, nodeId, params);
+        this(null, component, errorCode, message, cause, null, nodeId, params);
     }
 
     @Override
@@ -147,14 +148,25 @@
 
     @Override
     public String getMessage() {
-        if (msgCache == null) {
-            msgCache = ErrorMessageUtil.formatMessage(component, errorCode, super.getMessage(), sourceLoc, params);
+        String message = msgCache;
+        if (message == null) {
+            msgCache = message =
+                    ErrorMessageUtil.formatMessage(component, errorCode, super.getMessage(), sourceLoc, params);
         }
-        return msgCache;
+        return message;
     }
 
     @Override
     public String toString() {
         return getLocalizedMessage();
     }
+
+    @Override
+    public Optional<IError> getError() {
+        return Optional.ofNullable(error);
+    }
+
+    public boolean matches(ErrorCode errorCode) {
+        return component.equals(errorCode.component()) && getErrorCode() == errorCode.intValue();
+    }
 }
diff --git a/hyracks-fullstack/hyracks/hyracks-api/src/main/java/org/apache/hyracks/api/exceptions/IError.java b/hyracks-fullstack/hyracks/hyracks-api/src/main/java/org/apache/hyracks/api/exceptions/IError.java
new file mode 100644
index 0000000..6f889bb
--- /dev/null
+++ b/hyracks-fullstack/hyracks/hyracks-api/src/main/java/org/apache/hyracks/api/exceptions/IError.java
@@ -0,0 +1,41 @@
+/*
+ * 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.hyracks.api.exceptions;
+
+/**
+ * A type-safe error, consisting of a string-based component, integer value, and error message
+ * @since 0.3.5.1
+ */
+public interface IError {
+    String component();
+
+    int intValue();
+
+    String errorMessage();
+
+    default String errorCode() {
+        final int intCode = intValue();
+        if (intCode < 1000) {
+            String pad = intCode < 10 ? "000" : intCode < 100 ? "00" : "0";
+            return component() + pad + intCode;
+        } else {
+            return component() + intCode;
+        }
+    }
+}
diff --git a/hyracks-fullstack/hyracks/hyracks-api/src/main/java/org/apache/hyracks/api/exceptions/IFormattedException.java b/hyracks-fullstack/hyracks/hyracks-api/src/main/java/org/apache/hyracks/api/exceptions/IFormattedException.java
index f8b017b..a4ea8c3 100644
--- a/hyracks-fullstack/hyracks/hyracks-api/src/main/java/org/apache/hyracks/api/exceptions/IFormattedException.java
+++ b/hyracks-fullstack/hyracks/hyracks-api/src/main/java/org/apache/hyracks/api/exceptions/IFormattedException.java
@@ -19,6 +19,8 @@
 package org.apache.hyracks.api.exceptions;
 
 import java.util.Objects;
+import java.util.Optional;
+import java.util.stream.Stream;
 
 public interface IFormattedException {
 
@@ -44,25 +46,43 @@
     String getMessage();
 
     /**
-     * Tests for matching component & errorCode against this exception
-     *
-     * @param component the component to match
-     * @param errorCode the errorCode to match
-     * @return <code>true</code> if this {@link IFormattedException} instance matches the supplied parameters
+     * If available, returns the {@link IError} associated with this exception
+     * @return the error instance, othewise {@link Optional#empty()}
+     * @since 0.3.5.1
      */
-    default boolean matches(String component, int errorCode) {
-        Objects.requireNonNull(component, "component");
-        return component.equals(getComponent()) && errorCode == getErrorCode();
+    Optional<IError> getError();
+
+    /**
+     * Indicates whether this exception matches the supplied error code
+     */
+    default boolean matches(IError candidate) {
+        Objects.requireNonNull(candidate, "candidate");
+        return getComponent().equals(candidate.component()) && getErrorCode() == candidate.intValue();
+    }
+
+    /**
+     * Indicates whether this exception matches any of the supplied error codes
+     */
+    default boolean matchesAny(IError candidate, IError... otherCandidates) {
+        return matches(candidate) || Stream.of(otherCandidates).anyMatch(this::matches);
     }
 
     /**
      * Tests for matching component & errorCode against supplied throwable
      *
-     * @param component the component to match
-     * @param errorCode the errorCode to match
-     * @return <code>true</code> if the supplied {@link Throwable}  matches the supplied parameters
+     * @param candidate the error type to match
+     * @return <code>true</code> if the supplied {@link Throwable} matches the supplied candidate
      */
-    static boolean matches(Throwable th, String component, int errorCode) {
-        return th instanceof IFormattedException && ((IFormattedException) th).matches(component, errorCode);
+    static boolean matches(Throwable th, IError candidate) {
+        return th instanceof IFormattedException && ((IFormattedException) th).matches(candidate);
+    }
+
+    /**
+     * Tests for matching component & errorCode against supplied throwable
+     *
+     * @return <code>true</code> if the supplied {@link Throwable} matches any of the supplied candidates
+     */
+    static boolean matchesAny(Throwable th, IError candidate, IError... otherCandidates) {
+        return th instanceof IFormattedException && ((IFormattedException) th).matchesAny(candidate, otherCandidates);
     }
 }
\ No newline at end of file
diff --git a/hyracks-fullstack/hyracks/hyracks-api/src/main/java/org/apache/hyracks/api/exceptions/Warning.java b/hyracks-fullstack/hyracks/hyracks-api/src/main/java/org/apache/hyracks/api/exceptions/Warning.java
index 3face66..ec8f8e9 100644
--- a/hyracks-fullstack/hyracks/hyracks-api/src/main/java/org/apache/hyracks/api/exceptions/Warning.java
+++ b/hyracks-fullstack/hyracks/hyracks-api/src/main/java/org/apache/hyracks/api/exceptions/Warning.java
@@ -41,13 +41,9 @@
         this.message = message;
     }
 
-    public static Warning of(String component, SourceLocation srcLocation, int code, String message) {
-        return new Warning(component, srcLocation, code, message);
-    }
-
-    public static Warning forHyracks(SourceLocation srcLocation, int code, Serializable... params) {
-        return Warning.of(ErrorCode.HYRACKS, srcLocation, code, ErrorMessageUtil.formatMessage(ErrorCode.HYRACKS, code,
-                ErrorCode.getErrorMessage(code), srcLocation, params));
+    public static Warning of(SourceLocation srcLocation, IError code, Serializable... params) {
+        return new Warning(code.component(), srcLocation, code.intValue(), ErrorMessageUtil
+                .formatMessage(code.component(), code.intValue(), code.errorMessage(), srcLocation, params));
     }
 
     public String getComponent() {
diff --git a/hyracks-fullstack/hyracks/hyracks-api/src/main/java/org/apache/hyracks/api/util/ErrorMessageUtil.java b/hyracks-fullstack/hyracks/hyracks-api/src/main/java/org/apache/hyracks/api/util/ErrorMessageUtil.java
index 8758ef7..a7372ae 100644
--- a/hyracks-fullstack/hyracks/hyracks-api/src/main/java/org/apache/hyracks/api/util/ErrorMessageUtil.java
+++ b/hyracks-fullstack/hyracks/hyracks-api/src/main/java/org/apache/hyracks/api/util/ErrorMessageUtil.java
@@ -22,11 +22,13 @@
 import java.io.IOException;
 import java.io.InputStream;
 import java.io.Serializable;
+import java.util.Arrays;
 import java.util.Formatter;
 import java.util.HashMap;
 import java.util.Map;
 import java.util.Properties;
 
+import org.apache.hyracks.api.exceptions.IError;
 import org.apache.hyracks.api.exceptions.IFormattedException;
 import org.apache.hyracks.api.exceptions.SourceLocation;
 import org.apache.logging.log4j.Level;
@@ -110,8 +112,10 @@
             return fmt.out().toString();
         } catch (Exception e) {
             // Do not throw further exceptions during exception processing.
-            LOGGER.log(Level.WARN, e.getLocalizedMessage(), e);
-            return e.getMessage();
+            final String paramsString = Arrays.toString(params);
+            LOGGER.log(Level.WARN, "error formatting {}{}: message {} params {}", component, errorCode, message,
+                    paramsString, e);
+            return message + "; " + paramsString;
         }
     }
 
@@ -121,4 +125,19 @@
         }
         return String.valueOf(t);
     }
+
+    public static String[] defineMessageEnumOrdinalMap(IError[] values, String resourcePath) {
+        String[] enumMessages = new String[values.length];
+        try (InputStream resourceStream = values[0].getClass().getClassLoader().getResourceAsStream(resourcePath)) {
+            Map<Integer, String> errorMessageMap = loadErrorMap(resourceStream);
+            for (IError error : values) {
+                enumMessages[((Enum) error).ordinal()] = errorMessageMap.computeIfAbsent(error.intValue(), intValue -> {
+                    throw new IllegalStateException("error message missing for " + error + " (" + intValue + ")");
+                });
+            }
+        } catch (Exception e) {
+            throw new IllegalStateException(e);
+        }
+        return enumMessages;
+    }
 }
diff --git a/hyracks-fullstack/hyracks/hyracks-api/src/main/java/org/apache/hyracks/api/util/ExceptionUtils.java b/hyracks-fullstack/hyracks/hyracks-api/src/main/java/org/apache/hyracks/api/util/ExceptionUtils.java
index 21f393c..9067dce 100644
--- a/hyracks-fullstack/hyracks/hyracks-api/src/main/java/org/apache/hyracks/api/util/ExceptionUtils.java
+++ b/hyracks-fullstack/hyracks/hyracks-api/src/main/java/org/apache/hyracks/api/util/ExceptionUtils.java
@@ -65,7 +65,7 @@
                     newExceptions.add(e);
                 }
             } else {
-                newExceptions.add(new HyracksDataException(ErrorCode.HYRACKS, ErrorCode.FAILURE_ON_NODE, e, nodeId));
+                newExceptions.add(HyracksDataException.create(ErrorCode.FAILURE_ON_NODE, e, nodeId));
             }
         }
         exceptions.clear();
diff --git a/hyracks-fullstack/hyracks/hyracks-api/src/main/resources/errormsg/en.properties b/hyracks-fullstack/hyracks/hyracks-api/src/main/resources/errormsg/en.properties
index c01f39a..9f04fb2 100644
--- a/hyracks-fullstack/hyracks/hyracks-api/src/main/resources/errormsg/en.properties
+++ b/hyracks-fullstack/hyracks/hyracks-api/src/main/resources/errormsg/en.properties
@@ -139,7 +139,7 @@
 119 = Unsupported window specification: PARTITION BY %1$s, ORDER BY %2$s
 120 = End of file
 121 = A numeric type promotion error has occurred: %1$s
-122 = Encountered an error while printing the plan
+122 = Encountered an error while printing the plan: %1$s
 123 = Insufficient memory is provided for the join operators, please increase the join memory budget.
 124 = Parsing error at %1$s line %2$s field %3$s: %4$s
 125 = Invalid inverted list type traits: %1$s
diff --git a/hyracks-fullstack/hyracks/hyracks-api/src/test/java/org/apache/hyracks/api/job/resource/ClusterCapacityTest.java b/hyracks-fullstack/hyracks/hyracks-api/src/test/java/org/apache/hyracks/api/job/resource/ClusterCapacityTest.java
index 277e8e2..e8bc546 100644
--- a/hyracks-fullstack/hyracks/hyracks-api/src/test/java/org/apache/hyracks/api/job/resource/ClusterCapacityTest.java
+++ b/hyracks-fullstack/hyracks/hyracks-api/src/test/java/org/apache/hyracks/api/job/resource/ClusterCapacityTest.java
@@ -47,14 +47,14 @@
         try {
             capacity.getMemoryByteSize(nodeId);
         } catch (HyracksException e) {
-            nodeNotExist = e.getErrorCode() == ErrorCode.NO_SUCH_NODE;
+            nodeNotExist = e.matches(ErrorCode.NO_SUCH_NODE);
         }
         Assert.assertTrue(nodeNotExist);
         nodeNotExist = false;
         try {
             capacity.getCores(nodeId);
         } catch (HyracksException e) {
-            nodeNotExist = e.getErrorCode() == ErrorCode.NO_SUCH_NODE;
+            nodeNotExist = e.matches(ErrorCode.NO_SUCH_NODE);
         }
         Assert.assertTrue(nodeNotExist);
 
@@ -70,14 +70,14 @@
         try {
             capacity.getMemoryByteSize(nodeId);
         } catch (HyracksException e) {
-            nodeNotExist = e.getErrorCode() == ErrorCode.NO_SUCH_NODE;
+            nodeNotExist = e.matches(ErrorCode.NO_SUCH_NODE);
         }
         Assert.assertTrue(nodeNotExist);
         nodeNotExist = false;
         try {
             capacity.getCores(nodeId);
         } catch (HyracksException e) {
-            nodeNotExist = e.getErrorCode() == ErrorCode.NO_SUCH_NODE;
+            nodeNotExist = e.matches(ErrorCode.NO_SUCH_NODE);
         }
         Assert.assertTrue(nodeNotExist);
     }
diff --git a/hyracks-fullstack/hyracks/hyracks-api/src/test/java/org/apache/hyracks/api/test/HyracksDataExceptionTest.java b/hyracks-fullstack/hyracks/hyracks-api/src/test/java/org/apache/hyracks/api/test/HyracksDataExceptionTest.java
index c8c1790..e4a49f0 100644
--- a/hyracks-fullstack/hyracks/hyracks-api/src/test/java/org/apache/hyracks/api/test/HyracksDataExceptionTest.java
+++ b/hyracks-fullstack/hyracks/hyracks-api/src/test/java/org/apache/hyracks/api/test/HyracksDataExceptionTest.java
@@ -20,7 +20,6 @@
 
 import org.apache.hyracks.api.exceptions.ErrorCode;
 import org.apache.hyracks.api.exceptions.HyracksDataException;
-import org.apache.hyracks.api.util.ErrorMessageUtil;
 import org.junit.Assert;
 import org.junit.Test;
 
@@ -32,12 +31,4 @@
         HyracksDataException causeWithNodeId = HyracksDataException.create(cause, "nc1");
         Assert.assertEquals(cause.getMessage(), causeWithNodeId.getMessage());
     }
-
-    @Test
-    public void returnedMessageWithNoComponentTest() {
-        HyracksDataException cause = new HyracksDataException(ErrorMessageUtil.NONE, ErrorCode.ERROR_PROCESSING_TUPLE,
-                ErrorCode.getErrorMessage(ErrorCode.ERROR_PROCESSING_TUPLE), 2);
-        HyracksDataException causeWithNodeId = HyracksDataException.create(cause, "nc1");
-        Assert.assertEquals(cause.getMessage(), causeWithNodeId.getMessage());
-    }
 }
\ No newline at end of file
diff --git a/hyracks-fullstack/hyracks/hyracks-client/src/main/java/org/apache/hyracks/client/result/ResultSetReader.java b/hyracks-fullstack/hyracks/hyracks-client/src/main/java/org/apache/hyracks/client/result/ResultSetReader.java
index 3c5a3d1..b29e2ea2 100644
--- a/hyracks-fullstack/hyracks/hyracks-client/src/main/java/org/apache/hyracks/client/result/ResultSetReader.java
+++ b/hyracks-fullstack/hyracks/hyracks-client/src/main/java/org/apache/hyracks/client/result/ResultSetReader.java
@@ -77,7 +77,7 @@
         try {
             return resultDirectory.getResultStatus(jobId, resultSetId);
         } catch (HyracksDataException e) {
-            if (e.getErrorCode() != ErrorCode.NO_RESULT_SET) {
+            if (!e.matches(ErrorCode.NO_RESULT_SET)) {
                 LOGGER.log(Level.WARN, "Exception retrieving result set for job " + jobId, e);
             }
         } catch (Exception e) {
@@ -135,7 +135,7 @@
         try {
             return resultDirectory.getResultMetadata(jobId, resultSetId);
         } catch (HyracksDataException e) {
-            if (e.getErrorCode() != ErrorCode.NO_RESULT_SET) {
+            if (!e.matches(ErrorCode.NO_RESULT_SET)) {
                 LOGGER.log(Level.WARN, "Exception retrieving result set for job " + jobId, e);
             }
         } catch (Exception e) {
diff --git a/hyracks-fullstack/hyracks/hyracks-control/hyracks-control-cc/src/test/java/org/apache/hyracks/control/cc/cluster/NodeManagerTest.java b/hyracks-fullstack/hyracks/hyracks-control/hyracks-control-cc/src/test/java/org/apache/hyracks/control/cc/cluster/NodeManagerTest.java
index 5c85134..9c7a43e 100644
--- a/hyracks-fullstack/hyracks/hyracks-control/hyracks-control-cc/src/test/java/org/apache/hyracks/control/cc/cluster/NodeManagerTest.java
+++ b/hyracks-fullstack/hyracks/hyracks-control/hyracks-control-cc/src/test/java/org/apache/hyracks/control/cc/cluster/NodeManagerTest.java
@@ -122,7 +122,7 @@
         try {
             nodeManager.addNode(NODE1, ncState1);
         } catch (HyracksException e) {
-            invalidNetworkAddress = e.getErrorCode() == ErrorCode.INVALID_NETWORK_ADDRESS;
+            invalidNetworkAddress = e.matches(ErrorCode.INVALID_NETWORK_ADDRESS);
         }
         Assert.assertTrue(invalidNetworkAddress);
 
@@ -150,7 +150,7 @@
         try {
             nodeManager.addNode(null, null);
         } catch (HyracksException e) {
-            invalidParameter = e.getErrorCode() == ErrorCode.INVALID_INPUT_PARAMETER;
+            invalidParameter = e.matches(ErrorCode.INVALID_INPUT_PARAMETER);
         }
         Assert.assertTrue(invalidParameter);
 
@@ -205,14 +205,14 @@
         try {
             capacity.getMemoryByteSize(nodeId);
         } catch (HyracksException e) {
-            nodeNotExist = e.getErrorCode() == ErrorCode.NO_SUCH_NODE;
+            nodeNotExist = e.matches(ErrorCode.NO_SUCH_NODE);
         }
         Assert.assertTrue(nodeNotExist);
         nodeNotExist = false;
         try {
             capacity.getCores(nodeId);
         } catch (HyracksException e) {
-            nodeNotExist = e.getErrorCode() == ErrorCode.NO_SUCH_NODE;
+            nodeNotExist = e.matches(ErrorCode.NO_SUCH_NODE);
         }
         Assert.assertTrue(nodeNotExist);
     }
@@ -230,7 +230,7 @@
         try {
             nodeManager.addNode(NODE2, ncState2);
         } catch (HyracksException e) {
-            nodeNotExist = e.getErrorCode() == ErrorCode.NO_SUCH_NODE;
+            nodeNotExist = e.matches(ErrorCode.NO_SUCH_NODE);
         }
         Assert.assertTrue(nodeNotExist);
         Assert.assertTrue(nodeManager.getIpAddressNodeNameMap().size() == 1);
diff --git a/hyracks-fullstack/hyracks/hyracks-control/hyracks-control-cc/src/test/java/org/apache/hyracks/control/cc/job/JobManagerTest.java b/hyracks-fullstack/hyracks/hyracks-control/hyracks-control-cc/src/test/java/org/apache/hyracks/control/cc/job/JobManagerTest.java
index 251aed8..19340d0 100644
--- a/hyracks-fullstack/hyracks/hyracks-control/hyracks-control-cc/src/test/java/org/apache/hyracks/control/cc/job/JobManagerTest.java
+++ b/hyracks-fullstack/hyracks/hyracks-control/hyracks-control-cc/src/test/java/org/apache/hyracks/control/cc/job/JobManagerTest.java
@@ -114,7 +114,7 @@
             jobManager.add(run);
         } catch (HyracksException e) {
             // Verifies the error code.
-            jobQueueFull = e.getErrorCode() == ErrorCode.JOB_QUEUE_FULL;
+            jobQueueFull = e.matches(ErrorCode.JOB_QUEUE_FULL);
         }
         Assert.assertTrue(jobQueueFull);
 
@@ -154,7 +154,7 @@
             jobManager.add(run);
         } catch (HyracksException e) {
             // Verifies the error code.
-            rejected = e.getErrorCode() == ErrorCode.JOB_REQUIREMENTS_EXCEED_CAPACITY;
+            rejected = e.matches(ErrorCode.JOB_REQUIREMENTS_EXCEED_CAPACITY);
         }
         Assert.assertTrue(rejected);
         Assert.assertTrue(jobManager.getRunningJobs().isEmpty());
@@ -200,7 +200,7 @@
         try {
             jobManager.add(null);
         } catch (HyracksException e) {
-            invalidParameter = e.getErrorCode() == ErrorCode.INVALID_INPUT_PARAMETER;
+            invalidParameter = e.matches(ErrorCode.INVALID_INPUT_PARAMETER);
         }
         Assert.assertTrue(invalidParameter);
         Assert.assertTrue(jobManager.getRunningJobs().isEmpty());
diff --git a/hyracks-fullstack/hyracks/hyracks-control/hyracks-control-nc/src/main/java/org/apache/hyracks/control/nc/heartbeat/HeartbeatManager.java b/hyracks-fullstack/hyracks/hyracks-control/hyracks-control-nc/src/main/java/org/apache/hyracks/control/nc/heartbeat/HeartbeatManager.java
index 08b8c11..20c1576 100644
--- a/hyracks-fullstack/hyracks/hyracks-control/hyracks-control-nc/src/main/java/org/apache/hyracks/control/nc/heartbeat/HeartbeatManager.java
+++ b/hyracks-fullstack/hyracks/hyracks-control/hyracks-control-nc/src/main/java/org/apache/hyracks/control/nc/heartbeat/HeartbeatManager.java
@@ -64,12 +64,12 @@
 
     public void notifyAck(HyracksDataException exception) {
         LOGGER.debug("ack rec'd from {} w/ exception: {}", ccId::toString, () -> String.valueOf(exception));
-        if (exception != null && exception.matches(ErrorCode.HYRACKS, ErrorCode.NO_SUCH_NODE)) {
+        if (exception != null && exception.matches(ErrorCode.NO_SUCH_NODE)) {
             LOGGER.info("{} indicates it does not recognize us; force a reconnect", ccId);
             try {
                 ccc.forceReregister(ncs);
             } catch (Exception e) {
-                LOGGER.warn("ignoring exception attempting to reregister with {}", ccId, e);
+                LOGGER.warn("ignoring exception attempting to re-register with {}", ccId, e);
             }
         }
     }
diff --git a/hyracks-fullstack/hyracks/hyracks-dataflow-std/src/main/java/org/apache/hyracks/dataflow/std/file/FieldCursorForDelimitedDataParser.java b/hyracks-fullstack/hyracks/hyracks-dataflow-std/src/main/java/org/apache/hyracks/dataflow/std/file/FieldCursorForDelimitedDataParser.java
index e401efc..936d63e 100644
--- a/hyracks-fullstack/hyracks/hyracks-dataflow-std/src/main/java/org/apache/hyracks/dataflow/std/file/FieldCursorForDelimitedDataParser.java
+++ b/hyracks-fullstack/hyracks/hyracks-dataflow-std/src/main/java/org/apache/hyracks/dataflow/std/file/FieldCursorForDelimitedDataParser.java
@@ -448,7 +448,6 @@
     }
 
     private void warn(String message) {
-        warnings.warn(Warning.forHyracks(null, ErrorCode.PARSING_ERROR, dataSourceName.get(), lineCount, fieldCount,
-                message));
+        warnings.warn(Warning.of(null, ErrorCode.PARSING_ERROR, dataSourceName.get(), lineCount, fieldCount, message));
     }
 }
diff --git a/hyracks-fullstack/hyracks/hyracks-examples/hyracks-integration-tests/src/test/java/org/apache/hyracks/tests/integration/CancelJobTest.java b/hyracks-fullstack/hyracks/hyracks-examples/hyracks-integration-tests/src/test/java/org/apache/hyracks/tests/integration/CancelJobTest.java
index c4f2ac6..dc5d017 100644
--- a/hyracks-fullstack/hyracks/hyracks-examples/hyracks-integration-tests/src/test/java/org/apache/hyracks/tests/integration/CancelJobTest.java
+++ b/hyracks-fullstack/hyracks/hyracks-examples/hyracks-integration-tests/src/test/java/org/apache/hyracks/tests/integration/CancelJobTest.java
@@ -155,7 +155,7 @@
             exceptionMatched = true;
             Assert.assertTrue(e instanceof HyracksException);
             HyracksException hyracksException = (HyracksException) e;
-            Assert.assertTrue(hyracksException.getErrorCode() == ErrorCode.JOB_CANCELED);
+            Assert.assertTrue(hyracksException.matches(ErrorCode.JOB_CANCELED));
         } finally {
             Assert.assertTrue(exceptionMatched);
         }
@@ -170,7 +170,7 @@
             waitForCompletion(jobId);
         } catch (HyracksException e) {
             exceptionMatched = true;
-            Assert.assertTrue(e.getErrorCode() == ErrorCode.JOB_CANCELED);
+            Assert.assertTrue(e.matches(ErrorCode.JOB_CANCELED));
         } finally {
             Assert.assertTrue(exceptionMatched);
         }
diff --git a/hyracks-fullstack/hyracks/hyracks-storage-am-common/src/main/java/org/apache/hyracks/storage/am/common/dataflow/IndexDropOperatorNodePushable.java b/hyracks-fullstack/hyracks/hyracks-storage-am-common/src/main/java/org/apache/hyracks/storage/am/common/dataflow/IndexDropOperatorNodePushable.java
index 8490c6a..e48db2b 100644
--- a/hyracks-fullstack/hyracks/hyracks-storage-am-common/src/main/java/org/apache/hyracks/storage/am/common/dataflow/IndexDropOperatorNodePushable.java
+++ b/hyracks-fullstack/hyracks/hyracks-storage-am-common/src/main/java/org/apache/hyracks/storage/am/common/dataflow/IndexDropOperatorNodePushable.java
@@ -96,11 +96,11 @@
     }
 
     private boolean isIgnorable(HyracksDataException e) {
-        return e.getErrorCode() == INDEX_DOES_NOT_EXIST && options.contains(IF_EXISTS);
+        return e.matches(INDEX_DOES_NOT_EXIST) && options.contains(IF_EXISTS);
     }
 
     private boolean canRetry(HyracksDataException e) throws HyracksDataException {
-        if (e.getErrorCode() == CANNOT_DROP_IN_USE_INDEX && options.contains(WAIT_ON_IN_USE)) {
+        if (e.matches(CANNOT_DROP_IN_USE_INDEX) && options.contains(WAIT_ON_IN_USE)) {
             if (maxWaitTimeMillis <= 0) {
                 return false;
             }
diff --git a/hyracks-fullstack/hyracks/hyracks-storage-am-common/src/main/java/org/apache/hyracks/storage/am/common/dataflow/IndexInsertUpdateDeleteOperatorNodePushable.java b/hyracks-fullstack/hyracks/hyracks-storage-am-common/src/main/java/org/apache/hyracks/storage/am/common/dataflow/IndexInsertUpdateDeleteOperatorNodePushable.java
index cf57d0e..9ff9249 100644
--- a/hyracks-fullstack/hyracks/hyracks-storage-am-common/src/main/java/org/apache/hyracks/storage/am/common/dataflow/IndexInsertUpdateDeleteOperatorNodePushable.java
+++ b/hyracks-fullstack/hyracks/hyracks-storage-am-common/src/main/java/org/apache/hyracks/storage/am/common/dataflow/IndexInsertUpdateDeleteOperatorNodePushable.java
@@ -114,7 +114,7 @@
                             indexAccessor.insert(tuple);
                         } catch (HyracksDataException e) {
                             // ignore that exception to allow inserting existing keys which becomes an NoOp
-                            if (e.getErrorCode() != ErrorCode.DUPLICATE_KEY) {
+                            if (!e.matches(ErrorCode.DUPLICATE_KEY)) {
                                 throw e;
                             }
                         }
@@ -132,8 +132,8 @@
                         try {
                             indexAccessor.delete(tuple);
                         } catch (HyracksDataException e) {
-                            // ingnore that exception to allow deletions of non-existing keys
-                            if (e.getErrorCode() != ErrorCode.UPDATE_OR_DELETE_NON_EXISTENT_KEY) {
+                            // ignore that exception to allow deletions of non-existing keys
+                            if (!e.matches(ErrorCode.UPDATE_OR_DELETE_NON_EXISTENT_KEY)) {
                                 throw e;
                             }
                         }
diff --git a/hyracks-fullstack/hyracks/hyracks-storage-am-lsm-common/src/main/java/org/apache/hyracks/storage/am/lsm/common/impls/IndexWithBuddyBulkLoader.java b/hyracks-fullstack/hyracks/hyracks-storage-am-lsm-common/src/main/java/org/apache/hyracks/storage/am/lsm/common/impls/IndexWithBuddyBulkLoader.java
index 17dfb1d..494dd52 100644
--- a/hyracks-fullstack/hyracks/hyracks-storage-am-lsm-common/src/main/java/org/apache/hyracks/storage/am/lsm/common/impls/IndexWithBuddyBulkLoader.java
+++ b/hyracks-fullstack/hyracks/hyracks-storage-am-lsm-common/src/main/java/org/apache/hyracks/storage/am/lsm/common/impls/IndexWithBuddyBulkLoader.java
@@ -40,7 +40,7 @@
             buddyBTreeBulkLoader.add(tuple);
         } catch (HyracksDataException e) {
             //deleting a key multiple times is OK
-            if (e.getErrorCode() != ErrorCode.DUPLICATE_KEY) {
+            if (!e.matches(ErrorCode.DUPLICATE_KEY)) {
                 cleanupArtifacts();
                 throw e;
             }
diff --git a/hyracks-fullstack/hyracks/hyracks-storage-am-lsm-invertedindex/src/main/java/org/apache/hyracks/storage/am/lsm/invertedindex/impls/LSMInvertedIndex.java b/hyracks-fullstack/hyracks/hyracks-storage-am-lsm-invertedindex/src/main/java/org/apache/hyracks/storage/am/lsm/invertedindex/impls/LSMInvertedIndex.java
index 1469304..de65e3e 100644
--- a/hyracks-fullstack/hyracks/hyracks-storage-am-lsm-invertedindex/src/main/java/org/apache/hyracks/storage/am/lsm/invertedindex/impls/LSMInvertedIndex.java
+++ b/hyracks-fullstack/hyracks/hyracks-storage-am-lsm-invertedindex/src/main/java/org/apache/hyracks/storage/am/lsm/invertedindex/impls/LSMInvertedIndex.java
@@ -178,7 +178,7 @@
                 try {
                     ctx.getCurrentDeletedKeysBTreeAccessors().insert(ctx.getKeysOnlyTuple());
                 } catch (HyracksDataException e) {
-                    if (e.getErrorCode() != ErrorCode.DUPLICATE_KEY) {
+                    if (!e.matches(ErrorCode.DUPLICATE_KEY)) {
                         // Key has already been deleted.
                         LOGGER.log(Level.WARN, "Failure during index delete operation", e);
                         throw e;
diff --git a/hyracks-fullstack/hyracks/hyracks-storage-am-lsm-invertedindex/src/main/java/org/apache/hyracks/storage/am/lsm/invertedindex/inmemory/InMemoryInvertedIndex.java b/hyracks-fullstack/hyracks/hyracks-storage-am-lsm-invertedindex/src/main/java/org/apache/hyracks/storage/am/lsm/invertedindex/inmemory/InMemoryInvertedIndex.java
index 5d74529..6998861 100644
--- a/hyracks-fullstack/hyracks/hyracks-storage-am-lsm-invertedindex/src/main/java/org/apache/hyracks/storage/am/lsm/invertedindex/inmemory/InMemoryInvertedIndex.java
+++ b/hyracks-fullstack/hyracks/hyracks-storage-am-lsm-invertedindex/src/main/java/org/apache/hyracks/storage/am/lsm/invertedindex/inmemory/InMemoryInvertedIndex.java
@@ -123,7 +123,7 @@
             try {
                 btreeAccessor.insert(insertTuple);
             } catch (HyracksDataException e) {
-                if (e.getErrorCode() != ErrorCode.DUPLICATE_KEY) {
+                if (!e.matches(ErrorCode.DUPLICATE_KEY)) {
                     // This exception may be caused by duplicate tokens in the same insert "document".
                     // We ignore such duplicate tokens in all inverted-index implementations, hence
                     // we can safely ignore this exception.
@@ -143,7 +143,7 @@
             try {
                 btreeAccessor.delete(deleteTuple);
             } catch (HyracksDataException e) {
-                if (e.getErrorCode() != ErrorCode.UPDATE_OR_DELETE_NON_EXISTENT_KEY) {
+                if (!e.matches(ErrorCode.UPDATE_OR_DELETE_NON_EXISTENT_KEY)) {
                     // Ignore this exception, since a document may have duplicate tokens.
                     throw e;
                 }
diff --git a/hyracks-fullstack/hyracks/hyracks-storage-am-lsm-rtree/src/main/java/org/apache/hyracks/storage/am/lsm/rtree/impls/AbstractLSMRTree.java b/hyracks-fullstack/hyracks/hyracks-storage-am-lsm-rtree/src/main/java/org/apache/hyracks/storage/am/lsm/rtree/impls/AbstractLSMRTree.java
index b04570e..1b847a0 100644
--- a/hyracks-fullstack/hyracks/hyracks-storage-am-lsm-rtree/src/main/java/org/apache/hyracks/storage/am/lsm/rtree/impls/AbstractLSMRTree.java
+++ b/hyracks-fullstack/hyracks/hyracks-storage-am-lsm-rtree/src/main/java/org/apache/hyracks/storage/am/lsm/rtree/impls/AbstractLSMRTree.java
@@ -220,7 +220,7 @@
             try {
                 ctx.getCurrentMutableBTreeAccessor().insert(indexTuple);
             } catch (HyracksDataException e) {
-                if (e.getErrorCode() != ErrorCode.DUPLICATE_KEY) {
+                if (!e.matches(ErrorCode.DUPLICATE_KEY)) {
                     // Do nothing, because one delete tuple is enough to indicate
                     // that all the corresponding insert tuples are deleted
                     throw e;
diff --git a/hyracks-fullstack/hyracks/hyracks-storage-am-lsm-rtree/src/main/java/org/apache/hyracks/storage/am/lsm/rtree/impls/LSMRTree.java b/hyracks-fullstack/hyracks/hyracks-storage-am-lsm-rtree/src/main/java/org/apache/hyracks/storage/am/lsm/rtree/impls/LSMRTree.java
index 92449e4..7afecd8 100644
--- a/hyracks-fullstack/hyracks/hyracks-storage-am-lsm-rtree/src/main/java/org/apache/hyracks/storage/am/lsm/rtree/impls/LSMRTree.java
+++ b/hyracks-fullstack/hyracks/hyracks-storage-am-lsm-rtree/src/main/java/org/apache/hyracks/storage/am/lsm/rtree/impls/LSMRTree.java
@@ -417,7 +417,7 @@
             } catch (HyracksDataException e) {
                 // Do nothing, because one delete tuple is enough to indicate
                 // that all the corresponding insert tuples are deleted
-                if (e.getErrorCode() != ErrorCode.DUPLICATE_KEY) {
+                if (!e.matches(ErrorCode.DUPLICATE_KEY)) {
                     throw e;
                 }
             }
diff --git a/hyracks-fullstack/hyracks/hyracks-storage-common/src/main/java/org/apache/hyracks/storage/common/buffercache/BufferCache.java b/hyracks-fullstack/hyracks/hyracks-storage-common/src/main/java/org/apache/hyracks/storage/common/buffercache/BufferCache.java
index 5afddef..f1fe86f 100644
--- a/hyracks-fullstack/hyracks/hyracks-storage-common/src/main/java/org/apache/hyracks/storage/common/buffercache/BufferCache.java
+++ b/hyracks-fullstack/hyracks/hyracks-storage-common/src/main/java/org/apache/hyracks/storage/common/buffercache/BufferCache.java
@@ -527,8 +527,8 @@
                 read(cPage);
                 return;
             } catch (HyracksDataException readException) {
-                if (readException.getErrorCode() == ErrorCode.CANNOT_READ_CLOSED_FILE && i <= MAX_PAGE_READ_ATTEMPTS) {
-                    /**
+                if (readException.matches(ErrorCode.CANNOT_READ_CLOSED_FILE) && i != MAX_PAGE_READ_ATTEMPTS) {
+                    /*
                      * if the read failure was due to another thread closing the file channel because
                      * it was interrupted, we will try to read again since the interrupted thread
                      * will re-open the file.
diff --git a/hyracks-fullstack/hyracks/hyracks-test-support/pom.xml b/hyracks-fullstack/hyracks/hyracks-test-support/pom.xml
index c162eb6..db7000c 100644
--- a/hyracks-fullstack/hyracks/hyracks-test-support/pom.xml
+++ b/hyracks-fullstack/hyracks/hyracks-test-support/pom.xml
@@ -116,5 +116,9 @@
       <groupId>commons-io</groupId>
       <artifactId>commons-io</artifactId>
     </dependency>
+    <dependency>
+      <groupId>org.mockito</groupId>
+      <artifactId>mockito-all</artifactId>
+    </dependency>
   </dependencies>
 </project>
diff --git a/hyracks-fullstack/hyracks/hyracks-test-support/src/main/java/org/apache/hyracks/storage/am/btree/OrderedIndexExamplesTest.java b/hyracks-fullstack/hyracks/hyracks-test-support/src/main/java/org/apache/hyracks/storage/am/btree/OrderedIndexExamplesTest.java
index c37d781..3560230 100644
--- a/hyracks-fullstack/hyracks/hyracks-test-support/src/main/java/org/apache/hyracks/storage/am/btree/OrderedIndexExamplesTest.java
+++ b/hyracks-fullstack/hyracks/hyracks-test-support/src/main/java/org/apache/hyracks/storage/am/btree/OrderedIndexExamplesTest.java
@@ -118,7 +118,7 @@
             try {
                 indexAccessor.insert(tuple);
             } catch (HyracksDataException e) {
-                if (e.getErrorCode() != ErrorCode.DUPLICATE_KEY) {
+                if (!e.matches(ErrorCode.DUPLICATE_KEY)) {
                     throw e;
                 }
             }
@@ -285,7 +285,7 @@
             try {
                 indexAccessor.insert(tuple);
             } catch (HyracksDataException e) {
-                if (e.getErrorCode() != ErrorCode.DUPLICATE_KEY) {
+                if (!e.matches(ErrorCode.DUPLICATE_KEY)) {
                     throw e;
                 }
             }
@@ -373,7 +373,7 @@
             try {
                 indexAccessor.insert(tuple);
             } catch (HyracksDataException e) {
-                if (e.getErrorCode() != ErrorCode.DUPLICATE_KEY) {
+                if (!e.matches(ErrorCode.DUPLICATE_KEY)) {
                     throw e;
                 }
             }
@@ -470,7 +470,7 @@
                     indexAccessor.insert(tuple);
                     insDone++;
                 } catch (HyracksDataException e) {
-                    if (e.getErrorCode() != ErrorCode.DUPLICATE_KEY) {
+                    if (!e.matches(ErrorCode.DUPLICATE_KEY)) {
                         throw e;
                     }
                 }
@@ -492,7 +492,7 @@
                     indexAccessor.delete(tuple);
                     delDone++;
                 } catch (HyracksDataException e) {
-                    if (e.getErrorCode() != ErrorCode.UPDATE_OR_DELETE_NON_EXISTENT_KEY) {
+                    if (!e.matches(ErrorCode.UPDATE_OR_DELETE_NON_EXISTENT_KEY)) {
                         throw e;
                     }
                 }
@@ -574,7 +574,7 @@
             try {
                 indexAccessor.insert(tuple);
             } catch (HyracksDataException e) {
-                if (e.getErrorCode() != ErrorCode.DUPLICATE_KEY) {
+                if (!e.matches(ErrorCode.DUPLICATE_KEY)) {
                     throw e;
                 }
             }
@@ -742,8 +742,8 @@
                 try {
                     bulkLoader.add(tuple);
                 } catch (HyracksDataException e) {
-                    if (e.getErrorCode() == ErrorCode.UNSORTED_LOAD_INPUT || e.getErrorCode() == ErrorCode.DUPLICATE_KEY
-                            || e.getErrorCode() == ErrorCode.DUPLICATE_LOAD_INPUT) {
+                    if (e.matchesAny(ErrorCode.UNSORTED_LOAD_INPUT, ErrorCode.DUPLICATE_KEY,
+                            ErrorCode.DUPLICATE_LOAD_INPUT)) {
                         if (j != i) {
                             fail("Unexpected exception: " + e.getMessage());
                         }
diff --git a/hyracks-fullstack/hyracks/hyracks-test-support/src/main/java/org/apache/hyracks/storage/am/btree/OrderedIndexTestUtils.java b/hyracks-fullstack/hyracks/hyracks-test-support/src/main/java/org/apache/hyracks/storage/am/btree/OrderedIndexTestUtils.java
index d3dac3e..c974987 100644
--- a/hyracks-fullstack/hyracks/hyracks-test-support/src/main/java/org/apache/hyracks/storage/am/btree/OrderedIndexTestUtils.java
+++ b/hyracks-fullstack/hyracks/hyracks-test-support/src/main/java/org/apache/hyracks/storage/am/btree/OrderedIndexTestUtils.java
@@ -309,7 +309,7 @@
                 }
             } catch (HyracksDataException e) {
                 // Ignore duplicate key insertions.
-                if (e.getErrorCode() != ErrorCode.DUPLICATE_KEY) {
+                if (!e.matches(ErrorCode.DUPLICATE_KEY)) {
                     throw e;
                 }
             }
diff --git a/hyracks-fullstack/hyracks/hyracks-test-support/src/main/java/org/apache/hyracks/storage/am/common/TreeIndexTestUtils.java b/hyracks-fullstack/hyracks/hyracks-test-support/src/main/java/org/apache/hyracks/storage/am/common/TreeIndexTestUtils.java
index 0c7b5f9..a298fe5 100644
--- a/hyracks-fullstack/hyracks/hyracks-test-support/src/main/java/org/apache/hyracks/storage/am/common/TreeIndexTestUtils.java
+++ b/hyracks-fullstack/hyracks/hyracks-test-support/src/main/java/org/apache/hyracks/storage/am/common/TreeIndexTestUtils.java
@@ -237,7 +237,7 @@
             } catch (HyracksDataException e) {
                 // We set expected values only after insertion succeeds because
                 // we ignore duplicate keys.
-                if (e.getErrorCode() != ErrorCode.DUPLICATE_KEY) {
+                if (!e.matches(ErrorCode.DUPLICATE_KEY)) {
                     throw e;
                 }
             }
@@ -291,7 +291,7 @@
             } catch (HyracksDataException e) {
                 // We set expected values only after insertion succeeds because
                 // we ignore duplicate keys.
-                if (e.getErrorCode() != ErrorCode.DUPLICATE_KEY) {
+                if (!e.matches(ErrorCode.DUPLICATE_KEY)) {
                     throw e;
                 }
             }
diff --git a/hyracks-fullstack/hyracks/hyracks-test-support/src/main/java/org/apache/hyracks/storage/am/rtree/AbstractRTreeExamplesTest.java b/hyracks-fullstack/hyracks/hyracks-test-support/src/main/java/org/apache/hyracks/storage/am/rtree/AbstractRTreeExamplesTest.java
index 48ae036..1fb5905 100644
--- a/hyracks-fullstack/hyracks/hyracks-test-support/src/main/java/org/apache/hyracks/storage/am/rtree/AbstractRTreeExamplesTest.java
+++ b/hyracks-fullstack/hyracks/hyracks-test-support/src/main/java/org/apache/hyracks/storage/am/rtree/AbstractRTreeExamplesTest.java
@@ -169,7 +169,7 @@
             try {
                 indexAccessor.insert(tuple);
             } catch (HyracksDataException e) {
-                if (e.getErrorCode() != ErrorCode.DUPLICATE_KEY) {
+                if (!e.matches(ErrorCode.DUPLICATE_KEY)) {
                     throw e;
                 }
             }
@@ -574,7 +574,7 @@
             try {
                 indexAccessor.insert(tuple);
             } catch (HyracksDataException e) {
-                if (e.getErrorCode() != ErrorCode.DUPLICATE_KEY) {
+                if (!e.matches(ErrorCode.DUPLICATE_KEY)) {
                     throw e;
                 }
             }
@@ -698,7 +698,7 @@
                 try {
                     indexAccessor.insert(tuple);
                 } catch (HyracksDataException e) {
-                    if (e.getErrorCode() != ErrorCode.DUPLICATE_KEY) {
+                    if (!e.matches(ErrorCode.DUPLICATE_KEY)) {
                         throw e;
                     }
                 }
@@ -715,7 +715,7 @@
                     indexAccessor.delete(tuple);
                     delDone++;
                 } catch (HyracksDataException e) {
-                    if (e.getErrorCode() != ErrorCode.UPDATE_OR_DELETE_NON_EXISTENT_KEY) {
+                    if (!e.matches(ErrorCode.UPDATE_OR_DELETE_NON_EXISTENT_KEY)) {
                         throw e;
                     }
                 }
diff --git a/hyracks-fullstack/hyracks/hyracks-test-support/src/main/java/org/apache/hyracks/storage/am/rtree/RTreeTestUtils.java b/hyracks-fullstack/hyracks/hyracks-test-support/src/main/java/org/apache/hyracks/storage/am/rtree/RTreeTestUtils.java
index 92f5055..55dcb5b 100644
--- a/hyracks-fullstack/hyracks/hyracks-test-support/src/main/java/org/apache/hyracks/storage/am/rtree/RTreeTestUtils.java
+++ b/hyracks-fullstack/hyracks/hyracks-test-support/src/main/java/org/apache/hyracks/storage/am/rtree/RTreeTestUtils.java
@@ -124,7 +124,7 @@
             } catch (HyracksDataException e) {
                 // We set expected values only after insertion succeeds because
                 // we ignore duplicate keys.
-                if (e.getErrorCode() != ErrorCode.DUPLICATE_KEY) {
+                if (!e.matches(ErrorCode.DUPLICATE_KEY)) {
                     throw e;
                 }
             }
diff --git a/hyracks-fullstack/hyracks/hyracks-test-support/src/main/java/org/apache/hyracks/test/support/FormattedExceptionTestBase.java b/hyracks-fullstack/hyracks/hyracks-test-support/src/main/java/org/apache/hyracks/test/support/FormattedExceptionTestBase.java
new file mode 100644
index 0000000..c912097
--- /dev/null
+++ b/hyracks-fullstack/hyracks/hyracks-test-support/src/main/java/org/apache/hyracks/test/support/FormattedExceptionTestBase.java
@@ -0,0 +1,299 @@
+/*
+ * 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.hyracks.test.support;
+
+import java.io.File;
+import java.io.Serializable;
+import java.lang.reflect.Array;
+import java.lang.reflect.Constructor;
+import java.lang.reflect.Executable;
+import java.lang.reflect.Field;
+import java.lang.reflect.Method;
+import java.lang.reflect.Modifier;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Comparator;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Objects;
+import java.util.Optional;
+import java.util.Set;
+import java.util.function.Predicate;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
+
+import org.apache.commons.io.FileUtils;
+import org.apache.commons.lang3.RandomUtils;
+import org.apache.commons.lang3.tuple.Pair;
+import org.apache.hyracks.api.exceptions.HyracksDataException;
+import org.apache.hyracks.api.exceptions.IError;
+import org.apache.hyracks.api.exceptions.IFormattedException;
+import org.apache.hyracks.api.exceptions.SourceLocation;
+import org.apache.logging.log4j.LogManager;
+import org.apache.logging.log4j.Logger;
+import org.junit.Assert;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+import org.mockito.Mockito;
+
+@RunWith(Parameterized.class)
+public class FormattedExceptionTestBase {
+    private static final Logger LOGGER = LogManager.getLogger();
+    private static final Serializable[] FAKE_ARGS = new Serializable[] { "one", 2, 3.0f, 4.0d, (byte) 0x05 };
+    private static final Serializable[] EMPTY_ARGS = new Serializable[0];
+    private static final Class SERIALIZABLE_ARR_CLASS = EMPTY_ARGS.getClass();
+    private static final org.apache.hyracks.api.exceptions.ErrorCode HYR_ERROR_CODE =
+            random(org.apache.hyracks.api.exceptions.ErrorCode.values());
+    private static final StackTraceElement[] STACK_TRACE = new Throwable().getStackTrace();
+    private static final SourceLocation SOURCE_LOCATION = new SourceLocation(99, 9);
+    private static final ClassLoader CLASSLOADER = FormattedExceptionTestBase.class.getClassLoader();
+    private static final Field THROWABLE_DETAIL_MESSAGE = getDeclaredAccessibleField(Throwable.class, "detailMessage");
+    private static final Field THROWABLE_CAUSE = getDeclaredAccessibleField(Throwable.class, "cause");
+    private static final UnsupportedOperationException FAKE_THROWABLE = new UnsupportedOperationException();
+    private static final int PUBLIC_STATIC = (Modifier.PUBLIC | Modifier.STATIC);
+    private static Collection<Class<? extends IFormattedException>> exceptionClasses;
+    protected static Set<Class<? extends IFormattedException>> roots;
+    private static Set<Executable> publicContractOverrides = new HashSet<>();
+    protected final Executable action;
+    protected final Class<? extends IFormattedException> root;
+    private static final Map<Pair<Class<? extends IFormattedException>, Object>, Field> rootFields = new HashMap<>();
+    private static final Set<Class> visited = new HashSet<>();
+    protected static Predicate<String> classSelector = className -> true;
+
+    protected static Iterable<Object[]> defineParameters() throws ClassNotFoundException {
+        initClasses();
+        List<Object[]> tests = new ArrayList<>();
+        for (Class<? extends IFormattedException> clazz : exceptionClasses) {
+            Class<? extends IFormattedException> root = roots.stream().filter(c -> c.isAssignableFrom(clazz)).findAny()
+                    .orElseThrow(IllegalStateException::new);
+            final Constructor<?>[] declaredConstructors = clazz.getDeclaredConstructors();
+            for (Constructor<?> ctor : declaredConstructors) {
+                tests.add(new Object[] { clazz.getSimpleName() + ".<init>"
+                        + Stream.of(ctor.getParameterTypes()).map(Class::getSimpleName).collect(Collectors.toList()),
+                        ctor, root });
+            }
+            int methods = 0;
+            for (Method m : clazz.getDeclaredMethods()) {
+                if ((m.getModifiers() & PUBLIC_STATIC) == PUBLIC_STATIC) {
+                    methods++;
+                    tests.add(new Object[] { clazz.getSimpleName() + "." + m.getName()
+                            + Stream.of(m.getParameterTypes()).map(Class::getSimpleName).collect(Collectors.toList()),
+                            m, root });
+                }
+            }
+            LOGGER.info("discovered {} ctors, {} methods for class {}", declaredConstructors.length, methods, clazz);
+        }
+        return tests;
+    }
+
+    protected static void addPublicContractOverride(Executable override) {
+        publicContractOverrides.add(override);
+    }
+
+    public FormattedExceptionTestBase(String desc, Executable action, Class<? extends IFormattedException> root) {
+        this.action = action;
+        this.root = root;
+    }
+
+    @Test
+    public void test() throws Exception {
+        if (Modifier.isPublic(action.getModifiers())) {
+            try {
+                checkPublicContract();
+            } catch (AssertionError e) {
+                if (publicContractOverrides.contains(action)) {
+                    LOGGER.info("ignoring public contract vioilation for override executable: " + action);
+                } else {
+                    throw e;
+                }
+            }
+        }
+        if (action.getName().equals("create") || action instanceof Constructor) {
+            checkParameterPropagation(action);
+        }
+    }
+
+    protected void checkPublicContract() {
+        for (Class type : action.getParameterTypes()) {
+            Assert.assertNotEquals("generic IError forbidden on public ctor or static method", type, IError.class);
+        }
+    }
+
+    private void checkParameterPropagation(Executable factory) throws Exception {
+        Object[] args = Stream.of(factory.getParameterTypes()).map(this::defaultValue).toArray(Object[]::new);
+        factory.setAccessible(true);
+        Field paramsField = rootParamsField();
+        Object instance = factory instanceof Constructor ? ((Constructor) factory).newInstance(args)
+                : ((Method) factory).invoke(null, args);
+        Serializable[] params = (Serializable[]) paramsField.get(instance);
+        IError error = null;
+        for (Class type : factory.getParameterTypes()) {
+            if (type.equals(paramsField.getType())) {
+                Assert.assertArrayEquals(FAKE_ARGS, params);
+            } else if (SourceLocation.class.isAssignableFrom(type)) {
+                final Object value = rootSrcLocField().get(instance);
+                Assert.assertEquals("source location is wrong, was: " + value, SOURCE_LOCATION, value);
+            } else if (IError.class.isAssignableFrom(type)) {
+                error = (IError) rootErrorField().get(instance);
+                Assert.assertNotNull("error object", error);
+            } else if (type.equals(Throwable.class)) {
+                Assert.assertEquals(FAKE_THROWABLE, THROWABLE_CAUSE.get(instance));
+            }
+        }
+        if (error != null) {
+            Assert.assertEquals(error.component(), getRootField("component").get(instance));
+            Assert.assertEquals(error.intValue(), getRootField("errorCode").get(instance));
+            Assert.assertEquals(error.errorMessage(), THROWABLE_DETAIL_MESSAGE.get(instance));
+        }
+    }
+
+    protected Field rootParamsField() {
+        return getRootField(SERIALIZABLE_ARR_CLASS);
+    }
+
+    protected Field rootErrorField() {
+        return getRootField(IError.class);
+    }
+
+    protected Field rootSrcLocField() {
+        return getRootField(SourceLocation.class);
+    }
+
+    protected Field getRootField(Class<?> type) {
+        return rootFields.computeIfAbsent(Pair.of(root, type),
+                key -> Stream.of(root.getDeclaredFields()).filter(f -> f.getType().equals(type))
+                        .peek(f -> f.setAccessible(true)).findAny().orElseThrow(IllegalStateException::new));
+    }
+
+    protected Field getRootField(String name) {
+        return rootFields.computeIfAbsent(Pair.of(root, name), key -> getDeclaredAccessibleField(root, name));
+    }
+
+    protected static Field getDeclaredAccessibleField(Class clazz, String name) {
+        try {
+            Field field = clazz.getDeclaredField(name);
+            field.setAccessible(true);
+            return field;
+        } catch (NoSuchFieldException e) {
+            throw new IllegalStateException(e);
+        }
+    }
+
+    protected Object defaultValue(Class type) {
+        switch (type.getName()) {
+            case "int":
+                return 0;
+            case "float":
+                return 0.0f;
+            case "double":
+                return 0.0d;
+            case "long":
+                return 0L;
+            case "boolean":
+                return false;
+            case "short":
+                return (short) 0;
+            case "byte":
+                return (byte) 0;
+            case "[Ljava.io.Serializable;":
+                return FAKE_ARGS;
+            case "java.lang.Throwable":
+                return FAKE_THROWABLE;
+            case "org.apache.hyracks.api.exceptions.IError":
+            case "org.apache.hyracks.api.exceptions.ErrorCode":
+                return HYR_ERROR_CODE;
+            case "[Ljava.lang.StackTraceElement;":
+                return STACK_TRACE;
+            case "org.apache.hyracks.api.exceptions.SourceLocation":
+                return SOURCE_LOCATION;
+            case "org.apache.hyracks.api.exceptions.HyracksDataException":
+                HyracksDataException hde = Mockito.mock(HyracksDataException.class);
+                Mockito.when(hde.getError()).thenReturn(Optional.empty());
+                return hde;
+            default:
+                if (type.isArray()) {
+                    return Array.newInstance(type.getComponentType(), 0);
+                } else if (type.isEnum()) {
+                    return random(type.getEnumConstants());
+                } else if (type.isAnonymousClass() || Modifier.isFinal(type.getModifiers())) {
+                    if (visited.add(type)) {
+                        LOGGER.info("defaulting to null for un-mockable class {}", type.getName());
+                    }
+                    return null;
+                }
+                if (visited.add(type)) {
+                    LOGGER.info("defaulting to mock for unmapped class {}", type.getName());
+                }
+                return Mockito.mock(type);
+        }
+    }
+
+    protected static <T> T random(T[] values) {
+        return values[RandomUtils.nextInt(0, values.length)];
+    }
+
+    @SuppressWarnings("unchecked")
+    private static void initClasses() throws ClassNotFoundException {
+        LOGGER.info("discovering instances of IFormattedException");
+        //noinspection unchecked
+        final Class<IFormattedException> clazz =
+                (Class) Class.forName(IFormattedException.class.getName(), false, CLASSLOADER);
+        exceptionClasses =
+                getInstanceClasses(clazz).sorted(Comparator.comparing(Class::getName)).collect(Collectors.toList());
+        exceptionClasses.remove(clazz);
+        LOGGER.info("found {} instances of IFormattedException: {}", exceptionClasses.size(), exceptionClasses);
+
+        roots = exceptionClasses.stream().map(ex -> {
+            while (IFormattedException.class.isAssignableFrom(ex.getSuperclass())) {
+                ex = (Class<? extends IFormattedException>) ex.getSuperclass();
+            }
+            return ex;
+        }).collect(Collectors.toSet());
+        LOGGER.info("found {} roots: {}", roots.size(), roots);
+        exceptionClasses.removeAll(roots);
+    }
+
+    @SuppressWarnings("unchecked")
+    private static <T> Stream<Class<? extends T>> getInstanceClasses(Class<T> clazz) {
+        return (Stream) getProductClasses().filter(name -> name.matches(".*(Exception|Error|Warning).*")).map(name -> {
+            try {
+                return Class.forName(name, false, CLASSLOADER);
+            } catch (Throwable e) {
+                LOGGER.warn("unable to open {} due to: {}", name, String.valueOf(e));
+                return null;
+            }
+        }).filter(Objects::nonNull).filter(clazz::isAssignableFrom);
+    }
+
+    private static Stream<String> getProductClasses() {
+        String[] cp = System.getProperty("java.class.path").split(File.pathSeparator);
+        return Stream.of(cp).map(File::new).filter(File::isDirectory)
+                .flatMap(FormattedExceptionTestBase::extractClassFiles).map(name -> name.replace("/", "."))
+                .filter(classSelector).map(name -> name.replaceAll("\\.class$", "")).sorted();
+    }
+
+    private static Stream<? extends String> extractClassFiles(File dir) {
+        final int beginIndex = dir.toString().length() + 1;
+        return FileUtils.listFiles(dir, new String[] { "class" }, true).stream()
+                .map(file -> file.getAbsolutePath().substring(beginIndex));
+    }
+}
diff --git a/hyracks-fullstack/hyracks/hyracks-tests/hyracks-storage-am-btree-test/src/test/java/org/apache/hyracks/storage/am/btree/BTreeStatsTest.java b/hyracks-fullstack/hyracks/hyracks-tests/hyracks-storage-am-btree-test/src/test/java/org/apache/hyracks/storage/am/btree/BTreeStatsTest.java
index dfaa7f9..7a24727 100644
--- a/hyracks-fullstack/hyracks/hyracks-tests/hyracks-storage-am-btree-test/src/test/java/org/apache/hyracks/storage/am/btree/BTreeStatsTest.java
+++ b/hyracks-fullstack/hyracks/hyracks-tests/hyracks-storage-am-btree-test/src/test/java/org/apache/hyracks/storage/am/btree/BTreeStatsTest.java
@@ -136,7 +136,7 @@
             try {
                 indexAccessor.insert(tuple);
             } catch (HyracksDataException e) {
-                if (e.getErrorCode() != ErrorCode.DUPLICATE_KEY) {
+                if (!e.matches(ErrorCode.DUPLICATE_KEY)) {
                     e.printStackTrace();
                     throw e;
                 }
diff --git a/hyracks-fullstack/hyracks/hyracks-tests/hyracks-storage-am-btree-test/src/test/java/org/apache/hyracks/storage/am/btree/BTreeUpdateSearchTest.java b/hyracks-fullstack/hyracks/hyracks-tests/hyracks-storage-am-btree-test/src/test/java/org/apache/hyracks/storage/am/btree/BTreeUpdateSearchTest.java
index 8e5c77d..5b86b4f 100644
--- a/hyracks-fullstack/hyracks/hyracks-tests/hyracks-storage-am-btree-test/src/test/java/org/apache/hyracks/storage/am/btree/BTreeUpdateSearchTest.java
+++ b/hyracks-fullstack/hyracks/hyracks-tests/hyracks-storage-am-btree-test/src/test/java/org/apache/hyracks/storage/am/btree/BTreeUpdateSearchTest.java
@@ -117,7 +117,7 @@
                 try {
                     indexAccessor.insert(insertTuple);
                 } catch (HyracksDataException hde) {
-                    if (hde.getErrorCode() != ErrorCode.DUPLICATE_KEY) {
+                    if (!hde.matches(ErrorCode.DUPLICATE_KEY)) {
                         hde.printStackTrace();
                         throw hde;
                     }
diff --git a/hyracks-fullstack/hyracks/hyracks-tests/hyracks-storage-am-btree-test/src/test/java/org/apache/hyracks/storage/am/btree/multithread/BTreeTestWorker.java b/hyracks-fullstack/hyracks/hyracks-tests/hyracks-storage-am-btree-test/src/test/java/org/apache/hyracks/storage/am/btree/multithread/BTreeTestWorker.java
index a67450b..5d74fc9 100644
--- a/hyracks-fullstack/hyracks/hyracks-tests/hyracks-storage-am-btree-test/src/test/java/org/apache/hyracks/storage/am/btree/multithread/BTreeTestWorker.java
+++ b/hyracks-fullstack/hyracks/hyracks-tests/hyracks-storage-am-btree-test/src/test/java/org/apache/hyracks/storage/am/btree/multithread/BTreeTestWorker.java
@@ -62,7 +62,7 @@
                     try {
                         accessor.insert(tuple);
                     } catch (HyracksDataException e) {
-                        if (e.getErrorCode() != ErrorCode.DUPLICATE_KEY) {
+                        if (!e.matches(ErrorCode.DUPLICATE_KEY)) {
                             // Ignore duplicate keys, since we get random tuples.
                             throw e;
                         }
@@ -79,7 +79,7 @@
                     try {
                         accessor.delete(deleteTuple);
                     } catch (HyracksDataException e) {
-                        if (e.getErrorCode() != ErrorCode.UPDATE_OR_DELETE_NON_EXISTENT_KEY) {
+                        if (!e.matches(ErrorCode.UPDATE_OR_DELETE_NON_EXISTENT_KEY)) {
                             // Ignore non-existant keys, since we get random tuples.
                             throw e;
                         }
@@ -91,8 +91,8 @@
                         accessor.update(tuple);
                     } catch (HyracksDataException e) {
                         // Ignore non-existant keys, since we get random tuples.
-                        if (e.getErrorCode() != ErrorCode.UPDATE_OR_DELETE_NON_EXISTENT_KEY
-                                && e.getErrorCode() != ErrorCode.INDEX_NOT_UPDATABLE) {
+                        if (!e.matches(ErrorCode.UPDATE_OR_DELETE_NON_EXISTENT_KEY)
+                                && !e.matches(ErrorCode.INDEX_NOT_UPDATABLE)) {
                             // Ignore non-existant keys, since we get random tuples.
                             // Ignore not updateable exception due to numKeys == numFields.
                             throw e;
diff --git a/hyracks-fullstack/hyracks/hyracks-tests/hyracks-storage-am-lsm-btree-test/src/test/java/org/apache/hyracks/storage/am/lsm/btree/LSMBTreeScanDiskComponentsTest.java b/hyracks-fullstack/hyracks/hyracks-tests/hyracks-storage-am-lsm-btree-test/src/test/java/org/apache/hyracks/storage/am/lsm/btree/LSMBTreeScanDiskComponentsTest.java
index b47f5dd..c9c87bd 100644
--- a/hyracks-fullstack/hyracks/hyracks-tests/hyracks-storage-am-lsm-btree-test/src/test/java/org/apache/hyracks/storage/am/lsm/btree/LSMBTreeScanDiskComponentsTest.java
+++ b/hyracks-fullstack/hyracks/hyracks-tests/hyracks-storage-am-lsm-btree-test/src/test/java/org/apache/hyracks/storage/am/lsm/btree/LSMBTreeScanDiskComponentsTest.java
@@ -205,7 +205,7 @@
         try {
             ctx.getIndexAccessor().upsert(tuple);
         } catch (HyracksDataException e) {
-            if (e.getErrorCode() != ErrorCode.DUPLICATE_KEY) {
+            if (!e.matches(ErrorCode.DUPLICATE_KEY)) {
                 throw e;
             }
         }
@@ -222,7 +222,7 @@
         try {
             ctx.getIndexAccessor().delete(deleteTuple);
         } catch (HyracksDataException e) {
-            if (e.getErrorCode() != ErrorCode.DUPLICATE_KEY) {
+            if (!e.matches(ErrorCode.DUPLICATE_KEY)) {
                 throw e;
             }
         }
diff --git a/hyracks-fullstack/hyracks/hyracks-tests/hyracks-storage-am-lsm-btree-test/src/test/java/org/apache/hyracks/storage/am/lsm/btree/LSMBTreeUpdateInPlaceScanDiskComponentsTest.java b/hyracks-fullstack/hyracks/hyracks-tests/hyracks-storage-am-lsm-btree-test/src/test/java/org/apache/hyracks/storage/am/lsm/btree/LSMBTreeUpdateInPlaceScanDiskComponentsTest.java
index bbe0966..8d82405 100644
--- a/hyracks-fullstack/hyracks/hyracks-tests/hyracks-storage-am-lsm-btree-test/src/test/java/org/apache/hyracks/storage/am/lsm/btree/LSMBTreeUpdateInPlaceScanDiskComponentsTest.java
+++ b/hyracks-fullstack/hyracks/hyracks-tests/hyracks-storage-am-lsm-btree-test/src/test/java/org/apache/hyracks/storage/am/lsm/btree/LSMBTreeUpdateInPlaceScanDiskComponentsTest.java
@@ -140,7 +140,7 @@
                 } catch (HyracksDataException e) {
                     // We set expected values only after insertion succeeds because
                     // we ignore duplicate keys.
-                    if (e.getErrorCode() != ErrorCode.DUPLICATE_KEY) {
+                    if (!e.matches(ErrorCode.DUPLICATE_KEY)) {
                         throw e;
                     }
                 }
@@ -162,7 +162,7 @@
                 } catch (HyracksDataException e) {
                     // We set expected values only after insertion succeeds because
                     // we ignore duplicate keys.
-                    if (e.getErrorCode() != ErrorCode.DUPLICATE_KEY) {
+                    if (!e.matches(ErrorCode.DUPLICATE_KEY)) {
                         throw e;
                     }
                 }
diff --git a/hyracks-fullstack/hyracks/hyracks-tests/hyracks-storage-am-lsm-btree-test/src/test/java/org/apache/hyracks/storage/am/lsm/btree/cursor/LSMBTreeBatchPointSearchCursorTest.java b/hyracks-fullstack/hyracks/hyracks-tests/hyracks-storage-am-lsm-btree-test/src/test/java/org/apache/hyracks/storage/am/lsm/btree/cursor/LSMBTreeBatchPointSearchCursorTest.java
index 82aeed2..91e2a09 100644
--- a/hyracks-fullstack/hyracks/hyracks-tests/hyracks-storage-am-lsm-btree-test/src/test/java/org/apache/hyracks/storage/am/lsm/btree/cursor/LSMBTreeBatchPointSearchCursorTest.java
+++ b/hyracks-fullstack/hyracks/hyracks-tests/hyracks-storage-am-lsm-btree-test/src/test/java/org/apache/hyracks/storage/am/lsm/btree/cursor/LSMBTreeBatchPointSearchCursorTest.java
@@ -32,6 +32,7 @@
 import org.apache.hyracks.api.dataflow.value.RecordDescriptor;
 import org.apache.hyracks.api.exceptions.ErrorCode;
 import org.apache.hyracks.api.exceptions.HyracksDataException;
+import org.apache.hyracks.api.exceptions.IFormattedException;
 import org.apache.hyracks.data.std.accessors.IntegerBinaryComparatorFactory;
 import org.apache.hyracks.data.std.primitive.IntegerPointable;
 import org.apache.hyracks.dataflow.common.comm.io.ArrayTupleBuilder;
@@ -153,14 +154,11 @@
                 TupleUtils.createIntegerTuple(tb, tuple, f0, f1);
                 try {
                     indexAccessor.insert(tuple);
-                } catch (HyracksDataException e) {
-                    if (e.getErrorCode() != ErrorCode.DUPLICATE_KEY) {
+                } catch (Exception e) {
+                    if (!IFormattedException.matches(e, ErrorCode.DUPLICATE_KEY)) {
                         e.printStackTrace();
                         throw e;
                     }
-                } catch (Exception e) {
-                    e.printStackTrace();
-                    throw e;
                 }
             }
         } finally {
diff --git a/hyracks-fullstack/hyracks/hyracks-tests/hyracks-storage-am-lsm-btree-test/src/test/java/org/apache/hyracks/storage/am/lsm/btree/cursor/LSMBTreePointSearchCursorTest.java b/hyracks-fullstack/hyracks/hyracks-tests/hyracks-storage-am-lsm-btree-test/src/test/java/org/apache/hyracks/storage/am/lsm/btree/cursor/LSMBTreePointSearchCursorTest.java
index 3c4ae51..5e5410c 100644
--- a/hyracks-fullstack/hyracks/hyracks-tests/hyracks-storage-am-lsm-btree-test/src/test/java/org/apache/hyracks/storage/am/lsm/btree/cursor/LSMBTreePointSearchCursorTest.java
+++ b/hyracks-fullstack/hyracks/hyracks-tests/hyracks-storage-am-lsm-btree-test/src/test/java/org/apache/hyracks/storage/am/lsm/btree/cursor/LSMBTreePointSearchCursorTest.java
@@ -145,7 +145,7 @@
                 try {
                     indexAccessor.insert(tuple);
                 } catch (HyracksDataException e) {
-                    if (e.getErrorCode() != ErrorCode.DUPLICATE_KEY) {
+                    if (!e.matches(ErrorCode.DUPLICATE_KEY)) {
                         e.printStackTrace();
                         throw e;
                     }
diff --git a/hyracks-fullstack/hyracks/hyracks-tests/hyracks-storage-am-lsm-btree-test/src/test/java/org/apache/hyracks/storage/am/lsm/btree/multithread/LSMBTreeTestWorker.java b/hyracks-fullstack/hyracks/hyracks-tests/hyracks-storage-am-lsm-btree-test/src/test/java/org/apache/hyracks/storage/am/lsm/btree/multithread/LSMBTreeTestWorker.java
index 583fd5a..60a3fa7 100644
--- a/hyracks-fullstack/hyracks/hyracks-tests/hyracks-storage-am-lsm-btree-test/src/test/java/org/apache/hyracks/storage/am/lsm/btree/multithread/LSMBTreeTestWorker.java
+++ b/hyracks-fullstack/hyracks/hyracks-tests/hyracks-storage-am-lsm-btree-test/src/test/java/org/apache/hyracks/storage/am/lsm/btree/multithread/LSMBTreeTestWorker.java
@@ -63,7 +63,7 @@
                 try {
                     accessor.insert(tuple);
                 } catch (HyracksDataException e) {
-                    if (e.getErrorCode() != ErrorCode.DUPLICATE_KEY) {
+                    if (!e.matches(ErrorCode.DUPLICATE_KEY)) {
                         // Ignore duplicate keys, since we get random tuples.
                         throw e;
                     }
@@ -81,7 +81,7 @@
                     accessor.delete(deleteTuple);
                 } catch (HyracksDataException e) {
                     // Ignore non-existant keys, since we get random tuples.
-                    if (e.getErrorCode() != ErrorCode.UPDATE_OR_DELETE_NON_EXISTENT_KEY) {
+                    if (!e.matches(ErrorCode.UPDATE_OR_DELETE_NON_EXISTENT_KEY)) {
                         throw e;
                     }
                 }
@@ -91,8 +91,8 @@
                 try {
                     accessor.update(tuple);
                 } catch (HyracksDataException e) {
-                    if (e.getErrorCode() != ErrorCode.UPDATE_OR_DELETE_NON_EXISTENT_KEY
-                            && e.getErrorCode() != ErrorCode.INDEX_NOT_UPDATABLE) {
+                    if (!e.matches(ErrorCode.UPDATE_OR_DELETE_NON_EXISTENT_KEY)
+                            && !e.matches(ErrorCode.INDEX_NOT_UPDATABLE)) {
                         // Ignore non-existant keys, since we get random tuples.
                         // Ignore not updateable exception due to numKeys == numFields.
                         throw e;
diff --git a/hyracks-fullstack/hyracks/hyracks-tests/hyracks-storage-am-lsm-invertedindex-test/src/test/java/org/apache/hyracks/storage/am/lsm/invertedindex/multithread/LSMInvertedIndexTestWorker.java b/hyracks-fullstack/hyracks/hyracks-tests/hyracks-storage-am-lsm-invertedindex-test/src/test/java/org/apache/hyracks/storage/am/lsm/invertedindex/multithread/LSMInvertedIndexTestWorker.java
index 9818147..6f742ab 100644
--- a/hyracks-fullstack/hyracks/hyracks-tests/hyracks-storage-am-lsm-invertedindex-test/src/test/java/org/apache/hyracks/storage/am/lsm/invertedindex/multithread/LSMInvertedIndexTestWorker.java
+++ b/hyracks-fullstack/hyracks/hyracks-tests/hyracks-storage-am-lsm-invertedindex-test/src/test/java/org/apache/hyracks/storage/am/lsm/invertedindex/multithread/LSMInvertedIndexTestWorker.java
@@ -125,7 +125,7 @@
                     consumeCursorTuples(searchCursor);
                 } catch (HyracksDataException e) {
                     // Ignore.
-                    if (e.getErrorCode() != ErrorCode.OCCURRENCE_THRESHOLD_PANIC_EXCEPTION) {
+                    if (!e.matches(ErrorCode.OCCURRENCE_THRESHOLD_PANIC_EXCEPTION)) {
                         throw e;
                     }
                 }
diff --git a/hyracks-fullstack/hyracks/hyracks-tests/hyracks-storage-am-lsm-invertedindex-test/src/test/java/org/apache/hyracks/storage/am/lsm/invertedindex/util/LSMInvertedIndexTestUtils.java b/hyracks-fullstack/hyracks/hyracks-tests/hyracks-storage-am-lsm-invertedindex-test/src/test/java/org/apache/hyracks/storage/am/lsm/invertedindex/util/LSMInvertedIndexTestUtils.java
index 3cc0913..aa9cd5a 100644
--- a/hyracks-fullstack/hyracks/hyracks-tests/hyracks-storage-am-lsm-invertedindex-test/src/test/java/org/apache/hyracks/storage/am/lsm/invertedindex/util/LSMInvertedIndexTestUtils.java
+++ b/hyracks-fullstack/hyracks/hyracks-tests/hyracks-storage-am-lsm-invertedindex-test/src/test/java/org/apache/hyracks/storage/am/lsm/invertedindex/util/LSMInvertedIndexTestUtils.java
@@ -606,7 +606,7 @@
                     accessor.search(resultCursor, searchPred);
                 } catch (HyracksDataException e) {
                     // ignore panic queries.
-                    if (e.getErrorCode() == ErrorCode.OCCURRENCE_THRESHOLD_PANIC_EXCEPTION) {
+                    if (e.matches(ErrorCode.OCCURRENCE_THRESHOLD_PANIC_EXCEPTION)) {
                         panic = true;
                     } else {
                         throw e;
@@ -625,7 +625,7 @@
                                 actualResults.add(Integer.valueOf(actual));
                             }
                         } catch (HyracksDataException e) {
-                            if (e.getErrorCode() == ErrorCode.OCCURRENCE_THRESHOLD_PANIC_EXCEPTION) {
+                            if (e.matches(ErrorCode.OCCURRENCE_THRESHOLD_PANIC_EXCEPTION)) {
                                 // Ignore panic queries.
                                 continue;
                             } else {
diff --git a/hyracks-fullstack/hyracks/hyracks-tests/hyracks-storage-am-lsm-rtree-test/src/test/java/org/apache/hyracks/storage/am/lsm/rtree/AbstractLSMRTreeExamplesTest.java b/hyracks-fullstack/hyracks/hyracks-tests/hyracks-storage-am-lsm-rtree-test/src/test/java/org/apache/hyracks/storage/am/lsm/rtree/AbstractLSMRTreeExamplesTest.java
index 39fb98f..9698578 100644
--- a/hyracks-fullstack/hyracks/hyracks-tests/hyracks-storage-am-lsm-rtree-test/src/test/java/org/apache/hyracks/storage/am/lsm/rtree/AbstractLSMRTreeExamplesTest.java
+++ b/hyracks-fullstack/hyracks/hyracks-tests/hyracks-storage-am-lsm-rtree-test/src/test/java/org/apache/hyracks/storage/am/lsm/rtree/AbstractLSMRTreeExamplesTest.java
@@ -134,7 +134,7 @@
             try {
                 indexAccessor.insert(tuple);
             } catch (HyracksDataException e) {
-                if (e.getErrorCode() != ErrorCode.DUPLICATE_KEY) {
+                if (!e.matches(ErrorCode.DUPLICATE_KEY)) {
                     throw e;
                 }
             }
diff --git a/hyracks-fullstack/hyracks/hyracks-tests/hyracks-storage-am-rtree-test/src/test/java/org/apache/hyracks/storage/am/rtree/RTreeSearchCursorTest.java b/hyracks-fullstack/hyracks/hyracks-tests/hyracks-storage-am-rtree-test/src/test/java/org/apache/hyracks/storage/am/rtree/RTreeSearchCursorTest.java
index faf0693..bef7ac7 100644
--- a/hyracks-fullstack/hyracks/hyracks-tests/hyracks-storage-am-rtree-test/src/test/java/org/apache/hyracks/storage/am/rtree/RTreeSearchCursorTest.java
+++ b/hyracks-fullstack/hyracks/hyracks-tests/hyracks-storage-am-rtree-test/src/test/java/org/apache/hyracks/storage/am/rtree/RTreeSearchCursorTest.java
@@ -168,7 +168,7 @@
             try {
                 indexAccessor.insert(tuple);
             } catch (HyracksDataException e) {
-                if (e.getErrorCode() != ErrorCode.DUPLICATE_KEY) {
+                if (!e.matches(ErrorCode.DUPLICATE_KEY)) {
                     throw e;
                 }
             }