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:64
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:170
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:160

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:90
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:1304
uint16 OffsetNumber
Definition: off.h:24
const void * data
#define qsort(a, b, c, d)
Definition: port.h:449
static Datum PointerGetDatum(const void *X)
Definition: postgres.h:322
static int gseg_picksplit_item_cmp(const void *a, const void *b)
Definition: seg.c:298
int spl_nleft
Definition: gist.h:143
OffsetNumber * spl_right
Definition: gist.h:147
Datum spl_ldatum
Definition: gist.h:144
Datum spl_rdatum
Definition: gist.h:149
int spl_nright
Definition: gist.h:148
OffsetNumber * spl_left
Definition: gist.h:142
GISTENTRY vector[FLEXIBLE_ARRAY_MEMBER]
Definition: gist.h:236
int32 n
Definition: gist.h:235
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. (n should not be
932  * negative, but check to protect ourselves against corrupted data.)
933  */
934  if (n <= 0)
935  n = FLT_DIG;
936  else
937  n = Min(n, FLT_DIG);
938 
939  /* remember the sign */
940  sign = (val < 0 ? 1 : 0);
941 
942  /* print, in %e style to start with */
943  sprintf(result, "%.*e", n - 1, val);
944 
945  /* find the exponent */
946  p = strchr(result, 'e');
947 
948  /* punt if we have 'inf' or similar */
949  if (p == NULL)
950  return strlen(result);
951 
952  exp = atoi(p + 1);
953  if (exp == 0)
954  {
955  /* just truncate off the 'e+00' */
956  *p = '\0';
957  }
958  else
959  {
960  if (abs(exp) <= 4)
961  {
962  /*
963  * remove the decimal point from the mantissa and write the digits
964  * to the buf array
965  */
966  for (p = result + sign, i = 10, dp = 0; *p != 'e'; p++, i++)
967  {
968  buf[i] = *p;
969  if (*p == '.')
970  {
971  dp = i--; /* skip the decimal point */
972  }
973  }
974  if (dp == 0)
975  dp = i--; /* no decimal point was found in the above
976  * for() loop */
977 
978  if (exp > 0)
979  {
980  if (dp - 10 + exp >= n)
981  {
982  /*
983  * the decimal point is behind the last significant digit;
984  * the digits in between must be converted to the exponent
985  * and the decimal point placed after the first digit
986  */
987  exp = dp - 10 + exp - n;
988  buf[10 + n] = '\0';
989 
990  /* insert the decimal point */
991  if (n > 1)
992  {
993  dp = 11;
994  for (i = 23; i > dp; i--)
995  buf[i] = buf[i - 1];
996  buf[dp] = '.';
997  }
998 
999  /*
1000  * adjust the exponent by the number of digits after the
1001  * decimal point
1002  */
1003  if (n > 1)
1004  sprintf(&buf[11 + n], "e%d", exp + n - 1);
1005  else
1006  sprintf(&buf[11], "e%d", exp + n - 1);
1007 
1008  if (sign)
1009  {
1010  buf[9] = '-';
1011  strcpy(result, &buf[9]);
1012  }
1013  else
1014  strcpy(result, &buf[10]);
1015  }
1016  else
1017  { /* insert the decimal point */
1018  dp += exp;
1019  for (i = 23; i > dp; i--)
1020  buf[i] = buf[i - 1];
1021  buf[11 + n] = '\0';
1022  buf[dp] = '.';
1023  if (sign)
1024  {
1025  buf[9] = '-';
1026  strcpy(result, &buf[9]);
1027  }
1028  else
1029  strcpy(result, &buf[10]);
1030  }
1031  }
1032  else
1033  { /* exp <= 0 */
1034  dp += exp - 1;
1035  buf[10 + n] = '\0';
1036  buf[dp] = '.';
1037  if (sign)
1038  {
1039  buf[dp - 2] = '-';
1040  strcpy(result, &buf[dp - 2]);
1041  }
1042  else
1043  strcpy(result, &buf[dp - 1]);
1044  }
1045  }
1046 
1047  /* do nothing for abs(exp) > 4; %e must be OK */
1048  /* just get rid of zeroes after [eE]- and +zeroes after [Ee]. */
1049 
1050  /* ... this is not done yet. */
1051  }
1052  return strlen(result);
1053 }
#define Min(x, y)
Definition: c.h:991
long val
Definition: informix.c:670
char sign
Definition: informix.c:674
static char * buf
Definition: pg_test_fsync.c:73
#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 }
static pg_noinline void Size size
Definition: slab.c:607

References a, and size.

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:39
#define elog(elevel,...)
Definition: elog.h:224
#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:202
static int cmp(const chr *x, const chr *y, size_t len)
Definition: regc_locale.c:743
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, fcinfo->context) != 0)
112  seg_yyerror(result, fcinfo->context, "bogus input");
113 
115 
116  PG_RETURN_POINTER(result);
117 }
#define PG_GETARG_CSTRING(n)
Definition: fmgr.h:277
int seg_yyparse(SEG *result, struct Node *escontext)
void seg_yyerror(SEG *result, struct Node *escontext, const char *message)
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 1064 of file seg.c.

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

Variable Documentation

◆ PG_MODULE_MAGIC

PG_MODULE_MAGIC

Definition at line 31 of file seg.c.