Re: BUG #14870: wrong query results when using WITH with UPDATE
Marko Tiikkaja <marko@joh.to>
From: Marko Tiikkaja <marko@joh.to>
To: andreigorita@gmail.com
Cc: Pg Bugs <pgsql-bugs@postgresql.org>
Date: 2017-11-11T12:05:33Z
Lists: pgsql-bugs
Commits
Same data as JSON:
GET /api/v1/messages/:b64id/commits
the thread's linked commits as JSON, with link sources.
API reference →
-
Fix misbehavior of CTE-used-in-a-subplan during EPQ rechecks.
- 159efe4af450 11.0 landed
- ea6d67cf8e01 9.3.22 landed
- e11b6488e5a7 9.4.17 landed
- 795f2112ea28 9.6.8 landed
- 517e0fe866c6 10.3 landed
- 340d63bfb369 9.5.12 landed
Hi Andrei,
On Tue, Oct 24, 2017 at 6:53 PM, <andreigorita@gmail.com> wrote:
> test=> WITH updated AS (UPDATE tmp_test SET test = 'test' WHERE id = 1
> RETURNING id), inserted AS (INSERT INTO tmp_test2 (id, test) SELECT 1,
> 'test' WHERE NOT EXISTS (SELECT 1 FROM updated) RETURNING id) SELECT * FROM
> updated;
> id
> ----
> 1
> (1 row)
>
> This is the expected result, but when another session is executing in
> parallel:
>
> the result is:
>
> id
> ----
> 1
> 1
> (2 rows)
>
Right. We don't actually need tmp_test2 to trigger the bug, we simply need
an InitPlan on the CTE. This query:
WITH updated AS (
UPDATE tmp_test SET test = 'test' WHERE id = 1
RETURNING id
)
SELECT (SELECT 1 FROM updated), * FROM updated
has the same problem. The query plan looks like this:
CTE Scan on updated (actual rows=2 loops=1)
CTE updated
-> Update on tmp_test (actual rows=1 loops=1)
-> Index Scan using tmp_test_id_idx on tmp_test (actual rows=1
loops=1)
Index Cond: (id = 1)
InitPlan 2 (returns $2)
-> CTE Scan on updated updated_1 (actual rows=1 loops=1)
As you said, this problem only occurs when the row changed by the CTE is
concurrently UPDATEd, so I'm guessing something goes wrong with EPQ here.
.m