88 * Portions Copyright (c) 1994, Regents of the University of California
99 *
1010 * IDENTIFICATION
11- * $PostgreSQL: pgsql/src/backend/access/nbtree/nbtsearch.c,v 1.99 2005/12/07 19:37:53 tgl Exp $
11+ * $PostgreSQL: pgsql/src/backend/access/nbtree/nbtsearch.c,v 1.100 2006/01/17 00:09:01 tgl Exp $
1212 *
1313 *-------------------------------------------------------------------------
1414 */
@@ -29,6 +29,9 @@ static bool _bt_endpoint(IndexScanDesc scan, ScanDirection dir);
2929 *_bt_search() -- Search the tree for a particular scankey,
3030 *or more precisely for the first leaf page it could be on.
3131 *
32+ * The passed scankey must be an insertion-type scankey (see nbtree/README),
33+ * but it can omit the rightmost column(s) of the index.
34+ *
3235 * When nextkey is false (the usual case), we are looking for the first
3336 * item >= scankey. When nextkey is true, we are looking for the first
3437 * item strictly greater than scankey.
@@ -127,15 +130,18 @@ _bt_search(Relation rel, int keysz, ScanKey scankey, bool nextkey,
127130 * data that appeared on the page originally is either on the page
128131 * or strictly to the right of it.
129132 *
130- * When nextkey is false (the usual case), we are looking for the first
131- * item >= scankey. When nextkey is true, we are looking for the first
132- * item strictly greater than scankey.
133- *
134133 * This routine decides whether or not we need to move right in the
135134 * tree by examining the high key entry on the page. If that entry
136135 * is strictly less than the scankey, or <= the scankey in the nextkey=true
137136 * case, then we followed the wrong link and we need to move right.
138137 *
138+ * The passed scankey must be an insertion-type scankey (see nbtree/README),
139+ * but it can omit the rightmost column(s) of the index.
140+ *
141+ * When nextkey is false (the usual case), we are looking for the first
142+ * item >= scankey. When nextkey is true, we are looking for the first
143+ * item strictly greater than scankey.
144+ *
139145 * On entry, we have the buffer pinned and a lock of the type specified by
140146 * 'access'. If we move right, we release the buffer and lock and acquire
141147 * the same on the right sibling. Return value is the buffer we stop at.
@@ -194,14 +200,13 @@ _bt_moveright(Relation rel,
194200/*
195201 *_bt_binsrch() -- Do a binary search for a key on a particular page.
196202 *
203+ * The passed scankey must be an insertion-type scankey (see nbtree/README),
204+ * but it can omit the rightmost column(s) of the index.
205+ *
197206 * When nextkey is false (the usual case), we are looking for the first
198207 * item >= scankey. When nextkey is true, we are looking for the first
199208 * item strictly greater than scankey.
200209 *
201- * The scankey we get has the compare function stored in the procedure
202- * entry of each data struct. We invoke this regproc to do the
203- * comparison for every key in the scankey.
204- *
205210 * On a leaf page, _bt_binsrch() returns the OffsetNumber of the first
206211 * key >= given scankey, or > scankey if nextkey is true. (NOTE: in
207212 * particular, this means it is possible to return a value 1 greater than the
@@ -301,8 +306,11 @@ _bt_binsrch(Relation rel,
301306/*----------
302307 *_bt_compare() -- Compare scankey to a particular tuple on the page.
303308 *
309+ * The passed scankey must be an insertion-type scankey (see nbtree/README),
310+ * but it can omit the rightmost column(s) of the index.
311+ *
304312 *keysz: number of key conditions to be checked (might be less than the
305- *total length ofthe scan key !)
313+ *number ofindex columns !)
306314 *page/offnum: location of btree item to be compared to.
307315 *
308316 *This routine returns:
@@ -464,12 +472,17 @@ _bt_next(IndexScanDesc scan, ScanDirection dir)
464472/*
465473 *_bt_first() -- Find the first item in a scan.
466474 *
467- *We need to be clever about thetype of scan, theoperation it's
468- *performing , and the tree ordering. We find the
469- *first item in the tree that satisfies the qualification
470- *associated with the scandescriptor . On exit, the page containing
475+ *We need to be clever about thedirection of scan, thesearch
476+ *conditions , and the tree ordering. We find the first item (or,
477+ *if backwards scan, the last item) in the tree that satisfies the
478+ *qualifications in the scankey . On exit, the page containing
471479 *the current index tuple is read locked and pinned, and the scan's
472480 *opaque data entry is updated to include the buffer.
481+ *
482+ * Note that scan->keyData[], and the so->keyData[] scankey built from it,
483+ * are both search-type scankeys (see nbtree/README for more about this).
484+ * Within this routine, we build a temporary insertion-type scankey to use
485+ * in locating the scan start position.
473486 */
474487bool
475488_bt_first (IndexScanDesc scan ,ScanDirection dir )
@@ -537,6 +550,9 @@ _bt_first(IndexScanDesc scan, ScanDirection dir)
537550 * equality quals survive preprocessing, however, it doesn't matter which
538551 * one we use --- by definition, they are either redundant or
539552 * contradictory.
553+ *
554+ * The selected scan keys (at most one per index column) are remembered by
555+ * storing their addresses into the local startKeys[] array.
540556 *----------
541557 */
542558strat_total = BTEqualStrategyNumber ;
@@ -631,9 +647,10 @@ _bt_first(IndexScanDesc scan, ScanDirection dir)
631647return _bt_endpoint (scan ,dir );
632648
633649/*
634- * We want to start the scan somewhere within the index. Set up a
635- * 3-way-comparison scankey we can use to search for the boundary point we
636- * identified above.
650+ * We want to start the scan somewhere within the index. Set up an
651+ * insertion scankey we can use to search for the boundary point we
652+ * identified above. The insertion scankey is built in the local
653+ * scankeys[] array, using the keys identified by startKeys[].
637654 */
638655Assert (keysCount <=INDEX_MAX_KEYS );
639656for (i = 0 ;i < keysCount ;i ++ )
@@ -681,19 +698,20 @@ _bt_first(IndexScanDesc scan, ScanDirection dir)
681698}
682699}
683700
684- /*
701+ /*----------
685702 * Examine the selected initial-positioning strategy to determine exactly
686703 * where we need to start the scan, and set flag variables to control the
687704 * code below.
688705 *
689706 * If nextkey = false, _bt_search and _bt_binsrch will locate the first
690- * item >= scan key. If nextkey = true, they will locate the first item >
691- * scan key.
707+ * item >= scan key. If nextkey = true, they will locate the first
708+ *item > scan key.
692709 *
693- * If goback = true, we will then step back one item, while if goback =
694- * false, we will start the scan on the located item.
710+ * If goback = true, we will then step back one item, while if
711+ *goback = false, we will start the scan on the located item.
695712 *
696713 * it's yet other place to add some code later for is(not)null ...
714+ *----------
697715 */
698716switch (strat_total )
699717{
@@ -774,8 +792,8 @@ _bt_first(IndexScanDesc scan, ScanDirection dir)
774792}
775793
776794/*
777- * Use the manufactured scan key to descend the tree and position
778- * ourselves on the target leaf page.
795+ * Use the manufacturedinsertion scan key to descend the tree and
796+ *position ourselves on the target leaf page.
779797 */
780798stack = _bt_search (rel ,keysCount ,scankeys ,nextkey ,& buf ,BT_READ );
781799