1 | /***************************************************************************** |
2 | |
3 | Copyright (c) 1997, 2016, Oracle and/or its affiliates. All Rights Reserved. |
4 | Copyright (c) 2017, 2018, MariaDB Corporation. |
5 | |
6 | This program is free software; you can redistribute it and/or modify it under |
7 | the terms of the GNU General Public License as published by the Free Software |
8 | Foundation; version 2 of the License. |
9 | |
10 | This program is distributed in the hope that it will be useful, but WITHOUT |
11 | ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS |
12 | FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. |
13 | |
14 | You should have received a copy of the GNU General Public License along with |
15 | this program; if not, write to the Free Software Foundation, Inc., |
16 | 51 Franklin Street, Suite 500, Boston, MA 02110-1335 USA |
17 | |
18 | *****************************************************************************/ |
19 | |
20 | /**************************************************//** |
21 | @file include/pars0sym.h |
22 | SQL parser symbol table |
23 | |
24 | Created 12/15/1997 Heikki Tuuri |
25 | *******************************************************/ |
26 | |
27 | #ifndef pars0sym_h |
28 | #define pars0sym_h |
29 | |
30 | #include "univ.i" |
31 | #include "que0types.h" |
32 | #include "dict0types.h" |
33 | #include "pars0types.h" |
34 | #include "row0types.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 | Frees the memory allocated dynamically AFTER parsing phase for variables |
45 | etc. in the symbol table. Does not free the mem heap where the table was |
46 | originally created. Frees also SQL explicit cursor definitions. */ |
47 | void |
48 | sym_tab_free_private( |
49 | /*=================*/ |
50 | sym_tab_t* sym_tab); /*!< in, own: symbol table */ |
51 | /******************************************************************//** |
52 | Adds an integer literal to a symbol table. |
53 | @return symbol table node */ |
54 | sym_node_t* |
55 | sym_tab_add_int_lit( |
56 | /*================*/ |
57 | sym_tab_t* sym_tab, /*!< in: symbol table */ |
58 | ulint val); /*!< in: integer value */ |
59 | /******************************************************************//** |
60 | Adds an string literal to a symbol table. |
61 | @return symbol table node */ |
62 | sym_node_t* |
63 | sym_tab_add_str_lit( |
64 | /*================*/ |
65 | sym_tab_t* sym_tab, /*!< in: symbol table */ |
66 | const byte* str, /*!< in: string with no quotes around |
67 | it */ |
68 | ulint len); /*!< in: string length */ |
69 | /******************************************************************//** |
70 | Add a bound literal to a symbol table. |
71 | @return symbol table node */ |
72 | sym_node_t* |
73 | sym_tab_add_bound_lit( |
74 | /*==================*/ |
75 | sym_tab_t* sym_tab, /*!< in: symbol table */ |
76 | const char* name, /*!< in: name of bound literal */ |
77 | ulint* lit_type); /*!< out: type of literal (PARS_*_LIT) */ |
78 | /********************************************************************** |
79 | Rebind literal to a node in the symbol table. */ |
80 | sym_node_t* |
81 | sym_tab_rebind_lit( |
82 | /*===============*/ |
83 | /* out: symbol table node */ |
84 | sym_node_t* node, /* in: node that is bound to literal*/ |
85 | const void* address, /* in: pointer to data */ |
86 | ulint length); /* in: length of data */ |
87 | /******************************************************************//** |
88 | Adds an SQL null literal to a symbol table. |
89 | @return symbol table node */ |
90 | sym_node_t* |
91 | sym_tab_add_null_lit( |
92 | /*=================*/ |
93 | sym_tab_t* sym_tab); /*!< in: symbol table */ |
94 | /******************************************************************//** |
95 | Adds an identifier to a symbol table. |
96 | @return symbol table node */ |
97 | sym_node_t* |
98 | sym_tab_add_id( |
99 | /*===========*/ |
100 | sym_tab_t* sym_tab, /*!< in: symbol table */ |
101 | byte* name, /*!< in: identifier name */ |
102 | ulint len); /*!< in: identifier length */ |
103 | |
104 | /******************************************************************//** |
105 | Add a bound identifier to a symbol table. |
106 | @return symbol table node */ |
107 | sym_node_t* |
108 | sym_tab_add_bound_id( |
109 | /*===========*/ |
110 | sym_tab_t* sym_tab, /*!< in: symbol table */ |
111 | const char* name); /*!< in: name of bound id */ |
112 | |
113 | /** Index of sym_node_t::field_nos corresponding to the clustered index */ |
114 | #define SYM_CLUST_FIELD_NO 0 |
115 | /** Index of sym_node_t::field_nos corresponding to a secondary index */ |
116 | #define SYM_SEC_FIELD_NO 1 |
117 | |
118 | /** Types of a symbol table node */ |
119 | enum sym_tab_entry { |
120 | SYM_UNSET, /*!< Unset entry. */ |
121 | SYM_VAR = 91, /*!< declared parameter or local |
122 | variable of a procedure */ |
123 | SYM_IMPLICIT_VAR, /*!< storage for a intermediate result |
124 | of a calculation */ |
125 | SYM_LIT, /*!< literal */ |
126 | SYM_TABLE_REF_COUNTED, /*!< database table name, ref counted. Must |
127 | be closed explicitly. */ |
128 | SYM_TABLE, /*!< database table name */ |
129 | SYM_COLUMN, /*!< database table name */ |
130 | SYM_CURSOR, /*!< named cursor */ |
131 | SYM_PROCEDURE_NAME, /*!< stored procedure name */ |
132 | SYM_INDEX, /*!< database index name */ |
133 | SYM_FUNCTION /*!< user function name */ |
134 | }; |
135 | |
136 | /** Symbol table node */ |
137 | struct sym_node_t{ |
138 | que_common_t common; /*!< node type: |
139 | QUE_NODE_SYMBOL */ |
140 | /* NOTE: if the data field in 'common.val' is not NULL and the symbol |
141 | table node is not for a temporary column, the memory for the value has |
142 | been allocated from dynamic memory and it should be freed when the |
143 | symbol table is discarded */ |
144 | |
145 | /* 'alias' and 'indirection' are almost the same, but not quite. |
146 | 'alias' always points to the primary instance of the variable, while |
147 | 'indirection' does the same only if we should use the primary |
148 | instance's values for the node's data. This is usually the case, but |
149 | when initializing a cursor (e.g., "DECLARE CURSOR c IS SELECT * FROM |
150 | t WHERE id = x;"), we copy the values from the primary instance to |
151 | the cursor's instance so that they are fixed for the duration of the |
152 | cursor, and set 'indirection' to NULL. If we did not, the value of |
153 | 'x' could change between fetches and things would break horribly. |
154 | |
155 | TODO: It would be cleaner to make 'indirection' a boolean field and |
156 | always use 'alias' to refer to the primary node. */ |
157 | |
158 | sym_node_t* indirection; /*!< pointer to |
159 | another symbol table |
160 | node which contains |
161 | the value for this |
162 | node, NULL otherwise */ |
163 | sym_node_t* alias; /*!< pointer to |
164 | another symbol table |
165 | node for which this |
166 | node is an alias, |
167 | NULL otherwise */ |
168 | UT_LIST_NODE_T(sym_node_t) col_var_list; /*!< list of table |
169 | columns or a list of |
170 | input variables for an |
171 | explicit cursor */ |
172 | ibool copy_val; /*!< TRUE if a column |
173 | and its value should |
174 | be copied to dynamic |
175 | memory when fetched */ |
176 | ulint field_nos[2]; /*!< if a column, in |
177 | the position |
178 | SYM_CLUST_FIELD_NO is |
179 | the field number in the |
180 | clustered index; in |
181 | the position |
182 | SYM_SEC_FIELD_NO |
183 | the field number in the |
184 | non-clustered index to |
185 | use first; if not found |
186 | from the index, then |
187 | ULINT_UNDEFINED */ |
188 | ibool resolved; /*!< TRUE if the |
189 | meaning of a variable |
190 | or a column has been |
191 | resolved; for literals |
192 | this is always TRUE */ |
193 | enum sym_tab_entry token_type; /*!< type of the |
194 | parsed token */ |
195 | const char* name; /*!< name of an id */ |
196 | ulint name_len; /*!< id name length */ |
197 | dict_table_t* table; /*!< table definition |
198 | if a table id or a |
199 | column id */ |
200 | ulint col_no; /*!< column number if a |
201 | column */ |
202 | sel_buf_t* prefetch_buf; /*!< NULL, or a buffer |
203 | for cached column |
204 | values for prefetched |
205 | rows */ |
206 | sel_node_t* cursor_def; /*!< cursor definition |
207 | select node if a |
208 | named cursor */ |
209 | ulint param_type; /*!< PARS_INPUT, |
210 | PARS_OUTPUT, or |
211 | PARS_NOT_PARAM if not a |
212 | procedure parameter */ |
213 | sym_tab_t* sym_table; /*!< back pointer to |
214 | the symbol table */ |
215 | UT_LIST_NODE_T(sym_node_t) sym_list; /*!< list of symbol |
216 | nodes */ |
217 | sym_node_t* like_node; /* LIKE operator node*/ |
218 | }; |
219 | |
220 | /** Symbol table */ |
221 | struct sym_tab_t{ |
222 | que_t* query_graph; |
223 | /*!< query graph generated by the |
224 | parser */ |
225 | const char* sql_string; |
226 | /*!< SQL string to parse */ |
227 | size_t string_len; |
228 | /*!< SQL string length */ |
229 | int next_char_pos; |
230 | /*!< position of the next character in |
231 | sql_string to give to the lexical |
232 | analyzer */ |
233 | pars_info_t* info; /*!< extra information, or NULL */ |
234 | sym_node_list_t sym_list; |
235 | /*!< list of symbol nodes in the symbol |
236 | table */ |
237 | UT_LIST_BASE_NODE_T(func_node_t) |
238 | func_node_list; |
239 | /*!< list of function nodes in the |
240 | parsed query graph */ |
241 | mem_heap_t* heap; /*!< memory heap from which we can |
242 | allocate space */ |
243 | }; |
244 | |
245 | #endif |
246 | |