Re: data modifying WITH seems to drop rows in cascading updates -- bug?

Merlin Moncure <mmoncure@gmail.com>

From: Merlin Moncure <mmoncure@gmail.com>
To: Tom Lane <tgl@sss.pgh.pa.us>
Cc: pgsql-bugs <pgsql-bugs@lists.postgresql.org>
Date: 2019-08-24T03:02:03Z
Lists: pgsql-bugs
On Friday, August 23, 2019, Tom Lane <tgl@sss.pgh.pa.us> wrote:

> Merlin Moncure <mmoncure@gmail.com> writes:
> > Trying to figure out if this is undefined behavior of a bug. It's
> > confusing, and I'm aware of certain oddities in the fringes of the
> > data modifying with queries where the query dependencies are not
> > really clear.  Why does the query only return one row?
>
> > postgres=# create table foo(id int);
> > CREATE TABLE
> > postgres=# insert into foo values(1);
> > INSERT 0 1
> > postgres=# with a as (update foo set id = id + 1 returning *), b
> > as(update foo set id = id + 1 returning * ) select * from a union all
> > select id from b;
> >  id
> > ────
> >   2
> > (1 row)
>
> FWIW, I think it's intentional.  The two UPDATEs execute against the
> same snapshot, so only one of them can update the row --- the other
> one is going to see it as already-updated-by-self.  It's undefined
> only to the extent that it's not completely clear which one gets
> there first.  In this formulation of the outer query, I think it's
> pretty safe to assume that "a" will get there first, but if you'd
> joined "a" and "b" in some other fashion, conceivably "b" would.
>
> Note that the fine manual (sec. 7.8.2) says
>
>     Trying to update the same row twice in a single statement is not
>     supported. Only one of the modifications takes place, but it is not
>     easy (and sometimes not possible) to reliably predict which one. This
>     also applies to deleting a row that was already updated in the same
>     statement: only the update is performed. Therefore you should
>     generally avoid trying to modify a single row twice in a single
>     statement. In particular avoid writing WITH sub-statements that could
>     affect the same rows changed by the main statement or a sibling
>     sub-statement. The effects of such a statement will not be
>     predictable.
>

Right.  Shame on me for not checking the docs before posting.  Simply
stated, this is undefined behavior.

merlin