1 /***************************************************************************** 2 3 Copyright (c) 1996, 2021, Oracle and/or its affiliates. 4 Copyright (c) 2012, Facebook Inc. 5 6 This program is free software; you can redistribute it and/or modify 7 it under the terms of the GNU General Public License, version 2.0, 8 as published by the Free Software Foundation. 9 10 This program is also distributed with certain software (including 11 but not limited to OpenSSL) that is licensed under separate terms, 12 as designated in a particular file or component or in included license 13 documentation. The authors of MySQL hereby grant you an additional 14 permission to link the program and your derivative works with the 15 separately licensed software that they have included with MySQL. 16 17 This program is distributed in the hope that it will be useful, 18 but WITHOUT ANY WARRANTY; without even the implied warranty of 19 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 20 GNU General Public License, version 2.0, for more details. 21 22 You should have received a copy of the GNU General Public License along with 23 this program; if not, write to the Free Software Foundation, Inc., 24 51 Franklin Street, Suite 500, Boston, MA 02110-1335 USA 25 26 *****************************************************************************/ 27 28 /**************************************************//** 29 @file include/dict0dict.h 30 Data dictionary system 31 32 Created 1/8/1996 Heikki Tuuri 33 *******************************************************/ 34 35 #ifndef dict0dict_h 36 #define dict0dict_h 37 38 #include "univ.i" 39 #include "data0data.h" 40 #include "data0type.h" 41 #include "dict0mem.h" 42 #include "dict0types.h" 43 #include "fsp0fsp.h" 44 #include "fsp0sysspace.h" 45 #include "hash0hash.h" 46 #include "mem0mem.h" 47 #include "rem0types.h" 48 #include "row0types.h" 49 #include "trx0types.h" 50 #include "trx0sys.h" 51 #include "ut0byte.h" 52 #include "ut0mem.h" 53 #include "ut0new.h" 54 #include "ut0rnd.h" 55 #include <deque> 56 57 #ifndef UNIV_HOTBACKUP 58 # include "sync0rw.h" 59 /********************************************************************//** 60 Get the database name length in a table name. 61 @return database name length */ 62 ulint 63 dict_get_db_name_len( 64 /*=================*/ 65 const char* name) /*!< in: table name in the form 66 dbname '/' tablename */ 67 MY_ATTRIBUTE((warn_unused_result)); 68 /*********************************************************************//** 69 Open a table from its database and table name, this is currently used by 70 foreign constraint parser to get the referenced table. 71 @return complete table name with database and table name, allocated from 72 heap memory passed in */ 73 char* 74 dict_get_referenced_table( 75 /*======================*/ 76 const char* name, /*!< in: foreign key table name */ 77 const char* database_name, /*!< in: table db name */ 78 ulint database_name_len,/*!< in: db name length */ 79 const char* table_name, /*!< in: table name */ 80 ulint table_name_len, /*!< in: table name length */ 81 dict_table_t** table, /*!< out: table object or NULL */ 82 mem_heap_t* heap); /*!< in: heap memory */ 83 /*********************************************************************//** 84 Frees a foreign key struct. */ 85 void 86 dict_foreign_free( 87 /*==============*/ 88 dict_foreign_t* foreign); /*!< in, own: foreign key struct */ 89 /*********************************************************************//** 90 Finds the highest [number] for foreign key constraints of the table. Looks 91 only at the >= 4.0.18-format id's, which are of the form 92 databasename/tablename_ibfk_[number]. 93 @return highest number, 0 if table has no new format foreign key constraints */ 94 ulint 95 dict_table_get_highest_foreign_id( 96 /*==============================*/ 97 dict_table_t* table); /*!< in: table in the dictionary 98 memory cache */ 99 /********************************************************************//** 100 Return the end of table name where we have removed dbname and '/'. 101 @return table name */ 102 const char* 103 dict_remove_db_name( 104 /*================*/ 105 const char* name) /*!< in: table name in the form 106 dbname '/' tablename */ 107 MY_ATTRIBUTE((warn_unused_result)); 108 109 /** Operation to perform when opening a table */ 110 enum dict_table_op_t { 111 /** Expect the tablespace to exist. */ 112 DICT_TABLE_OP_NORMAL = 0, 113 /** Drop any orphan indexes after an aborted online index creation */ 114 DICT_TABLE_OP_DROP_ORPHAN, 115 /** Silently load the tablespace if it does not exist, 116 and do not load the definitions of incomplete indexes. */ 117 DICT_TABLE_OP_LOAD_TABLESPACE 118 }; 119 120 /**********************************************************************//** 121 Returns a table object based on table id. 122 @return table, NULL if does not exist */ 123 dict_table_t* 124 dict_table_open_on_id( 125 /*==================*/ 126 table_id_t table_id, /*!< in: table id */ 127 ibool dict_locked, /*!< in: TRUE=data dictionary locked */ 128 dict_table_op_t table_op) /*!< in: operation to perform */ 129 MY_ATTRIBUTE((warn_unused_result)); 130 131 dict_table_t* 132 dict_table_open_on_index_id( 133 /*==================*/ 134 table_id_t table_id, /*!< in: table id */ 135 bool dict_locked) /*!< in: TRUE=data dictionary locked */ 136 __attribute__((warn_unused_result)); 137 /********************************************************************//** 138 Decrements the count of open handles to a table. */ 139 void 140 dict_table_close( 141 /*=============*/ 142 dict_table_t* table, /*!< in/out: table */ 143 ibool dict_locked, /*!< in: TRUE=data dictionary locked */ 144 ibool try_drop); /*!< in: TRUE=try to drop any orphan 145 indexes after an aborted online 146 index creation */ 147 /*********************************************************************//** 148 Closes the only open handle to a table and drops a table while assuring 149 that dict_sys->mutex is held the whole time. This assures that the table 150 is not evicted after the close when the count of open handles goes to zero. 151 Because dict_sys->mutex is held, we do not need to call 152 dict_table_prevent_eviction(). */ 153 void 154 dict_table_close_and_drop( 155 /*======================*/ 156 trx_t* trx, /*!< in: data dictionary transaction */ 157 dict_table_t* table); /*!< in/out: table */ 158 /**********************************************************************//** 159 Inits the data dictionary module. */ 160 void 161 dict_init(void); 162 163 /*********************************************************************//** 164 Gets the minimum number of bytes per character. 165 @return minimum multi-byte char size, in bytes */ 166 UNIV_INLINE 167 ulint 168 dict_col_get_mbminlen( 169 /*==================*/ 170 const dict_col_t* col) /*!< in: column */ 171 MY_ATTRIBUTE((warn_unused_result)); 172 /*********************************************************************//** 173 Gets the maximum number of bytes per character. 174 @return maximum multi-byte char size, in bytes */ 175 UNIV_INLINE 176 ulint 177 dict_col_get_mbmaxlen( 178 /*==================*/ 179 const dict_col_t* col) /*!< in: column */ 180 MY_ATTRIBUTE((warn_unused_result)); 181 /*********************************************************************//** 182 Sets the minimum and maximum number of bytes per character. */ 183 UNIV_INLINE 184 void 185 dict_col_set_mbminmaxlen( 186 /*=====================*/ 187 dict_col_t* col, /*!< in/out: column */ 188 ulint mbminlen, /*!< in: minimum multi-byte 189 character size, in bytes */ 190 ulint mbmaxlen); /*!< in: minimum multi-byte 191 character size, in bytes */ 192 193 /*********************************************************************//** 194 Gets the column data type. */ 195 UNIV_INLINE 196 void 197 dict_col_copy_type( 198 /*===============*/ 199 const dict_col_t* col, /*!< in: column */ 200 dtype_t* type); /*!< out: data type */ 201 202 /**********************************************************************//** 203 Determine bytes of column prefix to be stored in the undo log. Please 204 note if the table format is UNIV_FORMAT_A (< UNIV_FORMAT_B), no prefix 205 needs to be stored in the undo log. 206 @return bytes of column prefix to be stored in the undo log */ 207 UNIV_INLINE 208 ulint 209 dict_max_field_len_store_undo( 210 /*==========================*/ 211 dict_table_t* table, /*!< in: table */ 212 const dict_col_t* col) /*!< in: column which index prefix 213 is based on */ 214 MY_ATTRIBUTE((warn_unused_result)); 215 216 /** Determine maximum bytes of a virtual column need to be stored 217 in the undo log. 218 @param[in] table dict_table_t for the table 219 @param[in] col_no virtual column number 220 @return maximum bytes of virtual column to be stored in the undo log */ 221 UNIV_INLINE 222 ulint 223 dict_max_v_field_len_store_undo( 224 dict_table_t* table, 225 ulint col_no); 226 227 #endif /* !UNIV_HOTBACKUP */ 228 #ifdef UNIV_DEBUG 229 /*********************************************************************//** 230 Assert that a column and a data type match. 231 @return TRUE */ 232 UNIV_INLINE 233 ibool 234 dict_col_type_assert_equal( 235 /*=======================*/ 236 const dict_col_t* col, /*!< in: column */ 237 const dtype_t* type) /*!< in: data type */ 238 MY_ATTRIBUTE((warn_unused_result)); 239 #endif /* UNIV_DEBUG */ 240 #ifndef UNIV_HOTBACKUP 241 /***********************************************************************//** 242 Returns the minimum size of the column. 243 @return minimum size */ 244 UNIV_INLINE 245 ulint 246 dict_col_get_min_size( 247 /*==================*/ 248 const dict_col_t* col) /*!< in: column */ 249 MY_ATTRIBUTE((warn_unused_result)); 250 /***********************************************************************//** 251 Returns the maximum size of the column. 252 @return maximum size */ 253 UNIV_INLINE 254 ulint 255 dict_col_get_max_size( 256 /*==================*/ 257 const dict_col_t* col) /*!< in: column */ 258 MY_ATTRIBUTE((warn_unused_result)); 259 /***********************************************************************//** 260 Returns the size of a fixed size column, 0 if not a fixed size column. 261 @return fixed size, or 0 */ 262 UNIV_INLINE 263 ulint 264 dict_col_get_fixed_size( 265 /*====================*/ 266 const dict_col_t* col, /*!< in: column */ 267 ulint comp) /*!< in: nonzero=ROW_FORMAT=COMPACT */ 268 MY_ATTRIBUTE((warn_unused_result)); 269 /***********************************************************************//** 270 Returns the ROW_FORMAT=REDUNDANT stored SQL NULL size of a column. 271 For fixed length types it is the fixed length of the type, otherwise 0. 272 @return SQL null storage size in ROW_FORMAT=REDUNDANT */ 273 UNIV_INLINE 274 ulint 275 dict_col_get_sql_null_size( 276 /*=======================*/ 277 const dict_col_t* col, /*!< in: column */ 278 ulint comp) /*!< in: nonzero=ROW_FORMAT=COMPACT */ 279 MY_ATTRIBUTE((warn_unused_result)); 280 /*********************************************************************//** 281 Gets the column number. 282 @return col->ind, table column position (starting from 0) */ 283 UNIV_INLINE 284 ulint 285 dict_col_get_no( 286 /*============*/ 287 const dict_col_t* col) /*!< in: column */ 288 MY_ATTRIBUTE((warn_unused_result)); 289 /*********************************************************************//** 290 Gets the column position in the clustered index. */ 291 UNIV_INLINE 292 ulint 293 dict_col_get_clust_pos( 294 /*===================*/ 295 const dict_col_t* col, /*!< in: table column */ 296 const dict_index_t* clust_index) /*!< in: clustered index */ 297 MY_ATTRIBUTE((warn_unused_result)); 298 299 /** Gets the column position in the given index. 300 @param[in] col table column 301 @param[in] index index to be searched for column 302 @return position of column in the given index. */ 303 UNIV_INLINE 304 ulint 305 dict_col_get_index_pos( 306 const dict_col_t* col, 307 const dict_index_t* index) 308 MY_ATTRIBUTE((warn_unused_result)); 309 310 /****************************************************************//** 311 If the given column name is reserved for InnoDB system columns, return 312 TRUE. 313 @return TRUE if name is reserved */ 314 ibool 315 dict_col_name_is_reserved( 316 /*======================*/ 317 const char* name) /*!< in: column name */ 318 MY_ATTRIBUTE((warn_unused_result)); 319 /********************************************************************//** 320 Acquire the autoinc lock. */ 321 void 322 dict_table_autoinc_lock( 323 /*====================*/ 324 dict_table_t* table); /*!< in/out: table */ 325 326 /********************************************************************//** 327 Unconditionally set the autoinc counter. */ 328 void 329 dict_table_autoinc_initialize( 330 /*==========================*/ 331 dict_table_t* table, /*!< in/out: table */ 332 ib_uint64_t value); /*!< in: next value to assign to a row */ 333 334 /** Store autoinc value when the table is evicted. 335 @param[in] table table evicted */ 336 void 337 dict_table_autoinc_store( 338 const dict_table_t* table); 339 340 /** Restore autoinc value when the table is loaded. 341 @param[in] table table loaded */ 342 void 343 dict_table_autoinc_restore( 344 dict_table_t* table); 345 346 /********************************************************************//** 347 Reads the next autoinc value (== autoinc counter value), 0 if not yet 348 initialized. 349 @return value for a new row, or 0 */ 350 ib_uint64_t 351 dict_table_autoinc_read( 352 /*====================*/ 353 const dict_table_t* table) /*!< in: table */ 354 MY_ATTRIBUTE((warn_unused_result)); 355 /********************************************************************//** 356 Updates the autoinc counter if the value supplied is greater than the 357 current value. */ 358 void 359 dict_table_autoinc_update_if_greater( 360 /*=================================*/ 361 362 dict_table_t* table, /*!< in/out: table */ 363 ib_uint64_t value); /*!< in: value which was assigned to a row */ 364 /********************************************************************//** 365 Release the autoinc lock. */ 366 void 367 dict_table_autoinc_unlock( 368 /*======================*/ 369 dict_table_t* table); /*!< in/out: table */ 370 371 /** Acquire the analyze index lock. 372 @param[in] table table whose analyze_index latch to lock */ 373 void 374 dict_table_analyze_index_lock( 375 dict_table_t* table); 376 377 /** Release the analyze index lock. 378 @param[in] table table whose analyze_index latch to unlock */ 379 void 380 dict_table_analyze_index_unlock( 381 dict_table_t* table); 382 #endif /* !UNIV_HOTBACKUP */ 383 /**********************************************************************//** 384 Adds system columns to a table object. */ 385 void 386 dict_table_add_system_columns( 387 /*==========================*/ 388 dict_table_t* table, /*!< in/out: table */ 389 mem_heap_t* heap); /*!< in: temporary heap */ 390 #ifndef UNIV_HOTBACKUP 391 /** Mark if table has big rows. 392 @param[in,out] table table handler */ 393 void 394 dict_table_set_big_rows( 395 dict_table_t* table) 396 MY_ATTRIBUTE((nonnull)); 397 /**********************************************************************//** 398 Adds a table object to the dictionary cache. */ 399 void 400 dict_table_add_to_cache( 401 /*====================*/ 402 dict_table_t* table, /*!< in: table */ 403 ibool can_be_evicted, /*!< in: TRUE if can be evicted*/ 404 mem_heap_t* heap); /*!< in: temporary heap */ 405 406 /**********************************************************************//** 407 Removes a table object from the dictionary cache. */ 408 void 409 dict_table_remove_from_cache( 410 /*=========================*/ 411 dict_table_t* table); /*!< in, own: table */ 412 413 /**********************************************************************//** 414 Removes a table object from the dictionary cache. */ 415 void 416 dict_table_remove_from_cache_low( 417 /*=============================*/ 418 dict_table_t* table, /*!< in, own: table */ 419 ibool lru_evict); /*!< in: TRUE if table being evicted 420 to make room in the table LRU list */ 421 /**********************************************************************//** 422 Renames a table object. 423 @return TRUE if success */ 424 dberr_t 425 dict_table_rename_in_cache( 426 /*=======================*/ 427 dict_table_t* table, /*!< in/out: table */ 428 const char* new_name, /*!< in: new name */ 429 ibool rename_also_foreigns) 430 /*!< in: in ALTER TABLE we want 431 to preserve the original table name 432 in constraints which reference it */ 433 MY_ATTRIBUTE((warn_unused_result)); 434 435 /** Removes an index from the dictionary cache. 436 @param[in,out] table table whose index to remove 437 @param[in,out] index index to remove, this object is destroyed and must not 438 be accessed by the caller afterwards */ 439 void 440 dict_index_remove_from_cache( 441 dict_table_t* table, 442 dict_index_t* index); 443 444 /**********************************************************************//** 445 Change the id of a table object in the dictionary cache. This is used in 446 DISCARD TABLESPACE. */ 447 void 448 dict_table_change_id_in_cache( 449 /*==========================*/ 450 dict_table_t* table, /*!< in/out: table object already in cache */ 451 table_id_t new_id); /*!< in: new id to set */ 452 /**********************************************************************//** 453 Removes a foreign constraint struct from the dictionary cache. */ 454 void 455 dict_foreign_remove_from_cache( 456 /*===========================*/ 457 dict_foreign_t* foreign); /*!< in, own: foreign constraint */ 458 /**********************************************************************//** 459 Adds a foreign key constraint object to the dictionary cache. May free 460 the object if there already is an object with the same identifier in. 461 At least one of foreign table or referenced table must already be in 462 the dictionary cache! 463 @return DB_SUCCESS or error code */ 464 dberr_t 465 dict_foreign_add_to_cache( 466 /*======================*/ 467 dict_foreign_t* foreign, 468 /*!< in, own: foreign key constraint */ 469 const char** col_names, 470 /*!< in: column names, or NULL to use 471 foreign->foreign_table->col_names */ 472 bool check_charsets, 473 /*!< in: whether to check charset 474 compatibility */ 475 dict_err_ignore_t ignore_err) 476 /*!< in: error to be ignored */ 477 MY_ATTRIBUTE((warn_unused_result)); 478 /*********************************************************************//** 479 Checks if a table is referenced by foreign keys. 480 @return TRUE if table is referenced by a foreign key */ 481 ibool 482 dict_table_is_referenced_by_foreign_key( 483 /*====================================*/ 484 const dict_table_t* table) /*!< in: InnoDB table */ 485 MY_ATTRIBUTE((warn_unused_result)); 486 /**********************************************************************//** 487 Replace the index passed in with another equivalent index in the 488 foreign key lists of the table. 489 @return whether all replacements were found */ 490 bool 491 dict_foreign_replace_index( 492 /*=======================*/ 493 dict_table_t* table, /*!< in/out: table */ 494 const char** col_names, 495 /*!< in: column names, or NULL 496 to use table->col_names */ 497 const dict_index_t* index) /*!< in: index to be replaced */ 498 MY_ATTRIBUTE((warn_unused_result)); 499 /**********************************************************************//** 500 Determines whether a string starts with the specified keyword. 501 @return TRUE if str starts with keyword */ 502 ibool 503 dict_str_starts_with_keyword( 504 /*=========================*/ 505 THD* thd, /*!< in: MySQL thread handle */ 506 const char* str, /*!< in: string to scan for keyword */ 507 const char* keyword) /*!< in: keyword to look for */ 508 MY_ATTRIBUTE((warn_unused_result)); 509 /** Scans a table create SQL string and adds to the data dictionary 510 the foreign key constraints declared in the string. This function 511 should be called after the indexes for a table have been created. 512 Each foreign key constraint must be accompanied with indexes in 513 bot participating tables. The indexes are allowed to contain more 514 fields than mentioned in the constraint. 515 516 @param[in] trx transaction 517 @param[in] sql_string table create statement where 518 foreign keys are declared like: 519 FOREIGN KEY (a, b) REFERENCES table2(c, d), 520 table2 can be written also with the database 521 name before it: test.table2; the default 522 database id the database of parameter name 523 @param[in] sql_length length of sql_string 524 @param[in] name table full name in normalized form 525 @param[in] reject_fks if TRUE, fail with error code 526 DB_CANNOT_ADD_CONSTRAINT if any 527 foreign keys are found. 528 @return error code or DB_SUCCESS */ 529 dberr_t 530 dict_create_foreign_constraints( 531 trx_t* trx, 532 const char* sql_string, 533 size_t sql_length, 534 const char* name, 535 ibool reject_fks) 536 MY_ATTRIBUTE((warn_unused_result)); 537 /**********************************************************************//** 538 Parses the CONSTRAINT id's to be dropped in an ALTER TABLE statement. 539 @return DB_SUCCESS or DB_CANNOT_DROP_CONSTRAINT if syntax error or the 540 constraint id does not match */ 541 dberr_t 542 dict_foreign_parse_drop_constraints( 543 /*================================*/ 544 mem_heap_t* heap, /*!< in: heap from which we can 545 allocate memory */ 546 trx_t* trx, /*!< in: transaction */ 547 dict_table_t* table, /*!< in: table */ 548 ulint* n, /*!< out: number of constraints 549 to drop */ 550 const char*** constraints_to_drop) /*!< out: id's of the 551 constraints to drop */ 552 MY_ATTRIBUTE((warn_unused_result)); 553 /**********************************************************************//** 554 Returns a table object and increments its open handle count. 555 NOTE! This is a high-level function to be used mainly from outside the 556 'dict' directory. Inside this directory dict_table_get_low 557 is usually the appropriate function. 558 @param[in] table_name Table name 559 @param[in] dict_locked TRUE=data dictionary locked 560 @param[in] try_drop TRUE=try to drop any orphan indexes after 561 an aborted online index creation 562 @param[in] ignore_err error to be ignored when loading the table 563 @return table, NULL if does not exist */ 564 dict_table_t* 565 dict_table_open_on_name( 566 const char* table_name, 567 ibool dict_locked, 568 ibool try_drop, 569 dict_err_ignore_t ignore_err) 570 MY_ATTRIBUTE((warn_unused_result)); 571 572 /*********************************************************************//** 573 Tries to find an index whose first fields are the columns in the array, 574 in the same order and is not marked for deletion and is not the same 575 as types_idx. 576 @return matching index, NULL if not found */ 577 dict_index_t* 578 dict_foreign_find_index( 579 /*====================*/ 580 const dict_table_t* table, /*!< in: table */ 581 const char** col_names, 582 /*!< in: column names, or NULL 583 to use table->col_names */ 584 const char** columns,/*!< in: array of column names */ 585 ulint n_cols, /*!< in: number of columns */ 586 const dict_index_t* types_idx, 587 /*!< in: NULL or an index 588 whose types the column types 589 must match */ 590 bool check_charsets, 591 /*!< in: whether to check 592 charsets. only has an effect 593 if types_idx != NULL */ 594 ulint check_null) 595 /*!< in: nonzero if none of 596 the columns must be declared 597 NOT NULL */ 598 MY_ATTRIBUTE((warn_unused_result)); 599 /**********************************************************************//** 600 Returns a column's name. 601 @return column name. NOTE: not guaranteed to stay valid if table is 602 modified in any way (columns added, etc.). */ 603 const char* 604 dict_table_get_col_name( 605 /*====================*/ 606 const dict_table_t* table, /*!< in: table */ 607 ulint col_nr) /*!< in: column number */ 608 MY_ATTRIBUTE((warn_unused_result)); 609 610 /** Returns a virtual column's name. 611 @param[in] table table object 612 @param[in] col_nr virtual column number(nth virtual column) 613 @return column name. */ 614 const char* 615 dict_table_get_v_col_name( 616 const dict_table_t* table, 617 ulint col_nr); 618 619 /** Check if the table has a given column. 620 @param[in] table table object 621 @param[in] col_name column name 622 @param[in] col_nr column number guessed, 0 as default 623 @return column number if the table has the specified column, 624 otherwise table->n_def */ 625 ulint 626 dict_table_has_column( 627 const dict_table_t* table, 628 const char* col_name, 629 ulint col_nr = 0); 630 631 /**********************************************************************//** 632 Outputs info on foreign keys of a table. */ 633 void 634 dict_print_info_on_foreign_keys( 635 /*============================*/ 636 ibool create_table_format, /*!< in: if TRUE then print in 637 a format suitable to be inserted into 638 a CREATE TABLE, otherwise in the format 639 of SHOW TABLE STATUS */ 640 FILE* file, /*!< in: file where to print */ 641 trx_t* trx, /*!< in: transaction */ 642 dict_table_t* table); /*!< in: table */ 643 /**********************************************************************//** 644 Outputs info on a foreign key of a table in a format suitable for 645 CREATE TABLE. */ 646 void 647 dict_print_info_on_foreign_key_in_create_format( 648 /*============================================*/ 649 FILE* file, /*!< in: file where to print */ 650 trx_t* trx, /*!< in: transaction */ 651 dict_foreign_t* foreign, /*!< in: foreign key constraint */ 652 ibool add_newline); /*!< in: whether to add a newline */ 653 /*********************************************************************//** 654 Tries to find an index whose first fields are the columns in the array, 655 in the same order and is not marked for deletion and is not the same 656 as types_idx. 657 @return matching index, NULL if not found */ 658 bool 659 dict_foreign_qualify_index( 660 /*====================*/ 661 const dict_table_t* table, /*!< in: table */ 662 const char** col_names, 663 /*!< in: column names, or NULL 664 to use table->col_names */ 665 const char** columns,/*!< in: array of column names */ 666 ulint n_cols, /*!< in: number of columns */ 667 const dict_index_t* index, /*!< in: index to check */ 668 const dict_index_t* types_idx, 669 /*!< in: NULL or an index 670 whose types the column types 671 must match */ 672 bool check_charsets, 673 /*!< in: whether to check 674 charsets. only has an effect 675 if types_idx != NULL */ 676 ulint check_null) 677 /*!< in: nonzero if none of 678 the columns must be declared 679 NOT NULL */ 680 MY_ATTRIBUTE((warn_unused_result)); 681 #ifdef UNIV_DEBUG 682 /********************************************************************//** 683 Gets the first index on the table (the clustered index). 684 @return index, NULL if none exists */ 685 UNIV_INLINE 686 dict_index_t* 687 dict_table_get_first_index( 688 /*=======================*/ 689 const dict_table_t* table) /*!< in: table */ 690 MY_ATTRIBUTE((warn_unused_result)); 691 /********************************************************************//** 692 Gets the last index on the table. 693 @return index, NULL if none exists */ 694 UNIV_INLINE 695 dict_index_t* 696 dict_table_get_last_index( 697 /*=======================*/ 698 const dict_table_t* table) /*!< in: table */ 699 MY_ATTRIBUTE((warn_unused_result)); 700 /********************************************************************//** 701 Gets the next index on the table. 702 @return index, NULL if none left */ 703 UNIV_INLINE 704 dict_index_t* 705 dict_table_get_next_index( 706 /*======================*/ 707 const dict_index_t* index) /*!< in: index */ 708 MY_ATTRIBUTE((warn_unused_result)); 709 #else /* UNIV_DEBUG */ 710 # define dict_table_get_first_index(table) UT_LIST_GET_FIRST((table)->indexes) 711 # define dict_table_get_last_index(table) UT_LIST_GET_LAST((table)->indexes) 712 # define dict_table_get_next_index(index) UT_LIST_GET_NEXT(indexes, index) 713 #endif /* UNIV_DEBUG */ 714 #endif /* !UNIV_HOTBACKUP */ 715 716 /* Skip corrupted index */ 717 #define dict_table_skip_corrupt_index(index) \ 718 while (index && dict_index_is_corrupted(index)) { \ 719 index = dict_table_get_next_index(index); \ 720 } 721 722 /* Get the next non-corrupt index */ 723 #define dict_table_next_uncorrupted_index(index) \ 724 do { \ 725 index = dict_table_get_next_index(index); \ 726 dict_table_skip_corrupt_index(index); \ 727 } while (0) 728 729 /********************************************************************//** 730 Check whether the index is the clustered index. 731 @return nonzero for clustered index, zero for other indexes */ 732 UNIV_INLINE 733 ulint 734 dict_index_is_clust( 735 /*================*/ 736 const dict_index_t* index) /*!< in: index */ 737 MY_ATTRIBUTE((warn_unused_result)); 738 739 /** Check if index is auto-generated clustered index. 740 @param[in] index index 741 742 @return true if index is auto-generated clustered index. */ 743 UNIV_INLINE 744 bool 745 dict_index_is_auto_gen_clust( 746 const dict_index_t* index); 747 748 /********************************************************************//** 749 Check whether the index is unique. 750 @return nonzero for unique index, zero for other indexes */ 751 UNIV_INLINE 752 ulint 753 dict_index_is_unique( 754 /*=================*/ 755 const dict_index_t* index) /*!< in: index */ 756 MY_ATTRIBUTE((warn_unused_result)); 757 /********************************************************************//** 758 Check whether the index is a Spatial Index. 759 @return nonzero for Spatial Index, zero for other indexes */ 760 UNIV_INLINE 761 ulint 762 dict_index_is_spatial( 763 /*==================*/ 764 const dict_index_t* index) /*!< in: index */ 765 MY_ATTRIBUTE((warn_unused_result)); 766 /** Check whether the index contains a virtual column. 767 @param[in] index index 768 @return nonzero for index on virtual column, zero for other indexes */ 769 UNIV_INLINE 770 ulint 771 dict_index_has_virtual( 772 const dict_index_t* index); 773 /********************************************************************//** 774 Check whether the index is the insert buffer tree. 775 @return nonzero for insert buffer, zero for other indexes */ 776 UNIV_INLINE 777 ulint 778 dict_index_is_ibuf( 779 /*===============*/ 780 const dict_index_t* index) /*!< in: index */ 781 MY_ATTRIBUTE((warn_unused_result)); 782 /********************************************************************//** 783 Check whether the index is a secondary index or the insert buffer tree. 784 @return nonzero for insert buffer, zero for other indexes */ 785 UNIV_INLINE 786 ulint 787 dict_index_is_sec_or_ibuf( 788 /*======================*/ 789 const dict_index_t* index) /*!< in: index */ 790 MY_ATTRIBUTE((warn_unused_result)); 791 792 /** Get all the FTS indexes on a table. 793 @param[in] table table 794 @param[out] indexes all FTS indexes on this table 795 @return number of FTS indexes */ 796 ulint 797 dict_table_get_all_fts_indexes( 798 const dict_table_t* table, 799 ib_vector_t* indexes); 800 801 /********************************************************************//** 802 Gets the number of user-defined non-virtual columns in a table in the 803 dictionary cache. 804 @return number of user-defined (e.g., not ROW_ID) non-virtual 805 columns of a table */ 806 UNIV_INLINE 807 ulint 808 dict_table_get_n_user_cols( 809 /*=======================*/ 810 const dict_table_t* table) /*!< in: table */ 811 MY_ATTRIBUTE((warn_unused_result)); 812 /** Gets the number of user-defined virtual and non-virtual columns in a table 813 in the dictionary cache. 814 @param[in] table table 815 @return number of user-defined (e.g., not ROW_ID) columns of a table */ 816 UNIV_INLINE 817 ulint 818 dict_table_get_n_tot_u_cols( 819 const dict_table_t* table); 820 /********************************************************************//** 821 Gets the number of system columns in a table. 822 For intrinsic table on ROW_ID column is added for all other 823 tables TRX_ID and ROLL_PTR are all also appeneded. 824 @return number of system (e.g., ROW_ID) columns of a table */ 825 UNIV_INLINE 826 ulint 827 dict_table_get_n_sys_cols( 828 /*======================*/ 829 const dict_table_t* table) /*!< in: table */ 830 MY_ATTRIBUTE((warn_unused_result)); 831 /********************************************************************//** 832 Gets the number of all non-virtual columns (also system) in a table 833 in the dictionary cache. 834 @return number of columns of a table */ 835 UNIV_INLINE 836 ulint 837 dict_table_get_n_cols( 838 /*==================*/ 839 const dict_table_t* table) /*!< in: table */ 840 MY_ATTRIBUTE((warn_unused_result)); 841 842 /** Gets the number of virtual columns in a table in the dictionary cache. 843 @param[in] table the table to check 844 @return number of virtual columns of a table */ 845 UNIV_INLINE 846 ulint 847 dict_table_get_n_v_cols( 848 const dict_table_t* table); 849 850 /** Check if a table has indexed virtual columns 851 @param[in] table the table to check 852 @return true is the table has indexed virtual columns */ 853 UNIV_INLINE 854 bool 855 dict_table_has_indexed_v_cols( 856 const dict_table_t* table); 857 858 /********************************************************************//** 859 Gets the approximately estimated number of rows in the table. 860 @return estimated number of rows */ 861 UNIV_INLINE 862 ib_uint64_t 863 dict_table_get_n_rows( 864 /*==================*/ 865 const dict_table_t* table) /*!< in: table */ 866 MY_ATTRIBUTE((warn_unused_result)); 867 /********************************************************************//** 868 Increment the number of rows in the table by one. 869 Notice that this operation is not protected by any latch, the number is 870 approximate. */ 871 UNIV_INLINE 872 void 873 dict_table_n_rows_inc( 874 /*==================*/ 875 dict_table_t* table); /*!< in/out: table */ 876 /********************************************************************//** 877 Decrement the number of rows in the table by one. 878 Notice that this operation is not protected by any latch, the number is 879 approximate. */ 880 UNIV_INLINE 881 void 882 dict_table_n_rows_dec( 883 /*==================*/ 884 dict_table_t* table); /*!< in/out: table */ 885 886 /** Get nth virtual column 887 @param[in] table target table 888 @param[in] col_nr column number in MySQL Table definition 889 @return dict_v_col_t ptr */ 890 dict_v_col_t* 891 dict_table_get_nth_v_col_mysql( 892 const dict_table_t* table, 893 ulint col_nr); 894 895 #ifdef UNIV_DEBUG 896 /********************************************************************//** 897 Gets the nth column of a table. 898 @return pointer to column object */ 899 UNIV_INLINE 900 dict_col_t* 901 dict_table_get_nth_col( 902 /*===================*/ 903 const dict_table_t* table, /*!< in: table */ 904 ulint pos) /*!< in: position of column */ 905 MY_ATTRIBUTE((warn_unused_result)); 906 /** Gets the nth virtual column of a table. 907 @param[in] table table 908 @param[in] pos position of virtual column 909 @return pointer to virtual column object */ 910 UNIV_INLINE 911 dict_v_col_t* 912 dict_table_get_nth_v_col( 913 const dict_table_t* table, 914 ulint pos); 915 /********************************************************************//** 916 Gets the given system column of a table. 917 @return pointer to column object */ 918 UNIV_INLINE 919 dict_col_t* 920 dict_table_get_sys_col( 921 /*===================*/ 922 const dict_table_t* table, /*!< in: table */ 923 ulint sys) /*!< in: DATA_ROW_ID, ... */ 924 MY_ATTRIBUTE((warn_unused_result)); 925 #else /* UNIV_DEBUG */ 926 #define dict_table_get_nth_col(table, pos) \ 927 ((table)->cols + (pos)) 928 #define dict_table_get_sys_col(table, sys) \ 929 ((table)->cols + (table)->n_cols + (sys) \ 930 - (dict_table_get_n_sys_cols(table))) 931 /* Get nth virtual columns */ 932 #define dict_table_get_nth_v_col(table, pos) ((table)->v_cols + (pos)) 933 #endif /* UNIV_DEBUG */ 934 /********************************************************************//** 935 Gets the given system column number of a table. 936 @return column number */ 937 UNIV_INLINE 938 ulint 939 dict_table_get_sys_col_no( 940 /*======================*/ 941 const dict_table_t* table, /*!< in: table */ 942 ulint sys) /*!< in: DATA_ROW_ID, ... */ 943 MY_ATTRIBUTE((warn_unused_result)); 944 #ifndef UNIV_HOTBACKUP 945 /********************************************************************//** 946 Returns the minimum data size of an index record. 947 @return minimum data size in bytes */ 948 UNIV_INLINE 949 ulint 950 dict_index_get_min_size( 951 /*====================*/ 952 const dict_index_t* index) /*!< in: index */ 953 MY_ATTRIBUTE((warn_unused_result)); 954 #endif /* !UNIV_HOTBACKUP */ 955 /********************************************************************//** 956 Check whether the table uses the compact page format. 957 @return TRUE if table uses the compact page format */ 958 UNIV_INLINE 959 ibool 960 dict_table_is_comp( 961 /*===============*/ 962 const dict_table_t* table) /*!< in: table */ 963 MY_ATTRIBUTE((warn_unused_result)); 964 965 /********************************************************************//** 966 Determine the file format of a table. 967 @return file format version */ 968 UNIV_INLINE 969 ulint 970 dict_table_get_format( 971 /*==================*/ 972 const dict_table_t* table) /*!< in: table */ 973 MY_ATTRIBUTE((warn_unused_result)); 974 /********************************************************************//** 975 Determine the file format from a dict_table_t::flags. 976 @return file format version */ 977 UNIV_INLINE 978 ulint 979 dict_tf_get_format( 980 /*===============*/ 981 ulint flags) /*!< in: dict_table_t::flags */ 982 MY_ATTRIBUTE((warn_unused_result)); 983 984 /** Set the various values in a dict_table_t::flags pointer. 985 @param[in,out] flags, Pointer to a 4 byte Table Flags 986 @param[in] format, File Format 987 @param[in] zip_ssize Zip Shift Size 988 @param[in] use_data_dir Table uses DATA DIRECTORY 989 @param[in] shared_space Table uses a General Shared Tablespace */ 990 UNIV_INLINE 991 void 992 dict_tf_set( 993 ulint* flags, 994 rec_format_t format, 995 ulint zip_ssize, 996 bool use_data_dir, 997 bool shared_space); 998 999 /** Initialize a dict_table_t::flags pointer. 1000 @param[in] compact, Table uses Compact or greater 1001 @param[in] zip_ssize Zip Shift Size (log 2 minus 9) 1002 @param[in] atomic_blobs Table uses Compressed or Dynamic 1003 @param[in] data_dir Table uses DATA DIRECTORY 1004 @param[in] shared_space Table uses a General Shared Tablespace */ 1005 UNIV_INLINE 1006 ulint 1007 dict_tf_init( 1008 bool compact, 1009 ulint zip_ssize, 1010 bool atomic_blobs, 1011 bool data_dir, 1012 bool shared_space); 1013 1014 /** Convert a 32 bit integer table flags to the 32 bit FSP Flags. 1015 Fsp Flags are written into the tablespace header at the offset 1016 FSP_SPACE_FLAGS and are also stored in the fil_space_t::flags field. 1017 The following chart shows the translation of the low order bit. 1018 Other bits are the same. 1019 ========================= Low order bit ========================== 1020 | REDUNDANT | COMPACT | COMPRESSED | DYNAMIC 1021 dict_table_t::flags | 0 | 1 | 1 | 1 1022 fil_space_t::flags | 0 | 0 | 1 | 1 1023 ================================================================== 1024 @param[in] table_flags dict_table_t::flags 1025 @param[in] is_temp whether the tablespace is temporary 1026 @param[in] is_encrypted whether the tablespace is encrypted 1027 @return tablespace flags (fil_space_t::flags) */ 1028 ulint 1029 dict_tf_to_fsp_flags( 1030 ulint table_flags, 1031 bool is_temp, 1032 bool is_encrypted = false) 1033 MY_ATTRIBUTE((const)); 1034 1035 /** Extract the page size from table flags. 1036 @param[in] flags flags 1037 @return compressed page size, or 0 if not compressed */ 1038 UNIV_INLINE 1039 const page_size_t 1040 dict_tf_get_page_size( 1041 ulint flags) 1042 MY_ATTRIBUTE((const)); 1043 1044 /** Determine the extent size (in pages) for the given table 1045 @param[in] table the table whose extent size is being 1046 calculated. 1047 @return extent size in pages (256, 128 or 64) */ 1048 ulint 1049 dict_table_extent_size( 1050 const dict_table_t* table); 1051 1052 /** Get the table page size. 1053 @param[in] table table 1054 @return compressed page size, or 0 if not compressed */ 1055 UNIV_INLINE 1056 const page_size_t 1057 dict_table_page_size( 1058 const dict_table_t* table) 1059 MY_ATTRIBUTE((warn_unused_result)); 1060 1061 #ifndef UNIV_HOTBACKUP 1062 /*********************************************************************//** 1063 Obtain exclusive locks on all index trees of the table. This is to prevent 1064 accessing index trees while InnoDB is updating internal metadata for 1065 operations such as truncate tables. */ 1066 UNIV_INLINE 1067 void 1068 dict_table_x_lock_indexes( 1069 /*======================*/ 1070 dict_table_t* table); /*!< in: table */ 1071 /*********************************************************************//** 1072 Release the exclusive locks on all index tree. */ 1073 UNIV_INLINE 1074 void 1075 dict_table_x_unlock_indexes( 1076 /*========================*/ 1077 dict_table_t* table); /*!< in: table */ 1078 /********************************************************************//** 1079 Checks if a column is in the ordering columns of the clustered index of a 1080 table. Column prefixes are treated like whole columns. 1081 @return TRUE if the column, or its prefix, is in the clustered key */ 1082 ibool 1083 dict_table_col_in_clustered_key( 1084 /*============================*/ 1085 const dict_table_t* table, /*!< in: table */ 1086 ulint n) /*!< in: column number */ 1087 MY_ATTRIBUTE((warn_unused_result)); 1088 /*******************************************************************//** 1089 Check if the table has an FTS index. 1090 @return TRUE if table has an FTS index */ 1091 UNIV_INLINE 1092 ibool 1093 dict_table_has_fts_index( 1094 /*=====================*/ 1095 dict_table_t* table) /*!< in: table */ 1096 MY_ATTRIBUTE((warn_unused_result)); 1097 /** Copies types of virtual columns contained in table to tuple and sets all 1098 fields of the tuple to the SQL NULL value. This function should 1099 be called right after dtuple_create(). 1100 @param[in,out] tuple data tuple 1101 @param[in] table table 1102 */ 1103 void 1104 dict_table_copy_v_types( 1105 dtuple_t* tuple, 1106 const dict_table_t* table); 1107 1108 /*******************************************************************//** 1109 Copies types of columns contained in table to tuple and sets all 1110 fields of the tuple to the SQL NULL value. This function should 1111 be called right after dtuple_create(). */ 1112 void 1113 dict_table_copy_types( 1114 /*==================*/ 1115 dtuple_t* tuple, /*!< in/out: data tuple */ 1116 const dict_table_t* table); /*!< in: table */ 1117 /******************************************************************** 1118 Wait until all the background threads of the given table have exited, i.e., 1119 bg_threads == 0. Note: bg_threads_mutex must be reserved when 1120 calling this. */ 1121 void 1122 dict_table_wait_for_bg_threads_to_exit( 1123 /*===================================*/ 1124 dict_table_t* table, /* in: table */ 1125 ulint delay); /* in: time in microseconds to wait between 1126 checks of bg_threads. */ 1127 /**********************************************************************//** 1128 Looks for an index with the given id. NOTE that we do not reserve 1129 the dictionary mutex: this function is for emergency purposes like 1130 printing info of a corrupt database page! 1131 @return index or NULL if not found from cache */ 1132 dict_index_t* 1133 dict_index_find_on_id_low( 1134 /*======================*/ 1135 index_id_t id) /*!< in: index id */ 1136 MY_ATTRIBUTE((warn_unused_result)); 1137 /**********************************************************************//** 1138 Make room in the table cache by evicting an unused table. The unused table 1139 should not be part of FK relationship and currently not used in any user 1140 transaction. There is no guarantee that it will remove a table. 1141 @return number of tables evicted. */ 1142 ulint 1143 dict_make_room_in_cache( 1144 /*====================*/ 1145 ulint max_tables, /*!< in: max tables allowed in cache */ 1146 ulint pct_check); /*!< in: max percent to check */ 1147 1148 #define BIG_ROW_SIZE 1024 1149 1150 /** Adds an index to the dictionary cache. 1151 @param[in] table table on which the index is 1152 @param[in] index index; NOTE! The index memory 1153 object is freed in this function! 1154 @param[in] page_no root page number of the index 1155 @param[in] strict TRUE=refuse to create the index 1156 if records could be too big to fit in 1157 an B-tree page 1158 @return DB_SUCCESS, DB_TOO_BIG_RECORD, or DB_CORRUPTION */ 1159 dberr_t 1160 dict_index_add_to_cache( 1161 dict_table_t* table, 1162 dict_index_t* index, 1163 ulint page_no, 1164 ibool strict) 1165 MY_ATTRIBUTE((warn_unused_result)); 1166 1167 /** Clears the virtual column's index list before index is being freed. 1168 @param[in] index Index being freed */ 1169 void 1170 dict_index_remove_from_v_col_list( 1171 dict_index_t* index); 1172 1173 /** Adds an index to the dictionary cache, with possible indexing newly 1174 added column. 1175 @param[in] table table on which the index is 1176 @param[in] index index; NOTE! The index memory 1177 object is freed in this function! 1178 @param[in] add_v new virtual column that being added along with 1179 an add index call 1180 @param[in] page_no root page number of the index 1181 @param[in] strict TRUE=refuse to create the index 1182 if records could be too big to fit in 1183 an B-tree page 1184 @return DB_SUCCESS, DB_TOO_BIG_RECORD, or DB_CORRUPTION */ 1185 dberr_t 1186 dict_index_add_to_cache_w_vcol( 1187 dict_table_t* table, 1188 dict_index_t* index, 1189 const dict_add_v_col_t* add_v, 1190 ulint page_no, 1191 ibool strict) 1192 MY_ATTRIBUTE((warn_unused_result)); 1193 #endif /* !UNIV_HOTBACKUP */ 1194 /********************************************************************//** 1195 Gets the number of fields in the internal representation of an index, 1196 including fields added by the dictionary system. 1197 @return number of fields */ 1198 UNIV_INLINE 1199 ulint 1200 dict_index_get_n_fields( 1201 /*====================*/ 1202 const dict_index_t* index) /*!< in: an internal 1203 representation of index (in 1204 the dictionary cache) */ 1205 MY_ATTRIBUTE((warn_unused_result)); 1206 /********************************************************************//** 1207 Gets the number of fields in the internal representation of an index 1208 that uniquely determine the position of an index entry in the index, if 1209 we do not take multiversioning into account: in the B-tree use the value 1210 returned by dict_index_get_n_unique_in_tree. 1211 @return number of fields */ 1212 UNIV_INLINE 1213 ulint 1214 dict_index_get_n_unique( 1215 /*====================*/ 1216 const dict_index_t* index) /*!< in: an internal representation 1217 of index (in the dictionary cache) */ 1218 MY_ATTRIBUTE((warn_unused_result)); 1219 /********************************************************************//** 1220 Gets the number of fields in the internal representation of an index 1221 which uniquely determine the position of an index entry in the index, if 1222 we also take multiversioning into account. 1223 @return number of fields */ 1224 UNIV_INLINE 1225 ulint 1226 dict_index_get_n_unique_in_tree( 1227 /*============================*/ 1228 const dict_index_t* index) /*!< in: an internal representation 1229 of index (in the dictionary cache) */ 1230 MY_ATTRIBUTE((warn_unused_result)); 1231 1232 /** The number of fields in the nonleaf page of spatial index, except 1233 the page no field. */ 1234 #define DICT_INDEX_SPATIAL_NODEPTR_SIZE 1 1235 /** 1236 Gets the number of fields on nonleaf page level in the internal representation 1237 of an index which uniquely determine the position of an index entry in the 1238 index, if we also take multiversioning into account. Note, it doesn't 1239 include page no field. 1240 @param[in] index index 1241 @return number of fields */ 1242 UNIV_INLINE 1243 ulint 1244 dict_index_get_n_unique_in_tree_nonleaf( 1245 const dict_index_t* index) 1246 MY_ATTRIBUTE((warn_unused_result)); 1247 /********************************************************************//** 1248 Gets the number of user-defined ordering fields in the index. In the internal 1249 representation we add the row id to the ordering fields to make all indexes 1250 unique, but this function returns the number of fields the user defined 1251 in the index as ordering fields. 1252 @return number of fields */ 1253 UNIV_INLINE 1254 ulint 1255 dict_index_get_n_ordering_defined_by_user( 1256 /*======================================*/ 1257 const dict_index_t* index) /*!< in: an internal representation 1258 of index (in the dictionary cache) */ 1259 MY_ATTRIBUTE((warn_unused_result)); 1260 #ifdef UNIV_DEBUG 1261 /********************************************************************//** 1262 Gets the nth field of an index. 1263 @return pointer to field object */ 1264 UNIV_INLINE 1265 dict_field_t* 1266 dict_index_get_nth_field( 1267 /*=====================*/ 1268 const dict_index_t* index, /*!< in: index */ 1269 ulint pos) /*!< in: position of field */ 1270 MY_ATTRIBUTE((warn_unused_result)); 1271 #else /* UNIV_DEBUG */ 1272 # define dict_index_get_nth_field(index, pos) ((index)->fields + (pos)) 1273 #endif /* UNIV_DEBUG */ 1274 /********************************************************************//** 1275 Gets pointer to the nth column in an index. 1276 @return column */ 1277 UNIV_INLINE 1278 const dict_col_t* 1279 dict_index_get_nth_col( 1280 /*===================*/ 1281 const dict_index_t* index, /*!< in: index */ 1282 ulint pos) /*!< in: position of the field */ 1283 MY_ATTRIBUTE((warn_unused_result)); 1284 /********************************************************************//** 1285 Gets the column number of the nth field in an index. 1286 @return column number */ 1287 UNIV_INLINE 1288 ulint 1289 dict_index_get_nth_col_no( 1290 /*======================*/ 1291 const dict_index_t* index, /*!< in: index */ 1292 ulint pos) /*!< in: position of the field */ 1293 MY_ATTRIBUTE((warn_unused_result)); 1294 /********************************************************************//** 1295 Looks for column n in an index. 1296 @return position in internal representation of the index; 1297 ULINT_UNDEFINED if not contained */ 1298 UNIV_INLINE 1299 ulint 1300 dict_index_get_nth_col_pos( 1301 /*=======================*/ 1302 const dict_index_t* index, /*!< in: index */ 1303 ulint n, /*!< in: column number */ 1304 ulint* prefix_col_pos) /*!< out: col num if prefix */ 1305 MY_ATTRIBUTE((nonnull(1), warn_unused_result)); 1306 /** Looks for column n in an index. 1307 @param[in] index index 1308 @param[in] n column number 1309 @param[in] inc_prefix true=consider column prefixes too 1310 @param[in] is_virtual true==virtual column 1311 @param[in] prefix_col_pos col num if prefix 1312 @return position in internal representation of the index; 1313 ULINT_UNDEFINED if not contained */ 1314 ulint 1315 dict_index_get_nth_col_or_prefix_pos( 1316 const dict_index_t* index, /*!< in: index */ 1317 ulint n, /*!< in: column number */ 1318 bool inc_prefix, /*!< in: TRUE=consider 1319 column prefixes too */ 1320 bool is_virtual, /*!< in: is a virtual column */ 1321 ulint* prefix_col_pos) /*!< out: col num if prefix */ 1322 MY_ATTRIBUTE((warn_unused_result)); 1323 /********************************************************************//** 1324 Returns TRUE if the index contains a column or a prefix of that column. 1325 @param[in] index index 1326 @param[in] n column number 1327 @param[in] is_virtual whether it is a virtual col 1328 @return TRUE if contains the column or its prefix */ 1329 ibool 1330 dict_index_contains_col_or_prefix( 1331 /*==============================*/ 1332 const dict_index_t* index, /*!< in: index */ 1333 ulint n, /*!< in: column number */ 1334 bool is_virtual) 1335 /*!< in: whether it is a virtual col */ 1336 MY_ATTRIBUTE((warn_unused_result)); 1337 /********************************************************************//** 1338 Looks for a matching field in an index. The column has to be the same. The 1339 column in index must be complete, or must contain a prefix longer than the 1340 column in index2. That is, we must be able to construct the prefix in index2 1341 from the prefix in index. 1342 @return position in internal representation of the index; 1343 ULINT_UNDEFINED if not contained */ 1344 ulint 1345 dict_index_get_nth_field_pos( 1346 /*=========================*/ 1347 const dict_index_t* index, /*!< in: index from which to search */ 1348 const dict_index_t* index2, /*!< in: index */ 1349 ulint n) /*!< in: field number in index2 */ 1350 MY_ATTRIBUTE((warn_unused_result)); 1351 /********************************************************************//** 1352 Looks for column n position in the clustered index. 1353 @return position in internal representation of the clustered index */ 1354 ulint 1355 dict_table_get_nth_col_pos( 1356 /*=======================*/ 1357 const dict_table_t* table, /*!< in: table */ 1358 ulint n) /*!< in: column number */ 1359 MY_ATTRIBUTE((warn_unused_result)); 1360 /********************************************************************//** 1361 Returns the position of a system column in an index. 1362 @return position, ULINT_UNDEFINED if not contained */ 1363 UNIV_INLINE 1364 ulint 1365 dict_index_get_sys_col_pos( 1366 /*=======================*/ 1367 const dict_index_t* index, /*!< in: index */ 1368 ulint type) /*!< in: DATA_ROW_ID, ... */ 1369 MY_ATTRIBUTE((warn_unused_result)); 1370 /*******************************************************************//** 1371 Adds a column to index. */ 1372 void 1373 dict_index_add_col( 1374 /*===============*/ 1375 dict_index_t* index, /*!< in/out: index */ 1376 const dict_table_t* table, /*!< in: table */ 1377 dict_col_t* col, /*!< in: column */ 1378 ulint prefix_len); /*!< in: column prefix length */ 1379 #ifndef UNIV_HOTBACKUP 1380 /*******************************************************************//** 1381 Copies types of fields contained in index to tuple. */ 1382 void 1383 dict_index_copy_types( 1384 /*==================*/ 1385 dtuple_t* tuple, /*!< in/out: data tuple */ 1386 const dict_index_t* index, /*!< in: index */ 1387 ulint n_fields); /*!< in: number of 1388 field types to copy */ 1389 #endif /* !UNIV_HOTBACKUP */ 1390 /*********************************************************************//** 1391 Gets the field column. 1392 @return field->col, pointer to the table column */ 1393 UNIV_INLINE 1394 const dict_col_t* 1395 dict_field_get_col( 1396 /*===============*/ 1397 const dict_field_t* field) /*!< in: index field */ 1398 MY_ATTRIBUTE((warn_unused_result)); 1399 #ifndef UNIV_HOTBACKUP 1400 /**********************************************************************//** 1401 Returns an index object if it is found in the dictionary cache. 1402 Assumes that dict_sys->mutex is already being held. 1403 @return index, NULL if not found */ 1404 dict_index_t* 1405 dict_index_get_if_in_cache_low( 1406 /*===========================*/ 1407 index_id_t index_id) /*!< in: index id */ 1408 MY_ATTRIBUTE((warn_unused_result)); 1409 #if defined UNIV_DEBUG || defined UNIV_BUF_DEBUG 1410 /**********************************************************************//** 1411 Returns an index object if it is found in the dictionary cache. 1412 @return index, NULL if not found */ 1413 dict_index_t* 1414 dict_index_get_if_in_cache( 1415 /*=======================*/ 1416 index_id_t index_id) /*!< in: index id */ 1417 MY_ATTRIBUTE((warn_unused_result)); 1418 #endif /* UNIV_DEBUG || UNIV_BUF_DEBUG */ 1419 #ifdef UNIV_DEBUG 1420 /**********************************************************************//** 1421 Checks that a tuple has n_fields_cmp value in a sensible range, so that 1422 no comparison can occur with the page number field in a node pointer. 1423 @return TRUE if ok */ 1424 ibool 1425 dict_index_check_search_tuple( 1426 /*==========================*/ 1427 const dict_index_t* index, /*!< in: index tree */ 1428 const dtuple_t* tuple) /*!< in: tuple used in a search */ 1429 MY_ATTRIBUTE((warn_unused_result)); 1430 /** Whether and when to allow temporary index names */ 1431 enum check_name { 1432 /** Require all indexes to be complete. */ 1433 CHECK_ALL_COMPLETE, 1434 /** Allow aborted online index creation. */ 1435 CHECK_ABORTED_OK, 1436 /** Allow partial indexes to exist. */ 1437 CHECK_PARTIAL_OK 1438 }; 1439 /**********************************************************************//** 1440 Check for duplicate index entries in a table [using the index name] */ 1441 void 1442 dict_table_check_for_dup_indexes( 1443 /*=============================*/ 1444 const dict_table_t* table, /*!< in: Check for dup indexes 1445 in this table */ 1446 enum check_name check); /*!< in: whether and when to allow 1447 temporary index names */ 1448 #endif /* UNIV_DEBUG */ 1449 /**********************************************************************//** 1450 Builds a node pointer out of a physical record and a page number. 1451 @return own: node pointer */ 1452 dtuple_t* 1453 dict_index_build_node_ptr( 1454 /*======================*/ 1455 const dict_index_t* index, /*!< in: index */ 1456 const rec_t* rec, /*!< in: record for which to build node 1457 pointer */ 1458 ulint page_no,/*!< in: page number to put in node 1459 pointer */ 1460 mem_heap_t* heap, /*!< in: memory heap where pointer 1461 created */ 1462 ulint level) /*!< in: level of rec in tree: 1463 0 means leaf level */ 1464 MY_ATTRIBUTE((warn_unused_result)); 1465 /**********************************************************************//** 1466 Copies an initial segment of a physical record, long enough to specify an 1467 index entry uniquely. 1468 @return pointer to the prefix record */ 1469 rec_t* 1470 dict_index_copy_rec_order_prefix( 1471 /*=============================*/ 1472 const dict_index_t* index, /*!< in: index */ 1473 const rec_t* rec, /*!< in: record for which to 1474 copy prefix */ 1475 ulint* n_fields,/*!< out: number of fields copied */ 1476 byte** buf, /*!< in/out: memory buffer for the 1477 copied prefix, or NULL */ 1478 ulint* buf_size)/*!< in/out: buffer size */ 1479 MY_ATTRIBUTE((warn_unused_result)); 1480 /**********************************************************************//** 1481 Builds a typed data tuple out of a physical record. 1482 @return own: data tuple */ 1483 dtuple_t* 1484 dict_index_build_data_tuple( 1485 /*========================*/ 1486 dict_index_t* index, /*!< in: index */ 1487 rec_t* rec, /*!< in: record for which to build data tuple */ 1488 ulint n_fields,/*!< in: number of data fields */ 1489 mem_heap_t* heap) /*!< in: memory heap where tuple created */ 1490 MY_ATTRIBUTE((warn_unused_result)); 1491 /*********************************************************************//** 1492 Gets the space id of the root of the index tree. 1493 @return space id */ 1494 UNIV_INLINE 1495 ulint 1496 dict_index_get_space( 1497 /*=================*/ 1498 const dict_index_t* index) /*!< in: index */ 1499 MY_ATTRIBUTE((warn_unused_result)); 1500 1501 /*********************************************************************//** 1502 Sets the space id of the root of the index tree. */ 1503 UNIV_INLINE 1504 void 1505 dict_index_set_space( 1506 /*=================*/ 1507 dict_index_t* index, /*!< in/out: index */ 1508 ulint space); /*!< in: space id */ 1509 1510 /*********************************************************************//** 1511 Gets the page number of the root of the index tree. 1512 @return page number */ 1513 UNIV_INLINE 1514 ulint 1515 dict_index_get_page( 1516 /*================*/ 1517 const dict_index_t* tree) /*!< in: index */ 1518 MY_ATTRIBUTE((warn_unused_result)); 1519 /*********************************************************************//** 1520 Gets the read-write lock of the index tree. 1521 @return read-write lock */ 1522 UNIV_INLINE 1523 rw_lock_t* 1524 dict_index_get_lock( 1525 /*================*/ 1526 dict_index_t* index) /*!< in: index */ 1527 MY_ATTRIBUTE((warn_unused_result)); 1528 /********************************************************************//** 1529 Returns free space reserved for future updates of records. This is 1530 relevant only in the case of many consecutive inserts, as updates 1531 which make the records bigger might fragment the index. 1532 @return number of free bytes on page, reserved for updates */ 1533 UNIV_INLINE 1534 ulint 1535 dict_index_get_space_reserve(void); 1536 /*==============================*/ 1537 1538 /* Online index creation @{ */ 1539 /********************************************************************//** 1540 Gets the status of online index creation. 1541 @return the status */ 1542 UNIV_INLINE 1543 enum online_index_status 1544 dict_index_get_online_status( 1545 /*=========================*/ 1546 const dict_index_t* index) /*!< in: secondary index */ 1547 MY_ATTRIBUTE((warn_unused_result)); 1548 1549 /********************************************************************//** 1550 Sets the status of online index creation. */ 1551 UNIV_INLINE 1552 void 1553 dict_index_set_online_status( 1554 /*=========================*/ 1555 dict_index_t* index, /*!< in/out: index */ 1556 enum online_index_status status); /*!< in: status */ 1557 /********************************************************************//** 1558 Determines if a secondary index is being or has been created online, 1559 or if the table is being rebuilt online, allowing concurrent modifications 1560 to the table. 1561 @retval true if the index is being or has been built online, or 1562 if this is a clustered index and the table is being or has been rebuilt online 1563 @retval false if the index has been created or the table has been 1564 rebuilt completely */ 1565 UNIV_INLINE 1566 bool 1567 dict_index_is_online_ddl( 1568 /*=====================*/ 1569 const dict_index_t* index) /*!< in: index */ 1570 MY_ATTRIBUTE((warn_unused_result)); 1571 /*********************************************************************//** 1572 Calculates the minimum record length in an index. */ 1573 ulint 1574 dict_index_calc_min_rec_len( 1575 /*========================*/ 1576 const dict_index_t* index) /*!< in: index */ 1577 MY_ATTRIBUTE((warn_unused_result)); 1578 /********************************************************************//** 1579 Reserves the dictionary system mutex for MySQL. */ 1580 void 1581 dict_mutex_enter_for_mysql(void); 1582 /*============================*/ 1583 /********************************************************************//** 1584 Releases the dictionary system mutex for MySQL. */ 1585 void 1586 dict_mutex_exit_for_mysql(void); 1587 /*===========================*/ 1588 1589 /** Create a dict_table_t's stats latch or delay for lazy creation. 1590 This function is only called from either single threaded environment 1591 or from a thread that has not shared the table object with other threads. 1592 @param[in,out] table table whose stats latch to create 1593 @param[in] enabled if false then the latch is disabled 1594 and dict_table_stats_lock()/unlock() become noop on this table. */ 1595 void 1596 dict_table_stats_latch_create( 1597 dict_table_t* table, 1598 bool enabled); 1599 1600 /** Destroy a dict_table_t's stats latch. 1601 This function is only called from either single threaded environment 1602 or from a thread that has not shared the table object with other threads. 1603 @param[in,out] table table whose stats latch to destroy */ 1604 void 1605 dict_table_stats_latch_destroy( 1606 dict_table_t* table); 1607 1608 /** Lock the appropriate latch to protect a given table's statistics. 1609 @param[in] table table whose stats to lock 1610 @param[in] latch_mode RW_S_LATCH or RW_X_LATCH */ 1611 void 1612 dict_table_stats_lock( 1613 dict_table_t* table, 1614 ulint latch_mode); 1615 1616 /** Unlock the latch that has been locked by dict_table_stats_lock(). 1617 @param[in] table table whose stats to unlock 1618 @param[in] latch_mode RW_S_LATCH or RW_X_LATCH */ 1619 void 1620 dict_table_stats_unlock( 1621 dict_table_t* table, 1622 ulint latch_mode); 1623 1624 /********************************************************************//** 1625 Checks if the database name in two table names is the same. 1626 @return TRUE if same db name */ 1627 ibool 1628 dict_tables_have_same_db( 1629 /*=====================*/ 1630 const char* name1, /*!< in: table name in the form 1631 dbname '/' tablename */ 1632 const char* name2) /*!< in: table name in the form 1633 dbname '/' tablename */ 1634 MY_ATTRIBUTE((warn_unused_result)); 1635 /** Get an index by name. 1636 @param[in] table the table where to look for the index 1637 @param[in] name the index name to look for 1638 @param[in] committed true=search for committed, 1639 false=search for uncommitted 1640 @return index, NULL if does not exist */ 1641 dict_index_t* 1642 dict_table_get_index_on_name( 1643 dict_table_t* table, 1644 const char* name, 1645 bool committed=true) 1646 MY_ATTRIBUTE((warn_unused_result)); 1647 /** Get an index by name. 1648 @param[in] table the table where to look for the index 1649 @param[in] name the index name to look for 1650 @param[in] committed true=search for committed, 1651 false=search for uncommitted 1652 @return index, NULL if does not exist */ 1653 inline 1654 const dict_index_t* 1655 dict_table_get_index_on_name( 1656 const dict_table_t* table, 1657 const char* name, 1658 bool committed=true) 1659 { 1660 return(dict_table_get_index_on_name( 1661 const_cast<dict_table_t*>(table), name, committed)); 1662 } 1663 1664 /*************************************************************** 1665 Check whether a column exists in an FTS index. */ 1666 UNIV_INLINE 1667 ulint 1668 dict_table_is_fts_column( 1669 /*=====================*/ 1670 /* out: ULINT_UNDEFINED if no match else 1671 the offset within the vector */ 1672 ib_vector_t* indexes,/* in: vector containing only FTS indexes */ 1673 ulint col_no, /* in: col number to search for */ 1674 bool is_virtual)/*!< in: whether it is a virtual column */ 1675 MY_ATTRIBUTE((warn_unused_result)); 1676 /**********************************************************************//** 1677 Prevent table eviction by moving a table to the non-LRU list from the 1678 LRU list if it is not already there. */ 1679 UNIV_INLINE 1680 void 1681 dict_table_prevent_eviction( 1682 /*========================*/ 1683 dict_table_t* table); /*!< in: table to prevent eviction */ 1684 /**********************************************************************//** 1685 Move a table to the non LRU end of the LRU list. */ 1686 void 1687 dict_table_move_from_lru_to_non_lru( 1688 /*================================*/ 1689 dict_table_t* table); /*!< in: table to move from LRU to non-LRU */ 1690 /** Looks for an index with the given id given a table instance. 1691 @param[in] table table instance 1692 @param[in] id index id 1693 @return index or NULL */ 1694 dict_index_t* 1695 dict_table_find_index_on_id( 1696 const dict_table_t* table, 1697 index_id_t id); 1698 /**********************************************************************//** 1699 Move to the most recently used segment of the LRU list. */ 1700 void 1701 dict_move_to_mru( 1702 /*=============*/ 1703 dict_table_t* table); /*!< in: table to move to MRU */ 1704 1705 /** Maximum number of columns in a foreign key constraint. Please Note MySQL 1706 has a much lower limit on the number of columns allowed in a foreign key 1707 constraint */ 1708 #define MAX_NUM_FK_COLUMNS 500 1709 1710 /* Buffers for storing detailed information about the latest foreign key 1711 and unique key errors */ 1712 extern FILE* dict_foreign_err_file; 1713 extern ib_mutex_t dict_foreign_err_mutex; /* mutex protecting the 1714 foreign key error messages */ 1715 1716 /** the dictionary system */ 1717 extern dict_sys_t* dict_sys; 1718 /** the data dictionary rw-latch protecting dict_sys */ 1719 extern rw_lock_t* dict_operation_lock; 1720 1721 typedef std::map<table_id_t, ib_uint64_t> autoinc_map_t; 1722 1723 /* Dictionary system struct */ 1724 struct dict_sys_t{ 1725 DictSysMutex mutex; /*!< mutex protecting the data 1726 dictionary; protects also the 1727 disk-based dictionary system tables; 1728 this mutex serializes CREATE TABLE 1729 and DROP TABLE, as well as reading 1730 the dictionary data for a table from 1731 system tables */ 1732 row_id_t row_id; /*!< the next row id to assign; 1733 NOTE that at a checkpoint this 1734 must be written to the dict system 1735 header and flushed to a file; in 1736 recovery this must be derived from 1737 the log records */ 1738 hash_table_t* table_hash; /*!< hash table of the tables, based 1739 on name */ 1740 hash_table_t* table_id_hash; /*!< hash table of the tables, based 1741 on id */ 1742 size_t hash_size; /*!< size of table_hash and 1743 table_id_hash combined */ 1744 lint size; /*!< varying space in bytes occupied 1745 by the data dictionary table and 1746 index objects */ 1747 dict_table_t* sys_tables; /*!< SYS_TABLES table */ 1748 dict_table_t* sys_columns; /*!< SYS_COLUMNS table */ 1749 dict_table_t* sys_indexes; /*!< SYS_INDEXES table */ 1750 dict_table_t* sys_fields; /*!< SYS_FIELDS table */ 1751 dict_table_t* sys_virtual; /*!< SYS_VIRTUAL table */ 1752 1753 /*=============================*/ 1754 UT_LIST_BASE_NODE_T(dict_table_t) 1755 table_LRU; /*!< List of tables that can be evicted 1756 from the cache */ 1757 UT_LIST_BASE_NODE_T(dict_table_t) 1758 table_non_LRU; /*!< List of tables that can't be 1759 evicted from the cache */ 1760 autoinc_map_t* autoinc_map; /*!< Map to store table id and autoinc 1761 when table is evicted */ 1762 1763 /** The first ID of the redo log pseudo-tablespace */ 1764 static const ulint s_log_space_first_id = 0xFFFFFFF0UL; 1765 /** Use maximum UINT value to indicate invalid space ID. */ 1766 static const ulint s_invalid_space_id = 0xFFFFFFFF; 1767 /** The data dictionary tablespace ID. The data dictionary 1768 tablespace does not exist in 5.7, but its ID added here 1769 for assertion checking. */ 1770 static const ulint s_space_id = 0xFFFFFFFE; 1771 /** The innodb_temporary tablespace ID. */ 1772 static const ulint s_temp_space_id = 0xFFFFFFFD; 1773 /** The lowest undo tablespace ID. */ 1774 static const ulint s_min_undo_space_id 1775 = s_log_space_first_id - TRX_SYS_N_RSEGS; 1776 /** The highest undo tablespace ID. */ 1777 static const ulint s_max_undo_space_id 1778 = s_log_space_first_id - 1; 1779 /** The first reserved tablespace ID */ 1780 static const ulint s_reserved_space_id = 1781 s_min_undo_space_id; 1782 }; 1783 #endif /* !UNIV_HOTBACKUP */ 1784 1785 /** dummy index for ROW_FORMAT=REDUNDANT supremum and infimum records */ 1786 extern dict_index_t* dict_ind_redundant; 1787 1788 /**********************************************************************//** 1789 Inits dict_ind_redundant. */ 1790 void 1791 dict_ind_init(void); 1792 /*===============*/ 1793 1794 /* Auxiliary structs for checking a table definition @{ */ 1795 1796 /* This struct is used to specify the name and type that a column must 1797 have when checking a table's schema. */ 1798 struct dict_col_meta_t { 1799 const char* name; /* column name */ 1800 ulint mtype; /* required column main type */ 1801 ulint prtype_mask; /* required column precise type mask; 1802 if this is non-zero then all the 1803 bits it has set must also be set 1804 in the column's prtype */ 1805 ulint len; /* required column length */ 1806 }; 1807 1808 /* This struct is used for checking whether a given table exists and 1809 whether it has a predefined schema (number of columns and column names 1810 and types) */ 1811 struct dict_table_schema_t { 1812 const char* table_name; /* the name of the table whose 1813 structure we are checking */ 1814 ulint n_cols; /* the number of columns the 1815 table must have */ 1816 dict_col_meta_t* columns; /* metadata for the columns; 1817 this array has n_cols 1818 elements */ 1819 ulint n_foreign; /* number of foreign keys this 1820 table has, pointing to other 1821 tables (where this table is 1822 FK child) */ 1823 ulint n_referenced; /* number of foreign keys other 1824 tables have, pointing to this 1825 table (where this table is 1826 parent) */ 1827 }; 1828 /* @} */ 1829 1830 /*********************************************************************//** 1831 Checks whether a table exists and whether it has the given structure. 1832 The table must have the same number of columns with the same names and 1833 types. The order of the columns does not matter. 1834 The caller must own the dictionary mutex. 1835 dict_table_schema_check() @{ 1836 @return DB_SUCCESS if the table exists and contains the necessary columns */ 1837 dberr_t 1838 dict_table_schema_check( 1839 /*====================*/ 1840 dict_table_schema_t* req_schema, /*!< in/out: required table 1841 schema */ 1842 char* errstr, /*!< out: human readable error 1843 message if != DB_SUCCESS and 1844 != DB_TABLE_NOT_FOUND is 1845 returned */ 1846 size_t errstr_sz) /*!< in: errstr size */ 1847 MY_ATTRIBUTE((warn_unused_result)); 1848 /* @} */ 1849 1850 /*********************************************************************//** 1851 Converts a database and table name from filesystem encoding 1852 (e.g. d@i1b/a@q1b@1Kc, same format as used in dict_table_t::name) in two 1853 strings in UTF8 encoding (e.g. dцb and aюbØc). The output buffers must be 1854 at least MAX_DB_UTF8_LEN and MAX_TABLE_UTF8_LEN bytes. */ 1855 void 1856 dict_fs2utf8( 1857 /*=========*/ 1858 const char* db_and_table, /*!< in: database and table names, 1859 e.g. d@i1b/a@q1b@1Kc */ 1860 char* db_utf8, /*!< out: database name, e.g. dцb */ 1861 size_t db_utf8_size, /*!< in: dbname_utf8 size */ 1862 char* table_utf8, /*!< out: table name, e.g. aюbØc */ 1863 size_t table_utf8_size); /*!< in: table_utf8 size */ 1864 1865 /** Resize the hash tables besed on the current buffer pool size. */ 1866 void 1867 dict_resize(); 1868 1869 /**********************************************************************//** 1870 Closes the data dictionary module. */ 1871 void 1872 dict_close(void); 1873 /*============*/ 1874 #ifndef UNIV_HOTBACKUP 1875 /**********************************************************************//** 1876 Check whether the table is corrupted. 1877 @return nonzero for corrupted table, zero for valid tables */ 1878 UNIV_INLINE 1879 ulint 1880 dict_table_is_corrupted( 1881 /*====================*/ 1882 const dict_table_t* table) /*!< in: table */ 1883 MY_ATTRIBUTE((warn_unused_result)); 1884 1885 /**********************************************************************//** 1886 Check whether the index is corrupted. 1887 @return nonzero for corrupted index, zero for valid indexes */ 1888 UNIV_INLINE 1889 ulint 1890 dict_index_is_corrupted( 1891 /*====================*/ 1892 const dict_index_t* index) /*!< in: index */ 1893 MY_ATTRIBUTE((warn_unused_result)); 1894 1895 #endif /* !UNIV_HOTBACKUP */ 1896 /**********************************************************************//** 1897 Flags an index and table corrupted both in the data dictionary cache 1898 and in the system table SYS_INDEXES. */ 1899 void 1900 dict_set_corrupted( 1901 /*===============*/ 1902 dict_index_t* index, /*!< in/out: index */ 1903 trx_t* trx, /*!< in/out: transaction */ 1904 const char* ctx) /*!< in: context */ 1905 UNIV_COLD; 1906 1907 /** Flags an index corrupted in the data dictionary cache only. This 1908 is used mostly to mark a corrupted index when index's own dictionary 1909 is corrupted, and we force to load such index for repair purpose 1910 @param[in,out] index index that is corrupted */ 1911 void 1912 dict_set_corrupted_index_cache_only( 1913 dict_index_t* index); 1914 1915 /**********************************************************************//** 1916 Flags a table with specified space_id corrupted in the table dictionary 1917 cache. 1918 @return TRUE if successful */ 1919 ibool 1920 dict_set_corrupted_by_space( 1921 /*========================*/ 1922 ulint space_id); /*!< in: space ID */ 1923 1924 bool dict_set_corrupted_by_space(const fil_space_t* space); 1925 1926 /** Flag a table with specified space_id encrypted in the data dictionary 1927 cache 1928 @param[in] space_id Tablespace id */ 1929 void 1930 dict_set_encrypted_by_space( 1931 ulint space_id); 1932 1933 /** Sets merge_threshold in the SYS_INDEXES 1934 @param[in,out] index index 1935 @param[in] merge_threshold value to set */ 1936 void 1937 dict_index_set_merge_threshold( 1938 dict_index_t* index, 1939 ulint merge_threshold); 1940 1941 #ifdef UNIV_DEBUG 1942 /** Sets merge_threshold for all indexes in dictionary cache for debug. 1943 @param[in] merge_threshold_all value to set for all indexes */ 1944 void 1945 dict_set_merge_threshold_all_debug( 1946 uint merge_threshold_all); 1947 #endif /* UNIV_DEBUG */ 1948 1949 /** Validate the table flags. 1950 @param[in] flags Table flags 1951 @return true if valid. */ 1952 UNIV_INLINE 1953 bool 1954 dict_tf_is_valid( 1955 ulint flags); 1956 1957 /** Validate both table flags and table flags2 and make sure they 1958 are compatible. 1959 @param[in] flags Table flags 1960 @param[in] flags2 Table flags2 1961 @return true if valid. */ 1962 UNIV_INLINE 1963 bool 1964 dict_tf2_is_valid( 1965 ulint flags, 1966 ulint flags2); 1967 1968 /********************************************************************//** 1969 Check if the tablespace for the table has been discarded. 1970 @return true if the tablespace has been discarded. */ 1971 UNIV_INLINE 1972 bool 1973 dict_table_is_discarded( 1974 /*====================*/ 1975 const dict_table_t* table) /*!< in: table to check */ 1976 MY_ATTRIBUTE((warn_unused_result)); 1977 1978 /********************************************************************//** 1979 Check if it is a temporary table. 1980 @return true if temporary table flag is set. */ 1981 UNIV_INLINE 1982 bool 1983 dict_table_is_temporary( 1984 /*====================*/ 1985 const dict_table_t* table) /*!< in: table to check */ 1986 MY_ATTRIBUTE((warn_unused_result)); 1987 1988 /********************************************************************//** 1989 Check if it is a encrypted table. 1990 @return true if table encryption flag is set. */ 1991 UNIV_INLINE 1992 bool 1993 dict_table_is_encrypted( 1994 /*====================*/ 1995 const dict_table_t* table) /*!< in: table to check */ 1996 MY_ATTRIBUTE((warn_unused_result)); 1997 1998 /** Check whether the table is intrinsic. 1999 An intrinsic table is a special kind of temporary table that 2000 is invisible to the end user. It is created internally by the MySQL server 2001 layer or other module connected to InnoDB in order to gather and use data 2002 as part of a larger task. Since access to it must be as fast as possible, 2003 it does not need UNDO semantics, system fields DB_TRX_ID & DB_ROLL_PTR, 2004 doublewrite, checksum, insert buffer, use of the shared data dictionary, 2005 locking, or even a transaction. In short, these are not ACID tables at all, 2006 just temporary 2007 2008 @param[in] table table to check 2009 @return true if intrinsic table flag is set. */ 2010 UNIV_INLINE 2011 bool 2012 dict_table_is_intrinsic( 2013 const dict_table_t* table) 2014 MY_ATTRIBUTE((warn_unused_result)); 2015 2016 /** Check if the table is in a shared tablespace (System or General). 2017 @param[in] id Space ID to check 2018 @return true if id is a shared tablespace, false if not. */ 2019 UNIV_INLINE 2020 bool 2021 dict_table_in_shared_tablespace( 2022 const dict_table_t* table) 2023 MY_ATTRIBUTE((warn_unused_result)); 2024 2025 /** Check whether locking is disabled for this table. 2026 Currently this is done for intrinsic table as their visibility is limited 2027 to the connection only. 2028 2029 @param[in] table table to check 2030 @return true if locking is disabled. */ 2031 UNIV_INLINE 2032 bool 2033 dict_table_is_locking_disabled( 2034 const dict_table_t* table) 2035 MY_ATTRIBUTE((warn_unused_result)); 2036 2037 /********************************************************************//** 2038 Turn-off redo-logging if temporary table. */ 2039 UNIV_INLINE 2040 void 2041 dict_disable_redo_if_temporary( 2042 /*===========================*/ 2043 const dict_table_t* table, /*!< in: table to check */ 2044 mtr_t* mtr); /*!< out: mini-transaction */ 2045 2046 /** Get table session row-id and increment the row-id counter for next use. 2047 @param[in,out] table table handler 2048 @return next table local row-id. */ 2049 UNIV_INLINE 2050 row_id_t 2051 dict_table_get_next_table_sess_row_id( 2052 dict_table_t* table); 2053 2054 /** Get table session trx-id and increment the trx-id counter for next use. 2055 @param[in,out] table table handler 2056 @return next table local trx-id. */ 2057 UNIV_INLINE 2058 trx_id_t 2059 dict_table_get_next_table_sess_trx_id( 2060 dict_table_t* table); 2061 2062 /** Get current session trx-id. 2063 @param[in] table table handler 2064 @return table local trx-id. */ 2065 UNIV_INLINE 2066 trx_id_t 2067 dict_table_get_curr_table_sess_trx_id( 2068 const dict_table_t* table); 2069 2070 #ifndef UNIV_HOTBACKUP 2071 /*********************************************************************//** 2072 This function should be called whenever a page is successfully 2073 compressed. Updates the compression padding information. */ 2074 void 2075 dict_index_zip_success( 2076 /*===================*/ 2077 dict_index_t* index); /*!< in/out: index to be updated. */ 2078 /*********************************************************************//** 2079 This function should be called whenever a page compression attempt 2080 fails. Updates the compression padding information. */ 2081 void 2082 dict_index_zip_failure( 2083 /*===================*/ 2084 dict_index_t* index); /*!< in/out: index to be updated. */ 2085 /*********************************************************************//** 2086 Return the optimal page size, for which page will likely compress. 2087 @return page size beyond which page may not compress*/ 2088 ulint 2089 dict_index_zip_pad_optimal_page_size( 2090 /*=================================*/ 2091 dict_index_t* index) /*!< in: index for which page size 2092 is requested */ 2093 MY_ATTRIBUTE((warn_unused_result)); 2094 /*************************************************************//** 2095 Convert table flag to row format string. 2096 @return row format name */ 2097 const char* 2098 dict_tf_to_row_format_string( 2099 /*=========================*/ 2100 ulint table_flag); /*!< in: row format setting */ 2101 /****************************************************************//** 2102 Return maximum size of the node pointer record. 2103 @return maximum size of the record in bytes */ 2104 ulint 2105 dict_index_node_ptr_max_size( 2106 /*=========================*/ 2107 const dict_index_t* index) /*!< in: index */ 2108 MY_ATTRIBUTE((warn_unused_result)); 2109 /*****************************************************************//** 2110 Get index by first field of the index 2111 @return index which is having first field matches 2112 with the field present in field_index position of table */ 2113 UNIV_INLINE 2114 dict_index_t* 2115 dict_table_get_index_on_first_col( 2116 /*==============================*/ 2117 const dict_table_t* table, /*!< in: table */ 2118 ulint col_index); /*!< in: position of column 2119 in table */ 2120 /** Check if a column is a virtual column 2121 @param[in] col column 2122 @return true if it is a virtual column, false otherwise */ 2123 UNIV_INLINE 2124 bool 2125 dict_col_is_virtual( 2126 const dict_col_t* col); 2127 2128 /** encode number of columns and number of virtual columns in one 2129 4 bytes value. We could do this because the number of columns in 2130 InnoDB is limited to 1017 2131 @param[in] n_col number of non-virtual column 2132 @param[in] n_v_col number of virtual column 2133 @return encoded value */ 2134 UNIV_INLINE 2135 ulint 2136 dict_table_encode_n_col( 2137 ulint n_col, 2138 ulint n_v_col); 2139 2140 /** Decode number of virtual and non-virtual columns in one 4 bytes value. 2141 @param[in] encoded encoded value 2142 @param[in,out] n_col number of non-virtual column 2143 @param[in,out] n_v_col number of virtual column */ 2144 UNIV_INLINE 2145 void 2146 dict_table_decode_n_col( 2147 ulint encoded, 2148 ulint* n_col, 2149 ulint* n_v_col); 2150 2151 /** Look for any dictionary objects that are found in the given tablespace. 2152 @param[in] space_id Tablespace ID to search for. 2153 @return true if tablespace is empty. */ 2154 bool 2155 dict_space_is_empty( 2156 ulint space_id); 2157 2158 /** Find the space_id for the given name in sys_tablespaces. 2159 @param[in] name Tablespace name to search for. 2160 @return the tablespace ID. */ 2161 ulint 2162 dict_space_get_id( 2163 const char* name); 2164 2165 /** Free the virtual column template 2166 @param[in,out] vc_templ virtual column template */ 2167 UNIV_INLINE 2168 void 2169 dict_free_vc_templ( 2170 dict_vcol_templ_t* vc_templ); 2171 2172 /** Check whether the table have virtual index. 2173 @param[in] table InnoDB table 2174 @return true if the table have virtual index, false otherwise. */ 2175 UNIV_INLINE 2176 bool 2177 dict_table_have_virtual_index( 2178 dict_table_t* table); 2179 2180 /** Allocate memory for intrinsic cache elements in the index 2181 * @param[in] index index object */ 2182 UNIV_INLINE 2183 void 2184 dict_allocate_mem_intrinsic_cache( 2185 dict_index_t* index); 2186 2187 /** Check whether the table is a partitioned table. 2188 @param[in] table Table to check. 2189 @return true if the table is a partitioned table else false. */ 2190 UNIV_INLINE 2191 bool 2192 dict_table_is_partition( 2193 const dict_table_t* table); 2194 2195 /** @return true if all base column of virtual column is foreign key column 2196 @param[in] vcol in-memory virtul column 2197 @param[in] foreign in-memory Foreign key constraint */ 2198 uint32_t dict_vcol_base_is_foreign_key(dict_v_col_t *vcol, dict_foreign_t *foreign); 2199 2200 #endif /* !UNIV_HOTBACKUP */ 2201 /************************************************************************* 2202 set is_corrupt flag by space_id*/ 2203 2204 void 2205 dict_table_set_corrupt_by_space( 2206 /*============================*/ 2207 ulint space_id, 2208 bool need_mutex); 2209 2210 /** Insert a records into SYS_ZIP_DICT. 2211 @retval DB_SUCCESS if OK 2212 @retval dberr_t if the insert failed */ 2213 dberr_t 2214 dict_create_zip_dict( 2215 const char* name, /*!< in: zip_dict name */ 2216 ulint name_len, /*!< in: zip_dict name length*/ 2217 const char* data, /*!< in: zip_dict data */ 2218 ulint data_len); /*!< in: zip_dict data length */ 2219 2220 /** Get single compression dictionary id for the given 2221 (table id, column pos) pair. 2222 @retval DB_SUCCESS if OK 2223 @retval DB_RECORD_NOT_FOUND if not found */ 2224 dberr_t 2225 dict_get_dictionary_id_by_key( 2226 table_id_t table_id, /*!< in: table id */ 2227 ulint column_pos, /*!< in: column position */ 2228 ulint* dict_id, /*!< out: zip_dict id */ 2229 bool dict_locked); /*!< in: true if data dictionary locked */ 2230 2231 2232 /** Get compression dictionary info (name and data) for the given id. 2233 Allocates memory in name->str and data->str on success. 2234 Must be freed with mem_free(). 2235 @retval DB_SUCCESS if OK 2236 @retval DB_RECORD_NOT_FOUND if not found */ 2237 dberr_t 2238 dict_get_dictionary_info_by_id( 2239 ulint dict_id, /*!< in: dictionary id */ 2240 char** name, /*!< out: dictionary name */ 2241 ulint* name_len, /*!< out: dictionary name length*/ 2242 char** data, /*!< out: dictionary data */ 2243 ulint* data_len, /*!< out: dictionary data length*/ 2244 bool dict_locked); /*!< in: true if data dictionary locked */ 2245 2246 /** Delete a record in SYS_ZIP_DICT with the given name. 2247 @retval DB_SUCCESS if OK 2248 @retval DB_RECORD_NOT_FOUND if not found 2249 @retval DB_ROW_IS_REFERENCED if in use */ 2250 dberr_t 2251 dict_drop_zip_dict( 2252 const char* name, /*!< in: zip_dict name */ 2253 ulint name_len); /*!< in: zip_dict name length*/ 2254 2255 #ifndef UNIV_NONINL 2256 #include "dict0dict.ic" 2257 #endif 2258 2259 #endif 2260