@@ -112,8 +112,9 @@ gistkillitems(IndexScanDesc scan)
112112 * Similarly, *recheck_distances_p is set to indicate whether the distances
113113 * need to be rechecked, and it is also ignored for non-leaf entries.
114114 *
115- * If we are doing an ordered scan, so->distances[] is filled with distance
116- * data from the distance() functions before returning success.
115+ * If we are doing an ordered scan, so->distancesValues[] and
116+ * so->distancesNulls[] is filled with distance data from the distance()
117+ * functions before returning success.
117118 *
118119 * We must decompress the key in the IndexTuple before passing it to the
119120 * sk_funcs (which actually are the opclass Consistent or Distance methods).
@@ -134,7 +135,8 @@ gistindex_keytest(IndexScanDesc scan,
134135 GISTSTATE * giststate = so -> giststate ;
135136 ScanKey key = scan -> keyData ;
136137 int keySize = scan -> numberOfKeys ;
137- double * distance_p ;
138+ double * distance_value_p ;
139+ bool * distance_null_p ;
138140 Relation r = scan -> indexRelation ;
139141
140142 * recheck_p = false;
@@ -152,7 +154,10 @@ gistindex_keytest(IndexScanDesc scan,
152154 if (GistPageIsLeaf (page )) /* shouldn't happen */
153155 elog (ERROR , "invalid GiST tuple found on leaf page" );
154156 for (i = 0 ; i < scan -> numberOfOrderBys ; i ++ )
155- so -> distances [i ] = - get_float8_infinity ();
157+ {
158+ so -> distanceValues [i ] = - get_float8_infinity ();
159+ so -> distanceNulls [i ] = false;
160+ }
156161 return true;
157162 }
158163
@@ -235,7 +240,8 @@ gistindex_keytest(IndexScanDesc scan,
235240
236241 /* OK, it passes --- now let's compute the distances */
237242 key = scan -> orderByData ;
238- distance_p = so -> distances ;
243+ distance_value_p = so -> distanceValues ;
244+ distance_null_p = so -> distanceNulls ;
239245 keySize = scan -> numberOfOrderBys ;
240246 while (keySize > 0 )
241247 {
@@ -249,8 +255,9 @@ gistindex_keytest(IndexScanDesc scan,
249255
250256 if ((key -> sk_flags & SK_ISNULL ) || isNull )
251257 {
252- /* Assume distance computes as null and sorts to the end */
253- * distance_p = get_float8_infinity ();
258+ /* Assume distance computes as null */
259+ * distance_value_p = 0.0 ;
260+ * distance_null_p = true;
254261 }
255262 else
256263 {
@@ -287,11 +294,13 @@ gistindex_keytest(IndexScanDesc scan,
287294 ObjectIdGetDatum (key -> sk_subtype ),
288295 PointerGetDatum (& recheck ));
289296 * recheck_distances_p |= recheck ;
290- * distance_p = DatumGetFloat8 (dist );
297+ * distance_value_p = DatumGetFloat8 (dist );
298+ * distance_null_p = false;
291299 }
292300
293301 key ++ ;
294- distance_p ++ ;
302+ distance_value_p ++ ;
303+ distance_null_p ++ ;
295304 keySize -- ;
296305 }
297306
@@ -304,7 +313,8 @@ gistindex_keytest(IndexScanDesc scan,
304313 *
305314 * scan: index scan we are executing
306315 * pageItem: search queue item identifying an index page to scan
307- * myDistances: distances array associated with pageItem, or NULL at the root
316+ * myDistanceValues: distances array associated with pageItem, or NULL at the root
317+ * myDistanceNulls: null flags for myDistanceValues array, or NULL at the root
308318 * tbm: if not NULL, gistgetbitmap's output bitmap
309319 * ntids: if not NULL, gistgetbitmap's output tuple counter
310320 *
@@ -321,7 +331,8 @@ gistindex_keytest(IndexScanDesc scan,
321331 * sibling will be processed next.
322332 */
323333static void
324- gistScanPage (IndexScanDesc scan , GISTSearchItem * pageItem , double * myDistances ,
334+ gistScanPage (IndexScanDesc scan , GISTSearchItem * pageItem ,
335+ double * myDistanceValues , bool * myDistanceNulls ,
325336 TIDBitmap * tbm , int64 * ntids )
326337{
327338 GISTScanOpaque so = (GISTScanOpaque ) scan -> opaque ;
@@ -359,7 +370,7 @@ gistScanPage(IndexScanDesc scan, GISTSearchItem *pageItem, double *myDistances,
359370 GISTSearchItem * item ;
360371
361372 /* This can't happen when starting at the root */
362- Assert (myDistances != NULL );
373+ Assert (myDistanceValues != NULL && myDistanceNulls != NULL );
363374
364375 oldcxt = MemoryContextSwitchTo (so -> queueCxt );
365376
@@ -369,8 +380,10 @@ gistScanPage(IndexScanDesc scan, GISTSearchItem *pageItem, double *myDistances,
369380 item -> data .parentlsn = pageItem -> data .parentlsn ;
370381
371382 /* Insert it into the queue using same distances as for this page */
372- memcpy (item -> distances , myDistances ,
373- sizeof (double ) * scan -> numberOfOrderBys );
383+ memcpy (GISTSearchItemDistanceValues (item , scan -> numberOfOrderBys ),
384+ myDistanceValues , sizeof (double ) * scan -> numberOfOrderBys );
385+ memcpy (GISTSearchItemDistanceNulls (item , scan -> numberOfOrderBys ),
386+ myDistanceNulls , sizeof (bool ) * scan -> numberOfOrderBys );
374387
375388 pairingheap_add (so -> queue , & item -> phNode );
376389
@@ -479,6 +492,7 @@ gistScanPage(IndexScanDesc scan, GISTSearchItem *pageItem, double *myDistances,
479492 * search.
480493 */
481494 GISTSearchItem * item ;
495+ int nOrderBys = scan -> numberOfOrderBys ;
482496
483497 oldcxt = MemoryContextSwitchTo (so -> queueCxt );
484498
@@ -513,8 +527,10 @@ gistScanPage(IndexScanDesc scan, GISTSearchItem *pageItem, double *myDistances,
513527 }
514528
515529 /* Insert it into the queue using new distance data */
516- memcpy (item -> distances , so -> distances ,
517- sizeof (double ) * scan -> numberOfOrderBys );
530+ memcpy (GISTSearchItemDistanceValues (item , nOrderBys ),
531+ so -> distanceValues , sizeof (double ) * nOrderBys );
532+ memcpy (GISTSearchItemDistanceNulls (item , nOrderBys ),
533+ so -> distanceNulls , sizeof (bool ) * nOrderBys );
518534
519535 pairingheap_add (so -> queue , & item -> phNode );
520536
@@ -579,7 +595,8 @@ getNextNearest(IndexScanDesc scan)
579595 scan -> xs_recheck = item -> data .heap .recheck ;
580596
581597 index_store_float8_orderby_distances (scan , so -> orderByTypes ,
582- item -> distances ,
598+ GISTSearchItemDistanceValues (item , scan -> numberOfOrderBys ),
599+ GISTSearchItemDistanceNulls (item , scan -> numberOfOrderBys ),
583600 item -> data .heap .recheckDistances );
584601
585602 /* in an index-only scan, also return the reconstructed tuple. */
@@ -592,7 +609,10 @@ getNextNearest(IndexScanDesc scan)
592609 /* visit an index page, extract its items into queue */
593610 CHECK_FOR_INTERRUPTS ();
594611
595- gistScanPage (scan , item , item -> distances , NULL , NULL );
612+ gistScanPage (scan , item ,
613+ GISTSearchItemDistanceValues (item , scan -> numberOfOrderBys ),
614+ GISTSearchItemDistanceNulls (item , scan -> numberOfOrderBys ),
615+ NULL , NULL );
596616 }
597617
598618 pfree (item );
@@ -630,7 +650,7 @@ gistgettuple(IndexScanDesc scan, ScanDirection dir)
630650
631651 fakeItem .blkno = GIST_ROOT_BLKNO ;
632652 memset (& fakeItem .data .parentlsn , 0 , sizeof (GistNSN ));
633- gistScanPage (scan , & fakeItem , NULL , NULL , NULL );
653+ gistScanPage (scan , & fakeItem , NULL , NULL , NULL , NULL );
634654 }
635655
636656 if (scan -> numberOfOrderBys > 0 )
@@ -724,7 +744,10 @@ gistgettuple(IndexScanDesc scan, ScanDirection dir)
724744 * this page, we fall out of the inner "do" and loop around to
725745 * return them.
726746 */
727- gistScanPage (scan , item , item -> distances , NULL , NULL );
747+ gistScanPage (scan , item ,
748+ GISTSearchItemDistanceValues (item , scan -> numberOfOrderBys ),
749+ GISTSearchItemDistanceNulls (item , scan -> numberOfOrderBys ),
750+ NULL , NULL );
728751
729752 pfree (item );
730753 } while (so -> nPageData == 0 );
@@ -755,7 +778,7 @@ gistgetbitmap(IndexScanDesc scan, TIDBitmap *tbm)
755778
756779 fakeItem .blkno = GIST_ROOT_BLKNO ;
757780 memset (& fakeItem .data .parentlsn , 0 , sizeof (GistNSN ));
758- gistScanPage (scan , & fakeItem , NULL , tbm , & ntids );
781+ gistScanPage (scan , & fakeItem , NULL , NULL , tbm , & ntids );
759782
760783 /*
761784 * While scanning a leaf page, ItemPointers of matching heap tuples will
@@ -770,7 +793,10 @@ gistgetbitmap(IndexScanDesc scan, TIDBitmap *tbm)
770793
771794 CHECK_FOR_INTERRUPTS ();
772795
773- gistScanPage (scan , item , item -> distances , tbm , & ntids );
796+ gistScanPage (scan , item ,
797+ GISTSearchItemDistanceValues (item , scan -> numberOfOrderBys ),
798+ GISTSearchItemDistanceNulls (item , scan -> numberOfOrderBys ),
799+ tbm , & ntids );
774800
775801 pfree (item );
776802 }
0 commit comments