Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
Skip to content

Commit b291488

Browse files
committed
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
1 parent 6b0208e commit b291488

File tree

3 files changed

+42
-1
lines changed

3 files changed

+42
-1
lines changed

src/backend/executor/execMain.c

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3136,7 +3136,7 @@ EvalPlanQualStart(EPQState *epqstate, EState *parentestate, Plan *planTree)
31363136
* es_param_exec_vals, etc.
31373137
*
31383138
* The ResultRelInfo array management is trickier than it looks. We
3139-
* create a fresh array for the child but copy all the content from the
3139+
* create fresh arrays for the child but copy all the content from the
31403140
* parent. This is because it's okay for the child to share any
31413141
* per-relation state the parent has already created --- but if the child
31423142
* sets up any ResultRelInfo fields, such as its own junkfilter, that
@@ -3153,6 +3153,7 @@ EvalPlanQualStart(EPQState *epqstate, EState *parentestate, Plan *planTree)
31533153
if (parentestate->es_num_result_relations > 0)
31543154
{
31553155
int numResultRelations = parentestate->es_num_result_relations;
3156+
int numRootResultRels = parentestate->es_num_root_result_relations;
31563157
ResultRelInfo *resultRelInfos;
31573158

31583159
resultRelInfos = (ResultRelInfo *)
@@ -3161,6 +3162,17 @@ EvalPlanQualStart(EPQState *epqstate, EState *parentestate, Plan *planTree)
31613162
numResultRelations * sizeof(ResultRelInfo));
31623163
estate->es_result_relations = resultRelInfos;
31633164
estate->es_num_result_relations = numResultRelations;
3165+
3166+
/* Also transfer partitioned root result relations. */
3167+
if (numRootResultRels > 0)
3168+
{
3169+
resultRelInfos = (ResultRelInfo *)
3170+
palloc(numRootResultRels * sizeof(ResultRelInfo));
3171+
memcpy(resultRelInfos, parentestate->es_root_result_relations,
3172+
numRootResultRels * sizeof(ResultRelInfo));
3173+
estate->es_root_result_relations = resultRelInfos;
3174+
estate->es_num_root_result_relations = numRootResultRels;
3175+
}
31643176
}
31653177
/* es_result_relation_info must NOT be copied */
31663178
/* es_trig_target_relations must NOT be copied */

src/test/isolation/expected/eval-plan-qual.out

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -283,3 +283,15 @@ step multireadwcte: <... completed>
283283
subid id
284284

285285
1 1
286+
287+
starting permutation: simplepartupdate complexpartupdate c1 c2
288+
step simplepartupdate:
289+
update parttbl set a = a;
290+
291+
step complexpartupdate:
292+
with u as (update parttbl set a = a returning parttbl.*)
293+
update parttbl set a = u.a from u;
294+
<waiting ...>
295+
step c1: COMMIT;
296+
step complexpartupdate: <... completed>
297+
step c2: COMMIT;

src/test/isolation/specs/eval-plan-qual.spec

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,10 @@ setup
2929

3030
CREATE TABLE jointest AS SELECT generate_series(1,10) AS id, 0 AS data;
3131
CREATE INDEX ON jointest(id);
32+
33+
CREATE TABLE parttbl (a int) PARTITION BY LIST (a);
34+
CREATE TABLE parttbl1 PARTITION OF parttbl FOR VALUES IN (1);
35+
INSERT INTO parttbl VALUES (1);
3236
}
3337

3438
teardown
@@ -37,6 +41,7 @@ teardown
3741
DROP TABLE accounts_ext;
3842
DROP TABLE p CASCADE;
3943
DROP TABLE table_a, table_b, jointest;
44+
DROP TABLE parttbl;
4045
}
4146

4247
session "s1"
@@ -110,6 +115,12 @@ step "selectjoinforupdate" {
110115
select * from jointest a join jointest b on a.id=b.id for update;
111116
}
112117

118+
# test for EPQ on a partitioned result table
119+
120+
step "simplepartupdate" {
121+
update parttbl set a = a;
122+
}
123+
113124

114125
session "s2"
115126
setup { BEGIN ISOLATION LEVEL READ COMMITTED; }
@@ -145,6 +156,10 @@ step "updateforcip3" {
145156
}
146157
step "wrtwcte" { UPDATE table_a SET value = 'tableAValue2' WHERE id = 1; }
147158
step "wrjt" { UPDATE jointest SET data = 42 WHERE id = 7; }
159+
step "complexpartupdate" {
160+
with u as (update parttbl set a = a returning parttbl.*)
161+
update parttbl set a = u.a from u;
162+
}
148163
step "c2" { COMMIT; }
149164

150165
session "s3"
@@ -191,3 +206,5 @@ permutation "updateforcip" "updateforcip3" "c1" "c2" "read_a"
191206
permutation "wrtwcte" "readwcte" "c1" "c2"
192207
permutation "wrjt" "selectjoinforupdate" "c2" "c1"
193208
permutation "wrtwcte" "multireadwcte" "c1" "c2"
209+
210+
permutation "simplepartupdate" "complexpartupdate" "c1" "c2"

0 commit comments

Comments
 (0)