diff --git a/src/backend/access/nbtree/nbtinsert.c b/src/backend/access/nbtree/nbtinsert.c index 1675298f73..cbd4ec3b39 100644 --- a/src/backend/access/nbtree/nbtinsert.c +++ b/src/backend/access/nbtree/nbtinsert.c @@ -2413,7 +2413,7 @@ _bt_newroot(Relation rel, Buffer lbuf, Buffer rbuf) left_item = (IndexTuple) palloc(left_item_sz); left_item->t_info = left_item_sz; BTreeTupleSetDownLink(left_item, lbkno); - BTreeTupleSetNAtts(left_item, 0); + BTreeTupleSetNAtts(left_item, 0, false); /* * Create downlink item for right page. The key for it is obtained from @@ -2571,7 +2571,7 @@ _bt_pgaddtup(Page page, { trunctuple = *itup; trunctuple.t_info = sizeof(IndexTupleData); - BTreeTupleSetNAtts(&trunctuple, 0); + BTreeTupleSetNAtts(&trunctuple, 0, false); itup = &trunctuple; itemsize = sizeof(IndexTupleData); } diff --git a/src/backend/access/nbtree/nbtsort.c b/src/backend/access/nbtree/nbtsort.c index 29a6f5ade6..9d249f7a6b 100644 --- a/src/backend/access/nbtree/nbtsort.c +++ b/src/backend/access/nbtree/nbtsort.c @@ -771,7 +771,7 @@ _bt_sortaddtup(Page page, { trunctuple = *itup; trunctuple.t_info = sizeof(IndexTupleData); - BTreeTupleSetNAtts(&trunctuple, 0); + BTreeTupleSetNAtts(&trunctuple, 0, false); itup = &trunctuple; itemsize = sizeof(IndexTupleData); } @@ -1045,7 +1045,7 @@ _bt_buildadd(BTWriteState *wstate, BTPageState *state, IndexTuple itup, Assert(state->btps_lowkey == NULL); state->btps_lowkey = palloc0(sizeof(IndexTupleData)); state->btps_lowkey->t_info = sizeof(IndexTupleData); - BTreeTupleSetNAtts(state->btps_lowkey, 0); + BTreeTupleSetNAtts(state->btps_lowkey, 0, false); } /* diff --git a/src/backend/access/nbtree/nbtutils.c b/src/backend/access/nbtree/nbtutils.c index 86cec24859..08d7201f19 100644 --- a/src/backend/access/nbtree/nbtutils.c +++ b/src/backend/access/nbtree/nbtutils.c @@ -2239,7 +2239,7 @@ _bt_truncate(Relation rel, IndexTuple lastleft, IndexTuple firstright, */ if (keepnatts <= nkeyatts) { - BTreeTupleSetNAtts(pivot, keepnatts); + BTreeTupleSetNAtts(pivot, keepnatts, false); return pivot; } @@ -2262,11 +2262,13 @@ _bt_truncate(Relation rel, IndexTuple lastleft, IndexTuple firstright, /* Cannot leak memory here */ pfree(pivot); - /* Store heap TID in enlarged pivot tuple */ + /* + * Store all of firstright's key attribute values plus a tiebreaker heap + * TID value in enlarged pivot tuple + */ tidpivot->t_info &= ~INDEX_SIZE_MASK; tidpivot->t_info |= newsize; - BTreeTupleSetNAtts(tidpivot, nkeyatts); - BTreeTupleSetAltHeapTID(tidpivot); + BTreeTupleSetNAtts(tidpivot, nkeyatts, true); pivotheaptid = BTreeTupleGetHeapTID(tidpivot); /* diff --git a/src/include/access/nbtree.h b/src/include/access/nbtree.h index 5f67fc04e0..072a41ef8b 100644 --- a/src/include/access/nbtree.h +++ b/src/include/access/nbtree.h @@ -460,34 +460,30 @@ BTreeTupleSetDownLink(IndexTuple pivot, BlockNumber blkno) ) /* - * Set number of attributes in tuple, making it into a pivot tuple + * Set number of key attributes in tuple. + * + * The heap TID tiebreaker attribute bit may also be set here, indicating that + * a heap TID value will be stored at the end of the tuple (i.e. using the + * special pivot tuple representation). */ static inline void -BTreeTupleSetNAtts(IndexTuple itup, int natts) +BTreeTupleSetNAtts(IndexTuple itup, uint16 nkeyatts, bool heaptid) { - Assert(natts <= INDEX_MAX_KEYS); + Assert(nkeyatts <= INDEX_MAX_KEYS); + Assert((nkeyatts & BT_RESERVED_OFFSET_MASK) == 0); + Assert(!heaptid || nkeyatts > 0); + Assert(!BTreeTupleIsPivot(itup) || nkeyatts == 0); itup->t_info |= INDEX_ALT_TID_MASK; - /* BT_IS_POSTING bit may be unset -- tuple always becomes a pivot tuple */ - ItemPointerSetOffsetNumber(&itup->t_tid, natts); + + if (heaptid) + nkeyatts |= BT_PIVOT_HEAP_TID_ATTR; + + /* BT_IS_POSTING bit is deliberately unset here */ + ItemPointerSetOffsetNumber(&itup->t_tid, nkeyatts); Assert(BTreeTupleIsPivot(itup)); } -/* - * Set the bit indicating heap TID attribute present in pivot tuple - */ -static inline void -BTreeTupleSetAltHeapTID(IndexTuple pivot) -{ - OffsetNumber existing; - - Assert(BTreeTupleIsPivot(pivot)); - - existing = ItemPointerGetOffsetNumberNoCheck(&pivot->t_tid); - ItemPointerSetOffsetNumber(&pivot->t_tid, - existing | BT_PIVOT_HEAP_TID_ATTR); -} - /* * Get/set leaf page's "top parent" link from its high key. Used during page * deletion. @@ -505,7 +501,7 @@ static inline void BTreeTupleSetTopParent(IndexTuple leafhikey, BlockNumber blkno) { ItemPointerSetBlockNumber(&leafhikey->t_tid, blkno); - BTreeTupleSetNAtts(leafhikey, 0); + BTreeTupleSetNAtts(leafhikey, 0, false); } /*