This is an automated email from the ASF dual-hosted git repository.
singhpk234 pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/iceberg.git
The following commit(s) were added to refs/heads/main by this push:
new ef077f4588 Core: Fix JdbcCatalog & InMemoryCatalog to prevent dropping
parent namespaces with children (#16061)
ef077f4588 is described below
commit ef077f45881d7700160eedfd4c129e64bd3aa93c
Author: sagib-sqream <[email protected]>
AuthorDate: Wed May 6 17:49:17 2026 +0300
Core: Fix JdbcCatalog & InMemoryCatalog to prevent dropping parent
namespaces with children (#16061)
* Fix for issue #16060
* formatting
* formatting
* CR fix
* Enforce child namespaces scan also on InMemoryCatalog
* empry commit for triggering failed CI again (failed on zizmor job)
* CR requirements
---
.../apache/iceberg/inmemory/InMemoryCatalog.java | 7 ++++
.../java/org/apache/iceberg/jdbc/JdbcCatalog.java | 7 ++++
.../org/apache/iceberg/catalog/CatalogTests.java | 38 ++++++++++++++++++++++
.../iceberg/inmemory/TestInMemoryCatalog.java | 5 +++
.../org/apache/iceberg/jdbc/TestJdbcCatalog.java | 4 +--
5 files changed, 59 insertions(+), 2 deletions(-)
diff --git
a/core/src/main/java/org/apache/iceberg/inmemory/InMemoryCatalog.java
b/core/src/main/java/org/apache/iceberg/inmemory/InMemoryCatalog.java
index 55c982f3d6..2234d418de 100644
--- a/core/src/main/java/org/apache/iceberg/inmemory/InMemoryCatalog.java
+++ b/core/src/main/java/org/apache/iceberg/inmemory/InMemoryCatalog.java
@@ -219,6 +219,13 @@ public class InMemoryCatalog extends
BaseMetastoreViewCatalog
return false;
}
+ List<Namespace> childNamespaces = listNamespaces(namespace);
+ if (!childNamespaces.isEmpty()) {
+ throw new NamespaceNotEmptyException(
+ "Namespace %s is not empty. Contains %d child namespace(s).",
+ namespace, childNamespaces.size());
+ }
+
List<TableIdentifier> tableIdentifiers = listTables(namespace);
if (!tableIdentifiers.isEmpty()) {
throw new NamespaceNotEmptyException(
diff --git a/core/src/main/java/org/apache/iceberg/jdbc/JdbcCatalog.java
b/core/src/main/java/org/apache/iceberg/jdbc/JdbcCatalog.java
index 007821da39..2d24e5598a 100644
--- a/core/src/main/java/org/apache/iceberg/jdbc/JdbcCatalog.java
+++ b/core/src/main/java/org/apache/iceberg/jdbc/JdbcCatalog.java
@@ -543,6 +543,13 @@ public class JdbcCatalog extends BaseMetastoreViewCatalog
return false;
}
+ List<Namespace> childNamespaces = listNamespaces(namespace);
+ if (childNamespaces != null && !childNamespaces.isEmpty()) {
+ throw new NamespaceNotEmptyException(
+ "Namespace %s is not empty. Contains %d child namespace(s).",
+ namespace, childNamespaces.size());
+ }
+
List<TableIdentifier> tableIdentifiers = listTables(namespace);
if (tableIdentifiers != null && !tableIdentifiers.isEmpty()) {
throw new NamespaceNotEmptyException(
diff --git a/core/src/test/java/org/apache/iceberg/catalog/CatalogTests.java
b/core/src/test/java/org/apache/iceberg/catalog/CatalogTests.java
index 9053f21ea1..8997cf15a0 100644
--- a/core/src/test/java/org/apache/iceberg/catalog/CatalogTests.java
+++ b/core/src/test/java/org/apache/iceberg/catalog/CatalogTests.java
@@ -431,6 +431,44 @@ public abstract class CatalogTests<C extends Catalog &
SupportsNamespaces> {
assertThat(catalog.namespaceExists(NS)).as("Namespace should not
exist").isFalse();
}
+ @Test
+ public void testDropNamespaceWithNestedNamespace() {
+ assumeThat(supportsNestedNamespaces())
+ .as("Only valid when the catalog supports nested namespaces")
+ .isTrue();
+
+ C catalog = catalog();
+
+ Namespace parent = Namespace.of("parent");
+ Namespace nested = Namespace.of("parent", "child");
+
+ assertThat(catalog.namespaceExists(parent)).as("Parent namespace should
not exist").isFalse();
+ assertThat(catalog.namespaceExists(nested)).as("Nested namespace should
not exist").isFalse();
+
+ catalog.createNamespace(parent);
+ catalog.createNamespace(nested);
+
+ assertThat(catalog.namespaceExists(parent)).as("Parent namespace should
exist").isTrue();
+ assertThat(catalog.namespaceExists(nested)).as("Nested namespace should
exist").isTrue();
+
+ assertThatThrownBy(() -> catalog.dropNamespace(parent))
+ .isInstanceOf(NamespaceNotEmptyException.class)
+ .hasMessageContaining("is not empty");
+
+ assertThat(catalog.namespaceExists(parent)).as("Parent namespace should
still exist").isTrue();
+ assertThat(catalog.namespaceExists(nested)).as("Nested namespace should
still exist").isTrue();
+
+ assertThat(catalog.dropNamespace(nested))
+ .as("Dropping an existing nested namespace should return true")
+ .isTrue();
+ assertThat(catalog.namespaceExists(nested)).as("Nested namespace should
not exist").isFalse();
+
+ assertThat(catalog.dropNamespace(parent))
+ .as("Dropping an existing namespace should return true")
+ .isTrue();
+ assertThat(catalog.namespaceExists(parent)).as("Parent namespace should
not exist").isFalse();
+ }
+
@Test
public void testListNamespaces() {
C catalog = catalog();
diff --git
a/core/src/test/java/org/apache/iceberg/inmemory/TestInMemoryCatalog.java
b/core/src/test/java/org/apache/iceberg/inmemory/TestInMemoryCatalog.java
index c2c683e7d8..827450d4a3 100644
--- a/core/src/test/java/org/apache/iceberg/inmemory/TestInMemoryCatalog.java
+++ b/core/src/test/java/org/apache/iceberg/inmemory/TestInMemoryCatalog.java
@@ -82,6 +82,11 @@ public class TestInMemoryCatalog extends
CatalogTests<InMemoryCatalog> {
return true;
}
+ @Override
+ protected boolean supportsNestedNamespaces() {
+ return true;
+ }
+
@Test
@Override
public void testLoadTableWithMissingMetadataFile(@TempDir Path tempDir)
throws IOException {
diff --git a/core/src/test/java/org/apache/iceberg/jdbc/TestJdbcCatalog.java
b/core/src/test/java/org/apache/iceberg/jdbc/TestJdbcCatalog.java
index 310d918849..ff0af5c563 100644
--- a/core/src/test/java/org/apache/iceberg/jdbc/TestJdbcCatalog.java
+++ b/core/src/test/java/org/apache/iceberg/jdbc/TestJdbcCatalog.java
@@ -852,11 +852,11 @@ public class TestJdbcCatalog extends
CatalogTests<JdbcCatalog> {
assertThatThrownBy(() -> catalog.dropNamespace(tbl2.namespace()))
.isInstanceOf(NamespaceNotEmptyException.class)
- .hasMessage("Namespace db.ns1 is not empty. Contains 1 table(s).");
+ .hasMessage("Namespace db.ns1 is not empty. Contains 1 child
namespace(s).");
assertThatThrownBy(() -> catalog.dropNamespace(tbl4.namespace()))
.isInstanceOf(NamespaceNotEmptyException.class)
- .hasMessage("Namespace db is not empty. Contains 1 table(s).");
+ .hasMessage("Namespace db is not empty. Contains 2 child
namespace(s).");
}
@Test