diff --git a/backend/.sqlx/query-e34f4d6a151cc791960c61197a4b00ea9db2f6ee47dc154faefe4c06c41cf1cf.json b/backend/.sqlx/query-fc2081d9077c743bc3978ae1905db558549b2356fc6ac8f0557aa40e1345ff46.json similarity index 52% rename from backend/.sqlx/query-e34f4d6a151cc791960c61197a4b00ea9db2f6ee47dc154faefe4c06c41cf1cf.json rename to backend/.sqlx/query-fc2081d9077c743bc3978ae1905db558549b2356fc6ac8f0557aa40e1345ff46.json index dcacf92573..27cb37b876 100644 --- a/backend/.sqlx/query-e34f4d6a151cc791960c61197a4b00ea9db2f6ee47dc154faefe4c06c41cf1cf.json +++ b/backend/.sqlx/query-fc2081d9077c743bc3978ae1905db558549b2356fc6ac8f0557aa40e1345ff46.json @@ -1,6 +1,6 @@ { "db_name": "PostgreSQL", - "query": "SELECT d.email IS NULL as \"legacy!\", COALESCE(u.username, p.username) as username\n FROM draft d\n LEFT JOIN usr u ON u.workspace_id = d.workspace_id AND u.email = d.email\n LEFT JOIN password p ON p.email = d.email AND p.super_admin = true\n WHERE d.workspace_id = $1 AND d.path = $2 AND d.typ::text = ANY($3::text[])\n -- A row of the consuming owner's that a move brought here from the very path\n -- being renamed is the draft this deploy carries, not an item in its way. Any\n -- other row of theirs is a second item and still collides.\n AND ($4::text IS NULL OR d.email IS DISTINCT FROM $4 OR NOT EXISTS (\n SELECT 1 FROM draft_move m\n WHERE m.workspace_id = $1 AND m.typ::text = ANY($3::text[])\n AND m.old_path = $5 AND m.new_path = $2\n AND (m.email IS NULL OR m.email = $4)\n ))\n ORDER BY 2", + "query": "SELECT d.email IS NULL as \"legacy!\", COALESCE(u.username, p.username) as username\n FROM draft d\n LEFT JOIN usr u ON u.workspace_id = d.workspace_id AND u.email = d.email\n LEFT JOIN password p ON p.email = d.email AND p.super_admin = true\n WHERE d.workspace_id = $1 AND d.path = $2 AND d.typ::text = ANY($3::text[])\n -- A row a move already brought here from the very path being renamed is this\n -- rename's own draft, not an item in its way: the record says which owners\n -- it moved (all of them for an item move, one for a draft-only move). Any\n -- other row is a second item and still collides.\n AND NOT EXISTS (\n SELECT 1 FROM draft_move m\n WHERE m.workspace_id = $1 AND m.typ::text = ANY($3::text[])\n AND m.old_path = $4 AND m.new_path = $2\n AND (m.email IS NULL OR m.email IS NOT DISTINCT FROM d.email)\n )\n ORDER BY 2", "describe": { "columns": [ { @@ -19,7 +19,6 @@ "Text", "Text", "TextArray", - "Text", "Text" ] }, @@ -28,5 +27,5 @@ null ] }, - "hash": "e34f4d6a151cc791960c61197a4b00ea9db2f6ee47dc154faefe4c06c41cf1cf" + "hash": "fc2081d9077c743bc3978ae1905db558549b2356fc6ac8f0557aa40e1345ff46" } diff --git a/backend/windmill-api-flows/src/flows.rs b/backend/windmill-api-flows/src/flows.rs index 8d9b222199..92d291344b 100644 --- a/backend/windmill-api-flows/src/flows.rs +++ b/backend/windmill-api-flows/src/flows.rs @@ -1426,7 +1426,6 @@ async fn update_flow( &[UserDraftItemKind::Flow], flow_path, &nf.path, - (!nf.skip_draft_deletion.unwrap_or(false)).then_some(authed.email.as_str()), ) .await?; } diff --git a/backend/windmill-api-scripts/src/scripts.rs b/backend/windmill-api-scripts/src/scripts.rs index f0e11fe964..1eebfc1389 100644 --- a/backend/windmill-api-scripts/src/scripts.rs +++ b/backend/windmill-api-scripts/src/scripts.rs @@ -2322,7 +2322,6 @@ async fn create_script_internal<'c>( &[UserDraftItemKind::Script], p_path, &ns.path, - (!skip_draft_deletion).then_some(authed.email.as_str()), ) .await?; } diff --git a/backend/windmill-api/src/apps.rs b/backend/windmill-api/src/apps.rs index bfc554e81b..9931198a75 100644 --- a/backend/windmill-api/src/apps.rs +++ b/backend/windmill-api/src/apps.rs @@ -3770,7 +3770,6 @@ async fn update_app_internal<'a>( &[UserDraftItemKind::App, UserDraftItemKind::RawApp], path, &npath, - (!ns.skip_draft_deletion.unwrap_or(false)).then_some(authed.email.as_str()), ) .await?; } diff --git a/backend/windmill-common/src/user_drafts.rs b/backend/windmill-common/src/user_drafts.rs index 5aab500942..99ec3cce5e 100644 --- a/backend/windmill-common/src/user_drafts.rs +++ b/backend/windmill-common/src/user_drafts.rs @@ -662,16 +662,15 @@ pub async fn delete_own_draft_for_path( /// /// A draft already at `new_path` occupies it the way a deployed item does, so the move is /// refused with `BadRequest` inside the deploy's transaction, refusing the rename itself: -/// moving onto it would merge two items or strand the row that lost. `consumed_by` names -/// the owner whose row there this deploy consumes, which is the draft being deployed after -/// an earlier move carried it, and so cannot be in its own way. +/// moving onto it would merge two items or strand the row that lost. A row a `draft_move` +/// record already brought there from `old_path` is this rename's own draft and does not +/// count: deploying it would otherwise be refused against itself, with no way out. pub async fn move_drafts_for_path( tx: &mut sqlx::Transaction<'_, sqlx::Postgres>, w_id: &str, kinds: &[UserDraftItemKind], old_path: &str, new_path: &str, - consumed_by: Option<&str>, ) -> Result<()> { let typs = kinds.iter().map(|k| k.as_str()).collect::>(); // Named by workspace username, as the editors name other users' drafts: the @@ -682,20 +681,20 @@ pub async fn move_drafts_for_path( LEFT JOIN usr u ON u.workspace_id = d.workspace_id AND u.email = d.email LEFT JOIN password p ON p.email = d.email AND p.super_admin = true WHERE d.workspace_id = $1 AND d.path = $2 AND d.typ::text = ANY($3::text[]) - -- A row of the consuming owner's that a move brought here from the very path - -- being renamed is the draft this deploy carries, not an item in its way. Any - -- other row of theirs is a second item and still collides. - AND ($4::text IS NULL OR d.email IS DISTINCT FROM $4 OR NOT EXISTS ( + -- A row a move already brought here from the very path being renamed is this + -- rename's own draft, not an item in its way: the record says which owners + -- it moved (all of them for an item move, one for a draft-only move). Any + -- other row is a second item and still collides. + AND NOT EXISTS ( SELECT 1 FROM draft_move m WHERE m.workspace_id = $1 AND m.typ::text = ANY($3::text[]) - AND m.old_path = $5 AND m.new_path = $2 - AND (m.email IS NULL OR m.email = $4) - )) + AND m.old_path = $4 AND m.new_path = $2 + AND (m.email IS NULL OR m.email IS NOT DISTINCT FROM d.email) + ) ORDER BY 2"#, w_id, new_path, &typs as &[&str], - consumed_by, old_path, ) .fetch_all(&mut **tx)