In postgres, I'd like to dynamically add a trigger to all my tables on insert for each row. I want to be able to add the trigger for all future tables that get added without requiring db users to do something else to create a table (like call a function to create a table instead of using the CREATE TABLE syntax). To do this, I thought it would be easiest to add a trigger to pg_class, but when I do that, I get an error:
ERROR: permission denied: "pg_class" is a system catalog
Here is my code
> docker run --name pg -e POSTGRES_PASSWORD=password postgres:13
> docker exec -ti pg psql -Upostgres
# then run this...
CREATE FUNCTION my_func() RETURNS trigger AS $$
BEGIN
RAISE NOTICE 'This is a test';
RETURN NULL;
END;
$$ LANGUAGE plpgsql;
CREATE TRIGGER my_pg_trigger
AFTER INSERT ON pg_catalog.pg_class
FOR EACH ROW
WHEN (NEW.relkind = 'r')
EXECUTE FUNCTION my_func();
I didn't see anything in the documentation saying that you couldn't add triggers. I found docs saying that they are "regular tables", however editing them can severely mess things up: https://www.postgresql.org/docs/13/catalogs.html. However nothing about permissions or limitations.
PostgreSQL's system catalogs are regular tables. You can drop and recreate the tables, add columns, insert and update values, and severely mess up your system that way.
If this isn't possible, can you point me to the documentation on this to help me understand? Better yet, let me know if there is another way you can dynamically add triggers to tables?