Re: BUG #17792: MERGE uses uninitialized pointer and crashes when target tuple is updated concurrently

Dean Rasheed <dean.a.rasheed@gmail.com>

From: Dean Rasheed <dean.a.rasheed@gmail.com>
To: Alvaro Herrera <alvherre@alvh.no-ip.org>
Cc: exclusion@gmail.com, pgsql-bugs@lists.postgresql.org
Date: 2023-02-15T09:41:13Z
Lists: pgsql-bugs
On Tue, 14 Feb 2023 at 19:19, Alvaro Herrera <alvherre@alvh.no-ip.org> wrote:
>
> I agree, this looks to be a good fix.  However, I couldn't in a quick
> try reproduce the problem, so I haven't been able to verify it.  I'll
> try to do that early tomorrow.
>

I did some more testing, and the fix looks good.

> (I also delete the XXX comment there.)
>

That makes sense. It's a bit inconsistent (though not related to this
bug) that a cross-partition update will return OK if the tuple was
concurrently deleted, so merge will think that it updated the tuple
and not try an insert action, whereas for a normal update it will try
an insert action if the tuple was concurrently deleted. The thing that
seems wrong there is that ExecUpdateAct() sets updateCxt->updated =
true for a cross-partition update regardless of whether it actually
executed the insert half of the update/move. In theory, that flag
could be set to false so that merge would know if the tuple was
concurrently deleted, though it's not clear if it's worth it.

Regards,
Dean



Commits

  1. Don't rely on uninitialized value in MERGE / DELETE