fix(db): claim_next_mutation works on MySQL — derived-table workaround
MySQL ERROR 1093 forbids referencing the UPDATE target inside a subquery; the existing UPDATE ... WHERE id = (SELECT id FROM topology_mutations ...) form blew up on every mutation claim under the MySQL backend, so no mutation ever progressed past pending. Wrap the inner SELECT in a derived table (SELECT id FROM (...) AS _next). MySQL materialises the derived rowset before applying the UPDATE, sidestepping 1093. SQLite accepts both forms, so the single-statement atomic claim semantics are preserved on both backends — racing watchers still serialise correctly.
This commit is contained in:
@@ -1711,15 +1711,21 @@ class SQLModelRepository(BaseRepository):
|
|||||||
# oldest pending row; the outer UPDATE re-checks state so a
|
# oldest pending row; the outer UPDATE re-checks state so a
|
||||||
# second racer that also saw that id finds state='applying'
|
# second racer that also saw that id finds state='applying'
|
||||||
# and matches zero rows.
|
# and matches zero rows.
|
||||||
|
# MySQL forbids referencing the UPDATE target inside a
|
||||||
|
# subquery (ERROR 1093). Wrapping the inner SELECT in a
|
||||||
|
# derived table forces materialisation and sidesteps the
|
||||||
|
# rule. SQLite accepts both forms, so this stays portable.
|
||||||
sql = text(
|
sql = text(
|
||||||
"""
|
"""
|
||||||
UPDATE topology_mutations
|
UPDATE topology_mutations
|
||||||
SET state = 'applying'
|
SET state = 'applying'
|
||||||
WHERE id = (
|
WHERE id = (
|
||||||
SELECT id FROM topology_mutations
|
SELECT id FROM (
|
||||||
WHERE topology_id = :t AND state = 'pending'
|
SELECT id FROM topology_mutations
|
||||||
ORDER BY requested_at ASC
|
WHERE topology_id = :t AND state = 'pending'
|
||||||
LIMIT 1
|
ORDER BY requested_at ASC
|
||||||
|
LIMIT 1
|
||||||
|
) AS _next
|
||||||
)
|
)
|
||||||
AND state = 'pending'
|
AND state = 'pending'
|
||||||
"""
|
"""
|
||||||
|
|||||||
Reference in New Issue
Block a user