Skip to content

Show pre-delete tables in SHOW TABLES and reject modifications on them - #18770

Open
alpass163 wants to merge 4 commits into
apache:masterfrom
alpass163:cyb/fix_pre_delete_table
Open

alpass163 wants to merge 4 commits into
apache:masterfrom
alpass163:cyb/fix_pre_delete_table

Conversation

@alpass163

Copy link
Copy Markdown
Contributor

Handle tables that are stuck in the pre-delete status (PRE_DELETE), i.e. a DROP TABLE
has started for them but has not finished:

  1. SHOW TABLES now lists them, so such a table is visible to the user instead of
    silently missing from the result.
  2. Schema modifications on them are rejected with a dedicated status code and a
    message that tells the user to retry DROP TABLE.

@Caideyipi Caideyipi left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Findings

[P2] DataNode 查询会丢失 555 状态码

iotdb-core/datanode/src/main/java/org/apache/iotdb/db/schemaengine/table/DataNodeTableCache.java:712-718 直接构造带 TABLE_IN_PRE_DELETE(555) 的 SemanticException。但 ErrorHandlingUtils.tryCatchQueryException() 对 SemanticException 只有在 cause 是 IoTDBException 时才读取 cause 的状态码,否则固定返回 SEMANTIC_ERROR(701)(iotdb-core/datanode/src/main/java/org/apache/iotdb/db/utils/ErrorHandlingUtils.java:194-200)。因此查询分析阶段命中 PRE_DELETE 表时,客户端收到 701 而不是本 PR 新增的 555,无法按专用状态码处理。请改为包装 TableInDeletionException,或让查询异常处理读取该异常自身的 getErrorCode(),并补一个 RPC 层测试。

[P2] 同名 CREATE TABLE 仍把 PRE_DELETE 表当作普通已存在表

iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/procedure/impl/schema/table/CreateTableProcedure.java:118-130 仍调用 getTableIfExists(),只要表节点存在就返回 TABLE_ALREADY_EXISTS(551)。当 DROP TABLE 卡在 PRE_DELETE 后重试同名 CREATE 时,用户得到 551 而不是本 PR 定义的 555;非 replace 的 CREATE VIEW 也会走这个基类检查。请读取表状态并对 PRE_DELETE 抛出 TableInDeletionException;共识层 ConfigMTree.preCreateTable() 的同名检查也应保持一致。

[P2] RENAME TABLE 未检查目标名的 PRE_DELETE 状态

iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/manager/schema/ClusterSchemaManager.java:1702-1730 已用 getTableWithUsingStatusIfExists() 检查源表,但目标名仍调用 getTableIfExists(database, newName)。因此把表重命名为一个处于 PRE_DELETE 的目标名时,返回的是 TABLE_ALREADY_EXISTS(551),而不是 555,客户端无法区分“正在删除、稍后重试”和普通重名冲突。请读取目标表的 TableNodeStatus,在 PRE_DELETE 时抛出 TableInDeletionException。

Verification

未运行 Maven 测试;上述结论基于 PR head 3fe2ff16ff11afab3c730850bcccfd55b293da04 的调用链和源码核对。

@alpass163

Copy link
Copy Markdown
Contributor Author

Findings

[P2] DataNode 查询会丢失 555 状态码

iotdb-core/datanode/src/main/java/org/apache/iotdb/db/schemaengine/table/DataNodeTableCache.java:712-718 直接构造带 TABLE_IN_PRE_DELETE(555) 的 SemanticException。但 ErrorHandlingUtils.tryCatchQueryException() 对 SemanticException 只有在 cause 是 IoTDBException 时才读取 cause 的状态码,否则固定返回 SEMANTIC_ERROR(701)(iotdb-core/datanode/src/main/java/org/apache/iotdb/db/utils/ErrorHandlingUtils.java:194-200)。因此查询分析阶段命中 PRE_DELETE 表时,客户端收到 701 而不是本 PR 新增的 555,无法按专用状态码处理。请改为包装 TableInDeletionException,或让查询异常处理读取该异常自身的 getErrorCode(),并补一个 RPC 层测试。

[P2] 同名 CREATE TABLE 仍把 PRE_DELETE 表当作普通已存在表

iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/procedure/impl/schema/table/CreateTableProcedure.java:118-130 仍调用 getTableIfExists(),只要表节点存在就返回 TABLE_ALREADY_EXISTS(551)。当 DROP TABLE 卡在 PRE_DELETE 后重试同名 CREATE 时,用户得到 551 而不是本 PR 定义的 555;非 replace 的 CREATE VIEW 也会走这个基类检查。请读取表状态并对 PRE_DELETE 抛出 TableInDeletionException;共识层 ConfigMTree.preCreateTable() 的同名检查也应保持一致。

[P2] RENAME TABLE 未检查目标名的 PRE_DELETE 状态

iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/manager/schema/ClusterSchemaManager.java:1702-1730 已用 getTableWithUsingStatusIfExists() 检查源表,但目标名仍调用 getTableIfExists(database, newName)。因此把表重命名为一个处于 PRE_DELETE 的目标名时,返回的是 TABLE_ALREADY_EXISTS(551),而不是 555,客户端无法区分“正在删除、稍后重试”和普通重名冲突。请读取目标表的 TableNodeStatus,在 PRE_DELETE 时抛出 TableInDeletionException。

Verification

未运行 Maven 测试;上述结论基于 PR head 3fe2ff16ff11afab3c730850bcccfd55b293da04 的调用链和源码核对。

  1. 关于【DataNode 查询会丢失 555 状态码】,已经修复

  2. 关于【同名 CREATE TABLE 仍把 PRE_DELETE 表当作普通已存在表】 和 【[P2] RENAME TABLE 未检查目标名的 PRE_DELETE 状态】 这里是故意调用`getTableIfExists(),这里其实无需区分该表是处于删除状态还是正常使用状态,该pr合入之后,show tables也能看到删除的表;

@alpass163
alpass163 force-pushed the cyb/fix_pre_delete_table branch from 52290a8 to 28812a1 Compare September 30, 2026 02:59
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants