@@ -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,
134135GISTSTATE * giststate = so -> giststate ;
135136ScanKey key = scan -> keyData ;
136137int keySize = scan -> numberOfKeys ;
137- double * distance_p ;
138+ double * distance_value_p ;
139+ bool * distance_null_p ;
138140Relation r = scan -> indexRelation ;
139141
140142* recheck_p = false;
@@ -152,7 +154,10 @@ gistindex_keytest(IndexScanDesc scan,
152154if (GistPageIsLeaf (page ))/* shouldn't happen */
153155elog (ERROR ,"invalid GiST tuple found on leaf page" );
154156for (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+ }
156161return true;
157162}
158163
@@ -235,7 +240,8 @@ gistindex_keytest(IndexScanDesc scan,
235240
236241/* OK, it passes --- now let's compute the distances */
237242key = scan -> orderByData ;
238- distance_p = so -> distances ;
243+ distance_value_p = so -> distanceValues ;
244+ distance_null_p = so -> distanceNulls ;
239245keySize = scan -> numberOfOrderBys ;
240246while (keySize > 0 )
241247{
@@ -249,8 +255,9 @@ gistindex_keytest(IndexScanDesc scan,
249255
250256if ((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}
255262else
256263{
@@ -287,11 +294,13 @@ gistindex_keytest(IndexScanDesc scan,
287294ObjectIdGetDatum (key -> sk_subtype ),
288295PointerGetDatum (& recheck ));
289296* recheck_distances_p |=recheck ;
290- * distance_p = DatumGetFloat8 (dist );
297+ * distance_value_p = DatumGetFloat8 (dist );
298+ * distance_null_p = false;
291299}
292300
293301key ++ ;
294- distance_p ++ ;
302+ distance_value_p ++ ;
303+ distance_null_p ++ ;
295304keySize -- ;
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 ,
325336TIDBitmap * tbm ,int64 * ntids )
326337{
327338GISTScanOpaque so = (GISTScanOpaque )scan -> opaque ;
@@ -359,7 +370,7 @@ gistScanPage(IndexScanDesc scan, GISTSearchItem *pageItem, double *myDistances,
359370GISTSearchItem * item ;
360371
361372/* This can't happen when starting at the root */
362- Assert (myDistances != NULL );
373+ Assert (myDistanceValues != NULL && myDistanceNulls != NULL );
363374
364375oldcxt = MemoryContextSwitchTo (so -> queueCxt );
365376
@@ -369,8 +380,10 @@ gistScanPage(IndexScanDesc scan, GISTSearchItem *pageItem, double *myDistances,
369380item -> 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
375388pairingheap_add (so -> queue ,& item -> phNode );
376389
@@ -465,6 +478,7 @@ gistScanPage(IndexScanDesc scan, GISTSearchItem *pageItem, double *myDistances,
465478 * search.
466479 */
467480GISTSearchItem * item ;
481+ int nOrderBys = scan -> numberOfOrderBys ;
468482
469483oldcxt = MemoryContextSwitchTo (so -> queueCxt );
470484
@@ -499,8 +513,10 @@ gistScanPage(IndexScanDesc scan, GISTSearchItem *pageItem, double *myDistances,
499513}
500514
501515/* Insert it into the queue using new distance data */
502- memcpy (item -> distances ,so -> distances ,
503- sizeof (double )* scan -> numberOfOrderBys );
516+ memcpy (GISTSearchItemDistanceValues (item ,nOrderBys ),
517+ so -> distanceValues ,sizeof (double )* nOrderBys );
518+ memcpy (GISTSearchItemDistanceNulls (item ,nOrderBys ),
519+ so -> distanceNulls ,sizeof (bool )* nOrderBys );
504520
505521pairingheap_add (so -> queue ,& item -> phNode );
506522
@@ -555,6 +571,8 @@ getNextNearest(IndexScanDesc scan)
555571do
556572{
557573GISTSearchItem * item = getNextGISTSearchItem (so );
574+ float8 * distanceValues = GISTSearchItemDistanceValues (item ,scan -> numberOfOrderBys );
575+ bool * distanceNulls = GISTSearchItemDistanceNulls (item ,scan -> numberOfOrderBys );
558576
559577if (!item )
560578break ;
@@ -574,8 +592,8 @@ getNextNearest(IndexScanDesc scan)
574592if (!scan -> xs_orderbynulls [i ])
575593pfree (DatumGetPointer (scan -> xs_orderbyvals [i ]));
576594#endif
577- scan -> xs_orderbyvals [i ]= Float8GetDatum (item -> distances [i ]);
578- scan -> xs_orderbynulls [i ]= false ;
595+ scan -> xs_orderbyvals [i ]= Float8GetDatum (distanceValues [i ]);
596+ scan -> xs_orderbynulls [i ]= distanceNulls [ i ] ;
579597}
580598else if (so -> orderByTypes [i ]== FLOAT4OID )
581599{
@@ -585,8 +603,8 @@ getNextNearest(IndexScanDesc scan)
585603if (!scan -> xs_orderbynulls [i ])
586604pfree (DatumGetPointer (scan -> xs_orderbyvals [i ]));
587605#endif
588- scan -> xs_orderbyvals [i ]= Float4GetDatum (( float4 ) item -> distances [i ]);
589- scan -> xs_orderbynulls [i ]= false ;
606+ scan -> xs_orderbyvals [i ]= Float4GetDatum (distanceValues [i ]);
607+ scan -> xs_orderbynulls [i ]= distanceNulls [ i ] ;
590608}
591609else
592610{
@@ -614,7 +632,10 @@ getNextNearest(IndexScanDesc scan)
614632/* visit an index page, extract its items into queue */
615633CHECK_FOR_INTERRUPTS ();
616634
617- gistScanPage (scan ,item ,item -> distances ,NULL ,NULL );
635+ gistScanPage (scan ,item ,
636+ GISTSearchItemDistanceValues (item ,scan -> numberOfOrderBys ),
637+ GISTSearchItemDistanceNulls (item ,scan -> numberOfOrderBys ),
638+ NULL ,NULL );
618639}
619640
620641pfree (item );
@@ -652,7 +673,7 @@ gistgettuple(IndexScanDesc scan, ScanDirection dir)
652673
653674fakeItem .blkno = GIST_ROOT_BLKNO ;
654675memset (& fakeItem .data .parentlsn ,0 ,sizeof (GistNSN ));
655- gistScanPage (scan ,& fakeItem ,NULL ,NULL ,NULL );
676+ gistScanPage (scan ,& fakeItem ,NULL ,NULL ,NULL , NULL );
656677}
657678
658679if (scan -> numberOfOrderBys > 0 )
@@ -746,7 +767,10 @@ gistgettuple(IndexScanDesc scan, ScanDirection dir)
746767 * this page, we fall out of the inner "do" and loop around to
747768 * return them.
748769 */
749- gistScanPage (scan ,item ,item -> distances ,NULL ,NULL );
770+ gistScanPage (scan ,item ,
771+ GISTSearchItemDistanceValues (item ,scan -> numberOfOrderBys ),
772+ GISTSearchItemDistanceNulls (item ,scan -> numberOfOrderBys ),
773+ NULL ,NULL );
750774
751775pfree (item );
752776}while (so -> nPageData == 0 );
@@ -777,7 +801,7 @@ gistgetbitmap(IndexScanDesc scan, TIDBitmap *tbm)
777801
778802fakeItem .blkno = GIST_ROOT_BLKNO ;
779803memset (& fakeItem .data .parentlsn ,0 ,sizeof (GistNSN ));
780- gistScanPage (scan ,& fakeItem ,NULL ,tbm ,& ntids );
804+ gistScanPage (scan ,& fakeItem ,NULL ,NULL , tbm ,& ntids );
781805
782806/*
783807 * While scanning a leaf page, ItemPointers of matching heap tuples will
@@ -792,7 +816,10 @@ gistgetbitmap(IndexScanDesc scan, TIDBitmap *tbm)
792816
793817CHECK_FOR_INTERRUPTS ();
794818
795- gistScanPage (scan ,item ,item -> distances ,tbm ,& ntids );
819+ gistScanPage (scan ,item ,
820+ GISTSearchItemDistanceValues (item ,scan -> numberOfOrderBys ),
821+ GISTSearchItemDistanceNulls (item ,scan -> numberOfOrderBys ),
822+ tbm ,& ntids );
796823
797824pfree (item );
798825}