Age Owner Branch data TLA Line data Source code
1 : : /*
2 : : * contrib/intarray/_intbig_gist.c
3 : : */
4 : : #include "postgres.h"
5 : :
6 : : #include <math.h>
7 : :
8 : : #include "_int.h"
9 : : #include "access/gist.h"
10 : : #include "access/reloptions.h"
11 : : #include "access/stratnum.h"
12 : : #include "common/int.h"
13 : : #include "port/pg_bitutils.h"
14 : :
15 : : #define GETENTRY(vec,pos) ((GISTTYPE *) DatumGetPointer((vec)->vector[(pos)].key))
16 : : /*
17 : : ** _intbig methods
18 : : */
8123 bruce@momjian.us 19 :CBC 2 : PG_FUNCTION_INFO_V1(g_intbig_consistent);
20 : 2 : PG_FUNCTION_INFO_V1(g_intbig_compress);
21 : 2 : PG_FUNCTION_INFO_V1(g_intbig_decompress);
22 : 2 : PG_FUNCTION_INFO_V1(g_intbig_penalty);
23 : 2 : PG_FUNCTION_INFO_V1(g_intbig_picksplit);
24 : 2 : PG_FUNCTION_INFO_V1(g_intbig_union);
25 : 2 : PG_FUNCTION_INFO_V1(g_intbig_same);
1986 akorotkov@postgresql 26 : 2 : PG_FUNCTION_INFO_V1(g_intbig_options);
27 : :
8123 bruce@momjian.us 28 : 1 : PG_FUNCTION_INFO_V1(_intbig_in);
29 : 1 : PG_FUNCTION_INFO_V1(_intbig_out);
30 : :
31 : : Datum
7678 bruce@momjian.us 32 :UBC 0 : _intbig_in(PG_FUNCTION_ARGS)
33 : : {
34 [ # # ]: 0 : ereport(ERROR,
35 : : (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
36 : : errmsg("cannot accept a value of type %s", "intbig_gkey")));
37 : :
38 : : PG_RETURN_VOID(); /* keep compiler quiet */
39 : : }
40 : :
41 : : Datum
42 : 0 : _intbig_out(PG_FUNCTION_ARGS)
43 : : {
44 [ # # ]: 0 : ereport(ERROR,
45 : : (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
46 : : errmsg("cannot display a value of type %s", "intbig_gkey")));
47 : :
48 : : PG_RETURN_VOID(); /* keep compiler quiet */
49 : : }
50 : :
51 : : static GISTTYPE *
1986 akorotkov@postgresql 52 :CBC 85980 : _intbig_alloc(bool allistrue, int siglen, BITVECP sign)
53 : : {
54 [ - + ]: 85980 : int flag = allistrue ? ALLISTRUE : 0;
55 [ + - ]: 85980 : int size = CALCGTSIZE(flag, siglen);
56 : 85980 : GISTTYPE *res = (GISTTYPE *) palloc(size);
57 : :
58 : 85980 : SET_VARSIZE(res, size);
59 : 85980 : res->flag = flag;
60 : :
61 [ + - ]: 85980 : if (!allistrue)
62 : : {
63 [ + + ]: 85980 : if (sign)
64 : 9050 : memcpy(GETSIGN(res), sign, siglen);
65 : : else
66 : 76930 : memset(GETSIGN(res), 0, siglen);
67 : : }
68 : :
69 : 85980 : return res;
70 : : }
71 : :
72 : :
73 : : /*********************************************************************
74 : : ** intbig functions
75 : : *********************************************************************/
76 : : static bool
77 : 7296 : _intbig_overlap(GISTTYPE *a, ArrayType *b, int siglen)
78 : : {
7678 bruce@momjian.us 79 : 7296 : int num = ARRNELEMS(b);
4821 peter_e@gmx.net 80 [ - + ]: 7296 : int32 *ptr = ARRPTR(b);
81 : :
7231 tgl@sss.pgh.pa.us 82 [ - + - - : 7296 : CHECKARRVALID(b);
- - ]
83 : :
7678 bruce@momjian.us 84 [ + + ]: 18594 : while (num--)
85 : : {
1986 akorotkov@postgresql 86 [ + + ]: 13373 : if (GETBIT(GETSIGN(a), HASHVAL(*ptr, siglen)))
8123 bruce@momjian.us 87 : 2075 : return true;
88 : 11298 : ptr++;
89 : : }
90 : :
91 : 5221 : return false;
92 : : }
93 : :
94 : : static bool
1986 akorotkov@postgresql 95 : 9537 : _intbig_contains(GISTTYPE *a, ArrayType *b, int siglen)
96 : : {
7678 bruce@momjian.us 97 : 9537 : int num = ARRNELEMS(b);
4821 peter_e@gmx.net 98 [ - + ]: 9537 : int32 *ptr = ARRPTR(b);
99 : :
7231 tgl@sss.pgh.pa.us 100 [ - + - - : 9537 : CHECKARRVALID(b);
- - ]
101 : :
7678 bruce@momjian.us 102 [ + + ]: 14283 : while (num--)
103 : : {
1986 akorotkov@postgresql 104 [ + + ]: 12705 : if (!GETBIT(GETSIGN(a), HASHVAL(*ptr, siglen)))
8123 bruce@momjian.us 105 : 7959 : return false;
106 : 4746 : ptr++;
107 : : }
108 : :
109 : 1578 : return true;
110 : : }
111 : :
112 : : Datum
7678 113 : 63200 : g_intbig_same(PG_FUNCTION_ARGS)
114 : : {
8123 115 : 63200 : GISTTYPE *a = (GISTTYPE *) PG_GETARG_POINTER(0);
116 : 63200 : GISTTYPE *b = (GISTTYPE *) PG_GETARG_POINTER(1);
7678 117 : 63200 : bool *result = (bool *) PG_GETARG_POINTER(2);
1986 akorotkov@postgresql 118 [ + - ]: 63200 : int siglen = GET_SIGLEN();
119 : :
8123 bruce@momjian.us 120 [ - + - - ]: 63200 : if (ISALLTRUE(a) && ISALLTRUE(b))
8123 bruce@momjian.us 121 :UBC 0 : *result = true;
8123 bruce@momjian.us 122 [ - + ]:CBC 63200 : else if (ISALLTRUE(a))
8123 bruce@momjian.us 123 :UBC 0 : *result = false;
8123 bruce@momjian.us 124 [ - + ]:CBC 63200 : else if (ISALLTRUE(b))
8123 bruce@momjian.us 125 :UBC 0 : *result = false;
126 : : else
127 : : {
128 : : int32 i;
7678 bruce@momjian.us 129 :CBC 63200 : BITVECP sa = GETSIGN(a),
130 : 63200 : sb = GETSIGN(b);
131 : :
8123 132 : 63200 : *result = true;
1986 akorotkov@postgresql 133 [ + + ]: 46945620 : LOOPBYTE(siglen)
134 : : {
6504 bruce@momjian.us 135 [ + + ]: 46917049 : if (sa[i] != sb[i])
136 : : {
137 : 34629 : *result = false;
138 : 34629 : break;
139 : : }
140 : : }
141 : : }
8123 142 : 63200 : PG_RETURN_POINTER(result);
143 : : }
144 : :
145 : : Datum
146 : 57203 : g_intbig_compress(PG_FUNCTION_ARGS)
147 : : {
148 : 57203 : GISTENTRY *entry = (GISTENTRY *) PG_GETARG_POINTER(0);
1986 akorotkov@postgresql 149 [ + - ]: 57203 : int siglen = GET_SIGLEN();
150 : :
7678 bruce@momjian.us 151 [ + + ]: 57203 : if (entry->leafkey)
152 : : {
153 : : GISTENTRY *retval;
5354 tgl@sss.pgh.pa.us 154 : 13514 : ArrayType *in = DatumGetArrayTypeP(entry->key);
155 : : int32 *ptr;
156 : : int num;
1986 akorotkov@postgresql 157 : 13514 : GISTTYPE *res = _intbig_alloc(false, siglen, NULL);
158 : :
7231 tgl@sss.pgh.pa.us 159 [ - + - - : 13514 : CHECKARRVALID(in);
- - ]
5354 160 [ + + ]: 13514 : if (ARRISEMPTY(in))
161 : : {
7231 162 : 18 : ptr = NULL;
163 : 18 : num = 0;
164 : : }
165 : : else
166 : : {
167 [ - + ]: 13496 : ptr = ARRPTR(in);
168 : 13496 : num = ARRNELEMS(in);
169 : : }
170 : :
7678 bruce@momjian.us 171 [ + + ]: 67822 : while (num--)
172 : : {
1986 akorotkov@postgresql 173 : 54308 : HASH(GETSIGN(res), *ptr, siglen);
8123 bruce@momjian.us 174 : 54308 : ptr++;
175 : : }
176 : :
177 : 13514 : retval = (GISTENTRY *) palloc(sizeof(GISTENTRY));
178 : 13514 : gistentryinit(*retval, PointerGetDatum(res),
179 : : entry->rel, entry->page,
180 : : entry->offset, false);
181 : :
182 : 13514 : PG_RETURN_POINTER(retval);
183 : : }
7678 184 [ + - ]: 43689 : else if (!ISALLTRUE(DatumGetPointer(entry->key)))
185 : : {
186 : : GISTENTRY *retval;
187 : : int i;
188 : 43689 : BITVECP sign = GETSIGN(DatumGetPointer(entry->key));
189 : : GISTTYPE *res;
190 : :
1986 akorotkov@postgresql 191 [ + - ]: 61647 : LOOPBYTE(siglen)
192 : : {
6504 bruce@momjian.us 193 [ + + ]: 61647 : if ((sign[i] & 0xff) != 0xff)
194 : 43689 : PG_RETURN_POINTER(entry);
195 : : }
196 : :
1986 akorotkov@postgresql 197 :UBC 0 : res = _intbig_alloc(true, siglen, sign);
8123 bruce@momjian.us 198 : 0 : retval = (GISTENTRY *) palloc(sizeof(GISTENTRY));
199 : 0 : gistentryinit(*retval, PointerGetDatum(res),
200 : : entry->rel, entry->page,
201 : : entry->offset, false);
202 : :
203 : 0 : PG_RETURN_POINTER(retval);
204 : : }
205 : :
206 : 0 : PG_RETURN_POINTER(entry);
207 : : }
208 : :
209 : :
210 : : static int32
1986 akorotkov@postgresql 211 : 0 : sizebitvec(BITVECP sign, int siglen)
212 : : {
213 : 0 : return pg_popcount(sign, siglen);
214 : : }
215 : :
216 : : static int
1986 akorotkov@postgresql 217 :CBC 497904 : hemdistsign(BITVECP a, BITVECP b, int siglen)
218 : : {
219 : : int i,
220 : : diff,
7678 bruce@momjian.us 221 : 497904 : dist = 0;
222 : :
1986 akorotkov@postgresql 223 [ + + ]: 453279376 : LOOPBYTE(siglen)
224 : : {
6504 bruce@momjian.us 225 : 452781472 : diff = (unsigned char) (a[i] ^ b[i]);
226 : : /* Using the popcount functions here isn't likely to win */
2395 tgl@sss.pgh.pa.us 227 : 452781472 : dist += pg_number_of_ones[diff];
228 : : }
7678 bruce@momjian.us 229 : 497904 : return dist;
230 : : }
231 : :
232 : : static int
1986 akorotkov@postgresql 233 : 497904 : hemdist(GISTTYPE *a, GISTTYPE *b, int siglen)
234 : : {
7678 bruce@momjian.us 235 [ - + ]: 497904 : if (ISALLTRUE(a))
236 : : {
7678 bruce@momjian.us 237 [ # # ]:UBC 0 : if (ISALLTRUE(b))
238 : 0 : return 0;
239 : : else
1986 akorotkov@postgresql 240 : 0 : return SIGLENBIT(siglen) - sizebitvec(GETSIGN(b), siglen);
241 : : }
7678 bruce@momjian.us 242 [ - + ]:CBC 497904 : else if (ISALLTRUE(b))
1986 akorotkov@postgresql 243 :UBC 0 : return SIGLENBIT(siglen) - sizebitvec(GETSIGN(a), siglen);
244 : :
1986 akorotkov@postgresql 245 :CBC 497904 : return hemdistsign(GETSIGN(a), GETSIGN(b), siglen);
246 : : }
247 : :
248 : : Datum
8123 bruce@momjian.us 249 : 586995 : g_intbig_decompress(PG_FUNCTION_ARGS)
250 : : {
251 : 586995 : PG_RETURN_DATUM(PG_GETARG_DATUM(0));
252 : : }
253 : :
254 : : static int32
1986 akorotkov@postgresql 255 : 127111 : unionkey(BITVECP sbase, GISTTYPE *add, int siglen)
256 : : {
257 : : int32 i;
7678 bruce@momjian.us 258 : 127111 : BITVECP sadd = GETSIGN(add);
259 : :
8123 260 [ - + ]: 127111 : if (ISALLTRUE(add))
8123 bruce@momjian.us 261 :UBC 0 : return 1;
1986 akorotkov@postgresql 262 [ + + ]:CBC 211162979 : LOOPBYTE(siglen)
6504 bruce@momjian.us 263 : 211035868 : sbase[i] |= sadd[i];
8123 264 : 127111 : return 0;
265 : : }
266 : :
267 : : Datum
7678 268 : 63416 : g_intbig_union(PG_FUNCTION_ARGS)
269 : : {
270 : 63416 : GistEntryVector *entryvec = (GistEntryVector *) PG_GETARG_POINTER(0);
271 : 63416 : int *size = (int *) PG_GETARG_POINTER(1);
1986 akorotkov@postgresql 272 [ + - ]: 63416 : int siglen = GET_SIGLEN();
273 : : int32 i;
274 : 63416 : GISTTYPE *result = _intbig_alloc(false, siglen, NULL);
275 : 63416 : BITVECP base = GETSIGN(result);
276 : :
7678 bruce@momjian.us 277 [ + + ]: 190527 : for (i = 0; i < entryvec->n; i++)
278 : : {
1986 akorotkov@postgresql 279 [ - + ]: 127111 : if (unionkey(base, GETENTRY(entryvec, i), siglen))
280 : : {
1986 akorotkov@postgresql 281 :UBC 0 : result->flag |= ALLISTRUE;
282 : 0 : SET_VARSIZE(result, CALCGTSIZE(ALLISTRUE, siglen));
8123 bruce@momjian.us 283 : 0 : break;
284 : : }
285 : : }
286 : :
1986 akorotkov@postgresql 287 :CBC 63416 : *size = VARSIZE(result);
288 : :
8123 bruce@momjian.us 289 : 63416 : PG_RETURN_POINTER(result);
290 : : }
291 : :
292 : : Datum
7678 293 : 300327 : g_intbig_penalty(PG_FUNCTION_ARGS)
294 : : {
8123 295 : 300327 : GISTENTRY *origentry = (GISTENTRY *) PG_GETARG_POINTER(0); /* always ISSIGNKEY */
296 : 300327 : GISTENTRY *newentry = (GISTENTRY *) PG_GETARG_POINTER(1);
7678 297 : 300327 : float *penalty = (float *) PG_GETARG_POINTER(2);
8123 298 : 300327 : GISTTYPE *origval = (GISTTYPE *) DatumGetPointer(origentry->key);
299 : 300327 : GISTTYPE *newval = (GISTTYPE *) DatumGetPointer(newentry->key);
1986 akorotkov@postgresql 300 [ + - ]: 300327 : int siglen = GET_SIGLEN();
301 : :
302 : 300327 : *penalty = hemdist(origval, newval, siglen);
8123 bruce@momjian.us 303 : 300327 : PG_RETURN_POINTER(penalty);
304 : : }
305 : :
306 : :
307 : : typedef struct
308 : : {
309 : : OffsetNumber pos;
310 : : int32 cost;
311 : : } SPLITCOST;
312 : :
313 : : static int
7678 314 : 39604 : comparecost(const void *a, const void *b)
315 : : {
568 nathan@postgresql.or 316 : 79208 : return pg_cmp_s32(((const SPLITCOST *) a)->cost,
317 : 39604 : ((const SPLITCOST *) b)->cost);
318 : : }
319 : :
320 : :
321 : : Datum
7678 bruce@momjian.us 322 : 4525 : g_intbig_picksplit(PG_FUNCTION_ARGS)
323 : : {
324 : 4525 : GistEntryVector *entryvec = (GistEntryVector *) PG_GETARG_POINTER(0);
325 : 4525 : GIST_SPLITVEC *v = (GIST_SPLITVEC *) PG_GETARG_POINTER(1);
1986 akorotkov@postgresql 326 [ + - ]: 4525 : int siglen = GET_SIGLEN();
327 : : OffsetNumber k,
328 : : j;
329 : : GISTTYPE *datum_l,
330 : : *datum_r;
331 : : BITVECP union_l,
332 : : union_r;
333 : : int32 size_alpha,
334 : : size_beta;
335 : : int32 size_waste,
7678 bruce@momjian.us 336 : 4525 : waste = -1;
337 : : int32 nbytes;
338 : 4525 : OffsetNumber seed_1 = 0,
339 : 4525 : seed_2 = 0;
340 : : OffsetNumber *left,
341 : : *right;
342 : : OffsetNumber maxoff;
343 : : BITVECP ptr;
344 : : int i;
345 : : SPLITCOST *costvector;
346 : : GISTTYPE *_k,
347 : : *_j;
348 : :
349 : 4525 : maxoff = entryvec->n - 2;
350 : 4525 : nbytes = (maxoff + 2) * sizeof(OffsetNumber);
351 : 4525 : v->spl_left = (OffsetNumber *) palloc(nbytes);
352 : 4525 : v->spl_right = (OffsetNumber *) palloc(nbytes);
353 : :
354 [ + + ]: 20778 : for (k = FirstOffsetNumber; k < maxoff; k = OffsetNumberNext(k))
355 : : {
356 : 16253 : _k = GETENTRY(entryvec, k);
357 [ + + ]: 130718 : for (j = OffsetNumberNext(k); j <= maxoff; j = OffsetNumberNext(j))
358 : : {
1986 akorotkov@postgresql 359 : 114465 : size_waste = hemdist(_k, GETENTRY(entryvec, j), siglen);
7678 bruce@momjian.us 360 [ + + ]: 114465 : if (size_waste > waste)
361 : : {
362 : 8807 : waste = size_waste;
363 : 8807 : seed_1 = k;
364 : 8807 : seed_2 = j;
365 : : }
366 : : }
367 : : }
368 : :
369 : 4525 : left = v->spl_left;
370 : 4525 : v->spl_nleft = 0;
371 : 4525 : right = v->spl_right;
372 : 4525 : v->spl_nright = 0;
373 : :
374 [ + - - + ]: 4525 : if (seed_1 == 0 || seed_2 == 0)
375 : : {
7678 bruce@momjian.us 376 :UBC 0 : seed_1 = 1;
377 : 0 : seed_2 = 2;
378 : : }
379 : :
380 : : /* form initial .. */
1986 akorotkov@postgresql 381 :CBC 4525 : datum_l = _intbig_alloc(ISALLTRUE(GETENTRY(entryvec, seed_1)), siglen,
382 : 4525 : GETSIGN(GETENTRY(entryvec, seed_1)));
383 : 4525 : datum_r = _intbig_alloc(ISALLTRUE(GETENTRY(entryvec, seed_2)), siglen,
384 : 4525 : GETSIGN(GETENTRY(entryvec, seed_2)));
385 : :
7678 bruce@momjian.us 386 : 4525 : maxoff = OffsetNumberNext(maxoff);
387 : : /* sort before ... */
388 : 4525 : costvector = (SPLITCOST *) palloc(sizeof(SPLITCOST) * maxoff);
389 [ + + ]: 29828 : for (j = FirstOffsetNumber; j <= maxoff; j = OffsetNumberNext(j))
390 : : {
391 : 25303 : costvector[j - 1].pos = j;
392 : 25303 : _j = GETENTRY(entryvec, j);
1986 akorotkov@postgresql 393 : 25303 : size_alpha = hemdist(datum_l, _j, siglen);
394 : 25303 : size_beta = hemdist(datum_r, _j, siglen);
1065 peter@eisentraut.org 395 : 25303 : costvector[j - 1].cost = abs(size_alpha - size_beta);
396 : : }
942 397 : 4525 : qsort(costvector, maxoff, sizeof(SPLITCOST), comparecost);
398 : :
7678 bruce@momjian.us 399 : 4525 : union_l = GETSIGN(datum_l);
400 : 4525 : union_r = GETSIGN(datum_r);
401 : :
402 [ + + ]: 29828 : for (k = 0; k < maxoff; k++)
403 : : {
404 : 25303 : j = costvector[k].pos;
405 [ + + ]: 25303 : if (j == seed_1)
406 : : {
407 : 4525 : *left++ = j;
408 : 4525 : v->spl_nleft++;
409 : 4525 : continue;
410 : : }
411 [ + + ]: 20778 : else if (j == seed_2)
412 : : {
413 : 4525 : *right++ = j;
414 : 4525 : v->spl_nright++;
415 : 4525 : continue;
416 : : }
417 : 16253 : _j = GETENTRY(entryvec, j);
1986 akorotkov@postgresql 418 : 16253 : size_alpha = hemdist(datum_l, _j, siglen);
419 : 16253 : size_beta = hemdist(datum_r, _j, siglen);
420 : :
7678 bruce@momjian.us 421 [ + + ]: 16253 : if (size_alpha < size_beta + WISH_F(v->spl_nleft, v->spl_nright, 0.00001))
422 : : {
423 [ + - - + ]: 8117 : if (ISALLTRUE(datum_l) || ISALLTRUE(_j))
424 : : {
7678 bruce@momjian.us 425 [ # # ]:UBC 0 : if (!ISALLTRUE(datum_l))
942 peter@eisentraut.org 426 : 0 : memset(union_l, 0xff, siglen);
427 : : }
428 : : else
429 : : {
7678 bruce@momjian.us 430 :CBC 8117 : ptr = GETSIGN(_j);
1986 akorotkov@postgresql 431 [ + + ]: 9416261 : LOOPBYTE(siglen)
6504 bruce@momjian.us 432 : 9408144 : union_l[i] |= ptr[i];
433 : : }
7678 434 : 8117 : *left++ = j;
435 : 8117 : v->spl_nleft++;
436 : : }
437 : : else
438 : : {
439 [ + - - + ]: 8136 : if (ISALLTRUE(datum_r) || ISALLTRUE(_j))
440 : : {
7678 bruce@momjian.us 441 [ # # ]:UBC 0 : if (!ISALLTRUE(datum_r))
942 peter@eisentraut.org 442 : 0 : memset(union_r, 0xff, siglen);
443 : : }
444 : : else
445 : : {
7678 bruce@momjian.us 446 :CBC 8136 : ptr = GETSIGN(_j);
1986 akorotkov@postgresql 447 [ + + ]: 9623076 : LOOPBYTE(siglen)
6504 bruce@momjian.us 448 : 9614940 : union_r[i] |= ptr[i];
449 : : }
7678 450 : 8136 : *right++ = j;
451 : 8136 : v->spl_nright++;
452 : : }
453 : : }
454 : :
455 : 4525 : *right = *left = FirstOffsetNumber;
456 : 4525 : pfree(costvector);
457 : :
458 : 4525 : v->spl_ldatum = PointerGetDatum(datum_l);
459 : 4525 : v->spl_rdatum = PointerGetDatum(datum_r);
460 : :
461 : 4525 : PG_RETURN_POINTER(v);
462 : : }
463 : :
464 : : Datum
8123 465 : 68977 : g_intbig_consistent(PG_FUNCTION_ARGS)
466 : : {
467 : 68977 : GISTENTRY *entry = (GISTENTRY *) PG_GETARG_POINTER(0);
5354 tgl@sss.pgh.pa.us 468 : 68977 : ArrayType *query = PG_GETARG_ARRAYTYPE_P(1);
8123 bruce@momjian.us 469 : 68977 : StrategyNumber strategy = (StrategyNumber) PG_GETARG_UINT16(2);
470 : :
471 : : /* Oid subtype = PG_GETARG_OID(3); */
6354 tgl@sss.pgh.pa.us 472 : 68977 : bool *recheck = (bool *) PG_GETARG_POINTER(4);
1986 akorotkov@postgresql 473 [ + - ]: 68977 : int siglen = GET_SIGLEN();
474 : : bool retval;
475 : :
476 : : /* All cases served by this function are inexact */
6354 tgl@sss.pgh.pa.us 477 : 68977 : *recheck = true;
478 : :
7678 bruce@momjian.us 479 [ - + ]: 68977 : if (ISALLTRUE(DatumGetPointer(entry->key)))
8123 bruce@momjian.us 480 :UBC 0 : PG_RETURN_BOOL(true);
481 : :
7678 bruce@momjian.us 482 [ + + ]:CBC 68977 : if (strategy == BooleanSearchStrategy)
483 : : {
6912 484 : 51715 : retval = signconsistent((QUERYTYPE *) query,
485 : 51715 : GETSIGN(DatumGetPointer(entry->key)),
486 : : siglen,
487 : : false);
488 [ - + ]: 51715 : PG_FREE_IF_COPY(query, 1);
7096 teodor@sigaev.ru 489 : 51715 : PG_RETURN_BOOL(retval);
490 : : }
491 : :
7231 tgl@sss.pgh.pa.us 492 [ - + - - : 17262 : CHECKARRVALID(query);
- - ]
493 : :
8123 bruce@momjian.us 494 [ + + + - : 17262 : switch (strategy)
- ]
495 : : {
496 : 7296 : case RTOverlapStrategyNumber:
1986 akorotkov@postgresql 497 : 7296 : retval = _intbig_overlap((GISTTYPE *) DatumGetPointer(entry->key),
498 : : query, siglen);
8123 bruce@momjian.us 499 : 7296 : break;
500 : 1147 : case RTSameStrategyNumber:
7678 501 [ + + ]: 1147 : if (GIST_LEAF(entry))
502 : : {
503 : : int i,
504 : 429 : num = ARRNELEMS(query);
4821 peter_e@gmx.net 505 [ - + ]: 429 : int32 *ptr = ARRPTR(query);
1986 akorotkov@postgresql 506 : 429 : BITVECP dq = palloc0(siglen),
507 : : de;
508 : :
7678 bruce@momjian.us 509 [ + + ]: 1716 : while (num--)
510 : : {
1986 akorotkov@postgresql 511 : 1287 : HASH(dq, *ptr, siglen);
8123 bruce@momjian.us 512 : 1287 : ptr++;
513 : : }
514 : :
7678 515 : 429 : de = GETSIGN((GISTTYPE *) DatumGetPointer(entry->key));
516 : 429 : retval = true;
1986 akorotkov@postgresql 517 [ + + ]: 3269 : LOOPBYTE(siglen)
518 : : {
6504 bruce@momjian.us 519 [ + + ]: 3267 : if (de[i] != dq[i])
520 : : {
521 : 427 : retval = false;
522 : 427 : break;
523 : : }
524 : : }
525 : :
1986 akorotkov@postgresql 526 : 429 : pfree(dq);
527 : : }
528 : : else
529 : 718 : retval = _intbig_contains((GISTTYPE *) DatumGetPointer(entry->key),
530 : : query, siglen);
8123 bruce@momjian.us 531 : 1147 : break;
532 : 8819 : case RTContainsStrategyNumber:
533 : : case RTOldContainsStrategyNumber:
1986 akorotkov@postgresql 534 : 8819 : retval = _intbig_contains((GISTTYPE *) DatumGetPointer(entry->key),
535 : : query, siglen);
8123 bruce@momjian.us 536 : 8819 : break;
8123 bruce@momjian.us 537 :UBC 0 : case RTContainedByStrategyNumber:
538 : : case RTOldContainedByStrategyNumber:
539 : :
540 : : /*
541 : : * This code is unreachable as of intarray 1.4, because the <@
542 : : * operator has been removed from the opclass. We keep it for now
543 : : * to support older versions of the SQL definitions.
544 : : */
7678 545 [ # # ]: 0 : if (GIST_LEAF(entry))
546 : : {
547 : : int i,
548 : 0 : num = ARRNELEMS(query);
4821 peter_e@gmx.net 549 [ # # ]: 0 : int32 *ptr = ARRPTR(query);
1986 akorotkov@postgresql 550 : 0 : BITVECP dq = palloc0(siglen),
551 : : de;
552 : :
7678 bruce@momjian.us 553 [ # # ]: 0 : while (num--)
554 : : {
1986 akorotkov@postgresql 555 : 0 : HASH(dq, *ptr, siglen);
8123 bruce@momjian.us 556 : 0 : ptr++;
557 : : }
558 : :
7678 559 : 0 : de = GETSIGN((GISTTYPE *) DatumGetPointer(entry->key));
560 : 0 : retval = true;
1986 akorotkov@postgresql 561 [ # # ]: 0 : LOOPBYTE(siglen)
562 : : {
6504 bruce@momjian.us 563 [ # # ]: 0 : if (de[i] & ~dq[i])
564 : : {
565 : 0 : retval = false;
566 : 0 : break;
567 : : }
568 : : }
569 : : }
570 : : else
571 : : {
572 : : /*
573 : : * Unfortunately, because empty arrays could be anywhere in
574 : : * the index, we must search the whole tree.
575 : : */
2223 tgl@sss.pgh.pa.us 576 : 0 : retval = true;
577 : : }
8123 bruce@momjian.us 578 : 0 : break;
579 : 0 : default:
2943 peter_e@gmx.net 580 : 0 : retval = false;
581 : : }
6912 bruce@momjian.us 582 [ - + ]:CBC 17262 : PG_FREE_IF_COPY(query, 1);
8123 583 : 17262 : PG_RETURN_BOOL(retval);
584 : : }
585 : :
586 : : Datum
1986 akorotkov@postgresql 587 : 10 : g_intbig_options(PG_FUNCTION_ARGS)
588 : : {
589 : 10 : local_relopts *relopts = (local_relopts *) PG_GETARG_POINTER(0);
590 : :
591 : 10 : init_local_reloptions(relopts, sizeof(GISTIntArrayBigOptions));
592 : 10 : add_local_int_reloption(relopts, "siglen",
593 : : "signature length in bytes",
594 : : SIGLEN_DEFAULT, 1, SIGLEN_MAX,
595 : : offsetof(GISTIntArrayBigOptions, siglen));
596 : :
597 : 10 : PG_RETURN_VOID();
598 : : }
|