@@ -2180,10 +2180,10 @@ _bt_truncate(Relation rel, IndexTuple lastleft, IndexTuple firstright,
2180
2180
BTScanInsert itup_key )
2181
2181
{
2182
2182
TupleDesc itupdesc = RelationGetDescr (rel );
2183
- int16 natts = IndexRelationGetNumberOfAttributes (rel );
2184
2183
int16 nkeyatts = IndexRelationGetNumberOfKeyAttributes (rel );
2185
2184
int keepnatts ;
2186
2185
IndexTuple pivot ;
2186
+ IndexTuple tidpivot ;
2187
2187
ItemPointer pivotheaptid ;
2188
2188
Size newsize ;
2189
2189
@@ -2201,95 +2201,56 @@ _bt_truncate(Relation rel, IndexTuple lastleft, IndexTuple firstright,
2201
2201
keepnatts = nkeyatts + 1 ;
2202
2202
#endif
2203
2203
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 ));
2233
2206
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 ))
2250
2208
{
2251
2209
/*
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.
2258
2213
*/
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
+ }
2263
2219
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 ;
2276
2228
}
2277
2229
2278
2230
/*
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).
2284
2237
*
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 .
2289
2242
*/
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 );
2293
2254
2294
2255
/*
2295
2256
* 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,
2298
2259
* TID. (This is also the closest value to negative infinity that's
2299
2260
* legally usable.)
2300
2261
*/
2301
- pivotheaptid = (ItemPointer ) ((char * ) pivot + newsize -
2262
+ pivotheaptid = (ItemPointer ) ((char * ) tidpivot + newsize -
2302
2263
sizeof (ItemPointerData ));
2303
2264
ItemPointerCopy (BTreeTupleGetMaxHeapTID (lastleft ), pivotheaptid );
2304
2265
2305
2266
/*
2267
+ * We're done. Assert() that heap TID invariants hold before returning.
2268
+ *
2306
2269
* Lehman and Yao require that the downlink to the right page, which is to
2307
2270
* be inserted into the parent page in the second phase of a page split be
2308
2271
* 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,
2342
2305
BTreeTupleGetHeapTID (firstright )) < 0 );
2343
2306
#endif
2344
2307
2345
- BTreeTupleSetNAtts (pivot , nkeyatts );
2346
- BTreeTupleSetAltHeapTID (pivot );
2347
-
2348
- return pivot ;
2308
+ return tidpivot ;
2349
2309
}
2350
2310
2351
2311
/*
0 commit comments