MySQL 9.0.0
Source Code Documentation
rem0rec.h
Go to the documentation of this file.
1/*****************************************************************************
2
3Copyright (c) 1994, 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/rem0rec.h
29 Record manager
30
31 Created 5/30/1994 Heikki Tuuri
32 *************************************************************************/
33
34#ifndef rem0rec_h
35#define rem0rec_h
36
37#include <ostream>
38#include <sstream>
39
40#include "univ.i"
41
42#include "data0data.h"
43#include "mtr0types.h"
44#include "page0types.h"
45#include "rem/rec.h"
46#include "rem0types.h"
47#include "trx0types.h"
48#include "ut0class_life_cycle.h"
49
50#include "rem0wrec.h"
51
52/** The following function is used to get the pointer of the next chained record
53on the same page.
54@param[in] rec Physical record.
55@param[in] comp Nonzero=compact page format.
56@return pointer to the next chained record, or nullptr if none */
57[[nodiscard]] static inline const rec_t *rec_get_next_ptr_const(
58 const rec_t *rec, ulint comp);
59/** The following function is used to get the pointer of the next chained record
60on the same page.
61@param[in] rec Physical record.
62@param[in] comp Nonzero=compact page format.
63@return pointer to the next chained record, or nullptr if none */
64[[nodiscard]] static inline rec_t *rec_get_next_ptr(rec_t *rec, ulint comp);
65/** The following function is used to get the offset of the
66next chained record on the same page.
67@param[in] rec Physical record.
68@param[in] comp Nonzero=compact page format.
69@return the page offset of the next chained record, or 0 if none */
70[[nodiscard]] static inline ulint rec_get_next_offs(const rec_t *rec,
71 ulint comp);
72
73/** The following function is used to set the next record offset field of an
74old-style record.
75@param[in] rec old-style physical record
76@param[in] next offset of the next record */
77static inline void rec_set_next_offs_old(rec_t *rec, ulint next);
78
79/** The following function is used to set the next record offset field of a
80new-style record. */
81static inline void rec_set_next_offs_new(rec_t *rec, ulint next);
82
83/** The following function is used to get the number of records owned by the
84 previous directory record.
85 @return number of owned records */
86[[nodiscard]] static inline ulint rec_get_n_owned_old(
87 const rec_t *rec); /*!< in: old-style physical record */
88
89/** The following function is used to set the number of owned records.
90@param[in] rec old-style physical record
91@param[in] n_owned the number of owned */
92static inline void rec_set_n_owned_old(rec_t *rec, ulint n_owned);
93
94/** The following function is used to get the number of records owned by the
95 previous directory record.
96 @return number of owned records */
97[[nodiscard]] static inline ulint rec_get_n_owned_new(
98 const rec_t *rec); /*!< in: new-style physical record */
99
100/** The following function is used to set the number of owned records.
101@param[in,out] rec new-style physical record
102@param[in,out] page_zip compressed page, or NULL
103@param[in] n_owned the number of owned */
104static inline void rec_set_n_owned_new(rec_t *rec, page_zip_des_t *page_zip,
105 ulint n_owned);
106
107/** The following function is used to set the info bits of a record.
108@param[in] rec old-style physical record
109@param[in] bits info bits */
110static inline void rec_set_info_bits_old(rec_t *rec, ulint bits);
111
112/** The following function is used to set the info bits of a record.
113@param[in,out] rec new-style physical record
114@param[in] bits info bits */
115static inline void rec_set_info_bits_new(rec_t *rec, ulint bits);
116
117/** The following function is used to set the status bits of a new-style record.
118@param[in,out] rec physical record
119@param[in] bits info bits */
120static inline void rec_set_status(rec_t *rec, ulint bits);
121
122/** The following function is used to retrieve the info and status
123bits of a record. (Only compact records have status bits.)
124@param[in] rec Physical record.
125@param[in] comp Nonzero=compact page format.
126@return info bits */
127[[nodiscard]] static inline ulint rec_get_info_and_status_bits(const rec_t *rec,
128 bool comp);
129
130/** The following function is used to set the info and status bits of a record.
131(Only compact records have status bits.)
132@param[in,out] rec compact physical record
133@param[in] bits info bits */
134static inline void rec_set_info_and_status_bits(rec_t *rec, ulint bits);
135
136/** The following function tells if record is delete marked.
137@param[in] rec Physical record.
138@param[in] comp Nonzero=compact page format.
139@return nonzero if delete marked */
140[[nodiscard]] static inline bool rec_get_deleted_flag(const rec_t *rec,
141 bool comp);
142
143/** The following function is used to set the deleted bit.
144@param[in] rec old-style physical record
145@param[in] flag true if delete marked */
146static inline void rec_set_deleted_flag_old(rec_t *rec, bool flag);
147
148/** The following function is used to set the deleted bit.
149@param[in,out] rec new-style physical record
150@param[in,out] page_zip compressed page, or NULL
151@param[in] flag true if delete marked */
152static inline void rec_set_deleted_flag_new(rec_t *rec,
153 page_zip_des_t *page_zip,
154 bool flag);
155
156/** The following function is used to set the instant bit.
157@param[in,out] rec new-style physical record */
158static inline void rec_new_set_instant(rec_t *rec);
159
160/** The following function is used to set the row version bit.
161@param[in,out] rec new-style (COMPACT/DYNAMIC) physical record */
162static inline void rec_new_set_versioned(rec_t *rec);
163
164/** The following function is used to reset the instant bit and the row version
165bit.
166@param[in,out] rec new-style (COMPACT/DYNAMIC) physical record */
167static inline void rec_new_reset_instant_version(rec_t *rec);
168
169/** The following function is used to set the instant bit.
170@param[in,out] rec old-style (REDUNDANT) physical record
171@param[in] flag set the bit to this flag */
172static inline void rec_old_set_versioned(rec_t *rec, bool flag);
173
174/** The following function tells if a new-style record is a node pointer.
175 @return true if node pointer */
176[[nodiscard]] static inline bool rec_get_node_ptr_flag(
177 const rec_t *rec); /*!< in: physical record */
178
179/** The following function is used to get the order number of an old-style
180record in the heap of the index page.
181@param[in] rec physical record
182@return heap order number */
183[[nodiscard]] static inline ulint rec_get_heap_no_old(const rec_t *rec);
184
185/** The following function is used to set the heap number field in an old-style
186record.
187@param[in] rec physical record
188@param[in] heap_no the heap number */
189static inline void rec_set_heap_no_old(rec_t *rec, ulint heap_no);
190
191/** The following function is used to get the order number of a new-style
192record in the heap of the index page.
193@param[in] rec physical record
194@return heap order number */
195[[nodiscard]] static inline ulint rec_get_heap_no_new(const rec_t *rec);
196
197/** The following function is used to set the heap number field in a new-style
198record.
199@param[in,out] rec physical record
200@param[in] heap_no the heap number */
201static inline void rec_set_heap_no_new(rec_t *rec, ulint heap_no);
202
203/** The following function is used to set the 1-byte offsets flag.
204@param[in] rec physical record
205@param[in] flag true if 1byte form */
206static inline void rec_set_1byte_offs_flag(rec_t *rec, bool flag);
207
208/** Determine how many of the first n columns in a compact
209physical record are stored externally.
210@param[in] rec compact physical record
211@param[in] index record descriptor
212@param[in] n number of columns to scan
213@return number of externally stored columns */
214[[nodiscard]] ulint rec_get_n_extern_new(const rec_t *rec,
215 const dict_index_t *index, ulint n);
216
217/** Gets the value of the specified field in the record in old style.
218This is only used for record from instant index, which is clustered
219index and has some instantly added columns.
220@param[in] rec physical record
221@param[in] n index of the field
222@param[in] index clustered index where the record resides
223@param[out] len length of the field, UNIV_SQL if SQL null
224@return value of the field, could be either pointer to rec or default value */
225static inline const byte *rec_get_nth_field_old_instant(
226 const rec_t *rec, uint16_t n, const dict_index_t *index, ulint *len);
227
228/** Gets the value of the specified field in the record.
229This is only used when there is possibility that the record comes from the
230clustered index, which has some instantly added columns.
231@param[in] rec physical record
232@param[in] offsets array returned by rec_get_offsets()
233@param[in] n index of the field
234@param[in] index clustered index where the record resides, or nullptr
235 if the record doesn't have instantly added columns
236 for sure
237@param[out] len length of the field, UNIV_SQL_NULL if SQL null
238@return value of the field, could be either pointer to rec or default value */
239static inline const byte *rec_get_nth_field_instant(const rec_t *rec,
240 const ulint *offsets,
241 ulint n,
242 const dict_index_t *index,
243 ulint *len);
244
245/** Determine if the field is not NULL and not having default value
246after instant ADD COLUMN
247@param[in] len length of a field
248@return true if not NULL and not having default value */
250
251/** Determine if the offsets are for a record in the new compact format.
252@param[in] offsets array returned by rec_get_offsets()
253@return nonzero if compact format */
254[[nodiscard]] static inline bool rec_offs_comp(const ulint *offsets);
255
256/** Determine if the offsets are for a record containing externally stored
257columns.
258@param[in] offsets array returned by rec_get_offsets()
259@return nonzero if externally stored */
260[[nodiscard]] static inline bool rec_offs_any_extern(const ulint *offsets);
261
262/** Determine if the offsets are for a record containing null BLOB pointers.
263@param[in] index record descriptor
264@param[in] rec record
265@param[in] offsets array returned by rec_get_offsets()
266@return first field containing a null BLOB pointer, or NULL if none found */
267[[nodiscard]] static inline const byte *rec_offs_any_null_extern(
268 const dict_index_t *index, const rec_t *rec, const ulint *offsets);
269
270/** Returns the number of extern bits set in a record.
271@param[in] index record descriptor
272@param[in] offsets array returned by rec_get_offsets()
273@return number of externally stored fields */
274[[nodiscard]] static inline ulint rec_offs_n_extern(const dict_index_t *index,
275 const ulint *offsets);
276
277#define rec_offs_init(offsets) \
278 rec_offs_set_n_alloc(offsets, (sizeof offsets) / sizeof *offsets)
279
280/**
281A helper RAII wrapper for otherwise difficult to use sequence of:
282
283 ulint offsets_[REC_OFFS_NORMAL_SIZE];
284 rec_offs_init(offsets_);
285 mem_heap_t *heap = nullptr;
286
287 const ulint *offsets =
288 rec_get_offsets(rec, index, offsets_, ULINT_UNDEFINED, &heap);
289
290 DO_SOMETHING(offsets);
291
292 if (heap != nullptr) {
293 mem_heap_free(heap);
294 }
295
296With this helper you can simply do:
297
298 DO_SOMETHING(Rec_offsets().compute(rec,index));
299
300And if you need to reuse the memory allocated offsets several times you can:
301 Rec_offsets offsets;
302 for(rec: recs) DO_SOMTHING(offsets.compute(rec,index))
303*/
305 public:
306 /** Prepares offsets to initially point to the fixed-size buffer, and marks
307 the memory as allocated, but uninitialized. You first need to call compute()
308 to use it */
310
311 /** Computes offsets for given record. Returned array is owned by this
312 instance. You can use its value as long as this object does not go out of
313 scope (which can free the buffer), and you don't call compute() again (which
314 can overwrite the offsets).
315 @param[in] rec The record for which you want to compute the offsets
316 @param[in] index The index which contains the record
317 @param[in] n_fields Number of columns to scan
318 @return A pointer to offsets array owned by this instance. Valid till next
319 call to compute() or end of this instance lifetime.
320 */
321 const ulint *compute(const rec_t *rec, const dict_index_t *index,
322 const ulint n_fields = ULINT_UNDEFINED) {
323 m_offsets = rec_get_offsets(rec, index, m_offsets, n_fields,
325 return m_offsets;
326 }
327 /** Deallocated dynamically allocated memory, if any. */
329 if (m_heap) {
331 m_heap = nullptr;
332 }
333 }
334
335 private:
336 /** Pointer to heap used by rec_get_offsets(). Initially nullptr. If row is
337 really big, rec_get_offsets() may need to allocate new buffer for offsets.
338 At, first, when heap is null, rec_get_offsets() will create new heap, and pass
339 it back via reference. On subsequent calls, we will pass this heap, so it
340 is reused if needed. Therefore all allocated buffers are in this heap, if it
341 is not nullptr */
343
344 /** Buffer with size large enough to handle common cases without having to use
345 heap. This is the initial value of m_offsets.*/
347
348 /* Initially points to m_preallocated_buffer (which is uninitialized memory).
349 After each call to compute() contains the pointer to the most recently
350 computed offsets.
351 We pass it back to rec_get_offsets() on subsequent calls to compute() to reuse
352 the same memory if possible. */
354};
355
356/** The following function returns the data size of a physical
357record, that is the sum of field lengths. SQL null fields
358are counted as length 0 fields. The value returned by the function
359is the distance from record origin to record end in bytes.
360@param[in] offsets array returned by rec_get_offsets()
361@return size */
362[[nodiscard]] static inline ulint rec_offs_data_size(const ulint *offsets);
363
364/** Returns the total size of record minus data size of record.
365The value returned by the function is the distance from record
366start to record origin in bytes.
367@param[in] offsets array returned by rec_get_offsets()
368@return size */
369[[nodiscard]] static inline ulint rec_offs_extra_size(const ulint *offsets);
370
371/** Returns the total size of a physical record.
372@param[in] offsets array returned by rec_get_offsets()
373@return size */
374[[nodiscard]] static inline ulint rec_offs_size(const ulint *offsets);
375
376#ifdef UNIV_DEBUG
377/** Returns a pointer to the start of the record.
378@param[in] rec pointer to record
379@param[in] offsets array returned by rec_get_offsets()
380@return pointer to start */
381[[nodiscard]] static inline byte *rec_get_start(const rec_t *rec,
382 const ulint *offsets);
383
384/** Returns a pointer to the end of the record.
385@param[in] rec pointer to record
386@param[in] offsets array returned by rec_get_offsets()
387@return pointer to end */
388[[nodiscard]] static inline byte *rec_get_end(const rec_t *rec,
389 const ulint *offsets);
390#else /* UNIV_DEBUG */
391#define rec_get_start(rec, offsets) ((rec)-rec_offs_extra_size(offsets))
392#define rec_get_end(rec, offsets) ((rec) + rec_offs_data_size(offsets))
393#endif /* UNIV_DEBUG */
394
395/** Copy a physical record to a buffer.
396@param[in] buf buffer
397@param[in] rec physical record
398@param[in] offsets array returned by rec_get_offsets()
399@return pointer to the origin of the copy */
400static inline rec_t *rec_copy(void *buf, const rec_t *rec,
401 const ulint *offsets);
402
403#ifndef UNIV_HOTBACKUP
404/** Determines the size of a data tuple prefix in a temporary file.
405@param[in] index record descriptor
406@param[in] fields array of data fields
407@param[in] n_fields number of data fields
408@param[in] v_entry dtuple contains virtual column data
409@param[out] extra extra size
410@param[in] rec_version row version of record
411@return total size */
412[[nodiscard]] ulint rec_get_serialize_size(const dict_index_t *index,
413 const dfield_t *fields,
414 ulint n_fields,
415 const dtuple_t *v_entry,
416 ulint *extra, uint8_t rec_version);
417
418/** Determine the offset to each field in temporary file.
419@param[in] rec temporary file record
420@param[in] index record descriptor
421@param[in,out] offsets array of offsets
422 @see rec_serialize_dtuple() */
423void rec_deserialize_init_offsets(const rec_t *rec, const dict_index_t *index,
424 ulint *offsets);
425
426/** Builds a temporary file record out of a data tuple.
427@param[out] rec record
428@param[in] index record descriptor
429@param[in] fields array of data fields
430@param[in] n_fields number of fields
431@param[in] v_entry dtuple contains virtual column data
432@param[in] rec_version rec version
433@see rec_deserialize_init_offsets() */
434void rec_serialize_dtuple(rec_t *rec, const dict_index_t *index,
435 const dfield_t *fields, ulint n_fields,
436 const dtuple_t *v_entry, uint8_t rec_version);
437
438/** Copies the first n fields of a physical record to a new physical record in
439a buffer.
440@param[in] rec physical record
441@param[in] index record descriptor
442@param[in] n_fields number of fields to copy
443@param[in,out] buf memory buffer for the copied prefix, or NULL
444@param[in,out] buf_size buffer size
445@return own: copied record */
446rec_t *rec_copy_prefix_to_buf(const rec_t *rec, const dict_index_t *index,
447 ulint n_fields, byte **buf, size_t *buf_size);
448
449/** Compute a hash value of a prefix of a leaf page record.
450@param[in] rec leaf page record
451@param[in] offsets rec_get_offsets(rec)
452@param[in] n_fields number of complete fields to hash
453@param[in] n_bytes number of bytes to hash in the last field
454@param[in] hashed_value hash value of the index identifier
455@param[in] index index where the record resides
456@return the hashed value */
457[[nodiscard]] static inline uint64_t rec_hash(const rec_t *rec,
458 const ulint *offsets,
459 ulint n_fields, ulint n_bytes,
460 uint64_t hashed_value,
461 const dict_index_t *index);
462#endif /* !UNIV_HOTBACKUP */
463
464/** Builds a physical record out of a data tuple and stores it into the given
465buffer.
466@param[in] buf start address of the physical record
467@param[in] index record descriptor
468@param[in] dtuple data tuple
469@return pointer to the origin of physical record */
470[[nodiscard]] rec_t *rec_convert_dtuple_to_rec(byte *buf,
471 const dict_index_t *index,
472 const dtuple_t *dtuple);
473
474/** Returns the extra size of an old-style physical record if we know its
475 data size and number of fields.
476 @param[in] data_size data size
477 @param[in] n_fields number of fields
478 @param[in] has_ext true if tuple has ext fields
479 @return extra size */
481 ulint n_fields, bool has_ext);
482
483/** Determines the size of a data tuple prefix in ROW_FORMAT=COMPACT.
484@param[in] index record descriptor
485@param[in] fields array of data fields
486@param[in] n_fields number of data fields
487@param[out] extra extra size
488@return total size */
490 const dict_index_t *index, const dfield_t *fields, ulint n_fields,
491 ulint *extra);
492
493/** Determines the size of a data tuple in ROW_FORMAT=COMPACT.
494@param[in] index record descriptor; dict_table_is_comp() is
495 assumed to hold, even if it does not
496@param[in] status status bits of the record
497@param[in] fields array of data fields
498@param[in] n_fields number of data fields
499@param[out] extra extra size
500@return total size */
502 const dfield_t *fields, ulint n_fields,
503 ulint *extra);
504
505/** The following function returns the size of a data tuple when converted to
506a physical record.
507@param[in] index record descriptor
508@param[in] dtuple data tuple
509@return size */
510[[nodiscard]] static inline ulint rec_get_converted_size(
511 const dict_index_t *index, const dtuple_t *dtuple);
512
513#ifndef UNIV_HOTBACKUP
514/** Copies the first n fields of a physical record to a data tuple.
515The fields are copied to the memory heap.
516@param[out] tuple data tuple
517@param[in] rec physical record
518@param[in] index record descriptor
519@param[in] n_fields number of fields to copy
520@param[in] heap memory heap */
521void rec_copy_prefix_to_dtuple(dtuple_t *tuple, const rec_t *rec,
522 const dict_index_t *index, ulint n_fields,
523 mem_heap_t *heap);
524#endif /* !UNIV_HOTBACKUP */
525
526/** Get the length of the number of fields for any new style record.
527@param[in] n_fields number of fields in the record
528@return length of specified number of fields */
529static inline uint8_t rec_get_n_fields_length(ulint n_fields);
530
531/** Set the row version on one new style leaf page record.
532This is only needed for table after instant ADD/DROP COLUMN.
533@param[in,out] rec leaf page record
534@param[in] version row version */
535static inline void rec_set_instant_row_version_new(rec_t *rec, uint8_t version);
536
537/** Set the row version on one old style leaf page record.
538This is only needed for table after instant ADD/DROP COLUMN.
539@param[in,out] rec leaf page record
540@param[in] version row version */
541static inline void rec_set_instant_row_version_old(rec_t *rec, uint8_t version);
542
543/** Validates the consistency of a physical record.
544@param[in] rec physical record
545@param[in] offsets array returned by rec_get_offsets()
546@return true if ok */
547bool rec_validate(const rec_t *rec, const ulint *offsets);
548
549/** Prints an old-style physical record.
550@param[in] file File where to print
551@param[in] rec Physical record */
552void rec_print_old(FILE *file, const rec_t *rec);
553
554#ifndef UNIV_HOTBACKUP
555
556/** Prints a spatial index record.
557@param[in] file File where to print
558@param[in] rec Physical record
559@param[in] offsets Array returned by rec_get_offsets() */
560void rec_print_mbr_rec(FILE *file, const rec_t *rec, const ulint *offsets);
561
562/** Prints a physical record.
563@param[in] file file where to print
564@param[in] rec physical record
565@param[in] offsets array returned by rec_get_offsets() */
566void rec_print_new(FILE *file, const rec_t *rec, const ulint *offsets);
567
568/** Prints a physical record.
569@param[in] file File where to print
570@param[in] rec Physical record
571@param[in] index Record descriptor */
572void rec_print(FILE *file, const rec_t *rec, const dict_index_t *index);
573
574/** Pretty-print a record.
575@param[in,out] o output stream
576@param[in] rec physical record
577@param[in] info rec_get_info_bits(rec)
578@param[in] offsets rec_get_offsets(rec) */
579void rec_print(std::ostream &o, const rec_t *rec, ulint info,
580 const ulint *offsets);
581
582/** Wrapper for pretty-printing a record */
584 /** Constructor */
585 rec_index_print(const rec_t *rec, const dict_index_t *index)
586 : m_rec(rec), m_index(index) {}
587
588 /** Record */
589 const rec_t *m_rec;
590 /** Index */
592};
593
594/** Display a record.
595@param[in,out] o output stream
596@param[in] r record to display
597@return the output stream */
598std::ostream &operator<<(std::ostream &o, const rec_index_print &r);
599
600/** Wrapper for pretty-printing a record */
602 /** Constructor */
603 rec_offsets_print(const rec_t *rec, const ulint *offsets)
604 : m_rec(rec), m_offsets(offsets) {}
605
606 /** Record */
607 const rec_t *m_rec;
608 /** Offsets to each field */
610};
611
612/** Display a record.
613@param[in,out] o output stream
614@param[in] r record to display
615@return the output stream */
616std::ostream &operator<<(std::ostream &o, const rec_offsets_print &r);
617
618#ifdef UNIV_DEBUG
619/** Pretty-printer of records and tuples */
621 public:
622 /** Construct a pretty-printed record.
623 @param rec record with header
624 @param offsets rec_get_offsets(rec, ...) */
625 rec_printer(const rec_t *rec, const ulint *offsets) : std::ostringstream() {
626 rec_print(*this, rec, rec_get_info_bits(rec, rec_offs_comp(offsets)),
627 offsets);
628 }
629
630 /** Construct a pretty-printed record.
631 @param rec record, possibly lacking header
632 @param info rec_get_info_bits(rec)
633 @param offsets rec_get_offsets(rec, ...) */
634 rec_printer(const rec_t *rec, ulint info, const ulint *offsets)
635 : std::ostringstream() {
636 rec_print(*this, rec, info, offsets);
637 }
638
639 /** Construct a pretty-printed tuple.
640 @param tuple data tuple */
642 dtuple_print(*this, tuple);
643 }
644
645 /** Construct a pretty-printed tuple.
646 @param field array of data tuple fields
647 @param n number of fields */
649 dfield_print(*this, field, n);
650 }
651
652 /** Destructor */
653 virtual ~rec_printer() = default;
654
655 private:
656 /** Copy constructor */
658 /** Assignment operator */
660};
661#endif /* UNIV_DEBUG */
662
663/** Reads the DB_TRX_ID of a clustered index record.
664@param[in] rec record
665@param[in] index clustered index
666@return the value of DB_TRX_ID */
667[[nodiscard]] trx_id_t rec_get_trx_id(const rec_t *rec,
668 const dict_index_t *index);
669#endif /* UNIV_HOTBACKUP */
670
671/* Maximum lengths for the data in a physical record if the offsets
672are given in one byte (resp. two byte) format. */
673constexpr ulint REC_1BYTE_OFFS_LIMIT = 0x7FUL;
674constexpr ulint REC_2BYTE_OFFS_LIMIT = 0x7FFFUL;
675
676/* The data size of record must be smaller than this because we reserve
677two upmost bits in a two byte offset for special purposes */
678constexpr ulint REC_MAX_DATA_SIZE = 16384;
679
680/** For a given clustered index, version is to be stored on physical record.
681@param[in] index clustered index
682@param[in] n_tuple_fields number of fields in tuple
683@return true, if version is to be stored */
684bool is_store_version(const dict_index_t *index, size_t n_tuple_fields);
685
686/* A temp record, generated for a REDUNDANT row record, will have info bits
687iff table has INSTANT ADD columns. And if record has row version, then it will
688also be stored on temp record header. Following function finds the number of
689more bytes needed in record header to store this info.
690@param[in] index record descriptor
691@param[in] valid_version true if record has version
692@return number of bytes NULL pointer should be adjusted. */
694 bool valid_version);
695#include "rem0rec.ic"
696
697#endif
A helper RAII wrapper for otherwise difficult to use sequence of:
Definition: rem0rec.h:304
ulint m_preallocated_buffer[REC_OFFS_NORMAL_SIZE]
Buffer with size large enough to handle common cases without having to use heap.
Definition: rem0rec.h:346
~Rec_offsets()
Deallocated dynamically allocated memory, if any.
Definition: rem0rec.h:328
Rec_offsets()
Prepares offsets to initially point to the fixed-size buffer, and marks the memory as allocated,...
Definition: rem0rec.h:309
ulint * m_offsets
Definition: rem0rec.h:353
mem_heap_t * m_heap
Pointer to heap used by rec_get_offsets().
Definition: rem0rec.h:342
const ulint * compute(const rec_t *rec, const dict_index_t *index, const ulint n_fields=ULINT_UNDEFINED)
Computes offsets for given record.
Definition: rem0rec.h:321
Pretty-printer of records and tuples.
Definition: rem0rec.h:620
rec_printer(const dfield_t *field, ulint n)
Construct a pretty-printed tuple.
Definition: rem0rec.h:648
rec_printer(const rec_printer &other)
Copy constructor.
rec_printer & operator=(const rec_printer &other)
Assignment operator.
rec_printer(const rec_t *rec, const ulint *offsets)
Construct a pretty-printed record.
Definition: rem0rec.h:625
rec_printer(const rec_t *rec, ulint info, const ulint *offsets)
Construct a pretty-printed record.
Definition: rem0rec.h:634
rec_printer(const dtuple_t *tuple)
Construct a pretty-printed tuple.
Definition: rem0rec.h:641
virtual ~rec_printer()=default
Destructor.
A utility class which, if inherited from, prevents the descendant class from being copied,...
Definition: ut0class_life_cycle.h:41
constexpr DWORD buf_size
Definition: create_def.cc:229
void dtuple_print(FILE *f, const dtuple_t *tuple)
The following function prints the contents of a tuple.
Definition: data0data.cc:368
void dfield_print(std::ostream &o, const dfield_t *field, ulint n)
Print the contents of a tuple.
Definition: data0data.cc:385
SQL data field and tuple.
static int flag
Definition: hp_test1.cc:40
static void mem_heap_free(mem_heap_t *heap)
Frees the space occupied by a memory heap.
Mini-transaction buffer global types.
Definition: buf0block_hint.cc:30
const std::string FILE("FILE")
Definition: os0file.h:89
Definition: gcs_xcom_synode.h:64
std::basic_ostringstream< char, std::char_traits< char >, ut::allocator< char > > ostringstream
Specialization of basic_ostringstream which uses ut::allocator.
Definition: ut0new.h:2871
Index page routines.
const mysql_service_registry_t * r
Definition: pfs_example_plugin_employee.cc:86
ulint * rec_get_offsets(const rec_t *rec, const dict_index_t *index, ulint *offsets, ulint n_fields, ut::Location location, mem_heap_t **heap)
The following function determines the offsets to each field in the record.
Definition: rec.cc:359
Record manager.
static ulint rec_get_info_bits(const rec_t *rec, ulint comp)
The following function is used to retrieve the info bits of a record.
Definition: rec.h:328
constexpr uint32_t REC_OFFS_NORMAL_SIZE
Definition: rec.h:209
static const byte * rec_get_nth_field_instant(const rec_t *rec, const ulint *offsets, ulint n, const dict_index_t *index, ulint *len)
Gets the value of the specified field in the record.
void rec_print(FILE *file, const rec_t *rec, const dict_index_t *index)
Prints a physical record.
Definition: rem0rec.cc:1779
ulint rec_get_n_extern_new(const rec_t *rec, const dict_index_t *index, ulint n)
Determine how many of the first n columns in a compact physical record are stored externally.
Definition: rem0rec.cc:175
ulint rec_get_serialize_size(const dict_index_t *index, const dfield_t *fields, ulint n_fields, const dtuple_t *v_entry, ulint *extra, uint8_t rec_version)
Determines the size of a data tuple prefix in a temporary file.
Definition: rem0rec.cc:1156
static void rec_set_n_owned_old(rec_t *rec, ulint n_owned)
The following function is used to set the number of owned records.
static bool rec_get_node_ptr_flag(const rec_t *rec)
The following function tells if a new-style record is a node pointer.
void rec_deserialize_init_offsets(const rec_t *rec, const dict_index_t *index, ulint *offsets)
Determine the offset to each field in temporary file.
Definition: rem0rec.cc:1165
ulint rec_get_converted_size_comp_prefix(const dict_index_t *index, const dfield_t *fields, ulint n_fields, ulint *extra)
Determines the size of a data tuple prefix in ROW_FORMAT=COMPACT.
Definition: rem0rec.cc:504
void rec_print_new(FILE *file, const rec_t *rec, const ulint *offsets)
Prints a physical record.
Definition: rem0rec.cc:1743
static void rec_new_set_instant(rec_t *rec)
The following function is used to set the instant bit.
static void rec_set_info_bits_old(rec_t *rec, ulint bits)
The following function is used to set the info bits of a record.
static void rec_set_next_offs_old(rec_t *rec, ulint next)
The following function is used to set the next record offset field of an old-style record.
bool is_store_version(const dict_index_t *index, size_t n_tuple_fields)
For a given clustered index, version is to be stored on physical record.
Definition: rem0rec.cc:247
ulint rec_get_converted_size_comp(const dict_index_t *index, ulint status, const dfield_t *fields, ulint n_fields, ulint *extra)
Determines the size of a data tuple in ROW_FORMAT=COMPACT.
Definition: rem0rec.cc:518
static void rec_set_status(rec_t *rec, ulint bits)
The following function is used to set the status bits of a new-style record.
#define rec_offs_init(offsets)
Definition: rem0rec.h:277
static ulint rec_get_converted_size(const dict_index_t *index, const dtuple_t *dtuple)
The following function returns the size of a data tuple when converted to a physical record.
trx_id_t rec_get_trx_id(const rec_t *rec, const dict_index_t *index)
Reads the DB_TRX_ID of a clustered index record.
Definition: rem0rec.cc:1879
static void rec_new_reset_instant_version(rec_t *rec)
The following function is used to reset the instant bit and the row version bit.
static const byte * rec_offs_any_null_extern(const dict_index_t *index, const rec_t *rec, const ulint *offsets)
Determine if the offsets are for a record containing null BLOB pointers.
static void rec_set_n_owned_new(rec_t *rec, page_zip_des_t *page_zip, ulint n_owned)
The following function is used to set the number of owned records.
constexpr ulint REC_MAX_DATA_SIZE
Definition: rem0rec.h:678
static ulint rec_offs_size(const ulint *offsets)
Returns the total size of a physical record.
static const rec_t * rec_get_next_ptr_const(const rec_t *rec, ulint comp)
The following function is used to get the pointer of the next chained record on the same page.
static bool rec_get_deleted_flag(const rec_t *rec, bool comp)
The following function tells if record is delete marked.
static ulint rec_get_n_owned_new(const rec_t *rec)
The following function is used to get the number of records owned by the previous directory record.
static ulint rec_get_heap_no_old(const rec_t *rec)
The following function is used to get the order number of an old-style record in the heap of the inde...
static void rec_new_set_versioned(rec_t *rec)
The following function is used to set the row version bit.
static void rec_set_heap_no_new(rec_t *rec, ulint heap_no)
The following function is used to set the heap number field in a new-style record.
static void rec_old_set_versioned(rec_t *rec, bool flag)
The following function is used to set the instant bit.
void rec_serialize_dtuple(rec_t *rec, const dict_index_t *index, const dfield_t *fields, ulint n_fields, const dtuple_t *v_entry, uint8_t rec_version)
Builds a temporary file record out of a data tuple.
Definition: rem0rec.cc:1182
static byte * rec_get_start(const rec_t *rec, const ulint *offsets)
Returns a pointer to the start of the record.
size_t get_extra_bytes_for_temp_redundant(const dict_index_t *index, bool valid_version)
Definition: rem0rec.cc:716
static rec_t * rec_get_next_ptr(rec_t *rec, ulint comp)
The following function is used to get the pointer of the next chained record on the same page.
static ulint rec_get_converted_extra_size(ulint data_size, ulint n_fields, bool has_ext)
Returns the extra size of an old-style physical record if we know its data size and number of fields.
void rec_copy_prefix_to_dtuple(dtuple_t *tuple, const rec_t *rec, const dict_index_t *index, ulint n_fields, mem_heap_t *heap)
Copies the first n fields of a physical record to a data tuple.
Definition: rem0rec.cc:1191
static bool rec_offs_any_extern(const ulint *offsets)
Determine if the offsets are for a record containing externally stored columns.
static void rec_set_instant_row_version_new(rec_t *rec, uint8_t version)
Set the row version on one new style leaf page record.
static ulint rec_get_info_and_status_bits(const rec_t *rec, bool comp)
The following function is used to retrieve the info and status bits of a record.
void rec_print_mbr_rec(FILE *file, const rec_t *rec, const ulint *offsets)
Prints a spatial index record.
Definition: rem0rec.cc:1683
static ulint rec_offs_data_size(const ulint *offsets)
The following function returns the data size of a physical record, that is the sum of field lengths.
static bool rec_field_not_null_not_add_col_def(ulint len)
Determine if the field is not NULL and not having default value after instant ADD COLUMN.
static void rec_set_next_offs_new(rec_t *rec, ulint next)
The following function is used to set the next record offset field of a new-style record.
static bool rec_offs_comp(const ulint *offsets)
Determine if the offsets are for a record in the new compact format.
static void rec_set_info_and_status_bits(rec_t *rec, ulint bits)
The following function is used to set the info and status bits of a record.
static ulint rec_get_n_owned_old(const rec_t *rec)
The following function is used to get the number of records owned by the previous directory record.
static ulint rec_get_next_offs(const rec_t *rec, ulint comp)
The following function is used to get the offset of the next chained record on the same page.
std::ostream & operator<<(std::ostream &o, const rec_index_print &r)
Display a record.
Definition: rem0rec.cc:1857
static void rec_set_deleted_flag_old(rec_t *rec, bool flag)
The following function is used to set the deleted bit.
static ulint rec_offs_n_extern(const dict_index_t *index, const ulint *offsets)
Returns the number of extern bits set in a record.
static ulint rec_get_heap_no_new(const rec_t *rec)
The following function is used to get the order number of a new-style record in the heap of the index...
static const byte * rec_get_nth_field_old_instant(const rec_t *rec, uint16_t n, const dict_index_t *index, ulint *len)
Gets the value of the specified field in the record in old style.
void rec_print_old(FILE *file, const rec_t *rec)
Prints an old-style physical record.
Definition: rem0rec.cc:1521
bool rec_validate(const rec_t *rec, const ulint *offsets)
Validates the consistency of a physical record.
Definition: rem0rec.cc:1446
static uint64_t rec_hash(const rec_t *rec, const ulint *offsets, ulint n_fields, ulint n_bytes, uint64_t hashed_value, const dict_index_t *index)
Compute a hash value of a prefix of a leaf page record.
static void rec_set_heap_no_old(rec_t *rec, ulint heap_no)
The following function is used to set the heap number field in an old-style record.
static ulint rec_offs_extra_size(const ulint *offsets)
Returns the total size of record minus data size of record.
constexpr ulint REC_2BYTE_OFFS_LIMIT
Definition: rem0rec.h:674
rec_t * rec_copy_prefix_to_buf(const rec_t *rec, const dict_index_t *index, ulint n_fields, byte **buf, size_t *buf_size)
Copies the first n fields of a physical record to a new physical record in a buffer.
Definition: rem0rec.cc:1271
static rec_t * rec_copy(void *buf, const rec_t *rec, const ulint *offsets)
Copy a physical record to a buffer.
static void rec_set_info_bits_new(rec_t *rec, ulint bits)
The following function is used to set the info bits of a record.
static void rec_set_instant_row_version_old(rec_t *rec, uint8_t version)
Set the row version on one old style leaf page record.
rec_t * rec_convert_dtuple_to_rec(byte *buf, const dict_index_t *index, const dtuple_t *dtuple)
Builds a physical record out of a data tuple and stores it into the given buffer.
Definition: rem0rec.cc:1104
constexpr ulint REC_1BYTE_OFFS_LIMIT
Definition: rem0rec.h:673
static byte * rec_get_end(const rec_t *rec, const ulint *offsets)
Returns a pointer to the end of the record.
static uint8_t rec_get_n_fields_length(ulint n_fields)
Get the length of the number of fields for any new style record.
static void rec_set_deleted_flag_new(rec_t *rec, page_zip_des_t *page_zip, bool flag)
The following function is used to set the deleted bit.
static void rec_set_1byte_offs_flag(rec_t *rec, bool flag)
The following function is used to set the 1-byte offsets flag.
Record manager.
Record manager global types.
byte rec_t
Definition: rem0types.h:41
Record manager wrapper declaration.
required uint32 status
Definition: replication_asynchronous_connection_failover.proto:61
required uint64 version
Definition: replication_group_member_actions.proto:41
Structure for an SQL data field.
Definition: data0data.h:605
Data structure for an index.
Definition: dict0mem.h:1046
Structure for an SQL data tuple of fields (logical record)
Definition: data0data.h:684
The info structure stored at the beginning of a heap block.
Definition: mem0mem.h:302
Compressed page descriptor.
Definition: page0types.h:201
Part of traditional "extra" column or related hierarchical property.
Definition: opt_explain_format.h:267
Wrapper for pretty-printing a record.
Definition: rem0rec.h:583
const dict_index_t * m_index
Index.
Definition: rem0rec.h:591
const rec_t * m_rec
Record.
Definition: rem0rec.h:589
rec_index_print(const rec_t *rec, const dict_index_t *index)
Constructor.
Definition: rem0rec.h:585
Wrapper for pretty-printing a record.
Definition: rem0rec.h:601
const rec_t * m_rec
Record.
Definition: rem0rec.h:607
const ulint * m_offsets
Offsets to each field.
Definition: rem0rec.h:609
rec_offsets_print(const rec_t *rec, const ulint *offsets)
Constructor.
Definition: rem0rec.h:603
Transaction system global type definitions.
ib_id_t trx_id_t
Transaction identifier (DB_TRX_ID, DATA_TRX_ID)
Definition: trx0types.h:138
Version control for database, common definitions, and include files.
unsigned long int ulint
Definition: univ.i:406
constexpr ulint ULINT_UNDEFINED
The 'undefined' value for a ulint.
Definition: univ.i:420
Utilities related to class lifecycle.
#define UT_LOCATION_HERE
Definition: ut0core.h:73
int n
Definition: xcom_base.cc:509