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);
