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;