fix(db): track ALTER TABLE … RENAME TO so column-collision detection survives a rebuild - #9841
Conversation
…survives a rebuild `detectColumnCollisions` replays every migration's schema events to catch a same-table/same-column definition across two files. But `extractSchemaEvents` emitted nothing for `ALTER TABLE <old> RENAME TO <new>` — the standard SQLite rebuild-and-rename (migrations/0201). So every column tracked under the temporary `_new` table stayed keyed to it, and the detector went blind on the real table: a later duplicate ADD COLUMN read as a fresh, non-colliding definition. Add a `rename_table` SchemaEvent and parse the RENAME TO form — matched before the column-rename rule and requiring `RENAME` immediately followed by `TO`, which the column form (an identifier between RENAME and TO) never has, so the two are disambiguated both directions. `detectColumnCollisions` handles it by re-keying every column tracked under the old table name to the new one (and vacating the old name, so a fresh table reusing it does not falsely collide). Closes JSONbored#9647
|
Warning ⏸️ LoopOver review result - manual review recommendedReview updated: 2026-07-29 13:24:53 UTC
Review summary Nits — 3 non-blocking
Decision drivers
Context & advisory signals — never blocks the verdict
Linked issue satisfactionAddressed Review context
Contributor next steps
Signal definitions
🧪 Chat with LoopOverAsk LoopOver a question about this PR directly in a comment — grounded only in the same cached, public-safe facts shown above, never a new claim.
Full command reference: https://loopover.ai/docs/loopover-commands 🧪 Experimental — new and may change. 🟩 Safe / merged · 🟦 Advisory · 🟨 Held for review · 🟥 Blocked / closed 💰 Earn for open-source contributions like this. Gittensor lets GitHub contributors earn for the work they already do — register to start earning →. Checked by LoopOver, a quiet PR intelligence layer for OSS maintainers.
|
|
Superagent didn't find any vulnerabilities or security issues in this PR. |
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## main #9841 +/- ##
==========================================
+ Coverage 79.04% 79.09% +0.05%
==========================================
Files 281 282 +1
Lines 58409 58549 +140
Branches 6698 6737 +39
==========================================
+ Hits 46171 46311 +140
Misses 11955 11955
Partials 283 283
Flags with carried forward coverage won't be shown. Click here to find out more.
|
What & why
detectColumnCollisions(src/db/migration-column-extraction.ts) replays every migration's schema events in order to catch a same-table/same-column definition split across two individually-valid migrations. ButextractSchemaEventsemitted nothing forALTER TABLE <old> RENAME TO <new>— the standard SQLite rebuild-and-rename (migrations/0201_ledger_anchor_bittensor.sqldoes exactly this, since SQLite can'tALTERa CHECK constraint).So every column tracked under the temporary
_newtable stayed keyed to it, and the detector went blind on the real table: a later duplicateADD COLUMNread as a fresh, non-colliding definition — the very class of collision this check exists to catch.The fix
{ type: "rename_table"; from; to }SchemaEventvariant.ALTER TABLE <old> RENAME TO <new>into it — matched before the column-rename rule and requiringRENAMEimmediately followed byTO. The column form (RENAME [COLUMN] <a> TO <b>, an identifier betweenRENAMEandTO) never matches that, and the table form never matches the column rule, so the two are disambiguated in both directions.detectColumnCollisionshandlesrename_tableby re-keying every column tracked under the old table name to the new one — and vacating the old name, so a fresh table reusing it doesn't falsely collide.Tests (
test/unit/migration-column-extraction.test.ts)extractSchemaEventsreturns a singlerename_tablefor 0201's exact statement; the two column-rename forms still produceremove_column+define_column(disambiguation proven) — fails onmain.CREATE t(backend)→ rebuild-and-renamet_new → t→ALTER t ADD COLUMN backendyields exactly one collision ont.backend(fails onmain, which sees none).Validation
npm run typecheckgreen; the extraction suite (39 tests) green.git diff --check <base> HEADclean; no migration or schema change.Closes #9647