Conversation
pan3793
left a comment
There was a problem hiding this comment.
Review of #7718 (head 8ffa541). Verdict: request changes. The #7673 diagnosis and the Iceberg fix mechanism are verified real; the listing refactor introduces the regressions below in the same configurations the PR targets.
-
[Blocker, regression] Local temp views leak into the new v2 listing.
catalog.listTables(ns)(SparkCatalogUtils.scala:202-204) reachesV2SessionCatalog.listTables->SessionCatalog.listTables(db)withincludeLocalTempViews = true, so temp views come back asIdentifier.of(Array(), name); they are typed TABLE withTABLE_SCHEM=""(:217-232) andgetTempViews(:350-359) emits the same view a second time as VIEW. Master usedincludeLocalTempViews = falsehere. Fix: drop identifiers with an empty namespace before typing/loading. -
[Blocker, regression]
catalog.loadTable(ident)at :229 is unguarded and runs per row whenignoreTableProperties=false(the default), so the namespace-less identifier from (1) throws (requiresSinglePartNamespace/NoSuchTable) and fails the whole GetTables; any unloadable, dropped, or corrupt table does the same. It also forces per-table format I/O (Delta_delta_log, Iceberg metadata JSON) where master did one bulk HMS call. Fix: wrap inTryand degrade REMARKS to "" (or keep the session-catalog listing load-free). -
[Blocker, regression] The view probe keys
listViewsresults by the outer db (:211-215) whileSessionCatalog.listViewsalso returns local temp views, so a temp viewvmarks permanent tabledb.vas VIEW and removes it undertableTypes={TABLE}. Fix: only keepTableIdentifiers with a database. -
[Major, regression]
getSchemas("spark_catalog", ...)with a custom session catalog now returns backtick-quoted namespaces and matches the pattern against the quoted form (:126, :170-173); a DB like2024_dbis returned as`2024_db`and no longer matchable by its own pattern. Master returned raw v1 names. -
[Major, regression]
listAllNamespacesis a non-exhaustive match (:153-163) and is now reachable for the session catalog, so aTableCatalog-only session catalog throwsMatchErrorin GetSchemas where master returned v1 rows. -
[Major, new failure mode] The per-namespace
spark.sessionState.catalog.listViews(db, ...)probe callsrequireDbExists, so a custom session catalog whose namespaces are not v1-backed now fails the whole GetTables withNoSuchDatabaseException. Guard withdatabaseExistsor catch and skip the probe for that namespace. -
[Major]
hasCustomSessionCatalog(:106-109) compares case-sensitively; Spark 4.x normalizesBUILTINtobuiltin, so such a value is treated as custom. UseequalsIgnoreCase(mirrorsV2SessionCatalog.hasCustomSessionCatalog). -
[Major, behavior change]
tableTypesis now applied to ordinary v2 catalogs (:225) while view detection exists only for the session catalog, sogetTables(<v2 catalog>, ..., Array("VIEW"))goes from all-rows-typed-TABLE to empty. DSv2ViewCatalogis still immature, so covering v2 tables only is fine for this PR - please just document the limitation (non-session v2 catalogs report tables only, VIEW-only filters return empty) and drop the filter or add a test pinning the empty-result behavior. -
[Major, scope/claim] The fix guarantees only "the custom catalog can load the table". Tables delegated back to v1 (e.g.
DeltaCatalog+catalogImplementation=hive, or non-Iceberg tables under Iceberg's session catalog) still hitHiveExternalCatalog/HiveClientImpl.getStorageHandlerand the sameClassNotFoundException. Narrow the claim, or make the listing independent of per-catalog loading. -
[Major]
TABLE_CATis inconsistent within one result:catalog.name()at :231 vs the raw request string ingetTempViews(:357) andgetColumnsByCatalog, sogetTables(null, ...)mixes"spark_catalog"withnull. Align all row producers and tighten the assertions. -
[Test]
DeltaMetadataTests#get tables and viewsexercises the new path (DeltaCatalog is a custom session catalog) but passes on master, so it does not discriminate the fix. Add a case that fails without the change, or drop it. -
[Test] Nothing covers GetSchemas: reverting only the getSchemas change keeps the suites green, because the test session catalogs delegate namespaces to the v1 catalog. Add a test-only
CatalogExtensionexposing a namespace the v1 catalog cannot see. -
[Test]
IcebergMetadataTestscreatesspark_catalog.<db>namespaces and never drops them (withDatabasesonly drops unqualified names), making the exact-countget schemasassertion order-dependent. Drop them in thefinallyblocks. -
[Test]
kyuubi.operation.getTables.ignoreTablePropertieshas no coverage repo-wide; the new path has three distinct behaviors for it (:208, :225, :228). Add a test. -
[Minor] The new tests never assert
TABLE_SCHEM/TABLE_CAT; the docstring at :186-191 overstates ("returns both v1 and v2 views", "never loads the Hive storage handler") - it only covers views registered in the v1 catalog;catalog.name()andcatalog.nameare mixed in one file. -
[Minor] The new
WithSimpleHMSContainerduplicatesWithSecuredHMSContainer(drop the unusedenv, consider sharing the container def),hmsThriftUrishas no null guard, andHostPortWaitStrategyhas no startup-timeout margin. -
[Hygiene] Commit
80255d65eis tagged #7064 while the PR head/title use #7673, and the description does not describe the final diff or list the commands run. Please update the description for the final state.
8ffa541 to
5b7ec6a
Compare
|
Thanks for the thorough review. All blockers and majors are addressed, code, tests, and PR metadata are now aligned. Point-by-point:
|
Why are the changes needed?
The thrift
GetSchemas/GetTablesoperations assumedspark_catalogis always the builtin V1 session catalog and listed databases/tables viaspark.sessionState.catalog. When a custom session catalog is configured, e.g.these operations bypass the DSv2 catalog APIs (
SupportsNamespaces/TableCatalog) and the V1 session catalog path cannot even parse the V2 table metadata the custom catalog persists in HMS - it may return wrong results, or throw and fail the whole request. #7673 is a real-world example:GetTablesfails withClassNotFoundException: org.apache.iceberg.mr.hive.HiveIcebergSerDewhen the V1HiveExternalCatalogtries to load tables registered by Iceberg withstorage_handler = org.apache.iceberg.mr.hive.HiveIcebergStorageHandler.How was this patch tested?
Added test coverage:
IcebergMetadataTests#get tables— exercises bothspark_catalog(hive-backed session catalog) andhadoop_prod(hadoop-backed v2 catalog), now assertingTABLE_SCHEM/TABLE_CATand dropping namespaces infinally.IcebergMetadataTests#get tables and views— custom session catalog view detection, verifyingtableTypesfiltering (TABLE/VIEW).IcebergMetadataTests#get tables with ignoreTableProperties— covers all three behaviors ofignoreTableProperties(skip view probe, skiptableTypesfilter, skip per-table property loading).SparkCatalogUtilsSuite#getSchemas lists DSv2-only namespace— covers the custom session catalog GetSchemas path via a test-onlyDummySessionCatalogexposing a namespace the v1 catalog cannot see.WithSimpleHMSContaineris wired intoSparkIcebergOperationSuiteandIcebergOperationSuiteso these run against a real Hive metastore (catalogImplementation=hive).Manually verified against Iceberg 1.10.1 (which removed
iceberg-hive-runtime):beeline -u "jdbc:hive2://<kyuubi-host>:<port>/" -n <user> -e "!tables". This previously threwClassNotFoundException: org.apache.iceberg.mr.hive.HiveIcebergStorageHandler, and now returns the table asTABLEand v1/v2 views asVIEW.Limitations
TABLE); thetableTypesfilter is not applied to them, so aVIEW-only request still returns those tables typedTABLE(noVIEWrows are produced by the catalog itself). DSv2ViewCatalogis still immature, so covering v2 tables only is intentional for this PR.Was this patch assisted by generative AI tooling?
Assisted-by: DeepSeek-V4-Pro