nbtree: Rename BT_RESERVED_OFFSET_MASK.
authorPeter Geoghegan <pg@bowt.ie>
Wed, 22 Apr 2020 23:09:55 +0000 (16:09 -0700)
committerPeter Geoghegan <pg@bowt.ie>
Wed, 22 Apr 2020 23:09:55 +0000 (16:09 -0700)
The mask was added by commit 8224de4f, which introduced INCLUDE nbtree
indexes.  The status bits really were reserved initially.  We now use 2
out of 4 of the bits for additional tuple metadata, though.  Rename the
mask to BT_STATUS_OFFSET_MASK.

Also consolidate related nbtree.h code comments about the format of
pivot tuples and posting list tuples.

src/include/access/nbtree.h

index 072a41ef8bfeb27c2eaa5c20e8f8ddb78ca26a7f..9a3acd26b7ef520c25790a1ca4b51c9889ec138d 100644 (file)
@@ -282,7 +282,7 @@ typedef struct BTMetaPageData
  *
  * We store the number of columns present inside pivot tuples by abusing
  * their t_tid offset field, since pivot tuples never need to store a real
- * offset (downlinks only need to store a block number in t_tid).  The
+ * offset (pivot tuples generally store a downlink in t_tid, though).  The
  * offset field only stores the number of columns/attributes when the
  * INDEX_ALT_TID_MASK bit is set, which doesn't count the trailing heap
  * TID column sometimes stored in pivot tuples -- that's represented by
@@ -290,21 +290,19 @@ typedef struct BTMetaPageData
  * t_info is always set on BTREE_VERSION 4 pivot tuples, since
  * BTreeTupleIsPivot() must work reliably on heapkeyspace versions.
  *
- * In version 3 indexes, the INDEX_ALT_TID_MASK flag might not be set in
- * pivot tuples.  In that case, the number of key columns is implicitly
- * the same as the number of key columns in the index.  It is not usually
- * set on version 2 indexes, which predate the introduction of INCLUDE
- * indexes.  (Only explicitly truncated pivot tuples explicitly represent
- * the number of key columns on versions 2 and 3, whereas all pivot tuples
- * are formed using truncation on version 4.  A version 2 index will have
- * it set for an internal page negative infinity item iff internal page
- * split occurred after upgrade to Postgres 11+.)
+ * In version 2 or version 3 (!heapkeyspace) indexes, INDEX_ALT_TID_MASK
+ * might not be set in pivot tuples.  BTreeTupleIsPivot() won't work
+ * reliably as a result.  The number of columns stored is implicitly the
+ * same as the number of columns in the index, just like any non-pivot
+ * tuple. (The number of columns stored should not vary, since suffix
+ * truncation of key columns is unsafe within any !heapkeyspace index.)
  *
- * The 12 least significant offset bits from t_tid are used to represent
- * the number of columns in INDEX_ALT_TID_MASK tuples, leaving 4 status
- * bits (BT_RESERVED_OFFSET_MASK bits), 3 of which that are reserved for
- * future use.  BT_OFFSET_MASK should be large enough to store any number
- * of columns/attributes <= INDEX_MAX_KEYS.
+ * The 12 least significant bits from t_tid's offset number are used to
+ * represent the number of key columns within a pivot tuple.  This leaves 4
+ * status bits (BT_STATUS_OFFSET_MASK bits), which are shared by all tuples
+ * that have the INDEX_ALT_TID_MASK bit set (set in t_info) to store basic
+ * tuple metadata.  BTreeTupleIsPivot() and BTreeTupleIsPosting() use the
+ * BT_STATUS_OFFSET_MASK bits.
  *
  * Sometimes non-pivot tuples also use a representation that repurposes
  * t_tid to store metadata rather than a TID.  PostgreSQL v13 introduced a
@@ -321,31 +319,24 @@ typedef struct BTMetaPageData
  *
  * Posting list tuples are recognized as such by having the
  * INDEX_ALT_TID_MASK status bit set in t_info and the BT_IS_POSTING status
- * bit set in t_tid.  These flags redefine the content of the posting
- * tuple's t_tid to store an offset to the posting list, as well as the
- * total number of posting list array elements.
+ * bit set in t_tid's offset number.  These flags redefine the content of
+ * the posting tuple's t_tid to store the location of the posting list
+ * (instead of a block number), as well as the total number of heap TIDs
+ * present in the tuple (instead of a real offset number).
  *
- * The 12 least significant offset bits from t_tid are used to represent
- * the number of posting items present in the tuple, leaving 4 status
- * bits (BT_RESERVED_OFFSET_MASK bits), 3 of which that are reserved for
- * future use.  Like any non-pivot tuple, the number of columns stored is
- * always implicitly the total number in the index (in practice there can
- * never be non-key columns stored, since deduplication is not supported
- * with INCLUDE indexes).  BT_OFFSET_MASK should be large enough to store
- * any number of posting list TIDs that might be present in a tuple (since
- * tuple size is subject to the INDEX_SIZE_MASK limit).
- *
- * Note well: The macros that deal with the number of attributes in tuples
- * assume that a tuple with INDEX_ALT_TID_MASK set must be a pivot tuple or
- * non-pivot posting tuple, and that a tuple without INDEX_ALT_TID_MASK set
- * must be a non-pivot tuple (or must have the same number of attributes as
- * the index has generally in the case of !heapkeyspace indexes).
+ * The 12 least significant bits from t_tid's offset number are used to
+ * represent the number of heap TIDs present in the tuple, leaving 4 status
+ * bits (the BT_STATUS_OFFSET_MASK bits).  Like any non-pivot tuple, the
+ * number of columns stored is always implicitly the total number in the
+ * index (in practice there can never be non-key columns stored, since
+ * deduplication is not supported with INCLUDE indexes).
  */
 #define INDEX_ALT_TID_MASK         INDEX_AM_RESERVED_BIT
 
-/* Item pointer offset bits */
-#define BT_RESERVED_OFFSET_MASK        0xF000
+/* Item pointer offset bit masks */
 #define BT_OFFSET_MASK             0x0FFF
+#define BT_STATUS_OFFSET_MASK      0xF000
+/* BT_STATUS_OFFSET_MASK status bits */
 #define BT_PIVOT_HEAP_TID_ATTR     0x1000
 #define BT_IS_POSTING              0x2000
 
@@ -378,11 +369,13 @@ BTreeTupleIsPosting(IndexTuple itup)
 }
 
 static inline void
-BTreeTupleSetPosting(IndexTuple itup, int nhtids, int postingoffset)
+BTreeTupleSetPosting(IndexTuple itup, uint16 nhtids, int postingoffset)
 {
-   Assert(nhtids > 1 && (nhtids & BT_OFFSET_MASK) == nhtids);
+   Assert(nhtids > 1);
+   Assert((nhtids & BT_STATUS_OFFSET_MASK) == 0);
    Assert((size_t) postingoffset == MAXALIGN(postingoffset));
    Assert(postingoffset < INDEX_SIZE_MASK);
+   Assert(!BTreeTupleIsPivot(itup));
 
    itup->t_info |= INDEX_ALT_TID_MASK;
    ItemPointerSetOffsetNumber(&itup->t_tid, (nhtids | BT_IS_POSTING));
@@ -470,7 +463,7 @@ static inline void
 BTreeTupleSetNAtts(IndexTuple itup, uint16 nkeyatts, bool heaptid)
 {
    Assert(nkeyatts <= INDEX_MAX_KEYS);
-   Assert((nkeyatts & BT_RESERVED_OFFSET_MASK) == 0);
+   Assert((nkeyatts & BT_STATUS_OFFSET_MASK) == 0);
    Assert(!heaptid || nkeyatts > 0);
    Assert(!BTreeTupleIsPivot(itup) || nkeyatts == 0);