dhruvarya-db opened a new pull request, #17543:
URL: https://github.com/apache/iceberg/pull/17543

   Opening this to drive discussion on what the REST catalog spec needs for 
table format version 4. It is a proposal rather than a merge candidate — parts 
of it depend on table spec work that is still in review, and one change is 
deliberately breaking. Both are called out under Open questions.
   
   ## Motivation
   
   A REST catalog serves tables at mixed format versions to clients at mixed 
capability levels, and v4's changes are concentrated in metadata structure, 
which is exactly what the REST contract carries. Three constraints in the 
current spec prevent a catalog from serving a v4 table at all:
   
   | Constraint | V4 requirement |
   | --- | --- |
   | `TableMetadata.format-version` has `maximum: 3` | must accept `4` |
   | `Snapshot` requires `manifest-list` | v4 snapshots reference a root 
manifest instead |
   | `CommitTableResponse` requires `metadata-location` | may not exist when 
the catalog owns table state |
   
   ## Changes
   
   **`TableMetadata`** — raise the `format-version` maximum to 4. Document that 
`location` is optional in v4, where it may be supplied by the catalog rather 
than carried in metadata.
   
   **`Snapshot`** — add `root-manifest`, make `manifest-list` optional, and add 
a `oneOf` requiring exactly one of the two:
   
   ```yaml
   oneOf:
     - required: [manifest-list]
     - required: [root-manifest]
   ```
   
   A snapshot with neither is invalid and must not be read as a snapshot with 
no files; one with both is also invalid. Which of the two applies is determined 
by `format-version`, which cannot be expressed here because that field lives in 
the enclosing `TableMetadata`, so it is stated normatively in the description.
   
   **`LoadTableResult` / `CommitTableResponse`** — add `table-location`, 
carrying the table's base location for resolving relative paths. V4 makes 
`TableMetadata.location` optional while allowing relative paths, so a table can 
legitimately have metadata that is unreadable without a catalog-supplied base. 
`CommitTableResponse` no longer requires `metadata-location`, and both 
responses document that it may be absent when the catalog is the source of 
truth for table state and no client-visible metadata pointer exists. Clients 
obtain a location for such a table through `unregisterTable`, whose existing 
contract guarantees the catalog stops accepting commits, so the returned 
pointer cannot go stale.
   
   **`UnregisterTableResult`** — add `table-location`, so the endpoint that 
hands back a metadata location cannot return metadata with no base to resolve 
against.
   
   **Endpoint paths** — move the table endpoints to `/v2`. Every path whose 
response can carry table metadata moves together: `tables`, `tables/{table}`, 
`register`, and `tables/{table}/unregister`.
   
   ## Open questions
   
   **`root-manifest` is not in the ratified spec.** It comes from the adaptive 
metadata tree proposal (#16025), which is still open, so the field name and 
shape may change. Note also that `SnapshotParser` currently writes 
`manifest-list` for v4 tables, so the `oneOf` as written would reject snapshots 
this repository produces today. Whether to keep the field, defer it until 
#16025 lands, or make it purely additive is the main thing worth discussing 
here.
   
   **Moving the table endpoints to `/v2` is breaking**, and assumes v1 is no 
longer supported. Adding `/v2` alongside `/v1` is the obvious alternative if 
that assumption does not hold — that requires v1 to refuse format versions 
above 3, ideally with a typed error so clients can retry on v2 rather than 
guessing at a generic 400.
   
   **Is path versioning the right mechanism** at all, versus a header or a 
content-type parameter? The path prefix composes with the existing 
`CatalogConfig.endpoints` advertisement without new machinery, which is why it 
is used here.
   
   **Snapshot offloading** is not yet in the spec and would interact with the 
`snapshots` query parameter on `loadTable` if it lands later. Worth knowing 
whether it should be folded in before any endpoint versioning is finalised, 
since retrofitting it would mean another version.
   
   ## Testing
   
   `make lint` and `make generate` both pass; the generated model is committed 
and regeneration is idempotent.
   
   One note on the generated Python: `datamodel-codegen` expands the `Snapshot` 
`oneOf` into `Snapshot1`, `Snapshot2`, and `Snapshot(RootModel[Snapshot1 | 
Snapshot2])`. That union is a lossy rendering — it matches the first satisfying 
member, so a snapshot carrying both pointers coerces into `Snapshot1` rather 
than being rejected. The YAML schema does reject it, verified with 
`jsonschema`, so this is a codegen artifact rather than a gap in the spec.
   


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to