1 /*****************************************************************************
2 
3 Copyright (c) 1997, 2009, Innobase Oy. All Rights Reserved.
4 
5 This program is free software; you can redistribute it and/or modify it under
6 the terms of the GNU General Public License as published by the Free Software
7 Foundation; version 2 of the License.
8 
9 This program is distributed in the hope that it will be useful, but WITHOUT
10 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
11 FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
12 
13 You should have received a copy of the GNU General Public License along with
14 this program; if not, write to the Free Software Foundation, Inc.,
15 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
16 
17 *****************************************************************************/
18 
19 /******************************************************
20 SQL parser: input file for the GNU Bison parser generator
21 
22 Look from pars0lex.l for instructions how to generate the C files for
23 the InnoDB parser.
24 
25 Created 12/14/1997 Heikki Tuuri
26 *******************************************************/
27 
28 %{
29 /* The value of the semantic attribute is a pointer to a query tree node
30 que_node_t */
31 
32 #include "univ.i"
33 #include <math.h>				/* Can't be before univ.i */
34 #include "pars0pars.h"
35 #include "mem0mem.h"
36 #include "que0types.h"
37 #include "que0que.h"
38 #include "row0sel.h"
39 
40 #define YYSTYPE que_node_t*
41 
42 /* #define __STDC__ */
43 
44 int
45 yylex(void);
46 %}
47 
48 %token PARS_INT_LIT
49 %token PARS_FLOAT_LIT
50 %token PARS_STR_LIT
51 %token PARS_FIXBINARY_LIT
52 %token PARS_BLOB_LIT
53 %token PARS_NULL_LIT
54 %token PARS_ID_TOKEN
55 %token PARS_AND_TOKEN
56 %token PARS_OR_TOKEN
57 %token PARS_NOT_TOKEN
58 %token PARS_GE_TOKEN
59 %token PARS_LE_TOKEN
60 %token PARS_NE_TOKEN
61 %token PARS_PROCEDURE_TOKEN
62 %token PARS_IN_TOKEN
63 %token PARS_OUT_TOKEN
64 %token PARS_BINARY_TOKEN
65 %token PARS_BLOB_TOKEN
66 %token PARS_INT_TOKEN
67 %token PARS_INTEGER_TOKEN
68 %token PARS_FLOAT_TOKEN
69 %token PARS_CHAR_TOKEN
70 %token PARS_IS_TOKEN
71 %token PARS_BEGIN_TOKEN
72 %token PARS_END_TOKEN
73 %token PARS_IF_TOKEN
74 %token PARS_THEN_TOKEN
75 %token PARS_ELSE_TOKEN
76 %token PARS_ELSIF_TOKEN
77 %token PARS_LOOP_TOKEN
78 %token PARS_WHILE_TOKEN
79 %token PARS_RETURN_TOKEN
80 %token PARS_SELECT_TOKEN
81 %token PARS_SUM_TOKEN
82 %token PARS_COUNT_TOKEN
83 %token PARS_DISTINCT_TOKEN
84 %token PARS_FROM_TOKEN
85 %token PARS_WHERE_TOKEN
86 %token PARS_FOR_TOKEN
87 %token PARS_DDOT_TOKEN
88 %token PARS_READ_TOKEN
89 %token PARS_ORDER_TOKEN
90 %token PARS_BY_TOKEN
91 %token PARS_ASC_TOKEN
92 %token PARS_DESC_TOKEN
93 %token PARS_INSERT_TOKEN
94 %token PARS_INTO_TOKEN
95 %token PARS_VALUES_TOKEN
96 %token PARS_UPDATE_TOKEN
97 %token PARS_SET_TOKEN
98 %token PARS_DELETE_TOKEN
99 %token PARS_CURRENT_TOKEN
100 %token PARS_OF_TOKEN
101 %token PARS_CREATE_TOKEN
102 %token PARS_TABLE_TOKEN
103 %token PARS_INDEX_TOKEN
104 %token PARS_UNIQUE_TOKEN
105 %token PARS_CLUSTERED_TOKEN
106 %token PARS_DOES_NOT_FIT_IN_MEM_TOKEN
107 %token PARS_ON_TOKEN
108 %token PARS_ASSIGN_TOKEN
109 %token PARS_DECLARE_TOKEN
110 %token PARS_CURSOR_TOKEN
111 %token PARS_SQL_TOKEN
112 %token PARS_OPEN_TOKEN
113 %token PARS_FETCH_TOKEN
114 %token PARS_CLOSE_TOKEN
115 %token PARS_NOTFOUND_TOKEN
116 %token PARS_TO_CHAR_TOKEN
117 %token PARS_TO_NUMBER_TOKEN
118 %token PARS_TO_BINARY_TOKEN
119 %token PARS_BINARY_TO_NUMBER_TOKEN
120 %token PARS_SUBSTR_TOKEN
121 %token PARS_REPLSTR_TOKEN
122 %token PARS_CONCAT_TOKEN
123 %token PARS_INSTR_TOKEN
124 %token PARS_LENGTH_TOKEN
125 %token PARS_SYSDATE_TOKEN
126 %token PARS_PRINTF_TOKEN
127 %token PARS_ASSERT_TOKEN
128 %token PARS_RND_TOKEN
129 %token PARS_RND_STR_TOKEN
130 %token PARS_ROW_PRINTF_TOKEN
131 %token PARS_COMMIT_TOKEN
132 %token PARS_ROLLBACK_TOKEN
133 %token PARS_WORK_TOKEN
134 %token PARS_UNSIGNED_TOKEN
135 %token PARS_EXIT_TOKEN
136 %token PARS_FUNCTION_TOKEN
137 %token PARS_LOCK_TOKEN
138 %token PARS_SHARE_TOKEN
139 %token PARS_MODE_TOKEN
140 
141 %left PARS_AND_TOKEN PARS_OR_TOKEN
142 %left PARS_NOT_TOKEN
143 %left '=' '<' '>' PARS_GE_TOKEN PARS_LE_TOKEN
144 %left '-' '+'
145 %left '*' '/'
146 %left NEG     /* negation--unary minus */
147 %left '%'
148 
149 /* Grammar follows */
150 %%
151 
152 top_statement:
153         procedure_definition ';'
154 
155 statement:
156 	stored_procedure_call
157 	| predefined_procedure_call ';'
158 	| while_statement ';'
159 	| for_statement ';'
160 	| exit_statement ';'
161 	| if_statement ';'
162 	| return_statement ';'
163 	| assignment_statement ';'
164 	| select_statement ';'
165 	| insert_statement ';'
166 	| row_printf_statement ';'
167 	| delete_statement_searched ';'
168 	| delete_statement_positioned ';'
169 	| update_statement_searched ';'
170 	| update_statement_positioned ';'
171 	| open_cursor_statement ';'
172 	| fetch_statement ';'
173 	| close_cursor_statement ';'
174 	| commit_statement ';'
175 	| rollback_statement ';'
176 	| create_table ';'
177 	| create_index ';'
178 ;
179 
180 statement_list:
181 	statement		{ $$ = que_node_list_add_last(NULL, $1); }
182 	| statement_list statement
183 				{ $$ = que_node_list_add_last($1, $2); }
184 ;
185 
186 exp:
187 	PARS_ID_TOKEN		{ $$ = $1;}
188 	| function_name '(' exp_list ')'
189 				{ $$ = pars_func($1, $3); }
190 	| PARS_INT_LIT		{ $$ = $1;}
191 	| PARS_FLOAT_LIT	{ $$ = $1;}
192 	| PARS_STR_LIT		{ $$ = $1;}
193 	| PARS_FIXBINARY_LIT	{ $$ = $1;}
194 	| PARS_BLOB_LIT		{ $$ = $1;}
195 	| PARS_NULL_LIT		{ $$ = $1;}
196 	| PARS_SQL_TOKEN	{ $$ = $1;}
197 	| exp '+' exp        	{ $$ = pars_op('+', $1, $3); }
198 	| exp '-' exp        	{ $$ = pars_op('-', $1, $3); }
199 	| exp '*' exp        	{ $$ = pars_op('*', $1, $3); }
200 	| exp '/' exp        	{ $$ = pars_op('/', $1, $3); }
201 	| '-' exp %prec NEG 	{ $$ = pars_op('-', $2, NULL); }
202 	| '(' exp ')'        	{ $$ = $2; }
203 	| exp '=' exp		{ $$ = pars_op('=', $1, $3); }
204 	| exp '<' exp		{ $$ = pars_op('<', $1, $3); }
205 	| exp '>' exp		{ $$ = pars_op('>', $1, $3); }
206 	| exp PARS_GE_TOKEN exp	{ $$ = pars_op(PARS_GE_TOKEN, $1, $3); }
207 	| exp PARS_LE_TOKEN exp	{ $$ = pars_op(PARS_LE_TOKEN, $1, $3); }
208 	| exp PARS_NE_TOKEN exp	{ $$ = pars_op(PARS_NE_TOKEN, $1, $3); }
209 	| exp PARS_AND_TOKEN exp{ $$ = pars_op(PARS_AND_TOKEN, $1, $3); }
210 	| exp PARS_OR_TOKEN exp	{ $$ = pars_op(PARS_OR_TOKEN, $1, $3); }
211 	| PARS_NOT_TOKEN exp	{ $$ = pars_op(PARS_NOT_TOKEN, $2, NULL); }
212 	| PARS_ID_TOKEN '%' PARS_NOTFOUND_TOKEN
213 				{ $$ = pars_op(PARS_NOTFOUND_TOKEN, $1, NULL); }
214 	| PARS_SQL_TOKEN '%' PARS_NOTFOUND_TOKEN
215 				{ $$ = pars_op(PARS_NOTFOUND_TOKEN, $1, NULL); }
216 ;
217 
218 function_name:
219 	PARS_TO_CHAR_TOKEN	{ $$ = &pars_to_char_token; }
220 	| PARS_TO_NUMBER_TOKEN	{ $$ = &pars_to_number_token; }
221 	| PARS_TO_BINARY_TOKEN	{ $$ = &pars_to_binary_token; }
222 	| PARS_BINARY_TO_NUMBER_TOKEN
223 				{ $$ = &pars_binary_to_number_token; }
224 	| PARS_SUBSTR_TOKEN	{ $$ = &pars_substr_token; }
225 	| PARS_CONCAT_TOKEN	{ $$ = &pars_concat_token; }
226 	| PARS_INSTR_TOKEN	{ $$ = &pars_instr_token; }
227 	| PARS_LENGTH_TOKEN	{ $$ = &pars_length_token; }
228 	| PARS_SYSDATE_TOKEN	{ $$ = &pars_sysdate_token; }
229 	| PARS_RND_TOKEN	{ $$ = &pars_rnd_token; }
230 	| PARS_RND_STR_TOKEN	{ $$ = &pars_rnd_str_token; }
231 ;
232 
233 question_mark_list:
234 	/* Nothing */
235 	| '?'
236 	| question_mark_list ',' '?'
237 ;
238 
239 stored_procedure_call:
240 	'{' PARS_ID_TOKEN '(' question_mark_list ')' '}'
241 				{ $$ = pars_stored_procedure_call($2); }
242 ;
243 
244 predefined_procedure_call:
245 	predefined_procedure_name '(' exp_list ')'
246 				{ $$ = pars_procedure_call($1, $3); }
247 ;
248 
249 predefined_procedure_name:
250 	PARS_REPLSTR_TOKEN	{ $$ = &pars_replstr_token; }
251 	| PARS_PRINTF_TOKEN	{ $$ = &pars_printf_token; }
252 	| PARS_ASSERT_TOKEN	{ $$ = &pars_assert_token; }
253 ;
254 
255 user_function_call:
256 	PARS_ID_TOKEN '(' ')'	{ $$ = $1; }
257 ;
258 
259 table_list:
260 	PARS_ID_TOKEN		{ $$ = que_node_list_add_last(NULL, $1); }
261 	| table_list ',' PARS_ID_TOKEN
262 				{ $$ = que_node_list_add_last($1, $3); }
263 ;
264 
265 variable_list:
266 	/* Nothing */		{ $$ = NULL; }
267 	| PARS_ID_TOKEN		{ $$ = que_node_list_add_last(NULL, $1); }
268 	| variable_list ',' PARS_ID_TOKEN
269 				{ $$ = que_node_list_add_last($1, $3); }
270 ;
271 
272 exp_list:
273 	/* Nothing */		{ $$ = NULL; }
274 	| exp			{ $$ = que_node_list_add_last(NULL, $1);}
275 	| exp_list ',' exp	{ $$ = que_node_list_add_last($1, $3); }
276 ;
277 
278 select_item:
279 	exp			{ $$ = $1; }
280 	| PARS_COUNT_TOKEN '(' '*' ')'
281 				{ $$ = pars_func(&pars_count_token,
282 				          que_node_list_add_last(NULL,
283 					    sym_tab_add_int_lit(
284 						pars_sym_tab_global, 1))); }
285 	| PARS_COUNT_TOKEN '(' PARS_DISTINCT_TOKEN PARS_ID_TOKEN ')'
286 				{ $$ = pars_func(&pars_count_token,
287 					    que_node_list_add_last(NULL,
288 						pars_func(&pars_distinct_token,
289 						     que_node_list_add_last(
290 								NULL, $4)))); }
291 	| PARS_SUM_TOKEN '(' exp ')'
292 				{ $$ = pars_func(&pars_sum_token,
293 						que_node_list_add_last(NULL,
294 									$3)); }
295 ;
296 
297 select_item_list:
298 	/* Nothing */		{ $$ = NULL; }
299 	| select_item		{ $$ = que_node_list_add_last(NULL, $1); }
300 	| select_item_list ',' select_item
301 				{ $$ = que_node_list_add_last($1, $3); }
302 ;
303 
304 select_list:
305 	'*'			{ $$ = pars_select_list(&pars_star_denoter,
306 								NULL); }
307 	| select_item_list PARS_INTO_TOKEN variable_list
308 				{ $$ = pars_select_list($1, $3); }
309 	| select_item_list	{ $$ = pars_select_list($1, NULL); }
310 ;
311 
312 search_condition:
313 	/* Nothing */		{ $$ = NULL; }
314 	| PARS_WHERE_TOKEN exp	{ $$ = $2; }
315 ;
316 
317 for_update_clause:
318 	/* Nothing */		{ $$ = NULL; }
319 	| PARS_FOR_TOKEN PARS_UPDATE_TOKEN
320 				{ $$ = &pars_update_token; }
321 ;
322 
323 lock_shared_clause:
324 	/* Nothing */		{ $$ = NULL; }
325 	| PARS_LOCK_TOKEN PARS_IN_TOKEN PARS_SHARE_TOKEN PARS_MODE_TOKEN
326 				{ $$ = &pars_share_token; }
327 ;
328 
329 order_direction:
330 	/* Nothing */		{ $$ = &pars_asc_token; }
331 	| PARS_ASC_TOKEN	{ $$ = &pars_asc_token; }
332 	| PARS_DESC_TOKEN	{ $$ = &pars_desc_token; }
333 ;
334 
335 order_by_clause:
336 	/* Nothing */		{ $$ = NULL; }
337 	| PARS_ORDER_TOKEN PARS_BY_TOKEN PARS_ID_TOKEN order_direction
338 				{ $$ = pars_order_by($3, $4); }
339 ;
340 
341 select_statement:
342 	PARS_SELECT_TOKEN select_list
343 	PARS_FROM_TOKEN table_list
344 	search_condition
345 	for_update_clause
346 	lock_shared_clause
347 	order_by_clause		{ $$ = pars_select_statement($2, $4, $5,
348 								$6, $7, $8); }
349 ;
350 
351 insert_statement_start:
352 	PARS_INSERT_TOKEN PARS_INTO_TOKEN
353 	PARS_ID_TOKEN		{ $$ = $3; }
354 ;
355 
356 insert_statement:
357 	insert_statement_start PARS_VALUES_TOKEN '(' exp_list ')'
358 				{ $$ = pars_insert_statement($1, $4, NULL); }
359 	| insert_statement_start select_statement
360 				{ $$ = pars_insert_statement($1, NULL, $2); }
361 ;
362 
363 column_assignment:
364 	PARS_ID_TOKEN '=' exp	{ $$ = pars_column_assignment($1, $3); }
365 ;
366 
367 column_assignment_list:
368 	column_assignment	{ $$ = que_node_list_add_last(NULL, $1); }
369 	| column_assignment_list ',' column_assignment
370 				{ $$ = que_node_list_add_last($1, $3); }
371 ;
372 
373 cursor_positioned:
374 	PARS_WHERE_TOKEN
375 	PARS_CURRENT_TOKEN PARS_OF_TOKEN
376 	PARS_ID_TOKEN 		{ $$ = $4; }
377 ;
378 
379 update_statement_start:
380 	PARS_UPDATE_TOKEN PARS_ID_TOKEN
381 	PARS_SET_TOKEN
382 	column_assignment_list	{ $$ = pars_update_statement_start(FALSE,
383 								$2, $4); }
384 ;
385 
386 update_statement_searched:
387 	update_statement_start
388 	search_condition	{ $$ = pars_update_statement($1, NULL, $2); }
389 ;
390 
391 update_statement_positioned:
392 	update_statement_start
393 	cursor_positioned	{ $$ = pars_update_statement($1, $2, NULL); }
394 ;
395 
396 delete_statement_start:
397 	PARS_DELETE_TOKEN PARS_FROM_TOKEN
398 	PARS_ID_TOKEN		{ $$ = pars_update_statement_start(TRUE,
399 								$3, NULL); }
400 ;
401 
402 delete_statement_searched:
403 	delete_statement_start
404 	search_condition	{ $$ = pars_update_statement($1, NULL, $2); }
405 ;
406 
407 delete_statement_positioned:
408 	delete_statement_start
409 	cursor_positioned	{ $$ = pars_update_statement($1, $2, NULL); }
410 ;
411 
412 row_printf_statement:
413 	PARS_ROW_PRINTF_TOKEN select_statement
414 				{ $$ = pars_row_printf_statement($2); }
415 ;
416 
417 assignment_statement:
418 	PARS_ID_TOKEN PARS_ASSIGN_TOKEN exp
419 				{ $$ = pars_assignment_statement($1, $3); }
420 ;
421 
422 elsif_element:
423 	PARS_ELSIF_TOKEN
424 	exp PARS_THEN_TOKEN statement_list
425 				{ $$ = pars_elsif_element($2, $4); }
426 ;
427 
428 elsif_list:
429 	elsif_element		{ $$ = que_node_list_add_last(NULL, $1); }
430 	| elsif_list elsif_element
431 				{ $$ = que_node_list_add_last($1, $2); }
432 ;
433 
434 else_part:
435 	/* Nothing */		{ $$ = NULL; }
436 	| PARS_ELSE_TOKEN statement_list
437 				{ $$ = $2; }
438 	| elsif_list		{ $$ = $1; }
439 ;
440 
441 if_statement:
442 	PARS_IF_TOKEN exp PARS_THEN_TOKEN statement_list
443 	else_part
444 	PARS_END_TOKEN PARS_IF_TOKEN
445 				{ $$ = pars_if_statement($2, $4, $5); }
446 ;
447 
448 while_statement:
449 	PARS_WHILE_TOKEN exp PARS_LOOP_TOKEN statement_list
450 	PARS_END_TOKEN PARS_LOOP_TOKEN
451 				{ $$ = pars_while_statement($2, $4); }
452 ;
453 
454 for_statement:
455 	PARS_FOR_TOKEN PARS_ID_TOKEN PARS_IN_TOKEN
456 	exp PARS_DDOT_TOKEN exp
457 	PARS_LOOP_TOKEN statement_list
458 	PARS_END_TOKEN PARS_LOOP_TOKEN
459 				{ $$ = pars_for_statement($2, $4, $6, $8); }
460 ;
461 
462 exit_statement:
463 	PARS_EXIT_TOKEN		{ $$ = pars_exit_statement(); }
464 ;
465 
466 return_statement:
467 	PARS_RETURN_TOKEN	{ $$ = pars_return_statement(); }
468 ;
469 
470 open_cursor_statement:
471 	PARS_OPEN_TOKEN PARS_ID_TOKEN
472 				{ $$ = pars_open_statement(
473 						ROW_SEL_OPEN_CURSOR, $2); }
474 ;
475 
476 close_cursor_statement:
477 	PARS_CLOSE_TOKEN PARS_ID_TOKEN
478 				{ $$ = pars_open_statement(
479 						ROW_SEL_CLOSE_CURSOR, $2); }
480 ;
481 
482 fetch_statement:
483 	PARS_FETCH_TOKEN PARS_ID_TOKEN PARS_INTO_TOKEN variable_list
484 				{ $$ = pars_fetch_statement($2, $4, NULL); }
485 	| PARS_FETCH_TOKEN PARS_ID_TOKEN PARS_INTO_TOKEN user_function_call
486 				{ $$ = pars_fetch_statement($2, NULL, $4); }
487 ;
488 
489 column_def:
490 	PARS_ID_TOKEN type_name	opt_column_len opt_unsigned opt_not_null
491 				{ $$ = pars_column_def($1, $2, $3, $4, $5); }
492 ;
493 
494 column_def_list:
495 	column_def		{ $$ = que_node_list_add_last(NULL, $1); }
496 	| column_def_list ',' column_def
497 				{ $$ = que_node_list_add_last($1, $3); }
498 ;
499 
500 opt_column_len:
501 	/* Nothing */		{ $$ = NULL; }
502 	| '(' PARS_INT_LIT ')'
503 				{ $$ = $2; }
504 ;
505 
506 opt_unsigned:
507 	/* Nothing */		{ $$ = NULL; }
508 	| PARS_UNSIGNED_TOKEN
509 				{ $$ = &pars_int_token;
510 					/* pass any non-NULL pointer */ }
511 ;
512 
513 opt_not_null:
514 	/* Nothing */		{ $$ = NULL; }
515 	| PARS_NOT_TOKEN PARS_NULL_LIT
516 				{ $$ = &pars_int_token;
517 					/* pass any non-NULL pointer */ }
518 ;
519 
520 not_fit_in_memory:
521 	/* Nothing */		{ $$ = NULL; }
522 	| PARS_DOES_NOT_FIT_IN_MEM_TOKEN
523 				{ $$ = &pars_int_token;
524 					/* pass any non-NULL pointer */ }
525 ;
526 
527 create_table:
528 	PARS_CREATE_TOKEN PARS_TABLE_TOKEN
529 	PARS_ID_TOKEN '(' column_def_list ')'
530 	not_fit_in_memory	{ $$ = pars_create_table($3, $5, $7); }
531 ;
532 
533 column_list:
534 	PARS_ID_TOKEN		{ $$ = que_node_list_add_last(NULL, $1); }
535 	| column_list ',' PARS_ID_TOKEN
536 				{ $$ = que_node_list_add_last($1, $3); }
537 ;
538 
539 unique_def:
540 	/* Nothing */		{ $$ = NULL; }
541 	| PARS_UNIQUE_TOKEN	{ $$ = &pars_unique_token; }
542 ;
543 
544 clustered_def:
545 	/* Nothing */		{ $$ = NULL; }
546 	| PARS_CLUSTERED_TOKEN	{ $$ = &pars_clustered_token; }
547 ;
548 
549 create_index:
550 	PARS_CREATE_TOKEN unique_def
551 	clustered_def
552 	PARS_INDEX_TOKEN
553 	PARS_ID_TOKEN PARS_ON_TOKEN PARS_ID_TOKEN
554 	'(' column_list ')'	{ $$ = pars_create_index($2, $3, $5, $7, $9); }
555 ;
556 
557 commit_statement:
558 	PARS_COMMIT_TOKEN PARS_WORK_TOKEN
559 				{ $$ = pars_commit_statement(); }
560 ;
561 
562 rollback_statement:
563 	PARS_ROLLBACK_TOKEN PARS_WORK_TOKEN
564 				{ $$ = pars_rollback_statement(); }
565 ;
566 
567 type_name:
568 	PARS_INT_TOKEN		{ $$ = &pars_int_token; }
569 	| PARS_INTEGER_TOKEN	{ $$ = &pars_int_token; }
570 	| PARS_CHAR_TOKEN	{ $$ = &pars_char_token; }
571 	| PARS_BINARY_TOKEN	{ $$ = &pars_binary_token; }
572 	| PARS_BLOB_TOKEN	{ $$ = &pars_blob_token; }
573 ;
574 
575 parameter_declaration:
576 	PARS_ID_TOKEN PARS_IN_TOKEN type_name
577 				{ $$ = pars_parameter_declaration($1,
578 							PARS_INPUT, $3); }
579 	| PARS_ID_TOKEN PARS_OUT_TOKEN type_name
580 				{ $$ = pars_parameter_declaration($1,
581 							PARS_OUTPUT, $3); }
582 ;
583 
584 parameter_declaration_list:
585 	/* Nothing */		{ $$ = NULL; }
586 	| parameter_declaration	{ $$ = que_node_list_add_last(NULL, $1); }
587 	| parameter_declaration_list ',' parameter_declaration
588 				{ $$ = que_node_list_add_last($1, $3); }
589 ;
590 
591 variable_declaration:
592 	PARS_ID_TOKEN type_name ';'
593 				{ $$ = pars_variable_declaration($1, $2); }
594 ;
595 
596 variable_declaration_list:
597 	/* Nothing */
598 	| variable_declaration
599 	| variable_declaration_list variable_declaration
600 ;
601 
602 cursor_declaration:
603 	PARS_DECLARE_TOKEN PARS_CURSOR_TOKEN PARS_ID_TOKEN
604 	PARS_IS_TOKEN select_statement ';'
605 				{ $$ = pars_cursor_declaration($3, $5); }
606 ;
607 
608 function_declaration:
609 	PARS_DECLARE_TOKEN PARS_FUNCTION_TOKEN PARS_ID_TOKEN ';'
610 				{ $$ = pars_function_declaration($3); }
611 ;
612 
613 declaration:
614 	cursor_declaration
615 	| function_declaration
616 ;
617 
618 declaration_list:
619 	/* Nothing */
620 	| declaration
621 	| declaration_list declaration
622 ;
623 
624 procedure_definition:
625 	PARS_PROCEDURE_TOKEN PARS_ID_TOKEN '(' parameter_declaration_list ')'
626 	PARS_IS_TOKEN
627 	variable_declaration_list
628 	declaration_list
629 	PARS_BEGIN_TOKEN
630 	statement_list
631 	PARS_END_TOKEN		{ $$ = pars_procedure_definition($2, $4,
632 								$10); }
633 ;
634 
635 %%
636