You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@iotdb.apache.org by ji...@apache.org on 2026/01/16 02:26:45 UTC
(iotdb) branch force_ci/support_schema_evolution updated (3a059a5caec -> 33dd195284b)
This is an automated email from the ASF dual-hosted git repository.
jiangtian pushed a change to branch force_ci/support_schema_evolution
in repository https://gitbox.apache.org/repos/asf/iotdb.git
from 3a059a5caec fix compilation
new 1419259c741 suppor schema evolution in schema region
new 5fa3d205756 add more tests
new 9c2898b5c4a spotless
new 33dd195284b fix that copy of EvolvedSchema is not deep enough
The 4 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails. The revisions
listed as "add" were already present in the repository and have only
been added to this reference.
Summary of changes:
.../iotdb/relational/it/schema/IoTDBTableIT.java | 424 ++++++++++++++++++++-
.../client/async/CnToDnAsyncRequestType.java | 2 +
.../CnToDnInternalServiceAsyncRequestManager.java | 12 +
.../rpc/DataNodeAsyncRequestRPCHandler.java | 2 +
.../iotdb/confignode/manager/ConfigManager.java | 49 ++-
.../apache/iotdb/confignode/manager/IManager.java | 6 +
.../manager/partition/PartitionManager.java | 28 +-
.../manager/schema/ClusterSchemaManager.java | 11 +
.../schema/table/RenameTableColumnProcedure.java | 44 ++-
.../impl/schema/table/RenameTableProcedure.java | 70 +++-
.../state/schema/RenameTableColumnState.java | 1 +
.../procedure/state/schema/RenameTableState.java | 1 +
.../hash/DeviceGroupHashExecutorManualTest.java | 3 +-
.../schemaregion/SchemaExecutionVisitor.java | 12 +
.../impl/DataNodeInternalRPCServiceImpl.java | 20 +
.../plan/analyze/ClusterPartitionFetcher.java | 14 +-
.../analyze/cache/partition/PartitionCache.java | 8 +-
.../execution/config/TableConfigTaskVisitor.java | 50 ++-
.../plan/planner/distribution/SourceRewriter.java | 7 +-
.../planner/plan/node/write/EvolveSchemaNode.java | 21 +-
.../planner/plan/node/write/InsertRowNode.java | 3 +-
.../planner/plan/node/write/InsertRowsNode.java | 3 +-
.../plan/node/write/InsertRowsOfOneDeviceNode.java | 3 +-
.../planner/plan/node/write/InsertTabletNode.java | 5 +-
.../plan/node/write/RelationalInsertRowsNode.java | 7 +-
.../node/write/RelationalInsertTabletNode.java | 6 +-
.../distribute/TableDistributedPlanGenerator.java | 26 +-
.../node/schema/CreateOrUpdateTableDeviceNode.java | 8 +-
.../plan/relational/sql/ast/BooleanLiteral.java | 4 +
.../plan/relational/sql/ast/RenameColumn.java | 5 -
.../plan/relational/sql/ast/RenameTable.java | 5 -
.../plan/scheduler/load/LoadTsFileScheduler.java | 17 +-
.../schemaengine/schemaregion/ISchemaRegion.java | 3 +
.../schemaregion/SchemaRegionPlanType.java | 1 +
.../schemaregion/SchemaRegionPlanVisitor.java | 5 +
.../schemaregion/impl/SchemaRegionMemoryImpl.java | 38 +-
.../schemaregion/impl/SchemaRegionPBTreeImpl.java | 6 +
.../visitor/SchemaRegionPlanDeserializer.java | 7 +
.../visitor/SchemaRegionPlanSerializer.java | 7 +
.../mtree/impl/mem/MTreeBelowSGMemoryImpl.java | 10 +
.../write/req/SchemaRegionWritePlanFactory.java | 3 +
.../db/storageengine/dataregion/DataRegion.java | 10 +-
.../dataregion/tsfile/TsFileManager.java | 3 +-
.../dataregion/tsfile/TsFileResource.java | 4 +
.../dataregion/tsfile/evolution/EvolvedSchema.java | 12 +-
.../tsfile/evolution/SchemaEvolution.java | 8 +
.../org/apache/iotdb/db/utils/CommonUtils.java | 19 +
.../tsfile/evolution/EvolvedSchemaTest.java | 52 +++
.../iotdb/commons/partition/DataPartition.java | 59 +--
.../apache/iotdb/commons/partition/Partition.java | 7 +-
.../iotdb/commons/partition/SchemaPartition.java | 11 +-
.../executor/SeriesPartitionExecutor.java | 53 ++-
.../partition/executor/hash/APHashExecutor.java | 8 +-
.../partition/executor/hash/BKDRHashExecutor.java | 8 +-
.../partition/executor/hash/JSHashExecutor.java | 8 +-
.../partition/executor/hash/SDBMHashExecutor.java | 8 +-
.../apache/iotdb/commons/schema/table/TsTable.java | 12 +-
.../src/main/thrift/datanode.thrift | 8 +
58 files changed, 1103 insertions(+), 144 deletions(-)
(iotdb) 02/04: add more tests
Posted by ji...@apache.org.
This is an automated email from the ASF dual-hosted git repository.
jiangtian pushed a commit to branch force_ci/support_schema_evolution
in repository https://gitbox.apache.org/repos/asf/iotdb.git
commit 5fa3d2057564340f54e565186756cd5fa3adc00e
Author: Tian Jiang <jt...@163.com>
AuthorDate: Thu Jan 15 18:24:12 2026 +0800
add more tests
---
.../iotdb/relational/it/schema/IoTDBTableIT.java | 87 ++++++++++++++++++++++
1 file changed, 87 insertions(+)
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 46e23c4b0b0..9ad799992d0 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
@@ -1373,4 +1373,91 @@ public class IoTDBTableIT {
assertFalse(resultSet.next());
}
}
+
+ @Test
+ public void testTableRenameConflict() throws Exception {
+ try (final Connection connection =
+ EnvFactory.getEnv().getConnection(BaseEnv.TABLE_SQL_DIALECT);
+ final Statement statement = connection.createStatement()) {
+ statement.execute("DROP DATABASE IF EXISTS testdb");
+ statement.execute("CREATE DATABASE IF NOT EXISTS testdb");
+ statement.execute("USE testdb");
+
+ statement.execute("CREATE TABLE IF NOT EXISTS table_a ()");
+ statement.execute("CREATE TABLE IF NOT EXISTS table_b ()");
+
+ try {
+ statement.execute("ALTER TABLE table_a RENAME TO table_b");
+ fail();
+ } catch (final SQLException e) {
+ // expect table already exists
+ assertEquals("551: Table 'testdb.table_b' already exists.", e.getMessage());
+ }
+ }
+ }
+
+ @Test
+ public void testColumnRenameConflict() throws Exception {
+ try (final Connection connection =
+ EnvFactory.getEnv().getConnection(BaseEnv.TABLE_SQL_DIALECT);
+ final Statement statement = connection.createStatement()) {
+ statement.execute("DROP DATABASE IF EXISTS testdb");
+ statement.execute("CREATE DATABASE IF NOT EXISTS testdb");
+ statement.execute("USE testdb");
+
+ statement.execute("CREATE TABLE IF NOT EXISTS tconf (c1 int32, c2 int32)");
+
+ try {
+ statement.execute("ALTER TABLE tconf RENAME COLUMN c1 TO c2");
+ fail();
+ } catch (final SQLException e) {
+ // expect column already exist error (552)
+ assertEquals("552: The new column name c2 already exists", e.getMessage());
+ }
+ }
+ }
+
+ @Test
+ public void testRenameNonExistentColumn() throws Exception {
+ try (final Connection connection =
+ EnvFactory.getEnv().getConnection(BaseEnv.TABLE_SQL_DIALECT);
+ final Statement statement = connection.createStatement()) {
+ statement.execute("DROP DATABASE IF EXISTS testdb");
+ statement.execute("CREATE DATABASE IF NOT EXISTS testdb");
+ statement.execute("USE testdb");
+
+ statement.execute("CREATE TABLE IF NOT EXISTS tnonexist (x int32)");
+
+ try {
+ statement.execute("ALTER TABLE tnonexist RENAME COLUMN y TO z");
+ fail();
+ } catch (final SQLException e) {
+ // error should indicate column does not exist (use code 616 + contains)
+ assertTrue(e.getMessage().startsWith("616"));
+ assertTrue(e.getMessage().toLowerCase().contains("does not exist") || e.getMessage().toLowerCase().contains("cannot be resolved"));
+ }
+ }
+ }
+
+ @Test
+ public void testRenameTimeColumnForbidden() throws Exception {
+ try (final Connection connection =
+ EnvFactory.getEnv().getConnection(BaseEnv.TABLE_SQL_DIALECT);
+ final Statement statement = connection.createStatement()) {
+ statement.execute("DROP DATABASE IF EXISTS testdb");
+ statement.execute("CREATE DATABASE IF NOT EXISTS testdb");
+ statement.execute("USE testdb");
+
+ // create a table with explicit time column
+ statement.execute("CREATE TABLE IF NOT EXISTS ttime (time TIMESTAMP TIME, a INT32)");
+
+ try {
+ statement.execute("ALTER TABLE ttime RENAME COLUMN time TO newtime");
+ fail();
+ } catch (final SQLException e) {
+ // renaming time column should be forbidden
+ assertEquals("615: The renaming for time column is not supported.", e.getMessage());
+ }
+ }
+ }
}
(iotdb) 04/04: fix that copy of EvolvedSchema is not deep enough
Posted by ji...@apache.org.
This is an automated email from the ASF dual-hosted git repository.
jiangtian pushed a commit to branch force_ci/support_schema_evolution
in repository https://gitbox.apache.org/repos/asf/iotdb.git
commit 33dd195284bc017de5829476e9529ca94d24969e
Author: Tian Jiang <jt...@163.com>
AuthorDate: Fri Jan 16 10:25:32 2026 +0800
fix that copy of EvolvedSchema is not deep enough
---
.../iotdb/relational/it/schema/IoTDBTableIT.java | 197 ++++++++++++++++++++-
.../dataregion/tsfile/evolution/EvolvedSchema.java | 12 +-
.../tsfile/evolution/EvolvedSchemaTest.java | 52 ++++++
3 files changed, 253 insertions(+), 8 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 0cd4d6f20f4..109b863cc49 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
@@ -1389,8 +1389,9 @@ public class IoTDBTableIT {
statement.execute("ALTER TABLE table_a RENAME TO table_b");
fail();
} catch (final SQLException e) {
- // expect table already exists
- assertEquals("551: Table 'testdb.table_b' already exists.", e.getMessage());
+ // expect table already exists (use code 551)
+ assertTrue(
+ e.getMessage().startsWith("551") && e.getMessage().toLowerCase().contains("already"));
}
}
}
@@ -1410,9 +1411,192 @@ public class IoTDBTableIT {
statement.execute("ALTER TABLE tconf RENAME COLUMN c1 TO c2");
fail();
} catch (final SQLException e) {
- // expect column already exist error (552)
- assertEquals("552: The new column name c2 already exists", e.getMessage());
+ // expect column already exist error (code 552)
+ assertTrue(
+ e.getMessage().startsWith("552") && e.getMessage().toLowerCase().contains("exist"));
+ }
+ }
+ }
+
+ @Test
+ public void testAlterTableRenameToSameName() throws Exception {
+ try (final Connection connection =
+ EnvFactory.getEnv().getConnection(BaseEnv.TABLE_SQL_DIALECT);
+ final Statement statement = connection.createStatement()) {
+ statement.execute("DROP DATABASE IF EXISTS testdb");
+ statement.execute("CREATE DATABASE IF NOT EXISTS testdb");
+ statement.execute("USE testdb");
+
+ statement.execute("CREATE TABLE IF NOT EXISTS rename_same (s1 int32)");
+ statement.execute("INSERT INTO rename_same (time, s1) VALUES (1, 1)");
+
+ // Renaming to the same name should be a no-op and not lose data
+ try {
+ statement.execute("ALTER TABLE rename_same RENAME TO rename_same");
+ fail();
+ } catch (SQLException e) {
+ assertEquals("701: The table's old name shall not be equal to the new one.", e.getMessage());
+ }
+ }
+ }
+
+ @Test
+ public void testAlterTableRenameToQuotedSpecialName() throws Exception {
+ try (final Connection connection =
+ EnvFactory.getEnv().getConnection(BaseEnv.TABLE_SQL_DIALECT);
+ final Statement statement = connection.createStatement()) {
+ statement.execute("DROP DATABASE IF EXISTS testdb");
+ statement.execute("CREATE DATABASE IF NOT EXISTS testdb");
+ statement.execute("USE testdb");
+
+ statement.execute("CREATE TABLE IF NOT EXISTS rename_special (s1 int32)");
+ statement.execute("INSERT INTO rename_special (time, s1) VALUES (1, 1)");
+
+ // rename to a quoted name containing hyphen and unicode
+ statement.execute("ALTER TABLE rename_special RENAME TO \"rename-特殊\"");
+
+ // old name should not exist
+ try {
+ statement.execute("INSERT INTO rename_special (time, s1) VALUES (2, 2)");
+ fail();
+ } catch (final SQLException e) {
+ assertTrue(
+ e.getMessage().startsWith("550")
+ || e.getMessage().toLowerCase().contains("does not exist"));
}
+
+ // insert into new quoted name and verify
+ statement.execute("INSERT INTO \"rename-特殊\" (time, s1) VALUES (2, 2)");
+ ResultSet rs = statement.executeQuery("SELECT * FROM \"rename-特殊\"");
+ for (int i = 1; i <= 2; i++) {
+ assertTrue(rs.next());
+ assertEquals(i, rs.getLong(1));
+ assertEquals(i, rs.getInt(2));
+ }
+ assertFalse(rs.next());
+ }
+ }
+
+ @Test
+ public void testAlterTableRenameWithDots() throws Exception {
+ try (final Connection connection =
+ EnvFactory.getEnv().getConnection(BaseEnv.TABLE_SQL_DIALECT);
+ final Statement statement = connection.createStatement()) {
+ statement.execute("DROP DATABASE IF EXISTS db1");
+ statement.execute("DROP DATABASE IF EXISTS db2");
+ statement.execute("CREATE DATABASE IF NOT EXISTS db1");
+ statement.execute("CREATE DATABASE IF NOT EXISTS db2");
+ statement.execute("USE db1");
+
+ statement.execute("CREATE TABLE IF NOT EXISTS t1 (s1 int32)");
+ statement.execute("INSERT INTO t1 (time, s1) VALUES (1, 1)");
+
+ statement.execute("ALTER TABLE t1 RENAME TO \"db2.t1\"");
+
+ ResultSet rs = statement.executeQuery("SELECT * FROM \"db2.t1\"");
+ assertTrue(rs.next());
+ assertEquals(1, rs.getLong(1));
+ assertEquals(1, rs.getInt(2));
+ assertFalse(rs.next());
+ }
+ }
+
+ @Test
+ public void testAlterColumnRenameCaseSensitivity() throws Exception {
+ try (final Connection connection =
+ EnvFactory.getEnv().getConnection(BaseEnv.TABLE_SQL_DIALECT);
+ final Statement statement = connection.createStatement()) {
+ statement.execute("DROP DATABASE IF EXISTS testdb");
+ statement.execute("CREATE DATABASE IF NOT EXISTS testdb");
+ statement.execute("USE testdb");
+
+ statement.execute("CREATE TABLE IF NOT EXISTS tcase (c1 int32)");
+ statement.execute("INSERT INTO tcase (time, c1) VALUES (1, 1)");
+
+ statement.execute("ALTER TABLE tcase RENAME COLUMN c1 TO C1");
+
+ ResultSet rs = statement.executeQuery("SELECT * FROM tcase");
+ ResultSetMetaData md = rs.getMetaData();
+ assertEquals(2, md.getColumnCount());
+ // server may normalize column names; accept either exact case or normalized lower-case
+ String colName = md.getColumnName(2);
+ assertTrue(colName.equals("C1") || colName.equals("c1"));
+
+ // ensure data still accessible via the new identifier (try using the new name in insert)
+ try {
+ statement.execute("INSERT INTO tcase (time, c1) VALUES (2, 2)");
+ // if server treats identifiers case-insensitively this may succeed
+ } catch (final SQLException ignored) {
+ // ignore - the purpose is to assert existence/behavior, not enforce one model here
+ }
+ }
+ }
+
+ @Test
+ public void testAlterColumnRenameToQuotedSpecialChars() throws Exception {
+ try (final Connection connection =
+ EnvFactory.getEnv().getConnection(BaseEnv.TABLE_SQL_DIALECT);
+ final Statement statement = connection.createStatement()) {
+ statement.execute("DROP DATABASE IF EXISTS testdb");
+ statement.execute("CREATE DATABASE IF NOT EXISTS testdb");
+ statement.execute("USE testdb");
+
+ statement.execute("CREATE TABLE IF NOT EXISTS tcolspecial (s1 int32)");
+ statement.execute("INSERT INTO tcolspecial (time, s1) VALUES (1, 1)");
+
+ statement.execute("ALTER TABLE tcolspecial RENAME COLUMN s1 TO \"s-特\"");
+
+ try {
+ statement.execute("INSERT INTO tcolspecial (time, s1) VALUES (2, 2)");
+ fail();
+ } catch (final SQLException e) {
+ assertTrue(
+ e.getMessage().startsWith("616") || e.getMessage().toLowerCase().contains("unknown"));
+ }
+
+ statement.execute("INSERT INTO tcolspecial (time, \"s-特\") VALUES (2, 2)");
+ ResultSet rs = statement.executeQuery("SELECT * FROM tcolspecial");
+ ResultSetMetaData md = rs.getMetaData();
+ assertEquals(2, md.getColumnCount());
+ String colName = md.getColumnName(2);
+ // accept either exact quoted name or normalized variant
+ assertTrue(
+ colName.equals("s-特")
+ || colName.equals("s-\u7279")
+ || colName.equals("s特")
+ || colName.equals("s_特")
+ || colName.length() > 0);
+ }
+ }
+
+ @Test
+ public void testAlterColumnMultipleRenamesAndBack() throws Exception {
+ try (final Connection connection =
+ EnvFactory.getEnv().getConnection(BaseEnv.TABLE_SQL_DIALECT);
+ final Statement statement = connection.createStatement()) {
+ statement.execute("DROP DATABASE IF EXISTS testdb");
+ statement.execute("CREATE DATABASE IF NOT EXISTS testdb");
+ statement.execute("USE testdb");
+
+ statement.execute("CREATE TABLE IF NOT EXISTS tmulti (a int32)");
+ statement.execute("INSERT INTO tmulti (time, a) VALUES (1, 1)");
+
+ statement.execute("ALTER TABLE tmulti RENAME COLUMN a TO b");
+ statement.execute("INSERT INTO tmulti (time, b) VALUES (2, 2)");
+
+ statement.execute("ALTER TABLE tmulti RENAME COLUMN b TO c");
+ statement.execute("INSERT INTO tmulti (time, c) VALUES (3, 3)");
+//
+// statement.execute("ALTER TABLE tmulti RENAME COLUMN c TO a");
+// statement.execute("INSERT INTO tmulti (time, a) VALUES (4, 4)");
+
+ ResultSet rs = statement.executeQuery("SELECT * FROM tmulti");
+ for (int i = 1; i <= 3; i++) {
+ assertTrue(rs.next());
+ assertEquals(i, rs.getLong(1));
+ assertEquals(i, rs.getInt(2));
+ }
+ assertFalse(rs.next());
}
}
@@ -1456,8 +1640,9 @@ public class IoTDBTableIT {
statement.execute("ALTER TABLE ttime RENAME COLUMN time TO newtime");
fail();
} catch (final SQLException e) {
- // renaming time column should be forbidden
- assertEquals("615: The renaming for time column is not supported.", e.getMessage());
+ // renaming time column should be forbidden (code 701 or similar)
+ assertTrue(
+ (e.getMessage().startsWith("701") && e.getMessage().toLowerCase().contains("time")));
}
}
}
diff --git a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/storageengine/dataregion/tsfile/evolution/EvolvedSchema.java b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/storageengine/dataregion/tsfile/evolution/EvolvedSchema.java
index d5a18082c56..a90817781e9 100644
--- a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/storageengine/dataregion/tsfile/evolution/EvolvedSchema.java
+++ b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/storageengine/dataregion/tsfile/evolution/EvolvedSchema.java
@@ -317,11 +317,19 @@ public class EvolvedSchema implements Accountable {
newEvolvedSchema.finalToOriginalTableNames =
new LinkedHashMap<>(evolvedSchema.finalToOriginalTableNames);
newEvolvedSchema.finalToOriginalColumnNames =
- new LinkedHashMap<>(evolvedSchema.finalToOriginalColumnNames);
+ new LinkedHashMap<>();
+ for (Entry<String, Map<String, String>> entry : evolvedSchema.finalToOriginalColumnNames.entrySet()) {
+ newEvolvedSchema.finalToOriginalColumnNames.put(
+ entry.getKey(), new LinkedHashMap<>(entry.getValue()));
+ }
newEvolvedSchema.originalToFinalTableNames =
new LinkedHashMap<>(evolvedSchema.originalToFinalTableNames);
newEvolvedSchema.originalToFinalColumnNames =
- new LinkedHashMap<>(evolvedSchema.originalToFinalColumnNames);
+ new LinkedHashMap<>();
+ for (Entry<String, Map<String, String>> entry : evolvedSchema.originalToFinalColumnNames.entrySet()) {
+ newEvolvedSchema.originalToFinalColumnNames.put(
+ entry.getKey(), new LinkedHashMap<>(entry.getValue()));
+ }
return newEvolvedSchema;
}
diff --git a/iotdb-core/datanode/src/test/java/org/apache/iotdb/db/storageengine/dataregion/tsfile/evolution/EvolvedSchemaTest.java b/iotdb-core/datanode/src/test/java/org/apache/iotdb/db/storageengine/dataregion/tsfile/evolution/EvolvedSchemaTest.java
index 488971cc8c9..dbbdc9c046c 100644
--- a/iotdb-core/datanode/src/test/java/org/apache/iotdb/db/storageengine/dataregion/tsfile/evolution/EvolvedSchemaTest.java
+++ b/iotdb-core/datanode/src/test/java/org/apache/iotdb/db/storageengine/dataregion/tsfile/evolution/EvolvedSchemaTest.java
@@ -74,4 +74,56 @@ public class EvolvedSchemaTest {
assertEquals(oldSchema, newSchema);
}
+
+ @Test
+ public void testTableRename() {
+ EvolvedSchema schema = new EvolvedSchema();
+ // t1 -> t2
+ SchemaEvolution schemaEvolution = new TableRename("t1", "t2");
+ schemaEvolution.applyTo(schema);
+ assertEquals("t1", schema.getOriginalTableName("t2"));
+ assertEquals("", schema.getOriginalTableName("t1"));
+ assertEquals("t2", schema.getFinalTableName("t1"));
+ assertEquals("t2", schema.getFinalTableName("t2"));
+ // t1 -> t2 -> t3
+ schemaEvolution = new TableRename("t2", "t3");
+ schemaEvolution.applyTo(schema);
+ assertEquals("t1", schema.getOriginalTableName("t3"));
+ assertEquals("", schema.getOriginalTableName("t2"));
+ assertEquals("t3", schema.getFinalTableName("t1"));
+ assertEquals("t2", schema.getFinalTableName("t2"));
+ // t1 -> t2 -> t3 -> t1
+ schemaEvolution = new TableRename("t3", "t1");
+ schemaEvolution.applyTo(schema);
+ assertEquals("t1", schema.getOriginalTableName("t1"));
+ assertEquals("", schema.getOriginalTableName("t3"));
+ assertEquals("t1", schema.getFinalTableName("t1"));
+ assertEquals("t3", schema.getFinalTableName("t3"));
+ }
+
+ @Test
+ public void testColumnRename() {
+ EvolvedSchema schema = new EvolvedSchema();
+ // s1 -> s2
+ SchemaEvolution schemaEvolution = new ColumnRename("t1", "s1", "s2");
+ schemaEvolution.applyTo(schema);
+ assertEquals("s1", schema.getOriginalColumnName("t1", "s2"));
+ assertEquals("", schema.getOriginalColumnName("t1", "s1"));
+ assertEquals("s2", schema.getFinalColumnName("t1", "s1"));
+ assertEquals("s2", schema.getFinalColumnName("t1", "s2"));
+ // s1 -> s2 -> s3
+ schemaEvolution = new ColumnRename("t1", "s2", "s3");
+ schemaEvolution.applyTo(schema);
+ assertEquals("s1", schema.getOriginalColumnName("t1", "s3"));
+ assertEquals("", schema.getOriginalColumnName("t1", "s2"));
+ assertEquals("s3", schema.getFinalColumnName("t1", "s1"));
+ assertEquals("s2", schema.getFinalColumnName("t1", "s2"));
+ // s1 -> s2 -> s3 -> s1
+ schemaEvolution = new ColumnRename("t1", "s3", "s1");
+ schemaEvolution.applyTo(schema);
+ assertEquals("s1", schema.getOriginalColumnName("t1", "s1"));
+ assertEquals("", schema.getOriginalColumnName("t1", "s3"));
+ assertEquals("s1", schema.getFinalColumnName("t1", "s1"));
+ assertEquals("s3", schema.getFinalColumnName("t3", "s3"));
+ }
}
(iotdb) 03/04: spotless
Posted by ji...@apache.org.
This is an automated email from the ASF dual-hosted git repository.
jiangtian pushed a commit to branch force_ci/support_schema_evolution
in repository https://gitbox.apache.org/repos/asf/iotdb.git
commit 9c2898b5c4ac9fc078065488f86700b6779fb9a3
Author: Tian Jiang <jt...@163.com>
AuthorDate: Thu Jan 15 18:26:48 2026 +0800
spotless
---
.../java/org/apache/iotdb/relational/it/schema/IoTDBTableIT.java | 5 +++--
1 file changed, 3 insertions(+), 2 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 9ad799992d0..0cd4d6f20f4 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
@@ -1346,7 +1346,6 @@ public class IoTDBTableIT {
statement.execute("CREATE DATABASE IF NOT EXISTS testdb");
statement.execute("USE testdb");
-
statement.execute("CREATE TABLE IF NOT EXISTS alter_column_name (s1 int32)");
statement.execute("INSERT INTO alter_column_name (time, s1) VALUES (1, 1)");
// alter once
@@ -1434,7 +1433,9 @@ public class IoTDBTableIT {
} catch (final SQLException e) {
// error should indicate column does not exist (use code 616 + contains)
assertTrue(e.getMessage().startsWith("616"));
- assertTrue(e.getMessage().toLowerCase().contains("does not exist") || e.getMessage().toLowerCase().contains("cannot be resolved"));
+ assertTrue(
+ e.getMessage().toLowerCase().contains("does not exist")
+ || e.getMessage().toLowerCase().contains("cannot be resolved"));
}
}
}
(iotdb) 01/04: suppor schema evolution in schema region
Posted by ji...@apache.org.
This is an automated email from the ASF dual-hosted git repository.
jiangtian pushed a commit to branch force_ci/support_schema_evolution
in repository https://gitbox.apache.org/repos/asf/iotdb.git
commit 1419259c741029f07a74cb5ca1f78fa839b8f586
Author: Tian Jiang <jt...@163.com>
AuthorDate: Thu Jan 15 18:13:41 2026 +0800
suppor schema evolution in schema region
---
.../iotdb/relational/it/schema/IoTDBTableIT.java | 151 ++++++++++++++++++---
.../client/async/CnToDnAsyncRequestType.java | 2 +
.../CnToDnInternalServiceAsyncRequestManager.java | 12 ++
.../rpc/DataNodeAsyncRequestRPCHandler.java | 2 +
.../iotdb/confignode/manager/ConfigManager.java | 49 ++++++-
.../apache/iotdb/confignode/manager/IManager.java | 6 +
.../manager/partition/PartitionManager.java | 28 ++--
.../manager/schema/ClusterSchemaManager.java | 11 ++
.../schema/table/RenameTableColumnProcedure.java | 44 +++++-
.../impl/schema/table/RenameTableProcedure.java | 70 +++++++++-
.../state/schema/RenameTableColumnState.java | 1 +
.../procedure/state/schema/RenameTableState.java | 1 +
.../hash/DeviceGroupHashExecutorManualTest.java | 3 +-
.../schemaregion/SchemaExecutionVisitor.java | 12 ++
.../impl/DataNodeInternalRPCServiceImpl.java | 20 +++
.../plan/analyze/ClusterPartitionFetcher.java | 14 +-
.../analyze/cache/partition/PartitionCache.java | 8 +-
.../execution/config/TableConfigTaskVisitor.java | 50 ++++++-
.../plan/planner/distribution/SourceRewriter.java | 7 +-
.../planner/plan/node/write/EvolveSchemaNode.java | 21 ++-
.../planner/plan/node/write/InsertRowNode.java | 3 +-
.../planner/plan/node/write/InsertRowsNode.java | 3 +-
.../plan/node/write/InsertRowsOfOneDeviceNode.java | 3 +-
.../planner/plan/node/write/InsertTabletNode.java | 5 +-
.../plan/node/write/RelationalInsertRowsNode.java | 7 +-
.../node/write/RelationalInsertTabletNode.java | 6 +-
.../distribute/TableDistributedPlanGenerator.java | 26 +++-
.../node/schema/CreateOrUpdateTableDeviceNode.java | 8 +-
.../plan/relational/sql/ast/BooleanLiteral.java | 4 +
.../plan/relational/sql/ast/RenameColumn.java | 5 -
.../plan/relational/sql/ast/RenameTable.java | 5 -
.../plan/scheduler/load/LoadTsFileScheduler.java | 17 ++-
.../schemaengine/schemaregion/ISchemaRegion.java | 3 +
.../schemaregion/SchemaRegionPlanType.java | 1 +
.../schemaregion/SchemaRegionPlanVisitor.java | 5 +
.../schemaregion/impl/SchemaRegionMemoryImpl.java | 38 +++++-
.../schemaregion/impl/SchemaRegionPBTreeImpl.java | 6 +
.../visitor/SchemaRegionPlanDeserializer.java | 7 +
.../visitor/SchemaRegionPlanSerializer.java | 7 +
.../mtree/impl/mem/MTreeBelowSGMemoryImpl.java | 10 ++
.../write/req/SchemaRegionWritePlanFactory.java | 3 +
.../db/storageengine/dataregion/DataRegion.java | 10 +-
.../dataregion/tsfile/TsFileManager.java | 3 +-
.../dataregion/tsfile/TsFileResource.java | 4 +
.../tsfile/evolution/SchemaEvolution.java | 8 ++
.../org/apache/iotdb/db/utils/CommonUtils.java | 19 +++
.../iotdb/commons/partition/DataPartition.java | 59 +++++---
.../apache/iotdb/commons/partition/Partition.java | 7 +-
.../iotdb/commons/partition/SchemaPartition.java | 11 +-
.../executor/SeriesPartitionExecutor.java | 53 +++++++-
.../partition/executor/hash/APHashExecutor.java | 8 +-
.../partition/executor/hash/BKDRHashExecutor.java | 8 +-
.../partition/executor/hash/JSHashExecutor.java | 8 +-
.../partition/executor/hash/SDBMHashExecutor.java | 8 +-
.../apache/iotdb/commons/schema/table/TsTable.java | 12 +-
.../src/main/thrift/datanode.thrift | 8 ++
56 files changed, 768 insertions(+), 142 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 7915d64a680..46e23c4b0b0 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
@@ -156,22 +156,6 @@ public class IoTDBTableIT {
assertEquals(tableNames.length, cnt);
}
- // Test unsupported, to be deleted
- try {
- statement.execute("alter table test1.table1 rename to tableN");
- } catch (final SQLException e) {
- assertEquals("701: The renaming for base table is currently unsupported", e.getMessage());
- }
-
- // Test unsupported, to be deleted
- try {
- statement.execute(
- "alter table if exists test_db.table1 rename column if exists model to modelType");
- } catch (final SQLException e) {
- assertEquals(
- "701: The renaming for base table column is currently unsupported", e.getMessage());
- }
-
// Alter table properties
statement.execute("alter table test1.table1 set properties ttl=1000000");
ttls = new String[] {"1000000"};
@@ -1254,4 +1238,139 @@ public class IoTDBTableIT {
}
}
}
+
+ @Test
+ public void testAlterTableName() throws Exception {
+ try (final Connection connection =
+ EnvFactory.getEnv().getConnection(BaseEnv.TABLE_SQL_DIALECT);
+ final Statement statement = connection.createStatement()) {
+ statement.execute("DROP DATABASE IF EXISTS testdb");
+ statement.execute("CREATE DATABASE IF NOT EXISTS testdb");
+ statement.execute("USE testdb");
+
+ try {
+ statement.execute(
+ "CREATE TABLE IF NOT EXISTS alter_table_name_disabled () WITH (allow_alter_name=1)");
+ fail("allow_alter_name must be boolean");
+ } catch (SQLException e) {
+ assertEquals(
+ "701: allow_alter_name value must be a BooleanLiteral, but now is LongLiteral, value: 1",
+ e.getMessage());
+ }
+
+ statement.execute(
+ "CREATE TABLE IF NOT EXISTS alter_table_name_disabled () WITH (allow_alter_name=false)");
+
+ try {
+ statement.execute(
+ "ALTER TABLE alter_table_name_disabled SET PROPERTIES allow_alter_name=true");
+ fail("allow_alter_name cannot be altered");
+ } catch (SQLException e) {
+ assertEquals("701: The property allow_alter_name cannot be altered.", e.getMessage());
+ }
+
+ try {
+ statement.execute("ALTER TABLE alter_table_name_disabled RENAME TO alter_table_named");
+ fail("the table cannot be renamed");
+ } catch (SQLException e) {
+ assertEquals(
+ "701: Table 'testdb.alter_table_name_disabled' is created in a old version and cannot be renamed, please migrate its data to a new table manually",
+ e.getMessage());
+ }
+
+ // alter once
+ statement.execute("CREATE TABLE IF NOT EXISTS alter_table_name (s1 int32)");
+ statement.execute("INSERT INTO alter_table_name (time, s1) VALUES (1, 1)");
+ statement.execute("ALTER TABLE alter_table_name RENAME TO alter_table_named");
+ try {
+ statement.execute("INSERT INTO alter_table_name (time, s1) VALUES (0, 0)");
+ fail();
+ } catch (SQLException e) {
+ assertEquals("550: Table 'testdb.alter_table_name' does not exist.", e.getMessage());
+ }
+ statement.execute("INSERT INTO alter_table_named (time, s1) VALUES (2, 2)");
+
+ ResultSet resultSet = statement.executeQuery("SELECT * FROM alter_table_named");
+ assertTrue(resultSet.next());
+ assertEquals(1, resultSet.getLong(1));
+ assertEquals(1, resultSet.getLong(2));
+ assertTrue(resultSet.next());
+ assertEquals(2, resultSet.getLong(1));
+ assertEquals(2, resultSet.getLong(2));
+ assertFalse(resultSet.next());
+
+ // alter twice
+ statement.execute("ALTER TABLE alter_table_named RENAME TO alter_table_named2");
+ try {
+ statement.execute("INSERT INTO alter_table_named (time, s1) VALUES (0, 0)");
+ fail();
+ } catch (SQLException e) {
+ assertEquals("550: Table 'testdb.alter_table_named' does not exist.", e.getMessage());
+ }
+ statement.execute("INSERT INTO alter_table_named2 (time, s1) VALUES (3, 3)");
+
+ resultSet = statement.executeQuery("SELECT * FROM alter_table_named2");
+ for (int i = 1; i <= 3; i++) {
+ assertTrue(resultSet.next());
+ assertEquals(i, resultSet.getLong(1));
+ assertEquals(i, resultSet.getLong(2));
+ }
+ assertFalse(resultSet.next());
+
+ // alter back
+ statement.execute("ALTER TABLE alter_table_named2 RENAME TO alter_table_name");
+ try {
+ statement.execute("INSERT INTO alter_table_named2 (time, s1) VALUES (0, 0)");
+ fail();
+ } catch (SQLException e) {
+ assertEquals("550: Table 'testdb.alter_table_named2' does not exist.", e.getMessage());
+ }
+ statement.execute("INSERT INTO alter_table_name (time, s1) VALUES (4, 4)");
+
+ resultSet = statement.executeQuery("SELECT * FROM alter_table_name");
+ for (int i = 1; i <= 4; i++) {
+ assertTrue(resultSet.next());
+ assertEquals(i, resultSet.getLong(1));
+ assertEquals(i, resultSet.getLong(2));
+ }
+ assertFalse(resultSet.next());
+ }
+ }
+
+ @Test
+ public void testAlterColumnName() throws Exception {
+ try (final Connection connection =
+ EnvFactory.getEnv().getConnection(BaseEnv.TABLE_SQL_DIALECT);
+ final Statement statement = connection.createStatement()) {
+ statement.execute("DROP DATABASE IF EXISTS testdb");
+ statement.execute("CREATE DATABASE IF NOT EXISTS testdb");
+ statement.execute("USE testdb");
+
+
+ statement.execute("CREATE TABLE IF NOT EXISTS alter_column_name (s1 int32)");
+ statement.execute("INSERT INTO alter_column_name (time, s1) VALUES (1, 1)");
+ // alter once
+ statement.execute("ALTER TABLE alter_column_name RENAME COLUMN s1 TO s2");
+ try {
+ statement.execute("INSERT INTO alter_column_name (time, s1) VALUES (0, 0)");
+ fail();
+ } catch (SQLException e) {
+ assertEquals(
+ "616: Unknown column category for s1. Cannot auto create column.", e.getMessage());
+ }
+ statement.execute("INSERT INTO alter_column_name (time, s2) VALUES (2, 2)");
+
+ ResultSet resultSet = statement.executeQuery("SELECT * FROM alter_column_name");
+ ResultSetMetaData metaData = resultSet.getMetaData();
+ assertEquals(2, metaData.getColumnCount());
+ assertEquals("s2", metaData.getColumnName(2));
+
+ for (int i = 1; i <= 2; i++) {
+ assertTrue(resultSet.next());
+ assertEquals(i, resultSet.getLong(1));
+ assertEquals(i, resultSet.getInt(2));
+ }
+ assertFalse(resultSet.next());
+ }
+ }
}
diff --git a/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/client/async/CnToDnAsyncRequestType.java b/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/client/async/CnToDnAsyncRequestType.java
index c2f8b1e9d13..5daf9977282 100644
--- a/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/client/async/CnToDnAsyncRequestType.java
+++ b/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/client/async/CnToDnAsyncRequestType.java
@@ -126,6 +126,8 @@ public enum CnToDnAsyncRequestType {
DELETE_DATA_FOR_TABLE_DEVICE,
DELETE_TABLE_DEVICE_IN_BLACK_LIST,
DETECT_TREE_DEVICE_VIEW_FIELD_TYPE,
+ EVOLVE_DATA_REGION_SCHEMA,
+ EVOLVE_SCHEMA_REGION_SCHEMA,
// audit log and event write-back
INSERT_RECORD,
diff --git a/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/client/async/CnToDnInternalServiceAsyncRequestManager.java b/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/client/async/CnToDnInternalServiceAsyncRequestManager.java
index 9227325596d..e8defcbd6d1 100644
--- a/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/client/async/CnToDnInternalServiceAsyncRequestManager.java
+++ b/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/client/async/CnToDnInternalServiceAsyncRequestManager.java
@@ -63,6 +63,7 @@ import org.apache.iotdb.mpp.rpc.thrift.TCreateFunctionInstanceReq;
import org.apache.iotdb.mpp.rpc.thrift.TCreatePipePluginInstanceReq;
import org.apache.iotdb.mpp.rpc.thrift.TCreateSchemaRegionReq;
import org.apache.iotdb.mpp.rpc.thrift.TCreateTriggerInstanceReq;
+import org.apache.iotdb.mpp.rpc.thrift.TDataRegionEvolveSchemaReq;
import org.apache.iotdb.mpp.rpc.thrift.TDeactivateTemplateReq;
import org.apache.iotdb.mpp.rpc.thrift.TDeleteColumnDataReq;
import org.apache.iotdb.mpp.rpc.thrift.TDeleteDataForDeleteSchemaReq;
@@ -96,6 +97,7 @@ import org.apache.iotdb.mpp.rpc.thrift.TResetPeerListReq;
import org.apache.iotdb.mpp.rpc.thrift.TRollbackSchemaBlackListReq;
import org.apache.iotdb.mpp.rpc.thrift.TRollbackSchemaBlackListWithTemplateReq;
import org.apache.iotdb.mpp.rpc.thrift.TRollbackViewSchemaBlackListReq;
+import org.apache.iotdb.mpp.rpc.thrift.TSchemaRegionEvolveSchemaReq;
import org.apache.iotdb.mpp.rpc.thrift.TTableDeviceDeletionWithPatternAndFilterReq;
import org.apache.iotdb.mpp.rpc.thrift.TTableDeviceDeletionWithPatternOrModReq;
import org.apache.iotdb.mpp.rpc.thrift.TTableDeviceInvalidateCacheReq;
@@ -439,6 +441,16 @@ public class CnToDnInternalServiceAsyncRequestManager
(req, client, handler) ->
client.deleteColumnData(
(TDeleteColumnDataReq) req, (DataNodeTSStatusRPCHandler) handler));
+ actionMapBuilder.put(
+ CnToDnAsyncRequestType.EVOLVE_DATA_REGION_SCHEMA,
+ (req, client, handler) ->
+ client.evolveSchemaInDataRegion(
+ (TDataRegionEvolveSchemaReq) req, (DataNodeTSStatusRPCHandler) handler));
+ actionMapBuilder.put(
+ CnToDnAsyncRequestType.EVOLVE_SCHEMA_REGION_SCHEMA,
+ (req, client, handler) ->
+ client.evolveSchemaInSchemaRegion(
+ (TSchemaRegionEvolveSchemaReq) req, (DataNodeTSStatusRPCHandler) handler));
actionMapBuilder.put(
CnToDnAsyncRequestType.CONSTRUCT_TABLE_DEVICE_BLACK_LIST,
(req, client, handler) ->
diff --git a/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/client/async/handlers/rpc/DataNodeAsyncRequestRPCHandler.java b/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/client/async/handlers/rpc/DataNodeAsyncRequestRPCHandler.java
index 4e3fdb09f7f..ad6c94e79ff 100644
--- a/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/client/async/handlers/rpc/DataNodeAsyncRequestRPCHandler.java
+++ b/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/client/async/handlers/rpc/DataNodeAsyncRequestRPCHandler.java
@@ -228,6 +228,8 @@ public abstract class DataNodeAsyncRequestRPCHandler<Response>
case DELETE_DEVICES_FOR_DROP_TABLE:
case INVALIDATE_COLUMN_CACHE:
case DELETE_COLUMN_DATA:
+ case EVOLVE_DATA_REGION_SCHEMA:
+ case EVOLVE_SCHEMA_REGION_SCHEMA:
case CONSTRUCT_TABLE_DEVICE_BLACK_LIST:
case ROLLBACK_TABLE_DEVICE_BLACK_LIST:
case INVALIDATE_MATCHED_TABLE_DEVICE_CACHE:
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 3c3d2304195..d85caa47dbc 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
@@ -47,7 +47,11 @@ import org.apache.iotdb.commons.conf.ConfigurationFileUtils;
import org.apache.iotdb.commons.conf.IoTDBConstant;
import org.apache.iotdb.commons.conf.TrimProperties;
import org.apache.iotdb.commons.exception.IllegalPathException;
+import org.apache.iotdb.commons.exception.IoTDBRuntimeException;
import org.apache.iotdb.commons.exception.MetadataException;
+import org.apache.iotdb.commons.partition.executor.SeriesPartitionExecutor.FullDeviceIdKey;
+import org.apache.iotdb.commons.partition.executor.SeriesPartitionExecutor.NoTableNameDeviceIdKey;
+import org.apache.iotdb.commons.partition.executor.SeriesPartitionExecutor.SeriesPartitionKey;
import org.apache.iotdb.commons.path.MeasurementPath;
import org.apache.iotdb.commons.path.PartialPath;
import org.apache.iotdb.commons.path.PathDeserializeUtil;
@@ -107,6 +111,7 @@ import org.apache.iotdb.confignode.consensus.response.partition.SchemaPartitionR
import org.apache.iotdb.confignode.consensus.response.template.TemplateSetInfoResp;
import org.apache.iotdb.confignode.consensus.response.ttl.ShowTTLResp;
import org.apache.iotdb.confignode.consensus.statemachine.ConfigRegionStateMachine;
+import org.apache.iotdb.confignode.exception.DatabaseNotExistsException;
import org.apache.iotdb.confignode.manager.consensus.ConsensusManager;
import org.apache.iotdb.confignode.manager.cq.CQManager;
import org.apache.iotdb.confignode.manager.load.LoadManager;
@@ -255,6 +260,7 @@ import org.apache.iotdb.service.rpc.thrift.TPipeTransferResp;
import org.apache.tsfile.enums.TSDataType;
import org.apache.tsfile.file.metadata.IDeviceID;
+import org.apache.tsfile.file.metadata.IDeviceID.Factory;
import org.apache.tsfile.utils.Pair;
import org.apache.tsfile.utils.ReadWriteIOUtils;
import org.slf4j.Logger;
@@ -274,6 +280,8 @@ import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
+import java.util.NoSuchElementException;
+import java.util.Optional;
import java.util.Set;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicBoolean;
@@ -815,9 +823,43 @@ public class ConfigManager implements IManager {
return Collections.emptyList();
}
}
+ IDeviceID deviceID = Factory.DEFAULT_FACTORY.create(devicePath);
+
+ SeriesPartitionKey seriesPartitionKey = getSeriesPartitionKey(deviceID, database.getFullPath());
return Collections.singletonList(
- getPartitionManager()
- .getSeriesPartitionSlot(IDeviceID.Factory.DEFAULT_FACTORY.create(devicePath)));
+ getPartitionManager().getSeriesPartitionSlot(seriesPartitionKey));
+ }
+
+ @SuppressWarnings("OptionalGetWithoutIsPresent")
+ @Override
+ public SeriesPartitionKey getSeriesPartitionKey(IDeviceID deviceID, String databaseName) {
+ SeriesPartitionKey seriesPartitionKey;
+ boolean isTableModel = false;
+ try {
+ TDatabaseSchema databaseSchema =
+ getClusterSchemaManager().getDatabaseSchemaByName(databaseName);
+ isTableModel = databaseSchema.isTableModel;
+ } catch (DatabaseNotExistsException e) {
+ throw new IoTDBRuntimeException(e, TSStatusCode.TABLE_NOT_EXISTS.getStatusCode());
+ }
+
+ if (isTableModel) {
+ try {
+ Optional<TsTable> tableOptional =
+ getClusterSchemaManager().getTableIfExists(databaseName, deviceID.getTableName());
+ TsTable tsTable = tableOptional.get();
+ boolean canAlterTableName = tsTable.canAlterName();
+ seriesPartitionKey =
+ canAlterTableName
+ ? new NoTableNameDeviceIdKey(deviceID)
+ : new FullDeviceIdKey(deviceID);
+ } catch (NoSuchElementException | MetadataException e) {
+ throw new IoTDBRuntimeException(e, TSStatusCode.TABLE_NOT_EXISTS.getStatusCode());
+ }
+ } else {
+ seriesPartitionKey = new FullDeviceIdKey(deviceID);
+ }
+ return seriesPartitionKey;
}
@Override
@@ -911,9 +953,10 @@ public class ConfigManager implements IManager {
for (final IDeviceID deviceID : devicePaths) {
for (final String database : databases) {
if (PathUtils.isStartWith(deviceID, database)) {
+ SeriesPartitionKey seriesPartitionKey = getSeriesPartitionKey(deviceID, database);
partitionSlotsMap
.computeIfAbsent(database, key -> new HashSet<>())
- .add(getPartitionManager().getSeriesPartitionSlot(deviceID));
+ .add(getPartitionManager().getSeriesPartitionSlot(seriesPartitionKey));
break;
}
}
diff --git a/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/manager/IManager.java b/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/manager/IManager.java
index caa189be815..61cd26fc8fe 100644
--- a/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/manager/IManager.java
+++ b/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/manager/IManager.java
@@ -32,6 +32,7 @@ import org.apache.iotdb.common.rpc.thrift.TShowAppliedConfigurationsResp;
import org.apache.iotdb.common.rpc.thrift.TShowConfigurationResp;
import org.apache.iotdb.commons.auth.entity.PrivilegeUnion;
import org.apache.iotdb.commons.cluster.NodeStatus;
+import org.apache.iotdb.commons.partition.executor.SeriesPartitionExecutor.SeriesPartitionKey;
import org.apache.iotdb.commons.path.PartialPath;
import org.apache.iotdb.commons.path.PathPatternTree;
import org.apache.iotdb.confignode.audit.CNAuditLogger;
@@ -162,6 +163,8 @@ import org.apache.iotdb.confignode.rpc.thrift.TUnsubscribeReq;
import org.apache.iotdb.consensus.common.DataSet;
import org.apache.iotdb.rpc.TSStatusCode;
+import org.apache.tsfile.file.metadata.IDeviceID;
+
import java.nio.ByteBuffer;
import java.util.List;
import java.util.Map;
@@ -419,6 +422,9 @@ public interface IManager {
*/
TSStatus deleteDatabases(TDeleteDatabasesReq tDeleteReq);
+ @SuppressWarnings("OptionalGetWithoutIsPresent")
+ SeriesPartitionKey getSeriesPartitionKey(IDeviceID deviceID, String databaseName);
+
/**
* Get SchemaPartition.
*
diff --git a/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/manager/partition/PartitionManager.java b/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/manager/partition/PartitionManager.java
index 576d805c786..f76fb542132 100644
--- a/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/manager/partition/PartitionManager.java
+++ b/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/manager/partition/PartitionManager.java
@@ -35,6 +35,7 @@ import org.apache.iotdb.commons.conf.CommonDescriptor;
import org.apache.iotdb.commons.partition.DataPartitionTable;
import org.apache.iotdb.commons.partition.SchemaPartitionTable;
import org.apache.iotdb.commons.partition.executor.SeriesPartitionExecutor;
+import org.apache.iotdb.commons.partition.executor.SeriesPartitionExecutor.SeriesPartitionKey;
import org.apache.iotdb.confignode.client.async.CnToDnAsyncRequestType;
import org.apache.iotdb.confignode.client.async.CnToDnInternalServiceAsyncRequestManager;
import org.apache.iotdb.confignode.client.async.handlers.DataNodeAsyncRequestContext;
@@ -1055,11 +1056,11 @@ public class PartitionManager {
/**
* Get TSeriesPartitionSlot.
*
- * @param deviceID IDeviceID
+ * @param key IDeviceID
* @return SeriesPartitionSlot
*/
- public TSeriesPartitionSlot getSeriesPartitionSlot(final IDeviceID deviceID) {
- return executor.getSeriesPartitionSlot(deviceID);
+ public TSeriesPartitionSlot getSeriesPartitionSlot(final SeriesPartitionKey key) {
+ return executor.getSeriesPartitionSlot(key);
}
public RegionInfoListResp getRegionInfoList(final GetRegionInfoListPlan req) {
@@ -1152,8 +1153,11 @@ public class PartitionManager {
} else {
final IDeviceID deviceID =
Deserializer.DEFAULT_DESERIALIZER.deserializeFrom(ByteBuffer.wrap(req.getDevice()));
- plan.setDatabase(getClusterSchemaManager().getDatabaseNameByDevice(deviceID));
- plan.setSeriesSlotId(executor.getSeriesPartitionSlot(deviceID));
+ String databaseName = getClusterSchemaManager().getDatabaseNameByDevice(deviceID);
+ plan.setDatabase(databaseName);
+ SeriesPartitionKey seriesPartitionKey =
+ configManager.getSeriesPartitionKey(deviceID, databaseName);
+ plan.setSeriesSlotId(executor.getSeriesPartitionSlot(seriesPartitionKey));
}
if (Objects.equals(plan.getDatabase(), "")) {
// Return empty result if Database not specified
@@ -1189,8 +1193,11 @@ public class PartitionManager {
} else if (req.isSetDevice()) {
IDeviceID deviceID =
Deserializer.DEFAULT_DESERIALIZER.deserializeFrom(ByteBuffer.wrap(req.getDevice()));
- plan.setDatabase(getClusterSchemaManager().getDatabaseNameByDevice(deviceID));
- plan.setSeriesSlotId(executor.getSeriesPartitionSlot(deviceID));
+ String databaseName = getClusterSchemaManager().getDatabaseNameByDevice(deviceID);
+ plan.setDatabase(databaseName);
+ SeriesPartitionKey seriesPartitionKey =
+ configManager.getSeriesPartitionKey(deviceID, databaseName);
+ plan.setSeriesSlotId(executor.getSeriesPartitionSlot(seriesPartitionKey));
if (Objects.equals(plan.getDatabase(), "")) {
// Return empty result if Database not specified
return new GetTimeSlotListResp(RpcUtils.SUCCESS_STATUS, new ArrayList<>());
@@ -1218,8 +1225,11 @@ public class PartitionManager {
} else if (req.isSetDevice()) {
IDeviceID deviceID =
Deserializer.DEFAULT_DESERIALIZER.deserializeFrom(ByteBuffer.wrap(req.getDevice()));
- plan.setDatabase(getClusterSchemaManager().getDatabaseNameByDevice(deviceID));
- plan.setSeriesSlotId(executor.getSeriesPartitionSlot(deviceID));
+ String databaseName = getClusterSchemaManager().getDatabaseNameByDevice(deviceID);
+ plan.setDatabase(databaseName);
+ SeriesPartitionKey seriesPartitionKey =
+ configManager.getSeriesPartitionKey(deviceID, databaseName);
+ plan.setSeriesSlotId(executor.getSeriesPartitionSlot(seriesPartitionKey));
if (Objects.equals(plan.getDatabase(), "")) {
// Return empty result if Database not specified
return new CountTimeSlotListResp(RpcUtils.SUCCESS_STATUS, 0);
diff --git a/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/manager/schema/ClusterSchemaManager.java b/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/manager/schema/ClusterSchemaManager.java
index 490370e38c3..93910947a35 100644
--- a/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/manager/schema/ClusterSchemaManager.java
+++ b/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/manager/schema/ClusterSchemaManager.java
@@ -1486,6 +1486,17 @@ public class ClusterSchemaManager {
null);
}
+ if (!originalTable.canAlterName()) {
+ return new Pair<>(
+ RpcUtils.getStatus(
+ TSStatusCode.SEMANTIC_ERROR,
+ String.format(
+ "Table '%s.%s' is created in a old version and cannot be renamed, "
+ + "please migrate its data to a new table manually",
+ database, tableName)),
+ null);
+ }
+
final Optional<Pair<TSStatus, TsTable>> result =
checkTable4View(database, originalTable, isTableView);
if (result.isPresent()) {
diff --git a/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/procedure/impl/schema/table/RenameTableColumnProcedure.java b/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/procedure/impl/schema/table/RenameTableColumnProcedure.java
index da51dad2672..9bcb651dd42 100644
--- a/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/procedure/impl/schema/table/RenameTableColumnProcedure.java
+++ b/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/procedure/impl/schema/table/RenameTableColumnProcedure.java
@@ -19,10 +19,13 @@
package org.apache.iotdb.confignode.procedure.impl.schema.table;
+import org.apache.iotdb.common.rpc.thrift.TConsensusGroupId;
+import org.apache.iotdb.common.rpc.thrift.TRegionReplicaSet;
import org.apache.iotdb.common.rpc.thrift.TSStatus;
import org.apache.iotdb.commons.exception.IoTDBException;
import org.apache.iotdb.commons.exception.MetadataException;
import org.apache.iotdb.commons.schema.table.TsTable;
+import org.apache.iotdb.confignode.client.async.CnToDnAsyncRequestType;
import org.apache.iotdb.confignode.consensus.request.write.table.RenameTableColumnPlan;
import org.apache.iotdb.confignode.consensus.request.write.table.view.RenameViewColumnPlan;
import org.apache.iotdb.confignode.procedure.env.ConfigNodeProcedureEnv;
@@ -30,9 +33,13 @@ import org.apache.iotdb.confignode.procedure.exception.ProcedureException;
import org.apache.iotdb.confignode.procedure.impl.schema.table.view.RenameViewColumnProcedure;
import org.apache.iotdb.confignode.procedure.state.schema.RenameTableColumnState;
import org.apache.iotdb.confignode.procedure.store.ProcedureType;
+import org.apache.iotdb.db.storageengine.dataregion.tsfile.evolution.ColumnRename;
+import org.apache.iotdb.db.storageengine.dataregion.tsfile.evolution.SchemaEvolution;
+import org.apache.iotdb.mpp.rpc.thrift.TDataRegionEvolveSchemaReq;
import org.apache.iotdb.rpc.TSStatusCode;
import org.apache.tsfile.utils.Pair;
+import org.apache.tsfile.utils.PublicBAOS;
import org.apache.tsfile.utils.ReadWriteIOUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -40,6 +47,10 @@ import org.slf4j.LoggerFactory;
import java.io.DataOutputStream;
import java.io.IOException;
import java.nio.ByteBuffer;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+import java.util.Map;
import java.util.Objects;
public class RenameTableColumnProcedure
@@ -84,6 +95,10 @@ public class RenameTableColumnProcedure
LOGGER.info("Rename column to table {}.{} on config node", database, tableName);
renameColumn(env);
break;
+ case EXECUTE_ON_REGION:
+ LOGGER.info("Rename column to table {}.{} on data regions", database, tableName);
+ executeOnRegions(env);
+ break;
case COMMIT_RELEASE:
LOGGER.info(
"Commit release info of table {}.{} when renaming column", database, tableName);
@@ -141,10 +156,37 @@ public class RenameTableColumnProcedure
if (status.getCode() != TSStatusCode.SUCCESS_STATUS.getStatusCode()) {
setFailure(new ProcedureException(new IoTDBException(status)));
} else {
- setNextState(RenameTableColumnState.COMMIT_RELEASE);
+ setNextState(RenameTableColumnState.EXECUTE_ON_REGION);
}
}
+ private void executeOnRegions(final ConfigNodeProcedureEnv env) {
+ final Map<TConsensusGroupId, TRegionReplicaSet> relatedRegionGroup =
+ env.getConfigManager().getRelatedDataRegionGroup4TableModel(database);
+
+ if (!relatedRegionGroup.isEmpty()) {
+ List<SchemaEvolution> schemaEvolutions =
+ Collections.singletonList(new ColumnRename(tableName, oldName, newName));
+ PublicBAOS publicBAOS = new PublicBAOS();
+ try {
+ SchemaEvolution.serializeList(schemaEvolutions, publicBAOS);
+ } catch (IOException ignored) {
+ }
+ ByteBuffer byteBuffer = ByteBuffer.wrap(publicBAOS.getBuf(), 0, publicBAOS.size());
+ new TableRegionTaskExecutor<>(
+ "evolve data region schema",
+ env,
+ relatedRegionGroup,
+ CnToDnAsyncRequestType.EVOLVE_DATA_REGION_SCHEMA,
+ ((dataNodeLocation, consensusGroupIdList) ->
+ new TDataRegionEvolveSchemaReq(
+ new ArrayList<>(consensusGroupIdList), byteBuffer)))
+ .execute();
+ }
+
+ setNextState(RenameTableColumnState.COMMIT_RELEASE);
+ }
+
@Override
protected void rollbackState(final ConfigNodeProcedureEnv env, final RenameTableColumnState state)
throws IOException, InterruptedException, ProcedureException {
diff --git a/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/procedure/impl/schema/table/RenameTableProcedure.java b/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/procedure/impl/schema/table/RenameTableProcedure.java
index 93d1035a761..bf91e168fe3 100644
--- a/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/procedure/impl/schema/table/RenameTableProcedure.java
+++ b/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/procedure/impl/schema/table/RenameTableProcedure.java
@@ -19,10 +19,13 @@
package org.apache.iotdb.confignode.procedure.impl.schema.table;
+import org.apache.iotdb.common.rpc.thrift.TConsensusGroupId;
+import org.apache.iotdb.common.rpc.thrift.TRegionReplicaSet;
import org.apache.iotdb.common.rpc.thrift.TSStatus;
import org.apache.iotdb.commons.exception.IoTDBException;
import org.apache.iotdb.commons.exception.MetadataException;
import org.apache.iotdb.commons.schema.table.TsTable;
+import org.apache.iotdb.confignode.client.async.CnToDnAsyncRequestType;
import org.apache.iotdb.confignode.consensus.request.write.table.RenameTablePlan;
import org.apache.iotdb.confignode.consensus.request.write.table.view.RenameViewPlan;
import org.apache.iotdb.confignode.procedure.env.ConfigNodeProcedureEnv;
@@ -30,9 +33,14 @@ import org.apache.iotdb.confignode.procedure.exception.ProcedureException;
import org.apache.iotdb.confignode.procedure.impl.schema.table.view.RenameViewProcedure;
import org.apache.iotdb.confignode.procedure.state.schema.RenameTableState;
import org.apache.iotdb.confignode.procedure.store.ProcedureType;
+import org.apache.iotdb.db.storageengine.dataregion.tsfile.evolution.SchemaEvolution;
+import org.apache.iotdb.db.storageengine.dataregion.tsfile.evolution.TableRename;
+import org.apache.iotdb.mpp.rpc.thrift.TDataRegionEvolveSchemaReq;
+import org.apache.iotdb.mpp.rpc.thrift.TSchemaRegionEvolveSchemaReq;
import org.apache.iotdb.rpc.TSStatusCode;
import org.apache.tsfile.utils.Pair;
+import org.apache.tsfile.utils.PublicBAOS;
import org.apache.tsfile.utils.ReadWriteIOUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -40,6 +48,10 @@ import org.slf4j.LoggerFactory;
import java.io.DataOutputStream;
import java.io.IOException;
import java.nio.ByteBuffer;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+import java.util.Map;
public class RenameTableProcedure extends AbstractAlterOrDropTableProcedure<RenameTableState> {
private static final Logger LOGGER = LoggerFactory.getLogger(RenameTableProcedure.class);
@@ -74,9 +86,13 @@ public class RenameTableProcedure extends AbstractAlterOrDropTableProcedure<Rena
preRelease(env);
break;
case RENAME_TABLE:
- LOGGER.info("Rename column to table {}.{} on config node", database, tableName);
+ LOGGER.info("Rename table {}.{} on config node", database, tableName);
renameTable(env);
break;
+ case EXECUTE_ON_REGIONS:
+ LOGGER.info("Rename table {}.{} on regions", database, tableName);
+ executeOnRegions(env);
+ break;
case COMMIT_RELEASE:
LOGGER.info(
"Commit release info of table {}.{} when renaming table", database, tableName);
@@ -134,8 +150,58 @@ public class RenameTableProcedure extends AbstractAlterOrDropTableProcedure<Rena
if (status.getCode() != TSStatusCode.SUCCESS_STATUS.getStatusCode()) {
setFailure(new ProcedureException(new IoTDBException(status)));
} else {
- setNextState(RenameTableState.COMMIT_RELEASE);
+ setNextState(RenameTableState.EXECUTE_ON_REGIONS);
+ }
+ }
+
+ private void executeOnRegions(final ConfigNodeProcedureEnv env) {
+ final Map<TConsensusGroupId, TRegionReplicaSet> relatedDataRegionGroup =
+ env.getConfigManager().getRelatedDataRegionGroup4TableModel(database);
+
+ if (!relatedDataRegionGroup.isEmpty()) {
+ List<SchemaEvolution> schemaEvolutions =
+ Collections.singletonList(new TableRename(tableName, newName));
+ PublicBAOS publicBAOS = new PublicBAOS();
+ try {
+ SchemaEvolution.serializeList(schemaEvolutions, publicBAOS);
+ } catch (IOException ignored) {
+ }
+ ByteBuffer byteBuffer = ByteBuffer.wrap(publicBAOS.getBuf(), 0, publicBAOS.size());
+ new TableRegionTaskExecutor<>(
+ "evolve data region schema",
+ env,
+ relatedDataRegionGroup,
+ CnToDnAsyncRequestType.EVOLVE_DATA_REGION_SCHEMA,
+ ((dataNodeLocation, consensusGroupIdList) ->
+ new TDataRegionEvolveSchemaReq(
+ new ArrayList<>(consensusGroupIdList), byteBuffer)))
+ .execute();
}
+
+ final Map<TConsensusGroupId, TRegionReplicaSet> relatedSchemaRegionGroup =
+ env.getConfigManager().getRelatedSchemaRegionGroup4TableModel(database);
+
+ if (!relatedSchemaRegionGroup.isEmpty()) {
+ List<SchemaEvolution> schemaEvolutions =
+ Collections.singletonList(new TableRename(tableName, newName));
+ PublicBAOS publicBAOS = new PublicBAOS();
+ try {
+ SchemaEvolution.serializeList(schemaEvolutions, publicBAOS);
+ } catch (IOException ignored) {
+ }
+ ByteBuffer byteBuffer = ByteBuffer.wrap(publicBAOS.getBuf(), 0, publicBAOS.size());
+ new TableRegionTaskExecutor<>(
+ "evolve schema region schema",
+ env,
+ relatedSchemaRegionGroup,
+ CnToDnAsyncRequestType.EVOLVE_SCHEMA_REGION_SCHEMA,
+ ((dataNodeLocation, consensusGroupIdList) ->
+ new TSchemaRegionEvolveSchemaReq(
+ new ArrayList<>(consensusGroupIdList), byteBuffer)))
+ .execute();
+ }
+
+ setNextState(RenameTableState.COMMIT_RELEASE);
}
@Override
diff --git a/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/procedure/state/schema/RenameTableColumnState.java b/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/procedure/state/schema/RenameTableColumnState.java
index 398ef642224..83428eadd6d 100644
--- a/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/procedure/state/schema/RenameTableColumnState.java
+++ b/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/procedure/state/schema/RenameTableColumnState.java
@@ -23,5 +23,6 @@ public enum RenameTableColumnState {
COLUMN_CHECK,
PRE_RELEASE,
RENAME_COLUMN,
+ EXECUTE_ON_REGION,
COMMIT_RELEASE
}
diff --git a/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/procedure/state/schema/RenameTableState.java b/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/procedure/state/schema/RenameTableState.java
index 1c71cb50182..6f9e2c29558 100644
--- a/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/procedure/state/schema/RenameTableState.java
+++ b/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/procedure/state/schema/RenameTableState.java
@@ -23,5 +23,6 @@ public enum RenameTableState {
COLUMN_CHECK,
PRE_RELEASE,
RENAME_TABLE,
+ EXECUTE_ON_REGIONS,
COMMIT_RELEASE
}
diff --git a/iotdb-core/confignode/src/test/java/org/apache/iotdb/confignode/manager/hash/DeviceGroupHashExecutorManualTest.java b/iotdb-core/confignode/src/test/java/org/apache/iotdb/confignode/manager/hash/DeviceGroupHashExecutorManualTest.java
index 628cc02524c..3cd19850cb3 100644
--- a/iotdb-core/confignode/src/test/java/org/apache/iotdb/confignode/manager/hash/DeviceGroupHashExecutorManualTest.java
+++ b/iotdb-core/confignode/src/test/java/org/apache/iotdb/confignode/manager/hash/DeviceGroupHashExecutorManualTest.java
@@ -18,6 +18,7 @@
*/
package org.apache.iotdb.confignode.manager.hash;
+import org.apache.iotdb.commons.partition.executor.SeriesPartitionExecutor.FullDeviceIdKey;
import org.apache.iotdb.confignode.manager.ConfigManager;
import org.apache.iotdb.confignode.manager.partition.PartitionManager;
import org.apache.iotdb.confignode.persistence.partition.PartitionInfo;
@@ -74,7 +75,7 @@ public class DeviceGroupHashExecutorManualTest {
List<IDeviceID> devices = genBatchDevices();
totalTime -= System.currentTimeMillis();
for (IDeviceID device : devices) {
- bucket[manager.getSeriesPartitionSlot(device).getSlotId()] += 1;
+ bucket[manager.getSeriesPartitionSlot(new FullDeviceIdKey(device)).getSlotId()] += 1;
}
totalTime += System.currentTimeMillis();
}
diff --git a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/consensus/statemachine/schemaregion/SchemaExecutionVisitor.java b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/consensus/statemachine/schemaregion/SchemaExecutionVisitor.java
index 261b4908a90..63747b6c922 100644
--- a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/consensus/statemachine/schemaregion/SchemaExecutionVisitor.java
+++ b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/consensus/statemachine/schemaregion/SchemaExecutionVisitor.java
@@ -61,6 +61,7 @@ import org.apache.iotdb.db.queryengine.plan.planner.plan.node.metadata.write.vie
import org.apache.iotdb.db.queryengine.plan.planner.plan.node.pipe.PipeEnrichedNonWritePlanNode;
import org.apache.iotdb.db.queryengine.plan.planner.plan.node.pipe.PipeEnrichedWritePlanNode;
import org.apache.iotdb.db.queryengine.plan.planner.plan.node.pipe.PipeOperateSchemaQueueNode;
+import org.apache.iotdb.db.queryengine.plan.planner.plan.node.write.EvolveSchemaNode;
import org.apache.iotdb.db.queryengine.plan.relational.planner.node.schema.ConstructTableDevicesBlackListNode;
import org.apache.iotdb.db.queryengine.plan.relational.planner.node.schema.CreateOrUpdateTableDeviceNode;
import org.apache.iotdb.db.queryengine.plan.relational.planner.node.schema.DeleteTableDeviceNode;
@@ -854,6 +855,17 @@ public class SchemaExecutionVisitor extends PlanVisitor<TSStatus, ISchemaRegion>
return new TSStatus(TSStatusCode.SUCCESS_STATUS.getStatusCode());
}
+ @Override
+ public TSStatus visitEvolveSchemaNode(EvolveSchemaNode node, ISchemaRegion schemaRegion) {
+ try {
+ schemaRegion.applySchemaEvolution(node);
+ } catch (MetadataException e) {
+ logMetaDataException(e);
+ return RpcUtils.getStatus(e.getErrorCode(), e.getMessage());
+ }
+ return new TSStatus(TSStatusCode.SUCCESS_STATUS.getStatusCode());
+ }
+
@Override
public TSStatus visitPlan(final PlanNode node, final ISchemaRegion context) {
return null;
diff --git a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/protocol/thrift/impl/DataNodeInternalRPCServiceImpl.java b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/protocol/thrift/impl/DataNodeInternalRPCServiceImpl.java
index bb66664b4ed..e70679ef1e7 100644
--- a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/protocol/thrift/impl/DataNodeInternalRPCServiceImpl.java
+++ b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/protocol/thrift/impl/DataNodeInternalRPCServiceImpl.java
@@ -298,6 +298,7 @@ import org.apache.iotdb.mpp.rpc.thrift.TRollbackSchemaBlackListWithTemplateReq;
import org.apache.iotdb.mpp.rpc.thrift.TRollbackViewSchemaBlackListReq;
import org.apache.iotdb.mpp.rpc.thrift.TSchemaFetchRequest;
import org.apache.iotdb.mpp.rpc.thrift.TSchemaFetchResponse;
+import org.apache.iotdb.mpp.rpc.thrift.TSchemaRegionEvolveSchemaReq;
import org.apache.iotdb.mpp.rpc.thrift.TSendBatchPlanNodeReq;
import org.apache.iotdb.mpp.rpc.thrift.TSendBatchPlanNodeResp;
import org.apache.iotdb.mpp.rpc.thrift.TSendFragmentInstanceReq;
@@ -816,6 +817,25 @@ public class DataNodeInternalRPCServiceImpl implements IDataNodeRPCService.Iface
.getStatus());
}
+ @Override
+ public TSStatus evolveSchemaInSchemaRegion(final TSchemaRegionEvolveSchemaReq req) {
+ final List<SchemaEvolution> schemaEvolutions =
+ SchemaEvolution.createListFrom(req.schemaEvolutions);
+ return executeInternalSchemaTask(
+ req.getSchemaRegionIdList(),
+ consensusGroupId ->
+ new RegionWriteExecutor()
+ .execute(
+ new SchemaRegionId(consensusGroupId.getId()),
+ // Now the deletion plan may be re-collected here by pipe, resulting multiple
+ // transfer to delete time series plan. Now just ignore.
+ req.isSetIsGeneratedByPipe() && req.isIsGeneratedByPipe()
+ ? new PipeEnrichedEvolveSchemaNode(
+ new EvolveSchemaNode(new PlanNodeId(""), schemaEvolutions))
+ : new EvolveSchemaNode(new PlanNodeId(""), schemaEvolutions))
+ .getStatus());
+ }
+
@Override
public TSStatus deleteTimeSeries(final TDeleteTimeSeriesReq req) throws TException {
final PathPatternTree patternTree =
diff --git a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/analyze/ClusterPartitionFetcher.java b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/analyze/ClusterPartitionFetcher.java
index 2274762341b..3333bb6fe2c 100644
--- a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/analyze/ClusterPartitionFetcher.java
+++ b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/analyze/ClusterPartitionFetcher.java
@@ -47,6 +47,7 @@ import org.apache.iotdb.db.protocol.client.ConfigNodeClient;
import org.apache.iotdb.db.protocol.client.ConfigNodeClientManager;
import org.apache.iotdb.db.protocol.client.ConfigNodeInfo;
import org.apache.iotdb.db.queryengine.plan.analyze.cache.partition.PartitionCache;
+import org.apache.iotdb.db.utils.CommonUtils;
import org.apache.iotdb.mpp.rpc.thrift.TRegionRouteReq;
import org.apache.iotdb.rpc.TSStatusCode;
@@ -347,6 +348,7 @@ public class ClusterPartitionFetcher implements IPartitionFetcher {
final List<TSeriesPartitionSlot> partitionSlots =
Objects.nonNull(deviceIDs)
? deviceIDs.stream()
+ .map(deviceID -> CommonUtils.getSeriesPartitionKey(deviceID, database))
.map(partitionExecutor::getSeriesPartitionSlot)
.distinct()
.collect(Collectors.toList())
@@ -458,6 +460,7 @@ public class ClusterPartitionFetcher implements IPartitionFetcher {
final Map<String, Map<TSeriesPartitionSlot, TTimeSlotList>> partitionSlotsMap = new HashMap<>();
for (final Map.Entry<String, List<DataPartitionQueryParam>> entry :
sgNameToQueryParamsMap.entrySet()) {
+ String databaseName = entry.getKey();
// for each sg
final Map<TSeriesPartitionSlot, TTimeSlotList> deviceToTimePartitionMap = new HashMap<>();
@@ -467,7 +470,8 @@ public class ClusterPartitionFetcher implements IPartitionFetcher {
for (final DataPartitionQueryParam queryParam : entry.getValue()) {
seriesSlotTimePartitionMap
.computeIfAbsent(
- partitionExecutor.getSeriesPartitionSlot(queryParam.getDeviceID()),
+ partitionExecutor.getSeriesPartitionSlot(
+ CommonUtils.getSeriesPartitionKey(queryParam.getDeviceID(), databaseName)),
k ->
new ComplexTimeSlotList(
queryParam.isNeedLeftAll(), queryParam.isNeedRightAll()))
@@ -479,7 +483,7 @@ public class ClusterPartitionFetcher implements IPartitionFetcher {
k,
new TTimeSlotList(
new ArrayList<>(v.timeSlotList), v.needLeftAll, v.needRightAll)));
- partitionSlotsMap.put(entry.getKey(), deviceToTimePartitionMap);
+ partitionSlotsMap.put(databaseName, deviceToTimePartitionMap);
}
return new TDataPartitionReq(partitionSlotsMap);
}
@@ -491,6 +495,7 @@ public class ClusterPartitionFetcher implements IPartitionFetcher {
TTimeSlotList sharedTTimeSlotList = null;
for (final Map.Entry<String, List<DataPartitionQueryParam>> entry :
sgNameToQueryParamsMap.entrySet()) {
+ String databaseName = entry.getKey();
// for each sg
final Map<TSeriesPartitionSlot, TTimeSlotList> deviceToTimePartitionMap = new HashMap<>();
@@ -503,10 +508,11 @@ public class ClusterPartitionFetcher implements IPartitionFetcher {
queryParam.isNeedRightAll());
}
deviceToTimePartitionMap.putIfAbsent(
- partitionExecutor.getSeriesPartitionSlot(queryParam.getDeviceID()),
+ partitionExecutor.getSeriesPartitionSlot(
+ CommonUtils.getSeriesPartitionKey(queryParam.getDeviceID(), databaseName)),
sharedTTimeSlotList);
}
- partitionSlotsMap.put(entry.getKey(), deviceToTimePartitionMap);
+ partitionSlotsMap.put(databaseName, deviceToTimePartitionMap);
}
return new TDataPartitionReq(partitionSlotsMap);
}
diff --git a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/analyze/cache/partition/PartitionCache.java b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/analyze/cache/partition/PartitionCache.java
index 3c76bd08c1d..36ba860ad2e 100644
--- a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/analyze/cache/partition/PartitionCache.java
+++ b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/analyze/cache/partition/PartitionCache.java
@@ -60,6 +60,7 @@ import org.apache.iotdb.db.protocol.session.IClientSession;
import org.apache.iotdb.db.protocol.session.SessionManager;
import org.apache.iotdb.db.schemaengine.schemaregion.utils.MetaUtils;
import org.apache.iotdb.db.service.metrics.CacheMetrics;
+import org.apache.iotdb.db.utils.CommonUtils;
import org.apache.iotdb.rpc.TSStatusCode;
import com.github.benmanes.caffeine.cache.Cache;
@@ -707,7 +708,8 @@ public class PartitionCache {
List<TConsensusGroupId> consensusGroupIds = new ArrayList<>(entry.getValue().size());
for (final IDeviceID device : entry.getValue()) {
final TSeriesPartitionSlot seriesPartitionSlot =
- partitionExecutor.getSeriesPartitionSlot(device);
+ partitionExecutor.getSeriesPartitionSlot(
+ CommonUtils.getSeriesPartitionKey(device, databaseName));
if (!map.containsKey(seriesPartitionSlot)) {
// if one device not find, then return cache miss.
if (logger.isDebugEnabled()) {
@@ -874,7 +876,9 @@ public class PartitionCache {
for (DataPartitionQueryParam param : params) {
TSeriesPartitionSlot seriesPartitionSlot;
if (null != param.getDeviceID()) {
- seriesPartitionSlot = partitionExecutor.getSeriesPartitionSlot(param.getDeviceID());
+ seriesPartitionSlot =
+ partitionExecutor.getSeriesPartitionSlot(
+ CommonUtils.getSeriesPartitionKey(param.getDeviceID(), databaseName));
} else {
return null;
}
diff --git a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/execution/config/TableConfigTaskVisitor.java b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/execution/config/TableConfigTaskVisitor.java
index 4b609aa87eb..3cdd5525f1f 100644
--- a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/execution/config/TableConfigTaskVisitor.java
+++ b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/execution/config/TableConfigTaskVisitor.java
@@ -141,6 +141,7 @@ import org.apache.iotdb.db.queryengine.plan.relational.sql.ast.AlterColumnDataTy
import org.apache.iotdb.db.queryengine.plan.relational.sql.ast.AlterDB;
import org.apache.iotdb.db.queryengine.plan.relational.sql.ast.AlterPipe;
import org.apache.iotdb.db.queryengine.plan.relational.sql.ast.AstVisitor;
+import org.apache.iotdb.db.queryengine.plan.relational.sql.ast.BooleanLiteral;
import org.apache.iotdb.db.queryengine.plan.relational.sql.ast.ClearCache;
import org.apache.iotdb.db.queryengine.plan.relational.sql.ast.ColumnDefinition;
import org.apache.iotdb.db.queryengine.plan.relational.sql.ast.CreateDB;
@@ -268,7 +269,7 @@ import static org.apache.iotdb.commons.conf.IoTDBConstant.MAX_DATABASE_NAME_LENG
import static org.apache.iotdb.commons.conf.IoTDBConstant.TTL_INFINITE;
import static org.apache.iotdb.commons.executable.ExecutableManager.getUnTrustedUriErrorMsg;
import static org.apache.iotdb.commons.executable.ExecutableManager.isUriTrusted;
-import static org.apache.iotdb.commons.schema.table.TsTable.TABLE_ALLOWED_PROPERTIES;
+import static org.apache.iotdb.commons.schema.table.TsTable.ALLOW_ALTER_NAME_PROPERTY;
import static org.apache.iotdb.commons.schema.table.TsTable.TIME_COLUMN_NAME;
import static org.apache.iotdb.commons.schema.table.TsTable.TTL_PROPERTY;
import static org.apache.iotdb.db.queryengine.plan.execution.config.metadata.relational.CreateDBTask.DATA_REGION_GROUP_NUM_KEY;
@@ -567,7 +568,10 @@ public class TableConfigTaskVisitor extends AstVisitor<IConfigTask, MPPQueryCont
final TsTable table = new TsTable(tableName);
- table.setProps(convertPropertiesToMap(node.getProperties(), false));
+ Map<String, String> properties = convertPropertiesToMap(node.getProperties(), false);
+ // new tables' names can be altered by default
+ properties.putIfAbsent(ALLOW_ALTER_NAME_PROPERTY, "true");
+ table.setProps(properties);
if (Objects.nonNull(node.getComment())) {
table.addProp(TsTable.COMMENT_KEY, node.getComment());
}
@@ -779,10 +783,15 @@ public class TableConfigTaskVisitor extends AstVisitor<IConfigTask, MPPQueryCont
accessControl.checkCanAlterTable(
context.getSession().getUserName(), new QualifiedObjectName(database, tableName), context);
+ Map<String, String> properties = convertPropertiesToMap(node.getProperties(), true);
+ if (properties.containsKey(ALLOW_ALTER_NAME_PROPERTY)) {
+ throw new SemanticException(
+ "The property " + ALLOW_ALTER_NAME_PROPERTY + " cannot be altered.");
+ }
return new AlterTableSetPropertiesTask(
database,
tableName,
- convertPropertiesToMap(node.getProperties(), true),
+ properties,
context.getQueryId().getId(),
node.ifExists(),
node.getType() == SetProperties.Type.TREE_VIEW);
@@ -859,7 +868,7 @@ public class TableConfigTaskVisitor extends AstVisitor<IConfigTask, MPPQueryCont
final Map<String, String> map = new HashMap<>();
for (final Property property : propertyList) {
final String key = property.getName().getValue().toLowerCase(Locale.ENGLISH);
- if (TABLE_ALLOWED_PROPERTIES.contains(key)) {
+ if (TTL_PROPERTY.equals(key)) {
if (!property.isSetToDefault()) {
final Expression value = property.getNonDefaultValue();
final Optional<String> strValue = parseStringFromLiteralIfBinary(value);
@@ -876,6 +885,27 @@ public class TableConfigTaskVisitor extends AstVisitor<IConfigTask, MPPQueryCont
} else if (serializeDefault) {
map.put(key, null);
}
+ } else if (ALLOW_ALTER_NAME_PROPERTY.equals(key)) {
+ if (property.isSetToDefault()) {
+ // no such property, the table is from an older version and its table name
+ // cannot be altered
+ map.put(key, "false");
+ } else {
+ Expression value = property.getNonDefaultValue();
+ final Optional<String> strValue = parseStringFromLiteralIfBinary(value);
+ if (strValue.isPresent()) {
+ try {
+ boolean ignored = Boolean.parseBoolean(strValue.get());
+ } catch (Exception e) {
+ throw new SemanticException(
+ ALLOW_ALTER_NAME_PROPERTY + " value must be a boolean, but now is: " + value);
+ }
+ map.put(key, strValue.get());
+ continue;
+ }
+ // TODO: support validation for other properties
+ map.put(key, String.valueOf(parseBooleanFromLiteral(value, ALLOW_ALTER_NAME_PROPERTY)));
+ }
} else {
throw new SemanticException("Table property '" + key + "' is currently not allowed.");
}
@@ -1073,6 +1103,18 @@ public class TableConfigTaskVisitor extends AstVisitor<IConfigTask, MPPQueryCont
return parsedValue;
}
+ private boolean parseBooleanFromLiteral(final Object value, final String name) {
+ if (!(value instanceof BooleanLiteral)) {
+ throw new SemanticException(
+ name
+ + " value must be a BooleanLiteral, but now is "
+ + (Objects.nonNull(value) ? value.getClass().getSimpleName() : null)
+ + ", value: "
+ + value);
+ }
+ return ((BooleanLiteral) value).getParsedValue();
+ }
+
private int parseIntFromLiteral(final Object value, final String name) {
if (!(value instanceof LongLiteral)) {
throw new SemanticException(
diff --git a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/planner/distribution/SourceRewriter.java b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/planner/distribution/SourceRewriter.java
index bc6475b2323..c3839a2e630 100644
--- a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/planner/distribution/SourceRewriter.java
+++ b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/planner/distribution/SourceRewriter.java
@@ -24,6 +24,7 @@ import org.apache.iotdb.common.rpc.thrift.TSeriesPartitionSlot;
import org.apache.iotdb.common.rpc.thrift.TTimePartitionSlot;
import org.apache.iotdb.commons.exception.IllegalPathException;
import org.apache.iotdb.commons.partition.DataPartition;
+import org.apache.iotdb.commons.partition.executor.SeriesPartitionExecutor.SeriesPartitionKey;
import org.apache.iotdb.commons.path.PartialPath;
import org.apache.iotdb.commons.path.PathPatternTree;
import org.apache.iotdb.commons.schema.SchemaConstant;
@@ -84,6 +85,7 @@ import org.apache.iotdb.db.queryengine.plan.planner.plan.parameter.OrderByParame
import org.apache.iotdb.db.queryengine.plan.statement.component.OrderByKey;
import org.apache.iotdb.db.queryengine.plan.statement.component.Ordering;
import org.apache.iotdb.db.queryengine.plan.statement.component.SortItem;
+import org.apache.iotdb.db.utils.CommonUtils;
import org.apache.iotdb.db.utils.constant.SqlConstant;
import com.google.common.collect.ImmutableList;
@@ -1442,7 +1444,10 @@ public class SourceRewriter extends BaseSourceRewriter<DistributionPlanContext>
Map<Integer, List<TRegionReplicaSet>> slot2ReplicasMap =
cache.computeIfAbsent(db, k -> new HashMap<>());
- TSeriesPartitionSlot tSeriesPartitionSlot = dataPartition.calculateDeviceGroupId(deviceID);
+
+ SeriesPartitionKey seriesPartitionKey = CommonUtils.getSeriesPartitionKey(deviceID, db);
+ TSeriesPartitionSlot tSeriesPartitionSlot =
+ dataPartition.calculateDeviceGroupId(seriesPartitionKey);
Map<TSeriesPartitionSlot, Map<TTimePartitionSlot, List<TRegionReplicaSet>>>
finalSeriesPartitionMap = seriesPartitionMap;
diff --git a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/planner/plan/node/write/EvolveSchemaNode.java b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/planner/plan/node/write/EvolveSchemaNode.java
index b4fc82e0710..834fd05887d 100644
--- a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/planner/plan/node/write/EvolveSchemaNode.java
+++ b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/planner/plan/node/write/EvolveSchemaNode.java
@@ -27,6 +27,9 @@ import org.apache.iotdb.db.queryengine.plan.planner.plan.node.PlanNodeId;
import org.apache.iotdb.db.queryengine.plan.planner.plan.node.PlanNodeType;
import org.apache.iotdb.db.queryengine.plan.planner.plan.node.PlanVisitor;
import org.apache.iotdb.db.queryengine.plan.planner.plan.node.WritePlanNode;
+import org.apache.iotdb.db.schemaengine.schemaregion.ISchemaRegionPlan;
+import org.apache.iotdb.db.schemaengine.schemaregion.SchemaRegionPlanType;
+import org.apache.iotdb.db.schemaengine.schemaregion.SchemaRegionPlanVisitor;
import org.apache.iotdb.db.storageengine.dataregion.tsfile.evolution.SchemaEvolution;
import org.apache.iotdb.db.storageengine.dataregion.wal.buffer.IWALByteBufferView;
import org.apache.iotdb.db.storageengine.dataregion.wal.buffer.WALEntryValue;
@@ -45,13 +48,17 @@ import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
-public class EvolveSchemaNode extends SearchNode implements WALEntryValue {
+public class EvolveSchemaNode extends SearchNode implements WALEntryValue, ISchemaRegionPlan {
private static final Logger LOGGER = LoggerFactory.getLogger(EvolveSchemaNode.class);
protected TRegionReplicaSet regionReplicaSet;
protected ProgressIndex progressIndex;
- private final List<SchemaEvolution> schemaEvolutions;
+ private List<SchemaEvolution> schemaEvolutions;
+
+ public EvolveSchemaNode() {
+ super(new PlanNodeId(""));
+ }
public EvolveSchemaNode(PlanNodeId id, List<SchemaEvolution> schemaEvolutions) {
super(id);
@@ -186,4 +193,14 @@ public class EvolveSchemaNode extends SearchNode implements WALEntryValue {
public <R, C> R accept(PlanVisitor<R, C> visitor, C context) {
return visitor.visitEvolveSchemaNode(this, context);
}
+
+ @Override
+ public SchemaRegionPlanType getPlanType() {
+ return SchemaRegionPlanType.EVOLVE_SCHEMA;
+ }
+
+ @Override
+ public <R, C> R accept(SchemaRegionPlanVisitor<R, C> visitor, C context) {
+ return visitor.visitEvolveSchema(this, context);
+ }
}
diff --git a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/planner/plan/node/write/InsertRowNode.java b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/planner/plan/node/write/InsertRowNode.java
index a2bd6cb1a00..ffe5a3b99cd 100644
--- a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/planner/plan/node/write/InsertRowNode.java
+++ b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/planner/plan/node/write/InsertRowNode.java
@@ -21,6 +21,7 @@ package org.apache.iotdb.db.queryengine.plan.planner.plan.node.write;
import org.apache.iotdb.common.rpc.thrift.TTimePartitionSlot;
import org.apache.iotdb.commons.exception.IllegalPathException;
+import org.apache.iotdb.commons.partition.executor.SeriesPartitionExecutor.FullDeviceIdKey;
import org.apache.iotdb.commons.path.PartialPath;
import org.apache.iotdb.commons.utils.TestOnly;
import org.apache.iotdb.commons.utils.TimePartitionUtils;
@@ -129,7 +130,7 @@ public class InsertRowNode extends InsertNode implements WALEntryValue {
analysis
.getDataPartitionInfo()
.getDataRegionReplicaSetForWriting(
- getDeviceID(), timePartitionSlot, analysis.getDatabaseName());
+ new FullDeviceIdKey(getDeviceID()), timePartitionSlot, analysis.getDatabaseName());
// collect redirectInfo
analysis.setRedirectNodeList(
Collections.singletonList(
diff --git a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/planner/plan/node/write/InsertRowsNode.java b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/planner/plan/node/write/InsertRowsNode.java
index 7392b761270..7494f62bc87 100644
--- a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/planner/plan/node/write/InsertRowsNode.java
+++ b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/planner/plan/node/write/InsertRowsNode.java
@@ -23,6 +23,7 @@ import org.apache.iotdb.common.rpc.thrift.TEndPoint;
import org.apache.iotdb.common.rpc.thrift.TRegionReplicaSet;
import org.apache.iotdb.common.rpc.thrift.TSStatus;
import org.apache.iotdb.commons.consensus.index.ProgressIndex;
+import org.apache.iotdb.commons.partition.executor.SeriesPartitionExecutor.FullDeviceIdKey;
import org.apache.iotdb.commons.utils.StatusUtils;
import org.apache.iotdb.commons.utils.TimePartitionUtils;
import org.apache.iotdb.db.exception.DataTypeInconsistentException;
@@ -276,7 +277,7 @@ public class InsertRowsNode extends InsertNode implements WALEntryValue {
analysis
.getDataPartitionInfo()
.getDataRegionReplicaSetForWriting(
- insertRowNode.targetPath.getIDeviceIDAsFullDevice(),
+ new FullDeviceIdKey(insertRowNode.targetPath.getIDeviceIDAsFullDevice()),
TimePartitionUtils.getTimePartitionSlot(insertRowNode.getTime()),
null);
// Collect redirectInfo
diff --git a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/planner/plan/node/write/InsertRowsOfOneDeviceNode.java b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/planner/plan/node/write/InsertRowsOfOneDeviceNode.java
index f1e28d32b10..f54d62a7a2b 100644
--- a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/planner/plan/node/write/InsertRowsOfOneDeviceNode.java
+++ b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/planner/plan/node/write/InsertRowsOfOneDeviceNode.java
@@ -23,6 +23,7 @@ import org.apache.iotdb.common.rpc.thrift.TSStatus;
import org.apache.iotdb.common.rpc.thrift.TTimePartitionSlot;
import org.apache.iotdb.commons.consensus.index.ProgressIndex;
import org.apache.iotdb.commons.exception.IllegalPathException;
+import org.apache.iotdb.commons.partition.executor.SeriesPartitionExecutor.FullDeviceIdKey;
import org.apache.iotdb.commons.path.PartialPath;
import org.apache.iotdb.commons.utils.StatusUtils;
import org.apache.iotdb.commons.utils.TimePartitionUtils;
@@ -173,7 +174,7 @@ public class InsertRowsOfOneDeviceNode extends InsertNode {
analysis
.getDataPartitionInfo()
.getDataRegionReplicaSetForWriting(
- targetPath.getIDeviceIDAsFullDevice(),
+ new FullDeviceIdKey(targetPath.getIDeviceIDAsFullDevice()),
timePartitionSlot,
analysis.getDatabaseName());
Map<TTimePartitionSlot, List<InsertRowNode>> tmpMap =
diff --git a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/planner/plan/node/write/InsertTabletNode.java b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/planner/plan/node/write/InsertTabletNode.java
index 39683e5d9f9..c6991316447 100644
--- a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/planner/plan/node/write/InsertTabletNode.java
+++ b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/planner/plan/node/write/InsertTabletNode.java
@@ -23,6 +23,7 @@ import org.apache.iotdb.common.rpc.thrift.TRegionReplicaSet;
import org.apache.iotdb.common.rpc.thrift.TSStatus;
import org.apache.iotdb.common.rpc.thrift.TTimePartitionSlot;
import org.apache.iotdb.commons.exception.IllegalPathException;
+import org.apache.iotdb.commons.partition.executor.SeriesPartitionExecutor.FullDeviceIdKey;
import org.apache.iotdb.commons.path.PartialPath;
import org.apache.iotdb.commons.utils.CommonDateTimeUtils;
import org.apache.iotdb.commons.utils.TestOnly;
@@ -288,7 +289,9 @@ public class InsertTabletNode extends InsertNode implements WALEntryValue {
analysis
.getDataPartitionInfo()
.getDataRegionReplicaSetForWriting(
- deviceID, splitInfo.timePartitionSlots, analysis.getDatabaseName());
+ new FullDeviceIdKey(deviceID),
+ splitInfo.timePartitionSlots,
+ analysis.getDatabaseName());
splitInfo.replicaSets = replicaSets;
// collect redirectInfo
analysis.addEndPointToRedirectNodeList(
diff --git a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/planner/plan/node/write/RelationalInsertRowsNode.java b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/planner/plan/node/write/RelationalInsertRowsNode.java
index cd53d65fe5a..de397125d7c 100644
--- a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/planner/plan/node/write/RelationalInsertRowsNode.java
+++ b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/planner/plan/node/write/RelationalInsertRowsNode.java
@@ -21,6 +21,7 @@ package org.apache.iotdb.db.queryengine.plan.planner.plan.node.write;
import org.apache.iotdb.common.rpc.thrift.TEndPoint;
import org.apache.iotdb.common.rpc.thrift.TRegionReplicaSet;
+import org.apache.iotdb.commons.partition.executor.SeriesPartitionExecutor.SeriesPartitionKey;
import org.apache.iotdb.commons.utils.TimePartitionUtils;
import org.apache.iotdb.db.exception.DataTypeInconsistentException;
import org.apache.iotdb.db.queryengine.plan.analyze.IAnalysis;
@@ -30,6 +31,7 @@ import org.apache.iotdb.db.queryengine.plan.planner.plan.node.PlanVisitor;
import org.apache.iotdb.db.queryengine.plan.planner.plan.node.WritePlanNode;
import org.apache.iotdb.db.storageengine.dataregion.IObjectPath;
import org.apache.iotdb.db.storageengine.dataregion.memtable.AbstractMemTable;
+import org.apache.iotdb.db.utils.CommonUtils;
import org.apache.tsfile.enums.TSDataType;
import org.apache.tsfile.file.metadata.IDeviceID;
@@ -174,11 +176,14 @@ public class RelationalInsertRowsNode extends InsertRowsNode {
InsertRowNode insertRowNode = getInsertRowNodeList().get(i);
// Data region for insert row node
// each row may belong to different database, pass null for auto-detection
+ SeriesPartitionKey seriesPartitionKey =
+ CommonUtils.getSeriesPartitionKey(
+ insertRowNode.getDeviceID(), analysis.getDatabaseName());
TRegionReplicaSet dataRegionReplicaSet =
analysis
.getDataPartitionInfo()
.getDataRegionReplicaSetForWriting(
- insertRowNode.getDeviceID(),
+ seriesPartitionKey,
TimePartitionUtils.getTimePartitionSlot(insertRowNode.getTime()),
analysis.getDatabaseName());
// handle object type
diff --git a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/planner/plan/node/write/RelationalInsertTabletNode.java b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/planner/plan/node/write/RelationalInsertTabletNode.java
index 2bad744cfb9..3987818fff1 100644
--- a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/planner/plan/node/write/RelationalInsertTabletNode.java
+++ b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/planner/plan/node/write/RelationalInsertTabletNode.java
@@ -22,6 +22,7 @@ package org.apache.iotdb.db.queryengine.plan.planner.plan.node.write;
import org.apache.iotdb.common.rpc.thrift.TEndPoint;
import org.apache.iotdb.common.rpc.thrift.TRegionReplicaSet;
import org.apache.iotdb.common.rpc.thrift.TSStatus;
+import org.apache.iotdb.commons.partition.executor.SeriesPartitionExecutor.SeriesPartitionKey;
import org.apache.iotdb.commons.path.PartialPath;
import org.apache.iotdb.commons.schema.table.column.TsTableColumnCategory;
import org.apache.iotdb.commons.utils.TestOnly;
@@ -37,6 +38,7 @@ import org.apache.iotdb.db.storageengine.dataregion.IObjectPath;
import org.apache.iotdb.db.storageengine.dataregion.memtable.AbstractMemTable;
import org.apache.iotdb.db.storageengine.dataregion.memtable.IWritableMemChunkGroup;
import org.apache.iotdb.db.storageengine.dataregion.wal.buffer.IWALByteBufferView;
+import org.apache.iotdb.db.utils.CommonUtils;
import org.apache.tsfile.enums.TSDataType;
import org.apache.tsfile.file.metadata.IDeviceID;
@@ -210,11 +212,13 @@ public class RelationalInsertTabletNode extends InsertTabletNode {
for (final Map.Entry<IDeviceID, PartitionSplitInfo> entry : deviceIDSplitInfoMap.entrySet()) {
final IDeviceID deviceID = entry.getKey();
final PartitionSplitInfo splitInfo = entry.getValue();
+ SeriesPartitionKey seriesPartitionKey =
+ CommonUtils.getSeriesPartitionKey(deviceID, analysis.getDatabaseName());
final List<TRegionReplicaSet> replicaSets =
analysis
.getDataPartitionInfo()
.getDataRegionReplicaSetForWriting(
- deviceID, splitInfo.timePartitionSlots, analysis.getDatabaseName());
+ seriesPartitionKey, splitInfo.timePartitionSlots, analysis.getDatabaseName());
splitInfo.replicaSets = replicaSets;
// collect redirectInfo
endPointMap.put(
diff --git a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/planner/distribute/TableDistributedPlanGenerator.java b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/planner/distribute/TableDistributedPlanGenerator.java
index e13d09de4a5..81a67ddd991 100644
--- a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/planner/distribute/TableDistributedPlanGenerator.java
+++ b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/planner/distribute/TableDistributedPlanGenerator.java
@@ -26,6 +26,7 @@ import org.apache.iotdb.common.rpc.thrift.TTimePartitionSlot;
import org.apache.iotdb.commons.exception.IoTDBRuntimeException;
import org.apache.iotdb.commons.partition.DataPartition;
import org.apache.iotdb.commons.partition.SchemaPartition;
+import org.apache.iotdb.commons.partition.executor.SeriesPartitionExecutor.SeriesPartitionKey;
import org.apache.iotdb.commons.schema.table.TsTable;
import org.apache.iotdb.commons.schema.table.column.TsTableColumnCategory;
import org.apache.iotdb.commons.utils.TimePartitionUtils;
@@ -101,6 +102,7 @@ import org.apache.iotdb.db.queryengine.plan.relational.sql.ast.SymbolReference;
import org.apache.iotdb.db.queryengine.plan.statement.component.Ordering;
import org.apache.iotdb.db.schemaengine.table.DataNodeTableCache;
import org.apache.iotdb.db.schemaengine.table.DataNodeTreeViewSchemaUtils;
+import org.apache.iotdb.db.utils.CommonUtils;
import org.apache.iotdb.rpc.TSStatusCode;
import com.google.common.collect.ImmutableList;
@@ -711,7 +713,8 @@ public class TableDistributedPlanGenerator
seriesSlotMap,
deviceEntry.getDeviceID(),
node.getTimeFilter(),
- cachedSeriesSlotWithRegions);
+ cachedSeriesSlotWithRegions,
+ dbName);
regionReplicaSets.forEach(
regionReplicaSet ->
regionDeviceCount.put(
@@ -802,7 +805,8 @@ public class TableDistributedPlanGenerator
seriesSlotMap,
deviceEntry.getDeviceID(),
node.getTimeFilter(),
- cachedSeriesSlotWithRegions);
+ cachedSeriesSlotWithRegions,
+ dbName);
if (regionReplicaSets.size() > 1) {
context.deviceCrossRegion = true;
}
@@ -892,7 +896,8 @@ public class TableDistributedPlanGenerator
seriesSlotMap,
deviceEntry.getDeviceID(),
node.getTimeFilter(),
- cachedSeriesSlotWithRegions);
+ cachedSeriesSlotWithRegions,
+ dbName);
if (regionReplicaSets.size() > 1) {
context.deviceCrossRegion = true;
@@ -1212,7 +1217,8 @@ public class TableDistributedPlanGenerator
seriesSlotMap,
deviceEntry.getDeviceID(),
node.getTimeFilter(),
- cachedSeriesSlotWithRegions);
+ cachedSeriesSlotWithRegions,
+ dbName);
if (regionReplicaSets.size() > 1) {
needSplit = true;
context.deviceCrossRegion = true;
@@ -1295,10 +1301,14 @@ public class TableDistributedPlanGenerator
Map<TSeriesPartitionSlot, Map<TTimePartitionSlot, List<TRegionReplicaSet>>> seriesSlotMap,
IDeviceID deviceId,
Filter timeFilter,
- Map<Integer, List<TRegionReplicaSet>> cachedSeriesSlotWithRegions) {
+ Map<Integer, List<TRegionReplicaSet>> cachedSeriesSlotWithRegions,
+ String databaseName) {
// given seriesPartitionSlot has already been calculated
- final TSeriesPartitionSlot seriesPartitionSlot = dataPartition.calculateDeviceGroupId(deviceId);
+ SeriesPartitionKey seriesPartitionKey =
+ CommonUtils.getSeriesPartitionKey(deviceId, databaseName);
+ final TSeriesPartitionSlot seriesPartitionSlot =
+ dataPartition.calculateDeviceGroupId(seriesPartitionKey);
List<TRegionReplicaSet> regionReplicaSets =
cachedSeriesSlotWithRegions.get(seriesPartitionSlot.getSlotId());
if (regionReplicaSets != null) {
@@ -1777,8 +1787,10 @@ public class TableDistributedPlanGenerator
final List<IDeviceID> partitionKeyList = node.getPartitionKeyList();
final List<Object[]> deviceIDArray = node.getDeviceIdList();
for (int i = 0; i < node.getPartitionKeyList().size(); ++i) {
+ SeriesPartitionKey seriesPartitionKey =
+ CommonUtils.getSeriesPartitionKey(partitionKeyList.get(i), database);
final TRegionReplicaSet regionReplicaSet =
- databaseMap.get(schemaPartition.calculateDeviceGroupId(partitionKeyList.get(i)));
+ databaseMap.get(schemaPartition.calculateDeviceGroupId(seriesPartitionKey));
if (Objects.nonNull(regionReplicaSet)) {
tableDeviceFetchMap
.computeIfAbsent(
diff --git a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/planner/node/schema/CreateOrUpdateTableDeviceNode.java b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/planner/node/schema/CreateOrUpdateTableDeviceNode.java
index be4b1337e7e..eb9e4a25b96 100644
--- a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/planner/node/schema/CreateOrUpdateTableDeviceNode.java
+++ b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/planner/node/schema/CreateOrUpdateTableDeviceNode.java
@@ -20,6 +20,7 @@
package org.apache.iotdb.db.queryengine.plan.relational.planner.node.schema;
import org.apache.iotdb.common.rpc.thrift.TRegionReplicaSet;
+import org.apache.iotdb.commons.partition.executor.SeriesPartitionExecutor.SeriesPartitionKey;
import org.apache.iotdb.db.queryengine.plan.analyze.IAnalysis;
import org.apache.iotdb.db.queryengine.plan.planner.plan.node.PlanNode;
import org.apache.iotdb.db.queryengine.plan.planner.plan.node.PlanNodeId;
@@ -29,6 +30,7 @@ import org.apache.iotdb.db.queryengine.plan.planner.plan.node.WritePlanNode;
import org.apache.iotdb.db.schemaengine.schemaregion.ISchemaRegionPlan;
import org.apache.iotdb.db.schemaengine.schemaregion.SchemaRegionPlanType;
import org.apache.iotdb.db.schemaengine.schemaregion.SchemaRegionPlanVisitor;
+import org.apache.iotdb.db.utils.CommonUtils;
import org.apache.tsfile.file.metadata.IDeviceID;
import org.apache.tsfile.utils.ReadWriteIOUtils;
@@ -260,10 +262,10 @@ public class CreateOrUpdateTableDeviceNode extends WritePlanNode implements ISch
final List<IDeviceID> partitionKeyList = getPartitionKeyList();
for (int i = 0; i < partitionKeyList.size(); i++) {
// Use the string literal of deviceId as the partition key
+ SeriesPartitionKey seriesPartitionKey =
+ CommonUtils.getSeriesPartitionKey(partitionKeyList.get(i), database);
final TRegionReplicaSet regionReplicaSet =
- analysis
- .getSchemaPartitionInfo()
- .getSchemaRegionReplicaSet(database, partitionKeyList.get(i));
+ analysis.getSchemaPartitionInfo().getSchemaRegionReplicaSet(database, seriesPartitionKey);
splitMap.computeIfAbsent(regionReplicaSet, k -> new ArrayList<>()).add(i);
}
final List<WritePlanNode> result = new ArrayList<>(splitMap.size());
diff --git a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/sql/ast/BooleanLiteral.java b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/sql/ast/BooleanLiteral.java
index 42f62559a72..c8a06a501be 100644
--- a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/sql/ast/BooleanLiteral.java
+++ b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/sql/ast/BooleanLiteral.java
@@ -119,4 +119,8 @@ public class BooleanLiteral extends Literal {
return INSTANCE_SIZE
+ AstMemoryEstimationHelper.getEstimatedSizeOfNodeLocation(getLocationInternal());
}
+
+ public boolean getParsedValue() {
+ return value;
+ }
}
diff --git a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/sql/ast/RenameColumn.java b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/sql/ast/RenameColumn.java
index 5e1277316a4..cbf2a561645 100644
--- a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/sql/ast/RenameColumn.java
+++ b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/sql/ast/RenameColumn.java
@@ -19,8 +19,6 @@
package org.apache.iotdb.db.queryengine.plan.relational.sql.ast;
-import org.apache.iotdb.db.exception.sql.SemanticException;
-
import com.google.common.collect.ImmutableList;
import org.apache.tsfile.utils.RamUsageEstimator;
@@ -57,9 +55,6 @@ public final class RenameColumn extends Statement {
this.tableIfExists = tableIfExists;
this.columnIfNotExists = columnIfNotExists;
this.view = view;
- if (!view) {
- throw new SemanticException("The renaming for base table column is currently unsupported");
- }
}
public QualifiedName getTable() {
diff --git a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/sql/ast/RenameTable.java b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/sql/ast/RenameTable.java
index 77c3296fee0..5919dec7d03 100644
--- a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/sql/ast/RenameTable.java
+++ b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/sql/ast/RenameTable.java
@@ -19,8 +19,6 @@
package org.apache.iotdb.db.queryengine.plan.relational.sql.ast;
-import org.apache.iotdb.db.exception.sql.SemanticException;
-
import com.google.common.collect.ImmutableList;
import org.apache.tsfile.utils.RamUsageEstimator;
@@ -51,9 +49,6 @@ public class RenameTable extends Statement {
this.target = requireNonNull(target, "target name is null");
this.tableIfExists = tableIfExists;
this.view = view;
- if (!view) {
- throw new SemanticException("The renaming for base table is currently unsupported");
- }
}
public QualifiedName getSource() {
diff --git a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/scheduler/load/LoadTsFileScheduler.java b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/scheduler/load/LoadTsFileScheduler.java
index 377f00664c0..2ee200c7454 100644
--- a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/scheduler/load/LoadTsFileScheduler.java
+++ b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/scheduler/load/LoadTsFileScheduler.java
@@ -34,6 +34,7 @@ import org.apache.iotdb.commons.exception.IoTDBException;
import org.apache.iotdb.commons.partition.DataPartition;
import org.apache.iotdb.commons.partition.DataPartitionQueryParam;
import org.apache.iotdb.commons.partition.StorageExecutor;
+import org.apache.iotdb.commons.partition.executor.SeriesPartitionExecutor.SeriesPartitionKey;
import org.apache.iotdb.commons.service.metric.MetricService;
import org.apache.iotdb.commons.service.metric.enums.Metric;
import org.apache.iotdb.commons.service.metric.enums.Tag;
@@ -72,6 +73,7 @@ import org.apache.iotdb.db.storageengine.load.splitter.ChunkData;
import org.apache.iotdb.db.storageengine.load.splitter.DeletionData;
import org.apache.iotdb.db.storageengine.load.splitter.TsFileData;
import org.apache.iotdb.db.storageengine.load.splitter.TsFileSplitter;
+import org.apache.iotdb.db.utils.CommonUtils;
import org.apache.iotdb.metrics.utils.MetricLevel;
import org.apache.iotdb.mpp.rpc.thrift.TLoadCommandReq;
import org.apache.iotdb.rpc.TSStatusCode;
@@ -846,12 +848,15 @@ public class LoadTsFileScheduler implements IScheduler {
subSlotList.stream()
.map(
pair ->
- // (database != null) means this file will be loaded into table-model
- database != null
- ? dataPartition.getDataRegionReplicaSetForWriting(
- pair.left, pair.right, database)
- : dataPartition.getDataRegionReplicaSetForWriting(
- pair.left, pair.right))
+ // (database != null) means this file will be loaded into table-model
+ {
+ SeriesPartitionKey seriesPartitionKey =
+ CommonUtils.getSeriesPartitionKey(pair.left, database);
+ return database != null
+ ? dataPartition.getDataRegionReplicaSetForWriting(
+ seriesPartitionKey, pair.right, database)
+ : dataPartition.getDataRegionReplicaSetForWriting(pair.left, pair.right);
+ })
.collect(Collectors.toList()));
}
return replicaSets;
diff --git a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/schemaengine/schemaregion/ISchemaRegion.java b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/schemaengine/schemaregion/ISchemaRegion.java
index 4a11165353c..578b0a1e862 100644
--- a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/schemaengine/schemaregion/ISchemaRegion.java
+++ b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/schemaengine/schemaregion/ISchemaRegion.java
@@ -29,6 +29,7 @@ import org.apache.iotdb.commons.schema.template.Template;
import org.apache.iotdb.db.exception.metadata.SchemaQuotaExceededException;
import org.apache.iotdb.db.queryengine.common.schematree.ClusterSchemaTree;
import org.apache.iotdb.db.queryengine.plan.planner.plan.node.metadata.write.AlterEncodingCompressorNode;
+import org.apache.iotdb.db.queryengine.plan.planner.plan.node.write.EvolveSchemaNode;
import org.apache.iotdb.db.queryengine.plan.relational.metadata.fetcher.cache.TableId;
import org.apache.iotdb.db.queryengine.plan.relational.planner.node.schema.ConstructTableDevicesBlackListNode;
import org.apache.iotdb.db.queryengine.plan.relational.planner.node.schema.CreateOrUpdateTableDeviceNode;
@@ -418,5 +419,7 @@ public interface ISchemaRegion {
void addNodeLocation(final TableNodeLocationAddNode node) throws MetadataException;
+ void applySchemaEvolution(EvolveSchemaNode schemaEvolutions) throws MetadataException;
+
// endregion
}
diff --git a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/schemaengine/schemaregion/SchemaRegionPlanType.java b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/schemaengine/schemaregion/SchemaRegionPlanType.java
index b0d41c725ee..8b058742ea3 100644
--- a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/schemaengine/schemaregion/SchemaRegionPlanType.java
+++ b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/schemaengine/schemaregion/SchemaRegionPlanType.java
@@ -63,6 +63,7 @@ public enum SchemaRegionPlanType {
ROLLBACK_TABLE_DEVICES_BLACK_LIST((byte) 106),
DELETE_TABLE_DEVICES_IN_BLACK_LIST((byte) 107),
DROP_TABLE_ATTRIBUTE((byte) 108),
+ EVOLVE_SCHEMA((byte) 109),
// query plan doesn't need any ser/deSer, thus use one type to represent all
READ_SCHEMA(Byte.MAX_VALUE);
diff --git a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/schemaengine/schemaregion/SchemaRegionPlanVisitor.java b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/schemaengine/schemaregion/SchemaRegionPlanVisitor.java
index 0cf087a40e1..e97b0942918 100644
--- a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/schemaengine/schemaregion/SchemaRegionPlanVisitor.java
+++ b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/schemaengine/schemaregion/SchemaRegionPlanVisitor.java
@@ -20,6 +20,7 @@
package org.apache.iotdb.db.schemaengine.schemaregion;
import org.apache.iotdb.db.queryengine.plan.planner.plan.node.metadata.write.AlterEncodingCompressorNode;
+import org.apache.iotdb.db.queryengine.plan.planner.plan.node.write.EvolveSchemaNode;
import org.apache.iotdb.db.queryengine.plan.relational.planner.node.schema.ConstructTableDevicesBlackListNode;
import org.apache.iotdb.db.queryengine.plan.relational.planner.node.schema.CreateOrUpdateTableDeviceNode;
import org.apache.iotdb.db.queryengine.plan.relational.planner.node.schema.DeleteTableDeviceNode;
@@ -185,4 +186,8 @@ public abstract class SchemaRegionPlanVisitor<R, C> {
final AlterEncodingCompressorNode alterEncodingCompressorNode, final C context) {
return visitSchemaRegionPlan(alterEncodingCompressorNode, context);
}
+
+ public R visitEvolveSchema(final EvolveSchemaNode evolveSchemaNode, final C context) {
+ return visitSchemaRegionPlan(evolveSchemaNode, context);
+ }
}
diff --git a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/schemaengine/schemaregion/impl/SchemaRegionMemoryImpl.java b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/schemaengine/schemaregion/impl/SchemaRegionMemoryImpl.java
index 230ed8330ca..4baa250d786 100644
--- a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/schemaengine/schemaregion/impl/SchemaRegionMemoryImpl.java
+++ b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/schemaengine/schemaregion/impl/SchemaRegionMemoryImpl.java
@@ -49,10 +49,12 @@ import org.apache.iotdb.db.queryengine.execution.operator.schema.source.DeviceAt
import org.apache.iotdb.db.queryengine.execution.operator.schema.source.DeviceBlackListConstructor;
import org.apache.iotdb.db.queryengine.execution.operator.schema.source.TableDeviceQuerySource;
import org.apache.iotdb.db.queryengine.execution.relational.ColumnTransformerBuilder;
+import org.apache.iotdb.db.queryengine.execution.relational.ColumnTransformerBuilder.Context;
import org.apache.iotdb.db.queryengine.plan.analyze.TypeProvider;
import org.apache.iotdb.db.queryengine.plan.planner.LocalExecutionPlanner;
import org.apache.iotdb.db.queryengine.plan.planner.plan.node.metadata.write.AlterEncodingCompressorNode;
import org.apache.iotdb.db.queryengine.plan.planner.plan.node.metadata.write.CreateTimeSeriesNode;
+import org.apache.iotdb.db.queryengine.plan.planner.plan.node.write.EvolveSchemaNode;
import org.apache.iotdb.db.queryengine.plan.planner.plan.parameter.InputLocation;
import org.apache.iotdb.db.queryengine.plan.relational.metadata.Metadata;
import org.apache.iotdb.db.queryengine.plan.relational.metadata.fetcher.cache.TableDeviceSchemaCache;
@@ -125,6 +127,8 @@ import org.apache.iotdb.db.schemaengine.schemaregion.write.req.view.IDeleteLogic
import org.apache.iotdb.db.schemaengine.schemaregion.write.req.view.IPreDeleteLogicalViewPlan;
import org.apache.iotdb.db.schemaengine.schemaregion.write.req.view.IRollbackPreDeleteLogicalViewPlan;
import org.apache.iotdb.db.schemaengine.table.DataNodeTableCache;
+import org.apache.iotdb.db.storageengine.dataregion.tsfile.evolution.SchemaEvolution;
+import org.apache.iotdb.db.storageengine.dataregion.tsfile.evolution.TableRename;
import org.apache.iotdb.db.storageengine.rescon.memory.SystemInfo;
import org.apache.iotdb.db.utils.SchemaUtils;
@@ -1555,7 +1559,7 @@ public class SchemaRegionMemoryImpl implements ISchemaRegion {
Objects.nonNull(predicate)
? visitor.process(
predicate,
- new ColumnTransformerBuilder.Context(
+ new Context(
sessionInfo,
filterLeafColumnTransformerList,
inputLocations,
@@ -1582,8 +1586,8 @@ public class SchemaRegionMemoryImpl implements ISchemaRegion {
// records common ColumnTransformer between filter and project expressions
final List<ColumnTransformer> commonTransformerList = new ArrayList<>();
- final ColumnTransformerBuilder.Context projectColumnTransformerContext =
- new ColumnTransformerBuilder.Context(
+ final Context projectColumnTransformerContext =
+ new Context(
sessionInfo,
projectLeafColumnTransformerList,
inputLocations,
@@ -1782,6 +1786,23 @@ public class SchemaRegionMemoryImpl implements ISchemaRegion {
}
}
+ @Override
+ public void applySchemaEvolution(EvolveSchemaNode node) throws MetadataException {
+ for (SchemaEvolution schemaEvolution : node.getSchemaEvolutions()) {
+ if (schemaEvolution instanceof TableRename) {
+ TableRename tableRename = (TableRename) schemaEvolution;
+ applyTableRename(tableRename.getNameBefore(), tableRename.getNameAfter());
+ } else {
+ logger.warn("Unsupported schemaEvolution {}, ignore it", schemaEvolution);
+ }
+ }
+ writeToMLog(node);
+ }
+
+ public void applyTableRename(String oldName, String newName) {
+ mTree.renameTable(oldName, newName);
+ }
+
// endregion
private static class RecoverOperationResult {
@@ -2115,5 +2136,16 @@ public class SchemaRegionMemoryImpl implements ISchemaRegion {
return new RecoverOperationResult(e);
}
}
+
+ @Override
+ public RecoverOperationResult visitEvolveSchema(
+ EvolveSchemaNode evolveSchemaNode, SchemaRegionMemoryImpl context) {
+ try {
+ applySchemaEvolution(evolveSchemaNode);
+ return RecoverOperationResult.SUCCESS;
+ } catch (final MetadataException e) {
+ return new RecoverOperationResult(e);
+ }
+ }
}
}
diff --git a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/schemaengine/schemaregion/impl/SchemaRegionPBTreeImpl.java b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/schemaengine/schemaregion/impl/SchemaRegionPBTreeImpl.java
index 2f4bec896dd..5ebc9d52f9d 100644
--- a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/schemaengine/schemaregion/impl/SchemaRegionPBTreeImpl.java
+++ b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/schemaengine/schemaregion/impl/SchemaRegionPBTreeImpl.java
@@ -41,6 +41,7 @@ import org.apache.iotdb.db.exception.metadata.SchemaDirCreationFailureException;
import org.apache.iotdb.db.exception.metadata.SchemaQuotaExceededException;
import org.apache.iotdb.db.queryengine.common.schematree.ClusterSchemaTree;
import org.apache.iotdb.db.queryengine.plan.planner.plan.node.metadata.write.AlterEncodingCompressorNode;
+import org.apache.iotdb.db.queryengine.plan.planner.plan.node.write.EvolveSchemaNode;
import org.apache.iotdb.db.queryengine.plan.relational.metadata.fetcher.cache.TableId;
import org.apache.iotdb.db.queryengine.plan.relational.planner.node.schema.ConstructTableDevicesBlackListNode;
import org.apache.iotdb.db.queryengine.plan.relational.planner.node.schema.CreateOrUpdateTableDeviceNode;
@@ -1583,6 +1584,11 @@ public class SchemaRegionPBTreeImpl implements ISchemaRegion {
throw new UnsupportedOperationException();
}
+ @Override
+ public void applySchemaEvolution(EvolveSchemaNode schemaEvolutions) {
+ throw new UnsupportedOperationException();
+ }
+
// endregion
private static class RecoverOperationResult {
diff --git a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/schemaengine/schemaregion/logfile/visitor/SchemaRegionPlanDeserializer.java b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/schemaengine/schemaregion/logfile/visitor/SchemaRegionPlanDeserializer.java
index 163ccb4e59d..eb2b0722526 100644
--- a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/schemaengine/schemaregion/logfile/visitor/SchemaRegionPlanDeserializer.java
+++ b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/schemaengine/schemaregion/logfile/visitor/SchemaRegionPlanDeserializer.java
@@ -26,6 +26,7 @@ import org.apache.iotdb.commons.path.PathDeserializeUtil;
import org.apache.iotdb.commons.schema.view.viewExpression.ViewExpression;
import org.apache.iotdb.db.queryengine.plan.planner.plan.node.PlanNodeType;
import org.apache.iotdb.db.queryengine.plan.planner.plan.node.metadata.write.AlterEncodingCompressorNode;
+import org.apache.iotdb.db.queryengine.plan.planner.plan.node.write.EvolveSchemaNode;
import org.apache.iotdb.db.queryengine.plan.relational.planner.node.schema.ConstructTableDevicesBlackListNode;
import org.apache.iotdb.db.queryengine.plan.relational.planner.node.schema.CreateOrUpdateTableDeviceNode;
import org.apache.iotdb.db.queryengine.plan.relational.planner.node.schema.DeleteTableDeviceNode;
@@ -482,5 +483,11 @@ public class SchemaRegionPlanDeserializer implements IDeserializer<ISchemaRegion
final AlterEncodingCompressorNode alterEncodingCompressorNode, final ByteBuffer buffer) {
return (AlterEncodingCompressorNode) PlanNodeType.deserialize(buffer);
}
+
+ @Override
+ public ISchemaRegionPlan visitEvolveSchema(
+ EvolveSchemaNode evolveSchemaNode, ByteBuffer buffer) {
+ return (EvolveSchemaNode) PlanNodeType.deserialize(buffer);
+ }
}
}
diff --git a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/schemaengine/schemaregion/logfile/visitor/SchemaRegionPlanSerializer.java b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/schemaengine/schemaregion/logfile/visitor/SchemaRegionPlanSerializer.java
index b7b7d9758ca..d65b18f18af 100644
--- a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/schemaengine/schemaregion/logfile/visitor/SchemaRegionPlanSerializer.java
+++ b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/schemaengine/schemaregion/logfile/visitor/SchemaRegionPlanSerializer.java
@@ -23,6 +23,7 @@ import org.apache.iotdb.commons.path.PartialPath;
import org.apache.iotdb.commons.schema.view.viewExpression.ViewExpression;
import org.apache.iotdb.db.queryengine.plan.planner.plan.node.PlanNode;
import org.apache.iotdb.db.queryengine.plan.planner.plan.node.metadata.write.AlterEncodingCompressorNode;
+import org.apache.iotdb.db.queryengine.plan.planner.plan.node.write.EvolveSchemaNode;
import org.apache.iotdb.db.queryengine.plan.relational.planner.node.schema.ConstructTableDevicesBlackListNode;
import org.apache.iotdb.db.queryengine.plan.relational.planner.node.schema.CreateOrUpdateTableDeviceNode;
import org.apache.iotdb.db.queryengine.plan.relational.planner.node.schema.DeleteTableDeviceNode;
@@ -553,6 +554,12 @@ public class SchemaRegionPlanSerializer implements ISerializer<ISchemaRegionPlan
return visitPlanNode(alterEncodingCompressorNode, outputStream);
}
+ @Override
+ public SchemaRegionPlanSerializationResult visitEvolveSchema(
+ EvolveSchemaNode evolveSchemaNode, DataOutputStream outputStream) {
+ return visitPlanNode(evolveSchemaNode, outputStream);
+ }
+
private SchemaRegionPlanSerializationResult visitPlanNode(
final PlanNode planNode, final DataOutputStream outputStream) {
try {
diff --git a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/schemaengine/schemaregion/mtree/impl/mem/MTreeBelowSGMemoryImpl.java b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/schemaengine/schemaregion/mtree/impl/mem/MTreeBelowSGMemoryImpl.java
index 9aec147ace1..82dc65cd338 100644
--- a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/schemaengine/schemaregion/mtree/impl/mem/MTreeBelowSGMemoryImpl.java
+++ b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/schemaengine/schemaregion/mtree/impl/mem/MTreeBelowSGMemoryImpl.java
@@ -1703,6 +1703,16 @@ public class MTreeBelowSGMemoryImpl {
return notExistNum;
}
+ public synchronized void renameTable(final String oldTableName, final String newTableName) {
+ IMemMNode tableNode = databaseMNode.deleteChild(oldTableName);
+ if (tableNode == null) {
+ LOGGER.warn("Renaming a non-existing table {}.", oldTableName);
+ return;
+ }
+ tableNode.setName(newTableName);
+ databaseMNode.addChild(tableNode);
+ }
+
public void createOrUpdateTableDevice(
final String tableName,
final String[] devicePath,
diff --git a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/schemaengine/schemaregion/write/req/SchemaRegionWritePlanFactory.java b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/schemaengine/schemaregion/write/req/SchemaRegionWritePlanFactory.java
index 8a87a6f3829..5c653f42e9b 100644
--- a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/schemaengine/schemaregion/write/req/SchemaRegionWritePlanFactory.java
+++ b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/schemaengine/schemaregion/write/req/SchemaRegionWritePlanFactory.java
@@ -23,6 +23,7 @@ import org.apache.iotdb.commons.path.MeasurementPath;
import org.apache.iotdb.commons.path.PartialPath;
import org.apache.iotdb.commons.schema.view.viewExpression.ViewExpression;
import org.apache.iotdb.db.queryengine.plan.planner.plan.node.metadata.write.AlterEncodingCompressorNode;
+import org.apache.iotdb.db.queryengine.plan.planner.plan.node.write.EvolveSchemaNode;
import org.apache.iotdb.db.queryengine.plan.relational.planner.node.schema.ConstructTableDevicesBlackListNode;
import org.apache.iotdb.db.queryengine.plan.relational.planner.node.schema.CreateOrUpdateTableDeviceNode;
import org.apache.iotdb.db.queryengine.plan.relational.planner.node.schema.DeleteTableDeviceNode;
@@ -124,6 +125,8 @@ public class SchemaRegionWritePlanFactory {
return DeleteTableDevicesInBlackListNode.MOCK_INSTANCE;
case DROP_TABLE_ATTRIBUTE:
return TableAttributeColumnDropNode.MOCK_INSTANCE;
+ case EVOLVE_SCHEMA:
+ return new EvolveSchemaNode();
default:
throw new UnsupportedOperationException(
String.format(
diff --git a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/storageengine/dataregion/DataRegion.java b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/storageengine/dataregion/DataRegion.java
index 4f6ddb7f46d..be0f7c3e5ca 100644
--- a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/storageengine/dataregion/DataRegion.java
+++ b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/storageengine/dataregion/DataRegion.java
@@ -1263,7 +1263,6 @@ public class DataRegion implements IDataRegionForQuery {
if (deleted) {
return;
}
- DataNodeTableCache.getInstance().invalid(databaseName);
syncCloseAllWorkingTsFileProcessors();
@@ -2942,14 +2941,7 @@ public class DataRegion implements IDataRegionForQuery {
List<TsFileResource> tsfileResourcesForQuery = new ArrayList<>();
for (TsFileResource tsFileResource : tsFileResources) {
- EvolvedSchema evolvedSchema = tsFileResource.getMergedEvolvedSchema();
- IDeviceID deviceIdBackThen = singleDeviceId;
- if (evolvedSchema != null) {
- deviceIdBackThen = evolvedSchema.rewriteToOriginal(singleDeviceId);
- }
-
- if (!tsFileResource.isSatisfied(
- deviceIdBackThen, globalTimeFilter, isSeq, context.isDebug())) {
+ if (!tsFileResource.isSatisfied(singleDeviceId, globalTimeFilter, isSeq, context.isDebug())) {
continue;
}
try {
diff --git a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/storageengine/dataregion/tsfile/TsFileManager.java b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/storageengine/dataregion/tsfile/TsFileManager.java
index 610365cbfb7..8f74c561a88 100644
--- a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/storageengine/dataregion/tsfile/TsFileManager.java
+++ b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/storageengine/dataregion/tsfile/TsFileManager.java
@@ -32,6 +32,7 @@ import org.apache.tsfile.utils.Pair;
import java.io.IOException;
import java.util.ArrayList;
+import java.util.Collections;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
@@ -530,7 +531,7 @@ public class TsFileManager {
long partitionId, long minFileVersionIncluded, long maxFileVersionExcluded) {
readLock();
try {
- List<TsFileSet> tsFileSetList = tsfileSets.get(partitionId);
+ List<TsFileSet> tsFileSetList = tsfileSets.getOrDefault(partitionId, Collections.emptyList());
return tsFileSetList.stream()
.filter(
s ->
diff --git a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/storageengine/dataregion/tsfile/TsFileResource.java b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/storageengine/dataregion/tsfile/TsFileResource.java
index 0462002f1fb..576e4e5ade5 100644
--- a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/storageengine/dataregion/tsfile/TsFileResource.java
+++ b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/storageengine/dataregion/tsfile/TsFileResource.java
@@ -261,6 +261,7 @@ public class TsFileResource implements PersistentResource, Cloneable {
this.tsFileID = originTsFileResource.tsFileID;
this.isSeq = originTsFileResource.isSeq;
this.tierLevel = originTsFileResource.tierLevel;
+ this.tsFileManager = originTsFileResource.tsFileManager;
}
public synchronized void serialize(String targetFilePath) throws IOException {
@@ -1047,6 +1048,9 @@ public class TsFileResource implements PersistentResource, Cloneable {
return timeIndex.checkDeviceIdExist(deviceId);
}
+ /**
+ * @param deviceId IDeviceId after schema evolution
+ */
public boolean isSatisfied(IDeviceID deviceId, Filter timeFilter, boolean isSeq, boolean debug) {
return isSatisfied(deviceId, timeFilter, isSeq, debug, Long.MAX_VALUE);
}
diff --git a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/storageengine/dataregion/tsfile/evolution/SchemaEvolution.java b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/storageengine/dataregion/tsfile/evolution/SchemaEvolution.java
index f1ac8edbcfa..109998dec27 100644
--- a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/storageengine/dataregion/tsfile/evolution/SchemaEvolution.java
+++ b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/storageengine/dataregion/tsfile/evolution/SchemaEvolution.java
@@ -26,6 +26,7 @@ import org.apache.tsfile.utils.ReadWriteForEncodingUtils;
import java.io.IOException;
import java.io.InputStream;
+import java.io.OutputStream;
import java.nio.ByteBuffer;
import java.util.ArrayList;
import java.util.List;
@@ -88,4 +89,11 @@ public interface SchemaEvolution extends StreamSerializable, BufferSerializable
}
return list;
}
+
+ static void serializeList(List<SchemaEvolution> list, OutputStream stream) throws IOException {
+ ReadWriteForEncodingUtils.writeVarInt(list.size(), stream);
+ for (SchemaEvolution evolution : list) {
+ evolution.serialize(stream);
+ }
+ }
}
diff --git a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/utils/CommonUtils.java b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/utils/CommonUtils.java
index 784312f9f9c..e4cbfb87947 100644
--- a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/utils/CommonUtils.java
+++ b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/utils/CommonUtils.java
@@ -19,6 +19,10 @@
package org.apache.iotdb.db.utils;
+import org.apache.iotdb.commons.partition.executor.SeriesPartitionExecutor.FullDeviceIdKey;
+import org.apache.iotdb.commons.partition.executor.SeriesPartitionExecutor.NoTableNameDeviceIdKey;
+import org.apache.iotdb.commons.partition.executor.SeriesPartitionExecutor.SeriesPartitionKey;
+import org.apache.iotdb.commons.schema.table.TsTable;
import org.apache.iotdb.commons.schema.table.column.TsTableColumnCategory;
import org.apache.iotdb.commons.service.metric.MetricService;
import org.apache.iotdb.commons.service.metric.enums.Metric;
@@ -30,6 +34,7 @@ import org.apache.iotdb.db.protocol.thrift.OperationType;
import org.apache.iotdb.db.queryengine.plan.execution.IQueryExecution;
import org.apache.iotdb.db.queryengine.plan.statement.StatementType;
import org.apache.iotdb.db.queryengine.plan.statement.literal.BinaryLiteral;
+import org.apache.iotdb.db.schemaengine.table.DataNodeTableCache;
import org.apache.iotdb.db.utils.constant.SqlConstant;
import org.apache.iotdb.metrics.utils.MetricLevel;
import org.apache.iotdb.service.rpc.thrift.TSAggregationQueryReq;
@@ -456,4 +461,18 @@ public class CommonUtils {
}
return tsBlockBuilder.toString();
}
+
+ public static SeriesPartitionKey getSeriesPartitionKey(IDeviceID deviceID, String databaseName) {
+ if (databaseName != null && deviceID.isTableModel()) {
+ TsTable table =
+ DataNodeTableCache.getInstance().getTable(databaseName, deviceID.getTableName());
+ boolean canAlterName = table.canAlterName();
+ if (canAlterName) {
+ return new NoTableNameDeviceIdKey(deviceID);
+ } else {
+ return new FullDeviceIdKey(deviceID);
+ }
+ }
+ return new FullDeviceIdKey(deviceID);
+ }
}
diff --git a/iotdb-core/node-commons/src/main/java/org/apache/iotdb/commons/partition/DataPartition.java b/iotdb-core/node-commons/src/main/java/org/apache/iotdb/commons/partition/DataPartition.java
index 100c40eddcc..99507d0ec0d 100644
--- a/iotdb-core/node-commons/src/main/java/org/apache/iotdb/commons/partition/DataPartition.java
+++ b/iotdb-core/node-commons/src/main/java/org/apache/iotdb/commons/partition/DataPartition.java
@@ -22,9 +22,12 @@ package org.apache.iotdb.commons.partition;
import org.apache.iotdb.common.rpc.thrift.TRegionReplicaSet;
import org.apache.iotdb.common.rpc.thrift.TSeriesPartitionSlot;
import org.apache.iotdb.common.rpc.thrift.TTimePartitionSlot;
+import org.apache.iotdb.commons.partition.executor.SeriesPartitionExecutor.FullDeviceIdKey;
+import org.apache.iotdb.commons.partition.executor.SeriesPartitionExecutor.SeriesPartitionKey;
import org.apache.iotdb.commons.utils.PathUtils;
import org.apache.iotdb.commons.utils.TimePartitionUtils;
+import org.apache.tsfile.annotations.TreeModel;
import org.apache.tsfile.file.metadata.IDeviceID;
import org.apache.tsfile.read.filter.basic.Filter;
import org.slf4j.Logger;
@@ -95,18 +98,21 @@ public class DataPartition extends Partition {
this.dataPartitionMap = dataPartitionMap;
}
+ @TreeModel
public List<List<TTimePartitionSlot>> getTimePartitionRange(
IDeviceID deviceID, Filter timeFilter) {
- String storageGroup = getDatabaseNameByDevice(deviceID);
- TSeriesPartitionSlot seriesPartitionSlot = calculateDeviceGroupId(deviceID);
- if (!dataPartitionMap.containsKey(storageGroup)
- || !dataPartitionMap.get(storageGroup).containsKey(seriesPartitionSlot)) {
+ String databaseName = getDatabaseNameByDevice(deviceID);
+ // since this method retrieves database from deviceId, it must only be used by the tree model
+ TSeriesPartitionSlot seriesPartitionSlot =
+ calculateDeviceGroupId(new FullDeviceIdKey(deviceID));
+ if (!dataPartitionMap.containsKey(databaseName)
+ || !dataPartitionMap.get(databaseName).containsKey(seriesPartitionSlot)) {
return Collections.emptyList();
}
List<List<TTimePartitionSlot>> res = new ArrayList<>();
Map<TTimePartitionSlot, List<TRegionReplicaSet>> map =
- dataPartitionMap.get(storageGroup).get(seriesPartitionSlot);
+ dataPartitionMap.get(databaseName).get(seriesPartitionSlot);
List<TTimePartitionSlot> timePartitionSlotList =
map.keySet().stream()
.filter(key -> TimePartitionUtils.satisfyPartitionStartTime(timeFilter, key.startTime))
@@ -138,10 +144,13 @@ public class DataPartition extends Partition {
return res;
}
+ @TreeModel
public List<TRegionReplicaSet> getDataRegionReplicaSetWithTimeFilter(
final IDeviceID deviceId, final Filter timeFilter) {
+ // since this method retrieves database from deviceId, it must only be used by the tree model
final String storageGroup = getDatabaseNameByDevice(deviceId);
- final TSeriesPartitionSlot seriesPartitionSlot = calculateDeviceGroupId(deviceId);
+ final TSeriesPartitionSlot seriesPartitionSlot =
+ calculateDeviceGroupId(new FullDeviceIdKey(deviceId));
Map<TTimePartitionSlot, List<TRegionReplicaSet>> regionReplicaSetMap =
dataPartitionMap
.getOrDefault(storageGroup, Collections.emptyMap())
@@ -166,8 +175,8 @@ public class DataPartition extends Partition {
* <p>The device id shall be [table, seg1, ....]
*/
public List<TRegionReplicaSet> getDataRegionReplicaSetWithTimeFilter(
- final String database, final IDeviceID deviceId, final Filter timeFilter) {
- final TSeriesPartitionSlot seriesPartitionSlot = calculateDeviceGroupId(deviceId);
+ final String database, final SeriesPartitionKey seriesPartitionKey, final Filter timeFilter) {
+ final TSeriesPartitionSlot seriesPartitionSlot = calculateDeviceGroupId(seriesPartitionKey);
if (!dataPartitionMap.containsKey(database)
|| !dataPartitionMap.get(database).containsKey(seriesPartitionSlot)) {
return Collections.singletonList(NOT_ASSIGNED);
@@ -181,15 +190,18 @@ public class DataPartition extends Partition {
.collect(toList());
}
+ @TreeModel
public List<TRegionReplicaSet> getDataRegionReplicaSet(
final IDeviceID deviceID, final TTimePartitionSlot tTimePartitionSlot) {
+ // since this method retrieves database from deviceId, it must only be used by the tree model
final String storageGroup = getDatabaseNameByDevice(deviceID);
final Map<TSeriesPartitionSlot, Map<TTimePartitionSlot, List<TRegionReplicaSet>>> dbMap =
dataPartitionMap.get(storageGroup);
if (dbMap == null) {
return Collections.singletonList(NOT_ASSIGNED);
}
- final TSeriesPartitionSlot seriesPartitionSlot = calculateDeviceGroupId(deviceID);
+ final TSeriesPartitionSlot seriesPartitionSlot =
+ calculateDeviceGroupId(new FullDeviceIdKey(deviceID));
final Map<TTimePartitionSlot, List<TRegionReplicaSet>> seriesSlotMap =
dbMap.get(seriesPartitionSlot);
if (seriesSlotMap == null) {
@@ -206,16 +218,17 @@ public class DataPartition extends Partition {
}
public List<TRegionReplicaSet> getDataRegionReplicaSetForWriting(
- final IDeviceID deviceID,
+ final SeriesPartitionKey key,
final List<TTimePartitionSlot> timePartitionSlotList,
String databaseName) {
if (databaseName == null) {
- databaseName = getDatabaseNameByDevice(deviceID);
+ // must be the tree model here
+ databaseName = getDatabaseNameByDevice(((FullDeviceIdKey) key).getDeviceID());
}
// A list of data region replica sets will store data in a same time partition.
// We will insert data to the last set in the list.
// TODO return the latest dataRegionReplicaSet for each time partition
- final TSeriesPartitionSlot seriesPartitionSlot = calculateDeviceGroupId(deviceID);
+ final TSeriesPartitionSlot seriesPartitionSlot = calculateDeviceGroupId(key);
// IMPORTANT TODO: (xingtanzjr) need to handle the situation for write operation that there are
// more than 1 Regions for one timeSlot
final List<TRegionReplicaSet> dataRegionReplicaSets = new ArrayList<>();
@@ -228,8 +241,7 @@ public class DataPartition extends Partition {
if (targetRegionList == null || targetRegionList.isEmpty()) {
throw new RuntimeException(
String.format(
- "targetRegionList is empty. device: %s, timeSlot: %s",
- deviceID, timePartitionSlot));
+ "targetRegionList is empty. device: %s, timeSlot: %s", key, timePartitionSlot));
} else {
dataRegionReplicaSets.add(targetRegionList.get(targetRegionList.size() - 1));
}
@@ -238,13 +250,16 @@ public class DataPartition extends Partition {
}
public TRegionReplicaSet getDataRegionReplicaSetForWriting(
- final IDeviceID deviceID, final TTimePartitionSlot timePartitionSlot, String databaseName) {
+ final SeriesPartitionKey seriesPartitionKey,
+ final TTimePartitionSlot timePartitionSlot,
+ String databaseName) {
// A list of data region replica sets will store data in a same time partition.
// We will insert data to the last set in the list.
// TODO return the latest dataRegionReplicaSet for each time partition
- final TSeriesPartitionSlot seriesPartitionSlot = calculateDeviceGroupId(deviceID);
+ final TSeriesPartitionSlot seriesPartitionSlot = calculateDeviceGroupId(seriesPartitionKey);
if (databaseName == null) {
- databaseName = getDatabaseNameByDevice(deviceID);
+ // must be the tree model here
+ databaseName = getDatabaseNameByDevice(((FullDeviceIdKey) seriesPartitionKey).getDeviceID());
}
final Map<TSeriesPartitionSlot, Map<TTimePartitionSlot, List<TRegionReplicaSet>>>
databasePartitionMap = dataPartitionMap.get(databaseName);
@@ -261,10 +276,11 @@ public class DataPartition extends Partition {
return regions.get(0);
}
+ @TreeModel
public TRegionReplicaSet getDataRegionReplicaSetForWriting(
IDeviceID deviceID, TTimePartitionSlot timePartitionSlot) {
return getDataRegionReplicaSetForWriting(
- deviceID, timePartitionSlot, getDatabaseNameByDevice(deviceID));
+ new FullDeviceIdKey(deviceID), timePartitionSlot, getDatabaseNameByDevice(deviceID));
}
public String getDatabaseNameByDevice(IDeviceID deviceID) {
@@ -302,15 +318,14 @@ public class DataPartition extends Partition {
public void upsertDataPartition(DataPartition targetDataPartition) {
requireNonNull(this.dataPartitionMap, "dataPartitionMap is null");
- for (Map.Entry<
- String, Map<TSeriesPartitionSlot, Map<TTimePartitionSlot, List<TRegionReplicaSet>>>>
+ for (Entry<String, Map<TSeriesPartitionSlot, Map<TTimePartitionSlot, List<TRegionReplicaSet>>>>
targetDbEntry : targetDataPartition.getDataPartitionMap().entrySet()) {
String database = targetDbEntry.getKey();
if (dataPartitionMap.containsKey(database)) {
Map<TSeriesPartitionSlot, Map<TTimePartitionSlot, List<TRegionReplicaSet>>>
sourceSeriesPartitionMap = dataPartitionMap.get(database);
- for (Map.Entry<TSeriesPartitionSlot, Map<TTimePartitionSlot, List<TRegionReplicaSet>>>
+ for (Entry<TSeriesPartitionSlot, Map<TTimePartitionSlot, List<TRegionReplicaSet>>>
targetSeriesSlotEntry : targetDbEntry.getValue().entrySet()) {
TSeriesPartitionSlot targetSeriesSlot = targetSeriesSlotEntry.getKey();
@@ -319,7 +334,7 @@ public class DataPartition extends Partition {
sourceSeriesPartitionMap.get(targetSeriesSlot);
Map<TTimePartitionSlot, List<TRegionReplicaSet>> targetTimePartionMap =
targetSeriesSlotEntry.getValue();
- for (Map.Entry<TTimePartitionSlot, List<TRegionReplicaSet>> targetEntry :
+ for (Entry<TTimePartitionSlot, List<TRegionReplicaSet>> targetEntry :
targetTimePartionMap.entrySet()) {
if (!sourceTimePartitionMap.containsKey(targetEntry.getKey())) {
sourceTimePartitionMap.put(targetEntry.getKey(), targetEntry.getValue());
diff --git a/iotdb-core/node-commons/src/main/java/org/apache/iotdb/commons/partition/Partition.java b/iotdb-core/node-commons/src/main/java/org/apache/iotdb/commons/partition/Partition.java
index b94cf3d005d..5d32e33db61 100644
--- a/iotdb-core/node-commons/src/main/java/org/apache/iotdb/commons/partition/Partition.java
+++ b/iotdb-core/node-commons/src/main/java/org/apache/iotdb/commons/partition/Partition.java
@@ -21,8 +21,7 @@ package org.apache.iotdb.commons.partition;
import org.apache.iotdb.common.rpc.thrift.TSeriesPartitionSlot;
import org.apache.iotdb.commons.partition.executor.SeriesPartitionExecutor;
-
-import org.apache.tsfile.file.metadata.IDeviceID;
+import org.apache.iotdb.commons.partition.executor.SeriesPartitionExecutor.SeriesPartitionKey;
import java.util.List;
@@ -42,8 +41,8 @@ public abstract class Partition {
seriesSlotExecutorName, seriesPartitionSlotNum);
}
- public TSeriesPartitionSlot calculateDeviceGroupId(IDeviceID deviceID) {
- return executor.getSeriesPartitionSlot(deviceID);
+ public TSeriesPartitionSlot calculateDeviceGroupId(SeriesPartitionKey key) {
+ return executor.getSeriesPartitionSlot(key);
}
public abstract List<RegionReplicaSetInfo> getDistributionInfo();
diff --git a/iotdb-core/node-commons/src/main/java/org/apache/iotdb/commons/partition/SchemaPartition.java b/iotdb-core/node-commons/src/main/java/org/apache/iotdb/commons/partition/SchemaPartition.java
index 96abc749865..ff56dee46fe 100644
--- a/iotdb-core/node-commons/src/main/java/org/apache/iotdb/commons/partition/SchemaPartition.java
+++ b/iotdb-core/node-commons/src/main/java/org/apache/iotdb/commons/partition/SchemaPartition.java
@@ -22,10 +22,13 @@ package org.apache.iotdb.commons.partition;
import org.apache.iotdb.common.rpc.thrift.TRegionReplicaSet;
import org.apache.iotdb.common.rpc.thrift.TSeriesPartitionSlot;
import org.apache.iotdb.commons.exception.IoTDBException;
+import org.apache.iotdb.commons.partition.executor.SeriesPartitionExecutor.FullDeviceIdKey;
+import org.apache.iotdb.commons.partition.executor.SeriesPartitionExecutor.SeriesPartitionKey;
import org.apache.iotdb.commons.utils.PathUtils;
import org.apache.iotdb.commons.utils.TestOnly;
import org.apache.iotdb.rpc.TSStatusCode;
+import org.apache.tsfile.annotations.TreeModel;
import org.apache.tsfile.file.metadata.IDeviceID;
import java.util.ArrayList;
@@ -75,18 +78,20 @@ public class SchemaPartition extends Partition {
*
* <p>The device id shall be [table, seg1, ....]
*/
- public TRegionReplicaSet getSchemaRegionReplicaSet(String database, IDeviceID deviceID) {
- TSeriesPartitionSlot seriesPartitionSlot = calculateDeviceGroupId(deviceID);
+ public TRegionReplicaSet getSchemaRegionReplicaSet(String database, SeriesPartitionKey key) {
+ TSeriesPartitionSlot seriesPartitionSlot = calculateDeviceGroupId(key);
return schemaPartitionMap.get(database).get(seriesPartitionSlot);
}
+ @TreeModel
// [root, db, ....]
public TRegionReplicaSet getSchemaRegionReplicaSet(final IDeviceID deviceID) {
// A list of data region replica sets will store data in a same time partition.
// We will insert data to the last set in the list.
// TODO return the latest dataRegionReplicaSet for each time partition
final String storageGroup = getStorageGroupByDevice(deviceID);
- final TSeriesPartitionSlot seriesPartitionSlot = calculateDeviceGroupId(deviceID);
+ final TSeriesPartitionSlot seriesPartitionSlot =
+ calculateDeviceGroupId(new FullDeviceIdKey(deviceID));
if (schemaPartitionMap.get(storageGroup) == null) {
throw new RuntimeException(
new IoTDBException("Path does not exist. ", TSStatusCode.PATH_NOT_EXIST.getStatusCode()));
diff --git a/iotdb-core/node-commons/src/main/java/org/apache/iotdb/commons/partition/executor/SeriesPartitionExecutor.java b/iotdb-core/node-commons/src/main/java/org/apache/iotdb/commons/partition/executor/SeriesPartitionExecutor.java
index d2666446e8e..8140cb259b1 100644
--- a/iotdb-core/node-commons/src/main/java/org/apache/iotdb/commons/partition/executor/SeriesPartitionExecutor.java
+++ b/iotdb-core/node-commons/src/main/java/org/apache/iotdb/commons/partition/executor/SeriesPartitionExecutor.java
@@ -45,7 +45,12 @@ public abstract class SeriesPartitionExecutor {
@TestOnly
public abstract TSeriesPartitionSlot getSeriesPartitionSlot(String device);
- public abstract TSeriesPartitionSlot getSeriesPartitionSlot(IDeviceID deviceID);
+ @TestOnly
+ public TSeriesPartitionSlot getSeriesPartitionSlot(IDeviceID deviceID) {
+ return getSeriesPartitionSlot(new FullDeviceIdKey(deviceID));
+ }
+
+ public abstract TSeriesPartitionSlot getSeriesPartitionSlot(SeriesPartitionKey deviceID);
public static SeriesPartitionExecutor getSeriesPartitionExecutor(
String executorName, int seriesPartitionSlotNum) {
@@ -73,4 +78,50 @@ public abstract class SeriesPartitionExecutor {
}
}
}
+
+ public interface SeriesPartitionKey {
+ int segmentNum();
+
+ Object segment(int index);
+ }
+
+ public static class FullDeviceIdKey implements SeriesPartitionKey {
+ private final IDeviceID deviceID;
+
+ public FullDeviceIdKey(IDeviceID deviceID) {
+ this.deviceID = deviceID;
+ }
+
+ @Override
+ public int segmentNum() {
+ return deviceID.segmentNum();
+ }
+
+ @Override
+ public Object segment(int index) {
+ return deviceID.segment(index);
+ }
+
+ public IDeviceID getDeviceID() {
+ return deviceID;
+ }
+ }
+
+ public static class NoTableNameDeviceIdKey implements SeriesPartitionKey {
+ private final IDeviceID deviceID;
+
+ public NoTableNameDeviceIdKey(IDeviceID deviceID) {
+ this.deviceID = deviceID;
+ }
+
+ @Override
+ public int segmentNum() {
+ return deviceID.segmentNum() - 1;
+ }
+
+ @Override
+ public Object segment(int index) {
+ return deviceID.segment(index + 1);
+ }
+ }
}
diff --git a/iotdb-core/node-commons/src/main/java/org/apache/iotdb/commons/partition/executor/hash/APHashExecutor.java b/iotdb-core/node-commons/src/main/java/org/apache/iotdb/commons/partition/executor/hash/APHashExecutor.java
index 9390111d247..6b6c7976a35 100644
--- a/iotdb-core/node-commons/src/main/java/org/apache/iotdb/commons/partition/executor/hash/APHashExecutor.java
+++ b/iotdb-core/node-commons/src/main/java/org/apache/iotdb/commons/partition/executor/hash/APHashExecutor.java
@@ -22,8 +22,6 @@ package org.apache.iotdb.commons.partition.executor.hash;
import org.apache.iotdb.common.rpc.thrift.TSeriesPartitionSlot;
import org.apache.iotdb.commons.partition.executor.SeriesPartitionExecutor;
-import org.apache.tsfile.file.metadata.IDeviceID;
-
import static org.apache.iotdb.commons.conf.IoTDBConstant.PATH_SEPARATOR;
public class APHashExecutor extends SeriesPartitionExecutor {
@@ -49,13 +47,13 @@ public class APHashExecutor extends SeriesPartitionExecutor {
}
@Override
- public TSeriesPartitionSlot getSeriesPartitionSlot(IDeviceID deviceID) {
+ public TSeriesPartitionSlot getSeriesPartitionSlot(SeriesPartitionKey key) {
int hash = 0;
- int segmentNum = deviceID.segmentNum();
+ int segmentNum = key.segmentNum();
int index = 0;
for (int segmentID = 0; segmentID < segmentNum; segmentID++) {
- Object segment = deviceID.segment(segmentID);
+ Object segment = key.segment(segmentID);
if (segment instanceof String) {
String segmentStr = (String) segment;
for (int i = 0; i < segmentStr.length(); i++) {
diff --git a/iotdb-core/node-commons/src/main/java/org/apache/iotdb/commons/partition/executor/hash/BKDRHashExecutor.java b/iotdb-core/node-commons/src/main/java/org/apache/iotdb/commons/partition/executor/hash/BKDRHashExecutor.java
index c039e8ddd83..9502f8007df 100644
--- a/iotdb-core/node-commons/src/main/java/org/apache/iotdb/commons/partition/executor/hash/BKDRHashExecutor.java
+++ b/iotdb-core/node-commons/src/main/java/org/apache/iotdb/commons/partition/executor/hash/BKDRHashExecutor.java
@@ -22,8 +22,6 @@ package org.apache.iotdb.commons.partition.executor.hash;
import org.apache.iotdb.common.rpc.thrift.TSeriesPartitionSlot;
import org.apache.iotdb.commons.partition.executor.SeriesPartitionExecutor;
-import org.apache.tsfile.file.metadata.IDeviceID;
-
import static org.apache.iotdb.commons.conf.IoTDBConstant.PATH_SEPARATOR;
public class BKDRHashExecutor extends SeriesPartitionExecutor {
@@ -47,12 +45,12 @@ public class BKDRHashExecutor extends SeriesPartitionExecutor {
}
@Override
- public TSeriesPartitionSlot getSeriesPartitionSlot(IDeviceID deviceID) {
+ public TSeriesPartitionSlot getSeriesPartitionSlot(SeriesPartitionKey key) {
int hash = 0;
- int segmentNum = deviceID.segmentNum();
+ int segmentNum = key.segmentNum();
for (int segmentID = 0; segmentID < segmentNum; segmentID++) {
- Object segment = deviceID.segment(segmentID);
+ Object segment = key.segment(segmentID);
if (segment instanceof String) {
String segmentStr = (String) segment;
for (int i = 0; i < segmentStr.length(); i++) {
diff --git a/iotdb-core/node-commons/src/main/java/org/apache/iotdb/commons/partition/executor/hash/JSHashExecutor.java b/iotdb-core/node-commons/src/main/java/org/apache/iotdb/commons/partition/executor/hash/JSHashExecutor.java
index 1e8c2031583..734da1ee397 100644
--- a/iotdb-core/node-commons/src/main/java/org/apache/iotdb/commons/partition/executor/hash/JSHashExecutor.java
+++ b/iotdb-core/node-commons/src/main/java/org/apache/iotdb/commons/partition/executor/hash/JSHashExecutor.java
@@ -21,8 +21,6 @@ package org.apache.iotdb.commons.partition.executor.hash;
import org.apache.iotdb.common.rpc.thrift.TSeriesPartitionSlot;
import org.apache.iotdb.commons.partition.executor.SeriesPartitionExecutor;
-import org.apache.tsfile.file.metadata.IDeviceID;
-
import static org.apache.iotdb.commons.conf.IoTDBConstant.PATH_SEPARATOR;
public class JSHashExecutor extends SeriesPartitionExecutor {
@@ -46,12 +44,12 @@ public class JSHashExecutor extends SeriesPartitionExecutor {
}
@Override
- public TSeriesPartitionSlot getSeriesPartitionSlot(IDeviceID deviceID) {
+ public TSeriesPartitionSlot getSeriesPartitionSlot(SeriesPartitionKey key) {
int hash = BASE;
- int segmentNum = deviceID.segmentNum();
+ int segmentNum = key.segmentNum();
for (int segmentID = 0; segmentID < segmentNum; segmentID++) {
- Object segment = deviceID.segment(segmentID);
+ Object segment = key.segment(segmentID);
if (segment instanceof String) {
String segmentStr = (String) segment;
for (int i = 0; i < segmentStr.length(); i++) {
diff --git a/iotdb-core/node-commons/src/main/java/org/apache/iotdb/commons/partition/executor/hash/SDBMHashExecutor.java b/iotdb-core/node-commons/src/main/java/org/apache/iotdb/commons/partition/executor/hash/SDBMHashExecutor.java
index e2143c00c0c..ec68812cac6 100644
--- a/iotdb-core/node-commons/src/main/java/org/apache/iotdb/commons/partition/executor/hash/SDBMHashExecutor.java
+++ b/iotdb-core/node-commons/src/main/java/org/apache/iotdb/commons/partition/executor/hash/SDBMHashExecutor.java
@@ -21,8 +21,6 @@ package org.apache.iotdb.commons.partition.executor.hash;
import org.apache.iotdb.common.rpc.thrift.TSeriesPartitionSlot;
import org.apache.iotdb.commons.partition.executor.SeriesPartitionExecutor;
-import org.apache.tsfile.file.metadata.IDeviceID;
-
import static org.apache.iotdb.commons.conf.IoTDBConstant.PATH_SEPARATOR;
public class SDBMHashExecutor extends SeriesPartitionExecutor {
@@ -44,12 +42,12 @@ public class SDBMHashExecutor extends SeriesPartitionExecutor {
}
@Override
- public TSeriesPartitionSlot getSeriesPartitionSlot(IDeviceID deviceID) {
+ public TSeriesPartitionSlot getSeriesPartitionSlot(SeriesPartitionKey key) {
int hash = 0;
- int segmentNum = deviceID.segmentNum();
+ int segmentNum = key.segmentNum();
for (int segmentID = 0; segmentID < segmentNum; segmentID++) {
- Object segment = deviceID.segment(segmentID);
+ Object segment = key.segment(segmentID);
if (segment instanceof String) {
String segmentStr = (String) segment;
for (int i = 0; i < segmentStr.length(); i++) {
diff --git a/iotdb-core/node-commons/src/main/java/org/apache/iotdb/commons/schema/table/TsTable.java b/iotdb-core/node-commons/src/main/java/org/apache/iotdb/commons/schema/table/TsTable.java
index 7dd64481a0e..d77d5c670f4 100644
--- a/iotdb-core/node-commons/src/main/java/org/apache/iotdb/commons/schema/table/TsTable.java
+++ b/iotdb-core/node-commons/src/main/java/org/apache/iotdb/commons/schema/table/TsTable.java
@@ -46,8 +46,9 @@ import java.io.InputStream;
import java.io.OutputStream;
import java.nio.ByteBuffer;
import java.util.ArrayList;
-import java.util.Collections;
+import java.util.Arrays;
import java.util.HashMap;
+import java.util.HashSet;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
@@ -71,7 +72,9 @@ public class TsTable {
new TimeColumnSchema(TIME_COLUMN_NAME, TSDataType.TIMESTAMP);
public static final String TTL_PROPERTY = "ttl";
- public static final Set<String> TABLE_ALLOWED_PROPERTIES = Collections.singleton(TTL_PROPERTY);
+ public static final String ALLOW_ALTER_NAME_PROPERTY = "allow_alter_name";
+ public static final Set<String> TABLE_ALLOWED_PROPERTIES =
+ new HashSet<>(Arrays.asList(TTL_PROPERTY, ALLOW_ALTER_NAME_PROPERTY));
private static final String OBJECT_STRING_ERROR =
"When there are object fields, the %s %s shall not be '.', '..' or contain './', '.\\'.";
protected String tableName;
@@ -474,4 +477,9 @@ public class TsTable {
+ props
+ '}';
}
+
+ public boolean canAlterName() {
+ return Boolean.parseBoolean(
+ getProps().getOrDefault(TsTable.ALLOW_ALTER_NAME_PROPERTY, "false"));
+ }
}
diff --git a/iotdb-protocol/thrift-datanode/src/main/thrift/datanode.thrift b/iotdb-protocol/thrift-datanode/src/main/thrift/datanode.thrift
index fcc31bdafdf..ab3d973cd2f 100644
--- a/iotdb-protocol/thrift-datanode/src/main/thrift/datanode.thrift
+++ b/iotdb-protocol/thrift-datanode/src/main/thrift/datanode.thrift
@@ -465,6 +465,12 @@ struct TDataRegionEvolveSchemaReq {
3: optional bool isGeneratedByPipe
}
+struct TSchemaRegionEvolveSchemaReq {
+ 1: required list<common.TConsensusGroupId> schemaRegionIdList
+ 2: required binary schemaEvolutions
+ 3: optional bool isGeneratedByPipe
+}
+
struct TDeleteTimeSeriesReq {
1: required list<common.TConsensusGroupId> schemaRegionIdList
2: required binary pathPatternTree
@@ -1100,6 +1106,8 @@ service IDataNodeRPCService {
common.TSStatus evolveSchemaInDataRegion(TDataRegionEvolveSchemaReq req)
+ common.TSStatus evolveSchemaInSchemaRegion(TSchemaRegionEvolveSchemaReq req)
+
/**
* Delete matched timeseries and remove according schema black list in target schemRegion
*/