mirror of
https://gh-proxy.org/https://github.com/klinsmaya/multica.git
synced 2026-11-10 10:26:46 +08:00
* feat(server): add the duplicate-mark column and keep it correct (MUL-7349) Expand step for marking an issue as a duplicate of another. A duplicate is an ordinary cancelled issue that records which issue it duplicates; there is no duplicate status. This release adds the column and the code that maintains it, and nothing writes a pointer yet. - A mark survives only a write that leaves an already cancelled issue cancelled. Every other write drops it, so reopening removes a mark and cancelling again does not bring one back. Both status-writing queries carry the rule, which covers the UI, batch updates and background writers. - Deleting an issue clears the pointers of its duplicates in the same transaction, the way deleting a parent detaches its children. Shipping this before marking is what makes marking safe to roll back: the release a rollback lands on already clears the pointer. Tests seed a mark the way the next release will write it. Co-authored-by: multica-agent <[email protected]> * fix(server): compute issue updates from the locked row (MUL-7349) UpdateIssue built its next_* values in a CTE that read the row before the UPDATE took its row lock. A write that waited there behind another transaction then resumed with the values it had read before the wait and wrote them back, so an ordinary priority or status edit could restore a duplicate mark the other transaction had just cleared — by reopening the issue or by deleting its original — and did_change/did_activity were decided against the pre-wait row as well. Lock the row in the CTE instead, so every computed value comes from the row the statement is about to write. Tests hold the clearing transaction open and wait for the update to block on the row lock, so the interleaving is deterministic; both fail without this change. Co-authored-by: multica-agent <[email protected]> --------- Co-authored-by: J <[email protected]> Co-authored-by: multica-agent <[email protected]>
26 lines
1.4 KiB
SQL
26 lines
1.4 KiB
SQL
-- Record which issue a cancelled issue duplicates (MUL-7349).
|
|
--
|
|
-- A duplicate is an ordinary cancelled issue with a pointer to the issue it
|
|
-- duplicates; there is no duplicate status. The pointer only lives while the
|
|
-- issue is cancelled: a write that leaves an already cancelled issue cancelled
|
|
-- keeps it, and every other write drops it. Reopening an issue is therefore how
|
|
-- a mark is removed, and cancelling it again does not bring the mark back.
|
|
--
|
|
-- This is the expand half of the feature: the column ships with the code that
|
|
-- maintains it, and nothing writes a pointer yet. A later release adds marking.
|
|
-- That order is what makes marking safe to roll back — the release it rolls
|
|
-- back to already clears the pointer on reopen and on delete, so no issue is
|
|
-- left carrying a mark the product no longer honours.
|
|
--
|
|
-- No foreign key (repository rule). Deleting the original clears the pointers
|
|
-- to it in the same transaction, the way deleting a parent detaches children.
|
|
--
|
|
-- A nullable column with no default is a catalog-only change, so this does not
|
|
-- rewrite the table. Bound lock acquisition so the ALTER fails fast and retries
|
|
-- on the next run instead of queueing an ACCESS EXCLUSIVE lock in front of
|
|
-- every issue query.
|
|
SET LOCAL lock_timeout = '2s';
|
|
SET LOCAL statement_timeout = '10s';
|
|
|
|
ALTER TABLE issue ADD COLUMN IF NOT EXISTS duplicate_of_issue_id UUID;
|