Merge branch 'cheshire-cat'

Change-Id: Iaa3ab431d3225c9f95ec530b8099bf211684c34f
diff --git a/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/optimizer/base/AnalysisUtil.java b/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/optimizer/base/AnalysisUtil.java
index 7eea595..8b5c8bc 100644
--- a/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/optimizer/base/AnalysisUtil.java
+++ b/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/optimizer/base/AnalysisUtil.java
@@ -28,6 +28,7 @@
 import org.apache.asterix.om.functions.BuiltinFunctions;
 import org.apache.asterix.optimizer.rules.am.AccessMethodUtils;
 import org.apache.commons.lang3.mutable.Mutable;
+import org.apache.hyracks.algebricks.common.exceptions.AlgebricksException;
 import org.apache.hyracks.algebricks.common.utils.Pair;
 import org.apache.hyracks.algebricks.core.algebra.base.ILogicalExpression;
 import org.apache.hyracks.algebricks.core.algebra.base.ILogicalOperator;
@@ -127,7 +128,7 @@
         return new Pair<>(srcId.getDataverseName(), srcId.getDatasourceName());
     }
 
-    public static Pair<DataverseName, String> getExternalDatasetInfo(UnnestMapOperator op) {
+    public static Pair<DataverseName, String> getExternalDatasetInfo(UnnestMapOperator op) throws AlgebricksException {
         AbstractFunctionCallExpression unnestExpr = (AbstractFunctionCallExpression) op.getExpressionRef().getValue();
         DataverseName dataverseName = DataverseName
                 .createFromCanonicalForm(AccessMethodUtils.getStringConstant(unnestExpr.getArguments().get(0)));
diff --git a/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/IntroduceMaterializationForInsertWithSelfScanRule.java b/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/IntroduceMaterializationForInsertWithSelfScanRule.java
index d838d71..5e60b6f 100644
--- a/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/IntroduceMaterializationForInsertWithSelfScanRule.java
+++ b/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/IntroduceMaterializationForInsertWithSelfScanRule.java
@@ -83,7 +83,8 @@
 
     }
 
-    private boolean checkIfInsertAndScanDatasetsSame(AbstractLogicalOperator op, String insertDatasetName) {
+    private boolean checkIfInsertAndScanDatasetsSame(AbstractLogicalOperator op, String insertDatasetName)
+            throws AlgebricksException {
         boolean sameDataset = false;
         for (int i = 0; i < op.getInputs().size(); ++i) {
             AbstractLogicalOperator descendantOp = (AbstractLogicalOperator) op.getInputs().get(i).getValue();
diff --git a/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/PushLimitIntoPrimarySearchRule.java b/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/PushLimitIntoPrimarySearchRule.java
index 22dad3a..d95a952 100644
--- a/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/PushLimitIntoPrimarySearchRule.java
+++ b/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/PushLimitIntoPrimarySearchRule.java
@@ -156,7 +156,7 @@
         return changed;
     }
 
-    private boolean setLimitForScanOrUnnestMap(ILogicalOperator op, int outputLimit) {
+    private boolean setLimitForScanOrUnnestMap(ILogicalOperator op, int outputLimit) throws AlgebricksException {
         if (op.getOperatorTag() == LogicalOperatorTag.DATASOURCESCAN) {
             DataSourceScanOperator scan = (DataSourceScanOperator) op;
             if (isScanPushable(scan, Collections.emptySet())) {
@@ -173,7 +173,8 @@
         return false;
     }
 
-    private boolean isUnnestMapPushable(UnnestMapOperator op, Set<LogicalVariable> selectedVariables) {
+    private boolean isUnnestMapPushable(UnnestMapOperator op, Set<LogicalVariable> selectedVariables)
+            throws AlgebricksException {
         if (op.getOutputLimit() >= 0) {
             // already pushed
             return false;
diff --git a/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/am/AccessMethodJobGenParams.java b/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/am/AccessMethodJobGenParams.java
index a4795ba..c4f1487 100644
--- a/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/am/AccessMethodJobGenParams.java
+++ b/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/am/AccessMethodJobGenParams.java
@@ -26,6 +26,7 @@
 import org.apache.asterix.om.constants.AsterixConstantValue;
 import org.apache.commons.lang3.mutable.Mutable;
 import org.apache.commons.lang3.mutable.MutableObject;
+import org.apache.hyracks.algebricks.common.exceptions.AlgebricksException;
 import org.apache.hyracks.algebricks.core.algebra.base.ILogicalExpression;
 import org.apache.hyracks.algebricks.core.algebra.base.LogicalVariable;
 import org.apache.hyracks.algebricks.core.algebra.expressions.ConstantExpression;
@@ -69,7 +70,7 @@
         funcArgs.add(new MutableObject<>(AccessMethodUtils.createBooleanConstant(requiresBroadcast)));
     }
 
-    public void readFromFuncArgs(List<Mutable<ILogicalExpression>> funcArgs) {
+    public void readFromFuncArgs(List<Mutable<ILogicalExpression>> funcArgs) throws AlgebricksException {
         indexName = AccessMethodUtils.getStringConstant(funcArgs.get(0));
         indexType = IndexType.values()[AccessMethodUtils.getInt32Constant(funcArgs.get(1))];
         dataverseName = DataverseName.createFromCanonicalForm(AccessMethodUtils.getStringConstant(funcArgs.get(2)));
diff --git a/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/am/BTreeJobGenParams.java b/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/am/BTreeJobGenParams.java
index 2eefc8c..7bcaaac 100644
--- a/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/am/BTreeJobGenParams.java
+++ b/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/am/BTreeJobGenParams.java
@@ -25,6 +25,7 @@
 import org.apache.asterix.common.metadata.DataverseName;
 import org.apache.commons.lang3.mutable.Mutable;
 import org.apache.commons.lang3.mutable.MutableObject;
+import org.apache.hyracks.algebricks.common.exceptions.AlgebricksException;
 import org.apache.hyracks.algebricks.core.algebra.base.ILogicalExpression;
 import org.apache.hyracks.algebricks.core.algebra.base.LogicalVariable;
 import org.apache.hyracks.algebricks.core.algebra.expressions.ConstantExpression;
@@ -88,7 +89,7 @@
         writeBoolean(isEqCondition, funcArgs);
     }
 
-    public void readFromFuncArgs(List<Mutable<ILogicalExpression>> funcArgs) {
+    public void readFromFuncArgs(List<Mutable<ILogicalExpression>> funcArgs) throws AlgebricksException {
         super.readFromFuncArgs(funcArgs);
         int index = super.getNumParams();
         lowKeyVarList = new ArrayList<LogicalVariable>();
diff --git a/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/am/InvertedIndexJobGenParams.java b/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/am/InvertedIndexJobGenParams.java
index 26350d8..550b130 100644
--- a/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/am/InvertedIndexJobGenParams.java
+++ b/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/am/InvertedIndexJobGenParams.java
@@ -27,6 +27,7 @@
 import org.apache.asterix.optimizer.rules.am.InvertedIndexAccessMethod.SearchModifierType;
 import org.apache.commons.lang3.mutable.Mutable;
 import org.apache.commons.lang3.mutable.MutableObject;
+import org.apache.hyracks.algebricks.common.exceptions.AlgebricksException;
 import org.apache.hyracks.algebricks.core.algebra.base.ILogicalExpression;
 import org.apache.hyracks.algebricks.core.algebra.base.LogicalVariable;
 import org.apache.hyracks.algebricks.core.algebra.expressions.ConstantExpression;
@@ -105,7 +106,7 @@
     }
 
     @Override
-    public void readFromFuncArgs(List<Mutable<ILogicalExpression>> funcArgs) {
+    public void readFromFuncArgs(List<Mutable<ILogicalExpression>> funcArgs) throws AlgebricksException {
         super.readFromFuncArgs(funcArgs);
         int index = super.getNumParams();
         // Read search modifier type.
diff --git a/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/am/OptimizableOperatorSubTree.java b/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/am/OptimizableOperatorSubTree.java
index b765bd0..d45e7f2 100644
--- a/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/am/OptimizableOperatorSubTree.java
+++ b/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/am/OptimizableOperatorSubTree.java
@@ -145,7 +145,7 @@
         return initializeDataSource(searchOpRef);
     }
 
-    private boolean initializeDataSource(Mutable<ILogicalOperator> subTreeOpRef) {
+    private boolean initializeDataSource(Mutable<ILogicalOperator> subTreeOpRef) throws AlgebricksException {
         AbstractLogicalOperator subTreeOp = (AbstractLogicalOperator) subTreeOpRef.getValue();
 
         if (subTreeOp.getOperatorTag() == LogicalOperatorTag.DATASOURCESCAN) {
diff --git a/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/am/RTreeJobGenParams.java b/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/am/RTreeJobGenParams.java
index d58766e..1e5983a 100644
--- a/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/am/RTreeJobGenParams.java
+++ b/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/am/RTreeJobGenParams.java
@@ -24,6 +24,7 @@
 import org.apache.asterix.common.config.DatasetConfig.IndexType;
 import org.apache.asterix.common.metadata.DataverseName;
 import org.apache.commons.lang3.mutable.Mutable;
+import org.apache.hyracks.algebricks.common.exceptions.AlgebricksException;
 import org.apache.hyracks.algebricks.core.algebra.base.ILogicalExpression;
 import org.apache.hyracks.algebricks.core.algebra.base.LogicalVariable;
 
@@ -48,7 +49,7 @@
         writeVarList(keyVarList, funcArgs);
     }
 
-    public void readFromFuncArgs(List<Mutable<ILogicalExpression>> funcArgs) {
+    public void readFromFuncArgs(List<Mutable<ILogicalExpression>> funcArgs) throws AlgebricksException {
         super.readFromFuncArgs(funcArgs);
         int index = super.getNumParams();
         keyVarList = new ArrayList<LogicalVariable>();
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 eb424af..cf287d9 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
@@ -151,7 +151,8 @@
         return field == null || !field.getHttpDataType().equals(InterfaceHttpData.HttpDataType.Attribute);
     }
 
-    protected Pair<DataverseName, String> decodeDvAndLibFromLocalPath(String localPath) throws RuntimeDataException {
+    protected Pair<DataverseName, String> decodeDvAndLibFromLocalPath(String localPath)
+            throws RuntimeDataException, AlgebricksException {
         String[] pathSegments = StringUtils.split(localPath, '/');
         if (pathSegments.length != 2) {
             throw RuntimeDataException.create(ErrorCode.PARAMETERS_REQUIRED,
@@ -205,7 +206,7 @@
         }
         if (IFormattedException.matchesAny(e, ErrorCode.LIBRARY_EXTERNAL_FUNCTION_UNKNOWN_KIND,
                 ErrorCode.LIBRARY_EXTERNAL_FUNCTION_UNSUPPORTED_KIND, ErrorCode.INVALID_REQ_PARAM_VAL,
-                ErrorCode.PARAMETERS_REQUIRED)) {
+                ErrorCode.PARAMETERS_REQUIRED, ErrorCode.INVALID_DATABASE_OBJECT_NAME)) {
             return HttpResponseStatus.BAD_REQUEST;
         }
         if (e instanceof AlgebricksException) {
diff --git a/asterixdb/asterix-app/src/main/java/org/apache/asterix/api/http/server/RebalanceApiServlet.java b/asterixdb/asterix-app/src/main/java/org/apache/asterix/api/http/server/RebalanceApiServlet.java
index c4d664b..f1652ea 100644
--- a/asterixdb/asterix-app/src/main/java/org/apache/asterix/api/http/server/RebalanceApiServlet.java
+++ b/asterixdb/asterix-app/src/main/java/org/apache/asterix/api/http/server/RebalanceApiServlet.java
@@ -48,6 +48,7 @@
 import org.apache.asterix.metadata.utils.MetadataConstants;
 import org.apache.asterix.rebalance.NoOpDatasetRebalanceCallback;
 import org.apache.asterix.utils.RebalanceUtil;
+import org.apache.hyracks.algebricks.common.exceptions.AlgebricksException;
 import org.apache.hyracks.api.client.IHyracksClientConnection;
 import org.apache.hyracks.http.api.IServletRequest;
 import org.apache.hyracks.http.api.IServletResponse;
@@ -105,7 +106,13 @@
     protected void post(IServletRequest request, IServletResponse response) {
         try {
             // Gets dataverse, dataset, and target nodes for rebalance.
-            DataverseName dataverseName = ServletUtil.getDataverseName(request, "dataverseName");
+            DataverseName dataverseName;
+            try {
+                dataverseName = ServletUtil.getDataverseName(request, "dataverseName");
+            } catch (AlgebricksException e) {
+                sendResponse(response, HttpResponseStatus.BAD_REQUEST, e.getMessage());
+                return;
+            }
             String datasetName = request.getParameter("datasetName");
             Set<String> targetNodes = new LinkedHashSet<>(request.getParameterValues("targetNode"));
             boolean forceRebalance = true;
diff --git a/asterixdb/asterix-app/src/main/java/org/apache/asterix/api/http/server/ServletUtil.java b/asterixdb/asterix-app/src/main/java/org/apache/asterix/api/http/server/ServletUtil.java
index 51fa326..3ac37bf 100644
--- a/asterixdb/asterix-app/src/main/java/org/apache/asterix/api/http/server/ServletUtil.java
+++ b/asterixdb/asterix-app/src/main/java/org/apache/asterix/api/http/server/ServletUtil.java
@@ -29,6 +29,7 @@
 import org.apache.asterix.common.metadata.DataverseName;
 import org.apache.commons.codec.DecoderException;
 import org.apache.commons.codec.net.URLCodec;
+import org.apache.hyracks.algebricks.common.exceptions.AlgebricksException;
 import org.apache.hyracks.api.client.IHyracksClientConnection;
 import org.apache.hyracks.api.result.IResultSet;
 import org.apache.hyracks.client.result.ResultSet;
@@ -53,7 +54,8 @@
         return resultSet;
     }
 
-    public static DataverseName getDataverseName(IServletRequest request, String dataverseParameterName) {
+    public static DataverseName getDataverseName(IServletRequest request, String dataverseParameterName)
+            throws AlgebricksException {
         List<String> values = request.getParameterValues(dataverseParameterName);
         return !values.isEmpty() ? DataverseName.create(values) : null;
     }
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 777f4d5..7154814 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
@@ -484,7 +484,7 @@
                         outputFile = result.second;
                         break;
                     case FUNCTION_DECL:
-                        handleDeclareFunctionStatement(stmt);
+                        handleDeclareFunctionStatement(metadataProvider, stmt);
                         break;
                     case EXTENSION:
                         final ExtensionStatement extStmt = (ExtensionStatement) stmt;
@@ -1784,6 +1784,7 @@
         DataverseDropStatement stmtDropDataverse = (DataverseDropStatement) stmt;
         SourceLocation sourceLoc = stmtDropDataverse.getSourceLocation();
         DataverseName dataverseName = stmtDropDataverse.getDataverseName();
+        metadataProvider.validateDataverseName(dataverseName, sourceLoc);
         if (dataverseName.equals(MetadataBuiltinEntities.DEFAULT_DATAVERSE_NAME)
                 || dataverseName.equals(MetadataConstants.METADATA_DATAVERSE_NAME)) {
             throw new CompilationException(ErrorCode.COMPILATION_ERROR, sourceLoc,
@@ -1974,8 +1975,9 @@
             IHyracksClientConnection hcc, IRequestParameters requestParameters) throws Exception {
         DropDatasetStatement stmtDelete = (DropDatasetStatement) stmt;
         SourceLocation sourceLoc = stmtDelete.getSourceLocation();
-        DataverseName dataverseName = getActiveDataverseName(stmtDelete.getDataverseName());
         String datasetName = stmtDelete.getDatasetName().getValue();
+        metadataProvider.validateDatabaseObjectName(stmtDelete.getDataverseName(), datasetName, sourceLoc);
+        DataverseName dataverseName = getActiveDataverseName(stmtDelete.getDataverseName());
         lockUtil.dropDatasetBegin(lockManager, metadataProvider.getLocks(), dataverseName, datasetName);
         try {
             doDropDataset(dataverseName, datasetName, metadataProvider, stmtDelete.getIfExists(), hcc,
@@ -2072,6 +2074,8 @@
     protected void handleIndexDropStatement(MetadataProvider metadataProvider, Statement stmt,
             IHyracksClientConnection hcc, IRequestParameters requestParameters) throws Exception {
         IndexDropStatement stmtIndexDrop = (IndexDropStatement) stmt;
+        metadataProvider.validateDatabaseObjectName(stmtIndexDrop.getDataverseName(),
+                stmtIndexDrop.getIndexName().getValue(), stmtIndexDrop.getSourceLocation());
         DataverseName dataverseName = getActiveDataverseName(stmtIndexDrop.getDataverseName());
         String datasetName = stmtIndexDrop.getDatasetName().getValue();
         lockUtil.dropIndexBegin(lockManager, metadataProvider.getLocks(), dataverseName, datasetName);
@@ -2342,9 +2346,9 @@
     protected void handleTypeDropStatement(MetadataProvider metadataProvider, Statement stmt) throws Exception {
         TypeDropStatement stmtTypeDrop = (TypeDropStatement) stmt;
         SourceLocation sourceLoc = stmtTypeDrop.getSourceLocation();
-        DataverseName dataverseName = getActiveDataverseName(stmtTypeDrop.getDataverseName());
         String typeName = stmtTypeDrop.getTypeName().getValue();
-
+        metadataProvider.validateDatabaseObjectName(stmtTypeDrop.getDataverseName(), typeName, sourceLoc);
+        DataverseName dataverseName = getActiveDataverseName(stmtTypeDrop.getDataverseName());
         MetadataTransactionContext mdTxnCtx = MetadataManager.INSTANCE.beginTransaction();
         metadataProvider.setMetadataTxnContext(mdTxnCtx);
         lockUtil.dropTypeBegin(lockManager, metadataProvider.getLocks(), dataverseName, typeName);
@@ -2384,6 +2388,7 @@
         NodeGroupDropStatement stmtDelete = (NodeGroupDropStatement) stmt;
         SourceLocation sourceLoc = stmtDelete.getSourceLocation();
         String nodegroupName = stmtDelete.getNodeGroupName().getValue();
+        metadataProvider.validateDatabaseObjectName(null, nodegroupName, sourceLoc);
         MetadataTransactionContext mdTxnCtx = MetadataManager.INSTANCE.beginTransaction();
         metadataProvider.setMetadataTxnContext(mdTxnCtx);
         lockManager.acquireNodeGroupWriteLock(metadataProvider.getLocks(), nodegroupName);
@@ -2406,9 +2411,11 @@
         }
     }
 
-    protected void handleDeclareFunctionStatement(Statement stmt) {
+    protected void handleDeclareFunctionStatement(MetadataProvider metadataProvider, Statement stmt) throws Exception {
         FunctionDecl fds = (FunctionDecl) stmt;
         FunctionSignature signature = fds.getSignature();
+        metadataProvider.validateDatabaseObjectName(signature.getDataverseName(), signature.getName(),
+                stmt.getSourceLocation());
         signature.setDataverseName(getActiveDataverseName(signature.getDataverseName()));
         declaredFunctions.add(fds);
     }
@@ -2680,6 +2687,8 @@
     protected void handleFunctionDropStatement(MetadataProvider metadataProvider, Statement stmt) throws Exception {
         FunctionDropStatement stmtDropFunction = (FunctionDropStatement) stmt;
         FunctionSignature signature = stmtDropFunction.getFunctionSignature();
+        metadataProvider.validateDatabaseObjectName(signature.getDataverseName(), signature.getName(),
+                stmtDropFunction.getSourceLocation());
         DataverseName dataverseName = getActiveDataverseName(signature.getDataverseName());
         signature.setDataverseName(dataverseName);
         lockUtil.dropFunctionBegin(lockManager, metadataProvider.getLocks(), dataverseName, signature.getName());
@@ -2732,13 +2741,15 @@
 
     protected void handleCreateAdapterStatement(MetadataProvider metadataProvider, Statement stmt) throws Exception {
         CreateAdapterStatement cas = (CreateAdapterStatement) stmt;
+        String adapterName = cas.getAdapterName();
+        metadataProvider.validateDatabaseObjectName(cas.getDataverseName(), adapterName, cas.getSourceLocation());
         DataverseName dataverseName = getActiveDataverseName(cas.getDataverseName());
         DataverseName libraryDataverseName = cas.getLibraryDataverseName();
         if (libraryDataverseName == null) {
             libraryDataverseName = dataverseName;
         }
         String libraryName = cas.getLibraryName();
-        lockUtil.createAdapterBegin(lockManager, metadataProvider.getLocks(), dataverseName, cas.getAdapterName(),
+        lockUtil.createAdapterBegin(lockManager, metadataProvider.getLocks(), dataverseName, adapterName,
                 libraryDataverseName, libraryName);
         try {
             doCreateAdapter(metadataProvider, cas);
@@ -2804,8 +2815,10 @@
 
     protected void handleAdapterDropStatement(MetadataProvider metadataProvider, Statement stmt) throws Exception {
         AdapterDropStatement stmtDropAdapter = (AdapterDropStatement) stmt;
-        DataverseName dataverseName = getActiveDataverseName(stmtDropAdapter.getDataverseName());
+        SourceLocation sourceLoc = stmtDropAdapter.getSourceLocation();
         String adapterName = stmtDropAdapter.getAdapterName();
+        metadataProvider.validateDatabaseObjectName(stmtDropAdapter.getDataverseName(), adapterName, sourceLoc);
+        DataverseName dataverseName = getActiveDataverseName(stmtDropAdapter.getDataverseName());
         lockUtil.dropAdapterBegin(lockManager, metadataProvider.getLocks(), dataverseName, adapterName);
         try {
             doDropAdapter(metadataProvider, stmtDropAdapter, dataverseName, adapterName);
@@ -2851,6 +2864,8 @@
     protected void handleCreateLibraryStatement(MetadataProvider metadataProvider, Statement stmt,
             IHyracksClientConnection hcc, IRequestParameters requestParameters) throws Exception {
         CreateLibraryStatement cls = (CreateLibraryStatement) stmt;
+        metadataProvider.validateDatabaseObjectName(cls.getDataverseName(), cls.getLibraryName(),
+                cls.getSourceLocation());
         DataverseName dataverseName = getActiveDataverseName(cls.getDataverseName());
         String libraryName = cls.getLibraryName();
         String libraryHash = cls.getHash();
@@ -2977,8 +2992,10 @@
     protected void handleLibraryDropStatement(MetadataProvider metadataProvider, Statement stmt,
             IHyracksClientConnection hcc) throws Exception {
         LibraryDropStatement stmtDropLibrary = (LibraryDropStatement) stmt;
-        DataverseName dataverseName = getActiveDataverseName(stmtDropLibrary.getDataverseName());
         String libraryName = stmtDropLibrary.getLibraryName();
+        metadataProvider.validateDatabaseObjectName(stmtDropLibrary.getDataverseName(), libraryName,
+                stmtDropLibrary.getSourceLocation());
+        DataverseName dataverseName = getActiveDataverseName(stmtDropLibrary.getDataverseName());
         lockUtil.dropLibraryBegin(lockManager, metadataProvider.getLocks(), dataverseName, libraryName);
         try {
             doDropLibrary(metadataProvider, stmtDropLibrary, dataverseName, libraryName, hcc);
@@ -3065,6 +3082,8 @@
 
     protected void handleCreateSynonymStatement(MetadataProvider metadataProvider, Statement stmt) throws Exception {
         CreateSynonymStatement css = (CreateSynonymStatement) stmt;
+        metadataProvider.validateDatabaseObjectName(css.getDataverseName(), css.getSynonymName(),
+                css.getSourceLocation());
         DataverseName dataverseName = getActiveDataverseName(css.getDataverseName());
         String synonymName = css.getSynonymName();
         DataverseName objectDataverseName =
@@ -3112,8 +3131,10 @@
 
     protected void handleDropSynonymStatement(MetadataProvider metadataProvider, Statement stmt) throws Exception {
         SynonymDropStatement stmtSynDrop = (SynonymDropStatement) stmt;
-        DataverseName dataverseName = getActiveDataverseName(stmtSynDrop.getDataverseName());
         String synonymName = stmtSynDrop.getSynonymName();
+        metadataProvider.validateDatabaseObjectName(stmtSynDrop.getDataverseName(), synonymName,
+                stmtSynDrop.getSourceLocation());
+        DataverseName dataverseName = getActiveDataverseName(stmtSynDrop.getDataverseName());
         lockUtil.dropSynonymBegin(lockManager, metadataProvider.getLocks(), dataverseName, synonymName);
         try {
             doDropSynonym(metadataProvider, stmtSynDrop, dataverseName, synonymName);
@@ -3147,8 +3168,10 @@
     protected void handleLoadStatement(MetadataProvider metadataProvider, Statement stmt, IHyracksClientConnection hcc)
             throws Exception {
         LoadStatement loadStmt = (LoadStatement) stmt;
-        DataverseName dataverseName = getActiveDataverseName(loadStmt.getDataverseName());
         String datasetName = loadStmt.getDatasetName();
+        metadataProvider.validateDatabaseObjectName(loadStmt.getDataverseName(), datasetName,
+                loadStmt.getSourceLocation());
+        DataverseName dataverseName = getActiveDataverseName(loadStmt.getDataverseName());
         MetadataTransactionContext mdTxnCtx = MetadataManager.INSTANCE.beginTransaction();
         boolean bActiveTxn = true;
         metadataProvider.setMetadataTxnContext(mdTxnCtx);
@@ -3183,12 +3206,14 @@
             ResultMetadata outMetadata, Stats stats, boolean compileOnly, IRequestParameters requestParameters,
             Map<String, IAObject> stmtParams, IStatementRewriter stmtRewriter) throws Exception {
         InsertStatement stmtInsertUpsert = (InsertStatement) stmt;
+        String datasetName = stmtInsertUpsert.getDatasetName();
+        metadataProvider.validateDatabaseObjectName(stmtInsertUpsert.getDataverseName(), datasetName,
+                stmtInsertUpsert.getSourceLocation());
         DataverseName dataverseName = getActiveDataverseName(stmtInsertUpsert.getDataverseName());
         final IMetadataLocker locker = new IMetadataLocker() {
             @Override
             public void lock() throws AlgebricksException {
-                lockUtil.insertDeleteUpsertBegin(lockManager, metadataProvider.getLocks(), dataverseName,
-                        stmtInsertUpsert.getDatasetName());
+                lockUtil.insertDeleteUpsertBegin(lockManager, metadataProvider.getLocks(), dataverseName, datasetName);
             }
 
             @Override
@@ -3245,17 +3270,18 @@
             IHyracksClientConnection hcc, boolean compileOnly, Map<String, IAObject> stmtParams,
             IStatementRewriter stmtRewriter) throws Exception {
         DeleteStatement stmtDelete = (DeleteStatement) stmt;
+        String datasetName = stmtDelete.getDatasetName();
+        metadataProvider.validateDatabaseObjectName(stmtDelete.getDataverseName(), datasetName,
+                stmt.getSourceLocation());
         DataverseName dataverseName = getActiveDataverseName(stmtDelete.getDataverseName());
         MetadataTransactionContext mdTxnCtx = MetadataManager.INSTANCE.beginTransaction();
         boolean bActiveTxn = true;
         metadataProvider.setMetadataTxnContext(mdTxnCtx);
-        lockUtil.insertDeleteUpsertBegin(lockManager, metadataProvider.getLocks(), dataverseName,
-                stmtDelete.getDatasetName());
+        lockUtil.insertDeleteUpsertBegin(lockManager, metadataProvider.getLocks(), dataverseName, datasetName);
         try {
             metadataProvider.setWriteTransaction(true);
             CompiledDeleteStatement clfrqs = new CompiledDeleteStatement(stmtDelete.getVariableExpr(), dataverseName,
-                    stmtDelete.getDatasetName(), stmtDelete.getCondition(), stmtDelete.getVarCounter(),
-                    stmtDelete.getQuery());
+                    datasetName, stmtDelete.getCondition(), stmtDelete.getVarCounter(), stmtDelete.getQuery());
             clfrqs.setSourceLocation(stmt.getSourceLocation());
             JobSpecification jobSpec =
                     rewriteCompileQuery(hcc, metadataProvider, clfrqs.getQuery(), clfrqs, stmtParams, stmtRewriter);
@@ -3438,8 +3464,9 @@
             IHyracksClientConnection hcc) throws Exception {
         FeedDropStatement stmtFeedDrop = (FeedDropStatement) stmt;
         SourceLocation sourceLoc = stmtFeedDrop.getSourceLocation();
-        DataverseName dataverseName = getActiveDataverseName(stmtFeedDrop.getDataverseName());
         String feedName = stmtFeedDrop.getFeedName().getValue();
+        metadataProvider.validateDatabaseObjectName(stmtFeedDrop.getDataverseName(), feedName, sourceLoc);
+        DataverseName dataverseName = getActiveDataverseName(stmtFeedDrop.getDataverseName());
         MetadataTransactionContext mdTxnCtx = MetadataManager.INSTANCE.beginTransaction();
         metadataProvider.setMetadataTxnContext(mdTxnCtx);
         lockUtil.dropFeedBegin(lockManager, metadataProvider.getLocks(), dataverseName, feedName);
@@ -3488,12 +3515,13 @@
     }
 
     protected void handleDropFeedPolicyStatement(MetadataProvider metadataProvider, Statement stmt) throws Exception {
-        MetadataTransactionContext mdTxnCtx = MetadataManager.INSTANCE.beginTransaction();
-        metadataProvider.setMetadataTxnContext(mdTxnCtx);
         FeedPolicyDropStatement stmtFeedPolicyDrop = (FeedPolicyDropStatement) stmt;
         SourceLocation sourceLoc = stmtFeedPolicyDrop.getSourceLocation();
-        DataverseName dataverseName = getActiveDataverseName(stmtFeedPolicyDrop.getDataverseName());
         String policyName = stmtFeedPolicyDrop.getPolicyName().getValue();
+        metadataProvider.validateDatabaseObjectName(stmtFeedPolicyDrop.getDataverseName(), policyName, sourceLoc);
+        DataverseName dataverseName = getActiveDataverseName(stmtFeedPolicyDrop.getDataverseName());
+        MetadataTransactionContext mdTxnCtx = MetadataManager.INSTANCE.beginTransaction();
+        metadataProvider.setMetadataTxnContext(mdTxnCtx);
         lockUtil.dropFeedPolicyBegin(lockManager, metadataProvider.getLocks(), dataverseName, policyName);
         try {
             FeedPolicyEntity feedPolicy = MetadataManager.INSTANCE.getFeedPolicy(mdTxnCtx, dataverseName, policyName);
diff --git a/asterixdb/asterix-app/src/test/java/org/apache/asterix/test/dataflow/CheckpointInSecondaryIndexTest.java b/asterixdb/asterix-app/src/test/java/org/apache/asterix/test/dataflow/CheckpointInSecondaryIndexTest.java
index d60702f..1913233 100644
--- a/asterixdb/asterix-app/src/test/java/org/apache/asterix/test/dataflow/CheckpointInSecondaryIndexTest.java
+++ b/asterixdb/asterix-app/src/test/java/org/apache/asterix/test/dataflow/CheckpointInSecondaryIndexTest.java
@@ -108,7 +108,7 @@
     private static final List<Integer> KEY_INDICATORS_LIST = Collections.singletonList(Index.RECORD_INDICATOR);
     private static final int RECORDS_PER_COMPONENT = 500;
     private static final int DATASET_ID = 101;
-    private static final DataverseName DATAVERSE_NAME = DataverseName.createSinglePartName("TestDV");
+    private static final String DATAVERSE_NAME = "TestDV";
     private static final String DATASET_NAME = "TestDS";
     private static final String INDEX_NAME = "TestIdx";
     private static final String DATA_TYPE_NAME = "DUMMY";
@@ -163,13 +163,14 @@
 
     @Before
     public void createIndex() throws Exception {
+        DataverseName dvName = DataverseName.createSinglePartName(DATAVERSE_NAME);
         List<List<String>> partitioningKeys = new ArrayList<>();
         partitioningKeys.add(Collections.singletonList("key"));
-        dataset = new TestDataset(DATAVERSE_NAME, DATASET_NAME, DATAVERSE_NAME, DATA_TYPE_NAME, NODE_GROUP_NAME,
+        dataset = new TestDataset(dvName, DATASET_NAME, dvName, DATA_TYPE_NAME, NODE_GROUP_NAME,
                 NoMergePolicyFactory.NAME, null, new InternalDatasetDetails(null, PartitioningStrategy.HASH,
                         partitioningKeys, null, null, null, false, null, null),
                 null, DatasetType.INTERNAL, DATASET_ID, 0);
-        secondaryIndex = new Index(DATAVERSE_NAME, DATASET_NAME, INDEX_NAME, INDEX_TYPE, INDEX_FIELD_NAMES,
+        secondaryIndex = new Index(dvName, DATASET_NAME, INDEX_NAME, INDEX_TYPE, INDEX_FIELD_NAMES,
                 INDEX_FIELD_INDICATORS, INDEX_FIELD_TYPES, false, false, false, 0);
         taskCtx = null;
         primaryIndexDataflowHelper = null;
diff --git a/asterixdb/asterix-app/src/test/java/org/apache/asterix/test/dataflow/GlobalVirtualBufferCacheTest.java b/asterixdb/asterix-app/src/test/java/org/apache/asterix/test/dataflow/GlobalVirtualBufferCacheTest.java
index abfe2ec..b056bbe 100644
--- a/asterixdb/asterix-app/src/test/java/org/apache/asterix/test/dataflow/GlobalVirtualBufferCacheTest.java
+++ b/asterixdb/asterix-app/src/test/java/org/apache/asterix/test/dataflow/GlobalVirtualBufferCacheTest.java
@@ -32,6 +32,7 @@
 import org.apache.asterix.common.api.IDatasetLifecycleManager;
 import org.apache.asterix.common.config.DatasetConfig.DatasetType;
 import org.apache.asterix.common.config.StorageProperties.Option;
+import org.apache.asterix.common.metadata.DataverseName;
 import org.apache.asterix.common.transactions.ITransactionContext;
 import org.apache.asterix.common.transactions.ITransactionManager;
 import org.apache.asterix.common.transactions.TransactionOptions;
@@ -190,15 +191,15 @@
     }
 
     private void createIndex() throws Exception {
-        dataset = new TestDataset(StorageTestUtils.DATAVERSE_NAME, "ds", StorageTestUtils.DATAVERSE_NAME,
-                StorageTestUtils.DATA_TYPE_NAME, StorageTestUtils.NODE_GROUP_NAME, NoMergePolicyFactory.NAME,
+        DataverseName dvName = DataverseName.createSinglePartName(StorageTestUtils.DATAVERSE_NAME);
+        dataset = new TestDataset(dvName, "ds", dvName, StorageTestUtils.DATA_TYPE_NAME,
+                StorageTestUtils.NODE_GROUP_NAME, NoMergePolicyFactory.NAME,
                 null, new InternalDatasetDetails(null, PartitioningStrategy.HASH, StorageTestUtils.PARTITIONING_KEYS,
                         null, null, null, false, null, null),
                 null, DatasetType.INTERNAL, StorageTestUtils.DATASET_ID, 0);
 
-        filteredDataset = new TestDataset(StorageTestUtils.DATAVERSE_NAME, "filtered_ds",
-                StorageTestUtils.DATAVERSE_NAME, StorageTestUtils.DATA_TYPE_NAME, StorageTestUtils.NODE_GROUP_NAME,
-                NoMergePolicyFactory.NAME, null,
+        filteredDataset = new TestDataset(dvName, "filtered_ds", dvName, StorageTestUtils.DATA_TYPE_NAME,
+                StorageTestUtils.NODE_GROUP_NAME, NoMergePolicyFactory.NAME, null,
                 new InternalDatasetDetails(null, PartitioningStrategy.HASH, StorageTestUtils.PARTITIONING_KEYS, null,
                         null, null, false, 0, Collections.singletonList("value")),
                 null, DatasetType.INTERNAL, StorageTestUtils.DATASET_ID + 1, 0);
diff --git a/asterixdb/asterix-app/src/test/java/org/apache/asterix/test/dataflow/MultiPartitionLSMIndexTest.java b/asterixdb/asterix-app/src/test/java/org/apache/asterix/test/dataflow/MultiPartitionLSMIndexTest.java
index 41b889d..ef3a7cb 100644
--- a/asterixdb/asterix-app/src/test/java/org/apache/asterix/test/dataflow/MultiPartitionLSMIndexTest.java
+++ b/asterixdb/asterix-app/src/test/java/org/apache/asterix/test/dataflow/MultiPartitionLSMIndexTest.java
@@ -103,7 +103,7 @@
     private static final int TOTAL_NUM_OF_RECORDS = 5000;
     private static final int RECORDS_PER_COMPONENT = 500;
     private static final int DATASET_ID = 101;
-    private static final DataverseName DATAVERSE_NAME = DataverseName.createSinglePartName("TestDV");
+    private static final String DATAVERSE_NAME = "TestDV";
     private static final String DATASET_NAME = "TestDS";
     private static final String INDEX_NAME = "TestIdx";
     private static final String DATA_TYPE_NAME = "DUMMY";
@@ -153,13 +153,14 @@
 
     @Before
     public void createIndex() throws Exception {
+        DataverseName dvName = DataverseName.createSinglePartName(DATAVERSE_NAME);
         List<List<String>> partitioningKeys = new ArrayList<>();
         partitioningKeys.add(Collections.singletonList("key"));
-        dataset = new TestDataset(DATAVERSE_NAME, DATASET_NAME, DATAVERSE_NAME, DATA_TYPE_NAME, NODE_GROUP_NAME,
+        dataset = new TestDataset(dvName, DATASET_NAME, dvName, DATA_TYPE_NAME, NODE_GROUP_NAME,
                 NoMergePolicyFactory.NAME, null, new InternalDatasetDetails(null, PartitioningStrategy.HASH,
                         partitioningKeys, null, null, null, false, null, null),
                 null, DatasetType.INTERNAL, DATASET_ID, 0);
-        secondaryIndex = new Index(DATAVERSE_NAME, DATASET_NAME, INDEX_NAME, INDEX_TYPE, INDEX_FIELD_NAMES,
+        secondaryIndex = new Index(dvName, DATASET_NAME, INDEX_NAME, INDEX_TYPE, INDEX_FIELD_NAMES,
                 INDEX_FIELD_INDICATORS, INDEX_FIELD_TYPES, false, false, false, 0);
         taskCtxs = new IHyracksTaskContext[NUM_PARTITIONS];
         primaryIndexDataflowHelpers = new IIndexDataflowHelper[NUM_PARTITIONS];
diff --git a/asterixdb/asterix-app/src/test/java/org/apache/asterix/test/dataflow/SearchCursorComponentSwitchTest.java b/asterixdb/asterix-app/src/test/java/org/apache/asterix/test/dataflow/SearchCursorComponentSwitchTest.java
index a9e86cb..24379a3 100644
--- a/asterixdb/asterix-app/src/test/java/org/apache/asterix/test/dataflow/SearchCursorComponentSwitchTest.java
+++ b/asterixdb/asterix-app/src/test/java/org/apache/asterix/test/dataflow/SearchCursorComponentSwitchTest.java
@@ -88,7 +88,7 @@
     private static final int TOTAL_NUM_OF_RECORDS = 2000;
     private static final int RECORDS_PER_COMPONENT = 1000;
     private static final int DATASET_ID = 101;
-    private static final DataverseName DATAVERSE_NAME = DataverseName.createSinglePartName("TestDV");
+    private static final String DATAVERSE_NAME = "TestDV";
     private static final String DATASET_NAME = "TestDS";
     private static final String DATA_TYPE_NAME = "DUMMY";
     private static final String NODE_GROUP_NAME = "DEFAULT";
@@ -122,9 +122,10 @@
 
     @Before
     public void createIndex() throws Exception {
+        DataverseName dvName = DataverseName.createSinglePartName(DATAVERSE_NAME);
         List<List<String>> partitioningKeys = new ArrayList<>();
         partitioningKeys.add(Collections.singletonList("key"));
-        dataset = new TestDataset(DATAVERSE_NAME, DATASET_NAME, DATAVERSE_NAME, DATA_TYPE_NAME, NODE_GROUP_NAME,
+        dataset = new TestDataset(dvName, DATASET_NAME, dvName, DATA_TYPE_NAME, NODE_GROUP_NAME,
                 NoMergePolicyFactory.NAME, null, new InternalDatasetDetails(null, PartitioningStrategy.HASH,
                         partitioningKeys, null, null, null, false, null, null),
                 null, DatasetType.INTERNAL, DATASET_ID, 0);
diff --git a/asterixdb/asterix-app/src/test/java/org/apache/asterix/test/dataflow/StorageTestUtils.java b/asterixdb/asterix-app/src/test/java/org/apache/asterix/test/dataflow/StorageTestUtils.java
index 3ef1e62..ec778ed 100644
--- a/asterixdb/asterix-app/src/test/java/org/apache/asterix/test/dataflow/StorageTestUtils.java
+++ b/asterixdb/asterix-app/src/test/java/org/apache/asterix/test/dataflow/StorageTestUtils.java
@@ -42,6 +42,7 @@
 import org.apache.asterix.common.context.PrimaryIndexOperationTracker;
 import org.apache.asterix.common.dataflow.LSMInsertDeleteOperatorNodePushable;
 import org.apache.asterix.common.exceptions.ACIDException;
+import org.apache.asterix.common.exceptions.AsterixException;
 import org.apache.asterix.common.metadata.DataverseName;
 import org.apache.asterix.file.StorageComponentProvider;
 import org.apache.asterix.metadata.entities.Dataset;
@@ -85,18 +86,26 @@
     public static final int TOTAL_NUM_OF_RECORDS = 10000;
     public static final int RECORDS_PER_COMPONENT = 1000;
     public static final int DATASET_ID = 101;
-    public static final DataverseName DATAVERSE_NAME = DataverseName.createSinglePartName("TestDV");
+    public static final String DATAVERSE_NAME = "TestDV";
     public static final String DATASET_NAME = "TestDS";
     public static final String DATA_TYPE_NAME = "DUMMY";
     public static final String NODE_GROUP_NAME = "DEFAULT";
     public static final StorageComponentProvider STORAGE_MANAGER = new StorageComponentProvider();
     public static final List<List<String>> PARTITIONING_KEYS =
             new ArrayList<>(Collections.singletonList(Collections.singletonList(RECORD_TYPE.getFieldNames()[0])));
-    public static final TestDataset DATASET =
-            new TestDataset(DATAVERSE_NAME, DATASET_NAME, DATAVERSE_NAME, DATA_TYPE_NAME, NODE_GROUP_NAME,
+    public static final TestDataset DATASET;
+
+    static {
+        try {
+            DataverseName dvName = DataverseName.createSinglePartName(DATAVERSE_NAME);
+            DATASET = new TestDataset(dvName, DATASET_NAME, dvName, DATA_TYPE_NAME, NODE_GROUP_NAME,
                     NoMergePolicyFactory.NAME, null, new InternalDatasetDetails(null, PartitioningStrategy.HASH,
                             PARTITIONING_KEYS, null, null, null, false, null, null),
                     null, DatasetType.INTERNAL, DATASET_ID, 0);
+        } catch (AsterixException e) {
+            throw new IllegalArgumentException(e);
+        }
+    }
 
     private StorageTestUtils() {
     }
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 eed9ae1..b0e2046 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
@@ -175,22 +175,21 @@
     public void testInvalidCharacters() throws Exception {
         TestCaseContext.OutputFormat cleanJson = TestCaseContext.OutputFormat.CLEAN_JSON;
 
-        List<DataverseName> dvNameBadCharsList = Arrays.asList(
+        List<List<String>> dvNameBadCharsList = Arrays.asList(
                 // #1. nul characters
-                DataverseName.createSinglePartName("abc\u0000def"),
+                Collections.singletonList("abc\u0000def"),
                 // #2. leading whitespace
-                DataverseName.createSinglePartName(" abcdef"),
+                Collections.singletonList(" abcdef"),
                 // #3. file separator
-                DataverseName.createSinglePartName("abc" + File.separatorChar + "def"),
+                Collections.singletonList("abc" + File.separatorChar + "def"),
                 // #4. single-part starting with ^
-                DataverseName.createSinglePartName(StoragePathUtil.DATAVERSE_CONTINUATION_MARKER + "abcdef"),
+                Collections.singletonList(StoragePathUtil.DATAVERSE_CONTINUATION_MARKER + "abcdef"),
                 // #5. multi-part w/ first part starting with ^
-                DataverseName
-                        .create(Arrays.asList(StoragePathUtil.DATAVERSE_CONTINUATION_MARKER + "abcdef", "abcdef")));
+                Arrays.asList(StoragePathUtil.DATAVERSE_CONTINUATION_MARKER + "abcdef", "abcdef"));
 
         ErrorCode invalidNameErrCode = ErrorCode.INVALID_DATABASE_OBJECT_NAME;
-        for (DataverseName dvNameOk : dvNameBadCharsList) {
-            String sql = String.format("create dataverse %s;", dvNameOk);
+        for (List<String> dvName : dvNameBadCharsList) {
+            String sql = String.format("create dataverse `%s`;", StringUtils.join(dvName, "`.`"));
             try {
                 testExecutor.executeSqlppUpdateOrDdl(sql, cleanJson);
                 Assert.fail("Expected failure: " + invalidNameErrCode);
diff --git a/asterixdb/asterix-app/src/test/java/org/apache/asterix/test/metadata/MetadataManagerWindowsOsTest.java b/asterixdb/asterix-app/src/test/java/org/apache/asterix/test/metadata/MetadataManagerWindowsOsTest.java
index b9f25e1..20ea90a 100644
--- a/asterixdb/asterix-app/src/test/java/org/apache/asterix/test/metadata/MetadataManagerWindowsOsTest.java
+++ b/asterixdb/asterix-app/src/test/java/org/apache/asterix/test/metadata/MetadataManagerWindowsOsTest.java
@@ -24,7 +24,6 @@
 import org.apache.asterix.api.common.AsterixHyracksIntegrationUtil;
 import org.apache.asterix.common.config.GlobalConfig;
 import org.apache.asterix.common.exceptions.ErrorCode;
-import org.apache.asterix.common.metadata.DataverseName;
 import org.apache.asterix.test.common.TestExecutor;
 import org.apache.asterix.testframework.context.TestCaseContext;
 import org.apache.commons.lang3.SystemUtils;
@@ -60,21 +59,21 @@
     public void testInvalidCharacters() throws Exception {
         TestCaseContext.OutputFormat cleanJson = TestCaseContext.OutputFormat.CLEAN_JSON;
 
-        List<DataverseName> dvNameBadCharsList = new ArrayList<>();
+        List<String> dvNameBadCharsList = new ArrayList<>();
 
         for (char c = 0; c <= 0x1F; c++) {
             dvNameBadCharsList.add(badCharName(c));
         }
         dvNameBadCharsList.add(badCharName('\u007f'));
-        dvNameBadCharsList.add(badCharName('\\'));
+        dvNameBadCharsList.add(badCharName("\\\\"));
         dvNameBadCharsList.add(badCharName('/'));
         dvNameBadCharsList.add(badCharName('>'));
         dvNameBadCharsList.add(badCharName('\n'));
         dvNameBadCharsList.add(badCharName('|'));
 
         ErrorCode invalidNameErrCode = ErrorCode.INVALID_DATABASE_OBJECT_NAME;
-        for (DataverseName dvNameOk : dvNameBadCharsList) {
-            String sql = String.format("create dataverse %s;", dvNameOk);
+        for (String dvName : dvNameBadCharsList) {
+            String sql = String.format("create dataverse `%s`;", dvName);
             try {
                 testExecutor.executeSqlppUpdateOrDdl(sql, cleanJson);
                 Assert.fail("Expected failure: " + invalidNameErrCode);
@@ -86,7 +85,12 @@
     }
 
     @NotNull
-    protected DataverseName badCharName(char c) {
-        return DataverseName.createSinglePartName("abc" + c + "def");
+    protected String badCharName(char c) {
+        return badCharName(String.valueOf(c));
+    }
+
+    @NotNull
+    protected String badCharName(String s) {
+        return "abc" + s + "def";
     }
 }
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 5bacd41..3624a33 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
@@ -71,7 +71,7 @@
     private static final int[] KEY_INDEXES = { 0 };
     private static final List<Integer> KEY_INDICATORS_LIST = Arrays.asList(new Integer[] { Index.RECORD_INDICATOR });
     private static final int DATASET_ID = 101;
-    private static final DataverseName DATAVERSE_NAME = DataverseName.createSinglePartName("TestDV");
+    private static final String DATAVERSE_NAME = "TestDV";
     private static final String DATASET_NAME = "TestDS";
     private static final String DATA_TYPE_NAME = "DUMMY";
     private static final String NODE_GROUP_NAME = "DEFAULT";
@@ -102,9 +102,10 @@
         try {
             nc.init();
             StorageComponentProvider storageManager = new StorageComponentProvider();
+            DataverseName dvName = DataverseName.createSinglePartName(DATAVERSE_NAME);
             List<List<String>> partitioningKeys = new ArrayList<>();
             partitioningKeys.add(Collections.singletonList("key"));
-            Dataset dataset = new Dataset(DATAVERSE_NAME, DATASET_NAME, DATAVERSE_NAME, DATA_TYPE_NAME, NODE_GROUP_NAME,
+            Dataset dataset = new Dataset(dvName, DATASET_NAME, dvName, DATA_TYPE_NAME, NODE_GROUP_NAME,
                     NoMergePolicyFactory.NAME, null,
                     new InternalDatasetDetails(null, InternalDatasetDetails.PartitioningStrategy.HASH, partitioningKeys,
                             null, null, null, false, null, null),
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/ddl/invalid-dataset-name/invalid-dataset-name.3.ddl.sqlpp b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/ddl/invalid-dataset-name/invalid-dataset-name.3.ddl.sqlpp
index fcd7cb1..2ec7e87 100644
--- a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/ddl/invalid-dataset-name/invalid-dataset-name.3.ddl.sqlpp
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/ddl/invalid-dataset-name/invalid-dataset-name.3.ddl.sqlpp
@@ -21,4 +21,9 @@
  * Invalid dataverse name in CREATE DATASET -> Error
  */
 
+drop dataverse test if exists;
+create dataverse test;
+
+use test;
+
 create dataset ` invalid`.a(id int not unknown) primary key id;
\ No newline at end of file
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/ddl/invalid-dataset-name/invalid-dataset-name.4.ddl.sqlpp b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/ddl/invalid-dataset-name/invalid-dataset-name.4.ddl.sqlpp
index dc10acd..91d4ec5 100644
--- a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/ddl/invalid-dataset-name/invalid-dataset-name.4.ddl.sqlpp
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/ddl/invalid-dataset-name/invalid-dataset-name.4.ddl.sqlpp
@@ -17,4 +17,13 @@
  * under the License.
  */
 
+/*
+ * Invalid dataverse name in CREATE DATASET -> Error
+ */
+
 drop dataverse test if exists;
+create dataverse test;
+
+use test;
+
+create dataset `a/b`.a(id int not unknown) primary key id;
\ No newline at end of file
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/ddl/invalid-dataset-name/invalid-dataset-name.5.ddl.sqlpp b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/ddl/invalid-dataset-name/invalid-dataset-name.5.ddl.sqlpp
new file mode 100644
index 0000000..7a9926f
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/ddl/invalid-dataset-name/invalid-dataset-name.5.ddl.sqlpp
@@ -0,0 +1,31 @@
+/*
+ * 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.
+ */
+
+/*
+ * Invalid dataverse name in DROP DATASET -> Error
+ */
+
+drop dataverse c.d if exists;
+create dataverse c.d;
+
+use c.d;
+
+create dataset e(id int not unknown) primary key id;
+
+drop dataset `c/d`.e;
\ No newline at end of file
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/ddl/invalid-dataverse-name/invalid-dataverse-name.6.ddl.sqlpp b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/ddl/invalid-dataverse-name/invalid-dataverse-name.6.ddl.sqlpp
new file mode 100644
index 0000000..84a5205
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/ddl/invalid-dataverse-name/invalid-dataverse-name.6.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.
+ */
+
+/*
+ * Empty dataverse name in DROP -> Error
+ */
+
+drop dataverse ``;
\ No newline at end of file
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/ddl/invalid-dataverse-name/invalid-dataverse-name.7.ddl.sqlpp b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/ddl/invalid-dataverse-name/invalid-dataverse-name.7.ddl.sqlpp
new file mode 100644
index 0000000..ad941fd
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/ddl/invalid-dataverse-name/invalid-dataverse-name.7.ddl.sqlpp
@@ -0,0 +1,27 @@
+/*
+ * 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.
+ */
+
+/*
+ * Invalid dataverse name in DROP -> Error
+ */
+
+drop dataverse a.b if exists;
+create dataverse a.b;
+
+drop dataverse `a/b`;
\ No newline at end of file
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/ddl/invalid-feed-name/invalid-feed-name.4.ddl.sqlpp b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/ddl/invalid-feed-name/invalid-feed-name.4.ddl.sqlpp
index dc10acd..1cf4ada 100644
--- a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/ddl/invalid-feed-name/invalid-feed-name.4.ddl.sqlpp
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/ddl/invalid-feed-name/invalid-feed-name.4.ddl.sqlpp
@@ -17,4 +17,24 @@
  * under the License.
  */
 
+/*
+ * Invalid dataverse name in CREATE FEED -> Error
+ */
+
 drop dataverse test if exists;
+create dataverse test;
+
+use test;
+
+create type Tweet as closed
+{
+  id: int64
+};
+
+create feed `a/b`.a with {
+ "adapter-name" : "socket_adapter",
+ "sockets" : "127.0.0.1:10001",
+ "address-type" : "IP",
+ "type-name" : "Tweet",
+ "format" : "adm"
+};
\ No newline at end of file
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/ddl/invalid-feed-name/invalid-feed-name.5.ddl.sqlpp b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/ddl/invalid-feed-name/invalid-feed-name.5.ddl.sqlpp
new file mode 100644
index 0000000..226850e
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/ddl/invalid-feed-name/invalid-feed-name.5.ddl.sqlpp
@@ -0,0 +1,42 @@
+/*
+ * 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.
+ */
+
+/*
+ * Invalid dataverse name in DROP FEED -> Error
+ */
+
+drop dataverse c.d if exists;
+create dataverse c.d;
+
+use c.d;
+
+create type Tweet as closed
+{
+  id: int64
+};
+
+create feed e with {
+ "adapter-name" : "socket_adapter",
+ "sockets" : "127.0.0.1:10001",
+ "address-type" : "IP",
+ "type-name" : "Tweet",
+ "format" : "adm"
+};
+
+drop feed `c/d`.e;
\ No newline at end of file
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/ddl/invalid-feed-policy-name/invalid-feed-policy-name.3.ddl.sqlpp b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/ddl/invalid-feed-policy-name/invalid-feed-policy-name.3.ddl.sqlpp
index dc10acd..44b1163 100644
--- a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/ddl/invalid-feed-policy-name/invalid-feed-policy-name.3.ddl.sqlpp
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/ddl/invalid-feed-policy-name/invalid-feed-policy-name.3.ddl.sqlpp
@@ -17,4 +17,14 @@
  * under the License.
  */
 
+/*
+ * Invalid feed policy name -> Error
+ */
+
 drop dataverse test if exists;
+create dataverse test;
+
+use test;
+
+create ingestion policy `a/b` from path 'data/feed-policy/policy.properties'
+  definition 'someString';
\ No newline at end of file
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/ddl/invalid-feed-policy-name/invalid-feed-policy-name.4.ddl.sqlpp b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/ddl/invalid-feed-policy-name/invalid-feed-policy-name.4.ddl.sqlpp
new file mode 100644
index 0000000..2e88dfe
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/ddl/invalid-feed-policy-name/invalid-feed-policy-name.4.ddl.sqlpp
@@ -0,0 +1,32 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+/*
+ * Invalid feed policy name in DROP -> Error
+ */
+
+drop dataverse c.d if exists;
+create dataverse c.d;
+
+use c.d;
+
+create ingestion policy e from path 'data/feed-policy/policy.properties'
+  definition 'someString';
+
+drop ingestion policy `c/d`.e;
\ No newline at end of file
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/ddl/invalid-index-name/invalid-index-name.3.ddl.sqlpp b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/ddl/invalid-index-name/invalid-index-name.3.ddl.sqlpp
index 4799420..b585dcb 100644
--- a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/ddl/invalid-index-name/invalid-index-name.3.ddl.sqlpp
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/ddl/invalid-index-name/invalid-index-name.3.ddl.sqlpp
@@ -21,4 +21,9 @@
  * Invalid dataverse name in CREATE INDEX -> Error
  */
 
+drop dataverse test if exists;
+create dataverse test;
+
+use test;
+
 create index a on ` invalid`.t1(x);
\ No newline at end of file
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/ddl/invalid-index-name/invalid-index-name.4.ddl.sqlpp b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/ddl/invalid-index-name/invalid-index-name.4.ddl.sqlpp
index dc10acd..49bd20c 100644
--- a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/ddl/invalid-index-name/invalid-index-name.4.ddl.sqlpp
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/ddl/invalid-index-name/invalid-index-name.4.ddl.sqlpp
@@ -17,4 +17,13 @@
  * under the License.
  */
 
+/*
+ * Invalid dataverse name in CREATE INDEX -> Error
+ */
+
 drop dataverse test if exists;
+create dataverse test;
+
+use test;
+
+create index a on `a/b`.t1(x);
\ No newline at end of file
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/ddl/invalid-index-name/invalid-index-name.5.ddl.sqlpp b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/ddl/invalid-index-name/invalid-index-name.5.ddl.sqlpp
new file mode 100644
index 0000000..8e7f6c3
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/ddl/invalid-index-name/invalid-index-name.5.ddl.sqlpp
@@ -0,0 +1,33 @@
+/*
+ * 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.
+ */
+
+/*
+ * Invalid dataverse name in DROP INDEX -> Error
+ */
+
+drop dataverse c.d if exists;
+create dataverse c.d;
+
+use c.d;
+
+create dataset e(id int not unknown, v int not unknown) primary key id;
+
+create index i1 on e(v);
+
+drop index `c/d`.e.i1;
\ No newline at end of file
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/ddl/invalid-type-name/invalid-type-name.3.ddl.sqlpp b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/ddl/invalid-type-name/invalid-type-name.3.ddl.sqlpp
index ed322ef..6666975 100644
--- a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/ddl/invalid-type-name/invalid-type-name.3.ddl.sqlpp
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/ddl/invalid-type-name/invalid-type-name.3.ddl.sqlpp
@@ -21,6 +21,11 @@
  * Invalid dataverse name in CREATE TYPE -> Error
  */
 
+drop dataverse test if exists;
+create dataverse test;
+
+use test;
+
 create type ` invalid`.a as closed {
   id: int
 };
\ No newline at end of file
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/ddl/invalid-type-name/invalid-type-name.4.ddl.sqlpp b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/ddl/invalid-type-name/invalid-type-name.4.ddl.sqlpp
index dc10acd..22b4efb 100644
--- a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/ddl/invalid-type-name/invalid-type-name.4.ddl.sqlpp
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/ddl/invalid-type-name/invalid-type-name.4.ddl.sqlpp
@@ -17,4 +17,15 @@
  * under the License.
  */
 
+/*
+ * Invalid dataverse name in CREATE TYPE -> Error
+ */
+
 drop dataverse test if exists;
+create dataverse test;
+
+use test;
+
+create type `a/b`.a as closed {
+  id: int
+};
\ No newline at end of file
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/ddl/invalid-type-name/invalid-type-name.5.ddl.sqlpp b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/ddl/invalid-type-name/invalid-type-name.5.ddl.sqlpp
new file mode 100644
index 0000000..c74ae52
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/ddl/invalid-type-name/invalid-type-name.5.ddl.sqlpp
@@ -0,0 +1,33 @@
+/*
+ * 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.
+ */
+
+/*
+ * Invalid dataverse name in DROP TYPE -> Error
+ */
+
+drop dataverse c.d if exists;
+create dataverse c.d;
+
+use c.d;
+
+create type e as closed {
+  id: int
+};
+
+drop type `c/d`.e;
\ No newline at end of file
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/ddl/invalid-udf-name/invalid-udf-name.3.ddl.sqlpp b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/ddl/invalid-udf-name/invalid-udf-name.3.ddl.sqlpp
index 1d85543..4eba639 100644
--- a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/ddl/invalid-udf-name/invalid-udf-name.3.ddl.sqlpp
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/ddl/invalid-udf-name/invalid-udf-name.3.ddl.sqlpp
@@ -21,6 +21,11 @@
  * Invalid dataverse name in CREATE FUNCTION -> Error
  */
 
+drop dataverse test if exists;
+create dataverse test;
+
+use test;
+
 create function ` invalid`.a() {
   1
 };
\ No newline at end of file
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/ddl/invalid-udf-name/invalid-udf-name.4.ddl.sqlpp b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/ddl/invalid-udf-name/invalid-udf-name.4.ddl.sqlpp
index dc10acd..dd65669 100644
--- a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/ddl/invalid-udf-name/invalid-udf-name.4.ddl.sqlpp
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/ddl/invalid-udf-name/invalid-udf-name.4.ddl.sqlpp
@@ -17,4 +17,15 @@
  * under the License.
  */
 
+/*
+ * Invalid dataverse name in CREATE FUNCTION -> Error
+ */
+
 drop dataverse test if exists;
+create dataverse test;
+
+use test;
+
+create function `a/b`.a() {
+  1
+};
\ No newline at end of file
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/ddl/invalid-udf-name/invalid-udf-name.5.ddl.sqlpp b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/ddl/invalid-udf-name/invalid-udf-name.5.ddl.sqlpp
new file mode 100644
index 0000000..ab33494
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/ddl/invalid-udf-name/invalid-udf-name.5.ddl.sqlpp
@@ -0,0 +1,33 @@
+/*
+ * 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.
+ */
+
+/*
+ * Invalid dataverse name in DROP FUNCTION -> Error
+ */
+
+drop dataverse c.d if exists;
+create dataverse c.d;
+
+use c.d;
+
+create function e() {
+  1
+};
+
+drop function `c/d`.e();
\ No newline at end of file
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/testsuite_sqlpp.xml b/asterixdb/asterix-app/src/test/resources/runtimets/testsuite_sqlpp.xml
index 7277c0b..f8f2597 100644
--- a/asterixdb/asterix-app/src/test/resources/runtimets/testsuite_sqlpp.xml
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/testsuite_sqlpp.xml
@@ -4033,65 +4033,79 @@
     <test-case FilePath="ddl">
       <compilation-unit name="invalid-dataverse-name">
         <output-dir compare="Text">none</output-dir>
-        <expected-error>ASX1115: Invalid name for a database object: "&lt;empty&gt;"</expected-error>
+        <expected-error>ASX1115: Invalid name for a database object: ""</expected-error>
         <expected-error>ASX1115: Invalid name for a database object: " a"</expected-error>
         <expected-error>ASX1115: Invalid name for a database object: " invalid"</expected-error>
         <expected-error>ASX1079: Compilation error: Invalid operation - Cannot create dataverse: asterix</expected-error>
         <expected-error>ASX1079: Compilation error: Invalid operation - Cannot create dataverse: algebricks</expected-error>
+        <expected-error>ASX1115: Invalid name for a database object: "" (in line 24, at column 16)</expected-error>
+        <expected-error>ASX1115: Invalid name for a database object: "a/b" (in line 27, at column 16)</expected-error>
       </compilation-unit>
     </test-case>
     <test-case FilePath="ddl">
       <compilation-unit name="invalid-dataset-name">
         <output-dir compare="Text">none</output-dir>
-        <expected-error>ASX1115: Invalid name for a database object: "&lt;empty&gt;"</expected-error>
+        <expected-error>ASX1115: Invalid name for a database object: ""</expected-error>
         <expected-error>ASX1115: Invalid name for a database object: " a"</expected-error>
         <expected-error>ASX1115: Invalid name for a database object: " invalid"</expected-error>
+        <expected-error>ASX1115: Invalid name for a database object: "a/b" (in line 29, at column 16)</expected-error>
+        <expected-error>ASX1115: Invalid name for a database object: "c/d" (in line 31, at column 14)</expected-error>
       </compilation-unit>
     </test-case>
     <test-case FilePath="ddl">
       <compilation-unit name="invalid-feed-name">
         <output-dir compare="Text">none</output-dir>
-        <expected-error>ASX1115: Invalid name for a database object: "&lt;empty&gt;"</expected-error>
+        <expected-error>ASX1115: Invalid name for a database object: ""</expected-error>
         <expected-error>ASX1115: Invalid name for a database object: " a"</expected-error>
         <expected-error>ASX1115: Invalid name for a database object: " invalid"</expected-error>
+        <expected-error>ASX1115: Invalid name for a database object: "a/b" (in line 34, at column 13)</expected-error>
+        <expected-error>ASX1115: Invalid name for a database object: "c/d" (in line 42, at column 11)</expected-error>
       </compilation-unit>
     </test-case>
     <test-case FilePath="ddl">
       <compilation-unit name="invalid-feed-policy-name">
         <output-dir compare="Text">none</output-dir>
-        <expected-error>ASX1115: Invalid name for a database object: "&lt;empty&gt;"</expected-error>
+        <expected-error>ASX1115: Invalid name for a database object: ""</expected-error>
         <expected-error>ASX1115: Invalid name for a database object: " a"</expected-error>
+        <expected-error>ASX1115: Invalid name for a database object: "a/b" (in line 29, at column 1)</expected-error>
+        <expected-error>ASX1115: Invalid name for a database object: "c/d" (in line 32, at column 23)</expected-error>
       </compilation-unit>
     </test-case>
     <test-case FilePath="ddl">
       <compilation-unit name="invalid-index-name">
         <output-dir compare="Text">none</output-dir>
-        <expected-error>ASX1115: Invalid name for a database object: "&lt;empty&gt;"</expected-error>
+        <expected-error>ASX1115: Invalid name for a database object: ""</expected-error>
         <expected-error>ASX1115: Invalid name for a database object: " a"</expected-error>
         <expected-error>ASX1115: Invalid name for a database object: " invalid"</expected-error>
+        <expected-error>ASX1115: Invalid name for a database object: "a/b" (in line 29, at column 19)</expected-error>
+        <expected-error>ASX1115: Invalid name for a database object: "c/d" (in line 33, at column 12)</expected-error>
       </compilation-unit>
     </test-case>
     <test-case FilePath="ddl">
       <compilation-unit name="invalid-nodegroup-name">
         <output-dir compare="Text">none</output-dir>
-        <expected-error>ASX1115: Invalid name for a database object: "&lt;empty&gt;"</expected-error>
+        <expected-error>ASX1115: Invalid name for a database object: ""</expected-error>
         <expected-error>ASX1115: Invalid name for a database object: " a"</expected-error>
       </compilation-unit>
     </test-case>
     <test-case FilePath="ddl">
       <compilation-unit name="invalid-type-name">
         <output-dir compare="Text">none</output-dir>
-        <expected-error>ASX1115: Invalid name for a database object: "&lt;empty&gt;"</expected-error>
+        <expected-error>ASX1115: Invalid name for a database object: ""</expected-error>
         <expected-error>ASX1115: Invalid name for a database object: " a"</expected-error>
         <expected-error>ASX1115: Invalid name for a database object: " invalid"</expected-error>
+        <expected-error>ASX1115: Invalid name for a database object: "a/b" (in line 29, at column 13)</expected-error>
+        <expected-error>ASX1115: Invalid name for a database object: "c/d" (in line 33, at column 11)</expected-error>
       </compilation-unit>
     </test-case>
     <test-case FilePath="ddl">
       <compilation-unit name="invalid-udf-name">
         <output-dir compare="Text">none</output-dir>
-        <expected-error>ASX1115: Invalid name for a database object: "&lt;empty&gt;"</expected-error>
+        <expected-error>ASX1115: Invalid name for a database object: ""</expected-error>
         <expected-error>ASX1115: Invalid name for a database object: " a"</expected-error>
         <expected-error>ASX1115: Invalid name for a database object: " invalid"</expected-error>
+        <expected-error>ASX1115: Invalid name for a database object: "a/b" (in line 29, at column 17)</expected-error>
+        <expected-error>ASX1115: Invalid name for a database object: "c/d" (in line 33, at column 15)</expected-error>
       </compilation-unit>
     </test-case>
     <test-case FilePath="ddl">
diff --git a/asterixdb/asterix-common/src/main/java/org/apache/asterix/common/functions/FunctionSignature.java b/asterixdb/asterix-common/src/main/java/org/apache/asterix/common/functions/FunctionSignature.java
index 1efdd42..f3b1605 100644
--- a/asterixdb/asterix-common/src/main/java/org/apache/asterix/common/functions/FunctionSignature.java
+++ b/asterixdb/asterix-common/src/main/java/org/apache/asterix/common/functions/FunctionSignature.java
@@ -21,6 +21,7 @@
 import java.io.Serializable;
 import java.util.Objects;
 
+import org.apache.asterix.common.exceptions.AsterixException;
 import org.apache.asterix.common.metadata.DataverseName;
 import org.apache.hyracks.algebricks.core.algebra.functions.AlgebricksBuiltinFunctions;
 import org.apache.hyracks.algebricks.core.algebra.functions.FunctionIdentifier;
@@ -132,7 +133,11 @@
             case AlgebricksBuiltinFunctions.ALGEBRICKS_NS:
                 return FunctionConstants.ALGEBRICKS_DV;
             default:
-                return DataverseName.createFromCanonicalForm(dataverseCanonicalName);
+                try {
+                    return DataverseName.createFromCanonicalForm(dataverseCanonicalName);
+                } catch (AsterixException e) {
+                    throw new IllegalArgumentException(dataverseCanonicalName);
+                }
         }
     }
 }
diff --git a/asterixdb/asterix-common/src/main/java/org/apache/asterix/common/metadata/DataverseName.java b/asterixdb/asterix-common/src/main/java/org/apache/asterix/common/metadata/DataverseName.java
index f943dea..f492fd1 100644
--- a/asterixdb/asterix-common/src/main/java/org/apache/asterix/common/metadata/DataverseName.java
+++ b/asterixdb/asterix-common/src/main/java/org/apache/asterix/common/metadata/DataverseName.java
@@ -24,9 +24,9 @@
 import java.util.Collection;
 import java.util.List;
 import java.util.Objects;
-import java.util.function.BiConsumer;
 
-import org.apache.commons.lang3.StringUtils;
+import org.apache.asterix.common.exceptions.AsterixException;
+import org.apache.asterix.common.exceptions.ErrorCode;
 
 /**
  * This class represents a dataverse name.
@@ -36,7 +36,7 @@
  * <p>
  * Each dataverse name can be encoded into a single string (called a canonical form) by
  * {@link #getCanonicalForm()} and decoded back from it with {@link #createFromCanonicalForm(String)}.
- * The canonical form encoding concatenates name parts together with {@link #CANONICAL_FORM_SEPARATOR_CHAR '/'}
+ * The canonical form encoding concatenates name parts together with {@link #CANONICAL_FORM_PART_SEPARATOR '/'}
  * character.
  * <p>
  * E.g. the canonical form for a dataverse name {@code ["a", "b", "c"]} is {@code "a/b/c"}
@@ -58,9 +58,9 @@
  */
 public final class DataverseName implements Serializable, Comparable<DataverseName> {
 
-    private static final long serialVersionUID = 2L;
+    private static final long serialVersionUID = 3L;
 
-    public static final char CANONICAL_FORM_SEPARATOR_CHAR = '/';
+    public static final String CANONICAL_FORM_PART_SEPARATOR = "/";
 
     public static final char DISPLAY_FORM_SEPARATOR_CHAR = '.';
 
@@ -68,25 +68,12 @@
 
     private static final char DISPLAY_FORM_ESCAPE_CHAR = '\\';
 
-    private static final char[] CANONICAL_FORM_SEPARATOR_AND_ESCAPE_CHARS =
-            new char[] { CANONICAL_FORM_SEPARATOR_CHAR };
-
-    private final boolean isMultiPart;
-
     private final String canonicalForm;
 
     private transient volatile String displayForm;
 
-    private DataverseName(String canonicalForm, boolean isMultiPart) {
+    private DataverseName(String canonicalForm) {
         this.canonicalForm = Objects.requireNonNull(canonicalForm);
-        this.isMultiPart = isMultiPart;
-    }
-
-    /**
-     * Returns whether this dataverse name contains multiple name parts or not.
-     */
-    public boolean isMultiPart() {
-        return isMultiPart;
     }
 
     /**
@@ -104,7 +91,7 @@
      * Returns a new list containing dataverse name parts
      */
     public List<String> getParts() {
-        List<String> parts = new ArrayList<>(isMultiPart ? 4 : 1);
+        List<String> parts = new ArrayList<>(4);
         getParts(parts);
         return parts;
     }
@@ -113,28 +100,32 @@
      * Appends dataverse name parts into a given output collection
      */
     public void getParts(Collection<? super String> outParts) {
-        getPartsFromCanonicalForm(canonicalForm, isMultiPart, outParts);
+        getPartsFromCanonicalFormImpl(canonicalForm, outParts);
     }
 
     /**
      * Appends dataverse name parts into a given output collection
      */
-    public static void getPartsFromCanonicalForm(String canonicalForm, Collection<? super String> outParts) {
-        getPartsFromCanonicalForm(canonicalForm, isMultiPartCanonicalForm(canonicalForm), outParts);
-    }
-
-    /**
-     * Appends dataverse name parts into a given output collection
-     */
-    private static void getPartsFromCanonicalForm(String canonicalForm, boolean isMultiPart,
-            Collection<? super String> outParts) {
-        if (isMultiPart) {
-            decodeCanonicalForm(canonicalForm, DataverseName::addPartToCollection, outParts);
-        } else {
-            outParts.add(decodeSinglePartNameFromCanonicalForm(canonicalForm));
+    public static void getPartsFromCanonicalForm(String canonicalForm, Collection<? super String> outParts)
+            throws AsterixException {
+        int partCount = getPartsFromCanonicalFormImpl(canonicalForm, outParts);
+        if (partCount <= 0) {
+            throw new AsterixException(ErrorCode.INVALID_DATABASE_OBJECT_NAME, canonicalForm);
         }
     }
 
+    public int getPartCount() {
+        return getPartCountFromCanonicalFormImpl(canonicalForm);
+    }
+
+    public static int getPartCountFromCanonicalForm(String canonicalForm) throws AsterixException {
+        int partCount = getPartCountFromCanonicalFormImpl(canonicalForm);
+        if (partCount <= 0) {
+            throw new AsterixException(ErrorCode.INVALID_DATABASE_OBJECT_NAME, canonicalForm);
+        }
+        return partCount;
+    }
+
     /**
      * Returns a display form which suitable for error messages, and is a valid SQL++ multi-part identifier.
      */
@@ -154,21 +145,31 @@
     }
 
     public void getDisplayForm(StringBuilder out) {
-        getDisplayFormFromCanonicalForm(canonicalForm, isMultiPart, out);
+        getDisplayFormFromCanonicalFormImpl(canonicalForm, out);
     }
 
-    public static void getDisplayFormFromCanonicalForm(String canonicalForm, StringBuilder out) {
-        getDisplayFormFromCanonicalForm(canonicalForm, isMultiPartCanonicalForm(canonicalForm), out);
-    }
-
-    private static void getDisplayFormFromCanonicalForm(String canonicalForm, boolean isMultiPart, StringBuilder out) {
-        if (isMultiPart) {
-            decodeCanonicalForm(canonicalForm, DataverseName::addPartToDisplayForm, out);
-        } else {
-            String singlePart = decodeSinglePartNameFromCanonicalForm(canonicalForm);
-            addPartToDisplayForm(singlePart, out);
+    public static void getDisplayFormFromCanonicalForm(String canonicalForm, StringBuilder out)
+            throws AsterixException {
+        int partCount = getDisplayFormFromCanonicalFormImpl(canonicalForm, out);
+        if (partCount <= 0) {
+            throw new AsterixException(ErrorCode.INVALID_DATABASE_OBJECT_NAME, canonicalForm);
         }
-        out.setLength(out.length() - 1); // remove last separator char
+    }
+
+    private static int getPartsFromCanonicalFormImpl(String canonicalForm, Collection<? super String> outParts) {
+        return decodeCanonicalForm(canonicalForm, DataverseName::addPartToCollection, outParts);
+    }
+
+    private static int getPartCountFromCanonicalFormImpl(String canonicalForm) {
+        return decodeCanonicalForm(canonicalForm, null, null);
+    }
+
+    private static int getDisplayFormFromCanonicalFormImpl(String canonicalForm, StringBuilder out) {
+        int partCount = decodeCanonicalForm(canonicalForm, DataverseName::addPartToDisplayForm, out);
+        if (partCount > 0) {
+            out.setLength(out.length() - 1); // remove last separator char
+        }
+        return partCount;
     }
 
     @Override
@@ -194,7 +195,7 @@
      * Creates a new dataverse name from a given list of name parts.
      * Equivalent to {@code create(parts, 0, parts.size())}.
      */
-    public static DataverseName create(List<String> parts) {
+    public static DataverseName create(List<String> parts) throws AsterixException {
         return create(parts, 0, parts.size());
     }
 
@@ -208,7 +209,7 @@
      * @param toIndex
      *            index to stop at (exclusive, value at that index is not used)
      */
-    public static DataverseName create(List<String> parts, int fromIndex, int toIndex) {
+    public static DataverseName create(List<String> parts, int fromIndex, int toIndex) throws AsterixException {
         int partCount = toIndex - fromIndex;
         return partCount == 1 ? createSinglePartName(parts.get(fromIndex))
                 : createMultiPartName(parts, fromIndex, toIndex);
@@ -217,18 +218,21 @@
     /**
      * Creates a new dataverse name from its scalar encoding (canonical form) returned by {@link #getCanonicalForm()}
      */
-    public static DataverseName createFromCanonicalForm(String canonicalForm) {
-        boolean isMultiPart = isMultiPartCanonicalForm(canonicalForm);
-        return new DataverseName(canonicalForm, isMultiPart);
+    public static DataverseName createFromCanonicalForm(String canonicalForm) throws AsterixException {
+        int partCount = getPartCountFromCanonicalFormImpl(canonicalForm);
+        if (partCount <= 0) {
+            throw new AsterixException(ErrorCode.INVALID_DATABASE_OBJECT_NAME, canonicalForm);
+        }
+        return new DataverseName(canonicalForm);
     }
 
     /**
      * Creates a single-part dataverse name.
      * Equivalent to {@code create(Collections.singletonList(singlePart))}, but performs faster.
      */
-    public static DataverseName createSinglePartName(String singlePart) {
+    public static DataverseName createSinglePartName(String singlePart) throws AsterixException {
         String canonicalForm = encodeSinglePartNamePartIntoCanonicalForm(singlePart);
-        return new DataverseName(canonicalForm, false);
+        return new DataverseName(canonicalForm);
     }
 
     /**
@@ -236,87 +240,90 @@
      * Validates that the canonical form of the created dataverse name is the same as its given single name part.
      */
     public static DataverseName createBuiltinDataverseName(String singlePart) {
-        if (StringUtils.containsAny(singlePart, CANONICAL_FORM_SEPARATOR_AND_ESCAPE_CHARS)) {
-            throw new IllegalArgumentException(singlePart);
+        try {
+            return createSinglePartName(singlePart); // 1-part name
+        } catch (AsterixException e) {
+            throw new IllegalArgumentException(e.getMessage(), e);
         }
-        DataverseName dataverseName = createSinglePartName(singlePart); // 1-part name
-        String canonicalForm = dataverseName.getCanonicalForm();
-        if (!canonicalForm.equals(singlePart)) {
-            throw new IllegalStateException(canonicalForm + "!=" + singlePart);
-        }
-        return dataverseName;
     }
 
-    private static DataverseName createMultiPartName(List<String> parts, int fromIndex, int toIndex) {
+    private static DataverseName createMultiPartName(List<String> parts, int fromIndex, int toIndex)
+            throws AsterixException {
         String canonicalForm = encodeMultiPartNameIntoCanonicalForm(parts, fromIndex, toIndex);
-        return new DataverseName(canonicalForm, true);
+        return new DataverseName(canonicalForm);
     }
 
-    private static String encodeMultiPartNameIntoCanonicalForm(List<String> parts, int fromIndex, int toIndex) {
+    private static String encodeMultiPartNameIntoCanonicalForm(List<String> parts, int fromIndex, int toIndex)
+            throws AsterixException {
         Objects.requireNonNull(parts);
         int partCount = toIndex - fromIndex;
         if (partCount <= 0) {
             throw new IllegalArgumentException(fromIndex + "," + toIndex);
         }
-        StringBuilder sb = new StringBuilder(32);
-        for (int i = 0; i < partCount; i++) {
-            if (i > 0) {
-                sb.append(CANONICAL_FORM_SEPARATOR_CHAR);
-            }
-            encodePartIntoCanonicalForm(parts.get(fromIndex + i), sb);
+        int canonicalFormLength = (partCount - 1) * CANONICAL_FORM_PART_SEPARATOR.length();
+        for (int i = fromIndex; i < toIndex; i++) {
+            canonicalFormLength += parts.get(i).length();
+        }
+        String sep = "";
+        StringBuilder sb = new StringBuilder(canonicalFormLength);
+        for (int i = fromIndex; i < toIndex; i++) {
+            sb.append(sep);
+            encodePartIntoCanonicalForm(parts.get(i), sb);
+            sep = CANONICAL_FORM_PART_SEPARATOR;
         }
         return sb.toString();
     }
 
-    private static String encodeSinglePartNamePartIntoCanonicalForm(String singlePart) {
-        if (StringUtils.indexOfAny(singlePart, CANONICAL_FORM_SEPARATOR_AND_ESCAPE_CHARS) < 0) {
-            // no escaping needed
-            return singlePart;
-        }
-        StringBuilder sb = new StringBuilder(singlePart.length() + 4);
-        encodePartIntoCanonicalForm(singlePart, sb);
-        return sb.toString();
+    private static String encodeSinglePartNamePartIntoCanonicalForm(String singlePart) throws AsterixException {
+        validatePart(singlePart);
+        return singlePart;
     }
 
-    private static void encodePartIntoCanonicalForm(String part, StringBuilder out) {
+    private static void encodePartIntoCanonicalForm(String part, StringBuilder out) throws AsterixException {
+        validatePart(part);
         out.append(part);
     }
 
-    private static <T> void decodeCanonicalForm(String canonicalForm, BiConsumer<CharSequence, T> partConsumer,
+    private static void validatePart(String part) throws AsterixException {
+        if (part.isEmpty() || part.contains(CANONICAL_FORM_PART_SEPARATOR)) {
+            throw new AsterixException(ErrorCode.INVALID_DATABASE_OBJECT_NAME, part);
+        }
+    }
+
+    private static <T> int decodeCanonicalForm(String canonicalForm, DataverseNamePartConsumer<T> partConsumer,
             T partConsumerArg) {
-        int ln = canonicalForm.length();
-        StringBuilder sb = new StringBuilder(ln);
-        for (int i = 0; i < ln; i++) {
-            char c = canonicalForm.charAt(i);
-            if (c == CANONICAL_FORM_SEPARATOR_CHAR) {
-                partConsumer.accept(sb, partConsumerArg);
-                sb.setLength(0);
-            } else {
-                sb.append(c);
+        int partCount = 0, from = 0, to;
+        while ((to = canonicalForm.indexOf(CANONICAL_FORM_PART_SEPARATOR, from)) > from) {
+            if (partConsumer != null) {
+                partConsumer.accept(canonicalForm, from, to, partConsumerArg);
             }
+            partCount++;
+            from = to + CANONICAL_FORM_PART_SEPARATOR.length();
         }
-        if (sb.length() > 0) {
-            partConsumer.accept(sb, partConsumerArg);
+        boolean hasOneMore = from != to && from < canonicalForm.length();
+        if (!hasOneMore) {
+            return 0;
         }
+        if (partConsumer != null) {
+            partConsumer.accept(canonicalForm, from, canonicalForm.length(), partConsumerArg);
+        }
+        partCount++;
+        return partCount;
     }
 
-    // optimization for a single part name
-    private static String decodeSinglePartNameFromCanonicalForm(String canonicalForm) {
-        return canonicalForm;
+    @FunctionalInterface
+    private interface DataverseNamePartConsumer<T> {
+        void accept(String canonicalForm, int from, int to, T arg);
     }
 
-    private static boolean isMultiPartCanonicalForm(String canonicalForm) {
-        return canonicalForm.indexOf(CANONICAL_FORM_SEPARATOR_CHAR) != -1;
+    private static void addPartToCollection(String canonicalForm, int from, int to, Collection<? super String> out) {
+        out.add(canonicalForm.substring(from, to));
     }
 
-    private static void addPartToCollection(CharSequence part, Collection<? super String> out) {
-        out.add(part.toString());
-    }
-
-    private static void addPartToDisplayForm(CharSequence part, StringBuilder out) {
+    private static void addPartToDisplayForm(String canonicalForm, int from, int to, StringBuilder out) {
         boolean needQuote = false;
-        for (int i = 0, ln = part.length(); i < ln; i++) {
-            char c = part.charAt(i);
+        for (int i = from; i < to; i++) {
+            char c = canonicalForm.charAt(i);
             boolean noQuote = isLetter(c) || c == '_' || (i > 0 && (isDigit(c) || c == '$'));
             if (!noQuote) {
                 needQuote = true;
@@ -326,8 +333,8 @@
         if (needQuote) {
             out.append(DISPLAY_FORM_QUOTE_CHAR);
         }
-        for (int i = 0, ln = part.length(); i < ln; i++) {
-            char c = part.charAt(i);
+        for (int i = from; i < to; i++) {
+            char c = canonicalForm.charAt(i);
             if (c == DISPLAY_FORM_ESCAPE_CHAR || c == DISPLAY_FORM_QUOTE_CHAR) {
                 out.append(DISPLAY_FORM_ESCAPE_CHAR);
             }
diff --git a/asterixdb/asterix-common/src/main/java/org/apache/asterix/common/storage/ResourceReference.java b/asterixdb/asterix-common/src/main/java/org/apache/asterix/common/storage/ResourceReference.java
index 94a5f2a..ebf212b 100644
--- a/asterixdb/asterix-common/src/main/java/org/apache/asterix/common/storage/ResourceReference.java
+++ b/asterixdb/asterix-common/src/main/java/org/apache/asterix/common/storage/ResourceReference.java
@@ -25,6 +25,7 @@
 import java.util.Collections;
 import java.util.List;
 
+import org.apache.asterix.common.exceptions.AsterixException;
 import org.apache.asterix.common.metadata.DataverseName;
 import org.apache.asterix.common.utils.StorageConstants;
 import org.apache.asterix.common.utils.StoragePathUtil;
@@ -67,14 +68,22 @@
         String probablyPartition = tokens[--offset];
         if (dvParts.isEmpty()) {
             // root/partition/dataverse/dataset/rebalanceCount/index/fileName
-            dataverse = DataverseName.createSinglePartName(dvPart);
+            try {
+                dataverse = DataverseName.createSinglePartName(dvPart);
+            } catch (AsterixException e) {
+                throw new IllegalArgumentException("unable to parse path: '" + path + "'!", e);
+            }
             partition = probablyPartition;
             root = tokens[--offset];
         } else if (probablyPartition.startsWith(StorageConstants.PARTITION_DIR_PREFIX)) {
             // root/partition/dataverse_p1/^dataverse_p2/.../^dataverse_pn/dataset/rebalanceCount/index/fileName
             dvParts.add(dvPart);
             Collections.reverse(dvParts);
-            dataverse = DataverseName.create(dvParts);
+            try {
+                dataverse = DataverseName.create(dvParts);
+            } catch (AsterixException e) {
+                throw new IllegalArgumentException("unable to parse path: '" + path + "'!", e);
+            }
             partition = probablyPartition;
             root = tokens[--offset];
         } else if (dvPart.startsWith(StorageConstants.PARTITION_DIR_PREFIX)) {
@@ -82,8 +91,12 @@
             if (dvParts.size() != 1) {
                 throw new IllegalArgumentException("unable to parse path: '" + path + "'!");
             }
-            dataverse =
-                    DataverseName.createSinglePartName(StoragePathUtil.DATAVERSE_CONTINUATION_MARKER + dvParts.get(0));
+            try {
+                dataverse = DataverseName
+                        .createSinglePartName(StoragePathUtil.DATAVERSE_CONTINUATION_MARKER + dvParts.get(0));
+            } catch (AsterixException e) {
+                throw new IllegalArgumentException("unable to parse path: '" + path + "'!", e);
+            }
             LOGGER.info("legacy dataverse starting with ^ found: '{}'; this is not supported for new dataverses",
                     dataverse);
             partition = dvPart;
diff --git a/asterixdb/asterix-common/src/test/java/org/apache/asterix/common/metadata/DataverseNameTest.java b/asterixdb/asterix-common/src/test/java/org/apache/asterix/common/metadata/DataverseNameTest.java
index 75b3989..faf1960 100644
--- a/asterixdb/asterix-common/src/test/java/org/apache/asterix/common/metadata/DataverseNameTest.java
+++ b/asterixdb/asterix-common/src/test/java/org/apache/asterix/common/metadata/DataverseNameTest.java
@@ -25,8 +25,9 @@
 import java.util.Arrays;
 import java.util.Collections;
 import java.util.List;
-import java.util.function.Supplier;
 
+import org.apache.asterix.common.exceptions.AsterixException;
+import org.apache.asterix.common.exceptions.ErrorCode;
 import org.apache.commons.collections4.ListUtils;
 import org.apache.hyracks.algebricks.common.utils.Triple;
 import org.apache.hyracks.algebricks.core.algebra.functions.AlgebricksBuiltinFunctions;
@@ -49,10 +50,6 @@
             // dataverse for Asterix functions
             ASTERIX_NS);
 
-    private static final List<String> TEST_BUILTIN_DATAVERSE_INVALID_NAME_PARAMS = Arrays.asList(
-            // separator character is not allowed
-            "a/b");
-
     private static final List<Triple<String, String, String>> TEST_SINGLE_PART_NAME_PARAMS = Arrays.asList(
             // <1-part-name, canonical-form, display-form>
             new Triple<>("abz", "abz", "abz"),
@@ -86,6 +83,15 @@
             // with display form escape character
             new Triple<>(Arrays.asList("a\\b", "c\\d"), "a\\b/c\\d", "`a\\\\b`.`c\\\\d`"));
 
+    private static final List<String> TEST_INVALID_SINGLE_PART_PARAMS =
+            Arrays.asList("", "/", "//", "///", "a/", "a/b", "a/b/");
+
+    private static final List<List<String>> TEST_INVALID_MULTI_PART_PARAMS =
+            Arrays.asList(Arrays.asList("", ""), Arrays.asList("a", "", "d"), Arrays.asList("a", "b/c", "d"));
+
+    private static final List<String> TEST_INVALID_CANONICAL_FORM_PARAMS =
+            Arrays.asList("", "/", "//", "///", "/a", "a/", "a/b/");
+
     @Test
     public void testBuiltinDataverseName() throws Exception {
         for (String p : TEST_BUILTIN_DATAVERSE_NAME_PARAMS) {
@@ -161,8 +167,7 @@
 
     protected void testDataverseNameImpl(DataverseName dataverseName, List<String> parts, String expectedCanonicalForm,
             String expectedDisplayForm) throws Exception {
-        boolean isMultiPart = parts.size() > 1;
-        Assert.assertEquals("is-multipart", isMultiPart, dataverseName.isMultiPart());
+        Assert.assertEquals("get-part-count", parts.size(), dataverseName.getPartCount());
 
         // test getParts()
         Assert.assertArrayEquals("get-parts-0", parts.toArray(), dataverseName.getParts().toArray());
@@ -184,7 +189,7 @@
     }
 
     @Test
-    public void testCompare() {
+    public void testCompare() throws Exception {
         List<DataverseName> dvList =
                 Arrays.asList(DataverseName.createSinglePartName("a"), DataverseName.create(Arrays.asList("a", "a")),
                         DataverseName.createSinglePartName("aa"), DataverseName.createSinglePartName("b"));
@@ -205,11 +210,7 @@
 
     @Test
     public void testExceptions() {
-        // 1. Invalid names for builtin dataverses
-        for (String p : TEST_BUILTIN_DATAVERSE_INVALID_NAME_PARAMS) {
-            testInvalidBuiltinDataverseNameImpl(p);
-        }
-        // 2. NullPointerException
+        // 1. NullPointerException
         testRuntimeException(() -> DataverseName.create(null), NullPointerException.class);
         testRuntimeException(() -> DataverseName.create(null, 0, 0), NullPointerException.class);
         testRuntimeException(() -> DataverseName.create(null, 0, 1), NullPointerException.class);
@@ -218,19 +219,61 @@
         testRuntimeException(() -> DataverseName.createBuiltinDataverseName(null), NullPointerException.class);
         testRuntimeException(() -> DataverseName.createFromCanonicalForm(null), NullPointerException.class);
         testRuntimeException(() -> DataverseName.create(Collections.singletonList(null)), NullPointerException.class);
-        // 3. IndexOutOfBoundsException
+
+        // 2. IndexOutOfBoundsException
         testRuntimeException(() -> DataverseName.create(Collections.emptyList(), 0, 1),
                 IndexOutOfBoundsException.class);
         testRuntimeException(() -> DataverseName.create(Collections.emptyList(), 0, 2),
                 IndexOutOfBoundsException.class);
-        // 4. IllegalArgumentException
+
+        // 3.1 IllegalArgumentException
         testRuntimeException(() -> DataverseName.create(Collections.emptyList()), IllegalArgumentException.class);
         testRuntimeException(() -> DataverseName.create(Collections.emptyList(), 0, 0), IllegalArgumentException.class);
         testRuntimeException(() -> DataverseName.create(Arrays.asList("a", "b", "c"), 2, 1),
                 IllegalArgumentException.class);
+
+        // 3.2 IllegalArgumentException -> invalid builtin dataverse name
+        for (String invalidForm : TEST_INVALID_SINGLE_PART_PARAMS) {
+            testRuntimeException(() -> DataverseName.createBuiltinDataverseName(invalidForm),
+                    IllegalArgumentException.class);
+        }
+
+        // 4.1 ErrorCode.INVALID_DATABASE_OBJECT_NAME (invalid single part name)
+        for (String invalidForm : TEST_INVALID_SINGLE_PART_PARAMS) {
+            testAsterixException(invalidForm, DataverseName::createSinglePartName,
+                    ErrorCode.INVALID_DATABASE_OBJECT_NAME);
+        }
+
+        // 4.2 ErrorCode.INVALID_DATABASE_OBJECT_NAME (invalid multi part name)
+        for (List<String> invalidForm : TEST_INVALID_MULTI_PART_PARAMS) {
+            testAsterixException(invalidForm, DataverseName::create, ErrorCode.INVALID_DATABASE_OBJECT_NAME);
+        }
+        testAsterixException(Arrays.asList("a", "", "d"), (arg) -> DataverseName.create(arg, 0, 2),
+                ErrorCode.INVALID_DATABASE_OBJECT_NAME);
+        testAsterixException(Arrays.asList("a", "b/c", "d"), (arg) -> DataverseName.create(arg, 0, 2),
+                ErrorCode.INVALID_DATABASE_OBJECT_NAME);
+
+        // 4.3 ErrorCode.INVALID_DATABASE_OBJECT_NAME (invalid canonical form)
+        for (String invalidForm : TEST_INVALID_CANONICAL_FORM_PARAMS) {
+            testAsterixException(invalidForm, DataverseName::createFromCanonicalForm,
+                    ErrorCode.INVALID_DATABASE_OBJECT_NAME);
+            testAsterixException(invalidForm, DataverseName::getPartCountFromCanonicalForm,
+                    ErrorCode.INVALID_DATABASE_OBJECT_NAME);
+            testAsterixException(invalidForm, this::getPartsFromCanonicalForm, ErrorCode.INVALID_DATABASE_OBJECT_NAME);
+            testAsterixException(invalidForm, this::getDisplayFormFromCanonicalForm,
+                    ErrorCode.INVALID_DATABASE_OBJECT_NAME);
+        }
     }
 
-    private <E extends RuntimeException> void testRuntimeException(Supplier<DataverseName> supplier,
+    private interface DataverseNameSupplier<R> {
+        R get() throws AsterixException;
+    }
+
+    private interface DataverseNameFunction<V, R> {
+        R get(V value) throws AsterixException;
+    }
+
+    private <R, E extends RuntimeException> void testRuntimeException(DataverseNameSupplier<R> supplier,
             Class<E> exceptionClass) {
         try {
             supplier.get();
@@ -245,15 +288,38 @@
                     throw ae;
                 }
             }
+        } catch (AsterixException e) {
+            Assert.fail("Expected to catch " + exceptionClass.getName() + ", but caught " + e.getClass().getName());
         }
     }
 
-    private void testInvalidBuiltinDataverseNameImpl(String singlePart) {
+    private <V, R> void testAsterixException(V supplierArg, DataverseNameFunction<V, R> supplier, ErrorCode errorCode) {
         try {
-            DataverseName.createBuiltinDataverseName(singlePart);
-            Assert.fail(singlePart);
-        } catch (IllegalArgumentException e) {
-            // this error is expected
+            supplier.get(supplierArg);
+            Assert.fail(
+                    "Did not get expected exception with error code " + errorCode.intValue() + " for " + supplierArg);
+        } catch (AsterixException e) {
+            if (e.getErrorCode() != errorCode.intValue()) {
+                try {
+                    Assert.fail("Expected to catch exception with error code " + errorCode.intValue()
+                            + ", but caught exceptionn with error code " + e.getErrorCode());
+                } catch (AssertionError ae) {
+                    ae.initCause(e);
+                    throw ae;
+                }
+            }
         }
     }
+
+    private List<String> getPartsFromCanonicalForm(String canonicalForm) throws AsterixException {
+        ArrayList<String> list = new ArrayList<>();
+        DataverseName.getPartsFromCanonicalForm(canonicalForm, list);
+        return list;
+    }
+
+    private String getDisplayFormFromCanonicalForm(String canonicalForm) throws AsterixException {
+        StringBuilder sb = new StringBuilder();
+        DataverseName.getDisplayFormFromCanonicalForm(canonicalForm, sb);
+        return sb.toString();
+    }
 }
diff --git a/asterixdb/asterix-external-data/src/main/java/org/apache/asterix/external/library/ExternalLibraryManager.java b/asterixdb/asterix-external-data/src/main/java/org/apache/asterix/external/library/ExternalLibraryManager.java
index dce5503..e54b729 100755
--- a/asterixdb/asterix-external-data/src/main/java/org/apache/asterix/external/library/ExternalLibraryManager.java
+++ b/asterixdb/asterix-external-data/src/main/java/org/apache/asterix/external/library/ExternalLibraryManager.java
@@ -282,7 +282,13 @@
                     return FileVisitResult.SKIP_SUBTREE;
                 }
                 String candidateLib = tokens[currToken];
-                DataverseName candidateDv = DataverseName.create(dvParts);
+                DataverseName candidateDv;
+                try {
+                    candidateDv = DataverseName.create(dvParts);
+                } catch (AsterixException e) {
+                    // shouldn't happen
+                    throw HyracksDataException.create(e);
+                }
                 FileReference candidateLibPath = findLibraryRevDir(candidateDv, candidateLib);
                 if (candidateLibPath != null) {
                     libs.add(new Pair<>(candidateDv, candidateLib));
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 4beb932..2c29e60 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
@@ -201,7 +201,7 @@
         }
     }
 
-    public static DataverseName getDatasetDataverse(Map<String, String> configuration) {
+    public static DataverseName getDatasetDataverse(Map<String, String> configuration) throws AsterixException {
         return DataverseName.createFromCanonicalForm(configuration.get(ExternalDataConstants.KEY_DATASET_DATAVERSE));
     }
 
diff --git a/asterixdb/asterix-external-data/src/test/java/org/apache/asterix/external/feed/test/InputHandlerTest.java b/asterixdb/asterix-external-data/src/test/java/org/apache/asterix/external/feed/test/InputHandlerTest.java
index 2c64ce3..30d3266 100644
--- a/asterixdb/asterix-external-data/src/test/java/org/apache/asterix/external/feed/test/InputHandlerTest.java
+++ b/asterixdb/asterix-external-data/src/test/java/org/apache/asterix/external/feed/test/InputHandlerTest.java
@@ -31,6 +31,7 @@
 
 import org.apache.asterix.active.ActiveRuntimeId;
 import org.apache.asterix.active.EntityId;
+import org.apache.asterix.common.exceptions.AsterixException;
 import org.apache.asterix.common.memory.ConcurrentFramePool;
 import org.apache.asterix.common.metadata.DataverseName;
 import org.apache.asterix.external.feed.dataflow.FeedRuntimeInputHandler;
@@ -60,7 +61,7 @@
     private static final int DEFAULT_FRAME_SIZE = 32768;
     private static final int NUM_FRAMES = 128;
     private static final long FEED_MEM_BUDGET = DEFAULT_FRAME_SIZE * NUM_FRAMES;
-    private static final DataverseName DATAVERSE = DataverseName.createSinglePartName("dataverse");
+    private static final String DATAVERSE_NAME = "dataverse";
     private static final String DATASET = "dataset";
     private static final String FEED = "feed";
     private static final String NODE_ID = "NodeId";
@@ -69,9 +70,10 @@
     private volatile static HyracksDataException cause = null;
 
     private FeedRuntimeInputHandler createInputHandler(IHyracksTaskContext ctx, IFrameWriter writer,
-            FeedPolicyAccessor fpa, ConcurrentFramePool framePool) throws HyracksDataException {
+            FeedPolicyAccessor fpa, ConcurrentFramePool framePool) throws HyracksDataException, AsterixException {
+        DataverseName dvName = DataverseName.createSinglePartName(DATAVERSE_NAME);
         FrameTupleAccessor fta = Mockito.mock(FrameTupleAccessor.class);
-        EntityId feedId = new EntityId(FeedUtils.FEED_EXTENSION_NAME, DATAVERSE, FEED);
+        EntityId feedId = new EntityId(FeedUtils.FEED_EXTENSION_NAME, dvName, FEED);
         FeedConnectionId connectionId = new FeedConnectionId(feedId, DATASET);
         ActiveRuntimeId runtimeId = new ActiveRuntimeId(feedId, FeedRuntimeType.COLLECT.toString(), 0);
         return new FeedRuntimeInputHandler(ctx, connectionId, runtimeId, writer, fpa, fta, framePool);
diff --git a/asterixdb/asterix-lang-common/src/main/java/org/apache/asterix/lang/common/util/FunctionUtil.java b/asterixdb/asterix-lang-common/src/main/java/org/apache/asterix/lang/common/util/FunctionUtil.java
index 50a4bf2..ded91af 100644
--- a/asterixdb/asterix-lang-common/src/main/java/org/apache/asterix/lang/common/util/FunctionUtil.java
+++ b/asterixdb/asterix-lang-common/src/main/java/org/apache/asterix/lang/common/util/FunctionUtil.java
@@ -31,6 +31,7 @@
 import java.util.Set;
 import java.util.function.BiFunction;
 
+import org.apache.asterix.common.exceptions.AsterixException;
 import org.apache.asterix.common.exceptions.CompilationException;
 import org.apache.asterix.common.exceptions.ErrorCode;
 import org.apache.asterix.common.functions.FunctionConstants;
@@ -326,8 +327,12 @@
         if (dataverseNameArg == null) {
             throw new CompilationException(ErrorCode.COMPILATION_ERROR, sourceLoc, "Invalid argument to dataset()");
         }
-        DataverseName dataverseName = DataverseName.createFromCanonicalForm(dataverseNameArg);
-
+        DataverseName dataverseName;
+        try {
+            dataverseName = DataverseName.createFromCanonicalForm(dataverseNameArg);
+        } catch (AsterixException e) {
+            throw new CompilationException(ErrorCode.COMPILATION_ERROR, sourceLoc, e, "Invalid argument to dataset()");
+        }
         String datasetName = argExtractFunction.apply(datasetFnArgs.get(startPos + 1));
         if (datasetName == null) {
             throw new CompilationException(ErrorCode.COMPILATION_ERROR, sourceLoc, "Invalid argument to dataset()");
diff --git a/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/rewrites/visitor/VariableCheckAndRewriteVisitor.java b/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/rewrites/visitor/VariableCheckAndRewriteVisitor.java
index 8e8cfc7..bbf1a46 100644
--- a/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/rewrites/visitor/VariableCheckAndRewriteVisitor.java
+++ b/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/rewrites/visitor/VariableCheckAndRewriteVisitor.java
@@ -25,6 +25,7 @@
 import java.util.Map;
 import java.util.Set;
 
+import org.apache.asterix.common.exceptions.AsterixException;
 import org.apache.asterix.common.exceptions.CompilationException;
 import org.apache.asterix.common.exceptions.ErrorCode;
 import org.apache.asterix.common.functions.FunctionSignature;
@@ -91,7 +92,13 @@
             } else {
                 String dataverseNamePart =
                         SqlppVariableUtil.toUserDefinedVariableName(leadingVarExpr.getVar().getValue()).getValue();
-                DataverseName dataverseName = DataverseName.createSinglePartName(dataverseNamePart); // 1-part name
+                DataverseName dataverseName; // 1-part name
+                try {
+                    dataverseName = DataverseName.createSinglePartName(dataverseNamePart);
+                } catch (AsterixException e) {
+                    throw new CompilationException(ErrorCode.INVALID_DATABASE_OBJECT_NAME, fa.getSourceLocation(),
+                            dataverseNamePart);
+                }
                 String datasetName = fa.getIdent().getValue();
                 CallExpr datasetExpr = resolveAsDataset(dataverseName, datasetName, parent, leadingVarExpr);
                 if (datasetExpr != null) {
@@ -110,7 +117,13 @@
                 if (resolveAsVariableReference(topVarExpr)) {
                     return fa;
                 } else {
-                    DataverseName dataverseName = DataverseName.create(dataverseNameParts);
+                    DataverseName dataverseName;
+                    try {
+                        dataverseName = DataverseName.create(dataverseNameParts);
+                    } catch (AsterixException e) {
+                        throw new CompilationException(ErrorCode.INVALID_DATABASE_OBJECT_NAME, fa.getSourceLocation(),
+                                dataverseNameParts.toString());
+                    }
                     String datasetName = fa.getIdent().getValue();
                     CallExpr datasetExpr = resolveAsDataset(dataverseName, datasetName, parent, topVarExpr);
                     if (datasetExpr != null) {
diff --git a/asterixdb/asterix-lang-sqlpp/src/main/javacc/SQLPP.jj b/asterixdb/asterix-lang-sqlpp/src/main/javacc/SQLPP.jj
index d8fd123..c4c86f4 100644
--- a/asterixdb/asterix-lang-sqlpp/src/main/javacc/SQLPP.jj
+++ b/asterixdb/asterix-lang-sqlpp/src/main/javacc/SQLPP.jj
@@ -67,6 +67,7 @@
 import org.apache.asterix.common.annotations.UndeclaredFieldsDataGen;
 import org.apache.asterix.common.config.DatasetConfig.DatasetType;
 import org.apache.asterix.common.config.DatasetConfig.IndexType;
+import org.apache.asterix.common.exceptions.AsterixException;
 import org.apache.asterix.common.exceptions.CompilationException;
 import org.apache.asterix.common.exceptions.ErrorCode;
 import org.apache.asterix.common.exceptions.WarningCollector;
@@ -374,7 +375,7 @@
         return parseImpl(new ParseFunction<List<String>>() {
             @Override
             public List<String> parse() throws ParseException {
-                return SQLPPParser.this.MultipartIdentifier();
+                return SQLPPParser.this.MultipartIdentifier().first;
             }
         });
     }
@@ -420,7 +421,15 @@
         try {
             return parseFunction.parse();
         } catch (SqlppParseException e) {
-            throw new CompilationException(ErrorCode.PARSE_ERROR, e.getSourceLocation(), LogRedactionUtil.userData(getMessage(e)));
+            if (e.getCause() instanceof AlgebricksException) {
+              AlgebricksException cause = (AlgebricksException) e.getCause();
+              if (cause.getError().isPresent() && cause.getError().get() instanceof ErrorCode) {
+                throw new CompilationException((ErrorCode) cause.getError().get(), e.getSourceLocation(),
+                  cause.getParams());
+              }
+            }
+            throw new CompilationException(ErrorCode.PARSE_ERROR, e.getSourceLocation(),
+              LogRedactionUtil.userData(getMessage(e)));
         } catch (ParseException e) {
             throw new CompilationException(ErrorCode.PARSE_ERROR, LogRedactionUtil.userData(getMessage(e)));
         } catch (Error e) {
@@ -669,6 +678,17 @@
             throw new SqlppParseException(expr.getSourceLocation(), errorPrefix + " should be an INTEGER");
         }
     }
+
+    private DataverseName createDataverseName(List<String> parts, int fromIndex, int toIndex, Token startToken)
+      throws SqlppParseException {
+      try {
+        return DataverseName.create(parts, fromIndex, toIndex);
+      } catch (AsterixException e) {
+        SqlppParseException pe = new SqlppParseException(getSourceLocation(startToken), e.getMessage());
+        pe.initCause(e);
+        throw pe;
+      }
+    }
 }
 
 PARSER_END(SQLPPParser)
@@ -745,12 +765,12 @@
 DataverseDecl DataverseDeclaration() throws ParseException:
 {
   Token startToken = null;
-  List<String> dvName = null;
+  DataverseName dvName = null;
 }
 {
-  <USE> { startToken = token; } dvName = MultipartIdentifier()
+  <USE> { startToken = token; } dvName = DataverseName()
     {
-      defaultDataverse = DataverseName.create(dvName);
+      defaultDataverse = dvName;
       DataverseDecl dvDecl = new DataverseDecl(defaultDataverse);
       return addSourceLocation(dvDecl, startToken);
     }
@@ -1187,14 +1207,14 @@
 Pair<List<List<String>>, List<Pair<List<String>, IndexedTypeExpression>>> IndexedElementUnnestSelectBody()
   throws ParseException:
 {
-  List<String> path = null;
+  Triple<List<String>, Token, Token> path = null;
   IndexedTypeExpression type = null;
   List<List<String>> unnestList = new ArrayList();
   List<Pair<List<String>, IndexedTypeExpression>> projectList = new ArrayList();
 }
 {
-  path = MultipartIdentifier() { unnestList.add(path); }
-  ( <UNNEST> path = MultipartIdentifier() { unnestList.add(path); })*
+  path = MultipartIdentifier() { unnestList.add(path.first); }
+  ( <UNNEST> path = MultipartIdentifier() { unnestList.add(path.first); })*
   (
     ( <COLON> type = IndexedTypeExpr(false)
       {
@@ -1204,11 +1224,11 @@
     (
       <SELECT> path = MultipartIdentifier() ( <COLON> type = IndexedTypeExpr(false) )?
       {
-        projectList.add(new Pair<List<String>, IndexedTypeExpression>(path, type));
+        projectList.add(new Pair<List<String>, IndexedTypeExpression>(path.first, type));
       }
       ( <COMMA> path = MultipartIdentifier() ( <COLON> type = IndexedTypeExpr(false) )?
         {
-          projectList.add(new Pair<List<String>, IndexedTypeExpression>(path, type));
+          projectList.add(new Pair<List<String>, IndexedTypeExpression>(path.first, type));
         }
       )*
     )
@@ -1225,13 +1245,13 @@
 
 Pair<List<String>, IndexedTypeExpression> IndexedField() throws ParseException:
 {
-  List<String> path = null;
+  Triple<List<String>, Token, Token> path = null;
   IndexedTypeExpression type = null;
 }
 {
   path = MultipartIdentifier() ( <COLON> type = IndexedTypeExpr(true) )?
   {
-    return new Pair<List<String>, IndexedTypeExpression>(path, type);
+    return new Pair<List<String>, IndexedTypeExpression>(path.first, type);
   }
 }
 
@@ -1320,13 +1340,13 @@
 
 CreateDataverseStatement DataverseSpecification(Token startStmtToken) throws ParseException :
 {
-  List<String> dvName = null;
+  DataverseName dvName = null;
   boolean ifNotExists = false;
 }
 {
-  dvName = MultipartIdentifier() ifNotExists = IfNotExists()
+  dvName = DataverseName() ifNotExists = IfNotExists()
   {
-    CreateDataverseStatement stmt = new CreateDataverseStatement(DataverseName.create(dvName), null, ifNotExists);
+    CreateDataverseStatement stmt = new CreateDataverseStatement(dvName, null, ifNotExists);
     return addSourceLocation(stmt, startStmtToken);
   }
 }
@@ -1991,13 +2011,13 @@
 
 DataverseDropStatement DropDataverseSpecification(Token startStmtToken) throws ParseException:
 {
-  List<String> multipartId = null;
+  DataverseName dvName = null;
   boolean ifExists = false;
 }
 {
-  multipartId = MultipartIdentifier() ifExists = IfExists()
+  dvName = DataverseName() ifExists = IfExists()
   {
-    DataverseDropStatement stmt = new DataverseDropStatement(DataverseName.create(multipartId), ifExists);
+    DataverseDropStatement stmt = new DataverseDropStatement(dvName, ifExists);
     return addSourceLocation(stmt, startStmtToken);
   }
 }
@@ -2690,7 +2710,7 @@
 
 FunctionName FunctionName() throws ParseException:
 {
-  Triple<List<String>, SourceLocation, Token> prefix = null;
+  Triple<List<String>, Token, Token> prefix = null;
   String suffix = null;
 }
 {
@@ -2702,8 +2722,9 @@
   )
   (<SHARP> suffix = Identifier())?
   {
+    Token startToken = prefix.second;
     FunctionName result = new FunctionName();
-    result.sourceLoc = prefix.second;
+    result.sourceLoc = getSourceLocation(startToken);
     result.hintToken = prefix.third;
     List<String> list = prefix.first;
     int ln = list.size();
@@ -2719,7 +2740,7 @@
       result.function = suffix;
     }
     if (ln > 1) {
-      result.dataverse = DataverseName.create(list, 0, ln - 1);
+      result.dataverse = createDataverseName(list, 0, ln - 1, startToken);
     } else {
       result.dataverse = defaultDataverse;
     }
@@ -2861,49 +2882,64 @@
     }
 }
 
-List<String> MultipartIdentifier() throws ParseException:
+Triple<List<String>, Token, Token> MultipartIdentifier() throws ParseException:
 {
-  Triple<List<String>, SourceLocation, Token> result = null;
+  Triple<List<String>, Token, Token> result = null;
 }
 {
   result = MultipartIdentifierWithHints(null)
   {
-    return result.first;
+    return result;
   }
 }
 
-Triple<List<String>, SourceLocation, Token> MultipartIdentifierWithHints(SqlppHint... expectedHints)
+Triple<List<String>, Token, Token> MultipartIdentifierWithHints(SqlppHint... expectedHints)
   throws ParseException:
 {
   List<String> list = new ArrayList<String>();
   SourceLocation sourceLoc = null;
-  Token hint = null;
+  Token startToken, hintToken = null;
   String item = null;
 }
 {
   item = Identifier()
   {
     list.add(item);
-    sourceLoc = getSourceLocation(token);
+    startToken = token;
     if (expectedHints != null && expectedHints.length > 0) {
-      hint = fetchHint(token, expectedHints);
+      hintToken = fetchHint(token, expectedHints);
     }
   }
   (<DOT> item = Identifier() { list.add(item); } )*
   {
-    return new Triple<List<String>, SourceLocation, Token>(list, sourceLoc, hint);
+    return new Triple<List<String>, Token, Token>(list, startToken, hintToken);
+  }
+}
+
+DataverseName DataverseName() throws ParseException:
+{
+  Triple<List<String>, Token, Token> ident = null;
+}
+{
+  ident = MultipartIdentifier()
+  {
+    List<String> list = ident.first;
+    Token startToken = ident.second;
+    return createDataverseName(list, 0, list.size(), startToken);
   }
 }
 
 Pair<DataverseName,Identifier> QualifiedName() throws ParseException:
 {
-  List<String> list = null;
+  Triple<List<String>, Token, Token> ident = null;
 }
 {
-  list = MultipartIdentifier()
+  ident = MultipartIdentifier()
   {
+    List<String> list = ident.first;
+    Token startToken = ident.second;
     int len = list.size();
-    DataverseName id1 = len > 1 ? DataverseName.create(list, 0, len - 1) : null;
+    DataverseName id1 = len > 1 ? createDataverseName(list, 0, len - 1, startToken) : null;
     Identifier id2 = new Identifier(list.get(len - 1));
     return new Pair<DataverseName,Identifier>(id1, id2);
   }
@@ -2913,13 +2949,14 @@
 {
   List<String> list = new ArrayList<String>();
   String item = null;
+  Token startToken = null;
 }
 {
-  item = Identifier() { list.add(item); }
+  item = Identifier() { list.add(item); startToken = token; }
   (<DOT> item = Identifier() { list.add(item); } )+
   {
     int len = list.size();
-    DataverseName id1 = len > 2 ? DataverseName.create(list, 0, len - 2) : null;
+    DataverseName id1 = len > 2 ? createDataverseName(list, 0, len - 2, startToken) : null;
     Identifier id2 = new Identifier(list.get(len - 2));
     Identifier id3 = new Identifier(list.get(len - 1));
     return new Triple<DataverseName,Identifier,Identifier>(id1, id2, id3);
diff --git a/asterixdb/asterix-metadata/src/main/java/org/apache/asterix/metadata/declared/LoadableDataSource.java b/asterixdb/asterix-metadata/src/main/java/org/apache/asterix/metadata/declared/LoadableDataSource.java
index f766da3..79a9d00 100644
--- a/asterixdb/asterix-metadata/src/main/java/org/apache/asterix/metadata/declared/LoadableDataSource.java
+++ b/asterixdb/asterix-metadata/src/main/java/org/apache/asterix/metadata/declared/LoadableDataSource.java
@@ -52,7 +52,7 @@
 
 public class LoadableDataSource extends DataSource {
 
-    private static final DataverseName LOADABLE_DV = DataverseName.createSinglePartName("loadable_dv"); // 1-part name
+    private static final String LOADABLE_DV = "loadable_dv";
     private static final String LOADABLE_DS = "loadable_ds";
 
     private final Dataset targetDataset;
@@ -63,7 +63,8 @@
 
     public LoadableDataSource(Dataset targetDataset, IAType itemType, IAType metaItemType, String adapter,
             Map<String, String> properties) throws AlgebricksException, IOException {
-        super(new DataSourceId(LOADABLE_DV, LOADABLE_DS), itemType, metaItemType, Type.LOADABLE, null);
+        super(new DataSourceId(DataverseName.createSinglePartName(LOADABLE_DV), LOADABLE_DS), itemType, metaItemType,
+                Type.LOADABLE, null);
         this.targetDataset = targetDataset;
         this.adapter = adapter;
         this.adapterProperties = properties;
diff --git a/asterixdb/asterix-metadata/src/main/java/org/apache/asterix/metadata/declared/MetadataProvider.java b/asterixdb/asterix-metadata/src/main/java/org/apache/asterix/metadata/declared/MetadataProvider.java
index 3ab295e..281e59c 100644
--- a/asterixdb/asterix-metadata/src/main/java/org/apache/asterix/metadata/declared/MetadataProvider.java
+++ b/asterixdb/asterix-metadata/src/main/java/org/apache/asterix/metadata/declared/MetadataProvider.java
@@ -1896,7 +1896,7 @@
 
     private void validateDatabaseObjectNameImpl(String name, SourceLocation sourceLoc) throws AlgebricksException {
         if (name == null || name.isEmpty()) {
-            throw new AsterixException(ErrorCode.INVALID_DATABASE_OBJECT_NAME, sourceLoc, "<empty>");
+            throw new AsterixException(ErrorCode.INVALID_DATABASE_OBJECT_NAME, sourceLoc, "");
         }
         if (Character.isWhitespace(name.codePointAt(0)) || METADATA_OBJECT_NAME_INVALID_CHARS.matcher(name).find()) {
             throw new AsterixException(ErrorCode.INVALID_DATABASE_OBJECT_NAME, sourceLoc, name);
diff --git a/asterixdb/asterix-metadata/src/main/java/org/apache/asterix/metadata/entitytupletranslators/CompactionPolicyTupleTranslator.java b/asterixdb/asterix-metadata/src/main/java/org/apache/asterix/metadata/entitytupletranslators/CompactionPolicyTupleTranslator.java
index 1d8e408..0acc91d 100644
--- a/asterixdb/asterix-metadata/src/main/java/org/apache/asterix/metadata/entitytupletranslators/CompactionPolicyTupleTranslator.java
+++ b/asterixdb/asterix-metadata/src/main/java/org/apache/asterix/metadata/entitytupletranslators/CompactionPolicyTupleTranslator.java
@@ -25,6 +25,7 @@
 import org.apache.asterix.metadata.entities.CompactionPolicy;
 import org.apache.asterix.om.base.ARecord;
 import org.apache.asterix.om.base.AString;
+import org.apache.hyracks.algebricks.common.exceptions.AlgebricksException;
 import org.apache.hyracks.api.exceptions.HyracksDataException;
 import org.apache.hyracks.dataflow.common.data.accessors.ITupleReference;
 
@@ -41,7 +42,8 @@
     }
 
     @Override
-    protected CompactionPolicy createMetadataEntityFromARecord(ARecord compactionPolicyRecord) {
+    protected CompactionPolicy createMetadataEntityFromARecord(ARecord compactionPolicyRecord)
+            throws AlgebricksException {
         String dataverseCanonicalName = ((AString) compactionPolicyRecord
                 .getValueByPos(MetadataRecordTypes.COMPACTION_POLICY_ARECORD_DATAVERSE_NAME_FIELD_INDEX))
                         .getStringValue();
diff --git a/asterixdb/asterix-metadata/src/main/java/org/apache/asterix/metadata/entitytupletranslators/DatasetTupleTranslator.java b/asterixdb/asterix-metadata/src/main/java/org/apache/asterix/metadata/entitytupletranslators/DatasetTupleTranslator.java
index e4069c2..19722ef 100644
--- a/asterixdb/asterix-metadata/src/main/java/org/apache/asterix/metadata/entitytupletranslators/DatasetTupleTranslator.java
+++ b/asterixdb/asterix-metadata/src/main/java/org/apache/asterix/metadata/entitytupletranslators/DatasetTupleTranslator.java
@@ -65,6 +65,7 @@
 import org.apache.asterix.om.types.BuiltinType;
 import org.apache.asterix.om.types.IAType;
 import org.apache.asterix.runtime.compression.CompressionManager;
+import org.apache.hyracks.algebricks.common.exceptions.AlgebricksException;
 import org.apache.hyracks.algebricks.common.utils.Pair;
 import org.apache.hyracks.api.exceptions.HyracksDataException;
 import org.apache.hyracks.data.std.util.ArrayBackedValueStorage;
@@ -90,7 +91,7 @@
     }
 
     @Override
-    protected Dataset createMetadataEntityFromARecord(ARecord datasetRecord) {
+    protected Dataset createMetadataEntityFromARecord(ARecord datasetRecord) throws AlgebricksException {
         String dataverseCanonicalName =
                 ((AString) datasetRecord.getValueByPos(MetadataRecordTypes.DATASET_ARECORD_DATAVERSENAME_FIELD_INDEX))
                         .getStringValue();
diff --git a/asterixdb/asterix-metadata/src/main/java/org/apache/asterix/metadata/entitytupletranslators/DatasourceAdapterTupleTranslator.java b/asterixdb/asterix-metadata/src/main/java/org/apache/asterix/metadata/entitytupletranslators/DatasourceAdapterTupleTranslator.java
index 5327b22..5d80796 100644
--- a/asterixdb/asterix-metadata/src/main/java/org/apache/asterix/metadata/entitytupletranslators/DatasourceAdapterTupleTranslator.java
+++ b/asterixdb/asterix-metadata/src/main/java/org/apache/asterix/metadata/entitytupletranslators/DatasourceAdapterTupleTranslator.java
@@ -29,6 +29,7 @@
 import org.apache.asterix.metadata.entities.DatasourceAdapter;
 import org.apache.asterix.om.base.ARecord;
 import org.apache.asterix.om.base.AString;
+import org.apache.hyracks.algebricks.common.exceptions.AlgebricksException;
 import org.apache.hyracks.api.exceptions.HyracksDataException;
 import org.apache.hyracks.dataflow.common.data.accessors.ITupleReference;
 
@@ -42,7 +43,7 @@
     }
 
     @Override
-    protected DatasourceAdapter createMetadataEntityFromARecord(ARecord adapterRecord) {
+    protected DatasourceAdapter createMetadataEntityFromARecord(ARecord adapterRecord) throws AlgebricksException {
         String dataverseCanonicalName = ((AString) adapterRecord
                 .getValueByPos(MetadataRecordTypes.DATASOURCE_ADAPTER_ARECORD_DATAVERSENAME_FIELD_INDEX))
                         .getStringValue();
diff --git a/asterixdb/asterix-metadata/src/main/java/org/apache/asterix/metadata/entitytupletranslators/DataverseTupleTranslator.java b/asterixdb/asterix-metadata/src/main/java/org/apache/asterix/metadata/entitytupletranslators/DataverseTupleTranslator.java
index 10fe6bf..77c838a 100644
--- a/asterixdb/asterix-metadata/src/main/java/org/apache/asterix/metadata/entitytupletranslators/DataverseTupleTranslator.java
+++ b/asterixdb/asterix-metadata/src/main/java/org/apache/asterix/metadata/entitytupletranslators/DataverseTupleTranslator.java
@@ -29,6 +29,7 @@
 import org.apache.asterix.om.base.AMutableInt32;
 import org.apache.asterix.om.base.ARecord;
 import org.apache.asterix.om.base.AString;
+import org.apache.hyracks.algebricks.common.exceptions.AlgebricksException;
 import org.apache.hyracks.api.exceptions.HyracksDataException;
 import org.apache.hyracks.dataflow.common.data.accessors.ITupleReference;
 
@@ -50,7 +51,7 @@
     }
 
     @Override
-    protected Dataverse createMetadataEntityFromARecord(ARecord dataverseRecord) {
+    protected Dataverse createMetadataEntityFromARecord(ARecord dataverseRecord) throws AlgebricksException {
         String dataverseCanonicalName = ((AString) dataverseRecord.getValueByPos(0)).getStringValue();
         DataverseName dataverseName = DataverseName.createFromCanonicalForm(dataverseCanonicalName);
         String format = ((AString) dataverseRecord.getValueByPos(1)).getStringValue();
diff --git a/asterixdb/asterix-metadata/src/main/java/org/apache/asterix/metadata/entitytupletranslators/ExternalFileTupleTranslator.java b/asterixdb/asterix-metadata/src/main/java/org/apache/asterix/metadata/entitytupletranslators/ExternalFileTupleTranslator.java
index abf3719..8c3cacf 100644
--- a/asterixdb/asterix-metadata/src/main/java/org/apache/asterix/metadata/entitytupletranslators/ExternalFileTupleTranslator.java
+++ b/asterixdb/asterix-metadata/src/main/java/org/apache/asterix/metadata/entitytupletranslators/ExternalFileTupleTranslator.java
@@ -35,6 +35,7 @@
 import org.apache.asterix.om.base.ARecord;
 import org.apache.asterix.om.base.AString;
 import org.apache.asterix.om.types.BuiltinType;
+import org.apache.hyracks.algebricks.common.exceptions.AlgebricksException;
 import org.apache.hyracks.api.dataflow.value.ISerializerDeserializer;
 import org.apache.hyracks.api.exceptions.HyracksDataException;
 import org.apache.hyracks.dataflow.common.data.accessors.ITupleReference;
@@ -61,7 +62,7 @@
     }
 
     @Override
-    protected ExternalFile createMetadataEntityFromARecord(ARecord externalFileRecord) {
+    protected ExternalFile createMetadataEntityFromARecord(ARecord externalFileRecord) throws AlgebricksException {
         String dataverseCanonicalName = ((AString) externalFileRecord
                 .getValueByPos(MetadataRecordTypes.EXTERNAL_FILE_ARECORD_DATAVERSENAME_FIELD_INDEX)).getStringValue();
         DataverseName dataverseName = DataverseName.createFromCanonicalForm(dataverseCanonicalName);
diff --git a/asterixdb/asterix-metadata/src/main/java/org/apache/asterix/metadata/entitytupletranslators/FeedConnectionTupleTranslator.java b/asterixdb/asterix-metadata/src/main/java/org/apache/asterix/metadata/entitytupletranslators/FeedConnectionTupleTranslator.java
index a976e10..11b4cea 100644
--- a/asterixdb/asterix-metadata/src/main/java/org/apache/asterix/metadata/entitytupletranslators/FeedConnectionTupleTranslator.java
+++ b/asterixdb/asterix-metadata/src/main/java/org/apache/asterix/metadata/entitytupletranslators/FeedConnectionTupleTranslator.java
@@ -36,6 +36,7 @@
 import org.apache.asterix.om.base.AUnorderedList;
 import org.apache.asterix.om.base.IACursor;
 import org.apache.asterix.om.types.AUnorderedListType;
+import org.apache.hyracks.algebricks.common.exceptions.AlgebricksException;
 import org.apache.hyracks.api.exceptions.HyracksDataException;
 import org.apache.hyracks.data.std.util.ArrayBackedValueStorage;
 import org.apache.hyracks.dataflow.common.data.accessors.ITupleReference;
@@ -50,7 +51,7 @@
     }
 
     @Override
-    protected FeedConnection createMetadataEntityFromARecord(ARecord feedConnectionRecord) {
+    protected FeedConnection createMetadataEntityFromARecord(ARecord feedConnectionRecord) throws AlgebricksException {
         String dataverseCanonicalName =
                 ((AString) feedConnectionRecord.getValueByPos(MetadataRecordTypes.FEED_CONN_DATAVERSE_NAME_FIELD_INDEX))
                         .getStringValue();
diff --git a/asterixdb/asterix-metadata/src/main/java/org/apache/asterix/metadata/entitytupletranslators/FeedPolicyTupleTranslator.java b/asterixdb/asterix-metadata/src/main/java/org/apache/asterix/metadata/entitytupletranslators/FeedPolicyTupleTranslator.java
index 2407d22..9ffe5dc 100644
--- a/asterixdb/asterix-metadata/src/main/java/org/apache/asterix/metadata/entitytupletranslators/FeedPolicyTupleTranslator.java
+++ b/asterixdb/asterix-metadata/src/main/java/org/apache/asterix/metadata/entitytupletranslators/FeedPolicyTupleTranslator.java
@@ -36,6 +36,7 @@
 import org.apache.asterix.om.base.AUnorderedList;
 import org.apache.asterix.om.base.IACursor;
 import org.apache.asterix.om.types.AUnorderedListType;
+import org.apache.hyracks.algebricks.common.exceptions.AlgebricksException;
 import org.apache.hyracks.api.exceptions.HyracksDataException;
 import org.apache.hyracks.data.std.util.ArrayBackedValueStorage;
 import org.apache.hyracks.dataflow.common.data.accessors.ITupleReference;
@@ -53,7 +54,7 @@
     }
 
     @Override
-    protected FeedPolicyEntity createMetadataEntityFromARecord(ARecord feedPolicyRecord) {
+    protected FeedPolicyEntity createMetadataEntityFromARecord(ARecord feedPolicyRecord) throws AlgebricksException {
         String dataverseCanonicalName = ((AString) feedPolicyRecord
                 .getValueByPos(MetadataRecordTypes.FEED_POLICY_ARECORD_DATAVERSE_NAME_FIELD_INDEX)).getStringValue();
         DataverseName dataverseName = DataverseName.createFromCanonicalForm(dataverseCanonicalName);
diff --git a/asterixdb/asterix-metadata/src/main/java/org/apache/asterix/metadata/entitytupletranslators/FeedTupleTranslator.java b/asterixdb/asterix-metadata/src/main/java/org/apache/asterix/metadata/entitytupletranslators/FeedTupleTranslator.java
index 77a3c92..8834522 100644
--- a/asterixdb/asterix-metadata/src/main/java/org/apache/asterix/metadata/entitytupletranslators/FeedTupleTranslator.java
+++ b/asterixdb/asterix-metadata/src/main/java/org/apache/asterix/metadata/entitytupletranslators/FeedTupleTranslator.java
@@ -37,6 +37,7 @@
 import org.apache.asterix.om.base.AUnorderedList;
 import org.apache.asterix.om.base.IACursor;
 import org.apache.asterix.om.types.AUnorderedListType;
+import org.apache.hyracks.algebricks.common.exceptions.AlgebricksException;
 import org.apache.hyracks.api.exceptions.HyracksDataException;
 import org.apache.hyracks.data.std.util.ArrayBackedValueStorage;
 import org.apache.hyracks.dataflow.common.data.accessors.ITupleReference;
@@ -54,7 +55,7 @@
     }
 
     @Override
-    protected Feed createMetadataEntityFromARecord(ARecord feedRecord) {
+    protected Feed createMetadataEntityFromARecord(ARecord feedRecord) throws AlgebricksException {
         String dataverseCanonicalName =
                 ((AString) feedRecord.getValueByPos(MetadataRecordTypes.FEED_ARECORD_DATAVERSE_NAME_FIELD_INDEX))
                         .getStringValue();
diff --git a/asterixdb/asterix-metadata/src/main/java/org/apache/asterix/metadata/entitytupletranslators/FullTextFilterMetadataEntityTupleTranslator.java b/asterixdb/asterix-metadata/src/main/java/org/apache/asterix/metadata/entitytupletranslators/FullTextFilterMetadataEntityTupleTranslator.java
index 4845310..2212e82 100644
--- a/asterixdb/asterix-metadata/src/main/java/org/apache/asterix/metadata/entitytupletranslators/FullTextFilterMetadataEntityTupleTranslator.java
+++ b/asterixdb/asterix-metadata/src/main/java/org/apache/asterix/metadata/entitytupletranslators/FullTextFilterMetadataEntityTupleTranslator.java
@@ -89,7 +89,7 @@
     }
 
     public FullTextFilterMetadataEntity createStopwordsFilterDescriptorFromARecord(AString dataverseName, AString name,
-            ARecord aRecord) {
+            ARecord aRecord) throws AlgebricksException {
         ImmutableList.Builder<String> stopwordsBuilder = ImmutableList.<String> builder();
         IACursor stopwordsCursor = ((AOrderedList) (aRecord
                 .getValueByPos(MetadataRecordTypes.FULLTEXT_ENTITY_ARECORD_STOPWORD_LIST_FIELD_INDEX))).getCursor();
diff --git a/asterixdb/asterix-metadata/src/main/java/org/apache/asterix/metadata/entitytupletranslators/FunctionTupleTranslator.java b/asterixdb/asterix-metadata/src/main/java/org/apache/asterix/metadata/entitytupletranslators/FunctionTupleTranslator.java
index 81c654b2..ccae8a4 100644
--- a/asterixdb/asterix-metadata/src/main/java/org/apache/asterix/metadata/entitytupletranslators/FunctionTupleTranslator.java
+++ b/asterixdb/asterix-metadata/src/main/java/org/apache/asterix/metadata/entitytupletranslators/FunctionTupleTranslator.java
@@ -198,7 +198,7 @@
     }
 
     private List<TypeSignature> getParamTypes(ARecord functionRecord, DataverseName functionDataverseName)
-            throws AsterixException {
+            throws AlgebricksException {
         ARecordType functionRecordType = functionRecord.getType();
         int paramTypesFieldIdx = functionRecordType.getFieldIndex(FUNCTION_ARECORD_FUNCTION_PARAMTYPES_FIELD_NAME);
         if (paramTypesFieldIdx < 0) {
@@ -230,7 +230,7 @@
     }
 
     private TypeSignature getTypeSignature(String typeName, String typeDataverseNameCanonical,
-            DataverseName functionDataverseName) {
+            DataverseName functionDataverseName) throws AlgebricksException {
         // back-compat: handle "any"
         if (BuiltinType.ANY.getTypeName().equals(typeName)) {
             return null; // == any
@@ -244,7 +244,8 @@
         return new TypeSignature(typeDataverseName, typeName);
     }
 
-    private Triple<DataverseName, String, String> getDependency(AOrderedList dependencySubnames) {
+    private Triple<DataverseName, String, String> getDependency(AOrderedList dependencySubnames)
+            throws AlgebricksException {
         String dataverseCanonicalName = ((AString) dependencySubnames.getItem(0)).getStringValue();
         DataverseName dataverseName = DataverseName.createFromCanonicalForm(dataverseCanonicalName);
         String second = null, third = null;
diff --git a/asterixdb/asterix-metadata/src/main/java/org/apache/asterix/metadata/entitytupletranslators/LibraryTupleTranslator.java b/asterixdb/asterix-metadata/src/main/java/org/apache/asterix/metadata/entitytupletranslators/LibraryTupleTranslator.java
index 03abec8..e3e879b 100644
--- a/asterixdb/asterix-metadata/src/main/java/org/apache/asterix/metadata/entitytupletranslators/LibraryTupleTranslator.java
+++ b/asterixdb/asterix-metadata/src/main/java/org/apache/asterix/metadata/entitytupletranslators/LibraryTupleTranslator.java
@@ -35,6 +35,7 @@
 import org.apache.asterix.om.base.ARecord;
 import org.apache.asterix.om.base.AString;
 import org.apache.asterix.om.types.ARecordType;
+import org.apache.hyracks.algebricks.common.exceptions.AlgebricksException;
 import org.apache.hyracks.api.exceptions.HyracksDataException;
 import org.apache.hyracks.dataflow.common.data.accessors.ITupleReference;
 
@@ -51,7 +52,7 @@
     }
 
     @Override
-    protected Library createMetadataEntityFromARecord(ARecord libraryRecord) {
+    protected Library createMetadataEntityFromARecord(ARecord libraryRecord) throws AlgebricksException {
         String dataverseCanonicalName =
                 ((AString) libraryRecord.getValueByPos(MetadataRecordTypes.LIBRARY_ARECORD_DATAVERSENAME_FIELD_INDEX))
                         .getStringValue();
diff --git a/asterixdb/asterix-metadata/src/main/java/org/apache/asterix/metadata/entitytupletranslators/SynonymTupleTranslator.java b/asterixdb/asterix-metadata/src/main/java/org/apache/asterix/metadata/entitytupletranslators/SynonymTupleTranslator.java
index 4a282c3..6bad2d4 100644
--- a/asterixdb/asterix-metadata/src/main/java/org/apache/asterix/metadata/entitytupletranslators/SynonymTupleTranslator.java
+++ b/asterixdb/asterix-metadata/src/main/java/org/apache/asterix/metadata/entitytupletranslators/SynonymTupleTranslator.java
@@ -25,6 +25,7 @@
 import org.apache.asterix.metadata.entities.Synonym;
 import org.apache.asterix.om.base.ARecord;
 import org.apache.asterix.om.base.AString;
+import org.apache.hyracks.algebricks.common.exceptions.AlgebricksException;
 import org.apache.hyracks.api.exceptions.HyracksDataException;
 import org.apache.hyracks.dataflow.common.data.accessors.ITupleReference;
 
@@ -42,7 +43,7 @@
     }
 
     @Override
-    protected Synonym createMetadataEntityFromARecord(ARecord synonymRecord) {
+    protected Synonym createMetadataEntityFromARecord(ARecord synonymRecord) throws AlgebricksException {
         String dataverseCanonicalName =
                 ((AString) synonymRecord.getValueByPos(MetadataRecordTypes.SYNONYM_ARECORD_DATAVERSENAME_FIELD_INDEX))
                         .getStringValue();
diff --git a/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/DecodeDataverseDisplayNameDescriptor.java b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/DecodeDataverseDisplayNameDescriptor.java
index ddf6ecd..fd78b72 100644
--- a/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/DecodeDataverseDisplayNameDescriptor.java
+++ b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/DecodeDataverseDisplayNameDescriptor.java
@@ -22,6 +22,7 @@
 import java.io.IOException;
 
 import org.apache.asterix.common.annotations.MissingNullInOutFunction;
+import org.apache.asterix.common.exceptions.AsterixException;
 import org.apache.asterix.common.metadata.DataverseName;
 import org.apache.asterix.om.functions.BuiltinFunctions;
 import org.apache.asterix.om.functions.IFunctionDescriptorFactory;
@@ -56,12 +57,25 @@
                         String dataverseCanonicalName = inputString.toString();
 
                         sb.setLength(0);
-                        DataverseName.getDisplayFormFromCanonicalForm(dataverseCanonicalName, sb);
+                        try {
+                            DataverseName.getDisplayFormFromCanonicalForm(dataverseCanonicalName, sb);
+                        } catch (AsterixException e) {
+                            return; // writeResult() will emit NULL
+                        }
 
                         resultBuilder.reset(resultArray, inputString.getUTF8Length());
                         resultBuilder.appendString(sb);
                         resultBuilder.finish();
                     }
+
+                    @Override
+                    void writeResult(IPointable resultPointable) throws IOException {
+                        if (sb.length() == 0) {
+                            PointableHelper.setNull(resultPointable);
+                        } else {
+                            super.writeResult(resultPointable);
+                        }
+                    }
                 };
             }
         };
diff --git a/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/DecodeDataverseNameDescriptor.java b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/DecodeDataverseNameDescriptor.java
index fbbe5c5..530fe4a 100644
--- a/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/DecodeDataverseNameDescriptor.java
+++ b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/DecodeDataverseNameDescriptor.java
@@ -25,6 +25,7 @@
 
 import org.apache.asterix.builders.OrderedListBuilder;
 import org.apache.asterix.common.annotations.MissingNullInOutFunction;
+import org.apache.asterix.common.exceptions.AsterixException;
 import org.apache.asterix.common.metadata.DataverseName;
 import org.apache.asterix.formats.nontagged.SerializerDeserializerProvider;
 import org.apache.asterix.om.base.AMutableString;
@@ -101,8 +102,13 @@
                         strPtr.set(bytes, offset + 1, len - 1);
                         String dataverseCanonicalName = strPtr.toString();
 
-                        dataverseNameParts.clear();
-                        DataverseName.getPartsFromCanonicalForm(dataverseCanonicalName, dataverseNameParts);
+                        try {
+                            dataverseNameParts.clear();
+                            DataverseName.getPartsFromCanonicalForm(dataverseCanonicalName, dataverseNameParts);
+                        } catch (AsterixException e) {
+                            PointableHelper.setNull(result);
+                            return;
+                        }
 
                         resultStorage.reset();
                         listBuilder.reset(listType);