1 /*****************************************************************************
2 
3 Copyright (c) 1996, 2021, Oracle and/or its affiliates.
4 
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License, version 2.0,
7 as published by the Free Software Foundation.
8 
9 This program is also distributed with certain software (including
10 but not limited to OpenSSL) that is licensed under separate terms,
11 as designated in a particular file or component or in included license
12 documentation.  The authors of MySQL hereby grant you an additional
13 permission to link the program and your derivative works with the
14 separately licensed software that they have included with MySQL.
15 
16 This program is distributed in the hope that it will be useful,
17 but WITHOUT ANY WARRANTY; without even the implied warranty of
18 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19 GNU General Public License, version 2.0, for more details.
20 
21 You should have received a copy of the GNU General Public License along with
22 this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St,
23 Fifth Floor, Boston, MA 02110-1301 USA
24 
25 *****************************************************************************/
26 
27 /**************************************************//**
28 @file pars/pars0pars.c
29 SQL parser
30 
31 Created 11/19/1996 Heikki Tuuri
32 *******************************************************/
33 
34 /* Historical note: Innobase executed its first SQL string (CREATE TABLE)
35 on 1/27/1998 */
36 
37 #include "ha_prototypes.h"
38 
39 #include "pars0pars.h"
40 
41 #ifdef UNIV_NONINL
42 #include "pars0pars.ic"
43 #endif
44 
45 #include "row0sel.h"
46 #include "row0ins.h"
47 #include "row0upd.h"
48 #include "dict0dict.h"
49 #include "dict0mem.h"
50 #include "dict0crea.h"
51 #include "que0que.h"
52 #include "pars0grm.h"
53 #include "pars0opt.h"
54 #include "data0data.h"
55 #include "data0type.h"
56 #include "trx0trx.h"
57 #include "trx0roll.h"
58 #include "lock0lock.h"
59 #include "eval0eval.h"
60 
61 /* Global variable used while parsing a single procedure or query : the code is
62 NOT re-entrant */
63 sym_tab_t*	pars_sym_tab_global;
64 
65 /* Global variables used to denote certain reserved words, used in
66 constructing the parsing tree */
67 
68 pars_res_word_t	pars_to_char_token = {PARS_TO_CHAR_TOKEN};
69 pars_res_word_t	pars_to_number_token = {PARS_TO_NUMBER_TOKEN};
70 pars_res_word_t	pars_to_binary_token = {PARS_TO_BINARY_TOKEN};
71 pars_res_word_t	pars_binary_to_number_token = {PARS_BINARY_TO_NUMBER_TOKEN};
72 pars_res_word_t	pars_substr_token = {PARS_SUBSTR_TOKEN};
73 pars_res_word_t	pars_replstr_token = {PARS_REPLSTR_TOKEN};
74 pars_res_word_t	pars_concat_token = {PARS_CONCAT_TOKEN};
75 pars_res_word_t	pars_instr_token = {PARS_INSTR_TOKEN};
76 pars_res_word_t	pars_length_token = {PARS_LENGTH_TOKEN};
77 pars_res_word_t	pars_sysdate_token = {PARS_SYSDATE_TOKEN};
78 pars_res_word_t	pars_printf_token = {PARS_PRINTF_TOKEN};
79 pars_res_word_t	pars_assert_token = {PARS_ASSERT_TOKEN};
80 pars_res_word_t	pars_rnd_token = {PARS_RND_TOKEN};
81 pars_res_word_t	pars_rnd_str_token = {PARS_RND_STR_TOKEN};
82 pars_res_word_t	pars_count_token = {PARS_COUNT_TOKEN};
83 pars_res_word_t	pars_sum_token = {PARS_SUM_TOKEN};
84 pars_res_word_t	pars_distinct_token = {PARS_DISTINCT_TOKEN};
85 pars_res_word_t	pars_binary_token = {PARS_BINARY_TOKEN};
86 pars_res_word_t	pars_blob_token = {PARS_BLOB_TOKEN};
87 pars_res_word_t	pars_int_token = {PARS_INT_TOKEN};
88 pars_res_word_t	pars_bigint_token = {PARS_BIGINT_TOKEN};
89 pars_res_word_t	pars_char_token = {PARS_CHAR_TOKEN};
90 pars_res_word_t	pars_float_token = {PARS_FLOAT_TOKEN};
91 pars_res_word_t	pars_update_token = {PARS_UPDATE_TOKEN};
92 pars_res_word_t	pars_asc_token = {PARS_ASC_TOKEN};
93 pars_res_word_t	pars_desc_token = {PARS_DESC_TOKEN};
94 pars_res_word_t	pars_open_token = {PARS_OPEN_TOKEN};
95 pars_res_word_t	pars_close_token = {PARS_CLOSE_TOKEN};
96 pars_res_word_t	pars_share_token = {PARS_SHARE_TOKEN};
97 pars_res_word_t	pars_unique_token = {PARS_UNIQUE_TOKEN};
98 pars_res_word_t	pars_clustered_token = {PARS_CLUSTERED_TOKEN};
99 
100 /** Global variable used to denote the '*' in SELECT * FROM.. */
101 ulint	pars_star_denoter	= 12345678;
102 
103 /********************************************************************
104 Get user function with the given name.*/
105 UNIV_INLINE
106 pars_user_func_t*
pars_info_lookup_user_func(pars_info_t * info,const char * name)107 pars_info_lookup_user_func(
108 /*=======================*/
109 					/* out: user func, or NULL if not
110 					found */
111 	pars_info_t*		info,	/* in: info struct */
112 	const char*		name)	/* in: function name to find*/
113 {
114 	if (info && info->funcs) {
115 		ulint		i;
116 		ib_vector_t*	vec = info->funcs;
117 
118 		for (i = 0; i < ib_vector_size(vec); i++) {
119 			pars_user_func_t*	puf;
120 
121 			puf = static_cast<pars_user_func_t*>(
122 				ib_vector_get(vec, i));
123 
124 			if (strcmp(puf->name, name) == 0) {
125 				return(puf);
126 			}
127 		}
128 	}
129 
130 	return(NULL);
131 }
132 
133 /********************************************************************
134 Get bound identifier with the given name.*/
135 UNIV_INLINE
136 pars_bound_id_t*
pars_info_lookup_bound_id(pars_info_t * info,const char * name)137 pars_info_lookup_bound_id(
138 /*======================*/
139 					/* out: bound literal, or NULL if
140 					not found */
141 	pars_info_t*		info,	/* in: info struct */
142 	const char*		name)	/* in: bound literal name to find */
143 {
144 	if (info && info->bound_ids) {
145 		ulint		i;
146 		ib_vector_t*	vec = info->bound_ids;
147 
148 		for (i = 0; i < ib_vector_size(vec); i++) {
149 			pars_bound_id_t*	bid;
150 
151 		       	bid = static_cast<pars_bound_id_t*>(
152 				ib_vector_get(vec, i));
153 
154 			if (strcmp(bid->name, name) == 0) {
155 				return(bid);
156 			}
157 		}
158 	}
159 
160 	return(NULL);
161 }
162 
163 /********************************************************************
164 Get bound literal with the given name.*/
165 UNIV_INLINE
166 pars_bound_lit_t*
pars_info_lookup_bound_lit(pars_info_t * info,const char * name)167 pars_info_lookup_bound_lit(
168 /*=======================*/
169 					/* out: bound literal, or NULL if
170 					not found */
171 	pars_info_t*		info,	/* in: info struct */
172 	const char*		name)	/* in: bound literal name to find */
173 {
174 	if (info && info->bound_lits) {
175 		ulint		i;
176 		ib_vector_t*	vec = info->bound_lits;
177 
178 		for (i = 0; i < ib_vector_size(vec); i++) {
179 			pars_bound_lit_t*	pbl;
180 
181 			pbl = static_cast<pars_bound_lit_t*>(
182 				ib_vector_get(vec, i));
183 
184 			if (strcmp(pbl->name, name) == 0) {
185 				return(pbl);
186 			}
187 		}
188 	}
189 
190 	return(NULL);
191 }
192 
193 /*********************************************************************//**
194 Determines the class of a function code.
195 @return function class: PARS_FUNC_ARITH, ... */
196 static
197 ulint
pars_func_get_class(int func)198 pars_func_get_class(
199 /*================*/
200 	int	func)	/*!< in: function code: '=', PARS_GE_TOKEN, ... */
201 {
202 	switch (func) {
203 	case '+': case '-': case '*': case '/':
204 		return(PARS_FUNC_ARITH);
205 
206 	case '=': case '<': case '>':
207 	case PARS_GE_TOKEN: case PARS_LE_TOKEN: case PARS_NE_TOKEN:
208 		return(PARS_FUNC_CMP);
209 
210 	case PARS_AND_TOKEN: case PARS_OR_TOKEN: case PARS_NOT_TOKEN:
211 		return(PARS_FUNC_LOGICAL);
212 
213 	case PARS_COUNT_TOKEN: case PARS_SUM_TOKEN:
214 		return(PARS_FUNC_AGGREGATE);
215 
216 	case PARS_TO_CHAR_TOKEN:
217 	case PARS_TO_NUMBER_TOKEN:
218 	case PARS_TO_BINARY_TOKEN:
219 	case PARS_BINARY_TO_NUMBER_TOKEN:
220 	case PARS_SUBSTR_TOKEN:
221 	case PARS_CONCAT_TOKEN:
222 	case PARS_LENGTH_TOKEN:
223 	case PARS_INSTR_TOKEN:
224 	case PARS_SYSDATE_TOKEN:
225 	case PARS_NOTFOUND_TOKEN:
226 	case PARS_PRINTF_TOKEN:
227 	case PARS_ASSERT_TOKEN:
228 	case PARS_RND_TOKEN:
229 	case PARS_RND_STR_TOKEN:
230 	case PARS_REPLSTR_TOKEN:
231 		return(PARS_FUNC_PREDEFINED);
232 
233 	default:
234 		return(PARS_FUNC_OTHER);
235 	}
236 }
237 
238 /*********************************************************************//**
239 Parses an operator or predefined function expression.
240 @return own: function node in a query tree */
241 static
242 func_node_t*
pars_func_low(int func,que_node_t * arg)243 pars_func_low(
244 /*==========*/
245 	int		func,	/*!< in: function token code */
246 	que_node_t*	arg)	/*!< in: first argument in the argument list */
247 {
248 	func_node_t*	node;
249 
250 	node = static_cast<func_node_t*>(
251 		mem_heap_alloc(pars_sym_tab_global->heap, sizeof(func_node_t)));
252 
253 	node->common.type = QUE_NODE_FUNC;
254 	dfield_set_data(&(node->common.val), NULL, 0);
255 	node->common.val_buf_size = 0;
256 
257 	node->func = func;
258 
259 	node->fclass = pars_func_get_class(func);
260 
261 	node->args = arg;
262 
263 	UT_LIST_ADD_LAST(pars_sym_tab_global->func_node_list, node);
264 
265 	return(node);
266 }
267 
268 /*********************************************************************//**
269 Parses a function expression.
270 @return own: function node in a query tree */
271 func_node_t*
pars_func(que_node_t * res_word,que_node_t * arg)272 pars_func(
273 /*======*/
274 	que_node_t*	res_word,/*!< in: function name reserved word */
275 	que_node_t*	arg)	/*!< in: first argument in the argument list */
276 {
277 	return(pars_func_low(((pars_res_word_t*) res_word)->code, arg));
278 }
279 
280 /*************************************************************************
281 Rebind a LIKE search string. NOTE: We ignore any '%' characters embedded
282 within the search string.*/
283 int
pars_like_rebind(sym_node_t * node,const byte * ptr,ulint ptr_len)284 pars_like_rebind(
285 /*=============*/
286 				/* out, own: function node in a query tree */
287 	sym_node_t*	node,	/* in: The search string node.*/
288 	const byte*	ptr,	/* in: literal to (re) bind */
289 	ulint		ptr_len)/* in: length of literal to (re) bind*/
290 {
291 	dtype_t*	dtype;
292 	dfield_t*	dfield;
293 	ib_like_t	op_check;
294 	sym_node_t*	like_node;
295 	sym_node_t*	str_node = NULL;
296 	ib_like_t	op = IB_LIKE_EXACT;
297 	int		func = PARS_LIKE_TOKEN_EXACT;
298 
299 	/* Is this a STRING% ? */
300 	if (ptr[ptr_len - 1] == '%') {
301 		op = IB_LIKE_PREFIX;
302 	}
303 
304 	/* Is this a '%STRING' or %STRING% ?*/
305 	ut_ad(*ptr != '%');
306 
307 	if (node->like_node == NULL) {
308 		/* Add the LIKE operator info node to the node list.
309 		This will be used during the comparison phase to determine
310 		how to match.*/
311 		like_node = sym_tab_add_int_lit(node->sym_table, op);
312 		que_node_list_add_last(NULL, like_node);
313 		node->like_node = like_node;
314 		str_node = sym_tab_add_str_lit(node->sym_table, ptr, ptr_len);
315 		que_node_list_add_last(like_node, str_node);
316 	} else {
317 		like_node = node->like_node;
318 
319 		/* Change the value of the string in the existing
320 		string node of like node */
321 		str_node = static_cast<sym_node_t*>(
322 			que_node_list_get_last(like_node));
323 
324 		/* Must find the string node */
325 		ut_a(str_node);
326 		ut_a(str_node != like_node);
327 		ut_a(str_node->token_type == SYM_LIT);
328 
329 		dfield = que_node_get_val(str_node);
330 		dfield_set_data(dfield, ptr, ptr_len);
331 	}
332 
333 	dfield = que_node_get_val(like_node);
334 	dtype = dfield_get_type(dfield);
335 
336 	ut_a(dtype_get_mtype(dtype) == DATA_INT);
337 	op_check = static_cast<ib_like_t>(
338 		mach_read_from_4(static_cast<byte*>(dfield_get_data(dfield))));
339 
340 	switch (op_check) {
341 	case IB_LIKE_PREFIX:
342 	case IB_LIKE_EXACT:
343 		break;
344 
345 	default:
346 		ut_error;
347 	}
348 
349 	mach_write_to_4(static_cast<byte*>(dfield_get_data(dfield)), op);
350 
351 	dfield = que_node_get_val(node);
352 
353 	/* Adjust the length of the search value so the '%' is not
354 	visible. Then create and add a search string node to the
355 	search value node. Searching for %SUFFIX and %SUBSTR% requires
356 	a full table scan and so we set the search value to ''.
357 	For PREFIX% we simply remove the trailing '%'.*/
358 
359 	switch (op) {
360 	case	IB_LIKE_EXACT:
361 		dfield = que_node_get_val(str_node);
362 		dtype = dfield_get_type(dfield);
363 
364 		ut_a(dtype_get_mtype(dtype) == DATA_VARCHAR);
365 
366 		dfield_set_data(dfield, ptr, ptr_len);
367 		break;
368 
369 	case	IB_LIKE_PREFIX:
370 		func = PARS_LIKE_TOKEN_PREFIX;
371 
372 		/* Modify the original node */
373 		dfield_set_len(dfield, ptr_len - 1);
374 
375 		dfield = que_node_get_val(str_node);
376 		dtype = dfield_get_type(dfield);
377 
378 		ut_a(dtype_get_mtype(dtype) == DATA_VARCHAR);
379 
380 		dfield_set_data(dfield, ptr, ptr_len - 1);
381 		break;
382 
383 	default:
384 		ut_error;
385 	}
386 
387 	return(func);
388 }
389 
390 /*************************************************************************
391 Parses a LIKE operator expression. */
392 static
393 int
pars_like_op(que_node_t * arg)394 pars_like_op(
395 /*=========*/
396 				/* out, own: function node in a query tree */
397 	que_node_t*	arg)	/* in: LIKE comparison string.*/
398 {
399 	char*		ptr;
400 	ulint		ptr_len;
401 	int		func = PARS_LIKE_TOKEN_EXACT;
402 	dfield_t*	dfield = que_node_get_val(arg);
403 	dtype_t*	dtype = dfield_get_type(dfield);
404 
405 	ut_a(dtype_get_mtype(dtype) == DATA_CHAR
406 	     || dtype_get_mtype(dtype) == DATA_VARCHAR);
407 
408 	ptr = static_cast<char*>(dfield_get_data(dfield));
409 	ptr_len = strlen(ptr);
410 
411 	if (ptr_len) {
412 
413 		func = pars_like_rebind(
414 			static_cast<sym_node_t*>(arg), (byte*) ptr, ptr_len);
415 	}
416 
417 	return(func);
418 }
419 /*********************************************************************//**
420 Parses an operator expression.
421 @return own: function node in a query tree */
422 func_node_t*
pars_op(int func,que_node_t * arg1,que_node_t * arg2)423 pars_op(
424 /*====*/
425 	int		func,	/*!< in: operator token code */
426 	que_node_t*	arg1,	/*!< in: first argument */
427 	que_node_t*	arg2)	/*!< in: second argument or NULL for an unary
428 				operator */
429 {
430 	que_node_list_add_last(NULL, arg1);
431 
432 	if (arg2) {
433 		que_node_list_add_last(arg1, arg2);
434 	}
435 
436 	/* We need to parse the string and determine whether it's a
437 	PREFIX, SUFFIX or SUBSTRING comparison */
438 	if (func == PARS_LIKE_TOKEN) {
439 
440 		ut_a(que_node_get_type(arg2) == QUE_NODE_SYMBOL);
441 
442 		func = pars_like_op(arg2);
443 
444 		ut_a(func == PARS_LIKE_TOKEN_EXACT
445 		     || func == PARS_LIKE_TOKEN_PREFIX
446 		     || func == PARS_LIKE_TOKEN_SUFFIX
447 		     || func == PARS_LIKE_TOKEN_SUBSTR);
448 	}
449 
450 	return(pars_func_low(func, arg1));
451 }
452 
453 /*********************************************************************//**
454 Parses an ORDER BY clause. Order by a single column only is supported.
455 @return own: order-by node in a query tree */
456 order_node_t*
pars_order_by(sym_node_t * column,pars_res_word_t * asc)457 pars_order_by(
458 /*==========*/
459 	sym_node_t*	column,	/*!< in: column name */
460 	pars_res_word_t* asc)	/*!< in: &pars_asc_token or pars_desc_token */
461 {
462 	order_node_t*	node;
463 
464 	node = static_cast<order_node_t*>(
465 		mem_heap_alloc(
466 			pars_sym_tab_global->heap, sizeof(order_node_t)));
467 
468 	node->common.type = QUE_NODE_ORDER;
469 
470 	node->column = column;
471 
472 	if (asc == &pars_asc_token) {
473 		node->asc = TRUE;
474 	} else {
475 		ut_a(asc == &pars_desc_token);
476 		node->asc = FALSE;
477 	}
478 
479 	return(node);
480 }
481 
482 /*********************************************************************//**
483 Determine if a data type is a built-in string data type of the InnoDB
484 SQL parser.
485 @return TRUE if string data type */
486 static
487 ibool
pars_is_string_type(ulint mtype)488 pars_is_string_type(
489 /*================*/
490 	ulint	mtype)	/*!< in: main data type */
491 {
492 	switch (mtype) {
493 	case DATA_VARCHAR: case DATA_CHAR:
494 	case DATA_FIXBINARY: case DATA_BINARY:
495 		return(TRUE);
496 	}
497 
498 	return(FALSE);
499 }
500 
501 /*********************************************************************//**
502 Resolves the data type of a function in an expression. The argument data
503 types must already be resolved. */
504 static
505 void
pars_resolve_func_data_type(func_node_t * node)506 pars_resolve_func_data_type(
507 /*========================*/
508 	func_node_t*	node)	/*!< in: function node */
509 {
510 	que_node_t*	arg;
511 
512 	ut_a(que_node_get_type(node) == QUE_NODE_FUNC);
513 
514 	arg = node->args;
515 
516 	switch (node->func) {
517 	case PARS_SUM_TOKEN:
518 	case '+': case '-': case '*': case '/':
519 		/* Inherit the data type from the first argument (which must
520 		not be the SQL null literal whose type is DATA_ERROR) */
521 
522 		dtype_copy(que_node_get_data_type(node),
523 			   que_node_get_data_type(arg));
524 
525 		ut_a(dtype_get_mtype(que_node_get_data_type(node))
526 		     == DATA_INT);
527 		break;
528 
529 	case PARS_COUNT_TOKEN:
530 		ut_a(arg);
531 		dtype_set(que_node_get_data_type(node), DATA_INT, 0, 4);
532 		break;
533 
534 	case PARS_TO_CHAR_TOKEN:
535 	case PARS_RND_STR_TOKEN:
536 		ut_a(dtype_get_mtype(que_node_get_data_type(arg)) == DATA_INT);
537 		dtype_set(que_node_get_data_type(node), DATA_VARCHAR,
538 			  DATA_ENGLISH, 0);
539 		break;
540 
541 	case PARS_TO_BINARY_TOKEN:
542 		if (dtype_get_mtype(que_node_get_data_type(arg)) == DATA_INT) {
543 			dtype_set(que_node_get_data_type(node), DATA_VARCHAR,
544 				  DATA_ENGLISH, 0);
545 		} else {
546 			dtype_set(que_node_get_data_type(node), DATA_BINARY,
547 				  0, 0);
548 		}
549 		break;
550 
551 	case PARS_TO_NUMBER_TOKEN:
552 	case PARS_BINARY_TO_NUMBER_TOKEN:
553 	case PARS_LENGTH_TOKEN:
554 	case PARS_INSTR_TOKEN:
555 		ut_a(pars_is_string_type(que_node_get_data_type(arg)->mtype));
556 		dtype_set(que_node_get_data_type(node), DATA_INT, 0, 4);
557 		break;
558 
559 	case PARS_SYSDATE_TOKEN:
560 		ut_a(arg == NULL);
561 		dtype_set(que_node_get_data_type(node), DATA_INT, 0, 4);
562 		break;
563 
564 	case PARS_SUBSTR_TOKEN:
565 	case PARS_CONCAT_TOKEN:
566 		ut_a(pars_is_string_type(que_node_get_data_type(arg)->mtype));
567 		dtype_set(que_node_get_data_type(node), DATA_VARCHAR,
568 			  DATA_ENGLISH, 0);
569 		break;
570 
571 	case '>': case '<': case '=':
572 	case PARS_GE_TOKEN:
573 	case PARS_LE_TOKEN:
574 	case PARS_NE_TOKEN:
575 	case PARS_AND_TOKEN:
576 	case PARS_OR_TOKEN:
577 	case PARS_NOT_TOKEN:
578 	case PARS_NOTFOUND_TOKEN:
579 
580 		/* We currently have no iboolean type: use integer type */
581 		dtype_set(que_node_get_data_type(node), DATA_INT, 0, 4);
582 		break;
583 
584 	case PARS_RND_TOKEN:
585 		ut_a(dtype_get_mtype(que_node_get_data_type(arg)) == DATA_INT);
586 		dtype_set(que_node_get_data_type(node), DATA_INT, 0, 4);
587 		break;
588 
589 	case PARS_LIKE_TOKEN_EXACT:
590 	case PARS_LIKE_TOKEN_PREFIX:
591 	case PARS_LIKE_TOKEN_SUFFIX:
592 	case PARS_LIKE_TOKEN_SUBSTR:
593 		dtype_set(que_node_get_data_type(node), DATA_VARCHAR,
594 			  DATA_ENGLISH, 0);
595 		break;
596 
597 	default:
598 		ut_error;
599 	}
600 }
601 
602 /*********************************************************************//**
603 Resolves the meaning of variables in an expression and the data types of
604 functions. It is an error if some identifier cannot be resolved here. */
605 static
606 void
pars_resolve_exp_variables_and_types(sel_node_t * select_node,que_node_t * exp_node)607 pars_resolve_exp_variables_and_types(
608 /*=================================*/
609 	sel_node_t*	select_node,	/*!< in: select node or NULL; if
610 					this is not NULL then the variable
611 					sym nodes are added to the
612 					copy_variables list of select_node */
613 	que_node_t*	exp_node)	/*!< in: expression */
614 {
615 	func_node_t*	func_node;
616 	que_node_t*	arg;
617 	sym_node_t*	sym_node;
618 	sym_node_t*	node;
619 
620 	ut_a(exp_node);
621 
622 	if (que_node_get_type(exp_node) == QUE_NODE_FUNC) {
623 		func_node = static_cast<func_node_t*>(exp_node);
624 
625 		arg = func_node->args;
626 
627 		while (arg) {
628 			pars_resolve_exp_variables_and_types(select_node, arg);
629 
630 			arg = que_node_get_next(arg);
631 		}
632 
633 		pars_resolve_func_data_type(func_node);
634 
635 		return;
636 	}
637 
638 	ut_a(que_node_get_type(exp_node) == QUE_NODE_SYMBOL);
639 
640 	sym_node = static_cast<sym_node_t*>(exp_node);
641 
642 	if (sym_node->resolved) {
643 
644 		return;
645 	}
646 
647 	/* Not resolved yet: look in the symbol table for a variable
648 	or a cursor or a function with the same name */
649 
650 	node = UT_LIST_GET_FIRST(pars_sym_tab_global->sym_list);
651 
652 	while (node) {
653 		if (node->resolved
654 		    && ((node->token_type == SYM_VAR)
655 			|| (node->token_type == SYM_CURSOR)
656 			|| (node->token_type == SYM_FUNCTION))
657 		    && node->name
658 		    && (sym_node->name_len == node->name_len)
659 		    && (ut_memcmp(sym_node->name, node->name,
660 				  node->name_len) == 0)) {
661 
662 			/* Found a variable or a cursor declared with
663 			the same name */
664 
665 			break;
666 		}
667 
668 		node = UT_LIST_GET_NEXT(sym_list, node);
669 	}
670 
671 	if (!node) {
672 		fprintf(stderr, "PARSER ERROR: Unresolved identifier %s\n",
673 			sym_node->name);
674 	}
675 
676 	ut_a(node);
677 
678 	sym_node->resolved = TRUE;
679 	sym_node->token_type = SYM_IMPLICIT_VAR;
680 	sym_node->alias = node;
681 	sym_node->indirection = node;
682 
683 	if (select_node) {
684 		UT_LIST_ADD_LAST(select_node->copy_variables, sym_node);
685 	}
686 
687 	dfield_set_type(que_node_get_val(sym_node),
688 			que_node_get_data_type(node));
689 }
690 
691 /*********************************************************************//**
692 Resolves the meaning of variables in an expression list. It is an error if
693 some identifier cannot be resolved here. Resolves also the data types of
694 functions. */
695 static
696 void
pars_resolve_exp_list_variables_and_types(sel_node_t * select_node,que_node_t * exp_node)697 pars_resolve_exp_list_variables_and_types(
698 /*======================================*/
699 	sel_node_t*	select_node,	/*!< in: select node or NULL */
700 	que_node_t*	exp_node)	/*!< in: expression list first node, or
701 					NULL */
702 {
703 	while (exp_node) {
704 		pars_resolve_exp_variables_and_types(select_node, exp_node);
705 
706 		exp_node = que_node_get_next(exp_node);
707 	}
708 }
709 
710 /*********************************************************************//**
711 Resolves the columns in an expression. */
712 static
713 void
pars_resolve_exp_columns(sym_node_t * table_node,que_node_t * exp_node)714 pars_resolve_exp_columns(
715 /*=====================*/
716 	sym_node_t*	table_node,	/*!< in: first node in a table list */
717 	que_node_t*	exp_node)	/*!< in: expression */
718 {
719 	func_node_t*	func_node;
720 	que_node_t*	arg;
721 	sym_node_t*	sym_node;
722 	dict_table_t*	table;
723 	sym_node_t*	t_node;
724 	ulint		n_cols;
725 	ulint		i;
726 
727 	ut_a(exp_node);
728 
729 	if (que_node_get_type(exp_node) == QUE_NODE_FUNC) {
730 		func_node = static_cast<func_node_t*>(exp_node);
731 
732 		arg = func_node->args;
733 
734 		while (arg) {
735 			pars_resolve_exp_columns(table_node, arg);
736 
737 			arg = que_node_get_next(arg);
738 		}
739 
740 		return;
741 	}
742 
743 	ut_a(que_node_get_type(exp_node) == QUE_NODE_SYMBOL);
744 
745 	sym_node = static_cast<sym_node_t*>(exp_node);
746 
747 	if (sym_node->resolved) {
748 
749 		return;
750 	}
751 
752 	/* Not resolved yet: look in the table list for a column with the
753 	same name */
754 
755 	t_node = table_node;
756 
757 	while (t_node) {
758 		table = t_node->table;
759 
760 		n_cols = dict_table_get_n_cols(table);
761 
762 		for (i = 0; i < n_cols; i++) {
763 			const dict_col_t*	col
764 				= dict_table_get_nth_col(table, i);
765 			const char*		col_name
766 				= dict_table_get_col_name(table, i);
767 
768 			if ((sym_node->name_len == ut_strlen(col_name))
769 			    && (0 == ut_memcmp(sym_node->name, col_name,
770 					       sym_node->name_len))) {
771 				/* Found */
772 				sym_node->resolved = TRUE;
773 				sym_node->token_type = SYM_COLUMN;
774 				sym_node->table = table;
775 				sym_node->col_no = i;
776 				sym_node->prefetch_buf = NULL;
777 
778 				dict_col_copy_type(
779 					col,
780 					dfield_get_type(&sym_node
781 							->common.val));
782 
783 				return;
784 			}
785 		}
786 
787 		t_node = static_cast<sym_node_t*>(que_node_get_next(t_node));
788 	}
789 }
790 
791 /*********************************************************************//**
792 Resolves the meaning of columns in an expression list. */
793 static
794 void
pars_resolve_exp_list_columns(sym_node_t * table_node,que_node_t * exp_node)795 pars_resolve_exp_list_columns(
796 /*==========================*/
797 	sym_node_t*	table_node,	/*!< in: first node in a table list */
798 	que_node_t*	exp_node)	/*!< in: expression list first node, or
799 					NULL */
800 {
801 	while (exp_node) {
802 		pars_resolve_exp_columns(table_node, exp_node);
803 
804 		exp_node = que_node_get_next(exp_node);
805 	}
806 }
807 
808 /*********************************************************************//**
809 Retrieves the table definition for a table name id. */
810 static
811 void
pars_retrieve_table_def(sym_node_t * sym_node)812 pars_retrieve_table_def(
813 /*====================*/
814 	sym_node_t*	sym_node)	/*!< in: table node */
815 {
816 	ut_a(sym_node);
817 	ut_a(que_node_get_type(sym_node) == QUE_NODE_SYMBOL);
818 
819 	/* Open the table only if it is not already opened. */
820 	if (sym_node->token_type != SYM_TABLE_REF_COUNTED) {
821 
822 		ut_a(sym_node->table == NULL);
823 
824 		sym_node->resolved = TRUE;
825 		sym_node->token_type = SYM_TABLE_REF_COUNTED;
826 
827 		sym_node->table = dict_table_open_on_name(
828 			sym_node->name, TRUE, FALSE, DICT_ERR_IGNORE_NONE);
829 
830 		ut_a(sym_node->table != NULL);
831 	}
832 }
833 
834 /*********************************************************************//**
835 Retrieves the table definitions for a list of table name ids.
836 @return number of tables */
837 static
838 ulint
pars_retrieve_table_list_defs(sym_node_t * sym_node)839 pars_retrieve_table_list_defs(
840 /*==========================*/
841 	sym_node_t*	sym_node)	/*!< in: first table node in list */
842 {
843 	ulint		count		= 0;
844 
845 	if (sym_node == NULL) {
846 
847 		return(count);
848 	}
849 
850 	while (sym_node) {
851 		pars_retrieve_table_def(sym_node);
852 
853 		count++;
854 
855 		sym_node = static_cast<sym_node_t*>(
856 			que_node_get_next(sym_node));
857 	}
858 
859 	return(count);
860 }
861 
862 /*********************************************************************//**
863 Adds all columns to the select list if the query is SELECT * FROM ... */
864 static
865 void
pars_select_all_columns(sel_node_t * select_node)866 pars_select_all_columns(
867 /*====================*/
868 	sel_node_t*	select_node)	/*!< in: select node already containing
869 					the table list */
870 {
871 	sym_node_t*	col_node;
872 	sym_node_t*	table_node;
873 	dict_table_t*	table;
874 	ulint		i;
875 
876 	select_node->select_list = NULL;
877 
878 	table_node = select_node->table_list;
879 
880 	while (table_node) {
881 		table = table_node->table;
882 
883 		for (i = 0; i < dict_table_get_n_user_cols(table); i++) {
884 			const char*	col_name = dict_table_get_col_name(
885 				table, i);
886 
887 			col_node = sym_tab_add_id(pars_sym_tab_global,
888 						  (byte*) col_name,
889 						  ut_strlen(col_name));
890 
891 			select_node->select_list = que_node_list_add_last(
892 				select_node->select_list, col_node);
893 		}
894 
895 		table_node = static_cast<sym_node_t*>(
896 			que_node_get_next(table_node));
897 	}
898 }
899 
900 /*********************************************************************//**
901 Parses a select list; creates a query graph node for the whole SELECT
902 statement.
903 @return own: select node in a query tree */
904 sel_node_t*
pars_select_list(que_node_t * select_list,sym_node_t * into_list)905 pars_select_list(
906 /*=============*/
907 	que_node_t*	select_list,	/*!< in: select list */
908 	sym_node_t*	into_list)	/*!< in: variables list or NULL */
909 {
910 	sel_node_t*	node;
911 
912 	node = sel_node_create(pars_sym_tab_global->heap);
913 
914 	node->select_list = select_list;
915 	node->into_list = into_list;
916 
917 	pars_resolve_exp_list_variables_and_types(NULL, into_list);
918 
919 	return(node);
920 }
921 
922 /*********************************************************************//**
923 Checks if the query is an aggregate query, in which case the selct list must
924 contain only aggregate function items. */
925 static
926 void
pars_check_aggregate(sel_node_t * select_node)927 pars_check_aggregate(
928 /*=================*/
929 	sel_node_t*	select_node)	/*!< in: select node already containing
930 					the select list */
931 {
932 	que_node_t*	exp_node;
933 	func_node_t*	func_node;
934 	ulint		n_nodes			= 0;
935 	ulint		n_aggregate_nodes	= 0;
936 
937 	exp_node = select_node->select_list;
938 
939 	while (exp_node) {
940 
941 		n_nodes++;
942 
943 		if (que_node_get_type(exp_node) == QUE_NODE_FUNC) {
944 
945 			func_node = static_cast<func_node_t*>(exp_node);
946 
947 			if (func_node->fclass == PARS_FUNC_AGGREGATE) {
948 
949 				n_aggregate_nodes++;
950 			}
951 		}
952 
953 		exp_node = que_node_get_next(exp_node);
954 	}
955 
956 	if (n_aggregate_nodes > 0) {
957 		ut_a(n_nodes == n_aggregate_nodes);
958 
959 		select_node->is_aggregate = TRUE;
960 	} else {
961 		select_node->is_aggregate = FALSE;
962 	}
963 }
964 
965 /*********************************************************************//**
966 Parses a select statement.
967 @return own: select node in a query tree */
968 sel_node_t*
pars_select_statement(sel_node_t * select_node,sym_node_t * table_list,que_node_t * search_cond,pars_res_word_t * for_update,pars_res_word_t * lock_shared,order_node_t * order_by)969 pars_select_statement(
970 /*==================*/
971 	sel_node_t*	select_node,	/*!< in: select node already containing
972 					the select list */
973 	sym_node_t*	table_list,	/*!< in: table list */
974 	que_node_t*	search_cond,	/*!< in: search condition or NULL */
975 	pars_res_word_t* for_update,	/*!< in: NULL or &pars_update_token */
976 	pars_res_word_t* lock_shared,	/*!< in: NULL or &pars_share_token */
977 	order_node_t*	order_by)	/*!< in: NULL or an order-by node */
978 {
979 	select_node->state = SEL_NODE_OPEN;
980 
981 	select_node->table_list = table_list;
982 	select_node->n_tables = pars_retrieve_table_list_defs(table_list);
983 
984 	if (select_node->select_list == &pars_star_denoter) {
985 
986 		/* SELECT * FROM ... */
987 		pars_select_all_columns(select_node);
988 	}
989 
990 	if (select_node->into_list) {
991 		ut_a(que_node_list_get_len(select_node->into_list)
992 		     == que_node_list_get_len(select_node->select_list));
993 	}
994 
995 	UT_LIST_INIT(select_node->copy_variables, &sym_node_t::col_var_list);
996 
997 	pars_resolve_exp_list_columns(table_list, select_node->select_list);
998 	pars_resolve_exp_list_variables_and_types(select_node,
999 						  select_node->select_list);
1000 	pars_check_aggregate(select_node);
1001 
1002 	select_node->search_cond = search_cond;
1003 
1004 	if (search_cond) {
1005 		pars_resolve_exp_columns(table_list, search_cond);
1006 		pars_resolve_exp_variables_and_types(select_node, search_cond);
1007 	}
1008 
1009 	if (for_update) {
1010 		ut_a(!lock_shared);
1011 
1012 		select_node->set_x_locks = TRUE;
1013 		select_node->row_lock_mode = LOCK_X;
1014 
1015 		select_node->consistent_read = FALSE;
1016 		select_node->read_view = NULL;
1017 	} else if (lock_shared){
1018 		select_node->set_x_locks = FALSE;
1019 		select_node->row_lock_mode = LOCK_S;
1020 
1021 		select_node->consistent_read = FALSE;
1022 		select_node->read_view = NULL;
1023 	} else {
1024 		select_node->set_x_locks = FALSE;
1025 		select_node->row_lock_mode = LOCK_S;
1026 
1027 		select_node->consistent_read = TRUE;
1028 	}
1029 
1030 	select_node->order_by = order_by;
1031 
1032 	if (order_by) {
1033 		pars_resolve_exp_columns(table_list, order_by->column);
1034 	}
1035 
1036 	/* The final value of the following fields depend on the environment
1037 	where the select statement appears: */
1038 
1039 	select_node->can_get_updated = FALSE;
1040 	select_node->explicit_cursor = NULL;
1041 
1042 	opt_search_plan(select_node);
1043 
1044 	return(select_node);
1045 }
1046 
1047 /*********************************************************************//**
1048 Parses a cursor declaration.
1049 @return sym_node */
1050 que_node_t*
pars_cursor_declaration(sym_node_t * sym_node,sel_node_t * select_node)1051 pars_cursor_declaration(
1052 /*====================*/
1053 	sym_node_t*	sym_node,	/*!< in: cursor id node in the symbol
1054 					table */
1055 	sel_node_t*	select_node)	/*!< in: select node */
1056 {
1057 	sym_node->resolved = TRUE;
1058 	sym_node->token_type = SYM_CURSOR;
1059 	sym_node->cursor_def = select_node;
1060 
1061 	select_node->state = SEL_NODE_CLOSED;
1062 	select_node->explicit_cursor = sym_node;
1063 
1064 	return(sym_node);
1065 }
1066 
1067 /*********************************************************************//**
1068 Parses a function declaration.
1069 @return sym_node */
1070 que_node_t*
pars_function_declaration(sym_node_t * sym_node)1071 pars_function_declaration(
1072 /*======================*/
1073 	sym_node_t*	sym_node)	/*!< in: function id node in the symbol
1074 					table */
1075 {
1076 	sym_node->resolved = TRUE;
1077 	sym_node->token_type = SYM_FUNCTION;
1078 
1079 	/* Check that the function exists. */
1080 	ut_a(pars_info_lookup_user_func(
1081 		pars_sym_tab_global->info, sym_node->name));
1082 
1083 	return(sym_node);
1084 }
1085 
1086 /*********************************************************************//**
1087 Parses a delete or update statement start.
1088 @return own: update node in a query tree */
1089 upd_node_t*
pars_update_statement_start(ibool is_delete,sym_node_t * table_sym,col_assign_node_t * col_assign_list)1090 pars_update_statement_start(
1091 /*========================*/
1092 	ibool		is_delete,	/*!< in: TRUE if delete */
1093 	sym_node_t*	table_sym,	/*!< in: table name node */
1094 	col_assign_node_t* col_assign_list)/*!< in: column assignment list, NULL
1095 					if delete */
1096 {
1097 	upd_node_t*	node;
1098 
1099 	node = upd_node_create(pars_sym_tab_global->heap);
1100 
1101 	node->is_delete = is_delete;
1102 
1103 	node->table_sym = table_sym;
1104 	node->col_assign_list = col_assign_list;
1105 
1106 	return(node);
1107 }
1108 
1109 /*********************************************************************//**
1110 Parses a column assignment in an update.
1111 @return column assignment node */
1112 col_assign_node_t*
pars_column_assignment(sym_node_t * column,que_node_t * exp)1113 pars_column_assignment(
1114 /*===================*/
1115 	sym_node_t*	column,	/*!< in: column to assign */
1116 	que_node_t*	exp)	/*!< in: value to assign */
1117 {
1118 	col_assign_node_t*	node;
1119 
1120 	node = static_cast<col_assign_node_t*>(
1121 		mem_heap_alloc(pars_sym_tab_global->heap,
1122 			      sizeof(col_assign_node_t)));
1123 	node->common.type = QUE_NODE_COL_ASSIGNMENT;
1124 
1125 	node->col = column;
1126 	node->val = exp;
1127 
1128 	return(node);
1129 }
1130 
1131 /*********************************************************************//**
1132 Processes an update node assignment list. */
1133 static
1134 void
pars_process_assign_list(upd_node_t * node)1135 pars_process_assign_list(
1136 /*=====================*/
1137 	upd_node_t*	node)	/*!< in: update node */
1138 {
1139 	col_assign_node_t*	col_assign_list;
1140 	sym_node_t*		table_sym;
1141 	col_assign_node_t*	assign_node;
1142 	upd_field_t*		upd_field;
1143 	dict_index_t*		clust_index;
1144 	sym_node_t*		col_sym;
1145 	ulint			changes_ord_field;
1146 	ulint			changes_field_size;
1147 	ulint			n_assigns;
1148 	ulint			i;
1149 
1150 	table_sym = node->table_sym;
1151 	col_assign_list = static_cast<col_assign_node_t*>(
1152 		 node->col_assign_list);
1153 	clust_index = dict_table_get_first_index(node->table);
1154 
1155 	assign_node = col_assign_list;
1156 	n_assigns = 0;
1157 
1158 	while (assign_node) {
1159 		pars_resolve_exp_columns(table_sym, assign_node->col);
1160 		pars_resolve_exp_columns(table_sym, assign_node->val);
1161 		pars_resolve_exp_variables_and_types(NULL, assign_node->val);
1162 #if 0
1163 		ut_a(dtype_get_mtype(
1164 			     dfield_get_type(que_node_get_val(
1165 						     assign_node->col)))
1166 		     == dtype_get_mtype(
1167 			     dfield_get_type(que_node_get_val(
1168 						     assign_node->val))));
1169 #endif
1170 
1171 		/* Add to the update node all the columns found in assignment
1172 		values as columns to copy: therefore, TRUE */
1173 
1174 		opt_find_all_cols(TRUE, clust_index, &(node->columns), NULL,
1175 				  assign_node->val);
1176 		n_assigns++;
1177 
1178 		assign_node = static_cast<col_assign_node_t*>(
1179 				que_node_get_next(assign_node));
1180 	}
1181 
1182 	node->update = upd_create(n_assigns, pars_sym_tab_global->heap);
1183 
1184 	assign_node = col_assign_list;
1185 
1186 	changes_field_size = UPD_NODE_NO_SIZE_CHANGE;
1187 
1188 	for (i = 0; i < n_assigns; i++) {
1189 		upd_field = upd_get_nth_field(node->update, i);
1190 
1191 		col_sym = assign_node->col;
1192 
1193 		upd_field_set_field_no(upd_field, dict_index_get_nth_col_pos(
1194 						clust_index, col_sym->col_no,
1195 						NULL),
1196 				       clust_index, NULL);
1197 		upd_field->exp = assign_node->val;
1198 
1199 		if (!dict_col_get_fixed_size(
1200 			    dict_index_get_nth_col(clust_index,
1201 						   upd_field->field_no),
1202 			    dict_table_is_comp(node->table))) {
1203 			changes_field_size = 0;
1204 		}
1205 
1206 		assign_node = static_cast<col_assign_node_t*>(
1207 				que_node_get_next(assign_node));
1208 	}
1209 
1210 	/* Find out if the update can modify an ordering field in any index */
1211 
1212 	changes_ord_field = UPD_NODE_NO_ORD_CHANGE;
1213 
1214 	if (row_upd_changes_some_index_ord_field_binary(node->table,
1215 							node->update)) {
1216 		changes_ord_field = 0;
1217 	}
1218 
1219 	node->cmpl_info = changes_ord_field | changes_field_size;
1220 }
1221 
1222 /*********************************************************************//**
1223 Parses an update or delete statement.
1224 @return own: update node in a query tree */
1225 upd_node_t*
pars_update_statement(upd_node_t * node,sym_node_t * cursor_sym,que_node_t * search_cond)1226 pars_update_statement(
1227 /*==================*/
1228 	upd_node_t*	node,		/*!< in: update node */
1229 	sym_node_t*	cursor_sym,	/*!< in: pointer to a cursor entry in
1230 					the symbol table or NULL */
1231 	que_node_t*	search_cond)	/*!< in: search condition or NULL */
1232 {
1233 	sym_node_t*	table_sym;
1234 	sel_node_t*	sel_node;
1235 	plan_t*		plan;
1236 
1237 	table_sym = node->table_sym;
1238 
1239 	pars_retrieve_table_def(table_sym);
1240 	node->table = table_sym->table;
1241 
1242 	UT_LIST_INIT(node->columns, &sym_node_t::col_var_list);
1243 
1244 	/* Make the single table node into a list of table nodes of length 1 */
1245 
1246 	que_node_list_add_last(NULL, table_sym);
1247 
1248 	if (cursor_sym) {
1249 		pars_resolve_exp_variables_and_types(NULL, cursor_sym);
1250 
1251 		sel_node = cursor_sym->alias->cursor_def;
1252 
1253 		node->searched_update = FALSE;
1254 	} else {
1255 		sel_node = pars_select_list(NULL, NULL);
1256 
1257 		pars_select_statement(sel_node, table_sym, search_cond, NULL,
1258 				      &pars_share_token, NULL);
1259 		node->searched_update = TRUE;
1260 		sel_node->common.parent = node;
1261 	}
1262 
1263 	node->select = sel_node;
1264 
1265 	ut_a(!node->is_delete || (node->col_assign_list == NULL));
1266 	ut_a(node->is_delete || (node->col_assign_list != NULL));
1267 
1268 	if (node->is_delete) {
1269 		node->cmpl_info = 0;
1270 	} else {
1271 		pars_process_assign_list(node);
1272 	}
1273 
1274 	if (node->searched_update) {
1275 		node->has_clust_rec_x_lock = TRUE;
1276 		sel_node->set_x_locks = TRUE;
1277 		sel_node->row_lock_mode = LOCK_X;
1278 	} else {
1279 		node->has_clust_rec_x_lock = sel_node->set_x_locks;
1280 	}
1281 
1282 	ut_a(sel_node->n_tables == 1);
1283 	ut_a(sel_node->consistent_read == FALSE);
1284 	ut_a(sel_node->order_by == NULL);
1285 	ut_a(sel_node->is_aggregate == FALSE);
1286 
1287 	sel_node->can_get_updated = TRUE;
1288 
1289 	node->state = UPD_NODE_UPDATE_CLUSTERED;
1290 
1291 	plan = sel_node_get_nth_plan(sel_node, 0);
1292 
1293 	plan->no_prefetch = TRUE;
1294 
1295 	if (!dict_index_is_clust(plan->index)) {
1296 
1297 		plan->must_get_clust = TRUE;
1298 
1299 		node->pcur = &(plan->clust_pcur);
1300 	} else {
1301 		node->pcur = &(plan->pcur);
1302 	}
1303 
1304 	return(node);
1305 }
1306 
1307 /*********************************************************************//**
1308 Parses an insert statement.
1309 @return own: update node in a query tree */
1310 ins_node_t*
pars_insert_statement(sym_node_t * table_sym,que_node_t * values_list,sel_node_t * select)1311 pars_insert_statement(
1312 /*==================*/
1313 	sym_node_t*	table_sym,	/*!< in: table name node */
1314 	que_node_t*	values_list,	/*!< in: value expression list or NULL */
1315 	sel_node_t*	select)		/*!< in: select condition or NULL */
1316 {
1317 	ins_node_t*	node;
1318 	dtuple_t*	row;
1319 	ulint		ins_type;
1320 
1321 	ut_a(values_list || select);
1322 	ut_a(!values_list || !select);
1323 
1324 	if (values_list) {
1325 		ins_type = INS_VALUES;
1326 	} else {
1327 		ins_type = INS_SEARCHED;
1328 	}
1329 
1330 	pars_retrieve_table_def(table_sym);
1331 
1332 	node = ins_node_create(ins_type, table_sym->table,
1333 			       pars_sym_tab_global->heap);
1334 
1335 	row = dtuple_create(pars_sym_tab_global->heap,
1336 			    dict_table_get_n_cols(node->table));
1337 
1338 	dict_table_copy_types(row, table_sym->table);
1339 
1340 	ins_node_set_new_row(node, row);
1341 
1342 	node->select = select;
1343 
1344 	if (select) {
1345 		select->common.parent = node;
1346 
1347 		ut_a(que_node_list_get_len(select->select_list)
1348 		     == dict_table_get_n_user_cols(table_sym->table));
1349 	}
1350 
1351 	node->values_list = values_list;
1352 
1353 	if (node->values_list) {
1354 		pars_resolve_exp_list_variables_and_types(NULL, values_list);
1355 
1356 		ut_a(que_node_list_get_len(values_list)
1357 		     == dict_table_get_n_user_cols(table_sym->table));
1358 	}
1359 
1360 	return(node);
1361 }
1362 
1363 /*********************************************************************//**
1364 Set the type of a dfield. */
1365 static
1366 void
pars_set_dfield_type(dfield_t * dfield,pars_res_word_t * type,ulint len,ibool is_unsigned,ibool is_not_null)1367 pars_set_dfield_type(
1368 /*=================*/
1369 	dfield_t*		dfield,		/*!< in: dfield */
1370 	pars_res_word_t*	type,		/*!< in: pointer to a type
1371 						token */
1372 	ulint			len,		/*!< in: length, or 0 */
1373 	ibool			is_unsigned,	/*!< in: if TRUE, column is
1374 						UNSIGNED. */
1375 	ibool			is_not_null)	/*!< in: if TRUE, column is
1376 						NOT NULL. */
1377 {
1378 	ulint flags = 0;
1379 
1380 	if (is_not_null) {
1381 		flags |= DATA_NOT_NULL;
1382 	}
1383 
1384 	if (is_unsigned) {
1385 		flags |= DATA_UNSIGNED;
1386 	}
1387 
1388 	if (type == &pars_bigint_token) {
1389 		ut_a(len == 0);
1390 
1391 		dtype_set(dfield_get_type(dfield), DATA_INT, flags, 8);
1392 	} else if (type == &pars_int_token) {
1393 		ut_a(len == 0);
1394 
1395 		dtype_set(dfield_get_type(dfield), DATA_INT, flags, 4);
1396 
1397 	} else if (type == &pars_char_token) {
1398 		//ut_a(len == 0);
1399 
1400 		dtype_set(dfield_get_type(dfield), DATA_VARCHAR,
1401 			  DATA_ENGLISH | flags, len);
1402 	} else if (type == &pars_binary_token) {
1403 		ut_a(len != 0);
1404 
1405 		dtype_set(dfield_get_type(dfield), DATA_FIXBINARY,
1406 			  DATA_BINARY_TYPE | flags, len);
1407 	} else if (type == &pars_blob_token) {
1408 		ut_a(len == 0);
1409 
1410 		dtype_set(dfield_get_type(dfield), DATA_BLOB,
1411 			  DATA_BINARY_TYPE | flags, 0);
1412 	} else {
1413 		ut_error;
1414 	}
1415 }
1416 
1417 /*********************************************************************//**
1418 Parses a variable declaration.
1419 @return own: symbol table node of type SYM_VAR */
1420 sym_node_t*
pars_variable_declaration(sym_node_t * node,pars_res_word_t * type)1421 pars_variable_declaration(
1422 /*======================*/
1423 	sym_node_t*	node,	/*!< in: symbol table node allocated for the
1424 				id of the variable */
1425 	pars_res_word_t* type)	/*!< in: pointer to a type token */
1426 {
1427 	node->resolved = TRUE;
1428 	node->token_type = SYM_VAR;
1429 
1430 	node->param_type = PARS_NOT_PARAM;
1431 
1432 	pars_set_dfield_type(que_node_get_val(node), type, 0, FALSE, FALSE);
1433 
1434 	return(node);
1435 }
1436 
1437 /*********************************************************************//**
1438 Parses a procedure parameter declaration.
1439 @return own: symbol table node of type SYM_VAR */
1440 sym_node_t*
pars_parameter_declaration(sym_node_t * node,ulint param_type,pars_res_word_t * type)1441 pars_parameter_declaration(
1442 /*=======================*/
1443 	sym_node_t*	node,	/*!< in: symbol table node allocated for the
1444 				id of the parameter */
1445 	ulint		param_type,
1446 				/*!< in: PARS_INPUT or PARS_OUTPUT */
1447 	pars_res_word_t* type)	/*!< in: pointer to a type token */
1448 {
1449 	ut_a((param_type == PARS_INPUT) || (param_type == PARS_OUTPUT));
1450 
1451 	pars_variable_declaration(node, type);
1452 
1453 	node->param_type = param_type;
1454 
1455 	return(node);
1456 }
1457 
1458 /*********************************************************************//**
1459 Sets the parent field in a query node list. */
1460 static
1461 void
pars_set_parent_in_list(que_node_t * node_list,que_node_t * parent)1462 pars_set_parent_in_list(
1463 /*====================*/
1464 	que_node_t*	node_list,	/*!< in: first node in a list */
1465 	que_node_t*	parent)		/*!< in: parent value to set in all
1466 					nodes of the list */
1467 {
1468 	que_common_t*	common;
1469 
1470 	common = static_cast<que_common_t*>(node_list);
1471 
1472 	while (common) {
1473 		common->parent = parent;
1474 
1475 		common = static_cast<que_common_t*>(que_node_get_next(common));
1476 	}
1477 }
1478 
1479 /*********************************************************************//**
1480 Parses an elsif element.
1481 @return elsif node */
1482 elsif_node_t*
pars_elsif_element(que_node_t * cond,que_node_t * stat_list)1483 pars_elsif_element(
1484 /*===============*/
1485 	que_node_t*	cond,		/*!< in: if-condition */
1486 	que_node_t*	stat_list)	/*!< in: statement list */
1487 {
1488 	elsif_node_t*	node;
1489 
1490 	node = static_cast<elsif_node_t*>(
1491 		mem_heap_alloc(
1492 			pars_sym_tab_global->heap, sizeof(elsif_node_t)));
1493 
1494 	node->common.type = QUE_NODE_ELSIF;
1495 
1496 	node->cond = cond;
1497 
1498 	pars_resolve_exp_variables_and_types(NULL, cond);
1499 
1500 	node->stat_list = stat_list;
1501 
1502 	return(node);
1503 }
1504 
1505 /*********************************************************************//**
1506 Parses an if-statement.
1507 @return if-statement node */
1508 if_node_t*
pars_if_statement(que_node_t * cond,que_node_t * stat_list,que_node_t * else_part)1509 pars_if_statement(
1510 /*==============*/
1511 	que_node_t*	cond,		/*!< in: if-condition */
1512 	que_node_t*	stat_list,	/*!< in: statement list */
1513 	que_node_t*	else_part)	/*!< in: else-part statement list
1514 					or elsif element list */
1515 {
1516 	if_node_t*	node;
1517 	elsif_node_t*	elsif_node;
1518 
1519 	node = static_cast<if_node_t*>(
1520 		 mem_heap_alloc(
1521 			pars_sym_tab_global->heap, sizeof(if_node_t)));
1522 
1523 	node->common.type = QUE_NODE_IF;
1524 
1525 	node->cond = cond;
1526 
1527 	pars_resolve_exp_variables_and_types(NULL, cond);
1528 
1529 	node->stat_list = stat_list;
1530 
1531 	if (else_part && (que_node_get_type(else_part) == QUE_NODE_ELSIF)) {
1532 
1533 		/* There is a list of elsif conditions */
1534 
1535 		node->else_part = NULL;
1536 		node->elsif_list = static_cast<elsif_node_t*>(else_part);
1537 
1538 		elsif_node = static_cast<elsif_node_t*>(else_part);
1539 
1540 		while (elsif_node) {
1541 			pars_set_parent_in_list(elsif_node->stat_list, node);
1542 
1543 			elsif_node = static_cast<elsif_node_t*>(
1544 				que_node_get_next(elsif_node));
1545 		}
1546 	} else {
1547 		node->else_part = else_part;
1548 		node->elsif_list = NULL;
1549 
1550 		pars_set_parent_in_list(else_part, node);
1551 	}
1552 
1553 	pars_set_parent_in_list(stat_list, node);
1554 
1555 	return(node);
1556 }
1557 
1558 /*********************************************************************//**
1559 Parses a while-statement.
1560 @return while-statement node */
1561 while_node_t*
pars_while_statement(que_node_t * cond,que_node_t * stat_list)1562 pars_while_statement(
1563 /*=================*/
1564 	que_node_t*	cond,		/*!< in: while-condition */
1565 	que_node_t*	stat_list)	/*!< in: statement list */
1566 {
1567 	while_node_t*	node;
1568 
1569 	node = static_cast<while_node_t*>(
1570 		mem_heap_alloc(
1571 			pars_sym_tab_global->heap, sizeof(while_node_t)));
1572 
1573 	node->common.type = QUE_NODE_WHILE;
1574 
1575 	node->cond = cond;
1576 
1577 	pars_resolve_exp_variables_and_types(NULL, cond);
1578 
1579 	node->stat_list = stat_list;
1580 
1581 	pars_set_parent_in_list(stat_list, node);
1582 
1583 	return(node);
1584 }
1585 
1586 /*********************************************************************//**
1587 Parses a for-loop-statement.
1588 @return for-statement node */
1589 for_node_t*
pars_for_statement(sym_node_t * loop_var,que_node_t * loop_start_limit,que_node_t * loop_end_limit,que_node_t * stat_list)1590 pars_for_statement(
1591 /*===============*/
1592 	sym_node_t*	loop_var,	/*!< in: loop variable */
1593 	que_node_t*	loop_start_limit,/*!< in: loop start expression */
1594 	que_node_t*	loop_end_limit,	/*!< in: loop end expression */
1595 	que_node_t*	stat_list)	/*!< in: statement list */
1596 {
1597 	for_node_t*	node;
1598 
1599 	node = static_cast<for_node_t*>(
1600 		mem_heap_alloc(pars_sym_tab_global->heap, sizeof(for_node_t)));
1601 
1602 	node->common.type = QUE_NODE_FOR;
1603 
1604 	pars_resolve_exp_variables_and_types(NULL, loop_var);
1605 	pars_resolve_exp_variables_and_types(NULL, loop_start_limit);
1606 	pars_resolve_exp_variables_and_types(NULL, loop_end_limit);
1607 
1608 	node->loop_var = loop_var->indirection;
1609 
1610 	ut_a(loop_var->indirection);
1611 
1612 	node->loop_start_limit = loop_start_limit;
1613 	node->loop_end_limit = loop_end_limit;
1614 
1615 	node->stat_list = stat_list;
1616 
1617 	pars_set_parent_in_list(stat_list, node);
1618 
1619 	return(node);
1620 }
1621 
1622 /*********************************************************************//**
1623 Parses an exit statement.
1624 @return exit statement node */
1625 exit_node_t*
pars_exit_statement(void)1626 pars_exit_statement(void)
1627 /*=====================*/
1628 {
1629 	exit_node_t*	node;
1630 
1631 	node = static_cast<exit_node_t*>(
1632 		mem_heap_alloc(pars_sym_tab_global->heap, sizeof(exit_node_t)));
1633 	node->common.type = QUE_NODE_EXIT;
1634 
1635 	return(node);
1636 }
1637 
1638 /*********************************************************************//**
1639 Parses a return-statement.
1640 @return return-statement node */
1641 return_node_t*
pars_return_statement(void)1642 pars_return_statement(void)
1643 /*=======================*/
1644 {
1645 	return_node_t*	node;
1646 
1647 	node = static_cast<return_node_t*>(
1648 		mem_heap_alloc(
1649 			pars_sym_tab_global->heap, sizeof(return_node_t)));
1650 	node->common.type = QUE_NODE_RETURN;
1651 
1652 	return(node);
1653 }
1654 
1655 /*********************************************************************//**
1656 Parses an assignment statement.
1657 @return assignment statement node */
1658 assign_node_t*
pars_assignment_statement(sym_node_t * var,que_node_t * val)1659 pars_assignment_statement(
1660 /*======================*/
1661 	sym_node_t*	var,	/*!< in: variable to assign */
1662 	que_node_t*	val)	/*!< in: value to assign */
1663 {
1664 	assign_node_t*	node;
1665 
1666 	node = static_cast<assign_node_t*>(
1667 		mem_heap_alloc(
1668 			pars_sym_tab_global->heap, sizeof(assign_node_t)));
1669 	node->common.type = QUE_NODE_ASSIGNMENT;
1670 
1671 	node->var = var;
1672 	node->val = val;
1673 
1674 	pars_resolve_exp_variables_and_types(NULL, var);
1675 	pars_resolve_exp_variables_and_types(NULL, val);
1676 
1677 	ut_a(dtype_get_mtype(dfield_get_type(que_node_get_val(var)))
1678 	     == dtype_get_mtype(dfield_get_type(que_node_get_val(val))));
1679 
1680 	return(node);
1681 }
1682 
1683 /*********************************************************************//**
1684 Parses a procedure call.
1685 @return function node */
1686 func_node_t*
pars_procedure_call(que_node_t * res_word,que_node_t * args)1687 pars_procedure_call(
1688 /*================*/
1689 	que_node_t*	res_word,/*!< in: procedure name reserved word */
1690 	que_node_t*	args)	/*!< in: argument list */
1691 {
1692 	func_node_t*	node;
1693 
1694 	node = pars_func(res_word, args);
1695 
1696 	pars_resolve_exp_list_variables_and_types(NULL, args);
1697 
1698 	return(node);
1699 }
1700 
1701 /*********************************************************************//**
1702 Parses a fetch statement. into_list or user_func (but not both) must be
1703 non-NULL.
1704 @return fetch statement node */
1705 fetch_node_t*
pars_fetch_statement(sym_node_t * cursor,sym_node_t * into_list,sym_node_t * user_func)1706 pars_fetch_statement(
1707 /*=================*/
1708 	sym_node_t*	cursor,		/*!< in: cursor node */
1709 	sym_node_t*	into_list,	/*!< in: variables to set, or NULL */
1710 	sym_node_t*	user_func)	/*!< in: user function name, or NULL */
1711 {
1712 	sym_node_t*	cursor_decl;
1713 	fetch_node_t*	node;
1714 
1715 	/* Logical XOR. */
1716 	ut_a(!into_list != !user_func);
1717 
1718 	node = static_cast<fetch_node_t*>(
1719 		mem_heap_alloc(
1720 			pars_sym_tab_global->heap, sizeof(fetch_node_t)));
1721 
1722 	node->common.type = QUE_NODE_FETCH;
1723 
1724 	pars_resolve_exp_variables_and_types(NULL, cursor);
1725 
1726 	if (into_list) {
1727 		pars_resolve_exp_list_variables_and_types(NULL, into_list);
1728 		node->into_list = into_list;
1729 		node->func = NULL;
1730 	} else {
1731 		pars_resolve_exp_variables_and_types(NULL, user_func);
1732 
1733 		node->func = pars_info_lookup_user_func(
1734 			pars_sym_tab_global->info, user_func->name);
1735 
1736 		ut_a(node->func);
1737 
1738 		node->into_list = NULL;
1739 	}
1740 
1741 	cursor_decl = cursor->alias;
1742 
1743 	ut_a(cursor_decl->token_type == SYM_CURSOR);
1744 
1745 	node->cursor_def = cursor_decl->cursor_def;
1746 
1747 	if (into_list) {
1748 		ut_a(que_node_list_get_len(into_list)
1749 		     == que_node_list_get_len(node->cursor_def->select_list));
1750 	}
1751 
1752 	return(node);
1753 }
1754 
1755 /*********************************************************************//**
1756 Parses an open or close cursor statement.
1757 @return fetch statement node */
1758 open_node_t*
pars_open_statement(ulint type,sym_node_t * cursor)1759 pars_open_statement(
1760 /*================*/
1761 	ulint		type,	/*!< in: ROW_SEL_OPEN_CURSOR
1762 				or ROW_SEL_CLOSE_CURSOR */
1763 	sym_node_t*	cursor)	/*!< in: cursor node */
1764 {
1765 	sym_node_t*	cursor_decl;
1766 	open_node_t*	node;
1767 
1768 	node = static_cast<open_node_t*>(
1769 		mem_heap_alloc(
1770 			pars_sym_tab_global->heap, sizeof(open_node_t)));
1771 
1772 	node->common.type = QUE_NODE_OPEN;
1773 
1774 	pars_resolve_exp_variables_and_types(NULL, cursor);
1775 
1776 	cursor_decl = cursor->alias;
1777 
1778 	ut_a(cursor_decl->token_type == SYM_CURSOR);
1779 
1780 	node->op_type = static_cast<open_node_op>(type);
1781 	node->cursor_def = cursor_decl->cursor_def;
1782 
1783 	return(node);
1784 }
1785 
1786 /*********************************************************************//**
1787 Parses a row_printf-statement.
1788 @return row_printf-statement node */
1789 row_printf_node_t*
pars_row_printf_statement(sel_node_t * sel_node)1790 pars_row_printf_statement(
1791 /*======================*/
1792 	sel_node_t*	sel_node)	/*!< in: select node */
1793 {
1794 	row_printf_node_t*	node;
1795 
1796 	node = static_cast<row_printf_node_t*>(
1797 		mem_heap_alloc(
1798 			pars_sym_tab_global->heap, sizeof(row_printf_node_t)));
1799 	node->common.type = QUE_NODE_ROW_PRINTF;
1800 
1801 	node->sel_node = sel_node;
1802 
1803 	sel_node->common.parent = node;
1804 
1805 	return(node);
1806 }
1807 
1808 /*********************************************************************//**
1809 Parses a commit statement.
1810 @return own: commit node struct */
1811 commit_node_t*
pars_commit_statement(void)1812 pars_commit_statement(void)
1813 /*=======================*/
1814 {
1815 	return(trx_commit_node_create(pars_sym_tab_global->heap));
1816 }
1817 
1818 /*********************************************************************//**
1819 Parses a rollback statement.
1820 @return own: rollback node struct */
1821 roll_node_t*
pars_rollback_statement(void)1822 pars_rollback_statement(void)
1823 /*=========================*/
1824 {
1825 	return(roll_node_create(pars_sym_tab_global->heap));
1826 }
1827 
1828 /*********************************************************************//**
1829 Parses a column definition at a table creation.
1830 @return column sym table node */
1831 sym_node_t*
pars_column_def(sym_node_t * sym_node,pars_res_word_t * type,sym_node_t * len,void * is_unsigned,void * is_not_null)1832 pars_column_def(
1833 /*============*/
1834 	sym_node_t*		sym_node,	/*!< in: column node in the
1835 						symbol table */
1836 	pars_res_word_t*	type,		/*!< in: data type */
1837 	sym_node_t*		len,		/*!< in: length of column, or
1838 						NULL */
1839 	void*			is_unsigned,	/*!< in: if not NULL, column
1840 						is of type UNSIGNED. */
1841 	void*			is_not_null)	/*!< in: if not NULL, column
1842 						is of type NOT NULL. */
1843 {
1844 	ulint len2;
1845 
1846 	if (len) {
1847 		len2 = eval_node_get_int_val(len);
1848 	} else {
1849 		len2 = 0;
1850 	}
1851 
1852 	pars_set_dfield_type(que_node_get_val(sym_node), type, len2,
1853 			     is_unsigned != NULL, is_not_null != NULL);
1854 
1855 	return(sym_node);
1856 }
1857 
1858 /*********************************************************************//**
1859 Parses a table creation operation.
1860 @return table create subgraph */
1861 tab_node_t*
pars_create_table(sym_node_t * table_sym,sym_node_t * column_defs,sym_node_t * compact,sym_node_t * block_size,void * not_fit_in_memory MY_ATTRIBUTE ((unused)))1862 pars_create_table(
1863 /*==============*/
1864 	sym_node_t*	table_sym,	/*!< in: table name node in the symbol
1865 					table */
1866 	sym_node_t*	column_defs,	/*!< in: list of column names */
1867 	sym_node_t*	compact,	/* in: non-NULL if COMPACT table. */
1868 	sym_node_t*	block_size,	/* in: block size (can be NULL) */
1869 	void*		not_fit_in_memory MY_ATTRIBUTE((unused)))
1870 					/*!< in: a non-NULL pointer means that
1871 					this is a table which in simulations
1872 					should be simulated as not fitting
1873 					in memory; thread is put to sleep
1874 					to simulate disk accesses; NOTE that
1875 					this flag is not stored to the data
1876 					dictionary on disk, and the database
1877 					will forget about non-NULL value if
1878 					it has to reload the table definition
1879 					from disk */
1880 {
1881 	dict_table_t*	table;
1882 	sym_node_t*	column;
1883 	tab_node_t*	node;
1884 	const dtype_t*	dtype;
1885 	ulint		n_cols;
1886 	ulint		flags = 0;
1887 	ulint		flags2 = 0;
1888 
1889 	if (compact != NULL) {
1890 
1891 		/* System tables currently only use the REDUNDANT row
1892 		format therefore the check for srv_file_per_table should be
1893 		safe for now. */
1894 
1895 		flags |= DICT_TF_COMPACT;
1896 
1897 		/* FIXME: Ideally this should be part of the SQL syntax
1898 		or use some other mechanism. We want to reduce dependency
1899 		on global variables. There is an inherent race here but
1900 		that has always existed around this variable. */
1901 		if (srv_file_per_table) {
1902 			flags2 |= DICT_TF2_USE_FILE_PER_TABLE;
1903 		}
1904 	}
1905 
1906 	if (block_size != NULL) {
1907 		ulint		size;
1908 		dfield_t*	dfield;
1909 
1910 		dfield = que_node_get_val(block_size);
1911 
1912 		ut_a(dfield_get_len(dfield) == 4);
1913 		size = mach_read_from_4(static_cast<byte*>(
1914 			dfield_get_data(dfield)));
1915 
1916 
1917 		switch (size) {
1918 		case 0:
1919 			break;
1920 
1921 		case 1: case 2: case 4: case 8: case 16:
1922 			flags |= DICT_TF_COMPACT;
1923 			/* FTS-FIXME: needs the zip changes */
1924 			/* flags |= size << DICT_TF_COMPRESSED_SHIFT; */
1925 			break;
1926 
1927 		default:
1928 			ut_error;
1929 		}
1930 	}
1931 
1932 	/* Set the flags2 when create table or alter tables */
1933 	flags2 |= DICT_TF2_FTS_AUX_HEX_NAME;
1934 	DBUG_EXECUTE_IF("innodb_test_wrong_fts_aux_table_name",
1935 			flags2 &= ~DICT_TF2_FTS_AUX_HEX_NAME;);
1936 
1937 
1938 	n_cols = que_node_list_get_len(column_defs);
1939 
1940 	table = dict_mem_table_create(
1941 		table_sym->name, 0, n_cols, 0, flags, flags2);
1942 
1943 #ifdef UNIV_DEBUG
1944 	if (not_fit_in_memory != NULL) {
1945 		table->does_not_fit_in_memory = TRUE;
1946 	}
1947 #endif /* UNIV_DEBUG */
1948 	column = column_defs;
1949 
1950 	while (column) {
1951 		dtype = dfield_get_type(que_node_get_val(column));
1952 
1953 		dict_mem_table_add_col(table, table->heap,
1954 				       column->name, dtype->mtype,
1955 				       dtype->prtype, dtype->len);
1956 		column->resolved = TRUE;
1957 		column->token_type = SYM_COLUMN;
1958 
1959 		column = static_cast<sym_node_t*>(que_node_get_next(column));
1960 	}
1961 
1962 	node = tab_create_graph_create(table, pars_sym_tab_global->heap, FIL_ENCRYPTION_DEFAULT, CreateInfoEncryptionKeyId());
1963 
1964 	table_sym->resolved = TRUE;
1965 	table_sym->token_type = SYM_TABLE;
1966 
1967 	return(node);
1968 }
1969 
1970 /*********************************************************************//**
1971 Parses an index creation operation.
1972 @return index create subgraph */
1973 ind_node_t*
pars_create_index(pars_res_word_t * unique_def,pars_res_word_t * clustered_def,sym_node_t * index_sym,sym_node_t * table_sym,sym_node_t * column_list)1974 pars_create_index(
1975 /*==============*/
1976 	pars_res_word_t* unique_def,	/*!< in: not NULL if a unique index */
1977 	pars_res_word_t* clustered_def,	/*!< in: not NULL if a clustered index */
1978 	sym_node_t*	index_sym,	/*!< in: index name node in the symbol
1979 					table */
1980 	sym_node_t*	table_sym,	/*!< in: table name node in the symbol
1981 					table */
1982 	sym_node_t*	column_list)	/*!< in: list of column names */
1983 {
1984 	dict_index_t*	index;
1985 	sym_node_t*	column;
1986 	ind_node_t*	node;
1987 	ulint		n_fields;
1988 	ulint		ind_type;
1989 
1990 	n_fields = que_node_list_get_len(column_list);
1991 
1992 	ind_type = 0;
1993 
1994 	if (unique_def) {
1995 		ind_type = ind_type | DICT_UNIQUE;
1996 	}
1997 
1998 	if (clustered_def) {
1999 		ind_type = ind_type | DICT_CLUSTERED;
2000 	}
2001 
2002 	index = dict_mem_index_create(table_sym->name, index_sym->name, 0,
2003 				      ind_type, n_fields);
2004 	column = column_list;
2005 
2006 	while (column) {
2007 		dict_mem_index_add_field(index, column->name, 0);
2008 
2009 		column->resolved = TRUE;
2010 		column->token_type = SYM_COLUMN;
2011 
2012 		column = static_cast<sym_node_t*>(que_node_get_next(column));
2013 	}
2014 
2015 	node = ind_create_graph_create(index, pars_sym_tab_global->heap, NULL);
2016 
2017 	table_sym->resolved = TRUE;
2018 	table_sym->token_type = SYM_TABLE;
2019 
2020 	index_sym->resolved = TRUE;
2021 	index_sym->token_type = SYM_TABLE;
2022 
2023 	return(node);
2024 }
2025 
2026 /*********************************************************************//**
2027 Parses a procedure definition.
2028 @return query fork node */
2029 que_fork_t*
pars_procedure_definition(sym_node_t * sym_node,sym_node_t * param_list,que_node_t * stat_list)2030 pars_procedure_definition(
2031 /*======================*/
2032 	sym_node_t*	sym_node,	/*!< in: procedure id node in the symbol
2033 					table */
2034 	sym_node_t*	param_list,	/*!< in: parameter declaration list */
2035 	que_node_t*	stat_list)	/*!< in: statement list */
2036 {
2037 	proc_node_t*	node;
2038 	que_fork_t*	fork;
2039 	que_thr_t*	thr;
2040 	mem_heap_t*	heap;
2041 
2042 	heap = pars_sym_tab_global->heap;
2043 
2044 	fork = que_fork_create(NULL, NULL, QUE_FORK_PROCEDURE, heap);
2045 	fork->trx = NULL;
2046 
2047 	thr = que_thr_create(fork, heap, NULL);
2048 
2049 	node = static_cast<proc_node_t*>(
2050 		mem_heap_alloc(heap, sizeof(proc_node_t)));
2051 
2052 	node->common.type = QUE_NODE_PROC;
2053 	node->common.parent = thr;
2054 
2055 	sym_node->token_type = SYM_PROCEDURE_NAME;
2056 	sym_node->resolved = TRUE;
2057 
2058 	node->proc_id = sym_node;
2059 	node->param_list = param_list;
2060 	node->stat_list = stat_list;
2061 
2062 	pars_set_parent_in_list(stat_list, node);
2063 
2064 	node->sym_tab = pars_sym_tab_global;
2065 
2066 	thr->child = node;
2067 
2068 	pars_sym_tab_global->query_graph = fork;
2069 
2070 	return(fork);
2071 }
2072 
2073 /*************************************************************//**
2074 Parses a stored procedure call, when this is not within another stored
2075 procedure, that is, the client issues a procedure call directly.
2076 In MySQL/InnoDB, stored InnoDB procedures are invoked via the
2077 parsed procedure tree, not via InnoDB SQL, so this function is not used.
2078 @return query graph */
2079 que_fork_t*
pars_stored_procedure_call(sym_node_t * sym_node MY_ATTRIBUTE ((unused)))2080 pars_stored_procedure_call(
2081 /*=======================*/
2082 	sym_node_t*	sym_node MY_ATTRIBUTE((unused)))
2083 					/*!< in: stored procedure name */
2084 {
2085 	ut_error;
2086 	return(NULL);
2087 }
2088 
2089 /*************************************************************//**
2090 Retrieves characters to the lexical analyzer. */
2091 int
pars_get_lex_chars(char * buf,int max_size)2092 pars_get_lex_chars(
2093 /*===============*/
2094 	char*	buf,		/*!< in/out: buffer where to copy */
2095 	int	max_size)	/*!< in: maximum number of characters which fit
2096 				in the buffer */
2097 {
2098 	int	len;
2099 
2100 	len = static_cast<int>(
2101 		pars_sym_tab_global->string_len
2102 		- pars_sym_tab_global->next_char_pos);
2103 	if (len == 0) {
2104 		return(0);
2105 	}
2106 
2107 	if (len > max_size) {
2108 		len = max_size;
2109 	}
2110 
2111 	ut_memcpy(buf, pars_sym_tab_global->sql_string
2112 		  + pars_sym_tab_global->next_char_pos, len);
2113 
2114 	pars_sym_tab_global->next_char_pos += len;
2115 
2116 	return(len);
2117 }
2118 
2119 /*************************************************************//**
2120 Called by yyparse on error. */
2121 void
yyerror(const char * s MY_ATTRIBUTE ((unused)))2122 yyerror(
2123 /*====*/
2124 	const char*	s MY_ATTRIBUTE((unused)))
2125 				/*!< in: error message string */
2126 {
2127 	ut_ad(s);
2128 
2129 	ib::fatal() << "PARSER: Syntax error in SQL string";
2130 }
2131 
2132 /*************************************************************//**
2133 Parses an SQL string returning the query graph.
2134 @return own: the query graph */
2135 que_t*
pars_sql(pars_info_t * info,const char * str)2136 pars_sql(
2137 /*=====*/
2138 	pars_info_t*	info,	/*!< in: extra information, or NULL */
2139 	const char*	str)	/*!< in: SQL string */
2140 {
2141 	sym_node_t*	sym_node;
2142 	mem_heap_t*	heap;
2143 	que_t*		graph;
2144 
2145 	ut_ad(str);
2146 
2147 	heap = mem_heap_create(16000);
2148 
2149 	/* Currently, the parser is not reentrant: */
2150 	ut_ad(mutex_own(&dict_sys->mutex));
2151 
2152 	pars_sym_tab_global = sym_tab_create(heap);
2153 
2154 	pars_sym_tab_global->string_len = strlen(str);
2155 	pars_sym_tab_global->sql_string = static_cast<char*>(
2156 		mem_heap_dup(heap, str, pars_sym_tab_global->string_len + 1));
2157 	pars_sym_tab_global->next_char_pos = 0;
2158 	pars_sym_tab_global->info = info;
2159 
2160 	yyparse();
2161 
2162 	sym_node = UT_LIST_GET_FIRST(pars_sym_tab_global->sym_list);
2163 
2164 	while (sym_node) {
2165 		ut_a(sym_node->resolved);
2166 
2167 		sym_node = UT_LIST_GET_NEXT(sym_list, sym_node);
2168 	}
2169 
2170 	graph = pars_sym_tab_global->query_graph;
2171 
2172 	graph->sym_tab = pars_sym_tab_global;
2173 	graph->info = info;
2174 
2175 	pars_sym_tab_global = NULL;
2176 
2177 	/* fprintf(stderr, "SQL graph size %lu\n", mem_heap_get_size(heap)); */
2178 
2179 	return(graph);
2180 }
2181 
2182 /** Completes a query graph by adding query thread and fork nodes
2183 above it and prepares the graph for running. The fork created is of
2184 type QUE_FORK_MYSQL_INTERFACE.
2185 @param[in]	node		root node for an incomplete query
2186 				graph, or NULL for dummy graph
2187 @param[in]	trx		transaction handle
2188 @param[in]	heap		memory heap from which allocated
2189 @param[in]	prebuilt	row prebuilt structure
2190 @return query thread node to run */
2191 que_thr_t*
pars_complete_graph_for_exec(que_node_t * node,trx_t * trx,mem_heap_t * heap,row_prebuilt_t * prebuilt)2192 pars_complete_graph_for_exec(
2193 	que_node_t*	node,
2194 	trx_t*		trx,
2195 	mem_heap_t*	heap,
2196 	row_prebuilt_t*	prebuilt)
2197 {
2198 	que_fork_t*	fork;
2199 	que_thr_t*	thr;
2200 
2201 	fork = que_fork_create(NULL, NULL, QUE_FORK_MYSQL_INTERFACE, heap);
2202 	fork->trx = trx;
2203 
2204 	thr = que_thr_create(fork, heap, prebuilt);
2205 
2206 	thr->child = node;
2207 
2208 	if (node) {
2209 		que_node_set_parent(node, thr);
2210 	}
2211 
2212 	trx->graph = NULL;
2213 
2214 	return(thr);
2215 }
2216 
2217 /****************************************************************//**
2218 Create parser info struct.
2219 @return own: info struct */
2220 pars_info_t*
pars_info_create(void)2221 pars_info_create(void)
2222 /*==================*/
2223 {
2224 	pars_info_t*	info;
2225 	mem_heap_t*	heap;
2226 
2227 	heap = mem_heap_create(512);
2228 
2229 	info = static_cast<pars_info_t*>(mem_heap_alloc(heap, sizeof(*info)));
2230 
2231 	info->heap = heap;
2232 	info->funcs = NULL;
2233 	info->bound_lits = NULL;
2234 	info->bound_ids = NULL;
2235 	info->graph_owns_us = TRUE;
2236 
2237 	return(info);
2238 }
2239 
2240 /****************************************************************//**
2241 Free info struct and everything it contains. */
2242 void
pars_info_free(pars_info_t * info)2243 pars_info_free(
2244 /*===========*/
2245 	pars_info_t*	info)	/*!< in, own: info struct */
2246 {
2247 	mem_heap_free(info->heap);
2248 }
2249 
2250 /****************************************************************//**
2251 Add bound literal. */
2252 void
pars_info_add_literal(pars_info_t * info,const char * name,const void * address,ulint length,ulint type,ulint prtype)2253 pars_info_add_literal(
2254 /*==================*/
2255 	pars_info_t*	info,		/*!< in: info struct */
2256 	const char*	name,		/*!< in: name */
2257 	const void*	address,	/*!< in: address */
2258 	ulint		length,		/*!< in: length of data */
2259 	ulint		type,		/*!< in: type, e.g. DATA_FIXBINARY */
2260 	ulint		prtype)		/*!< in: precise type, e.g.
2261 					DATA_UNSIGNED */
2262 {
2263 	pars_bound_lit_t*	pbl;
2264 
2265 	ut_ad(!pars_info_get_bound_lit(info, name));
2266 
2267 	pbl = static_cast<pars_bound_lit_t*>(
2268 		mem_heap_alloc(info->heap, sizeof(*pbl)));
2269 
2270 	pbl->name = name;
2271 
2272 	pbl->address = address;
2273 	pbl->length = length;
2274 	pbl->type = type;
2275 	pbl->prtype = prtype;
2276 
2277 	if (!info->bound_lits) {
2278 		ib_alloc_t*     heap_alloc;
2279 
2280 		heap_alloc = ib_heap_allocator_create(info->heap);
2281 
2282 		info->bound_lits = ib_vector_create(heap_alloc, sizeof(*pbl), 8);
2283 	}
2284 
2285 	ib_vector_push(info->bound_lits, pbl);
2286 }
2287 
2288 /****************************************************************//**
2289 Equivalent to pars_info_add_literal(info, name, str, strlen(str),
2290 DATA_VARCHAR, DATA_ENGLISH). */
2291 void
pars_info_add_str_literal(pars_info_t * info,const char * name,const char * str)2292 pars_info_add_str_literal(
2293 /*======================*/
2294 	pars_info_t*	info,		/*!< in: info struct */
2295 	const char*	name,		/*!< in: name */
2296 	const char*	str)		/*!< in: string */
2297 {
2298 	pars_info_add_literal(info, name, str, strlen(str),
2299 			      DATA_VARCHAR, DATA_ENGLISH);
2300 }
2301 
2302 /********************************************************************
2303 If the literal value already exists then it rebinds otherwise it
2304 creates a new entry.*/
2305 void
pars_info_bind_literal(pars_info_t * info,const char * name,const void * address,ulint length,ulint type,ulint prtype)2306 pars_info_bind_literal(
2307 /*===================*/
2308 	pars_info_t*	info,		/* in: info struct */
2309 	const char*	name,		/* in: name */
2310 	const void*	address,	/* in: address */
2311 	ulint		length,		/* in: length of data */
2312 	ulint		type,		/* in: type, e.g. DATA_FIXBINARY */
2313 	ulint		prtype)		/* in: precise type, e.g. */
2314 {
2315 	pars_bound_lit_t*	pbl;
2316 
2317 	pbl = pars_info_lookup_bound_lit(info, name);
2318 
2319 	if (!pbl) {
2320 		pars_info_add_literal(
2321 			info, name, address, length, type, prtype);
2322 	} else {
2323 		pbl->address = address;
2324 		pbl->length = length;
2325 
2326 		sym_tab_rebind_lit(pbl->node, address, length);
2327 	}
2328 }
2329 
2330 /********************************************************************
2331 If the literal value already exists then it rebinds otherwise it
2332 creates a new entry.*/
2333 void
pars_info_bind_varchar_literal(pars_info_t * info,const char * name,const byte * str,ulint str_len)2334 pars_info_bind_varchar_literal(
2335 /*===========================*/
2336 	pars_info_t*	info,		/*!< in: info struct */
2337 	const char*	name,		/*!< in: name */
2338 	const byte*	str,		/*!< in: string */
2339 	ulint		str_len)	/*!< in: string length */
2340 {
2341 	pars_bound_lit_t*	pbl;
2342 
2343 	pbl = pars_info_lookup_bound_lit(info, name);
2344 
2345 	if (!pbl) {
2346 		pars_info_add_literal(
2347 			info, name, str, str_len, DATA_VARCHAR, DATA_ENGLISH);
2348 	} else {
2349 
2350 		pbl->address = str;
2351 		pbl->length = str_len;
2352 
2353 		sym_tab_rebind_lit(pbl->node, str, str_len);
2354 	}
2355 }
2356 
2357 /****************************************************************//**
2358 Equivalent to:
2359 
2360 char buf[4];
2361 mach_write_to_4(buf, val);
2362 pars_info_add_literal(info, name, buf, 4, DATA_INT, 0);
2363 
2364 except that the buffer is dynamically allocated from the info struct's
2365 heap. */
2366 void
pars_info_add_int4_literal(pars_info_t * info,const char * name,lint val)2367 pars_info_add_int4_literal(
2368 /*=======================*/
2369 	pars_info_t*	info,		/*!< in: info struct */
2370 	const char*	name,		/*!< in: name */
2371 	lint		val)		/*!< in: value */
2372 {
2373 	byte*	buf = static_cast<byte*>(mem_heap_alloc(info->heap, 4));
2374 
2375 	mach_write_to_4(buf, val);
2376 	pars_info_add_literal(info, name, buf, 4, DATA_INT, 0);
2377 }
2378 
2379 /********************************************************************
2380 If the literal value already exists then it rebinds otherwise it
2381 creates a new entry. */
2382 void
pars_info_bind_int4_literal(pars_info_t * info,const char * name,const ib_uint32_t * val)2383 pars_info_bind_int4_literal(
2384 /*========================*/
2385 	pars_info_t*		info,   /* in: info struct */
2386 	const char*		name,   /* in: name */
2387 	const ib_uint32_t*	val)    /* in: value */
2388 {
2389 	pars_bound_lit_t*       pbl;
2390 
2391 	pbl = pars_info_lookup_bound_lit(info, name);
2392 
2393 	if (!pbl) {
2394 		pars_info_add_literal(info, name, val, 4, DATA_INT, 0);
2395 	} else {
2396 
2397 		pbl->address = val;
2398 		pbl->length = sizeof(*val);
2399 
2400 		sym_tab_rebind_lit(pbl->node, val, sizeof(*val));
2401 	}
2402 }
2403 
2404 /********************************************************************
2405 If the literal value already exists then it rebinds otherwise it
2406 creates a new entry. */
2407 void
pars_info_bind_int8_literal(pars_info_t * info,const char * name,const ib_uint64_t * val)2408 pars_info_bind_int8_literal(
2409 /*========================*/
2410 	pars_info_t*		info,	/* in: info struct */
2411 	const char*		name,	/* in: name */
2412 	const ib_uint64_t*	val)	/* in: value */
2413 {
2414 	pars_bound_lit_t*	pbl;
2415 
2416 	pbl = pars_info_lookup_bound_lit(info, name);
2417 
2418 	if (!pbl) {
2419 		pars_info_add_literal(
2420 			info, name, val, sizeof(*val), DATA_INT, 0);
2421 	} else {
2422 
2423 		pbl->address = val;
2424 		pbl->length = sizeof(*val);
2425 
2426 		sym_tab_rebind_lit(pbl->node, val, sizeof(*val));
2427 	}
2428 }
2429 
2430 /****************************************************************//**
2431 Equivalent to:
2432 
2433 char buf[8];
2434 mach_write_to_8(buf, val);
2435 pars_info_add_literal(info, name, buf, 8, DATA_FIXBINARY, 0);
2436 
2437 except that the buffer is dynamically allocated from the info struct's
2438 heap. */
2439 void
pars_info_add_ull_literal(pars_info_t * info,const char * name,ib_uint64_t val)2440 pars_info_add_ull_literal(
2441 /*======================*/
2442 	pars_info_t*	info,		/*!< in: info struct */
2443 	const char*	name,		/*!< in: name */
2444 	ib_uint64_t	val)		/*!< in: value */
2445 {
2446 	byte*	buf = static_cast<byte*>(mem_heap_alloc(info->heap, 8));
2447 
2448 	mach_write_to_8(buf, val);
2449 
2450 	pars_info_add_literal(info, name, buf, 8, DATA_FIXBINARY, 0);
2451 }
2452 
2453 /****************************************************************//**
2454 If the literal value already exists then it rebinds otherwise it
2455 creates a new entry. */
2456 void
pars_info_bind_ull_literal(pars_info_t * info,const char * name,const ib_uint64_t * val)2457 pars_info_bind_ull_literal(
2458 /*=======================*/
2459 	pars_info_t*		info,		/*!< in: info struct */
2460 	const char*		name,		/*!< in: name */
2461 	const ib_uint64_t*	val)		/*!< in: value */
2462 {
2463 	pars_bound_lit_t*	pbl;
2464 
2465 	pbl = pars_info_lookup_bound_lit(info, name);
2466 
2467 	if (!pbl) {
2468 		pars_info_add_literal(
2469 			info, name, val, sizeof(*val), DATA_FIXBINARY, 0);
2470 	} else {
2471 
2472 		pbl->address = val;
2473 		pbl->length = sizeof(*val);
2474 
2475 		sym_tab_rebind_lit(pbl->node, val, sizeof(*val));
2476 	}
2477 }
2478 
2479 /****************************************************************//**
2480 Add user function. */
2481 void
pars_info_bind_function(pars_info_t * info,const char * name,pars_user_func_cb_t func,void * arg)2482 pars_info_bind_function(
2483 /*====================*/
2484 	pars_info_t*		info,	/*!< in: info struct */
2485 	const char*		name,	/*!< in: function name */
2486 	pars_user_func_cb_t	func,	/*!< in: function address */
2487 	void*			arg)	/*!< in: user-supplied argument */
2488 {
2489 	pars_user_func_t*	puf;
2490 
2491 	puf = pars_info_lookup_user_func(info, name);
2492 
2493 	if (!puf) {
2494 		if (!info->funcs) {
2495 			ib_alloc_t*     heap_alloc;
2496 
2497 			heap_alloc = ib_heap_allocator_create(info->heap);
2498 
2499 			info->funcs = ib_vector_create(
2500 				heap_alloc, sizeof(*puf), 8);
2501 		}
2502 
2503 		/* Create a "new" element */
2504 		puf = static_cast<pars_user_func_t*>(
2505 			ib_vector_push(info->funcs, NULL));
2506 		puf->name = name;
2507 	}
2508 
2509 	puf->arg = arg;
2510 	puf->func = func;
2511 }
2512 
2513 /********************************************************************
2514 Add bound id. */
2515 void
pars_info_bind_id(pars_info_t * info,ibool copy_name,const char * name,const char * id)2516 pars_info_bind_id(
2517 /*==============*/
2518 	pars_info_t*	info,		/*!< in: info struct */
2519 	ibool		copy_name,	/* in: copy name if TRUE */
2520 	const char*	name,		/*!< in: name */
2521 	const char*	id)		/*!< in: id */
2522 {
2523 	pars_bound_id_t*	bid;
2524 
2525 	bid = pars_info_lookup_bound_id(info, name);
2526 
2527 	if (!bid) {
2528 
2529 		if (!info->bound_ids) {
2530 			ib_alloc_t*     heap_alloc;
2531 
2532 			heap_alloc = ib_heap_allocator_create(info->heap);
2533 
2534 			info->bound_ids = ib_vector_create(
2535 				heap_alloc, sizeof(*bid), 8);
2536 		}
2537 
2538 		/* Create a "new" element */
2539 		bid = static_cast<pars_bound_id_t*>(
2540 			ib_vector_push(info->bound_ids, NULL));
2541 
2542 		bid->name = (copy_name)
2543 		    ? mem_heap_strdup(info->heap, name) : name;
2544 	}
2545 
2546 	bid->id = id;
2547 }
2548 
2549 /********************************************************************
2550 Get bound identifier with the given name.*/
2551 pars_bound_id_t*
pars_info_get_bound_id(pars_info_t * info,const char * name)2552 pars_info_get_bound_id(
2553 /*===================*/
2554 					/* out: bound id, or NULL if not
2555 					found */
2556 	pars_info_t*		info,	/* in: info struct */
2557 	const char*		name)	/* in: bound id name to find */
2558 {
2559 	return(pars_info_lookup_bound_id(info, name));
2560 }
2561 
2562 /****************************************************************//**
2563 Get bound literal with the given name.
2564 @return bound literal, or NULL if not found */
2565 pars_bound_lit_t*
pars_info_get_bound_lit(pars_info_t * info,const char * name)2566 pars_info_get_bound_lit(
2567 /*====================*/
2568 	pars_info_t*		info,	/*!< in: info struct */
2569 	const char*		name)	/*!< in: bound literal name to find */
2570 {
2571 	return(pars_info_lookup_bound_lit(info, name));
2572 }
2573