MySQL 9.1.0
Source Code Documentation
row0upd.h
Go to the documentation of this file.
1/*****************************************************************************
2
3Copyright (c) 1996, 2024, Oracle and/or its affiliates.
4
5This program is free software; you can redistribute it and/or modify it under
6the terms of the GNU General Public License, version 2.0, as published by the
7Free Software Foundation.
8
9This program is designed to work with certain software (including
10but not limited to OpenSSL) that is licensed under separate terms,
11as designated in a particular file or component or in included license
12documentation. The authors of MySQL hereby grant you an additional
13permission to link the program and your derivative works with the
14separately licensed software that they have either included with
15the program or referenced in the documentation.
16
17This program is distributed in the hope that it will be useful, but WITHOUT
18ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
19FOR A PARTICULAR PURPOSE. See the GNU General Public License, version 2.0,
20for more details.
21
22You should have received a copy of the GNU General Public License along with
23this program; if not, write to the Free Software Foundation, Inc.,
2451 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
25
26*****************************************************************************/
27
28/** @file include/row0upd.h
29 Update of a row
30
31 Created 12/27/1996 Heikki Tuuri
32 *******************************************************/
33
34#ifndef row0upd_h
35#define row0upd_h
36
37#include <stack>
38#include "btr0types.h"
39#include "data0data.h"
40#include "dict0types.h"
41#include "lob0lob.h"
42#include "row0types.h"
43#include "table.h"
44#include "trx0types.h"
45#include "univ.i"
46
47#include "btr0pcur.h"
48#ifndef UNIV_HOTBACKUP
49#include "pars0types.h"
50#include "que0types.h"
51#endif /* !UNIV_HOTBACKUP */
52
53/** Creates an update vector object.
54@param[in] n number of fields
55@param[in] heap heap from which memory allocated
56@return own: update vector object */
57static inline upd_t *upd_create(ulint n, mem_heap_t *heap);
58
59/** Returns the number of fields in the update vector == number of columns
60 to be updated by an update vector.
61 @return number of fields */
62static inline ulint upd_get_n_fields(
63 const upd_t *update); /*!< in: update vector */
64
65#ifdef UNIV_DEBUG
66/** Returns the nth field of an update vector.
67@param[in] update update vector
68@param[in] n field position in update vector
69@return update vector field */
71#else
72#define upd_get_nth_field(update, n) ((update)->fields + (n))
73#endif
74/** Sets an index field number to be updated by an update vector field.
75@param[in] upd_field update vector field
76@param[in] field_no field number in a clustered index
77@param[in] index index */
78static inline void upd_field_set_field_no(upd_field_t *upd_field,
79 ulint field_no,
80 const 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 */
86static inline void upd_field_set_v_field_no(upd_field_t *upd_field,
87 ulint field_no,
88 const dict_index_t *index);
89/** Returns a field of an update vector by field_no.
90@param[in] update Update vector.
91@param[in] no Field no.
92@param[in] is_virtual If it is a virtual column.
93@return update vector field, or nullptr. */
94[[nodiscard]] static inline const upd_field_t *upd_get_field_by_field_no(
95 const upd_t *update, ulint no, bool is_virtual);
96/** Writes into the redo log the values of trx id and roll ptr and enough info
97to determine their positions within a clustered index record.
98@param[in] index Clustered index.
99@param[in] trx_id Transaction ID.
100@param[in] roll_ptr Roll ptr of the undo log record.
101@param[in] log_ptr Pointer to a buffer of size > 20 opened in mlog.
102@param[in] mtr Mini-transaction.
103@return new pointer to mlog */
105 roll_ptr_t roll_ptr, byte *log_ptr,
106 mtr_t *mtr);
107
108#ifndef UNIV_HOTBACKUP
109/** Updates the trx id and roll ptr field in a clustered index record when a
110row is updated or marked deleted.
111@param[in,out] rec record
112@param[in,out] page_zip compressed page whose uncompressed part will
113 be updated, or NULL
114@param[in] index clustered index
115@param[in] offsets rec_get_offsets(rec, index)
116@param[in] trx transaction
117@param[in] roll_ptr roll ptr of the undo log record, can be 0
118 during IMPORT */
119static inline void row_upd_rec_sys_fields(rec_t *rec, page_zip_des_t *page_zip,
120 const dict_index_t *index,
121 const ulint *offsets,
122 const trx_t *trx,
123 roll_ptr_t roll_ptr);
124#endif /* !UNIV_HOTBACKUP */
125
126/** Sets the trx id or roll ptr field of a clustered index entry.
127@param[in,out] entry Index entry, where the memory buffers for sys fields are
128already allocated: the function just copies the new values to them
129@param[in] index Clustered index
130@param[in] type Data_trx_id or data_roll_ptr
131@param[in] val Value to write */
133 ulint type, uint64_t val);
134
135/** Creates an update node for a query graph.
136 @return own: update node */
138 mem_heap_t *heap); /*!< in: mem heap where created */
139
140/** Writes to the redo log the new values of the fields occurring in the index.
141@param[in] index index which to be updated
142@param[in] update update vector
143@param[in] log_ptr pointer to mlog buffer: must contain at least
144 MLOG_BUF_MARGIN bytes of free space; the buffer
145 is closed within this function
146@param[in] mtr mtr into whose log to write */
148 byte *log_ptr, mtr_t *mtr);
149
150/** Returns true if row update changes size of some field in index or if some
151 field to be updated is stored externally in rec or update.
152 @return true if the update changes the size of some field in index or
153 the field is external in rec or update */
155 const dict_index_t *index, /*!< in: index */
156 const ulint *offsets, /*!< in: rec_get_offsets(rec, index) */
157 const upd_t *update); /*!< in: update vector */
158/** Returns true if row update contains disowned external fields.
159 @return true if the update contains disowned external fields. */
160[[nodiscard]] bool row_upd_changes_disowned_external(
161 const upd_t *update); /*!< in: update vector */
162/** Replaces the new column values stored in the update vector to the
163 record given. No field size changes are allowed. This function is
164 usually invoked on a clustered index. The only use case for a
165 secondary index is row_ins_sec_index_entry_by_modify() or its
166 counterpart in ibuf_insert_to_index_page(). */
168 rec_t *rec, /*!< in/out: record where replaced */
169 const dict_index_t *index, /*!< in: the index the record belongs to */
170 const ulint *offsets, /*!< in: array returned by rec_get_offsets() */
171 const upd_t *update, /*!< in: update vector */
172 page_zip_des_t *page_zip); /*!< in: compressed page with enough space
173 available, or NULL */
174/** Builds an update vector from those fields which in a secondary index entry
175 differ from a record that has the equal ordering fields. NOTE: we compare
176 the fields as binary strings!
177 @return own: update vector of differing fields */
179 const rec_t *rec, /*!< in: secondary index record */
180 dict_index_t *index, /*!< in: index */
181 const ulint *offsets, /*!< in: rec_get_offsets(rec, index) */
182 const dtuple_t *entry, /*!< in: entry to insert */
183 mem_heap_t *heap); /*!< in: memory heap from which allocated */
184/** Builds an update vector from those fields, excluding the roll ptr and
185trx id fields, which in an index entry differ from a record that has
186the equal ordering fields. NOTE: we compare the fields as binary strings!
187@param[in] index clustered index
188@param[in] entry clustered index entry to insert
189@param[in] rec clustered index record
190@param[in] offsets rec_get_offsets(rec,index), or NULL
191@param[in] no_sys skip the system columns
192 DB_TRX_ID and DB_ROLL_PTR
193@param[in] trx transaction (for diagnostics),
194 or NULL
195@param[in] heap memory heap from which allocated
196@param[in] mysql_table NULL, or mysql table object when
197 user thread invokes dml
198@param[out] error error number in case of failure
199@return own: update vector of differing fields, excluding roll ptr and
200trx id */
202 dict_index_t *index, const dtuple_t *entry, const rec_t *rec,
203 const ulint *offsets, bool no_sys, trx_t *trx, mem_heap_t *heap,
204 TABLE *mysql_table, dberr_t *error);
205
206/** Replaces the new column values stored in the update vector to the index
207 entry given.
208@param[in,out] entry Index entry where replaced; the clustered index record must
209be covered by a lock or a page latch to prevent deletion [rollback or purge]
210@param[in] index Index; note that this may also be a non-clustered index
211@param[in] update An update vector built for the index so that the field number
212in an upd_field is the index position
213@param[in] order_only If true, limit the replacement to ordering fields of
214index; note that this does not work for non-clustered indexes.
215@param[in] heap Memory heap for allocating and copying the new values */
217 const dict_index_t *index,
218 const upd_t *update,
219 bool order_only,
220 mem_heap_t *heap);
221
222/** Replaces the new column values stored in the update vector to the index
223 entry given.
224@param[in,out] entry Index entry where replaced; the clustered index record must
225be covered by a lock or a page latch to prevent deletion (rollback or purge)
226@param[in] index Index; note that this may also be a non-clustered index
227@param[in] update An update vector built for the clustered index so that the
228field number in an upd_field is the clustered index position
229@param[in] heap Memory heap for allocating and copying the new values */
231 const dict_index_t *index,
232 const upd_t *update, mem_heap_t *heap);
233
234/** Replaces the new column values stored in the update vector.
235@param[in,out] row Row where replaced, indexed by col_no; the clustered index
236record must be covered by a lock or a page latch to prevent deletion (rollback
237or purge)
238@param[in,out] ext Null, or externally stored column prefixes
239@param[in] index Clustered index
240@param[in] update An update vector built for the clustered index
241@param[in] heap Memory heap */
242void row_upd_replace(dtuple_t *row, row_ext_t **ext, const dict_index_t *index,
243 const upd_t *update, mem_heap_t *heap);
244
245/** Replaces the virtual column values stored in a dtuple with that of
246a update vector.
247@param[in,out] row dtuple whose column to be updated
248@param[in] table table
249@param[in] update an update vector built for the clustered index
250@param[in] upd_new update to new or old value
251@param[in,out] undo_row undo row (if needs to be updated)
252@param[in] ptr remaining part in update undo log */
254 const upd_t *update, bool upd_new, dtuple_t *undo_row,
255 const byte *ptr);
256
257/** Checks if an update vector changes an ordering field of an index record.
258It will also help check if any non-multi-value field on the multi-value index
259gets updated or not.
260
261This function is fast if the update vector is short or the number of ordering
262fields in the index is small. Otherwise, this can be quadratic.
263NOTE: we compare the fields as binary strings!
264@param[in] index index of the record
265@param[in] update update vector for the row; NOTE: the
266 field numbers in this MUST be clustered index
267 positions!
268@param[in] thr query thread, or NULL
269@param[in] row old value of row, or NULL if the
270 row and the data values in update are not
271 known when this function is called, e.g., at
272 compile time
273@param[in] ext NULL, or prefixes of the externally
274 stored columns in the old row
275@param[in,out] non_mv_upd NULL, or not NULL pointer to get the
276 information about whether any non-multi-value
277 field on the multi-value index gets updated
278@param[in] flag ROW_BUILD_NORMAL, ROW_BUILD_FOR_PURGE or
279 ROW_BUILD_FOR_UNDO
280@return true if update vector changes an ordering field in the index record */
282 dict_index_t *index, const upd_t *update,
283 IF_DEBUG(const que_thr_t *thr, ) const dtuple_t *row, const row_ext_t *ext,
284 bool *non_mv_upd, ulint flag);
285
287 dict_index_t *index, const upd_t *update,
288 const que_thr_t *thr [[maybe_unused]], const dtuple_t *row,
289 const row_ext_t *ext, bool *non_mv_upd) {
291 index, update, IF_DEBUG(thr, ) row, ext, non_mv_upd, 0);
292}
293
294/** Checks if an FTS indexed column is affected by an UPDATE.
295 @return offset within fts_t::indexes if FTS indexed column updated else
296 ULINT_UNDEFINED */
298 dict_table_t *table, /*!< in: table */
299 upd_field_t *upd_field); /*!< in: field to check */
300/** Checks if an FTS Doc ID column is affected by an UPDATE.
301 @return whether Doc ID column is affected */
302[[nodiscard]] bool row_upd_changes_doc_id(
303 dict_table_t *table, /*!< in: table */
304 upd_field_t *upd_field); /*!< in: field to check */
305/** Checks if an update vector changes an ordering field of an index record.
306 This function is fast if the update vector is short or the number of ordering
307 fields in the index is small. Otherwise, this can be quadratic.
308 NOTE: we compare the fields as binary strings!
309 @return true if update vector may change an ordering field in an index
310 record */
312 const dict_table_t *table, /*!< in: table */
313 const upd_t *update); /*!< in: update vector for the row */
314
315/** Stores to the heap the row on which the node->pcur is positioned.
316@param[in] node row update node
317@param[in] thd mysql thread handle
318@param[in,out] mysql_table NULL, or mysql table object when
319 user thread invokes dml */
320void row_upd_store_row(upd_node_t *node, THD *thd, TABLE *mysql_table);
321
322/** Updates a row in a table. This is a high-level function used
323 in SQL execution graphs.
324 @return query thread to run next or NULL */
325que_thr_t *row_upd_step(que_thr_t *thr); /*!< in: query thread */
326/** Parses the log data of system field values.
327 @return log data end or NULL */
328byte *row_upd_parse_sys_vals(const byte *ptr, /*!< in: buffer */
329 const byte *end_ptr, /*!< in: buffer end */
330 ulint *pos, /*!< out: TRX_ID position in record */
331 trx_id_t *trx_id, /*!< out: trx id */
332 roll_ptr_t *roll_ptr); /*!< out: roll ptr */
333
334/** Updates the trx id and roll ptr field in a clustered index record in
335 database recovery.
336@param[in,out] rec Record
337@param[in,out] page_zip Compressed page, or null
338@param[in] offsets Array returned by rec_get_offsets()
339@param[in] pos Trx_id position in rec
340@param[in] trx_id Transaction id
341@param[in] roll_ptr Roll ptr of the undo log record */
343 const ulint *offsets, ulint pos,
344 trx_id_t trx_id, roll_ptr_t roll_ptr);
345
346/** Parses the log data written by row_upd_index_write_log.
347 @return log data end or NULL */
348byte *row_upd_index_parse(const byte *ptr, /*!< in: buffer */
349 const byte *end_ptr, /*!< in: buffer end */
350 mem_heap_t *heap, /*!< in: memory heap where update
351 vector is built */
352 upd_t **update_out); /*!< out: update vector */
353
354/** Get the new autoinc counter from the update vector when there is
355an autoinc field defined in this table.
356@param[in] update update vector for the clustered index
357@param[in] autoinc_field_no autoinc field's order in clustered index
358@return the new counter if we find it in the update vector, otherwise 0.
359We don't mind that the new counter happens to be 0, we just care about
360non-zero counters. */
362 ulint autoinc_field_no);
363
364/** This structure is used for undo logging of LOB index changes. */
368
369 /** Print the current object into the given output stream.
370 @param[in,out] out the output stream.
371 @return the output stream. */
372 std::ostream &print(std::ostream &out) const {
373 out << "[lob_index_diff_t: m_modifier_trxid=" << m_modifier_trxid
374 << ", m_modifier_undo_no=" << m_modifier_undo_no << "]";
375 return (out);
376 }
377};
378
380 std::vector<lob_index_diff_t, mem_heap_allocator<lob_index_diff_t>>;
381
382/** Overloading the global output operator to print lob_index_diff_t object.
383@param[in,out] out the output stream.
384@param[in] obj the object to be printed.
385@return the output stream.*/
386inline std::ostream &operator<<(std::ostream &out,
387 const lob_index_diff_t &obj) {
388 return (obj.print(out));
389}
390
391/** The modification done to the LOB. */
392struct Lob_diff {
393 /** Constructor.
394 @param[in] mem_heap the memory heap in which this object
395 has been created. */
396 Lob_diff(mem_heap_t *mem_heap) : heap(mem_heap) {
397 m_idx_diffs = static_cast<Lob_index_diff_vec *>(
399 new (m_idx_diffs)
401 }
402
403 /** Read the offset from the undo record.
404 @param[in] undo_ptr pointer into the undo log record.
405 @return pointer into the undo log record after offset. */
406 const byte *read_offset(const byte *undo_ptr) {
407 /* Read the offset. */
409 return (undo_ptr);
410 }
411
412 /** Read the length from the undo record.
413 @param[in] undo_ptr pointer into the undo log record.
414 @return pointer into the undo log record after length information. */
415 const byte *read_length(const byte *undo_ptr) {
416 /* Read the length. */
419
420 return (undo_ptr);
421 }
422
423 void set_old_data(const byte *undo_ptr) { m_old_data = undo_ptr; }
424
425 std::ostream &print(std::ostream &out) const {
426 out << "[Lob_diff: offset=" << m_offset << ", length=" << m_length;
427 if (m_old_data == nullptr) {
428 out << ", m_old_data=nullptr";
429 } else {
430 out << ", m_old_data=" << PrintBuffer(m_old_data, m_length);
431 }
432
433 if (m_idx_diffs != nullptr) {
434 for (auto iter = m_idx_diffs->begin(); iter != m_idx_diffs->end();
435 ++iter) {
436 out << *iter;
437 }
438 }
439
440 out << "]";
441 return (out);
442 }
443
444 /** The offset within LOB where partial update happened. */
446
447 /** The length of the modification. */
449
450 /** Changes to the LOB data. */
451 const byte *m_old_data = nullptr;
452
453 /** Changes to the LOB index. */
455
456 /** Memory heap in which this object is allocated. */
458};
459
460using Lob_diff_vector = std::vector<Lob_diff, mem_heap_allocator<Lob_diff>>;
461
462inline std::ostream &operator<<(std::ostream &out, const Lob_diff &obj) {
463 return (obj.print(out));
464}
465
466/* Update vector field */
469 : field_no(0),
470 orig_len(0),
471 exp(nullptr),
474 ext_in_old(false),
477 lob_version(0),
478 last_trx_id(0),
479 last_undo_no(0),
480 heap(nullptr) {}
481
482 bool is_virtual() const { return (new_val.is_virtual()); }
483
484 unsigned field_no : 16; /*!< field number in an index, usually
485 the clustered index, but in updating
486 a secondary index record in btr0cur.cc
487 this is the position in the secondary
488 index, also it could be the position
489 in virtual index for virtual column */
491 unsigned orig_len : 16; /*!< original length of the locally
492 stored part of an externally stored
493 column, or 0 */
494 que_node_t *exp; /*!< expression for calculating a new
495 value: it refers to column values and
496 constants in the symbol table of the
497 query graph */
498 dfield_t old_val; /*!< old value for the column */
499 dfield_t new_val; /*!< new value for the column */
500 dfield_t *old_v_val; /*!< old value for the virtual column */
501
502 Field *mysql_field; /*!< the mysql field object. */
503
504 /** If true, the field was stored externally in the old row. */
506
507 void push_lob_diff(const Lob_diff &lob_diff) {
508 if (lob_diffs == nullptr) {
509 lob_diffs = static_cast<Lob_diff_vector *>(
512 }
513 lob_diffs->push_back(lob_diff);
514 }
515
516 /** List of changes done to this updated field. This is usually
517 populated from the undo log. */
519
520 /** The LOB first page number. This information is read from
521 the undo log. */
523
525
526 /** The last trx that modified the LOB. */
528
529 /** The last stmt within trx that modified the LOB. */
531
532 std::ostream &print(std::ostream &out) const;
533
534 /** Empty the information collected on LOB diffs. */
535 void reset() {
536 if (lob_diffs != nullptr) {
537 lob_diffs->clear();
538 }
539 }
540
541 /** Memory heap in which this object is allocated. */
543};
544
545inline std::ostream &operator<<(std::ostream &out, const upd_field_t &obj) {
546 return (obj.print(out));
547}
548
549/* check whether an update field is on virtual column */
550static inline bool upd_fld_is_virtual_col(const upd_field_t *upd_fld) {
551 return (upd_fld->new_val.type.prtype & DATA_VIRTUAL) == DATA_VIRTUAL;
552}
553
554/* check whether an update field is on multi-value virtual column */
555static inline bool upd_fld_is_multi_value_col(const upd_field_t *upd_fld) {
556 return dfield_is_multi_value(&upd_fld->new_val);
557}
558
559/* set DATA_VIRTUAL bit on update field to show it is a virtual column */
560static inline void upd_fld_set_virtual_col(upd_field_t *upd_fld) {
561 upd_fld->new_val.type.prtype |= DATA_VIRTUAL;
562}
563
564/* Update vector structure */
565struct upd_t {
566 /** Heap from which memory allocated. This is not a new heap, rather
567 will point to other heap. Therefore memory allocated from this heap
568 is released when the pointed heap is freed or emptied. */
570
571 /** Heap from which memory is allocated if required only for current
572 statement. This heap is emtied at the end of statement from inside
573 ha_innobase::end_stmt(). */
575
576 /** New value of info bits to record; default is 0. */
578
579 /** Pointer to old row, used for virtual column update now. */
581
582 /** The table object. */
584
585 /** The mysql table object. */
587
588 /** Number of update fields. */
590
591 /** Array of update fields. */
593
594 /** Append an update field to the end of array
595 @param[in] field an update field */
596 void append(const upd_field_t &field) { fields[n_fields++] = field; }
597
598 /** Determine if the given field_no is modified.
599 @return true if modified, false otherwise. */
600 bool is_modified(const ulint field_no) const {
601 if (table == nullptr) {
602 ut_d(ut_error);
603 ut_o(return false);
604 }
605
606 return (get_field_by_field_no(field_no, table->first_index()) != nullptr);
607 }
608
609 /** Reset the update fields. */
610 void reset() {
611 for (ulint i = 0; i < n_fields; ++i) {
612 fields[i].reset();
613 }
614 }
615
616#ifdef UNIV_DEBUG
617 bool validate() const {
618 for (ulint i = 0; i < n_fields; ++i) {
619 dfield_t *field = &fields[i].new_val;
620 if (dfield_is_ext(field)) {
622 }
623 }
624 return (true);
625 }
626#endif // UNIV_DEBUG
627
628 /** Check if the given field number is partially updated.
629 @param[in] field_no the field number.
630 @return true if partially updated, false otherwise. */
631 bool is_partially_updated(ulint field_no) const;
632
633 upd_field_t *get_field_by_field_no(ulint field_no, dict_index_t *index) const;
634
636
637 /** Calculate the total number of bytes modified in one BLOB.
638 @param[in] bdv the binary diff vector containing all the
639 modifications to one BLOB.
640 @return the total modified bytes. */
642 size_t total = 0;
643 for (const Binary_diff &bdiff : bdv) {
644 total += bdiff.length();
645 }
646 return (total);
647 }
648
649 /** Empty the per_stmt_heap. */
651 if (per_stmt_heap != nullptr) {
653 }
654 }
655
656 /** Free the per_stmt_heap. */
658 if (per_stmt_heap != nullptr) {
660 per_stmt_heap = nullptr;
661 }
662 }
663
664 std::ostream &print(std::ostream &out) const;
665
666 /** Print the partial update vector (puvect) of the given update
667 field.
668 @param[in,out] out the output stream
669 @param[in] uf the updated field.
670 @return the output stream. */
671 std::ostream &print_puvect(std::ostream &out, upd_field_t *uf) const;
672};
673
674#ifdef UNIV_DEBUG
675/** Print the given binary diff into the given output stream.
676@param[in] out the output stream
677@param[in] bdiff binary diff to be printed.
678@param[in] table the table dictionary object.
679@param[in] field mysql field object.
680@param[in] print_old prints old data of the updated field
681@return the output stream */
682std::ostream &print_binary_diff(std::ostream &out, const Binary_diff *bdiff,
683 const dict_table_t *table, const Field *field,
684 bool print_old);
685
686std::ostream &print_binary_diff(std::ostream &out, const Binary_diff *bdiff);
687
688inline std::ostream &operator<<(std::ostream &out, const upd_t &obj) {
689 return (obj.print(out));
690}
691
692inline std::ostream &operator<<(std::ostream &out, const Binary_diff_vector &) {
693 return (out);
694}
695#endif /* UNIV_DEBUG */
696
697#ifndef UNIV_HOTBACKUP
698/* Update node structure which also implements the delete operation
699of a row */
700
702 que_common_t common; /*!< node type: QUE_NODE_UPDATE */
703 bool is_delete; /* true if delete, false if update */
705 /* true if searched update, false if
706 positioned */
708 /* true if the update node was created
709 for the MySQL interface */
710 dict_foreign_t *foreign; /* NULL or pointer to a foreign key
711 constraint if this update node is used in
712 doing an ON DELETE or ON UPDATE operation */
713 upd_node_t *cascade_node; /* NULL or an update node template which
714 is used to implement ON DELETE/UPDATE CASCADE
715 or ... SET NULL for foreign keys */
717 /*!< NULL or a mem heap where cascade_upd_nodes
718 are created.*/
719 sel_node_t *select; /*!< query graph subtree implementing a base
720 table cursor: the rows returned will be
721 updated */
722 btr_pcur_t *pcur; /*!< persistent cursor placed on the clustered
723 index record which should be updated or
724 deleted; the cursor is stored in the graph
725 of 'select' field above, except in the case
726 of the MySQL interface */
727 dict_table_t *table; /*!< table where updated */
728 upd_t *update; /*!< update vector for the row */
730 /* when this struct is used to implement
731 a cascade operation for foreign keys, we store
732 here the size of the buffer allocated for use
733 as the update vector */
734 sym_node_list_t columns; /* symbol table nodes for the columns
735 to retrieve from the table */
737 /* true if the select which retrieves the
738 records to update already sets an x-lock on
739 the clustered record; note that it must always
740 set at least an s-lock */
741 ulint cmpl_info; /* information extracted during query
742 compilation; speeds up execution:
743 UPD_NODE_NO_ORD_CHANGE and
744 UPD_NODE_NO_SIZE_CHANGE, ORed */
745 /*----------------------*/
746 /* Local storage for this graph node */
747 ulint state; /*!< node execution state */
748 dict_index_t *index; /*!< NULL, or the next index whose record should
749 be updated */
750 dtuple_t *row; /*!< NULL, or a copy (also fields copied to
751 heap) of the row to update; this must be reset
752 to NULL after a successful update */
753 row_ext_t *ext; /*!< NULL, or prefixes of the externally
754 stored columns in the old row */
755 dtuple_t *upd_row; /* NULL, or a copy of the updated row */
756 row_ext_t *upd_ext; /* NULL, or prefixes of the externally
757 stored columns in upd_row */
758 mem_heap_t *heap; /*!< memory heap used as auxiliary storage;
759 this must be emptied after a successful
760 update */
761 /*----------------------*/
762 sym_node_t *table_sym; /* table node in symbol table */
764 /* column assignment list */
765
766 /** When there is a lock wait error, this remembers current position of
767 the multi-value field, before which the values have been deleted.
768 This will be used for both DELETE and the delete phase of UPDATE. */
770
771 /** When there is a lock wait error, this remembers current position of
772 the multi-value field, before which the values have been updated. */
774
776};
777
778constexpr uint32_t UPD_NODE_MAGIC_N = 1579975;
779
780/* Node execution states */
781/** execution came to the node from a node above and if the field
782has_clust_rec_x_lock is false, we should set an intention x-lock on the table
783 */
784constexpr uint32_t UPD_NODE_SET_IX_LOCK = 1;
785/** clustered index record should be updated */
786constexpr uint32_t UPD_NODE_UPDATE_CLUSTERED = 2;
787/* clustered index record should be inserted, old record is already delete
788 marked */
789constexpr uint32_t UPD_NODE_INSERT_CLUSTERED = 3;
790/** an ordering field of the clustered index record was changed, or this is a
791 delete operation: should update all the secondary index records */
792constexpr uint32_t UPD_NODE_UPDATE_ALL_SEC = 5;
793/** secondary index entries should be looked at and updated if an ordering field
794 changed */
795constexpr uint32_t UPD_NODE_UPDATE_SOME_SEC = 6;
796
797/* Compilation info flags: these must fit within 2 bits; see trx0rec.h */
798/** no secondary index record will be changed in the update and no ordering
799 field of the clustered index */
800constexpr uint32_t UPD_NODE_NO_ORD_CHANGE = 1;
801/** no record field size will be changed in the update */
802constexpr uint32_t UPD_NODE_NO_SIZE_CHANGE = 2;
803#endif /* !UNIV_HOTBACKUP */
804
805#include "row0upd.ic"
806
807#endif
uint32_t page_no_t
Page number.
Definition: api0api.h:46
Kerberos Client Authentication nullptr
Definition: auth_kerberos_client_plugin.cc:251
The index tree persistent cursor.
The index tree general types.
constexpr uint32_t BTR_EXTERN_FIELD_REF_SIZE
The size of a reference to data stored on a different page.
Definition: btr0types.h:66
Class that represents a single change to a column value in partial update of a JSON column.
Definition: table.h:1338
Definition: field.h:577
A typesafe replacement for DYNAMIC_ARRAY.
Definition: mem_root_array.h:426
For each client connection we create a separate thread with THD serving as a thread/connection descri...
Definition: sql_lexer_thd.h:36
A C++ wrapper class to the mem_heap_t routines, so that it can be used as an STL allocator.
Definition: mem0mem.h:356
SQL data field and tuple.
static uint32_t dfield_get_len(const dfield_t *field)
Gets length of field data.
static bool dfield_is_ext(const dfield_t *field)
Determines if a field is externally stored.
static bool dfield_is_multi_value(const dfield_t *field)
Determine if a field is of multi-value type.
constexpr uint32_t DATA_VIRTUAL
Virtual column.
Definition: data0type.h:223
dberr_t
Definition: db0err.h:39
Data dictionary global types.
constexpr page_no_t FIL_NULL
'null' (undefined) page offset in the context of file spaces
Definition: fil0fil.h:1156
static int flag
Definition: hp_test1.cc:40
#define UINT16_MAX
Definition: lexyy.cc:83
Implements the large objects (LOB) module.
static uint32_t mach_read_next_compressed(const byte **b)
Read a 32-bit integer in a compressed form.
static void * mem_heap_alloc(mem_heap_t *heap, ulint n)
Allocates n bytes of memory from a memory heap.
static void mem_heap_free(mem_heap_t *heap)
Frees the space occupied by a memory heap.
static void mem_heap_empty(mem_heap_t *heap)
Empties a memory heap.
static uint update
Definition: myisamlog.cc:94
void error(const char *format,...)
Type total(const Shards< COUNT > &shards) noexcept
Get the total value of all shards.
Definition: ut0counter.h:333
static PFS_engine_table_share_proxy table
Definition: pfs.cc:61
Json_data_extension ext
Definition: backend.cc:50
SQL parser global types.
Query graph global types.
void que_node_t
Definition: que0types.h:41
byte rec_t
Definition: rem0types.h:41
required string type
Definition: replication_group_member_actions.proto:34
Row operation global types.
upd_t * row_upd_build_difference_binary(dict_index_t *index, const dtuple_t *entry, const rec_t *rec, const ulint *offsets, bool no_sys, trx_t *trx, mem_heap_t *heap, TABLE *mysql_table, dberr_t *error)
Builds an update vector from those fields, excluding the roll ptr and trx id fields,...
Definition: row0upd.cc:832
constexpr uint32_t UPD_NODE_UPDATE_SOME_SEC
secondary index entries should be looked at and updated if an ordering field changed
Definition: row0upd.h:795
byte * row_upd_index_parse(const byte *ptr, const byte *end_ptr, mem_heap_t *heap, upd_t **update_out)
Parses the log data written by row_upd_index_write_log.
Definition: row0upd.cc:680
static void upd_field_set_field_no(upd_field_t *upd_field, ulint field_no, const dict_index_t *index)
Sets an index field number to be updated by an update vector field.
static ulint upd_get_n_fields(const upd_t *update)
Returns the number of fields in the update vector == number of columns to be updated by an update vec...
bool row_upd_changes_some_index_ord_field_binary(const dict_table_t *table, const upd_t *update)
Checks if an update vector changes an ordering field of an index record.
Definition: row0upd.cc:1656
static void upd_fld_set_virtual_col(upd_field_t *upd_fld)
Definition: row0upd.h:560
static void upd_field_set_v_field_no(upd_field_t *upd_field, ulint field_no, const dict_index_t *index)
set field number to a update vector field, marks this field is updated
bool row_upd_changes_field_size_or_external(const dict_index_t *index, const ulint *offsets, const upd_t *update)
Returns true if row update changes size of some field in index or if some field to be updated is stor...
Definition: row0upd.cc:358
void row_upd_index_write_log(dict_index_t *index, const upd_t *update, byte *log_ptr, mtr_t *mtr)
Writes to the redo log the new values of the fields occurring in the index.
Definition: row0upd.cc:595
static bool upd_fld_is_multi_value_col(const upd_field_t *upd_fld)
Definition: row0upd.h:555
std::vector< lob_index_diff_t, mem_heap_allocator< lob_index_diff_t > > Lob_index_diff_vec
Definition: row0upd.h:380
constexpr uint32_t UPD_NODE_MAGIC_N
Definition: row0upd.h:778
std::vector< Lob_diff, mem_heap_allocator< Lob_diff > > Lob_diff_vector
Definition: row0upd.h:460
constexpr uint32_t UPD_NODE_NO_ORD_CHANGE
no secondary index record will be changed in the update and no ordering field of the clustered index
Definition: row0upd.h:800
void row_upd_replace(dtuple_t *row, row_ext_t **ext, const dict_index_t *index, const upd_t *update, mem_heap_t *heap)
Replaces the new column values stored in the update vector.
Definition: row0upd.cc:1362
static bool row_upd_changes_ord_field_binary(dict_index_t *index, const upd_t *update, const que_thr_t *thr, const dtuple_t *row, const row_ext_t *ext, bool *non_mv_upd)
Definition: row0upd.h:286
static const upd_field_t * upd_get_field_by_field_no(const upd_t *update, ulint no, bool is_virtual)
Returns a field of an update vector by field_no.
void row_upd_index_entry_sys_field(dtuple_t *entry, dict_index_t *index, ulint type, uint64_t val)
Sets the trx id or roll ptr field of a clustered index entry.
Definition: row0upd.cc:332
constexpr uint32_t UPD_NODE_UPDATE_CLUSTERED
clustered index record should be updated
Definition: row0upd.h:786
upd_node_t * upd_node_create(mem_heap_t *heap)
Creates an update node for a query graph.
Definition: row0upd.cc:283
static upd_t * upd_create(ulint n, mem_heap_t *heap)
Creates an update vector object.
void row_upd_store_row(upd_node_t *node, THD *thd, TABLE *mysql_table)
Stores to the heap the row on which the node->pcur is positioned.
Definition: row0upd.cc:1920
bool row_upd_changes_disowned_external(const upd_t *update)
Returns true if row update contains disowned external fields.
Definition: row0upd.cc:438
constexpr uint32_t UPD_NODE_INSERT_CLUSTERED
Definition: row0upd.h:789
byte * row_upd_parse_sys_vals(const byte *ptr, const byte *end_ptr, ulint *pos, trx_id_t *trx_id, roll_ptr_t *roll_ptr)
Parses the log data of system field values.
Definition: row0upd.cc:570
que_thr_t * row_upd_step(que_thr_t *thr)
Updates a row in a table.
Definition: row0upd.cc:3242
static upd_field_t * upd_get_nth_field(const upd_t *update, ulint n)
Returns the nth field of an update vector.
void row_upd_index_replace_new_col_vals(dtuple_t *entry, const dict_index_t *index, const upd_t *update, mem_heap_t *heap)
Replaces the new column values stored in the update vector to the index entry given.
Definition: row0upd.cc:1174
byte * row_upd_write_sys_vals_to_log(dict_index_t *index, trx_id_t trx_id, roll_ptr_t roll_ptr, byte *log_ptr, mtr_t *mtr)
Writes into the redo log the values of trx id and roll ptr and enough info to determine their positio...
Definition: row0upd.cc:550
static void row_upd_rec_sys_fields(rec_t *rec, page_zip_des_t *page_zip, const dict_index_t *index, const ulint *offsets, const trx_t *trx, roll_ptr_t roll_ptr)
Updates the trx id and roll ptr field in a clustered index record when a row is updated or marked del...
constexpr uint32_t UPD_NODE_UPDATE_ALL_SEC
an ordering field of the clustered index record was changed, or this is a delete operation: should up...
Definition: row0upd.h:792
std::ostream & print_binary_diff(std::ostream &out, const Binary_diff *bdiff, const dict_table_t *table, const Field *field, bool print_old)
Print the given binary diff into the given output stream.
Definition: row0upd.cc:3369
ulint row_upd_changes_fts_column(dict_table_t *table, upd_field_t *upd_field)
Checks if an FTS indexed column is affected by an UPDATE.
Definition: row0upd.cc:1706
constexpr uint32_t UPD_NODE_SET_IX_LOCK
execution came to the node from a node above and if the field has_clust_rec_x_lock is false,...
Definition: row0upd.h:784
std::ostream & operator<<(std::ostream &out, const lob_index_diff_t &obj)
Overloading the global output operator to print lob_index_diff_t object.
Definition: row0upd.h:386
void row_upd_rec_sys_fields_in_recovery(rec_t *rec, page_zip_des_t *page_zip, const ulint *offsets, ulint pos, trx_id_t trx_id, roll_ptr_t roll_ptr)
Updates the trx id and roll ptr field in a clustered index record in database recovery.
Definition: row0upd.cc:306
constexpr uint32_t UPD_NODE_NO_SIZE_CHANGE
no record field size will be changed in the update
Definition: row0upd.h:802
upd_t * row_upd_build_sec_rec_difference_binary(const rec_t *rec, dict_index_t *index, const ulint *offsets, const dtuple_t *entry, mem_heap_t *heap)
Builds an update vector from those fields which in a secondary index entry differ from a record that ...
Definition: row0upd.cc:757
void row_upd_rec_in_place(rec_t *rec, const dict_index_t *index, const ulint *offsets, const upd_t *update, page_zip_des_t *page_zip)
Replaces the new column values stored in the update vector to the record given.
Definition: row0upd.cc:474
static bool upd_fld_is_virtual_col(const upd_field_t *upd_fld)
Definition: row0upd.h:550
void row_upd_replace_vcol(dtuple_t *row, const dict_table_t *table, const upd_t *update, bool upd_new, dtuple_t *undo_row, const byte *ptr)
Replaces the virtual column values stored in a dtuple with that of a update vector.
Definition: row0upd.cc:1233
uint64_t row_upd_get_new_autoinc_counter(const upd_t *update, ulint autoinc_field_no)
Get the new autoinc counter from the update vector when there is an autoinc field defined in this tab...
Definition: row0upd.cc:2700
void row_upd_index_replace_new_col_vals_index_pos(dtuple_t *entry, const dict_index_t *index, const upd_t *update, bool order_only, mem_heap_t *heap)
Replaces the new column values stored in the update vector to the index entry given.
Definition: row0upd.cc:1116
bool row_upd_changes_doc_id(dict_table_t *table, upd_field_t *upd_field)
Checks if an FTS Doc ID column is affected by an UPDATE.
Definition: row0upd.cc:1686
bool row_upd_changes_ord_field_binary_func(dict_index_t *index, const upd_t *update, const que_thr_t *thr, const dtuple_t *row, const row_ext_t *ext, bool *non_mv_upd, ulint flag)
Checks if an update vector changes an ordering field of an index record.
Definition: row0upd.cc:1429
Update of a row.
TempTable Table declarations.
The modification done to the LOB.
Definition: row0upd.h:392
std::ostream & print(std::ostream &out) const
Definition: row0upd.h:425
const byte * read_offset(const byte *undo_ptr)
Read the offset from the undo record.
Definition: row0upd.h:406
Lob_diff(mem_heap_t *mem_heap)
Constructor.
Definition: row0upd.h:396
const byte * m_old_data
Changes to the LOB data.
Definition: row0upd.h:451
mem_heap_t * heap
Memory heap in which this object is allocated.
Definition: row0upd.h:457
Lob_index_diff_vec * m_idx_diffs
Changes to the LOB index.
Definition: row0upd.h:454
const byte * read_length(const byte *undo_ptr)
Read the length from the undo record.
Definition: row0upd.h:415
ulint m_length
The length of the modification.
Definition: row0upd.h:448
void set_old_data(const byte *undo_ptr)
Definition: row0upd.h:423
ulint m_offset
The offset within LOB where partial update happened.
Definition: row0upd.h:445
Definition: ut.h:72
Definition: table.h:1421
Definition: completion_hash.h:35
Definition: btr0pcur.h:99
Structure for an SQL data field.
Definition: data0data.h:617
dtype_t type
type of data
Definition: data0data.h:624
bool is_virtual() const
Definition: data0data.h:628
Data structure for a foreign key constraint; an example: FOREIGN KEY (A, B) REFERENCES TABLE2 (C,...
Definition: dict0mem.h:1661
Data structure for an index.
Definition: dict0mem.h:1041
Data structure for a database table.
Definition: dict0mem.h:1904
const dict_index_t * first_index() const
Definition: dict0mem.h:2462
Structure for an SQL data tuple of fields (logical record)
Definition: data0data.h:696
unsigned prtype
precise type; MySQL data type, charset code, flags to indicate nullability, signedness,...
Definition: data0type.h:499
static const ulint LOB_SMALL_CHANGE_THRESHOLD
If the total number of bytes modified in an LOB, in an update operation, is less than or equal to thi...
Definition: lob0lob.h:210
This structure is used for undo logging of LOB index changes.
Definition: row0upd.h:365
undo_no_t m_modifier_undo_no
Definition: row0upd.h:367
trx_id_t m_modifier_trxid
Definition: row0upd.h:366
std::ostream & print(std::ostream &out) const
Print the current object into the given output stream.
Definition: row0upd.h:372
The info structure stored at the beginning of a heap block.
Definition: mem0mem.h:302
Mini-transaction handle and buffer.
Definition: mtr0mtr.h:177
Compressed page descriptor.
Definition: page0types.h:201
Definition: que0types.h:51
Definition: que0que.h:242
Prefixes of externally stored columns.
Definition: row0ext.h:95
Select statement node.
Definition: row0sel.h:329
Symbol table node.
Definition: pars0sym.h:113
Definition: trx0trx.h:675
Definition: row0upd.h:467
unsigned orig_len
original length of the locally stored part of an externally stored column, or 0
Definition: row0upd.h:491
dfield_t new_val
new value for the column
Definition: row0upd.h:499
undo_no_t last_undo_no
The last stmt within trx that modified the LOB.
Definition: row0upd.h:530
bool ext_in_old
If true, the field was stored externally in the old row.
Definition: row0upd.h:505
unsigned field_no
field number in an index, usually the clustered index, but in updating a secondary index record in bt...
Definition: row0upd.h:484
trx_id_t last_trx_id
The last trx that modified the LOB.
Definition: row0upd.h:527
void push_lob_diff(const Lob_diff &lob_diff)
Definition: row0upd.h:507
page_no_t lob_first_page_no
The LOB first page number.
Definition: row0upd.h:522
upd_field_t()
Definition: row0upd.h:468
dfield_t old_val
old value for the column
Definition: row0upd.h:498
std::ostream & print(std::ostream &out) const
Definition: row0upd.cc:3343
Field * mysql_field
the mysql field object.
Definition: row0upd.h:502
mem_heap_t * heap
Memory heap in which this object is allocated.
Definition: row0upd.h:542
que_node_t * exp
expression for calculating a new value: it refers to column values and constants in the symbol table ...
Definition: row0upd.h:494
Lob_diff_vector * lob_diffs
List of changes done to this updated field.
Definition: row0upd.h:518
uint16_t field_phy_pos
Definition: row0upd.h:490
bool is_virtual() const
Definition: row0upd.h:482
ulint lob_version
Definition: row0upd.h:524
dfield_t * old_v_val
old value for the virtual column
Definition: row0upd.h:500
void reset()
Empty the information collected on LOB diffs.
Definition: row0upd.h:535
Definition: row0upd.h:701
bool in_mysql_interface
Definition: row0upd.h:707
sym_node_list_t columns
Definition: row0upd.h:734
sym_node_t * table_sym
Definition: row0upd.h:762
dtuple_t * upd_row
Definition: row0upd.h:755
ulint update_n_fields
Definition: row0upd.h:729
dict_foreign_t * foreign
Definition: row0upd.h:710
dict_index_t * index
NULL, or the next index whose record should be updated.
Definition: row0upd.h:748
row_ext_t * ext
NULL, or prefixes of the externally stored columns in the old row.
Definition: row0upd.h:753
mem_heap_t * cascade_heap
NULL or a mem heap where cascade_upd_nodes are created.
Definition: row0upd.h:716
uint32_t del_multi_val_pos
When there is a lock wait error, this remembers current position of the multi-value field,...
Definition: row0upd.h:769
que_node_t * col_assign_list
Definition: row0upd.h:763
bool searched_update
Definition: row0upd.h:704
ulint state
node execution state
Definition: row0upd.h:747
upd_t * update
update vector for the row
Definition: row0upd.h:728
dict_table_t * table
table where updated
Definition: row0upd.h:727
sel_node_t * select
query graph subtree implementing a base table cursor: the rows returned will be updated
Definition: row0upd.h:719
btr_pcur_t * pcur
persistent cursor placed on the clustered index record which should be updated or deleted; the cursor...
Definition: row0upd.h:722
row_ext_t * upd_ext
Definition: row0upd.h:756
dtuple_t * row
NULL, or a copy (also fields copied to heap) of the row to update; this must be reset to NULL after a...
Definition: row0upd.h:750
que_common_t common
node type: QUE_NODE_UPDATE
Definition: row0upd.h:702
bool has_clust_rec_x_lock
Definition: row0upd.h:736
bool is_delete
Definition: row0upd.h:703
ulint magic_n
Definition: row0upd.h:775
uint32_t upd_multi_val_pos
When there is a lock wait error, this remembers current position of the multi-value field,...
Definition: row0upd.h:773
ulint cmpl_info
Definition: row0upd.h:741
mem_heap_t * heap
memory heap used as auxiliary storage; this must be emptied after a successful update
Definition: row0upd.h:758
upd_node_t * cascade_node
Definition: row0upd.h:713
Definition: row0upd.h:565
void append(const upd_field_t &field)
Append an update field to the end of array.
Definition: row0upd.h:596
static size_t get_total_modified_bytes(const Binary_diff_vector &bdv)
Calculate the total number of bytes modified in one BLOB.
Definition: row0upd.h:641
bool is_partially_updated(ulint field_no) const
Check if the given field number is partially updated.
Definition: row0upd.cc:3444
mem_heap_t * heap
Heap from which memory allocated.
Definition: row0upd.h:569
void free_per_stmt_heap()
Free the per_stmt_heap.
Definition: row0upd.h:657
bool validate() const
Definition: row0upd.h:617
void empty_per_stmt_heap()
Empty the per_stmt_heap.
Definition: row0upd.h:650
dtuple_t * old_vrow
Pointer to old row, used for virtual column update now.
Definition: row0upd.h:580
upd_field_t * fields
Array of update fields.
Definition: row0upd.h:592
ulint info_bits
New value of info bits to record; default is 0.
Definition: row0upd.h:577
mem_heap_t * per_stmt_heap
Heap from which memory is allocated if required only for current statement.
Definition: row0upd.h:574
const Binary_diff_vector * get_binary_diff_by_field_no(ulint field_no) const
Definition: row0upd.cc:3488
std::ostream & print(std::ostream &out) const
Definition: row0upd.cc:3359
dict_table_t * table
The table object.
Definition: row0upd.h:583
upd_field_t * get_field_by_field_no(ulint field_no, dict_index_t *index) const
Definition: row0upd.cc:3423
TABLE * mysql_table
The mysql table object.
Definition: row0upd.h:586
bool is_modified(const ulint field_no) const
Determine if the given field_no is modified.
Definition: row0upd.h:600
ulint n_fields
Number of update fields.
Definition: row0upd.h:589
void reset()
Reset the update fields.
Definition: row0upd.h:610
std::ostream & print_puvect(std::ostream &out, upd_field_t *uf) const
Print the partial update vector (puvect) of the given update field.
Definition: row0upd.cc:3405
Transaction system global type definitions.
ib_id_t undo_no_t
Undo number.
Definition: trx0types.h:142
ib_id_t trx_id_t
Transaction identifier (DB_TRX_ID, DATA_TRX_ID)
Definition: trx0types.h:138
ib_id_t roll_ptr_t
Rollback pointer (DB_ROLL_PTR, DATA_ROLL_PTR)
Definition: trx0types.h:140
Version control for database, common definitions, and include files.
#define IF_DEBUG(...)
Definition: univ.i:674
unsigned long int ulint
Definition: univ.i:406
#define ut_error
Abort execution.
Definition: ut0dbg.h:101
#define ut_ad(EXPR)
Debug assertion.
Definition: ut0dbg.h:105
#define ut_o(EXPR)
Opposite of ut_d().
Definition: ut0dbg.h:109
#define ut_d(EXPR)
Debug statement.
Definition: ut0dbg.h:107
int n
Definition: xcom_base.cc:509