PostgreSQL Source Code git master
All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Pages
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_MODULE_MAGIC_EXT (.name="seg",.version=PG_VERSION)
 
 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)
 

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

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

References DirectFunctionCall2, and seg_union().

Referenced by gseg_union().

◆ gseg_compress()

Datum gseg_compress ( PG_FUNCTION_ARGS  )

Definition at line 258 of file seg.c.

259{
261}
#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 200 of file seg.c.

201{
202 GISTENTRY *entry = (GISTENTRY *) PG_GETARG_POINTER(0);
203 Datum query = PG_GETARG_DATUM(1);
205
206 /* Oid subtype = PG_GETARG_OID(3); */
207 bool *recheck = (bool *) PG_GETARG_POINTER(4);
208
209 /* All cases served by this function are exact */
210 *recheck = false;
211
212 /*
213 * if entry is not leaf, use gseg_internal_consistent, else use
214 * gseg_leaf_consistent
215 */
216 if (GIST_LEAF(entry))
217 return gseg_leaf_consistent(entry->key, query, strategy);
218 else
219 return gseg_internal_consistent(entry->key, query, strategy);
220}
#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:436
static Datum gseg_internal_consistent(Datum key, Datum query, StrategyNumber strategy)
Definition: seg.c:480
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 264 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 480 of file seg.c.

481{
482 bool retval;
483
484#ifdef GIST_QUERY_DEBUG
485 fprintf(stderr, "internal_consistent, %d\n", strategy);
486#endif
487
488 switch (strategy)
489 {
491 retval =
493 break;
495 retval =
497 break;
499 retval =
501 break;
503 retval =
505 break;
507 retval =
509 break;
513 retval =
515 break;
518 retval =
520 break;
521 default:
522 retval = false;
523 }
524
525 PG_RETURN_BOOL(retval);
526}
#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:620
Datum seg_overlap(PG_FUNCTION_ARGS)
Definition: seg.c:575
Datum seg_right(PG_FUNCTION_ARGS)
Definition: seg.c:609
Datum seg_left(PG_FUNCTION_ARGS)
Definition: seg.c:598
Datum seg_over_left(PG_FUNCTION_ARGS)
Definition: seg.c:587
Datum seg_contains(PG_FUNCTION_ARGS)
Definition: seg.c:541
#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 436 of file seg.c.

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

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

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

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

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

303{
304 const gseg_picksplit_item *i1 = (const gseg_picksplit_item *) a;
305 const gseg_picksplit_item *i2 = (const gseg_picksplit_item *) b;
306
307 if (i1->center < i2->center)
308 return -1;
309 else if (i1->center == i2->center)
310 return 0;
311 else
312 return 1;
313}
int b
Definition: isn.c:74
int a
Definition: isn.c:73

References a, b, and gseg_picksplit_item::center.

Referenced by gseg_picksplit().

◆ gseg_same()

Datum gseg_same ( PG_FUNCTION_ARGS  )

Definition at line 416 of file seg.c.

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

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

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

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  )

◆ PG_MODULE_MAGIC_EXT()

PG_MODULE_MAGIC_EXT ( name = "seg",
version = PG_VERSION 
)

◆ restore()

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

Definition at line 918 of file seg.c.

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

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

References a.

Referenced by gseg_penalty().

◆ seg_center()

Datum seg_center ( PG_FUNCTION_ARGS  )

Definition at line 165 of file seg.c.

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

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

542{
543 SEG *a = PG_GETARG_SEG_P(0);
544 SEG *b = PG_GETARG_SEG_P(1);
545
546 PG_RETURN_BOOL((a->lower <= b->lower) && (a->upper >= b->upper));
547}

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

894{
897 PG_GETARG_DATUM(1)));
898
899 PG_RETURN_BOOL(cmp != 0);
900}
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:730

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

◆ seg_ge()

Datum seg_ge ( PG_FUNCTION_ARGS  )

Definition at line 882 of file seg.c.

883{
886 PG_GETARG_DATUM(1)));
887
888 PG_RETURN_BOOL(cmp >= 0);
889}

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

◆ seg_gt()

Datum seg_gt ( PG_FUNCTION_ARGS  )

Definition at line 872 of file seg.c.

873{
876 PG_GETARG_DATUM(1)));
877
878 PG_RETURN_BOOL(cmp > 0);
879}

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

◆ seg_in()

Datum seg_in ( PG_FUNCTION_ARGS  )

Definition at line 107 of file seg.c.

108{
109 char *str = PG_GETARG_CSTRING(0);
110 SEG *result = palloc(sizeof(SEG));
111 yyscan_t scanner;
112
113 seg_scanner_init(str, &scanner);
114
115 if (seg_yyparse(result, fcinfo->context, scanner) != 0)
116 seg_yyerror(result, fcinfo->context, scanner, "bogus input");
117
118 seg_scanner_finish(scanner);
119
120 PG_RETURN_POINTER(result);
121}
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 669 of file seg.c.

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

863{
866 PG_GETARG_DATUM(1)));
867
868 PG_RETURN_BOOL(cmp <= 0);
869}

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

◆ seg_left()

Datum seg_left ( PG_FUNCTION_ARGS  )

Definition at line 598 of file seg.c.

599{
600 SEG *a = PG_GETARG_SEG_P(0);
601 SEG *b = PG_GETARG_SEG_P(1);
602
603 PG_RETURN_BOOL(a->upper < b->lower);
604}

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

174{
175 SEG *seg = PG_GETARG_SEG_P(0);
176
178}

References SEG::lower, PG_GETARG_SEG_P, and PG_RETURN_FLOAT4.

◆ seg_lt()

Datum seg_lt ( PG_FUNCTION_ARGS  )

Definition at line 852 of file seg.c.

853{
856 PG_GETARG_DATUM(1)));
857
858 PG_RETURN_BOOL(cmp < 0);
859}

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

◆ seg_out()

Datum seg_out ( PG_FUNCTION_ARGS  )

Definition at line 124 of file seg.c.

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

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

588{
589 SEG *a = PG_GETARG_SEG_P(0);
590 SEG *b = PG_GETARG_SEG_P(1);
591
592 PG_RETURN_BOOL(a->upper <= b->upper);
593}

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

621{
622 SEG *a = PG_GETARG_SEG_P(0);
623 SEG *b = PG_GETARG_SEG_P(1);
624
625 PG_RETURN_BOOL(a->lower >= b->lower);
626}

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

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

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

610{
611 SEG *a = PG_GETARG_SEG_P(0);
612 SEG *b = PG_GETARG_SEG_P(1);
613
614 PG_RETURN_BOOL(a->lower > b->upper);
615}

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

564{
567 PG_GETARG_DATUM(1)));
568
569 PG_RETURN_BOOL(cmp == 0);
570}

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

719{
720 SEG *seg = PG_GETARG_SEG_P(0);
721
722 PG_RETURN_FLOAT4(fabsf(seg->upper - seg->lower));
723}

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

◆ seg_union()

Datum seg_union ( PG_FUNCTION_ARGS  )

Definition at line 629 of file seg.c.

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

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

182{
183 SEG *seg = PG_GETARG_SEG_P(0);
184
186}

References PG_GETARG_SEG_P, PG_RETURN_FLOAT4, and SEG::upper.

◆ significant_digits()

int significant_digits ( const char *  s)

Definition at line 1068 of file seg.c.

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