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