markhoerth opened a new issue, #10803:
URL: https://github.com/apache/gravitino/issues/10803
### Version
main branch
### Describe what's wrong
When `gravitino.authorization.enable = true`, Trino `CREATE TABLE` against
the IRC fails with `NoSuchTableException`. The root cause is in
`IcebergTableHookDispatcher.createTable()`, which unconditionally calls
`importTable()` after the table is created in the backing catalog. When the
Iceberg client sends `stageCreate=true` (which Trino does by default for all
CREATE TABLE operations), the table is staged but not committed — it does not
exist in the backing catalog yet. The `importTable()` call then attempts to
`loadTable()` through the full catalog dispatcher chain, which fails because
the staged table cannot be found.
Without authorization enabled, the `IcebergTableHookDispatcher` is not in
the execution path and staged creates succeed.
### Error message and/or stacktrace
```
org.apache.gravitino.exceptions.NoSuchTableException: Iceberg table does not
exist: staged_repro
at
org.apache.gravitino.catalog.lakehouse.iceberg.IcebergCatalogOperations.loadTable(IcebergCatalogOperations.java:393)
at
org.apache.gravitino.catalog.TableOperationDispatcher.lambda$internalLoadTable$20(TableOperationDispatcher.java:502)
at
org.apache.gravitino.catalog.CatalogManager$CatalogWrapper.lambda$doWithTableOps$1(CatalogManager.java:153)
at
org.apache.gravitino.utils.IsolatedClassLoader.withClassLoader(IsolatedClassLoader.java:86)
...
at
org.apache.gravitino.catalog.TableOperationDispatcher.loadTable(TableOperationDispatcher.java:117)
at
org.apache.gravitino.hook.TableHookDispatcher.loadTable(TableHookDispatcher.java:63)
at
org.apache.gravitino.catalog.TableNormalizeDispatcher.loadTable(TableNormalizeDispatcher.java:63)
at
org.apache.gravitino.listener.TableEventDispatcher.loadTable(TableEventDispatcher.java:99)
at
org.apache.gravitino.iceberg.service.dispatcher.IcebergTableHookDispatcher.importTable(IcebergTableHookDispatcher.java:185)
at
org.apache.gravitino.iceberg.service.dispatcher.IcebergTableHookDispatcher.createTable(IcebergTableHookDispatcher.java:60)
```
### How to reproduce
1. Deploy Gravitino 1.2.0 full server with IRC as auxiliary service using
`dynamic-config-provider`
2. Enable authorization: `gravitino.authorization.enable = true`
3. Create a metalake and lakehouse-iceberg catalog
4. Connect Trino to the IRC endpoint as a REST catalog
5. Run: `CREATE TABLE irc_catalog.test_ns.my_table (id BIGINT, data
VARCHAR);`
Result: `Query failed: Server error: NoSuchTableException: Iceberg table
does not exist: my_table`
### Additional context
**Root Cause**
In `IcebergTableHookDispatcher.java`, the `createTable` method (line 60)
unconditionally calls `importTable()` after creating the table:
```java
LoadTableResponse response = dispatcher.createTable(context, namespace,
createTableRequest);
importTable(context.catalogName(), namespace, createTableRequest.name());
```
For staged creates, the table is not yet committed in the backing catalog.
The `importTable` → `loadTable` call fails with `NoSuchTableException`.
**Proposed Fix**
In `createTable()`, check `createTableRequest.stageCreate()` and skip the
import. Defer the import to `updateTable()` when the commit arrives with an
`AssertTableDoesNotExist` requirement:
```java
@Override
public LoadTableResponse createTable(
IcebergRequestContext context, Namespace namespace, CreateTableRequest
createTableRequest) {
LoadTableResponse response = dispatcher.createTable(context, namespace,
createTableRequest);
if (!createTableRequest.stageCreate()) {
importTable(context.catalogName(), namespace, createTableRequest.name());
IcebergOwnershipUtils.setTableOwner(...);
}
return response;
}
@Override
public LoadTableResponse updateTable(
IcebergRequestContext context, TableIdentifier tableIdentifier,
UpdateTableRequest updateTableRequest) {
LoadTableResponse response = dispatcher.updateTable(context,
tableIdentifier, updateTableRequest);
if (updateTableRequest.requirements().stream()
.anyMatch(r -> r instanceof
UpdateRequirement.AssertTableDoesNotExist)) {
importTable(context.catalogName(), tableIdentifier.namespace(),
tableIdentifier.name());
IcebergOwnershipUtils.setTableOwner(...);
}
return response;
}
```
**Environment**
- Gravitino: 1.2.0
- Trino: 469 (also reproduced by customer on Trino 479)
- IRC config: dynamic-config-provider, JDBC catalog backend, S3 storage
- Authorization: enabled (simple auth with serviceAdmins)
**Notes**
- This bug does NOT reproduce with `gravitino.authorization.enable = false`
because the `IcebergTableHookDispatcher` is not wired into the execution path
- This bug does NOT reproduce with the standalone IRC server
(`apache/gravitino-iceberg-rest`) because it lacks the dispatcher layer
- Trino sends `stageCreate=true` for ALL `CREATE TABLE` statements, making
this a complete blocker for Trino + IRC + authorization
- CTAS operations (issue #10750) are likely affected by the same root cause
--
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]