| 1 | /***************************************************************************** |
| 2 | |
| 3 | Copyright (c) 1996, 2015, Oracle and/or its affiliates. All Rights Reserved. |
| 4 | Copyright (c) 2017, 2018, MariaDB Corporation. |
| 5 | |
| 6 | This program is free software; you can redistribute it and/or modify it under |
| 7 | the terms of the GNU General Public License as published by the Free Software |
| 8 | Foundation; version 2 of the License. |
| 9 | |
| 10 | This program is distributed in the hope that it will be useful, but WITHOUT |
| 11 | ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS |
| 12 | FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. |
| 13 | |
| 14 | You should have received a copy of the GNU General Public License along with |
| 15 | this program; if not, write to the Free Software Foundation, Inc., |
| 16 | 51 Franklin Street, Suite 500, Boston, MA 02110-1335 USA |
| 17 | |
| 18 | *****************************************************************************/ |
| 19 | |
| 20 | /**************************************************//** |
| 21 | @file data/data0type.cc |
| 22 | Data types |
| 23 | |
| 24 | Created 1/16/1996 Heikki Tuuri |
| 25 | *******************************************************/ |
| 26 | |
| 27 | #include "ha_prototypes.h" |
| 28 | |
| 29 | #include "data0type.h" |
| 30 | |
| 31 | /** The DB_TRX_ID,DB_ROLL_PTR values for "no history is available" */ |
| 32 | const byte reset_trx_id[DATA_TRX_ID_LEN + DATA_ROLL_PTR_LEN] = { |
| 33 | 0, 0, 0, 0, 0, 0, |
| 34 | 0x80, 0, 0, 0, 0, 0, 0 |
| 35 | }; |
| 36 | |
| 37 | /* At the database startup we store the default-charset collation number of |
| 38 | this MySQL installation to this global variable. If we have < 4.1.2 format |
| 39 | column definitions, or records in the insert buffer, we use this |
| 40 | charset-collation code for them. */ |
| 41 | |
| 42 | ulint data_mysql_default_charset_coll; |
| 43 | |
| 44 | /*********************************************************************//** |
| 45 | Determine how many bytes the first n characters of the given string occupy. |
| 46 | If the string is shorter than n characters, returns the number of bytes |
| 47 | the characters in the string occupy. |
| 48 | @return length of the prefix, in bytes */ |
| 49 | ulint |
| 50 | dtype_get_at_most_n_mbchars( |
| 51 | /*========================*/ |
| 52 | ulint prtype, /*!< in: precise type */ |
| 53 | ulint mbminlen, /*!< in: minimum length of |
| 54 | a multi-byte character, in bytes */ |
| 55 | ulint mbmaxlen, /*!< in: maximum length of |
| 56 | a multi-byte character, in bytes */ |
| 57 | ulint prefix_len, /*!< in: length of the requested |
| 58 | prefix, in characters, multiplied by |
| 59 | dtype_get_mbmaxlen(dtype) */ |
| 60 | ulint data_len, /*!< in: length of str (in bytes) */ |
| 61 | const char* str) /*!< in: the string whose prefix |
| 62 | length is being determined */ |
| 63 | { |
| 64 | ut_a(len_is_stored(data_len)); |
| 65 | ut_ad(!mbmaxlen || !(prefix_len % mbmaxlen)); |
| 66 | |
| 67 | if (mbminlen != mbmaxlen) { |
| 68 | ut_a(!(prefix_len % mbmaxlen)); |
| 69 | return(innobase_get_at_most_n_mbchars( |
| 70 | dtype_get_charset_coll(prtype), |
| 71 | prefix_len, data_len, str)); |
| 72 | } |
| 73 | |
| 74 | if (prefix_len < data_len) { |
| 75 | |
| 76 | return(prefix_len); |
| 77 | |
| 78 | } |
| 79 | |
| 80 | return(data_len); |
| 81 | } |
| 82 | |
| 83 | /*********************************************************************//** |
| 84 | Checks if a data main type is a string type. Also a BLOB is considered a |
| 85 | string type. |
| 86 | @return TRUE if string type */ |
| 87 | ibool |
| 88 | dtype_is_string_type( |
| 89 | /*=================*/ |
| 90 | ulint mtype) /*!< in: InnoDB main data type code: DATA_CHAR, ... */ |
| 91 | { |
| 92 | if (mtype <= DATA_BLOB |
| 93 | || mtype == DATA_MYSQL |
| 94 | || mtype == DATA_VARMYSQL) { |
| 95 | |
| 96 | return(TRUE); |
| 97 | } |
| 98 | |
| 99 | return(FALSE); |
| 100 | } |
| 101 | |
| 102 | /*********************************************************************//** |
| 103 | Checks if a type is a binary string type. Note that for tables created with |
| 104 | < 4.0.14, we do not know if a DATA_BLOB column is a BLOB or a TEXT column. For |
| 105 | those DATA_BLOB columns this function currently returns FALSE. |
| 106 | @return TRUE if binary string type */ |
| 107 | ibool |
| 108 | dtype_is_binary_string_type( |
| 109 | /*========================*/ |
| 110 | ulint mtype, /*!< in: main data type */ |
| 111 | ulint prtype) /*!< in: precise type */ |
| 112 | { |
| 113 | if ((mtype == DATA_FIXBINARY) |
| 114 | || (mtype == DATA_BINARY) |
| 115 | || (mtype == DATA_BLOB && (prtype & DATA_BINARY_TYPE))) { |
| 116 | |
| 117 | return(TRUE); |
| 118 | } |
| 119 | |
| 120 | return(FALSE); |
| 121 | } |
| 122 | |
| 123 | /*********************************************************************//** |
| 124 | Checks if a type is a non-binary string type. That is, dtype_is_string_type is |
| 125 | TRUE and dtype_is_binary_string_type is FALSE. Note that for tables created |
| 126 | with < 4.0.14, we do not know if a DATA_BLOB column is a BLOB or a TEXT column. |
| 127 | For those DATA_BLOB columns this function currently returns TRUE. |
| 128 | @return TRUE if non-binary string type */ |
| 129 | ibool |
| 130 | dtype_is_non_binary_string_type( |
| 131 | /*============================*/ |
| 132 | ulint mtype, /*!< in: main data type */ |
| 133 | ulint prtype) /*!< in: precise type */ |
| 134 | { |
| 135 | if (dtype_is_string_type(mtype) == TRUE |
| 136 | && dtype_is_binary_string_type(mtype, prtype) == FALSE) { |
| 137 | |
| 138 | return(TRUE); |
| 139 | } |
| 140 | |
| 141 | return(FALSE); |
| 142 | } |
| 143 | |
| 144 | /*********************************************************************//** |
| 145 | Validates a data type structure. |
| 146 | @return TRUE if ok */ |
| 147 | ibool |
| 148 | dtype_validate( |
| 149 | /*===========*/ |
| 150 | const dtype_t* type) /*!< in: type struct to validate */ |
| 151 | { |
| 152 | ut_a(type); |
| 153 | ut_a(type->mtype >= DATA_VARCHAR); |
| 154 | ut_a(type->mtype <= DATA_MTYPE_MAX); |
| 155 | |
| 156 | if (type->mtype == DATA_SYS) { |
| 157 | ut_a((type->prtype & DATA_MYSQL_TYPE_MASK) < DATA_N_SYS_COLS); |
| 158 | } |
| 159 | |
| 160 | ut_a(dtype_get_mbminlen(type) <= dtype_get_mbmaxlen(type)); |
| 161 | |
| 162 | return(TRUE); |
| 163 | } |
| 164 | |
| 165 | #ifdef UNIV_DEBUG |
| 166 | /** Print a data type structure. |
| 167 | @param[in] type data type */ |
| 168 | void |
| 169 | dtype_print(const dtype_t* type) |
| 170 | { |
| 171 | ulint mtype; |
| 172 | ulint prtype; |
| 173 | ulint len; |
| 174 | |
| 175 | ut_a(type); |
| 176 | |
| 177 | mtype = type->mtype; |
| 178 | prtype = type->prtype; |
| 179 | |
| 180 | switch (mtype) { |
| 181 | case DATA_VARCHAR: |
| 182 | fputs("DATA_VARCHAR" , stderr); |
| 183 | break; |
| 184 | |
| 185 | case DATA_CHAR: |
| 186 | fputs("DATA_CHAR" , stderr); |
| 187 | break; |
| 188 | |
| 189 | case DATA_BINARY: |
| 190 | fputs("DATA_BINARY" , stderr); |
| 191 | break; |
| 192 | |
| 193 | case DATA_FIXBINARY: |
| 194 | fputs("DATA_FIXBINARY" , stderr); |
| 195 | break; |
| 196 | |
| 197 | case DATA_BLOB: |
| 198 | fputs("DATA_BLOB" , stderr); |
| 199 | break; |
| 200 | |
| 201 | case DATA_GEOMETRY: |
| 202 | fputs("DATA_GEOMETRY" , stderr); |
| 203 | break; |
| 204 | |
| 205 | case DATA_INT: |
| 206 | fputs("DATA_INT" , stderr); |
| 207 | break; |
| 208 | |
| 209 | case DATA_MYSQL: |
| 210 | fputs("DATA_MYSQL" , stderr); |
| 211 | break; |
| 212 | |
| 213 | case DATA_SYS: |
| 214 | fputs("DATA_SYS" , stderr); |
| 215 | break; |
| 216 | |
| 217 | case DATA_FLOAT: |
| 218 | fputs("DATA_FLOAT" , stderr); |
| 219 | break; |
| 220 | |
| 221 | case DATA_DOUBLE: |
| 222 | fputs("DATA_DOUBLE" , stderr); |
| 223 | break; |
| 224 | |
| 225 | case DATA_DECIMAL: |
| 226 | fputs("DATA_DECIMAL" , stderr); |
| 227 | break; |
| 228 | |
| 229 | case DATA_VARMYSQL: |
| 230 | fputs("DATA_VARMYSQL" , stderr); |
| 231 | break; |
| 232 | |
| 233 | default: |
| 234 | fprintf(stderr, "type %lu" , (ulong) mtype); |
| 235 | break; |
| 236 | } |
| 237 | |
| 238 | len = type->len; |
| 239 | |
| 240 | if ((type->mtype == DATA_SYS) |
| 241 | || (type->mtype == DATA_VARCHAR) |
| 242 | || (type->mtype == DATA_CHAR)) { |
| 243 | putc(' ', stderr); |
| 244 | if (prtype == DATA_ROW_ID) { |
| 245 | fputs("DATA_ROW_ID" , stderr); |
| 246 | len = DATA_ROW_ID_LEN; |
| 247 | } else if (prtype == DATA_ROLL_PTR) { |
| 248 | fputs("DATA_ROLL_PTR" , stderr); |
| 249 | len = DATA_ROLL_PTR_LEN; |
| 250 | } else if (prtype == DATA_TRX_ID) { |
| 251 | fputs("DATA_TRX_ID" , stderr); |
| 252 | len = DATA_TRX_ID_LEN; |
| 253 | } else if (prtype == DATA_ENGLISH) { |
| 254 | fputs("DATA_ENGLISH" , stderr); |
| 255 | } else { |
| 256 | fprintf(stderr, "prtype %lu" , (ulong) prtype); |
| 257 | } |
| 258 | } else { |
| 259 | if (prtype & DATA_UNSIGNED) { |
| 260 | fputs(" DATA_UNSIGNED" , stderr); |
| 261 | } |
| 262 | |
| 263 | if (prtype & DATA_BINARY_TYPE) { |
| 264 | fputs(" DATA_BINARY_TYPE" , stderr); |
| 265 | } |
| 266 | |
| 267 | if (prtype & DATA_NOT_NULL) { |
| 268 | fputs(" DATA_NOT_NULL" , stderr); |
| 269 | } |
| 270 | } |
| 271 | |
| 272 | fprintf(stderr, " len %lu" , (ulong) len); |
| 273 | } |
| 274 | #endif /* UNIV_DEBUG */ |
| 275 | |