PostgreSQL Source Code git master
All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Pages
_int_gist.c File Reference
#include "postgres.h"
#include <limits.h>
#include <math.h>
#include "_int.h"
#include "access/gist.h"
#include "access/reloptions.h"
#include "access/stratnum.h"
Include dependency graph for _int_gist.c:

Go to the source code of this file.

Data Structures

struct  SPLITCOST
 

Macros

#define GETENTRY(vec, pos)   ((ArrayType *) DatumGetPointer((vec)->vector[(pos)].key))
 
#define MAXNUMELTS   (Min((MaxAllocSize / sizeof(Datum)),((MaxAllocSize - ARR_OVERHEAD_NONULLS(1)) / sizeof(int)))/2)
 

Functions

 PG_FUNCTION_INFO_V1 (g_int_consistent)
 
 PG_FUNCTION_INFO_V1 (g_int_compress)
 
 PG_FUNCTION_INFO_V1 (g_int_decompress)
 
 PG_FUNCTION_INFO_V1 (g_int_penalty)
 
 PG_FUNCTION_INFO_V1 (g_int_picksplit)
 
 PG_FUNCTION_INFO_V1 (g_int_union)
 
 PG_FUNCTION_INFO_V1 (g_int_same)
 
 PG_FUNCTION_INFO_V1 (g_int_options)
 
Datum g_int_consistent (PG_FUNCTION_ARGS)
 
Datum g_int_union (PG_FUNCTION_ARGS)
 
Datum g_int_compress (PG_FUNCTION_ARGS)
 
Datum g_int_decompress (PG_FUNCTION_ARGS)
 
Datum g_int_penalty (PG_FUNCTION_ARGS)
 
Datum g_int_same (PG_FUNCTION_ARGS)
 
static int comparecost (const void *a, const void *b)
 
Datum g_int_picksplit (PG_FUNCTION_ARGS)
 
Datum g_int_options (PG_FUNCTION_ARGS)
 

Macro Definition Documentation

◆ GETENTRY

#define GETENTRY (   vec,
  pos 
)    ((ArrayType *) DatumGetPointer((vec)->vector[(pos)].key))

Definition at line 14 of file _int_gist.c.

◆ MAXNUMELTS

#define MAXNUMELTS   (Min((MaxAllocSize / sizeof(Datum)),((MaxAllocSize - ARR_OVERHEAD_NONULLS(1)) / sizeof(int)))/2)

Definition at line 24 of file _int_gist.c.

Function Documentation

◆ comparecost()

static int comparecost ( const void *  a,
const void *  b 
)
static

Definition at line 429 of file _int_gist.c.

430{
431 if (((const SPLITCOST *) a)->cost == ((const SPLITCOST *) b)->cost)
432 return 0;
433 else
434 return (((const SPLITCOST *) a)->cost > ((const SPLITCOST *) b)->cost) ? 1 : -1;
435}
int b
Definition: isn.c:71
int a
Definition: isn.c:70

References a, and b.

Referenced by g_int_picksplit().

◆ g_int_compress()

Datum g_int_compress ( PG_FUNCTION_ARGS  )

Definition at line 163 of file _int_gist.c.

164{
165 GISTENTRY *entry = (GISTENTRY *) PG_GETARG_POINTER(0);
166 GISTENTRY *retval;
167 ArrayType *r;
168 int num_ranges = G_INT_GET_NUMRANGES();
169 int len,
170 lenr;
171 int *dr;
172 int i,
173 j,
174 cand;
175 int64 min;
176
177 if (entry->leafkey)
178 {
179 r = DatumGetArrayTypePCopy(entry->key);
180 CHECKARRVALID(r);
181 PREPAREARR(r);
182
183 if (ARRNELEMS(r) >= 2 * num_ranges)
185 (errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
186 errmsg("input array is too big (%d maximum allowed, %d current), use gist__intbig_ops opclass instead",
187 2 * num_ranges - 1, ARRNELEMS(r))));
188
189 retval = palloc(sizeof(GISTENTRY));
190 gistentryinit(*retval, PointerGetDatum(r),
191 entry->rel, entry->page, entry->offset, false);
192
193 PG_RETURN_POINTER(retval);
194 }
195
196 /*
197 * leaf entries never compress one more time, only when entry->leafkey
198 * ==true, so now we work only with internal keys
199 */
200
201 r = DatumGetArrayTypeP(entry->key);
202 CHECKARRVALID(r);
203 if (ARRISEMPTY(r))
204 {
205 if (r != (ArrayType *) DatumGetPointer(entry->key))
206 pfree(r);
207 PG_RETURN_POINTER(entry);
208 }
209
210 if ((len = ARRNELEMS(r)) >= 2 * num_ranges)
211 { /* compress */
212 if (r == (ArrayType *) DatumGetPointer(entry->key))
213 r = DatumGetArrayTypePCopy(entry->key);
214 r = resize_intArrayType(r, 2 * (len));
215
216 dr = ARRPTR(r);
217
218 /*
219 * "len" at this point is the number of ranges we will construct.
220 * "lenr" is the number of ranges we must eventually remove by
221 * merging, we must be careful to remove no more than this number.
222 */
223 lenr = len - num_ranges;
224
225 /*
226 * Initially assume we can merge consecutive ints into a range. but we
227 * must count every value removed and stop when lenr runs out
228 */
229 for (j = i = len - 1; i > 0 && lenr > 0; i--, j--)
230 {
231 int r_end = dr[i];
232 int r_start = r_end;
233
234 while (i > 0 && lenr > 0 && dr[i - 1] == r_start - 1)
235 --r_start, --i, --lenr;
236 dr[2 * j] = r_start;
237 dr[2 * j + 1] = r_end;
238 }
239 /* just copy the rest, if any, as trivial ranges */
240 for (; i >= 0; i--, j--)
241 dr[2 * j] = dr[2 * j + 1] = dr[i];
242
243 if (++j)
244 {
245 /*
246 * shunt everything down to start at the right place
247 */
248 memmove(&dr[0], &dr[2 * j], 2 * (len - j) * sizeof(int32));
249 }
250
251 /*
252 * make "len" be number of array elements, not ranges
253 */
254 len = 2 * (len - j);
255 cand = 1;
256 while (len > num_ranges * 2)
257 {
258 min = PG_INT64_MAX;
259 for (i = 2; i < len; i += 2)
260 if (min > ((int64) dr[i] - (int64) dr[i - 1]))
261 {
262 min = ((int64) dr[i] - (int64) dr[i - 1]);
263 cand = i;
264 }
265 memmove(&dr[cand - 1], &dr[cand + 1], (len - cand - 1) * sizeof(int32));
266 len -= 2;
267 }
268
269 /*
270 * check sparseness of result
271 */
272 lenr = internal_size(dr, len);
273 if (lenr < 0 || lenr > MAXNUMELTS)
275 (errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
276 errmsg("data is too sparse, recreate index using gist__intbig_ops opclass instead")));
277
278 r = resize_intArrayType(r, len);
279 retval = palloc(sizeof(GISTENTRY));
280 gistentryinit(*retval, PointerGetDatum(r),
281 entry->rel, entry->page, entry->offset, false);
282 PG_RETURN_POINTER(retval);
283 }
284 else
285 PG_RETURN_POINTER(entry);
286}
#define G_INT_GET_NUMRANGES()
Definition: _int.h:14
int internal_size(int *a, int len)
Definition: _int_tool.c:295
#define PREPAREARR(x)
Definition: _int.h:49
#define CHECKARRVALID(x)
Definition: _int.h:30
ArrayType * resize_intArrayType(ArrayType *a, int num)
Definition: _int_tool.c:252
#define ARRISEMPTY(x)
Definition: _int.h:38
#define MAXNUMELTS
Definition: _int_gist.c:24
#define DatumGetArrayTypePCopy(X)
Definition: array.h:262
#define DatumGetArrayTypeP(X)
Definition: array.h:261
int64_t int64
Definition: c.h:499
int32_t int32
Definition: c.h:498
#define PG_INT64_MAX
Definition: c.h:563
#define ARRNELEMS(x)
Definition: cube.c:26
#define ARRPTR(x)
Definition: cube.c:25
int errcode(int sqlerrcode)
Definition: elog.c:853
int errmsg(const char *fmt,...)
Definition: elog.c:1070
#define ERROR
Definition: elog.h:39
#define ereport(elevel,...)
Definition: elog.h:149
#define PG_GETARG_POINTER(n)
Definition: fmgr.h:276
#define PG_RETURN_POINTER(x)
Definition: fmgr.h:361
#define gistentryinit(e, k, r, pg, o, l)
Definition: gist.h:245
int j
Definition: isn.c:75
int i
Definition: isn.c:74
void pfree(void *pointer)
Definition: mcxt.c:1524
void * palloc(Size size)
Definition: mcxt.c:1317
const void size_t len
static Datum PointerGetDatum(const void *X)
Definition: postgres.h:327
static Pointer DatumGetPointer(Datum X)
Definition: postgres.h:317
OffsetNumber offset
Definition: gist.h:164
Datum key
Definition: gist.h:161
Page page
Definition: gist.h:163
Relation rel
Definition: gist.h:162
bool leafkey
Definition: gist.h:165

References ARRISEMPTY, ARRNELEMS, ARRPTR, CHECKARRVALID, DatumGetArrayTypeP, DatumGetArrayTypePCopy, DatumGetPointer(), ereport, errcode(), errmsg(), ERROR, G_INT_GET_NUMRANGES, gistentryinit, i, internal_size(), j, GISTENTRY::key, GISTENTRY::leafkey, len, MAXNUMELTS, GISTENTRY::offset, GISTENTRY::page, palloc(), pfree(), PG_GETARG_POINTER, PG_INT64_MAX, PG_RETURN_POINTER, PointerGetDatum(), PREPAREARR, GISTENTRY::rel, and resize_intArrayType().

◆ g_int_consistent()

Datum g_int_consistent ( PG_FUNCTION_ARGS  )

Definition at line 47 of file _int_gist.c.

48{
52
53 /* Oid subtype = PG_GETARG_OID(3); */
54 bool *recheck = (bool *) PG_GETARG_POINTER(4);
55 bool retval = false; /* silence compiler warning */
56
57 /* this is exact except for RTSameStrategyNumber */
58 *recheck = (strategy == RTSameStrategyNumber);
59
60 if (strategy == BooleanSearchStrategy)
61 {
62 retval = execconsistent((QUERYTYPE *) query,
63 (ArrayType *) DatumGetPointer(entry->key),
64 GIST_LEAF(entry));
65
66 pfree(query);
67 PG_RETURN_BOOL(retval);
68 }
69
70 /* sort query for fast search, key is already sorted */
71 CHECKARRVALID(query);
72 PREPAREARR(query);
73
74 switch (strategy)
75 {
78 query);
79 break;
81 if (GIST_LEAF(entry))
83 entry->key,
84 PointerGetDatum(query),
85 PointerGetDatum(&retval));
86 else
88 query);
89 break;
93 query);
94 break;
97
98 /*
99 * This code is unreachable as of intarray 1.4, because the <@
100 * operator has been removed from the opclass. We keep it for now
101 * to support older versions of the SQL definitions.
102 */
103 if (GIST_LEAF(entry))
104 retval = inner_int_contains(query,
105 (ArrayType *) DatumGetPointer(entry->key));
106 else
107 {
108 /*
109 * Unfortunately, because empty arrays could be anywhere in
110 * the index, we must search the whole tree.
111 */
112 retval = true;
113 }
114 break;
115 default:
116 retval = false;
117 }
118 pfree(query);
119 PG_RETURN_BOOL(retval);
120}
bool inner_int_overlap(ArrayType *a, ArrayType *b)
Definition: _int_tool.c:50
bool inner_int_contains(ArrayType *a, ArrayType *b)
Definition: _int_tool.c:15
#define BooleanSearchStrategy
Definition: _int.h:134
bool execconsistent(QUERYTYPE *query, ArrayType *array, bool calcnot)
Definition: _int_bool.c:307
Datum g_int_same(PG_FUNCTION_ARGS)
Definition: _int_gist.c:386
#define PG_GETARG_ARRAYTYPE_P_COPY(n)
Definition: array.h:264
#define PG_GETARG_UINT16(n)
Definition: fmgr.h:272
#define DirectFunctionCall3(func, arg1, arg2, arg3)
Definition: fmgr.h:645
#define PG_RETURN_BOOL(x)
Definition: fmgr.h:359
#define GIST_LEAF(entry)
Definition: gist.h:171
#define RTOldContainsStrategyNumber
Definition: stratnum.h:63
uint16 StrategyNumber
Definition: stratnum.h:22
#define RTOverlapStrategyNumber
Definition: stratnum.h:53
#define RTSameStrategyNumber
Definition: stratnum.h:56
#define RTContainsStrategyNumber
Definition: stratnum.h:57
#define RTOldContainedByStrategyNumber
Definition: stratnum.h:64
#define RTContainedByStrategyNumber
Definition: stratnum.h:58

References BooleanSearchStrategy, CHECKARRVALID, DatumGetPointer(), DirectFunctionCall3, execconsistent(), g_int_same(), GIST_LEAF, inner_int_contains(), inner_int_overlap(), GISTENTRY::key, pfree(), PG_GETARG_ARRAYTYPE_P_COPY, PG_GETARG_POINTER, PG_GETARG_UINT16, PG_RETURN_BOOL, PointerGetDatum(), PREPAREARR, RTContainedByStrategyNumber, RTContainsStrategyNumber, RTOldContainedByStrategyNumber, RTOldContainsStrategyNumber, RTOverlapStrategyNumber, and RTSameStrategyNumber.

◆ g_int_decompress()

Datum g_int_decompress ( PG_FUNCTION_ARGS  )

Definition at line 289 of file _int_gist.c.

290{
291 GISTENTRY *entry = (GISTENTRY *) PG_GETARG_POINTER(0);
292 GISTENTRY *retval;
293 ArrayType *r;
294 int num_ranges = G_INT_GET_NUMRANGES();
295 int *dr,
296 lenr;
297 ArrayType *in;
298 int lenin;
299 int *din;
300 int i;
301
302 in = DatumGetArrayTypeP(entry->key);
303
304 CHECKARRVALID(in);
305 if (ARRISEMPTY(in))
306 {
307 if (in != (ArrayType *) DatumGetPointer(entry->key))
308 {
309 retval = palloc(sizeof(GISTENTRY));
310 gistentryinit(*retval, PointerGetDatum(in),
311 entry->rel, entry->page, entry->offset, false);
312 PG_RETURN_POINTER(retval);
313 }
314
315 PG_RETURN_POINTER(entry);
316 }
317
318 lenin = ARRNELEMS(in);
319
320 if (lenin < 2 * num_ranges)
321 { /* not compressed value */
322 if (in != (ArrayType *) DatumGetPointer(entry->key))
323 {
324 retval = palloc(sizeof(GISTENTRY));
325 gistentryinit(*retval, PointerGetDatum(in),
326 entry->rel, entry->page, entry->offset, false);
327
328 PG_RETURN_POINTER(retval);
329 }
330 PG_RETURN_POINTER(entry);
331 }
332
333 din = ARRPTR(in);
334 lenr = internal_size(din, lenin);
335 if (lenr < 0 || lenr > MAXNUMELTS)
337 (errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
338 errmsg("compressed array is too big, recreate index using gist__intbig_ops opclass instead")));
339
340 r = new_intArrayType(lenr);
341 dr = ARRPTR(r);
342
343 for (i = 0; i < lenin; i += 2)
344 {
345 /* use int64 for j in case din[i + 1] is INT_MAX */
346 for (int64 j = din[i]; j <= din[i + 1]; j++)
347 if ((!i) || *(dr - 1) != j)
348 *dr++ = (int) j;
349 }
350
351 if (in != (ArrayType *) DatumGetPointer(entry->key))
352 pfree(in);
353 retval = palloc(sizeof(GISTENTRY));
354 gistentryinit(*retval, PointerGetDatum(r),
355 entry->rel, entry->page, entry->offset, false);
356
357 PG_RETURN_POINTER(retval);
358}
ArrayType * new_intArrayType(int num)
Definition: _int_tool.c:224

References ARRISEMPTY, ARRNELEMS, ARRPTR, CHECKARRVALID, DatumGetArrayTypeP, DatumGetPointer(), ereport, errcode(), errmsg(), ERROR, G_INT_GET_NUMRANGES, gistentryinit, i, internal_size(), j, GISTENTRY::key, MAXNUMELTS, new_intArrayType(), GISTENTRY::offset, GISTENTRY::page, palloc(), pfree(), PG_GETARG_POINTER, PG_RETURN_POINTER, PointerGetDatum(), and GISTENTRY::rel.

◆ g_int_options()

Datum g_int_options ( PG_FUNCTION_ARGS  )

Definition at line 626 of file _int_gist.c.

627{
629
631 add_local_int_reloption(relopts, "numranges",
632 "number of ranges for compression",
634 offsetof(GISTIntArrayOptions, num_ranges));
635
637}
#define G_INT_NUMRANGES_DEFAULT
Definition: _int.h:11
#define G_INT_NUMRANGES_MAX
Definition: _int.h:12
#define PG_RETURN_VOID()
Definition: fmgr.h:349
void init_local_reloptions(local_relopts *relopts, Size relopt_struct_size)
Definition: reloptions.c:753
void add_local_int_reloption(local_relopts *relopts, const char *name, const char *desc, int default_val, int min_val, int max_val, int offset)
Definition: reloptions.c:937

References add_local_int_reloption(), G_INT_NUMRANGES_DEFAULT, G_INT_NUMRANGES_MAX, init_local_reloptions(), PG_GETARG_POINTER, and PG_RETURN_VOID.

◆ g_int_penalty()

Datum g_int_penalty ( PG_FUNCTION_ARGS  )

Definition at line 364 of file _int_gist.c.

365{
366 GISTENTRY *origentry = (GISTENTRY *) PG_GETARG_POINTER(0);
367 GISTENTRY *newentry = (GISTENTRY *) PG_GETARG_POINTER(1);
368 float *result = (float *) PG_GETARG_POINTER(2);
369 ArrayType *ud;
370 float tmp1,
371 tmp2;
372
373 ud = inner_int_union((ArrayType *) DatumGetPointer(origentry->key),
374 (ArrayType *) DatumGetPointer(newentry->key));
375 rt__int_size(ud, &tmp1);
376 rt__int_size((ArrayType *) DatumGetPointer(origentry->key), &tmp2);
377 *result = tmp1 - tmp2;
378 pfree(ud);
379
380 PG_RETURN_POINTER(result);
381}
ArrayType * inner_int_union(ArrayType *a, ArrayType *b)
Definition: _int_tool.c:79
void rt__int_size(ArrayType *a, float *size)
Definition: _int_tool.c:184

References DatumGetPointer(), inner_int_union(), GISTENTRY::key, pfree(), PG_GETARG_POINTER, PG_RETURN_POINTER, and rt__int_size().

◆ g_int_picksplit()

Datum g_int_picksplit ( PG_FUNCTION_ARGS  )

Definition at line 442 of file _int_gist.c.

443{
447 j;
448 ArrayType *datum_alpha,
449 *datum_beta;
450 ArrayType *datum_l,
451 *datum_r;
452 ArrayType *union_d,
453 *union_dl,
454 *union_dr;
455 ArrayType *inter_d;
456 bool firsttime;
457 float size_alpha,
458 size_beta,
459 size_union,
460 size_inter;
461 float size_waste,
462 waste;
463 float size_l,
464 size_r;
465 int nbytes;
466 OffsetNumber seed_1 = 0,
467 seed_2 = 0;
468 OffsetNumber *left,
469 *right;
470 OffsetNumber maxoff;
471 SPLITCOST *costvector;
472
473#ifdef GIST_DEBUG
474 elog(DEBUG3, "--------picksplit %d", entryvec->n);
475#endif
476
477 maxoff = entryvec->n - 2;
478 nbytes = (maxoff + 2) * sizeof(OffsetNumber);
479 v->spl_left = (OffsetNumber *) palloc(nbytes);
480 v->spl_right = (OffsetNumber *) palloc(nbytes);
481
482 firsttime = true;
483 waste = 0.0;
484 for (i = FirstOffsetNumber; i < maxoff; i = OffsetNumberNext(i))
485 {
486 datum_alpha = GETENTRY(entryvec, i);
487 for (j = OffsetNumberNext(i); j <= maxoff; j = OffsetNumberNext(j))
488 {
489 datum_beta = GETENTRY(entryvec, j);
490
491 /* compute the wasted space by unioning these guys */
492 /* size_waste = size_union - size_inter; */
493 union_d = inner_int_union(datum_alpha, datum_beta);
494 rt__int_size(union_d, &size_union);
495 inter_d = inner_int_inter(datum_alpha, datum_beta);
496 rt__int_size(inter_d, &size_inter);
497 size_waste = size_union - size_inter;
498
499 pfree(union_d);
500 pfree(inter_d);
501
502 /*
503 * are these a more promising split that what we've already seen?
504 */
505
506 if (size_waste > waste || firsttime)
507 {
508 waste = size_waste;
509 seed_1 = i;
510 seed_2 = j;
511 firsttime = false;
512 }
513 }
514 }
515
516 left = v->spl_left;
517 v->spl_nleft = 0;
518 right = v->spl_right;
519 v->spl_nright = 0;
520 if (seed_1 == 0 || seed_2 == 0)
521 {
522 seed_1 = 1;
523 seed_2 = 2;
524 }
525
526 datum_alpha = GETENTRY(entryvec, seed_1);
527 datum_l = copy_intArrayType(datum_alpha);
528 rt__int_size(datum_l, &size_l);
529 datum_beta = GETENTRY(entryvec, seed_2);
530 datum_r = copy_intArrayType(datum_beta);
531 rt__int_size(datum_r, &size_r);
532
533 maxoff = OffsetNumberNext(maxoff);
534
535 /*
536 * sort entries
537 */
538 costvector = (SPLITCOST *) palloc(sizeof(SPLITCOST) * maxoff);
539 for (i = FirstOffsetNumber; i <= maxoff; i = OffsetNumberNext(i))
540 {
541 costvector[i - 1].pos = i;
542 datum_alpha = GETENTRY(entryvec, i);
543 union_d = inner_int_union(datum_l, datum_alpha);
544 rt__int_size(union_d, &size_alpha);
545 pfree(union_d);
546 union_d = inner_int_union(datum_r, datum_alpha);
547 rt__int_size(union_d, &size_beta);
548 pfree(union_d);
549 costvector[i - 1].cost = fabsf((size_alpha - size_l) - (size_beta - size_r));
550 }
551 qsort(costvector, maxoff, sizeof(SPLITCOST), comparecost);
552
553 /*
554 * Now split up the regions between the two seeds. An important property
555 * of this split algorithm is that the split vector v has the indices of
556 * items to be split in order in its left and right vectors. We exploit
557 * this property by doing a merge in the code that actually splits the
558 * page.
559 *
560 * For efficiency, we also place the new index tuple in this loop. This is
561 * handled at the very end, when we have placed all the existing tuples
562 * and i == maxoff + 1.
563 */
564
565
566 for (j = 0; j < maxoff; j++)
567 {
568 i = costvector[j].pos;
569
570 /*
571 * If we've already decided where to place this item, just put it on
572 * the right list. Otherwise, we need to figure out which page needs
573 * the least enlargement in order to store the item.
574 */
575
576 if (i == seed_1)
577 {
578 *left++ = i;
579 v->spl_nleft++;
580 continue;
581 }
582 else if (i == seed_2)
583 {
584 *right++ = i;
585 v->spl_nright++;
586 continue;
587 }
588
589 /* okay, which page needs least enlargement? */
590 datum_alpha = GETENTRY(entryvec, i);
591 union_dl = inner_int_union(datum_l, datum_alpha);
592 union_dr = inner_int_union(datum_r, datum_alpha);
593 rt__int_size(union_dl, &size_alpha);
594 rt__int_size(union_dr, &size_beta);
595
596 /* pick which page to add it to */
597 if (size_alpha - size_l < size_beta - size_r + WISH_F(v->spl_nleft, v->spl_nright, 0.01))
598 {
599 pfree(datum_l);
600 pfree(union_dr);
601 datum_l = union_dl;
602 size_l = size_alpha;
603 *left++ = i;
604 v->spl_nleft++;
605 }
606 else
607 {
608 pfree(datum_r);
609 pfree(union_dl);
610 datum_r = union_dr;
611 size_r = size_beta;
612 *right++ = i;
613 v->spl_nright++;
614 }
615 }
616 pfree(costvector);
617 *right = *left = FirstOffsetNumber;
618
619 v->spl_ldatum = PointerGetDatum(datum_l);
620 v->spl_rdatum = PointerGetDatum(datum_r);
621
623}
ArrayType * copy_intArrayType(ArrayType *a)
Definition: _int_tool.c:283
ArrayType * inner_int_inter(ArrayType *a, ArrayType *b)
Definition: _int_tool.c:136
#define GETENTRY(vec, pos)
Definition: _int_gist.c:14
static int comparecost(const void *a, const void *b)
Definition: _int_gist.c:429
#define DEBUG3
Definition: elog.h:28
#define elog(elevel,...)
Definition: elog.h:225
#define WISH_F(a, b, c)
Definition: hstore_gist.c:77
#define OffsetNumberNext(offsetNumber)
Definition: off.h:52
uint16 OffsetNumber
Definition: off.h:24
#define FirstOffsetNumber
Definition: off.h:27
#define qsort(a, b, c, d)
Definition: port.h:475
int spl_nleft
Definition: gist.h:144
OffsetNumber * spl_right
Definition: gist.h:148
Datum spl_ldatum
Definition: gist.h:145
Datum spl_rdatum
Definition: gist.h:150
int spl_nright
Definition: gist.h:149
OffsetNumber * spl_left
Definition: gist.h:143
int32 n
Definition: gist.h:236
int32 cost
Definition: hstore_gist.c:354
OffsetNumber pos
Definition: hstore_gist.c:353

References comparecost(), copy_intArrayType(), SPLITCOST::cost, DEBUG3, elog, FirstOffsetNumber, GETENTRY, i, inner_int_inter(), inner_int_union(), j, GistEntryVector::n, OffsetNumberNext, palloc(), pfree(), PG_GETARG_POINTER, PG_RETURN_POINTER, PointerGetDatum(), SPLITCOST::pos, qsort, rt__int_size(), GIST_SPLITVEC::spl_ldatum, GIST_SPLITVEC::spl_left, GIST_SPLITVEC::spl_nleft, GIST_SPLITVEC::spl_nright, GIST_SPLITVEC::spl_rdatum, GIST_SPLITVEC::spl_right, and WISH_F.

◆ g_int_same()

Datum g_int_same ( PG_FUNCTION_ARGS  )

Definition at line 386 of file _int_gist.c.

387{
390 bool *result = (bool *) PG_GETARG_POINTER(2);
391 int32 n = ARRNELEMS(a);
392 int32 *da,
393 *db;
394
397
398 if (n != ARRNELEMS(b))
399 {
400 *result = false;
401 PG_RETURN_POINTER(result);
402 }
403 *result = true;
404 da = ARRPTR(a);
405 db = ARRPTR(b);
406 while (n--)
407 {
408 if (*da++ != *db++)
409 {
410 *result = false;
411 break;
412 }
413 }
414
415 PG_RETURN_POINTER(result);
416}
#define PG_GETARG_ARRAYTYPE_P(n)
Definition: array.h:263

References a, ARRNELEMS, ARRPTR, b, CHECKARRVALID, PG_GETARG_ARRAYTYPE_P, PG_GETARG_POINTER, and PG_RETURN_POINTER.

Referenced by g_int_consistent().

◆ g_int_union()

Datum g_int_union ( PG_FUNCTION_ARGS  )

Definition at line 123 of file _int_gist.c.

124{
126 int *size = (int *) PG_GETARG_POINTER(1);
127 int32 i,
128 *ptr;
129 ArrayType *res;
130 int totlen = 0;
131
132 for (i = 0; i < entryvec->n; i++)
133 {
134 ArrayType *ent = GETENTRY(entryvec, i);
135
136 CHECKARRVALID(ent);
137 totlen += ARRNELEMS(ent);
138 }
139
140 res = new_intArrayType(totlen);
141 ptr = ARRPTR(res);
142
143 for (i = 0; i < entryvec->n; i++)
144 {
145 ArrayType *ent = GETENTRY(entryvec, i);
146 int nel;
147
148 nel = ARRNELEMS(ent);
149 memcpy(ptr, ARRPTR(ent), nel * sizeof(int32));
150 ptr += nel;
151 }
152
153 QSORT(res, 1);
154 res = _int_unique(res);
155 *size = VARSIZE(res);
157}
#define QSORT(a, direction)
Definition: _int.h:180
ArrayType * _int_unique(ArrayType *r)
Definition: _int_tool.c:313
#define VARSIZE(PTR)
Definition: varatt.h:279

References _int_unique(), ARRNELEMS, ARRPTR, CHECKARRVALID, GETENTRY, i, GistEntryVector::n, new_intArrayType(), PG_GETARG_POINTER, PG_RETURN_POINTER, QSORT, and VARSIZE.

◆ PG_FUNCTION_INFO_V1() [1/8]

PG_FUNCTION_INFO_V1 ( g_int_compress  )

◆ PG_FUNCTION_INFO_V1() [2/8]

PG_FUNCTION_INFO_V1 ( g_int_consistent  )

◆ PG_FUNCTION_INFO_V1() [3/8]

PG_FUNCTION_INFO_V1 ( g_int_decompress  )

◆ PG_FUNCTION_INFO_V1() [4/8]

PG_FUNCTION_INFO_V1 ( g_int_options  )

◆ PG_FUNCTION_INFO_V1() [5/8]

PG_FUNCTION_INFO_V1 ( g_int_penalty  )

◆ PG_FUNCTION_INFO_V1() [6/8]

PG_FUNCTION_INFO_V1 ( g_int_picksplit  )

◆ PG_FUNCTION_INFO_V1() [7/8]

PG_FUNCTION_INFO_V1 ( g_int_same  )

◆ PG_FUNCTION_INFO_V1() [8/8]

PG_FUNCTION_INFO_V1 ( g_int_union  )