2023-06-11 16:26:39 +00:00
|
|
|
create function immutable(schema text, table_ text, columns text[])
|
2023-06-10 22:43:27 +00:00
|
|
|
returns void
|
|
|
|
language plpgsql
|
|
|
|
as $$
|
|
|
|
declare
|
|
|
|
col text;
|
|
|
|
qualified_name text := concat(schema, '.', table_);
|
|
|
|
do_table_immutable_columns text := concat('do_', table_, '_immutable_columns');
|
|
|
|
trigger_table_immutable_columns text := concat('trigger_', table_, '_immutable_columns');
|
|
|
|
create_do_table_immutable_columns text;
|
|
|
|
create_trigger_table_immutable_columns text;
|
|
|
|
begin
|
|
|
|
create_do_table_immutable_columns := concat( create_do_table_immutable_columns
|
|
|
|
, 'create function ', schema, '.', do_table_immutable_columns, E'() returns trigger language plpgsql as \$\$\n'
|
|
|
|
, E'begin\n'
|
|
|
|
, ' if OLD.', columns[1], ' <> NEW.', columns[1], E' then\n'
|
|
|
|
, E' raise exception \'', qualified_name, '.', columns[1], E' is immutable\' using errcode = \'restrict_violation\';\n'
|
|
|
|
);
|
|
|
|
foreach col in array columns[2:] loop
|
|
|
|
create_do_table_immutable_columns := concat( create_do_table_immutable_columns
|
|
|
|
, E' elsif OLD.', col, ' <> NEW.', col, E' then\n'
|
|
|
|
, E' raise exception \'', qualified_name, '.', col, E' is immutable\' using errcode = \'restrict_violation\';\n'
|
|
|
|
);
|
|
|
|
end loop;
|
|
|
|
|
|
|
|
create_do_table_immutable_columns := concat( create_do_table_immutable_columns
|
|
|
|
, E' end if;\n'
|
|
|
|
, E'\n'
|
|
|
|
, E' return NEW;\n'
|
|
|
|
, E'end;\n'
|
|
|
|
, E'\$\$;\n'
|
|
|
|
);
|
|
|
|
|
|
|
|
create_trigger_table_immutable_columns := concat( create_trigger_table_immutable_columns
|
|
|
|
, 'create trigger ', trigger_table_immutable_columns, E'\n'
|
|
|
|
, 'before update on ', qualified_name, E'\n'
|
|
|
|
, 'for each row execute function ', do_table_immutable_columns, '();'
|
|
|
|
);
|
|
|
|
|
|
|
|
execute create_do_table_immutable_columns;
|
|
|
|
execute create_trigger_table_immutable_columns;
|
|
|
|
end;
|
|
|
|
$$;
|