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