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