All rules Rule SL019 · DS
SQLite · alpha
critical
DS · Destructive changes
free in the CLI — --engine=sqlite

Table rebuild that drops the old table before copying its rows

Critical — SQLite refuses the statement, so the migration fails here.

What it catches

The rebuild recipe is create, copy, drop, rename. This migration creates the new table, drops the old one and renames the new one onto its name, but never copies the rows across before the DROP. DROP TABLE discards them; the rename brings back the name with an empty table, and nothing in SQLite fails to say so.

Fires on

CREATE TABLE orders_new (id INTEGER PRIMARY KEY, qty INTEGER NOT NULL);
DROP TABLE orders;
ALTER TABLE orders_new RENAME TO orders;

Do this instead

Copy before dropping: INSERT INTO the new table SELECT from the old, inside the same transaction, so a failed copy rolls the whole rebuild back. If the table is meant to come back empty, suppress the rule with a reason that says so.

BEGIN;
CREATE TABLE orders_new (id INTEGER PRIMARY KEY, qty INTEGER NOT NULL);
INSERT INTO orders_new SELECT id, qty FROM orders;
DROP TABLE orders;
ALTER TABLE orders_new RENAME TO orders;
COMMIT;
Catch this before it ships

SQLite support is in alpha: this rule runs locally in the free CLI, static only, and not in the hosted service yet: npx bolvrk check migration.sql --engine=sqlite