PostgreSQL Source Code  git master
seg.c File Reference
#include "postgres.h"
#include <float.h>
#include <math.h>
#include "access/gist.h"
#include "access/stratnum.h"
#include "fmgr.h"
#include "segdata.h"
Include dependency graph for seg.c:

Go to the source code of this file.

Data Structures

struct  gseg_picksplit_item
 

Macros

#define DatumGetSegP(X)   ((SEG *) DatumGetPointer(X))
 
#define PG_GETARG_SEG_P(n)   DatumGetSegP(PG_GETARG_DATUM(n))
 

Functions

 PG_FUNCTION_INFO_V1 (seg_in)
 
 PG_FUNCTION_INFO_V1 (seg_out)
 
 PG_FUNCTION_INFO_V1 (seg_size)
 
 PG_FUNCTION_INFO_V1 (seg_lower)
 
 PG_FUNCTION_INFO_V1 (seg_upper)
 
 PG_FUNCTION_INFO_V1 (seg_center)
 
 PG_FUNCTION_INFO_V1 (gseg_consistent)
 
 PG_FUNCTION_INFO_V1 (gseg_compress)
 
 PG_FUNCTION_INFO_V1 (gseg_decompress)
 
 PG_FUNCTION_INFO_V1 (gseg_picksplit)
 
 PG_FUNCTION_INFO_V1 (gseg_penalty)
 
 PG_FUNCTION_INFO_V1 (gseg_union)
 
 PG_FUNCTION_INFO_V1 (gseg_same)
 
static Datum gseg_leaf_consistent (Datum key, Datum query, StrategyNumber strategy)
 
static Datum gseg_internal_consistent (Datum key, Datum query, StrategyNumber strategy)
 
static Datum gseg_binary_union (Datum r1, Datum r2, int *sizep)
 
 PG_FUNCTION_INFO_V1 (seg_same)
 
 PG_FUNCTION_INFO_V1 (seg_contains)
 
 PG_FUNCTION_INFO_V1 (seg_contained)
 
 PG_FUNCTION_INFO_V1 (seg_overlap)
 
 PG_FUNCTION_INFO_V1 (seg_left)
 
 PG_FUNCTION_INFO_V1 (seg_over_left)
 
 PG_FUNCTION_INFO_V1 (seg_right)
 
 PG_FUNCTION_INFO_V1 (seg_over_right)
 
 PG_FUNCTION_INFO_V1 (seg_union)
 
 PG_FUNCTION_INFO_V1 (seg_inter)
 
static void rt_seg_size (SEG *a, float *size)
 
 PG_FUNCTION_INFO_V1 (seg_cmp)
 
 PG_FUNCTION_INFO_V1 (seg_lt)
 
 PG_FUNCTION_INFO_V1 (seg_le)
 
 PG_FUNCTION_INFO_V1 (seg_gt)
 
 PG_FUNCTION_INFO_V1 (seg_ge)
 
 PG_FUNCTION_INFO_V1 (seg_different)
 
static int restore (char *result, float val, int n)
 
Datum seg_in (PG_FUNCTION_ARGS)
 
Datum seg_out (PG_FUNCTION_ARGS)
 
Datum seg_center (PG_FUNCTION_ARGS)
 
Datum seg_lower (PG_FUNCTION_ARGS)
 
Datum seg_upper (PG_FUNCTION_ARGS)
 
Datum gseg_consistent (PG_FUNCTION_ARGS)
 
Datum gseg_union (PG_FUNCTION_ARGS)
 
Datum gseg_compress (PG_FUNCTION_ARGS)
 
Datum gseg_decompress (PG_FUNCTION_ARGS)
 
Datum gseg_penalty (PG_FUNCTION_ARGS)
 
static int gseg_picksplit_item_cmp (const void *a, const void *b)
 
Datum gseg_picksplit (PG_FUNCTION_ARGS)
 
Datum gseg_same (PG_FUNCTION_ARGS)
 
Datum seg_contains (PG_FUNCTION_ARGS)
 
Datum seg_contained (PG_FUNCTION_ARGS)
 
Datum seg_same (PG_FUNCTION_ARGS)
 
Datum seg_overlap (PG_FUNCTION_ARGS)
 
Datum seg_over_left (PG_FUNCTION_ARGS)
 
Datum seg_left (PG_FUNCTION_ARGS)
 
Datum seg_right (PG_FUNCTION_ARGS)
 
Datum seg_over_right (PG_FUNCTION_ARGS)
 
Datum seg_union (PG_FUNCTION_ARGS)
 
Datum seg_inter (PG_FUNCTION_ARGS)
 
Datum seg_size (PG_FUNCTION_ARGS)
 
Datum seg_cmp (PG_FUNCTION_ARGS)
 
Datum seg_lt (PG_FUNCTION_ARGS)
 
Datum seg_le (PG_FUNCTION_ARGS)
 
Datum seg_gt (PG_FUNCTION_ARGS)
 
Datum seg_ge (PG_FUNCTION_ARGS)
 
Datum seg_different (PG_FUNCTION_ARGS)
 
int significant_digits (const char *s)
 

Variables

 PG_MODULE_MAGIC
 

Macro Definition Documentation

◆ DatumGetSegP

#define DatumGetSegP (   X)    ((SEG *) DatumGetPointer(X))

Definition at line 22 of file seg.c.

◆ PG_GETARG_SEG_P

#define PG_GETARG_SEG_P (   n)    DatumGetSegP(PG_GETARG_DATUM(n))

Definition at line 23 of file seg.c.

Function Documentation

◆ gseg_binary_union()

static Datum gseg_binary_union ( Datum  r1,
Datum  r2,
int *  sizep 
)
static

Definition at line 525 of file seg.c.

526 {
527  Datum retval;
528 
529  retval = DirectFunctionCall2(seg_union, r1, r2);
530  *sizep = sizeof(SEG);
531 
532  return retval;
533 }
#define DirectFunctionCall2(func, arg1, arg2)
Definition: fmgr.h:644
uintptr_t Datum
Definition: postgres.h:412
Datum seg_union(PG_FUNCTION_ARGS)
Definition: seg.c:625
struct SEG SEG

References DirectFunctionCall2, and seg_union().

Referenced by gseg_union().

◆ gseg_compress()

Datum gseg_compress ( PG_FUNCTION_ARGS  )

Definition at line 254 of file seg.c.

255 {
257 }
#define PG_GETARG_POINTER(n)
Definition: fmgr.h:276
#define PG_RETURN_POINTER(x)
Definition: fmgr.h:361

References PG_GETARG_POINTER, and PG_RETURN_POINTER.

◆ gseg_consistent()

Datum gseg_consistent ( PG_FUNCTION_ARGS  )

Definition at line 196 of file seg.c.

197 {
198  GISTENTRY *entry = (GISTENTRY *) PG_GETARG_POINTER(0);
199  Datum query = PG_GETARG_DATUM(1);
201 
202  /* Oid subtype = PG_GETARG_OID(3); */
203  bool *recheck = (bool *) PG_GETARG_POINTER(4);
204 
205  /* All cases served by this function are exact */
206  *recheck = false;
207 
208  /*
209  * if entry is not leaf, use gseg_internal_consistent, else use
210  * gseg_leaf_consistent
211  */
212  if (GIST_LEAF(entry))
213  return gseg_leaf_consistent(entry->key, query, strategy);
214  else
215  return gseg_internal_consistent(entry->key, query, strategy);
216 }
#define PG_GETARG_DATUM(n)
Definition: fmgr.h:268
#define PG_GETARG_UINT16(n)
Definition: fmgr.h:272
#define GIST_LEAF(entry)
Definition: gist.h:168
static Datum gseg_leaf_consistent(Datum key, Datum query, StrategyNumber strategy)
Definition: seg.c:432
static Datum gseg_internal_consistent(Datum key, Datum query, StrategyNumber strategy)
Definition: seg.c:476
uint16 StrategyNumber
Definition: stratnum.h:22
Datum key
Definition: gist.h:158

References GIST_LEAF, gseg_internal_consistent(), gseg_leaf_consistent(), GISTENTRY::key, PG_GETARG_DATUM, PG_GETARG_POINTER, and PG_GETARG_UINT16.

◆ gseg_decompress()

Datum gseg_decompress ( PG_FUNCTION_ARGS  )

Definition at line 260 of file seg.c.

261 {
263 }

References PG_GETARG_POINTER, and PG_RETURN_POINTER.

◆ gseg_internal_consistent()

static Datum gseg_internal_consistent ( Datum  key,
Datum  query,
StrategyNumber  strategy 
)
static

Definition at line 476 of file seg.c.

477 {
478  bool retval;
479 
480 #ifdef GIST_QUERY_DEBUG
481  fprintf(stderr, "internal_consistent, %d\n", strategy);
482 #endif
483 
484  switch (strategy)
485  {
487  retval =
489  break;
491  retval =
493  break;
495  retval =
497  break;
499  retval =
501  break;
503  retval =
505  break;
509  retval =
511  break;
514  retval =
516  break;
517  default:
518  retval = false;
519  }
520 
521  PG_RETURN_BOOL(retval);
522 }
#define PG_RETURN_BOOL(x)
Definition: fmgr.h:359
#define fprintf
Definition: port.h:242
static bool DatumGetBool(Datum X)
Definition: postgres.h:438
Datum seg_over_right(PG_FUNCTION_ARGS)
Definition: seg.c:616
Datum seg_overlap(PG_FUNCTION_ARGS)
Definition: seg.c:571
Datum seg_right(PG_FUNCTION_ARGS)
Definition: seg.c:605
Datum seg_left(PG_FUNCTION_ARGS)
Definition: seg.c:594
Datum seg_over_left(PG_FUNCTION_ARGS)
Definition: seg.c:583
Datum seg_contains(PG_FUNCTION_ARGS)
Definition: seg.c:537
#define RTOldContainsStrategyNumber
Definition: stratnum.h:63
#define RTOverlapStrategyNumber
Definition: stratnum.h:53
#define RTLeftStrategyNumber
Definition: stratnum.h:51
#define RTOverRightStrategyNumber
Definition: stratnum.h:54
#define RTRightStrategyNumber
Definition: stratnum.h:55
#define RTSameStrategyNumber
Definition: stratnum.h:56
#define RTContainsStrategyNumber
Definition: stratnum.h:57
#define RTOverLeftStrategyNumber
Definition: stratnum.h:52
#define RTOldContainedByStrategyNumber
Definition: stratnum.h:64
#define RTContainedByStrategyNumber
Definition: stratnum.h:58

References DatumGetBool(), DirectFunctionCall2, fprintf, sort-test::key, PG_RETURN_BOOL, RTContainedByStrategyNumber, RTContainsStrategyNumber, RTLeftStrategyNumber, RTOldContainedByStrategyNumber, RTOldContainsStrategyNumber, RTOverlapStrategyNumber, RTOverLeftStrategyNumber, RTOverRightStrategyNumber, RTRightStrategyNumber, RTSameStrategyNumber, seg_contains(), seg_left(), seg_over_left(), seg_over_right(), seg_overlap(), and seg_right().

Referenced by gseg_consistent().

◆ gseg_leaf_consistent()

static Datum gseg_leaf_consistent ( Datum  key,
Datum  query,
StrategyNumber  strategy 
)
static

Definition at line 432 of file seg.c.

433 {
434  Datum retval;
435 
436 #ifdef GIST_QUERY_DEBUG
437  fprintf(stderr, "leaf_consistent, %d\n", strategy);
438 #endif
439 
440  switch (strategy)
441  {
443  retval = DirectFunctionCall2(seg_left, key, query);
444  break;
446  retval = DirectFunctionCall2(seg_over_left, key, query);
447  break;
449  retval = DirectFunctionCall2(seg_overlap, key, query);
450  break;
452  retval = DirectFunctionCall2(seg_over_right, key, query);
453  break;
455  retval = DirectFunctionCall2(seg_right, key, query);
456  break;
458  retval = DirectFunctionCall2(seg_same, key, query);
459  break;
462  retval = DirectFunctionCall2(seg_contains, key, query);
463  break;
466  retval = DirectFunctionCall2(seg_contained, key, query);
467  break;
468  default:
469  retval = false;
470  }
471 
472  PG_RETURN_DATUM(retval);
473 }
#define PG_RETURN_DATUM(x)
Definition: fmgr.h:353
Datum seg_contained(PG_FUNCTION_ARGS)
Definition: seg.c:546
Datum seg_same(PG_FUNCTION_ARGS)
Definition: seg.c:559

References DirectFunctionCall2, fprintf, sort-test::key, PG_RETURN_DATUM, RTContainedByStrategyNumber, RTContainsStrategyNumber, RTLeftStrategyNumber, RTOldContainedByStrategyNumber, RTOldContainsStrategyNumber, RTOverlapStrategyNumber, RTOverLeftStrategyNumber, RTOverRightStrategyNumber, RTRightStrategyNumber, RTSameStrategyNumber, seg_contained(), seg_contains(), seg_left(), seg_over_left(), seg_over_right(), seg_overlap(), seg_right(), and seg_same().

Referenced by gseg_consistent().

◆ gseg_penalty()

Datum gseg_penalty ( PG_FUNCTION_ARGS  )

Definition at line 270 of file seg.c.

271 {
272  GISTENTRY *origentry = (GISTENTRY *) PG_GETARG_POINTER(0);
273  GISTENTRY *newentry = (GISTENTRY *) PG_GETARG_POINTER(1);
274  float *result = (float *) PG_GETARG_POINTER(2);
275  SEG *ud;
276  float tmp1,
277  tmp2;
278 
280  origentry->key,
281  newentry->key));
282  rt_seg_size(ud, &tmp1);
283  rt_seg_size(DatumGetSegP(origentry->key), &tmp2);
284  *result = tmp1 - tmp2;
285 
286 #ifdef GIST_DEBUG
287  fprintf(stderr, "penalty\n");
288  fprintf(stderr, "\t%g\n", *result);
289 #endif
290 
291  PG_RETURN_POINTER(result);
292 }
#define DatumGetSegP(X)
Definition: seg.c:22
static void rt_seg_size(SEG *a, float *size)
Definition: seg.c:705
Definition: segdata.h:5

References DatumGetSegP, DirectFunctionCall2, fprintf, GISTENTRY::key, PG_GETARG_POINTER, PG_RETURN_POINTER, rt_seg_size(), and seg_union().

◆ gseg_picksplit()

Datum gseg_picksplit ( PG_FUNCTION_ARGS  )

Definition at line 319 of file seg.c.

320 {
323  int i;
324  SEG *seg,
325  *seg_l,
326  *seg_r;
327  gseg_picksplit_item *sort_items;
328  OffsetNumber *left,
329  *right;
330  OffsetNumber maxoff;
331  OffsetNumber firstright;
332 
333 #ifdef GIST_DEBUG
334  fprintf(stderr, "picksplit\n");
335 #endif
336 
337  /* Valid items in entryvec->vector[] are indexed 1..maxoff */
338  maxoff = entryvec->n - 1;
339 
340  /*
341  * Prepare the auxiliary array and sort it.
342  */
343  sort_items = (gseg_picksplit_item *)
344  palloc(maxoff * sizeof(gseg_picksplit_item));
345  for (i = 1; i <= maxoff; i++)
346  {
347  seg = DatumGetSegP(entryvec->vector[i].key);
348  /* center calculation is done this way to avoid possible overflow */
349  sort_items[i - 1].center = seg->lower * 0.5f + seg->upper * 0.5f;
350  sort_items[i - 1].index = i;
351  sort_items[i - 1].data = seg;
352  }
353  qsort(sort_items, maxoff, sizeof(gseg_picksplit_item),
355 
356  /* sort items below "firstright" will go into the left side */
357  firstright = maxoff / 2;
358 
359  v->spl_left = (OffsetNumber *) palloc(maxoff * sizeof(OffsetNumber));
360  v->spl_right = (OffsetNumber *) palloc(maxoff * sizeof(OffsetNumber));
361  left = v->spl_left;
362  v->spl_nleft = 0;
363  right = v->spl_right;
364  v->spl_nright = 0;
365 
366  /*
367  * Emit segments to the left output page, and compute its bounding box.
368  */
369  seg_l = (SEG *) palloc(sizeof(SEG));
370  memcpy(seg_l, sort_items[0].data, sizeof(SEG));
371  *left++ = sort_items[0].index;
372  v->spl_nleft++;
373  for (i = 1; i < firstright; i++)
374  {
375  Datum sortitem = PointerGetDatum(sort_items[i].data);
376 
378  PointerGetDatum(seg_l),
379  sortitem));
380  *left++ = sort_items[i].index;
381  v->spl_nleft++;
382  }
383 
384  /*
385  * Likewise for the right page.
386  */
387  seg_r = (SEG *) palloc(sizeof(SEG));
388  memcpy(seg_r, sort_items[firstright].data, sizeof(SEG));
389  *right++ = sort_items[firstright].index;
390  v->spl_nright++;
391  for (i = firstright + 1; i < maxoff; i++)
392  {
393  Datum sortitem = PointerGetDatum(sort_items[i].data);
394 
396  PointerGetDatum(seg_r),
397  sortitem));
398  *right++ = sort_items[i].index;
399  v->spl_nright++;
400  }
401 
402  v->spl_ldatum = PointerGetDatum(seg_l);
403  v->spl_rdatum = PointerGetDatum(seg_r);
404 
406 }
int i
Definition: isn.c:73
void * palloc(Size size)
Definition: mcxt.c:1199
uint16 OffsetNumber
Definition: off.h:24
const void * data
#define qsort(a, b, c, d)
Definition: port.h:445
static Datum PointerGetDatum(const void *X)
Definition: postgres.h:670
static int gseg_picksplit_item_cmp(const void *a, const void *b)
Definition: seg.c:298
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
GISTENTRY vector[FLEXIBLE_ARRAY_MEMBER]
Definition: gist.h:234
int32 n
Definition: gist.h:233
float4 upper
Definition: segdata.h:7
float4 lower
Definition: segdata.h:6
OffsetNumber index
Definition: seg.c:39
float center
Definition: seg.c:38
SEG * data
Definition: seg.c:40

References gseg_picksplit_item::center, gseg_picksplit_item::data, data, DatumGetSegP, DirectFunctionCall2, fprintf, gseg_picksplit_item_cmp(), i, gseg_picksplit_item::index, GISTENTRY::key, SEG::lower, GistEntryVector::n, palloc(), PG_GETARG_POINTER, PG_RETURN_POINTER, PointerGetDatum(), qsort, seg_union(), GIST_SPLITVEC::spl_ldatum, GIST_SPLITVEC::spl_left, GIST_SPLITVEC::spl_nleft, GIST_SPLITVEC::spl_nright, GIST_SPLITVEC::spl_rdatum, GIST_SPLITVEC::spl_right, SEG::upper, and GistEntryVector::vector.

◆ gseg_picksplit_item_cmp()

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

Definition at line 298 of file seg.c.

299 {
300  const gseg_picksplit_item *i1 = (const gseg_picksplit_item *) a;
301  const gseg_picksplit_item *i2 = (const gseg_picksplit_item *) b;
302 
303  if (i1->center < i2->center)
304  return -1;
305  else if (i1->center == i2->center)
306  return 0;
307  else
308  return 1;
309 }
int b
Definition: isn.c:70
int a
Definition: isn.c:69

References a, b, and gseg_picksplit_item::center.

Referenced by gseg_picksplit().

◆ gseg_same()

Datum gseg_same ( PG_FUNCTION_ARGS  )

Definition at line 412 of file seg.c.

413 {
414  bool *result = (bool *) PG_GETARG_POINTER(2);
415 
417  *result = true;
418  else
419  *result = false;
420 
421 #ifdef GIST_DEBUG
422  fprintf(stderr, "same: %s\n", (*result ? "TRUE" : "FALSE"));
423 #endif
424 
425  PG_RETURN_POINTER(result);
426 }

References DirectFunctionCall2, fprintf, PG_GETARG_DATUM, PG_GETARG_POINTER, PG_RETURN_POINTER, and seg_same().

◆ gseg_union()

Datum gseg_union ( PG_FUNCTION_ARGS  )

Definition at line 223 of file seg.c.

224 {
226  int *sizep = (int *) PG_GETARG_POINTER(1);
227  int numranges,
228  i;
229  Datum out = 0;
230  Datum tmp;
231 
232 #ifdef GIST_DEBUG
233  fprintf(stderr, "union\n");
234 #endif
235 
236  numranges = entryvec->n;
237  tmp = entryvec->vector[0].key;
238  *sizep = sizeof(SEG);
239 
240  for (i = 1; i < numranges; i++)
241  {
242  out = gseg_binary_union(tmp, entryvec->vector[i].key, sizep);
243  tmp = out;
244  }
245 
246  PG_RETURN_DATUM(out);
247 }
static Datum gseg_binary_union(Datum r1, Datum r2, int *sizep)
Definition: seg.c:525

References fprintf, gseg_binary_union(), i, GISTENTRY::key, GistEntryVector::n, PG_GETARG_POINTER, PG_RETURN_DATUM, and GistEntryVector::vector.

◆ PG_FUNCTION_INFO_V1() [1/29]

PG_FUNCTION_INFO_V1 ( gseg_compress  )

◆ PG_FUNCTION_INFO_V1() [2/29]

PG_FUNCTION_INFO_V1 ( gseg_consistent  )

◆ PG_FUNCTION_INFO_V1() [3/29]

PG_FUNCTION_INFO_V1 ( gseg_decompress  )

◆ PG_FUNCTION_INFO_V1() [4/29]

PG_FUNCTION_INFO_V1 ( gseg_penalty  )

◆ PG_FUNCTION_INFO_V1() [5/29]

PG_FUNCTION_INFO_V1 ( gseg_picksplit  )

◆ PG_FUNCTION_INFO_V1() [6/29]

PG_FUNCTION_INFO_V1 ( gseg_same  )

◆ PG_FUNCTION_INFO_V1() [7/29]

PG_FUNCTION_INFO_V1 ( gseg_union  )

◆ PG_FUNCTION_INFO_V1() [8/29]

PG_FUNCTION_INFO_V1 ( seg_center  )

◆ PG_FUNCTION_INFO_V1() [9/29]

PG_FUNCTION_INFO_V1 ( seg_cmp  )

◆ PG_FUNCTION_INFO_V1() [10/29]

PG_FUNCTION_INFO_V1 ( seg_contained  )

◆ PG_FUNCTION_INFO_V1() [11/29]

PG_FUNCTION_INFO_V1 ( seg_contains  )

◆ PG_FUNCTION_INFO_V1() [12/29]

PG_FUNCTION_INFO_V1 ( seg_different  )

◆ PG_FUNCTION_INFO_V1() [13/29]

PG_FUNCTION_INFO_V1 ( seg_ge  )

◆ PG_FUNCTION_INFO_V1() [14/29]

PG_FUNCTION_INFO_V1 ( seg_gt  )

◆ PG_FUNCTION_INFO_V1() [15/29]

PG_FUNCTION_INFO_V1 ( seg_in  )

◆ PG_FUNCTION_INFO_V1() [16/29]

PG_FUNCTION_INFO_V1 ( seg_inter  )

◆ PG_FUNCTION_INFO_V1() [17/29]

PG_FUNCTION_INFO_V1 ( seg_le  )

◆ PG_FUNCTION_INFO_V1() [18/29]

PG_FUNCTION_INFO_V1 ( seg_left  )

◆ PG_FUNCTION_INFO_V1() [19/29]

PG_FUNCTION_INFO_V1 ( seg_lower  )

◆ PG_FUNCTION_INFO_V1() [20/29]

PG_FUNCTION_INFO_V1 ( seg_lt  )

◆ PG_FUNCTION_INFO_V1() [21/29]

PG_FUNCTION_INFO_V1 ( seg_out  )

◆ PG_FUNCTION_INFO_V1() [22/29]

PG_FUNCTION_INFO_V1 ( seg_over_left  )

◆ PG_FUNCTION_INFO_V1() [23/29]

PG_FUNCTION_INFO_V1 ( seg_over_right  )

◆ PG_FUNCTION_INFO_V1() [24/29]

PG_FUNCTION_INFO_V1 ( seg_overlap  )

◆ PG_FUNCTION_INFO_V1() [25/29]

PG_FUNCTION_INFO_V1 ( seg_right  )

◆ PG_FUNCTION_INFO_V1() [26/29]

PG_FUNCTION_INFO_V1 ( seg_same  )

◆ PG_FUNCTION_INFO_V1() [27/29]

PG_FUNCTION_INFO_V1 ( seg_size  )

◆ PG_FUNCTION_INFO_V1() [28/29]

PG_FUNCTION_INFO_V1 ( seg_union  )

◆ PG_FUNCTION_INFO_V1() [29/29]

PG_FUNCTION_INFO_V1 ( seg_upper  )

◆ restore()

static int restore ( char *  result,
float  val,
int  n 
)
static

Definition at line 914 of file seg.c.

915 {
916  char buf[25] = {
917  '0', '0', '0', '0', '0',
918  '0', '0', '0', '0', '0',
919  '0', '0', '0', '0', '0',
920  '0', '0', '0', '0', '0',
921  '0', '0', '0', '0', '\0'
922  };
923  char *p;
924  int exp;
925  int i,
926  dp,
927  sign;
928 
929  /*
930  * Put a cap on the number of significant digits to avoid garbage in the
931  * output and ensure we don't overrun the result buffer.
932  */
933  n = Min(n, FLT_DIG);
934 
935  /* remember the sign */
936  sign = (val < 0 ? 1 : 0);
937 
938  /* print, in %e style to start with */
939  sprintf(result, "%.*e", n - 1, val);
940 
941  /* find the exponent */
942  p = strchr(result, 'e');
943 
944  /* punt if we have 'inf' or similar */
945  if (p == NULL)
946  return strlen(result);
947 
948  exp = atoi(p + 1);
949  if (exp == 0)
950  {
951  /* just truncate off the 'e+00' */
952  *p = '\0';
953  }
954  else
955  {
956  if (abs(exp) <= 4)
957  {
958  /*
959  * remove the decimal point from the mantissa and write the digits
960  * to the buf array
961  */
962  for (p = result + sign, i = 10, dp = 0; *p != 'e'; p++, i++)
963  {
964  buf[i] = *p;
965  if (*p == '.')
966  {
967  dp = i--; /* skip the decimal point */
968  }
969  }
970  if (dp == 0)
971  dp = i--; /* no decimal point was found in the above
972  * for() loop */
973 
974  if (exp > 0)
975  {
976  if (dp - 10 + exp >= n)
977  {
978  /*
979  * the decimal point is behind the last significant digit;
980  * the digits in between must be converted to the exponent
981  * and the decimal point placed after the first digit
982  */
983  exp = dp - 10 + exp - n;
984  buf[10 + n] = '\0';
985 
986  /* insert the decimal point */
987  if (n > 1)
988  {
989  dp = 11;
990  for (i = 23; i > dp; i--)
991  buf[i] = buf[i - 1];
992  buf[dp] = '.';
993  }
994 
995  /*
996  * adjust the exponent by the number of digits after the
997  * decimal point
998  */
999  if (n > 1)
1000  sprintf(&buf[11 + n], "e%d", exp + n - 1);
1001  else
1002  sprintf(&buf[11], "e%d", exp + n - 1);
1003 
1004  if (sign)
1005  {
1006  buf[9] = '-';
1007  strcpy(result, &buf[9]);
1008  }
1009  else
1010  strcpy(result, &buf[10]);
1011  }
1012  else
1013  { /* insert the decimal point */
1014  dp += exp;
1015  for (i = 23; i > dp; i--)
1016  buf[i] = buf[i - 1];
1017  buf[11 + n] = '\0';
1018  buf[dp] = '.';
1019  if (sign)
1020  {
1021  buf[9] = '-';
1022  strcpy(result, &buf[9]);
1023  }
1024  else
1025  strcpy(result, &buf[10]);
1026  }
1027  }
1028  else
1029  { /* exp <= 0 */
1030  dp += exp - 1;
1031  buf[10 + n] = '\0';
1032  buf[dp] = '.';
1033  if (sign)
1034  {
1035  buf[dp - 2] = '-';
1036  strcpy(result, &buf[dp - 2]);
1037  }
1038  else
1039  strcpy(result, &buf[dp - 1]);
1040  }
1041  }
1042 
1043  /* do nothing for abs(exp) > 4; %e must be OK */
1044  /* just get rid of zeroes after [eE]- and +zeroes after [Ee]. */
1045 
1046  /* ... this is not done yet. */
1047  }
1048  return strlen(result);
1049 }
#define Min(x, y)
Definition: c.h:937
long val
Definition: informix.c:664
char sign
Definition: informix.c:668
static char * buf
Definition: pg_test_fsync.c:67
#define sprintf
Definition: port.h:240

References buf, i, Min, sign, sprintf, and val.

Referenced by seg_out().

◆ rt_seg_size()

static void rt_seg_size ( SEG a,
float *  size 
)
static

Definition at line 705 of file seg.c.

706 {
707  if (a == (SEG *) NULL || a->upper <= a->lower)
708  *size = 0.0;
709  else
710  *size = fabsf(a->upper - a->lower);
711 }

References a.

Referenced by gseg_penalty().

◆ seg_center()

Datum seg_center ( PG_FUNCTION_ARGS  )

Definition at line 161 of file seg.c.

162 {
163  SEG *seg = PG_GETARG_SEG_P(0);
164 
165  PG_RETURN_FLOAT4(((float) seg->lower + (float) seg->upper) / 2.0);
166 }
#define PG_RETURN_FLOAT4(x)
Definition: fmgr.h:366
#define PG_GETARG_SEG_P(n)
Definition: seg.c:23

References SEG::lower, PG_GETARG_SEG_P, PG_RETURN_FLOAT4, and SEG::upper.

◆ seg_cmp()

Datum seg_cmp ( PG_FUNCTION_ARGS  )

Definition at line 726 of file seg.c.

727 {
728  SEG *a = PG_GETARG_SEG_P(0);
729  SEG *b = PG_GETARG_SEG_P(1);
730 
731  /*
732  * First compare on lower boundary position
733  */
734  if (a->lower < b->lower)
735  PG_RETURN_INT32(-1);
736  if (a->lower > b->lower)
737  PG_RETURN_INT32(1);
738 
739  /*
740  * a->lower == b->lower, so consider type of boundary.
741  *
742  * A '-' lower bound is < any other kind (this could only be relevant if
743  * -HUGE_VAL is used as a regular data value). A '<' lower bound is < any
744  * other kind except '-'. A '>' lower bound is > any other kind.
745  */
746  if (a->l_ext != b->l_ext)
747  {
748  if (a->l_ext == '-')
749  PG_RETURN_INT32(-1);
750  if (b->l_ext == '-')
751  PG_RETURN_INT32(1);
752  if (a->l_ext == '<')
753  PG_RETURN_INT32(-1);
754  if (b->l_ext == '<')
755  PG_RETURN_INT32(1);
756  if (a->l_ext == '>')
757  PG_RETURN_INT32(1);
758  if (b->l_ext == '>')
759  PG_RETURN_INT32(-1);
760  }
761 
762  /*
763  * For other boundary types, consider # of significant digits first.
764  */
765  if (a->l_sigd < b->l_sigd) /* (a) is blurred and is likely to include (b) */
766  PG_RETURN_INT32(-1);
767  if (a->l_sigd > b->l_sigd) /* (a) is less blurred and is likely to be
768  * included in (b) */
769  PG_RETURN_INT32(1);
770 
771  /*
772  * For same # of digits, an approximate boundary is more blurred than
773  * exact.
774  */
775  if (a->l_ext != b->l_ext)
776  {
777  if (a->l_ext == '~') /* (a) is approximate, while (b) is exact */
778  PG_RETURN_INT32(-1);
779  if (b->l_ext == '~')
780  PG_RETURN_INT32(1);
781  /* can't get here unless data is corrupt */
782  elog(ERROR, "bogus lower boundary types %d %d",
783  (int) a->l_ext, (int) b->l_ext);
784  }
785 
786  /* at this point, the lower boundaries are identical */
787 
788  /*
789  * First compare on upper boundary position
790  */
791  if (a->upper < b->upper)
792  PG_RETURN_INT32(-1);
793  if (a->upper > b->upper)
794  PG_RETURN_INT32(1);
795 
796  /*
797  * a->upper == b->upper, so consider type of boundary.
798  *
799  * A '-' upper bound is > any other kind (this could only be relevant if
800  * HUGE_VAL is used as a regular data value). A '<' upper bound is < any
801  * other kind. A '>' upper bound is > any other kind except '-'.
802  */
803  if (a->u_ext != b->u_ext)
804  {
805  if (a->u_ext == '-')
806  PG_RETURN_INT32(1);
807  if (b->u_ext == '-')
808  PG_RETURN_INT32(-1);
809  if (a->u_ext == '<')
810  PG_RETURN_INT32(-1);
811  if (b->u_ext == '<')
812  PG_RETURN_INT32(1);
813  if (a->u_ext == '>')
814  PG_RETURN_INT32(1);
815  if (b->u_ext == '>')
816  PG_RETURN_INT32(-1);
817  }
818 
819  /*
820  * For other boundary types, consider # of significant digits first. Note
821  * result here is converse of the lower-boundary case.
822  */
823  if (a->u_sigd < b->u_sigd) /* (a) is blurred and is likely to include (b) */
824  PG_RETURN_INT32(1);
825  if (a->u_sigd > b->u_sigd) /* (a) is less blurred and is likely to be
826  * included in (b) */
827  PG_RETURN_INT32(-1);
828 
829  /*
830  * For same # of digits, an approximate boundary is more blurred than
831  * exact. Again, result is converse of lower-boundary case.
832  */
833  if (a->u_ext != b->u_ext)
834  {
835  if (a->u_ext == '~') /* (a) is approximate, while (b) is exact */
836  PG_RETURN_INT32(1);
837  if (b->u_ext == '~')
838  PG_RETURN_INT32(-1);
839  /* can't get here unless data is corrupt */
840  elog(ERROR, "bogus upper boundary types %d %d",
841  (int) a->u_ext, (int) b->u_ext);
842  }
843 
844  PG_RETURN_INT32(0);
845 }
#define ERROR
Definition: elog.h:35
#define PG_RETURN_INT32(x)
Definition: fmgr.h:354

References a, b, elog(), ERROR, PG_GETARG_SEG_P, and PG_RETURN_INT32.

Referenced by seg_different(), seg_ge(), seg_gt(), seg_le(), seg_lt(), and seg_same().

◆ seg_contained()

Datum seg_contained ( PG_FUNCTION_ARGS  )

Definition at line 546 of file seg.c.

547 {
548  Datum a = PG_GETARG_DATUM(0);
549  Datum b = PG_GETARG_DATUM(1);
550 
552 }

References a, b, DirectFunctionCall2, PG_GETARG_DATUM, PG_RETURN_DATUM, and seg_contains().

Referenced by gseg_leaf_consistent().

◆ seg_contains()

Datum seg_contains ( PG_FUNCTION_ARGS  )

Definition at line 537 of file seg.c.

538 {
539  SEG *a = PG_GETARG_SEG_P(0);
540  SEG *b = PG_GETARG_SEG_P(1);
541 
542  PG_RETURN_BOOL((a->lower <= b->lower) && (a->upper >= b->upper));
543 }

References a, b, PG_GETARG_SEG_P, and PG_RETURN_BOOL.

Referenced by gseg_internal_consistent(), gseg_leaf_consistent(), and seg_contained().

◆ seg_different()

Datum seg_different ( PG_FUNCTION_ARGS  )

Definition at line 889 of file seg.c.

890 {
892  PG_GETARG_DATUM(0),
893  PG_GETARG_DATUM(1)));
894 
895  PG_RETURN_BOOL(cmp != 0);
896 }
static int32 DatumGetInt32(Datum X)
Definition: postgres.h:550
static int cmp(const chr *x, const chr *y, size_t len)
Definition: regc_locale.c:747
Datum seg_cmp(PG_FUNCTION_ARGS)
Definition: seg.c:726

References cmp(), DatumGetInt32(), DirectFunctionCall2, PG_GETARG_DATUM, PG_RETURN_BOOL, and seg_cmp().

◆ seg_ge()

Datum seg_ge ( PG_FUNCTION_ARGS  )

Definition at line 878 of file seg.c.

879 {
881  PG_GETARG_DATUM(0),
882  PG_GETARG_DATUM(1)));
883 
884  PG_RETURN_BOOL(cmp >= 0);
885 }

References cmp(), DatumGetInt32(), DirectFunctionCall2, PG_GETARG_DATUM, PG_RETURN_BOOL, and seg_cmp().

◆ seg_gt()

Datum seg_gt ( PG_FUNCTION_ARGS  )

Definition at line 868 of file seg.c.

869 {
871  PG_GETARG_DATUM(0),
872  PG_GETARG_DATUM(1)));
873 
874  PG_RETURN_BOOL(cmp > 0);
875 }

References cmp(), DatumGetInt32(), DirectFunctionCall2, PG_GETARG_DATUM, PG_RETURN_BOOL, and seg_cmp().

◆ seg_in()

Datum seg_in ( PG_FUNCTION_ARGS  )

Definition at line 104 of file seg.c.

105 {
106  char *str = PG_GETARG_CSTRING(0);
107  SEG *result = palloc(sizeof(SEG));
108 
110 
111  if (seg_yyparse(result) != 0)
112  seg_yyerror(result, "bogus input");
113 
115 
116  PG_RETURN_POINTER(result);
117 }
#define PG_GETARG_CSTRING(n)
Definition: fmgr.h:277
int seg_yyparse(SEG *result)
void seg_yyerror(SEG *result, const char *message) pg_attribute_noreturn()
void seg_scanner_init(const char *str)
void seg_scanner_finish(void)

References palloc(), PG_GETARG_CSTRING, PG_RETURN_POINTER, seg_scanner_finish(), seg_scanner_init(), seg_yyerror(), seg_yyparse(), and generate_unaccent_rules::str.

◆ seg_inter()

Datum seg_inter ( PG_FUNCTION_ARGS  )

Definition at line 665 of file seg.c.

666 {
667  SEG *a = PG_GETARG_SEG_P(0);
668  SEG *b = PG_GETARG_SEG_P(1);
669  SEG *n;
670 
671  n = (SEG *) palloc(sizeof(*n));
672 
673  /* take min of upper endpoints */
674  if (a->upper < b->upper)
675  {
676  n->upper = a->upper;
677  n->u_sigd = a->u_sigd;
678  n->u_ext = a->u_ext;
679  }
680  else
681  {
682  n->upper = b->upper;
683  n->u_sigd = b->u_sigd;
684  n->u_ext = b->u_ext;
685  }
686 
687  /* take max of lower endpoints */
688  if (a->lower > b->lower)
689  {
690  n->lower = a->lower;
691  n->l_sigd = a->l_sigd;
692  n->l_ext = a->l_ext;
693  }
694  else
695  {
696  n->lower = b->lower;
697  n->l_sigd = b->l_sigd;
698  n->l_ext = b->l_ext;
699  }
700 
702 }
char l_ext
Definition: segdata.h:10
char l_sigd
Definition: segdata.h:8
char u_sigd
Definition: segdata.h:9
char u_ext
Definition: segdata.h:11

References a, b, SEG::l_ext, SEG::l_sigd, SEG::lower, palloc(), PG_GETARG_SEG_P, PG_RETURN_POINTER, SEG::u_ext, SEG::u_sigd, and SEG::upper.

◆ seg_le()

Datum seg_le ( PG_FUNCTION_ARGS  )

Definition at line 858 of file seg.c.

859 {
861  PG_GETARG_DATUM(0),
862  PG_GETARG_DATUM(1)));
863 
864  PG_RETURN_BOOL(cmp <= 0);
865 }

References cmp(), DatumGetInt32(), DirectFunctionCall2, PG_GETARG_DATUM, PG_RETURN_BOOL, and seg_cmp().

◆ seg_left()

Datum seg_left ( PG_FUNCTION_ARGS  )

Definition at line 594 of file seg.c.

595 {
596  SEG *a = PG_GETARG_SEG_P(0);
597  SEG *b = PG_GETARG_SEG_P(1);
598 
599  PG_RETURN_BOOL(a->upper < b->lower);
600 }

References a, b, PG_GETARG_SEG_P, and PG_RETURN_BOOL.

Referenced by gseg_internal_consistent(), and gseg_leaf_consistent().

◆ seg_lower()

Datum seg_lower ( PG_FUNCTION_ARGS  )

Definition at line 169 of file seg.c.

170 {
171  SEG *seg = PG_GETARG_SEG_P(0);
172 
173  PG_RETURN_FLOAT4(seg->lower);
174 }

References SEG::lower, PG_GETARG_SEG_P, and PG_RETURN_FLOAT4.

◆ seg_lt()

Datum seg_lt ( PG_FUNCTION_ARGS  )

Definition at line 848 of file seg.c.

849 {
851  PG_GETARG_DATUM(0),
852  PG_GETARG_DATUM(1)));
853 
854  PG_RETURN_BOOL(cmp < 0);
855 }

References cmp(), DatumGetInt32(), DirectFunctionCall2, PG_GETARG_DATUM, PG_RETURN_BOOL, and seg_cmp().

◆ seg_out()

Datum seg_out ( PG_FUNCTION_ARGS  )

Definition at line 120 of file seg.c.

121 {
122  SEG *seg = PG_GETARG_SEG_P(0);
123  char *result;
124  char *p;
125 
126  p = result = (char *) palloc(40);
127 
128  if (seg->l_ext == '>' || seg->l_ext == '<' || seg->l_ext == '~')
129  p += sprintf(p, "%c", seg->l_ext);
130 
131  if (seg->lower == seg->upper && seg->l_ext == seg->u_ext)
132  {
133  /*
134  * indicates that this interval was built by seg_in off a single point
135  */
136  p += restore(p, seg->lower, seg->l_sigd);
137  }
138  else
139  {
140  if (seg->l_ext != '-')
141  {
142  /* print the lower boundary if exists */
143  p += restore(p, seg->lower, seg->l_sigd);
144  p += sprintf(p, " ");
145  }
146  p += sprintf(p, "..");
147  if (seg->u_ext != '-')
148  {
149  /* print the upper boundary if exists */
150  p += sprintf(p, " ");
151  if (seg->u_ext == '>' || seg->u_ext == '<' || seg->l_ext == '~')
152  p += sprintf(p, "%c", seg->u_ext);
153  p += restore(p, seg->upper, seg->u_sigd);
154  }
155  }
156 
157  PG_RETURN_CSTRING(result);
158 }
#define PG_RETURN_CSTRING(x)
Definition: fmgr.h:362
static int restore(char *result, float val, int n)
Definition: seg.c:914

References SEG::l_ext, SEG::l_sigd, SEG::lower, palloc(), PG_GETARG_SEG_P, PG_RETURN_CSTRING, restore(), sprintf, SEG::u_ext, SEG::u_sigd, and SEG::upper.

◆ seg_over_left()

Datum seg_over_left ( PG_FUNCTION_ARGS  )

Definition at line 583 of file seg.c.

584 {
585  SEG *a = PG_GETARG_SEG_P(0);
586  SEG *b = PG_GETARG_SEG_P(1);
587 
588  PG_RETURN_BOOL(a->upper <= b->upper);
589 }

References a, b, PG_GETARG_SEG_P, and PG_RETURN_BOOL.

Referenced by gseg_internal_consistent(), and gseg_leaf_consistent().

◆ seg_over_right()

Datum seg_over_right ( PG_FUNCTION_ARGS  )

Definition at line 616 of file seg.c.

617 {
618  SEG *a = PG_GETARG_SEG_P(0);
619  SEG *b = PG_GETARG_SEG_P(1);
620 
621  PG_RETURN_BOOL(a->lower >= b->lower);
622 }

References a, b, PG_GETARG_SEG_P, and PG_RETURN_BOOL.

Referenced by gseg_internal_consistent(), and gseg_leaf_consistent().

◆ seg_overlap()

Datum seg_overlap ( PG_FUNCTION_ARGS  )

Definition at line 571 of file seg.c.

572 {
573  SEG *a = PG_GETARG_SEG_P(0);
574  SEG *b = PG_GETARG_SEG_P(1);
575 
576  PG_RETURN_BOOL(((a->upper >= b->upper) && (a->lower <= b->upper)) ||
577  ((b->upper >= a->upper) && (b->lower <= a->upper)));
578 }

References a, b, PG_GETARG_SEG_P, and PG_RETURN_BOOL.

Referenced by gseg_internal_consistent(), and gseg_leaf_consistent().

◆ seg_right()

Datum seg_right ( PG_FUNCTION_ARGS  )

Definition at line 605 of file seg.c.

606 {
607  SEG *a = PG_GETARG_SEG_P(0);
608  SEG *b = PG_GETARG_SEG_P(1);
609 
610  PG_RETURN_BOOL(a->lower > b->upper);
611 }

References a, b, PG_GETARG_SEG_P, and PG_RETURN_BOOL.

Referenced by gseg_internal_consistent(), and gseg_leaf_consistent().

◆ seg_same()

Datum seg_same ( PG_FUNCTION_ARGS  )

Definition at line 559 of file seg.c.

560 {
562  PG_GETARG_DATUM(0),
563  PG_GETARG_DATUM(1)));
564 
565  PG_RETURN_BOOL(cmp == 0);
566 }

References cmp(), DatumGetInt32(), DirectFunctionCall2, PG_GETARG_DATUM, PG_RETURN_BOOL, and seg_cmp().

Referenced by gseg_leaf_consistent(), and gseg_same().

◆ seg_size()

Datum seg_size ( PG_FUNCTION_ARGS  )

Definition at line 714 of file seg.c.

715 {
716  SEG *seg = PG_GETARG_SEG_P(0);
717 
718  PG_RETURN_FLOAT4(fabsf(seg->upper - seg->lower));
719 }

References SEG::lower, PG_GETARG_SEG_P, PG_RETURN_FLOAT4, and SEG::upper.

◆ seg_union()

Datum seg_union ( PG_FUNCTION_ARGS  )

Definition at line 625 of file seg.c.

626 {
627  SEG *a = PG_GETARG_SEG_P(0);
628  SEG *b = PG_GETARG_SEG_P(1);
629  SEG *n;
630 
631  n = (SEG *) palloc(sizeof(*n));
632 
633  /* take max of upper endpoints */
634  if (a->upper > b->upper)
635  {
636  n->upper = a->upper;
637  n->u_sigd = a->u_sigd;
638  n->u_ext = a->u_ext;
639  }
640  else
641  {
642  n->upper = b->upper;
643  n->u_sigd = b->u_sigd;
644  n->u_ext = b->u_ext;
645  }
646 
647  /* take min of lower endpoints */
648  if (a->lower < b->lower)
649  {
650  n->lower = a->lower;
651  n->l_sigd = a->l_sigd;
652  n->l_ext = a->l_ext;
653  }
654  else
655  {
656  n->lower = b->lower;
657  n->l_sigd = b->l_sigd;
658  n->l_ext = b->l_ext;
659  }
660 
662 }

References a, b, SEG::l_ext, SEG::l_sigd, SEG::lower, palloc(), PG_GETARG_SEG_P, PG_RETURN_POINTER, SEG::u_ext, SEG::u_sigd, and SEG::upper.

Referenced by gseg_binary_union(), gseg_penalty(), and gseg_picksplit().

◆ seg_upper()

Datum seg_upper ( PG_FUNCTION_ARGS  )

Definition at line 177 of file seg.c.

178 {
179  SEG *seg = PG_GETARG_SEG_P(0);
180 
181  PG_RETURN_FLOAT4(seg->upper);
182 }

References PG_GETARG_SEG_P, PG_RETURN_FLOAT4, and SEG::upper.

◆ significant_digits()

int significant_digits ( const char *  s)

Definition at line 1060 of file seg.c.

1061 {
1062  const char *p = s;
1063  int n,
1064  c,
1065  zeroes;
1066 
1067  zeroes = 1;
1068  /* skip leading zeroes and sign */
1069  for (c = *p; (c == '0' || c == '+' || c == '-') && c != 0; c = *(++p));
1070 
1071  /* skip decimal point and following zeroes */
1072  for (c = *p; (c == '0' || c == '.') && c != 0; c = *(++p))
1073  {
1074  if (c != '.')
1075  zeroes++;
1076  }
1077 
1078  /* count significant digits (n) */
1079  for (c = *p, n = 0; c != 0; c = *(++p))
1080  {
1081  if (!((c >= '0' && c <= '9') || (c == '.')))
1082  break;
1083  if (c != '.')
1084  n++;
1085  }
1086 
1087  if (!n)
1088  return zeroes;
1089 
1090  return n;
1091 }
char * c

Variable Documentation

◆ PG_MODULE_MAGIC

PG_MODULE_MAGIC

Definition at line 31 of file seg.c.