Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
Skip to content

Commit 7c2dbc6

Browse files
Refactor nbtree high key truncation.
Simplify _bt_truncate(), the routine that generates truncated leaf page high keys. Remove a micro-optimization that avoided a second palloc0() call (this was used when a heap TID was needed in the final pivot tuple, though only when the index happened to not be an INCLUDE index). Removing this dubious micro-optimization allows _bt_truncate() to use the index_truncate_tuple() indextuple.c utility routine in all cases. This was already the common case. This commit is a HEAD-only follow up to bugfix commit 4b42a89.
1 parent d4b34f6 commit 7c2dbc6

File tree

1 file changed

+45
-85
lines changed

1 file changed

+45
-85
lines changed

src/backend/access/nbtree/nbtutils.c

Lines changed: 45 additions & 85 deletions
Original file line numberDiff line numberDiff line change
@@ -2180,10 +2180,10 @@ _bt_truncate(Relation rel, IndexTuple lastleft, IndexTuple firstright,
21802180
BTScanInsert itup_key)
21812181
{
21822182
TupleDesc itupdesc = RelationGetDescr(rel);
2183-
int16 natts = IndexRelationGetNumberOfAttributes(rel);
21842183
int16 nkeyatts = IndexRelationGetNumberOfKeyAttributes(rel);
21852184
int keepnatts;
21862185
IndexTuple pivot;
2186+
IndexTuple tidpivot;
21872187
ItemPointer pivotheaptid;
21882188
Size newsize;
21892189

@@ -2201,95 +2201,56 @@ _bt_truncate(Relation rel, IndexTuple lastleft, IndexTuple firstright,
22012201
keepnatts = nkeyatts + 1;
22022202
#endif
22032203

2204-
if (keepnatts <= natts)
2205-
{
2206-
IndexTuple tidpivot;
2207-
2208-
pivot = index_truncate_tuple(itupdesc, firstright,
2209-
Min(keepnatts, nkeyatts));
2210-
2211-
if (BTreeTupleIsPosting(pivot))
2212-
{
2213-
/*
2214-
* index_truncate_tuple() just returns a straight copy of
2215-
* firstright when it has no key attributes to truncate. We need
2216-
* to truncate away the posting list ourselves.
2217-
*/
2218-
Assert(keepnatts == nkeyatts);
2219-
Assert(natts == nkeyatts);
2220-
pivot->t_info &= ~INDEX_SIZE_MASK;
2221-
pivot->t_info |= MAXALIGN(BTreeTupleGetPostingOffset(firstright));
2222-
}
2223-
2224-
/*
2225-
* If there is a distinguishing key attribute within new pivot tuple,
2226-
* there is no need to add an explicit heap TID attribute
2227-
*/
2228-
if (keepnatts <= nkeyatts)
2229-
{
2230-
BTreeTupleSetNAtts(pivot, keepnatts);
2231-
return pivot;
2232-
}
2204+
pivot = index_truncate_tuple(itupdesc, firstright,
2205+
Min(keepnatts, nkeyatts));
22332206

2234-
/*
2235-
* Only truncation of non-key attributes was possible, since key
2236-
* attributes are all equal. It's necessary to add a heap TID
2237-
* attribute to the new pivot tuple.
2238-
*/
2239-
Assert(natts != nkeyatts);
2240-
Assert(!BTreeTupleIsPosting(lastleft) &&
2241-
!BTreeTupleIsPosting(firstright));
2242-
newsize = IndexTupleSize(pivot) + MAXALIGN(sizeof(ItemPointerData));
2243-
tidpivot = palloc0(newsize);
2244-
memcpy(tidpivot, pivot, IndexTupleSize(pivot));
2245-
/* cannot leak memory here */
2246-
pfree(pivot);
2247-
pivot = tidpivot;
2248-
}
2249-
else
2207+
if (BTreeTupleIsPosting(pivot))
22502208
{
22512209
/*
2252-
* No truncation was possible, since key attributes are all equal.
2253-
* It's necessary to add a heap TID attribute to the new pivot tuple.
2254-
*
2255-
* This path is only taken when rel is not an INCLUDE index. It
2256-
* avoids a second palloc0() by avoiding the index_truncate_tuple()
2257-
* call completely.
2210+
* index_truncate_tuple() just returns a straight copy of firstright
2211+
* when it has no attributes to truncate. When that happens, we may
2212+
* need to truncate away a posting list here instead.
22582213
*/
2259-
Assert(natts == nkeyatts);
2260-
newsize = IndexTupleSize(firstright) + MAXALIGN(sizeof(ItemPointerData));
2261-
pivot = palloc0(newsize);
2262-
memcpy(pivot, firstright, IndexTupleSize(firstright));
2214+
Assert(keepnatts == nkeyatts || keepnatts == nkeyatts + 1);
2215+
Assert(IndexRelationGetNumberOfAttributes(rel) == nkeyatts);
2216+
pivot->t_info &= ~INDEX_SIZE_MASK;
2217+
pivot->t_info |= MAXALIGN(BTreeTupleGetPostingOffset(firstright));
2218+
}
22632219

2264-
if (BTreeTupleIsPosting(firstright))
2265-
{
2266-
/*
2267-
* New pivot tuple was copied from firstright, which happens to be
2268-
* a posting list tuple. We will have to include the max lastleft
2269-
* heap TID in the final pivot tuple, but we can remove the
2270-
* posting list now. (Pivot tuples should never contain a posting
2271-
* list.)
2272-
*/
2273-
newsize = MAXALIGN(BTreeTupleGetPostingOffset(firstright)) +
2274-
MAXALIGN(sizeof(ItemPointerData));
2275-
}
2220+
/*
2221+
* If there is a distinguishing key attribute within pivot tuple, we're
2222+
* done
2223+
*/
2224+
if (keepnatts <= nkeyatts)
2225+
{
2226+
BTreeTupleSetNAtts(pivot, keepnatts);
2227+
return pivot;
22762228
}
22772229

22782230
/*
2279-
* We have to use heap TID as a unique-ifier in the new pivot tuple, since
2280-
* no non-TID key attribute in the right item readily distinguishes the
2281-
* right side of the split from the left side. Use enlarged space that
2282-
* holds a copy of first right tuple; place a heap TID value within the
2283-
* extra space that remains at the end.
2231+
* We have to store a heap TID in the new pivot tuple, since no non-TID
2232+
* key attribute value in firstright distinguishes the right side of the
2233+
* split from the left side. nbtree conceptualizes this case as an
2234+
* inability to truncate away any key attributes, since heap TID is
2235+
* treated as just another key attribute (despite lacking a pg_attribute
2236+
* entry).
22842237
*
2285-
* nbtree conceptualizes this case as an inability to truncate away any
2286-
* key attribute. We must use an alternative representation of heap TID
2287-
* within pivots because heap TID is only treated as an attribute within
2288-
* nbtree (e.g., there is no pg_attribute entry).
2238+
* Use enlarged space that holds a copy of pivot. We need the extra space
2239+
* to store a heap TID at the end (using the special pivot tuple
2240+
* representation). Note that the original pivot already has firstright's
2241+
* possible posting list/non-key attribute values removed at this point.
22892242
*/
2290-
Assert(itup_key->heapkeyspace);
2291-
pivot->t_info &= ~INDEX_SIZE_MASK;
2292-
pivot->t_info |= newsize;
2243+
newsize = MAXALIGN(IndexTupleSize(pivot)) + MAXALIGN(sizeof(ItemPointerData));
2244+
tidpivot = palloc0(newsize);
2245+
memcpy(tidpivot, pivot, MAXALIGN(IndexTupleSize(pivot)));
2246+
/* Cannot leak memory here */
2247+
pfree(pivot);
2248+
2249+
/* Store heap TID in enlarged pivot tuple */
2250+
tidpivot->t_info &= ~INDEX_SIZE_MASK;
2251+
tidpivot->t_info |= newsize;
2252+
BTreeTupleSetNAtts(tidpivot, nkeyatts);
2253+
BTreeTupleSetAltHeapTID(tidpivot);
22932254

22942255
/*
22952256
* Lehman & Yao use lastleft as the leaf high key in all cases, but don't
@@ -2298,11 +2259,13 @@ _bt_truncate(Relation rel, IndexTuple lastleft, IndexTuple firstright,
22982259
* TID. (This is also the closest value to negative infinity that's
22992260
* legally usable.)
23002261
*/
2301-
pivotheaptid = (ItemPointer) ((char *) pivot + newsize -
2262+
pivotheaptid = (ItemPointer) ((char *) tidpivot + newsize -
23022263
sizeof(ItemPointerData));
23032264
ItemPointerCopy(BTreeTupleGetMaxHeapTID(lastleft), pivotheaptid);
23042265

23052266
/*
2267+
* We're done. Assert() that heap TID invariants hold before returning.
2268+
*
23062269
* Lehman and Yao require that the downlink to the right page, which is to
23072270
* be inserted into the parent page in the second phase of a page split be
23082271
* a strict lower bound on items on the right page, and a non-strict upper
@@ -2342,10 +2305,7 @@ _bt_truncate(Relation rel, IndexTuple lastleft, IndexTuple firstright,
23422305
BTreeTupleGetHeapTID(firstright)) < 0);
23432306
#endif
23442307

2345-
BTreeTupleSetNAtts(pivot, nkeyatts);
2346-
BTreeTupleSetAltHeapTID(pivot);
2347-
2348-
return pivot;
2308+
return tidpivot;
23492309
}
23502310

23512311
/*

0 commit comments

Comments
 (0)