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);
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
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
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
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
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/*
574 * seg_overlap -- does a overlap b?
575 */
576Datum
578{
579 SEG *a = PG_GETARG_SEG_P(0);
580 SEG *b = PG_GETARG_SEG_P(1);
581
582 PG_RETURN_BOOL(((a->upper >= b->upper) && (a->lower <= b->upper)) ||
583 ((b->upper >= a->upper) && (b->lower <= a->upper)));
584}
585
586/*
587 * seg_over_left -- is the right edge of (a) located at or left of the right edge of (b)?
588 */
589Datum
591{
592 SEG *a = PG_GETARG_SEG_P(0);
593 SEG *b = PG_GETARG_SEG_P(1);
594
595 PG_RETURN_BOOL(a->upper <= b->upper);
596}
597
598/*
599 * seg_left -- is (a) entirely on the left of (b)?
600 */
601Datum
603{
604 SEG *a = PG_GETARG_SEG_P(0);
605 SEG *b = PG_GETARG_SEG_P(1);
606
607 PG_RETURN_BOOL(a->upper < b->lower);
608}
609
610/*
611 * seg_right -- is (a) entirely on the right of (b)?
612 */
613Datum
615{
616 SEG *a = PG_GETARG_SEG_P(0);
617 SEG *b = PG_GETARG_SEG_P(1);
618
619 PG_RETURN_BOOL(a->lower > b->upper);
620}
621
622/*
623 * seg_over_right -- is the left edge of (a) located at or right of the left edge of (b)?
624 */
625Datum
627{
628 SEG *a = PG_GETARG_SEG_P(0);
629 SEG *b = PG_GETARG_SEG_P(1);
630
631 PG_RETURN_BOOL(a->lower >= b->lower);
632}
633
634Datum
636{
637 SEG *a = PG_GETARG_SEG_P(0);
638 SEG *b = PG_GETARG_SEG_P(1);
639 SEG *n;
640
641 n = palloc_object(SEG);
642
643 /* take max of upper endpoints */
644 if (a->upper > b->upper)
645 {
646 n->upper = a->upper;
647 n->u_sigd = a->u_sigd;
648 n->u_ext = a->u_ext;
649 }
650 else
651 {
652 n->upper = b->upper;
653 n->u_sigd = b->u_sigd;
654 n->u_ext = b->u_ext;
655 }
656
657 /* take min of lower endpoints */
658 if (a->lower < b->lower)
659 {
660 n->lower = a->lower;
661 n->l_sigd = a->l_sigd;
662 n->l_ext = a->l_ext;
663 }
664 else
665 {
666 n->lower = b->lower;
667 n->l_sigd = b->l_sigd;
668 n->l_ext = b->l_ext;
669 }
670
672}
673
674Datum
676{
677 SEG *a = PG_GETARG_SEG_P(0);
678 SEG *b = PG_GETARG_SEG_P(1);
679 SEG *n;
680
681 n = palloc_object(SEG);
682
683 /* take min of upper endpoints */
684 if (a->upper < b->upper)
685 {
686 n->upper = a->upper;
687 n->u_sigd = a->u_sigd;
688 n->u_ext = a->u_ext;
689 }
690 else
691 {
692 n->upper = b->upper;
693 n->u_sigd = b->u_sigd;
694 n->u_ext = b->u_ext;
695 }
696
697 /* take max of lower endpoints */
698 if (a->lower > b->lower)
699 {
700 n->lower = a->lower;
701 n->l_sigd = a->l_sigd;
702 n->l_ext = a->l_ext;
703 }
704 else
705 {
706 n->lower = b->lower;
707 n->l_sigd = b->l_sigd;
708 n->l_ext = b->l_ext;
709 }
710
712}
713
714static void
715rt_seg_size(SEG *a, float *size)
716{
717 if (a == (SEG *) NULL || a->upper <= a->lower)
718 *size = 0.0;
719 else
720 *size = fabsf(a->upper - a->lower);
721}
722
723Datum
725{
726 SEG *seg = PG_GETARG_SEG_P(0);
727
728 PG_RETURN_FLOAT4(fabsf(seg->upper - seg->lower));
729}
730
731
732/*****************************************************************************
733 * Miscellaneous operators
734 *****************************************************************************/
735Datum
737{
738 SEG *a = PG_GETARG_SEG_P(0);
739 SEG *b = PG_GETARG_SEG_P(1);
740
741 /*
742 * First compare on lower boundary position
743 */
744 if (a->lower < b->lower)
745 PG_RETURN_INT32(-1);
746 if (a->lower > b->lower)
748
749 /*
750 * a->lower == b->lower, so consider type of boundary.
751 *
752 * A '-' lower bound is < any other kind (this could only be relevant if
753 * -HUGE_VAL is used as a regular data value). A '<' lower bound is < any
754 * other kind except '-'. A '>' lower bound is > any other kind.
755 */
756 if (a->l_ext != b->l_ext)
757 {
758 if (a->l_ext == '-')
759 PG_RETURN_INT32(-1);
760 if (b->l_ext == '-')
762 if (a->l_ext == '<')
763 PG_RETURN_INT32(-1);
764 if (b->l_ext == '<')
766 if (a->l_ext == '>')
768 if (b->l_ext == '>')
769 PG_RETURN_INT32(-1);
770 }
771
772 /*
773 * For other boundary types, consider # of significant digits first.
774 */
775 if (a->l_sigd < b->l_sigd) /* (a) is blurred and is likely to include (b) */
776 PG_RETURN_INT32(-1);
777 if (a->l_sigd > b->l_sigd) /* (a) is less blurred and is likely to be
778 * included in (b) */
780
781 /*
782 * For same # of digits, an approximate boundary is more blurred than
783 * exact.
784 */
785 if (a->l_ext != b->l_ext)
786 {
787 if (a->l_ext == '~') /* (a) is approximate, while (b) is exact */
788 PG_RETURN_INT32(-1);
789 if (b->l_ext == '~')
791 /* can't get here unless data is corrupt */
792 elog(ERROR, "bogus lower boundary types %d %d",
793 (int) a->l_ext, (int) b->l_ext);
794 }
795
796 /* at this point, the lower boundaries are identical */
797
798 /*
799 * First compare on upper boundary position
800 */
801 if (a->upper < b->upper)
802 PG_RETURN_INT32(-1);
803 if (a->upper > b->upper)
805
806 /*
807 * a->upper == b->upper, so consider type of boundary.
808 *
809 * A '-' upper bound is > any other kind (this could only be relevant if
810 * HUGE_VAL is used as a regular data value). A '<' upper bound is < any
811 * other kind. A '>' upper bound is > any other kind except '-'.
812 */
813 if (a->u_ext != b->u_ext)
814 {
815 if (a->u_ext == '-')
817 if (b->u_ext == '-')
818 PG_RETURN_INT32(-1);
819 if (a->u_ext == '<')
820 PG_RETURN_INT32(-1);
821 if (b->u_ext == '<')
823 if (a->u_ext == '>')
825 if (b->u_ext == '>')
826 PG_RETURN_INT32(-1);
827 }
828
829 /*
830 * For other boundary types, consider # of significant digits first. Note
831 * result here is converse of the lower-boundary case.
832 */
833 if (a->u_sigd < b->u_sigd) /* (a) is blurred and is likely to include (b) */
835 if (a->u_sigd > b->u_sigd) /* (a) is less blurred and is likely to be
836 * included in (b) */
837 PG_RETURN_INT32(-1);
838
839 /*
840 * For same # of digits, an approximate boundary is more blurred than
841 * exact. Again, result is converse of lower-boundary case.
842 */
843 if (a->u_ext != b->u_ext)
844 {
845 if (a->u_ext == '~') /* (a) is approximate, while (b) is exact */
847 if (b->u_ext == '~')
848 PG_RETURN_INT32(-1);
849 /* can't get here unless data is corrupt */
850 elog(ERROR, "bogus upper boundary types %d %d",
851 (int) a->u_ext, (int) b->u_ext);
852 }
853
855}
856
857Datum
866
867Datum
876
877Datum
886
887Datum
896
897
898Datum
907
908
909
910/*****************************************************************************
911 * Auxiliary functions
912 *****************************************************************************/
913
914/*
915 * The purpose of this routine is to print the given floating point
916 * value with exactly n significant digits. Its behaviour
917 * is similar to %.ng except it prints 8.00 where %.ng would
918 * print 8. Returns the length of the string written at "result".
919 *
920 * Caller must provide a sufficiently large result buffer; 16 bytes
921 * should be enough for all known float implementations.
922 */
923static int
924restore(char *result, float val, int n)
925{
926 char buf[25] = {
927 '0', '0', '0', '0', '0',
928 '0', '0', '0', '0', '0',
929 '0', '0', '0', '0', '0',
930 '0', '0', '0', '0', '0',
931 '0', '0', '0', '0', '\0'
932 };
933 char *p;
934 int exp;
935 int i,
936 dp,
937 sign;
938
939 /*
940 * Put a cap on the number of significant digits to avoid garbage in the
941 * output and ensure we don't overrun the result buffer. (n should not be
942 * negative, but check to protect ourselves against corrupted data.)
943 */
944 if (n <= 0)
945 n = FLT_DIG;
946 else
947 n = Min(n, FLT_DIG);
948
949 /* remember the sign */
950 sign = (val < 0 ? 1 : 0);
951
952 /* print, in %e style to start with */
953 sprintf(result, "%.*e", n - 1, val);
954
955 /* find the exponent */
956 p = strchr(result, 'e');
957
958 /* punt if we have 'inf' or similar */
959 if (p == NULL)
960 return strlen(result);
961
962 exp = atoi(p + 1);
963 if (exp == 0)
964 {
965 /* just truncate off the 'e+00' */
966 *p = '\0';
967 }
968 else
969 {
970 if (abs(exp) <= 4)
971 {
972 /*
973 * remove the decimal point from the mantissa and write the digits
974 * to the buf array
975 */
976 for (p = result + sign, i = 10, dp = 0; *p != 'e'; p++, i++)
977 {
978 buf[i] = *p;
979 if (*p == '.')
980 {
981 dp = i--; /* skip the decimal point */
982 }
983 }
984 if (dp == 0)
985 dp = i--; /* no decimal point was found in the above
986 * for() loop */
987
988 if (exp > 0)
989 {
990 if (dp - 10 + exp >= n)
991 {
992 /*
993 * the decimal point is behind the last significant digit;
994 * the digits in between must be converted to the exponent
995 * and the decimal point placed after the first digit
996 */
997 exp = dp - 10 + exp - n;
998 buf[10 + n] = '\0';
999
1000 /* insert the decimal point */
1001 if (n > 1)
1002 {
1003 dp = 11;
1004 for (i = 23; i > dp; i--)
1005 buf[i] = buf[i - 1];
1006 buf[dp] = '.';
1007 }
1008
1009 /*
1010 * adjust the exponent by the number of digits after the
1011 * decimal point
1012 */
1013 if (n > 1)
1014 sprintf(&buf[11 + n], "e%d", exp + n - 1);
1015 else
1016 sprintf(&buf[11], "e%d", exp + n - 1);
1017
1018 if (sign)
1019 {
1020 buf[9] = '-';
1021 strcpy(result, &buf[9]);
1022 }
1023 else
1024 strcpy(result, &buf[10]);
1025 }
1026 else
1027 { /* insert the decimal point */
1028 dp += exp;
1029 for (i = 23; i > dp; i--)
1030 buf[i] = buf[i - 1];
1031 buf[11 + n] = '\0';
1032 buf[dp] = '.';
1033 if (sign)
1034 {
1035 buf[9] = '-';
1036 strcpy(result, &buf[9]);
1037 }
1038 else
1039 strcpy(result, &buf[10]);
1040 }
1041 }
1042 else
1043 { /* exp <= 0 */
1044 dp += exp - 1;
1045 buf[10 + n] = '\0';
1046 buf[dp] = '.';
1047 if (sign)
1048 {
1049 buf[dp - 2] = '-';
1050 strcpy(result, &buf[dp - 2]);
1051 }
1052 else
1053 strcpy(result, &buf[dp - 1]);
1054 }
1055 }
1056
1057 /* do nothing for abs(exp) > 4; %e must be OK */
1058 /* just get rid of zeroes after [eE]- and +zeroes after [Ee]. */
1059
1060 /* ... this is not done yet. */
1061 }
1062 return strlen(result);
1063}
1064
1065
1066/*
1067 * Miscellany
1068 */
1069
1070/*
1071 * find out the number of significant digits in a string representing
1072 * a floating point number
1073 */
1074int
1076{
1077 const char *p = s;
1078 int n,
1079 c,
1080 zeroes;
1081
1082 zeroes = 1;
1083 /* skip leading zeroes and sign */
1084 for (c = *p; (c == '0' || c == '+' || c == '-') && c != 0; c = *(++p));
1085
1086 /* skip decimal point and following zeroes */
1087 for (c = *p; (c == '0' || c == '.') && c != 0; c = *(++p))
1088 {
1089 if (c != '.')
1090 zeroes++;
1091 }
1092
1093 /* count significant digits (n) */
1094 for (c = *p, n = 0; c != 0; c = *(++p))
1095 {
1096 if (!((c >= '0' && c <= '9') || (c == '.')))
1097 break;
1098 if (c != '.')
1099 n++;
1100 }
1101
1102 if (!n)
1103 return zeroes;
1104
1105 return n;
1106}
#define Min(x, y)
Definition c.h:1091
uint32 result
memcpy(sums, checksumBaseOffsets, sizeof(checksumBaseOffsets))
void * yyscan_t
Definition cubedata.h:65
#define fprintf(file, fmt, msg)
Definition cubescan.l:21
#define ERROR
Definition elog.h:40
#define elog(elevel,...)
Definition elog.h:228
#define palloc_object(type)
Definition fe_memutils.h:89
#define PG_GETARG_OID(n)
Definition fmgr.h:275
#define DirectFunctionCall2(func, arg1, arg2)
Definition fmgr.h:690
#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:1390
uint16 OffsetNumber
Definition off.h:24
const void * data
static char buf[DEFAULT_XLOG_SEG_SIZE]
#define sprintf
Definition port.h:263
#define qsort(a, b, c, d)
Definition port.h:496
static bool DatumGetBool(Datum X)
Definition postgres.h:100
static Datum BoolGetDatum(bool X)
Definition postgres.h:112
uint64_t Datum
Definition postgres.h:70
static int32 DatumGetInt32(Datum X)
Definition postgres.h:202
#define PointerGetDatum(X)
Definition postgres.h:354
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:868
Datum gseg_decompress(PG_FUNCTION_ARGS)
Definition seg.c:265
Datum seg_gt(PG_FUNCTION_ARGS)
Definition seg.c:878
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:626
Datum seg_contained(PG_FUNCTION_ARGS)
Definition seg.c:551
Datum seg_overlap(PG_FUNCTION_ARGS)
Definition seg.c:577
Datum seg_right(PG_FUNCTION_ARGS)
Definition seg.c:614
#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:858
#define DatumGetSegP(X)
Definition seg.c:22
Datum seg_size(PG_FUNCTION_ARGS)
Definition seg.c:724
Datum seg_union(PG_FUNCTION_ARGS)
Definition seg.c:635
int significant_digits(const char *s)
Definition seg.c:1075
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:888
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:736
static int restore(char *result, float val, int n)
Definition seg.c:924
Datum seg_inter(PG_FUNCTION_ARGS)
Definition seg.c:675
Datum seg_left(PG_FUNCTION_ARGS)
Definition seg.c:602
static void rt_seg_size(SEG *a, float *size)
Definition seg.c:715
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:590
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:899
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