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