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

Caideyipi pushed a commit to branch fix/schema-region-device-attribute-recovery
in repository https://gitbox.apache.org/repos/asf/iotdb.git

commit de6ac27a1f6462c4af98cdbace5cc0d367159ff4
Author: Caideyipi <[email protected]>
AuthorDate: Tue Aug 18 20:41:36 2026 +0800

    Fix schema recovery for single device attribute match
---
 .../iotdb/commons/schema/tree/AbstractTreeVisitor.java    |  4 +++-
 .../commons/schema/filter/impl/DeviceFilterUtilTest.java  | 15 +++++++++++++++
 2 files changed, 18 insertions(+), 1 deletion(-)

diff --git 
a/iotdb-core/node-commons/src/main/java/org/apache/iotdb/commons/schema/tree/AbstractTreeVisitor.java
 
b/iotdb-core/node-commons/src/main/java/org/apache/iotdb/commons/schema/tree/AbstractTreeVisitor.java
index 04f59402891..f1beb08095c 100644
--- 
a/iotdb-core/node-commons/src/main/java/org/apache/iotdb/commons/schema/tree/AbstractTreeVisitor.java
+++ 
b/iotdb-core/node-commons/src/main/java/org/apache/iotdb/commons/schema/tree/AbstractTreeVisitor.java
@@ -571,9 +571,11 @@ public abstract class AbstractTreeVisitor<N extends 
ITreeNode, R> implements Sch
       this.transitionIterator = preciseMatchTransitionMap.values().iterator();
       // Candidate counts are a rough cost estimate. Iterate the smaller side 
so this remains
       // adaptive without relying on unstable wall-clock thresholds. Prefer 
child iteration on a
-      // tie because it avoids a direct child lookup for every transition.
+      // tie because it avoids a direct child lookup for every transition. A 
single candidate is
+      // kept on the direct-lookup path because enumerating one child has no 
performance benefit.
       this.iterateChildren =
           patternFA.hasMultiExactMatchTransitions(sourceState)
+              && preciseMatchTransitionMap.size() > 1
               && getChildrenSize(parent) <= preciseMatchTransitionMap.size();
     }
 
diff --git 
a/iotdb-core/node-commons/src/test/java/org/apache/iotdb/commons/schema/filter/impl/DeviceFilterUtilTest.java
 
b/iotdb-core/node-commons/src/test/java/org/apache/iotdb/commons/schema/filter/impl/DeviceFilterUtilTest.java
index b74d7f007fd..af4c7e17e89 100644
--- 
a/iotdb-core/node-commons/src/test/java/org/apache/iotdb/commons/schema/filter/impl/DeviceFilterUtilTest.java
+++ 
b/iotdb-core/node-commons/src/test/java/org/apache/iotdb/commons/schema/filter/impl/DeviceFilterUtilTest.java
@@ -215,6 +215,21 @@ public class DeviceFilterUtilTest {
     Assert.assertEquals(1, visitor.getTargetChildrenIterationCount());
   }
 
+  @Test
+  public void testUseDirectLookupForSingleCandidate() {
+    final TestNode root = new TestNode("root");
+    final TestNode parent = new TestNode("meter");
+    root.addChild(parent);
+    parent.addChildren("card1");
+
+    final TestVisitor visitor =
+        new TestVisitor(root, createAdaptivePattern(Set.of("card1")), parent);
+
+    Assert.assertEquals(Collections.singletonList("card1"), collect(visitor));
+    Assert.assertEquals(1, visitor.getTargetDirectLookupCount());
+    Assert.assertEquals(0, visitor.getTargetChildrenIterationCount());
+  }
+
   private static ExtendedPartialPath createAdaptivePattern(final Set<String> 
values) {
     final ExtendedPartialPath pattern =
         new ExtendedPartialPath(new String[] {"root", "*", "*"}, true);

Reply via email to