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

jackietien 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 58927a19d3a Fixed the potential failure for table view query with 
pattern beyond databases
58927a19d3a is described below

commit 58927a19d3ae5271727bb28a6d7cab722f37930f
Author: Caideyipi <[email protected]>
AuthorDate: Tue Jun 17 14:26:35 2025 +0800

    Fixed the potential failure for table view query with pattern beyond 
databases
---
 .../apache/iotdb/relational/it/schema/IoTDBTableIT.java    | 10 ++++++++++
 .../org/apache/iotdb/confignode/manager/ConfigManager.java | 14 +++++++++++++-
 .../apache/iotdb/confignode/manager/ProcedureManager.java  |  2 +-
 .../operator/schema/source/TableDeviceQuerySource.java     |  9 ++++++++-
 .../cache/schema/dualkeycache/impl/DualKeyCacheImpl.java   |  1 +
 .../plan/relational/planner/TableLogicalPlanner.java       |  5 +++++
 .../planner/optimizations/PushPredicateIntoTableScan.java  |  3 +--
 7 files changed, 39 insertions(+), 5 deletions(-)

diff --git 
a/integration-test/src/test/java/org/apache/iotdb/relational/it/schema/IoTDBTableIT.java
 
b/integration-test/src/test/java/org/apache/iotdb/relational/it/schema/IoTDBTableIT.java
index be8a19077d0..db5b2f54693 100644
--- 
a/integration-test/src/test/java/org/apache/iotdb/relational/it/schema/IoTDBTableIT.java
+++ 
b/integration-test/src/test/java/org/apache/iotdb/relational/it/schema/IoTDBTableIT.java
@@ -764,6 +764,7 @@ public class IoTDBTableIT {
   public void testTreeViewTable() throws Exception {
     try (final Connection connection = EnvFactory.getEnv().getConnection();
         final Statement statement = connection.createStatement()) {
+      statement.execute("create database root.another");
       statement.execute("create database root.`重庆`.b");
       statement.execute("create timeSeries root.`重庆`.b.c.S1 int32");
       statement.execute("create timeSeries root.`重庆`.b.c.s2 string");
@@ -777,6 +778,15 @@ public class IoTDBTableIT {
         final Statement statement = connection.createStatement()) {
       statement.execute("create database tree_view_db");
       statement.execute("use tree_view_db");
+
+      try {
+        statement.execute("create view tree_table (tag1 tag, tag2 tag) as 
root.**");
+        fail();
+      } catch (final SQLException e) {
+        assertEquals(
+            "701: Cannot specify view pattern to match more than one tree 
database.",
+            e.getMessage());
+      }
       statement.execute("create view tree_table (tag1 tag, tag2 tag) as 
root.\"重庆\".**");
       statement.execute("drop view tree_table");
     }
diff --git 
a/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/manager/ConfigManager.java
 
b/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/manager/ConfigManager.java
index fa228a233e1..0c8f87c12b5 100644
--- 
a/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/manager/ConfigManager.java
+++ 
b/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/manager/ConfigManager.java
@@ -58,6 +58,7 @@ import org.apache.iotdb.commons.path.PathPatternUtil;
 import 
org.apache.iotdb.commons.pipe.connector.payload.airgap.AirGapPseudoTPipeTransferRequest;
 import org.apache.iotdb.commons.schema.SchemaConstant;
 import org.apache.iotdb.commons.schema.table.AlterOrDropTableOperationType;
+import org.apache.iotdb.commons.schema.table.TreeViewSchema;
 import org.apache.iotdb.commons.schema.table.TsTable;
 import org.apache.iotdb.commons.schema.table.TsTableInternalRPCUtil;
 import org.apache.iotdb.commons.schema.ttl.TTLCache;
@@ -2821,10 +2822,21 @@ public class ConfigManager implements IManager {
 
   @Override
   public TSStatus createTableView(final TCreateTableViewReq req) {
-    TSStatus status = confirmLeader();
+    final TSStatus status = confirmLeader();
     if (status.getCode() == TSStatusCode.SUCCESS_STATUS.getStatusCode()) {
       final Pair<String, TsTable> pair =
           
TsTableInternalRPCUtil.deserializeSingleTsTableWithDatabase(req.getTableInfo());
+      if (clusterSchemaManager
+              .getMatchedDatabaseSchemasByPrefix(
+                  new PartialPath(
+                      Arrays.copyOf(
+                          
TreeViewSchema.getPrefixPattern(pair.getRight()).getNodes(),
+                          
TreeViewSchema.getPrefixPattern(pair.getRight()).getNodeLength() - 1)))
+              .size()
+          > 1) {
+        return new TSStatus(TSStatusCode.SEMANTIC_ERROR.getStatusCode())
+            .setMessage("Cannot specify view pattern to match more than one 
tree database.");
+      }
       return procedureManager.createTableView(pair.left, pair.right, 
req.isReplace());
     } else {
       return status;
diff --git 
a/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/manager/ProcedureManager.java
 
b/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/manager/ProcedureManager.java
index 61e0639b558..bac74158cd6 100644
--- 
a/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/manager/ProcedureManager.java
+++ 
b/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/manager/ProcedureManager.java
@@ -2036,7 +2036,7 @@ public class ProcedureManager {
       final String queryId,
       final ProcedureType thisType,
       final Procedure<ConfigNodeProcedureEnv> procedure) {
-    long procedureId;
+    final long procedureId;
     synchronized (this) {
       final Pair<Long, Boolean> procedureIdDuplicatePair =
           checkDuplicateTableTask(database, table, tableName, queryId, 
thisType);
diff --git 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/execution/operator/schema/source/TableDeviceQuerySource.java
 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/execution/operator/schema/source/TableDeviceQuerySource.java
index b3d0cd80be2..6261a4220c8 100644
--- 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/execution/operator/schema/source/TableDeviceQuerySource.java
+++ 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/execution/operator/schema/source/TableDeviceQuerySource.java
@@ -22,6 +22,7 @@ package 
org.apache.iotdb.db.queryengine.execution.operator.schema.source;
 import org.apache.iotdb.commons.exception.runtime.SchemaExecutionException;
 import org.apache.iotdb.commons.path.ExtendedPartialPath;
 import org.apache.iotdb.commons.path.PartialPath;
+import org.apache.iotdb.commons.path.PathPatternUtil;
 import org.apache.iotdb.commons.schema.column.ColumnHeader;
 import org.apache.iotdb.commons.schema.filter.SchemaFilter;
 import org.apache.iotdb.commons.schema.filter.impl.DeviceFilterUtil;
@@ -327,7 +328,13 @@ public class TableDeviceQuerySource implements 
ISchemaSource<IDeviceSchemaInfo>
     final ISchemaRegionStatistics statistics = 
schemaRegion.getSchemaRegionStatistics();
     final String tableName = table.getTableName();
     final long devicesNumber = statistics.getTableDevicesNumber(tableName);
-    return devicePatternList.stream().allMatch(path -> ((ExtendedPartialPath) 
path).isNormalPath())
+    return !TreeViewSchema.isTreeViewTable(table)
+            && devicePatternList.stream()
+                .allMatch(
+                    path ->
+                        ((ExtendedPartialPath) path).isNormalPath()
+                            && Arrays.stream(path.getNodes())
+                                .noneMatch(PathPatternUtil::hasWildcard))
         ? Math.min(
             
TSFileDescriptor.getInstance().getConfig().getMaxTsBlockSizeInBytes(),
             devicePatternList.stream()
diff --git 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/analyze/cache/schema/dualkeycache/impl/DualKeyCacheImpl.java
 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/analyze/cache/schema/dualkeycache/impl/DualKeyCacheImpl.java
index ba7270ccafc..841444f4279 100644
--- 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/analyze/cache/schema/dualkeycache/impl/DualKeyCacheImpl.java
+++ 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/analyze/cache/schema/dualkeycache/impl/DualKeyCacheImpl.java
@@ -77,6 +77,7 @@ class DualKeyCacheImpl<FK, SK, V, T extends ICacheEntry<SK, 
V>>
     }
   }
 
+  @Override
   public <R> boolean batchApply(
       final Map<FK, Map<SK, R>> inputMap, final BiFunction<V, R, Boolean> 
mappingFunction) {
     for (final Map.Entry<FK, Map<SK, R>> fkMapEntry : inputMap.entrySet()) {
diff --git 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/planner/TableLogicalPlanner.java
 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/planner/TableLogicalPlanner.java
index bee55d2625d..413fafb2d09 100644
--- 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/planner/TableLogicalPlanner.java
+++ 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/planner/TableLogicalPlanner.java
@@ -26,6 +26,7 @@ import 
org.apache.iotdb.commons.schema.column.ColumnHeaderConstant;
 import org.apache.iotdb.commons.schema.table.TreeViewSchema;
 import org.apache.iotdb.commons.schema.table.TsTable;
 import org.apache.iotdb.commons.utils.TestOnly;
+import org.apache.iotdb.db.exception.sql.SemanticException;
 import org.apache.iotdb.db.queryengine.common.MPPQueryContext;
 import org.apache.iotdb.db.queryengine.common.QueryId;
 import org.apache.iotdb.db.queryengine.common.SessionInfo;
@@ -480,6 +481,10 @@ public class TableLogicalPlanner {
 
       analysis.setSchemaPartitionInfo(
           ClusterPartitionFetcher.getInstance().getSchemaPartition(tree));
+
+      if (analysis.getSchemaPartitionInfo().getSchemaPartitionMap().size() > 
1) {
+        throw new SemanticException("Tree device view with multiple databases 
is unsupported yet.");
+      }
     } else {
       analysis.setSchemaPartitionInfo(
           statement.isIdDetermined()
diff --git 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/planner/optimizations/PushPredicateIntoTableScan.java
 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/planner/optimizations/PushPredicateIntoTableScan.java
index ac3bbceffd5..f6be45cd2ac 100644
--- 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/planner/optimizations/PushPredicateIntoTableScan.java
+++ 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/planner/optimizations/PushPredicateIntoTableScan.java
@@ -583,8 +583,7 @@ public class PushPredicateIntoTableScan implements 
PlanOptimizer {
               attributeColumns,
               queryContext);
       if (deviceEntriesMap.size() > 1) {
-        throw new UnsupportedOperationException(
-            "Tree device view with multiple databases is unsupported yet.");
+        throw new SemanticException("Tree device view with multiple databases 
is unsupported yet.");
       }
       final String deviceDatabase =
           !deviceEntriesMap.isEmpty() ? 
deviceEntriesMap.keySet().iterator().next() : null;

Reply via email to