MP017warning

no-drop-column

DROP COLUMN acquires ACCESS EXCLUSIVE lock and may break application queries.

operation
Columns
lock taken
ACCESS EXCLUSIVE
remediation
Manual rewrite
category
Data safety

What triggers it

Fires on an AT_DropColumn command inside AlterTableStmt.cmds — any ALTER TABLE ... DROP COLUMN ....

What does not

Any AlterTableStmt whose commands don't include AT_DropColumnADD COLUMN, ALTER COLUMN TYPE, and so on — is skipped, as is any statement that isn't an AlterTableStmt.

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 catalog update itself is brief under ACCESS EXCLUSIVE, but any application code still selecting, inserting, or updating that column starts failing the instant it commits — that's the real hazard, not the lock duration.

Why it matters

Dropping a column acquires ACCESS EXCLUSIVE lock (briefly) and immediately breaks any query or application code referencing that column. Ensure all code is updated before dropping.

The operation, and the mitigation

Flagged

ALTER TABLE users DROP COLUMN old_field;

Mitigated — still flagged

-- 1. Remove all references in application code
-- 2. Deploy code changes
-- 3. Then drop the column
ALTER TABLE users DROP COLUMN old_field;

This operation is irreversible, so there is no syntax that makes it safe. The second block is what care looks like — and MigrationPilot still flags it. The mitigation is process: confirm nothing reads the object, keep a way back, and do it in a window where you can watch.

Deploy and transaction boundaries

The safe sequence is two separate application deploys: one that removes every code reference to the column, then a later deploy that runs the DROP COLUMN — dropping it in the same deploy as the code change risks a window where old code instances still reference the now-dropped column.

What it assumes

The rule can't see whether application code has actually stopped referencing the column — it flags every DROP COLUMN identically, including one where a prior deploy already removed every reference and the drop 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 ... DROP COLUMN is fast.

verified against
PostgreSQL 17.10
last checked
2026-08-11
confidence
High

What the CLI prints

migrationpilot analyze migration.sql
⚠ [MP017] WARNING (line 1)
  DROP COLUMN "old_field" on "users" takes ACCESS EXCLUSIVE lock. Running application code referencing this column will break immediately.

  Safe alternative:
  -- Safe multi-deploy approach:
  -- Deploy 1: Remove all application code references to "old_field"
  -- Deploy 2: Drop the column with a short lock timeout
  SET lock_timeout = '5s';
  ALTER TABLE users DROP COLUMN old_field;
  RESET lock_timeout;

  Why: DROP COLUMN takes an ACCESS EXCLUSIVE lock and instantly breaks any application code still selecting or inserting that column. Always remove all code references in a prior deploy before dropping the column.
  Docs: https://migrationpilot.dev/rules/mp017

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 MP017
ALTER TABLE users DROP COLUMN old_field;

For the whole project, in .migrationpilotrc.yml — by name or by id:

.migrationpilotrc.yml
rules:
  MP017: false

# or keep it, and downgrade it
rules:
  MP017:
    severity: warning

Try 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 MP017 in the playground

Related rules