addingNotNullField
Diagnostic Category: lint/safety/addingNotNullField
Since: vnext
Note
This rule is recommended. A diagnostic error will appear when linting your code.
Sources:
- Inspired from: squawk/adding-not-null-field
Description
Setting a column NOT NULL blocks reads while the table is scanned.
In PostgreSQL versions before 11, adding a NOT NULL constraint to an existing column requires a full table scan to verify that all existing rows satisfy the constraint. This operation takes an ACCESS EXCLUSIVE lock, blocking all reads and writes.
In PostgreSQL 11+, this operation is much faster as it can skip the full table scan for newly added columns with default values.
Instead of using SET NOT NULL, consider using a CHECK constraint with NOT VALID, then validating it in a separate transaction. This allows reads and writes to continue.
Examples
Invalid
ALTER TABLE "core_recipe" ALTER COLUMN "foo" SET NOT NULL;
code-block.sql:1:1 lint/safety/addingNotNullField ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
! Setting a column NOT NULL blocks reads while the table is scanned.
> 1 │ ALTER TABLE "core_recipe" ALTER COLUMN "foo" SET NOT NULL;
│ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
2 │
i This operation requires an ACCESS EXCLUSIVE lock and a full table scan to verify all rows.
i Use a CHECK constraint with NOT VALID instead, then validate it in a separate transaction.
Valid
-- First add a CHECK constraint as NOT VALID
ALTER TABLE "core_recipe" ADD CONSTRAINT foo_not_null CHECK (foo IS NOT NULL) NOT VALID;
-- Then validate it in a separate transaction
ALTER TABLE "core_recipe" VALIDATE CONSTRAINT foo_not_null;
How to configure
{
"linter": {
"rules": {
"safety": {
"addingNotNullField": "error"
}
}
}
}