Skip to content

[#12221] feat(iceberg): Add conditional table undrop - #12227

Open
nevzheng wants to merge 11 commits into
apache:mainfrom
nevzheng:codex/iceberg-rest-delete-20-03-undrop
Open

[#12221] feat(iceberg): Add conditional table undrop#12227
nevzheng wants to merge 11 commits into
apache:mainfrom
nevzheng:codex/iceberg-rest-delete-20-03-undrop

Conversation

@nevzheng

@nevzheng nevzheng commented Jul 27, 2026

Copy link
Copy Markdown
Collaborator

What changes were proposed in this pull request?

This is Stack 20 review unit 5 of 5 and depends on #12226.

Review the commits in order:

  1. feat(iceberg): add conditional table undrop
    • Adds POST /management/v1/{prefix}/namespaces/{namespace}/tables/{table}/undrop.
    • Requires the exact deletionId in the request body and one strong deletion ETag in If-Match; the ETag is a precondition, not an identifier.
    • Resolves the retained table through table_meta.deletion_id and verifies that it is still the requested D1.
    • Uses fine-grained row locks to require D1 to be DELETED, unexpired, and not attached to a purge job.
    • In one relational transaction, reactivates the original table_meta row, clears its deletion fields, consumes D1, and appends the ALTER change event.
    • Invalidates local and peer table caches after commit and returns the ordinary live table response.
  2. test(iceberg): cover undrop transaction boundaries
    • Verifies rollback and retry when the change event cannot commit.
    • Verifies that concurrent UNDROP requests can transition the retained row only once.

UNDROP never creates a replacement table and never runs an Iceberg unregister/register saga. There is no persisted RESTORED receipt or audit table in this POC; a repeated request after restoration observes no active deletion target.

After this PR: the Stack 20 API lifecycle is complete for review: DELETE retains the original row, deleted=true discovers D1 and its ETag, and conditional UNDROP directly reactivates that exact table generation. Purge selection, jobs, and physical file cleanup remain a separate epic.

Review order: #12222#12223#12225#12228#12229#12226#12227.

Incremental diff:
nevzheng/gravitino@codex/iceberg-rest-delete-20-02-deleted-table-reads...codex/iceberg-rest-delete-20-03-undrop

Why are the changes needed?

This provides generation-safe recovery with one short relational transaction and the same row-lock boundary that a future purge claimant will use.

Related: #12221

Does this PR introduce any user-facing change?

Yes. Authorized clients can restore an eligible deleted table using its deletion ID and current strong ETag. Malformed, missing, stale, conflicting, expired, and purge-boundary requests receive distinct sanitized errors.

How was this patch tested?

The full Stack 20 head passes the combined focused configuration, relational, cache, DELETE, deleted-read, authorization, ETag, UNDROP, rollback, retry, and concurrency suite. Every review-unit head compiles and passes its focused tests independently.

@github-actions

github-actions Bot commented Jul 27, 2026

Copy link
Copy Markdown

Code Coverage Report

Overall Project 68.12% +0.52% 🟢
Files changed 82.69% 🟢

Module Coverage
aliyun 1.72% 🔴
api 48.1% 🟢
authorization-common 85.96% 🟢
aws 42.04% 🟢
azure 2.47% 🔴
catalog-common 9.92% 🔴
catalog-fileset 79.74% 🟢
catalog-glue 66.91% 🟢
catalog-hive 79.4% 🟢
catalog-jdbc-common 45.7% 🟢
catalog-jdbc-doris 81.8% 🟢
catalog-jdbc-mysql 79.33% 🟢
catalog-jdbc-postgresql 83.39% 🟢
catalog-jdbc-starrocks 79.16% 🟢
catalog-kafka 77.01% 🟢
catalog-lakehouse-generic 59.18% 🟢
catalog-lakehouse-hudi 79.1% 🟢
catalog-lakehouse-iceberg 85.86% 🟢
catalog-lakehouse-paimon 84.23% 🟢
catalog-model 77.72% 🟢
cli 44.5% 🟢
client-java 78.27% 🟢
common 52.07% 🟢
core 82.79% -0.06% 🟢
filesystem-hadoop3 77.28% 🟢
flink 0.0% 🔴
flink-common 48.65% 🟢
flink-runtime 0.0% 🔴
gcp 14.12% 🔴
hadoop-auth 68.0% 🟢
hadoop-common 12.7% 🔴
hive-metastore-common 53.4% 🟢
iceberg-common 65.01% +10.26% 🟢
iceberg-rest-server 77.23% +1.13% 🟢
idp-basic 86.02% 🟢
integration-test-common 0.0% 🔴
jobs 66.17% 🟢
lance-common 20.67% 🔴
lance-rest-server 64.23% 🟢
lineage 53.02% 🟢
optimizer 83.24% 🟢
optimizer-api 21.95% 🔴
server 85.89% 🟢
server-common 76.31% -0.03% 🟢
spark 28.57% 🔴
spark-common 46.01% 🟢
tencent 69.84% 🟢
trino-connector 40.29% 🟢
Files
Module File Coverage
core DefaultMapperPackageProvider.java 100.0% 🟢
TableMetaPostgreSQLProvider.java 100.0% 🟢
EntityDeletionPO.java 100.0% 🟢
TableDeletionEntryPO.java 100.0% 🟢
EntityDeletionService.java 100.0% 🟢
POConverters.java 88.28% 🟢
TableEntityCacheChangeListener.java 81.25% 🟢
EntityDeletionSQLProvider.java 80.0% 🟢
TablePO.java 72.34% 🟢
TableMetaBaseSQLProvider.java 70.0% 🟢
RelationalEntityStore.java 65.33% 🟢
TableDeletionService.java 58.95% 🔴
SupportsEntityCacheInvalidation.java 0.0% 🔴
EntityDeletionMapper.java 0.0% 🔴
TableDeletionMapper.java 0.0% 🔴
iceberg-common IcebergConfig.java 100.0% 🟢
iceberg-rest-server IcebergDeletedTable.java 100.0% 🟢
IcebergDeletedTableMetadata.java 100.0% 🟢
IcebergDeletedTablesResponse.java 100.0% 🟢
IcebergDeletionAction.java 100.0% 🟢
IcebergDeletionAuthorization.java 100.0% 🟢
IcebergDeletionException.java 100.0% 🟢
IcebergRetainedTableDeletion.java 100.0% 🟢
IcebergUndropRequest.java 100.0% 🟢
IcebergNamespaceOperationExecutor.java 100.0% 🟢
IcebergTableOperationExecutor.java 98.41% 🟢
IcebergRESTServerContext.java 96.3% 🟢
IcebergDeletionResponses.java 95.24% 🟢
IcebergTableEventDispatcher.java 94.44% 🟢
IcebergDeletionETags.java 92.59% 🟢
IcebergRESTAuthInterceptionService.java 90.0% 🟢
IcebergTableDeletionLifecycle.java 88.16% 🟢
IcebergTableOperations.java 85.95% 🟢
IcebergDeletionManagementOperations.java 84.78% 🟢
IcebergTableHookDispatcher.java 81.0% 🟢
IcebergTableCacheInvalidator.java 76.47% 🟢
IcebergMetadataAuthorizationMethodInterceptor.java 73.21% 🟢
LoadTableAuthzHandler.java 59.62% 🔴
RESTService.java 0.0% 🔴
IcebergTableOperationDispatcher.java 0.0% 🔴
server-common AuthorizationExpressionConstants.java 0.0% 🔴

@nevzheng
nevzheng force-pushed the codex/iceberg-rest-delete-20-03-undrop branch 3 times, most recently from 7d521af to fbf5c70 Compare July 28, 2026 03:09
@nevzheng
nevzheng marked this pull request as ready for review July 28, 2026 03:15
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.

1 participant