1 /*****************************************************************************
2 
3 Copyright (c) 1997, 2011, Oracle and/or its affiliates. All Rights Reserved.
4 
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License, version 2.0,
7 as published by the Free Software Foundation.
8 
9 This program is also distributed with certain software (including
10 but not limited to OpenSSL) that is licensed under separate terms,
11 as designated in a particular file or component or in included license
12 documentation.  The authors of MySQL hereby grant you an additional
13 permission to link the program and your derivative works with the
14 separately licensed software that they have included with MySQL.
15 
16 This program is distributed in the hope that it will be useful,
17 but WITHOUT ANY WARRANTY; without even the implied warranty of
18 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19 GNU General Public License, version 2.0, for more details.
20 
21 You should have received a copy of the GNU General Public License along with
22 this program; if not, write to the Free Software Foundation, Inc.,
23 51 Franklin Street, Suite 500, Boston, MA 02110-1335 USA
24 
25 *****************************************************************************/
26 
27 /**************************************************//**
28 @file pars/pars0sym.cc
29 SQL parser symbol table
30 
31 Created 12/15/1997 Heikki Tuuri
32 *******************************************************/
33 
34 #include "pars0sym.h"
35 
36 #ifdef UNIV_NONINL
37 #include "pars0sym.ic"
38 #endif
39 
40 #include "mem0mem.h"
41 #include "data0type.h"
42 #include "data0data.h"
43 #include "pars0grm.h"
44 #include "pars0pars.h"
45 #include "que0que.h"
46 #include "eval0eval.h"
47 #include "row0sel.h"
48 
49 /******************************************************************//**
50 Creates a symbol table for a single stored procedure or query.
51 @return	own: symbol table */
52 UNIV_INTERN
53 sym_tab_t*
sym_tab_create(mem_heap_t * heap)54 sym_tab_create(
55 /*===========*/
56 	mem_heap_t*	heap)	/*!< in: memory heap where to create */
57 {
58 	sym_tab_t*	sym_tab;
59 
60 	sym_tab = static_cast<sym_tab_t*>(
61 		mem_heap_alloc(heap, sizeof(sym_tab_t)));
62 
63 	UT_LIST_INIT(sym_tab->sym_list);
64 	UT_LIST_INIT(sym_tab->func_node_list);
65 
66 	sym_tab->heap = heap;
67 
68 	return(sym_tab);
69 }
70 
71 
72 /******************************************************************//**
73 Frees the memory allocated dynamically AFTER parsing phase for variables
74 etc. in the symbol table. Does not free the mem heap where the table was
75 originally created. Frees also SQL explicit cursor definitions. */
76 UNIV_INTERN
77 void
sym_tab_free_private(sym_tab_t * sym_tab)78 sym_tab_free_private(
79 /*=================*/
80 	sym_tab_t*	sym_tab)	/*!< in, own: symbol table */
81 {
82 	sym_node_t*	sym;
83 	func_node_t*	func;
84 
85 	ut_ad(mutex_own(&dict_sys->mutex));
86 
87 	for (sym = UT_LIST_GET_FIRST(sym_tab->sym_list);
88 	     sym != NULL;
89 	     sym = UT_LIST_GET_NEXT(sym_list, sym)) {
90 
91 		/* Close the tables opened in pars_retrieve_table_def(). */
92 
93 		if (sym->token_type == SYM_TABLE_REF_COUNTED) {
94 
95 			dict_table_close(sym->table, TRUE, FALSE);
96 
97 			sym->table = NULL;
98 			sym->resolved = FALSE;
99 			sym->token_type = SYM_UNSET;
100 		}
101 
102 		eval_node_free_val_buf(sym);
103 
104 		if (sym->prefetch_buf) {
105 			sel_col_prefetch_buf_free(sym->prefetch_buf);
106 		}
107 
108 		if (sym->cursor_def) {
109 			que_graph_free_recursive(sym->cursor_def);
110 		}
111 	}
112 
113 	for (func = UT_LIST_GET_FIRST(sym_tab->func_node_list);
114 	     func != NULL;
115 	     func = UT_LIST_GET_NEXT(func_node_list, func)) {
116 
117 		eval_node_free_val_buf(func);
118 	}
119 }
120 
121 /******************************************************************//**
122 Adds an integer literal to a symbol table.
123 @return	symbol table node */
124 UNIV_INTERN
125 sym_node_t*
sym_tab_add_int_lit(sym_tab_t * sym_tab,ulint val)126 sym_tab_add_int_lit(
127 /*================*/
128 	sym_tab_t*	sym_tab,	/*!< in: symbol table */
129 	ulint		val)		/*!< in: integer value */
130 {
131 	sym_node_t*	node;
132 	byte*		data;
133 
134 	node = static_cast<sym_node_t*>(
135 		mem_heap_alloc(sym_tab->heap, sizeof(sym_node_t)));
136 
137 	node->common.type = QUE_NODE_SYMBOL;
138 
139 	node->table = NULL;
140 	node->resolved = TRUE;
141 	node->token_type = SYM_LIT;
142 
143 	node->indirection = NULL;
144 
145 	dtype_set(dfield_get_type(&node->common.val), DATA_INT, 0, 4);
146 
147 	data = static_cast<byte*>(mem_heap_alloc(sym_tab->heap, 4));
148 	mach_write_to_4(data, val);
149 
150 	dfield_set_data(&(node->common.val), data, 4);
151 
152 	node->common.val_buf_size = 0;
153 	node->prefetch_buf = NULL;
154 	node->cursor_def = NULL;
155 
156 	UT_LIST_ADD_LAST(sym_list, sym_tab->sym_list, node);
157 
158 	node->like_node = NULL;
159 
160 	node->sym_table = sym_tab;
161 
162 	return(node);
163 }
164 
165 /******************************************************************//**
166 Adds a string literal to a symbol table.
167 @return	symbol table node */
168 UNIV_INTERN
169 sym_node_t*
sym_tab_add_str_lit(sym_tab_t * sym_tab,const byte * str,ulint len)170 sym_tab_add_str_lit(
171 /*================*/
172 	sym_tab_t*	sym_tab,	/*!< in: symbol table */
173 	const byte*	str,		/*!< in: string with no quotes around
174 					it */
175 	ulint		len)		/*!< in: string length */
176 {
177 	sym_node_t*	node;
178 	byte*		data;
179 
180 	node = static_cast<sym_node_t*>(
181 		mem_heap_alloc(sym_tab->heap, sizeof(sym_node_t)));
182 
183 	node->common.type = QUE_NODE_SYMBOL;
184 
185 	node->table = NULL;
186 	node->resolved = TRUE;
187 	node->token_type = SYM_LIT;
188 
189 	node->indirection = NULL;
190 
191 	dtype_set(dfield_get_type(&node->common.val),
192 		  DATA_VARCHAR, DATA_ENGLISH, 0);
193 
194 	data = (len) ? static_cast<byte*>(mem_heap_dup(sym_tab->heap, str, len))
195 	      	     : NULL;
196 
197 	dfield_set_data(&(node->common.val), data, len);
198 
199 	node->common.val_buf_size = 0;
200 	node->prefetch_buf = NULL;
201 	node->cursor_def = NULL;
202 
203 	UT_LIST_ADD_LAST(sym_list, sym_tab->sym_list, node);
204 
205 	node->like_node = NULL;
206 
207 	node->sym_table = sym_tab;
208 
209 	return(node);
210 }
211 
212 /******************************************************************//**
213 Add a bound literal to a symbol table.
214 @return	symbol table node */
215 UNIV_INTERN
216 sym_node_t*
sym_tab_add_bound_lit(sym_tab_t * sym_tab,const char * name,ulint * lit_type)217 sym_tab_add_bound_lit(
218 /*==================*/
219 	sym_tab_t*	sym_tab,	/*!< in: symbol table */
220 	const char*	name,		/*!< in: name of bound literal */
221 	ulint*		lit_type)	/*!< out: type of literal (PARS_*_LIT) */
222 {
223 	sym_node_t*		node;
224 	pars_bound_lit_t*	blit;
225 	ulint			len = 0;
226 
227 	blit = pars_info_get_bound_lit(sym_tab->info, name);
228 	ut_a(blit);
229 
230 	node = static_cast<sym_node_t*>(
231 		mem_heap_alloc(sym_tab->heap, sizeof(sym_node_t)));
232 
233 	node->common.type = QUE_NODE_SYMBOL;
234 	node->common.brother = node->common.parent = NULL;
235 
236 	node->table = NULL;
237 	node->resolved = TRUE;
238 	node->token_type = SYM_LIT;
239 
240 	node->indirection = NULL;
241 
242 	switch (blit->type) {
243 	case DATA_FIXBINARY:
244 		len = blit->length;
245 		*lit_type = PARS_FIXBINARY_LIT;
246 		break;
247 
248 	case DATA_BLOB:
249 		*lit_type = PARS_BLOB_LIT;
250 		break;
251 
252 	case DATA_VARCHAR:
253 		*lit_type = PARS_STR_LIT;
254 		break;
255 
256 	case DATA_CHAR:
257 		ut_a(blit->length > 0);
258 
259 		len = blit->length;
260 		*lit_type = PARS_STR_LIT;
261 		break;
262 
263 	case DATA_INT:
264 		ut_a(blit->length > 0);
265 		ut_a(blit->length <= 8);
266 
267 		len = blit->length;
268 		*lit_type = PARS_INT_LIT;
269 		break;
270 
271 	default:
272 		ut_error;
273 	}
274 
275 	dtype_set(dfield_get_type(&node->common.val),
276 		  blit->type, blit->prtype, len);
277 
278 	dfield_set_data(&(node->common.val), blit->address, blit->length);
279 
280 	node->common.val_buf_size = 0;
281 	node->prefetch_buf = NULL;
282 	node->cursor_def = NULL;
283 
284 	UT_LIST_ADD_LAST(sym_list, sym_tab->sym_list, node);
285 
286 	blit->node = node;
287 	node->like_node = NULL;
288 	node->sym_table = sym_tab;
289 
290 	return(node);
291 }
292 
293 /**********************************************************************
294 Rebind literal to a node in the symbol table. */
295 
296 sym_node_t*
sym_tab_rebind_lit(sym_node_t * node,const void * address,ulint length)297 sym_tab_rebind_lit(
298 /*===============*/
299 					/* out: symbol table node */
300 	sym_node_t*	node,		/* in: node that is bound to literal*/
301 	const void*	address,	/* in: pointer to data */
302 	ulint		length)		/* in: length of data */
303 {
304 	dfield_t*	dfield = que_node_get_val(node);
305 	dtype_t*	dtype = dfield_get_type(dfield);
306 
307 	ut_a(node->token_type == SYM_LIT);
308 
309 	dfield_set_data(&node->common.val, address, length);
310 
311 	if (node->like_node) {
312 
313 	    ut_a(dtype_get_mtype(dtype) == DATA_CHAR
314 		 || dtype_get_mtype(dtype) == DATA_VARCHAR);
315 
316 		/* Don't force [FALSE] creation of sub-nodes (for LIKE) */
317 		pars_like_rebind(
318 			node,static_cast<const byte*>(address), length);
319 	}
320 
321 	/* FIXME: What's this ? */
322 	node->common.val_buf_size = 0;
323 
324 	if (node->prefetch_buf) {
325 		sel_col_prefetch_buf_free(node->prefetch_buf);
326 		node->prefetch_buf = NULL;
327 	}
328 
329 	if (node->cursor_def) {
330 		que_graph_free_recursive(node->cursor_def);
331 		node->cursor_def = NULL;
332 	}
333 
334 	return(node);
335 }
336 
337 /******************************************************************//**
338 Adds an SQL null literal to a symbol table.
339 @return	symbol table node */
340 UNIV_INTERN
341 sym_node_t*
sym_tab_add_null_lit(sym_tab_t * sym_tab)342 sym_tab_add_null_lit(
343 /*=================*/
344 	sym_tab_t*	sym_tab)	/*!< in: symbol table */
345 {
346 	sym_node_t*	node;
347 
348 	node = static_cast<sym_node_t*>(
349 		mem_heap_alloc(sym_tab->heap, sizeof(sym_node_t)));
350 
351 	node->common.type = QUE_NODE_SYMBOL;
352 
353 	node->table = NULL;
354 	node->resolved = TRUE;
355 	node->token_type = SYM_LIT;
356 
357 	node->indirection = NULL;
358 
359 	dfield_get_type(&node->common.val)->mtype = DATA_ERROR;
360 
361 	dfield_set_null(&node->common.val);
362 
363 	node->common.val_buf_size = 0;
364 	node->prefetch_buf = NULL;
365 	node->cursor_def = NULL;
366 
367 	UT_LIST_ADD_LAST(sym_list, sym_tab->sym_list, node);
368 
369 	node->like_node = NULL;
370 
371 	node->sym_table = sym_tab;
372 
373 	return(node);
374 }
375 
376 /******************************************************************//**
377 Adds an identifier to a symbol table.
378 @return	symbol table node */
379 UNIV_INTERN
380 sym_node_t*
sym_tab_add_id(sym_tab_t * sym_tab,byte * name,ulint len)381 sym_tab_add_id(
382 /*===========*/
383 	sym_tab_t*	sym_tab,	/*!< in: symbol table */
384 	byte*		name,		/*!< in: identifier name */
385 	ulint		len)		/*!< in: identifier length */
386 {
387 	sym_node_t*	node;
388 
389 	node = static_cast<sym_node_t*>(
390 		mem_heap_zalloc(sym_tab->heap, sizeof(*node)));
391 
392 	node->common.type = QUE_NODE_SYMBOL;
393 
394 	node->name = mem_heap_strdupl(sym_tab->heap, (char*) name, len);
395 	node->name_len = len;
396 
397 	UT_LIST_ADD_LAST(sym_list, sym_tab->sym_list, node);
398 
399 	dfield_set_null(&node->common.val);
400 
401 	node->sym_table = sym_tab;
402 
403 	return(node);
404 }
405 
406 /******************************************************************//**
407 Add a bound identifier to a symbol table.
408 @return	symbol table node */
409 UNIV_INTERN
410 sym_node_t*
sym_tab_add_bound_id(sym_tab_t * sym_tab,const char * name)411 sym_tab_add_bound_id(
412 /*=================*/
413 	sym_tab_t*	sym_tab,	/*!< in: symbol table */
414 	const char*	name)		/*!< in: name of bound id */
415 {
416 	sym_node_t*		node;
417 	pars_bound_id_t*	bid;
418 
419 	bid = pars_info_get_bound_id(sym_tab->info, name);
420 	ut_a(bid);
421 
422 	node = static_cast<sym_node_t*>(
423 		mem_heap_alloc(sym_tab->heap, sizeof(sym_node_t)));
424 
425 	node->common.type = QUE_NODE_SYMBOL;
426 
427 	node->table = NULL;
428 	node->resolved = FALSE;
429 	node->token_type = SYM_UNSET;
430 	node->indirection = NULL;
431 
432 	node->name = mem_heap_strdup(sym_tab->heap, bid->id);
433 	node->name_len = strlen(node->name);
434 
435 	UT_LIST_ADD_LAST(sym_list, sym_tab->sym_list, node);
436 
437 	dfield_set_null(&node->common.val);
438 
439 	node->common.val_buf_size = 0;
440 	node->prefetch_buf = NULL;
441 	node->cursor_def = NULL;
442 
443 	node->like_node = NULL;
444 
445 	node->sym_table = sym_tab;
446 
447 	return(node);
448 }
449