From af0477c16f2944df0ccd8fbd11747d0711cc2804 Mon Sep 17 00:00:00 2001 From: Diego Imbert Date: Sat, 5 Sep 2026 08:04:34 +0200 Subject: [PATCH] fix(datatables): a workspace-id change leaves one owner for each login MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The rename copies the whole config, so the archived id and the live one both named the same generated logins — and deleting the archive planned drops for logins the renamed workspace was still using, destroying their grants. The archived copy stops naming them: it is kept for reference, and a reference needs no credentials. The renamed workspace keeps working, since resolution uses the stored `pg_rolename` rather than the generated one, and its next permissions save finds the stored name no longer matches what this workspace id generates and renames the login to match — under the ownership proof that rename already carries. Also: a pending row action now has to name the same data table the manager is open on, not merely fail to differ from it. `undefined` — a plain postgres resource, or a DuckLake — is somewhere else too, and a matching schema and table name there would have run it. Both drawers drop what is pending when they close. Co-Authored-By: Claude Opus 5 (1M context) Claude-Session: https://claude.ai/code/session_01S5arH3G2Sa1Qqm32veJQ1n --- ...63139318a1d1a61af5ec7032353acd5e89027ae8dd.json | 14 ++++++++++++++ frontend/src/lib/components/DBManager.svelte | 4 +++- frontend/src/lib/components/DBManagerDrawer.svelte | 4 ++++ .../raw_apps/RawAppDataTableDrawer.svelte | 3 +++ 4 files changed, 24 insertions(+), 1 deletion(-) create mode 100644 backend/.sqlx/query-f42f40af69449bdd47103c63139318a1d1a61af5ec7032353acd5e89027ae8dd.json diff --git a/backend/.sqlx/query-f42f40af69449bdd47103c63139318a1d1a61af5ec7032353acd5e89027ae8dd.json b/backend/.sqlx/query-f42f40af69449bdd47103c63139318a1d1a61af5ec7032353acd5e89027ae8dd.json new file mode 100644 index 0000000000..6b4f7f930c --- /dev/null +++ b/backend/.sqlx/query-f42f40af69449bdd47103c63139318a1d1a61af5ec7032353acd5e89027ae8dd.json @@ -0,0 +1,14 @@ +{ + "db_name": "PostgreSQL", + "query": "UPDATE workspace_settings\n SET datatable = jsonb_set(datatable, '{datatables}', COALESCE((\n SELECT jsonb_object_agg(key, value - 'permissions')\n FROM jsonb_each(datatable->'datatables')\n ), '{}'::jsonb))\n WHERE workspace_id = $1 AND jsonb_typeof(datatable->'datatables') = 'object'", + "describe": { + "columns": [], + "parameters": { + "Left": [ + "Text" + ] + }, + "nullable": [] + }, + "hash": "f42f40af69449bdd47103c63139318a1d1a61af5ec7032353acd5e89027ae8dd" +} diff --git a/frontend/src/lib/components/DBManager.svelte b/frontend/src/lib/components/DBManager.svelte index af156ff939..73da09d770 100644 --- a/frontend/src/lib/components/DBManager.svelte +++ b/frontend/src/lib/components/DBManager.svelte @@ -458,7 +458,9 @@ // Landed somewhere else: the target may have failed to load, or the user // may have moved on. Either way this action was asked for on another // database, and dropping a schema is not a thing to do by approximation. - if (currentDatatable !== undefined && req.datatable !== currentDatatable) { + // `undefined` is somewhere else too — a plain postgres resource or a + // DuckLake — so the two must be equal, not merely not-known-to-differ. + if (req.datatable !== currentDatatable) { pendingAction = undefined return } diff --git a/frontend/src/lib/components/DBManagerDrawer.svelte b/frontend/src/lib/components/DBManagerDrawer.svelte index d07ed95ce9..4d81a7caed 100644 --- a/frontend/src/lib/components/DBManagerDrawer.svelte +++ b/frontend/src/lib/components/DBManagerDrawer.svelte @@ -131,6 +131,10 @@ if (!open) { expand = false uriState.closeDrawer() + // An action asked for on one data table must not be waiting when the + // drawer is next opened on another database — or on no data table at + // all, where nothing would recognise it as foreign. + pendingAction = undefined } }) diff --git a/frontend/src/lib/components/raw_apps/RawAppDataTableDrawer.svelte b/frontend/src/lib/components/raw_apps/RawAppDataTableDrawer.svelte index 4bce2d30d1..08d5043535 100644 --- a/frontend/src/lib/components/raw_apps/RawAppDataTableDrawer.svelte +++ b/frontend/src/lib/components/raw_apps/RawAppDataTableDrawer.svelte @@ -160,6 +160,9 @@ export function closeDrawer() { open = false dbManagerContent?.clearReplResult() + // Same reason as its sibling: an action outlives the data table it was + // asked for otherwise. + pendingAction = undefined } function handleAddTables() {