Re: Trigger firing order

From: Steve Baldwin <steve(dot)baldwin(at)gmail(dot)com>
To: Tom Lane <tgl(at)sss(dot)pgh(dot)pa(dot)us>
Cc: pgsql-novice <pgsql-novice(at)postgresql(dot)org>
Subject: Re: Trigger firing order
Date: 2018-05-17 00:54:06
Message-ID: CAKE1AiYdU8+rBio+k+Ndws6KTFe0nV3ppYs81GsNj28qstKvfw@mail.gmail.com
Views: Raw Message | Whole Thread | Download mbox | Resend email
Thread:
Lists: pgsql-novice

Thanks again Tom. I really appreciate the time you take to respond to my
noob questions.

Steve

On Thu, May 17, 2018 at 8:04 AM, Tom Lane <tgl(at)sss(dot)pgh(dot)pa(dot)us> wrote:

> Steve Baldwin <steve(dot)baldwin(at)gmail(dot)com> writes:
> > I'm using triggers to implement a DML auditing mechanism. I've been doing
> > some testing around cascading foreign key constraints and the results
> > surprised me (and somewhat busted my mechanism haha). I was hoping to be
> > able to log statement level data as well as actual row changes that link
> > back to the logged statement.
>
> > ...
>
> > What surprised me was the after statement trigger for t2 and 1+ of the
> > after row triggers for t2 fired after the after statement trigger for t1.
>
> Yeah. The reason is that all the "after" triggers fired by the outer
> statement on t1 (the RI enforcement triggers, and your a_ar triggers on
> t1, and your a_as trigger on t1) are queued up, then when the RI
> enforcement triggers run and cause additional "after" trigger events
> to be queued (the ones for t2), those go onto the end of the queue.
>
> > I guess I had imagined all operations for 'nested' tables would complete
> > before executing the after statement trigger of the outermost 'invoking'
> > table. (I'm coming from having used Oracle for many years).
>
> We could easily fire the newly-queued "after" triggers before returning
> from each RI enforcement trigger, but that creates a new set of problems:
> those triggers would see an incompletely-updated state of t2, if more RI
> enforcement actions remain in the queue. Essentially that would make
> visible the fact that whatever cascade actions need to be done are done
> in a separate command for each cascaded-from row, whereas the SQL spec
> would have us make it look like all the cascade effects occur in a single
> statement. So we do it like this instead. (I'm not totally wedded to
> this as being a great idea, but rejiggering it would be a complex task
> with probably not a lot of payoff in the end.)
>
> > Can anyone point me to somewhere in the docs where this behaviour is
> > explained?
>
> I doubt it's terribly well documented :-(
>
> > I understand postgres FK's are implement with triggers. How do I
> > find them so I can see what they're doing and hopefully better understand
> > the mechanism?
>
> Just look into pg_trigger, eg
>
> SELECT t.tgname, pg_catalog.pg_get_triggerdef(t.oid, true), t.tgisinternal
> FROM pg_catalog.pg_trigger t
> WHERE t.tgrelid = 'mytable'::regclass
> ORDER BY 1;
>
> (psql's \d command does essentially this to show you a table's triggers,
> but it skips "tgisinternal" triggers which is why you don't see the RI
> triggers.)
>
> regards, tom lane
>

In response to

Browse pgsql-novice by date

  From Date Subject
Next Message Stephen Froehlich 2018-05-18 14:59:55 pgbackrest archive-push exit code 25
Previous Message Tom Lane 2018-05-16 22:04:59 Re: Trigger firing order