Skip to content

SQL rules

19 rules

Rule Category
enforce-timestamptz TIMESTAMP without TIME ZONE — use TIMESTAMPTZ. correctness
excess-migration-index-requires-justification Require a structured local justification for excess explicit indexes in an authored migration. performance
existing-table-check-or-foreign-key-requires-not-valid CHECK and foreign-key constraints added to existing PostgreSQL tables should defer validation. performance
idempotent-ddl DDL without IF [NOT] EXISTS — migrations must be safe to re-run. correctness
index-concurrently CREATE INDEX without CONCURRENTLY — locks the table against writes. performance
insert-requires-replay-policy Every INSERT must declare replay-safe upsert behavior or explicitly document intentional insert-only semantics. correctness
mixed-migration-phases Review existing-table migrations that combine backfill, enforcement, and contract phases. architecture
no-application-schema-check Keep JSON shape and closed application value sets out of database CHECK constraints. architecture
no-database-triggers Keep behavioral logic in application code, not database triggers. architecture
no-duplicate-index Report duplicate and conservatively covered indexes that remain active in one authored migration. performance
no-long-migration-narration Long migration comments narrate implementation instead of recording durable constraints. maintainability
no-migration-comment-cruft Commented-out SQL, decorative banners, and untracked debt markers must be removed. maintainability
no-offset-pagination Dynamic OFFSET pagination in query SQL should use a stable cursor. performance
no-pg-enum CREATE TYPE ... AS ENUM — use TEXT with an application enum instead. maintainability
prefer-jsonb JSON column type or table-DDL cast — use JSONB. performance
prefer-text-over-varchar VARCHAR(n) — use TEXT (+ CHECK length if needed). maintainability
prefer-uuidv7-default `gen_random_uuid()` emits a random UUIDv4 — use `uuidv7()` so keys are time-ordered. performance
require-fk-index Cascading or set-value FOREIGN KEY action lacks a child-table index. performance
require-lock-timeout DDL migration missing positive SET [LOCAL] lock_timeout or statement_timeout prior to DDL. correctness