Re: PL/pgSQL : notion of deferred execution

From: Frank van Vugt <ftm(dot)van(dot)vugt(at)foxi(dot)nl>
To: pgsql-general(at)postgresql(dot)org
Cc: Bruno Wolff III <bruno(at)wolff(dot)to>, Tom Lane <tgl(at)sss(dot)pgh(dot)pa(dot)us>
Subject: Re: PL/pgSQL : notion of deferred execution
Date: 2005-12-12 13:16:21
Message-ID: 200512121416.22274.ftm.van.vugt@foxi.nl
Views: Raw Message | Whole Thread | Download mbox | Resend email
Thread:
Lists: pgsql-general

> >> Ratio: when deferred triggers on table A are used to calculate field
> >> values of table B (which then obviously need an update), one might want
> >> to prevent direct updates on these fields of table B

[BW III]
> It might also work for you to do this with access rights.

Well, actually that's kinda how it's working at the moment, however I would
rather avoid this additional dependancy on user/role since it's really
field/situation-dependent (see below).

> > The triggers can have different access rights than the user that
> > caused the trigger to fire.

Yep, and one can even get a bit more granularity switching roles.

[TL]
> Yes. Keying this off whether the triggers are deferred or not seems
> a fairly bizarre choice --- that's surely not the primary property that
> should determine what they can do to table B.

Well, I didn't want to immediately bore the reader ;)

The choice wasn't made lightely, though. The underlying reason is a
performance enhancement. Basically, what's determining if the particular (!)
fields in B can be updated is the fact whether or not this is done from a
deferred trigger, as it is the sole place where this can be done efficiently.

Table A is updated quite a lot within the same transaction and often the same
rows are updated on different points in time. Table B is amongst other
things, holding derivative information of table A, but this data is difficult
to calculate, i.e. it takes time. A comparable situation would be that A is
holding orderlines and B holds orders with values *that take long to
calculate* because they depend on more rows of A than just the
inserted/changed/deleted one. Or maybe even better, the derivative info in
table B cannot be determined by solely using the inserted/updated/deleted
data in A.

Now, regular triggers obviously can take care of calculating the correct
values for B upon each update of a row in A, but due to the amount of updates
as well as the fact that a lot of the time rows in A are updated multiple
times, this resulted in bad (at least, too bad) performance earlier. I solved
this by using deferred triggers on A that are able to detect whether the
corresponding row of B has already been updated, thus making sure the complex
calculations are only done once.

Now, table B is also in regular use by normal users, so they need normal write
access and I'm keeping track of who's updating B when (your regular
updated_on/by fields and history tables).

> Also, it's quite unclear which part of the system you expect to enforce
> the restriction against which other part. The suggestion as stated seemed
> to be to let a trigger find out whether it itself is being fired in
> a deferred fashion, but surely you don't want to trust the trigger to decide
> whether it may update B.

Ah, no, the trigger must not decide the latter, whether or not B as a whole
may be updated solely depends (as it should) on the access rights of the user
running/triggering the code. It's more like I'm trying to prevent direct
updates of certain fields in B while knowing that the only way such update
can be done efficiently is from within these deferred triggers.

I can use a 'security definer' on the deferred triggers to allow switching
roles, then switch role within them and check for that with 'current_user' in
the regular triggers that will fire upon B's update, while still using
'session_user' to get to the original id that logged in. But as stated, given
the efficiency-knowledge I'd rather know where I'm called from.

I just wondered if there was a way to know the difference. Given the TG_WHEN
var I could imagine there was, but If there is not and it's also not
something expected to be 'nice to have', so be it, no problem ;)

Too bad TriggerEvent doesn't seem to make this info available, either ;)

--
Best,

Frank.

In response to

Responses

Browse pgsql-general by date

  From Date Subject
Next Message Terry Lee Tucker 2005-12-12 13:49:06 Re: Issue With PQftable()
Previous Message Marcus Engene 2005-12-12 12:39:53 Re: fts, compond words?