summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorTom Lane <tgl@sss.pgh.pa.us>2019-04-08 12:20:23 -0400
committerTom Lane <tgl@sss.pgh.pa.us>2019-04-08 12:20:23 -0400
commit1b5bbe4bcc912b070ad705ad7a79806692af18c8 (patch)
tree47237ac3ce4c3625ee806cabe98dfac2d95413ca /src
parent67999b3547f7ee8b8c099f41ddab3001e2792202 (diff)
Fix EvalPlanQualStart to handle partitioned result rels correctly.
The es_root_result_relations array needs to be shallow-copied in the same way as the main es_result_relations array, else EPQ rechecks on partitioned result relations fail, as seen in bug #15677 from Norbert Benkocs. Amit Langote, isolation test case added by me Discussion: https://postgr.es/m/15677-0bf089579b4cd02d@postgresql.org Discussion: https://postgr.es/m/19321.1554567786@sss.pgh.pa.us
Diffstat (limited to 'src')
-rw-r--r--src/backend/executor/execMain.c14
-rw-r--r--src/test/isolation/expected/eval-plan-qual.out12
-rw-r--r--src/test/isolation/specs/eval-plan-qual.spec17
3 files changed, 42 insertions, 1 deletions
diff --git a/src/backend/executor/execMain.c b/src/backend/executor/execMain.c
index 14704f8838c..bf7631276d9 100644
--- a/src/backend/executor/execMain.c
+++ b/src/backend/executor/execMain.c
@@ -3101,7 +3101,7 @@ EvalPlanQualStart(EPQState *epqstate, EState *parentestate, Plan *planTree)
* es_param_exec_vals, etc.
*
* The ResultRelInfo array management is trickier than it looks. We
- * create a fresh array for the child but copy all the content from the
+ * create fresh arrays for the child but copy all the content from the
* parent. This is because it's okay for the child to share any
* per-relation state the parent has already created --- but if the child
* sets up any ResultRelInfo fields, such as its own junkfilter, that
@@ -3118,6 +3118,7 @@ EvalPlanQualStart(EPQState *epqstate, EState *parentestate, Plan *planTree)
if (parentestate->es_num_result_relations > 0)
{
int numResultRelations = parentestate->es_num_result_relations;
+ int numRootResultRels = parentestate->es_num_root_result_relations;
ResultRelInfo *resultRelInfos;
resultRelInfos = (ResultRelInfo *)
@@ -3126,6 +3127,17 @@ EvalPlanQualStart(EPQState *epqstate, EState *parentestate, Plan *planTree)
numResultRelations * sizeof(ResultRelInfo));
estate->es_result_relations = resultRelInfos;
estate->es_num_result_relations = numResultRelations;
+
+ /* Also transfer partitioned root result relations. */
+ if (numRootResultRels > 0)
+ {
+ resultRelInfos = (ResultRelInfo *)
+ palloc(numRootResultRels * sizeof(ResultRelInfo));
+ memcpy(resultRelInfos, parentestate->es_root_result_relations,
+ numRootResultRels * sizeof(ResultRelInfo));
+ estate->es_root_result_relations = resultRelInfos;
+ estate->es_num_root_result_relations = numRootResultRels;
+ }
}
/* es_result_relation_info must NOT be copied */
/* es_trig_target_relations must NOT be copied */
diff --git a/src/test/isolation/expected/eval-plan-qual.out b/src/test/isolation/expected/eval-plan-qual.out
index fe4100d51d4..92346802d87 100644
--- a/src/test/isolation/expected/eval-plan-qual.out
+++ b/src/test/isolation/expected/eval-plan-qual.out
@@ -263,3 +263,15 @@ step multireadwcte: <... completed>
subid id
1 1
+
+starting permutation: simplepartupdate complexpartupdate c1 c2
+step simplepartupdate:
+ update parttbl set a = a;
+
+step complexpartupdate:
+ with u as (update parttbl set a = a returning parttbl.*)
+ update parttbl set a = u.a from u;
+ <waiting ...>
+step c1: COMMIT;
+step complexpartupdate: <... completed>
+step c2: COMMIT;
diff --git a/src/test/isolation/specs/eval-plan-qual.spec b/src/test/isolation/specs/eval-plan-qual.spec
index 35f3be1cc8d..88531b7dbe7 100644
--- a/src/test/isolation/specs/eval-plan-qual.spec
+++ b/src/test/isolation/specs/eval-plan-qual.spec
@@ -24,6 +24,10 @@ setup
CREATE TABLE jointest AS SELECT generate_series(1,10) AS id, 0 AS data;
CREATE INDEX ON jointest(id);
+
+ CREATE TABLE parttbl (a int) PARTITION BY LIST (a);
+ CREATE TABLE parttbl1 PARTITION OF parttbl FOR VALUES IN (1);
+ INSERT INTO parttbl VALUES (1);
}
teardown
@@ -31,6 +35,7 @@ teardown
DROP TABLE accounts;
DROP TABLE p CASCADE;
DROP TABLE table_a, table_b, jointest;
+ DROP TABLE parttbl;
}
session "s1"
@@ -99,6 +104,12 @@ step "selectjoinforupdate" {
select * from jointest a join jointest b on a.id=b.id for update;
}
+# test for EPQ on a partitioned result table
+
+step "simplepartupdate" {
+ update parttbl set a = a;
+}
+
session "s2"
setup { BEGIN ISOLATION LEVEL READ COMMITTED; }
@@ -133,6 +144,10 @@ step "updateforcip3" {
}
step "wrtwcte" { UPDATE table_a SET value = 'tableAValue2' WHERE id = 1; }
step "wrjt" { UPDATE jointest SET data = 42 WHERE id = 7; }
+step "complexpartupdate" {
+ with u as (update parttbl set a = a returning parttbl.*)
+ update parttbl set a = u.a from u;
+}
step "c2" { COMMIT; }
session "s3"
@@ -177,3 +192,5 @@ permutation "updateforcip" "updateforcip3" "c1" "c2" "read_a"
permutation "wrtwcte" "readwcte" "c1" "c2"
permutation "wrjt" "selectjoinforupdate" "c2" "c1"
permutation "wrtwcte" "multireadwcte" "c1" "c2"
+
+permutation "simplepartupdate" "complexpartupdate" "c1" "c2"