Skip to content

Instantly share code, notes, and snippets.

@matthew-n
Last active December 29, 2020 17:17
Show Gist options
  • Save matthew-n/43836e6e9ccdfaf35ccebe11a5b51ee1 to your computer and use it in GitHub Desktop.
Save matthew-n/43836e6e9ccdfaf35ccebe11a5b51ee1 to your computer and use it in GitHub Desktop.
PosgreSQL function error handler that displays comments
CREATE OR REPLACE FUNCTION dummy_function( col_pk int, col_b my_domain, col_fk text)
AS
$BODY$
declare
v_msg text;
v_constraint text;
BEGIN
INSERT INTO some_table VALUES($1,$2,$3);
RETURN TRUE;
EXCEPTION
-- this will rewrite the message to be the comment on the constraint and return the original error code
WHEN check_violation OR unique_violation OR foreign_key_violation THEN
GET STACKED DIAGNOSTICS v_constraint := CONSTRAINT_NAME;
SELECT COALESCE(description,SQLERRM) into v_msg
FROM pg_constraint as c
JOIN pg_namespace as n ON n.oid = c.connamespace
LEFT join pg_description as cmt on cmt.objoid = c.oid
WHERE
contype IN ('f','p','c','u') AND
conname = v_constraint;
RAISE USING ERRCODE = SQLSTATE, MESSAGE=v_msg;
RETURN FALSE;
END;
$BODY$
LANGUAGE plpgsql;
drop table if exists some_parent;
drop table if exists some_table;
create table some_parent (
id int not null primary key
);
create table some_table (
id serial,
user_data varchar(200) not null,
some_fk int,
constraint pk_foo primary key (id),
constraint fk_bar foreign key (some_fk) references some_parent(id),
constraint ck_short check (length(user_data) < 2)
);
-- add comments
comment on constraint pk_foo on some_table is 'Primary key cannot have duplicates.';
comment on constraint fk_bar on some_table is 'prime numbers are the only ones worth keeping';
comment on constraint ck_short on some_table is 'for `some business reason` we are only allowing two chars now but might want 200 soon.';
--- add data
insert into some_parent (id)
values (3),(5),(7),(11),(13);
\i some_table.sql
\i function-template.sql
-- initialize
execute dummy_function(1,'aa',3);
-- examples
execute dummy_function(2,'aaa',3);
/*
Violates the business rule `ck_short` and so displays the
message:
for `some business reason` we are only allowing two chars now but might want 200 soon.
instead of the normal check constraint error
*/
execute dummy_function(2,'aa',4);
execute dummy_function(1,'aa',3);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment