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, Suite 500, 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* |
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 |
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* |
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* |
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* |
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* |
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* |
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* |
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* |
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 | |