You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@iotdb.apache.org by xi...@apache.org on 2022/05/22 12:21:01 UTC

[iotdb] branch master updated: [IOTDB-3184] Set up Delete timeseries statement and PlanNodes (#5974)

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

xingtanzjr 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 642c1b6725 [IOTDB-3184] Set up Delete timeseries statement and PlanNodes (#5974)
642c1b6725 is described below

commit 642c1b672544e22a34b58292df76fb9a96f89fa6
Author: Marcos_Zyk <38...@users.noreply.github.com>
AuthorDate: Sun May 22 20:20:54 2022 +0800

    [IOTDB-3184] Set up Delete timeseries statement and PlanNodes (#5974)
---
 .../db/mpp/common/schematree/PathPatternTree.java  |  12 +-
 .../apache/iotdb/db/mpp/plan/analyze/Analyzer.java |  44 +++++++
 .../iotdb/db/mpp/plan/parser/ASTVisitor.java       |  14 +++
 .../db/mpp/plan/planner/LogicalPlanBuilder.java    |   6 +-
 .../mpp/plan/planner/plan/node/PlanNodeType.java   |  14 ++-
 .../node/metedata/write/DeleteTimeSeriesNode.java  | 100 ++++++++++++++++
 .../metedata/write/InvalidateSchemaCacheNode.java  | 127 +++++++++++++++++++++
 .../planner/plan/node/write/DeleteDataNode.java    | 100 ++++++++++++++++
 .../db/mpp/plan/statement/StatementVisitor.java    |   5 +
 .../metadata/DeleteTimeSeriesStatement.java        |  45 ++++++++
 .../write/DeleteTimeSeriesNodeSerdeTest.java       |  61 ++++++++++
 .../plan/node/write/DeleteDataNodeSerdeTest.java   |  61 ++++++++++
 .../write/InvalidateSchemaCacheNodeSerdeTest.java  |  76 ++++++++++++
 13 files changed, 656 insertions(+), 9 deletions(-)

diff --git a/server/src/main/java/org/apache/iotdb/db/mpp/common/schematree/PathPatternTree.java b/server/src/main/java/org/apache/iotdb/db/mpp/common/schematree/PathPatternTree.java
index 8f3a78c498..2a34c2ad1c 100644
--- a/server/src/main/java/org/apache/iotdb/db/mpp/common/schematree/PathPatternTree.java
+++ b/server/src/main/java/org/apache/iotdb/db/mpp/common/schematree/PathPatternTree.java
@@ -38,8 +38,6 @@ import java.util.List;
 import java.util.Map;
 import java.util.stream.Collectors;
 
-import static org.apache.iotdb.commons.conf.IoTDBConstant.MULTI_LEVEL_PATH_WILDCARD;
-
 public class PathPatternTree {
 
   private PathPatternNode root;
@@ -252,18 +250,18 @@ public class PathPatternTree {
     return new PartialPath(nodeList.toArray(new String[0]));
   }
 
-  public PathPatternTree extractInvolvedPartByPrefix(PartialPath prefixPath) {
+  public PathPatternTree findOverlappedPattern(PartialPath pattern) {
     if (pathList.isEmpty()) {
       pathList = splitToPathList();
     }
-    PartialPath pattern = prefixPath.concatNode(MULTI_LEVEL_PATH_WILDCARD);
-    List<PartialPath> involvedPath = new ArrayList<>();
+
+    List<PartialPath> results = new ArrayList<>();
     for (PartialPath path : pathList) {
       if (pattern.overlapWith(path)) {
-        involvedPath.add(path);
+        results.add(path);
       }
     }
-    return new PathPatternTree(involvedPath);
+    return new PathPatternTree(results);
   }
 
   @TestOnly
diff --git a/server/src/main/java/org/apache/iotdb/db/mpp/plan/analyze/Analyzer.java b/server/src/main/java/org/apache/iotdb/db/mpp/plan/analyze/Analyzer.java
index 884b345b4b..c9139e51ae 100644
--- a/server/src/main/java/org/apache/iotdb/db/mpp/plan/analyze/Analyzer.java
+++ b/server/src/main/java/org/apache/iotdb/db/mpp/plan/analyze/Analyzer.java
@@ -20,6 +20,7 @@
 package org.apache.iotdb.db.mpp.plan.analyze;
 
 import org.apache.iotdb.commons.conf.IoTDBConstant;
+import org.apache.iotdb.commons.exception.IllegalPathException;
 import org.apache.iotdb.commons.partition.DataPartition;
 import org.apache.iotdb.commons.partition.DataPartitionQueryParam;
 import org.apache.iotdb.commons.partition.SchemaNodeManagementPartition;
@@ -62,6 +63,7 @@ import org.apache.iotdb.db.mpp.plan.statement.metadata.CountTimeSeriesStatement;
 import org.apache.iotdb.db.mpp.plan.statement.metadata.CreateAlignedTimeSeriesStatement;
 import org.apache.iotdb.db.mpp.plan.statement.metadata.CreateMultiTimeSeriesStatement;
 import org.apache.iotdb.db.mpp.plan.statement.metadata.CreateTimeSeriesStatement;
+import org.apache.iotdb.db.mpp.plan.statement.metadata.DeleteTimeSeriesStatement;
 import org.apache.iotdb.db.mpp.plan.statement.metadata.SchemaFetchStatement;
 import org.apache.iotdb.db.mpp.plan.statement.metadata.ShowChildNodesStatement;
 import org.apache.iotdb.db.mpp.plan.statement.metadata.ShowChildPathsStatement;
@@ -90,6 +92,8 @@ import java.util.Objects;
 import java.util.Set;
 import java.util.stream.Collectors;
 
+import static org.apache.iotdb.commons.conf.IoTDBConstant.MULTI_LEVEL_PATH_WILDCARD;
+
 /** Analyze the statement and generate Analysis. */
 public class Analyzer {
   private static final Logger logger = LoggerFactory.getLogger(Analyzer.class);
@@ -921,6 +925,46 @@ public class Analyzer {
       return analysis;
     }
 
+    @Override
+    public Analysis visitDeleteTimeseries(
+        DeleteTimeSeriesStatement deleteTimeSeriesStatement, MPPQueryContext context) {
+      context.setQueryType(QueryType.WRITE);
+      Analysis analysis = new Analysis();
+      analysis.setStatement(deleteTimeSeriesStatement);
+
+      // fetch partition information
+
+      PathPatternTree patternTree = new PathPatternTree(deleteTimeSeriesStatement.getPaths());
+
+      SchemaPartition schemaPartitionInfo = partitionFetcher.getSchemaPartition(patternTree);
+      analysis.setSchemaPartitionInfo(schemaPartitionInfo);
+
+      Map<String, List<DataPartitionQueryParam>> sgNameToQueryParamsMap = new HashMap<>();
+      for (String storageGroup : schemaPartitionInfo.getSchemaPartitionMap().keySet()) {
+        try {
+          for (String devicePath :
+              patternTree
+                  .findOverlappedPattern(
+                      new PartialPath(storageGroup).concatNode(MULTI_LEVEL_PATH_WILDCARD))
+                  .findAllDevicePaths()) {
+            DataPartitionQueryParam queryParam = new DataPartitionQueryParam();
+            queryParam.setDevicePath(devicePath);
+            sgNameToQueryParamsMap
+                .computeIfAbsent(storageGroup, key -> new ArrayList<>())
+                .add(queryParam);
+          }
+        } catch (IllegalPathException e) {
+          // definitely won't happen
+          throw new RuntimeException(e);
+        }
+      }
+
+      DataPartition dataPartition = partitionFetcher.getDataPartition(sgNameToQueryParamsMap);
+      analysis.setDataPartitionInfo(dataPartition);
+
+      return analysis;
+    }
+
     @Override
     public Analysis visitInsertTablet(
         InsertTabletStatement insertTabletStatement, MPPQueryContext context) {
diff --git a/server/src/main/java/org/apache/iotdb/db/mpp/plan/parser/ASTVisitor.java b/server/src/main/java/org/apache/iotdb/db/mpp/plan/parser/ASTVisitor.java
index ec6a293d53..90f3fc8952 100644
--- a/server/src/main/java/org/apache/iotdb/db/mpp/plan/parser/ASTVisitor.java
+++ b/server/src/main/java/org/apache/iotdb/db/mpp/plan/parser/ASTVisitor.java
@@ -80,6 +80,7 @@ import org.apache.iotdb.db.mpp.plan.statement.metadata.CountTimeSeriesStatement;
 import org.apache.iotdb.db.mpp.plan.statement.metadata.CreateAlignedTimeSeriesStatement;
 import org.apache.iotdb.db.mpp.plan.statement.metadata.CreateTimeSeriesStatement;
 import org.apache.iotdb.db.mpp.plan.statement.metadata.DeleteStorageGroupStatement;
+import org.apache.iotdb.db.mpp.plan.statement.metadata.DeleteTimeSeriesStatement;
 import org.apache.iotdb.db.mpp.plan.statement.metadata.SetStorageGroupStatement;
 import org.apache.iotdb.db.mpp.plan.statement.metadata.SetTTLStatement;
 import org.apache.iotdb.db.mpp.plan.statement.metadata.ShowChildNodesStatement;
@@ -354,6 +355,19 @@ public class ASTVisitor extends IoTDBSqlParserBaseVisitor<Statement> {
     }
   }
 
+  // Delete Timeseries ======================================================================
+
+  @Override
+  public Statement visitDeleteTimeseries(IoTDBSqlParser.DeleteTimeseriesContext ctx) {
+    DeleteTimeSeriesStatement deleteTimeSeriesStatement = new DeleteTimeSeriesStatement();
+    List<PartialPath> partialPaths = new ArrayList<>();
+    for (IoTDBSqlParser.PrefixPathContext prefixPathContext : ctx.prefixPath()) {
+      partialPaths.add(parsePrefixPath(prefixPathContext));
+    }
+    deleteTimeSeriesStatement.setPartialPaths(partialPaths);
+    return deleteTimeSeriesStatement;
+  }
+
   // Show Timeseries ========================================================================
 
   @Override
diff --git a/server/src/main/java/org/apache/iotdb/db/mpp/plan/planner/LogicalPlanBuilder.java b/server/src/main/java/org/apache/iotdb/db/mpp/plan/planner/LogicalPlanBuilder.java
index 589685a687..126e726d7b 100644
--- a/server/src/main/java/org/apache/iotdb/db/mpp/plan/planner/LogicalPlanBuilder.java
+++ b/server/src/main/java/org/apache/iotdb/db/mpp/plan/planner/LogicalPlanBuilder.java
@@ -82,6 +82,8 @@ import java.util.Map;
 import java.util.Set;
 import java.util.stream.Collectors;
 
+import static org.apache.iotdb.commons.conf.IoTDBConstant.MULTI_LEVEL_PATH_WILDCARD;
+
 public class LogicalPlanBuilder {
 
   private PlanNode root;
@@ -542,8 +544,10 @@ public class LogicalPlanBuilder {
             new SchemaFetchScanNode(
                 context.getQueryId().genPlanNodeId(),
                 storageGroupPath,
-                patternTree.extractInvolvedPartByPrefix(storageGroupPath)));
+                patternTree.findOverlappedPattern(
+                    storageGroupPath.concatNode(MULTI_LEVEL_PATH_WILDCARD))));
       } catch (IllegalPathException e) {
+        // definitely won't happen
         throw new RuntimeException(e);
       }
     }
diff --git a/server/src/main/java/org/apache/iotdb/db/mpp/plan/planner/plan/node/PlanNodeType.java b/server/src/main/java/org/apache/iotdb/db/mpp/plan/planner/plan/node/PlanNodeType.java
index 5daa489ea9..ea86fdcef9 100644
--- a/server/src/main/java/org/apache/iotdb/db/mpp/plan/planner/plan/node/PlanNodeType.java
+++ b/server/src/main/java/org/apache/iotdb/db/mpp/plan/planner/plan/node/PlanNodeType.java
@@ -35,6 +35,8 @@ import org.apache.iotdb.db.mpp.plan.planner.plan.node.metedata.write.AlterTimeSe
 import org.apache.iotdb.db.mpp.plan.planner.plan.node.metedata.write.CreateAlignedTimeSeriesNode;
 import org.apache.iotdb.db.mpp.plan.planner.plan.node.metedata.write.CreateMultiTimeSeriesNode;
 import org.apache.iotdb.db.mpp.plan.planner.plan.node.metedata.write.CreateTimeSeriesNode;
+import org.apache.iotdb.db.mpp.plan.planner.plan.node.metedata.write.DeleteTimeSeriesNode;
+import org.apache.iotdb.db.mpp.plan.planner.plan.node.metedata.write.InvalidateSchemaCacheNode;
 import org.apache.iotdb.db.mpp.plan.planner.plan.node.process.AggregationNode;
 import org.apache.iotdb.db.mpp.plan.planner.plan.node.process.DeviceViewNode;
 import org.apache.iotdb.db.mpp.plan.planner.plan.node.process.ExchangeNode;
@@ -54,6 +56,7 @@ import org.apache.iotdb.db.mpp.plan.planner.plan.node.source.AlignedSeriesAggreg
 import org.apache.iotdb.db.mpp.plan.planner.plan.node.source.AlignedSeriesScanNode;
 import org.apache.iotdb.db.mpp.plan.planner.plan.node.source.SeriesAggregationScanNode;
 import org.apache.iotdb.db.mpp.plan.planner.plan.node.source.SeriesScanNode;
+import org.apache.iotdb.db.mpp.plan.planner.plan.node.write.DeleteDataNode;
 import org.apache.iotdb.db.mpp.plan.planner.plan.node.write.InsertMultiTabletsNode;
 import org.apache.iotdb.db.mpp.plan.planner.plan.node.write.InsertRowNode;
 import org.apache.iotdb.db.mpp.plan.planner.plan.node.write.InsertRowsNode;
@@ -107,7 +110,10 @@ public enum PlanNodeType {
   CREATE_MULTI_TIME_SERIES((short) 39),
   CHILD_PATHS_SCAN((short) 40),
   CHILD_NODES_SCAN((short) 41),
-  NODE_MANAGEMENT_MEMORY_MERGE((short) 42);
+  NODE_MANAGEMENT_MEMORY_MERGE((short) 42),
+  INVALIDATE_SCHEMA_CACHE((short) 43),
+  DELETE_DATA((short) 44),
+  DELETE_TIMESERIES((short) 45);
 
   private final short nodeType;
 
@@ -217,6 +223,12 @@ public enum PlanNodeType {
         return ChildNodesSchemaScanNode.deserialize(buffer);
       case 42:
         return NodeManagementMemoryMergeNode.deserialize(buffer);
+      case 43:
+        return InvalidateSchemaCacheNode.deserialize(buffer);
+      case 44:
+        return DeleteDataNode.deserialize(buffer);
+      case 45:
+        return DeleteTimeSeriesNode.deserialize(buffer);
       default:
         throw new IllegalArgumentException("Invalid node type: " + nodeType);
     }
diff --git a/server/src/main/java/org/apache/iotdb/db/mpp/plan/planner/plan/node/metedata/write/DeleteTimeSeriesNode.java b/server/src/main/java/org/apache/iotdb/db/mpp/plan/planner/plan/node/metedata/write/DeleteTimeSeriesNode.java
new file mode 100644
index 0000000000..98df329b1a
--- /dev/null
+++ b/server/src/main/java/org/apache/iotdb/db/mpp/plan/planner/plan/node/metedata/write/DeleteTimeSeriesNode.java
@@ -0,0 +1,100 @@
+/*
+ * 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.plan.planner.plan.node.metedata.write;
+
+import org.apache.iotdb.common.rpc.thrift.TRegionReplicaSet;
+import org.apache.iotdb.commons.path.PartialPath;
+import org.apache.iotdb.db.metadata.path.PathDeserializeUtil;
+import org.apache.iotdb.db.mpp.plan.analyze.Analysis;
+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;
+import org.apache.iotdb.db.mpp.plan.planner.plan.node.WritePlanNode;
+import org.apache.iotdb.tsfile.utils.ReadWriteIOUtils;
+
+import java.nio.ByteBuffer;
+import java.util.ArrayList;
+import java.util.List;
+
+public class DeleteTimeSeriesNode extends WritePlanNode {
+
+  private final List<PartialPath> pathList;
+
+  public DeleteTimeSeriesNode(PlanNodeId id, List<PartialPath> pathList) {
+    super(id);
+    this.pathList = pathList;
+  }
+
+  public List<PartialPath> getPathList() {
+    return pathList;
+  }
+
+  @Override
+  public List<PlanNode> getChildren() {
+    return null;
+  }
+
+  @Override
+  public void addChild(PlanNode child) {}
+
+  @Override
+  public PlanNode clone() {
+    return new DeleteTimeSeriesNode(getPlanNodeId(), pathList);
+  }
+
+  @Override
+  public int allowedChildCount() {
+    return 0;
+  }
+
+  @Override
+  public List<String> getOutputColumnNames() {
+    return null;
+  }
+
+  @Override
+  protected void serializeAttributes(ByteBuffer byteBuffer) {
+    PlanNodeType.DELETE_TIMESERIES.serialize(byteBuffer);
+    ReadWriteIOUtils.write(pathList.size(), byteBuffer);
+    for (PartialPath path : pathList) {
+      path.serialize(byteBuffer);
+    }
+  }
+
+  public static DeleteTimeSeriesNode deserialize(ByteBuffer byteBuffer) {
+    int size = ReadWriteIOUtils.readInt(byteBuffer);
+    List<PartialPath> pathList = new ArrayList<>(size);
+    for (int i = 0; i < size; i++) {
+      pathList.add((PartialPath) PathDeserializeUtil.deserialize(byteBuffer));
+    }
+    PlanNodeId planNodeId = PlanNodeId.deserialize(byteBuffer);
+    return new DeleteTimeSeriesNode(planNodeId, pathList);
+  }
+
+  @Override
+  public TRegionReplicaSet getRegionReplicaSet() {
+    return null;
+  }
+
+  @Override
+  public List<WritePlanNode> splitByPartition(Analysis analysis) {
+    return null;
+  }
+}
diff --git a/server/src/main/java/org/apache/iotdb/db/mpp/plan/planner/plan/node/metedata/write/InvalidateSchemaCacheNode.java b/server/src/main/java/org/apache/iotdb/db/mpp/plan/planner/plan/node/metedata/write/InvalidateSchemaCacheNode.java
new file mode 100644
index 0000000000..95649d8248
--- /dev/null
+++ b/server/src/main/java/org/apache/iotdb/db/mpp/plan/planner/plan/node/metedata/write/InvalidateSchemaCacheNode.java
@@ -0,0 +1,127 @@
+/*
+ * 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.plan.planner.plan.node.metedata.write;
+
+import org.apache.iotdb.common.rpc.thrift.TRegionReplicaSet;
+import org.apache.iotdb.commons.path.PartialPath;
+import org.apache.iotdb.db.metadata.path.PathDeserializeUtil;
+import org.apache.iotdb.db.mpp.common.QueryId;
+import org.apache.iotdb.db.mpp.plan.analyze.Analysis;
+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;
+import org.apache.iotdb.db.mpp.plan.planner.plan.node.WritePlanNode;
+import org.apache.iotdb.tsfile.utils.ReadWriteIOUtils;
+
+import java.nio.ByteBuffer;
+import java.util.ArrayList;
+import java.util.List;
+
+public class InvalidateSchemaCacheNode extends WritePlanNode {
+
+  private final QueryId queryId;
+
+  private final List<PartialPath> pathList;
+
+  private final List<String> storageGroups;
+
+  public InvalidateSchemaCacheNode(
+      PlanNodeId id, QueryId queryId, List<PartialPath> pathList, List<String> storageGroups) {
+    super(id);
+    this.queryId = queryId;
+    this.pathList = pathList;
+    this.storageGroups = storageGroups;
+  }
+
+  public QueryId getQueryId() {
+    return queryId;
+  }
+
+  public List<PartialPath> getPathList() {
+    return pathList;
+  }
+
+  public List<String> getStorageGroups() {
+    return storageGroups;
+  }
+
+  @Override
+  public List<PlanNode> getChildren() {
+    return null;
+  }
+
+  @Override
+  public void addChild(PlanNode child) {}
+
+  @Override
+  public PlanNode clone() {
+    return new InvalidateSchemaCacheNode(getPlanNodeId(), queryId, pathList, storageGroups);
+  }
+
+  @Override
+  public int allowedChildCount() {
+    return 0;
+  }
+
+  @Override
+  public List<String> getOutputColumnNames() {
+    return null;
+  }
+
+  @Override
+  protected void serializeAttributes(ByteBuffer byteBuffer) {
+    PlanNodeType.INVALIDATE_SCHEMA_CACHE.serialize(byteBuffer);
+    queryId.serialize(byteBuffer);
+    ReadWriteIOUtils.write(pathList.size(), byteBuffer);
+    for (PartialPath path : pathList) {
+      path.serialize(byteBuffer);
+    }
+    ReadWriteIOUtils.write(storageGroups.size(), byteBuffer);
+    for (String storageGroup : storageGroups) {
+      ReadWriteIOUtils.write(storageGroup, byteBuffer);
+    }
+  }
+
+  public static InvalidateSchemaCacheNode deserialize(ByteBuffer byteBuffer) {
+    QueryId queryId = QueryId.deserialize(byteBuffer);
+    int size = ReadWriteIOUtils.readInt(byteBuffer);
+    List<PartialPath> pathList = new ArrayList<>(size);
+    for (int i = 0; i < size; i++) {
+      pathList.add((PartialPath) PathDeserializeUtil.deserialize(byteBuffer));
+    }
+    size = ReadWriteIOUtils.readInt(byteBuffer);
+    List<String> storageGroups = new ArrayList<>(size);
+    for (int i = 0; i < size; i++) {
+      storageGroups.add(ReadWriteIOUtils.readString(byteBuffer));
+    }
+    PlanNodeId planNodeId = PlanNodeId.deserialize(byteBuffer);
+    return new InvalidateSchemaCacheNode(planNodeId, queryId, pathList, storageGroups);
+  }
+
+  @Override
+  public TRegionReplicaSet getRegionReplicaSet() {
+    return null;
+  }
+
+  @Override
+  public List<WritePlanNode> splitByPartition(Analysis analysis) {
+    return null;
+  }
+}
diff --git a/server/src/main/java/org/apache/iotdb/db/mpp/plan/planner/plan/node/write/DeleteDataNode.java b/server/src/main/java/org/apache/iotdb/db/mpp/plan/planner/plan/node/write/DeleteDataNode.java
new file mode 100644
index 0000000000..21ebfec88d
--- /dev/null
+++ b/server/src/main/java/org/apache/iotdb/db/mpp/plan/planner/plan/node/write/DeleteDataNode.java
@@ -0,0 +1,100 @@
+/*
+ * 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.plan.planner.plan.node.write;
+
+import org.apache.iotdb.common.rpc.thrift.TRegionReplicaSet;
+import org.apache.iotdb.commons.path.PartialPath;
+import org.apache.iotdb.db.metadata.path.PathDeserializeUtil;
+import org.apache.iotdb.db.mpp.plan.analyze.Analysis;
+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;
+import org.apache.iotdb.db.mpp.plan.planner.plan.node.WritePlanNode;
+import org.apache.iotdb.tsfile.utils.ReadWriteIOUtils;
+
+import java.nio.ByteBuffer;
+import java.util.ArrayList;
+import java.util.List;
+
+public class DeleteDataNode extends WritePlanNode {
+
+  private final List<PartialPath> pathList;
+
+  public DeleteDataNode(PlanNodeId id, List<PartialPath> pathList) {
+    super(id);
+    this.pathList = pathList;
+  }
+
+  public List<PartialPath> getPathList() {
+    return pathList;
+  }
+
+  @Override
+  public List<PlanNode> getChildren() {
+    return null;
+  }
+
+  @Override
+  public void addChild(PlanNode child) {}
+
+  @Override
+  public PlanNode clone() {
+    return new DeleteDataNode(getPlanNodeId(), pathList);
+  }
+
+  @Override
+  public int allowedChildCount() {
+    return 0;
+  }
+
+  @Override
+  public List<String> getOutputColumnNames() {
+    return null;
+  }
+
+  @Override
+  protected void serializeAttributes(ByteBuffer byteBuffer) {
+    PlanNodeType.DELETE_DATA.serialize(byteBuffer);
+    ReadWriteIOUtils.write(pathList.size(), byteBuffer);
+    for (PartialPath path : pathList) {
+      path.serialize(byteBuffer);
+    }
+  }
+
+  public static DeleteDataNode deserialize(ByteBuffer buffer) {
+    int size = ReadWriteIOUtils.readInt(buffer);
+    List<PartialPath> pathList = new ArrayList<>(size);
+    for (int i = 0; i < size; i++) {
+      pathList.add((PartialPath) PathDeserializeUtil.deserialize(buffer));
+    }
+    PlanNodeId planNodeId = PlanNodeId.deserialize(buffer);
+    return new DeleteDataNode(planNodeId, pathList);
+  }
+
+  @Override
+  public TRegionReplicaSet getRegionReplicaSet() {
+    return null;
+  }
+
+  @Override
+  public List<WritePlanNode> splitByPartition(Analysis analysis) {
+    return null;
+  }
+}
diff --git a/server/src/main/java/org/apache/iotdb/db/mpp/plan/statement/StatementVisitor.java b/server/src/main/java/org/apache/iotdb/db/mpp/plan/statement/StatementVisitor.java
index 86daaafcc3..b8ceb59787 100644
--- a/server/src/main/java/org/apache/iotdb/db/mpp/plan/statement/StatementVisitor.java
+++ b/server/src/main/java/org/apache/iotdb/db/mpp/plan/statement/StatementVisitor.java
@@ -35,6 +35,7 @@ import org.apache.iotdb.db.mpp.plan.statement.metadata.CreateAlignedTimeSeriesSt
 import org.apache.iotdb.db.mpp.plan.statement.metadata.CreateMultiTimeSeriesStatement;
 import org.apache.iotdb.db.mpp.plan.statement.metadata.CreateTimeSeriesStatement;
 import org.apache.iotdb.db.mpp.plan.statement.metadata.DeleteStorageGroupStatement;
+import org.apache.iotdb.db.mpp.plan.statement.metadata.DeleteTimeSeriesStatement;
 import org.apache.iotdb.db.mpp.plan.statement.metadata.SchemaFetchStatement;
 import org.apache.iotdb.db.mpp.plan.statement.metadata.SetStorageGroupStatement;
 import org.apache.iotdb.db.mpp.plan.statement.metadata.SetTTLStatement;
@@ -92,6 +93,10 @@ public abstract class StatementVisitor<R, C> {
     return visitStatement(alterTimeSeriesStatement, context);
   }
 
+  public R visitDeleteTimeseries(DeleteTimeSeriesStatement deleteTimeSeriesStatement, C context) {
+    return visitStatement(deleteTimeSeriesStatement, context);
+  }
+
   public R visitDeleteStorageGroup(
       DeleteStorageGroupStatement deleteStorageGroupStatement, C context) {
     return visitStatement(deleteStorageGroupStatement, context);
diff --git a/server/src/main/java/org/apache/iotdb/db/mpp/plan/statement/metadata/DeleteTimeSeriesStatement.java b/server/src/main/java/org/apache/iotdb/db/mpp/plan/statement/metadata/DeleteTimeSeriesStatement.java
new file mode 100644
index 0000000000..edcccd58e0
--- /dev/null
+++ b/server/src/main/java/org/apache/iotdb/db/mpp/plan/statement/metadata/DeleteTimeSeriesStatement.java
@@ -0,0 +1,45 @@
+/*
+ * 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.plan.statement.metadata;
+
+import org.apache.iotdb.commons.path.PartialPath;
+import org.apache.iotdb.db.mpp.plan.statement.Statement;
+import org.apache.iotdb.db.mpp.plan.statement.StatementVisitor;
+
+import java.util.List;
+
+public class DeleteTimeSeriesStatement extends Statement {
+
+  List<PartialPath> partialPaths;
+
+  @Override
+  public List<PartialPath> getPaths() {
+    return null;
+  }
+
+  public void setPartialPaths(List<PartialPath> partialPaths) {
+    this.partialPaths = partialPaths;
+  }
+
+  @Override
+  public <R, C> R accept(StatementVisitor<R, C> visitor, C context) {
+    return visitor.visitDeleteTimeseries(this, context);
+  }
+}
diff --git a/server/src/test/java/org/apache/iotdb/db/mpp/plan/plan/node/metadata/write/DeleteTimeSeriesNodeSerdeTest.java b/server/src/test/java/org/apache/iotdb/db/mpp/plan/plan/node/metadata/write/DeleteTimeSeriesNodeSerdeTest.java
new file mode 100644
index 0000000000..4cc69bd672
--- /dev/null
+++ b/server/src/test/java/org/apache/iotdb/db/mpp/plan/plan/node/metadata/write/DeleteTimeSeriesNodeSerdeTest.java
@@ -0,0 +1,61 @@
+/*
+ * 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.plan.plan.node.metadata.write;
+
+import org.apache.iotdb.commons.exception.IllegalPathException;
+import org.apache.iotdb.commons.path.PartialPath;
+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;
+import org.apache.iotdb.db.mpp.plan.planner.plan.node.metedata.write.DeleteTimeSeriesNode;
+
+import org.junit.Assert;
+import org.junit.Test;
+
+import java.nio.ByteBuffer;
+import java.util.ArrayList;
+import java.util.List;
+
+public class DeleteTimeSeriesNodeSerdeTest {
+
+  @Test
+  public void testSerializeAndDeserialize() throws IllegalPathException {
+    PlanNodeId planNodeId = new PlanNodeId("DeleteTimeSeriesNode");
+    List<PartialPath> pathList = new ArrayList<>();
+    pathList.add(new PartialPath("root.sg.d1.s1"));
+    pathList.add(new PartialPath("root.sg.d2.*"));
+    DeleteTimeSeriesNode deleteTimeSeriesNode = new DeleteTimeSeriesNode(planNodeId, pathList);
+
+    ByteBuffer byteBuffer = ByteBuffer.allocate(1024);
+    deleteTimeSeriesNode.serialize(byteBuffer);
+    byteBuffer.flip();
+
+    PlanNode deserializedNode = PlanNodeType.deserialize(byteBuffer);
+    Assert.assertTrue(deserializedNode instanceof DeleteTimeSeriesNode);
+    Assert.assertEquals(planNodeId, deserializedNode.getPlanNodeId());
+
+    deleteTimeSeriesNode = (DeleteTimeSeriesNode) deserializedNode;
+    List<PartialPath> deserializedPathList = deleteTimeSeriesNode.getPathList();
+    Assert.assertEquals(pathList.size(), deserializedPathList.size());
+    for (int i = 0; i < pathList.size(); i++) {
+      Assert.assertEquals(pathList.get(i), deserializedPathList.get(i));
+    }
+  }
+}
diff --git a/server/src/test/java/org/apache/iotdb/db/mpp/plan/plan/node/write/DeleteDataNodeSerdeTest.java b/server/src/test/java/org/apache/iotdb/db/mpp/plan/plan/node/write/DeleteDataNodeSerdeTest.java
new file mode 100644
index 0000000000..5dbde28d3d
--- /dev/null
+++ b/server/src/test/java/org/apache/iotdb/db/mpp/plan/plan/node/write/DeleteDataNodeSerdeTest.java
@@ -0,0 +1,61 @@
+/*
+ * 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.plan.plan.node.write;
+
+import org.apache.iotdb.commons.exception.IllegalPathException;
+import org.apache.iotdb.commons.path.PartialPath;
+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;
+import org.apache.iotdb.db.mpp.plan.planner.plan.node.write.DeleteDataNode;
+
+import org.junit.Assert;
+import org.junit.Test;
+
+import java.nio.ByteBuffer;
+import java.util.ArrayList;
+import java.util.List;
+
+public class DeleteDataNodeSerdeTest {
+
+  @Test
+  public void testSerializeAndDeserialize() throws IllegalPathException {
+    PlanNodeId planNodeId = new PlanNodeId("DeleteDataNode");
+    List<PartialPath> pathList = new ArrayList<>();
+    pathList.add(new PartialPath("root.sg.d1.s1"));
+    pathList.add(new PartialPath("root.sg.d2.*"));
+    DeleteDataNode deleteDataNode = new DeleteDataNode(planNodeId, pathList);
+
+    ByteBuffer byteBuffer = ByteBuffer.allocate(1024);
+    deleteDataNode.serialize(byteBuffer);
+    byteBuffer.flip();
+
+    PlanNode deserializedNode = PlanNodeType.deserialize(byteBuffer);
+    Assert.assertTrue(deserializedNode instanceof DeleteDataNode);
+    Assert.assertEquals(planNodeId, deserializedNode.getPlanNodeId());
+
+    deleteDataNode = (DeleteDataNode) deserializedNode;
+    List<PartialPath> deserializedPathList = deleteDataNode.getPathList();
+    Assert.assertEquals(pathList.size(), deserializedPathList.size());
+    for (int i = 0; i < pathList.size(); i++) {
+      Assert.assertEquals(pathList.get(i), deserializedPathList.get(i));
+    }
+  }
+}
diff --git a/server/src/test/java/org/apache/iotdb/db/mpp/plan/plan/node/write/InvalidateSchemaCacheNodeSerdeTest.java b/server/src/test/java/org/apache/iotdb/db/mpp/plan/plan/node/write/InvalidateSchemaCacheNodeSerdeTest.java
new file mode 100644
index 0000000000..537dff95e0
--- /dev/null
+++ b/server/src/test/java/org/apache/iotdb/db/mpp/plan/plan/node/write/InvalidateSchemaCacheNodeSerdeTest.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.plan.plan.node.write;
+
+import org.apache.iotdb.commons.exception.IllegalPathException;
+import org.apache.iotdb.commons.path.PartialPath;
+import org.apache.iotdb.db.mpp.common.QueryId;
+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;
+import org.apache.iotdb.db.mpp.plan.planner.plan.node.metedata.write.InvalidateSchemaCacheNode;
+
+import org.junit.Assert;
+import org.junit.Test;
+
+import java.nio.ByteBuffer;
+import java.util.ArrayList;
+import java.util.List;
+
+public class InvalidateSchemaCacheNodeSerdeTest {
+
+  @Test
+  public void testSerializeAndDeserialize() throws IllegalPathException {
+    PlanNodeId planNodeId = new PlanNodeId("InvalidateSchemaCacheNode");
+    QueryId queryId = new QueryId("query");
+    List<PartialPath> pathList = new ArrayList<>();
+    pathList.add(new PartialPath("root.sg.d1.s1"));
+    pathList.add(new PartialPath("root.sg.d2.*"));
+    List<String> storageGroups = new ArrayList<>();
+    storageGroups.add("root.sg1");
+    storageGroups.add("root.sg2");
+    InvalidateSchemaCacheNode invalidateSchemaCacheNode =
+        new InvalidateSchemaCacheNode(planNodeId, queryId, pathList, storageGroups);
+
+    ByteBuffer byteBuffer = ByteBuffer.allocate(1024);
+    invalidateSchemaCacheNode.serialize(byteBuffer);
+    byteBuffer.flip();
+
+    PlanNode deserializedNode = PlanNodeType.deserialize(byteBuffer);
+    Assert.assertTrue(deserializedNode instanceof InvalidateSchemaCacheNode);
+    Assert.assertEquals(planNodeId, deserializedNode.getPlanNodeId());
+
+    invalidateSchemaCacheNode = (InvalidateSchemaCacheNode) deserializedNode;
+
+    Assert.assertEquals(queryId, invalidateSchemaCacheNode.getQueryId());
+
+    List<PartialPath> deserializedPathList = invalidateSchemaCacheNode.getPathList();
+    Assert.assertEquals(pathList.size(), deserializedPathList.size());
+    for (int i = 0; i < pathList.size(); i++) {
+      Assert.assertEquals(pathList.get(i), deserializedPathList.get(i));
+    }
+
+    List<String> deserializedStorageGroups = invalidateSchemaCacheNode.getStorageGroups();
+    Assert.assertEquals(storageGroups.size(), deserializedStorageGroups.size());
+    for (int i = 0; i < storageGroups.size(); i++) {
+      Assert.assertEquals(storageGroups.get(i), deserializedStorageGroups.get(i));
+    }
+  }
+}