Skip to content

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

Open
mengw15 wants to merge 1 commit 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 1 commit 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. The wire DTO keeps warehouseName.

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.

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 run locally: 26/26 passed 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 on lines +21 to +25
\c texera_db

SET search_path TO texera_db;

BEGIN;
Comment thread sql/updates/38.sql
Comment on lines +32 to +35
ALTER TABLE user_warehouse
RENAME COLUMN warehouse_name TO lakekeeper_warehouse_name;

COMMIT;
Comment on lines +142 to +145
val whid: Integer = context.fetchValue(
DSL.field(
"nextval(pg_get_serial_sequence('texera_db.user_warehouse','whid'))",
classOf[Integer]
Comment on lines 80 to +81
row.getName shouldBe "mybucket"
row.getWarehouseName shouldBe s"user-$uid-mybucket"
row.getLakekeeperWarehouseName shouldBe s"user-$uid-mybucket"
Comment on lines +186 to +193
val takenWhid = getDSLContext.fetchValue(
DSL.field(
"nextval(pg_get_serial_sequence('texera_db.user_warehouse','whid'))",
classOf[Integer]
)
)
squatter.setWhid(takenWhid)
squatter.setLakekeeperWarehouseName(s"user-${sessionUser.getUid}-${takenWhid + 1}")
@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

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: @tanishqgandhi1908, @aglinxinyuan, @Neilk1021
    You can notify them by mentioning @tanishqgandhi1908, @aglinxinyuan, @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.02%. Comparing base (60300e3) to head (6333c30).
✅ All tests successful. No failed tests found.

Additional details and impacted files
@@             Coverage Diff              @@
##               main    #7754      +/-   ##
============================================
- Coverage     91.02%   91.02%   -0.01%     
  Complexity     4454     4454              
============================================
  Files          1174     1174              
  Lines         47146    47150       +4     
  Branches       5287     5287              
============================================
+ Hits          42916    42918       +2     
- Misses         2550     2552       +2     
  Partials       1680     1680              
Flag Coverage Δ *Carryforward flag
access-control-service 81.00% <ø> (ø)
agent-service 98.62% <ø> (ø) Carriedforward from 60300e3
amber 87.45% <100.00%> (-0.01%) ⬇️
computing-unit-managing-service 73.67% <ø> (ø)
config-service 86.73% <ø> (ø)
file-service 68.90% <ø> (ø)
frontend 92.59% <ø> (ø) Carriedforward from 60300e3
notebook-migration-service 83.74% <ø> (ø)
pyamber 97.57% <ø> (ø) Carriedforward from 60300e3
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

Copy link
Copy Markdown
Contributor

⚠️ Benchmark changes need a look

🟢 9 better · 🔴 5 worse · ⚪ 1 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 647 0.395 15,434/19,294/19,294 us 🔴 +26.0% / 🔴 +20.7%
🔴 bs=100 sw=10 sl=64 1,276 0.779 74,348/124,123/124,123 us 🟢 +41.4% / 🟢 -26.4%
🟢 bs=1000 sw=10 sl=64 1,543 0.942 649,509/694,362/694,362 us 🟢 +67.0% / 🟢 +47.2%
Baseline details

Latest main e80add4 from 2026-08-17T13:30:51.393Z

config metric PR latest main 7d avg Δ latest Δ 7d
bs=10 sw=10 sl=64 throughput 647 tuples/sec 722.95 tuples/sec 779.07 tuples/sec -10.5% -17.0%
bs=10 sw=10 sl=64 MB/s 0.395 MB/s 0.441 MB/s 0.476 MB/s -10.5% -16.9%
bs=10 sw=10 sl=64 p50 15,434 us 13,608 us 12,818 us +13.4% +20.4%
bs=10 sw=10 sl=64 p95 19,294 us 15,308 us 15,986 us +26.0% +20.7%
bs=10 sw=10 sl=64 p99 19,294 us 20,362 us 19,339 us -5.2% -0.2%
bs=100 sw=10 sl=64 throughput 1,276 tuples/sec 902.81 tuples/sec 1,011 tuples/sec +41.3% +26.2%
bs=100 sw=10 sl=64 MB/s 0.779 MB/s 0.551 MB/s 0.617 MB/s +41.4% +26.2%
bs=100 sw=10 sl=64 p50 74,348 us 109,799 us 100,965 us -32.3% -26.4%
bs=100 sw=10 sl=64 p95 124,123 us 116,633 us 107,295 us +6.4% +15.7%
bs=100 sw=10 sl=64 p99 124,123 us 128,023 us 115,531 us -3.0% +7.4%
bs=1000 sw=10 sl=64 throughput 1,543 tuples/sec 924.33 tuples/sec 1,049 tuples/sec +66.9% +47.1%
bs=1000 sw=10 sl=64 MB/s 0.942 MB/s 0.564 MB/s 0.64 MB/s +67.0% +47.2%
bs=1000 sw=10 sl=64 p50 649,509 us 1,080,065 us 978,248 us -39.9% -33.6%
bs=1000 sw=10 sl=64 p95 694,362 us 1,121,514 us 1,021,881 us -38.1% -32.1%
bs=1000 sw=10 sl=64 p99 694,362 us 1,140,846 us 1,050,075 us -39.1% -33.9%
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,308.89,200,128000,647,0.395,15434.05,19294.06,19294.06
1,100,10,64,20,1567.79,2000,1280000,1276,0.779,74348.05,124123.37,124123.37
2,1000,10,64,20,12960.65,20000,12800000,1543,0.942,649508.78,694361.79,694361.79

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