addingFieldWithDefault
Diagnostic Category: lint/safety/addingFieldWithDefault
Since: vnext
Note
This rule is recommended. A diagnostic error will appear when linting your code.
Sources:
- Inspired from: squawk/adding-field-with-default
Description
Adding a column with a DEFAULT value may lead to a table rewrite while holding an ACCESS EXCLUSIVE lock.
In PostgreSQL versions before 11, adding a column with a DEFAULT value causes a full table rewrite, which holds an ACCESS EXCLUSIVE lock on the table and blocks all reads and writes.
In PostgreSQL 11+, this behavior was optimized for non-volatile defaults. However:
- Volatile default values (like random() or custom functions) still cause table rewrites
- Generated columns (GENERATED ALWAYS AS) always require table rewrites
- Non-volatile defaults are safe in PostgreSQL 11+
Examples
Invalid
ALTER TABLE "core_recipe" ADD COLUMN "foo" integer DEFAULT 10;
code-block.sql:1:1 lint/safety/addingFieldWithDefault ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
! Adding a column with a DEFAULT value causes a table rewrite.
> 1 │ ALTER TABLE "core_recipe" ADD COLUMN "foo" integer DEFAULT 10;
│ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
2 │
i This operation requires an ACCESS EXCLUSIVE lock and rewrites the entire table.
i Add the column without a default, then set the default in a separate statement.
Valid
ALTER TABLE "core_recipe" ADD COLUMN "foo" integer;
ALTER TABLE "core_recipe" ALTER COLUMN "foo" SET DEFAULT 10;
-- Then backfill and add NOT NULL constraint if needed
How to configure
{
"linter": {
"rules": {
"safety": {
"addingFieldWithDefault": "error"
}
}
}
}