postgresqlconstraintsexclude-constraint

Postgres constraint name need to be unique across single table or entire schema?


I'm trying to understand why some Postgres constraints can be named the same within different tables, and some don't

Here a simple example:

drop table if exists public.table_1;
drop table if exists public.table_2;

CREATE TABLE public.table_1 (
    id serial NOT NULL,
    date_start date NOT NULL,
    date_end date NULL
);

CREATE TABLE public.table_2 (
    id serial NOT NULL,
    date_start date NOT NULL,
    date_end date NULL
);


alter table public.table_1 add constraint my_constraint_1 check (date_start > now());
alter table public.table_2 add constraint my_constraint_1 check (date_start > now());


alter table public.table_1 add constraint my_constraint_2 EXCLUDE USING gist (daterange(date_start, coalesce(date_end, 'infinity'),  '[]') WITH &&);
alter table public.table_2 add constraint my_constraint_2 EXCLUDE USING gist (daterange(date_start, coalesce(date_end, 'infinity'),  '[]') WITH &&);

As you can see I can use the same name my_constraint_1 with different tables enter image description here

Why the name my_constraint_1 can be used as the same in different tables, while my_constraint_2 must be unique otherwise I get the error Errore SQL [42P07]: ERROR: relation "my_constraint_2" already exists?


Solution

  • Why the name my_constraint_1 can be used as the same in different tables, while my_constraint_2 must be unique

    Constraint 2 has underlying index with the same name, while constraint 1 is simple check contraint on table level.

    EXCLUDE Exclusion constraints are implemented using an index, so each specified operator must be associated with an appropriate operator class (see Section 11.10) for the index access method index_method.

    CREATE INDEX my_constraint_2 ON public.table_1 USING gist (daterange(date_start, COALESCE(date_end, 'infinity'::date), '[]'::text))
    

    db<>fiddle demo