mySQL 5.0.11 sources for tomato
[tomato.git] / release / src / router / mysql / storage / innodb_plugin / pars / pars0pars.c
blob578ff0dc062a73f8c8bdd84f409be32772fec5bb
1 /*****************************************************************************
3 Copyright (c) 1996, 2009, Innobase Oy. All Rights Reserved.
5 This program is free software; you can redistribute it and/or modify it under
6 the terms of the GNU General Public License as published by the Free Software
7 Foundation; version 2 of the License.
9 This program is distributed in the hope that it will be useful, but WITHOUT
10 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
11 FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
13 You should have received a copy of the GNU General Public License along with
14 this program; if not, write to the Free Software Foundation, Inc.,
15 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
17 *****************************************************************************/
19 /**************************************************//**
20 @file pars/pars0pars.c
21 SQL parser
23 Created 11/19/1996 Heikki Tuuri
24 *******************************************************/
26 /* Historical note: Innobase executed its first SQL string (CREATE TABLE)
27 on 1/27/1998 */
29 #include "pars0pars.h"
31 #ifdef UNIV_NONINL
32 #include "pars0pars.ic"
33 #endif
35 #include "row0sel.h"
36 #include "row0ins.h"
37 #include "row0upd.h"
38 #include "dict0dict.h"
39 #include "dict0mem.h"
40 #include "dict0crea.h"
41 #include "que0que.h"
42 #include "pars0grm.h"
43 #include "pars0opt.h"
44 #include "data0data.h"
45 #include "data0type.h"
46 #include "trx0trx.h"
47 #include "trx0roll.h"
48 #include "lock0lock.h"
49 #include "eval0eval.h"
51 #ifdef UNIV_SQL_DEBUG
52 /** If the following is set TRUE, the lexer will print the SQL string
53 as it tokenizes it */
54 UNIV_INTERN ibool pars_print_lexed = FALSE;
55 #endif /* UNIV_SQL_DEBUG */
57 /* Global variable used while parsing a single procedure or query : the code is
58 NOT re-entrant */
59 UNIV_INTERN sym_tab_t* pars_sym_tab_global;
61 /* Global variables used to denote certain reserved words, used in
62 constructing the parsing tree */
64 UNIV_INTERN pars_res_word_t pars_to_char_token = {PARS_TO_CHAR_TOKEN};
65 UNIV_INTERN pars_res_word_t pars_to_number_token = {PARS_TO_NUMBER_TOKEN};
66 UNIV_INTERN pars_res_word_t pars_to_binary_token = {PARS_TO_BINARY_TOKEN};
67 UNIV_INTERN pars_res_word_t pars_binary_to_number_token = {PARS_BINARY_TO_NUMBER_TOKEN};
68 UNIV_INTERN pars_res_word_t pars_substr_token = {PARS_SUBSTR_TOKEN};
69 UNIV_INTERN pars_res_word_t pars_replstr_token = {PARS_REPLSTR_TOKEN};
70 UNIV_INTERN pars_res_word_t pars_concat_token = {PARS_CONCAT_TOKEN};
71 UNIV_INTERN pars_res_word_t pars_instr_token = {PARS_INSTR_TOKEN};
72 UNIV_INTERN pars_res_word_t pars_length_token = {PARS_LENGTH_TOKEN};
73 UNIV_INTERN pars_res_word_t pars_sysdate_token = {PARS_SYSDATE_TOKEN};
74 UNIV_INTERN pars_res_word_t pars_printf_token = {PARS_PRINTF_TOKEN};
75 UNIV_INTERN pars_res_word_t pars_assert_token = {PARS_ASSERT_TOKEN};
76 UNIV_INTERN pars_res_word_t pars_rnd_token = {PARS_RND_TOKEN};
77 UNIV_INTERN pars_res_word_t pars_rnd_str_token = {PARS_RND_STR_TOKEN};
78 UNIV_INTERN pars_res_word_t pars_count_token = {PARS_COUNT_TOKEN};
79 UNIV_INTERN pars_res_word_t pars_sum_token = {PARS_SUM_TOKEN};
80 UNIV_INTERN pars_res_word_t pars_distinct_token = {PARS_DISTINCT_TOKEN};
81 UNIV_INTERN pars_res_word_t pars_binary_token = {PARS_BINARY_TOKEN};
82 UNIV_INTERN pars_res_word_t pars_blob_token = {PARS_BLOB_TOKEN};
83 UNIV_INTERN pars_res_word_t pars_int_token = {PARS_INT_TOKEN};
84 UNIV_INTERN pars_res_word_t pars_char_token = {PARS_CHAR_TOKEN};
85 UNIV_INTERN pars_res_word_t pars_float_token = {PARS_FLOAT_TOKEN};
86 UNIV_INTERN pars_res_word_t pars_update_token = {PARS_UPDATE_TOKEN};
87 UNIV_INTERN pars_res_word_t pars_asc_token = {PARS_ASC_TOKEN};
88 UNIV_INTERN pars_res_word_t pars_desc_token = {PARS_DESC_TOKEN};
89 UNIV_INTERN pars_res_word_t pars_open_token = {PARS_OPEN_TOKEN};
90 UNIV_INTERN pars_res_word_t pars_close_token = {PARS_CLOSE_TOKEN};
91 UNIV_INTERN pars_res_word_t pars_share_token = {PARS_SHARE_TOKEN};
92 UNIV_INTERN pars_res_word_t pars_unique_token = {PARS_UNIQUE_TOKEN};
93 UNIV_INTERN pars_res_word_t pars_clustered_token = {PARS_CLUSTERED_TOKEN};
95 /** Global variable used to denote the '*' in SELECT * FROM.. */
96 UNIV_INTERN ulint pars_star_denoter = 12345678;
99 /*********************************************************************//**
100 Determines the class of a function code.
101 @return function class: PARS_FUNC_ARITH, ... */
102 static
103 ulint
104 pars_func_get_class(
105 /*================*/
106 int func) /*!< in: function code: '=', PARS_GE_TOKEN, ... */
108 switch (func) {
109 case '+': case '-': case '*': case '/':
110 return(PARS_FUNC_ARITH);
112 case '=': case '<': case '>':
113 case PARS_GE_TOKEN: case PARS_LE_TOKEN: case PARS_NE_TOKEN:
114 return(PARS_FUNC_CMP);
116 case PARS_AND_TOKEN: case PARS_OR_TOKEN: case PARS_NOT_TOKEN:
117 return(PARS_FUNC_LOGICAL);
119 case PARS_COUNT_TOKEN: case PARS_SUM_TOKEN:
120 return(PARS_FUNC_AGGREGATE);
122 case PARS_TO_CHAR_TOKEN:
123 case PARS_TO_NUMBER_TOKEN:
124 case PARS_TO_BINARY_TOKEN:
125 case PARS_BINARY_TO_NUMBER_TOKEN:
126 case PARS_SUBSTR_TOKEN:
127 case PARS_CONCAT_TOKEN:
128 case PARS_LENGTH_TOKEN:
129 case PARS_INSTR_TOKEN:
130 case PARS_SYSDATE_TOKEN:
131 case PARS_NOTFOUND_TOKEN:
132 case PARS_PRINTF_TOKEN:
133 case PARS_ASSERT_TOKEN:
134 case PARS_RND_TOKEN:
135 case PARS_RND_STR_TOKEN:
136 case PARS_REPLSTR_TOKEN:
137 return(PARS_FUNC_PREDEFINED);
139 default:
140 return(PARS_FUNC_OTHER);
144 /*********************************************************************//**
145 Parses an operator or predefined function expression.
146 @return own: function node in a query tree */
147 static
148 func_node_t*
149 pars_func_low(
150 /*==========*/
151 int func, /*!< in: function token code */
152 que_node_t* arg) /*!< in: first argument in the argument list */
154 func_node_t* node;
156 node = mem_heap_alloc(pars_sym_tab_global->heap, sizeof(func_node_t));
158 node->common.type = QUE_NODE_FUNC;
159 dfield_set_data(&(node->common.val), NULL, 0);
160 node->common.val_buf_size = 0;
162 node->func = func;
164 node->class = pars_func_get_class(func);
166 node->args = arg;
168 UT_LIST_ADD_LAST(func_node_list, pars_sym_tab_global->func_node_list,
169 node);
170 return(node);
173 /*********************************************************************//**
174 Parses a function expression.
175 @return own: function node in a query tree */
176 UNIV_INTERN
177 func_node_t*
178 pars_func(
179 /*======*/
180 que_node_t* res_word,/*!< in: function name reserved word */
181 que_node_t* arg) /*!< in: first argument in the argument list */
183 return(pars_func_low(((pars_res_word_t*)res_word)->code, arg));
186 /*********************************************************************//**
187 Parses an operator expression.
188 @return own: function node in a query tree */
189 UNIV_INTERN
190 func_node_t*
191 pars_op(
192 /*====*/
193 int func, /*!< in: operator token code */
194 que_node_t* arg1, /*!< in: first argument */
195 que_node_t* arg2) /*!< in: second argument or NULL for an unary
196 operator */
198 que_node_list_add_last(NULL, arg1);
200 if (arg2) {
201 que_node_list_add_last(arg1, arg2);
204 return(pars_func_low(func, arg1));
207 /*********************************************************************//**
208 Parses an ORDER BY clause. Order by a single column only is supported.
209 @return own: order-by node in a query tree */
210 UNIV_INTERN
211 order_node_t*
212 pars_order_by(
213 /*==========*/
214 sym_node_t* column, /*!< in: column name */
215 pars_res_word_t* asc) /*!< in: &pars_asc_token or pars_desc_token */
217 order_node_t* node;
219 node = mem_heap_alloc(pars_sym_tab_global->heap, sizeof(order_node_t));
221 node->common.type = QUE_NODE_ORDER;
223 node->column = column;
225 if (asc == &pars_asc_token) {
226 node->asc = TRUE;
227 } else {
228 ut_a(asc == &pars_desc_token);
229 node->asc = FALSE;
232 return(node);
235 /*********************************************************************//**
236 Determine if a data type is a built-in string data type of the InnoDB
237 SQL parser.
238 @return TRUE if string data type */
239 static
240 ibool
241 pars_is_string_type(
242 /*================*/
243 ulint mtype) /*!< in: main data type */
245 switch (mtype) {
246 case DATA_VARCHAR: case DATA_CHAR:
247 case DATA_FIXBINARY: case DATA_BINARY:
248 return(TRUE);
251 return(FALSE);
254 /*********************************************************************//**
255 Resolves the data type of a function in an expression. The argument data
256 types must already be resolved. */
257 static
258 void
259 pars_resolve_func_data_type(
260 /*========================*/
261 func_node_t* node) /*!< in: function node */
263 que_node_t* arg;
265 ut_a(que_node_get_type(node) == QUE_NODE_FUNC);
267 arg = node->args;
269 switch (node->func) {
270 case PARS_SUM_TOKEN:
271 case '+': case '-': case '*': case '/':
272 /* Inherit the data type from the first argument (which must
273 not be the SQL null literal whose type is DATA_ERROR) */
275 dtype_copy(que_node_get_data_type(node),
276 que_node_get_data_type(arg));
278 ut_a(dtype_get_mtype(que_node_get_data_type(node))
279 == DATA_INT);
280 break;
282 case PARS_COUNT_TOKEN:
283 ut_a(arg);
284 dtype_set(que_node_get_data_type(node), DATA_INT, 0, 4);
285 break;
287 case PARS_TO_CHAR_TOKEN:
288 case PARS_RND_STR_TOKEN:
289 ut_a(dtype_get_mtype(que_node_get_data_type(arg)) == DATA_INT);
290 dtype_set(que_node_get_data_type(node), DATA_VARCHAR,
291 DATA_ENGLISH, 0);
292 break;
294 case PARS_TO_BINARY_TOKEN:
295 if (dtype_get_mtype(que_node_get_data_type(arg)) == DATA_INT) {
296 dtype_set(que_node_get_data_type(node), DATA_VARCHAR,
297 DATA_ENGLISH, 0);
298 } else {
299 dtype_set(que_node_get_data_type(node), DATA_BINARY,
300 0, 0);
302 break;
304 case PARS_TO_NUMBER_TOKEN:
305 case PARS_BINARY_TO_NUMBER_TOKEN:
306 case PARS_LENGTH_TOKEN:
307 case PARS_INSTR_TOKEN:
308 ut_a(pars_is_string_type(que_node_get_data_type(arg)->mtype));
309 dtype_set(que_node_get_data_type(node), DATA_INT, 0, 4);
310 break;
312 case PARS_SYSDATE_TOKEN:
313 ut_a(arg == NULL);
314 dtype_set(que_node_get_data_type(node), DATA_INT, 0, 4);
315 break;
317 case PARS_SUBSTR_TOKEN:
318 case PARS_CONCAT_TOKEN:
319 ut_a(pars_is_string_type(que_node_get_data_type(arg)->mtype));
320 dtype_set(que_node_get_data_type(node), DATA_VARCHAR,
321 DATA_ENGLISH, 0);
322 break;
324 case '>': case '<': case '=':
325 case PARS_GE_TOKEN:
326 case PARS_LE_TOKEN:
327 case PARS_NE_TOKEN:
328 case PARS_AND_TOKEN:
329 case PARS_OR_TOKEN:
330 case PARS_NOT_TOKEN:
331 case PARS_NOTFOUND_TOKEN:
333 /* We currently have no iboolean type: use integer type */
334 dtype_set(que_node_get_data_type(node), DATA_INT, 0, 4);
335 break;
337 case PARS_RND_TOKEN:
338 ut_a(dtype_get_mtype(que_node_get_data_type(arg)) == DATA_INT);
339 dtype_set(que_node_get_data_type(node), DATA_INT, 0, 4);
340 break;
342 default:
343 ut_error;
347 /*********************************************************************//**
348 Resolves the meaning of variables in an expression and the data types of
349 functions. It is an error if some identifier cannot be resolved here. */
350 static
351 void
352 pars_resolve_exp_variables_and_types(
353 /*=================================*/
354 sel_node_t* select_node, /*!< in: select node or NULL; if
355 this is not NULL then the variable
356 sym nodes are added to the
357 copy_variables list of select_node */
358 que_node_t* exp_node) /*!< in: expression */
360 func_node_t* func_node;
361 que_node_t* arg;
362 sym_node_t* sym_node;
363 sym_node_t* node;
365 ut_a(exp_node);
367 if (que_node_get_type(exp_node) == QUE_NODE_FUNC) {
368 func_node = exp_node;
370 arg = func_node->args;
372 while (arg) {
373 pars_resolve_exp_variables_and_types(select_node, arg);
375 arg = que_node_get_next(arg);
378 pars_resolve_func_data_type(func_node);
380 return;
383 ut_a(que_node_get_type(exp_node) == QUE_NODE_SYMBOL);
385 sym_node = exp_node;
387 if (sym_node->resolved) {
389 return;
392 /* Not resolved yet: look in the symbol table for a variable
393 or a cursor or a function with the same name */
395 node = UT_LIST_GET_FIRST(pars_sym_tab_global->sym_list);
397 while (node) {
398 if (node->resolved
399 && ((node->token_type == SYM_VAR)
400 || (node->token_type == SYM_CURSOR)
401 || (node->token_type == SYM_FUNCTION))
402 && node->name
403 && (sym_node->name_len == node->name_len)
404 && (ut_memcmp(sym_node->name, node->name,
405 node->name_len) == 0)) {
407 /* Found a variable or a cursor declared with
408 the same name */
410 break;
413 node = UT_LIST_GET_NEXT(sym_list, node);
416 if (!node) {
417 fprintf(stderr, "PARSER ERROR: Unresolved identifier %s\n",
418 sym_node->name);
421 ut_a(node);
423 sym_node->resolved = TRUE;
424 sym_node->token_type = SYM_IMPLICIT_VAR;
425 sym_node->alias = node;
426 sym_node->indirection = node;
428 if (select_node) {
429 UT_LIST_ADD_LAST(col_var_list, select_node->copy_variables,
430 sym_node);
433 dfield_set_type(que_node_get_val(sym_node),
434 que_node_get_data_type(node));
437 /*********************************************************************//**
438 Resolves the meaning of variables in an expression list. It is an error if
439 some identifier cannot be resolved here. Resolves also the data types of
440 functions. */
441 static
442 void
443 pars_resolve_exp_list_variables_and_types(
444 /*======================================*/
445 sel_node_t* select_node, /*!< in: select node or NULL */
446 que_node_t* exp_node) /*!< in: expression list first node, or
447 NULL */
449 while (exp_node) {
450 pars_resolve_exp_variables_and_types(select_node, exp_node);
452 exp_node = que_node_get_next(exp_node);
456 /*********************************************************************//**
457 Resolves the columns in an expression. */
458 static
459 void
460 pars_resolve_exp_columns(
461 /*=====================*/
462 sym_node_t* table_node, /*!< in: first node in a table list */
463 que_node_t* exp_node) /*!< in: expression */
465 func_node_t* func_node;
466 que_node_t* arg;
467 sym_node_t* sym_node;
468 dict_table_t* table;
469 sym_node_t* t_node;
470 ulint n_cols;
471 ulint i;
473 ut_a(exp_node);
475 if (que_node_get_type(exp_node) == QUE_NODE_FUNC) {
476 func_node = exp_node;
478 arg = func_node->args;
480 while (arg) {
481 pars_resolve_exp_columns(table_node, arg);
483 arg = que_node_get_next(arg);
486 return;
489 ut_a(que_node_get_type(exp_node) == QUE_NODE_SYMBOL);
491 sym_node = exp_node;
493 if (sym_node->resolved) {
495 return;
498 /* Not resolved yet: look in the table list for a column with the
499 same name */
501 t_node = table_node;
503 while (t_node) {
504 table = t_node->table;
506 n_cols = dict_table_get_n_cols(table);
508 for (i = 0; i < n_cols; i++) {
509 const dict_col_t* col
510 = dict_table_get_nth_col(table, i);
511 const char* col_name
512 = dict_table_get_col_name(table, i);
514 if ((sym_node->name_len == ut_strlen(col_name))
515 && (0 == ut_memcmp(sym_node->name, col_name,
516 sym_node->name_len))) {
517 /* Found */
518 sym_node->resolved = TRUE;
519 sym_node->token_type = SYM_COLUMN;
520 sym_node->table = table;
521 sym_node->col_no = i;
522 sym_node->prefetch_buf = NULL;
524 dict_col_copy_type(
525 col,
526 dfield_get_type(&sym_node
527 ->common.val));
529 return;
533 t_node = que_node_get_next(t_node);
537 /*********************************************************************//**
538 Resolves the meaning of columns in an expression list. */
539 static
540 void
541 pars_resolve_exp_list_columns(
542 /*==========================*/
543 sym_node_t* table_node, /*!< in: first node in a table list */
544 que_node_t* exp_node) /*!< in: expression list first node, or
545 NULL */
547 while (exp_node) {
548 pars_resolve_exp_columns(table_node, exp_node);
550 exp_node = que_node_get_next(exp_node);
554 /*********************************************************************//**
555 Retrieves the table definition for a table name id. */
556 static
557 void
558 pars_retrieve_table_def(
559 /*====================*/
560 sym_node_t* sym_node) /*!< in: table node */
562 const char* table_name;
564 ut_a(sym_node);
565 ut_a(que_node_get_type(sym_node) == QUE_NODE_SYMBOL);
567 sym_node->resolved = TRUE;
568 sym_node->token_type = SYM_TABLE;
570 table_name = (const char*) sym_node->name;
572 sym_node->table = dict_table_get_low(table_name);
574 ut_a(sym_node->table);
577 /*********************************************************************//**
578 Retrieves the table definitions for a list of table name ids.
579 @return number of tables */
580 static
581 ulint
582 pars_retrieve_table_list_defs(
583 /*==========================*/
584 sym_node_t* sym_node) /*!< in: first table node in list */
586 ulint count = 0;
588 if (sym_node == NULL) {
590 return(count);
593 while (sym_node) {
594 pars_retrieve_table_def(sym_node);
596 count++;
598 sym_node = que_node_get_next(sym_node);
601 return(count);
604 /*********************************************************************//**
605 Adds all columns to the select list if the query is SELECT * FROM ... */
606 static
607 void
608 pars_select_all_columns(
609 /*====================*/
610 sel_node_t* select_node) /*!< in: select node already containing
611 the table list */
613 sym_node_t* col_node;
614 sym_node_t* table_node;
615 dict_table_t* table;
616 ulint i;
618 select_node->select_list = NULL;
620 table_node = select_node->table_list;
622 while (table_node) {
623 table = table_node->table;
625 for (i = 0; i < dict_table_get_n_user_cols(table); i++) {
626 const char* col_name = dict_table_get_col_name(
627 table, i);
629 col_node = sym_tab_add_id(pars_sym_tab_global,
630 (byte*)col_name,
631 ut_strlen(col_name));
633 select_node->select_list = que_node_list_add_last(
634 select_node->select_list, col_node);
637 table_node = que_node_get_next(table_node);
641 /*********************************************************************//**
642 Parses a select list; creates a query graph node for the whole SELECT
643 statement.
644 @return own: select node in a query tree */
645 UNIV_INTERN
646 sel_node_t*
647 pars_select_list(
648 /*=============*/
649 que_node_t* select_list, /*!< in: select list */
650 sym_node_t* into_list) /*!< in: variables list or NULL */
652 sel_node_t* node;
654 node = sel_node_create(pars_sym_tab_global->heap);
656 node->select_list = select_list;
657 node->into_list = into_list;
659 pars_resolve_exp_list_variables_and_types(NULL, into_list);
661 return(node);
664 /*********************************************************************//**
665 Checks if the query is an aggregate query, in which case the selct list must
666 contain only aggregate function items. */
667 static
668 void
669 pars_check_aggregate(
670 /*=================*/
671 sel_node_t* select_node) /*!< in: select node already containing
672 the select list */
674 que_node_t* exp_node;
675 func_node_t* func_node;
676 ulint n_nodes = 0;
677 ulint n_aggregate_nodes = 0;
679 exp_node = select_node->select_list;
681 while (exp_node) {
683 n_nodes++;
685 if (que_node_get_type(exp_node) == QUE_NODE_FUNC) {
687 func_node = exp_node;
689 if (func_node->class == PARS_FUNC_AGGREGATE) {
691 n_aggregate_nodes++;
695 exp_node = que_node_get_next(exp_node);
698 if (n_aggregate_nodes > 0) {
699 ut_a(n_nodes == n_aggregate_nodes);
701 select_node->is_aggregate = TRUE;
702 } else {
703 select_node->is_aggregate = FALSE;
707 /*********************************************************************//**
708 Parses a select statement.
709 @return own: select node in a query tree */
710 UNIV_INTERN
711 sel_node_t*
712 pars_select_statement(
713 /*==================*/
714 sel_node_t* select_node, /*!< in: select node already containing
715 the select list */
716 sym_node_t* table_list, /*!< in: table list */
717 que_node_t* search_cond, /*!< in: search condition or NULL */
718 pars_res_word_t* for_update, /*!< in: NULL or &pars_update_token */
719 pars_res_word_t* lock_shared, /*!< in: NULL or &pars_share_token */
720 order_node_t* order_by) /*!< in: NULL or an order-by node */
722 select_node->state = SEL_NODE_OPEN;
724 select_node->table_list = table_list;
725 select_node->n_tables = pars_retrieve_table_list_defs(table_list);
727 if (select_node->select_list == &pars_star_denoter) {
729 /* SELECT * FROM ... */
730 pars_select_all_columns(select_node);
733 if (select_node->into_list) {
734 ut_a(que_node_list_get_len(select_node->into_list)
735 == que_node_list_get_len(select_node->select_list));
738 UT_LIST_INIT(select_node->copy_variables);
740 pars_resolve_exp_list_columns(table_list, select_node->select_list);
741 pars_resolve_exp_list_variables_and_types(select_node,
742 select_node->select_list);
743 pars_check_aggregate(select_node);
745 select_node->search_cond = search_cond;
747 if (search_cond) {
748 pars_resolve_exp_columns(table_list, search_cond);
749 pars_resolve_exp_variables_and_types(select_node, search_cond);
752 if (for_update) {
753 ut_a(!lock_shared);
755 select_node->set_x_locks = TRUE;
756 select_node->row_lock_mode = LOCK_X;
758 select_node->consistent_read = FALSE;
759 select_node->read_view = NULL;
760 } else if (lock_shared){
761 select_node->set_x_locks = FALSE;
762 select_node->row_lock_mode = LOCK_S;
764 select_node->consistent_read = FALSE;
765 select_node->read_view = NULL;
766 } else {
767 select_node->set_x_locks = FALSE;
768 select_node->row_lock_mode = LOCK_S;
770 select_node->consistent_read = TRUE;
773 select_node->order_by = order_by;
775 if (order_by) {
776 pars_resolve_exp_columns(table_list, order_by->column);
779 /* The final value of the following fields depend on the environment
780 where the select statement appears: */
782 select_node->can_get_updated = FALSE;
783 select_node->explicit_cursor = NULL;
785 opt_search_plan(select_node);
787 return(select_node);
790 /*********************************************************************//**
791 Parses a cursor declaration.
792 @return sym_node */
793 UNIV_INTERN
794 que_node_t*
795 pars_cursor_declaration(
796 /*====================*/
797 sym_node_t* sym_node, /*!< in: cursor id node in the symbol
798 table */
799 sel_node_t* select_node) /*!< in: select node */
801 sym_node->resolved = TRUE;
802 sym_node->token_type = SYM_CURSOR;
803 sym_node->cursor_def = select_node;
805 select_node->state = SEL_NODE_CLOSED;
806 select_node->explicit_cursor = sym_node;
808 return(sym_node);
811 /*********************************************************************//**
812 Parses a function declaration.
813 @return sym_node */
814 UNIV_INTERN
815 que_node_t*
816 pars_function_declaration(
817 /*======================*/
818 sym_node_t* sym_node) /*!< in: function id node in the symbol
819 table */
821 sym_node->resolved = TRUE;
822 sym_node->token_type = SYM_FUNCTION;
824 /* Check that the function exists. */
825 ut_a(pars_info_get_user_func(pars_sym_tab_global->info,
826 sym_node->name));
828 return(sym_node);
831 /*********************************************************************//**
832 Parses a delete or update statement start.
833 @return own: update node in a query tree */
834 UNIV_INTERN
835 upd_node_t*
836 pars_update_statement_start(
837 /*========================*/
838 ibool is_delete, /*!< in: TRUE if delete */
839 sym_node_t* table_sym, /*!< in: table name node */
840 col_assign_node_t* col_assign_list)/*!< in: column assignment list, NULL
841 if delete */
843 upd_node_t* node;
845 node = upd_node_create(pars_sym_tab_global->heap);
847 node->is_delete = is_delete;
849 node->table_sym = table_sym;
850 node->col_assign_list = col_assign_list;
852 return(node);
855 /*********************************************************************//**
856 Parses a column assignment in an update.
857 @return column assignment node */
858 UNIV_INTERN
859 col_assign_node_t*
860 pars_column_assignment(
861 /*===================*/
862 sym_node_t* column, /*!< in: column to assign */
863 que_node_t* exp) /*!< in: value to assign */
865 col_assign_node_t* node;
867 node = mem_heap_alloc(pars_sym_tab_global->heap,
868 sizeof(col_assign_node_t));
869 node->common.type = QUE_NODE_COL_ASSIGNMENT;
871 node->col = column;
872 node->val = exp;
874 return(node);
877 /*********************************************************************//**
878 Processes an update node assignment list. */
879 static
880 void
881 pars_process_assign_list(
882 /*=====================*/
883 upd_node_t* node) /*!< in: update node */
885 col_assign_node_t* col_assign_list;
886 sym_node_t* table_sym;
887 col_assign_node_t* assign_node;
888 upd_field_t* upd_field;
889 dict_index_t* clust_index;
890 sym_node_t* col_sym;
891 ulint changes_ord_field;
892 ulint changes_field_size;
893 ulint n_assigns;
894 ulint i;
896 table_sym = node->table_sym;
897 col_assign_list = node->col_assign_list;
898 clust_index = dict_table_get_first_index(node->table);
900 assign_node = col_assign_list;
901 n_assigns = 0;
903 while (assign_node) {
904 pars_resolve_exp_columns(table_sym, assign_node->col);
905 pars_resolve_exp_columns(table_sym, assign_node->val);
906 pars_resolve_exp_variables_and_types(NULL, assign_node->val);
907 #if 0
908 ut_a(dtype_get_mtype(
909 dfield_get_type(que_node_get_val(
910 assign_node->col)))
911 == dtype_get_mtype(
912 dfield_get_type(que_node_get_val(
913 assign_node->val))));
914 #endif
916 /* Add to the update node all the columns found in assignment
917 values as columns to copy: therefore, TRUE */
919 opt_find_all_cols(TRUE, clust_index, &(node->columns), NULL,
920 assign_node->val);
921 n_assigns++;
923 assign_node = que_node_get_next(assign_node);
926 node->update = upd_create(n_assigns, pars_sym_tab_global->heap);
928 assign_node = col_assign_list;
930 changes_field_size = UPD_NODE_NO_SIZE_CHANGE;
932 for (i = 0; i < n_assigns; i++) {
933 upd_field = upd_get_nth_field(node->update, i);
935 col_sym = assign_node->col;
937 upd_field_set_field_no(upd_field, dict_index_get_nth_col_pos(
938 clust_index, col_sym->col_no),
939 clust_index, NULL);
940 upd_field->exp = assign_node->val;
942 if (!dict_col_get_fixed_size(
943 dict_index_get_nth_col(clust_index,
944 upd_field->field_no),
945 dict_table_is_comp(node->table))) {
946 changes_field_size = 0;
949 assign_node = que_node_get_next(assign_node);
952 /* Find out if the update can modify an ordering field in any index */
954 changes_ord_field = UPD_NODE_NO_ORD_CHANGE;
956 if (row_upd_changes_some_index_ord_field_binary(node->table,
957 node->update)) {
958 changes_ord_field = 0;
961 node->cmpl_info = changes_ord_field | changes_field_size;
964 /*********************************************************************//**
965 Parses an update or delete statement.
966 @return own: update node in a query tree */
967 UNIV_INTERN
968 upd_node_t*
969 pars_update_statement(
970 /*==================*/
971 upd_node_t* node, /*!< in: update node */
972 sym_node_t* cursor_sym, /*!< in: pointer to a cursor entry in
973 the symbol table or NULL */
974 que_node_t* search_cond) /*!< in: search condition or NULL */
976 sym_node_t* table_sym;
977 sel_node_t* sel_node;
978 plan_t* plan;
980 table_sym = node->table_sym;
982 pars_retrieve_table_def(table_sym);
983 node->table = table_sym->table;
985 UT_LIST_INIT(node->columns);
987 /* Make the single table node into a list of table nodes of length 1 */
989 que_node_list_add_last(NULL, table_sym);
991 if (cursor_sym) {
992 pars_resolve_exp_variables_and_types(NULL, cursor_sym);
994 sel_node = cursor_sym->alias->cursor_def;
996 node->searched_update = FALSE;
997 } else {
998 sel_node = pars_select_list(NULL, NULL);
1000 pars_select_statement(sel_node, table_sym, search_cond, NULL,
1001 &pars_share_token, NULL);
1002 node->searched_update = TRUE;
1003 sel_node->common.parent = node;
1006 node->select = sel_node;
1008 ut_a(!node->is_delete || (node->col_assign_list == NULL));
1009 ut_a(node->is_delete || (node->col_assign_list != NULL));
1011 if (node->is_delete) {
1012 node->cmpl_info = 0;
1013 } else {
1014 pars_process_assign_list(node);
1017 if (node->searched_update) {
1018 node->has_clust_rec_x_lock = TRUE;
1019 sel_node->set_x_locks = TRUE;
1020 sel_node->row_lock_mode = LOCK_X;
1021 } else {
1022 node->has_clust_rec_x_lock = sel_node->set_x_locks;
1025 ut_a(sel_node->n_tables == 1);
1026 ut_a(sel_node->consistent_read == FALSE);
1027 ut_a(sel_node->order_by == NULL);
1028 ut_a(sel_node->is_aggregate == FALSE);
1030 sel_node->can_get_updated = TRUE;
1032 node->state = UPD_NODE_UPDATE_CLUSTERED;
1034 plan = sel_node_get_nth_plan(sel_node, 0);
1036 plan->no_prefetch = TRUE;
1038 if (!dict_index_is_clust(plan->index)) {
1040 plan->must_get_clust = TRUE;
1042 node->pcur = &(plan->clust_pcur);
1043 } else {
1044 node->pcur = &(plan->pcur);
1047 return(node);
1050 /*********************************************************************//**
1051 Parses an insert statement.
1052 @return own: update node in a query tree */
1053 UNIV_INTERN
1054 ins_node_t*
1055 pars_insert_statement(
1056 /*==================*/
1057 sym_node_t* table_sym, /*!< in: table name node */
1058 que_node_t* values_list, /*!< in: value expression list or NULL */
1059 sel_node_t* select) /*!< in: select condition or NULL */
1061 ins_node_t* node;
1062 dtuple_t* row;
1063 ulint ins_type;
1065 ut_a(values_list || select);
1066 ut_a(!values_list || !select);
1068 if (values_list) {
1069 ins_type = INS_VALUES;
1070 } else {
1071 ins_type = INS_SEARCHED;
1074 pars_retrieve_table_def(table_sym);
1076 node = ins_node_create(ins_type, table_sym->table,
1077 pars_sym_tab_global->heap);
1079 row = dtuple_create(pars_sym_tab_global->heap,
1080 dict_table_get_n_cols(node->table));
1082 dict_table_copy_types(row, table_sym->table);
1084 ins_node_set_new_row(node, row);
1086 node->select = select;
1088 if (select) {
1089 select->common.parent = node;
1091 ut_a(que_node_list_get_len(select->select_list)
1092 == dict_table_get_n_user_cols(table_sym->table));
1095 node->values_list = values_list;
1097 if (node->values_list) {
1098 pars_resolve_exp_list_variables_and_types(NULL, values_list);
1100 ut_a(que_node_list_get_len(values_list)
1101 == dict_table_get_n_user_cols(table_sym->table));
1104 return(node);
1107 /*********************************************************************//**
1108 Set the type of a dfield. */
1109 static
1110 void
1111 pars_set_dfield_type(
1112 /*=================*/
1113 dfield_t* dfield, /*!< in: dfield */
1114 pars_res_word_t* type, /*!< in: pointer to a type
1115 token */
1116 ulint len, /*!< in: length, or 0 */
1117 ibool is_unsigned, /*!< in: if TRUE, column is
1118 UNSIGNED. */
1119 ibool is_not_null) /*!< in: if TRUE, column is
1120 NOT NULL. */
1122 ulint flags = 0;
1124 if (is_not_null) {
1125 flags |= DATA_NOT_NULL;
1128 if (is_unsigned) {
1129 flags |= DATA_UNSIGNED;
1132 if (type == &pars_int_token) {
1133 ut_a(len == 0);
1135 dtype_set(dfield_get_type(dfield), DATA_INT, flags, 4);
1137 } else if (type == &pars_char_token) {
1138 ut_a(len == 0);
1140 dtype_set(dfield_get_type(dfield), DATA_VARCHAR,
1141 DATA_ENGLISH | flags, 0);
1142 } else if (type == &pars_binary_token) {
1143 ut_a(len != 0);
1145 dtype_set(dfield_get_type(dfield), DATA_FIXBINARY,
1146 DATA_BINARY_TYPE | flags, len);
1147 } else if (type == &pars_blob_token) {
1148 ut_a(len == 0);
1150 dtype_set(dfield_get_type(dfield), DATA_BLOB,
1151 DATA_BINARY_TYPE | flags, 0);
1152 } else {
1153 ut_error;
1157 /*********************************************************************//**
1158 Parses a variable declaration.
1159 @return own: symbol table node of type SYM_VAR */
1160 UNIV_INTERN
1161 sym_node_t*
1162 pars_variable_declaration(
1163 /*======================*/
1164 sym_node_t* node, /*!< in: symbol table node allocated for the
1165 id of the variable */
1166 pars_res_word_t* type) /*!< in: pointer to a type token */
1168 node->resolved = TRUE;
1169 node->token_type = SYM_VAR;
1171 node->param_type = PARS_NOT_PARAM;
1173 pars_set_dfield_type(que_node_get_val(node), type, 0, FALSE, FALSE);
1175 return(node);
1178 /*********************************************************************//**
1179 Parses a procedure parameter declaration.
1180 @return own: symbol table node of type SYM_VAR */
1181 UNIV_INTERN
1182 sym_node_t*
1183 pars_parameter_declaration(
1184 /*=======================*/
1185 sym_node_t* node, /*!< in: symbol table node allocated for the
1186 id of the parameter */
1187 ulint param_type,
1188 /*!< in: PARS_INPUT or PARS_OUTPUT */
1189 pars_res_word_t* type) /*!< in: pointer to a type token */
1191 ut_a((param_type == PARS_INPUT) || (param_type == PARS_OUTPUT));
1193 pars_variable_declaration(node, type);
1195 node->param_type = param_type;
1197 return(node);
1200 /*********************************************************************//**
1201 Sets the parent field in a query node list. */
1202 static
1203 void
1204 pars_set_parent_in_list(
1205 /*====================*/
1206 que_node_t* node_list, /*!< in: first node in a list */
1207 que_node_t* parent) /*!< in: parent value to set in all
1208 nodes of the list */
1210 que_common_t* common;
1212 common = node_list;
1214 while (common) {
1215 common->parent = parent;
1217 common = que_node_get_next(common);
1221 /*********************************************************************//**
1222 Parses an elsif element.
1223 @return elsif node */
1224 UNIV_INTERN
1225 elsif_node_t*
1226 pars_elsif_element(
1227 /*===============*/
1228 que_node_t* cond, /*!< in: if-condition */
1229 que_node_t* stat_list) /*!< in: statement list */
1231 elsif_node_t* node;
1233 node = mem_heap_alloc(pars_sym_tab_global->heap, sizeof(elsif_node_t));
1235 node->common.type = QUE_NODE_ELSIF;
1237 node->cond = cond;
1239 pars_resolve_exp_variables_and_types(NULL, cond);
1241 node->stat_list = stat_list;
1243 return(node);
1246 /*********************************************************************//**
1247 Parses an if-statement.
1248 @return if-statement node */
1249 UNIV_INTERN
1250 if_node_t*
1251 pars_if_statement(
1252 /*==============*/
1253 que_node_t* cond, /*!< in: if-condition */
1254 que_node_t* stat_list, /*!< in: statement list */
1255 que_node_t* else_part) /*!< in: else-part statement list
1256 or elsif element list */
1258 if_node_t* node;
1259 elsif_node_t* elsif_node;
1261 node = mem_heap_alloc(pars_sym_tab_global->heap, sizeof(if_node_t));
1263 node->common.type = QUE_NODE_IF;
1265 node->cond = cond;
1267 pars_resolve_exp_variables_and_types(NULL, cond);
1269 node->stat_list = stat_list;
1271 if (else_part && (que_node_get_type(else_part) == QUE_NODE_ELSIF)) {
1273 /* There is a list of elsif conditions */
1275 node->else_part = NULL;
1276 node->elsif_list = else_part;
1278 elsif_node = else_part;
1280 while (elsif_node) {
1281 pars_set_parent_in_list(elsif_node->stat_list, node);
1283 elsif_node = que_node_get_next(elsif_node);
1285 } else {
1286 node->else_part = else_part;
1287 node->elsif_list = NULL;
1289 pars_set_parent_in_list(else_part, node);
1292 pars_set_parent_in_list(stat_list, node);
1294 return(node);
1297 /*********************************************************************//**
1298 Parses a while-statement.
1299 @return while-statement node */
1300 UNIV_INTERN
1301 while_node_t*
1302 pars_while_statement(
1303 /*=================*/
1304 que_node_t* cond, /*!< in: while-condition */
1305 que_node_t* stat_list) /*!< in: statement list */
1307 while_node_t* node;
1309 node = mem_heap_alloc(pars_sym_tab_global->heap, sizeof(while_node_t));
1311 node->common.type = QUE_NODE_WHILE;
1313 node->cond = cond;
1315 pars_resolve_exp_variables_and_types(NULL, cond);
1317 node->stat_list = stat_list;
1319 pars_set_parent_in_list(stat_list, node);
1321 return(node);
1324 /*********************************************************************//**
1325 Parses a for-loop-statement.
1326 @return for-statement node */
1327 UNIV_INTERN
1328 for_node_t*
1329 pars_for_statement(
1330 /*===============*/
1331 sym_node_t* loop_var, /*!< in: loop variable */
1332 que_node_t* loop_start_limit,/*!< in: loop start expression */
1333 que_node_t* loop_end_limit, /*!< in: loop end expression */
1334 que_node_t* stat_list) /*!< in: statement list */
1336 for_node_t* node;
1338 node = mem_heap_alloc(pars_sym_tab_global->heap, sizeof(for_node_t));
1340 node->common.type = QUE_NODE_FOR;
1342 pars_resolve_exp_variables_and_types(NULL, loop_var);
1343 pars_resolve_exp_variables_and_types(NULL, loop_start_limit);
1344 pars_resolve_exp_variables_and_types(NULL, loop_end_limit);
1346 node->loop_var = loop_var->indirection;
1348 ut_a(loop_var->indirection);
1350 node->loop_start_limit = loop_start_limit;
1351 node->loop_end_limit = loop_end_limit;
1353 node->stat_list = stat_list;
1355 pars_set_parent_in_list(stat_list, node);
1357 return(node);
1360 /*********************************************************************//**
1361 Parses an exit statement.
1362 @return exit statement node */
1363 UNIV_INTERN
1364 exit_node_t*
1365 pars_exit_statement(void)
1366 /*=====================*/
1368 exit_node_t* node;
1370 node = mem_heap_alloc(pars_sym_tab_global->heap, sizeof(exit_node_t));
1371 node->common.type = QUE_NODE_EXIT;
1373 return(node);
1376 /*********************************************************************//**
1377 Parses a return-statement.
1378 @return return-statement node */
1379 UNIV_INTERN
1380 return_node_t*
1381 pars_return_statement(void)
1382 /*=======================*/
1384 return_node_t* node;
1386 node = mem_heap_alloc(pars_sym_tab_global->heap,
1387 sizeof(return_node_t));
1388 node->common.type = QUE_NODE_RETURN;
1390 return(node);
1393 /*********************************************************************//**
1394 Parses an assignment statement.
1395 @return assignment statement node */
1396 UNIV_INTERN
1397 assign_node_t*
1398 pars_assignment_statement(
1399 /*======================*/
1400 sym_node_t* var, /*!< in: variable to assign */
1401 que_node_t* val) /*!< in: value to assign */
1403 assign_node_t* node;
1405 node = mem_heap_alloc(pars_sym_tab_global->heap,
1406 sizeof(assign_node_t));
1407 node->common.type = QUE_NODE_ASSIGNMENT;
1409 node->var = var;
1410 node->val = val;
1412 pars_resolve_exp_variables_and_types(NULL, var);
1413 pars_resolve_exp_variables_and_types(NULL, val);
1415 ut_a(dtype_get_mtype(dfield_get_type(que_node_get_val(var)))
1416 == dtype_get_mtype(dfield_get_type(que_node_get_val(val))));
1418 return(node);
1421 /*********************************************************************//**
1422 Parses a procedure call.
1423 @return function node */
1424 UNIV_INTERN
1425 func_node_t*
1426 pars_procedure_call(
1427 /*================*/
1428 que_node_t* res_word,/*!< in: procedure name reserved word */
1429 que_node_t* args) /*!< in: argument list */
1431 func_node_t* node;
1433 node = pars_func(res_word, args);
1435 pars_resolve_exp_list_variables_and_types(NULL, args);
1437 return(node);
1440 /*********************************************************************//**
1441 Parses a fetch statement. into_list or user_func (but not both) must be
1442 non-NULL.
1443 @return fetch statement node */
1444 UNIV_INTERN
1445 fetch_node_t*
1446 pars_fetch_statement(
1447 /*=================*/
1448 sym_node_t* cursor, /*!< in: cursor node */
1449 sym_node_t* into_list, /*!< in: variables to set, or NULL */
1450 sym_node_t* user_func) /*!< in: user function name, or NULL */
1452 sym_node_t* cursor_decl;
1453 fetch_node_t* node;
1455 /* Logical XOR. */
1456 ut_a(!into_list != !user_func);
1458 node = mem_heap_alloc(pars_sym_tab_global->heap, sizeof(fetch_node_t));
1460 node->common.type = QUE_NODE_FETCH;
1462 pars_resolve_exp_variables_and_types(NULL, cursor);
1464 if (into_list) {
1465 pars_resolve_exp_list_variables_and_types(NULL, into_list);
1466 node->into_list = into_list;
1467 node->func = NULL;
1468 } else {
1469 pars_resolve_exp_variables_and_types(NULL, user_func);
1471 node->func = pars_info_get_user_func(pars_sym_tab_global->info,
1472 user_func->name);
1473 ut_a(node->func);
1475 node->into_list = NULL;
1478 cursor_decl = cursor->alias;
1480 ut_a(cursor_decl->token_type == SYM_CURSOR);
1482 node->cursor_def = cursor_decl->cursor_def;
1484 if (into_list) {
1485 ut_a(que_node_list_get_len(into_list)
1486 == que_node_list_get_len(node->cursor_def->select_list));
1489 return(node);
1492 /*********************************************************************//**
1493 Parses an open or close cursor statement.
1494 @return fetch statement node */
1495 UNIV_INTERN
1496 open_node_t*
1497 pars_open_statement(
1498 /*================*/
1499 ulint type, /*!< in: ROW_SEL_OPEN_CURSOR
1500 or ROW_SEL_CLOSE_CURSOR */
1501 sym_node_t* cursor) /*!< in: cursor node */
1503 sym_node_t* cursor_decl;
1504 open_node_t* node;
1506 node = mem_heap_alloc(pars_sym_tab_global->heap, sizeof(open_node_t));
1508 node->common.type = QUE_NODE_OPEN;
1510 pars_resolve_exp_variables_and_types(NULL, cursor);
1512 cursor_decl = cursor->alias;
1514 ut_a(cursor_decl->token_type == SYM_CURSOR);
1516 node->op_type = type;
1517 node->cursor_def = cursor_decl->cursor_def;
1519 return(node);
1522 /*********************************************************************//**
1523 Parses a row_printf-statement.
1524 @return row_printf-statement node */
1525 UNIV_INTERN
1526 row_printf_node_t*
1527 pars_row_printf_statement(
1528 /*======================*/
1529 sel_node_t* sel_node) /*!< in: select node */
1531 row_printf_node_t* node;
1533 node = mem_heap_alloc(pars_sym_tab_global->heap,
1534 sizeof(row_printf_node_t));
1535 node->common.type = QUE_NODE_ROW_PRINTF;
1537 node->sel_node = sel_node;
1539 sel_node->common.parent = node;
1541 return(node);
1544 /*********************************************************************//**
1545 Parses a commit statement.
1546 @return own: commit node struct */
1547 UNIV_INTERN
1548 commit_node_t*
1549 pars_commit_statement(void)
1550 /*=======================*/
1552 return(commit_node_create(pars_sym_tab_global->heap));
1555 /*********************************************************************//**
1556 Parses a rollback statement.
1557 @return own: rollback node struct */
1558 UNIV_INTERN
1559 roll_node_t*
1560 pars_rollback_statement(void)
1561 /*=========================*/
1563 return(roll_node_create(pars_sym_tab_global->heap));
1566 /*********************************************************************//**
1567 Parses a column definition at a table creation.
1568 @return column sym table node */
1569 UNIV_INTERN
1570 sym_node_t*
1571 pars_column_def(
1572 /*============*/
1573 sym_node_t* sym_node, /*!< in: column node in the
1574 symbol table */
1575 pars_res_word_t* type, /*!< in: data type */
1576 sym_node_t* len, /*!< in: length of column, or
1577 NULL */
1578 void* is_unsigned, /*!< in: if not NULL, column
1579 is of type UNSIGNED. */
1580 void* is_not_null) /*!< in: if not NULL, column
1581 is of type NOT NULL. */
1583 ulint len2;
1585 if (len) {
1586 len2 = eval_node_get_int_val(len);
1587 } else {
1588 len2 = 0;
1591 pars_set_dfield_type(que_node_get_val(sym_node), type, len2,
1592 is_unsigned != NULL, is_not_null != NULL);
1594 return(sym_node);
1597 /*********************************************************************//**
1598 Parses a table creation operation.
1599 @return table create subgraph */
1600 UNIV_INTERN
1601 tab_node_t*
1602 pars_create_table(
1603 /*==============*/
1604 sym_node_t* table_sym, /*!< in: table name node in the symbol
1605 table */
1606 sym_node_t* column_defs, /*!< in: list of column names */
1607 void* not_fit_in_memory __attribute__((unused)))
1608 /*!< in: a non-NULL pointer means that
1609 this is a table which in simulations
1610 should be simulated as not fitting
1611 in memory; thread is put to sleep
1612 to simulate disk accesses; NOTE that
1613 this flag is not stored to the data
1614 dictionary on disk, and the database
1615 will forget about non-NULL value if
1616 it has to reload the table definition
1617 from disk */
1619 dict_table_t* table;
1620 sym_node_t* column;
1621 tab_node_t* node;
1622 const dtype_t* dtype;
1623 ulint n_cols;
1625 n_cols = que_node_list_get_len(column_defs);
1627 /* As the InnoDB SQL parser is for internal use only,
1628 for creating some system tables, this function will only
1629 create tables in the old (not compact) record format. */
1630 table = dict_mem_table_create(table_sym->name, 0, n_cols, 0);
1632 #ifdef UNIV_DEBUG
1633 if (not_fit_in_memory != NULL) {
1634 table->does_not_fit_in_memory = TRUE;
1636 #endif /* UNIV_DEBUG */
1637 column = column_defs;
1639 while (column) {
1640 dtype = dfield_get_type(que_node_get_val(column));
1642 dict_mem_table_add_col(table, table->heap,
1643 column->name, dtype->mtype,
1644 dtype->prtype, dtype->len);
1645 column->resolved = TRUE;
1646 column->token_type = SYM_COLUMN;
1648 column = que_node_get_next(column);
1651 node = tab_create_graph_create(table, pars_sym_tab_global->heap);
1653 table_sym->resolved = TRUE;
1654 table_sym->token_type = SYM_TABLE;
1656 return(node);
1659 /*********************************************************************//**
1660 Parses an index creation operation.
1661 @return index create subgraph */
1662 UNIV_INTERN
1663 ind_node_t*
1664 pars_create_index(
1665 /*==============*/
1666 pars_res_word_t* unique_def, /*!< in: not NULL if a unique index */
1667 pars_res_word_t* clustered_def, /*!< in: not NULL if a clustered index */
1668 sym_node_t* index_sym, /*!< in: index name node in the symbol
1669 table */
1670 sym_node_t* table_sym, /*!< in: table name node in the symbol
1671 table */
1672 sym_node_t* column_list) /*!< in: list of column names */
1674 dict_index_t* index;
1675 sym_node_t* column;
1676 ind_node_t* node;
1677 ulint n_fields;
1678 ulint ind_type;
1680 n_fields = que_node_list_get_len(column_list);
1682 ind_type = 0;
1684 if (unique_def) {
1685 ind_type = ind_type | DICT_UNIQUE;
1688 if (clustered_def) {
1689 ind_type = ind_type | DICT_CLUSTERED;
1692 index = dict_mem_index_create(table_sym->name, index_sym->name, 0,
1693 ind_type, n_fields);
1694 column = column_list;
1696 while (column) {
1697 dict_mem_index_add_field(index, column->name, 0);
1699 column->resolved = TRUE;
1700 column->token_type = SYM_COLUMN;
1702 column = que_node_get_next(column);
1705 node = ind_create_graph_create(index, pars_sym_tab_global->heap);
1707 table_sym->resolved = TRUE;
1708 table_sym->token_type = SYM_TABLE;
1710 index_sym->resolved = TRUE;
1711 index_sym->token_type = SYM_TABLE;
1713 return(node);
1716 /*********************************************************************//**
1717 Parses a procedure definition.
1718 @return query fork node */
1719 UNIV_INTERN
1720 que_fork_t*
1721 pars_procedure_definition(
1722 /*======================*/
1723 sym_node_t* sym_node, /*!< in: procedure id node in the symbol
1724 table */
1725 sym_node_t* param_list, /*!< in: parameter declaration list */
1726 que_node_t* stat_list) /*!< in: statement list */
1728 proc_node_t* node;
1729 que_fork_t* fork;
1730 que_thr_t* thr;
1731 mem_heap_t* heap;
1733 heap = pars_sym_tab_global->heap;
1735 fork = que_fork_create(NULL, NULL, QUE_FORK_PROCEDURE, heap);
1736 fork->trx = NULL;
1738 thr = que_thr_create(fork, heap);
1740 node = mem_heap_alloc(heap, sizeof(proc_node_t));
1742 node->common.type = QUE_NODE_PROC;
1743 node->common.parent = thr;
1745 sym_node->token_type = SYM_PROCEDURE_NAME;
1746 sym_node->resolved = TRUE;
1748 node->proc_id = sym_node;
1749 node->param_list = param_list;
1750 node->stat_list = stat_list;
1752 pars_set_parent_in_list(stat_list, node);
1754 node->sym_tab = pars_sym_tab_global;
1756 thr->child = node;
1758 pars_sym_tab_global->query_graph = fork;
1760 return(fork);
1763 /*************************************************************//**
1764 Parses a stored procedure call, when this is not within another stored
1765 procedure, that is, the client issues a procedure call directly.
1766 In MySQL/InnoDB, stored InnoDB procedures are invoked via the
1767 parsed procedure tree, not via InnoDB SQL, so this function is not used.
1768 @return query graph */
1769 UNIV_INTERN
1770 que_fork_t*
1771 pars_stored_procedure_call(
1772 /*=======================*/
1773 sym_node_t* sym_node __attribute__((unused)))
1774 /*!< in: stored procedure name */
1776 ut_error;
1777 return(NULL);
1780 /*************************************************************//**
1781 Retrieves characters to the lexical analyzer. */
1782 UNIV_INTERN
1783 void
1784 pars_get_lex_chars(
1785 /*===============*/
1786 char* buf, /*!< in/out: buffer where to copy */
1787 int* result, /*!< out: number of characters copied or EOF */
1788 int max_size) /*!< in: maximum number of characters which fit
1789 in the buffer */
1791 int len;
1793 len = pars_sym_tab_global->string_len
1794 - pars_sym_tab_global->next_char_pos;
1795 if (len == 0) {
1796 #ifdef YYDEBUG
1797 /* fputs("SQL string ends\n", stderr); */
1798 #endif
1799 *result = 0;
1801 return;
1804 if (len > max_size) {
1805 len = max_size;
1808 #ifdef UNIV_SQL_DEBUG
1809 if (pars_print_lexed) {
1811 if (len >= 5) {
1812 len = 5;
1815 fwrite(pars_sym_tab_global->sql_string
1816 + pars_sym_tab_global->next_char_pos,
1817 1, len, stderr);
1819 #endif /* UNIV_SQL_DEBUG */
1821 ut_memcpy(buf, pars_sym_tab_global->sql_string
1822 + pars_sym_tab_global->next_char_pos, len);
1823 *result = len;
1825 pars_sym_tab_global->next_char_pos += len;
1828 /*************************************************************//**
1829 Called by yyparse on error. */
1830 UNIV_INTERN
1831 void
1832 yyerror(
1833 /*====*/
1834 const char* s __attribute__((unused)))
1835 /*!< in: error message string */
1837 ut_ad(s);
1839 fputs("PARSER ERROR: Syntax error in SQL string\n", stderr);
1841 ut_error;
1844 /*************************************************************//**
1845 Parses an SQL string returning the query graph.
1846 @return own: the query graph */
1847 UNIV_INTERN
1848 que_t*
1849 pars_sql(
1850 /*=====*/
1851 pars_info_t* info, /*!< in: extra information, or NULL */
1852 const char* str) /*!< in: SQL string */
1854 sym_node_t* sym_node;
1855 mem_heap_t* heap;
1856 que_t* graph;
1858 ut_ad(str);
1860 heap = mem_heap_create(256);
1862 /* Currently, the parser is not reentrant: */
1863 ut_ad(mutex_own(&(dict_sys->mutex)));
1865 pars_sym_tab_global = sym_tab_create(heap);
1867 pars_sym_tab_global->string_len = strlen(str);
1868 pars_sym_tab_global->sql_string = mem_heap_dup(
1869 heap, str, pars_sym_tab_global->string_len + 1);
1870 pars_sym_tab_global->next_char_pos = 0;
1871 pars_sym_tab_global->info = info;
1873 yyparse();
1875 sym_node = UT_LIST_GET_FIRST(pars_sym_tab_global->sym_list);
1877 while (sym_node) {
1878 ut_a(sym_node->resolved);
1880 sym_node = UT_LIST_GET_NEXT(sym_list, sym_node);
1883 graph = pars_sym_tab_global->query_graph;
1885 graph->sym_tab = pars_sym_tab_global;
1886 graph->info = info;
1888 /* fprintf(stderr, "SQL graph size %lu\n", mem_heap_get_size(heap)); */
1890 return(graph);
1893 /******************************************************************//**
1894 Completes a query graph by adding query thread and fork nodes
1895 above it and prepares the graph for running. The fork created is of
1896 type QUE_FORK_MYSQL_INTERFACE.
1897 @return query thread node to run */
1898 UNIV_INTERN
1899 que_thr_t*
1900 pars_complete_graph_for_exec(
1901 /*=========================*/
1902 que_node_t* node, /*!< in: root node for an incomplete
1903 query graph */
1904 trx_t* trx, /*!< in: transaction handle */
1905 mem_heap_t* heap) /*!< in: memory heap from which allocated */
1907 que_fork_t* fork;
1908 que_thr_t* thr;
1910 fork = que_fork_create(NULL, NULL, QUE_FORK_MYSQL_INTERFACE, heap);
1911 fork->trx = trx;
1913 thr = que_thr_create(fork, heap);
1915 thr->child = node;
1917 que_node_set_parent(node, thr);
1919 trx->graph = NULL;
1921 return(thr);
1924 /****************************************************************//**
1925 Create parser info struct.
1926 @return own: info struct */
1927 UNIV_INTERN
1928 pars_info_t*
1929 pars_info_create(void)
1930 /*==================*/
1932 pars_info_t* info;
1933 mem_heap_t* heap;
1935 heap = mem_heap_create(512);
1937 info = mem_heap_alloc(heap, sizeof(*info));
1939 info->heap = heap;
1940 info->funcs = NULL;
1941 info->bound_lits = NULL;
1942 info->bound_ids = NULL;
1943 info->graph_owns_us = TRUE;
1945 return(info);
1948 /****************************************************************//**
1949 Free info struct and everything it contains. */
1950 UNIV_INTERN
1951 void
1952 pars_info_free(
1953 /*===========*/
1954 pars_info_t* info) /*!< in, own: info struct */
1956 mem_heap_free(info->heap);
1959 /****************************************************************//**
1960 Add bound literal. */
1961 UNIV_INTERN
1962 void
1963 pars_info_add_literal(
1964 /*==================*/
1965 pars_info_t* info, /*!< in: info struct */
1966 const char* name, /*!< in: name */
1967 const void* address, /*!< in: address */
1968 ulint length, /*!< in: length of data */
1969 ulint type, /*!< in: type, e.g. DATA_FIXBINARY */
1970 ulint prtype) /*!< in: precise type, e.g.
1971 DATA_UNSIGNED */
1973 pars_bound_lit_t* pbl;
1975 ut_ad(!pars_info_get_bound_lit(info, name));
1977 pbl = mem_heap_alloc(info->heap, sizeof(*pbl));
1979 pbl->name = name;
1980 pbl->address = address;
1981 pbl->length = length;
1982 pbl->type = type;
1983 pbl->prtype = prtype;
1985 if (!info->bound_lits) {
1986 info->bound_lits = ib_vector_create(info->heap, 8);
1989 ib_vector_push(info->bound_lits, pbl);
1992 /****************************************************************//**
1993 Equivalent to pars_info_add_literal(info, name, str, strlen(str),
1994 DATA_VARCHAR, DATA_ENGLISH). */
1995 UNIV_INTERN
1996 void
1997 pars_info_add_str_literal(
1998 /*======================*/
1999 pars_info_t* info, /*!< in: info struct */
2000 const char* name, /*!< in: name */
2001 const char* str) /*!< in: string */
2003 pars_info_add_literal(info, name, str, strlen(str),
2004 DATA_VARCHAR, DATA_ENGLISH);
2007 /****************************************************************//**
2008 Equivalent to:
2010 char buf[4];
2011 mach_write_to_4(buf, val);
2012 pars_info_add_literal(info, name, buf, 4, DATA_INT, 0);
2014 except that the buffer is dynamically allocated from the info struct's
2015 heap. */
2016 UNIV_INTERN
2017 void
2018 pars_info_add_int4_literal(
2019 /*=======================*/
2020 pars_info_t* info, /*!< in: info struct */
2021 const char* name, /*!< in: name */
2022 lint val) /*!< in: value */
2024 byte* buf = mem_heap_alloc(info->heap, 4);
2026 mach_write_to_4(buf, val);
2027 pars_info_add_literal(info, name, buf, 4, DATA_INT, 0);
2030 /****************************************************************//**
2031 Equivalent to:
2033 char buf[8];
2034 mach_write_to_8(buf, val);
2035 pars_info_add_literal(info, name, buf, 8, DATA_FIXBINARY, 0);
2037 except that the buffer is dynamically allocated from the info struct's
2038 heap. */
2039 UNIV_INTERN
2040 void
2041 pars_info_add_dulint_literal(
2042 /*=========================*/
2043 pars_info_t* info, /*!< in: info struct */
2044 const char* name, /*!< in: name */
2045 dulint val) /*!< in: value */
2047 byte* buf = mem_heap_alloc(info->heap, 8);
2049 mach_write_to_8(buf, val);
2051 pars_info_add_literal(info, name, buf, 8, DATA_FIXBINARY, 0);
2054 /****************************************************************//**
2055 Add user function. */
2056 UNIV_INTERN
2057 void
2058 pars_info_add_function(
2059 /*===================*/
2060 pars_info_t* info, /*!< in: info struct */
2061 const char* name, /*!< in: function name */
2062 pars_user_func_cb_t func, /*!< in: function address */
2063 void* arg) /*!< in: user-supplied argument */
2065 pars_user_func_t* puf;
2067 ut_ad(!pars_info_get_user_func(info, name));
2069 puf = mem_heap_alloc(info->heap, sizeof(*puf));
2071 puf->name = name;
2072 puf->func = func;
2073 puf->arg = arg;
2075 if (!info->funcs) {
2076 info->funcs = ib_vector_create(info->heap, 8);
2079 ib_vector_push(info->funcs, puf);
2082 /****************************************************************//**
2083 Add bound id. */
2084 UNIV_INTERN
2085 void
2086 pars_info_add_id(
2087 /*=============*/
2088 pars_info_t* info, /*!< in: info struct */
2089 const char* name, /*!< in: name */
2090 const char* id) /*!< in: id */
2092 pars_bound_id_t* bid;
2094 ut_ad(!pars_info_get_bound_id(info, name));
2096 bid = mem_heap_alloc(info->heap, sizeof(*bid));
2098 bid->name = name;
2099 bid->id = id;
2101 if (!info->bound_ids) {
2102 info->bound_ids = ib_vector_create(info->heap, 8);
2105 ib_vector_push(info->bound_ids, bid);
2108 /****************************************************************//**
2109 Get user function with the given name.
2110 @return user func, or NULL if not found */
2111 UNIV_INTERN
2112 pars_user_func_t*
2113 pars_info_get_user_func(
2114 /*====================*/
2115 pars_info_t* info, /*!< in: info struct */
2116 const char* name) /*!< in: function name to find*/
2118 ulint i;
2119 ib_vector_t* vec;
2121 if (!info || !info->funcs) {
2122 return(NULL);
2125 vec = info->funcs;
2127 for (i = 0; i < ib_vector_size(vec); i++) {
2128 pars_user_func_t* puf = ib_vector_get(vec, i);
2130 if (strcmp(puf->name, name) == 0) {
2131 return(puf);
2135 return(NULL);
2138 /****************************************************************//**
2139 Get bound literal with the given name.
2140 @return bound literal, or NULL if not found */
2141 UNIV_INTERN
2142 pars_bound_lit_t*
2143 pars_info_get_bound_lit(
2144 /*====================*/
2145 pars_info_t* info, /*!< in: info struct */
2146 const char* name) /*!< in: bound literal name to find */
2148 ulint i;
2149 ib_vector_t* vec;
2151 if (!info || !info->bound_lits) {
2152 return(NULL);
2155 vec = info->bound_lits;
2157 for (i = 0; i < ib_vector_size(vec); i++) {
2158 pars_bound_lit_t* pbl = ib_vector_get(vec, i);
2160 if (strcmp(pbl->name, name) == 0) {
2161 return(pbl);
2165 return(NULL);
2168 /****************************************************************//**
2169 Get bound id with the given name.
2170 @return bound id, or NULL if not found */
2171 UNIV_INTERN
2172 pars_bound_id_t*
2173 pars_info_get_bound_id(
2174 /*===================*/
2175 pars_info_t* info, /*!< in: info struct */
2176 const char* name) /*!< in: bound id name to find */
2178 ulint i;
2179 ib_vector_t* vec;
2181 if (!info || !info->bound_ids) {
2182 return(NULL);
2185 vec = info->bound_ids;
2187 for (i = 0; i < ib_vector_size(vec); i++) {
2188 pars_bound_id_t* bid = ib_vector_get(vec, i);
2190 if (strcmp(bid->name, name) == 0) {
2191 return(bid);
2195 return(NULL);