Give an 'options' parameter to tuple_delete/_update

The tuple_insert() method already has an equivalent argument, so this
makes sense just on consistency grounds, for future growth.

table_delete() can immediately use it to carry the 'changingPart'
boolean; for table_update we don't have any options at present.

Author: Álvaro Herrera <alvherre@kurilemu.de>
Reviewed-by: Nathan Bossart <nathandbossart@gmail.com> (older version)
Reviewed-by: Zsolt Parragi <zsolt.parragi@percona.com>
Reviewed-by: Chao Li <li.evan.chao@gmail.com>
Reviewed-by: Antonin Houska <ah@cybertec.at>
Discussion: https://postgr.es/m/202603171606.kf6pmhscqbqz@alvherre.pgsql
This commit is contained in:
Álvaro Herrera 2026-04-01 20:26:57 +02:00
parent 8e72d914c5
commit db89a47115
No known key found for this signature in database
GPG key ID: 1C20ACB9D5C564AE
6 changed files with 52 additions and 29 deletions

View file

@ -2862,8 +2862,8 @@ xmax_infomask_changed(uint16 new_infomask, uint16 old_infomask)
*/
TM_Result
heap_delete(Relation relation, const ItemPointerData *tid,
CommandId cid, Snapshot crosscheck, bool wait,
TM_FailureData *tmfd, bool changingPart)
CommandId cid, uint32 options, Snapshot crosscheck,
bool wait, TM_FailureData *tmfd)
{
TM_Result result;
TransactionId xid = GetCurrentTransactionId();
@ -2876,6 +2876,7 @@ heap_delete(Relation relation, const ItemPointerData *tid,
TransactionId new_xmax;
uint16 new_infomask,
new_infomask2;
bool changingPart = (options & TABLE_DELETE_CHANGING_PARTITION) != 0;
bool have_tuple_lock = false;
bool iscombo;
bool all_visible_cleared = false;
@ -3290,9 +3291,11 @@ simple_heap_delete(Relation relation, const ItemPointerData *tid)
TM_FailureData tmfd;
result = heap_delete(relation, tid,
GetCurrentCommandId(true), InvalidSnapshot,
GetCurrentCommandId(true),
0,
InvalidSnapshot,
true /* wait for commit */ ,
&tmfd, false /* changingPart */ );
&tmfd);
switch (result)
{
case TM_SelfModified:
@ -3331,7 +3334,7 @@ simple_heap_delete(Relation relation, const ItemPointerData *tid)
*/
TM_Result
heap_update(Relation relation, const ItemPointerData *otid, HeapTuple newtup,
CommandId cid, Snapshot crosscheck, bool wait,
CommandId cid, uint32 options pg_attribute_unused(), Snapshot crosscheck, bool wait,
TM_FailureData *tmfd, LockTupleMode *lockmode,
TU_UpdateIndexes *update_indexes)
{
@ -4585,7 +4588,8 @@ simple_heap_update(Relation relation, const ItemPointerData *otid, HeapTuple tup
LockTupleMode lockmode;
result = heap_update(relation, otid, tup,
GetCurrentCommandId(true), InvalidSnapshot,
GetCurrentCommandId(true), 0,
InvalidSnapshot,
true /* wait for commit */ ,
&tmfd, &lockmode, update_indexes);
switch (result)

View file

@ -313,21 +313,23 @@ heapam_tuple_complete_speculative(Relation relation, TupleTableSlot *slot,
static TM_Result
heapam_tuple_delete(Relation relation, ItemPointer tid, CommandId cid,
Snapshot snapshot, Snapshot crosscheck, bool wait,
TM_FailureData *tmfd, bool changingPart)
uint32 options, Snapshot snapshot, Snapshot crosscheck,
bool wait, TM_FailureData *tmfd)
{
/*
* Currently Deleting of index tuples are handled at vacuum, in case if
* the storage itself is cleaning the dead tuples by itself, it is the
* time to call the index tuple deletion also.
*/
return heap_delete(relation, tid, cid, crosscheck, wait, tmfd, changingPart);
return heap_delete(relation, tid, cid, options, crosscheck, wait,
tmfd);
}
static TM_Result
heapam_tuple_update(Relation relation, ItemPointer otid, TupleTableSlot *slot,
CommandId cid, Snapshot snapshot, Snapshot crosscheck,
CommandId cid, uint32 options,
Snapshot snapshot, Snapshot crosscheck,
bool wait, TM_FailureData *tmfd,
LockTupleMode *lockmode, TU_UpdateIndexes *update_indexes)
{
@ -339,7 +341,8 @@ heapam_tuple_update(Relation relation, ItemPointer otid, TupleTableSlot *slot,
slot->tts_tableOid = RelationGetRelid(relation);
tuple->t_tableOid = slot->tts_tableOid;
result = heap_update(relation, otid, tuple, cid, crosscheck, wait,
result = heap_update(relation, otid, tuple, cid, options,
crosscheck, wait,
tmfd, lockmode, update_indexes);
ItemPointerCopy(&tuple->t_self, &slot->tts_tid);

View file

@ -320,9 +320,9 @@ simple_table_tuple_delete(Relation rel, ItemPointer tid, Snapshot snapshot)
result = table_tuple_delete(rel, tid,
GetCurrentCommandId(true),
snapshot, InvalidSnapshot,
0, snapshot, InvalidSnapshot,
true /* wait for commit */ ,
&tmfd, false /* changingPart */ );
&tmfd);
switch (result)
{
@ -369,7 +369,7 @@ simple_table_tuple_update(Relation rel, ItemPointer otid,
result = table_tuple_update(rel, otid, slot,
GetCurrentCommandId(true),
snapshot, InvalidSnapshot,
0, snapshot, InvalidSnapshot,
true /* wait for commit */ ,
&tmfd, &lockmode, update_indexes);

View file

@ -1751,14 +1751,18 @@ ExecDeleteAct(ModifyTableContext *context, ResultRelInfo *resultRelInfo,
ItemPointer tupleid, bool changingPart)
{
EState *estate = context->estate;
uint32 options = 0;
if (changingPart)
options |= TABLE_DELETE_CHANGING_PARTITION;
return table_tuple_delete(resultRelInfo->ri_RelationDesc, tupleid,
estate->es_output_cid,
options,
estate->es_snapshot,
estate->es_crosscheck_snapshot,
true /* wait for commit */ ,
&context->tmfd,
changingPart);
&context->tmfd);
}
/*
@ -2568,6 +2572,7 @@ lreplace:
*/
result = table_tuple_update(resultRelationDesc, tupleid, slot,
estate->es_output_cid,
0,
estate->es_snapshot,
estate->es_crosscheck_snapshot,
true /* wait for commit */ ,

View file

@ -382,13 +382,14 @@ extern void heap_multi_insert(Relation relation, TupleTableSlot **slots,
int ntuples, CommandId cid, uint32 options,
BulkInsertState bistate);
extern TM_Result heap_delete(Relation relation, const ItemPointerData *tid,
CommandId cid, Snapshot crosscheck, bool wait,
TM_FailureData *tmfd, bool changingPart);
CommandId cid, uint32 options, Snapshot crosscheck,
bool wait, TM_FailureData *tmfd);
extern void heap_finish_speculative(Relation relation, const ItemPointerData *tid);
extern void heap_abort_speculative(Relation relation, const ItemPointerData *tid);
extern TM_Result heap_update(Relation relation, const ItemPointerData *otid,
HeapTuple newtup,
CommandId cid, Snapshot crosscheck, bool wait,
CommandId cid, uint32 options,
Snapshot crosscheck, bool wait,
TM_FailureData *tmfd, LockTupleMode *lockmode,
TU_UpdateIndexes *update_indexes);
extern TM_Result heap_lock_tuple(Relation relation, HeapTuple tuple,

View file

@ -282,6 +282,12 @@ typedef struct TM_IndexDeleteOp
#define TABLE_INSERT_FROZEN 0x0004
#define TABLE_INSERT_NO_LOGICAL 0x0008
/* "options" flag bits for table_tuple_delete */
#define TABLE_DELETE_CHANGING_PARTITION (1 << 0)
/* "options" flag bits for table_tuple_update */
/* XXX none at present */
/* flag bits for table_tuple_lock */
/* Follow tuples whose update is in progress if lock modes don't conflict */
#define TUPLE_LOCK_FLAG_LOCK_UPDATE_IN_PROGRESS (1 << 0)
@ -559,17 +565,18 @@ typedef struct TableAmRoutine
TM_Result (*tuple_delete) (Relation rel,
ItemPointer tid,
CommandId cid,
uint32 options,
Snapshot snapshot,
Snapshot crosscheck,
bool wait,
TM_FailureData *tmfd,
bool changingPart);
TM_FailureData *tmfd);
/* see table_tuple_update() for reference about parameters */
TM_Result (*tuple_update) (Relation rel,
ItemPointer otid,
TupleTableSlot *slot,
CommandId cid,
uint32 options,
Snapshot snapshot,
Snapshot crosscheck,
bool wait,
@ -1516,10 +1523,11 @@ table_multi_insert(Relation rel, TupleTableSlot **slots, int nslots,
* tid - TID of tuple to be deleted
* cid - delete command ID (used for visibility test, and stored into
* cmax if successful)
* options - bitmask of options. Supported values:
* TABLE_DELETE_CHANGING_PARTITION: the tuple is being moved to another
* partition table due to an update of the partition key.
* crosscheck - if not InvalidSnapshot, also check tuple against this
* wait - true if should wait for any conflicting update to commit/abort
* changingPart - true iff the tuple is being moved to another partition
* table due to an update of the partition key. Otherwise, false.
*
* Output parameters:
* tmfd - filled in failure cases (see below)
@ -1534,12 +1542,12 @@ table_multi_insert(Relation rel, TupleTableSlot **slots, int nslots,
*/
static inline TM_Result
table_tuple_delete(Relation rel, ItemPointer tid, CommandId cid,
Snapshot snapshot, Snapshot crosscheck, bool wait,
TM_FailureData *tmfd, bool changingPart)
uint32 options, Snapshot snapshot, Snapshot crosscheck,
bool wait, TM_FailureData *tmfd)
{
return rel->rd_tableam->tuple_delete(rel, tid, cid,
return rel->rd_tableam->tuple_delete(rel, tid, cid, options,
snapshot, crosscheck,
wait, tmfd, changingPart);
wait, tmfd);
}
/*
@ -1553,6 +1561,7 @@ table_tuple_delete(Relation rel, ItemPointer tid, CommandId cid,
* otid - TID of old tuple to be replaced
* cid - update command ID (used for visibility test, and stored into
* cmax/cmin if successful)
* options - bitmask of options. No values are currently recognized.
* crosscheck - if not InvalidSnapshot, also check old tuple against this
* wait - true if should wait for any conflicting update to commit/abort
*
@ -1579,12 +1588,13 @@ table_tuple_delete(Relation rel, ItemPointer tid, CommandId cid,
*/
static inline TM_Result
table_tuple_update(Relation rel, ItemPointer otid, TupleTableSlot *slot,
CommandId cid, Snapshot snapshot, Snapshot crosscheck,
CommandId cid, uint32 options,
Snapshot snapshot, Snapshot crosscheck,
bool wait, TM_FailureData *tmfd, LockTupleMode *lockmode,
TU_UpdateIndexes *update_indexes)
{
return rel->rd_tableam->tuple_update(rel, otid, slot,
cid, snapshot, crosscheck,
cid, options, snapshot, crosscheck,
wait, tmfd,
lockmode, update_indexes);
}