From 1bd6f22f43ac1bd2215ba4ef720fc4f18fea26e5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=81lvaro=20Herrera?= Date: Mon, 30 Mar 2026 13:27:04 +0200 Subject: [PATCH] Have table_insert and siblings use an unsigned type for options Using signed types can lead to bugs, such as the one fixed by commit 2a2e1b470b9b. Discussion: https://postgr.es/m/44e6ze3kuunhky63wmfjxrmn72pds2whwf5ok6hpz7c4my7k2h@l65zhpcuasnf --- src/backend/access/heap/heapam.c | 8 ++++---- src/backend/access/heap/heapam_handler.c | 4 ++-- src/include/access/heapam.h | 4 ++-- src/include/access/tableam.h | 21 ++++++++++++--------- 4 files changed, 20 insertions(+), 17 deletions(-) diff --git a/src/backend/access/heap/heapam.c b/src/backend/access/heap/heapam.c index eb1f67f31cd..882deda6b95 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; diff --git a/src/backend/access/heap/heapam_handler.c b/src/backend/access/heap/heapam_handler.c index d40878928e1..7c2194b152b 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; diff --git a/src/include/access/heapam.h b/src/include/access/heapam.h index 9b403203006..53e86c0d6e1 100644 --- a/src/include/access/heapam.h +++ b/src/include/access/heapam.h @@ -379,9 +379,9 @@ 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, diff --git a/src/include/access/tableam.h b/src/include/access/tableam.h index 06084752245..3b017e043a0 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 @@ -508,14 +511,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,7 +530,7 @@ 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, @@ -574,7 +577,7 @@ typedef struct TableAmRoutine * * Optional callback. */ - void (*finish_bulk_insert) (Relation rel, int options); + void (*finish_bulk_insert) (Relation rel, bits32 options); /* ------------------------------------------------------------------------ @@ -1386,7 +1389,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 +1408,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 +1444,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); @@ -1582,7 +1585,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)