no-rename-column
Renaming a column breaks all running application queries that reference the old name.
- operation
- Columns
- lock taken
- ACCESS EXCLUSIVE
- remediation
- Multi-step plan
- category
- Data safety
- Breaks a rolling deploy
- Blocks reads
- Blocks writes
What triggers it
Fires on a RenameStmt whose renameType is OBJECT_COLUMN — any ALTER TABLE ... RENAME COLUMN ... TO ....
What does not
Any other RenameStmt variant — renaming a table, index, constraint, or schema — is skipped, since only OBJECT_COLUMN is checked. Non-RenameStmt statements return immediately too.
Where it applies
Applies to every PostgreSQL version MigrationPilot targets. It works on the SQL text alone — no database connection needed.
The lock, and what it blocks
The rename itself is a fast catalog-only change under ACCESS EXCLUSIVE, so the lock window is brief — the real damage is instant and permanent: any query, view, or function still using the old column name starts erroring the moment the rename commits.
Why it matters
Column renames take effect immediately. Any in-flight query or application code referencing the old column name will fail. Use the expand-contract pattern with a new column instead.
Unsafe, and safe
Flagged
ALTER TABLE users RENAME COLUMN name TO full_name;
Safe alternative
-- Add new column, backfill, update app code, drop old ALTER TABLE users ADD COLUMN full_name TEXT; UPDATE users SET full_name = name;
Deploy and transaction boundaries
The doc frames the safe fix as expand-contract across app releases: add the new column, backfill, update application code to read/write it, then drop the old column only once nothing references it — a multi-deploy sequence, not a single migration.
What it assumes
The rule can't see whether anything still references the old column name — it flags every column rename the same way, including one where every caller has already been migrated to the new name and the rename is genuinely safe.
What backs this rule
Every rule is a claim about PostgreSQL, so it carries what the claim rests on: a handbook chapter that cites the manual, the incidents that put it there, and the version it was last checked against.
ALTER TABLE ... RENAME COLUMN is instant, holds a lock for microseconds, rewrites nothing, and is fully reversible.
- verified against
- PostgreSQL 17.10
- last checked
- 2026-08-11
- confidence
- High
Public incidents and write-ups
What the CLI prints
⚠ [MP010] WARNING (line 1) Renaming column "name" to "full_name" on "users" will break any application queries or views referencing the old column name. Safe alternative: -- Step 1: Add new column ALTER TABLE users ADD COLUMN full_name <same_type>; -- Step 2: Backfill data (in batches for large tables) UPDATE users SET full_name = name WHERE full_name IS NULL; -- Step 3: Update application code to use "full_name" -- Step 4: Stop writing to "name" -- Step 5: Drop old column (after verifying no reads) ALTER TABLE users DROP COLUMN name; Why: Renaming a column takes an ACCESS EXCLUSIVE lock and instantly breaks every application query, view, and function referencing the old name. Use the expand-contract pattern: add a new column, migrate data, update code, then drop the old column. Docs: https://migrationpilot.dev/rules/mp010
Generated by running the CLI's own formatter over the flagged example above, so it is the text the tool actually produces. A real run also reports the other rules that fire on the same statement; those blocks are left out here.
Turning it off
For one statement, put a comment on the line before it:
-- migrationpilot-disable MP010 ALTER TABLE users RENAME COLUMN name TO full_name;
For the whole project, in .migrationpilotrc.yml — by name or by id:
rules:
MP010: false
# or keep it, and downgrade it
rules:
MP010:
severity: warningTry it
Open this rule's flagged example in the playground. It runs in your browser — edit it and watch the finding appear and disappear.
Run MP010 in the playground