Re: BUG #5798: Some weird error with pl/pgsql procedure

From: Merlin Moncure <mmoncure(at)gmail(dot)com>
To: Tom Lane <tgl(at)sss(dot)pgh(dot)pa(dot)us>
Cc: Maxim Boguk <maxim(dot)boguk(at)gmail(dot)com>, Robert Haas <robertmhaas(at)gmail(dot)com>, pgsql-bugs(at)postgresql(dot)org
Subject: Re: BUG #5798: Some weird error with pl/pgsql procedure
Date: 2011-06-14 14:39:29
Message-ID: BANLkTi=KvVsGfunz=v_6-qHVFk6AbOQeaw@mail.gmail.com
Views: Raw Message | Whole Thread | Download mbox | Resend email
Thread:
Lists: pgsql-bugs

On Mon, Feb 21, 2011 at 6:31 PM, Tom Lane <tgl(at)sss(dot)pgh(dot)pa(dot)us> wrote:
> 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.

I bumped into the 'virtual tuple' error on 9.0.3 on a completely
unrelated query:

create table foo(a int, b int);
insert into foo select 1, 1 where not exists (select 1 from foo where
a = 1 for update);

9.0.4 got rid of the error, but as there are no triggers or anything
like that on the foo so I thought I'd post my findings here in case
anyone else bumped into it.

merlin

In response to

Responses

Browse pgsql-bugs by date

  From Date Subject
Next Message Tom Lane 2011-06-14 14:55:27 Re: BUG #5798: Some weird error with pl/pgsql procedure
Previous Message Itagaki Takahiro 2011-06-14 13:42:29 Re: BUG #6056: sorting issues