34
34
* request it. recheck is not interesting when examining a non-leaf entry,
35
35
* since we must visit the lower index page if there's any doubt.
36
36
*
37
- * If we are doing an ordered scan, so->distances[] is filled with distance
38
- * data from the distance() functions before returning success.
37
+ * If we are doing an ordered scan, so->distancesValues[] and
38
+ * so->distancesNulls[] is filled with distance data from the distance()
39
+ * functions before returning success.
39
40
*
40
41
* We must decompress the key in the IndexTuple before passing it to the
41
42
* sk_funcs (which actually are the opclass Consistent or Distance methods).
@@ -55,7 +56,8 @@ gistindex_keytest(IndexScanDesc scan,
55
56
GISTSTATE * giststate = so -> giststate ;
56
57
ScanKey key = scan -> keyData ;
57
58
int keySize = scan -> numberOfKeys ;
58
- double * distance_p ;
59
+ double * distance_value_p ;
60
+ bool * distance_null_p ;
59
61
Relation r = scan -> indexRelation ;
60
62
61
63
* recheck_p = false;
@@ -72,7 +74,10 @@ gistindex_keytest(IndexScanDesc scan,
72
74
if (GistPageIsLeaf (page )) /* shouldn't happen */
73
75
elog (ERROR , "invalid GiST tuple found on leaf page" );
74
76
for (i = 0 ; i < scan -> numberOfOrderBys ; i ++ )
75
- so -> distances [i ] = - get_float8_infinity ();
77
+ {
78
+ so -> distanceValues [i ] = - get_float8_infinity ();
79
+ so -> distanceNulls [i ] = false;
80
+ }
76
81
return true;
77
82
}
78
83
@@ -155,7 +160,8 @@ gistindex_keytest(IndexScanDesc scan,
155
160
156
161
/* OK, it passes --- now let's compute the distances */
157
162
key = scan -> orderByData ;
158
- distance_p = so -> distances ;
163
+ distance_value_p = so -> distanceValues ;
164
+ distance_null_p = so -> distanceNulls ;
159
165
keySize = scan -> numberOfOrderBys ;
160
166
while (keySize > 0 )
161
167
{
@@ -169,8 +175,9 @@ gistindex_keytest(IndexScanDesc scan,
169
175
170
176
if ((key -> sk_flags & SK_ISNULL ) || isNull )
171
177
{
172
- /* Assume distance computes as null and sorts to the end */
173
- * distance_p = get_float8_infinity ();
178
+ /* Assume distance computes as null */
179
+ * distance_value_p = 0.0 ;
180
+ * distance_null_p = true;
174
181
}
175
182
else
176
183
{
@@ -199,14 +206,15 @@ gistindex_keytest(IndexScanDesc scan,
199
206
key -> sk_collation ,
200
207
PointerGetDatum (& de ),
201
208
key -> sk_argument ,
202
- Int32GetDatum (key -> sk_strategy ),
209
+ Int16GetDatum (key -> sk_strategy ),
203
210
ObjectIdGetDatum (key -> sk_subtype ));
204
-
205
- * distance_p = DatumGetFloat8 ( dist ) ;
211
+ * distance_value_p = DatumGetFloat8 ( dist );
212
+ * distance_null_p = false ;
206
213
}
207
214
208
215
key ++ ;
209
- distance_p ++ ;
216
+ distance_value_p ++ ;
217
+ distance_null_p ++ ;
210
218
keySize -- ;
211
219
}
212
220
@@ -219,7 +227,8 @@ gistindex_keytest(IndexScanDesc scan,
219
227
*
220
228
* scan: index scan we are executing
221
229
* pageItem: search queue item identifying an index page to scan
222
- * myDistances: distances array associated with pageItem, or NULL at the root
230
+ * myDistanceValues: distances array associated with pageItem, or NULL at the root
231
+ * myDistanceNulls: null flags for myDistanceValues array, or NULL at the root
223
232
* tbm: if not NULL, gistgetbitmap's output bitmap
224
233
* ntids: if not NULL, gistgetbitmap's output tuple counter
225
234
*
@@ -234,7 +243,8 @@ gistindex_keytest(IndexScanDesc scan,
234
243
* sibling will be processed next.
235
244
*/
236
245
static void
237
- gistScanPage (IndexScanDesc scan , GISTSearchItem * pageItem , double * myDistances ,
246
+ gistScanPage (IndexScanDesc scan , GISTSearchItem * pageItem ,
247
+ double * myDistanceValues , bool * myDistanceNulls ,
238
248
TIDBitmap * tbm , int64 * ntids )
239
249
{
240
250
GISTScanOpaque so = (GISTScanOpaque ) scan -> opaque ;
@@ -270,7 +280,7 @@ gistScanPage(IndexScanDesc scan, GISTSearchItem *pageItem, double *myDistances,
270
280
GISTSearchItem * item ;
271
281
272
282
/* This can't happen when starting at the root */
273
- Assert (myDistances != NULL );
283
+ Assert (myDistanceValues != NULL && myDistanceNulls != NULL );
274
284
275
285
oldcxt = MemoryContextSwitchTo (so -> queueCxt );
276
286
@@ -283,8 +293,10 @@ gistScanPage(IndexScanDesc scan, GISTSearchItem *pageItem, double *myDistances,
283
293
/* Insert it into the queue using same distances as for this page */
284
294
tmpItem -> head = item ;
285
295
tmpItem -> lastHeap = NULL ;
286
- memcpy (tmpItem -> distances , myDistances ,
287
- sizeof (double ) * scan -> numberOfOrderBys );
296
+ memcpy (GISTSearchTreeItemDistanceValues (tmpItem , scan -> numberOfOrderBys ),
297
+ myDistanceValues , sizeof (double ) * scan -> numberOfOrderBys );
298
+ memcpy (GISTSearchTreeItemDistanceNulls (tmpItem , scan -> numberOfOrderBys ),
299
+ myDistanceNulls , sizeof (bool ) * scan -> numberOfOrderBys );
288
300
289
301
(void ) rb_insert (so -> queue , (RBNode * ) tmpItem , & isNew );
290
302
@@ -344,6 +356,7 @@ gistScanPage(IndexScanDesc scan, GISTSearchItem *pageItem, double *myDistances,
344
356
* search.
345
357
*/
346
358
GISTSearchItem * item ;
359
+ int nOrderBys = scan -> numberOfOrderBys ;
347
360
348
361
oldcxt = MemoryContextSwitchTo (so -> queueCxt );
349
362
@@ -374,8 +387,10 @@ gistScanPage(IndexScanDesc scan, GISTSearchItem *pageItem, double *myDistances,
374
387
/* Insert it into the queue using new distance data */
375
388
tmpItem -> head = item ;
376
389
tmpItem -> lastHeap = GISTSearchItemIsHeap (* item ) ? item : NULL ;
377
- memcpy (tmpItem -> distances , so -> distances ,
378
- sizeof (double ) * scan -> numberOfOrderBys );
390
+ memcpy (GISTSearchTreeItemDistanceValues (tmpItem , nOrderBys ),
391
+ so -> distanceValues , sizeof (double ) * nOrderBys );
392
+ memcpy (GISTSearchTreeItemDistanceNulls (tmpItem , nOrderBys ),
393
+ so -> distanceNulls , sizeof (bool ) * nOrderBys );
379
394
380
395
(void ) rb_insert (so -> queue , (RBNode * ) tmpItem , & isNew );
381
396
@@ -458,7 +473,10 @@ getNextNearest(IndexScanDesc scan)
458
473
/* visit an index page, extract its items into queue */
459
474
CHECK_FOR_INTERRUPTS ();
460
475
461
- gistScanPage (scan , item , so -> curTreeItem -> distances , NULL , NULL );
476
+ gistScanPage (scan , item ,
477
+ GISTSearchTreeItemDistanceValues (so -> curTreeItem , scan -> numberOfOrderBys ),
478
+ GISTSearchTreeItemDistanceNulls (so -> curTreeItem , scan -> numberOfOrderBys ),
479
+ NULL , NULL );
462
480
}
463
481
464
482
pfree (item );
@@ -496,7 +514,7 @@ gistgettuple(PG_FUNCTION_ARGS)
496
514
497
515
fakeItem .blkno = GIST_ROOT_BLKNO ;
498
516
memset (& fakeItem .data .parentlsn , 0 , sizeof (GistNSN ));
499
- gistScanPage (scan , & fakeItem , NULL , NULL , NULL );
517
+ gistScanPage (scan , & fakeItem , NULL , NULL , NULL , NULL );
500
518
}
501
519
502
520
if (scan -> numberOfOrderBys > 0 )
@@ -534,7 +552,10 @@ gistgettuple(PG_FUNCTION_ARGS)
534
552
* this page, we fall out of the inner "do" and loop around to
535
553
* return them.
536
554
*/
537
- gistScanPage (scan , item , so -> curTreeItem -> distances , NULL , NULL );
555
+ gistScanPage (scan , item ,
556
+ GISTSearchTreeItemDistanceValues (so -> curTreeItem , scan -> numberOfOrderBys ),
557
+ GISTSearchTreeItemDistanceNulls (so -> curTreeItem , scan -> numberOfOrderBys ),
558
+ NULL , NULL );
538
559
539
560
pfree (item );
540
561
} while (so -> nPageData == 0 );
@@ -565,7 +586,7 @@ gistgetbitmap(PG_FUNCTION_ARGS)
565
586
566
587
fakeItem .blkno = GIST_ROOT_BLKNO ;
567
588
memset (& fakeItem .data .parentlsn , 0 , sizeof (GistNSN ));
568
- gistScanPage (scan , & fakeItem , NULL , tbm , & ntids );
589
+ gistScanPage (scan , & fakeItem , NULL , NULL , tbm , & ntids );
569
590
570
591
/*
571
592
* While scanning a leaf page, ItemPointers of matching heap tuples will
@@ -580,7 +601,10 @@ gistgetbitmap(PG_FUNCTION_ARGS)
580
601
581
602
CHECK_FOR_INTERRUPTS ();
582
603
583
- gistScanPage (scan , item , so -> curTreeItem -> distances , tbm , & ntids );
604
+ gistScanPage (scan , item ,
605
+ GISTSearchTreeItemDistanceValues (so -> curTreeItem , scan -> numberOfOrderBys ),
606
+ GISTSearchTreeItemDistanceNulls (so -> curTreeItem , scan -> numberOfOrderBys ),
607
+ tbm , & ntids );
584
608
585
609
pfree (item );
586
610
}
0 commit comments