mirror of
https://github.com/windmill-labs/windmill.git
synced 2026-10-15 08:02:53 +00:00
A clone is three stages a workspace apart — `create_pg_database`, then `import_pg_database`, then `apply_forked_datatable` inside the fork transaction. Only the third can roll back, and `CREATE DATABASE` is not transactional, so any refusal that lives there strands a registered `wm_fork_*` that no entry names and whose name blocks the retry. That orphan has now been fixed three times, most recently reintroduced by a guard added one commit ago. Patching each new refusal into the first endpoint is not the fix; having two places that can refuse is. `ensure_datatable_is_clonable` now answers every reason a copy can be refused and returns what it resolved, and the stage that writes the entry only does the work. Also takes an ACCESS EXCLUSIVE lock before the rollback guard counts, so a role created concurrently cannot slip between the check and the drop. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BjfMkJyKzodxkobqGZ6Lqb
19 lines
973 B
SQL
19 lines
973 B
SQL
-- Refuse while the catalog holds anything. Each row is a live Postgres login with a password
|
|
-- only this table carries, so dropping it would leave credentials on the cluster that Windmill can
|
|
-- no longer disable, delete or even name — and re-applying could not recreate them, because the
|
|
-- role names would already be taken. Cleaning them up here is not an option either: dropping a
|
|
-- role means reassigning what it owns in *every* instance database, and a migration runs in one.
|
|
--
|
|
-- Delete the roles through instance settings first; that path does the cluster work.
|
|
LOCK TABLE datatable_role IN ACCESS EXCLUSIVE MODE;
|
|
|
|
DO $$
|
|
BEGIN
|
|
IF EXISTS (SELECT 1 FROM datatable_role) THEN
|
|
RAISE EXCEPTION 'Cannot roll back: % data table role(s) still exist as Postgres logins. Delete them in instance settings first, which drops them from the cluster.',
|
|
(SELECT count(*) FROM datatable_role);
|
|
END IF;
|
|
END $$;
|
|
|
|
DROP TABLE IF EXISTS datatable_role;
|