@ -112,8 +112,9 @@ gistkillitems(IndexScanDesc scan)
* Similarly , * recheck_distances_p is set to indicate whether the distances
* Similarly , * recheck_distances_p is set to indicate whether the distances
* need to be rechecked , and it is also ignored for non - leaf entries .
* need to be rechecked , and it is also ignored for non - leaf entries .
*
*
* If we are doing an ordered scan , so - > distances [ ] is filled with distance
* If we are doing an ordered scan , so - > distancesValues [ ] and
* data from the distance ( ) functions before returning success .
* so - > distancesNulls [ ] is filled with distance data from the distance ( )
* functions before returning success .
*
*
* We must decompress the key in the IndexTuple before passing it to the
* We must decompress the key in the IndexTuple before passing it to the
* sk_funcs ( which actually are the opclass Consistent or Distance methods ) .
* sk_funcs ( which actually are the opclass Consistent or Distance methods ) .
@ -134,7 +135,8 @@ gistindex_keytest(IndexScanDesc scan,
GISTSTATE * giststate = so - > giststate ;
GISTSTATE * giststate = so - > giststate ;
ScanKey key = scan - > keyData ;
ScanKey key = scan - > keyData ;
int keySize = scan - > numberOfKeys ;
int keySize = scan - > numberOfKeys ;
double * distance_p ;
double * distance_value_p ;
bool * distance_null_p ;
Relation r = scan - > indexRelation ;
Relation r = scan - > indexRelation ;
* recheck_p = false ;
* recheck_p = false ;
@ -152,7 +154,10 @@ gistindex_keytest(IndexScanDesc scan,
if ( GistPageIsLeaf ( page ) ) /* shouldn't happen */
if ( GistPageIsLeaf ( page ) ) /* shouldn't happen */
elog ( ERROR , " invalid GiST tuple found on leaf page " ) ;
elog ( ERROR , " invalid GiST tuple found on leaf page " ) ;
for ( i = 0 ; i < scan - > numberOfOrderBys ; i + + )
for ( i = 0 ; i < scan - > numberOfOrderBys ; i + + )
so - > distances [ i ] = - get_float8_infinity ( ) ;
{
so - > distanceValues [ i ] = - get_float8_infinity ( ) ;
so - > distanceNulls [ i ] = false ;
}
return true ;
return true ;
}
}
@ -235,7 +240,8 @@ gistindex_keytest(IndexScanDesc scan,
/* OK, it passes --- now let's compute the distances */
/* OK, it passes --- now let's compute the distances */
key = scan - > orderByData ;
key = scan - > orderByData ;
distance_p = so - > distances ;
distance_value_p = so - > distanceValues ;
distance_null_p = so - > distanceNulls ;
keySize = scan - > numberOfOrderBys ;
keySize = scan - > numberOfOrderBys ;
while ( keySize > 0 )
while ( keySize > 0 )
{
{
@ -249,8 +255,9 @@ gistindex_keytest(IndexScanDesc scan,
if ( ( key - > sk_flags & SK_ISNULL ) | | isNull )
if ( ( key - > sk_flags & SK_ISNULL ) | | isNull )
{
{
/* Assume distance computes as null and sorts to the end */
/* Assume distance computes as null */
* distance_p = get_float8_infinity ( ) ;
* distance_value_p = 0.0 ;
* distance_null_p = true ;
}
}
else
else
{
{
@ -287,11 +294,13 @@ gistindex_keytest(IndexScanDesc scan,
ObjectIdGetDatum ( key - > sk_subtype ) ,
ObjectIdGetDatum ( key - > sk_subtype ) ,
PointerGetDatum ( & recheck ) ) ;
PointerGetDatum ( & recheck ) ) ;
* recheck_distances_p | = recheck ;
* recheck_distances_p | = recheck ;
* distance_p = DatumGetFloat8 ( dist ) ;
* distance_value_p = DatumGetFloat8 ( dist ) ;
* distance_null_p = false ;
}
}
key + + ;
key + + ;
distance_p + + ;
distance_value_p + + ;
distance_null_p + + ;
keySize - - ;
keySize - - ;
}
}
@ -304,7 +313,8 @@ gistindex_keytest(IndexScanDesc scan,
*
*
* scan : index scan we are executing
* scan : index scan we are executing
* pageItem : search queue item identifying an index page to scan
* pageItem : search queue item identifying an index page to scan
* myDistances : distances array associated with pageItem , or NULL at the root
* myDistanceValues : distances array associated with pageItem , or NULL at the root
* myDistanceNulls : null flags for myDistanceValues array , or NULL at the root
* tbm : if not NULL , gistgetbitmap ' s output bitmap
* tbm : if not NULL , gistgetbitmap ' s output bitmap
* ntids : if not NULL , gistgetbitmap ' s output tuple counter
* ntids : if not NULL , gistgetbitmap ' s output tuple counter
*
*
@ -321,7 +331,8 @@ gistindex_keytest(IndexScanDesc scan,
* sibling will be processed next .
* sibling will be processed next .
*/
*/
static void
static void
gistScanPage ( IndexScanDesc scan , GISTSearchItem * pageItem , double * myDistances ,
gistScanPage ( IndexScanDesc scan , GISTSearchItem * pageItem ,
double * myDistanceValues , bool * myDistanceNulls ,
TIDBitmap * tbm , int64 * ntids )
TIDBitmap * tbm , int64 * ntids )
{
{
GISTScanOpaque so = ( GISTScanOpaque ) scan - > opaque ;
GISTScanOpaque so = ( GISTScanOpaque ) scan - > opaque ;
@ -359,7 +370,7 @@ gistScanPage(IndexScanDesc scan, GISTSearchItem *pageItem, double *myDistances,
GISTSearchItem * item ;
GISTSearchItem * item ;
/* This can't happen when starting at the root */
/* This can't happen when starting at the root */
Assert ( myDistances ! = NULL ) ;
Assert ( myDistanceValues ! = NULL & & myDistanceNull s ! = NULL ) ;
oldcxt = MemoryContextSwitchTo ( so - > queueCxt ) ;
oldcxt = MemoryContextSwitchTo ( so - > queueCxt ) ;
@ -369,8 +380,10 @@ gistScanPage(IndexScanDesc scan, GISTSearchItem *pageItem, double *myDistances,
item - > data . parentlsn = pageItem - > data . parentlsn ;
item - > data . parentlsn = pageItem - > data . parentlsn ;
/* Insert it into the queue using same distances as for this page */
/* Insert it into the queue using same distances as for this page */
memcpy ( item - > distances , myDistances ,
memcpy ( GISTSearchItemDistanceValues ( item , scan - > numberOfOrderBys ) ,
sizeof ( double ) * scan - > numberOfOrderBys ) ;
myDistanceValues , sizeof ( double ) * scan - > numberOfOrderBys ) ;
memcpy ( GISTSearchItemDistanceNulls ( item , scan - > numberOfOrderBys ) ,
myDistanceNulls , sizeof ( bool ) * scan - > numberOfOrderBys ) ;
pairingheap_add ( so - > queue , & item - > phNode ) ;
pairingheap_add ( so - > queue , & item - > phNode ) ;
@ -479,6 +492,7 @@ gistScanPage(IndexScanDesc scan, GISTSearchItem *pageItem, double *myDistances,
* search .
* search .
*/
*/
GISTSearchItem * item ;
GISTSearchItem * item ;
int nOrderBys = scan - > numberOfOrderBys ;
oldcxt = MemoryContextSwitchTo ( so - > queueCxt ) ;
oldcxt = MemoryContextSwitchTo ( so - > queueCxt ) ;
@ -513,8 +527,10 @@ gistScanPage(IndexScanDesc scan, GISTSearchItem *pageItem, double *myDistances,
}
}
/* Insert it into the queue using new distance data */
/* Insert it into the queue using new distance data */
memcpy ( item - > distances , so - > distances ,
memcpy ( GISTSearchItemDistanceValues ( item , nOrderBys ) ,
sizeof ( double ) * scan - > numberOfOrderBys ) ;
so - > distanceValues , sizeof ( double ) * nOrderBys ) ;
memcpy ( GISTSearchItemDistanceNulls ( item , nOrderBys ) ,
so - > distanceNulls , sizeof ( bool ) * nOrderBys ) ;
pairingheap_add ( so - > queue , & item - > phNode ) ;
pairingheap_add ( so - > queue , & item - > phNode ) ;
@ -579,7 +595,8 @@ getNextNearest(IndexScanDesc scan)
scan - > xs_recheck = item - > data . heap . recheck ;
scan - > xs_recheck = item - > data . heap . recheck ;
index_store_float8_orderby_distances ( scan , so - > orderByTypes ,
index_store_float8_orderby_distances ( scan , so - > orderByTypes ,
item - > distances ,
GISTSearchItemDistanceValues ( item , scan - > numberOfOrderBys ) ,
GISTSearchItemDistanceNulls ( item , scan - > numberOfOrderBys ) ,
item - > data . heap . recheckDistances ) ;
item - > data . heap . recheckDistances ) ;
/* in an index-only scan, also return the reconstructed tuple. */
/* in an index-only scan, also return the reconstructed tuple. */
@ -592,7 +609,10 @@ getNextNearest(IndexScanDesc scan)
/* visit an index page, extract its items into queue */
/* visit an index page, extract its items into queue */
CHECK_FOR_INTERRUPTS ( ) ;
CHECK_FOR_INTERRUPTS ( ) ;
gistScanPage ( scan , item , item - > distances , NULL , NULL ) ;
gistScanPage ( scan , item ,
GISTSearchItemDistanceValues ( item , scan - > numberOfOrderBys ) ,
GISTSearchItemDistanceNulls ( item , scan - > numberOfOrderBys ) ,
NULL , NULL ) ;
}
}
pfree ( item ) ;
pfree ( item ) ;
@ -630,7 +650,7 @@ gistgettuple(IndexScanDesc scan, ScanDirection dir)
fakeItem . blkno = GIST_ROOT_BLKNO ;
fakeItem . blkno = GIST_ROOT_BLKNO ;
memset ( & fakeItem . data . parentlsn , 0 , sizeof ( GistNSN ) ) ;
memset ( & fakeItem . data . parentlsn , 0 , sizeof ( GistNSN ) ) ;
gistScanPage ( scan , & fakeItem , NULL , NULL , NULL ) ;
gistScanPage ( scan , & fakeItem , NULL , NULL , NULL , NULL ) ;
}
}
if ( scan - > numberOfOrderBys > 0 )
if ( scan - > numberOfOrderBys > 0 )
@ -724,7 +744,10 @@ gistgettuple(IndexScanDesc scan, ScanDirection dir)
* this page , we fall out of the inner " do " and loop around to
* this page , we fall out of the inner " do " and loop around to
* return them .
* return them .
*/
*/
gistScanPage ( scan , item , item - > distances , NULL , NULL ) ;
gistScanPage ( scan , item ,
GISTSearchItemDistanceValues ( item , scan - > numberOfOrderBys ) ,
GISTSearchItemDistanceNulls ( item , scan - > numberOfOrderBys ) ,
NULL , NULL ) ;
pfree ( item ) ;
pfree ( item ) ;
} while ( so - > nPageData = = 0 ) ;
} while ( so - > nPageData = = 0 ) ;
@ -755,7 +778,7 @@ gistgetbitmap(IndexScanDesc scan, TIDBitmap *tbm)
fakeItem . blkno = GIST_ROOT_BLKNO ;
fakeItem . blkno = GIST_ROOT_BLKNO ;
memset ( & fakeItem . data . parentlsn , 0 , sizeof ( GistNSN ) ) ;
memset ( & fakeItem . data . parentlsn , 0 , sizeof ( GistNSN ) ) ;
gistScanPage ( scan , & fakeItem , NULL , tbm , & ntids ) ;
gistScanPage ( scan , & fakeItem , NULL , NULL , tbm , & ntids ) ;
/*
/*
* While scanning a leaf page , ItemPointers of matching heap tuples will
* While scanning a leaf page , ItemPointers of matching heap tuples will
@ -770,7 +793,10 @@ gistgetbitmap(IndexScanDesc scan, TIDBitmap *tbm)
CHECK_FOR_INTERRUPTS ( ) ;
CHECK_FOR_INTERRUPTS ( ) ;
gistScanPage ( scan , item , item - > distances , tbm , & ntids ) ;
gistScanPage ( scan , item ,
GISTSearchItemDistanceValues ( item , scan - > numberOfOrderBys ) ,
GISTSearchItemDistanceNulls ( item , scan - > numberOfOrderBys ) ,
tbm , & ntids ) ;
pfree ( item ) ;
pfree ( item ) ;
}
}