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

chengpan pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/kyuubi.git


The following commit(s) were added to refs/heads/master by this push:
     new 1af6647132 [KYUUBI #7068] Iceberg ranger support check branch and tag 
ddl
1af6647132 is described below

commit 1af6647132e43f80145764c27b149b70ae59a95c
Author: davidyuan <[email protected]>
AuthorDate: Thu May 29 13:04:43 2025 +0800

    [KYUUBI #7068] Iceberg ranger support check branch and tag ddl
    
    ### Why are the changes needed?
    
    Iceberg ranger check support branch and tag ddl
    
    ### How was this patch tested?
    
    - [x] create branch
    - [x] replace branch
    - [x] drop branch
    - [x] create tag
    - [x] replace tag
    - [x] drop tag
    
    issue #7068
    ### Was this patch authored or co-authored using generative AI tooling?
    
    Closes #7069 from davidyuan1223/iceberg_branch_check.
    
    Closes #7068
    
    d060a24e1 [davidyuan] update
    1e05018d1 [davidyuan] Merge branch 'master' into iceberg_branch_check
    be2684671 [davidyuan] update
    231ed3356 [davidyuan] sort spi file
    6d2a5bf20 [davidyuan] sort spi file
    bc21310cc [davidyuan] update
    52ca367f1 [davidyuan] update
    
    Authored-by: davidyuan <[email protected]>
    Signed-off-by: Cheng Pan <[email protected]>
---
 .../src/main/resources/table_command_spec.json     |  64 +++++++++++++
 .../plugin/spark/authz/gen/IcebergCommands.scala   |  24 +++++
 .../IcebergCatalogRangerSparkExtensionSuite.scala  | 102 +++++++++++++++++++++
 3 files changed, 190 insertions(+)

diff --git 
a/extensions/spark/kyuubi-spark-authz/src/main/resources/table_command_spec.json
 
b/extensions/spark/kyuubi-spark-authz/src/main/resources/table_command_spec.json
index be18ffbf4e..7ce5591525 100644
--- 
a/extensions/spark/kyuubi-spark-authz/src/main/resources/table_command_spec.json
+++ 
b/extensions/spark/kyuubi-spark-authz/src/main/resources/table_command_spec.json
@@ -1841,6 +1841,38 @@
   "opType" : "ALTERTABLE_PROPERTIES",
   "queryDescs" : [ ],
   "uriDescs" : [ ]
+}, {
+  "classname" : 
"org.apache.spark.sql.catalyst.plans.logical.CreateOrReplaceBranch",
+  "tableDescs" : [ {
+    "fieldName" : "table",
+    "fieldExtractor" : "ArrayBufferTableExtractor",
+    "columnDesc" : null,
+    "actionTypeDesc" : null,
+    "tableTypeDesc" : null,
+    "catalogDesc" : null,
+    "isInput" : false,
+    "setCurrentDatabaseIfMissing" : false,
+    "comment" : "Iceberg"
+  } ],
+  "opType" : "ALTERTABLE_PROPERTIES",
+  "queryDescs" : [ ],
+  "uriDescs" : [ ]
+}, {
+  "classname" : 
"org.apache.spark.sql.catalyst.plans.logical.CreateOrReplaceTag",
+  "tableDescs" : [ {
+    "fieldName" : "table",
+    "fieldExtractor" : "ArrayBufferTableExtractor",
+    "columnDesc" : null,
+    "actionTypeDesc" : null,
+    "tableTypeDesc" : null,
+    "catalogDesc" : null,
+    "isInput" : false,
+    "setCurrentDatabaseIfMissing" : false,
+    "comment" : "Iceberg"
+  } ],
+  "opType" : "ALTERTABLE_PROPERTIES",
+  "queryDescs" : [ ],
+  "uriDescs" : [ ]
 }, {
   "classname" : 
"org.apache.spark.sql.catalyst.plans.logical.DeleteFromIcebergTable",
   "tableDescs" : [ {
@@ -1862,6 +1894,22 @@
   "opType" : "QUERY",
   "queryDescs" : [ ],
   "uriDescs" : [ ]
+}, {
+  "classname" : "org.apache.spark.sql.catalyst.plans.logical.DropBranch",
+  "tableDescs" : [ {
+    "fieldName" : "table",
+    "fieldExtractor" : "ArrayBufferTableExtractor",
+    "columnDesc" : null,
+    "actionTypeDesc" : null,
+    "tableTypeDesc" : null,
+    "catalogDesc" : null,
+    "isInput" : false,
+    "setCurrentDatabaseIfMissing" : false,
+    "comment" : "Iceberg"
+  } ],
+  "opType" : "ALTERTABLE_PROPERTIES",
+  "queryDescs" : [ ],
+  "uriDescs" : [ ]
 }, {
   "classname" : 
"org.apache.spark.sql.catalyst.plans.logical.DropIdentifierFields",
   "tableDescs" : [ {
@@ -1894,6 +1942,22 @@
   "opType" : "ALTERTABLE_PROPERTIES",
   "queryDescs" : [ ],
   "uriDescs" : [ ]
+}, {
+  "classname" : "org.apache.spark.sql.catalyst.plans.logical.DropTag",
+  "tableDescs" : [ {
+    "fieldName" : "table",
+    "fieldExtractor" : "ArrayBufferTableExtractor",
+    "columnDesc" : null,
+    "actionTypeDesc" : null,
+    "tableTypeDesc" : null,
+    "catalogDesc" : null,
+    "isInput" : false,
+    "setCurrentDatabaseIfMissing" : false,
+    "comment" : "Iceberg"
+  } ],
+  "opType" : "ALTERTABLE_PROPERTIES",
+  "queryDescs" : [ ],
+  "uriDescs" : [ ]
 }, {
   "classname" : 
"org.apache.spark.sql.catalyst.plans.logical.MergeIntoIcebergTable",
   "tableDescs" : [ {
diff --git 
a/extensions/spark/kyuubi-spark-authz/src/test/scala/org/apache/kyuubi/plugin/spark/authz/gen/IcebergCommands.scala
 
b/extensions/spark/kyuubi-spark-authz/src/test/scala/org/apache/kyuubi/plugin/spark/authz/gen/IcebergCommands.scala
index 7594ae8069..2cb3930fb2 100644
--- 
a/extensions/spark/kyuubi-spark-authz/src/test/scala/org/apache/kyuubi/plugin/spark/authz/gen/IcebergCommands.scala
+++ 
b/extensions/spark/kyuubi-spark-authz/src/test/scala/org/apache/kyuubi/plugin/spark/authz/gen/IcebergCommands.scala
@@ -93,6 +93,26 @@ object IcebergCommands extends 
CommandSpecs[TableCommandSpec] {
     AddPartitionFiled.copy(cmd)
   }
 
+  val CreateOrReplaceBranch = {
+    val cmd = 
"org.apache.spark.sql.catalyst.plans.logical.CreateOrReplaceBranch"
+    AddPartitionFiled.copy(cmd)
+  }
+
+  val CreateOrReplaceTag = {
+    val cmd = "org.apache.spark.sql.catalyst.plans.logical.CreateOrReplaceTag"
+    AddPartitionFiled.copy(cmd)
+  }
+
+  val DropBranch = {
+    val cmd = "org.apache.spark.sql.catalyst.plans.logical.DropBranch"
+    AddPartitionFiled.copy(cmd)
+  }
+
+  val DropTag = {
+    val cmd = "org.apache.spark.sql.catalyst.plans.logical.DropTag"
+    AddPartitionFiled.copy(cmd)
+  }
+
   override def specs: Seq[TableCommandSpec] = Seq(
     CallProcedure,
     DeleteFromIcebergTable,
@@ -104,6 +124,10 @@ object IcebergCommands extends 
CommandSpecs[TableCommandSpec] {
     WriteDistributionAndOrdering,
     SetIdentifierFields,
     DropIdentifierFields,
+    CreateOrReplaceBranch,
+    CreateOrReplaceTag,
+    DropBranch,
+    DropTag,
     MergeIntoIcebergTable.copy(classname =
       
"org.apache.spark.sql.catalyst.plans.logical.UnresolvedMergeIntoIcebergTable"))
 }
diff --git 
a/extensions/spark/kyuubi-spark-authz/src/test/scala/org/apache/kyuubi/plugin/spark/authz/ranger/IcebergCatalogRangerSparkExtensionSuite.scala
 
b/extensions/spark/kyuubi-spark-authz/src/test/scala/org/apache/kyuubi/plugin/spark/authz/ranger/IcebergCatalogRangerSparkExtensionSuite.scala
index 9e780d4e3e..24345624b5 100644
--- 
a/extensions/spark/kyuubi-spark-authz/src/test/scala/org/apache/kyuubi/plugin/spark/authz/ranger/IcebergCatalogRangerSparkExtensionSuite.scala
+++ 
b/extensions/spark/kyuubi-spark-authz/src/test/scala/org/apache/kyuubi/plugin/spark/authz/ranger/IcebergCatalogRangerSparkExtensionSuite.scala
@@ -484,4 +484,106 @@ class IcebergCatalogRangerSparkExtensionSuite extends 
RangerSparkExtensionSuite
       doAs(admin, sql(dropIdentifierSql))
     }
   }
+
+  test("CREATE BRANCH for Iceberg") {
+    val table = s"$catalogV2.$namespace1.partitioned_table"
+    withCleanTmpResources(Seq((table, "table"))) {
+      doAs(
+        admin,
+        sql(
+          s"CREATE TABLE $table (id int NOT NULL, name string, city string) 
USING iceberg"))
+      doAs(admin, sql(s"INSERT INTO $table VALUES (1, 'test', 'city')"))
+      val createBranchSql = s"ALTER TABLE $table CREATE BRANCH test_branch"
+      interceptEndsWith[AccessControlException] {
+        doAs(someone, sql(createBranchSql))
+      }(s"does not have [alter] privilege on [$namespace1/partitioned_table]")
+      doAs(admin, sql(createBranchSql))
+    }
+  }
+
+  test("CREATE TAG for Iceberg") {
+    val table = s"$catalogV2.$namespace1.partitioned_table"
+    withCleanTmpResources(Seq((table, "table"))) {
+      doAs(
+        admin,
+        sql(
+          s"CREATE TABLE $table (id int NOT NULL, name string, city string) 
USING iceberg"))
+      doAs(admin, sql(s"INSERT INTO $table VALUES (1, 'test', 'city')"))
+      val createTagSql = s"ALTER TABLE $table CREATE TAG test_tag"
+      interceptEndsWith[AccessControlException] {
+        doAs(someone, sql(createTagSql))
+      }(s"does not have [alter] privilege on [$namespace1/partitioned_table]")
+      doAs(admin, sql(createTagSql))
+    }
+  }
+
+  test("REPLACE BRANCH for Iceberg") {
+    val table = s"$catalogV2.$namespace1.partitioned_table"
+    withCleanTmpResources(Seq((table, "table"))) {
+      doAs(
+        admin,
+        sql(
+          s"CREATE TABLE $table (id int NOT NULL, name string, city string) 
USING iceberg"))
+      doAs(admin, sql(s"INSERT INTO $table VALUES (1, 'test', 'city')"))
+      doAs(admin, sql(s"ALTER TABLE $table CREATE BRANCH test_branch"))
+      doAs(admin, sql(s"INSERT INTO $table VALUES (2, 'test2', 'city2')"))
+      val replaceBranchSql = s"ALTER TABLE $table REPLACE BRANCH test_branch"
+      interceptEndsWith[AccessControlException] {
+        doAs(someone, sql(replaceBranchSql))
+      }(s"does not have [alter] privilege on [$namespace1/partitioned_table]")
+      doAs(admin, sql(replaceBranchSql))
+    }
+  }
+
+  test("REPLACE TAG for Iceberg") {
+    val table = s"$catalogV2.$namespace1.partitioned_table"
+    withCleanTmpResources(Seq((table, "table"))) {
+      doAs(
+        admin,
+        sql(
+          s"CREATE TABLE $table (id int NOT NULL, name string, city string) 
USING iceberg"))
+      doAs(admin, sql(s"INSERT INTO $table VALUES (1, 'test', 'city')"))
+      doAs(admin, sql(s"ALTER TABLE $table CREATE TAG test_tag"))
+      doAs(admin, sql(s"INSERT INTO $table VALUES (2, 'test2', 'city2')"))
+      val replaceTagSql = s"ALTER TABLE $table REPLACE TAG test_tag"
+      interceptEndsWith[AccessControlException] {
+        doAs(someone, sql(replaceTagSql))
+      }(s"does not have [alter] privilege on [$namespace1/partitioned_table]")
+      doAs(admin, sql(replaceTagSql))
+    }
+  }
+
+  test("DROP BRANCH for Iceberg") {
+    val table = s"$catalogV2.$namespace1.partitioned_table"
+    withCleanTmpResources(Seq((table, "table"))) {
+      doAs(
+        admin,
+        sql(
+          s"CREATE TABLE $table (id int NOT NULL, name string, city string) 
USING iceberg"))
+      doAs(admin, sql(s"INSERT INTO $table VALUES (1, 'test', 'city')"))
+      doAs(admin, sql(s"ALTER TABLE $table CREATE BRANCH test_branch"))
+      val dropBranchSql = s"ALTER TABLE $table DROP BRANCH test_branch"
+      interceptEndsWith[AccessControlException] {
+        doAs(someone, sql(dropBranchSql))
+      }(s"does not have [alter] privilege on [$namespace1/partitioned_table]")
+      doAs(admin, sql(dropBranchSql))
+    }
+  }
+
+  test("DROP TAG for Iceberg") {
+    val table = s"$catalogV2.$namespace1.partitioned_table"
+    withCleanTmpResources(Seq((table, "table"))) {
+      doAs(
+        admin,
+        sql(
+          s"CREATE TABLE $table (id int NOT NULL, name string, city string) 
USING iceberg"))
+      doAs(admin, sql(s"INSERT INTO $table VALUES (1, 'test', 'city')"))
+      doAs(admin, sql(s"ALTER TABLE $table CREATE TAG test_tag"))
+      val dropTagSql = s"ALTER TABLE $table DROP TAG test_tag"
+      interceptEndsWith[AccessControlException] {
+        doAs(someone, sql(dropTagSql))
+      }(s"does not have [alter] privilege on [$namespace1/partitioned_table]")
+      doAs(admin, sql(dropTagSql))
+    }
+  }
 }

Reply via email to