1
/*****************************************************************************
3
Copyright (C) 1996, 2010, 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., 51 Franklin
15
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 "pars0grm.hh"
47
#include "data0data.h"
48
#include "data0type.h"
51
#include "lock0lock.h"
52
#include "eval0eval.h"
55
/** If the following is set TRUE, the lexer will print the SQL string
57
UNIV_INTERN ibool pars_print_lexed = FALSE;
58
#endif /* UNIV_SQL_DEBUG */
60
/* Global variable used while parsing a single procedure or query : the code is
62
UNIV_INTERN sym_tab_t* pars_sym_tab_global;
64
/* Global variables used to denote certain reserved words, used in
65
constructing the parsing tree */
67
UNIV_INTERN pars_res_word_t pars_to_char_token = {PARS_TO_CHAR_TOKEN};
68
UNIV_INTERN pars_res_word_t pars_to_number_token = {PARS_TO_NUMBER_TOKEN};
69
UNIV_INTERN pars_res_word_t pars_to_binary_token = {PARS_TO_BINARY_TOKEN};
70
UNIV_INTERN pars_res_word_t pars_binary_to_number_token = {PARS_BINARY_TO_NUMBER_TOKEN};
71
UNIV_INTERN pars_res_word_t pars_substr_token = {PARS_SUBSTR_TOKEN};
72
UNIV_INTERN pars_res_word_t pars_replstr_token = {PARS_REPLSTR_TOKEN};
73
UNIV_INTERN pars_res_word_t pars_concat_token = {PARS_CONCAT_TOKEN};
74
UNIV_INTERN pars_res_word_t pars_instr_token = {PARS_INSTR_TOKEN};
75
UNIV_INTERN pars_res_word_t pars_length_token = {PARS_LENGTH_TOKEN};
76
UNIV_INTERN pars_res_word_t pars_sysdate_token = {PARS_SYSDATE_TOKEN};
77
UNIV_INTERN pars_res_word_t pars_printf_token = {PARS_PRINTF_TOKEN};
78
UNIV_INTERN pars_res_word_t pars_assert_token = {PARS_ASSERT_TOKEN};
79
UNIV_INTERN pars_res_word_t pars_rnd_token = {PARS_RND_TOKEN};
80
UNIV_INTERN pars_res_word_t pars_rnd_str_token = {PARS_RND_STR_TOKEN};
81
UNIV_INTERN pars_res_word_t pars_count_token = {PARS_COUNT_TOKEN};
82
UNIV_INTERN pars_res_word_t pars_sum_token = {PARS_SUM_TOKEN};
83
UNIV_INTERN pars_res_word_t pars_distinct_token = {PARS_DISTINCT_TOKEN};
84
UNIV_INTERN pars_res_word_t pars_binary_token = {PARS_BINARY_TOKEN};
85
UNIV_INTERN pars_res_word_t pars_blob_token = {PARS_BLOB_TOKEN};
86
UNIV_INTERN pars_res_word_t pars_int_token = {PARS_INT_TOKEN};
87
UNIV_INTERN pars_res_word_t pars_char_token = {PARS_CHAR_TOKEN};
88
UNIV_INTERN pars_res_word_t pars_float_token = {PARS_FLOAT_TOKEN};
89
UNIV_INTERN pars_res_word_t pars_update_token = {PARS_UPDATE_TOKEN};
90
UNIV_INTERN pars_res_word_t pars_asc_token = {PARS_ASC_TOKEN};
91
UNIV_INTERN pars_res_word_t pars_desc_token = {PARS_DESC_TOKEN};
92
UNIV_INTERN pars_res_word_t pars_open_token = {PARS_OPEN_TOKEN};
93
UNIV_INTERN pars_res_word_t pars_close_token = {PARS_CLOSE_TOKEN};
94
UNIV_INTERN pars_res_word_t pars_share_token = {PARS_SHARE_TOKEN};
95
UNIV_INTERN pars_res_word_t pars_unique_token = {PARS_UNIQUE_TOKEN};
96
UNIV_INTERN pars_res_word_t pars_clustered_token = {PARS_CLUSTERED_TOKEN};
98
/** Global variable used to denote the '*' in SELECT * FROM.. */
99
UNIV_INTERN ulint pars_star_denoter = 12345678;
102
/*********************************************************************//**
103
Determines the class of a function code.
104
@return function class: PARS_FUNC_ARITH, ... */
109
int func) /*!< in: function code: '=', PARS_GE_TOKEN, ... */
112
case '+': case '-': case '*': case '/':
113
return(PARS_FUNC_ARITH);
115
case '=': case '<': case '>':
116
case PARS_GE_TOKEN: case PARS_LE_TOKEN: case PARS_NE_TOKEN:
117
return(PARS_FUNC_CMP);
119
case PARS_AND_TOKEN: case PARS_OR_TOKEN: case PARS_NOT_TOKEN:
120
return(PARS_FUNC_LOGICAL);
122
case PARS_COUNT_TOKEN: case PARS_SUM_TOKEN:
123
return(PARS_FUNC_AGGREGATE);
125
case PARS_TO_CHAR_TOKEN:
126
case PARS_TO_NUMBER_TOKEN:
127
case PARS_TO_BINARY_TOKEN:
128
case PARS_BINARY_TO_NUMBER_TOKEN:
129
case PARS_SUBSTR_TOKEN:
130
case PARS_CONCAT_TOKEN:
131
case PARS_LENGTH_TOKEN:
132
case PARS_INSTR_TOKEN:
133
case PARS_SYSDATE_TOKEN:
134
case PARS_NOTFOUND_TOKEN:
135
case PARS_PRINTF_TOKEN:
136
case PARS_ASSERT_TOKEN:
138
case PARS_RND_STR_TOKEN:
139
case PARS_REPLSTR_TOKEN:
140
return(PARS_FUNC_PREDEFINED);
143
return(PARS_FUNC_OTHER);
147
/*********************************************************************//**
148
Parses an operator or predefined function expression.
149
@return own: function node in a query tree */
154
int func, /*!< in: function token code */
155
que_node_t* arg) /*!< in: first argument in the argument list */
159
node = static_cast<func_node_t *>(mem_heap_alloc(pars_sym_tab_global->heap, sizeof(func_node_t)));
161
node->common.type = QUE_NODE_FUNC;
162
dfield_set_data(&(node->common.val), NULL, 0);
163
node->common.val_buf_size = 0;
167
node->func_class = pars_func_get_class(func);
171
UT_LIST_ADD_LAST(func_node_list, pars_sym_tab_global->func_node_list,
176
/*********************************************************************//**
177
Parses a function expression.
178
@return own: function node in a query tree */
183
que_node_t* res_word,/*!< in: function name reserved word */
184
que_node_t* arg) /*!< in: first argument in the argument list */
186
return(pars_func_low(((pars_res_word_t*)res_word)->code, arg));
189
/*********************************************************************//**
190
Parses an operator expression.
191
@return own: function node in a query tree */
196
int func, /*!< in: operator token code */
197
que_node_t* arg1, /*!< in: first argument */
198
que_node_t* arg2) /*!< in: second argument or NULL for an unary
201
que_node_list_add_last(NULL, arg1);
204
que_node_list_add_last(arg1, arg2);
207
return(pars_func_low(func, arg1));
210
/*********************************************************************//**
211
Parses an ORDER BY clause. Order by a single column only is supported.
212
@return own: order-by node in a query tree */
217
sym_node_t* column, /*!< in: column name */
218
pars_res_word_t* asc) /*!< in: &pars_asc_token or pars_desc_token */
222
node = static_cast<order_node_t *>(mem_heap_alloc(pars_sym_tab_global->heap, sizeof(order_node_t)));
224
node->common.type = QUE_NODE_ORDER;
226
node->column = column;
228
if (asc == &pars_asc_token) {
231
ut_a(asc == &pars_desc_token);
238
/*********************************************************************//**
239
Determine if a data type is a built-in string data type of the InnoDB
241
@return TRUE if string data type */
246
ulint mtype) /*!< in: main data type */
249
case DATA_VARCHAR: case DATA_CHAR:
250
case DATA_FIXBINARY: case DATA_BINARY:
257
/*********************************************************************//**
258
Resolves the data type of a function in an expression. The argument data
259
types must already be resolved. */
262
pars_resolve_func_data_type(
263
/*========================*/
264
func_node_t* node) /*!< in: function node */
268
ut_a(que_node_get_type(node) == QUE_NODE_FUNC);
272
switch (node->func) {
274
case '+': case '-': case '*': case '/':
275
/* Inherit the data type from the first argument (which must
276
not be the SQL null literal whose type is DATA_ERROR) */
278
dtype_copy(que_node_get_data_type(node),
279
que_node_get_data_type(arg));
281
ut_a(dtype_get_mtype(que_node_get_data_type(node))
285
case PARS_COUNT_TOKEN:
287
dtype_set(que_node_get_data_type(node), DATA_INT, 0, 4);
290
case PARS_TO_CHAR_TOKEN:
291
case PARS_RND_STR_TOKEN:
292
ut_a(dtype_get_mtype(que_node_get_data_type(arg)) == DATA_INT);
293
dtype_set(que_node_get_data_type(node), DATA_VARCHAR,
297
case PARS_TO_BINARY_TOKEN:
298
if (dtype_get_mtype(que_node_get_data_type(arg)) == DATA_INT) {
299
dtype_set(que_node_get_data_type(node), DATA_VARCHAR,
302
dtype_set(que_node_get_data_type(node), DATA_BINARY,
307
case PARS_TO_NUMBER_TOKEN:
308
case PARS_BINARY_TO_NUMBER_TOKEN:
309
case PARS_LENGTH_TOKEN:
310
case PARS_INSTR_TOKEN:
311
ut_a(pars_is_string_type(que_node_get_data_type(arg)->mtype));
312
dtype_set(que_node_get_data_type(node), DATA_INT, 0, 4);
315
case PARS_SYSDATE_TOKEN:
317
dtype_set(que_node_get_data_type(node), DATA_INT, 0, 4);
320
case PARS_SUBSTR_TOKEN:
321
case PARS_CONCAT_TOKEN:
322
ut_a(pars_is_string_type(que_node_get_data_type(arg)->mtype));
323
dtype_set(que_node_get_data_type(node), DATA_VARCHAR,
327
case '>': case '<': case '=':
334
case PARS_NOTFOUND_TOKEN:
336
/* We currently have no iboolean type: use integer type */
337
dtype_set(que_node_get_data_type(node), DATA_INT, 0, 4);
341
ut_a(dtype_get_mtype(que_node_get_data_type(arg)) == DATA_INT);
342
dtype_set(que_node_get_data_type(node), DATA_INT, 0, 4);
350
/*********************************************************************//**
351
Resolves the meaning of variables in an expression and the data types of
352
functions. It is an error if some identifier cannot be resolved here. */
355
pars_resolve_exp_variables_and_types(
356
/*=================================*/
357
sel_node_t* select_node, /*!< in: select node or NULL; if
358
this is not NULL then the variable
359
sym nodes are added to the
360
copy_variables list of select_node */
361
que_node_t* exp_node) /*!< in: expression */
363
func_node_t* func_node;
365
sym_node_t* sym_node;
370
if (que_node_get_type(exp_node) == QUE_NODE_FUNC) {
371
func_node = static_cast<func_node_t *>(exp_node);
373
arg = func_node->args;
376
pars_resolve_exp_variables_and_types(select_node, arg);
378
arg = que_node_get_next(arg);
381
pars_resolve_func_data_type(func_node);
386
ut_a(que_node_get_type(exp_node) == QUE_NODE_SYMBOL);
388
sym_node = static_cast<sym_node_t *>(exp_node);
390
if (sym_node->resolved) {
395
/* Not resolved yet: look in the symbol table for a variable
396
or a cursor or a function with the same name */
398
node = UT_LIST_GET_FIRST(pars_sym_tab_global->sym_list);
402
&& ((node->token_type == SYM_VAR)
403
|| (node->token_type == SYM_CURSOR)
404
|| (node->token_type == SYM_FUNCTION))
406
&& (sym_node->name_len == node->name_len)
407
&& (ut_memcmp(sym_node->name, node->name,
408
node->name_len) == 0)) {
410
/* Found a variable or a cursor declared with
416
node = UT_LIST_GET_NEXT(sym_list, node);
420
fprintf(stderr, "PARSER ERROR: Unresolved identifier %s\n",
426
sym_node->resolved = TRUE;
427
sym_node->token_type = SYM_IMPLICIT_VAR;
428
sym_node->alias = node;
429
sym_node->indirection = node;
432
UT_LIST_ADD_LAST(col_var_list, select_node->copy_variables,
436
dfield_set_type(que_node_get_val(sym_node),
437
que_node_get_data_type(node));
440
/*********************************************************************//**
441
Resolves the meaning of variables in an expression list. It is an error if
442
some identifier cannot be resolved here. Resolves also the data types of
446
pars_resolve_exp_list_variables_and_types(
447
/*======================================*/
448
sel_node_t* select_node, /*!< in: select node or NULL */
449
que_node_t* exp_node) /*!< in: expression list first node, or
453
pars_resolve_exp_variables_and_types(select_node, exp_node);
455
exp_node = que_node_get_next(exp_node);
459
/*********************************************************************//**
460
Resolves the columns in an expression. */
463
pars_resolve_exp_columns(
464
/*=====================*/
465
sym_node_t* table_node, /*!< in: first node in a table list */
466
que_node_t* exp_node) /*!< in: expression */
468
func_node_t* func_node;
470
sym_node_t* sym_node;
478
if (que_node_get_type(exp_node) == QUE_NODE_FUNC) {
479
func_node = static_cast<func_node_t *>(exp_node);
481
arg = func_node->args;
484
pars_resolve_exp_columns(table_node, arg);
486
arg = que_node_get_next(arg);
492
ut_a(que_node_get_type(exp_node) == QUE_NODE_SYMBOL);
494
sym_node = static_cast<sym_node_t *>(exp_node);
496
if (sym_node->resolved) {
501
/* Not resolved yet: look in the table list for a column with the
507
table = t_node->table;
509
n_cols = dict_table_get_n_cols(table);
511
for (i = 0; i < n_cols; i++) {
512
const dict_col_t* col
513
= dict_table_get_nth_col(table, i);
515
= dict_table_get_col_name(table, i);
517
if ((sym_node->name_len == ut_strlen(col_name))
518
&& (0 == ut_memcmp(sym_node->name, col_name,
519
sym_node->name_len))) {
521
sym_node->resolved = TRUE;
522
sym_node->token_type = SYM_COLUMN;
523
sym_node->table = table;
524
sym_node->col_no = i;
525
sym_node->prefetch_buf = NULL;
529
dfield_get_type(&sym_node
536
t_node = static_cast<sym_node_t *>(que_node_get_next(t_node));
540
/*********************************************************************//**
541
Resolves the meaning of columns in an expression list. */
544
pars_resolve_exp_list_columns(
545
/*==========================*/
546
sym_node_t* table_node, /*!< in: first node in a table list */
547
que_node_t* exp_node) /*!< in: expression list first node, or
551
pars_resolve_exp_columns(table_node, exp_node);
553
exp_node = que_node_get_next(exp_node);
557
/*********************************************************************//**
558
Retrieves the table definition for a table name id. */
561
pars_retrieve_table_def(
562
/*====================*/
563
sym_node_t* sym_node) /*!< in: table node */
565
const char* table_name;
568
ut_a(que_node_get_type(sym_node) == QUE_NODE_SYMBOL);
570
sym_node->resolved = TRUE;
571
sym_node->token_type = SYM_TABLE;
573
table_name = (const char*) sym_node->name;
575
sym_node->table = dict_table_get_low(table_name);
577
ut_a(sym_node->table);
580
/*********************************************************************//**
581
Retrieves the table definitions for a list of table name ids.
582
@return number of tables */
585
pars_retrieve_table_list_defs(
586
/*==========================*/
587
sym_node_t* sym_node) /*!< in: first table node in list */
591
if (sym_node == NULL) {
597
pars_retrieve_table_def(sym_node);
601
sym_node = static_cast<sym_node_t *>(que_node_get_next(sym_node));
607
/*********************************************************************//**
608
Adds all columns to the select list if the query is SELECT * FROM ... */
611
pars_select_all_columns(
612
/*====================*/
613
sel_node_t* select_node) /*!< in: select node already containing
616
sym_node_t* col_node;
617
sym_node_t* table_node;
621
select_node->select_list = NULL;
623
table_node = select_node->table_list;
626
table = table_node->table;
628
for (i = 0; i < dict_table_get_n_user_cols(table); i++) {
629
const char* col_name = dict_table_get_col_name(
632
col_node = sym_tab_add_id(pars_sym_tab_global,
634
ut_strlen(col_name));
636
select_node->select_list = que_node_list_add_last(
637
select_node->select_list, col_node);
640
table_node = static_cast<sym_node_t *>(que_node_get_next(table_node));
644
/*********************************************************************//**
645
Parses a select list; creates a query graph node for the whole SELECT
647
@return own: select node in a query tree */
652
que_node_t* select_list, /*!< in: select list */
653
sym_node_t* into_list) /*!< in: variables list or NULL */
657
node = sel_node_create(pars_sym_tab_global->heap);
659
node->select_list = select_list;
660
node->into_list = into_list;
662
pars_resolve_exp_list_variables_and_types(NULL, into_list);
667
/*********************************************************************//**
668
Checks if the query is an aggregate query, in which case the selct list must
669
contain only aggregate function items. */
672
pars_check_aggregate(
673
/*=================*/
674
sel_node_t* select_node) /*!< in: select node already containing
677
que_node_t* exp_node;
678
func_node_t* func_node;
680
ulint n_aggregate_nodes = 0;
682
exp_node = select_node->select_list;
688
if (que_node_get_type(exp_node) == QUE_NODE_FUNC) {
690
func_node = static_cast<func_node_t *>(exp_node);
692
if (func_node->func_class == PARS_FUNC_AGGREGATE) {
698
exp_node = que_node_get_next(exp_node);
701
if (n_aggregate_nodes > 0) {
702
ut_a(n_nodes == n_aggregate_nodes);
704
select_node->is_aggregate = TRUE;
706
select_node->is_aggregate = FALSE;
710
/*********************************************************************//**
711
Parses a select statement.
712
@return own: select node in a query tree */
715
pars_select_statement(
716
/*==================*/
717
sel_node_t* select_node, /*!< in: select node already containing
719
sym_node_t* table_list, /*!< in: table list */
720
que_node_t* search_cond, /*!< in: search condition or NULL */
721
pars_res_word_t* for_update, /*!< in: NULL or &pars_update_token */
722
pars_res_word_t* lock_shared, /*!< in: NULL or &pars_share_token */
723
order_node_t* order_by) /*!< in: NULL or an order-by node */
725
select_node->state = SEL_NODE_OPEN;
727
select_node->table_list = table_list;
728
select_node->n_tables = pars_retrieve_table_list_defs(table_list);
730
if (select_node->select_list == &pars_star_denoter) {
732
/* SELECT * FROM ... */
733
pars_select_all_columns(select_node);
736
if (select_node->into_list) {
737
ut_a(que_node_list_get_len(select_node->into_list)
738
== que_node_list_get_len(select_node->select_list));
741
UT_LIST_INIT(select_node->copy_variables);
743
pars_resolve_exp_list_columns(table_list, select_node->select_list);
744
pars_resolve_exp_list_variables_and_types(select_node,
745
select_node->select_list);
746
pars_check_aggregate(select_node);
748
select_node->search_cond = search_cond;
751
pars_resolve_exp_columns(table_list, search_cond);
752
pars_resolve_exp_variables_and_types(select_node, search_cond);
758
select_node->set_x_locks = TRUE;
759
select_node->row_lock_mode = LOCK_X;
761
select_node->consistent_read = FALSE;
762
select_node->read_view = NULL;
763
} else if (lock_shared){
764
select_node->set_x_locks = FALSE;
765
select_node->row_lock_mode = LOCK_S;
767
select_node->consistent_read = FALSE;
768
select_node->read_view = NULL;
770
select_node->set_x_locks = FALSE;
771
select_node->row_lock_mode = LOCK_S;
773
select_node->consistent_read = TRUE;
776
select_node->order_by = order_by;
779
pars_resolve_exp_columns(table_list, order_by->column);
782
/* The final value of the following fields depend on the environment
783
where the select statement appears: */
785
select_node->can_get_updated = FALSE;
786
select_node->explicit_cursor = NULL;
788
opt_search_plan(select_node);
793
/*********************************************************************//**
794
Parses a cursor declaration.
798
pars_cursor_declaration(
799
/*====================*/
800
sym_node_t* sym_node, /*!< in: cursor id node in the symbol
802
sel_node_t* select_node) /*!< in: select node */
804
sym_node->resolved = TRUE;
805
sym_node->token_type = SYM_CURSOR;
806
sym_node->cursor_def = select_node;
808
select_node->state = SEL_NODE_CLOSED;
809
select_node->explicit_cursor = sym_node;
814
/*********************************************************************//**
815
Parses a function declaration.
819
pars_function_declaration(
820
/*======================*/
821
sym_node_t* sym_node) /*!< in: function id node in the symbol
824
sym_node->resolved = TRUE;
825
sym_node->token_type = SYM_FUNCTION;
827
/* Check that the function exists. */
828
ut_a(pars_info_get_user_func(pars_sym_tab_global->info,
834
/*********************************************************************//**
835
Parses a delete or update statement start.
836
@return own: update node in a query tree */
839
pars_update_statement_start(
840
/*========================*/
841
ibool is_delete, /*!< in: TRUE if delete */
842
sym_node_t* table_sym, /*!< in: table name node */
843
col_assign_node_t* col_assign_list)/*!< in: column assignment list, NULL
848
node = upd_node_create(pars_sym_tab_global->heap);
850
node->is_delete = is_delete;
852
node->table_sym = table_sym;
853
node->col_assign_list = col_assign_list;
858
/*********************************************************************//**
859
Parses a column assignment in an update.
860
@return column assignment node */
863
pars_column_assignment(
864
/*===================*/
865
sym_node_t* column, /*!< in: column to assign */
866
que_node_t* exp) /*!< in: value to assign */
868
col_assign_node_t* node;
870
node = static_cast<col_assign_node_t *>(mem_heap_alloc(pars_sym_tab_global->heap,
871
sizeof(col_assign_node_t)));
872
node->common.type = QUE_NODE_COL_ASSIGNMENT;
880
/*********************************************************************//**
881
Processes an update node assignment list. */
884
pars_process_assign_list(
885
/*=====================*/
886
upd_node_t* node) /*!< in: update node */
888
col_assign_node_t* col_assign_list;
889
sym_node_t* table_sym;
890
col_assign_node_t* assign_node;
891
upd_field_t* upd_field;
892
dict_index_t* clust_index;
894
ulint changes_ord_field;
895
ulint changes_field_size;
899
table_sym = node->table_sym;
900
col_assign_list = static_cast<col_assign_node_t *>(node->col_assign_list);
901
clust_index = dict_table_get_first_index(node->table);
903
assign_node = col_assign_list;
906
while (assign_node) {
907
pars_resolve_exp_columns(table_sym, assign_node->col);
908
pars_resolve_exp_columns(table_sym, assign_node->val);
909
pars_resolve_exp_variables_and_types(NULL, assign_node->val);
911
ut_a(dtype_get_mtype(
912
dfield_get_type(que_node_get_val(
915
dfield_get_type(que_node_get_val(
916
assign_node->val))));
919
/* Add to the update node all the columns found in assignment
920
values as columns to copy: therefore, TRUE */
922
opt_find_all_cols(TRUE, clust_index, &(node->columns), NULL,
926
assign_node = static_cast<col_assign_node_t *>(que_node_get_next(assign_node));
929
node->update = upd_create(n_assigns, pars_sym_tab_global->heap);
931
assign_node = col_assign_list;
933
changes_field_size = UPD_NODE_NO_SIZE_CHANGE;
935
for (i = 0; i < n_assigns; i++) {
936
upd_field = upd_get_nth_field(node->update, i);
938
col_sym = assign_node->col;
940
upd_field_set_field_no(upd_field, dict_index_get_nth_col_pos(
941
clust_index, col_sym->col_no),
943
upd_field->exp = assign_node->val;
945
if (!dict_col_get_fixed_size(
946
dict_index_get_nth_col(clust_index,
947
upd_field->field_no),
948
dict_table_is_comp(node->table))) {
949
changes_field_size = 0;
952
assign_node = static_cast<col_assign_node_t *>(que_node_get_next(assign_node));
955
/* Find out if the update can modify an ordering field in any index */
957
changes_ord_field = UPD_NODE_NO_ORD_CHANGE;
959
if (row_upd_changes_some_index_ord_field_binary(node->table,
961
changes_ord_field = 0;
964
node->cmpl_info = changes_ord_field | changes_field_size;
967
/*********************************************************************//**
968
Parses an update or delete statement.
969
@return own: update node in a query tree */
972
pars_update_statement(
973
/*==================*/
974
upd_node_t* node, /*!< in: update node */
975
sym_node_t* cursor_sym, /*!< in: pointer to a cursor entry in
976
the symbol table or NULL */
977
que_node_t* search_cond) /*!< in: search condition or NULL */
979
sym_node_t* table_sym;
980
sel_node_t* sel_node;
983
table_sym = node->table_sym;
985
pars_retrieve_table_def(table_sym);
986
node->table = table_sym->table;
988
UT_LIST_INIT(node->columns);
990
/* Make the single table node into a list of table nodes of length 1 */
992
que_node_list_add_last(NULL, table_sym);
995
pars_resolve_exp_variables_and_types(NULL, cursor_sym);
997
sel_node = cursor_sym->alias->cursor_def;
999
node->searched_update = FALSE;
1001
sel_node = pars_select_list(NULL, NULL);
1003
pars_select_statement(sel_node, table_sym, search_cond, NULL,
1004
&pars_share_token, NULL);
1005
node->searched_update = TRUE;
1006
sel_node->common.parent = node;
1009
node->select = sel_node;
1011
ut_a(!node->is_delete || (node->col_assign_list == NULL));
1012
ut_a(node->is_delete || (node->col_assign_list != NULL));
1014
if (node->is_delete) {
1015
node->cmpl_info = 0;
1017
pars_process_assign_list(node);
1020
if (node->searched_update) {
1021
node->has_clust_rec_x_lock = TRUE;
1022
sel_node->set_x_locks = TRUE;
1023
sel_node->row_lock_mode = LOCK_X;
1025
node->has_clust_rec_x_lock = sel_node->set_x_locks;
1028
ut_a(sel_node->n_tables == 1);
1029
ut_a(sel_node->consistent_read == FALSE);
1030
ut_a(sel_node->order_by == NULL);
1031
ut_a(sel_node->is_aggregate == FALSE);
1033
sel_node->can_get_updated = TRUE;
1035
node->state = UPD_NODE_UPDATE_CLUSTERED;
1037
plan = sel_node_get_nth_plan(sel_node, 0);
1039
plan->no_prefetch = TRUE;
1041
if (!dict_index_is_clust(plan->index)) {
1043
plan->must_get_clust = TRUE;
1045
node->pcur = &(plan->clust_pcur);
1047
node->pcur = &(plan->pcur);
1053
/*********************************************************************//**
1054
Parses an insert statement.
1055
@return own: update node in a query tree */
1058
pars_insert_statement(
1059
/*==================*/
1060
sym_node_t* table_sym, /*!< in: table name node */
1061
que_node_t* values_list, /*!< in: value expression list or NULL */
1062
sel_node_t* select) /*!< in: select condition or NULL */
1068
ut_a(values_list || select);
1069
ut_a(!values_list || !select);
1072
ins_type = INS_VALUES;
1074
ins_type = INS_SEARCHED;
1077
pars_retrieve_table_def(table_sym);
1079
node = ins_node_create(ins_type, table_sym->table,
1080
pars_sym_tab_global->heap);
1082
row = dtuple_create(pars_sym_tab_global->heap,
1083
dict_table_get_n_cols(node->table));
1085
dict_table_copy_types(row, table_sym->table);
1087
ins_node_set_new_row(node, row);
1089
node->select = select;
1092
select->common.parent = node;
1094
ut_a(que_node_list_get_len(select->select_list)
1095
== dict_table_get_n_user_cols(table_sym->table));
1098
node->values_list = values_list;
1100
if (node->values_list) {
1101
pars_resolve_exp_list_variables_and_types(NULL, values_list);
1103
ut_a(que_node_list_get_len(values_list)
1104
== dict_table_get_n_user_cols(table_sym->table));
1110
/*********************************************************************//**
1111
Set the type of a dfield. */
1114
pars_set_dfield_type(
1115
/*=================*/
1116
dfield_t* dfield, /*!< in: dfield */
1117
pars_res_word_t* type, /*!< in: pointer to a type
1119
ulint len, /*!< in: length, or 0 */
1120
ibool is_unsigned, /*!< in: if TRUE, column is
1122
ibool is_not_null) /*!< in: if TRUE, column is
1128
flags |= DATA_NOT_NULL;
1132
flags |= DATA_UNSIGNED;
1135
if (type == &pars_int_token) {
1136
ut_a((len == 0) || (len == 8));
1138
dtype_set(dfield_get_type(dfield), DATA_INT, flags, 8);
1140
dtype_set(dfield_get_type(dfield), DATA_INT, flags, 4);
1143
} else if (type == &pars_char_token) {
1146
dtype_set(dfield_get_type(dfield), DATA_VARCHAR,
1147
DATA_ENGLISH | flags, 0);
1148
} else if (type == &pars_binary_token) {
1151
dtype_set(dfield_get_type(dfield), DATA_FIXBINARY,
1152
DATA_BINARY_TYPE | flags, len);
1153
} else if (type == &pars_blob_token) {
1156
dtype_set(dfield_get_type(dfield), DATA_BLOB,
1157
DATA_BINARY_TYPE | flags, 0);
1163
/*********************************************************************//**
1164
Parses a variable declaration.
1165
@return own: symbol table node of type SYM_VAR */
1168
pars_variable_declaration(
1169
/*======================*/
1170
sym_node_t* node, /*!< in: symbol table node allocated for the
1171
id of the variable */
1172
pars_res_word_t* type) /*!< in: pointer to a type token */
1174
node->resolved = TRUE;
1175
node->token_type = SYM_VAR;
1177
node->param_type = PARS_NOT_PARAM;
1179
pars_set_dfield_type(que_node_get_val(node), type, 0, FALSE, FALSE);
1184
/*********************************************************************//**
1185
Parses a procedure parameter declaration.
1186
@return own: symbol table node of type SYM_VAR */
1189
pars_parameter_declaration(
1190
/*=======================*/
1191
sym_node_t* node, /*!< in: symbol table node allocated for the
1192
id of the parameter */
1194
/*!< in: PARS_INPUT or PARS_OUTPUT */
1195
pars_res_word_t* type) /*!< in: pointer to a type token */
1197
ut_a((param_type == PARS_INPUT) || (param_type == PARS_OUTPUT));
1199
pars_variable_declaration(node, type);
1201
node->param_type = param_type;
1206
/*********************************************************************//**
1207
Sets the parent field in a query node list. */
1210
pars_set_parent_in_list(
1211
/*====================*/
1212
que_node_t* node_list, /*!< in: first node in a list */
1213
que_node_t* parent) /*!< in: parent value to set in all
1214
nodes of the list */
1216
que_common_t* common;
1218
common = static_cast<que_common_t *>(node_list);
1221
common->parent = parent;
1223
common = static_cast<que_common_t *>(que_node_get_next(common));
1227
/*********************************************************************//**
1228
Parses an elsif element.
1229
@return elsif node */
1234
que_node_t* cond, /*!< in: if-condition */
1235
que_node_t* stat_list) /*!< in: statement list */
1239
node = static_cast<elsif_node_t *>(mem_heap_alloc(pars_sym_tab_global->heap, sizeof(elsif_node_t)));
1241
node->common.type = QUE_NODE_ELSIF;
1245
pars_resolve_exp_variables_and_types(NULL, cond);
1247
node->stat_list = stat_list;
1252
/*********************************************************************//**
1253
Parses an if-statement.
1254
@return if-statement node */
1259
que_node_t* cond, /*!< in: if-condition */
1260
que_node_t* stat_list, /*!< in: statement list */
1261
que_node_t* else_part) /*!< in: else-part statement list
1262
or elsif element list */
1265
elsif_node_t* elsif_node;
1267
node = static_cast<if_node_t *>(mem_heap_alloc(pars_sym_tab_global->heap, sizeof(if_node_t)));
1269
node->common.type = QUE_NODE_IF;
1273
pars_resolve_exp_variables_and_types(NULL, cond);
1275
node->stat_list = stat_list;
1277
if (else_part && (que_node_get_type(else_part) == QUE_NODE_ELSIF)) {
1279
/* There is a list of elsif conditions */
1281
node->else_part = NULL;
1282
node->elsif_list = static_cast<elsif_node_t *>(else_part);
1284
elsif_node = static_cast<elsif_node_t *>(else_part);
1286
while (elsif_node) {
1287
pars_set_parent_in_list(elsif_node->stat_list, node);
1289
elsif_node = static_cast<elsif_node_t *>(que_node_get_next(elsif_node));
1292
node->else_part = else_part;
1293
node->elsif_list = NULL;
1295
pars_set_parent_in_list(else_part, node);
1298
pars_set_parent_in_list(stat_list, node);
1303
/*********************************************************************//**
1304
Parses a while-statement.
1305
@return while-statement node */
1308
pars_while_statement(
1309
/*=================*/
1310
que_node_t* cond, /*!< in: while-condition */
1311
que_node_t* stat_list) /*!< in: statement list */
1315
node = static_cast<while_node_t *>(mem_heap_alloc(pars_sym_tab_global->heap, sizeof(while_node_t)));
1317
node->common.type = QUE_NODE_WHILE;
1321
pars_resolve_exp_variables_and_types(NULL, cond);
1323
node->stat_list = stat_list;
1325
pars_set_parent_in_list(stat_list, node);
1330
/*********************************************************************//**
1331
Parses a for-loop-statement.
1332
@return for-statement node */
1337
sym_node_t* loop_var, /*!< in: loop variable */
1338
que_node_t* loop_start_limit,/*!< in: loop start expression */
1339
que_node_t* loop_end_limit, /*!< in: loop end expression */
1340
que_node_t* stat_list) /*!< in: statement list */
1344
node = static_cast<for_node_t *>(mem_heap_alloc(pars_sym_tab_global->heap, sizeof(for_node_t)));
1346
node->common.type = QUE_NODE_FOR;
1348
pars_resolve_exp_variables_and_types(NULL, loop_var);
1349
pars_resolve_exp_variables_and_types(NULL, loop_start_limit);
1350
pars_resolve_exp_variables_and_types(NULL, loop_end_limit);
1352
node->loop_var = loop_var->indirection;
1354
ut_a(loop_var->indirection);
1356
node->loop_start_limit = loop_start_limit;
1357
node->loop_end_limit = loop_end_limit;
1359
node->stat_list = stat_list;
1361
pars_set_parent_in_list(stat_list, node);
1366
/*********************************************************************//**
1367
Parses an exit statement.
1368
@return exit statement node */
1371
pars_exit_statement(void)
1372
/*=====================*/
1376
node = static_cast<exit_node_t *>(mem_heap_alloc(pars_sym_tab_global->heap, sizeof(exit_node_t)));
1377
node->common.type = QUE_NODE_EXIT;
1382
/*********************************************************************//**
1383
Parses a return-statement.
1384
@return return-statement node */
1387
pars_return_statement(void)
1388
/*=======================*/
1390
return_node_t* node;
1392
node = static_cast<return_node_t *>(mem_heap_alloc(pars_sym_tab_global->heap,
1393
sizeof(return_node_t)));
1394
node->common.type = QUE_NODE_RETURN;
1399
/*********************************************************************//**
1400
Parses an assignment statement.
1401
@return assignment statement node */
1404
pars_assignment_statement(
1405
/*======================*/
1406
sym_node_t* var, /*!< in: variable to assign */
1407
que_node_t* val) /*!< in: value to assign */
1409
assign_node_t* node;
1411
node = static_cast<assign_node_t *>(mem_heap_alloc(pars_sym_tab_global->heap,
1412
sizeof(assign_node_t)));
1413
node->common.type = QUE_NODE_ASSIGNMENT;
1418
pars_resolve_exp_variables_and_types(NULL, var);
1419
pars_resolve_exp_variables_and_types(NULL, val);
1421
ut_a(dtype_get_mtype(dfield_get_type(que_node_get_val(var)))
1422
== dtype_get_mtype(dfield_get_type(que_node_get_val(val))));
1427
/*********************************************************************//**
1428
Parses a procedure call.
1429
@return function node */
1432
pars_procedure_call(
1433
/*================*/
1434
que_node_t* res_word,/*!< in: procedure name reserved word */
1435
que_node_t* args) /*!< in: argument list */
1439
node = pars_func(res_word, args);
1441
pars_resolve_exp_list_variables_and_types(NULL, args);
1446
/*********************************************************************//**
1447
Parses a fetch statement. into_list or user_func (but not both) must be
1449
@return fetch statement node */
1452
pars_fetch_statement(
1453
/*=================*/
1454
sym_node_t* cursor, /*!< in: cursor node */
1455
sym_node_t* into_list, /*!< in: variables to set, or NULL */
1456
sym_node_t* user_func) /*!< in: user function name, or NULL */
1458
sym_node_t* cursor_decl;
1462
ut_a(!into_list != !user_func);
1464
node = static_cast<fetch_node_t *>(mem_heap_alloc(pars_sym_tab_global->heap, sizeof(fetch_node_t)));
1466
node->common.type = QUE_NODE_FETCH;
1468
pars_resolve_exp_variables_and_types(NULL, cursor);
1471
pars_resolve_exp_list_variables_and_types(NULL, into_list);
1472
node->into_list = into_list;
1475
pars_resolve_exp_variables_and_types(NULL, user_func);
1477
node->func = pars_info_get_user_func(pars_sym_tab_global->info,
1481
node->into_list = NULL;
1484
cursor_decl = cursor->alias;
1486
ut_a(cursor_decl->token_type == SYM_CURSOR);
1488
node->cursor_def = cursor_decl->cursor_def;
1491
ut_a(que_node_list_get_len(into_list)
1492
== que_node_list_get_len(node->cursor_def->select_list));
1498
/*********************************************************************//**
1499
Parses an open or close cursor statement.
1500
@return fetch statement node */
1503
pars_open_statement(
1504
/*================*/
1505
ulint type, /*!< in: ROW_SEL_OPEN_CURSOR
1506
or ROW_SEL_CLOSE_CURSOR */
1507
sym_node_t* cursor) /*!< in: cursor node */
1509
sym_node_t* cursor_decl;
1512
node = static_cast<open_node_t *>(mem_heap_alloc(pars_sym_tab_global->heap, sizeof(open_node_t)));
1514
node->common.type = QUE_NODE_OPEN;
1516
pars_resolve_exp_variables_and_types(NULL, cursor);
1518
cursor_decl = cursor->alias;
1520
ut_a(cursor_decl->token_type == SYM_CURSOR);
1522
node->op_type = static_cast<open_node_op>(type);
1523
node->cursor_def = cursor_decl->cursor_def;
1528
/*********************************************************************//**
1529
Parses a row_printf-statement.
1530
@return row_printf-statement node */
1533
pars_row_printf_statement(
1534
/*======================*/
1535
sel_node_t* sel_node) /*!< in: select node */
1537
row_printf_node_t* node;
1539
node = static_cast<row_printf_node_t *>(mem_heap_alloc(pars_sym_tab_global->heap,
1540
sizeof(row_printf_node_t)));
1541
node->common.type = QUE_NODE_ROW_PRINTF;
1543
node->sel_node = sel_node;
1545
sel_node->common.parent = node;
1550
/*********************************************************************//**
1551
Parses a commit statement.
1552
@return own: commit node struct */
1555
pars_commit_statement(void)
1556
/*=======================*/
1558
return(commit_node_create(pars_sym_tab_global->heap));
1561
/*********************************************************************//**
1562
Parses a rollback statement.
1563
@return own: rollback node struct */
1566
pars_rollback_statement(void)
1567
/*=========================*/
1569
return(roll_node_create(pars_sym_tab_global->heap));
1572
/*********************************************************************//**
1573
Parses a column definition at a table creation.
1574
@return column sym table node */
1579
sym_node_t* sym_node, /*!< in: column node in the
1581
pars_res_word_t* type, /*!< in: data type */
1582
sym_node_t* len, /*!< in: length of column, or
1584
void* is_unsigned, /*!< in: if not NULL, column
1585
is of type UNSIGNED. */
1586
void* is_not_null) /*!< in: if not NULL, column
1587
is of type NOT NULL. */
1592
len2 = eval_node_get_int_val(len);
1597
pars_set_dfield_type(que_node_get_val(sym_node), type, len2,
1598
is_unsigned != NULL, is_not_null != NULL);
1603
/*********************************************************************//**
1604
Parses a table creation operation.
1605
@return table create subgraph */
1610
sym_node_t* table_sym, /*!< in: table name node in the symbol
1612
sym_node_t* column_defs, /*!< in: list of column names */
1613
void* /*not_fit_in_memory __attribute__((unused))*/)
1614
/*!< in: a non-NULL pointer means that
1615
this is a table which in simulations
1616
should be simulated as not fitting
1617
in memory; thread is put to sleep
1618
to simulate disk accesses; NOTE that
1619
this flag is not stored to the data
1620
dictionary on disk, and the database
1621
will forget about non-NULL value if
1622
it has to reload the table definition
1625
dict_table_t* table;
1628
const dtype_t* dtype;
1631
n_cols = que_node_list_get_len(column_defs);
1633
/* As the InnoDB SQL parser is for internal use only,
1634
for creating some system tables, this function will only
1635
create tables in the old (not compact) record format. */
1636
table = dict_mem_table_create(table_sym->name, 0, n_cols, 0);
1639
if (not_fit_in_memory != NULL) {
1640
table->does_not_fit_in_memory = TRUE;
1642
#endif /* UNIV_DEBUG */
1643
column = column_defs;
1646
dtype = dfield_get_type(que_node_get_val(column));
1648
dict_mem_table_add_col(table, table->heap,
1649
column->name, dtype->mtype,
1650
dtype->prtype, dtype->len);
1651
column->resolved = TRUE;
1652
column->token_type = SYM_COLUMN;
1654
column = static_cast<sym_node_t *>(que_node_get_next(column));
1657
node = tab_create_graph_create(table, pars_sym_tab_global->heap);
1659
table_sym->resolved = TRUE;
1660
table_sym->token_type = SYM_TABLE;
1665
/*********************************************************************//**
1666
Parses an index creation operation.
1667
@return index create subgraph */
1672
pars_res_word_t* unique_def, /*!< in: not NULL if a unique index */
1673
pars_res_word_t* clustered_def, /*!< in: not NULL if a clustered index */
1674
sym_node_t* index_sym, /*!< in: index name node in the symbol
1676
sym_node_t* table_sym, /*!< in: table name node in the symbol
1678
sym_node_t* column_list) /*!< in: list of column names */
1680
dict_index_t* index;
1686
n_fields = que_node_list_get_len(column_list);
1691
ind_type = ind_type | DICT_UNIQUE;
1694
if (clustered_def) {
1695
ind_type = ind_type | DICT_CLUSTERED;
1698
index = dict_mem_index_create(table_sym->name, index_sym->name, 0,
1699
ind_type, n_fields);
1700
column = column_list;
1703
dict_mem_index_add_field(index, column->name, 0);
1705
column->resolved = TRUE;
1706
column->token_type = SYM_COLUMN;
1708
column = static_cast<sym_node_t *>(que_node_get_next(column));
1711
node = ind_create_graph_create(index, pars_sym_tab_global->heap);
1713
table_sym->resolved = TRUE;
1714
table_sym->token_type = SYM_TABLE;
1716
index_sym->resolved = TRUE;
1717
index_sym->token_type = SYM_TABLE;
1722
/*********************************************************************//**
1723
Parses a procedure definition.
1724
@return query fork node */
1727
pars_procedure_definition(
1728
/*======================*/
1729
sym_node_t* sym_node, /*!< in: procedure id node in the symbol
1731
sym_node_t* param_list, /*!< in: parameter declaration list */
1732
que_node_t* stat_list) /*!< in: statement list */
1739
heap = pars_sym_tab_global->heap;
1741
fork = que_fork_create(NULL, NULL, QUE_FORK_PROCEDURE, heap);
1744
thr = que_thr_create(fork, heap);
1746
node = static_cast<proc_node_t *>(mem_heap_alloc(heap, sizeof(proc_node_t)));
1748
node->common.type = QUE_NODE_PROC;
1749
node->common.parent = thr;
1751
sym_node->token_type = SYM_PROCEDURE_NAME;
1752
sym_node->resolved = TRUE;
1754
node->proc_id = sym_node;
1755
node->param_list = param_list;
1756
node->stat_list = stat_list;
1758
pars_set_parent_in_list(stat_list, node);
1760
node->sym_tab = pars_sym_tab_global;
1764
pars_sym_tab_global->query_graph = fork;
1769
/*************************************************************//**
1770
Parses a stored procedure call, when this is not within another stored
1771
procedure, that is, the client issues a procedure call directly.
1772
In MySQL/InnoDB, stored InnoDB procedures are invoked via the
1773
parsed procedure tree, not via InnoDB SQL, so this function is not used.
1774
@return query graph */
1777
pars_stored_procedure_call(
1778
/*=======================*/
1779
sym_node_t* /*sym_node __attribute__((unused))*/)
1780
/*!< in: stored procedure name */
1786
/*************************************************************//**
1787
Retrieves characters to the lexical analyzer. */
1795
char* buf, /*!< in/out: buffer where to copy */
1796
int* result, /*!< out: number of characters copied or EOF */
1797
int max_size) /*!< in: maximum number of characters which fit
1802
len = pars_sym_tab_global->string_len
1803
- pars_sym_tab_global->next_char_pos;
1806
/* fputs("SQL string ends\n", stderr); */
1813
if (len > max_size) {
1817
#ifdef UNIV_SQL_DEBUG
1818
if (pars_print_lexed) {
1824
fwrite(pars_sym_tab_global->sql_string
1825
+ pars_sym_tab_global->next_char_pos,
1828
#endif /* UNIV_SQL_DEBUG */
1830
ut_memcpy(buf, pars_sym_tab_global->sql_string
1831
+ pars_sym_tab_global->next_char_pos, len);
1834
pars_sym_tab_global->next_char_pos += len;
1837
/*************************************************************//**
1838
Called by yyparse on error. */
1843
const char* /*s __attribute__((unused))*/)
1844
/*!< in: error message string */
1848
fputs("PARSER ERROR: Syntax error in SQL string\n", stderr);
1853
/*************************************************************//**
1854
Parses an SQL string returning the query graph.
1855
@return own: the query graph */
1860
pars_info_t* info, /*!< in: extra information, or NULL */
1861
const char* str) /*!< in: SQL string */
1863
sym_node_t* sym_node;
1869
heap = mem_heap_create(256);
1871
/* Currently, the parser is not reentrant: */
1872
ut_ad(mutex_own(&(dict_sys->mutex)));
1874
pars_sym_tab_global = sym_tab_create(heap);
1876
pars_sym_tab_global->string_len = strlen(str);
1877
pars_sym_tab_global->sql_string = static_cast<const char *>(mem_heap_dup(
1878
heap, str, pars_sym_tab_global->string_len + 1));
1879
pars_sym_tab_global->next_char_pos = 0;
1880
pars_sym_tab_global->info = info;
1884
sym_node = UT_LIST_GET_FIRST(pars_sym_tab_global->sym_list);
1887
ut_a(sym_node->resolved);
1889
sym_node = UT_LIST_GET_NEXT(sym_list, sym_node);
1892
graph = pars_sym_tab_global->query_graph;
1894
graph->sym_tab = pars_sym_tab_global;
1897
/* fprintf(stderr, "SQL graph size %lu\n", mem_heap_get_size(heap)); */
1902
/******************************************************************//**
1903
Completes a query graph by adding query thread and fork nodes
1904
above it and prepares the graph for running. The fork created is of
1905
type QUE_FORK_MYSQL_INTERFACE.
1906
@return query thread node to run */
1909
pars_complete_graph_for_exec(
1910
/*=========================*/
1911
que_node_t* node, /*!< in: root node for an incomplete
1913
trx_t* trx, /*!< in: transaction handle */
1914
mem_heap_t* heap) /*!< in: memory heap from which allocated */
1919
fork = que_fork_create(NULL, NULL, QUE_FORK_MYSQL_INTERFACE, heap);
1922
thr = que_thr_create(fork, heap);
1926
que_node_set_parent(node, thr);
1933
/****************************************************************//**
1934
Create parser info struct.
1935
@return own: info struct */
1938
pars_info_create(void)
1939
/*==================*/
1944
heap = mem_heap_create(512);
1946
info = static_cast<pars_info_t *>(mem_heap_alloc(heap, sizeof(*info)));
1950
info->bound_lits = NULL;
1951
info->bound_ids = NULL;
1952
info->graph_owns_us = TRUE;
1957
/****************************************************************//**
1958
Free info struct and everything it contains. */
1963
pars_info_t* info) /*!< in, own: info struct */
1965
mem_heap_free(info->heap);
1968
/****************************************************************//**
1969
Add bound literal. */
1972
pars_info_add_literal(
1973
/*==================*/
1974
pars_info_t* info, /*!< in: info struct */
1975
const char* name, /*!< in: name */
1976
const void* address, /*!< in: address */
1977
ulint length, /*!< in: length of data */
1978
ulint type, /*!< in: type, e.g. DATA_FIXBINARY */
1979
ulint prtype) /*!< in: precise type, e.g.
1982
pars_bound_lit_t* pbl;
1984
ut_ad(!pars_info_get_bound_lit(info, name));
1986
pbl = static_cast<pars_bound_lit_t *>(mem_heap_alloc(info->heap, sizeof(*pbl)));
1989
pbl->address = address;
1990
pbl->length = length;
1992
pbl->prtype = prtype;
1994
if (!info->bound_lits) {
1995
info->bound_lits = ib_vector_create(info->heap, 8);
1998
ib_vector_push(info->bound_lits, pbl);
2001
/****************************************************************//**
2002
Equivalent to pars_info_add_literal(info, name, str, strlen(str),
2003
DATA_VARCHAR, DATA_ENGLISH). */
2006
pars_info_add_str_literal(
2007
/*======================*/
2008
pars_info_t* info, /*!< in: info struct */
2009
const char* name, /*!< in: name */
2010
const char* str) /*!< in: string */
2012
pars_info_add_literal(info, name, str, strlen(str),
2013
DATA_VARCHAR, DATA_ENGLISH);
2016
/****************************************************************//**
2020
mach_write_to_4(buf, val);
2021
pars_info_add_literal(info, name, buf, 4, DATA_INT, 0);
2023
except that the buffer is dynamically allocated from the info struct's
2027
pars_info_add_int4_literal(
2028
/*=======================*/
2029
pars_info_t* info, /*!< in: info struct */
2030
const char* name, /*!< in: name */
2031
lint val) /*!< in: value */
2033
byte* buf = static_cast<byte *>(mem_heap_alloc(info->heap, 4));
2035
mach_write_to_4(buf, val);
2036
pars_info_add_literal(info, name, buf, 4, DATA_INT, 0);
2039
/****************************************************************//**
2043
mach_write_to_8(buf, val);
2044
pars_info_add_literal(info, name, buf, 8, DATA_FIXBINARY, 0);
2046
except that the buffer is dynamically allocated from the info struct's
2050
pars_info_add_ull_literal(
2051
/*======================*/
2052
pars_info_t* info, /*!< in: info struct */
2053
const char* name, /*!< in: name */
2054
ib_uint64_t val) /*!< in: value */
2056
byte* buf = static_cast<byte *>(mem_heap_alloc(info->heap, 8));
2058
mach_write_to_8(buf, val);
2060
pars_info_add_literal(info, name, buf, 8, DATA_FIXBINARY, 0);
2063
/****************************************************************//**
2064
Add user function. */
2067
pars_info_add_function(
2068
/*===================*/
2069
pars_info_t* info, /*!< in: info struct */
2070
const char* name, /*!< in: function name */
2071
pars_user_func_cb_t func, /*!< in: function address */
2072
void* arg) /*!< in: user-supplied argument */
2074
pars_user_func_t* puf;
2076
ut_ad(!pars_info_get_user_func(info, name));
2078
puf = static_cast<pars_user_func_t *>(mem_heap_alloc(info->heap, sizeof(*puf)));
2085
info->funcs = ib_vector_create(info->heap, 8);
2088
ib_vector_push(info->funcs, puf);
2091
/****************************************************************//**
2097
pars_info_t* info, /*!< in: info struct */
2098
const char* name, /*!< in: name */
2099
const char* id) /*!< in: id */
2101
pars_bound_id_t* bid;
2103
ut_ad(!pars_info_get_bound_id(info, name));
2105
bid = static_cast<pars_bound_id_t *>(mem_heap_alloc(info->heap, sizeof(*bid)));
2110
if (!info->bound_ids) {
2111
info->bound_ids = ib_vector_create(info->heap, 8);
2114
ib_vector_push(info->bound_ids, bid);
2117
/****************************************************************//**
2118
Get user function with the given name.
2119
@return user func, or NULL if not found */
2122
pars_info_get_user_func(
2123
/*====================*/
2124
pars_info_t* info, /*!< in: info struct */
2125
const char* name) /*!< in: function name to find*/
2130
if (!info || !info->funcs) {
2136
for (i = 0; i < ib_vector_size(vec); i++) {
2137
pars_user_func_t* puf = static_cast<pars_user_func_t *>(ib_vector_get(vec, i));
2139
if (strcmp(puf->name, name) == 0) {
2147
/****************************************************************//**
2148
Get bound literal with the given name.
2149
@return bound literal, or NULL if not found */
2152
pars_info_get_bound_lit(
2153
/*====================*/
2154
pars_info_t* info, /*!< in: info struct */
2155
const char* name) /*!< in: bound literal name to find */
2160
if (!info || !info->bound_lits) {
2164
vec = info->bound_lits;
2166
for (i = 0; i < ib_vector_size(vec); i++) {
2167
pars_bound_lit_t* pbl = static_cast<pars_bound_lit_t *>(ib_vector_get(vec, i));
2169
if (strcmp(pbl->name, name) == 0) {
2177
/****************************************************************//**
2178
Get bound id with the given name.
2179
@return bound id, or NULL if not found */
2182
pars_info_get_bound_id(
2183
/*===================*/
2184
pars_info_t* info, /*!< in: info struct */
2185
const char* name) /*!< in: bound id name to find */
2190
if (!info || !info->bound_ids) {
2194
vec = info->bound_ids;
2196
for (i = 0; i < ib_vector_size(vec); i++) {
2197
pars_bound_id_t* bid = static_cast<pars_bound_id_t *>(ib_vector_get(vec, i));
2199
if (strcmp(bid->name, name) == 0) {