Skip to content
Sarj Code Standards

idempotent-ddl

DDL omits a supported IF [NOT] EXISTS guard.

Why

Supported existence guards help replay DDL after partial application. A transactional migration runner such as dbmate owns version tracking and rollback; this rule does not require every statement to be independently replayable.

Fix

Use the native IF NOT EXISTS or IF EXISTS form where this rule supports it. Keep ADD CONSTRAINT as plain DDL in versioned transactional migrations; do not synthesize catalog-query DO blocks or catch duplicate-object errors solely for replay.

Examples

Before — flagged An index creation that fails when replayed
migrations/001_orders.sql
CREATE INDEX CONCURRENTLY orders_total ON orders (total);
After — preferred A replay-safe concurrent index creation
migrations/001_orders.sql
CREATE INDEX CONCURRENTLY IF NOT EXISTS orders_total ON orders (total);
Autofix output
migrations/001_orders.sql
CREATE INDEX CONCURRENTLY IF NOT EXISTS orders_total ON orders (total);
Before — flagged Table creation that fails on replay
migrations/001_orders.sql
CREATE TABLE orders (id BIGINT PRIMARY KEY);
After — preferred Replay-safe table creation
migrations/001_orders.sql
CREATE TABLE IF NOT EXISTS orders (id BIGINT PRIMARY KEY);
Autofix output
migrations/001_orders.sql
CREATE TABLE IF NOT EXISTS orders (id BIGINT PRIMARY KEY);