Remove incorrect entries in pg_walsummary's getopt_long call.
[pgsql.git] / contrib / cube / cubeparse.y
blobb39fbe63e6b9519fc5b2dd4797531c8dbea1d91f
1 %{
2 /* contrib/cube/cubeparse.y */
4 /* NdBox = [(lowerleft),(upperright)] */
5 /* [(xLL(1)...xLL(N)),(xUR(1)...xUR(n))] */
7 #include "postgres.h"
9 #include "cubedata.h"
10 #include "nodes/miscnodes.h"
11 #include "utils/float.h"
12 #include "varatt.h"
14 /* All grammar constructs return strings */
15 #define YYSTYPE char *
18 * Bison doesn't allocate anything that needs to live across parser calls,
19 * so we can easily have it use palloc instead of malloc. This prevents
20 * memory leaks if we error out during parsing.
22 #define YYMALLOC palloc
23 #define YYFREE pfree
25 static int item_count(const char *s, char delim);
26 static bool write_box(int dim, char *str1, char *str2,
27 NDBOX **result, struct Node *escontext);
28 static bool write_point_as_box(int dim, char *str,
29 NDBOX **result, struct Node *escontext);
33 /* BISON Declarations */
34 %parse-param {NDBOX **result}
35 %parse-param {Size scanbuflen}
36 %parse-param {struct Node *escontext}
37 %expect 0
38 %name-prefix="cube_yy"
40 %token CUBEFLOAT O_PAREN C_PAREN O_BRACKET C_BRACKET COMMA
41 %start box
43 /* Grammar follows */
46 box: O_BRACKET paren_list COMMA paren_list C_BRACKET
48 int dim;
50 dim = item_count($2, ',');
51 if (item_count($4, ',') != dim)
53 errsave(escontext,
54 (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
55 errmsg("invalid input syntax for cube"),
56 errdetail("Different point dimensions in (%s) and (%s).",
57 $2, $4)));
58 YYABORT;
60 if (dim > CUBE_MAX_DIM)
62 errsave(escontext,
63 (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
64 errmsg("invalid input syntax for cube"),
65 errdetail("A cube cannot have more than %d dimensions.",
66 CUBE_MAX_DIM)));
67 YYABORT;
70 if (!write_box(dim, $2, $4, result, escontext))
71 YYABORT;
74 | paren_list COMMA paren_list
76 int dim;
78 dim = item_count($1, ',');
79 if (item_count($3, ',') != dim)
81 errsave(escontext,
82 (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
83 errmsg("invalid input syntax for cube"),
84 errdetail("Different point dimensions in (%s) and (%s).",
85 $1, $3)));
86 YYABORT;
88 if (dim > CUBE_MAX_DIM)
90 errsave(escontext,
91 (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
92 errmsg("invalid input syntax for cube"),
93 errdetail("A cube cannot have more than %d dimensions.",
94 CUBE_MAX_DIM)));
95 YYABORT;
98 if (!write_box(dim, $1, $3, result, escontext))
99 YYABORT;
102 | paren_list
104 int dim;
106 dim = item_count($1, ',');
107 if (dim > CUBE_MAX_DIM)
109 errsave(escontext,
110 (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
111 errmsg("invalid input syntax for cube"),
112 errdetail("A cube cannot have more than %d dimensions.",
113 CUBE_MAX_DIM)));
114 YYABORT;
117 if (!write_point_as_box(dim, $1, result, escontext))
118 YYABORT;
121 | list
123 int dim;
125 dim = item_count($1, ',');
126 if (dim > CUBE_MAX_DIM)
128 errsave(escontext,
129 (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
130 errmsg("invalid input syntax for cube"),
131 errdetail("A cube cannot have more than %d dimensions.",
132 CUBE_MAX_DIM)));
133 YYABORT;
136 if (!write_point_as_box(dim, $1, result, escontext))
137 YYABORT;
141 paren_list: O_PAREN list C_PAREN
143 $$ = $2;
145 | O_PAREN C_PAREN
147 $$ = pstrdup("");
151 list: CUBEFLOAT
153 /* alloc enough space to be sure whole list will fit */
154 $$ = palloc(scanbuflen + 1);
155 strcpy($$, $1);
157 | list COMMA CUBEFLOAT
159 $$ = $1;
160 strcat($$, ",");
161 strcat($$, $3);
167 /* This assumes the string has been normalized by productions above */
168 static int
169 item_count(const char *s, char delim)
171 int nitems = 0;
173 if (s[0] != '\0')
175 nitems++;
176 while ((s = strchr(s, delim)) != NULL)
178 nitems++;
179 s++;
182 return nitems;
185 static bool
186 write_box(int dim, char *str1, char *str2,
187 NDBOX **result, struct Node *escontext)
189 NDBOX *bp;
190 char *s;
191 char *endptr;
192 int i;
193 int size = CUBE_SIZE(dim);
194 bool point = true;
196 bp = palloc0(size);
197 SET_VARSIZE(bp, size);
198 SET_DIM(bp, dim);
200 s = str1;
201 i = 0;
202 if (dim > 0)
204 bp->x[i++] = float8in_internal(s, &endptr, "cube", str1, escontext);
205 if (SOFT_ERROR_OCCURRED(escontext))
206 return false;
208 while ((s = strchr(s, ',')) != NULL)
210 s++;
211 bp->x[i++] = float8in_internal(s, &endptr, "cube", str1, escontext);
212 if (SOFT_ERROR_OCCURRED(escontext))
213 return false;
215 Assert(i == dim);
217 s = str2;
218 if (dim > 0)
220 bp->x[i] = float8in_internal(s, &endptr, "cube", str2, escontext);
221 if (SOFT_ERROR_OCCURRED(escontext))
222 return false;
223 /* code this way to do right thing with NaN */
224 point &= (bp->x[i] == bp->x[0]);
225 i++;
227 while ((s = strchr(s, ',')) != NULL)
229 s++;
230 bp->x[i] = float8in_internal(s, &endptr, "cube", str2, escontext);
231 if (SOFT_ERROR_OCCURRED(escontext))
232 return false;
233 point &= (bp->x[i] == bp->x[i - dim]);
234 i++;
236 Assert(i == dim * 2);
238 if (point)
241 * The value turned out to be a point, ie. all the upper-right
242 * coordinates were equal to the lower-left coordinates. Resize the
243 * cube we constructed. Note: we don't bother to repalloc() it
244 * smaller, as it's unlikely that the tiny amount of memory freed
245 * that way would be useful, and the output is always short-lived.
247 size = POINT_SIZE(dim);
248 SET_VARSIZE(bp, size);
249 SET_POINT_BIT(bp);
252 *result = bp;
253 return true;
256 static bool
257 write_point_as_box(int dim, char *str,
258 NDBOX **result, struct Node *escontext)
260 NDBOX *bp;
261 int i,
262 size;
263 char *s;
264 char *endptr;
266 size = POINT_SIZE(dim);
267 bp = palloc0(size);
268 SET_VARSIZE(bp, size);
269 SET_DIM(bp, dim);
270 SET_POINT_BIT(bp);
272 s = str;
273 i = 0;
274 if (dim > 0)
276 bp->x[i++] = float8in_internal(s, &endptr, "cube", str, escontext);
277 if (SOFT_ERROR_OCCURRED(escontext))
278 return false;
280 while ((s = strchr(s, ',')) != NULL)
282 s++;
283 bp->x[i++] = float8in_internal(s, &endptr, "cube", str, escontext);
284 if (SOFT_ERROR_OCCURRED(escontext))
285 return false;
287 Assert(i == dim);
289 *result = bp;
290 return true;