From 13454a9ccd82ff10e8cc7ce7637b843810aa16d3 Mon Sep 17 00:00:00 2001 From: Alexander Korotkov 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)