1 /***************************************************************************** 2 3 Copyright (c) 1996, 2018, Oracle and/or its affiliates. All Rights Reserved. 4 Copyright (c) 2017, 2020, 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/row0upd.h 22 Update of a row 23 24 Created 12/27/1996 Heikki Tuuri 25 *******************************************************/ 26 27 #ifndef row0upd_h 28 #define row0upd_h 29 30 #include "data0data.h" 31 #include "rem0types.h" 32 #include "row0types.h" 33 #include "btr0types.h" 34 #include "trx0types.h" 35 #include "btr0pcur.h" 36 #include "que0types.h" 37 #include "pars0types.h" 38 39 /*********************************************************************//** 40 Creates an update vector object. 41 @return own: update vector object */ 42 UNIV_INLINE 43 upd_t* 44 upd_create( 45 /*=======*/ 46 ulint n, /*!< in: number of fields */ 47 mem_heap_t* heap); /*!< in: heap from which memory allocated */ 48 /*********************************************************************//** 49 Returns the number of fields in the update vector == number of columns 50 to be updated by an update vector. 51 @return number of fields */ 52 UNIV_INLINE 53 ulint 54 upd_get_n_fields( 55 /*=============*/ 56 const upd_t* update); /*!< in: update vector */ 57 #ifdef UNIV_DEBUG 58 /*********************************************************************//** 59 Returns the nth field of an update vector. 60 @return update vector field */ 61 UNIV_INLINE 62 upd_field_t* 63 upd_get_nth_field( 64 /*==============*/ 65 const upd_t* update, /*!< in: update vector */ 66 ulint n); /*!< in: field position in update vector */ 67 #else 68 # define upd_get_nth_field(update, n) ((update)->fields + (n)) 69 #endif 70 71 /*********************************************************************//** 72 Sets an index field number to be updated by an update vector field. */ 73 UNIV_INLINE 74 void 75 upd_field_set_field_no( 76 /*===================*/ 77 upd_field_t* upd_field, /*!< in: update vector field */ 78 ulint field_no, /*!< in: field number in a clustered 79 index */ 80 dict_index_t* index); 81 82 /** set field number to a update vector field, marks this field is updated 83 @param[in,out] upd_field update vector field 84 @param[in] field_no virtual column sequence num 85 @param[in] index index */ 86 UNIV_INLINE 87 void 88 upd_field_set_v_field_no( 89 upd_field_t* upd_field, 90 ulint field_no, 91 dict_index_t* index); 92 /*********************************************************************//** 93 Returns a field of an update vector by field_no. 94 @return update vector field, or NULL */ 95 UNIV_INLINE 96 const upd_field_t* 97 upd_get_field_by_field_no( 98 /*======================*/ 99 const upd_t* update, /*!< in: update vector */ 100 ulint no, /*!< in: field_no */ 101 bool is_virtual) /*!< in: if it is a virtual column */ 102 MY_ATTRIBUTE((warn_unused_result)); 103 /*********************************************************************//** 104 Writes into the redo log the values of trx id and roll ptr and enough info 105 to determine their positions within a clustered index record. 106 @return new pointer to mlog */ 107 byte* 108 row_upd_write_sys_vals_to_log( 109 /*==========================*/ 110 dict_index_t* index, /*!< in: clustered index */ 111 trx_id_t trx_id, /*!< in: transaction id */ 112 roll_ptr_t roll_ptr,/*!< in: roll ptr of the undo log record */ 113 byte* log_ptr,/*!< pointer to a buffer of size > 20 opened 114 in mlog */ 115 mtr_t* mtr); /*!< in: mtr */ 116 /*********************************************************************//** 117 Updates the trx id and roll ptr field in a clustered index record when 118 a row is updated or marked deleted. */ 119 UNIV_INLINE 120 void 121 row_upd_rec_sys_fields( 122 /*===================*/ 123 rec_t* rec, /*!< in/out: record */ 124 page_zip_des_t* page_zip,/*!< in/out: compressed page whose 125 uncompressed part will be updated, or NULL */ 126 dict_index_t* index, /*!< in: clustered index */ 127 const rec_offs* offsets,/*!< in: rec_get_offsets(rec, index) */ 128 const trx_t* trx, /*!< in: transaction */ 129 roll_ptr_t roll_ptr);/*!< in: DB_ROLL_PTR to the undo log */ 130 /*********************************************************************//** 131 Sets the trx id or roll ptr field of a clustered index entry. */ 132 void 133 row_upd_index_entry_sys_field( 134 /*==========================*/ 135 dtuple_t* entry, /*!< in/out: index entry, where the memory 136 buffers for sys fields are already allocated: 137 the function just copies the new values to 138 them */ 139 dict_index_t* index, /*!< in: clustered index */ 140 ulint type, /*!< in: DATA_TRX_ID or DATA_ROLL_PTR */ 141 ib_uint64_t val); /*!< in: value to write */ 142 /*********************************************************************//** 143 Creates an update node for a query graph. 144 @return own: update node */ 145 upd_node_t* 146 upd_node_create( 147 /*============*/ 148 mem_heap_t* heap); /*!< in: mem heap where created */ 149 /***********************************************************//** 150 Writes to the redo log the new values of the fields occurring in the index. */ 151 void 152 row_upd_index_write_log( 153 /*====================*/ 154 const upd_t* update, /*!< in: update vector */ 155 byte* log_ptr,/*!< in: pointer to mlog buffer: must 156 contain at least MLOG_BUF_MARGIN bytes 157 of free space; the buffer is closed 158 within this function */ 159 mtr_t* mtr); /*!< in: mtr into whose log to write */ 160 /***********************************************************//** 161 Returns TRUE if row update changes size of some field in index or if some 162 field to be updated is stored externally in rec or update. 163 @return TRUE if the update changes the size of some field in index or 164 the field is external in rec or update */ 165 ibool 166 row_upd_changes_field_size_or_external( 167 /*===================================*/ 168 dict_index_t* index, /*!< in: index */ 169 const rec_offs* offsets,/*!< in: rec_get_offsets(rec, index) */ 170 const upd_t* update);/*!< in: update vector */ 171 /***********************************************************//** 172 Returns true if row update contains disowned external fields. 173 @return true if the update contains disowned external fields. */ 174 bool 175 row_upd_changes_disowned_external( 176 /*==============================*/ 177 const upd_t* update) /*!< in: update vector */ 178 MY_ATTRIBUTE((nonnull, warn_unused_result)); 179 /***********************************************************//** 180 Replaces the new column values stored in the update vector to the 181 record given. No field size changes are allowed. This function is 182 usually invoked on a clustered index. The only use case for a 183 secondary index is row_ins_sec_index_entry_by_modify() or its 184 counterpart in ibuf_insert_to_index_page(). */ 185 void 186 row_upd_rec_in_place( 187 /*=================*/ 188 rec_t* rec, /*!< in/out: record where replaced */ 189 dict_index_t* index, /*!< in: the index the record belongs to */ 190 const rec_offs* offsets,/*!< in: array returned by rec_get_offsets() */ 191 const upd_t* update, /*!< in: update vector */ 192 page_zip_des_t* page_zip);/*!< in: compressed page with enough space 193 available, or NULL */ 194 195 /***************************************************************//** 196 Builds an update vector from those fields which in a secondary index entry 197 differ from a record that has the equal ordering fields. NOTE: we compare 198 the fields as binary strings! 199 @return own: update vector of differing fields */ 200 upd_t* 201 row_upd_build_sec_rec_difference_binary( 202 /*====================================*/ 203 const rec_t* rec, /*!< in: secondary index record */ 204 dict_index_t* index, /*!< in: index */ 205 const rec_offs* offsets,/*!< in: rec_get_offsets(rec, index) */ 206 const dtuple_t* entry, /*!< in: entry to insert */ 207 mem_heap_t* heap) /*!< in: memory heap from which allocated */ 208 MY_ATTRIBUTE((warn_unused_result, nonnull)); 209 /** Builds an update vector from those fields, excluding the roll ptr and 210 trx id fields, which in an index entry differ from a record that has 211 the equal ordering fields. NOTE: we compare the fields as binary strings! 212 @param[in] index clustered index 213 @param[in] entry clustered index entry to insert 214 @param[in] rec clustered index record 215 @param[in] offsets rec_get_offsets(rec,index), or NULL 216 @param[in] no_sys skip the system columns 217 DB_TRX_ID and DB_ROLL_PTR 218 @param[in] trx transaction (for diagnostics), 219 or NULL 220 @param[in] heap memory heap from which allocated 221 @param[in,out] mysql_table NULL, or mysql table object when 222 user thread invokes dml 223 @param[out] error error number in case of failure 224 @return own: update vector of differing fields, excluding roll ptr and 225 trx id */ 226 upd_t* 227 row_upd_build_difference_binary( 228 dict_index_t* index, 229 const dtuple_t* entry, 230 const rec_t* rec, 231 const rec_offs* offsets, 232 bool no_sys, 233 trx_t* trx, 234 mem_heap_t* heap, 235 TABLE* mysql_table, 236 dberr_t* error) 237 MY_ATTRIBUTE((nonnull(1,2,3,7,9), warn_unused_result)); 238 /** Apply an update vector to an index entry. 239 @param[in,out] entry index entry to be updated; the clustered index record 240 must be covered by a lock or a page latch to prevent 241 deletion (rollback or purge) 242 @param[in] index index of the entry 243 @param[in] update update vector built for the entry 244 @param[in,out] heap memory heap for copying off-page columns */ 245 void 246 row_upd_index_replace_new_col_vals_index_pos( 247 dtuple_t* entry, 248 const dict_index_t* index, 249 const upd_t* update, 250 mem_heap_t* heap) 251 MY_ATTRIBUTE((nonnull)); 252 /** Replace the new column values stored in the update vector, 253 during trx_undo_prev_version_build(). 254 @param entry clustered index tuple where the values are replaced 255 (the clustered index leaf page latch must be held) 256 @param index clustered index 257 @param update update vector for the clustered index 258 @param heap memory heap for allocating and copying values 259 @return whether the previous version was built successfully */ 260 bool 261 row_upd_index_replace_new_col_vals(dtuple_t *entry, const dict_index_t &index, 262 const upd_t *update, mem_heap_t *heap) 263 MY_ATTRIBUTE((nonnull, warn_unused_result)); 264 /***********************************************************//** 265 Replaces the new column values stored in the update vector. */ 266 void 267 row_upd_replace( 268 /*============*/ 269 dtuple_t* row, /*!< in/out: row where replaced, 270 indexed by col_no; 271 the clustered index record must be 272 covered by a lock or a page latch to 273 prevent deletion (rollback or purge) */ 274 row_ext_t** ext, /*!< out, own: NULL, or externally 275 stored column prefixes */ 276 const dict_index_t* index, /*!< in: clustered index */ 277 const upd_t* update, /*!< in: an update vector built for the 278 clustered index */ 279 mem_heap_t* heap); /*!< in: memory heap */ 280 /** Replaces the virtual column values stored in a dtuple with that of 281 a update vector. 282 @param[in,out] row dtuple whose column to be updated 283 @param[in] table table 284 @param[in] update an update vector built for the clustered index 285 @param[in] upd_new update to new or old value 286 @param[in,out] undo_row undo row (if needs to be updated) 287 @param[in] ptr remaining part in update undo log */ 288 void 289 row_upd_replace_vcol( 290 dtuple_t* row, 291 const dict_table_t* table, 292 const upd_t* update, 293 bool upd_new, 294 dtuple_t* undo_row, 295 const byte* ptr); 296 297 /***********************************************************//** 298 Checks if an update vector changes an ordering field of an index record. 299 300 This function is fast if the update vector is short or the number of ordering 301 fields in the index is small. Otherwise, this can be quadratic. 302 NOTE: we compare the fields as binary strings! 303 @return TRUE if update vector changes an ordering field in the index record */ 304 ibool 305 row_upd_changes_ord_field_binary_func( 306 /*==================================*/ 307 dict_index_t* index, /*!< in: index of the record */ 308 const upd_t* update, /*!< in: update vector for the row; NOTE: the 309 field numbers in this MUST be clustered index 310 positions! */ 311 #ifdef UNIV_DEBUG 312 const que_thr_t*thr, /*!< in: query thread */ 313 #endif /* UNIV_DEBUG */ 314 const dtuple_t* row, /*!< in: old value of row, or NULL if the 315 row and the data values in update are not 316 known when this function is called, e.g., at 317 compile time */ 318 const row_ext_t*ext, /*!< NULL, or prefixes of the externally 319 stored columns in the old row */ 320 ulint flag) /*!< in: ROW_BUILD_NORMAL, 321 ROW_BUILD_FOR_PURGE or ROW_BUILD_FOR_UNDO */ 322 MY_ATTRIBUTE((nonnull(1,2), warn_unused_result)); 323 #ifdef UNIV_DEBUG 324 # define row_upd_changes_ord_field_binary(index,update,thr,row,ext) \ 325 row_upd_changes_ord_field_binary_func(index,update,thr,row,ext,0) 326 #else /* UNIV_DEBUG */ 327 # define row_upd_changes_ord_field_binary(index,update,thr,row,ext) \ 328 row_upd_changes_ord_field_binary_func(index,update,row,ext,0) 329 #endif /* UNIV_DEBUG */ 330 /***********************************************************//** 331 Checks if an FTS indexed column is affected by an UPDATE. 332 @return offset within fts_t::indexes if FTS indexed column updated else 333 ULINT_UNDEFINED */ 334 ulint 335 row_upd_changes_fts_column( 336 /*=======================*/ 337 dict_table_t* table, /*!< in: table */ 338 upd_field_t* upd_field); /*!< in: field to check */ 339 /***********************************************************//** 340 Checks if an FTS Doc ID column is affected by an UPDATE. 341 @return whether Doc ID column is affected */ 342 bool 343 row_upd_changes_doc_id( 344 /*===================*/ 345 dict_table_t* table, /*!< in: table */ 346 upd_field_t* upd_field) /*!< in: field to check */ 347 MY_ATTRIBUTE((nonnull, warn_unused_result)); 348 /***********************************************************//** 349 Checks if an update vector changes an ordering field of an index record. 350 This function is fast if the update vector is short or the number of ordering 351 fields in the index is small. Otherwise, this can be quadratic. 352 NOTE: we compare the fields as binary strings! 353 @return TRUE if update vector may change an ordering field in an index 354 record */ 355 ibool 356 row_upd_changes_some_index_ord_field_binary( 357 /*========================================*/ 358 const dict_table_t* table, /*!< in: table */ 359 const upd_t* update);/*!< in: update vector for the row */ 360 /***********************************************************//** 361 Updates a row in a table. This is a high-level function used 362 in SQL execution graphs. 363 @return query thread to run next or NULL */ 364 que_thr_t* 365 row_upd_step( 366 /*=========*/ 367 que_thr_t* thr); /*!< in: query thread */ 368 /*********************************************************************//** 369 Parses the log data of system field values. 370 @return log data end or NULL */ 371 byte* 372 row_upd_parse_sys_vals( 373 /*===================*/ 374 const byte* ptr, /*!< in: buffer */ 375 const byte* end_ptr,/*!< in: buffer end */ 376 ulint* pos, /*!< out: TRX_ID position in record */ 377 trx_id_t* trx_id, /*!< out: trx id */ 378 roll_ptr_t* roll_ptr);/*!< out: roll ptr */ 379 /*********************************************************************//** 380 Updates the trx id and roll ptr field in a clustered index record in database 381 recovery. */ 382 void 383 row_upd_rec_sys_fields_in_recovery( 384 /*===============================*/ 385 rec_t* rec, /*!< in/out: record */ 386 page_zip_des_t* page_zip,/*!< in/out: compressed page, or NULL */ 387 const rec_offs* offsets,/*!< in: array returned by rec_get_offsets() */ 388 ulint pos, /*!< in: TRX_ID position in rec */ 389 trx_id_t trx_id, /*!< in: transaction id */ 390 roll_ptr_t roll_ptr);/*!< in: roll ptr of the undo log record */ 391 /*********************************************************************//** 392 Parses the log data written by row_upd_index_write_log. 393 @return log data end or NULL */ 394 byte* 395 row_upd_index_parse( 396 /*================*/ 397 const byte* ptr, /*!< in: buffer */ 398 const byte* end_ptr,/*!< in: buffer end */ 399 mem_heap_t* heap, /*!< in: memory heap where update vector is 400 built */ 401 upd_t** update_out);/*!< out: update vector */ 402 403 404 /* Update vector field */ 405 struct upd_field_t{ 406 unsigned field_no:16; /*!< field number in an index, usually 407 the clustered index, but in updating 408 a secondary index record in btr0cur.cc 409 this is the position in the secondary 410 index. If this field is a virtual 411 column, then field_no represents 412 the nth virtual column in the table */ 413 unsigned orig_len:16; /*!< original length of the locally 414 stored part of an externally stored 415 column, or 0 */ 416 que_node_t* exp; /*!< expression for calculating a new 417 value: it refers to column values and 418 constants in the symbol table of the 419 query graph */ 420 dfield_t new_val; /*!< new value for the column */ 421 dfield_t* old_v_val; /*!< old value for the virtual column */ 422 }; 423 424 425 /* check whether an update field is on virtual column */ 426 #define upd_fld_is_virtual_col(upd_fld) \ 427 (((upd_fld)->new_val.type.prtype & DATA_VIRTUAL) == DATA_VIRTUAL) 428 429 /* set DATA_VIRTUAL bit on update field to show it is a virtual column */ 430 #define upd_fld_set_virtual_col(upd_fld) \ 431 ((upd_fld)->new_val.type.prtype |= DATA_VIRTUAL) 432 433 /* Update vector structure */ 434 struct upd_t{ 435 mem_heap_t* heap; /*!< heap from which memory allocated */ 436 ulint info_bits; /*!< new value of info bits to record; 437 default is 0 */ 438 dtuple_t* old_vrow; /*!< pointer to old row, used for 439 virtual column update now */ 440 ulint n_fields; /*!< number of update fields */ 441 upd_field_t* fields; /*!< array of update fields */ 442 byte vers_sys_value[8]; /*!< buffer for updating system fields */ 443 444 /** Append an update field to the end of array 445 @param[in] field an update field */ appendupd_t446 void append(const upd_field_t& field) 447 { 448 fields[n_fields++] = field; 449 } 450 remove_elementupd_t451 void remove_element(ulint i) 452 { 453 ut_ad(n_fields > 0); 454 ut_ad(i < n_fields); 455 while (i < n_fields - 1) 456 { 457 fields[i]= fields[i + 1]; 458 i++; 459 } 460 n_fields--; 461 } 462 removeupd_t463 bool remove(const ulint field_no) 464 { 465 for (ulint i= 0; i < n_fields; ++i) 466 { 467 if (field_no == fields[i].field_no) 468 { 469 remove_element(i); 470 return true; 471 } 472 } 473 return false; 474 } 475 476 /** Determine if the given field_no is modified. 477 @return true if modified, false otherwise. */ is_modifiedupd_t478 bool is_modified(const ulint field_no) const 479 { 480 for (ulint i = 0; i < n_fields; ++i) { 481 if (field_no == fields[i].field_no) { 482 return(true); 483 } 484 } 485 return(false); 486 } 487 488 /** Determine if the update affects a system versioned column or row_end. */ affects_versionedupd_t489 bool affects_versioned() const 490 { 491 for (ulint i = 0; i < n_fields; i++) { 492 dtype_t type = fields[i].new_val.type; 493 if (type.is_versioned()) { 494 return true; 495 } 496 // versioned DELETE is UPDATE SET row_end=NOW 497 if (type.vers_sys_end()) { 498 return true; 499 } 500 } 501 return false; 502 } 503 504 #ifdef UNIV_DEBUG validateupd_t505 bool validate() const 506 { 507 for (ulint i = 0; i < n_fields; ++i) { 508 dfield_t* field = &fields[i].new_val; 509 if (dfield_is_ext(field)) { 510 ut_ad(dfield_get_len(field) 511 >= BTR_EXTERN_FIELD_REF_SIZE); 512 } 513 } 514 return(true); 515 } 516 #endif // UNIV_DEBUG 517 518 }; 519 520 /** Kinds of update operation */ 521 enum delete_mode_t { 522 NO_DELETE = 0, /*!< this operation does not delete */ 523 PLAIN_DELETE, /*!< ordinary delete */ 524 VERSIONED_DELETE /*!< update old and insert a new row */ 525 }; 526 527 /* Update node structure which also implements the delete operation 528 of a row */ 529 530 struct upd_node_t{ 531 que_common_t common; /*!< node type: QUE_NODE_UPDATE */ 532 delete_mode_t is_delete; /*!< kind of DELETE */ 533 ibool searched_update; 534 /* TRUE if searched update, FALSE if 535 positioned */ 536 bool in_mysql_interface; 537 /* whether the update node was created 538 for the MySQL interface */ 539 dict_foreign_t* foreign;/* NULL or pointer to a foreign key 540 constraint if this update node is used in 541 doing an ON DELETE or ON UPDATE operation */ 542 upd_node_t* cascade_node;/* NULL or an update node template which 543 is used to implement ON DELETE/UPDATE CASCADE 544 or ... SET NULL for foreign keys */ 545 mem_heap_t* cascade_heap; 546 /*!< NULL or a mem heap where cascade 547 node is created.*/ 548 sel_node_t* select; /*!< query graph subtree implementing a base 549 table cursor: the rows returned will be 550 updated */ 551 btr_pcur_t* pcur; /*!< persistent cursor placed on the clustered 552 index record which should be updated or 553 deleted; the cursor is stored in the graph 554 of 'select' field above, except in the case 555 of the MySQL interface */ 556 dict_table_t* table; /*!< table where updated */ 557 upd_t* update; /*!< update vector for the row */ 558 ulint update_n_fields; 559 /* when this struct is used to implement 560 a cascade operation for foreign keys, we store 561 here the size of the buffer allocated for use 562 as the update vector */ 563 sym_node_list_t columns;/* symbol table nodes for the columns 564 to retrieve from the table */ 565 ibool has_clust_rec_x_lock; 566 /* TRUE if the select which retrieves the 567 records to update already sets an x-lock on 568 the clustered record; note that it must always 569 set at least an s-lock */ 570 ulint cmpl_info;/* information extracted during query 571 compilation; speeds up execution: 572 UPD_NODE_NO_ORD_CHANGE and 573 UPD_NODE_NO_SIZE_CHANGE, ORed */ 574 /*----------------------*/ 575 /* Local storage for this graph node */ 576 ulint state; /*!< node execution state */ 577 dict_index_t* index; /*!< NULL, or the next index whose record should 578 be updated */ 579 dtuple_t* row; /*!< NULL, or a copy (also fields copied to 580 heap) of the row to update; this must be reset 581 to NULL after a successful update */ 582 dtuple_t* historical_row; /*!< historical row used in 583 CASCADE UPDATE/SET NULL; 584 allocated from historical_heap */ 585 mem_heap_t* historical_heap; /*!< heap for historical row insertion; 586 created when row to update is located; 587 freed right before row update */ 588 row_ext_t* ext; /*!< NULL, or prefixes of the externally 589 stored columns in the old row */ 590 dtuple_t* upd_row;/* NULL, or a copy of the updated row */ 591 row_ext_t* upd_ext;/* NULL, or prefixes of the externally 592 stored columns in upd_row */ 593 mem_heap_t* heap; /*!< memory heap used as auxiliary storage; 594 this must be emptied after a successful 595 update */ 596 /*----------------------*/ 597 sym_node_t* table_sym;/* table node in symbol table */ 598 que_node_t* col_assign_list; 599 /* column assignment list */ 600 ulint magic_n; 601 602 private: 603 /** Appends row_start or row_end field to update vector and sets a 604 CURRENT_TIMESTAMP/trx->id value to it. 605 Supposed to be called only by make_versioned_update() and 606 make_versioned_delete(). 607 @param[in] trx transaction 608 @param[in] vers_sys_idx table->row_start or table->row_end */ 609 void vers_update_fields(const trx_t *trx, ulint idx); 610 611 public: 612 /** Also set row_start = CURRENT_TIMESTAMP/trx->id 613 @param[in] trx transaction */ vers_make_updateupd_node_t614 void vers_make_update(const trx_t *trx) 615 { 616 vers_update_fields(trx, table->vers_start); 617 } 618 619 /** Only set row_end = CURRENT_TIMESTAMP/trx->id. 620 Do not touch other fields at all. 621 @param[in] trx transaction */ vers_make_deleteupd_node_t622 void vers_make_delete(const trx_t *trx) 623 { 624 update->n_fields = 0; 625 is_delete = VERSIONED_DELETE; 626 vers_update_fields(trx, table->vers_end); 627 } 628 }; 629 630 #define UPD_NODE_MAGIC_N 1579975 631 632 /* Node execution states */ 633 #define UPD_NODE_SET_IX_LOCK 1 /* execution came to the node from 634 a node above and if the field 635 has_clust_rec_x_lock is FALSE, we 636 should set an intention x-lock on 637 the table */ 638 #define UPD_NODE_UPDATE_CLUSTERED 2 /* clustered index record should be 639 updated */ 640 #define UPD_NODE_INSERT_CLUSTERED 3 /* clustered index record should be 641 inserted, old record is already delete 642 marked */ 643 #define UPD_NODE_UPDATE_ALL_SEC 5 /* an ordering field of the clustered 644 index record was changed, or this is 645 a delete operation: should update 646 all the secondary index records */ 647 #define UPD_NODE_UPDATE_SOME_SEC 6 /* secondary index entries should be 648 looked at and updated if an ordering 649 field changed */ 650 651 /* Compilation info flags: these must fit within 3 bits; see trx0rec.h */ 652 #define UPD_NODE_NO_ORD_CHANGE 1 /* no secondary index record will be 653 changed in the update and no ordering 654 field of the clustered index */ 655 #define UPD_NODE_NO_SIZE_CHANGE 2 /* no record field size will be 656 changed in the update */ 657 658 659 #include "row0upd.inl" 660 661 #endif 662