~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to plugin/innobase/pars/pars0pars.cc

  • Committer: Mark Atwood
  • Date: 2008-10-03 01:39:40 UTC
  • mto: This revision was merged to the branch mainline in revision 437.
  • Revision ID: mark@fallenpegasus.com-20081003013940-mvefjo725dltz41h
rename logging_noop to logging_query

Show diffs side-by-side

added added

removed removed

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