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


##########
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:
   The post-cascade assertions can pass even when either setup path failed to 
create its relation, because `liveRows` would already be zero. Assert one 
active row for each relation before deleting the metalake so this regression 
test proves it 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:
   This opens a MyBatis `SqlSession` only to obtain its connection, but the 
session itself is never closed; closing the connection does not release the 
session's resources. Keep the `SqlSession` in the try-with-resources alongside 
the connection (and use the existing imports).



##########
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:
   `Statement` and `ResultSet` are already imported in this file, so the new 
fully qualified names are inconsistent with the repository's standard-import 
rule. Use the existing imports in this helper.



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