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 526 of file seg.c.

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

References DirectFunctionCall2, and seg_union().

Referenced by gseg_union().

◆ gseg_compress()

Datum gseg_compress ( PG_FUNCTION_ARGS  )

Definition at line 255 of file seg.c.

256{
258}
#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 197 of file seg.c.

198{
199 GISTENTRY *entry = (GISTENTRY *) PG_GETARG_POINTER(0);
200 Datum query = PG_GETARG_DATUM(1);
202
203 /* Oid subtype = PG_GETARG_OID(3); */
204 bool *recheck = (bool *) PG_GETARG_POINTER(4);
205
206 /* All cases served by this function are exact */
207 *recheck = false;
208
209 /*
210 * if entry is not leaf, use gseg_internal_consistent, else use
211 * gseg_leaf_consistent
212 */
213 if (GIST_LEAF(entry))
214 return gseg_leaf_consistent(entry->key, query, strategy);
215 else
216 return gseg_internal_consistent(entry->key, query, strategy);
217}
#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:171
static Datum gseg_leaf_consistent(Datum key, Datum query, StrategyNumber strategy)
Definition: seg.c:433
static Datum gseg_internal_consistent(Datum key, Datum query, StrategyNumber strategy)
Definition: seg.c:477
uint16 StrategyNumber
Definition: stratnum.h:22
Datum key
Definition: gist.h:161

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 261 of file seg.c.

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 477 of file seg.c.

478{
479 bool retval;
480
481#ifdef GIST_QUERY_DEBUG
482 fprintf(stderr, "internal_consistent, %d\n", strategy);
483#endif
484
485 switch (strategy)
486 {
488 retval =
490 break;
492 retval =
494 break;
496 retval =
498 break;
500 retval =
502 break;
504 retval =
506 break;
510 retval =
512 break;
515 retval =
517 break;
518 default:
519 retval = false;
520 }
521
522 PG_RETURN_BOOL(retval);
523}
#define fprintf(file, fmt, msg)
Definition: cubescan.l:21
#define PG_RETURN_BOOL(x)
Definition: fmgr.h:359
static bool DatumGetBool(Datum X)
Definition: postgres.h:95
Datum seg_over_right(PG_FUNCTION_ARGS)
Definition: seg.c:617
Datum seg_overlap(PG_FUNCTION_ARGS)
Definition: seg.c:572
Datum seg_right(PG_FUNCTION_ARGS)
Definition: seg.c:606
Datum seg_left(PG_FUNCTION_ARGS)
Definition: seg.c:595
Datum seg_over_left(PG_FUNCTION_ARGS)
Definition: seg.c:584
Datum seg_contains(PG_FUNCTION_ARGS)
Definition: seg.c:538
#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 433 of file seg.c.

434{
435 Datum retval;
436
437#ifdef GIST_QUERY_DEBUG
438 fprintf(stderr, "leaf_consistent, %d\n", strategy);
439#endif
440
441 switch (strategy)
442 {
444 retval = DirectFunctionCall2(seg_left, key, query);
445 break;
447 retval = DirectFunctionCall2(seg_over_left, key, query);
448 break;
450 retval = DirectFunctionCall2(seg_overlap, key, query);
451 break;
453 retval = DirectFunctionCall2(seg_over_right, key, query);
454 break;
456 retval = DirectFunctionCall2(seg_right, key, query);
457 break;
459 retval = DirectFunctionCall2(seg_same, key, query);
460 break;
463 retval = DirectFunctionCall2(seg_contains, key, query);
464 break;
467 retval = DirectFunctionCall2(seg_contained, key, query);
468 break;
469 default:
470 retval = false;
471 }
472
473 PG_RETURN_DATUM(retval);
474}
#define PG_RETURN_DATUM(x)
Definition: fmgr.h:353
Datum seg_contained(PG_FUNCTION_ARGS)
Definition: seg.c:547
Datum seg_same(PG_FUNCTION_ARGS)
Definition: seg.c:560

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 271 of file seg.c.

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

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

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

References a, b, and gseg_picksplit_item::center.

Referenced by gseg_picksplit().

◆ gseg_same()

Datum gseg_same ( PG_FUNCTION_ARGS  )

Definition at line 413 of file seg.c.

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

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 224 of file seg.c.

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

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 915 of file seg.c.

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

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 706 of file seg.c.

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

References a.

Referenced by gseg_penalty().

◆ seg_center()

Datum seg_center ( PG_FUNCTION_ARGS  )

Definition at line 162 of file seg.c.

163{
164 SEG *seg = PG_GETARG_SEG_P(0);
165
166 PG_RETURN_FLOAT4(((float) seg->lower + (float) seg->upper) / 2.0);
167}
#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 727 of file seg.c.

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

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 538 of file seg.c.

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

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 890 of file seg.c.

891{
894 PG_GETARG_DATUM(1)));
895
896 PG_RETURN_BOOL(cmp != 0);
897}
static int32 DatumGetInt32(Datum X)
Definition: postgres.h:207
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:727

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

◆ seg_ge()

Datum seg_ge ( PG_FUNCTION_ARGS  )

Definition at line 879 of file seg.c.

880{
883 PG_GETARG_DATUM(1)));
884
885 PG_RETURN_BOOL(cmp >= 0);
886}

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

◆ seg_gt()

Datum seg_gt ( PG_FUNCTION_ARGS  )

Definition at line 869 of file seg.c.

870{
873 PG_GETARG_DATUM(1)));
874
875 PG_RETURN_BOOL(cmp > 0);
876}

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 yyscan_t scanner;
109
110 seg_scanner_init(str, &scanner);
111
112 if (seg_yyparse(result, fcinfo->context, scanner) != 0)
113 seg_yyerror(result, fcinfo->context, scanner, "bogus input");
114
115 seg_scanner_finish(scanner);
116
117 PG_RETURN_POINTER(result);
118}
void * yyscan_t
Definition: cubedata.h:67
#define PG_GETARG_CSTRING(n)
Definition: fmgr.h:277
const char * str
void seg_yyerror(SEG *result, struct Node *escontext, yyscan_t yyscanner, const char *message)
Definition: segscan.l:67
void seg_scanner_init(const char *str, yyscan_t *yyscannerp)
Definition: segscan.l:99
int seg_yyparse(SEG *result, struct Node *escontext, yyscan_t yyscanner)
void seg_scanner_finish(yyscan_t yyscanner)
Definition: segscan.l:116

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

◆ seg_inter()

Datum seg_inter ( PG_FUNCTION_ARGS  )

Definition at line 666 of file seg.c.

667{
668 SEG *a = PG_GETARG_SEG_P(0);
669 SEG *b = PG_GETARG_SEG_P(1);
670 SEG *n;
671
672 n = (SEG *) palloc(sizeof(*n));
673
674 /* take min of upper endpoints */
675 if (a->upper < b->upper)
676 {
677 n->upper = a->upper;
678 n->u_sigd = a->u_sigd;
679 n->u_ext = a->u_ext;
680 }
681 else
682 {
683 n->upper = b->upper;
684 n->u_sigd = b->u_sigd;
685 n->u_ext = b->u_ext;
686 }
687
688 /* take max of lower endpoints */
689 if (a->lower > b->lower)
690 {
691 n->lower = a->lower;
692 n->l_sigd = a->l_sigd;
693 n->l_ext = a->l_ext;
694 }
695 else
696 {
697 n->lower = b->lower;
698 n->l_sigd = b->l_sigd;
699 n->l_ext = b->l_ext;
700 }
701
703}
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 859 of file seg.c.

860{
863 PG_GETARG_DATUM(1)));
864
865 PG_RETURN_BOOL(cmp <= 0);
866}

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

◆ seg_left()

Datum seg_left ( PG_FUNCTION_ARGS  )

Definition at line 595 of file seg.c.

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

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 170 of file seg.c.

171{
172 SEG *seg = PG_GETARG_SEG_P(0);
173
175}

References SEG::lower, PG_GETARG_SEG_P, and PG_RETURN_FLOAT4.

◆ seg_lt()

Datum seg_lt ( PG_FUNCTION_ARGS  )

Definition at line 849 of file seg.c.

850{
853 PG_GETARG_DATUM(1)));
854
855 PG_RETURN_BOOL(cmp < 0);
856}

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

◆ seg_out()

Datum seg_out ( PG_FUNCTION_ARGS  )

Definition at line 121 of file seg.c.

122{
123 SEG *seg = PG_GETARG_SEG_P(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}
#define PG_RETURN_CSTRING(x)
Definition: fmgr.h:362
static int restore(char *result, float val, int n)
Definition: seg.c:915

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 584 of file seg.c.

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

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 617 of file seg.c.

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

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 572 of file seg.c.

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

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 606 of file seg.c.

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

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 560 of file seg.c.

561{
564 PG_GETARG_DATUM(1)));
565
566 PG_RETURN_BOOL(cmp == 0);
567}

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 715 of file seg.c.

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

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

◆ seg_union()

Datum seg_union ( PG_FUNCTION_ARGS  )

Definition at line 626 of file seg.c.

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

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 178 of file seg.c.

179{
180 SEG *seg = PG_GETARG_SEG_P(0);
181
183}

References PG_GETARG_SEG_P, PG_RETURN_FLOAT4, and SEG::upper.

◆ significant_digits()

int significant_digits ( const char *  s)

Definition at line 1065 of file seg.c.

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

Variable Documentation

◆ PG_MODULE_MAGIC

PG_MODULE_MAGIC

Definition at line 31 of file seg.c.