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