PostgreSQL Source Code git master
Loading...
Searching...
No Matches
seg.c
Go to the documentation of this file.
1/*
2 * contrib/seg/seg.c
3 *
4 ******************************************************************************
5 This file contains routines that can be bound to a Postgres backend and
6 called by the backend in the process of processing queries. The calling
7 format for these routines is dictated by Postgres architecture.
8******************************************************************************/
9
10#include "postgres.h"
11
12#include <float.h>
13#include <math.h>
14
15#include "access/gist.h"
16#include "access/stratnum.h"
17#include "fmgr.h"
18
19#include "segdata.h"
20
21
22#define DatumGetSegP(X) ((SEG *) DatumGetPointer(X))
23#define PG_GETARG_SEG_P(n) DatumGetSegP(PG_GETARG_DATUM(n))
24
25
26/*
27#define GIST_DEBUG
28#define GIST_QUERY_DEBUG
29*/
30
32 .name = "seg",
33 .version = PG_VERSION
34);
35
36/*
37 * Auxiliary data structure for picksplit method.
38 */
45
46/*
47** Input/Output routines
48*/
55
56/*
57** GiST support methods
58*/
66static Datum gseg_leaf_consistent(Datum key, Datum query, StrategyNumber strategy);
67static Datum gseg_internal_consistent(Datum key, Datum query, StrategyNumber strategy);
69
70
71/*
72** R-tree support functions
73*/
84static void rt_seg_size(SEG *a, float *size);
85
86/*
87** Various operators
88*/
95
96/*
97** Auxiliary functions
98*/
99static int restore(char *result, float val, int n);
100
101
102/*****************************************************************************
103 * Input/Output functions
104 *****************************************************************************/
105
106Datum
108{
109 char *str = PG_GETARG_CSTRING(0);
110 SEG *result = palloc_object(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}
122
123Datum
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}
163
164Datum
166{
167 SEG *seg = PG_GETARG_SEG_P(0);
168
169 PG_RETURN_FLOAT4(((float) seg->lower + (float) seg->upper) / 2.0);
170}
171
172Datum
174{
175 SEG *seg = PG_GETARG_SEG_P(0);
176
178}
179
180Datum
182{
183 SEG *seg = PG_GETARG_SEG_P(0);
184
186}
187
188
189/*****************************************************************************
190 * GiST functions
191 *****************************************************************************/
192
193/*
194** The GiST Consistent method for segments
195** Should return false if for all data items x below entry,
196** the predicate x op query == false, where op is the oper
197** corresponding to strategy in the pg_amop table.
198*/
199Datum
201{
202 GISTENTRY *entry = (GISTENTRY *) PG_GETARG_POINTER(0);
203 Datum query = PG_GETARG_DATUM(1);
205#ifdef NOT_USED
206 Oid subtype = PG_GETARG_OID(3);
207#endif
208 bool *recheck = (bool *) PG_GETARG_POINTER(4);
209
210 /* All cases served by this function are exact */
211 *recheck = false;
212
213 /*
214 * if entry is not leaf, use gseg_internal_consistent, else use
215 * gseg_leaf_consistent
216 */
217 if (GIST_LEAF(entry))
218 return gseg_leaf_consistent(entry->key, query, strategy);
219 else
220 return gseg_internal_consistent(entry->key, query, strategy);
221}
222
223/*
224** The GiST Union method for segments
225** returns the minimal bounding seg that encloses all the entries in entryvec
226*/
227Datum
229{
231 int *sizep = (int *) PG_GETARG_POINTER(1);
232 int numranges,
233 i;
234 Datum out = 0;
235 Datum tmp;
236
237#ifdef GIST_DEBUG
238 fprintf(stderr, "union\n");
239#endif
240
241 numranges = entryvec->n;
242 tmp = entryvec->vector[0].key;
243 *sizep = sizeof(SEG);
244
245 for (i = 1; i < numranges; i++)
246 {
247 out = gseg_binary_union(tmp, entryvec->vector[i].key, sizep);
248 tmp = out;
249 }
250
251 PG_RETURN_DATUM(out);
252}
253
254/*
255** GiST Compress and Decompress methods for segments
256** do not do anything.
257*/
258Datum
263
264Datum
269
270/*
271** The GiST Penalty method for segments
272** As in the R-tree paper, we use change in area as our penalty metric
273*/
274Datum
276{
279 float *result = (float *) PG_GETARG_POINTER(2);
280 SEG *ud;
281 float tmp1,
282 tmp2;
283
285 origentry->key,
286 newentry->key));
289 *result = tmp1 - tmp2;
290
291#ifdef GIST_DEBUG
292 fprintf(stderr, "penalty\n");
293 fprintf(stderr, "\t%g\n", *result);
294#endif
295
296 PG_RETURN_POINTER(result);
297}
298
299/*
300 * Compare function for gseg_picksplit_item: sort by center.
301 */
302static int
303gseg_picksplit_item_cmp(const void *a, const void *b)
304{
305 const gseg_picksplit_item *i1 = (const gseg_picksplit_item *) a;
306 const gseg_picksplit_item *i2 = (const gseg_picksplit_item *) b;
307
308 if (i1->center < i2->center)
309 return -1;
310 else if (i1->center == i2->center)
311 return 0;
312 else
313 return 1;
314}
315
316/*
317 * The GiST PickSplit method for segments
318 *
319 * We used to use Guttman's split algorithm here, but since the data is 1-D
320 * it's easier and more robust to just sort the segments by center-point and
321 * split at the middle.
322 */
323Datum
325{
328 int i;
329 SEG *seg,
330 *seg_l,
331 *seg_r;
333 OffsetNumber *left,
334 *right;
335 OffsetNumber maxoff;
337
338#ifdef GIST_DEBUG
339 fprintf(stderr, "picksplit\n");
340#endif
341
342 /* Valid items in entryvec->vector[] are indexed 1..maxoff */
343 maxoff = entryvec->n - 1;
344
345 /*
346 * Prepare the auxiliary array and sort it.
347 */
349 palloc(maxoff * sizeof(gseg_picksplit_item));
350 for (i = 1; i <= maxoff; i++)
351 {
352 seg = DatumGetSegP(entryvec->vector[i].key);
353 /* center calculation is done this way to avoid possible overflow */
354 sort_items[i - 1].center = seg->lower * 0.5f + seg->upper * 0.5f;
355 sort_items[i - 1].index = i;
356 sort_items[i - 1].data = seg;
357 }
358 qsort(sort_items, maxoff, sizeof(gseg_picksplit_item),
360
361 /* sort items below "firstright" will go into the left side */
362 firstright = maxoff / 2;
363
364 v->spl_left = (OffsetNumber *) palloc(maxoff * sizeof(OffsetNumber));
365 v->spl_right = (OffsetNumber *) palloc(maxoff * sizeof(OffsetNumber));
366 left = v->spl_left;
367 v->spl_nleft = 0;
368 right = v->spl_right;
369 v->spl_nright = 0;
370
371 /*
372 * Emit segments to the left output page, and compute its bounding box.
373 */
375 memcpy(seg_l, sort_items[0].data, sizeof(SEG));
376 *left++ = sort_items[0].index;
377 v->spl_nleft++;
378 for (i = 1; i < firstright; i++)
379 {
381
384 sortitem));
385 *left++ = sort_items[i].index;
386 v->spl_nleft++;
387 }
388
389 /*
390 * Likewise for the right page.
391 */
394 *right++ = sort_items[firstright].index;
395 v->spl_nright++;
396 for (i = firstright + 1; i < maxoff; i++)
397 {
399
402 sortitem));
403 *right++ = sort_items[i].index;
404 v->spl_nright++;
405 }
406
409
411}
412
413/*
414** Equality methods
415*/
416Datum
418{
419 bool *result = (bool *) PG_GETARG_POINTER(2);
420
422 *result = true;
423 else
424 *result = false;
425
426#ifdef GIST_DEBUG
427 fprintf(stderr, "same: %s\n", (*result ? "TRUE" : "FALSE"));
428#endif
429
430 PG_RETURN_POINTER(result);
431}
432
433/*
434** SUPPORT ROUTINES
435*/
436static Datum
438{
439 Datum retval;
440
441#ifdef GIST_QUERY_DEBUG
442 fprintf(stderr, "leaf_consistent, %d\n", strategy);
443#endif
444
445 switch (strategy)
446 {
448 retval = DirectFunctionCall2(seg_left, key, query);
449 break;
451 retval = DirectFunctionCall2(seg_over_left, key, query);
452 break;
454 retval = DirectFunctionCall2(seg_overlap, key, query);
455 break;
457 retval = DirectFunctionCall2(seg_over_right, key, query);
458 break;
460 retval = DirectFunctionCall2(seg_right, key, query);
461 break;
463 retval = DirectFunctionCall2(seg_same, key, query);
464 break;
467 retval = DirectFunctionCall2(seg_contains, key, query);
468 break;
471 retval = DirectFunctionCall2(seg_contained, key, query);
472 break;
473 default:
474 retval = BoolGetDatum(false);
475 }
476
477 PG_RETURN_DATUM(retval);
478}
479
480static Datum
482{
483 bool retval;
484
485#ifdef GIST_QUERY_DEBUG
486 fprintf(stderr, "internal_consistent, %d\n", strategy);
487#endif
488
489 switch (strategy)
490 {
492 retval =
494 break;
496 retval =
498 break;
500 retval =
502 break;
504 retval =
506 break;
508 retval =
510 break;
514 retval =
516 break;
519 retval =
521 break;
522 default:
523 retval = false;
524 }
525
526 PG_RETURN_BOOL(retval);
527}
528
529static Datum
531{
532 Datum retval;
533
535 *sizep = sizeof(SEG);
536
537 return retval;
538}
539
540
541Datum
543{
544 SEG *a = PG_GETARG_SEG_P(0);
545 SEG *b = PG_GETARG_SEG_P(1);
546
547 PG_RETURN_BOOL((a->lower <= b->lower) && (a->upper >= b->upper));
548}
549
550Datum
558
559/*****************************************************************************
560 * Operator class for R-tree indexing
561 *****************************************************************************/
562
563Datum
572
573/* seg_overlap -- does a overlap b?
574 */
575Datum
577{
578 SEG *a = PG_GETARG_SEG_P(0);
579 SEG *b = PG_GETARG_SEG_P(1);
580
581 PG_RETURN_BOOL(((a->upper >= b->upper) && (a->lower <= b->upper)) ||
582 ((b->upper >= a->upper) && (b->lower <= a->upper)));
583}
584
585/* seg_over_left -- is the right edge of (a) located at or left of the right edge of (b)?
586 */
587Datum
589{
590 SEG *a = PG_GETARG_SEG_P(0);
591 SEG *b = PG_GETARG_SEG_P(1);
592
593 PG_RETURN_BOOL(a->upper <= b->upper);
594}
595
596/* seg_left -- is (a) entirely on the left of (b)?
597 */
598Datum
600{
601 SEG *a = PG_GETARG_SEG_P(0);
602 SEG *b = PG_GETARG_SEG_P(1);
603
604 PG_RETURN_BOOL(a->upper < b->lower);
605}
606
607/* seg_right -- is (a) entirely on the right of (b)?
608 */
609Datum
611{
612 SEG *a = PG_GETARG_SEG_P(0);
613 SEG *b = PG_GETARG_SEG_P(1);
614
615 PG_RETURN_BOOL(a->lower > b->upper);
616}
617
618/* seg_over_right -- is the left edge of (a) located at or right of the left edge of (b)?
619 */
620Datum
622{
623 SEG *a = PG_GETARG_SEG_P(0);
624 SEG *b = PG_GETARG_SEG_P(1);
625
626 PG_RETURN_BOOL(a->lower >= b->lower);
627}
628
629Datum
631{
632 SEG *a = PG_GETARG_SEG_P(0);
633 SEG *b = PG_GETARG_SEG_P(1);
634 SEG *n;
635
636 n = palloc_object(SEG);
637
638 /* take max of upper endpoints */
639 if (a->upper > b->upper)
640 {
641 n->upper = a->upper;
642 n->u_sigd = a->u_sigd;
643 n->u_ext = a->u_ext;
644 }
645 else
646 {
647 n->upper = b->upper;
648 n->u_sigd = b->u_sigd;
649 n->u_ext = b->u_ext;
650 }
651
652 /* take min of lower endpoints */
653 if (a->lower < b->lower)
654 {
655 n->lower = a->lower;
656 n->l_sigd = a->l_sigd;
657 n->l_ext = a->l_ext;
658 }
659 else
660 {
661 n->lower = b->lower;
662 n->l_sigd = b->l_sigd;
663 n->l_ext = b->l_ext;
664 }
665
667}
668
669Datum
671{
672 SEG *a = PG_GETARG_SEG_P(0);
673 SEG *b = PG_GETARG_SEG_P(1);
674 SEG *n;
675
676 n = palloc_object(SEG);
677
678 /* take min of upper endpoints */
679 if (a->upper < b->upper)
680 {
681 n->upper = a->upper;
682 n->u_sigd = a->u_sigd;
683 n->u_ext = a->u_ext;
684 }
685 else
686 {
687 n->upper = b->upper;
688 n->u_sigd = b->u_sigd;
689 n->u_ext = b->u_ext;
690 }
691
692 /* take max of lower endpoints */
693 if (a->lower > b->lower)
694 {
695 n->lower = a->lower;
696 n->l_sigd = a->l_sigd;
697 n->l_ext = a->l_ext;
698 }
699 else
700 {
701 n->lower = b->lower;
702 n->l_sigd = b->l_sigd;
703 n->l_ext = b->l_ext;
704 }
705
707}
708
709static void
710rt_seg_size(SEG *a, float *size)
711{
712 if (a == (SEG *) NULL || a->upper <= a->lower)
713 *size = 0.0;
714 else
715 *size = fabsf(a->upper - a->lower);
716}
717
718Datum
720{
721 SEG *seg = PG_GETARG_SEG_P(0);
722
723 PG_RETURN_FLOAT4(fabsf(seg->upper - seg->lower));
724}
725
726
727/*****************************************************************************
728 * Miscellaneous operators
729 *****************************************************************************/
730Datum
732{
733 SEG *a = PG_GETARG_SEG_P(0);
734 SEG *b = PG_GETARG_SEG_P(1);
735
736 /*
737 * First compare on lower boundary position
738 */
739 if (a->lower < b->lower)
740 PG_RETURN_INT32(-1);
741 if (a->lower > b->lower)
743
744 /*
745 * a->lower == b->lower, so consider type of boundary.
746 *
747 * A '-' lower bound is < any other kind (this could only be relevant if
748 * -HUGE_VAL is used as a regular data value). A '<' lower bound is < any
749 * other kind except '-'. A '>' lower bound is > any other kind.
750 */
751 if (a->l_ext != b->l_ext)
752 {
753 if (a->l_ext == '-')
754 PG_RETURN_INT32(-1);
755 if (b->l_ext == '-')
757 if (a->l_ext == '<')
758 PG_RETURN_INT32(-1);
759 if (b->l_ext == '<')
761 if (a->l_ext == '>')
763 if (b->l_ext == '>')
764 PG_RETURN_INT32(-1);
765 }
766
767 /*
768 * For other boundary types, consider # of significant digits first.
769 */
770 if (a->l_sigd < b->l_sigd) /* (a) is blurred and is likely to include (b) */
771 PG_RETURN_INT32(-1);
772 if (a->l_sigd > b->l_sigd) /* (a) is less blurred and is likely to be
773 * included in (b) */
775
776 /*
777 * For same # of digits, an approximate boundary is more blurred than
778 * exact.
779 */
780 if (a->l_ext != b->l_ext)
781 {
782 if (a->l_ext == '~') /* (a) is approximate, while (b) is exact */
783 PG_RETURN_INT32(-1);
784 if (b->l_ext == '~')
786 /* can't get here unless data is corrupt */
787 elog(ERROR, "bogus lower boundary types %d %d",
788 (int) a->l_ext, (int) b->l_ext);
789 }
790
791 /* at this point, the lower boundaries are identical */
792
793 /*
794 * First compare on upper boundary position
795 */
796 if (a->upper < b->upper)
797 PG_RETURN_INT32(-1);
798 if (a->upper > b->upper)
800
801 /*
802 * a->upper == b->upper, so consider type of boundary.
803 *
804 * A '-' upper bound is > any other kind (this could only be relevant if
805 * HUGE_VAL is used as a regular data value). A '<' upper bound is < any
806 * other kind. A '>' upper bound is > any other kind except '-'.
807 */
808 if (a->u_ext != b->u_ext)
809 {
810 if (a->u_ext == '-')
812 if (b->u_ext == '-')
813 PG_RETURN_INT32(-1);
814 if (a->u_ext == '<')
815 PG_RETURN_INT32(-1);
816 if (b->u_ext == '<')
818 if (a->u_ext == '>')
820 if (b->u_ext == '>')
821 PG_RETURN_INT32(-1);
822 }
823
824 /*
825 * For other boundary types, consider # of significant digits first. Note
826 * result here is converse of the lower-boundary case.
827 */
828 if (a->u_sigd < b->u_sigd) /* (a) is blurred and is likely to include (b) */
830 if (a->u_sigd > b->u_sigd) /* (a) is less blurred and is likely to be
831 * included in (b) */
832 PG_RETURN_INT32(-1);
833
834 /*
835 * For same # of digits, an approximate boundary is more blurred than
836 * exact. Again, result is converse of lower-boundary case.
837 */
838 if (a->u_ext != b->u_ext)
839 {
840 if (a->u_ext == '~') /* (a) is approximate, while (b) is exact */
842 if (b->u_ext == '~')
843 PG_RETURN_INT32(-1);
844 /* can't get here unless data is corrupt */
845 elog(ERROR, "bogus upper boundary types %d %d",
846 (int) a->u_ext, (int) b->u_ext);
847 }
848
850}
851
852Datum
861
862Datum
871
872Datum
881
882Datum
891
892
893Datum
902
903
904
905/*****************************************************************************
906 * Auxiliary functions
907 *****************************************************************************/
908
909/*
910 * The purpose of this routine is to print the given floating point
911 * value with exactly n significant digits. Its behaviour
912 * is similar to %.ng except it prints 8.00 where %.ng would
913 * print 8. Returns the length of the string written at "result".
914 *
915 * Caller must provide a sufficiently large result buffer; 16 bytes
916 * should be enough for all known float implementations.
917 */
918static int
919restore(char *result, float val, int n)
920{
921 char buf[25] = {
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 '0', '0', '0', '0', '\0'
927 };
928 char *p;
929 int exp;
930 int i,
931 dp,
932 sign;
933
934 /*
935 * Put a cap on the number of significant digits to avoid garbage in the
936 * output and ensure we don't overrun the result buffer. (n should not be
937 * negative, but check to protect ourselves against corrupted data.)
938 */
939 if (n <= 0)
940 n = FLT_DIG;
941 else
942 n = Min(n, FLT_DIG);
943
944 /* remember the sign */
945 sign = (val < 0 ? 1 : 0);
946
947 /* print, in %e style to start with */
948 sprintf(result, "%.*e", n - 1, val);
949
950 /* find the exponent */
951 p = strchr(result, 'e');
952
953 /* punt if we have 'inf' or similar */
954 if (p == NULL)
955 return strlen(result);
956
957 exp = atoi(p + 1);
958 if (exp == 0)
959 {
960 /* just truncate off the 'e+00' */
961 *p = '\0';
962 }
963 else
964 {
965 if (abs(exp) <= 4)
966 {
967 /*
968 * remove the decimal point from the mantissa and write the digits
969 * to the buf array
970 */
971 for (p = result + sign, i = 10, dp = 0; *p != 'e'; p++, i++)
972 {
973 buf[i] = *p;
974 if (*p == '.')
975 {
976 dp = i--; /* skip the decimal point */
977 }
978 }
979 if (dp == 0)
980 dp = i--; /* no decimal point was found in the above
981 * for() loop */
982
983 if (exp > 0)
984 {
985 if (dp - 10 + exp >= n)
986 {
987 /*
988 * the decimal point is behind the last significant digit;
989 * the digits in between must be converted to the exponent
990 * and the decimal point placed after the first digit
991 */
992 exp = dp - 10 + exp - n;
993 buf[10 + n] = '\0';
994
995 /* insert the decimal point */
996 if (n > 1)
997 {
998 dp = 11;
999 for (i = 23; i > dp; i--)
1000 buf[i] = buf[i - 1];
1001 buf[dp] = '.';
1002 }
1003
1004 /*
1005 * adjust the exponent by the number of digits after the
1006 * decimal point
1007 */
1008 if (n > 1)
1009 sprintf(&buf[11 + n], "e%d", exp + n - 1);
1010 else
1011 sprintf(&buf[11], "e%d", exp + n - 1);
1012
1013 if (sign)
1014 {
1015 buf[9] = '-';
1016 strcpy(result, &buf[9]);
1017 }
1018 else
1019 strcpy(result, &buf[10]);
1020 }
1021 else
1022 { /* insert the decimal point */
1023 dp += exp;
1024 for (i = 23; i > dp; i--)
1025 buf[i] = buf[i - 1];
1026 buf[11 + n] = '\0';
1027 buf[dp] = '.';
1028 if (sign)
1029 {
1030 buf[9] = '-';
1031 strcpy(result, &buf[9]);
1032 }
1033 else
1034 strcpy(result, &buf[10]);
1035 }
1036 }
1037 else
1038 { /* exp <= 0 */
1039 dp += exp - 1;
1040 buf[10 + n] = '\0';
1041 buf[dp] = '.';
1042 if (sign)
1043 {
1044 buf[dp - 2] = '-';
1045 strcpy(result, &buf[dp - 2]);
1046 }
1047 else
1048 strcpy(result, &buf[dp - 1]);
1049 }
1050 }
1051
1052 /* do nothing for abs(exp) > 4; %e must be OK */
1053 /* just get rid of zeroes after [eE]- and +zeroes after [Ee]. */
1054
1055 /* ... this is not done yet. */
1056 }
1057 return strlen(result);
1058}
1059
1060
1061/*
1062** Miscellany
1063*/
1064
1065/* find out the number of significant digits in a string representing
1066 * a floating point number
1067 */
1068int
1070{
1071 const char *p = s;
1072 int n,
1073 c,
1074 zeroes;
1075
1076 zeroes = 1;
1077 /* skip leading zeroes and sign */
1078 for (c = *p; (c == '0' || c == '+' || c == '-') && c != 0; c = *(++p));
1079
1080 /* skip decimal point and following zeroes */
1081 for (c = *p; (c == '0' || c == '.') && c != 0; c = *(++p))
1082 {
1083 if (c != '.')
1084 zeroes++;
1085 }
1086
1087 /* count significant digits (n) */
1088 for (c = *p, n = 0; c != 0; c = *(++p))
1089 {
1090 if (!((c >= '0' && c <= '9') || (c == '.')))
1091 break;
1092 if (c != '.')
1093 n++;
1094 }
1095
1096 if (!n)
1097 return zeroes;
1098
1099 return n;
1100}
#define Min(x, y)
Definition c.h:997
void * yyscan_t
Definition cubedata.h:65
#define fprintf(file, fmt, msg)
Definition cubescan.l:21
#define ERROR
Definition elog.h:39
#define elog(elevel,...)
Definition elog.h:226
#define palloc_object(type)
Definition fe_memutils.h:74
#define PG_GETARG_OID(n)
Definition fmgr.h:275
#define DirectFunctionCall2(func, arg1, arg2)
Definition fmgr.h:686
#define PG_GETARG_POINTER(n)
Definition fmgr.h:277
#define PG_MODULE_MAGIC_EXT(...)
Definition fmgr.h:540
#define PG_RETURN_CSTRING(x)
Definition fmgr.h:364
#define PG_GETARG_DATUM(n)
Definition fmgr.h:268
#define PG_GETARG_CSTRING(n)
Definition fmgr.h:278
#define PG_FUNCTION_INFO_V1(funcname)
Definition fmgr.h:417
#define PG_GETARG_UINT16(n)
Definition fmgr.h:272
#define PG_RETURN_INT32(x)
Definition fmgr.h:355
#define PG_RETURN_DATUM(x)
Definition fmgr.h:354
#define PG_RETURN_POINTER(x)
Definition fmgr.h:363
#define PG_RETURN_FLOAT4(x)
Definition fmgr.h:368
#define PG_FUNCTION_ARGS
Definition fmgr.h:193
#define PG_RETURN_BOOL(x)
Definition fmgr.h:360
#define GIST_LEAF(entry)
Definition gist.h:171
const char * str
long val
Definition informix.c:689
char sign
Definition informix.c:693
int b
Definition isn.c:74
int a
Definition isn.c:73
int i
Definition isn.c:77
void * palloc(Size size)
Definition mcxt.c:1387
uint16 OffsetNumber
Definition off.h:24
const void * data
static char buf[DEFAULT_XLOG_SEG_SIZE]
#define sprintf
Definition port.h:262
#define qsort(a, b, c, d)
Definition port.h:495
static bool DatumGetBool(Datum X)
Definition postgres.h:100
static Datum PointerGetDatum(const void *X)
Definition postgres.h:352
static Datum BoolGetDatum(bool X)
Definition postgres.h:112
uint64_t Datum
Definition postgres.h:70
static int32 DatumGetInt32(Datum X)
Definition postgres.h:212
unsigned int Oid
char * c
static int fb(int x)
static int cmp(const chr *x, const chr *y, size_t len)
Datum seg_le(PG_FUNCTION_ARGS)
Definition seg.c:863
Datum gseg_decompress(PG_FUNCTION_ARGS)
Definition seg.c:265
Datum seg_gt(PG_FUNCTION_ARGS)
Definition seg.c:873
static Datum gseg_leaf_consistent(Datum key, Datum query, StrategyNumber strategy)
Definition seg.c:437
Datum gseg_penalty(PG_FUNCTION_ARGS)
Definition seg.c:275
Datum gseg_union(PG_FUNCTION_ARGS)
Definition seg.c:228
Datum gseg_consistent(PG_FUNCTION_ARGS)
Definition seg.c:200
Datum seg_center(PG_FUNCTION_ARGS)
Definition seg.c:165
Datum seg_over_right(PG_FUNCTION_ARGS)
Definition seg.c:621
Datum seg_contained(PG_FUNCTION_ARGS)
Definition seg.c:551
Datum seg_overlap(PG_FUNCTION_ARGS)
Definition seg.c:576
Datum seg_right(PG_FUNCTION_ARGS)
Definition seg.c:610
#define PG_GETARG_SEG_P(n)
Definition seg.c:23
Datum gseg_same(PG_FUNCTION_ARGS)
Definition seg.c:417
static int gseg_picksplit_item_cmp(const void *a, const void *b)
Definition seg.c:303
Datum seg_lt(PG_FUNCTION_ARGS)
Definition seg.c:853
#define DatumGetSegP(X)
Definition seg.c:22
Datum seg_size(PG_FUNCTION_ARGS)
Definition seg.c:719
Datum seg_union(PG_FUNCTION_ARGS)
Definition seg.c:630
int significant_digits(const char *s)
Definition seg.c:1069
Datum seg_upper(PG_FUNCTION_ARGS)
Definition seg.c:181
static Datum gseg_internal_consistent(Datum key, Datum query, StrategyNumber strategy)
Definition seg.c:481
Datum seg_ge(PG_FUNCTION_ARGS)
Definition seg.c:883
Datum seg_lower(PG_FUNCTION_ARGS)
Definition seg.c:173
Datum gseg_picksplit(PG_FUNCTION_ARGS)
Definition seg.c:324
Datum seg_in(PG_FUNCTION_ARGS)
Definition seg.c:107
Datum seg_cmp(PG_FUNCTION_ARGS)
Definition seg.c:731
static int restore(char *result, float val, int n)
Definition seg.c:919
Datum seg_inter(PG_FUNCTION_ARGS)
Definition seg.c:670
Datum seg_left(PG_FUNCTION_ARGS)
Definition seg.c:599
static void rt_seg_size(SEG *a, float *size)
Definition seg.c:710
Datum seg_out(PG_FUNCTION_ARGS)
Definition seg.c:124
static Datum gseg_binary_union(Datum r1, Datum r2, int *sizep)
Definition seg.c:530
Datum seg_over_left(PG_FUNCTION_ARGS)
Definition seg.c:588
Datum gseg_compress(PG_FUNCTION_ARGS)
Definition seg.c:259
Datum seg_contains(PG_FUNCTION_ARGS)
Definition seg.c:542
Datum seg_same(PG_FUNCTION_ARGS)
Definition seg.c:564
Datum seg_different(PG_FUNCTION_ARGS)
Definition seg.c:894
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
#define RTOldContainsStrategyNumber
Definition stratnum.h:63
uint16 StrategyNumber
Definition stratnum.h:22
#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
Datum key
Definition gist.h:161
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
Definition segdata.h:5
char l_ext
Definition segdata.h:10
char l_sigd
Definition segdata.h:8
char u_sigd
Definition segdata.h:9
float4 upper
Definition segdata.h:7
char u_ext
Definition segdata.h:11
float4 lower
Definition segdata.h:6
OffsetNumber index
Definition seg.c:42
const char * name