aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/include/access/htup_details.h29
-rw-r--r--src/include/storage/itemptr.h29
2 files changed, 39 insertions, 19 deletions
diff --git a/src/include/access/htup_details.h b/src/include/access/htup_details.h
index cf56d4ace43..1867a70f6f3 100644
--- a/src/include/access/htup_details.h
+++ b/src/include/access/htup_details.h
@@ -83,13 +83,15 @@
*
* A word about t_ctid: whenever a new tuple is stored on disk, its t_ctid
* is initialized with its own TID (location). If the tuple is ever updated,
- * its t_ctid is changed to point to the replacement version of the tuple or
- * the block number (ip_blkid) is invalidated if the tuple is moved from one
- * partition to another partition relation due to an update of the partition
- * key. Thus, a tuple is the latest version of its row iff XMAX is invalid or
+ * its t_ctid is changed to point to the replacement version of the tuple. Or
+ * if the tuple is moved from one partition to another, due to an update of
+ * the partition key, t_ctid is set to a special value to indicate that
+ * (see ItemPointerSetMovedPartitions). Thus, a tuple is the latest version
+ * of its row iff XMAX is invalid or
* t_ctid points to itself (in which case, if XMAX is valid, the tuple is
* either locked or deleted). One can follow the chain of t_ctid links
- * to find the newest version of the row. Beware however that VACUUM might
+ * to find the newest version of the row, unless it was moved to a different
+ * partition. Beware however that VACUUM might
* erase the pointed-to (newer) tuple before erasing the pointing (older)
* tuple. Hence, when following a t_ctid link, it is necessary to check
* to see if the referenced slot is empty or contains an unrelated tuple.
@@ -288,14 +290,6 @@ struct HeapTupleHeaderData
#define HEAP_TUPLE_HAS_MATCH HEAP_ONLY_TUPLE /* tuple has a join match */
/*
- * Special value used in t_ctid.ip_posid, to indicate that it holds a
- * speculative insertion token rather than a real TID. This must be higher
- * than MaxOffsetNumber, so that it can be distinguished from a valid
- * offset number in a regular item pointer.
- */
-#define SpecTokenOffsetNumber 0xfffe
-
-/*
* HeapTupleHeader accessor macros
*
* Note: beware of multiple evaluations of "tup" argument. But the Set
@@ -447,11 +441,12 @@ do { \
ItemPointerSet(&(tup)->t_ctid, token, SpecTokenOffsetNumber) \
)
-#define HeapTupleHeaderSetMovedPartitions(tup) \
- ItemPointerSetMovedPartitions(&(tup)->t_ctid)
-
#define HeapTupleHeaderIndicatesMovedPartitions(tup) \
- ItemPointerIndicatesMovedPartitions(&tup->t_ctid)
+ (ItemPointerGetOffsetNumber(&(tup)->t_ctid) == MovedPartitionsOffsetNumber && \
+ ItemPointerGetBlockNumberNoCheck(&(tup)->t_ctid) == MovedPartitionsBlockNumber)
+
+#define HeapTupleHeaderSetMovedPartitions(tup) \
+ ItemPointerSet(&(tup)->t_ctid, MovedPartitionsBlockNumber, MovedPartitionsOffsetNumber)
#define HeapTupleHeaderGetDatumLength(tup) \
VARSIZE(tup)
diff --git a/src/include/storage/itemptr.h b/src/include/storage/itemptr.h
index 626c98f9691..d87101f2701 100644
--- a/src/include/storage/itemptr.h
+++ b/src/include/storage/itemptr.h
@@ -49,6 +49,28 @@ ItemPointerData;
typedef ItemPointerData *ItemPointer;
/* ----------------
+ * special values used in heap tuples (t_ctid)
+ * ----------------
+ */
+
+/*
+ * If a heap tuple holds a speculative insertion token rather than a real
+ * TID, ip_posid is set to SpecTokenOffsetNumber, and the token is stored in
+ * ip_blkid. SpecTokenOffsetNumber must be higher than MaxOffsetNumber, so
+ * that it can be distinguished from a valid offset number in a regular item
+ * pointer.
+ */
+#define SpecTokenOffsetNumber 0xfffe
+
+/*
+ * When a tuple is moved to a different partition by UPDATE, the t_ctid of
+ * the old tuple version is set to this magic value.
+ */
+#define MovedPartitionsOffsetNumber 0xfffd
+#define MovedPartitionsBlockNumber InvalidBlockNumber
+
+
+/* ----------------
* support macros
* ----------------
*/
@@ -160,7 +182,10 @@ typedef ItemPointerData *ItemPointer;
* partition.
*/
#define ItemPointerIndicatesMovedPartitions(pointer) \
- !BlockNumberIsValid(ItemPointerGetBlockNumberNoCheck(pointer))
+( \
+ ItemPointerGetOffsetNumber(pointer) == MovedPartitionsOffsetNumber && \
+ ItemPointerGetBlockNumberNoCheck(pointer) == MovedPartitionsBlockNumber \
+)
/*
* ItemPointerSetMovedPartitions
@@ -168,7 +193,7 @@ typedef ItemPointerData *ItemPointer;
* different partition.
*/
#define ItemPointerSetMovedPartitions(pointer) \
- ItemPointerSetBlockNumber((pointer), InvalidBlockNumber)
+ ItemPointerSet((pointer), MovedPartitionsBlockNumber, MovedPartitionsOffsetNumber)
/* ----------------
* externs