Further cleanup in _bt_first: eliminate duplicate code paths.
This commit is contained in:
parent
550d347811
commit
ef92b82dbb
@ -8,7 +8,7 @@
|
|||||||
* Portions Copyright (c) 1994, Regents of the University of California
|
* Portions Copyright (c) 1994, Regents of the University of California
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $PostgreSQL: pgsql/src/backend/access/nbtree/nbtsearch.c,v 1.85 2003/12/21 03:00:04 tgl Exp $
|
* $PostgreSQL: pgsql/src/backend/access/nbtree/nbtsearch.c,v 1.86 2003/12/21 17:52:34 tgl Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
@ -496,6 +496,7 @@ _bt_first(IndexScanDesc scan, ScanDirection dir)
|
|||||||
StrategyNumber strat;
|
StrategyNumber strat;
|
||||||
bool res;
|
bool res;
|
||||||
bool nextkey;
|
bool nextkey;
|
||||||
|
bool goback;
|
||||||
bool continuescan;
|
bool continuescan;
|
||||||
ScanKey scankeys;
|
ScanKey scankeys;
|
||||||
ScanKey *startKeys = NULL;
|
ScanKey *startKeys = NULL;
|
||||||
@ -695,18 +696,41 @@ _bt_first(IndexScanDesc scan, ScanDirection dir)
|
|||||||
pfree(startKeys);
|
pfree(startKeys);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* We want to locate either the first item >= boundary point, or
|
* Examine the selected initial-positioning strategy to determine
|
||||||
* first item > boundary point, depending on the initial-positioning
|
* exactly where we need to start the scan, and set flag variables
|
||||||
* strategy we just chose.
|
* to control the code below.
|
||||||
|
*
|
||||||
|
* If nextkey = false, _bt_search and _bt_binsrch will locate the
|
||||||
|
* first item >= scan key. If nextkey = true, they will locate the
|
||||||
|
* first item > scan key.
|
||||||
|
*
|
||||||
|
* If goback = true, we will then step back one item, while if
|
||||||
|
* goback = false, we will start the scan on the located item.
|
||||||
|
*
|
||||||
|
* it's yet other place to add some code later for is(not)null ...
|
||||||
*/
|
*/
|
||||||
switch (strat_total)
|
switch (strat_total)
|
||||||
{
|
{
|
||||||
case BTLessStrategyNumber:
|
case BTLessStrategyNumber:
|
||||||
|
/*
|
||||||
|
* Find first item >= scankey, then back up one to arrive at last
|
||||||
|
* item < scankey. (Note: this positioning strategy is only used
|
||||||
|
* for a backward scan, so that is always the correct starting
|
||||||
|
* position.)
|
||||||
|
*/
|
||||||
nextkey = false;
|
nextkey = false;
|
||||||
|
goback = true;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case BTLessEqualStrategyNumber:
|
case BTLessEqualStrategyNumber:
|
||||||
|
/*
|
||||||
|
* Find first item > scankey, then back up one to arrive at last
|
||||||
|
* item <= scankey. (Note: this positioning strategy is only used
|
||||||
|
* for a backward scan, so that is always the correct starting
|
||||||
|
* position.)
|
||||||
|
*/
|
||||||
nextkey = true;
|
nextkey = true;
|
||||||
|
goback = true;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case BTEqualStrategyNumber:
|
case BTEqualStrategyNumber:
|
||||||
@ -715,17 +739,41 @@ _bt_first(IndexScanDesc scan, ScanDirection dir)
|
|||||||
* equal item not first one.
|
* equal item not first one.
|
||||||
*/
|
*/
|
||||||
if (ScanDirectionIsBackward(dir))
|
if (ScanDirectionIsBackward(dir))
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* This is the same as the <= strategy. We will check
|
||||||
|
* at the end whether the found item is actually =.
|
||||||
|
*/
|
||||||
nextkey = true;
|
nextkey = true;
|
||||||
|
goback = true;
|
||||||
|
}
|
||||||
else
|
else
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* This is the same as the >= strategy. We will check
|
||||||
|
* at the end whether the found item is actually =.
|
||||||
|
*/
|
||||||
nextkey = false;
|
nextkey = false;
|
||||||
|
goback = false;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case BTGreaterEqualStrategyNumber:
|
case BTGreaterEqualStrategyNumber:
|
||||||
|
/*
|
||||||
|
* Find first item >= scankey. (This is only used for
|
||||||
|
* forward scans.)
|
||||||
|
*/
|
||||||
nextkey = false;
|
nextkey = false;
|
||||||
|
goback = false;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case BTGreaterStrategyNumber:
|
case BTGreaterStrategyNumber:
|
||||||
|
/*
|
||||||
|
* Find first item > scankey. (This is only used for
|
||||||
|
* forward scans.)
|
||||||
|
*/
|
||||||
nextkey = true;
|
nextkey = true;
|
||||||
|
goback = false;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
@ -756,21 +804,18 @@ _bt_first(IndexScanDesc scan, ScanDirection dir)
|
|||||||
|
|
||||||
/* remember which buffer we have pinned */
|
/* remember which buffer we have pinned */
|
||||||
so->btso_curbuf = buf;
|
so->btso_curbuf = buf;
|
||||||
blkno = BufferGetBlockNumber(buf);
|
|
||||||
page = BufferGetPage(buf);
|
|
||||||
|
|
||||||
/* position to the precise item on the page */
|
/* position to the precise item on the page */
|
||||||
offnum = _bt_binsrch(rel, buf, keysCount, scankeys, nextkey);
|
offnum = _bt_binsrch(rel, buf, keysCount, scankeys, nextkey);
|
||||||
|
|
||||||
|
page = BufferGetPage(buf);
|
||||||
|
blkno = BufferGetBlockNumber(buf);
|
||||||
ItemPointerSet(current, blkno, offnum);
|
ItemPointerSet(current, blkno, offnum);
|
||||||
|
|
||||||
/* done with manufactured scankey, now */
|
/* done with manufactured scankey, now */
|
||||||
pfree(scankeys);
|
pfree(scankeys);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* It's now time to examine the initial-positioning strategy to find the
|
|
||||||
* exact place to start the scan.
|
|
||||||
*
|
|
||||||
* If nextkey = false, we are positioned at the first item >= scan key,
|
* If nextkey = false, we are positioned at the first item >= scan key,
|
||||||
* or possibly at the end of a page on which all the existing items are
|
* or possibly at the end of a page on which all the existing items are
|
||||||
* less than the scan key and we know that everything on later pages
|
* less than the scan key and we know that everything on later pages
|
||||||
@ -781,103 +826,29 @@ _bt_first(IndexScanDesc scan, ScanDirection dir)
|
|||||||
* less than or equal to the scan key and we know that everything on
|
* less than or equal to the scan key and we know that everything on
|
||||||
* later pages is greater than scan key.
|
* later pages is greater than scan key.
|
||||||
*
|
*
|
||||||
* The actually desired starting point is either this item or an adjacent
|
* The actually desired starting point is either this item or the prior
|
||||||
* one, or in the end-of-page case it's the last item on this page or
|
* one, or in the end-of-page case it's the first item on the next page
|
||||||
* the first item on the next. We apply _bt_step if needed to get to
|
* or the last item on this page. We apply _bt_step if needed to get to
|
||||||
* the right place.
|
* the right place.
|
||||||
*
|
*
|
||||||
* Note: if _bt_step fails (meaning we fell off the end of the index in
|
* If _bt_step fails (meaning we fell off the end of the index in
|
||||||
* one direction or the other), then there are no matches so we just
|
* one direction or the other), then there are no matches so we just
|
||||||
* return false.
|
* return false.
|
||||||
*
|
|
||||||
* it's yet other place to add some code later for is(not)null ...
|
|
||||||
*/
|
*/
|
||||||
switch (strat_total)
|
if (goback)
|
||||||
{
|
{
|
||||||
case BTLessStrategyNumber:
|
/* _bt_step will do the right thing if we are at end-of-page */
|
||||||
|
if (!_bt_step(scan, &buf, BackwardScanDirection))
|
||||||
/*
|
return false;
|
||||||
* We are on first item >= scankey.
|
}
|
||||||
*
|
else
|
||||||
* Back up one to arrive at last item < scankey. (Note: this
|
{
|
||||||
* positioning strategy is only used for a backward scan, so
|
/* If we're at end-of-page, must step forward to next page */
|
||||||
* that is always the correct starting position.)
|
if (offnum > PageGetMaxOffsetNumber(page))
|
||||||
*/
|
{
|
||||||
if (!_bt_step(scan, &buf, BackwardScanDirection))
|
if (!_bt_step(scan, &buf, ForwardScanDirection))
|
||||||
return false;
|
return false;
|
||||||
break;
|
}
|
||||||
|
|
||||||
case BTLessEqualStrategyNumber:
|
|
||||||
|
|
||||||
/*
|
|
||||||
* We are on first item > scankey.
|
|
||||||
*
|
|
||||||
* Back up one to arrive at last item <= scankey. (Note: this
|
|
||||||
* positioning strategy is only used for a backward scan, so
|
|
||||||
* that is always the correct starting position.)
|
|
||||||
*/
|
|
||||||
if (!_bt_step(scan, &buf, BackwardScanDirection))
|
|
||||||
return false;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case BTEqualStrategyNumber:
|
|
||||||
/*
|
|
||||||
* If a backward scan was specified, need to start with last
|
|
||||||
* equal item not first one.
|
|
||||||
*/
|
|
||||||
if (ScanDirectionIsBackward(dir))
|
|
||||||
{
|
|
||||||
/*
|
|
||||||
* We are on first item > scankey.
|
|
||||||
*
|
|
||||||
* Back up one to arrive at last item <= scankey.
|
|
||||||
* We will check below to see if it is equal to scankey.
|
|
||||||
*/
|
|
||||||
if (!_bt_step(scan, &buf, BackwardScanDirection))
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
/*
|
|
||||||
* We are on first item >= scankey.
|
|
||||||
*
|
|
||||||
* Make sure we are on a real item; might have to
|
|
||||||
* step forward if currently at end of page.
|
|
||||||
* We will check below to see if it is equal to scankey.
|
|
||||||
*/
|
|
||||||
if (offnum > PageGetMaxOffsetNumber(page))
|
|
||||||
{
|
|
||||||
if (!_bt_step(scan, &buf, ForwardScanDirection))
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case BTGreaterEqualStrategyNumber:
|
|
||||||
|
|
||||||
/*
|
|
||||||
* We want the first item >= scankey, which is where we are...
|
|
||||||
* unless we're not anywhere at all...
|
|
||||||
*/
|
|
||||||
if (offnum > PageGetMaxOffsetNumber(page))
|
|
||||||
{
|
|
||||||
if (!_bt_step(scan, &buf, ForwardScanDirection))
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case BTGreaterStrategyNumber:
|
|
||||||
|
|
||||||
/*
|
|
||||||
* We want the first item > scankey, which is where we are...
|
|
||||||
* unless we're not anywhere at all...
|
|
||||||
*/
|
|
||||||
if (offnum > PageGetMaxOffsetNumber(page))
|
|
||||||
{
|
|
||||||
if (!_bt_step(scan, &buf, ForwardScanDirection))
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* okay, current item pointer for the scan is right */
|
/* okay, current item pointer for the scan is right */
|
||||||
|
Loading…
x
Reference in New Issue
Block a user