[ASTERIXDB-3259][MTD] Validate database names

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

Details:
Validate database names such that only letters, digits,
'_' and '-' characters are allowed.

- Ensure reserved database names are not allowed:
  'asterix', 'algebricks', 'Metadata'.
- Ensure database names don't start with 'partition_'.

- When database is used, validate that the dataverse is
only 1 part.

Change-Id: I27ac40e18f8ec63c09317cbc573abd6fc2b94e39
Reviewed-on: https://asterix-gerrit.ics.uci.edu/c/asterixdb/+/17872
Reviewed-by: Ali Alsuliman <ali.al.solaiman@gmail.com>
Reviewed-by: Murtadha Hubail <mhubail@apache.org>
Integration-Tests: Jenkins <jenkins@fulliautomatix.ics.uci.edu>
Tested-by: Ali Alsuliman <ali.al.solaiman@gmail.com>
diff --git a/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/translator/AbstractLangTranslator.java b/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/translator/AbstractLangTranslator.java
index 0a0685d..e7e1514 100644
--- a/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/translator/AbstractLangTranslator.java
+++ b/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/translator/AbstractLangTranslator.java
@@ -20,6 +20,7 @@
 
 import static org.apache.asterix.common.utils.IdentifierUtil.dataset;
 import static org.apache.asterix.common.utils.IdentifierUtil.dataverse;
+import static org.apache.hyracks.api.exceptions.ErrorCode.TIMEOUT;
 
 import java.util.Arrays;
 import java.util.HashSet;
@@ -41,6 +42,7 @@
 import org.apache.asterix.common.metadata.DataverseName;
 import org.apache.asterix.common.metadata.MetadataConstants;
 import org.apache.asterix.common.metadata.Namespace;
+import org.apache.asterix.common.utils.StorageConstants;
 import org.apache.asterix.lang.common.base.Statement;
 import org.apache.asterix.lang.common.statement.AnalyzeDropStatement;
 import org.apache.asterix.lang.common.statement.AnalyzeStatement;
@@ -68,6 +70,7 @@
 import org.apache.commons.lang3.StringUtils;
 import org.apache.hyracks.algebricks.common.exceptions.AlgebricksException;
 import org.apache.hyracks.algebricks.common.utils.Pair;
+import org.apache.hyracks.algebricks.core.algebra.functions.AlgebricksBuiltinFunctions;
 import org.apache.hyracks.api.exceptions.HyracksDataException;
 import org.apache.logging.log4j.LogManager;
 import org.apache.logging.log4j.Logger;
@@ -100,7 +103,7 @@
             try {
                 clusterStateManager.waitForState(ClusterState.ACTIVE, maxWaitCycles, TimeUnit.SECONDS);
             } catch (HyracksDataException e) {
-                throw new AsterixException(e);
+                throw new AlgebricksException(e, TIMEOUT);
             } catch (InterruptedException e) {
                 if (LOGGER.isWarnEnabled()) {
                     LOGGER.warn("Thread interrupted while waiting for cluster to be " + ClusterState.ACTIVE);
@@ -197,7 +200,7 @@
             case CREATE_DATABASE: {
                 CreateDatabaseStatement dbCreateStmt = (CreateDatabaseStatement) stmt;
                 String dbName = dbCreateStmt.getDatabaseName().getValue();
-                invalidOperation = isSystemDatabase(dbName) || isDefaultDatabase(dbName);
+                invalidOperation = isSystemDatabase(dbName) || isDefaultDatabase(dbName) || isReservedDatabase(dbName);
                 if (invalidOperation) {
                     message = String.format("Cannot create database: %s", dbName);
                 }
@@ -457,4 +460,11 @@
     protected static boolean isDefaultDataverse(DataverseName dataverseName) {
         return MetadataConstants.DEFAULT_DATAVERSE_NAME.equals(dataverseName);
     }
+
+    protected static boolean isReservedDatabase(String databaseName) {
+        return FunctionConstants.ASTERIX_DB.equals(databaseName)
+                || AlgebricksBuiltinFunctions.ALGEBRICKS_DB.equals(databaseName)
+                || MetadataConstants.METADATA_DATAVERSE_NAME.getCanonicalForm().equals(databaseName)
+                || databaseName.startsWith(StorageConstants.PARTITION_DIR_PREFIX);
+    }
 }
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 cd76c73..75ff63b 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
@@ -593,7 +593,7 @@
         DataverseDecl dvd = (DataverseDecl) stmt;
         DataverseName dvName = dvd.getDataverseName();
         String database = dvd.getDatabaseName();
-        metadataProvider.validateDataverseName(dvName, dvd.getSourceLocation());
+        metadataProvider.validateNamespaceName(dvd.getNamespace(), dvd.getSourceLocation());
         //TODO(DB): read lock on database
         lockManager.acquireDataverseReadLock(metadataProvider.getLocks(), database, dvName);
         try {
@@ -638,7 +638,7 @@
             IRequestParameters requestParameters) throws Exception {
         CreateDatabaseStatement stmtCreateDatabase = (CreateDatabaseStatement) stmt;
         String database = stmtCreateDatabase.getDatabaseName().getValue();
-        //TODO(DB): validate names
+        metadataProvider.validateDatabaseName(database, stmt.getSourceLocation());
         if (isCompileOnly()) {
             return;
         }
@@ -681,7 +681,8 @@
         CreateDataverseStatement stmtCreateDataverse = (CreateDataverseStatement) stmt;
         DataverseName dvName = stmtCreateDataverse.getDataverseName();
         String dbName = stmtCreateDataverse.getDatabaseName();
-        metadataProvider.validateDataverseName(dvName, stmtCreateDataverse.getSourceLocation());
+        Namespace stmtNamespace = stmtCreateDataverse.getNamespace();
+        metadataProvider.validateNamespaceName(stmtNamespace, stmtCreateDataverse.getSourceLocation());
         if (isCompileOnly()) {
             return;
         }
@@ -769,7 +770,7 @@
             IHyracksClientConnection hcc, IRequestParameters requestParameters) throws Exception {
         DatasetDecl dd = (DatasetDecl) stmt;
         String datasetName = dd.getName().getValue();
-        metadataProvider.validateDatabaseObjectName(dd.getDataverse(), datasetName, stmt.getSourceLocation());
+        metadataProvider.validateDatabaseObjectName(dd.getNamespace(), datasetName, stmt.getSourceLocation());
         Namespace stmtActiveNamespace = getActiveNamespace(dd.getNamespace());
         DataverseName dataverseName = stmtActiveNamespace.getDataverseName();
         String databaseName = stmtActiveNamespace.getDatabaseName();
@@ -1212,7 +1213,7 @@
         String datasetName = stmtCreateIndex.getDatasetName().getValue();
         String indexName = stmtCreateIndex.getIndexName().getValue();
         String fullTextConfigName = stmtCreateIndex.getFullTextConfigName();
-        metadataProvider.validateDatabaseObjectName(stmtCreateIndex.getDataverseName(), indexName,
+        metadataProvider.validateDatabaseObjectName(stmtCreateIndex.getNamespace(), indexName,
                 stmt.getSourceLocation());
         Namespace stmtActiveNamespace = getActiveNamespace(stmtCreateIndex.getNamespace());
         DataverseName dataverseName = stmtActiveNamespace.getDataverseName();
@@ -1568,7 +1569,7 @@
             throws Exception {
         CreateFullTextFilterStatement stmtCreateFilter = (CreateFullTextFilterStatement) stmt;
         String fullTextFilterName = stmtCreateFilter.getFilterName();
-        metadataProvider.validateDatabaseObjectName(stmtCreateFilter.getDataverseName(), fullTextFilterName,
+        metadataProvider.validateDatabaseObjectName(stmtCreateFilter.getNamespace(), fullTextFilterName,
                 stmt.getSourceLocation());
         Namespace stmtActiveNamespace = getActiveNamespace(stmtCreateFilter.getNamespace());
         DataverseName dataverseName = stmtActiveNamespace.getDataverseName();
@@ -1637,7 +1638,7 @@
             throws Exception {
         CreateFullTextConfigStatement stmtCreateConfig = (CreateFullTextConfigStatement) stmt;
         String configName = stmtCreateConfig.getConfigName();
-        metadataProvider.validateDatabaseObjectName(stmtCreateConfig.getDataverseName(), configName,
+        metadataProvider.validateDatabaseObjectName(stmtCreateConfig.getNamespace(), configName,
                 stmt.getSourceLocation());
         Namespace stmtActiveNamespace = getActiveNamespace(stmtCreateConfig.getNamespace());
         DataverseName dataverseName = stmtActiveNamespace.getDataverseName();
@@ -1882,7 +1883,7 @@
         TypeDecl stmtCreateType = (TypeDecl) stmt;
         SourceLocation sourceLoc = stmtCreateType.getSourceLocation();
         String typeName = stmtCreateType.getIdent().getValue();
-        metadataProvider.validateDatabaseObjectName(stmtCreateType.getDataverseName(), typeName, sourceLoc);
+        metadataProvider.validateDatabaseObjectName(stmtCreateType.getNamespace(), typeName, sourceLoc);
         Namespace stmtActiveNamespace = getActiveNamespace(stmtCreateType.getNamespace());
         DataverseName dataverseName = stmtActiveNamespace.getDataverseName();
         String databaseName = stmtActiveNamespace.getDatabaseName();
@@ -1938,7 +1939,7 @@
         DatabaseDropStatement stmtDropDatabase = (DatabaseDropStatement) stmt;
         SourceLocation sourceLoc = stmtDropDatabase.getSourceLocation();
         String databaseName = stmtDropDatabase.getDatabaseName().getValue();
-        //TODO(DB): validate names
+        metadataProvider.validateDatabaseName(databaseName, sourceLoc);
 
         if (isSystemDatabase(databaseName) || isDefaultDatabase(databaseName)) {
             throw new CompilationException(ErrorCode.COMPILATION_ERROR, sourceLoc,
@@ -2062,9 +2063,8 @@
         SourceLocation sourceLoc = stmtDropDataverse.getSourceLocation();
         DataverseName dataverseName = stmtDropDataverse.getDataverseName();
         String databaseName = stmtDropDataverse.getDatabaseName();
-        metadataProvider.validateDataverseName(dataverseName, sourceLoc);
-        if (dataverseName.equals(MetadataConstants.DEFAULT_DATAVERSE_NAME)
-                || dataverseName.equals(MetadataConstants.METADATA_DATAVERSE_NAME)) {
+        metadataProvider.validateNamespaceName(stmtDropDataverse.getNamespace(), sourceLoc);
+        if (isDefaultDataverse(dataverseName) || isMetadataDataverse(dataverseName)) {
             throw new CompilationException(ErrorCode.COMPILATION_ERROR, sourceLoc,
                     dataverseName + " " + dataverse() + " can't be dropped");
         }
@@ -2267,7 +2267,7 @@
         DropDatasetStatement stmtDelete = (DropDatasetStatement) stmt;
         SourceLocation sourceLoc = stmtDelete.getSourceLocation();
         String datasetName = stmtDelete.getDatasetName().getValue();
-        metadataProvider.validateDatabaseObjectName(stmtDelete.getDataverseName(), datasetName, sourceLoc);
+        metadataProvider.validateDatabaseObjectName(stmtDelete.getNamespace(), datasetName, sourceLoc);
         Namespace stmtActiveNamespace = getActiveNamespace(stmtDelete.getNamespace());
         DataverseName dataverseName = stmtActiveNamespace.getDataverseName();
         String databaseName = stmtActiveNamespace.getDatabaseName();
@@ -2379,7 +2379,7 @@
     protected void handleIndexDropStatement(MetadataProvider metadataProvider, Statement stmt,
             IHyracksClientConnection hcc, IRequestParameters requestParameters) throws Exception {
         IndexDropStatement stmtIndexDrop = (IndexDropStatement) stmt;
-        metadataProvider.validateDatabaseObjectName(stmtIndexDrop.getDataverseName(),
+        metadataProvider.validateDatabaseObjectName(stmtIndexDrop.getNamespace(),
                 stmtIndexDrop.getIndexName().getValue(), stmtIndexDrop.getSourceLocation());
         Namespace stmtActiveNamespace = getActiveNamespace(stmtIndexDrop.getNamespace());
         DataverseName dataverseName = stmtActiveNamespace.getDataverseName();
@@ -2590,7 +2590,7 @@
         TypeDropStatement stmtTypeDrop = (TypeDropStatement) stmt;
         SourceLocation sourceLoc = stmtTypeDrop.getSourceLocation();
         String typeName = stmtTypeDrop.getTypeName().getValue();
-        metadataProvider.validateDatabaseObjectName(stmtTypeDrop.getDataverseName(), typeName, sourceLoc);
+        metadataProvider.validateDatabaseObjectName(stmtTypeDrop.getNamespace(), typeName, sourceLoc);
         Namespace stmtActiveNamespace = getActiveNamespace(stmtTypeDrop.getNamespace());
         DataverseName dataverseName = stmtActiveNamespace.getDataverseName();
         String databaseName = stmtActiveNamespace.getDatabaseName();
@@ -2666,7 +2666,7 @@
             IStatementRewriter stmtRewriter, IRequestParameters requestParameters) throws Exception {
         CreateViewStatement cvs = (CreateViewStatement) stmt;
         String viewName = cvs.getViewName();
-        metadataProvider.validateDatabaseObjectName(cvs.getDataverseName(), viewName, stmt.getSourceLocation());
+        metadataProvider.validateDatabaseObjectName(cvs.getNamespace(), viewName, stmt.getSourceLocation());
         Namespace stmtActiveNamespace = getActiveNamespace(cvs.getNamespace());
         DataverseName dataverseName = stmtActiveNamespace.getDataverseName();
         String databaseName = stmtActiveNamespace.getDatabaseName();
@@ -2896,7 +2896,7 @@
         ViewDropStatement stmtDrop = (ViewDropStatement) stmt;
         SourceLocation sourceLoc = stmtDrop.getSourceLocation();
         String viewName = stmtDrop.getViewName().getValue();
-        metadataProvider.validateDatabaseObjectName(stmtDrop.getDataverseName(), viewName, sourceLoc);
+        metadataProvider.validateDatabaseObjectName(stmtDrop.getNamespace(), viewName, sourceLoc);
         Namespace stmtActiveNamespace = getActiveNamespace(stmtDrop.getNamespace());
         DataverseName dataverseName = stmtActiveNamespace.getDataverseName();
         String databaseName = stmtActiveNamespace.getDatabaseName();
@@ -2963,7 +2963,8 @@
         FunctionDecl fds = (FunctionDecl) stmt;
         FunctionSignature signature = fds.getSignature();
         DataverseName funDataverse = signature.getDataverseName();
-        metadataProvider.validateDatabaseObjectName(funDataverse, signature.getName(), stmt.getSourceLocation());
+        Namespace funNamespace = signature.getNamespace();
+        metadataProvider.validateDatabaseObjectName(funNamespace, signature.getName(), stmt.getSourceLocation());
         if (funDataverse == null) {
             signature.setDataverseName(activeNamespace.getDatabaseName(), activeNamespace.getDataverseName());
         }
@@ -2975,7 +2976,8 @@
         CreateFunctionStatement cfs = (CreateFunctionStatement) stmt;
         FunctionSignature signature = cfs.getFunctionSignature();
         DataverseName funDataverse = signature.getDataverseName();
-        metadataProvider.validateDatabaseObjectName(funDataverse, signature.getName(), stmt.getSourceLocation());
+        Namespace funNamespace = signature.getNamespace();
+        metadataProvider.validateDatabaseObjectName(funNamespace, signature.getName(), stmt.getSourceLocation());
         DataverseName dataverseName;
         String databaseName;
         if (funDataverse == null) {
@@ -3265,7 +3267,8 @@
         FunctionDropStatement stmtDropFunction = (FunctionDropStatement) stmt;
         FunctionSignature signature = stmtDropFunction.getFunctionSignature();
         DataverseName funDataverse = signature.getDataverseName();
-        metadataProvider.validateDatabaseObjectName(funDataverse, signature.getName(),
+        Namespace funNamespace = signature.getNamespace();
+        metadataProvider.validateDatabaseObjectName(funNamespace, signature.getName(),
                 stmtDropFunction.getSourceLocation());
         DataverseName dataverseName;
         String databaseName;
@@ -3334,7 +3337,7 @@
     protected void handleCreateAdapterStatement(MetadataProvider metadataProvider, Statement stmt) throws Exception {
         CreateAdapterStatement cas = (CreateAdapterStatement) stmt;
         String adapterName = cas.getAdapterName();
-        metadataProvider.validateDatabaseObjectName(cas.getDataverseName(), adapterName, cas.getSourceLocation());
+        metadataProvider.validateDatabaseObjectName(cas.getNamespace(), adapterName, cas.getSourceLocation());
         Namespace stmtActiveNamespace = getActiveNamespace(cas.getNamespace());
         DataverseName dataverseName = stmtActiveNamespace.getDataverseName();
         String databaseName = stmtActiveNamespace.getDatabaseName();
@@ -3421,7 +3424,7 @@
         AdapterDropStatement stmtDropAdapter = (AdapterDropStatement) stmt;
         SourceLocation sourceLoc = stmtDropAdapter.getSourceLocation();
         String adapterName = stmtDropAdapter.getAdapterName();
-        metadataProvider.validateDatabaseObjectName(stmtDropAdapter.getDataverseName(), adapterName, sourceLoc);
+        metadataProvider.validateDatabaseObjectName(stmtDropAdapter.getNamespace(), adapterName, sourceLoc);
         Namespace stmtActiveNamespace = getActiveNamespace(stmtDropAdapter.getNamespace());
         DataverseName dataverseName = stmtActiveNamespace.getDataverseName();
         String databaseName = stmtActiveNamespace.getDatabaseName();
@@ -3474,8 +3477,7 @@
     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());
+        metadataProvider.validateDatabaseObjectName(cls.getNamespace(), cls.getLibraryName(), cls.getSourceLocation());
         Namespace stmtActiveNamespace = getActiveNamespace(cls.getNamespace());
         DataverseName dataverseName = stmtActiveNamespace.getDataverseName();
         String databaseName = stmtActiveNamespace.getDatabaseName();
@@ -3612,7 +3614,7 @@
             IHyracksClientConnection hcc, IRequestParameters requestParameters) throws Exception {
         LibraryDropStatement stmtDropLibrary = (LibraryDropStatement) stmt;
         String libraryName = stmtDropLibrary.getLibraryName();
-        metadataProvider.validateDatabaseObjectName(stmtDropLibrary.getDataverseName(), libraryName,
+        metadataProvider.validateDatabaseObjectName(stmtDropLibrary.getNamespace(), libraryName,
                 stmtDropLibrary.getSourceLocation());
         Namespace stmtActiveNamespace = getActiveNamespace(stmtDropLibrary.getNamespace());
         DataverseName dataverseName = stmtActiveNamespace.getDataverseName();
@@ -3709,8 +3711,7 @@
 
     protected void handleCreateSynonymStatement(MetadataProvider metadataProvider, Statement stmt) throws Exception {
         CreateSynonymStatement css = (CreateSynonymStatement) stmt;
-        metadataProvider.validateDatabaseObjectName(css.getDataverseName(), css.getSynonymName(),
-                css.getSourceLocation());
+        metadataProvider.validateDatabaseObjectName(css.getNamespace(), css.getSynonymName(), css.getSourceLocation());
         Namespace stmtActiveNamespace = getActiveNamespace(css.getNamespace());
         DataverseName dataverseName = stmtActiveNamespace.getDataverseName();
         String databaseName = stmtActiveNamespace.getDatabaseName();
@@ -3766,7 +3767,7 @@
     protected void handleDropSynonymStatement(MetadataProvider metadataProvider, Statement stmt) throws Exception {
         SynonymDropStatement stmtSynDrop = (SynonymDropStatement) stmt;
         String synonymName = stmtSynDrop.getSynonymName();
-        metadataProvider.validateDatabaseObjectName(stmtSynDrop.getDataverseName(), synonymName,
+        metadataProvider.validateDatabaseObjectName(stmtSynDrop.getNamespace(), synonymName,
                 stmtSynDrop.getSourceLocation());
         Namespace stmtActiveNamespace = getActiveNamespace(stmtSynDrop.getNamespace());
         DataverseName dataverseName = stmtActiveNamespace.getDataverseName();
@@ -3808,8 +3809,7 @@
             throws Exception {
         LoadStatement loadStmt = (LoadStatement) stmt;
         String datasetName = loadStmt.getDatasetName();
-        metadataProvider.validateDatabaseObjectName(loadStmt.getDataverseName(), datasetName,
-                loadStmt.getSourceLocation());
+        metadataProvider.validateDatabaseObjectName(loadStmt.getNamespace(), datasetName, loadStmt.getSourceLocation());
         Namespace stmtActiveNamespace = getActiveNamespace(loadStmt.getNamespace());
         DataverseName dataverseName = stmtActiveNamespace.getDataverseName();
         String databaseName = stmtActiveNamespace.getDatabaseName();
@@ -3852,8 +3852,7 @@
             throws Exception {
         CopyStatement copyStmt = (CopyStatement) stmt;
         String datasetName = copyStmt.getDatasetName();
-        metadataProvider.validateDatabaseObjectName(copyStmt.getDataverseName(), datasetName,
-                copyStmt.getSourceLocation());
+        metadataProvider.validateDatabaseObjectName(copyStmt.getNamespace(), datasetName, copyStmt.getSourceLocation());
         Namespace stmtActiveNamespace = getActiveNamespace(copyStmt.getNamespace());
         DataverseName dataverseName = stmtActiveNamespace.getDataverseName();
         String databaseName = stmtActiveNamespace.getDatabaseName();
@@ -3947,7 +3946,7 @@
             Map<String, IAObject> stmtParams, IStatementRewriter stmtRewriter) throws Exception {
         InsertStatement stmtInsertUpsert = (InsertStatement) stmt;
         String datasetName = stmtInsertUpsert.getDatasetName();
-        metadataProvider.validateDatabaseObjectName(stmtInsertUpsert.getDataverseName(), datasetName,
+        metadataProvider.validateDatabaseObjectName(stmtInsertUpsert.getNamespace(), datasetName,
                 stmtInsertUpsert.getSourceLocation());
         Namespace stmtActiveNamespace = getActiveNamespace(stmtInsertUpsert.getNamespace());
         DataverseName dataverseName = stmtActiveNamespace.getDataverseName();
@@ -4037,8 +4036,7 @@
             throws Exception {
         DeleteStatement stmtDelete = (DeleteStatement) stmt;
         String datasetName = stmtDelete.getDatasetName();
-        metadataProvider.validateDatabaseObjectName(stmtDelete.getDataverseName(), datasetName,
-                stmt.getSourceLocation());
+        metadataProvider.validateDatabaseObjectName(stmtDelete.getNamespace(), datasetName, stmt.getSourceLocation());
         Namespace stmtActiveNamespace = getActiveNamespace(stmtDelete.getNamespace());
         DataverseName dataverseName = stmtActiveNamespace.getDataverseName();
         String databaseName = stmtActiveNamespace.getDatabaseName();
@@ -4168,7 +4166,7 @@
         CreateFeedStatement cfs = (CreateFeedStatement) stmt;
         SourceLocation sourceLoc = cfs.getSourceLocation();
         String feedName = cfs.getFeedName().getValue();
-        metadataProvider.validateDatabaseObjectName(cfs.getDataverseName(), feedName, sourceLoc);
+        metadataProvider.validateDatabaseObjectName(cfs.getNamespace(), feedName, sourceLoc);
         Namespace stmtActiveNamespace = getActiveNamespace(cfs.getNamespace());
         DataverseName dataverseName = stmtActiveNamespace.getDataverseName();
         String databaseName = stmtActiveNamespace.getDatabaseName();
@@ -4282,7 +4280,7 @@
         FeedDropStatement stmtFeedDrop = (FeedDropStatement) stmt;
         SourceLocation sourceLoc = stmtFeedDrop.getSourceLocation();
         String feedName = stmtFeedDrop.getFeedName().getValue();
-        metadataProvider.validateDatabaseObjectName(stmtFeedDrop.getDataverseName(), feedName, sourceLoc);
+        metadataProvider.validateDatabaseObjectName(stmtFeedDrop.getNamespace(), feedName, sourceLoc);
         Namespace stmtActiveNamespace = getActiveNamespace(stmtFeedDrop.getNamespace());
         DataverseName dataverseName = stmtActiveNamespace.getDataverseName();
         String databaseName = stmtActiveNamespace.getDatabaseName();
@@ -4340,7 +4338,7 @@
         FeedPolicyDropStatement stmtFeedPolicyDrop = (FeedPolicyDropStatement) stmt;
         SourceLocation sourceLoc = stmtFeedPolicyDrop.getSourceLocation();
         String policyName = stmtFeedPolicyDrop.getPolicyName().getValue();
-        metadataProvider.validateDatabaseObjectName(stmtFeedPolicyDrop.getDataverseName(), policyName, sourceLoc);
+        metadataProvider.validateDatabaseObjectName(stmtFeedPolicyDrop.getNamespace(), policyName, sourceLoc);
         Namespace stmtActiveNamespace = getActiveNamespace(stmtFeedPolicyDrop.getNamespace());
         DataverseName dataverseName = stmtActiveNamespace.getDataverseName();
         String databaseName = stmtActiveNamespace.getDatabaseName();
@@ -4577,8 +4575,8 @@
     protected void handleAnalyzeStatement(MetadataProvider metadataProvider, Statement stmt,
             IHyracksClientConnection hcc, IRequestParameters requestParameters) throws Exception {
         AnalyzeStatement analyzeStatement = (AnalyzeStatement) stmt;
-        metadataProvider.validateDatabaseObjectName(analyzeStatement.getDataverseName(),
-                analyzeStatement.getDatasetName(), analyzeStatement.getSourceLocation());
+        metadataProvider.validateDatabaseObjectName(analyzeStatement.getNamespace(), analyzeStatement.getDatasetName(),
+                analyzeStatement.getSourceLocation());
         Namespace stmtActiveNamespace = getActiveNamespace(analyzeStatement.getNamespace());
         DataverseName dataverseName = stmtActiveNamespace.getDataverseName();
         String databaseName = stmtActiveNamespace.getDatabaseName();
@@ -4804,8 +4802,8 @@
     protected void handleAnalyzeDropStatement(MetadataProvider metadataProvider, Statement stmt,
             IHyracksClientConnection hcc, IRequestParameters requestParams) throws Exception {
         AnalyzeDropStatement analyzeDropStmt = (AnalyzeDropStatement) stmt;
-        metadataProvider.validateDatabaseObjectName(analyzeDropStmt.getDataverseName(),
-                analyzeDropStmt.getDatasetName(), analyzeDropStmt.getSourceLocation());
+        metadataProvider.validateDatabaseObjectName(analyzeDropStmt.getNamespace(), analyzeDropStmt.getDatasetName(),
+                analyzeDropStmt.getSourceLocation());
         Namespace stmtActiveNamespace = getActiveNamespace(analyzeDropStmt.getNamespace());
         DataverseName dataverseName = stmtActiveNamespace.getDataverseName();
         String databaseName = stmtActiveNamespace.getDatabaseName();
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/cloud_storage/special-chars/test.000.ddl.sqlpp b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/cloud_storage/special-chars/test.000.ddl.sqlpp
index e7c2769..d3915a8 100644
--- a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/cloud_storage/special-chars/test.000.ddl.sqlpp
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/cloud_storage/special-chars/test.000.ddl.sqlpp
@@ -17,10 +17,10 @@
  * under the License.
  */
 
-DROP DATABASE `part1` IF EXISTS;
-CREATE DATABASE `part1`;
-DROP DATAVERSE `part1`.`p%r t2` IF EXISTS;
-CREATE DATAVERSE `part1`.`p%r t2`;
+DROP DATABASE `part_1-` IF EXISTS;
+CREATE DATABASE `part_1-`;
+DROP DATAVERSE `part_1-`.`p_r-t2` IF EXISTS;
+CREATE DATAVERSE `part_1-`.`p_r-t2`;
 
-USE `part1`.`p%r t2`;
+USE `part_1-`.`p_r-t2`;
 CREATE COLLECTION `some@dataset` PRIMARY KEY (id: int);
\ No newline at end of file
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/cloud_storage/special-chars/test.001.update.sqlpp b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/cloud_storage/special-chars/test.001.update.sqlpp
index 3629d7f..15d9bbd 100644
--- a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/cloud_storage/special-chars/test.001.update.sqlpp
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/cloud_storage/special-chars/test.001.update.sqlpp
@@ -17,6 +17,6 @@
  * under the License.
  */
 
-USE `part1`.`p%r t2`;
+USE `part_1-`.`p_r-t2`;
 
 UPSERT INTO `some@dataset` {"id": 1};
\ No newline at end of file
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/cloud_storage/special-chars/test.002.query.sqlpp b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/cloud_storage/special-chars/test.002.query.sqlpp
index ff2ab8f..7019cab 100644
--- a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/cloud_storage/special-chars/test.002.query.sqlpp
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/cloud_storage/special-chars/test.002.query.sqlpp
@@ -17,7 +17,7 @@
  * under the License.
  */
 
-USE `part1`.`p%r t2`;
+USE `part_1-`.`p_r-t2`;
 
 SELECT VALUE COUNT(*)
 FROM `some@dataset`;
\ No newline at end of file
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/cloud_storage/special-chars/test.999.ddl.sqlpp b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/cloud_storage/special-chars/test.999.ddl.sqlpp
index 923c81b..9efd9f7 100644
--- a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/cloud_storage/special-chars/test.999.ddl.sqlpp
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/cloud_storage/special-chars/test.999.ddl.sqlpp
@@ -17,5 +17,5 @@
  * under the License.
  */
 
-DROP DATAVERSE `part1`.`p%r t2` IF EXISTS;
-DROP DATABASE `part1`;
\ No newline at end of file
+DROP DATAVERSE `part_1-`.`p_r-t2` IF EXISTS;
+DROP DATABASE `part_1-`;
\ No newline at end of file
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 94621bf..890890c 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
@@ -23,6 +23,7 @@
 
 import org.apache.asterix.common.exceptions.AsterixException;
 import org.apache.asterix.common.metadata.DataverseName;
+import org.apache.asterix.common.metadata.Namespace;
 import org.apache.hyracks.algebricks.core.algebra.functions.AlgebricksBuiltinFunctions;
 import org.apache.hyracks.algebricks.core.algebra.functions.FunctionIdentifier;
 
@@ -108,6 +109,11 @@
         return dataverseName;
     }
 
+    public Namespace getNamespace() {
+        //TODO(DB): the dataverse name is the driver here. change so that it's similar to other statement
+        return dataverseName == null ? null : new Namespace(databaseName, dataverseName);
+    }
+
     public String getName() {
         return name;
     }
diff --git a/asterixdb/asterix-common/src/main/java/org/apache/asterix/common/metadata/MetadataConstants.java b/asterixdb/asterix-common/src/main/java/org/apache/asterix/common/metadata/MetadataConstants.java
index 044d920..9b1d5ae 100644
--- a/asterixdb/asterix-common/src/main/java/org/apache/asterix/common/metadata/MetadataConstants.java
+++ b/asterixdb/asterix-common/src/main/java/org/apache/asterix/common/metadata/MetadataConstants.java
@@ -28,6 +28,7 @@
  */
 public class MetadataConstants {
 
+    public static final int DB_SCOPE_PARTS_COUNT = 1;
     public static final int METADATA_OBJECT_NAME_LENGTH_LIMIT_UTF8 = 251;
     public static final int DATAVERSE_NAME_TOTAL_LENGTH_LIMIT_UTF8 = METADATA_OBJECT_NAME_LENGTH_LIMIT_UTF8 * 4;
     public static final Pattern METADATA_OBJECT_NAME_INVALID_CHARS =
diff --git a/asterixdb/asterix-lang-common/src/main/java/org/apache/asterix/lang/common/statement/CreateDataverseStatement.java b/asterixdb/asterix-lang-common/src/main/java/org/apache/asterix/lang/common/statement/CreateDataverseStatement.java
index 9b437c2..3579cbe 100644
--- a/asterixdb/asterix-lang-common/src/main/java/org/apache/asterix/lang/common/statement/CreateDataverseStatement.java
+++ b/asterixdb/asterix-lang-common/src/main/java/org/apache/asterix/lang/common/statement/CreateDataverseStatement.java
@@ -40,6 +40,10 @@
         this.ifNotExists = ifNotExists;
     }
 
+    public Namespace getNamespace() {
+        return namespace;
+    }
+
     public String getDatabaseName() {
         return namespace.getDatabaseName();
     }
diff --git a/asterixdb/asterix-lang-common/src/main/java/org/apache/asterix/lang/common/statement/DataverseDropStatement.java b/asterixdb/asterix-lang-common/src/main/java/org/apache/asterix/lang/common/statement/DataverseDropStatement.java
index 14ed0da..b40dc000 100644
--- a/asterixdb/asterix-lang-common/src/main/java/org/apache/asterix/lang/common/statement/DataverseDropStatement.java
+++ b/asterixdb/asterix-lang-common/src/main/java/org/apache/asterix/lang/common/statement/DataverseDropStatement.java
@@ -48,6 +48,10 @@
         return Statement.Kind.DATAVERSE_DROP;
     }
 
+    public Namespace getNamespace() {
+        return namespace;
+    }
+
     public String getDatabaseName() {
         return namespace.getDatabaseName();
     }
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 a5e7f15..fc63d89 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
@@ -1871,14 +1871,29 @@
         return appCtx.getCompressionManager();
     }
 
+    public void validateNamespaceName(Namespace namespace, SourceLocation srcLoc) throws AlgebricksException {
+        validateDatabaseName(namespace.getDatabaseName(), srcLoc);
+        validateDataverseName(namespace.getDataverseName(), srcLoc);
+    }
+
+    public void validateDatabaseName(String databaseName, SourceLocation srcLoc) throws AlgebricksException {
+        validateDatabaseObjectNameImpl(databaseName, srcLoc);
+        validateChars(databaseName, srcLoc);
+    }
+
     public void validateDataverseName(DataverseName dataverseName, SourceLocation sourceLoc)
             throws AlgebricksException {
+        List<String> dvParts = dataverseName.getParts();
+        validatePartsLimit(dataverseName, dvParts, sourceLoc);
         int totalLengthUTF8 = 0;
-        for (String dvNamePart : dataverseName.getParts()) {
+        for (String dvNamePart : dvParts) {
             validateDatabaseObjectNameImpl(dvNamePart, sourceLoc);
             if (totalLengthUTF8 == 0 && StoragePathUtil.DATAVERSE_CONTINUATION_MARKER == dvNamePart.codePointAt(0)) {
                 throw new AsterixException(ErrorCode.INVALID_DATABASE_OBJECT_NAME, sourceLoc, dvNamePart);
             }
+            if (namespaceResolver.isUsingDatabase()) {
+                validateChars(dvNamePart, sourceLoc);
+            }
             totalLengthUTF8 += dvNamePart.getBytes(StandardCharsets.UTF_8).length;
         }
         if (totalLengthUTF8 > MetadataConstants.DATAVERSE_NAME_TOTAL_LENGTH_LIMIT_UTF8) {
@@ -1892,10 +1907,10 @@
         return IndexUtil.createExternalFilterEvaluatorFactory(context, typeEnv, projectionFiltrationInfo, properties);
     }
 
-    public void validateDatabaseObjectName(DataverseName dataverseName, String objectName, SourceLocation sourceLoc)
+    public void validateDatabaseObjectName(Namespace namespace, String objectName, SourceLocation sourceLoc)
             throws AlgebricksException {
-        if (dataverseName != null) {
-            validateDataverseName(dataverseName, sourceLoc);
+        if (namespace != null) {
+            validateNamespaceName(namespace, sourceLoc);
         }
         validateDatabaseObjectNameImpl(objectName, sourceLoc);
     }
@@ -1912,4 +1927,23 @@
             throw new AsterixException(ErrorCode.INVALID_DATABASE_OBJECT_NAME, sourceLoc, name);
         }
     }
+
+    private void validatePartsLimit(DataverseName dvName, List<String> parts, SourceLocation srcLoc)
+            throws AsterixException {
+        if (namespaceResolver.isUsingDatabase() && parts.size() != MetadataConstants.DB_SCOPE_PARTS_COUNT) {
+            throw new AsterixException(ErrorCode.INVALID_DATABASE_OBJECT_NAME, srcLoc, dvName);
+        }
+    }
+
+    private static void validateChars(String name, SourceLocation srcLoc) throws AsterixException {
+        for (int off = 0, len = name.length(); off < len;) {
+            int codePointChar = name.codePointAt(off);
+            if (!Character.isLetterOrDigit(codePointChar)) {
+                if (codePointChar != '_' && codePointChar != '-') {
+                    throw new AsterixException(ErrorCode.INVALID_DATABASE_OBJECT_NAME, srcLoc, name);
+                }
+            }
+            off += Character.charCount(codePointChar);
+        }
+    }
 }