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

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


The following commit(s) were added to refs/heads/master by this push:
     new 77a2dd7232d Support distinguish of DB model && Fixed the table 
detection bug when indexOutOfRange && Fixed the bug that conflict databases may 
be saved in cache
77a2dd7232d is described below

commit 77a2dd7232d9193c78b9be31eeff702315ce346b
Author: Caideyipi <[email protected]>
AuthorDate: Fri Oct 25 12:21:29 2024 +0800

    Support distinguish of DB model && Fixed the table detection bug when 
indexOutOfRange && Fixed the bug that conflict databases may be saved in cache
---
 .../org/apache/iotdb/db/it/IoTDBSimpleQueryIT.java |  20 +--
 .../relational/it/schema/IoTDBDatabaseIT.java      |  22 +++
 .../java/org/apache/iotdb/rpc/TSStatusCode.java    |   1 +
 .../iotdb/confignode/manager/ConfigManager.java    |  40 ++---
 .../receiver/protocol/IoTDBConfigNodeReceiver.java |   2 +-
 .../manager/schema/ClusterSchemaManager.java       |  15 +-
 .../persistence/partition/PartitionInfo.java       |  18 +-
 .../persistence/schema/ClusterSchemaInfo.java      |  29 ++--
 .../confignode/persistence/schema/ConfigMTree.java |  90 +++++-----
 .../persistence/schema/mnode/IConfigMNode.java     |   1 +
 .../schema/mnode/impl/ConfigDatabaseMNode.java     |   5 +-
 .../schema/mnode/impl/ConfigTableNode.java         |   4 +-
 .../impl/schema/SetTemplateProcedure.java          | 148 +++++++++--------
 .../persistence/schema/ConfigMTreeTest.java        |  38 +++--
 .../metadata/DatabaseConflictException.java        |   2 +-
 ...tException.java => DatabaseModelException.java} |  31 +---
 .../iotdb/db/protocol/client/ConfigNodeClient.java |   2 +-
 .../common/header/ColumnHeaderConstant.java        |  12 +-
 .../common/header/DatasetHeaderFactory.java        |   6 +-
 .../plan/analyze/ClusterPartitionFetcher.java      | 185 +++++++++++----------
 .../analyze/cache/partition/PartitionCache.java    | 144 +++++++++-------
 .../execution/config/TableConfigTaskVisitor.java   |   3 +-
 .../config/executor/ClusterConfigTaskExecutor.java |  42 +++--
 .../config/metadata/DatabaseSchemaTask.java        |   5 +-
 .../config/metadata/ShowDatabaseTask.java          |   4 +-
 .../config/metadata/relational/ShowDBTask.java     |  60 ++++++-
 .../fetcher/TableHeaderSchemaValidator.java        |  10 +-
 .../plan/relational/sql/ast/ShowDB.java            |  16 +-
 .../plan/relational/sql/parser/AstBuilder.java     |   5 +-
 .../statement/metadata/ShowDatabaseStatement.java  |  23 ++-
 .../db/schemaengine/table/DataNodeTableCache.java  |   2 +
 .../metrics/IoTDBInternalLocalReporter.java        |   7 +-
 .../plan/analyze/cache/PartitionCacheTest.java     |   8 +-
 .../db/relational/grammar/sql/RelationalSql.g4     |   2 +-
 .../src/main/thrift/confignode.thrift              |   2 +
 35 files changed, 576 insertions(+), 428 deletions(-)

diff --git 
a/integration-test/src/test/java/org/apache/iotdb/db/it/IoTDBSimpleQueryIT.java 
b/integration-test/src/test/java/org/apache/iotdb/db/it/IoTDBSimpleQueryIT.java
index 19b48719383..e7bf18b4fd8 100644
--- 
a/integration-test/src/test/java/org/apache/iotdb/db/it/IoTDBSimpleQueryIT.java
+++ 
b/integration-test/src/test/java/org/apache/iotdb/db/it/IoTDBSimpleQueryIT.java
@@ -1041,25 +1041,23 @@ public class IoTDBSimpleQueryIT {
 
   @Test
   public void testStorageGroupWithHyphenInName() {
-    try (Connection connection = EnvFactory.getEnv().getConnection();
-        Statement statement = connection.createStatement()) {
+    try (final Connection connection = EnvFactory.getEnv().getConnection();
+        final Statement statement = connection.createStatement()) {
       statement.setFetchSize(5);
       statement.execute("CREATE DATABASE root.group_with_hyphen");
-    } catch (SQLException e) {
+    } catch (final SQLException e) {
       fail();
     }
 
-    try (Connection connection = EnvFactory.getEnv().getConnection();
-        Statement statement = connection.createStatement()) {
-      try (ResultSet resultSet = statement.executeQuery("SHOW DATABASES")) {
-        ResultSetMetaData resultSetMetaData = resultSet.getMetaData();
+    try (final Connection connection = EnvFactory.getEnv().getConnection();
+        final Statement statement = connection.createStatement()) {
+      try (final ResultSet resultSet = statement.executeQuery("SHOW DATABASES 
DETAILS")) {
         while (resultSet.next()) {
-          StringBuilder builder = new StringBuilder();
-          builder.append(resultSet.getString(1));
-          Assert.assertEquals(builder.toString(), "root.group_with_hyphen");
+          Assert.assertEquals("root.group_with_hyphen", 
resultSet.getString(1));
+          Assert.assertEquals("TREE", resultSet.getString(12));
         }
       }
-    } catch (SQLException e) {
+    } catch (final SQLException e) {
       fail();
     }
   }
diff --git 
a/integration-test/src/test/java/org/apache/iotdb/relational/it/schema/IoTDBDatabaseIT.java
 
b/integration-test/src/test/java/org/apache/iotdb/relational/it/schema/IoTDBDatabaseIT.java
index d1552826872..1c8683f6c32 100644
--- 
a/integration-test/src/test/java/org/apache/iotdb/relational/it/schema/IoTDBDatabaseIT.java
+++ 
b/integration-test/src/test/java/org/apache/iotdb/relational/it/schema/IoTDBDatabaseIT.java
@@ -40,6 +40,7 @@ import java.sql.Statement;
 import java.util.Collections;
 
 import static 
org.apache.iotdb.db.queryengine.common.header.ColumnHeaderConstant.showDBColumnHeaders;
+import static 
org.apache.iotdb.db.queryengine.common.header.ColumnHeaderConstant.showDBDetailsColumnHeaders;
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertFalse;
 import static org.junit.Assert.assertTrue;
@@ -83,6 +84,7 @@ public class IoTDBDatabaseIT {
       int[] schemaReplicaFactors = new int[] {1};
       int[] dataReplicaFactors = new int[] {1};
       int[] timePartitionInterval = new int[] {604800000};
+      String[] model = new String[] {"TABLE"};
 
       // show
       try (final ResultSet resultSet = statement.executeQuery("SHOW 
DATABASES")) {
@@ -102,6 +104,26 @@ public class IoTDBDatabaseIT {
         assertEquals(databaseNames.length, cnt);
       }
 
+      // show
+      try (final ResultSet resultSet = statement.executeQuery("SHOW DATABASES 
DETAILS")) {
+        int cnt = 0;
+        final ResultSetMetaData metaData = resultSet.getMetaData();
+        assertEquals(showDBDetailsColumnHeaders.size(), 
metaData.getColumnCount());
+        for (int i = 0; i < showDBDetailsColumnHeaders.size(); i++) {
+          assertEquals(
+              showDBDetailsColumnHeaders.get(i).getColumnName(), 
metaData.getColumnName(i + 1));
+        }
+        while (resultSet.next()) {
+          assertEquals(databaseNames[cnt], resultSet.getString(1));
+          assertEquals(schemaReplicaFactors[cnt], resultSet.getInt(2));
+          assertEquals(dataReplicaFactors[cnt], resultSet.getInt(3));
+          assertEquals(timePartitionInterval[cnt], resultSet.getLong(4));
+          assertEquals(model[cnt], resultSet.getString(5));
+          cnt++;
+        }
+        assertEquals(databaseNames.length, cnt);
+      }
+
       // use
       statement.execute("use test");
 
diff --git 
a/iotdb-client/service-rpc/src/main/java/org/apache/iotdb/rpc/TSStatusCode.java 
b/iotdb-client/service-rpc/src/main/java/org/apache/iotdb/rpc/TSStatusCode.java
index 70175e3ec35..bdd93f9844b 100644
--- 
a/iotdb-client/service-rpc/src/main/java/org/apache/iotdb/rpc/TSStatusCode.java
+++ 
b/iotdb-client/service-rpc/src/main/java/org/apache/iotdb/rpc/TSStatusCode.java
@@ -86,6 +86,7 @@ public enum TSStatusCode {
   MEASUREMENT_ALREADY_EXISTS_IN_TEMPLATE(527),
   TYPE_NOT_FOUND(528),
   DATABASE_CONFLICT(529),
+  DATABASE_MODEL(530),
 
   TABLE_NOT_EXISTS(550),
   TABLE_ALREADY_EXISTS(551),
diff --git 
a/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/manager/ConfigManager.java
 
b/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/manager/ConfigManager.java
index 93e05ed0992..356cd20ed6e 100644
--- 
a/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/manager/ConfigManager.java
+++ 
b/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/manager/ConfigManager.java
@@ -726,8 +726,8 @@ public class ConfigManager implements IManager {
   }
 
   @Override
-  public TSStatus alterDatabase(DatabaseSchemaPlan databaseSchemaPlan) {
-    TSStatus status = confirmLeader();
+  public TSStatus alterDatabase(final DatabaseSchemaPlan databaseSchemaPlan) {
+    final TSStatus status = confirmLeader();
     if (status.getCode() == TSStatusCode.SUCCESS_STATUS.getStatusCode()) {
       return clusterSchemaManager.alterDatabase(databaseSchemaPlan, false);
     } else {
@@ -736,19 +736,19 @@ public class ConfigManager implements IManager {
   }
 
   @Override
-  public synchronized TSStatus deleteDatabases(TDeleteDatabasesReq tDeleteReq) 
{
-    TSStatus status = confirmLeader();
+  public synchronized TSStatus deleteDatabases(final TDeleteDatabasesReq 
tDeleteReq) {
+    final TSStatus status = confirmLeader();
     if (status.getCode() == TSStatusCode.SUCCESS_STATUS.getStatusCode()) {
-      List<String> deletedPaths = tDeleteReq.getPrefixPathList();
+      final List<String> deletedPaths = tDeleteReq.getPrefixPathList();
       // remove wild
-      Map<String, TDatabaseSchema> deleteDatabaseSchemaMap =
+      final Map<String, TDatabaseSchema> deleteDatabaseSchemaMap =
           
getClusterSchemaManager().getMatchedDatabaseSchemasByName(deletedPaths);
       if (deleteDatabaseSchemaMap.isEmpty()) {
         return RpcUtils.getStatus(
             TSStatusCode.PATH_NOT_EXIST.getStatusCode(),
             String.format("Path %s does not exist", 
Arrays.toString(deletedPaths.toArray())));
       }
-      ArrayList<TDatabaseSchema> parsedDeleteDatabases =
+      final ArrayList<TDatabaseSchema> parsedDeleteDatabases =
           new ArrayList<>(deleteDatabaseSchemaMap.values());
       return procedureManager.deleteDatabases(
           parsedDeleteDatabases,
@@ -1834,14 +1834,15 @@ public class ConfigManager implements IManager {
   }
 
   @Override
-  public TShowDatabaseResp showDatabase(TGetDatabaseReq req) {
-    TSStatus status = confirmLeader();
+  public TShowDatabaseResp showDatabase(final TGetDatabaseReq req) {
+    final TSStatus status = confirmLeader();
     if (status.getCode() == TSStatusCode.SUCCESS_STATUS.getStatusCode()) {
-      PathPatternTree scope =
+      final PathPatternTree scope =
           req.getScopePatternTree() == null
               ? SchemaConstant.ALL_MATCH_SCOPE
               : 
PathPatternTree.deserialize(ByteBuffer.wrap(req.getScopePatternTree()));
-      GetDatabasePlan getDatabasePlan = new 
GetDatabasePlan(req.getDatabasePathPattern(), scope);
+      final GetDatabasePlan getDatabasePlan =
+          new GetDatabasePlan(req.getDatabasePathPattern(), scope);
       return getClusterSchemaManager().showDatabase(getDatabasePlan);
     } else {
       return new TShowDatabaseResp().setStatus(status);
@@ -1943,17 +1944,18 @@ public class ConfigManager implements IManager {
   }
 
   @Override
-  public TSStatus deactivateSchemaTemplate(TDeactivateSchemaTemplateReq req) {
-    TSStatus status = confirmLeader();
+  public TSStatus deactivateSchemaTemplate(final TDeactivateSchemaTemplateReq 
req) {
+    final TSStatus status = confirmLeader();
     if (status.getCode() != TSStatusCode.SUCCESS_STATUS.getStatusCode()) {
       return status;
     }
 
-    PathPatternTree patternTree =
+    final PathPatternTree patternTree =
         PathPatternTree.deserialize(ByteBuffer.wrap(req.getPathPatternTree()));
 
-    List<PartialPath> patternList = patternTree.getAllPathPatterns();
-    TemplateSetInfoResp templateSetInfoResp = 
clusterSchemaManager.getTemplateSetInfo(patternList);
+    final List<PartialPath> patternList = patternTree.getAllPathPatterns();
+    final TemplateSetInfoResp templateSetInfoResp =
+        clusterSchemaManager.getTemplateSetInfo(patternList);
     if (templateSetInfoResp.getStatus().getCode() != 
TSStatusCode.SUCCESS_STATUS.getStatusCode()) {
       return templateSetInfoResp.getStatus();
     }
@@ -1968,9 +1970,9 @@ public class ConfigManager implements IManager {
     }
 
     if (!req.getTemplateName().equals(ONE_LEVEL_PATH_WILDCARD)) {
-      Map<PartialPath, List<Template>> filteredTemplateSetInfo = new 
HashMap<>();
-      for (Map.Entry<PartialPath, List<Template>> entry : 
templateSetInfo.entrySet()) {
-        for (Template template : entry.getValue()) {
+      final Map<PartialPath, List<Template>> filteredTemplateSetInfo = new 
HashMap<>();
+      for (final Map.Entry<PartialPath, List<Template>> entry : 
templateSetInfo.entrySet()) {
+        for (final Template template : entry.getValue()) {
           if (template.getName().equals(req.getTemplateName())) {
             filteredTemplateSetInfo.put(entry.getKey(), 
Collections.singletonList(template));
             break;
diff --git 
a/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/manager/pipe/receiver/protocol/IoTDBConfigNodeReceiver.java
 
b/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/manager/pipe/receiver/protocol/IoTDBConfigNodeReceiver.java
index 43f17bcfb6d..67167500033 100644
--- 
a/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/manager/pipe/receiver/protocol/IoTDBConfigNodeReceiver.java
+++ 
b/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/manager/pipe/receiver/protocol/IoTDBConfigNodeReceiver.java
@@ -222,7 +222,7 @@ public class IoTDBConfigNodeReceiver extends 
IoTDBFileReceiver {
       case CreateDatabase:
         // Here we only reserve database name and substitute the sender's 
local information
         // with the receiver's default configurations
-        TDatabaseSchema schema = ((DatabaseSchemaPlan) plan).getSchema();
+        final TDatabaseSchema schema = ((DatabaseSchemaPlan) plan).getSchema();
         schema.setSchemaReplicationFactor(
             
ConfigNodeDescriptor.getInstance().getConf().getSchemaReplicationFactor());
         schema.setDataReplicationFactor(
diff --git 
a/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/manager/schema/ClusterSchemaManager.java
 
b/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/manager/schema/ClusterSchemaManager.java
index c306d8fe1ef..c319f7eb9aa 100644
--- 
a/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/manager/schema/ClusterSchemaManager.java
+++ 
b/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/manager/schema/ClusterSchemaManager.java
@@ -336,11 +336,11 @@ public class ClusterSchemaManager {
   }
 
   /** Only used in cluster tool show Databases. */
-  public TShowDatabaseResp showDatabase(GetDatabasePlan getDatabasePlan) {
+  public TShowDatabaseResp showDatabase(final GetDatabasePlan getDatabasePlan) 
{
     DatabaseSchemaResp databaseSchemaResp;
     try {
       databaseSchemaResp = (DatabaseSchemaResp) 
getConsensusManager().read(getDatabasePlan);
-    } catch (ConsensusException e) {
+    } catch (final ConsensusException e) {
       LOGGER.warn(CONSENSUS_READ_ERROR, e);
       TSStatus res = new 
TSStatus(TSStatusCode.EXECUTE_STATEMENT_ERROR.getStatusCode());
       res.setMessage(e.getMessage());
@@ -352,10 +352,10 @@ public class ClusterSchemaManager {
       return new TShowDatabaseResp().setStatus(databaseSchemaResp.getStatus());
     }
 
-    Map<String, TDatabaseInfo> infoMap = new ConcurrentHashMap<>();
-    for (TDatabaseSchema databaseSchema : 
databaseSchemaResp.getSchemaMap().values()) {
-      String database = databaseSchema.getName();
-      TDatabaseInfo databaseInfo = new TDatabaseInfo();
+    final Map<String, TDatabaseInfo> infoMap = new ConcurrentHashMap<>();
+    for (final TDatabaseSchema databaseSchema : 
databaseSchemaResp.getSchemaMap().values()) {
+      final String database = databaseSchema.getName();
+      final TDatabaseInfo databaseInfo = new TDatabaseInfo();
       databaseInfo.setName(database);
       
databaseInfo.setSchemaReplicationFactor(databaseSchema.getSchemaReplicationFactor());
       
databaseInfo.setDataReplicationFactor(databaseSchema.getDataReplicationFactor());
@@ -369,13 +369,14 @@ public class ClusterSchemaManager {
           getMinRegionGroupNum(database, TConsensusGroupType.DataRegion));
       databaseInfo.setMaxDataRegionNum(
           getMaxRegionGroupNum(database, TConsensusGroupType.DataRegion));
+      databaseInfo.setIsTableModel(databaseSchema.isIsTableModel());
 
       try {
         databaseInfo.setSchemaRegionNum(
             getPartitionManager().getRegionGroupCount(database, 
TConsensusGroupType.SchemaRegion));
         databaseInfo.setDataRegionNum(
             getPartitionManager().getRegionGroupCount(database, 
TConsensusGroupType.DataRegion));
-      } catch (DatabaseNotExistsException e) {
+      } catch (final DatabaseNotExistsException e) {
         // Skip pre-deleted Database
         LOGGER.warn(
             "The Database: {} doesn't exist. Maybe it has been pre-deleted.",
diff --git 
a/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/persistence/partition/PartitionInfo.java
 
b/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/persistence/partition/PartitionInfo.java
index fe48dd50797..a6ee20ea4d7 100644
--- 
a/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/persistence/partition/PartitionInfo.java
+++ 
b/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/persistence/partition/PartitionInfo.java
@@ -991,9 +991,9 @@ public class PartitionInfo implements SnapshotProcessor {
     }
   }
 
-  public void processLoadSnapshot(File snapshotDir) throws TException, 
IOException {
+  public void processLoadSnapshot(final File snapshotDir) throws TException, 
IOException {
 
-    File snapshotFile = new File(snapshotDir, SNAPSHOT_FILENAME);
+    final File snapshotFile = new File(snapshotDir, SNAPSHOT_FILENAME);
     if (!snapshotFile.exists() || !snapshotFile.isFile()) {
       LOGGER.error(
           "Failed to load snapshot,snapshot file [{}] is not exist.",
@@ -1001,11 +1001,11 @@ public class PartitionInfo implements SnapshotProcessor 
{
       return;
     }
 
-    try (BufferedInputStream fileInputStream =
+    try (final BufferedInputStream fileInputStream =
             new BufferedInputStream(
                 Files.newInputStream(snapshotFile.toPath()), 
PARTITION_TABLE_BUFFER_SIZE);
-        TIOStreamTransport tioStreamTransport = new 
TIOStreamTransport(fileInputStream)) {
-      TProtocol protocol = new TBinaryProtocol(tioStreamTransport);
+        final TIOStreamTransport tioStreamTransport = new 
TIOStreamTransport(fileInputStream)) {
+      final TProtocol protocol = new TBinaryProtocol(tioStreamTransport);
       // before restoring a snapshot, clear all old data
       clear();
 
@@ -1015,11 +1015,12 @@ public class PartitionInfo implements SnapshotProcessor 
{
       // restore StorageGroupPartitionTable
       int length = ReadWriteIOUtils.readInt(fileInputStream);
       for (int i = 0; i < length; i++) {
-        String storageGroup = ReadWriteIOUtils.readString(fileInputStream);
+        final String storageGroup = 
ReadWriteIOUtils.readString(fileInputStream);
         if (storageGroup == null) {
           throw new IOException("Failed to load snapshot because get null 
StorageGroup name");
         }
-        DatabasePartitionTable databasePartitionTable = new 
DatabasePartitionTable(storageGroup);
+        final DatabasePartitionTable databasePartitionTable =
+            new DatabasePartitionTable(storageGroup);
         databasePartitionTable.deserialize(fileInputStream, protocol);
         databasePartitionTables.put(storageGroup, databasePartitionTable);
       }
@@ -1027,7 +1028,8 @@ public class PartitionInfo implements SnapshotProcessor {
       // restore deletedRegionSet
       length = ReadWriteIOUtils.readInt(fileInputStream);
       for (int i = 0; i < length; i++) {
-        RegionMaintainTask task = 
RegionMaintainTask.Factory.create(fileInputStream, protocol);
+        final RegionMaintainTask task =
+            RegionMaintainTask.Factory.create(fileInputStream, protocol);
         regionMaintainTaskList.add(task);
       }
     }
diff --git 
a/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/persistence/schema/ClusterSchemaInfo.java
 
b/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/persistence/schema/ClusterSchemaInfo.java
index 22991eedb2b..ebd754b9b09 100644
--- 
a/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/persistence/schema/ClusterSchemaInfo.java
+++ 
b/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/persistence/schema/ClusterSchemaInfo.java
@@ -154,7 +154,7 @@ public class ClusterSchemaInfo implements SnapshotProcessor 
{
   /**
    * Cache DatabaseSchema.
    *
-   * @param plan DatabaseSchemaPlan
+   * @param plan {@link DatabaseSchemaPlan}
    * @return {@link TSStatusCode#SUCCESS_STATUS} if the Database is set 
successfully.
    */
   public TSStatus createDatabase(final DatabaseSchemaPlan plan) {
@@ -195,7 +195,7 @@ public class ClusterSchemaInfo implements SnapshotProcessor 
{
       final TDatabaseSchema alterSchema = plan.getSchema();
       final PartialPath partialPathName = new 
PartialPath(alterSchema.getName());
 
-      TDatabaseSchema currentSchema =
+      final TDatabaseSchema currentSchema =
           
mTree.getDatabaseNodeByDatabasePath(partialPathName).getAsMNode().getDatabaseSchema();
       // TODO: Support alter other fields
       if (alterSchema.isSetMinSchemaRegionGroupNum()) {
@@ -234,7 +234,7 @@ public class ClusterSchemaInfo implements SnapshotProcessor 
{
           .getAsMNode()
           .setDatabaseSchema(currentSchema);
       result.setCode(TSStatusCode.SUCCESS_STATUS.getStatusCode());
-    } catch (MetadataException e) {
+    } catch (final MetadataException e) {
       LOGGER.error(ERROR_NAME, e);
       result.setCode(e.getErrorCode()).setMessage(e.getMessage());
     } finally {
@@ -455,7 +455,7 @@ public class ClusterSchemaInfo implements SnapshotProcessor 
{
   public List<String> getDatabaseNames() {
     databaseReadWriteLock.readLock().lock();
     try {
-      return mTree.getAllDatabasePaths().stream()
+      return mTree.getAllDatabasePaths(false).stream()
           .map(PartialPath::getFullPath)
           .collect(Collectors.toList());
     } finally {
@@ -759,12 +759,12 @@ public class ClusterSchemaInfo implements 
SnapshotProcessor {
   }
 
   public synchronized TemplateInfoResp checkTemplateSettable(
-      CheckTemplateSettablePlan checkTemplateSettablePlan) {
-    TemplateInfoResp resp = new TemplateInfoResp();
-    PartialPath path;
+      final CheckTemplateSettablePlan checkTemplateSettablePlan) {
+    final TemplateInfoResp resp = new TemplateInfoResp();
+    final PartialPath path;
     try {
       path = new PartialPath(checkTemplateSettablePlan.getPath());
-    } catch (IllegalPathException e) {
+    } catch (final IllegalPathException e) {
       LOGGER.error(e.getMessage());
       resp.setStatus(RpcUtils.getStatus(e.getErrorCode(), e.getMessage()));
       return resp;
@@ -776,7 +776,7 @@ public class ClusterSchemaInfo implements SnapshotProcessor 
{
       resp.setTemplateList(
           Collections.singletonList(
               templateTable.getTemplate(checkTemplateSettablePlan.getName())));
-    } catch (MetadataException e) {
+    } catch (final MetadataException e) {
       LOGGER.error(e.getMessage(), e);
       resp.setStatus(RpcUtils.getStatus(e.getErrorCode(), e.getMessage()));
     }
@@ -933,13 +933,12 @@ public class ClusterSchemaInfo implements 
SnapshotProcessor {
    * into specified path pattern start with template set path. The result set 
is organized as
    * specified path pattern -> template id
    */
-  public TemplateSetInfoResp getTemplateSetInfo(GetTemplateSetInfoPlan plan) {
-    TemplateSetInfoResp resp = new TemplateSetInfoResp();
+  public TemplateSetInfoResp getTemplateSetInfo(final GetTemplateSetInfoPlan 
plan) {
+    final TemplateSetInfoResp resp = new TemplateSetInfoResp();
     try {
-
-      Map<PartialPath, Set<Integer>> allTemplateSetInfo = new HashMap<>();
-      for (PartialPath pattern : plan.getPatternList()) {
-        Map<Integer, Set<PartialPath>> templateSetInfo = 
mTree.getTemplateSetInfo(pattern);
+      final Map<PartialPath, Set<Integer>> allTemplateSetInfo = new 
HashMap<>();
+      for (final PartialPath pattern : plan.getPatternList()) {
+        final Map<Integer, Set<PartialPath>> templateSetInfo = 
mTree.getTemplateSetInfo(pattern);
         if (templateSetInfo.isEmpty()) {
           continue;
         }
diff --git 
a/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/persistence/schema/ConfigMTree.java
 
b/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/persistence/schema/ConfigMTree.java
index df93713239a..f761f5f1aa1 100644
--- 
a/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/persistence/schema/ConfigMTree.java
+++ 
b/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/persistence/schema/ConfigMTree.java
@@ -36,6 +36,7 @@ import 
org.apache.iotdb.confignode.persistence.schema.mnode.factory.ConfigMNodeF
 import 
org.apache.iotdb.confignode.persistence.schema.mnode.impl.ConfigTableNode;
 import org.apache.iotdb.db.exception.metadata.DatabaseAlreadySetException;
 import org.apache.iotdb.db.exception.metadata.DatabaseConflictException;
+import org.apache.iotdb.db.exception.metadata.DatabaseModelException;
 import org.apache.iotdb.db.exception.metadata.DatabaseNotSetException;
 import org.apache.iotdb.db.exception.metadata.PathAlreadyExistException;
 import org.apache.iotdb.db.exception.metadata.PathNotExistException;
@@ -227,13 +228,16 @@ public class ConfigMTree {
    *
    * @return a list contains all distinct databases
    */
-  public List<PartialPath> getAllDatabasePaths() {
-    List<PartialPath> res = new ArrayList<>();
-    Deque<IConfigMNode> nodeStack = new ArrayDeque<>();
+  public List<PartialPath> getAllDatabasePaths(final boolean onlyTableModel) {
+    final List<PartialPath> res = new ArrayList<>();
+    final Deque<IConfigMNode> nodeStack = new ArrayDeque<>();
     nodeStack.add(root);
     while (!nodeStack.isEmpty()) {
-      IConfigMNode current = nodeStack.pop();
+      final IConfigMNode current = nodeStack.pop();
       if (current.isDatabase()) {
+        if (onlyTableModel && !current.getDatabaseSchema().isIsTableModel()) {
+          continue;
+        }
         res.add(current.getPartialPath());
       } else {
         nodeStack.addAll(current.getChildren().values());
@@ -457,7 +461,7 @@ public class ConfigMTree {
    * check whether there is template on given path and the subTree has 
template return true,
    * otherwise false
    */
-  public void checkTemplateOnPath(PartialPath path) throws MetadataException {
+  public void checkTemplateOnPath(final PartialPath path) throws 
MetadataException {
     String[] nodeNames = path.getNodes();
     IConfigMNode cur = root;
     IConfigMNode child;
@@ -475,25 +479,23 @@ public class ConfigMTree {
       if (cur.getSchemaTemplateId() != NON_TEMPLATE) {
         throw new MetadataException("Template already exists on " + 
cur.getFullPath());
       }
-      if (cur.isMeasurement()) {
-        return;
+      if (cur.isDatabase() && cur.getDatabaseSchema().isIsTableModel()) {
+        throw new DatabaseModelException(cur.getFullPath(), true);
       }
     }
 
     checkTemplateOnSubtree(cur);
   }
 
-  // traverse  all the  descendant of the given path node
-  private void checkTemplateOnSubtree(IConfigMNode node) throws 
MetadataException {
-    if (node.isMeasurement()) {
-      return;
-    }
+  // traverse all the descendant of the given path node
+  private void checkTemplateOnSubtree(final IConfigMNode node) throws 
MetadataException {
     IConfigMNode child;
     IMNodeIterator<IConfigMNode> iterator = store.getChildrenIterator(node);
     while (iterator.hasNext()) {
       child = iterator.next();
 
-      if (child.isMeasurement()) {
+      // Skip table model databases
+      if (child.isDatabase() && child.getDatabaseSchema().isIsTableModel()) {
         continue;
       }
       if (child.getSchemaTemplateId() != NON_TEMPLATE) {
@@ -504,13 +506,14 @@ public class ConfigMTree {
   }
 
   public List<String> getPathsSetOnTemplate(
-      int templateId, PathPatternTree scope, boolean filterPreUnset) throws 
MetadataException {
-    List<String> resSet = new ArrayList<>();
-    try (MNodeCollector<Void, IConfigMNode> collector =
+      final int templateId, final PathPatternTree scope, final boolean 
filterPreUnset)
+      throws MetadataException {
+    final List<String> resSet = new ArrayList<>();
+    try (final MNodeCollector<Void, IConfigMNode> collector =
         new MNodeCollector<Void, IConfigMNode>(
             root, new PartialPath(ALL_RESULT_NODES), store, false, scope) {
           @Override
-          protected boolean acceptFullMatchedNode(IConfigMNode node) {
+          protected boolean acceptFullMatchedNode(final IConfigMNode node) {
             if (super.acceptFullMatchedNode(node)) {
               // if node not set template, go on traversing
               if (node.getSchemaTemplateId() != NON_TEMPLATE) {
@@ -526,23 +529,25 @@ public class ConfigMTree {
           }
 
           @Override
-          protected Void collectMNode(IConfigMNode node) {
+          protected Void collectMNode(final IConfigMNode node) {
             resSet.add(node.getFullPath());
             return null;
           }
 
           @Override
-          protected boolean shouldVisitSubtreeOfFullMatchedNode(IConfigMNode 
node) {
+          protected boolean shouldVisitSubtreeOfFullMatchedNode(final 
IConfigMNode node) {
             // descendants of the node cannot set another template, exit from 
this branch
-            return (node.getSchemaTemplateId() == NON_TEMPLATE)
+            return node.getSchemaTemplateId() == NON_TEMPLATE
+                && !(node.isDatabase() && 
node.getDatabaseSchema().isIsTableModel())
                 && super.shouldVisitSubtreeOfFullMatchedNode(node);
           }
 
           @Override
-          protected boolean 
shouldVisitSubtreeOfInternalMatchedNode(IConfigMNode node) {
+          protected boolean shouldVisitSubtreeOfInternalMatchedNode(final 
IConfigMNode node) {
             // descendants of the node cannot set another template, exit from 
this branch
-            return (node.getSchemaTemplateId() == NON_TEMPLATE)
-                && super.shouldVisitSubtreeOfFullMatchedNode(node);
+            return node.getSchemaTemplateId() == NON_TEMPLATE
+                && !(node.isDatabase() && 
node.getDatabaseSchema().isIsTableModel())
+                && super.shouldVisitSubtreeOfInternalMatchedNode(node);
           }
         }) {
       collector.traverse();
@@ -551,25 +556,24 @@ public class ConfigMTree {
   }
 
   /** This method returns the templateId set on paths covered by input path 
pattern. */
-  public Map<Integer, Set<PartialPath>> getTemplateSetInfo(PartialPath 
pathPattern)
+  public Map<Integer, Set<PartialPath>> getTemplateSetInfo(final PartialPath 
pathPattern)
       throws MetadataException {
-    Map<Integer, Set<PartialPath>> result = new HashMap<>();
-    try (MNodeCollector<Void, IConfigMNode> collector =
+    final Map<Integer, Set<PartialPath>> result = new HashMap<>();
+    try (final MNodeCollector<Void, IConfigMNode> collector =
         new MNodeCollector<Void, IConfigMNode>(root, pathPattern, store, 
false, ALL_MATCH_SCOPE) {
           @Override
-          protected boolean acceptFullMatchedNode(IConfigMNode node) {
-            return (node.getSchemaTemplateId() != NON_TEMPLATE)
-                || super.acceptFullMatchedNode(node);
+          protected boolean acceptFullMatchedNode(final IConfigMNode node) {
+            return node.getSchemaTemplateId() != NON_TEMPLATE || 
super.acceptFullMatchedNode(node);
           }
 
           @Override
-          protected boolean acceptInternalMatchedNode(IConfigMNode node) {
-            return (node.getSchemaTemplateId() != NON_TEMPLATE)
+          protected boolean acceptInternalMatchedNode(final IConfigMNode node) 
{
+            return node.getSchemaTemplateId() != NON_TEMPLATE
                 || super.acceptInternalMatchedNode(node);
           }
 
           @Override
-          protected Void collectMNode(IConfigMNode node) {
+          protected Void collectMNode(final IConfigMNode node) {
             if (node.getSchemaTemplateId() != NON_TEMPLATE && 
!node.isSchemaTemplatePreUnset()) {
               result
                   .computeIfAbsent(node.getSchemaTemplateId(), k -> new 
HashSet<>())
@@ -579,17 +583,19 @@ public class ConfigMTree {
           }
 
           @Override
-          protected boolean shouldVisitSubtreeOfFullMatchedNode(IConfigMNode 
node) {
+          protected boolean shouldVisitSubtreeOfFullMatchedNode(final 
IConfigMNode node) {
             // descendants of the node cannot set another template, exit from 
this branch
-            return (node.getSchemaTemplateId() == NON_TEMPLATE)
+            return node.getSchemaTemplateId() == NON_TEMPLATE
+                && !(node.isDatabase() && 
node.getDatabaseSchema().isIsTableModel())
                 && super.shouldVisitSubtreeOfFullMatchedNode(node);
           }
 
           @Override
-          protected boolean 
shouldVisitSubtreeOfInternalMatchedNode(IConfigMNode node) {
+          protected boolean shouldVisitSubtreeOfInternalMatchedNode(final 
IConfigMNode node) {
             // descendants of the node cannot set another template, exit from 
this branch
-            return (node.getSchemaTemplateId() == NON_TEMPLATE)
-                && super.shouldVisitSubtreeOfFullMatchedNode(node);
+            return node.getSchemaTemplateId() == NON_TEMPLATE
+                && !(node.isDatabase() && 
node.getDatabaseSchema().isIsTableModel())
+                && super.shouldVisitSubtreeOfInternalMatchedNode(node);
           }
         }) {
       collector.traverse();
@@ -597,7 +603,8 @@ public class ConfigMTree {
     return result;
   }
 
-  public void setTemplate(int templateId, PartialPath templateSetPath) throws 
MetadataException {
+  public void setTemplate(final int templateId, final PartialPath 
templateSetPath)
+      throws MetadataException {
     getNodeWithAutoCreate(templateSetPath).setSchemaTemplateId(templateId);
   }
 
@@ -637,6 +644,9 @@ public class ConfigMTree {
   public void preCreateTable(final PartialPath database, final TsTable table)
       throws MetadataException {
     final IConfigMNode databaseNode = 
getDatabaseNodeByDatabasePath(database).getAsMNode();
+    if (!databaseNode.getDatabaseSchema().isIsTableModel()) {
+      throw new DatabaseModelException(database.getFullPath(), false);
+    }
     final IConfigMNode node = databaseNode.getChild(table.getTableName());
     if (node == null) {
       final ConfigTableNode tableNode =
@@ -735,7 +745,7 @@ public class ConfigMTree {
   }
 
   public Map<String, List<TsTable>> getAllUsingTables() {
-    return getAllDatabasePaths().stream()
+    return getAllDatabasePaths(true).stream()
         .collect(
             Collectors.toMap(
                 PartialPath::getFullPath,
@@ -752,7 +762,7 @@ public class ConfigMTree {
 
   public Map<String, List<TsTable>> getAllPreCreateTables() throws 
MetadataException {
     final Map<String, List<TsTable>> result = new HashMap<>();
-    final List<PartialPath> databaseList = getAllDatabasePaths();
+    final List<PartialPath> databaseList = getAllDatabasePaths(true);
     for (PartialPath databasePath : databaseList) {
       final String database = 
databasePath.getFullPath().substring(ROOT.length() + 1);
       final IConfigMNode databaseNode = 
getDatabaseNodeByDatabasePath(databasePath).getAsMNode();
diff --git 
a/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/persistence/schema/mnode/IConfigMNode.java
 
b/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/persistence/schema/mnode/IConfigMNode.java
index 805c270ec46..dd2b5932b00 100644
--- 
a/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/persistence/schema/mnode/IConfigMNode.java
+++ 
b/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/persistence/schema/mnode/IConfigMNode.java
@@ -16,6 +16,7 @@
  * specific language governing permissions and limitations
  * under the License.
  */
+
 package org.apache.iotdb.confignode.persistence.schema.mnode;
 
 import org.apache.iotdb.commons.schema.node.IMNode;
diff --git 
a/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/persistence/schema/mnode/impl/ConfigDatabaseMNode.java
 
b/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/persistence/schema/mnode/impl/ConfigDatabaseMNode.java
index ea5e8b51b94..67058b68c27 100644
--- 
a/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/persistence/schema/mnode/impl/ConfigDatabaseMNode.java
+++ 
b/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/persistence/schema/mnode/impl/ConfigDatabaseMNode.java
@@ -16,6 +16,7 @@
  * specific language governing permissions and limitations
  * under the License.
  */
+
 package org.apache.iotdb.confignode.persistence.schema.mnode.impl;
 
 import org.apache.iotdb.commons.schema.node.common.AbstractDatabaseMNode;
@@ -28,13 +29,13 @@ public class ConfigDatabaseMNode extends 
AbstractDatabaseMNode<IConfigMNode, Con
     implements IConfigMNode {
   private final ConfigDatabaseInfo configDatabaseInfo;
 
-  public ConfigDatabaseMNode(IConfigMNode parent, String name) {
+  public ConfigDatabaseMNode(final IConfigMNode parent, final String name) {
     super(new ConfigBasicInternalMNode(parent, name), new 
ConfigDatabaseInfo(name));
     this.configDatabaseInfo = (ConfigDatabaseInfo) getDatabaseInfo();
   }
 
   @Override
-  public void setSchemaTemplateId(int id) {
+  public void setSchemaTemplateId(final int id) {
     basicMNode.setSchemaTemplateId(id);
   }
 
diff --git 
a/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/persistence/schema/mnode/impl/ConfigTableNode.java
 
b/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/persistence/schema/mnode/impl/ConfigTableNode.java
index 337f136919c..6e6b6753702 100644
--- 
a/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/persistence/schema/mnode/impl/ConfigTableNode.java
+++ 
b/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/persistence/schema/mnode/impl/ConfigTableNode.java
@@ -34,6 +34,8 @@ import 
org.apache.iotdb.confignode.persistence.schema.mnode.info.ConfigTableInfo
 import java.util.ArrayList;
 import java.util.List;
 
+import static org.apache.iotdb.commons.schema.SchemaConstant.NON_TEMPLATE;
+
 public class ConfigTableNode implements IConfigMNode {
 
   private IConfigMNode parent;
@@ -197,7 +199,7 @@ public class ConfigTableNode implements IConfigMNode {
 
   @Override
   public int getSchemaTemplateId() {
-    throw new UnsupportedOperationException();
+    return NON_TEMPLATE;
   }
 
   @Override
diff --git 
a/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/procedure/impl/schema/SetTemplateProcedure.java
 
b/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/procedure/impl/schema/SetTemplateProcedure.java
index 30f81816484..9180904cade 100644
--- 
a/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/procedure/impl/schema/SetTemplateProcedure.java
+++ 
b/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/procedure/impl/schema/SetTemplateProcedure.java
@@ -83,12 +83,15 @@ public class SetTemplateProcedure
   private static final String CONSENSUS_WRITE_ERROR =
       "Failed in the write API executing the consensus layer due to: ";
 
-  public SetTemplateProcedure(boolean isGeneratedByPipe) {
+  public SetTemplateProcedure(final boolean isGeneratedByPipe) {
     super(isGeneratedByPipe);
   }
 
   public SetTemplateProcedure(
-      String queryId, String templateName, String templateSetPath, boolean 
isGeneratedByPipe) {
+      final String queryId,
+      final String templateName,
+      final String templateSetPath,
+      final boolean isGeneratedByPipe) {
     super(isGeneratedByPipe);
     this.queryId = queryId;
     this.templateName = templateName;
@@ -96,7 +99,7 @@ public class SetTemplateProcedure
   }
 
   @Override
-  protected Flow executeFromState(ConfigNodeProcedureEnv env, SetTemplateState 
state)
+  protected Flow executeFromState(final ConfigNodeProcedureEnv env, final 
SetTemplateState state)
       throws ProcedureSuspendedException, ProcedureYieldException, 
InterruptedException {
     long startTime = System.currentTimeMillis();
     try {
@@ -148,18 +151,18 @@ public class SetTemplateProcedure
     }
   }
 
-  private void validateTemplateExistence(ConfigNodeProcedureEnv env) {
+  private void validateTemplateExistence(final ConfigNodeProcedureEnv env) {
     // check whether the template can be set on given path
-    CheckTemplateSettablePlan checkTemplateSettablePlan =
+    final CheckTemplateSettablePlan checkTemplateSettablePlan =
         new CheckTemplateSettablePlan(templateName, templateSetPath);
     TemplateInfoResp resp;
     try {
       resp =
           (TemplateInfoResp)
               
env.getConfigManager().getConsensusManager().read(checkTemplateSettablePlan);
-    } catch (ConsensusException e) {
+    } catch (final ConsensusException e) {
       LOGGER.warn("Failed in the read API executing the consensus layer due 
to: ", e);
-      TSStatus res = new 
TSStatus(TSStatusCode.EXECUTE_STATEMENT_ERROR.getStatusCode());
+      final TSStatus res = new 
TSStatus(TSStatusCode.EXECUTE_STATEMENT_ERROR.getStatusCode());
       res.setMessage(e.getMessage());
       resp = new TemplateInfoResp();
       resp.setStatus(res);
@@ -173,13 +176,13 @@ public class SetTemplateProcedure
     }
   }
 
-  private void preSetTemplate(ConfigNodeProcedureEnv env) {
-    PreSetSchemaTemplatePlan preSetSchemaTemplatePlan =
+  private void preSetTemplate(final ConfigNodeProcedureEnv env) {
+    final PreSetSchemaTemplatePlan preSetSchemaTemplatePlan =
         new PreSetSchemaTemplatePlan(templateName, templateSetPath);
     TSStatus status;
     try {
       status = 
env.getConfigManager().getConsensusManager().write(preSetSchemaTemplatePlan);
-    } catch (ConsensusException e) {
+    } catch (final ConsensusException e) {
       LOGGER.warn(CONSENSUS_WRITE_ERROR, e);
       status = new 
TSStatus(TSStatusCode.EXECUTE_STATEMENT_ERROR.getStatusCode());
       status.setMessage(e.getMessage());
@@ -196,26 +199,26 @@ public class SetTemplateProcedure
     }
   }
 
-  private void preReleaseTemplate(ConfigNodeProcedureEnv env) {
-    Template template = getTemplate(env);
+  private void preReleaseTemplate(final ConfigNodeProcedureEnv env) {
+    final Template template = getTemplate(env);
     if (template == null) {
       // already setFailure
       return;
     }
 
-    TUpdateTemplateReq req = new TUpdateTemplateReq();
+    final TUpdateTemplateReq req = new TUpdateTemplateReq();
     
req.setType(TemplateInternalRPCUpdateType.ADD_TEMPLATE_PRE_SET_INFO.toByte());
     req.setTemplateInfo(
         TemplateInternalRPCUtil.generateAddTemplateSetInfoBytes(template, 
templateSetPath));
 
-    Map<Integer, TDataNodeLocation> dataNodeLocationMap =
+    final Map<Integer, TDataNodeLocation> dataNodeLocationMap =
         
env.getConfigManager().getNodeManager().getRegisteredDataNodeLocations();
-    DataNodeAsyncRequestContext<TUpdateTemplateReq, TSStatus> clientHandler =
+    final DataNodeAsyncRequestContext<TUpdateTemplateReq, TSStatus> 
clientHandler =
         new DataNodeAsyncRequestContext<>(
             CnToDnAsyncRequestType.UPDATE_TEMPLATE, req, dataNodeLocationMap);
     
CnToDnInternalServiceAsyncRequestManager.getInstance().sendAsyncRequestWithRetry(clientHandler);
-    Map<Integer, TSStatus> statusMap = clientHandler.getResponseMap();
-    for (Map.Entry<Integer, TSStatus> entry : statusMap.entrySet()) {
+    final Map<Integer, TSStatus> statusMap = clientHandler.getResponseMap();
+    for (final Map.Entry<Integer, TSStatus> entry : statusMap.entrySet()) {
       if (entry.getValue().getCode() != 
TSStatusCode.SUCCESS_STATUS.getStatusCode()) {
         LOGGER.warn(
             "Failed to sync template {} pre-set info on path {} to DataNode 
{}",
@@ -229,16 +232,16 @@ public class SetTemplateProcedure
     setNextState(SetTemplateState.VALIDATE_TIMESERIES_EXISTENCE);
   }
 
-  private Template getTemplate(ConfigNodeProcedureEnv env) {
-    GetSchemaTemplatePlan getSchemaTemplatePlan = new 
GetSchemaTemplatePlan(templateName);
+  private Template getTemplate(final ConfigNodeProcedureEnv env) {
+    final GetSchemaTemplatePlan getSchemaTemplatePlan = new 
GetSchemaTemplatePlan(templateName);
     TemplateInfoResp templateResp;
     try {
       templateResp =
           (TemplateInfoResp)
               
env.getConfigManager().getConsensusManager().read(getSchemaTemplatePlan);
-    } catch (ConsensusException e) {
+    } catch (final ConsensusException e) {
       LOGGER.warn("Failed in the read API executing the consensus layer due 
to: ", e);
-      TSStatus res = new 
TSStatus(TSStatusCode.EXECUTE_STATEMENT_ERROR.getStatusCode());
+      final TSStatus res = new 
TSStatus(TSStatusCode.EXECUTE_STATEMENT_ERROR.getStatusCode());
       res.setMessage(e.getMessage());
       templateResp = new TemplateInfoResp();
       templateResp.setStatus(res);
@@ -257,25 +260,25 @@ public class SetTemplateProcedure
     return templateResp.getTemplateList().get(0);
   }
 
-  private void validateTimeSeriesExistence(ConfigNodeProcedureEnv env) {
-    PathPatternTree patternTree = new PathPatternTree();
-    ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
-    DataOutputStream dataOutputStream = new 
DataOutputStream(byteArrayOutputStream);
+  private void validateTimeSeriesExistence(final ConfigNodeProcedureEnv env) {
+    final PathPatternTree patternTree = new PathPatternTree();
+    final ByteArrayOutputStream byteArrayOutputStream = new 
ByteArrayOutputStream();
+    final DataOutputStream dataOutputStream = new 
DataOutputStream(byteArrayOutputStream);
     PartialPath path = null;
     try {
       path = new PartialPath(templateSetPath);
       patternTree.appendPathPattern(path);
       
patternTree.appendPathPattern(path.concatAsMeasurementPath(MULTI_LEVEL_PATH_WILDCARD));
       patternTree.serialize(dataOutputStream);
-    } catch (IllegalPathException | IOException ignored) {
+    } catch (final IllegalPathException | IOException ignored) {
     }
-    ByteBuffer patternTreeBytes = 
ByteBuffer.wrap(byteArrayOutputStream.toByteArray());
+    final ByteBuffer patternTreeBytes = 
ByteBuffer.wrap(byteArrayOutputStream.toByteArray());
 
-    Map<TConsensusGroupId, TRegionReplicaSet> relatedSchemaRegionGroup =
+    final Map<TConsensusGroupId, TRegionReplicaSet> relatedSchemaRegionGroup =
         env.getConfigManager().getRelatedSchemaRegionGroup(patternTree);
 
-    List<TCheckTimeSeriesExistenceResp> respList = new ArrayList<>();
-    DataNodeRegionTaskExecutor<TCheckTimeSeriesExistenceReq, 
TCheckTimeSeriesExistenceResp>
+    final List<TCheckTimeSeriesExistenceResp> respList = new ArrayList<>();
+    final DataNodeRegionTaskExecutor<TCheckTimeSeriesExistenceReq, 
TCheckTimeSeriesExistenceResp>
         regionTask =
             new DataNodeRegionTaskExecutor<
                 TCheckTimeSeriesExistenceReq, TCheckTimeSeriesExistenceResp>(
@@ -288,17 +291,17 @@ public class SetTemplateProcedure
 
               @Override
               protected List<TConsensusGroupId> processResponseOfOneDataNode(
-                  TDataNodeLocation dataNodeLocation,
-                  List<TConsensusGroupId> consensusGroupIdList,
-                  TCheckTimeSeriesExistenceResp response) {
+                  final TDataNodeLocation dataNodeLocation,
+                  final List<TConsensusGroupId> consensusGroupIdList,
+                  final TCheckTimeSeriesExistenceResp response) {
                 respList.add(response);
-                List<TConsensusGroupId> failedRegionList = new ArrayList<>();
+                final List<TConsensusGroupId> failedRegionList = new 
ArrayList<>();
                 if (response.getStatus().getCode() == 
TSStatusCode.SUCCESS_STATUS.getStatusCode()) {
                   return failedRegionList;
                 }
 
                 if (response.getStatus().getCode() == 
TSStatusCode.MULTIPLE_ERROR.getStatusCode()) {
-                  List<TSStatus> subStatus = 
response.getStatus().getSubStatus();
+                  final List<TSStatus> subStatus = 
response.getStatus().getSubStatus();
                   for (int i = 0; i < subStatus.size(); i++) {
                     if (subStatus.get(i).getCode() != 
TSStatusCode.SUCCESS_STATUS.getStatusCode()
                         && subStatus.get(i).getCode()
@@ -314,7 +317,8 @@ public class SetTemplateProcedure
 
               @Override
               protected void onAllReplicasetFailure(
-                  TConsensusGroupId consensusGroupId, Set<TDataNodeLocation> 
dataNodeLocationSet) {
+                  final TConsensusGroupId consensusGroupId,
+                  final Set<TDataNodeLocation> dataNodeLocationSet) {
                 setFailure(
                     new ProcedureException(
                         new MetadataException(
@@ -333,7 +337,7 @@ public class SetTemplateProcedure
       return;
     }
 
-    for (TCheckTimeSeriesExistenceResp resp : respList) {
+    for (final TCheckTimeSeriesExistenceResp resp : respList) {
       if (resp.isExists()) {
         setFailure(new ProcedureException(new 
TemplateIncompatibleException(templateName, path)));
       }
@@ -341,8 +345,8 @@ public class SetTemplateProcedure
     setNextState(SetTemplateState.COMMIT_SET);
   }
 
-  private void commitSetTemplate(ConfigNodeProcedureEnv env) {
-    CommitSetSchemaTemplatePlan commitSetSchemaTemplatePlan =
+  private void commitSetTemplate(final ConfigNodeProcedureEnv env) {
+    final CommitSetSchemaTemplatePlan commitSetSchemaTemplatePlan =
         new CommitSetSchemaTemplatePlan(templateName, templateSetPath);
     TSStatus status;
     try {
@@ -353,7 +357,7 @@ public class SetTemplateProcedure
                   isGeneratedByPipe
                       ? new PipeEnrichedPlan(commitSetSchemaTemplatePlan)
                       : commitSetSchemaTemplatePlan);
-    } catch (ConsensusException e) {
+    } catch (final ConsensusException e) {
       LOGGER.warn(CONSENSUS_WRITE_ERROR, e);
       status = new 
TSStatus(TSStatusCode.EXECUTE_STATEMENT_ERROR.getStatusCode());
       status.setMessage(e.getMessage());
@@ -370,26 +374,26 @@ public class SetTemplateProcedure
     }
   }
 
-  private void commitReleaseTemplate(ConfigNodeProcedureEnv env) {
-    Template template = getTemplate(env);
+  private void commitReleaseTemplate(final ConfigNodeProcedureEnv env) {
+    final Template template = getTemplate(env);
     if (template == null) {
       // already setFailure
       return;
     }
 
-    TUpdateTemplateReq req = new TUpdateTemplateReq();
+    final TUpdateTemplateReq req = new TUpdateTemplateReq();
     
req.setType(TemplateInternalRPCUpdateType.COMMIT_TEMPLATE_SET_INFO.toByte());
     req.setTemplateInfo(
         TemplateInternalRPCUtil.generateAddTemplateSetInfoBytes(template, 
templateSetPath));
 
-    Map<Integer, TDataNodeLocation> dataNodeLocationMap =
+    final Map<Integer, TDataNodeLocation> dataNodeLocationMap =
         
env.getConfigManager().getNodeManager().getRegisteredDataNodeLocations();
-    DataNodeAsyncRequestContext<TUpdateTemplateReq, TSStatus> clientHandler =
+    final DataNodeAsyncRequestContext<TUpdateTemplateReq, TSStatus> 
clientHandler =
         new DataNodeAsyncRequestContext<>(
             CnToDnAsyncRequestType.UPDATE_TEMPLATE, req, dataNodeLocationMap);
     
CnToDnInternalServiceAsyncRequestManager.getInstance().sendAsyncRequestWithRetry(clientHandler);
-    Map<Integer, TSStatus> statusMap = clientHandler.getResponseMap();
-    for (Map.Entry<Integer, TSStatus> entry : statusMap.entrySet()) {
+    final Map<Integer, TSStatus> statusMap = clientHandler.getResponseMap();
+    for (final Map.Entry<Integer, TSStatus> entry : statusMap.entrySet()) {
       if (entry.getValue().getCode() != 
TSStatusCode.SUCCESS_STATUS.getStatusCode()) {
         LOGGER.warn(
             "Failed to sync template {} commit-set info on path {} to DataNode 
{}",
@@ -413,14 +417,14 @@ public class SetTemplateProcedure
   }
 
   @Override
-  protected boolean isRollbackSupported(SetTemplateState setTemplateState) {
+  protected boolean isRollbackSupported(final SetTemplateState 
setTemplateState) {
     return true;
   }
 
   @Override
-  protected void rollbackState(ConfigNodeProcedureEnv env, SetTemplateState 
state)
+  protected void rollbackState(final ConfigNodeProcedureEnv env, final 
SetTemplateState state)
       throws IOException, InterruptedException, ProcedureException {
-    long startTime = System.currentTimeMillis();
+    final long startTime = System.currentTimeMillis();
     try {
       switch (state) {
         case PRE_SET:
@@ -451,13 +455,13 @@ public class SetTemplateProcedure
     }
   }
 
-  private void rollbackPreSet(ConfigNodeProcedureEnv env) {
-    PreSetSchemaTemplatePlan preSetSchemaTemplatePlan =
+  private void rollbackPreSet(final ConfigNodeProcedureEnv env) {
+    final PreSetSchemaTemplatePlan preSetSchemaTemplatePlan =
         new PreSetSchemaTemplatePlan(templateName, templateSetPath, true);
     TSStatus status;
     try {
       status = 
env.getConfigManager().getConsensusManager().write(preSetSchemaTemplatePlan);
-    } catch (ConsensusException e) {
+    } catch (final ConsensusException e) {
       LOGGER.warn(CONSENSUS_WRITE_ERROR, e);
       status = new 
TSStatus(TSStatusCode.EXECUTE_STATEMENT_ERROR.getStatusCode());
       status.setMessage(e.getMessage());
@@ -472,31 +476,31 @@ public class SetTemplateProcedure
     }
   }
 
-  private void rollbackPreRelease(ConfigNodeProcedureEnv env) {
+  private void rollbackPreRelease(final ConfigNodeProcedureEnv env) {
     Template template = getTemplate(env);
     if (template == null) {
       // already setFailure
       return;
     }
 
-    Map<Integer, TDataNodeLocation> dataNodeLocationMap =
+    final Map<Integer, TDataNodeLocation> dataNodeLocationMap =
         
env.getConfigManager().getNodeManager().getRegisteredDataNodeLocations();
 
-    TUpdateTemplateReq invalidateTemplateSetInfoReq = new TUpdateTemplateReq();
+    final TUpdateTemplateReq invalidateTemplateSetInfoReq = new 
TUpdateTemplateReq();
     invalidateTemplateSetInfoReq.setType(
         TemplateInternalRPCUpdateType.INVALIDATE_TEMPLATE_SET_INFO.toByte());
     invalidateTemplateSetInfoReq.setTemplateInfo(
         TemplateInternalRPCUtil.generateInvalidateTemplateSetInfoBytes(
             template.getId(), templateSetPath));
 
-    DataNodeAsyncRequestContext<TUpdateTemplateReq, TSStatus> clientHandler =
+    final DataNodeAsyncRequestContext<TUpdateTemplateReq, TSStatus> 
clientHandler =
         new DataNodeAsyncRequestContext<>(
             CnToDnAsyncRequestType.UPDATE_TEMPLATE,
             invalidateTemplateSetInfoReq,
             dataNodeLocationMap);
     
CnToDnInternalServiceAsyncRequestManager.getInstance().sendAsyncRequestWithRetry(clientHandler);
-    Map<Integer, TSStatus> statusMap = clientHandler.getResponseMap();
-    for (Map.Entry<Integer, TSStatus> entry : statusMap.entrySet()) {
+    final Map<Integer, TSStatus> statusMap = clientHandler.getResponseMap();
+    for (final Map.Entry<Integer, TSStatus> entry : statusMap.entrySet()) {
       // all dataNodes must clear the related template cache
       if (entry.getValue().getCode() != 
TSStatusCode.SUCCESS_STATUS.getStatusCode()) {
         LOGGER.error(
@@ -510,13 +514,13 @@ public class SetTemplateProcedure
     }
   }
 
-  private void rollbackCommitSet(ConfigNodeProcedureEnv env) {
-    CommitSetSchemaTemplatePlan commitSetSchemaTemplatePlan =
+  private void rollbackCommitSet(final ConfigNodeProcedureEnv env) {
+    final CommitSetSchemaTemplatePlan commitSetSchemaTemplatePlan =
         new CommitSetSchemaTemplatePlan(templateName, templateSetPath, true);
     TSStatus status;
     try {
       status = 
env.getConfigManager().getConsensusManager().write(commitSetSchemaTemplatePlan);
-    } catch (ConsensusException e) {
+    } catch (final ConsensusException e) {
       LOGGER.warn(CONSENSUS_WRITE_ERROR, e);
       status = new 
TSStatus(TSStatusCode.EXECUTE_STATEMENT_ERROR.getStatusCode());
       status.setMessage(e.getMessage());
@@ -532,12 +536,12 @@ public class SetTemplateProcedure
   }
 
   @Override
-  protected SetTemplateState getState(int stateId) {
+  protected SetTemplateState getState(final int stateId) {
     return SetTemplateState.values()[stateId];
   }
 
   @Override
-  protected int getStateId(SetTemplateState state) {
+  protected int getStateId(final SetTemplateState state) {
     return state.ordinal();
   }
 
@@ -559,7 +563,7 @@ public class SetTemplateProcedure
   }
 
   @Override
-  public void serialize(DataOutputStream stream) throws IOException {
+  public void serialize(final DataOutputStream stream) throws IOException {
     stream.writeShort(
         isGeneratedByPipe
             ? ProcedureType.PIPE_ENRICHED_SET_TEMPLATE_PROCEDURE.getTypeCode()
@@ -571,7 +575,7 @@ public class SetTemplateProcedure
   }
 
   @Override
-  public void deserialize(ByteBuffer byteBuffer) {
+  public void deserialize(final ByteBuffer byteBuffer) {
     super.deserialize(byteBuffer);
     queryId = ReadWriteIOUtils.readString(byteBuffer);
     templateName = ReadWriteIOUtils.readString(byteBuffer);
@@ -579,10 +583,14 @@ public class SetTemplateProcedure
   }
 
   @Override
-  public boolean equals(Object o) {
-    if (this == o) return true;
-    if (o == null || getClass() != o.getClass()) return false;
-    SetTemplateProcedure that = (SetTemplateProcedure) o;
+  public boolean equals(final Object o) {
+    if (this == o) {
+      return true;
+    }
+    if (o == null || getClass() != o.getClass()) {
+      return false;
+    }
+    final SetTemplateProcedure that = (SetTemplateProcedure) o;
     return Objects.equals(getProcId(), that.getProcId())
         && Objects.equals(getCurrentState(), that.getCurrentState())
         && Objects.equals(getCycles(), that.getCycles())
diff --git 
a/iotdb-core/confignode/src/test/java/org/apache/iotdb/confignode/persistence/schema/ConfigMTreeTest.java
 
b/iotdb-core/confignode/src/test/java/org/apache/iotdb/confignode/persistence/schema/ConfigMTreeTest.java
index 5b8dc0b89c9..bed27e6db83 100644
--- 
a/iotdb-core/confignode/src/test/java/org/apache/iotdb/confignode/persistence/schema/ConfigMTreeTest.java
+++ 
b/iotdb-core/confignode/src/test/java/org/apache/iotdb/confignode/persistence/schema/ConfigMTreeTest.java
@@ -16,6 +16,7 @@
  * specific language governing permissions and limitations
  * under the License.
  */
+
 package org.apache.iotdb.confignode.persistence.schema;
 
 import org.apache.iotdb.commons.exception.IllegalPathException;
@@ -71,7 +72,7 @@ public class ConfigMTreeTest {
       root.setStorageGroup(new PartialPath("root.edge1.access"));
       root.setStorageGroup(new PartialPath("root.edge1"));
       fail("Expected exception");
-    } catch (MetadataException e) {
+    } catch (final MetadataException e) {
       assertEquals(
           "some children of root.edge1 have already been created as database", 
e.getMessage());
     }
@@ -79,20 +80,20 @@ public class ConfigMTreeTest {
       root.setStorageGroup(new PartialPath("root.edge2"));
       root.setStorageGroup(new PartialPath("root.edge2.access"));
       fail("Expected exception");
-    } catch (MetadataException e) {
+    } catch (final MetadataException e) {
       assertEquals("root.edge2 has already been created as database", 
e.getMessage());
     }
     try {
       root.setStorageGroup(new PartialPath("root.edge1.access"));
       fail("Expected exception");
-    } catch (MetadataException e) {
+    } catch (final MetadataException e) {
       assertEquals("root.edge1.access has already been created as database", 
e.getMessage());
     }
   }
 
   @Test
   public void testAddAndPathExist() throws MetadataException {
-    String path1 = "root";
+    final String path1 = "root";
     root.setStorageGroup(new PartialPath("root.laptop"));
     assertTrue(root.isDatabaseAlreadySet(new PartialPath(path1)));
     assertTrue(root.isDatabaseAlreadySet(new PartialPath("root.laptop")));
@@ -105,25 +106,25 @@ public class ConfigMTreeTest {
       root.setStorageGroup(new PartialPath("root.laptop.d1"));
       assertTrue(root.isDatabaseAlreadySet(new PartialPath("root.laptop.d1")));
       assertTrue(root.isDatabaseAlreadySet(new 
PartialPath("root.laptop.d1.s1")));
-    } catch (MetadataException e) {
+    } catch (final MetadataException e) {
       e.printStackTrace();
       fail(e.getMessage());
     }
     try {
       root.setStorageGroup(new PartialPath("root.laptop.d2"));
-    } catch (MetadataException e) {
+    } catch (final MetadataException e) {
       fail(e.getMessage());
     }
     try {
       root.setStorageGroup(new PartialPath("root.laptop"));
-    } catch (MetadataException e) {
+    } catch (final MetadataException e) {
       Assert.assertEquals(
           "some children of root.laptop have already been created as 
database", e.getMessage());
     }
 
     try {
       root.deleteDatabase(new PartialPath("root.laptop.d1"));
-    } catch (MetadataException e) {
+    } catch (final MetadataException e) {
       e.printStackTrace();
       fail(e.getMessage());
     }
@@ -138,7 +139,7 @@ public class ConfigMTreeTest {
       root.setStorageGroup(new PartialPath("root.laptop.d1"));
       root.setStorageGroup(new PartialPath("root.laptop.d2"));
 
-      List<PartialPath> list = new ArrayList<>();
+      final List<PartialPath> list = new ArrayList<>();
 
       list.add(new PartialPath("root.laptop.d1"));
       assertEquals(list, root.getBelongedDatabases(new 
PartialPath("root.laptop.d1.s1")));
@@ -147,7 +148,7 @@ public class ConfigMTreeTest {
       list.add(new PartialPath("root.laptop.d2"));
       assertEquals(list, root.getBelongedDatabases(new 
PartialPath("root.laptop.**")));
       assertEquals(list, root.getBelongedDatabases(new 
PartialPath("root.**")));
-    } catch (MetadataException e) {
+    } catch (final MetadataException e) {
       e.printStackTrace();
       fail(e.getMessage());
     }
@@ -175,7 +176,7 @@ public class ConfigMTreeTest {
       assertTrue(root.getBelongedDatabases(new 
PartialPath("root.vehicle1.device2")).isEmpty());
       assertTrue(root.getBelongedDatabases(new 
PartialPath("root.vehicle1.device3")).isEmpty());
       assertFalse(root.getBelongedDatabases(new 
PartialPath("root.vehicle1.device0")).isEmpty());
-    } catch (MetadataException e) {
+    } catch (final MetadataException e) {
       e.printStackTrace();
       fail(e.getMessage());
     }
@@ -185,7 +186,7 @@ public class ConfigMTreeTest {
   public void testIllegalStorageGroup() {
     try {
       root.setStorageGroup(new PartialPath("root.\"sg.ln\""));
-    } catch (MetadataException e) {
+    } catch (final MetadataException e) {
       Assert.assertEquals("root.\"sg.ln\" is not a legal path", 
e.getMessage());
     }
   }
@@ -251,7 +252,7 @@ public class ConfigMTreeTest {
 
   @Test
   public void testSerialization() throws Exception {
-    PartialPath[] pathList =
+    final PartialPath[] pathList =
         new PartialPath[] {
           new PartialPath("root.sg"),
           new PartialPath("root.a.sg"),
@@ -260,7 +261,7 @@ public class ConfigMTreeTest {
         };
     for (int i = 0; i < pathList.length; i++) {
       root.setStorageGroup(pathList[i]);
-      IDatabaseMNode<IConfigMNode> storageGroupMNode =
+      final IDatabaseMNode<IConfigMNode> storageGroupMNode =
           root.getDatabaseNodeByDatabasePath(pathList[i]);
       
storageGroupMNode.getAsMNode().getDatabaseSchema().setDataReplicationFactor(i);
       
storageGroupMNode.getAsMNode().getDatabaseSchema().setSchemaReplicationFactor(i);
@@ -268,15 +269,15 @@ public class ConfigMTreeTest {
       
root.getNodeWithAutoCreate(pathList[i].concatNode("a")).setSchemaTemplateId(i);
     }
 
-    ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
+    final ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
     root.serialize(outputStream);
 
-    ConfigMTree newTree = new ConfigMTree();
-    ByteArrayInputStream inputStream = new 
ByteArrayInputStream(outputStream.toByteArray());
+    final ConfigMTree newTree = new ConfigMTree();
+    final ByteArrayInputStream inputStream = new 
ByteArrayInputStream(outputStream.toByteArray());
     newTree.deserialize(inputStream);
 
     for (int i = 0; i < pathList.length; i++) {
-      TDatabaseSchema storageGroupSchema =
+      final TDatabaseSchema storageGroupSchema =
           
newTree.getDatabaseNodeByDatabasePath(pathList[i]).getAsMNode().getDatabaseSchema();
       Assert.assertEquals(i, storageGroupSchema.getSchemaReplicationFactor());
       Assert.assertEquals(i, storageGroupSchema.getDataReplicationFactor());
@@ -322,6 +323,7 @@ public class ConfigMTreeTest {
       
storageGroupMNode.getAsMNode().getDatabaseSchema().setDataReplicationFactor(i);
       
storageGroupMNode.getAsMNode().getDatabaseSchema().setSchemaReplicationFactor(i);
       
storageGroupMNode.getAsMNode().getDatabaseSchema().setTimePartitionInterval(i);
+      storageGroupMNode.getAsMNode().getDatabaseSchema().setIsTableModel(true);
 
       final String tableName = "table" + i;
       final TsTable table = new TsTable(tableName);
diff --git 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/exception/metadata/DatabaseConflictException.java
 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/exception/metadata/DatabaseConflictException.java
index a6e4ed952c4..d253c7984ac 100644
--- 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/exception/metadata/DatabaseConflictException.java
+++ 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/exception/metadata/DatabaseConflictException.java
@@ -28,7 +28,7 @@ public class DatabaseConflictException extends 
MetadataException {
 
   private final String storageGroupPath;
 
-  public DatabaseConflictException(final String path, boolean isChild) {
+  public DatabaseConflictException(final String path, final boolean isChild) {
     super(getMessage(path, isChild), 
TSStatusCode.DATABASE_CONFLICT.getStatusCode());
     this.isChild = isChild;
     storageGroupPath = path;
diff --git 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/exception/metadata/DatabaseConflictException.java
 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/exception/metadata/DatabaseModelException.java
similarity index 55%
copy from 
iotdb-core/datanode/src/main/java/org/apache/iotdb/db/exception/metadata/DatabaseConflictException.java
copy to 
iotdb-core/datanode/src/main/java/org/apache/iotdb/db/exception/metadata/DatabaseModelException.java
index a6e4ed952c4..95c0d45c53e 100644
--- 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/exception/metadata/DatabaseConflictException.java
+++ 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/exception/metadata/DatabaseModelException.java
@@ -22,31 +22,10 @@ package org.apache.iotdb.db.exception.metadata;
 import org.apache.iotdb.commons.exception.MetadataException;
 import org.apache.iotdb.rpc.TSStatusCode;
 
-public class DatabaseConflictException extends MetadataException {
-
-  private final boolean isChild;
-
-  private final String storageGroupPath;
-
-  public DatabaseConflictException(final String path, boolean isChild) {
-    super(getMessage(path, isChild), 
TSStatusCode.DATABASE_CONFLICT.getStatusCode());
-    this.isChild = isChild;
-    storageGroupPath = path;
-  }
-
-  public boolean isChild() {
-    return isChild;
-  }
-
-  public String getStorageGroupPath() {
-    return storageGroupPath;
-  }
-
-  private static String getMessage(final String path, final boolean isChild) {
-    if (isChild) {
-      return String.format("some children of %s have already been created as 
database", path);
-    } else {
-      return String.format("%s has already been created as database", path);
-    }
+public class DatabaseModelException extends MetadataException {
+  public DatabaseModelException(final String path, final boolean isTableModel) 
{
+    super(
+        "The database " + path + " is a " + (isTableModel ? "table" : "tree") 
+ " model database.",
+        TSStatusCode.DATABASE_MODEL.getStatusCode());
   }
 }
diff --git 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/protocol/client/ConfigNodeClient.java
 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/protocol/client/ConfigNodeClient.java
index 8487af0dcc9..bf643cfbd5e 100644
--- 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/protocol/client/ConfigNodeClient.java
+++ 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/protocol/client/ConfigNodeClient.java
@@ -622,7 +622,7 @@ public class ConfigNodeClient implements 
IConfigNodeRPCService.Iface, ThriftClie
 
   @Override
   public TSchemaPartitionTableResp getOrCreateSchemaPartitionTableWithSlots(
-      Map<String, List<TSeriesPartitionSlot>> dbSlotMap) throws TException {
+      final Map<String, List<TSeriesPartitionSlot>> dbSlotMap) throws 
TException {
     return executeRemoteCallWithRetry(
         () -> client.getOrCreateSchemaPartitionTableWithSlots(dbSlotMap),
         resp -> !updateConfigNodeLeader(resp.status));
diff --git 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/common/header/ColumnHeaderConstant.java
 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/common/header/ColumnHeaderConstant.java
index 32bf02aca52..d2fa82f9feb 100644
--- 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/common/header/ColumnHeaderConstant.java
+++ 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/common/header/ColumnHeaderConstant.java
@@ -64,6 +64,7 @@ public class ColumnHeaderConstant {
   public static final String DATA_REGION_GROUP_NUM = "DataRegionGroupNum";
   public static final String MIN_DATA_REGION_GROUP_NUM = 
"MinDataRegionGroupNum";
   public static final String MAX_DATA_REGION_GROUP_NUM = 
"MaxDataRegionGroupNum";
+  public static final String MODEL = "Model";
   public static final String CHILD_PATHS = "ChildPaths";
   public static final String NODE_TYPES = "NodeTypes";
   public static final String CHILD_NODES = "ChildNodes";
@@ -281,7 +282,8 @@ public class ColumnHeaderConstant {
           new ColumnHeader(MAX_SCHEMA_REGION_GROUP_NUM, TSDataType.INT32),
           new ColumnHeader(DATA_REGION_GROUP_NUM, TSDataType.INT32),
           new ColumnHeader(MIN_DATA_REGION_GROUP_NUM, TSDataType.INT32),
-          new ColumnHeader(MAX_DATA_REGION_GROUP_NUM, TSDataType.INT32));
+          new ColumnHeader(MAX_DATA_REGION_GROUP_NUM, TSDataType.INT32),
+          new ColumnHeader(MODEL, TSDataType.TEXT));
 
   public static final List<ColumnHeader> showChildPathsColumnHeaders =
       ImmutableList.of(
@@ -544,6 +546,14 @@ public class ColumnHeaderConstant {
           new ColumnHeader(DATA_REPLICATION_FACTOR, TSDataType.INT32),
           new ColumnHeader(TIME_PARTITION_INTERVAL, TSDataType.INT64));
 
+  public static final List<ColumnHeader> showDBDetailsColumnHeaders =
+      ImmutableList.of(
+          new ColumnHeader(DATABASE, TSDataType.TEXT),
+          new ColumnHeader(SCHEMA_REPLICATION_FACTOR, TSDataType.INT32),
+          new ColumnHeader(DATA_REPLICATION_FACTOR, TSDataType.INT32),
+          new ColumnHeader(TIME_PARTITION_INTERVAL, TSDataType.INT64),
+          new ColumnHeader(MODEL, TSDataType.TEXT));
+
   public static final List<ColumnHeader> describeTableColumnHeaders =
       ImmutableList.of(
           new ColumnHeader(COLUMN_NAME, TSDataType.TEXT),
diff --git 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/common/header/DatasetHeaderFactory.java
 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/common/header/DatasetHeaderFactory.java
index 9dbbe22b05e..3b85268bc13 100644
--- 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/common/header/DatasetHeaderFactory.java
+++ 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/common/header/DatasetHeaderFactory.java
@@ -57,7 +57,7 @@ public class DatasetHeaderFactory {
     return new 
DatasetHeader(ColumnHeaderConstant.showDevicesWithSgColumnHeaders, true);
   }
 
-  public static DatasetHeader getShowStorageGroupHeader(boolean isDetailed) {
+  public static DatasetHeader getShowStorageGroupHeader(final boolean 
isDetailed) {
     return isDetailed
         ? new 
DatasetHeader(ColumnHeaderConstant.showStorageGroupsDetailColumnHeaders, true)
         : new 
DatasetHeader(ColumnHeaderConstant.showStorageGroupsColumnHeaders, true);
@@ -221,6 +221,10 @@ public class DatasetHeaderFactory {
     return new DatasetHeader(ColumnHeaderConstant.showDBColumnHeaders, true);
   }
 
+  public static DatasetHeader getShowDBDetailsHeader() {
+    return new DatasetHeader(ColumnHeaderConstant.showDBDetailsColumnHeaders, 
true);
+  }
+
   public static DatasetHeader getDescribeTableHeader() {
     return new DatasetHeader(ColumnHeaderConstant.describeTableColumnHeaders, 
true);
   }
diff --git 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/analyze/ClusterPartitionFetcher.java
 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/analyze/ClusterPartitionFetcher.java
index 58e7ed374f2..104fd4b9f83 100644
--- 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/analyze/ClusterPartitionFetcher.java
+++ 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/analyze/ClusterPartitionFetcher.java
@@ -46,6 +46,7 @@ import 
org.apache.iotdb.confignode.rpc.thrift.TSchemaPartitionTableResp;
 import org.apache.iotdb.confignode.rpc.thrift.TTimeSlotList;
 import org.apache.iotdb.db.conf.IoTDBConfig;
 import org.apache.iotdb.db.conf.IoTDBDescriptor;
+import org.apache.iotdb.db.exception.metadata.DatabaseModelException;
 import org.apache.iotdb.db.exception.sql.SemanticException;
 import org.apache.iotdb.db.exception.sql.StatementAnalyzeException;
 import org.apache.iotdb.db.protocol.client.ConfigNodeClient;
@@ -99,16 +100,16 @@ public class ClusterPartitionFetcher implements 
IPartitionFetcher {
   }
 
   @Override
-  public SchemaPartition getSchemaPartition(PathPatternTree patternTree) {
-    try (ConfigNodeClient client =
+  public SchemaPartition getSchemaPartition(final PathPatternTree patternTree) 
{
+    try (final ConfigNodeClient client =
         configNodeClientManager.borrowClient(ConfigNodeInfo.CONFIG_REGION_ID)) 
{
       patternTree.constructTree();
-      List<IDeviceID> deviceIDs = patternTree.getAllDevicePatterns();
-      Map<String, List<IDeviceID>> storageGroupToDeviceMap =
+      final List<IDeviceID> deviceIDs = patternTree.getAllDevicePatterns();
+      final Map<String, List<IDeviceID>> storageGroupToDeviceMap =
           partitionCache.getDatabaseToDevice(deviceIDs, true, false, null);
       SchemaPartition schemaPartition = 
partitionCache.getSchemaPartition(storageGroupToDeviceMap);
       if (null == schemaPartition) {
-        TSchemaPartitionTableResp schemaPartitionTableResp =
+        final TSchemaPartitionTableResp schemaPartitionTableResp =
             
client.getSchemaPartitionTable(constructSchemaPartitionReq(patternTree));
         if (schemaPartitionTableResp.getStatus().getCode()
             == TSStatusCode.SUCCESS_STATUS.getStatusCode()) {
@@ -123,23 +124,24 @@ public class ClusterPartitionFetcher implements 
IPartitionFetcher {
         }
       }
       return schemaPartition;
-    } catch (ClientManagerException | TException e) {
+    } catch (final ClientManagerException | TException | 
DatabaseModelException e) {
       throw new StatementAnalyzeException(
           "An error occurred when executing getSchemaPartition():" + 
e.getMessage());
     }
   }
 
   @Override
-  public SchemaPartition getOrCreateSchemaPartition(PathPatternTree 
patternTree, String userName) {
-    try (ConfigNodeClient client =
+  public SchemaPartition getOrCreateSchemaPartition(
+      final PathPatternTree patternTree, final String userName) {
+    try (final ConfigNodeClient client =
         configNodeClientManager.borrowClient(ConfigNodeInfo.CONFIG_REGION_ID)) 
{
       patternTree.constructTree();
-      List<IDeviceID> deviceIDs = patternTree.getAllDevicePatterns();
-      Map<String, List<IDeviceID>> storageGroupToDeviceMap =
+      final List<IDeviceID> deviceIDs = patternTree.getAllDevicePatterns();
+      final Map<String, List<IDeviceID>> storageGroupToDeviceMap =
           partitionCache.getDatabaseToDevice(deviceIDs, true, true, userName);
       SchemaPartition schemaPartition = 
partitionCache.getSchemaPartition(storageGroupToDeviceMap);
       if (null == schemaPartition) {
-        TSchemaPartitionTableResp schemaPartitionTableResp =
+        final TSchemaPartitionTableResp schemaPartitionTableResp =
             
client.getOrCreateSchemaPartitionTable(constructSchemaPartitionReq(patternTree));
         if (schemaPartitionTableResp.getStatus().getCode()
             == TSStatusCode.SUCCESS_STATUS.getStatusCode()) {
@@ -154,7 +156,7 @@ public class ClusterPartitionFetcher implements 
IPartitionFetcher {
         }
       }
       return schemaPartition;
-    } catch (ClientManagerException | TException e) {
+    } catch (final ClientManagerException | TException | 
DatabaseModelException e) {
       throw new StatementAnalyzeException(
           "An error occurred when executing getOrCreateSchemaPartition():" + 
e.getMessage());
     }
@@ -162,16 +164,16 @@ public class ClusterPartitionFetcher implements 
IPartitionFetcher {
 
   @Override
   public SchemaNodeManagementPartition 
getSchemaNodeManagementPartitionWithLevel(
-      PathPatternTree patternTree, PathPatternTree scope, Integer level) {
+      final PathPatternTree patternTree, final PathPatternTree scope, final 
Integer level) {
     try (ConfigNodeClient client =
         configNodeClientManager.borrowClient(ConfigNodeInfo.CONFIG_REGION_ID)) 
{
       patternTree.constructTree();
-      TSchemaNodeManagementResp schemaNodeManagementResp =
+      final TSchemaNodeManagementResp schemaNodeManagementResp =
           client.getSchemaNodeManagementPartition(
               constructSchemaNodeManagementPartitionReq(patternTree, scope, 
level));
 
       return parseSchemaNodeManagementPartitionResp(schemaNodeManagementResp);
-    } catch (ClientManagerException | TException e) {
+    } catch (final ClientManagerException | TException e) {
       throw new StatementAnalyzeException(
           "An error occurred when executing 
getSchemaNodeManagementPartition():" + e.getMessage());
     }
@@ -179,12 +181,12 @@ public class ClusterPartitionFetcher implements 
IPartitionFetcher {
 
   @Override
   public DataPartition getDataPartition(
-      Map<String, List<DataPartitionQueryParam>> sgNameToQueryParamsMap) {
+      final Map<String, List<DataPartitionQueryParam>> sgNameToQueryParamsMap) 
{
     DataPartition dataPartition = 
partitionCache.getDataPartition(sgNameToQueryParamsMap);
     if (null == dataPartition) {
       try (ConfigNodeClient client =
           
configNodeClientManager.borrowClient(ConfigNodeInfo.CONFIG_REGION_ID)) {
-        TDataPartitionTableResp dataPartitionTableResp =
+        final TDataPartitionTableResp dataPartitionTableResp =
             
client.getDataPartitionTable(constructDataPartitionReqForQuery(sgNameToQueryParamsMap));
         if (dataPartitionTableResp.getStatus().getCode()
             == TSStatusCode.SUCCESS_STATUS.getStatusCode()) {
@@ -195,7 +197,7 @@ public class ClusterPartitionFetcher implements 
IPartitionFetcher {
               "An error occurred when executing getDataPartition():"
                   + dataPartitionTableResp.getStatus().getMessage());
         }
-      } catch (ClientManagerException | TException e) {
+      } catch (final ClientManagerException | TException e) {
         throw new StatementAnalyzeException(
             "An error occurred when executing getDataPartition():" + 
e.getMessage());
       }
@@ -205,13 +207,13 @@ public class ClusterPartitionFetcher implements 
IPartitionFetcher {
 
   @Override
   public DataPartition getDataPartitionWithUnclosedTimeRange(
-      Map<String, List<DataPartitionQueryParam>> sgNameToQueryParamsMap) {
+      final Map<String, List<DataPartitionQueryParam>> sgNameToQueryParamsMap) 
{
     // In this method, we must fetch from config node because it contains -oo 
or +oo
     // and there is no need to update cache because since we will never fetch 
it from cache, the
     // update operation will be only time waste
-    try (ConfigNodeClient client =
+    try (final ConfigNodeClient client =
         configNodeClientManager.borrowClient(ConfigNodeInfo.CONFIG_REGION_ID)) 
{
-      TDataPartitionTableResp dataPartitionTableResp =
+      final TDataPartitionTableResp dataPartitionTableResp =
           
client.getDataPartitionTable(constructDataPartitionReqForQuery(sgNameToQueryParamsMap));
       if (dataPartitionTableResp.getStatus().getCode()
           == TSStatusCode.SUCCESS_STATUS.getStatusCode()) {
@@ -221,7 +223,7 @@ public class ClusterPartitionFetcher implements 
IPartitionFetcher {
             "An error occurred when executing getDataPartition():"
                 + dataPartitionTableResp.getStatus().getMessage());
       }
-    } catch (ClientManagerException | TException e) {
+    } catch (final ClientManagerException | TException e) {
       throw new StatementAnalyzeException(
           "An error occurred when executing getDataPartition():" + 
e.getMessage());
     }
@@ -229,13 +231,13 @@ public class ClusterPartitionFetcher implements 
IPartitionFetcher {
 
   @Override
   public DataPartition getOrCreateDataPartition(
-      Map<String, List<DataPartitionQueryParam>> sgNameToQueryParamsMap) {
+      final Map<String, List<DataPartitionQueryParam>> sgNameToQueryParamsMap) 
{
     DataPartition dataPartition = 
partitionCache.getDataPartition(sgNameToQueryParamsMap);
     if (null == dataPartition) {
       // Do not use data partition cache
-      try (ConfigNodeClient client =
+      try (final ConfigNodeClient client =
           
configNodeClientManager.borrowClient(ConfigNodeInfo.CONFIG_REGION_ID)) {
-        TDataPartitionTableResp dataPartitionTableResp =
+        final TDataPartitionTableResp dataPartitionTableResp =
             
client.getOrCreateDataPartitionTable(constructDataPartitionReq(sgNameToQueryParamsMap));
         if (dataPartitionTableResp.getStatus().getCode()
             == TSStatusCode.SUCCESS_STATUS.getStatusCode()) {
@@ -246,7 +248,7 @@ public class ClusterPartitionFetcher implements 
IPartitionFetcher {
               "An error occurred when executing getOrCreateDataPartition():"
                   + dataPartitionTableResp.getStatus().getMessage());
         }
-      } catch (ClientManagerException | TException e) {
+      } catch (final ClientManagerException | TException e) {
         throw new StatementAnalyzeException(
             "An error occurred when executing getOrCreateDataPartition():" + 
e.getMessage());
       }
@@ -256,18 +258,19 @@ public class ClusterPartitionFetcher implements 
IPartitionFetcher {
 
   @Override
   public DataPartition getOrCreateDataPartition(
-      List<DataPartitionQueryParam> dataPartitionQueryParams, String userName) 
{
-
-    Map<String, List<DataPartitionQueryParam>> splitDataPartitionQueryParams =
-        splitDataPartitionQueryParam(
-            dataPartitionQueryParams, config.isAutoCreateSchemaEnabled(), 
userName);
-    DataPartition dataPartition = 
partitionCache.getDataPartition(splitDataPartitionQueryParams);
+      final List<DataPartitionQueryParam> dataPartitionQueryParams, final 
String userName) {
+    DataPartition dataPartition;
+    try (final ConfigNodeClient client =
+        configNodeClientManager.borrowClient(ConfigNodeInfo.CONFIG_REGION_ID)) 
{
+      final Map<String, List<DataPartitionQueryParam>> 
splitDataPartitionQueryParams =
+          splitDataPartitionQueryParam(
+              dataPartitionQueryParams, config.isAutoCreateSchemaEnabled(), 
userName);
+      dataPartition = 
partitionCache.getDataPartition(splitDataPartitionQueryParams);
 
-    if (null == dataPartition) {
-      try (ConfigNodeClient client =
-          
configNodeClientManager.borrowClient(ConfigNodeInfo.CONFIG_REGION_ID)) {
-        TDataPartitionReq req = 
constructDataPartitionReq(splitDataPartitionQueryParams);
-        TDataPartitionTableResp dataPartitionTableResp = 
client.getOrCreateDataPartitionTable(req);
+      if (null == dataPartition) {
+        final TDataPartitionReq req = 
constructDataPartitionReq(splitDataPartitionQueryParams);
+        final TDataPartitionTableResp dataPartitionTableResp =
+            client.getOrCreateDataPartitionTable(req);
 
         if (dataPartitionTableResp.getStatus().getCode()
             == TSStatusCode.SUCCESS_STATUS.getStatusCode()) {
@@ -279,16 +282,16 @@ public class ClusterPartitionFetcher implements 
IPartitionFetcher {
                   dataPartitionTableResp.getStatus().getMessage(),
                   dataPartitionTableResp.getStatus().getCode()));
         }
-      } catch (ClientManagerException | TException e) {
-        throw new StatementAnalyzeException(
-            "An error occurred when executing getOrCreateDataPartition():" + 
e.getMessage());
       }
+    } catch (final ClientManagerException | TException | 
DatabaseModelException e) {
+      throw new StatementAnalyzeException(
+          "An error occurred when executing getOrCreateDataPartition():" + 
e.getMessage());
     }
     return dataPartition;
   }
 
   @Override
-  public boolean updateRegionCache(TRegionRouteReq req) {
+  public boolean updateRegionCache(final TRegionRouteReq req) {
     return partitionCache.updateGroupIdToReplicaSetMap(req.getTimestamp(), 
req.getRegionRouteMap());
   }
 
@@ -299,29 +302,33 @@ public class ClusterPartitionFetcher implements 
IPartitionFetcher {
 
   @Override
   public SchemaPartition getOrCreateSchemaPartition(
-      String database, List<IDeviceID> deviceIDs, String userName) {
+      final String database, final List<IDeviceID> deviceIDs, final String 
userName) {
     return getOrCreateSchemaPartition(database, deviceIDs, true, userName);
   }
 
   @Override
-  public SchemaPartition getSchemaPartition(String database, List<IDeviceID> 
deviceIDs) {
+  public SchemaPartition getSchemaPartition(
+      final String database, final List<IDeviceID> deviceIDs) {
     return getOrCreateSchemaPartition(database, deviceIDs, false, null);
   }
 
   private SchemaPartition getOrCreateSchemaPartition(
-      String database, List<IDeviceID> deviceIDs, boolean isAutoCreate, String 
userName) {
-    try (ConfigNodeClient client =
+      final String database,
+      final List<IDeviceID> deviceIDs,
+      final boolean isAutoCreate,
+      final String userName) {
+    try (final ConfigNodeClient client =
         configNodeClientManager.borrowClient(ConfigNodeInfo.CONFIG_REGION_ID)) 
{
       partitionCache.checkAndAutoCreateDatabase(database, isAutoCreate, 
userName);
       SchemaPartition schemaPartition =
           partitionCache.getSchemaPartition(Collections.singletonMap(database, 
deviceIDs));
       if (null == schemaPartition) {
-        List<TSeriesPartitionSlot> partitionSlots =
+        final List<TSeriesPartitionSlot> partitionSlots =
             deviceIDs.stream()
                 .map(partitionExecutor::getSeriesPartitionSlot)
                 .distinct()
                 .collect(Collectors.toList());
-        TSchemaPartitionTableResp schemaPartitionTableResp =
+        final TSchemaPartitionTableResp schemaPartitionTableResp =
             isAutoCreate
                 ? client.getOrCreateSchemaPartitionTableWithSlots(
                     Collections.singletonMap(database, partitionSlots))
@@ -340,7 +347,7 @@ public class ClusterPartitionFetcher implements 
IPartitionFetcher {
         }
       }
       return schemaPartition;
-    } catch (ClientManagerException | TException e) {
+    } catch (final ClientManagerException | TException | 
DatabaseModelException e) {
       throw new StatementAnalyzeException(
           "An error occurred when executing getSchemaPartition():" + 
e.getMessage());
     }
@@ -361,17 +368,18 @@ public class ClusterPartitionFetcher implements 
IPartitionFetcher {
 
   /** split data partition query param by database */
   private Map<String, List<DataPartitionQueryParam>> 
splitDataPartitionQueryParam(
-      List<DataPartitionQueryParam> dataPartitionQueryParams,
-      boolean isAutoCreate,
-      String userName) {
-    List<IDeviceID> deviceIDs = new ArrayList<>();
-    for (DataPartitionQueryParam dataPartitionQueryParam : 
dataPartitionQueryParams) {
+      final List<DataPartitionQueryParam> dataPartitionQueryParams,
+      final boolean isAutoCreate,
+      final String userName)
+      throws DatabaseModelException {
+    final List<IDeviceID> deviceIDs = new ArrayList<>();
+    for (final DataPartitionQueryParam dataPartitionQueryParam : 
dataPartitionQueryParams) {
       deviceIDs.add(dataPartitionQueryParam.getDeviceID());
     }
     Map<IDeviceID, String> deviceToDatabase = null;
-    Map<String, List<DataPartitionQueryParam>> result = new HashMap<>();
-    for (DataPartitionQueryParam dataPartitionQueryParam : 
dataPartitionQueryParams) {
-      IDeviceID deviceID = dataPartitionQueryParam.getDeviceID();
+    final Map<String, List<DataPartitionQueryParam>> result = new HashMap<>();
+    for (final DataPartitionQueryParam dataPartitionQueryParam : 
dataPartitionQueryParams) {
+      final IDeviceID deviceID = dataPartitionQueryParam.getDeviceID();
       String database = null;
       if (dataPartitionQueryParam.getDatabaseName() == null) {
         if (deviceToDatabase == null) {
@@ -391,7 +399,7 @@ public class ClusterPartitionFetcher implements 
IPartitionFetcher {
     return result;
   }
 
-  private TSchemaPartitionReq constructSchemaPartitionReq(PathPatternTree 
patternTree) {
+  private TSchemaPartitionReq constructSchemaPartitionReq(final 
PathPatternTree patternTree) {
     try {
       return new TSchemaPartitionReq(patternTree.serialize());
     } catch (IOException e) {
@@ -400,9 +408,9 @@ public class ClusterPartitionFetcher implements 
IPartitionFetcher {
   }
 
   private TSchemaNodeManagementReq constructSchemaNodeManagementPartitionReq(
-      PathPatternTree patternTree, PathPatternTree scope, Integer level) {
+      final PathPatternTree patternTree, final PathPatternTree scope, final 
Integer level) {
     try {
-      TSchemaNodeManagementReq schemaNodeManagementReq =
+      final TSchemaNodeManagementReq schemaNodeManagementReq =
           new TSchemaNodeManagementReq(patternTree.serialize());
       schemaNodeManagementReq.setScopePatternTree(scope.serialize());
       if (null == level) {
@@ -422,28 +430,29 @@ public class ClusterPartitionFetcher implements 
IPartitionFetcher {
     boolean needLeftAll;
     boolean needRightAll;
 
-    private ComplexTimeSlotList(boolean needLeftAll, boolean needRightAll) {
+    private ComplexTimeSlotList(final boolean needLeftAll, final boolean 
needRightAll) {
       timeSlotList = new HashSet<>();
       this.needLeftAll = needLeftAll;
       this.needRightAll = needRightAll;
     }
 
-    private void putTimeSlot(List<TTimePartitionSlot> slotList) {
+    private void putTimeSlot(final List<TTimePartitionSlot> slotList) {
       timeSlotList.addAll(slotList);
     }
   }
 
   private TDataPartitionReq constructDataPartitionReq(
-      Map<String, List<DataPartitionQueryParam>> sgNameToQueryParamsMap) {
-    Map<String, Map<TSeriesPartitionSlot, TTimeSlotList>> partitionSlotsMap = 
new HashMap<>();
-    for (Map.Entry<String, List<DataPartitionQueryParam>> entry :
+      final Map<String, List<DataPartitionQueryParam>> sgNameToQueryParamsMap) 
{
+    final Map<String, Map<TSeriesPartitionSlot, TTimeSlotList>> 
partitionSlotsMap = new HashMap<>();
+    for (final Map.Entry<String, List<DataPartitionQueryParam>> entry :
         sgNameToQueryParamsMap.entrySet()) {
       // for each sg
-      Map<TSeriesPartitionSlot, TTimeSlotList> deviceToTimePartitionMap = new 
HashMap<>();
+      final Map<TSeriesPartitionSlot, TTimeSlotList> deviceToTimePartitionMap 
= new HashMap<>();
 
-      Map<TSeriesPartitionSlot, ComplexTimeSlotList> 
seriesSlotTimePartitionMap = new HashMap<>();
+      final Map<TSeriesPartitionSlot, ComplexTimeSlotList> 
seriesSlotTimePartitionMap =
+          new HashMap<>();
 
-      for (DataPartitionQueryParam queryParam : entry.getValue()) {
+      for (final DataPartitionQueryParam queryParam : entry.getValue()) {
         seriesSlotTimePartitionMap
             .computeIfAbsent(
                 
partitionExecutor.getSeriesPartitionSlot(queryParam.getDeviceID()),
@@ -466,15 +475,15 @@ public class ClusterPartitionFetcher implements 
IPartitionFetcher {
 
   /** For query, DataPartitionQueryParam is shared by each device */
   private TDataPartitionReq constructDataPartitionReqForQuery(
-      Map<String, List<DataPartitionQueryParam>> sgNameToQueryParamsMap) {
-    Map<String, Map<TSeriesPartitionSlot, TTimeSlotList>> partitionSlotsMap = 
new HashMap<>();
+      final Map<String, List<DataPartitionQueryParam>> sgNameToQueryParamsMap) 
{
+    final Map<String, Map<TSeriesPartitionSlot, TTimeSlotList>> 
partitionSlotsMap = new HashMap<>();
     TTimeSlotList sharedTTimeSlotList = null;
-    for (Map.Entry<String, List<DataPartitionQueryParam>> entry :
+    for (final Map.Entry<String, List<DataPartitionQueryParam>> entry :
         sgNameToQueryParamsMap.entrySet()) {
       // for each sg
-      Map<TSeriesPartitionSlot, TTimeSlotList> deviceToTimePartitionMap = new 
HashMap<>();
+      final Map<TSeriesPartitionSlot, TTimeSlotList> deviceToTimePartitionMap 
= new HashMap<>();
 
-      for (DataPartitionQueryParam queryParam : entry.getValue()) {
+      for (final DataPartitionQueryParam queryParam : entry.getValue()) {
         if (sharedTTimeSlotList == null) {
           sharedTTimeSlotList =
               new TTimeSlotList(
@@ -492,13 +501,14 @@ public class ClusterPartitionFetcher implements 
IPartitionFetcher {
   }
 
   private SchemaPartition parseSchemaPartitionTableResp(
-      TSchemaPartitionTableResp schemaPartitionTableResp) {
-    Map<String, Map<TSeriesPartitionSlot, TRegionReplicaSet>> regionReplicaMap 
= new HashMap<>();
-    for (Map.Entry<String, Map<TSeriesPartitionSlot, TConsensusGroupId>> 
entry1 :
+      final TSchemaPartitionTableResp schemaPartitionTableResp) {
+    final Map<String, Map<TSeriesPartitionSlot, TRegionReplicaSet>> 
regionReplicaMap =
+        new HashMap<>();
+    for (final Map.Entry<String, Map<TSeriesPartitionSlot, TConsensusGroupId>> 
entry1 :
         schemaPartitionTableResp.getSchemaPartitionTable().entrySet()) {
-      Map<TSeriesPartitionSlot, TRegionReplicaSet> result1 =
+      final Map<TSeriesPartitionSlot, TRegionReplicaSet> result1 =
           regionReplicaMap.computeIfAbsent(entry1.getKey(), k -> new 
HashMap<>());
-      for (Map.Entry<TSeriesPartitionSlot, TConsensusGroupId> entry2 :
+      for (final Map.Entry<TSeriesPartitionSlot, TConsensusGroupId> entry2 :
           entry1.getValue().entrySet()) {
         TSeriesPartitionSlot seriesPartitionSlot = entry2.getKey();
         TConsensusGroupId consensusGroupId = entry2.getValue();
@@ -513,7 +523,7 @@ public class ClusterPartitionFetcher implements 
IPartitionFetcher {
   }
 
   private SchemaNodeManagementPartition parseSchemaNodeManagementPartitionResp(
-      TSchemaNodeManagementResp schemaNodeManagementResp) {
+      final TSchemaNodeManagementResp schemaNodeManagementResp) {
     return new SchemaNodeManagementPartition(
         schemaNodeManagementResp.getSchemaRegionMap(),
         
IoTDBDescriptor.getInstance().getConfig().getSeriesPartitionExecutorClass(),
@@ -521,22 +531,23 @@ public class ClusterPartitionFetcher implements 
IPartitionFetcher {
         schemaNodeManagementResp.getMatchedNode());
   }
 
-  private DataPartition parseDataPartitionResp(TDataPartitionTableResp 
dataPartitionTableResp) {
-    Map<String, Map<TSeriesPartitionSlot, Map<TTimePartitionSlot, 
List<TRegionReplicaSet>>>>
+  private DataPartition parseDataPartitionResp(
+      final TDataPartitionTableResp dataPartitionTableResp) {
+    final Map<String, Map<TSeriesPartitionSlot, Map<TTimePartitionSlot, 
List<TRegionReplicaSet>>>>
         regionReplicaSet = new HashMap<>();
-    for (Map.Entry<
+    for (final Map.Entry<
             String, Map<TSeriesPartitionSlot, Map<TTimePartitionSlot, 
List<TConsensusGroupId>>>>
         entry1 : dataPartitionTableResp.getDataPartitionTable().entrySet()) {
-      Map<TSeriesPartitionSlot, Map<TTimePartitionSlot, 
List<TRegionReplicaSet>>> result1 =
+      final Map<TSeriesPartitionSlot, Map<TTimePartitionSlot, 
List<TRegionReplicaSet>>> result1 =
           regionReplicaSet.computeIfAbsent(entry1.getKey(), k -> new 
HashMap<>());
-      for (Map.Entry<TSeriesPartitionSlot, Map<TTimePartitionSlot, 
List<TConsensusGroupId>>>
+      for (final Map.Entry<TSeriesPartitionSlot, Map<TTimePartitionSlot, 
List<TConsensusGroupId>>>
           entry2 : entry1.getValue().entrySet()) {
-        Map<TTimePartitionSlot, List<TRegionReplicaSet>> result2 =
+        final Map<TTimePartitionSlot, List<TRegionReplicaSet>> result2 =
             result1.computeIfAbsent(entry2.getKey(), k -> new HashMap<>());
-        for (Map.Entry<TTimePartitionSlot, List<TConsensusGroupId>> entry3 :
+        for (final Map.Entry<TTimePartitionSlot, List<TConsensusGroupId>> 
entry3 :
             entry2.getValue().entrySet()) {
-          List<TRegionReplicaSet> regionReplicaSets = new LinkedList<>();
-          for (TConsensusGroupId consensusGroupId : entry3.getValue()) {
+          final List<TRegionReplicaSet> regionReplicaSets = new LinkedList<>();
+          for (final TConsensusGroupId consensusGroupId : entry3.getValue()) {
             
regionReplicaSets.add(partitionCache.getRegionReplicaSet(consensusGroupId));
           }
           result2.put(entry3.getKey(), regionReplicaSets);
diff --git 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/analyze/cache/partition/PartitionCache.java
 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/analyze/cache/partition/PartitionCache.java
index 714d6b18082..e5d11d74f78 100644
--- 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/analyze/cache/partition/PartitionCache.java
+++ 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/analyze/cache/partition/PartitionCache.java
@@ -48,6 +48,7 @@ import 
org.apache.iotdb.confignode.rpc.thrift.TRegionRouteMapResp;
 import org.apache.iotdb.db.auth.AuthorityChecker;
 import org.apache.iotdb.db.conf.IoTDBConfig;
 import org.apache.iotdb.db.conf.IoTDBDescriptor;
+import org.apache.iotdb.db.exception.metadata.DatabaseModelException;
 import org.apache.iotdb.db.exception.sql.StatementAnalyzeException;
 import org.apache.iotdb.db.protocol.client.ConfigNodeClient;
 import org.apache.iotdb.db.protocol.client.ConfigNodeClientManager;
@@ -74,6 +75,7 @@ import java.util.Map;
 import java.util.Set;
 import java.util.concurrent.atomic.AtomicLong;
 import java.util.concurrent.locks.ReentrantReadWriteLock;
+import java.util.stream.Collectors;
 
 public class PartitionCache {
 
@@ -88,7 +90,7 @@ public class PartitionCache {
   private final SeriesPartitionExecutor partitionExecutor;
 
   /** the cache of database */
-  private final Set<String> databaseCache = new HashSet<>();
+  private final Map<String, Boolean> databaseCache = new HashMap<>();
 
   /** database -> schemaPartitionTable */
   private final Cache<String, SchemaPartitionTable> schemaPartitionCache;
@@ -136,11 +138,15 @@ public class PartitionCache {
    * @param userName the userName
    */
   public Map<String, List<IDeviceID>> getDatabaseToDevice(
-      List<IDeviceID> deviceIDs, boolean tryToFetch, boolean isAutoCreate, 
String userName) {
-    DatabaseCacheResult<String, List<IDeviceID>> result =
+      final List<IDeviceID> deviceIDs,
+      final boolean tryToFetch,
+      final boolean isAutoCreate,
+      final String userName)
+      throws DatabaseModelException {
+    final DatabaseCacheResult<String, List<IDeviceID>> result =
         new DatabaseCacheResult<String, List<IDeviceID>>() {
           @Override
-          public void put(IDeviceID device, String databaseName) {
+          public void put(final IDeviceID device, final String databaseName) {
             map.computeIfAbsent(databaseName, k -> new 
ArrayList<>()).add(device);
           }
         };
@@ -157,11 +163,15 @@ public class PartitionCache {
    * @param userName the userName
    */
   public Map<IDeviceID, String> getDeviceToDatabase(
-      List<IDeviceID> deviceIDs, boolean tryToFetch, boolean isAutoCreate, 
String userName) {
-    DatabaseCacheResult<IDeviceID, String> result =
+      final List<IDeviceID> deviceIDs,
+      final boolean tryToFetch,
+      final boolean isAutoCreate,
+      final String userName)
+      throws DatabaseModelException {
+    final DatabaseCacheResult<IDeviceID, String> result =
         new DatabaseCacheResult<IDeviceID, String>() {
           @Override
-          public void put(IDeviceID device, String databaseName) {
+          public void put(final IDeviceID device, final String databaseName) {
             map.put(device, databaseName);
           }
         };
@@ -173,12 +183,16 @@ public class PartitionCache {
    * get database of device
    *
    * @param deviceID the path of device
-   * @return database name, return null if cache miss
+   * @return database name, return {@code null} if cache miss
    */
-  private String getDatabaseName(IDeviceID deviceID) {
-    for (String databaseName : databaseCache) {
-      if (PathUtils.isStartWith(deviceID, databaseName)) {
-        return databaseName;
+  private String getDatabaseName(final IDeviceID deviceID) throws 
DatabaseModelException {
+    for (final Map.Entry<String, Boolean> entry : databaseCache.entrySet()) {
+      final String database = entry.getKey();
+      if (PathUtils.isStartWith(deviceID, database)) {
+        if (Boolean.TRUE.equals(entry.getValue())) {
+          throw new DatabaseModelException(database, true);
+        }
+        return entry.getKey();
       }
     }
     return null;
@@ -188,12 +202,18 @@ public class PartitionCache {
    * judge whether this database is existed
    *
    * @param database name
-   * @return true of false
+   * @return {@code true} if this database exists
    */
-  private boolean containsDatabase(String database) {
+  private boolean containsDatabase(final String database) throws 
DatabaseModelException {
     try {
       databaseCacheLock.readLock().lock();
-      return databaseCache.contains(database);
+      if (databaseCache.containsKey(database)) {
+        if (Boolean.FALSE.equals(databaseCache.get(database))) {
+          throw new 
DatabaseModelException(PathUtils.unQualifyDatabaseName(database), false);
+        }
+        return true;
+      }
+      return false;
     } finally {
       databaseCacheLock.readLock().unlock();
     }
@@ -206,21 +226,25 @@ public class PartitionCache {
    * @param deviceIDs the devices that need to hit
    */
   private void fetchDatabaseAndUpdateCache(
-      DatabaseCacheResult<?, ?> result, List<IDeviceID> deviceIDs)
-      throws ClientManagerException, TException {
+      final DatabaseCacheResult<?, ?> result, final List<IDeviceID> deviceIDs)
+      throws ClientManagerException, TException, DatabaseModelException {
     databaseCacheLock.writeLock().lock();
-    try (ConfigNodeClient client =
+    try (final ConfigNodeClient client =
         configNodeClientManager.borrowClient(ConfigNodeInfo.CONFIG_REGION_ID)) 
{
       result.reset();
       getDatabaseMap(result, deviceIDs, true);
       if (!result.isSuccess()) {
-        TGetDatabaseReq req = new TGetDatabaseReq(ROOT_PATH, 
SchemaConstant.ALL_MATCH_SCOPE_BINARY);
-        TDatabaseSchemaResp databaseSchemaResp = 
client.getMatchedDatabaseSchemas(req);
+        final TGetDatabaseReq req =
+            new TGetDatabaseReq(ROOT_PATH, 
SchemaConstant.ALL_MATCH_SCOPE_BINARY);
+        final TDatabaseSchemaResp databaseSchemaResp = 
client.getMatchedDatabaseSchemas(req);
         if (databaseSchemaResp.getStatus().getCode()
             == TSStatusCode.SUCCESS_STATUS.getStatusCode()) {
-          Set<String> databaseNames = 
databaseSchemaResp.getDatabaseSchemaMap().keySet();
           // update all database into cache
-          updateDatabaseCache(databaseNames);
+          updateDatabaseCache(
+              databaseSchemaResp.getDatabaseSchemaMap().entrySet().stream()
+                  .collect(
+                      Collectors.toMap(
+                          Map.Entry::getKey, entry -> 
entry.getValue().isIsTableModel())));
           getDatabaseMap(result, deviceIDs, true);
         }
       }
@@ -230,17 +254,20 @@ public class PartitionCache {
   }
 
   /** get all database from configNode and update database cache. */
-  private void fetchDatabaseAndUpdateCache(String database)
-      throws ClientManagerException, TException {
+  private void fetchDatabaseAndUpdateCache() throws ClientManagerException, 
TException {
     databaseCacheLock.writeLock().lock();
-    try (ConfigNodeClient client =
+    try (final ConfigNodeClient client =
         configNodeClientManager.borrowClient(ConfigNodeInfo.CONFIG_REGION_ID)) 
{
-      TGetDatabaseReq req = new TGetDatabaseReq(ROOT_PATH, 
SchemaConstant.ALL_MATCH_SCOPE_BINARY);
-      TDatabaseSchemaResp databaseSchemaResp = 
client.getMatchedDatabaseSchemas(req);
+      final TGetDatabaseReq req =
+          new TGetDatabaseReq(ROOT_PATH, 
SchemaConstant.ALL_MATCH_SCOPE_BINARY);
+      final TDatabaseSchemaResp databaseSchemaResp = 
client.getMatchedDatabaseSchemas(req);
       if (databaseSchemaResp.getStatus().getCode() == 
TSStatusCode.SUCCESS_STATUS.getStatusCode()) {
-        Set<String> databaseNames = 
databaseSchemaResp.getDatabaseSchemaMap().keySet();
         // update all database into cache
-        updateDatabaseCache(databaseNames);
+        updateDatabaseCache(
+            databaseSchemaResp.getDatabaseSchemaMap().entrySet().stream()
+                .collect(
+                    Collectors.toMap(
+                        Map.Entry::getKey, entry -> 
entry.getValue().isIsTableModel())));
       }
     } finally {
       databaseCacheLock.writeLock().unlock();
@@ -274,7 +301,7 @@ public class PartitionCache {
           if (PathUtils.isStartWith(deviceID, SchemaConstant.SYSTEM_DATABASE)) 
{
             databaseNamesNeedCreated.add(SchemaConstant.SYSTEM_DATABASE);
           } else {
-            PartialPath databaseNameNeedCreated =
+            final PartialPath databaseNameNeedCreated =
                 MetaUtils.getDatabasePathByLevel(
                     new PartialPath(deviceID), 
config.getDefaultStorageGroupLevel());
             
databaseNamesNeedCreated.add(databaseNameNeedCreated.getFullPath());
@@ -282,7 +309,7 @@ public class PartitionCache {
         }
 
         // Try to create databases one by one until done or one database fail
-        final Set<String> successFullyCreatedDatabase = new HashSet<>();
+        final Map<String, Boolean> successFullyCreatedDatabase = new 
HashMap<>();
         for (final String databaseName : databaseNamesNeedCreated) {
           final long startTime = System.nanoTime();
           try {
@@ -302,18 +329,11 @@ public class PartitionCache {
           }
           final TDatabaseSchema databaseSchema = new TDatabaseSchema();
           databaseSchema.setName(databaseName);
+          databaseSchema.setIsTableModel(false);
           final TSStatus tsStatus = client.setDatabase(databaseSchema);
-          if (SchemaConstant.SYSTEM_DATABASE.equals(databaseName)) {
-            databaseSchema.setSchemaReplicationFactor(1);
-            databaseSchema.setDataReplicationFactor(1);
-            databaseSchema.setMinSchemaRegionGroupNum(1);
-            databaseSchema.setMaxSchemaRegionGroupNum(1);
-            databaseSchema.setMaxDataRegionGroupNum(1);
-            databaseSchema.setMaxDataRegionGroupNum(1);
-          }
           if (TSStatusCode.SUCCESS_STATUS.getStatusCode() == tsStatus.getCode()
               || TSStatusCode.DATABASE_ALREADY_EXISTS.getStatusCode() == 
tsStatus.getCode()) {
-            successFullyCreatedDatabase.add(databaseName);
+            successFullyCreatedDatabase.put(databaseName, false);
             // In tree model, if the user creates a conflict database 
concurrently, for instance,
             // the database created by user is root.db.ss.a, the auto-creation 
failed database is
             // root.db, we wait till "getOrCreatePartition" to judge if the 
time series (like
@@ -330,7 +350,7 @@ public class PartitionCache {
           }
         }
         // Try to update database cache when all databases have already been 
created
-        updateDatabaseCache(databaseNamesNeedCreated);
+        updateDatabaseCache(successFullyCreatedDatabase);
         getDatabaseMap(result, deviceIDs, false);
       }
     } finally {
@@ -367,11 +387,12 @@ public class PartitionCache {
       }
       final TDatabaseSchema databaseSchema = new TDatabaseSchema();
       databaseSchema.setName(database);
+      databaseSchema.setIsTableModel(true);
       final TSStatus tsStatus = client.setDatabase(databaseSchema);
       if (TSStatusCode.SUCCESS_STATUS.getStatusCode() == tsStatus.getCode()
           || TSStatusCode.DATABASE_ALREADY_EXISTS.getStatusCode() == 
tsStatus.getCode()) {
         // Try to update cache by databases successfully created
-        updateDatabaseCache(Collections.singleton(database));
+        updateDatabaseCache(Collections.singletonMap(database, true));
       } else {
         logger.warn(
             "[{} Cache] failed to create database {}", 
CacheMetrics.DATABASE_CACHE_NAME, database);
@@ -387,17 +408,21 @@ public class PartitionCache {
    *
    * @param result contains result(boolean), failed devices and the map
    * @param deviceIDs the devices that need to hit
-   * @param failFast if true, return when failed. if false, return when all 
devices hit
+   * @param failFast if {@code true}, return when failed. if {@code false}, 
return when all devices
+   *     hit
    */
   private void getDatabaseMap(
-      DatabaseCacheResult<?, ?> result, List<IDeviceID> deviceIDs, boolean 
failFast) {
+      final DatabaseCacheResult<?, ?> result,
+      final List<IDeviceID> deviceIDs,
+      final boolean failFast)
+      throws DatabaseModelException {
     try {
       databaseCacheLock.readLock().lock();
       // reset result before try
       result.reset();
       boolean status = true;
-      for (IDeviceID devicePath : deviceIDs) {
-        String databaseName = getDatabaseName(devicePath);
+      for (final IDeviceID devicePath : deviceIDs) {
+        final String databaseName = getDatabaseName(devicePath);
         if (null == databaseName) {
           logger.debug(
               "[{} Cache] miss when search device {}",
@@ -435,15 +460,16 @@ public class PartitionCache {
    * @param userName
    */
   private void getDatabaseCacheResult(
-      DatabaseCacheResult<?, ?> result,
-      List<IDeviceID> deviceIDs,
-      boolean tryToFetch,
-      boolean isAutoCreate,
-      String userName) {
+      final DatabaseCacheResult<?, ?> result,
+      final List<IDeviceID> deviceIDs,
+      final boolean tryToFetch,
+      final boolean isAutoCreate,
+      final String userName)
+      throws DatabaseModelException {
     if (!isAutoCreate) {
       // TODO: avoid IDeviceID contains "*"
       // miss when deviceId contains *
-      for (IDeviceID deviceID : deviceIDs) {
+      for (final IDeviceID deviceID : deviceIDs) {
         for (int i = 0; i < deviceID.segmentNum(); i++) {
           if (((String) deviceID.segment(i)).contains("*")) {
             return;
@@ -464,25 +490,27 @@ public class PartitionCache {
             throw new StatementAnalyzeException("Failed to get database Map");
           }
         }
-      } catch (TException | MetadataException | ClientManagerException e) {
+      } catch (final TException | MetadataException | ClientManagerException 
e) {
         throw new StatementAnalyzeException(
             "An error occurred when executing getDeviceToDatabase():" + 
e.getMessage());
       }
     }
   }
 
-  public void checkAndAutoCreateDatabase(String database, boolean 
isAutoCreate, String userName) {
+  public void checkAndAutoCreateDatabase(
+      final String database, final boolean isAutoCreate, final String userName)
+      throws DatabaseModelException {
     boolean isExisted = containsDatabase(database);
     if (!isExisted) {
       try {
         // try to fetch database from config node when miss
-        fetchDatabaseAndUpdateCache(database);
+        fetchDatabaseAndUpdateCache();
         isExisted = containsDatabase(database);
         if (!isExisted && isAutoCreate) {
           // try to auto create database of failed device
           createDatabaseAndUpdateCache(database, userName);
         }
-      } catch (TException | ClientManagerException e) {
+      } catch (final TException | ClientManagerException e) {
         throw new StatementAnalyzeException(
             "An error occurred when executing getDeviceToDatabase():" + 
e.getMessage());
       }
@@ -494,10 +522,10 @@ public class PartitionCache {
    *
    * @param databaseNames the database names that need to update
    */
-  public void updateDatabaseCache(Set<String> databaseNames) {
+  public void updateDatabaseCache(final Map<String, Boolean> databaseNames) {
     databaseCacheLock.writeLock().lock();
     try {
-      databaseCache.addAll(databaseNames);
+      databaseCache.putAll(databaseNames);
     } finally {
       databaseCacheLock.writeLock().unlock();
     }
diff --git 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/execution/config/TableConfigTaskVisitor.java
 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/execution/config/TableConfigTaskVisitor.java
index 1f42d8ae9a1..59918c25265 100644
--- 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/execution/config/TableConfigTaskVisitor.java
+++ 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/execution/config/TableConfigTaskVisitor.java
@@ -157,6 +157,7 @@ public class TableConfigTaskVisitor extends 
AstVisitor<IConfigTask, MPPQueryCont
     context.setQueryType(QueryType.WRITE);
 
     final TDatabaseSchema schema = new TDatabaseSchema();
+    schema.setIsTableModel(true);
 
     final String dbName = node.getDbName();
     validateDatabaseName(dbName);
@@ -391,7 +392,7 @@ public class TableConfigTaskVisitor extends 
AstVisitor<IConfigTask, MPPQueryCont
         node.ifExists());
   }
 
-  public static void validateDatabaseName(String dbName) throws 
SemanticException {
+  public static void validateDatabaseName(final String dbName) throws 
SemanticException {
     // Check database length here
     // We need to calculate the database name without "root."
     if (dbName.contains(PATH_SEPARATOR)
diff --git 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/execution/config/executor/ClusterConfigTaskExecutor.java
 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/execution/config/executor/ClusterConfigTaskExecutor.java
index a34c820930a..66617ec3ef0 100644
--- 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/execution/config/executor/ClusterConfigTaskExecutor.java
+++ 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/execution/config/executor/ClusterConfigTaskExecutor.java
@@ -60,6 +60,7 @@ import 
org.apache.iotdb.commons.trigger.service.TriggerExecutableManager;
 import org.apache.iotdb.commons.udf.service.UDFClassLoader;
 import org.apache.iotdb.commons.udf.service.UDFExecutableManager;
 import org.apache.iotdb.commons.utils.CommonDateTimeUtils;
+import org.apache.iotdb.commons.utils.PathUtils;
 import org.apache.iotdb.commons.utils.TimePartitionUtils;
 import org.apache.iotdb.confignode.rpc.thrift.TAlterLogicalViewReq;
 import org.apache.iotdb.confignode.rpc.thrift.TAlterOrDropTableReq;
@@ -129,6 +130,7 @@ import org.apache.iotdb.db.conf.IoTDBConfig;
 import org.apache.iotdb.db.conf.IoTDBDescriptor;
 import org.apache.iotdb.db.exception.BatchProcessException;
 import org.apache.iotdb.db.exception.StorageEngineException;
+import org.apache.iotdb.db.exception.metadata.DatabaseModelException;
 import org.apache.iotdb.db.exception.metadata.PathNotExistException;
 import org.apache.iotdb.db.exception.metadata.SchemaQuotaExceededException;
 import org.apache.iotdb.db.exception.metadata.table.TableNotExistsException;
@@ -414,7 +416,7 @@ public class ClusterConfigTaskExecutor implements 
IConfigTaskExecutor {
       final TShowDatabaseResp resp = client.showDatabase(req);
       // build TSBlock
       showDatabaseStatement.buildTSBlock(resp.getDatabaseInfoMap(), future);
-    } catch (final IOException | ClientManagerException | TException | 
IllegalPathException e) {
+    } catch (final IOException | ClientManagerException | TException e) {
       future.setException(e);
     }
     return future;
@@ -2930,18 +2932,19 @@ public class ClusterConfigTaskExecutor implements 
IConfigTaskExecutor {
   }
 
   @Override
-  public SettableFuture<ConfigTaskResult> showDatabases(ShowDB showDB) {
-    SettableFuture<ConfigTaskResult> future = SettableFuture.create();
+  public SettableFuture<ConfigTaskResult> showDatabases(final ShowDB showDB) {
+    final SettableFuture<ConfigTaskResult> future = SettableFuture.create();
     // Construct request using statement
-    List<String> databasePathPattern = Arrays.asList(ALL_RESULT_NODES);
-    try (ConfigNodeClient client =
+    final List<String> databasePathPattern = Arrays.asList(ALL_RESULT_NODES);
+    try (final ConfigNodeClient client =
         
CONFIG_NODE_CLIENT_MANAGER.borrowClient(ConfigNodeInfo.CONFIG_REGION_ID)) {
       // Send request to some API server
-      TGetDatabaseReq req = new TGetDatabaseReq(databasePathPattern, 
ALL_MATCH_SCOPE.serialize());
-      TShowDatabaseResp resp = client.showDatabase(req);
+      final TGetDatabaseReq req =
+          new TGetDatabaseReq(databasePathPattern, 
ALL_MATCH_SCOPE.serialize());
+      final TShowDatabaseResp resp = client.showDatabase(req);
       // build TSBlock
-      ShowDBTask.buildTSBlock(resp.getDatabaseInfoMap(), future);
-    } catch (IOException | ClientManagerException | TException e) {
+      ShowDBTask.buildTSBlock(resp.getDatabaseInfoMap(), future, 
showDB.isDetails());
+    } catch (final IOException | ClientManagerException | TException e) {
       future.setException(e);
     }
     return future;
@@ -2957,16 +2960,23 @@ public class ClusterConfigTaskExecutor implements 
IConfigTaskExecutor {
   }
 
   @Override
-  public SettableFuture<ConfigTaskResult> useDatabase(Use useDB, 
IClientSession clientSession) {
-    SettableFuture<ConfigTaskResult> future = SettableFuture.create();
+  public SettableFuture<ConfigTaskResult> useDatabase(
+      final Use useDB, final IClientSession clientSession) {
+    final SettableFuture<ConfigTaskResult> future = SettableFuture.create();
     // Construct request using statement
-    List<String> databasePathPattern = Arrays.asList(ROOT, 
useDB.getDatabaseId().getValue());
-    try (ConfigNodeClient client =
+    final List<String> databasePathPattern = Arrays.asList(ROOT, 
useDB.getDatabaseId().getValue());
+    try (final ConfigNodeClient client =
         
CONFIG_NODE_CLIENT_MANAGER.borrowClient(ConfigNodeInfo.CONFIG_REGION_ID)) {
       // Send request to some API server
-      TGetDatabaseReq req = new TGetDatabaseReq(databasePathPattern, 
ALL_MATCH_SCOPE.serialize());
-      TShowDatabaseResp resp = client.showDatabase(req);
+      final TGetDatabaseReq req =
+          new TGetDatabaseReq(databasePathPattern, 
ALL_MATCH_SCOPE.serialize());
+      final TShowDatabaseResp resp = client.showDatabase(req);
       if (!resp.getDatabaseInfoMap().isEmpty()) {
+        if (!resp.getDatabaseInfoMap()
+            
.get(PathUtils.qualifyDatabaseName(useDB.getDatabaseId().getValue()))
+            .isIsTableModel()) {
+          throw new DatabaseModelException(useDB.getDatabaseId().getValue(), 
false);
+        }
         clientSession.setDatabaseName(useDB.getDatabaseId().getValue());
         future.set(new ConfigTaskResult(TSStatusCode.SUCCESS_STATUS));
       } else {
@@ -2975,7 +2985,7 @@ public class ClusterConfigTaskExecutor implements 
IConfigTaskExecutor {
                 String.format("Unknown database %s", 
useDB.getDatabaseId().getValue()),
                 TSStatusCode.DATABASE_NOT_EXIST.getStatusCode()));
       }
-    } catch (IOException | ClientManagerException | TException e) {
+    } catch (final IOException | ClientManagerException | TException | 
DatabaseModelException e) {
       future.setException(e);
     }
     return future;
diff --git 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/execution/config/metadata/DatabaseSchemaTask.java
 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/execution/config/metadata/DatabaseSchemaTask.java
index 48eb140f094..ab9dee095aa 100644
--- 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/execution/config/metadata/DatabaseSchemaTask.java
+++ 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/execution/config/metadata/DatabaseSchemaTask.java
@@ -50,8 +50,8 @@ public class DatabaseSchemaTask implements IConfigTask {
 
   /** Construct DatabaseSchema according to statement */
   public static TDatabaseSchema constructDatabaseSchema(
-      DatabaseSchemaStatement databaseSchemaStatement) {
-    TDatabaseSchema databaseSchema = new TDatabaseSchema();
+      final DatabaseSchemaStatement databaseSchemaStatement) {
+    final TDatabaseSchema databaseSchema = new TDatabaseSchema();
     
databaseSchema.setName(databaseSchemaStatement.getDatabasePath().getFullPath());
     if (databaseSchemaStatement.getTtl() != null) {
       databaseSchema.setTTL(databaseSchemaStatement.getTtl());
@@ -72,6 +72,7 @@ public class DatabaseSchemaTask implements IConfigTask {
     if (databaseSchemaStatement.getDataRegionGroupNum() != null) {
       
databaseSchema.setMinDataRegionGroupNum(databaseSchemaStatement.getDataRegionGroupNum());
     }
+    databaseSchema.setIsTableModel(false);
     return databaseSchema;
   }
 }
diff --git 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/execution/config/metadata/ShowDatabaseTask.java
 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/execution/config/metadata/ShowDatabaseTask.java
index fcf3f9d13dc..34330c28c43 100644
--- 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/execution/config/metadata/ShowDatabaseTask.java
+++ 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/execution/config/metadata/ShowDatabaseTask.java
@@ -30,12 +30,12 @@ public class ShowDatabaseTask implements IConfigTask {
 
   private final ShowDatabaseStatement showDatabaseStatement;
 
-  public ShowDatabaseTask(ShowDatabaseStatement showDatabaseStatement) {
+  public ShowDatabaseTask(final ShowDatabaseStatement showDatabaseStatement) {
     this.showDatabaseStatement = showDatabaseStatement;
   }
 
   @Override
-  public ListenableFuture<ConfigTaskResult> execute(IConfigTaskExecutor 
configTaskExecutor)
+  public ListenableFuture<ConfigTaskResult> execute(final IConfigTaskExecutor 
configTaskExecutor)
       throws InterruptedException {
     return configTaskExecutor.showDatabase(showDatabaseStatement);
   }
diff --git 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/execution/config/metadata/relational/ShowDBTask.java
 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/execution/config/metadata/relational/ShowDBTask.java
index 0a72f18a3d2..64580a97528 100644
--- 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/execution/config/metadata/relational/ShowDBTask.java
+++ 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/execution/config/metadata/relational/ShowDBTask.java
@@ -45,38 +45,80 @@ public class ShowDBTask implements IConfigTask {
 
   private final ShowDB node;
 
-  public ShowDBTask(ShowDB node) {
+  public ShowDBTask(final ShowDB node) {
     this.node = node;
   }
 
   @Override
-  public ListenableFuture<ConfigTaskResult> execute(IConfigTaskExecutor 
configTaskExecutor)
+  public ListenableFuture<ConfigTaskResult> execute(final IConfigTaskExecutor 
configTaskExecutor)
       throws InterruptedException {
     return configTaskExecutor.showDatabases(node);
   }
 
   public static void buildTSBlock(
-      Map<String, TDatabaseInfo> storageGroupInfoMap, 
SettableFuture<ConfigTaskResult> future) {
+      final Map<String, TDatabaseInfo> storageGroupInfoMap,
+      final SettableFuture<ConfigTaskResult> future,
+      final boolean isDetails) {
+    if (isDetails) {
+      buildTSBlockForDetails(storageGroupInfoMap, future);
+    } else {
+      buildTSBlockForNonDetails(storageGroupInfoMap, future);
+    }
+  }
 
-    List<TSDataType> outputDataTypes =
+  private static void buildTSBlockForNonDetails(
+      final Map<String, TDatabaseInfo> storageGroupInfoMap,
+      final SettableFuture<ConfigTaskResult> future) {
+    final List<TSDataType> outputDataTypes =
         ColumnHeaderConstant.showDBColumnHeaders.stream()
             .map(ColumnHeader::getColumnType)
             .collect(Collectors.toList());
 
-    TsBlockBuilder builder = new TsBlockBuilder(outputDataTypes);
-    for (Map.Entry<String, TDatabaseInfo> entry : 
storageGroupInfoMap.entrySet()) {
-      String dbName = entry.getKey().substring(5);
-      TDatabaseInfo storageGroupInfo = entry.getValue();
+    final TsBlockBuilder builder = new TsBlockBuilder(outputDataTypes);
+    for (final Map.Entry<String, TDatabaseInfo> entry : 
storageGroupInfoMap.entrySet()) {
+      final String dbName = entry.getKey().substring(5);
+      final TDatabaseInfo storageGroupInfo = entry.getValue();
+      builder.getTimeColumnBuilder().writeLong(0L);
+      builder.getColumnBuilder(0).writeBinary(new Binary(dbName, 
TSFileConfig.STRING_CHARSET));
+
+      
builder.getColumnBuilder(1).writeInt(storageGroupInfo.getSchemaReplicationFactor());
+      
builder.getColumnBuilder(2).writeInt(storageGroupInfo.getDataReplicationFactor());
+      
builder.getColumnBuilder(3).writeLong(storageGroupInfo.getTimePartitionInterval());
+      builder.declarePosition();
+    }
+
+    final DatasetHeader datasetHeader = DatasetHeaderFactory.getShowDBHeader();
+    future.set(new ConfigTaskResult(TSStatusCode.SUCCESS_STATUS, 
builder.build(), datasetHeader));
+  }
+
+  private static void buildTSBlockForDetails(
+      final Map<String, TDatabaseInfo> storageGroupInfoMap,
+      final SettableFuture<ConfigTaskResult> future) {
+    final List<TSDataType> outputDataTypes =
+        ColumnHeaderConstant.showDBDetailsColumnHeaders.stream()
+            .map(ColumnHeader::getColumnType)
+            .collect(Collectors.toList());
+
+    final TsBlockBuilder builder = new TsBlockBuilder(outputDataTypes);
+    for (final Map.Entry<String, TDatabaseInfo> entry : 
storageGroupInfoMap.entrySet()) {
+      final String dbName = entry.getKey().substring(5);
+      final TDatabaseInfo storageGroupInfo = entry.getValue();
       builder.getTimeColumnBuilder().writeLong(0L);
       builder.getColumnBuilder(0).writeBinary(new Binary(dbName, 
TSFileConfig.STRING_CHARSET));
 
       
builder.getColumnBuilder(1).writeInt(storageGroupInfo.getSchemaReplicationFactor());
       
builder.getColumnBuilder(2).writeInt(storageGroupInfo.getDataReplicationFactor());
       
builder.getColumnBuilder(3).writeLong(storageGroupInfo.getTimePartitionInterval());
+      builder
+          .getColumnBuilder(4)
+          .writeBinary(
+              new Binary(
+                  storageGroupInfo.isIsTableModel() ? "TABLE" : "TREE",
+                  TSFileConfig.STRING_CHARSET));
       builder.declarePosition();
     }
 
-    DatasetHeader datasetHeader = DatasetHeaderFactory.getShowDBHeader();
+    final DatasetHeader datasetHeader = 
DatasetHeaderFactory.getShowDBDetailsHeader();
     future.set(new ConfigTaskResult(TSStatusCode.SUCCESS_STATUS, 
builder.build(), datasetHeader));
   }
 }
diff --git 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/metadata/fetcher/TableHeaderSchemaValidator.java
 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/metadata/fetcher/TableHeaderSchemaValidator.java
index d9e7663d19b..caf93f90573 100644
--- 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/metadata/fetcher/TableHeaderSchemaValidator.java
+++ 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/metadata/fetcher/TableHeaderSchemaValidator.java
@@ -192,13 +192,13 @@ public class TableHeaderSchemaValidator {
     return Optional.of(new TableSchema(tableSchema.getTableName(), 
resultColumnList));
   }
 
-  private void autoCreateTable(String database, TableSchema tableSchema) {
-    TsTable tsTable = new TsTable(tableSchema.getTableName());
+  private void autoCreateTable(final String database, final TableSchema 
tableSchema) {
+    final TsTable tsTable = new TsTable(tableSchema.getTableName());
     addColumnSchema(tableSchema.getColumns(), tsTable);
-    CreateTableTask createTableTask = new CreateTableTask(tsTable, database, 
true);
+    final CreateTableTask createTableTask = new CreateTableTask(tsTable, 
database, true);
     try {
-      ListenableFuture<ConfigTaskResult> future = 
createTableTask.execute(configTaskExecutor);
-      ConfigTaskResult result = future.get();
+      final ListenableFuture<ConfigTaskResult> future = 
createTableTask.execute(configTaskExecutor);
+      final ConfigTaskResult result = future.get();
       if (result.getStatusCode().getStatusCode() != 
TSStatusCode.SUCCESS_STATUS.getStatusCode()) {
         throw new RuntimeException(
             new IoTDBException(
diff --git 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/sql/ast/ShowDB.java
 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/sql/ast/ShowDB.java
index 8b53b5641f3..b8dd93e3562 100644
--- 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/sql/ast/ShowDB.java
+++ 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/sql/ast/ShowDB.java
@@ -26,16 +26,20 @@ import java.util.List;
 import static java.util.Objects.requireNonNull;
 
 public class ShowDB extends Statement {
-  public ShowDB() {
-    super(null);
-  }
 
-  public ShowDB(NodeLocation location) {
+  private final boolean isDetails;
+
+  public ShowDB(final NodeLocation location, final boolean isDetails) {
     super(requireNonNull(location, "location is null"));
+    this.isDetails = isDetails;
+  }
+
+  public boolean isDetails() {
+    return isDetails;
   }
 
   @Override
-  public <R, C> R accept(AstVisitor<R, C> visitor, C context) {
+  public <R, C> R accept(final AstVisitor<R, C> visitor, final C context) {
     return visitor.visitShowDB(this, context);
   }
 
@@ -50,7 +54,7 @@ public class ShowDB extends Statement {
   }
 
   @Override
-  public boolean equals(Object obj) {
+  public boolean equals(final Object obj) {
     if (this == obj) {
       return true;
     }
diff --git 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/sql/parser/AstBuilder.java
 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/sql/parser/AstBuilder.java
index 42adb9e49ea..282ef4554dc 100644
--- 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/sql/parser/AstBuilder.java
+++ 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/sql/parser/AstBuilder.java
@@ -257,8 +257,9 @@ public class AstBuilder extends 
RelationalSqlBaseVisitor<Node> {
   }
 
   @Override
-  public Node 
visitShowDatabasesStatement(RelationalSqlParser.ShowDatabasesStatementContext 
ctx) {
-    return new ShowDB(getLocation(ctx));
+  public Node visitShowDatabasesStatement(
+      final RelationalSqlParser.ShowDatabasesStatementContext ctx) {
+    return new ShowDB(getLocation(ctx), Objects.nonNull(ctx.DETAILS()));
   }
 
   @Override
diff --git 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/statement/metadata/ShowDatabaseStatement.java
 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/statement/metadata/ShowDatabaseStatement.java
index 356336bf5ad..4a50bb0e1fc 100644
--- 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/statement/metadata/ShowDatabaseStatement.java
+++ 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/statement/metadata/ShowDatabaseStatement.java
@@ -19,7 +19,6 @@
 
 package org.apache.iotdb.db.queryengine.plan.statement.metadata;
 
-import org.apache.iotdb.commons.exception.IllegalPathException;
 import org.apache.iotdb.commons.path.PartialPath;
 import org.apache.iotdb.confignode.rpc.thrift.TDatabaseInfo;
 import org.apache.iotdb.db.queryengine.common.header.ColumnHeader;
@@ -74,10 +73,10 @@ public class ShowDatabaseStatement extends ShowStatement 
implements IConfigState
   }
 
   public void buildTSBlock(
-      Map<String, TDatabaseInfo> storageGroupInfoMap, 
SettableFuture<ConfigTaskResult> future)
-      throws IllegalPathException {
+      final Map<String, TDatabaseInfo> storageGroupInfoMap,
+      final SettableFuture<ConfigTaskResult> future) {
 
-    List<TSDataType> outputDataTypes =
+    final List<TSDataType> outputDataTypes =
         isDetailed
             ? 
ColumnHeaderConstant.showStorageGroupsDetailColumnHeaders.stream()
                 .map(ColumnHeader::getColumnType)
@@ -86,10 +85,10 @@ public class ShowDatabaseStatement extends ShowStatement 
implements IConfigState
                 .map(ColumnHeader::getColumnType)
                 .collect(Collectors.toList());
 
-    TsBlockBuilder builder = new TsBlockBuilder(outputDataTypes);
-    for (Map.Entry<String, TDatabaseInfo> entry : 
storageGroupInfoMap.entrySet()) {
-      String storageGroup = entry.getKey();
-      TDatabaseInfo storageGroupInfo = entry.getValue();
+    final TsBlockBuilder builder = new TsBlockBuilder(outputDataTypes);
+    for (final Map.Entry<String, TDatabaseInfo> entry : 
storageGroupInfoMap.entrySet()) {
+      final String storageGroup = entry.getKey();
+      final TDatabaseInfo storageGroupInfo = entry.getValue();
 
       builder.getTimeColumnBuilder().writeLong(0L);
       builder
@@ -106,11 +105,17 @@ public class ShowDatabaseStatement extends ShowStatement 
implements IConfigState
         
builder.getColumnBuilder(8).writeInt(storageGroupInfo.getDataRegionNum());
         
builder.getColumnBuilder(9).writeInt(storageGroupInfo.getMinDataRegionNum());
         
builder.getColumnBuilder(10).writeInt(storageGroupInfo.getMaxDataRegionNum());
+        builder
+            .getColumnBuilder(11)
+            .writeBinary(
+                new Binary(
+                    storageGroupInfo.isIsTableModel() ? "TABLE" : "TREE",
+                    TSFileConfig.STRING_CHARSET));
       }
       builder.declarePosition();
     }
 
-    DatasetHeader datasetHeader = 
DatasetHeaderFactory.getShowStorageGroupHeader(isDetailed);
+    final DatasetHeader datasetHeader = 
DatasetHeaderFactory.getShowStorageGroupHeader(isDetailed);
     future.set(new ConfigTaskResult(TSStatusCode.SUCCESS_STATUS, 
builder.build(), datasetHeader));
   }
 
diff --git 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/schemaengine/table/DataNodeTableCache.java
 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/schemaengine/table/DataNodeTableCache.java
index 9b8ed5ddbdf..4ada1b6b95e 100644
--- 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/schemaengine/table/DataNodeTableCache.java
+++ 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/schemaengine/table/DataNodeTableCache.java
@@ -369,12 +369,14 @@ public class DataNodeTableCache implements ITableCache {
     for (final Map.Entry<String, ? extends Map<String, ?>> dbEntry : 
tableMap.entrySet()) {
       final String database = dbEntry.getKey();
       if (!(path.startsWith(database, dbStartIndex)
+          && path.length() > dbStartIndex + database.length()
           && path.charAt(dbStartIndex + database.length()) == PATH_SEPARATOR)) 
{
         continue;
       }
       final int tableStartIndex = dbStartIndex + database.length() + 1;
       for (final String tableName : dbEntry.getValue().keySet()) {
         if (path.startsWith(tableName, tableStartIndex)
+            && path.length() > tableStartIndex + tableName.length()
             && path.charAt(tableStartIndex + tableName.length()) == 
PATH_SEPARATOR) {
           return new Pair<>(database, tableName);
         }
diff --git 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/service/metrics/IoTDBInternalLocalReporter.java
 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/service/metrics/IoTDBInternalLocalReporter.java
index 2b6478f7959..e6d37e49b9c 100644
--- 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/service/metrics/IoTDBInternalLocalReporter.java
+++ 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/service/metrics/IoTDBInternalLocalReporter.java
@@ -103,12 +103,7 @@ public class IoTDBInternalLocalReporter extends 
IoTDBInternalReporter {
           && showDatabaseResp.getDatabaseInfoMapSize() == 0) {
         TDatabaseSchema databaseSchema = new TDatabaseSchema();
         databaseSchema.setName(SchemaConstant.SYSTEM_DATABASE);
-        databaseSchema.setSchemaReplicationFactor(1);
-        databaseSchema.setDataReplicationFactor(1);
-        databaseSchema.setMaxSchemaRegionGroupNum(1);
-        databaseSchema.setMinSchemaRegionGroupNum(1);
-        databaseSchema.setMaxDataRegionGroupNum(1);
-        databaseSchema.setMinDataRegionGroupNum(1);
+        databaseSchema.setIsTableModel(false);
         TSStatus tsStatus = client.setDatabase(databaseSchema);
         if (TSStatusCode.SUCCESS_STATUS.getStatusCode() != tsStatus.getCode()) 
{
           LOGGER.error("IoTDBSessionReporter checkOrCreateDatabase failed.");
diff --git 
a/iotdb-core/datanode/src/test/java/org/apache/iotdb/db/queryengine/plan/analyze/cache/PartitionCacheTest.java
 
b/iotdb-core/datanode/src/test/java/org/apache/iotdb/db/queryengine/plan/analyze/cache/PartitionCacheTest.java
index c198c3971b4..725860eb70d 100644
--- 
a/iotdb-core/datanode/src/test/java/org/apache/iotdb/db/queryengine/plan/analyze/cache/PartitionCacheTest.java
+++ 
b/iotdb-core/datanode/src/test/java/org/apache/iotdb/db/queryengine/plan/analyze/cache/PartitionCacheTest.java
@@ -32,6 +32,7 @@ import 
org.apache.iotdb.commons.partition.executor.SeriesPartitionExecutor;
 import org.apache.iotdb.db.auth.AuthorityChecker;
 import org.apache.iotdb.db.conf.IoTDBConfig;
 import org.apache.iotdb.db.conf.IoTDBDescriptor;
+import org.apache.iotdb.db.exception.metadata.DatabaseModelException;
 import 
org.apache.iotdb.db.queryengine.plan.analyze.cache.partition.PartitionCache;
 
 import org.apache.tsfile.file.metadata.IDeviceID;
@@ -48,6 +49,8 @@ import java.util.HashSet;
 import java.util.List;
 import java.util.Map;
 import java.util.Set;
+import java.util.function.Function;
+import java.util.stream.Collectors;
 
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertFalse;
@@ -148,7 +151,8 @@ public class PartitionCacheTest {
   @Before
   public void setUp() throws Exception {
     partitionCache = new PartitionCache();
-    partitionCache.updateDatabaseCache(storageGroups);
+    partitionCache.updateDatabaseCache(
+        storageGroups.stream().collect(Collectors.toMap(Function.identity(), k 
-> false)));
     partitionCache.updateSchemaPartitionCache(schemaPartitionTable);
     partitionCache.updateDataPartitionCache(dataPartitionTable);
     partitionCache.updateGroupIdToReplicaSetMap(100, 
consensusGroupIdToRegionReplicaSet);
@@ -160,7 +164,7 @@ public class PartitionCacheTest {
   }
 
   @Test
-  public void testStorageGroupCache() {
+  public void testStorageGroupCache() throws DatabaseModelException {
     Map<String, List<IDeviceID>> storageGroupToDeviceMap;
     Map<IDeviceID, String> deviceToStorageGroupMap;
     // test devices in one database
diff --git 
a/iotdb-core/relational-grammar/src/main/antlr4/org/apache/iotdb/db/relational/grammar/sql/RelationalSql.g4
 
b/iotdb-core/relational-grammar/src/main/antlr4/org/apache/iotdb/db/relational/grammar/sql/RelationalSql.g4
index 30f57e994c6..6acfcf01657 100644
--- 
a/iotdb-core/relational-grammar/src/main/antlr4/org/apache/iotdb/db/relational/grammar/sql/RelationalSql.g4
+++ 
b/iotdb-core/relational-grammar/src/main/antlr4/org/apache/iotdb/db/relational/grammar/sql/RelationalSql.g4
@@ -125,7 +125,7 @@ useDatabaseStatement
     ;
 
 showDatabasesStatement
-    : SHOW DATABASES
+    : SHOW DATABASES (DETAILS)?
     ;
 
 createDbStatement
diff --git a/iotdb-protocol/thrift-confignode/src/main/thrift/confignode.thrift 
b/iotdb-protocol/thrift-confignode/src/main/thrift/confignode.thrift
index ffe7859c7bb..8f8727fbf0a 100644
--- a/iotdb-protocol/thrift-confignode/src/main/thrift/confignode.thrift
+++ b/iotdb-protocol/thrift-confignode/src/main/thrift/confignode.thrift
@@ -210,6 +210,7 @@ struct TDatabaseSchema {
     8: optional i32 minDataRegionGroupNum
     9: optional i32 maxDataRegionGroupNum
     10: optional i64 timePartitionOrigin
+    11: optional bool isTableModel
 }
 
 // Schema
@@ -595,6 +596,7 @@ struct TDatabaseInfo {
   10: required i32 minDataRegionNum
   11: required i32 maxDataRegionNum
   12: optional i64 timePartitionOrigin
+  13: optional bool isTableModel
 }
 
 struct TGetDatabaseReq {


Reply via email to