@@ -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