This is an automated email from the ASF dual-hosted git repository.
JackieTien97 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 00df0e3340e Ignore non-field columns when collecting tree-view source
names (#19000)
00df0e3340e is described below
commit 00df0e3340ea5a046e7327f61a6a06eb0bbb7ffa
Author: alpass163 <[email protected]>
AuthorDate: Fri Oct 23 16:57:34 2026 +0800
Ignore non-field columns when collecting tree-view source names (#19000)
---
.../it/schema/IoTDBTreeToTableViewAutoSyncIT.java | 26 +++++++++++++++++
.../manager/ClusterSchemaManagerTest.java | 33 ++++++++++++++++++++++
.../iotdb/commons/schema/table/TreeViewSchema.java | 14 ++++-----
3 files changed, 66 insertions(+), 7 deletions(-)
diff --git
a/integration-test/src/test/java/org/apache/iotdb/relational/it/schema/IoTDBTreeToTableViewAutoSyncIT.java
b/integration-test/src/test/java/org/apache/iotdb/relational/it/schema/IoTDBTreeToTableViewAutoSyncIT.java
index 17dfee84836..7a0569f4a5f 100644
---
a/integration-test/src/test/java/org/apache/iotdb/relational/it/schema/IoTDBTreeToTableViewAutoSyncIT.java
+++
b/integration-test/src/test/java/org/apache/iotdb/relational/it/schema/IoTDBTreeToTableViewAutoSyncIT.java
@@ -600,6 +600,32 @@ public class IoTDBTreeToTableViewAutoSyncIT {
}
}
+ /**
+ * A TAG column name is not a source measurement. It must not prevent an
explicit FROM column from
+ * referencing a tree measurement with the same name.
+ */
+ @Test
+ public void testTagColumnNameDoesNotBlockFromSource() throws Exception {
+ final String treeDb = "root.as21";
+ final String viewDb = "as21";
+ try (Connection tree = treeConnection();
+ Connection table = tableConnection()) {
+ execute(tree, "CREATE DATABASE " + treeDb);
+ execute(tree, "CREATE TIMESERIES " + treeDb + ".d1.s1 DOUBLE");
+
+ execute(table, "CREATE DATABASE " + viewDb);
+ execute(table, "USE " + viewDb);
+ execute(table, "CREATE VIEW v (dev STRING TAG, dev_s1 STRING TAG) AS " +
treeDb + ".**");
+
+ // Create the measurement after the view so that it is not auto-detected
as a column.
+ execute(tree, "CREATE TIMESERIES " + treeDb + ".d1.dev_s1 DOUBLE");
+
+ execute(table, "ALTER VIEW v ADD COLUMN test DOUBLE FIELD FROM dev_s1");
+
+ Assert.assertEquals("DOUBLE", fieldColumns(table, viewDb,
"v").get("test"));
+ }
+ }
+
// ==================== helpers ====================
private static Connection treeConnection() throws SQLException {
diff --git
a/iotdb-core/confignode/src/test/java/org/apache/iotdb/confignode/manager/ClusterSchemaManagerTest.java
b/iotdb-core/confignode/src/test/java/org/apache/iotdb/confignode/manager/ClusterSchemaManagerTest.java
index b86f62dec5e..ce6d7df577e 100644
---
a/iotdb-core/confignode/src/test/java/org/apache/iotdb/confignode/manager/ClusterSchemaManagerTest.java
+++
b/iotdb-core/confignode/src/test/java/org/apache/iotdb/confignode/manager/ClusterSchemaManagerTest.java
@@ -23,9 +23,13 @@ import org.apache.iotdb.common.rpc.thrift.TSStatus;
import org.apache.iotdb.commons.exception.table.ColumnInAlterException;
import org.apache.iotdb.commons.exception.table.ColumnInDeletionException;
import org.apache.iotdb.commons.exception.table.TableInDeletionException;
+import org.apache.iotdb.commons.path.PartialPath;
+import org.apache.iotdb.commons.schema.table.TableNodeStatus;
+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.table.column.FieldColumnSchema;
+import org.apache.iotdb.commons.schema.table.column.TagColumnSchema;
import org.apache.iotdb.commons.schema.table.column.TsTableColumnSchema;
import org.apache.iotdb.confignode.conf.ConfigNodeConfig;
import org.apache.iotdb.confignode.conf.ConfigNodeDescriptor;
@@ -37,6 +41,7 @@ import
org.apache.iotdb.confignode.consensus.request.write.table.PreAlterColumnD
import
org.apache.iotdb.confignode.consensus.request.write.table.PreCreateTablePlan;
import
org.apache.iotdb.confignode.consensus.request.write.table.PreDeleteColumnPlan;
import
org.apache.iotdb.confignode.consensus.request.write.table.PreDeleteTablePlan;
+import
org.apache.iotdb.confignode.consensus.request.write.table.view.PreCreateTableViewPlan;
import org.apache.iotdb.confignode.manager.consensus.ConsensusManager;
import org.apache.iotdb.confignode.manager.node.NodeManager;
import org.apache.iotdb.confignode.manager.partition.PartitionManager;
@@ -373,6 +378,34 @@ public class ClusterSchemaManagerTest {
return new FieldColumnSchema(columnName, TSDataType.INT32, TSEncoding.RLE,
CompressionType.LZ4);
}
+ @Test
+ public void testAddColumnIgnoresNonFieldColumnNamesAsSources() throws
Exception {
+ final String database = "root.source_name_test";
+ final String viewName = "tree_view";
+ final ClusterSchemaInfo clusterSchemaInfo = new ClusterSchemaInfo();
+ clusterSchemaInfo.createDatabase(
+ new DatabaseSchemaPlan(
+ ConfigPhysicalPlanType.CreateDatabase,
+ new TDatabaseSchema(database).setIsTableModel(true)));
+ final TsTable view = new TsTable(viewName);
+ Assert.assertNull(TreeViewSchema.setPathPattern(view, new
PartialPath("root.sg.**")));
+ view.addColumnSchema(new FieldColumnSchema("s1", TSDataType.INT32));
+ view.addColumnSchema(new TagColumnSchema("dev_s1", TSDataType.STRING));
+ clusterSchemaInfo.preCreateTableView(
+ new PreCreateTableViewPlan(database, view,
TableNodeStatus.PRE_CREATE));
+ clusterSchemaInfo.commitCreateTable(new CommitCreateTablePlan(database,
viewName));
+ final ClusterSchemaManager clusterSchemaManager =
managerOf(clusterSchemaInfo);
+
+ // The TAG column dev_s1 is not a source measurement, so it must not block
this FROM column.
+ final FieldColumnSchema test = new FieldColumnSchema("test",
TSDataType.INT32);
+ TreeViewSchema.setOriginalName(test, "dev_s1");
+ final Pair<TSStatus, TsTable> result =
+ clusterSchemaManager.tableColumnCheckForColumnExtension(
+ database, viewName, new
ArrayList<>(Collections.singletonList(test)), true);
+ Assert.assertEquals(TSStatusCode.SUCCESS_STATUS.getStatusCode(),
result.getLeft().getCode());
+ Assert.assertNotNull(result.getRight().getColumnSchema("test"));
+ }
+
private static ClusterSchemaManager managerOf(final ClusterSchemaInfo
clusterSchemaInfo) {
return new ClusterSchemaManager(
Mockito.mock(IManager.class),
diff --git
a/iotdb-core/node-commons/src/main/java/org/apache/iotdb/commons/schema/table/TreeViewSchema.java
b/iotdb-core/node-commons/src/main/java/org/apache/iotdb/commons/schema/table/TreeViewSchema.java
index e1068a21d15..e4ce221d71b 100644
---
a/iotdb-core/node-commons/src/main/java/org/apache/iotdb/commons/schema/table/TreeViewSchema.java
+++
b/iotdb-core/node-commons/src/main/java/org/apache/iotdb/commons/schema/table/TreeViewSchema.java
@@ -24,6 +24,7 @@ import
org.apache.iotdb.commons.exception.IoTDBRuntimeException;
import org.apache.iotdb.commons.i18n.SchemaMessages;
import org.apache.iotdb.commons.path.PartialPath;
import org.apache.iotdb.commons.path.PathPatternUtil;
+import org.apache.iotdb.commons.schema.table.column.TsTableColumnCategory;
import org.apache.iotdb.commons.schema.table.column.TsTableColumnSchema;
import org.apache.iotdb.rpc.TSStatusCode;
@@ -86,18 +87,17 @@ public class TreeViewSchema {
}
/**
- * A source measurement can only be referenced once, so this set decides
whether a column may
- * still be added for one.
+ * Source measurements already referenced by the view's FIELD columns, so
this set decides whether
+ * a column may still be added for one. TAG/TIME/ATTRIBUTE columns do not
reference tree
+ * measurements and therefore do not occupy the source-name namespace.
*/
public static Set<String> getSourceNames(final TsTable view) {
final Set<String> sourceNames = new HashSet<>();
for (final TsTableColumnSchema schema : view.getColumnList()) {
- if (Objects.isNull(schema.getProps())) {
- // the columns which carry no props reference their own name
- sourceNames.add(schema.getColumnName());
- } else {
- sourceNames.add(getSourceName(schema));
+ if (schema.getColumnCategory() != TsTableColumnCategory.FIELD) {
+ continue;
}
+ sourceNames.add(getSourceName(schema));
}
return sourceNames;
}