This is an automated email from the ASF dual-hosted git repository.

alsuliman pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/asterixdb.git


The following commit(s) were added to refs/heads/master by this push:
     new 3869f2f913 [ASTERIXDB-3259][MTD] Implement database name resolution
3869f2f913 is described below

commit 3869f2f913b1d940f578229b071573f996a4c6b2
Author: Ali Alsuliman <ali.al.solai...@gmail.com>
AuthorDate: Thu Oct 12 00:00:32 2023 -0700

    [ASTERIXDB-3259][MTD] Implement database name resolution
    
    - user model changes: no
    - storage format changes: no
    - interface changes: yes
    
    Details:
    Currently, qualification to database objects are resolved
    as DataverseName only. That is a multipart identifier is
    resolved as pure DataverseName only and the
    database name is defaulted to 'System'/'Default'.
    
    This patch is to resolve qualification to database objects
    as database_name + dataverse_name + database_object.
    This resolution is only applicable when database is used.
    That is when cloud deployment is used.
    
    Change-Id: Ic3f1d7b2019fcf62e5dcbce8c05a78d18cc0a710
    Reviewed-on: https://asterix-gerrit.ics.uci.edu/c/asterixdb/+/17861
    Reviewed-by: Murtadha Hubail <mhub...@apache.org>
    Integration-Tests: Jenkins <jenk...@fulliautomatix.ics.uci.edu>
    Tested-by: Ali Alsuliman <ali.al.solai...@gmail.com>
---
 .../asterix/app/cc/CcApplicationContext.java       |  9 ++---
 .../apache/asterix/app/nc/NCAppRuntimeContext.java | 11 +++---
 .../asterix/app/translator/QueryTranslator.java    | 28 ++++++++++++--
 .../asterix/hyracks/bootstrap/CCApplication.java   | 20 +++++++---
 .../asterix/hyracks/bootstrap/NCApplication.java   | 19 ++++++---
 .../test/cloud_storage/CloudStorageTest.java       | 18 ++++++++-
 .../apache/asterix/test/common/TestExecutor.java   | 45 ++++++++++++++++++----
 .../request-dataverse.1.ddl.sqlpp                  |  2 +
 .../cloud_storage/special-chars/test.000.ddl.sqlpp |  2 +
 .../cloud_storage/special-chars/test.999.ddl.sqlpp |  1 +
 .../index_1/index_1.1.ddl.sqlpp                    |  2 +
 .../resolution_1/resolution_1.1.ddl.sqlpp          |  2 +
 .../multipart-dataverse/udf_1/udf_1.1.ddl.sqlpp    |  2 +
 .../src/test/resources/runtimets/sqlpp_queries.xml |  2 +
 .../asterix/cloud/AbstractCloudIOManager.java      | 13 +++++--
 .../apache/asterix/cloud/CloudManagerProvider.java |  9 +++--
 .../apache/asterix/cloud/EagerCloudIOManager.java  |  6 ++-
 .../apache/asterix/cloud/LazyCloudIOManager.java   |  6 ++-
 .../asterix/common/api/INamespaceResolver.java     |  1 +
 .../asterix/common/config/CompilerProperties.java  | 13 ++++++-
 .../asterix/common/exceptions/ErrorCode.java       |  2 +
 .../common/metadata/DatasetFullyQualifiedName.java |  3 +-
 .../asterix/common/metadata/MetadataConstants.java |  1 +
 .../asterix/common/metadata/MetadataUtil.java      |  5 +++
 .../common/metadata/NamespacePathResolver.java     | 24 ++++++++++--
 .../asterix/common/metadata/NamespaceResolver.java | 42 ++++++++++++++++++--
 .../common/storage/DatasetCopyIdentifier.java      | 21 +++++-----
 .../asterix/common/storage/ResourceReference.java  | 17 +++++++-
 .../src/main/resources/asx_errormsg/en.properties  |  2 +
 .../ioopcallbacks/LSMIOOperationCallbackTest.java  | 11 ++++--
 .../asterix/lang/common/base/IQueryRewriter.java   |  3 +-
 .../lang/sqlpp/rewrites/SqlppQueryRewriter.java    | 29 ++++++++++----
 .../visitor/VariableCheckAndRewriteVisitor.java    |  7 ++--
 .../org/apache/asterix/metadata/MetadataNode.java  | 23 ++++++++++-
 .../apache/asterix/metadata/utils/DatasetUtil.java |  5 +++
 35 files changed, 327 insertions(+), 79 deletions(-)

diff --git 
a/asterixdb/asterix-app/src/main/java/org/apache/asterix/app/cc/CcApplicationContext.java
 
b/asterixdb/asterix-app/src/main/java/org/apache/asterix/app/cc/CcApplicationContext.java
index 24b4856ffe..6ea7aebf83 100644
--- 
a/asterixdb/asterix-app/src/main/java/org/apache/asterix/app/cc/CcApplicationContext.java
+++ 
b/asterixdb/asterix-app/src/main/java/org/apache/asterix/app/cc/CcApplicationContext.java
@@ -57,7 +57,6 @@ import 
org.apache.asterix.common.dataflow.IDataPartitioningProvider;
 import org.apache.asterix.common.external.IAdapterFactoryService;
 import org.apache.asterix.common.metadata.IMetadataBootstrap;
 import org.apache.asterix.common.metadata.IMetadataLockUtil;
-import org.apache.asterix.common.metadata.NamespacePathResolver;
 import org.apache.asterix.common.replication.INcLifecycleCoordinator;
 import org.apache.asterix.common.storage.ICompressionManager;
 import org.apache.asterix.common.transactions.IResourceIdManager;
@@ -126,7 +125,7 @@ public class CcApplicationContext implements 
ICcApplicationContext {
     private final IDataPartitioningProvider dataPartitioningProvider;
     private final IGlobalTxManager globalTxManager;
     private final IOManager ioManager;
-    private final NamespacePathResolver namespacePathResolver;
+    private final INamespacePathResolver namespacePathResolver;
     private final INamespaceResolver namespaceResolver;
 
     public CcApplicationContext(ICCServiceContext ccServiceCtx, 
HyracksConnection hcc,
@@ -136,8 +135,8 @@ public class CcApplicationContext implements 
ICcApplicationContext {
             IMetadataLockUtil mdLockUtil, IReceptionistFactory 
receptionistFactory,
             IConfigValidatorFactory configValidatorFactory, Object 
extensionManager,
             IAdapterFactoryService adapterFactoryService, IGlobalTxManager 
globalTxManager, IOManager ioManager,
-            CloudProperties cloudProperties, INamespaceResolver 
namespaceResolver)
-            throws AlgebricksException, IOException {
+            CloudProperties cloudProperties, INamespaceResolver 
namespaceResolver,
+            INamespacePathResolver namespacePathResolver) throws 
AlgebricksException, IOException {
         this.ccServiceCtx = ccServiceCtx;
         this.hcc = hcc;
         this.activeLifeCycleListener = activeLifeCycleListener;
@@ -173,7 +172,7 @@ public class CcApplicationContext implements 
ICcApplicationContext {
         requestTracker = new RequestTracker(this);
         configValidator = configValidatorFactory.create();
         this.adapterFactoryService = adapterFactoryService;
-        this.namespacePathResolver = new 
NamespacePathResolver(isCloudDeployment());
+        this.namespacePathResolver = namespacePathResolver;
         this.namespaceResolver = namespaceResolver;
         this.globalTxManager = globalTxManager;
         this.ioManager = ioManager;
diff --git 
a/asterixdb/asterix-app/src/main/java/org/apache/asterix/app/nc/NCAppRuntimeContext.java
 
b/asterixdb/asterix-app/src/main/java/org/apache/asterix/app/nc/NCAppRuntimeContext.java
index ab6a62ac13..a439fe57bf 100644
--- 
a/asterixdb/asterix-app/src/main/java/org/apache/asterix/app/nc/NCAppRuntimeContext.java
+++ 
b/asterixdb/asterix-app/src/main/java/org/apache/asterix/app/nc/NCAppRuntimeContext.java
@@ -61,7 +61,6 @@ import 
org.apache.asterix.common.context.DiskWriteRateLimiterProvider;
 import org.apache.asterix.common.context.GlobalVirtualBufferCache;
 import org.apache.asterix.common.context.IStorageComponentProvider;
 import org.apache.asterix.common.library.ILibraryManager;
-import org.apache.asterix.common.metadata.NamespacePathResolver;
 import org.apache.asterix.common.replication.IReplicationChannel;
 import org.apache.asterix.common.replication.IReplicationManager;
 import org.apache.asterix.common.replication.IReplicationStrategyFactory;
@@ -172,11 +171,12 @@ public class NCAppRuntimeContext implements 
INcApplicationContext {
     private IDiskWriteRateLimiterProvider diskWriteRateLimiterProvider;
     private final CloudProperties cloudProperties;
     private IPartitionBootstrapper partitionBootstrapper;
-    private final NamespacePathResolver namespacePathResolver;
+    private final INamespacePathResolver namespacePathResolver;
     private final INamespaceResolver namespaceResolver;
 
     public NCAppRuntimeContext(INCServiceContext ncServiceContext, 
NCExtensionManager extensionManager,
-            IPropertiesFactory propertiesFactory, INamespaceResolver 
namespaceResolver) {
+            IPropertiesFactory propertiesFactory, INamespaceResolver 
namespaceResolver,
+            INamespacePathResolver namespacePathResolver) {
         this.ncServiceContext = ncServiceContext;
         compilerProperties = propertiesFactory.newCompilerProperties();
         externalProperties = propertiesFactory.newExternalProperties();
@@ -195,7 +195,7 @@ public class NCAppRuntimeContext implements 
INcApplicationContext {
                 .createResourceIdFactory();
         persistedResourceRegistry = 
ncServiceContext.getPersistedResourceRegistry();
         cacheManager = new CacheManager();
-        namespacePathResolver = new NamespacePathResolver(isCloudDeployment());
+        this.namespacePathResolver = namespacePathResolver;
         this.namespaceResolver = namespaceResolver;
     }
 
@@ -205,7 +205,8 @@ public class NCAppRuntimeContext implements 
INcApplicationContext {
             boolean initialRun) throws IOException {
         ioManager = getServiceContext().getIoManager();
         if (isCloudDeployment()) {
-            persistenceIOManager = 
CloudManagerProvider.createIOManager(cloudProperties, ioManager);
+            persistenceIOManager =
+                    CloudManagerProvider.createIOManager(cloudProperties, 
ioManager, namespacePathResolver);
             partitionBootstrapper = 
CloudManagerProvider.getCloudPartitionBootstrapper(persistenceIOManager);
         } else {
             persistenceIOManager = ioManager;
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 4b19200102..f404ca5f6a 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
@@ -663,8 +663,7 @@ public class QueryTranslator extends AbstractLangTranslator 
implements IStatemen
                     MetadataManager.INSTANCE.commitTransaction(mdTxnCtx);
                     return false;
                 } else {
-                    //TODO(DB): change
-                    throw new CompilationException(ErrorCode.DATAVERSE_EXISTS, 
stmtCreateDatabase.getSourceLocation(),
+                    throw new CompilationException(ErrorCode.DATABASE_EXISTS, 
stmtCreateDatabase.getSourceLocation(),
                             databaseName);
                 }
             }
@@ -703,6 +702,12 @@ public class QueryTranslator extends 
AbstractLangTranslator implements IStatemen
         try {
             DataverseName dvName = stmtCreateDataverse.getDataverseName();
             String dbName = stmtCreateDataverse.getDatabaseName();
+            Database db = MetadataManager.INSTANCE.getDatabase(mdTxnCtx, 
dbName);
+            if (db == null) {
+                throw new CompilationException(ErrorCode.UNKNOWN_DATABASE, 
stmtCreateDataverse.getSourceLocation(),
+                        dbName);
+            }
+
             Dataverse dv =
                     
MetadataManager.INSTANCE.getDataverse(metadataProvider.getMetadataTxnContext(), 
dbName, dvName);
             if (dv != null) {
@@ -872,6 +877,8 @@ public class QueryTranslator extends AbstractLangTranslator 
implements IStatemen
         DatasetFormatInfo datasetFormatInfo = 
dd.getDatasetFormatInfo(storageProperties.getStorageFormat(),
                 storageProperties.getColumnMaxTupleCount(), 
storageProperties.getColumnFreeSpaceTolerance());
         try {
+            //TODO(DB): also check for database existence?
+
             // Check if the dataverse exists
             Dataverse dv = MetadataManager.INSTANCE.getDataverse(mdTxnCtx, 
databaseName, dataverseName);
             if (dv == null) {
@@ -2137,6 +2144,18 @@ public class QueryTranslator extends 
AbstractLangTranslator implements IStatemen
         List<FeedEventsListener> feedsToStop = new ArrayList<>();
         List<JobSpecification> jobsToExecute = new ArrayList<>();
         try {
+            Database db = MetadataManager.INSTANCE.getDatabase(mdTxnCtx, 
databaseName);
+            if (db == null) {
+                if (stmtDropDataverse.getIfExists()) {
+                    if (warningCollector.shouldWarn()) {
+                        warningCollector.warn(Warning.of(sourceLoc, 
ErrorCode.UNKNOWN_DATABASE, databaseName));
+                    }
+                    MetadataManager.INSTANCE.commitTransaction(mdTxnCtx);
+                    return false;
+                } else {
+                    throw new CompilationException(ErrorCode.UNKNOWN_DATABASE, 
sourceLoc, databaseName);
+                }
+            }
             Dataverse dv = MetadataManager.INSTANCE.getDataverse(mdTxnCtx, 
databaseName, dataverseName);
             if (dv == null) {
                 if (stmtDropDataverse.getIfExists()) {
@@ -2338,6 +2357,8 @@ public class QueryTranslator extends 
AbstractLangTranslator implements IStatemen
         List<JobSpecification> jobsToExecute = new ArrayList<>();
         Dataset ds = null;
         try {
+            //TODO(DB): also check for database existence?
+
             // Check if the dataverse exists
             Dataverse dv = 
MetadataManager.INSTANCE.getDataverse(mdTxnCtx.getValue(), databaseName, 
dataverseName);
             if (dv == null) {
@@ -2896,7 +2917,8 @@ public class QueryTranslator extends 
AbstractLangTranslator implements IStatemen
             ViewDecl viewDecl = new ViewDecl(viewQualifiedName, 
cvs.getViewBodyExpression());
             viewDecl.setSourceLocation(sourceLoc);
             IQueryRewriter queryRewriter = 
rewriterFactory.createQueryRewriter();
-            Query wrappedQuery = 
queryRewriter.createViewAccessorQuery(viewDecl);
+            Query wrappedQuery =
+                    queryRewriter.createViewAccessorQuery(viewDecl, 
metadataProvider.getNamespaceResolver());
             metadataProvider.setDefaultNamespace(ns);
             LangRewritingContext langRewritingContext = 
createLangRewritingContext(metadataProvider, declaredFunctions,
                     Collections.singletonList(viewDecl), warningCollector, 
wrappedQuery.getVarCounter());
diff --git 
a/asterixdb/asterix-app/src/main/java/org/apache/asterix/hyracks/bootstrap/CCApplication.java
 
b/asterixdb/asterix-app/src/main/java/org/apache/asterix/hyracks/bootstrap/CCApplication.java
index de3cb82379..c93a23b50d 100644
--- 
a/asterixdb/asterix-app/src/main/java/org/apache/asterix/hyracks/bootstrap/CCApplication.java
+++ 
b/asterixdb/asterix-app/src/main/java/org/apache/asterix/hyracks/bootstrap/CCApplication.java
@@ -64,6 +64,7 @@ import org.apache.asterix.app.result.JobResultCallback;
 import org.apache.asterix.cloud.CloudManagerProvider;
 import org.apache.asterix.common.api.AsterixThreadFactory;
 import org.apache.asterix.common.api.IConfigValidatorFactory;
+import org.apache.asterix.common.api.INamespacePathResolver;
 import org.apache.asterix.common.api.INamespaceResolver;
 import org.apache.asterix.common.api.INodeJobTracker;
 import org.apache.asterix.common.api.IReceptionistFactory;
@@ -71,6 +72,7 @@ import 
org.apache.asterix.common.cluster.IGlobalRecoveryManager;
 import org.apache.asterix.common.cluster.IGlobalTxManager;
 import org.apache.asterix.common.config.AsterixExtension;
 import org.apache.asterix.common.config.CloudProperties;
+import org.apache.asterix.common.config.CompilerProperties;
 import org.apache.asterix.common.config.ExtensionProperties;
 import org.apache.asterix.common.config.ExternalProperties;
 import org.apache.asterix.common.config.GlobalConfig;
@@ -82,6 +84,7 @@ import 
org.apache.asterix.common.dataflow.ICcApplicationContext;
 import org.apache.asterix.common.external.IAdapterFactoryService;
 import org.apache.asterix.common.library.ILibraryManager;
 import org.apache.asterix.common.metadata.IMetadataLockUtil;
+import org.apache.asterix.common.metadata.NamespacePathResolver;
 import org.apache.asterix.common.metadata.NamespaceResolver;
 import org.apache.asterix.common.replication.INcLifecycleCoordinator;
 import org.apache.asterix.common.utils.Servlets;
@@ -167,8 +170,12 @@ public class CCApplication extends BaseCCApplication {
                 new 
ReplicationProperties(PropertiesAccessor.getInstance(ccServiceCtx.getAppConfig()));
         INcLifecycleCoordinator lifecycleCoordinator = 
createNcLifeCycleCoordinator(repProp.isReplicationEnabled());
         componentProvider = new StorageComponentProvider();
+        boolean isDbResolutionEnabled =
+                
ccServiceCtx.getAppConfig().getBoolean(CompilerProperties.Option.COMPILER_ENABLE_DB_RESOLUTION);
         boolean cloudDeployment = 
ccServiceCtx.getAppConfig().getBoolean(CLOUD_DEPLOYMENT);
-        INamespaceResolver namespaceResolver = new 
NamespaceResolver(cloudDeployment);
+        boolean useDatabaseResolution = cloudDeployment && 
isDbResolutionEnabled;
+        INamespaceResolver namespaceResolver = new 
NamespaceResolver(useDatabaseResolution);
+        INamespacePathResolver namespacePathResolver = new 
NamespacePathResolver(useDatabaseResolution);
         ccExtensionManager = new CCExtensionManager(new 
ArrayList<>(getExtensions()), namespaceResolver);
         IGlobalRecoveryManager globalRecoveryManager = 
createGlobalRecoveryManager();
         final CCConfig ccConfig = controllerService.getCCConfig();
@@ -179,12 +186,13 @@ public class CCApplication extends BaseCCApplication {
         CloudProperties cloudProperties = null;
         if (cloudDeployment) {
             cloudProperties = new 
CloudProperties(PropertiesAccessor.getInstance(ccServiceCtx.getAppConfig()));
-            ioManager = (IOManager) 
CloudManagerProvider.createIOManager(cloudProperties, ioManager);
+            ioManager =
+                    (IOManager) 
CloudManagerProvider.createIOManager(cloudProperties, ioManager, 
namespacePathResolver);
         }
         IGlobalTxManager globalTxManager = createGlobalTxManager(ioManager);
         appCtx = createApplicationContext(null, globalRecoveryManager, 
lifecycleCoordinator, Receptionist::new,
                 ConfigValidator::new, ccExtensionManager, new 
AdapterFactoryService(), globalTxManager, ioManager,
-                cloudProperties, namespaceResolver);
+                cloudProperties, namespaceResolver, namespacePathResolver);
         if (System.getProperty("java.rmi.server.hostname") == null) {
             System.setProperty("java.rmi.server.hostname", 
ccConfig.getClusterPublicAddress());
         }
@@ -233,11 +241,13 @@ public class CCApplication extends BaseCCApplication {
             IReceptionistFactory receptionistFactory, IConfigValidatorFactory 
configValidatorFactory,
             CCExtensionManager ccExtensionManager, IAdapterFactoryService 
adapterFactoryService,
             IGlobalTxManager globalTxManager, IOManager ioManager, 
CloudProperties cloudProperties,
-            INamespaceResolver namespaceResolver) throws AlgebricksException, 
IOException {
+            INamespaceResolver namespaceResolver, INamespacePathResolver 
namespacePathResolver)
+            throws AlgebricksException, IOException {
         return new CcApplicationContext(ccServiceCtx, hcc, () -> 
MetadataManager.INSTANCE, globalRecoveryManager,
                 lifecycleCoordinator, new ActiveNotificationHandler(), 
componentProvider, new MetadataLockManager(),
                 createMetadataLockUtil(), receptionistFactory, 
configValidatorFactory, ccExtensionManager,
-                adapterFactoryService, globalTxManager, ioManager, 
cloudProperties, namespaceResolver);
+                adapterFactoryService, globalTxManager, ioManager, 
cloudProperties, namespaceResolver,
+                namespacePathResolver);
     }
 
     protected IGlobalRecoveryManager createGlobalRecoveryManager() throws 
Exception {
diff --git 
a/asterixdb/asterix-app/src/main/java/org/apache/asterix/hyracks/bootstrap/NCApplication.java
 
b/asterixdb/asterix-app/src/main/java/org/apache/asterix/hyracks/bootstrap/NCApplication.java
index eea87d853f..4acc0396d3 100644
--- 
a/asterixdb/asterix-app/src/main/java/org/apache/asterix/hyracks/bootstrap/NCApplication.java
+++ 
b/asterixdb/asterix-app/src/main/java/org/apache/asterix/hyracks/bootstrap/NCApplication.java
@@ -55,11 +55,13 @@ import org.apache.asterix.app.nc.RecoveryManager;
 import 
org.apache.asterix.app.replication.message.RegistrationTasksRequestMessage;
 import org.apache.asterix.common.api.AsterixThreadFactory;
 import org.apache.asterix.common.api.IConfigValidatorFactory;
+import org.apache.asterix.common.api.INamespacePathResolver;
 import org.apache.asterix.common.api.INamespaceResolver;
 import org.apache.asterix.common.api.INcApplicationContext;
 import org.apache.asterix.common.api.IPropertiesFactory;
 import org.apache.asterix.common.api.IReceptionistFactory;
 import org.apache.asterix.common.config.AsterixExtension;
+import org.apache.asterix.common.config.CompilerProperties;
 import org.apache.asterix.common.config.ExtensionProperties;
 import org.apache.asterix.common.config.ExternalProperties;
 import org.apache.asterix.common.config.GlobalConfig;
@@ -70,6 +72,7 @@ import org.apache.asterix.common.config.PropertiesAccessor;
 import org.apache.asterix.common.config.PropertiesFactory;
 import org.apache.asterix.common.config.StorageProperties;
 import org.apache.asterix.common.exceptions.AsterixException;
+import org.apache.asterix.common.metadata.NamespacePathResolver;
 import org.apache.asterix.common.metadata.NamespaceResolver;
 import org.apache.asterix.common.replication.IReplicationStrategyFactory;
 import org.apache.asterix.common.replication.ReplicationStrategyFactory;
@@ -157,12 +160,16 @@ public class NCApplication extends BaseNCApplication {
         }
         MetadataBuiltinFunctions.init();
 
+        boolean isDbResolutionEnabled =
+                
ncServiceCtx.getAppConfig().getBoolean(CompilerProperties.Option.COMPILER_ENABLE_DB_RESOLUTION);
         boolean cloudDeployment = 
ncServiceCtx.getAppConfig().getBoolean(CLOUD_DEPLOYMENT);
-        NamespaceResolver namespaceResolver = new 
NamespaceResolver(cloudDeployment);
+        boolean useDatabaseResolution = cloudDeployment && 
isDbResolutionEnabled;
+        NamespaceResolver namespaceResolver = new 
NamespaceResolver(useDatabaseResolution);
+        NamespacePathResolver namespacePathResolver = new 
NamespacePathResolver(useDatabaseResolution);
         ncExtensionManager =
                 new NCExtensionManager(new ArrayList<>(getExtensions()), 
cloudDeployment, namespaceResolver);
-        runtimeContext =
-                createNCApplicationContext(ncServiceCtx, ncExtensionManager, 
getPropertiesFactory(), namespaceResolver);
+        runtimeContext = createNCApplicationContext(ncServiceCtx, 
ncExtensionManager, getPropertiesFactory(),
+                namespaceResolver, namespacePathResolver);
         MetadataProperties metadataProperties = 
runtimeContext.getMetadataProperties();
         if 
(!metadataProperties.getNodeNames().contains(this.ncServiceCtx.getNodeId())) {
             if (LOGGER.isInfoEnabled()) {
@@ -196,8 +203,10 @@ public class NCApplication extends BaseNCApplication {
 
     protected INcApplicationContext 
createNCApplicationContext(INCServiceContext ncServiceCtx,
             NCExtensionManager ncExtensionManager, IPropertiesFactory 
propertiesFactory,
-            INamespaceResolver namespaceResolver) throws IOException, 
AsterixException {
-        return new NCAppRuntimeContext(ncServiceCtx, ncExtensionManager, 
propertiesFactory, namespaceResolver);
+            INamespaceResolver namespaceResolver, INamespacePathResolver 
namespacePathResolver)
+            throws IOException, AsterixException {
+        return new NCAppRuntimeContext(ncServiceCtx, ncExtensionManager, 
propertiesFactory, namespaceResolver,
+                namespacePathResolver);
     }
 
     protected IRecoveryManagerFactory getRecoveryManagerFactory() {
diff --git 
a/asterixdb/asterix-app/src/test/java/org/apache/asterix/test/cloud_storage/CloudStorageTest.java
 
b/asterixdb/asterix-app/src/test/java/org/apache/asterix/test/cloud_storage/CloudStorageTest.java
index a45a1bfa01..a23da8c0e8 100644
--- 
a/asterixdb/asterix-app/src/test/java/org/apache/asterix/test/cloud_storage/CloudStorageTest.java
+++ 
b/asterixdb/asterix-app/src/test/java/org/apache/asterix/test/cloud_storage/CloudStorageTest.java
@@ -19,13 +19,19 @@
 package org.apache.asterix.test.cloud_storage;
 
 import java.util.Collection;
+import java.util.List;
 
 import org.apache.asterix.api.common.LocalCloudUtil;
 import org.apache.asterix.common.config.GlobalConfig;
 import org.apache.asterix.test.common.TestExecutor;
 import org.apache.asterix.test.runtime.LangExecutionUtil;
 import org.apache.asterix.testframework.context.TestCaseContext;
+import org.apache.asterix.testframework.xml.Description;
+import org.apache.asterix.testframework.xml.TestCase;
+import org.apache.logging.log4j.LogManager;
+import org.apache.logging.log4j.Logger;
 import org.junit.AfterClass;
+import org.junit.Assume;
 import org.junit.BeforeClass;
 import org.junit.FixMethodOrder;
 import org.junit.Test;
@@ -41,11 +47,14 @@ import org.junit.runners.Parameterized.Parameters;
 @FixMethodOrder(MethodSorters.NAME_ASCENDING)
 public class CloudStorageTest {
 
-    protected TestCaseContext tcCtx;
+    private static final Logger LOGGER = LogManager.getLogger();
+
+    private final TestCaseContext tcCtx;
     private static final String SUITE_TESTS = "testsuite_cloud_storage.xml";
     private static final String ONLY_TESTS = 
"testsuite_cloud_storage_only.xml";
     private static final String CONFIG_FILE_NAME = 
"src/test/resources/cc-cloud-storage.conf";
     private static final String DELTA_RESULT_PATH = "results_cloud";
+    private static final String EXCLUDED_TESTS = "MP";
 
     public CloudStorageTest(TestCaseContext tcCtx) {
         this.tcCtx = tcCtx;
@@ -55,6 +64,7 @@ public class CloudStorageTest {
     public static void setUp() throws Exception {
         LocalCloudUtil.startS3CloudEnvironment(true);
         TestExecutor testExecutor = new TestExecutor(DELTA_RESULT_PATH);
+        testExecutor.stripSubstring = "//DB:";
         LangExecutionUtil.setUp(CONFIG_FILE_NAME, testExecutor);
         System.setProperty(GlobalConfig.CONFIG_FILE_PROPERTY, 
CONFIG_FILE_NAME);
     }
@@ -71,6 +81,12 @@ public class CloudStorageTest {
 
     @Test
     public void test() throws Exception {
+        List<TestCase.CompilationUnit> cu = 
tcCtx.getTestCase().getCompilationUnit();
+        Assume.assumeTrue(cu.size() > 1 || 
!EXCLUDED_TESTS.equals(getText(cu.get(0).getDescription())));
         LangExecutionUtil.test(tcCtx);
     }
+
+    private static String getText(Description description) {
+        return description == null ? "" : description.getValue();
+    }
 }
diff --git 
a/asterixdb/asterix-app/src/test/java/org/apache/asterix/test/common/TestExecutor.java
 
b/asterixdb/asterix-app/src/test/java/org/apache/asterix/test/common/TestExecutor.java
index 28608131f0..9498979a47 100644
--- 
a/asterixdb/asterix-app/src/test/java/org/apache/asterix/test/common/TestExecutor.java
+++ 
b/asterixdb/asterix-app/src/test/java/org/apache/asterix/test/common/TestExecutor.java
@@ -276,6 +276,7 @@ public class TestExecutor {
     protected int loopIteration;
 
     protected String deltaPath = null;
+    public String stripSubstring = null;
 
     public TestExecutor() {
         this(Collections.singletonList(
@@ -861,6 +862,9 @@ public class TestExecutor {
         }
 
         str = applyExternalDatasetSubstitution(str, placeholders);
+        if (stripSubstring != null && !stripSubstring.isBlank()) {
+            str = strip(str, stripSubstring);
+        }
 
         HttpUriRequest method = jsonEncoded ? constructPostMethodJson(str, 
uri, "statement", params)
                 : constructPostMethodUrl(str, uri, "statement", params);
@@ -2325,6 +2329,10 @@ public class TestExecutor {
         return substitute;
     }
 
+    protected static String strip(String str, String target) {
+        return str.replace(target, "");
+    }
+
     protected String applyExternalDatasetSubstitution(String str, 
List<Placeholder> placeholders) {
         // This replaces the full template of parameters depending on the 
adapter type
         for (Placeholder placeholder : placeholders) {
@@ -2589,12 +2597,12 @@ public class TestExecutor {
 
     public void cleanup(String testCase, List<String> badtestcases) throws 
Exception {
         try {
-            List<DataverseName> toBeDropped = new ArrayList<>();
+            List<Pair<String, DataverseName>> toBeDropped = new ArrayList<>();
             listUserDefinedDataverses(toBeDropped);
             if (!toBeDropped.isEmpty()) {
                 badtestcases.add(testCase);
                 LOGGER.info("Last test left some garbage. Dropping dataverses: 
" + StringUtils.join(toBeDropped, ','));
-                for (DataverseName dv : toBeDropped) {
+                for (Pair<String, DataverseName> dv : toBeDropped) {
                     dropDataverse(dv);
                 }
             }
@@ -2604,8 +2612,9 @@ public class TestExecutor {
         }
     }
 
-    protected void listUserDefinedDataverses(List<DataverseName> 
outDataverses) throws Exception {
-        String query = "select dv.DataverseName from Metadata.`Dataverse` as 
dv order by dv.DataverseName";
+    protected void listUserDefinedDataverses(List<Pair<String, DataverseName>> 
outDataverses) throws Exception {
+        String query =
+                "select dv.DatabaseName, dv.DataverseName from 
Metadata.`Dataverse` as dv order by dv.DataverseName";
         InputStream resultStream =
                 executeQueryService(query, 
getEndpoint(Servlets.QUERY_SERVICE), OutputFormat.CLEAN_JSON);
         JsonNode result = extractResult(IOUtils.toString(resultStream, UTF_8));
@@ -2615,16 +2624,26 @@ public class TestExecutor {
                 DataverseName dvName = 
DataverseName.createFromCanonicalForm(json.get("DataverseName").asText());
                 if (!dvName.equals(MetadataConstants.METADATA_DATAVERSE_NAME)
                         && 
!dvName.equals(MetadataConstants.DEFAULT_DATAVERSE_NAME)) {
-                    outDataverses.add(dvName);
+                    JsonNode databaseName = json.get("DatabaseName");
+                    String dbName = null;
+                    if (databaseName != null && !databaseName.isNull() && 
!databaseName.isMissingNode()) {
+                        dbName = databaseName.asText();
+                    }
+                    outDataverses.add(new Pair<>(dbName, dvName));
                 }
             }
         }
     }
 
-    protected void dropDataverse(DataverseName dv) throws Exception {
+    protected void dropDataverse(Pair<String, DataverseName> dv) throws 
Exception {
         StringBuilder dropStatement = new StringBuilder();
         dropStatement.append("drop dataverse ");
-        SqlppStatementUtil.encloseDataverseName(dropStatement, dv);
+        if (dv.first == null) {
+            SqlppStatementUtil.encloseDataverseName(dropStatement, dv.second);
+        } else {
+            SqlppStatementUtil.enclose(dropStatement, 
dv.first).append(SqlppStatementUtil.DOT);
+            SqlppStatementUtil.encloseDataverseName(dropStatement, dv.second);
+        }
         dropStatement.append(";\n");
         InputStream resultStream = 
executeQueryService(dropStatement.toString(), 
getEndpoint(Servlets.QUERY_SERVICE),
                 OutputFormat.CLEAN_JSON, UTF_8);
@@ -2652,6 +2671,18 @@ public class TestExecutor {
         }
     }
 
+    protected boolean metadataHasDatabase() throws Exception {
+        String query = "select d.DatabaseName from Metadata.`Dataverse` d 
limit 1;";
+        InputStream resultStream = executeQueryService(query, 
getEndpoint(Servlets.QUERY_SERVICE),
+                TestCaseContext.OutputFormat.CLEAN_JSON);
+        JsonNode result = extractResult(IOUtils.toString(resultStream, UTF_8));
+        if (result.size() > 1) {
+            JsonNode json = result.get(0);
+            return json != null && !json.get("DatabaseName").isNull() && 
!json.get("DatabaseName").isMissingNode();
+        }
+        return false;
+    }
+
     private JsonNode extractResult(String jsonString) throws IOException {
         try {
             final JsonNode result = RESULT_NODE_READER.<ObjectNode> 
readValue(jsonString).get("results");
diff --git 
a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/api/request-dataverse/request-dataverse.1.ddl.sqlpp
 
b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/api/request-dataverse/request-dataverse.1.ddl.sqlpp
index cb28d2fb26..33130f2aca 100644
--- 
a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/api/request-dataverse/request-dataverse.1.ddl.sqlpp
+++ 
b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/api/request-dataverse/request-dataverse.1.ddl.sqlpp
@@ -20,6 +20,8 @@
 drop dataverse test1 if exists;
 create dataverse test1;
 
+//DB: drop database test2 if exists;
+//DB: create database test2;
 drop dataverse test2.test3 if exists;
 create dataverse test2.test3;
 
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 18a98e38c2..e7c276902f 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,6 +17,8 @@
  * 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`;
 
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 3580ae92cc..923c81b9f0 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
@@ -18,3 +18,4 @@
  */
 
 DROP DATAVERSE `part1`.`p%r t2` IF EXISTS;
+DROP DATABASE `part1`;
\ No newline at end of file
diff --git 
a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/multipart-dataverse/index_1/index_1.1.ddl.sqlpp
 
b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/multipart-dataverse/index_1/index_1.1.ddl.sqlpp
index 910b6df187..e657e61f99 100644
--- 
a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/multipart-dataverse/index_1/index_1.1.ddl.sqlpp
+++ 
b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/multipart-dataverse/index_1/index_1.1.ddl.sqlpp
@@ -20,6 +20,8 @@
  * Description: index in a dataverse with a multipart name
  */
 
+//DB: drop database x if exists;
+//DB: create database x;
 drop  dataverse x.y if exists;
 create  dataverse x.y;
 
diff --git 
a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/multipart-dataverse/resolution_1/resolution_1.1.ddl.sqlpp
 
b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/multipart-dataverse/resolution_1/resolution_1.1.ddl.sqlpp
index 1089bc3fc2..e6c06f9611 100644
--- 
a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/multipart-dataverse/resolution_1/resolution_1.1.ddl.sqlpp
+++ 
b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/multipart-dataverse/resolution_1/resolution_1.1.ddl.sqlpp
@@ -20,6 +20,8 @@
  * Description: name resolution for a dataverse with a multipart name
  */
 
+//DB: drop database sales if exists;
+//DB: create database sales;
 drop dataverse sales.east if exists;
 create dataverse sales.east;
 
diff --git 
a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/multipart-dataverse/udf_1/udf_1.1.ddl.sqlpp
 
b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/multipart-dataverse/udf_1/udf_1.1.ddl.sqlpp
index 6b01a1123b..fea7c0a4a7 100644
--- 
a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/multipart-dataverse/udf_1/udf_1.1.ddl.sqlpp
+++ 
b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/multipart-dataverse/udf_1/udf_1.1.ddl.sqlpp
@@ -20,6 +20,8 @@
  * Description: user-defined function in a dataverse with a multipart name
  */
 
+//DB: drop database x if exists;
+//DB: create database x;
 drop  dataverse x.y if exists;
 create  dataverse x.y;
 
diff --git 
a/asterixdb/asterix-app/src/test/resources/runtimets/sqlpp_queries.xml 
b/asterixdb/asterix-app/src/test/resources/runtimets/sqlpp_queries.xml
index ffe81d62e9..0f537d7814 100644
--- a/asterixdb/asterix-app/src/test/resources/runtimets/sqlpp_queries.xml
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/sqlpp_queries.xml
@@ -7352,11 +7352,13 @@
     </test-case>
     <test-case FilePath="multipart-dataverse">
       <compilation-unit name="special_chars_1">
+        <description>MP</description>
         <output-dir compare="Text">special_chars_1</output-dir>
       </compilation-unit>
     </test-case>
     <test-case FilePath="multipart-dataverse">
       <compilation-unit name="special_chars_2">
+        <description>MP</description>
         <output-dir compare="Text">special_chars_2</output-dir>
       </compilation-unit>
     </test-case>
diff --git 
a/asterixdb/asterix-cloud/src/main/java/org/apache/asterix/cloud/AbstractCloudIOManager.java
 
b/asterixdb/asterix-cloud/src/main/java/org/apache/asterix/cloud/AbstractCloudIOManager.java
index 317928060f..8c7cd8a4f1 100644
--- 
a/asterixdb/asterix-cloud/src/main/java/org/apache/asterix/cloud/AbstractCloudIOManager.java
+++ 
b/asterixdb/asterix-cloud/src/main/java/org/apache/asterix/cloud/AbstractCloudIOManager.java
@@ -35,8 +35,10 @@ import org.apache.asterix.cloud.bulk.NoOpDeleteBulkCallBack;
 import org.apache.asterix.cloud.clients.CloudClientProvider;
 import org.apache.asterix.cloud.clients.ICloudClient;
 import org.apache.asterix.cloud.util.CloudFileUtil;
+import org.apache.asterix.common.api.INamespacePathResolver;
 import org.apache.asterix.common.cloud.IPartitionBootstrapper;
 import org.apache.asterix.common.config.CloudProperties;
+import org.apache.asterix.common.metadata.MetadataConstants;
 import org.apache.asterix.common.transactions.IRecoveryManager;
 import org.apache.asterix.common.utils.StoragePathUtil;
 import org.apache.hyracks.api.exceptions.HyracksDataException;
@@ -54,8 +56,8 @@ import com.fasterxml.jackson.databind.ObjectMapper;
 
 public abstract class AbstractCloudIOManager extends IOManager implements 
IPartitionBootstrapper {
     private static final Logger LOGGER = LogManager.getLogger();
-    private static final String DATAVERSE_PATH =
-            FileUtil.joinPath(STORAGE_ROOT_DIR_NAME, PARTITION_DIR_PREFIX + 
METADATA_PARTITION, "Metadata");
+    //TODO(DB): change
+    private final String metadataNamespacePath;
     protected final ICloudClient cloudClient;
     protected final WriteBufferProvider writeBufferProvider;
     protected final String bucket;
@@ -63,9 +65,12 @@ public abstract class AbstractCloudIOManager extends 
IOManager implements IParti
     protected final List<FileReference> partitionPaths;
     protected final IOManager localIoManager;
 
-    public AbstractCloudIOManager(IOManager ioManager, CloudProperties 
cloudProperties) throws HyracksDataException {
+    public AbstractCloudIOManager(IOManager ioManager, CloudProperties 
cloudProperties,
+            INamespacePathResolver nsPathResolver) throws HyracksDataException 
{
         super(ioManager.getIODevices(), ioManager.getDeviceComputer(), 
ioManager.getIOParallelism(),
                 ioManager.getQueueSize());
+        this.metadataNamespacePath = FileUtil.joinPath(STORAGE_ROOT_DIR_NAME, 
PARTITION_DIR_PREFIX + METADATA_PARTITION,
+                nsPathResolver.resolve(MetadataConstants.METADATA_NAMESPACE));
         this.bucket = cloudProperties.getStorageBucket();
         cloudClient = CloudClientProvider.getClient(cloudProperties);
         int numOfThreads = getIODevices().size() * getIOParallelism();
@@ -83,7 +88,7 @@ public abstract class AbstractCloudIOManager extends 
IOManager implements IParti
 
     @Override
     public IRecoveryManager.SystemState getSystemStateOnMissingCheckpoint() {
-        if (cloudClient.listObjects(bucket, DATAVERSE_PATH, 
IoUtil.NO_OP_FILTER).isEmpty()) {
+        if (cloudClient.listObjects(bucket, metadataNamespacePath, 
IoUtil.NO_OP_FILTER).isEmpty()) {
             LOGGER.info("First time to initialize this cluster: systemState = 
PERMANENT_DATA_LOSS");
             return IRecoveryManager.SystemState.PERMANENT_DATA_LOSS;
         } else {
diff --git 
a/asterixdb/asterix-cloud/src/main/java/org/apache/asterix/cloud/CloudManagerProvider.java
 
b/asterixdb/asterix-cloud/src/main/java/org/apache/asterix/cloud/CloudManagerProvider.java
index 6ba31db4f1..f325f41065 100644
--- 
a/asterixdb/asterix-cloud/src/main/java/org/apache/asterix/cloud/CloudManagerProvider.java
+++ 
b/asterixdb/asterix-cloud/src/main/java/org/apache/asterix/cloud/CloudManagerProvider.java
@@ -18,6 +18,7 @@
  */
 package org.apache.asterix.cloud;
 
+import org.apache.asterix.common.api.INamespacePathResolver;
 import org.apache.asterix.common.cloud.CloudCachePolicy;
 import org.apache.asterix.common.cloud.IPartitionBootstrapper;
 import org.apache.asterix.common.config.CloudProperties;
@@ -29,14 +30,14 @@ public class CloudManagerProvider {
     private CloudManagerProvider() {
     }
 
-    public static IIOManager createIOManager(CloudProperties cloudProperties, 
IIOManager ioManager)
-            throws HyracksDataException {
+    public static IIOManager createIOManager(CloudProperties cloudProperties, 
IIOManager ioManager,
+            INamespacePathResolver nsPathResolver) throws HyracksDataException 
{
         IOManager localIoManager = (IOManager) ioManager;
         if (cloudProperties.getCloudCachePolicy() == CloudCachePolicy.LAZY) {
-            return new LazyCloudIOManager(localIoManager, cloudProperties);
+            return new LazyCloudIOManager(localIoManager, cloudProperties, 
nsPathResolver);
         }
 
-        return new EagerCloudIOManager(localIoManager, cloudProperties);
+        return new EagerCloudIOManager(localIoManager, cloudProperties, 
nsPathResolver);
     }
 
     public static IPartitionBootstrapper 
getCloudPartitionBootstrapper(IIOManager ioManager) {
diff --git 
a/asterixdb/asterix-cloud/src/main/java/org/apache/asterix/cloud/EagerCloudIOManager.java
 
b/asterixdb/asterix-cloud/src/main/java/org/apache/asterix/cloud/EagerCloudIOManager.java
index b1f88cb083..d0b982c834 100644
--- 
a/asterixdb/asterix-cloud/src/main/java/org/apache/asterix/cloud/EagerCloudIOManager.java
+++ 
b/asterixdb/asterix-cloud/src/main/java/org/apache/asterix/cloud/EagerCloudIOManager.java
@@ -26,6 +26,7 @@ import java.util.Set;
 import java.util.stream.Collectors;
 
 import org.apache.asterix.cloud.clients.IParallelDownloader;
+import org.apache.asterix.common.api.INamespacePathResolver;
 import org.apache.asterix.common.config.CloudProperties;
 import org.apache.hyracks.api.exceptions.HyracksDataException;
 import org.apache.hyracks.api.io.FileReference;
@@ -44,8 +45,9 @@ import org.apache.logging.log4j.Logger;
 final class EagerCloudIOManager extends AbstractCloudIOManager {
     private static final Logger LOGGER = LogManager.getLogger();
 
-    public EagerCloudIOManager(IOManager ioManager, CloudProperties 
cloudProperties) throws HyracksDataException {
-        super(ioManager, cloudProperties);
+    public EagerCloudIOManager(IOManager ioManager, CloudProperties 
cloudProperties,
+            INamespacePathResolver nsPathResolver) throws HyracksDataException 
{
+        super(ioManager, cloudProperties, nsPathResolver);
     }
 
     /*
diff --git 
a/asterixdb/asterix-cloud/src/main/java/org/apache/asterix/cloud/LazyCloudIOManager.java
 
b/asterixdb/asterix-cloud/src/main/java/org/apache/asterix/cloud/LazyCloudIOManager.java
index 97a61733f0..6ecd201425 100644
--- 
a/asterixdb/asterix-cloud/src/main/java/org/apache/asterix/cloud/LazyCloudIOManager.java
+++ 
b/asterixdb/asterix-cloud/src/main/java/org/apache/asterix/cloud/LazyCloudIOManager.java
@@ -39,6 +39,7 @@ import 
org.apache.asterix.cloud.lazy.accessor.ILazyAccessorReplacer;
 import org.apache.asterix.cloud.lazy.accessor.InitialCloudAccessor;
 import org.apache.asterix.cloud.lazy.accessor.LocalAccessor;
 import org.apache.asterix.cloud.lazy.accessor.ReplaceableCloudAccessor;
+import org.apache.asterix.common.api.INamespacePathResolver;
 import org.apache.asterix.common.config.CloudProperties;
 import org.apache.asterix.common.utils.StoragePathUtil;
 import org.apache.hyracks.api.exceptions.HyracksDataException;
@@ -60,8 +61,9 @@ final class LazyCloudIOManager extends AbstractCloudIOManager 
{
     private final ILazyAccessorReplacer replacer;
     private ILazyAccessor accessor;
 
-    public LazyCloudIOManager(IOManager ioManager, CloudProperties 
cloudProperties) throws HyracksDataException {
-        super(ioManager, cloudProperties);
+    public LazyCloudIOManager(IOManager ioManager, CloudProperties 
cloudProperties,
+            INamespacePathResolver nsPathResolver) throws HyracksDataException 
{
+        super(ioManager, cloudProperties, nsPathResolver);
         accessor = new InitialCloudAccessor(cloudClient, bucket, 
localIoManager);
         replacer = () -> {
             synchronized (this) {
diff --git 
a/asterixdb/asterix-common/src/main/java/org/apache/asterix/common/api/INamespaceResolver.java
 
b/asterixdb/asterix-common/src/main/java/org/apache/asterix/common/api/INamespaceResolver.java
index 7f9bde614f..fb305095ee 100644
--- 
a/asterixdb/asterix-common/src/main/java/org/apache/asterix/common/api/INamespaceResolver.java
+++ 
b/asterixdb/asterix-common/src/main/java/org/apache/asterix/common/api/INamespaceResolver.java
@@ -31,4 +31,5 @@ public interface INamespaceResolver {
 
     Namespace resolve(String namespace) throws AsterixException;
 
+    boolean isUsingDatabase();
 }
diff --git 
a/asterixdb/asterix-common/src/main/java/org/apache/asterix/common/config/CompilerProperties.java
 
b/asterixdb/asterix-common/src/main/java/org/apache/asterix/common/config/CompilerProperties.java
index 01f9509663..85b80a6136 100644
--- 
a/asterixdb/asterix-common/src/main/java/org/apache/asterix/common/config/CompilerProperties.java
+++ 
b/asterixdb/asterix-common/src/main/java/org/apache/asterix/common/config/CompilerProperties.java
@@ -122,7 +122,9 @@ public class CompilerProperties extends AbstractProperties {
         COMPILER_COLUMN_FILTER(
                 BOOLEAN,
                 AlgebricksConfig.COLUMN_FILTER_DEFAULT,
-                "Enable/disable the use of column min/max filters");
+                "Enable/disable the use of column min/max filters"),
+        //TODO(DB): remove after
+        COMPILER_ENABLE_DB_RESOLUTION(BOOLEAN, true, "Enable/disable the 
resolution of namespaces to database");
 
         private final IOptionType type;
         private final Object defaultValue;
@@ -156,7 +158,8 @@ public class CompilerProperties extends AbstractProperties {
 
         @Override
         public boolean hidden() {
-            return this == COMPILER_EXTERNALSCANMEMORY || this == 
COMPILER_CBOTEST;
+            return this == COMPILER_EXTERNALSCANMEMORY || this == 
COMPILER_CBOTEST
+                    || this == COMPILER_ENABLE_DB_RESOLUTION;
         }
     }
 
@@ -204,6 +207,8 @@ public class CompilerProperties extends AbstractProperties {
 
     public static final String COMPILER_COLUMN_FILTER_KEY = 
Option.COMPILER_COLUMN_FILTER.ini();
 
+    public static final String COMPILER_ENABLE_DB_RESOLUTION_KEY = 
Option.COMPILER_ENABLE_DB_RESOLUTION.ini();
+
     public static final int COMPILER_PARALLELISM_AS_STORAGE = 0;
 
     public CompilerProperties(PropertiesAccessor accessor) {
@@ -306,4 +311,8 @@ public class CompilerProperties extends AbstractProperties {
     public boolean isColumnFilter() {
         return accessor.getBoolean(Option.COMPILER_COLUMN_FILTER);
     }
+
+    public boolean isDbResolutionEnabled() {
+        return accessor.getBoolean(Option.COMPILER_ENABLE_DB_RESOLUTION);
+    }
 }
diff --git 
a/asterixdb/asterix-common/src/main/java/org/apache/asterix/common/exceptions/ErrorCode.java
 
b/asterixdb/asterix-common/src/main/java/org/apache/asterix/common/exceptions/ErrorCode.java
index ff00aefb03..83418a4ecc 100644
--- 
a/asterixdb/asterix-common/src/main/java/org/apache/asterix/common/exceptions/ErrorCode.java
+++ 
b/asterixdb/asterix-common/src/main/java/org/apache/asterix/common/exceptions/ErrorCode.java
@@ -279,6 +279,8 @@ public enum ErrorCode implements IError {
     FAILED_TO_CALCULATE_COMPUTED_FIELDS(1182),
     FAILED_TO_EVALUATE_COMPUTED_FIELD(1183),
     ILLEGAL_DML_OPERATION(1184),
+    UNKNOWN_DATABASE(1185),
+    DATABASE_EXISTS(1186),
 
     // Feed errors
     DATAFLOW_ILLEGAL_STATE(3001),
diff --git 
a/asterixdb/asterix-common/src/main/java/org/apache/asterix/common/metadata/DatasetFullyQualifiedName.java
 
b/asterixdb/asterix-common/src/main/java/org/apache/asterix/common/metadata/DatasetFullyQualifiedName.java
index f53a3a3a42..261cddc6f6 100644
--- 
a/asterixdb/asterix-common/src/main/java/org/apache/asterix/common/metadata/DatasetFullyQualifiedName.java
+++ 
b/asterixdb/asterix-common/src/main/java/org/apache/asterix/common/metadata/DatasetFullyQualifiedName.java
@@ -48,7 +48,8 @@ public class DatasetFullyQualifiedName implements 
Serializable {
 
     @Override
     public String toString() {
-        return dataverseName + "." + datasetName;
+        return (MetadataConstants.DEFAULT_DATABASE.equals(databaseName) ? "" : 
datasetName + ".") + dataverseName + "."
+                + datasetName;
     }
 
     @Override
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 02cf6d6d36..044d920991 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
@@ -43,6 +43,7 @@ public class MetadataConstants {
     // Name of the pre-defined default dataverse
     public static final DataverseName DEFAULT_DATAVERSE_NAME = 
DataverseName.createBuiltinDataverseName("Default");
 
+    public static final Namespace METADATA_NAMESPACE = new 
Namespace(SYSTEM_DATABASE, METADATA_DATAVERSE_NAME);
     public static final Namespace DEFAULT_NAMESPACE = new 
Namespace(DEFAULT_DATABASE, DEFAULT_DATAVERSE_NAME);
 
     // Name of the node group where metadata is stored on.
diff --git 
a/asterixdb/asterix-common/src/main/java/org/apache/asterix/common/metadata/MetadataUtil.java
 
b/asterixdb/asterix-common/src/main/java/org/apache/asterix/common/metadata/MetadataUtil.java
index 06d12fa56b..539b8c4b43 100644
--- 
a/asterixdb/asterix-common/src/main/java/org/apache/asterix/common/metadata/MetadataUtil.java
+++ 
b/asterixdb/asterix-common/src/main/java/org/apache/asterix/common/metadata/MetadataUtil.java
@@ -46,6 +46,11 @@ public class MetadataUtil {
         return dataverseName + "." + objectName;
     }
 
+    public static String getFullyQualifiedDisplayName(String databaseName, 
DataverseName dataverseName,
+            String objectName) {
+        return databaseName + "." + dataverseName + "." + objectName;
+    }
+
     public static String databaseFor(DataverseName dataverse) {
         if (dataverse == null) {
             return null;
diff --git 
a/asterixdb/asterix-common/src/main/java/org/apache/asterix/common/metadata/NamespacePathResolver.java
 
b/asterixdb/asterix-common/src/main/java/org/apache/asterix/common/metadata/NamespacePathResolver.java
index 26d1ce06f9..910c3ef68f 100644
--- 
a/asterixdb/asterix-common/src/main/java/org/apache/asterix/common/metadata/NamespacePathResolver.java
+++ 
b/asterixdb/asterix-common/src/main/java/org/apache/asterix/common/metadata/NamespacePathResolver.java
@@ -19,6 +19,8 @@
 
 package org.apache.asterix.common.metadata;
 
+import java.io.File;
+
 import org.apache.asterix.common.api.INamespacePathResolver;
 import org.apache.asterix.common.utils.StoragePathUtil;
 
@@ -27,16 +29,32 @@ public class NamespacePathResolver implements 
INamespacePathResolver {
     private final boolean usingDatabase;
 
     public NamespacePathResolver(boolean usingDatabase) {
-        this.usingDatabase = false;
+        this.usingDatabase = usingDatabase;
     }
 
     @Override
     public String resolve(Namespace namespace) {
-        return 
StoragePathUtil.prepareDataverseName(namespace.getDataverseName());
+        DataverseName dataverseName = namespace.getDataverseName();
+        if (usingDatabase) {
+            if 
(MetadataConstants.METADATA_DATAVERSE_NAME.equals(dataverseName)) {
+                return StoragePathUtil.prepareDataverseName(dataverseName);
+            }
+            return namespace.getDatabaseName() + File.separatorChar
+                    + StoragePathUtil.prepareDataverseName(dataverseName);
+        } else {
+            return StoragePathUtil.prepareDataverseName(dataverseName);
+        }
     }
 
     @Override
     public String resolve(String databaseName, DataverseName dataverseName) {
-        return StoragePathUtil.prepareDataverseName(dataverseName);
+        if (usingDatabase) {
+            if 
(MetadataConstants.METADATA_DATAVERSE_NAME.equals(dataverseName)) {
+                return StoragePathUtil.prepareDataverseName(dataverseName);
+            }
+            return databaseName + File.separatorChar + 
StoragePathUtil.prepareDataverseName(dataverseName);
+        } else {
+            return StoragePathUtil.prepareDataverseName(dataverseName);
+        }
     }
 }
diff --git 
a/asterixdb/asterix-common/src/main/java/org/apache/asterix/common/metadata/NamespaceResolver.java
 
b/asterixdb/asterix-common/src/main/java/org/apache/asterix/common/metadata/NamespaceResolver.java
index b18562e738..d1d813e84f 100644
--- 
a/asterixdb/asterix-common/src/main/java/org/apache/asterix/common/metadata/NamespaceResolver.java
+++ 
b/asterixdb/asterix-common/src/main/java/org/apache/asterix/common/metadata/NamespaceResolver.java
@@ -29,7 +29,7 @@ public class NamespaceResolver implements INamespaceResolver {
     private final boolean usingDatabase;
 
     public NamespaceResolver(boolean usingDatabase) {
-        this.usingDatabase = false;
+        this.usingDatabase = usingDatabase;
     }
 
     @Override
@@ -42,13 +42,49 @@ public class NamespaceResolver implements 
INamespaceResolver {
         if (multiIdentifier == null) {
             return null;
         }
-        DataverseName dataverseName = DataverseName.create(multiIdentifier, 
fromIndex, toIndex);
-        return new Namespace(MetadataUtil.databaseFor(dataverseName), 
dataverseName);
+        if (usingDatabase) {
+            int partsNum = toIndex - fromIndex;
+            if (partsNum > 1) {
+                String databaseName = multiIdentifier.get(fromIndex);
+                return ofDatabase(databaseName, multiIdentifier, fromIndex + 
1, toIndex);
+            } else {
+                return ofDataverse(multiIdentifier, fromIndex, toIndex);
+            }
+        } else {
+            return ofDataverse(multiIdentifier, fromIndex, toIndex);
+        }
     }
 
     @Override
     public Namespace resolve(String namespace) throws AsterixException {
         DataverseName dataverseName = 
DataverseName.createFromCanonicalForm(namespace);
+        if (usingDatabase) {
+            List<String> parts = dataverseName.getParts();
+            if (parts.size() > 1) {
+                String databaseName = parts.get(0);
+                return ofDatabase(databaseName, parts, 1, parts.size());
+            } else {
+                return new Namespace(MetadataUtil.databaseFor(dataverseName), 
dataverseName);
+            }
+        } else {
+            return new Namespace(MetadataUtil.databaseFor(dataverseName), 
dataverseName);
+        }
+    }
+
+    @Override
+    public boolean isUsingDatabase() {
+        return usingDatabase;
+    }
+
+    private static Namespace ofDatabase(String databaseName, List<String> 
multiIdentifier, int fromIndex, int toIndex)
+            throws AsterixException {
+        DataverseName dataverseName = DataverseName.create(multiIdentifier, 
fromIndex, toIndex);
+        return new Namespace(databaseName, dataverseName);
+    }
+
+    private static Namespace ofDataverse(List<String> multiIdentifier, int 
fromIndex, int toIndex)
+            throws AsterixException {
+        DataverseName dataverseName = DataverseName.create(multiIdentifier, 
fromIndex, toIndex);
         return new Namespace(MetadataUtil.databaseFor(dataverseName), 
dataverseName);
     }
 }
diff --git 
a/asterixdb/asterix-common/src/main/java/org/apache/asterix/common/storage/DatasetCopyIdentifier.java
 
b/asterixdb/asterix-common/src/main/java/org/apache/asterix/common/storage/DatasetCopyIdentifier.java
index 6fea755c9b..4533361cf9 100644
--- 
a/asterixdb/asterix-common/src/main/java/org/apache/asterix/common/storage/DatasetCopyIdentifier.java
+++ 
b/asterixdb/asterix-common/src/main/java/org/apache/asterix/common/storage/DatasetCopyIdentifier.java
@@ -25,19 +25,22 @@ import org.apache.asterix.common.metadata.DataverseName;
 
 public class DatasetCopyIdentifier implements Serializable {
 
-    private static final long serialVersionUID = 1L;
+    private static final long serialVersionUID = 2L;
+    private final String database;
     private final DataverseName dataverse;
     private final String dataset;
     private final String rebalance;
 
-    private DatasetCopyIdentifier(DataverseName dataverse, String datasetName, 
String rebalance) {
+    private DatasetCopyIdentifier(String database, DataverseName dataverse, 
String datasetName, String rebalance) {
+        this.database = database;
         this.dataverse = dataverse;
         this.dataset = datasetName;
         this.rebalance = rebalance;
     }
 
-    public static DatasetCopyIdentifier of(DataverseName dataverse, String 
datasetName, String rebalance) {
-        return new DatasetCopyIdentifier(dataverse, datasetName, rebalance);
+    public static DatasetCopyIdentifier of(String database, DataverseName 
dataverse, String datasetName,
+            String rebalance) {
+        return new DatasetCopyIdentifier(database, dataverse, datasetName, 
rebalance);
     }
 
     public String getDataset() {
@@ -57,13 +60,13 @@ public class DatasetCopyIdentifier implements Serializable {
             return false;
         }
         DatasetCopyIdentifier that = (DatasetCopyIdentifier) o;
-        return Objects.equals(dataverse, that.dataverse) && 
Objects.equals(dataset, that.dataset)
-                && Objects.equals(rebalance, that.rebalance);
+        return Objects.equals(database, that.database) && 
Objects.equals(dataverse, that.dataverse)
+                && Objects.equals(dataset, that.dataset) && 
Objects.equals(rebalance, that.rebalance);
     }
 
     @Override
     public int hashCode() {
-        return Objects.hash(dataverse, dataset, rebalance);
+        return Objects.hash(database, dataverse, dataset, rebalance);
     }
 
     public DataverseName getDataverse() {
@@ -71,8 +74,8 @@ public class DatasetCopyIdentifier implements Serializable {
     }
 
     public boolean isMatch(ResourceReference resourceReference) {
-        return resourceReference.getDataverse().equals(dataverse) && 
resourceReference.getDataset().equals(dataset)
-                && resourceReference.getRebalance().equals(rebalance);
+        return resourceReference.getDatabase().equals(database) && 
resourceReference.getDataverse().equals(dataverse)
+                && resourceReference.getDataset().equals(dataset) && 
resourceReference.getRebalance().equals(rebalance);
     }
 
     @Override
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 7065767cd5..a163ece942 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
@@ -27,6 +27,7 @@ import java.util.List;
 
 import org.apache.asterix.common.exceptions.AsterixException;
 import org.apache.asterix.common.metadata.DataverseName;
+import org.apache.asterix.common.metadata.MetadataUtil;
 import org.apache.asterix.common.utils.StorageConstants;
 import org.apache.asterix.common.utils.StoragePathUtil;
 import org.apache.commons.lang3.ArrayUtils;
@@ -40,6 +41,7 @@ public class ResourceReference {
     private static final Logger LOGGER = LogManager.getLogger();
     protected final String root;
     protected final String partition;
+    protected final String database;
     protected final DataverseName dataverse;
     protected final String dataset;
     protected final String rebalance;
@@ -68,12 +70,19 @@ public class ResourceReference {
         String probablyPartition = tokens[--offset];
         if (dvParts.isEmpty()) {
             // root/partition/dataverse/dataset/rebalanceCount/index/fileName
+            // 
root/partition/database?/dataverse/dataset/rebalanceCount/index/fileName
             try {
                 dataverse = DataverseName.createSinglePartName(dvPart);
             } catch (AsterixException e) {
                 throw new IllegalArgumentException("unable to parse path: '" + 
path + "'!", e);
             }
-            partition = probablyPartition;
+            if 
(!probablyPartition.startsWith(StorageConstants.PARTITION_DIR_PREFIX)) {
+                database = probablyPartition;
+                partition = tokens[--offset];
+            } else {
+                database = MetadataUtil.databaseFor(dataverse);
+                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
@@ -84,6 +93,7 @@ public class ResourceReference {
             } catch (AsterixException e) {
                 throw new IllegalArgumentException("unable to parse path: '" + 
path + "'!", e);
             }
+            database = MetadataUtil.databaseFor(dataverse);
             partition = probablyPartition;
             root = tokens[--offset];
         } else if (dvPart.startsWith(StorageConstants.PARTITION_DIR_PREFIX)) {
@@ -99,6 +109,7 @@ public class ResourceReference {
             }
             LOGGER.info("legacy dataverse starting with ^ found: '{}'; this is 
not supported for new dataverses",
                     dataverse);
+            database = MetadataUtil.databaseFor(dataverse);
             partition = dvPart;
             root = probablyPartition;
         } else {
@@ -119,6 +130,10 @@ public class ResourceReference {
         return partition;
     }
 
+    public String getDatabase() {
+        return database;
+    }
+
     public DataverseName getDataverse() {
         return dataverse;
     }
diff --git 
a/asterixdb/asterix-common/src/main/resources/asx_errormsg/en.properties 
b/asterixdb/asterix-common/src/main/resources/asx_errormsg/en.properties
index 3f61b85359..ab77067ca0 100644
--- a/asterixdb/asterix-common/src/main/resources/asx_errormsg/en.properties
+++ b/asterixdb/asterix-common/src/main/resources/asx_errormsg/en.properties
@@ -281,6 +281,8 @@
 1182 = Failed to calculate computed fields: %1$s
 1183 = Failed to evaluate computed field. File: '%1$s'. Computed Field Name: 
'%2$s'. Computed Field Type: '%3$s'. Computed Field Value: '%4$s'. Reason: 
'%5$s'
 1184 = Compilation error: %1$s: %2$s dataset is not supported on datasets with 
meta records
+1185 = Cannot find database with name %1$s
+1186 = A database with this name %1$s already exists
 
 # Feed Errors
 3001 = Illegal state.
diff --git 
a/asterixdb/asterix-common/src/test/java/org/apache/asterix/test/ioopcallbacks/LSMIOOperationCallbackTest.java
 
b/asterixdb/asterix-common/src/test/java/org/apache/asterix/test/ioopcallbacks/LSMIOOperationCallbackTest.java
index 33d513f7e4..befdd1a915 100644
--- 
a/asterixdb/asterix-common/src/test/java/org/apache/asterix/test/ioopcallbacks/LSMIOOperationCallbackTest.java
+++ 
b/asterixdb/asterix-common/src/test/java/org/apache/asterix/test/ioopcallbacks/LSMIOOperationCallbackTest.java
@@ -21,6 +21,7 @@ package org.apache.asterix.test.ioopcallbacks;
 
 import static 
org.apache.hyracks.storage.am.lsm.common.impls.LSMComponentId.MIN_VALID_COMPONENT_ID;
 
+import java.io.File;
 import java.util.HashMap;
 import java.util.Map;
 
@@ -91,7 +92,9 @@ public class LSMIOOperationCallbackTest extends TestCase {
         flushMap.put(LSMIOOperationCallback.KEY_NEXT_COMPONENT_ID, 
nextComponentId);
         ILSMIndexAccessor firstAccessor = new TestLSMIndexAccessor(new 
TestLSMIndexOperationContext(mockIndex));
         firstAccessor.getOpContext().setParameters(flushMap);
-        FileReference firstTarget = new 
FileReference(Mockito.mock(IODeviceHandle.class), getComponentFileName());
+        IODeviceHandle mockIoDevice = Mockito.mock(IODeviceHandle.class);
+        Mockito.when(mockIoDevice.getMount()).thenReturn(new 
File(getIndexPath()));
+        FileReference firstTarget = new FileReference(mockIoDevice, 
getComponentFileName());
         LSMComponentFileReferences firstFiles = new 
LSMComponentFileReferences(firstTarget, firstTarget, firstTarget);
         FlushOperation firstFlush = new TestFlushOperation(firstAccessor, 
firstTarget, callback, indexId, firstFiles,
                 new LSMComponentId(0, 0));
@@ -107,7 +110,7 @@ public class LSMIOOperationCallbackTest extends TestCase {
         flushMap.put(LSMIOOperationCallback.KEY_NEXT_COMPONENT_ID, 
nextComponentId);
         ILSMIndexAccessor secondAccessor = new TestLSMIndexAccessor(new 
TestLSMIndexOperationContext(mockIndex));
         secondAccessor.getOpContext().setParameters(flushMap);
-        FileReference secondTarget = new 
FileReference(Mockito.mock(IODeviceHandle.class), getComponentFileName());
+        FileReference secondTarget = new FileReference(mockIoDevice, 
getComponentFileName());
         LSMComponentFileReferences secondFiles =
                 new LSMComponentFileReferences(secondTarget, secondTarget, 
secondTarget);
         FlushOperation secondFlush = new TestFlushOperation(secondAccessor, 
secondTarget, callback, indexId,
@@ -173,6 +176,8 @@ public class LSMIOOperationCallbackTest extends TestCase {
         callback.recycled(mockComponent);
         checkMemoryComponent(id, mockComponent);
 
+        IODeviceHandle mockIoDevice = Mockito.mock(IODeviceHandle.class);
+        Mockito.when(mockIoDevice.getMount()).thenReturn(new 
File(getIndexPath()));
         Mockito.when(mockIndex.isMemoryComponentsAllocated()).thenReturn(true);
         for (int i = 0; i < 100; i++) {
             // schedule a flush
@@ -184,7 +189,7 @@ public class LSMIOOperationCallbackTest extends TestCase {
             flushMap.put(LSMIOOperationCallback.KEY_NEXT_COMPONENT_ID, 
expectedId);
             ILSMIndexAccessor accessor = new TestLSMIndexAccessor(new 
TestLSMIndexOperationContext(mockIndex));
             accessor.getOpContext().setParameters(flushMap);
-            FileReference target = new 
FileReference(Mockito.mock(IODeviceHandle.class), getComponentFileName());
+            FileReference target = new FileReference(mockIoDevice, 
getComponentFileName());
             LSMComponentFileReferences files = new 
LSMComponentFileReferences(target, target, target);
             FlushOperation flush =
                     new TestFlushOperation(accessor, target, callback, 
indexId, files, new LSMComponentId(0, 0));
diff --git 
a/asterixdb/asterix-lang-common/src/main/java/org/apache/asterix/lang/common/base/IQueryRewriter.java
 
b/asterixdb/asterix-lang-common/src/main/java/org/apache/asterix/lang/common/base/IQueryRewriter.java
index 6099cb6d96..12c3b93269 100644
--- 
a/asterixdb/asterix-lang-common/src/main/java/org/apache/asterix/lang/common/base/IQueryRewriter.java
+++ 
b/asterixdb/asterix-lang-common/src/main/java/org/apache/asterix/lang/common/base/IQueryRewriter.java
@@ -21,6 +21,7 @@ package org.apache.asterix.lang.common.base;
 import java.util.Collection;
 import java.util.Set;
 
+import org.apache.asterix.common.api.INamespaceResolver;
 import org.apache.asterix.common.exceptions.CompilationException;
 import org.apache.asterix.lang.common.expression.AbstractCallExpression;
 import org.apache.asterix.lang.common.expression.VariableExpr;
@@ -64,5 +65,5 @@ public interface IQueryRewriter {
 
     Query createFunctionAccessorQuery(FunctionDecl functionDecl);
 
-    Query createViewAccessorQuery(ViewDecl viewDecl);
+    Query createViewAccessorQuery(ViewDecl viewDecl, INamespaceResolver 
namespaceResolver);
 }
diff --git 
a/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/rewrites/SqlppQueryRewriter.java
 
b/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/rewrites/SqlppQueryRewriter.java
index 0ce09e54ab..bad48c29b4 100644
--- 
a/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/rewrites/SqlppQueryRewriter.java
+++ 
b/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/rewrites/SqlppQueryRewriter.java
@@ -28,6 +28,7 @@ import java.util.List;
 import java.util.Map;
 import java.util.Set;
 
+import org.apache.asterix.common.api.INamespaceResolver;
 import org.apache.asterix.common.exceptions.CompilationException;
 import org.apache.asterix.common.exceptions.ErrorCode;
 import org.apache.asterix.common.functions.FunctionSignature;
@@ -603,22 +604,34 @@ public class SqlppQueryRewriter implements IQueryRewriter 
{
     }
 
     @Override
-    public Query createViewAccessorQuery(ViewDecl viewDecl) {
+    public Query createViewAccessorQuery(ViewDecl viewDecl, INamespaceResolver 
namespaceResolver) {
+        boolean usingDatabase = namespaceResolver.isUsingDatabase();
         // dataverse_name.view_name
+        String databaseName = viewDecl.getViewName().getDatabaseName();
         DataverseName dataverseName = 
viewDecl.getViewName().getDataverseName();
         String viewName = viewDecl.getViewName().getDatasetName();
-        Expression vAccessExpr = createDatasetAccessExpression(dataverseName, 
viewName, viewDecl.getSourceLocation());
+        Expression vAccessExpr = createDatasetAccessExpression(databaseName, 
dataverseName, viewName,
+                viewDecl.getSourceLocation(), usingDatabase);
         return ExpressionUtils.createWrappedQuery(vAccessExpr, 
viewDecl.getSourceLocation());
     }
 
-    private static Expression createDatasetAccessExpression(DataverseName 
dataverseName, String datasetName,
-            SourceLocation sourceLoc) {
-        AbstractExpression resultExpr = null;
+    private static Expression createDatasetAccessExpression(String 
databaseName, DataverseName dataverseName,
+            String datasetName, SourceLocation sourceLoc, boolean 
usingDatabase) {
+        AbstractExpression resultExpr;
         List<String> dataverseNameParts = dataverseName.getParts();
-        for (int i = 0, n = dataverseNameParts.size(); i < n; i++) {
+        int startIdx;
+        if (usingDatabase) {
+            resultExpr = new VariableExpr(new 
VarIdentifier(SqlppVariableUtil.toInternalVariableName(databaseName)));
+            startIdx = 0;
+        } else {
+            resultExpr = new VariableExpr(
+                    new 
VarIdentifier(SqlppVariableUtil.toInternalVariableName(dataverseNameParts.get(0))));
+            startIdx = 1;
+        }
+        resultExpr.setSourceLocation(sourceLoc);
+        for (int i = startIdx, n = dataverseNameParts.size(); i < n; i++) {
             String part = dataverseNameParts.get(i);
-            resultExpr = i == 0 ? new VariableExpr(new 
VarIdentifier(SqlppVariableUtil.toInternalVariableName(part)))
-                    : new FieldAccessor(resultExpr, new Identifier(part));
+            resultExpr = new FieldAccessor(resultExpr, new Identifier(part));
             resultExpr.setSourceLocation(sourceLoc);
         }
         resultExpr = new FieldAccessor(resultExpr, new 
Identifier(datasetName));
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 27a63d2d7a..97a41712ad 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
@@ -126,15 +126,16 @@ public class VariableCheckAndRewriteVisitor extends 
AbstractSqlppExpressionScopi
                 if (resolveAsVariableReference(topVarExpr)) {
                     return fa;
                 } else {
-                    DataverseName dataverseName;
+                    Namespace namespace;
                     try {
-                        dataverseName = 
DataverseName.create(dataverseNameParts);
+                        namespace = 
metadataProvider.resolve(dataverseNameParts);
                     } catch (AsterixException e) {
                         throw new 
CompilationException(ErrorCode.INVALID_DATABASE_OBJECT_NAME, 
fa.getSourceLocation(),
                                 dataverseNameParts.toString());
                     }
                     //TODO(DB): decide
-                    String databaseName = MetadataUtil.resolveDatabase(null, 
dataverseName);
+                    String databaseName = namespace.getDatabaseName();
+                    DataverseName dataverseName = namespace.getDataverseName();
                     String datasetName = fa.getIdent().getValue();
                     CallExpr datasetExpr =
                             resolveAsDataset(databaseName, dataverseName, 
datasetName, parent, topVarExpr);
diff --git 
a/asterixdb/asterix-metadata/src/main/java/org/apache/asterix/metadata/MetadataNode.java
 
b/asterixdb/asterix-metadata/src/main/java/org/apache/asterix/metadata/MetadataNode.java
index cc1251bd96..5383ac96ba 100644
--- 
a/asterixdb/asterix-metadata/src/main/java/org/apache/asterix/metadata/MetadataNode.java
+++ 
b/asterixdb/asterix-metadata/src/main/java/org/apache/asterix/metadata/MetadataNode.java
@@ -40,6 +40,7 @@ import org.apache.asterix.common.exceptions.MetadataException;
 import org.apache.asterix.common.functions.FunctionSignature;
 import org.apache.asterix.common.metadata.DataverseName;
 import org.apache.asterix.common.metadata.DependencyFullyQualifiedName;
+import org.apache.asterix.common.metadata.MetadataConstants;
 import org.apache.asterix.common.metadata.MetadataIndexImmutableProperties;
 import org.apache.asterix.common.metadata.MetadataUtil;
 import org.apache.asterix.common.transactions.IRecoveryManager.ResourceType;
@@ -63,6 +64,7 @@ import org.apache.asterix.metadata.api.IMetadataExtension;
 import org.apache.asterix.metadata.api.IMetadataIndex;
 import org.apache.asterix.metadata.api.IMetadataNode;
 import org.apache.asterix.metadata.api.IValueExtractor;
+import org.apache.asterix.metadata.bootstrap.MetadataBuiltinEntities;
 import org.apache.asterix.metadata.bootstrap.MetadataIndexesProvider;
 import org.apache.asterix.metadata.entities.CompactionPolicy;
 import org.apache.asterix.metadata.entities.Database;
@@ -354,13 +356,15 @@ public class MetadataNode implements IMetadataNode {
     @Override
     public void addDatabase(TxnId txnId, Database database) throws 
AlgebricksException, RemoteException {
         try {
+            if (!mdIndexesProvider.isUsingDatabase()) {
+                return;
+            }
             DatabaseTupleTranslator tupleReaderWriter = 
tupleTranslatorProvider.getDatabaseTupleTranslator(true);
             ITupleReference tuple = 
tupleReaderWriter.getTupleFromMetadataEntity(database);
             insertTupleIntoIndex(txnId, 
mdIndexesProvider.getDatabaseEntity().getIndex(), tuple);
         } catch (HyracksDataException e) {
             if (e.matches(ErrorCode.DUPLICATE_KEY)) {
-                //TODO(DB): change to database
-                throw new 
AsterixException(org.apache.asterix.common.exceptions.ErrorCode.DATAVERSE_EXISTS,
 e,
+                throw new 
AsterixException(org.apache.asterix.common.exceptions.ErrorCode.DATABASE_EXISTS,
 e,
                         database.getDatabaseName());
             } else {
                 throw new AlgebricksException(e);
@@ -699,6 +703,9 @@ public class MetadataNode implements IMetadataNode {
     @Override
     public void dropDatabase(TxnId txnId, String databaseName) throws 
AlgebricksException, RemoteException {
         try {
+            if (!mdIndexesProvider.isUsingDatabase()) {
+                return;
+            }
             //TODO(DB): review
             confirmDatabaseCanBeDeleted(txnId, databaseName);
 
@@ -1123,6 +1130,9 @@ public class MetadataNode implements IMetadataNode {
     @Override
     public Database getDatabase(TxnId txnId, String databaseName) throws 
AlgebricksException {
         try {
+            if (!mdIndexesProvider.isUsingDatabase()) {
+                return defaultDatabase(databaseName);
+            }
             ITupleReference searchKey = createTuple(databaseName);
             DatabaseTupleTranslator tupleReaderWriter = 
tupleTranslatorProvider.getDatabaseTupleTranslator(false);
             IValueExtractor<Database> valueExtractor = new 
MetadataEntityValueExtractor<>(tupleReaderWriter);
@@ -2995,4 +3005,13 @@ public class MetadataNode implements IMetadataNode {
     public ITxnIdFactory getTxnIdFactory() {
         return txnIdFactory;
     }
+
+    private Database defaultDatabase(String databaseName) {
+        //TODO(DB): review
+        if (MetadataConstants.SYSTEM_DATABASE.equals(databaseName)) {
+            return MetadataBuiltinEntities.SYSTEM_DATABASE;
+        } else {
+            return MetadataBuiltinEntities.DEFAULT_DATABASE;
+        }
+    }
 }
diff --git 
a/asterixdb/asterix-metadata/src/main/java/org/apache/asterix/metadata/utils/DatasetUtil.java
 
b/asterixdb/asterix-metadata/src/main/java/org/apache/asterix/metadata/utils/DatasetUtil.java
index 73797d8096..4d1c4a656b 100644
--- 
a/asterixdb/asterix-metadata/src/main/java/org/apache/asterix/metadata/utils/DatasetUtil.java
+++ 
b/asterixdb/asterix-metadata/src/main/java/org/apache/asterix/metadata/utils/DatasetUtil.java
@@ -628,6 +628,11 @@ public class DatasetUtil {
         return MetadataUtil.getFullyQualifiedDisplayName(dataverseName, 
datasetName);
     }
 
+    public static String getFullyQualifiedDisplayName(String databaseName, 
DataverseName dataverseName,
+            String datasetName) {
+        return MetadataUtil.getFullyQualifiedDisplayName(databaseName, 
dataverseName, datasetName);
+    }
+
     /***
      * Creates a node group that is associated with a new dataset.
      *

Reply via email to