Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to get SQL text from Postgres event trigger

Tags:

In a pgsql event trigger on tag ALTER TABLE, I wish to know which table is being altered.

The pg variables do not cover this, nor do the variables exposed by GET STACKED DIAGNOSTICS.

With variables available, is there any way within the trigger function itself to see the text of the SQL command responsible for initiating the function.

for example, if

ALTER TABLE base1 ADD COLUMN col1 int;

were responsible for calling the event trigger, is there any way within the event trigger to see then ALTER TABLE base1 ADD COLUMN col1 int text itself?

like image 265
cc young Avatar asked May 06 '14 07:05

cc young


People also ask

Can trigger return a value?

The return value of a row-level trigger fired AFTER or a statement-level trigger fired BEFORE or AFTER is always ignored; it might as well be null. However, any of these types of triggers might still abort the entire operation by raising an error. Example 43.3 shows an example of a trigger function in PL/pgSQL.

How do I call a trigger in PostgreSQL?

Syntax. CREATE TRIGGER trigger_name [BEFORE|AFTER|INSTEAD OF] event_name ON table_name [ -- Trigger logic goes here.... ]; Here, event_name could be INSERT, DELETE, UPDATE, and TRUNCATE database operation on the mentioned table table_name. You can optionally specify FOR EACH ROW after table name.

What are event triggers in PostgreSQL?

A PostgreSQL trigger is a function invoked automatically whenever an event associated with a table occurs. An event could be any of the following: INSERT, UPDATE, DELETE or TRUNCATE. A trigger is a special user-defined function associated with a table.


1 Answers

Starting from PostgreSQL 9.5, function pg_event_trigger_ddl_commands() is available for ddl_command_end event triggers. Using the TAG filter, it may be used for processing any ALTERed table. object_identity (or objid) may be used to solve the original problem of knowing which table has been ALTERed. As for getting the complete command, it is available, too, but it is of an internal type pg_ddl_command.

CREATE TABLE t (n INT);

CREATE FUNCTION notice_event() 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 tr_notice_alter_table
  ON ddl_command_end WHEN TAG IN ('ALTER TABLE')
  EXECUTE PROCEDURE notice_event();

ALTER TABLE t ADD c CHAR;

outputs: NOTICE: caught ALTER TABLE event on public.t

like image 158
Ondřej Bouda Avatar answered Sep 19 '22 00:09

Ondřej Bouda