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