Repository navigation
fix(iceberg): recover empty namespace upserts on OrioleDB - #1677
ferhatelmas wants to merge 2 commits into
Conversation
There was a problem hiding this comment.
I reviewed this PR and didn't find any bugs. It adds an engine-specific fallback to namespace creation and the repo's CODEOWNERS covers these files, so a human look from the owning team would still be worthwhile.
What was reviewed:
- The
tgtypebitmask checks in the trigger query: BEFORE row triggers on INSERT/UPDATE and UPDATE statement triggers are matched correctly, and replica-only triggers are conservatively counted as unsafe. - The fallback UPDATE: parameters are bound, the schema/table name goes through
quoteIdentifier, and it filters on the same catalog_id/name/tenant scope as the upsert's conflict target. - Non-OrioleDB tables and tables with an unsafe trigger still fall through to the existing
NoSuchKeyerror.
Extended reasoning...
The change touches only createNamespace in src/storage/protocols/iceberg/pg.ts and adds unit and integration tests. When the upsert returns no row, the new code reads the table's access method and triggers from the Postgres catalog, then runs a scoped metadata-merge UPDATE, but only on OrioleDB. The SQL is parameterized and tenant-scoped, and I found no injection or cross-tenant exposure. I deferred instead of approving because the repo's CODEOWNERS (* @ supabase/storage) covers every changed file, and because this workaround depends on OrioleDB behavior that a maintainer should confirm.
There was a problem hiding this comment.
🔵 Needs a closer look
Retry safety requires actual-engine validation of OrioleDB 1.10.2’s write-skipping behavior and trigger side effects, which simulated empty-upsert tests cannot establish.
No open issues 🎉
What changed in this PR
Adds a targeted workaround for empty namespace upsert results on OrioleDB 1.10.2, allowing the Iceberg metastore to recover the namespace property merge.
Changes:
- Retries empty OrioleDB upserts with a namespace-scoped, tenant-aware update.
- Preserves
NoSuchKeywhen relevant triggers make retrying unsafe or recovery finds no row. - Adds unit and integration coverage for recovery, trigger handling, and tenant isolation.
| File | Description |
|---|---|
src/test/iceberg.test.ts |
Adds database-backed trigger and tenant-isolation tests. |
src/storage/protocols/iceberg/pg.ts |
Adds the guarded OrioleDB fallback update. |
src/storage/protocols/iceberg/pg.test.ts |
Tests recovery, query scoping, and unchanged error paths. |
Review effort: Balanced
Coverage Report for CI Build 42294994932Coverage increased (+0.05%) to 87.595%Details
Uncovered ChangesNo uncovered changes found. Coverage RegressionsNo coverage regressions found. Coverage Stats💛 - Coveralls |
c17d492 to
9e3cfa8
Compare
Signed-off-by: Ferhat Elmas <elmas.ferhat@gmail.com>
Signed-off-by: Ferhat Elmas <elmas.ferhat@gmail.com>
9e3cfa8 to
89265f9
Compare
What kind of change does this PR introduce?
Bug fix
What is the current behavior?
Creating an existing namespace merges its properties. If the upsert returns no row we return no key. An OrioleDB (1.10.2) defect can cause that empty result even when the namespace exists.
What is the new behavior?
When an OrioleDB upsert returns no row, retry the property merge with a scoped update. Keep previous no key error if a relevant trigger is enabled or the update finds no row.
Additional context
Change is workaround for OrioleDB 1.10.2 compatibility. Doesn't affect Postgres or Multigres.
orioledb/orioledb#1530