aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorTom Lane <tgl@sss.pgh.pa.us>2003-12-21 17:52:34 +0000
committerTom Lane <tgl@sss.pgh.pa.us>2003-12-21 17:52:34 +0000
commitef92b82dbbd9f30c60ca3c8c2d3860ccd4e01987 (patch)
treea824e97345443afb783276db2cf63c020b2b2120 /src
parent550d347811ba2a604255a54ec91a0b4545be0fd7 (diff)
downloadpostgresql-ef92b82dbbd9f30c60ca3c8c2d3860ccd4e01987.tar.gz
postgresql-ef92b82dbbd9f30c60ca3c8c2d3860ccd4e01987.zip
Further cleanup in _bt_first: eliminate duplicate code paths.
Diffstat (limited to 'src')
-rw-r--r--src/backend/access/nbtree/nbtsearch.c169
1 files changed, 70 insertions, 99 deletions
diff --git a/src/backend/access/nbtree/nbtsearch.c b/src/backend/access/nbtree/nbtsearch.c
index cc852984ce2..acdcf3e0a56 100644
--- a/src/backend/access/nbtree/nbtsearch.c
+++ b/src/backend/access/nbtree/nbtsearch.c
@@ -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))
- 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))
+ /* _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 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 */