Now some foreign data wrappers support TRUNCATE command.
So it's useful to support TRUNCATE triggers on foreign tables for
audit logging or for preventing undesired truncation.
Author: Yugo Nagata
Reviewed-by: Fujii Masao, Ian Lawrence Barwick
Discussion: https://postgr.es/m/
20220630193848.
5b02e0d6076b86617a915682@sraoss.co.jp
TG_ARGV[0], TG_OP, TG_WHEN, TG_LEVEL;
RETURN NULL;
END;$$;
-CREATE TRIGGER trig_stmt_before BEFORE DELETE OR INSERT OR UPDATE ON rem1
+CREATE TRIGGER trig_stmt_before BEFORE DELETE OR INSERT OR UPDATE OR TRUNCATE ON rem1
FOR EACH STATEMENT EXECUTE PROCEDURE trigger_func();
-CREATE TRIGGER trig_stmt_after AFTER DELETE OR INSERT OR UPDATE ON rem1
+CREATE TRIGGER trig_stmt_after AFTER DELETE OR INSERT OR UPDATE OR TRUNCATE ON rem1
FOR EACH STATEMENT EXECUTE PROCEDURE trigger_func();
CREATE OR REPLACE FUNCTION trigger_data() RETURNS trigger
LANGUAGE plpgsql AS $$
NOTICE: trig_row_after(23, skidoo) AFTER ROW UPDATE ON rem1
NOTICE: OLD: (1,update),NEW: (1,updateupdate)
NOTICE: trigger_func(<NULL>) called: action = UPDATE, when = AFTER, level = STATEMENT
+truncate rem1;
+NOTICE: trigger_func(<NULL>) called: action = TRUNCATE, when = BEFORE, level = STATEMENT
+NOTICE: trigger_func(<NULL>) called: action = TRUNCATE, when = AFTER, level = STATEMENT
-- cleanup
DROP TRIGGER trig_row_before ON rem1;
DROP TRIGGER trig_row_after ON rem1;
NOTICE: NEW: (13,"test triggered !")
ctid
--------
- (0,32)
+ (0,25)
(1 row)
-- cleanup
RETURN NULL;
END;$$;
-CREATE TRIGGER trig_stmt_before BEFORE DELETE OR INSERT OR UPDATE ON rem1
+CREATE TRIGGER trig_stmt_before BEFORE DELETE OR INSERT OR UPDATE OR TRUNCATE ON rem1
FOR EACH STATEMENT EXECUTE PROCEDURE trigger_func();
-CREATE TRIGGER trig_stmt_after AFTER DELETE OR INSERT OR UPDATE ON rem1
+CREATE TRIGGER trig_stmt_after AFTER DELETE OR INSERT OR UPDATE OR TRUNCATE ON rem1
FOR EACH STATEMENT EXECUTE PROCEDURE trigger_func();
CREATE OR REPLACE FUNCTION trigger_data() RETURNS trigger
insert into rem1 values(1,'insert');
update rem1 set f2 = 'update' where f1 = 1;
update rem1 set f2 = f2 || f2;
+truncate rem1;
-- cleanup
<row>
<entry align="center"><command>TRUNCATE</command></entry>
<entry align="center">—</entry>
- <entry align="center">Tables</entry>
+ <entry align="center">Tables and foreign tables</entry>
</row>
<row>
<entry align="center" morerows="1"><literal>AFTER</literal></entry>
<row>
<entry align="center"><command>TRUNCATE</command></entry>
<entry align="center">—</entry>
- <entry align="center">Tables</entry>
+ <entry align="center">Tables and foreign tables</entry>
</row>
<row>
<entry align="center" morerows="1"><literal>INSTEAD OF</literal></entry>
RelationGetRelationName(rel)),
errdetail("Foreign tables cannot have INSTEAD OF triggers.")));
- if (TRIGGER_FOR_TRUNCATE(stmt->events))
- ereport(ERROR,
- (errcode(ERRCODE_WRONG_OBJECT_TYPE),
- errmsg("\"%s\" is a foreign table",
- RelationGetRelationName(rel)),
- errdetail("Foreign tables cannot have TRUNCATE triggers.")));
-
/*
* We disallow constraint triggers to protect the assumption that
* triggers on FKs can't be deferred. See notes with AfterTriggers