This is an automated email from the ASF dual-hosted git repository.
mchades pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/gravitino.git
The following commit(s) were added to refs/heads/main by this push:
new 51e9831f7c [#9078] Improvement(core):In SchemaMetaService.java block
non-cascading schema deletions when topics still exist (#9465)
51e9831f7c is described below
commit 51e9831f7c2b9472391781f1d78e86d288f70638
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);
+ }
}