| 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 | |