danhuawang opened a new issue, #11296:
URL: https://github.com/apache/gravitino/issues/11296
### Version
main branch
### Describe what's wrong
When using the Gravitino REST API path to drop a parent schema that still
has child namespaces (e.g., dropping `parent` when `parent:child` exists), the
operation succeeds instead of failing. This violates the design specification
in `design-docs/iceberg-supported-nested-namespace.md` which states:
> Drop must fail when target namespace still contains child namespaces,
tables, or views.
> Users must delete children objects explicitly before dropping parent
namespace.
The root cause is that `IcebergCatalogOperations.dropSchema()` delegates
directly to the underlying Iceberg catalog's `dropNamespace()` without first
checking whether child namespaces exist. The underlying Iceberg `dropNamespace`
only checks if the target namespace itself directly contains tables — it does
not check for child namespaces. This is
catalog-backend-implementation-dependent behavior, and Gravitino should enforce
the hierarchical constraint at its own layer.
### Error message and/or stacktrace
No error is thrown — that is the bug. The expected behavior is a
`NonEmptySchemaException` (or equivalent) when child namespaces exist, but
instead `dropSchema` returns `true` silently.
Test failure demonstrating the issue:
```
org.opentest4j.AssertionFailedError: Expected java.lang.Exception to be
thrown, but nothing was thrown.
at org.junit.jupiter.api.AssertThrows.assertThrows(AssertThrows.java:71)
at org.apache.gravitino.integration.test.schema.TestHierarchicalSchemaIT
.testDropParentSchemaWithNonEmptyChildShouldFail(TestHierarchicalSchemaIT.java:411)
```
### How to reproduce
1. Use Gravitino main branch with an Iceberg catalog configured (any JDBC
backend).
2. Create a hierarchical schema structure via the Gravitino Java client:
```java
icebergCatalog.asSchemas().createSchema("parent", "comment", Map.of());
icebergCatalog.asSchemas().createSchema("parent:child", "comment",
Map.of());
```
3. Create a table in the child schema:
```java
icebergCatalog.asTableCatalog().createTable(
NameIdentifier.of("parent:child", "tbl"),
columns, "comment", Map.of());
```
4. Attempt to drop the parent schema:
```java
icebergCatalog.asSchemas().dropSchema("parent", false);
```
5. **Actual result**: `dropSchema` returns `true`, parent is deleted, child
namespace and its table become orphaned.
6. **Expected result**: `dropSchema` should throw `NonEmptySchemaException`
because `parent:child` still exists under `parent`.
### Additional context
**Affected code**:
`catalogs/catalog-lakehouse-iceberg/src/main/java/org/apache/gravitino/catalog/lakehouse/iceberg/IcebergCatalogOperations.java`,
method `dropSchema()` (line ~351).
**Design reference**: `design-docs/iceberg-supported-nested-namespace.md`
lines 244-245 and 288-289.
**Suggested fix**: Before delegating to
`icebergCatalogWrapper.dropNamespace()`, call `listNamespace(targetNamespace)`
to check if any child namespaces exist. If children are found, throw
`NonEmptySchemaException` to enforce the hierarchical constraint consistently
regardless of the underlying catalog backend behavior.
Note: The Iceberg REST server path
(`IcebergNamespaceHookDispatcher.dropNamespace`) has a similar gap — it also
delegates to the underlying catalog without pre-checking for child namespaces,
though it does handle post-drop cleanup of phantom ancestor entities.
--
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]