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