1/*****************************************************************************
2
3Copyright (c) 1997, 2014, 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 include/eval0eval.ic
21SQL evaluator: evaluates simple data structures, like expressions, in
22a query graph
23
24Created 12/29/1997 Heikki Tuuri
25*******************************************************/
26
27#include "que0que.h"
28#include "rem0cmp.h"
29#include "pars0grm.h"
30
31/*****************************************************************//**
32Evaluates a function node. */
33void
34eval_func(
35/*======*/
36 func_node_t* func_node); /*!< in: function node */
37/*****************************************************************//**
38Allocate a buffer from global dynamic memory for a value of a que_node.
39NOTE that this memory must be explicitly freed when the query graph is
40freed. If the node already has allocated buffer, that buffer is freed
41here. NOTE that this is the only function where dynamic memory should be
42allocated for a query node val field.
43@return pointer to allocated buffer */
44byte*
45eval_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/*****************************************************************//**
54Allocates a new buffer if needed.
55@return pointer to buffer */
56UNIV_INLINE
57byte*
58eval_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/*****************************************************************//**
82Evaluates a symbol table symbol. */
83UNIV_INLINE
84void
85eval_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/*****************************************************************//**
102Evaluates an expression. */
103UNIV_INLINE
104void
105eval_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/*****************************************************************//**
120Sets an integer value as the value of an expression node. */
121UNIV_INLINE
122void
123eval_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/*****************************************************************//**
145Gets an integer non-SQL null value from an expression node.
146@return integer value */
147UNIV_INLINE
148lint
149eval_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/*****************************************************************//**
165Gets a iboolean value from a query node.
166@return iboolean value */
167UNIV_INLINE
168ibool
169eval_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/*****************************************************************//**
186Sets a iboolean value as the value of a function node. */
187UNIV_INLINE
188void
189eval_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/*****************************************************************//**
213Copies a binary string value as the value of a query graph node. Allocates a
214new buffer if necessary. */
215UNIV_INLINE
216void
217eval_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/*****************************************************************//**
237Copies a query node value to another node. */
238UNIV_INLINE
239void
240eval_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