Ignoring temp table in Postgres event trigger

Posted on

Question :

I am trying to have a trigger that gets invoked when new tables, except temporary tables, are created.

This is what I have tried:

CREATE OR REPLACE FUNCTION insert()
RETURNS event_trigger
AS $$
DECLARE
    r RECORD;
BEGIN
    FOR r IN SELECT * FROM pg_event_trigger_ddl_commands() LOOP
        RAISE NOTICE 'caught % event on %', r.command_tag, r.object_identity;
    END LOOP;
 END;
 $$
 LANGUAGE plpgsql;

CREATE EVENT TRIGGER insert_event ON ddl_command_end
  WHEN TAG IN ('CREATE TABLE', 'CREATE TABLE AS', 'CREATE FUNCTION', 'ALTER TABLE', 'DROP TABLE')
 EXECUTE PROCEDURE insert();

create TEMP table my_table(id serial primary key);

This is the output I see:

CREATE TABLE
CREATE FUNCTION
CREATE EVENT TRIGGER
CREATE FUNCTION
CREATE EVENT TRIGGER
NOTICE:  caught CREATE SEQUENCE event on pg_temp.my_table_id_seq
NOTICE:  caught CREATE TABLE event on pg_temp.my_table
NOTICE:  caught CREATE INDEX event on pg_temp.my_table_pkey
NOTICE:  caught ALTER SEQUENCE event on pg_temp.my_table_id_seq

How do I exclude temporary tables from invoking the trigger?

Answer :

You’ll have to exclude temporary objects by schema name:

FOR r IN
   SELECT * FROM pg_event_trigger_ddl_commands() AS ddl
   WHERE ddl.schema_name NOT LIKE 'pg_temp%'
LOOP
   ...
END LOOP;

The strange pattern is because temporary objects in PostgreSQL are created in schemas that are actually called pg_temp_1, pg_temp_2 and the like (a different one per user), and even though your example suggests that you always see pg_temp, I’d prefer to use the pattern just to be on the safe side.

Leave a Reply

Your email address will not be published. Required fields are marked *