1/*****************************************************************************
2
3Copyright (c) 1997, 2016, Oracle and/or its affiliates. All Rights Reserved.
4
5This program is free software; you can redistribute it and/or modify it under
6the terms of the GNU General Public License as published by the Free Software
7Foundation; version 2 of the License.
8
9This program is distributed in the hope that it will be useful, but WITHOUT
10ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
11FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
12
13You should have received a copy of the GNU General Public License along with
14this program; if not, write to the Free Software Foundation, Inc.,
1551 Franklin Street, Suite 500, Boston, MA 02110-1335 USA
16
17*****************************************************************************/
18
19/**************************************************//**
20@file pars/pars0sym.cc
21SQL parser symbol table
22
23Created 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/******************************************************************//**
37Creates a symbol table for a single stored procedure or query.
38@return own: symbol table */
39sym_tab_t*
40sym_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/******************************************************************//**
59Frees the memory allocated dynamically AFTER parsing phase for variables
60etc. in the symbol table. Does not free the mem heap where the table was
61originally created. Frees also SQL explicit cursor definitions. */
62void
63sym_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/******************************************************************//**
107Adds an integer literal to a symbol table.
108@return symbol table node */
109sym_node_t*
110sym_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/******************************************************************//**
150Adds a string literal to a symbol table.
151@return symbol table node */
152sym_node_t*
153sym_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/******************************************************************//**
196Add a bound literal to a symbol table.
197@return symbol table node */
198sym_node_t*
199sym_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/**********************************************************************
266Rebind literal to a node in the symbol table. */
267sym_node_t*
268sym_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/******************************************************************//**
309Adds an SQL null literal to a symbol table.
310@return symbol table node */
311sym_node_t*
312sym_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/******************************************************************//**
347Adds an identifier to a symbol table.
348@return symbol table node */
349sym_node_t*
350sym_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/******************************************************************//**
376Add a bound identifier to a symbol table.
377@return symbol table node */
378sym_node_t*
379sym_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