PR TIMESの開発者ブログに寄稿した記事です。PostgreSQL 15 で導入された NULLS NOT DISTINCT オプションを解説しています。
背景
「SELECT → INSERT」パターンで複数トランザクションが競合すると、意図しない UNIQUE 制約違反エラーが発生するケースがありました。その調査をきっかけに、PostgreSQL の NULL と一意性制約の仕組みを深掘りしました。
NULLS NOT DISTINCT とは
SQL 標準では NULL = NULL は偽とみなすため、従来の PostgreSQL は同一カラムに複数の NULL を挿入できます。NULLS NOT DISTINCT を付与すると NULL 同士も重複とみなされ、一意性チェックの対象になります。
CREATE UNIQUE INDEX idx_name ON table_name (col) NULLS NOT DISTINCT;
内部ロジック
anynullkeys と checkingUnique の 2 つのフラグで制御されており、NULLS NOT DISTINCT 指定時は anynullkeys を強制的に false に上書きして検証を実行します。通常は NULL を含む行の一意性チェックがスキップされますが、このオプションによりスキップされなくなります。