0

I'm using logical replication and managed to have the trigger fire when I have the following:

CREATE TRIGGER set_updated_time_trig
    AFTER INSERT OR UPDATE OR DELETE ON test
    FOR EACH ROW EXECUTE FUNCTION set_updated_time();

alter table test enable always trigger set_updated_time_trig;

I tried with ALWAYS -> REPLICA too.

But when I use for each STATEMENT, it is no longer working. I prefer to use for each statement since I can add also OR TRUNCATE.

CREATE TRIGGER set_updated_time_trig
    AFTER INSERT OR UPDATE OR DELETE ON test
    FOR EACH STATEMENT EXECUTE FUNCTION set_updated_time();

How can I have a trigger that is fired on Truncate?

Laurenz Albe
  • 209,280
  • 17
  • 206
  • 263
user1409708
  • 953
  • 2
  • 11
  • 20

1 Answers1

0

That can never work, because it is rows that are replicated, not statements. If you run an UPDATE that changes ten rows, the standby will modify those ten individual rows. Contrariwise, if the UPDATE changes no row, nothing will be replicated. So it wouldn't make sense to execute statement level triggers on the standby, because they wouldn't work differently from row level triggers.

Laurenz Albe
  • 209,280
  • 17
  • 206
  • 263
  • Very good explanation. Was not aware of this, thanks! – Tom Nov 30 '22 at 12:50
  • Thanks! If it is not supported, shouldn't it raise an exception upon trigger creation? – user1409708 Dec 01 '22 at 12:15
  • An exception would be too much, but a warning might be a good idea. You could write a patch or suggest it on the pgsql-hackers mailing list. – Laurenz Albe Dec 01 '22 at 12:30
  • 2
    A clarification I got from pgsql-hackers group. The trigger is fired only during the initial table synchronization since it is implemented like a COPY command and thus fires both row and statement triggers for INSERT. – user1409708 Dec 04 '22 at 15:39