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

Commitd376ab5

Browse files
committed
In ExecInitModifyTable, don't scribble on the source plan.
The code carelessly modified mtstate->ps.plan->targetlist,which it's not supposed to do. Fortunately, there's notreally any need to do that because the planner alreadyset up a perfectly acceptable targetlist for the plan node.We just need to remove the erroneous assignments and update somerelevant comments.As it happens, the erroneous assignments caused the targetlist topoint to a different part of the source plan tree, so that thereisn't really a risk of the pointer becoming dangling after executortermination. The only visible effect of this change we can find isthat EXPLAIN will show upper references to the ModifyTable's outputexpressions using different variables. Formerly it showed Vars fromthe first target relation that survived executor-startup pruning.Now it always shows such references using the first relation appearingin the planner output, independently of what happens during executorpruning. On the whole that seems like a good thing.Also make a small tweak in ExplainPreScanNode to ensure that the firstrelation will receive a refname assignment in set_rtable_names, evenif it got pruned at startup. Previously the Vars might be shownwithout any table qualification, which is confusing in a multi-tablequery.I considered back-patching this, but since the bug doesn't seem tohave any really terrible consequences in existing branches, itseems better to not change their EXPLAIN output. It's not too latefor v18 though, especially since v18 already made other changes inthe EXPLAIN output for these cases.Reported-by: Tom Lane <tgl@sss.pgh.pa.us>Author: Andres Freund <andres@anarazel.de>Co-authored-by: Tom Lane <tgl@sss.pgh.pa.us>Discussion:https://postgr.es/m/213261.1747611093@sss.pgh.pa.us
1 parentf24605e commitd376ab5

File tree

5 files changed

+41
-33
lines changed

5 files changed

+41
-33
lines changed

‎src/backend/commands/explain.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1220,6 +1220,10 @@ ExplainPreScanNode(PlanState *planstate, Bitmapset **rels_used)
12201220
if (((ModifyTable*)plan)->exclRelRTI)
12211221
*rels_used=bms_add_member(*rels_used,
12221222
((ModifyTable*)plan)->exclRelRTI);
1223+
/* Ensure Vars used in RETURNING will have refnames */
1224+
if (plan->targetlist)
1225+
*rels_used=bms_add_member(*rels_used,
1226+
linitial_int(((ModifyTable*)plan)->resultRelations));
12231227
break;
12241228
caseT_Append:
12251229
*rels_used=bms_add_members(*rels_used,

‎src/backend/executor/nodeModifyTable.c

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4830,12 +4830,11 @@ ExecInitModifyTable(ModifyTable *node, EState *estate, int eflags)
48304830
ExprContext*econtext;
48314831

48324832
/*
4833-
* Initialize result tuple slot and assign its rowtype using the first
4834-
* RETURNING list. We assume the rest will look the same.
4833+
* Initialize result tuple slot and assign its rowtype using the plan
4834+
* node's declared targetlist, which the planner set up to be the same
4835+
* as the first (before runtime pruning) RETURNING list. We assume
4836+
* all the result rels will produce compatible output.
48354837
*/
4836-
mtstate->ps.plan->targetlist= (List*)linitial(returningLists);
4837-
4838-
/* Set up a slot for the output of the RETURNING projection(s) */
48394838
ExecInitResultTupleSlotTL(&mtstate->ps,&TTSOpsVirtual);
48404839
slot=mtstate->ps.ps_ResultTupleSlot;
48414840

@@ -4865,7 +4864,6 @@ ExecInitModifyTable(ModifyTable *node, EState *estate, int eflags)
48654864
* We still must construct a dummy result tuple type, because InitPlan
48664865
* expects one (maybe should change that?).
48674866
*/
4868-
mtstate->ps.plan->targetlist=NIL;
48694867
ExecInitResultTypeTL(&mtstate->ps);
48704868

48714869
mtstate->ps.ps_ExprContext=NULL;

‎src/backend/optimizer/plan/setrefs.c

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1097,9 +1097,10 @@ set_plan_refs(PlannerInfo *root, Plan *plan, int rtoffset)
10971097

10981098
/*
10991099
* Set up the visible plan targetlist as being the same as
1100-
* the first RETURNING list. This is for the use of
1101-
* EXPLAIN; the executor won't pay any attention to the
1102-
* targetlist. We postpone this step until here so that
1100+
* the first RETURNING list. This is mostly for the use
1101+
* of EXPLAIN; the executor won't execute that targetlist,
1102+
* although it does use it to prepare the node's result
1103+
* tuple slot. We postpone this step until here so that
11031104
* we don't have to do set_returning_clause_references()
11041105
* twice on identical targetlists.
11051106
*/

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

Lines changed: 26 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -4553,45 +4553,50 @@ create view part_abc_view as select * from part_abc where b <> 'a' with check op
45534553
prepare update_part_abc_view as update part_abc_view set b = $2 where a = $1 returning *;
45544554
-- Only the unpruned partition should be shown in the list of relations to be
45554555
-- updated
4556-
explain (costs off) execute update_part_abc_view (1, 'd');
4557-
QUERY PLAN
4558-
-------------------------------------------------------
4559-
Update on part_abc
4560-
Update on part_abc_1
4556+
explain (verbose, costs off) execute update_part_abc_view (1, 'd');
4557+
QUERY PLAN
4558+
-----------------------------------------------------------------------------
4559+
Update on public.part_abc
4560+
Output: part_abc_1.a, part_abc_1.b, part_abc_1.c
4561+
Update on public.part_abc_1
45614562
-> Append
45624563
Subplans Removed: 1
4563-
-> Seq Scan on part_abc_1
4564-
Filter: ((b <> 'a'::text) AND (a = $1))
4565-
(6 rows)
4564+
-> Seq Scan on public.part_abc_1
4565+
Output: $2, part_abc_1.tableoid, part_abc_1.ctid
4566+
Filter: ((part_abc_1.b <> 'a'::text) AND (part_abc_1.a = $1))
4567+
(8 rows)
45664568

45674569
execute update_part_abc_view (1, 'd');
45684570
a | b | c
45694571
---+---+---
45704572
1 | d | t
45714573
(1 row)
45724574

4573-
explain (costs off) execute update_part_abc_view (2, 'a');
4574-
QUERY PLAN
4575-
-------------------------------------------------------
4576-
Update on part_abc
4577-
Update on part_abc_2 part_abc_1
4575+
explain (verbose, costs off) execute update_part_abc_view (2, 'a');
4576+
QUERY PLAN
4577+
-----------------------------------------------------------------------------
4578+
Update on public.part_abc
4579+
Output: part_abc_1.a, part_abc_1.b, part_abc_1.c
4580+
Update on public.part_abc_2
45784581
-> Append
45794582
Subplans Removed: 1
4580-
-> Seq Scan on part_abc_2 part_abc_1
4581-
Filter: ((b <> 'a'::text) AND (a = $1))
4582-
(6 rows)
4583+
-> Seq Scan on public.part_abc_2
4584+
Output: $2, part_abc_2.tableoid, part_abc_2.ctid
4585+
Filter: ((part_abc_2.b <> 'a'::text) AND (part_abc_2.a = $1))
4586+
(8 rows)
45834587

45844588
execute update_part_abc_view (2, 'a');
45854589
ERROR: new row violates check option for view "part_abc_view"
45864590
DETAIL: Failing row contains (2, a, t).
45874591
-- All pruned.
4588-
explain (costs off) execute update_part_abc_view (3, 'a');
4589-
QUERY PLAN
4590-
-----------------------------
4591-
Update on part_abc
4592+
explain (verbose, costs off) execute update_part_abc_view (3, 'a');
4593+
QUERY PLAN
4594+
----------------------------------------------------
4595+
Update on public.part_abc
4596+
Output: part_abc_1.a, part_abc_1.b, part_abc_1.c
45924597
-> Append
45934598
Subplans Removed: 2
4594-
(3 rows)
4599+
(4 rows)
45954600

45964601
execute update_part_abc_view (3, 'a');
45974602
a | b | c

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

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1371,12 +1371,12 @@ create view part_abc_view as select * from part_abc where b <> 'a' with check op
13711371
prepare update_part_abc_viewasupdate part_abc_viewset b= $2where a= $1 returning*;
13721372
-- Only the unpruned partition should be shown in the list of relations to be
13731373
-- updated
1374-
explain (costs off) execute update_part_abc_view (1,'d');
1374+
explain (verbose,costs off) execute update_part_abc_view (1,'d');
13751375
execute update_part_abc_view (1,'d');
1376-
explain (costs off) execute update_part_abc_view (2,'a');
1376+
explain (verbose,costs off) execute update_part_abc_view (2,'a');
13771377
execute update_part_abc_view (2,'a');
13781378
-- All pruned.
1379-
explain (costs off) execute update_part_abc_view (3,'a');
1379+
explain (verbose,costs off) execute update_part_abc_view (3,'a');
13801380
execute update_part_abc_view (3,'a');
13811381
deallocate update_part_abc_view;
13821382

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp