[SPARK-58389][SQL] Pass all options while loading tables - #57582
Conversation
### What changes were proposed in this pull request? This is a follow-up to apache#56044 (which passed all options while loading changelogs). It does the same for table reads by adding `TableCatalog.loadTable(Identifier, TableContext, CaseInsensitiveStringMap)`, where `TableContext` carries the parsed, Spark-recognized parameters (time travel, write privileges) and the `CaseInsensitiveStringMap` carries all raw user options. - New public connector types `TableContext` and `TimeTravel` (a clean sealed interface with `Version`/`Timestamp` records), mirroring how apache#56044 introduced `ChangelogContext`/`ChangelogRange` rather than leaking the catalyst-internal `TimeTravelSpec`. - The new `loadTable` overload has a default implementation that delegates to the existing `loadTable` overloads based on `TableContext`, so existing connectors keep working unchanged. - `CatalogV2Util.getTable`/`loadTable` now build a `TableContext` from the catalyst `TimeTravelSpec` + write-privileges string and forward the user options, making the Java default the single dispatch site. - Options are threaded through the read paths in `RelationResolution` and `DataSourceV2Utils`. This PR does not touch the `RelationCatalog` single-RPC `loadRelation(Identifier)` read path, which for a table-and-view catalog is the primary path for a plain read (no time travel / write privileges) and so does not forward options. That is an independent improvement -- it needs nothing from this change (a new `loadRelation(Identifier, CaseInsensitiveStringMap)` overload plus wiring) -- and will be a separate PR. ### Why are the changes needed? To make the API usable in connectors like Iceberg and Delta, which need the user options while reading a table. The functionality hasn't been released yet. ### Does this PR introduce _any_ user-facing change? No. ### How was this patch tested? New tests in `CatalogV2UtilSuite` (the default-dispatch mapping for each `TableContext` shape, and the time-travel/write-privileges mutual-exclusion invariant) and `DataSourceV2OptionSuite` (end-to-end option forwarding via the DataFrame API, SQL, streaming, time travel, and the write path). Existing `SupportsCatalogOptionsSuite`, `ChangelogResolutionSuite`, `ChangelogEndToEndSuite`, and the DataSourceV2 SQL/DataFrame suites pass.
b86022f to
e1e6c66
Compare
|
Heads-up on an overlap: @anuragmantri has #57508 (SPARK-58330) open, and it changes the same lines this PR touches. #57508 fixes the case where the same table appears more than once in a statement with different Mechanically the two will conflict: #57508 restructures the The design question. A cache hit never calls the catalog. So once Spark already has a worked example of an option that affects the load, and it's instructive: time travel can be given purely as an option, So the question for this API is which kind of option it is meant to carry:
The javadoc currently says both — "take them into account when producing the The two treatments are not interchangeable, either. Putting options in the cache key means one load per distinct option bag, which gives up resolve-once-per-query: Side note on a problem this creates regardless of which way it goes: the single-pass resolver keys on Separate point on the same refactor. assert(writePrivilegesString.isEmpty, "Should not write to a table with time travel")This PR removes it, and the new default overload replaces it with silent precedence: if (context.timeTravel().isPresent()) { ... }
else if (!context.writePrivileges().isEmpty()) { ... }If both are ever set, time travel wins and the write privileges are dropped, so the catalog is never asked to authorize the write — the same shape as SPARK-58370. I couldn't find an earlier analyzer guard, so as far as I can tell that assert was the enforcement. It may be unreachable from SQL via the grammar today, in which case keeping the assert seems better than silently choosing one. A connector overriding the new method also receives a Last thing: neither this PR nor #57585 has a test with the same table referenced twice, and the The same argument applies to #57585 ( |
What changes were proposed in this pull request?
This is a follow-up to #56044 (which passed all options while loading changelogs). It does the same for table reads by adding
TableCatalog.loadTable(Identifier, TableContext, CaseInsensitiveStringMap), whereTableContextcarries the parsed, Spark-recognized parameters (time travel, write privileges) and theCaseInsensitiveStringMapcarries all raw user options.TableContextandTimeTravel(a clean sealed interface withVersion/Timestamprecords), mirroring how [SPARK-56961][SQL] Pass all options while loading changelog #56044 introducedChangelogContext/ChangelogRangerather than leaking the catalyst-internalTimeTravelSpec.loadTableoverload has a default implementation that delegates to the existingloadTableoverloads based onTableContext, so existing connectors keep working unchanged.CatalogV2Util.getTable/loadTablenow build aTableContextfrom the catalystTimeTravelSpec+ write-privileges string and forward the user options, making the Java default the single dispatch site.RelationResolutionandDataSourceV2Utils.Potential follow-up (intentionally out of scope here): the
RelationCatalogsingle-RPCloadRelation(Identifier)path is not updated to forward options. It applies only to catalogs that expose both tables and views, and fires only when there is no time travel or write privileges; closing that gap cleanly would add aloadRelation(Identifier, CaseInsensitiveStringMap)overload and is better done as a separate change.Why are the changes needed?
To make the API usable in connectors like Iceberg and Delta, which need the user options while reading a table. The functionality hasn't been released yet.
Does this PR introduce any user-facing change?
No.
How was this patch tested?
New tests in
CatalogV2UtilSuite(the default-dispatch mapping for eachTableContextshape, and the time-travel/write-privileges mutual-exclusion invariant) andDataSourceV2OptionSuite(end-to-end option forwarding via the DataFrame API, SQL, streaming, time travel, and the write path). ExistingSupportsCatalogOptionsSuite,ChangelogResolutionSuite,ChangelogEndToEndSuite, and the DataSourceV2 SQL/DataFrame suites pass.Was this patch authored or co-authored using generative AI tooling?
Generated-by: Claude code Opus 4.8