8
8
* Portions Copyright (c) 1994, Regents of the University of California
9
9
*
10
10
* IDENTIFICATION
11
- * $PostgreSQL: pgsql/src/backend/access/nbtree/nbtsearch.c,v 1.85 2003/12/21 03:00:04 tgl Exp $
11
+ * $PostgreSQL: pgsql/src/backend/access/nbtree/nbtsearch.c,v 1.86 2003/12/21 17:52:34 tgl Exp $
12
12
*
13
13
*-------------------------------------------------------------------------
14
14
*/
@@ -496,6 +496,7 @@ _bt_first(IndexScanDesc scan, ScanDirection dir)
496
496
StrategyNumber strat ;
497
497
bool res ;
498
498
bool nextkey ;
499
+ bool goback ;
499
500
bool continuescan ;
500
501
ScanKey scankeys ;
501
502
ScanKey * startKeys = NULL ;
@@ -695,18 +696,41 @@ _bt_first(IndexScanDesc scan, ScanDirection dir)
695
696
pfree (startKeys );
696
697
697
698
/*
698
- * We want to locate either the first item >= boundary point, or
699
- * first item > boundary point, depending on the initial-positioning
700
- * strategy we just chose.
699
+ * Examine the selected initial-positioning strategy to determine
700
+ * exactly where we need to start the scan, and set flag variables
701
+ * to control the code below.
702
+ *
703
+ * If nextkey = false, _bt_search and _bt_binsrch will locate the
704
+ * first item >= scan key. If nextkey = true, they will locate the
705
+ * first item > scan key.
706
+ *
707
+ * If goback = true, we will then step back one item, while if
708
+ * goback = false, we will start the scan on the located item.
709
+ *
710
+ * it's yet other place to add some code later for is(not)null ...
701
711
*/
702
712
switch (strat_total )
703
713
{
704
714
case BTLessStrategyNumber :
715
+ /*
716
+ * Find first item >= scankey, then back up one to arrive at last
717
+ * item < scankey. (Note: this positioning strategy is only used
718
+ * for a backward scan, so that is always the correct starting
719
+ * position.)
720
+ */
705
721
nextkey = false;
722
+ goback = true;
706
723
break ;
707
724
708
725
case BTLessEqualStrategyNumber :
726
+ /*
727
+ * Find first item > scankey, then back up one to arrive at last
728
+ * item <= scankey. (Note: this positioning strategy is only used
729
+ * for a backward scan, so that is always the correct starting
730
+ * position.)
731
+ */
709
732
nextkey = true;
733
+ goback = true;
710
734
break ;
711
735
712
736
case BTEqualStrategyNumber :
@@ -715,17 +739,41 @@ _bt_first(IndexScanDesc scan, ScanDirection dir)
715
739
* equal item not first one.
716
740
*/
717
741
if (ScanDirectionIsBackward (dir ))
742
+ {
743
+ /*
744
+ * This is the same as the <= strategy. We will check
745
+ * at the end whether the found item is actually =.
746
+ */
718
747
nextkey = true;
748
+ goback = true;
749
+ }
719
750
else
751
+ {
752
+ /*
753
+ * This is the same as the >= strategy. We will check
754
+ * at the end whether the found item is actually =.
755
+ */
720
756
nextkey = false;
757
+ goback = false;
758
+ }
721
759
break ;
722
760
723
761
case BTGreaterEqualStrategyNumber :
762
+ /*
763
+ * Find first item >= scankey. (This is only used for
764
+ * forward scans.)
765
+ */
724
766
nextkey = false;
767
+ goback = false;
725
768
break ;
726
769
727
770
case BTGreaterStrategyNumber :
771
+ /*
772
+ * Find first item > scankey. (This is only used for
773
+ * forward scans.)
774
+ */
728
775
nextkey = true;
776
+ goback = false;
729
777
break ;
730
778
731
779
default :
@@ -756,21 +804,18 @@ _bt_first(IndexScanDesc scan, ScanDirection dir)
756
804
757
805
/* remember which buffer we have pinned */
758
806
so -> btso_curbuf = buf ;
759
- blkno = BufferGetBlockNumber (buf );
760
- page = BufferGetPage (buf );
761
807
762
808
/* position to the precise item on the page */
763
809
offnum = _bt_binsrch (rel , buf , keysCount , scankeys , nextkey );
764
810
811
+ page = BufferGetPage (buf );
812
+ blkno = BufferGetBlockNumber (buf );
765
813
ItemPointerSet (current , blkno , offnum );
766
814
767
815
/* done with manufactured scankey, now */
768
816
pfree (scankeys );
769
817
770
818
/*
771
- * It's now time to examine the initial-positioning strategy to find the
772
- * exact place to start the scan.
773
- *
774
819
* If nextkey = false, we are positioned at the first item >= scan key,
775
820
* or possibly at the end of a page on which all the existing items are
776
821
* less than the scan key and we know that everything on later pages
@@ -781,103 +826,29 @@ _bt_first(IndexScanDesc scan, ScanDirection dir)
781
826
* less than or equal to the scan key and we know that everything on
782
827
* later pages is greater than scan key.
783
828
*
784
- * The actually desired starting point is either this item or an adjacent
785
- * one, or in the end-of-page case it's the last item on this page or
786
- * the first item on the next . We apply _bt_step if needed to get to
829
+ * The actually desired starting point is either this item or the prior
830
+ * one, or in the end-of-page case it's the first item on the next page
831
+ * or the last item on this page . We apply _bt_step if needed to get to
787
832
* the right place.
788
833
*
789
- * Note: if _bt_step fails (meaning we fell off the end of the index in
834
+ * If _bt_step fails (meaning we fell off the end of the index in
790
835
* one direction or the other), then there are no matches so we just
791
836
* return false.
792
- *
793
- * it's yet other place to add some code later for is(not)null ...
794
837
*/
795
- switch ( strat_total )
838
+ if ( goback )
796
839
{
797
- case BTLessStrategyNumber :
798
-
799
- /*
800
- * We are on first item >= scankey.
801
- *
802
- * Back up one to arrive at last item < scankey. (Note: this
803
- * positioning strategy is only used for a backward scan, so
804
- * that is always the correct starting position.)
805
- */
806
- if (!_bt_step (scan , & buf , BackwardScanDirection ))
807
- return false;
808
- break ;
809
-
810
- case BTLessEqualStrategyNumber :
811
-
812
- /*
813
- * We are on first item > scankey.
814
- *
815
- * Back up one to arrive at last item <= scankey. (Note: this
816
- * positioning strategy is only used for a backward scan, so
817
- * that is always the correct starting position.)
818
- */
819
- if (!_bt_step (scan , & buf , BackwardScanDirection ))
840
+ /* _bt_step will do the right thing if we are at end-of-page */
841
+ if (!_bt_step (scan , & buf , BackwardScanDirection ))
842
+ return false;
843
+ }
844
+ else
845
+ {
846
+ /* If we're at end-of-page, must step forward to next page */
847
+ if (offnum > PageGetMaxOffsetNumber (page ))
848
+ {
849
+ if (!_bt_step (scan , & buf , ForwardScanDirection ))
820
850
return false;
821
- break ;
822
-
823
- case BTEqualStrategyNumber :
824
- /*
825
- * If a backward scan was specified, need to start with last
826
- * equal item not first one.
827
- */
828
- if (ScanDirectionIsBackward (dir ))
829
- {
830
- /*
831
- * We are on first item > scankey.
832
- *
833
- * Back up one to arrive at last item <= scankey.
834
- * We will check below to see if it is equal to scankey.
835
- */
836
- if (!_bt_step (scan , & buf , BackwardScanDirection ))
837
- return false;
838
- }
839
- else
840
- {
841
- /*
842
- * We are on first item >= scankey.
843
- *
844
- * Make sure we are on a real item; might have to
845
- * step forward if currently at end of page.
846
- * We will check below to see if it is equal to scankey.
847
- */
848
- if (offnum > PageGetMaxOffsetNumber (page ))
849
- {
850
- if (!_bt_step (scan , & buf , ForwardScanDirection ))
851
- return false;
852
- }
853
- }
854
- break ;
855
-
856
- case BTGreaterEqualStrategyNumber :
857
-
858
- /*
859
- * We want the first item >= scankey, which is where we are...
860
- * unless we're not anywhere at all...
861
- */
862
- if (offnum > PageGetMaxOffsetNumber (page ))
863
- {
864
- if (!_bt_step (scan , & buf , ForwardScanDirection ))
865
- return false;
866
- }
867
- break ;
868
-
869
- case BTGreaterStrategyNumber :
870
-
871
- /*
872
- * We want the first item > scankey, which is where we are...
873
- * unless we're not anywhere at all...
874
- */
875
- if (offnum > PageGetMaxOffsetNumber (page ))
876
- {
877
- if (!_bt_step (scan , & buf , ForwardScanDirection ))
878
- return false;
879
- }
880
- break ;
851
+ }
881
852
}
882
853
883
854
/* okay, current item pointer for the scan is right */
0 commit comments