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