Re: BUG #5798: Some weird error with pl/pgsql procedure - Mailing list pgsql-bugs

From Tom Lane
Subject Re: BUG #5798: Some weird error with pl/pgsql procedure
Date
Msg-id 9875.1298334660@sss.pgh.pa.us
Whole thread Raw
In response to Re: BUG #5798: Some weird error with pl/pgsql procedure  (Tom Lane <tgl@sss.pgh.pa.us>)
Responses Re: BUG #5798: Some weird error with pl/pgsql procedure  (Maxim Boguk <maxim.boguk@gmail.com>)
Re: BUG #5798: Some weird error with pl/pgsql procedure  (Merlin Moncure <mmoncure@gmail.com>)
List pgsql-bugs
I wrote:
> Ugh.  That quick little "ExecRemoveJunk" is a lot more dangerous than it
> looks.  I had actually looked at this before, but concluded it was OK
> because I couldn't reproduce the problem with a trigger in place.
> I guess I wasn't unlucky enough to have the chance pointer equality
> occur.

On closer inspection, the palloc collision is actually extremely likely,
because what will happen is we'll pfree the old tuple and immediately
palloc the new one, and if the new one is of sufficiently similar size
that it needs the same size of alloc chunk, it's *guaranteed* to get
that same chunk back, because of the LIFO free-chunk chains in aset.c.

The reason that the problem is hard to reproduce is that most triggers
(certainly those written in plpgsql) will give back newly allocated
tuples even when you return the unmodified NEW tuple.  The only way to
expose the problem is for ExecBRUpdateTrigger's trigger-calling loop to
not replace the "newtuple", and the easiest way for that to happen is if
all the triggers are disabled.  So that's why you're seeing it when
fooling with the replication-role setting.  I was able to reproduce the
failure by creating a trigger with a false WHEN condition, and of course
there are other ways to prevent a trigger from being called too.

            regards, tom lane

pgsql-bugs by date:

Previous
From: Tom Lane
Date:
Subject: Re: BUG #5798: Some weird error with pl/pgsql procedure
Next
From: Mark Kirkwood
Date:
Subject: Hung Vacuum in 8.3