From: =?UTF-8?q?=C3=81lvaro=20Herrera?= Date: Sun, 29 Mar 2026 22:57:27 +0200 Subject: [PATCH v2 1/2] Make table_update/table_delete take bitmask options Right now, table_update doesn't recognize any; but table_delete has an option TABLE_DELETE_CHANGING_PARTITION to replace the boolean changingPart argument it previously had. The reason for this is to more cleanly introduce further options -- in particular, the REPACK patch wants to add a NO_LOGICAL option to both these functions, to match the one that table_insert already has. While at it, change the 'int options' argument of the insert side to 'bits32', which is unsigned, per Andres. XXX this could perhaps be a separate commit. --- src/backend/access/heap/heapam.c | 24 +++++++------ src/backend/access/heap/heapam_handler.c | 17 +++++---- src/backend/access/table/tableam.c | 6 ++-- src/backend/executor/nodeModifyTable.c | 9 +++-- src/include/access/heapam.h | 11 +++--- src/include/access/tableam.h | 44 +++++++++++++++--------- 6 files changed, 67 insertions(+), 44 deletions(-) diff --git a/src/backend/access/heap/heapam.c b/src/backend/access/heap/heapam.c index eb1f67f31cd..1b873f55c70 100644 --- a/src/backend/access/heap/heapam.c +++ b/src/backend/access/heap/heapam.c @@ -57,7 +57,7 @@ static HeapTuple heap_prepare_insert(Relation relation, HeapTuple tup, - TransactionId xid, CommandId cid, int options); + TransactionId xid, CommandId cid, bits32 options); static XLogRecPtr log_heap_update(Relation reln, Buffer oldbuf, Buffer newbuf, HeapTuple oldtup, HeapTuple newtup, HeapTuple old_key_tuple, @@ -2148,7 +2148,7 @@ ReleaseBulkInsertStatePin(BulkInsertState bistate) */ void heap_insert(Relation relation, HeapTuple tup, CommandId cid, - int options, BulkInsertState bistate) + bits32 options, BulkInsertState bistate) { TransactionId xid = GetCurrentTransactionId(); HeapTuple heaptup; @@ -2339,7 +2339,7 @@ heap_insert(Relation relation, HeapTuple tup, CommandId cid, */ static HeapTuple heap_prepare_insert(Relation relation, HeapTuple tup, TransactionId xid, - CommandId cid, int options) + CommandId cid, bits32 options) { /* * To allow parallel inserts, we need to ensure that they are safe to be @@ -2419,7 +2419,7 @@ heap_multi_insert_pages(HeapTuple *heaptuples, int done, int ntuples, Size saveF */ void heap_multi_insert(Relation relation, TupleTableSlot **slots, int ntuples, - CommandId cid, int options, BulkInsertState bistate) + CommandId cid, bits32 options, BulkInsertState bistate) { TransactionId xid = GetCurrentTransactionId(); HeapTuple *heaptuples; @@ -2850,8 +2850,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, bits32 options, Snapshot crosscheck, + bool wait, TM_FailureData *tmfd) { TM_Result result; TransactionId xid = GetCurrentTransactionId(); @@ -2864,6 +2864,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; @@ -3278,9 +3279,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: @@ -3319,7 +3322,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, bits32 options, Snapshot crosscheck, bool wait, TM_FailureData *tmfd, LockTupleMode *lockmode, TU_UpdateIndexes *update_indexes) { @@ -4573,7 +4576,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) diff --git a/src/backend/access/heap/heapam_handler.c b/src/backend/access/heap/heapam_handler.c index d40878928e1..dd03c8c29a6 100644 --- a/src/backend/access/heap/heapam_handler.c +++ b/src/backend/access/heap/heapam_handler.c @@ -252,7 +252,7 @@ heapam_tuple_satisfies_snapshot(Relation rel, TupleTableSlot *slot, static void heapam_tuple_insert(Relation relation, TupleTableSlot *slot, CommandId cid, - int options, BulkInsertState bistate) + bits32 options, BulkInsertState bistate) { bool shouldFree = true; HeapTuple tuple = ExecFetchSlotHeapTuple(slot, true, &shouldFree); @@ -271,7 +271,7 @@ heapam_tuple_insert(Relation relation, TupleTableSlot *slot, CommandId cid, static void heapam_tuple_insert_speculative(Relation relation, TupleTableSlot *slot, - CommandId cid, int options, + CommandId cid, bits32 options, BulkInsertState bistate, uint32 specToken) { bool shouldFree = true; @@ -311,21 +311,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) + bits32 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, bits32 options pg_attribute_unused(), + Snapshot snapshot, Snapshot crosscheck, bool wait, TM_FailureData *tmfd, LockTupleMode *lockmode, TU_UpdateIndexes *update_indexes) { @@ -337,7 +339,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); diff --git a/src/backend/access/table/tableam.c b/src/backend/access/table/tableam.c index dfda1af412e..50206ae782f 100644 --- a/src/backend/access/table/tableam.c +++ b/src/backend/access/table/tableam.c @@ -318,9 +318,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) { @@ -367,7 +367,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); diff --git a/src/backend/executor/nodeModifyTable.c b/src/backend/executor/nodeModifyTable.c index 4cd5e262e0f..9f763f756b0 100644 --- a/src/backend/executor/nodeModifyTable.c +++ b/src/backend/executor/nodeModifyTable.c @@ -1522,14 +1522,18 @@ ExecDeleteAct(ModifyTableContext *context, ResultRelInfo *resultRelInfo, ItemPointer tupleid, bool changingPart) { EState *estate = context->estate; + bits32 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); } /* @@ -2331,6 +2335,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 */ , diff --git a/src/include/access/heapam.h b/src/include/access/heapam.h index 9b403203006..80bcda02cb7 100644 --- a/src/include/access/heapam.h +++ b/src/include/access/heapam.h @@ -379,18 +379,19 @@ extern void FreeBulkInsertState(BulkInsertState); extern void ReleaseBulkInsertStatePin(BulkInsertState bistate); extern void heap_insert(Relation relation, HeapTuple tup, CommandId cid, - int options, BulkInsertState bistate); + bits32 options, BulkInsertState bistate); extern void heap_multi_insert(Relation relation, TupleTableSlot **slots, - int ntuples, CommandId cid, int options, + int ntuples, CommandId cid, bits32 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, bits32 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, bits32 options, + Snapshot crosscheck, bool wait, TM_FailureData *tmfd, LockTupleMode *lockmode, TU_UpdateIndexes *update_indexes); extern TM_Result heap_lock_tuple(Relation relation, HeapTuple tuple, diff --git a/src/include/access/tableam.h b/src/include/access/tableam.h index 06084752245..3c82b80d45d 100644 --- a/src/include/access/tableam.h +++ b/src/include/access/tableam.h @@ -254,7 +254,10 @@ typedef struct TM_IndexDeleteOp TM_IndexStatus *status; } TM_IndexDeleteOp; -/* "options" flag bits for table_tuple_insert */ +/* + * "options" flag bits for table_tuple_insert. Access methods may define + * their own bits for internal use, as long as they don't collide with these. + */ /* TABLE_INSERT_SKIP_WAL was 0x0001; RelationNeedsWAL() now governs */ #define TABLE_INSERT_SKIP_FSM 0x0002 #define TABLE_INSERT_FROZEN 0x0004 @@ -266,6 +269,11 @@ typedef struct TM_IndexDeleteOp /* Follow update chain and lock latest version of tuple */ #define TUPLE_LOCK_FLAG_FIND_LAST_VERSION (1 << 1) +/* "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 */ /* Typedef for callback function for table_index_build_scan */ typedef void (*IndexBuildCallback) (Relation index, @@ -508,14 +516,14 @@ typedef struct TableAmRoutine /* see table_tuple_insert() for reference about parameters */ void (*tuple_insert) (Relation rel, TupleTableSlot *slot, - CommandId cid, int options, + CommandId cid, bits32 options, BulkInsertStateData *bistate); /* see table_tuple_insert_speculative() for reference about parameters */ void (*tuple_insert_speculative) (Relation rel, TupleTableSlot *slot, CommandId cid, - int options, + bits32 options, BulkInsertStateData *bistate, uint32 specToken); @@ -527,23 +535,24 @@ typedef struct TableAmRoutine /* see table_multi_insert() for reference about parameters */ void (*multi_insert) (Relation rel, TupleTableSlot **slots, int nslots, - CommandId cid, int options, BulkInsertStateData *bistate); + CommandId cid, bits32 options, BulkInsertStateData *bistate); /* see table_tuple_delete() for reference about parameters */ TM_Result (*tuple_delete) (Relation rel, ItemPointer tid, CommandId cid, + bits32 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, + bits32 options, Snapshot snapshot, Snapshot crosscheck, bool wait, @@ -574,7 +583,7 @@ typedef struct TableAmRoutine * * Optional callback. */ - void (*finish_bulk_insert) (Relation rel, int options); + void (*finish_bulk_insert) (Relation rel, bits32 options); /* ------------------------------------------------------------------------ @@ -1386,7 +1395,7 @@ table_index_delete_tuples(Relation rel, TM_IndexDeleteOp *delstate) */ static inline void table_tuple_insert(Relation rel, TupleTableSlot *slot, CommandId cid, - int options, BulkInsertStateData *bistate) + bits32 options, BulkInsertStateData *bistate) { rel->rd_tableam->tuple_insert(rel, slot, cid, options, bistate); @@ -1405,7 +1414,7 @@ table_tuple_insert(Relation rel, TupleTableSlot *slot, CommandId cid, */ static inline void table_tuple_insert_speculative(Relation rel, TupleTableSlot *slot, - CommandId cid, int options, + CommandId cid, bits32 options, BulkInsertStateData *bistate, uint32 specToken) { @@ -1441,7 +1450,7 @@ table_tuple_complete_speculative(Relation rel, TupleTableSlot *slot, */ static inline void table_multi_insert(Relation rel, TupleTableSlot **slots, int nslots, - CommandId cid, int options, BulkInsertStateData *bistate) + CommandId cid, bits32 options, BulkInsertStateData *bistate) { rel->rd_tableam->multi_insert(rel, slots, nslots, cid, options, bistate); @@ -1476,12 +1485,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) + bits32 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); } /* @@ -1521,12 +1530,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, bits32 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); } @@ -1582,7 +1592,7 @@ table_tuple_lock(Relation rel, ItemPointer tid, Snapshot snapshot, * tuple_insert and multi_insert with a BulkInsertState specified. */ static inline void -table_finish_bulk_insert(Relation rel, int options) +table_finish_bulk_insert(Relation rel, bits32 options) { /* optional callback */ if (rel->rd_tableam && rel->rd_tableam->finish_bulk_insert) -- 2.47.3 --hvxy7gv3jnhbw7zz Content-Type: text/x-diff; charset=utf-8 Content-Disposition: attachment; filename="v2-0002-Define-heap_insert-to-obey-tableam.h-option-bits-.patch"