nevzheng opened a new issue, #14261: URL: https://github.com/apache/gravitino/issues/14261
### Version main branch ### Describe what's wrong Iceberg REST tables and views carry no Gravitino id in their properties. For such objects, the core import treats any entity stored under the name as already imported and keeps its id (`TableOperationDispatcher` and `ViewOperationDispatcher`, the "not created by Gravitino" case). The Iceberg REST create hooks import straight after the backend create and never check for a leftover entity (`IcebergTableHookDispatcher#importTableAndSetOwner`, `IcebergViewHookDispatcher#createView`). `IcebergNamespaceHookDispatcher#registerTable` and `#registerView` go further: when an entity exists, they skip the import and keep it, owner included. Leftover entities come from normal paths: a drop whose entity cleanup fails (logged at WARN and ignored), a rename whose entity update fails, a drop and recreate on two nodes, or a drop while the hooks are not installed. So a new table or view **inherits the old object's id, and with it the role grants, tags, policies and statistics bound to it.** Register also keeps the old owner. A successful backend create, or a register without overwrite, proves that no object had the name, so any entity under it is stale. ### Error message and/or stacktrace None. The create returns 200. The drop that left the entity logs `Failed to reconcile Gravitino table entity after the Iceberg backend operation succeeded` at WARN. ### How to reproduce 1. Run the Iceberg REST server in auxiliary mode with `gravitino.authorization.enable=true`. 2. Grant `SELECT_TABLE` on `s1.t1` to a role of user `u1`. 3. Drop `t1` through Iceberg REST while the entity store delete fails, so the entity stays. 4. As user `u2`, create a new `t1` through Iceberg REST. 5. As `u1`, load `s1.t1`. Expected: the new `t1` gets a new id, is owned by `u2`, and `u1` is denied. Actual: the new `t1` keeps the old id, so `u1` can read it. `registerTable` without overwrite, `createView` and `registerView` behave the same way. ### Additional context Proposed fix: after a successful backend create, staged-create commit, register without overwrite, or view create or register, delete any entity under the name (this cascades its bindings) and remove the plugin privileges for the name, then import. Keep register with overwrite as today. Keep the drop reconcile best-effort, but log a failure at ERROR. A follow-up in core could store the Iceberg table UUID at import and treat a mismatch as "not imported". -- This is an automated message from the Apache Git Service. To respond to the message, please log on to GitHub and use the URL above to go to the specific comment. To unsubscribe, e-mail: [email protected] For queries about this service, please contact Infrastructure at: [email protected]
