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