PostgreSQL Source Code  git master
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros
seg.c File Reference
#include "postgres.h"
#include <float.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
 

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)
 
bool gseg_consistent (GISTENTRY *entry, SEG *query, StrategyNumber strategy, Oid subtype, bool *recheck)
 
GISTENTRYgseg_compress (GISTENTRY *entry)
 
GISTENTRYgseg_decompress (GISTENTRY *entry)
 
float * gseg_penalty (GISTENTRY *origentry, GISTENTRY *newentry, float *result)
 
GIST_SPLITVECgseg_picksplit (GistEntryVector *entryvec, GIST_SPLITVEC *v)
 
bool gseg_leaf_consistent (SEG *key, SEG *query, StrategyNumber strategy)
 
bool gseg_internal_consistent (SEG *key, SEG *query, StrategyNumber strategy)
 
SEGgseg_union (GistEntryVector *entryvec, int *sizep)
 
SEGgseg_binary_union (SEG *r1, SEG *r2, int *sizep)
 
boolgseg_same (SEG *b1, SEG *b2, bool *result)
 
bool seg_same (SEG *a, SEG *b)
 
bool seg_contains_int (SEG *a, int *b)
 
bool seg_contains_float4 (SEG *a, float4 *b)
 
bool seg_contains_float8 (SEG *a, float8 *b)
 
bool seg_contains (SEG *a, SEG *b)
 
bool seg_contained (SEG *a, SEG *b)
 
bool seg_overlap (SEG *a, SEG *b)
 
bool seg_left (SEG *a, SEG *b)
 
bool seg_over_left (SEG *a, SEG *b)
 
bool seg_right (SEG *a, SEG *b)
 
bool seg_over_right (SEG *a, SEG *b)
 
SEGseg_union (SEG *a, SEG *b)
 
SEGseg_inter (SEG *a, SEG *b)
 
void rt_seg_size (SEG *a, float *sz)
 
int32 seg_cmp (SEG *a, SEG *b)
 
bool seg_lt (SEG *a, SEG *b)
 
bool seg_le (SEG *a, SEG *b)
 
bool seg_gt (SEG *a, SEG *b)
 
bool seg_ge (SEG *a, SEG *b)
 
bool seg_different (SEG *a, SEG *b)
 
static int restore (char *s, 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)
 
static int gseg_picksplit_item_cmp (const void *a, const void *b)
 
Datum seg_size (PG_FUNCTION_ARGS)
 
int significant_digits (char *s)
 

Variables

 PG_MODULE_MAGIC
 

Function Documentation

SEG * gseg_binary_union ( SEG r1,
SEG r2,
int *  sizep 
)

Definition at line 503 of file seg.c.

References seg_union().

Referenced by gseg_union().

504 {
505  SEG *retval;
506 
507  retval = seg_union(r1, r2);
508  *sizep = sizeof(SEG);
509 
510  return (retval);
511 }
SEG * seg_union(SEG *a, SEG *b)
Definition: seg.c:582
struct SEG SEG
Definition: segdata.h:4
GISTENTRY * gseg_compress ( GISTENTRY entry)

Definition at line 252 of file seg.c.

253 {
254  return (entry);
255 }
bool gseg_consistent ( GISTENTRY entry,
SEG query,
StrategyNumber  strategy,
Oid  subtype,
bool recheck 
)

Definition at line 197 of file seg.c.

References DatumGetPointer, GIST_LEAF, gseg_internal_consistent(), gseg_leaf_consistent(), and GISTENTRY::key.

202 {
203  /* All cases served by this function are exact */
204  *recheck = false;
205 
206  /*
207  * if entry is not leaf, use gseg_internal_consistent, else use
208  * gseg_leaf_consistent
209  */
210  if (GIST_LEAF(entry))
211  return (gseg_leaf_consistent((SEG *) DatumGetPointer(entry->key), query, strategy));
212  else
213  return (gseg_internal_consistent((SEG *) DatumGetPointer(entry->key), query, strategy));
214 }
#define GIST_LEAF(entry)
Definition: gist.h:133
bool gseg_leaf_consistent(SEG *key, SEG *query, StrategyNumber strategy)
Definition: seg.c:415
Datum key
Definition: gist.h:123
Definition: segdata.h:4
bool gseg_internal_consistent(SEG *key, SEG *query, StrategyNumber strategy)
Definition: seg.c:460
#define DatumGetPointer(X)
Definition: postgres.h:555
GISTENTRY * gseg_decompress ( GISTENTRY entry)

Definition at line 258 of file seg.c.

259 {
260  return (entry);
261 }
bool gseg_internal_consistent ( SEG key,
SEG query,
StrategyNumber  strategy 
)

Definition at line 460 of file seg.c.

References FALSE, 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().

463 {
464  bool retval;
465 
466 #ifdef GIST_QUERY_DEBUG
467  fprintf(stderr, "internal_consistent, %d\n", strategy);
468 #endif
469 
470  switch (strategy)
471  {
473  retval = (bool) !seg_over_right(key, query);
474  break;
476  retval = (bool) !seg_right(key, query);
477  break;
479  retval = (bool) seg_overlap(key, query);
480  break;
482  retval = (bool) !seg_left(key, query);
483  break;
485  retval = (bool) !seg_over_left(key, query);
486  break;
490  retval = (bool) seg_contains(key, query);
491  break;
494  retval = (bool) seg_overlap(key, query);
495  break;
496  default:
497  retval = FALSE;
498  }
499  return (retval);
500 }
bool seg_right(SEG *a, SEG *b)
Definition: seg.c:567
#define RTOldContainsStrategyNumber
Definition: stratnum.h:56
bool seg_overlap(SEG *a, SEG *b)
Definition: seg.c:539
#define RTOldContainedByStrategyNumber
Definition: stratnum.h:57
#define RTLeftStrategyNumber
Definition: stratnum.h:44
bool seg_left(SEG *a, SEG *b)
Definition: seg.c:559
#define RTContainedByStrategyNumber
Definition: stratnum.h:51
char bool
Definition: c.h:202
#define FALSE
Definition: c.h:221
#define RTSameStrategyNumber
Definition: stratnum.h:49
bool seg_contains(SEG *a, SEG *b)
Definition: seg.c:515
#define RTOverRightStrategyNumber
Definition: stratnum.h:47
#define RTOverLeftStrategyNumber
Definition: stratnum.h:45
bool seg_over_right(SEG *a, SEG *b)
Definition: seg.c:575
#define RTRightStrategyNumber
Definition: stratnum.h:48
#define RTContainsStrategyNumber
Definition: stratnum.h:50
#define RTOverlapStrategyNumber
Definition: stratnum.h:46
bool seg_over_left(SEG *a, SEG *b)
Definition: seg.c:551
bool gseg_leaf_consistent ( SEG key,
SEG query,
StrategyNumber  strategy 
)

Definition at line 415 of file seg.c.

References FALSE, 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().

418 {
419  bool retval;
420 
421 #ifdef GIST_QUERY_DEBUG
422  fprintf(stderr, "leaf_consistent, %d\n", strategy);
423 #endif
424 
425  switch (strategy)
426  {
428  retval = (bool) seg_left(key, query);
429  break;
431  retval = (bool) seg_over_left(key, query);
432  break;
434  retval = (bool) seg_overlap(key, query);
435  break;
437  retval = (bool) seg_over_right(key, query);
438  break;
440  retval = (bool) seg_right(key, query);
441  break;
443  retval = (bool) seg_same(key, query);
444  break;
447  retval = (bool) seg_contains(key, query);
448  break;
451  retval = (bool) seg_contained(key, query);
452  break;
453  default:
454  retval = FALSE;
455  }
456  return (retval);
457 }
bool seg_right(SEG *a, SEG *b)
Definition: seg.c:567
#define RTOldContainsStrategyNumber
Definition: stratnum.h:56
bool seg_overlap(SEG *a, SEG *b)
Definition: seg.c:539
#define RTOldContainedByStrategyNumber
Definition: stratnum.h:57
#define RTLeftStrategyNumber
Definition: stratnum.h:44
bool seg_left(SEG *a, SEG *b)
Definition: seg.c:559
#define RTContainedByStrategyNumber
Definition: stratnum.h:51
char bool
Definition: c.h:202
bool seg_same(SEG *a, SEG *b)
Definition: seg.c:531
#define FALSE
Definition: c.h:221
bool seg_contained(SEG *a, SEG *b)
Definition: seg.c:521
#define RTSameStrategyNumber
Definition: stratnum.h:49
bool seg_contains(SEG *a, SEG *b)
Definition: seg.c:515
#define RTOverRightStrategyNumber
Definition: stratnum.h:47
#define RTOverLeftStrategyNumber
Definition: stratnum.h:45
bool seg_over_right(SEG *a, SEG *b)
Definition: seg.c:575
#define RTRightStrategyNumber
Definition: stratnum.h:48
#define RTContainsStrategyNumber
Definition: stratnum.h:50
#define RTOverlapStrategyNumber
Definition: stratnum.h:46
bool seg_over_left(SEG *a, SEG *b)
Definition: seg.c:551
float * gseg_penalty ( GISTENTRY origentry,
GISTENTRY newentry,
float *  result 
)

Definition at line 268 of file seg.c.

References DatumGetPointer, GISTENTRY::key, rt_seg_size(), and seg_union().

269 {
270  SEG *ud;
271  float tmp1,
272  tmp2;
273 
274  ud = seg_union((SEG *) DatumGetPointer(origentry->key),
275  (SEG *) DatumGetPointer(newentry->key));
276  rt_seg_size(ud, &tmp1);
277  rt_seg_size((SEG *) DatumGetPointer(origentry->key), &tmp2);
278  *result = tmp1 - tmp2;
279 
280 #ifdef GIST_DEBUG
281  fprintf(stderr, "penalty\n");
282  fprintf(stderr, "\t%g\n", *result);
283 #endif
284 
285  return (result);
286 }
void rt_seg_size(SEG *a, float *sz)
Definition: seg.c:659
SEG * seg_union(SEG *a, SEG *b)
Definition: seg.c:582
return result
Definition: formatting.c:1618
Datum key
Definition: gist.h:123
Definition: segdata.h:4
#define DatumGetPointer(X)
Definition: postgres.h:555
GIST_SPLITVEC * gseg_picksplit ( GistEntryVector entryvec,
GIST_SPLITVEC v 
)

Definition at line 313 of file seg.c.

References gseg_picksplit_item::center, gseg_picksplit_item::data, DatumGetPointer, gseg_picksplit_item_cmp(), i, gseg_picksplit_item::index, GISTENTRY::key, SEG::lower, GistEntryVector::n, palloc(), 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.

315 {
316  int i;
317  SEG *datum_l,
318  *datum_r,
319  *seg;
320  gseg_picksplit_item *sort_items;
321  OffsetNumber *left,
322  *right;
323  OffsetNumber maxoff;
324  OffsetNumber firstright;
325 
326 #ifdef GIST_DEBUG
327  fprintf(stderr, "picksplit\n");
328 #endif
329 
330  /* Valid items in entryvec->vector[] are indexed 1..maxoff */
331  maxoff = entryvec->n - 1;
332 
333  /*
334  * Prepare the auxiliary array and sort it.
335  */
336  sort_items = (gseg_picksplit_item *)
337  palloc(maxoff * sizeof(gseg_picksplit_item));
338  for (i = 1; i <= maxoff; i++)
339  {
340  seg = (SEG *) DatumGetPointer(entryvec->vector[i].key);
341  /* center calculation is done this way to avoid possible overflow */
342  sort_items[i - 1].center = seg->lower * 0.5f + seg->upper * 0.5f;
343  sort_items[i - 1].index = i;
344  sort_items[i - 1].data = seg;
345  }
346  qsort(sort_items, maxoff, sizeof(gseg_picksplit_item),
348 
349  /* sort items below "firstright" will go into the left side */
350  firstright = maxoff / 2;
351 
352  v->spl_left = (OffsetNumber *) palloc(maxoff * sizeof(OffsetNumber));
353  v->spl_right = (OffsetNumber *) palloc(maxoff * sizeof(OffsetNumber));
354  left = v->spl_left;
355  v->spl_nleft = 0;
356  right = v->spl_right;
357  v->spl_nright = 0;
358 
359  /*
360  * Emit segments to the left output page, and compute its bounding box.
361  */
362  datum_l = (SEG *) palloc(sizeof(SEG));
363  memcpy(datum_l, sort_items[0].data, sizeof(SEG));
364  *left++ = sort_items[0].index;
365  v->spl_nleft++;
366  for (i = 1; i < firstright; i++)
367  {
368  datum_l = seg_union(datum_l, sort_items[i].data);
369  *left++ = sort_items[i].index;
370  v->spl_nleft++;
371  }
372 
373  /*
374  * Likewise for the right page.
375  */
376  datum_r = (SEG *) palloc(sizeof(SEG));
377  memcpy(datum_r, sort_items[firstright].data, sizeof(SEG));
378  *right++ = sort_items[firstright].index;
379  v->spl_nright++;
380  for (i = firstright + 1; i < maxoff; i++)
381  {
382  datum_r = seg_union(datum_r, sort_items[i].data);
383  *right++ = sort_items[i].index;
384  v->spl_nright++;
385  }
386 
387  v->spl_ldatum = PointerGetDatum(datum_l);
388  v->spl_rdatum = PointerGetDatum(datum_r);
389 
390  return v;
391 }
OffsetNumber index
Definition: seg.c:33
float4 lower
Definition: segdata.h:6
static int gseg_picksplit_item_cmp(const void *a, const void *b)
Definition: seg.c:292
#define PointerGetDatum(X)
Definition: postgres.h:562
float center
Definition: seg.c:32
OffsetNumber * spl_left
Definition: gist.h:105
Datum spl_rdatum
Definition: gist.h:112
int32 n
Definition: gist.h:160
SEG * seg_union(SEG *a, SEG *b)
Definition: seg.c:582
int spl_nleft
Definition: gist.h:106
uint16 OffsetNumber
Definition: off.h:24
GISTENTRY vector[FLEXIBLE_ARRAY_MEMBER]
Definition: gist.h:161
int spl_nright
Definition: gist.h:111
Datum key
Definition: gist.h:123
Definition: segdata.h:4
Datum spl_ldatum
Definition: gist.h:107
OffsetNumber * spl_right
Definition: gist.h:110
#define DatumGetPointer(X)
Definition: postgres.h:555
SEG * data
Definition: seg.c:34
void * palloc(Size size)
Definition: mcxt.c:849
float4 upper
Definition: segdata.h:7
int i
#define qsort(a, b, c, d)
Definition: port.h:440
static int gseg_picksplit_item_cmp ( const void *  a,
const void *  b 
)
static

Definition at line 292 of file seg.c.

References gseg_picksplit_item::center.

Referenced by gseg_picksplit().

293 {
294  const gseg_picksplit_item *i1 = (const gseg_picksplit_item *) a;
295  const gseg_picksplit_item *i2 = (const gseg_picksplit_item *) b;
296 
297  if (i1->center < i2->center)
298  return -1;
299  else if (i1->center == i2->center)
300  return 0;
301  else
302  return 1;
303 }
float center
Definition: seg.c:32
bool * gseg_same ( SEG b1,
SEG b2,
bool result 
)

Definition at line 397 of file seg.c.

References FALSE, seg_same(), and TRUE.

398 {
399  if (seg_same(b1, b2))
400  *result = TRUE;
401  else
402  *result = FALSE;
403 
404 #ifdef GIST_DEBUG
405  fprintf(stderr, "same: %s\n", (*result ? "TRUE" : "FALSE"));
406 #endif
407 
408  return (result);
409 }
return result
Definition: formatting.c:1618
bool seg_same(SEG *a, SEG *b)
Definition: seg.c:531
#define FALSE
Definition: c.h:221
#define TRUE
Definition: c.h:217
SEG * gseg_union ( GistEntryVector entryvec,
int *  sizep 
)

Definition at line 221 of file seg.c.

References DatumGetPointer, gseg_binary_union(), i, GISTENTRY::key, GistEntryVector::n, NULL, and GistEntryVector::vector.

222 {
223  int numranges,
224  i;
225  SEG *out = (SEG *) NULL;
226  SEG *tmp;
227 
228 #ifdef GIST_DEBUG
229  fprintf(stderr, "union\n");
230 #endif
231 
232  numranges = entryvec->n;
233  tmp = (SEG *) DatumGetPointer(entryvec->vector[0].key);
234  *sizep = sizeof(SEG);
235 
236  for (i = 1; i < numranges; i++)
237  {
238  out = gseg_binary_union(tmp, (SEG *)
239  DatumGetPointer(entryvec->vector[i].key),
240  sizep);
241  tmp = out;
242  }
243 
244  return (out);
245 }
int32 n
Definition: gist.h:160
GISTENTRY vector[FLEXIBLE_ARRAY_MEMBER]
Definition: gist.h:161
Datum key
Definition: gist.h:123
struct SEG SEG
Definition: segdata.h:4
#define NULL
Definition: c.h:229
#define DatumGetPointer(X)
Definition: postgres.h:555
int i
SEG * gseg_binary_union(SEG *r1, SEG *r2, int *sizep)
Definition: seg.c:503
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  )
static int restore ( char *  s,
float  val,
int  n 
)
static

Definition at line 846 of file seg.c.

References Abs, buf, i, Min, NULL, and sign.

Referenced by seg_out().

847 {
848  char buf[25] = {
849  '0', '0', '0', '0', '0',
850  '0', '0', '0', '0', '0',
851  '0', '0', '0', '0', '0',
852  '0', '0', '0', '0', '0',
853  '0', '0', '0', '0', '\0'
854  };
855  char *p;
856  int exp;
857  int i,
858  dp,
859  sign;
860 
861  /*
862  * Put a cap on the number of significant digits to avoid garbage in the
863  * output and ensure we don't overrun the result buffer.
864  */
865  n = Min(n, FLT_DIG);
866 
867  /* remember the sign */
868  sign = (val < 0 ? 1 : 0);
869 
870  /* print, in %e style to start with */
871  sprintf(result, "%.*e", n - 1, val);
872 
873  /* find the exponent */
874  p = strchr(result, 'e');
875 
876  /* punt if we have 'inf' or similar */
877  if (p == NULL)
878  return strlen(result);
879 
880  exp = atoi(p + 1);
881  if (exp == 0)
882  {
883  /* just truncate off the 'e+00' */
884  *p = '\0';
885  }
886  else
887  {
888  if (Abs(exp) <= 4)
889  {
890  /*
891  * remove the decimal point from the mantissa and write the digits
892  * to the buf array
893  */
894  for (p = result + sign, i = 10, dp = 0; *p != 'e'; p++, i++)
895  {
896  buf[i] = *p;
897  if (*p == '.')
898  {
899  dp = i--; /* skip the decimal point */
900  }
901  }
902  if (dp == 0)
903  dp = i--; /* no decimal point was found in the above
904  * for() loop */
905 
906  if (exp > 0)
907  {
908  if (dp - 10 + exp >= n)
909  {
910  /*
911  * the decimal point is behind the last significant digit;
912  * the digits in between must be converted to the exponent
913  * and the decimal point placed after the first digit
914  */
915  exp = dp - 10 + exp - n;
916  buf[10 + n] = '\0';
917 
918  /* insert the decimal point */
919  if (n > 1)
920  {
921  dp = 11;
922  for (i = 23; i > dp; i--)
923  buf[i] = buf[i - 1];
924  buf[dp] = '.';
925  }
926 
927  /*
928  * adjust the exponent by the number of digits after the
929  * decimal point
930  */
931  if (n > 1)
932  sprintf(&buf[11 + n], "e%d", exp + n - 1);
933  else
934  sprintf(&buf[11], "e%d", exp + n - 1);
935 
936  if (sign)
937  {
938  buf[9] = '-';
939  strcpy(result, &buf[9]);
940  }
941  else
942  strcpy(result, &buf[10]);
943  }
944  else
945  { /* insert the decimal point */
946  dp += exp;
947  for (i = 23; i > dp; i--)
948  buf[i] = buf[i - 1];
949  buf[11 + n] = '\0';
950  buf[dp] = '.';
951  if (sign)
952  {
953  buf[9] = '-';
954  strcpy(result, &buf[9]);
955  }
956  else
957  strcpy(result, &buf[10]);
958  }
959  }
960  else
961  { /* exp <= 0 */
962  dp += exp - 1;
963  buf[10 + n] = '\0';
964  buf[dp] = '.';
965  if (sign)
966  {
967  buf[dp - 2] = '-';
968  strcpy(result, &buf[dp - 2]);
969  }
970  else
971  strcpy(result, &buf[dp - 1]);
972  }
973  }
974 
975  /* do nothing for Abs(exp) > 4; %e must be OK */
976  /* just get rid of zeroes after [eE]- and +zeroes after [Ee]. */
977 
978  /* ... this is not done yet. */
979  }
980  return (strlen(result));
981 }
#define Min(x, y)
Definition: c.h:806
return result
Definition: formatting.c:1618
#define Abs(x)
Definition: c.h:812
char sign
Definition: informix.c:693
static char * buf
Definition: pg_test_fsync.c:65
#define NULL
Definition: c.h:229
int i
long val
Definition: informix.c:689
void rt_seg_size ( SEG a,
float *  sz 
)

Definition at line 659 of file seg.c.

References Abs, SEG::lower, NULL, and SEG::upper.

Referenced by gseg_penalty().

660 {
661  if (a == (SEG *) NULL || a->upper <= a->lower)
662  *size = 0.0;
663  else
664  *size = (float) Abs(a->upper - a->lower);
665 
666  return;
667 }
float4 lower
Definition: segdata.h:6
#define Abs(x)
Definition: c.h:812
Definition: segdata.h:4
#define NULL
Definition: c.h:229
float4 upper
Definition: segdata.h:7
Datum seg_center ( PG_FUNCTION_ARGS  )

Definition at line 162 of file seg.c.

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

163 {
164  SEG *seg = (SEG *) PG_GETARG_POINTER(0);
165 
166  PG_RETURN_FLOAT4(((float) seg->lower + (float) seg->upper) / 2.0);
167 }
#define PG_RETURN_FLOAT4(x)
Definition: fmgr.h:325
float4 lower
Definition: segdata.h:6
#define PG_GETARG_POINTER(n)
Definition: fmgr.h:241
Definition: segdata.h:4
float4 upper
Definition: segdata.h:7
int32 seg_cmp ( SEG a,
SEG b 
)

Definition at line 682 of file seg.c.

References elog, ERROR, SEG::l_ext, SEG::l_sigd, SEG::lower, SEG::u_ext, SEG::u_sigd, and SEG::upper.

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

683 {
684  /*
685  * First compare on lower boundary position
686  */
687  if (a->lower < b->lower)
688  return -1;
689  if (a->lower > b->lower)
690  return 1;
691 
692  /*
693  * a->lower == b->lower, so consider type of boundary.
694  *
695  * A '-' lower bound is < any other kind (this could only be relevant if
696  * -HUGE_VAL is used as a regular data value). A '<' lower bound is < any
697  * other kind except '-'. A '>' lower bound is > any other kind.
698  */
699  if (a->l_ext != b->l_ext)
700  {
701  if (a->l_ext == '-')
702  return -1;
703  if (b->l_ext == '-')
704  return 1;
705  if (a->l_ext == '<')
706  return -1;
707  if (b->l_ext == '<')
708  return 1;
709  if (a->l_ext == '>')
710  return 1;
711  if (b->l_ext == '>')
712  return -1;
713  }
714 
715  /*
716  * For other boundary types, consider # of significant digits first.
717  */
718  if (a->l_sigd < b->l_sigd) /* (a) is blurred and is likely to include (b) */
719  return -1;
720  if (a->l_sigd > b->l_sigd) /* (a) is less blurred and is likely to be
721  * included in (b) */
722  return 1;
723 
724  /*
725  * For same # of digits, an approximate boundary is more blurred than
726  * exact.
727  */
728  if (a->l_ext != b->l_ext)
729  {
730  if (a->l_ext == '~') /* (a) is approximate, while (b) is exact */
731  return -1;
732  if (b->l_ext == '~')
733  return 1;
734  /* can't get here unless data is corrupt */
735  elog(ERROR, "bogus lower boundary types %d %d",
736  (int) a->l_ext, (int) b->l_ext);
737  }
738 
739  /* at this point, the lower boundaries are identical */
740 
741  /*
742  * First compare on upper boundary position
743  */
744  if (a->upper < b->upper)
745  return -1;
746  if (a->upper > b->upper)
747  return 1;
748 
749  /*
750  * a->upper == b->upper, so consider type of boundary.
751  *
752  * A '-' upper bound is > any other kind (this could only be relevant if
753  * HUGE_VAL is used as a regular data value). A '<' upper bound is < any
754  * other kind. A '>' upper bound is > any other kind except '-'.
755  */
756  if (a->u_ext != b->u_ext)
757  {
758  if (a->u_ext == '-')
759  return 1;
760  if (b->u_ext == '-')
761  return -1;
762  if (a->u_ext == '<')
763  return -1;
764  if (b->u_ext == '<')
765  return 1;
766  if (a->u_ext == '>')
767  return 1;
768  if (b->u_ext == '>')
769  return -1;
770  }
771 
772  /*
773  * For other boundary types, consider # of significant digits first. Note
774  * result here is converse of the lower-boundary case.
775  */
776  if (a->u_sigd < b->u_sigd) /* (a) is blurred and is likely to include (b) */
777  return 1;
778  if (a->u_sigd > b->u_sigd) /* (a) is less blurred and is likely to be
779  * included in (b) */
780  return -1;
781 
782  /*
783  * For same # of digits, an approximate boundary is more blurred than
784  * exact. Again, result is converse of lower-boundary case.
785  */
786  if (a->u_ext != b->u_ext)
787  {
788  if (a->u_ext == '~') /* (a) is approximate, while (b) is exact */
789  return 1;
790  if (b->u_ext == '~')
791  return -1;
792  /* can't get here unless data is corrupt */
793  elog(ERROR, "bogus upper boundary types %d %d",
794  (int) a->u_ext, (int) b->u_ext);
795  }
796 
797  return 0;
798 }
char u_sigd
Definition: segdata.h:9
float4 lower
Definition: segdata.h:6
#define ERROR
Definition: elog.h:43
char l_ext
Definition: segdata.h:10
char l_sigd
Definition: segdata.h:8
float4 upper
Definition: segdata.h:7
char u_ext
Definition: segdata.h:11
#define elog
Definition: elog.h:219
bool seg_contained ( SEG a,
SEG b 
)

Definition at line 521 of file seg.c.

References seg_contains().

Referenced by gseg_leaf_consistent().

522 {
523  return (seg_contains(b, a));
524 }
bool seg_contains(SEG *a, SEG *b)
Definition: seg.c:515
bool seg_contains ( SEG a,
SEG b 
)

Definition at line 515 of file seg.c.

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

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

516 {
517  return ((a->lower <= b->lower) && (a->upper >= b->upper));
518 }
float4 lower
Definition: segdata.h:6
float4 upper
Definition: segdata.h:7
bool seg_contains_float4 ( SEG a,
float4 b 
)

Definition at line 995 of file seg.c.

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

996 {
997  return ((a->lower <= *b) && (a->upper >= *b));
998 }
float4 lower
Definition: segdata.h:6
float4 upper
Definition: segdata.h:7
bool seg_contains_float8 ( SEG a,
float8 b 
)

Definition at line 1001 of file seg.c.

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

1002 {
1003  return ((a->lower <= *b) && (a->upper >= *b));
1004 }
float4 lower
Definition: segdata.h:6
float4 upper
Definition: segdata.h:7
bool seg_contains_int ( SEG a,
int *  b 
)

Definition at line 989 of file seg.c.

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

990 {
991  return ((a->lower <= *b) && (a->upper >= *b));
992 }
float4 lower
Definition: segdata.h:6
float4 upper
Definition: segdata.h:7
bool seg_different ( SEG a,
SEG b 
)

Definition at line 825 of file seg.c.

References seg_cmp().

826 {
827  return seg_cmp(a, b) != 0;
828 }
int32 seg_cmp(SEG *a, SEG *b)
Definition: seg.c:682
bool seg_ge ( SEG a,
SEG b 
)

Definition at line 819 of file seg.c.

References seg_cmp().

820 {
821  return seg_cmp(a, b) >= 0;
822 }
int32 seg_cmp(SEG *a, SEG *b)
Definition: seg.c:682
bool seg_gt ( SEG a,
SEG b 
)

Definition at line 813 of file seg.c.

References seg_cmp().

814 {
815  return seg_cmp(a, b) > 0;
816 }
int32 seg_cmp(SEG *a, SEG *b)
Definition: seg.c:682
Datum seg_in ( PG_FUNCTION_ARGS  )

Definition at line 105 of file seg.c.

References palloc(), PG_GETARG_CSTRING, PG_RETURN_POINTER, result, seg_scanner_finish(), seg_scanner_init(), seg_yyerror(), and seg_yyparse().

106 {
107  char *str = PG_GETARG_CSTRING(0);
108  SEG *result = palloc(sizeof(SEG));
109 
110  seg_scanner_init(str);
111 
112  if (seg_yyparse(result) != 0)
113  seg_yyerror(result, "bogus input");
114 
116 
117  PG_RETURN_POINTER(result);
118 }
#define PG_RETURN_POINTER(x)
Definition: fmgr.h:321
return result
Definition: formatting.c:1618
void seg_scanner_finish(void)
int seg_yyparse(SEG *result)
void seg_scanner_init(const char *str)
Definition: segdata.h:4
void seg_yyerror(SEG *result, const char *message) pg_attribute_noreturn()
void * palloc(Size size)
Definition: mcxt.c:849
#define PG_GETARG_CSTRING(n)
Definition: fmgr.h:242
SEG * seg_inter ( SEG a,
SEG b 
)

Definition at line 621 of file seg.c.

References SEG::l_ext, SEG::l_sigd, SEG::lower, palloc(), SEG::u_ext, SEG::u_sigd, and SEG::upper.

622 {
623  SEG *n;
624 
625  n = (SEG *) palloc(sizeof(*n));
626 
627  /* take min of upper endpoints */
628  if (a->upper < b->upper)
629  {
630  n->upper = a->upper;
631  n->u_sigd = a->u_sigd;
632  n->u_ext = a->u_ext;
633  }
634  else
635  {
636  n->upper = b->upper;
637  n->u_sigd = b->u_sigd;
638  n->u_ext = b->u_ext;
639  }
640 
641  /* take max of lower endpoints */
642  if (a->lower > b->lower)
643  {
644  n->lower = a->lower;
645  n->l_sigd = a->l_sigd;
646  n->l_ext = a->l_ext;
647  }
648  else
649  {
650  n->lower = b->lower;
651  n->l_sigd = b->l_sigd;
652  n->l_ext = b->l_ext;
653  }
654 
655  return (n);
656 }
char u_sigd
Definition: segdata.h:9
float4 lower
Definition: segdata.h:6
char l_ext
Definition: segdata.h:10
Definition: segdata.h:4
char l_sigd
Definition: segdata.h:8
void * palloc(Size size)
Definition: mcxt.c:849
float4 upper
Definition: segdata.h:7
char u_ext
Definition: segdata.h:11
bool seg_le ( SEG a,
SEG b 
)

Definition at line 807 of file seg.c.

References seg_cmp().

808 {
809  return seg_cmp(a, b) <= 0;
810 }
int32 seg_cmp(SEG *a, SEG *b)
Definition: seg.c:682
bool seg_left ( SEG a,
SEG b 
)

Definition at line 559 of file seg.c.

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

Referenced by gseg_internal_consistent(), and gseg_leaf_consistent().

560 {
561  return (a->upper < b->lower);
562 }
float4 lower
Definition: segdata.h:6
float4 upper
Definition: segdata.h:7
Datum seg_lower ( PG_FUNCTION_ARGS  )

Definition at line 170 of file seg.c.

References SEG::lower, PG_GETARG_POINTER, and PG_RETURN_FLOAT4.

171 {
172  SEG *seg = (SEG *) PG_GETARG_POINTER(0);
173 
174  PG_RETURN_FLOAT4(seg->lower);
175 }
#define PG_RETURN_FLOAT4(x)
Definition: fmgr.h:325
float4 lower
Definition: segdata.h:6
#define PG_GETARG_POINTER(n)
Definition: fmgr.h:241
Definition: segdata.h:4
bool seg_lt ( SEG a,
SEG b 
)

Definition at line 801 of file seg.c.

References seg_cmp().

802 {
803  return seg_cmp(a, b) < 0;
804 }
int32 seg_cmp(SEG *a, SEG *b)
Definition: seg.c:682
Datum seg_out ( PG_FUNCTION_ARGS  )

Definition at line 121 of file seg.c.

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

122 {
123  SEG *seg = (SEG *) PG_GETARG_POINTER(0);
124  char *result;
125  char *p;
126 
127  p = result = (char *) palloc(40);
128 
129  if (seg->l_ext == '>' || seg->l_ext == '<' || seg->l_ext == '~')
130  p += sprintf(p, "%c", seg->l_ext);
131 
132  if (seg->lower == seg->upper && seg->l_ext == seg->u_ext)
133  {
134  /*
135  * indicates that this interval was built by seg_in off a single point
136  */
137  p += restore(p, seg->lower, seg->l_sigd);
138  }
139  else
140  {
141  if (seg->l_ext != '-')
142  {
143  /* print the lower boundary if exists */
144  p += restore(p, seg->lower, seg->l_sigd);
145  p += sprintf(p, " ");
146  }
147  p += sprintf(p, "..");
148  if (seg->u_ext != '-')
149  {
150  /* print the upper boundary if exists */
151  p += sprintf(p, " ");
152  if (seg->u_ext == '>' || seg->u_ext == '<' || seg->l_ext == '~')
153  p += sprintf(p, "%c", seg->u_ext);
154  p += restore(p, seg->upper, seg->u_sigd);
155  }
156  }
157 
158  PG_RETURN_CSTRING(result);
159 }
char u_sigd
Definition: segdata.h:9
float4 lower
Definition: segdata.h:6
return result
Definition: formatting.c:1618
#define PG_GETARG_POINTER(n)
Definition: fmgr.h:241
char l_ext
Definition: segdata.h:10
Definition: segdata.h:4
char l_sigd
Definition: segdata.h:8
#define PG_RETURN_CSTRING(x)
Definition: fmgr.h:322
static int restore(char *s, float val, int n)
Definition: seg.c:846
void * palloc(Size size)
Definition: mcxt.c:849
float4 upper
Definition: segdata.h:7
char u_ext
Definition: segdata.h:11
bool seg_over_left ( SEG a,
SEG b 
)

Definition at line 551 of file seg.c.

References SEG::upper.

Referenced by gseg_internal_consistent(), and gseg_leaf_consistent().

552 {
553  return (a->upper <= b->upper);
554 }
float4 upper
Definition: segdata.h:7
bool seg_over_right ( SEG a,
SEG b 
)

Definition at line 575 of file seg.c.

References SEG::lower.

Referenced by gseg_internal_consistent(), and gseg_leaf_consistent().

576 {
577  return (a->lower >= b->lower);
578 }
float4 lower
Definition: segdata.h:6
bool seg_overlap ( SEG a,
SEG b 
)

Definition at line 539 of file seg.c.

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

Referenced by gseg_internal_consistent(), and gseg_leaf_consistent().

540 {
541  return (
542  ((a->upper >= b->upper) && (a->lower <= b->upper))
543  ||
544  ((b->upper >= a->upper) && (b->lower <= a->upper))
545  );
546 }
float4 lower
Definition: segdata.h:6
float4 upper
Definition: segdata.h:7
bool seg_right ( SEG a,
SEG b 
)

Definition at line 567 of file seg.c.

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

Referenced by gseg_internal_consistent(), and gseg_leaf_consistent().

568 {
569  return (a->lower > b->upper);
570 }
float4 lower
Definition: segdata.h:6
float4 upper
Definition: segdata.h:7
bool seg_same ( SEG a,
SEG b 
)

Definition at line 531 of file seg.c.

References seg_cmp().

Referenced by gseg_leaf_consistent(), and gseg_same().

532 {
533  return seg_cmp(a, b) == 0;
534 }
int32 seg_cmp(SEG *a, SEG *b)
Definition: seg.c:682
Datum seg_size ( PG_FUNCTION_ARGS  )

Definition at line 670 of file seg.c.

References Abs, SEG::lower, PG_GETARG_POINTER, PG_RETURN_FLOAT4, and SEG::upper.

671 {
672  SEG *seg = (SEG *) PG_GETARG_POINTER(0);
673 
674  PG_RETURN_FLOAT4((float) Abs(seg->upper - seg->lower));
675 }
#define PG_RETURN_FLOAT4(x)
Definition: fmgr.h:325
float4 lower
Definition: segdata.h:6
#define PG_GETARG_POINTER(n)
Definition: fmgr.h:241
#define Abs(x)
Definition: c.h:812
Definition: segdata.h:4
float4 upper
Definition: segdata.h:7
SEG * seg_union ( SEG a,
SEG b 
)

Definition at line 582 of file seg.c.

References SEG::l_ext, SEG::l_sigd, SEG::lower, palloc(), SEG::u_ext, SEG::u_sigd, and SEG::upper.

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

583 {
584  SEG *n;
585 
586  n = (SEG *) palloc(sizeof(*n));
587 
588  /* take max of upper endpoints */
589  if (a->upper > b->upper)
590  {
591  n->upper = a->upper;
592  n->u_sigd = a->u_sigd;
593  n->u_ext = a->u_ext;
594  }
595  else
596  {
597  n->upper = b->upper;
598  n->u_sigd = b->u_sigd;
599  n->u_ext = b->u_ext;
600  }
601 
602  /* take min of lower endpoints */
603  if (a->lower < b->lower)
604  {
605  n->lower = a->lower;
606  n->l_sigd = a->l_sigd;
607  n->l_ext = a->l_ext;
608  }
609  else
610  {
611  n->lower = b->lower;
612  n->l_sigd = b->l_sigd;
613  n->l_ext = b->l_ext;
614  }
615 
616  return (n);
617 }
char u_sigd
Definition: segdata.h:9
float4 lower
Definition: segdata.h:6
char l_ext
Definition: segdata.h:10
Definition: segdata.h:4
char l_sigd
Definition: segdata.h:8
void * palloc(Size size)
Definition: mcxt.c:849
float4 upper
Definition: segdata.h:7
char u_ext
Definition: segdata.h:11
Datum seg_upper ( PG_FUNCTION_ARGS  )

Definition at line 178 of file seg.c.

References PG_GETARG_POINTER, PG_RETURN_FLOAT4, and SEG::upper.

179 {
180  SEG *seg = (SEG *) PG_GETARG_POINTER(0);
181 
182  PG_RETURN_FLOAT4(seg->upper);
183 }
#define PG_RETURN_FLOAT4(x)
Definition: fmgr.h:325
#define PG_GETARG_POINTER(n)
Definition: fmgr.h:241
Definition: segdata.h:4
float4 upper
Definition: segdata.h:7
int significant_digits ( char *  s)

Definition at line 1010 of file seg.c.

1011 {
1012  char *p = s;
1013  int n,
1014  c,
1015  zeroes;
1016 
1017  zeroes = 1;
1018  /* skip leading zeroes and sign */
1019  for (c = *p; (c == '0' || c == '+' || c == '-') && c != 0; c = *(++p));
1020 
1021  /* skip decimal point and following zeroes */
1022  for (c = *p; (c == '0' || c == '.') && c != 0; c = *(++p))
1023  {
1024  if (c != '.')
1025  zeroes++;
1026  }
1027 
1028  /* count significant digits (n) */
1029  for (c = *p, n = 0; c != 0; c = *(++p))
1030  {
1031  if (!((c >= '0' && c <= '9') || (c == '.')))
1032  break;
1033  if (c != '.')
1034  n++;
1035  }
1036 
1037  if (!n)
1038  return (zeroes);
1039 
1040  return (n);
1041 }
char * c

Variable Documentation

PG_MODULE_MAGIC

Definition at line 25 of file seg.c.