This is an automated email from the ASF dual-hosted git repository.

yuqi4733 pushed a commit to branch internal-main
in repository https://gitbox.apache.org/repos/asf/gravitino.git

commit d3c0e7d5f32914d86edc0d6a59022e421fb0586c
Author: Salmane Khalili <[email protected]>
AuthorDate: Fri Dec 12 10:39:16 2025 +0100

    [#9078] Improvement(core):In SchemaMetaService.java block non-cascading 
schema deletions when topics still exist (#9465)
    
    ## What changes were proposed in this pull request?
    
    This PR implements a check to prevent the deletion of non-cascading
    schemas that still contain topic metadata.
    
    ## Why are the changes needed?
    
    Currently, schema deletion checks for dependant tables, filesets and
    models. If the schema contains topics, the deletion proceeds regardless.
    Leaving orphaned topic metadata in the database.
    This fix ensures a NonEmptyEntityException is thrown if any active
    topics are found within the schema. This matches previous checks for
    other subschema entities.
    
    The fix was implemeted through a check in the non cascading branch of
    deleteSchema method in SchemaMetaService.java.
    
    Fix: #9078
    
    ## Does this PR introduce any user-facing change?
    
    Nothing more than an error message.
    
    ## How was this patch tested?
    Added testDeleteSchemaNonCascadingFailsWhenTopicExists, to
    TestSchemaMetaService.java
    ./gradlew :core:test
    
    All tests passed.
    
    [#9078] Improvement(core):In SchemaMetaService.java block non-cascading
    schema deletions when topics still exist
---
 .../relational/service/SchemaMetaService.java      | 13 ++++++++
 .../relational/service/TestSchemaMetaService.java  | 38 ++++++++++++++++++++++
 2 files changed, 51 insertions(+)

diff --git 
a/core/src/main/java/org/apache/gravitino/storage/relational/service/SchemaMetaService.java
 
b/core/src/main/java/org/apache/gravitino/storage/relational/service/SchemaMetaService.java
index 44e2e58c7c..c6eb4becf3 100644
--- 
a/core/src/main/java/org/apache/gravitino/storage/relational/service/SchemaMetaService.java
+++ 
b/core/src/main/java/org/apache/gravitino/storage/relational/service/SchemaMetaService.java
@@ -37,6 +37,7 @@ import org.apache.gravitino.meta.ModelEntity;
 import org.apache.gravitino.meta.NamespacedEntityId;
 import org.apache.gravitino.meta.SchemaEntity;
 import org.apache.gravitino.meta.TableEntity;
+import org.apache.gravitino.meta.TopicEntity;
 import org.apache.gravitino.metrics.Monitored;
 import org.apache.gravitino.storage.relational.helper.SchemaIds;
 import org.apache.gravitino.storage.relational.mapper.FilesetMetaMapper;
@@ -327,6 +328,18 @@ public class SchemaMetaService {
             "Entity %s has sub-entities, you should remove sub-entities 
first", identifier);
       }
 
+      List<TopicEntity> topicEntities =
+          TopicMetaService.getInstance()
+              .listTopicsByNamespace(
+                  NamespaceUtil.ofTopic(
+                      identifier.namespace().level(0),
+                      identifier.namespace().level(1),
+                      schemaName));
+      if (!topicEntities.isEmpty()) {
+        throw new NonEmptyEntityException(
+            "Entity %s has sub-entities, you should remove sub-entities 
first", identifier);
+      }
+
       SessionUtils.doMultipleWithCommit(
           () ->
               SessionUtils.doWithoutCommit(
diff --git 
a/core/src/test/java/org/apache/gravitino/storage/relational/service/TestSchemaMetaService.java
 
b/core/src/test/java/org/apache/gravitino/storage/relational/service/TestSchemaMetaService.java
index 799a21432f..5e9a345ee3 100644
--- 
a/core/src/test/java/org/apache/gravitino/storage/relational/service/TestSchemaMetaService.java
+++ 
b/core/src/test/java/org/apache/gravitino/storage/relational/service/TestSchemaMetaService.java
@@ -27,7 +27,9 @@ import java.time.Instant;
 import java.util.List;
 import org.apache.gravitino.Entity;
 import org.apache.gravitino.EntityAlreadyExistsException;
+import org.apache.gravitino.exceptions.NonEmptyEntityException;
 import org.apache.gravitino.meta.SchemaEntity;
+import org.apache.gravitino.meta.TopicEntity;
 import org.apache.gravitino.storage.RandomIdGenerator;
 import org.apache.gravitino.storage.relational.TestJDBCBackend;
 import org.apache.gravitino.utils.NameIdentifierUtil;
@@ -167,4 +169,40 @@ public class TestSchemaMetaService extends TestJDBCBackend 
{
     }
     assertFalse(legacyRecordExistsInDB(schema.id(), Entity.EntityType.SCHEMA));
   }
+
+  @TestTemplate
+  public void testDeleteSchemlaaNonCascadingFailsWhenTopicExists() throws 
IOException {
+
+    createAndInsertMakeLake(metalakeName);
+    createAndInsertCatalog(metalakeName, catalogName);
+
+    SchemaMetaService schemaMetaService = SchemaMetaService.getInstance();
+    TopicMetaService topicMetaService = TopicMetaService.getInstance();
+
+    final String schemaName = "schema_with_topic";
+    SchemaEntity schema =
+        createSchemaEntity(
+            RandomIdGenerator.INSTANCE.nextId(),
+            NamespaceUtil.ofSchema(metalakeName, catalogName),
+            schemaName,
+            AUDIT_INFO);
+    schemaMetaService.insertSchema(schema, false);
+
+    final String topicName = "test_topic_dependency";
+    TopicEntity topic =
+        createTopicEntity(
+            RandomIdGenerator.INSTANCE.nextId(),
+            NamespaceUtil.ofTopic(metalakeName, catalogName, schemaName),
+            topicName,
+            AUDIT_INFO);
+    topicMetaService.insertTopic(topic, false);
+
+    Assertions.assertThrows(
+        NonEmptyEntityException.class,
+        () -> schemaMetaService.deleteSchema(schema.nameIdentifier(), false),
+        "Non-cascading delete must fail when dependent topics exist.");
+
+    topicMetaService.deleteTopic(topic.nameIdentifier());
+    schemaMetaService.deleteSchema(schema.nameIdentifier(), false);
+  }
 }

Reply via email to