MP062CRITICALFree

ban-add-generated-stored-column

What It Detects

Adding a stored generated column causes a full table rewrite under ACCESS EXCLUSIVE lock.

Why It's Dangerous

ALTER TABLE ADD COLUMN with GENERATED ALWAYS AS ... STORED rewrites every row to compute and store the expression. On tables with millions of rows, this holds an ACCESS EXCLUSIVE lock for the entire rewrite — blocking all reads and writes.

Bad Example

ALTER TABLE users
  ADD COLUMN full_name TEXT
  GENERATED ALWAYS AS (first_name || ' ' || last_name) STORED;

Good Example

-- Use a regular column + trigger instead
ALTER TABLE users ADD COLUMN full_name TEXT;

CREATE FUNCTION update_full_name() RETURNS trigger AS $$
BEGIN
  NEW.full_name := NEW.first_name || ' ' || NEW.last_name;
  RETURN NEW;
END;
$$ LANGUAGE plpgsql;

CREATE TRIGGER trg_full_name
  BEFORE INSERT OR UPDATE ON users
  FOR EACH ROW EXECUTE FUNCTION update_full_name();

Configuration

Disable this rule:

# .migrationpilotrc.yml
rules:
  MP062: false

Or change its severity:

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