Skip to content

Commit a8cb8f1

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 348f57c commit a8cb8f1

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
@@ -2779,7 +2779,7 @@ EvalPlanQualStart(EPQState *epqstate, EState *parentestate, Plan *planTree)
27792779
* es_param_exec_vals, etc.
27802780
*
27812781
* The ResultRelInfo array management is trickier than it looks. We
2782-
* create a fresh array for the child but copy all the content from the
2782+
* create fresh arrays for the child but copy all the content from the
27832783
* parent. This is because it's okay for the child to share any
27842784
* per-relation state the parent has already created --- but if the child
27852785
* sets up any ResultRelInfo fields, such as its own junkfilter, that
@@ -2800,6 +2800,7 @@ EvalPlanQualStart(EPQState *epqstate, EState *parentestate, Plan *planTree)
28002800
if (parentestate->es_num_result_relations > 0)
28012801
{
28022802
int numResultRelations = parentestate->es_num_result_relations;
2803+
int numRootResultRels = parentestate->es_num_root_result_relations;
28032804
ResultRelInfo *resultRelInfos;
28042805

28052806
resultRelInfos = (ResultRelInfo *)
@@ -2808,6 +2809,17 @@ EvalPlanQualStart(EPQState *epqstate, EState *parentestate, Plan *planTree)
28082809
numResultRelations * sizeof(ResultRelInfo));
28092810
estate->es_result_relations = resultRelInfos;
28102811
estate->es_num_result_relations = numResultRelations;
2812+
2813+
/* Also transfer partitioned root result relations. */
2814+
if (numRootResultRels > 0)
2815+
{
2816+
resultRelInfos = (ResultRelInfo *)
2817+
palloc(numRootResultRels * sizeof(ResultRelInfo));
2818+
memcpy(resultRelInfos, parentestate->es_root_result_relations,
2819+
numRootResultRels * sizeof(ResultRelInfo));
2820+
estate->es_root_result_relations = resultRelInfos;
2821+
estate->es_num_root_result_relations = numRootResultRels;
2822+
}
28112823
}
28122824
/* es_result_relation_info must NOT be copied */
28132825
/* 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
@@ -629,3 +629,15 @@ step multireadwcte: <... completed>
629629
subid id
630630

631631
1 1
632+
633+
starting permutation: simplepartupdate complexpartupdate c1 c2
634+
step simplepartupdate:
635+
update parttbl set a = a;
636+
637+
step complexpartupdate:
638+
with u as (update parttbl set a = a returning parttbl.*)
639+
update parttbl set a = u.a from u;
640+
<waiting ...>
641+
step c1: COMMIT;
642+
step complexpartupdate: <... completed>
643+
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
@@ -32,6 +32,10 @@ setup
3232

3333
CREATE TABLE jointest AS SELECT generate_series(1,10) AS id, 0 AS data;
3434
CREATE INDEX ON jointest(id);
35+
36+
CREATE TABLE parttbl (a int) PARTITION BY LIST (a);
37+
CREATE TABLE parttbl1 PARTITION OF parttbl FOR VALUES IN (1);
38+
INSERT INTO parttbl VALUES (1);
3539
}
3640

3741
teardown
@@ -41,6 +45,7 @@ teardown
4145
DROP TABLE accounts_ext;
4246
DROP TABLE p CASCADE;
4347
DROP TABLE table_a, table_b, jointest;
48+
DROP TABLE parttbl;
4449
}
4550

4651
session "s1"
@@ -137,6 +142,12 @@ step "selectresultforupdate" {
137142
where jt.id = y for update of jt, ss1, ss2;
138143
}
139144

145+
# test for EPQ on a partitioned result table
146+
147+
step "simplepartupdate" {
148+
update parttbl set a = a;
149+
}
150+
140151

141152
session "s2"
142153
setup { BEGIN ISOLATION LEVEL READ COMMITTED; }
@@ -174,6 +185,10 @@ step "updateforcip3" {
174185
}
175186
step "wrtwcte" { UPDATE table_a SET value = 'tableAValue2' WHERE id = 1; }
176187
step "wrjt" { UPDATE jointest SET data = 42 WHERE id = 7; }
188+
step "complexpartupdate" {
189+
with u as (update parttbl set a = a returning parttbl.*)
190+
update parttbl set a = u.a from u;
191+
}
177192

178193
# Use writable CTEs to create self-updated rows, that then are
179194
# (updated|deleted). The *fail versions of the tests additionally
@@ -261,3 +276,5 @@ permutation "wrtwcte" "readwcte" "c1" "c2"
261276
permutation "wrjt" "selectjoinforupdate" "c2" "c1"
262277
permutation "wrjt" "selectresultforupdate" "c2" "c1"
263278
permutation "wrtwcte" "multireadwcte" "c1" "c2"
279+
280+
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