1
0
mirror of https://github.com/postgres/postgres.git synced 2025-09-08 00:47:37 +03:00

Fix longstanding error in _bt_search(): should moveright at top of loop not

bottom.  Otherwise we fail to moveright when the root page was split while
we were "in flight" to it.  This is not a significant problem when the root
is above the leaf level, but if the root was also a leaf (ie, a single-page
index just got split) we may return the wrong leaf page to the caller,
resulting in failure to find a key that is in fact present.  Bug has existed
at least since 7.1, probably forever.
This commit is contained in:
Tom Lane
2003-07-29 22:18:48 +00:00
parent 091b9c211c
commit a4ffca6bdf

View File

@@ -8,7 +8,7 @@
* Portions Copyright (c) 1994, Regents of the University of California
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/access/nbtree/nbtsearch.c,v 1.72 2002/06/20 20:29:25 momjian Exp $
* $Header: /cvsroot/pgsql/src/backend/access/nbtree/nbtsearch.c,v 1.72.2.1 2003/07/29 22:18:48 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -61,6 +61,13 @@ _bt_search(Relation rel, int keysz, ScanKey scankey,
BlockNumber par_blkno;
BTStack new_stack;
/*
* Race -- the page we just grabbed may have split since we read
* its pointer in the parent (or metapage). If it has, we may need
* to move right to its new sibling. Do that.
*/
*bufP = _bt_moveright(rel, *bufP, keysz, scankey, BT_READ);
/* if this is a leaf page, we're done */
page = BufferGetPage(*bufP);
opaque = (BTPageOpaque) PageGetSpecialPointer(page);
@@ -97,13 +104,6 @@ _bt_search(Relation rel, int keysz, ScanKey scankey,
_bt_relbuf(rel, *bufP);
*bufP = _bt_getbuf(rel, blkno, BT_READ);
/*
* Race -- the page we just grabbed may have split since we read
* its pointer in the parent. If it has, we may need to move
* right to its new sibling. Do that.
*/
*bufP = _bt_moveright(rel, *bufP, keysz, scankey, BT_READ);
/* okay, all set to move down a level */
stack_in = new_stack;
}
@@ -589,8 +589,8 @@ _bt_first(IndexScanDesc scan, ScanDirection dir)
/*
* At this point we are positioned at the first item >= scan key, or
* possibly at the end of a page on which all the existing items are
* greater than the scan key and we know that everything on later
* pages is less than or equal to scan key.
* less than the scan key and we know that everything on later
* pages is greater than or equal to scan key.
*
* We could step forward in the latter case, but that'd be a waste of
* time if we want to scan backwards. So, it's now time to examine