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

justinchen pushed a commit to branch template-fix
in repository https://gitbox.apache.org/repos/asf/iotdb.git


The following commit(s) were added to refs/heads/template-fix by this push:
     new ea0d3adbee0 shop
ea0d3adbee0 is described below

commit ea0d3adbee0a43a2bf21c9597f916a18a9f35333
Author: Caideyipi <[email protected]>
AuthorDate: Wed Feb 4 11:15:56 2026 +0800

    shop
---
 .../mtree/impl/mem/MTreeBelowSGMemoryImpl.java     | 18 +++----
 .../mtree/impl/pbtree/MTreeBelowSGCachedImpl.java  | 58 +++++++++++++---------
 2 files changed, 44 insertions(+), 32 deletions(-)

diff --git 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/schemaengine/schemaregion/mtree/impl/mem/MTreeBelowSGMemoryImpl.java
 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/schemaengine/schemaregion/mtree/impl/mem/MTreeBelowSGMemoryImpl.java
index 9cb3270cd82..7b6f890dc44 100644
--- 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/schemaengine/schemaregion/mtree/impl/mem/MTreeBelowSGMemoryImpl.java
+++ 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/schemaengine/schemaregion/mtree/impl/mem/MTreeBelowSGMemoryImpl.java
@@ -151,7 +151,7 @@ public class MTreeBelowSGMemoryImpl {
   private final Function<IMeasurementMNode<IMemMNode>, Map<String, String>> 
attributeGetter;
   private final IMNodeFactory<IMemMNode> nodeFactory =
       MNodeFactoryLoader.getInstance().getMemMNodeIMNodeFactory();
-  private final int levelOfSG;
+  private final int levelOfDB;
   private final MemSchemaRegionStatistics regionStatistics;
 
   // region MTree initialization, clear and serialization
@@ -165,7 +165,7 @@ public class MTreeBelowSGMemoryImpl {
     this.regionStatistics = regionStatistics;
     this.databaseMNode = store.getRoot();
     this.rootNode = store.generatePrefix(databasePath);
-    levelOfSG = databasePath.getNodeLength() - 1;
+    levelOfDB = databasePath.getNodeLength() - 1;
     this.tagGetter = tagGetter;
     this.attributeGetter = attributeGetter;
   }
@@ -180,7 +180,7 @@ public class MTreeBelowSGMemoryImpl {
     this.regionStatistics = regionStatistics;
     this.databaseMNode = store.getRoot();
     this.rootNode = store.generatePrefix(databasePath);
-    levelOfSG = databasePath.getNodeLength() - 1;
+    levelOfDB = databasePath.getNodeLength() - 1;
     this.tagGetter = tagGetter;
     this.attributeGetter = attributeGetter;
   }
@@ -423,14 +423,14 @@ public class MTreeBelowSGMemoryImpl {
       throws MetadataException {
     final String[] nodeNames = devicePath.getNodes();
     MetaFormatUtils.checkTimeseries(devicePath);
-    if (nodeNames.length == levelOfSG + 1) {
+    if (nodeNames.length == levelOfDB + 1) {
       return null;
     }
     IMemMNode cur = databaseMNode;
     IMemMNode child;
     String childName;
     // e.g, path = root.sg.d1.s1,  create internal nodes and set cur to sg 
node, parent of d1
-    for (int i = levelOfSG + 1; i < nodeNames.length - 1; i++) {
+    for (int i = levelOfDB + 1; i < nodeNames.length - 1; i++) {
       childName = nodeNames[i];
       child = cur.getChild(childName);
       if (child == null) {
@@ -808,7 +808,7 @@ public class MTreeBelowSGMemoryImpl {
     final String[] nodeNames = deviceId.getNodes();
     IMemMNode cur = databaseMNode;
     IMemMNode child;
-    for (int i = levelOfSG + 1; i < nodeNames.length; i++) {
+    for (int i = levelOfDB + 1; i < nodeNames.length; i++) {
       child = cur.getChild(nodeNames[i]);
       if (child == null) {
         if (cur.isDevice()
@@ -964,7 +964,7 @@ public class MTreeBelowSGMemoryImpl {
     final String[] nodes = path.getNodes();
     IMemMNode cur = databaseMNode;
     IMemMNode next;
-    for (int i = levelOfSG + 1; i < nodes.length; i++) {
+    for (int i = levelOfDB + 1; i < nodes.length; i++) {
       next = cur.getChild(nodes[i]);
       if (next == null) {
         throw new PathNotExistException(path.getFullPath(), true);
@@ -999,7 +999,7 @@ public class MTreeBelowSGMemoryImpl {
       throws MetadataException {
     final String[] nodes = activatePath.getNodes();
     IMemMNode cur = databaseMNode;
-    for (int i = levelOfSG + 1; i < nodes.length; i++) {
+    for (int i = levelOfDB + 1; i < nodes.length; i++) {
       cur = cur.getChild(nodes[i]);
     }
 
@@ -1106,7 +1106,7 @@ public class MTreeBelowSGMemoryImpl {
       final PartialPath activatePath, final int templateId, final boolean 
isAligned) {
     final String[] nodes = activatePath.getNodes();
     IMemMNode cur = databaseMNode;
-    for (int i = levelOfSG + 1; i < nodes.length; i++) {
+    for (int i = levelOfDB + 1; i < nodes.length; i++) {
       cur = cur.getChild(nodes[i]);
     }
 
diff --git 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/schemaengine/schemaregion/mtree/impl/pbtree/MTreeBelowSGCachedImpl.java
 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/schemaengine/schemaregion/mtree/impl/pbtree/MTreeBelowSGCachedImpl.java
index 6ff965f112f..5c29755c9ef 100644
--- 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/schemaengine/schemaregion/mtree/impl/pbtree/MTreeBelowSGCachedImpl.java
+++ 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/schemaengine/schemaregion/mtree/impl/pbtree/MTreeBelowSGCachedImpl.java
@@ -66,6 +66,7 @@ import 
org.apache.iotdb.db.schemaengine.schemaregion.read.resp.reader.impl.Schem
 import 
org.apache.iotdb.db.schemaengine.schemaregion.read.resp.reader.impl.TimeseriesReaderWithViewFetch;
 import org.apache.iotdb.db.schemaengine.schemaregion.utils.MetaFormatUtils;
 import 
org.apache.iotdb.db.schemaengine.schemaregion.utils.filter.DeviceFilterVisitor;
+import org.apache.iotdb.db.schemaengine.template.ClusterTemplateManager;
 
 import com.google.common.util.concurrent.ListenableFuture;
 import org.apache.tsfile.enums.TSDataType;
@@ -93,6 +94,8 @@ import java.util.concurrent.atomic.AtomicBoolean;
 import java.util.function.Consumer;
 import java.util.function.Function;
 
+import static org.apache.iotdb.commons.schema.SchemaConstant.NON_TEMPLATE;
+
 /**
  * The hierarchical struct of the Metadata Tree is implemented in this class.
  *
@@ -119,14 +122,14 @@ public class MTreeBelowSGCachedImpl {
   private final CachedMTreeStore store;
 
   @SuppressWarnings("java:S3077")
-  private volatile ICachedMNode storageGroupMNode;
+  private volatile ICachedMNode databaseMNode;
 
   private final ICachedMNode rootNode;
   private final Function<IMeasurementMNode<ICachedMNode>, Map<String, String>> 
tagGetter;
   private final Function<IMeasurementMNode<ICachedMNode>, Map<String, String>> 
attributeGetter;
   private final IMNodeFactory<ICachedMNode> nodeFactory =
       MNodeFactoryLoader.getInstance().getCachedMNodeIMNodeFactory();
-  private final int levelOfSG;
+  private final int levelOfDB;
   private final CachedSchemaRegionStatistics regionStatistics;
 
   // region MTree initialization, clear and serialization
@@ -148,16 +151,16 @@ public class MTreeBelowSGCachedImpl {
         PBTreeFactory.getInstance()
             .createNewCachedMTreeStore(
                 storageGroupPath, schemaRegionId, regionStatistics, metric, 
flushCallback);
-    this.storageGroupMNode = store.getRoot();
-    this.storageGroupMNode.setParent(storageGroupMNode.getParent());
+    this.databaseMNode = store.getRoot();
+    this.databaseMNode.setParent(databaseMNode.getParent());
     this.rootNode = store.generatePrefix(storageGroupPath);
-    levelOfSG = storageGroupPath.getNodeLength() - 1;
+    levelOfDB = storageGroupPath.getNodeLength() - 1;
 
     // recover MNode
     try (MNodeCollector<Void, ICachedMNode> collector =
         new MNodeCollector<Void, ICachedMNode>(
             this.rootNode,
-            new PartialPath(storageGroupMNode.getFullPath()),
+            new PartialPath(databaseMNode.getFullPath()),
             this.store,
             true,
             SchemaConstant.ALL_MATCH_SCOPE) {
@@ -187,9 +190,9 @@ public class MTreeBelowSGCachedImpl {
       throws MetadataException {
     this.store = store;
     this.regionStatistics = regionStatistics;
-    this.storageGroupMNode = store.getRoot();
+    this.databaseMNode = store.getRoot();
     this.rootNode = store.generatePrefix(storageGroupPath);
-    levelOfSG = storageGroupMNode.getPartialPath().getNodeLength() - 1;
+    levelOfDB = databaseMNode.getPartialPath().getNodeLength() - 1;
     this.tagGetter = tagGetter;
     this.attributeGetter = attributeGetter;
 
@@ -197,7 +200,7 @@ public class MTreeBelowSGCachedImpl {
     try (MNodeCollector<Void, ICachedMNode> collector =
         new MNodeCollector<Void, ICachedMNode>(
             this.rootNode,
-            new PartialPath(storageGroupMNode.getFullPath()),
+            new PartialPath(databaseMNode.getFullPath()),
             this.store,
             true,
             SchemaConstant.ALL_MATCH_SCOPE) {
@@ -217,7 +220,7 @@ public class MTreeBelowSGCachedImpl {
 
   public void clear() {
     store.clear();
-    storageGroupMNode = null;
+    databaseMNode = null;
   }
 
   public boolean createSnapshot(File snapshotDir) {
@@ -590,15 +593,15 @@ public class MTreeBelowSGCachedImpl {
       throws MetadataException {
     String[] nodeNames = devicePath.getNodes();
     MetaFormatUtils.checkTimeseries(devicePath);
-    if (nodeNames.length == levelOfSG + 1) {
+    if (nodeNames.length == levelOfDB + 1) {
       return null;
     }
-    ICachedMNode cur = storageGroupMNode;
+    ICachedMNode cur = databaseMNode;
     ICachedMNode child;
     String childName;
     try {
       // e.g, path = root.sg.d1.s1,  create internal nodes and set cur to sg 
node, parent of d1
-      for (int i = levelOfSG + 1; i < nodeNames.length - 1; i++) {
+      for (int i = levelOfDB + 1; i < nodeNames.length - 1; i++) {
         childName = nodeNames[i];
         child = store.getChild(cur, childName);
         if (child == null) {
@@ -621,8 +624,8 @@ public class MTreeBelowSGCachedImpl {
       throws MetadataException {
     if (deviceParent == null) {
       // device is sg
-      pinMNode(storageGroupMNode);
-      return storageGroupMNode;
+      pinMNode(databaseMNode);
+      return databaseMNode;
     }
     ICachedMNode device = store.getChild(deviceParent, deviceName);
     if (device == null) {
@@ -830,12 +833,21 @@ public class MTreeBelowSGCachedImpl {
   public ICachedMNode getDeviceNodeWithAutoCreating(PartialPath deviceId) 
throws MetadataException {
     String[] nodeNames = deviceId.getNodes();
     MetaFormatUtils.checkTimeseries(deviceId);
-    ICachedMNode cur = storageGroupMNode;
+    ICachedMNode cur = databaseMNode;
     ICachedMNode child;
     try {
-      for (int i = levelOfSG + 1; i < nodeNames.length; i++) {
+      for (int i = levelOfDB + 1; i < nodeNames.length; i++) {
         child = store.getChild(cur, nodeNames[i]);
         if (child == null) {
+          if (cur.isDevice()
+              && cur.getAsDeviceMNode().getSchemaTemplateId() != NON_TEMPLATE
+              && ClusterTemplateManager.getInstance()
+                      
.getTemplate(cur.getAsDeviceMNode().getSchemaTemplateId())
+                      .getSchema(nodeNames[i])
+                  != null) {
+            throw new PathAlreadyExistException(
+                new PartialPath(Arrays.copyOf(deviceId.getNodes(), i + 
1)).getFullPath());
+          }
           child =
               store.addChild(cur, nodeNames[i], 
nodeFactory.createInternalMNode(cur, nodeNames[i]));
         }
@@ -983,10 +995,10 @@ public class MTreeBelowSGCachedImpl {
    */
   public ICachedMNode getNodeByPath(PartialPath path) throws MetadataException 
{
     String[] nodes = path.getNodes();
-    ICachedMNode cur = storageGroupMNode;
+    ICachedMNode cur = databaseMNode;
     ICachedMNode next;
     try {
-      for (int i = levelOfSG + 1; i < nodes.length; i++) {
+      for (int i = levelOfDB + 1; i < nodes.length; i++) {
         next = store.getChild(cur, nodes[i]);
         if (next == null) {
           throw new PathNotExistException(path.getFullPath(), true);
@@ -1164,12 +1176,12 @@ public class MTreeBelowSGCachedImpl {
   public void activateTemplate(PartialPath activatePath, Template template)
       throws MetadataException {
     String[] nodes = activatePath.getNodes();
-    ICachedMNode cur = storageGroupMNode;
+    ICachedMNode cur = databaseMNode;
     ICachedMNode child;
     IDeviceMNode<ICachedMNode> entityMNode;
 
     try {
-      for (int i = levelOfSG + 1; i < nodes.length; i++) {
+      for (int i = levelOfDB + 1; i < nodes.length; i++) {
         child = store.getChild(cur, nodes[i]);
         if (child == null) {
           throw new PathNotExistException(activatePath.getFullPath());
@@ -1211,12 +1223,12 @@ public class MTreeBelowSGCachedImpl {
   public void activateTemplateWithoutCheck(
       PartialPath activatePath, int templateId, boolean isAligned) throws 
MetadataException {
     String[] nodes = activatePath.getNodes();
-    ICachedMNode cur = storageGroupMNode;
+    ICachedMNode cur = databaseMNode;
     ICachedMNode child;
     IDeviceMNode<ICachedMNode> entityMNode;
 
     try {
-      for (int i = levelOfSG + 1; i < nodes.length; i++) {
+      for (int i = levelOfDB + 1; i < nodes.length; i++) {
         child = store.getChild(cur, nodes[i]);
         if (child == null) {
           throw new PathNotExistException(activatePath.getFullPath());

Reply via email to