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