1 | /***************************************************************************** |
2 | |
3 | Copyright (c) 1997, 2014, 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 include/eval0eval.ic |
21 | SQL evaluator: evaluates simple data structures, like expressions, in |
22 | a query graph |
23 | |
24 | Created 12/29/1997 Heikki Tuuri |
25 | *******************************************************/ |
26 | |
27 | #include "que0que.h" |
28 | #include "rem0cmp.h" |
29 | #include "pars0grm.h" |
30 | |
31 | /*****************************************************************//** |
32 | Evaluates a function node. */ |
33 | void |
34 | eval_func( |
35 | /*======*/ |
36 | func_node_t* func_node); /*!< in: function node */ |
37 | /*****************************************************************//** |
38 | Allocate a buffer from global dynamic memory for a value of a que_node. |
39 | NOTE that this memory must be explicitly freed when the query graph is |
40 | freed. If the node already has allocated buffer, that buffer is freed |
41 | here. NOTE that this is the only function where dynamic memory should be |
42 | allocated for a query node val field. |
43 | @return pointer to allocated buffer */ |
44 | byte* |
45 | eval_node_alloc_val_buf( |
46 | /*====================*/ |
47 | que_node_t* node, /*!< in: query graph node; sets the val field |
48 | data field to point to the new buffer, and |
49 | len field equal to size */ |
50 | ulint size); /*!< in: buffer size */ |
51 | |
52 | |
53 | /*****************************************************************//** |
54 | Allocates a new buffer if needed. |
55 | @return pointer to buffer */ |
56 | UNIV_INLINE |
57 | byte* |
58 | eval_node_ensure_val_buf( |
59 | /*=====================*/ |
60 | que_node_t* node, /*!< in: query graph node; sets the val field |
61 | data field to point to the new buffer, and |
62 | len field equal to size */ |
63 | ulint size) /*!< in: buffer size */ |
64 | { |
65 | dfield_t* dfield; |
66 | byte* data; |
67 | |
68 | dfield = que_node_get_val(node); |
69 | dfield_set_len(dfield, size); |
70 | |
71 | data = static_cast<byte*>(dfield_get_data(dfield)); |
72 | |
73 | if (!data || que_node_get_val_buf_size(node) < size) { |
74 | |
75 | data = eval_node_alloc_val_buf(node, size); |
76 | } |
77 | |
78 | return(data); |
79 | } |
80 | |
81 | /*****************************************************************//** |
82 | Evaluates a symbol table symbol. */ |
83 | UNIV_INLINE |
84 | void |
85 | eval_sym( |
86 | /*=====*/ |
87 | sym_node_t* sym_node) /*!< in: symbol table node */ |
88 | { |
89 | |
90 | ut_ad(que_node_get_type(sym_node) == QUE_NODE_SYMBOL); |
91 | |
92 | if (sym_node->indirection) { |
93 | /* The symbol table node is an alias for a variable or a |
94 | column */ |
95 | |
96 | dfield_copy_data(que_node_get_val(sym_node), |
97 | que_node_get_val(sym_node->indirection)); |
98 | } |
99 | } |
100 | |
101 | /*****************************************************************//** |
102 | Evaluates an expression. */ |
103 | UNIV_INLINE |
104 | void |
105 | eval_exp( |
106 | /*=====*/ |
107 | que_node_t* exp_node) /*!< in: expression */ |
108 | { |
109 | if (que_node_get_type(exp_node) == QUE_NODE_SYMBOL) { |
110 | |
111 | eval_sym((sym_node_t*) exp_node); |
112 | |
113 | return; |
114 | } |
115 | |
116 | eval_func(static_cast<func_node_t*>(exp_node)); |
117 | } |
118 | |
119 | /*****************************************************************//** |
120 | Sets an integer value as the value of an expression node. */ |
121 | UNIV_INLINE |
122 | void |
123 | eval_node_set_int_val( |
124 | /*==================*/ |
125 | que_node_t* node, /*!< in: expression node */ |
126 | lint val) /*!< in: value to set */ |
127 | { |
128 | dfield_t* dfield; |
129 | byte* data; |
130 | |
131 | dfield = que_node_get_val(node); |
132 | |
133 | data = static_cast<byte*>(dfield_get_data(dfield)); |
134 | |
135 | if (data == NULL) { |
136 | data = eval_node_alloc_val_buf(node, 4); |
137 | } |
138 | |
139 | ut_ad(dfield_get_len(dfield) == 4); |
140 | |
141 | mach_write_to_4(data, (ulint) val); |
142 | } |
143 | |
144 | /*****************************************************************//** |
145 | Gets an integer non-SQL null value from an expression node. |
146 | @return integer value */ |
147 | UNIV_INLINE |
148 | lint |
149 | eval_node_get_int_val( |
150 | /*==================*/ |
151 | que_node_t* node) /*!< in: expression node */ |
152 | { |
153 | const byte* ptr; |
154 | dfield_t* dfield; |
155 | |
156 | dfield = que_node_get_val(node); |
157 | ptr = static_cast<byte*>(dfield_get_data(dfield)); |
158 | |
159 | ut_ad(dfield_get_len(dfield) == 4); |
160 | |
161 | return((int) mach_read_from_4(ptr)); |
162 | } |
163 | |
164 | /*****************************************************************//** |
165 | Gets a iboolean value from a query node. |
166 | @return iboolean value */ |
167 | UNIV_INLINE |
168 | ibool |
169 | eval_node_get_ibool_val( |
170 | /*====================*/ |
171 | que_node_t* node) /*!< in: query graph node */ |
172 | { |
173 | dfield_t* dfield; |
174 | byte* data; |
175 | |
176 | dfield = que_node_get_val(node); |
177 | |
178 | data = static_cast<byte*>(dfield_get_data(dfield)); |
179 | |
180 | ut_ad(data != NULL); |
181 | |
182 | return(mach_read_from_1(data)); |
183 | } |
184 | |
185 | /*****************************************************************//** |
186 | Sets a iboolean value as the value of a function node. */ |
187 | UNIV_INLINE |
188 | void |
189 | eval_node_set_ibool_val( |
190 | /*====================*/ |
191 | func_node_t* func_node, /*!< in: function node */ |
192 | ibool val) /*!< in: value to set */ |
193 | { |
194 | dfield_t* dfield; |
195 | byte* data; |
196 | |
197 | dfield = que_node_get_val(func_node); |
198 | |
199 | data = static_cast<byte*>(dfield_get_data(dfield)); |
200 | |
201 | if (data == NULL) { |
202 | /* Allocate 1 byte to hold the value */ |
203 | |
204 | data = eval_node_alloc_val_buf(func_node, 1); |
205 | } |
206 | |
207 | ut_ad(dfield_get_len(dfield) == 1); |
208 | |
209 | mach_write_to_1(data, val); |
210 | } |
211 | |
212 | /*****************************************************************//** |
213 | Copies a binary string value as the value of a query graph node. Allocates a |
214 | new buffer if necessary. */ |
215 | UNIV_INLINE |
216 | void |
217 | eval_node_copy_and_alloc_val( |
218 | /*=========================*/ |
219 | que_node_t* node, /*!< in: query graph node */ |
220 | const byte* str, /*!< in: binary string */ |
221 | ulint len) /*!< in: string length or UNIV_SQL_NULL */ |
222 | { |
223 | byte* data; |
224 | |
225 | if (len == UNIV_SQL_NULL) { |
226 | dfield_set_len(que_node_get_val(node), len); |
227 | |
228 | return; |
229 | } |
230 | |
231 | data = eval_node_ensure_val_buf(node, len); |
232 | |
233 | ut_memcpy(data, str, len); |
234 | } |
235 | |
236 | /*****************************************************************//** |
237 | Copies a query node value to another node. */ |
238 | UNIV_INLINE |
239 | void |
240 | eval_node_copy_val( |
241 | /*===============*/ |
242 | que_node_t* node1, /*!< in: node to copy to */ |
243 | que_node_t* node2) /*!< in: node to copy from */ |
244 | { |
245 | dfield_t* dfield2; |
246 | |
247 | dfield2 = que_node_get_val(node2); |
248 | |
249 | eval_node_copy_and_alloc_val( |
250 | node1, |
251 | static_cast<byte*>(dfield_get_data(dfield2)), |
252 | dfield_get_len(dfield2)); |
253 | } |
254 | |