You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@iotdb.apache.org by ja...@apache.org on 2022/04/19 06:04:42 UTC

[iotdb] branch master updated: [IOTDB-2803][new cluster][mpp] refine show plan node ser/deserialize (#5581)

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

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


The following commit(s) were added to refs/heads/master by this push:
     new 8a00e48876 [IOTDB-2803][new cluster][mpp] refine show plan node ser/deserialize  (#5581)
8a00e48876 is described below

commit 8a00e4887632828b05f97ba3c00bf7cf3da9d799
Author: xinzhongtianxia <45...@qq.com>
AuthorDate: Tue Apr 19 14:04:36 2022 +0800

    [IOTDB-2803][new cluster][mpp] refine show plan node ser/deserialize  (#5581)
---
 .../operator/schema/DevicesSchemaScanOperator.java | 12 +---
 .../db/mpp/operator/schema/SchemaScanOperator.java | 17 +++--
 .../schema/TimeSeriesSchemaScanOperator.java       | 12 +---
 .../apache/iotdb/db/mpp/sql/analyze/Analyzer.java  |  8 ++-
 .../db/mpp/sql/planner/LocalExecutionPlanner.java  |  8 +--
 .../iotdb/db/mpp/sql/planner/QueryPlanBuilder.java |  9 ++-
 .../db/mpp/sql/planner/plan/node/PlanNodeType.java | 12 ++--
 .../node/metedata/read/DevicesSchemaScanNode.java  | 47 ++++++-------
 .../plan/node/metedata/read/SchemaFetchNode.java   |  6 --
 .../plan/node/metedata/read/SchemaScanNode.java    | 27 +++++---
 .../plan/node/metedata/read/ShowDevicesNode.java   | 67 ------------------
 .../planner/plan/node/metedata/read/ShowNode.java  | 36 ----------
 .../metedata/read/TimeSeriesSchemaScanNode.java    | 51 +++++++-------
 .../metadata/ShowStorageGroupStatement.java        |  7 ++
 .../{ => schema}/SchemaScanOperatorTest.java       | 20 +++---
 .../read/DeviceSchemaScanNodeSerdeTest.java        | 76 +++++++++++++++++++++
 .../metadata/read/ShowDevicesNodeSerdeTest.java    | 42 ------------
 .../read/TimeSeriesSchemaScanNodeSerdeTest.java    | 79 ++++++++++++++++++++++
 .../plan/node/process/AggregateNodeSerdeTest.java  | 15 +++-
 .../node/process/DeviceMergeNodeSerdeTest.java     | 17 +++--
 .../plan/node/process/ExchangeNodeSerdeTest.java   | 19 ++++--
 .../sql/plan/node/process/FillNodeSerdeTest.java   | 17 +++--
 .../sql/plan/node/process/FilterNodeSerdeTest.java | 17 +++--
 .../plan/node/process/FilterNullNodeSerdeTest.java | 17 +++--
 .../node/process/GroupByLevelNodeSerdeTest.java    | 17 +++--
 .../sql/plan/node/process/LimitNodeSerdeTest.java  | 17 +++--
 .../sql/plan/node/process/OffsetNodeSerdeTest.java | 15 ++--
 .../sql/plan/node/process/SortNodeSerdeTest.java   | 18 +++--
 .../plan/node/process/TimeJoinNodeSerdeTest.java   | 19 ++++--
 .../plan/node/sink/FragmentSinkNodeSerdeTest.java  |  7 +-
 .../iotdb/tsfile/utils/ReadWriteIOUtils.java       | 12 ++++
 31 files changed, 439 insertions(+), 304 deletions(-)

diff --git a/server/src/main/java/org/apache/iotdb/db/mpp/operator/schema/DevicesSchemaScanOperator.java b/server/src/main/java/org/apache/iotdb/db/mpp/operator/schema/DevicesSchemaScanOperator.java
index 2284239cef..c13fcf97d2 100644
--- a/server/src/main/java/org/apache/iotdb/db/mpp/operator/schema/DevicesSchemaScanOperator.java
+++ b/server/src/main/java/org/apache/iotdb/db/mpp/operator/schema/DevicesSchemaScanOperator.java
@@ -31,7 +31,6 @@ import org.apache.iotdb.tsfile.read.common.block.TsBlockBuilder;
 import org.apache.iotdb.tsfile.utils.Binary;
 
 import java.util.Arrays;
-import java.util.List;
 
 public class DevicesSchemaScanOperator extends SchemaScanOperator {
   private final boolean hasSgCol;
@@ -45,14 +44,14 @@ public class DevicesSchemaScanOperator extends SchemaScanOperator {
   };
 
   public DevicesSchemaScanOperator(
+      PlanNodeId sourceId,
       OperatorContext operatorContext,
       int limit,
       int offset,
       PartialPath partialPath,
       boolean isPrefixPath,
-      boolean hasSgCol,
-      List<String> columns) {
-    super(operatorContext, limit, offset, partialPath, isPrefixPath, columns);
+      boolean hasSgCol) {
+    super(sourceId, operatorContext, limit, offset, partialPath, isPrefixPath);
     this.hasSgCol = hasSgCol;
   }
 
@@ -89,9 +88,4 @@ public class DevicesSchemaScanOperator extends SchemaScanOperator {
     }
     builder.declarePosition();
   }
-
-  @Override
-  public PlanNodeId getSourceId() {
-    return null;
-  }
 }
diff --git a/server/src/main/java/org/apache/iotdb/db/mpp/operator/schema/SchemaScanOperator.java b/server/src/main/java/org/apache/iotdb/db/mpp/operator/schema/SchemaScanOperator.java
index 6fa48dc67c..52b1c4afc3 100644
--- a/server/src/main/java/org/apache/iotdb/db/mpp/operator/schema/SchemaScanOperator.java
+++ b/server/src/main/java/org/apache/iotdb/db/mpp/operator/schema/SchemaScanOperator.java
@@ -21,10 +21,9 @@ package org.apache.iotdb.db.mpp.operator.schema;
 import org.apache.iotdb.db.metadata.path.PartialPath;
 import org.apache.iotdb.db.mpp.operator.OperatorContext;
 import org.apache.iotdb.db.mpp.operator.source.SourceOperator;
+import org.apache.iotdb.db.mpp.sql.planner.plan.node.PlanNodeId;
 import org.apache.iotdb.tsfile.read.common.block.TsBlock;
 
-import java.util.List;
-
 public abstract class SchemaScanOperator implements SourceOperator {
 
   protected OperatorContext operatorContext;
@@ -35,21 +34,22 @@ public abstract class SchemaScanOperator implements SourceOperator {
   protected int offset;
   protected PartialPath partialPath;
   protected boolean isPrefixPath;
-  protected List<String> columns;
+
+  protected PlanNodeId sourceId;
 
   protected SchemaScanOperator(
+      PlanNodeId sourceId,
       OperatorContext operatorContext,
       int limit,
       int offset,
       PartialPath partialPath,
-      boolean isPrefixPath,
-      List<String> columns) {
+      boolean isPrefixPath) {
     this.operatorContext = operatorContext;
     this.limit = limit;
     this.offset = offset;
     this.partialPath = partialPath;
     this.isPrefixPath = isPrefixPath;
-    this.columns = columns;
+    this.sourceId = sourceId;
   }
 
   protected abstract TsBlock createTsBlock();
@@ -104,4 +104,9 @@ public abstract class SchemaScanOperator implements SourceOperator {
   public boolean isFinished() {
     return !hasNext();
   }
+
+  @Override
+  public PlanNodeId getSourceId() {
+    return sourceId;
+  }
 }
diff --git a/server/src/main/java/org/apache/iotdb/db/mpp/operator/schema/TimeSeriesSchemaScanOperator.java b/server/src/main/java/org/apache/iotdb/db/mpp/operator/schema/TimeSeriesSchemaScanOperator.java
index 0a6fbce960..39dcf0c741 100644
--- a/server/src/main/java/org/apache/iotdb/db/mpp/operator/schema/TimeSeriesSchemaScanOperator.java
+++ b/server/src/main/java/org/apache/iotdb/db/mpp/operator/schema/TimeSeriesSchemaScanOperator.java
@@ -31,7 +31,6 @@ import org.apache.iotdb.tsfile.read.common.block.TsBlockBuilder;
 import org.apache.iotdb.tsfile.utils.Binary;
 
 import java.util.Arrays;
-import java.util.List;
 import java.util.Map;
 import java.util.stream.Collectors;
 
@@ -55,6 +54,7 @@ public class TimeSeriesSchemaScanOperator extends SchemaScanOperator {
   };
 
   public TimeSeriesSchemaScanOperator(
+      PlanNodeId planNodeId,
       OperatorContext operatorContext,
       int limit,
       int offset,
@@ -63,9 +63,8 @@ public class TimeSeriesSchemaScanOperator extends SchemaScanOperator {
       String value,
       boolean isContains,
       boolean orderByHeat,
-      boolean isPrefixPath,
-      List<String> columns) {
-    super(operatorContext, limit, offset, partialPath, isPrefixPath, columns);
+      boolean isPrefixPath) {
+    super(planNodeId, operatorContext, limit, offset, partialPath, isPrefixPath);
     this.isContains = isContains;
     this.key = key;
     this.value = value;
@@ -134,9 +133,4 @@ public class TimeSeriesSchemaScanOperator extends SchemaScanOperator {
         .map(e -> "\"" + e.getKey() + "\"" + ":" + "\"" + e.getValue() + "\"")
         .collect(Collectors.joining(","));
   }
-
-  @Override
-  public PlanNodeId getSourceId() {
-    return null;
-  }
 }
diff --git a/server/src/main/java/org/apache/iotdb/db/mpp/sql/analyze/Analyzer.java b/server/src/main/java/org/apache/iotdb/db/mpp/sql/analyze/Analyzer.java
index 7c783694c9..7bfec1905e 100644
--- a/server/src/main/java/org/apache/iotdb/db/mpp/sql/analyze/Analyzer.java
+++ b/server/src/main/java/org/apache/iotdb/db/mpp/sql/analyze/Analyzer.java
@@ -41,7 +41,13 @@ import org.apache.iotdb.db.mpp.sql.statement.Statement;
 import org.apache.iotdb.db.mpp.sql.statement.StatementVisitor;
 import org.apache.iotdb.db.mpp.sql.statement.component.ResultColumn;
 import org.apache.iotdb.db.mpp.sql.statement.component.WhereCondition;
-import org.apache.iotdb.db.mpp.sql.statement.crud.*;
+import org.apache.iotdb.db.mpp.sql.statement.crud.InsertMultiTabletsStatement;
+import org.apache.iotdb.db.mpp.sql.statement.crud.InsertRowStatement;
+import org.apache.iotdb.db.mpp.sql.statement.crud.InsertRowsOfOneDeviceStatement;
+import org.apache.iotdb.db.mpp.sql.statement.crud.InsertRowsStatement;
+import org.apache.iotdb.db.mpp.sql.statement.crud.InsertStatement;
+import org.apache.iotdb.db.mpp.sql.statement.crud.InsertTabletStatement;
+import org.apache.iotdb.db.mpp.sql.statement.crud.QueryStatement;
 import org.apache.iotdb.db.mpp.sql.statement.metadata.AlterTimeSeriesStatement;
 import org.apache.iotdb.db.mpp.sql.statement.metadata.CreateAlignedTimeSeriesStatement;
 import org.apache.iotdb.db.mpp.sql.statement.metadata.CreateTimeSeriesStatement;
diff --git a/server/src/main/java/org/apache/iotdb/db/mpp/sql/planner/LocalExecutionPlanner.java b/server/src/main/java/org/apache/iotdb/db/mpp/sql/planner/LocalExecutionPlanner.java
index b0c277f65e..e02becf770 100644
--- a/server/src/main/java/org/apache/iotdb/db/mpp/sql/planner/LocalExecutionPlanner.java
+++ b/server/src/main/java/org/apache/iotdb/db/mpp/sql/planner/LocalExecutionPlanner.java
@@ -167,6 +167,7 @@ public class LocalExecutionPlanner {
               node.getPlanNodeId(),
               TimeSeriesSchemaScanOperator.class.getSimpleName());
       return new TimeSeriesSchemaScanOperator(
+          node.getPlanNodeId(),
           operatorContext,
           node.getLimit(),
           node.getOffset(),
@@ -175,8 +176,7 @@ public class LocalExecutionPlanner {
           node.getValue(),
           node.isContains(),
           node.isOrderByHeat(),
-          node.isPrefixPath(),
-          node.getOutputColumnNames());
+          node.isPrefixPath());
     }
 
     @Override
@@ -188,13 +188,13 @@ public class LocalExecutionPlanner {
               node.getPlanNodeId(),
               DevicesSchemaScanOperator.class.getSimpleName());
       return new DevicesSchemaScanOperator(
+          node.getPlanNodeId(),
           operatorContext,
           node.getLimit(),
           node.getOffset(),
           node.getPath(),
           node.isPrefixPath(),
-          node.isHasSgCol(),
-          node.getOutputColumnNames());
+          node.isHasSgCol());
     }
 
     @Override
diff --git a/server/src/main/java/org/apache/iotdb/db/mpp/sql/planner/QueryPlanBuilder.java b/server/src/main/java/org/apache/iotdb/db/mpp/sql/planner/QueryPlanBuilder.java
index fb1a5ef0fc..4b0ee9c1ff 100644
--- a/server/src/main/java/org/apache/iotdb/db/mpp/sql/planner/QueryPlanBuilder.java
+++ b/server/src/main/java/org/apache/iotdb/db/mpp/sql/planner/QueryPlanBuilder.java
@@ -27,7 +27,14 @@ import org.apache.iotdb.db.mpp.sql.planner.plan.node.metedata.read.DevicesSchema
 import org.apache.iotdb.db.mpp.sql.planner.plan.node.metedata.read.SchemaFetchNode;
 import org.apache.iotdb.db.mpp.sql.planner.plan.node.metedata.read.SchemaMergeNode;
 import org.apache.iotdb.db.mpp.sql.planner.plan.node.metedata.read.TimeSeriesSchemaScanNode;
-import org.apache.iotdb.db.mpp.sql.planner.plan.node.process.*;
+import org.apache.iotdb.db.mpp.sql.planner.plan.node.process.AggregateNode;
+import org.apache.iotdb.db.mpp.sql.planner.plan.node.process.DeviceMergeNode;
+import org.apache.iotdb.db.mpp.sql.planner.plan.node.process.FilterNode;
+import org.apache.iotdb.db.mpp.sql.planner.plan.node.process.FilterNullNode;
+import org.apache.iotdb.db.mpp.sql.planner.plan.node.process.GroupByLevelNode;
+import org.apache.iotdb.db.mpp.sql.planner.plan.node.process.LimitNode;
+import org.apache.iotdb.db.mpp.sql.planner.plan.node.process.OffsetNode;
+import org.apache.iotdb.db.mpp.sql.planner.plan.node.process.TimeJoinNode;
 import org.apache.iotdb.db.mpp.sql.planner.plan.node.source.SeriesAggregateScanNode;
 import org.apache.iotdb.db.mpp.sql.planner.plan.node.source.SeriesScanNode;
 import org.apache.iotdb.db.mpp.sql.statement.component.FilterNullComponent;
diff --git a/server/src/main/java/org/apache/iotdb/db/mpp/sql/planner/plan/node/PlanNodeType.java b/server/src/main/java/org/apache/iotdb/db/mpp/sql/planner/plan/node/PlanNodeType.java
index a97ccddc16..cde6e52d48 100644
--- a/server/src/main/java/org/apache/iotdb/db/mpp/sql/planner/plan/node/PlanNodeType.java
+++ b/server/src/main/java/org/apache/iotdb/db/mpp/sql/planner/plan/node/PlanNodeType.java
@@ -22,7 +22,6 @@ import org.apache.iotdb.db.exception.metadata.IllegalPathException;
 import org.apache.iotdb.db.mpp.sql.planner.plan.node.metedata.read.DevicesSchemaScanNode;
 import org.apache.iotdb.db.mpp.sql.planner.plan.node.metedata.read.SchemaFetchNode;
 import org.apache.iotdb.db.mpp.sql.planner.plan.node.metedata.read.SchemaMergeNode;
-import org.apache.iotdb.db.mpp.sql.planner.plan.node.metedata.read.ShowDevicesNode;
 import org.apache.iotdb.db.mpp.sql.planner.plan.node.metedata.read.TimeSeriesSchemaScanNode;
 import org.apache.iotdb.db.mpp.sql.planner.plan.node.metedata.write.AlterTimeSeriesNode;
 import org.apache.iotdb.db.mpp.sql.planner.plan.node.metedata.write.AuthorNode;
@@ -78,10 +77,9 @@ public enum PlanNodeType {
   ALTER_TIME_SERIES((short) 22),
   CREATE_ALIGNED_TIME_SERIES((short) 23),
   TIME_SERIES_SCHEMA_SCAN((short) 24),
-  // TODO @xinzhongtianxia remove this
-  SHOW_DEVICES((short) 25),
-  SCHEMA_FETCH((short) 26),
-  SCHEMA_MERGE((short) 27);
+  SCHEMA_FETCH((short) 25),
+  SCHEMA_MERGE((short) 26),
+  STORAGE_GROUP_SCHEMA_SCAN((short) 27);
 
   private final short nodeType;
 
@@ -160,10 +158,8 @@ public enum PlanNodeType {
       case 24:
         return TimeSeriesSchemaScanNode.deserialize(buffer);
       case 25:
-        return ShowDevicesNode.deserialize(buffer);
-      case 26:
         return SchemaFetchNode.deserialize(buffer);
-      case 27:
+      case 26:
         return SchemaMergeNode.deserialize(buffer);
       default:
         throw new IllegalArgumentException("Invalid node type: " + nodeType);
diff --git a/server/src/main/java/org/apache/iotdb/db/mpp/sql/planner/plan/node/metedata/read/DevicesSchemaScanNode.java b/server/src/main/java/org/apache/iotdb/db/mpp/sql/planner/plan/node/metedata/read/DevicesSchemaScanNode.java
index 43be8ea836..4afa2fad9b 100644
--- a/server/src/main/java/org/apache/iotdb/db/mpp/sql/planner/plan/node/metedata/read/DevicesSchemaScanNode.java
+++ b/server/src/main/java/org/apache/iotdb/db/mpp/sql/planner/plan/node/metedata/read/DevicesSchemaScanNode.java
@@ -26,12 +26,8 @@ import org.apache.iotdb.db.mpp.sql.planner.plan.node.PlanNodeType;
 import org.apache.iotdb.tsfile.utils.ReadWriteIOUtils;
 
 import java.nio.ByteBuffer;
-import java.util.Arrays;
 import java.util.List;
-
-import static org.apache.iotdb.commons.conf.IoTDBConstant.COLUMN_DEVICES;
-import static org.apache.iotdb.commons.conf.IoTDBConstant.COLUMN_IS_ALIGNED;
-import static org.apache.iotdb.commons.conf.IoTDBConstant.COLUMN_STORAGE_GROUP;
+import java.util.Objects;
 
 public class DevicesSchemaScanNode extends SchemaScanNode {
 
@@ -66,22 +62,8 @@ public class DevicesSchemaScanNode extends SchemaScanNode {
   }
 
   @Override
-  public int allowedChildCount() {
-    return NO_CHILD_ALLOWED;
-  }
-
-  @Override
-  public List<String> getOutputColumnNames() {
-    if (hasSgCol) {
-      return Arrays.asList(COLUMN_DEVICES, COLUMN_STORAGE_GROUP, COLUMN_IS_ALIGNED);
-    }
-    return Arrays.asList(COLUMN_DEVICES, COLUMN_IS_ALIGNED);
-  }
-
-  @Override
-  public void serialize(ByteBuffer byteBuffer) {
+  protected void serializeAttributes(ByteBuffer byteBuffer) {
     PlanNodeType.DEVICES_SCHEMA_SCAN.serialize(byteBuffer);
-    ReadWriteIOUtils.write(getPlanNodeId().getId(), byteBuffer);
     ReadWriteIOUtils.write(path.getFullPath(), byteBuffer);
     ReadWriteIOUtils.write(limit, byteBuffer);
     ReadWriteIOUtils.write(offset, byteBuffer);
@@ -90,10 +72,8 @@ public class DevicesSchemaScanNode extends SchemaScanNode {
   }
 
   public static DevicesSchemaScanNode deserialize(ByteBuffer byteBuffer) {
-    String id = ReadWriteIOUtils.readString(byteBuffer);
-    PlanNodeId planNodeId = new PlanNodeId(id);
     String fullPath = ReadWriteIOUtils.readString(byteBuffer);
-    PartialPath path = null;
+    PartialPath path;
     try {
       path = new PartialPath(fullPath);
     } catch (IllegalPathException e) {
@@ -103,6 +83,27 @@ public class DevicesSchemaScanNode extends SchemaScanNode {
     int offset = ReadWriteIOUtils.readInt(byteBuffer);
     boolean isPrefixPath = ReadWriteIOUtils.readBool(byteBuffer);
     boolean hasSgCol = ReadWriteIOUtils.readBool(byteBuffer);
+    PlanNodeId planNodeId = PlanNodeId.deserialize(byteBuffer);
     return new DevicesSchemaScanNode(planNodeId, path, limit, offset, isPrefixPath, hasSgCol);
   }
+
+  @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;
+    }
+    DevicesSchemaScanNode that = (DevicesSchemaScanNode) o;
+    return hasSgCol == that.hasSgCol;
+  }
+
+  @Override
+  public int hashCode() {
+    return Objects.hash(super.hashCode(), hasSgCol);
+  }
 }
diff --git a/server/src/main/java/org/apache/iotdb/db/mpp/sql/planner/plan/node/metedata/read/SchemaFetchNode.java b/server/src/main/java/org/apache/iotdb/db/mpp/sql/planner/plan/node/metedata/read/SchemaFetchNode.java
index 5100ba3f21..54800d33a1 100644
--- a/server/src/main/java/org/apache/iotdb/db/mpp/sql/planner/plan/node/metedata/read/SchemaFetchNode.java
+++ b/server/src/main/java/org/apache/iotdb/db/mpp/sql/planner/plan/node/metedata/read/SchemaFetchNode.java
@@ -28,7 +28,6 @@ import org.apache.iotdb.db.mpp.sql.planner.plan.node.PlanVisitor;
 import com.google.common.collect.ImmutableList;
 
 import java.nio.ByteBuffer;
-import java.util.Collections;
 import java.util.List;
 
 public class SchemaFetchNode extends SchemaScanNode {
@@ -77,11 +76,6 @@ public class SchemaFetchNode extends SchemaScanNode {
   @Override
   public void open() throws Exception {}
 
-  @Override
-  public List<String> getOutputColumnNames() {
-    return Collections.singletonList("SchemaTree");
-  }
-
   @Override
   public void close() throws Exception {}
 
diff --git a/server/src/main/java/org/apache/iotdb/db/mpp/sql/planner/plan/node/metedata/read/SchemaScanNode.java b/server/src/main/java/org/apache/iotdb/db/mpp/sql/planner/plan/node/metedata/read/SchemaScanNode.java
index 72d32da4e4..90812b842d 100644
--- a/server/src/main/java/org/apache/iotdb/db/mpp/sql/planner/plan/node/metedata/read/SchemaScanNode.java
+++ b/server/src/main/java/org/apache/iotdb/db/mpp/sql/planner/plan/node/metedata/read/SchemaScanNode.java
@@ -21,11 +21,9 @@ package org.apache.iotdb.db.mpp.sql.planner.plan.node.metedata.read;
 import org.apache.iotdb.commons.partition.RegionReplicaSet;
 import org.apache.iotdb.db.metadata.path.PartialPath;
 import org.apache.iotdb.db.mpp.sql.planner.plan.node.PlanNodeId;
-import org.apache.iotdb.db.mpp.sql.planner.plan.node.PlanVisitor;
 import org.apache.iotdb.db.mpp.sql.planner.plan.node.source.SourceNode;
 
-import java.nio.ByteBuffer;
-import java.util.List;
+import java.util.Objects;
 
 public abstract class SchemaScanNode extends SourceNode {
   protected int limit;
@@ -116,13 +114,26 @@ public abstract class SchemaScanNode extends SourceNode {
     this.hasLimit = hasLimit;
   }
 
-  public abstract List<String> getOutputColumnNames();
-
   @Override
-  protected void serializeAttributes(ByteBuffer byteBuffer) {}
+  public boolean equals(Object o) {
+    if (this == o) {
+      return true;
+    }
+    if (o == null || getClass() != o.getClass()) {
+      return false;
+    }
+    if (!super.equals(o)) {
+      return false;
+    }
+    SchemaScanNode that = (SchemaScanNode) o;
+    return limit == that.limit
+        && offset == that.offset
+        && isPrefixPath == that.isPrefixPath
+        && path.equals(that.path);
+  }
 
   @Override
-  public <R, C> R accept(PlanVisitor<R, C> visitor, C context) {
-    return visitor.visitSchemaScan(this, context);
+  public int hashCode() {
+    return Objects.hash(super.hashCode(), limit, offset, path, isPrefixPath);
   }
 }
diff --git a/server/src/main/java/org/apache/iotdb/db/mpp/sql/planner/plan/node/metedata/read/ShowDevicesNode.java b/server/src/main/java/org/apache/iotdb/db/mpp/sql/planner/plan/node/metedata/read/ShowDevicesNode.java
deleted file mode 100644
index 13ddb938b8..0000000000
--- a/server/src/main/java/org/apache/iotdb/db/mpp/sql/planner/plan/node/metedata/read/ShowDevicesNode.java
+++ /dev/null
@@ -1,67 +0,0 @@
-/*
- * 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.mpp.sql.planner.plan.node.metedata.read;
-
-import org.apache.iotdb.db.mpp.sql.planner.plan.node.PlanNode;
-import org.apache.iotdb.db.mpp.sql.planner.plan.node.PlanNodeId;
-import org.apache.iotdb.db.mpp.sql.planner.plan.node.PlanNodeType;
-import org.apache.iotdb.tsfile.exception.NotImplementedException;
-
-import java.nio.ByteBuffer;
-import java.util.List;
-
-public class ShowDevicesNode extends ShowNode {
-
-  public ShowDevicesNode(PlanNodeId id) {
-    super(id);
-  }
-
-  @Override
-  public List<PlanNode> getChildren() {
-    return null;
-  }
-
-  @Override
-  public void addChild(PlanNode child) {}
-
-  @Override
-  public PlanNode clone() {
-    throw new NotImplementedException("Clone of ShowDevicesNode is not implemented");
-  }
-
-  @Override
-  public int allowedChildCount() {
-    return NO_CHILD_ALLOWED;
-  }
-
-  @Override
-  protected void serializeAttributes(ByteBuffer byteBuffer) {
-    PlanNodeType.SHOW_DEVICES.serialize(byteBuffer);
-  }
-
-  public static ShowDevicesNode deserialize(ByteBuffer byteBuffer) {
-    PlanNodeId planNodeId = PlanNodeId.deserialize(byteBuffer);
-    return new ShowDevicesNode(planNodeId);
-  }
-
-  @Override
-  public boolean equals(Object o) {
-    return super.equals(o);
-  }
-}
diff --git a/server/src/main/java/org/apache/iotdb/db/mpp/sql/planner/plan/node/metedata/read/ShowNode.java b/server/src/main/java/org/apache/iotdb/db/mpp/sql/planner/plan/node/metedata/read/ShowNode.java
deleted file mode 100644
index c9333b6b8e..0000000000
--- a/server/src/main/java/org/apache/iotdb/db/mpp/sql/planner/plan/node/metedata/read/ShowNode.java
+++ /dev/null
@@ -1,36 +0,0 @@
-/*
- * 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.mpp.sql.planner.plan.node.metedata.read;
-
-import org.apache.iotdb.db.mpp.sql.planner.plan.node.PlanNode;
-import org.apache.iotdb.db.mpp.sql.planner.plan.node.PlanNodeId;
-
-import java.nio.ByteBuffer;
-
-public abstract class ShowNode extends PlanNode {
-
-  protected ShowNode(PlanNodeId id) {
-    super(id);
-  }
-
-  @Override
-  public void serialize(ByteBuffer byteBuffer) {
-    super.serialize(byteBuffer);
-  }
-}
diff --git a/server/src/main/java/org/apache/iotdb/db/mpp/sql/planner/plan/node/metedata/read/TimeSeriesSchemaScanNode.java b/server/src/main/java/org/apache/iotdb/db/mpp/sql/planner/plan/node/metedata/read/TimeSeriesSchemaScanNode.java
index 1e2cc49c25..ab5337f8a8 100644
--- a/server/src/main/java/org/apache/iotdb/db/mpp/sql/planner/plan/node/metedata/read/TimeSeriesSchemaScanNode.java
+++ b/server/src/main/java/org/apache/iotdb/db/mpp/sql/planner/plan/node/metedata/read/TimeSeriesSchemaScanNode.java
@@ -26,18 +26,9 @@ import org.apache.iotdb.db.mpp.sql.planner.plan.node.PlanNodeType;
 import org.apache.iotdb.tsfile.utils.ReadWriteIOUtils;
 
 import java.nio.ByteBuffer;
-import java.util.Arrays;
 import java.util.Collections;
 import java.util.List;
-
-import static org.apache.iotdb.commons.conf.IoTDBConstant.COLUMN_ATTRIBUTES;
-import static org.apache.iotdb.commons.conf.IoTDBConstant.COLUMN_STORAGE_GROUP;
-import static org.apache.iotdb.commons.conf.IoTDBConstant.COLUMN_TAGS;
-import static org.apache.iotdb.commons.conf.IoTDBConstant.COLUMN_TIMESERIES;
-import static org.apache.iotdb.commons.conf.IoTDBConstant.COLUMN_TIMESERIES_ALIAS;
-import static org.apache.iotdb.commons.conf.IoTDBConstant.COLUMN_TIMESERIES_COMPRESSION;
-import static org.apache.iotdb.commons.conf.IoTDBConstant.COLUMN_TIMESERIES_DATATYPE;
-import static org.apache.iotdb.commons.conf.IoTDBConstant.COLUMN_TIMESERIES_ENCODING;
+import java.util.Objects;
 
 public class TimeSeriesSchemaScanNode extends SchemaScanNode {
 
@@ -66,9 +57,8 @@ public class TimeSeriesSchemaScanNode extends SchemaScanNode {
   }
 
   @Override
-  public void serialize(ByteBuffer byteBuffer) {
+  protected void serializeAttributes(ByteBuffer byteBuffer) {
     PlanNodeType.TIME_SERIES_SCHEMA_SCAN.serialize(byteBuffer);
-    ReadWriteIOUtils.write(getPlanNodeId().getId(), byteBuffer);
     ReadWriteIOUtils.write(path.getFullPath(), byteBuffer);
     ReadWriteIOUtils.write(key, byteBuffer);
     ReadWriteIOUtils.write(value, byteBuffer);
@@ -80,10 +70,8 @@ public class TimeSeriesSchemaScanNode extends SchemaScanNode {
   }
 
   public static TimeSeriesSchemaScanNode deserialize(ByteBuffer byteBuffer) {
-    String id = ReadWriteIOUtils.readString(byteBuffer);
-    PlanNodeId planNodeId = new PlanNodeId(id);
     String fullPath = ReadWriteIOUtils.readString(byteBuffer);
-    PartialPath path = null;
+    PartialPath path;
     try {
       path = new PartialPath(fullPath);
     } catch (IllegalPathException e) {
@@ -96,6 +84,9 @@ public class TimeSeriesSchemaScanNode extends SchemaScanNode {
     boolean oderByHeat = ReadWriteIOUtils.readBool(byteBuffer);
     boolean isContains = ReadWriteIOUtils.readBool(byteBuffer);
     boolean isPrefixPath = ReadWriteIOUtils.readBool(byteBuffer);
+
+    PlanNodeId planNodeId = PlanNodeId.deserialize(byteBuffer);
+
     return new TimeSeriesSchemaScanNode(
         planNodeId, path, key, value, limit, offset, oderByHeat, isContains, isPrefixPath);
   }
@@ -131,15 +122,25 @@ public class TimeSeriesSchemaScanNode extends SchemaScanNode {
   }
 
   @Override
-  public List<String> getOutputColumnNames() {
-    return Arrays.asList(
-        COLUMN_TIMESERIES,
-        COLUMN_TIMESERIES_ALIAS,
-        COLUMN_STORAGE_GROUP,
-        COLUMN_TIMESERIES_DATATYPE,
-        COLUMN_TIMESERIES_ENCODING,
-        COLUMN_TIMESERIES_COMPRESSION,
-        COLUMN_TAGS,
-        COLUMN_ATTRIBUTES);
+  public boolean equals(Object o) {
+    if (this == o) {
+      return true;
+    }
+    if (o == null || getClass() != o.getClass()) {
+      return false;
+    }
+    if (!super.equals(o)) {
+      return false;
+    }
+    TimeSeriesSchemaScanNode that = (TimeSeriesSchemaScanNode) o;
+    return isContains == that.isContains
+        && orderByHeat == that.orderByHeat
+        && Objects.equals(key, that.key)
+        && Objects.equals(value, that.value);
+  }
+
+  @Override
+  public int hashCode() {
+    return Objects.hash(super.hashCode(), key, value, isContains, orderByHeat);
   }
 }
diff --git a/server/src/main/java/org/apache/iotdb/db/mpp/sql/statement/metadata/ShowStorageGroupStatement.java b/server/src/main/java/org/apache/iotdb/db/mpp/sql/statement/metadata/ShowStorageGroupStatement.java
index 50742ce767..226b7c15f4 100644
--- a/server/src/main/java/org/apache/iotdb/db/mpp/sql/statement/metadata/ShowStorageGroupStatement.java
+++ b/server/src/main/java/org/apache/iotdb/db/mpp/sql/statement/metadata/ShowStorageGroupStatement.java
@@ -22,6 +22,13 @@ package org.apache.iotdb.db.mpp.sql.statement.metadata;
 import org.apache.iotdb.db.metadata.path.PartialPath;
 import org.apache.iotdb.db.mpp.sql.statement.StatementVisitor;
 
+/**
+ * SHOW STORAGE GROUP statement
+ *
+ * <p>Here is the syntax definition:
+ *
+ * <p>SHOW STORAGE GROUP prefixPath?
+ */
 public class ShowStorageGroupStatement extends ShowStatement {
 
   private final PartialPath pathPattern;
diff --git a/server/src/test/java/org/apache/iotdb/db/mpp/operator/SchemaScanOperatorTest.java b/server/src/test/java/org/apache/iotdb/db/mpp/operator/schema/SchemaScanOperatorTest.java
similarity index 95%
rename from server/src/test/java/org/apache/iotdb/db/mpp/operator/SchemaScanOperatorTest.java
rename to server/src/test/java/org/apache/iotdb/db/mpp/operator/schema/SchemaScanOperatorTest.java
index 09a1f89f13..609dc9befa 100644
--- a/server/src/test/java/org/apache/iotdb/db/mpp/operator/SchemaScanOperatorTest.java
+++ b/server/src/test/java/org/apache/iotdb/db/mpp/operator/schema/SchemaScanOperatorTest.java
@@ -16,7 +16,7 @@
  * specific language governing permissions and limitations
  * under the License.
  */
-package org.apache.iotdb.db.mpp.operator;
+package org.apache.iotdb.db.mpp.operator.schema;
 
 import org.apache.iotdb.db.engine.storagegroup.TsFileResource;
 import org.apache.iotdb.db.exception.metadata.MetadataException;
@@ -30,9 +30,7 @@ import org.apache.iotdb.db.mpp.common.QueryId;
 import org.apache.iotdb.db.mpp.execution.FragmentInstanceContext;
 import org.apache.iotdb.db.mpp.execution.FragmentInstanceState;
 import org.apache.iotdb.db.mpp.execution.SchemaDriverContext;
-import org.apache.iotdb.db.mpp.operator.schema.DevicesSchemaScanOperator;
-import org.apache.iotdb.db.mpp.operator.schema.SchemaScanOperator;
-import org.apache.iotdb.db.mpp.operator.schema.TimeSeriesSchemaScanOperator;
+import org.apache.iotdb.db.mpp.operator.OperatorContext;
 import org.apache.iotdb.db.mpp.sql.planner.plan.node.PlanNodeId;
 import org.apache.iotdb.db.query.reader.series.SeriesReaderTestUtil;
 import org.apache.iotdb.tsfile.exception.write.WriteProcessException;
@@ -99,9 +97,10 @@ public class SchemaScanOperatorTest {
       FragmentInstanceContext fragmentInstanceContext =
           new FragmentInstanceContext(
               new FragmentInstanceId(new PlanFragmentId(queryId, 0), "stub-instance"), state);
+      PlanNodeId planNodeId = queryId.genPlanNodeId();
       OperatorContext operatorContext =
           fragmentInstanceContext.addOperatorContext(
-              1, new PlanNodeId("1"), SchemaScanOperator.class.getSimpleName());
+              1, planNodeId, SchemaScanOperator.class.getSimpleName());
       PartialPath partialPath = new PartialPath(META_SCAN_OPERATOR_TEST_SG + ".device0");
       ISchemaRegion schemaRegion =
           SchemaEngine.getInstance()
@@ -113,13 +112,13 @@ public class SchemaScanOperatorTest {
       List<String> columns = Arrays.asList(COLUMN_DEVICES, COLUMN_STORAGE_GROUP, COLUMN_IS_ALIGNED);
       DevicesSchemaScanOperator deviceMetaScanOperator =
           new DevicesSchemaScanOperator(
+              planNodeId,
               fragmentInstanceContext.getOperatorContexts().get(0),
               10,
               0,
               partialPath,
               false,
-              true,
-              columns);
+              true);
       while (deviceMetaScanOperator.hasNext()) {
         TsBlock tsBlock = deviceMetaScanOperator.next();
         assertEquals(3, tsBlock.getValueColumnCount());
@@ -162,9 +161,10 @@ public class SchemaScanOperatorTest {
       FragmentInstanceContext fragmentInstanceContext =
           new FragmentInstanceContext(
               new FragmentInstanceId(new PlanFragmentId(queryId, 0), "stub-instance"), state);
+      PlanNodeId planNodeId = queryId.genPlanNodeId();
       OperatorContext operatorContext =
           fragmentInstanceContext.addOperatorContext(
-              1, new PlanNodeId("1"), SchemaScanOperator.class.getSimpleName());
+              1, planNodeId, SchemaScanOperator.class.getSimpleName());
       PartialPath partialPath = new PartialPath(META_SCAN_OPERATOR_TEST_SG + ".device0.*");
       ISchemaRegion schemaRegion =
           SchemaEngine.getInstance()
@@ -185,6 +185,7 @@ public class SchemaScanOperatorTest {
               COLUMN_ATTRIBUTES);
       TimeSeriesSchemaScanOperator timeSeriesMetaScanOperator =
           new TimeSeriesSchemaScanOperator(
+              planNodeId,
               fragmentInstanceContext.getOperatorContexts().get(0),
               10,
               0,
@@ -193,8 +194,7 @@ public class SchemaScanOperatorTest {
               null,
               false,
               false,
-              false,
-              columns);
+              false);
       while (timeSeriesMetaScanOperator.hasNext()) {
         TsBlock tsBlock = timeSeriesMetaScanOperator.next();
         assertEquals(8, tsBlock.getValueColumnCount());
diff --git a/server/src/test/java/org/apache/iotdb/db/mpp/sql/plan/node/metadata/read/DeviceSchemaScanNodeSerdeTest.java b/server/src/test/java/org/apache/iotdb/db/mpp/sql/plan/node/metadata/read/DeviceSchemaScanNodeSerdeTest.java
new file mode 100644
index 0000000000..eadfb2258c
--- /dev/null
+++ b/server/src/test/java/org/apache/iotdb/db/mpp/sql/plan/node/metadata/read/DeviceSchemaScanNodeSerdeTest.java
@@ -0,0 +1,76 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.iotdb.db.mpp.sql.plan.node.metadata.read;
+
+import org.apache.iotdb.commons.cluster.Endpoint;
+import org.apache.iotdb.db.exception.metadata.IllegalPathException;
+import org.apache.iotdb.db.metadata.path.PartialPath;
+import org.apache.iotdb.db.mpp.common.FragmentInstanceId;
+import org.apache.iotdb.db.mpp.common.PlanFragmentId;
+import org.apache.iotdb.db.mpp.sql.plan.node.PlanNodeDeserializeHelper;
+import org.apache.iotdb.db.mpp.sql.planner.plan.node.PlanNodeId;
+import org.apache.iotdb.db.mpp.sql.planner.plan.node.metedata.read.DevicesSchemaScanNode;
+import org.apache.iotdb.db.mpp.sql.planner.plan.node.metedata.read.SchemaMergeNode;
+import org.apache.iotdb.db.mpp.sql.planner.plan.node.process.ExchangeNode;
+import org.apache.iotdb.db.mpp.sql.planner.plan.node.process.LimitNode;
+import org.apache.iotdb.db.mpp.sql.planner.plan.node.process.OffsetNode;
+import org.apache.iotdb.db.mpp.sql.planner.plan.node.sink.FragmentSinkNode;
+
+import org.junit.Assert;
+import org.junit.Test;
+
+import java.nio.ByteBuffer;
+
+public class DeviceSchemaScanNodeSerdeTest {
+
+  @Test
+  public void TestSerializeAndDeserialize() throws IllegalPathException {
+    OffsetNode offsetNode = new OffsetNode(new PlanNodeId("offset"), 10);
+    LimitNode limitNode = new LimitNode(new PlanNodeId("limit"), 10);
+    SchemaMergeNode schemaMergeNode = new SchemaMergeNode(new PlanNodeId("schemaMerge"));
+    ExchangeNode exchangeNode = new ExchangeNode(new PlanNodeId("exchange"));
+    DevicesSchemaScanNode devicesSchemaScanNode =
+        new DevicesSchemaScanNode(
+            new PlanNodeId("deviceSchemaScan"),
+            new PartialPath("root.sg.device"),
+            10,
+            10,
+            false,
+            false);
+    FragmentSinkNode fragmentSinkNode = new FragmentSinkNode(new PlanNodeId("fragmentSink"));
+    fragmentSinkNode.addChild(devicesSchemaScanNode);
+    fragmentSinkNode.setDownStream(
+        new Endpoint("127.0.0.1", 6667),
+        new FragmentInstanceId(new PlanFragmentId("q", 1), "ds"),
+        new PlanNodeId("test"));
+    exchangeNode.addChild(schemaMergeNode);
+    exchangeNode.setRemoteSourceNode(fragmentSinkNode);
+    exchangeNode.setUpstream(
+        new Endpoint("127.0.0.1", 6667),
+        new FragmentInstanceId(new PlanFragmentId("q", 1), "ds"),
+        new PlanNodeId("test"));
+    offsetNode.addChild(exchangeNode);
+    limitNode.addChild(offsetNode);
+    ByteBuffer byteBuffer = ByteBuffer.allocate(1024);
+    limitNode.serialize(byteBuffer);
+    byteBuffer.flip();
+    LimitNode limitNode1 = (LimitNode) PlanNodeDeserializeHelper.deserialize(byteBuffer);
+    Assert.assertEquals(limitNode, limitNode1);
+  }
+}
diff --git a/server/src/test/java/org/apache/iotdb/db/mpp/sql/plan/node/metadata/read/ShowDevicesNodeSerdeTest.java b/server/src/test/java/org/apache/iotdb/db/mpp/sql/plan/node/metadata/read/ShowDevicesNodeSerdeTest.java
deleted file mode 100644
index 80ca97c47f..0000000000
--- a/server/src/test/java/org/apache/iotdb/db/mpp/sql/plan/node/metadata/read/ShowDevicesNodeSerdeTest.java
+++ /dev/null
@@ -1,42 +0,0 @@
-/*
- * 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.mpp.sql.plan.node.metadata.read;
-
-import org.apache.iotdb.db.exception.metadata.IllegalPathException;
-import org.apache.iotdb.db.mpp.sql.plan.node.PlanNodeDeserializeHelper;
-import org.apache.iotdb.db.mpp.sql.planner.plan.node.PlanNodeId;
-import org.apache.iotdb.db.mpp.sql.planner.plan.node.metedata.read.ShowDevicesNode;
-
-import org.junit.Test;
-
-import java.nio.ByteBuffer;
-
-import static org.junit.Assert.assertEquals;
-
-public class ShowDevicesNodeSerdeTest {
-
-  @Test
-  public void TestSerializeAndDeserialize() throws IllegalPathException {
-    ShowDevicesNode showDevicesNode = new ShowDevicesNode(new PlanNodeId("TestShowDevicesNode"));
-    ByteBuffer byteBuffer = ByteBuffer.allocate(1024);
-    showDevicesNode.serialize(byteBuffer);
-    byteBuffer.flip();
-    assertEquals(PlanNodeDeserializeHelper.deserialize(byteBuffer), showDevicesNode);
-  }
-}
diff --git a/server/src/test/java/org/apache/iotdb/db/mpp/sql/plan/node/metadata/read/TimeSeriesSchemaScanNodeSerdeTest.java b/server/src/test/java/org/apache/iotdb/db/mpp/sql/plan/node/metadata/read/TimeSeriesSchemaScanNodeSerdeTest.java
new file mode 100644
index 0000000000..3680c12251
--- /dev/null
+++ b/server/src/test/java/org/apache/iotdb/db/mpp/sql/plan/node/metadata/read/TimeSeriesSchemaScanNodeSerdeTest.java
@@ -0,0 +1,79 @@
+/*
+ * 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.mpp.sql.plan.node.metadata.read;
+
+import org.apache.iotdb.commons.cluster.Endpoint;
+import org.apache.iotdb.db.exception.metadata.IllegalPathException;
+import org.apache.iotdb.db.metadata.path.PartialPath;
+import org.apache.iotdb.db.mpp.common.FragmentInstanceId;
+import org.apache.iotdb.db.mpp.common.PlanFragmentId;
+import org.apache.iotdb.db.mpp.sql.plan.node.PlanNodeDeserializeHelper;
+import org.apache.iotdb.db.mpp.sql.planner.plan.node.PlanNodeId;
+import org.apache.iotdb.db.mpp.sql.planner.plan.node.metedata.read.SchemaMergeNode;
+import org.apache.iotdb.db.mpp.sql.planner.plan.node.metedata.read.TimeSeriesSchemaScanNode;
+import org.apache.iotdb.db.mpp.sql.planner.plan.node.process.ExchangeNode;
+import org.apache.iotdb.db.mpp.sql.planner.plan.node.process.LimitNode;
+import org.apache.iotdb.db.mpp.sql.planner.plan.node.process.OffsetNode;
+import org.apache.iotdb.db.mpp.sql.planner.plan.node.sink.FragmentSinkNode;
+
+import org.junit.Assert;
+import org.junit.Test;
+
+import java.nio.ByteBuffer;
+
+public class TimeSeriesSchemaScanNodeSerdeTest {
+
+  @Test
+  public void TestSerializeAndDeserialize() throws IllegalPathException {
+    OffsetNode offsetNode = new OffsetNode(new PlanNodeId("offset"), 10);
+    LimitNode limitNode = new LimitNode(new PlanNodeId("limit"), 10);
+    SchemaMergeNode schemaMergeNode = new SchemaMergeNode(new PlanNodeId("schemaMerge"));
+    ExchangeNode exchangeNode = new ExchangeNode(new PlanNodeId("exchange"));
+    TimeSeriesSchemaScanNode timeSeriesSchemaScanNode =
+        new TimeSeriesSchemaScanNode(
+            new PlanNodeId("timeSeriesSchemaScan"),
+            new PartialPath("root.sg.device.sensor"),
+            null,
+            null,
+            10,
+            0,
+            false,
+            false,
+            false);
+    FragmentSinkNode fragmentSinkNode = new FragmentSinkNode(new PlanNodeId("fragmentSink"));
+    fragmentSinkNode.addChild(timeSeriesSchemaScanNode);
+    fragmentSinkNode.setDownStream(
+        new Endpoint("127.0.0.1", 6667),
+        new FragmentInstanceId(new PlanFragmentId("q", 1), "ds"),
+        new PlanNodeId("test"));
+    exchangeNode.addChild(schemaMergeNode);
+    exchangeNode.setRemoteSourceNode(fragmentSinkNode);
+    exchangeNode.setUpstream(
+        new Endpoint("127.0.0.1", 6667),
+        new FragmentInstanceId(new PlanFragmentId("q", 1), "ds"),
+        new PlanNodeId("test"));
+    offsetNode.addChild(exchangeNode);
+    limitNode.addChild(offsetNode);
+    ByteBuffer byteBuffer = ByteBuffer.allocate(1024);
+    limitNode.serialize(byteBuffer);
+    byteBuffer.flip();
+    LimitNode limitNode1 = (LimitNode) PlanNodeDeserializeHelper.deserialize(byteBuffer);
+    Assert.assertEquals(limitNode, limitNode1);
+  }
+}
diff --git a/server/src/test/java/org/apache/iotdb/db/mpp/sql/plan/node/process/AggregateNodeSerdeTest.java b/server/src/test/java/org/apache/iotdb/db/mpp/sql/plan/node/process/AggregateNodeSerdeTest.java
index 5248fe4376..ab20e99e8e 100644
--- a/server/src/test/java/org/apache/iotdb/db/mpp/sql/plan/node/process/AggregateNodeSerdeTest.java
+++ b/server/src/test/java/org/apache/iotdb/db/mpp/sql/plan/node/process/AggregateNodeSerdeTest.java
@@ -18,19 +18,23 @@
  */
 package org.apache.iotdb.db.mpp.sql.plan.node.process;
 
+import org.apache.iotdb.commons.consensus.DataRegionId;
+import org.apache.iotdb.commons.partition.RegionReplicaSet;
 import org.apache.iotdb.db.exception.metadata.IllegalPathException;
+import org.apache.iotdb.db.metadata.path.AlignedPath;
 import org.apache.iotdb.db.metadata.path.MeasurementPath;
 import org.apache.iotdb.db.metadata.path.PartialPath;
 import org.apache.iotdb.db.mpp.sql.plan.node.PlanNodeDeserializeHelper;
 import org.apache.iotdb.db.mpp.sql.planner.plan.node.PlanNodeId;
-import org.apache.iotdb.db.mpp.sql.planner.plan.node.metedata.read.ShowDevicesNode;
 import org.apache.iotdb.db.mpp.sql.planner.plan.node.process.AggregateNode;
+import org.apache.iotdb.db.mpp.sql.planner.plan.node.source.SeriesScanNode;
 import org.apache.iotdb.db.query.aggregation.AggregationType;
 import org.apache.iotdb.tsfile.file.metadata.enums.TSDataType;
 
 import org.junit.Test;
 
 import java.nio.ByteBuffer;
+import java.util.ArrayList;
 import java.util.HashMap;
 import java.util.HashSet;
 import java.util.Map;
@@ -49,10 +53,15 @@ public class AggregateNodeSerdeTest {
         new MeasurementPath("root.sg.d1.s1", TSDataType.BOOLEAN), aggregationTypes);
     AggregateNode aggregateNode =
         new AggregateNode(new PlanNodeId("TestAggregateNode"), null, aggregateFuncMap, null);
-    aggregateNode.addChild(new ShowDevicesNode(new PlanNodeId("TestShowDevice")));
+    SeriesScanNode seriesScanNode =
+        new SeriesScanNode(
+            new PlanNodeId("TestSeriesScanNode"),
+            new AlignedPath("s1"),
+            new RegionReplicaSet(new DataRegionId(1), new ArrayList<>()));
+    aggregateNode.addChild(seriesScanNode);
     ByteBuffer byteBuffer = ByteBuffer.allocate(1024);
     aggregateNode.serialize(byteBuffer);
     byteBuffer.flip();
-    assertEquals((AggregateNode) PlanNodeDeserializeHelper.deserialize(byteBuffer), aggregateNode);
+    assertEquals(PlanNodeDeserializeHelper.deserialize(byteBuffer), aggregateNode);
   }
 }
diff --git a/server/src/test/java/org/apache/iotdb/db/mpp/sql/plan/node/process/DeviceMergeNodeSerdeTest.java b/server/src/test/java/org/apache/iotdb/db/mpp/sql/plan/node/process/DeviceMergeNodeSerdeTest.java
index 19dd567370..66463f1aa5 100644
--- a/server/src/test/java/org/apache/iotdb/db/mpp/sql/plan/node/process/DeviceMergeNodeSerdeTest.java
+++ b/server/src/test/java/org/apache/iotdb/db/mpp/sql/plan/node/process/DeviceMergeNodeSerdeTest.java
@@ -18,14 +18,17 @@
  */
 package org.apache.iotdb.db.mpp.sql.plan.node.process;
 
+import org.apache.iotdb.commons.consensus.DataRegionId;
+import org.apache.iotdb.commons.partition.RegionReplicaSet;
 import org.apache.iotdb.db.exception.metadata.IllegalPathException;
+import org.apache.iotdb.db.metadata.path.AlignedPath;
 import org.apache.iotdb.db.metadata.path.MeasurementPath;
 import org.apache.iotdb.db.metadata.path.PartialPath;
 import org.apache.iotdb.db.mpp.sql.plan.node.PlanNodeDeserializeHelper;
 import org.apache.iotdb.db.mpp.sql.planner.plan.node.PlanNodeId;
-import org.apache.iotdb.db.mpp.sql.planner.plan.node.metedata.read.ShowDevicesNode;
 import org.apache.iotdb.db.mpp.sql.planner.plan.node.process.AggregateNode;
 import org.apache.iotdb.db.mpp.sql.planner.plan.node.process.DeviceMergeNode;
+import org.apache.iotdb.db.mpp.sql.planner.plan.node.source.SeriesScanNode;
 import org.apache.iotdb.db.mpp.sql.statement.component.FilterNullComponent;
 import org.apache.iotdb.db.mpp.sql.statement.component.OrderBy;
 import org.apache.iotdb.db.query.aggregation.AggregationType;
@@ -34,6 +37,7 @@ import org.apache.iotdb.tsfile.file.metadata.enums.TSDataType;
 import org.junit.Test;
 
 import java.nio.ByteBuffer;
+import java.util.ArrayList;
 import java.util.HashMap;
 import java.util.HashSet;
 import java.util.Map;
@@ -51,7 +55,12 @@ public class DeviceMergeNodeSerdeTest {
         new MeasurementPath("root.sg.d1.s1", TSDataType.BOOLEAN), aggregationTypes);
     AggregateNode aggregateNode =
         new AggregateNode(new PlanNodeId("TestAggregateNode"), null, aggregateFuncMap, null);
-    aggregateNode.addChild(new ShowDevicesNode(new PlanNodeId("TestShowDevice")));
+    SeriesScanNode seriesScanNode =
+        new SeriesScanNode(
+            new PlanNodeId("TestSeriesScanNode"),
+            new AlignedPath("s1"),
+            new RegionReplicaSet(new DataRegionId(1), new ArrayList<>()));
+    aggregateNode.addChild(seriesScanNode);
 
     DeviceMergeNode deviceMergeNode =
         new DeviceMergeNode(new PlanNodeId("TestDeviceMergeNode"), OrderBy.TIMESTAMP_ASC);
@@ -67,10 +76,10 @@ public class DeviceMergeNodeSerdeTest {
         new MeasurementPath("root.sg.d1.s1", TSDataType.BOOLEAN), aggregationTypes);
     aggregateNode =
         new AggregateNode(new PlanNodeId("TestAggregateNode"), null, aggregateFuncMap, null);
-    aggregateNode.addChild(new ShowDevicesNode(new PlanNodeId("TestShowDevice")));
+    aggregateNode.addChild(seriesScanNode);
 
     deviceMergeNode.addChild(aggregateNode);
-    deviceMergeNode.addChild(new ShowDevicesNode(new PlanNodeId("TestShowDevice")));
+    deviceMergeNode.addChild(seriesScanNode);
 
     ByteBuffer byteBuffer = ByteBuffer.allocate(1024);
     deviceMergeNode.serialize(byteBuffer);
diff --git a/server/src/test/java/org/apache/iotdb/db/mpp/sql/plan/node/process/ExchangeNodeSerdeTest.java b/server/src/test/java/org/apache/iotdb/db/mpp/sql/plan/node/process/ExchangeNodeSerdeTest.java
index 7f813e2b20..3dc47fb4f5 100644
--- a/server/src/test/java/org/apache/iotdb/db/mpp/sql/plan/node/process/ExchangeNodeSerdeTest.java
+++ b/server/src/test/java/org/apache/iotdb/db/mpp/sql/plan/node/process/ExchangeNodeSerdeTest.java
@@ -19,18 +19,21 @@
 package org.apache.iotdb.db.mpp.sql.plan.node.process;
 
 import org.apache.iotdb.commons.cluster.Endpoint;
+import org.apache.iotdb.commons.consensus.DataRegionId;
+import org.apache.iotdb.commons.partition.RegionReplicaSet;
 import org.apache.iotdb.db.exception.metadata.IllegalPathException;
+import org.apache.iotdb.db.metadata.path.AlignedPath;
 import org.apache.iotdb.db.metadata.path.MeasurementPath;
 import org.apache.iotdb.db.metadata.path.PartialPath;
 import org.apache.iotdb.db.mpp.common.FragmentInstanceId;
 import org.apache.iotdb.db.mpp.common.PlanFragmentId;
 import org.apache.iotdb.db.mpp.sql.plan.node.PlanNodeDeserializeHelper;
 import org.apache.iotdb.db.mpp.sql.planner.plan.node.PlanNodeId;
-import org.apache.iotdb.db.mpp.sql.planner.plan.node.metedata.read.ShowDevicesNode;
 import org.apache.iotdb.db.mpp.sql.planner.plan.node.process.AggregateNode;
 import org.apache.iotdb.db.mpp.sql.planner.plan.node.process.DeviceMergeNode;
 import org.apache.iotdb.db.mpp.sql.planner.plan.node.process.ExchangeNode;
 import org.apache.iotdb.db.mpp.sql.planner.plan.node.sink.FragmentSinkNode;
+import org.apache.iotdb.db.mpp.sql.planner.plan.node.source.SeriesScanNode;
 import org.apache.iotdb.db.mpp.sql.statement.component.FilterNullComponent;
 import org.apache.iotdb.db.mpp.sql.statement.component.OrderBy;
 import org.apache.iotdb.db.query.aggregation.AggregationType;
@@ -39,6 +42,7 @@ import org.apache.iotdb.tsfile.file.metadata.enums.TSDataType;
 import org.junit.Test;
 
 import java.nio.ByteBuffer;
+import java.util.ArrayList;
 import java.util.HashMap;
 import java.util.HashSet;
 import java.util.Map;
@@ -57,7 +61,12 @@ public class ExchangeNodeSerdeTest {
         new MeasurementPath("root.sg.d1.s1", TSDataType.BOOLEAN), aggregationTypes);
     AggregateNode aggregateNode =
         new AggregateNode(new PlanNodeId("TestAggregateNode"), null, aggregateFuncMap, null);
-    aggregateNode.addChild(new ShowDevicesNode(new PlanNodeId("TestShowDevice")));
+    SeriesScanNode seriesScanNode =
+        new SeriesScanNode(
+            new PlanNodeId("TestSeriesScanNode"),
+            new AlignedPath("s1"),
+            new RegionReplicaSet(new DataRegionId(1), new ArrayList<>()));
+    aggregateNode.addChild(seriesScanNode);
 
     DeviceMergeNode deviceMergeNode =
         new DeviceMergeNode(new PlanNodeId("TestDeviceMergeNode"), OrderBy.TIMESTAMP_ASC);
@@ -73,10 +82,10 @@ public class ExchangeNodeSerdeTest {
         new MeasurementPath("root.sg.d1.s1", TSDataType.BOOLEAN), aggregationTypes);
     aggregateNode =
         new AggregateNode(new PlanNodeId("TestAggregateNode"), null, aggregateFuncMap, null);
-    aggregateNode.addChild(new ShowDevicesNode(new PlanNodeId("TestShowDevice")));
+    aggregateNode.addChild(seriesScanNode);
 
     deviceMergeNode.addChild(aggregateNode);
-    deviceMergeNode.addChild(new ShowDevicesNode(new PlanNodeId("TestShowDevice")));
+    deviceMergeNode.addChild(seriesScanNode);
 
     ExchangeNode exchangeNode = new ExchangeNode(new PlanNodeId("TestExchangeNode"));
     FragmentSinkNode fragmentSinkNode =
@@ -85,7 +94,7 @@ public class ExchangeNodeSerdeTest {
         new Endpoint("127.0.0.1", 6666),
         new FragmentInstanceId(new PlanFragmentId("q", 1), "ds"),
         new PlanNodeId("test"));
-    fragmentSinkNode.addChild(new ShowDevicesNode(new PlanNodeId("ss")));
+    fragmentSinkNode.addChild(seriesScanNode);
     exchangeNode.setRemoteSourceNode(fragmentSinkNode);
     exchangeNode.addChild(deviceMergeNode);
     exchangeNode.setUpstream(
diff --git a/server/src/test/java/org/apache/iotdb/db/mpp/sql/plan/node/process/FillNodeSerdeTest.java b/server/src/test/java/org/apache/iotdb/db/mpp/sql/plan/node/process/FillNodeSerdeTest.java
index 686b96a032..c282d26626 100644
--- a/server/src/test/java/org/apache/iotdb/db/mpp/sql/plan/node/process/FillNodeSerdeTest.java
+++ b/server/src/test/java/org/apache/iotdb/db/mpp/sql/plan/node/process/FillNodeSerdeTest.java
@@ -18,15 +18,18 @@
  */
 package org.apache.iotdb.db.mpp.sql.plan.node.process;
 
+import org.apache.iotdb.commons.consensus.DataRegionId;
+import org.apache.iotdb.commons.partition.RegionReplicaSet;
 import org.apache.iotdb.db.exception.metadata.IllegalPathException;
+import org.apache.iotdb.db.metadata.path.AlignedPath;
 import org.apache.iotdb.db.metadata.path.MeasurementPath;
 import org.apache.iotdb.db.metadata.path.PartialPath;
 import org.apache.iotdb.db.mpp.sql.plan.node.PlanNodeDeserializeHelper;
 import org.apache.iotdb.db.mpp.sql.planner.plan.node.PlanNodeId;
-import org.apache.iotdb.db.mpp.sql.planner.plan.node.metedata.read.ShowDevicesNode;
 import org.apache.iotdb.db.mpp.sql.planner.plan.node.process.AggregateNode;
 import org.apache.iotdb.db.mpp.sql.planner.plan.node.process.DeviceMergeNode;
 import org.apache.iotdb.db.mpp.sql.planner.plan.node.process.FillNode;
+import org.apache.iotdb.db.mpp.sql.planner.plan.node.source.SeriesScanNode;
 import org.apache.iotdb.db.mpp.sql.statement.component.FillPolicy;
 import org.apache.iotdb.db.mpp.sql.statement.component.FilterNullComponent;
 import org.apache.iotdb.db.mpp.sql.statement.component.OrderBy;
@@ -36,6 +39,7 @@ import org.apache.iotdb.tsfile.file.metadata.enums.TSDataType;
 import org.junit.Test;
 
 import java.nio.ByteBuffer;
+import java.util.ArrayList;
 import java.util.HashMap;
 import java.util.HashSet;
 import java.util.Map;
@@ -61,7 +65,12 @@ public class FillNodeSerdeTest {
         new MeasurementPath("root.sg.d1.s1", TSDataType.BOOLEAN), aggregationTypes);
     AggregateNode aggregateNode =
         new AggregateNode(new PlanNodeId("TestAggregateNode"), null, aggregateFuncMap, null);
-    aggregateNode.addChild(new ShowDevicesNode(new PlanNodeId("TestShowDevice")));
+    SeriesScanNode seriesScanNode =
+        new SeriesScanNode(
+            new PlanNodeId("TestSeriesScanNode"),
+            new AlignedPath("s1"),
+            new RegionReplicaSet(new DataRegionId(1), new ArrayList<>()));
+    aggregateNode.addChild(seriesScanNode);
     deviceMergeNode.addChildDeviceNode("device", aggregateNode);
 
     aggregateFuncMap = new HashMap<>();
@@ -71,9 +80,9 @@ public class FillNodeSerdeTest {
         new MeasurementPath("root.sg.d1.s1", TSDataType.BOOLEAN), aggregationTypes);
     aggregateNode =
         new AggregateNode(new PlanNodeId("TestAggregateNode"), null, aggregateFuncMap, null);
-    aggregateNode.addChild(new ShowDevicesNode(new PlanNodeId("TestShowDevice")));
+    aggregateNode.addChild(seriesScanNode);
     deviceMergeNode.addChild(aggregateNode);
-    deviceMergeNode.addChild(new ShowDevicesNode(new PlanNodeId("TestShowDevice")));
+    deviceMergeNode.addChild(seriesScanNode);
 
     fillNode.addChild(deviceMergeNode);
 
diff --git a/server/src/test/java/org/apache/iotdb/db/mpp/sql/plan/node/process/FilterNodeSerdeTest.java b/server/src/test/java/org/apache/iotdb/db/mpp/sql/plan/node/process/FilterNodeSerdeTest.java
index 2e253f4149..74f416e2c1 100644
--- a/server/src/test/java/org/apache/iotdb/db/mpp/sql/plan/node/process/FilterNodeSerdeTest.java
+++ b/server/src/test/java/org/apache/iotdb/db/mpp/sql/plan/node/process/FilterNodeSerdeTest.java
@@ -18,16 +18,19 @@
  */
 package org.apache.iotdb.db.mpp.sql.plan.node.process;
 
+import org.apache.iotdb.commons.consensus.DataRegionId;
+import org.apache.iotdb.commons.partition.RegionReplicaSet;
 import org.apache.iotdb.db.exception.metadata.IllegalPathException;
+import org.apache.iotdb.db.metadata.path.AlignedPath;
 import org.apache.iotdb.db.metadata.path.MeasurementPath;
 import org.apache.iotdb.db.metadata.path.PartialPath;
 import org.apache.iotdb.db.mpp.sql.plan.node.PlanNodeDeserializeHelper;
 import org.apache.iotdb.db.mpp.sql.planner.plan.node.PlanNodeId;
-import org.apache.iotdb.db.mpp.sql.planner.plan.node.metedata.read.ShowDevicesNode;
 import org.apache.iotdb.db.mpp.sql.planner.plan.node.process.AggregateNode;
 import org.apache.iotdb.db.mpp.sql.planner.plan.node.process.DeviceMergeNode;
 import org.apache.iotdb.db.mpp.sql.planner.plan.node.process.FillNode;
 import org.apache.iotdb.db.mpp.sql.planner.plan.node.process.FilterNode;
+import org.apache.iotdb.db.mpp.sql.planner.plan.node.source.SeriesScanNode;
 import org.apache.iotdb.db.mpp.sql.statement.component.FillPolicy;
 import org.apache.iotdb.db.mpp.sql.statement.component.FilterNullComponent;
 import org.apache.iotdb.db.mpp.sql.statement.component.OrderBy;
@@ -41,6 +44,7 @@ import org.apache.iotdb.tsfile.read.filter.operator.Regexp;
 import org.junit.Test;
 
 import java.nio.ByteBuffer;
+import java.util.ArrayList;
 import java.util.HashMap;
 import java.util.HashSet;
 import java.util.Map;
@@ -72,7 +76,12 @@ public class FilterNodeSerdeTest {
         new MeasurementPath("root.sg.d1.s1", TSDataType.BOOLEAN), aggregationTypes);
     AggregateNode aggregateNode =
         new AggregateNode(new PlanNodeId("TestAggregateNode"), null, aggregateFuncMap, null);
-    aggregateNode.addChild(new ShowDevicesNode(new PlanNodeId("TestShowDevice")));
+    SeriesScanNode seriesScanNode =
+        new SeriesScanNode(
+            new PlanNodeId("TestSeriesScanNode"),
+            new AlignedPath("s1"),
+            new RegionReplicaSet(new DataRegionId(1), new ArrayList<>()));
+    aggregateNode.addChild(seriesScanNode);
     deviceMergeNode.addChildDeviceNode("device", aggregateNode);
 
     aggregateFuncMap = new HashMap<>();
@@ -82,9 +91,9 @@ public class FilterNodeSerdeTest {
         new MeasurementPath("root.sg.d1.s1", TSDataType.BOOLEAN), aggregationTypes);
     aggregateNode =
         new AggregateNode(new PlanNodeId("TestAggregateNode"), null, aggregateFuncMap, null);
-    aggregateNode.addChild(new ShowDevicesNode(new PlanNodeId("TestShowDevice")));
+    aggregateNode.addChild(seriesScanNode);
     deviceMergeNode.addChild(aggregateNode);
-    deviceMergeNode.addChild(new ShowDevicesNode(new PlanNodeId("TestShowDevice")));
+    deviceMergeNode.addChild(seriesScanNode);
 
     fillNode.addChild(deviceMergeNode);
     filterNode.addChild(fillNode);
diff --git a/server/src/test/java/org/apache/iotdb/db/mpp/sql/plan/node/process/FilterNullNodeSerdeTest.java b/server/src/test/java/org/apache/iotdb/db/mpp/sql/plan/node/process/FilterNullNodeSerdeTest.java
index ccbd81d7bd..9740b0d530 100644
--- a/server/src/test/java/org/apache/iotdb/db/mpp/sql/plan/node/process/FilterNullNodeSerdeTest.java
+++ b/server/src/test/java/org/apache/iotdb/db/mpp/sql/plan/node/process/FilterNullNodeSerdeTest.java
@@ -18,17 +18,20 @@
  */
 package org.apache.iotdb.db.mpp.sql.plan.node.process;
 
+import org.apache.iotdb.commons.consensus.DataRegionId;
+import org.apache.iotdb.commons.partition.RegionReplicaSet;
 import org.apache.iotdb.db.exception.metadata.IllegalPathException;
+import org.apache.iotdb.db.metadata.path.AlignedPath;
 import org.apache.iotdb.db.metadata.path.MeasurementPath;
 import org.apache.iotdb.db.metadata.path.PartialPath;
 import org.apache.iotdb.db.mpp.sql.plan.node.PlanNodeDeserializeHelper;
 import org.apache.iotdb.db.mpp.sql.planner.plan.node.PlanNodeId;
-import org.apache.iotdb.db.mpp.sql.planner.plan.node.metedata.read.ShowDevicesNode;
 import org.apache.iotdb.db.mpp.sql.planner.plan.node.process.AggregateNode;
 import org.apache.iotdb.db.mpp.sql.planner.plan.node.process.DeviceMergeNode;
 import org.apache.iotdb.db.mpp.sql.planner.plan.node.process.FillNode;
 import org.apache.iotdb.db.mpp.sql.planner.plan.node.process.FilterNode;
 import org.apache.iotdb.db.mpp.sql.planner.plan.node.process.FilterNullNode;
+import org.apache.iotdb.db.mpp.sql.planner.plan.node.source.SeriesScanNode;
 import org.apache.iotdb.db.mpp.sql.statement.component.FillPolicy;
 import org.apache.iotdb.db.mpp.sql.statement.component.FilterNullComponent;
 import org.apache.iotdb.db.mpp.sql.statement.component.FilterNullPolicy;
@@ -43,6 +46,7 @@ import org.apache.iotdb.tsfile.read.filter.operator.Regexp;
 import org.junit.Test;
 
 import java.nio.ByteBuffer;
+import java.util.ArrayList;
 import java.util.HashMap;
 import java.util.HashSet;
 import java.util.Map;
@@ -74,7 +78,12 @@ public class FilterNullNodeSerdeTest {
         new MeasurementPath("root.sg.d1.s1", TSDataType.BOOLEAN), aggregationTypes);
     AggregateNode aggregateNode =
         new AggregateNode(new PlanNodeId("TestAggregateNode"), null, aggregateFuncMap, null);
-    aggregateNode.addChild(new ShowDevicesNode(new PlanNodeId("TestShowDevice")));
+    SeriesScanNode seriesScanNode =
+        new SeriesScanNode(
+            new PlanNodeId("TestSeriesScanNode"),
+            new AlignedPath("s1"),
+            new RegionReplicaSet(new DataRegionId(1), new ArrayList<>()));
+    aggregateNode.addChild(seriesScanNode);
     deviceMergeNode.addChildDeviceNode("device", aggregateNode);
 
     aggregateFuncMap = new HashMap<>();
@@ -84,9 +93,9 @@ public class FilterNullNodeSerdeTest {
         new MeasurementPath("root.sg.d1.s1", TSDataType.BOOLEAN), aggregationTypes);
     aggregateNode =
         new AggregateNode(new PlanNodeId("TestAggregateNode"), null, aggregateFuncMap, null);
-    aggregateNode.addChild(new ShowDevicesNode(new PlanNodeId("TestShowDevice")));
+    aggregateNode.addChild(seriesScanNode);
     deviceMergeNode.addChild(aggregateNode);
-    deviceMergeNode.addChild(new ShowDevicesNode(new PlanNodeId("TestShowDevice")));
+    deviceMergeNode.addChild(seriesScanNode);
 
     fillNode.addChild(deviceMergeNode);
     filterNode.addChild(fillNode);
diff --git a/server/src/test/java/org/apache/iotdb/db/mpp/sql/plan/node/process/GroupByLevelNodeSerdeTest.java b/server/src/test/java/org/apache/iotdb/db/mpp/sql/plan/node/process/GroupByLevelNodeSerdeTest.java
index ada62da218..cdbd5015cc 100644
--- a/server/src/test/java/org/apache/iotdb/db/mpp/sql/plan/node/process/GroupByLevelNodeSerdeTest.java
+++ b/server/src/test/java/org/apache/iotdb/db/mpp/sql/plan/node/process/GroupByLevelNodeSerdeTest.java
@@ -18,19 +18,22 @@
  */
 package org.apache.iotdb.db.mpp.sql.plan.node.process;
 
+import org.apache.iotdb.commons.consensus.DataRegionId;
+import org.apache.iotdb.commons.partition.RegionReplicaSet;
 import org.apache.iotdb.db.exception.metadata.IllegalPathException;
+import org.apache.iotdb.db.metadata.path.AlignedPath;
 import org.apache.iotdb.db.metadata.path.MeasurementPath;
 import org.apache.iotdb.db.metadata.path.PartialPath;
 import org.apache.iotdb.db.mpp.common.header.ColumnHeader;
 import org.apache.iotdb.db.mpp.sql.plan.node.PlanNodeDeserializeHelper;
 import org.apache.iotdb.db.mpp.sql.planner.plan.node.PlanNodeId;
-import org.apache.iotdb.db.mpp.sql.planner.plan.node.metedata.read.ShowDevicesNode;
 import org.apache.iotdb.db.mpp.sql.planner.plan.node.process.AggregateNode;
 import org.apache.iotdb.db.mpp.sql.planner.plan.node.process.DeviceMergeNode;
 import org.apache.iotdb.db.mpp.sql.planner.plan.node.process.FillNode;
 import org.apache.iotdb.db.mpp.sql.planner.plan.node.process.FilterNode;
 import org.apache.iotdb.db.mpp.sql.planner.plan.node.process.FilterNullNode;
 import org.apache.iotdb.db.mpp.sql.planner.plan.node.process.GroupByLevelNode;
+import org.apache.iotdb.db.mpp.sql.planner.plan.node.source.SeriesScanNode;
 import org.apache.iotdb.db.mpp.sql.statement.component.FillPolicy;
 import org.apache.iotdb.db.mpp.sql.statement.component.FilterNullComponent;
 import org.apache.iotdb.db.mpp.sql.statement.component.FilterNullPolicy;
@@ -45,6 +48,7 @@ import org.apache.iotdb.tsfile.read.filter.operator.Regexp;
 import org.junit.Test;
 
 import java.nio.ByteBuffer;
+import java.util.ArrayList;
 import java.util.HashMap;
 import java.util.HashSet;
 import java.util.Map;
@@ -76,7 +80,12 @@ public class GroupByLevelNodeSerdeTest {
         new MeasurementPath("root.sg.d1.s1", TSDataType.BOOLEAN), aggregationTypes);
     AggregateNode aggregateNode =
         new AggregateNode(new PlanNodeId("TestAggregateNode"), null, aggregateFuncMap, null);
-    aggregateNode.addChild(new ShowDevicesNode(new PlanNodeId("TestShowDevice")));
+    SeriesScanNode seriesScanNode =
+        new SeriesScanNode(
+            new PlanNodeId("TestSeriesScanNode"),
+            new AlignedPath("s1"),
+            new RegionReplicaSet(new DataRegionId(1), new ArrayList<>()));
+    aggregateNode.addChild(seriesScanNode);
     deviceMergeNode.addChildDeviceNode("device", aggregateNode);
 
     aggregateFuncMap = new HashMap<>();
@@ -86,9 +95,9 @@ public class GroupByLevelNodeSerdeTest {
         new MeasurementPath("root.sg.d1.s1", TSDataType.BOOLEAN), aggregationTypes);
     aggregateNode =
         new AggregateNode(new PlanNodeId("TestAggregateNode"), null, aggregateFuncMap, null);
-    aggregateNode.addChild(new ShowDevicesNode(new PlanNodeId("TestShowDevice")));
+    aggregateNode.addChild(seriesScanNode);
     deviceMergeNode.addChild(aggregateNode);
-    deviceMergeNode.addChild(new ShowDevicesNode(new PlanNodeId("TestShowDevice")));
+    deviceMergeNode.addChild(seriesScanNode);
 
     fillNode.addChild(deviceMergeNode);
     filterNode.addChild(fillNode);
diff --git a/server/src/test/java/org/apache/iotdb/db/mpp/sql/plan/node/process/LimitNodeSerdeTest.java b/server/src/test/java/org/apache/iotdb/db/mpp/sql/plan/node/process/LimitNodeSerdeTest.java
index 47392bdb00..c693aa735e 100644
--- a/server/src/test/java/org/apache/iotdb/db/mpp/sql/plan/node/process/LimitNodeSerdeTest.java
+++ b/server/src/test/java/org/apache/iotdb/db/mpp/sql/plan/node/process/LimitNodeSerdeTest.java
@@ -18,13 +18,15 @@
  */
 package org.apache.iotdb.db.mpp.sql.plan.node.process;
 
+import org.apache.iotdb.commons.consensus.DataRegionId;
+import org.apache.iotdb.commons.partition.RegionReplicaSet;
 import org.apache.iotdb.db.exception.metadata.IllegalPathException;
+import org.apache.iotdb.db.metadata.path.AlignedPath;
 import org.apache.iotdb.db.metadata.path.MeasurementPath;
 import org.apache.iotdb.db.metadata.path.PartialPath;
 import org.apache.iotdb.db.mpp.common.header.ColumnHeader;
 import org.apache.iotdb.db.mpp.sql.plan.node.PlanNodeDeserializeHelper;
 import org.apache.iotdb.db.mpp.sql.planner.plan.node.PlanNodeId;
-import org.apache.iotdb.db.mpp.sql.planner.plan.node.metedata.read.ShowDevicesNode;
 import org.apache.iotdb.db.mpp.sql.planner.plan.node.process.AggregateNode;
 import org.apache.iotdb.db.mpp.sql.planner.plan.node.process.DeviceMergeNode;
 import org.apache.iotdb.db.mpp.sql.planner.plan.node.process.FillNode;
@@ -32,6 +34,7 @@ import org.apache.iotdb.db.mpp.sql.planner.plan.node.process.FilterNode;
 import org.apache.iotdb.db.mpp.sql.planner.plan.node.process.FilterNullNode;
 import org.apache.iotdb.db.mpp.sql.planner.plan.node.process.GroupByLevelNode;
 import org.apache.iotdb.db.mpp.sql.planner.plan.node.process.LimitNode;
+import org.apache.iotdb.db.mpp.sql.planner.plan.node.source.SeriesScanNode;
 import org.apache.iotdb.db.mpp.sql.statement.component.FillPolicy;
 import org.apache.iotdb.db.mpp.sql.statement.component.FilterNullComponent;
 import org.apache.iotdb.db.mpp.sql.statement.component.FilterNullPolicy;
@@ -46,6 +49,7 @@ import org.apache.iotdb.tsfile.read.filter.operator.Regexp;
 import org.junit.Test;
 
 import java.nio.ByteBuffer;
+import java.util.ArrayList;
 import java.util.HashMap;
 import java.util.HashSet;
 import java.util.Map;
@@ -77,7 +81,12 @@ public class LimitNodeSerdeTest {
         new MeasurementPath("root.sg.d1.s1", TSDataType.BOOLEAN), aggregationTypes);
     AggregateNode aggregateNode =
         new AggregateNode(new PlanNodeId("TestAggregateNode"), null, aggregateFuncMap, null);
-    aggregateNode.addChild(new ShowDevicesNode(new PlanNodeId("TestShowDevice")));
+    SeriesScanNode seriesScanNode =
+        new SeriesScanNode(
+            new PlanNodeId("TestSeriesScanNode"),
+            new AlignedPath("s1"),
+            new RegionReplicaSet(new DataRegionId(1), new ArrayList<>()));
+    aggregateNode.addChild(seriesScanNode);
     deviceMergeNode.addChildDeviceNode("device", aggregateNode);
 
     aggregateFuncMap = new HashMap<>();
@@ -87,9 +96,9 @@ public class LimitNodeSerdeTest {
         new MeasurementPath("root.sg.d1.s1", TSDataType.BOOLEAN), aggregationTypes);
     aggregateNode =
         new AggregateNode(new PlanNodeId("TestAggregateNode"), null, aggregateFuncMap, null);
-    aggregateNode.addChild(new ShowDevicesNode(new PlanNodeId("TestShowDevice")));
+    aggregateNode.addChild(seriesScanNode);
     deviceMergeNode.addChild(aggregateNode);
-    deviceMergeNode.addChild(new ShowDevicesNode(new PlanNodeId("TestShowDevice")));
+    deviceMergeNode.addChild(seriesScanNode);
 
     fillNode.addChild(deviceMergeNode);
     filterNode.addChild(fillNode);
diff --git a/server/src/test/java/org/apache/iotdb/db/mpp/sql/plan/node/process/OffsetNodeSerdeTest.java b/server/src/test/java/org/apache/iotdb/db/mpp/sql/plan/node/process/OffsetNodeSerdeTest.java
index 5c6ecdd9cd..eb2f482b99 100644
--- a/server/src/test/java/org/apache/iotdb/db/mpp/sql/plan/node/process/OffsetNodeSerdeTest.java
+++ b/server/src/test/java/org/apache/iotdb/db/mpp/sql/plan/node/process/OffsetNodeSerdeTest.java
@@ -21,6 +21,7 @@ package org.apache.iotdb.db.mpp.sql.plan.node.process;
 import org.apache.iotdb.commons.consensus.DataRegionId;
 import org.apache.iotdb.commons.partition.RegionReplicaSet;
 import org.apache.iotdb.db.exception.metadata.IllegalPathException;
+import org.apache.iotdb.db.metadata.path.AlignedPath;
 import org.apache.iotdb.db.metadata.path.MeasurementPath;
 import org.apache.iotdb.db.metadata.path.PartialPath;
 import org.apache.iotdb.db.mpp.common.filter.BasicFunctionFilter;
@@ -29,7 +30,6 @@ import org.apache.iotdb.db.mpp.common.header.ColumnHeader;
 import org.apache.iotdb.db.mpp.sql.constant.FilterConstant.FilterType;
 import org.apache.iotdb.db.mpp.sql.plan.node.PlanNodeDeserializeHelper;
 import org.apache.iotdb.db.mpp.sql.planner.plan.node.PlanNodeId;
-import org.apache.iotdb.db.mpp.sql.planner.plan.node.metedata.read.ShowDevicesNode;
 import org.apache.iotdb.db.mpp.sql.planner.plan.node.process.AggregateNode;
 import org.apache.iotdb.db.mpp.sql.planner.plan.node.process.DeviceMergeNode;
 import org.apache.iotdb.db.mpp.sql.planner.plan.node.process.FillNode;
@@ -87,7 +87,12 @@ public class OffsetNodeSerdeTest {
         new MeasurementPath("root.sg.d1.s1", TSDataType.BOOLEAN), aggregationTypes);
     AggregateNode aggregateNode =
         new AggregateNode(new PlanNodeId("TestAggregateNode"), null, aggregateFuncMap, null);
-    aggregateNode.addChild(new ShowDevicesNode(new PlanNodeId("TestShowDevice")));
+    SeriesScanNode seriesScanNode =
+        new SeriesScanNode(
+            new PlanNodeId("TestSeriesScanNode"),
+            new AlignedPath("s1"),
+            new RegionReplicaSet(new DataRegionId(1), new ArrayList<>()));
+    aggregateNode.addChild(seriesScanNode);
     deviceMergeNode.addChildDeviceNode("device", aggregateNode);
 
     aggregateFuncMap = new HashMap<>();
@@ -97,9 +102,9 @@ public class OffsetNodeSerdeTest {
         new MeasurementPath("root.sg.d1.s1", TSDataType.BOOLEAN), aggregationTypes);
     aggregateNode =
         new AggregateNode(new PlanNodeId("TestAggregateNode"), null, aggregateFuncMap, null);
-    aggregateNode.addChild(new ShowDevicesNode(new PlanNodeId("TestShowDevice")));
+    aggregateNode.addChild(seriesScanNode);
     deviceMergeNode.addChild(aggregateNode);
-    deviceMergeNode.addChild(new ShowDevicesNode(new PlanNodeId("TestShowDevice")));
+    deviceMergeNode.addChild(seriesScanNode);
 
     fillNode.addChild(deviceMergeNode);
     filterNode.addChild(fillNode);
@@ -122,7 +127,7 @@ public class OffsetNodeSerdeTest {
 
     LimitNode limitNode = new LimitNode(new PlanNodeId("TestLimitNode"), groupByLevelNode, 3);
     OffsetNode offsetNode = new OffsetNode(new PlanNodeId("TestOffsetNode"), limitNode, 2);
-    ByteBuffer byteBuffer = ByteBuffer.allocate(1024);
+    ByteBuffer byteBuffer = ByteBuffer.allocate(2048);
     offsetNode.serialize(byteBuffer);
     byteBuffer.flip();
     assertEquals(PlanNodeDeserializeHelper.deserialize(byteBuffer), offsetNode);
diff --git a/server/src/test/java/org/apache/iotdb/db/mpp/sql/plan/node/process/SortNodeSerdeTest.java b/server/src/test/java/org/apache/iotdb/db/mpp/sql/plan/node/process/SortNodeSerdeTest.java
index 58f397c7e0..d2385f117a 100644
--- a/server/src/test/java/org/apache/iotdb/db/mpp/sql/plan/node/process/SortNodeSerdeTest.java
+++ b/server/src/test/java/org/apache/iotdb/db/mpp/sql/plan/node/process/SortNodeSerdeTest.java
@@ -18,13 +18,15 @@
  */
 package org.apache.iotdb.db.mpp.sql.plan.node.process;
 
+import org.apache.iotdb.commons.consensus.DataRegionId;
+import org.apache.iotdb.commons.partition.RegionReplicaSet;
 import org.apache.iotdb.db.exception.metadata.IllegalPathException;
+import org.apache.iotdb.db.metadata.path.AlignedPath;
 import org.apache.iotdb.db.metadata.path.MeasurementPath;
 import org.apache.iotdb.db.metadata.path.PartialPath;
 import org.apache.iotdb.db.mpp.common.header.ColumnHeader;
 import org.apache.iotdb.db.mpp.sql.plan.node.PlanNodeDeserializeHelper;
 import org.apache.iotdb.db.mpp.sql.planner.plan.node.PlanNodeId;
-import org.apache.iotdb.db.mpp.sql.planner.plan.node.metedata.read.ShowDevicesNode;
 import org.apache.iotdb.db.mpp.sql.planner.plan.node.process.AggregateNode;
 import org.apache.iotdb.db.mpp.sql.planner.plan.node.process.DeviceMergeNode;
 import org.apache.iotdb.db.mpp.sql.planner.plan.node.process.FillNode;
@@ -34,6 +36,7 @@ import org.apache.iotdb.db.mpp.sql.planner.plan.node.process.GroupByLevelNode;
 import org.apache.iotdb.db.mpp.sql.planner.plan.node.process.LimitNode;
 import org.apache.iotdb.db.mpp.sql.planner.plan.node.process.OffsetNode;
 import org.apache.iotdb.db.mpp.sql.planner.plan.node.process.SortNode;
+import org.apache.iotdb.db.mpp.sql.planner.plan.node.source.SeriesScanNode;
 import org.apache.iotdb.db.mpp.sql.statement.component.FillPolicy;
 import org.apache.iotdb.db.mpp.sql.statement.component.FilterNullComponent;
 import org.apache.iotdb.db.mpp.sql.statement.component.FilterNullPolicy;
@@ -82,7 +85,12 @@ public class SortNodeSerdeTest {
         new MeasurementPath("root.sg.d1.s1", TSDataType.BOOLEAN), aggregationTypes);
     AggregateNode aggregateNode =
         new AggregateNode(new PlanNodeId("TestAggregateNode"), null, aggregateFuncMap, null);
-    aggregateNode.addChild(new ShowDevicesNode(new PlanNodeId("TestShowDevice")));
+    SeriesScanNode seriesScanNode =
+        new SeriesScanNode(
+            new PlanNodeId("TestSeriesScanNode"),
+            new AlignedPath("s1"),
+            new RegionReplicaSet(new DataRegionId(1), new ArrayList<>()));
+    aggregateNode.addChild(seriesScanNode);
     deviceMergeNode.addChildDeviceNode("device", aggregateNode);
 
     aggregateFuncMap = new HashMap<>();
@@ -92,9 +100,9 @@ public class SortNodeSerdeTest {
         new MeasurementPath("root.sg.d1.s1", TSDataType.BOOLEAN), aggregationTypes);
     aggregateNode =
         new AggregateNode(new PlanNodeId("TestAggregateNode"), null, aggregateFuncMap, null);
-    aggregateNode.addChild(new ShowDevicesNode(new PlanNodeId("TestShowDevice")));
+    aggregateNode.addChild(seriesScanNode);
     deviceMergeNode.addChild(aggregateNode);
-    deviceMergeNode.addChild(new ShowDevicesNode(new PlanNodeId("TestShowDevice")));
+    deviceMergeNode.addChild(seriesScanNode);
 
     fillNode.addChild(deviceMergeNode);
     filterNode.addChild(fillNode);
@@ -122,7 +130,7 @@ public class SortNodeSerdeTest {
     orderByStr.add("s1");
     SortNode sortNode =
         new SortNode(new PlanNodeId("TestSortNode"), offsetNode, orderByStr, OrderBy.TIMESTAMP_ASC);
-    ByteBuffer byteBuffer = ByteBuffer.allocate(1024);
+    ByteBuffer byteBuffer = ByteBuffer.allocate(2048);
     sortNode.serialize(byteBuffer);
     byteBuffer.flip();
     assertEquals(PlanNodeDeserializeHelper.deserialize(byteBuffer), sortNode);
diff --git a/server/src/test/java/org/apache/iotdb/db/mpp/sql/plan/node/process/TimeJoinNodeSerdeTest.java b/server/src/test/java/org/apache/iotdb/db/mpp/sql/plan/node/process/TimeJoinNodeSerdeTest.java
index 987c8a3f68..9c99507611 100644
--- a/server/src/test/java/org/apache/iotdb/db/mpp/sql/plan/node/process/TimeJoinNodeSerdeTest.java
+++ b/server/src/test/java/org/apache/iotdb/db/mpp/sql/plan/node/process/TimeJoinNodeSerdeTest.java
@@ -18,13 +18,15 @@
  */
 package org.apache.iotdb.db.mpp.sql.plan.node.process;
 
+import org.apache.iotdb.commons.consensus.DataRegionId;
+import org.apache.iotdb.commons.partition.RegionReplicaSet;
 import org.apache.iotdb.db.exception.metadata.IllegalPathException;
+import org.apache.iotdb.db.metadata.path.AlignedPath;
 import org.apache.iotdb.db.metadata.path.MeasurementPath;
 import org.apache.iotdb.db.metadata.path.PartialPath;
 import org.apache.iotdb.db.mpp.common.header.ColumnHeader;
 import org.apache.iotdb.db.mpp.sql.plan.node.PlanNodeDeserializeHelper;
 import org.apache.iotdb.db.mpp.sql.planner.plan.node.PlanNodeId;
-import org.apache.iotdb.db.mpp.sql.planner.plan.node.metedata.read.ShowDevicesNode;
 import org.apache.iotdb.db.mpp.sql.planner.plan.node.process.AggregateNode;
 import org.apache.iotdb.db.mpp.sql.planner.plan.node.process.DeviceMergeNode;
 import org.apache.iotdb.db.mpp.sql.planner.plan.node.process.FillNode;
@@ -35,6 +37,7 @@ import org.apache.iotdb.db.mpp.sql.planner.plan.node.process.LimitNode;
 import org.apache.iotdb.db.mpp.sql.planner.plan.node.process.OffsetNode;
 import org.apache.iotdb.db.mpp.sql.planner.plan.node.process.SortNode;
 import org.apache.iotdb.db.mpp.sql.planner.plan.node.process.TimeJoinNode;
+import org.apache.iotdb.db.mpp.sql.planner.plan.node.source.SeriesScanNode;
 import org.apache.iotdb.db.mpp.sql.statement.component.FillPolicy;
 import org.apache.iotdb.db.mpp.sql.statement.component.FilterNullComponent;
 import org.apache.iotdb.db.mpp.sql.statement.component.FilterNullPolicy;
@@ -82,7 +85,13 @@ public class TimeJoinNodeSerdeTest {
         new MeasurementPath("root.sg.d1.s1", TSDataType.BOOLEAN), aggregationTypes);
     AggregateNode aggregateNode =
         new AggregateNode(new PlanNodeId("TestAggregateNode"), null, aggregateFuncMap, null);
-    aggregateNode.addChild(new ShowDevicesNode(new PlanNodeId("TestShowDevice")));
+
+    SeriesScanNode seriesScanNode =
+        new SeriesScanNode(
+            new PlanNodeId("TestSeriesScanNode"),
+            new AlignedPath("s1"),
+            new RegionReplicaSet(new DataRegionId(1), new ArrayList<>()));
+    aggregateNode.addChild(seriesScanNode);
     deviceMergeNode.addChildDeviceNode("device", aggregateNode);
 
     aggregateFuncMap = new HashMap<>();
@@ -92,9 +101,9 @@ public class TimeJoinNodeSerdeTest {
         new MeasurementPath("root.sg.d1.s1", TSDataType.BOOLEAN), aggregationTypes);
     aggregateNode =
         new AggregateNode(new PlanNodeId("TestAggregateNode"), null, aggregateFuncMap, null);
-    aggregateNode.addChild(new ShowDevicesNode(new PlanNodeId("TestShowDevice")));
+    aggregateNode.addChild(seriesScanNode);
     deviceMergeNode.addChild(aggregateNode);
-    deviceMergeNode.addChild(new ShowDevicesNode(new PlanNodeId("TestShowDevice")));
+    deviceMergeNode.addChild(seriesScanNode);
 
     fillNode.addChild(deviceMergeNode);
     filterNode.addChild(fillNode);
@@ -127,7 +136,7 @@ public class TimeJoinNodeSerdeTest {
         new TimeJoinNode(new PlanNodeId("TestTimeJoinNode"), OrderBy.TIMESTAMP_ASC);
     timeJoinNode.setWithoutPolicy(FilterNullPolicy.CONTAINS_NULL);
     timeJoinNode.addChild(sortNode);
-    ByteBuffer byteBuffer = ByteBuffer.allocate(1024);
+    ByteBuffer byteBuffer = ByteBuffer.allocate(2048);
     timeJoinNode.serialize(byteBuffer);
     byteBuffer.flip();
     assertEquals(PlanNodeDeserializeHelper.deserialize(byteBuffer), timeJoinNode);
diff --git a/server/src/test/java/org/apache/iotdb/db/mpp/sql/plan/node/sink/FragmentSinkNodeSerdeTest.java b/server/src/test/java/org/apache/iotdb/db/mpp/sql/plan/node/sink/FragmentSinkNodeSerdeTest.java
index 2aa2610bde..a2804b8c2e 100644
--- a/server/src/test/java/org/apache/iotdb/db/mpp/sql/plan/node/sink/FragmentSinkNodeSerdeTest.java
+++ b/server/src/test/java/org/apache/iotdb/db/mpp/sql/plan/node/sink/FragmentSinkNodeSerdeTest.java
@@ -20,11 +20,12 @@ package org.apache.iotdb.db.mpp.sql.plan.node.sink;
 
 import org.apache.iotdb.commons.cluster.Endpoint;
 import org.apache.iotdb.db.exception.metadata.IllegalPathException;
+import org.apache.iotdb.db.metadata.path.PartialPath;
 import org.apache.iotdb.db.mpp.common.FragmentInstanceId;
 import org.apache.iotdb.db.mpp.common.PlanFragmentId;
 import org.apache.iotdb.db.mpp.sql.plan.node.PlanNodeDeserializeHelper;
 import org.apache.iotdb.db.mpp.sql.planner.plan.node.PlanNodeId;
-import org.apache.iotdb.db.mpp.sql.planner.plan.node.metedata.read.ShowDevicesNode;
+import org.apache.iotdb.db.mpp.sql.planner.plan.node.metedata.read.DevicesSchemaScanNode;
 import org.apache.iotdb.db.mpp.sql.planner.plan.node.sink.FragmentSinkNode;
 
 import org.junit.Test;
@@ -39,7 +40,9 @@ public class FragmentSinkNodeSerdeTest {
   public void TestSerializeAndDeserialize() throws IllegalPathException {
     FragmentSinkNode fragmentSinkNode =
         new FragmentSinkNode(new PlanNodeId("TestFragmentSinkNode"));
-    fragmentSinkNode.addChild(new ShowDevicesNode(new PlanNodeId("TestShowDevicesNode")));
+    fragmentSinkNode.addChild(
+        new DevicesSchemaScanNode(
+            new PlanNodeId("deviceSchema"), new PartialPath("root.sg.device"), 0, 0, false, false));
     fragmentSinkNode.setDownStream(
         new Endpoint("127.0.0.1", 6666),
         new FragmentInstanceId(new PlanFragmentId("q", 1), "ds"),
diff --git a/tsfile/src/main/java/org/apache/iotdb/tsfile/utils/ReadWriteIOUtils.java b/tsfile/src/main/java/org/apache/iotdb/tsfile/utils/ReadWriteIOUtils.java
index ef8ce93535..5fa9b9346e 100644
--- a/tsfile/src/main/java/org/apache/iotdb/tsfile/utils/ReadWriteIOUtils.java
+++ b/tsfile/src/main/java/org/apache/iotdb/tsfile/utils/ReadWriteIOUtils.java
@@ -803,6 +803,18 @@ public class ReadWriteIOUtils {
     return list;
   }
 
+  /** write string list with self define length. */
+  public static void writeStringList(List<String> list, ByteBuffer buffer) {
+    if (list == null) {
+      throw new IllegalArgumentException("stringList must not be null!");
+    }
+    int size = list.size();
+    buffer.putInt(size);
+    for (String s : list) {
+      buffer.put(s.getBytes());
+    }
+  }
+
   public static CompressionType readCompressionType(InputStream inputStream) throws IOException {
     byte n = readByte(inputStream);
     return CompressionType.deserialize(n);