R002 · default CAUTION
ALTER COLUMN TYPE (incompatible)
ALTER COLUMN TYPE that requires re-encoding rows holds an AccessExclusiveLock for the duration of the rewrite.
Why this is a problem
Compatible changes (e.g., VARCHAR(N) → VARCHAR(M) where M ≥ N, or VARCHAR → TEXT) are metadata-only. Anything with a USING clause or a different storage representation (INTEGER → BIGINT, BYTEA → TEXT) requires a full table rewrite.
Don't do this
ALTER TABLE orders ALTER COLUMN user_id TYPE BIGINT;Do this instead
-- Add new column nullable
ALTER TABLE orders ADD COLUMN user_id_new BIGINT;
-- Backfill in batches
UPDATE orders SET user_id_new = user_id WHERE user_id_new IS NULL AND id BETWEEN 0 AND 100000;
-- Switch reads, then drop + rename
BEGIN;
ALTER TABLE orders DROP COLUMN user_id;
ALTER TABLE orders RENAME COLUMN user_id_new TO user_id;
COMMIT;References
Catch this rule on every PR.
dbivio runs all 10 rules automatically with your real Postgres stats. Install once, get a verdict on every migration PR.
Install on GitHub