You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@iotdb.apache.org by xu...@apache.org on 2022/01/18 03:25:00 UTC

[iotdb] branch master updated: Enable display and deletion of schema templates (#4862)

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

xuekaifeng 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 4519150  Enable display and deletion of schema templates (#4862)
4519150 is described below

commit 451915010087cc14c89c8af3c7837031c14a3faa
Author: ZhaoXin <x_...@163.com>
AuthorDate: Tue Jan 18 11:24:16 2022 +0800

    Enable display and deletion of schema templates (#4862)
    
    * add interface to show and drop schema template
    
    * encapsulate MNode manipulation inside MTree, update docs, change-list
    
    * move synchorinzed decorator to inner layer
    
    * remove synchronized decorator for dropping template
    
    * merge master and format code
---
 docs/UserGuide/API/Programming-Java-Native-API.md  |  25 +++-
 .../UserGuide/API/Programming-Java-Native-API.md   |  19 ++-
 .../org/apache/iotdb/db/metadata/MManager.java     |  54 +++++++++
 .../iotdb/db/metadata/logfile/MLogTxtWriter.java   |  24 ++++
 .../iotdb/db/metadata/logfile/MLogWriter.java      |   5 +
 .../db/metadata/logfile/MetadataOperationType.java |   2 +
 .../org/apache/iotdb/db/metadata/mtree/MTree.java  | 105 +++++++++++++++-
 .../db/metadata/template/TemplateManager.java      |  10 ++
 .../db/metadata/template/TemplateQueryType.java    |   5 +-
 .../apache/iotdb/db/qp/executor/PlanExecutor.java  |  12 ++
 .../org/apache/iotdb/db/qp/logical/Operator.java   |   3 +-
 .../apache/iotdb/db/qp/physical/PhysicalPlan.java  |  11 +-
 .../iotdb/db/qp/physical/sys/DropTemplatePlan.java |  78 ++++++++++++
 .../db/service/thrift/impl/TSServiceImpl.java      |  36 +++++-
 .../org/apache/iotdb/db/tools/mlog/MLogParser.java |   8 ++
 .../org/apache/iotdb/db/metadata/TemplateTest.java | 135 ++++++++++++++++++++-
 .../java/org/apache/iotdb/session/Session.java     |  43 +++++++
 .../apache/iotdb/session/SessionConnection.java    |  20 +++
 .../org/apache/iotdb/session/pool/SessionPool.java |  97 +++++++++++++++
 .../iotdb/session/template/TemplateQueryType.java  |   5 +-
 .../apache/iotdb/session/template/TemplateUT.java  | 131 ++++++++++++++++++++
 thrift/rpc-changelist.md                           |   3 +-
 thrift/src/main/thrift/rpc.thrift                  |   7 ++
 23 files changed, 823 insertions(+), 15 deletions(-)

diff --git a/docs/UserGuide/API/Programming-Java-Native-API.md b/docs/UserGuide/API/Programming-Java-Native-API.md
index 121b121..e0c731b 100644
--- a/docs/UserGuide/API/Programming-Java-Native-API.md
+++ b/docs/UserGuide/API/Programming-Java-Native-API.md
@@ -266,7 +266,7 @@ public void addUnalignedMeasurementsIntemplate(String templateName,
 public void deleteNodeInTemplate(String templateName, String path);
 ```
 
-You can query measurement templates with these APIS:
+You can query measurement inside templates with these APIS:
 
 ```java
 // Return the amount of measurements inside a template
@@ -285,7 +285,7 @@ public List<String> showMeasurementsInTemplate(String templateName);
 public List<String> showMeasurementsInTemplate(String templateName, String pattern);
 ```
 
-Set the measurement template named 'templateName' at path 'prefixPath'.
+To implement schema template, you can  set the measurement template named 'templateName' at path 'prefixPath'.
 
 ``` java
 void setSchemaTemplate(String templateName, String prefixPath)
@@ -296,11 +296,28 @@ Before setting template, you should firstly create the template using
 ```java
 void createSchemaTemplate(Template template)
 ```
+
+After setting template to a certain path, you can query for info about template using belowed interface in session:
+
+```java
+/** @return All template names. */
+public List<String> showAllTemplates();
+
+/** @return All paths have been set to designated template. */
+public List<String> showPathsTemplateSetOn(String templateName);
+
+/** @return All paths are using designated template. */
+public List<String> showPathsTemplateUsingOn(String templateName)
+```
+
+If you are ready to get rid of schema template, you can drop it with belowed interface. Make sure the template to drop has been unset from MTree.
+
 ```java
-void unsetSchemaTemplate(String prefixPath, String templateName)
+void unsetSchemaTemplate(String prefixPath, String templateName);
+public void dropSchemaTemplate(String templateName);
 ```
 
-Unset the measurement template named 'templateName' from path 'prefixPath'. You should ensure that there is a template named 'templateName' set at the path 'prefixPath'.
+Unset the measurement template named 'templateName' from path 'prefixPath'. When you issue this interface, you should assure that there is a template named 'templateName' set at the path 'prefixPath'.
 
 Attention: Unsetting the template named 'templateName' from node at path 'prefixPath' or descendant nodes which have already inserted records using template is **not supported**.
 
diff --git a/docs/zh/UserGuide/API/Programming-Java-Native-API.md b/docs/zh/UserGuide/API/Programming-Java-Native-API.md
index 0c67cd4..8d47447 100644
--- a/docs/zh/UserGuide/API/Programming-Java-Native-API.md
+++ b/docs/zh/UserGuide/API/Programming-Java-Native-API.md
@@ -270,8 +270,25 @@ public List<String> showMeasurementsInTemplate(String templateName, String patte
 void setSchemaTemplate(String templateName, String prefixPath)
 ```
 
+- 将模板挂载到 MTree 上之后,你可以随时查询所有模板的名称、某模板被设置到 MTree 的所有路径、所有正在使用某模板的所有路径,即如下接口:
+
+```java
+/** @return All template names. */
+public List<String> showAllTemplates();
+
+/** @return All paths have been set to designated template. */
+public List<String> showPathsTemplateSetOn(String templateName);
+
+/** @return All paths are using designated template. */
+public List<String> showPathsTemplateUsingOn(String templateName)
+```
+
+- 如果你需要删除某一个模板,请确保在进行删除之前,MTree 上已经没有节点被挂载了模板,对于已经被挂载模板的节点,可以用如下接口卸载模板;
+
+
 ``` java
-void unsetSchemaTemplate(String prefixPath, String templateName)
+void unsetSchemaTemplate(String prefixPath, String templateName);
+public void dropSchemaTemplate(String templateName);
 ```
 
 * 请注意,如果一个子树中有多个孩子节点需要使用模板,可以在其共同父母节点上使用 setSchemaTemplate 。而只有在已有数据点插入模板对应的物理量时,模板才会被设置为激活状态,进而被 show timeseries 等查询检测到。
diff --git a/server/src/main/java/org/apache/iotdb/db/metadata/MManager.java b/server/src/main/java/org/apache/iotdb/db/metadata/MManager.java
index be4480c..d8287c3 100644
--- a/server/src/main/java/org/apache/iotdb/db/metadata/MManager.java
+++ b/server/src/main/java/org/apache/iotdb/db/metadata/MManager.java
@@ -73,6 +73,7 @@ import org.apache.iotdb.db.qp.physical.sys.CreateTimeSeriesPlan;
 import org.apache.iotdb.db.qp.physical.sys.DeleteStorageGroupPlan;
 import org.apache.iotdb.db.qp.physical.sys.DeleteTimeSeriesPlan;
 import org.apache.iotdb.db.qp.physical.sys.DropContinuousQueryPlan;
+import org.apache.iotdb.db.qp.physical.sys.DropTemplatePlan;
 import org.apache.iotdb.db.qp.physical.sys.PruneTemplatePlan;
 import org.apache.iotdb.db.qp.physical.sys.SetStorageGroupPlan;
 import org.apache.iotdb.db.qp.physical.sys.SetTTLPlan;
@@ -483,6 +484,18 @@ public class MManager {
         CreateTemplatePlan createTemplatePlan = (CreateTemplatePlan) plan;
         createSchemaTemplate(createTemplatePlan);
         break;
+      case DROP_TEMPLATE:
+        DropTemplatePlan dropTemplatePlan = (DropTemplatePlan) plan;
+        dropSchemaTemplate(dropTemplatePlan);
+        break;
+      case APPEND_TEMPLATE:
+        AppendTemplatePlan appendTemplatePlan = (AppendTemplatePlan) plan;
+        appendSchemaTemplate(appendTemplatePlan);
+        break;
+      case PRUNE_TEMPLATE:
+        PruneTemplatePlan pruneTemplatePlan = (PruneTemplatePlan) plan;
+        pruneSchemaTemplate(pruneTemplatePlan);
+        break;
       case SET_TEMPLATE:
         SetTemplatePlan setTemplatePlan = (SetTemplatePlan) plan;
         setSchemaTemplate(setTemplatePlan);
@@ -2233,6 +2246,47 @@ public class MManager {
     return templateManager.getTemplate(templateName).getMeasurementsUnderPath(path);
   }
 
+  public Set<String> getAllTemplates() {
+    return templateManager.getAllTemplateName();
+  }
+
+  /**
+   * Get all paths set designated template
+   *
+   * @param templateName designated template name, blank string for any template exists
+   * @return paths set
+   */
+  public Set<String> getPathsSetTemplate(String templateName) throws MetadataException {
+    return new HashSet<>(mtree.getPathsSetOnTemplate(templateName));
+  }
+
+  public Set<String> getPathsUsingTemplate(String templateName) throws MetadataException {
+    return new HashSet<>(mtree.getPathsUsingTemplate(templateName));
+  }
+
+  public void dropSchemaTemplate(DropTemplatePlan plan) throws MetadataException {
+    try {
+      String templateName = plan.getName();
+      // check whether template exists
+      if (!templateManager.getAllTemplateName().contains(templateName)) {
+        throw new UndefinedTemplateException(templateName);
+      }
+
+      if (mtree.isTemplateSetOnMTree(templateName)) {
+        throw new MetadataException(
+            String.format(
+                "Template [%s] has been set on MTree, cannot be dropped now.", templateName));
+      }
+
+      templateManager.dropSchemaTemplate(plan);
+      if (!isRecovering) {
+        logWriter.dropSchemaTemplate(plan);
+      }
+    } catch (IOException e) {
+      throw new MetadataException(e);
+    }
+  }
+
   public synchronized void setSchemaTemplate(SetTemplatePlan plan) throws MetadataException {
     // get mnode and update template should be atomic
     Template template = templateManager.getTemplate(plan.getTemplateName());
diff --git a/server/src/main/java/org/apache/iotdb/db/metadata/logfile/MLogTxtWriter.java b/server/src/main/java/org/apache/iotdb/db/metadata/logfile/MLogTxtWriter.java
index a6a6ecc..265f6f3 100644
--- a/server/src/main/java/org/apache/iotdb/db/metadata/logfile/MLogTxtWriter.java
+++ b/server/src/main/java/org/apache/iotdb/db/metadata/logfile/MLogTxtWriter.java
@@ -27,11 +27,13 @@ import org.apache.iotdb.db.qp.physical.sys.CreateContinuousQueryPlan;
 import org.apache.iotdb.db.qp.physical.sys.CreateTemplatePlan;
 import org.apache.iotdb.db.qp.physical.sys.CreateTimeSeriesPlan;
 import org.apache.iotdb.db.qp.physical.sys.DropContinuousQueryPlan;
+import org.apache.iotdb.db.qp.physical.sys.DropTemplatePlan;
 import org.apache.iotdb.db.qp.physical.sys.MNodePlan;
 import org.apache.iotdb.db.qp.physical.sys.MeasurementMNodePlan;
 import org.apache.iotdb.db.qp.physical.sys.PruneTemplatePlan;
 import org.apache.iotdb.db.qp.physical.sys.SetTemplatePlan;
 import org.apache.iotdb.db.qp.physical.sys.StorageGroupMNodePlan;
+import org.apache.iotdb.db.qp.physical.sys.UnsetTemplatePlan;
 import org.apache.iotdb.tsfile.file.metadata.enums.CompressionType;
 import org.apache.iotdb.tsfile.file.metadata.enums.TSDataType;
 import org.apache.iotdb.tsfile.file.metadata.enums.TSEncoding;
@@ -332,6 +334,28 @@ public class MLogTxtWriter implements AutoCloseable {
     lineNumber.incrementAndGet();
   }
 
+  public void unsetTemplate(UnsetTemplatePlan plan) throws IOException {
+    StringBuilder buf = new StringBuilder(String.valueOf(MetadataOperationType.UNSET_TEMPLATE));
+    buf.append(",");
+    buf.append(plan.getTemplateName());
+    buf.append(",");
+    buf.append(plan.getPrefixPath());
+    buf.append(LINE_SEPARATOR);
+    ByteBuffer buff = ByteBuffer.wrap(buf.toString().getBytes());
+    channel.write(buff);
+    lineNumber.incrementAndGet();
+  }
+
+  public void dropTemplate(DropTemplatePlan plan) throws IOException {
+    StringBuilder buf = new StringBuilder(String.valueOf(MetadataOperationType.DROP_TEMPLATE));
+    buf.append(",");
+    buf.append(plan.getName());
+    buf.append(LINE_SEPARATOR);
+    ByteBuffer buff = ByteBuffer.wrap(buf.toString().getBytes());
+    channel.write(buff);
+    lineNumber.incrementAndGet();
+  }
+
   public void setUsingTemplate(ActivateTemplatePlan plan) throws IOException {
     StringBuilder buf = new StringBuilder(String.valueOf(MetadataOperationType.SET_USING_TEMPLATE));
     buf.append(",");
diff --git a/server/src/main/java/org/apache/iotdb/db/metadata/logfile/MLogWriter.java b/server/src/main/java/org/apache/iotdb/db/metadata/logfile/MLogWriter.java
index 2f1c8f9..303322d 100644
--- a/server/src/main/java/org/apache/iotdb/db/metadata/logfile/MLogWriter.java
+++ b/server/src/main/java/org/apache/iotdb/db/metadata/logfile/MLogWriter.java
@@ -37,6 +37,7 @@ import org.apache.iotdb.db.qp.physical.sys.CreateTimeSeriesPlan;
 import org.apache.iotdb.db.qp.physical.sys.DeleteStorageGroupPlan;
 import org.apache.iotdb.db.qp.physical.sys.DeleteTimeSeriesPlan;
 import org.apache.iotdb.db.qp.physical.sys.DropContinuousQueryPlan;
+import org.apache.iotdb.db.qp.physical.sys.DropTemplatePlan;
 import org.apache.iotdb.db.qp.physical.sys.MNodePlan;
 import org.apache.iotdb.db.qp.physical.sys.MeasurementMNodePlan;
 import org.apache.iotdb.db.qp.physical.sys.PruneTemplatePlan;
@@ -187,6 +188,10 @@ public class MLogWriter implements AutoCloseable {
     putLog(plan);
   }
 
+  public void dropSchemaTemplate(DropTemplatePlan plan) throws IOException {
+    putLog(plan);
+  }
+
   public void autoCreateDeviceMNode(AutoCreateDeviceMNodePlan plan) throws IOException {
     putLog(plan);
   }
diff --git a/server/src/main/java/org/apache/iotdb/db/metadata/logfile/MetadataOperationType.java b/server/src/main/java/org/apache/iotdb/db/metadata/logfile/MetadataOperationType.java
index 977259d..672a4ec 100644
--- a/server/src/main/java/org/apache/iotdb/db/metadata/logfile/MetadataOperationType.java
+++ b/server/src/main/java/org/apache/iotdb/db/metadata/logfile/MetadataOperationType.java
@@ -40,7 +40,9 @@ public class MetadataOperationType {
   public static final String AUTO_CREATE_DEVICE = "4";
   public static final String CREATE_TEMPLATE = "5";
   public static final String SET_TEMPLATE = "6";
+  public static final String UNSET_TEMPLATE = "69";
   public static final String SET_USING_TEMPLATE = "61";
   public static final String APPEND_TEMPLATE = "51";
   public static final String PRUNE_TEMPLATE = "52";
+  public static final String DROP_TEMPLATE = "59";
 }
diff --git a/server/src/main/java/org/apache/iotdb/db/metadata/mtree/MTree.java b/server/src/main/java/org/apache/iotdb/db/metadata/mtree/MTree.java
index 91ebe52..bddc4cf 100644
--- a/server/src/main/java/org/apache/iotdb/db/metadata/mtree/MTree.java
+++ b/server/src/main/java/org/apache/iotdb/db/metadata/mtree/MTree.java
@@ -44,6 +44,7 @@ import org.apache.iotdb.db.metadata.mnode.InternalMNode;
 import org.apache.iotdb.db.metadata.mnode.MNodeUtils;
 import org.apache.iotdb.db.metadata.mnode.MeasurementMNode;
 import org.apache.iotdb.db.metadata.mnode.StorageGroupMNode;
+import org.apache.iotdb.db.metadata.mtree.traverser.collector.CollectorTraverser;
 import org.apache.iotdb.db.metadata.mtree.traverser.collector.EntityCollector;
 import org.apache.iotdb.db.metadata.mtree.traverser.collector.MNodeCollector;
 import org.apache.iotdb.db.metadata.mtree.traverser.collector.MeasurementCollector;
@@ -104,6 +105,7 @@ import java.util.concurrent.ConcurrentHashMap;
 import java.util.stream.Stream;
 
 import static java.util.stream.Collectors.toList;
+import static org.apache.iotdb.db.conf.IoTDBConstant.MULTI_LEVEL_PATH_WILDCARD;
 import static org.apache.iotdb.db.conf.IoTDBConstant.ONE_LEVEL_PATH_WILDCARD;
 import static org.apache.iotdb.db.metadata.lastCache.LastCacheManager.getLastTimeStamp;
 
@@ -1518,7 +1520,7 @@ public class MTree implements Serializable {
 
   // endregion
 
-  // region Interfaces and Implementation for Template check
+  // region Interfaces and Implementation for Template check and query
   /**
    * check whether there is template on given path and the subTree has template return true,
    * otherwise false
@@ -1715,6 +1717,107 @@ public class MTree implements Serializable {
     return fullPathNodes.length - 1;
   }
 
+  public List<String> getPathsSetOnTemplate(String templateName) throws MetadataException {
+    List<String> resSet = new ArrayList<>();
+    CollectorTraverser<Set<String>> setTemplatePaths =
+        new CollectorTraverser<Set<String>>(
+            root, root.getPartialPath().concatNode(MULTI_LEVEL_PATH_WILDCARD)) {
+          @Override
+          protected boolean processInternalMatchedMNode(IMNode node, int idx, int level)
+              throws MetadataException {
+            // will never get here, implement for placeholder
+            return false;
+          }
+
+          @Override
+          protected boolean processFullMatchedMNode(IMNode node, int idx, int level)
+              throws MetadataException {
+            // shall not traverse nodes inside template
+            if (!node.getPartialPath().equals(getCurrentPartialPath(node))) {
+              return true;
+            }
+
+            // if node not set template, go on traversing
+            if (node.getUpperTemplate() != null) {
+              // if set template, and equals to target or target for all, add to result
+              if (templateName.equals("")
+                  || templateName.equals(node.getUpperTemplate().getName())) {
+                resSet.add(node.getFullPath());
+              }
+              // descendants of the node cannot set another template, exit from this branch
+              return true;
+            }
+            return false;
+          }
+        };
+    setTemplatePaths.traverse();
+    return resSet;
+  }
+
+  public List<String> getPathsUsingTemplate(String templateName) throws MetadataException {
+    List<String> result = new ArrayList<>();
+
+    CollectorTraverser<Set<String>> usingTemplatePaths =
+        new CollectorTraverser<Set<String>>(
+            root, root.getPartialPath().concatNode(MULTI_LEVEL_PATH_WILDCARD)) {
+          @Override
+          protected boolean processInternalMatchedMNode(IMNode node, int idx, int level)
+              throws MetadataException {
+            // will never get here, implement for placeholder
+            return false;
+          }
+
+          @Override
+          protected boolean processFullMatchedMNode(IMNode node, int idx, int level)
+              throws MetadataException {
+            // shall not traverse nodes inside template
+            if (!node.getPartialPath().equals(getCurrentPartialPath(node))) {
+              return true;
+            }
+
+            if (node.getUpperTemplate() != null) {
+              // this node and its descendants are set other template, exit from this branch
+              if (!templateName.equals("")
+                  && !templateName.equals(node.getUpperTemplate().getName())) {
+                return true;
+              }
+
+              // descendants of this node may be using template too
+              if (node.isUseTemplate()) {
+                result.add(node.getFullPath());
+              }
+            }
+            return false;
+          }
+        };
+
+    usingTemplatePaths.traverse();
+    return result;
+  }
+
+  public boolean isTemplateSetOnMTree(String templateName) {
+    // check whether template has been set
+    Deque<IMNode> nodeStack = new ArrayDeque<>();
+    nodeStack.push(root);
+
+    // DFT traverse on MTree
+    while (nodeStack.size() != 0) {
+      IMNode curNode = nodeStack.pop();
+      if (curNode.getUpperTemplate() != null) {
+        if (curNode.getUpperTemplate().getName().equals(templateName)) {
+          return true;
+        }
+        // curNode set to other templates, cut this branch
+      }
+
+      // no template on curNode, push children to stack
+      for (IMNode child : curNode.getChildren().values()) {
+        nodeStack.push(child);
+      }
+    }
+    return false;
+  }
+
   // endregion
 
   // region TestOnly Interface
diff --git a/server/src/main/java/org/apache/iotdb/db/metadata/template/TemplateManager.java b/server/src/main/java/org/apache/iotdb/db/metadata/template/TemplateManager.java
index 512c27d..3cfc2c1 100644
--- a/server/src/main/java/org/apache/iotdb/db/metadata/template/TemplateManager.java
+++ b/server/src/main/java/org/apache/iotdb/db/metadata/template/TemplateManager.java
@@ -27,6 +27,7 @@ import org.apache.iotdb.db.metadata.utils.MetaFormatUtils;
 import org.apache.iotdb.db.metadata.utils.MetaUtils;
 import org.apache.iotdb.db.qp.physical.sys.AppendTemplatePlan;
 import org.apache.iotdb.db.qp.physical.sys.CreateTemplatePlan;
+import org.apache.iotdb.db.qp.physical.sys.DropTemplatePlan;
 import org.apache.iotdb.db.qp.physical.sys.PruneTemplatePlan;
 import org.apache.iotdb.db.utils.TestOnly;
 import org.apache.iotdb.tsfile.file.metadata.enums.CompressionType;
@@ -35,6 +36,7 @@ import org.apache.iotdb.tsfile.file.metadata.enums.TSEncoding;
 
 import java.util.List;
 import java.util.Map;
+import java.util.Set;
 import java.util.concurrent.ConcurrentHashMap;
 
 public class TemplateManager {
@@ -83,6 +85,10 @@ public class TemplateManager {
     }
   }
 
+  public void dropSchemaTemplate(DropTemplatePlan plan) {
+    templateMap.remove(plan.getName());
+  }
+
   public void appendSchemaTemplate(AppendTemplatePlan plan) throws MetadataException {
     String templateName = plan.getName();
     Template temp = templateMap.getOrDefault(templateName, null);
@@ -139,6 +145,10 @@ public class TemplateManager {
     return templateMap;
   }
 
+  public Set<String> getAllTemplateName() {
+    return templateMap.keySet();
+  }
+
   public void checkIsTemplateAndMNodeCompatible(Template template, IMNode node)
       throws MetadataException {
     if (node.getSchemaTemplate() != null) {
diff --git a/server/src/main/java/org/apache/iotdb/db/metadata/template/TemplateQueryType.java b/server/src/main/java/org/apache/iotdb/db/metadata/template/TemplateQueryType.java
index a5cf733..ebac103 100644
--- a/server/src/main/java/org/apache/iotdb/db/metadata/template/TemplateQueryType.java
+++ b/server/src/main/java/org/apache/iotdb/db/metadata/template/TemplateQueryType.java
@@ -23,5 +23,8 @@ public enum TemplateQueryType {
   COUNT_MEASUREMENTS,
   IS_MEASUREMENT,
   PATH_EXIST,
-  SHOW_MEASUREMENTS
+  SHOW_MEASUREMENTS,
+  SHOW_TEMPLATES,
+  SHOW_SET_TEMPLATES,
+  SHOW_USING_TEMPLATES
 }
diff --git a/server/src/main/java/org/apache/iotdb/db/qp/executor/PlanExecutor.java b/server/src/main/java/org/apache/iotdb/db/qp/executor/PlanExecutor.java
index 95802c4..2f0f3f9 100644
--- a/server/src/main/java/org/apache/iotdb/db/qp/executor/PlanExecutor.java
+++ b/server/src/main/java/org/apache/iotdb/db/qp/executor/PlanExecutor.java
@@ -100,6 +100,7 @@ import org.apache.iotdb.db.qp.physical.sys.DeleteStorageGroupPlan;
 import org.apache.iotdb.db.qp.physical.sys.DeleteTimeSeriesPlan;
 import org.apache.iotdb.db.qp.physical.sys.DropContinuousQueryPlan;
 import org.apache.iotdb.db.qp.physical.sys.DropFunctionPlan;
+import org.apache.iotdb.db.qp.physical.sys.DropTemplatePlan;
 import org.apache.iotdb.db.qp.physical.sys.DropTriggerPlan;
 import org.apache.iotdb.db.qp.physical.sys.FlushPlan;
 import org.apache.iotdb.db.qp.physical.sys.KillQueryPlan;
@@ -377,6 +378,8 @@ public class PlanExecutor implements IPlanExecutor {
         return true;
       case CREATE_TEMPLATE:
         return createTemplate((CreateTemplatePlan) plan);
+      case DROP_TEMPLATE:
+        return dropTemplate((DropTemplatePlan) plan);
       case APPEND_TEMPLATE:
         return appendTemplate((AppendTemplatePlan) plan);
       case PRUNE_TEMPLATE:
@@ -410,6 +413,15 @@ public class PlanExecutor implements IPlanExecutor {
     return true;
   }
 
+  private boolean dropTemplate(DropTemplatePlan dropTemplatePlan) throws QueryProcessException {
+    try {
+      IoTDB.metaManager.dropSchemaTemplate(dropTemplatePlan);
+    } catch (MetadataException e) {
+      throw new QueryProcessException(e);
+    }
+    return true;
+  }
+
   private boolean appendTemplate(AppendTemplatePlan plan) throws QueryProcessException {
     try {
       IoTDB.metaManager.appendSchemaTemplate(plan);
diff --git a/server/src/main/java/org/apache/iotdb/db/qp/logical/Operator.java b/server/src/main/java/org/apache/iotdb/db/qp/logical/Operator.java
index 428610f..570c01d 100644
--- a/server/src/main/java/org/apache/iotdb/db/qp/logical/Operator.java
+++ b/server/src/main/java/org/apache/iotdb/db/qp/logical/Operator.java
@@ -191,6 +191,7 @@ public abstract class Operator {
 
     UNSET_TEMPLATE,
     PRUNE_TEMPLATE,
-    APPEND_TEMPLATE
+    APPEND_TEMPLATE,
+    DROP_TEMPLATE
   }
 }
diff --git a/server/src/main/java/org/apache/iotdb/db/qp/physical/PhysicalPlan.java b/server/src/main/java/org/apache/iotdb/db/qp/physical/PhysicalPlan.java
index 3ed4ff7..91cc485 100644
--- a/server/src/main/java/org/apache/iotdb/db/qp/physical/PhysicalPlan.java
+++ b/server/src/main/java/org/apache/iotdb/db/qp/physical/PhysicalPlan.java
@@ -53,6 +53,7 @@ import org.apache.iotdb.db.qp.physical.sys.DeleteTimeSeriesPlan;
 import org.apache.iotdb.db.qp.physical.sys.DropContinuousQueryPlan;
 import org.apache.iotdb.db.qp.physical.sys.DropFunctionPlan;
 import org.apache.iotdb.db.qp.physical.sys.DropIndexPlan;
+import org.apache.iotdb.db.qp.physical.sys.DropTemplatePlan;
 import org.apache.iotdb.db.qp.physical.sys.DropTriggerPlan;
 import org.apache.iotdb.db.qp.physical.sys.FlushPlan;
 import org.apache.iotdb.db.qp.physical.sys.LoadConfigurationPlan;
@@ -70,6 +71,7 @@ import org.apache.iotdb.db.qp.physical.sys.ShowTimeSeriesPlan;
 import org.apache.iotdb.db.qp.physical.sys.StartTriggerPlan;
 import org.apache.iotdb.db.qp.physical.sys.StopTriggerPlan;
 import org.apache.iotdb.db.qp.physical.sys.StorageGroupMNodePlan;
+import org.apache.iotdb.db.qp.physical.sys.UnsetTemplatePlan;
 import org.apache.iotdb.db.qp.utils.EmptyOutputStream;
 import org.apache.iotdb.tsfile.utils.ReadWriteIOUtils;
 
@@ -439,6 +441,12 @@ public abstract class PhysicalPlan {
         case PRUNE_TEMPLATE:
           plan = new PruneTemplatePlan();
           break;
+        case DROP_TEMPLATE:
+          plan = new DropTemplatePlan();
+          break;
+        case UNSET_TEMPLATE:
+          plan = new UnsetTemplatePlan();
+          break;
         case SET_TEMPLATE:
           plan = new SetTemplatePlan();
           break;
@@ -544,7 +552,8 @@ public abstract class PhysicalPlan {
     SET_SYSTEM_MODE,
     UNSET_TEMPLATE,
     APPEND_TEMPLATE,
-    PRUNE_TEMPLATE
+    PRUNE_TEMPLATE,
+    DROP_TEMPLATE
   }
 
   public long getIndex() {
diff --git a/server/src/main/java/org/apache/iotdb/db/qp/physical/sys/DropTemplatePlan.java b/server/src/main/java/org/apache/iotdb/db/qp/physical/sys/DropTemplatePlan.java
new file mode 100644
index 0000000..17ea3bb
--- /dev/null
+++ b/server/src/main/java/org/apache/iotdb/db/qp/physical/sys/DropTemplatePlan.java
@@ -0,0 +1,78 @@
+/*
+ * 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.qp.physical.sys;
+
+import org.apache.iotdb.db.metadata.path.PartialPath;
+import org.apache.iotdb.db.qp.logical.Operator.OperatorType;
+import org.apache.iotdb.db.qp.physical.PhysicalPlan;
+import org.apache.iotdb.tsfile.utils.ReadWriteIOUtils;
+
+import java.io.DataOutputStream;
+import java.io.IOException;
+import java.nio.ByteBuffer;
+import java.util.List;
+
+public class DropTemplatePlan extends PhysicalPlan {
+
+  String name;
+
+  public DropTemplatePlan() {
+    super(OperatorType.DROP_TEMPLATE);
+  }
+
+  public DropTemplatePlan(String name) {
+    super(OperatorType.DROP_TEMPLATE);
+    this.name = name;
+  }
+
+  public String getName() {
+    return name;
+  }
+
+  public void setName(String name) {
+    this.name = name;
+  }
+
+  @Override
+  public void serializeImpl(ByteBuffer buffer) {
+    buffer.put((byte) PhysicalPlanType.DROP_TEMPLATE.ordinal());
+    ReadWriteIOUtils.write(name, buffer);
+    buffer.putLong(index);
+  }
+
+  @Override
+  @SuppressWarnings("Duplicates")
+  public void deserialize(ByteBuffer buffer) {
+    name = ReadWriteIOUtils.readString(buffer);
+    this.index = buffer.getLong();
+  }
+
+  @Override
+  public void serialize(DataOutputStream stream) throws IOException {
+    stream.writeByte((byte) PhysicalPlanType.DROP_TEMPLATE.ordinal());
+    ReadWriteIOUtils.write(name, stream);
+    stream.writeLong(index);
+  }
+
+  @Override
+  public List<PartialPath> getPaths() {
+    return null;
+  }
+}
diff --git a/server/src/main/java/org/apache/iotdb/db/service/thrift/impl/TSServiceImpl.java b/server/src/main/java/org/apache/iotdb/db/service/thrift/impl/TSServiceImpl.java
index 991e21a..a8ad168 100644
--- a/server/src/main/java/org/apache/iotdb/db/service/thrift/impl/TSServiceImpl.java
+++ b/server/src/main/java/org/apache/iotdb/db/service/thrift/impl/TSServiceImpl.java
@@ -53,6 +53,7 @@ import org.apache.iotdb.db.qp.physical.sys.CreateTemplatePlan;
 import org.apache.iotdb.db.qp.physical.sys.CreateTimeSeriesPlan;
 import org.apache.iotdb.db.qp.physical.sys.DeleteStorageGroupPlan;
 import org.apache.iotdb.db.qp.physical.sys.DeleteTimeSeriesPlan;
+import org.apache.iotdb.db.qp.physical.sys.DropTemplatePlan;
 import org.apache.iotdb.db.qp.physical.sys.PruneTemplatePlan;
 import org.apache.iotdb.db.qp.physical.sys.SetStorageGroupPlan;
 import org.apache.iotdb.db.qp.physical.sys.SetTemplatePlan;
@@ -86,6 +87,7 @@ import org.apache.iotdb.service.rpc.thrift.TSCreateMultiTimeseriesReq;
 import org.apache.iotdb.service.rpc.thrift.TSCreateSchemaTemplateReq;
 import org.apache.iotdb.service.rpc.thrift.TSCreateTimeseriesReq;
 import org.apache.iotdb.service.rpc.thrift.TSDeleteDataReq;
+import org.apache.iotdb.service.rpc.thrift.TSDropSchemaTemplateReq;
 import org.apache.iotdb.service.rpc.thrift.TSExecuteBatchStatementReq;
 import org.apache.iotdb.service.rpc.thrift.TSExecuteStatementReq;
 import org.apache.iotdb.service.rpc.thrift.TSExecuteStatementResp;
@@ -1901,6 +1903,20 @@ public class TSServiceImpl implements TSIService.Iface {
           resp.setQueryType(TemplateQueryType.SHOW_MEASUREMENTS.ordinal());
           resp.setMeasurements(IoTDB.metaManager.getMeasurementsInTemplate(req.name, path));
           break;
+        case SHOW_TEMPLATES:
+          resp.setQueryType(TemplateQueryType.SHOW_TEMPLATES.ordinal());
+          resp.setMeasurements(new ArrayList<>(IoTDB.metaManager.getAllTemplates()));
+          break;
+        case SHOW_SET_TEMPLATES:
+          path = req.getName();
+          resp.setQueryType(TemplateQueryType.SHOW_SET_TEMPLATES.ordinal());
+          resp.setMeasurements(new ArrayList<>(IoTDB.metaManager.getPathsSetTemplate(path)));
+          break;
+        case SHOW_USING_TEMPLATES:
+          path = req.getName();
+          resp.setQueryType(TemplateQueryType.SHOW_USING_TEMPLATES.ordinal());
+          resp.setMeasurements(new ArrayList<>(IoTDB.metaManager.getPathsUsingTemplate(path)));
+          break;
       }
       resp.setStatus(RpcUtils.getStatus(TSStatusCode.SUCCESS_STATUS, "Execute successfully"));
       return resp;
@@ -1937,7 +1953,7 @@ public class TSServiceImpl implements TSIService.Iface {
 
     if (AUDIT_LOGGER.isDebugEnabled()) {
       AUDIT_LOGGER.debug(
-          "Session-{} unset device template {}.{}",
+          "Session-{} unset schema template {}.{}",
           SESSION_MANAGER.getCurrSessionId(),
           req.getPrefixPath(),
           req.getTemplateName());
@@ -1948,6 +1964,24 @@ public class TSServiceImpl implements TSIService.Iface {
     return status != null ? status : executeNonQueryPlan(plan);
   }
 
+  @Override
+  public TSStatus dropSchemaTemplate(TSDropSchemaTemplateReq req) throws TException {
+    if (!serviceProvider.checkLogin(req.getSessionId())) {
+      return getNotLoggedInStatus();
+    }
+
+    if (AUDIT_LOGGER.isDebugEnabled()) {
+      AUDIT_LOGGER.debug(
+          "Session-{} drop schema template {}.",
+          SESSION_MANAGER.getCurrSessionId(),
+          req.getTemplateName());
+    }
+
+    DropTemplatePlan plan = new DropTemplatePlan(req.templateName);
+    TSStatus status = serviceProvider.checkAuthority(plan, req.getSessionId());
+    return status != null ? status : executeNonQueryPlan(plan);
+  }
+
   protected TSStatus executeNonQueryPlan(PhysicalPlan plan) {
     try {
       return serviceProvider.executeNonQuery(plan)
diff --git a/server/src/main/java/org/apache/iotdb/db/tools/mlog/MLogParser.java b/server/src/main/java/org/apache/iotdb/db/tools/mlog/MLogParser.java
index 672defa..773ae2c 100644
--- a/server/src/main/java/org/apache/iotdb/db/tools/mlog/MLogParser.java
+++ b/server/src/main/java/org/apache/iotdb/db/tools/mlog/MLogParser.java
@@ -32,6 +32,7 @@ import org.apache.iotdb.db.qp.physical.sys.CreateContinuousQueryPlan;
 import org.apache.iotdb.db.qp.physical.sys.CreateTemplatePlan;
 import org.apache.iotdb.db.qp.physical.sys.CreateTimeSeriesPlan;
 import org.apache.iotdb.db.qp.physical.sys.DropContinuousQueryPlan;
+import org.apache.iotdb.db.qp.physical.sys.DropTemplatePlan;
 import org.apache.iotdb.db.qp.physical.sys.MNodePlan;
 import org.apache.iotdb.db.qp.physical.sys.MeasurementMNodePlan;
 import org.apache.iotdb.db.qp.physical.sys.PruneTemplatePlan;
@@ -39,6 +40,7 @@ import org.apache.iotdb.db.qp.physical.sys.SetStorageGroupPlan;
 import org.apache.iotdb.db.qp.physical.sys.SetTTLPlan;
 import org.apache.iotdb.db.qp.physical.sys.SetTemplatePlan;
 import org.apache.iotdb.db.qp.physical.sys.StorageGroupMNodePlan;
+import org.apache.iotdb.db.qp.physical.sys.UnsetTemplatePlan;
 
 import org.apache.commons.cli.CommandLine;
 import org.apache.commons.cli.CommandLineParser;
@@ -227,6 +229,12 @@ public class MLogParser {
           case SET_TEMPLATE:
             mLogTxtWriter.setTemplate((SetTemplatePlan) plan);
             break;
+          case UNSET_TEMPLATE:
+            mLogTxtWriter.unsetTemplate((UnsetTemplatePlan) plan);
+            break;
+          case DROP_TEMPLATE:
+            mLogTxtWriter.dropTemplate((DropTemplatePlan) plan);
+            break;
           case ACTIVATE_TEMPLATE:
             mLogTxtWriter.setUsingTemplate((ActivateTemplatePlan) plan);
             break;
diff --git a/server/src/test/java/org/apache/iotdb/db/metadata/TemplateTest.java b/server/src/test/java/org/apache/iotdb/db/metadata/TemplateTest.java
index 781b82e..3ed4cee 100644
--- a/server/src/test/java/org/apache/iotdb/db/metadata/TemplateTest.java
+++ b/server/src/test/java/org/apache/iotdb/db/metadata/TemplateTest.java
@@ -18,16 +18,22 @@
  */
 package org.apache.iotdb.db.metadata;
 
+import org.apache.iotdb.db.exception.metadata.IllegalPathException;
 import org.apache.iotdb.db.exception.metadata.MetadataException;
 import org.apache.iotdb.db.exception.metadata.PathNotExistException;
+import org.apache.iotdb.db.exception.query.QueryProcessException;
 import org.apache.iotdb.db.metadata.mnode.IMNode;
 import org.apache.iotdb.db.metadata.mnode.IMeasurementMNode;
 import org.apache.iotdb.db.metadata.path.MeasurementPath;
 import org.apache.iotdb.db.metadata.path.PartialPath;
 import org.apache.iotdb.db.metadata.template.Template;
+import org.apache.iotdb.db.qp.executor.PlanExecutor;
 import org.apache.iotdb.db.qp.physical.PhysicalPlan;
+import org.apache.iotdb.db.qp.physical.crud.InsertRowPlan;
 import org.apache.iotdb.db.qp.physical.sys.CreateTemplatePlan;
+import org.apache.iotdb.db.qp.physical.sys.DropTemplatePlan;
 import org.apache.iotdb.db.qp.physical.sys.SetTemplatePlan;
+import org.apache.iotdb.db.qp.physical.sys.UnsetTemplatePlan;
 import org.apache.iotdb.db.service.IoTDB;
 import org.apache.iotdb.db.utils.EnvironmentUtils;
 import org.apache.iotdb.tsfile.file.metadata.enums.CompressionType;
@@ -191,8 +197,8 @@ public class TemplateTest {
     measurementList.add(Arrays.asList("GPS.x", "GPS.y"));
 
     List<List<TSDataType>> dataTypeList = new ArrayList<>();
-    dataTypeList.add(Collections.singletonList(TSDataType.INT32));
-    dataTypeList.add(Collections.singletonList(TSDataType.INT32));
+    dataTypeList.add(Collections.singletonList(TSDataType.INT64));
+    dataTypeList.add(Collections.singletonList(TSDataType.INT64));
     dataTypeList.add(Arrays.asList(TSDataType.FLOAT, TSDataType.FLOAT));
 
     List<List<TSEncoding>> encodingList = new ArrayList<>();
@@ -201,7 +207,7 @@ public class TemplateTest {
     encodingList.add(Arrays.asList(TSEncoding.RLE, TSEncoding.RLE));
 
     List<List<CompressionType>> compressionTypes = new ArrayList<>();
-    compressionTypes.add(Collections.singletonList(CompressionType.SDT));
+    compressionTypes.add(Collections.singletonList(CompressionType.UNCOMPRESSED));
     compressionTypes.add(Collections.singletonList(CompressionType.SNAPPY));
     compressionTypes.add(Arrays.asList(CompressionType.SNAPPY, CompressionType.SNAPPY));
 
@@ -249,4 +255,127 @@ public class TemplateTest {
     return new CreateTemplatePlan(
         "template1", schemaNames, measurementList, dataTypeList, encodingList, compressionTypes);
   }
+
+  /**
+   * Test for show templates, including all templates, paths set or using designated template
+   *
+   * @throws MetadataException
+   */
+  @Test
+  public void testShowTemplates() throws MetadataException, QueryProcessException {
+    MManager manager = IoTDB.metaManager;
+    assertEquals(0, manager.getAllTemplates().size());
+    CreateTemplatePlan plan1 = getTreeTemplatePlan();
+    CreateTemplatePlan plan2 = getCreateTemplatePlan();
+    manager.createSchemaTemplate(plan1);
+    manager.createSchemaTemplate(plan2);
+
+    assertEquals("[template1, treeTemplate]", manager.getAllTemplates().toString());
+
+    for (int i = 0; i < 3; i++) {
+      SetTemplatePlan setTemplatePlan =
+          new SetTemplatePlan("template1", String.format("root.sg%d.d%d", i, i + 1));
+      manager.setSchemaTemplate(setTemplatePlan);
+    }
+
+    assertEquals(
+        new HashSet<>(Arrays.asList("root.sg1.d2", "root.sg0.d1", "root.sg2.d3")),
+        manager.getPathsSetTemplate(""));
+    assertEquals(new HashSet<>(Arrays.asList()), manager.getPathsSetTemplate("treeTemplate"));
+
+    for (int i = 0; i < 3; i++) {
+      SetTemplatePlan setTemplatePlan =
+          new SetTemplatePlan("treeTemplate", String.format("root.tsg%d.d%d", i + 9, i + 10));
+      manager.setSchemaTemplate(setTemplatePlan);
+    }
+
+    assertEquals(
+        new HashSet<>(Arrays.asList("root.tsg10.d11", "root.tsg11.d12", "root.tsg9.d10")),
+        manager.getPathsSetTemplate("treeTemplate"));
+    assertEquals(
+        new HashSet<>(
+            Arrays.asList(
+                "root.tsg10.d11",
+                "root.tsg11.d12",
+                "root.tsg9.d10",
+                "root.sg1.d2",
+                "root.sg0.d1",
+                "root.sg2.d3")),
+        manager.getPathsSetTemplate(""));
+
+    PlanExecutor exe1 = new PlanExecutor();
+    exe1.insert(getInsertRowPlan("root.sg0.d1", "s11"));
+    exe1.insert(getInsertRowPlan("root.sg1.d2", "s11"));
+    exe1.insert(getInsertRowPlan("root.tsg10.d11.d1", "s1"));
+
+    assertEquals(
+        new HashSet<>(Arrays.asList("root.tsg10.d11", "root.sg1.d2", "root.sg0.d1")),
+        manager.getPathsUsingTemplate(""));
+
+    try {
+      manager.createSchemaTemplate(plan1);
+      fail();
+    } catch (MetadataException e) {
+      assertEquals("Duplicated template name: treeTemplate", e.getMessage());
+    }
+
+    try {
+      manager.dropSchemaTemplate(new DropTemplatePlan("treeTemplate"));
+      fail();
+    } catch (MetadataException e) {
+      assertEquals(
+          "Template [treeTemplate] has been set on MTree, cannot be dropped now.", e.getMessage());
+    }
+  }
+
+  @Test
+  public void testDropTemplate() throws MetadataException {
+    MManager manager = IoTDB.metaManager;
+    CreateTemplatePlan plan1 = getTreeTemplatePlan();
+    CreateTemplatePlan plan2 = getCreateTemplatePlan();
+    manager.createSchemaTemplate(plan1);
+    manager.createSchemaTemplate(plan2);
+
+    assertEquals("[template1, treeTemplate]", manager.getAllTemplates().toString());
+
+    try {
+      manager.createSchemaTemplate(plan2);
+      fail();
+    } catch (MetadataException e) {
+      assertEquals("Duplicated template name: template1", e.getMessage());
+    }
+
+    SetTemplatePlan setTemplatePlan = new SetTemplatePlan("template1", "root.sg.d0");
+    manager.setSchemaTemplate(setTemplatePlan);
+
+    try {
+      manager.dropSchemaTemplate(new DropTemplatePlan("template1"));
+      fail();
+    } catch (MetadataException e) {
+      assertEquals(
+          "Template [template1] has been set on MTree, cannot be dropped now.", e.getMessage());
+    }
+
+    UnsetTemplatePlan unsetPlan = new UnsetTemplatePlan("root.sg.d0", "template1");
+    manager.unsetSchemaTemplate(unsetPlan);
+
+    manager.dropSchemaTemplate(new DropTemplatePlan("template1"));
+    assertEquals("[treeTemplate]", manager.getAllTemplates().toString());
+    manager.createSchemaTemplate(plan2);
+    assertEquals("[template1, treeTemplate]", manager.getAllTemplates().toString());
+    manager.dropSchemaTemplate(new DropTemplatePlan("template1"));
+    manager.dropSchemaTemplate(new DropTemplatePlan("treeTemplate"));
+  }
+
+  private InsertRowPlan getInsertRowPlan(String prefixPath, String measurement)
+      throws IllegalPathException {
+    long time = 110L;
+    TSDataType[] dataTypes = new TSDataType[] {TSDataType.INT64};
+
+    String[] columns = new String[1];
+    columns[0] = "1";
+
+    return new InsertRowPlan(
+        new PartialPath(prefixPath), time, new String[] {measurement}, dataTypes, columns);
+  }
 }
diff --git a/session/src/main/java/org/apache/iotdb/session/Session.java b/session/src/main/java/org/apache/iotdb/session/Session.java
index 9b30a8a..cc7360e 100644
--- a/session/src/main/java/org/apache/iotdb/session/Session.java
+++ b/session/src/main/java/org/apache/iotdb/session/Session.java
@@ -29,6 +29,7 @@ import org.apache.iotdb.service.rpc.thrift.TSCreateMultiTimeseriesReq;
 import org.apache.iotdb.service.rpc.thrift.TSCreateSchemaTemplateReq;
 import org.apache.iotdb.service.rpc.thrift.TSCreateTimeseriesReq;
 import org.apache.iotdb.service.rpc.thrift.TSDeleteDataReq;
+import org.apache.iotdb.service.rpc.thrift.TSDropSchemaTemplateReq;
 import org.apache.iotdb.service.rpc.thrift.TSInsertRecordReq;
 import org.apache.iotdb.service.rpc.thrift.TSInsertRecordsOfOneDeviceReq;
 import org.apache.iotdb.service.rpc.thrift.TSInsertRecordsReq;
@@ -2162,12 +2163,48 @@ public class Session {
     return resp.getMeasurements();
   }
 
+  /** @return All template names. */
+  public List<String> showAllTemplates()
+      throws StatementExecutionException, IoTDBConnectionException {
+    TSQueryTemplateReq req = new TSQueryTemplateReq();
+    req.setName("");
+    req.setQueryType(TemplateQueryType.SHOW_TEMPLATES.ordinal());
+    TSQueryTemplateResp resp = defaultSessionConnection.querySchemaTemplate(req);
+    return resp.getMeasurements();
+  }
+
+  /** @return All paths have been set to designated template. */
+  public List<String> showPathsTemplateSetOn(String templateName)
+      throws StatementExecutionException, IoTDBConnectionException {
+    TSQueryTemplateReq req = new TSQueryTemplateReq();
+    req.setName(templateName);
+    req.setQueryType(TemplateQueryType.SHOW_SET_TEMPLATES.ordinal());
+    TSQueryTemplateResp resp = defaultSessionConnection.querySchemaTemplate(req);
+    return resp.getMeasurements();
+  }
+
+  /** @return All paths are using designated template. */
+  public List<String> showPathsTemplateUsingOn(String templateName)
+      throws StatementExecutionException, IoTDBConnectionException {
+    TSQueryTemplateReq req = new TSQueryTemplateReq();
+    req.setName(templateName);
+    req.setQueryType(TemplateQueryType.SHOW_USING_TEMPLATES.ordinal());
+    TSQueryTemplateResp resp = defaultSessionConnection.querySchemaTemplate(req);
+    return resp.getMeasurements();
+  }
+
   public void unsetSchemaTemplate(String prefixPath, String templateName)
       throws IoTDBConnectionException, StatementExecutionException {
     TSUnsetSchemaTemplateReq request = getTSUnsetSchemaTemplateReq(prefixPath, templateName);
     defaultSessionConnection.unsetSchemaTemplate(request);
   }
 
+  public void dropSchemaTemplate(String templateName)
+      throws IoTDBConnectionException, StatementExecutionException {
+    TSDropSchemaTemplateReq request = getTSDropSchemaTemplateReq(templateName);
+    defaultSessionConnection.dropSchemaTemplate(request);
+  }
+
   private TSSetSchemaTemplateReq getTSSetSchemaTemplateReq(String templateName, String prefixPath) {
     TSSetSchemaTemplateReq request = new TSSetSchemaTemplateReq();
     request.setTemplateName(templateName);
@@ -2183,6 +2220,12 @@ public class Session {
     return request;
   }
 
+  private TSDropSchemaTemplateReq getTSDropSchemaTemplateReq(String templateName) {
+    TSDropSchemaTemplateReq request = new TSDropSchemaTemplateReq();
+    request.setTemplateName(templateName);
+    return request;
+  }
+
   /**
    * @param recordsGroup connection to record map
    * @param insertConsumer insert function
diff --git a/session/src/main/java/org/apache/iotdb/session/SessionConnection.java b/session/src/main/java/org/apache/iotdb/session/SessionConnection.java
index d787ddf..ee33134 100644
--- a/session/src/main/java/org/apache/iotdb/session/SessionConnection.java
+++ b/session/src/main/java/org/apache/iotdb/session/SessionConnection.java
@@ -32,6 +32,7 @@ import org.apache.iotdb.service.rpc.thrift.TSCreateMultiTimeseriesReq;
 import org.apache.iotdb.service.rpc.thrift.TSCreateSchemaTemplateReq;
 import org.apache.iotdb.service.rpc.thrift.TSCreateTimeseriesReq;
 import org.apache.iotdb.service.rpc.thrift.TSDeleteDataReq;
+import org.apache.iotdb.service.rpc.thrift.TSDropSchemaTemplateReq;
 import org.apache.iotdb.service.rpc.thrift.TSExecuteStatementReq;
 import org.apache.iotdb.service.rpc.thrift.TSExecuteStatementResp;
 import org.apache.iotdb.service.rpc.thrift.TSIService;
@@ -902,6 +903,25 @@ public class SessionConnection {
     }
   }
 
+  protected void dropSchemaTemplate(TSDropSchemaTemplateReq request)
+      throws IoTDBConnectionException, StatementExecutionException {
+    request.setSessionId(sessionId);
+    try {
+      RpcUtils.verifySuccess(client.dropSchemaTemplate(request));
+    } catch (TException e) {
+      if (reconnect()) {
+        try {
+          request.setSessionId(sessionId);
+          RpcUtils.verifySuccess(client.dropSchemaTemplate(request));
+        } catch (TException tException) {
+          throw new IoTDBConnectionException(tException);
+        }
+      } else {
+        throw new IoTDBConnectionException(MSG_RECONNECTION_FAIL);
+      }
+    }
+  }
+
   public boolean isEnableRedirect() {
     return enableRedirect;
   }
diff --git a/session/src/main/java/org/apache/iotdb/session/pool/SessionPool.java b/session/src/main/java/org/apache/iotdb/session/pool/SessionPool.java
index d61d86e..ba8c9e9 100644
--- a/session/src/main/java/org/apache/iotdb/session/pool/SessionPool.java
+++ b/session/src/main/java/org/apache/iotdb/session/pool/SessionPool.java
@@ -1681,6 +1681,103 @@ public class SessionPool {
     return null;
   }
 
+  public List<String> showAllTemplates()
+      throws StatementExecutionException, IoTDBConnectionException {
+    for (int i = 0; i < RETRY; i++) {
+      Session session = getSession();
+      try {
+        List<String> resp = session.showAllTemplates();
+        putBack(session);
+        return resp;
+      } catch (IoTDBConnectionException e) {
+        // TException means the connection is broken, remove it and get a new one.
+        logger.warn("showAllTemplates failed", e);
+        cleanSessionAndMayThrowConnectionException(session, i, e);
+      } catch (StatementExecutionException | RuntimeException e) {
+        putBack(session);
+        throw e;
+      }
+    }
+    return null;
+  }
+
+  public List<String> showPathsTemplateSetOn(String templateName)
+      throws StatementExecutionException, IoTDBConnectionException {
+    for (int i = 0; i < RETRY; i++) {
+      Session session = getSession();
+      try {
+        List<String> resp = session.showPathsTemplateSetOn(templateName);
+        putBack(session);
+        return resp;
+      } catch (IoTDBConnectionException e) {
+        // TException means the connection is broken, remove it and get a new one.
+        logger.warn("showPathsTemplateSetOn failed", e);
+        cleanSessionAndMayThrowConnectionException(session, i, e);
+      } catch (StatementExecutionException | RuntimeException e) {
+        putBack(session);
+        throw e;
+      }
+    }
+    return null;
+  }
+
+  public List<String> showPathsTemplateUsingOn(String templateName)
+      throws StatementExecutionException, IoTDBConnectionException {
+    for (int i = 0; i < RETRY; i++) {
+      Session session = getSession();
+      try {
+        List<String> resp = session.showPathsTemplateUsingOn(templateName);
+        putBack(session);
+        return resp;
+      } catch (IoTDBConnectionException e) {
+        // TException means the connection is broken, remove it and get a new one.
+        logger.warn("showPathsTemplateUsingOn failed", e);
+        cleanSessionAndMayThrowConnectionException(session, i, e);
+      } catch (StatementExecutionException | RuntimeException e) {
+        putBack(session);
+        throw e;
+      }
+    }
+    return null;
+  }
+
+  public void unsetSchemaTemplate(String prefixPath, String templateName)
+      throws StatementExecutionException, IoTDBConnectionException {
+    for (int i = 0; i < RETRY; i++) {
+      Session session = getSession();
+      try {
+        session.unsetSchemaTemplate(prefixPath, templateName);
+        putBack(session);
+      } catch (IoTDBConnectionException e) {
+        // TException means the connection is broken, remove it and get a new one.
+        logger.warn(
+            String.format("unsetSchemaTemplate [%s] on [%s] failed", templateName, prefixPath), e);
+        cleanSessionAndMayThrowConnectionException(session, i, e);
+      } catch (StatementExecutionException | RuntimeException e) {
+        putBack(session);
+        throw e;
+      }
+    }
+  }
+
+  public void dropSchemaTemplate(String templateName)
+      throws StatementExecutionException, IoTDBConnectionException {
+    for (int i = 0; i < RETRY; i++) {
+      Session session = getSession();
+      try {
+        session.dropSchemaTemplate(templateName);
+        putBack(session);
+      } catch (IoTDBConnectionException e) {
+        // TException means the connection is broken, remove it and get a new one.
+        logger.warn(String.format("dropSchemaTemplate [%s] failed", templateName), e);
+        cleanSessionAndMayThrowConnectionException(session, i, e);
+      } catch (StatementExecutionException | RuntimeException e) {
+        putBack(session);
+        throw e;
+      }
+    }
+  }
+
   /**
    * execure query sql users must call closeResultSet(SessionDataSetWrapper) if they do not use the
    * SessionDataSet any more. users do not need to call sessionDataSet.closeOpeationHandler() any
diff --git a/session/src/main/java/org/apache/iotdb/session/template/TemplateQueryType.java b/session/src/main/java/org/apache/iotdb/session/template/TemplateQueryType.java
index 82f229a..d7e8b87 100644
--- a/session/src/main/java/org/apache/iotdb/session/template/TemplateQueryType.java
+++ b/session/src/main/java/org/apache/iotdb/session/template/TemplateQueryType.java
@@ -23,5 +23,8 @@ public enum TemplateQueryType {
   COUNT_MEASUREMENTS,
   IS_MEASUREMENT,
   PATH_EXIST,
-  SHOW_MEASUREMENTS
+  SHOW_MEASUREMENTS,
+  SHOW_TEMPLATES,
+  SHOW_SET_TEMPLATES,
+  SHOW_USING_TEMPLATES
 }
diff --git a/session/src/test/java/org/apache/iotdb/session/template/TemplateUT.java b/session/src/test/java/org/apache/iotdb/session/template/TemplateUT.java
index b947f2f..2cad97c 100644
--- a/session/src/test/java/org/apache/iotdb/session/template/TemplateUT.java
+++ b/session/src/test/java/org/apache/iotdb/session/template/TemplateUT.java
@@ -38,6 +38,7 @@ import java.io.IOException;
 import java.nio.ByteBuffer;
 import java.time.ZoneId;
 import java.util.Arrays;
+import java.util.HashSet;
 import java.util.List;
 
 import static junit.framework.TestCase.fail;
@@ -123,4 +124,134 @@ public class TemplateUT {
       assertEquals("303: Template already exists on root.sg.d0", e.getMessage());
     }
   }
+
+  @Test
+  public void testShowTemplates()
+      throws StatementExecutionException, IoTDBConnectionException, IOException {
+    Template temp1 = getTemplate("template1");
+    Template temp2 = getTemplate("template2");
+
+    assertEquals("[]", session.showAllTemplates().toString());
+
+    session.createSchemaTemplate(temp1);
+    session.createSchemaTemplate(temp2);
+
+    assertEquals(
+        new HashSet<>(Arrays.asList("template1", "template2")),
+        new HashSet<>(session.showAllTemplates()));
+
+    session.setSchemaTemplate("template1", "root.sg.v1");
+    session.setSchemaTemplate("template1", "root.sg.v2");
+    session.setSchemaTemplate("template1", "root.sg.v3");
+
+    assertEquals(
+        new HashSet<>(Arrays.asList("root.sg.v1", "root.sg.v2", "root.sg.v3")),
+        new HashSet<>(session.showPathsTemplateSetOn("template1")));
+
+    assertEquals(
+        new HashSet<>(Arrays.asList()),
+        new HashSet<>(session.showPathsTemplateUsingOn("template1")));
+
+    session.setSchemaTemplate("template2", "root.sg.v4");
+    session.setSchemaTemplate("template2", "root.sg.v5");
+    session.setSchemaTemplate("template2", "root.sg.v6");
+
+    assertEquals(
+        new HashSet<>(Arrays.asList("root.sg.v4", "root.sg.v5", "root.sg.v6")),
+        new HashSet<>(session.showPathsTemplateSetOn("template2")));
+
+    assertEquals(
+        new HashSet<>(
+            Arrays.asList(
+                "root.sg.v1",
+                "root.sg.v2",
+                "root.sg.v3",
+                "root.sg.v4",
+                "root.sg.v5",
+                "root.sg.v6")),
+        new HashSet<>(session.showPathsTemplateSetOn("")));
+
+    session.insertRecord(
+        "root.sg.v1.GPS",
+        110L,
+        Arrays.asList("x"),
+        Arrays.asList(TSDataType.FLOAT),
+        Arrays.asList(1.0f));
+
+    assertEquals(
+        new HashSet<>(Arrays.asList("root.sg.v1")),
+        new HashSet<>(session.showPathsTemplateUsingOn("template1")));
+
+    session.insertRecord(
+        "root.sg.v5.GPS",
+        110L,
+        Arrays.asList("x"),
+        Arrays.asList(TSDataType.FLOAT),
+        Arrays.asList(1.0f));
+
+    assertEquals(
+        new HashSet<>(Arrays.asList("root.sg.v1", "root.sg.v5")),
+        new HashSet<>(session.showPathsTemplateUsingOn("")));
+  }
+
+  @Test
+  public void testDropTemplate()
+      throws StatementExecutionException, IoTDBConnectionException, IOException {
+    Template temp1 = getTemplate("template1");
+
+    assertEquals("[]", session.showAllTemplates().toString());
+
+    session.createSchemaTemplate(temp1);
+
+    assertEquals("[]", session.showPathsTemplateSetOn("template1").toString());
+
+    try {
+      session.createSchemaTemplate(temp1);
+      fail();
+    } catch (Exception e) {
+      assertEquals("303: Duplicated template name: template1", e.getMessage());
+    }
+
+    session.dropSchemaTemplate("template1");
+    session.createSchemaTemplate(temp1);
+
+    session.setSchemaTemplate("template1", "root.sg.v1");
+
+    try {
+      session.dropSchemaTemplate("template1");
+      fail();
+    } catch (Exception e) {
+      assertEquals(
+          "303: Template [template1] has been set on MTree, cannot be dropped now.",
+          e.getMessage());
+    }
+
+    session.unsetSchemaTemplate("root.sg.v1", "template1");
+    session.dropSchemaTemplate("template1");
+
+    session.createSchemaTemplate(temp1);
+  }
+
+  private Template getTemplate(String name) throws StatementExecutionException {
+    Template sessionTemplate = new Template(name, true);
+    TemplateNode iNodeGPS = new InternalNode("GPS", false);
+    TemplateNode iNodeV = new InternalNode("vehicle", true);
+    TemplateNode mNodeX =
+        new MeasurementNode("x", TSDataType.FLOAT, TSEncoding.RLE, CompressionType.SNAPPY);
+    TemplateNode mNodeY =
+        new MeasurementNode("y", TSDataType.FLOAT, TSEncoding.RLE, CompressionType.SNAPPY);
+    ByteArrayOutputStream stream = new ByteArrayOutputStream();
+
+    iNodeGPS.addChild(mNodeX);
+    iNodeGPS.addChild(mNodeY);
+    iNodeV.addChild(mNodeX);
+    iNodeV.addChild(mNodeY);
+    iNodeV.addChild(iNodeGPS);
+    sessionTemplate.addToTemplate(iNodeGPS);
+    sessionTemplate.addToTemplate(iNodeV);
+    sessionTemplate.addToTemplate(mNodeX);
+    sessionTemplate.addToTemplate(mNodeY);
+
+    return sessionTemplate;
+  }
 }
diff --git a/thrift/rpc-changelist.md b/thrift/rpc-changelist.md
index 6597785..306c37e 100644
--- a/thrift/rpc-changelist.md
+++ b/thrift/rpc-changelist.md
@@ -21,7 +21,7 @@
 
 # 0.12.x(version-1) -> 0.13.x(version-SNAPSHOT)
 
-Last Updated on 2021.11.16 by Minghui Liu.
+Last Updated on 2022.1.17 by Xin Zhao.
 
 ## 1. Delete Old
 
@@ -34,6 +34,7 @@ Last Updated on 2021.11.16 by Minghui Liu.
 | ------------------------------------------------------------ | ------------------ |
 | Add TSTracingInfo                                            | Minghui Liu        |
 | Add structs and interfaces to append, prune, query and unset Schema Template (detail: TSAppendSchemaTemplateReq, TSPruneSchemaTemplateReq, TSQueryTemplateReq, TSQueryTemplateResp, TSUnsetSchemaTemplateReq, appendSchemaTemplate, pruneSchemaTemplate, querySchemaTemplate, unsetSchemaTemplate), and serializedTemplate in TSCreateSchemaTemplateReq | Xin Zhao           |
+| Add TSDropSchemaTemplateReq, TSStatus dropSchemaTemplate     | Xin Zhao           |
 
 ## 3. Update
 
diff --git a/thrift/src/main/thrift/rpc.thrift b/thrift/src/main/thrift/rpc.thrift
index a981a8c..c80918f 100644
--- a/thrift/src/main/thrift/rpc.thrift
+++ b/thrift/src/main/thrift/rpc.thrift
@@ -402,6 +402,11 @@ struct TSUnsetSchemaTemplateReq {
   3: required string templateName
 }
 
+struct TSDropSchemaTemplateReq {
+  1: required i64 sessionId
+  2: required string templateName
+}
+
 service TSIService {
   TSOpenSessionResp openSession(1:TSOpenSessionReq req);
 
@@ -488,4 +493,6 @@ service TSIService {
   TSStatus setSchemaTemplate(1:TSSetSchemaTemplateReq req);
 
   TSStatus unsetSchemaTemplate(1:TSUnsetSchemaTemplateReq req);
+
+  TSStatus dropSchemaTemplate(1:TSDropSchemaTemplateReq req);
 }
\ No newline at end of file