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 a8d9e4b ustzh complete session unsetSchemaTemplate method (#4220)
a8d9e4b is described below
commit a8d9e4b5d7bd4deb42785612f8e5880eab22f398
Author: Hang Zhang <[email protected]>
AuthorDate: Tue Oct 26 00:09:32 2021 +0800
ustzh complete session unsetSchemaTemplate method (#4220)
* finish Session unsetSchemaTemplate
* finish server unsetSchemaTemplate
* add testUnsetSchemaTemplate method
* fixed import *
* fixed MManager import *
* fixed pr issues -v1
* add MManager unit test and format code using spotless
* delete template in use exception unit test
* add unsetSchemaTemplate userguide
---
docs/UserGuide/API/Programming-Java-Native-API.md | 10 +++
.../UserGuide/API/Programming-Java-Native-API.md | 8 ++
.../metadata/DifferentTemplateException.java | 33 ++++++++
.../metadata/NoTemplateOnMNodeException.java | 33 ++++++++
.../metadata/TemplateIsInUseException.java | 33 ++++++++
.../org/apache/iotdb/db/metadata/MManager.java | 31 +++++++
.../iotdb/db/metadata/logfile/MLogWriter.java | 5 ++
.../org/apache/iotdb/db/metadata/mtree/MTree.java | 16 ++++
.../apache/iotdb/db/qp/executor/PlanExecutor.java | 13 +++
.../org/apache/iotdb/db/qp/logical/Operator.java | 4 +-
.../apache/iotdb/db/qp/physical/PhysicalPlan.java | 3 +-
.../qp/physical/crud/UnsetSchemaTemplatePlan.java | 96 ++++++++++++++++++++++
.../org/apache/iotdb/db/service/TSServiceImpl.java | 22 +++++
.../iotdb/db/metadata/MManagerBasicTest.java | 67 +++++++++++++++
.../java/org/apache/iotdb/rpc/TSStatusCode.java | 3 +
.../java/org/apache/iotdb/session/Session.java | 15 ++++
.../apache/iotdb/session/SessionConnection.java | 20 +++++
.../java/org/apache/iotdb/session/SessionTest.java | 94 +++++++++++++++++++++
thrift/src/main/thrift/rpc.thrift | 10 ++-
19 files changed, 513 insertions(+), 3 deletions(-)
diff --git a/docs/UserGuide/API/Programming-Java-Native-API.md
b/docs/UserGuide/API/Programming-Java-Native-API.md
index 033fefe..18bae1a 100644
--- a/docs/UserGuide/API/Programming-Java-Native-API.md
+++ b/docs/UserGuide/API/Programming-Java-Native-API.md
@@ -428,6 +428,16 @@ void createSchemaTemplate
```
+```
+
+void unsetSchemaTemplate(String prefixPath, 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'.
+
+Attention: Unsetting the template named 'templateName' from node at path
'prefixPath' or descendant nodes which have already inserted records using
template is **not supported**.
+
### Cluster information related APIs (only works in the cluster mode)
Cluster information related APIs allow users get the cluster info like where a
storage group will be
diff --git a/docs/zh/UserGuide/API/Programming-Java-Native-API.md
b/docs/zh/UserGuide/API/Programming-Java-Native-API.md
index c80636f..2a93e22 100644
--- a/docs/zh/UserGuide/API/Programming-Java-Native-API.md
+++ b/docs/zh/UserGuide/API/Programming-Java-Native-API.md
@@ -237,6 +237,14 @@ void createSchemaTemplate(
void setSchemaTemplate(String templateName, String prefixPath)
```
+```
+void unsetSchemaTemplate(String prefixPath, String templateName)
+```
+
+*
卸载'prefixPath'路径下的名为'templateName'的物理量模板。你需要保证给定的路径'prefixPath'下需要有名为'templateName'的物理量模板。
+
+注意:目前不支持从曾经在'prefixPath'路径及其后代节点使用模板插入数据后(即使数据已被删除)卸载模板。
+
### 测试接口说明
* 测试 testInsertRecords,不实际写入数据,只将数据传输到 server 即返回。
diff --git
a/server/src/main/java/org/apache/iotdb/db/exception/metadata/DifferentTemplateException.java
b/server/src/main/java/org/apache/iotdb/db/exception/metadata/DifferentTemplateException.java
new file mode 100644
index 0000000..49ce984
--- /dev/null
+++
b/server/src/main/java/org/apache/iotdb/db/exception/metadata/DifferentTemplateException.java
@@ -0,0 +1,33 @@
+/*
+ * 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.exception.metadata;
+
+import org.apache.iotdb.rpc.TSStatusCode;
+
+public class DifferentTemplateException extends MetadataException {
+
+ public DifferentTemplateException(String path, String templateName) {
+ super(
+ String.format("The template on " + path + " is different from " +
templateName),
+ TSStatusCode.DIFFERENT_TEMPLATE.getStatusCode(),
+ true);
+ }
+}
diff --git
a/server/src/main/java/org/apache/iotdb/db/exception/metadata/NoTemplateOnMNodeException.java
b/server/src/main/java/org/apache/iotdb/db/exception/metadata/NoTemplateOnMNodeException.java
new file mode 100644
index 0000000..0e5d4e8
--- /dev/null
+++
b/server/src/main/java/org/apache/iotdb/db/exception/metadata/NoTemplateOnMNodeException.java
@@ -0,0 +1,33 @@
+/*
+ * 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.exception.metadata;
+
+import org.apache.iotdb.rpc.TSStatusCode;
+
+public class NoTemplateOnMNodeException extends MetadataException {
+
+ public NoTemplateOnMNodeException(String path) {
+ super(
+ String.format("NO template on " + path),
+ TSStatusCode.NO_TEMPLATE_ON_MNODE.getStatusCode(),
+ true);
+ }
+}
diff --git
a/server/src/main/java/org/apache/iotdb/db/exception/metadata/TemplateIsInUseException.java
b/server/src/main/java/org/apache/iotdb/db/exception/metadata/TemplateIsInUseException.java
new file mode 100644
index 0000000..923832d
--- /dev/null
+++
b/server/src/main/java/org/apache/iotdb/db/exception/metadata/TemplateIsInUseException.java
@@ -0,0 +1,33 @@
+/*
+ * 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.exception.metadata;
+
+import org.apache.iotdb.rpc.TSStatusCode;
+
+public class TemplateIsInUseException extends MetadataException {
+
+ public TemplateIsInUseException(String path) {
+ super(
+ String.format("Template is in use on " + path),
+ TSStatusCode.TEMPLATE_IS_IN_USE.getStatusCode(),
+ true);
+ }
+}
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 153fcbf..455d1d5 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
@@ -26,12 +26,15 @@ import
org.apache.iotdb.db.engine.trigger.executor.TriggerEngine;
import org.apache.iotdb.db.exception.metadata.AliasAlreadyExistException;
import org.apache.iotdb.db.exception.metadata.DataTypeMismatchException;
import org.apache.iotdb.db.exception.metadata.DeleteFailedException;
+import org.apache.iotdb.db.exception.metadata.DifferentTemplateException;
import org.apache.iotdb.db.exception.metadata.MNodeTypeMismatchException;
import org.apache.iotdb.db.exception.metadata.MetadataException;
+import org.apache.iotdb.db.exception.metadata.NoTemplateOnMNodeException;
import org.apache.iotdb.db.exception.metadata.PathAlreadyExistException;
import org.apache.iotdb.db.exception.metadata.PathNotExistException;
import org.apache.iotdb.db.exception.metadata.StorageGroupAlreadySetException;
import org.apache.iotdb.db.exception.metadata.StorageGroupNotSetException;
+import org.apache.iotdb.db.exception.metadata.TemplateIsInUseException;
import org.apache.iotdb.db.metadata.lastCache.LastCacheManager;
import org.apache.iotdb.db.metadata.logfile.MLogReader;
import org.apache.iotdb.db.metadata.logfile.MLogWriter;
@@ -55,6 +58,7 @@ import org.apache.iotdb.db.qp.physical.crud.InsertPlan;
import org.apache.iotdb.db.qp.physical.crud.InsertRowPlan;
import org.apache.iotdb.db.qp.physical.crud.InsertTabletPlan;
import org.apache.iotdb.db.qp.physical.crud.SetSchemaTemplatePlan;
+import org.apache.iotdb.db.qp.physical.crud.UnsetSchemaTemplatePlan;
import org.apache.iotdb.db.qp.physical.sys.AutoCreateDeviceMNodePlan;
import org.apache.iotdb.db.qp.physical.sys.ChangeAliasPlan;
import org.apache.iotdb.db.qp.physical.sys.ChangeTagOffsetPlan;
@@ -428,6 +432,9 @@ public class MManager {
AutoCreateDeviceMNodePlan autoCreateDeviceMNodePlan =
(AutoCreateDeviceMNodePlan) plan;
autoCreateDeviceMNode(autoCreateDeviceMNodePlan);
break;
+ case UNSET_SCHEMA_TEMPLATE:
+ UnsetSchemaTemplatePlan unsetSchemaTemplatePlan =
(UnsetSchemaTemplatePlan) plan;
+ unsetSchemaTemplate(unsetSchemaTemplatePlan);
default:
logger.error("Unrecognizable command {}", plan.getOperatorType());
}
@@ -2130,6 +2137,30 @@ public class MManager {
}
}
+ public synchronized void unsetSchemaTemplate(UnsetSchemaTemplatePlan plan)
+ throws MetadataException {
+ // get mnode should be atomic
+ try {
+ PartialPath path = new PartialPath(plan.getPrefixPath());
+ IMNode node = mtree.getNodeByPath(path);
+ if (node.getSchemaTemplate() == null) {
+ throw new NoTemplateOnMNodeException(plan.getPrefixPath());
+ } else if
(!node.getSchemaTemplate().getName().equals(plan.getTemplateName())) {
+ throw new DifferentTemplateException(plan.getPrefixPath(),
plan.getTemplateName());
+ } else if (node.isUseTemplate()) {
+ throw new TemplateIsInUseException(plan.getPrefixPath());
+ }
+ mtree.checkTemplateInUseOnLowerNode(node);
+ node.setSchemaTemplate(null);
+ // write wal
+ if (!isRecovering) {
+ logWriter.unsetSchemaTemplate(plan);
+ }
+ } catch (IOException e) {
+ throw new MetadataException(e);
+ }
+ }
+
public void setUsingSchemaTemplate(SetUsingSchemaTemplatePlan plan) throws
MetadataException {
try {
setUsingSchemaTemplate(getDeviceNode(plan.getPrefixPath()));
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 36f3b30..d4791ba 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
@@ -27,6 +27,7 @@ import org.apache.iotdb.db.metadata.mnode.IStorageGroupMNode;
import org.apache.iotdb.db.qp.physical.PhysicalPlan;
import org.apache.iotdb.db.qp.physical.crud.CreateTemplatePlan;
import org.apache.iotdb.db.qp.physical.crud.SetSchemaTemplatePlan;
+import org.apache.iotdb.db.qp.physical.crud.UnsetSchemaTemplatePlan;
import org.apache.iotdb.db.qp.physical.sys.AutoCreateDeviceMNodePlan;
import org.apache.iotdb.db.qp.physical.sys.ChangeAliasPlan;
import org.apache.iotdb.db.qp.physical.sys.ChangeTagOffsetPlan;
@@ -172,6 +173,10 @@ public class MLogWriter implements AutoCloseable {
putLog(plan);
}
+ public void unsetSchemaTemplate(UnsetSchemaTemplatePlan 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/mtree/MTree.java
b/server/src/main/java/org/apache/iotdb/db/metadata/mtree/MTree.java
index 219b27d..d51e8e7 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
@@ -29,6 +29,7 @@ import
org.apache.iotdb.db.exception.metadata.PathAlreadyExistException;
import org.apache.iotdb.db.exception.metadata.PathNotExistException;
import org.apache.iotdb.db.exception.metadata.StorageGroupAlreadySetException;
import org.apache.iotdb.db.exception.metadata.StorageGroupNotSetException;
+import org.apache.iotdb.db.exception.metadata.TemplateIsInUseException;
import org.apache.iotdb.db.metadata.MManager.StorageGroupFilter;
import org.apache.iotdb.db.metadata.MetadataConstant;
import org.apache.iotdb.db.metadata.PartialPath;
@@ -1346,6 +1347,21 @@ public class MTree implements Serializable {
checkTemplateOnSubtree(child);
}
}
+
+ public void checkTemplateInUseOnLowerNode(IMNode node) throws
TemplateIsInUseException {
+ if (node.isMeasurement()) {
+ return;
+ }
+ for (IMNode child : node.getChildren().values()) {
+ if (child.isMeasurement()) {
+ continue;
+ }
+ if (child.isUseTemplate()) {
+ throw new TemplateIsInUseException(child.getFullPath());
+ }
+ checkTemplateInUseOnLowerNode(child);
+ }
+ }
// endregion
// region TestOnly Interface
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 638941c..fe4c59f 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
@@ -82,6 +82,7 @@ import org.apache.iotdb.db.qp.physical.crud.QueryPlan;
import org.apache.iotdb.db.qp.physical.crud.RawDataQueryPlan;
import org.apache.iotdb.db.qp.physical.crud.SetSchemaTemplatePlan;
import org.apache.iotdb.db.qp.physical.crud.UDTFPlan;
+import org.apache.iotdb.db.qp.physical.crud.UnsetSchemaTemplatePlan;
import org.apache.iotdb.db.qp.physical.sys.AlterTimeSeriesPlan;
import org.apache.iotdb.db.qp.physical.sys.AuthorPlan;
import org.apache.iotdb.db.qp.physical.sys.CountPlan;
@@ -363,6 +364,8 @@ public class PlanExecutor implements IPlanExecutor {
return createSchemaTemplate((CreateTemplatePlan) plan);
case SET_SCHEMA_TEMPLATE:
return setSchemaTemplate((SetSchemaTemplatePlan) plan);
+ case UNSET_SCHEMA_TEMPLATE:
+ return unsetSchemaTemplate((UnsetSchemaTemplatePlan) plan);
case CREATE_CONTINUOUS_QUERY:
return operateCreateContinuousQuery((CreateContinuousQueryPlan) plan);
case DROP_CONTINUOUS_QUERY:
@@ -396,6 +399,16 @@ public class PlanExecutor implements IPlanExecutor {
return true;
}
+ private boolean unsetSchemaTemplate(UnsetSchemaTemplatePlan
unsetSchemaTemplatePlan)
+ throws QueryProcessException {
+ try {
+ IoTDB.metaManager.unsetSchemaTemplate(unsetSchemaTemplatePlan);
+ } catch (MetadataException e) {
+ throw new QueryProcessException(e);
+ }
+ return true;
+ }
+
private boolean operateCreateFunction(CreateFunctionPlan plan) throws
UDFRegistrationException {
UDFRegistrationService.getInstance().register(plan.getUdfName(),
plan.getClassName(), true);
return true;
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 05432cb..483415e 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
@@ -173,6 +173,8 @@ public abstract class Operator {
SHOW_CONTINUOUS_QUERIES,
SET_SYSTEM_MODE,
- SETTLE
+ SETTLE,
+
+ UNSET_SCHEMA_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 a8d3e31..e0371ef 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
@@ -484,7 +484,8 @@ public abstract class PhysicalPlan {
CREATE_FUNCTION,
DROP_FUNCTION,
SELECT_INTO,
- SET_SYSTEM_MODE
+ SET_SYSTEM_MODE,
+ UNSET_SCHEMA_TEMPLATE
}
public long getIndex() {
diff --git
a/server/src/main/java/org/apache/iotdb/db/qp/physical/crud/UnsetSchemaTemplatePlan.java
b/server/src/main/java/org/apache/iotdb/db/qp/physical/crud/UnsetSchemaTemplatePlan.java
new file mode 100644
index 0000000..6a4716e
--- /dev/null
+++
b/server/src/main/java/org/apache/iotdb/db/qp/physical/crud/UnsetSchemaTemplatePlan.java
@@ -0,0 +1,96 @@
+/*
+ * 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.crud;
+
+import org.apache.iotdb.db.metadata.PartialPath;
+import org.apache.iotdb.db.qp.logical.Operator;
+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 UnsetSchemaTemplatePlan extends PhysicalPlan {
+
+ String prefixPath;
+ String templateName;
+
+ public UnsetSchemaTemplatePlan() {
+ super(false, Operator.OperatorType.UNSET_SCHEMA_TEMPLATE);
+ }
+
+ public UnsetSchemaTemplatePlan(String prefixPath, String templateName) {
+ super(false, Operator.OperatorType.UNSET_SCHEMA_TEMPLATE);
+ this.prefixPath = prefixPath;
+ this.templateName = templateName;
+ }
+
+ public String getPrefixPath() {
+ return prefixPath;
+ }
+
+ public void setPrefixPath(String prefixPath) {
+ this.prefixPath = prefixPath;
+ }
+
+ public String getTemplateName() {
+ return templateName;
+ }
+
+ public void setTemplateName(String templateName) {
+ this.templateName = templateName;
+ }
+
+ @Override
+ public List<PartialPath> getPaths() {
+ return null;
+ }
+
+ @Override
+ public void serialize(ByteBuffer buffer) {
+ buffer.put((byte) PhysicalPlanType.UNSET_SCHEMA_TEMPLATE.ordinal());
+
+ ReadWriteIOUtils.write(prefixPath, buffer);
+ ReadWriteIOUtils.write(templateName, buffer);
+
+ buffer.putLong(index);
+ }
+
+ @Override
+ public void deserialize(ByteBuffer buffer) {
+ prefixPath = ReadWriteIOUtils.readString(buffer);
+ templateName = ReadWriteIOUtils.readString(buffer);
+
+ this.index = buffer.getLong();
+ }
+
+ @Override
+ public void serialize(DataOutputStream stream) throws IOException {
+ stream.writeByte((byte) PhysicalPlanType.UNSET_SCHEMA_TEMPLATE.ordinal());
+
+ ReadWriteIOUtils.write(prefixPath, stream);
+ ReadWriteIOUtils.write(templateName, stream);
+
+ stream.writeLong(index);
+ }
+}
diff --git
a/server/src/main/java/org/apache/iotdb/db/service/TSServiceImpl.java
b/server/src/main/java/org/apache/iotdb/db/service/TSServiceImpl.java
index 3c658a9..6a8cc7e 100644
--- a/server/src/main/java/org/apache/iotdb/db/service/TSServiceImpl.java
+++ b/server/src/main/java/org/apache/iotdb/db/service/TSServiceImpl.java
@@ -63,6 +63,7 @@ import org.apache.iotdb.db.qp.physical.crud.SelectIntoPlan;
import org.apache.iotdb.db.qp.physical.crud.SetSchemaTemplatePlan;
import org.apache.iotdb.db.qp.physical.crud.UDFPlan;
import org.apache.iotdb.db.qp.physical.crud.UDTFPlan;
+import org.apache.iotdb.db.qp.physical.crud.UnsetSchemaTemplatePlan;
import org.apache.iotdb.db.qp.physical.sys.AuthorPlan;
import org.apache.iotdb.db.qp.physical.sys.CreateAlignedTimeSeriesPlan;
import org.apache.iotdb.db.qp.physical.sys.CreateMultiTimeSeriesPlan;
@@ -129,6 +130,7 @@ import
org.apache.iotdb.service.rpc.thrift.TSSetSchemaTemplateReq;
import org.apache.iotdb.service.rpc.thrift.TSSetTimeZoneReq;
import org.apache.iotdb.service.rpc.thrift.TSStatus;
import org.apache.iotdb.service.rpc.thrift.TSTracingInfo;
+import org.apache.iotdb.service.rpc.thrift.TSUnsetSchemaTemplateReq;
import
org.apache.iotdb.tsfile.exception.filter.QueryFilterOptimizationException;
import org.apache.iotdb.tsfile.exception.write.UnSupportedDataTypeException;
import org.apache.iotdb.tsfile.file.metadata.enums.CompressionType;
@@ -2121,6 +2123,26 @@ public class TSServiceImpl implements TSIService.Iface {
return status != null ? status : executeNonQueryPlan(plan);
}
+ @Override
+ public TSStatus unsetSchemaTemplate(TSUnsetSchemaTemplateReq req) throws
TException {
+ if (!checkLogin(req.getSessionId())) {
+ return getNotLoggedInStatus();
+ }
+
+ if (AUDIT_LOGGER.isDebugEnabled()) {
+ AUDIT_LOGGER.debug(
+ "Session-{} unset device template {}.{}",
+ sessionManager.getCurrSessionId(),
+ req.getPrefixPath(),
+ req.getTemplateName());
+ }
+
+ UnsetSchemaTemplatePlan plan = new UnsetSchemaTemplatePlan(req.prefixPath,
req.templateName);
+
+ TSStatus status = checkAuthority(plan, req.getSessionId());
+ return status != null ? status : executeNonQueryPlan(plan);
+ }
+
private TSStatus checkAuthority(PhysicalPlan plan, long sessionId) {
List<PartialPath> paths = plan.getPaths();
try {
diff --git
a/server/src/test/java/org/apache/iotdb/db/metadata/MManagerBasicTest.java
b/server/src/test/java/org/apache/iotdb/db/metadata/MManagerBasicTest.java
index 6bd54a1..d694c90 100644
--- a/server/src/test/java/org/apache/iotdb/db/metadata/MManagerBasicTest.java
+++ b/server/src/test/java/org/apache/iotdb/db/metadata/MManagerBasicTest.java
@@ -30,6 +30,7 @@ import
org.apache.iotdb.db.qp.physical.crud.CreateTemplatePlan;
import org.apache.iotdb.db.qp.physical.crud.InsertPlan;
import org.apache.iotdb.db.qp.physical.crud.InsertRowPlan;
import org.apache.iotdb.db.qp.physical.crud.SetSchemaTemplatePlan;
+import org.apache.iotdb.db.qp.physical.crud.UnsetSchemaTemplatePlan;
import org.apache.iotdb.db.qp.physical.sys.CreateTimeSeriesPlan;
import org.apache.iotdb.db.qp.physical.sys.ShowTimeSeriesPlan;
import org.apache.iotdb.db.query.dataset.ShowTimeSeriesResult;
@@ -942,6 +943,72 @@ public class MManagerBasicTest {
}
@Test
+ public void testUnsetSchemaTemplate() throws MetadataException {
+
+ List<List<String>> measurementList = new ArrayList<>();
+ measurementList.add(Collections.singletonList("s1"));
+ measurementList.add(Collections.singletonList("s2"));
+ measurementList.add(Collections.singletonList("s3"));
+
+ List<List<TSDataType>> dataTypeList = new ArrayList<>();
+ dataTypeList.add(Collections.singletonList(TSDataType.INT64));
+ dataTypeList.add(Collections.singletonList(TSDataType.INT64));
+ dataTypeList.add(Collections.singletonList(TSDataType.INT64));
+
+ List<List<TSEncoding>> encodingList = new ArrayList<>();
+ encodingList.add(Collections.singletonList(TSEncoding.RLE));
+ encodingList.add(Collections.singletonList(TSEncoding.RLE));
+ encodingList.add(Collections.singletonList(TSEncoding.RLE));
+
+ List<CompressionType> compressionTypes = new ArrayList<>();
+ for (int i = 0; i < 3; i++) {
+ compressionTypes.add(CompressionType.SNAPPY);
+ }
+ List<String> schemaNames = new ArrayList<>();
+ schemaNames.add("s1");
+ schemaNames.add("s2");
+ schemaNames.add("s3");
+
+ CreateTemplatePlan createTemplatePlan =
+ new CreateTemplatePlan(
+ "template1",
+ schemaNames,
+ measurementList,
+ dataTypeList,
+ encodingList,
+ compressionTypes);
+ SetSchemaTemplatePlan setSchemaTemplatePlan =
+ new SetSchemaTemplatePlan("template1", "root.sg.1");
+ UnsetSchemaTemplatePlan unsetSchemaTemplatePlan =
+ new UnsetSchemaTemplatePlan("root.sg.1", "template1");
+ MManager manager = IoTDB.metaManager;
+ manager.createSchemaTemplate(createTemplatePlan);
+
+ // path does not exist test
+ try {
+ manager.unsetSchemaTemplate(unsetSchemaTemplatePlan);
+ fail("No exception thrown.");
+ } catch (Exception e) {
+ assertEquals("Path [root.sg.1] does not exist", e.getMessage());
+ }
+
+ manager.setSchemaTemplate(setSchemaTemplatePlan);
+
+ // template unset test
+ manager.unsetSchemaTemplate(unsetSchemaTemplatePlan);
+ manager.setSchemaTemplate(setSchemaTemplatePlan);
+
+ // no template on path test
+ manager.unsetSchemaTemplate(unsetSchemaTemplatePlan);
+ try {
+ manager.unsetSchemaTemplate(unsetSchemaTemplatePlan);
+ fail("No exception thrown.");
+ } catch (Exception e) {
+ assertEquals("NO template on root.sg.1", e.getMessage());
+ }
+ }
+
+ @Test
public void testTemplateAndTimeSeriesCompatibility() throws
MetadataException {
CreateTemplatePlan plan = getCreateTemplatePlan();
MManager manager = IoTDB.metaManager;
diff --git a/service-rpc/src/main/java/org/apache/iotdb/rpc/TSStatusCode.java
b/service-rpc/src/main/java/org/apache/iotdb/rpc/TSStatusCode.java
index c8effe2..5c6a6f3 100644
--- a/service-rpc/src/main/java/org/apache/iotdb/rpc/TSStatusCode.java
+++ b/service-rpc/src/main/java/org/apache/iotdb/rpc/TSStatusCode.java
@@ -54,6 +54,9 @@ public enum TSStatusCode {
UNDEFINED_TEMPLATE(321),
STORAGE_GROUP_NOT_EXIST(322),
CONTINUOUS_QUERY_ERROR(323),
+ NO_TEMPLATE_ON_MNODE(324),
+ DIFFERENT_TEMPLATE(325),
+ TEMPLATE_IS_IN_USE(326),
EXECUTE_STATEMENT_ERROR(400),
SQL_PARSE_ERROR(401),
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 48833aa..d6c71cd 100644
--- a/session/src/main/java/org/apache/iotdb/session/Session.java
+++ b/session/src/main/java/org/apache/iotdb/session/Session.java
@@ -37,6 +37,7 @@ import org.apache.iotdb.service.rpc.thrift.TSInsertTabletReq;
import org.apache.iotdb.service.rpc.thrift.TSInsertTabletsReq;
import org.apache.iotdb.service.rpc.thrift.TSProtocolVersion;
import org.apache.iotdb.service.rpc.thrift.TSSetSchemaTemplateReq;
+import org.apache.iotdb.service.rpc.thrift.TSUnsetSchemaTemplateReq;
import org.apache.iotdb.session.util.SessionUtils;
import org.apache.iotdb.session.util.ThreadUtils;
import org.apache.iotdb.tsfile.common.conf.TSFileConfig;
@@ -1985,6 +1986,12 @@ public class Session {
defaultSessionConnection.createSchemaTemplate(request);
}
+ public void unsetSchemaTemplate(String prefixPath, String templateName)
+ throws IoTDBConnectionException, StatementExecutionException {
+ TSUnsetSchemaTemplateReq request = getTSUnsetSchemaTemplateReq(prefixPath,
templateName);
+ defaultSessionConnection.unsetSchemaTemplate(request);
+ }
+
private TSSetSchemaTemplateReq getTSSetSchemaTemplateReq(String
templateName, String prefixPath) {
TSSetSchemaTemplateReq request = new TSSetSchemaTemplateReq();
request.setTemplateName(templateName);
@@ -2021,6 +2028,14 @@ public class Session {
return request;
}
+ private TSUnsetSchemaTemplateReq getTSUnsetSchemaTemplateReq(
+ String prefixPath, String templateName) {
+ TSUnsetSchemaTemplateReq request = new TSUnsetSchemaTemplateReq();
+ request.setPrefixPath(prefixPath);
+ 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 9f39e7e..ec899d1 100644
--- a/session/src/main/java/org/apache/iotdb/session/SessionConnection.java
+++ b/session/src/main/java/org/apache/iotdb/session/SessionConnection.java
@@ -49,6 +49,7 @@ import org.apache.iotdb.service.rpc.thrift.TSRawDataQueryReq;
import org.apache.iotdb.service.rpc.thrift.TSSetSchemaTemplateReq;
import org.apache.iotdb.service.rpc.thrift.TSSetTimeZoneReq;
import org.apache.iotdb.service.rpc.thrift.TSStatus;
+import org.apache.iotdb.service.rpc.thrift.TSUnsetSchemaTemplateReq;
import org.apache.iotdb.session.util.SessionUtils;
import org.apache.thrift.TException;
@@ -819,6 +820,25 @@ public class SessionConnection {
}
}
+ protected void unsetSchemaTemplate(TSUnsetSchemaTemplateReq request)
+ throws IoTDBConnectionException, StatementExecutionException {
+ request.setSessionId(sessionId);
+ try {
+ RpcUtils.verifySuccess(client.unsetSchemaTemplate(request));
+ } catch (TException e) {
+ if (reconnect()) {
+ try {
+ request.setSessionId(sessionId);
+ RpcUtils.verifySuccess(client.unsetSchemaTemplate(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/test/java/org/apache/iotdb/session/SessionTest.java
b/session/src/test/java/org/apache/iotdb/session/SessionTest.java
index 84ef06f..0c56771 100644
--- a/session/src/test/java/org/apache/iotdb/session/SessionTest.java
+++ b/session/src/test/java/org/apache/iotdb/session/SessionTest.java
@@ -288,4 +288,98 @@ public class SessionTest {
fail();
}
}
+
+ @Test
+ public void testUnsetSchemaTemplate()
+ throws IoTDBConnectionException, StatementExecutionException {
+ session = new Session("127.0.0.1", 6667, "root", "root",
ZoneId.of("+05:00"));
+ session.open();
+
+ List<List<String>> measurementList = new ArrayList<>();
+ measurementList.add(Collections.singletonList("s1"));
+ measurementList.add(Collections.singletonList("s2"));
+ measurementList.add(Collections.singletonList("s3"));
+
+ List<List<TSDataType>> dataTypeList = new ArrayList<>();
+ dataTypeList.add(Collections.singletonList(TSDataType.INT64));
+ dataTypeList.add(Collections.singletonList(TSDataType.INT64));
+ dataTypeList.add(Collections.singletonList(TSDataType.INT64));
+
+ List<List<TSEncoding>> encodingList = new ArrayList<>();
+ encodingList.add(Collections.singletonList(TSEncoding.RLE));
+ encodingList.add(Collections.singletonList(TSEncoding.RLE));
+ encodingList.add(Collections.singletonList(TSEncoding.RLE));
+
+ List<CompressionType> compressionTypes = new ArrayList<>();
+ for (int i = 0; i < 3; i++) {
+ compressionTypes.add(CompressionType.SNAPPY);
+ }
+ List<String> schemaNames = new ArrayList<>();
+ schemaNames.add("s1");
+ schemaNames.add("s2");
+ schemaNames.add("s3");
+
+ session.createSchemaTemplate(
+ "template1", schemaNames, measurementList, dataTypeList, encodingList,
compressionTypes);
+
+ // path does not exist test
+ try {
+ session.unsetSchemaTemplate("root.sg.1", "template1");
+ fail("No exception thrown.");
+ } catch (Exception e) {
+ assertEquals("304: Path [root.sg.1] does not exist", e.getMessage());
+ }
+
+ session.setSchemaTemplate("template1", "root.sg.1");
+
+ // template already exists test
+ try {
+ session.setSchemaTemplate("template1", "root.sg.1");
+ fail("No exception thrown.");
+ } catch (Exception e) {
+ assertEquals("303: Template already exists on root.sg.1",
e.getMessage());
+ }
+
+ // template unset test
+ session.unsetSchemaTemplate("root.sg.1", "template1");
+
+ session.setSchemaTemplate("template1", "root.sg.1");
+
+ // no template on path test
+ session.unsetSchemaTemplate("root.sg.1", "template1");
+ try {
+ session.unsetSchemaTemplate("root.sg.1", "template1");
+ fail("No exception thrown.");
+ } catch (Exception e) {
+ assertEquals("324: NO template on root.sg.1", e.getMessage());
+ }
+
+ // template is in use test
+ session.setSchemaTemplate("template1", "root.sg.1");
+
+ String deviceId = "root.sg.1.cd";
+ List<String> measurements = new ArrayList<>();
+ List<TSDataType> types = new ArrayList<>();
+ measurements.add("s1");
+ measurements.add("s2");
+ measurements.add("s3");
+ types.add(TSDataType.INT64);
+ types.add(TSDataType.INT64);
+ types.add(TSDataType.INT64);
+
+ for (long time = 0; time < 5; time++) {
+ List<Object> values = new ArrayList<>();
+ values.add(1L);
+ values.add(2L);
+ values.add(3L);
+ session.insertRecord(deviceId, time, measurements, types, values);
+ }
+
+ try {
+ session.unsetSchemaTemplate("root.sg.1", "template1");
+ fail("No exception thrown.");
+ } catch (Exception e) {
+ assertEquals("326: Template is in use on root.sg.1.cd", e.getMessage());
+ }
+ }
}
diff --git a/thrift/src/main/thrift/rpc.thrift
b/thrift/src/main/thrift/rpc.thrift
index c9ed36b..f8ae06c 100644
--- a/thrift/src/main/thrift/rpc.thrift
+++ b/thrift/src/main/thrift/rpc.thrift
@@ -369,6 +369,12 @@ struct TSCreateSchemaTemplateReq {
7: required list<i32> compressors
}
+struct TSUnsetSchemaTemplateReq {
+ 1: required i64 sessionId
+ 2: required string prefixPath
+ 3: required string templateName
+}
+
service TSIService {
TSOpenSessionResp openSession(1:TSOpenSessionReq req);
@@ -447,4 +453,6 @@ service TSIService {
TSStatus createSchemaTemplate(1:TSCreateSchemaTemplateReq req);
TSStatus setSchemaTemplate(1:TSSetSchemaTemplateReq req);
-}
+
+ TSStatus unsetSchemaTemplate(1:TSUnsetSchemaTemplateReq req);
+}
\ No newline at end of file