1/*****************************************************************************
2
3Copyright (c) 1996, 2015, Oracle and/or its affiliates. All Rights Reserved.
4Copyright (c) 2017, 2018, MariaDB Corporation.
5
6This program is free software; you can redistribute it and/or modify it under
7the terms of the GNU General Public License as published by the Free Software
8Foundation; version 2 of the License.
9
10This program is distributed in the hope that it will be useful, but WITHOUT
11ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
12FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
13
14You should have received a copy of the GNU General Public License along with
15this program; if not, write to the Free Software Foundation, Inc.,
1651 Franklin Street, Suite 500, Boston, MA 02110-1335 USA
17
18*****************************************************************************/
19
20/**************************************************//**
21@file data/data0type.cc
22Data types
23
24Created 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" */
32const 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
38this MySQL installation to this global variable. If we have < 4.1.2 format
39column definitions, or records in the insert buffer, we use this
40charset-collation code for them. */
41
42ulint data_mysql_default_charset_coll;
43
44/*********************************************************************//**
45Determine how many bytes the first n characters of the given string occupy.
46If the string is shorter than n characters, returns the number of bytes
47the characters in the string occupy.
48@return length of the prefix, in bytes */
49ulint
50dtype_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/*********************************************************************//**
84Checks if a data main type is a string type. Also a BLOB is considered a
85string type.
86@return TRUE if string type */
87ibool
88dtype_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/*********************************************************************//**
103Checks 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
105those DATA_BLOB columns this function currently returns FALSE.
106@return TRUE if binary string type */
107ibool
108dtype_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/*********************************************************************//**
124Checks if a type is a non-binary string type. That is, dtype_is_string_type is
125TRUE and dtype_is_binary_string_type is FALSE. Note that for tables created
126with < 4.0.14, we do not know if a DATA_BLOB column is a BLOB or a TEXT column.
127For those DATA_BLOB columns this function currently returns TRUE.
128@return TRUE if non-binary string type */
129ibool
130dtype_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/*********************************************************************//**
145Validates a data type structure.
146@return TRUE if ok */
147ibool
148dtype_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 */
168void
169dtype_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