summaryrefslogtreecommitdiff
path: root/src/test
diff options
context:
space:
mode:
authorTom Lane2018-02-19 21:00:18 +0000
committerTom Lane2018-02-19 21:00:18 +0000
commite11b6488e5a70f870bc7069d7f08a9570ccd3fc2 (patch)
tree6be7353fbcc61cdd67648ec9c6b30c52384969cd /src/test
parent1bb87c0fae5e242b49518a12348f41231f90d45d (diff)
Fix misbehavior of CTE-used-in-a-subplan during EPQ rechecks.
An updating query that reads a CTE within an InitPlan or SubPlan could get incorrect results if it updates rows that are concurrently being modified. This is caused by CteScanNext supposing that nothing inside its recursive ExecProcNode call could change which read pointer is selected in the CTE's shared tuplestore. While that's normally true because of scoping considerations, it can break down if an EPQ plan tree gets built during the call, because EvalPlanQualStart builds execution trees for all subplans whether they're going to be used during the recheck or not. And it seems like a pretty shaky assumption anyway, so let's just reselect our own read pointer here. Per bug #14870 from Andrei Gorita. This has been broken since CTEs were implemented, so back-patch to all supported branches. Discussion: https://postgr.es/m/20171024155358.1471.82377@wrigleys.postgresql.org
Diffstat (limited to 'src/test')
-rw-r--r--src/test/isolation/expected/eval-plan-qual.out15
-rw-r--r--src/test/isolation/specs/eval-plan-qual.spec9
2 files changed, 24 insertions, 0 deletions
diff --git a/src/test/isolation/expected/eval-plan-qual.out b/src/test/isolation/expected/eval-plan-qual.out
index 99c4137e14a..be87d1b0c27 100644
--- a/src/test/isolation/expected/eval-plan-qual.out
+++ b/src/test/isolation/expected/eval-plan-qual.out
@@ -125,3 +125,18 @@ step readwcte: <... completed>
id value
1 tableAValue2
+
+starting permutation: wrtwcte multireadwcte c1 c2
+step wrtwcte: UPDATE table_a SET value = 'tableAValue2' WHERE id = 1;
+step multireadwcte:
+ WITH updated AS (
+ UPDATE table_a SET value = 'tableAValue3' WHERE id = 1 RETURNING id
+ )
+ SELECT (SELECT id FROM updated) AS subid, * FROM updated;
+ <waiting ...>
+step c1: COMMIT;
+step c2: COMMIT;
+step multireadwcte: <... completed>
+subid id
+
+1 1
diff --git a/src/test/isolation/specs/eval-plan-qual.spec b/src/test/isolation/specs/eval-plan-qual.spec
index f15dee385fc..749c6405796 100644
--- a/src/test/isolation/specs/eval-plan-qual.spec
+++ b/src/test/isolation/specs/eval-plan-qual.spec
@@ -94,6 +94,14 @@ step "readwcte" {
SELECT * FROM cte2;
}
+# this test exercises a different CTE misbehavior, cf bug #14870
+step "multireadwcte" {
+ WITH updated AS (
+ UPDATE table_a SET value = 'tableAValue3' WHERE id = 1 RETURNING id
+ )
+ SELECT (SELECT id FROM updated) AS subid, * FROM updated;
+}
+
teardown { COMMIT; }
permutation "wx1" "wx2" "c1" "c2" "read"
@@ -102,3 +110,4 @@ permutation "upsert1" "upsert2" "c1" "c2" "read"
permutation "readp1" "writep1" "readp2" "c1" "c2"
permutation "writep2" "returningp1" "c1" "c2"
permutation "wrtwcte" "readwcte" "c1" "c2"
+permutation "wrtwcte" "multireadwcte" "c1" "c2"