Skip to content

feat(amber): decouple the Lakekeeper catalog name from the user-facing name - #7754

Open
mengw15 wants to merge 4 commits into
apache:mainfrom
mengw15:feat/7753-decouple-catalog-name
Open

feat(amber): decouple the Lakekeeper catalog name from the user-facing name#7754
mengw15 wants to merge 4 commits into
apache:mainfrom
mengw15:feat/7753-decouple-catalog-name

Conversation

@mengw15

@mengw15 mengw15 commented Aug 18, 2026

Copy link
Copy Markdown
Contributor

What changes were proposed in this PR?

WarehouseResource derived the Lakekeeper catalog name from the user-facing name: user-<uid>-<name>. That one string is simultaneously the Lakekeeper warehouse identifier, the REST catalog URL prefix, the S3 key prefix, and a component of every result URI stored by executions that wrote into the warehouse — so the display name was frozen at creation and a warehouse could never be renamed. Computing units rename freely precisely because their name is pure display metadata; cuid is the identity everywhere else.

  • Derive the catalog name from the row id: user-<uid>-<whid>. The id is drawn from the table's own sequence before the Lakekeeper call, so the creation order is unchanged — Lakekeeper first, DB row after, with the existing compensating delete — and no schema or nullability change is needed. The sequence is resolved through pg_get_serial_sequence rather than named literally, because the generated sequence name is not a stable contract (the jOOQ output already carries both user_warehouse_whid_seq and ..._seq1 from a re-created table).
  • name stays the per-user-unique display name, now free to change; a rename endpoint mirroring computing-unit rename becomes a straightforward follow-up.
  • Rename the column: user_warehouse.warehouse_namelakekeeper_warehouse_name, matching its sibling lakekeeper_warehouse_id.
  • Carry that naming into the code: resolveWarehouseNameresolveLakekeeperWarehouseName and the DTO field warehouseNamelakekeeperWarehouseName, so the column, the method and the field all say which name they hold. WorkflowContext.warehouse keeps its name — it feeds a chain of parameters all called warehouse (VFSURIFactory here and in Python), none of which sit beside a display name.
  • Tell the two warehouse ids apart: warehouseId named both the user_warehouse row id we pick (an Int) and the id Lakekeeper assigns its own entity (a UUID), so a call site had to be read type-first. They are now whid and lakekeeperWarehouseId, matching their columns; anything prefixed lakekeeper is an identifier owned by that system. WorkflowExecuteRequest.warehouseId becomes whid as part of this — it is a wire field, but nothing sends it yet (the warehouse frontend is an unmerged draft), so renaming now costs nothing while doing it later would change a live contract.

Deviation from the issue, and why. The issue proposed user-<uid>-<8 random hex>, on the reasoning that deriving from whid "would need the DB row before the Lakekeeper create — an order flip plus a nullable column". Taking the id from the sequence up front avoids both, so that cost does not apply. Doing so also removes the collision-retry path the random suffix required: a 32-bit suffix collides often enough to need one, and that retry would have to recognise Lakekeeper's name-conflict error — the same brittle response-parsing #7742 just had to harden. A sequence-derived name cannot collide, and user-7-42 points straight at whid = 42 when tracing storage back to a row.

The migration is guarded. texera_ddl.sql now creates the column under its new name, so on a fresh database the column to rename was never there — and the local-dev replay of unrecorded change sets tolerates only "already exists", so an unguarded RENAME COLUMN aborts up with "column warehouse_name does not exist". 38.sql guards the rename with the same existence check 33.sql uses, verified against a live database both ways: a schema already holding lakekeeper_warehouse_name is a clean no-op, one still holding warehouse_name is renamed.

On "zero migration". No data migration is needed — the table is empty in every deployment while the flag is off — but the column rename still needs a schema migration (sql/updates/38.sql): texera_ddl.sql is CREATE TABLE IF NOT EXISTS, so an existing database keeps the old column, and jOOQ generates its code from the live database. Without the migration, existing databases would generate WAREHOUSE_NAME and fail to compile against this change.

Any related issues, documentation, discussions?

Closes #7753. Part of #6870, follow-up to #6932. Worth settling while the flag is off everywhere: once real data exists under name-derived prefixes, this becomes a migration project.

How was this PR tested?

  • WarehouseResourceSpec now asserts the catalog name equals user-<uid>-<whid> and does not contain the display name, pinning the decoupling itself.
  • New case: deleting a warehouse and recreating it with the same display name mints a different catalog name — a reused name would let a new warehouse inherit an old one's storage path.
  • The two compensation cases previously created their conflict by pre-claiming user-<uid>-<name>, which this change makes unreachable. They now draw an id from the sequence, set it explicitly on the squatter row (so storing it consumes nothing further), and squat on the next one — so they still exercise the UNIQUE conflict, and additionally pin the "catalog name = uid + sequence id" rule.
  • WarehouseResourceSpec, WorkflowServiceWarehouseSpec, ExecutionsMetadataPersistServiceSpec, LakekeeperClientSpec and WorkflowServiceSpec run locally: 38/38 passed, plus UserWarehouseSpec 4/4, against a database migrated with sql/updates/38.sql and jOOQ regenerated from it; WorkflowExecutionService/scalafmtCheck (main + Test) passes.

Was this PR authored or co-authored using generative AI tooling?

Generated-by: Claude Code (claude-opus-4-8)

…g name

The catalog name was derived from the display name: user-<uid>-<name>.
That one string is also the REST catalog prefix, the S3 key prefix and a
component of every result URI an execution wrote into the warehouse, so
the display name was frozen at creation and a warehouse could never be
renamed -- unlike a computing unit, whose name is pure display metadata
because cuid is the identity everywhere else.

Derive the catalog name from the row id instead: user-<uid>-<whid>. The
id is drawn from the table's sequence before the Lakekeeper call, so the
creation order is unchanged (Lakekeeper first, row after, with the
compensating delete) and no schema or nullability change is needed. The
sequence is resolved through pg_get_serial_sequence rather than named
literally, because the generated name is not a stable contract -- the
jOOQ output already carries both user_warehouse_whid_seq and ..._seq1.

A sequence-derived name also cannot collide, so it needs no retry path.
A random suffix would have needed one, and that retry would have to
recognise Lakekeeper's name-conflict error -- the same brittle response
parsing apache#7742 just had to harden.

Rename user_warehouse.warehouse_name to lakekeeper_warehouse_name to sit
beside lakekeeper_warehouse_id; the table already has its own `name`
column, and the value is no longer a name in any user-facing sense. The
wire DTO keeps warehouseName. The table is empty in every deployment
while the flag is off, so the rename carries no data -- but it still
needs a schema migration (sql/updates/38.sql): texera_ddl.sql is CREATE
TABLE IF NOT EXISTS, and jOOQ generates from the live database.

Closes apache#7753.
@mengw15
mengw15 requested a balanced review from Copilot August 18, 2026 07:30

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.

Pull request overview

Warning

Copilot couldn't run its full agentic review because it didn't start before the timeout. Make sure your repository has a runner available, or add a copilot-code-review.yml file specifying one with the runs-on attribute. See the docs for more details.

This PR decouples the Lakekeeper catalog/warehouse identifier from the user-facing warehouse display name by deriving the Lakekeeper name from the user_warehouse.whid sequence ID, enabling future warehouse renames without affecting storage/catalog paths.

Changes:

  • Rename user_warehouse.warehouse_name to lakekeeper_warehouse_name and add a Liquibase migration.
  • Update warehouse creation to pre-allocate whid from the sequence and mint user-<uid>-<whid> for Lakekeeper.
  • Update affected services and tests to use lakekeeper_warehouse_name and assert the new naming behavior.

Reviewed changes

Copilot reviewed 10 out of 10 changed files in this pull request and generated 5 comments.

Show a summary per file
File Description
sql/updates/38.sql Adds migration to rename the warehouse name column for the new semantics.
sql/texera_ddl.sql Updates base DDL to use lakekeeper_warehouse_name column name.
sql/changelog.xml Registers migration 38 in Liquibase changelog.
common/dao/src/test/scala/org/apache/texera/dao/UserWarehouseSpec.scala Switches test to column rename (but still asserts old name semantics).
amber/src/test/scala/org/apache/texera/web/service/WorkflowServiceWarehouseSpec.scala Updates test inserts to use lakekeeper_warehouse_name.
amber/src/test/scala/org/apache/texera/web/service/ExecutionsMetadataPersistServiceSpec.scala Updates test inserts to use lakekeeper_warehouse_name.
amber/src/test/scala/org/apache/texera/web/resource/dashboard/user/workflow/WorkflowExecutionsResourceSpec.scala Updates test inserts to use lakekeeper_warehouse_name.
amber/src/test/scala/org/apache/texera/web/resource/dashboard/user/warehouse/WarehouseResourceSpec.scala Updates assertions to user-<uid>-<whid> and adds coverage for name reuse behavior.
amber/src/main/scala/org/apache/texera/web/service/WorkflowService.scala Reads Lakekeeper warehouse name from the renamed column.
amber/src/main/scala/org/apache/texera/web/resource/dashboard/user/warehouse/WarehouseResource.scala Mints Lakekeeper name from pre-allocated whid sequence value and persists it to DB.

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment thread sql/updates/38.sql
Comment thread sql/updates/38.sql Outdated
@mengw15 mengw15 self-assigned this Aug 18, 2026
@github-actions github-actions Bot added feature engine ddl-change Changes to the TexeraDB DDL common labels Aug 18, 2026
@github-actions

github-actions Bot commented Aug 18, 2026

Copy link
Copy Markdown
Contributor

Automated Reviewer Suggestions

Based on the git blame history of the changed files, we recommend the following reviewers:

  • Contributors with relevant context: @aglinxinyuan, @tanishqgandhi1908, @Neilk1021
    You can notify them by mentioning @aglinxinyuan, @tanishqgandhi1908, @Neilk1021 in a comment.

@codecov-commenter

codecov-commenter commented Aug 18, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 91.03%. Comparing base (60300e3) to head (ff3f87a).
⚠️ Report is 2 commits behind head on main.

Additional details and impacted files
@@             Coverage Diff              @@
##               main    #7754      +/-   ##
============================================
+ Coverage     91.02%   91.03%   +0.01%     
- Complexity     4454     4458       +4     
============================================
  Files          1174     1174              
  Lines         47146    47156      +10     
  Branches       5287     5287              
============================================
+ Hits          42916    42930      +14     
  Misses         2550     2550              
+ Partials       1680     1676       -4     
Flag Coverage Δ *Carryforward flag
access-control-service 81.00% <ø> (ø)
agent-service 98.62% <ø> (ø) Carriedforward from 36293cc
amber 87.48% <100.00%> (+0.03%) ⬆️
computing-unit-managing-service 73.67% <ø> (ø)
config-service 86.73% <ø> (ø)
file-service 68.90% <ø> (ø)
frontend 92.59% <ø> (ø) Carriedforward from 36293cc
notebook-migration-service 83.74% <ø> (ø)
pyamber 97.57% <ø> (ø) Carriedforward from 36293cc
workflow-compiling-service 77.19% <ø> (ø)

*This pull request uses carry forward flags. Click here to find out more.

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@github-actions

github-actions Bot commented Aug 18, 2026

Copy link
Copy Markdown
Contributor

⚠️ Benchmark changes need a look

🟢 6 better · 🔴 7 worse · ⚪ 2 noise (<±5%) · 0 without baseline

CI benchmark results are noisy; treat <±5% as noise unless repeated.

Dashboard · Run

config throughput MB/s latency max Δ latest / 7d
🔴 bs=10 sw=10 sl=64 505 0.308 20,702/31,261/31,261 us 🔴 +132.5% / 🔴 +92.7%
🔴 bs=100 sw=10 sl=64 1,091 0.666 83,518/140,827/140,827 us 🔴 +42.7% / 🔴 +26.8%
🟢 bs=1000 sw=10 sl=64 1,408 0.86 707,370/784,481/784,481 us 🟢 +25.4% / 🟢 +41.7%
Baseline details

Latest main fb9f4e2 from 2026-08-18T14:33:07.467Z

config metric PR latest main 7d avg Δ latest Δ 7d
bs=10 sw=10 sl=64 throughput 505 tuples/sec 835.59 tuples/sec 743.3 tuples/sec -39.6% -32.1%
bs=10 sw=10 sl=64 MB/s 0.308 MB/s 0.51 MB/s 0.454 MB/s -39.6% -32.1%
bs=10 sw=10 sl=64 p50 20,702 us 11,611 us 13,204 us +78.3% +56.8%
bs=10 sw=10 sl=64 p95 31,261 us 13,446 us 16,220 us +132.5% +92.7%
bs=10 sw=10 sl=64 p99 31,261 us 17,885 us 19,867 us +74.8% +57.3%
bs=100 sw=10 sl=64 throughput 1,091 tuples/sec 1,091 tuples/sec 959.52 tuples/sec +0.0% +13.7%
bs=100 sw=10 sl=64 MB/s 0.666 MB/s 0.666 MB/s 0.586 MB/s +0.0% +13.7%
bs=100 sw=10 sl=64 p50 83,518 us 89,031 us 103,974 us -6.2% -19.7%
bs=100 sw=10 sl=64 p95 140,827 us 98,690 us 111,036 us +42.7% +26.8%
bs=100 sw=10 sl=64 p99 140,827 us 101,358 us 118,982 us +38.9% +18.4%
bs=1000 sw=10 sl=64 throughput 1,408 tuples/sec 1,123 tuples/sec 994.68 tuples/sec +25.3% +41.6%
bs=1000 sw=10 sl=64 MB/s 0.86 MB/s 0.686 MB/s 0.607 MB/s +25.4% +41.7%
bs=1000 sw=10 sl=64 p50 707,370 us 888,033 us 1,011,206 us -20.3% -30.0%
bs=1000 sw=10 sl=64 p95 784,481 us 934,711 us 1,055,603 us -16.1% -25.7%
bs=1000 sw=10 sl=64 p99 784,481 us 961,294 us 1,084,808 us -18.4% -27.7%
Raw CSV
config_idx,batch_size,schema_width,string_len,num_batches,total_ms,total_tuples,total_bytes,tuples_per_sec,mb_per_sec,lat_p50_us,lat_p95_us,lat_p99_us
0,10,10,64,20,396.30,200,128000,505,0.308,20701.72,31261.19,31261.19
1,100,10,64,20,1833.81,2000,1280000,1091,0.666,83518.46,140826.80,140826.80
2,1000,10,64,20,14201.52,20000,12800000,1408,0.860,707369.61,784480.68,784480.68

The column rename left the same ambiguity in the code: a method called
resolveWarehouseName and a DTO field called warehouseName both carry the
Lakekeeper catalog name while sitting next to a `name` that means the
display name. Rename them to resolveLakekeeperWarehouseName and
lakekeeperWarehouseName, so all three -- column, method, DTO field --
say what they hold.

WorkflowContext.warehouse keeps its name: it feeds a chain of parameters
and fields all called `warehouse` (VFSURIFactory here and its Python
counterpart), none of which sit beside a display name, so renaming only
this end would break that consistency instead of removing ambiguity. A
comment records what it holds. LakekeeperClient's own `warehouseName`
parameters likewise stay -- inside that client the term is unambiguous.

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.

Pull request overview

Copilot reviewed 12 out of 12 changed files in this pull request and generated 1 comment.

Suppressed comments (1)

amber/src/main/scala/org/apache/texera/web/resource/dashboard/user/warehouse/WarehouseResource.scala:60

  • Renaming this case-class parameter changes the serialized field returned by both POST /warehouse and GET /warehouse/status to lakekeeperWarehouseName. The PR description explicitly says the wire DTO keeps warehouseName, so this introduces an API-contract break unrelated to the database-column rename. Keep or explicitly map the JSON property to warehouseName and adjust the Scala-facing tests accordingly.
      lakekeeperWarehouseName: String,

Comment thread sql/updates/38.sql Outdated
texera_ddl.sql already creates the column under its new name, so on a
fresh local-dev database the rename hit a column that was never there and
aborted `up`: the replay of unrecorded change sets only tolerates
"already exists", and PostgreSQL reports "column warehouse_name does not
exist". Guard it with the same existence check 33.sql uses for its
rename. Verified against a live database both ways -- a schema already
holding lakekeeper_warehouse_name is left untouched, one still holding
warehouse_name is renamed.

Also take the qualified table and column names for the sequence lookup
from the jOOQ metadata instead of a literal texera_db.user_warehouse, so
it follows whatever schema the generated code targets, and rename
UserWarehouseSpec's fixture parameter (with a note) since the old value
read like a naming rule the DAO layer does not own.
@mengw15
mengw15 force-pushed the feat/7753-decouple-catalog-name branch from ecb5aff to 36293cc Compare August 18, 2026 20:12
`warehouseId` named two unrelated things: the user_warehouse row id we
pick (an Int, the table's whid) and the id Lakekeeper assigns its own
warehouse entity (a UUID, stored in lakekeeper_warehouse_id). The two
never mean the same thing, so reading a call site required checking the
type first.

Name them after what they identify: `whid` for ours, matching the column
and the DashboardWarehouse field, and `lakekeeperWarehouseId` for
Lakekeeper's, matching its column and sitting beside
lakekeeperWarehouseName. Anything prefixed `lakekeeper` is now an
identifier owned by that system.

WorkflowExecuteRequest.warehouseId becomes `whid` as part of this. It is
a wire field, but nothing sends it yet -- the warehouse frontend is still
an unmerged draft -- so renaming it now costs nothing, whereas doing it
after that lands would mean changing a live contract.
@mengw15
mengw15 requested a review from kunwp1 August 18, 2026 20:24
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

common ddl-change Changes to the TexeraDB DDL engine feature

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[BYO-S3] Decouple the Lakekeeper warehouse name from the user-facing name

3 participants