Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit75dfde1

Browse files
committed
Fix an oversight incbc1279 to handle MERGE correctly
ExecInitModifyTable() forgot to trim MERGE-related lists to excludeentries for result relations pruned during initial pruning, so fixthat.While at it, make the function's use of the pruned resultRelationslist, rather than ModifyTable.resultRelations, more consistent.Reported-by: Alexander Lakhin <exclusion@gmail.com> (via sqlsmith)Reviewed-by: Junwang Zhao <zhjwpku@gmail.com>Discussion:https://postgr.es/m/e72c94d9-e5f9-4753-9bc1-69d72bd54b8a@gmail.com
1 parent6a8a7ce commit75dfde1

File tree

4 files changed

+134
-10
lines changed

4 files changed

+134
-10
lines changed

‎src/backend/executor/nodeModifyTable.c

Lines changed: 27 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -3643,14 +3643,15 @@ ExecMergeNotMatched(ModifyTableContext *context, ResultRelInfo *resultRelInfo,
36433643
void
36443644
ExecInitMerge(ModifyTableState*mtstate,EState*estate)
36453645
{
3646-
ModifyTable*node= (ModifyTable*)mtstate->ps.plan;
3646+
List*mergeActionLists=mtstate->mt_mergeActionLists;
3647+
List*mergeJoinConditions=mtstate->mt_mergeJoinConditions;
36473648
ResultRelInfo*rootRelInfo=mtstate->rootResultRelInfo;
36483649
ResultRelInfo*resultRelInfo;
36493650
ExprContext*econtext;
36503651
ListCell*lc;
36513652
inti;
36523653

3653-
if (node->mergeActionLists==NIL)
3654+
if (mergeActionLists==NIL)
36543655
return;
36553656

36563657
mtstate->mt_merge_subcommands=0;
@@ -3667,14 +3668,14 @@ ExecInitMerge(ModifyTableState *mtstate, EState *estate)
36673668
* anything here, do so there too.
36683669
*/
36693670
i=0;
3670-
foreach(lc,node->mergeActionLists)
3671+
foreach(lc,mergeActionLists)
36713672
{
36723673
List*mergeActionList=lfirst(lc);
36733674
Node*joinCondition;
36743675
TupleDescrelationDesc;
36753676
ListCell*l;
36763677

3677-
joinCondition= (Node*)list_nth(node->mergeJoinConditions,i);
3678+
joinCondition= (Node*)list_nth(mergeJoinConditions,i);
36783679
resultRelInfo=mtstate->resultRelInfo+i;
36793680
i++;
36803681
relationDesc=RelationGetDescr(resultRelInfo->ri_RelationDesc);
@@ -4475,6 +4476,8 @@ ExecInitModifyTable(ModifyTable *node, EState *estate, int eflags)
44754476
List*withCheckOptionLists=NIL;
44764477
List*returningLists=NIL;
44774478
List*updateColnosLists=NIL;
4479+
List*mergeActionLists=NIL;
4480+
List*mergeJoinConditions=NIL;
44784481
ResultRelInfo*resultRelInfo;
44794482
List*arowmarks;
44804483
ListCell*l;
@@ -4518,6 +4521,18 @@ ExecInitModifyTable(ModifyTable *node, EState *estate, int eflags)
45184521

45194522
updateColnosLists=lappend(updateColnosLists,updateColnosList);
45204523
}
4524+
if (node->mergeActionLists)
4525+
{
4526+
List*mergeActionList=list_nth(node->mergeActionLists,i);
4527+
4528+
mergeActionLists=lappend(mergeActionLists,mergeActionList);
4529+
}
4530+
if (node->mergeJoinConditions)
4531+
{
4532+
List*mergeJoinCondition=list_nth(node->mergeJoinConditions,i);
4533+
4534+
mergeJoinConditions=lappend(mergeJoinConditions,mergeJoinCondition);
4535+
}
45214536
}
45224537
i++;
45234538
}
@@ -4544,6 +4559,8 @@ ExecInitModifyTable(ModifyTable *node, EState *estate, int eflags)
45444559
mtstate->mt_merge_updated=0;
45454560
mtstate->mt_merge_deleted=0;
45464561
mtstate->mt_updateColnosLists=updateColnosLists;
4562+
mtstate->mt_mergeActionLists=mergeActionLists;
4563+
mtstate->mt_mergeJoinConditions=mergeJoinConditions;
45474564

45484565
/*----------
45494566
* Resolve the target relation. This is the same as:
@@ -4556,7 +4573,8 @@ ExecInitModifyTable(ModifyTable *node, EState *estate, int eflags)
45564573
* If it's a partitioned or inherited table, the root partition or
45574574
* appendrel RTE doesn't appear elsewhere in the plan and its RT index is
45584575
* given explicitly in node->rootRelation. Otherwise, the target relation
4559-
* is the sole relation in the node->resultRelations list.
4576+
* is the sole relation in the node->resultRelations list and, since it can
4577+
* never be pruned, also in the resultRelations list constructed above.
45604578
*----------
45614579
*/
45624580
if (node->rootRelation>0)
@@ -4569,9 +4587,10 @@ ExecInitModifyTable(ModifyTable *node, EState *estate, int eflags)
45694587
else
45704588
{
45714589
Assert(list_length(node->resultRelations)==1);
4590+
Assert(list_length(resultRelations)==1);
45724591
mtstate->rootResultRelInfo=mtstate->resultRelInfo;
45734592
ExecInitResultRelation(estate,mtstate->resultRelInfo,
4574-
linitial_int(node->resultRelations));
4593+
linitial_int(resultRelations));
45754594
}
45764595

45774596
/* set up epqstate with dummy subplan data for the moment */
@@ -4599,8 +4618,8 @@ ExecInitModifyTable(ModifyTable *node, EState *estate, int eflags)
45994618
IndexresultRelation=lfirst_int(l);
46004619
List*mergeActions=NIL;
46014620

4602-
if (node->mergeActionLists)
4603-
mergeActions=list_nth(node->mergeActionLists,i);
4621+
if (mergeActionLists)
4622+
mergeActions=list_nth(mergeActionLists,i);
46044623

46054624
if (resultRelInfo!=mtstate->rootResultRelInfo)
46064625
{

‎src/include/nodes/execnodes.h

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1448,10 +1448,13 @@ typedef struct ModifyTableState
14481448
doublemt_merge_deleted;
14491449

14501450
/*
1451-
* List of valid updateColnosLists. Contains only those belonging to
1452-
* unpruned relations from ModifyTable.updateColnosLists.
1451+
* Lists of valid updateColnosLists, mergeActionLists, and
1452+
* mergeJoinConditions. These contain only entries for unpruned
1453+
* relations, filtered from the corresponding lists in ModifyTable.
14531454
*/
14541455
List*mt_updateColnosLists;
1456+
List*mt_mergeActionLists;
1457+
List*mt_mergeJoinConditions;
14551458
}ModifyTableState;
14561459

14571460
/* ----------------

‎src/test/regress/expected/partition_prune.out

Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4512,6 +4512,83 @@ explain (costs off) execute update_part_abc_view (2, 'a');
45124512
execute update_part_abc_view (2, 'a');
45134513
ERROR: new row violates check option for view "part_abc_view"
45144514
DETAIL: Failing row contains (2, a, t).
4515+
-- All pruned.
4516+
explain (costs off) execute update_part_abc_view (3, 'a');
4517+
QUERY PLAN
4518+
-----------------------------
4519+
Update on part_abc
4520+
-> Append
4521+
Subplans Removed: 2
4522+
(3 rows)
4523+
4524+
execute update_part_abc_view (3, 'a');
4525+
a | b | c
4526+
---+---+---
4527+
(0 rows)
4528+
45154529
deallocate update_part_abc_view;
4530+
-- Runtime pruning on MERGE using a stable function
4531+
create function stable_one() returns int as $$ begin return 1; end; $$ language plpgsql stable;
4532+
explain (costs off)
4533+
merge into part_abc_view pt
4534+
using (select stable_one() as pid) as q join part_abc_1 pt1 on (q.pid = pt1.a) on pt.a = pt1.a
4535+
when matched then delete returning pt.a;
4536+
QUERY PLAN
4537+
-----------------------------------------------------------------------
4538+
Merge on part_abc
4539+
Merge on part_abc_1
4540+
-> Nested Loop
4541+
-> Append
4542+
Subplans Removed: 1
4543+
-> Seq Scan on part_abc_1
4544+
Filter: ((b <> 'a'::text) AND (a = stable_one()))
4545+
-> Materialize
4546+
-> Seq Scan on part_abc_1 pt1
4547+
Filter: (a = stable_one())
4548+
(10 rows)
4549+
4550+
merge into part_abc_view pt
4551+
using (select stable_one() as pid) as q join part_abc_1 pt1 on (q.pid = pt1.a) on pt.a = pt1.a
4552+
when matched then delete returning pt.a;
4553+
a
4554+
---
4555+
1
4556+
(1 row)
4557+
4558+
table part_abc_view;
4559+
a | b | c
4560+
---+---+---
4561+
2 | c | t
4562+
(1 row)
4563+
4564+
-- All pruned.
4565+
explain (costs off)
4566+
merge into part_abc_view pt
4567+
using (select stable_one() + 2 as pid) as q join part_abc_1 pt1 on (q.pid = pt1.a) on pt.a = pt1.a
4568+
when matched then delete returning pt.a;
4569+
QUERY PLAN
4570+
------------------------------------------------------
4571+
Merge on part_abc
4572+
-> Nested Loop
4573+
-> Append
4574+
Subplans Removed: 2
4575+
-> Materialize
4576+
-> Seq Scan on part_abc_1 pt1
4577+
Filter: (a = (stable_one() + 2))
4578+
(7 rows)
4579+
4580+
merge into part_abc_view pt
4581+
using (select stable_one() + 2 as pid) as q join part_abc_1 pt1 on (q.pid = pt1.a) on pt.a = pt1.a
4582+
when matched then delete returning pt.a;
4583+
a
4584+
---
4585+
(0 rows)
4586+
4587+
table part_abc_view;
4588+
a | b | c
4589+
---+---+---
4590+
2 | c | t
4591+
(1 row)
4592+
45164593
drop view part_abc_view;
45174594
drop table part_abc;

‎src/test/regress/sql/partition_prune.sql

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1371,6 +1371,31 @@ explain (costs off) execute update_part_abc_view (1, 'd');
13711371
execute update_part_abc_view (1,'d');
13721372
explain (costs off) execute update_part_abc_view (2,'a');
13731373
execute update_part_abc_view (2,'a');
1374+
-- All pruned.
1375+
explain (costs off) execute update_part_abc_view (3,'a');
1376+
execute update_part_abc_view (3,'a');
13741377
deallocate update_part_abc_view;
1378+
1379+
-- Runtime pruning on MERGE using a stable function
1380+
createfunctionstable_one() returnsintas $$begin return1; end; $$ language plpgsql stable;
1381+
explain (costs off)
1382+
merge into part_abc_view pt
1383+
using (select stable_one()as pid)as qjoin part_abc_1 pt1on (q.pid=pt1.a)onpt.a=pt1.a
1384+
when matched thendelete returningpt.a;
1385+
merge into part_abc_view pt
1386+
using (select stable_one()as pid)as qjoin part_abc_1 pt1on (q.pid=pt1.a)onpt.a=pt1.a
1387+
when matched thendelete returningpt.a;
1388+
table part_abc_view;
1389+
1390+
-- All pruned.
1391+
explain (costs off)
1392+
merge into part_abc_view pt
1393+
using (select stable_one()+2as pid)as qjoin part_abc_1 pt1on (q.pid=pt1.a)onpt.a=pt1.a
1394+
when matched thendelete returningpt.a;
1395+
merge into part_abc_view pt
1396+
using (select stable_one()+2as pid)as qjoin part_abc_1 pt1on (q.pid=pt1.a)onpt.a=pt1.a
1397+
when matched thendelete returningpt.a;
1398+
table part_abc_view;
1399+
13751400
dropview part_abc_view;
13761401
droptable part_abc;

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp