Doc: mention executor memory usage for enable_partitionwise* GUCs
[pgsql.git] / contrib / seg / segparse.y
blob9635c3af6e62713e0a05fdc03fcf4df4fcf03cea
1 %{
2 /* contrib/seg/segparse.y */
4 #include "postgres.h"
6 #include <float.h>
7 #include <math.h>
9 #include "fmgr.h"
10 #include "nodes/miscnodes.h"
11 #include "utils/builtins.h"
12 #include "utils/float.h"
14 #include "segdata.h"
16 /* silence -Wmissing-variable-declarations */
17 extern int seg_yychar;
18 extern int seg_yynerrs;
21 * Bison doesn't allocate anything that needs to live across parser calls,
22 * so we can easily have it use palloc instead of malloc. This prevents
23 * memory leaks if we error out during parsing.
25 #define YYMALLOC palloc
26 #define YYFREE pfree
28 static bool seg_atof(char *value, float *result, struct Node *escontext);
30 static int sig_digits(const char *value);
34 /* BISON Declarations */
35 %parse-param {SEG *result}
36 %parse-param {struct Node *escontext}
37 %expect 0
38 %name-prefix="seg_yy"
40 %union
42 struct BND
44 float val;
45 char ext;
46 char sigd;
47 } bnd;
48 char *text;
50 %token <text> SEGFLOAT
51 %token <text> RANGE
52 %token <text> PLUMIN
53 %token <text> EXTENSION
54 %type <bnd> boundary
55 %type <bnd> deviation
56 %start range
58 /* Grammar follows */
62 range: boundary PLUMIN deviation
64 char strbuf[25];
66 result->lower = $1.val - $3.val;
67 result->upper = $1.val + $3.val;
68 snprintf(strbuf, sizeof(strbuf), "%g", result->lower);
69 result->l_sigd = Max(sig_digits(strbuf), Max($1.sigd, $3.sigd));
70 snprintf(strbuf, sizeof(strbuf), "%g", result->upper);
71 result->u_sigd = Max(sig_digits(strbuf), Max($1.sigd, $3.sigd));
72 result->l_ext = '\0';
73 result->u_ext = '\0';
76 | boundary RANGE boundary
78 result->lower = $1.val;
79 result->upper = $3.val;
80 if ( result->lower > result->upper ) {
81 errsave(escontext,
82 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
83 errmsg("swapped boundaries: %g is greater than %g",
84 result->lower, result->upper)));
86 YYERROR;
88 result->l_sigd = $1.sigd;
89 result->u_sigd = $3.sigd;
90 result->l_ext = ( $1.ext ? $1.ext : '\0' );
91 result->u_ext = ( $3.ext ? $3.ext : '\0' );
94 | boundary RANGE
96 result->lower = $1.val;
97 result->upper = HUGE_VAL;
98 result->l_sigd = $1.sigd;
99 result->u_sigd = 0;
100 result->l_ext = ( $1.ext ? $1.ext : '\0' );
101 result->u_ext = '-';
104 | RANGE boundary
106 result->lower = -HUGE_VAL;
107 result->upper = $2.val;
108 result->l_sigd = 0;
109 result->u_sigd = $2.sigd;
110 result->l_ext = '-';
111 result->u_ext = ( $2.ext ? $2.ext : '\0' );
114 | boundary
116 result->lower = result->upper = $1.val;
117 result->l_sigd = result->u_sigd = $1.sigd;
118 result->l_ext = result->u_ext = ( $1.ext ? $1.ext : '\0' );
122 boundary: SEGFLOAT
124 /* temp variable avoids a gcc 3.3.x bug on Sparc64 */
125 float val;
127 if (!seg_atof($1, &val, escontext))
128 YYABORT;
130 $$.ext = '\0';
131 $$.sigd = sig_digits($1);
132 $$.val = val;
134 | EXTENSION SEGFLOAT
136 /* temp variable avoids a gcc 3.3.x bug on Sparc64 */
137 float val;
139 if (!seg_atof($2, &val, escontext))
140 YYABORT;
142 $$.ext = $1[0];
143 $$.sigd = sig_digits($2);
144 $$.val = val;
148 deviation: SEGFLOAT
150 /* temp variable avoids a gcc 3.3.x bug on Sparc64 */
151 float val;
153 if (!seg_atof($1, &val, escontext))
154 YYABORT;
156 $$.ext = '\0';
157 $$.sigd = sig_digits($1);
158 $$.val = val;
165 static bool
166 seg_atof(char *value, float *result, struct Node *escontext)
168 *result = float4in_internal(value, NULL, "seg", value, escontext);
169 if (SOFT_ERROR_OCCURRED(escontext))
170 return false;
171 return true;
174 static int
175 sig_digits(const char *value)
177 int n = significant_digits(value);
179 /* Clamp, to ensure value will fit in sigd fields */
180 return Min(n, FLT_DIG);