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