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)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy