1 /***************************************************************************** 2 3 Copyright (c) 2000, 2017, Oracle and/or its affiliates. All Rights Reserved. 4 5 This program is free software; you can redistribute it and/or modify 6 it under the terms of the GNU General Public License, version 2.0, 7 as published by the Free Software Foundation. 8 9 This program is also distributed with certain software (including 10 but not limited to OpenSSL) that is licensed under separate terms, 11 as designated in a particular file or component or in included license 12 documentation. The authors of MySQL hereby grant you an additional 13 permission to link the program and your derivative works with the 14 separately licensed software that they have included with MySQL. 15 16 This program is distributed in the hope that it will be useful, 17 but WITHOUT ANY WARRANTY; without even the implied warranty of 18 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 19 GNU General Public License, version 2.0, for more details. 20 21 You should have received a copy of the GNU General Public License along with 22 this program; if not, write to the Free Software Foundation, Inc., 23 51 Franklin Street, Suite 500, Boston, MA 02110-1335 USA 24 25 *****************************************************************************/ 26 27 /**************************************************//** 28 @file include/row0mysql.h 29 Interface between Innobase row operations and MySQL. 30 Contains also create table and other data dictionary operations. 31 32 Created 9/17/2000 Heikki Tuuri 33 *******************************************************/ 34 35 #ifndef row0mysql_h 36 #define row0mysql_h 37 38 #include "univ.i" 39 #include "data0data.h" 40 #include "que0types.h" 41 #include "dict0types.h" 42 #include "trx0types.h" 43 #include "row0types.h" 44 #include "btr0pcur.h" 45 #include "trx0types.h" 46 47 // Forward declaration 48 struct SysIndexCallback; 49 50 extern ibool row_rollback_on_timeout; 51 52 struct row_prebuilt_t; 53 54 /*******************************************************************//** 55 Frees the blob heap in prebuilt when no longer needed. */ 56 UNIV_INTERN 57 void 58 row_mysql_prebuilt_free_blob_heap( 59 /*==============================*/ 60 row_prebuilt_t* prebuilt); /*!< in: prebuilt struct of a 61 ha_innobase:: table handle */ 62 /*******************************************************************//** 63 Stores a >= 5.0.3 format true VARCHAR length to dest, in the MySQL row 64 format. 65 @return pointer to the data, we skip the 1 or 2 bytes at the start 66 that are used to store the len */ 67 UNIV_INTERN 68 byte* 69 row_mysql_store_true_var_len( 70 /*=========================*/ 71 byte* dest, /*!< in: where to store */ 72 ulint len, /*!< in: length, must fit in two bytes */ 73 ulint lenlen);/*!< in: storage length of len: either 1 or 2 bytes */ 74 /*******************************************************************//** 75 Reads a >= 5.0.3 format true VARCHAR length, in the MySQL row format, and 76 returns a pointer to the data. 77 @return pointer to the data, we skip the 1 or 2 bytes at the start 78 that are used to store the len */ 79 UNIV_INTERN 80 const byte* 81 row_mysql_read_true_varchar( 82 /*========================*/ 83 ulint* len, /*!< out: variable-length field length */ 84 const byte* field, /*!< in: field in the MySQL format */ 85 ulint lenlen);/*!< in: storage length of len: either 1 86 or 2 bytes */ 87 /*******************************************************************//** 88 Stores a reference to a BLOB in the MySQL format. */ 89 UNIV_INTERN 90 void 91 row_mysql_store_blob_ref( 92 /*=====================*/ 93 byte* dest, /*!< in: where to store */ 94 ulint col_len,/*!< in: dest buffer size: determines into 95 how many bytes the BLOB length is stored, 96 the space for the length may vary from 1 97 to 4 bytes */ 98 const void* data, /*!< in: BLOB data; if the value to store 99 is SQL NULL this should be NULL pointer */ 100 ulint len); /*!< in: BLOB length; if the value to store 101 is SQL NULL this should be 0; remember 102 also to set the NULL bit in the MySQL record 103 header! */ 104 /*******************************************************************//** 105 Reads a reference to a BLOB in the MySQL format. 106 @return pointer to BLOB data */ 107 UNIV_INTERN 108 const byte* 109 row_mysql_read_blob_ref( 110 /*====================*/ 111 ulint* len, /*!< out: BLOB length */ 112 const byte* ref, /*!< in: BLOB reference in the 113 MySQL format */ 114 ulint col_len); /*!< in: BLOB reference length 115 (not BLOB length) */ 116 /**************************************************************//** 117 Pad a column with spaces. */ 118 UNIV_INTERN 119 void 120 row_mysql_pad_col( 121 /*==============*/ 122 ulint mbminlen, /*!< in: minimum size of a character, 123 in bytes */ 124 byte* pad, /*!< out: padded buffer */ 125 ulint len); /*!< in: number of bytes to pad */ 126 127 /**************************************************************//** 128 Stores a non-SQL-NULL field given in the MySQL format in the InnoDB format. 129 The counterpart of this function is row_sel_field_store_in_mysql_format() in 130 row0sel.cc. 131 @return up to which byte we used buf in the conversion */ 132 UNIV_INTERN 133 byte* 134 row_mysql_store_col_in_innobase_format( 135 /*===================================*/ 136 dfield_t* dfield, /*!< in/out: dfield where dtype 137 information must be already set when 138 this function is called! */ 139 byte* buf, /*!< in/out: buffer for a converted 140 integer value; this must be at least 141 col_len long then! NOTE that dfield 142 may also get a pointer to 'buf', 143 therefore do not discard this as long 144 as dfield is used! */ 145 ibool row_format_col, /*!< TRUE if the mysql_data is from 146 a MySQL row, FALSE if from a MySQL 147 key value; 148 in MySQL, a true VARCHAR storage 149 format differs in a row and in a 150 key value: in a key value the length 151 is always stored in 2 bytes! */ 152 const byte* mysql_data, /*!< in: MySQL column value, not 153 SQL NULL; NOTE that dfield may also 154 get a pointer to mysql_data, 155 therefore do not discard this as long 156 as dfield is used! */ 157 ulint col_len, /*!< in: MySQL column length; NOTE that 158 this is the storage length of the 159 column in the MySQL format row, not 160 necessarily the length of the actual 161 payload data; if the column is a true 162 VARCHAR then this is irrelevant */ 163 ulint comp); /*!< in: nonzero=compact format */ 164 /****************************************************************//** 165 Handles user errors and lock waits detected by the database engine. 166 @return true if it was a lock wait and we should continue running the 167 query thread */ 168 UNIV_INTERN 169 bool 170 row_mysql_handle_errors( 171 /*====================*/ 172 dberr_t* new_err,/*!< out: possible new error encountered in 173 rollback, or the old error which was 174 during the function entry */ 175 trx_t* trx, /*!< in: transaction */ 176 que_thr_t* thr, /*!< in: query thread, or NULL */ 177 trx_savept_t* savept) /*!< in: savepoint, or NULL */ 178 MY_ATTRIBUTE((nonnull(1,2))); 179 /********************************************************************//** 180 Create a prebuilt struct for a MySQL table handle. 181 @return own: a prebuilt struct */ 182 UNIV_INTERN 183 row_prebuilt_t* 184 row_create_prebuilt( 185 /*================*/ 186 dict_table_t* table, /*!< in: Innobase table handle */ 187 ulint mysql_row_len); /*!< in: length in bytes of a row in 188 the MySQL format */ 189 /********************************************************************//** 190 Free a prebuilt struct for a MySQL table handle. */ 191 UNIV_INTERN 192 void 193 row_prebuilt_free( 194 /*==============*/ 195 row_prebuilt_t* prebuilt, /*!< in, own: prebuilt struct */ 196 ibool dict_locked); /*!< in: TRUE=data dictionary locked */ 197 /*********************************************************************//** 198 Updates the transaction pointers in query graphs stored in the prebuilt 199 struct. */ 200 UNIV_INTERN 201 void 202 row_update_prebuilt_trx( 203 /*====================*/ 204 row_prebuilt_t* prebuilt, /*!< in/out: prebuilt struct 205 in MySQL handle */ 206 trx_t* trx); /*!< in: transaction handle */ 207 /*********************************************************************//** 208 Sets an AUTO_INC type lock on the table mentioned in prebuilt. The 209 AUTO_INC lock gives exclusive access to the auto-inc counter of the 210 table. The lock is reserved only for the duration of an SQL statement. 211 It is not compatible with another AUTO_INC or exclusive lock on the 212 table. 213 @return error code or DB_SUCCESS */ 214 UNIV_INTERN 215 dberr_t 216 row_lock_table_autoinc_for_mysql( 217 /*=============================*/ 218 row_prebuilt_t* prebuilt) /*!< in: prebuilt struct in the MySQL 219 table handle */ 220 MY_ATTRIBUTE((nonnull, warn_unused_result)); 221 /*********************************************************************//** 222 Sets a table lock on the table mentioned in prebuilt. 223 @return error code or DB_SUCCESS */ 224 UNIV_INTERN 225 dberr_t 226 row_lock_table_for_mysql( 227 /*=====================*/ 228 row_prebuilt_t* prebuilt, /*!< in: prebuilt struct in the MySQL 229 table handle */ 230 dict_table_t* table, /*!< in: table to lock, or NULL 231 if prebuilt->table should be 232 locked as 233 prebuilt->select_lock_type */ 234 ulint mode) /*!< in: lock mode of table 235 (ignored if table==NULL) */ 236 MY_ATTRIBUTE((nonnull(1))); 237 /*********************************************************************//** 238 Does an insert for MySQL. 239 @return error code or DB_SUCCESS */ 240 UNIV_INTERN 241 dberr_t 242 row_insert_for_mysql( 243 /*=================*/ 244 byte* mysql_rec, /*!< in: row in the MySQL format */ 245 row_prebuilt_t* prebuilt) /*!< in: prebuilt struct in MySQL 246 handle */ 247 MY_ATTRIBUTE((nonnull, warn_unused_result)); 248 /*********************************************************************//** 249 Builds a dummy query graph used in selects. */ 250 UNIV_INTERN 251 void 252 row_prebuild_sel_graph( 253 /*===================*/ 254 row_prebuilt_t* prebuilt); /*!< in: prebuilt struct in MySQL 255 handle */ 256 /*********************************************************************//** 257 Gets pointer to a prebuilt update vector used in updates. If the update 258 graph has not yet been built in the prebuilt struct, then this function 259 first builds it. 260 @return prebuilt update vector */ 261 UNIV_INTERN 262 upd_t* 263 row_get_prebuilt_update_vector( 264 /*===========================*/ 265 row_prebuilt_t* prebuilt); /*!< in: prebuilt struct in MySQL 266 handle */ 267 /*********************************************************************//** 268 Checks if a table is such that we automatically created a clustered 269 index on it (on row id). 270 @return TRUE if the clustered index was generated automatically */ 271 UNIV_INTERN 272 ibool 273 row_table_got_default_clust_index( 274 /*==============================*/ 275 const dict_table_t* table); /*!< in: table */ 276 /*********************************************************************//** 277 Does an update or delete of a row for MySQL. 278 @return error code or DB_SUCCESS */ 279 UNIV_INTERN 280 dberr_t 281 row_update_for_mysql( 282 /*=================*/ 283 byte* mysql_rec, /*!< in: the row to be updated, in 284 the MySQL format */ 285 row_prebuilt_t* prebuilt) /*!< in: prebuilt struct in MySQL 286 handle */ 287 MY_ATTRIBUTE((nonnull, warn_unused_result)); 288 /*********************************************************************//** 289 This can only be used when srv_locks_unsafe_for_binlog is TRUE or this 290 session is using a READ COMMITTED or READ UNCOMMITTED isolation level. 291 Before calling this function row_search_for_mysql() must have 292 initialized prebuilt->new_rec_locks to store the information which new 293 record locks really were set. This function removes a newly set 294 clustered index record lock under prebuilt->pcur or 295 prebuilt->clust_pcur. Thus, this implements a 'mini-rollback' that 296 releases the latest clustered index record lock we set. */ 297 UNIV_INTERN 298 void 299 row_unlock_for_mysql( 300 /*=================*/ 301 row_prebuilt_t* prebuilt, /*!< in/out: prebuilt struct in MySQL 302 handle */ 303 ibool has_latches_on_recs)/*!< in: TRUE if called 304 so that we have the latches on 305 the records under pcur and 306 clust_pcur, and we do not need 307 to reposition the cursors. */ 308 MY_ATTRIBUTE((nonnull)); 309 /*********************************************************************//** 310 Checks if a table name contains the string "/#sql" which denotes temporary 311 tables in MySQL. 312 @return true if temporary table */ 313 UNIV_INTERN 314 bool 315 row_is_mysql_tmp_table_name( 316 /*========================*/ 317 const char* name) MY_ATTRIBUTE((warn_unused_result)); 318 /*!< in: table name in the form 319 'database/tablename' */ 320 321 /*********************************************************************//** 322 Creates an query graph node of 'update' type to be used in the MySQL 323 interface. 324 @return own: update node */ 325 UNIV_INTERN 326 upd_node_t* 327 row_create_update_node_for_mysql( 328 /*=============================*/ 329 dict_table_t* table, /*!< in: table to update */ 330 mem_heap_t* heap); /*!< in: mem heap from which allocated */ 331 /**********************************************************************//** 332 Does a cascaded delete or set null in a foreign key operation. 333 @return error code or DB_SUCCESS */ 334 UNIV_INTERN 335 dberr_t 336 row_update_cascade_for_mysql( 337 /*=========================*/ 338 que_thr_t* thr, /*!< in: query thread */ 339 upd_node_t* node, /*!< in: update node used in the cascade 340 or set null operation */ 341 dict_table_t* table) /*!< in: table where we do the operation */ 342 MY_ATTRIBUTE((nonnull, warn_unused_result)); 343 /*********************************************************************//** 344 Locks the data dictionary exclusively for performing a table create or other 345 data dictionary modification operation. */ 346 UNIV_INTERN 347 void 348 row_mysql_lock_data_dictionary_func( 349 /*================================*/ 350 trx_t* trx, /*!< in/out: transaction */ 351 const char* file, /*!< in: file name */ 352 ulint line); /*!< in: line number */ 353 #define row_mysql_lock_data_dictionary(trx) \ 354 row_mysql_lock_data_dictionary_func(trx, __FILE__, __LINE__) 355 /*********************************************************************//** 356 Unlocks the data dictionary exclusive lock. */ 357 UNIV_INTERN 358 void 359 row_mysql_unlock_data_dictionary( 360 /*=============================*/ 361 trx_t* trx); /*!< in/out: transaction */ 362 /*********************************************************************//** 363 Locks the data dictionary in shared mode from modifications, for performing 364 foreign key check, rollback, or other operation invisible to MySQL. */ 365 UNIV_INTERN 366 void 367 row_mysql_freeze_data_dictionary_func( 368 /*==================================*/ 369 trx_t* trx, /*!< in/out: transaction */ 370 const char* file, /*!< in: file name */ 371 ulint line); /*!< in: line number */ 372 #define row_mysql_freeze_data_dictionary(trx) \ 373 row_mysql_freeze_data_dictionary_func(trx, __FILE__, __LINE__) 374 /*********************************************************************//** 375 Unlocks the data dictionary shared lock. */ 376 UNIV_INTERN 377 void 378 row_mysql_unfreeze_data_dictionary( 379 /*===============================*/ 380 trx_t* trx); /*!< in/out: transaction */ 381 /*********************************************************************//** 382 Creates a table for MySQL. If the name of the table ends in 383 one of "innodb_monitor", "innodb_lock_monitor", "innodb_tablespace_monitor", 384 "innodb_table_monitor", then this will also start the printing of monitor 385 output by the master thread. If the table name ends in "innodb_mem_validate", 386 InnoDB will try to invoke mem_validate(). On failure the transaction will 387 be rolled back. 388 @return error code or DB_SUCCESS */ 389 UNIV_INTERN 390 dberr_t 391 row_create_table_for_mysql( 392 /*=======================*/ 393 dict_table_t* table, /*!< in, own: table definition 394 (will be freed, or on DB_SUCCESS 395 added to the data dictionary cache) */ 396 trx_t* trx, /*!< in/out: transaction */ 397 bool commit) /*!< in: if true, commit the transaction */ 398 MY_ATTRIBUTE((nonnull, warn_unused_result)); 399 /*********************************************************************//** 400 Does an index creation operation for MySQL. TODO: currently failure 401 to create an index results in dropping the whole table! This is no problem 402 currently as all indexes must be created at the same time as the table. 403 @return error number or DB_SUCCESS */ 404 UNIV_INTERN 405 dberr_t 406 row_create_index_for_mysql( 407 /*=======================*/ 408 dict_index_t* index, /*!< in, own: index definition 409 (will be freed) */ 410 trx_t* trx, /*!< in: transaction handle */ 411 const ulint* field_lengths) /*!< in: if not NULL, must contain 412 dict_index_get_n_fields(index) 413 actual field lengths for the 414 index columns, which are 415 then checked for not being too 416 large. */ 417 MY_ATTRIBUTE((nonnull(1,2), warn_unused_result)); 418 /*********************************************************************//** 419 Scans a table create SQL string and adds to the data dictionary 420 the foreign key constraints declared in the string. This function 421 should be called after the indexes for a table have been created. 422 Each foreign key constraint must be accompanied with indexes in 423 bot participating tables. The indexes are allowed to contain more 424 fields than mentioned in the constraint. 425 @return error code or DB_SUCCESS */ 426 UNIV_INTERN 427 dberr_t 428 row_table_add_foreign_constraints( 429 /*==============================*/ 430 trx_t* trx, /*!< in: transaction */ 431 const char* sql_string, /*!< in: table create statement where 432 foreign keys are declared like: 433 FOREIGN KEY (a, b) REFERENCES table2(c, d), 434 table2 can be written also with the 435 database name before it: test.table2 */ 436 size_t sql_length, /*!< in: length of sql_string */ 437 const char* name, /*!< in: table full name in the 438 normalized form 439 database_name/table_name */ 440 ibool reject_fks) /*!< in: if TRUE, fail with error 441 code DB_CANNOT_ADD_CONSTRAINT if 442 any foreign keys are found. */ 443 MY_ATTRIBUTE((nonnull, warn_unused_result)); 444 /*********************************************************************//** 445 The master thread in srv0srv.cc calls this regularly to drop tables which 446 we must drop in background after queries to them have ended. Such lazy 447 dropping of tables is needed in ALTER TABLE on Unix. 448 @return how many tables dropped + remaining tables in list */ 449 UNIV_INTERN 450 ulint 451 row_drop_tables_for_mysql_in_background(void); 452 /*=========================================*/ 453 /*********************************************************************//** 454 Get the background drop list length. NOTE: the caller must own the kernel 455 mutex! 456 @return how many tables in list */ 457 UNIV_INTERN 458 ulint 459 row_get_background_drop_list_len_low(void); 460 /*======================================*/ 461 /*********************************************************************//** 462 Sets an exclusive lock on a table. 463 @return error code or DB_SUCCESS */ 464 UNIV_INTERN 465 dberr_t 466 row_mysql_lock_table( 467 /*=================*/ 468 trx_t* trx, /*!< in/out: transaction */ 469 dict_table_t* table, /*!< in: table to lock */ 470 enum lock_mode mode, /*!< in: LOCK_X or LOCK_S */ 471 const char* op_info) /*!< in: string for trx->op_info */ 472 MY_ATTRIBUTE((nonnull, warn_unused_result)); 473 474 /*********************************************************************//** 475 Truncates a table for MySQL. 476 @return error code or DB_SUCCESS */ 477 UNIV_INTERN 478 dberr_t 479 row_truncate_table_for_mysql( 480 /*=========================*/ 481 dict_table_t* table, /*!< in: table handle */ 482 trx_t* trx) /*!< in: transaction handle */ 483 MY_ATTRIBUTE((nonnull, warn_unused_result)); 484 /*********************************************************************//** 485 Drops a table for MySQL. If the name of the dropped table ends in 486 one of "innodb_monitor", "innodb_lock_monitor", "innodb_tablespace_monitor", 487 "innodb_table_monitor", then this will also stop the printing of monitor 488 output by the master thread. If the data dictionary was not already locked 489 by the transaction, the transaction will be committed. Otherwise, the 490 data dictionary will remain locked. 491 @return error code or DB_SUCCESS */ 492 UNIV_INTERN 493 dberr_t 494 row_drop_table_for_mysql( 495 /*=====================*/ 496 const char* name, /*!< in: table name */ 497 trx_t* trx, /*!< in: dictionary transaction handle */ 498 bool drop_db,/*!< in: true=dropping whole database */ 499 bool nonatomic = true) 500 /*!< in: whether it is permitted 501 to release and reacquire dict_operation_lock */ 502 MY_ATTRIBUTE((nonnull)); 503 /*********************************************************************//** 504 Drop all temporary tables during crash recovery. */ 505 UNIV_INTERN 506 void 507 row_mysql_drop_temp_tables(void); 508 /*============================*/ 509 510 /*********************************************************************//** 511 Discards the tablespace of a table which stored in an .ibd file. Discarding 512 means that this function deletes the .ibd file and assigns a new table id for 513 the table. Also the flag table->ibd_file_missing is set TRUE. 514 @return error code or DB_SUCCESS */ 515 UNIV_INTERN 516 dberr_t 517 row_discard_tablespace_for_mysql( 518 /*=============================*/ 519 const char* name, /*!< in: table name */ 520 trx_t* trx) /*!< in: transaction handle */ 521 MY_ATTRIBUTE((nonnull, warn_unused_result)); 522 /*****************************************************************//** 523 Imports a tablespace. The space id in the .ibd file must match the space id 524 of the table in the data dictionary. 525 @return error code or DB_SUCCESS */ 526 UNIV_INTERN 527 dberr_t 528 row_import_tablespace_for_mysql( 529 /*============================*/ 530 dict_table_t* table, /*!< in/out: table */ 531 row_prebuilt_t* prebuilt) /*!< in: prebuilt struct in MySQL */ 532 MY_ATTRIBUTE((nonnull, warn_unused_result)); 533 /*********************************************************************//** 534 Drops a database for MySQL. 535 @return error code or DB_SUCCESS */ 536 UNIV_INTERN 537 dberr_t 538 row_drop_database_for_mysql( 539 /*========================*/ 540 const char* name, /*!< in: database name which ends to '/' */ 541 trx_t* trx) /*!< in: transaction handle */ 542 MY_ATTRIBUTE((nonnull)); 543 /*********************************************************************//** 544 Renames a table for MySQL. 545 @return error code or DB_SUCCESS */ 546 UNIV_INTERN 547 dberr_t 548 row_rename_table_for_mysql( 549 /*=======================*/ 550 const char* old_name, /*!< in: old table name */ 551 const char* new_name, /*!< in: new table name */ 552 trx_t* trx, /*!< in/out: transaction */ 553 bool commit) /*!< in: whether to commit trx */ 554 MY_ATTRIBUTE((nonnull, warn_unused_result)); 555 /*********************************************************************//** 556 Checks that the index contains entries in an ascending order, unique 557 constraint is not broken, and calculates the number of index entries 558 in the read view of the current transaction. 559 @return true if ok */ 560 UNIV_INTERN 561 bool 562 row_check_index_for_mysql( 563 /*======================*/ 564 row_prebuilt_t* prebuilt, /*!< in: prebuilt struct 565 in MySQL handle */ 566 const dict_index_t* index, /*!< in: index */ 567 ulint* n_rows) /*!< out: number of entries 568 seen in the consistent read */ 569 MY_ATTRIBUTE((nonnull, warn_unused_result)); 570 /*********************************************************************//** 571 Determines if a table is a magic monitor table. 572 @return true if monitor table */ 573 UNIV_INTERN 574 bool 575 row_is_magic_monitor_table( 576 /*=======================*/ 577 const char* table_name) /*!< in: name of the table, in the 578 form database/table_name */ 579 MY_ATTRIBUTE((nonnull, warn_unused_result)); 580 /*********************************************************************//** 581 Initialize this module */ 582 UNIV_INTERN 583 void 584 row_mysql_init(void); 585 /*================*/ 586 587 /*********************************************************************//** 588 Close this module */ 589 UNIV_INTERN 590 void 591 row_mysql_close(void); 592 /*=================*/ 593 594 /*********************************************************************//** 595 Reassigns the table identifier of a table. 596 @return error code or DB_SUCCESS */ 597 UNIV_INTERN 598 dberr_t 599 row_mysql_table_id_reassign( 600 /*========================*/ 601 dict_table_t* table, /*!< in/out: table */ 602 trx_t* trx, /*!< in/out: transaction */ 603 table_id_t* new_id) /*!< out: new table id */ 604 MY_ATTRIBUTE((nonnull, warn_unused_result)); 605 606 /* A struct describing a place for an individual column in the MySQL 607 row format which is presented to the table handler in ha_innobase. 608 This template struct is used to speed up row transformations between 609 Innobase and MySQL. */ 610 611 struct mysql_row_templ_t { 612 ulint col_no; /*!< column number of the column */ 613 ulint rec_field_no; /*!< field number of the column in an 614 Innobase record in the current index; 615 not defined if template_type is 616 ROW_MYSQL_WHOLE_ROW */ 617 ulint clust_rec_field_no; /*!< field number of the column in an 618 Innobase record in the clustered index; 619 not defined if template_type is 620 ROW_MYSQL_WHOLE_ROW */ 621 ulint icp_rec_field_no; /*!< field number of the column in an 622 Innobase record in the current index; 623 not defined unless 624 index condition pushdown is used */ 625 ulint mysql_col_offset; /*!< offset of the column in the MySQL 626 row format */ 627 ulint mysql_col_len; /*!< length of the column in the MySQL 628 row format */ 629 ulint mysql_null_byte_offset; /*!< MySQL NULL bit byte offset in a 630 MySQL record */ 631 ulint mysql_null_bit_mask; /*!< bit mask to get the NULL bit, 632 zero if column cannot be NULL */ 633 ulint type; /*!< column type in Innobase mtype 634 numbers DATA_CHAR... */ 635 ulint mysql_type; /*!< MySQL type code; this is always 636 < 256 */ 637 ulint mysql_length_bytes; /*!< if mysql_type 638 == DATA_MYSQL_TRUE_VARCHAR, this tells 639 whether we should use 1 or 2 bytes to 640 store the MySQL true VARCHAR data 641 length at the start of row in the MySQL 642 format (NOTE that the MySQL key value 643 format always uses 2 bytes for the data 644 len) */ 645 ulint charset; /*!< MySQL charset-collation code 646 of the column, or zero */ 647 ulint mbminlen; /*!< minimum length of a char, in bytes, 648 or zero if not a char type */ 649 ulint mbmaxlen; /*!< maximum length of a char, in bytes, 650 or zero if not a char type */ 651 ulint is_unsigned; /*!< if a column type is an integer 652 type and this field is != 0, then 653 it is an unsigned integer type */ 654 }; 655 656 #define MYSQL_FETCH_CACHE_SIZE 8 657 /* After fetching this many rows, we start caching them in fetch_cache */ 658 #define MYSQL_FETCH_CACHE_THRESHOLD 4 659 660 #define ROW_PREBUILT_ALLOCATED 78540783 661 #define ROW_PREBUILT_FREED 26423527 662 663 class ha_innobase; 664 665 /** A struct for (sometimes lazily) prebuilt structures in an Innobase table 666 handle used within MySQL; these are used to save CPU time. */ 667 668 struct row_prebuilt_t { 669 ulint magic_n; /*!< this magic number is set to 670 ROW_PREBUILT_ALLOCATED when created, 671 or ROW_PREBUILT_FREED when the 672 struct has been freed */ 673 dict_table_t* table; /*!< Innobase table handle */ 674 dict_index_t* index; /*!< current index for a search, if 675 any */ 676 trx_t* trx; /*!< current transaction handle */ 677 unsigned sql_stat_start:1;/*!< TRUE when we start processing of 678 an SQL statement: we may have to set 679 an intention lock on the table, 680 create a consistent read view etc. */ 681 unsigned mysql_has_locked:1;/*!< this is set TRUE when MySQL 682 calls external_lock on this handle 683 with a lock flag, and set FALSE when 684 with the F_UNLOCK flag */ 685 unsigned clust_index_was_generated:1; 686 /*!< if the user did not define a 687 primary key in MySQL, then Innobase 688 automatically generated a clustered 689 index where the ordering column is 690 the row id: in this case this flag 691 is set to TRUE */ 692 unsigned index_usable:1; /*!< caches the value of 693 row_merge_is_index_usable(trx,index) */ 694 unsigned read_just_key:1;/*!< set to 1 when MySQL calls 695 ha_innobase::extra with the 696 argument HA_EXTRA_KEYREAD; it is enough 697 to read just columns defined in 698 the index (i.e., no read of the 699 clustered index record necessary) */ 700 unsigned used_in_HANDLER:1;/*!< TRUE if we have been using this 701 handle in a MySQL HANDLER low level 702 index cursor command: then we must 703 store the pcur position even in a 704 unique search from a clustered index, 705 because HANDLER allows NEXT and PREV 706 in such a situation */ 707 unsigned template_type:2;/*!< ROW_MYSQL_WHOLE_ROW, 708 ROW_MYSQL_REC_FIELDS, 709 ROW_MYSQL_DUMMY_TEMPLATE, or 710 ROW_MYSQL_NO_TEMPLATE */ 711 unsigned n_template:10; /*!< number of elements in the 712 template */ 713 unsigned null_bitmap_len:10;/*!< number of bytes in the SQL NULL 714 bitmap at the start of a row in the 715 MySQL format */ 716 unsigned need_to_access_clustered:1; /*!< if we are fetching 717 columns through a secondary index 718 and at least one column is not in 719 the secondary index, then this is 720 set to TRUE */ 721 unsigned templ_contains_blob:1;/*!< TRUE if the template contains 722 a column with DATA_BLOB == 723 get_innobase_type_from_mysql_type(); 724 not to be confused with InnoDB 725 externally stored columns 726 (VARCHAR can be off-page too) */ 727 mysql_row_templ_t* mysql_template;/*!< template used to transform 728 rows fast between MySQL and Innobase 729 formats; memory for this template 730 is not allocated from 'heap' */ 731 mem_heap_t* heap; /*!< memory heap from which 732 these auxiliary structures are 733 allocated when needed */ 734 mem_heap_t* cursor_heap; /*!< memory heap from which 735 innodb_api_buf is allocated per session*/ 736 ins_node_t* ins_node; /*!< Innobase SQL insert node 737 used to perform inserts 738 to the table */ 739 byte* ins_upd_rec_buff;/*!< buffer for storing data converted 740 to the Innobase format from the MySQL 741 format */ 742 const byte* default_rec; /*!< the default values of all columns 743 (a "default row") in MySQL format */ 744 ulint hint_need_to_fetch_extra_cols; 745 /*!< normally this is set to 0; if this 746 is set to ROW_RETRIEVE_PRIMARY_KEY, 747 then we should at least retrieve all 748 columns in the primary key; if this 749 is set to ROW_RETRIEVE_ALL_COLS, then 750 we must retrieve all columns in the 751 key (if read_just_key == 1), or all 752 columns in the table */ 753 upd_node_t* upd_node; /*!< Innobase SQL update node used 754 to perform updates and deletes */ 755 trx_id_t trx_id; /*!< The table->def_trx_id when 756 ins_graph was built */ 757 que_fork_t* ins_graph; /*!< Innobase SQL query graph used 758 in inserts. Will be rebuilt on 759 trx_id or n_indexes mismatch. */ 760 que_fork_t* upd_graph; /*!< Innobase SQL query graph used 761 in updates or deletes */ 762 btr_pcur_t pcur; /*!< persistent cursor used in selects 763 and updates */ 764 btr_pcur_t clust_pcur; /*!< persistent cursor used in 765 some selects and updates */ 766 que_fork_t* sel_graph; /*!< dummy query graph used in 767 selects */ 768 dtuple_t* search_tuple; /*!< prebuilt dtuple used in selects */ 769 byte row_id[DATA_ROW_ID_LEN]; 770 /*!< if the clustered index was 771 generated, the row id of the 772 last row fetched is stored 773 here */ 774 doc_id_t fts_doc_id; /* if the table has an FTS index on 775 it then we fetch the doc_id. 776 FTS-FIXME: Currently we fetch it always 777 but in the future we must only fetch 778 it when FTS columns are being 779 updated */ 780 dtuple_t* clust_ref; /*!< prebuilt dtuple used in 781 sel/upd/del */ 782 ulint select_lock_type;/*!< LOCK_NONE, LOCK_S, or LOCK_X */ 783 ulint stored_select_lock_type;/*!< this field is used to 784 remember the original select_lock_type 785 that was decided in ha_innodb.cc, 786 ::store_lock(), ::external_lock(), 787 etc. */ 788 ulint row_read_type; /*!< ROW_READ_WITH_LOCKS if row locks 789 should be the obtained for records 790 under an UPDATE or DELETE cursor. 791 If innodb_locks_unsafe_for_binlog 792 is TRUE, this can be set to 793 ROW_READ_TRY_SEMI_CONSISTENT, so that 794 if the row under an UPDATE or DELETE 795 cursor was locked by another 796 transaction, InnoDB will resort 797 to reading the last committed value 798 ('semi-consistent read'). Then, 799 this field will be set to 800 ROW_READ_DID_SEMI_CONSISTENT to 801 indicate that. If the row does not 802 match the WHERE condition, MySQL will 803 invoke handler::unlock_row() to 804 clear the flag back to 805 ROW_READ_TRY_SEMI_CONSISTENT and 806 to simply skip the row. If 807 the row matches, the next call to 808 row_search_for_mysql() will lock 809 the row. 810 This eliminates lock waits in some 811 cases; note that this breaks 812 serializability. */ 813 ulint new_rec_locks; /*!< normally 0; if 814 srv_locks_unsafe_for_binlog is 815 TRUE or session is using READ 816 COMMITTED or READ UNCOMMITTED 817 isolation level, set in 818 row_search_for_mysql() if we set a new 819 record lock on the secondary 820 or clustered index; this is 821 used in row_unlock_for_mysql() 822 when releasing the lock under 823 the cursor if we determine 824 after retrieving the row that 825 it does not need to be locked 826 ('mini-rollback') */ 827 ulint mysql_prefix_len;/*!< byte offset of the end of 828 the last requested column */ 829 ulint mysql_row_len; /*!< length in bytes of a row in the 830 MySQL format */ 831 ulint n_rows_fetched; /*!< number of rows fetched after 832 positioning the current cursor */ 833 ulint fetch_direction;/*!< ROW_SEL_NEXT or ROW_SEL_PREV */ 834 byte* fetch_cache[MYSQL_FETCH_CACHE_SIZE]; 835 /*!< a cache for fetched rows if we 836 fetch many rows from the same cursor: 837 it saves CPU time to fetch them in a 838 batch; we reserve mysql_row_len 839 bytes for each such row; these 840 pointers point 4 bytes past the 841 allocated mem buf start, because 842 there is a 4 byte magic number at the 843 start and at the end */ 844 ibool keep_other_fields_on_keyread; /*!< when using fetch 845 cache with HA_EXTRA_KEYREAD, don't 846 overwrite other fields in mysql row 847 row buffer.*/ 848 ulint fetch_cache_first;/*!< position of the first not yet 849 fetched row in fetch_cache */ 850 ulint n_fetch_cached; /*!< number of not yet fetched rows 851 in fetch_cache */ 852 mem_heap_t* blob_heap; /*!< in SELECTS BLOB fields are copied 853 to this heap */ 854 mem_heap_t* old_vers_heap; /*!< memory heap where a previous 855 version is built in consistent read */ 856 bool in_fts_query; /*!< Whether we are in a FTS query */ 857 /*----------------------*/ 858 ulonglong autoinc_last_value; 859 /*!< last value of AUTO-INC interval */ 860 ulonglong autoinc_increment;/*!< The increment step of the auto 861 increment column. Value must be 862 greater than or equal to 1. Required to 863 calculate the next value */ 864 ulonglong autoinc_offset; /*!< The offset passed to 865 get_auto_increment() by MySQL. Required 866 to calculate the next value */ 867 dberr_t autoinc_error; /*!< The actual error code encountered 868 while trying to init or read the 869 autoinc value from the table. We 870 store it here so that we can return 871 it to MySQL */ 872 /*----------------------*/ 873 void* idx_cond; /*!< In ICP, pointer to a ha_innobase, 874 passed to innobase_index_cond(). 875 NULL if index condition pushdown is 876 not used. */ 877 ulint idx_cond_n_cols;/*!< Number of fields in idx_cond_cols. 878 0 if and only if idx_cond == NULL. */ 879 /*----------------------*/ 880 ulint magic_n2; /*!< this should be the same as 881 magic_n */ 882 /*----------------------*/ 883 unsigned innodb_api:1; /*!< whether this is a InnoDB API 884 query */ 885 const rec_t* innodb_api_rec; /*!< InnoDB API search result */ 886 void* innodb_api_buf; /*!< Buffer holding copy of the physical 887 Innodb API search record */ 888 ulint innodb_api_rec_size; /*!< Size of the Innodb API record */ 889 byte* srch_key_val1; /*!< buffer used in converting 890 search key values from MySQL format 891 to InnoDB format.*/ 892 byte* srch_key_val2; /*!< buffer used in converting 893 search key values from MySQL format 894 to InnoDB format.*/ 895 uint srch_key_val_len; /*!< Size of search key */ 896 897 /** MySQL handler object. */ 898 ha_innobase* mysql_handler; 899 900 /** True if exceeded the end_range while filling the prefetch cache. */ 901 bool end_range; 902 903 }; 904 905 /** Callback for row_mysql_sys_index_iterate() */ 906 struct SysIndexCallback { ~SysIndexCallbackSysIndexCallback907 virtual ~SysIndexCallback() { } 908 909 /** Callback method 910 @param mtr - current mini transaction 911 @param pcur - persistent cursor. */ 912 virtual void operator()(mtr_t* mtr, btr_pcur_t* pcur) throw() = 0; 913 }; 914 915 #define ROW_PREBUILT_FETCH_MAGIC_N 465765687 916 917 #define ROW_MYSQL_WHOLE_ROW 0 918 #define ROW_MYSQL_REC_FIELDS 1 919 #define ROW_MYSQL_NO_TEMPLATE 2 920 #define ROW_MYSQL_DUMMY_TEMPLATE 3 /* dummy template used in 921 row_scan_and_check_index */ 922 923 /* Values for hint_need_to_fetch_extra_cols */ 924 #define ROW_RETRIEVE_PRIMARY_KEY 1 925 #define ROW_RETRIEVE_ALL_COLS 2 926 927 /* Values for row_read_type */ 928 #define ROW_READ_WITH_LOCKS 0 929 #define ROW_READ_TRY_SEMI_CONSISTENT 1 930 #define ROW_READ_DID_SEMI_CONSISTENT 2 931 932 #ifndef UNIV_NONINL 933 #include "row0mysql.ic" 934 #endif 935 936 #endif /* row0mysql.h */ 937