MySQL 26.10.0
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(
410 const dict_index_t *index, const dfield_t *fields, ulint n_fields,
411 const dtuple_t *v_entry, ulint *extra, row_version_t rec_version);
412
413/** Determine the offset to each field in temporary file.
414@param[in] rec temporary file record
415@param[in] index record descriptor
416@param[in,out] offsets array of offsets
417 @see rec_serialize_dtuple() */
419 ulint *offsets);
420
421/** Builds a temporary file record out of a data tuple.
422@param[out] rec record
423@param[in] index record descriptor
424@param[in] fields array of data fields
425@param[in] n_fields number of fields
426@param[in] v_entry dtuple contains virtual column data
427@param[in] rec_version rec version
428@see rec_deserialize_init_offsets() */
430 const dfield_t *fields, ulint n_fields,
431 const dtuple_t *v_entry, row_version_t rec_version);
432
433/** Copies the first n fields of a physical record to a new physical record in
434a buffer.
435@param[in] rec physical record
436@param[in] index record descriptor
437@param[in] n_fields number of fields to copy
438@param[in,out] buf memory buffer for the copied prefix, or NULL
439@param[in,out] buf_size buffer size
440@return own: copied record */
442 ulint n_fields, byte **buf, size_t *buf_size);
443
444/** Compute a hash value of a prefix of a leaf page record.
445@param[in] rec leaf page record
446@param[in] offsets rec_get_offsets(rec)
447@param[in] n_fields number of complete fields to hash
448@param[in] n_bytes number of bytes to hash in the last field
449@param[in] hashed_value hash value of the index identifier
450@param[in] index index where the record resides
451@return the hashed value */
452[[nodiscard]] static inline uint64_t rec_hash(const rec_t *rec,
453 const ulint *offsets,
454 ulint n_fields, ulint n_bytes,
455 uint64_t hashed_value,
456 const dict_index_t *index);
457#endif /* !UNIV_HOTBACKUP */
458
459/** Builds a physical record out of a data tuple and stores it into the given
460buffer.
461@param[in] buf start address of the physical record
462@param[in] index record descriptor
463@param[in] dtuple data tuple
464@return pointer to the origin of physical record */
465[[nodiscard]] rec_t *rec_convert_dtuple_to_rec(byte *buf,
466 const dict_index_t *index,
467 const dtuple_t *dtuple);
468
469/** Returns the extra size of an old-style physical record if we know its
470 data size and number of fields.
471 @param[in] data_size data size
472 @param[in] n_fields number of fields
473 @param[in] has_ext true if tuple has ext fields
474 @return extra size */
476 ulint n_fields, bool has_ext);
477
478/** Determines the size of a data tuple prefix in ROW_FORMAT=COMPACT.
479@param[in] index record descriptor
480@param[in] fields array of data fields
481@param[in] n_fields number of data fields
482@param[out] extra extra size
483@return total size */
485 const dict_index_t *index, const dfield_t *fields, ulint n_fields,
486 ulint *extra);
487
488/** Determines the size of a data tuple in ROW_FORMAT=COMPACT.
489@param[in] index record descriptor; dict_table_is_comp() is
490 assumed to hold, even if it does not
491@param[in] status status bits of the record
492@param[in] fields array of data fields
493@param[in] n_fields number of data fields
494@param[out] extra extra size
495@return total size */
497 const dfield_t *fields, ulint n_fields,
498 ulint *extra);
499
500/** The following function returns the size of a data tuple when converted to
501a physical record.
502@param[in] index record descriptor
503@param[in] dtuple data tuple
504@return size */
505[[nodiscard]] static inline ulint rec_get_converted_size(
506 const dict_index_t *index, const dtuple_t *dtuple);
507
508#ifndef UNIV_HOTBACKUP
509/** Copies the first n fields of a physical record to a data tuple.
510The fields are copied to the memory heap.
511@param[out] tuple data tuple
512@param[in] rec physical record
513@param[in] index record descriptor
514@param[in] n_fields number of fields to copy
515@param[in] heap memory heap */
516void rec_copy_prefix_to_dtuple(dtuple_t *tuple, const rec_t *rec,
517 const dict_index_t *index, ulint n_fields,
518 mem_heap_t *heap);
519#endif /* !UNIV_HOTBACKUP */
520
521/** Get the length of the number of fields for any new style record.
522@param[in] n_fields number of fields in the record
523@return length of specified number of fields */
524static inline uint8_t rec_get_n_fields_length(ulint n_fields);
525
526/** Set the row version on one new style leaf page record.
527This is only needed for table after instant ADD/DROP COLUMN.
528@param[in,out] rec leaf page record
529@param[in] version row version */
532
533/** Set the row version on one old style leaf page record.
534This is only needed for table after instant ADD/DROP COLUMN.
535@param[in,out] rec leaf page record
536@param[in] version row 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 */
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:74
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
bool index(const std::string &value, const String &search_for, uint32_t *idx)
Definition: contains.h:76
Define std::hash<Gtid>.
Definition: gtid.h:355
std::basic_ostringstream< char, std::char_traits< char >, ut::allocator< char > > ostringstream
Specialization of basic_ostringstream which uses ut::allocator.
Definition: ut0new.h:2720
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 void rec_set_instant_row_version_old(rec_t *rec, row_version_t version)
Set the row version on one old style leaf page record.
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:1777
static void rec_set_instant_row_version_new(rec_t *rec, row_version_t version)
Set the row version on one new style leaf page record.
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
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:1163
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:1741
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: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:1877
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.
ulint rec_get_serialize_size(const dict_index_t *index, const dfield_t *fields, ulint n_fields, const dtuple_t *v_entry, ulint *extra, row_version_t rec_version)
Determines the size of a data tuple prefix in a temporary file.
Definition: rem0rec.cc:1154
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.
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:1189
static bool rec_offs_any_extern(const ulint *offsets)
Determine if the offsets are for a record containing externally stored columns.
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:1681
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:1855
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:1519
bool rec_validate(const rec_t *rec, const ulint *offsets)
Validates the consistency of a physical record.
Definition: rem0rec.cc:1444
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.
void rec_serialize_dtuple(rec_t *rec, const dict_index_t *index, const dfield_t *fields, ulint n_fields, const dtuple_t *v_entry, row_version_t rec_version)
Builds a temporary file record out of a data tuple.
Definition: rem0rec.cc:1180
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:1269
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.
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:1102
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
uint16_t row_version_t
Definition: rem0types.h:53
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:625
Data structure for an index.
Definition: dict0mem.h:1069
Structure for an SQL data tuple of fields (logical record)
Definition: data0data.h:706
The info structure stored at the beginning of a heap block.
Definition: mem0mem.h:295
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:403
constexpr ulint ULINT_UNDEFINED
The 'undefined' value for a ulint.
Definition: univ.i:417
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