Skip to content

fix(iceberg): recover empty namespace upserts on OrioleDB - #1677

Open
ferhatelmas wants to merge 2 commits into
masterfrom
ferhat/iceberg-orioledb
Open

ferhatelmas wants to merge 2 commits into
masterfrom
ferhat/iceberg-orioledb

Conversation

@ferhatelmas

@ferhatelmas ferhatelmas commented Nov 6, 2026 •

Copy link
Copy Markdown
Member

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

@ferhatelmas
ferhatelmas requested a review from a team as a code owner November 6, 2026 20:02
Copilot AI balanced review requested due to automatic review settings November 6, 2026 20:02

@claude claude Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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 tgtype bitmask 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 NoSuchKey error.
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.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔵 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 NoSuchKey when 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

@coveralls

coveralls commented Nov 6, 2026 •

Copy link
Copy Markdown

Coverage Report for CI Build 42294994932

Coverage increased (+0.05%) to 87.595%

Details

  • Coverage increased (+0.05%) from the base build.
  • Patch coverage: 16 of 16 lines across 2 files are fully covered (100%).
  • No coverage regressions found.

Uncovered Changes

No uncovered changes found.

Coverage Regressions

No coverage regressions found.


Coverage Stats

Coverage Status
Relevant Lines: 16005
Covered Lines: 14459
Line Coverage: 90.34%
Relevant Branches: 10179
Covered Branches: 8477
Branch Coverage: 83.28%
Branches in Coverage %: Yes
Coverage Strength: 1297.53 hits per line

💛 - Coveralls

@ferhatelmas
ferhatelmas force-pushed the ferhat/iceberg-orioledb branch from c17d492 to 9e3cfa8 Compare November 6, 2026 21:12
Signed-off-by: Ferhat Elmas <elmas.ferhat@gmail.com>
Signed-off-by: Ferhat Elmas <elmas.ferhat@gmail.com>
@ferhatelmas
ferhatelmas force-pushed the ferhat/iceberg-orioledb branch from 9e3cfa8 to 89265f9 Compare November 6, 2026 21:13

This branch has not been deployed

No deployments
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.

3 participants