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 ad1bd47951f Fix tree path quoting in SHOW CREATE VIEW (#18911)
ad1bd47951f is described below
commit ad1bd47951f76ff5d3c174b10aaf3f5b8a89c8c9
Author: Caideyipi <[email protected]>
AuthorDate: Mon Oct 19 14:16:21 2026 +0800
Fix tree path quoting in SHOW CREATE VIEW (#18911)
---
.../iotdb/relational/it/schema/IoTDBTableIT.java | 56 ++++++++++++-
.../metadata/relational/ShowCreateViewTask.java | 3 +-
.../relational/ShowCreateViewTaskTest.java | 91 ++++++++++++++++++++++
3 files changed, 147 insertions(+), 3 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 25f4cdc66cf..f7a5bc4581c 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
@@ -912,6 +912,58 @@ public class IoTDBTableIT {
}
}
+ @Test
+ public void testShowCreateViewPreservesQuotedTreePath() throws Exception {
+ final String[][] pathNodes = {
+ {"`a``b`", "\"`a``b`\""},
+ {"`a b`", "\"`a b`\""},
+ {"`a\"b`", "\"`a\"\"b`\""}
+ };
+ try (final Connection connection = EnvFactory.getEnv().getConnection();
+ final Statement statement = connection.createStatement()) {
+ statement.execute("CREATE DATABASE root.show_create_view_source");
+ for (int i = 0; i < pathNodes.length; i++) {
+ final String device = "root.show_create_view_source." +
pathNodes[i][0] + ".d1";
+ statement.execute("CREATE TIMESERIES " + device + ".s1 INT32");
+ statement.execute("INSERT INTO " + device + "(time,s1) VALUES (1," +
(10 + i) + ")");
+ }
+ statement.execute("CREATE TIMESERIES
root.show_create_view_source.ab.d1.s1 INT32");
+ statement.execute("INSERT INTO
root.show_create_view_source.ab.d1(time,s1) VALUES (1,999)");
+ }
+
+ try (final Connection connection =
+ EnvFactory.getEnv().getConnection(BaseEnv.TABLE_SQL_DIALECT);
+ final Statement statement = connection.createStatement()) {
+ statement.execute("CREATE DATABASE show_create_view_db");
+ statement.execute("USE show_create_view_db");
+ for (int i = 0; i < pathNodes.length; i++) {
+ final String viewName = "v" + i;
+ final String prefixPath = "root.\"show_create_view_source\"." +
pathNodes[i][1] + ".**";
+ statement.execute(
+ "CREATE VIEW "
+ + viewName
+ + " (device STRING TAG, value INT32 FIELD FROM s1) AS "
+ + prefixPath);
+ for (final String command : new String[] {"SHOW CREATE VIEW ", "SHOW
CREATE TABLE "}) {
+ final String createSql;
+ try (final ResultSet resultSet = statement.executeQuery(command +
viewName)) {
+ assertTrue(resultSet.next());
+ assertEquals(viewName, resultSet.getString(1));
+ createSql = resultSet.getString(2);
+ assertTrue(createSql.endsWith(" AS " + prefixPath));
+ assertFalse(resultSet.next());
+ }
+ statement.execute("DROP VIEW " + viewName);
+ statement.execute(createSql);
+ TestUtils.assertResultSetEqual(
+ statement.executeQuery("SELECT value FROM " + viewName + " ORDER
BY time"),
+ "value,",
+ Collections.singleton((10 + i) + ","));
+ }
+ }
+ }
+ }
+
@Test
public void testTreeViewTable() throws Exception {
try (final Connection connection = EnvFactory.getEnv().getConnection();
@@ -1219,14 +1271,14 @@ public class IoTDBTableIT {
statement.executeQuery("show create view view_table"),
"View,Create View,",
Collections.singleton(
- "view_table,CREATE VIEW \"view_table\" (\"time\" TIMESTAMP
TIME,\"tag1\" STRING TAG,\"tag2\" STRING TAG,\"s11\" INT32 FIELD,\"s3\" STRING
FIELD FROM \"s2\") RESTRICT WITH (ttl=100) AS root.\"重庆\".\"1\".**,"));
+ "view_table,CREATE VIEW \"view_table\" (\"time\" TIMESTAMP
TIME,\"tag1\" STRING TAG,\"tag2\" STRING TAG,\"s11\" INT32 FIELD,\"s3\" STRING
FIELD FROM \"s2\") RESTRICT WITH (ttl=100) AS root.\"重庆\".\"`1`\".**,"));
// Can also use "show create table"
TestUtils.assertResultSetEqual(
statement.executeQuery("show create table view_table"),
"View,Create View,",
Collections.singleton(
- "view_table,CREATE VIEW \"view_table\" (\"time\" TIMESTAMP
TIME,\"tag1\" STRING TAG,\"tag2\" STRING TAG,\"s11\" INT32 FIELD,\"s3\" STRING
FIELD FROM \"s2\") RESTRICT WITH (ttl=100) AS root.\"重庆\".\"1\".**,"));
+ "view_table,CREATE VIEW \"view_table\" (\"time\" TIMESTAMP
TIME,\"tag1\" STRING TAG,\"tag2\" STRING TAG,\"s11\" INT32 FIELD,\"s3\" STRING
FIELD FROM \"s2\") RESTRICT WITH (ttl=100) AS root.\"重庆\".\"`1`\".**,"));
statement.execute("create table a ()");
try {
diff --git
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/execution/config/metadata/relational/ShowCreateViewTask.java
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/execution/config/metadata/relational/ShowCreateViewTask.java
index d46f3e7774d..a616282e7c4 100644
---
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/execution/config/metadata/relational/ShowCreateViewTask.java
+++
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/execution/config/metadata/relational/ShowCreateViewTask.java
@@ -154,7 +154,8 @@ public class ShowCreateViewTask extends AbstractTableTask {
final String[] pathNodes =
TreeViewSchema.getPrefixPattern(table).getNodes();
builder.append(pathNodes[0]);
for (int i = 1; i < pathNodes.length - 1; ++i) {
- builder.append(".\"").append(pathNodes[i].replace("`", "")).append("\"");
+ // Preserve tree-model quoting inside the table-model identifier for
round-trip parsing.
+ builder.append(".").append(getIdentifier(pathNodes[i]));
}
builder.append(".").append(pathNodes[pathNodes.length - 1]);
diff --git
a/iotdb-core/datanode/src/test/java/org/apache/iotdb/db/queryengine/plan/execution/config/metadata/relational/ShowCreateViewTaskTest.java
b/iotdb-core/datanode/src/test/java/org/apache/iotdb/db/queryengine/plan/execution/config/metadata/relational/ShowCreateViewTaskTest.java
new file mode 100644
index 00000000000..9ea96d4a448
--- /dev/null
+++
b/iotdb-core/datanode/src/test/java/org/apache/iotdb/db/queryengine/plan/execution/config/metadata/relational/ShowCreateViewTaskTest.java
@@ -0,0 +1,91 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package
org.apache.iotdb.db.queryengine.plan.execution.config.metadata.relational;
+
+import org.apache.iotdb.commons.path.PartialPath;
+import org.apache.iotdb.commons.schema.table.TreeViewSchema;
+import org.apache.iotdb.commons.schema.table.TsTable;
+import org.apache.iotdb.commons.schema.table.column.FieldColumnSchema;
+import org.apache.iotdb.commons.schema.table.column.TagColumnSchema;
+import org.apache.iotdb.commons.schema.table.column.TimeColumnSchema;
+import org.apache.iotdb.db.queryengine.plan.relational.sql.ast.CreateView;
+import org.apache.iotdb.db.queryengine.plan.relational.sql.parser.SqlParser;
+
+import org.apache.tsfile.enums.TSDataType;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+
+import java.time.ZoneId;
+import java.util.Arrays;
+import java.util.Collection;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNull;
+
+@RunWith(Parameterized.class)
+public class ShowCreateViewTaskTest {
+
+ @Parameterized.Parameters(name = "{0}")
+ public static Collection<Object[]> paths() {
+ return Arrays.asList(
+ new Object[][] {
+ {"root.demo_tick.ab.**", "root.\"demo_tick\".\"ab\".**"},
+ {"root.demo_tick.`a``b`.**", "root.\"demo_tick\".\"`a``b`\".**"},
+ {"root.`demo``tick`.`a````b`.**",
"root.\"`demo``tick`\".\"`a````b`\".**"},
+ {"root.demo_tick.`a b`.**", "root.\"demo_tick\".\"`a b`\".**"},
+ {"root.demo_tick.`a.b`.**", "root.\"demo_tick\".\"`a.b`\".**"},
+ {"root.demo_tick.`a\"b`.**", "root.\"demo_tick\".\"`a\"\"b`\".**"},
+ {"root.demo_tick.`a``\"b`.**",
"root.\"demo_tick\".\"`a``\"\"b`\".**"},
+ {"root.demo_tick.`*`.**", "root.\"demo_tick\".\"`*`\".**"},
+ {"root.demo_tick.`1`.**", "root.\"demo_tick\".\"`1`\".**"}
+ });
+ }
+
+ private final String treePath;
+ private final String sqlPath;
+
+ public ShowCreateViewTaskTest(final String treePath, final String sqlPath) {
+ this.treePath = treePath;
+ this.sqlPath = sqlPath;
+ }
+
+ @Test
+ public void testShowCreateViewPreservesPrefixPath() throws Exception {
+ final PartialPath prefixPath = new PartialPath(treePath);
+ final TsTable table = new TsTable("v");
+ table.addColumnSchema(new TimeColumnSchema("time", TSDataType.TIMESTAMP));
+ table.addColumnSchema(new TagColumnSchema("device", TSDataType.STRING));
+ final FieldColumnSchema field = new FieldColumnSchema("value",
TSDataType.INT32);
+ TreeViewSchema.setOriginalName(field, "s1");
+ table.addColumnSchema(field);
+ assertNull(TreeViewSchema.setPathPattern(table, prefixPath));
+
+ final String sql = ShowCreateViewTask.getShowCreateViewSQL(table);
+ assertEquals(
+ "CREATE VIEW \"v\" (\"time\" TIMESTAMP TIME,\"device\" STRING TAG,"
+ + "\"value\" INT32 FIELD FROM \"s1\") WITH (ttl='INF') AS "
+ + sqlPath,
+ sql);
+ final CreateView recreatedView =
+ (CreateView) new SqlParser().createStatement(sql,
ZoneId.systemDefault(), null);
+ assertEquals(prefixPath, recreatedView.getPrefixPath());
+ }
+}