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
23 Created 11/19/1996 Heikki Tuuri
24 *******************************************************/
26 /* Historical note: Innobase executed its first SQL string (CREATE TABLE)
29 #include "pars0pars.h"
32 #include "pars0pars.ic"
38 #include "dict0dict.h"
40 #include "dict0crea.h"
44 #include "data0data.h"
45 #include "data0type.h"
48 #include "lock0lock.h"
49 #include "eval0eval.h"
52 /** If the following is set TRUE, the lexer will print the SQL string
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
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, ... */
106 int func
) /*!< in: function code: '=', PARS_GE_TOKEN, ... */
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
:
135 case PARS_RND_STR_TOKEN
:
136 case PARS_REPLSTR_TOKEN
:
137 return(PARS_FUNC_PREDEFINED
);
140 return(PARS_FUNC_OTHER
);
144 /*********************************************************************//**
145 Parses an operator or predefined function expression.
146 @return own: function node in a query tree */
151 int func
, /*!< in: function token code */
152 que_node_t
* arg
) /*!< in: first argument in the argument list */
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;
164 node
->class = pars_func_get_class(func
);
168 UT_LIST_ADD_LAST(func_node_list
, pars_sym_tab_global
->func_node_list
,
173 /*********************************************************************//**
174 Parses a function expression.
175 @return own: function node in a query tree */
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 */
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
198 que_node_list_add_last(NULL
, arg1
);
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 */
214 sym_node_t
* column
, /*!< in: column name */
215 pars_res_word_t
* asc
) /*!< in: &pars_asc_token or pars_desc_token */
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
) {
228 ut_a(asc
== &pars_desc_token
);
235 /*********************************************************************//**
236 Determine if a data type is a built-in string data type of the InnoDB
238 @return TRUE if string data type */
243 ulint mtype
) /*!< in: main data type */
246 case DATA_VARCHAR
: case DATA_CHAR
:
247 case DATA_FIXBINARY
: case DATA_BINARY
:
254 /*********************************************************************//**
255 Resolves the data type of a function in an expression. The argument data
256 types must already be resolved. */
259 pars_resolve_func_data_type(
260 /*========================*/
261 func_node_t
* node
) /*!< in: function node */
265 ut_a(que_node_get_type(node
) == QUE_NODE_FUNC
);
269 switch (node
->func
) {
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
))
282 case PARS_COUNT_TOKEN
:
284 dtype_set(que_node_get_data_type(node
), DATA_INT
, 0, 4);
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
,
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
,
299 dtype_set(que_node_get_data_type(node
), DATA_BINARY
,
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);
312 case PARS_SYSDATE_TOKEN
:
314 dtype_set(que_node_get_data_type(node
), DATA_INT
, 0, 4);
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
,
324 case '>': case '<': case '=':
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);
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);
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. */
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
;
362 sym_node_t
* sym_node
;
367 if (que_node_get_type(exp_node
) == QUE_NODE_FUNC
) {
368 func_node
= exp_node
;
370 arg
= func_node
->args
;
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
);
383 ut_a(que_node_get_type(exp_node
) == QUE_NODE_SYMBOL
);
387 if (sym_node
->resolved
) {
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
);
399 && ((node
->token_type
== SYM_VAR
)
400 || (node
->token_type
== SYM_CURSOR
)
401 || (node
->token_type
== SYM_FUNCTION
))
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
413 node
= UT_LIST_GET_NEXT(sym_list
, node
);
417 fprintf(stderr
, "PARSER ERROR: Unresolved identifier %s\n",
423 sym_node
->resolved
= TRUE
;
424 sym_node
->token_type
= SYM_IMPLICIT_VAR
;
425 sym_node
->alias
= node
;
426 sym_node
->indirection
= node
;
429 UT_LIST_ADD_LAST(col_var_list
, select_node
->copy_variables
,
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
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
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. */
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
;
467 sym_node_t
* sym_node
;
475 if (que_node_get_type(exp_node
) == QUE_NODE_FUNC
) {
476 func_node
= exp_node
;
478 arg
= func_node
->args
;
481 pars_resolve_exp_columns(table_node
, arg
);
483 arg
= que_node_get_next(arg
);
489 ut_a(que_node_get_type(exp_node
) == QUE_NODE_SYMBOL
);
493 if (sym_node
->resolved
) {
498 /* Not resolved yet: look in the table list for a column with the
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
);
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
))) {
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
;
526 dfield_get_type(&sym_node
533 t_node
= que_node_get_next(t_node
);
537 /*********************************************************************//**
538 Resolves the meaning of columns in an expression list. */
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
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. */
558 pars_retrieve_table_def(
559 /*====================*/
560 sym_node_t
* sym_node
) /*!< in: table node */
562 const char* table_name
;
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 */
582 pars_retrieve_table_list_defs(
583 /*==========================*/
584 sym_node_t
* sym_node
) /*!< in: first table node in list */
588 if (sym_node
== NULL
) {
594 pars_retrieve_table_def(sym_node
);
598 sym_node
= que_node_get_next(sym_node
);
604 /*********************************************************************//**
605 Adds all columns to the select list if the query is SELECT * FROM ... */
608 pars_select_all_columns(
609 /*====================*/
610 sel_node_t
* select_node
) /*!< in: select node already containing
613 sym_node_t
* col_node
;
614 sym_node_t
* table_node
;
618 select_node
->select_list
= NULL
;
620 table_node
= select_node
->table_list
;
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(
629 col_node
= sym_tab_add_id(pars_sym_tab_global
,
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
644 @return own: select node in a query tree */
649 que_node_t
* select_list
, /*!< in: select list */
650 sym_node_t
* into_list
) /*!< in: variables list or NULL */
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
);
664 /*********************************************************************//**
665 Checks if the query is an aggregate query, in which case the selct list must
666 contain only aggregate function items. */
669 pars_check_aggregate(
670 /*=================*/
671 sel_node_t
* select_node
) /*!< in: select node already containing
674 que_node_t
* exp_node
;
675 func_node_t
* func_node
;
677 ulint n_aggregate_nodes
= 0;
679 exp_node
= select_node
->select_list
;
685 if (que_node_get_type(exp_node
) == QUE_NODE_FUNC
) {
687 func_node
= exp_node
;
689 if (func_node
->class == PARS_FUNC_AGGREGATE
) {
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
;
703 select_node
->is_aggregate
= FALSE
;
707 /*********************************************************************//**
708 Parses a select statement.
709 @return own: select node in a query tree */
712 pars_select_statement(
713 /*==================*/
714 sel_node_t
* select_node
, /*!< in: select node already containing
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
;
748 pars_resolve_exp_columns(table_list
, search_cond
);
749 pars_resolve_exp_variables_and_types(select_node
, search_cond
);
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
;
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
;
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
);
790 /*********************************************************************//**
791 Parses a cursor declaration.
795 pars_cursor_declaration(
796 /*====================*/
797 sym_node_t
* sym_node
, /*!< in: cursor id node in the symbol
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
;
811 /*********************************************************************//**
812 Parses a function declaration.
816 pars_function_declaration(
817 /*======================*/
818 sym_node_t
* sym_node
) /*!< in: function id node in the symbol
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
,
831 /*********************************************************************//**
832 Parses a delete or update statement start.
833 @return own: update node in a query tree */
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
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
;
855 /*********************************************************************//**
856 Parses a column assignment in an update.
857 @return column assignment node */
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
;
877 /*********************************************************************//**
878 Processes an update node assignment list. */
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
;
891 ulint changes_ord_field
;
892 ulint changes_field_size
;
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
;
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
);
908 ut_a(dtype_get_mtype(
909 dfield_get_type(que_node_get_val(
912 dfield_get_type(que_node_get_val(
913 assign_node
->val
))));
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
,
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
),
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
,
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 */
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
;
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
);
992 pars_resolve_exp_variables_and_types(NULL
, cursor_sym
);
994 sel_node
= cursor_sym
->alias
->cursor_def
;
996 node
->searched_update
= FALSE
;
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;
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
;
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
);
1044 node
->pcur
= &(plan
->pcur
);
1050 /*********************************************************************//**
1051 Parses an insert statement.
1052 @return own: update node in a query tree */
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 */
1065 ut_a(values_list
|| select
);
1066 ut_a(!values_list
|| !select
);
1069 ins_type
= INS_VALUES
;
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
;
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
));
1107 /*********************************************************************//**
1108 Set the type of a dfield. */
1111 pars_set_dfield_type(
1112 /*=================*/
1113 dfield_t
* dfield
, /*!< in: dfield */
1114 pars_res_word_t
* type
, /*!< in: pointer to a type
1116 ulint len
, /*!< in: length, or 0 */
1117 ibool is_unsigned
, /*!< in: if TRUE, column is
1119 ibool is_not_null
) /*!< in: if TRUE, column is
1125 flags
|= DATA_NOT_NULL
;
1129 flags
|= DATA_UNSIGNED
;
1132 if (type
== &pars_int_token
) {
1135 dtype_set(dfield_get_type(dfield
), DATA_INT
, flags
, 4);
1137 } else if (type
== &pars_char_token
) {
1140 dtype_set(dfield_get_type(dfield
), DATA_VARCHAR
,
1141 DATA_ENGLISH
| flags
, 0);
1142 } else if (type
== &pars_binary_token
) {
1145 dtype_set(dfield_get_type(dfield
), DATA_FIXBINARY
,
1146 DATA_BINARY_TYPE
| flags
, len
);
1147 } else if (type
== &pars_blob_token
) {
1150 dtype_set(dfield_get_type(dfield
), DATA_BLOB
,
1151 DATA_BINARY_TYPE
| flags
, 0);
1157 /*********************************************************************//**
1158 Parses a variable declaration.
1159 @return own: symbol table node of type SYM_VAR */
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
);
1178 /*********************************************************************//**
1179 Parses a procedure parameter declaration.
1180 @return own: symbol table node of type SYM_VAR */
1183 pars_parameter_declaration(
1184 /*=======================*/
1185 sym_node_t
* node
, /*!< in: symbol table node allocated for the
1186 id of the parameter */
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
;
1200 /*********************************************************************//**
1201 Sets the parent field in a query node list. */
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
;
1215 common
->parent
= parent
;
1217 common
= que_node_get_next(common
);
1221 /*********************************************************************//**
1222 Parses an elsif element.
1223 @return elsif node */
1228 que_node_t
* cond
, /*!< in: if-condition */
1229 que_node_t
* stat_list
) /*!< in: statement list */
1233 node
= mem_heap_alloc(pars_sym_tab_global
->heap
, sizeof(elsif_node_t
));
1235 node
->common
.type
= QUE_NODE_ELSIF
;
1239 pars_resolve_exp_variables_and_types(NULL
, cond
);
1241 node
->stat_list
= stat_list
;
1246 /*********************************************************************//**
1247 Parses an if-statement.
1248 @return if-statement node */
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 */
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
;
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
);
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
);
1297 /*********************************************************************//**
1298 Parses a while-statement.
1299 @return while-statement node */
1302 pars_while_statement(
1303 /*=================*/
1304 que_node_t
* cond
, /*!< in: while-condition */
1305 que_node_t
* stat_list
) /*!< in: statement list */
1309 node
= mem_heap_alloc(pars_sym_tab_global
->heap
, sizeof(while_node_t
));
1311 node
->common
.type
= QUE_NODE_WHILE
;
1315 pars_resolve_exp_variables_and_types(NULL
, cond
);
1317 node
->stat_list
= stat_list
;
1319 pars_set_parent_in_list(stat_list
, node
);
1324 /*********************************************************************//**
1325 Parses a for-loop-statement.
1326 @return for-statement node */
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 */
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
);
1360 /*********************************************************************//**
1361 Parses an exit statement.
1362 @return exit statement node */
1365 pars_exit_statement(void)
1366 /*=====================*/
1370 node
= mem_heap_alloc(pars_sym_tab_global
->heap
, sizeof(exit_node_t
));
1371 node
->common
.type
= QUE_NODE_EXIT
;
1376 /*********************************************************************//**
1377 Parses a return-statement.
1378 @return return-statement node */
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
;
1393 /*********************************************************************//**
1394 Parses an assignment statement.
1395 @return assignment statement node */
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
;
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
))));
1421 /*********************************************************************//**
1422 Parses a procedure call.
1423 @return function node */
1426 pars_procedure_call(
1427 /*================*/
1428 que_node_t
* res_word
,/*!< in: procedure name reserved word */
1429 que_node_t
* args
) /*!< in: argument list */
1433 node
= pars_func(res_word
, args
);
1435 pars_resolve_exp_list_variables_and_types(NULL
, args
);
1440 /*********************************************************************//**
1441 Parses a fetch statement. into_list or user_func (but not both) must be
1443 @return fetch statement node */
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
;
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
);
1465 pars_resolve_exp_list_variables_and_types(NULL
, into_list
);
1466 node
->into_list
= into_list
;
1469 pars_resolve_exp_variables_and_types(NULL
, user_func
);
1471 node
->func
= pars_info_get_user_func(pars_sym_tab_global
->info
,
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
;
1485 ut_a(que_node_list_get_len(into_list
)
1486 == que_node_list_get_len(node
->cursor_def
->select_list
));
1492 /*********************************************************************//**
1493 Parses an open or close cursor statement.
1494 @return fetch statement node */
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
;
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
;
1522 /*********************************************************************//**
1523 Parses a row_printf-statement.
1524 @return row_printf-statement node */
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
;
1544 /*********************************************************************//**
1545 Parses a commit statement.
1546 @return own: commit node struct */
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 */
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 */
1573 sym_node_t
* sym_node
, /*!< in: column node in the
1575 pars_res_word_t
* type
, /*!< in: data type */
1576 sym_node_t
* len
, /*!< in: length of column, or
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. */
1586 len2
= eval_node_get_int_val(len
);
1591 pars_set_dfield_type(que_node_get_val(sym_node
), type
, len2
,
1592 is_unsigned
!= NULL
, is_not_null
!= NULL
);
1597 /*********************************************************************//**
1598 Parses a table creation operation.
1599 @return table create subgraph */
1604 sym_node_t
* table_sym
, /*!< in: table name node in the symbol
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
1619 dict_table_t
* table
;
1622 const dtype_t
* dtype
;
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);
1633 if (not_fit_in_memory
!= NULL
) {
1634 table
->does_not_fit_in_memory
= TRUE
;
1636 #endif /* UNIV_DEBUG */
1637 column
= column_defs
;
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
;
1659 /*********************************************************************//**
1660 Parses an index creation operation.
1661 @return index create subgraph */
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
1670 sym_node_t
* table_sym
, /*!< in: table name node in the symbol
1672 sym_node_t
* column_list
) /*!< in: list of column names */
1674 dict_index_t
* index
;
1680 n_fields
= que_node_list_get_len(column_list
);
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
;
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
;
1716 /*********************************************************************//**
1717 Parses a procedure definition.
1718 @return query fork node */
1721 pars_procedure_definition(
1722 /*======================*/
1723 sym_node_t
* sym_node
, /*!< in: procedure id node in the symbol
1725 sym_node_t
* param_list
, /*!< in: parameter declaration list */
1726 que_node_t
* stat_list
) /*!< in: statement list */
1733 heap
= pars_sym_tab_global
->heap
;
1735 fork
= que_fork_create(NULL
, NULL
, QUE_FORK_PROCEDURE
, heap
);
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
;
1758 pars_sym_tab_global
->query_graph
= 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 */
1771 pars_stored_procedure_call(
1772 /*=======================*/
1773 sym_node_t
* sym_node
__attribute__((unused
)))
1774 /*!< in: stored procedure name */
1780 /*************************************************************//**
1781 Retrieves characters to the lexical analyzer. */
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
1793 len
= pars_sym_tab_global
->string_len
1794 - pars_sym_tab_global
->next_char_pos
;
1797 /* fputs("SQL string ends\n", stderr); */
1804 if (len
> max_size
) {
1808 #ifdef UNIV_SQL_DEBUG
1809 if (pars_print_lexed
) {
1815 fwrite(pars_sym_tab_global
->sql_string
1816 + pars_sym_tab_global
->next_char_pos
,
1819 #endif /* UNIV_SQL_DEBUG */
1821 ut_memcpy(buf
, pars_sym_tab_global
->sql_string
1822 + pars_sym_tab_global
->next_char_pos
, len
);
1825 pars_sym_tab_global
->next_char_pos
+= len
;
1828 /*************************************************************//**
1829 Called by yyparse on error. */
1834 const char* s
__attribute__((unused
)))
1835 /*!< in: error message string */
1839 fputs("PARSER ERROR: Syntax error in SQL string\n", stderr
);
1844 /*************************************************************//**
1845 Parses an SQL string returning the query graph.
1846 @return own: the query graph */
1851 pars_info_t
* info
, /*!< in: extra information, or NULL */
1852 const char* str
) /*!< in: SQL string */
1854 sym_node_t
* sym_node
;
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
;
1875 sym_node
= UT_LIST_GET_FIRST(pars_sym_tab_global
->sym_list
);
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
;
1888 /* fprintf(stderr, "SQL graph size %lu\n", mem_heap_get_size(heap)); */
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 */
1900 pars_complete_graph_for_exec(
1901 /*=========================*/
1902 que_node_t
* node
, /*!< in: root node for an incomplete
1904 trx_t
* trx
, /*!< in: transaction handle */
1905 mem_heap_t
* heap
) /*!< in: memory heap from which allocated */
1910 fork
= que_fork_create(NULL
, NULL
, QUE_FORK_MYSQL_INTERFACE
, heap
);
1913 thr
= que_thr_create(fork
, heap
);
1917 que_node_set_parent(node
, thr
);
1924 /****************************************************************//**
1925 Create parser info struct.
1926 @return own: info struct */
1929 pars_info_create(void)
1930 /*==================*/
1935 heap
= mem_heap_create(512);
1937 info
= mem_heap_alloc(heap
, sizeof(*info
));
1941 info
->bound_lits
= NULL
;
1942 info
->bound_ids
= NULL
;
1943 info
->graph_owns_us
= TRUE
;
1948 /****************************************************************//**
1949 Free info struct and everything it contains. */
1954 pars_info_t
* info
) /*!< in, own: info struct */
1956 mem_heap_free(info
->heap
);
1959 /****************************************************************//**
1960 Add bound literal. */
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.
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
));
1980 pbl
->address
= address
;
1981 pbl
->length
= length
;
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). */
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 /****************************************************************//**
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
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 /****************************************************************//**
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
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. */
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
));
2076 info
->funcs
= ib_vector_create(info
->heap
, 8);
2079 ib_vector_push(info
->funcs
, puf
);
2082 /****************************************************************//**
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
));
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 */
2113 pars_info_get_user_func(
2114 /*====================*/
2115 pars_info_t
* info
, /*!< in: info struct */
2116 const char* name
) /*!< in: function name to find*/
2121 if (!info
|| !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) {
2138 /****************************************************************//**
2139 Get bound literal with the given name.
2140 @return bound literal, or NULL if not found */
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 */
2151 if (!info
|| !info
->bound_lits
) {
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) {
2168 /****************************************************************//**
2169 Get bound id with the given name.
2170 @return bound id, or NULL if not found */
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 */
2181 if (!info
|| !info
->bound_ids
) {
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) {