feat: add v3 geometry and geography support - #880
Conversation
wgtmac
commented
Aug 8, 2026
- align geospatial type semantics and schema JSON with the v3 spec
- add bound encoding and Java-compatible intersection evaluation
- represent WKB as Arrow binary and support Avro byte round trips
- generate and validate Parquet geospatial logical types
- preserve count metrics while omitting geospatial byte-order bounds
- align geospatial type semantics and schema JSON with the v3 spec - add bound encoding and Java-compatible intersection evaluation - represent WKB as Arrow binary and support Avro byte round trips - generate and validate Parquet geospatial logical types - preserve count metrics while omitting geospatial byte-order bounds
There was a problem hiding this comment.
Pull request overview
Adds Iceberg v3 geospatial (geometry/geography) support across type semantics, JSON schema strings, and file format integrations (Arrow, Avro, Parquet), including bound encoding/intersection utilities.
Changes:
- Update Geometry/Geography type parameter defaults and equality/string semantics to match v3 expectations.
- Add geospatial bounds encoding + intersection evaluation utilities and corresponding tests.
- Enable round-tripping of geospatial WKB through Arrow (binary), Avro (bytes), and Parquet (geospatial logical types), plus metrics behavior updates.
Reviewed changes
Copilot reviewed 23 out of 23 changed files in this pull request and generated 1 comment.
Show a summary per file
| File | Description |
|---|---|
| src/iceberg/type.h | Default CRS/algorithm storage for geospatial primitive types. |
| src/iceberg/type.cc | Updated geospatial constructors, equality, and string representations. |
| src/iceberg/test/visit_type_test.cc | Update expected primitive type string representations. |
| src/iceberg/test/type_test.cc | Extend geospatial type tests; add bounds/intersection test coverage. |
| src/iceberg/test/schema_json_test.cc | Align schema JSON strings with v3; accept bare geospatial type names. |
| src/iceberg/test/parquet_test.cc | Add Parquet round-trip test for WKB stored as binary. |
| src/iceberg/test/parquet_schema_test.cc | Add Parquet geospatial logical type conversion/projection tests. |
| src/iceberg/test/parquet_metrics_test.cc | Ensure geospatial metrics exclude bounds while preserving counts. |
| src/iceberg/test/avro_test.cc | Add Avro writer test treating geospatial values as opaque bytes. |
| src/iceberg/test/avro_schema_test.cc | Ensure geospatial types map/project as Avro bytes. |
| src/iceberg/test/arrow_test.cc | Map geometry/geography to Arrow binary and adjust unsupported list. |
| src/iceberg/schema_internal.cc | Enable Arrow schema conversion for geometry/geography as binary. |
| src/iceberg/parquet/parquet_writer.cc | Switch Parquet writer to Iceberg-driven Parquet schema generation. |
| src/iceberg/parquet/parquet_schema_util.cc | Implement Parquet schema generation + geospatial compatibility validation. |
| src/iceberg/parquet/parquet_schema_util_internal.h | Expose Iceberg→Parquet schema conversion API. |
| src/iceberg/parquet/parquet_metrics.cc | Skip bounds collection for geometry/geography metrics. |
| src/iceberg/meson.build | Add geospatial sources/headers to Meson build/install. |
| src/iceberg/geospatial.h | New public API for bounds/box encoding and intersection checks. |
| src/iceberg/geospatial.cc | Implement geospatial bound/box encoding and intersection logic. |
| src/iceberg/CMakeLists.txt | Add geospatial.cc to CMake sources. |
| src/iceberg/avro/avro_schema_util.cc | Write geospatial types as Avro bytes nodes. |
| src/iceberg/avro/avro_direct_decoder.cc | Decode geospatial values via the Avro-bytes path. |
| src/iceberg/avro/avro_data_util.cc | Append geospatial values via the Avro-bytes path. |
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
|
@zhjwpku @manuzhang PTAL :) |
| case TypeId::kVariant: | ||
| return NotSupported("Cannot write Iceberg variant type to Parquet"); | ||
| default: | ||
| return InvalidSchema("Expected nested Iceberg type, got {}", type); |
There was a problem hiding this comment.
nit: Variant is not a nested type in spec, maybe we can use unreachable here.
| if (descr.physical_type() != ::parquet::Type::BYTE_ARRAY) { | ||
| return InvalidSchema("Iceberg type {} requires Parquet BYTE_ARRAY", expected_type); | ||
| } | ||
| if (expected_type.type_id() == TypeId::kGeometry) { |
There was a problem hiding this comment.
This (and the following) validates only whether the logical type is GEOMETRY or GEOGRAPHY; it does not compare the logical-type parameters with the expected Iceberg type. As a result, the reader currently accepts cases such as:
geometry(EPSG:3857) projected as geometry(OGC:CRS84)
geography(OGC:CRS84, spherical) projected as geography(EPSG:4326, karney)
Because WKB does not encode the CRS or edge-interpolation algorithm, this can silently interpret the same bytes using different semantics.
|
cc @huan233usc who implemented geometry and geography support in iceberg java |