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