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