0002-Move-heap_get_latest_tid-within-the-heap-AM-handler.patch
text/x-diff
Filename: 0002-Move-heap_get_latest_tid-within-the-heap-AM-handler.patch
Type: text/x-diff
Part: 1
Patch
Format: format-patch
Series: patch 0002
Subject: Move heap_get_latest_tid() within the heap AM handler
| File | + | − |
|---|---|---|
| src/backend/access/heap/heapam.c | 0 | 117 |
| src/backend/access/heap/heapam_handler.c | 117 | 0 |
| src/include/access/heapam.h | 0 | 2 |
From 94f29c626633fa05050b702b00ff31c04de55de1 Mon Sep 17 00:00:00 2001
From: Michael Paquier <michael@paquier.xyz>
Date: Wed, 3 Jun 2020 11:01:48 +0900
Subject: [PATCH 2/2] Move heap_get_latest_tid() within the heap AM handler
This routine is not getting called in any code path except through the
table AM interface, so let's make the cut clear.
---
src/include/access/heapam.h | 2 -
src/backend/access/heap/heapam.c | 117 -----------------------
src/backend/access/heap/heapam_handler.c | 117 +++++++++++++++++++++++
3 files changed, 117 insertions(+), 119 deletions(-)
diff --git a/src/include/access/heapam.h b/src/include/access/heapam.h
index 4a5b14f10e..273b8be02e 100644
--- a/src/include/access/heapam.h
+++ b/src/include/access/heapam.h
@@ -128,8 +128,6 @@ extern bool heap_hot_search_buffer(ItemPointer tid, Relation relation,
Buffer buffer, Snapshot snapshot, HeapTuple heapTuple,
bool *all_dead, bool first_call);
-extern void heap_get_latest_tid(TableScanDesc scan, ItemPointer tid);
-
extern BulkInsertState GetBulkInsertState(void);
extern void FreeBulkInsertState(BulkInsertState);
extern void ReleaseBulkInsertStatePin(BulkInsertState bistate);
diff --git a/src/backend/access/heap/heapam.c b/src/backend/access/heap/heapam.c
index 94eb37d48d..e177065e20 100644
--- a/src/backend/access/heap/heapam.c
+++ b/src/backend/access/heap/heapam.c
@@ -1618,123 +1618,6 @@ heap_hot_search_buffer(ItemPointer tid, Relation relation, Buffer buffer,
return false;
}
-/*
- * heap_get_latest_tid - get the latest tid of a specified tuple
- *
- * Actually, this gets the latest version that is visible according to the
- * scan's snapshot. Create a scan using SnapshotDirty to get the very latest,
- * possibly uncommitted version.
- *
- * *tid is both an input and an output parameter: it is updated to
- * show the latest version of the row. Note that it will not be changed
- * if no version of the row passes the snapshot test.
- */
-void
-heap_get_latest_tid(TableScanDesc sscan,
- ItemPointer tid)
-{
- Relation relation = sscan->rs_rd;
- Snapshot snapshot = sscan->rs_snapshot;
- ItemPointerData ctid;
- TransactionId priorXmax;
-
- /*
- * table_get_latest_tid verified that the passed in tid is valid. Assume
- * that t_ctid links are valid however - there shouldn't be invalid ones
- * in the table.
- */
- Assert(ItemPointerIsValid(tid));
-
- /*
- * Loop to chase down t_ctid links. At top of loop, ctid is the tuple we
- * need to examine, and *tid is the TID we will return if ctid turns out
- * to be bogus.
- *
- * Note that we will loop until we reach the end of the t_ctid chain.
- * Depending on the snapshot passed, there might be at most one visible
- * version of the row, but we don't try to optimize for that.
- */
- ctid = *tid;
- priorXmax = InvalidTransactionId; /* cannot check first XMIN */
- for (;;)
- {
- Buffer buffer;
- Page page;
- OffsetNumber offnum;
- ItemId lp;
- HeapTupleData tp;
- bool valid;
-
- /*
- * Read, pin, and lock the page.
- */
- buffer = ReadBuffer(relation, ItemPointerGetBlockNumber(&ctid));
- LockBuffer(buffer, BUFFER_LOCK_SHARE);
- page = BufferGetPage(buffer);
- TestForOldSnapshot(snapshot, relation, page);
-
- /*
- * Check for bogus item number. This is not treated as an error
- * condition because it can happen while following a t_ctid link. We
- * just assume that the prior tid is OK and return it unchanged.
- */
- offnum = ItemPointerGetOffsetNumber(&ctid);
- if (offnum < FirstOffsetNumber || offnum > PageGetMaxOffsetNumber(page))
- {
- UnlockReleaseBuffer(buffer);
- break;
- }
- lp = PageGetItemId(page, offnum);
- if (!ItemIdIsNormal(lp))
- {
- UnlockReleaseBuffer(buffer);
- break;
- }
-
- /* OK to access the tuple */
- tp.t_self = ctid;
- tp.t_data = (HeapTupleHeader) PageGetItem(page, lp);
- tp.t_len = ItemIdGetLength(lp);
- tp.t_tableOid = RelationGetRelid(relation);
-
- /*
- * After following a t_ctid link, we might arrive at an unrelated
- * tuple. Check for XMIN match.
- */
- if (TransactionIdIsValid(priorXmax) &&
- !TransactionIdEquals(priorXmax, HeapTupleHeaderGetXmin(tp.t_data)))
- {
- UnlockReleaseBuffer(buffer);
- break;
- }
-
- /*
- * Check tuple visibility; if visible, set it as the new result
- * candidate.
- */
- valid = HeapTupleSatisfiesVisibility(&tp, snapshot, buffer);
- HeapCheckForSerializableConflictOut(valid, relation, &tp, buffer, snapshot);
- if (valid)
- *tid = ctid;
-
- /*
- * If there's a valid t_ctid link, follow it, else we're done.
- */
- if ((tp.t_data->t_infomask & HEAP_XMAX_INVALID) ||
- HeapTupleHeaderIsOnlyLocked(tp.t_data) ||
- HeapTupleHeaderIndicatesMovedPartitions(tp.t_data) ||
- ItemPointerEquals(&tp.t_self, &tp.t_data->t_ctid))
- {
- UnlockReleaseBuffer(buffer);
- break;
- }
-
- ctid = tp.t_data->t_ctid;
- priorXmax = HeapTupleHeaderGetUpdateXid(tp.t_data);
- UnlockReleaseBuffer(buffer);
- } /* end of loop */
-}
-
/*
* UpdateXmaxHintBits - update tuple hint bits after xmax transaction ends
diff --git a/src/backend/access/heap/heapam_handler.c b/src/backend/access/heap/heapam_handler.c
index 56b35622f1..84d32bc4ff 100644
--- a/src/backend/access/heap/heapam_handler.c
+++ b/src/backend/access/heap/heapam_handler.c
@@ -199,6 +199,123 @@ heapam_fetch_row_version(Relation relation,
return false;
}
+/*
+ * heap_get_latest_tid - get the latest tid of a specified tuple
+ *
+ * Actually, this gets the latest version that is visible according to the
+ * scan's snapshot. Create a scan using SnapshotDirty to get the very latest,
+ * possibly uncommitted version.
+ *
+ * *tid is both an input and an output parameter: it is updated to
+ * show the latest version of the row. Note that it will not be changed
+ * if no version of the row passes the snapshot test.
+ */
+static void
+heap_get_latest_tid(TableScanDesc sscan,
+ ItemPointer tid)
+{
+ Relation relation = sscan->rs_rd;
+ Snapshot snapshot = sscan->rs_snapshot;
+ ItemPointerData ctid;
+ TransactionId priorXmax;
+
+ /*
+ * table_get_latest_tid verified that the passed in tid is valid. Assume
+ * that t_ctid links are valid however - there shouldn't be invalid ones
+ * in the table.
+ */
+ Assert(ItemPointerIsValid(tid));
+
+ /*
+ * Loop to chase down t_ctid links. At top of loop, ctid is the tuple we
+ * need to examine, and *tid is the TID we will return if ctid turns out
+ * to be bogus.
+ *
+ * Note that we will loop until we reach the end of the t_ctid chain.
+ * Depending on the snapshot passed, there might be at most one visible
+ * version of the row, but we don't try to optimize for that.
+ */
+ ctid = *tid;
+ priorXmax = InvalidTransactionId; /* cannot check first XMIN */
+ for (;;)
+ {
+ Buffer buffer;
+ Page page;
+ OffsetNumber offnum;
+ ItemId lp;
+ HeapTupleData tp;
+ bool valid;
+
+ /*
+ * Read, pin, and lock the page.
+ */
+ buffer = ReadBuffer(relation, ItemPointerGetBlockNumber(&ctid));
+ LockBuffer(buffer, BUFFER_LOCK_SHARE);
+ page = BufferGetPage(buffer);
+ TestForOldSnapshot(snapshot, relation, page);
+
+ /*
+ * Check for bogus item number. This is not treated as an error
+ * condition because it can happen while following a t_ctid link. We
+ * just assume that the prior tid is OK and return it unchanged.
+ */
+ offnum = ItemPointerGetOffsetNumber(&ctid);
+ if (offnum < FirstOffsetNumber || offnum > PageGetMaxOffsetNumber(page))
+ {
+ UnlockReleaseBuffer(buffer);
+ break;
+ }
+ lp = PageGetItemId(page, offnum);
+ if (!ItemIdIsNormal(lp))
+ {
+ UnlockReleaseBuffer(buffer);
+ break;
+ }
+
+ /* OK to access the tuple */
+ tp.t_self = ctid;
+ tp.t_data = (HeapTupleHeader) PageGetItem(page, lp);
+ tp.t_len = ItemIdGetLength(lp);
+ tp.t_tableOid = RelationGetRelid(relation);
+
+ /*
+ * After following a t_ctid link, we might arrive at an unrelated
+ * tuple. Check for XMIN match.
+ */
+ if (TransactionIdIsValid(priorXmax) &&
+ !TransactionIdEquals(priorXmax, HeapTupleHeaderGetXmin(tp.t_data)))
+ {
+ UnlockReleaseBuffer(buffer);
+ break;
+ }
+
+ /*
+ * Check tuple visibility; if visible, set it as the new result
+ * candidate.
+ */
+ valid = HeapTupleSatisfiesVisibility(&tp, snapshot, buffer);
+ HeapCheckForSerializableConflictOut(valid, relation, &tp, buffer, snapshot);
+ if (valid)
+ *tid = ctid;
+
+ /*
+ * If there's a valid t_ctid link, follow it, else we're done.
+ */
+ if ((tp.t_data->t_infomask & HEAP_XMAX_INVALID) ||
+ HeapTupleHeaderIsOnlyLocked(tp.t_data) ||
+ HeapTupleHeaderIndicatesMovedPartitions(tp.t_data) ||
+ ItemPointerEquals(&tp.t_self, &tp.t_data->t_ctid))
+ {
+ UnlockReleaseBuffer(buffer);
+ break;
+ }
+
+ ctid = tp.t_data->t_ctid;
+ priorXmax = HeapTupleHeaderGetUpdateXid(tp.t_data);
+ UnlockReleaseBuffer(buffer);
+ } /* end of loop */
+}
+
static bool
heapam_tuple_tid_valid(TableScanDesc scan, ItemPointer tid)
{
--
2.27.0.rc0