MP003CRITICALFree

volatile-default-table-rewrite

What It Detects

ADD COLUMN with a volatile DEFAULT (e.g., now(), random()) causes a full table rewrite on PG < 11.

Why It's Dangerous

On PostgreSQL < 11, adding a column with a volatile default rewrites every row in the table under ACCESS EXCLUSIVE lock. On PG 11+, non-volatile defaults are stored in pg_attribute and applied lazily, but volatile defaults still evaluate per-row.

Bad Example

ALTER TABLE users ADD COLUMN created_at TIMESTAMP DEFAULT now();

Good Example

-- On PG 11+: volatile defaults are evaluated per-row (no rewrite)
-- On PG < 11: add column without default, then backfill
ALTER TABLE users ADD COLUMN created_at TIMESTAMP;
UPDATE users SET created_at = now() WHERE created_at IS NULL;

Configuration

Disable this rule:

# .migrationpilotrc.yml
rules:
  MP003: false

Or change its severity:

# .migrationpilotrc.yml
rules:
  MP003:
    severity: warning