Spark 4.1: [WIP] Geometry / Geography end-to-end support - #16650
Spark 4.1: [WIP] Geometry / Geography end-to-end support#16650huan233usc wants to merge 2 commits into
Conversation
|
cc @szehon-ho |
Iceberg v3 stores geometry and geography lower/upper bounds as binary using the x:y:z:m encoding defined in the Bound Serialization section of the spec (Appendix D). The encoding is already implemented in GeospatialBound, but Conversions.toByteBuffer / fromByteBuffer have no GEOMETRY / GEOGRAPHY cases and throw UnsupportedOperationException, blocking ManifestEvaluator and any metric-based use of geo bounds. Wire GeospatialBound through Conversions for both geometry and geography, and add round-trip coverage in TestConversions for the 16-, 24-, and 32-byte shapes (including the x:y:NaN:m case for XYM bounds), CRS variants, and nulls.
Build on top of apache#16607 to enable end-to-end CREATE / INSERT / SELECT / DELETE on Iceberg geometry and geography columns from Spark 4.1. Parquet schema mapping - TypeToMessageType: emit Iceberg GEOMETRY / GEOGRAPHY as Parquet BINARY with LogicalTypeAnnotation.geometryType / geographyType, propagating CRS and (for geography) the EdgeAlgorithm. - MessageTypeToType: read those annotations back into Iceberg Types.GeometryType / Types.GeographyType. - ParquetMetrics: skip lex min/max bounds for geometry / geography (Comparators.forType has no ordering for spatial WKB) and fall back to value / null counts only. Spatial bounding boxes (X:Y:Z:M) will be plumbed through FieldMetrics in a follow-up. Generic Parquet readers / writers - BaseParquetReaders / BaseParquetWriter: dispatch the geometry and geography logical type annotations to ParquetValueReaders.byteBuffers and ParquetValueWriters.byteBuffers, surfacing WKB as ByteBuffer for the engine-agnostic data path. Spark 4.1 type bridge - TypeToSparkType / SparkTypeToType: bidirectional mapping between Iceberg GEOMETRY / GEOGRAPHY and Spark's GeometryType / GeographyType, preserving the CRS string. Geography defaults to the SPHERICAL edge algorithm on the Iceberg side. - PruneColumnsWithoutReordering: register GEOMETRY and GEOGRAPHY in the type-id table so column pruning does not reject geo columns. Spark 4.1 Parquet readers / writers - SparkParquetReaders: new GeometryReader / GeographyReader that read pure WKB from Parquet and prepend the 4-byte little-endian SRID header expected by Spark's internal GeometryVal / GeographyVal. The SRID is derived from the column's CRS via Spark's CartesianSpatialReference- SystemMapper / GeographicSpatialReferenceSystemMapper. - SparkParquetWriters: new GeometryWriter / GeographyWriter that strip Spark's SRID header and write only the WKB body to Parquet, matching the Iceberg / Parquet on-disk representation. Tests - TestSparkGeoTypes (Spark 4.1): 11 end-to-end SQL tests covering - flat geometry / geography round-trip, - ST_Srid predicate (validates SRID re-attachment from CRS), - DELETE on a v3 merge-on-read table producing a Puffin DV, - NULL geometry mixed with non-NULL, - mixed geometry + geography in the same table, - STRUCT<..., loc: GEOMETRY>, ARRAY<GEOMETRY>, MAP<STRING, GEOMETRY>, STRUCT<..., points: ARRAY<GEOMETRY>>, - DELETE + DV on a table whose geometry sits inside a struct. Vectorized reads are disabled per-table because the vectorized geo path is not yet implemented. Topological predicates such as ST_Intersects are not part of stock Spark 4.1, so predicate coverage is limited to ST_Srid for now.
|
|
||
| insertGeometry(GEOMETRY_TABLE, 1L, point2D(1.0, 2.0)); | ||
| insertGeometry(GEOMETRY_TABLE, 2L, point2D(3.0, 4.0)); | ||
|
|
There was a problem hiding this comment.
TODO: look up metadata
|
This pull request has been marked as stale due to 30 days of inactivity. It will be closed in 1 week if no further activity occurs. If you think that’s incorrect or this pull request requires a review, please simply write any comment. If closed, you can revive the PR at any time and @mention a reviewer or discuss it on the dev@iceberg.apache.org list. Thank you for your contributions. |
|
Closing this WIP tracking PR — the end-to-end geometry/geography support it prototyped has all landed on |
Note
Closing as done. This was a WIP / tracking PR that wired Iceberg's geometry and
geography types end-to-end on Spark 4.1 to prove the full
CREATE / INSERT / SELECT / DELETEpath over Parquet. That goal is complete: every piece has since landed onmainthrough focused, individually reviewed sub-PRs. Nothing here remains to merge.
What landed, and where
The end-to-end change was split into these merged PRs:
Conversions)TypeToMessageType,MessageTypeToType)ParquetMetrics)BaseParquetReaders/BaseParquetWriter)TypeToSparkType,SparkTypeToType,PruneColumnsWithoutReordering)SparkParquetReaders/SparkParquetWriters)The large in-progress
TestSparkGeoTypeshere was not merged as-is; its coverage wasreworked into
TestSparkGeospatialplus the DML/vectorization-fallback tests in #17149.Follow-ups (tracked separately)
Thanks to everyone who reviewed the split-out PRs.