summaryrefslogtreecommitdiff
path: root/storage/innobase/include/data0type.h
blob: f641af8a6c1d4618a8675a4a7fd6f33806884a9b (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
/*****************************************************************************

Copyright (c) 1996, 2016, Oracle and/or its affiliates. All Rights Reserved.
Copyright (c) 2017, 2019, MariaDB Corporation.

This program is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free Software
Foundation; version 2 of the License.

This program is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.

You should have received a copy of the GNU General Public License along with
this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1335 USA

*****************************************************************************/

/**************************************************//**
@file include/data0type.h
Data types

Created 1/16/1996 Heikki Tuuri
*******************************************************/

#ifndef data0type_h
#define data0type_h

#include "univ.i"

extern ulint	data_mysql_default_charset_coll;
#define DATA_MYSQL_BINARY_CHARSET_COLL 63

/* SQL data type struct */
struct dtype_t;

/** SQL Like operator comparison types */
enum ib_like_t {
	IB_LIKE_EXACT,	/**< e.g.  STRING */
	IB_LIKE_PREFIX	/**< e.g., STRING% */
};

/*-------------------------------------------*/
/* The 'MAIN TYPE' of a column */
#define DATA_MISSING	0	/* missing column */
#define	DATA_VARCHAR	1	/* character varying of the
				latin1_swedish_ci charset-collation; note
				that the MySQL format for this, DATA_BINARY,
				DATA_VARMYSQL, is also affected by whether the
				'precise type' contains
				DATA_MYSQL_TRUE_VARCHAR */
#define DATA_CHAR	2	/* fixed length character of the
				latin1_swedish_ci charset-collation */
#define DATA_FIXBINARY	3	/* binary string of fixed length */
#define DATA_BINARY	4	/* binary string */
#define DATA_BLOB	5	/* binary large object, or a TEXT type;
				if prtype & DATA_BINARY_TYPE == 0, then this is
				actually a TEXT column (or a BLOB created
				with < 4.0.14; since column prefix indexes
				came only in 4.0.14, the missing flag in BLOBs
				created before that does not cause any harm) */
#define	DATA_INT	6	/* integer: can be any size 1 - 8 bytes */
#define	DATA_SYS_CHILD	7	/* address of the child page in node pointer */
#define	DATA_SYS	8	/* system column */

/* Data types >= DATA_FLOAT must be compared using the whole field, not as
binary strings */

#define DATA_FLOAT	9
#define DATA_DOUBLE	10
#define DATA_DECIMAL	11	/* decimal number stored as an ASCII string */
#define	DATA_VARMYSQL	12	/* any charset varying length char */
#define	DATA_MYSQL	13	/* any charset fixed length char */
				/* NOTE that 4.1.1 used DATA_MYSQL and
				DATA_VARMYSQL for all character sets, and the
				charset-collation for tables created with it
				can also be latin1_swedish_ci */

/* DATA_GEOMETRY includes all standard geometry datatypes as described in
OGC standard(point, line_string, polygon, multi_point, multi_polygon,
multi_line_string, geometry_collection, geometry).
Currently, geometry data is stored in the standard Well-Known Binary(WKB)
format (http://www.opengeospatial.org/standards/sfa).
We use BLOB as the underlying datatype. */
#define DATA_GEOMETRY	14	/* geometry datatype of variable length */
#define DATA_MTYPE_MAX	63	/* dtype_store_for_order_and_null_size()
				requires the values are <= 63 */

#define DATA_MTYPE_CURRENT_MIN	DATA_VARCHAR	/* minimum value of mtype */
#define DATA_MTYPE_CURRENT_MAX	DATA_GEOMETRY	/* maximum value of mtype */
/*-------------------------------------------*/
/* The 'PRECISE TYPE' of a column */
/*
Tables created by a MySQL user have the following convention:

- In the least significant byte in the precise type we store the MySQL type
code (not applicable for system columns).

- In the second least significant byte we OR flags DATA_NOT_NULL,
DATA_UNSIGNED, DATA_BINARY_TYPE.

- In the third least significant byte of the precise type of string types we
store the MySQL charset-collation code. In DATA_BLOB columns created with
< 4.0.14 we do not actually know if it is a BLOB or a TEXT column. Since there
are no indexes on prefixes of BLOB or TEXT columns in < 4.0.14, this is no
problem, though.

Note that versions < 4.1.2 or < 5.0.1 did not store the charset code to the
precise type, since the charset was always the default charset of the MySQL
installation. If the stored charset code is 0 in the system table SYS_COLUMNS
of InnoDB, that means that the default charset of this MySQL installation
should be used.

When loading a table definition from the system tables to the InnoDB data
dictionary cache in main memory, InnoDB versions >= 4.1.2 and >= 5.0.1 check
if the stored charset-collation is 0, and if that is the case and the type is
a non-binary string, replace that 0 by the default charset-collation code of
this MySQL installation. In short, in old tables, the charset-collation code
in the system tables on disk can be 0, but in in-memory data structures
(dtype_t), the charset-collation code is always != 0 for non-binary string
types.

In new tables, in binary string types, the charset-collation code is the
MySQL code for the 'binary charset', that is, != 0.

For binary string types and for DATA_CHAR, DATA_VARCHAR, and for those
DATA_BLOB which are binary or have the charset-collation latin1_swedish_ci,
InnoDB performs all comparisons internally, without resorting to the MySQL
comparison functions. This is to save CPU time.

InnoDB's own internal system tables have different precise types for their
columns, and for them the precise type is usually not used at all.
*/

#define DATA_ENGLISH	4	/* English language character string: this
				is a relic from pre-MySQL time and only used
				for InnoDB's own system tables */
#define DATA_ERROR	111	/* another relic from pre-MySQL time */

#define DATA_MYSQL_TYPE_MASK 255U/* AND with this mask to extract the MySQL
				 type from the precise type */
#define DATA_MYSQL_TRUE_VARCHAR 15 /* MySQL type code for the >= 5.0.3
				   format true VARCHAR */

/* Precise data types for system columns and the length of those columns;
NOTE: the values must run from 0 up in the order given! All codes must
be less than 256 */
#define	DATA_ROW_ID	0	/* row id: a 48-bit integer */
#define DATA_ROW_ID_LEN	6	/* stored length for row id */

#define DATA_TRX_ID	1	/* transaction id: 6 bytes */
#define DATA_TRX_ID_LEN	6

#define	DATA_ROLL_PTR	2	/* rollback data pointer: 7 bytes */
#define DATA_ROLL_PTR_LEN 7

#define	DATA_N_SYS_COLS 3	/* number of system columns defined above */

#define DATA_FTS_DOC_ID	3	/* Used as FTS DOC ID column */

#define DATA_SYS_PRTYPE_MASK 0xFU /* mask to extract the above from prtype */

/* Flags ORed to the precise data type */
#define DATA_NOT_NULL	256U	/* this is ORed to the precise type when
				the column is declared as NOT NULL */
#define DATA_UNSIGNED	512U	/* this id ORed to the precise type when
				we have an unsigned integer type */
#define	DATA_BINARY_TYPE 1024U	/* if the data type is a binary character
				string, this is ORed to the precise type:
				this only holds for tables created with
				>= MySQL-4.0.14 */
/* #define	DATA_NONLATIN1	2048 This is a relic from < 4.1.2 and < 5.0.1.
				In earlier versions this was set for some
				BLOB columns.
*/
#define DATA_GIS_MBR	2048U	/* Used as GIS MBR column */
#define DATA_MBR_LEN	SPDIMS * 2 * sizeof(double) /* GIS MBR length*/

#define	DATA_LONG_TRUE_VARCHAR 4096U	/* this is ORed to the precise data
				type when the column is true VARCHAR where
				MySQL uses 2 bytes to store the data len;
				for shorter VARCHARs MySQL uses only 1 byte */
#define	DATA_VIRTUAL	8192U	/* Virtual column */

/** Check whether locking is disabled (never). */
#define dict_table_is_locking_disabled(table) false

/*-------------------------------------------*/

/* This many bytes we need to store the type information affecting the
alphabetical order for a single field and decide the storage size of an
SQL null*/
#define DATA_ORDER_NULL_TYPE_BUF_SIZE		4
/* In the >= 4.1.x storage format we add 2 bytes more so that we can also
store the charset-collation number; one byte is left unused, though */
#define DATA_NEW_ORDER_NULL_TYPE_BUF_SIZE	6

/* Maximum multi-byte character length in bytes, plus 1 */
#define DATA_MBMAX	8

/* For checking if mtype is GEOMETRY datatype */
#define DATA_GEOMETRY_MTYPE(mtype)	((mtype) == DATA_GEOMETRY)

/* For checking if mtype is BLOB or GEOMETRY, since we use BLOB as
the underlying datatype of GEOMETRY data. */
#define DATA_LARGE_MTYPE(mtype) ((mtype) == DATA_BLOB			\
				 || (mtype) == DATA_GEOMETRY)

/* For checking if data type is big length data type. */
#define DATA_BIG_LEN_MTYPE(len, mtype) ((len) > 255 || DATA_LARGE_MTYPE(mtype))

/* For checking if the column is a big length column. */
#define DATA_BIG_COL(col) DATA_BIG_LEN_MTYPE((col)->len, (col)->mtype)

/* For checking if data type is large binary data type. */
#define DATA_LARGE_BINARY(mtype,prtype) ((mtype) == DATA_GEOMETRY || \
	((mtype) == DATA_BLOB && !((prtype) & DATA_BINARY_TYPE)))

/* We now support 15 bits (up to 32767) collation number */
#define MAX_CHAR_COLL_NUM	32767

/* Mask to get the Charset Collation number (0x7fff) */
#define CHAR_COLL_MASK		MAX_CHAR_COLL_NUM

/*********************************************************************//**
Gets the MySQL type code from a dtype.
@return MySQL type code; this is NOT an InnoDB type code! */
UNIV_INLINE
ulint
dtype_get_mysql_type(
/*=================*/
	const dtype_t*	type);	/*!< in: type struct */
/*********************************************************************//**
Determine how many bytes the first n characters of the given string occupy.
If the string is shorter than n characters, returns the number of bytes
the characters in the string occupy.
@return length of the prefix, in bytes */
ulint
dtype_get_at_most_n_mbchars(
/*========================*/
	ulint		prtype,		/*!< in: precise type */
	ulint		mbminlen,	/*!< in: minimum length of
					a multi-byte character, in bytes */
	ulint		mbmaxlen,	/*!< in: maximum length of
					a multi-byte character, in bytes */
	ulint		prefix_len,	/*!< in: length of the requested
					prefix, in characters, multiplied by
					dtype_get_mbmaxlen(dtype) */
	ulint		data_len,	/*!< in: length of str (in bytes) */
	const char*	str);		/*!< in: the string whose prefix
					length is being determined */
/*********************************************************************//**
Checks if a data main type is a string type. Also a BLOB is considered a
string type.
@return TRUE if string type */
ibool
dtype_is_string_type(
/*=================*/
	ulint	mtype);	/*!< in: InnoDB main data type code: DATA_CHAR, ... */
/*********************************************************************//**
Checks if a type is a binary string type. Note that for tables created with
< 4.0.14, we do not know if a DATA_BLOB column is a BLOB or a TEXT column. For
those DATA_BLOB columns this function currently returns FALSE.
@return TRUE if binary string type */
ibool
dtype_is_binary_string_type(
/*========================*/
	ulint	mtype,	/*!< in: main data type */
	ulint	prtype);/*!< in: precise type */
/*********************************************************************//**
Checks if a type is a non-binary string type. That is, dtype_is_string_type is
TRUE and dtype_is_binary_string_type is FALSE. Note that for tables created
with < 4.0.14, we do not know if a DATA_BLOB column is a BLOB or a TEXT column.
For those DATA_BLOB columns this function currently returns TRUE.
@return TRUE if non-binary string type */
ibool
dtype_is_non_binary_string_type(
/*============================*/
	ulint	mtype,	/*!< in: main data type */
	ulint	prtype);/*!< in: precise type */
/*********************************************************************//**
Sets a data type structure. */
UNIV_INLINE
void
dtype_set(
/*======*/
	dtype_t*	type,	/*!< in: type struct to init */
	ulint		mtype,	/*!< in: main data type */
	ulint		prtype,	/*!< in: precise type */
	ulint		len);	/*!< in: precision of type */
/*********************************************************************//**
Copies a data type structure. */
UNIV_INLINE
void
dtype_copy(
/*=======*/
	dtype_t*	type1,	/*!< in: type struct to copy to */
	const dtype_t*	type2);	/*!< in: type struct to copy from */
/*********************************************************************//**
Gets the SQL main data type.
@return SQL main data type */
UNIV_INLINE
ulint
dtype_get_mtype(
/*============*/
	const dtype_t*	type);	/*!< in: data type */
/*********************************************************************//**
Gets the precise data type.
@return precise data type */
UNIV_INLINE
ulint
dtype_get_prtype(
/*=============*/
	const dtype_t*	type);	/*!< in: data type */

/*********************************************************************//**
Compute the mbminlen and mbmaxlen members of a data type structure. */
UNIV_INLINE
void
dtype_get_mblen(
/*============*/
	ulint	mtype,		/*!< in: main type */
	ulint	prtype,		/*!< in: precise type (and collation) */
	ulint*	mbminlen,	/*!< out: minimum length of a
				multi-byte character */
	ulint*	mbmaxlen);	/*!< out: maximum length of a
				multi-byte character */
/*********************************************************************//**
Gets the MySQL charset-collation code for MySQL string types.
@return MySQL charset-collation code */
UNIV_INLINE
ulint
dtype_get_charset_coll(
/*===================*/
	ulint	prtype);/*!< in: precise data type */
/** Form a precise type from the < 4.1.2 format precise type plus the
charset-collation code.
@param[in]	old_prtype	MySQL type code and the flags
				DATA_BINARY_TYPE etc.
@param[in]	charset_coll	character-set collation code
@return precise type, including the charset-collation code */
UNIV_INLINE
uint32_t
dtype_form_prtype(ulint old_prtype, ulint charset_coll)
{
	ut_ad(old_prtype < 256 * 256);
	ut_ad(charset_coll <= MAX_CHAR_COLL_NUM);
	return(uint32_t(old_prtype + (charset_coll << 16)));
}

/*********************************************************************//**
Determines if a MySQL string type is a subset of UTF-8.  This function
may return false negatives, in case further character-set collation
codes are introduced in MySQL later.
@return TRUE if a subset of UTF-8 */
UNIV_INLINE
ibool
dtype_is_utf8(
/*==========*/
	ulint	prtype);/*!< in: precise data type */
/*********************************************************************//**
Gets the type length.
@return fixed length of the type, in bytes, or 0 if variable-length */
UNIV_INLINE
ulint
dtype_get_len(
/*==========*/
	const dtype_t*	type);	/*!< in: data type */

/*********************************************************************//**
Gets the minimum length of a character, in bytes.
@return minimum length of a char, in bytes, or 0 if this is not a
character type */
UNIV_INLINE
ulint
dtype_get_mbminlen(
/*===============*/
	const dtype_t*	type);	/*!< in: type */
/*********************************************************************//**
Gets the maximum length of a character, in bytes.
@return maximum length of a char, in bytes, or 0 if this is not a
character type */
UNIV_INLINE
ulint
dtype_get_mbmaxlen(
/*===============*/
	const dtype_t*	type);	/*!< in: type */
/***********************************************************************//**
Returns the size of a fixed size data type, 0 if not a fixed size type.
@return fixed size, or 0 */
UNIV_INLINE
ulint
dtype_get_fixed_size_low(
/*=====================*/
	ulint	mtype,		/*!< in: main type */
	ulint	prtype,		/*!< in: precise type */
	ulint	len,		/*!< in: length */
	ulint	mbminlen,	/*!< in: minimum length of a
				multibyte character, in bytes */
	ulint	mbmaxlen,	/*!< in: maximum length of a
				multibyte character, in bytes */
	ulint	comp);		/*!< in: nonzero=ROW_FORMAT=COMPACT  */

/***********************************************************************//**
Returns the minimum size of a data type.
@return minimum size */
UNIV_INLINE
ulint
dtype_get_min_size_low(
/*===================*/
	ulint	mtype,		/*!< in: main type */
	ulint	prtype,		/*!< in: precise type */
	ulint	len,		/*!< in: length */
	ulint	mbminlen,	/*!< in: minimum length of a character */
	ulint	mbmaxlen);	/*!< in: maximum length of a character */
/***********************************************************************//**
Returns the maximum size of a data type. Note: types in system tables may be
incomplete and return incorrect information.
@return maximum size */
UNIV_INLINE
ulint
dtype_get_max_size_low(
/*===================*/
	ulint	mtype,		/*!< in: main type */
	ulint	len);		/*!< in: length */
/***********************************************************************//**
Returns the ROW_FORMAT=REDUNDANT stored SQL NULL size of a type.
For fixed length types it is the fixed length of the type, otherwise 0.
@return SQL null storage size in ROW_FORMAT=REDUNDANT */
UNIV_INLINE
ulint
dtype_get_sql_null_size(
/*====================*/
	const dtype_t*	type,	/*!< in: type */
	ulint		comp);	/*!< in: nonzero=ROW_FORMAT=COMPACT  */

/**********************************************************************//**
Reads to a type the stored information which determines its alphabetical
ordering and the storage size of an SQL NULL value. */
UNIV_INLINE
void
dtype_read_for_order_and_null_size(
/*===============================*/
	dtype_t*	type,	/*!< in: type struct */
	const byte*	buf);	/*!< in: buffer for the stored order info */
/**********************************************************************//**
Stores for a type the information which determines its alphabetical ordering
and the storage size of an SQL NULL value. This is the >= 4.1.x storage
format. */
UNIV_INLINE
void
dtype_new_store_for_order_and_null_size(
/*====================================*/
	byte*		buf,	/*!< in: buffer for
				DATA_NEW_ORDER_NULL_TYPE_BUF_SIZE
				bytes where we store the info */
	const dtype_t*	type,	/*!< in: type struct */
	ulint		prefix_len);/*!< in: prefix length to
				replace type->len, or 0 */
/**********************************************************************//**
Reads to a type the stored information which determines its alphabetical
ordering and the storage size of an SQL NULL value. This is the 4.1.x storage
format. */
UNIV_INLINE
void
dtype_new_read_for_order_and_null_size(
/*===================================*/
	dtype_t*	type,	/*!< in: type struct */
	const byte*	buf);	/*!< in: buffer for stored type order info */

/*********************************************************************//**
Returns the type's SQL name (e.g. BIGINT UNSIGNED) from mtype,prtype,len
@return the SQL type name */
UNIV_INLINE
char*
dtype_sql_name(
/*===========*/
	unsigned	mtype,	/*!< in: mtype */
	unsigned	prtype,	/*!< in: prtype */
	unsigned	len,	/*!< in: len */
	char*		name,	/*!< out: SQL name */
	unsigned	name_sz);/*!< in: size of the name buffer */

/*********************************************************************//**
Validates a data type structure.
@return TRUE if ok */
ibool
dtype_validate(
/*===========*/
	const dtype_t*	type);	/*!< in: type struct to validate */
#ifdef UNIV_DEBUG
/** Print a data type structure.
@param[in]	type	data type */
void
dtype_print(
	const dtype_t*	type);
#endif /* UNIV_DEBUG */

/* Structure for an SQL data type.
If you add fields to this structure, be sure to initialize them everywhere.
This structure is initialized in the following functions:
dtype_set()
dtype_read_for_order_and_null_size()
dtype_new_read_for_order_and_null_size()
sym_tab_add_null_lit() */

struct dtype_t{
	unsigned	prtype:32;	/*!< precise type; MySQL data
					type, charset code, flags to
					indicate nullability,
					signedness, whether this is a
					binary string, whether this is
					a true VARCHAR where MySQL
					uses 2 bytes to store the length */
	unsigned	mtype:8;	/*!< main data type */

	/* the remaining fields do not affect alphabetical ordering: */

	unsigned	len:16;		/*!< length; for MySQL data this
					is field->pack_length(),
					except that for a >= 5.0.3
					type true VARCHAR this is the
					maximum byte length of the
					string data (in addition to
					the string, MySQL uses 1 or 2
					bytes to store the string length) */
	unsigned	mbminlen:3;	/*!< minimum length of a character,
					in bytes */
	unsigned	mbmaxlen:3;	/*!< maximum length of a character,
					in bytes */
};

#include "data0type.ic"

#endif