Robert Haas <robertmhaas(at)gmail(dot)com> wrote:
> Florian Pflug <fgp(at)phlo(dot)org> wrote:
>> Here's a step-by-step description of what happens in the case of
>> two UPDATES, assuming that we don't ignore any updated and throw
>> no error.
>>
>> 1) UPDATE T SET ... WHERE ID=1
>> 2) Row with ID=1 is found & locked
>> 3) BEFORE UPDATE triggers are fired, with OLD containing the
>> original row's contents and NEW the values specified in (1)
>> 4) UPDATE T SET ... WHERE ID=1, executed from within one of the
>> triggers
>> 5) BEFORE UPDATE triggers are fired again, with OLD containing
>> the original row's contents and NEW the value specified in
>> (4).
>> 6) The row is updated with the values specified in (4), possibly
>> changed by the triggers in (5)
>> 7) The row is updated with the values specified in (2), possibly
>> changed by the triggers in (3).
>> The different between Kevin's original patch and my suggestion
>> is, BTW, that he made step (7) through an error while I suggested
>> the error to be thrown already at (4).
>
> I think Kevin's proposal is better, because AFAICS if the BEFORE
> UPDATE trigger returns NULL then we haven't got a problem; and we
> can't know that until we get to step 7.
Robert makes a good point -- at step 4 we can't know whether the
BEFORE trigger will return an unmodified record, a modified record,
or NULL. Without some way to deal with that, an throwing the error
earlier seems like a non-starter.
-Kevin