I have a PostgreSQL trigger that is not firing sometimes, even though the status is always shown as "enabled".
My trigger code is as follows:
CREATE OR REPLACE FUNCTION audit_src_exhibit() RETURNS trigger AS $BODY$
BEGIN
IF TG_OP = 'INSERT' then
if new.audit_created_date is null THEN
new.audit_created_date := current_timestamp;
new.audit_created_by := session_user::text;
end if;
else
if new.audit_modified_date is null THEN
new.audit_modified_date := current_timestamp;
new.audit_modified_by := session_user::text;
end if;
END IF;
RETURN NEW;
END; $BODY$ LANGUAGE plpgsql VOLATILE;
CREATE TRIGGER audit_src_exhibit_tr
BEFORE INSERT OR UPDATE ON <table>
FOR EACH ROW EXECUTE PROCEDURE audit_src_exhibit();
Is there any specific reason for this behaviour? Does my code show any signs of known issues which would result in triggers not firing?
I find the audit columns populated as null when some insert happened today
select audit_created_date
from sd_source_exhibit_link
where audit_created_date is null;
MY Table DDL :
CREATE TABLE source_domain.sd_source_exhibit_link (
source_exhibit_link_id serial DEFAULT nextval('sd_source_exhibit_link_source_exhibit_link_id_seq'::regclass) NOT NULL,
source_exhibit_id varchar(300),
source_entity_id varchar(300),
created_by_provenance varchar(200),
occurence_id varchar(200),
source_matched_percentage int4,
link_type varchar(200),
soft_deleted varchar(50),
is_inner_exhibit bool DEFAULT false,
is_skinny_exhibit bool DEFAULT false NOT NULL,
provided_by varchar(500),
audit_created_date timestamptz NOT NULL,
audit_created_by varchar(100) NOT NULL,
audit_modified_date timestamptz,
audit_modified_by varchar(100),
CONSTRAINT sd_source_exhibit_link_pkey PRIMARY KEY (source_exhibit_link_id)
);
CREATE INDEX idx_source_exhibit_link ON source_domain.sd_source_exhibit_link (occurence_id);
3 Answers 3
I think the issue isn't that the trigger isn't firing.
Looking at the trigger code, you only check if new.audit_created_date is null
if TG_OP = 'INSERT'
.
That means you can perform an UPDATE
, setting audit_create_date
to NULL
; the trigger would still fire, but the first branch of the IF
, which sets new.audit_create_date
to current_timestamp
, would not execute as TG_OP
is not equal to INSERT
.
In that case, new.audit_create_date
would still be NULL
after trigger execution.
there are a lot of IF statement without else statement that can generate the situation you are telling.
Examples:
- TG_OP is always INSERT? Or can be "Insert"? (case sensitive problem)
- IF "new.audit_created_date is null".. else???
- and again similar.
For debug, you can think about a table in which you write when TRIGGER do nothing.
ExAMPLES:
- IF TG_OP = 'INSERT' then "doWork()" else "add in table "tg_op = value"".
I dont' think database not fire insert, I think you are skipping some IF branch.
-
1Read the docs plpgsql trigger TG_OP Data type text; a string of INSERT, UPDATE, DELETE, or TRUNCATE telling for which operation the trigger was fired. This is not really an answer.Adrian Klaver– Adrian Klaver2023年02月07日 16:02:07 +00:00Commented Feb 7, 2023 at 16:02
As @cogitoergosum mentioned above that's a DML possibility that nulls the created columns.
Or if session_replication_role is set to 'replica'.
Also to catch the errant DML, look into the possibility of changing the audit_created_* columns' constraint to not null. Since based on the trigger code, it seems like the intention is for those columns to always be populated.
it could also help if the table DDL is shared.
-
my session_replication_role -->'Origin'Arun– Arun2025年08月22日 07:18:12 +00:00Commented Aug 22 at 7:18
-
Tested this addin not not null on audit_created_date & audit_created_by since this needed on every insert and it is working but my issue intermittent dont know when this trigger actaully wont fireArun– Arun2025年08月22日 07:20:00 +00:00Commented Aug 22 at 7:20
-
Added the ddl in my question itselfArun– Arun2025年08月22日 07:21:51 +00:00Commented Aug 22 at 7:21
-
well, after adding the not null constraint, now all you have to do is wait for any applications/ users which error out. Check the logs. and hopefully your log_line_prefix will help ascertain that. Also FYI, any session setting is valid only for that session, if you wanted to test this in your session (the role setting i mentioned is a remote possibility) I would also suggest replying to Laurenz and improve the formatting for future referenceamacvar– amacvar2025年08月22日 14:54:46 +00:00Commented Aug 22 at 14:54
Explore related questions
See similar questions with these tags.
END IF
beforeELSE
). Please post your actual code or (bedder) a minimal reproducer that you tested. Then you claim that the trigger is not firing sometimes. How do you determine that? What is the exact DML statement that should invoke the trigger but doesn't? What is the resulting row, and how does that differ from what you expect?if
statements, and a lousy formatting......