~stewart/haildb/trunk

« back to all changes in this revision

Viewing changes to pars/pars0pars.c

  • Committer: Stewart Smith
  • Date: 2010-04-09 07:57:43 UTC
  • Revision ID: stewart@flamingspork.com-20100409075743-jfh1oml3el1uouvh
Embedded InnoDB 1.0.0 released

2009-04-21      The InnoDB Team

        Embedded InnoDB 1.0.0 released

Show diffs side-by-side

added added

removed removed

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