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
|
||||
*
|
||||
* 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;
|
||||
bool res;
|
||||
bool nextkey;
|
||||
bool goback;
|
||||
bool continuescan;
|
||||
ScanKey scankeys;
|
||||
ScanKey *startKeys = NULL;
|
||||
@ -695,18 +696,41 @@ _bt_first(IndexScanDesc scan, ScanDirection dir)
|
||||
pfree(startKeys);
|
||||
|
||||
/*
|
||||
* We want to locate either the first item >= boundary point, or
|
||||
* first item > boundary point, depending on the initial-positioning
|
||||
* strategy we just chose.
|
||||
* Examine the selected initial-positioning strategy to determine
|
||||
* exactly where we need to start the scan, and set flag variables
|
||||
* 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)
|
||||
{
|
||||
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;
|
||||
goback = true;
|
||||
break;
|
||||
|
||||
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;
|
||||
goback = true;
|
||||
break;
|
||||
|
||||
case BTEqualStrategyNumber:
|
||||
@ -715,17 +739,41 @@ _bt_first(IndexScanDesc scan, ScanDirection dir)
|
||||
* equal item not first one.
|
||||
*/
|
||||
if (ScanDirectionIsBackward(dir))
|
||||
{
|
||||
/*
|
||||
* This is the same as the <= strategy. We will check
|
||||
* at the end whether the found item is actually =.
|
||||
*/
|
||||
nextkey = true;
|
||||
goback = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
/*
|
||||
* This is the same as the >= strategy. We will check
|
||||
* at the end whether the found item is actually =.
|
||||
*/
|
||||
nextkey = false;
|
||||
goback = false;
|
||||
}
|
||||
break;
|
||||
|
||||
case BTGreaterEqualStrategyNumber:
|
||||
/*
|
||||
* Find first item >= scankey. (This is only used for
|
||||
* forward scans.)
|
||||
*/
|
||||
nextkey = false;
|
||||
goback = false;
|
||||
break;
|
||||
|
||||
case BTGreaterStrategyNumber:
|
||||
/*
|
||||
* Find first item > scankey. (This is only used for
|
||||
* forward scans.)
|
||||
*/
|
||||
nextkey = true;
|
||||
goback = false;
|
||||
break;
|
||||
|
||||
default:
|
||||
@ -756,21 +804,18 @@ _bt_first(IndexScanDesc scan, ScanDirection dir)
|
||||
|
||||
/* remember which buffer we have pinned */
|
||||
so->btso_curbuf = buf;
|
||||
blkno = BufferGetBlockNumber(buf);
|
||||
page = BufferGetPage(buf);
|
||||
|
||||
/* position to the precise item on the page */
|
||||
offnum = _bt_binsrch(rel, buf, keysCount, scankeys, nextkey);
|
||||
|
||||
page = BufferGetPage(buf);
|
||||
blkno = BufferGetBlockNumber(buf);
|
||||
ItemPointerSet(current, blkno, offnum);
|
||||
|
||||
/* done with manufactured scankey, now */
|
||||
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,
|
||||
* 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
|
||||
@ -781,103 +826,29 @@ _bt_first(IndexScanDesc scan, ScanDirection dir)
|
||||
* less than or equal to the scan key and we know that everything on
|
||||
* later pages is greater than scan key.
|
||||
*
|
||||
* The actually desired starting point is either this item or an adjacent
|
||||
* one, or in the end-of-page case it's the last item on this page or
|
||||
* the first item on the next. We apply _bt_step if needed to get to
|
||||
* The actually desired starting point is either this item or the prior
|
||||
* one, or in the end-of-page case it's the first item on the next page
|
||||
* or the last item on this page. We apply _bt_step if needed to get to
|
||||
* 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
|
||||
* return false.
|
||||
*
|
||||
* it's yet other place to add some code later for is(not)null ...
|
||||
*/
|
||||
switch (strat_total)
|
||||
if (goback)
|
||||
{
|
||||
case BTLessStrategyNumber:
|
||||
|
||||
/*
|
||||
* 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))
|
||||
/* _bt_step will do the right thing if we are at end-of-page */
|
||||
if (!_bt_step(scan, &buf, BackwardScanDirection))
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* If we're at end-of-page, must step forward to next page */
|
||||
if (offnum > PageGetMaxOffsetNumber(page))
|
||||
{
|
||||
if (!_bt_step(scan, &buf, ForwardScanDirection))
|
||||
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 */
|
||||
|
Loading…
x
Reference in New Issue
Block a user