1-- should fail, return type mismatch
2create event trigger regress_event_trigger
3   on ddl_command_start
4   execute procedure pg_backend_pid();
5ERROR:  function pg_backend_pid must return type event_trigger
6-- OK
7create function test_event_trigger() returns event_trigger as $$
8BEGIN
9    RAISE NOTICE 'test_event_trigger: % %', tg_event, tg_tag;
10END
11$$ language plpgsql;
12-- should fail, can't call it as a plain function
13SELECT test_event_trigger();
14ERROR:  trigger functions can only be called as triggers
15CONTEXT:  compilation of PL/pgSQL function "test_event_trigger" near line 1
16-- should fail, event triggers cannot have declared arguments
17create function test_event_trigger_arg(name text)
18returns event_trigger as $$ BEGIN RETURN 1; END $$ language plpgsql;
19ERROR:  event trigger functions cannot have declared arguments
20CONTEXT:  compilation of PL/pgSQL function "test_event_trigger_arg" near line 1
21-- should fail, SQL functions cannot be event triggers
22create function test_event_trigger_sql() returns event_trigger as $$
23SELECT 1 $$ language sql;
24ERROR:  SQL functions cannot return type event_trigger
25-- should fail, no elephant_bootstrap entry point
26create event trigger regress_event_trigger on elephant_bootstrap
27   execute procedure test_event_trigger();
28ERROR:  unrecognized event name "elephant_bootstrap"
29-- OK
30create event trigger regress_event_trigger on ddl_command_start
31   execute procedure test_event_trigger();
32-- OK
33create event trigger regress_event_trigger_end on ddl_command_end
34   execute procedure test_event_trigger();
35-- should fail, food is not a valid filter variable
36create event trigger regress_event_trigger2 on ddl_command_start
37   when food in ('sandwich')
38   execute procedure test_event_trigger();
39ERROR:  unrecognized filter variable "food"
40-- should fail, sandwich is not a valid command tag
41create event trigger regress_event_trigger2 on ddl_command_start
42   when tag in ('sandwich')
43   execute procedure test_event_trigger();
44ERROR:  filter value "sandwich" not recognized for filter variable "tag"
45-- should fail, create skunkcabbage is not a valid command tag
46create event trigger regress_event_trigger2 on ddl_command_start
47   when tag in ('create table', 'create skunkcabbage')
48   execute procedure test_event_trigger();
49ERROR:  filter value "create skunkcabbage" not recognized for filter variable "tag"
50-- should fail, can't have event triggers on event triggers
51create event trigger regress_event_trigger2 on ddl_command_start
52   when tag in ('DROP EVENT TRIGGER')
53   execute procedure test_event_trigger();
54ERROR:  event triggers are not supported for DROP EVENT TRIGGER
55-- should fail, can't have event triggers on global objects
56create event trigger regress_event_trigger2 on ddl_command_start
57   when tag in ('CREATE ROLE')
58   execute procedure test_event_trigger();
59ERROR:  event triggers are not supported for CREATE ROLE
60-- should fail, can't have event triggers on global objects
61create event trigger regress_event_trigger2 on ddl_command_start
62   when tag in ('CREATE DATABASE')
63   execute procedure test_event_trigger();
64ERROR:  event triggers are not supported for CREATE DATABASE
65-- should fail, can't have event triggers on global objects
66create event trigger regress_event_trigger2 on ddl_command_start
67   when tag in ('CREATE TABLESPACE')
68   execute procedure test_event_trigger();
69ERROR:  event triggers are not supported for CREATE TABLESPACE
70-- should fail, can't have same filter variable twice
71create event trigger regress_event_trigger2 on ddl_command_start
72   when tag in ('create table') and tag in ('CREATE FUNCTION')
73   execute procedure test_event_trigger();
74ERROR:  filter variable "tag" specified more than once
75-- should fail, can't have arguments
76create event trigger regress_event_trigger2 on ddl_command_start
77   execute procedure test_event_trigger('argument not allowed');
78ERROR:  syntax error at or near "'argument not allowed'"
79LINE 2:    execute procedure test_event_trigger('argument not allowe...
80                                                ^
81-- OK
82create event trigger regress_event_trigger2 on ddl_command_start
83   when tag in ('create table', 'CREATE FUNCTION')
84   execute procedure test_event_trigger();
85-- OK
86comment on event trigger regress_event_trigger is 'test comment';
87-- drop as non-superuser should fail
88create role regress_evt_user;
89set role regress_evt_user;
90create event trigger regress_event_trigger_noperms on ddl_command_start
91   execute procedure test_event_trigger();
92ERROR:  permission denied to create event trigger "regress_event_trigger_noperms"
93HINT:  Must be superuser to create an event trigger.
94reset role;
95-- all OK
96alter event trigger regress_event_trigger enable replica;
97alter event trigger regress_event_trigger enable always;
98alter event trigger regress_event_trigger enable;
99alter event trigger regress_event_trigger disable;
100-- regress_event_trigger2 and regress_event_trigger_end should fire, but not
101-- regress_event_trigger
102create table event_trigger_fire1 (a int);
103NOTICE:  test_event_trigger: ddl_command_start CREATE TABLE
104NOTICE:  test_event_trigger: ddl_command_end CREATE TABLE
105-- regress_event_trigger_end should fire on these commands
106grant all on table event_trigger_fire1 to public;
107NOTICE:  test_event_trigger: ddl_command_end GRANT
108comment on table event_trigger_fire1 is 'here is a comment';
109NOTICE:  test_event_trigger: ddl_command_end COMMENT
110revoke all on table event_trigger_fire1 from public;
111NOTICE:  test_event_trigger: ddl_command_end REVOKE
112drop table event_trigger_fire1;
113NOTICE:  test_event_trigger: ddl_command_end DROP TABLE
114create foreign data wrapper useless;
115NOTICE:  test_event_trigger: ddl_command_end CREATE FOREIGN DATA WRAPPER
116create server useless_server foreign data wrapper useless;
117NOTICE:  test_event_trigger: ddl_command_end CREATE SERVER
118create user mapping for regress_evt_user server useless_server;
119NOTICE:  test_event_trigger: ddl_command_end CREATE USER MAPPING
120alter default privileges for role regress_evt_user
121 revoke delete on tables from regress_evt_user;
122NOTICE:  test_event_trigger: ddl_command_end ALTER DEFAULT PRIVILEGES
123-- alter owner to non-superuser should fail
124alter event trigger regress_event_trigger owner to regress_evt_user;
125ERROR:  permission denied to change owner of event trigger "regress_event_trigger"
126HINT:  The owner of an event trigger must be a superuser.
127-- alter owner to superuser should work
128alter role regress_evt_user superuser;
129alter event trigger regress_event_trigger owner to regress_evt_user;
130-- should fail, name collision
131alter event trigger regress_event_trigger rename to regress_event_trigger2;
132ERROR:  event trigger "regress_event_trigger2" already exists
133-- OK
134alter event trigger regress_event_trigger rename to regress_event_trigger3;
135-- should fail, doesn't exist any more
136drop event trigger regress_event_trigger;
137ERROR:  event trigger "regress_event_trigger" does not exist
138-- should fail, regress_evt_user owns some objects
139drop role regress_evt_user;
140ERROR:  role "regress_evt_user" cannot be dropped because some objects depend on it
141DETAIL:  owner of event trigger regress_event_trigger3
142owner of default privileges on new relations belonging to role regress_evt_user
143owner of user mapping for regress_evt_user on server useless_server
144-- cleanup before next test
145-- these are all OK; the second one should emit a NOTICE
146drop event trigger if exists regress_event_trigger2;
147drop event trigger if exists regress_event_trigger2;
148NOTICE:  event trigger "regress_event_trigger2" does not exist, skipping
149drop event trigger regress_event_trigger3;
150drop event trigger regress_event_trigger_end;
151-- test support for dropped objects
152CREATE SCHEMA schema_one authorization regress_evt_user;
153CREATE SCHEMA schema_two authorization regress_evt_user;
154CREATE SCHEMA audit_tbls authorization regress_evt_user;
155CREATE TEMP TABLE a_temp_tbl ();
156SET SESSION AUTHORIZATION regress_evt_user;
157CREATE TABLE schema_one.table_one(a int);
158CREATE TABLE schema_one."table two"(a int);
159CREATE TABLE schema_one.table_three(a int);
160CREATE TABLE audit_tbls.schema_one_table_two(the_value text);
161CREATE TABLE schema_two.table_two(a int);
162CREATE TABLE schema_two.table_three(a int, b text);
163CREATE TABLE audit_tbls.schema_two_table_three(the_value text);
164CREATE OR REPLACE FUNCTION schema_two.add(int, int) RETURNS int LANGUAGE plpgsql
165  CALLED ON NULL INPUT
166  AS $$ BEGIN RETURN coalesce($1,0) + coalesce($2,0); END; $$;
167CREATE AGGREGATE schema_two.newton
168  (BASETYPE = int, SFUNC = schema_two.add, STYPE = int);
169RESET SESSION AUTHORIZATION;
170CREATE TABLE undroppable_objs (
171	object_type text,
172	object_identity text
173);
174INSERT INTO undroppable_objs VALUES
175('table', 'schema_one.table_three'),
176('table', 'audit_tbls.schema_two_table_three');
177CREATE TABLE dropped_objects (
178	type text,
179	schema text,
180	object text
181);
182-- This tests errors raised within event triggers; the one in audit_tbls
183-- uses 2nd-level recursive invocation via test_evtrig_dropped_objects().
184CREATE OR REPLACE FUNCTION undroppable() RETURNS event_trigger
185LANGUAGE plpgsql AS $$
186DECLARE
187	obj record;
188BEGIN
189	PERFORM 1 FROM pg_tables WHERE tablename = 'undroppable_objs';
190	IF NOT FOUND THEN
191		RAISE NOTICE 'table undroppable_objs not found, skipping';
192		RETURN;
193	END IF;
194	FOR obj IN
195		SELECT * FROM pg_event_trigger_dropped_objects() JOIN
196			undroppable_objs USING (object_type, object_identity)
197	LOOP
198		RAISE EXCEPTION 'object % of type % cannot be dropped',
199			obj.object_identity, obj.object_type;
200	END LOOP;
201END;
202$$;
203CREATE EVENT TRIGGER undroppable ON sql_drop
204	EXECUTE PROCEDURE undroppable();
205CREATE OR REPLACE FUNCTION test_evtrig_dropped_objects() RETURNS event_trigger
206LANGUAGE plpgsql AS $$
207DECLARE
208    obj record;
209BEGIN
210    FOR obj IN SELECT * FROM pg_event_trigger_dropped_objects()
211    LOOP
212        IF obj.object_type = 'table' THEN
213                EXECUTE format('DROP TABLE IF EXISTS audit_tbls.%I',
214					format('%s_%s', obj.schema_name, obj.object_name));
215        END IF;
216
217	INSERT INTO dropped_objects
218		(type, schema, object) VALUES
219		(obj.object_type, obj.schema_name, obj.object_identity);
220    END LOOP;
221END
222$$;
223CREATE EVENT TRIGGER regress_event_trigger_drop_objects ON sql_drop
224	WHEN TAG IN ('drop table', 'drop function', 'drop view',
225		'drop owned', 'drop schema', 'alter table')
226	EXECUTE PROCEDURE test_evtrig_dropped_objects();
227ALTER TABLE schema_one.table_one DROP COLUMN a;
228DROP SCHEMA schema_one, schema_two CASCADE;
229NOTICE:  drop cascades to 7 other objects
230DETAIL:  drop cascades to table schema_two.table_two
231drop cascades to table schema_two.table_three
232drop cascades to function schema_two.add(integer,integer)
233drop cascades to function schema_two.newton(integer)
234drop cascades to table schema_one.table_one
235drop cascades to table schema_one."table two"
236drop cascades to table schema_one.table_three
237NOTICE:  table "schema_two_table_two" does not exist, skipping
238NOTICE:  table "audit_tbls_schema_two_table_three" does not exist, skipping
239ERROR:  object audit_tbls.schema_two_table_three of type table cannot be dropped
240CONTEXT:  PL/pgSQL function undroppable() line 14 at RAISE
241SQL statement "DROP TABLE IF EXISTS audit_tbls.schema_two_table_three"
242PL/pgSQL function test_evtrig_dropped_objects() line 8 at EXECUTE
243DELETE FROM undroppable_objs WHERE object_identity = 'audit_tbls.schema_two_table_three';
244DROP SCHEMA schema_one, schema_two CASCADE;
245NOTICE:  drop cascades to 7 other objects
246DETAIL:  drop cascades to table schema_two.table_two
247drop cascades to table schema_two.table_three
248drop cascades to function schema_two.add(integer,integer)
249drop cascades to function schema_two.newton(integer)
250drop cascades to table schema_one.table_one
251drop cascades to table schema_one."table two"
252drop cascades to table schema_one.table_three
253NOTICE:  table "schema_two_table_two" does not exist, skipping
254NOTICE:  table "audit_tbls_schema_two_table_three" does not exist, skipping
255NOTICE:  table "schema_one_table_one" does not exist, skipping
256NOTICE:  table "schema_one_table two" does not exist, skipping
257NOTICE:  table "schema_one_table_three" does not exist, skipping
258ERROR:  object schema_one.table_three of type table cannot be dropped
259CONTEXT:  PL/pgSQL function undroppable() line 14 at RAISE
260DELETE FROM undroppable_objs WHERE object_identity = 'schema_one.table_three';
261DROP SCHEMA schema_one, schema_two CASCADE;
262NOTICE:  drop cascades to 7 other objects
263DETAIL:  drop cascades to table schema_two.table_two
264drop cascades to table schema_two.table_three
265drop cascades to function schema_two.add(integer,integer)
266drop cascades to function schema_two.newton(integer)
267drop cascades to table schema_one.table_one
268drop cascades to table schema_one."table two"
269drop cascades to table schema_one.table_three
270NOTICE:  table "schema_two_table_two" does not exist, skipping
271NOTICE:  table "audit_tbls_schema_two_table_three" does not exist, skipping
272NOTICE:  table "schema_one_table_one" does not exist, skipping
273NOTICE:  table "schema_one_table two" does not exist, skipping
274NOTICE:  table "schema_one_table_three" does not exist, skipping
275SELECT * FROM dropped_objects WHERE schema IS NULL OR schema <> 'pg_toast';
276     type     |   schema   |               object
277--------------+------------+-------------------------------------
278 table column | schema_one | schema_one.table_one.a
279 schema       |            | schema_two
280 table        | schema_two | schema_two.table_two
281 type         | schema_two | schema_two.table_two
282 type         | schema_two | schema_two.table_two[]
283 table        | audit_tbls | audit_tbls.schema_two_table_three
284 type         | audit_tbls | audit_tbls.schema_two_table_three
285 type         | audit_tbls | audit_tbls.schema_two_table_three[]
286 table        | schema_two | schema_two.table_three
287 type         | schema_two | schema_two.table_three
288 type         | schema_two | schema_two.table_three[]
289 function     | schema_two | schema_two.add(integer,integer)
290 aggregate    | schema_two | schema_two.newton(integer)
291 schema       |            | schema_one
292 table        | schema_one | schema_one.table_one
293 type         | schema_one | schema_one.table_one
294 type         | schema_one | schema_one.table_one[]
295 table        | schema_one | schema_one."table two"
296 type         | schema_one | schema_one."table two"
297 type         | schema_one | schema_one."table two"[]
298 table        | schema_one | schema_one.table_three
299 type         | schema_one | schema_one.table_three
300 type         | schema_one | schema_one.table_three[]
301(23 rows)
302
303DROP OWNED BY regress_evt_user;
304NOTICE:  schema "audit_tbls" does not exist, skipping
305SELECT * FROM dropped_objects WHERE type = 'schema';
306  type  | schema |   object
307--------+--------+------------
308 schema |        | schema_two
309 schema |        | schema_one
310 schema |        | audit_tbls
311(3 rows)
312
313DROP ROLE regress_evt_user;
314DROP EVENT TRIGGER regress_event_trigger_drop_objects;
315DROP EVENT TRIGGER undroppable;
316CREATE OR REPLACE FUNCTION event_trigger_report_dropped()
317 RETURNS event_trigger
318 LANGUAGE plpgsql
319AS $$
320DECLARE r record;
321BEGIN
322    FOR r IN SELECT * from pg_event_trigger_dropped_objects()
323    LOOP
324    IF NOT r.normal AND NOT r.original THEN
325        CONTINUE;
326    END IF;
327    RAISE NOTICE 'NORMAL: orig=% normal=% istemp=% type=% identity=% name=% args=%',
328        r.original, r.normal, r.is_temporary, r.object_type,
329        r.object_identity, r.address_names, r.address_args;
330    END LOOP;
331END; $$;
332CREATE EVENT TRIGGER regress_event_trigger_report_dropped ON sql_drop
333    EXECUTE PROCEDURE event_trigger_report_dropped();
334CREATE SCHEMA evttrig
335	CREATE TABLE one (col_a SERIAL PRIMARY KEY, col_b text DEFAULT 'forty two')
336	CREATE INDEX one_idx ON one (col_b)
337	CREATE TABLE two (col_c INTEGER CHECK (col_c > 0) REFERENCES one DEFAULT 42);
338-- Partitioned tables
339CREATE TABLE evttrig.parted (
340    id int)
341    PARTITION BY RANGE (id);
342CREATE TABLE evttrig.part_1_10 PARTITION OF evttrig.parted (id)
343  FOR VALUES FROM (1) TO (10);
344CREATE TABLE evttrig.part_10_20 PARTITION OF evttrig.parted (id)
345  FOR VALUES FROM (10) TO (20) PARTITION BY RANGE (id);
346CREATE TABLE evttrig.part_10_15 PARTITION OF evttrig.part_10_20 (id)
347  FOR VALUES FROM (10) TO (15);
348CREATE TABLE evttrig.part_15_20 PARTITION OF evttrig.part_10_20 (id)
349  FOR VALUES FROM (15) TO (20);
350ALTER TABLE evttrig.two DROP COLUMN col_c;
351NOTICE:  NORMAL: orig=t normal=f istemp=f type=table column identity=evttrig.two.col_c name={evttrig,two,col_c} args={}
352NOTICE:  NORMAL: orig=f normal=t istemp=f type=table constraint identity=two_col_c_check on evttrig.two name={evttrig,two,two_col_c_check} args={}
353ALTER TABLE evttrig.one ALTER COLUMN col_b DROP DEFAULT;
354NOTICE:  NORMAL: orig=t normal=f istemp=f type=default value identity=for evttrig.one.col_b name={evttrig,one,col_b} args={}
355ALTER TABLE evttrig.one DROP CONSTRAINT one_pkey;
356NOTICE:  NORMAL: orig=t normal=f istemp=f type=table constraint identity=one_pkey on evttrig.one name={evttrig,one,one_pkey} args={}
357DROP INDEX evttrig.one_idx;
358NOTICE:  NORMAL: orig=t normal=f istemp=f type=index identity=evttrig.one_idx name={evttrig,one_idx} args={}
359DROP SCHEMA evttrig CASCADE;
360NOTICE:  drop cascades to 3 other objects
361DETAIL:  drop cascades to table evttrig.one
362drop cascades to table evttrig.two
363drop cascades to table evttrig.parted
364NOTICE:  NORMAL: orig=t normal=f istemp=f type=schema identity=evttrig name={evttrig} args={}
365NOTICE:  NORMAL: orig=f normal=t istemp=f type=table identity=evttrig.one name={evttrig,one} args={}
366NOTICE:  NORMAL: orig=f normal=t istemp=f type=sequence identity=evttrig.one_col_a_seq name={evttrig,one_col_a_seq} args={}
367NOTICE:  NORMAL: orig=f normal=t istemp=f type=default value identity=for evttrig.one.col_a name={evttrig,one,col_a} args={}
368NOTICE:  NORMAL: orig=f normal=t istemp=f type=table identity=evttrig.two name={evttrig,two} args={}
369NOTICE:  NORMAL: orig=f normal=t istemp=f type=table identity=evttrig.parted name={evttrig,parted} args={}
370NOTICE:  NORMAL: orig=f normal=t istemp=f type=table identity=evttrig.part_1_10 name={evttrig,part_1_10} args={}
371NOTICE:  NORMAL: orig=f normal=t istemp=f type=table identity=evttrig.part_10_20 name={evttrig,part_10_20} args={}
372NOTICE:  NORMAL: orig=f normal=t istemp=f type=table identity=evttrig.part_10_15 name={evttrig,part_10_15} args={}
373NOTICE:  NORMAL: orig=f normal=t istemp=f type=table identity=evttrig.part_15_20 name={evttrig,part_15_20} args={}
374DROP TABLE a_temp_tbl;
375NOTICE:  NORMAL: orig=t normal=f istemp=t type=table identity=pg_temp.a_temp_tbl name={pg_temp,a_temp_tbl} args={}
376DROP EVENT TRIGGER regress_event_trigger_report_dropped;
377-- only allowed from within an event trigger function, should fail
378select pg_event_trigger_table_rewrite_oid();
379ERROR:  pg_event_trigger_table_rewrite_oid() can only be called in a table_rewrite event trigger function
380-- test Table Rewrite Event Trigger
381CREATE OR REPLACE FUNCTION test_evtrig_no_rewrite() RETURNS event_trigger
382LANGUAGE plpgsql AS $$
383BEGIN
384  RAISE EXCEPTION 'rewrites not allowed';
385END;
386$$;
387create event trigger no_rewrite_allowed on table_rewrite
388  execute procedure test_evtrig_no_rewrite();
389create table rewriteme (id serial primary key, foo float);
390insert into rewriteme
391     select x * 1.001 from generate_series(1, 500) as t(x);
392alter table rewriteme alter column foo type numeric;
393ERROR:  rewrites not allowed
394CONTEXT:  PL/pgSQL function test_evtrig_no_rewrite() line 3 at RAISE
395alter table rewriteme add column baz int default 0;
396ERROR:  rewrites not allowed
397CONTEXT:  PL/pgSQL function test_evtrig_no_rewrite() line 3 at RAISE
398-- test with more than one reason to rewrite a single table
399CREATE OR REPLACE FUNCTION test_evtrig_no_rewrite() RETURNS event_trigger
400LANGUAGE plpgsql AS $$
401BEGIN
402  RAISE NOTICE 'Table ''%'' is being rewritten (reason = %)',
403               pg_event_trigger_table_rewrite_oid()::regclass,
404               pg_event_trigger_table_rewrite_reason();
405END;
406$$;
407alter table rewriteme
408 add column onemore int default 0,
409 add column another int default -1,
410 alter column foo type numeric(10,4);
411NOTICE:  Table 'rewriteme' is being rewritten (reason = 6)
412-- shouldn't trigger a table_rewrite event
413alter table rewriteme alter column foo type numeric(12,4);
414-- typed tables are rewritten when their type changes.  Don't emit table
415-- name, because firing order is not stable.
416CREATE OR REPLACE FUNCTION test_evtrig_no_rewrite() RETURNS event_trigger
417LANGUAGE plpgsql AS $$
418BEGIN
419  RAISE NOTICE 'Table is being rewritten (reason = %)',
420               pg_event_trigger_table_rewrite_reason();
421END;
422$$;
423create type rewritetype as (a int);
424create table rewritemetoo1 of rewritetype;
425create table rewritemetoo2 of rewritetype;
426alter type rewritetype alter attribute a type text cascade;
427NOTICE:  Table is being rewritten (reason = 4)
428NOTICE:  Table is being rewritten (reason = 4)
429-- but this doesn't work
430create table rewritemetoo3 (a rewritetype);
431alter type rewritetype alter attribute a type varchar cascade;
432ERROR:  cannot alter type "rewritetype" because column "rewritemetoo3.a" uses it
433drop table rewriteme;
434drop event trigger no_rewrite_allowed;
435drop function test_evtrig_no_rewrite();
436-- test Row Security Event Trigger
437RESET SESSION AUTHORIZATION;
438CREATE TABLE event_trigger_test (a integer, b text);
439CREATE OR REPLACE FUNCTION start_command()
440RETURNS event_trigger AS $$
441BEGIN
442RAISE NOTICE '% - ddl_command_start', tg_tag;
443END;
444$$ LANGUAGE plpgsql;
445CREATE OR REPLACE FUNCTION end_command()
446RETURNS event_trigger AS $$
447BEGIN
448RAISE NOTICE '% - ddl_command_end', tg_tag;
449END;
450$$ LANGUAGE plpgsql;
451CREATE OR REPLACE FUNCTION drop_sql_command()
452RETURNS event_trigger AS $$
453BEGIN
454RAISE NOTICE '% - sql_drop', tg_tag;
455END;
456$$ LANGUAGE plpgsql;
457CREATE EVENT TRIGGER start_rls_command ON ddl_command_start
458    WHEN TAG IN ('CREATE POLICY', 'ALTER POLICY', 'DROP POLICY') EXECUTE PROCEDURE start_command();
459CREATE EVENT TRIGGER end_rls_command ON ddl_command_end
460    WHEN TAG IN ('CREATE POLICY', 'ALTER POLICY', 'DROP POLICY') EXECUTE PROCEDURE end_command();
461CREATE EVENT TRIGGER sql_drop_command ON sql_drop
462    WHEN TAG IN ('DROP POLICY') EXECUTE PROCEDURE drop_sql_command();
463CREATE POLICY p1 ON event_trigger_test USING (FALSE);
464NOTICE:  CREATE POLICY - ddl_command_start
465NOTICE:  CREATE POLICY - ddl_command_end
466ALTER POLICY p1 ON event_trigger_test USING (TRUE);
467NOTICE:  ALTER POLICY - ddl_command_start
468NOTICE:  ALTER POLICY - ddl_command_end
469ALTER POLICY p1 ON event_trigger_test RENAME TO p2;
470NOTICE:  ALTER POLICY - ddl_command_start
471NOTICE:  ALTER POLICY - ddl_command_end
472DROP POLICY p2 ON event_trigger_test;
473NOTICE:  DROP POLICY - ddl_command_start
474NOTICE:  DROP POLICY - sql_drop
475NOTICE:  DROP POLICY - ddl_command_end
476-- Check the object addresses of all the event triggers.
477SELECT
478    e.evtname,
479    pg_describe_object('pg_event_trigger'::regclass, e.oid, 0) as descr,
480    b.type, b.object_names, b.object_args,
481    pg_identify_object(a.classid, a.objid, a.objsubid) as ident
482  FROM pg_event_trigger as e,
483    LATERAL pg_identify_object_as_address('pg_event_trigger'::regclass, e.oid, 0) as b,
484    LATERAL pg_get_object_address(b.type, b.object_names, b.object_args) as a
485  ORDER BY e.evtname;
486      evtname      |              descr              |     type      |    object_names     | object_args |                         ident
487-------------------+---------------------------------+---------------+---------------------+-------------+--------------------------------------------------------
488 end_rls_command   | event trigger end_rls_command   | event trigger | {end_rls_command}   | {}          | ("event trigger",,end_rls_command,end_rls_command)
489 sql_drop_command  | event trigger sql_drop_command  | event trigger | {sql_drop_command}  | {}          | ("event trigger",,sql_drop_command,sql_drop_command)
490 start_rls_command | event trigger start_rls_command | event trigger | {start_rls_command} | {}          | ("event trigger",,start_rls_command,start_rls_command)
491(3 rows)
492
493DROP EVENT TRIGGER start_rls_command;
494DROP EVENT TRIGGER end_rls_command;
495DROP EVENT TRIGGER sql_drop_command;
496