1 /*****************************************************************************
2 
3 Copyright (c) 1996, 2016, Oracle and/or its affiliates. All Rights Reserved.
4 Copyright (c) 2017, 2021, MariaDB Corporation.
5 
6 This program is free software; you can redistribute it and/or modify it under
7 the terms of the GNU General Public License as published by the Free Software
8 Foundation; version 2 of the License.
9 
10 This program is distributed in the hope that it will be useful, but WITHOUT
11 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
12 FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
13 
14 You should have received a copy of the GNU General Public License along with
15 this program; if not, write to the Free Software Foundation, Inc.,
16 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335 USA
17 
18 *****************************************************************************/
19 
20 /**************************************************//**
21 @file include/pars0pars.h
22 SQL parser
23 
24 Created 11/19/1996 Heikki Tuuri
25 *******************************************************/
26 
27 #ifndef pars0pars_h
28 #define pars0pars_h
29 
30 #include "que0types.h"
31 #include "pars0types.h"
32 #include "row0types.h"
33 #include "trx0types.h"
34 #include "ut0vec.h"
35 #include "row0mysql.h"
36 
37 /** Type of the user functions. The first argument is always InnoDB-supplied
38 and varies in type, while 'user_arg' is a user-supplied argument. The
39 meaning of the return type also varies. See the individual use cases, e.g.
40 the FETCH statement, for details on them. */
41 typedef ibool	(*pars_user_func_cb_t)(void* arg, void* user_arg);
42 
43 /** If the following is set TRUE, the parser will emit debugging
44 information */
45 extern int	yydebug;
46 
47 /* Global variable used while parsing a single procedure or query : the code is
48 NOT re-entrant */
49 extern sym_tab_t*	pars_sym_tab_global;
50 
51 extern pars_res_word_t	pars_to_binary_token;
52 extern pars_res_word_t	pars_substr_token;
53 extern pars_res_word_t	pars_concat_token;
54 extern pars_res_word_t	pars_length_token;
55 extern pars_res_word_t	pars_instr_token;
56 extern pars_res_word_t	pars_count_token;
57 extern pars_res_word_t	pars_int_token;
58 extern pars_res_word_t	pars_bigint_token;
59 extern pars_res_word_t	pars_char_token;
60 extern pars_res_word_t	pars_update_token;
61 extern pars_res_word_t	pars_asc_token;
62 extern pars_res_word_t	pars_desc_token;
63 extern pars_res_word_t	pars_open_token;
64 extern pars_res_word_t	pars_close_token;
65 extern pars_res_word_t	pars_share_token;
66 extern pars_res_word_t	pars_unique_token;
67 extern pars_res_word_t	pars_clustered_token;
68 
69 extern ulint		pars_star_denoter;
70 
71 /* Procedure parameter types */
72 #define PARS_INPUT	0
73 #define PARS_OUTPUT	1
74 #define PARS_NOT_PARAM	2
75 
76 int
77 yyparse(void);
78 
79 /*************************************************************//**
80 Parses an SQL string returning the query graph.
81 @return own: the query graph */
82 que_t*
83 pars_sql(
84 /*=====*/
85 	pars_info_t*	info,	/*!< in: extra information, or NULL */
86 	const char*	str);	/*!< in: SQL string */
87 /*************************************************************//**
88 Retrieves characters to the lexical analyzer.
89 @return number of characters copied or 0 on EOF */
90 size_t
91 pars_get_lex_chars(
92 /*===============*/
93 	char*	buf,		/*!< in/out: buffer where to copy */
94 	size_t	max_size);	/*!< in: maximum number of characters which fit
95 				in the buffer */
96 /*************************************************************//**
97 Called by yyparse on error. */
98 void
99 yyerror(
100 /*====*/
101 	const char*	s);	/*!< in: error message string */
102 /*********************************************************************//**
103 Parses a variable declaration.
104 @return own: symbol table node of type SYM_VAR */
page_zip_get_size(const page_zip_des_t * page_zip)105 sym_node_t*
106 pars_variable_declaration(
107 /*======================*/
108 	sym_node_t*	node,	/*!< in: symbol table node allocated for the
109 				id of the variable */
110 	pars_res_word_t* type);	/*!< in: pointer to a type token */
111 /*********************************************************************//**
112 Parses a function expression.
113 @return own: function node in a query tree */
114 func_node_t*
115 pars_func(
116 /*======*/
117 	que_node_t*	res_word,/*!< in: function name reserved word */
118 	que_node_t*	arg);	/*!< in: first argument in the argument list */
119 /*************************************************************************
120 Rebind a LIKE search string. NOTE: We ignore any '%' characters embedded
121 within the search string.
122 @return own: function node in a query tree */
123 int
124 pars_like_rebind(
125 /*=============*/
page_zip_set_size(page_zip_des_t * page_zip,ulint size)126         sym_node_t*     node,   /* in: The search string node.*/
127         const byte*     ptr,    /* in: literal to (re) bind */
128         ulint           len);   /* in: length of literal to (re) bind*/
129 /*********************************************************************//**
130 Parses an operator expression.
131 @return own: function node in a query tree */
132 func_node_t*
133 pars_op(
134 /*====*/
135 	int		func,	/*!< in: operator token code */
136 	que_node_t*	arg1,	/*!< in: first argument */
137 	que_node_t*	arg2);	/*!< in: second argument or NULL for an unary
138 				operator */
139 /*********************************************************************//**
140 Parses an ORDER BY clause. Order by a single column only is supported.
141 @return own: order-by node in a query tree */
142 order_node_t*
143 pars_order_by(
144 /*==========*/
145 	sym_node_t*	column,	/*!< in: column name */
146 	pars_res_word_t* asc);	/*!< in: &pars_asc_token or pars_desc_token */
147 /*********************************************************************//**
148 Parses a select list; creates a query graph node for the whole SELECT
149 statement.
150 @return own: select node in a query tree */
151 sel_node_t*
152 pars_select_list(
153 /*=============*/
page_zip_rec_needs_ext(ulint rec_size,ulint comp,ulint n_fields,ulint zip_size)154 	que_node_t*	select_list,	/*!< in: select list */
155 	sym_node_t*	into_list);	/*!< in: variables list or NULL */
156 /*********************************************************************//**
157 Parses a cursor declaration.
158 @return sym_node */
159 que_node_t*
160 pars_cursor_declaration(
161 /*====================*/
162 	sym_node_t*	sym_node,	/*!< in: cursor id node in the symbol
163 					table */
164 	sel_node_t*	select_node);	/*!< in: select node */
165 /*********************************************************************//**
166 Parses a function declaration.
167 @return sym_node */
168 que_node_t*
169 pars_function_declaration(
170 /*======================*/
171 	sym_node_t*	sym_node);	/*!< in: function id node in the symbol
172 					table */
173 /*********************************************************************//**
174 Parses a select statement.
175 @return own: select node in a query tree */
176 sel_node_t*
177 pars_select_statement(
178 /*==================*/
179 	sel_node_t*	select_node,	/*!< in: select node already containing
180 					the select list */
181 	sym_node_t*	table_list,	/*!< in: table list */
182 	que_node_t*	search_cond,	/*!< in: search condition or NULL */
183 	pars_res_word_t* for_update,	/*!< in: NULL or &pars_update_token */
184 	pars_res_word_t* consistent_read,/*!< in: NULL or
185 						&pars_consistent_token */
186 	order_node_t*	order_by);	/*!< in: NULL or an order-by node */
187 /*********************************************************************//**
188 Parses a column assignment in an update.
189 @return column assignment node */
190 col_assign_node_t*
191 pars_column_assignment(
192 /*===================*/
page_zip_simple_validate(const page_zip_des_t * page_zip)193 	sym_node_t*	column,	/*!< in: column to assign */
194 	que_node_t*	exp);	/*!< in: value to assign */
195 /*********************************************************************//**
196 Parses a delete or update statement start.
197 @return own: update node in a query tree */
198 upd_node_t*
199 pars_update_statement_start(
200 /*========================*/
201 	ibool		is_delete,	/*!< in: TRUE if delete */
202 	sym_node_t*	table_sym,	/*!< in: table name node */
203 	col_assign_node_t* col_assign_list);/*!< in: column assignment list, NULL
204 					if delete */
205 /*********************************************************************//**
206 Parses an update or delete statement.
207 @return own: update node in a query tree */
208 upd_node_t*
209 pars_update_statement(
210 /*==================*/
211 	upd_node_t*	node,		/*!< in: update node */
212 	sym_node_t*	cursor_sym,	/*!< in: pointer to a cursor entry in
213 					the symbol table or NULL */
214 	que_node_t*	search_cond);	/*!< in: search condition or NULL */
215 /*********************************************************************//**
page_zip_get_trailer_len(const page_zip_des_t * page_zip,ibool is_clust)216 Parses an insert statement.
217 @return own: update node in a query tree */
218 ins_node_t*
219 pars_insert_statement(
220 /*==================*/
221 	sym_node_t*	table_sym,	/*!< in: table name node */
222 	que_node_t*	values_list,	/*!< in: value expression list or NULL */
223 	sel_node_t*	select);	/*!< in: select condition or NULL */
224 /*********************************************************************//**
225 Parses an elsif element.
226 @return elsif node */
227 elsif_node_t*
228 pars_elsif_element(
229 /*===============*/
230 	que_node_t*	cond,		/*!< in: if-condition */
231 	que_node_t*	stat_list);	/*!< in: statement list */
232 /*********************************************************************//**
233 Parses an if-statement.
234 @return if-statement node */
235 if_node_t*
236 pars_if_statement(
237 /*==============*/
238 	que_node_t*	cond,		/*!< in: if-condition */
239 	que_node_t*	stat_list,	/*!< in: statement list */
240 	que_node_t*	else_part);	/*!< in: else-part statement list */
241 /*********************************************************************//**
242 Parses a for-loop-statement.
243 @return for-statement node */
244 for_node_t*
245 pars_for_statement(
246 /*===============*/
247 	sym_node_t*	loop_var,	/*!< in: loop variable */
248 	que_node_t*	loop_start_limit,/*!< in: loop start expression */
page_zip_max_ins_size(const page_zip_des_t * page_zip,ibool is_clust)249 	que_node_t*	loop_end_limit,	/*!< in: loop end expression */
250 	que_node_t*	stat_list);	/*!< in: statement list */
251 /*********************************************************************//**
252 Parses a while-statement.
253 @return while-statement node */
254 while_node_t*
255 pars_while_statement(
256 /*=================*/
257 	que_node_t*	cond,		/*!< in: while-condition */
258 	que_node_t*	stat_list);	/*!< in: statement list */
259 /*********************************************************************//**
260 Parses an exit statement.
261 @return exit statement node */
262 exit_node_t*
263 pars_exit_statement(void);
264 /*=====================*/
265 /*********************************************************************//**
266 Parses a return-statement.
267 @return return-statement node */
268 return_node_t*
269 pars_return_statement(void);
270 /*=======================*/
271 /*********************************************************************//**
272 Parses a procedure call.
273 @return function node */
274 func_node_t*
275 pars_procedure_call(
276 /*================*/
page_zip_available(const page_zip_des_t * page_zip,ibool is_clust,ulint length,ulint create)277 	que_node_t*	res_word,/*!< in: procedure name reserved word */
278 	que_node_t*	args);	/*!< in: argument list */
279 /*********************************************************************//**
280 Parses an assignment statement.
281 @return assignment statement node */
282 assign_node_t*
283 pars_assignment_statement(
284 /*======================*/
285 	sym_node_t*	var,	/*!< in: variable to assign */
286 	que_node_t*	val);	/*!< in: value to assign */
287 /*********************************************************************//**
288 Parses a fetch statement. into_list or user_func (but not both) must be
289 non-NULL.
290 @return fetch statement node */
291 fetch_node_t*
292 pars_fetch_statement(
293 /*=================*/
294 	sym_node_t*	cursor,		/*!< in: cursor node */
295 	sym_node_t*	into_list,	/*!< in: variables to set, or NULL */
296 	sym_node_t*	user_func);	/*!< in: user function name, or NULL */
297 /*********************************************************************//**
298 Parses an open or close cursor statement.
299 @return fetch statement node */
300 open_node_t*
301 pars_open_statement(
302 /*================*/
303 	ulint		type,	/*!< in: ROW_SEL_OPEN_CURSOR
304 				or ROW_SEL_CLOSE_CURSOR */
305 	sym_node_t*	cursor);	/*!< in: cursor node */
306 /*********************************************************************//**
307 Parses a row_printf-statement.
308 @return row_printf-statement node */
309 row_printf_node_t*
310 pars_row_printf_statement(
311 /*======================*/
312 	sel_node_t*	sel_node);	/*!< in: select node */
313 /*********************************************************************//**
page_zip_des_init(page_zip_des_t * page_zip)314 Parses a commit statement.
315 @return own: commit node struct */
316 commit_node_t*
317 pars_commit_statement(void);
318 /*=======================*/
319 /*********************************************************************//**
320 Parses a rollback statement.
321 @return own: rollback node struct */
322 roll_node_t*
323 pars_rollback_statement(void);
324 /*=========================*/
325 /*********************************************************************//**
326 Parses a column definition at a table creation.
327 @return column sym table node */
328 sym_node_t*
329 pars_column_def(
330 /*============*/
331 	sym_node_t*		sym_node,	/*!< in: column node in the
332 						symbol table */
333 	pars_res_word_t*	type,		/*!< in: data type */
334 	sym_node_t*		len,		/*!< in: length of column, or
335 						NULL */
336 	void*			is_not_null);	/*!< in: if not NULL, column
337 						is of type NOT NULL. */
338 /*********************************************************************//**
page_zip_write_header(page_zip_des_t * page_zip,const byte * str,ulint length,mtr_t * mtr)339 Parses a table creation operation.
340 @return table create subgraph */
341 tab_node_t*
342 pars_create_table(
343 /*==============*/
344 	sym_node_t*	table_sym,	/*!< in: table name node in the symbol
345 					table */
346 	sym_node_t*	column_defs);	/*!< in: list of column names */
347 /*********************************************************************//**
348 Parses an index creation operation.
349 @return index create subgraph */
350 ind_node_t*
351 pars_create_index(
352 /*==============*/
353 	pars_res_word_t* unique_def,	/*!< in: not NULL if a unique index */
354 	pars_res_word_t* clustered_def,	/*!< in: not NULL if a clustered index */
355 	sym_node_t*	index_sym,	/*!< in: index name node in the symbol
356 					table */
357 	sym_node_t*	table_sym,	/*!< in: table name node in the symbol
358 					table */
359 	sym_node_t*	column_list);	/*!< in: list of column names */
360 /*********************************************************************//**
361 Parses a procedure definition.
362 @return query fork node */
363 que_fork_t*
364 pars_procedure_definition(
365 /*======================*/
366 	sym_node_t*	sym_node,	/*!< in: procedure id node in the symbol
367 					table */
368 	que_node_t*	stat_list);	/*!< in: statement list */
page_zip_compress_write_log_no_data(ulint level,const page_t * page,dict_index_t * index,mtr_t * mtr)369 
370 /*************************************************************//**
371 Parses a stored procedure call, when this is not within another stored
372 procedure, that is, the client issues a procedure call directly.
373 In MySQL/InnoDB, stored InnoDB procedures are invoked via the
374 parsed procedure tree, not via InnoDB SQL, so this function is not used.
375 @return query graph */
376 que_fork_t*
377 pars_stored_procedure_call(
378 /*=======================*/
379 	sym_node_t*	sym_node);	/*!< in: stored procedure name */
380 /** Completes a query graph by adding query thread and fork nodes
381 above it and prepares the graph for running. The fork created is of
382 type QUE_FORK_MYSQL_INTERFACE.
383 @param[in]	node		root node for an incomplete query
384 				graph, or NULL for dummy graph
385 @param[in]	trx		transaction handle
386 @param[in]	heap		memory heap from which allocated
387 @param[in]	prebuilt	row prebuilt structure
388 @return query thread node to run */
389 que_thr_t*
page_zip_parse_compress_no_data(byte * ptr,byte * end_ptr,page_t * page,page_zip_des_t * page_zip,dict_index_t * index)390 pars_complete_graph_for_exec(
391 	que_node_t*	node,
392 	trx_t*		trx,
393 	mem_heap_t*	heap,
394 	row_prebuilt_t*	prebuilt)
395 	MY_ATTRIBUTE((nonnull(2,3), warn_unused_result));
396 
397 /****************************************************************//**
398 Create parser info struct.
399 @return own: info struct */
400 pars_info_t*
401 pars_info_create(void);
402 /*==================*/
403 
404 /****************************************************************//**
405 Free info struct and everything it contains. */
406 void
407 pars_info_free(
408 /*===========*/
409 	pars_info_t*	info);	/*!< in, own: info struct */
410 
411 /****************************************************************//**
412 Add bound literal. */
413 void
414 pars_info_add_literal(
415 /*==================*/
416 	pars_info_t*	info,		/*!< in: info struct */
417 	const char*	name,		/*!< in: name */
418 	const void*	address,	/*!< in: address */
419 	ulint		length,		/*!< in: length of data */
420 	ulint		type,		/*!< in: type, e.g. DATA_FIXBINARY */
421 	ulint		prtype);	/*!< in: precise type, e.g.
page_zip_reset_stat_per_index()422 					DATA_UNSIGNED */
423 
424 /****************************************************************//**
425 Equivalent to pars_info_add_literal(info, name, str, strlen(str),
426 DATA_VARCHAR, DATA_ENGLISH). */
427 void
428 pars_info_add_str_literal(
429 /*======================*/
430 	pars_info_t*	info,		/*!< in: info struct */
431 	const char*	name,		/*!< in: name */
432 	const char*	str);		/*!< in: string */
433 /********************************************************************
434 If the literal value already exists then it rebinds otherwise it
435 creates a new entry.*/
436 void
437 pars_info_bind_literal(
438 /*===================*/
439 	pars_info_t*	info,		/* in: info struct */
440 	const char*	name,		/* in: name */
441 	const void*	address,	/* in: address */
442 	ulint		length,		/* in: length of data */
443 	ulint		type,		/* in: type, e.g. DATA_FIXBINARY */
444 	ulint		prtype);	/* in: precise type, e.g. */
445 /********************************************************************
446 If the literal value already exists then it rebinds otherwise it
447 creates a new entry.*/
448 void
449 pars_info_bind_varchar_literal(
450 /*===========================*/
451 	pars_info_t*	info,		/*!< in: info struct */
452 	const char*	name,		/*!< in: name */
453 	const byte*	str,		/*!< in: string */
454 	ulint		str_len);	/*!< in: string length */
455 /****************************************************************//**
456 Equivalent to:
457 
458 char buf[4];
459 mach_write_to_4(buf, val);
460 pars_info_add_literal(info, name, buf, 4, DATA_INT, 0);
461 
462 except that the buffer is dynamically allocated from the info struct's
463 heap. */
464 void
465 pars_info_bind_int4_literal(
466 /*=======================*/
467 	pars_info_t*		info,		/*!< in: info struct */
468 	const char*		name,		/*!< in: name */
469 	const ib_uint32_t*	val);		/*!< in: value */
470 /********************************************************************
471 If the literal value already exists then it rebinds otherwise it
472 creates a new entry. */
473 void
474 pars_info_bind_int8_literal(
475 /*=======================*/
476 	pars_info_t*		info,		/*!< in: info struct */
477 	const char*		name,		/*!< in: name */
478 	const ib_uint64_t*	val);		/*!< in: value */
479 /****************************************************************//**
480 Add user function. */
481 void
482 pars_info_bind_function(
483 /*===================*/
484 	pars_info_t*		info,	/*!< in: info struct */
485 	const char*		name,	/*!< in: function name */
486 	pars_user_func_cb_t	func,	/*!< in: function address */
487 	void*			arg);	/*!< in: user-supplied argument */
488 /****************************************************************//**
489 Add bound id. */
490 void
491 pars_info_bind_id(
492 /*=============*/
493 	pars_info_t*		info,	/*!< in: info struct */
494 	const char*		name,	/*!< in: name */
495 	const char*		id);	/*!< in: id */
496 /****************************************************************//**
497 Equivalent to:
498 
499 char buf[4];
500 mach_write_to_4(buf, val);
501 pars_info_add_literal(info, name, buf, 4, DATA_INT, 0);
502 
503 except that the buffer is dynamically allocated from the info struct's
504 heap. */
505 void
506 pars_info_add_int4_literal(
507 /*=======================*/
508 	pars_info_t*	info,		/*!< in: info struct */
509 	const char*	name,		/*!< in: name */
510 	ulint		val);		/*!< in: value */
511 
512 /****************************************************************//**
513 Equivalent to:
514 
515 char buf[8];
516 mach_write_to_8(buf, val);
517 pars_info_add_literal(info, name, buf, 8, DATA_FIXBINARY, 0);
518 
519 except that the buffer is dynamically allocated from the info struct's
520 heap. */
521 void
522 pars_info_add_ull_literal(
523 /*======================*/
524 	pars_info_t*	info,		/*!< in: info struct */
525 	const char*	name,		/*!< in: name */
526 	ib_uint64_t	val);		/*!< in: value */
527 
528 /****************************************************************//**
529 If the literal value already exists then it rebinds otherwise it
530 creates a new entry. */
531 void
532 pars_info_bind_ull_literal(
533 /*=======================*/
534 	pars_info_t*		info,	/*!< in: info struct */
535 	const char*		name,	/*!< in: name */
536 	const ib_uint64_t*	val)	/*!< in: value */
537 	MY_ATTRIBUTE((nonnull));
538 
539 /****************************************************************//**
540 Get bound literal with the given name.
541 @return bound literal, or NULL if not found */
542 pars_bound_lit_t*
543 pars_info_get_bound_lit(
544 /*====================*/
545 	pars_info_t*		info,	/*!< in: info struct */
546 	const char*		name);	/*!< in: bound literal name to find */
547 
548 /****************************************************************//**
549 Get bound id with the given name.
550 @return bound id, or NULL if not found */
551 pars_bound_id_t*
552 pars_info_get_bound_id(
553 /*===================*/
554 	pars_info_t*		info,	/*!< in: info struct */
555 	const char*		name);	/*!< in: bound id name to find */
556 
557 /******************************************************************//**
558 Release any resources used by the lexer. */
559 void
560 pars_lexer_close(void);
561 /*==================*/
562 
563 /** Extra information supplied for pars_sql(). */
564 struct pars_info_t {
565 	mem_heap_t*	heap;		/*!< our own memory heap */
566 
567 	ib_vector_t*	funcs;		/*!< user functions, or NUll
568 					(pars_user_func_t*) */
569 	ib_vector_t*	bound_lits;	/*!< bound literals, or NULL
570 					(pars_bound_lit_t*) */
571 	ib_vector_t*	bound_ids;	/*!< bound ids, or NULL
572 					(pars_bound_id_t*) */
573 
574 	ibool		graph_owns_us;	/*!< if TRUE (which is the default),
575 					que_graph_free() will free us */
576 };
577 
578 /** User-supplied function and argument. */
579 struct pars_user_func_t {
580 	const char*		name;	/*!< function name */
581 	pars_user_func_cb_t	func;	/*!< function address */
582 	void*			arg;	/*!< user-supplied argument */
583 };
584 
585 /** Bound literal. */
586 struct pars_bound_lit_t {
587 	const char*	name;		/*!< name */
588 	const void*	address;	/*!< address */
589 	ulint		length;		/*!< length of data */
590 	ulint		type;		/*!< type, e.g. DATA_FIXBINARY */
591 	ulint		prtype;		/*!< precise type, e.g. DATA_UNSIGNED */
592 	sym_node_t*	node;		/*!< symbol node */
593 };
594 
595 /** Bound identifier. */
596 struct pars_bound_id_t {
597 	const char*	name;		/*!< name */
598 	const char*	id;		/*!< identifier */
599 };
600 
601 /** Struct used to denote a reserved word in a parsing tree */
602 struct pars_res_word_t{
603 	int	code;	/*!< the token code for the reserved word from
604 			pars0grm.h */
605 };
606 
607 /** A predefined function or operator node in a parsing tree; this construct
608 is also used for some non-functions like the assignment ':=' */
609 struct func_node_t{
610 	que_common_t	common;	/*!< type: QUE_NODE_FUNC */
611 	int		func;	/*!< token code of the function name */
612 	ulint		fclass;	/*!< class of the function */
613 	que_node_t*	args;	/*!< argument(s) of the function */
614 	UT_LIST_NODE_T(func_node_t) cond_list;
615 				/*!< list of comparison conditions; defined
616 				only for comparison operator nodes except,
617 				presently, for OPT_SCROLL_TYPE ones */
618 	UT_LIST_NODE_T(func_node_t) func_node_list;
619 				/*!< list of function nodes in a parsed
620 				query graph */
621 };
622 
623 /** An order-by node in a select */
624 struct order_node_t{
625 	que_common_t	common;	/*!< type: QUE_NODE_ORDER */
626 	sym_node_t*	column;	/*!< order-by column */
627 	ibool		asc;	/*!< TRUE if ascending, FALSE if descending */
628 };
629 
630 /** Procedure definition node */
631 struct proc_node_t{
632 	que_common_t	common;		/*!< type: QUE_NODE_PROC */
633 	sym_node_t*	proc_id;	/*!< procedure name symbol in the symbol
634 					table of this same procedure */
635 	que_node_t*	stat_list;	/*!< statement list */
636 	sym_tab_t*	sym_tab;	/*!< symbol table of this procedure */
637 };
638 
639 /** elsif-element node */
640 struct elsif_node_t{
641 	que_common_t	common;		/*!< type: QUE_NODE_ELSIF */
642 	que_node_t*	cond;		/*!< if condition */
643 	que_node_t*	stat_list;	/*!< statement list */
644 };
645 
646 /** if-statement node */
647 struct if_node_t{
648 	que_common_t	common;		/*!< type: QUE_NODE_IF */
649 	que_node_t*	cond;		/*!< if condition */
650 	que_node_t*	stat_list;	/*!< statement list */
651 	que_node_t*	else_part;	/*!< else-part statement list */
652 	elsif_node_t*	elsif_list;	/*!< elsif element list */
653 };
654 
655 /** while-statement node */
656 struct while_node_t{
657 	que_common_t	common;		/*!< type: QUE_NODE_WHILE */
658 	que_node_t*	cond;		/*!< while condition */
659 	que_node_t*	stat_list;	/*!< statement list */
660 };
661 
662 /** for-loop-statement node */
663 struct for_node_t{
664 	que_common_t	common;		/*!< type: QUE_NODE_FOR */
665 	sym_node_t*	loop_var;	/*!< loop variable: this is the
666 					dereferenced symbol from the
667 					variable declarations, not the
668 					symbol occurrence in the for loop
669 					definition */
670 	que_node_t*	loop_start_limit;/*!< initial value of loop variable */
671 	que_node_t*	loop_end_limit;	/*!< end value of loop variable */
672 	lint		loop_end_value;	/*!< evaluated value for the end value:
673 					it is calculated only when the loop
674 					is entered, and will not change within
675 					the loop */
676 	que_node_t*	stat_list;	/*!< statement list */
677 };
678 
679 /** exit statement node */
680 struct exit_node_t{
681 	que_common_t	common;		/*!< type: QUE_NODE_EXIT */
682 };
683 
684 /** return-statement node */
685 struct return_node_t{
686 	que_common_t	common;		/*!< type: QUE_NODE_RETURN */
687 };
688 
689 /** Assignment statement node */
690 struct assign_node_t{
691 	que_common_t	common;		/*!< type: QUE_NODE_ASSIGNMENT */
692 	sym_node_t*	var;		/*!< variable to set */
693 	que_node_t*	val;		/*!< value to assign */
694 };
695 
696 /** Column assignment node */
697 struct col_assign_node_t{
698 	que_common_t	common;		/*!< type: QUE_NODE_COL_ASSIGN */
699 	sym_node_t*	col;		/*!< column to set */
700 	que_node_t*	val;		/*!< value to assign */
701 };
702 
703 /** Classes of functions */
704 /* @{ */
705 #define PARS_FUNC_ARITH		1	/*!< +, -, *, / */
706 #define	PARS_FUNC_LOGICAL	2	/*!< AND, OR, NOT */
707 #define PARS_FUNC_CMP		3	/*!< comparison operators */
708 #define	PARS_FUNC_PREDEFINED	4	/*!< TO_NUMBER, SUBSTR, ... */
709 #define	PARS_FUNC_AGGREGATE	5	/*!< COUNT */
710 #define	PARS_FUNC_OTHER		6	/*!< these are not real functions,
711 					e.g., := */
712 /* @} */
713 
714 #endif
715