Skip to content

feat(hive): add Iceberg-to-HMS schema and record conversion helpers - #904

Open
MisterRaindrop wants to merge 2 commits into
apache:mainfrom
MisterRaindrop:feat/hive-conversion-layer
Open

feat(hive): add Iceberg-to-HMS schema and record conversion helpers#904
MisterRaindrop wants to merge 2 commits into
apache:mainfrom
MisterRaindrop:feat/hive-conversion-layer

Conversation

@MisterRaindrop

@MisterRaindrop MisterRaindrop commented Sep 2, 2026

Copy link
Copy Markdown
Contributor

Next step of the HiveCatalog split (follows #796): two conversion layers between Iceberg's catalog model and the HMS record shape. No Thrift, no I/O, fully unit tested.

  • hive_schema — renders an Iceberg Schema as the Hive DDL column list HMS stores, nested types included.
  • hive_utilsNamespace / TableIdentifier ↔ HMS Database / Table, the Iceberg-on-HMS parameter keys (metadata_location, table_type, EXTERNAL), and the LazySimpleSerDe descriptor Spark and Trino expect. Plain structs rather than Thrift objects, so HmsClient stays the only translation unit that includes the generated bindings.

Where the two reference implementations disagree:

  • timestamptztimestamp with local time zone, following iceberg-java; iceberg-rust rejects zoned timestamps outright, which would make such tables uncreatable. Java's sub-Hive-3 fallback is not reproduced — no Hive-version probe here, and the vendored IDL is Hive 4.0.1.
  • A database owner is carried by hive.metastore.database.owner / hive.metastore.database.owner-type, the keys both references use; a bare owner is the table owner key.

Iceberg v3 types that neither reference maps to a real Hive type return kNotImplemented rather than guessing a spelling. Nothing calls any of this yet — HiveCatalog remains a stub; HmsClient's Thrift wrappers and the catalog CRUD paths come next.

33 new unit tests; hive_catalog_test goes from 17 to 50 cases.

Creating an Iceberg table through HMS means rendering its schema as
Hive DDL. Add `TypeToHiveString` for one `Type` and
`SchemaToHiveColumns` for a whole `Schema`; nested struct / list / map
render recursively.

`timestamptz` follows iceberg-java and emits `timestamp with local time
zone`, since engines reading through HMS take their column types from
this DDL. Java's sub-Hive-3 fallback is not reproduced: there is no
Hive-version probe here and the vendored IDL is Hive 4.0.1.

Iceberg v3 types that no reference maps to a real Hive type
(timestamp_ns, variant, geometry, geography, unknown) return
kNotImplemented rather than guessing a spelling.
HMS speaks `Database` and `Table`; Iceberg speaks `Namespace`,
`TableIdentifier` and `Schema`. Add the conversion between them, plus
the parameter keys (`metadata_location`, `table_type`, `EXTERNAL`) that
iceberg-java and iceberg-rust use to recognise an Iceberg table, and
the LazySimpleSerDe descriptor that keeps Spark and Trino reading it.
The helpers produce plain structs rather than Thrift objects, so
HmsClient stays the only translation unit that includes the generated
bindings.

A database owner is carried by `hive.metastore.database.owner` and
`hive.metastore.database.owner-type`, the keys both references use; a
bare `owner` is the table owner key. `owner-type` requires an owner and
must name an HMS PrincipalType -- USER, GROUP or ROLE, compared
case-insensitively.
@MisterRaindrop
MisterRaindrop force-pushed the feat/hive-conversion-layer branch from 69b9934 to 8a4041c Compare September 2, 2026 06:34
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant