agora inbox for pgsql-hackers@postgresql.org
help / color / mirror / Atom feedFrom: Álvaro Herrera <alvherre@kurilemu.de>
To: Chao Li <li.evan.chao@gmail.com>
Cc: Andres Freund <andres@anarazel.de>
Cc: Pg Hackers <pgsql-hackers@lists.postgresql.org>
Cc: Zsolt Parragi <zsolt.parragi@percona.com>
Cc: Nathan Bossart <nathandbossart@gmail.com>
Subject: Re: table AM option passing
Date: Wed, 1 Apr 2026 16:27:18 +0200
Message-ID: <202604011417.bwthhrwmivd4@alvherre.pgsql> (raw)
In-Reply-To: <40E570EE-5A60-49D8-B8F7-2F8F2B7C8DFA@gmail.com>
On 2026-Apr-01, Chao Li wrote:
> 1 - 0001
> For table_tuple_delete(), options is added and changingPart is
> removed, but the header comment should be updated to reflect the
> change.
True, fixed.
> 2 - 0002
> For table_tuple_update(), options is added, the header comment should
> be updated as well.
Done.
> 3 - 0002
> Now TABLE_INSERT_SKIP_FSM, TABLE_INSERT_FROZEN, TABLE_INSERT_NO_LOGICAL belong to the same options word as HEAP_INSERT_SPECULATIVE, but they are still defined as:
> ```
> #define TABLE_INSERT_SKIP_FSM 0x0002
> #define TABLE_INSERT_FROZEN 0x0004
> #define TABLE_INSERT_NO_LOGICAL 0x0008
> ```
>
> Could it make sense to change them to the left-shift form?
Yeah, I don't know. I don't like this style, but some people like it,
and I don't want to get into an argument about this kind of thing.
> 4 - 0002
> In heap_multi_insert(), heap_prepare_insert(), and heap_insert(),
> options is defined as uint32, but in RelationGetBufferForTuple() and
> raw_heap_insert() it is still defined as int. Would it make sense to
> take this opportunity to change all “options" to uint32 for
> consistency? Otherwise, if this is left for later, a trivial follow-up
> patch just to change int to uint32 may be harder to get processed.
Hmm, this is actually a problem in 1bd6f22f43ac. I added a preliminary
patch that should fix this.
--
Álvaro Herrera PostgreSQL Developer — https://www.EnterpriseDB.com/
"No renuncies a nada. No te aferres a nada."
Attachments:
[text/x-diff] v5-0001-Fix-callers-of-heap_insert-and-siblings-to-use-ui.patch (10.5K, ../202604011417.bwthhrwmivd4@alvherre.pgsql/2-v5-0001-Fix-callers-of-heap_insert-and-siblings-to-use-ui.patch)
download | inline diff:
From 368d46e17eaff4b79a8451713169c3580348c3fb Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=C3=81lvaro=20Herrera?= <alvherre@kurilemu.de>
Date: Wed, 1 Apr 2026 15:06:15 +0200
Subject: [PATCH v5 1/3] Fix callers of heap_insert and siblings to use uint32
for options, not int
Oversight in commit 1bd6f22f43ac: I was way too optimistic about the
compiler letting me know what variables needed to be updated, and missed
a few of them. Clean it up.
Reported-by: Chao Li <li.evan.chao@gmail.com>
Discussion: https://postgr.es/m/40E570EE-5A60-49D8-B8F7-2F8F2B7C8DFA@gmail.com
---
src/backend/access/common/toast_internals.c | 2 +-
src/backend/access/heap/heaptoast.c | 2 +-
src/backend/access/heap/hio.c | 2 +-
src/backend/access/heap/rewriteheap.c | 2 +-
src/backend/access/table/toast_helper.c | 2 +-
src/backend/commands/copyfrom.c | 8 ++++----
src/backend/commands/createas.c | 2 +-
src/backend/commands/matview.c | 2 +-
src/backend/commands/tablecmds.c | 8 ++++----
src/include/access/heaptoast.h | 2 +-
src/include/access/hio.h | 2 +-
src/include/access/toast_helper.h | 2 +-
src/include/access/toast_internals.h | 2 +-
13 files changed, 19 insertions(+), 19 deletions(-)
diff --git a/src/backend/access/common/toast_internals.c b/src/backend/access/common/toast_internals.c
index 4d0da07135e..77d42e7ed65 100644
--- a/src/backend/access/common/toast_internals.c
+++ b/src/backend/access/common/toast_internals.c
@@ -117,7 +117,7 @@ toast_compress_datum(Datum value, char cmethod)
*/
Datum
toast_save_datum(Relation rel, Datum value,
- varlena *oldexternal, int options)
+ varlena *oldexternal, uint32 options)
{
Relation toastrel;
Relation *toastidxs;
diff --git a/src/backend/access/heap/heaptoast.c b/src/backend/access/heap/heaptoast.c
index ba541bd60c9..03f885a25b0 100644
--- a/src/backend/access/heap/heaptoast.c
+++ b/src/backend/access/heap/heaptoast.c
@@ -94,7 +94,7 @@ heap_toast_delete(Relation rel, HeapTuple oldtup, bool is_speculative)
*/
HeapTuple
heap_toast_insert_or_update(Relation rel, HeapTuple newtup, HeapTuple oldtup,
- int options)
+ uint32 options)
{
HeapTuple result_tuple;
TupleDesc tupleDesc;
diff --git a/src/backend/access/heap/hio.c b/src/backend/access/heap/hio.c
index 1097f44a74e..e96e0f77d92 100644
--- a/src/backend/access/heap/hio.c
+++ b/src/backend/access/heap/hio.c
@@ -498,7 +498,7 @@ RelationAddBlocks(Relation relation, BulkInsertState bistate,
*/
Buffer
RelationGetBufferForTuple(Relation relation, Size len,
- Buffer otherBuffer, int options,
+ Buffer otherBuffer, uint32 options,
BulkInsertState bistate,
Buffer *vmbuffer, Buffer *vmbuffer_other,
int num_pages)
diff --git a/src/backend/access/heap/rewriteheap.c b/src/backend/access/heap/rewriteheap.c
index 6b19ac3030d..f707b102c72 100644
--- a/src/backend/access/heap/rewriteheap.c
+++ b/src/backend/access/heap/rewriteheap.c
@@ -618,7 +618,7 @@ raw_heap_insert(RewriteState state, HeapTuple tup)
}
else if (HeapTupleHasExternal(tup) || tup->t_len > TOAST_TUPLE_THRESHOLD)
{
- int options = HEAP_INSERT_SKIP_FSM;
+ uint32 options = HEAP_INSERT_SKIP_FSM;
/*
* While rewriting the heap for VACUUM FULL / CLUSTER, make sure data
diff --git a/src/backend/access/table/toast_helper.c b/src/backend/access/table/toast_helper.c
index 0d792a60ca0..2f2022d9951 100644
--- a/src/backend/access/table/toast_helper.c
+++ b/src/backend/access/table/toast_helper.c
@@ -253,7 +253,7 @@ toast_tuple_try_compression(ToastTupleContext *ttc, int attribute)
* Move an attribute to external storage.
*/
void
-toast_tuple_externalize(ToastTupleContext *ttc, int attribute, int options)
+toast_tuple_externalize(ToastTupleContext *ttc, int attribute, uint32 options)
{
Datum *value = &ttc->ttc_values[attribute];
Datum old_value = *value;
diff --git a/src/backend/commands/copyfrom.c b/src/backend/commands/copyfrom.c
index aa253b587aa..64ac3063c61 100644
--- a/src/backend/commands/copyfrom.c
+++ b/src/backend/commands/copyfrom.c
@@ -101,7 +101,7 @@ typedef struct CopyMultiInsertInfo
CopyFromState cstate; /* Copy state for this CopyMultiInsertInfo */
EState *estate; /* Executor state used for COPY */
CommandId mycid; /* Command Id used for COPY */
- int ti_options; /* table insert options */
+ uint32 ti_options; /* table insert options */
} CopyMultiInsertInfo;
@@ -401,7 +401,7 @@ CopyMultiInsertInfoSetupBuffer(CopyMultiInsertInfo *miinfo,
static void
CopyMultiInsertInfoInit(CopyMultiInsertInfo *miinfo, ResultRelInfo *rri,
CopyFromState cstate, EState *estate, CommandId mycid,
- int ti_options)
+ uint32 ti_options)
{
miinfo->multiInsertBuffers = NIL;
miinfo->bufferedTuples = 0;
@@ -535,7 +535,7 @@ CopyMultiInsertBufferFlush(CopyMultiInsertInfo *miinfo,
else
{
CommandId mycid = miinfo->mycid;
- int ti_options = miinfo->ti_options;
+ uint32 ti_options = miinfo->ti_options;
bool line_buf_valid = cstate->line_buf_valid;
uint64 save_cur_lineno = cstate->cur_lineno;
MemoryContext oldcontext;
@@ -792,7 +792,7 @@ CopyFrom(CopyFromState cstate)
PartitionTupleRouting *proute = NULL;
ErrorContextCallback errcallback;
CommandId mycid = GetCurrentCommandId(true);
- int ti_options = 0; /* start with default options for insert */
+ uint32 ti_options = 0; /* start with default options for insert */
BulkInsertState bistate = NULL;
CopyInsertMethod insertMethod;
CopyMultiInsertInfo multiInsertInfo = {0}; /* pacify compiler */
diff --git a/src/backend/commands/createas.c b/src/backend/commands/createas.c
index 270e9bf3110..6dbb831ca89 100644
--- a/src/backend/commands/createas.c
+++ b/src/backend/commands/createas.c
@@ -56,7 +56,7 @@ typedef struct
Relation rel; /* relation to write to */
ObjectAddress reladdr; /* address of rel, for ExecCreateTableAs */
CommandId output_cid; /* cmin to insert in output tuples */
- int ti_options; /* table_tuple_insert performance options */
+ uint32 ti_options; /* table_tuple_insert performance options */
BulkInsertState bistate; /* bulk insert state */
} DR_intorel;
diff --git a/src/backend/commands/matview.c b/src/backend/commands/matview.c
index 81a55a33ef2..d3be8939011 100644
--- a/src/backend/commands/matview.c
+++ b/src/backend/commands/matview.c
@@ -49,7 +49,7 @@ typedef struct
/* These fields are filled by transientrel_startup: */
Relation transientrel; /* relation to write to */
CommandId output_cid; /* cmin to insert in output tuples */
- int ti_options; /* table_tuple_insert performance options */
+ uint32 ti_options; /* table_tuple_insert performance options */
BulkInsertState bistate; /* bulk insert state */
} DR_transientrel;
diff --git a/src/backend/commands/tablecmds.c b/src/backend/commands/tablecmds.c
index 8b4ebc6f226..0ce2e81f9c2 100644
--- a/src/backend/commands/tablecmds.c
+++ b/src/backend/commands/tablecmds.c
@@ -6195,7 +6195,7 @@ ATRewriteTable(AlteredTableInfo *tab, Oid OIDNewHeap)
EState *estate;
CommandId mycid;
BulkInsertState bistate;
- int ti_options;
+ uint32 ti_options;
ExprState *partqualstate = NULL;
/*
@@ -22835,7 +22835,7 @@ MergePartitionsMoveRows(List **wqueue, List *mergingPartitions, Relation newPart
ListCell *ltab;
/* The FSM is empty, so don't bother using it. */
- int ti_options = TABLE_INSERT_SKIP_FSM;
+ uint32 ti_options = TABLE_INSERT_SKIP_FSM;
BulkInsertState bistate; /* state of bulk inserts for partition */
TupleTableSlot *dstslot;
@@ -23226,7 +23226,7 @@ createSplitPartitionContext(Relation partRel)
* deleteSplitPartitionContext: delete context for partition
*/
static void
-deleteSplitPartitionContext(SplitPartitionContext *pc, List **wqueue, int ti_options)
+deleteSplitPartitionContext(SplitPartitionContext *pc, List **wqueue, uint32 ti_options)
{
ListCell *ltab;
@@ -23268,7 +23268,7 @@ SplitPartitionMoveRows(List **wqueue, Relation rel, Relation splitRel,
List *partlist, List *newPartRels)
{
/* The FSM is empty, so don't bother using it. */
- int ti_options = TABLE_INSERT_SKIP_FSM;
+ uint32 ti_options = TABLE_INSERT_SKIP_FSM;
CommandId mycid;
EState *estate;
ListCell *listptr,
diff --git a/src/include/access/heaptoast.h b/src/include/access/heaptoast.h
index 725c0ce7554..631cb1836b9 100644
--- a/src/include/access/heaptoast.h
+++ b/src/include/access/heaptoast.h
@@ -95,7 +95,7 @@
* ----------
*/
extern HeapTuple heap_toast_insert_or_update(Relation rel, HeapTuple newtup,
- HeapTuple oldtup, int options);
+ HeapTuple oldtup, uint32 options);
/* ----------
* heap_toast_delete -
diff --git a/src/include/access/hio.h b/src/include/access/hio.h
index d8e63a54ea5..60cfc375fd5 100644
--- a/src/include/access/hio.h
+++ b/src/include/access/hio.h
@@ -54,7 +54,7 @@ typedef struct BulkInsertStateData
extern void RelationPutHeapTuple(Relation relation, Buffer buffer,
HeapTuple tuple, bool token);
extern Buffer RelationGetBufferForTuple(Relation relation, Size len,
- Buffer otherBuffer, int options,
+ Buffer otherBuffer, uint32 options,
BulkInsertStateData *bistate,
Buffer *vmbuffer, Buffer *vmbuffer_other,
int num_pages);
diff --git a/src/include/access/toast_helper.h b/src/include/access/toast_helper.h
index e8ecb995cb3..2ec92397f26 100644
--- a/src/include/access/toast_helper.h
+++ b/src/include/access/toast_helper.h
@@ -107,7 +107,7 @@ extern int toast_tuple_find_biggest_attribute(ToastTupleContext *ttc,
bool check_main);
extern void toast_tuple_try_compression(ToastTupleContext *ttc, int attribute);
extern void toast_tuple_externalize(ToastTupleContext *ttc, int attribute,
- int options);
+ uint32 options);
extern void toast_tuple_cleanup(ToastTupleContext *ttc);
extern void toast_delete_external(Relation rel, const Datum *values, const bool *isnull,
diff --git a/src/include/access/toast_internals.h b/src/include/access/toast_internals.h
index d382db34262..bf45889a642 100644
--- a/src/include/access/toast_internals.h
+++ b/src/include/access/toast_internals.h
@@ -50,7 +50,7 @@ extern Oid toast_get_valid_index(Oid toastoid, LOCKMODE lock);
extern void toast_delete_datum(Relation rel, Datum value, bool is_speculative);
extern Datum toast_save_datum(Relation rel, Datum value,
- varlena *oldexternal, int options);
+ varlena *oldexternal, uint32 options);
extern int toast_open_indexes(Relation toastrel,
LOCKMODE lock,
--
2.47.3
[text/x-diff] v5-0002-Give-options-parameter-to-table_delete-table_upda.patch (12.3K, ../202604011417.bwthhrwmivd4@alvherre.pgsql/3-v5-0002-Give-options-parameter-to-table_delete-table_upda.patch)
download | inline diff:
From c8e58c1a0c4aa3d946ceaa655c0ada793350fb85 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=C3=81lvaro=20Herrera?= <alvherre@kurilemu.de>
Date: Mon, 30 Mar 2026 13:27:42 +0200
Subject: [PATCH v5 2/3] Give 'options' parameter to table_delete/table_update
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
The table_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 (which is arguably misplaced in the current API); for
table_update we don't have any options at present, but an upcoming patch
would add one.
Author: Álvaro Herrera <alvherre@kurilemu.de>
Reviewed-by: Zsolt Parragi <zsolt.parragi@percona.com>
Reviewed-by: Chao Li <li.evan.chao@gmail.com>
Discussion: https://postgr.es/m/202603171606.kf6pmhscqbqz@alvherre.pgsql
---
src/backend/access/heap/heapam.c | 16 +++++++-----
src/backend/access/heap/heapam_handler.c | 13 ++++++----
src/backend/access/table/tableam.c | 6 ++---
src/backend/executor/nodeModifyTable.c | 9 +++++--
src/include/access/heapam.h | 7 +++---
src/include/access/tableam.h | 31 +++++++++++++++---------
6 files changed, 52 insertions(+), 30 deletions(-)
diff --git a/src/backend/access/heap/heapam.c b/src/backend/access/heap/heapam.c
index d34136d2e94..6bff0032db2 100644
--- a/src/backend/access/heap/heapam.c
+++ b/src/backend/access/heap/heapam.c
@@ -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)
diff --git a/src/backend/access/heap/heapam_handler.c b/src/backend/access/heap/heapam_handler.c
index cdd153c6b6d..1be8ea4845a 100644
--- a/src/backend/access/heap/heapam_handler.c
+++ b/src/backend/access/heap/heapam_handler.c
@@ -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);
diff --git a/src/backend/access/table/tableam.c b/src/backend/access/table/tableam.c
index 86481d7c029..68ff0966f1c 100644
--- a/src/backend/access/table/tableam.c
+++ b/src/backend/access/table/tableam.c
@@ -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);
diff --git a/src/backend/executor/nodeModifyTable.c b/src/backend/executor/nodeModifyTable.c
index 582bcc367c0..76728f08734 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;
+ 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);
}
/*
@@ -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 f46c83e88f3..54067b828e4 100644
--- a/src/include/access/heapam.h
+++ b/src/include/access/heapam.h
@@ -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,
diff --git a/src/include/access/tableam.h b/src/include/access/tableam.h
index 57892152957..9b5d7424dda 100644
--- a/src/include/access/tableam.h
+++ b/src/include/access/tableam.h
@@ -282,13 +282,18 @@ 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)
/* Follow update chain and lock latest version of tuple */
#define TUPLE_LOCK_FLAG_FIND_LAST_VERSION (1 << 1)
-
/* Typedef for callback function for table_index_build_scan */
typedef void (*IndexBuildCallback) (Relation index,
ItemPointer tid,
@@ -559,17 +564,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 +1522,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 +1541,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 +1560,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 +1587,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);
}
--
2.47.3
[text/x-diff] v5-0003-Define-heap_insert-to-obey-tableam.h-option-bits-.patch (8.7K, ../202604011417.bwthhrwmivd4@alvherre.pgsql/4-v5-0003-Define-heap_insert-to-obey-tableam.h-option-bits-.patch)
download | inline diff:
From 6d527c234238cc2085fe7552fb840a59bb5ecf80 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=C3=81lvaro=20Herrera?= <alvherre@kurilemu.de>
Date: Sun, 29 Mar 2026 23:11:42 +0200
Subject: [PATCH v5 3/3] Define heap_insert to obey tableam.h option bits
directly
Redefining the bits at the heapam.h interface serves no purpose.
Also, whenever somebody next defines a new TABLE_INSERT_* bit, the value
value would collide with HEAP_INSERT_SPECULATIVE. Move the latter to
the other end of the bits word.
---
src/backend/access/heap/heapam.c | 20 ++++++++++----------
src/backend/access/heap/hio.c | 10 +++++-----
src/backend/access/heap/rewriteheap.c | 4 ++--
src/backend/replication/logical/decode.c | 2 +-
src/include/access/heapam.h | 11 ++++++-----
5 files changed, 24 insertions(+), 23 deletions(-)
diff --git a/src/backend/access/heap/heapam.c b/src/backend/access/heap/heapam.c
index 6bff0032db2..efcde4e8094 100644
--- a/src/backend/access/heap/heapam.c
+++ b/src/backend/access/heap/heapam.c
@@ -2138,9 +2138,9 @@ ReleaseBulkInsertStatePin(BulkInsertState bistate)
* See table_tuple_insert for comments about most of the input flags, except
* that this routine directly takes a tuple rather than a slot.
*
- * There's corresponding HEAP_INSERT_ options to all the TABLE_INSERT_
- * options, and there additionally is HEAP_INSERT_SPECULATIVE which is used to
- * implement table_tuple_insert_speculative().
+ * In addition to the TABLE_INSERT_ options, there additionally is
+ * HEAP_INSERT_SPECULATIVE which is used to implement
+ * table_tuple_insert_speculative().
*
* On return the header fields of *tup are updated to match the stored tuple;
* in particular tup->t_self receives the actual TID where the tuple was
@@ -2228,7 +2228,7 @@ heap_insert(Relation relation, HeapTuple tup, CommandId cid,
* Don't set it if we are in bootstrap mode or we are inserting a frozen
* tuple, as there is no further pruning/freezing needed in those cases.
*/
- if (TransactionIdIsNormal(xid) && !(options & HEAP_INSERT_FROZEN))
+ if (TransactionIdIsNormal(xid) && !(options & TABLE_INSERT_FROZEN))
PageSetPrunable(page, xid);
MarkBufferDirty(buffer);
@@ -2275,7 +2275,7 @@ heap_insert(Relation relation, HeapTuple tup, CommandId cid,
* image. (XXX We could alternatively store a pointer into the FPW).
*/
if (RelationIsLogicallyLogged(relation) &&
- !(options & HEAP_INSERT_NO_LOGICAL))
+ !(options & TABLE_INSERT_NO_LOGICAL))
{
xlrec.flags |= XLH_INSERT_CONTAINS_NEW_TUPLE;
bufflags |= REGBUF_KEEP_DATA;
@@ -2364,7 +2364,7 @@ heap_prepare_insert(Relation relation, HeapTuple tup, TransactionId xid,
tup->t_data->t_infomask2 &= ~(HEAP2_XACT_MASK);
tup->t_data->t_infomask |= HEAP_XMAX_INVALID;
HeapTupleHeaderSetXmin(tup->t_data, xid);
- if (options & HEAP_INSERT_FROZEN)
+ if (options & TABLE_INSERT_FROZEN)
HeapTupleHeaderSetXminFrozen(tup->t_data);
HeapTupleHeaderSetCmin(tup->t_data, cid);
@@ -2445,7 +2445,7 @@ heap_multi_insert(Relation relation, TupleTableSlot **slots, int ntuples,
int npages_used = 0;
/* currently not needed (thus unsupported) for heap_multi_insert() */
- Assert(!(options & HEAP_INSERT_NO_LOGICAL));
+ Assert(!(options & TABLE_INSERT_NO_LOGICAL));
AssertHasSnapshotForToast(relation);
@@ -2535,7 +2535,7 @@ heap_multi_insert(Relation relation, TupleTableSlot **slots, int ntuples,
starting_with_empty_page = PageGetMaxOffsetNumber(page) == 0;
- if (starting_with_empty_page && (options & HEAP_INSERT_FROZEN))
+ if (starting_with_empty_page && (options & TABLE_INSERT_FROZEN))
{
all_frozen_set = true;
/* Lock the vmbuffer before entering the critical section */
@@ -2583,7 +2583,7 @@ heap_multi_insert(Relation relation, TupleTableSlot **slots, int ntuples,
* page, mark it as all-frozen and update the visibility map. We're
* already holding a pin on the vmbuffer.
*/
- if (PageIsAllVisible(page) && !(options & HEAP_INSERT_FROZEN))
+ if (PageIsAllVisible(page) && !(options & TABLE_INSERT_FROZEN))
{
all_visible_cleared = true;
PageClearAllVisible(page);
@@ -2655,7 +2655,7 @@ heap_multi_insert(Relation relation, TupleTableSlot **slots, int ntuples,
/*
* We don't have to worry about including a conflict xid in the
- * WAL record, as HEAP_INSERT_FROZEN intentionally violates
+ * WAL record, as TABLE_INSERT_FROZEN intentionally violates
* visibility rules.
*/
if (all_frozen_set)
diff --git a/src/backend/access/heap/hio.c b/src/backend/access/heap/hio.c
index e96e0f77d92..17f87f693ea 100644
--- a/src/backend/access/heap/hio.c
+++ b/src/backend/access/heap/hio.c
@@ -469,12 +469,12 @@ RelationAddBlocks(Relation relation, BulkInsertState bistate,
* which is indicated by these arguments not being InvalidBuffer on entry.
*
* We normally use FSM to help us find free space. However,
- * if HEAP_INSERT_SKIP_FSM is specified, we just append a new empty page to
+ * if TABLE_INSERT_SKIP_FSM is specified, we just append a new empty page to
* the end of the relation if the tuple won't fit on the current target page.
* This can save some cycles when we know the relation is new and doesn't
* contain useful amounts of free space.
*
- * HEAP_INSERT_SKIP_FSM is also useful for non-WAL-logged additions to a
+ * TABLE_INSERT_SKIP_FSM is also useful for non-WAL-logged additions to a
* relation, if the caller holds exclusive lock and is careful to invalidate
* relation's smgr_targblock before the first insertion --- that ensures that
* all insertions will occur into newly added pages and not be intermixed
@@ -503,7 +503,7 @@ RelationGetBufferForTuple(Relation relation, Size len,
Buffer *vmbuffer, Buffer *vmbuffer_other,
int num_pages)
{
- bool use_fsm = !(options & HEAP_INSERT_SKIP_FSM);
+ bool use_fsm = !(options & TABLE_INSERT_SKIP_FSM);
Buffer buffer = InvalidBuffer;
Page page;
Size nearlyEmptyFreeSpace,
@@ -621,7 +621,7 @@ loop:
/*
* If the page is empty, pin vmbuffer to set all_frozen bit later.
*/
- if ((options & HEAP_INSERT_FROZEN) &&
+ if ((options & TABLE_INSERT_FROZEN) &&
(PageGetMaxOffsetNumber(BufferGetPage(buffer)) == 0))
visibilitymap_pin(relation, targetBlock, vmbuffer);
@@ -774,7 +774,7 @@ loop:
* do IO while the buffer is locked, so we unlock the page first if IO is
* needed (necessitating checks below).
*/
- if (options & HEAP_INSERT_FROZEN)
+ if (options & TABLE_INSERT_FROZEN)
{
Assert(PageGetMaxOffsetNumber(page) == 0);
diff --git a/src/backend/access/heap/rewriteheap.c b/src/backend/access/heap/rewriteheap.c
index f707b102c72..ce4f41672f9 100644
--- a/src/backend/access/heap/rewriteheap.c
+++ b/src/backend/access/heap/rewriteheap.c
@@ -618,14 +618,14 @@ raw_heap_insert(RewriteState state, HeapTuple tup)
}
else if (HeapTupleHasExternal(tup) || tup->t_len > TOAST_TUPLE_THRESHOLD)
{
- uint32 options = HEAP_INSERT_SKIP_FSM;
+ uint32 options = TABLE_INSERT_SKIP_FSM;
/*
* While rewriting the heap for VACUUM FULL / CLUSTER, make sure data
* for the TOAST table are not logically decoded. The main heap is
* WAL-logged as XLOG FPI records, which are not logically decoded.
*/
- options |= HEAP_INSERT_NO_LOGICAL;
+ options |= TABLE_INSERT_NO_LOGICAL;
heaptup = heap_toast_insert_or_update(state->rs_new_rel, tup, NULL,
options);
diff --git a/src/backend/replication/logical/decode.c b/src/backend/replication/logical/decode.c
index 3c027bcb2f7..d80a26ce88e 100644
--- a/src/backend/replication/logical/decode.c
+++ b/src/backend/replication/logical/decode.c
@@ -898,7 +898,7 @@ DecodeInsert(LogicalDecodingContext *ctx, XLogRecordBuffer *buf)
/*
* Ignore insert records without new tuples (this does happen when
- * raw_heap_insert marks the TOAST record as HEAP_INSERT_NO_LOGICAL).
+ * raw_heap_insert marks the TOAST record as TABLE_INSERT_NO_LOGICAL).
*/
if (!(xlrec->flags & XLH_INSERT_CONTAINS_NEW_TUPLE))
return;
diff --git a/src/include/access/heapam.h b/src/include/access/heapam.h
index 54067b828e4..20e952ec64f 100644
--- a/src/include/access/heapam.h
+++ b/src/include/access/heapam.h
@@ -32,11 +32,12 @@
#include "utils/snapshot.h"
-/* "options" flag bits for heap_insert */
-#define HEAP_INSERT_SKIP_FSM TABLE_INSERT_SKIP_FSM
-#define HEAP_INSERT_FROZEN TABLE_INSERT_FROZEN
-#define HEAP_INSERT_NO_LOGICAL TABLE_INSERT_NO_LOGICAL
-#define HEAP_INSERT_SPECULATIVE 0x0010
+/*
+ * "options" flag bits for heap_insert. That routine also obeys bits defined
+ * for table_tuple_insert; see tableam.h. We define these starting from the
+ * opposite end of the options word.
+ */
+#define HEAP_INSERT_SPECULATIVE (1 << 31)
/* "options" flag bits for heap_page_prune_and_freeze */
#define HEAP_PAGE_PRUNE_MARK_UNUSED_NOW (1 << 0)
--
2.47.3
view thread (17+ messages) latest in thread
Message-ID: <202604011417.bwthhrwmivd4@alvherre.pgsql>
Permalink: ../202604011417.bwthhrwmivd4@alvherre.pgsql/
Also on: postgresql.org/message-id/202604011417.bwthhrwmivd4@alvherre.pgsql
reply
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Reply to all the recipients using the --to and --cc options:
reply via email
To: pgsql-hackers@postgresql.org
Cc: alvherre@kurilemu.de, li.evan.chao@gmail.com, andres@anarazel.de, pgsql-hackers@lists.postgresql.org, zsolt.parragi@percona.com, nathandbossart@gmail.com
Subject: Re: table AM option passing
In-Reply-To: <202604011417.bwthhrwmivd4@alvherre.pgsql>
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
This inbox is served by agora; see mirroring instructions
for how to clone and mirror all data and code used for this inbox