Repository navigation
[KYUUBI #7774][AUTHZ] Resolve the table owner for v1 (Hive) tables - #7775
attilapiros wants to merge 3 commits into
Conversation
Granting ownership privileges needs the table owner on the privilege object, but it
came back empty for Hive tables.
`TableExtractor.getOwner` assumed its argument wraps a connector `Table` in a `table`
member. `V1Table`, which `V2SessionCatalog.loadTable` returns for a session-catalog
(Hive) table, carries the properties itself and has no `table` accessor, so the
lookup threw, was swallowed by the surrounding `catch`, and the owner was lost.
`DROP TABLE` on a Hive table reaches exactly this path. With
`spark.sql.legacy.useV1Command` at its default of `false` the plan is not downgraded
to `DropTableCommand`; it stays as the v2 `DropTable(ResolvedIdentifier(...))`, whose
first table descriptor resolves the owner through `loadTable`.
- `getOwner` picks the properties holder -- `V1Table` itself, or the wrapped table
otherwise -- and then reads the owner once, instead of duplicating the lookup.
- Empty owners are filtered out. `V1Table.addV2TableProperties` sets `PROP_OWNER`
unconditionally, so a table with no owner yielded `Some("")`. The other owner
lookups in this file already filter on `nonEmpty`.
- A debug line when the catalog lookup fails, so a genuinely absent owner can be told
apart from a failed load.
`V1Table` is `private[sql]`, so it is matched by class name; it cannot be referenced
as a type from this package.
```
build/mvn test -Dcdpd.build -pl extensions/spark/kyuubi-spark-authz -am
```
A new test in `HiveCatalogRangerSparkExtensionSuite` asserts the owner on the
privilege object built for `DROP TABLE`. It fails without this change: the owner is
`None`, because `getOwner` throws on a `V1Table`. The test asserts the owner value
rather than `isDefined` -- since `PROP_OWNER` is always set, `isDefined` would also
hold for an empty owner.
| val table = invokeAs[AnyRef](v, "table") | ||
| val properties = invokeAs[JMap[String, String]](table, "properties").asScala | ||
| properties.get("owner") | ||
| // It holds the properties itself, rather than wrapping another table. |
There was a problem hiding this comment.
should move this comment to the V1Table branch?
|
Match on the public import org.apache.spark.sql.connector.catalog.{Identifier, Table => V2Table}
val maybeTable = v match {
case table: V2Table => table
case _ => invokeAs[AnyRef](v, "table")
}For example, Delta Lake\s |
|
@pan3793 I just would not call it |
|
Spark uses |
|
@pan3793 ok, I have done the rename |
### Why are the changes needed?
Granting ownership privileges needs the table owner on the privilege object, but it came back empty for Hive tables.
`TableExtractor.getOwner` assumed its argument wraps a connector `Table` in a `table` member. `V1Table`, which `V2SessionCatalog.loadTable` returns for a session-catalog (Hive) table, carries the properties itself and has no `table` accessor, so the lookup threw, was swallowed by the surrounding `catch`, and the owner was lost.
`DROP TABLE` on a Hive table reaches exactly this path. With `spark.sql.legacy.useV1Command` at its default of `false` the plan is not downgraded to `DropTableCommand`; it stays as the v2 `DropTable(ResolvedIdentifier(...))`, whose first table descriptor resolves the owner through `loadTable`.
- `getOwner` picks the properties holder -- `V1Table` itself, or the wrapped table otherwise -- and then reads the owner once, instead of duplicating the lookup.
- Empty owners are filtered out. `V1Table.addV2TableProperties` sets `PROP_OWNER` unconditionally, so a table with no owner yielded `Some("")`. The other owner lookups in this file already filter on `nonEmpty`.
- A debug line when the catalog lookup fails, so a genuinely absent owner can be told apart from a failed load.
`V1Table` is `private[sql]`, so it is matched by class name; it cannot be referenced as a type from this package.
### How was this patch tested?
A new test in `HiveCatalogRangerSparkExtensionSuite` asserts the owner on the privilege object built for `DROP TABLE`. It fails without this change: the owner is `None`, because `getOwner` throws on a `V1Table`. The test asserts the owner value rather than `isDefined` -- since `PROP_OWNER` is always set, `isDefined` would also hold for an empty owner.
### Was this patch assisted by generative AI tooling?
Assisted-by: Claude Opus 5
Closes #7775 from attilapiros/7774.
Closes #7774
304aafd [attilapiros] renaming ConnectorTable to V2Table
86d9108 [attilapiros] Applying review comments
389b555 [attilapiros] [KYUUBI #7774][AUTHZ] Resolve the table owner for v1 (Hive) tables
Authored-by: Attila Zsolt Piros <piros.attila.zsolt@gmail.com>
Signed-off-by: Cheng Pan <chengpan@apache.org>
(cherry picked from commit e130c3e)
Signed-off-by: Cheng Pan <chengpan@apache.org>
Why are the changes needed?
Granting ownership privileges needs the table owner on the privilege object, but it came back empty for Hive tables.
TableExtractor.getOwnerassumed its argument wraps a connectorTablein atablemember.V1Table, whichV2SessionCatalog.loadTablereturns for a session-catalog (Hive) table, carries the properties itself and has notableaccessor, so the lookup threw, was swallowed by the surroundingcatch, and the owner was lost.DROP TABLEon a Hive table reaches exactly this path. Withspark.sql.legacy.useV1Commandat its default offalsethe plan is not downgraded toDropTableCommand; it stays as the v2DropTable(ResolvedIdentifier(...)), whose first table descriptor resolves the owner throughloadTable.getOwnerpicks the properties holder --V1Tableitself, or the wrapped table otherwise -- and then reads the owner once, instead of duplicating the lookup.V1Table.addV2TablePropertiessetsPROP_OWNERunconditionally, so a table with no owner yieldedSome(""). The other owner lookups in this file already filter onnonEmpty.V1Tableisprivate[sql], so it is matched by class name; it cannot be referenced as a type from this package.How was this patch tested?
A new test in
HiveCatalogRangerSparkExtensionSuiteasserts the owner on the privilege object built forDROP TABLE. It fails without this change: the owner isNone, becausegetOwnerthrows on aV1Table. The test asserts the owner value rather thanisDefined-- sincePROP_OWNERis always set,isDefinedwould also hold for an empty owner.Was this patch assisted by generative AI tooling?
Assisted-by: Claude Opus 5