LuciferYang commented on code in PR #13527:
URL: https://github.com/apache/gravitino/pull/13527#discussion_r4115746573


##########
core/src/test/java/org/apache/gravitino/storage/relational/service/TestMetalakeMetaService.java:
##########
@@ -68,6 +74,72 @@ public class TestMetalakeMetaService extends TestJDBCBackend 
{
 
   private static final String METALAKE_NAME = "metalake_for_metalake_test";
 
+  @TestTemplate
+  public void testCascadeDeleteCleansSecurableObjectsAndTagRels() throws 
Exception {
+    BaseMetalake metalake = createAndInsertMakeLake(METALAKE_NAME);
+    long metalakeId = metalake.id();
+
+    CatalogEntity catalog = createAndInsertCatalog(METALAKE_NAME, 
"cascade_cat");
+
+    // A role with a securable object under this metalake.
+    backend.insert(
+        RoleEntity.builder()
+            .withId(RandomIdGenerator.INSTANCE.nextId())
+            .withName("cascade_role")
+            .withNamespace(Namespace.of(METALAKE_NAME, "system", "role"))
+            .withAuditInfo(AUDIT_INFO)
+            .withSecurableObjects(
+                Lists.newArrayList(
+                    SecurableObjects.ofCatalog(
+                        "cascade_cat", 
Lists.newArrayList(Privileges.UseCatalog.allow()))))
+            .build(),
+        false);
+
+    // A tag assigned to a metadata object under this metalake.
+    TagEntity tag =
+        TagEntity.builder()
+            .withId(RandomIdGenerator.INSTANCE.nextId())
+            .withName("cascade_tag")
+            .withNamespace(Namespace.of(METALAKE_NAME))
+            .withAuditInfo(AUDIT_INFO)
+            .build();
+    backend.insert(tag, false);
+    TagMetaService.getInstance()
+        .associateTagsWithMetadataObject(
+            catalog.nameIdentifier(),
+            catalog.type(),
+            new NameIdentifier[] {NameIdentifier.of(METALAKE_NAME, 
"cascade_tag")},
+            new NameIdentifier[0]);
+
+    // The metalake cascade tombstones roles and tags BEFORE the relation 
cleanups in
+    // one transaction; the relation cleanups must not filter on the parents' 
live rows.
+    Assertions.assertTrue(
+        backend.delete(metalake.nameIdentifier(), Entity.EntityType.METALAKE, 
true));

Review Comment:
   Done in b398b21f: the test now asserts one live row for each relation before 
the drop, so the post-drop zero assertions prove the cascade actually exercised 
both cleanup statements.



##########
core/src/test/java/org/apache/gravitino/storage/relational/service/TestMetalakeMetaService.java:
##########
@@ -68,6 +74,72 @@ public class TestMetalakeMetaService extends TestJDBCBackend 
{
 
   private static final String METALAKE_NAME = "metalake_for_metalake_test";
 
+  @TestTemplate
+  public void testCascadeDeleteCleansSecurableObjectsAndTagRels() throws 
Exception {
+    BaseMetalake metalake = createAndInsertMakeLake(METALAKE_NAME);
+    long metalakeId = metalake.id();
+
+    CatalogEntity catalog = createAndInsertCatalog(METALAKE_NAME, 
"cascade_cat");
+
+    // A role with a securable object under this metalake.
+    backend.insert(
+        RoleEntity.builder()
+            .withId(RandomIdGenerator.INSTANCE.nextId())
+            .withName("cascade_role")
+            .withNamespace(Namespace.of(METALAKE_NAME, "system", "role"))
+            .withAuditInfo(AUDIT_INFO)
+            .withSecurableObjects(
+                Lists.newArrayList(
+                    SecurableObjects.ofCatalog(
+                        "cascade_cat", 
Lists.newArrayList(Privileges.UseCatalog.allow()))))
+            .build(),
+        false);
+
+    // A tag assigned to a metadata object under this metalake.
+    TagEntity tag =
+        TagEntity.builder()
+            .withId(RandomIdGenerator.INSTANCE.nextId())
+            .withName("cascade_tag")
+            .withNamespace(Namespace.of(METALAKE_NAME))
+            .withAuditInfo(AUDIT_INFO)
+            .build();
+    backend.insert(tag, false);
+    TagMetaService.getInstance()
+        .associateTagsWithMetadataObject(
+            catalog.nameIdentifier(),
+            catalog.type(),
+            new NameIdentifier[] {NameIdentifier.of(METALAKE_NAME, 
"cascade_tag")},
+            new NameIdentifier[0]);
+
+    // The metalake cascade tombstones roles and tags BEFORE the relation 
cleanups in
+    // one transaction; the relation cleanups must not filter on the parents' 
live rows.
+    Assertions.assertTrue(
+        backend.delete(metalake.nameIdentifier(), Entity.EntityType.METALAKE, 
true));
+
+    Assertions.assertEquals(
+        0, liveRows("role_meta_securable_object", "role_id IN (SELECT role_id 
FROM role_meta)"));
+    Assertions.assertEquals(
+        0,
+        liveRows(
+            "tag_relation_meta",
+            "tag_id IN (SELECT tag_id FROM tag_meta WHERE metalake_id = " + 
metalakeId + ")"));
+  }
+
+  private long liveRows(String table, String scope) throws Exception {
+    try (java.sql.Connection connection =
+        SqlSessionFactoryHelper.getInstance()
+            .getSqlSessionFactory()
+            .openSession(true)
+            .getConnection()) {

Review Comment:
   Done in b398b21f: `liveRows` now keeps the `SqlSession` in the 
try-with-resources alongside the statement and result set, so the session is 
closed with them.



##########
core/src/test/java/org/apache/gravitino/storage/relational/service/TestMetalakeMetaService.java:
##########
@@ -68,6 +74,72 @@ public class TestMetalakeMetaService extends TestJDBCBackend 
{
 
   private static final String METALAKE_NAME = "metalake_for_metalake_test";
 
+  @TestTemplate
+  public void testCascadeDeleteCleansSecurableObjectsAndTagRels() throws 
Exception {
+    BaseMetalake metalake = createAndInsertMakeLake(METALAKE_NAME);
+    long metalakeId = metalake.id();
+
+    CatalogEntity catalog = createAndInsertCatalog(METALAKE_NAME, 
"cascade_cat");
+
+    // A role with a securable object under this metalake.
+    backend.insert(
+        RoleEntity.builder()
+            .withId(RandomIdGenerator.INSTANCE.nextId())
+            .withName("cascade_role")
+            .withNamespace(Namespace.of(METALAKE_NAME, "system", "role"))
+            .withAuditInfo(AUDIT_INFO)
+            .withSecurableObjects(
+                Lists.newArrayList(
+                    SecurableObjects.ofCatalog(
+                        "cascade_cat", 
Lists.newArrayList(Privileges.UseCatalog.allow()))))
+            .build(),
+        false);
+
+    // A tag assigned to a metadata object under this metalake.
+    TagEntity tag =
+        TagEntity.builder()
+            .withId(RandomIdGenerator.INSTANCE.nextId())
+            .withName("cascade_tag")
+            .withNamespace(Namespace.of(METALAKE_NAME))
+            .withAuditInfo(AUDIT_INFO)
+            .build();
+    backend.insert(tag, false);
+    TagMetaService.getInstance()
+        .associateTagsWithMetadataObject(
+            catalog.nameIdentifier(),
+            catalog.type(),
+            new NameIdentifier[] {NameIdentifier.of(METALAKE_NAME, 
"cascade_tag")},
+            new NameIdentifier[0]);
+
+    // The metalake cascade tombstones roles and tags BEFORE the relation 
cleanups in
+    // one transaction; the relation cleanups must not filter on the parents' 
live rows.
+    Assertions.assertTrue(
+        backend.delete(metalake.nameIdentifier(), Entity.EntityType.METALAKE, 
true));
+
+    Assertions.assertEquals(
+        0, liveRows("role_meta_securable_object", "role_id IN (SELECT role_id 
FROM role_meta)"));
+    Assertions.assertEquals(
+        0,
+        liveRows(
+            "tag_relation_meta",
+            "tag_id IN (SELECT tag_id FROM tag_meta WHERE metalake_id = " + 
metalakeId + ")"));
+  }
+
+  private long liveRows(String table, String scope) throws Exception {
+    try (java.sql.Connection connection =
+        SqlSessionFactoryHelper.getInstance()
+            .getSqlSessionFactory()
+            .openSession(true)
+            .getConnection()) {
+      try (java.sql.Statement st = connection.createStatement()) {
+        java.sql.ResultSet rs =
+            st.executeQuery("SELECT COUNT(*) FROM " + table + " WHERE 
deleted_at = 0 AND " + scope);

Review Comment:
   Done in b398b21f: `liveRows` uses the existing `Statement` and `ResultSet` 
imports instead of fully qualified names.



-- 
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