~drizzle-trunk/drizzle/development

« back to all changes in this revision

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

  • Committer: Brian Aker
  • Date: 2010-01-22 00:53:13 UTC
  • Revision ID: brian@gaz-20100122005313-jmizcbcdi1lt4tcx
Revert db patch.

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->klass = 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->klass == 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_DRIZZLE_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_DRIZZLE_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
 
}