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]

Reply via email to