From 13454a9ccd82ff10e8cc7ce7637b843810aa16d3 Mon Sep 17 00:00:00 2001
From: Alexander Korotkov <akorotkov@postgresql.org>
Date: Wed, 7 Jun 2023 13:47:53 +0300
Subject: [PATCH 04/12] Add table AM tuple_is_current method

This allows to abstract how/whether table AM uses transaction identifiers.
---
 src/backend/access/heap/heapam_handler.c | 14 ++++++++++++++
 src/backend/access/table/tableamapi.c    |  2 ++
 src/backend/utils/adt/ri_triggers.c      |  8 +-------
 src/include/access/tableam.h             | 14 ++++++++++++++
 4 files changed, 31 insertions(+), 7 deletions(-)

diff --git a/src/backend/access/heap/heapam_handler.c b/src/backend/access/heap/heapam_handler.c
index 29cf023b274..2d4c243028a 100644
--- a/src/backend/access/heap/heapam_handler.c
+++ b/src/backend/access/heap/heapam_handler.c
@@ -75,6 +75,19 @@ heapam_slot_callbacks(Relation relation)
 	return &TTSOpsBufferHeapTuple;
 }
 
+static bool
+heapam_tuple_is_current(Relation rel, TupleTableSlot *slot)
+{
+	Datum		xminDatum;
+	TransactionId xmin;
+	bool		isnull;
+
+	xminDatum = slot_getsysattr(slot, MinTransactionIdAttributeNumber, &isnull);
+	Assert(!isnull);
+	xmin = DatumGetTransactionId(xminDatum);
+	return TransactionIdIsCurrentTransactionId(xmin);
+}
+
 
 /* ------------------------------------------------------------------------
  * Index Scan Callbacks for heap AM
@@ -2600,6 +2613,7 @@ static const TableAmRoutine heapam_methods = {
 	.type = T_TableAmRoutine,
 
 	.slot_callbacks = heapam_slot_callbacks,
+	.tuple_is_current = heapam_tuple_is_current,
 
 	.scan_begin = heap_beginscan,
 	.scan_end = heap_endscan,
diff --git a/src/backend/access/table/tableamapi.c b/src/backend/access/table/tableamapi.c
index d7798b6afb6..0d43e9c1a4f 100644
--- a/src/backend/access/table/tableamapi.c
+++ b/src/backend/access/table/tableamapi.c
@@ -49,6 +49,8 @@ GetTableAmRoutine(Oid amhandler)
 	 * easier to keep AMs up to date, e.g. when forward porting them to a new
 	 * major version.
 	 */
+	Assert(routine->tuple_is_current != NULL);
+
 	Assert(routine->scan_begin != NULL);
 	Assert(routine->scan_end != NULL);
 	Assert(routine->scan_rescan != NULL);
diff --git a/src/backend/utils/adt/ri_triggers.c b/src/backend/utils/adt/ri_triggers.c
index 6945d99b3d5..0412cfac431 100644
--- a/src/backend/utils/adt/ri_triggers.c
+++ b/src/backend/utils/adt/ri_triggers.c
@@ -1263,9 +1263,6 @@ RI_FKey_fk_upd_check_required(Trigger *trigger, Relation fk_rel,
 {
 	const RI_ConstraintInfo *riinfo;
 	int			ri_nullcheck;
-	Datum		xminDatum;
-	TransactionId xmin;
-	bool		isnull;
 
 	/*
 	 * AfterTriggerSaveEvent() handles things such that this function is never
@@ -1333,10 +1330,7 @@ RI_FKey_fk_upd_check_required(Trigger *trigger, Relation fk_rel,
 	 * this if we knew the INSERT trigger already fired, but there is no easy
 	 * way to know that.)
 	 */
-	xminDatum = slot_getsysattr(oldslot, MinTransactionIdAttributeNumber, &isnull);
-	Assert(!isnull);
-	xmin = DatumGetTransactionId(xminDatum);
-	if (TransactionIdIsCurrentTransactionId(xmin))
+	if (table_tuple_is_current(fk_rel, oldslot))
 		return true;
 
 	/* If all old and new key values are equal, no check is needed */
diff --git a/src/include/access/tableam.h b/src/include/access/tableam.h
index d5972d7a580..8f9caf3f3c3 100644
--- a/src/include/access/tableam.h
+++ b/src/include/access/tableam.h
@@ -300,6 +300,11 @@ typedef struct TableAmRoutine
 	 */
 	const TupleTableSlotOps *(*slot_callbacks) (Relation rel);
 
+	/*
+	 * Check if tuple in the slot belongs to the current transaction.
+	 */
+	bool		(*tuple_is_current) (Relation rel, TupleTableSlot *slot);
+
 
 	/* ------------------------------------------------------------------------
 	 * Table scan callbacks.
@@ -901,6 +906,15 @@ extern const TupleTableSlotOps *table_slot_callbacks(Relation relation);
  */
 extern TupleTableSlot *table_slot_create(Relation relation, List **reglist);
 
+/*
+ * Check if tuple in the slot belongs to the current transaction.
+ */
+static inline bool
+table_tuple_is_current(Relation rel, TupleTableSlot *slot)
+{
+	return rel->rd_tableam->tuple_is_current(rel, slot);
+}
+
 
 /* ----------------------------------------------------------------------------
  * Table scan functions.
-- 
2.39.3 (Apple Git-145)

