Skip Navigation code drift

Making nulls distinct in Postgres < 15

written  &  updated
in TIL, but also Code, & Databases

From the postgres docs on unique indexes:

When an index is declared unique, multiple table rows with equal indexed values are not allowed. Null values are not considered equal. A multicolumn unique index will only reject cases where all indexed columns are equal in multiple rows.

Unfortunately, disabling distinct null values via NULLS NOT DISTINCT is a pg 15+ feature meaning it might be a while until you can use it. As a workaround, you can instead store a generated column. For example, a nullable uuid column that must still be unique can be solved first by creating the generated column

ALTER TABLE table_name
ADD COLUMN
  generated_column uuid GENERATED ALWAYS AS (
    COALESCE(nullable_uuid_column, uuid_nil())
  ) STORED

Then the resulting generated_column can be used in a unique index. The coalesce function lets you turn null values into a non-null value ensuring the unique index works as expected. In this case uuid_nil() returns a special uuid of all 0 characters.