@@ -1797,7 +1797,6 @@ _bt_insert_parent(Relation rel,
1797
1797
stack = & fakestack ;
1798
1798
stack -> bts_blkno = BufferGetBlockNumber (pbuf );
1799
1799
stack -> bts_offset = InvalidOffsetNumber ;
1800
- stack -> bts_btentry = InvalidBlockNumber ;
1801
1800
stack -> bts_parent = NULL ;
1802
1801
_bt_relbuf (rel , pbuf );
1803
1802
}
@@ -1819,8 +1818,7 @@ _bt_insert_parent(Relation rel,
1819
1818
* new downlink will be inserted at the correct offset. Even buf's
1820
1819
* parent may have changed.
1821
1820
*/
1822
- stack -> bts_btentry = bknum ;
1823
- pbuf = _bt_getstackbuf (rel , stack );
1821
+ pbuf = _bt_getstackbuf (rel , stack , bknum );
1824
1822
1825
1823
/*
1826
1824
* Now we can unlock the right child. The left child will be unlocked
@@ -1834,7 +1832,7 @@ _bt_insert_parent(Relation rel,
1834
1832
errmsg_internal ("failed to re-find parent key in index \"%s\" for split pages %u/%u" ,
1835
1833
RelationGetRelationName (rel ), bknum , rbknum )));
1836
1834
1837
- /* Recursively update the parent */
1835
+ /* Recursively insert into the parent */
1838
1836
_bt_insertonpg (rel , NULL , pbuf , buf , stack -> bts_parent ,
1839
1837
new_item , stack -> bts_offset + 1 ,
1840
1838
is_only );
@@ -1901,21 +1899,37 @@ _bt_finish_split(Relation rel, Buffer lbuf, BTStack stack)
1901
1899
}
1902
1900
1903
1901
/*
1904
- * _bt_getstackbuf() -- Walk back up the tree one step, and find the item
1905
- * we last looked at in the parent .
1902
+ * _bt_getstackbuf() -- Walk back up the tree one step, and find the pivot
1903
+ * tuple whose downlink points to child page .
1906
1904
*
1907
- * This is possible because we save the downlink from the parent item,
1908
- * which is enough to uniquely identify it. Insertions into the parent
1909
- * level could cause the item to move right; deletions could cause it
1910
- * to move left, but not left of the page we previously found it in.
1905
+ * Caller passes child's block number, which is used to identify
1906
+ * associated pivot tuple in parent page using a linear search that
1907
+ * matches on pivot's downlink/block number. The expected location of
1908
+ * the pivot tuple is taken from the stack one level above the child
1909
+ * page. This is used as a starting point. Insertions into the
1910
+ * parent level could cause the pivot tuple to move right; deletions
1911
+ * could cause it to move left, but not left of the page we previously
1912
+ * found it on.
1911
1913
*
1912
- * Adjusts bts_blkno & bts_offset if changed.
1914
+ * Caller can use its stack to relocate the pivot tuple/downlink for
1915
+ * any same-level page to the right of the page found by its initial
1916
+ * descent. This is necessary because of the possibility that caller
1917
+ * moved right to recover from a concurrent page split. It's also
1918
+ * convenient for certain callers to be able to step right when there
1919
+ * wasn't a concurrent page split, while still using their original
1920
+ * stack. For example, the checkingunique _bt_doinsert() case may
1921
+ * have to step right when there are many physical duplicates, and its
1922
+ * scantid forces an insertion to the right of the "first page the
1923
+ * value could be on".
1913
1924
*
1914
- * Returns write-locked buffer, or InvalidBuffer if item not found
1915
- * (should not happen).
1925
+ * Returns write-locked parent page buffer, or InvalidBuffer if pivot
1926
+ * tuple not found (should not happen). Adjusts bts_blkno &
1927
+ * bts_offset if changed. Page split caller should insert its new
1928
+ * pivot tuple for its new right sibling page on parent page, at the
1929
+ * offset number bts_offset + 1.
1916
1930
*/
1917
1931
Buffer
1918
- _bt_getstackbuf (Relation rel , BTStack stack )
1932
+ _bt_getstackbuf (Relation rel , BTStack stack , BlockNumber child )
1919
1933
{
1920
1934
BlockNumber blkno ;
1921
1935
OffsetNumber start ;
@@ -1977,7 +1991,7 @@ _bt_getstackbuf(Relation rel, BTStack stack)
1977
1991
itemid = PageGetItemId (page , offnum );
1978
1992
item = (IndexTuple ) PageGetItem (page , itemid );
1979
1993
1980
- if (BTreeInnerTupleGetDownLink (item ) == stack -> bts_btentry )
1994
+ if (BTreeInnerTupleGetDownLink (item ) == child )
1981
1995
{
1982
1996
/* Return accurate pointer to where link is now */
1983
1997
stack -> bts_blkno = blkno ;
@@ -1993,7 +2007,7 @@ _bt_getstackbuf(Relation rel, BTStack stack)
1993
2007
itemid = PageGetItemId (page , offnum );
1994
2008
item = (IndexTuple ) PageGetItem (page , itemid );
1995
2009
1996
- if (BTreeInnerTupleGetDownLink (item ) == stack -> bts_btentry )
2010
+ if (BTreeInnerTupleGetDownLink (item ) == child )
1997
2011
{
1998
2012
/* Return accurate pointer to where link is now */
1999
2013
stack -> bts_blkno = blkno ;
0 commit comments