How Events Flowed — Summary¶
For each INSERT INTO records:
INSERT INTO records
→ records_after_insert trigger
→ pgrelay.notify('json_record', row_json) [event 1]
→ pgrelay.notify('audit_action', NEW_RECORD) [event 2]
Processor runs event 1: insert_json_record → INSERT INTO records_json
→ records_json_after_insert trigger
→ pgrelay.notify('audit_action', NEW_JSON_RECORD) [event 3]
Processor runs event 2: insert_audit_record → INSERT INTO records_audit
Processor runs event 3: insert_audit_record → INSERT INTO records_audit
For each UPDATE records:
UPDATE records
→ records_after_update trigger
→ pgrelay.notify('json_record', row_json) [event 1]
→ pgrelay.notify('audit_action', RECORD_UPDATED. ) [event 2]
Processor runs event 1: insert_json_record → UPDATE records_json (UPSERT conflict)
→ records_json_after_update trigger
→ pgrelay.notify('audit_action', UPDATED_JSON_RECORD) [event 3]
Processor runs event 2: insert_audit_record → INSERT INTO records_audit
Processor runs event 3: insert_audit_record → INSERT INTO records_audit
Notice that neither trigger function ever calls the other directly. Every step of this chain — from the original insert, through the JSON snapshot, to both audit entries — passes through pg_relay, and every step gets its own row in pgrelay.log.
Continue to Cleaning Up to remove everything this example created.