~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to storage/innobase/pars/pars0pars.c

  • Committer: brian
  • Date: 2008-06-25 05:29:13 UTC
  • Revision ID: brian@localhost.localdomain-20080625052913-6upwo0jsrl4lnapl
clean slate

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/******************************************************
 
2
SQL parser
 
3
 
 
4
(c) 1996 Innobase Oy
 
5
 
 
6
Created 11/19/1996 Heikki Tuuri
 
7
*******************************************************/
 
8
 
 
9
/* Historical note: Innobase executed its first SQL string (CREATE TABLE)
 
10
on 1/27/1998 */
 
11
 
 
12
#include "pars0pars.h"
 
13
 
 
14
#ifdef UNIV_NONINL
 
15
#include "pars0pars.ic"
 
16
#endif
 
17
 
 
18
#include "row0sel.h"
 
19
#include "row0ins.h"
 
20
#include "row0upd.h"
 
21
#include "dict0dict.h"
 
22
#include "dict0mem.h"
 
23
#include "dict0crea.h"
 
24
#include "que0que.h"
 
25
#include "pars0grm.h"
 
26
#include "pars0opt.h"
 
27
#include "data0data.h"
 
28
#include "data0type.h"
 
29
#include "trx0trx.h"
 
30
#include "trx0roll.h"
 
31
#include "lock0lock.h"
 
32
#include "eval0eval.h"
 
33
 
 
34
#ifdef UNIV_SQL_DEBUG
 
35
/* If the following is set TRUE, the lexer will print the SQL string
 
36
as it tokenizes it */
 
37
 
 
38
ibool   pars_print_lexed        = FALSE;
 
39
#endif /* UNIV_SQL_DEBUG */
 
40
 
 
41
/* Global variable used while parsing a single procedure or query : the code is
 
42
NOT re-entrant */
 
43
sym_tab_t*      pars_sym_tab_global;
 
44
 
 
45
/* Global variables used to denote certain reserved words, used in
 
46
constructing the parsing tree */
 
47
 
 
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};
 
78
 
 
79
/* Global variable used to denote the '*' in SELECT * FROM.. */
 
80
#define PARS_STAR_DENOTER       12345678
 
81
ulint   pars_star_denoter       = PARS_STAR_DENOTER;
 
82
 
 
83
 
 
84
/*************************************************************************
 
85
Determines the class of a function code. */
 
86
static
 
87
ulint
 
88
pars_func_get_class(
 
89
/*================*/
 
90
                        /* out: function class: PARS_FUNC_ARITH, ... */
 
91
        int     func)   /* in: function code: '=', PARS_GE_TOKEN, ... */
 
92
{
 
93
        if ((func == '+') || (func == '-') || (func == '*') || (func == '/')) {
 
94
 
 
95
                return(PARS_FUNC_ARITH);
 
96
 
 
97
        } else if ((func == '=') || (func == '<') || (func == '>')
 
98
                   || (func == PARS_GE_TOKEN) || (func == PARS_LE_TOKEN)
 
99
                   || (func == PARS_NE_TOKEN)) {
 
100
 
 
101
                return(PARS_FUNC_CMP);
 
102
 
 
103
        } else if ((func == PARS_AND_TOKEN) || (func == PARS_OR_TOKEN)
 
104
                   || (func == PARS_NOT_TOKEN)) {
 
105
 
 
106
                return(PARS_FUNC_LOGICAL);
 
107
 
 
108
        } else if ((func == PARS_COUNT_TOKEN) || (func == PARS_SUM_TOKEN)) {
 
109
 
 
110
                return(PARS_FUNC_AGGREGATE);
 
111
 
 
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)) {
 
127
 
 
128
                return(PARS_FUNC_PREDEFINED);
 
129
        } else {
 
130
                return(PARS_FUNC_OTHER);
 
131
        }
 
132
}
 
133
 
 
134
/*************************************************************************
 
135
Parses an operator or predefined function expression. */
 
136
static
 
137
func_node_t*
 
138
pars_func_low(
 
139
/*==========*/
 
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 */
 
143
{
 
144
        func_node_t*    node;
 
145
 
 
146
        node = mem_heap_alloc(pars_sym_tab_global->heap, sizeof(func_node_t));
 
147
 
 
148
        node->common.type = QUE_NODE_FUNC;
 
149
        dfield_set_data(&(node->common.val), NULL, 0);
 
150
        node->common.val_buf_size = 0;
 
151
 
 
152
        node->func = func;
 
153
 
 
154
        node->class = pars_func_get_class(func);
 
155
 
 
156
        node->args = arg;
 
157
 
 
158
        UT_LIST_ADD_LAST(func_node_list, pars_sym_tab_global->func_node_list,
 
159
                         node);
 
160
        return(node);
 
161
}
 
162
 
 
163
/*************************************************************************
 
164
Parses a function expression. */
 
165
 
 
166
func_node_t*
 
167
pars_func(
 
168
/*======*/
 
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 */
 
172
{
 
173
        return(pars_func_low(((pars_res_word_t*)res_word)->code, arg));
 
174
}
 
175
 
 
176
/*************************************************************************
 
177
Parses an operator expression. */
 
178
 
 
179
func_node_t*
 
180
pars_op(
 
181
/*====*/
 
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
 
186
                                operator */
 
187
{
 
188
        que_node_list_add_last(NULL, arg1);
 
189
 
 
190
        if (arg2) {
 
191
                que_node_list_add_last(arg1, arg2);
 
192
        }
 
193
 
 
194
        return(pars_func_low(func, arg1));
 
195
}
 
196
 
 
197
/*************************************************************************
 
198
Parses an ORDER BY clause. Order by a single column only is supported. */
 
199
 
 
200
order_node_t*
 
201
pars_order_by(
 
202
/*==========*/
 
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 */
 
206
{
 
207
        order_node_t*   node;
 
208
 
 
209
        node = mem_heap_alloc(pars_sym_tab_global->heap, sizeof(order_node_t));
 
210
 
 
211
        node->common.type = QUE_NODE_ORDER;
 
212
 
 
213
        node->column = column;
 
214
 
 
215
        if (asc == &pars_asc_token) {
 
216
                node->asc = TRUE;
 
217
        } else {
 
218
                ut_a(asc == &pars_desc_token);
 
219
                node->asc = FALSE;
 
220
        }
 
221
 
 
222
        return(node);
 
223
}
 
224
 
 
225
/*************************************************************************
 
226
Resolves the data type of a function in an expression. The argument data
 
227
types must already be resolved. */
 
228
static
 
229
void
 
230
pars_resolve_func_data_type(
 
231
/*========================*/
 
232
        func_node_t*    node)   /* in: function node */
 
233
{
 
234
        que_node_t*     arg;
 
235
        ulint           func;
 
236
 
 
237
        ut_a(que_node_get_type(node) == QUE_NODE_FUNC);
 
238
 
 
239
        arg = node->args;
 
240
 
 
241
        func = node->func;
 
242
 
 
243
        if ((func == PARS_SUM_TOKEN)
 
244
            || (func == '+') || (func == '-') || (func == '*')
 
245
            || (func == '/') || (func == '+')) {
 
246
 
 
247
                /* Inherit the data type from the first argument (which must
 
248
                not be the SQL null literal whose type is DATA_ERROR) */
 
249
 
 
250
                dtype_copy(que_node_get_data_type(node),
 
251
                           que_node_get_data_type(arg));
 
252
 
 
253
                ut_a(dtype_get_mtype(que_node_get_data_type(node))
 
254
                     == DATA_INT);
 
255
        } else if (func == PARS_COUNT_TOKEN) {
 
256
                ut_a(arg);
 
257
                dtype_set(que_node_get_data_type(node), DATA_INT, 0, 4);
 
258
 
 
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,
 
262
                          DATA_ENGLISH, 0);
 
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,
 
266
                                  DATA_ENGLISH, 0);
 
267
                } else {
 
268
                        dtype_set(que_node_get_data_type(node), DATA_BINARY,
 
269
                                  0, 0);
 
270
                }
 
271
        } else if (func == PARS_TO_NUMBER_TOKEN) {
 
272
                ut_a(dtype_get_mtype(que_node_get_data_type(arg))
 
273
                     == DATA_VARCHAR);
 
274
                dtype_set(que_node_get_data_type(node), DATA_INT, 0, 4);
 
275
 
 
276
        } else if (func == PARS_BINARY_TO_NUMBER_TOKEN) {
 
277
                ut_a(dtype_get_mtype(que_node_get_data_type(arg))
 
278
                     == DATA_VARCHAR);
 
279
                dtype_set(que_node_get_data_type(node), DATA_INT, 0, 4);
 
280
 
 
281
        } else if (func == PARS_LENGTH_TOKEN) {
 
282
                ut_a(dtype_get_mtype(que_node_get_data_type(arg))
 
283
                     == DATA_VARCHAR);
 
284
                dtype_set(que_node_get_data_type(node), DATA_INT, 0, 4);
 
285
 
 
286
        } else if (func == PARS_INSTR_TOKEN) {
 
287
                ut_a(dtype_get_mtype(que_node_get_data_type(arg))
 
288
                     == DATA_VARCHAR);
 
289
                dtype_set(que_node_get_data_type(node), DATA_INT, 0, 4);
 
290
 
 
291
        } else if (func == PARS_SYSDATE_TOKEN) {
 
292
                ut_a(arg == NULL);
 
293
                dtype_set(que_node_get_data_type(node), DATA_INT, 0, 4);
 
294
 
 
295
        } else if ((func == PARS_SUBSTR_TOKEN)
 
296
                   || (func == PARS_CONCAT_TOKEN)) {
 
297
 
 
298
                ut_a(dtype_get_mtype(que_node_get_data_type(arg))
 
299
                     == DATA_VARCHAR);
 
300
                dtype_set(que_node_get_data_type(node), DATA_VARCHAR,
 
301
                          DATA_ENGLISH, 0);
 
302
 
 
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)) {
 
311
 
 
312
                /* We currently have no iboolean type: use integer type */
 
313
                dtype_set(que_node_get_data_type(node), DATA_INT, 0, 4);
 
314
 
 
315
        } else if (func == PARS_RND_TOKEN) {
 
316
                ut_a(dtype_get_mtype(que_node_get_data_type(arg)) == DATA_INT);
 
317
 
 
318
                dtype_set(que_node_get_data_type(node), DATA_INT, 0, 4);
 
319
 
 
320
        } else if (func == PARS_RND_STR_TOKEN) {
 
321
                ut_a(dtype_get_mtype(que_node_get_data_type(arg)) == DATA_INT);
 
322
 
 
323
                dtype_set(que_node_get_data_type(node), DATA_VARCHAR,
 
324
                          DATA_ENGLISH, 0);
 
325
        } else {
 
326
                ut_error;
 
327
        }
 
328
}
 
329
 
 
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. */
 
333
static
 
334
void
 
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 */
 
342
{
 
343
        func_node_t*    func_node;
 
344
        que_node_t*     arg;
 
345
        sym_node_t*     sym_node;
 
346
        sym_node_t*     node;
 
347
 
 
348
        ut_a(exp_node);
 
349
 
 
350
        if (que_node_get_type(exp_node) == QUE_NODE_FUNC) {
 
351
                func_node = exp_node;
 
352
 
 
353
                arg = func_node->args;
 
354
 
 
355
                while (arg) {
 
356
                        pars_resolve_exp_variables_and_types(select_node, arg);
 
357
 
 
358
                        arg = que_node_get_next(arg);
 
359
                }
 
360
 
 
361
                pars_resolve_func_data_type(func_node);
 
362
 
 
363
                return;
 
364
        }
 
365
 
 
366
        ut_a(que_node_get_type(exp_node) == QUE_NODE_SYMBOL);
 
367
 
 
368
        sym_node = exp_node;
 
369
 
 
370
        if (sym_node->resolved) {
 
371
 
 
372
                return;
 
373
        }
 
374
 
 
375
        /* Not resolved yet: look in the symbol table for a variable
 
376
        or a cursor or a function with the same name */
 
377
 
 
378
        node = UT_LIST_GET_FIRST(pars_sym_tab_global->sym_list);
 
379
 
 
380
        while (node) {
 
381
                if (node->resolved
 
382
                    && ((node->token_type == SYM_VAR)
 
383
                        || (node->token_type == SYM_CURSOR)
 
384
                        || (node->token_type == SYM_FUNCTION))
 
385
                    && node->name
 
386
                    && (sym_node->name_len == node->name_len)
 
387
                    && (ut_memcmp(sym_node->name, node->name,
 
388
                                  node->name_len) == 0)) {
 
389
 
 
390
                        /* Found a variable or a cursor declared with
 
391
                        the same name */
 
392
 
 
393
                        break;
 
394
                }
 
395
 
 
396
                node = UT_LIST_GET_NEXT(sym_list, node);
 
397
        }
 
398
 
 
399
        if (!node) {
 
400
                fprintf(stderr, "PARSER ERROR: Unresolved identifier %s\n",
 
401
                        sym_node->name);
 
402
        }
 
403
 
 
404
        ut_a(node);
 
405
 
 
406
        sym_node->resolved = TRUE;
 
407
        sym_node->token_type = SYM_IMPLICIT_VAR;
 
408
        sym_node->alias = node;
 
409
        sym_node->indirection = node;
 
410
 
 
411
        if (select_node) {
 
412
                UT_LIST_ADD_LAST(col_var_list, select_node->copy_variables,
 
413
                                 sym_node);
 
414
        }
 
415
 
 
416
        dfield_set_type(que_node_get_val(sym_node),
 
417
                        que_node_get_data_type(node));
 
418
}
 
419
 
 
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
 
423
functions. */
 
424
static
 
425
void
 
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
 
430
                                        NULL */
 
431
{
 
432
        while (exp_node) {
 
433
                pars_resolve_exp_variables_and_types(select_node, exp_node);
 
434
 
 
435
                exp_node = que_node_get_next(exp_node);
 
436
        }
 
437
}
 
438
 
 
439
/*************************************************************************
 
440
Resolves the columns in an expression. */
 
441
static
 
442
void
 
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 */
 
447
{
 
448
        func_node_t*    func_node;
 
449
        que_node_t*     arg;
 
450
        sym_node_t*     sym_node;
 
451
        dict_table_t*   table;
 
452
        sym_node_t*     t_node;
 
453
        ulint           n_cols;
 
454
        ulint           i;
 
455
 
 
456
        ut_a(exp_node);
 
457
 
 
458
        if (que_node_get_type(exp_node) == QUE_NODE_FUNC) {
 
459
                func_node = exp_node;
 
460
 
 
461
                arg = func_node->args;
 
462
 
 
463
                while (arg) {
 
464
                        pars_resolve_exp_columns(table_node, arg);
 
465
 
 
466
                        arg = que_node_get_next(arg);
 
467
                }
 
468
 
 
469
                return;
 
470
        }
 
471
 
 
472
        ut_a(que_node_get_type(exp_node) == QUE_NODE_SYMBOL);
 
473
 
 
474
        sym_node = exp_node;
 
475
 
 
476
        if (sym_node->resolved) {
 
477
 
 
478
                return;
 
479
        }
 
480
 
 
481
        /* Not resolved yet: look in the table list for a column with the
 
482
        same name */
 
483
 
 
484
        t_node = table_node;
 
485
 
 
486
        while (t_node) {
 
487
                table = t_node->table;
 
488
 
 
489
                n_cols = dict_table_get_n_cols(table);
 
490
 
 
491
                for (i = 0; i < n_cols; i++) {
 
492
                        const dict_col_t*       col
 
493
                                = dict_table_get_nth_col(table, i);
 
494
                        const char*             col_name
 
495
                                = dict_table_get_col_name(table, i);
 
496
 
 
497
                        if ((sym_node->name_len == ut_strlen(col_name))
 
498
                            && (0 == ut_memcmp(sym_node->name, col_name,
 
499
                                               sym_node->name_len))) {
 
500
                                /* Found */
 
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;
 
506
 
 
507
                                dict_col_copy_type(
 
508
                                        col,
 
509
                                        dfield_get_type(&sym_node
 
510
                                                        ->common.val));
 
511
 
 
512
                                return;
 
513
                        }
 
514
                }
 
515
 
 
516
                t_node = que_node_get_next(t_node);
 
517
        }
 
518
}
 
519
 
 
520
/*************************************************************************
 
521
Resolves the meaning of columns in an expression list. */
 
522
static
 
523
void
 
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
 
528
                                        NULL */
 
529
{
 
530
        while (exp_node) {
 
531
                pars_resolve_exp_columns(table_node, exp_node);
 
532
 
 
533
                exp_node = que_node_get_next(exp_node);
 
534
        }
 
535
}
 
536
 
 
537
/*************************************************************************
 
538
Retrieves the table definition for a table name id. */
 
539
static
 
540
void
 
541
pars_retrieve_table_def(
 
542
/*====================*/
 
543
        sym_node_t*     sym_node)       /* in: table node */
 
544
{
 
545
        const char*     table_name;
 
546
 
 
547
        ut_a(sym_node);
 
548
        ut_a(que_node_get_type(sym_node) == QUE_NODE_SYMBOL);
 
549
 
 
550
        sym_node->resolved = TRUE;
 
551
        sym_node->token_type = SYM_TABLE;
 
552
 
 
553
        table_name = (const char*) sym_node->name;
 
554
 
 
555
        sym_node->table = dict_table_get_low(table_name);
 
556
 
 
557
        ut_a(sym_node->table);
 
558
}
 
559
 
 
560
/*************************************************************************
 
561
Retrieves the table definitions for a list of table name ids. */
 
562
static
 
563
ulint
 
564
pars_retrieve_table_list_defs(
 
565
/*==========================*/
 
566
                                        /* out: number of tables */
 
567
        sym_node_t*     sym_node)       /* in: first table node in list */
 
568
{
 
569
        ulint           count           = 0;
 
570
 
 
571
        if (sym_node == NULL) {
 
572
 
 
573
                return(count);
 
574
        }
 
575
 
 
576
        while (sym_node) {
 
577
                pars_retrieve_table_def(sym_node);
 
578
 
 
579
                count++;
 
580
 
 
581
                sym_node = que_node_get_next(sym_node);
 
582
        }
 
583
 
 
584
        return(count);
 
585
}
 
586
 
 
587
/*************************************************************************
 
588
Adds all columns to the select list if the query is SELECT * FROM ... */
 
589
static
 
590
void
 
591
pars_select_all_columns(
 
592
/*====================*/
 
593
        sel_node_t*     select_node)    /* in: select node already containing
 
594
                                        the table list */
 
595
{
 
596
        sym_node_t*     col_node;
 
597
        sym_node_t*     table_node;
 
598
        dict_table_t*   table;
 
599
        ulint           i;
 
600
 
 
601
        select_node->select_list = NULL;
 
602
 
 
603
        table_node = select_node->table_list;
 
604
 
 
605
        while (table_node) {
 
606
                table = table_node->table;
 
607
 
 
608
                for (i = 0; i < dict_table_get_n_user_cols(table); i++) {
 
609
                        const char*     col_name = dict_table_get_col_name(
 
610
                                table, i);
 
611
 
 
612
                        col_node = sym_tab_add_id(pars_sym_tab_global,
 
613
                                                  (byte*)col_name,
 
614
                                                  ut_strlen(col_name));
 
615
 
 
616
                        select_node->select_list = que_node_list_add_last(
 
617
                                select_node->select_list, col_node);
 
618
                }
 
619
 
 
620
                table_node = que_node_get_next(table_node);
 
621
        }
 
622
}
 
623
 
 
624
/*************************************************************************
 
625
Parses a select list; creates a query graph node for the whole SELECT
 
626
statement. */
 
627
 
 
628
sel_node_t*
 
629
pars_select_list(
 
630
/*=============*/
 
631
                                        /* out, own: select node in a query
 
632
                                        tree */
 
633
        que_node_t*     select_list,    /* in: select list */
 
634
        sym_node_t*     into_list)      /* in: variables list or NULL */
 
635
{
 
636
        sel_node_t*     node;
 
637
 
 
638
        node = sel_node_create(pars_sym_tab_global->heap);
 
639
 
 
640
        node->select_list = select_list;
 
641
        node->into_list = into_list;
 
642
 
 
643
        pars_resolve_exp_list_variables_and_types(NULL, into_list);
 
644
 
 
645
        return(node);
 
646
}
 
647
 
 
648
/*************************************************************************
 
649
Checks if the query is an aggregate query, in which case the selct list must
 
650
contain only aggregate function items. */
 
651
static
 
652
void
 
653
pars_check_aggregate(
 
654
/*=================*/
 
655
        sel_node_t*     select_node)    /* in: select node already containing
 
656
                                        the select list */
 
657
{
 
658
        que_node_t*     exp_node;
 
659
        func_node_t*    func_node;
 
660
        ulint           n_nodes                 = 0;
 
661
        ulint           n_aggregate_nodes       = 0;
 
662
 
 
663
        exp_node = select_node->select_list;
 
664
 
 
665
        while (exp_node) {
 
666
 
 
667
                n_nodes++;
 
668
 
 
669
                if (que_node_get_type(exp_node) == QUE_NODE_FUNC) {
 
670
 
 
671
                        func_node = exp_node;
 
672
 
 
673
                        if (func_node->class == PARS_FUNC_AGGREGATE) {
 
674
 
 
675
                                n_aggregate_nodes++;
 
676
                        }
 
677
                }
 
678
 
 
679
                exp_node = que_node_get_next(exp_node);
 
680
        }
 
681
 
 
682
        if (n_aggregate_nodes > 0) {
 
683
                ut_a(n_nodes == n_aggregate_nodes);
 
684
 
 
685
                select_node->is_aggregate = TRUE;
 
686
        } else {
 
687
                select_node->is_aggregate = FALSE;
 
688
        }
 
689
}
 
690
 
 
691
/*************************************************************************
 
692
Parses a select statement. */
 
693
 
 
694
sel_node_t*
 
695
pars_select_statement(
 
696
/*==================*/
 
697
                                        /* out, own: select node in a query
 
698
                                        tree */
 
699
        sel_node_t*     select_node,    /* in: select node already containing
 
700
                                        the select list */
 
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 */
 
706
{
 
707
        select_node->state = SEL_NODE_OPEN;
 
708
 
 
709
        select_node->table_list = table_list;
 
710
        select_node->n_tables = pars_retrieve_table_list_defs(table_list);
 
711
 
 
712
        if (select_node->select_list == &pars_star_denoter) {
 
713
 
 
714
                /* SELECT * FROM ... */
 
715
                pars_select_all_columns(select_node);
 
716
        }
 
717
 
 
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));
 
721
        }
 
722
 
 
723
        UT_LIST_INIT(select_node->copy_variables);
 
724
 
 
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);
 
729
 
 
730
        select_node->search_cond = search_cond;
 
731
 
 
732
        if (search_cond) {
 
733
                pars_resolve_exp_columns(table_list, search_cond);
 
734
                pars_resolve_exp_variables_and_types(select_node, search_cond);
 
735
        }
 
736
 
 
737
        if (for_update) {
 
738
                ut_a(!lock_shared);
 
739
 
 
740
                select_node->set_x_locks = TRUE;
 
741
                select_node->row_lock_mode = LOCK_X;
 
742
 
 
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;
 
748
 
 
749
                select_node->consistent_read = FALSE;
 
750
                select_node->read_view = NULL;
 
751
        } else {
 
752
                select_node->set_x_locks = FALSE;
 
753
                select_node->row_lock_mode = LOCK_S;
 
754
 
 
755
                select_node->consistent_read = TRUE;
 
756
        }
 
757
 
 
758
        select_node->order_by = order_by;
 
759
 
 
760
        if (order_by) {
 
761
                pars_resolve_exp_columns(table_list, order_by->column);
 
762
        }
 
763
 
 
764
        /* The final value of the following fields depend on the environment
 
765
        where the select statement appears: */
 
766
 
 
767
        select_node->can_get_updated = FALSE;
 
768
        select_node->explicit_cursor = NULL;
 
769
 
 
770
        opt_search_plan(select_node);
 
771
 
 
772
        return(select_node);
 
773
}
 
774
 
 
775
/*************************************************************************
 
776
Parses a cursor declaration. */
 
777
 
 
778
que_node_t*
 
779
pars_cursor_declaration(
 
780
/*====================*/
 
781
                                        /* out: sym_node */
 
782
        sym_node_t*     sym_node,       /* in: cursor id node in the symbol
 
783
                                        table */
 
784
        sel_node_t*     select_node)    /* in: select node */
 
785
{
 
786
        sym_node->resolved = TRUE;
 
787
        sym_node->token_type = SYM_CURSOR;
 
788
        sym_node->cursor_def = select_node;
 
789
 
 
790
        select_node->state = SEL_NODE_CLOSED;
 
791
        select_node->explicit_cursor = sym_node;
 
792
 
 
793
        return(sym_node);
 
794
}
 
795
 
 
796
/*************************************************************************
 
797
Parses a function declaration. */
 
798
 
 
799
que_node_t*
 
800
pars_function_declaration(
 
801
/*======================*/
 
802
                                        /* out: sym_node */
 
803
        sym_node_t*     sym_node)       /* in: function id node in the symbol
 
804
                                        table */
 
805
{
 
806
        sym_node->resolved = TRUE;
 
807
        sym_node->token_type = SYM_FUNCTION;
 
808
 
 
809
        /* Check that the function exists. */
 
810
        ut_a(pars_info_get_user_func(pars_sym_tab_global->info,
 
811
                                     sym_node->name));
 
812
 
 
813
        return(sym_node);
 
814
}
 
815
 
 
816
/*************************************************************************
 
817
Parses a delete or update statement start. */
 
818
 
 
819
upd_node_t*
 
820
pars_update_statement_start(
 
821
/*========================*/
 
822
                                        /* out, own: update node in a query
 
823
                                        tree */
 
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
 
827
                                        if delete */
 
828
{
 
829
        upd_node_t*     node;
 
830
 
 
831
        node = upd_node_create(pars_sym_tab_global->heap);
 
832
 
 
833
        node->is_delete = is_delete;
 
834
 
 
835
        node->table_sym = table_sym;
 
836
        node->col_assign_list = col_assign_list;
 
837
 
 
838
        return(node);
 
839
}
 
840
 
 
841
/*************************************************************************
 
842
Parses a column assignment in an update. */
 
843
 
 
844
col_assign_node_t*
 
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 */
 
850
{
 
851
        col_assign_node_t*      node;
 
852
 
 
853
        node = mem_heap_alloc(pars_sym_tab_global->heap,
 
854
                              sizeof(col_assign_node_t));
 
855
        node->common.type = QUE_NODE_COL_ASSIGNMENT;
 
856
 
 
857
        node->col = column;
 
858
        node->val = exp;
 
859
 
 
860
        return(node);
 
861
}
 
862
 
 
863
/*************************************************************************
 
864
Processes an update node assignment list. */
 
865
static
 
866
void
 
867
pars_process_assign_list(
 
868
/*=====================*/
 
869
        upd_node_t*     node)   /* in: update node */
 
870
{
 
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;
 
876
        sym_node_t*             col_sym;
 
877
        ulint                   changes_ord_field;
 
878
        ulint                   changes_field_size;
 
879
        ulint                   n_assigns;
 
880
        ulint                   i;
 
881
 
 
882
        table_sym = node->table_sym;
 
883
        col_assign_list = node->col_assign_list;
 
884
        clust_index = dict_table_get_first_index(node->table);
 
885
 
 
886
        assign_node = col_assign_list;
 
887
        n_assigns = 0;
 
888
 
 
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);
 
893
#if 0
 
894
                ut_a(dtype_get_mtype(
 
895
                             dfield_get_type(que_node_get_val(
 
896
                                                     assign_node->col)))
 
897
                     == dtype_get_mtype(
 
898
                             dfield_get_type(que_node_get_val(
 
899
                                                     assign_node->val))));
 
900
#endif
 
901
 
 
902
                /* Add to the update node all the columns found in assignment
 
903
                values as columns to copy: therefore, TRUE */
 
904
 
 
905
                opt_find_all_cols(TRUE, clust_index, &(node->columns), NULL,
 
906
                                  assign_node->val);
 
907
                n_assigns++;
 
908
 
 
909
                assign_node = que_node_get_next(assign_node);
 
910
        }
 
911
 
 
912
        node->update = upd_create(n_assigns, pars_sym_tab_global->heap);
 
913
 
 
914
        assign_node = col_assign_list;
 
915
 
 
916
        changes_field_size = UPD_NODE_NO_SIZE_CHANGE;
 
917
 
 
918
        for (i = 0; i < n_assigns; i++) {
 
919
                upd_field = upd_get_nth_field(node->update, i);
 
920
 
 
921
                col_sym = assign_node->col;
 
922
 
 
923
                upd_field_set_field_no(upd_field, dict_index_get_nth_col_pos(
 
924
                                               clust_index, col_sym->col_no),
 
925
                                       clust_index, NULL);
 
926
                upd_field->exp = assign_node->val;
 
927
 
 
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;
 
932
                }
 
933
 
 
934
                assign_node = que_node_get_next(assign_node);
 
935
        }
 
936
 
 
937
        /* Find out if the update can modify an ordering field in any index */
 
938
 
 
939
        changes_ord_field = UPD_NODE_NO_ORD_CHANGE;
 
940
 
 
941
        if (row_upd_changes_some_index_ord_field_binary(node->table,
 
942
                                                        node->update)) {
 
943
                changes_ord_field = 0;
 
944
        }
 
945
 
 
946
        node->cmpl_info = changes_ord_field | changes_field_size;
 
947
}
 
948
 
 
949
/*************************************************************************
 
950
Parses an update or delete statement. */
 
951
 
 
952
upd_node_t*
 
953
pars_update_statement(
 
954
/*==================*/
 
955
                                        /* out, own: update node in a query
 
956
                                        tree */
 
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 */
 
961
{
 
962
        sym_node_t*     table_sym;
 
963
        sel_node_t*     sel_node;
 
964
        plan_t*         plan;
 
965
 
 
966
        table_sym = node->table_sym;
 
967
 
 
968
        pars_retrieve_table_def(table_sym);
 
969
        node->table = table_sym->table;
 
970
 
 
971
        UT_LIST_INIT(node->columns);
 
972
 
 
973
        /* Make the single table node into a list of table nodes of length 1 */
 
974
 
 
975
        que_node_list_add_last(NULL, table_sym);
 
976
 
 
977
        if (cursor_sym) {
 
978
                pars_resolve_exp_variables_and_types(NULL, cursor_sym);
 
979
 
 
980
                sel_node = cursor_sym->alias->cursor_def;
 
981
 
 
982
                node->searched_update = FALSE;
 
983
        } else {
 
984
                sel_node = pars_select_list(NULL, NULL);
 
985
 
 
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;
 
990
        }
 
991
 
 
992
        node->select = sel_node;
 
993
 
 
994
        ut_a(!node->is_delete || (node->col_assign_list == NULL));
 
995
        ut_a(node->is_delete || (node->col_assign_list != NULL));
 
996
 
 
997
        if (node->is_delete) {
 
998
                node->cmpl_info = 0;
 
999
        } else {
 
1000
                pars_process_assign_list(node);
 
1001
        }
 
1002
 
 
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;
 
1007
        } else {
 
1008
                node->has_clust_rec_x_lock = sel_node->set_x_locks;
 
1009
        }
 
1010
 
 
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);
 
1015
 
 
1016
        sel_node->can_get_updated = TRUE;
 
1017
 
 
1018
        node->state = UPD_NODE_UPDATE_CLUSTERED;
 
1019
 
 
1020
        plan = sel_node_get_nth_plan(sel_node, 0);
 
1021
 
 
1022
        plan->no_prefetch = TRUE;
 
1023
 
 
1024
        if (!((plan->index)->type & DICT_CLUSTERED)) {
 
1025
 
 
1026
                plan->must_get_clust = TRUE;
 
1027
 
 
1028
                node->pcur = &(plan->clust_pcur);
 
1029
        } else {
 
1030
                node->pcur = &(plan->pcur);
 
1031
        }
 
1032
 
 
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)) {
 
1036
 
 
1037
                /* The select node can perform the update in-place */
 
1038
 
 
1039
                ut_a(plan->asc);
 
1040
 
 
1041
                node->select_will_do_update = TRUE;
 
1042
                sel_node->select_will_do_update = TRUE;
 
1043
                sel_node->latch_mode = BTR_MODIFY_LEAF;
 
1044
        }
 
1045
 
 
1046
        return(node);
 
1047
}
 
1048
 
 
1049
/*************************************************************************
 
1050
Parses an insert statement. */
 
1051
 
 
1052
ins_node_t*
 
1053
pars_insert_statement(
 
1054
/*==================*/
 
1055
                                        /* out, own: update node in a query
 
1056
                                        tree */
 
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 */
 
1060
{
 
1061
        ins_node_t*     node;
 
1062
        dtuple_t*       row;
 
1063
        ulint           ins_type;
 
1064
 
 
1065
        ut_a(values_list || select);
 
1066
        ut_a(!values_list || !select);
 
1067
 
 
1068
        if (values_list) {
 
1069
                ins_type = INS_VALUES;
 
1070
        } else {
 
1071
                ins_type = INS_SEARCHED;
 
1072
        }
 
1073
 
 
1074
        pars_retrieve_table_def(table_sym);
 
1075
 
 
1076
        node = ins_node_create(ins_type, table_sym->table,
 
1077
                               pars_sym_tab_global->heap);
 
1078
 
 
1079
        row = dtuple_create(pars_sym_tab_global->heap,
 
1080
                            dict_table_get_n_cols(node->table));
 
1081
 
 
1082
        dict_table_copy_types(row, table_sym->table);
 
1083
 
 
1084
        ins_node_set_new_row(node, row);
 
1085
 
 
1086
        node->select = select;
 
1087
 
 
1088
        if (select) {
 
1089
                select->common.parent = node;
 
1090
 
 
1091
                ut_a(que_node_list_get_len(select->select_list)
 
1092
                     == dict_table_get_n_user_cols(table_sym->table));
 
1093
        }
 
1094
 
 
1095
        node->values_list = values_list;
 
1096
 
 
1097
        if (node->values_list) {
 
1098
                pars_resolve_exp_list_variables_and_types(NULL, values_list);
 
1099
 
 
1100
                ut_a(que_node_list_get_len(values_list)
 
1101
                     == dict_table_get_n_user_cols(table_sym->table));
 
1102
        }
 
1103
 
 
1104
        return(node);
 
1105
}
 
1106
 
 
1107
/*************************************************************************
 
1108
Set the type of a dfield. */
 
1109
static
 
1110
void
 
1111
pars_set_dfield_type(
 
1112
/*=================*/
 
1113
        dfield_t*               dfield,         /* in: dfield */
 
1114
        pars_res_word_t*        type,           /* in: pointer to a type
 
1115
                                                token */
 
1116
        ulint                   len,            /* in: length, or 0 */
 
1117
        ibool                   is_unsigned,    /* in: if TRUE, column is
 
1118
                                                UNSIGNED. */
 
1119
        ibool                   is_not_null)    /* in: if TRUE, column is
 
1120
                                                NOT NULL. */
 
1121
{
 
1122
        ulint flags = 0;
 
1123
 
 
1124
        if (is_not_null) {
 
1125
                flags |= DATA_NOT_NULL;
 
1126
        }
 
1127
 
 
1128
        if (is_unsigned) {
 
1129
                flags |= DATA_UNSIGNED;
 
1130
        }
 
1131
 
 
1132
        if (type == &pars_int_token) {
 
1133
                ut_a(len == 0);
 
1134
 
 
1135
                dtype_set(dfield_get_type(dfield), DATA_INT, flags, 4);
 
1136
 
 
1137
        } else if (type == &pars_char_token) {
 
1138
                ut_a(len == 0);
 
1139
 
 
1140
                dtype_set(dfield_get_type(dfield), DATA_VARCHAR,
 
1141
                          DATA_ENGLISH | flags, 0);
 
1142
        } else if (type == &pars_binary_token) {
 
1143
                ut_a(len != 0);
 
1144
 
 
1145
                dtype_set(dfield_get_type(dfield), DATA_FIXBINARY,
 
1146
                          DATA_BINARY_TYPE | flags, len);
 
1147
        } else if (type == &pars_blob_token) {
 
1148
                ut_a(len == 0);
 
1149
 
 
1150
                dtype_set(dfield_get_type(dfield), DATA_BLOB,
 
1151
                          DATA_BINARY_TYPE | flags, 0);
 
1152
        } else {
 
1153
                ut_error;
 
1154
        }
 
1155
}
 
1156
 
 
1157
/*************************************************************************
 
1158
Parses a variable declaration. */
 
1159
 
 
1160
sym_node_t*
 
1161
pars_variable_declaration(
 
1162
/*======================*/
 
1163
                                /* out, own: symbol table node of type
 
1164
                                SYM_VAR */
 
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 */
 
1168
{
 
1169
        node->resolved = TRUE;
 
1170
        node->token_type = SYM_VAR;
 
1171
 
 
1172
        node->param_type = PARS_NOT_PARAM;
 
1173
 
 
1174
        pars_set_dfield_type(que_node_get_val(node), type, 0, FALSE, FALSE);
 
1175
 
 
1176
        return(node);
 
1177
}
 
1178
 
 
1179
/*************************************************************************
 
1180
Parses a procedure parameter declaration. */
 
1181
 
 
1182
sym_node_t*
 
1183
pars_parameter_declaration(
 
1184
/*=======================*/
 
1185
                                /* out, own: symbol table node of type
 
1186
                                SYM_VAR */
 
1187
        sym_node_t*     node,   /* in: symbol table node allocated for the
 
1188
                                id of the parameter */
 
1189
        ulint           param_type,
 
1190
                                /* in: PARS_INPUT or PARS_OUTPUT */
 
1191
        pars_res_word_t* type)  /* in: pointer to a type token */
 
1192
{
 
1193
        ut_a((param_type == PARS_INPUT) || (param_type == PARS_OUTPUT));
 
1194
 
 
1195
        pars_variable_declaration(node, type);
 
1196
 
 
1197
        node->param_type = param_type;
 
1198
 
 
1199
        return(node);
 
1200
}
 
1201
 
 
1202
/*************************************************************************
 
1203
Sets the parent field in a query node list. */
 
1204
static
 
1205
void
 
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 */
 
1211
{
 
1212
        que_common_t*   common;
 
1213
 
 
1214
        common = node_list;
 
1215
 
 
1216
        while (common) {
 
1217
                common->parent = parent;
 
1218
 
 
1219
                common = que_node_get_next(common);
 
1220
        }
 
1221
}
 
1222
 
 
1223
/*************************************************************************
 
1224
Parses an elsif element. */
 
1225
 
 
1226
elsif_node_t*
 
1227
pars_elsif_element(
 
1228
/*===============*/
 
1229
                                        /* out: elsif node */
 
1230
        que_node_t*     cond,           /* in: if-condition */
 
1231
        que_node_t*     stat_list)      /* in: statement list */
 
1232
{
 
1233
        elsif_node_t*   node;
 
1234
 
 
1235
        node = mem_heap_alloc(pars_sym_tab_global->heap, sizeof(elsif_node_t));
 
1236
 
 
1237
        node->common.type = QUE_NODE_ELSIF;
 
1238
 
 
1239
        node->cond = cond;
 
1240
 
 
1241
        pars_resolve_exp_variables_and_types(NULL, cond);
 
1242
 
 
1243
        node->stat_list = stat_list;
 
1244
 
 
1245
        return(node);
 
1246
}
 
1247
 
 
1248
/*************************************************************************
 
1249
Parses an if-statement. */
 
1250
 
 
1251
if_node_t*
 
1252
pars_if_statement(
 
1253
/*==============*/
 
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 */
 
1259
{
 
1260
        if_node_t*      node;
 
1261
        elsif_node_t*   elsif_node;
 
1262
 
 
1263
        node = mem_heap_alloc(pars_sym_tab_global->heap, sizeof(if_node_t));
 
1264
 
 
1265
        node->common.type = QUE_NODE_IF;
 
1266
 
 
1267
        node->cond = cond;
 
1268
 
 
1269
        pars_resolve_exp_variables_and_types(NULL, cond);
 
1270
 
 
1271
        node->stat_list = stat_list;
 
1272
 
 
1273
        if (else_part && (que_node_get_type(else_part) == QUE_NODE_ELSIF)) {
 
1274
 
 
1275
                /* There is a list of elsif conditions */
 
1276
 
 
1277
                node->else_part = NULL;
 
1278
                node->elsif_list = else_part;
 
1279
 
 
1280
                elsif_node = else_part;
 
1281
 
 
1282
                while (elsif_node) {
 
1283
                        pars_set_parent_in_list(elsif_node->stat_list, node);
 
1284
 
 
1285
                        elsif_node = que_node_get_next(elsif_node);
 
1286
                }
 
1287
        } else {
 
1288
                node->else_part = else_part;
 
1289
                node->elsif_list = NULL;
 
1290
 
 
1291
                pars_set_parent_in_list(else_part, node);
 
1292
        }
 
1293
 
 
1294
        pars_set_parent_in_list(stat_list, node);
 
1295
 
 
1296
        return(node);
 
1297
}
 
1298
 
 
1299
/*************************************************************************
 
1300
Parses a while-statement. */
 
1301
 
 
1302
while_node_t*
 
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 */
 
1308
{
 
1309
        while_node_t*   node;
 
1310
 
 
1311
        node = mem_heap_alloc(pars_sym_tab_global->heap, sizeof(while_node_t));
 
1312
 
 
1313
        node->common.type = QUE_NODE_WHILE;
 
1314
 
 
1315
        node->cond = cond;
 
1316
 
 
1317
        pars_resolve_exp_variables_and_types(NULL, cond);
 
1318
 
 
1319
        node->stat_list = stat_list;
 
1320
 
 
1321
        pars_set_parent_in_list(stat_list, node);
 
1322
 
 
1323
        return(node);
 
1324
}
 
1325
 
 
1326
/*************************************************************************
 
1327
Parses a for-loop-statement. */
 
1328
 
 
1329
for_node_t*
 
1330
pars_for_statement(
 
1331
/*===============*/
 
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 */
 
1337
{
 
1338
        for_node_t*     node;
 
1339
 
 
1340
        node = mem_heap_alloc(pars_sym_tab_global->heap, sizeof(for_node_t));
 
1341
 
 
1342
        node->common.type = QUE_NODE_FOR;
 
1343
 
 
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);
 
1347
 
 
1348
        node->loop_var = loop_var->indirection;
 
1349
 
 
1350
        ut_a(loop_var->indirection);
 
1351
 
 
1352
        node->loop_start_limit = loop_start_limit;
 
1353
        node->loop_end_limit = loop_end_limit;
 
1354
 
 
1355
        node->stat_list = stat_list;
 
1356
 
 
1357
        pars_set_parent_in_list(stat_list, node);
 
1358
 
 
1359
        return(node);
 
1360
}
 
1361
 
 
1362
/*************************************************************************
 
1363
Parses an exit statement. */
 
1364
 
 
1365
exit_node_t*
 
1366
pars_exit_statement(void)
 
1367
/*=====================*/
 
1368
                                        /* out: exit statement node */
 
1369
{
 
1370
        exit_node_t*    node;
 
1371
 
 
1372
        node = mem_heap_alloc(pars_sym_tab_global->heap, sizeof(exit_node_t));
 
1373
        node->common.type = QUE_NODE_EXIT;
 
1374
 
 
1375
        return(node);
 
1376
}
 
1377
 
 
1378
/*************************************************************************
 
1379
Parses a return-statement. */
 
1380
 
 
1381
return_node_t*
 
1382
pars_return_statement(void)
 
1383
/*=======================*/
 
1384
                                        /* out: return-statement node */
 
1385
{
 
1386
        return_node_t*  node;
 
1387
 
 
1388
        node = mem_heap_alloc(pars_sym_tab_global->heap,
 
1389
                              sizeof(return_node_t));
 
1390
        node->common.type = QUE_NODE_RETURN;
 
1391
 
 
1392
        return(node);
 
1393
}
 
1394
 
 
1395
/*************************************************************************
 
1396
Parses an assignment statement. */
 
1397
 
 
1398
assign_node_t*
 
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 */
 
1404
{
 
1405
        assign_node_t*  node;
 
1406
 
 
1407
        node = mem_heap_alloc(pars_sym_tab_global->heap,
 
1408
                              sizeof(assign_node_t));
 
1409
        node->common.type = QUE_NODE_ASSIGNMENT;
 
1410
 
 
1411
        node->var = var;
 
1412
        node->val = val;
 
1413
 
 
1414
        pars_resolve_exp_variables_and_types(NULL, var);
 
1415
        pars_resolve_exp_variables_and_types(NULL, val);
 
1416
 
 
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))));
 
1419
 
 
1420
        return(node);
 
1421
}
 
1422
 
 
1423
/*************************************************************************
 
1424
Parses a procedure call. */
 
1425
 
 
1426
func_node_t*
 
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 */
 
1432
{
 
1433
        func_node_t*    node;
 
1434
 
 
1435
        node = pars_func(res_word, args);
 
1436
 
 
1437
        pars_resolve_exp_list_variables_and_types(NULL, args);
 
1438
 
 
1439
        return(node);
 
1440
}
 
1441
 
 
1442
/*************************************************************************
 
1443
Parses a fetch statement. into_list or user_func (but not both) must be
 
1444
non-NULL. */
 
1445
 
 
1446
fetch_node_t*
 
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 */
 
1453
{
 
1454
        sym_node_t*     cursor_decl;
 
1455
        fetch_node_t*   node;
 
1456
 
 
1457
        /* Logical XOR. */
 
1458
        ut_a(!into_list != !user_func);
 
1459
 
 
1460
        node = mem_heap_alloc(pars_sym_tab_global->heap, sizeof(fetch_node_t));
 
1461
 
 
1462
        node->common.type = QUE_NODE_FETCH;
 
1463
 
 
1464
        pars_resolve_exp_variables_and_types(NULL, cursor);
 
1465
 
 
1466
        if (into_list) {
 
1467
                pars_resolve_exp_list_variables_and_types(NULL, into_list);
 
1468
                node->into_list = into_list;
 
1469
                node->func = NULL;
 
1470
        } else {
 
1471
                pars_resolve_exp_variables_and_types(NULL, user_func);
 
1472
 
 
1473
                node->func = pars_info_get_user_func(pars_sym_tab_global->info,
 
1474
                                                     user_func->name);
 
1475
                ut_a(node->func);
 
1476
 
 
1477
                node->into_list = NULL;
 
1478
        }
 
1479
 
 
1480
        cursor_decl = cursor->alias;
 
1481
 
 
1482
        ut_a(cursor_decl->token_type == SYM_CURSOR);
 
1483
 
 
1484
        node->cursor_def = cursor_decl->cursor_def;
 
1485
 
 
1486
        if (into_list) {
 
1487
                ut_a(que_node_list_get_len(into_list)
 
1488
                     == que_node_list_get_len(node->cursor_def->select_list));
 
1489
        }
 
1490
 
 
1491
        return(node);
 
1492
}
 
1493
 
 
1494
/*************************************************************************
 
1495
Parses an open or close cursor statement. */
 
1496
 
 
1497
open_node_t*
 
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 */
 
1504
{
 
1505
        sym_node_t*     cursor_decl;
 
1506
        open_node_t*    node;
 
1507
 
 
1508
        node = mem_heap_alloc(pars_sym_tab_global->heap, sizeof(open_node_t));
 
1509
 
 
1510
        node->common.type = QUE_NODE_OPEN;
 
1511
 
 
1512
        pars_resolve_exp_variables_and_types(NULL, cursor);
 
1513
 
 
1514
        cursor_decl = cursor->alias;
 
1515
 
 
1516
        ut_a(cursor_decl->token_type == SYM_CURSOR);
 
1517
 
 
1518
        node->op_type = type;
 
1519
        node->cursor_def = cursor_decl->cursor_def;
 
1520
 
 
1521
        return(node);
 
1522
}
 
1523
 
 
1524
/*************************************************************************
 
1525
Parses a row_printf-statement. */
 
1526
 
 
1527
row_printf_node_t*
 
1528
pars_row_printf_statement(
 
1529
/*======================*/
 
1530
                                        /* out: row_printf-statement node */
 
1531
        sel_node_t*     sel_node)       /* in: select node */
 
1532
{
 
1533
        row_printf_node_t*      node;
 
1534
 
 
1535
        node = mem_heap_alloc(pars_sym_tab_global->heap,
 
1536
                              sizeof(row_printf_node_t));
 
1537
        node->common.type = QUE_NODE_ROW_PRINTF;
 
1538
 
 
1539
        node->sel_node = sel_node;
 
1540
 
 
1541
        sel_node->common.parent = node;
 
1542
 
 
1543
        return(node);
 
1544
}
 
1545
 
 
1546
/*************************************************************************
 
1547
Parses a commit statement. */
 
1548
 
 
1549
commit_node_t*
 
1550
pars_commit_statement(void)
 
1551
/*=======================*/
 
1552
{
 
1553
        return(commit_node_create(pars_sym_tab_global->heap));
 
1554
}
 
1555
 
 
1556
/*************************************************************************
 
1557
Parses a rollback statement. */
 
1558
 
 
1559
roll_node_t*
 
1560
pars_rollback_statement(void)
 
1561
/*=========================*/
 
1562
{
 
1563
        return(roll_node_create(pars_sym_tab_global->heap));
 
1564
}
 
1565
 
 
1566
/*************************************************************************
 
1567
Parses a column definition at a table creation. */
 
1568
 
 
1569
sym_node_t*
 
1570
pars_column_def(
 
1571
/*============*/
 
1572
                                                /* out: column sym table
 
1573
                                                node */
 
1574
        sym_node_t*             sym_node,       /* in: column node in the
 
1575
                                                symbol table */
 
1576
        pars_res_word_t*        type,           /* in: data type */
 
1577
        sym_node_t*             len,            /* in: length of column, or
 
1578
                                                NULL */
 
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. */
 
1583
{
 
1584
        ulint len2;
 
1585
 
 
1586
        if (len) {
 
1587
                len2 = eval_node_get_int_val(len);
 
1588
        } else {
 
1589
                len2 = 0;
 
1590
        }
 
1591
 
 
1592
        pars_set_dfield_type(que_node_get_val(sym_node), type, len2,
 
1593
                             is_unsigned != NULL, is_not_null != NULL);
 
1594
 
 
1595
        return(sym_node);
 
1596
}
 
1597
 
 
1598
/*************************************************************************
 
1599
Parses a table creation operation. */
 
1600
 
 
1601
tab_node_t*
 
1602
pars_create_table(
 
1603
/*==============*/
 
1604
                                        /* out: table create subgraph */
 
1605
        sym_node_t*     table_sym,      /* in: table name node in the symbol
 
1606
                                        table */
 
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
 
1618
                                        from disk */
 
1619
{
 
1620
        dict_table_t*   table;
 
1621
        sym_node_t*     column;
 
1622
        tab_node_t*     node;
 
1623
        dtype_t*        dtype;
 
1624
        ulint           n_cols;
 
1625
 
 
1626
        n_cols = que_node_list_get_len(column_defs);
 
1627
 
 
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);
 
1632
 
 
1633
#ifdef UNIV_DEBUG
 
1634
        if (not_fit_in_memory != NULL) {
 
1635
                table->does_not_fit_in_memory = TRUE;
 
1636
        }
 
1637
#endif /* UNIV_DEBUG */
 
1638
        column = column_defs;
 
1639
 
 
1640
        while (column) {
 
1641
                dtype = dfield_get_type(que_node_get_val(column));
 
1642
 
 
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;
 
1648
 
 
1649
                column = que_node_get_next(column);
 
1650
        }
 
1651
 
 
1652
        node = tab_create_graph_create(table, pars_sym_tab_global->heap);
 
1653
 
 
1654
        table_sym->resolved = TRUE;
 
1655
        table_sym->token_type = SYM_TABLE;
 
1656
 
 
1657
        return(node);
 
1658
}
 
1659
 
 
1660
/*************************************************************************
 
1661
Parses an index creation operation. */
 
1662
 
 
1663
ind_node_t*
 
1664
pars_create_index(
 
1665
/*==============*/
 
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
 
1670
                                        table */
 
1671
        sym_node_t*     table_sym,      /* in: table name node in the symbol
 
1672
                                        table */
 
1673
        sym_node_t*     column_list)    /* in: list of column names */
 
1674
{
 
1675
        dict_index_t*   index;
 
1676
        sym_node_t*     column;
 
1677
        ind_node_t*     node;
 
1678
        ulint           n_fields;
 
1679
        ulint           ind_type;
 
1680
 
 
1681
        n_fields = que_node_list_get_len(column_list);
 
1682
 
 
1683
        ind_type = 0;
 
1684
 
 
1685
        if (unique_def) {
 
1686
                ind_type = ind_type | DICT_UNIQUE;
 
1687
        }
 
1688
 
 
1689
        if (clustered_def) {
 
1690
                ind_type = ind_type | DICT_CLUSTERED;
 
1691
        }
 
1692
 
 
1693
        index = dict_mem_index_create(table_sym->name, index_sym->name, 0,
 
1694
                                      ind_type, n_fields);
 
1695
        column = column_list;
 
1696
 
 
1697
        while (column) {
 
1698
                dict_mem_index_add_field(index, column->name, 0);
 
1699
 
 
1700
                column->resolved = TRUE;
 
1701
                column->token_type = SYM_COLUMN;
 
1702
 
 
1703
                column = que_node_get_next(column);
 
1704
        }
 
1705
 
 
1706
        node = ind_create_graph_create(index, pars_sym_tab_global->heap);
 
1707
 
 
1708
        table_sym->resolved = TRUE;
 
1709
        table_sym->token_type = SYM_TABLE;
 
1710
 
 
1711
        index_sym->resolved = TRUE;
 
1712
        index_sym->token_type = SYM_TABLE;
 
1713
 
 
1714
        return(node);
 
1715
}
 
1716
 
 
1717
/*************************************************************************
 
1718
Parses a procedure definition. */
 
1719
 
 
1720
que_fork_t*
 
1721
pars_procedure_definition(
 
1722
/*======================*/
 
1723
                                        /* out: query fork node */
 
1724
        sym_node_t*     sym_node,       /* in: procedure id node in the symbol
 
1725
                                        table */
 
1726
        sym_node_t*     param_list,     /* in: parameter declaration list */
 
1727
        que_node_t*     stat_list)      /* in: statement list */
 
1728
{
 
1729
        proc_node_t*    node;
 
1730
        que_fork_t*     fork;
 
1731
        que_thr_t*      thr;
 
1732
        mem_heap_t*     heap;
 
1733
 
 
1734
        heap = pars_sym_tab_global->heap;
 
1735
 
 
1736
        fork = que_fork_create(NULL, NULL, QUE_FORK_PROCEDURE, heap);
 
1737
        fork->trx = NULL;
 
1738
 
 
1739
        thr = que_thr_create(fork, heap);
 
1740
 
 
1741
        node = mem_heap_alloc(heap, sizeof(proc_node_t));
 
1742
 
 
1743
        node->common.type = QUE_NODE_PROC;
 
1744
        node->common.parent = thr;
 
1745
 
 
1746
        sym_node->token_type = SYM_PROCEDURE_NAME;
 
1747
        sym_node->resolved = TRUE;
 
1748
 
 
1749
        node->proc_id = sym_node;
 
1750
        node->param_list = param_list;
 
1751
        node->stat_list = stat_list;
 
1752
 
 
1753
        pars_set_parent_in_list(stat_list, node);
 
1754
 
 
1755
        node->sym_tab = pars_sym_tab_global;
 
1756
 
 
1757
        thr->child = node;
 
1758
 
 
1759
        pars_sym_tab_global->query_graph = fork;
 
1760
 
 
1761
        return(fork);
 
1762
}
 
1763
 
 
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. */
 
1769
 
 
1770
que_fork_t*
 
1771
pars_stored_procedure_call(
 
1772
/*=======================*/
 
1773
                                        /* out: query graph */
 
1774
        sym_node_t*     sym_node __attribute__((unused)))
 
1775
                                        /* in: stored procedure name */
 
1776
{
 
1777
        ut_error;
 
1778
        return(NULL);
 
1779
}
 
1780
 
 
1781
/*****************************************************************
 
1782
Retrieves characters to the lexical analyzer. */
 
1783
 
 
1784
void
 
1785
pars_get_lex_chars(
 
1786
/*===============*/
 
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
 
1790
                                in the buffer */
 
1791
{
 
1792
        int     len;
 
1793
 
 
1794
        len = pars_sym_tab_global->string_len
 
1795
                - pars_sym_tab_global->next_char_pos;
 
1796
        if (len == 0) {
 
1797
#ifdef YYDEBUG
 
1798
                /* fputs("SQL string ends\n", stderr); */
 
1799
#endif
 
1800
                *result = 0;
 
1801
 
 
1802
                return;
 
1803
        }
 
1804
 
 
1805
        if (len > max_size) {
 
1806
                len = max_size;
 
1807
        }
 
1808
 
 
1809
#ifdef UNIV_SQL_DEBUG
 
1810
        if (pars_print_lexed) {
 
1811
 
 
1812
                if (len >= 5) {
 
1813
                        len = 5;
 
1814
                }
 
1815
 
 
1816
                fwrite(pars_sym_tab_global->sql_string
 
1817
                       + pars_sym_tab_global->next_char_pos,
 
1818
                       1, len, stderr);
 
1819
        }
 
1820
#endif /* UNIV_SQL_DEBUG */
 
1821
 
 
1822
        ut_memcpy(buf, pars_sym_tab_global->sql_string
 
1823
                  + pars_sym_tab_global->next_char_pos, len);
 
1824
        *result = len;
 
1825
 
 
1826
        pars_sym_tab_global->next_char_pos += len;
 
1827
}
 
1828
 
 
1829
/*****************************************************************
 
1830
Called by yyparse on error. */
 
1831
 
 
1832
void
 
1833
yyerror(
 
1834
/*====*/
 
1835
        const char*     s __attribute__((unused)))
 
1836
                                /* in: error message string */
 
1837
{
 
1838
        ut_ad(s);
 
1839
 
 
1840
        fputs("PARSER ERROR: Syntax error in SQL string\n", stderr);
 
1841
 
 
1842
        ut_error;
 
1843
}
 
1844
 
 
1845
/*****************************************************************
 
1846
Parses an SQL string returning the query graph. */
 
1847
 
 
1848
que_t*
 
1849
pars_sql(
 
1850
/*=====*/
 
1851
                                /* out, own: the query graph */
 
1852
        pars_info_t*    info,   /* in: extra information, or NULL */
 
1853
        const char*     str)    /* in: SQL string */
 
1854
{
 
1855
        sym_node_t*     sym_node;
 
1856
        mem_heap_t*     heap;
 
1857
        que_t*          graph;
 
1858
 
 
1859
        ut_ad(str);
 
1860
 
 
1861
        heap = mem_heap_create(256);
 
1862
 
 
1863
        /* Currently, the parser is not reentrant: */
 
1864
        ut_ad(mutex_own(&(dict_sys->mutex)));
 
1865
 
 
1866
        pars_sym_tab_global = sym_tab_create(heap);
 
1867
 
 
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;
 
1873
 
 
1874
        yyparse();
 
1875
 
 
1876
        sym_node = UT_LIST_GET_FIRST(pars_sym_tab_global->sym_list);
 
1877
 
 
1878
        while (sym_node) {
 
1879
                ut_a(sym_node->resolved);
 
1880
 
 
1881
                sym_node = UT_LIST_GET_NEXT(sym_list, sym_node);
 
1882
        }
 
1883
 
 
1884
        graph = pars_sym_tab_global->query_graph;
 
1885
 
 
1886
        graph->sym_tab = pars_sym_tab_global;
 
1887
        graph->info = info;
 
1888
 
 
1889
        /* fprintf(stderr, "SQL graph size %lu\n", mem_heap_get_size(heap)); */
 
1890
 
 
1891
        return(graph);
 
1892
}
 
1893
 
 
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. */
 
1898
 
 
1899
que_thr_t*
 
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
 
1904
                                query graph */
 
1905
        trx_t*          trx,    /* in: transaction handle */
 
1906
        mem_heap_t*     heap)   /* in: memory heap from which allocated */
 
1907
{
 
1908
        que_fork_t*     fork;
 
1909
        que_thr_t*      thr;
 
1910
 
 
1911
        fork = que_fork_create(NULL, NULL, QUE_FORK_MYSQL_INTERFACE, heap);
 
1912
        fork->trx = trx;
 
1913
 
 
1914
        thr = que_thr_create(fork, heap);
 
1915
 
 
1916
        thr->child = node;
 
1917
 
 
1918
        que_node_set_parent(node, thr);
 
1919
 
 
1920
        trx->graph = NULL;
 
1921
 
 
1922
        return(thr);
 
1923
}
 
1924
 
 
1925
/********************************************************************
 
1926
Create parser info struct.*/
 
1927
 
 
1928
pars_info_t*
 
1929
pars_info_create(void)
 
1930
/*==================*/
 
1931
                /* out, own: info struct */
 
1932
{
 
1933
        pars_info_t*    info;
 
1934
        mem_heap_t*     heap;
 
1935
 
 
1936
        heap = mem_heap_create(512);
 
1937
 
 
1938
        info = mem_heap_alloc(heap, sizeof(*info));
 
1939
 
 
1940
        info->heap = heap;
 
1941
        info->funcs = NULL;
 
1942
        info->bound_lits = NULL;
 
1943
        info->bound_ids = NULL;
 
1944
        info->graph_owns_us = TRUE;
 
1945
 
 
1946
        return(info);
 
1947
}
 
1948
 
 
1949
/********************************************************************
 
1950
Free info struct and everything it contains.*/
 
1951
 
 
1952
void
 
1953
pars_info_free(
 
1954
/*===========*/
 
1955
        pars_info_t*    info)   /* in: info struct */
 
1956
{
 
1957
        mem_heap_free(info->heap);
 
1958
}
 
1959
 
 
1960
/********************************************************************
 
1961
Add bound literal. */
 
1962
 
 
1963
void
 
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.
 
1972
                                        DATA_UNSIGNED */
 
1973
{
 
1974
        pars_bound_lit_t*       pbl;
 
1975
 
 
1976
        ut_ad(!pars_info_get_bound_lit(info, name));
 
1977
 
 
1978
        pbl = mem_heap_alloc(info->heap, sizeof(*pbl));
 
1979
 
 
1980
        pbl->name = name;
 
1981
        pbl->address = address;
 
1982
        pbl->length = length;
 
1983
        pbl->type = type;
 
1984
        pbl->prtype = prtype;
 
1985
 
 
1986
        if (!info->bound_lits) {
 
1987
                info->bound_lits = ib_vector_create(info->heap, 8);
 
1988
        }
 
1989
 
 
1990
        ib_vector_push(info->bound_lits, pbl);
 
1991
}
 
1992
 
 
1993
/********************************************************************
 
1994
Equivalent to pars_info_add_literal(info, name, str, strlen(str),
 
1995
DATA_VARCHAR, DATA_ENGLISH). */
 
1996
 
 
1997
void
 
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 */
 
2003
{
 
2004
        pars_info_add_literal(info, name, str, strlen(str),
 
2005
                              DATA_VARCHAR, DATA_ENGLISH);
 
2006
}
 
2007
 
 
2008
/********************************************************************
 
2009
Equivalent to:
 
2010
 
 
2011
char buf[4];
 
2012
mach_write_to_4(buf, val);
 
2013
pars_info_add_literal(info, name, buf, 4, DATA_INT, 0);
 
2014
 
 
2015
except that the buffer is dynamically allocated from the info struct's
 
2016
heap. */
 
2017
 
 
2018
void
 
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 */
 
2024
{
 
2025
        byte*   buf = mem_heap_alloc(info->heap, 4);
 
2026
 
 
2027
        mach_write_to_4(buf, val);
 
2028
        pars_info_add_literal(info, name, buf, 4, DATA_INT, 0);
 
2029
}
 
2030
 
 
2031
/********************************************************************
 
2032
Equivalent to:
 
2033
 
 
2034
char buf[8];
 
2035
mach_write_to_8(buf, val);
 
2036
pars_info_add_literal(info, name, buf, 8, DATA_FIXBINARY, 0);
 
2037
 
 
2038
except that the buffer is dynamically allocated from the info struct's
 
2039
heap. */
 
2040
 
 
2041
void
 
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 */
 
2047
{
 
2048
        byte*   buf = mem_heap_alloc(info->heap, 8);
 
2049
 
 
2050
        mach_write_to_8(buf, val);
 
2051
 
 
2052
        pars_info_add_literal(info, name, buf, 8, DATA_FIXBINARY, 0);
 
2053
}
 
2054
 
 
2055
/********************************************************************
 
2056
Add user function. */
 
2057
 
 
2058
void
 
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 */
 
2065
{
 
2066
        pars_user_func_t*       puf;
 
2067
 
 
2068
        ut_ad(!pars_info_get_user_func(info, name));
 
2069
 
 
2070
        puf = mem_heap_alloc(info->heap, sizeof(*puf));
 
2071
 
 
2072
        puf->name = name;
 
2073
        puf->func = func;
 
2074
        puf->arg = arg;
 
2075
 
 
2076
        if (!info->funcs) {
 
2077
                info->funcs = ib_vector_create(info->heap, 8);
 
2078
        }
 
2079
 
 
2080
        ib_vector_push(info->funcs, puf);
 
2081
}
 
2082
 
 
2083
/********************************************************************
 
2084
Add bound id. */
 
2085
 
 
2086
void
 
2087
pars_info_add_id(
 
2088
/*=============*/
 
2089
        pars_info_t*    info,           /* in: info struct */
 
2090
        const char*     name,           /* in: name */
 
2091
        const char*     id)             /* in: id */
 
2092
{
 
2093
        pars_bound_id_t*        bid;
 
2094
 
 
2095
        ut_ad(!pars_info_get_bound_id(info, name));
 
2096
 
 
2097
        bid = mem_heap_alloc(info->heap, sizeof(*bid));
 
2098
 
 
2099
        bid->name = name;
 
2100
        bid->id = id;
 
2101
 
 
2102
        if (!info->bound_ids) {
 
2103
                info->bound_ids = ib_vector_create(info->heap, 8);
 
2104
        }
 
2105
 
 
2106
        ib_vector_push(info->bound_ids, bid);
 
2107
}
 
2108
 
 
2109
/********************************************************************
 
2110
Get user function with the given name.*/
 
2111
 
 
2112
pars_user_func_t*
 
2113
pars_info_get_user_func(
 
2114
/*====================*/
 
2115
                                        /* out: user func, or NULL if not
 
2116
                                        found */
 
2117
        pars_info_t*            info,   /* in: info struct */
 
2118
        const char*             name)   /* in: function name to find*/
 
2119
{
 
2120
        ulint           i;
 
2121
        ib_vector_t*    vec;
 
2122
 
 
2123
        if (!info || !info->funcs) {
 
2124
                return(NULL);
 
2125
        }
 
2126
 
 
2127
        vec = info->funcs;
 
2128
 
 
2129
        for (i = 0; i < ib_vector_size(vec); i++) {
 
2130
                pars_user_func_t*       puf = ib_vector_get(vec, i);
 
2131
 
 
2132
                if (strcmp(puf->name, name) == 0) {
 
2133
                        return(puf);
 
2134
                }
 
2135
        }
 
2136
 
 
2137
        return(NULL);
 
2138
}
 
2139
 
 
2140
/********************************************************************
 
2141
Get bound literal with the given name.*/
 
2142
 
 
2143
pars_bound_lit_t*
 
2144
pars_info_get_bound_lit(
 
2145
/*====================*/
 
2146
                                        /* out: bound literal, or NULL if
 
2147
                                        not found */
 
2148
        pars_info_t*            info,   /* in: info struct */
 
2149
        const char*             name)   /* in: bound literal name to find */
 
2150
{
 
2151
        ulint           i;
 
2152
        ib_vector_t*    vec;
 
2153
 
 
2154
        if (!info || !info->bound_lits) {
 
2155
                return(NULL);
 
2156
        }
 
2157
 
 
2158
        vec = info->bound_lits;
 
2159
 
 
2160
        for (i = 0; i < ib_vector_size(vec); i++) {
 
2161
                pars_bound_lit_t*       pbl = ib_vector_get(vec, i);
 
2162
 
 
2163
                if (strcmp(pbl->name, name) == 0) {
 
2164
                        return(pbl);
 
2165
                }
 
2166
        }
 
2167
 
 
2168
        return(NULL);
 
2169
}
 
2170
 
 
2171
/********************************************************************
 
2172
Get bound id with the given name.*/
 
2173
 
 
2174
pars_bound_id_t*
 
2175
pars_info_get_bound_id(
 
2176
/*===================*/
 
2177
                                        /* out: bound id, or NULL if not
 
2178
                                        found */
 
2179
        pars_info_t*            info,   /* in: info struct */
 
2180
        const char*             name)   /* in: bound id name to find */
 
2181
{
 
2182
        ulint           i;
 
2183
        ib_vector_t*    vec;
 
2184
 
 
2185
        if (!info || !info->bound_ids) {
 
2186
                return(NULL);
 
2187
        }
 
2188
 
 
2189
        vec = info->bound_ids;
 
2190
 
 
2191
        for (i = 0; i < ib_vector_size(vec); i++) {
 
2192
                pars_bound_id_t*        bid = ib_vector_get(vec, i);
 
2193
 
 
2194
                if (strcmp(bid->name, name) == 0) {
 
2195
                        return(bid);
 
2196
                }
 
2197
        }
 
2198
 
 
2199
        return(NULL);
 
2200
}