2 /* contrib/cube/cubeparse.y */
4 /* NdBox = [(lowerleft),(upperright)] */
5 /* [(xLL(1)...xLL(N)),(xUR(1)...xUR(n))] */
10 #include "nodes/miscnodes.h"
11 #include "utils/float.h"
14 /* All grammar constructs return strings */
15 #define YYSTYPE char *
17 #include "cubeparse.h"
19 /* silence -Wmissing-variable-declarations */
20 extern
int cube_yychar
;
21 extern
int cube_yynerrs
;
24 * Bison doesn't allocate anything that needs to live across parser calls,
25 * so we can easily have it use palloc instead of malloc. This prevents
26 * memory leaks if we error out during parsing.
28 #define YYMALLOC palloc
31 static int item_count
(const char *s
, char delim
);
32 static bool write_box
(int dim
, char *str1
, char *str2
,
33 NDBOX
**result
, struct Node
*escontext
);
34 static bool write_point_as_box
(int dim
, char *str
,
35 NDBOX
**result
, struct Node
*escontext
);
39 /* BISON Declarations */
40 %parse
-param
{NDBOX
**result
}
41 %parse
-param
{Size scanbuflen
}
42 %parse
-param
{struct Node
*escontext
}
44 %name
-prefix
="cube_yy"
46 %token CUBEFLOAT O_PAREN C_PAREN O_BRACKET C_BRACKET COMMA
52 box: O_BRACKET paren_list COMMA paren_list C_BRACKET
56 dim
= item_count
($2, ',');
57 if
(item_count
($4, ',') != dim
)
60 (errcode
(ERRCODE_INVALID_TEXT_REPRESENTATION
),
61 errmsg
("invalid input syntax for cube"),
62 errdetail
("Different point dimensions in (%s) and (%s).",
66 if
(dim
> CUBE_MAX_DIM
)
69 (errcode
(ERRCODE_INVALID_TEXT_REPRESENTATION
),
70 errmsg
("invalid input syntax for cube"),
71 errdetail
("A cube cannot have more than %d dimensions.",
76 if
(!write_box
(dim
, $2, $4, result
, escontext
))
80 | paren_list COMMA paren_list
84 dim
= item_count
($1, ',');
85 if
(item_count
($3, ',') != dim
)
88 (errcode
(ERRCODE_INVALID_TEXT_REPRESENTATION
),
89 errmsg
("invalid input syntax for cube"),
90 errdetail
("Different point dimensions in (%s) and (%s).",
94 if
(dim
> CUBE_MAX_DIM
)
97 (errcode
(ERRCODE_INVALID_TEXT_REPRESENTATION
),
98 errmsg
("invalid input syntax for cube"),
99 errdetail
("A cube cannot have more than %d dimensions.",
104 if
(!write_box
(dim
, $1, $3, result
, escontext
))
112 dim
= item_count
($1, ',');
113 if
(dim
> CUBE_MAX_DIM
)
116 (errcode
(ERRCODE_INVALID_TEXT_REPRESENTATION
),
117 errmsg
("invalid input syntax for cube"),
118 errdetail
("A cube cannot have more than %d dimensions.",
123 if
(!write_point_as_box
(dim
, $1, result
, escontext
))
131 dim
= item_count
($1, ',');
132 if
(dim
> CUBE_MAX_DIM
)
135 (errcode
(ERRCODE_INVALID_TEXT_REPRESENTATION
),
136 errmsg
("invalid input syntax for cube"),
137 errdetail
("A cube cannot have more than %d dimensions.",
142 if
(!write_point_as_box
(dim
, $1, result
, escontext
))
147 paren_list: O_PAREN list C_PAREN
159 /* alloc enough space to be sure whole list will fit */
160 $$
= palloc
(scanbuflen
+ 1);
163 | list COMMA CUBEFLOAT
173 /* This assumes the string has been normalized by productions above */
175 item_count
(const char *s
, char delim
)
182 while
((s
= strchr
(s
, delim
)) != NULL
)
192 write_box
(int dim
, char *str1
, char *str2
,
193 NDBOX
**result
, struct Node
*escontext
)
199 int size
= CUBE_SIZE
(dim
);
203 SET_VARSIZE
(bp
, size
);
210 bp
->x
[i
++] = float8in_internal
(s
, &endptr
, "cube", str1
, escontext
);
211 if
(SOFT_ERROR_OCCURRED
(escontext
))
214 while
((s
= strchr
(s
, ',')) != NULL
)
217 bp
->x
[i
++] = float8in_internal
(s
, &endptr
, "cube", str1
, escontext
);
218 if
(SOFT_ERROR_OCCURRED
(escontext
))
226 bp
->x
[i
] = float8in_internal
(s
, &endptr
, "cube", str2
, escontext
);
227 if
(SOFT_ERROR_OCCURRED
(escontext
))
229 /* code this way to do right thing with NaN */
230 point
&= (bp
->x
[i
] == bp
->x
[0]);
233 while
((s
= strchr
(s
, ',')) != NULL
)
236 bp
->x
[i
] = float8in_internal
(s
, &endptr
, "cube", str2
, escontext
);
237 if
(SOFT_ERROR_OCCURRED
(escontext
))
239 point
&= (bp
->x
[i
] == bp
->x
[i
- dim
]);
242 Assert
(i
== dim
* 2);
247 * The value turned out to be a point, ie. all the upper-right
248 * coordinates were equal to the lower-left coordinates. Resize the
249 * cube we constructed. Note: we don't bother to repalloc() it
250 * smaller, as it's unlikely that the tiny amount of memory freed
251 * that way would be useful, and the output is always short-lived.
253 size
= POINT_SIZE
(dim
);
254 SET_VARSIZE
(bp
, size
);
263 write_point_as_box
(int dim
, char *str
,
264 NDBOX
**result
, struct Node
*escontext
)
272 size
= POINT_SIZE
(dim
);
274 SET_VARSIZE
(bp
, size
);
282 bp
->x
[i
++] = float8in_internal
(s
, &endptr
, "cube", str
, escontext
);
283 if
(SOFT_ERROR_OCCURRED
(escontext
))
286 while
((s
= strchr
(s
, ',')) != NULL
)
289 bp
->x
[i
++] = float8in_internal
(s
, &endptr
, "cube", str
, escontext
);
290 if
(SOFT_ERROR_OCCURRED
(escontext
))