~drizzle-trunk/drizzle/development

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