nimesh1601 opened a new pull request, #17847:
URL: https://github.com/apache/iceberg/pull/17847

   ## What & Why
   
   Metadata tables were detected from the **last part of an identifier alone** 
(`MetadataTableType.from(identifier.name())`). This caused three related 
problems:
   
   1. **A regular table that shares a metadata table name was unusable 
(#10550).** A table like `db.files` was interpreted as the `files` metadata 
table of namespace `db`, so it could not be created, loaded, or written — in 
Spark it surfaced as `Cannot write into v1 table` / appeared as a non-Iceberg 
table.
   2. **Wrong identifier in the "not found" error (#13115).** Loading 
`ns1.ns2.snapshots` when the base table `ns1.ns2` doesn't exist reported `Table 
does not exist: ns1.ns2` instead of the identifier the caller actually 
requested.
   3. **REST catalog failure on a shallow metadata identifier (#13115).** 
`loadTable("ns1", "snapshots")` fell back to loading a base table with an 
**empty namespace**, producing `Malformed request: Ambiguous URI empty segment` 
instead of a normal `NoSuchTableException`.
   
   ## Approach
   
   Introduce `MetadataTableType.from(TableIdentifier)` that treats an 
identifier as a metadata table **only when its namespace has at least two 
levels** — i.e. the base table (the identifier without its last part) still has 
a namespace. Route the catalog code through it:
   
   - `BaseMetastoreCatalog.loadMetadataTable` / `isValidMetadataIdentifier`
   - `MetadataTableUtils.hasMetadataTableName`
   - `RESTSessionCatalog.loadTable` (metadata-table fallback)
   
   and report the **requested identifier** when the base table is missing.
   
   Because all metastore-backed catalogs (Hive, JDBC, Hadoop, Glue, DynamoDB, 
Nessie, BigQuery, Snowflake, ECS, InMemory) extend `BaseMetastoreCatalog`, they 
inherit the fix; `RESTSessionCatalog` is the only catalog that reimplements 
`loadTable`, so it gets the equivalent change. Spark/Flink use explicit `$`/`#` 
delimiters and are unaffected.
   
   | Identifier | Before | After |
   |---|---|---|
   | `db.files` (real table, 1-level ns) | hijacked as metadata of `db` | 
regular table `db.files` |
   | `ns1.ns2.snapshots`, base missing | `Table does not exist: ns1.ns2` | 
`Table does not exist: ns1.ns2.snapshots` |
   | `ns1.snapshots` via REST | `Ambiguous URI empty segment` | clean 
`NoSuchTableException` |
   | `db.tbl.snapshots` (normal metadata table) | works | works (unchanged) |
   
   ## Behavior change / limitation
   
   Metadata tables of a **root-namespace (empty-namespace) base table** 
accessed via dotted syntax (e.g. `tbl.snapshots` where `tbl` lives at the 
catalog root) are no longer recognized — a table sharing a metadata name in a 
single-level namespace now wins. This ambiguity is inherent (`X.snapshots` 
can't mean both) and matches the direction agreed in the prior PRs; it is not 
reachable on REST, which rejects empty-namespace identifiers.
   
   ## Tests
   
   - New `TestMetadataTableType` unit tests for `from(TableIdentifier)`.
   - New parameterized `CatalogTests.tableSharingMetadataTableName` (all 16 
metadata-table types × `{ns, ns1.ns2}`) covering create/load of a table that 
shares a metadata name, resolution of its own metadata table, and correct "not 
found" messaging. Inherited by every catalog suite; verified on InMemory, JDBC, 
Hadoop, and REST. `spotlessCheck` and `:iceberg-core:revapi` pass.
   
   ## Credits
   
   Builds on prior work by @nastra in #11963 and @adutra in #13223, which 
stalled via the stale bot.
   
   Closes #10550
   Closes #13115
   
   


-- 
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