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

Commit764da77

Browse files
committed
Evade extra table_tuple_fetch_row_version() in ExecUpdate()/ExecDelete()
When we lock tuple using table_tuple_lock() then we at the same time fetchthe locked tuple to the slot. In this case we can skip extratable_tuple_fetch_row_version() thank to we've already fetched the 'old' tupleand nobody can change it concurrently since it's locked.Discussion:https://postgr.es/m/CAPpHfdua-YFw3XTprfutzGp28xXLigFtzNbuFY8yPhqeq6X5kg%40mail.gmail.comReviewed-by: Aleksander Alekseev, Pavel Borisov, Vignesh C, Mason SharpReviewed-by: Andres Freund, Chris Travers
1 parentc75a623 commit764da77

File tree

1 file changed

+35
-13
lines changed

1 file changed

+35
-13
lines changed

‎src/backend/executor/nodeModifyTable.c

Lines changed: 35 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1559,6 +1559,22 @@ ExecDelete(ModifyTableContext *context,
15591559
{
15601560
caseTM_Ok:
15611561
Assert(context->tmfd.traversed);
1562+
1563+
/*
1564+
* Save locked tuple for further processing of
1565+
* RETURNING clause.
1566+
*/
1567+
if (processReturning&&
1568+
resultRelInfo->ri_projectReturning&&
1569+
!resultRelInfo->ri_FdwRoutine)
1570+
{
1571+
TupleTableSlot*returningSlot;
1572+
1573+
returningSlot=ExecGetReturningSlot(estate,resultRelInfo);
1574+
ExecCopySlot(returningSlot,inputslot);
1575+
ExecMaterializeSlot(returningSlot);
1576+
}
1577+
15621578
epqslot=EvalPlanQual(context->epqstate,
15631579
resultRelationDesc,
15641580
resultRelInfo->ri_RangeTableIndex,
@@ -1673,12 +1689,17 @@ ExecDelete(ModifyTableContext *context,
16731689
}
16741690
else
16751691
{
1692+
/*
1693+
* Tuple can be already fetched to the returning slot in case
1694+
* we've previously locked it. Fetch the tuple only if the slot
1695+
* is empty.
1696+
*/
16761697
slot=ExecGetReturningSlot(estate,resultRelInfo);
16771698
if (oldtuple!=NULL)
16781699
{
16791700
ExecForceStoreHeapTuple(oldtuple,slot, false);
16801701
}
1681-
else
1702+
elseif (TupIsNull(slot))
16821703
{
16831704
if (!table_tuple_fetch_row_version(resultRelationDesc,tupleid,
16841705
SnapshotAny,slot))
@@ -2393,6 +2414,19 @@ ExecUpdate(ModifyTableContext *context, ResultRelInfo *resultRelInfo,
23932414
caseTM_Ok:
23942415
Assert(context->tmfd.traversed);
23952416

2417+
/* Make sure ri_oldTupleSlot is initialized. */
2418+
if (unlikely(!resultRelInfo->ri_projectNewInfoValid))
2419+
ExecInitUpdateProjection(context->mtstate,
2420+
resultRelInfo);
2421+
2422+
/*
2423+
* Save the locked tuple for further calculation
2424+
* of the new tuple.
2425+
*/
2426+
oldSlot=resultRelInfo->ri_oldTupleSlot;
2427+
ExecCopySlot(oldSlot,inputslot);
2428+
ExecMaterializeSlot(oldSlot);
2429+
23962430
epqslot=EvalPlanQual(context->epqstate,
23972431
resultRelationDesc,
23982432
resultRelInfo->ri_RangeTableIndex,
@@ -2401,18 +2435,6 @@ ExecUpdate(ModifyTableContext *context, ResultRelInfo *resultRelInfo,
24012435
/* Tuple not passing quals anymore, exiting... */
24022436
returnNULL;
24032437

2404-
/* Make sure ri_oldTupleSlot is initialized. */
2405-
if (unlikely(!resultRelInfo->ri_projectNewInfoValid))
2406-
ExecInitUpdateProjection(context->mtstate,
2407-
resultRelInfo);
2408-
2409-
/* Fetch the most recent version of old tuple. */
2410-
oldSlot=resultRelInfo->ri_oldTupleSlot;
2411-
if (!table_tuple_fetch_row_version(resultRelationDesc,
2412-
tupleid,
2413-
SnapshotAny,
2414-
oldSlot))
2415-
elog(ERROR,"failed to fetch tuple being updated");
24162438
slot=ExecGetUpdateNewTuple(resultRelInfo,
24172439
epqslot,oldSlot);
24182440
gotoredo_act;

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp