1/***************************************************************************** 2 3Copyright (c) 1996, 2018, Oracle and/or its affiliates. All Rights Reserved. 4 5This program is free software; you can redistribute it and/or modify 6it under the terms of the GNU General Public License, version 2.0, 7as published by the Free Software Foundation. 8 9This program is also distributed with certain software (including 10but not limited to OpenSSL) that is licensed under separate terms, 11as designated in a particular file or component or in included license 12documentation. The authors of MySQL hereby grant you an additional 13permission to link the program and your derivative works with the 14separately licensed software that they have included with MySQL. 15 16This program is distributed in the hope that it will be useful, 17but WITHOUT ANY WARRANTY; without even the implied warranty of 18MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 19GNU General Public License, version 2.0, for more details. 20 21You should have received a copy of the GNU General Public License along with 22this program; if not, write to the Free Software Foundation, Inc., 2351 Franklin Street, Suite 500, Boston, MA 02110-1335 USA 24 25*****************************************************************************/ 26 27/**************************************************//** 28@file include/data0type.ic 29Data types 30 31Created 1/16/1996 Heikki Tuuri 32*******************************************************/ 33 34#include "mach0data.h" 35#ifndef UNIV_HOTBACKUP 36# include "ha_prototypes.h" 37 38/*********************************************************************//** 39Gets the MySQL charset-collation code for MySQL string types. 40@return MySQL charset-collation code */ 41UNIV_INLINE 42ulint 43dtype_get_charset_coll( 44/*===================*/ 45 ulint prtype) /*!< in: precise data type */ 46{ 47 return((prtype >> 16) & CHAR_COLL_MASK); 48} 49 50/*********************************************************************//** 51Determines if a MySQL string type is a subset of UTF-8. This function 52may return false negatives, in case further character-set collation 53codes are introduced in MySQL later. 54@return TRUE if a subset of UTF-8 */ 55UNIV_INLINE 56ibool 57dtype_is_utf8( 58/*==========*/ 59 ulint prtype) /*!< in: precise data type */ 60{ 61 /* These codes have been copied from strings/ctype-extra.c 62 and strings/ctype-utf8.c. */ 63 switch (dtype_get_charset_coll(prtype)) { 64 case 11: /* ascii_general_ci */ 65 case 65: /* ascii_bin */ 66 case 33: /* utf8_general_ci */ 67 case 83: /* utf8_bin */ 68 case 254: /* utf8_general_cs */ 69 return(TRUE); 70 } 71 72 return(FALSE); 73} 74 75/*********************************************************************//** 76Gets the MySQL type code from a dtype. 77@return MySQL type code; this is NOT an InnoDB type code! */ 78UNIV_INLINE 79ulint 80dtype_get_mysql_type( 81/*=================*/ 82 const dtype_t* type) /*!< in: type struct */ 83{ 84 return(type->prtype & 0xFFUL); 85} 86 87/*********************************************************************//** 88Compute the mbminlen and mbmaxlen members of a data type structure. */ 89UNIV_INLINE 90void 91dtype_get_mblen( 92/*============*/ 93 ulint mtype, /*!< in: main type */ 94 ulint prtype, /*!< in: precise type (and collation) */ 95 ulint* mbminlen, /*!< out: minimum length of a 96 multi-byte character */ 97 ulint* mbmaxlen) /*!< out: maximum length of a 98 multi-byte character */ 99{ 100 if (dtype_is_string_type(mtype)) { 101 innobase_get_cset_width(dtype_get_charset_coll(prtype), 102 mbminlen, mbmaxlen); 103 ut_ad(*mbminlen <= *mbmaxlen); 104 ut_ad(*mbminlen < DATA_MBMAX); 105 ut_ad(*mbmaxlen < DATA_MBMAX); 106 } else { 107 *mbminlen = *mbmaxlen = 0; 108 } 109} 110 111/*********************************************************************//** 112Sets the minimum and maximum length of a character, in bytes. */ 113UNIV_INLINE 114void 115dtype_set_mbminmaxlen( 116/*==================*/ 117 dtype_t* type, /*!< in/out: type */ 118 ulint mbminlen, /*!< in: minimum length of a char, 119 in bytes, or 0 if this is not 120 a character type */ 121 ulint mbmaxlen) /*!< in: maximum length of a char, 122 in bytes, or 0 if this is not 123 a character type */ 124{ 125 ut_ad(mbminlen < DATA_MBMAX); 126 ut_ad(mbmaxlen < DATA_MBMAX); 127 ut_ad(mbminlen <= mbmaxlen); 128 129 type->mbminmaxlen = DATA_MBMINMAXLEN(mbminlen, mbmaxlen); 130} 131 132/*********************************************************************//** 133Compute the mbminlen and mbmaxlen members of a data type structure. */ 134UNIV_INLINE 135void 136dtype_set_mblen( 137/*============*/ 138 dtype_t* type) /*!< in/out: type */ 139{ 140 ulint mbminlen; 141 ulint mbmaxlen; 142 143 dtype_get_mblen(type->mtype, type->prtype, &mbminlen, &mbmaxlen); 144 dtype_set_mbminmaxlen(type, mbminlen, mbmaxlen); 145 146 ut_ad(dtype_validate(type)); 147} 148#else /* !UNIV_HOTBACKUP */ 149# define dtype_set_mblen(type) (void) 0 150#endif /* !UNIV_HOTBACKUP */ 151 152/*********************************************************************//** 153Sets a data type structure. */ 154UNIV_INLINE 155void 156dtype_set( 157/*======*/ 158 dtype_t* type, /*!< in: type struct to init */ 159 ulint mtype, /*!< in: main data type */ 160 ulint prtype, /*!< in: precise type */ 161 ulint len) /*!< in: precision of type */ 162{ 163 ut_ad(type); 164 ut_ad(mtype <= DATA_MTYPE_MAX); 165 166 type->mtype = mtype; 167 type->prtype = prtype; 168 type->len = len; 169 170 dtype_set_mblen(type); 171} 172 173/*********************************************************************//** 174Copies a data type structure. */ 175UNIV_INLINE 176void 177dtype_copy( 178/*=======*/ 179 dtype_t* type1, /*!< in: type struct to copy to */ 180 const dtype_t* type2) /*!< in: type struct to copy from */ 181{ 182 *type1 = *type2; 183 184 ut_ad(dtype_validate(type1)); 185} 186 187/*********************************************************************//** 188Gets the SQL main data type. 189@return SQL main data type */ 190UNIV_INLINE 191ulint 192dtype_get_mtype( 193/*============*/ 194 const dtype_t* type) /*!< in: data type */ 195{ 196 ut_ad(type); 197 198 return(type->mtype); 199} 200 201/*********************************************************************//** 202Gets the precise data type. 203@return precise data type */ 204UNIV_INLINE 205ulint 206dtype_get_prtype( 207/*=============*/ 208 const dtype_t* type) /*!< in: data type */ 209{ 210 ut_ad(type); 211 212 return(type->prtype); 213} 214 215/*********************************************************************//** 216Gets the type length. 217@return fixed length of the type, in bytes, or 0 if variable-length */ 218UNIV_INLINE 219ulint 220dtype_get_len( 221/*==========*/ 222 const dtype_t* type) /*!< in: data type */ 223{ 224 ut_ad(type); 225 226 return(type->len); 227} 228 229#ifndef UNIV_HOTBACKUP 230/*********************************************************************//** 231Gets the minimum length of a character, in bytes. 232@return minimum length of a char, in bytes, or 0 if this is not a 233character type */ 234UNIV_INLINE 235ulint 236dtype_get_mbminlen( 237/*===============*/ 238 const dtype_t* type) /*!< in: type */ 239{ 240 ut_ad(type); 241 return(DATA_MBMINLEN(type->mbminmaxlen)); 242} 243/*********************************************************************//** 244Gets the maximum length of a character, in bytes. 245@return maximum length of a char, in bytes, or 0 if this is not a 246character type */ 247UNIV_INLINE 248ulint 249dtype_get_mbmaxlen( 250/*===============*/ 251 const dtype_t* type) /*!< in: type */ 252{ 253 ut_ad(type); 254 return(DATA_MBMAXLEN(type->mbminmaxlen)); 255} 256 257/**********************************************************************//** 258Stores for a type the information which determines its alphabetical ordering 259and the storage size of an SQL NULL value. This is the >= 4.1.x storage 260format. */ 261UNIV_INLINE 262void 263dtype_new_store_for_order_and_null_size( 264/*====================================*/ 265 byte* buf, /*!< in: buffer for 266 DATA_NEW_ORDER_NULL_TYPE_BUF_SIZE 267 bytes where we store the info */ 268 const dtype_t* type, /*!< in: type struct */ 269 ulint prefix_len)/*!< in: prefix length to 270 replace type->len, or 0 */ 271{ 272#if 6 != DATA_NEW_ORDER_NULL_TYPE_BUF_SIZE 273#error "6 != DATA_NEW_ORDER_NULL_TYPE_BUF_SIZE" 274#endif 275 ulint len; 276 277 ut_ad(type); 278 ut_ad(type->mtype >= DATA_VARCHAR); 279 ut_ad(type->mtype <= DATA_MTYPE_MAX); 280 281 buf[0] = (byte)(type->mtype & 0xFFUL); 282 283 if (type->prtype & DATA_BINARY_TYPE) { 284 buf[0] |= 128; 285 } 286 287 /* In versions < 4.1.2 we had: if (type->prtype & DATA_NONLATIN1) { 288 buf[0] |= 64; 289 } 290 */ 291 292 buf[1] = (byte)(type->prtype & 0xFFUL); 293 294 len = prefix_len ? prefix_len : type->len; 295 296 mach_write_to_2(buf + 2, len & 0xFFFFUL); 297 298 ut_ad(dtype_get_charset_coll(type->prtype) <= MAX_CHAR_COLL_NUM); 299 mach_write_to_2(buf + 4, dtype_get_charset_coll(type->prtype)); 300 301 if (type->prtype & DATA_NOT_NULL) { 302 buf[4] |= 128; 303 } 304} 305 306/**********************************************************************//** 307Reads to a type the stored information which determines its alphabetical 308ordering and the storage size of an SQL NULL value. This is the < 4.1.x 309storage format. */ 310UNIV_INLINE 311void 312dtype_read_for_order_and_null_size( 313/*===============================*/ 314 dtype_t* type, /*!< in: type struct */ 315 const byte* buf) /*!< in: buffer for stored type order info */ 316{ 317#if 4 != DATA_ORDER_NULL_TYPE_BUF_SIZE 318# error "4 != DATA_ORDER_NULL_TYPE_BUF_SIZE" 319#endif 320 321 type->mtype = buf[0] & 63; 322 type->prtype = buf[1]; 323 324 if (buf[0] & 128) { 325 type->prtype |= DATA_BINARY_TYPE; 326 } 327 328 type->len = mach_read_from_2(buf + 2); 329 330 type->prtype = dtype_form_prtype(type->prtype, 331 data_mysql_default_charset_coll); 332 dtype_set_mblen(type); 333} 334 335/**********************************************************************//** 336Reads to a type the stored information which determines its alphabetical 337ordering and the storage size of an SQL NULL value. This is the >= 4.1.x 338storage format. */ 339UNIV_INLINE 340void 341dtype_new_read_for_order_and_null_size( 342/*===================================*/ 343 dtype_t* type, /*!< in: type struct */ 344 const byte* buf) /*!< in: buffer for stored type order info */ 345{ 346 ulint charset_coll; 347 348#if 6 != DATA_NEW_ORDER_NULL_TYPE_BUF_SIZE 349#error "6 != DATA_NEW_ORDER_NULL_TYPE_BUF_SIZE" 350#endif 351 352 type->mtype = buf[0] & 63; 353 type->prtype = buf[1]; 354 355 if (buf[0] & 128) { 356 type->prtype |= DATA_BINARY_TYPE; 357 } 358 359 if (buf[4] & 128) { 360 type->prtype |= DATA_NOT_NULL; 361 } 362 363 type->len = mach_read_from_2(buf + 2); 364 365 charset_coll = mach_read_from_2(buf + 4) & CHAR_COLL_MASK; 366 367 if (dtype_is_string_type(type->mtype)) { 368 ut_a(charset_coll <= MAX_CHAR_COLL_NUM); 369 370 if (charset_coll == 0) { 371 /* This insert buffer record was inserted with MySQL 372 version < 4.1.2, and the charset-collation code was not 373 explicitly stored to dtype->prtype at that time. It 374 must be the default charset-collation of this MySQL 375 installation. */ 376 377 charset_coll = data_mysql_default_charset_coll; 378 } 379 380 type->prtype = dtype_form_prtype(type->prtype, charset_coll); 381 } 382 dtype_set_mblen(type); 383} 384 385/*********************************************************************//** 386Returns the type's SQL name (e.g. BIGINT UNSIGNED) from mtype,prtype,len 387@return the SQL type name */ 388UNIV_INLINE 389char* 390dtype_sql_name( 391/*===========*/ 392 unsigned mtype, /*!< in: mtype */ 393 unsigned prtype, /*!< in: prtype */ 394 unsigned len, /*!< in: len */ 395 char* name, /*!< out: SQL name */ 396 unsigned name_sz)/*!< in: size of the name buffer */ 397{ 398 399#define APPEND_UNSIGNED() \ 400 do { \ 401 if (prtype & DATA_UNSIGNED) { \ 402 ut_snprintf(name + strlen(name), \ 403 name_sz - strlen(name), \ 404 " UNSIGNED"); \ 405 } \ 406 } while (0) 407 408 ut_snprintf(name, name_sz, "UNKNOWN"); 409 410 switch (mtype) { 411 case DATA_INT: 412 switch (len) { 413 case 1: 414 ut_snprintf(name, name_sz, "TINYINT"); 415 break; 416 case 2: 417 ut_snprintf(name, name_sz, "SMALLINT"); 418 break; 419 case 3: 420 ut_snprintf(name, name_sz, "MEDIUMINT"); 421 break; 422 case 4: 423 ut_snprintf(name, name_sz, "INT"); 424 break; 425 case 8: 426 ut_snprintf(name, name_sz, "BIGINT"); 427 break; 428 } 429 APPEND_UNSIGNED(); 430 break; 431 case DATA_FLOAT: 432 ut_snprintf(name, name_sz, "FLOAT"); 433 APPEND_UNSIGNED(); 434 break; 435 case DATA_DOUBLE: 436 ut_snprintf(name, name_sz, "DOUBLE"); 437 APPEND_UNSIGNED(); 438 break; 439 case DATA_FIXBINARY: 440 ut_snprintf(name, name_sz, "BINARY(%u)", len); 441 break; 442 case DATA_CHAR: 443 case DATA_MYSQL: 444 ut_snprintf(name, name_sz, "CHAR(%u)", len); 445 break; 446 case DATA_VARCHAR: 447 case DATA_VARMYSQL: 448 ut_snprintf(name, name_sz, "VARCHAR(%u)", len); 449 break; 450 case DATA_BINARY: 451 ut_snprintf(name, name_sz, "VARBINARY(%u)", len); 452 break; 453 case DATA_GEOMETRY: 454 ut_snprintf(name, name_sz, "GEOMETRY"); 455 break; 456 case DATA_BLOB: 457 switch (len) { 458 case 9: 459 ut_snprintf(name, name_sz, "TINYBLOB"); 460 break; 461 case 10: 462 ut_snprintf(name, name_sz, "BLOB"); 463 break; 464 case 11: 465 ut_snprintf(name, name_sz, "MEDIUMBLOB"); 466 break; 467 case 12: 468 ut_snprintf(name, name_sz, "LONGBLOB"); 469 break; 470 } 471 } 472 473 if (prtype & DATA_NOT_NULL) { 474 ut_snprintf(name + strlen(name), 475 name_sz - strlen(name), 476 " NOT NULL"); 477 } 478 479 return(name); 480} 481 482#endif /* !UNIV_HOTBACKUP */ 483 484/***********************************************************************//** 485Returns the size of a fixed size data type, 0 if not a fixed size type. 486@return fixed size, or 0 */ 487UNIV_INLINE 488ulint 489dtype_get_fixed_size_low( 490/*=====================*/ 491 ulint mtype, /*!< in: main type */ 492 ulint prtype, /*!< in: precise type */ 493 ulint len, /*!< in: length */ 494 ulint mbminmaxlen, /*!< in: minimum and maximum length of 495 a multibyte character, in bytes */ 496 ulint comp) /*!< in: nonzero=ROW_FORMAT=COMPACT */ 497{ 498 switch (mtype) { 499 case DATA_SYS: 500#ifdef UNIV_DEBUG 501 switch (prtype & DATA_MYSQL_TYPE_MASK) { 502 case DATA_ROW_ID: 503 ut_ad(len == DATA_ROW_ID_LEN); 504 break; 505 case DATA_TRX_ID: 506 ut_ad(len == DATA_TRX_ID_LEN); 507 break; 508 case DATA_ROLL_PTR: 509 ut_ad(len == DATA_ROLL_PTR_LEN); 510 break; 511 default: 512 ut_ad(0); 513 return(0); 514 } 515#endif /* UNIV_DEBUG */ 516 // Fall through. 517 case DATA_CHAR: 518 case DATA_FIXBINARY: 519 case DATA_INT: 520 case DATA_FLOAT: 521 case DATA_DOUBLE: 522 case DATA_POINT: 523 return(len); 524 case DATA_MYSQL: 525#ifndef UNIV_HOTBACKUP 526 if (prtype & DATA_BINARY_TYPE) { 527 return(len); 528 } else if (!comp) { 529 return(len); 530 } else { 531#ifdef UNIV_DEBUG 532 ulint i_mbminlen, i_mbmaxlen; 533 534 innobase_get_cset_width( 535 dtype_get_charset_coll(prtype), 536 &i_mbminlen, &i_mbmaxlen); 537 538 ut_ad(DATA_MBMINMAXLEN(i_mbminlen, i_mbmaxlen) 539 == mbminmaxlen); 540#endif /* UNIV_DEBUG */ 541 if (DATA_MBMINLEN(mbminmaxlen) 542 == DATA_MBMAXLEN(mbminmaxlen)) { 543 return(len); 544 } 545 } 546#else /* !UNIV_HOTBACKUP */ 547 return(len); 548#endif /* !UNIV_HOTBACKUP */ 549 /* fall through for variable-length charsets */ 550 case DATA_VARCHAR: 551 case DATA_BINARY: 552 case DATA_DECIMAL: 553 case DATA_VARMYSQL: 554 case DATA_VAR_POINT: 555 case DATA_GEOMETRY: 556 case DATA_BLOB: 557 return(0); 558 default: 559 ut_error; 560 } 561 562 return(0); 563} 564 565#ifndef UNIV_HOTBACKUP 566/***********************************************************************//** 567Returns the minimum size of a data type. 568@return minimum size */ 569UNIV_INLINE 570ulint 571dtype_get_min_size_low( 572/*===================*/ 573 ulint mtype, /*!< in: main type */ 574 ulint prtype, /*!< in: precise type */ 575 ulint len, /*!< in: length */ 576 ulint mbminmaxlen) /*!< in: minimum and maximum length of a 577 multi-byte character */ 578{ 579 switch (mtype) { 580 case DATA_SYS: 581#ifdef UNIV_DEBUG 582 switch (prtype & DATA_MYSQL_TYPE_MASK) { 583 case DATA_ROW_ID: 584 ut_ad(len == DATA_ROW_ID_LEN); 585 break; 586 case DATA_TRX_ID: 587 ut_ad(len == DATA_TRX_ID_LEN); 588 break; 589 case DATA_ROLL_PTR: 590 ut_ad(len == DATA_ROLL_PTR_LEN); 591 break; 592 default: 593 ut_ad(0); 594 return(0); 595 } 596#endif /* UNIV_DEBUG */ 597 // Fall through. 598 case DATA_CHAR: 599 case DATA_FIXBINARY: 600 case DATA_INT: 601 case DATA_FLOAT: 602 case DATA_DOUBLE: 603 case DATA_POINT: 604 return(len); 605 case DATA_MYSQL: 606 if (prtype & DATA_BINARY_TYPE) { 607 return(len); 608 } else { 609 ulint mbminlen = DATA_MBMINLEN(mbminmaxlen); 610 ulint mbmaxlen = DATA_MBMAXLEN(mbminmaxlen); 611 612 if (mbminlen == mbmaxlen) { 613 return(len); 614 } 615 616 /* this is a variable-length character set */ 617 ut_a(mbminlen > 0); 618 ut_a(mbmaxlen > mbminlen); 619 ut_a(len % mbmaxlen == 0); 620 return(len * mbminlen / mbmaxlen); 621 } 622 case DATA_VARCHAR: 623 case DATA_BINARY: 624 case DATA_DECIMAL: 625 case DATA_VARMYSQL: 626 case DATA_VAR_POINT: 627 case DATA_GEOMETRY: 628 case DATA_BLOB: 629 return(0); 630 default: 631 ut_error; 632 } 633 634 return(0); 635} 636 637/***********************************************************************//** 638Returns the maximum size of a data type. Note: types in system tables may be 639incomplete and return incorrect information. 640@return maximum size */ 641UNIV_INLINE 642ulint 643dtype_get_max_size_low( 644/*===================*/ 645 ulint mtype, /*!< in: main type */ 646 ulint len) /*!< in: length */ 647{ 648 switch (mtype) { 649 case DATA_SYS: 650 case DATA_CHAR: 651 case DATA_FIXBINARY: 652 case DATA_INT: 653 case DATA_FLOAT: 654 case DATA_DOUBLE: 655 case DATA_MYSQL: 656 case DATA_VARCHAR: 657 case DATA_BINARY: 658 case DATA_DECIMAL: 659 case DATA_VARMYSQL: 660 case DATA_POINT: 661 return(len); 662 case DATA_VAR_POINT: 663 case DATA_GEOMETRY: 664 case DATA_BLOB: 665 break; 666 default: 667 ut_error; 668 } 669 670 return(ULINT_MAX); 671} 672#endif /* !UNIV_HOTBACKUP */ 673 674/***********************************************************************//** 675Returns the ROW_FORMAT=REDUNDANT stored SQL NULL size of a type. 676For fixed length types it is the fixed length of the type, otherwise 0. 677@return SQL null storage size in ROW_FORMAT=REDUNDANT */ 678UNIV_INLINE 679ulint 680dtype_get_sql_null_size( 681/*====================*/ 682 const dtype_t* type, /*!< in: type */ 683 ulint comp) /*!< in: nonzero=ROW_FORMAT=COMPACT */ 684{ 685#ifndef UNIV_HOTBACKUP 686 return(dtype_get_fixed_size_low(type->mtype, type->prtype, type->len, 687 type->mbminmaxlen, comp)); 688#else /* !UNIV_HOTBACKUP */ 689 return(dtype_get_fixed_size_low(type->mtype, type->prtype, type->len, 690 0, 0)); 691#endif /* !UNIV_HOTBACKUP */ 692} 693