[ASTERIXDB-3483][MTD]: Owner changes

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

details:
- Add 'Creator' nested open fields in the database
and dataverse entities.
- Extend methods to pass the creator.
- This change is backward compatible.

Ext-ref: MB-62971
Change-Id: Iaf57c37b40fea6a7f0241d1bad5dd7e8530bd4d4
Reviewed-on: https://asterix-gerrit.ics.uci.edu/c/asterixdb/+/18651
Integration-Tests: Jenkins <jenkins@fulliautomatix.ics.uci.edu>
Tested-by: Jenkins <jenkins@fulliautomatix.ics.uci.edu>
Reviewed-by: Janhavi Tripurwar <janhavi.tripurwar@couchbase.com>
Reviewed-by: Ali Alsuliman <ali.al.solaiman@gmail.com>
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 f30c800..bf07018 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
@@ -190,6 +190,7 @@
 import org.apache.asterix.metadata.entities.DatasourceAdapter;
 import org.apache.asterix.metadata.entities.Datatype;
 import org.apache.asterix.metadata.entities.Dataverse;
+import org.apache.asterix.metadata.entities.EntityDetails;
 import org.apache.asterix.metadata.entities.ExternalDatasetDetails;
 import org.apache.asterix.metadata.entities.Feed;
 import org.apache.asterix.metadata.entities.FeedConnection;
@@ -205,6 +206,7 @@
 import org.apache.asterix.metadata.entities.ViewDetails;
 import org.apache.asterix.metadata.feeds.FeedMetadataUtil;
 import org.apache.asterix.metadata.functions.ExternalFunctionCompilerUtil;
+import org.apache.asterix.metadata.utils.Creator;
 import org.apache.asterix.metadata.utils.DatasetUtil;
 import org.apache.asterix.metadata.utils.IndexUtil;
 import org.apache.asterix.metadata.utils.KeyFieldTypeUtil;
@@ -385,11 +387,11 @@
                         break;
                     case CREATE_DATABASE:
                         handleCreateDatabaseStatement(metadataProvider, stmt, requestParameters,
-                                MetadataConstants.DEFAULT_OWNER);
+                                Creator.DEFAULT_CREATOR);
                         break;
                     case CREATE_DATAVERSE:
                         handleCreateDataverseStatement(metadataProvider, stmt, requestParameters,
-                                MetadataConstants.DEFAULT_OWNER);
+                                Creator.DEFAULT_CREATOR);
                         break;
                     case DATASET_DECL:
                         handleCreateDatasetStatement(metadataProvider, stmt, hcc, requestParameters);
@@ -659,7 +661,7 @@
     }
 
     protected void handleCreateDatabaseStatement(MetadataProvider metadataProvider, Statement stmt,
-            IRequestParameters requestParameters, String ownerName) throws Exception {
+            IRequestParameters requestParameters, Creator creator) throws Exception {
         CreateDatabaseStatement stmtCreateDatabase = (CreateDatabaseStatement) stmt;
         String database = stmtCreateDatabase.getDatabaseName().getValue();
         metadataProvider.validateDatabaseName(database, stmt.getSourceLocation());
@@ -668,14 +670,14 @@
         }
         lockUtil.createDatabaseBegin(lockManager, metadataProvider.getLocks(), database);
         try {
-            doCreateDatabaseStatement(metadataProvider, stmtCreateDatabase, requestParameters, ownerName);
+            doCreateDatabaseStatement(metadataProvider, stmtCreateDatabase, requestParameters, creator);
         } finally {
             metadataProvider.getLocks().unlock();
         }
     }
 
     protected boolean doCreateDatabaseStatement(MetadataProvider mdProvider, CreateDatabaseStatement stmtCreateDatabase,
-            IRequestParameters requestParameters, String ownerName) throws Exception {
+            IRequestParameters requestParameters, Creator creator) throws Exception {
         MetadataTransactionContext mdTxnCtx = MetadataManager.INSTANCE.beginTransaction();
         mdProvider.setMetadataTxnContext(mdTxnCtx);
         try {
@@ -691,8 +693,9 @@
                 }
             }
 
+            beforeTxnCommit(mdProvider, creator, databaseName, null, null, EntityDetails.EntityType.DATABASE);
             MetadataManager.INSTANCE.addDatabase(mdTxnCtx,
-                    new Database(databaseName, false, ownerName, MetadataUtil.PENDING_NO_OP));
+                    new Database(databaseName, false, MetadataUtil.PENDING_NO_OP, creator));
             MetadataManager.INSTANCE.commitTransaction(mdTxnCtx);
             return true;
         } catch (Exception e) {
@@ -702,7 +705,7 @@
     }
 
     protected void handleCreateDataverseStatement(MetadataProvider metadataProvider, Statement stmt,
-            IRequestParameters requestParameters, String ownerName) throws Exception {
+            IRequestParameters requestParameters, Creator creator) throws Exception {
         CreateDataverseStatement stmtCreateDataverse = (CreateDataverseStatement) stmt;
         DataverseName dvName = stmtCreateDataverse.getDataverseName();
         String dbName = stmtCreateDataverse.getDatabaseName();
@@ -713,7 +716,7 @@
         }
         lockUtil.createDataverseBegin(lockManager, metadataProvider.getLocks(), dbName, dvName);
         try {
-            doCreateDataverseStatement(metadataProvider, stmtCreateDataverse, requestParameters, ownerName);
+            doCreateDataverseStatement(metadataProvider, stmtCreateDataverse, requestParameters, creator);
         } finally {
             metadataProvider.getLocks().unlock();
         }
@@ -721,7 +724,7 @@
 
     @SuppressWarnings("squid:S00112")
     protected boolean doCreateDataverseStatement(MetadataProvider metadataProvider,
-            CreateDataverseStatement stmtCreateDataverse, IRequestParameters requestParameters, String ownerName)
+            CreateDataverseStatement stmtCreateDataverse, IRequestParameters requestParameters, Creator creator)
             throws Exception {
         MetadataTransactionContext mdTxnCtx = MetadataManager.INSTANCE.beginTransaction();
         metadataProvider.setMetadataTxnContext(mdTxnCtx);
@@ -745,8 +748,9 @@
                             dvName);
                 }
             }
+            beforeTxnCommit(metadataProvider, creator, dbName, dvName, null, EntityDetails.EntityType.DATAVERSE);
             MetadataManager.INSTANCE.addDataverse(metadataProvider.getMetadataTxnContext(), new Dataverse(dbName,
-                    dvName, stmtCreateDataverse.getFormat(), MetadataUtil.PENDING_NO_OP, ownerName));
+                    dvName, stmtCreateDataverse.getFormat(), MetadataUtil.PENDING_NO_OP, creator));
             MetadataManager.INSTANCE.commitTransaction(mdTxnCtx);
             return true;
         } catch (Exception e) {
@@ -2074,7 +2078,7 @@
             // Note: the delete operation fails if the database cannot be deleted due to metadata dependencies
             MetadataManager.INSTANCE.dropDatabase(mdTxnCtx, databaseName);
             MetadataManager.INSTANCE.addDatabase(mdTxnCtx, new Database(databaseName, database.isSystemDatabase(),
-                    MetadataConstants.DEFAULT_OWNER, MetadataUtil.PENDING_DROP_OP));
+                    MetadataUtil.PENDING_DROP_OP, database.getCreator()));
 
             MetadataManager.INSTANCE.commitTransaction(mdTxnCtx);
             bActiveTxn = false;
@@ -2260,7 +2264,7 @@
             // Note: the delete operation fails if the dataverse cannot be deleted due to metadata dependencies
             MetadataManager.INSTANCE.dropDataverse(mdTxnCtx, databaseName, dataverseName);
             MetadataManager.INSTANCE.addDataverse(mdTxnCtx, new Dataverse(databaseName, dataverseName,
-                    dv.getDataFormat(), MetadataUtil.PENDING_DROP_OP, MetadataConstants.DEFAULT_OWNER));
+                    dv.getDataFormat(), MetadataUtil.PENDING_DROP_OP, dv.getCreator()));
 
             MetadataManager.INSTANCE.commitTransaction(mdTxnCtx);
             bActiveTxn = false;
@@ -5820,6 +5824,11 @@
         }
     }
 
+    protected void beforeTxnCommit(MetadataProvider metadataProvider, Creator creator, String databaseName,
+            DataverseName dataverseName, String objectName, Object objectType) throws AlgebricksException {
+        //no op
+    }
+
     protected enum CreateResult {
         NOOP,
         CREATED,
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 2af06b7..7c4c551 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
@@ -36,7 +36,6 @@
 import org.apache.asterix.common.dataflow.ICcApplicationContext;
 import org.apache.asterix.common.dataflow.LSMInsertDeleteOperatorNodePushable;
 import org.apache.asterix.common.exceptions.ACIDException;
-import org.apache.asterix.common.metadata.MetadataConstants;
 import org.apache.asterix.common.metadata.MetadataUtil;
 import org.apache.asterix.common.metadata.Namespace;
 import org.apache.asterix.common.metadata.NamespacePathResolver;
@@ -54,6 +53,7 @@
 import org.apache.asterix.metadata.entities.Dataverse;
 import org.apache.asterix.metadata.entities.Index;
 import org.apache.asterix.metadata.entities.NoOpLSMTupleFilterCallbackFactory;
+import org.apache.asterix.metadata.utils.Creator;
 import org.apache.asterix.metadata.utils.DatasetUtil;
 import org.apache.asterix.metadata.utils.SplitsAndConstraintsUtil;
 import org.apache.asterix.om.types.ARecordType;
@@ -501,7 +501,7 @@
         PrimaryIndexInfo primaryIndexInfo = new PrimaryIndexInfo(dataset, primaryKeyTypes, recordType, metaType,
                 mergePolicy.first, mergePolicy.second, filterFields, primaryKeyIndexes, primaryKeyIndicators);
         Dataverse dataverse = new Dataverse(dataset.getDatabaseName(), dataset.getDataverseName(),
-                NonTaggedDataFormat.class.getName(), MetadataUtil.PENDING_NO_OP, MetadataConstants.DEFAULT_OWNER);
+                NonTaggedDataFormat.class.getName(), MetadataUtil.PENDING_NO_OP, Creator.DEFAULT_CREATOR);
         Namespace namespace = new Namespace(dataverse.getDatabaseName(), dataverse.getDataverseName());
         MetadataProvider mdProvider = MetadataProvider.create(
                 (ICcApplicationContext) ExecutionTestUtil.integrationUtil.cc.getApplicationContext(), namespace);
@@ -527,9 +527,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.getDatabaseName(),
-                primaryIndexInfo.dataset.getDataverseName(), NonTaggedDataFormat.class.getName(),
-                MetadataUtil.PENDING_NO_OP, MetadataConstants.DEFAULT_OWNER);
+        Dataverse dataverse =
+                new Dataverse(primaryIndexInfo.dataset.getDatabaseName(), primaryIndexInfo.dataset.getDataverseName(),
+                        NonTaggedDataFormat.class.getName(), MetadataUtil.PENDING_NO_OP, Creator.DEFAULT_CREATOR);
         Namespace namespace = new Namespace(dataverse.getDatabaseName(), dataverse.getDataverseName());
         MetadataProvider mdProvider = MetadataProvider.create(
                 (ICcApplicationContext) ExecutionTestUtil.integrationUtil.cc.getApplicationContext(), namespace);
diff --git a/asterixdb/asterix-common/src/main/java/org/apache/asterix/common/metadata/MetadataConstants.java b/asterixdb/asterix-common/src/main/java/org/apache/asterix/common/metadata/MetadataConstants.java
index 5bff2c1..05b21af 100644
--- a/asterixdb/asterix-common/src/main/java/org/apache/asterix/common/metadata/MetadataConstants.java
+++ b/asterixdb/asterix-common/src/main/java/org/apache/asterix/common/metadata/MetadataConstants.java
@@ -38,8 +38,9 @@
     public static final String SYSTEM_DATABASE = "System";
     public static final String DEFAULT_DATABASE = "Default";
 
-    // Pre-defined owner
-    public static final String DEFAULT_OWNER = "@sys";
+    // Pre-defined creator
+    public static final String DEFAULT_CREATOR = "@sys";
+    public static final String DEFAULT_CREATOR_UUID = "97c793f3-bcbf-4595-8bf0-e9d6a5953523";
 
     // Name of the dataverse the metadata lives in.
     public static final DataverseName METADATA_DATAVERSE_NAME = DataverseName.createBuiltinDataverseName("Metadata");
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 76b8a0b..1901798 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
@@ -178,7 +178,7 @@
     }
 
     public void dropDatabase(String databaseName) {
-        Database database = new Database(databaseName, false, null, MetadataUtil.PENDING_NO_OP);
+        Database database = new Database(databaseName, false, MetadataUtil.PENDING_NO_OP, null);
         droppedCache.addDatabaseIfNotExists(database);
         logAndApply(new MetadataLogicalOperation(database, false));
     }
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 7f60345..f11ab01 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
@@ -24,26 +24,27 @@
 import org.apache.asterix.metadata.entities.Database;
 import org.apache.asterix.metadata.entities.Datatype;
 import org.apache.asterix.metadata.entities.Dataverse;
+import org.apache.asterix.metadata.utils.Creator;
 import org.apache.asterix.om.utils.RecordUtil;
 import org.apache.asterix.runtime.formats.NonTaggedDataFormat;
 
 public class MetadataBuiltinEntities {
 
     //--------------------------------------- Databases ----------------------------------------//
-    public static final Database SYSTEM_DATABASE = new Database(MetadataConstants.SYSTEM_DATABASE, true,
-            MetadataConstants.DEFAULT_OWNER, MetadataUtil.PENDING_NO_OP);
+    public static final Database SYSTEM_DATABASE =
+            new Database(MetadataConstants.SYSTEM_DATABASE, true, MetadataUtil.PENDING_NO_OP, Creator.DEFAULT_CREATOR);
 
     public static final Database DEFAULT_DATABASE = new Database(MetadataConstants.DEFAULT_DATABASE, false,
-            MetadataConstants.DEFAULT_OWNER, MetadataUtil.PENDING_NO_OP);
+            MetadataUtil.PENDING_NO_OP, Creator.DEFAULT_CREATOR);
 
     //--------------------------------------- Dataverses ----------------------------------------//
-    public static final Dataverse METADATA_DATAVERSE = new Dataverse(MetadataConstants.SYSTEM_DATABASE,
-            MetadataConstants.METADATA_DATAVERSE_NAME, NonTaggedDataFormat.NON_TAGGED_DATA_FORMAT,
-            MetadataUtil.PENDING_NO_OP, MetadataConstants.DEFAULT_OWNER);
+    public static final Dataverse METADATA_DATAVERSE =
+            new Dataverse(MetadataConstants.SYSTEM_DATABASE, MetadataConstants.METADATA_DATAVERSE_NAME,
+                    NonTaggedDataFormat.NON_TAGGED_DATA_FORMAT, MetadataUtil.PENDING_NO_OP, Creator.DEFAULT_CREATOR);
 
     public static final Dataverse DEFAULT_DATAVERSE =
             new Dataverse(MetadataConstants.DEFAULT_DATABASE, MetadataConstants.DEFAULT_DATAVERSE_NAME,
-                    NonTaggedDataFormat.class.getName(), MetadataUtil.PENDING_NO_OP, MetadataConstants.DEFAULT_OWNER);
+                    NonTaggedDataFormat.class.getName(), MetadataUtil.PENDING_NO_OP, Creator.DEFAULT_CREATOR);
 
     //--------------------------------------- Datatypes -----------------------------------------//
     public static final Datatype ANY_OBJECT_DATATYPE =
diff --git a/asterixdb/asterix-metadata/src/main/java/org/apache/asterix/metadata/bootstrap/MetadataRecordTypes.java b/asterixdb/asterix-metadata/src/main/java/org/apache/asterix/metadata/bootstrap/MetadataRecordTypes.java
index a6b3863..338e00d 100644
--- a/asterixdb/asterix-metadata/src/main/java/org/apache/asterix/metadata/bootstrap/MetadataRecordTypes.java
+++ b/asterixdb/asterix-metadata/src/main/java/org/apache/asterix/metadata/bootstrap/MetadataRecordTypes.java
@@ -131,7 +131,9 @@
     public static final String FIELD_NAME_FULL_TEXT_STOPWORD_LIST = "StopwordList";
 
     //open field
-    public static final String FIELD_NAME_OWNER_NAME = "OwnerName";
+    public static final String FIELD_NAME_CREATOR_NAME = "Name";
+    public static final String FIELD_NAME_CREATOR_UUID = "Uuid";
+    public static final String CREATOR_ARECORD_FIELD_NAME = "Creator";
 
     //---------------------------------- Record Types Creation ----------------------------------//
     //--------------------------------------- Properties ----------------------------------------//
diff --git a/asterixdb/asterix-metadata/src/main/java/org/apache/asterix/metadata/entities/Database.java b/asterixdb/asterix-metadata/src/main/java/org/apache/asterix/metadata/entities/Database.java
index e734e51..6336596 100644
--- a/asterixdb/asterix-metadata/src/main/java/org/apache/asterix/metadata/entities/Database.java
+++ b/asterixdb/asterix-metadata/src/main/java/org/apache/asterix/metadata/entities/Database.java
@@ -23,6 +23,7 @@
 
 import org.apache.asterix.metadata.MetadataCache;
 import org.apache.asterix.metadata.api.IMetadataEntity;
+import org.apache.asterix.metadata.utils.Creator;
 
 /**
  * Metadata describing a database.
@@ -33,14 +34,14 @@
 
     private final String databaseName;
     private final boolean isSystemDatabase;
-    private final String owner;
     private final int pendingOp;
+    private final Creator creator;
 
-    public Database(String databaseName, boolean isSystemDatabase, String owner, int pendingOp) {
+    public Database(String databaseName, boolean isSystemDatabase, int pendingOp, Creator creator) {
         this.databaseName = databaseName;
         this.isSystemDatabase = isSystemDatabase;
-        this.owner = owner;
         this.pendingOp = pendingOp;
+        this.creator = creator;
     }
 
     public String getDatabaseName() {
@@ -51,14 +52,14 @@
         return isSystemDatabase;
     }
 
-    public String getOwnerName() {
-        return owner;
-    }
-
     public int getPendingOp() {
         return pendingOp;
     }
 
+    public Creator getCreator() {
+        return creator;
+    }
+
     @Override
     public Database addToCache(MetadataCache cache) {
         return cache.addDatabaseIfNotExists(this);
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 a07a495..5b52be4 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
@@ -24,6 +24,7 @@
 import org.apache.asterix.common.metadata.DataverseName;
 import org.apache.asterix.metadata.MetadataCache;
 import org.apache.asterix.metadata.api.IMetadataEntity;
+import org.apache.asterix.metadata.utils.Creator;
 
 /**
  * Metadata describing a dataverse.
@@ -35,14 +36,14 @@
     private final DataverseName dataverseName;
     private final String dataFormat;
     private final int pendingOp;
-    private final String ownerName;
+    private final Creator creator;
 
-    public Dataverse(String databaseName, DataverseName dataverseName, String format, int pendingOp, String ownerName) {
+    public Dataverse(String databaseName, DataverseName dataverseName, String format, int pendingOp, Creator creator) {
         this.databaseName = Objects.requireNonNull(databaseName);
         this.dataverseName = dataverseName;
         this.dataFormat = format;
         this.pendingOp = pendingOp;
-        this.ownerName = ownerName;
+        this.creator = creator;
     }
 
     public String getDatabaseName() {
@@ -61,8 +62,8 @@
         return pendingOp;
     }
 
-    public String getOwnerName() {
-        return ownerName;
+    public Creator getCreator() {
+        return creator;
     }
 
     @Override
diff --git a/asterixdb/asterix-metadata/src/main/java/org/apache/asterix/metadata/entities/EntityDetails.java b/asterixdb/asterix-metadata/src/main/java/org/apache/asterix/metadata/entities/EntityDetails.java
index a341a39..9493349 100644
--- a/asterixdb/asterix-metadata/src/main/java/org/apache/asterix/metadata/entities/EntityDetails.java
+++ b/asterixdb/asterix-metadata/src/main/java/org/apache/asterix/metadata/entities/EntityDetails.java
@@ -25,7 +25,9 @@
     public enum EntityType {
         DATASET,
         VIEW,
-        FUNCTION
+        FUNCTION,
+        DATABASE,
+        DATAVERSE
     }
 
     private final String databaseName;
diff --git a/asterixdb/asterix-metadata/src/main/java/org/apache/asterix/metadata/entitytupletranslators/DatabaseTupleTranslator.java b/asterixdb/asterix-metadata/src/main/java/org/apache/asterix/metadata/entitytupletranslators/DatabaseTupleTranslator.java
index 9a5a5d8..ef1b450 100644
--- a/asterixdb/asterix-metadata/src/main/java/org/apache/asterix/metadata/entitytupletranslators/DatabaseTupleTranslator.java
+++ b/asterixdb/asterix-metadata/src/main/java/org/apache/asterix/metadata/entitytupletranslators/DatabaseTupleTranslator.java
@@ -21,16 +21,17 @@
 
 import java.util.Calendar;
 
-import org.apache.asterix.common.metadata.MetadataConstants;
+import org.apache.asterix.builders.RecordBuilder;
 import org.apache.asterix.metadata.bootstrap.DatabaseEntity;
 import org.apache.asterix.metadata.bootstrap.MetadataRecordTypes;
 import org.apache.asterix.metadata.entities.Database;
+import org.apache.asterix.metadata.utils.Creator;
 import org.apache.asterix.om.base.ABoolean;
 import org.apache.asterix.om.base.AInt32;
 import org.apache.asterix.om.base.AMutableInt32;
 import org.apache.asterix.om.base.ARecord;
 import org.apache.asterix.om.base.AString;
-import org.apache.asterix.om.types.ARecordType;
+import org.apache.asterix.om.pointables.base.DefaultOpenFieldType;
 import org.apache.hyracks.algebricks.common.exceptions.AlgebricksException;
 import org.apache.hyracks.api.exceptions.HyracksDataException;
 import org.apache.hyracks.dataflow.common.data.accessors.ITupleReference;
@@ -53,20 +54,14 @@
 
     @Override
     protected Database createMetadataEntityFromARecord(ARecord databaseRecord) throws AlgebricksException {
-        ARecordType recType = databaseRecord.getType();
         String databaseName =
                 ((AString) databaseRecord.getValueByPos(databaseEntity.databaseNameIndex())).getStringValue();
         boolean isSystemDatabase =
                 ((ABoolean) databaseRecord.getValueByPos(databaseEntity.systemDatabaseIndex())).getBoolean();
-        int ownerIndex = recType.getFieldIndex(MetadataRecordTypes.FIELD_NAME_OWNER_NAME);
-        String ownerName;
-        if (ownerIndex >= 0) {
-            ownerName = ((AString) databaseRecord.getValueByPos(ownerIndex)).getStringValue();
-        } else {
-            ownerName = MetadataConstants.DEFAULT_OWNER;
-        }
         int pendingOp = ((AInt32) databaseRecord.getValueByPos(databaseEntity.pendingOpIndex())).getIntegerValue();
-        return new Database(databaseName, isSystemDatabase, ownerName, pendingOp);
+        Creator creator = Creator.createOrDefault(databaseRecord);
+
+        return new Database(databaseName, isSystemDatabase, pendingOp, creator);
     }
 
     @Override
@@ -117,17 +112,36 @@
     }
 
     protected void writeOpenFields(Database database) throws HyracksDataException {
-        writeDatabaseOwner(database);
+        writeDatabaseCreator(database);
     }
 
-    private void writeDatabaseOwner(Database database) throws HyracksDataException {
+    private void writeDatabaseCreator(Database database) throws HyracksDataException {
         if (databaseEntity.databaseNameIndex() >= 0) {
-            fieldValue.reset();
-            aString.setValue(MetadataRecordTypes.FIELD_NAME_OWNER_NAME);
+            Creator creatorInfo = database.getCreator();
+            RecordBuilder creatorObject = new RecordBuilder();
+            creatorObject.reset(DefaultOpenFieldType.NESTED_OPEN_RECORD_TYPE);
+
+            fieldName.reset();
+            aString.setValue(MetadataRecordTypes.FIELD_NAME_CREATOR_NAME);
             stringSerde.serialize(aString, fieldName.getDataOutput());
             fieldValue.reset();
-            aString.setValue(database.getOwnerName());
+            aString.setValue(creatorInfo.getName());
             stringSerde.serialize(aString, fieldValue.getDataOutput());
+            creatorObject.addField(fieldName, fieldValue);
+
+            fieldName.reset();
+            aString.setValue(MetadataRecordTypes.FIELD_NAME_CREATOR_UUID);
+            stringSerde.serialize(aString, fieldName.getDataOutput());
+            fieldValue.reset();
+            aString.setValue(creatorInfo.getUuid());
+            stringSerde.serialize(aString, fieldValue.getDataOutput());
+            creatorObject.addField(fieldName, fieldValue);
+
+            fieldName.reset();
+            aString.setValue(MetadataRecordTypes.CREATOR_ARECORD_FIELD_NAME);
+            stringSerde.serialize(aString, fieldName.getDataOutput());
+            fieldValue.reset();
+            creatorObject.write(fieldValue.getDataOutput(), true);
             recordBuilder.addField(fieldName, fieldValue);
         }
     }
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 e2d097b..10c4b07 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
@@ -21,17 +21,18 @@
 
 import java.util.Calendar;
 
+import org.apache.asterix.builders.RecordBuilder;
 import org.apache.asterix.common.metadata.DataverseName;
-import org.apache.asterix.common.metadata.MetadataConstants;
 import org.apache.asterix.common.metadata.MetadataUtil;
 import org.apache.asterix.metadata.bootstrap.DataverseEntity;
 import org.apache.asterix.metadata.bootstrap.MetadataRecordTypes;
 import org.apache.asterix.metadata.entities.Dataverse;
+import org.apache.asterix.metadata.utils.Creator;
 import org.apache.asterix.om.base.AInt32;
 import org.apache.asterix.om.base.AMutableInt32;
 import org.apache.asterix.om.base.ARecord;
 import org.apache.asterix.om.base.AString;
-import org.apache.asterix.om.types.ARecordType;
+import org.apache.asterix.om.pointables.base.DefaultOpenFieldType;
 import org.apache.hyracks.algebricks.common.exceptions.AlgebricksException;
 import org.apache.hyracks.api.exceptions.HyracksDataException;
 import org.apache.hyracks.dataflow.common.data.accessors.ITupleReference;
@@ -54,29 +55,22 @@
 
     @Override
     protected Dataverse createMetadataEntityFromARecord(ARecord dataverseRecord) throws AlgebricksException {
-        ARecordType recType = dataverseRecord.getType();
-
         String dataverseCanonicalName =
                 ((AString) dataverseRecord.getValueByPos(dataverseEntity.dataverseNameIndex())).getStringValue();
         DataverseName dataverseName = DataverseName.createFromCanonicalForm(dataverseCanonicalName);
         int databaseNameIndex = dataverseEntity.databaseNameIndex();
-        int ownerNameIndex = recType.getFieldIndex(MetadataRecordTypes.FIELD_NAME_OWNER_NAME);
-        String databaseName, ownerName;
+
+        String databaseName;
         if (databaseNameIndex >= 0) {
             databaseName = ((AString) dataverseRecord.getValueByPos(databaseNameIndex)).getStringValue();
         } else {
             databaseName = MetadataUtil.databaseFor(dataverseName);
         }
-
-        if (ownerNameIndex >= 0) {
-            ownerName = ((AString) dataverseRecord.getValueByPos(ownerNameIndex)).getStringValue();
-        } else {
-            ownerName = MetadataConstants.DEFAULT_OWNER;
-        }
         String format = ((AString) dataverseRecord.getValueByPos(dataverseEntity.dataFormatIndex())).getStringValue();
         int pendingOp = ((AInt32) dataverseRecord.getValueByPos(dataverseEntity.pendingOpIndex())).getIntegerValue();
+        Creator creator = Creator.createOrDefault(dataverseRecord);
 
-        return new Dataverse(databaseName, dataverseName, format, pendingOp, ownerName);
+        return new Dataverse(databaseName, dataverseName, format, pendingOp, creator);
     }
 
     @Override
@@ -139,17 +133,36 @@
     }
 
     protected void writeOpenFields(Dataverse dataverse) throws HyracksDataException {
-        writeDataverseOwner(dataverse);
+        writeDataverseCreator(dataverse);
     }
 
-    private void writeDataverseOwner(Dataverse dataverse) throws HyracksDataException {
+    private void writeDataverseCreator(Dataverse dataverse) throws HyracksDataException {
         if (dataverseEntity.databaseNameIndex() >= 0) {
-            fieldValue.reset();
-            aString.setValue(MetadataRecordTypes.FIELD_NAME_OWNER_NAME);
+            RecordBuilder creatorObject = new RecordBuilder();
+            creatorObject.reset(DefaultOpenFieldType.NESTED_OPEN_RECORD_TYPE);
+            Creator creatorInfo = dataverse.getCreator();
+
+            fieldName.reset();
+            aString.setValue(MetadataRecordTypes.FIELD_NAME_CREATOR_NAME);
             stringSerde.serialize(aString, fieldName.getDataOutput());
             fieldValue.reset();
-            aString.setValue(dataverse.getOwnerName());
+            aString.setValue(creatorInfo.getName());
             stringSerde.serialize(aString, fieldValue.getDataOutput());
+            creatorObject.addField(fieldName, fieldValue);
+
+            fieldName.reset();
+            aString.setValue(MetadataRecordTypes.FIELD_NAME_CREATOR_UUID);
+            stringSerde.serialize(aString, fieldName.getDataOutput());
+            fieldValue.reset();
+            aString.setValue(creatorInfo.getUuid());
+            stringSerde.serialize(aString, fieldValue.getDataOutput());
+            creatorObject.addField(fieldName, fieldValue);
+
+            fieldName.reset();
+            aString.setValue(MetadataRecordTypes.CREATOR_ARECORD_FIELD_NAME);
+            stringSerde.serialize(aString, fieldName.getDataOutput());
+            fieldValue.reset();
+            creatorObject.write(fieldValue.getDataOutput(), true);
             recordBuilder.addField(fieldName, fieldValue);
         }
     }
diff --git a/asterixdb/asterix-metadata/src/main/java/org/apache/asterix/metadata/utils/Creator.java b/asterixdb/asterix-metadata/src/main/java/org/apache/asterix/metadata/utils/Creator.java
new file mode 100644
index 0000000..3cf6567
--- /dev/null
+++ b/asterixdb/asterix-metadata/src/main/java/org/apache/asterix/metadata/utils/Creator.java
@@ -0,0 +1,76 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.asterix.metadata.utils;
+
+import java.io.Serializable;
+
+import org.apache.asterix.common.metadata.MetadataConstants;
+import org.apache.asterix.metadata.bootstrap.MetadataRecordTypes;
+import org.apache.asterix.om.base.ARecord;
+import org.apache.asterix.om.base.AString;
+import org.apache.asterix.om.types.ARecordType;
+
+public class Creator implements Serializable {
+    private static final long serialVersionUID = 1L;
+
+    public static final Creator DEFAULT_CREATOR =
+            new Creator(MetadataConstants.DEFAULT_CREATOR, MetadataConstants.DEFAULT_CREATOR_UUID);
+    private final String name;
+    private final String uuid;
+
+    private Creator(String name, String uuid) {
+        this.name = name;
+        this.uuid = uuid;
+    }
+
+    public static Creator create(String name, String uuid) {
+        return new Creator(name, uuid);
+    }
+
+    public String getName() {
+        return name;
+    }
+
+    public String getUuid() {
+        return uuid;
+    }
+
+    public static Creator createOrDefault(ARecord record) {
+        ARecordType recType = record.getType();
+        int creatorIndex = recType.getFieldIndex(MetadataRecordTypes.CREATOR_ARECORD_FIELD_NAME);
+        String name = null, uuid = null;
+
+        if (creatorIndex >= 0) {
+            ARecordType creatorType = (ARecordType) recType.getFieldTypes()[creatorIndex];
+            ARecord creatorRecord = (ARecord) record.getValueByPos(creatorIndex);
+            int nameIndex = creatorType.getFieldIndex(MetadataRecordTypes.FIELD_NAME_CREATOR_NAME);
+            int uuidIndex = creatorType.getFieldIndex(MetadataRecordTypes.FIELD_NAME_CREATOR_UUID);
+
+            if (nameIndex >= 0) {
+                name = ((AString) creatorRecord.getValueByPos(nameIndex)).getStringValue();
+            }
+            if (uuidIndex >= 0) {
+                uuid = ((AString) creatorRecord.getValueByPos(uuidIndex)).getStringValue();
+            }
+            return create(name, uuid);
+        }
+        return DEFAULT_CREATOR;
+    }
+
+}