mirror of
https://github.com/postgres/postgres.git
synced 2025-05-08 07:21:33 +03:00
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
This commit is contained in:
parent
6b0208ebc4
commit
b291488da5
@ -3136,7 +3136,7 @@ EvalPlanQualStart(EPQState *epqstate, EState *parentestate, Plan *planTree)
|
|||||||
* es_param_exec_vals, etc.
|
* es_param_exec_vals, etc.
|
||||||
*
|
*
|
||||||
* The ResultRelInfo array management is trickier than it looks. We
|
* 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
|
* 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
|
* per-relation state the parent has already created --- but if the child
|
||||||
* sets up any ResultRelInfo fields, such as its own junkfilter, that
|
* sets up any ResultRelInfo fields, such as its own junkfilter, that
|
||||||
@ -3153,6 +3153,7 @@ EvalPlanQualStart(EPQState *epqstate, EState *parentestate, Plan *planTree)
|
|||||||
if (parentestate->es_num_result_relations > 0)
|
if (parentestate->es_num_result_relations > 0)
|
||||||
{
|
{
|
||||||
int numResultRelations = parentestate->es_num_result_relations;
|
int numResultRelations = parentestate->es_num_result_relations;
|
||||||
|
int numRootResultRels = parentestate->es_num_root_result_relations;
|
||||||
ResultRelInfo *resultRelInfos;
|
ResultRelInfo *resultRelInfos;
|
||||||
|
|
||||||
resultRelInfos = (ResultRelInfo *)
|
resultRelInfos = (ResultRelInfo *)
|
||||||
@ -3161,6 +3162,17 @@ EvalPlanQualStart(EPQState *epqstate, EState *parentestate, Plan *planTree)
|
|||||||
numResultRelations * sizeof(ResultRelInfo));
|
numResultRelations * sizeof(ResultRelInfo));
|
||||||
estate->es_result_relations = resultRelInfos;
|
estate->es_result_relations = resultRelInfos;
|
||||||
estate->es_num_result_relations = numResultRelations;
|
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_result_relation_info must NOT be copied */
|
||||||
/* es_trig_target_relations must NOT be copied */
|
/* es_trig_target_relations must NOT be copied */
|
||||||
|
@ -283,3 +283,15 @@ step multireadwcte: <... completed>
|
|||||||
subid id
|
subid id
|
||||||
|
|
||||||
1 1
|
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;
|
||||||
|
@ -29,6 +29,10 @@ setup
|
|||||||
|
|
||||||
CREATE TABLE jointest AS SELECT generate_series(1,10) AS id, 0 AS data;
|
CREATE TABLE jointest AS SELECT generate_series(1,10) AS id, 0 AS data;
|
||||||
CREATE INDEX ON jointest(id);
|
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
|
teardown
|
||||||
@ -37,6 +41,7 @@ teardown
|
|||||||
DROP TABLE accounts_ext;
|
DROP TABLE accounts_ext;
|
||||||
DROP TABLE p CASCADE;
|
DROP TABLE p CASCADE;
|
||||||
DROP TABLE table_a, table_b, jointest;
|
DROP TABLE table_a, table_b, jointest;
|
||||||
|
DROP TABLE parttbl;
|
||||||
}
|
}
|
||||||
|
|
||||||
session "s1"
|
session "s1"
|
||||||
@ -110,6 +115,12 @@ step "selectjoinforupdate" {
|
|||||||
select * from jointest a join jointest b on a.id=b.id for update;
|
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"
|
session "s2"
|
||||||
setup { BEGIN ISOLATION LEVEL READ COMMITTED; }
|
setup { BEGIN ISOLATION LEVEL READ COMMITTED; }
|
||||||
@ -145,6 +156,10 @@ step "updateforcip3" {
|
|||||||
}
|
}
|
||||||
step "wrtwcte" { UPDATE table_a SET value = 'tableAValue2' WHERE id = 1; }
|
step "wrtwcte" { UPDATE table_a SET value = 'tableAValue2' WHERE id = 1; }
|
||||||
step "wrjt" { UPDATE jointest SET data = 42 WHERE id = 7; }
|
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; }
|
step "c2" { COMMIT; }
|
||||||
|
|
||||||
session "s3"
|
session "s3"
|
||||||
@ -191,3 +206,5 @@ permutation "updateforcip" "updateforcip3" "c1" "c2" "read_a"
|
|||||||
permutation "wrtwcte" "readwcte" "c1" "c2"
|
permutation "wrtwcte" "readwcte" "c1" "c2"
|
||||||
permutation "wrjt" "selectjoinforupdate" "c2" "c1"
|
permutation "wrjt" "selectjoinforupdate" "c2" "c1"
|
||||||
permutation "wrtwcte" "multireadwcte" "c1" "c2"
|
permutation "wrtwcte" "multireadwcte" "c1" "c2"
|
||||||
|
|
||||||
|
permutation "simplepartupdate" "complexpartupdate" "c1" "c2"
|
||||||
|
Loading…
x
Reference in New Issue
Block a user