Uh oh!
There was an error while loading. Please reload this page.
Spark: Add support for 4.2.0 - #14984
Conversation
0d5d05d to
330955bComparebd2bff7 to
af86915CompareThis failure from testing Spark 4.2.0-preview2 is caused by apache/spark#53788, after which an |
af86915 to
a15674cComparemanuzhang
commented
Mar 17, 2026
Failed tests after upgrading to Spark 4.2.0-preview3-rc1
|
manuzhang
commented
Mar 19, 2026
apache/spark#54884 has been opened to fix the first failure. |
cc08c55 to
cbdcfc9Comparemanuzhang
commented
Mar 20, 2026
I will update |
There was a problem hiding this comment.
leave a note here to implement the new method in the Reducer once apache/spark#54884 is in (next Spark 4.2 preview)
Sorry just saw, it is the same comment
b19679d to
d478651Comparemanuzhang
commented
Apr 7, 2026
The failed tests in 4.2.0-preview3 have been fixed in 4.2.0-preview4. |
@szehon-ho Thanks for the thorough review. I've addressed all the comments, either fixing as recommended, or updating comments, or opening follow-up issues. Please take another look at your convenience. We are not in a rush to get this in now, thanks for @nssalian's heads-up. |
szehon-ho
commented
Aug 20, 2026
Thank you @manuzhang for persistence, sorry about the previous review if its not so clear. I'll try to make it more clear in the future. It's just a huge pr so hard to review as other folks mention. I'm a bit swamped but try to take a look in next day or two. By the way, @nssalian would one option maybe, we merge some version and then fix different parts in smaller prs? For the release, we will have the source code, but this won't make any release artifact, would that work? |
huan233usc
commented
Aug 20, 2026
+1 to merging a version first and then fixing the individual parts in smaller PRs — right now it does feel like we're reviewing a moving target. IIUC about the changes -- the bulk of the real logic is the view migration to Spark 4.2's RelationCatalog (Spark now owns view parsing/resolution, so ResolveViews changes a lot, plus the new Iceberg*V2View exec nodes and catalog wiring). The geo side looks mostly like a mechanical GeometryVal/GeographyVal → BinaryView migration. We could do additional follow-ups items and check like cross-version view testing to guard against regressions. |
manuzhang
commented
Aug 20, 2026
@szehon-ho No worry. The review comments are valuable. It's just that how we can collaborate more efficiently on such a huge PR involving both AI and human.
+1. I can remove the codes to publish the 4.2 artifacts. |
nssalian
commented
Aug 20, 2026
This makes more sense. Let's get the baseline there and then we can add features on top of it. |
manuzhang
commented
Aug 20, 2026
@nssalian I think this PR is already in good shape after many rounds of reviews. The only remaining work is to remove the release codes. |
| /examples/**export-ignore | ||
| /docsexport-ignore | ||
| /docs/**export-ignore | ||
| /spark/v4.2export-ignore |
There was a problem hiding this comment.
This excludes Spark 4.2 support from source-release tarball.
nssalian
commented
Aug 25, 2026
CC: @huaxingao@szehon-ho PTAL at the latest changes |
There was a problem hiding this comment.
Thanks, the compatibility changes look sound overall. I found two remaining SparkSessionCatalog correctness issues in the inline comments.
For documentation, the user-visible behavior changes for Iceberg-backed views in Spark 4.2 are:
- View columns are matched by recorded name and occurrence ordinal instead of absolute position.
- Example: after
(id, data)is reordered to(data, id), Spark 4.2 preserves the view output as(id, data); Spark 4.1 may mis-map or fail.
- Example: after
CREATE VIEW ... WITH SCHEMA { BINDING | COMPENSATION | TYPE EVOLUTION | EVOLUTION }is supported. The default isCOMPENSATION.- Views capture and replay relevant creation-time SQL settings.
- Example: a view created with ANSI mode enabled still raises invalid-cast errors when queried from a session with ANSI mode disabled.
- Persistent views require explicit aliases for generated expressions.
- Example:
SELECT id + 1now fails during view creation; useSELECT id + 1 AS new_id.spark.sql.legacy.allowAutoGeneratedAliasForView=truerestores the old behavior.
- Example:
- Persistent views referencing temporary variables are rejected.
CREATE OR REPLACE VIEWremoves user properties omitted from the replacement.- Example: replacing a view with
TBLPROPERTIES (purpose=reporting)without specifyingpurposeremoves that property; Spark 4.1 retained it.
- Example: replacing a view with
SparkSessionCatalog.listViewscombines Iceberg and session-catalog views, soSHOW VIEWSmay return more entries.listTableSummariesreturns tables only. The newlistRelationSummariesreturns tables and views, andSHOW TABLESuses the combined listing.- Recursive-view detection covers cross-catalog views, multi-level namespaces, V1 views, and nested expressions.
- Example: if
v2referencesv1,CREATE OR REPLACE VIEW v1 AS SELECT * FROM v2is rejected during analysis with a recursive-view error.
- Example: if
- View output column names containing commas now round-trip correctly.
- Example: aliasing
idto the single column nameid,datapreserves it as one name; previously it could be interpreted as two names.
- Example: aliasing
- Replacing a view or changing its properties invalidates its cached plan. Renaming a cached view preserves the cache under the new name.
- View inspection commands (
SHOW CREATE TABLE,SHOW TBLPROPERTIES, andDESCRIBE EXTENDED) produce updated output.
I think there's no way around it as we are moving from Iceberg extension to Spark view behavior.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Generated-by: Codex
Generated-by: Codex
Generated-by: Codex
Preserve BINDING semantics for legacy Iceberg views without persisted schema-mode metadata and align the catalog tests with that behavior. Generated-by: Codex
GGraziadei
left a comment
There was a problem hiding this comment.
According to the conversation and considering the last commit, LGTM!
szehon-ho
left a comment
There was a problem hiding this comment.
The follow-up changes, including the schema-mode correction, look good. There is just one more small production correctness problem in the cross-backend collision handling, covered by the two inline comments.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Reject staged table create-or-replace operations when a view exists in either backend and keep relation summaries consistent with table-first resolution. Generated-by: Codex
Uh oh!
There was an error while loading. Please reload this page.
Generated-by: Codex
Uh oh!
There was an error while loading. Please reload this page.
Generated-by: Codex
szehon-ho
left a comment
There was a problem hiding this comment.
lgtm. I think from https://lists.apache.org/thread/821bjvx2jym709yvt56xl6vm733z742t that @aokolnychyi wanted to take another look as well before we officially release Spark 4.2 support (I think he will soon return from vacation). But it looks ok from my side and now we are not going to release a jar for 1.12
szehon-ho
commented
Sep 4, 2026
Merged, lets continue iterating on the code. Thanks @manuzhang for the persistence and everyone for additional reviews |
anuragmantri
commented
Sep 4, 2026
Thanks @manuzhang for the PR and everyone for the thorough reviews. |
This PR adds support for Apache Spark 4.2.0.
Release publishing: Spark 4.2 artifacts are excluded from
dev/stage-binaries.shand will not be published by default.The first two commits rename the Spark 4.1 module to 4.2 and then restore 4.1 so Git retains file history. The remaining commits contain the Spark 4.2 compatibility changes and review follow-ups.
Changes
RelationCatalogandViewAPIs while preserving Iceberg property-only updates for view properties, including cached and session catalogs.BinaryViewrepresentation and Iceberg's pure WKB Parquet representation, includingStructInternalRowand nested values.Geospatial compatibility details
GeometryandGeographyvalues. It accepts the seven OGC base geometry types, including Z/M variants, and enforces longitude and latitude bounds for geography. Existing Iceberg data with extended geometry types or out-of-bounds geography coordinates can now fail withwkbParseErrorinstead of passing through as it did in Spark 4.1.POINT EMPTYremains accepted. Iceberg uses Spark's public conversion API and cannot bypass this validation.BinaryViewphysical representation, so arrays, maps, and structs must convert Iceberg WKB values explicitly. Older Spark versions use different physical types and can be handled separately.View compatibility details
RelationCatalog. It also represents query text, current catalog and namespace, schema mode, SQL configs, dependencies, and properties through its newViewmodel.SparkCatalogandSparkSessionCatalogtranslate that model to and from Iceberg view metadata and implement create, replace, create-or-replace, load, drop, and rename through the new signatures.ResolveRelationsnow callsRelationCatalog.loadRelationbefore extension resolution rules, andBaseCatalog.loadRelationfalls back from tables to views. Spark therefore expands Iceberg views into logicalViewnodes and appliesGetViewColumnByNameAndOrdinalplus schema-mode-driven casting. This replaces Iceberg 4.1's positional expansion. The unreachableResolveViewsrelation expansion and its identifier rewrites have been removed; Spark function resolution now owns references such assystem.bucket.ResolveSessionCatalogexits early or selects V1 handling for several view commands.RewriteViewCommandsrecognizes only Iceberg-backed V2 view catalogs before that happens, while preserving local and global temporary-view behavior, and routes create, drop, rename, describe, show-create, show-properties, and show-views commands to Iceberg-aware logical and physical nodes. Resolved commands carry the already-loaded view into inspection planning, avoiding a second catalog lookup.CreateViewmeans Spark's nativeCheckViewReferencesno longer sees the original node.CheckViewsexplicitly reuses Spark's checks for temporary objects, generated aliases, and column counts, and traverses Spark logicalViewnodes for fully qualified recursive-view detection. Iceberg retains its complete nested-expression traversal because Spark's helper only matches aSubqueryExpressionat the root of an expression.SparkViewround-trips query column names as JSON (with legacy comma-separated read compatibility), SQL configs, schema-binding mode, metric-view dependencies, engine versions, and non-default view types through reserved Iceberg properties. Views without persisted schema-mode metadata useBINDINGto preserve Spark 4.1's strict behavior, while Spark 4.2-created views persist their native mode explicitly; type-promotion coverage verifies the legacy fallback. Metric-view dependencies remain persisted because Iceberg has no native dependency field and Spark must receive the structured list again when loading the view.ALTER VIEW SET/UNSET TBLPROPERTIESas property-only metadata commits because Spark 4.2 removedViewCatalog.alterView, and its replacement path would discard non-Spark SQL representations. These commands translate identifiers through the owning catalog and invalidate cached plans. Rename preserves an existing cache entry.CREATE OR REPLACE VIEWremoves omitted properties on a best-effort follow-up commit because Iceberg'sViewBuildercannot yet express atomic property removals. The owning Spark catalog remains persisted in portabledefault-catalogmetadata; the load path only falls back to the adapter's catalog name for older metadata where it is absent.CREATE VIEW v AS SELECT id + 1 FROM tare rejected unless the expression has an explicit alias.spark.sql.legacy.allowAutoGeneratedAliasForView=trueprovides the Spark compatibility escape hatch.Verification
TestViewscoverage for legacy schema binding, recursive cycles, rename behavior, property replacement, and property ALTER across the existing catalog configurations.TestViewCatalogCacheacross named and session catalogs, covering replace, property removal, ALTER, rename, and cache invalidation.TestSparkCatalogIdentifierMapping,TestSparkCatalogOperations,TestSparkSessionCatalog,TestSparkParquetReader,TestSparkParquetWriter,TestAlterTable, andTestTimestampWithoutZone.git diff --check.AI Disclosure