This is an automated email from the ASF dual-hosted git repository.
jt2594838 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 5a9c6b9f293 Fix SHOW TTL wildcard path scope (#18763)
5a9c6b9f293 is described below
commit 5a9c6b9f2934182f78185e7715df16b93626e264
Author: Hongzhi Gao <[email protected]>
AuthorDate: Wed Sep 30 12:09:35 2026 +0800
Fix SHOW TTL wildcard path scope (#18763)
* Fix SHOW TTL wildcard path scope
* Fix SHOW TTL wildcard query and authority scope intersection
---
.../iotdb/db/it/auth/IoTDBSeriesPermissionIT.java | 68 ++++++++++++++++++++++
.../config/executor/ClusterConfigTaskExecutor.java | 10 +++-
2 files changed, 76 insertions(+), 2 deletions(-)
diff --git
a/integration-test/src/test/java/org/apache/iotdb/db/it/auth/IoTDBSeriesPermissionIT.java
b/integration-test/src/test/java/org/apache/iotdb/db/it/auth/IoTDBSeriesPermissionIT.java
index a0feb9712da..c6e23467413 100644
---
a/integration-test/src/test/java/org/apache/iotdb/db/it/auth/IoTDBSeriesPermissionIT.java
+++
b/integration-test/src/test/java/org/apache/iotdb/db/it/auth/IoTDBSeriesPermissionIT.java
@@ -354,6 +354,74 @@ public class IoTDBSeriesPermissionIT {
"test123123456");
}
+ @Test
+ public void showTTLWithMultiLevelWildcardTest() throws SQLException {
+ try (Connection connection = EnvFactory.getEnv().getConnection();
+ Statement statement = connection.createStatement()) {
+ statement.execute("create user ttl_scope_user 'test123123456'");
+ statement.execute("set ttl to root.ttl_scope_a 3600000");
+ statement.execute("set ttl to root.ttl_scope_b 7200000");
+
+ try (ResultSet resultSet = statement.executeQuery("show ttl on
root.ttl_scope_a.g_0.**")) {
+ Assert.assertFalse(resultSet.next());
+ }
+
+ statement.execute("set ttl to root.ttl_scope_a.g_0.** 10000");
+ String[] headers =
+
showTTLColumnHeaders.stream().map(ColumnHeader::getColumnName).toArray(String[]::new);
+ resultSetEqualTest(
+ "show ttl on root.ttl_scope_a.g_0.**",
+ headers,
+ new String[] {"root.ttl_scope_a.g_0.**,10000,"});
+
+ resultSetEqualTest(
+ "show ttl on root.*.**", headers, new String[0], "ttl_scope_user",
"test123123456");
+ statement.execute("grant READ_SCHEMA on root.ttl_scope_a.** to user
ttl_scope_user");
+ for (String query :
+ new String[] {"show ttl on root.*.**", "show ttl on root.ttl_*.**",
"show all ttl"}) {
+ resultSetEqualTest(
+ query,
+ headers,
+ new String[] {"root.ttl_scope_a,3600000,",
"root.ttl_scope_a.g_0.**,10000,"},
+ "ttl_scope_user",
+ "test123123456");
+ }
+ for (String query :
+ new String[] {"show ttl on root.*.g_*.**", "show ttl on
root.ttl_*.g_0.**"}) {
+ resultSetEqualTest(
+ query,
+ headers,
+ new String[] {"root.ttl_scope_a.g_0.**,10000,"},
+ "ttl_scope_user",
+ "test123123456");
+ }
+ resultSetEqualTest(
+ "show ttl on root.ttl_scope_b.**",
+ headers,
+ new String[0],
+ "ttl_scope_user",
+ "test123123456");
+ statement.execute("revoke READ_SCHEMA on root.ttl_scope_a.** from user
ttl_scope_user");
+ statement.execute("grant READ_SCHEMA on root.ttl_scope_a.g_0.** to user
ttl_scope_user");
+ for (String query : new String[] {"show ttl on root.*.**", "show ttl on
root.ttl_*.**"}) {
+ resultSetEqualTest(
+ query,
+ headers,
+ new String[] {"root.ttl_scope_a.g_0.**,10000,"},
+ "ttl_scope_user",
+ "test123123456");
+ }
+ } finally {
+ try (Connection connection = EnvFactory.getEnv().getConnection();
+ Statement statement = connection.createStatement()) {
+ executeQuietly(statement, "drop user ttl_scope_user");
+ executeQuietly(statement, "unset ttl from root.ttl_scope_a.g_0.**");
+ executeQuietly(statement, "unset ttl from root.ttl_scope_a");
+ executeQuietly(statement, "unset ttl from root.ttl_scope_b");
+ }
+ }
+ }
+
@Test
public void ttlOperationsTest() {
try {
diff --git
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/execution/config/executor/ClusterConfigTaskExecutor.java
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/execution/config/executor/ClusterConfigTaskExecutor.java
index 7a3580fe66b..2ebfc3fdbc4 100644
---
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/execution/config/executor/ClusterConfigTaskExecutor.java
+++
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/execution/config/executor/ClusterConfigTaskExecutor.java
@@ -1786,13 +1786,19 @@ public class ClusterConfigTaskExecutor implements
IConfigTaskExecutor {
databaseToTTL.putAll(resp.getPathTTLMap());
continue;
}
+ PathPatternTree queryScope = new PathPatternTree();
+ queryScope.appendPathPattern(pathPattern);
+ queryScope.constructTree();
+ // Query patterns may contain wildcards before the trailing **. Only
the authority
+ // scope is restricted to full paths and literal prefixes.
for (PartialPath overlappedPathPattern :
- authorityScope.getOverlappedPathPatterns(pathPattern)) {
+
queryScope.intersectWithFullPathPrefixTree(authorityScope).getAllPathPatterns())
{
List<String> nodes = Arrays.asList(overlappedPathPattern.getNodes());
TShowTTLReq req = new TShowTTLReq(nodes);
TShowTTLResp resp = client.showTTL(req);
databaseToTTL.putAll(resp.getPathTTLMap());
- if (showTTLStatement.isShowAllTTL()) {
+ // TTL rules can be stored on the prefix itself as well as on
prefix.**.
+ if (overlappedPathPattern.endWithMultiLevelWildcard()) {
req.setPathPattern(nodes.subList(0, nodes.size() - 1));
resp = client.showTTL(req);
databaseToTTL.putAll(resp.getPathTTLMap());