Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save jirutka/41981b6e972bf6aa3b710b927fd2954e to your computer and use it in GitHub Desktop.
Save jirutka/41981b6e972bf6aa3b710b927fd2954e to your computer and use it in GitHub Desktop.
PostgreSQL constraint trigger to check if each array element is unique within the table
-------------------------------------------------------------------------------
-- EXAMPLE USAGE
--
-- create table specialization (
-- id bigserial,
-- name text not null,
-- study_plan_codes text[] not null default '{}'
-- )
--
-- create constraint trigger study_plan_codes_unique_check
-- after insert or update of study_plan_codes on specialization
-- for each row
-- when (cardinality(NEW.study_plan_codes) > 0)
-- execute function trg_check_array_elements_column_uniq('study_plan_codes');
-------------------------------------------------------------------------------
create function trg_check_array_elements_column_uniq ()
returns trigger
language plpgsql
as $$
declare
col_name text := TG_ARGV[0];
duplicates text;
ok boolean;
begin
if TG_NARGS != 1 then
raise 'invalid number of arguments: expected 1, but given %', TG_NARGS using
detail = 'The function was called from trigger "' || TG_NAME || '".';
end if;
execute format('
select not exists (
select 1
from %2$I
where %1$I && $1.%1$I
offset 1
)',
col_name, TG_TABLE_NAME)
into strict ok
using NEW;
if ok then
return null;
else
execute format('
select string_agg(quote_literal(value), '', '')
from (
select unnest(%1$I) as value
from %2$I
where %1$I && $1.%1$I
group by value
having count(*) > 1
) x',
col_name, TG_TABLE_NAME)
into strict duplicates
using NEW;
raise 'duplicate array element in column "%"', col_name using
detail = 'Following element(s) already exist in table "' || TG_TABLE_NAME || '": ' || duplicates || '.',
column = col_name,
table = TG_TABLE_NAME,
errcode = 'unique_violation';
end if;
end;
$$;
comment on function trg_check_array_elements_column_uniq is
'A trigger function for AFTER INSERT OR UPDATE trigger that checks if all elements '
'of the specified array column are unique across the table. If duplicate elements are '
'are found, an exception with ERRCODE "unique_violation" is raised.'
'This function does not check for duplicates inside an array (in a row), just between '
'the arrays in the column.'
'The column name to check must be passed as the first and only argument of the function.';
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment