Skip to content

Commit

Permalink
[KYUUBI #5359] [AUTHZ] Support Create Table Commands for Hudi
Browse files Browse the repository at this point in the history
### _Why are the changes needed?_
To close #5359. Kyuubi authz support hudi create table commands

- [CreateHoodieTableCommand](https://github.com/apache/hudi/blob/master/hudi-spark-datasource/hudi-spark-common/src/main/scala/org/apache/spark/sql/hudi/command/CreateHoodieTableCommand.scala): https://hudi.apache.org/docs/sql_ddl#create-table
- [CreateHoodieTableAsSelectCommand](https://github.com/apache/hudi/blob/master/hudi-spark-datasource/hudi-spark-common/src/main/scala/org/apache/spark/sql/hudi/command/CreateHoodieTableCommand.scala): https://hudi.apache.org/docs/sql_ddl#create-table-as-select-ctas
- [CreateHoodieTableLikeCommand](https://github.com/apache/hudi/blob/master/hudi-spark-datasource/hudi-spark-common/src/main/scala/org/apache/spark/sql/hudi/command/CreateHoodieTableLikeCommand.scala): https://github.com/apache/hudi/blob/master/hudi-spark-datasource/hudi-spark-common/src/main/scala/org/apache/spark/sql/hudi/command/CreateHoodieTableLikeCommand.scala

### _How was this patch tested?_
- [x] Add some test cases that check the changes thoroughly including negative and positive cases if possible

- [ ] Add screenshots for manual tests if appropriate

- [ ] [Run test](https://kyuubi.readthedocs.io/en/master/contributing/code/testing.html#running-tests) locally before make a pull request

### _Was this patch authored or co-authored using generative AI tooling?_
No

Closes #5439 from AngersZhuuuu/KYUUBI-5359.

Closes #5359

d070109 [Angerszhuuuu] Update HudiCatalogRangerSparkExtensionSuite.scala
f0bc79a [Angerszhuuuu] [KYUUBI #5284] Support Hudi Creeate Table Command in Authz

Authored-by: Angerszhuuuu <[email protected]>
Signed-off-by: Cheng Pan <[email protected]>
  • Loading branch information
AngersZhuuuu authored and pan3793 committed Oct 17, 2023
1 parent f714327 commit f6ccc4d
Show file tree
Hide file tree
Showing 3 changed files with 163 additions and 1 deletion.
Original file line number Diff line number Diff line change
Expand Up @@ -1513,6 +1513,60 @@
} ],
"opType" : "ALTERTABLE_PROPERTIES",
"queryDescs" : [ ]
}, {
"classname" : "org.apache.spark.sql.hudi.command.CreateHoodieTableAsSelectCommand",
"tableDescs" : [ {
"fieldName" : "table",
"fieldExtractor" : "CatalogTableTableExtractor",
"columnDesc" : null,
"actionTypeDesc" : null,
"tableTypeDesc" : null,
"catalogDesc" : null,
"isInput" : false,
"setCurrentDatabaseIfMissing" : false
} ],
"opType" : "CREATETABLE_AS_SELECT",
"queryDescs" : [ {
"fieldName" : "query",
"fieldExtractor" : "LogicalPlanQueryExtractor"
} ]
}, {
"classname" : "org.apache.spark.sql.hudi.command.CreateHoodieTableCommand",
"tableDescs" : [ {
"fieldName" : "table",
"fieldExtractor" : "CatalogTableTableExtractor",
"columnDesc" : null,
"actionTypeDesc" : null,
"tableTypeDesc" : null,
"catalogDesc" : null,
"isInput" : false,
"setCurrentDatabaseIfMissing" : false
} ],
"opType" : "CREATETABLE",
"queryDescs" : [ ]
}, {
"classname" : "org.apache.spark.sql.hudi.command.CreateHoodieTableLikeCommand",
"tableDescs" : [ {
"fieldName" : "targetTable",
"fieldExtractor" : "TableIdentifierTableExtractor",
"columnDesc" : null,
"actionTypeDesc" : null,
"tableTypeDesc" : null,
"catalogDesc" : null,
"isInput" : false,
"setCurrentDatabaseIfMissing" : true
}, {
"fieldName" : "sourceTable",
"fieldExtractor" : "TableIdentifierTableExtractor",
"columnDesc" : null,
"actionTypeDesc" : null,
"tableTypeDesc" : null,
"catalogDesc" : null,
"isInput" : true,
"setCurrentDatabaseIfMissing" : true
} ],
"opType" : "CREATETABLE",
"queryDescs" : [ ]
}, {
"classname" : "org.apache.spark.sql.hudi.command.Spark31AlterTableCommand",
"tableDescs" : [ {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -72,11 +72,42 @@ object HudiCommands {
TableCommandSpec(cmd, Seq(tableDesc), ALTERTABLE_PROPERTIES)
}

val CreateHoodieTableCommand = {
val cmd = "org.apache.spark.sql.hudi.command.CreateHoodieTableCommand"
val tableDesc = TableDesc("table", classOf[CatalogTableTableExtractor])
TableCommandSpec(cmd, Seq(tableDesc), CREATETABLE)
}

val CreateHoodieTableAsSelectCommand = {
val cmd = "org.apache.spark.sql.hudi.command.CreateHoodieTableAsSelectCommand"
CreateHoodieTableCommand.copy(
classname = cmd,
opType = CREATETABLE_AS_SELECT,
queryDescs = Seq(QueryDesc("query")))
}

val CreateHoodieTableLikeCommand = {
val cmd = "org.apache.spark.sql.hudi.command.CreateHoodieTableLikeCommand"
val tableDesc1 = TableDesc(
"targetTable",
classOf[TableIdentifierTableExtractor],
setCurrentDatabaseIfMissing = true)
val tableDesc2 = TableDesc(
"sourceTable",
classOf[TableIdentifierTableExtractor],
isInput = true,
setCurrentDatabaseIfMissing = true)
TableCommandSpec(cmd, Seq(tableDesc1, tableDesc2), CREATETABLE)
}

val data: Array[TableCommandSpec] = Array(
AlterHoodieTableAddColumnsCommand,
AlterHoodieTableChangeColumnCommand,
AlterHoodieTableDropPartitionCommand,
AlterHoodieTableRenameCommand,
AlterTableCommand,
Spark31AlterTableCommand)
Spark31AlterTableCommand,
CreateHoodieTableCommand,
CreateHoodieTableAsSelectCommand,
CreateHoodieTableLikeCommand)
}
Original file line number Diff line number Diff line change
Expand Up @@ -129,4 +129,81 @@ class HudiCatalogRangerSparkExtensionSuite extends RangerSparkExtensionSuite {
s"does not have [alter] privilege on [$namespace1/$table1]")
}
}

test("CreateHoodieTableCommand") {
withCleanTmpResources(Seq((namespace1, "database"))) {
doAs(admin, sql(s"CREATE DATABASE IF NOT EXISTS $namespace1"))
interceptContains[AccessControlException](
doAs(
someone,
sql(
s"""
|CREATE TABLE IF NOT EXISTS $namespace1.$table1(id int, name string, city string)
|USING HUDI
|OPTIONS (
| type = 'cow',
| primaryKey = 'id',
| 'hoodie.datasource.hive_sync.enable' = 'false'
|)
|PARTITIONED BY(city)
|""".stripMargin)))(s"does not have [create] privilege on [$namespace1/$table1]")
}
}

test("CreateHoodieTableAsSelectCommand") {
withCleanTmpResources(Seq((s"$namespace1.$table1", "table"), (namespace1, "database"))) {
doAs(admin, sql(s"CREATE DATABASE IF NOT EXISTS $namespace1"))
doAs(
admin,
sql(
s"""
|CREATE TABLE IF NOT EXISTS $namespace1.$table1(id int, name string, city string)
|USING HUDI
|OPTIONS (
| type = 'cow',
| primaryKey = 'id',
| 'hoodie.datasource.hive_sync.enable' = 'false'
|)
|PARTITIONED BY(city)
|""".stripMargin))
interceptContains[AccessControlException](
doAs(
someone,
sql(
s"""
|CREATE TABLE IF NOT EXISTS $namespace1.$table2
|USING HUDI
|AS
|SELECT id FROM $namespace1.$table1
|""".stripMargin)))(s"does not have [select] privilege on [$namespace1/$table1/id]")
}
}

test("CreateHoodieTableLikeCommand") {
withCleanTmpResources(Seq((s"$namespace1.$table1", "table"), (namespace1, "database"))) {
doAs(admin, sql(s"CREATE DATABASE IF NOT EXISTS $namespace1"))
doAs(
admin,
sql(
s"""
|CREATE TABLE IF NOT EXISTS $namespace1.$table1(id int, name string, city string)
|USING HUDI
|OPTIONS (
| type = 'cow',
| primaryKey = 'id',
| 'hoodie.datasource.hive_sync.enable' = 'false'
|)
|PARTITIONED BY(city)
|""".stripMargin))
interceptContains[AccessControlException](
doAs(
someone,
sql(
s"""
|CREATE TABLE IF NOT EXISTS $namespace1.$table2
|LIKE $namespace1.$table1
|USING HUDI
|""".stripMargin)))(s"does not have [select] privilege on [$namespace1/$table1]")
}
}
}

0 comments on commit f6ccc4d

Please sign in to comment.