This is an automated email from the ASF dual-hosted git repository.
JackieTien97 pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/iotdb.git
The following commit(s) were added to refs/heads/master by this push:
new 80d16007436 Reject column changes that conflict with a pending column
deletion or data type change (#18776)
80d16007436 is described below
commit 80d16007436a94e763a8c0d8db66b7e7cbd87ca2
Author: alpass163 <[email protected]>
AuthorDate: Thu Oct 22 13:56:41 2026 +0800
Reject column changes that conflict with a pending column deletion or data
type change (#18776)
---
.../java/org/apache/iotdb/rpc/TSStatusCode.java | 2 +
.../manager/schema/ClusterSchemaManager.java | 120 +++++++++++++++++++--
.../persistence/schema/ClusterSchemaInfo.java | 12 +++
.../confignode/persistence/schema/ConfigMTree.java | 11 ++
.../manager/ClusterSchemaManagerTest.java | 111 +++++++++++++++++++
.../persistence/schema/ConfigMTreeTest.java | 36 +++++++
.../apache/iotdb/commons/i18n/CommonMessages.java | 16 ++-
.../apache/iotdb/commons/i18n/CommonMessages.java | 6 ++
.../exception/table/ColumnInAlterException.java | 40 +++++++
.../exception/table/ColumnInDeletionException.java | 40 +++++++
10 files changed, 381 insertions(+), 13 deletions(-)
diff --git
a/iotdb-client/service-rpc/src/main/java/org/apache/iotdb/rpc/TSStatusCode.java
b/iotdb-client/service-rpc/src/main/java/org/apache/iotdb/rpc/TSStatusCode.java
index da9b4388691..6df31101e47 100644
---
a/iotdb-client/service-rpc/src/main/java/org/apache/iotdb/rpc/TSStatusCode.java
+++
b/iotdb-client/service-rpc/src/main/java/org/apache/iotdb/rpc/TSStatusCode.java
@@ -100,6 +100,8 @@ public enum TSStatusCode {
TABLE_IS_LOST(553),
TABLE_INCOMPATIBLE(554),
TABLE_IN_PRE_DELETE(555),
+ COLUMN_IN_PRE_DELETE(556),
+ COLUMN_IN_PRE_ALTER(557),
ONLY_LOGICAL_VIEW(560),
// Storage Engine
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 e7f96322a53..d85e2e81013 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
@@ -24,6 +24,8 @@ import org.apache.iotdb.common.rpc.thrift.TDataNodeLocation;
import org.apache.iotdb.common.rpc.thrift.TSStatus;
import org.apache.iotdb.commons.conf.CommonDescriptor;
import org.apache.iotdb.commons.exception.MetadataException;
+import org.apache.iotdb.commons.exception.table.ColumnInAlterException;
+import org.apache.iotdb.commons.exception.table.ColumnInDeletionException;
import org.apache.iotdb.commons.exception.table.TableInDeletionException;
import org.apache.iotdb.commons.path.PartialPath;
import org.apache.iotdb.commons.path.PathPatternTree;
@@ -100,6 +102,7 @@ import
org.apache.iotdb.confignode.manager.partition.PartitionMetrics;
import
org.apache.iotdb.confignode.manager.partition.RegionGroupExtensionPolicy;
import org.apache.iotdb.confignode.persistence.schema.ClusterSchemaInfo;
import org.apache.iotdb.confignode.persistence.schema.ConfigSchemaStatistics;
+import
org.apache.iotdb.confignode.persistence.schema.mnode.impl.ConfigTableNode;
import org.apache.iotdb.confignode.rpc.thrift.TDatabaseInfo;
import org.apache.iotdb.confignode.rpc.thrift.TDatabaseSchema;
import org.apache.iotdb.confignode.rpc.thrift.TDescTable4InformationSchemaResp;
@@ -1541,17 +1544,113 @@ public class ClusterSchemaManager {
return clusterSchemaInfo.getTsTableIfExists(database, tableName);
}
+ /**
+ * The table must exist and must not be in the pre-delete status.
+ *
+ * @return the table node, or empty when the table does not exist
+ */
+ private Optional<ConfigTableNode> getTableNodeForModification(
+ final String database, final String tableName) throws MetadataException {
+ final Optional<ConfigTableNode> tableNodeOptional =
+ clusterSchemaInfo.getTableNodeIfExists(database, tableName);
+ if (tableNodeOptional.isPresent()
+ && TableNodeStatus.PRE_DELETE == tableNodeOptional.get().getStatus()) {
+ throw new TableInDeletionException(database, tableName);
+ }
+ return tableNodeOptional;
+ }
+
public Optional<TsTable> getTableWithUsingStatusIfExists(
final String database, final String tableName) throws MetadataException {
- final Optional<Pair<TsTable, TableNodeStatus>> tableAndStatus =
- getTableAndStatusIfExists(database, tableName);
- if (tableAndStatus.isEmpty()) {
+ return getTableNodeForModification(database,
tableName).map(ConfigTableNode::getTable);
+ }
+
+ /**
+ * The new column names must not belong to a column whose deletion or data
type change has not
+ * finished, otherwise the column being added would collide with it.
+ *
+ * @return the table, or empty when the table does not exist
+ */
+ public Optional<TsTable> checkTableAndColumnsForAddition(
+ final String database,
+ final String tableName,
+ final List<TsTableColumnSchema> columnSchemaList)
+ throws MetadataException {
+ final Optional<ConfigTableNode> tableNodeOptional =
+ getTableNodeForModification(database, tableName);
+ if (tableNodeOptional.isEmpty()) {
return Optional.empty();
}
- if (TableNodeStatus.PRE_DELETE == tableAndStatus.get().getRight()) {
- throw new TableInDeletionException(database, tableName);
+ final ConfigTableNode tableNode = tableNodeOptional.get();
+ for (final TsTableColumnSchema columnSchema : columnSchemaList) {
+ final String columnName = columnSchema.getColumnName();
+ checkColumnNotDeleting(tableNode, database, tableName, columnName);
+ checkColumnNotAltering(tableNode, database, tableName, columnName);
+ }
+ return Optional.of(tableNode.getTable());
+ }
+
+ /**
+ * The column must not be one whose deletion has not finished. A pending
data type change is
+ * allowed here: the new type replaces the pending one.
+ *
+ * @return the table, or empty when the table does not exist
+ */
+ public Optional<TsTable> checkTableAndColumnForAltering(
+ final String database, final String tableName, final String columnName)
+ throws MetadataException {
+ final Optional<ConfigTableNode> tableNodeOptional =
+ getTableNodeForModification(database, tableName);
+ if (tableNodeOptional.isEmpty()) {
+ return Optional.empty();
+ }
+ final ConfigTableNode tableNode = tableNodeOptional.get();
+ checkColumnNotDeleting(tableNode, database, tableName, columnName);
+ return Optional.of(tableNode.getTable());
+ }
+
+ /**
+ * Neither the old nor the new column name may belong to a column whose
deletion or data type
+ * change has not finished.
+ *
+ * @return the table, or empty when the table does not exist
+ */
+ public Optional<TsTable> checkTableAndColumnsForRenaming(
+ final String database, final String tableName, final String oldName,
final String newName)
+ throws MetadataException {
+ final Optional<ConfigTableNode> tableNodeOptional =
+ getTableNodeForModification(database, tableName);
+ if (tableNodeOptional.isEmpty()) {
+ return Optional.empty();
+ }
+ final ConfigTableNode tableNode = tableNodeOptional.get();
+ checkColumnNotDeleting(tableNode, database, tableName, oldName);
+ checkColumnNotAltering(tableNode, database, tableName, oldName);
+ checkColumnNotDeleting(tableNode, database, tableName, newName);
+ checkColumnNotAltering(tableNode, database, tableName, newName);
+ return Optional.of(tableNode.getTable());
+ }
+
+ private void checkColumnNotDeleting(
+ final ConfigTableNode tableNode,
+ final String database,
+ final String tableName,
+ final String columnName)
+ throws ColumnInDeletionException {
+ if (tableNode.getPreDeletedColumns().contains(columnName)) {
+ throw new ColumnInDeletionException(database, tableName, columnName);
+ }
+ }
+
+ private void checkColumnNotAltering(
+ final ConfigTableNode tableNode,
+ final String database,
+ final String tableName,
+ final String columnName)
+ throws ColumnInAlterException {
+ if (tableNode.getPreAlteredColumns().containsKey(columnName)) {
+ throw new ColumnInAlterException(database, tableName, columnName);
}
- return Optional.of(tableAndStatus.get().getLeft());
}
public synchronized Pair<TSStatus, TsTable>
tableColumnCheckForColumnExtension(
@@ -1560,7 +1659,8 @@ public class ClusterSchemaManager {
final List<TsTableColumnSchema> columnSchemaList,
final boolean isTableView)
throws MetadataException {
- final TsTable originalTable = getTableWithUsingStatusIfExists(database,
tableName).orElse(null);
+ final TsTable originalTable =
+ checkTableAndColumnsForAddition(database, tableName,
columnSchemaList).orElse(null);
if (Objects.isNull(originalTable)) {
return new Pair<>(
@@ -1615,7 +1715,8 @@ public class ClusterSchemaManager {
final TSDataType dataType,
final boolean isGeneratedByPipe)
throws MetadataException {
- final TsTable originalTable = getTableWithUsingStatusIfExists(database,
tableName).orElse(null);
+ final TsTable originalTable =
+ checkTableAndColumnForAltering(database, tableName,
columnName).orElse(null);
if (Objects.isNull(originalTable)) {
return new Pair<>(
@@ -1652,7 +1753,8 @@ public class ClusterSchemaManager {
final String newName,
final boolean isTableView)
throws MetadataException {
- final TsTable originalTable = getTableWithUsingStatusIfExists(database,
tableName).orElse(null);
+ final TsTable originalTable =
+ checkTableAndColumnsForRenaming(database, tableName, oldName,
newName).orElse(null);
if (Objects.isNull(originalTable)) {
return new Pair<>(
diff --git
a/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/persistence/schema/ClusterSchemaInfo.java
b/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/persistence/schema/ClusterSchemaInfo.java
index 6bae27bc7f2..94fc65e8ba2 100644
---
a/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/persistence/schema/ClusterSchemaInfo.java
+++
b/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/persistence/schema/ClusterSchemaInfo.java
@@ -99,6 +99,7 @@ import
org.apache.iotdb.confignode.consensus.response.template.TemplateSetInfoRe
import org.apache.iotdb.confignode.exception.DatabaseNotExistsException;
import org.apache.iotdb.confignode.i18n.ConfigNodeMessages;
import
org.apache.iotdb.confignode.persistence.schema.ConfigMTree.TableSchemaDetails;
+import
org.apache.iotdb.confignode.persistence.schema.mnode.impl.ConfigTableNode;
import org.apache.iotdb.confignode.rpc.thrift.TDatabaseSchema;
import org.apache.iotdb.confignode.rpc.thrift.TTableColumnInfo;
import org.apache.iotdb.confignode.rpc.thrift.TTableInfo;
@@ -1560,6 +1561,17 @@ public class ClusterSchemaInfo implements
SnapshotProcessor {
}
}
+ public Optional<ConfigTableNode> getTableNodeIfExists(
+ final String database, final String tableName) throws MetadataException {
+ databaseReadWriteLock.readLock().lock();
+ try {
+ return tableModelMTree.getTableNodeIfExists(
+ getQualifiedDatabasePartialPath(database), tableName);
+ } finally {
+ databaseReadWriteLock.readLock().unlock();
+ }
+ }
+
public TSStatus addTableColumn(final AddTableColumnPlan plan) {
return executeWithLock(
() -> {
diff --git
a/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/persistence/schema/ConfigMTree.java
b/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/persistence/schema/ConfigMTree.java
index ddb16660498..f31454b7b4c 100644
---
a/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/persistence/schema/ConfigMTree.java
+++
b/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/persistence/schema/ConfigMTree.java
@@ -1027,6 +1027,8 @@ public class ConfigMTree {
throw new
SemanticException(ConfigNodeMessages.DROPPING_TAG_OR_TIME_COLUMN_IS_NOT_SUPPORTED);
}
+ // Dropping the column makes a pending data type change moot.
+ node.removePreAlteredColumn(columnName);
node.addPreDeletedColumn(columnName);
return columnSchema.getColumnCategory() == TsTableColumnCategory.ATTRIBUTE;
}
@@ -1181,6 +1183,15 @@ public class ConfigMTree {
return ((ConfigTableNode) databaseNode.getChild(tableName));
}
+ public Optional<ConfigTableNode> getTableNodeIfExists(
+ final PartialPath database, final String tableName) throws
MetadataException {
+ final IConfigMNode databaseNode =
getDatabaseNodeByDatabasePath(database).getAsMNode();
+ if (!databaseNode.hasChild(tableName)) {
+ return Optional.empty();
+ }
+ return Optional.of((ConfigTableNode) databaseNode.getChild(tableName));
+ }
+
/**
* A table in the pre-delete status is about to be dropped, pre-create
status is a temporary
* status, ignore it.
diff --git
a/iotdb-core/confignode/src/test/java/org/apache/iotdb/confignode/manager/ClusterSchemaManagerTest.java
b/iotdb-core/confignode/src/test/java/org/apache/iotdb/confignode/manager/ClusterSchemaManagerTest.java
index 1be38df602a..c63ea9a98d6 100644
---
a/iotdb-core/confignode/src/test/java/org/apache/iotdb/confignode/manager/ClusterSchemaManagerTest.java
+++
b/iotdb-core/confignode/src/test/java/org/apache/iotdb/confignode/manager/ClusterSchemaManagerTest.java
@@ -18,13 +18,19 @@
*/
package org.apache.iotdb.confignode.manager;
+import org.apache.iotdb.commons.exception.table.ColumnInAlterException;
+import org.apache.iotdb.commons.exception.table.ColumnInDeletionException;
import org.apache.iotdb.commons.exception.table.TableInDeletionException;
import org.apache.iotdb.commons.schema.table.TsTable;
import org.apache.iotdb.commons.schema.table.TsTableInternalRPCUtil;
+import org.apache.iotdb.commons.schema.table.column.FieldColumnSchema;
+import org.apache.iotdb.commons.schema.table.column.TsTableColumnSchema;
import org.apache.iotdb.confignode.consensus.request.ConfigPhysicalPlanType;
import
org.apache.iotdb.confignode.consensus.request.write.database.DatabaseSchemaPlan;
import
org.apache.iotdb.confignode.consensus.request.write.table.CommitCreateTablePlan;
+import
org.apache.iotdb.confignode.consensus.request.write.table.PreAlterColumnDataTypePlan;
import
org.apache.iotdb.confignode.consensus.request.write.table.PreCreateTablePlan;
+import
org.apache.iotdb.confignode.consensus.request.write.table.PreDeleteColumnPlan;
import
org.apache.iotdb.confignode.consensus.request.write.table.PreDeleteTablePlan;
import org.apache.iotdb.confignode.manager.schema.ClusterSchemaManager;
import org.apache.iotdb.confignode.manager.schema.ClusterSchemaQuotaStatistics;
@@ -33,6 +39,8 @@ import org.apache.iotdb.confignode.rpc.thrift.TDatabaseSchema;
import org.apache.iotdb.rpc.TSStatusCode;
import org.apache.tsfile.enums.TSDataType;
+import org.apache.tsfile.file.metadata.enums.CompressionType;
+import org.apache.tsfile.file.metadata.enums.TSEncoding;
import org.apache.tsfile.utils.Pair;
import org.junit.Assert;
import org.junit.Test;
@@ -46,6 +54,9 @@ import java.util.Map;
public class ClusterSchemaManagerTest {
+ private static final String DATABASE = "root.pending_column_test";
+ private static final String TABLE = "table1";
+
@Test
public void testCalcMaxRegionGroupNum() {
@@ -172,6 +183,106 @@ public class ClusterSchemaManagerTest {
database, table, new HashMap<>(), new HashMap<>(), false));
}
+ @Test
+ public void testAddColumnRejectsPendingColumnNames() throws Exception {
+ final ClusterSchemaManager clusterSchemaManager =
prepareTableWithPendingColumns();
+
+ // A name whose deletion has not finished, and a name whose data type
change has not finished,
+ // are both rejected by the entry point the ADD COLUMN procedure uses.
+ Assert.assertThrows(
+ ColumnInDeletionException.class,
+ () ->
+ clusterSchemaManager.tableColumnCheckForColumnExtension(
+ DATABASE, TABLE, columns("deleting"), false));
+ Assert.assertThrows(
+ ColumnInAlterException.class,
+ () ->
+ clusterSchemaManager.tableColumnCheckForColumnExtension(
+ DATABASE, TABLE, columns("altering"), false));
+ // A name that no pending column takes can still be added.
+ Assert.assertEquals(
+ TSStatusCode.SUCCESS_STATUS.getStatusCode(),
+ clusterSchemaManager
+ .tableColumnCheckForColumnExtension(DATABASE, TABLE,
columns("added"), false)
+ .getLeft()
+ .getCode());
+ }
+
+ @Test
+ public void testAlterColumnTypeRejectsDeletingColumn() throws Exception {
+ final ClusterSchemaManager clusterSchemaManager =
prepareTableWithPendingColumns();
+
+ // Changing the data type of a column whose deletion has not finished is
rejected.
+ Assert.assertThrows(
+ ColumnInDeletionException.class,
+ () ->
+ clusterSchemaManager.tableColumnCheckForColumnAltering(
+ DATABASE, TABLE, "deleting", TSDataType.INT64, false));
+ // A column that already has a pending data type change may be changed
again. Only the check is
+ // used here, because the entry point above writes the new pending type
through the consensus
+ // layer, which a unit test does not provide.
+ Assert.assertTrue(
+ clusterSchemaManager
+ .checkTableAndColumnForAltering(DATABASE, TABLE, "altering")
+ .isPresent());
+ }
+
+ @Test
+ public void testRenameColumnRejectsPendingNames() throws Exception {
+ final ClusterSchemaManager clusterSchemaManager =
prepareTableWithPendingColumns();
+
+ // The entry point the RENAME COLUMN procedure uses rejects an old name
that is being deleted,
+ // and a new name that a pending column already takes.
+ Assert.assertThrows(
+ ColumnInDeletionException.class,
+ () ->
+ clusterSchemaManager.tableColumnCheckForColumnRenaming(
+ DATABASE, TABLE, "deleting", "renamed", false));
+ Assert.assertThrows(
+ ColumnInAlterException.class,
+ () ->
+ clusterSchemaManager.tableColumnCheckForColumnRenaming(
+ DATABASE, TABLE, "live", "altering", false));
+ // Renaming between two names that no pending column takes is allowed.
+ Assert.assertEquals(
+ TSStatusCode.SUCCESS_STATUS.getStatusCode(),
+ clusterSchemaManager
+ .tableColumnCheckForColumnRenaming(DATABASE, TABLE, "live",
"added", false)
+ .getLeft()
+ .getCode());
+ }
+
+ /** A table whose {@code deleting} column is being deleted and {@code
altering} column altered. */
+ private static ClusterSchemaManager prepareTableWithPendingColumns() throws
Exception {
+ final ClusterSchemaInfo clusterSchemaInfo = new ClusterSchemaInfo();
+ clusterSchemaInfo.createDatabase(
+ new DatabaseSchemaPlan(
+ ConfigPhysicalPlanType.CreateDatabase,
+ new TDatabaseSchema(DATABASE).setIsTableModel(true)));
+ final TsTable table = new TsTable(TABLE);
+ table.addColumnSchema(field("live"));
+ table.addColumnSchema(field("deleting"));
+ table.addColumnSchema(field("altering"));
+ clusterSchemaInfo.preCreateTable(new PreCreateTablePlan(DATABASE, table));
+ clusterSchemaInfo.commitCreateTable(new CommitCreateTablePlan(DATABASE,
TABLE));
+ clusterSchemaInfo.preDeleteColumn(new PreDeleteColumnPlan(DATABASE, TABLE,
"deleting"));
+ clusterSchemaInfo.preAlterColumnDataType(
+ new PreAlterColumnDataTypePlan(DATABASE, TABLE, "altering",
TSDataType.INT64));
+ return managerOf(clusterSchemaInfo);
+ }
+
+ private static List<TsTableColumnSchema> columns(final String...
columnNames) {
+ final List<TsTableColumnSchema> columnSchemaList = new ArrayList<>();
+ for (final String columnName : columnNames) {
+ columnSchemaList.add(field(columnName));
+ }
+ return columnSchemaList;
+ }
+
+ private static FieldColumnSchema field(final String columnName) {
+ return new FieldColumnSchema(columnName, TSDataType.INT32, TSEncoding.RLE,
CompressionType.LZ4);
+ }
+
private static ClusterSchemaManager managerOf(final ClusterSchemaInfo
clusterSchemaInfo) {
return new ClusterSchemaManager(
Mockito.mock(IManager.class),
diff --git
a/iotdb-core/confignode/src/test/java/org/apache/iotdb/confignode/persistence/schema/ConfigMTreeTest.java
b/iotdb-core/confignode/src/test/java/org/apache/iotdb/confignode/persistence/schema/ConfigMTreeTest.java
index f66edecbbcc..29ea80f9dd9 100644
---
a/iotdb-core/confignode/src/test/java/org/apache/iotdb/confignode/persistence/schema/ConfigMTreeTest.java
+++
b/iotdb-core/confignode/src/test/java/org/apache/iotdb/confignode/persistence/schema/ConfigMTreeTest.java
@@ -484,6 +484,42 @@ public class ConfigMTreeTest {
root.getUsingTableSchema(database,
table.getTableName()).getColumnSchema("measurement"));
}
+ @Test
+ public void testDropColumnClearsPendingDataTypeChange() throws Exception {
+ root = new ConfigMTree(true);
+
+ final PartialPath database = new PartialPath("root.sg");
+ root.setStorageGroup(database);
+ final IDatabaseMNode<IConfigMNode> databaseNode =
root.getDatabaseNodeByDatabasePath(database);
+ databaseNode
+ .getAsMNode()
+ .getDatabaseSchema()
+ .setName(PathUtils.unQualifyDatabaseName(database.getFullPath()));
+ databaseNode.getAsMNode().getDatabaseSchema().setIsTableModel(true);
+
+ final TsTable table = new TsTable("table1");
+ table.addColumnSchema(new TagColumnSchema("id", TSDataType.STRING));
+ table.addColumnSchema(
+ new FieldColumnSchema(
+ "measurement", TSDataType.DOUBLE, TSEncoding.GORILLA,
CompressionType.SNAPPY));
+ root.preCreateTable(database, table);
+ root.commitCreateTable(database, table.getTableName());
+
+ root.preAlterColumnDataType(database, table.getTableName(), "measurement",
TSDataType.STRING);
+ Assert.assertTrue(
+ root.getTableSchemaDetails(database, table.getTableName())
+ .preAlteredColumns
+ .containsKey("measurement"));
+
+ root.preDeleteColumn(database, table.getTableName(), "measurement", false);
+
+ ConfigMTree.TableSchemaDetails tableSchemaDetails =
+ root.getTableSchemaDetails(database, table.getTableName());
+
Assert.assertTrue(tableSchemaDetails.preDeletedColumns.contains("measurement"));
+ // The pending data type change is moot once the column is dropped.
+
Assert.assertFalse(tableSchemaDetails.preAlteredColumns.containsKey("measurement"));
+ }
+
@Test
public void testSetTemplate() throws MetadataException {
root.setStorageGroup(new PartialPath("root.a"));
diff --git
a/iotdb-core/node-commons/src/main/i18n/en/org/apache/iotdb/commons/i18n/CommonMessages.java
b/iotdb-core/node-commons/src/main/i18n/en/org/apache/iotdb/commons/i18n/CommonMessages.java
index a0bcb6078e2..df88f4dbb18 100644
---
a/iotdb-core/node-commons/src/main/i18n/en/org/apache/iotdb/commons/i18n/CommonMessages.java
+++
b/iotdb-core/node-commons/src/main/i18n/en/org/apache/iotdb/commons/i18n/CommonMessages.java
@@ -124,10 +124,12 @@ public final class CommonMessages {
public static final String REPAIR_SYSTEM_PROPERTIES = "repair
system.properties, lack {}";
public static final String
PARAMETER_CANNOT_BE_MODIFIED_AFTER_FIRST_STARTUP_FMT =
"%s can't be modified after first startup";
- public static final String
MISC_LOG_SERIALIZE_MUTABLE_SYSTEM_PROPERTIES_SUCCESSFULLY_WHICH_TAKES_4656A206 =
- "Serialize mutable system properties successfully, which takes {} ms.";
- public static final String
MISC_LOG_DO_NOT_UPGRADE_IOTDB_FROM_V0_9_OR_LOWER_VERSION_TO_V1_0_9878EC88 =
- "DO NOT UPGRADE IoTDB from v0.9 or lower version to v1.0! Please upgrade
to v0.10 first";
+ public static final String
+
MISC_LOG_SERIALIZE_MUTABLE_SYSTEM_PROPERTIES_SUCCESSFULLY_WHICH_TAKES_4656A206 =
+ "Serialize mutable system properties successfully, which takes {}
ms.";
+ public static final String
+
MISC_LOG_DO_NOT_UPGRADE_IOTDB_FROM_V0_9_OR_LOWER_VERSION_TO_V1_0_9878EC88 =
+ "DO NOT UPGRADE IoTDB from v0.9 or lower version to v1.0! Please
upgrade to v0.10 first";
private CommonMessages() {}
@@ -341,6 +343,12 @@ public final class CommonMessages {
public static final String
EXCEPTION_THE_TABLE_ARG_ARG_IS_IN_THE_PRE_DELETE_STATE_PLEASE_WAIT_A_FEW_SECONDS_IF_THE_TABLE_IS_STILL_IN_THIS_STATE_PLEASE_DROP_IT_AGAIN_13B9D39F
=
"The table %s.%s is in the pre-delete state. Please wait a few
seconds. If the table is still in this state, please drop it again.";
+ public static final String
+
EXCEPTION_COLUMN_ARG_IN_TABLE_ARG_ARG_IS_BEING_DELETED_PLEASE_WAIT_FOR_DELETION_TO_FINISH_OR_RETRY_DROPPING_THE_COLUMN_IF_IT_IS_STUCK_875DAFFE
=
+ "Column '%s' in table '%s.%s' is being deleted. Please wait for
deletion to finish, or retry dropping the column if it is stuck.";
+ public static final String
+
EXCEPTION_COLUMN_ARG_IN_TABLE_ARG_ARG_IS_BEING_ALTERED_PLEASE_WAIT_FOR_ALTERATION_TO_FINISH_OR_RETRY_ALTERING_THE_COLUMN_IF_IT_IS_STUCK_11155B55
=
+ "Column '%s' in table '%s.%s' is being altered. Please wait for
alteration to finish, or retry altering the column if it is stuck.";
public static final String EXCEPTION_MEMORY_BLOCK_ARG_IS_READ_ONLY_D10B3340 =
"Memory block %s is read-only";
public static final String
EXCEPTION_MEMORY_BLOCK_ARG_ALREADY_USES_MUTABLE_ACCOUNTING_6F7DCB3F =
diff --git
a/iotdb-core/node-commons/src/main/i18n/zh/org/apache/iotdb/commons/i18n/CommonMessages.java
b/iotdb-core/node-commons/src/main/i18n/zh/org/apache/iotdb/commons/i18n/CommonMessages.java
index 75873a97671..25be984f2d1 100644
---
a/iotdb-core/node-commons/src/main/i18n/zh/org/apache/iotdb/commons/i18n/CommonMessages.java
+++
b/iotdb-core/node-commons/src/main/i18n/zh/org/apache/iotdb/commons/i18n/CommonMessages.java
@@ -241,4 +241,10 @@ public final class CommonMessages {
public static final String EXCEPTION_MEMORY_BLOCK_ARG_IS_READ_ONLY_D10B3340
= "内存块 %s 为只读";
public static final String
EXCEPTION_MEMORY_BLOCK_ARG_ALREADY_USES_MUTABLE_ACCOUNTING_6F7DCB3F =
"内存块 %s 已使用可变计量";
+ public static final String
+
EXCEPTION_COLUMN_ARG_IN_TABLE_ARG_ARG_IS_BEING_DELETED_PLEASE_WAIT_FOR_DELETION_TO_FINISH_OR_RETRY_DROPPING_THE_COLUMN_IF_IT_IS_STUCK_875DAFFE
=
+ "列 '%s'(位于表 '%s.%s')正在删除中。请等待删除完成;如果删除一直未完成,请重试删除该列。";
+ public static final String
+
EXCEPTION_COLUMN_ARG_IN_TABLE_ARG_ARG_IS_BEING_ALTERED_PLEASE_WAIT_FOR_ALTERATION_TO_FINISH_OR_RETRY_ALTERING_THE_COLUMN_IF_IT_IS_STUCK_11155B55
=
+ "列 '%s'(位于表 '%s.%s')正在修改中。请等待修改完成;如果修改一直未完成,请重试修改该列。";
}
diff --git
a/iotdb-core/node-commons/src/main/java/org/apache/iotdb/commons/exception/table/ColumnInAlterException.java
b/iotdb-core/node-commons/src/main/java/org/apache/iotdb/commons/exception/table/ColumnInAlterException.java
new file mode 100644
index 00000000000..ee08f2f0a58
--- /dev/null
+++
b/iotdb-core/node-commons/src/main/java/org/apache/iotdb/commons/exception/table/ColumnInAlterException.java
@@ -0,0 +1,40 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.iotdb.commons.exception.table;
+
+import org.apache.iotdb.commons.exception.MetadataException;
+import org.apache.iotdb.commons.i18n.CommonMessages;
+import org.apache.iotdb.commons.utils.PathUtils;
+import org.apache.iotdb.rpc.TSStatusCode;
+
+public class ColumnInAlterException extends MetadataException {
+
+ public ColumnInAlterException(
+ final String database, final String tableName, final String columnName) {
+ super(
+ String.format(
+ CommonMessages
+
.EXCEPTION_COLUMN_ARG_IN_TABLE_ARG_ARG_IS_BEING_ALTERED_PLEASE_WAIT_FOR_ALTERATION_TO_FINISH_OR_RETRY_ALTERING_THE_COLUMN_IF_IT_IS_STUCK_11155B55,
+ columnName,
+ PathUtils.unQualifyDatabaseName(database),
+ tableName),
+ TSStatusCode.COLUMN_IN_PRE_ALTER.getStatusCode());
+ }
+}
diff --git
a/iotdb-core/node-commons/src/main/java/org/apache/iotdb/commons/exception/table/ColumnInDeletionException.java
b/iotdb-core/node-commons/src/main/java/org/apache/iotdb/commons/exception/table/ColumnInDeletionException.java
new file mode 100644
index 00000000000..93bdbc305df
--- /dev/null
+++
b/iotdb-core/node-commons/src/main/java/org/apache/iotdb/commons/exception/table/ColumnInDeletionException.java
@@ -0,0 +1,40 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.iotdb.commons.exception.table;
+
+import org.apache.iotdb.commons.exception.MetadataException;
+import org.apache.iotdb.commons.i18n.CommonMessages;
+import org.apache.iotdb.commons.utils.PathUtils;
+import org.apache.iotdb.rpc.TSStatusCode;
+
+public class ColumnInDeletionException extends MetadataException {
+
+ public ColumnInDeletionException(
+ final String database, final String tableName, final String columnName) {
+ super(
+ String.format(
+ CommonMessages
+
.EXCEPTION_COLUMN_ARG_IN_TABLE_ARG_ARG_IS_BEING_DELETED_PLEASE_WAIT_FOR_DELETION_TO_FINISH_OR_RETRY_DROPPING_THE_COLUMN_IF_IT_IS_STUCK_875DAFFE,
+ columnName,
+ PathUtils.unQualifyDatabaseName(database),
+ tableName),
+ TSStatusCode.COLUMN_IN_PRE_DELETE.getStatusCode());
+ }
+}