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