1/*****************************************************************************
2
3Copyright (c) 1997, 2011, Oracle and/or its affiliates. All Rights Reserved.
4
5This program is free software; you can redistribute it and/or modify
6it under the terms of the GNU General Public License, version 2.0,
7as published by the Free Software Foundation.
8
9This program is also distributed with certain software (including
10but not limited to OpenSSL) that is licensed under separate terms,
11as designated in a particular file or component or in included license
12documentation.  The authors of MySQL hereby grant you an additional
13permission to link the program and your derivative works with the
14separately licensed software that they have included with MySQL.
15
16This program is distributed in the hope that it will be useful,
17but WITHOUT ANY WARRANTY; without even the implied warranty of
18MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19GNU General Public License, version 2.0, for more details.
20
21You should have received a copy of the GNU General Public License along with
22this program; if not, write to the Free Software Foundation, Inc.,
2351 Franklin Street, Suite 500, Boston, MA 02110-1335 USA
24
25*****************************************************************************/
26
27/**************************************************//**
28@file include/eval0eval.ic
29SQL evaluator: evaluates simple data structures, like expressions, in
30a query graph
31
32Created 12/29/1997 Heikki Tuuri
33*******************************************************/
34
35#include "que0que.h"
36#include "rem0cmp.h"
37#include "pars0grm.h"
38
39/*****************************************************************//**
40Evaluates a function node. */
41UNIV_INTERN
42void
43eval_func(
44/*======*/
45	func_node_t*	func_node);	/*!< in: function node */
46/*****************************************************************//**
47Allocate a buffer from global dynamic memory for a value of a que_node.
48NOTE that this memory must be explicitly freed when the query graph is
49freed. If the node already has allocated buffer, that buffer is freed
50here. NOTE that this is the only function where dynamic memory should be
51allocated for a query node val field.
52@return	pointer to allocated buffer */
53UNIV_INTERN
54byte*
55eval_node_alloc_val_buf(
56/*====================*/
57	que_node_t*	node,	/*!< in: query graph node; sets the val field
58				data field to point to the new buffer, and
59				len field equal to size */
60	ulint		size);	/*!< in: buffer size */
61
62
63/*****************************************************************//**
64Allocates a new buffer if needed.
65@return	pointer to buffer */
66UNIV_INLINE
67byte*
68eval_node_ensure_val_buf(
69/*=====================*/
70	que_node_t*	node,	/*!< in: query graph node; sets the val field
71				data field to point to the new buffer, and
72				len field equal to size */
73	ulint		size)	/*!< in: buffer size */
74{
75	dfield_t*	dfield;
76	byte*		data;
77
78	dfield = que_node_get_val(node);
79	dfield_set_len(dfield, size);
80
81	data = static_cast<byte*>(dfield_get_data(dfield));
82
83	if (!data || que_node_get_val_buf_size(node) < size) {
84
85		data = eval_node_alloc_val_buf(node, size);
86	}
87
88	return(data);
89}
90
91/*****************************************************************//**
92Evaluates a symbol table symbol. */
93UNIV_INLINE
94void
95eval_sym(
96/*=====*/
97	sym_node_t*	sym_node)	/*!< in: symbol table node */
98{
99
100	ut_ad(que_node_get_type(sym_node) == QUE_NODE_SYMBOL);
101
102	if (sym_node->indirection) {
103		/* The symbol table node is an alias for a variable or a
104		column */
105
106		dfield_copy_data(que_node_get_val(sym_node),
107				 que_node_get_val(sym_node->indirection));
108	}
109}
110
111/*****************************************************************//**
112Evaluates an expression. */
113UNIV_INLINE
114void
115eval_exp(
116/*=====*/
117	que_node_t*	exp_node)	/*!< in: expression */
118{
119	if (que_node_get_type(exp_node) == QUE_NODE_SYMBOL) {
120
121		eval_sym((sym_node_t*) exp_node);
122
123		return;
124	}
125
126	eval_func(static_cast<func_node_t*>(exp_node));
127}
128
129/*****************************************************************//**
130Sets an integer value as the value of an expression node. */
131UNIV_INLINE
132void
133eval_node_set_int_val(
134/*==================*/
135	que_node_t*	node,	/*!< in: expression node */
136	lint		val)	/*!< in: value to set */
137{
138	dfield_t*	dfield;
139	byte*		data;
140
141	dfield = que_node_get_val(node);
142
143	data = static_cast<byte*>(dfield_get_data(dfield));
144
145	if (data == NULL) {
146		data = eval_node_alloc_val_buf(node, 4);
147	}
148
149	ut_ad(dfield_get_len(dfield) == 4);
150
151	mach_write_to_4(data, (ulint) val);
152}
153
154/*****************************************************************//**
155Gets an integer non-SQL null value from an expression node.
156@return	integer value */
157UNIV_INLINE
158lint
159eval_node_get_int_val(
160/*==================*/
161	que_node_t*	node)	/*!< in: expression node */
162{
163	const byte*	ptr;
164	dfield_t*	dfield;
165
166	dfield = que_node_get_val(node);
167	ptr = static_cast<byte*>(dfield_get_data(dfield));
168
169	ut_ad(dfield_get_len(dfield) == 4);
170
171	return((int) mach_read_from_4(ptr));
172}
173
174/*****************************************************************//**
175Gets a iboolean value from a query node.
176@return	iboolean value */
177UNIV_INLINE
178ibool
179eval_node_get_ibool_val(
180/*====================*/
181	que_node_t*	node)	/*!< in: query graph node */
182{
183	dfield_t*	dfield;
184	byte*		data;
185
186	dfield = que_node_get_val(node);
187
188	data = static_cast<byte*>(dfield_get_data(dfield));
189
190	ut_ad(data != NULL);
191
192	return(mach_read_from_1(data));
193}
194
195/*****************************************************************//**
196Sets a iboolean value as the value of a function node. */
197UNIV_INLINE
198void
199eval_node_set_ibool_val(
200/*====================*/
201	func_node_t*	func_node,	/*!< in: function node */
202	ibool		val)		/*!< in: value to set */
203{
204	dfield_t*	dfield;
205	byte*		data;
206
207	dfield = que_node_get_val(func_node);
208
209	data = static_cast<byte*>(dfield_get_data(dfield));
210
211	if (data == NULL) {
212		/* Allocate 1 byte to hold the value */
213
214		data = eval_node_alloc_val_buf(func_node, 1);
215	}
216
217	ut_ad(dfield_get_len(dfield) == 1);
218
219	mach_write_to_1(data, val);
220}
221
222/*****************************************************************//**
223Copies a binary string value as the value of a query graph node. Allocates a
224new buffer if necessary. */
225UNIV_INLINE
226void
227eval_node_copy_and_alloc_val(
228/*=========================*/
229	que_node_t*	node,	/*!< in: query graph node */
230	const byte*	str,	/*!< in: binary string */
231	ulint		len)	/*!< in: string length or UNIV_SQL_NULL */
232{
233	byte*		data;
234
235	if (len == UNIV_SQL_NULL) {
236		dfield_set_len(que_node_get_val(node), len);
237
238		return;
239	}
240
241	data = eval_node_ensure_val_buf(node, len);
242
243	ut_memcpy(data, str, len);
244}
245
246/*****************************************************************//**
247Copies a query node value to another node. */
248UNIV_INLINE
249void
250eval_node_copy_val(
251/*===============*/
252	que_node_t*	node1,	/*!< in: node to copy to */
253	que_node_t*	node2)	/*!< in: node to copy from */
254{
255	dfield_t*	dfield2;
256
257	dfield2 = que_node_get_val(node2);
258
259	eval_node_copy_and_alloc_val(
260		node1,
261		static_cast<byte*>(dfield_get_data(dfield2)),
262		dfield_get_len(dfield2));
263}
264