mirror of
https://git.postgresql.org/git/postgresql.git
synced 2024-12-15 08:20:16 +08: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:
parent
90011a8918
commit
5925377401
@ -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.69 2001/10/25 05:49:21 momjian Exp $
|
||||
* $Header: /cvsroot/pgsql/src/backend/access/nbtree/nbtsearch.c,v 1.69.2.1 2003/07/29 22:18:53 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;
|
||||
}
|
||||
@ -590,8 +590,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
|
||||
|
Loading…
Reference in New Issue
Block a user