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