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

Commit05bd889

Browse files
committed
Fix RETURNING to work correctly with partition tuple routing.
In ExecInsert(), do not switch back to the root partitioned tableResultRelInfo until after we finish ExecProcessReturning(), so thatRETURNING projection is done using the partition's descriptor. Forthe projection to work correctly, we must initialize the same for eachleaf partition during ModifyTableState initialization.Amit Langote
1 parent39162b2 commit05bd889

File tree

7 files changed

+82
-17
lines changed

7 files changed

+82
-17
lines changed

‎src/backend/catalog/partition.c

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -883,7 +883,8 @@ get_qual_from_partbound(Relation rel, Relation parent, Node *bound)
883883
* different from the parent's.
884884
*/
885885
List*
886-
map_partition_varattnos(List*expr,Relationpartrel,Relationparent)
886+
map_partition_varattnos(List*expr,inttarget_varno,
887+
Relationpartrel,Relationparent)
887888
{
888889
TupleDesctupdesc=RelationGetDescr(parent);
889890
AttrNumberattno;
@@ -908,7 +909,7 @@ map_partition_varattnos(List *expr, Relation partrel, Relation parent)
908909
}
909910

910911
expr= (List*)map_variable_attnos((Node*)expr,
911-
1,0,
912+
target_varno,0,
912913
part_attnos,
913914
tupdesc->natts,
914915
&found_whole_row);
@@ -1540,8 +1541,9 @@ generate_partition_qual(Relation rel)
15401541
* Change Vars to have partition's attnos instead of the parent's.
15411542
* We do this after we concatenate the parent's quals, because
15421543
* we want every Var in it to bear this relation's attnos.
1544+
* It's safe to assume varno = 1 here.
15431545
*/
1544-
result=map_partition_varattnos(result,rel,parent);
1546+
result=map_partition_varattnos(result,1,rel,parent);
15451547

15461548
/* Save a copy in the relcache */
15471549
oldcxt=MemoryContextSwitchTo(CacheMemoryContext);

‎src/backend/commands/tablecmds.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13454,6 +13454,7 @@ ATExecAttachPartition(List **wqueue, Relation rel, PartitionCmd *cmd)
1345413454
constr=linitial(partConstraint);
1345513455
my_constr=make_ands_implicit((Expr*)constr);
1345613456
tab->partition_constraint=map_partition_varattnos(my_constr,
13457+
1,
1345713458
part_rel,
1345813459
rel);
1345913460
/* keep our lock until commit */

‎src/backend/executor/execMain.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1279,10 +1279,10 @@ InitResultRelInfo(ResultRelInfo *resultRelInfo,
12791279
/*
12801280
* This is not our own partition constraint, but rather an ancestor's.
12811281
* So any Vars in it bear the ancestor's attribute numbers. We must
1282-
* switch them to our own.
1282+
* switch them to our own. (dummy varno = 1)
12831283
*/
12841284
if (partition_check!=NIL)
1285-
partition_check=map_partition_varattnos(partition_check,
1285+
partition_check=map_partition_varattnos(partition_check,1,
12861286
resultRelationDesc,
12871287
partition_root);
12881288
}

‎src/backend/executor/nodeModifyTable.c

Lines changed: 34 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -262,7 +262,8 @@ ExecInsert(ModifyTableState *mtstate,
262262
RelationresultRelationDesc;
263263
OidnewId;
264264
List*recheckIndexes=NIL;
265-
TupleTableSlot*oldslot=slot;
265+
TupleTableSlot*oldslot=slot,
266+
*result=NULL;
266267

267268
/*
268269
* get the heap tuple out of the tuple table slot, making sure we have a
@@ -574,12 +575,6 @@ ExecInsert(ModifyTableState *mtstate,
574575

575576
list_free(recheckIndexes);
576577

577-
if (saved_resultRelInfo)
578-
{
579-
resultRelInfo=saved_resultRelInfo;
580-
estate->es_result_relation_info=resultRelInfo;
581-
}
582-
583578
/*
584579
* Check any WITH CHECK OPTION constraints from parent views. We are
585580
* required to do this after testing all constraints and uniqueness
@@ -597,9 +592,12 @@ ExecInsert(ModifyTableState *mtstate,
597592

598593
/* Process RETURNING if present */
599594
if (resultRelInfo->ri_projectReturning)
600-
returnExecProcessReturning(resultRelInfo,slot,planSlot);
595+
result=ExecProcessReturning(resultRelInfo,slot,planSlot);
601596

602-
returnNULL;
597+
if (saved_resultRelInfo)
598+
estate->es_result_relation_info=saved_resultRelInfo;
599+
600+
returnresult;
603601
}
604602

605603
/* ----------------------------------------------------------------
@@ -1786,6 +1784,7 @@ ExecInitModifyTable(ModifyTable *node, EState *estate, int eflags)
17861784
{
17871785
TupleTableSlot*slot;
17881786
ExprContext*econtext;
1787+
List*returningList;
17891788

17901789
/*
17911790
* Initialize result tuple slot and assign its rowtype using the first
@@ -1818,6 +1817,32 @@ ExecInitModifyTable(ModifyTable *node, EState *estate, int eflags)
18181817
resultRelInfo->ri_RelationDesc->rd_att);
18191818
resultRelInfo++;
18201819
}
1820+
1821+
/*
1822+
* Build a projection for each leaf partition rel. Note that we
1823+
* didn't build the returningList for each partition within the
1824+
* planner, but simple translation of the varattnos for each
1825+
* partition will suffice. This only occurs for the INSERT case;
1826+
* UPDATE/DELETE are handled above.
1827+
*/
1828+
resultRelInfo=mtstate->mt_partitions;
1829+
returningList=linitial(node->returningLists);
1830+
for (i=0;i<mtstate->mt_num_partitions;i++)
1831+
{
1832+
Relationpartrel=resultRelInfo->ri_RelationDesc;
1833+
List*rlist,
1834+
*rliststate;
1835+
1836+
/* varno = node->nominalRelation */
1837+
rlist=map_partition_varattnos(returningList,
1838+
node->nominalRelation,
1839+
partrel,rel);
1840+
rliststate= (List*)ExecInitExpr((Expr*)rlist,&mtstate->ps);
1841+
resultRelInfo->ri_projectReturning=
1842+
ExecBuildProjectionInfo(rliststate,econtext,slot,
1843+
resultRelInfo->ri_RelationDesc->rd_att);
1844+
resultRelInfo++;
1845+
}
18211846
}
18221847
else
18231848
{

‎src/include/catalog/partition.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,8 @@ extern bool partition_bounds_equal(PartitionKey key,
7777
externvoidcheck_new_partition_bound(char*relname,Relationparent,Node*bound);
7878
externOidget_partition_parent(Oidrelid);
7979
externList*get_qual_from_partbound(Relationrel,Relationparent,Node*bound);
80-
externList*map_partition_varattnos(List*expr,Relationpartrel,Relationparent);
80+
externList*map_partition_varattnos(List*expr,inttarget_varno,
81+
Relationpartrel,Relationparent);
8182
externList*RelationGetPartitionQual(Relationrel);
8283

8384
/* For tuple routing */

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

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -364,5 +364,27 @@ DETAIL: Failing row contains (1, 2).
364364
insert into p1 (a, b) values (2, 3);
365365
ERROR: new row for relation "p11" violates partition constraint
366366
DETAIL: Failing row contains (3, 2).
367+
-- check that RETURNING works correctly with tuple-routing
368+
alter table p drop constraint check_b;
369+
create table p12 partition of p1 for values from (5) to (10);
370+
create table p2 (b int not null, a int not null);
371+
alter table p attach partition p2 for values from (1, 10) to (1, 20);
372+
create table p3 partition of p for values from (1, 20) to (1, 30);
373+
create table p4 (like p);
374+
alter table p4 drop a;
375+
alter table p4 add a int not null;
376+
alter table p attach partition p4 for values from (1, 30) to (1, 40);
377+
with ins (a, b, c) as
378+
(insert into p (b, a) select s.a, 1 from generate_series(2, 39) s(a) returning tableoid::regclass, *)
379+
select a, b, min(c), max(c) from ins group by a, b order by 1;
380+
a | b | min | max
381+
-----+---+-----+-----
382+
p11 | 1 | 2 | 4
383+
p12 | 1 | 5 | 9
384+
p2 | 1 | 10 | 19
385+
p3 | 1 | 20 | 29
386+
p4 | 1 | 30 | 39
387+
(5 rows)
388+
367389
-- cleanup
368-
drop table p, p1, p11;
390+
drop table p, p1, p11, p12, p2, p3, p4;

‎src/test/regress/sql/insert.sql

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -226,5 +226,19 @@ insert into p values (1, 2);
226226
-- selected by tuple-routing
227227
insert into p1 (a, b)values (2,3);
228228

229+
-- check that RETURNING works correctly with tuple-routing
230+
altertable p dropconstraint check_b;
231+
createtablep12 partition of p1 forvaluesfrom (5) to (10);
232+
createtablep2 (bintnot null, aintnot null);
233+
altertable p attach partition p2 forvaluesfrom (1,10) to (1,20);
234+
createtablep3 partition of p forvaluesfrom (1,20) to (1,30);
235+
createtablep4 (like p);
236+
altertable p4 drop a;
237+
altertable p4 add aintnot null;
238+
altertable p attach partition p4 forvaluesfrom (1,30) to (1,40);
239+
with ins (a, b, c)as
240+
(insert into p (b, a)selects.a,1from generate_series(2,39) s(a) returning tableoid::regclass,*)
241+
select a, b,min(c),max(c)from insgroup by a, border by1;
242+
229243
-- cleanup
230-
droptable p, p1, p11;
244+
droptable p, p1, p11, p12, p2, p3, p4;

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp