[ASTERIXDB-3259][MTD] Pass 'database' to metadata entities

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

Details:
Ensure 'database' is present in metadata entities.

- default to 'System' database for 'Metadata' dataverse
- default to 'Default' database for all other dataverses

Change-Id: If92a58f2269874842d7d95203369a4e27f43fa86
Reviewed-on: https://asterix-gerrit.ics.uci.edu/c/asterixdb/+/17789
Integration-Tests: Jenkins <jenkins@fulliautomatix.ics.uci.edu>
Tested-by: Jenkins <jenkins@fulliautomatix.ics.uci.edu>
Reviewed-by: Ali Alsuliman <ali.al.solaiman@gmail.com>
Reviewed-by: Murtadha Hubail <mhubail@apache.org>
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 d32d7a9..3a95595 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
@@ -208,7 +208,6 @@
 import org.apache.asterix.om.utils.RecordUtil;
 import org.apache.asterix.runtime.fulltext.AbstractFullTextFilterDescriptor;
 import org.apache.asterix.runtime.fulltext.FullTextConfigDescriptor;
-import org.apache.asterix.runtime.fulltext.IFullTextFilterDescriptor;
 import org.apache.asterix.runtime.fulltext.StopwordsFullTextFilterDescriptor;
 import org.apache.asterix.runtime.operators.DatasetStreamStats;
 import org.apache.asterix.transaction.management.service.transaction.DatasetIdFactory;
@@ -594,7 +593,7 @@
         metadataProvider.setMetadataTxnContext(mdTxnCtx);
         try {
             DataverseName dvName = stmtUseDataverse.getDataverseName();
-            String database = null;
+            String database = MetadataUtil.resolveDatabase(null, dvName);
             Dataverse dv =
                     MetadataManager.INSTANCE.getDataverse(metadataProvider.getMetadataTxnContext(), database, dvName);
             if (dv == null) {
@@ -641,7 +640,7 @@
         metadataProvider.setMetadataTxnContext(mdTxnCtx);
         try {
             DataverseName dvName = stmtCreateDataverse.getDataverseName();
-            String database = null;
+            String database = MetadataUtil.resolveDatabase(null, dvName);
             Dataverse dv =
                     MetadataManager.INSTANCE.getDataverse(metadataProvider.getMetadataTxnContext(), database, dvName);
             if (dv != null) {
@@ -654,7 +653,7 @@
                 }
             }
             MetadataManager.INSTANCE.addDataverse(metadataProvider.getMetadataTxnContext(),
-                    new Dataverse(dvName, stmtCreateDataverse.getFormat(), MetadataUtil.PENDING_NO_OP));
+                    new Dataverse(database, dvName, stmtCreateDataverse.getFormat(), MetadataUtil.PENDING_NO_OP));
             MetadataManager.INSTANCE.commitTransaction(mdTxnCtx);
             return true;
         } catch (Exception e) {
@@ -766,7 +765,7 @@
             TypeExpression itemTypeExpr, String itemTypeName, TypeExpression metaItemTypeExpr,
             DataverseName metaItemTypeDataverseName, String metaItemTypeName, IHyracksClientConnection hcc,
             IRequestParameters requestParameters) throws Exception {
-        String database = null;
+        String database = MetadataUtil.resolveDatabase(null, dataverseName);
         MutableObject<ProgressState> progress = new MutableObject<>(ProgressState.NO_PROGRESS);
         SourceLocation sourceLoc = dd.getSourceLocation();
         DatasetType dsType = dd.getDatasetType();
@@ -894,9 +893,9 @@
             }
 
             // #. add a new dataset with PendingAddOp
-            dataset = (Dataset) createDataset(dd, dataverseName, datasetName, itemTypeDataverseName, itemTypeName,
-                    metaItemTypeDataverseName, metaItemTypeName, dsType, compactionPolicy, compactionPolicyProperties,
-                    compressionScheme, datasetFormatInfo, datasetDetails, ngName);
+            dataset = (Dataset) createDataset(dd, database, dataverseName, datasetName, itemTypeDataverseName,
+                    itemTypeName, metaItemTypeDataverseName, metaItemTypeName, dsType, compactionPolicy,
+                    compactionPolicyProperties, compressionScheme, datasetFormatInfo, datasetDetails, ngName);
             MetadataManager.INSTANCE.addDataset(metadataProvider.getMetadataTxnContext(), dataset);
 
             if (itemTypeIsInline) {
@@ -988,16 +987,16 @@
         return Optional.of(dataset);
     }
 
-    protected IDataset createDataset(DatasetDecl dd, DataverseName dataverseName, String datasetName,
+    protected IDataset createDataset(DatasetDecl dd, String database, DataverseName dataverseName, String datasetName,
             DataverseName itemTypeDataverseName, String itemTypeName, DataverseName metaItemTypeDataverseName,
             String metaItemTypeName, DatasetType dsType, String compactionPolicy,
             Map<String, String> compactionPolicyProperties, String compressionScheme,
             DatasetFormatInfo datasetFormatInfo, IDatasetDetails datasetDetails, String ngName)
             throws AlgebricksException {
-        return new Dataset(dataverseName, datasetName, itemTypeDataverseName, itemTypeName, metaItemTypeDataverseName,
-                metaItemTypeName, ngName, compactionPolicy, compactionPolicyProperties, datasetDetails, dd.getHints(),
-                dsType, DatasetIdFactory.generateDatasetId(), MetadataUtil.PENDING_ADD_OP, compressionScheme,
-                datasetFormatInfo);
+        return new Dataset(database, dataverseName, datasetName, itemTypeDataverseName, itemTypeName,
+                metaItemTypeDataverseName, metaItemTypeName, ngName, compactionPolicy, compactionPolicyProperties,
+                datasetDetails, dd.getHints(), dsType, DatasetIdFactory.generateDatasetId(),
+                MetadataUtil.PENDING_ADD_OP, compressionScheme, datasetFormatInfo);
     }
 
     protected Triple<DataverseName, String, Boolean> extractDatasetItemTypeName(DataverseName datasetDataverseName,
@@ -1024,6 +1023,7 @@
             DataverseName itemTypeDataverseName, String itemTypeName, TypeExpression itemTypeExpr,
             boolean isMetaItemType, MetadataProvider metadataProvider, SourceLocation sourceLoc)
             throws AlgebricksException {
+        String itemTypeDatabase = MetadataUtil.resolveDatabase(null, itemTypeDataverseName);
         switch (itemTypeExpr.getTypeKind()) {
             case TYPEREFERENCE:
                 Datatype itemTypeEntity = metadataProvider.findTypeEntity(itemTypeDataverseName, itemTypeName);
@@ -1038,7 +1038,7 @@
             case RECORD:
                 itemType = translateType(itemTypeDataverseName, itemTypeName, itemTypeExpr, mdTxnCtx);
                 validateDatasetItemType(datasetType, itemType, isMetaItemType, sourceLoc);
-                itemTypeEntity = new Datatype(itemTypeDataverseName, itemTypeName, itemType, true);
+                itemTypeEntity = new Datatype(itemTypeDatabase, itemTypeDataverseName, itemTypeName, itemType, true);
                 return new Pair<>(itemTypeEntity, true);
             default:
                 throw new CompilationException(ErrorCode.COMPILATION_ILLEGAL_STATE, sourceLoc,
@@ -1133,7 +1133,7 @@
     protected void doCreateIndex(MetadataProvider metadataProvider, CreateIndexStatement stmtCreateIndex,
             DataverseName dataverseName, String datasetName, IHyracksClientConnection hcc,
             IRequestParameters requestParameters) throws Exception {
-        String database = null;
+        String database = MetadataUtil.resolveDatabase(null, dataverseName);
         SourceLocation sourceLoc = stmtCreateIndex.getSourceLocation();
         MetadataTransactionContext mdTxnCtx = MetadataManager.INSTANCE.beginTransaction();
         boolean bActiveTxn = true;
@@ -1452,7 +1452,7 @@
                 }
             }
 
-            Index newIndex = new Index(dataverseName, datasetName, indexName, indexType, indexDetails,
+            Index newIndex = new Index(database, dataverseName, datasetName, indexName, indexType, indexDetails,
                     stmtCreateIndex.isEnforced(), false, MetadataUtil.PENDING_ADD_OP);
 
             bActiveTxn = false; // doCreateIndexImpl() takes over the current transaction
@@ -1488,7 +1488,7 @@
     protected void doCreateFullTextFilter(MetadataProvider metadataProvider,
             CreateFullTextFilterStatement stmtCreateFilter, DataverseName dataverseName) throws Exception {
         AbstractFullTextFilterDescriptor filterDescriptor;
-        String database = null;
+        String database = MetadataUtil.resolveDatabase(null, dataverseName);
         String filterType = stmtCreateFilter.getFilterType();
         if (filterType == null) {
             throw new CompilationException(ErrorCode.PARSE_ERROR, stmtCreateFilter.getSourceLocation(),
@@ -1496,8 +1496,8 @@
         }
 
         if (FIELD_TYPE_STOPWORDS.equals(filterType)) {
-            filterDescriptor = new StopwordsFullTextFilterDescriptor(dataverseName, stmtCreateFilter.getFilterName(),
-                    stmtCreateFilter.getStopwordsList());
+            filterDescriptor = new StopwordsFullTextFilterDescriptor(database, dataverseName,
+                    stmtCreateFilter.getFilterName(), stmtCreateFilter.getStopwordsList());
         } else {
             throw new CompilationException(ErrorCode.COMPILATION_ERROR, stmtCreateFilter.getSourceLocation(),
                     "Unexpected full-text filter type: " + filterType);
@@ -1557,7 +1557,7 @@
     protected void doCreateFullTextConfig(MetadataProvider metadataProvider,
             CreateFullTextConfigStatement stmtCreateConfig, DataverseName dataverseName, String configName,
             ImmutableList<String> filterNames) throws Exception {
-        String database = null;
+        String database = MetadataUtil.resolveDatabase(null, dataverseName);
         MetadataTransactionContext mdTxnCtx = MetadataManager.INSTANCE.beginTransaction();
         metadataProvider.setMetadataTxnContext(mdTxnCtx);
 
@@ -1574,7 +1574,6 @@
                 }
             }
 
-            ImmutableList.Builder<IFullTextFilterDescriptor> filterDescriptorsBuilder = ImmutableList.builder();
             for (String filterName : filterNames) {
                 FullTextFilterMetadataEntity filterMetadataEntity =
                         MetadataManager.INSTANCE.getFullTextFilter(mdTxnCtx, database, dataverseName, filterName);
@@ -1586,7 +1585,7 @@
 
             TokenizerCategory tokenizerCategory = stmtCreateConfig.getTokenizerCategory();
             FullTextConfigDescriptor configDescriptor =
-                    new FullTextConfigDescriptor(dataverseName, configName, tokenizerCategory, filterNames);
+                    new FullTextConfigDescriptor(database, dataverseName, configName, tokenizerCategory, filterNames);
             FullTextConfigMetadataEntity configMetadataEntity = new FullTextConfigMetadataEntity(configDescriptor);
 
             MetadataManager.INSTANCE.addFullTextConfig(mdTxnCtx, configMetadataEntity);
@@ -1781,8 +1780,8 @@
         SourceLocation sourceLoc = stmtCreateType.getSourceLocation();
         String typeName = stmtCreateType.getIdent().getValue();
         metadataProvider.validateDatabaseObjectName(stmtCreateType.getDataverseName(), typeName, sourceLoc);
-        String database = null;
         DataverseName dataverseName = getActiveDataverseName(stmtCreateType.getDataverseName());
+        String database = MetadataUtil.resolveDatabase(null, dataverseName);
         if (isCompileOnly()) {
             return;
         }
@@ -1808,7 +1807,8 @@
                             "Reserved type name " + typeName + ".");
                 } else {
                     IAType type = translateType(dataverseName, typeName, stmtCreateType.getTypeDef(), mdTxnCtx);
-                    MetadataManager.INSTANCE.addDatatype(mdTxnCtx, new Datatype(dataverseName, typeName, type, false));
+                    MetadataManager.INSTANCE.addDatatype(mdTxnCtx,
+                            new Datatype(database, dataverseName, typeName, type, false));
                 }
             }
             MetadataManager.INSTANCE.commitTransaction(mdTxnCtx);
@@ -1854,7 +1854,7 @@
             IHyracksClientConnection hcc, IRequestParameters requestParameters) throws Exception {
         SourceLocation sourceLoc = stmtDropDataverse.getSourceLocation();
         DataverseName dataverseName = stmtDropDataverse.getDataverseName();
-        String database = null;
+        String database = MetadataUtil.resolveDatabase(null, dataverseName);
         ProgressState progress = ProgressState.NO_PROGRESS;
         MetadataTransactionContext mdTxnCtx = MetadataManager.INSTANCE.beginTransaction();
         boolean bActiveTxn = true;
@@ -1929,7 +1929,7 @@
             // Note: the delete operation fails if the dataverse cannot be deleted due to metadata dependencies
             MetadataManager.INSTANCE.dropDataverse(mdTxnCtx, database, dataverseName);
             MetadataManager.INSTANCE.addDataverse(mdTxnCtx,
-                    new Dataverse(dataverseName, dv.getDataFormat(), MetadataUtil.PENDING_DROP_OP));
+                    new Dataverse(database, dataverseName, dv.getDataFormat(), MetadataUtil.PENDING_DROP_OP));
 
             MetadataManager.INSTANCE.commitTransaction(mdTxnCtx);
             bActiveTxn = false;
@@ -2043,7 +2043,7 @@
     protected boolean doDropDataset(DataverseName dataverseName, String datasetName, MetadataProvider metadataProvider,
             boolean ifExists, IHyracksClientConnection hcc, IRequestParameters requestParameters,
             boolean dropCorrespondingNodeGroup, SourceLocation sourceLoc) throws Exception {
-        String database = null;
+        String database = MetadataUtil.resolveDatabase(null, dataverseName);
         MutableObject<ProgressState> progress = new MutableObject<>(ProgressState.NO_PROGRESS);
         MutableObject<MetadataTransactionContext> mdTxnCtx =
                 new MutableObject<>(MetadataManager.INSTANCE.beginTransaction());
@@ -2152,7 +2152,7 @@
     protected boolean doDropIndex(MetadataProvider metadataProvider, IndexDropStatement stmtIndexDrop,
             DataverseName dataverseName, String datasetName, IHyracksClientConnection hcc,
             IRequestParameters requestParameters) throws Exception {
-        String database = null;
+        String database = MetadataUtil.resolveDatabase(null, dataverseName);
         SourceLocation sourceLoc = stmtIndexDrop.getSourceLocation();
         String indexName = stmtIndexDrop.getIndexName().getValue();
         ProgressState progress = ProgressState.NO_PROGRESS;
@@ -2257,7 +2257,7 @@
 
     protected void doDropFullTextFilter(MetadataProvider metadataProvider, FullTextFilterDropStatement stmtFilterDrop,
             DataverseName dataverseName, String fullTextFilterName) throws AlgebricksException, RemoteException {
-        String database = null;
+        String database = MetadataUtil.resolveDatabase(null, dataverseName);
         MetadataTransactionContext mdTxnCtx = MetadataManager.INSTANCE.beginTransaction();
         metadataProvider.setMetadataTxnContext(mdTxnCtx);
         try {
@@ -2308,8 +2308,8 @@
                     stmtConfigDrop.getSourceLocation());
         }
 
-        String database = null;
         DataverseName dataverseName = getActiveDataverseName(stmtConfigDrop.getDataverseName());
+        String database = MetadataUtil.resolveDatabase(null, dataverseName);
         MetadataTransactionContext mdTxnCtx = MetadataManager.INSTANCE.beginTransaction();
         metadataProvider.setMetadataTxnContext(mdTxnCtx);
         String fullTextConfigName = stmtConfigDrop.getConfigName();
@@ -2340,8 +2340,8 @@
         SourceLocation sourceLoc = stmtTypeDrop.getSourceLocation();
         String typeName = stmtTypeDrop.getTypeName().getValue();
         metadataProvider.validateDatabaseObjectName(stmtTypeDrop.getDataverseName(), typeName, sourceLoc);
-        String database = null;
         DataverseName dataverseName = getActiveDataverseName(stmtTypeDrop.getDataverseName());
+        String database = MetadataUtil.resolveDatabase(null, dataverseName);
         if (isCompileOnly()) {
             return;
         }
@@ -2450,7 +2450,7 @@
     protected CreateResult doCreateView(MetadataProvider metadataProvider, CreateViewStatement cvs,
             DataverseName dataverseName, String viewName, DataverseName itemTypeDataverseName, String itemTypeName,
             IStatementRewriter stmtRewriter, IRequestParameters requestParameters) throws Exception {
-        String database = null;
+        String database = MetadataUtil.resolveDatabase(null, dataverseName);
         SourceLocation sourceLoc = cvs.getSourceLocation();
         MetadataTransactionContext mdTxnCtx = MetadataManager.INSTANCE.beginTransaction();
         metadataProvider.setMetadataTxnContext(mdTxnCtx);
@@ -2603,7 +2603,7 @@
             ViewDetails viewDetails = new ViewDetails(cvs.getViewBody(), dependencies, cvs.getDefaultNull(),
                     primaryKeyFields, foreignKeys, datetimeFormat, dateFormat, timeFormat);
 
-            Dataset view = new Dataset(dataverseName, viewName, itemTypeDataverseName, itemTypeName,
+            Dataset view = new Dataset(database, dataverseName, viewName, itemTypeDataverseName, itemTypeName,
                     MetadataConstants.METADATA_NODEGROUP_NAME, "", Collections.emptyMap(), viewDetails,
                     Collections.emptyMap(), DatasetType.VIEW, 0, MetadataUtil.PENDING_NO_OP);
             if (existingDataset == null) {
@@ -2644,7 +2644,7 @@
 
     protected boolean doDropView(MetadataProvider metadataProvider, ViewDropStatement stmtViewDrop,
             DataverseName dataverseName, String viewName) throws Exception {
-        String database = null;
+        String database = MetadataUtil.resolveDatabase(null, dataverseName);
         SourceLocation sourceLoc = stmtViewDrop.getSourceLocation();
         MetadataTransactionContext mdTxnCtx = MetadataManager.INSTANCE.beginTransaction();
         metadataProvider.setMetadataTxnContext(mdTxnCtx);
@@ -2679,7 +2679,7 @@
             MetadataManager.INSTANCE.dropDataset(mdTxnCtx, database, dataverseName, viewName, false);
             if (TypeUtil.isDatasetInlineTypeName(dataset, dataset.getItemTypeDataverseName(),
                     dataset.getItemTypeName())) {
-                String itemDatabase = null;
+                String itemDatabase = MetadataUtil.resolveDatabase(null, dataset.getItemTypeDataverseName());
                 MetadataManager.INSTANCE.dropDatatype(mdTxnCtx, itemDatabase, dataset.getItemTypeDataverseName(),
                         dataset.getItemTypeName());
             }
@@ -2899,7 +2899,8 @@
                     Datatype newInlineType =
                             newInlineTypes.isEmpty() ? null : newInlineTypes.remove(existingInlineType);
                     if (newInlineType == null) {
-                        String existingInlineTypeDatabase = null;
+                        String existingInlineTypeDatabase =
+                                MetadataUtil.resolveDatabase(null, existingInlineType.getDataverseName());
                         MetadataManager.INSTANCE.dropDatatype(mdTxnCtx, existingInlineTypeDatabase,
                                 existingInlineType.getDataverseName(), existingInlineType.getName());
                     } else {
@@ -2952,13 +2953,14 @@
             case ORDEREDLIST:
             case UNORDEREDLIST:
                 DataverseName paramTypeDataverseName = functionSignature.getDataverseName();
+                String database = MetadataUtil.resolveDatabase(null, paramTypeDataverseName);
                 paramTypeName = TypeUtil.createFunctionParameterTypeName(functionSignature.getName(),
                         functionSignature.getArity(), paramIdx);
                 IAType paramType = translateType(paramTypeDataverseName, paramTypeName, paramTypeExpr, mdTxnCtx);
                 paramTypeSignature = new TypeSignature(paramTypeDataverseName, paramTypeName);
                 depTypeSignature =
                         FunctionUtil.getTypeDependencyFromFunctionParameter(paramTypeExpr, paramTypeDataverseName);
-                paramInlineTypeEntity = new Datatype(paramTypeDataverseName, paramTypeName, paramType, true);
+                paramInlineTypeEntity = new Datatype(database, paramTypeDataverseName, paramTypeName, paramType, true);
                 break;
             default:
                 throw new CompilationException(ErrorCode.COMPILATION_ILLEGAL_STATE, sourceLoc);
@@ -3017,7 +3019,7 @@
 
             MetadataManager.INSTANCE.dropFunction(mdTxnCtx, signature);
             for (TypeSignature inlineType : inlineTypes) {
-                String inlineTypeDatabase = null;
+                String inlineTypeDatabase = MetadataUtil.resolveDatabase(null, inlineType.getDataverseName());
                 MetadataManager.INSTANCE.dropDatatype(mdTxnCtx, inlineTypeDatabase, inlineType.getDataverseName(),
                         inlineType.getName());
             }
@@ -3056,8 +3058,8 @@
         MetadataTransactionContext mdTxnCtx = MetadataManager.INSTANCE.beginTransaction();
         metadataProvider.setMetadataTxnContext(mdTxnCtx);
         try {
-            String database = null;
             DataverseName dataverseName = getActiveDataverseName(cas.getDataverseName());
+            String database = MetadataUtil.resolveDatabase(null, dataverseName);
             Dataverse dv = MetadataManager.INSTANCE.getDataverse(mdTxnCtx, database, dataverseName);
             if (dv == null) {
                 throw new CompilationException(ErrorCode.UNKNOWN_DATAVERSE, sourceLoc, dataverseName);
@@ -3073,11 +3075,11 @@
                 throw new CompilationException(ErrorCode.ADAPTER_EXISTS, sourceLoc, adapterName);
             }
 
-            String libraryDatabase = null;
             DataverseName libraryDataverseName = cas.getLibraryDataverseName();
             if (libraryDataverseName == null) {
                 libraryDataverseName = dataverseName;
             }
+            String libraryDatabase = MetadataUtil.resolveDatabase(null, libraryDataverseName);
             String libraryName = cas.getLibraryName();
             Library library =
                     MetadataManager.INSTANCE.getLibrary(mdTxnCtx, libraryDatabase, libraryDataverseName, libraryName);
@@ -3097,8 +3099,9 @@
             }
             String adapterFactoryClass = externalIdentifier.get(0);
 
-            adapter = new DatasourceAdapter(new AdapterIdentifier(dataverseName, adapterName),
-                    IDataSourceAdapter.AdapterType.EXTERNAL, adapterFactoryClass, libraryDataverseName, libraryName);
+            adapter = new DatasourceAdapter(new AdapterIdentifier(database, dataverseName, adapterName),
+                    IDataSourceAdapter.AdapterType.EXTERNAL, adapterFactoryClass, libraryDatabase, libraryDataverseName,
+                    libraryName);
             MetadataManager.INSTANCE.addAdapter(mdTxnCtx, adapter);
             if (LOGGER.isInfoEnabled()) {
                 LOGGER.info("Installed adapter: " + adapterName);
@@ -3129,7 +3132,7 @@
 
     protected boolean doDropAdapter(MetadataProvider metadataProvider, AdapterDropStatement stmtDropAdapter,
             DataverseName dataverseName, String adapterName) throws Exception {
-        String database = null;
+        String database = MetadataUtil.resolveDatabase(null, dataverseName);
         SourceLocation sourceLoc = stmtDropAdapter.getSourceLocation();
         MetadataTransactionContext mdTxnCtx = MetadataManager.INSTANCE.beginTransaction();
         metadataProvider.setMetadataTxnContext(mdTxnCtx);
@@ -3185,7 +3188,7 @@
     protected CreateResult doCreateLibrary(MetadataProvider metadataProvider, DataverseName dataverseName,
             String libraryName, String libraryHash, CreateLibraryStatement cls, IHyracksClientConnection hcc,
             IRequestParameters requestParameters) throws Exception {
-        String database = null;
+        String database = MetadataUtil.resolveDatabase(null, dataverseName);
         JobUtils.ProgressState progress = ProgressState.NO_PROGRESS;
         boolean prepareJobSuccessful = false;
         JobSpecification abortJobSpec = null;
@@ -3206,8 +3209,8 @@
             }
 
             // #. add/update library with PendingAddOp
-            Library libraryPendingAdd =
-                    new Library(dataverseName, libraryName, language.name(), libraryHash, MetadataUtil.PENDING_ADD_OP);
+            Library libraryPendingAdd = new Library(database, dataverseName, libraryName, language.name(), libraryHash,
+                    MetadataUtil.PENDING_ADD_OP);
             if (existingLibrary == null) {
                 MetadataManager.INSTANCE.addLibrary(mdTxnCtx, libraryPendingAdd);
             } else {
@@ -3236,8 +3239,8 @@
             bActiveTxn = true;
             metadataProvider.setMetadataTxnContext(mdTxnCtx);
 
-            Library newLibrary =
-                    new Library(dataverseName, libraryName, language.name(), libraryHash, MetadataUtil.PENDING_NO_OP);
+            Library newLibrary = new Library(database, dataverseName, libraryName, language.name(), libraryHash,
+                    MetadataUtil.PENDING_NO_OP);
             MetadataManager.INSTANCE.updateLibrary(mdTxnCtx, newLibrary);
 
             MetadataManager.INSTANCE.commitTransaction(mdTxnCtx);
@@ -3317,7 +3320,7 @@
     protected boolean doDropLibrary(MetadataProvider metadataProvider, LibraryDropStatement stmtDropLibrary,
             DataverseName dataverseName, String libraryName, IHyracksClientConnection hcc,
             IRequestParameters requestParameters) throws Exception {
-        String database = null;
+        String database = MetadataUtil.resolveDatabase(null, dataverseName);
         JobUtils.ProgressState progress = ProgressState.NO_PROGRESS;
         MetadataTransactionContext mdTxnCtx = MetadataManager.INSTANCE.beginTransaction();
         boolean bActiveTxn = true;
@@ -3347,8 +3350,8 @@
             // #. mark the existing library as PendingDropOp
             // do drop instead of update because drop will fail if the library is used by functions/adapters
             MetadataManager.INSTANCE.dropLibrary(mdTxnCtx, database, dataverseName, libraryName);
-            MetadataManager.INSTANCE.addLibrary(mdTxnCtx, new Library(dataverseName, libraryName, library.getLanguage(),
-                    library.getHash(), MetadataUtil.PENDING_DROP_OP));
+            MetadataManager.INSTANCE.addLibrary(mdTxnCtx, new Library(database, dataverseName, libraryName,
+                    library.getLanguage(), library.getHash(), MetadataUtil.PENDING_DROP_OP));
 
             // #. drop library artifacts in NCs.
             JobSpecification jobSpec =
@@ -3415,7 +3418,7 @@
     protected CreateResult doCreateSynonym(MetadataProvider metadataProvider, CreateSynonymStatement css,
             DataverseName dataverseName, String synonymName, DataverseName objectDataverseName, String objectName)
             throws Exception {
-        String database = null;
+        String database = MetadataUtil.resolveDatabase(null, dataverseName);
         MetadataTransactionContext mdTxnCtx = MetadataManager.INSTANCE.beginTransaction();
         metadataProvider.setMetadataTxnContext(mdTxnCtx);
         try {
@@ -3436,7 +3439,7 @@
                 }
                 throw new CompilationException(ErrorCode.SYNONYM_EXISTS, css.getSourceLocation(), synonymName);
             }
-            synonym = new Synonym(dataverseName, synonymName, objectDataverseName, objectName);
+            synonym = new Synonym(database, dataverseName, synonymName, objectDataverseName, objectName);
             MetadataManager.INSTANCE.addSynonym(metadataProvider.getMetadataTxnContext(), synonym);
             MetadataManager.INSTANCE.commitTransaction(mdTxnCtx);
             return CreateResult.CREATED;
@@ -3465,7 +3468,7 @@
 
     protected boolean doDropSynonym(MetadataProvider metadataProvider, SynonymDropStatement stmtSynDrop,
             DataverseName dataverseName, String synonymName) throws Exception {
-        String database = null;
+        String database = MetadataUtil.resolveDatabase(null, dataverseName);
         MetadataTransactionContext mdTxnCtx = MetadataManager.INSTANCE.beginTransaction();
         metadataProvider.setMetadataTxnContext(mdTxnCtx);
         try {
@@ -3558,8 +3561,9 @@
                         datasetName, itemTypeExpr, false, stmt.getSourceLocation());
                 DataverseName itemTypeDataverseName = itemTypeQualifiedName.first;
                 String itemTypeName = itemTypeQualifiedName.second;
+                String database = MetadataUtil.resolveDatabase(null, itemTypeDataverseName);
                 IAType itemTypeEntity = translateType(itemTypeDataverseName, itemTypeName, itemTypeExpr, mdTxnCtx);
-                itemType = new Datatype(itemTypeDataverseName, itemTypeName, itemTypeEntity, true);
+                itemType = new Datatype(database, itemTypeDataverseName, itemTypeName, itemTypeEntity, true);
             }
             ExternalDetailsDecl externalDetails = copyStmt.getExternalDetails();
             Map<String, String> properties =
@@ -3878,8 +3882,8 @@
         SourceLocation sourceLoc = cfps.getSourceLocation();
         String policyName = cfps.getPolicyName();
         metadataProvider.validateDatabaseObjectName(null, policyName, sourceLoc);
-        String database = null;
         DataverseName dataverseName = getActiveDataverseName(null);
+        String database = MetadataUtil.resolveDatabase(null, dataverseName);
         if (isCompileOnly()) {
             return;
         }
@@ -3913,7 +3917,7 @@
                 }
                 Map<String, String> policyProperties = sourceFeedPolicy.getProperties();
                 policyProperties.putAll(cfps.getProperties());
-                newPolicy = new FeedPolicyEntity(dataverseName, policyName, description, policyProperties);
+                newPolicy = new FeedPolicyEntity(database, dataverseName, policyName, description, policyProperties);
             } else {
                 Properties prop = new Properties();
                 try {
@@ -3925,7 +3929,7 @@
                 }
                 Map<String, String> policyProperties = new HashMap<>();
                 prop.forEach((key, value) -> policyProperties.put((String) key, (String) value));
-                newPolicy = new FeedPolicyEntity(dataverseName, policyName, description, policyProperties);
+                newPolicy = new FeedPolicyEntity(database, dataverseName, policyName, description, policyProperties);
             }
             MetadataManager.INSTANCE.addFeedPolicy(mdTxnCtx, newPolicy);
             MetadataManager.INSTANCE.commitTransaction(mdTxnCtx);
@@ -3985,7 +3989,7 @@
         } else if (listener != null) {
             listener.unregister();
         }
-        String feedDatabase = null;
+        String feedDatabase = MetadataUtil.resolveDatabase(null, feedId.getDataverseName());
         JobSpecification spec = FeedOperations.buildRemoveFeedStorageJob(metadataProvider, MetadataManager.INSTANCE
                 .getFeed(mdTxnCtx, feedDatabase, feedId.getDataverseName(), feedId.getEntityName()));
         runJob(hcc, spec);
@@ -4000,8 +4004,8 @@
         SourceLocation sourceLoc = stmtFeedPolicyDrop.getSourceLocation();
         String policyName = stmtFeedPolicyDrop.getPolicyName().getValue();
         metadataProvider.validateDatabaseObjectName(stmtFeedPolicyDrop.getDataverseName(), policyName, sourceLoc);
-        String database = null;
         DataverseName dataverseName = getActiveDataverseName(stmtFeedPolicyDrop.getDataverseName());
+        String database = MetadataUtil.resolveDatabase(null, dataverseName);
         if (isCompileOnly()) {
             return;
         }
@@ -4116,8 +4120,8 @@
         FeedConnection fc;
         ConnectFeedStatement cfs = (ConnectFeedStatement) stmt;
         SourceLocation sourceLoc = cfs.getSourceLocation();
-        String database = null;
         DataverseName dataverseName = getActiveDataverseName(cfs.getDataverseName());
+        String database = MetadataUtil.resolveDatabase(null, dataverseName);
         String feedName = cfs.getFeedName();
         String datasetName = cfs.getDatasetName().getValue();
         String policyName = cfs.getPolicy();
@@ -4158,8 +4162,8 @@
                 throw new CompilationException(ErrorCode.COMPILATION_ERROR, sourceLoc,
                         "Feed" + feedName + " is already connected to " + dataset() + " " + datasetName);
             }
-            fc = new FeedConnection(dataverseName, feedName, datasetName, appliedFunctions, policyName, whereClauseBody,
-                    outputType.getTypeName());
+            fc = new FeedConnection(database, dataverseName, feedName, datasetName, appliedFunctions, policyName,
+                    whereClauseBody, outputType.getTypeName());
             MetadataManager.INSTANCE.addFeedConnection(metadataProvider.getMetadataTxnContext(), fc);
             MetadataManager.INSTANCE.commitTransaction(mdTxnCtx);
             if (listener != null) {
@@ -4177,8 +4181,8 @@
     protected void handleDisconnectFeedStatement(MetadataProvider metadataProvider, Statement stmt) throws Exception {
         DisconnectFeedStatement cfs = (DisconnectFeedStatement) stmt;
         SourceLocation sourceLoc = cfs.getSourceLocation();
-        String database = null;
         DataverseName dataverseName = getActiveDataverseName(cfs.getDataverseName());
+        String database = MetadataUtil.resolveDatabase(null, dataverseName);
         String datasetName = cfs.getDatasetName().getValue();
         String feedName = cfs.getFeedName().getValue();
         if (isCompileOnly()) {
@@ -4244,7 +4248,7 @@
     protected void doAnalyzeDataset(MetadataProvider metadataProvider, AnalyzeStatement stmtAnalyze,
             DataverseName dataverseName, String datasetName, IHyracksClientConnection hcc,
             IRequestParameters requestParameters) throws Exception {
-        String database = null;
+        String database = MetadataUtil.resolveDatabase(null, dataverseName);
         SourceLocation sourceLoc = stmtAnalyze.getSourceLocation();
         ProgressState progressNewIndexCreate = ProgressState.NO_PROGRESS;
         ProgressState progressExistingIndexDrop = ProgressState.NO_PROGRESS;
@@ -4292,7 +4296,7 @@
             Index.SampleIndexDetails newIndexDetailsPendingAdd = new Index.SampleIndexDetails(dsDetails.getPrimaryKey(),
                     dsDetails.getKeySourceIndicator(), dsDetails.getPrimaryKeyType(), sampleCardinalityTarget, 0, 0,
                     sampleSeed, Collections.emptyMap());
-            newIndexPendingAdd = new Index(dataverseName, datasetName, newIndexName, sampleIndexType,
+            newIndexPendingAdd = new Index(database, dataverseName, datasetName, newIndexName, sampleIndexType,
                     newIndexDetailsPendingAdd, false, false, MetadataUtil.PENDING_ADD_OP);
 
             // #. add a new index with PendingAddOp
@@ -4334,7 +4338,7 @@
             Index.SampleIndexDetails newIndexDetailsFinal = new Index.SampleIndexDetails(dsDetails.getPrimaryKey(),
                     dsDetails.getKeySourceIndicator(), dsDetails.getPrimaryKeyType(), sampleCardinalityTarget,
                     stats.getCardinality(), stats.getAvgTupleSize(), sampleSeed, stats.getIndexesStats());
-            Index newIndexFinal = new Index(dataverseName, datasetName, newIndexName, sampleIndexType,
+            Index newIndexFinal = new Index(database, dataverseName, datasetName, newIndexName, sampleIndexType,
                     newIndexDetailsFinal, false, false, MetadataUtil.PENDING_NO_OP);
 
             // #. begin new metadataTxn
@@ -4468,7 +4472,7 @@
     protected boolean doAnalyzeDatasetDrop(MetadataProvider metadataProvider, AnalyzeDropStatement stmtIndexDrop,
             DataverseName dataverseName, String datasetName, IHyracksClientConnection hcc,
             IRequestParameters requestParams) throws Exception {
-        String database = null;
+        String database = MetadataUtil.resolveDatabase(null, dataverseName);
         SourceLocation sourceLoc = stmtIndexDrop.getSourceLocation();
         Pair<String, String> sampleIndexNames = IndexUtil.getSampleIndexNames(datasetName);
         String indexName1 = sampleIndexNames.first;
@@ -4587,7 +4591,7 @@
     private void prepareIndexDrop(MetadataProvider metadataProvider, DataverseName dataverseName, String datasetName,
             SourceLocation sourceLoc, String indexName, List<JobSpecification> jobsToExecute,
             MetadataTransactionContext mdTxnCtx, Dataset ds, Index index) throws AlgebricksException {
-        String database = null;
+        String database = MetadataUtil.resolveDatabase(null, dataverseName);
         if (index != null) {
             // #. prepare a job to drop the index in NC.
             jobsToExecute.add(IndexUtil.buildDropIndexJobSpec(index, metadataProvider, ds, sourceLoc));
@@ -4595,8 +4599,9 @@
             // #. mark PendingDropOp on the existing index
             MetadataManager.INSTANCE.dropIndex(mdTxnCtx, database, dataverseName, datasetName, indexName);
             MetadataManager.INSTANCE.addIndex(mdTxnCtx,
-                    new Index(dataverseName, datasetName, indexName, index.getIndexType(), index.getIndexDetails(),
-                            index.isEnforced(), index.isPrimaryIndex(), MetadataUtil.PENDING_DROP_OP));
+                    new Index(database, dataverseName, datasetName, indexName, index.getIndexType(),
+                            index.getIndexDetails(), index.isEnforced(), index.isPrimaryIndex(),
+                            MetadataUtil.PENDING_DROP_OP));
         }
     }
 
diff --git a/asterixdb/asterix-app/src/test/java/org/apache/asterix/app/bootstrap/TestNodeController.java b/asterixdb/asterix-app/src/test/java/org/apache/asterix/app/bootstrap/TestNodeController.java
index d3c708d..e111524 100644
--- a/asterixdb/asterix-app/src/test/java/org/apache/asterix/app/bootstrap/TestNodeController.java
+++ b/asterixdb/asterix-app/src/test/java/org/apache/asterix/app/bootstrap/TestNodeController.java
@@ -489,8 +489,8 @@
 
     public IResourceFactory getPrimaryResourceFactory(IHyracksTaskContext ctx, PrimaryIndexInfo primaryIndexInfo,
             IStorageComponentProvider storageComponentProvider, Dataset dataset) throws AlgebricksException {
-        Dataverse dataverse = new Dataverse(dataset.getDataverseName(), NonTaggedDataFormat.class.getName(),
-                MetadataUtil.PENDING_NO_OP);
+        Dataverse dataverse = new Dataverse(dataset.getDatabaseName(), dataset.getDataverseName(),
+                NonTaggedDataFormat.class.getName(), MetadataUtil.PENDING_NO_OP);
         Index index = primaryIndexInfo.getIndex();
         CcApplicationContext appCtx =
                 (CcApplicationContext) ExecutionTestUtil.integrationUtil.cc.getApplicationContext();
@@ -513,8 +513,8 @@
         MetadataManager.INSTANCE.commitTransaction(mdTxnCtx);
         PrimaryIndexInfo primaryIndexInfo = new PrimaryIndexInfo(dataset, primaryKeyTypes, recordType, metaType,
                 mergePolicy.first, mergePolicy.second, filterFields, primaryKeyIndexes, primaryKeyIndicators);
-        Dataverse dataverse = new Dataverse(dataset.getDataverseName(), NonTaggedDataFormat.class.getName(),
-                MetadataUtil.PENDING_NO_OP);
+        Dataverse dataverse = new Dataverse(dataset.getDatabaseName(), dataset.getDataverseName(),
+                NonTaggedDataFormat.class.getName(), MetadataUtil.PENDING_NO_OP);
         MetadataProvider mdProvider = MetadataProvider.create(
                 (ICcApplicationContext) ExecutionTestUtil.integrationUtil.cc.getApplicationContext(), dataverse);
         try {
@@ -539,8 +539,9 @@
         org.apache.hyracks.algebricks.common.utils.Pair<ILSMMergePolicyFactory, Map<String, String>> mergePolicy =
                 DatasetUtil.getMergePolicyFactory(primaryIndexInfo.dataset, mdTxnCtx);
         MetadataManager.INSTANCE.commitTransaction(mdTxnCtx);
-        Dataverse dataverse = new Dataverse(primaryIndexInfo.dataset.getDataverseName(),
-                NonTaggedDataFormat.class.getName(), MetadataUtil.PENDING_NO_OP);
+        Dataverse dataverse =
+                new Dataverse(primaryIndexInfo.dataset.getDatabaseName(), primaryIndexInfo.dataset.getDataverseName(),
+                        NonTaggedDataFormat.class.getName(), MetadataUtil.PENDING_NO_OP);
         MetadataProvider mdProvider = MetadataProvider.create(
                 (ICcApplicationContext) ExecutionTestUtil.integrationUtil.cc.getApplicationContext(), dataverse);
         SecondaryIndexInfo secondaryIndexInfo = new SecondaryIndexInfo(primaryIndexInfo, secondaryIndex);
@@ -753,8 +754,9 @@
                         indicator == Index.RECORD_INDICATOR ? recordType.getFieldNames() : metaType.getFieldNames();
                 keyFieldNames.add(Collections.singletonList(fieldNames[primaryKeyIndexes[i]]));
             }
-            index = Index.createPrimaryIndex(dataset.getDataverseName(), dataset.getDatasetName(), keyFieldNames,
-                    primaryKeyIndicators, keyFieldTypes, MetadataUtil.PENDING_NO_OP);
+            index = Index.createPrimaryIndex(dataset.getDatabaseName(), dataset.getDataverseName(),
+                    dataset.getDatasetName(), keyFieldNames, primaryKeyIndicators, keyFieldTypes,
+                    MetadataUtil.PENDING_NO_OP);
             List<String> nodes = Collections.singletonList(ExecutionTestUtil.integrationUtil.ncs[0].getId());
             CcApplicationContext appCtx =
                     (CcApplicationContext) ExecutionTestUtil.integrationUtil.cc.getApplicationContext();
diff --git a/asterixdb/asterix-app/src/test/java/org/apache/asterix/test/active/ActiveEventsListenerTest.java b/asterixdb/asterix-app/src/test/java/org/apache/asterix/test/active/ActiveEventsListenerTest.java
index e5e33d0..962b820 100644
--- a/asterixdb/asterix-app/src/test/java/org/apache/asterix/test/active/ActiveEventsListenerTest.java
+++ b/asterixdb/asterix-app/src/test/java/org/apache/asterix/test/active/ActiveEventsListenerTest.java
@@ -52,6 +52,7 @@
 import org.apache.asterix.metadata.entities.Feed;
 import org.apache.asterix.metadata.lock.MetadataLockManager;
 import org.apache.asterix.metadata.utils.MetadataLockUtil;
+import org.apache.asterix.metadata.utils.MetadataUtil;
 import org.apache.asterix.runtime.functions.FunctionCollection;
 import org.apache.asterix.runtime.functions.FunctionManager;
 import org.apache.asterix.test.active.TestEventsListener.Behavior;
@@ -83,6 +84,7 @@
     static String[] nodes = { "node1", "node2" };
     static ActiveNotificationHandler handler;
     static DataverseName dataverseName = MetadataBuiltinEntities.DEFAULT_DATAVERSE_NAME;
+    static String database = MetadataUtil.databaseFor(dataverseName);
     static String entityName = "entityName";
     static EntityId entityId = new EntityId(Feed.EXTENSION_NAME, dataverseName, entityName);
     static Dataset firstDataset;
@@ -110,9 +112,10 @@
         jobIdFactory = new JobIdFactory(CcId.valueOf((short) 0));
         handler = new ActiveNotificationHandler();
         allDatasets = new ArrayList<>();
-        firstDataset = new Dataset(dataverseName, "firstDataset", null, null, null, null, null, null, null, null, 0, 0);
-        secondDataset =
-                new Dataset(dataverseName, "secondDataset", null, null, null, null, null, null, null, null, 0, 0);
+        firstDataset = new Dataset(database, dataverseName, "firstDataset", null, null, null, null, null, null, null,
+                null, 0, 0);
+        secondDataset = new Dataset(database, dataverseName, "secondDataset", null, null, null, null, null, null, null,
+                null, 0, 0);
         allDatasets.add(firstDataset);
         allDatasets.add(secondDataset);
         AtomicInteger threadCounter = new AtomicInteger(0);
@@ -987,8 +990,8 @@
         WaitForStateSubscriber recoveringSubscriber =
                 new WaitForStateSubscriber(listener, EnumSet.of(ActivityState.RECOVERING));
         recoveringSubscriber.sync();
-        Dataset newDataset =
-                new Dataset(dataverseName, "newDataset", null, null, null, null, null, null, null, null, 0, 0);
+        Dataset newDataset = new Dataset(database, dataverseName, "newDataset", null, null, null, null, null, null,
+                null, null, 0, 0);
         Action add = users[1].addDataset(newDataset, listener);
         listener.allowStep();
         runningSubscriber.sync();
@@ -1014,8 +1017,8 @@
                 new WaitForStateSubscriber(listener, EnumSet.of(ActivityState.RECOVERING));
         recoveringSubscriber.sync();
         tempFailSubscriber = new WaitForStateSubscriber(listener, EnumSet.of(ActivityState.TEMPORARILY_FAILED));
-        Dataset newDataset =
-                new Dataset(dataverseName, "newDataset", null, null, null, null, null, null, null, null, 0, 0);
+        Dataset newDataset = new Dataset(database, dataverseName, "newDataset", null, null, null, null, null, null,
+                null, null, 0, 0);
         Action add = users[1].addDataset(newDataset, listener);
         listener.allowStep();
         tempFailSubscriber.sync();
@@ -1041,8 +1044,8 @@
                 new WaitForStateSubscriber(listener, EnumSet.of(ActivityState.RECOVERING));
         recoveringSubscriber.sync();
         tempFailSubscriber = new WaitForStateSubscriber(listener, EnumSet.of(ActivityState.TEMPORARILY_FAILED));
-        Dataset newDataset =
-                new Dataset(dataverseName, "newDataset", null, null, null, null, null, null, null, null, 0, 0);
+        Dataset newDataset = new Dataset(database, dataverseName, "newDataset", null, null, null, null, null, null,
+                null, null, 0, 0);
         Action add = users[1].addDataset(newDataset, listener);
         listener.allowStep();
         tempFailSubscriber.sync();
@@ -1060,8 +1063,8 @@
         WaitForStateSubscriber subscriber =
                 new WaitForStateSubscriber(listener, Collections.singleton(ActivityState.STARTING));
         subscriber.sync();
-        Dataset newDataset =
-                new Dataset(dataverseName, "newDataset", null, null, null, null, null, null, null, null, 0, 0);
+        Dataset newDataset = new Dataset(database, dataverseName, "newDataset", null, null, null, null, null, null,
+                null, null, 0, 0);
         Action createDatasetAction = users[1].addDataset(newDataset, listener);
         listener.allowStep();
         startAction.sync();
@@ -1076,8 +1079,8 @@
     @Test
     public void testCreateNewDatasetWhileRunning() throws Exception {
         testStartWhenStartSucceed();
-        Dataset newDataset =
-                new Dataset(dataverseName, "newDataset", null, null, null, null, null, null, null, null, 0, 0);
+        Dataset newDataset = new Dataset(database, dataverseName, "newDataset", null, null, null, null, null, null,
+                null, null, 0, 0);
         Action createDatasetAction = users[1].addDataset(newDataset, listener);
         createDatasetAction.sync();
         assertFailure(createDatasetAction, ErrorCode.CANNOT_ADD_DATASET_TO_ACTIVE_ENTITY);
@@ -1096,8 +1099,8 @@
         WaitForStateSubscriber subscriber =
                 new WaitForStateSubscriber(listener, EnumSet.of(ActivityState.SUSPENDING, ActivityState.SUSPENDED));
         subscriber.sync();
-        Dataset newDataset =
-                new Dataset(dataverseName, "newDataset", null, null, null, null, null, null, null, null, 0, 0);
+        Dataset newDataset = new Dataset(database, dataverseName, "newDataset", null, null, null, null, null, null,
+                null, null, 0, 0);
         Action createDatasetAction = users[0].addDataset(newDataset, listener);
         listener.allowStep();
         listener.allowStep();
@@ -1115,8 +1118,8 @@
     public void testCreateNewDatasetWhilePermanentFailure() throws Exception {
         testRecoveryFailureAfterOneAttemptCompilationFailure();
         Assert.assertEquals(ActivityState.STOPPED, listener.getState());
-        Dataset newDataset =
-                new Dataset(dataverseName, "newDataset", null, null, null, null, null, null, null, null, 0, 0);
+        Dataset newDataset = new Dataset(database, dataverseName, "newDataset", null, null, null, null, null, null,
+                null, null, 0, 0);
         Action createDatasetAction = users[0].addDataset(newDataset, listener);
         createDatasetAction.sync();
         assertSuccess(createDatasetAction);
@@ -1548,8 +1551,8 @@
         Action query = users[1].query(firstDataset, new Semaphore(1));
         query.sync();
         assertSuccess(query);
-        Dataset newDataset =
-                new Dataset(dataverseName, "newDataset", null, null, null, null, null, null, null, null, 0, 0);
+        Dataset newDataset = new Dataset(database, dataverseName, "newDataset", null, null, null, null, null, null,
+                null, null, 0, 0);
         Action addDataset = users[1].addDataset(newDataset, listener);
         // blocked by suspension
         Assert.assertFalse(addDataset.isDone());
diff --git a/asterixdb/asterix-app/src/test/java/org/apache/asterix/test/dataflow/CheckpointInSecondaryIndexTest.java b/asterixdb/asterix-app/src/test/java/org/apache/asterix/test/dataflow/CheckpointInSecondaryIndexTest.java
index 3973dee..1353acc 100644
--- a/asterixdb/asterix-app/src/test/java/org/apache/asterix/test/dataflow/CheckpointInSecondaryIndexTest.java
+++ b/asterixdb/asterix-app/src/test/java/org/apache/asterix/test/dataflow/CheckpointInSecondaryIndexTest.java
@@ -50,6 +50,7 @@
 import org.apache.asterix.metadata.entities.Index;
 import org.apache.asterix.metadata.entities.InternalDatasetDetails;
 import org.apache.asterix.metadata.entities.InternalDatasetDetails.PartitioningStrategy;
+import org.apache.asterix.metadata.utils.MetadataUtil;
 import org.apache.asterix.om.types.ARecordType;
 import org.apache.asterix.om.types.BuiltinType;
 import org.apache.asterix.om.types.IAType;
@@ -171,7 +172,8 @@
                 NoMergePolicyFactory.NAME, null, new InternalDatasetDetails(null, PartitioningStrategy.HASH,
                         partitioningKeys, null, null, null, false, null, null),
                 null, DatasetType.INTERNAL, DATASET_ID, 0);
-        secondaryIndex = new Index(dvName, DATASET_NAME, INDEX_NAME, INDEX_TYPE, INDEX_FIELD_NAMES,
+        String database = MetadataUtil.databaseFor(dvName);
+        secondaryIndex = new Index(database, dvName, DATASET_NAME, INDEX_NAME, INDEX_TYPE, INDEX_FIELD_NAMES,
                 INDEX_FIELD_INDICATORS, INDEX_FIELD_TYPES, false, false, false, 0, OptionalBoolean.of(false));
         taskCtx = null;
         primaryIndexDataflowHelper = null;
diff --git a/asterixdb/asterix-app/src/test/java/org/apache/asterix/test/dataflow/ConcurrentInsertTest.java b/asterixdb/asterix-app/src/test/java/org/apache/asterix/test/dataflow/ConcurrentInsertTest.java
index e99e5d6..b458874 100644
--- a/asterixdb/asterix-app/src/test/java/org/apache/asterix/test/dataflow/ConcurrentInsertTest.java
+++ b/asterixdb/asterix-app/src/test/java/org/apache/asterix/test/dataflow/ConcurrentInsertTest.java
@@ -126,9 +126,9 @@
         lsmBtree = (TestLsmBtree) indexDataflowHelper.getIndexInstance();
         indexDataflowHelper.close();
 
-        Index secondaryIndexEntity = new Index(StorageTestUtils.DATASET.getDataverseName(),
-                StorageTestUtils.DATASET.getDatasetName(), "TestIndex", IndexType.BTREE,
-                Arrays.asList(Arrays.asList(StorageTestUtils.RECORD_TYPE.getFieldNames()[1])),
+        Index secondaryIndexEntity = new Index(StorageTestUtils.DATASET.getDatabaseName(),
+                StorageTestUtils.DATASET.getDataverseName(), StorageTestUtils.DATASET.getDatasetName(), "TestIndex",
+                IndexType.BTREE, Arrays.asList(Arrays.asList(StorageTestUtils.RECORD_TYPE.getFieldNames()[1])),
                 Arrays.asList(Index.RECORD_INDICATOR), Arrays.asList(BuiltinType.AINT64), false, false, false, 0,
                 OptionalBoolean.of(false));
 
@@ -142,9 +142,10 @@
         secondaryIndex = (TestLsmBtree) secondaryDataflowHelper.getIndexInstance();
         secondaryDataflowHelper.close();
 
-        Index primaryKeyIndexEntity = new Index(StorageTestUtils.DATASET.getDataverseName(),
-                StorageTestUtils.DATASET.getDatasetName(), "PrimaryKeyIndex", IndexType.BTREE, Arrays.asList(),
-                Arrays.asList(), Arrays.asList(), false, false, false, 0, OptionalBoolean.empty());
+        Index primaryKeyIndexEntity =
+                new Index(StorageTestUtils.DATASET.getDatabaseName(), StorageTestUtils.DATASET.getDataverseName(),
+                        StorageTestUtils.DATASET.getDatasetName(), "PrimaryKeyIndex", IndexType.BTREE, Arrays.asList(),
+                        Arrays.asList(), Arrays.asList(), false, false, false, 0, OptionalBoolean.empty());
 
         SecondaryIndexInfo primaryKeyIndexInfo =
                 nc.createSecondaryIndex(primaryIndexInfo, primaryKeyIndexEntity, StorageTestUtils.STORAGE_MANAGER, 0);
diff --git a/asterixdb/asterix-app/src/test/java/org/apache/asterix/test/dataflow/LSMFlushRecoveryTest.java b/asterixdb/asterix-app/src/test/java/org/apache/asterix/test/dataflow/LSMFlushRecoveryTest.java
index d24d081..b574c1b 100644
--- a/asterixdb/asterix-app/src/test/java/org/apache/asterix/test/dataflow/LSMFlushRecoveryTest.java
+++ b/asterixdb/asterix-app/src/test/java/org/apache/asterix/test/dataflow/LSMFlushRecoveryTest.java
@@ -186,9 +186,10 @@
 
     public void createIndex() throws Exception {
         dataset = StorageTestUtils.DATASET;
-        secondaryIndexEntity = new Index(dataset.getDataverseName(), dataset.getDatasetName(), SECONDARY_INDEX_NAME,
-                SECONDARY_INDEX_TYPE, SECONDARY_INDEX_FIELD_NAMES, SECONDARY_INDEX_FIELD_INDICATORS,
-                SECONDARY_INDEX_FIELD_TYPES, false, false, false, 0, OptionalBoolean.of(false));
+        secondaryIndexEntity = new Index(dataset.getDatabaseName(), dataset.getDataverseName(),
+                dataset.getDatasetName(), SECONDARY_INDEX_NAME, SECONDARY_INDEX_TYPE, SECONDARY_INDEX_FIELD_NAMES,
+                SECONDARY_INDEX_FIELD_INDICATORS, SECONDARY_INDEX_FIELD_TYPES, false, false, false, 0,
+                OptionalBoolean.of(false));
 
         primaryIndexInfos = new PrimaryIndexInfo[NUM_PARTITIONS];
         secondaryIndexInfo = new SecondaryIndexInfo[NUM_PARTITIONS];
diff --git a/asterixdb/asterix-app/src/test/java/org/apache/asterix/test/dataflow/MultiPartitionLSMIndexTest.java b/asterixdb/asterix-app/src/test/java/org/apache/asterix/test/dataflow/MultiPartitionLSMIndexTest.java
index 6f9bed4..d921127 100644
--- a/asterixdb/asterix-app/src/test/java/org/apache/asterix/test/dataflow/MultiPartitionLSMIndexTest.java
+++ b/asterixdb/asterix-app/src/test/java/org/apache/asterix/test/dataflow/MultiPartitionLSMIndexTest.java
@@ -161,8 +161,9 @@
                 NoMergePolicyFactory.NAME, null, new InternalDatasetDetails(null, PartitioningStrategy.HASH,
                         partitioningKeys, null, null, null, false, null, null),
                 null, DatasetType.INTERNAL, DATASET_ID, 0);
-        secondaryIndex = new Index(dvName, DATASET_NAME, INDEX_NAME, INDEX_TYPE, INDEX_FIELD_NAMES,
-                INDEX_FIELD_INDICATORS, INDEX_FIELD_TYPES, false, false, false, 0, OptionalBoolean.of(false));
+        secondaryIndex =
+                new Index(dataset.getDatabaseName(), dvName, DATASET_NAME, INDEX_NAME, INDEX_TYPE, INDEX_FIELD_NAMES,
+                        INDEX_FIELD_INDICATORS, INDEX_FIELD_TYPES, false, false, false, 0, OptionalBoolean.of(false));
         taskCtxs = new IHyracksTaskContext[NUM_PARTITIONS];
         primaryIndexDataflowHelpers = new IIndexDataflowHelper[NUM_PARTITIONS];
         secondaryIndexDataflowHelpers = new IIndexDataflowHelper[NUM_PARTITIONS];
diff --git a/asterixdb/asterix-app/src/test/java/org/apache/asterix/test/dataflow/TestDataset.java b/asterixdb/asterix-app/src/test/java/org/apache/asterix/test/dataflow/TestDataset.java
index f684405..ada12d7 100644
--- a/asterixdb/asterix-app/src/test/java/org/apache/asterix/test/dataflow/TestDataset.java
+++ b/asterixdb/asterix-app/src/test/java/org/apache/asterix/test/dataflow/TestDataset.java
@@ -28,6 +28,7 @@
 import org.apache.asterix.metadata.entities.Dataset;
 import org.apache.asterix.metadata.entities.Index;
 import org.apache.asterix.metadata.utils.DatasetUtil;
+import org.apache.asterix.metadata.utils.MetadataUtil;
 import org.apache.asterix.om.types.ARecordType;
 import org.apache.asterix.transaction.management.resource.DatasetLocalResourceFactory;
 import org.apache.asterix.transaction.management.runtime.CommitRuntime;
@@ -50,8 +51,9 @@
             String recordTypeName, String nodeGroupName, String compactionPolicy,
             Map<String, String> compactionPolicyProperties, IDatasetDetails datasetDetails, Map<String, String> hints,
             DatasetType datasetType, int datasetId, int pendingOp) {
-        super(dataverseName, datasetName, recordTypeDataverseName, recordTypeName, nodeGroupName, compactionPolicy,
-                compactionPolicyProperties, datasetDetails, hints, datasetType, datasetId, pendingOp);
+        super(MetadataUtil.databaseFor(dataverseName), dataverseName, datasetName, recordTypeDataverseName,
+                recordTypeName, nodeGroupName, compactionPolicy, compactionPolicyProperties, datasetDetails, hints,
+                datasetType, datasetId, pendingOp);
     }
 
     @Override
diff --git a/asterixdb/asterix-app/src/test/java/org/apache/asterix/test/metadata/MetadataTxnTest.java b/asterixdb/asterix-app/src/test/java/org/apache/asterix/test/metadata/MetadataTxnTest.java
index aaf9fcb..ec2620fb 100644
--- a/asterixdb/asterix-app/src/test/java/org/apache/asterix/test/metadata/MetadataTxnTest.java
+++ b/asterixdb/asterix-app/src/test/java/org/apache/asterix/test/metadata/MetadataTxnTest.java
@@ -319,9 +319,10 @@
 
     private void addDataset(ICcApplicationContext appCtx, Dataset source, int datasetPostfix, boolean abort)
             throws Exception {
-        Dataset dataset = new Dataset(source.getDataverseName(), "ds_" + datasetPostfix, source.getDataverseName(),
-                source.getDatasetType().name(), source.getNodeGroupName(), NoMergePolicyFactory.NAME, null,
-                source.getDatasetDetails(), source.getHints(), DatasetConfig.DatasetType.INTERNAL, datasetPostfix, 0);
+        Dataset dataset = new Dataset(source.getDatabaseName(), source.getDataverseName(), "ds_" + datasetPostfix,
+                source.getDataverseName(), source.getDatasetType().name(), source.getNodeGroupName(),
+                NoMergePolicyFactory.NAME, null, source.getDatasetDetails(), source.getHints(),
+                DatasetConfig.DatasetType.INTERNAL, datasetPostfix, 0);
         MetadataProvider metadataProvider = MetadataProvider.create(appCtx, null);
         final MetadataTransactionContext writeTxn = MetadataManager.INSTANCE.beginTransaction();
         metadataProvider.setMetadataTxnContext(writeTxn);
diff --git a/asterixdb/asterix-app/src/test/java/org/apache/asterix/test/storage/IndexDropOperatorNodePushableTest.java b/asterixdb/asterix-app/src/test/java/org/apache/asterix/test/storage/IndexDropOperatorNodePushableTest.java
index ba89e4c..a06f7b7 100644
--- a/asterixdb/asterix-app/src/test/java/org/apache/asterix/test/storage/IndexDropOperatorNodePushableTest.java
+++ b/asterixdb/asterix-app/src/test/java/org/apache/asterix/test/storage/IndexDropOperatorNodePushableTest.java
@@ -38,6 +38,7 @@
 import org.apache.asterix.metadata.entities.Dataset;
 import org.apache.asterix.metadata.entities.Index;
 import org.apache.asterix.metadata.entities.InternalDatasetDetails;
+import org.apache.asterix.metadata.utils.MetadataUtil;
 import org.apache.asterix.metadata.utils.SplitsAndConstraintsUtil;
 import org.apache.asterix.om.types.ARecordType;
 import org.apache.asterix.om.types.BuiltinType;
@@ -104,9 +105,10 @@
             nc.init();
             StorageComponentProvider storageManager = new StorageComponentProvider();
             DataverseName dvName = DataverseName.createSinglePartName(DATAVERSE_NAME);
+            String database = MetadataUtil.databaseFor(dvName);
             List<List<String>> partitioningKeys = new ArrayList<>();
             partitioningKeys.add(Collections.singletonList("key"));
-            Dataset dataset = new Dataset(dvName, DATASET_NAME, dvName, DATA_TYPE_NAME, NODE_GROUP_NAME,
+            Dataset dataset = new Dataset(database, dvName, DATASET_NAME, dvName, DATA_TYPE_NAME, NODE_GROUP_NAME,
                     NoMergePolicyFactory.NAME, null,
                     new InternalDatasetDetails(null, InternalDatasetDetails.PartitioningStrategy.HASH, partitioningKeys,
                             null, null, null, false, null, null),
diff --git a/asterixdb/asterix-external-data/src/main/java/org/apache/asterix/external/dataset/adapter/AdapterIdentifier.java b/asterixdb/asterix-external-data/src/main/java/org/apache/asterix/external/dataset/adapter/AdapterIdentifier.java
index bc82898..4b5d6c8 100644
--- a/asterixdb/asterix-external-data/src/main/java/org/apache/asterix/external/dataset/adapter/AdapterIdentifier.java
+++ b/asterixdb/asterix-external-data/src/main/java/org/apache/asterix/external/dataset/adapter/AdapterIdentifier.java
@@ -30,11 +30,12 @@
 
     private static final long serialVersionUID = 3L;
 
-    private final String databaseName = null;
+    private final String databaseName;
     private final DataverseName dataverseName;
     private final String adapterName;
 
-    public AdapterIdentifier(DataverseName dataverse, String name) {
+    public AdapterIdentifier(String databaseName, DataverseName dataverse, String name) {
+        this.databaseName = Objects.requireNonNull(databaseName);
         this.dataverseName = dataverse;
         this.adapterName = name;
     }
diff --git a/asterixdb/asterix-external-data/src/main/java/org/apache/asterix/external/feed/policy/FeedPolicy.java b/asterixdb/asterix-external-data/src/main/java/org/apache/asterix/external/feed/policy/FeedPolicy.java
index 78075e2..4cf084f 100644
--- a/asterixdb/asterix-external-data/src/main/java/org/apache/asterix/external/feed/policy/FeedPolicy.java
+++ b/asterixdb/asterix-external-data/src/main/java/org/apache/asterix/external/feed/policy/FeedPolicy.java
@@ -27,7 +27,7 @@
 public class FeedPolicy implements Serializable {
 
     private static final long serialVersionUID = 3L;
-    private final String databaseName = null;
+    private final String databaseName;
     private final DataverseName dataverseName;
     private final String policyName;
     // A description of the policy
@@ -35,8 +35,9 @@
     // The policy properties associated with the feed dataset
     private Map<String, String> properties;
 
-    public FeedPolicy(DataverseName dataverseName, String policyName, String description,
+    public FeedPolicy(String databaseName, DataverseName dataverseName, String policyName, String description,
             Map<String, String> properties) {
+        this.databaseName = Objects.requireNonNull(databaseName);
         this.dataverseName = dataverseName;
         this.policyName = policyName;
         this.description = description;
diff --git a/asterixdb/asterix-external-data/src/main/java/org/apache/asterix/external/indexing/ExternalFile.java b/asterixdb/asterix-external-data/src/main/java/org/apache/asterix/external/indexing/ExternalFile.java
index 973e890..d6c7c7c 100644
--- a/asterixdb/asterix-external-data/src/main/java/org/apache/asterix/external/indexing/ExternalFile.java
+++ b/asterixdb/asterix-external-data/src/main/java/org/apache/asterix/external/indexing/ExternalFile.java
@@ -34,7 +34,7 @@
      */
     private static final long serialVersionUID = 2L;
 
-    private final String databaseName = null;
+    private final String databaseName;
     private DataverseName dataverseName;
     private String datasetName;
     private Date lastModefiedTime;
@@ -43,18 +43,9 @@
     private int fileNumber;
     private ExternalFilePendingOp pendingOp;
 
-    public ExternalFile() {
-        this.dataverseName = null;
-        this.datasetName = "";
-        this.fileNumber = -1;
-        this.fileName = "";
-        this.lastModefiedTime = new Date();
-        this.size = 0;
-        this.pendingOp = ExternalFilePendingOp.NO_OP;
-    }
-
-    public ExternalFile(DataverseName dataverseName, String datasetName, int fileNumber, String fileName,
-            Date lastModefiedTime, long size, ExternalFilePendingOp pendingOp) {
+    public ExternalFile(String databaseName, DataverseName dataverseName, String datasetName, int fileNumber,
+            String fileName, Date lastModefiedTime, long size, ExternalFilePendingOp pendingOp) {
+        this.databaseName = Objects.requireNonNull(databaseName);
         this.dataverseName = dataverseName;
         this.datasetName = datasetName;
         this.fileNumber = fileNumber;
diff --git a/asterixdb/asterix-metadata/src/main/java/org/apache/asterix/metadata/MetadataManager.java b/asterixdb/asterix-metadata/src/main/java/org/apache/asterix/metadata/MetadataManager.java
index b75fc3a..7d91f73 100644
--- a/asterixdb/asterix-metadata/src/main/java/org/apache/asterix/metadata/MetadataManager.java
+++ b/asterixdb/asterix-metadata/src/main/java/org/apache/asterix/metadata/MetadataManager.java
@@ -207,7 +207,7 @@
         } catch (RemoteException e) {
             throw new MetadataException(ErrorCode.REMOTE_EXCEPTION_WHEN_CALLING_METADATA_NODE, e);
         }
-        ctx.dropDataverse(dataverseName);
+        ctx.dropDataverse(database, dataverseName);
     }
 
     @Override
@@ -301,7 +301,7 @@
             throw new MetadataException(ErrorCode.REMOTE_EXCEPTION_WHEN_CALLING_METADATA_NODE, e);
         }
         // Drops the dataset from cache
-        ctx.dropDataset(dataverseName, datasetName);
+        ctx.dropDataset(database, dataverseName, datasetName);
     }
 
     @Override
@@ -402,7 +402,7 @@
         } catch (RemoteException e) {
             throw new MetadataException(ErrorCode.REMOTE_EXCEPTION_WHEN_CALLING_METADATA_NODE, e);
         }
-        ctx.dropDataDatatype(dataverseName, datatypeName);
+        ctx.dropDataDatatype(database, dataverseName, datatypeName);
     }
 
     @Override
@@ -468,7 +468,7 @@
         } catch (RemoteException e) {
             throw new MetadataException(ErrorCode.REMOTE_EXCEPTION_WHEN_CALLING_METADATA_NODE, e);
         }
-        ctx.dropIndex(dataverseName, datasetName, indexName);
+        ctx.dropIndex(database, dataverseName, datasetName, indexName);
     }
 
     @Override
@@ -673,7 +673,7 @@
         } catch (RemoteException e) {
             throw new MetadataException(ErrorCode.REMOTE_EXCEPTION_WHEN_CALLING_METADATA_NODE, e);
         }
-        mdTxnCtx.dropFullTextFilter(dataverseName, filterName);
+        mdTxnCtx.dropFullTextFilter(database, dataverseName, filterName);
     }
 
     @Override
@@ -786,7 +786,7 @@
         } catch (RemoteException e) {
             throw new MetadataException(ErrorCode.REMOTE_EXCEPTION_WHEN_CALLING_METADATA_NODE, e);
         }
-        mdTxnCtx.dropFullTextConfig(dataverseName, configName);
+        mdTxnCtx.dropFullTextConfig(database, dataverseName, configName);
     }
 
     @Override
@@ -826,7 +826,7 @@
         } catch (RemoteException e) {
             throw new MetadataException(ErrorCode.REMOTE_EXCEPTION_WHEN_CALLING_METADATA_NODE, e);
         }
-        ctx.dropAdapter(dataverseName, name);
+        ctx.dropAdapter(database, dataverseName, name);
     }
 
     @Override
@@ -849,7 +849,7 @@
         } catch (RemoteException e) {
             throw new MetadataException(ErrorCode.REMOTE_EXCEPTION_WHEN_CALLING_METADATA_NODE, e);
         }
-        ctx.dropLibrary(dataverseName, libraryName);
+        ctx.dropLibrary(database, dataverseName, libraryName);
     }
 
     @Override
@@ -938,7 +938,7 @@
             for (FeedConnection feedConnection : feedConnections) {
                 metadataNode.dropFeedConnection(ctx.getTxnId(), database, dataverseName, feedName,
                         feedConnection.getDatasetName());
-                ctx.dropFeedConnection(dataverseName, feedName, feedConnection.getDatasetName());
+                ctx.dropFeedConnection(database, dataverseName, feedName, feedConnection.getDatasetName());
             }
         } catch (RemoteException e) {
             throw new MetadataException(ErrorCode.REMOTE_EXCEPTION_WHEN_CALLING_METADATA_NODE, e);
@@ -975,7 +975,7 @@
         } catch (RemoteException e) {
             throw new MetadataException(ErrorCode.REMOTE_EXCEPTION_WHEN_CALLING_METADATA_NODE, e);
         }
-        ctx.dropFeedConnection(dataverseName, feedName, datasetName);
+        ctx.dropFeedConnection(database, dataverseName, feedName, datasetName);
     }
 
     @Override
@@ -1136,7 +1136,7 @@
             throw new MetadataException(ErrorCode.REMOTE_EXCEPTION_WHEN_CALLING_METADATA_NODE, e);
         }
         // reflect the dataset into the cache
-        ctx.dropDataset(dataset.getDataverseName(), dataset.getDatasetName());
+        ctx.dropDataset(dataset.getDatabaseName(), dataset.getDataverseName(), dataset.getDatasetName());
         ctx.addDataset(dataset);
     }
 
@@ -1148,7 +1148,7 @@
             throw new MetadataException(ErrorCode.REMOTE_EXCEPTION_WHEN_CALLING_METADATA_NODE, e);
         }
         // reflect the library into the cache
-        ctx.dropLibrary(library.getDataverseName(), library.getName());
+        ctx.dropLibrary(library.getDatabaseName(), library.getDataverseName(), library.getName());
         ctx.addLibrary(library);
     }
 
@@ -1172,7 +1172,7 @@
             throw new MetadataException(ErrorCode.REMOTE_EXCEPTION_WHEN_CALLING_METADATA_NODE, e);
         }
         // reflect the datatype into the cache
-        ctx.dropDataDatatype(datatype.getDataverseName(), datatype.getDatatypeName());
+        ctx.dropDataDatatype(datatype.getDatabaseName(), datatype.getDataverseName(), datatype.getDatatypeName());
         ctx.addDatatype(datatype);
     }
 
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 a8bbd45..0447c91 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
@@ -399,8 +399,9 @@
             if (dataset.getDatasetType() == DatasetType.INTERNAL) {
                 // Add the primary index for the dataset.
                 InternalDatasetDetails id = (InternalDatasetDetails) dataset.getDatasetDetails();
-                Index primaryIndex = Index.createPrimaryIndex(dataset.getDataverseName(), dataset.getDatasetName(),
-                        id.getPrimaryKey(), id.getKeySourceIndicator(), id.getPrimaryKeyType(), dataset.getPendingOp());
+                Index primaryIndex = Index.createPrimaryIndex(dataset.getDatabaseName(), dataset.getDataverseName(),
+                        dataset.getDatasetName(), id.getPrimaryKey(), id.getKeySourceIndicator(),
+                        id.getPrimaryKeyType(), dataset.getPendingOp());
 
                 addIndex(txnId, primaryIndex);
             }
diff --git a/asterixdb/asterix-metadata/src/main/java/org/apache/asterix/metadata/MetadataTransactionContext.java b/asterixdb/asterix-metadata/src/main/java/org/apache/asterix/metadata/MetadataTransactionContext.java
index 54bc0bc..40f6345 100644
--- a/asterixdb/asterix-metadata/src/main/java/org/apache/asterix/metadata/MetadataTransactionContext.java
+++ b/asterixdb/asterix-metadata/src/main/java/org/apache/asterix/metadata/MetadataTransactionContext.java
@@ -142,16 +142,16 @@
         logAndApply(new MetadataLogicalOperation(compactionPolicy, true));
     }
 
-    public void dropDataset(DataverseName dataverseName, String datasetName) {
-        Dataset dataset = new Dataset(dataverseName, datasetName, null, null, null, null, null, null, null, null, -1,
-                MetadataUtil.PENDING_NO_OP);
+    public void dropDataset(String database, DataverseName dataverseName, String datasetName) {
+        Dataset dataset = new Dataset(database, dataverseName, datasetName, null, null, null, null, null, null, null,
+                null, -1, MetadataUtil.PENDING_NO_OP);
         droppedCache.addDatasetIfNotExists(dataset);
         logAndApply(new MetadataLogicalOperation(dataset, false));
     }
 
-    public void dropIndex(DataverseName dataverseName, String datasetName, String indexName) {
-        Index index =
-                new Index(dataverseName, datasetName, indexName, null, null, false, false, MetadataUtil.PENDING_NO_OP);
+    public void dropIndex(String database, DataverseName dataverseName, String datasetName, String indexName) {
+        Index index = new Index(database, dataverseName, datasetName, indexName, null, null, false, false,
+                MetadataUtil.PENDING_NO_OP);
         droppedCache.addIndexIfNotExists(index);
         logAndApply(new MetadataLogicalOperation(index, false));
     }
@@ -162,8 +162,8 @@
         logAndApply(new MetadataLogicalOperation(database, false));
     }
 
-    public void dropDataverse(DataverseName dataverseName) {
-        Dataverse dataverse = new Dataverse(dataverseName, null, MetadataUtil.PENDING_NO_OP);
+    public void dropDataverse(String database, DataverseName dataverseName) {
+        Dataverse dataverse = new Dataverse(database, dataverseName, null, MetadataUtil.PENDING_NO_OP);
         droppedCache.addDataverseIfNotExists(dataverse);
         logAndApply(new MetadataLogicalOperation(dataverse, false));
     }
@@ -173,8 +173,8 @@
         logAndApply(new MetadataLogicalOperation(library, true));
     }
 
-    public void dropDataDatatype(DataverseName dataverseName, String datatypeName) {
-        Datatype datatype = new Datatype(dataverseName, datatypeName, null, false);
+    public void dropDataDatatype(String database, DataverseName dataverseName, String datatypeName) {
+        Datatype datatype = new Datatype(database, dataverseName, datatypeName, null, false);
         droppedCache.addDatatypeIfNotExists(datatype);
         logAndApply(new MetadataLogicalOperation(datatype, false));
     }
@@ -192,42 +192,43 @@
         logAndApply(new MetadataLogicalOperation(function, false));
     }
 
-    public void dropFullTextConfig(DataverseName dataverseName, String configName) {
-        FullTextConfigDescriptor config = new FullTextConfigDescriptor(dataverseName, configName, null, null);
+    public void dropFullTextConfig(String database, DataverseName dataverseName, String configName) {
+        FullTextConfigDescriptor config = new FullTextConfigDescriptor(database, dataverseName, configName, null, null);
         FullTextConfigMetadataEntity configMetadataEntity = new FullTextConfigMetadataEntity(config);
 
         droppedCache.addFullTextConfigIfNotExists(configMetadataEntity);
         logAndApply(new MetadataLogicalOperation(configMetadataEntity, false));
     }
 
-    public void dropFullTextFilter(DataverseName dataverseName, String filterName) {
-        AbstractFullTextFilterDescriptor filter = new AbstractFullTextFilterDescriptor(dataverseName, filterName) {
-            private static final long serialVersionUID = -8222222581298765902L;
+    public void dropFullTextFilter(String database, DataverseName dataverseName, String filterName) {
+        AbstractFullTextFilterDescriptor filter =
+                new AbstractFullTextFilterDescriptor(database, dataverseName, filterName) {
+                    private static final long serialVersionUID = -8222222581298765902L;
 
-            @Override
-            public FullTextFilterType getFilterType() {
-                return null;
-            }
+                    @Override
+                    public FullTextFilterType getFilterType() {
+                        return null;
+                    }
 
-            @Override
-            public IFullTextFilterEvaluatorFactory createEvaluatorFactory() {
-                return null;
-            }
-        };
+                    @Override
+                    public IFullTextFilterEvaluatorFactory createEvaluatorFactory() {
+                        return null;
+                    }
+                };
         FullTextFilterMetadataEntity filterMetadataEntity = new FullTextFilterMetadataEntity(filter);
         droppedCache.addFullTextFilterIfNotExists(filterMetadataEntity);
         logAndApply(new MetadataLogicalOperation(filterMetadataEntity, false));
     }
 
-    public void dropAdapter(DataverseName dataverseName, String adapterName) {
-        AdapterIdentifier adapterIdentifier = new AdapterIdentifier(dataverseName, adapterName);
-        DatasourceAdapter adapter = new DatasourceAdapter(adapterIdentifier, null, null, null, null);
+    public void dropAdapter(String database, DataverseName dataverseName, String adapterName) {
+        AdapterIdentifier adapterIdentifier = new AdapterIdentifier(database, dataverseName, adapterName);
+        DatasourceAdapter adapter = new DatasourceAdapter(adapterIdentifier, null, null, null, null, null);
         droppedCache.addAdapterIfNotExists(adapter);
         logAndApply(new MetadataLogicalOperation(adapter, false));
     }
 
-    public void dropLibrary(DataverseName dataverseName, String libraryName) {
-        Library library = new Library(dataverseName, libraryName, null, null, MetadataUtil.PENDING_NO_OP);
+    public void dropLibrary(String database, DataverseName dataverseName, String libraryName) {
+        Library library = new Library(database, dataverseName, libraryName, null, null, MetadataUtil.PENDING_NO_OP);
         droppedCache.addLibraryIfNotExists(library);
         logAndApply(new MetadataLogicalOperation(library, false));
     }
@@ -306,9 +307,9 @@
         logAndApply(new MetadataLogicalOperation(feedConnection, true));
     }
 
-    public void dropFeedConnection(DataverseName dataverseName, String feedName, String datasetName) {
+    public void dropFeedConnection(String database, DataverseName dataverseName, String feedName, String datasetName) {
         FeedConnection feedConnection =
-                new FeedConnection(dataverseName, feedName, datasetName, null, null, null, null);
+                new FeedConnection(database, dataverseName, feedName, datasetName, null, null, null, null);
         droppedCache.addFeedConnectionIfNotExists(feedConnection);
         logAndApply(new MetadataLogicalOperation(feedConnection, false));
     }
diff --git a/asterixdb/asterix-metadata/src/main/java/org/apache/asterix/metadata/api/IMetadataEntity.java b/asterixdb/asterix-metadata/src/main/java/org/apache/asterix/metadata/api/IMetadataEntity.java
index 482cc3b..4403989 100644
--- a/asterixdb/asterix-metadata/src/main/java/org/apache/asterix/metadata/api/IMetadataEntity.java
+++ b/asterixdb/asterix-metadata/src/main/java/org/apache/asterix/metadata/api/IMetadataEntity.java
@@ -24,7 +24,7 @@
 
 public interface IMetadataEntity<T> extends Serializable {
 
-    public T addToCache(MetadataCache cache);
+    T addToCache(MetadataCache cache);
 
-    public T dropFromCache(MetadataCache cache);
+    T dropFromCache(MetadataCache cache);
 }
diff --git a/asterixdb/asterix-metadata/src/main/java/org/apache/asterix/metadata/api/IMetadataIndex.java b/asterixdb/asterix-metadata/src/main/java/org/apache/asterix/metadata/api/IMetadataIndex.java
index 522c2e6..21329ac 100644
--- a/asterixdb/asterix-metadata/src/main/java/org/apache/asterix/metadata/api/IMetadataIndex.java
+++ b/asterixdb/asterix-metadata/src/main/java/org/apache/asterix/metadata/api/IMetadataIndex.java
@@ -36,6 +36,9 @@
  * Descriptor interface for a primary or secondary index on metadata datasets.
  */
 public interface IMetadataIndex extends Serializable {
+
+    public String getDatabaseName();
+
     public DataverseName getDataverseName();
 
     public String getNodeGroupName();
diff --git a/asterixdb/asterix-metadata/src/main/java/org/apache/asterix/metadata/bootstrap/MetadataBootstrap.java b/asterixdb/asterix-metadata/src/main/java/org/apache/asterix/metadata/bootstrap/MetadataBootstrap.java
index d3a7535..e0966f8 100644
--- a/asterixdb/asterix-metadata/src/main/java/org/apache/asterix/metadata/bootstrap/MetadataBootstrap.java
+++ b/asterixdb/asterix-metadata/src/main/java/org/apache/asterix/metadata/bootstrap/MetadataBootstrap.java
@@ -219,9 +219,10 @@
                     indexes[i].getPartitioningExpr(), indexes[i].getPartitioningExpr(), null,
                     indexes[i].getPartitioningExprType(), false, null, null);
             MetadataManager.INSTANCE.addDataset(mdTxnCtx,
-                    new Dataset(indexes[i].getDataverseName(), indexes[i].getIndexedDatasetName(),
-                            indexes[i].getDataverseName(), indexes[i].getPayloadRecordType().getTypeName(),
-                            indexes[i].getNodeGroupName(), StorageConstants.DEFAULT_COMPACTION_POLICY_NAME,
+                    new Dataset(indexes[i].getDatabaseName(), indexes[i].getDataverseName(),
+                            indexes[i].getIndexedDatasetName(), indexes[i].getDataverseName(),
+                            indexes[i].getPayloadRecordType().getTypeName(), indexes[i].getNodeGroupName(),
+                            StorageConstants.DEFAULT_COMPACTION_POLICY_NAME,
                             StorageConstants.DEFAULT_COMPACTION_POLICY_PROPERTIES, id, new HashMap<>(),
                             DatasetType.INTERNAL, indexes[i].getDatasetId().getId(), MetadataUtil.PENDING_NO_OP));
         }
@@ -245,8 +246,8 @@
         types.addAll(BuiltinTypeMap.getAllBuiltinTypes());
         getMetadataTypes(types);
         for (int i = 0; i < types.size(); i++) {
-            MetadataManager.INSTANCE.addDatatype(mdTxnCtx, new Datatype(MetadataConstants.METADATA_DATAVERSE_NAME,
-                    types.get(i).getTypeName(), types.get(i), false));
+            MetadataManager.INSTANCE.addDatatype(mdTxnCtx, new Datatype(MetadataConstants.SYSTEM_DATABASE,
+                    MetadataConstants.METADATA_DATAVERSE_NAME, types.get(i).getTypeName(), types.get(i), false));
         }
         MetadataManager.INSTANCE.addDatatype(mdTxnCtx, MetadataBuiltinEntities.ANY_OBJECT_DATATYPE);
         if (LOGGER.isInfoEnabled()) {
@@ -298,8 +299,8 @@
      */
     private static void insertNewCompactionPoliciesIfNotExist(MetadataTransactionContext mdTxnCtx)
             throws AlgebricksException {
-        if (MetadataManager.INSTANCE.getCompactionPolicy(mdTxnCtx, null, MetadataConstants.METADATA_DATAVERSE_NAME,
-                ConcurrentMergePolicyFactory.NAME) == null) {
+        if (MetadataManager.INSTANCE.getCompactionPolicy(mdTxnCtx, MetadataConstants.SYSTEM_DATABASE,
+                MetadataConstants.METADATA_DATAVERSE_NAME, ConcurrentMergePolicyFactory.NAME) == null) {
             CompactionPolicy compactionPolicy = getCompactionPolicyEntity(ConcurrentMergePolicyFactory.class.getName());
             MetadataManager.INSTANCE.addCompactionPolicy(mdTxnCtx, compactionPolicy);
         }
@@ -308,13 +309,14 @@
     private static void insertSynonymEntitiesIfNotExist(MetadataTransactionContext mdTxnCtx,
             MetadataIndexesProvider mdIndexesProvider) throws AlgebricksException {
         IAType synonymDatasetRecordType = mdIndexesProvider.getSynonymEntity().getRecordType();
-        if (MetadataManager.INSTANCE.getDatatype(mdTxnCtx, null, MetadataConstants.METADATA_DATAVERSE_NAME,
-                synonymDatasetRecordType.getTypeName()) == null) {
-            MetadataManager.INSTANCE.addDatatype(mdTxnCtx, new Datatype(MetadataConstants.METADATA_DATAVERSE_NAME,
-                    synonymDatasetRecordType.getTypeName(), synonymDatasetRecordType, false));
+        if (MetadataManager.INSTANCE.getDatatype(mdTxnCtx, MetadataConstants.SYSTEM_DATABASE,
+                MetadataConstants.METADATA_DATAVERSE_NAME, synonymDatasetRecordType.getTypeName()) == null) {
+            MetadataManager.INSTANCE.addDatatype(mdTxnCtx,
+                    new Datatype(MetadataConstants.SYSTEM_DATABASE, MetadataConstants.METADATA_DATAVERSE_NAME,
+                            synonymDatasetRecordType.getTypeName(), synonymDatasetRecordType, false));
         }
-        if (MetadataManager.INSTANCE.getDataset(mdTxnCtx, null, MetadataConstants.METADATA_DATAVERSE_NAME,
-                MetadataConstants.SYNONYM_DATASET_NAME) == null) {
+        if (MetadataManager.INSTANCE.getDataset(mdTxnCtx, MetadataConstants.SYSTEM_DATABASE,
+                MetadataConstants.METADATA_DATAVERSE_NAME, MetadataConstants.SYNONYM_DATASET_NAME) == null) {
             insertMetadataDatasets(mdTxnCtx, new IMetadataIndex[] { mdIndexesProvider.getSynonymEntity().getIndex() });
         }
     }
@@ -329,25 +331,27 @@
         // We need to insert data types first because datasets depend on data types
         // ToDo: create a new function to reduce duplicated code here: addDatatypeIfNotExist()
         IAType fullTextConfigRecordType = metadataIndexesProvider.getFullTextConfigEntity().getRecordType();
-        if (MetadataManager.INSTANCE.getDatatype(mdTxnCtx, null, MetadataConstants.METADATA_DATAVERSE_NAME,
-                fullTextConfigRecordType.getTypeName()) == null) {
-            MetadataManager.INSTANCE.addDatatype(mdTxnCtx, new Datatype(MetadataConstants.METADATA_DATAVERSE_NAME,
-                    fullTextConfigRecordType.getTypeName(), fullTextConfigRecordType, false));
+        if (MetadataManager.INSTANCE.getDatatype(mdTxnCtx, MetadataConstants.SYSTEM_DATABASE,
+                MetadataConstants.METADATA_DATAVERSE_NAME, fullTextConfigRecordType.getTypeName()) == null) {
+            MetadataManager.INSTANCE.addDatatype(mdTxnCtx,
+                    new Datatype(MetadataConstants.SYSTEM_DATABASE, MetadataConstants.METADATA_DATAVERSE_NAME,
+                            fullTextConfigRecordType.getTypeName(), fullTextConfigRecordType, false));
         }
         IAType fullTextFilterRecordType = metadataIndexesProvider.getFullTextFilterEntity().getRecordType();
-        if (MetadataManager.INSTANCE.getDatatype(mdTxnCtx, null, MetadataConstants.METADATA_DATAVERSE_NAME,
-                fullTextFilterRecordType.getTypeName()) == null) {
-            MetadataManager.INSTANCE.addDatatype(mdTxnCtx, new Datatype(MetadataConstants.METADATA_DATAVERSE_NAME,
-                    fullTextFilterRecordType.getTypeName(), fullTextFilterRecordType, false));
+        if (MetadataManager.INSTANCE.getDatatype(mdTxnCtx, MetadataConstants.SYSTEM_DATABASE,
+                MetadataConstants.METADATA_DATAVERSE_NAME, fullTextFilterRecordType.getTypeName()) == null) {
+            MetadataManager.INSTANCE.addDatatype(mdTxnCtx,
+                    new Datatype(MetadataConstants.SYSTEM_DATABASE, MetadataConstants.METADATA_DATAVERSE_NAME,
+                            fullTextFilterRecordType.getTypeName(), fullTextFilterRecordType, false));
         }
 
-        if (MetadataManager.INSTANCE.getDataset(mdTxnCtx, null, MetadataConstants.METADATA_DATAVERSE_NAME,
-                MetadataConstants.FULL_TEXT_CONFIG_DATASET_NAME) == null) {
+        if (MetadataManager.INSTANCE.getDataset(mdTxnCtx, MetadataConstants.SYSTEM_DATABASE,
+                MetadataConstants.METADATA_DATAVERSE_NAME, MetadataConstants.FULL_TEXT_CONFIG_DATASET_NAME) == null) {
             insertMetadataDatasets(mdTxnCtx,
                     new IMetadataIndex[] { metadataIndexesProvider.getFullTextConfigEntity().getIndex() });
         }
-        if (MetadataManager.INSTANCE.getDataset(mdTxnCtx, null, MetadataConstants.METADATA_DATAVERSE_NAME,
-                MetadataConstants.FULL_TEXT_FILTER_DATASET_NAME) == null) {
+        if (MetadataManager.INSTANCE.getDataset(mdTxnCtx, MetadataConstants.SYSTEM_DATABASE,
+                MetadataConstants.METADATA_DATAVERSE_NAME, MetadataConstants.FULL_TEXT_FILTER_DATASET_NAME) == null) {
             insertMetadataDatasets(mdTxnCtx,
                     new IMetadataIndex[] { metadataIndexesProvider.getFullTextFilterEntity().getIndex() });
         }
@@ -357,8 +361,10 @@
         try {
             String adapterName =
                     ((ITypedAdapterFactory) (Class.forName(adapterFactoryClassName).newInstance())).getAlias();
-            return new DatasourceAdapter(new AdapterIdentifier(MetadataConstants.METADATA_DATAVERSE_NAME, adapterName),
-                    IDataSourceAdapter.AdapterType.INTERNAL, adapterFactoryClassName, null, null);
+            return new DatasourceAdapter(
+                    new AdapterIdentifier(MetadataConstants.SYSTEM_DATABASE, MetadataConstants.METADATA_DATAVERSE_NAME,
+                            adapterName),
+                    IDataSourceAdapter.AdapterType.INTERNAL, adapterFactoryClassName, null, null, null);
         } catch (InstantiationException | IllegalAccessException | ClassNotFoundException e) {
             throw new MetadataException("Unable to instantiate builtin Adapter", e);
         }
@@ -369,8 +375,8 @@
         try {
             String policyName =
                     ((ILSMMergePolicyFactory) (Class.forName(compactionPolicyClassName).newInstance())).getName();
-            return new CompactionPolicy(MetadataConstants.METADATA_DATAVERSE_NAME, policyName,
-                    compactionPolicyClassName);
+            return new CompactionPolicy(MetadataConstants.SYSTEM_DATABASE, MetadataConstants.METADATA_DATAVERSE_NAME,
+                    policyName, compactionPolicyClassName);
         } catch (InstantiationException | IllegalAccessException | ClassNotFoundException e) {
             throw new MetadataException("Unable to instantiate builtin Merge Policy Factory", e);
         }
diff --git a/asterixdb/asterix-metadata/src/main/java/org/apache/asterix/metadata/bootstrap/MetadataBuiltinEntities.java b/asterixdb/asterix-metadata/src/main/java/org/apache/asterix/metadata/bootstrap/MetadataBuiltinEntities.java
index 4077573..2b010e5 100644
--- a/asterixdb/asterix-metadata/src/main/java/org/apache/asterix/metadata/bootstrap/MetadataBuiltinEntities.java
+++ b/asterixdb/asterix-metadata/src/main/java/org/apache/asterix/metadata/bootstrap/MetadataBuiltinEntities.java
@@ -36,14 +36,16 @@
             new Database(MetadataConstants.DEFAULT_DATABASE, false, MetadataUtil.PENDING_NO_OP);
 
     //--------------------------------------- Dataverses ----------------------------------------//
-    public static final Dataverse METADATA_DATAVERSE = new Dataverse(MetadataConstants.METADATA_DATAVERSE_NAME,
-            NonTaggedDataFormat.NON_TAGGED_DATA_FORMAT, MetadataUtil.PENDING_NO_OP);
+    public static final Dataverse METADATA_DATAVERSE =
+            new Dataverse(MetadataConstants.SYSTEM_DATABASE, MetadataConstants.METADATA_DATAVERSE_NAME,
+                    NonTaggedDataFormat.NON_TAGGED_DATA_FORMAT, MetadataUtil.PENDING_NO_OP);
     public static final DataverseName DEFAULT_DATAVERSE_NAME = DataverseName.createBuiltinDataverseName("Default");
-    public static final Dataverse DEFAULT_DATAVERSE =
-            new Dataverse(DEFAULT_DATAVERSE_NAME, NonTaggedDataFormat.class.getName(), MetadataUtil.PENDING_NO_OP);
+    public static final Dataverse DEFAULT_DATAVERSE = new Dataverse(MetadataConstants.DEFAULT_DATABASE,
+            DEFAULT_DATAVERSE_NAME, NonTaggedDataFormat.class.getName(), MetadataUtil.PENDING_NO_OP);
     //--------------------------------------- Datatypes -----------------------------------------//
-    public static final Datatype ANY_OBJECT_DATATYPE = new Datatype(MetadataConstants.METADATA_DATAVERSE_NAME,
-            RecordUtil.FULLY_OPEN_RECORD_TYPE.getTypeName(), RecordUtil.FULLY_OPEN_RECORD_TYPE, false);
+    public static final Datatype ANY_OBJECT_DATATYPE =
+            new Datatype(MetadataConstants.SYSTEM_DATABASE, MetadataConstants.METADATA_DATAVERSE_NAME,
+                    RecordUtil.FULLY_OPEN_RECORD_TYPE.getTypeName(), RecordUtil.FULLY_OPEN_RECORD_TYPE, false);
 
     private MetadataBuiltinEntities() {
     }
diff --git a/asterixdb/asterix-metadata/src/main/java/org/apache/asterix/metadata/bootstrap/MetadataIndex.java b/asterixdb/asterix-metadata/src/main/java/org/apache/asterix/metadata/bootstrap/MetadataIndex.java
index c33cac1..7d31ced 100644
--- a/asterixdb/asterix-metadata/src/main/java/org/apache/asterix/metadata/bootstrap/MetadataIndex.java
+++ b/asterixdb/asterix-metadata/src/main/java/org/apache/asterix/metadata/bootstrap/MetadataIndex.java
@@ -183,6 +183,11 @@
     }
 
     @Override
+    public String getDatabaseName() {
+        return MetadataConstants.SYSTEM_DATABASE;
+    }
+
+    @Override
     public DataverseName getDataverseName() {
         return MetadataConstants.METADATA_DATAVERSE_NAME;
     }
diff --git a/asterixdb/asterix-metadata/src/main/java/org/apache/asterix/metadata/declared/DatasetDataSource.java b/asterixdb/asterix-metadata/src/main/java/org/apache/asterix/metadata/declared/DatasetDataSource.java
index e5842dc..39a70f8 100644
--- a/asterixdb/asterix-metadata/src/main/java/org/apache/asterix/metadata/declared/DatasetDataSource.java
+++ b/asterixdb/asterix-metadata/src/main/java/org/apache/asterix/metadata/declared/DatasetDataSource.java
@@ -40,6 +40,7 @@
 import org.apache.asterix.metadata.entities.InternalDatasetDetails;
 import org.apache.asterix.metadata.utils.IndexUtil;
 import org.apache.asterix.metadata.utils.KeyFieldTypeUtil;
+import org.apache.asterix.metadata.utils.MetadataUtil;
 import org.apache.asterix.om.types.ARecordType;
 import org.apache.asterix.om.types.IAType;
 import org.apache.asterix.runtime.projection.ExternalDatasetProjectionFiltrationInfo;
@@ -148,8 +149,8 @@
                         tupleFilterFactory, outputLimit);
             case INTERNAL:
                 DataSourceId id = getId();
-                String database = null;
                 DataverseName dataverseName = id.getDataverseName();
+                String database = MetadataUtil.resolveDatabase(null, dataverseName);
                 String datasetName = id.getDatasourceName();
                 Index primaryIndex = MetadataManager.INSTANCE.getIndex(metadataProvider.getMetadataTxnContext(),
                         database, dataverseName, datasetName, datasetName);
diff --git a/asterixdb/asterix-metadata/src/main/java/org/apache/asterix/metadata/entities/CompactionPolicy.java b/asterixdb/asterix-metadata/src/main/java/org/apache/asterix/metadata/entities/CompactionPolicy.java
index aae1da1..29a44aa 100644
--- a/asterixdb/asterix-metadata/src/main/java/org/apache/asterix/metadata/entities/CompactionPolicy.java
+++ b/asterixdb/asterix-metadata/src/main/java/org/apache/asterix/metadata/entities/CompactionPolicy.java
@@ -32,12 +32,13 @@
 
     private static final long serialVersionUID = 3L;
 
-    private final String databaseName = null;
+    private final String databaseName;
     private final DataverseName dataverseName;
     private final String policyName;
     private final String className;
 
-    public CompactionPolicy(DataverseName dataverseName, String policyName, String className) {
+    public CompactionPolicy(String databaseName, DataverseName dataverseName, String policyName, String className) {
+        this.databaseName = Objects.requireNonNull(databaseName);
         this.dataverseName = dataverseName;
         this.policyName = policyName;
         this.className = className;
diff --git a/asterixdb/asterix-metadata/src/main/java/org/apache/asterix/metadata/entities/Dataset.java b/asterixdb/asterix-metadata/src/main/java/org/apache/asterix/metadata/entities/Dataset.java
index cd8c64b..5e46b6c 100644
--- a/asterixdb/asterix-metadata/src/main/java/org/apache/asterix/metadata/entities/Dataset.java
+++ b/asterixdb/asterix-metadata/src/main/java/org/apache/asterix/metadata/entities/Dataset.java
@@ -142,7 +142,7 @@
      * Members
      */
     private final int datasetId;
-    private final String databaseName = null;
+    private final String databaseName;
     private final DataverseName dataverseName;
     private final String datasetName;
     private final DataverseName recordTypeDataverseName;
@@ -161,38 +161,42 @@
     private final DatasetFullyQualifiedName datasetFullyQualifiedName;
     private final DatasetFormatInfo datasetFormatInfo;
 
-    public Dataset(DataverseName dataverseName, String datasetName, DataverseName recordTypeDataverseName,
-            String recordTypeName, String nodeGroupName, String compactionPolicy,
+    public Dataset(String databaseName, DataverseName dataverseName, String datasetName,
+            DataverseName recordTypeDataverseName, String recordTypeName, String nodeGroupName, String compactionPolicy,
             Map<String, String> compactionPolicyProperties, IDatasetDetails datasetDetails, Map<String, String> hints,
             DatasetType datasetType, int datasetId, int pendingOp) {
-        this(dataverseName, datasetName, recordTypeDataverseName, recordTypeName, /*metaTypeDataverseName*/null,
-                /*metaTypeName*/null, nodeGroupName, compactionPolicy, compactionPolicyProperties, datasetDetails,
-                hints, datasetType, datasetId, pendingOp, CompressionManager.NONE, DatasetFormatInfo.SYSTEM_DEFAULT);
+        this(databaseName, dataverseName, datasetName, recordTypeDataverseName, recordTypeName,
+                /*metaTypeDataverseName*/null, /*metaTypeName*/null, nodeGroupName, compactionPolicy,
+                compactionPolicyProperties, datasetDetails, hints, datasetType, datasetId, pendingOp,
+                CompressionManager.NONE, DatasetFormatInfo.SYSTEM_DEFAULT);
     }
 
-    public Dataset(DataverseName dataverseName, String datasetName, DataverseName itemTypeDataverseName,
-            String itemTypeName, DataverseName metaItemTypeDataverseName, String metaItemTypeName, String nodeGroupName,
-            String compactionPolicy, Map<String, String> compactionPolicyProperties, IDatasetDetails datasetDetails,
-            Map<String, String> hints, DatasetType datasetType, int datasetId, int pendingOp, String compressionScheme,
+    public Dataset(String databaseName, DataverseName dataverseName, String datasetName,
+            DataverseName itemTypeDataverseName, String itemTypeName, DataverseName metaItemTypeDataverseName,
+            String metaItemTypeName, String nodeGroupName, String compactionPolicy,
+            Map<String, String> compactionPolicyProperties, IDatasetDetails datasetDetails, Map<String, String> hints,
+            DatasetType datasetType, int datasetId, int pendingOp, String compressionScheme,
             DatasetFormatInfo datasetFormatInfo) {
-        this(dataverseName, datasetName, itemTypeDataverseName, itemTypeName, metaItemTypeDataverseName,
+        this(databaseName, dataverseName, datasetName, itemTypeDataverseName, itemTypeName, metaItemTypeDataverseName,
                 metaItemTypeName, nodeGroupName, compactionPolicy, compactionPolicyProperties, datasetDetails, hints,
                 datasetType, datasetId, pendingOp, 0L, compressionScheme, datasetFormatInfo);
     }
 
     public Dataset(Dataset dataset) {
-        this(dataset.dataverseName, dataset.datasetName, dataset.recordTypeDataverseName, dataset.recordTypeName,
-                dataset.metaTypeDataverseName, dataset.metaTypeName, dataset.nodeGroupName,
+        this(dataset.databaseName, dataset.dataverseName, dataset.datasetName, dataset.recordTypeDataverseName,
+                dataset.recordTypeName, dataset.metaTypeDataverseName, dataset.metaTypeName, dataset.nodeGroupName,
                 dataset.compactionPolicyFactory, dataset.compactionPolicyProperties, dataset.datasetDetails,
                 dataset.hints, dataset.datasetType, dataset.datasetId, dataset.pendingOp, dataset.rebalanceCount,
                 dataset.compressionScheme, dataset.datasetFormatInfo);
     }
 
-    public Dataset(DataverseName dataverseName, String datasetName, DataverseName itemTypeDataverseName,
-            String itemTypeName, DataverseName metaItemTypeDataverseName, String metaItemTypeName, String nodeGroupName,
-            String compactionPolicy, Map<String, String> compactionPolicyProperties, IDatasetDetails datasetDetails,
-            Map<String, String> hints, DatasetType datasetType, int datasetId, int pendingOp, long rebalanceCount,
-            String compressionScheme, DatasetFormatInfo datasetFormatInfo) {
+    public Dataset(String databaseName, DataverseName dataverseName, String datasetName,
+            DataverseName itemTypeDataverseName, String itemTypeName, DataverseName metaItemTypeDataverseName,
+            String metaItemTypeName, String nodeGroupName, String compactionPolicy,
+            Map<String, String> compactionPolicyProperties, IDatasetDetails datasetDetails, Map<String, String> hints,
+            DatasetType datasetType, int datasetId, int pendingOp, long rebalanceCount, String compressionScheme,
+            DatasetFormatInfo datasetFormatInfo) {
+        this.databaseName = Objects.requireNonNull(databaseName);
         this.dataverseName = dataverseName;
         this.datasetName = datasetName;
         this.recordTypeName = itemTypeName;
@@ -367,7 +371,7 @@
             // #. mark the existing dataset as PendingDropOp
             MetadataManager.INSTANCE.dropDataset(mdTxnCtx.getValue(), databaseName, dataverseName, datasetName, force);
             MetadataManager.INSTANCE.addDataset(mdTxnCtx.getValue(),
-                    new Dataset(dataverseName, datasetName, getItemTypeDataverseName(), getItemTypeName(),
+                    new Dataset(databaseName, dataverseName, datasetName, getItemTypeDataverseName(), getItemTypeName(),
                             getMetaItemTypeDataverseName(), getMetaItemTypeName(), getNodeGroupName(),
                             getCompactionPolicy(), getCompactionPolicyProperties(), getDatasetDetails(), getHints(),
                             getDatasetType(), getDatasetId(), MetadataUtil.PENDING_DROP_OP, getCompressionScheme(),
@@ -392,12 +396,12 @@
         MetadataManager.INSTANCE.dropDataset(mdTxnCtx.getValue(), databaseName, dataverseName, datasetName, force);
 
         // drop inline types
-        String recordTypeDatabase = null;
+        String recordTypeDatabase = MetadataUtil.resolveDatabase(null, recordTypeDataverseName);
         if (TypeUtil.isDatasetInlineTypeName(this, recordTypeDataverseName, recordTypeName)) {
             MetadataManager.INSTANCE.dropDatatype(mdTxnCtx.getValue(), recordTypeDatabase, recordTypeDataverseName,
                     recordTypeName);
         }
-        String metaTypeDatabase = null;
+        String metaTypeDatabase = MetadataUtil.resolveDatabase(null, metaTypeDataverseName);
         if (hasMetaPart() && TypeUtil.isDatasetInlineTypeName(this, metaTypeDataverseName, metaTypeName)) {
             MetadataManager.INSTANCE.dropDatatype(mdTxnCtx.getValue(), metaTypeDatabase, metaTypeDataverseName,
                     metaTypeName);
@@ -827,11 +831,11 @@
 
     // Gets the target dataset for the purpose of rebalance.
     public Dataset getTargetDatasetForRebalance(String targetNodeGroupName) {
-        return new Dataset(this.dataverseName, this.datasetName, this.recordTypeDataverseName, this.recordTypeName,
-                this.metaTypeDataverseName, this.metaTypeName, targetNodeGroupName, this.compactionPolicyFactory,
-                this.compactionPolicyProperties, this.datasetDetails, this.hints, this.datasetType,
-                DatasetIdFactory.generateAlternatingDatasetId(this.datasetId), this.pendingOp, this.rebalanceCount + 1,
-                this.compressionScheme, this.datasetFormatInfo);
+        return new Dataset(this.databaseName, this.dataverseName, this.datasetName, this.recordTypeDataverseName,
+                this.recordTypeName, this.metaTypeDataverseName, this.metaTypeName, targetNodeGroupName,
+                this.compactionPolicyFactory, this.compactionPolicyProperties, this.datasetDetails, this.hints,
+                this.datasetType, DatasetIdFactory.generateAlternatingDatasetId(this.datasetId), this.pendingOp,
+                this.rebalanceCount + 1, this.compressionScheme, this.datasetFormatInfo);
     }
 
     // Gets an array of partition numbers for this dataset.
diff --git a/asterixdb/asterix-metadata/src/main/java/org/apache/asterix/metadata/entities/DatasourceAdapter.java b/asterixdb/asterix-metadata/src/main/java/org/apache/asterix/metadata/entities/DatasourceAdapter.java
index eedfe8d..4edc335 100644
--- a/asterixdb/asterix-metadata/src/main/java/org/apache/asterix/metadata/entities/DatasourceAdapter.java
+++ b/asterixdb/asterix-metadata/src/main/java/org/apache/asterix/metadata/entities/DatasourceAdapter.java
@@ -26,19 +26,21 @@
 
 public class DatasourceAdapter implements IMetadataEntity<DatasourceAdapter> {
 
-    private static final long serialVersionUID = 3L;
+    private static final long serialVersionUID = 4L;
 
     private final AdapterIdentifier adapterIdentifier;
     private final String classname;
     private final AdapterType type;
+    private final String libraryDatabase;
     private final DataverseName libraryDataverseName;
     private final String libraryName;
 
     public DatasourceAdapter(AdapterIdentifier adapterIdentifier, AdapterType type, String classname,
-            DataverseName libraryDataverseName, String libraryName) {
+            String libraryDatabase, DataverseName libraryDataverseName, String libraryName) {
         this.adapterIdentifier = adapterIdentifier;
         this.type = type;
         this.classname = classname;
+        this.libraryDatabase = libraryDatabase;
         this.libraryDataverseName = libraryDataverseName;
         this.libraryName = libraryName;
     }
@@ -65,6 +67,10 @@
         return type;
     }
 
+    public String getLibraryDatabaseName() {
+        return libraryDatabase;
+    }
+
     public DataverseName getLibraryDataverseName() {
         return libraryDataverseName;
     }
diff --git a/asterixdb/asterix-metadata/src/main/java/org/apache/asterix/metadata/entities/Datatype.java b/asterixdb/asterix-metadata/src/main/java/org/apache/asterix/metadata/entities/Datatype.java
index d3d1787..bbf265f 100644
--- a/asterixdb/asterix-metadata/src/main/java/org/apache/asterix/metadata/entities/Datatype.java
+++ b/asterixdb/asterix-metadata/src/main/java/org/apache/asterix/metadata/entities/Datatype.java
@@ -19,6 +19,8 @@
 
 package org.apache.asterix.metadata.entities;
 
+import java.util.Objects;
+
 import org.apache.asterix.common.metadata.DataverseName;
 import org.apache.asterix.common.transactions.TxnId;
 import org.apache.asterix.metadata.MetadataCache;
@@ -35,13 +37,15 @@
 
     private static final long serialVersionUID = 3L;
 
-    private final String databaseName = null;
+    private final String databaseName;
     private final DataverseName dataverseName;
     private final String datatypeName;
     private final IAType datatype;
     private final boolean isAnonymous;
 
-    public Datatype(DataverseName dataverseName, String datatypeName, IAType datatype, boolean isAnonymous) {
+    public Datatype(String databaseName, DataverseName dataverseName, String datatypeName, IAType datatype,
+            boolean isAnonymous) {
+        this.databaseName = Objects.requireNonNull(databaseName);
         this.dataverseName = dataverseName;
         this.datatypeName = datatypeName;
         this.datatype = datatype;
diff --git a/asterixdb/asterix-metadata/src/main/java/org/apache/asterix/metadata/entities/Dataverse.java b/asterixdb/asterix-metadata/src/main/java/org/apache/asterix/metadata/entities/Dataverse.java
index 866fb8b..bba1763 100644
--- a/asterixdb/asterix-metadata/src/main/java/org/apache/asterix/metadata/entities/Dataverse.java
+++ b/asterixdb/asterix-metadata/src/main/java/org/apache/asterix/metadata/entities/Dataverse.java
@@ -31,12 +31,13 @@
 public class Dataverse implements IMetadataEntity<Dataverse> {
 
     private static final long serialVersionUID = 3L;
-    private final String databaseName = null;
+    private final String databaseName;
     private final DataverseName dataverseName;
     private final String dataFormat;
     private final int pendingOp;
 
-    public Dataverse(DataverseName dataverseName, String format, int pendingOp) {
+    public Dataverse(String databaseName, DataverseName dataverseName, String format, int pendingOp) {
+        this.databaseName = Objects.requireNonNull(databaseName);
         this.dataverseName = dataverseName;
         this.dataFormat = format;
         this.pendingOp = pendingOp;
diff --git a/asterixdb/asterix-metadata/src/main/java/org/apache/asterix/metadata/entities/Feed.java b/asterixdb/asterix-metadata/src/main/java/org/apache/asterix/metadata/entities/Feed.java
index cd0c0f6..e78b7d4 100644
--- a/asterixdb/asterix-metadata/src/main/java/org/apache/asterix/metadata/entities/Feed.java
+++ b/asterixdb/asterix-metadata/src/main/java/org/apache/asterix/metadata/entities/Feed.java
@@ -35,11 +35,11 @@
     public static final String EXTENSION_NAME = "Feed";
 
     /** A unique identifier for the feed */
-    private EntityId feedId;
+    private final EntityId feedId;
     /** A string representation of the instance **/
-    private String displayName;
+    private final String displayName;
     /** Feed configurations */
-    private Map<String, String> feedConfiguration;
+    private final Map<String, String> feedConfiguration;
 
     public Feed(DataverseName dataverseName, String feedName, Map<String, String> feedConfiguration) {
         this.feedId = new EntityId(EXTENSION_NAME, dataverseName, feedName);
diff --git a/asterixdb/asterix-metadata/src/main/java/org/apache/asterix/metadata/entities/FeedConnection.java b/asterixdb/asterix-metadata/src/main/java/org/apache/asterix/metadata/entities/FeedConnection.java
index 213682a..06ffce4 100644
--- a/asterixdb/asterix-metadata/src/main/java/org/apache/asterix/metadata/entities/FeedConnection.java
+++ b/asterixdb/asterix-metadata/src/main/java/org/apache/asterix/metadata/entities/FeedConnection.java
@@ -20,6 +20,7 @@
 package org.apache.asterix.metadata.entities;
 
 import java.util.List;
+import java.util.Objects;
 
 import org.apache.asterix.active.EntityId;
 import org.apache.asterix.common.functions.FunctionSignature;
@@ -37,7 +38,7 @@
 
     private final EntityId feedId;
     private final String connectionId;
-    private final String databaseName = null;
+    private final String databaseName;
     private final DataverseName dataverseName;
     private final String feedName;
     private final String datasetName;
@@ -46,8 +47,9 @@
     private final String outputType;
     private final List<FunctionSignature> appliedFunctions;
 
-    public FeedConnection(DataverseName dataverseName, String feedName, String datasetName,
+    public FeedConnection(String databaseName, DataverseName dataverseName, String feedName, String datasetName,
             List<FunctionSignature> appliedFunctions, String policyName, String whereClauseBody, String outputType) {
+        this.databaseName = Objects.requireNonNull(databaseName);
         this.dataverseName = dataverseName;
         this.feedName = feedName;
         this.datasetName = datasetName;
diff --git a/asterixdb/asterix-metadata/src/main/java/org/apache/asterix/metadata/entities/FeedPolicyEntity.java b/asterixdb/asterix-metadata/src/main/java/org/apache/asterix/metadata/entities/FeedPolicyEntity.java
index 65076c8..6a7ada2 100644
--- a/asterixdb/asterix-metadata/src/main/java/org/apache/asterix/metadata/entities/FeedPolicyEntity.java
+++ b/asterixdb/asterix-metadata/src/main/java/org/apache/asterix/metadata/entities/FeedPolicyEntity.java
@@ -31,9 +31,9 @@
  */
 public class FeedPolicyEntity extends FeedPolicy implements IMetadataEntity<FeedPolicyEntity> {
 
-    public FeedPolicyEntity(DataverseName dataverseName, String policyName, String description,
+    public FeedPolicyEntity(String databaseName, DataverseName dataverseName, String policyName, String description,
             Map<String, String> properties) {
-        super(dataverseName, policyName, description, properties);
+        super(databaseName, dataverseName, policyName, description, properties);
     }
 
     private static final long serialVersionUID = 2L;
diff --git a/asterixdb/asterix-metadata/src/main/java/org/apache/asterix/metadata/entities/Index.java b/asterixdb/asterix-metadata/src/main/java/org/apache/asterix/metadata/entities/Index.java
index 92650ee..fbd0670 100644
--- a/asterixdb/asterix-metadata/src/main/java/org/apache/asterix/metadata/entities/Index.java
+++ b/asterixdb/asterix-metadata/src/main/java/org/apache/asterix/metadata/entities/Index.java
@@ -54,7 +54,7 @@
     public static final int RECORD_INDICATOR = 0;
     public static final int META_RECORD_INDICATOR = 1;
 
-    private final String databaseName = null;
+    private final String databaseName;
     private final DataverseName dataverseName;
     // Enforced to be unique within a dataverse.
     private final String datasetName;
@@ -67,14 +67,16 @@
     // Type of pending operations with respect to atomic DDL operation
     private int pendingOp;
 
-    public Index(DataverseName dataverseName, String datasetName, String indexName, IndexType indexType,
-            IIndexDetails indexDetails, boolean isEnforced, boolean isPrimaryIndex, int pendingOp) {
+    public Index(String databaseName, DataverseName dataverseName, String datasetName, String indexName,
+            IndexType indexType, IIndexDetails indexDetails, boolean isEnforced, boolean isPrimaryIndex,
+            int pendingOp) {
         boolean categoryOk = (indexType == null && indexDetails == null) || (IndexCategory
                 .of(Objects.requireNonNull(indexType)) == ((AbstractIndexDetails) Objects.requireNonNull(indexDetails))
                         .getIndexCategory());
         if (!categoryOk) {
             throw new IllegalArgumentException();
         }
+        this.databaseName = Objects.requireNonNull(databaseName);
         this.dataverseName = Objects.requireNonNull(dataverseName);
         this.datasetName = Objects.requireNonNull(datasetName);
         this.indexName = Objects.requireNonNull(indexName);
@@ -86,20 +88,20 @@
     }
 
     @Deprecated
-    public Index(DataverseName dataverseName, String datasetName, String indexName, IndexType indexType,
-            List<List<String>> keyFieldNames, List<Integer> keyFieldSourceIndicators, List<IAType> keyFieldTypes,
-            boolean overrideKeyFieldTypes, boolean isEnforced, boolean isPrimaryIndex, int pendingOp,
-            OptionalBoolean excludeUnknownKey) {
-        this(dataverseName, datasetName,
+    public Index(String database, DataverseName dataverseName, String datasetName, String indexName,
+            IndexType indexType, List<List<String>> keyFieldNames, List<Integer> keyFieldSourceIndicators,
+            List<IAType> keyFieldTypes, boolean overrideKeyFieldTypes, boolean isEnforced, boolean isPrimaryIndex,
+            int pendingOp, OptionalBoolean excludeUnknownKey) {
+        this(database, dataverseName, datasetName,
                 indexName, indexType, createSimpleIndexDetails(indexType, keyFieldNames, keyFieldSourceIndicators,
                         keyFieldTypes, overrideKeyFieldTypes, excludeUnknownKey),
                 isEnforced, isPrimaryIndex, pendingOp);
     }
 
-    public static Index createPrimaryIndex(DataverseName dataverseName, String datasetName,
+    public static Index createPrimaryIndex(String database, DataverseName dataverseName, String datasetName,
             List<List<String>> keyFieldNames, List<Integer> keyFieldSourceIndicators, List<IAType> keyFieldTypes,
             int pendingOp) {
-        return new Index(dataverseName, datasetName,
+        return new Index(database, dataverseName, datasetName,
                 datasetName, IndexType.BTREE, new ValueIndexDetails(keyFieldNames, keyFieldSourceIndicators,
                         keyFieldTypes, false, OptionalBoolean.empty(), OptionalBoolean.empty(), null, null, null),
                 false, true, pendingOp);
diff --git a/asterixdb/asterix-metadata/src/main/java/org/apache/asterix/metadata/entities/Library.java b/asterixdb/asterix-metadata/src/main/java/org/apache/asterix/metadata/entities/Library.java
index 5373eb2..4674a1e 100644
--- a/asterixdb/asterix-metadata/src/main/java/org/apache/asterix/metadata/entities/Library.java
+++ b/asterixdb/asterix-metadata/src/main/java/org/apache/asterix/metadata/entities/Library.java
@@ -18,6 +18,8 @@
  */
 package org.apache.asterix.metadata.entities;
 
+import java.util.Objects;
+
 import org.apache.asterix.common.metadata.DataverseName;
 import org.apache.asterix.metadata.MetadataCache;
 import org.apache.asterix.metadata.api.IMetadataEntity;
@@ -26,14 +28,16 @@
 
     private static final long serialVersionUID = 3L;
 
-    private final String databaseName = null;
+    private final String databaseName;
     private final DataverseName dataverse;
     private final String name;
     private final String language;
     private final String hash;
     private final int pendingOp;
 
-    public Library(DataverseName dataverseName, String libraryName, String language, String hash, int pendingOp) {
+    public Library(String databaseName, DataverseName dataverseName, String libraryName, String language, String hash,
+            int pendingOp) {
+        this.databaseName = Objects.requireNonNull(databaseName);
         this.dataverse = dataverseName;
         this.name = libraryName;
         this.language = language;
diff --git a/asterixdb/asterix-metadata/src/main/java/org/apache/asterix/metadata/entities/Synonym.java b/asterixdb/asterix-metadata/src/main/java/org/apache/asterix/metadata/entities/Synonym.java
index 9da7f99..135356a 100644
--- a/asterixdb/asterix-metadata/src/main/java/org/apache/asterix/metadata/entities/Synonym.java
+++ b/asterixdb/asterix-metadata/src/main/java/org/apache/asterix/metadata/entities/Synonym.java
@@ -29,7 +29,7 @@
 
     private static final long serialVersionUID = 2L;
 
-    private final String databaseName = null;
+    private final String databaseName;
 
     private final DataverseName dataverseName;
 
@@ -39,8 +39,9 @@
 
     private final String objectName;
 
-    public Synonym(DataverseName dataverseName, String synonymName, DataverseName objectDataverseName,
-            String objectName) {
+    public Synonym(String databaseName, DataverseName dataverseName, String synonymName,
+            DataverseName objectDataverseName, String objectName) {
+        this.databaseName = Objects.requireNonNull(databaseName);
         this.dataverseName = Objects.requireNonNull(dataverseName);
         this.synonymName = Objects.requireNonNull(synonymName);
         this.objectDataverseName = Objects.requireNonNull(objectDataverseName);
diff --git a/asterixdb/asterix-metadata/src/main/java/org/apache/asterix/metadata/entitytupletranslators/AbstractDatatypeTupleTranslator.java b/asterixdb/asterix-metadata/src/main/java/org/apache/asterix/metadata/entitytupletranslators/AbstractDatatypeTupleTranslator.java
index e663798..87a49c6 100644
--- a/asterixdb/asterix-metadata/src/main/java/org/apache/asterix/metadata/entitytupletranslators/AbstractDatatypeTupleTranslator.java
+++ b/asterixdb/asterix-metadata/src/main/java/org/apache/asterix/metadata/entitytupletranslators/AbstractDatatypeTupleTranslator.java
@@ -30,6 +30,7 @@
 import org.apache.asterix.metadata.api.IMetadataIndex;
 import org.apache.asterix.metadata.bootstrap.MetadataRecordTypes;
 import org.apache.asterix.metadata.entities.Datatype;
+import org.apache.asterix.metadata.utils.MetadataUtil;
 import org.apache.asterix.om.base.ABoolean;
 import org.apache.asterix.om.types.AOrderedListType;
 import org.apache.asterix.om.types.ARecordType;
@@ -209,7 +210,8 @@
     protected void handleNestedDerivedType(DataverseName dataverseName, String typeName, AbstractComplexType nestedType)
             throws HyracksDataException {
         try {
-            metadataNode.addDatatype(txnId, new Datatype(dataverseName, typeName, nestedType, true));
+            String database = MetadataUtil.databaseFor(dataverseName);
+            metadataNode.addDatatype(txnId, new Datatype(database, dataverseName, typeName, nestedType, true));
         } catch (AlgebricksException e) {
             // The nested record type may have been inserted by a previous DDL statement or
             // by a previous nested type.
diff --git a/asterixdb/asterix-metadata/src/main/java/org/apache/asterix/metadata/entitytupletranslators/CompactionPolicyTupleTranslator.java b/asterixdb/asterix-metadata/src/main/java/org/apache/asterix/metadata/entitytupletranslators/CompactionPolicyTupleTranslator.java
index e60d65b..da6df13 100644
--- a/asterixdb/asterix-metadata/src/main/java/org/apache/asterix/metadata/entitytupletranslators/CompactionPolicyTupleTranslator.java
+++ b/asterixdb/asterix-metadata/src/main/java/org/apache/asterix/metadata/entitytupletranslators/CompactionPolicyTupleTranslator.java
@@ -22,6 +22,7 @@
 import org.apache.asterix.common.metadata.DataverseName;
 import org.apache.asterix.metadata.bootstrap.CompactionPolicyEntity;
 import org.apache.asterix.metadata.entities.CompactionPolicy;
+import org.apache.asterix.metadata.utils.MetadataUtil;
 import org.apache.asterix.om.base.ARecord;
 import org.apache.asterix.om.base.AString;
 import org.apache.hyracks.algebricks.common.exceptions.AlgebricksException;
@@ -43,21 +44,23 @@
     @Override
     protected CompactionPolicy createMetadataEntityFromARecord(ARecord compactionPolicyRecord)
             throws AlgebricksException {
-        int databaseNameIndex = compactionPolicyEntity.databaseNameIndex();
-        String databaseName;
-        if (databaseNameIndex >= 0) {
-            databaseName = ((AString) compactionPolicyRecord.getValueByPos(databaseNameIndex)).getStringValue();
-        }
         String dataverseCanonicalName =
                 ((AString) compactionPolicyRecord.getValueByPos(compactionPolicyEntity.dataverseNameIndex()))
                         .getStringValue();
         DataverseName dataverseName = DataverseName.createFromCanonicalForm(dataverseCanonicalName);
+        String databaseName;
+        int databaseNameIndex = compactionPolicyEntity.databaseNameIndex();
+        if (databaseNameIndex >= 0) {
+            databaseName = ((AString) compactionPolicyRecord.getValueByPos(databaseNameIndex)).getStringValue();
+        } else {
+            databaseName = MetadataUtil.databaseFor(dataverseName);
+        }
         String policyName = ((AString) compactionPolicyRecord.getValueByPos(compactionPolicyEntity.policyNameIndex()))
                 .getStringValue();
         String className = ((AString) compactionPolicyRecord.getValueByPos(compactionPolicyEntity.classNameIndex()))
                 .getStringValue();
 
-        return new CompactionPolicy(dataverseName, policyName, className);
+        return new CompactionPolicy(databaseName, dataverseName, policyName, className);
     }
 
     @Override
diff --git a/asterixdb/asterix-metadata/src/main/java/org/apache/asterix/metadata/entitytupletranslators/DatasetTupleTranslator.java b/asterixdb/asterix-metadata/src/main/java/org/apache/asterix/metadata/entitytupletranslators/DatasetTupleTranslator.java
index 37c7246..c74724d 100644
--- a/asterixdb/asterix-metadata/src/main/java/org/apache/asterix/metadata/entitytupletranslators/DatasetTupleTranslator.java
+++ b/asterixdb/asterix-metadata/src/main/java/org/apache/asterix/metadata/entitytupletranslators/DatasetTupleTranslator.java
@@ -51,6 +51,7 @@
 import org.apache.asterix.metadata.entities.InternalDatasetDetails.PartitioningStrategy;
 import org.apache.asterix.metadata.entities.ViewDetails;
 import org.apache.asterix.metadata.utils.DatasetUtil;
+import org.apache.asterix.metadata.utils.MetadataUtil;
 import org.apache.asterix.om.base.ABoolean;
 import org.apache.asterix.om.base.ADateTime;
 import org.apache.asterix.om.base.ADouble;
@@ -105,15 +106,17 @@
     @Override
     protected Dataset createMetadataEntityFromARecord(ARecord datasetRecord) throws AlgebricksException {
         ARecordType recType = datasetRecord.getType();
-        int databaseNameIndex = datasetEntity.databaseNameIndex();
-        String databaseName;
-        if (databaseNameIndex >= 0) {
-            databaseName = ((AString) datasetRecord.getValueByPos(databaseNameIndex)).getStringValue();
-        }
 
         String dataverseCanonicalName =
                 ((AString) datasetRecord.getValueByPos(datasetEntity.dataverseNameIndex())).getStringValue();
         DataverseName dataverseName = DataverseName.createFromCanonicalForm(dataverseCanonicalName);
+        int databaseNameIndex = datasetEntity.databaseNameIndex();
+        String databaseName;
+        if (databaseNameIndex >= 0) {
+            databaseName = ((AString) datasetRecord.getValueByPos(databaseNameIndex)).getStringValue();
+        } else {
+            databaseName = MetadataUtil.databaseFor(dataverseName);
+        }
         String datasetName = ((AString) datasetRecord.getValueByPos(datasetEntity.datasetNameIndex())).getStringValue();
         String typeName = ((AString) datasetRecord.getValueByPos(datasetEntity.datatypeNameIndex())).getStringValue();
         String typeDataverseCanonicalName =
@@ -382,9 +385,9 @@
         String compressionScheme = getCompressionScheme(datasetRecord);
         DatasetFormatInfo datasetFormatInfo = getDatasetFormatInfo(datasetRecord);
 
-        return new Dataset(dataverseName, datasetName, typeDataverseName, typeName, metaTypeDataverseName, metaTypeName,
-                nodeGroupName, compactionPolicy.first, compactionPolicy.second, datasetDetails, hints, datasetType,
-                datasetId, pendingOp, rebalanceCount, compressionScheme, datasetFormatInfo);
+        return new Dataset(databaseName, dataverseName, datasetName, typeDataverseName, typeName, metaTypeDataverseName,
+                metaTypeName, nodeGroupName, compactionPolicy.first, compactionPolicy.second, datasetDetails, hints,
+                datasetType, datasetId, pendingOp, rebalanceCount, compressionScheme, datasetFormatInfo);
     }
 
     protected Pair<String, Map<String, String>> readCompactionPolicy(DatasetType datasetType, ARecord datasetRecord) {
diff --git a/asterixdb/asterix-metadata/src/main/java/org/apache/asterix/metadata/entitytupletranslators/DatasourceAdapterTupleTranslator.java b/asterixdb/asterix-metadata/src/main/java/org/apache/asterix/metadata/entitytupletranslators/DatasourceAdapterTupleTranslator.java
index 971f995..e09eb8f 100644
--- a/asterixdb/asterix-metadata/src/main/java/org/apache/asterix/metadata/entitytupletranslators/DatasourceAdapterTupleTranslator.java
+++ b/asterixdb/asterix-metadata/src/main/java/org/apache/asterix/metadata/entitytupletranslators/DatasourceAdapterTupleTranslator.java
@@ -27,6 +27,7 @@
 import org.apache.asterix.metadata.bootstrap.DatasourceAdapterEntity;
 import org.apache.asterix.metadata.bootstrap.MetadataRecordTypes;
 import org.apache.asterix.metadata.entities.DatasourceAdapter;
+import org.apache.asterix.metadata.utils.MetadataUtil;
 import org.apache.asterix.om.base.ARecord;
 import org.apache.asterix.om.base.AString;
 import org.apache.hyracks.algebricks.common.exceptions.AlgebricksException;
@@ -44,14 +45,16 @@
 
     @Override
     protected DatasourceAdapter createMetadataEntityFromARecord(ARecord adapterRecord) throws AlgebricksException {
+        String dataverseCanonicalName =
+                ((AString) adapterRecord.getValueByPos(datasourceAdapterEntity.dataverseNameIndex())).getStringValue();
+        DataverseName dataverseName = DataverseName.createFromCanonicalForm(dataverseCanonicalName);
         int databaseNameIndex = datasourceAdapterEntity.databaseNameIndex();
         String databaseName;
         if (databaseNameIndex >= 0) {
             databaseName = ((AString) adapterRecord.getValueByPos(databaseNameIndex)).getStringValue();
+        } else {
+            databaseName = MetadataUtil.databaseFor(dataverseName);
         }
-        String dataverseCanonicalName =
-                ((AString) adapterRecord.getValueByPos(datasourceAdapterEntity.dataverseNameIndex())).getStringValue();
-        DataverseName dataverseName = DataverseName.createFromCanonicalForm(dataverseCanonicalName);
         String adapterName =
                 ((AString) adapterRecord.getValueByPos(datasourceAdapterEntity.adapterNameIndex())).getStringValue();
         String classname =
@@ -59,6 +62,7 @@
         IDataSourceAdapter.AdapterType adapterType = IDataSourceAdapter.AdapterType
                 .valueOf(((AString) adapterRecord.getValueByPos(datasourceAdapterEntity.typeIndex())).getStringValue());
 
+        String libraryDatabase = null;
         DataverseName libraryDataverseName = null;
         String libraryName = null;
         int libraryNameIdx = adapterRecord.getType().getFieldIndex(MetadataRecordTypes.FIELD_NAME_LIBRARY_NAME);
@@ -70,10 +74,11 @@
                     ? DataverseName.createFromCanonicalForm(
                             ((AString) adapterRecord.getValueByPos(libraryDataverseNameIdx)).getStringValue())
                     : dataverseName;
+            libraryDatabase = MetadataUtil.resolveDatabase(libraryDatabase, libraryDataverseName);
         }
 
-        return new DatasourceAdapter(new AdapterIdentifier(dataverseName, adapterName), adapterType, classname,
-                libraryDataverseName, libraryName);
+        return new DatasourceAdapter(new AdapterIdentifier(databaseName, dataverseName, adapterName), adapterType,
+                classname, libraryDatabase, libraryDataverseName, libraryName);
     }
 
     @Override
@@ -155,6 +160,7 @@
             return;
         }
 
+        //TODO(DB): write library database name
         fieldName.reset();
         aString.setValue(MetadataRecordTypes.FIELD_NAME_LIBRARY_DATAVERSE_NAME);
         stringSerde.serialize(aString, fieldName.getDataOutput());
diff --git a/asterixdb/asterix-metadata/src/main/java/org/apache/asterix/metadata/entitytupletranslators/DatatypeTupleTranslator.java b/asterixdb/asterix-metadata/src/main/java/org/apache/asterix/metadata/entitytupletranslators/DatatypeTupleTranslator.java
index e0a0db0..504a491 100644
--- a/asterixdb/asterix-metadata/src/main/java/org/apache/asterix/metadata/entitytupletranslators/DatatypeTupleTranslator.java
+++ b/asterixdb/asterix-metadata/src/main/java/org/apache/asterix/metadata/entitytupletranslators/DatatypeTupleTranslator.java
@@ -27,6 +27,7 @@
 import org.apache.asterix.metadata.bootstrap.DatatypeEntity;
 import org.apache.asterix.metadata.bootstrap.MetadataRecordTypes;
 import org.apache.asterix.metadata.entities.Datatype;
+import org.apache.asterix.metadata.utils.MetadataUtil;
 import org.apache.asterix.metadata.utils.TypeUtil;
 import org.apache.asterix.om.base.ABoolean;
 import org.apache.asterix.om.base.AOrderedList;
@@ -58,14 +59,16 @@
 
     @Override
     protected Datatype createMetadataEntityFromARecord(ARecord datatypeRecord) throws AlgebricksException {
-        int databaseNameIndex = datatypeEntity.databaseNameIndex();
-        String databaseName = null;
-        if (databaseNameIndex >= 0) {
-            databaseName = ((AString) datatypeRecord.getValueByPos(databaseNameIndex)).getStringValue();
-        }
         String dataverseCanonicalName =
                 ((AString) datatypeRecord.getValueByPos(datatypeEntity.dataverseNameIndex())).getStringValue();
         DataverseName dataverseName = DataverseName.createFromCanonicalForm(dataverseCanonicalName);
+        int databaseNameIndex = datatypeEntity.databaseNameIndex();
+        String databaseName;
+        if (databaseNameIndex >= 0) {
+            databaseName = ((AString) datatypeRecord.getValueByPos(databaseNameIndex)).getStringValue();
+        } else {
+            databaseName = MetadataUtil.databaseFor(dataverseName);
+        }
         String datatypeName =
                 ((AString) datatypeRecord.getValueByPos(datatypeEntity.datatypeNameIndex())).getStringValue();
         IAType type = BuiltinTypeMap.getBuiltinType(datatypeName);
@@ -118,14 +121,14 @@
                         fieldTypes[fieldId] = TypeUtil.createQuantifiedType(fieldType, isNullable, isMissable);
                         fieldId++;
                     }
-                    return new Datatype(dataverseName, datatypeName,
+                    return new Datatype(databaseName, dataverseName, datatypeName,
                             new ARecordType(datatypeName, fieldNames, fieldTypes, isOpen), isAnonymous);
                 }
                 case UNORDEREDLIST: {
                     String unorderedlistTypeName = ((AString) derivedTypeRecord
                             .getValueByPos(MetadataRecordTypes.DERIVEDTYPE_ARECORD_UNORDEREDLIST_FIELD_INDEX))
                                     .getStringValue();
-                    return new Datatype(dataverseName, datatypeName,
+                    return new Datatype(databaseName, dataverseName, datatypeName,
                             new AUnorderedListType(Datatype.getTypeFromTypeName(metadataNode, txnId, databaseName,
                                     dataverseName, unorderedlistTypeName), datatypeName),
                             isAnonymous);
@@ -134,7 +137,7 @@
                     String orderedlistTypeName = ((AString) derivedTypeRecord
                             .getValueByPos(MetadataRecordTypes.DERIVEDTYPE_ARECORD_ORDEREDLIST_FIELD_INDEX))
                                     .getStringValue();
-                    return new Datatype(
+                    return new Datatype(databaseName,
                             dataverseName, datatypeName, new AOrderedListType(Datatype.getTypeFromTypeName(metadataNode,
                                     txnId, databaseName, dataverseName, orderedlistTypeName), datatypeName),
                             isAnonymous);
@@ -143,7 +146,7 @@
                     throw new UnsupportedOperationException("Unsupported derived type: " + tag);
             }
         }
-        return new Datatype(dataverseName, datatypeName, type, false);
+        return new Datatype(databaseName, dataverseName, datatypeName, type, false);
     }
 
     @Override
diff --git a/asterixdb/asterix-metadata/src/main/java/org/apache/asterix/metadata/entitytupletranslators/DataverseTupleTranslator.java b/asterixdb/asterix-metadata/src/main/java/org/apache/asterix/metadata/entitytupletranslators/DataverseTupleTranslator.java
index 1c79e76..4e2a5df 100644
--- a/asterixdb/asterix-metadata/src/main/java/org/apache/asterix/metadata/entitytupletranslators/DataverseTupleTranslator.java
+++ b/asterixdb/asterix-metadata/src/main/java/org/apache/asterix/metadata/entitytupletranslators/DataverseTupleTranslator.java
@@ -24,6 +24,7 @@
 import org.apache.asterix.common.metadata.DataverseName;
 import org.apache.asterix.metadata.bootstrap.DataverseEntity;
 import org.apache.asterix.metadata.entities.Dataverse;
+import org.apache.asterix.metadata.utils.MetadataUtil;
 import org.apache.asterix.om.base.AInt32;
 import org.apache.asterix.om.base.AMutableInt32;
 import org.apache.asterix.om.base.ARecord;
@@ -50,18 +51,20 @@
 
     @Override
     protected Dataverse createMetadataEntityFromARecord(ARecord dataverseRecord) throws AlgebricksException {
+        String dataverseCanonicalName =
+                ((AString) dataverseRecord.getValueByPos(dataverseEntity.dataverseNameIndex())).getStringValue();
+        DataverseName dataverseName = DataverseName.createFromCanonicalForm(dataverseCanonicalName);
         int databaseNameIndex = dataverseEntity.databaseNameIndex();
         String databaseName;
         if (databaseNameIndex >= 0) {
             databaseName = ((AString) dataverseRecord.getValueByPos(databaseNameIndex)).getStringValue();
+        } else {
+            databaseName = MetadataUtil.databaseFor(dataverseName);
         }
-        String dataverseCanonicalName =
-                ((AString) dataverseRecord.getValueByPos(dataverseEntity.dataverseNameIndex())).getStringValue();
-        DataverseName dataverseName = DataverseName.createFromCanonicalForm(dataverseCanonicalName);
         String format = ((AString) dataverseRecord.getValueByPos(dataverseEntity.dataFormatIndex())).getStringValue();
         int pendingOp = ((AInt32) dataverseRecord.getValueByPos(dataverseEntity.pendingOpIndex())).getIntegerValue();
 
-        return new Dataverse(dataverseName, format, pendingOp);
+        return new Dataverse(databaseName, dataverseName, format, pendingOp);
     }
 
     @Override
diff --git a/asterixdb/asterix-metadata/src/main/java/org/apache/asterix/metadata/entitytupletranslators/ExternalFileTupleTranslator.java b/asterixdb/asterix-metadata/src/main/java/org/apache/asterix/metadata/entitytupletranslators/ExternalFileTupleTranslator.java
index 3d1b054..4654e0f 100644
--- a/asterixdb/asterix-metadata/src/main/java/org/apache/asterix/metadata/entitytupletranslators/ExternalFileTupleTranslator.java
+++ b/asterixdb/asterix-metadata/src/main/java/org/apache/asterix/metadata/entitytupletranslators/ExternalFileTupleTranslator.java
@@ -25,6 +25,7 @@
 import org.apache.asterix.external.indexing.ExternalFile;
 import org.apache.asterix.formats.nontagged.SerializerDeserializerProvider;
 import org.apache.asterix.metadata.bootstrap.ExternalFileEntity;
+import org.apache.asterix.metadata.utils.MetadataUtil;
 import org.apache.asterix.om.base.ADateTime;
 import org.apache.asterix.om.base.AInt32;
 import org.apache.asterix.om.base.AInt64;
@@ -61,14 +62,16 @@
 
     @Override
     protected ExternalFile createMetadataEntityFromARecord(ARecord externalFileRecord) throws AlgebricksException {
+        String dataverseCanonicalName =
+                ((AString) externalFileRecord.getValueByPos(externalFileEntity.dataverseNameIndex())).getStringValue();
+        DataverseName dataverseName = DataverseName.createFromCanonicalForm(dataverseCanonicalName);
         int databaseNameIndex = externalFileEntity.databaseNameIndex();
         String databaseName;
         if (databaseNameIndex >= 0) {
             databaseName = ((AString) externalFileRecord.getValueByPos(databaseNameIndex)).getStringValue();
+        } else {
+            databaseName = MetadataUtil.databaseFor(dataverseName);
         }
-        String dataverseCanonicalName =
-                ((AString) externalFileRecord.getValueByPos(externalFileEntity.dataverseNameIndex())).getStringValue();
-        DataverseName dataverseName = DataverseName.createFromCanonicalForm(dataverseCanonicalName);
         String datasetName =
                 ((AString) externalFileRecord.getValueByPos(externalFileEntity.datasetNameIndex())).getStringValue();
         int fileNumber =
@@ -81,8 +84,8 @@
         ExternalFilePendingOp pendingOp = ExternalFilePendingOp
                 .values()[((AInt32) externalFileRecord.getValueByPos(externalFileEntity.pendingOpIndex()))
                         .getIntegerValue()];
-        return new ExternalFile(dataverseName, datasetName, fileNumber, fileName, lastMoDifiedDate, fileSize,
-                pendingOp);
+        return new ExternalFile(databaseName, dataverseName, datasetName, fileNumber, fileName, lastMoDifiedDate,
+                fileSize, pendingOp);
     }
 
     @Override
diff --git a/asterixdb/asterix-metadata/src/main/java/org/apache/asterix/metadata/entitytupletranslators/FeedConnectionTupleTranslator.java b/asterixdb/asterix-metadata/src/main/java/org/apache/asterix/metadata/entitytupletranslators/FeedConnectionTupleTranslator.java
index 6459c8d..163ce03 100644
--- a/asterixdb/asterix-metadata/src/main/java/org/apache/asterix/metadata/entitytupletranslators/FeedConnectionTupleTranslator.java
+++ b/asterixdb/asterix-metadata/src/main/java/org/apache/asterix/metadata/entitytupletranslators/FeedConnectionTupleTranslator.java
@@ -29,6 +29,7 @@
 import org.apache.asterix.metadata.bootstrap.FeedConnectionEntity;
 import org.apache.asterix.metadata.bootstrap.MetadataRecordTypes;
 import org.apache.asterix.metadata.entities.FeedConnection;
+import org.apache.asterix.metadata.utils.MetadataUtil;
 import org.apache.asterix.om.base.AMissing;
 import org.apache.asterix.om.base.ANull;
 import org.apache.asterix.om.base.ARecord;
@@ -52,15 +53,17 @@
 
     @Override
     protected FeedConnection createMetadataEntityFromARecord(ARecord feedConnectionRecord) throws AlgebricksException {
-        int databaseNameIndex = feedConnectionEntity.databaseNameIndex();
-        String databaseName;
-        if (databaseNameIndex >= 0) {
-            databaseName = ((AString) feedConnectionRecord.getValueByPos(databaseNameIndex)).getStringValue();
-        }
         String dataverseCanonicalName =
                 ((AString) feedConnectionRecord.getValueByPos(feedConnectionEntity.dataverseNameIndex()))
                         .getStringValue();
         DataverseName dataverseName = DataverseName.createFromCanonicalForm(dataverseCanonicalName);
+        int databaseNameIndex = feedConnectionEntity.databaseNameIndex();
+        String databaseName;
+        if (databaseNameIndex >= 0) {
+            databaseName = ((AString) feedConnectionRecord.getValueByPos(databaseNameIndex)).getStringValue();
+        } else {
+            databaseName = MetadataUtil.databaseFor(dataverseName);
+        }
         String feedName =
                 ((AString) feedConnectionRecord.getValueByPos(feedConnectionEntity.feedNameIndex())).getStringValue();
         String datasetName = ((AString) feedConnectionRecord.getValueByPos(feedConnectionEntity.datasetNameIndex()))
@@ -93,8 +96,8 @@
         String whereClauseBody = whereClauseIdx >= 0
                 ? ((AString) feedConnectionRecord.getValueByPos(whereClauseIdx)).getStringValue() : "";
 
-        return new FeedConnection(dataverseName, feedName, datasetName, appliedFunctions, policyName, whereClauseBody,
-                outputType);
+        return new FeedConnection(databaseName, dataverseName, feedName, datasetName, appliedFunctions, policyName,
+                whereClauseBody, outputType);
     }
 
     @Override
diff --git a/asterixdb/asterix-metadata/src/main/java/org/apache/asterix/metadata/entitytupletranslators/FeedPolicyTupleTranslator.java b/asterixdb/asterix-metadata/src/main/java/org/apache/asterix/metadata/entitytupletranslators/FeedPolicyTupleTranslator.java
index 99b5f6f..887d606 100644
--- a/asterixdb/asterix-metadata/src/main/java/org/apache/asterix/metadata/entitytupletranslators/FeedPolicyTupleTranslator.java
+++ b/asterixdb/asterix-metadata/src/main/java/org/apache/asterix/metadata/entitytupletranslators/FeedPolicyTupleTranslator.java
@@ -29,6 +29,7 @@
 import org.apache.asterix.common.metadata.DataverseName;
 import org.apache.asterix.metadata.bootstrap.MetadataRecordTypes;
 import org.apache.asterix.metadata.entities.FeedPolicyEntity;
+import org.apache.asterix.metadata.utils.MetadataUtil;
 import org.apache.asterix.om.base.AMutableString;
 import org.apache.asterix.om.base.ARecord;
 import org.apache.asterix.om.base.AString;
@@ -55,14 +56,16 @@
 
     @Override
     protected FeedPolicyEntity createMetadataEntityFromARecord(ARecord feedPolicyRecord) throws AlgebricksException {
+        String dataverseCanonicalName =
+                ((AString) feedPolicyRecord.getValueByPos(feedPolicyEntity.dataverseNameIndex())).getStringValue();
+        DataverseName dataverseName = DataverseName.createFromCanonicalForm(dataverseCanonicalName);
         int databaseNameIndex = feedPolicyEntity.databaseNameIndex();
         String databaseName;
         if (databaseNameIndex >= 0) {
             databaseName = ((AString) feedPolicyRecord.getValueByPos(databaseNameIndex)).getStringValue();
+        } else {
+            databaseName = MetadataUtil.databaseFor(dataverseName);
         }
-        String dataverseCanonicalName =
-                ((AString) feedPolicyRecord.getValueByPos(feedPolicyEntity.dataverseNameIndex())).getStringValue();
-        DataverseName dataverseName = DataverseName.createFromCanonicalForm(dataverseCanonicalName);
         String policyName =
                 ((AString) feedPolicyRecord.getValueByPos(feedPolicyEntity.policyNameIndex())).getStringValue();
         String description =
@@ -80,7 +83,7 @@
             policyParamters.put(key, value);
         }
 
-        return new FeedPolicyEntity(dataverseName, policyName, description, policyParamters);
+        return new FeedPolicyEntity(databaseName, dataverseName, policyName, description, policyParamters);
     }
 
     @Override
diff --git a/asterixdb/asterix-metadata/src/main/java/org/apache/asterix/metadata/entitytupletranslators/FullTextConfigMetadataEntityTupleTranslator.java b/asterixdb/asterix-metadata/src/main/java/org/apache/asterix/metadata/entitytupletranslators/FullTextConfigMetadataEntityTupleTranslator.java
index 7a06954..907c886 100644
--- a/asterixdb/asterix-metadata/src/main/java/org/apache/asterix/metadata/entitytupletranslators/FullTextConfigMetadataEntityTupleTranslator.java
+++ b/asterixdb/asterix-metadata/src/main/java/org/apache/asterix/metadata/entitytupletranslators/FullTextConfigMetadataEntityTupleTranslator.java
@@ -25,6 +25,7 @@
 import org.apache.asterix.common.metadata.DataverseName;
 import org.apache.asterix.metadata.bootstrap.FullTextConfigEntity;
 import org.apache.asterix.metadata.entities.FullTextConfigMetadataEntity;
+import org.apache.asterix.metadata.utils.MetadataUtil;
 import org.apache.asterix.om.base.AOrderedList;
 import org.apache.asterix.om.base.ARecord;
 import org.apache.asterix.om.base.AString;
@@ -61,14 +62,15 @@
     @Override
     protected FullTextConfigMetadataEntity createMetadataEntityFromARecord(ARecord aRecord)
             throws HyracksDataException, AlgebricksException {
+        DataverseName dataverseName = DataverseName.createFromCanonicalForm(
+                ((AString) aRecord.getValueByPos(fullTextConfigEntity.dataverseNameIndex())).getStringValue());
         int databaseNameIndex = fullTextConfigEntity.databaseNameIndex();
         String databaseName;
         if (databaseNameIndex >= 0) {
             databaseName = ((AString) aRecord.getValueByPos(databaseNameIndex)).getStringValue();
+        } else {
+            databaseName = MetadataUtil.databaseFor(dataverseName);
         }
-        DataverseName dataverseName = DataverseName.createFromCanonicalForm(
-                ((AString) aRecord.getValueByPos(fullTextConfigEntity.dataverseNameIndex())).getStringValue());
-
         String name = ((AString) aRecord.getValueByPos(fullTextConfigEntity.configNameIndex())).getStringValue();
 
         TokenizerCategory tokenizerCategory = EnumUtils.getEnumIgnoreCase(TokenizerCategory.class,
@@ -81,8 +83,8 @@
             filterNamesBuilder.add(((AString) filterNamesCursor.get()).getStringValue());
         }
 
-        FullTextConfigDescriptor configDescriptor =
-                new FullTextConfigDescriptor(dataverseName, name, tokenizerCategory, filterNamesBuilder.build());
+        FullTextConfigDescriptor configDescriptor = new FullTextConfigDescriptor(databaseName, dataverseName, name,
+                tokenizerCategory, filterNamesBuilder.build());
         return new FullTextConfigMetadataEntity(configDescriptor);
     }
 
diff --git a/asterixdb/asterix-metadata/src/main/java/org/apache/asterix/metadata/entitytupletranslators/FullTextFilterMetadataEntityTupleTranslator.java b/asterixdb/asterix-metadata/src/main/java/org/apache/asterix/metadata/entitytupletranslators/FullTextFilterMetadataEntityTupleTranslator.java
index 6ab2fea..0cb4e8a 100644
--- a/asterixdb/asterix-metadata/src/main/java/org/apache/asterix/metadata/entitytupletranslators/FullTextFilterMetadataEntityTupleTranslator.java
+++ b/asterixdb/asterix-metadata/src/main/java/org/apache/asterix/metadata/entitytupletranslators/FullTextFilterMetadataEntityTupleTranslator.java
@@ -29,6 +29,7 @@
 import org.apache.asterix.common.metadata.DataverseName;
 import org.apache.asterix.metadata.bootstrap.FullTextFilterEntity;
 import org.apache.asterix.metadata.entities.FullTextFilterMetadataEntity;
+import org.apache.asterix.metadata.utils.MetadataUtil;
 import org.apache.asterix.om.base.AOrderedList;
 import org.apache.asterix.om.base.ARecord;
 import org.apache.asterix.om.base.AString;
@@ -95,9 +96,10 @@
             }
         }
 
-        StopwordsFullTextFilterDescriptor filterDescriptor = new StopwordsFullTextFilterDescriptor(
-                DataverseName.createFromCanonicalForm(dataverseName.getStringValue()), name.getStringValue(),
-                stopwordsBuilder.build());
+        DataverseName dataverse = DataverseName.createFromCanonicalForm(dataverseName.getStringValue());
+        String database = MetadataUtil.databaseFor(dataverse);
+        StopwordsFullTextFilterDescriptor filterDescriptor = new StopwordsFullTextFilterDescriptor(database, dataverse,
+                name.getStringValue(), stopwordsBuilder.build());
         return new FullTextFilterMetadataEntity(filterDescriptor);
     }
 
diff --git a/asterixdb/asterix-metadata/src/main/java/org/apache/asterix/metadata/entitytupletranslators/FunctionTupleTranslator.java b/asterixdb/asterix-metadata/src/main/java/org/apache/asterix/metadata/entitytupletranslators/FunctionTupleTranslator.java
index 2439ae9..ed35c41 100644
--- a/asterixdb/asterix-metadata/src/main/java/org/apache/asterix/metadata/entitytupletranslators/FunctionTupleTranslator.java
+++ b/asterixdb/asterix-metadata/src/main/java/org/apache/asterix/metadata/entitytupletranslators/FunctionTupleTranslator.java
@@ -56,6 +56,7 @@
 import org.apache.asterix.metadata.bootstrap.FunctionEntity;
 import org.apache.asterix.metadata.bootstrap.MetadataRecordTypes;
 import org.apache.asterix.metadata.entities.Function;
+import org.apache.asterix.metadata.utils.MetadataUtil;
 import org.apache.asterix.om.base.ABoolean;
 import org.apache.asterix.om.base.ANull;
 import org.apache.asterix.om.base.AOrderedList;
@@ -103,14 +104,16 @@
     }
 
     protected Function createMetadataEntityFromARecord(ARecord functionRecord) throws AlgebricksException {
+        String dataverseCanonicalName =
+                ((AString) functionRecord.getValueByPos(functionEntity.dataverseNameIndex())).getStringValue();
+        DataverseName dataverseName = DataverseName.createFromCanonicalForm(dataverseCanonicalName);
         int databaseNameIndex = functionEntity.databaseNameIndex();
         String databaseName;
         if (databaseNameIndex >= 0) {
             databaseName = ((AString) functionRecord.getValueByPos(databaseNameIndex)).getStringValue();
+        } else {
+            databaseName = MetadataUtil.databaseFor(dataverseName);
         }
-        String dataverseCanonicalName =
-                ((AString) functionRecord.getValueByPos(functionEntity.dataverseNameIndex())).getStringValue();
-        DataverseName dataverseName = DataverseName.createFromCanonicalForm(dataverseCanonicalName);
         String functionName =
                 ((AString) functionRecord.getValueByPos(functionEntity.functionNameIndex())).getStringValue();
         int arity = Integer.parseInt(
diff --git a/asterixdb/asterix-metadata/src/main/java/org/apache/asterix/metadata/entitytupletranslators/IndexTupleTranslator.java b/asterixdb/asterix-metadata/src/main/java/org/apache/asterix/metadata/entitytupletranslators/IndexTupleTranslator.java
index a178b1a..ea84d83 100644
--- a/asterixdb/asterix-metadata/src/main/java/org/apache/asterix/metadata/entitytupletranslators/IndexTupleTranslator.java
+++ b/asterixdb/asterix-metadata/src/main/java/org/apache/asterix/metadata/entitytupletranslators/IndexTupleTranslator.java
@@ -46,6 +46,7 @@
 import org.apache.asterix.metadata.entities.Datatype;
 import org.apache.asterix.metadata.entities.Index;
 import org.apache.asterix.metadata.utils.KeyFieldTypeUtil;
+import org.apache.asterix.metadata.utils.MetadataUtil;
 import org.apache.asterix.om.base.ABoolean;
 import org.apache.asterix.om.base.ACollectionCursor;
 import org.apache.asterix.om.base.AInt32;
@@ -147,14 +148,16 @@
 
     @Override
     protected Index createMetadataEntityFromARecord(ARecord indexRecord) throws AlgebricksException {
-        int databaseNameIndex = indexEntity.databaseNameIndex();
-        String databaseName = null;
-        if (databaseNameIndex >= 0) {
-            databaseName = ((AString) indexRecord.getValueByPos(databaseNameIndex)).getStringValue();
-        }
         String dataverseCanonicalName =
                 ((AString) indexRecord.getValueByPos(indexEntity.dataverseNameIndex())).getStringValue();
         DataverseName dataverseName = DataverseName.createFromCanonicalForm(dataverseCanonicalName);
+        int databaseNameIndex = indexEntity.databaseNameIndex();
+        String databaseName;
+        if (databaseNameIndex >= 0) {
+            databaseName = ((AString) indexRecord.getValueByPos(databaseNameIndex)).getStringValue();
+        } else {
+            databaseName = MetadataUtil.databaseFor(dataverseName);
+        }
         String datasetName = ((AString) indexRecord.getValueByPos(indexEntity.datasetNameIndex())).getStringValue();
         String indexName = ((AString) indexRecord.getValueByPos(indexEntity.indexNameIndex())).getStringValue();
         IndexType indexType = IndexType
@@ -322,14 +325,16 @@
             String datatypeName = dataset.getItemTypeName();
             //TODO(DB): get 'database' of item type and meta type
             DataverseName datatypeDataverseName = dataset.getItemTypeDataverseName();
+            String datatypeDatabase = MetadataUtil.databaseFor(datatypeDataverseName);
             ARecordType recordDt = (ARecordType) metadataNode
-                    .getDatatype(txnId, null, datatypeDataverseName, datatypeName).getDatatype();
+                    .getDatatype(txnId, datatypeDatabase, datatypeDataverseName, datatypeName).getDatatype();
             String metatypeName = dataset.getMetaItemTypeName();
             DataverseName metatypeDataverseName = dataset.getMetaItemTypeDataverseName();
+            String metaTypeDatabase = MetadataUtil.databaseFor(metatypeDataverseName);
             ARecordType metaDt = null;
             if (metatypeName != null && metatypeDataverseName != null) {
-                metaDt = (ARecordType) metadataNode.getDatatype(txnId, null, metatypeDataverseName, metatypeName)
-                        .getDatatype();
+                metaDt = (ARecordType) metadataNode
+                        .getDatatype(txnId, metaTypeDatabase, metatypeDataverseName, metatypeName).getDatatype();
             }
             recordDt = (ARecordType) MetadataManagerUtil.findTypeForDatasetWithoutType(recordDt, metaDt, dataset);
             searchKeyType = new ArrayList<>(searchElementCount);
@@ -532,7 +537,7 @@
         }
         int pendingOp = ((AInt32) indexRecord.getValueByPos(indexEntity.pendingOpIndex())).getIntegerValue();
 
-        return new Index(dataverseName, datasetName, indexName, indexType, indexDetails, isEnforcingKeys,
+        return new Index(databaseName, dataverseName, datasetName, indexName, indexType, indexDetails, isEnforcingKeys,
                 isPrimaryIndex, pendingOp);
     }
 
diff --git a/asterixdb/asterix-metadata/src/main/java/org/apache/asterix/metadata/entitytupletranslators/LibraryTupleTranslator.java b/asterixdb/asterix-metadata/src/main/java/org/apache/asterix/metadata/entitytupletranslators/LibraryTupleTranslator.java
index ba8a854..d7ea169 100644
--- a/asterixdb/asterix-metadata/src/main/java/org/apache/asterix/metadata/entitytupletranslators/LibraryTupleTranslator.java
+++ b/asterixdb/asterix-metadata/src/main/java/org/apache/asterix/metadata/entitytupletranslators/LibraryTupleTranslator.java
@@ -52,14 +52,16 @@
 
     @Override
     protected Library createMetadataEntityFromARecord(ARecord libraryRecord) throws AlgebricksException {
+        String dataverseCanonicalName =
+                ((AString) libraryRecord.getValueByPos(libraryEntity.dataverseNameIndex())).getStringValue();
+        DataverseName dataverseName = DataverseName.createFromCanonicalForm(dataverseCanonicalName);
         int databaseNameIndex = libraryEntity.databaseNameIndex();
         String databaseName;
         if (databaseNameIndex >= 0) {
             databaseName = ((AString) libraryRecord.getValueByPos(databaseNameIndex)).getStringValue();
+        } else {
+            databaseName = MetadataUtil.databaseFor(dataverseName);
         }
-        String dataverseCanonicalName =
-                ((AString) libraryRecord.getValueByPos(libraryEntity.dataverseNameIndex())).getStringValue();
-        DataverseName dataverseName = DataverseName.createFromCanonicalForm(dataverseCanonicalName);
         String libraryName = ((AString) libraryRecord.getValueByPos(libraryEntity.libraryNameIndex())).getStringValue();
 
         ARecordType libraryRecordType = libraryRecord.getType();
@@ -74,7 +76,7 @@
         int hashIdx = libraryRecordType.getFieldIndex(FIELD_NAME_HASH);
         String hash = hashIdx >= 0 ? ((AString) libraryRecord.getValueByPos(hashIdx)).getStringValue() : null;
 
-        return new Library(dataverseName, libraryName, language, hash, pendingOp);
+        return new Library(databaseName, dataverseName, libraryName, language, hash, pendingOp);
     }
 
     @Override
diff --git a/asterixdb/asterix-metadata/src/main/java/org/apache/asterix/metadata/entitytupletranslators/SynonymTupleTranslator.java b/asterixdb/asterix-metadata/src/main/java/org/apache/asterix/metadata/entitytupletranslators/SynonymTupleTranslator.java
index 114e46c..cb4bf99 100644
--- a/asterixdb/asterix-metadata/src/main/java/org/apache/asterix/metadata/entitytupletranslators/SynonymTupleTranslator.java
+++ b/asterixdb/asterix-metadata/src/main/java/org/apache/asterix/metadata/entitytupletranslators/SynonymTupleTranslator.java
@@ -22,6 +22,7 @@
 import org.apache.asterix.common.metadata.DataverseName;
 import org.apache.asterix.metadata.bootstrap.SynonymEntity;
 import org.apache.asterix.metadata.entities.Synonym;
+import org.apache.asterix.metadata.utils.MetadataUtil;
 import org.apache.asterix.om.base.ARecord;
 import org.apache.asterix.om.base.AString;
 import org.apache.hyracks.algebricks.common.exceptions.AlgebricksException;
@@ -42,15 +43,16 @@
 
     @Override
     protected Synonym createMetadataEntityFromARecord(ARecord synonymRecord) throws AlgebricksException {
+        String dataverseCanonicalName =
+                ((AString) synonymRecord.getValueByPos(synonymEntity.dataverseNameIndex())).getStringValue();
+        DataverseName dataverseName = DataverseName.createFromCanonicalForm(dataverseCanonicalName);
         int databaseNameIndex = synonymEntity.databaseNameIndex();
         String databaseName;
         if (databaseNameIndex >= 0) {
             databaseName = ((AString) synonymRecord.getValueByPos(databaseNameIndex)).getStringValue();
+        } else {
+            databaseName = MetadataUtil.databaseFor(dataverseName);
         }
-        String dataverseCanonicalName =
-                ((AString) synonymRecord.getValueByPos(synonymEntity.dataverseNameIndex())).getStringValue();
-        DataverseName dataverseName = DataverseName.createFromCanonicalForm(dataverseCanonicalName);
-
         String synonymName = ((AString) synonymRecord.getValueByPos(synonymEntity.synonymNameIndex())).getStringValue();
 
         String objectDataverseCanonicalName =
@@ -59,7 +61,7 @@
 
         String objectName = ((AString) synonymRecord.getValueByPos(synonymEntity.objectNameIndex())).getStringValue();
 
-        return new Synonym(dataverseName, synonymName, objectDataverseName, objectName);
+        return new Synonym(databaseName, dataverseName, synonymName, objectDataverseName, objectName);
     }
 
     @Override
diff --git a/asterixdb/asterix-metadata/src/main/java/org/apache/asterix/metadata/feeds/BuiltinFeedPolicies.java b/asterixdb/asterix-metadata/src/main/java/org/apache/asterix/metadata/feeds/BuiltinFeedPolicies.java
index f9ce755..05f1947 100644
--- a/asterixdb/asterix-metadata/src/main/java/org/apache/asterix/metadata/feeds/BuiltinFeedPolicies.java
+++ b/asterixdb/asterix-metadata/src/main/java/org/apache/asterix/metadata/feeds/BuiltinFeedPolicies.java
@@ -67,7 +67,8 @@
         policyParams.put(FeedPolicyAccessor.ELASTIC, Boolean.toString(false));
 
         String description = "Basic";
-        return new FeedPolicyEntity(MetadataConstants.METADATA_DATAVERSE_NAME, "Basic", description, policyParams);
+        return new FeedPolicyEntity(MetadataConstants.SYSTEM_DATABASE, MetadataConstants.METADATA_DATAVERSE_NAME,
+                "Basic", description, policyParams);
     }
 
     // Discard
@@ -80,7 +81,8 @@
         policyParams.put(FeedPolicyAccessor.LOGGING_STATISTICS, Boolean.toString(true));
 
         String description = "FlowControl 100% Discard during congestion";
-        return new FeedPolicyEntity(MetadataConstants.METADATA_DATAVERSE_NAME, "Discard", description, policyParams);
+        return new FeedPolicyEntity(MetadataConstants.SYSTEM_DATABASE, MetadataConstants.METADATA_DATAVERSE_NAME,
+                "Discard", description, policyParams);
     }
 
     // Spill
@@ -92,7 +94,8 @@
         policyParams.put(FeedPolicyAccessor.MAX_SPILL_SIZE_ON_DISK, "" + Long.toString(FeedPolicyAccessor.NO_LIMIT));
 
         String description = "FlowControl 100% Spill during congestion";
-        return new FeedPolicyEntity(MetadataConstants.METADATA_DATAVERSE_NAME, "Spill", description, policyParams);
+        return new FeedPolicyEntity(MetadataConstants.SYSTEM_DATABASE, MetadataConstants.METADATA_DATAVERSE_NAME,
+                "Spill", description, policyParams);
     }
 
     // AdvancedFT_Elastic
@@ -102,8 +105,8 @@
         policyParams.put(FeedPolicyAccessor.FLOWCONTROL_ENABLED, Boolean.toString(true));
         policyParams.put(FeedPolicyAccessor.LOGGING_STATISTICS, Boolean.toString(true));
         String description = "Basic Monitored Fault-Tolerant Elastic";
-        return new FeedPolicyEntity(MetadataConstants.METADATA_DATAVERSE_NAME, "AdvancedFT_Elastic", description,
-                policyParams);
+        return new FeedPolicyEntity(MetadataConstants.SYSTEM_DATABASE, MetadataConstants.METADATA_DATAVERSE_NAME,
+                "AdvancedFT_Elastic", description, policyParams);
     }
 
     public static void insertInitialFeedPolicies(MetadataTransactionContext mdTxnCtx) throws AlgebricksException {
diff --git a/asterixdb/asterix-metadata/src/main/java/org/apache/asterix/metadata/feeds/FeedMetadataUtil.java b/asterixdb/asterix-metadata/src/main/java/org/apache/asterix/metadata/feeds/FeedMetadataUtil.java
index a76f8a9..cccd3dd 100644
--- a/asterixdb/asterix-metadata/src/main/java/org/apache/asterix/metadata/feeds/FeedMetadataUtil.java
+++ b/asterixdb/asterix-metadata/src/main/java/org/apache/asterix/metadata/feeds/FeedMetadataUtil.java
@@ -178,9 +178,11 @@
     private static ITypedAdapterFactory createExternalAdapterFactory(MetadataTransactionContext mdTxnCtx,
             DatasourceAdapter adapterEntity, String adapterFactoryClassname)
             throws AlgebricksException, RemoteException, HyracksDataException {
+        String libraryDatabaseName = adapterEntity.getLibraryDatabaseName();
         DataverseName libraryDataverse = adapterEntity.getLibraryDataverseName();
         String libraryName = adapterEntity.getLibraryName();
-        Library library = MetadataManager.INSTANCE.getLibrary(mdTxnCtx, null, libraryDataverse, libraryName);
+        Library library =
+                MetadataManager.INSTANCE.getLibrary(mdTxnCtx, libraryDatabaseName, libraryDataverse, libraryName);
         if (library == null) {
             throw new CompilationException(ErrorCode.UNKNOWN_LIBRARY, libraryName);
         }
diff --git a/asterixdb/asterix-metadata/src/main/java/org/apache/asterix/metadata/utils/IndexUtil.java b/asterixdb/asterix-metadata/src/main/java/org/apache/asterix/metadata/utils/IndexUtil.java
index 87bc496..93bdf68 100644
--- a/asterixdb/asterix-metadata/src/main/java/org/apache/asterix/metadata/utils/IndexUtil.java
+++ b/asterixdb/asterix-metadata/src/main/java/org/apache/asterix/metadata/utils/IndexUtil.java
@@ -92,8 +92,8 @@
 
     public static Index getPrimaryIndex(Dataset dataset) {
         InternalDatasetDetails id = (InternalDatasetDetails) dataset.getDatasetDetails();
-        return Index.createPrimaryIndex(dataset.getDataverseName(), dataset.getDatasetName(), id.getPartitioningKey(),
-                id.getKeySourceIndicator(), id.getPrimaryKeyType(), dataset.getPendingOp());
+        return Index.createPrimaryIndex(dataset.getDatabaseName(), dataset.getDataverseName(), dataset.getDatasetName(),
+                id.getPartitioningKey(), id.getKeySourceIndicator(), id.getPrimaryKeyType(), dataset.getPendingOp());
     }
 
     public static int[] getBtreeFieldsIfFiltered(Dataset dataset, Index index) throws AlgebricksException {
diff --git a/asterixdb/asterix-metadata/src/main/java/org/apache/asterix/metadata/utils/MetadataUtil.java b/asterixdb/asterix-metadata/src/main/java/org/apache/asterix/metadata/utils/MetadataUtil.java
index 7bc6e98..638c3f4 100644
--- a/asterixdb/asterix-metadata/src/main/java/org/apache/asterix/metadata/utils/MetadataUtil.java
+++ b/asterixdb/asterix-metadata/src/main/java/org/apache/asterix/metadata/utils/MetadataUtil.java
@@ -44,4 +44,16 @@
     public static String getFullyQualifiedDisplayName(DataverseName dataverseName, String objectName) {
         return dataverseName + "." + objectName;
     }
+
+    public static String databaseFor(DataverseName dataverse) {
+        return MetadataConstants.METADATA_DATAVERSE_NAME.equals(dataverse) ? MetadataConstants.SYSTEM_DATABASE
+                : MetadataConstants.DEFAULT_DATABASE;
+    }
+
+    public static String resolveDatabase(String database, DataverseName dataverse) {
+        if (database != null) {
+            return database;
+        }
+        return databaseFor(dataverse);
+    }
 }
diff --git a/asterixdb/asterix-metadata/src/test/java/org/apache/asterix/metadata/entitytupletranslators/DatasetTupleTranslatorTest.java b/asterixdb/asterix-metadata/src/test/java/org/apache/asterix/metadata/entitytupletranslators/DatasetTupleTranslatorTest.java
index 8e40d3e..4567131 100644
--- a/asterixdb/asterix-metadata/src/test/java/org/apache/asterix/metadata/entitytupletranslators/DatasetTupleTranslatorTest.java
+++ b/asterixdb/asterix-metadata/src/test/java/org/apache/asterix/metadata/entitytupletranslators/DatasetTupleTranslatorTest.java
@@ -31,6 +31,7 @@
 import org.apache.asterix.metadata.entities.InternalDatasetDetails;
 import org.apache.asterix.metadata.entities.InternalDatasetDetails.FileStructure;
 import org.apache.asterix.metadata.entities.InternalDatasetDetails.PartitioningStrategy;
+import org.apache.asterix.metadata.utils.MetadataUtil;
 import org.apache.asterix.om.types.BuiltinType;
 import org.apache.asterix.runtime.compression.CompressionManager;
 import org.apache.hyracks.algebricks.common.exceptions.AlgebricksException;
@@ -54,11 +55,12 @@
                     indicator == null ? null : Collections.singletonList(indicator),
                     Collections.singletonList(BuiltinType.AINT64), false, null, null);
 
-            Dataset dataset = new Dataset(DataverseName.createSinglePartName("test"), "log",
-                    DataverseName.createSinglePartName("foo"), "LogType", DataverseName.createSinglePartName("CB"),
-                    "MetaType", "DEFAULT_NG_ALL_NODES", "prefix", compactionPolicyProperties, details,
-                    Collections.emptyMap(), DatasetType.INTERNAL, 115, 0, CompressionManager.NONE,
-                    DatasetFormatInfo.SYSTEM_DEFAULT);
+            DataverseName dv = DataverseName.createSinglePartName("test");
+            String db = MetadataUtil.databaseFor(dv);
+            Dataset dataset = new Dataset(db, dv, "log", DataverseName.createSinglePartName("foo"), "LogType",
+                    DataverseName.createSinglePartName("CB"), "MetaType", "DEFAULT_NG_ALL_NODES", "prefix",
+                    compactionPolicyProperties, details, Collections.emptyMap(), DatasetType.INTERNAL, 115, 0,
+                    CompressionManager.NONE, DatasetFormatInfo.SYSTEM_DEFAULT);
             DatasetTupleTranslator dtTranslator = new DatasetTupleTranslator(true, DatasetEntity.of(false));
             ITupleReference tuple = dtTranslator.getTupleFromMetadataEntity(dataset);
             Dataset deserializedDataset = dtTranslator.getMetadataEntityFromTuple(tuple);
diff --git a/asterixdb/asterix-metadata/src/test/java/org/apache/asterix/metadata/entitytupletranslators/IndexTupleTranslatorTest.java b/asterixdb/asterix-metadata/src/test/java/org/apache/asterix/metadata/entitytupletranslators/IndexTupleTranslatorTest.java
index 9ab3e66..6476a9f 100644
--- a/asterixdb/asterix-metadata/src/test/java/org/apache/asterix/metadata/entitytupletranslators/IndexTupleTranslatorTest.java
+++ b/asterixdb/asterix-metadata/src/test/java/org/apache/asterix/metadata/entitytupletranslators/IndexTupleTranslatorTest.java
@@ -18,7 +18,6 @@
  */
 package org.apache.asterix.metadata.entitytupletranslators;
 
-import static org.mockito.ArgumentMatchers.isNull;
 import static org.mockito.Matchers.any;
 import static org.mockito.Matchers.anyString;
 import static org.mockito.Mockito.mock;
@@ -41,6 +40,7 @@
 import org.apache.asterix.metadata.entities.InternalDatasetDetails;
 import org.apache.asterix.metadata.entities.InternalDatasetDetails.FileStructure;
 import org.apache.asterix.metadata.entities.InternalDatasetDetails.PartitioningStrategy;
+import org.apache.asterix.metadata.utils.MetadataUtil;
 import org.apache.asterix.om.types.ARecordType;
 import org.apache.asterix.om.types.BuiltinType;
 import org.apache.asterix.om.types.IAType;
@@ -70,21 +70,22 @@
             DataverseName dvTest = DataverseName.createSinglePartName("test");
             DataverseName dvFoo = DataverseName.createSinglePartName("foo");
             DataverseName dvCB = DataverseName.createSinglePartName("CB");
-            Dataset dataset = new Dataset(dvTest, "d1", dvFoo, "LogType", dvCB, "MetaType", "DEFAULT_NG_ALL_NODES",
-                    "prefix", compactionPolicyProperties, details, Collections.emptyMap(), DatasetType.INTERNAL, 115, 0,
-                    CompressionManager.NONE, DatasetFormatInfo.SYSTEM_DEFAULT);
+            String dvTestDatabase = MetadataUtil.databaseFor(dvTest);
+            Dataset dataset = new Dataset(dvTestDatabase, dvTest, "d1", dvFoo, "LogType", dvCB, "MetaType",
+                    "DEFAULT_NG_ALL_NODES", "prefix", compactionPolicyProperties, details, Collections.emptyMap(),
+                    DatasetType.INTERNAL, 115, 0, CompressionManager.NONE, DatasetFormatInfo.SYSTEM_DEFAULT);
 
-            Index index = new Index(dvTest, "d1", "i1", IndexType.BTREE,
+            Index index = new Index(dvTestDatabase, dvTest, "d1", "i1", IndexType.BTREE,
                     Collections.singletonList(Collections.singletonList("row_id")),
                     indicator == null ? null : Collections.singletonList(indicator),
                     Collections.singletonList(BuiltinType.AINT64), false, false, false, 0, OptionalBoolean.of(false));
 
             MetadataNode mockMetadataNode = mock(MetadataNode.class);
-            when(mockMetadataNode.getDatatype(any(), isNull(), any(DataverseName.class), anyString()))
-                    .thenReturn(new Datatype(dvTest, "d1",
+            when(mockMetadataNode.getDatatype(any(), anyString(), any(DataverseName.class), anyString()))
+                    .thenReturn(new Datatype(dvTestDatabase, dvTest, "d1",
                             new ARecordType("", new String[] { "row_id" }, new IAType[] { BuiltinType.AINT64 }, true),
                             true));
-            when(mockMetadataNode.getDataset(any(), isNull(), any(DataverseName.class), anyString()))
+            when(mockMetadataNode.getDataset(any(), anyString(), any(DataverseName.class), anyString()))
                     .thenReturn(dataset);
 
             IndexTupleTranslator idxTranslator =
diff --git a/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/fulltext/AbstractFullTextFilterDescriptor.java b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/fulltext/AbstractFullTextFilterDescriptor.java
index 139a983..637ea48 100644
--- a/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/fulltext/AbstractFullTextFilterDescriptor.java
+++ b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/fulltext/AbstractFullTextFilterDescriptor.java
@@ -19,16 +19,19 @@
 
 package org.apache.asterix.runtime.fulltext;
 
+import java.util.Objects;
+
 import org.apache.asterix.common.metadata.DataverseName;
 
 public abstract class AbstractFullTextFilterDescriptor implements IFullTextFilterDescriptor {
     private static final long serialVersionUID = 5325972301942118022L;
 
-    private final String databaseName = null;
+    private final String databaseName;
     protected final DataverseName dataverseName;
     protected final String name;
 
-    public AbstractFullTextFilterDescriptor(DataverseName dataverseName, String name) {
+    public AbstractFullTextFilterDescriptor(String databaseName, DataverseName dataverseName, String name) {
+        this.databaseName = Objects.requireNonNull(databaseName);
         this.dataverseName = dataverseName;
         this.name = name;
     }
diff --git a/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/fulltext/FullTextConfigDescriptor.java b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/fulltext/FullTextConfigDescriptor.java
index 524e46a..4ae5900 100644
--- a/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/fulltext/FullTextConfigDescriptor.java
+++ b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/fulltext/FullTextConfigDescriptor.java
@@ -33,14 +33,16 @@
 public class FullTextConfigDescriptor implements IFullTextConfigDescriptor {
     private static final long serialVersionUID = 2L;
 
-    private final String databaseName = null;
+    private final String databaseName;
     private final DataverseName dataverseName;
     private final String name;
     private final TokenizerCategory tokenizerCategory;
     private final ImmutableList<String> filterNames;
 
-    public FullTextConfigDescriptor(DataverseName dataverseName, String name, TokenizerCategory tokenizerCategory,
-            ImmutableList<String> filterNames) {
+    public FullTextConfigDescriptor(String databaseName, DataverseName dataverseName, String name,
+            TokenizerCategory tokenizerCategory, ImmutableList<String> filterNames) {
+        //TODO(DB): database name should not be null
+        this.databaseName = databaseName;
         this.dataverseName = dataverseName;
         this.name = name;
         this.tokenizerCategory = tokenizerCategory;
@@ -53,7 +55,7 @@
     // the metadata manager will return this default full-text config without looking into the metadata catalog
     // In this way we avoid the edge cases to insert or delete the default config in the metadata catalog
     public static FullTextConfigDescriptor getDefaultFullTextConfig() {
-        return new FullTextConfigDescriptor(null, null, TokenizerCategory.WORD, ImmutableList.of());
+        return new FullTextConfigDescriptor(null, null, null, TokenizerCategory.WORD, ImmutableList.of());
     }
 
     public String getDatabaseName() {
diff --git a/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/fulltext/StopwordsFullTextFilterDescriptor.java b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/fulltext/StopwordsFullTextFilterDescriptor.java
index 1dbef70..76e9470 100644
--- a/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/fulltext/StopwordsFullTextFilterDescriptor.java
+++ b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/fulltext/StopwordsFullTextFilterDescriptor.java
@@ -33,9 +33,9 @@
 
     public ImmutableList<String> stopwordList;
 
-    public StopwordsFullTextFilterDescriptor(DataverseName dataverseName, String name,
+    public StopwordsFullTextFilterDescriptor(String database, DataverseName dataverseName, String name,
             ImmutableList<String> stopwordList) {
-        super(dataverseName, name);
+        super(database, dataverseName, name);
         this.stopwordList = stopwordList;
     }