1
/******************************************************
6
Created 11/19/1996 Heikki Tuuri
7
*******************************************************/
9
/* Historical note: Innobase executed its first SQL string (CREATE TABLE)
12
#include "pars0pars.h"
15
#include "pars0pars.ic"
21
#include "dict0dict.h"
23
#include "dict0crea.h"
27
#include "data0data.h"
28
#include "data0type.h"
31
#include "lock0lock.h"
32
#include "eval0eval.h"
35
/* If the following is set TRUE, the lexer will print the SQL string
38
ibool pars_print_lexed = FALSE;
39
#endif /* UNIV_SQL_DEBUG */
41
/* Global variable used while parsing a single procedure or query : the code is
43
sym_tab_t* pars_sym_tab_global;
45
/* Global variables used to denote certain reserved words, used in
46
constructing the parsing tree */
48
pars_res_word_t pars_to_char_token = {PARS_TO_CHAR_TOKEN};
49
pars_res_word_t pars_to_number_token = {PARS_TO_NUMBER_TOKEN};
50
pars_res_word_t pars_to_binary_token = {PARS_TO_BINARY_TOKEN};
51
pars_res_word_t pars_binary_to_number_token = {PARS_BINARY_TO_NUMBER_TOKEN};
52
pars_res_word_t pars_substr_token = {PARS_SUBSTR_TOKEN};
53
pars_res_word_t pars_replstr_token = {PARS_REPLSTR_TOKEN};
54
pars_res_word_t pars_concat_token = {PARS_CONCAT_TOKEN};
55
pars_res_word_t pars_instr_token = {PARS_INSTR_TOKEN};
56
pars_res_word_t pars_length_token = {PARS_LENGTH_TOKEN};
57
pars_res_word_t pars_sysdate_token = {PARS_SYSDATE_TOKEN};
58
pars_res_word_t pars_printf_token = {PARS_PRINTF_TOKEN};
59
pars_res_word_t pars_assert_token = {PARS_ASSERT_TOKEN};
60
pars_res_word_t pars_rnd_token = {PARS_RND_TOKEN};
61
pars_res_word_t pars_rnd_str_token = {PARS_RND_STR_TOKEN};
62
pars_res_word_t pars_count_token = {PARS_COUNT_TOKEN};
63
pars_res_word_t pars_sum_token = {PARS_SUM_TOKEN};
64
pars_res_word_t pars_distinct_token = {PARS_DISTINCT_TOKEN};
65
pars_res_word_t pars_binary_token = {PARS_BINARY_TOKEN};
66
pars_res_word_t pars_blob_token = {PARS_BLOB_TOKEN};
67
pars_res_word_t pars_int_token = {PARS_INT_TOKEN};
68
pars_res_word_t pars_char_token = {PARS_CHAR_TOKEN};
69
pars_res_word_t pars_float_token = {PARS_FLOAT_TOKEN};
70
pars_res_word_t pars_update_token = {PARS_UPDATE_TOKEN};
71
pars_res_word_t pars_asc_token = {PARS_ASC_TOKEN};
72
pars_res_word_t pars_desc_token = {PARS_DESC_TOKEN};
73
pars_res_word_t pars_open_token = {PARS_OPEN_TOKEN};
74
pars_res_word_t pars_close_token = {PARS_CLOSE_TOKEN};
75
pars_res_word_t pars_share_token = {PARS_SHARE_TOKEN};
76
pars_res_word_t pars_unique_token = {PARS_UNIQUE_TOKEN};
77
pars_res_word_t pars_clustered_token = {PARS_CLUSTERED_TOKEN};
79
/* Global variable used to denote the '*' in SELECT * FROM.. */
80
#define PARS_STAR_DENOTER 12345678
81
ulint pars_star_denoter = PARS_STAR_DENOTER;
84
/*************************************************************************
85
Determines the class of a function code. */
90
/* out: function class: PARS_FUNC_ARITH, ... */
91
int func) /* in: function code: '=', PARS_GE_TOKEN, ... */
93
if ((func == '+') || (func == '-') || (func == '*') || (func == '/')) {
95
return(PARS_FUNC_ARITH);
97
} else if ((func == '=') || (func == '<') || (func == '>')
98
|| (func == PARS_GE_TOKEN) || (func == PARS_LE_TOKEN)
99
|| (func == PARS_NE_TOKEN)) {
101
return(PARS_FUNC_CMP);
103
} else if ((func == PARS_AND_TOKEN) || (func == PARS_OR_TOKEN)
104
|| (func == PARS_NOT_TOKEN)) {
106
return(PARS_FUNC_LOGICAL);
108
} else if ((func == PARS_COUNT_TOKEN) || (func == PARS_SUM_TOKEN)) {
110
return(PARS_FUNC_AGGREGATE);
112
} else if ((func == PARS_TO_CHAR_TOKEN)
113
|| (func == PARS_TO_NUMBER_TOKEN)
114
|| (func == PARS_TO_BINARY_TOKEN)
115
|| (func == PARS_BINARY_TO_NUMBER_TOKEN)
116
|| (func == PARS_SUBSTR_TOKEN)
117
|| (func == PARS_CONCAT_TOKEN)
118
|| (func == PARS_LENGTH_TOKEN)
119
|| (func == PARS_INSTR_TOKEN)
120
|| (func == PARS_SYSDATE_TOKEN)
121
|| (func == PARS_NOTFOUND_TOKEN)
122
|| (func == PARS_PRINTF_TOKEN)
123
|| (func == PARS_ASSERT_TOKEN)
124
|| (func == PARS_RND_TOKEN)
125
|| (func == PARS_RND_STR_TOKEN)
126
|| (func == PARS_REPLSTR_TOKEN)) {
128
return(PARS_FUNC_PREDEFINED);
130
return(PARS_FUNC_OTHER);
134
/*************************************************************************
135
Parses an operator or predefined function expression. */
140
/* out, own: function node in a query tree */
141
int func, /* in: function token code */
142
que_node_t* arg) /* in: first argument in the argument list */
146
node = mem_heap_alloc(pars_sym_tab_global->heap, sizeof(func_node_t));
148
node->common.type = QUE_NODE_FUNC;
149
dfield_set_data(&(node->common.val), NULL, 0);
150
node->common.val_buf_size = 0;
154
node->class = pars_func_get_class(func);
158
UT_LIST_ADD_LAST(func_node_list, pars_sym_tab_global->func_node_list,
163
/*************************************************************************
164
Parses a function expression. */
169
/* out, own: function node in a query tree */
170
que_node_t* res_word,/* in: function name reserved word */
171
que_node_t* arg) /* in: first argument in the argument list */
173
return(pars_func_low(((pars_res_word_t*)res_word)->code, arg));
176
/*************************************************************************
177
Parses an operator expression. */
182
/* out, own: function node in a query tree */
183
int func, /* in: operator token code */
184
que_node_t* arg1, /* in: first argument */
185
que_node_t* arg2) /* in: second argument or NULL for an unary
188
que_node_list_add_last(NULL, arg1);
191
que_node_list_add_last(arg1, arg2);
194
return(pars_func_low(func, arg1));
197
/*************************************************************************
198
Parses an ORDER BY clause. Order by a single column only is supported. */
203
/* out, own: order-by node in a query tree */
204
sym_node_t* column, /* in: column name */
205
pars_res_word_t* asc) /* in: &pars_asc_token or pars_desc_token */
209
node = mem_heap_alloc(pars_sym_tab_global->heap, sizeof(order_node_t));
211
node->common.type = QUE_NODE_ORDER;
213
node->column = column;
215
if (asc == &pars_asc_token) {
218
ut_a(asc == &pars_desc_token);
225
/*************************************************************************
226
Resolves the data type of a function in an expression. The argument data
227
types must already be resolved. */
230
pars_resolve_func_data_type(
231
/*========================*/
232
func_node_t* node) /* in: function node */
237
ut_a(que_node_get_type(node) == QUE_NODE_FUNC);
243
if ((func == PARS_SUM_TOKEN)
244
|| (func == '+') || (func == '-') || (func == '*')
245
|| (func == '/') || (func == '+')) {
247
/* Inherit the data type from the first argument (which must
248
not be the SQL null literal whose type is DATA_ERROR) */
250
dtype_copy(que_node_get_data_type(node),
251
que_node_get_data_type(arg));
253
ut_a(dtype_get_mtype(que_node_get_data_type(node))
255
} else if (func == PARS_COUNT_TOKEN) {
257
dtype_set(que_node_get_data_type(node), DATA_INT, 0, 4);
259
} else if (func == PARS_TO_CHAR_TOKEN) {
260
ut_a(dtype_get_mtype(que_node_get_data_type(arg)) == DATA_INT);
261
dtype_set(que_node_get_data_type(node), DATA_VARCHAR,
263
} else if (func == PARS_TO_BINARY_TOKEN) {
264
if (dtype_get_mtype(que_node_get_data_type(arg)) == DATA_INT) {
265
dtype_set(que_node_get_data_type(node), DATA_VARCHAR,
268
dtype_set(que_node_get_data_type(node), DATA_BINARY,
271
} else if (func == PARS_TO_NUMBER_TOKEN) {
272
ut_a(dtype_get_mtype(que_node_get_data_type(arg))
274
dtype_set(que_node_get_data_type(node), DATA_INT, 0, 4);
276
} else if (func == PARS_BINARY_TO_NUMBER_TOKEN) {
277
ut_a(dtype_get_mtype(que_node_get_data_type(arg))
279
dtype_set(que_node_get_data_type(node), DATA_INT, 0, 4);
281
} else if (func == PARS_LENGTH_TOKEN) {
282
ut_a(dtype_get_mtype(que_node_get_data_type(arg))
284
dtype_set(que_node_get_data_type(node), DATA_INT, 0, 4);
286
} else if (func == PARS_INSTR_TOKEN) {
287
ut_a(dtype_get_mtype(que_node_get_data_type(arg))
289
dtype_set(que_node_get_data_type(node), DATA_INT, 0, 4);
291
} else if (func == PARS_SYSDATE_TOKEN) {
293
dtype_set(que_node_get_data_type(node), DATA_INT, 0, 4);
295
} else if ((func == PARS_SUBSTR_TOKEN)
296
|| (func == PARS_CONCAT_TOKEN)) {
298
ut_a(dtype_get_mtype(que_node_get_data_type(arg))
300
dtype_set(que_node_get_data_type(node), DATA_VARCHAR,
303
} else if ((func == '>') || (func == '<') || (func == '=')
304
|| (func == PARS_GE_TOKEN)
305
|| (func == PARS_LE_TOKEN)
306
|| (func == PARS_NE_TOKEN)
307
|| (func == PARS_AND_TOKEN)
308
|| (func == PARS_OR_TOKEN)
309
|| (func == PARS_NOT_TOKEN)
310
|| (func == PARS_NOTFOUND_TOKEN)) {
312
/* We currently have no iboolean type: use integer type */
313
dtype_set(que_node_get_data_type(node), DATA_INT, 0, 4);
315
} else if (func == PARS_RND_TOKEN) {
316
ut_a(dtype_get_mtype(que_node_get_data_type(arg)) == DATA_INT);
318
dtype_set(que_node_get_data_type(node), DATA_INT, 0, 4);
320
} else if (func == PARS_RND_STR_TOKEN) {
321
ut_a(dtype_get_mtype(que_node_get_data_type(arg)) == DATA_INT);
323
dtype_set(que_node_get_data_type(node), DATA_VARCHAR,
330
/*************************************************************************
331
Resolves the meaning of variables in an expression and the data types of
332
functions. It is an error if some identifier cannot be resolved here. */
335
pars_resolve_exp_variables_and_types(
336
/*=================================*/
337
sel_node_t* select_node, /* in: select node or NULL; if
338
this is not NULL then the variable
339
sym nodes are added to the
340
copy_variables list of select_node */
341
que_node_t* exp_node) /* in: expression */
343
func_node_t* func_node;
345
sym_node_t* sym_node;
350
if (que_node_get_type(exp_node) == QUE_NODE_FUNC) {
351
func_node = exp_node;
353
arg = func_node->args;
356
pars_resolve_exp_variables_and_types(select_node, arg);
358
arg = que_node_get_next(arg);
361
pars_resolve_func_data_type(func_node);
366
ut_a(que_node_get_type(exp_node) == QUE_NODE_SYMBOL);
370
if (sym_node->resolved) {
375
/* Not resolved yet: look in the symbol table for a variable
376
or a cursor or a function with the same name */
378
node = UT_LIST_GET_FIRST(pars_sym_tab_global->sym_list);
382
&& ((node->token_type == SYM_VAR)
383
|| (node->token_type == SYM_CURSOR)
384
|| (node->token_type == SYM_FUNCTION))
386
&& (sym_node->name_len == node->name_len)
387
&& (ut_memcmp(sym_node->name, node->name,
388
node->name_len) == 0)) {
390
/* Found a variable or a cursor declared with
396
node = UT_LIST_GET_NEXT(sym_list, node);
400
fprintf(stderr, "PARSER ERROR: Unresolved identifier %s\n",
406
sym_node->resolved = TRUE;
407
sym_node->token_type = SYM_IMPLICIT_VAR;
408
sym_node->alias = node;
409
sym_node->indirection = node;
412
UT_LIST_ADD_LAST(col_var_list, select_node->copy_variables,
416
dfield_set_type(que_node_get_val(sym_node),
417
que_node_get_data_type(node));
420
/*************************************************************************
421
Resolves the meaning of variables in an expression list. It is an error if
422
some identifier cannot be resolved here. Resolves also the data types of
426
pars_resolve_exp_list_variables_and_types(
427
/*======================================*/
428
sel_node_t* select_node, /* in: select node or NULL */
429
que_node_t* exp_node) /* in: expression list first node, or
433
pars_resolve_exp_variables_and_types(select_node, exp_node);
435
exp_node = que_node_get_next(exp_node);
439
/*************************************************************************
440
Resolves the columns in an expression. */
443
pars_resolve_exp_columns(
444
/*=====================*/
445
sym_node_t* table_node, /* in: first node in a table list */
446
que_node_t* exp_node) /* in: expression */
448
func_node_t* func_node;
450
sym_node_t* sym_node;
458
if (que_node_get_type(exp_node) == QUE_NODE_FUNC) {
459
func_node = exp_node;
461
arg = func_node->args;
464
pars_resolve_exp_columns(table_node, arg);
466
arg = que_node_get_next(arg);
472
ut_a(que_node_get_type(exp_node) == QUE_NODE_SYMBOL);
476
if (sym_node->resolved) {
481
/* Not resolved yet: look in the table list for a column with the
487
table = t_node->table;
489
n_cols = dict_table_get_n_cols(table);
491
for (i = 0; i < n_cols; i++) {
492
const dict_col_t* col
493
= dict_table_get_nth_col(table, i);
495
= dict_table_get_col_name(table, i);
497
if ((sym_node->name_len == ut_strlen(col_name))
498
&& (0 == ut_memcmp(sym_node->name, col_name,
499
sym_node->name_len))) {
501
sym_node->resolved = TRUE;
502
sym_node->token_type = SYM_COLUMN;
503
sym_node->table = table;
504
sym_node->col_no = i;
505
sym_node->prefetch_buf = NULL;
509
dfield_get_type(&sym_node
516
t_node = que_node_get_next(t_node);
520
/*************************************************************************
521
Resolves the meaning of columns in an expression list. */
524
pars_resolve_exp_list_columns(
525
/*==========================*/
526
sym_node_t* table_node, /* in: first node in a table list */
527
que_node_t* exp_node) /* in: expression list first node, or
531
pars_resolve_exp_columns(table_node, exp_node);
533
exp_node = que_node_get_next(exp_node);
537
/*************************************************************************
538
Retrieves the table definition for a table name id. */
541
pars_retrieve_table_def(
542
/*====================*/
543
sym_node_t* sym_node) /* in: table node */
545
const char* table_name;
548
ut_a(que_node_get_type(sym_node) == QUE_NODE_SYMBOL);
550
sym_node->resolved = TRUE;
551
sym_node->token_type = SYM_TABLE;
553
table_name = (const char*) sym_node->name;
555
sym_node->table = dict_table_get_low(table_name);
557
ut_a(sym_node->table);
560
/*************************************************************************
561
Retrieves the table definitions for a list of table name ids. */
564
pars_retrieve_table_list_defs(
565
/*==========================*/
566
/* out: number of tables */
567
sym_node_t* sym_node) /* in: first table node in list */
571
if (sym_node == NULL) {
577
pars_retrieve_table_def(sym_node);
581
sym_node = que_node_get_next(sym_node);
587
/*************************************************************************
588
Adds all columns to the select list if the query is SELECT * FROM ... */
591
pars_select_all_columns(
592
/*====================*/
593
sel_node_t* select_node) /* in: select node already containing
596
sym_node_t* col_node;
597
sym_node_t* table_node;
601
select_node->select_list = NULL;
603
table_node = select_node->table_list;
606
table = table_node->table;
608
for (i = 0; i < dict_table_get_n_user_cols(table); i++) {
609
const char* col_name = dict_table_get_col_name(
612
col_node = sym_tab_add_id(pars_sym_tab_global,
614
ut_strlen(col_name));
616
select_node->select_list = que_node_list_add_last(
617
select_node->select_list, col_node);
620
table_node = que_node_get_next(table_node);
624
/*************************************************************************
625
Parses a select list; creates a query graph node for the whole SELECT
631
/* out, own: select node in a query
633
que_node_t* select_list, /* in: select list */
634
sym_node_t* into_list) /* in: variables list or NULL */
638
node = sel_node_create(pars_sym_tab_global->heap);
640
node->select_list = select_list;
641
node->into_list = into_list;
643
pars_resolve_exp_list_variables_and_types(NULL, into_list);
648
/*************************************************************************
649
Checks if the query is an aggregate query, in which case the selct list must
650
contain only aggregate function items. */
653
pars_check_aggregate(
654
/*=================*/
655
sel_node_t* select_node) /* in: select node already containing
658
que_node_t* exp_node;
659
func_node_t* func_node;
661
ulint n_aggregate_nodes = 0;
663
exp_node = select_node->select_list;
669
if (que_node_get_type(exp_node) == QUE_NODE_FUNC) {
671
func_node = exp_node;
673
if (func_node->class == PARS_FUNC_AGGREGATE) {
679
exp_node = que_node_get_next(exp_node);
682
if (n_aggregate_nodes > 0) {
683
ut_a(n_nodes == n_aggregate_nodes);
685
select_node->is_aggregate = TRUE;
687
select_node->is_aggregate = FALSE;
691
/*************************************************************************
692
Parses a select statement. */
695
pars_select_statement(
696
/*==================*/
697
/* out, own: select node in a query
699
sel_node_t* select_node, /* in: select node already containing
701
sym_node_t* table_list, /* in: table list */
702
que_node_t* search_cond, /* in: search condition or NULL */
703
pars_res_word_t* for_update, /* in: NULL or &pars_update_token */
704
pars_res_word_t* lock_shared, /* in: NULL or &pars_share_token */
705
order_node_t* order_by) /* in: NULL or an order-by node */
707
select_node->state = SEL_NODE_OPEN;
709
select_node->table_list = table_list;
710
select_node->n_tables = pars_retrieve_table_list_defs(table_list);
712
if (select_node->select_list == &pars_star_denoter) {
714
/* SELECT * FROM ... */
715
pars_select_all_columns(select_node);
718
if (select_node->into_list) {
719
ut_a(que_node_list_get_len(select_node->into_list)
720
== que_node_list_get_len(select_node->select_list));
723
UT_LIST_INIT(select_node->copy_variables);
725
pars_resolve_exp_list_columns(table_list, select_node->select_list);
726
pars_resolve_exp_list_variables_and_types(select_node,
727
select_node->select_list);
728
pars_check_aggregate(select_node);
730
select_node->search_cond = search_cond;
733
pars_resolve_exp_columns(table_list, search_cond);
734
pars_resolve_exp_variables_and_types(select_node, search_cond);
740
select_node->set_x_locks = TRUE;
741
select_node->row_lock_mode = LOCK_X;
743
select_node->consistent_read = FALSE;
744
select_node->read_view = NULL;
745
} else if (lock_shared){
746
select_node->set_x_locks = FALSE;
747
select_node->row_lock_mode = LOCK_S;
749
select_node->consistent_read = FALSE;
750
select_node->read_view = NULL;
752
select_node->set_x_locks = FALSE;
753
select_node->row_lock_mode = LOCK_S;
755
select_node->consistent_read = TRUE;
758
select_node->order_by = order_by;
761
pars_resolve_exp_columns(table_list, order_by->column);
764
/* The final value of the following fields depend on the environment
765
where the select statement appears: */
767
select_node->can_get_updated = FALSE;
768
select_node->explicit_cursor = NULL;
770
opt_search_plan(select_node);
775
/*************************************************************************
776
Parses a cursor declaration. */
779
pars_cursor_declaration(
780
/*====================*/
782
sym_node_t* sym_node, /* in: cursor id node in the symbol
784
sel_node_t* select_node) /* in: select node */
786
sym_node->resolved = TRUE;
787
sym_node->token_type = SYM_CURSOR;
788
sym_node->cursor_def = select_node;
790
select_node->state = SEL_NODE_CLOSED;
791
select_node->explicit_cursor = sym_node;
796
/*************************************************************************
797
Parses a function declaration. */
800
pars_function_declaration(
801
/*======================*/
803
sym_node_t* sym_node) /* in: function id node in the symbol
806
sym_node->resolved = TRUE;
807
sym_node->token_type = SYM_FUNCTION;
809
/* Check that the function exists. */
810
ut_a(pars_info_get_user_func(pars_sym_tab_global->info,
816
/*************************************************************************
817
Parses a delete or update statement start. */
820
pars_update_statement_start(
821
/*========================*/
822
/* out, own: update node in a query
824
ibool is_delete, /* in: TRUE if delete */
825
sym_node_t* table_sym, /* in: table name node */
826
col_assign_node_t* col_assign_list)/* in: column assignment list, NULL
831
node = upd_node_create(pars_sym_tab_global->heap);
833
node->is_delete = is_delete;
835
node->table_sym = table_sym;
836
node->col_assign_list = col_assign_list;
841
/*************************************************************************
842
Parses a column assignment in an update. */
845
pars_column_assignment(
846
/*===================*/
847
/* out: column assignment node */
848
sym_node_t* column, /* in: column to assign */
849
que_node_t* exp) /* in: value to assign */
851
col_assign_node_t* node;
853
node = mem_heap_alloc(pars_sym_tab_global->heap,
854
sizeof(col_assign_node_t));
855
node->common.type = QUE_NODE_COL_ASSIGNMENT;
863
/*************************************************************************
864
Processes an update node assignment list. */
867
pars_process_assign_list(
868
/*=====================*/
869
upd_node_t* node) /* in: update node */
871
col_assign_node_t* col_assign_list;
872
sym_node_t* table_sym;
873
col_assign_node_t* assign_node;
874
upd_field_t* upd_field;
875
dict_index_t* clust_index;
877
ulint changes_ord_field;
878
ulint changes_field_size;
882
table_sym = node->table_sym;
883
col_assign_list = node->col_assign_list;
884
clust_index = dict_table_get_first_index(node->table);
886
assign_node = col_assign_list;
889
while (assign_node) {
890
pars_resolve_exp_columns(table_sym, assign_node->col);
891
pars_resolve_exp_columns(table_sym, assign_node->val);
892
pars_resolve_exp_variables_and_types(NULL, assign_node->val);
894
ut_a(dtype_get_mtype(
895
dfield_get_type(que_node_get_val(
898
dfield_get_type(que_node_get_val(
899
assign_node->val))));
902
/* Add to the update node all the columns found in assignment
903
values as columns to copy: therefore, TRUE */
905
opt_find_all_cols(TRUE, clust_index, &(node->columns), NULL,
909
assign_node = que_node_get_next(assign_node);
912
node->update = upd_create(n_assigns, pars_sym_tab_global->heap);
914
assign_node = col_assign_list;
916
changes_field_size = UPD_NODE_NO_SIZE_CHANGE;
918
for (i = 0; i < n_assigns; i++) {
919
upd_field = upd_get_nth_field(node->update, i);
921
col_sym = assign_node->col;
923
upd_field_set_field_no(upd_field, dict_index_get_nth_col_pos(
924
clust_index, col_sym->col_no),
926
upd_field->exp = assign_node->val;
928
if (!dict_col_get_fixed_size(
929
dict_index_get_nth_col(clust_index,
930
upd_field->field_no))) {
931
changes_field_size = 0;
934
assign_node = que_node_get_next(assign_node);
937
/* Find out if the update can modify an ordering field in any index */
939
changes_ord_field = UPD_NODE_NO_ORD_CHANGE;
941
if (row_upd_changes_some_index_ord_field_binary(node->table,
943
changes_ord_field = 0;
946
node->cmpl_info = changes_ord_field | changes_field_size;
949
/*************************************************************************
950
Parses an update or delete statement. */
953
pars_update_statement(
954
/*==================*/
955
/* out, own: update node in a query
957
upd_node_t* node, /* in: update node */
958
sym_node_t* cursor_sym, /* in: pointer to a cursor entry in
959
the symbol table or NULL */
960
que_node_t* search_cond) /* in: search condition or NULL */
962
sym_node_t* table_sym;
963
sel_node_t* sel_node;
966
table_sym = node->table_sym;
968
pars_retrieve_table_def(table_sym);
969
node->table = table_sym->table;
971
UT_LIST_INIT(node->columns);
973
/* Make the single table node into a list of table nodes of length 1 */
975
que_node_list_add_last(NULL, table_sym);
978
pars_resolve_exp_variables_and_types(NULL, cursor_sym);
980
sel_node = cursor_sym->alias->cursor_def;
982
node->searched_update = FALSE;
984
sel_node = pars_select_list(NULL, NULL);
986
pars_select_statement(sel_node, table_sym, search_cond, NULL,
987
&pars_share_token, NULL);
988
node->searched_update = TRUE;
989
sel_node->common.parent = node;
992
node->select = sel_node;
994
ut_a(!node->is_delete || (node->col_assign_list == NULL));
995
ut_a(node->is_delete || (node->col_assign_list != NULL));
997
if (node->is_delete) {
1000
pars_process_assign_list(node);
1003
if (node->searched_update) {
1004
node->has_clust_rec_x_lock = TRUE;
1005
sel_node->set_x_locks = TRUE;
1006
sel_node->row_lock_mode = LOCK_X;
1008
node->has_clust_rec_x_lock = sel_node->set_x_locks;
1011
ut_a(sel_node->n_tables == 1);
1012
ut_a(sel_node->consistent_read == FALSE);
1013
ut_a(sel_node->order_by == NULL);
1014
ut_a(sel_node->is_aggregate == FALSE);
1016
sel_node->can_get_updated = TRUE;
1018
node->state = UPD_NODE_UPDATE_CLUSTERED;
1020
plan = sel_node_get_nth_plan(sel_node, 0);
1022
plan->no_prefetch = TRUE;
1024
if (!((plan->index)->type & DICT_CLUSTERED)) {
1026
plan->must_get_clust = TRUE;
1028
node->pcur = &(plan->clust_pcur);
1030
node->pcur = &(plan->pcur);
1033
if (!node->is_delete && node->searched_update
1034
&& (node->cmpl_info & UPD_NODE_NO_SIZE_CHANGE)
1035
&& (node->cmpl_info & UPD_NODE_NO_ORD_CHANGE)) {
1037
/* The select node can perform the update in-place */
1041
node->select_will_do_update = TRUE;
1042
sel_node->select_will_do_update = TRUE;
1043
sel_node->latch_mode = BTR_MODIFY_LEAF;
1049
/*************************************************************************
1050
Parses an insert statement. */
1053
pars_insert_statement(
1054
/*==================*/
1055
/* out, own: update node in a query
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. */
1161
pars_variable_declaration(
1162
/*======================*/
1163
/* out, own: symbol table node of type
1165
sym_node_t* node, /* in: symbol table node allocated for the
1166
id of the variable */
1167
pars_res_word_t* type) /* in: pointer to a type token */
1169
node->resolved = TRUE;
1170
node->token_type = SYM_VAR;
1172
node->param_type = PARS_NOT_PARAM;
1174
pars_set_dfield_type(que_node_get_val(node), type, 0, FALSE, FALSE);
1179
/*************************************************************************
1180
Parses a procedure parameter declaration. */
1183
pars_parameter_declaration(
1184
/*=======================*/
1185
/* out, own: symbol table node of type
1187
sym_node_t* node, /* in: symbol table node allocated for the
1188
id of the parameter */
1190
/* in: PARS_INPUT or PARS_OUTPUT */
1191
pars_res_word_t* type) /* in: pointer to a type token */
1193
ut_a((param_type == PARS_INPUT) || (param_type == PARS_OUTPUT));
1195
pars_variable_declaration(node, type);
1197
node->param_type = param_type;
1202
/*************************************************************************
1203
Sets the parent field in a query node list. */
1206
pars_set_parent_in_list(
1207
/*====================*/
1208
que_node_t* node_list, /* in: first node in a list */
1209
que_node_t* parent) /* in: parent value to set in all
1210
nodes of the list */
1212
que_common_t* common;
1217
common->parent = parent;
1219
common = que_node_get_next(common);
1223
/*************************************************************************
1224
Parses an elsif element. */
1229
/* out: elsif node */
1230
que_node_t* cond, /* in: if-condition */
1231
que_node_t* stat_list) /* in: statement list */
1235
node = mem_heap_alloc(pars_sym_tab_global->heap, sizeof(elsif_node_t));
1237
node->common.type = QUE_NODE_ELSIF;
1241
pars_resolve_exp_variables_and_types(NULL, cond);
1243
node->stat_list = stat_list;
1248
/*************************************************************************
1249
Parses an if-statement. */
1254
/* out: if-statement node */
1255
que_node_t* cond, /* in: if-condition */
1256
que_node_t* stat_list, /* in: statement list */
1257
que_node_t* else_part) /* in: else-part statement list
1258
or elsif element list */
1261
elsif_node_t* elsif_node;
1263
node = mem_heap_alloc(pars_sym_tab_global->heap, sizeof(if_node_t));
1265
node->common.type = QUE_NODE_IF;
1269
pars_resolve_exp_variables_and_types(NULL, cond);
1271
node->stat_list = stat_list;
1273
if (else_part && (que_node_get_type(else_part) == QUE_NODE_ELSIF)) {
1275
/* There is a list of elsif conditions */
1277
node->else_part = NULL;
1278
node->elsif_list = else_part;
1280
elsif_node = else_part;
1282
while (elsif_node) {
1283
pars_set_parent_in_list(elsif_node->stat_list, node);
1285
elsif_node = que_node_get_next(elsif_node);
1288
node->else_part = else_part;
1289
node->elsif_list = NULL;
1291
pars_set_parent_in_list(else_part, node);
1294
pars_set_parent_in_list(stat_list, node);
1299
/*************************************************************************
1300
Parses a while-statement. */
1303
pars_while_statement(
1304
/*=================*/
1305
/* out: while-statement node */
1306
que_node_t* cond, /* in: while-condition */
1307
que_node_t* stat_list) /* in: statement list */
1311
node = mem_heap_alloc(pars_sym_tab_global->heap, sizeof(while_node_t));
1313
node->common.type = QUE_NODE_WHILE;
1317
pars_resolve_exp_variables_and_types(NULL, cond);
1319
node->stat_list = stat_list;
1321
pars_set_parent_in_list(stat_list, node);
1326
/*************************************************************************
1327
Parses a for-loop-statement. */
1332
/* out: for-statement node */
1333
sym_node_t* loop_var, /* in: loop variable */
1334
que_node_t* loop_start_limit,/* in: loop start expression */
1335
que_node_t* loop_end_limit, /* in: loop end expression */
1336
que_node_t* stat_list) /* in: statement list */
1340
node = mem_heap_alloc(pars_sym_tab_global->heap, sizeof(for_node_t));
1342
node->common.type = QUE_NODE_FOR;
1344
pars_resolve_exp_variables_and_types(NULL, loop_var);
1345
pars_resolve_exp_variables_and_types(NULL, loop_start_limit);
1346
pars_resolve_exp_variables_and_types(NULL, loop_end_limit);
1348
node->loop_var = loop_var->indirection;
1350
ut_a(loop_var->indirection);
1352
node->loop_start_limit = loop_start_limit;
1353
node->loop_end_limit = loop_end_limit;
1355
node->stat_list = stat_list;
1357
pars_set_parent_in_list(stat_list, node);
1362
/*************************************************************************
1363
Parses an exit statement. */
1366
pars_exit_statement(void)
1367
/*=====================*/
1368
/* out: exit statement node */
1372
node = mem_heap_alloc(pars_sym_tab_global->heap, sizeof(exit_node_t));
1373
node->common.type = QUE_NODE_EXIT;
1378
/*************************************************************************
1379
Parses a return-statement. */
1382
pars_return_statement(void)
1383
/*=======================*/
1384
/* out: return-statement node */
1386
return_node_t* node;
1388
node = mem_heap_alloc(pars_sym_tab_global->heap,
1389
sizeof(return_node_t));
1390
node->common.type = QUE_NODE_RETURN;
1395
/*************************************************************************
1396
Parses an assignment statement. */
1399
pars_assignment_statement(
1400
/*======================*/
1401
/* out: assignment statement node */
1402
sym_node_t* var, /* in: variable to assign */
1403
que_node_t* val) /* in: value to assign */
1405
assign_node_t* node;
1407
node = mem_heap_alloc(pars_sym_tab_global->heap,
1408
sizeof(assign_node_t));
1409
node->common.type = QUE_NODE_ASSIGNMENT;
1414
pars_resolve_exp_variables_and_types(NULL, var);
1415
pars_resolve_exp_variables_and_types(NULL, val);
1417
ut_a(dtype_get_mtype(dfield_get_type(que_node_get_val(var)))
1418
== dtype_get_mtype(dfield_get_type(que_node_get_val(val))));
1423
/*************************************************************************
1424
Parses a procedure call. */
1427
pars_procedure_call(
1428
/*================*/
1429
/* out: function node */
1430
que_node_t* res_word,/* in: procedure name reserved word */
1431
que_node_t* args) /* in: argument list */
1435
node = pars_func(res_word, args);
1437
pars_resolve_exp_list_variables_and_types(NULL, args);
1442
/*************************************************************************
1443
Parses a fetch statement. into_list or user_func (but not both) must be
1447
pars_fetch_statement(
1448
/*=================*/
1449
/* out: fetch statement node */
1450
sym_node_t* cursor, /* in: cursor node */
1451
sym_node_t* into_list, /* in: variables to set, or NULL */
1452
sym_node_t* user_func) /* in: user function name, or NULL */
1454
sym_node_t* cursor_decl;
1458
ut_a(!into_list != !user_func);
1460
node = mem_heap_alloc(pars_sym_tab_global->heap, sizeof(fetch_node_t));
1462
node->common.type = QUE_NODE_FETCH;
1464
pars_resolve_exp_variables_and_types(NULL, cursor);
1467
pars_resolve_exp_list_variables_and_types(NULL, into_list);
1468
node->into_list = into_list;
1471
pars_resolve_exp_variables_and_types(NULL, user_func);
1473
node->func = pars_info_get_user_func(pars_sym_tab_global->info,
1477
node->into_list = NULL;
1480
cursor_decl = cursor->alias;
1482
ut_a(cursor_decl->token_type == SYM_CURSOR);
1484
node->cursor_def = cursor_decl->cursor_def;
1487
ut_a(que_node_list_get_len(into_list)
1488
== que_node_list_get_len(node->cursor_def->select_list));
1494
/*************************************************************************
1495
Parses an open or close cursor statement. */
1498
pars_open_statement(
1499
/*================*/
1500
/* out: fetch statement node */
1501
ulint type, /* in: ROW_SEL_OPEN_CURSOR
1502
or ROW_SEL_CLOSE_CURSOR */
1503
sym_node_t* cursor) /* in: cursor node */
1505
sym_node_t* cursor_decl;
1508
node = mem_heap_alloc(pars_sym_tab_global->heap, sizeof(open_node_t));
1510
node->common.type = QUE_NODE_OPEN;
1512
pars_resolve_exp_variables_and_types(NULL, cursor);
1514
cursor_decl = cursor->alias;
1516
ut_a(cursor_decl->token_type == SYM_CURSOR);
1518
node->op_type = type;
1519
node->cursor_def = cursor_decl->cursor_def;
1524
/*************************************************************************
1525
Parses a row_printf-statement. */
1528
pars_row_printf_statement(
1529
/*======================*/
1530
/* out: row_printf-statement node */
1531
sel_node_t* sel_node) /* in: select node */
1533
row_printf_node_t* node;
1535
node = mem_heap_alloc(pars_sym_tab_global->heap,
1536
sizeof(row_printf_node_t));
1537
node->common.type = QUE_NODE_ROW_PRINTF;
1539
node->sel_node = sel_node;
1541
sel_node->common.parent = node;
1546
/*************************************************************************
1547
Parses a commit statement. */
1550
pars_commit_statement(void)
1551
/*=======================*/
1553
return(commit_node_create(pars_sym_tab_global->heap));
1556
/*************************************************************************
1557
Parses a rollback statement. */
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. */
1572
/* out: column sym table
1574
sym_node_t* sym_node, /* in: column node in the
1576
pars_res_word_t* type, /* in: data type */
1577
sym_node_t* len, /* in: length of column, or
1579
void* is_unsigned, /* in: if not NULL, column
1580
is of type UNSIGNED. */
1581
void* is_not_null) /* in: if not NULL, column
1582
is of type NOT NULL. */
1587
len2 = eval_node_get_int_val(len);
1592
pars_set_dfield_type(que_node_get_val(sym_node), type, len2,
1593
is_unsigned != NULL, is_not_null != NULL);
1598
/*************************************************************************
1599
Parses a table creation operation. */
1604
/* out: table create subgraph */
1605
sym_node_t* table_sym, /* in: table name node in the symbol
1607
sym_node_t* column_defs, /* in: list of column names */
1608
void* not_fit_in_memory __attribute__((unused)))
1609
/* in: a non-NULL pointer means that
1610
this is a table which in simulations
1611
should be simulated as not fitting
1612
in memory; thread is put to sleep
1613
to simulate disk accesses; NOTE that
1614
this flag is not stored to the data
1615
dictionary on disk, and the database
1616
will forget about non-NULL value if
1617
it has to reload the table definition
1620
dict_table_t* table;
1626
n_cols = que_node_list_get_len(column_defs);
1628
/* As the InnoDB SQL parser is for internal use only,
1629
for creating some system tables, this function will only
1630
create tables in the old (not compact) record format. */
1631
table = dict_mem_table_create(table_sym->name, 0, n_cols, 0);
1634
if (not_fit_in_memory != NULL) {
1635
table->does_not_fit_in_memory = TRUE;
1637
#endif /* UNIV_DEBUG */
1638
column = column_defs;
1641
dtype = dfield_get_type(que_node_get_val(column));
1643
dict_mem_table_add_col(table, table->heap,
1644
column->name, dtype->mtype,
1645
dtype->prtype, dtype->len);
1646
column->resolved = TRUE;
1647
column->token_type = SYM_COLUMN;
1649
column = que_node_get_next(column);
1652
node = tab_create_graph_create(table, pars_sym_tab_global->heap);
1654
table_sym->resolved = TRUE;
1655
table_sym->token_type = SYM_TABLE;
1660
/*************************************************************************
1661
Parses an index creation operation. */
1666
/* out: index create subgraph */
1667
pars_res_word_t* unique_def, /* in: not NULL if a unique index */
1668
pars_res_word_t* clustered_def, /* in: not NULL if a clustered index */
1669
sym_node_t* index_sym, /* in: index name node in the symbol
1671
sym_node_t* table_sym, /* in: table name node in the symbol
1673
sym_node_t* column_list) /* in: list of column names */
1675
dict_index_t* index;
1681
n_fields = que_node_list_get_len(column_list);
1686
ind_type = ind_type | DICT_UNIQUE;
1689
if (clustered_def) {
1690
ind_type = ind_type | DICT_CLUSTERED;
1693
index = dict_mem_index_create(table_sym->name, index_sym->name, 0,
1694
ind_type, n_fields);
1695
column = column_list;
1698
dict_mem_index_add_field(index, column->name, 0);
1700
column->resolved = TRUE;
1701
column->token_type = SYM_COLUMN;
1703
column = que_node_get_next(column);
1706
node = ind_create_graph_create(index, pars_sym_tab_global->heap);
1708
table_sym->resolved = TRUE;
1709
table_sym->token_type = SYM_TABLE;
1711
index_sym->resolved = TRUE;
1712
index_sym->token_type = SYM_TABLE;
1717
/*************************************************************************
1718
Parses a procedure definition. */
1721
pars_procedure_definition(
1722
/*======================*/
1723
/* out: query fork node */
1724
sym_node_t* sym_node, /* in: procedure id node in the symbol
1726
sym_node_t* param_list, /* in: parameter declaration list */
1727
que_node_t* stat_list) /* in: statement list */
1734
heap = pars_sym_tab_global->heap;
1736
fork = que_fork_create(NULL, NULL, QUE_FORK_PROCEDURE, heap);
1739
thr = que_thr_create(fork, heap);
1741
node = mem_heap_alloc(heap, sizeof(proc_node_t));
1743
node->common.type = QUE_NODE_PROC;
1744
node->common.parent = thr;
1746
sym_node->token_type = SYM_PROCEDURE_NAME;
1747
sym_node->resolved = TRUE;
1749
node->proc_id = sym_node;
1750
node->param_list = param_list;
1751
node->stat_list = stat_list;
1753
pars_set_parent_in_list(stat_list, node);
1755
node->sym_tab = pars_sym_tab_global;
1759
pars_sym_tab_global->query_graph = fork;
1764
/*****************************************************************
1765
Parses a stored procedure call, when this is not within another stored
1766
procedure, that is, the client issues a procedure call directly.
1767
In MySQL/InnoDB, stored InnoDB procedures are invoked via the
1768
parsed procedure tree, not via InnoDB SQL, so this function is not used. */
1771
pars_stored_procedure_call(
1772
/*=======================*/
1773
/* out: query graph */
1774
sym_node_t* sym_node __attribute__((unused)))
1775
/* in: stored procedure name */
1781
/*****************************************************************
1782
Retrieves characters to the lexical analyzer. */
1787
char* buf, /* in/out: buffer where to copy */
1788
int* result, /* out: number of characters copied or EOF */
1789
int max_size) /* in: maximum number of characters which fit
1794
len = pars_sym_tab_global->string_len
1795
- pars_sym_tab_global->next_char_pos;
1798
/* fputs("SQL string ends\n", stderr); */
1805
if (len > max_size) {
1809
#ifdef UNIV_SQL_DEBUG
1810
if (pars_print_lexed) {
1816
fwrite(pars_sym_tab_global->sql_string
1817
+ pars_sym_tab_global->next_char_pos,
1820
#endif /* UNIV_SQL_DEBUG */
1822
ut_memcpy(buf, pars_sym_tab_global->sql_string
1823
+ pars_sym_tab_global->next_char_pos, len);
1826
pars_sym_tab_global->next_char_pos += len;
1829
/*****************************************************************
1830
Called by yyparse on error. */
1835
const char* s __attribute__((unused)))
1836
/* in: error message string */
1840
fputs("PARSER ERROR: Syntax error in SQL string\n", stderr);
1845
/*****************************************************************
1846
Parses an SQL string returning the query graph. */
1851
/* out, own: the query graph */
1852
pars_info_t* info, /* in: extra information, or NULL */
1853
const char* str) /* in: SQL string */
1855
sym_node_t* sym_node;
1861
heap = mem_heap_create(256);
1863
/* Currently, the parser is not reentrant: */
1864
ut_ad(mutex_own(&(dict_sys->mutex)));
1866
pars_sym_tab_global = sym_tab_create(heap);
1868
pars_sym_tab_global->string_len = strlen(str);
1869
pars_sym_tab_global->sql_string = mem_heap_dup(
1870
heap, str, pars_sym_tab_global->string_len + 1);
1871
pars_sym_tab_global->next_char_pos = 0;
1872
pars_sym_tab_global->info = info;
1876
sym_node = UT_LIST_GET_FIRST(pars_sym_tab_global->sym_list);
1879
ut_a(sym_node->resolved);
1881
sym_node = UT_LIST_GET_NEXT(sym_list, sym_node);
1884
graph = pars_sym_tab_global->query_graph;
1886
graph->sym_tab = pars_sym_tab_global;
1889
/* fprintf(stderr, "SQL graph size %lu\n", mem_heap_get_size(heap)); */
1894
/**********************************************************************
1895
Completes a query graph by adding query thread and fork nodes
1896
above it and prepares the graph for running. The fork created is of
1897
type QUE_FORK_MYSQL_INTERFACE. */
1900
pars_complete_graph_for_exec(
1901
/*=========================*/
1902
/* out: query thread node to run */
1903
que_node_t* node, /* in: root node for an incomplete
1905
trx_t* trx, /* in: transaction handle */
1906
mem_heap_t* heap) /* in: memory heap from which allocated */
1911
fork = que_fork_create(NULL, NULL, QUE_FORK_MYSQL_INTERFACE, heap);
1914
thr = que_thr_create(fork, heap);
1918
que_node_set_parent(node, thr);
1925
/********************************************************************
1926
Create parser info struct.*/
1929
pars_info_create(void)
1930
/*==================*/
1931
/* out, own: info struct */
1936
heap = mem_heap_create(512);
1938
info = mem_heap_alloc(heap, sizeof(*info));
1942
info->bound_lits = NULL;
1943
info->bound_ids = NULL;
1944
info->graph_owns_us = TRUE;
1949
/********************************************************************
1950
Free info struct and everything it contains.*/
1955
pars_info_t* info) /* in: info struct */
1957
mem_heap_free(info->heap);
1960
/********************************************************************
1961
Add bound literal. */
1964
pars_info_add_literal(
1965
/*==================*/
1966
pars_info_t* info, /* in: info struct */
1967
const char* name, /* in: name */
1968
const void* address, /* in: address */
1969
ulint length, /* in: length of data */
1970
ulint type, /* in: type, e.g. DATA_FIXBINARY */
1971
ulint prtype) /* in: precise type, e.g.
1974
pars_bound_lit_t* pbl;
1976
ut_ad(!pars_info_get_bound_lit(info, name));
1978
pbl = mem_heap_alloc(info->heap, sizeof(*pbl));
1981
pbl->address = address;
1982
pbl->length = length;
1984
pbl->prtype = prtype;
1986
if (!info->bound_lits) {
1987
info->bound_lits = ib_vector_create(info->heap, 8);
1990
ib_vector_push(info->bound_lits, pbl);
1993
/********************************************************************
1994
Equivalent to pars_info_add_literal(info, name, str, strlen(str),
1995
DATA_VARCHAR, DATA_ENGLISH). */
1998
pars_info_add_str_literal(
1999
/*======================*/
2000
pars_info_t* info, /* in: info struct */
2001
const char* name, /* in: name */
2002
const char* str) /* in: string */
2004
pars_info_add_literal(info, name, str, strlen(str),
2005
DATA_VARCHAR, DATA_ENGLISH);
2008
/********************************************************************
2012
mach_write_to_4(buf, val);
2013
pars_info_add_literal(info, name, buf, 4, DATA_INT, 0);
2015
except that the buffer is dynamically allocated from the info struct's
2019
pars_info_add_int4_literal(
2020
/*=======================*/
2021
pars_info_t* info, /* in: info struct */
2022
const char* name, /* in: name */
2023
lint val) /* in: value */
2025
byte* buf = mem_heap_alloc(info->heap, 4);
2027
mach_write_to_4(buf, val);
2028
pars_info_add_literal(info, name, buf, 4, DATA_INT, 0);
2031
/********************************************************************
2035
mach_write_to_8(buf, val);
2036
pars_info_add_literal(info, name, buf, 8, DATA_FIXBINARY, 0);
2038
except that the buffer is dynamically allocated from the info struct's
2042
pars_info_add_dulint_literal(
2043
/*=========================*/
2044
pars_info_t* info, /* in: info struct */
2045
const char* name, /* in: name */
2046
dulint val) /* in: value */
2048
byte* buf = mem_heap_alloc(info->heap, 8);
2050
mach_write_to_8(buf, val);
2052
pars_info_add_literal(info, name, buf, 8, DATA_FIXBINARY, 0);
2055
/********************************************************************
2056
Add user function. */
2059
pars_info_add_function(
2060
/*===================*/
2061
pars_info_t* info, /* in: info struct */
2062
const char* name, /* in: function name */
2063
pars_user_func_cb_t func, /* in: function address */
2064
void* arg) /* in: user-supplied argument */
2066
pars_user_func_t* puf;
2068
ut_ad(!pars_info_get_user_func(info, name));
2070
puf = mem_heap_alloc(info->heap, sizeof(*puf));
2077
info->funcs = ib_vector_create(info->heap, 8);
2080
ib_vector_push(info->funcs, puf);
2083
/********************************************************************
2089
pars_info_t* info, /* in: info struct */
2090
const char* name, /* in: name */
2091
const char* id) /* in: id */
2093
pars_bound_id_t* bid;
2095
ut_ad(!pars_info_get_bound_id(info, name));
2097
bid = mem_heap_alloc(info->heap, sizeof(*bid));
2102
if (!info->bound_ids) {
2103
info->bound_ids = ib_vector_create(info->heap, 8);
2106
ib_vector_push(info->bound_ids, bid);
2109
/********************************************************************
2110
Get user function with the given name.*/
2113
pars_info_get_user_func(
2114
/*====================*/
2115
/* out: user func, or NULL if not
2117
pars_info_t* info, /* in: info struct */
2118
const char* name) /* in: function name to find*/
2123
if (!info || !info->funcs) {
2129
for (i = 0; i < ib_vector_size(vec); i++) {
2130
pars_user_func_t* puf = ib_vector_get(vec, i);
2132
if (strcmp(puf->name, name) == 0) {
2140
/********************************************************************
2141
Get bound literal with the given name.*/
2144
pars_info_get_bound_lit(
2145
/*====================*/
2146
/* out: bound literal, or NULL if
2148
pars_info_t* info, /* in: info struct */
2149
const char* name) /* in: bound literal name to find */
2154
if (!info || !info->bound_lits) {
2158
vec = info->bound_lits;
2160
for (i = 0; i < ib_vector_size(vec); i++) {
2161
pars_bound_lit_t* pbl = ib_vector_get(vec, i);
2163
if (strcmp(pbl->name, name) == 0) {
2171
/********************************************************************
2172
Get bound id with the given name.*/
2175
pars_info_get_bound_id(
2176
/*===================*/
2177
/* out: bound id, or NULL if not
2179
pars_info_t* info, /* in: info struct */
2180
const char* name) /* in: bound id name to find */
2185
if (!info || !info->bound_ids) {
2189
vec = info->bound_ids;
2191
for (i = 0; i < ib_vector_size(vec); i++) {
2192
pars_bound_id_t* bid = ib_vector_get(vec, i);
2194
if (strcmp(bid->name, name) == 0) {