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

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


The following commit(s) were added to refs/heads/master by this push:
     new dc6c722dc1 [IOTDB-5707] Support Activate Template for Session API 
(#9392)
dc6c722dc1 is described below

commit dc6c722dc1b72383c45eed645da2db565f8151db
Author: Marcos_Zyk <[email protected]>
AuthorDate: Tue Mar 21 15:44:22 2023 +0800

    [IOTDB-5707] Support Activate Template for Session API (#9392)
---
 .../session/it/IoTDBSessionSchemaTemplateIT.java   |  61 ++++++++
 .../java/org/apache/iotdb/isession/ISession.java   |   3 +
 .../apache/iotdb/isession/pool/ISessionPool.java   |   3 +
 .../metadata/visitor/SchemaExecutionVisitor.java   |  20 +++
 .../execution/executor/RegionWriteExecutor.java    |  31 ++++
 .../apache/iotdb/db/mpp/plan/analyze/Analysis.java |  12 ++
 .../iotdb/db/mpp/plan/analyze/AnalyzeVisitor.java  |  33 ++++
 .../db/mpp/plan/parser/StatementGenerator.java     |  13 ++
 .../db/mpp/plan/planner/LogicalPlanVisitor.java    |  16 ++
 .../mpp/plan/planner/plan/node/PlanNodeType.java   |   6 +-
 .../db/mpp/plan/planner/plan/node/PlanVisitor.java |   5 +
 .../node/metedata/write/ActivateTemplateNode.java  |   2 +-
 .../metedata/write/BatchActivateTemplateNode.java  | 166 +++++++++++++++++++++
 .../iotdb/db/mpp/plan/statement/StatementType.java |   2 +
 .../db/mpp/plan/statement/StatementVisitor.java    |   6 +
 ...nt.java => BatchActivateTemplateStatement.java} |  33 ++--
 .../template/DropSchemaTemplateStatement.java      |  13 +-
 .../service/thrift/impl/ClientRPCServiceImpl.java  |  48 ++++++
 .../java/org/apache/iotdb/session/Session.java     |  14 ++
 .../apache/iotdb/session/SessionConnection.java    |  20 +++
 .../org/apache/iotdb/session/pool/SessionPool.java |  20 +++
 thrift/src/main/thrift/client.thrift               |   7 +
 22 files changed, 512 insertions(+), 22 deletions(-)

diff --git 
a/integration-test/src/test/java/org/apache/iotdb/session/it/IoTDBSessionSchemaTemplateIT.java
 
b/integration-test/src/test/java/org/apache/iotdb/session/it/IoTDBSessionSchemaTemplateIT.java
index 42a33747a0..f81d627092 100644
--- 
a/integration-test/src/test/java/org/apache/iotdb/session/it/IoTDBSessionSchemaTemplateIT.java
+++ 
b/integration-test/src/test/java/org/apache/iotdb/session/it/IoTDBSessionSchemaTemplateIT.java
@@ -224,4 +224,65 @@ public class IoTDBSessionSchemaTemplateIT {
 
     return sessionTemplate;
   }
+
+  @Test
+  public void testBatchActivateTemplate()
+      throws StatementExecutionException, IoTDBConnectionException, 
IOException {
+    session.createDatabase("root.db");
+
+    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.db.v1");
+    session.setSchemaTemplate("template1", "root.db.v2");
+    session.setSchemaTemplate("template1", "root.db.v3");
+
+    assertEquals(
+        new HashSet<>(Collections.emptyList()),
+        new HashSet<>(session.showPathsTemplateUsingOn("template1")));
+
+    session.setSchemaTemplate("template2", "root.db.v4");
+    session.setSchemaTemplate("template2", "root.db.v5");
+    session.setSchemaTemplate("template2", "root.db.v6");
+
+    assertEquals(
+        new HashSet<>(Arrays.asList("root.db.v4", "root.db.v5", "root.db.v6")),
+        new HashSet<>(session.showPathsTemplateSetOn("template2")));
+
+    
session.createTimeseriesOfSchemaTemplate(Collections.singletonList("root.db.v1.GPS"));
+
+    assertEquals(
+        new HashSet<>(Collections.singletonList("root.db.v1.GPS")),
+        new HashSet<>(session.showPathsTemplateUsingOn("template1")));
+
+    
session.createTimeseriesOfSchemaTemplate(Collections.singletonList("root.db.v5.GPS"));
+
+    assertEquals(
+        new HashSet<>(Collections.singletonList("root.db.v1.GPS")),
+        new HashSet<>(session.showPathsTemplateUsingOn("template1")));
+
+    assertEquals(
+        new HashSet<>(Collections.singletonList("root.db.v5.GPS")),
+        new HashSet<>(session.showPathsTemplateUsingOn("template2")));
+
+    session.createTimeseriesOfSchemaTemplate(
+        Arrays.asList("root.db.v2.GPS", "root.db.v3.GPS", "root.db.v4.GPS", 
"root.db.v6.GPS"));
+
+    assertEquals(
+        new HashSet<>(Arrays.asList("root.db.v1.GPS", "root.db.v2.GPS", 
"root.db.v3.GPS")),
+        new HashSet<>(session.showPathsTemplateUsingOn("template1")));
+
+    assertEquals(
+        new HashSet<>(Arrays.asList("root.db.v4.GPS", "root.db.v5.GPS", 
"root.db.v6.GPS")),
+        new HashSet<>(session.showPathsTemplateUsingOn("template2")));
+  }
 }
diff --git a/isession/src/main/java/org/apache/iotdb/isession/ISession.java 
b/isession/src/main/java/org/apache/iotdb/isession/ISession.java
index 92a617b6d8..338e4cad37 100644
--- a/isession/src/main/java/org/apache/iotdb/isession/ISession.java
+++ b/isession/src/main/java/org/apache/iotdb/isession/ISession.java
@@ -478,6 +478,9 @@ public interface ISession extends AutoCloseable {
   void dropSchemaTemplate(String templateName)
       throws IoTDBConnectionException, StatementExecutionException;
 
+  void createTimeseriesOfSchemaTemplate(List<String> devicePathList)
+      throws IoTDBConnectionException, StatementExecutionException;
+
   boolean isEnableQueryRedirection();
 
   void setEnableQueryRedirection(boolean enableQueryRedirection);
diff --git 
a/isession/src/main/java/org/apache/iotdb/isession/pool/ISessionPool.java 
b/isession/src/main/java/org/apache/iotdb/isession/pool/ISessionPool.java
index ae71cb4132..7e554478df 100644
--- a/isession/src/main/java/org/apache/iotdb/isession/pool/ISessionPool.java
+++ b/isession/src/main/java/org/apache/iotdb/isession/pool/ISessionPool.java
@@ -394,6 +394,9 @@ public interface ISessionPool {
   void dropSchemaTemplate(String templateName)
       throws StatementExecutionException, IoTDBConnectionException;
 
+  void createTimeseriesOfSchemaTemplate(List<String> devicePathList)
+      throws StatementExecutionException, IoTDBConnectionException;
+
   SessionDataSetWrapper executeQueryStatement(String sql)
       throws IoTDBConnectionException, StatementExecutionException;
 
diff --git 
a/server/src/main/java/org/apache/iotdb/db/metadata/visitor/SchemaExecutionVisitor.java
 
b/server/src/main/java/org/apache/iotdb/db/metadata/visitor/SchemaExecutionVisitor.java
index d553b049a0..d2ca0038b2 100644
--- 
a/server/src/main/java/org/apache/iotdb/db/metadata/visitor/SchemaExecutionVisitor.java
+++ 
b/server/src/main/java/org/apache/iotdb/db/metadata/visitor/SchemaExecutionVisitor.java
@@ -36,6 +36,7 @@ import 
org.apache.iotdb.db.mpp.plan.planner.plan.node.PlanNode;
 import org.apache.iotdb.db.mpp.plan.planner.plan.node.PlanVisitor;
 import 
org.apache.iotdb.db.mpp.plan.planner.plan.node.metedata.write.ActivateTemplateNode;
 import 
org.apache.iotdb.db.mpp.plan.planner.plan.node.metedata.write.AlterTimeSeriesNode;
+import 
org.apache.iotdb.db.mpp.plan.planner.plan.node.metedata.write.BatchActivateTemplateNode;
 import 
org.apache.iotdb.db.mpp.plan.planner.plan.node.metedata.write.ConstructSchemaBlackListNode;
 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;
@@ -326,6 +327,25 @@ public class SchemaExecutionVisitor extends 
PlanVisitor<TSStatus, ISchemaRegion>
     }
   }
 
+  @Override
+  public TSStatus visitBatchActivateTemplate(
+      BatchActivateTemplateNode node, ISchemaRegion schemaRegion) {
+    for (Map.Entry<PartialPath, Pair<Integer, Integer>> entry :
+        node.getTemplateActivationMap().entrySet()) {
+      Template template = 
ClusterTemplateManager.getInstance().getTemplate(entry.getValue().left);
+      try {
+        schemaRegion.activateSchemaTemplate(
+            SchemaRegionWritePlanFactory.getActivateTemplateInClusterPlan(
+                entry.getKey(), entry.getValue().right, entry.getValue().left),
+            template);
+      } catch (MetadataException e) {
+        logger.error(e.getMessage(), e);
+        return RpcUtils.getStatus(e.getErrorCode(), e.getMessage());
+      }
+    }
+    return RpcUtils.getStatus(TSStatusCode.SUCCESS_STATUS);
+  }
+
   @Override
   public TSStatus visitInternalBatchActivateTemplate(
       InternalBatchActivateTemplateNode node, ISchemaRegion schemaRegion) {
diff --git 
a/server/src/main/java/org/apache/iotdb/db/mpp/execution/executor/RegionWriteExecutor.java
 
b/server/src/main/java/org/apache/iotdb/db/mpp/execution/executor/RegionWriteExecutor.java
index 9c5917664b..c035edabe5 100644
--- 
a/server/src/main/java/org/apache/iotdb/db/mpp/execution/executor/RegionWriteExecutor.java
+++ 
b/server/src/main/java/org/apache/iotdb/db/mpp/execution/executor/RegionWriteExecutor.java
@@ -45,6 +45,7 @@ import 
org.apache.iotdb.db.mpp.plan.analyze.schema.SchemaValidator;
 import org.apache.iotdb.db.mpp.plan.planner.plan.node.PlanNode;
 import org.apache.iotdb.db.mpp.plan.planner.plan.node.PlanVisitor;
 import 
org.apache.iotdb.db.mpp.plan.planner.plan.node.metedata.write.ActivateTemplateNode;
+import 
org.apache.iotdb.db.mpp.plan.planner.plan.node.metedata.write.BatchActivateTemplateNode;
 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;
@@ -622,6 +623,36 @@ public class RegionWriteExecutor {
       }
     }
 
+    @Override
+    public RegionExecutionResult visitBatchActivateTemplate(
+        BatchActivateTemplateNode node, WritePlanNodeExecutionContext context) 
{
+      // activate template operation shall be blocked by unset template check
+      context.getRegionWriteValidationRWLock().readLock().lock();
+      try {
+        for (PartialPath devicePath : 
node.getTemplateActivationMap().keySet()) {
+          Pair<Template, PartialPath> templateSetInfo =
+              
ClusterTemplateManager.getInstance().checkTemplateSetInfo(devicePath);
+          if (templateSetInfo == null) {
+            // The activation has already been validated during analyzing.
+            // That means the template is being unset during the activation 
plan transport.
+            RegionExecutionResult result = new RegionExecutionResult();
+            result.setAccepted(false);
+            String message =
+                String.format(
+                    "Template is being unsetting from path %s. Please try 
activating later.",
+                    node.getPathSetTemplate(devicePath));
+            result.setMessage(message);
+            result.setStatus(RpcUtils.getStatus(TSStatusCode.METADATA_ERROR, 
message));
+            return result;
+          }
+        }
+
+        return super.visitBatchActivateTemplate(node, context);
+      } finally {
+        context.getRegionWriteValidationRWLock().readLock().unlock();
+      }
+    }
+
     @Override
     public RegionExecutionResult visitInternalBatchActivateTemplate(
         InternalBatchActivateTemplateNode node, WritePlanNodeExecutionContext 
context) {
diff --git 
a/server/src/main/java/org/apache/iotdb/db/mpp/plan/analyze/Analysis.java 
b/server/src/main/java/org/apache/iotdb/db/mpp/plan/analyze/Analysis.java
index bf15b2a826..e012669ac0 100644
--- a/server/src/main/java/org/apache/iotdb/db/mpp/plan/analyze/Analysis.java
+++ b/server/src/main/java/org/apache/iotdb/db/mpp/plan/analyze/Analysis.java
@@ -199,6 +199,9 @@ public class Analysis {
   // template and paths set template
   private Pair<Template, List<PartialPath>> templateSetInfo;
 
+  // devicePath -> <template, paths set template>
+  private Map<PartialPath, Pair<Template, PartialPath>> 
deviceTemplateSetInfoMap;
+
   // potential template used in timeseries query or fetch
   private Map<Integer, Template> relatedTemplateInfo;
 
@@ -494,6 +497,15 @@ public class Analysis {
     this.templateSetInfo = templateSetInfo;
   }
 
+  public Map<PartialPath, Pair<Template, PartialPath>> 
getDeviceTemplateSetInfoMap() {
+    return deviceTemplateSetInfoMap;
+  }
+
+  public void setDeviceTemplateSetInfoMap(
+      Map<PartialPath, Pair<Template, PartialPath>> deviceTemplateSetInfoMap) {
+    this.deviceTemplateSetInfoMap = deviceTemplateSetInfoMap;
+  }
+
   public Map<Integer, Template> getRelatedTemplateInfo() {
     return relatedTemplateInfo;
   }
diff --git 
a/server/src/main/java/org/apache/iotdb/db/mpp/plan/analyze/AnalyzeVisitor.java 
b/server/src/main/java/org/apache/iotdb/db/mpp/plan/analyze/AnalyzeVisitor.java
index a6bc60a90e..939417253c 100644
--- 
a/server/src/main/java/org/apache/iotdb/db/mpp/plan/analyze/AnalyzeVisitor.java
+++ 
b/server/src/main/java/org/apache/iotdb/db/mpp/plan/analyze/AnalyzeVisitor.java
@@ -122,6 +122,7 @@ import 
org.apache.iotdb.db.mpp.plan.statement.metadata.ShowDevicesStatement;
 import org.apache.iotdb.db.mpp.plan.statement.metadata.ShowTTLStatement;
 import org.apache.iotdb.db.mpp.plan.statement.metadata.ShowTimeSeriesStatement;
 import 
org.apache.iotdb.db.mpp.plan.statement.metadata.template.ActivateTemplateStatement;
+import 
org.apache.iotdb.db.mpp.plan.statement.metadata.template.BatchActivateTemplateStatement;
 import 
org.apache.iotdb.db.mpp.plan.statement.metadata.template.CreateSchemaTemplateStatement;
 import 
org.apache.iotdb.db.mpp.plan.statement.metadata.template.SetSchemaTemplateStatement;
 import 
org.apache.iotdb.db.mpp.plan.statement.metadata.template.ShowNodesInSchemaTemplateStatement;
@@ -2756,6 +2757,38 @@ public class AnalyzeVisitor extends 
StatementVisitor<Analysis, MPPQueryContext>
     return analysis;
   }
 
+  @Override
+  public Analysis visitBatchActivateTemplate(
+      BatchActivateTemplateStatement batchActivateTemplateStatement, 
MPPQueryContext context) {
+    context.setQueryType(QueryType.WRITE);
+    Analysis analysis = new Analysis();
+    analysis.setStatement(batchActivateTemplateStatement);
+
+    Map<PartialPath, Pair<Template, PartialPath>> deviceTemplateSetInfoMap =
+        new HashMap<>(batchActivateTemplateStatement.getPaths().size());
+    for (PartialPath devicePath : 
batchActivateTemplateStatement.getDevicePathList()) {
+      Pair<Template, PartialPath> templateSetInfo = 
schemaFetcher.checkTemplateSetInfo(devicePath);
+      if (templateSetInfo == null) {
+        throw new StatementAnalyzeException(
+            new MetadataException(
+                String.format(
+                    "Path [%s] has not been set any template.", 
devicePath.getFullPath())));
+      }
+      deviceTemplateSetInfoMap.put(devicePath, templateSetInfo);
+    }
+    analysis.setDeviceTemplateSetInfoMap(deviceTemplateSetInfoMap);
+
+    PathPatternTree patternTree = new PathPatternTree();
+    for (PartialPath devicePath : 
batchActivateTemplateStatement.getDevicePathList()) {
+      
patternTree.appendPathPattern(devicePath.concatNode(ONE_LEVEL_PATH_WILDCARD));
+    }
+    SchemaPartition partition = 
partitionFetcher.getOrCreateSchemaPartition(patternTree);
+
+    analysis.setSchemaPartitionInfo(partition);
+
+    return analysis;
+  }
+
   @Override
   public Analysis visitInternalBatchActivateTemplate(
       InternalBatchActivateTemplateStatement 
internalBatchActivateTemplateStatement,
diff --git 
a/server/src/main/java/org/apache/iotdb/db/mpp/plan/parser/StatementGenerator.java
 
b/server/src/main/java/org/apache/iotdb/db/mpp/plan/parser/StatementGenerator.java
index 1ed6966daf..630d882f22 100644
--- 
a/server/src/main/java/org/apache/iotdb/db/mpp/plan/parser/StatementGenerator.java
+++ 
b/server/src/main/java/org/apache/iotdb/db/mpp/plan/parser/StatementGenerator.java
@@ -54,6 +54,7 @@ import 
org.apache.iotdb.db.mpp.plan.statement.metadata.CreateTimeSeriesStatement
 import org.apache.iotdb.db.mpp.plan.statement.metadata.DatabaseSchemaStatement;
 import org.apache.iotdb.db.mpp.plan.statement.metadata.DeleteDatabaseStatement;
 import 
org.apache.iotdb.db.mpp.plan.statement.metadata.DeleteTimeSeriesStatement;
+import 
org.apache.iotdb.db.mpp.plan.statement.metadata.template.BatchActivateTemplateStatement;
 import 
org.apache.iotdb.db.mpp.plan.statement.metadata.template.CreateSchemaTemplateStatement;
 import 
org.apache.iotdb.db.mpp.plan.statement.metadata.template.DropSchemaTemplateStatement;
 import 
org.apache.iotdb.db.mpp.plan.statement.metadata.template.SetSchemaTemplateStatement;
@@ -701,6 +702,18 @@ public class StatementGenerator {
     return statement;
   }
 
+  public static BatchActivateTemplateStatement 
createBatchActivateTemplateStatement(
+      List<String> devicePathStringList) throws IllegalPathException {
+    final long startTime = System.nanoTime();
+    List<PartialPath> devicePathList = new 
ArrayList<>(devicePathStringList.size());
+    for (String pathString : devicePathStringList) {
+      devicePathList.add(new PartialPath(pathString));
+    }
+    BatchActivateTemplateStatement statement = new 
BatchActivateTemplateStatement(devicePathList);
+    PerformanceOverviewMetricsManager.recordParseCost(System.nanoTime() - 
startTime);
+    return statement;
+  }
+
   public static DeleteTimeSeriesStatement createDeleteTimeSeriesStatement(
       List<String> pathPatternStringList) throws IllegalPathException {
     final long startTime = System.nanoTime();
diff --git 
a/server/src/main/java/org/apache/iotdb/db/mpp/plan/planner/LogicalPlanVisitor.java
 
b/server/src/main/java/org/apache/iotdb/db/mpp/plan/planner/LogicalPlanVisitor.java
index 5e503cb6c6..8895c253c1 100644
--- 
a/server/src/main/java/org/apache/iotdb/db/mpp/plan/planner/LogicalPlanVisitor.java
+++ 
b/server/src/main/java/org/apache/iotdb/db/mpp/plan/planner/LogicalPlanVisitor.java
@@ -30,6 +30,7 @@ import 
org.apache.iotdb.db.mpp.plan.planner.plan.node.PlanNode;
 import org.apache.iotdb.db.mpp.plan.planner.plan.node.load.LoadTsFileNode;
 import 
org.apache.iotdb.db.mpp.plan.planner.plan.node.metedata.write.ActivateTemplateNode;
 import 
org.apache.iotdb.db.mpp.plan.planner.plan.node.metedata.write.AlterTimeSeriesNode;
+import 
org.apache.iotdb.db.mpp.plan.planner.plan.node.metedata.write.BatchActivateTemplateNode;
 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;
@@ -73,6 +74,7 @@ import 
org.apache.iotdb.db.mpp.plan.statement.metadata.ShowChildPathsStatement;
 import org.apache.iotdb.db.mpp.plan.statement.metadata.ShowDevicesStatement;
 import org.apache.iotdb.db.mpp.plan.statement.metadata.ShowTimeSeriesStatement;
 import 
org.apache.iotdb.db.mpp.plan.statement.metadata.template.ActivateTemplateStatement;
+import 
org.apache.iotdb.db.mpp.plan.statement.metadata.template.BatchActivateTemplateStatement;
 import 
org.apache.iotdb.db.mpp.plan.statement.metadata.template.ShowPathsUsingTemplateStatement;
 import org.apache.iotdb.db.mpp.plan.statement.sys.ShowQueriesStatement;
 import org.apache.iotdb.tsfile.utils.Pair;
@@ -742,6 +744,20 @@ public class LogicalPlanVisitor extends 
StatementVisitor<PlanNode, MPPQueryConte
         analysis.getTemplateSetInfo().left.getId());
   }
 
+  @Override
+  public PlanNode visitBatchActivateTemplate(
+      BatchActivateTemplateStatement batchActivateTemplateStatement, 
MPPQueryContext context) {
+    Map<PartialPath, Pair<Integer, Integer>> templateActivationMap = new 
HashMap<>();
+    for (Map.Entry<PartialPath, Pair<Template, PartialPath>> entry :
+        analysis.getDeviceTemplateSetInfoMap().entrySet()) {
+      templateActivationMap.put(
+          entry.getKey(),
+          new Pair<>(entry.getValue().left.getId(), 
entry.getValue().right.getNodeLength() - 1));
+    }
+    return new BatchActivateTemplateNode(
+        context.getQueryId().genPlanNodeId(), templateActivationMap);
+  }
+
   @Override
   public PlanNode visitInternalBatchActivateTemplate(
       InternalBatchActivateTemplateStatement 
internalBatchActivateTemplateStatement,
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 9b75d9e4a1..11b7b71717 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
@@ -36,6 +36,7 @@ import 
org.apache.iotdb.db.mpp.plan.planner.plan.node.metedata.read.TimeSeriesCo
 import 
org.apache.iotdb.db.mpp.plan.planner.plan.node.metedata.read.TimeSeriesSchemaScanNode;
 import 
org.apache.iotdb.db.mpp.plan.planner.plan.node.metedata.write.ActivateTemplateNode;
 import 
org.apache.iotdb.db.mpp.plan.planner.plan.node.metedata.write.AlterTimeSeriesNode;
+import 
org.apache.iotdb.db.mpp.plan.planner.plan.node.metedata.write.BatchActivateTemplateNode;
 import 
org.apache.iotdb.db.mpp.plan.planner.plan.node.metedata.write.ConstructSchemaBlackListNode;
 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;
@@ -165,7 +166,8 @@ public enum PlanNodeType {
   INTERNAL_BATCH_ACTIVATE_TEMPLATE((short) 68),
   INTERNAL_CREATE_MULTI_TIMESERIES((short) 69),
   IDENTITY_SINK((short) 70),
-  SHUFFLE_SINK((short) 71);
+  SHUFFLE_SINK((short) 71),
+  BATCH_ACTIVATE_TEMPLATE((short) 72);
 
   public static final int BYTES = Short.BYTES;
 
@@ -356,6 +358,8 @@ public enum PlanNodeType {
         return IdentitySinkNode.deserialize(buffer);
       case 71:
         return ShuffleSinkNode.deserialize(buffer);
+      case 72:
+        return BatchActivateTemplateNode.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/PlanVisitor.java
 
b/server/src/main/java/org/apache/iotdb/db/mpp/plan/planner/plan/node/PlanVisitor.java
index cf3fbe02af..16d81d9c4f 100644
--- 
a/server/src/main/java/org/apache/iotdb/db/mpp/plan/planner/plan/node/PlanVisitor.java
+++ 
b/server/src/main/java/org/apache/iotdb/db/mpp/plan/planner/plan/node/PlanVisitor.java
@@ -35,6 +35,7 @@ import 
org.apache.iotdb.db.mpp.plan.planner.plan.node.metedata.read.TimeSeriesCo
 import 
org.apache.iotdb.db.mpp.plan.planner.plan.node.metedata.read.TimeSeriesSchemaScanNode;
 import 
org.apache.iotdb.db.mpp.plan.planner.plan.node.metedata.write.ActivateTemplateNode;
 import 
org.apache.iotdb.db.mpp.plan.planner.plan.node.metedata.write.AlterTimeSeriesNode;
+import 
org.apache.iotdb.db.mpp.plan.planner.plan.node.metedata.write.BatchActivateTemplateNode;
 import 
org.apache.iotdb.db.mpp.plan.planner.plan.node.metedata.write.ConstructSchemaBlackListNode;
 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;
@@ -325,6 +326,10 @@ public abstract class PlanVisitor<R, C> {
     return visitPlan(node, context);
   }
 
+  public R visitBatchActivateTemplate(BatchActivateTemplateNode node, C 
context) {
+    return visitPlan(node, context);
+  }
+
   public R visitPreDeactivateTemplate(PreDeactivateTemplateNode node, C 
context) {
     return visitPlan(node, context);
   }
diff --git 
a/server/src/main/java/org/apache/iotdb/db/mpp/plan/planner/plan/node/metedata/write/ActivateTemplateNode.java
 
b/server/src/main/java/org/apache/iotdb/db/mpp/plan/planner/plan/node/metedata/write/ActivateTemplateNode.java
index 4d7bf8acf5..f941d75075 100644
--- 
a/server/src/main/java/org/apache/iotdb/db/mpp/plan/planner/plan/node/metedata/write/ActivateTemplateNode.java
+++ 
b/server/src/main/java/org/apache/iotdb/db/mpp/plan/planner/plan/node/metedata/write/ActivateTemplateNode.java
@@ -45,7 +45,7 @@ public class ActivateTemplateNode extends WritePlanNode 
implements IActivateTemp
   private int templateSetLevel;
   private int templateId;
 
-  private boolean isAligned;
+  private transient boolean isAligned;
 
   private TRegionReplicaSet regionReplicaSet;
 
diff --git 
a/server/src/main/java/org/apache/iotdb/db/mpp/plan/planner/plan/node/metedata/write/BatchActivateTemplateNode.java
 
b/server/src/main/java/org/apache/iotdb/db/mpp/plan/planner/plan/node/metedata/write/BatchActivateTemplateNode.java
new file mode 100644
index 0000000000..12ecb50c3e
--- /dev/null
+++ 
b/server/src/main/java/org/apache/iotdb/db/mpp/plan/planner/plan/node/metedata/write/BatchActivateTemplateNode.java
@@ -0,0 +1,166 @@
+/*
+ * 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.commons.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.PlanVisitor;
+import org.apache.iotdb.db.mpp.plan.planner.plan.node.WritePlanNode;
+import org.apache.iotdb.tsfile.utils.Pair;
+import org.apache.iotdb.tsfile.utils.ReadWriteIOUtils;
+
+import java.io.DataOutputStream;
+import java.io.IOException;
+import java.nio.ByteBuffer;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+public class BatchActivateTemplateNode extends WritePlanNode {
+
+  // devicePath -> <templateId, templateSetLevel>
+  private final Map<PartialPath, Pair<Integer, Integer>> templateActivationMap;
+
+  private TRegionReplicaSet regionReplicaSet;
+
+  public BatchActivateTemplateNode(
+      PlanNodeId id, Map<PartialPath, Pair<Integer, Integer>> 
templateActivationMap) {
+    super(id);
+    this.templateActivationMap = templateActivationMap;
+  }
+
+  private BatchActivateTemplateNode(
+      PlanNodeId id,
+      Map<PartialPath, Pair<Integer, Integer>> templateActivationMap,
+      TRegionReplicaSet regionReplicaSet) {
+    super(id);
+    this.templateActivationMap = templateActivationMap;
+    this.regionReplicaSet = regionReplicaSet;
+  }
+
+  public Map<PartialPath, Pair<Integer, Integer>> getTemplateActivationMap() {
+    return templateActivationMap;
+  }
+
+  public PartialPath getPathSetTemplate(PartialPath devicePath) {
+    return new PartialPath(
+        Arrays.copyOf(devicePath.getNodes(), 
templateActivationMap.get(devicePath).right + 1));
+  }
+
+  @Override
+  public TRegionReplicaSet getRegionReplicaSet() {
+    return regionReplicaSet;
+  }
+
+  @Override
+  public List<PlanNode> getChildren() {
+    return new ArrayList<>();
+  }
+
+  @Override
+  public void addChild(PlanNode child) {}
+
+  @Override
+  public PlanNode clone() {
+    return new BatchActivateTemplateNode(getPlanNodeId(), 
templateActivationMap, regionReplicaSet);
+  }
+
+  @Override
+  public int allowedChildCount() {
+    return 0;
+  }
+
+  @Override
+  public List<String> getOutputColumnNames() {
+    return null;
+  }
+
+  @Override
+  protected void serializeAttributes(ByteBuffer byteBuffer) {
+    PlanNodeType.BATCH_ACTIVATE_TEMPLATE.serialize(byteBuffer);
+
+    int size = templateActivationMap.size();
+    ReadWriteIOUtils.write(size, byteBuffer);
+    for (Map.Entry<PartialPath, Pair<Integer, Integer>> entry : 
templateActivationMap.entrySet()) {
+      entry.getKey().serialize(byteBuffer);
+      ReadWriteIOUtils.write(entry.getValue().left, byteBuffer);
+      ReadWriteIOUtils.write(entry.getValue().right, byteBuffer);
+    }
+  }
+
+  @Override
+  protected void serializeAttributes(DataOutputStream stream) throws 
IOException {
+    PlanNodeType.BATCH_ACTIVATE_TEMPLATE.serialize(stream);
+
+    int size = templateActivationMap.size();
+    ReadWriteIOUtils.write(size, stream);
+    for (Map.Entry<PartialPath, Pair<Integer, Integer>> entry : 
templateActivationMap.entrySet()) {
+      entry.getKey().serialize(stream);
+      ReadWriteIOUtils.write(entry.getValue().left, stream);
+      ReadWriteIOUtils.write(entry.getValue().right, stream);
+    }
+  }
+
+  public static InternalBatchActivateTemplateNode deserialize(ByteBuffer 
byteBuffer) {
+    int size = ReadWriteIOUtils.readInt(byteBuffer);
+    Map<PartialPath, Pair<Integer, Integer>> templateActivationMap = new 
HashMap<>(size);
+    for (int i = 0; i < size; i++) {
+      templateActivationMap.put(
+          (PartialPath) PathDeserializeUtil.deserialize(byteBuffer),
+          new Pair<>(ReadWriteIOUtils.readInt(byteBuffer), 
ReadWriteIOUtils.readInt(byteBuffer)));
+    }
+
+    PlanNodeId planNodeId = PlanNodeId.deserialize(byteBuffer);
+    return new InternalBatchActivateTemplateNode(planNodeId, 
templateActivationMap);
+  }
+
+  @Override
+  public List<WritePlanNode> splitByPartition(Analysis analysis) {
+    // gather devices to same target region
+    Map<TRegionReplicaSet, Map<PartialPath, Pair<Integer, Integer>>> splitMap 
= new HashMap<>();
+    for (Map.Entry<PartialPath, Pair<Integer, Integer>> entry : 
templateActivationMap.entrySet()) {
+      TRegionReplicaSet regionReplicaSet =
+          
analysis.getSchemaPartitionInfo().getSchemaRegionReplicaSet(entry.getKey().getFullPath());
+      splitMap
+          .computeIfAbsent(regionReplicaSet, k -> new HashMap<>())
+          .put(entry.getKey(), entry.getValue());
+    }
+
+    List<WritePlanNode> result = new ArrayList<>();
+    for (Map.Entry<TRegionReplicaSet, Map<PartialPath, Pair<Integer, 
Integer>>> entry :
+        splitMap.entrySet()) {
+      result.add(new BatchActivateTemplateNode(getPlanNodeId(), 
entry.getValue(), entry.getKey()));
+    }
+
+    return result;
+  }
+
+  @Override
+  public <R, C> R accept(PlanVisitor<R, C> visitor, C context) {
+    return visitor.visitBatchActivateTemplate(this, context);
+  }
+}
diff --git 
a/server/src/main/java/org/apache/iotdb/db/mpp/plan/statement/StatementType.java
 
b/server/src/main/java/org/apache/iotdb/db/mpp/plan/statement/StatementType.java
index ddd019de92..f0a91bbfee 100644
--- 
a/server/src/main/java/org/apache/iotdb/db/mpp/plan/statement/StatementType.java
+++ 
b/server/src/main/java/org/apache/iotdb/db/mpp/plan/statement/StatementType.java
@@ -159,4 +159,6 @@ public enum StatementType {
   SHOW_PIPEPLUGINS,
 
   SHOW_PIPES,
+
+  BATCH_ACTIVATE_TEMPLATE,
 }
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 34e2777ec7..10f6b7df2a 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
@@ -74,6 +74,7 @@ import 
org.apache.iotdb.db.mpp.plan.statement.metadata.ShowTriggersStatement;
 import org.apache.iotdb.db.mpp.plan.statement.metadata.ShowVariablesStatement;
 import org.apache.iotdb.db.mpp.plan.statement.metadata.UnSetTTLStatement;
 import 
org.apache.iotdb.db.mpp.plan.statement.metadata.template.ActivateTemplateStatement;
+import 
org.apache.iotdb.db.mpp.plan.statement.metadata.template.BatchActivateTemplateStatement;
 import 
org.apache.iotdb.db.mpp.plan.statement.metadata.template.CreateSchemaTemplateStatement;
 import 
org.apache.iotdb.db.mpp.plan.statement.metadata.template.DeactivateTemplateStatement;
 import 
org.apache.iotdb.db.mpp.plan.statement.metadata.template.DropSchemaTemplateStatement;
@@ -398,6 +399,11 @@ public abstract class StatementVisitor<R, C> {
     return visitStatement(activateTemplateStatement, context);
   }
 
+  public R visitBatchActivateTemplate(
+      BatchActivateTemplateStatement batchActivateTemplateStatement, C 
context) {
+    return visitStatement(batchActivateTemplateStatement, context);
+  }
+
   public R visitShowPathsUsingTemplate(
       ShowPathsUsingTemplateStatement showPathsUsingTemplateStatement, C 
context) {
     return visitStatement(showPathsUsingTemplateStatement, context);
diff --git 
a/server/src/main/java/org/apache/iotdb/db/mpp/plan/statement/metadata/template/DropSchemaTemplateStatement.java
 
b/server/src/main/java/org/apache/iotdb/db/mpp/plan/statement/metadata/template/BatchActivateTemplateStatement.java
similarity index 60%
copy from 
server/src/main/java/org/apache/iotdb/db/mpp/plan/statement/metadata/template/DropSchemaTemplateStatement.java
copy to 
server/src/main/java/org/apache/iotdb/db/mpp/plan/statement/metadata/template/BatchActivateTemplateStatement.java
index 1bf587c1c6..08dd879eec 100644
--- 
a/server/src/main/java/org/apache/iotdb/db/mpp/plan/statement/metadata/template/DropSchemaTemplateStatement.java
+++ 
b/server/src/main/java/org/apache/iotdb/db/mpp/plan/statement/metadata/template/BatchActivateTemplateStatement.java
@@ -19,37 +19,34 @@
 
 package org.apache.iotdb.db.mpp.plan.statement.metadata.template;
 
-import org.apache.iotdb.db.mpp.plan.analyze.QueryType;
-import org.apache.iotdb.db.mpp.plan.statement.IConfigStatement;
+import org.apache.iotdb.commons.path.PartialPath;
+import org.apache.iotdb.db.mpp.plan.statement.Statement;
 import org.apache.iotdb.db.mpp.plan.statement.StatementType;
 import org.apache.iotdb.db.mpp.plan.statement.StatementVisitor;
-import org.apache.iotdb.db.mpp.plan.statement.metadata.ShowStatement;
 
-public class DropSchemaTemplateStatement extends ShowStatement implements 
IConfigStatement {
+import java.util.List;
 
-  private String templateName;
+public class BatchActivateTemplateStatement extends Statement {
 
-  public DropSchemaTemplateStatement(String templateName) {
+  private final List<PartialPath> devicePathList;
+
+  public BatchActivateTemplateStatement(List<PartialPath> devicePathList) {
     super();
-    this.templateName = templateName;
-    this.statementType = StatementType.DROP_TEMPLATE;
+    this.devicePathList = devicePathList;
+    statementType = StatementType.BATCH_ACTIVATE_TEMPLATE;
   }
 
-  public String getTemplateName() {
-    return templateName;
+  @Override
+  public List<? extends PartialPath> getPaths() {
+    return devicePathList;
   }
 
-  public void setTemplateName(String templateName) {
-    this.templateName = templateName;
+  public List<PartialPath> getDevicePathList() {
+    return devicePathList;
   }
 
   @Override
   public <R, C> R accept(StatementVisitor<R, C> visitor, C context) {
-    return visitor.visitDropSchemaTemplate(this, context);
-  }
-
-  @Override
-  public QueryType getQueryType() {
-    return QueryType.WRITE;
+    return visitor.visitBatchActivateTemplate(this, context);
   }
 }
diff --git 
a/server/src/main/java/org/apache/iotdb/db/mpp/plan/statement/metadata/template/DropSchemaTemplateStatement.java
 
b/server/src/main/java/org/apache/iotdb/db/mpp/plan/statement/metadata/template/DropSchemaTemplateStatement.java
index 1bf587c1c6..c8f6bfd928 100644
--- 
a/server/src/main/java/org/apache/iotdb/db/mpp/plan/statement/metadata/template/DropSchemaTemplateStatement.java
+++ 
b/server/src/main/java/org/apache/iotdb/db/mpp/plan/statement/metadata/template/DropSchemaTemplateStatement.java
@@ -19,13 +19,17 @@
 
 package org.apache.iotdb.db.mpp.plan.statement.metadata.template;
 
+import org.apache.iotdb.commons.path.PartialPath;
 import org.apache.iotdb.db.mpp.plan.analyze.QueryType;
 import org.apache.iotdb.db.mpp.plan.statement.IConfigStatement;
+import org.apache.iotdb.db.mpp.plan.statement.Statement;
 import org.apache.iotdb.db.mpp.plan.statement.StatementType;
 import org.apache.iotdb.db.mpp.plan.statement.StatementVisitor;
-import org.apache.iotdb.db.mpp.plan.statement.metadata.ShowStatement;
 
-public class DropSchemaTemplateStatement extends ShowStatement implements 
IConfigStatement {
+import java.util.Collections;
+import java.util.List;
+
+public class DropSchemaTemplateStatement extends Statement implements 
IConfigStatement {
 
   private String templateName;
 
@@ -52,4 +56,9 @@ public class DropSchemaTemplateStatement extends 
ShowStatement implements IConfi
   public QueryType getQueryType() {
     return QueryType.WRITE;
   }
+
+  @Override
+  public List<? extends PartialPath> getPaths() {
+    return Collections.emptyList();
+  }
 }
diff --git 
a/server/src/main/java/org/apache/iotdb/db/service/thrift/impl/ClientRPCServiceImpl.java
 
b/server/src/main/java/org/apache/iotdb/db/service/thrift/impl/ClientRPCServiceImpl.java
index 8d7b212435..2d56e0719c 100644
--- 
a/server/src/main/java/org/apache/iotdb/db/service/thrift/impl/ClientRPCServiceImpl.java
+++ 
b/server/src/main/java/org/apache/iotdb/db/service/thrift/impl/ClientRPCServiceImpl.java
@@ -57,6 +57,7 @@ import 
org.apache.iotdb.db.mpp.plan.statement.metadata.CreateTimeSeriesStatement
 import org.apache.iotdb.db.mpp.plan.statement.metadata.DatabaseSchemaStatement;
 import org.apache.iotdb.db.mpp.plan.statement.metadata.DeleteDatabaseStatement;
 import 
org.apache.iotdb.db.mpp.plan.statement.metadata.DeleteTimeSeriesStatement;
+import 
org.apache.iotdb.db.mpp.plan.statement.metadata.template.BatchActivateTemplateStatement;
 import 
org.apache.iotdb.db.mpp.plan.statement.metadata.template.CreateSchemaTemplateStatement;
 import 
org.apache.iotdb.db.mpp.plan.statement.metadata.template.DropSchemaTemplateStatement;
 import 
org.apache.iotdb.db.mpp.plan.statement.metadata.template.SetSchemaTemplateStatement;
@@ -71,6 +72,7 @@ import org.apache.iotdb.metrics.utils.MetricLevel;
 import org.apache.iotdb.rpc.RpcUtils;
 import org.apache.iotdb.rpc.TSStatusCode;
 import org.apache.iotdb.service.rpc.thrift.ServerProperties;
+import 
org.apache.iotdb.service.rpc.thrift.TCreateTimeseriesOfSchemaTemplateReq;
 import org.apache.iotdb.service.rpc.thrift.TSAggregationQueryReq;
 import org.apache.iotdb.service.rpc.thrift.TSAppendSchemaTemplateReq;
 import org.apache.iotdb.service.rpc.thrift.TSBackupConfigurationResp;
@@ -1867,6 +1869,52 @@ public class ClientRPCServiceImpl implements 
IClientRPCServiceWithHandler {
     }
   }
 
+  @Override
+  public TSStatus 
createTimeseriesOfSchemaTemplate(TCreateTimeseriesOfSchemaTemplateReq req)
+      throws TException {
+    try {
+      IClientSession clientSession = 
SESSION_MANAGER.getCurrSessionAndUpdateIdleTime();
+      if (!SESSION_MANAGER.checkLogin(clientSession)) {
+        return getNotLoggedInStatus();
+      }
+
+      // Step 1: transfer to Statement
+      BatchActivateTemplateStatement statement =
+          
StatementGenerator.createBatchActivateTemplateStatement(req.getDevicePathList());
+
+      if (enableAuditLog) {
+        AuditLogger.log(
+            String.format("batch activate schema template %s", 
req.getDevicePathList()), statement);
+      }
+
+      // permission check
+      TSStatus status = AuthorityChecker.checkAuthority(statement, 
clientSession);
+      if (status.getCode() != TSStatusCode.SUCCESS_STATUS.getStatusCode()) {
+        return status;
+      }
+
+      // Step 2: call the coordinator
+      long queryId = SESSION_MANAGER.requestQueryId();
+      ExecutionResult result =
+          COORDINATOR.execute(
+              statement,
+              queryId,
+              SESSION_MANAGER.getSessionInfo(clientSession),
+              "",
+              partitionFetcher,
+              schemaFetcher);
+
+      return result.status;
+    } catch (IoTDBException e) {
+      return onIoTDBException(e, OperationType.EXECUTE_STATEMENT, 
e.getErrorCode());
+    } catch (Exception e) {
+      return onNPEOrUnexpectedException(
+          e, OperationType.EXECUTE_STATEMENT, 
TSStatusCode.EXECUTE_STATEMENT_ERROR);
+    } finally {
+      SESSION_MANAGER.updateIdleTime();
+    }
+  }
+
   @Override
   public TSStatus handshake(TSyncIdentityInfo info) throws TException {
     // TODO(sync): Check permissions here
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 5043ef89e4..f900c834f4 100644
--- a/session/src/main/java/org/apache/iotdb/session/Session.java
+++ b/session/src/main/java/org/apache/iotdb/session/Session.java
@@ -30,6 +30,7 @@ import org.apache.iotdb.rpc.IoTDBConnectionException;
 import org.apache.iotdb.rpc.NoValidValueException;
 import org.apache.iotdb.rpc.RedirectException;
 import org.apache.iotdb.rpc.StatementExecutionException;
+import 
org.apache.iotdb.service.rpc.thrift.TCreateTimeseriesOfSchemaTemplateReq;
 import org.apache.iotdb.service.rpc.thrift.TSAppendSchemaTemplateReq;
 import org.apache.iotdb.service.rpc.thrift.TSBackupConfigurationResp;
 import org.apache.iotdb.service.rpc.thrift.TSConnectionInfoResp;
@@ -3339,6 +3340,19 @@ public class Session implements ISession {
     return request;
   }
 
+  /**
+   * Create timeseries represented by schema template under given device paths.
+   *
+   * @param devicePathList the target device paths used for timeseries creation
+   */
+  @Override
+  public void createTimeseriesOfSchemaTemplate(List<String> devicePathList)
+      throws IoTDBConnectionException, StatementExecutionException {
+    TCreateTimeseriesOfSchemaTemplateReq request = new 
TCreateTimeseriesOfSchemaTemplateReq();
+    request.setDevicePathList(devicePathList);
+    defaultSessionConnection.createTimeseriesOfSchemaTemplate(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 dfa77ef892..774d42c462 100644
--- a/session/src/main/java/org/apache/iotdb/session/SessionConnection.java
+++ b/session/src/main/java/org/apache/iotdb/session/SessionConnection.java
@@ -30,6 +30,7 @@ import org.apache.iotdb.rpc.RpcTransportFactory;
 import org.apache.iotdb.rpc.RpcUtils;
 import org.apache.iotdb.rpc.StatementExecutionException;
 import org.apache.iotdb.service.rpc.thrift.IClientRPCService;
+import 
org.apache.iotdb.service.rpc.thrift.TCreateTimeseriesOfSchemaTemplateReq;
 import org.apache.iotdb.service.rpc.thrift.TSAggregationQueryReq;
 import org.apache.iotdb.service.rpc.thrift.TSAppendSchemaTemplateReq;
 import org.apache.iotdb.service.rpc.thrift.TSBackupConfigurationResp;
@@ -1057,6 +1058,25 @@ public class SessionConnection {
     }
   }
 
+  protected void 
createTimeseriesOfSchemaTemplate(TCreateTimeseriesOfSchemaTemplateReq request)
+      throws IoTDBConnectionException, StatementExecutionException {
+    request.setSessionId(sessionId);
+    try {
+      RpcUtils.verifySuccess(client.createTimeseriesOfSchemaTemplate(request));
+    } catch (TException e) {
+      if (reconnect()) {
+        try {
+          request.setSessionId(sessionId);
+          
RpcUtils.verifySuccess(client.createTimeseriesOfSchemaTemplate(request));
+        } catch (TException tException) {
+          throw new IoTDBConnectionException(tException);
+        }
+      } else {
+        throw new IoTDBConnectionException(MSG_RECONNECTION_FAIL);
+      }
+    }
+  }
+
   protected TSBackupConfigurationResp getBackupConfiguration()
       throws IoTDBConnectionException, StatementExecutionException {
     TSBackupConfigurationResp execResp;
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 1f598a06e9..4afd111bdd 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
@@ -2401,6 +2401,26 @@ public class SessionPool implements ISessionPool {
     }
   }
 
+  public void createTimeseriesOfSchemaTemplate(List<String> devicePathList)
+      throws StatementExecutionException, IoTDBConnectionException {
+    for (int i = 0; i < RETRY; i++) {
+      ISession session = getSession();
+      try {
+        session.createTimeseriesOfSchemaTemplate(devicePathList);
+        putBack(session);
+        return;
+      } catch (IoTDBConnectionException e) {
+        // TException means the connection is broken, remove it and get a new 
one.
+        logger.warn(
+            String.format("createTimeseriesOfSchemaTemplate [%s] failed", 
devicePathList), 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/thrift/src/main/thrift/client.thrift 
b/thrift/src/main/thrift/client.thrift
index 357589db82..09ed33ac53 100644
--- a/thrift/src/main/thrift/client.thrift
+++ b/thrift/src/main/thrift/client.thrift
@@ -429,6 +429,11 @@ struct TSDropSchemaTemplateReq {
   2: required string templateName
 }
 
+struct TCreateTimeseriesOfSchemaTemplateReq{
+  1: required i64 sessionId
+  2: required list<string> devicePathList
+}
+
 // The sender and receiver need to check some info to confirm validity
 struct TSyncIdentityInfo{
   // Sender needs to tell receiver its identity.
@@ -578,6 +583,8 @@ service IClientRPCService {
 
   common.TSStatus dropSchemaTemplate(1:TSDropSchemaTemplateReq req);
 
+  common.TSStatus 
createTimeseriesOfSchemaTemplate(1:TCreateTimeseriesOfSchemaTemplateReq req);
+
   common.TSStatus handshake(TSyncIdentityInfo info);
 
   common.TSStatus sendPipeData(1:binary buff);


Reply via email to