PostgreSQL Source Code  git master
_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 423 of file _int_gist.c.

424 {
425  if (((const SPLITCOST *) a)->cost == ((const SPLITCOST *) b)->cost)
426  return 0;
427  else
428  return (((const SPLITCOST *) a)->cost > ((const SPLITCOST *) b)->cost) ? 1 : -1;
429 }
int b
Definition: isn.c:70
int a
Definition: isn.c:69

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

References ARRISEMPTY, ARRNELEMS, ARRPTR, CHECKARRVALID, DatumGetArrayTypeP, DatumGetArrayTypePCopy, DatumGetPointer(), elog(), ereport, errmsg(), ERROR, G_INT_GET_NUMRANGES, gistentryinit, i, internal_size(), j, GISTENTRY::key, GISTENTRY::leafkey, len, MAXNUMELTS, NOTICE, 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 {
49  GISTENTRY *entry = (GISTENTRY *) PG_GETARG_POINTER(0);
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  {
77  retval = inner_int_overlap((ArrayType *) DatumGetPointer(entry->key),
78  query);
79  break;
81  if (GIST_LEAF(entry))
83  entry->key,
84  PointerGetDatum(query),
85  PointerGetDatum(&retval));
86  else
87  retval = inner_int_contains((ArrayType *) DatumGetPointer(entry->key),
88  query);
89  break;
92  retval = inner_int_contains((ArrayType *) DatumGetPointer(entry->key),
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:49
bool inner_int_contains(ArrayType *a, ArrayType *b)
Definition: _int_tool.c:14
#define BooleanSearchStrategy
Definition: _int.h:134
bool execconsistent(QUERYTYPE *query, ArrayType *array, bool calcnot)
Definition: _int_bool.c:308
Datum g_int_same(PG_FUNCTION_ARGS)
Definition: _int_gist.c:380
#define PG_GETARG_ARRAYTYPE_P_COPY(n)
Definition: array.h:257
#define PG_GETARG_UINT16(n)
Definition: fmgr.h:272
#define DirectFunctionCall3(func, arg1, arg2, arg3)
Definition: fmgr.h:646
#define PG_RETURN_BOOL(x)
Definition: fmgr.h:359
#define GIST_LEAF(entry)
Definition: gist.h:168
#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 286 of file _int_gist.c.

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

References ARRISEMPTY, ARRNELEMS, ARRPTR, CHECKARRVALID, DatumGetArrayTypeP, DatumGetPointer(), ereport, 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 620 of file _int_gist.c.

621 {
623 
624  init_local_reloptions(relopts, sizeof(GISTIntArrayOptions));
625  add_local_int_reloption(relopts, "numranges",
626  "number of ranges for compression",
628  offsetof(GISTIntArrayOptions, num_ranges));
629 
630  PG_RETURN_VOID();
631 }
#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:736
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:920

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 358 of file _int_gist.c.

359 {
360  GISTENTRY *origentry = (GISTENTRY *) PG_GETARG_POINTER(0);
361  GISTENTRY *newentry = (GISTENTRY *) PG_GETARG_POINTER(1);
362  float *result = (float *) PG_GETARG_POINTER(2);
363  ArrayType *ud;
364  float tmp1,
365  tmp2;
366 
367  ud = inner_int_union((ArrayType *) DatumGetPointer(origentry->key),
368  (ArrayType *) DatumGetPointer(newentry->key));
369  rt__int_size(ud, &tmp1);
370  rt__int_size((ArrayType *) DatumGetPointer(origentry->key), &tmp2);
371  *result = tmp1 - tmp2;
372  pfree(ud);
373 
374  PG_RETURN_POINTER(result);
375 }
ArrayType * inner_int_union(ArrayType *a, ArrayType *b)
Definition: _int_tool.c:78
void rt__int_size(ArrayType *a, float *size)
Definition: _int_tool.c:183

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 436 of file _int_gist.c.

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

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 380 of file _int_gist.c.

381 {
384  bool *result = (bool *) PG_GETARG_POINTER(2);
385  int32 n = ARRNELEMS(a);
386  int32 *da,
387  *db;
388 
389  CHECKARRVALID(a);
390  CHECKARRVALID(b);
391 
392  if (n != ARRNELEMS(b))
393  {
394  *result = false;
395  PG_RETURN_POINTER(result);
396  }
397  *result = true;
398  da = ARRPTR(a);
399  db = ARRPTR(b);
400  while (n--)
401  {
402  if (*da++ != *db++)
403  {
404  *result = false;
405  break;
406  }
407  }
408 
409  PG_RETURN_POINTER(result);
410 }
#define PG_GETARG_ARRAYTYPE_P(n)
Definition: array.h:256

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:183
ArrayType * _int_unique(ArrayType *r)
Definition: _int_tool.c:310
#define VARSIZE(PTR)
Definition: postgres.h:317

References _int_unique(), ARRNELEMS, ARRPTR, CHECKARRVALID, GETENTRY, i, GistEntryVector::n, new_intArrayType(), PG_GETARG_POINTER, PG_RETURN_POINTER, QSORT, res, 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  )