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 537 538 539 540 541 542 543 544
|
/*****************************************************************************
Copyright (c) 1996, 2016, Oracle and/or its affiliates. All Rights Reserved.
Copyright (c) 2017, 2023, 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
*******************************************************/
#pragma once
#include "univ.i"
/** Special length indicating a missing instantly added column */
#define UNIV_SQL_DEFAULT (UNIV_SQL_NULL - 1)
/** @return whether a length is actually stored in a field */
#define len_is_stored(len) (len != UNIV_SQL_NULL && len != UNIV_SQL_DEFAULT)
#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 */
/** the size of a GIS maximum bounding rectangle */
constexpr uint8_t DATA_MBR_LEN= uint8_t(SPDIMS * 2 * sizeof(double));
#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 */
/** System Versioning */
#define DATA_VERS_START 16384U /* start system field */
#define DATA_VERS_END 32768U /* end system field */
/** system-versioned user data column */
#define DATA_VERSIONED (DATA_VERS_START|DATA_VERS_END)
/*-------------------------------------------*/
/* 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 */
/** @return whether main type is a string type */
inline bool dtype_is_string_type(ulint mtype)
{
return mtype <= DATA_BLOB
|| mtype == DATA_MYSQL || mtype == DATA_VARMYSQL;
}
/** @return whether a type is a binary string type */
inline bool dtype_is_binary_string_type(ulint mtype, ulint prtype)
{
/* Note that for tables created before MySQL 4.0.14,
we do not know if a DATA_BLOB column is a BLOB or a TEXT column.
For those DATA_BLOB columns we return false. */
return mtype == DATA_FIXBINARY || mtype == DATA_BINARY
|| (mtype == DATA_BLOB && (prtype & DATA_BINARY_TYPE));
}
/** @return whether a type is a non-binary string type */
inline bool dtype_is_non_binary_string_type(ulint mtype, ulint prtype)
{
return dtype_is_string_type(mtype)
&& !dtype_is_binary_string_type(mtype, prtype);
}
/*********************************************************************//**
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. */
void
dtype_get_mblen(
/*============*/
ulint mtype, /*!< in: main type */
ulint prtype, /*!< in: precise type (and collation) */
unsigned* mbminlen, /*!< out: minimum length of a
multi-byte character */
unsigned* mbmaxlen); /*!< out: maximum length of a
multi-byte character */
/**
Get the charset-collation code for string types.
@param prtype InnoDB precise type
@return charset-collation code */
inline uint16_t dtype_get_charset_coll(ulint prtype)
{
return static_cast<uint16_t>(prtype >> 16) & CHAR_COLL_MASK;
}
/** 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 */
inline uint32_t dtype_form_prtype(ulint old_prtype, ulint charset_coll)
{
ut_ad(old_prtype <= 0xffff);
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 whether a subset of UTF-8 */
UNIV_INLINE
bool
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
unsigned
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
unsigned
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 */
/*********************************************************************//**
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 */
struct dict_col_t;
/* 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()
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 */
/** @return whether this is system versioned user field */
bool is_versioned() const { return !(~prtype & DATA_VERSIONED); }
/** @return whether this is the system field start */
bool vers_sys_start() const
{
return (prtype & DATA_VERSIONED) == DATA_VERS_START;
}
/** @return whether this is the system field end */
bool vers_sys_end() const
{
return (prtype & DATA_VERSIONED) == DATA_VERS_END;
}
/** Set the type of the BLOB in the hidden metadata record. */
void metadata_blob_init()
{
prtype = DATA_NOT_NULL;
mtype = DATA_BLOB;
len = 0;
mbminlen = 0;
mbmaxlen = 0;
}
/** Copy the type information from a column.
@param col column type to be copied */
void assign(const dict_col_t &col);
};
/** The DB_TRX_ID,DB_ROLL_PTR values for "no history is available" */
extern const byte reset_trx_id[DATA_TRX_ID_LEN + DATA_ROLL_PTR_LEN];
/** Info bit denoting the predefined minimum record: this bit is set
if and only if the record is the first user record on a non-leaf
B-tree page that is the leftmost page on its level
(PAGE_LEVEL is nonzero and FIL_PAGE_PREV is FIL_NULL). */
#define REC_INFO_MIN_REC_FLAG 0x10UL
/** The delete-mark flag in info bits */
#define REC_INFO_DELETED_FLAG 0x20UL
/** Record status values for ROW_FORMAT=COMPACT,DYNAMIC,COMPRESSED */
enum rec_comp_status_t {
/** User record (PAGE_LEVEL=0, heap>=PAGE_HEAP_NO_USER_LOW) */
REC_STATUS_ORDINARY = 0,
/** Node pointer record (PAGE_LEVEL>=0, heap>=PAGE_HEAP_NO_USER_LOW) */
REC_STATUS_NODE_PTR = 1,
/** The page infimum pseudo-record (heap=PAGE_HEAP_NO_INFIMUM) */
REC_STATUS_INFIMUM = 2,
/** The page supremum pseudo-record (heap=PAGE_HEAP_NO_SUPREMUM) */
REC_STATUS_SUPREMUM = 3,
/** Clustered index record that has been inserted or updated
after instant ADD COLUMN (more than dict_index_t::n_core_fields) */
REC_STATUS_INSTANT = 4
};
/** The dtuple_t::info_bits of the hidden metadata of instant ADD COLUMN.
@see rec_is_metadata()
@see rec_is_alter_metadata() */
static const byte REC_INFO_METADATA_ADD
= REC_INFO_MIN_REC_FLAG | REC_STATUS_INSTANT;
/** The dtuple_t::info_bits of the hidden metadata of instant ALTER TABLE.
@see rec_is_metadata() */
static const byte REC_INFO_METADATA_ALTER
= REC_INFO_METADATA_ADD | REC_INFO_DELETED_FLAG;
#include "data0type.inl"
|