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

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


The following commit(s) were added to refs/heads/ty/TableModelGrammar by this 
push:
     new 12641415a96 [Table Model] Create table device (#12746)
12641415a96 is described below

commit 12641415a962f34df66034db811f9e71484055f7
Author: Marcos_Zyk <[email protected]>
AuthorDate: Tue Jun 18 19:36:43 2024 +0800

    [Table Model] Create table device (#12746)
---
 .../schemaregion/SchemaExecutionVisitor.java       |  17 ++
 .../plan/analyze/ClusterPartitionFetcher.java      |  19 ++
 .../db/queryengine/plan/analyze/IAnalysis.java     |   2 +
 .../plan/analyze/IPartitionFetcher.java            |  32 +++
 .../plan/planner/plan/node/PlanVisitor.java        |   5 +
 .../plan/relational/analyzer/Analysis.java         |  11 +-
 .../relational/analyzer/StatementAnalyzer.java     |   9 +
 .../plan/relational/metadata/Metadata.java         |  32 +++
 .../relational/metadata/TableMetadataImpl.java     |  24 ++
 .../plan/relational/planner/LogicalPlanner.java    |  30 ++
 .../planner/node/CreateTableDeviceNode.java        | 316 +++++++++++++++++++++
 .../plan/relational/sql/ast/AstVisitor.java        |   4 +
 .../plan/relational/sql/ast/CreateDevice.java      | 116 ++++++++
 .../schemaengine/schemaregion/ISchemaRegion.java   |   5 +-
 .../attribute/DeviceAttributeStore.java            |  19 +-
 .../attribute/IDeviceAttributeStore.java           |   4 +-
 .../schemaregion/impl/SchemaRegionMemoryImpl.java  |   6 +-
 .../schemaregion/impl/SchemaRegionPBTreeImpl.java  |   5 +-
 .../mtree/impl/mem/MTreeBelowSGMemoryImpl.java     |  23 +-
 .../schemaRegion/SchemaRegionTestUtil.java         |   7 +-
 .../plan/analyze/FakePartitionFetcherImpl.java     |  18 ++
 .../plan/planner/distribution/Util.java            |  17 ++
 .../plan/planner/distribution/Util2.java           |  17 ++
 .../plan/relational/analyzer/AnalyzerTest.java     |  17 ++
 .../plan/relational/analyzer/TestMatadata.java     |  18 ++
 .../iotdb/commons/partition/SchemaPartition.java   |  15 +
 26 files changed, 761 insertions(+), 27 deletions(-)

diff --git 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/consensus/statemachine/schemaregion/SchemaExecutionVisitor.java
 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/consensus/statemachine/schemaregion/SchemaExecutionVisitor.java
index e82ed922045..0ef64674d11 100644
--- 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/consensus/statemachine/schemaregion/SchemaExecutionVisitor.java
+++ 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/consensus/statemachine/schemaregion/SchemaExecutionVisitor.java
@@ -56,6 +56,7 @@ import 
org.apache.iotdb.db.queryengine.plan.planner.plan.node.metedata.write.vie
 import 
org.apache.iotdb.db.queryengine.plan.planner.plan.node.pipe.PipeEnrichedNonWritePlanNode;
 import 
org.apache.iotdb.db.queryengine.plan.planner.plan.node.pipe.PipeEnrichedWritePlanNode;
 import 
org.apache.iotdb.db.queryengine.plan.planner.plan.node.pipe.PipeOperateSchemaQueueNode;
+import 
org.apache.iotdb.db.queryengine.plan.relational.planner.node.CreateTableDeviceNode;
 import org.apache.iotdb.db.schemaengine.schemaregion.ISchemaRegion;
 import 
org.apache.iotdb.db.schemaengine.schemaregion.write.req.ICreateAlignedTimeSeriesPlan;
 import 
org.apache.iotdb.db.schemaengine.schemaregion.write.req.ICreateTimeSeriesPlan;
@@ -525,6 +526,22 @@ public class SchemaExecutionVisitor extends 
PlanVisitor<TSStatus, ISchemaRegion>
     }
   }
 
+  @Override
+  public TSStatus visitCreateTableDevice(CreateTableDeviceNode node, 
ISchemaRegion schemaRegion) {
+    try {
+      // todo implement storage for device of diverse data types
+      schemaRegion.createTableDevice(
+          node.getTableName(),
+          node.getDeviceIdList(),
+          node.getAttributeNameList(),
+          node.getAttributeValueList());
+      return RpcUtils.getStatus(TSStatusCode.SUCCESS_STATUS);
+    } catch (MetadataException e) {
+      logger.error(e.getMessage(), e);
+      return RpcUtils.getStatus(e.getErrorCode(), e.getMessage());
+    }
+  }
+
   @Override
   public TSStatus visitPipeEnrichedWritePlanNode(
       final PipeEnrichedWritePlanNode node, final ISchemaRegion schemaRegion) {
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 1f9a47e6c10..eb6db8e6051 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
@@ -293,6 +293,25 @@ public class ClusterPartitionFetcher implements 
IPartitionFetcher {
     partitionCache.invalidAllCache();
   }
 
+  @Override
+  public SchemaPartition getOrCreateSchemaPartition(
+      String database, List<IDeviceID> deviceIDList, String userName) {
+    // todo implement related logic @Potato
+    throw new UnsupportedOperationException("Unsupported schema partition 
operation");
+  }
+
+  @Override
+  public SchemaPartition getSchemaPartition(String database, List<IDeviceID> 
deviceIDList) {
+    // todo implement related logic @Potato
+    throw new UnsupportedOperationException("Unsupported schema partition 
operation");
+  }
+
+  @Override
+  public SchemaPartition getSchemaPartition(String database) {
+    // todo implement related logic @Potato
+    throw new UnsupportedOperationException("Unsupported schema partition 
operation");
+  }
+
   /** split data partition query param by database */
   private Map<String, List<DataPartitionQueryParam>> 
splitDataPartitionQueryParam(
       List<DataPartitionQueryParam> dataPartitionQueryParams,
diff --git 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/analyze/IAnalysis.java
 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/analyze/IAnalysis.java
index 4adcd7e298c..70cff5c0779 100644
--- 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/analyze/IAnalysis.java
+++ 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/analyze/IAnalysis.java
@@ -51,6 +51,8 @@ public interface IAnalysis {
 
   SchemaPartition getSchemaPartitionInfo();
 
+  void setSchemaPartitionInfo(SchemaPartition schemaPartition);
+
   DataPartition getDataPartitionInfo();
 
   void setRedirectNodeList(List<TEndPoint> redirectNodeList);
diff --git 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/analyze/IPartitionFetcher.java
 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/analyze/IPartitionFetcher.java
index ecd88a9c647..2fddd356229 100644
--- 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/analyze/IPartitionFetcher.java
+++ 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/analyze/IPartitionFetcher.java
@@ -26,6 +26,8 @@ import org.apache.iotdb.commons.partition.SchemaPartition;
 import org.apache.iotdb.commons.path.PathPatternTree;
 import org.apache.iotdb.mpp.rpc.thrift.TRegionRouteReq;
 
+import org.apache.tsfile.file.metadata.IDeviceID;
+
 import java.util.List;
 import java.util.Map;
 
@@ -90,4 +92,34 @@ public interface IPartitionFetcher {
 
   /** Invalid all partition cache */
   void invalidAllCache();
+
+  // ======================== Table Model Schema Partition Interface 
========================
+  /**
+   * Get or create schema partition, used in data insertion with 
enable_auto_create_schema is true.
+   * if schemaPartition does not exist, then automatically create.
+   *
+   * <p>The database shall start with "root.". Concat this to a user-provided 
db name if necessary.
+   *
+   * <p>The device id shall be [table, seg1, ....]
+   */
+  SchemaPartition getOrCreateSchemaPartition(
+      String database, List<IDeviceID> deviceIDList, String userName);
+
+  /**
+   * For data query with completed id.
+   *
+   * <p>The database shall start with "root.". Concat this to a user-provided 
db name if necessary.
+   *
+   * <p>The device id shall be [table, seg1, ....]
+   */
+  SchemaPartition getSchemaPartition(String database, List<IDeviceID> 
deviceIDList);
+
+  /**
+   * For data query with partial device id conditions.
+   *
+   * <p>The database shall start with "root.". Concat this to a user-provided 
db name if necessary.
+   *
+   * <p>The device id shall be [table, seg1, ....]
+   */
+  SchemaPartition getSchemaPartition(String database);
 }
diff --git 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/planner/plan/node/PlanVisitor.java
 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/planner/plan/node/PlanVisitor.java
index 2e5a61b7a83..11d504b4cc4 100644
--- 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/planner/plan/node/PlanVisitor.java
+++ 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/planner/plan/node/PlanVisitor.java
@@ -112,6 +112,7 @@ import 
org.apache.iotdb.db.queryengine.plan.planner.plan.node.write.InsertRowNod
 import 
org.apache.iotdb.db.queryengine.plan.planner.plan.node.write.InsertRowsNode;
 import 
org.apache.iotdb.db.queryengine.plan.planner.plan.node.write.InsertRowsOfOneDeviceNode;
 import 
org.apache.iotdb.db.queryengine.plan.planner.plan.node.write.InsertTabletNode;
+import 
org.apache.iotdb.db.queryengine.plan.relational.planner.node.CreateTableDeviceNode;
 import 
org.apache.iotdb.db.queryengine.plan.relational.planner.node.MergeSortNode;
 import 
org.apache.iotdb.db.queryengine.plan.relational.planner.node.TableScanNode;
 
@@ -484,6 +485,10 @@ public abstract class PlanVisitor<R, C> {
     return visitPlan(node, context);
   }
 
+  public R visitCreateTableDevice(CreateTableDeviceNode node, C context) {
+    return visitPlan(node, context);
+  }
+
   
/////////////////////////////////////////////////////////////////////////////////////////////////
   // Data Write Node
   
/////////////////////////////////////////////////////////////////////////////////////////////////
diff --git 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/analyzer/Analysis.java
 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/analyzer/Analysis.java
index 4d019248d86..749e40a3abf 100644
--- 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/analyzer/Analysis.java
+++ 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/analyzer/Analysis.java
@@ -158,6 +158,8 @@ public class Analysis implements IAnalysis {
 
   private DataPartition dataPartition;
 
+  private SchemaPartition schemaPartition;
+
   private DatasetHeader respDatasetHeader;
 
   private boolean finishQueryAfterAnalyze;
@@ -653,7 +655,12 @@ public class Analysis implements IAnalysis {
 
   @Override
   public SchemaPartition getSchemaPartitionInfo() {
-    throw new UnsupportedOperationException();
+    return schemaPartition;
+  }
+
+  @Override
+  public void setSchemaPartitionInfo(SchemaPartition schemaPartition) {
+    this.schemaPartition = schemaPartition;
   }
 
   @Override
@@ -673,7 +680,7 @@ public class Analysis implements IAnalysis {
 
   @Override
   public TimePredicate getCovertedTimePredicate() {
-    throw new UnsupportedOperationException();
+    return null;
   }
 
   public static final class AccessControlInfo {
diff --git 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/analyzer/StatementAnalyzer.java
 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/analyzer/StatementAnalyzer.java
index 1fcc4e89024..25bf3cd5f83 100644
--- 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/analyzer/StatementAnalyzer.java
+++ 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/analyzer/StatementAnalyzer.java
@@ -36,6 +36,7 @@ import 
org.apache.iotdb.db.queryengine.plan.relational.sql.ast.AllColumns;
 import org.apache.iotdb.db.queryengine.plan.relational.sql.ast.AllRows;
 import org.apache.iotdb.db.queryengine.plan.relational.sql.ast.AstVisitor;
 import org.apache.iotdb.db.queryengine.plan.relational.sql.ast.CreateDB;
+import org.apache.iotdb.db.queryengine.plan.relational.sql.ast.CreateDevice;
 import org.apache.iotdb.db.queryengine.plan.relational.sql.ast.CreateIndex;
 import org.apache.iotdb.db.queryengine.plan.relational.sql.ast.CreateTable;
 import org.apache.iotdb.db.queryengine.plan.relational.sql.ast.Delete;
@@ -231,6 +232,9 @@ public class StatementAnalyzer {
     @Override
     public Scope process(Node node, Optional<Scope> scope) {
       Scope returnScope = super.process(node, scope);
+      if (node instanceof CreateDevice) {
+        return returnScope;
+      }
       checkState(
           returnScope.getOuterQueryParent().equals(outerQueryScope),
           "result scope should have outer query scope equal with parameter 
outer query scope");
@@ -2420,6 +2424,11 @@ public class StatementAnalyzer {
 
       return scopeBuilder;
     }
+
+    @Override
+    protected Scope visitCreateDevice(CreateDevice node, Optional<Scope> 
context) {
+      return null;
+    }
   }
 
   private static boolean hasScopeAsLocalParent(Scope root, Scope parent) {
diff --git 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/metadata/Metadata.java
 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/metadata/Metadata.java
index dc66581b74c..b369347bdff 100644
--- 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/metadata/Metadata.java
+++ 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/metadata/Metadata.java
@@ -19,6 +19,7 @@
 
 package org.apache.iotdb.db.queryengine.plan.relational.metadata;
 
+import org.apache.iotdb.commons.partition.SchemaPartition;
 import org.apache.iotdb.db.queryengine.common.MPPQueryContext;
 import org.apache.iotdb.db.queryengine.common.SessionInfo;
 import org.apache.iotdb.db.queryengine.plan.relational.function.OperatorType;
@@ -27,6 +28,7 @@ import 
org.apache.iotdb.db.queryengine.plan.relational.sql.ast.Expression;
 import 
org.apache.iotdb.db.queryengine.plan.relational.type.TypeNotFoundException;
 import org.apache.iotdb.db.queryengine.plan.relational.type.TypeSignature;
 
+import org.apache.tsfile.file.metadata.IDeviceID;
 import org.apache.tsfile.read.common.type.Type;
 
 import java.util.List;
@@ -97,4 +99,34 @@ public interface Metadata {
    * <p>If validation failed, a SemanticException will be thrown.
    */
   void validateDeviceSchema(ITableDeviceSchemaValidation schemaValidation, 
MPPQueryContext context);
+
+  // ======================== Table Model Schema Partition Interface 
========================
+  /**
+   * Get or create schema partition, used in data insertion with 
enable_auto_create_schema is true.
+   * if schemaPartition does not exist, then automatically create.
+   *
+   * <p>The database shall start with "root.". Concat this to a user-provided 
db name if necessary.
+   *
+   * <p>The device id shall be [table, seg1, ....]
+   */
+  SchemaPartition getOrCreateSchemaPartition(
+      String database, List<IDeviceID> deviceIDList, String userName);
+
+  /**
+   * For data query with completed id.
+   *
+   * <p>The database is a user-provided db name.
+   *
+   * <p>The device id shall be [table, seg1, ....]
+   */
+  SchemaPartition getSchemaPartition(String database, List<IDeviceID> 
deviceIDList);
+
+  /**
+   * For data query with partial device id conditions.
+   *
+   * <p>The database is a user-provided db name.
+   *
+   * <p>The device id shall be [table, seg1, ....]
+   */
+  SchemaPartition getSchemaPartition(String database);
 }
diff --git 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/metadata/TableMetadataImpl.java
 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/metadata/TableMetadataImpl.java
index f3ff0b59834..ea7c031b5ff 100644
--- 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/metadata/TableMetadataImpl.java
+++ 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/metadata/TableMetadataImpl.java
@@ -19,11 +19,14 @@
 
 package org.apache.iotdb.db.queryengine.plan.relational.metadata;
 
+import org.apache.iotdb.commons.partition.SchemaPartition;
 import org.apache.iotdb.commons.udf.builtin.BuiltinAggregationFunction;
 import org.apache.iotdb.commons.udf.builtin.BuiltinScalarFunction;
 import org.apache.iotdb.db.exception.sql.SemanticException;
 import org.apache.iotdb.db.queryengine.common.MPPQueryContext;
 import org.apache.iotdb.db.queryengine.common.SessionInfo;
+import org.apache.iotdb.db.queryengine.plan.analyze.ClusterPartitionFetcher;
+import org.apache.iotdb.db.queryengine.plan.analyze.IPartitionFetcher;
 import org.apache.iotdb.db.queryengine.plan.relational.function.OperatorType;
 import org.apache.iotdb.db.queryengine.plan.relational.security.AccessControl;
 import org.apache.iotdb.db.queryengine.plan.relational.sql.ast.Expression;
@@ -43,6 +46,8 @@ import java.util.List;
 import java.util.Locale;
 import java.util.Optional;
 
+import static org.apache.iotdb.commons.conf.IoTDBConstant.PATH_ROOT;
+import static org.apache.iotdb.commons.conf.IoTDBConstant.PATH_SEPARATOR;
 import static org.apache.tsfile.read.common.type.BinaryType.TEXT;
 import static org.apache.tsfile.read.common.type.BooleanType.BOOLEAN;
 import static org.apache.tsfile.read.common.type.DoubleType.DOUBLE;
@@ -54,6 +59,8 @@ public class TableMetadataImpl implements Metadata {
 
   private final TypeManager typeManager = new InternalTypeManager();
 
+  private final IPartitionFetcher partitionFetcher = 
ClusterPartitionFetcher.getInstance();
+
   @Override
   public boolean tableExists(QualifiedObjectName name) {
     return false;
@@ -288,6 +295,23 @@ public class TableMetadataImpl implements Metadata {
     throw new UnsupportedOperationException();
   }
 
+  @Override
+  public SchemaPartition getOrCreateSchemaPartition(
+      String database, List<IDeviceID> deviceIDList, String userName) {
+    return partitionFetcher.getOrCreateSchemaPartition(
+        PATH_ROOT + PATH_SEPARATOR + database, deviceIDList, userName);
+  }
+
+  @Override
+  public SchemaPartition getSchemaPartition(String database, List<IDeviceID> 
deviceIDList) {
+    return partitionFetcher.getSchemaPartition(PATH_ROOT + PATH_SEPARATOR + 
database, deviceIDList);
+  }
+
+  @Override
+  public SchemaPartition getSchemaPartition(String database) {
+    return partitionFetcher.getSchemaPartition(PATH_ROOT + PATH_SEPARATOR + 
database);
+  }
+
   public static boolean isTwoNumericType(List<? extends Type> argumentTypes) {
     return argumentTypes.size() == 2
         && isNumericType(argumentTypes.get(0))
diff --git 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/planner/LogicalPlanner.java
 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/planner/LogicalPlanner.java
index a7537c4e680..b4e63779f12 100644
--- 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/planner/LogicalPlanner.java
+++ 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/planner/LogicalPlanner.java
@@ -14,18 +14,21 @@
 
 package org.apache.iotdb.db.queryengine.plan.relational.planner;
 
+import org.apache.iotdb.commons.partition.SchemaPartition;
 import org.apache.iotdb.db.queryengine.common.MPPQueryContext;
 import org.apache.iotdb.db.queryengine.common.SessionInfo;
 import org.apache.iotdb.db.queryengine.common.header.ColumnHeader;
 import org.apache.iotdb.db.queryengine.common.header.DatasetHeader;
 import org.apache.iotdb.db.queryengine.execution.warnings.WarningCollector;
 import org.apache.iotdb.db.queryengine.plan.analyze.IPartitionFetcher;
+import org.apache.iotdb.db.queryengine.plan.analyze.QueryType;
 import org.apache.iotdb.db.queryengine.plan.planner.plan.LogicalQueryPlan;
 import org.apache.iotdb.db.queryengine.plan.planner.plan.node.PlanNode;
 import org.apache.iotdb.db.queryengine.plan.relational.analyzer.Analysis;
 import org.apache.iotdb.db.queryengine.plan.relational.analyzer.Field;
 import org.apache.iotdb.db.queryengine.plan.relational.analyzer.RelationType;
 import org.apache.iotdb.db.queryengine.plan.relational.metadata.Metadata;
+import 
org.apache.iotdb.db.queryengine.plan.relational.planner.node.CreateTableDeviceNode;
 import org.apache.iotdb.db.queryengine.plan.relational.planner.node.OutputNode;
 import 
org.apache.iotdb.db.queryengine.plan.relational.planner.optimizations.FilterScanCombine;
 import 
org.apache.iotdb.db.queryengine.plan.relational.planner.optimizations.IndexScan;
@@ -33,6 +36,7 @@ import 
org.apache.iotdb.db.queryengine.plan.relational.planner.optimizations.Pru
 import 
org.apache.iotdb.db.queryengine.plan.relational.planner.optimizations.RelationalPlanOptimizer;
 import 
org.apache.iotdb.db.queryengine.plan.relational.planner.optimizations.RemoveRedundantIdentityProjections;
 import 
org.apache.iotdb.db.queryengine.plan.relational.planner.optimizations.SimplifyExpressions;
+import org.apache.iotdb.db.queryengine.plan.relational.sql.ast.CreateDevice;
 import org.apache.iotdb.db.queryengine.plan.relational.sql.ast.Explain;
 import org.apache.iotdb.db.queryengine.plan.relational.sql.ast.Query;
 import org.apache.iotdb.db.queryengine.plan.relational.sql.ast.Statement;
@@ -96,6 +100,9 @@ public class LogicalPlanner {
   }
 
   private PlanNode planStatement(Analysis analysis, Statement statement) {
+    if (statement instanceof CreateDevice) {
+      return planCreateDevice((CreateDevice) statement, analysis);
+    }
     return createOutputPlan(planStatementWithoutOutput(analysis, statement), 
analysis);
   }
 
@@ -181,4 +188,27 @@ public class LogicalPlanner {
     OPTIMIZED,
     OPTIMIZED_AND_VALIDATED
   }
+
+  private PlanNode planCreateDevice(CreateDevice statement, Analysis analysis) 
{
+    context.setQueryType(QueryType.WRITE);
+
+    CreateTableDeviceNode node =
+        new CreateTableDeviceNode(
+            context.getQueryId().genPlanNodeId(),
+            statement.getDatabase(),
+            statement.getTable(),
+            statement.getDeviceIdList(),
+            statement.getAttributeNameList(),
+            statement.getAttributeValueList());
+
+    analysis.setStatement(statement);
+    SchemaPartition partition =
+        metadata.getOrCreateSchemaPartition(
+            statement.getDatabase(),
+            node.getPartitionKeyList(),
+            context.getSession().getUserName());
+    analysis.setSchemaPartitionInfo(partition);
+
+    return node;
+  }
 }
diff --git 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/planner/node/CreateTableDeviceNode.java
 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/planner/node/CreateTableDeviceNode.java
new file mode 100644
index 00000000000..13209c2274f
--- /dev/null
+++ 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/planner/node/CreateTableDeviceNode.java
@@ -0,0 +1,316 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.iotdb.db.queryengine.plan.relational.planner.node;
+
+import org.apache.iotdb.common.rpc.thrift.TRegionReplicaSet;
+import org.apache.iotdb.db.queryengine.plan.analyze.IAnalysis;
+import org.apache.iotdb.db.queryengine.plan.planner.plan.node.PlanNode;
+import org.apache.iotdb.db.queryengine.plan.planner.plan.node.PlanNodeId;
+import org.apache.iotdb.db.queryengine.plan.planner.plan.node.PlanNodeType;
+import org.apache.iotdb.db.queryengine.plan.planner.plan.node.PlanVisitor;
+import org.apache.iotdb.db.queryengine.plan.planner.plan.node.WritePlanNode;
+
+import org.apache.tsfile.file.metadata.IDeviceID;
+import org.apache.tsfile.utils.ReadWriteIOUtils;
+
+import java.io.DataOutputStream;
+import java.io.IOException;
+import java.nio.ByteBuffer;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Objects;
+
+import static org.apache.iotdb.commons.conf.IoTDBConstant.PATH_ROOT;
+import static org.apache.iotdb.commons.conf.IoTDBConstant.PATH_SEPARATOR;
+
+public class CreateTableDeviceNode extends WritePlanNode {
+
+  private final String database;
+
+  private final String tableName;
+
+  private final List<Object[]> deviceIdList;
+
+  private final List<String> attributeNameList;
+
+  private final List<Object[]> attributeValueList;
+
+  private TRegionReplicaSet regionReplicaSet;
+
+  private transient List<IDeviceID> partitionKeyList;
+
+  public CreateTableDeviceNode(
+      PlanNodeId id,
+      String database,
+      String tableName,
+      List<Object[]> deviceIdList,
+      List<String> attributeNameList,
+      List<Object[]> attributeValueList) {
+    super(id);
+    this.database = database;
+    this.tableName = tableName;
+    this.deviceIdList = deviceIdList;
+    this.attributeNameList = attributeNameList;
+    this.attributeValueList = attributeValueList;
+  }
+
+  public CreateTableDeviceNode(
+      PlanNodeId id,
+      TRegionReplicaSet regionReplicaSet,
+      String database,
+      String tableName,
+      List<Object[]> deviceIdList,
+      List<String> attributeNameList,
+      List<Object[]> attributeValueList) {
+    super(id);
+    this.database = database;
+    this.tableName = tableName;
+    this.deviceIdList = deviceIdList;
+    this.attributeNameList = attributeNameList;
+    this.attributeValueList = attributeValueList;
+    this.regionReplicaSet = regionReplicaSet;
+  }
+
+  @Override
+  public PlanNodeType getType() {
+    return PlanNodeType.CREATE_TABLE_DEVICE;
+  }
+
+  public String getDatabase() {
+    return database;
+  }
+
+  public String getTableName() {
+    return tableName;
+  }
+
+  public List<Object[]> getDeviceIdList() {
+    return deviceIdList;
+  }
+
+  public List<String> getAttributeNameList() {
+    return attributeNameList;
+  }
+
+  public List<Object[]> getAttributeValueList() {
+    return attributeValueList;
+  }
+
+  @Override
+  public TRegionReplicaSet getRegionReplicaSet() {
+    return regionReplicaSet;
+  }
+
+  public List<IDeviceID> getPartitionKeyList() {
+    if (partitionKeyList == null) {
+      List<IDeviceID> partitionKeyList = new ArrayList<>();
+      for (Object[] rawId : deviceIdList) {
+        String[] partitionKey = new String[rawId.length + 1];
+        partitionKey[0] = tableName;
+        for (int i = 0; i < rawId.length; i++) {
+          partitionKey[i + 1] = Objects.toString(rawId[i].toString());
+        }
+        
partitionKeyList.add(IDeviceID.Factory.DEFAULT_FACTORY.create(partitionKey));
+      }
+      this.partitionKeyList = partitionKeyList;
+    }
+    return partitionKeyList;
+  }
+
+  @Override
+  public List<PlanNode> getChildren() {
+    return new ArrayList<>();
+  }
+
+  @Override
+  public void addChild(PlanNode child) {}
+
+  @Override
+  public PlanNode clone() {
+    return new CreateTableDeviceNode(
+        getPlanNodeId(),
+        regionReplicaSet,
+        database,
+        tableName,
+        deviceIdList,
+        attributeNameList,
+        attributeValueList);
+  }
+
+  @Override
+  public int allowedChildCount() {
+    return 0;
+  }
+
+  @Override
+  public List<String> getOutputColumnNames() {
+    return null;
+  }
+
+  @Override
+  protected void serializeAttributes(ByteBuffer byteBuffer) {
+    PlanNodeType.CREATE_TABLE_DEVICE.serialize(byteBuffer);
+    ReadWriteIOUtils.write(database, byteBuffer);
+    ReadWriteIOUtils.write(tableName, byteBuffer);
+    ReadWriteIOUtils.write(deviceIdList.size(), byteBuffer);
+    for (Object[] deviceId : deviceIdList) {
+      ReadWriteIOUtils.write(deviceId.length, byteBuffer);
+      for (Object idSeg : deviceId) {
+        ReadWriteIOUtils.writeObject(idSeg, byteBuffer);
+      }
+    }
+    ReadWriteIOUtils.write(attributeNameList.size(), byteBuffer);
+    for (String attributeName : attributeNameList) {
+      ReadWriteIOUtils.write(attributeName, byteBuffer);
+    }
+    ReadWriteIOUtils.write(attributeValueList.size(), byteBuffer);
+    for (Object[] deviceValueList : attributeValueList) {
+      for (Object value : deviceValueList) {
+        ReadWriteIOUtils.writeObject(value, byteBuffer);
+      }
+    }
+  }
+
+  @Override
+  protected void serializeAttributes(DataOutputStream stream) throws 
IOException {
+    PlanNodeType.CREATE_TABLE_DEVICE.serialize(stream);
+    ReadWriteIOUtils.write(database, stream);
+    ReadWriteIOUtils.write(tableName, stream);
+    ReadWriteIOUtils.write(deviceIdList.size(), stream);
+    for (Object[] deviceId : deviceIdList) {
+      ReadWriteIOUtils.write(deviceId.length, stream);
+      for (Object idSeg : deviceId) {
+        ReadWriteIOUtils.writeObject(idSeg, stream);
+      }
+    }
+    ReadWriteIOUtils.write(attributeNameList.size(), stream);
+    for (String attributeName : attributeNameList) {
+      ReadWriteIOUtils.write(attributeName, stream);
+    }
+    for (Object[] deviceValueList : attributeValueList) {
+      for (Object value : deviceValueList) {
+        ReadWriteIOUtils.writeObject(value, stream);
+      }
+    }
+  }
+
+  public static CreateTableDeviceNode deserialize(ByteBuffer buffer) {
+    String database = ReadWriteIOUtils.readString(buffer);
+    String tableName = ReadWriteIOUtils.readString(buffer);
+    int deviceNum = ReadWriteIOUtils.readInt(buffer);
+    List<Object[]> deviceIdList = new ArrayList<>(deviceNum);
+    int length;
+    Object[] deviceId;
+    for (int i = 0; i < deviceNum; i++) {
+      length = ReadWriteIOUtils.readInt(buffer);
+      deviceId = new Object[length];
+      for (int j = 0; j < length; j++) {
+        deviceId[j] = ReadWriteIOUtils.readObject(buffer);
+      }
+      deviceIdList.add(deviceId);
+    }
+    int attributeNameNum = ReadWriteIOUtils.readInt(buffer);
+    List<String> attributeNameList = new ArrayList<>(attributeNameNum);
+    for (int i = 0; i < attributeNameNum; i++) {
+      attributeNameList.add(ReadWriteIOUtils.readString(buffer));
+    }
+    List<Object[]> attributeValueList = new ArrayList<>(deviceNum);
+    Object[] deviceAttributeValues;
+    for (int i = 0; i < deviceNum; i++) {
+      deviceAttributeValues = new Object[attributeNameNum];
+      for (int j = 0; j < attributeNameNum; j++) {
+        deviceAttributeValues[j] = ReadWriteIOUtils.readObject(buffer);
+      }
+      attributeValueList.add(deviceAttributeValues);
+    }
+    PlanNodeId planNodeId = PlanNodeId.deserialize(buffer);
+    return new CreateTableDeviceNode(
+        planNodeId, database, tableName, deviceIdList, attributeNameList, 
attributeValueList);
+  }
+
+  @Override
+  public List<WritePlanNode> splitByPartition(IAnalysis analysis) {
+    String dbNameForInvoke = PATH_ROOT + PATH_SEPARATOR + database;
+    Map<TRegionReplicaSet, List<Integer>> splitMap = new HashMap<>();
+    List<IDeviceID> partitionKeyList = getPartitionKeyList();
+    for (int i = 0; i < partitionKeyList.size(); i++) {
+      // use the string literal of deviceId as the partition key
+      TRegionReplicaSet regionReplicaSet =
+          analysis
+              .getSchemaPartitionInfo()
+              .getSchemaRegionReplicaSet(dbNameForInvoke, 
partitionKeyList.get(i));
+      splitMap.computeIfAbsent(regionReplicaSet, k -> new 
ArrayList<>()).add(i);
+    }
+    List<WritePlanNode> result = new ArrayList<>(splitMap.size());
+    for (Map.Entry<TRegionReplicaSet, List<Integer>> entry : 
splitMap.entrySet()) {
+      List<Object[]> subDeviceIdList = new 
ArrayList<>(entry.getValue().size());
+      List<Object[]> subAttributeValueList = new 
ArrayList<>(entry.getValue().size());
+      for (Integer index : entry.getValue()) {
+        subDeviceIdList.add(deviceIdList.get(index));
+        subAttributeValueList.add(attributeValueList.get(index));
+      }
+      result.add(
+          new CreateTableDeviceNode(
+              getPlanNodeId(),
+              entry.getKey(),
+              database,
+              tableName,
+              subDeviceIdList,
+              attributeNameList,
+              subAttributeValueList));
+    }
+    return result;
+  }
+
+  @Override
+  public <R, C> R accept(PlanVisitor<R, C> visitor, C context) {
+    return visitor.visitCreateTableDevice(this, context);
+  }
+
+  @Override
+  public boolean equals(Object o) {
+    if (this == o) return true;
+    if (o == null || getClass() != o.getClass()) return false;
+    if (!super.equals(o)) return false;
+    CreateTableDeviceNode node = (CreateTableDeviceNode) o;
+    return Objects.equals(database, node.database)
+        && Objects.equals(tableName, node.tableName)
+        && Objects.equals(deviceIdList, node.deviceIdList)
+        && Objects.equals(attributeNameList, node.attributeNameList)
+        && Objects.equals(attributeValueList, node.attributeValueList)
+        && Objects.equals(regionReplicaSet, node.regionReplicaSet)
+        && Objects.equals(partitionKeyList, node.partitionKeyList);
+  }
+
+  @Override
+  public int hashCode() {
+    return Objects.hash(
+        super.hashCode(),
+        database,
+        tableName,
+        deviceIdList,
+        attributeNameList,
+        attributeValueList,
+        regionReplicaSet,
+        partitionKeyList);
+  }
+}
diff --git 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/sql/ast/AstVisitor.java
 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/sql/ast/AstVisitor.java
index d2c1e487458..26cbe300c2a 100644
--- 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/sql/ast/AstVisitor.java
+++ 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/sql/ast/AstVisitor.java
@@ -446,4 +446,8 @@ public abstract class AstVisitor<R, C> {
   protected R visitDropFunction(DropFunction node, C context) {
     return visitStatement(node, context);
   }
+
+  protected R visitCreateDevice(CreateDevice node, C context) {
+    return visitStatement(node, context);
+  }
 }
diff --git 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/sql/ast/CreateDevice.java
 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/sql/ast/CreateDevice.java
new file mode 100644
index 00000000000..d06740804e7
--- /dev/null
+++ 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/sql/ast/CreateDevice.java
@@ -0,0 +1,116 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.iotdb.db.queryengine.plan.relational.sql.ast;
+
+import java.util.Collections;
+import java.util.List;
+import java.util.Objects;
+
+public class CreateDevice extends Statement {
+
+  private final String database;
+
+  private final String table;
+
+  private final List<Object[]> deviceIdList;
+
+  private final List<String> attributeNameList;
+
+  private final List<Object[]> attributeValueList;
+
+  public CreateDevice(
+      String database,
+      String table,
+      List<Object[]> deviceIdList,
+      List<String> attributeNameList,
+      List<Object[]> attributeValueList) {
+    super(null);
+    this.database = database;
+    this.table = table;
+    this.deviceIdList = deviceIdList;
+    this.attributeNameList = attributeNameList;
+    this.attributeValueList = attributeValueList;
+  }
+
+  public String getDatabase() {
+    return database;
+  }
+
+  public String getTable() {
+    return table;
+  }
+
+  public List<Object[]> getDeviceIdList() {
+    return deviceIdList;
+  }
+
+  public List<String> getAttributeNameList() {
+    return attributeNameList;
+  }
+
+  public List<Object[]> getAttributeValueList() {
+    return attributeValueList;
+  }
+
+  @Override
+  public <R, C> R accept(AstVisitor<R, C> visitor, C context) {
+    return visitor.visitCreateDevice(this, context);
+  }
+
+  @Override
+  public List<? extends Node> getChildren() {
+    return Collections.emptyList();
+  }
+
+  @Override
+  public boolean equals(Object o) {
+    if (this == o) return true;
+    if (o == null || getClass() != o.getClass()) return false;
+    CreateDevice that = (CreateDevice) o;
+    return Objects.equals(database, that.database)
+        && Objects.equals(table, that.table)
+        && Objects.equals(deviceIdList, that.deviceIdList)
+        && Objects.equals(attributeNameList, that.attributeNameList)
+        && Objects.equals(attributeValueList, that.attributeValueList);
+  }
+
+  @Override
+  public int hashCode() {
+    return Objects.hash(database, table, deviceIdList, attributeNameList, 
attributeValueList);
+  }
+
+  @Override
+  public String toString() {
+    return "CreateDevice{"
+        + "database='"
+        + database
+        + '\''
+        + ", table='"
+        + table
+        + '\''
+        + ", deviceIdList="
+        + deviceIdList
+        + ", attributeNameList="
+        + attributeNameList
+        + ", attributeValueList="
+        + attributeValueList
+        + '}';
+  }
+}
diff --git 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/schemaengine/schemaregion/ISchemaRegion.java
 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/schemaengine/schemaregion/ISchemaRegion.java
index 18d94528bc2..1b679aa8bb0 100644
--- 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/schemaengine/schemaregion/ISchemaRegion.java
+++ 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/schemaengine/schemaregion/ISchemaRegion.java
@@ -301,9 +301,10 @@ public interface ISchemaRegion {
   // region table device management
 
   void createTableDevice(
-      List<PartialPath> devicePathList,
+      String tableName,
+      List<Object[]> devicePathList,
       List<String> attributeNameList,
-      List<List<String>> attributeValueList)
+      List<Object[]> attributeValueList)
       throws MetadataException;
 
   void deleteTableDevice(String table) throws MetadataException;
diff --git 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/schemaengine/schemaregion/attribute/DeviceAttributeStore.java
 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/schemaengine/schemaregion/attribute/DeviceAttributeStore.java
index 65ea0cb50a7..70125fe2831 100644
--- 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/schemaengine/schemaregion/attribute/DeviceAttributeStore.java
+++ 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/schemaengine/schemaregion/attribute/DeviceAttributeStore.java
@@ -117,12 +117,15 @@ public class DeviceAttributeStore implements 
IDeviceAttributeStore {
   }
 
   @Override
-  public synchronized int createAttribute(List<String> nameList, List<String> 
valueList) {
+  public synchronized int createAttribute(List<String> nameList, Object[] 
valueList) {
+    // todo implement storage for device of diverse data types
     long memUsage = 0L;
     Map<String, String> attributeMap = new HashMap<>();
+    String value;
     for (int i = 0; i < nameList.size(); i++) {
-      attributeMap.put(nameList.get(i), valueList.get(i));
-      memUsage += MemUsageUtil.computeKVMemUsageInMap(nameList.get(i), 
valueList.get(i));
+      value = valueList[i] == null ? null : valueList[i].toString();
+      attributeMap.put(nameList.get(i), value);
+      memUsage += MemUsageUtil.computeKVMemUsageInMap(nameList.get(i), value);
     }
     deviceAttributeList.add(attributeMap);
     requestMemory(memUsage);
@@ -130,11 +133,13 @@ public class DeviceAttributeStore implements 
IDeviceAttributeStore {
   }
 
   @Override
-  public void alterAttribute(int pointer, List<String> nameList, List<String> 
valueList) {
+  public void alterAttribute(int pointer, List<String> nameList, Object[] 
valueList) {
+    // todo implement storage for device of diverse data types
     long memUsageDelta = 0L;
     long originMemUsage;
     long updatedMemUsage;
     Map<String, String> attributeMap = deviceAttributeList.get(pointer);
+    String value;
     for (int i = 0; i < nameList.size(); i++) {
       String key = nameList.get(i);
       originMemUsage =
@@ -142,9 +147,9 @@ public class DeviceAttributeStore implements 
IDeviceAttributeStore {
               ? 0
               : MemUsageUtil.computeKVMemUsageInMap(key, 
attributeMap.get(key));
 
-      attributeMap.put(key, valueList.get(i));
-
-      updatedMemUsage = MemUsageUtil.computeKVMemUsageInMap(key, 
valueList.get(i));
+      value = valueList[i] == null ? null : valueList[i].toString();
+      attributeMap.put(key, value);
+      updatedMemUsage = MemUsageUtil.computeKVMemUsageInMap(key, value);
       memUsageDelta += updatedMemUsage - originMemUsage;
     }
     requestMemory(memUsageDelta);
diff --git 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/schemaengine/schemaregion/attribute/IDeviceAttributeStore.java
 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/schemaengine/schemaregion/attribute/IDeviceAttributeStore.java
index 79f44d20bd2..768afca54ca 100644
--- 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/schemaengine/schemaregion/attribute/IDeviceAttributeStore.java
+++ 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/schemaengine/schemaregion/attribute/IDeviceAttributeStore.java
@@ -31,9 +31,9 @@ public interface IDeviceAttributeStore {
 
   void loadFromSnapshot(File snapshotDir, String sgSchemaDirPath) throws 
IOException;
 
-  int createAttribute(List<String> nameList, List<String> valueList);
+  int createAttribute(List<String> nameList, Object[] valueList);
 
-  void alterAttribute(int pointer, List<String> nameList, List<String> 
valueList);
+  void alterAttribute(int pointer, List<String> nameList, Object[] valueList);
 
   String getAttribute(int pointer, String name);
 }
diff --git 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/schemaengine/schemaregion/impl/SchemaRegionMemoryImpl.java
 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/schemaengine/schemaregion/impl/SchemaRegionMemoryImpl.java
index 7775bc315a8..b7c7257b880 100644
--- 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/schemaengine/schemaregion/impl/SchemaRegionMemoryImpl.java
+++ 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/schemaengine/schemaregion/impl/SchemaRegionMemoryImpl.java
@@ -1275,13 +1275,15 @@ public class SchemaRegionMemoryImpl implements 
ISchemaRegion {
 
   @Override
   public void createTableDevice(
-      List<PartialPath> devicePathList,
+      String tableName,
+      List<Object[]> devicePathList,
       List<String> attributeNameList,
-      List<List<String>> attributeValueList)
+      List<Object[]> attributeValueList)
       throws MetadataException {
     for (int i = 0; i < devicePathList.size(); i++) {
       int finalI = i;
       mtree.createTableDevice(
+          tableName,
           devicePathList.get(i),
           () ->
               deviceAttributeStore.createAttribute(
diff --git 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/schemaengine/schemaregion/impl/SchemaRegionPBTreeImpl.java
 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/schemaengine/schemaregion/impl/SchemaRegionPBTreeImpl.java
index 6ae52183a90..c1ec3c37df5 100644
--- 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/schemaengine/schemaregion/impl/SchemaRegionPBTreeImpl.java
+++ 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/schemaengine/schemaregion/impl/SchemaRegionPBTreeImpl.java
@@ -1361,9 +1361,10 @@ public class SchemaRegionPBTreeImpl implements 
ISchemaRegion {
 
   @Override
   public void createTableDevice(
-      List<PartialPath> devicePathList,
+      String tableName,
+      List<Object[]> devicePathList,
       List<String> attributeNameList,
-      List<List<String>> attributeValueList)
+      List<Object[]> attributeValueList)
       throws MetadataException {
     throw new UnsupportedOperationException();
   }
diff --git 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/schemaengine/schemaregion/mtree/impl/mem/MTreeBelowSGMemoryImpl.java
 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/schemaengine/schemaregion/mtree/impl/mem/MTreeBelowSGMemoryImpl.java
index 66e58b18563..4abd4b1c529 100644
--- 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/schemaengine/schemaregion/mtree/impl/mem/MTreeBelowSGMemoryImpl.java
+++ 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/schemaengine/schemaregion/mtree/impl/mem/MTreeBelowSGMemoryImpl.java
@@ -1420,16 +1420,25 @@ public class MTreeBelowSGMemoryImpl {
   // region table device management
 
   public void createTableDevice(
-      PartialPath devicePath, IntSupplier attributePointerGetter, IntConsumer 
attributeUppdater)
+      String tableName,
+      Object[] devicePath,
+      IntSupplier attributePointerGetter,
+      IntConsumer attributeUppdater)
       throws MetadataException {
-    String[] nodeNames = devicePath.getNodes();
+    // todo implement storage for device of diverse data types
     IMemMNode cur = storageGroupMNode;
-    IMemMNode child;
-    for (int i = levelOfSG + 1; i < nodeNames.length; i++) {
-      child = cur.getChild(nodeNames[i]);
+    IMemMNode child = cur.getChild(tableName);
+    if (child == null) {
+      child = store.addChild(cur, tableName, 
nodeFactory.createInternalMNode(cur, tableName));
+    }
+    cur = child;
+
+    String nodeName;
+    for (int i = 0; i < devicePath.length; i++) {
+      nodeName = devicePath[i] == null ? null : devicePath[i].toString();
+      child = cur.getChild(nodeName);
       if (child == null) {
-        child =
-            store.addChild(cur, nodeNames[i], 
nodeFactory.createInternalMNode(cur, nodeNames[i]));
+        child = store.addChild(cur, nodeName, 
nodeFactory.createInternalMNode(cur, nodeName));
       }
       cur = child;
     }
diff --git 
a/iotdb-core/datanode/src/test/java/org/apache/iotdb/db/metadata/schemaRegion/SchemaRegionTestUtil.java
 
b/iotdb-core/datanode/src/test/java/org/apache/iotdb/db/metadata/schemaRegion/SchemaRegionTestUtil.java
index e5c6382a44d..ec8c8d236bb 100644
--- 
a/iotdb-core/datanode/src/test/java/org/apache/iotdb/db/metadata/schemaRegion/SchemaRegionTestUtil.java
+++ 
b/iotdb-core/datanode/src/test/java/org/apache/iotdb/db/metadata/schemaRegion/SchemaRegionTestUtil.java
@@ -382,7 +382,7 @@ public class SchemaRegionTestUtil {
   }
 
   public static void createTableDevice(
-      ISchemaRegion schemaRegion, String table, String[] deviceIds, 
Map<String, String> attributes)
+      ISchemaRegion schemaRegion, String table, Object[] deviceIds, 
Map<String, String> attributes)
       throws MetadataException {
     String[] fullId = new String[deviceIds.length + 3];
     fullId[0] = ROOT;
@@ -390,9 +390,10 @@ public class SchemaRegionTestUtil {
     fullId[2] = table;
     System.arraycopy(deviceIds, 0, fullId, 3, deviceIds.length);
     schemaRegion.createTableDevice(
-        Collections.singletonList(new PartialPath(fullId)),
+        table,
+        Collections.singletonList(deviceIds),
         new ArrayList<>(attributes.keySet()),
-        Collections.singletonList(new ArrayList<>(attributes.values())));
+        Collections.singletonList(attributes.values().toArray()));
   }
 
   public static List<IDeviceSchemaInfo> getTableDevice(
diff --git 
a/iotdb-core/datanode/src/test/java/org/apache/iotdb/db/queryengine/plan/analyze/FakePartitionFetcherImpl.java
 
b/iotdb-core/datanode/src/test/java/org/apache/iotdb/db/queryengine/plan/analyze/FakePartitionFetcherImpl.java
index 38799372cf8..b7e4ac4567f 100644
--- 
a/iotdb-core/datanode/src/test/java/org/apache/iotdb/db/queryengine/plan/analyze/FakePartitionFetcherImpl.java
+++ 
b/iotdb-core/datanode/src/test/java/org/apache/iotdb/db/queryengine/plan/analyze/FakePartitionFetcherImpl.java
@@ -35,6 +35,8 @@ import org.apache.iotdb.commons.path.PathPatternTree;
 import org.apache.iotdb.db.conf.IoTDBDescriptor;
 import org.apache.iotdb.mpp.rpc.thrift.TRegionRouteReq;
 
+import org.apache.tsfile.file.metadata.IDeviceID;
+
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.HashMap;
@@ -298,4 +300,20 @@ public class FakePartitionFetcherImpl implements 
IPartitionFetcher {
 
   @Override
   public void invalidAllCache() {}
+
+  @Override
+  public SchemaPartition getOrCreateSchemaPartition(
+      String database, List<IDeviceID> deviceIDList, String userName) {
+    return null;
+  }
+
+  @Override
+  public SchemaPartition getSchemaPartition(String database, List<IDeviceID> 
deviceIDList) {
+    return null;
+  }
+
+  @Override
+  public SchemaPartition getSchemaPartition(String database) {
+    return null;
+  }
 }
diff --git 
a/iotdb-core/datanode/src/test/java/org/apache/iotdb/db/queryengine/plan/planner/distribution/Util.java
 
b/iotdb-core/datanode/src/test/java/org/apache/iotdb/db/queryengine/plan/planner/distribution/Util.java
index 59cd36a2f8a..764393b3714 100644
--- 
a/iotdb-core/datanode/src/test/java/org/apache/iotdb/db/queryengine/plan/planner/distribution/Util.java
+++ 
b/iotdb-core/datanode/src/test/java/org/apache/iotdb/db/queryengine/plan/planner/distribution/Util.java
@@ -58,6 +58,7 @@ import org.apache.iotdb.db.schemaengine.template.Template;
 import org.apache.iotdb.mpp.rpc.thrift.TRegionRouteReq;
 
 import org.apache.tsfile.enums.TSDataType;
+import org.apache.tsfile.file.metadata.IDeviceID;
 import org.apache.tsfile.file.metadata.enums.CompressionType;
 import org.apache.tsfile.file.metadata.enums.TSEncoding;
 import org.apache.tsfile.utils.Pair;
@@ -406,6 +407,22 @@ public class Util {
 
       @Override
       public void invalidAllCache() {}
+
+      @Override
+      public SchemaPartition getOrCreateSchemaPartition(
+          String database, List<IDeviceID> deviceIDList, String userName) {
+        return null;
+      }
+
+      @Override
+      public SchemaPartition getSchemaPartition(String database, 
List<IDeviceID> deviceIDList) {
+        return null;
+      }
+
+      @Override
+      public SchemaPartition getSchemaPartition(String database) {
+        return null;
+      }
     };
   }
 
diff --git 
a/iotdb-core/datanode/src/test/java/org/apache/iotdb/db/queryengine/plan/planner/distribution/Util2.java
 
b/iotdb-core/datanode/src/test/java/org/apache/iotdb/db/queryengine/plan/planner/distribution/Util2.java
index eb802edd9e5..38158b402e5 100644
--- 
a/iotdb-core/datanode/src/test/java/org/apache/iotdb/db/queryengine/plan/planner/distribution/Util2.java
+++ 
b/iotdb-core/datanode/src/test/java/org/apache/iotdb/db/queryengine/plan/planner/distribution/Util2.java
@@ -55,6 +55,7 @@ import org.apache.iotdb.db.schemaengine.template.Template;
 import org.apache.iotdb.mpp.rpc.thrift.TRegionRouteReq;
 
 import org.apache.tsfile.enums.TSDataType;
+import org.apache.tsfile.file.metadata.IDeviceID;
 import org.apache.tsfile.file.metadata.enums.CompressionType;
 import org.apache.tsfile.file.metadata.enums.TSEncoding;
 import org.apache.tsfile.utils.Pair;
@@ -300,6 +301,22 @@ public class Util2 {
 
       @Override
       public void invalidAllCache() {}
+
+      @Override
+      public SchemaPartition getOrCreateSchemaPartition(
+          String database, List<IDeviceID> deviceIDList, String userName) {
+        return null;
+      }
+
+      @Override
+      public SchemaPartition getSchemaPartition(String database, 
List<IDeviceID> deviceIDList) {
+        return null;
+      }
+
+      @Override
+      public SchemaPartition getSchemaPartition(String database) {
+        return null;
+      }
     };
   }
 
diff --git 
a/iotdb-core/datanode/src/test/java/org/apache/iotdb/db/queryengine/plan/relational/analyzer/AnalyzerTest.java
 
b/iotdb-core/datanode/src/test/java/org/apache/iotdb/db/queryengine/plan/relational/analyzer/AnalyzerTest.java
index f59af819f8f..03608978707 100644
--- 
a/iotdb-core/datanode/src/test/java/org/apache/iotdb/db/queryengine/plan/relational/analyzer/AnalyzerTest.java
+++ 
b/iotdb-core/datanode/src/test/java/org/apache/iotdb/db/queryengine/plan/relational/analyzer/AnalyzerTest.java
@@ -55,6 +55,7 @@ import 
org.apache.iotdb.db.queryengine.plan.relational.sql.ast.Statement;
 import org.apache.iotdb.db.queryengine.plan.relational.sql.parser.SqlParser;
 import org.apache.iotdb.mpp.rpc.thrift.TRegionRouteReq;
 
+import org.apache.tsfile.file.metadata.IDeviceID;
 import org.junit.Test;
 import org.mockito.Mockito;
 
@@ -563,6 +564,22 @@ public class AnalyzerTest {
 
       @Override
       public void invalidAllCache() {}
+
+      @Override
+      public SchemaPartition getOrCreateSchemaPartition(
+          String database, List<IDeviceID> deviceIDList, String userName) {
+        return null;
+      }
+
+      @Override
+      public SchemaPartition getSchemaPartition(String database, 
List<IDeviceID> deviceIDList) {
+        return null;
+      }
+
+      @Override
+      public SchemaPartition getSchemaPartition(String database) {
+        return null;
+      }
     };
   }
 
diff --git 
a/iotdb-core/datanode/src/test/java/org/apache/iotdb/db/queryengine/plan/relational/analyzer/TestMatadata.java
 
b/iotdb-core/datanode/src/test/java/org/apache/iotdb/db/queryengine/plan/relational/analyzer/TestMatadata.java
index 585898e2b08..4c483f4c8fa 100644
--- 
a/iotdb-core/datanode/src/test/java/org/apache/iotdb/db/queryengine/plan/relational/analyzer/TestMatadata.java
+++ 
b/iotdb-core/datanode/src/test/java/org/apache/iotdb/db/queryengine/plan/relational/analyzer/TestMatadata.java
@@ -14,6 +14,7 @@
 
 package org.apache.iotdb.db.queryengine.plan.relational.analyzer;
 
+import org.apache.iotdb.commons.partition.SchemaPartition;
 import org.apache.iotdb.commons.schema.table.column.TsTableColumnCategory;
 import org.apache.iotdb.commons.udf.builtin.BuiltinAggregationFunction;
 import org.apache.iotdb.db.queryengine.common.MPPQueryContext;
@@ -34,6 +35,7 @@ import 
org.apache.iotdb.db.queryengine.plan.relational.type.TypeManager;
 import 
org.apache.iotdb.db.queryengine.plan.relational.type.TypeNotFoundException;
 import org.apache.iotdb.db.queryengine.plan.relational.type.TypeSignature;
 
+import org.apache.tsfile.file.metadata.IDeviceID;
 import org.apache.tsfile.file.metadata.StringArrayDeviceID;
 import org.apache.tsfile.read.common.type.BinaryType;
 import org.apache.tsfile.read.common.type.Type;
@@ -198,6 +200,22 @@ public class TestMatadata implements Metadata {
     throw new UnsupportedOperationException();
   }
 
+  @Override
+  public SchemaPartition getOrCreateSchemaPartition(
+      String database, List<IDeviceID> deviceIDList, String userName) {
+    return null;
+  }
+
+  @Override
+  public SchemaPartition getSchemaPartition(String database, List<IDeviceID> 
deviceIDList) {
+    return null;
+  }
+
+  @Override
+  public SchemaPartition getSchemaPartition(String database) {
+    return null;
+  }
+
   public static boolean isTwoNumericType(List<? extends Type> argumentTypes) {
     return argumentTypes.size() == 2
         && isNumericType(argumentTypes.get(0))
diff --git 
a/iotdb-core/node-commons/src/main/java/org/apache/iotdb/commons/partition/SchemaPartition.java
 
b/iotdb-core/node-commons/src/main/java/org/apache/iotdb/commons/partition/SchemaPartition.java
index 4c47941ca3a..ca4cd74bb10 100644
--- 
a/iotdb-core/node-commons/src/main/java/org/apache/iotdb/commons/partition/SchemaPartition.java
+++ 
b/iotdb-core/node-commons/src/main/java/org/apache/iotdb/commons/partition/SchemaPartition.java
@@ -63,6 +63,21 @@ public class SchemaPartition extends Partition {
     this.schemaPartitionMap = schemaPartitionMap;
   }
 
+  // table model usage
+
+  /**
+   * For table model usage.
+   *
+   * <p>The database shall start with "root.". Concat this to a user-provided 
db name if necessary.
+   *
+   * <p>The device id shall be [table, seg1, ....]
+   */
+  public TRegionReplicaSet getSchemaRegionReplicaSet(String database, 
IDeviceID deviceID) {
+    // todo implement this interface, @Potato
+    throw new UnsupportedOperationException();
+  }
+
+  // [root, db, ....]
   public TRegionReplicaSet getSchemaRegionReplicaSet(IDeviceID deviceID) {
     // A list of data region replica sets will store data in a same time 
partition.
     // We will insert data to the last set in the list.

Reply via email to