You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@iotdb.apache.org by zy...@apache.org on 2023/02/09 10:55:51 UTC

[iotdb] branch master updated: [IOTDB-5477] Refactor the interaction between InsertNode and SchemaFetcher (#8993)

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

zyk 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 4abad1cdac [IOTDB-5477] Refactor the interaction between InsertNode and SchemaFetcher (#8993)
4abad1cdac is described below

commit 4abad1cdacbf4f99a7ab8953fa49ce1cdce7a429
Author: Marcos_Zyk <38...@users.noreply.github.com>
AuthorDate: Thu Feb 9 18:55:44 2023 +0800

    [IOTDB-5477] Refactor the interaction between InsertNode and SchemaFetcher (#8993)
---
 .../iotdb/db/it/IoTDBPartialInsertionIT.java       |   7 +-
 .../db/metadata/cache/DataNodeSchemaCache.java     |  44 +++++
 .../mpp/common/schematree/ClusterSchemaTree.java   |  33 ++++
 .../schematree/IMeasurementSchemaInfo.java}        |  21 +--
 .../schematree/node/SchemaMeasurementNode.java     |   3 +-
 .../plan/analyze/schema/ClusterSchemaFetcher.java  | 178 +++++++++++++++++----
 .../schema/ISchemaAutoCreation.java}               |  24 +--
 .../schema/ISchemaComputation.java}                |  25 +--
 .../ISchemaComputationWithAutoCreation.java}       |  23 +--
 .../db/mpp/plan/analyze/schema/ISchemaFetcher.java |  44 +++--
 .../schema/ISchemaValidation.java}                 |  28 ++--
 .../mpp/plan/analyze/schema/SchemaValidator.java   |  34 ++--
 .../planner/plan/node/write/BatchInsertNode.java   |  11 +-
 .../plan/node/write/InsertMultiTabletsNode.java    |  52 +-----
 .../plan/planner/plan/node/write/InsertNode.java   |  76 ++++-----
 .../planner/plan/node/write/InsertRowNode.java     | 100 +++++++-----
 .../planner/plan/node/write/InsertRowsNode.java    |  53 ++----
 .../plan/node/write/InsertRowsOfOneDeviceNode.java |  51 ++----
 .../planner/plan/node/write/InsertTabletNode.java  |  83 ++++++----
 .../db/mpp/plan/analyze/FakeSchemaFetcherImpl.java |  24 +--
 .../iotdb/db/mpp/plan/plan/distribution/Util.java  |  21 +--
 21 files changed, 518 insertions(+), 417 deletions(-)

diff --git a/integration-test/src/test/java/org/apache/iotdb/db/it/IoTDBPartialInsertionIT.java b/integration-test/src/test/java/org/apache/iotdb/db/it/IoTDBPartialInsertionIT.java
index fdd6e906e9..0b284573a8 100644
--- a/integration-test/src/test/java/org/apache/iotdb/db/it/IoTDBPartialInsertionIT.java
+++ b/integration-test/src/test/java/org/apache/iotdb/db/it/IoTDBPartialInsertionIT.java
@@ -22,7 +22,6 @@ import org.apache.iotdb.it.env.EnvFactory;
 import org.apache.iotdb.it.framework.IoTDBTestRunner;
 import org.apache.iotdb.itbase.category.ClusterIT;
 import org.apache.iotdb.itbase.category.LocalStandaloneIT;
-import org.apache.iotdb.rpc.TSStatusCode;
 
 import org.junit.After;
 import org.junit.Before;
@@ -70,11 +69,7 @@ public class IoTDBPartialInsertionIT {
         statement.execute("INSERT INTO root.sg1(timestamp, s0) VALUES (1, 1)");
         fail();
       } catch (SQLException e) {
-        assertTrue(
-            e.getMessage()
-                .contains(
-                    TSStatusCode.PATH_NOT_EXIST.getStatusCode()
-                        + ": Path [root.sg1.s0] does not exist"));
+        assertTrue(e.getMessage().contains("Path [root.sg1.s0] does not exist"));
       }
     }
   }
diff --git a/server/src/main/java/org/apache/iotdb/db/metadata/cache/DataNodeSchemaCache.java b/server/src/main/java/org/apache/iotdb/db/metadata/cache/DataNodeSchemaCache.java
index 42f75406f0..714cf61aeb 100644
--- a/server/src/main/java/org/apache/iotdb/db/metadata/cache/DataNodeSchemaCache.java
+++ b/server/src/main/java/org/apache/iotdb/db/metadata/cache/DataNodeSchemaCache.java
@@ -25,6 +25,8 @@ import org.apache.iotdb.commons.service.metric.MetricService;
 import org.apache.iotdb.db.conf.IoTDBConfig;
 import org.apache.iotdb.db.conf.IoTDBDescriptor;
 import org.apache.iotdb.db.mpp.common.schematree.ClusterSchemaTree;
+import org.apache.iotdb.db.mpp.common.schematree.IMeasurementSchemaInfo;
+import org.apache.iotdb.db.mpp.plan.analyze.schema.ISchemaComputation;
 import org.apache.iotdb.tsfile.read.TimeValuePair;
 import org.apache.iotdb.tsfile.write.schema.MeasurementSchema;
 
@@ -33,8 +35,10 @@ import com.github.benmanes.caffeine.cache.Caffeine;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
+import java.util.ArrayList;
 import java.util.Collections;
 import java.util.HashSet;
+import java.util.List;
 import java.util.Set;
 import java.util.concurrent.locks.ReentrantReadWriteLock;
 
@@ -136,6 +140,46 @@ public class DataNodeSchemaCache {
     return schemaTree;
   }
 
+  public List<Integer> compute(ISchemaComputation schemaComputation) {
+    PartialPath devicePath = schemaComputation.getDevicePath();
+    String[] measurements = schemaComputation.getMeasurements();
+    List<Integer> indexOfMissingMeasurements = new ArrayList<>();
+    boolean isFirstMeasurement = true;
+    PartialPath fullPath;
+    for (int i = 0, length = measurements.length; i < length; i++) {
+      String measurement = measurements[i];
+      fullPath = devicePath.concatNode(measurement);
+      SchemaCacheEntry schemaCacheEntry = cache.getIfPresent(fullPath);
+      if (schemaCacheEntry == null) {
+        indexOfMissingMeasurements.add(i);
+      } else {
+        if (isFirstMeasurement) {
+          schemaComputation.computeDevice(schemaCacheEntry.isAligned());
+          isFirstMeasurement = false;
+        }
+        schemaComputation.computeMeasurement(
+            i,
+            new IMeasurementSchemaInfo() {
+              @Override
+              public String getName() {
+                return measurement;
+              }
+
+              @Override
+              public MeasurementSchema getSchema() {
+                return schemaCacheEntry.getMeasurementSchema();
+              }
+
+              @Override
+              public String getAlias() {
+                throw new UnsupportedOperationException();
+              }
+            });
+      }
+    }
+    return indexOfMissingMeasurements;
+  }
+
   public void put(ClusterSchemaTree schemaTree) {
     for (MeasurementPath measurementPath : schemaTree.getAllMeasurement()) {
       putSingleMeasurementPath(schemaTree.getBelongedDatabase(measurementPath), measurementPath);
diff --git a/server/src/main/java/org/apache/iotdb/db/mpp/common/schematree/ClusterSchemaTree.java b/server/src/main/java/org/apache/iotdb/db/mpp/common/schematree/ClusterSchemaTree.java
index 4b547c28ec..3708dd77ea 100644
--- a/server/src/main/java/org/apache/iotdb/db/mpp/common/schematree/ClusterSchemaTree.java
+++ b/server/src/main/java/org/apache/iotdb/db/mpp/common/schematree/ClusterSchemaTree.java
@@ -31,6 +31,7 @@ import org.apache.iotdb.db.mpp.common.schematree.node.SchemaNode;
 import org.apache.iotdb.db.mpp.common.schematree.visitor.SchemaTreeDeviceVisitor;
 import org.apache.iotdb.db.mpp.common.schematree.visitor.SchemaTreeVisitorFactory;
 import org.apache.iotdb.db.mpp.common.schematree.visitor.SchemaTreeVisitorWithLimitOffsetWrapper;
+import org.apache.iotdb.db.mpp.plan.analyze.schema.ISchemaComputation;
 import org.apache.iotdb.tsfile.utils.Pair;
 import org.apache.iotdb.tsfile.utils.ReadWriteIOUtils;
 import org.apache.iotdb.tsfile.write.schema.MeasurementSchema;
@@ -154,6 +155,38 @@ public class ClusterSchemaTree implements ISchemaTree {
         devicePath, cur.getAsEntityNode().isAligned(), measurementSchemaInfoList);
   }
 
+  public List<Integer> compute(
+      ISchemaComputation schemaComputation, List<Integer> indexOfTargetMeasurements) {
+    PartialPath devicePath = schemaComputation.getDevicePath();
+    String[] measurements = schemaComputation.getMeasurements();
+
+    String[] nodes = devicePath.getNodes();
+    SchemaNode cur = root;
+    for (int i = 1; i < nodes.length; i++) {
+      if (cur == null) {
+        return indexOfTargetMeasurements;
+      }
+      cur = cur.getChild(nodes[i]);
+    }
+    if (cur == null) {
+      return indexOfTargetMeasurements;
+    }
+    if (cur.isEntity()) {
+      schemaComputation.computeDevice(cur.getAsEntityNode().isAligned());
+    }
+    List<Integer> indexOfMissingMeasurements = new ArrayList<>();
+    SchemaNode node;
+    for (int index : indexOfTargetMeasurements) {
+      node = cur.getChild(measurements[index]);
+      if (node == null) {
+        indexOfMissingMeasurements.add(index);
+      } else {
+        schemaComputation.computeMeasurement(index, node.getAsMeasurementNode());
+      }
+    }
+    return indexOfMissingMeasurements;
+  }
+
   public void appendMeasurementPaths(List<MeasurementPath> measurementPathList) {
     for (MeasurementPath measurementPath : measurementPathList) {
       appendSingleMeasurementPath(measurementPath);
diff --git a/server/src/main/java/org/apache/iotdb/db/mpp/plan/planner/plan/node/write/BatchInsertNode.java b/server/src/main/java/org/apache/iotdb/db/mpp/common/schematree/IMeasurementSchemaInfo.java
similarity index 60%
copy from server/src/main/java/org/apache/iotdb/db/mpp/plan/planner/plan/node/write/BatchInsertNode.java
copy to server/src/main/java/org/apache/iotdb/db/mpp/common/schematree/IMeasurementSchemaInfo.java
index d326b53895..057ccd2497 100644
--- a/server/src/main/java/org/apache/iotdb/db/mpp/plan/planner/plan/node/write/BatchInsertNode.java
+++ b/server/src/main/java/org/apache/iotdb/db/mpp/common/schematree/IMeasurementSchemaInfo.java
@@ -17,24 +17,15 @@
  * under the License.
  */
 
-package org.apache.iotdb.db.mpp.plan.planner.plan.node.write;
+package org.apache.iotdb.db.mpp.common.schematree;
 
-import org.apache.iotdb.commons.path.PartialPath;
-import org.apache.iotdb.tsfile.file.metadata.enums.TSDataType;
+import org.apache.iotdb.tsfile.write.schema.MeasurementSchema;
 
-import java.util.List;
+public interface IMeasurementSchemaInfo {
 
-/**
- * BatchInsertNode contains multiple sub insert. Insert node which contains multiple sub insert
- * nodes needs to implement it.
- */
-public interface BatchInsertNode {
-
-  List<PartialPath> getDevicePaths();
-
-  List<String[]> getMeasurementsList();
+  String getName();
 
-  List<TSDataType[]> getDataTypesList();
+  MeasurementSchema getSchema();
 
-  List<Boolean> getAlignedList();
+  String getAlias();
 }
diff --git a/server/src/main/java/org/apache/iotdb/db/mpp/common/schematree/node/SchemaMeasurementNode.java b/server/src/main/java/org/apache/iotdb/db/mpp/common/schematree/node/SchemaMeasurementNode.java
index d7751ef317..8ed530317d 100644
--- a/server/src/main/java/org/apache/iotdb/db/mpp/common/schematree/node/SchemaMeasurementNode.java
+++ b/server/src/main/java/org/apache/iotdb/db/mpp/common/schematree/node/SchemaMeasurementNode.java
@@ -19,6 +19,7 @@
 
 package org.apache.iotdb.db.mpp.common.schematree.node;
 
+import org.apache.iotdb.db.mpp.common.schematree.IMeasurementSchemaInfo;
 import org.apache.iotdb.tsfile.utils.ReadWriteIOUtils;
 import org.apache.iotdb.tsfile.write.schema.MeasurementSchema;
 
@@ -27,7 +28,7 @@ import java.io.InputStream;
 import java.io.OutputStream;
 import java.util.Map;
 
-public class SchemaMeasurementNode extends SchemaNode {
+public class SchemaMeasurementNode extends SchemaNode implements IMeasurementSchemaInfo {
 
   private String alias;
   private MeasurementSchema schema;
diff --git a/server/src/main/java/org/apache/iotdb/db/mpp/plan/analyze/schema/ClusterSchemaFetcher.java b/server/src/main/java/org/apache/iotdb/db/mpp/plan/analyze/schema/ClusterSchemaFetcher.java
index 09868e6b9a..002882d930 100644
--- a/server/src/main/java/org/apache/iotdb/db/mpp/plan/analyze/schema/ClusterSchemaFetcher.java
+++ b/server/src/main/java/org/apache/iotdb/db/mpp/plan/analyze/schema/ClusterSchemaFetcher.java
@@ -44,7 +44,6 @@ 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 java.util.stream.IntStream;
 
@@ -152,64 +151,183 @@ public class ClusterSchemaFetcher implements ISchemaFetcher {
   }
 
   @Override
-  public ISchemaTree fetchSchemaWithAutoCreate(
-      PartialPath devicePath,
-      String[] measurements,
-      Function<Integer, TSDataType> getDataType,
-      boolean isAligned) {
+  public void fetchAndComputeSchemaWithAutoCreate(
+      ISchemaComputationWithAutoCreation schemaComputationWithAutoCreation) {
     // The schema cache R/W and fetch operation must be locked together thus the cache clean
     // operation executed by delete timeseries will be effective.
     schemaCache.takeReadLock();
     try {
-      ClusterSchemaTree schemaTree = schemaCache.get(devicePath, measurements);
-      List<Integer> indexOfMissingMeasurements =
-          checkMissingMeasurements(schemaTree, devicePath, measurements);
+      PartialPath devicePath = schemaComputationWithAutoCreation.getDevicePath();
+      String[] measurements = schemaComputationWithAutoCreation.getMeasurements();
 
+      List<Integer> indexOfMissingMeasurements =
+          schemaCache.compute(schemaComputationWithAutoCreation);
       // all schema can be taken from cache
       if (indexOfMissingMeasurements.isEmpty()) {
-        return schemaTree;
+        return;
       }
 
       // try fetch the missing schema from remote and cache fetched schema
       ClusterSchemaTree remoteSchemaTree =
           clusterSchemaFetchExecutor.fetchSchemaOfOneDevice(
               devicePath, measurements, indexOfMissingMeasurements);
-      if (!remoteSchemaTree.isEmpty()) {
-        schemaTree.mergeSchemaTree(remoteSchemaTree);
-      }
+      // check and compute the fetched schema
+      indexOfMissingMeasurements =
+          remoteSchemaTree.compute(schemaComputationWithAutoCreation, indexOfMissingMeasurements);
 
-      if (!config.isAutoCreateSchemaEnabled()) {
-        return schemaTree;
+      // all schema has been taken and processed
+      if (indexOfMissingMeasurements.isEmpty()) {
+        return;
       }
 
-      // auto create the still missing schema and merge them into schemaTree
-      indexOfMissingMeasurements =
-          checkMissingMeasurementsAfterSchemaFetch(
-              schemaTree, devicePath, indexOfMissingMeasurements, measurements);
-      if (!indexOfMissingMeasurements.isEmpty()) {
+      // auto create and process the missing schema
+      if (config.isAutoCreateSchemaEnabled()) {
+        ClusterSchemaTree schemaTree = new ClusterSchemaTree();
         autoCreateSchemaExecutor.autoCreateMissingMeasurements(
             schemaTree,
             devicePath,
             indexOfMissingMeasurements,
             measurements,
-            getDataType,
-            isAligned);
+            schemaComputationWithAutoCreation::getDataType,
+            schemaComputationWithAutoCreation.isAligned());
+        indexOfMissingMeasurements =
+            schemaTree.compute(schemaComputationWithAutoCreation, indexOfMissingMeasurements);
+
+        // all schema has been taken and processed
+        if (indexOfMissingMeasurements.isEmpty()) {
+          return;
+        }
       }
 
-      return schemaTree;
+      // offer null for the rest missing schema processing
+      for (int index : indexOfMissingMeasurements) {
+        schemaComputationWithAutoCreation.computeMeasurement(index, null);
+      }
     } finally {
       schemaCache.releaseReadLock();
     }
   }
 
   @Override
-  public ISchemaTree fetchSchemaListWithAutoCreate(
-      List<PartialPath> devicePathList,
-      List<String[]> measurementsList,
-      List<TSDataType[]> tsDataTypesList,
-      List<Boolean> isAlignedList) {
-    return fetchSchemaListWithAutoCreate(
-        devicePathList, measurementsList, tsDataTypesList, null, null, isAlignedList);
+  public void fetchAndComputeSchemaWithAutoCreate(
+      List<? extends ISchemaComputationWithAutoCreation> schemaComputationWithAutoCreationList) {
+    // The schema cache R/W and fetch operation must be locked together thus the cache clean
+    // operation executed by delete timeseries will be effective.
+    schemaCache.takeReadLock();
+    try {
+
+      List<List<Integer>> indexOfMissingMeasurementsList =
+          new ArrayList<>(schemaComputationWithAutoCreationList.size());
+      List<Integer> indexOfDevicesWithMissingMeasurements = new ArrayList<>();
+      ISchemaComputationWithAutoCreation schemaComputationWithAutoCreation;
+      List<Integer> indexOfMissingMeasurements;
+      for (int i = 0, size = schemaComputationWithAutoCreationList.size(); i < size; i++) {
+        schemaComputationWithAutoCreation = schemaComputationWithAutoCreationList.get(i);
+        indexOfMissingMeasurements = schemaCache.compute(schemaComputationWithAutoCreation);
+        if (!indexOfMissingMeasurements.isEmpty()) {
+          indexOfDevicesWithMissingMeasurements.add(i);
+          indexOfMissingMeasurementsList.add(indexOfMissingMeasurements);
+        }
+      }
+
+      // all schema can be taken from cache
+      if (indexOfDevicesWithMissingMeasurements.isEmpty()) {
+        return;
+      }
+
+      // try fetch the missing schema from remote
+      ClusterSchemaTree remoteSchemaTree =
+          clusterSchemaFetchExecutor.fetchSchemaOfMultiDevices(
+              schemaComputationWithAutoCreationList.stream()
+                  .map(ISchemaComputationWithAutoCreation::getDevicePath)
+                  .collect(Collectors.toList()),
+              schemaComputationWithAutoCreationList.stream()
+                  .map(ISchemaComputationWithAutoCreation::getMeasurements)
+                  .collect(Collectors.toList()),
+              indexOfDevicesWithMissingMeasurements,
+              indexOfMissingMeasurementsList);
+      // check and compute the fetched schema
+      List<Integer> indexOfDevicesNeedAutoCreateSchema = new ArrayList<>();
+      List<List<Integer>> indexOfMeasurementsNeedAutoCreate = new ArrayList<>();
+      for (int i = 0; i < indexOfDevicesWithMissingMeasurements.size(); i++) {
+        schemaComputationWithAutoCreation =
+            schemaComputationWithAutoCreationList.get(indexOfDevicesWithMissingMeasurements.get(i));
+        indexOfMissingMeasurements =
+            remoteSchemaTree.compute(
+                schemaComputationWithAutoCreation, indexOfMissingMeasurementsList.get(i));
+        if (!indexOfMissingMeasurements.isEmpty()) {
+          indexOfDevicesNeedAutoCreateSchema.add(indexOfDevicesWithMissingMeasurements.get(i));
+          indexOfMeasurementsNeedAutoCreate.add(indexOfMissingMeasurements);
+        }
+      }
+
+      // all schema has been taken and processed
+      if (indexOfDevicesNeedAutoCreateSchema.isEmpty()) {
+        return;
+      }
+
+      // auto create and process the missing schema
+      if (config.isAutoCreateSchemaEnabled()) {
+        ClusterSchemaTree schemaTree = new ClusterSchemaTree();
+        autoCreateSchemaExecutor.autoCreateMissingMeasurements(
+            schemaTree,
+            schemaComputationWithAutoCreationList.stream()
+                .map(ISchemaComputationWithAutoCreation::getDevicePath)
+                .collect(Collectors.toList()),
+            indexOfDevicesNeedAutoCreateSchema,
+            indexOfMeasurementsNeedAutoCreate,
+            schemaComputationWithAutoCreationList.stream()
+                .map(ISchemaComputationWithAutoCreation::getMeasurements)
+                .collect(Collectors.toList()),
+            schemaComputationWithAutoCreationList.stream()
+                .map(
+                    o -> {
+                      TSDataType[] dataTypes = new TSDataType[o.getMeasurements().length];
+                      for (int i = 0, length = dataTypes.length; i < length; i++) {
+                        dataTypes[i] = o.getDataType(i);
+                      }
+                      return dataTypes;
+                    })
+                .collect(Collectors.toList()),
+            null,
+            null,
+            schemaComputationWithAutoCreationList.stream()
+                .map(ISchemaComputationWithAutoCreation::isAligned)
+                .collect(Collectors.toList()));
+        indexOfDevicesWithMissingMeasurements = new ArrayList<>();
+        indexOfMissingMeasurementsList = new ArrayList<>();
+        for (int i = 0; i < indexOfDevicesNeedAutoCreateSchema.size(); i++) {
+          schemaComputationWithAutoCreation =
+              schemaComputationWithAutoCreationList.get(indexOfDevicesNeedAutoCreateSchema.get(i));
+          indexOfMissingMeasurements =
+              schemaTree.compute(
+                  schemaComputationWithAutoCreation, indexOfMeasurementsNeedAutoCreate.get(i));
+          if (!indexOfMissingMeasurements.isEmpty()) {
+            indexOfDevicesWithMissingMeasurements.add(indexOfDevicesNeedAutoCreateSchema.get(i));
+            indexOfMissingMeasurementsList.add(indexOfMissingMeasurements);
+          }
+        }
+
+        // all schema has been taken and processed
+        if (indexOfDevicesWithMissingMeasurements.isEmpty()) {
+          return;
+        }
+      } else {
+        indexOfDevicesWithMissingMeasurements = indexOfDevicesNeedAutoCreateSchema;
+        indexOfMissingMeasurementsList = indexOfMeasurementsNeedAutoCreate;
+      }
+
+      // offer null for the rest missing schema processing
+      for (int i = 0; i < indexOfDevicesWithMissingMeasurements.size(); i++) {
+        schemaComputationWithAutoCreation =
+            schemaComputationWithAutoCreationList.get(indexOfDevicesWithMissingMeasurements.get(i));
+        for (int index : indexOfMissingMeasurementsList.get(i)) {
+          schemaComputationWithAutoCreation.computeMeasurement(index, null);
+        }
+      }
+    } finally {
+      schemaCache.releaseReadLock();
+    }
   }
 
   @Override
diff --git a/server/src/main/java/org/apache/iotdb/db/mpp/plan/planner/plan/node/write/BatchInsertNode.java b/server/src/main/java/org/apache/iotdb/db/mpp/plan/analyze/schema/ISchemaAutoCreation.java
similarity index 63%
copy from server/src/main/java/org/apache/iotdb/db/mpp/plan/planner/plan/node/write/BatchInsertNode.java
copy to server/src/main/java/org/apache/iotdb/db/mpp/plan/analyze/schema/ISchemaAutoCreation.java
index d326b53895..a519946875 100644
--- a/server/src/main/java/org/apache/iotdb/db/mpp/plan/planner/plan/node/write/BatchInsertNode.java
+++ b/server/src/main/java/org/apache/iotdb/db/mpp/plan/analyze/schema/ISchemaAutoCreation.java
@@ -17,24 +17,28 @@
  * under the License.
  */
 
-package org.apache.iotdb.db.mpp.plan.planner.plan.node.write;
+package org.apache.iotdb.db.mpp.plan.analyze.schema;
 
 import org.apache.iotdb.commons.path.PartialPath;
+import org.apache.iotdb.tsfile.file.metadata.enums.CompressionType;
 import org.apache.iotdb.tsfile.file.metadata.enums.TSDataType;
-
-import java.util.List;
+import org.apache.iotdb.tsfile.file.metadata.enums.TSEncoding;
 
 /**
- * BatchInsertNode contains multiple sub insert. Insert node which contains multiple sub insert
- * nodes needs to implement it.
+ * This interface defines the required info provided for schema auto creation, which is executed
+ * schema fetcher.
  */
-public interface BatchInsertNode {
+public interface ISchemaAutoCreation {
+
+  PartialPath getDevicePath();
+
+  String[] getMeasurements();
 
-  List<PartialPath> getDevicePaths();
+  boolean isAligned();
 
-  List<String[]> getMeasurementsList();
+  TSDataType getDataType(int index);
 
-  List<TSDataType[]> getDataTypesList();
+  TSEncoding getEncoding(int index);
 
-  List<Boolean> getAlignedList();
+  CompressionType getCompressionType(int index);
 }
diff --git a/server/src/main/java/org/apache/iotdb/db/mpp/plan/planner/plan/node/write/BatchInsertNode.java b/server/src/main/java/org/apache/iotdb/db/mpp/plan/analyze/schema/ISchemaComputation.java
similarity index 54%
copy from server/src/main/java/org/apache/iotdb/db/mpp/plan/planner/plan/node/write/BatchInsertNode.java
copy to server/src/main/java/org/apache/iotdb/db/mpp/plan/analyze/schema/ISchemaComputation.java
index d326b53895..8fdc9a9fcc 100644
--- a/server/src/main/java/org/apache/iotdb/db/mpp/plan/planner/plan/node/write/BatchInsertNode.java
+++ b/server/src/main/java/org/apache/iotdb/db/mpp/plan/analyze/schema/ISchemaComputation.java
@@ -17,24 +17,27 @@
  * under the License.
  */
 
-package org.apache.iotdb.db.mpp.plan.planner.plan.node.write;
+package org.apache.iotdb.db.mpp.plan.analyze.schema;
 
 import org.apache.iotdb.commons.path.PartialPath;
-import org.apache.iotdb.tsfile.file.metadata.enums.TSDataType;
-
-import java.util.List;
+import org.apache.iotdb.db.mpp.common.schematree.IMeasurementSchemaInfo;
 
 /**
- * BatchInsertNode contains multiple sub insert. Insert node which contains multiple sub insert
- * nodes needs to implement it.
+ * This interface defines the required behaviour invoked during schema fetch/computation, which is
+ * executed by schema fetcher.
  */
-public interface BatchInsertNode {
+public interface ISchemaComputation {
 
-  List<PartialPath> getDevicePaths();
+  PartialPath getDevicePath();
 
-  List<String[]> getMeasurementsList();
+  String[] getMeasurements();
 
-  List<TSDataType[]> getDataTypesList();
+  /** @param isAligned whether the fetched device is aligned */
+  void computeDevice(boolean isAligned);
 
-  List<Boolean> getAlignedList();
+  /**
+   * @param index the index of fetched measurement in array returned by getMeasurements
+   * @param measurementSchemaInfo the measurement schema of fetched measurement
+   */
+  void computeMeasurement(int index, IMeasurementSchemaInfo measurementSchemaInfo);
 }
diff --git a/server/src/main/java/org/apache/iotdb/db/mpp/plan/planner/plan/node/write/BatchInsertNode.java b/server/src/main/java/org/apache/iotdb/db/mpp/plan/analyze/schema/ISchemaComputationWithAutoCreation.java
similarity index 60%
copy from server/src/main/java/org/apache/iotdb/db/mpp/plan/planner/plan/node/write/BatchInsertNode.java
copy to server/src/main/java/org/apache/iotdb/db/mpp/plan/analyze/schema/ISchemaComputationWithAutoCreation.java
index d326b53895..572eeece09 100644
--- a/server/src/main/java/org/apache/iotdb/db/mpp/plan/planner/plan/node/write/BatchInsertNode.java
+++ b/server/src/main/java/org/apache/iotdb/db/mpp/plan/analyze/schema/ISchemaComputationWithAutoCreation.java
@@ -17,24 +17,7 @@
  * under the License.
  */
 
-package org.apache.iotdb.db.mpp.plan.planner.plan.node.write;
+package org.apache.iotdb.db.mpp.plan.analyze.schema;
 
-import org.apache.iotdb.commons.path.PartialPath;
-import org.apache.iotdb.tsfile.file.metadata.enums.TSDataType;
-
-import java.util.List;
-
-/**
- * BatchInsertNode contains multiple sub insert. Insert node which contains multiple sub insert
- * nodes needs to implement it.
- */
-public interface BatchInsertNode {
-
-  List<PartialPath> getDevicePaths();
-
-  List<String[]> getMeasurementsList();
-
-  List<TSDataType[]> getDataTypesList();
-
-  List<Boolean> getAlignedList();
-}
+public interface ISchemaComputationWithAutoCreation
+    extends ISchemaComputation, ISchemaAutoCreation {}
diff --git a/server/src/main/java/org/apache/iotdb/db/mpp/plan/analyze/schema/ISchemaFetcher.java b/server/src/main/java/org/apache/iotdb/db/mpp/plan/analyze/schema/ISchemaFetcher.java
index 37516321c0..7007d4d3be 100644
--- a/server/src/main/java/org/apache/iotdb/db/mpp/plan/analyze/schema/ISchemaFetcher.java
+++ b/server/src/main/java/org/apache/iotdb/db/mpp/plan/analyze/schema/ISchemaFetcher.java
@@ -30,28 +30,50 @@ import org.apache.iotdb.tsfile.utils.Pair;
 
 import java.util.List;
 import java.util.Map;
-import java.util.function.Function;
 
 /**
  * This interface is used to fetch the metadata information required in execution plan generating.
  */
 public interface ISchemaFetcher {
 
+  /**
+   * Fetch all the schema of existing timeseries matched by the given patternTree
+   *
+   * @param patternTree used for matching the timeseries
+   * @return the matched timeseries schema organized as tree structure logically
+   */
   ISchemaTree fetchSchema(PathPatternTree patternTree);
 
+  /**
+   * Fetch all the schema with tags of existing timeseries matched by the given patternTree
+   *
+   * @param patternTree used for matching the timeseries
+   * @return the matched timeseries schema organized as tree structure logically
+   */
   ISchemaTree fetchSchemaWithTags(PathPatternTree patternTree);
 
-  ISchemaTree fetchSchemaWithAutoCreate(
-      PartialPath devicePath,
-      String[] measurements,
-      Function<Integer, TSDataType> getDataType,
-      boolean aligned);
+  /**
+   * Fetch and compute the schema of target timeseries, with device and measurement defined in given
+   * schemaComputationWithAutoCreation. The computation defined in given
+   * schemaComputationWithAutoCreation will be executed during scanning the fetched schema. If some
+   * target timeseries doesn't exist, they will be auto created.
+   *
+   * @param schemaComputationWithAutoCreation define the target device, measurements and computation
+   */
+  void fetchAndComputeSchemaWithAutoCreate(
+      ISchemaComputationWithAutoCreation schemaComputationWithAutoCreation);
 
-  ISchemaTree fetchSchemaListWithAutoCreate(
-      List<PartialPath> devicePath,
-      List<String[]> measurements,
-      List<TSDataType[]> tsDataTypes,
-      List<Boolean> aligned);
+  /**
+   * Fetch and compute the schema of target timeseries, with device and measurement defined in given
+   * schemaComputationWithAutoCreation. The computation defined in given
+   * schemaComputationWithAutoCreation will be executed during scanning the fetched schema. If some
+   * target timeseries doesn't exist, they will be auto created.
+   *
+   * @param schemaComputationWithAutoCreationList define the target devices, measurements and
+   *     computation
+   */
+  void fetchAndComputeSchemaWithAutoCreate(
+      List<? extends ISchemaComputationWithAutoCreation> schemaComputationWithAutoCreationList);
 
   ISchemaTree fetchSchemaListWithAutoCreate(
       List<PartialPath> devicePath,
diff --git a/server/src/main/java/org/apache/iotdb/db/mpp/plan/planner/plan/node/write/BatchInsertNode.java b/server/src/main/java/org/apache/iotdb/db/mpp/plan/analyze/schema/ISchemaValidation.java
similarity index 53%
copy from server/src/main/java/org/apache/iotdb/db/mpp/plan/planner/plan/node/write/BatchInsertNode.java
copy to server/src/main/java/org/apache/iotdb/db/mpp/plan/analyze/schema/ISchemaValidation.java
index d326b53895..b0141f89b6 100644
--- a/server/src/main/java/org/apache/iotdb/db/mpp/plan/planner/plan/node/write/BatchInsertNode.java
+++ b/server/src/main/java/org/apache/iotdb/db/mpp/plan/analyze/schema/ISchemaValidation.java
@@ -17,24 +17,24 @@
  * under the License.
  */
 
-package org.apache.iotdb.db.mpp.plan.planner.plan.node.write;
+package org.apache.iotdb.db.mpp.plan.analyze.schema;
 
-import org.apache.iotdb.commons.path.PartialPath;
-import org.apache.iotdb.tsfile.file.metadata.enums.TSDataType;
+import org.apache.iotdb.db.mpp.common.schematree.IMeasurementSchemaInfo;
 
-import java.util.List;
+/** This interface defines the info and behaviour of a schema validation task. */
+public interface ISchemaValidation extends ISchemaComputationWithAutoCreation {
 
-/**
- * BatchInsertNode contains multiple sub insert. Insert node which contains multiple sub insert
- * nodes needs to implement it.
- */
-public interface BatchInsertNode {
-
-  List<PartialPath> getDevicePaths();
+  @Override
+  default void computeDevice(boolean isAligned) {
+    validateDeviceSchema(isAligned);
+  }
 
-  List<String[]> getMeasurementsList();
+  @Override
+  default void computeMeasurement(int index, IMeasurementSchemaInfo measurementSchemaInfo) {
+    validateMeasurementSchema(index, measurementSchemaInfo);
+  }
 
-  List<TSDataType[]> getDataTypesList();
+  void validateDeviceSchema(boolean isAligned);
 
-  List<Boolean> getAlignedList();
+  void validateMeasurementSchema(int index, IMeasurementSchemaInfo measurementSchemaInfo);
 }
diff --git a/server/src/main/java/org/apache/iotdb/db/mpp/plan/analyze/schema/SchemaValidator.java b/server/src/main/java/org/apache/iotdb/db/mpp/plan/analyze/schema/SchemaValidator.java
index 3882d6e34d..6cbd587a00 100644
--- a/server/src/main/java/org/apache/iotdb/db/mpp/plan/analyze/schema/SchemaValidator.java
+++ b/server/src/main/java/org/apache/iotdb/db/mpp/plan/analyze/schema/SchemaValidator.java
@@ -19,7 +19,6 @@
 
 package org.apache.iotdb.db.mpp.plan.analyze.schema;
 
-import org.apache.iotdb.commons.exception.MetadataException;
 import org.apache.iotdb.commons.path.PartialPath;
 import org.apache.iotdb.db.exception.query.QueryProcessException;
 import org.apache.iotdb.db.exception.sql.SemanticException;
@@ -36,33 +35,18 @@ public class SchemaValidator {
 
   private static final ISchemaFetcher SCHEMA_FETCHER = ClusterSchemaFetcher.getInstance();
 
-  public static ISchemaTree validate(InsertNode insertNode) {
-
-    ISchemaTree schemaTree;
-    if (insertNode instanceof BatchInsertNode) {
-      BatchInsertNode batchInsertNode = (BatchInsertNode) insertNode;
-      schemaTree =
-          SCHEMA_FETCHER.fetchSchemaListWithAutoCreate(
-              batchInsertNode.getDevicePaths(),
-              batchInsertNode.getMeasurementsList(),
-              batchInsertNode.getDataTypesList(),
-              batchInsertNode.getAlignedList());
-    } else {
-      schemaTree =
-          SCHEMA_FETCHER.fetchSchemaWithAutoCreate(
-              insertNode.getDevicePath(),
-              insertNode.getMeasurements(),
-              insertNode::getDataType,
-              insertNode.isAligned());
-    }
-
+  public static void validate(InsertNode insertNode) {
     try {
-      insertNode.validateAndSetSchema(schemaTree);
-    } catch (QueryProcessException | MetadataException e) {
+      if (insertNode instanceof BatchInsertNode) {
+        SCHEMA_FETCHER.fetchAndComputeSchemaWithAutoCreate(
+            ((BatchInsertNode) insertNode).getSchemaValidationList());
+      } else {
+        SCHEMA_FETCHER.fetchAndComputeSchemaWithAutoCreate(insertNode.getSchemaValidation());
+      }
+      insertNode.updateAfterSchemaValidation();
+    } catch (QueryProcessException e) {
       throw new SemanticException(e);
     }
-
-    return schemaTree;
   }
 
   public static ISchemaTree validate(
diff --git a/server/src/main/java/org/apache/iotdb/db/mpp/plan/planner/plan/node/write/BatchInsertNode.java b/server/src/main/java/org/apache/iotdb/db/mpp/plan/planner/plan/node/write/BatchInsertNode.java
index d326b53895..a0c774d5c4 100644
--- a/server/src/main/java/org/apache/iotdb/db/mpp/plan/planner/plan/node/write/BatchInsertNode.java
+++ b/server/src/main/java/org/apache/iotdb/db/mpp/plan/planner/plan/node/write/BatchInsertNode.java
@@ -19,8 +19,7 @@
 
 package org.apache.iotdb.db.mpp.plan.planner.plan.node.write;
 
-import org.apache.iotdb.commons.path.PartialPath;
-import org.apache.iotdb.tsfile.file.metadata.enums.TSDataType;
+import org.apache.iotdb.db.mpp.plan.analyze.schema.ISchemaValidation;
 
 import java.util.List;
 
@@ -30,11 +29,5 @@ import java.util.List;
  */
 public interface BatchInsertNode {
 
-  List<PartialPath> getDevicePaths();
-
-  List<String[]> getMeasurementsList();
-
-  List<TSDataType[]> getDataTypesList();
-
-  List<Boolean> getAlignedList();
+  List<ISchemaValidation> getSchemaValidationList();
 }
diff --git a/server/src/main/java/org/apache/iotdb/db/mpp/plan/planner/plan/node/write/InsertMultiTabletsNode.java b/server/src/main/java/org/apache/iotdb/db/mpp/plan/planner/plan/node/write/InsertMultiTabletsNode.java
index 6ce2eeff80..d0b46b103a 100644
--- a/server/src/main/java/org/apache/iotdb/db/mpp/plan/planner/plan/node/write/InsertMultiTabletsNode.java
+++ b/server/src/main/java/org/apache/iotdb/db/mpp/plan/planner/plan/node/write/InsertMultiTabletsNode.java
@@ -20,11 +20,9 @@ package org.apache.iotdb.db.mpp.plan.planner.plan.node.write;
 
 import org.apache.iotdb.common.rpc.thrift.TRegionReplicaSet;
 import org.apache.iotdb.common.rpc.thrift.TSStatus;
-import org.apache.iotdb.commons.exception.MetadataException;
-import org.apache.iotdb.commons.path.PartialPath;
 import org.apache.iotdb.commons.utils.StatusUtils;
-import org.apache.iotdb.db.mpp.common.schematree.ISchemaTree;
 import org.apache.iotdb.db.mpp.plan.analyze.Analysis;
+import org.apache.iotdb.db.mpp.plan.analyze.schema.ISchemaValidation;
 import org.apache.iotdb.db.mpp.plan.planner.plan.node.PlanNode;
 import org.apache.iotdb.db.mpp.plan.planner.plan.node.PlanNodeId;
 import org.apache.iotdb.db.mpp.plan.planner.plan.node.PlanNodeType;
@@ -42,6 +40,7 @@ import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
 import java.util.Objects;
+import java.util.stream.Collectors;
 
 public class InsertMultiTabletsNode extends InsertNode implements BatchInsertNode {
 
@@ -136,16 +135,6 @@ public class InsertMultiTabletsNode extends InsertNode implements BatchInsertNod
     insertTabletNodeList.forEach(plan -> plan.setSearchIndex(index));
   }
 
-  @Override
-  public void validateAndSetSchema(ISchemaTree schemaTree) throws MetadataException {
-    for (InsertTabletNode insertTabletNode : insertTabletNodeList) {
-      insertTabletNode.validateAndSetSchema(schemaTree);
-      if (!this.hasFailedMeasurements() && insertTabletNode.hasFailedMeasurements()) {
-        this.failedMeasurementIndex2Info = insertTabletNode.failedMeasurementIndex2Info;
-      }
-    }
-  }
-
   @Override
   protected boolean checkAndCastDataType(int columnIndex, TSDataType dataType) {
     return false;
@@ -205,39 +194,10 @@ public class InsertMultiTabletsNode extends InsertNode implements BatchInsertNod
   }
 
   @Override
-  public List<PartialPath> getDevicePaths() {
-    List<PartialPath> partialPaths = new ArrayList<>();
-    for (InsertTabletNode insertTabletNode : insertTabletNodeList) {
-      partialPaths.add(insertTabletNode.devicePath);
-    }
-    return partialPaths;
-  }
-
-  @Override
-  public List<String[]> getMeasurementsList() {
-    List<String[]> measurementsList = new ArrayList<>();
-    for (InsertTabletNode insertTabletNode : insertTabletNodeList) {
-      measurementsList.add(insertTabletNode.measurements);
-    }
-    return measurementsList;
-  }
-
-  @Override
-  public List<TSDataType[]> getDataTypesList() {
-    List<TSDataType[]> dataTypesList = new ArrayList<>();
-    for (InsertTabletNode insertTabletNode : insertTabletNodeList) {
-      dataTypesList.add(insertTabletNode.dataTypes);
-    }
-    return dataTypesList;
-  }
-
-  @Override
-  public List<Boolean> getAlignedList() {
-    List<Boolean> alignedList = new ArrayList<>();
-    for (InsertTabletNode insertTabletNode : insertTabletNodeList) {
-      alignedList.add(insertTabletNode.isAligned);
-    }
-    return alignedList;
+  public List<ISchemaValidation> getSchemaValidationList() {
+    return insertTabletNodeList.stream()
+        .map(InsertTabletNode::getSchemaValidation)
+        .collect(Collectors.toList());
   }
 
   public static InsertMultiTabletsNode deserialize(ByteBuffer byteBuffer) {
diff --git a/server/src/main/java/org/apache/iotdb/db/mpp/plan/planner/plan/node/write/InsertNode.java b/server/src/main/java/org/apache/iotdb/db/mpp/plan/planner/plan/node/write/InsertNode.java
index ac63f82940..0994935c95 100644
--- a/server/src/main/java/org/apache/iotdb/db/mpp/plan/planner/plan/node/write/InsertNode.java
+++ b/server/src/main/java/org/apache/iotdb/db/mpp/plan/planner/plan/node/write/InsertNode.java
@@ -19,7 +19,6 @@
 package org.apache.iotdb.db.mpp.plan.planner.plan.node.write;
 
 import org.apache.iotdb.common.rpc.thrift.TRegionReplicaSet;
-import org.apache.iotdb.commons.exception.MetadataException;
 import org.apache.iotdb.commons.path.PartialPath;
 import org.apache.iotdb.consensus.iot.wal.ConsensusReqReader;
 import org.apache.iotdb.db.conf.IoTDBDescriptor;
@@ -27,7 +26,7 @@ import org.apache.iotdb.db.exception.metadata.DataTypeMismatchException;
 import org.apache.iotdb.db.exception.metadata.PathNotExistException;
 import org.apache.iotdb.db.exception.query.QueryProcessException;
 import org.apache.iotdb.db.metadata.idtable.entry.IDeviceID;
-import org.apache.iotdb.db.mpp.common.schematree.ISchemaTree;
+import org.apache.iotdb.db.mpp.plan.analyze.schema.ISchemaValidation;
 import org.apache.iotdb.db.mpp.plan.planner.plan.node.PlanNodeId;
 import org.apache.iotdb.db.mpp.plan.planner.plan.node.WritePlanNode;
 import org.apache.iotdb.db.wal.buffer.IWALByteBufferView;
@@ -243,43 +242,46 @@ public abstract class InsertNode extends WritePlanNode {
     return dataRegionReplicaSet;
   }
 
-  public abstract void validateAndSetSchema(ISchemaTree schemaTree)
-      throws QueryProcessException, MetadataException;
+  public ISchemaValidation getSchemaValidation() {
+    throw new UnsupportedOperationException();
+  }
+
+  public void updateAfterSchemaValidation() throws QueryProcessException {}
 
   /** Check whether data types are matched with measurement schemas */
-  protected void selfCheckDataTypes() throws DataTypeMismatchException, PathNotExistException {
-    for (int i = 0; i < measurementSchemas.length; i++) {
-      if (IoTDBDescriptor.getInstance().getConfig().isEnablePartialInsert()) {
-        // if enable partial insert, mark failed measurements with exception
-        if (measurementSchemas[i] == null) {
-          markFailedMeasurement(
-              i, new PathNotExistException(devicePath.concatNode(measurements[i]).getFullPath()));
-        } else if ((dataTypes[i] != measurementSchemas[i].getType()
-            && !checkAndCastDataType(i, measurementSchemas[i].getType()))) {
-          markFailedMeasurement(
-              i,
-              new DataTypeMismatchException(
-                  devicePath.getFullPath(),
-                  measurements[i],
-                  dataTypes[i],
-                  measurementSchemas[i].getType(),
-                  getMinTime(),
-                  getFirstValueOfIndex(i)));
-        }
-      } else {
-        // if not enable partial insert, throw the exception directly
-        if (measurementSchemas[i] == null) {
-          throw new PathNotExistException(devicePath.concatNode(measurements[i]).getFullPath());
-        } else if ((dataTypes[i] != measurementSchemas[i].getType()
-            && !checkAndCastDataType(i, measurementSchemas[i].getType()))) {
-          throw new DataTypeMismatchException(
-              devicePath.getFullPath(),
-              measurements[i],
-              dataTypes[i],
-              measurementSchemas[i].getType(),
-              getMinTime(),
-              getFirstValueOfIndex(i));
-        }
+  protected void selfCheckDataTypes(int index)
+      throws DataTypeMismatchException, PathNotExistException {
+    if (IoTDBDescriptor.getInstance().getConfig().isEnablePartialInsert()) {
+      // if enable partial insert, mark failed measurements with exception
+      if (measurementSchemas[index] == null) {
+        markFailedMeasurement(
+            index,
+            new PathNotExistException(devicePath.concatNode(measurements[index]).getFullPath()));
+      } else if ((dataTypes[index] != measurementSchemas[index].getType()
+          && !checkAndCastDataType(index, measurementSchemas[index].getType()))) {
+        markFailedMeasurement(
+            index,
+            new DataTypeMismatchException(
+                devicePath.getFullPath(),
+                measurements[index],
+                dataTypes[index],
+                measurementSchemas[index].getType(),
+                getMinTime(),
+                getFirstValueOfIndex(index)));
+      }
+    } else {
+      // if not enable partial insert, throw the exception directly
+      if (measurementSchemas[index] == null) {
+        throw new PathNotExistException(devicePath.concatNode(measurements[index]).getFullPath());
+      } else if ((dataTypes[index] != measurementSchemas[index].getType()
+          && !checkAndCastDataType(index, measurementSchemas[index].getType()))) {
+        throw new DataTypeMismatchException(
+            devicePath.getFullPath(),
+            measurements[index],
+            dataTypes[index],
+            measurementSchemas[index].getType(),
+            getMinTime(),
+            getFirstValueOfIndex(index));
       }
     }
   }
diff --git a/server/src/main/java/org/apache/iotdb/db/mpp/plan/planner/plan/node/write/InsertRowNode.java b/server/src/main/java/org/apache/iotdb/db/mpp/plan/planner/plan/node/write/InsertRowNode.java
index 36cba297e3..e599e26344 100644
--- a/server/src/main/java/org/apache/iotdb/db/mpp/plan/planner/plan/node/write/InsertRowNode.java
+++ b/server/src/main/java/org/apache/iotdb/db/mpp/plan/planner/plan/node/write/InsertRowNode.java
@@ -21,16 +21,17 @@ package org.apache.iotdb.db.mpp.plan.planner.plan.node.write;
 import org.apache.iotdb.common.rpc.thrift.TTimePartitionSlot;
 import org.apache.iotdb.commons.conf.IoTDBConstant;
 import org.apache.iotdb.commons.exception.IllegalPathException;
-import org.apache.iotdb.commons.exception.MetadataException;
 import org.apache.iotdb.commons.path.PartialPath;
 import org.apache.iotdb.commons.utils.TestOnly;
 import org.apache.iotdb.db.conf.IoTDBDescriptor;
 import org.apache.iotdb.db.exception.metadata.AlignedTimeseriesException;
+import org.apache.iotdb.db.exception.metadata.DataTypeMismatchException;
 import org.apache.iotdb.db.exception.metadata.PathNotExistException;
 import org.apache.iotdb.db.exception.query.QueryProcessException;
-import org.apache.iotdb.db.mpp.common.schematree.DeviceSchemaInfo;
-import org.apache.iotdb.db.mpp.common.schematree.ISchemaTree;
+import org.apache.iotdb.db.exception.sql.SemanticException;
+import org.apache.iotdb.db.mpp.common.schematree.IMeasurementSchemaInfo;
 import org.apache.iotdb.db.mpp.plan.analyze.Analysis;
+import org.apache.iotdb.db.mpp.plan.analyze.schema.ISchemaValidation;
 import org.apache.iotdb.db.mpp.plan.planner.plan.node.PlanNode;
 import org.apache.iotdb.db.mpp.plan.planner.plan.node.PlanNodeId;
 import org.apache.iotdb.db.mpp.plan.planner.plan.node.PlanNodeType;
@@ -42,9 +43,10 @@ import org.apache.iotdb.db.utils.TypeInferenceUtils;
 import org.apache.iotdb.db.wal.buffer.IWALByteBufferView;
 import org.apache.iotdb.db.wal.buffer.WALEntryValue;
 import org.apache.iotdb.db.wal.utils.WALWriteUtils;
-import org.apache.iotdb.tsfile.common.constant.TsFileConstant;
 import org.apache.iotdb.tsfile.exception.NotImplementedException;
+import org.apache.iotdb.tsfile.file.metadata.enums.CompressionType;
 import org.apache.iotdb.tsfile.file.metadata.enums.TSDataType;
+import org.apache.iotdb.tsfile.file.metadata.enums.TSEncoding;
 import org.apache.iotdb.tsfile.read.TimeValuePair;
 import org.apache.iotdb.tsfile.utils.Binary;
 import org.apache.iotdb.tsfile.utils.ReadWriteIOUtils;
@@ -63,9 +65,8 @@ import java.util.Collections;
 import java.util.HashMap;
 import java.util.List;
 import java.util.Objects;
-import java.util.stream.Collectors;
 
-public class InsertRowNode extends InsertNode implements WALEntryValue {
+public class InsertRowNode extends InsertNode implements WALEntryValue, ISchemaValidation {
 
   private static final Logger logger = LoggerFactory.getLogger(InsertRowNode.class);
 
@@ -152,6 +153,16 @@ public class InsertRowNode extends InsertNode implements WALEntryValue {
     }
   }
 
+  @Override
+  public TSEncoding getEncoding(int index) {
+    return null;
+  }
+
+  @Override
+  public CompressionType getCompressionType(int index) {
+    return null;
+  }
+
   public Object[] getValues() {
     return values;
   }
@@ -181,38 +192,6 @@ public class InsertRowNode extends InsertNode implements WALEntryValue {
     return Collections.singletonList(TimePartitionUtils.getTimePartition(time));
   }
 
-  @Override
-  public void validateAndSetSchema(ISchemaTree schemaTree)
-      throws QueryProcessException, MetadataException {
-    DeviceSchemaInfo deviceSchemaInfo =
-        schemaTree.searchDeviceSchemaInfo(devicePath, Arrays.asList(measurements));
-    if (deviceSchemaInfo == null) {
-      throw new PathNotExistException(
-          Arrays.stream(measurements)
-              .map(s -> devicePath.getFullPath() + TsFileConstant.PATH_SEPARATOR + s)
-              .collect(Collectors.toList()));
-    }
-    if (deviceSchemaInfo.isAligned() != isAligned) {
-      throw new AlignedTimeseriesException(
-          String.format(
-              "timeseries under this device are%s aligned, " + "please use %s interface",
-              deviceSchemaInfo.isAligned() ? "" : " not",
-              deviceSchemaInfo.isAligned() ? "aligned" : "non-aligned"),
-          devicePath.getFullPath());
-    }
-    this.measurementSchemas =
-        deviceSchemaInfo.getMeasurementSchemaList().toArray(new MeasurementSchema[0]);
-
-    // transfer data types from string values when necessary
-    if (isNeedInferType) {
-      transferType();
-      return;
-    }
-
-    // validate whether data types are matched
-    selfCheckDataTypes();
-  }
-
   @Override
   protected boolean checkAndCastDataType(int columnIndex, TSDataType dataType) {
     if (CommonUtils.checkCanCastType(dataTypes[columnIndex], dataType)) {
@@ -827,4 +806,49 @@ public class InsertRowNode extends InsertNode implements WALEntryValue {
     Object value = values[columnIndex];
     return new TimeValuePair(time, TsPrimitiveType.getByType(dataTypes[columnIndex], value));
   }
+
+  @Override
+  public void validateDeviceSchema(boolean isAligned) {
+    if (this.isAligned != isAligned) {
+      throw new SemanticException(
+          new AlignedTimeseriesException(
+              String.format(
+                  "timeseries under this device are%s aligned, " + "please use %s interface",
+                  isAligned ? "" : " not", isAligned ? "aligned" : "non-aligned"),
+              devicePath.getFullPath()));
+    }
+  }
+
+  @Override
+  public ISchemaValidation getSchemaValidation() {
+    return this;
+  }
+
+  @Override
+  public void updateAfterSchemaValidation() throws QueryProcessException {
+    if (isNeedInferType) {
+      transferType();
+    }
+  }
+
+  @Override
+  public void validateMeasurementSchema(int index, IMeasurementSchemaInfo measurementSchemaInfo) {
+    if (measurementSchemas == null) {
+      measurementSchemas = new MeasurementSchema[measurements.length];
+    }
+    if (measurementSchemaInfo == null) {
+      measurementSchemas[index] = null;
+    } else {
+      measurementSchemas[index] = measurementSchemaInfo.getSchema();
+    }
+    if (isNeedInferType) {
+      return;
+    }
+
+    try {
+      selfCheckDataTypes(index);
+    } catch (DataTypeMismatchException | PathNotExistException e) {
+      throw new SemanticException(e);
+    }
+  }
 }
diff --git a/server/src/main/java/org/apache/iotdb/db/mpp/plan/planner/plan/node/write/InsertRowsNode.java b/server/src/main/java/org/apache/iotdb/db/mpp/plan/planner/plan/node/write/InsertRowsNode.java
index 70cfaa63b2..3cb42dda31 100644
--- a/server/src/main/java/org/apache/iotdb/db/mpp/plan/planner/plan/node/write/InsertRowsNode.java
+++ b/server/src/main/java/org/apache/iotdb/db/mpp/plan/planner/plan/node/write/InsertRowsNode.java
@@ -20,12 +20,10 @@ package org.apache.iotdb.db.mpp.plan.planner.plan.node.write;
 
 import org.apache.iotdb.common.rpc.thrift.TRegionReplicaSet;
 import org.apache.iotdb.common.rpc.thrift.TSStatus;
-import org.apache.iotdb.commons.exception.MetadataException;
-import org.apache.iotdb.commons.path.PartialPath;
 import org.apache.iotdb.commons.utils.StatusUtils;
 import org.apache.iotdb.db.exception.query.QueryProcessException;
-import org.apache.iotdb.db.mpp.common.schematree.ISchemaTree;
 import org.apache.iotdb.db.mpp.plan.analyze.Analysis;
+import org.apache.iotdb.db.mpp.plan.analyze.schema.ISchemaValidation;
 import org.apache.iotdb.db.mpp.plan.planner.plan.node.PlanNode;
 import org.apache.iotdb.db.mpp.plan.planner.plan.node.PlanNodeId;
 import org.apache.iotdb.db.mpp.plan.planner.plan.node.PlanNodeType;
@@ -44,6 +42,7 @@ import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
 import java.util.Objects;
+import java.util.stream.Collectors;
 
 public class InsertRowsNode extends InsertNode implements BatchInsertNode {
 
@@ -121,17 +120,6 @@ public class InsertRowsNode extends InsertNode implements BatchInsertNode {
   @Override
   public void addChild(PlanNode child) {}
 
-  @Override
-  public void validateAndSetSchema(ISchemaTree schemaTree)
-      throws QueryProcessException, MetadataException {
-    for (InsertRowNode insertRowNode : insertRowNodeList) {
-      insertRowNode.validateAndSetSchema(schemaTree);
-      if (!this.hasFailedMeasurements() && insertRowNode.hasFailedMeasurements()) {
-        this.failedMeasurementIndex2Info = insertRowNode.failedMeasurementIndex2Info;
-      }
-    }
-  }
-
   @Override
   protected boolean checkAndCastDataType(int columnIndex, TSDataType dataType) {
     return false;
@@ -168,39 +156,20 @@ public class InsertRowsNode extends InsertNode implements BatchInsertNode {
   }
 
   @Override
-  public List<PartialPath> getDevicePaths() {
-    List<PartialPath> partialPaths = new ArrayList<>();
-    for (InsertRowNode insertRowNode : insertRowNodeList) {
-      partialPaths.add(insertRowNode.devicePath);
-    }
-    return partialPaths;
+  public List<ISchemaValidation> getSchemaValidationList() {
+    return insertRowNodeList.stream()
+        .map(InsertRowNode::getSchemaValidation)
+        .collect(Collectors.toList());
   }
 
   @Override
-  public List<String[]> getMeasurementsList() {
-    List<String[]> measurementsList = new ArrayList<>();
+  public void updateAfterSchemaValidation() throws QueryProcessException {
     for (InsertRowNode insertRowNode : insertRowNodeList) {
-      measurementsList.add(insertRowNode.measurements);
-    }
-    return measurementsList;
-  }
-
-  @Override
-  public List<TSDataType[]> getDataTypesList() {
-    List<TSDataType[]> dataTypesList = new ArrayList<>();
-    for (InsertRowNode insertRowNode : insertRowNodeList) {
-      dataTypesList.add(insertRowNode.getDataTypes());
-    }
-    return dataTypesList;
-  }
-
-  @Override
-  public List<Boolean> getAlignedList() {
-    List<Boolean> alignedList = new ArrayList<>();
-    for (InsertRowNode insertRowNode : insertRowNodeList) {
-      alignedList.add(insertRowNode.isAligned);
+      insertRowNode.updateAfterSchemaValidation();
+      if (!this.hasFailedMeasurements() && insertRowNode.hasFailedMeasurements()) {
+        this.failedMeasurementIndex2Info = insertRowNode.failedMeasurementIndex2Info;
+      }
     }
-    return alignedList;
   }
 
   public static InsertRowsNode deserialize(ByteBuffer byteBuffer) {
diff --git a/server/src/main/java/org/apache/iotdb/db/mpp/plan/planner/plan/node/write/InsertRowsOfOneDeviceNode.java b/server/src/main/java/org/apache/iotdb/db/mpp/plan/planner/plan/node/write/InsertRowsOfOneDeviceNode.java
index 70ea605e9a..710c5b7d89 100644
--- a/server/src/main/java/org/apache/iotdb/db/mpp/plan/planner/plan/node/write/InsertRowsOfOneDeviceNode.java
+++ b/server/src/main/java/org/apache/iotdb/db/mpp/plan/planner/plan/node/write/InsertRowsOfOneDeviceNode.java
@@ -21,12 +21,11 @@ package org.apache.iotdb.db.mpp.plan.planner.plan.node.write;
 import org.apache.iotdb.common.rpc.thrift.TRegionReplicaSet;
 import org.apache.iotdb.common.rpc.thrift.TSStatus;
 import org.apache.iotdb.commons.exception.IllegalPathException;
-import org.apache.iotdb.commons.exception.MetadataException;
 import org.apache.iotdb.commons.path.PartialPath;
 import org.apache.iotdb.commons.utils.StatusUtils;
 import org.apache.iotdb.db.exception.query.QueryProcessException;
-import org.apache.iotdb.db.mpp.common.schematree.ISchemaTree;
 import org.apache.iotdb.db.mpp.plan.analyze.Analysis;
+import org.apache.iotdb.db.mpp.plan.analyze.schema.ISchemaValidation;
 import org.apache.iotdb.db.mpp.plan.planner.plan.node.PlanNode;
 import org.apache.iotdb.db.mpp.plan.planner.plan.node.PlanNodeId;
 import org.apache.iotdb.db.mpp.plan.planner.plan.node.PlanNodeType;
@@ -41,13 +40,13 @@ import java.io.DataOutputStream;
 import java.io.IOException;
 import java.nio.ByteBuffer;
 import java.util.ArrayList;
-import java.util.Collections;
 import java.util.HashMap;
 import java.util.HashSet;
 import java.util.List;
 import java.util.Map;
 import java.util.Objects;
 import java.util.Set;
+import java.util.stream.Collectors;
 
 public class InsertRowsOfOneDeviceNode extends InsertNode implements BatchInsertNode {
 
@@ -144,17 +143,6 @@ public class InsertRowsOfOneDeviceNode extends InsertNode implements BatchInsert
     return null;
   }
 
-  @Override
-  public void validateAndSetSchema(ISchemaTree schemaTree)
-      throws QueryProcessException, MetadataException {
-    for (InsertRowNode insertRowNode : insertRowNodeList) {
-      insertRowNode.validateAndSetSchema(schemaTree);
-      if (!this.hasFailedMeasurements() && insertRowNode.hasFailedMeasurements()) {
-        this.failedMeasurementIndex2Info = insertRowNode.failedMeasurementIndex2Info;
-      }
-    }
-  }
-
   @Override
   protected boolean checkAndCastDataType(int columnIndex, TSDataType dataType) {
     return false;
@@ -297,35 +285,20 @@ public class InsertRowsOfOneDeviceNode extends InsertNode implements BatchInsert
   }
 
   @Override
-  public List<PartialPath> getDevicePaths() {
-    if (insertRowNodeList == null || insertRowNodeList.isEmpty()) {
-      return Collections.emptyList();
-    }
-    return Collections.singletonList(insertRowNodeList.get(0).devicePath);
+  public List<ISchemaValidation> getSchemaValidationList() {
+    return insertRowNodeList.stream()
+        .map(InsertRowNode::getSchemaValidation)
+        .collect(Collectors.toList());
   }
 
   @Override
-  public List<String[]> getMeasurementsList() {
-    if (insertRowNodeList == null || insertRowNodeList.isEmpty()) {
-      return Collections.emptyList();
-    }
-    return Collections.singletonList(measurements);
-  }
-
-  @Override
-  public List<TSDataType[]> getDataTypesList() {
-    if (insertRowNodeList == null || insertRowNodeList.isEmpty()) {
-      return Collections.emptyList();
-    }
-    return Collections.singletonList(dataTypes);
-  }
-
-  @Override
-  public List<Boolean> getAlignedList() {
-    if (insertRowNodeList == null || insertRowNodeList.isEmpty()) {
-      return Collections.emptyList();
+  public void updateAfterSchemaValidation() throws QueryProcessException {
+    for (InsertRowNode insertRowNode : insertRowNodeList) {
+      insertRowNode.updateAfterSchemaValidation();
+      if (!this.hasFailedMeasurements() && insertRowNode.hasFailedMeasurements()) {
+        this.failedMeasurementIndex2Info = insertRowNode.failedMeasurementIndex2Info;
+      }
     }
-    return Collections.singletonList(insertRowNodeList.get(0).isAligned);
   }
 
   @Override
diff --git a/server/src/main/java/org/apache/iotdb/db/mpp/plan/planner/plan/node/write/InsertTabletNode.java b/server/src/main/java/org/apache/iotdb/db/mpp/plan/planner/plan/node/write/InsertTabletNode.java
index 250bbf1679..c023792b95 100644
--- a/server/src/main/java/org/apache/iotdb/db/mpp/plan/planner/plan/node/write/InsertTabletNode.java
+++ b/server/src/main/java/org/apache/iotdb/db/mpp/plan/planner/plan/node/write/InsertTabletNode.java
@@ -21,14 +21,15 @@ package org.apache.iotdb.db.mpp.plan.planner.plan.node.write;
 import org.apache.iotdb.common.rpc.thrift.TRegionReplicaSet;
 import org.apache.iotdb.common.rpc.thrift.TTimePartitionSlot;
 import org.apache.iotdb.commons.exception.IllegalPathException;
-import org.apache.iotdb.commons.exception.MetadataException;
 import org.apache.iotdb.commons.path.PartialPath;
 import org.apache.iotdb.commons.utils.TestOnly;
 import org.apache.iotdb.db.exception.metadata.AlignedTimeseriesException;
+import org.apache.iotdb.db.exception.metadata.DataTypeMismatchException;
 import org.apache.iotdb.db.exception.metadata.PathNotExistException;
-import org.apache.iotdb.db.mpp.common.schematree.DeviceSchemaInfo;
-import org.apache.iotdb.db.mpp.common.schematree.ISchemaTree;
+import org.apache.iotdb.db.exception.sql.SemanticException;
+import org.apache.iotdb.db.mpp.common.schematree.IMeasurementSchemaInfo;
 import org.apache.iotdb.db.mpp.plan.analyze.Analysis;
+import org.apache.iotdb.db.mpp.plan.analyze.schema.ISchemaValidation;
 import org.apache.iotdb.db.mpp.plan.planner.plan.node.PlanNode;
 import org.apache.iotdb.db.mpp.plan.planner.plan.node.PlanNodeId;
 import org.apache.iotdb.db.mpp.plan.planner.plan.node.PlanNodeType;
@@ -40,10 +41,11 @@ import org.apache.iotdb.db.utils.TimePartitionUtils;
 import org.apache.iotdb.db.wal.buffer.IWALByteBufferView;
 import org.apache.iotdb.db.wal.buffer.WALEntryValue;
 import org.apache.iotdb.db.wal.utils.WALWriteUtils;
-import org.apache.iotdb.tsfile.common.constant.TsFileConstant;
 import org.apache.iotdb.tsfile.exception.NotImplementedException;
 import org.apache.iotdb.tsfile.exception.write.UnSupportedDataTypeException;
+import org.apache.iotdb.tsfile.file.metadata.enums.CompressionType;
 import org.apache.iotdb.tsfile.file.metadata.enums.TSDataType;
+import org.apache.iotdb.tsfile.file.metadata.enums.TSEncoding;
 import org.apache.iotdb.tsfile.read.TimeValuePair;
 import org.apache.iotdb.tsfile.utils.Binary;
 import org.apache.iotdb.tsfile.utils.BitMap;
@@ -66,9 +68,8 @@ import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
 import java.util.Objects;
-import java.util.stream.Collectors;
 
-public class InsertTabletNode extends InsertNode implements WALEntryValue {
+public class InsertTabletNode extends InsertNode implements WALEntryValue, ISchemaValidation {
 
   private static final Logger logger = LoggerFactory.getLogger(InsertTabletNode.class);
 
@@ -176,31 +177,6 @@ public class InsertTabletNode extends InsertNode implements WALEntryValue {
     return null;
   }
 
-  @Override
-  public void validateAndSetSchema(ISchemaTree schemaTree) throws MetadataException {
-    DeviceSchemaInfo deviceSchemaInfo =
-        schemaTree.searchDeviceSchemaInfo(devicePath, Arrays.asList(measurements));
-    if (deviceSchemaInfo == null) {
-      throw new PathNotExistException(
-          Arrays.stream(measurements)
-              .map(s -> devicePath.getFullPath() + TsFileConstant.PATH_SEPARATOR + s)
-              .collect(Collectors.toList()));
-    }
-    if (deviceSchemaInfo.isAligned() != isAligned) {
-      throw new AlignedTimeseriesException(
-          String.format(
-              "timeseries under this device are%s aligned, " + "please use %s interface",
-              deviceSchemaInfo.isAligned() ? "" : " not",
-              deviceSchemaInfo.isAligned() ? "aligned" : "non-aligned"),
-          devicePath.getFullPath());
-    }
-    measurementSchemas =
-        deviceSchemaInfo.getMeasurementSchemaList().toArray(new MeasurementSchema[0]);
-
-    // validate whether data types are matched
-    selfCheckDataTypes();
-  }
-
   @Override
   protected boolean checkAndCastDataType(int columnIndex, TSDataType dataType) {
     if (CommonUtils.checkCanCastType(dataTypes[columnIndex], dataType)) {
@@ -1138,4 +1114,49 @@ public class InsertTabletNode extends InsertNode implements WALEntryValue {
     }
     return new TimeValuePair(times[lastIdx], value);
   }
+
+  @Override
+  public TSEncoding getEncoding(int index) {
+    return null;
+  }
+
+  @Override
+  public CompressionType getCompressionType(int index) {
+    return null;
+  }
+
+  @Override
+  public void validateDeviceSchema(boolean isAligned) {
+    if (this.isAligned != isAligned) {
+      throw new SemanticException(
+          new AlignedTimeseriesException(
+              String.format(
+                  "timeseries under this device are%s aligned, " + "please use %s interface",
+                  isAligned ? "" : " not", isAligned ? "aligned" : "non-aligned"),
+              devicePath.getFullPath()));
+    }
+  }
+
+  @Override
+  public ISchemaValidation getSchemaValidation() {
+    return this;
+  }
+
+  @Override
+  public void validateMeasurementSchema(int index, IMeasurementSchemaInfo measurementSchemaInfo) {
+    if (measurementSchemas == null) {
+      measurementSchemas = new MeasurementSchema[measurements.length];
+    }
+    if (measurementSchemaInfo == null) {
+      measurementSchemas[index] = null;
+    } else {
+      measurementSchemas[index] = measurementSchemaInfo.getSchema();
+    }
+
+    try {
+      selfCheckDataTypes(index);
+    } catch (DataTypeMismatchException | PathNotExistException e) {
+      throw new SemanticException(e);
+    }
+  }
 }
diff --git a/server/src/test/java/org/apache/iotdb/db/mpp/plan/analyze/FakeSchemaFetcherImpl.java b/server/src/test/java/org/apache/iotdb/db/mpp/plan/analyze/FakeSchemaFetcherImpl.java
index a65b83d03a..c294422d93 100644
--- a/server/src/test/java/org/apache/iotdb/db/mpp/plan/analyze/FakeSchemaFetcherImpl.java
+++ b/server/src/test/java/org/apache/iotdb/db/mpp/plan/analyze/FakeSchemaFetcherImpl.java
@@ -28,6 +28,7 @@ import org.apache.iotdb.db.mpp.common.schematree.node.SchemaEntityNode;
 import org.apache.iotdb.db.mpp.common.schematree.node.SchemaInternalNode;
 import org.apache.iotdb.db.mpp.common.schematree.node.SchemaMeasurementNode;
 import org.apache.iotdb.db.mpp.common.schematree.node.SchemaNode;
+import org.apache.iotdb.db.mpp.plan.analyze.schema.ISchemaComputationWithAutoCreation;
 import org.apache.iotdb.db.mpp.plan.analyze.schema.ISchemaFetcher;
 import org.apache.iotdb.tsfile.file.metadata.enums.CompressionType;
 import org.apache.iotdb.tsfile.file.metadata.enums.TSDataType;
@@ -38,7 +39,6 @@ import org.apache.iotdb.tsfile.write.schema.MeasurementSchema;
 import java.util.Collections;
 import java.util.List;
 import java.util.Map;
-import java.util.function.Function;
 
 public class FakeSchemaFetcherImpl implements ISchemaFetcher {
 
@@ -56,13 +56,12 @@ public class FakeSchemaFetcherImpl implements ISchemaFetcher {
   }
 
   @Override
-  public ISchemaTree fetchSchemaWithAutoCreate(
-      PartialPath devicePath,
-      String[] measurements,
-      Function<Integer, TSDataType> getDataType,
-      boolean aligned) {
-    return schemaTree;
-  }
+  public void fetchAndComputeSchemaWithAutoCreate(
+      ISchemaComputationWithAutoCreation schemaComputationWithAutoCreation) {}
+
+  @Override
+  public void fetchAndComputeSchemaWithAutoCreate(
+      List<? extends ISchemaComputationWithAutoCreation> schemaComputationWithAutoCreationList) {}
 
   /**
    * Generate the following tree: root.sg.d1.s1, root.sg.d1.s2(status) root.sg.d2.s1,
@@ -114,15 +113,6 @@ public class FakeSchemaFetcherImpl implements ISchemaFetcher {
     return root;
   }
 
-  @Override
-  public ISchemaTree fetchSchemaListWithAutoCreate(
-      List<PartialPath> devicePath,
-      List<String[]> measurements,
-      List<TSDataType[]> tsDataTypes,
-      List<Boolean> aligned) {
-    return null;
-  }
-
   @Override
   public ISchemaTree fetchSchemaListWithAutoCreate(
       List<PartialPath> devicePath,
diff --git a/server/src/test/java/org/apache/iotdb/db/mpp/plan/plan/distribution/Util.java b/server/src/test/java/org/apache/iotdb/db/mpp/plan/plan/distribution/Util.java
index 7c908b2f4d..8c2d00a34f 100644
--- a/server/src/test/java/org/apache/iotdb/db/mpp/plan/plan/distribution/Util.java
+++ b/server/src/test/java/org/apache/iotdb/db/mpp/plan/plan/distribution/Util.java
@@ -46,6 +46,7 @@ import org.apache.iotdb.db.mpp.common.schematree.node.SchemaNode;
 import org.apache.iotdb.db.mpp.plan.analyze.Analysis;
 import org.apache.iotdb.db.mpp.plan.analyze.Analyzer;
 import org.apache.iotdb.db.mpp.plan.analyze.IPartitionFetcher;
+import org.apache.iotdb.db.mpp.plan.analyze.schema.ISchemaComputationWithAutoCreation;
 import org.apache.iotdb.db.mpp.plan.analyze.schema.ISchemaFetcher;
 import org.apache.iotdb.db.mpp.plan.expression.Expression;
 import org.apache.iotdb.db.mpp.plan.expression.leaf.TimeSeriesOperand;
@@ -69,7 +70,6 @@ import java.util.HashSet;
 import java.util.List;
 import java.util.Map;
 import java.util.Set;
-import java.util.function.Function;
 
 public class Util {
   public static final Analysis ANALYSIS = constructAnalysis();
@@ -304,22 +304,13 @@ public class Util {
       }
 
       @Override
-      public ISchemaTree fetchSchemaWithAutoCreate(
-          PartialPath devicePath,
-          String[] measurements,
-          Function<Integer, TSDataType> getDataType,
-          boolean aligned) {
-        return ANALYSIS.getSchemaTree();
-      }
+      public void fetchAndComputeSchemaWithAutoCreate(
+          ISchemaComputationWithAutoCreation schemaComputationWithAutoCreation) {}
 
       @Override
-      public ISchemaTree fetchSchemaListWithAutoCreate(
-          List<PartialPath> devicePath,
-          List<String[]> measurements,
-          List<TSDataType[]> tsDataTypes,
-          List<Boolean> aligned) {
-        return ANALYSIS.getSchemaTree();
-      }
+      public void fetchAndComputeSchemaWithAutoCreate(
+          List<? extends ISchemaComputationWithAutoCreation>
+              schemaComputationWithAutoCreationList) {}
 
       @Override
       public ISchemaTree fetchSchemaListWithAutoCreate(