@ -1530,7 +1530,8 @@ _bt_readpage(IndexScanDesc scan, ScanDirection dir, OffsetNumber offnum,
int itemIndex ;
int itemIndex ;
bool continuescan ;
bool continuescan ;
int indnatts ;
int indnatts ;
bool requiredMatchedByPrecheck ;
bool continuescanPrechecked ;
bool haveFirstMatch = false ;
/*
/*
* We must have the buffer pinned and locked , but the usual macro can ' t be
* We must have the buffer pinned and locked , but the usual macro can ' t be
@ -1585,12 +1586,11 @@ _bt_readpage(IndexScanDesc scan, ScanDirection dir, OffsetNumber offnum,
Assert ( BTScanPosIsPinned ( so - > currPos ) ) ;
Assert ( BTScanPosIsPinned ( so - > currPos ) ) ;
/*
/*
* Prechecking the page with scan keys required for direction scan . We
* Prechecking the value of the continuescan flag for the last item on the
* check these keys with the last item on the page ( according to our scan
* page ( for backwards scan it will be the first item on a page ) . If we
* direction ) . If these keys are matched , we can skip checking them with
* observe it to be true , then it should be true for all other items . This
* every item on the page . Scan keys for our scan direction would
* allows us to do significant optimizations in the _bt_checkkeys ( )
* necessarily match the previous items . Scan keys required for opposite
* function for all the items on the page .
* direction scan are already matched by the _bt_first ( ) call .
*
*
* With the forward scan , we do this check for the last item on the page
* With the forward scan , we do this check for the last item on the page
* instead of the high key . It ' s relatively likely that the most
* instead of the high key . It ' s relatively likely that the most
@ -1610,17 +1610,17 @@ _bt_readpage(IndexScanDesc scan, ScanDirection dir, OffsetNumber offnum,
itup = ( IndexTuple ) PageGetItem ( page , iid ) ;
itup = ( IndexTuple ) PageGetItem ( page , iid ) ;
/*
/*
* Do the precheck . Note that we pass the pointer to
* Do the precheck . Note that we pass the pointer to the
* ' requiredMatchedByPrecheck ' to ' continuescan ' argument . That will
* ' continuescanPrechecked ' to the ' continuescan ' argument . That will
* set flag to true if all required keys are satisfied and false
* set flag to true if all required keys are satisfied and false
* otherwise .
* otherwise .
*/
*/
( void ) _bt_checkkeys ( scan , itup , indnatts , dir ,
( void ) _bt_checkkeys ( scan , itup , indnatts , dir ,
& requiredMatchedByPrecheck , false ) ;
& continuescanPrechecked , false , false ) ;
}
}
else
else
{
{
requiredMatchedByPrecheck = false ;
continuescanPrechecked = false ;
}
}
if ( ScanDirectionIsForward ( dir ) )
if ( ScanDirectionIsForward ( dir ) )
@ -1650,19 +1650,22 @@ _bt_readpage(IndexScanDesc scan, ScanDirection dir, OffsetNumber offnum,
Assert ( ! BTreeTupleIsPivot ( itup ) ) ;
Assert ( ! BTreeTupleIsPivot ( itup ) ) ;
passes_quals = _bt_checkkeys ( scan , itup , indnatts , dir ,
passes_quals = _bt_checkkeys ( scan , itup , indnatts , dir ,
& continuescan , requiredMatchedByPrecheck ) ;
& continuescan ,
continuescanPrechecked ,
haveFirstMatch ) ;
/*
/*
* If the result of prechecking required keys was true , then in
* If the result of prechecking required keys was true , then in
* assert - enabled builds we also recheck that the _bt_checkkeys ( )
* assert - enabled builds we also recheck that the _bt_checkkeys ( )
* result is the same .
* result is the same .
*/
*/
Assert ( ! requiredMatchedByPrecheck | |
Assert ( ( ! continuescanPrechecked & & haveFirstMatch ) | |
passes_quals = = _bt_checkkeys ( scan , itup , indnatts , dir ,
passes_quals = = _bt_checkkeys ( scan , itup , indnatts , dir ,
& continuescan , false ) ) ;
& continuescan , false , false ) ) ;
if ( passes_quals )
if ( passes_quals )
{
{
/* tuple passes all scan key conditions */
/* tuple passes all scan key conditions */
haveFirstMatch = true ;
if ( ! BTreeTupleIsPosting ( itup ) )
if ( ! BTreeTupleIsPosting ( itup ) )
{
{
/* Remember it */
/* Remember it */
@ -1717,7 +1720,7 @@ _bt_readpage(IndexScanDesc scan, ScanDirection dir, OffsetNumber offnum,
int truncatt ;
int truncatt ;
truncatt = BTreeTupleGetNAtts ( itup , scan - > indexRelation ) ;
truncatt = BTreeTupleGetNAtts ( itup , scan - > indexRelation ) ;
_bt_checkkeys ( scan , itup , truncatt , dir , & continuescan , false ) ;
_bt_checkkeys ( scan , itup , truncatt , dir , & continuescan , false , false ) ;
}
}
if ( ! continuescan )
if ( ! continuescan )
@ -1770,19 +1773,22 @@ _bt_readpage(IndexScanDesc scan, ScanDirection dir, OffsetNumber offnum,
Assert ( ! BTreeTupleIsPivot ( itup ) ) ;
Assert ( ! BTreeTupleIsPivot ( itup ) ) ;
passes_quals = _bt_checkkeys ( scan , itup , indnatts , dir ,
passes_quals = _bt_checkkeys ( scan , itup , indnatts , dir ,
& continuescan , requiredMatchedByPrecheck ) ;
& continuescan ,
continuescanPrechecked ,
haveFirstMatch ) ;
/*
/*
* If the result of prechecking required keys was true , then in
* If the result of prechecking required keys was true , then in
* assert - enabled builds we also recheck that the _bt_checkkeys ( )
* assert - enabled builds we also recheck that the _bt_checkkeys ( )
* result is the same .
* result is the same .
*/
*/
Assert ( ! requiredMatchedByPrecheck | |
Assert ( ( ! continuescanPrechecked & & ! haveFirstMatch ) | |
passes_quals = = _bt_checkkeys ( scan , itup , indnatts , dir ,
passes_quals = = _bt_checkkeys ( scan , itup , indnatts , dir ,
& continuescan , false ) ) ;
& continuescan , false , false ) ) ;
if ( passes_quals & & tuple_alive )
if ( passes_quals & & tuple_alive )
{
{
/* tuple passes all scan key conditions */
/* tuple passes all scan key conditions */
haveFirstMatch = true ;
if ( ! BTreeTupleIsPosting ( itup ) )
if ( ! BTreeTupleIsPosting ( itup ) )
{
{
/* Remember it */
/* Remember it */