@@ -110,8 +110,9 @@ gistkillitems(IndexScanDesc scan)
110110 * Similarly, *recheck_distances_p is set to indicate whether the distances
111111 * need to be rechecked, and it is also ignored for non-leaf entries.
112112 *
113- * If we are doing an ordered scan, so->distances[] is filled with distance
114- * data from the distance() functions before returning success.
113+ * If we are doing an ordered scan, so->distancesValues[] and
114+ * so->distancesNulls[] is filled with distance data from the distance()
115+ * functions before returning success.
115116 *
116117 * We must decompress the key in the IndexTuple before passing it to the
117118 * sk_funcs (which actually are the opclass Consistent or Distance methods).
@@ -132,7 +133,8 @@ gistindex_keytest(IndexScanDesc scan,
132133GISTSTATE * giststate = so -> giststate ;
133134ScanKey key = scan -> keyData ;
134135int keySize = scan -> numberOfKeys ;
135- double * distance_p ;
136+ double * distance_value_p ;
137+ bool * distance_null_p ;
136138Relation r = scan -> indexRelation ;
137139
138140* recheck_p = false;
@@ -150,7 +152,10 @@ gistindex_keytest(IndexScanDesc scan,
150152if (GistPageIsLeaf (page ))/* shouldn't happen */
151153elog (ERROR ,"invalid GiST tuple found on leaf page" );
152154for (i = 0 ;i < scan -> numberOfOrderBys ;i ++ )
153- so -> distances [i ]= - get_float8_infinity ();
155+ {
156+ so -> distanceValues [i ]= - get_float8_infinity ();
157+ so -> distanceNulls [i ]= false;
158+ }
154159return true;
155160}
156161
@@ -233,7 +238,8 @@ gistindex_keytest(IndexScanDesc scan,
233238
234239/* OK, it passes --- now let's compute the distances */
235240key = scan -> orderByData ;
236- distance_p = so -> distances ;
241+ distance_value_p = so -> distanceValues ;
242+ distance_null_p = so -> distanceNulls ;
237243keySize = scan -> numberOfOrderBys ;
238244while (keySize > 0 )
239245{
@@ -247,8 +253,9 @@ gistindex_keytest(IndexScanDesc scan,
247253
248254if ((key -> sk_flags & SK_ISNULL )|| isNull )
249255{
250- /* Assume distance computes as null and sorts to the end */
251- * distance_p = get_float8_infinity ();
256+ /* Assume distance computes as null */
257+ * distance_value_p = 0.0 ;
258+ * distance_null_p = true;
252259}
253260else
254261{
@@ -285,11 +292,13 @@ gistindex_keytest(IndexScanDesc scan,
285292ObjectIdGetDatum (key -> sk_subtype ),
286293PointerGetDatum (& recheck ));
287294* recheck_distances_p |=recheck ;
288- * distance_p = DatumGetFloat8 (dist );
295+ * distance_value_p = DatumGetFloat8 (dist );
296+ * distance_null_p = false;
289297}
290298
291299key ++ ;
292- distance_p ++ ;
300+ distance_value_p ++ ;
301+ distance_null_p ++ ;
293302keySize -- ;
294303}
295304
@@ -302,7 +311,8 @@ gistindex_keytest(IndexScanDesc scan,
302311 *
303312 * scan: index scan we are executing
304313 * pageItem: search queue item identifying an index page to scan
305- * myDistances: distances array associated with pageItem, or NULL at the root
314+ * myDistanceValues: distances array associated with pageItem, or NULL at the root
315+ * myDistanceNulls: null flags for myDistanceValues array, or NULL at the root
306316 * tbm: if not NULL, gistgetbitmap's output bitmap
307317 * ntids: if not NULL, gistgetbitmap's output tuple counter
308318 *
@@ -319,7 +329,8 @@ gistindex_keytest(IndexScanDesc scan,
319329 * sibling will be processed next.
320330 */
321331static void
322- gistScanPage (IndexScanDesc scan ,GISTSearchItem * pageItem ,double * myDistances ,
332+ gistScanPage (IndexScanDesc scan ,GISTSearchItem * pageItem ,
333+ double * myDistanceValues ,bool * myDistanceNulls ,
323334TIDBitmap * tbm ,int64 * ntids )
324335{
325336GISTScanOpaque so = (GISTScanOpaque )scan -> opaque ;
@@ -356,7 +367,7 @@ gistScanPage(IndexScanDesc scan, GISTSearchItem *pageItem, double *myDistances,
356367GISTSearchItem * item ;
357368
358369/* This can't happen when starting at the root */
359- Assert (myDistances != NULL );
370+ Assert (myDistanceValues != NULL && myDistanceNulls != NULL );
360371
361372oldcxt = MemoryContextSwitchTo (so -> queueCxt );
362373
@@ -366,8 +377,10 @@ gistScanPage(IndexScanDesc scan, GISTSearchItem *pageItem, double *myDistances,
366377item -> data .parentlsn = pageItem -> data .parentlsn ;
367378
368379/* Insert it into the queue using same distances as for this page */
369- memcpy (item -> distances ,myDistances ,
370- sizeof (double )* scan -> numberOfOrderBys );
380+ memcpy (GISTSearchItemDistanceValues (item ,scan -> numberOfOrderBys ),
381+ myDistanceValues ,sizeof (double )* scan -> numberOfOrderBys );
382+ memcpy (GISTSearchItemDistanceNulls (item ,scan -> numberOfOrderBys ),
383+ myDistanceNulls ,sizeof (bool )* scan -> numberOfOrderBys );
371384
372385pairingheap_add (so -> queue ,& item -> phNode );
373386
@@ -462,6 +475,7 @@ gistScanPage(IndexScanDesc scan, GISTSearchItem *pageItem, double *myDistances,
462475 * search.
463476 */
464477GISTSearchItem * item ;
478+ int nOrderBys = scan -> numberOfOrderBys ;
465479
466480oldcxt = MemoryContextSwitchTo (so -> queueCxt );
467481
@@ -496,8 +510,10 @@ gistScanPage(IndexScanDesc scan, GISTSearchItem *pageItem, double *myDistances,
496510}
497511
498512/* Insert it into the queue using new distance data */
499- memcpy (item -> distances ,so -> distances ,
500- sizeof (double )* scan -> numberOfOrderBys );
513+ memcpy (GISTSearchItemDistanceValues (item ,nOrderBys ),
514+ so -> distanceValues ,sizeof (double )* nOrderBys );
515+ memcpy (GISTSearchItemDistanceNulls (item ,nOrderBys ),
516+ so -> distanceNulls ,sizeof (bool )* nOrderBys );
501517
502518pairingheap_add (so -> queue ,& item -> phNode );
503519
@@ -552,6 +568,8 @@ getNextNearest(IndexScanDesc scan)
552568do
553569{
554570GISTSearchItem * item = getNextGISTSearchItem (so );
571+ float8 * distanceValues = GISTSearchItemDistanceValues (item ,scan -> numberOfOrderBys );
572+ bool * distanceNulls = GISTSearchItemDistanceNulls (item ,scan -> numberOfOrderBys );
555573
556574if (!item )
557575break ;
@@ -571,8 +589,8 @@ getNextNearest(IndexScanDesc scan)
571589if (!scan -> xs_orderbynulls [i ])
572590pfree (DatumGetPointer (scan -> xs_orderbyvals [i ]));
573591#endif
574- scan -> xs_orderbyvals [i ]= Float8GetDatum (item -> distances [i ]);
575- scan -> xs_orderbynulls [i ]= false ;
592+ scan -> xs_orderbyvals [i ]= Float8GetDatum (distanceValues [i ]);
593+ scan -> xs_orderbynulls [i ]= distanceNulls [ i ] ;
576594}
577595else if (so -> orderByTypes [i ]== FLOAT4OID )
578596{
@@ -582,8 +600,8 @@ getNextNearest(IndexScanDesc scan)
582600if (!scan -> xs_orderbynulls [i ])
583601pfree (DatumGetPointer (scan -> xs_orderbyvals [i ]));
584602#endif
585- scan -> xs_orderbyvals [i ]= Float4GetDatum (( float4 ) item -> distances [i ]);
586- scan -> xs_orderbynulls [i ]= false ;
603+ scan -> xs_orderbyvals [i ]= Float4GetDatum (distanceValues [i ]);
604+ scan -> xs_orderbynulls [i ]= distanceNulls [ i ] ;
587605}
588606else
589607{
@@ -611,7 +629,10 @@ getNextNearest(IndexScanDesc scan)
611629/* visit an index page, extract its items into queue */
612630CHECK_FOR_INTERRUPTS ();
613631
614- gistScanPage (scan ,item ,item -> distances ,NULL ,NULL );
632+ gistScanPage (scan ,item ,
633+ GISTSearchItemDistanceValues (item ,scan -> numberOfOrderBys ),
634+ GISTSearchItemDistanceNulls (item ,scan -> numberOfOrderBys ),
635+ NULL ,NULL );
615636}
616637
617638pfree (item );
@@ -649,7 +670,7 @@ gistgettuple(IndexScanDesc scan, ScanDirection dir)
649670
650671fakeItem .blkno = GIST_ROOT_BLKNO ;
651672memset (& fakeItem .data .parentlsn ,0 ,sizeof (GistNSN ));
652- gistScanPage (scan ,& fakeItem ,NULL ,NULL ,NULL );
673+ gistScanPage (scan ,& fakeItem ,NULL ,NULL ,NULL , NULL );
653674}
654675
655676if (scan -> numberOfOrderBys > 0 )
@@ -743,7 +764,10 @@ gistgettuple(IndexScanDesc scan, ScanDirection dir)
743764 * this page, we fall out of the inner "do" and loop around to
744765 * return them.
745766 */
746- gistScanPage (scan ,item ,item -> distances ,NULL ,NULL );
767+ gistScanPage (scan ,item ,
768+ GISTSearchItemDistanceValues (item ,scan -> numberOfOrderBys ),
769+ GISTSearchItemDistanceNulls (item ,scan -> numberOfOrderBys ),
770+ NULL ,NULL );
747771
748772pfree (item );
749773}while (so -> nPageData == 0 );
@@ -774,7 +798,7 @@ gistgetbitmap(IndexScanDesc scan, TIDBitmap *tbm)
774798
775799fakeItem .blkno = GIST_ROOT_BLKNO ;
776800memset (& fakeItem .data .parentlsn ,0 ,sizeof (GistNSN ));
777- gistScanPage (scan ,& fakeItem ,NULL ,tbm ,& ntids );
801+ gistScanPage (scan ,& fakeItem ,NULL ,NULL , tbm ,& ntids );
778802
779803/*
780804 * While scanning a leaf page, ItemPointers of matching heap tuples will
@@ -789,7 +813,10 @@ gistgetbitmap(IndexScanDesc scan, TIDBitmap *tbm)
789813
790814CHECK_FOR_INTERRUPTS ();
791815
792- gistScanPage (scan ,item ,item -> distances ,tbm ,& ntids );
816+ gistScanPage (scan ,item ,
817+ GISTSearchItemDistanceValues (item ,scan -> numberOfOrderBys ),
818+ GISTSearchItemDistanceNulls (item ,scan -> numberOfOrderBys ),
819+ tbm ,& ntids );
793820
794821pfree (item );
795822}