I have an INSERT statement in Postgres 9.5+, but the INSERT sometimes doesn't actually happen because of a key conflict (I've set ON CONFLICT DO NOTHING on the INSERT).
If the INSERT happens, then of course the trigger runs. But if the INSERT doesn't happen because of a key conflict, will triggers still run?
Does it depend on whether it's a BEFORE or AFTER trigger?
Per-row
BEFORE INSERTtriggers are fired, and possible effects on the proposed row applied, before checking for conflicts. The manual:A plain
INSERTwould raise anEXCEPTIONbecause of the unique violation, and that rolls back everything (except what cannot be rolled back, like incrementing a sequence).But the UPSERT with
ON CONFLICT DO NOTHINGsuppresses the exception, hence the effects of any such triggers persist, even if the row proposed for insertion is skipped.(Consequently, when using
ON CONFLICT DO UPDATE ..., effects of such triggers are reflected in the specialEXCLUDEDrow that's visible in theUPDATEpart.)But
AFTER INSERTtriggers are not even fired for either case. The row is never actually inserted - with or without raising an exception.I thought of using a
RULEinstead, which can rewrite anINSERTto run additional commands, independent of the outcome. More tricky than a trigger, but it kicks in before theINSERTmight be cancelled. However, the manual warns:So, no dice.