Re: Incorrect UPDATE trigger invocation in the UPDATE clause of an UPSERT statement.

From: Peter Geoghegan <pg(at)heroku(dot)com>
To: Michael Paquier <michael(dot)paquier(at)gmail(dot)com>
Cc: Dean Rasheed <dean(dot)a(dot)rasheed(at)gmail(dot)com>, Stanislav Grozev <tacho(at)daemonz(dot)org>, PostgreSQL mailing lists <pgsql-bugs(at)postgresql(dot)org>, Andres Freund <andres(at)anarazel(dot)de>
Subject: Re: Incorrect UPDATE trigger invocation in the UPDATE clause of an UPSERT statement.
Date: 2015-12-04 01:34:12
Message-ID: CAM3SWZSiX3_6H149ZH6QF8Y9LuaYgpg1218bbF9_cjvyykaK4w@mail.gmail.com
Views: Raw Message | Whole Thread | Download mbox | Resend email
Thread:
Lists: pgsql-bugs

On Thu, Dec 3, 2015 at 1:10 PM, Peter Geoghegan <pg(at)heroku(dot)com> wrote:
> I'll need to think about a fix.

The problem was with the pointer we pass to ExecUpdate().

It's a pointer to the target tuple in shared memory. So the field
"tuple.t_data->t_ctid" within ExecOnConflictUpdate() starts out
pointing to an ItemPointerData with the correct ctid (when it
initially points to the current/target tuple, since as an
about-to-be-upserted tuple the "t_ctid" field must be a pointer to the
self-same tuple). Then, it is modified in-place in shared memory by
heap_update(), within its critical section.

The fix is to take a deep copy (pass a pointer to an ItemPointerData
on the stack), as in the attached. I've also fixed up the tests, which
should have caught this, but didn't. Mea culpa.

Many thanks to Stanislav for the report! While I didn't adopt his
suggestion, he certainly almost had it right.

--
Peter Geoghegan

Attachment Content-Type Size
0001-Fix-stray-pointer-bug-in-ExecOnConflictUpdate.patch text/x-patch 5.0 KB

In response to

Responses

Browse pgsql-bugs by date

  From Date Subject
Next Message Peter Eisentraut 2015-12-04 03:22:31 Re: pg_rewind exiting with error code 1 when source and target are on the same timeline
Previous Message peter 2015-12-04 00:18:27 BUG #13794: pgAdmin Crash on launch