MySQL 9.1.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 set the heap number field in an old-style
180record.
181@param[in] rec physical record
182@param[in] heap_no the heap number */
183static inline void rec_set_heap_no_old(rec_t *rec, ulint heap_no);
184
185/** The following function is used to set the heap number field in a new-style
186record.
187@param[in,out] rec physical record
188@param[in] heap_no the heap number */
189static inline void rec_set_heap_no_new(rec_t *rec, ulint heap_no);
190
191/** The following function is used to set the 1-byte offsets flag.
192@param[in] rec physical record
193@param[in] flag true if 1byte form */
194static inline void rec_set_1byte_offs_flag(rec_t *rec, bool flag);
195
196/** Determine how many of the first n columns in a compact
197physical record are stored externally.
198@param[in] rec compact physical record
199@param[in] index record descriptor
200@param[in] n number of columns to scan
201@return number of externally stored columns */
202[[nodiscard]] ulint rec_get_n_extern_new(const rec_t *rec,
203 const dict_index_t *index, ulint n);
204
205/** Gets the value of the specified field in the record in old style.
206This is only used for record from instant index, which is clustered
207index and has some instantly added columns.
208@param[in] rec physical record
209@param[in] n index of the field
210@param[in] index clustered index where the record resides
211@param[out] len length of the field, UNIV_SQL if SQL null
212@return value of the field, could be either pointer to rec or default value */
213static inline const byte *rec_get_nth_field_old_instant(
214 const rec_t *rec, uint16_t n, const dict_index_t *index, ulint *len);
215
216/** Gets the value of the specified field in the record.
217This is only used when there is possibility that the record comes from the
218clustered index, which has some instantly added columns.
219@param[in] rec physical record
220@param[in] offsets array returned by rec_get_offsets()
221@param[in] n index of the field
222@param[in] index clustered index where the record resides, or nullptr
223 if the record doesn't have instantly added columns
224 for sure
225@param[out] len length of the field, UNIV_SQL_NULL if SQL null
226@return value of the field, could be either pointer to rec or default value */
227static inline const byte *rec_get_nth_field_instant(const rec_t *rec,
228 const ulint *offsets,
229 ulint n,
230 const dict_index_t *index,
231 ulint *len);
232
233/** Determine if the field is not NULL and not having default value
234after instant ADD COLUMN
235@param[in] len length of a field
236@return true if not NULL and not having default value */
238
239/** Determine if the offsets are for a record in the new compact format.
240@param[in] offsets array returned by rec_get_offsets()
241@return nonzero if compact format */
242[[nodiscard]] static inline bool rec_offs_comp(const ulint *offsets);
243
244/** Determine if the offsets are for a record containing externally stored
245columns.
246@param[in] offsets array returned by rec_get_offsets()
247@return nonzero if externally stored */
248[[nodiscard]] static inline bool rec_offs_any_extern(const ulint *offsets);
249
250/** Determine if the offsets are for a record containing null BLOB pointers.
251@param[in] index record descriptor
252@param[in] rec record
253@param[in] offsets array returned by rec_get_offsets()
254@return first field containing a null BLOB pointer, or NULL if none found */
255[[nodiscard]] static inline const byte *rec_offs_any_null_extern(
256 const dict_index_t *index, const rec_t *rec, const ulint *offsets);
257
258/** Returns the number of extern bits set in a record.
259@param[in] index record descriptor
260@param[in] offsets array returned by rec_get_offsets()
261@return number of externally stored fields */
262[[nodiscard]] static inline ulint rec_offs_n_extern(const dict_index_t *index,
263 const ulint *offsets);
264
265#define rec_offs_init(offsets) \
266 rec_offs_set_n_alloc(offsets, (sizeof offsets) / sizeof *offsets)
267
268/**
269A helper RAII wrapper for otherwise difficult to use sequence of:
270
271 ulint offsets_[REC_OFFS_NORMAL_SIZE];
272 rec_offs_init(offsets_);
273 mem_heap_t *heap = nullptr;
274
275 const ulint *offsets =
276 rec_get_offsets(rec, index, offsets_, ULINT_UNDEFINED, &heap);
277
278 DO_SOMETHING(offsets);
279
280 if (heap != nullptr) {
281 mem_heap_free(heap);
282 }
283
284With this helper you can simply do:
285
286 DO_SOMETHING(Rec_offsets().compute(rec,index));
287
288And if you need to reuse the memory allocated offsets several times you can:
289 Rec_offsets offsets;
290 for(rec: recs) DO_SOMTHING(offsets.compute(rec,index))
291*/
293 public:
294 /** Prepares offsets to initially point to the fixed-size buffer, and marks
295 the memory as allocated, but uninitialized. You first need to call compute()
296 to use it */
298
299 /** Computes offsets for given record. Returned array is owned by this
300 instance. You can use its value as long as this object does not go out of
301 scope (which can free the buffer), and you don't call compute() again (which
302 can overwrite the offsets).
303 @param[in] rec The record for which you want to compute the offsets
304 @param[in] index The index which contains the record
305 @param[in] n_fields Number of columns to scan
306 @return A pointer to offsets array owned by this instance. Valid till next
307 call to compute() or end of this instance lifetime.
308 */
309 const ulint *compute(const rec_t *rec, const dict_index_t *index,
310 const ulint n_fields = ULINT_UNDEFINED) {
311 m_offsets = rec_get_offsets(rec, index, m_offsets, n_fields,
313 return m_offsets;
314 }
315 /** Deallocated dynamically allocated memory, if any. */
317 if (m_heap) {
319 m_heap = nullptr;
320 }
321 }
322
323 private:
324 /** Pointer to heap used by rec_get_offsets(). Initially nullptr. If row is
325 really big, rec_get_offsets() may need to allocate new buffer for offsets.
326 At, first, when heap is null, rec_get_offsets() will create new heap, and pass
327 it back via reference. On subsequent calls, we will pass this heap, so it
328 is reused if needed. Therefore all allocated buffers are in this heap, if it
329 is not nullptr */
331
332 /** Buffer with size large enough to handle common cases without having to use
333 heap. This is the initial value of m_offsets.*/
335
336 /* Initially points to m_preallocated_buffer (which is uninitialized memory).
337 After each call to compute() contains the pointer to the most recently
338 computed offsets.
339 We pass it back to rec_get_offsets() on subsequent calls to compute() to reuse
340 the same memory if possible. */
342};
343
344/** The following function returns the data size of a physical
345record, that is the sum of field lengths. SQL null fields
346are counted as length 0 fields. The value returned by the function
347is the distance from record origin to record end in bytes.
348@param[in] offsets array returned by rec_get_offsets()
349@return size */
350[[nodiscard]] static inline ulint rec_offs_data_size(const ulint *offsets);
351
352/** Returns the total size of record minus data size of record.
353The value returned by the function is the distance from record
354start to record origin in bytes.
355@param[in] offsets array returned by rec_get_offsets()
356@return size */
357[[nodiscard]] static inline ulint rec_offs_extra_size(const ulint *offsets);
358
359/** Returns the total size of a physical record.
360@param[in] offsets array returned by rec_get_offsets()
361@return size */
362[[nodiscard]] static inline ulint rec_offs_size(const ulint *offsets);
363
364#ifdef UNIV_DEBUG
365/** Returns a pointer to the start of the record.
366@param[in] rec pointer to record
367@param[in] offsets array returned by rec_get_offsets()
368@return pointer to start */
369[[nodiscard]] static inline byte *rec_get_start(const rec_t *rec,
370 const ulint *offsets);
371
372/** Returns a pointer to the end of the record.
373@param[in] rec pointer to record
374@param[in] offsets array returned by rec_get_offsets()
375@return pointer to end */
376[[nodiscard]] static inline byte *rec_get_end(const rec_t *rec,
377 const ulint *offsets);
378#else /* UNIV_DEBUG */
379#define rec_get_start(rec, offsets) ((rec)-rec_offs_extra_size(offsets))
380#define rec_get_end(rec, offsets) ((rec) + rec_offs_data_size(offsets))
381#endif /* UNIV_DEBUG */
382
383/** Copy a physical record to a buffer.
384@param[in] buf buffer
385@param[in] rec physical record
386@param[in] offsets array returned by rec_get_offsets()
387@return pointer to the origin of the copy */
388static inline rec_t *rec_copy(void *buf, const rec_t *rec,
389 const ulint *offsets);
390
391#ifndef UNIV_HOTBACKUP
392/** Determines the size of a data tuple prefix in a temporary file.
393@param[in] index record descriptor
394@param[in] fields array of data fields
395@param[in] n_fields number of data fields
396@param[in] v_entry dtuple contains virtual column data
397@param[out] extra extra size
398@param[in] rec_version row version of record
399@return total size */
400[[nodiscard]] ulint rec_get_serialize_size(
401 const dict_index_t *index, const dfield_t *fields, ulint n_fields,
402 const dtuple_t *v_entry, ulint *extra, row_version_t rec_version);
403
404/** Determine the offset to each field in temporary file.
405@param[in] rec temporary file record
406@param[in] index record descriptor
407@param[in,out] offsets array of offsets
408 @see rec_serialize_dtuple() */
409void rec_deserialize_init_offsets(const rec_t *rec, const dict_index_t *index,
410 ulint *offsets);
411
412/** Builds a temporary file record out of a data tuple.
413@param[out] rec record
414@param[in] index record descriptor
415@param[in] fields array of data fields
416@param[in] n_fields number of fields
417@param[in] v_entry dtuple contains virtual column data
418@param[in] rec_version rec version
419@see rec_deserialize_init_offsets() */
420void rec_serialize_dtuple(rec_t *rec, const dict_index_t *index,
421 const dfield_t *fields, ulint n_fields,
422 const dtuple_t *v_entry, row_version_t rec_version);
423
424/** Copies the first n fields of a physical record to a new physical record in
425a buffer.
426@param[in] rec physical record
427@param[in] index record descriptor
428@param[in] n_fields number of fields to copy
429@param[in,out] buf memory buffer for the copied prefix, or NULL
430@param[in,out] buf_size buffer size
431@return own: copied record */
432rec_t *rec_copy_prefix_to_buf(const rec_t *rec, const dict_index_t *index,
433 ulint n_fields, byte **buf, size_t *buf_size);
434
435/** Compute a hash value of a prefix of a leaf page record.
436@param[in] rec leaf page record
437@param[in] offsets rec_get_offsets(rec)
438@param[in] n_fields number of complete fields to hash
439@param[in] n_bytes number of bytes to hash in the last field
440@param[in] hashed_value hash value of the index identifier
441@param[in] index index where the record resides
442@return the hashed value */
443[[nodiscard]] static inline uint64_t rec_hash(const rec_t *rec,
444 const ulint *offsets,
445 ulint n_fields, ulint n_bytes,
446 uint64_t hashed_value,
447 const dict_index_t *index);
448#endif /* !UNIV_HOTBACKUP */
449
450/** Builds a physical record out of a data tuple and stores it into the given
451buffer.
452@param[in] buf start address of the physical record
453@param[in] index record descriptor
454@param[in] dtuple data tuple
455@return pointer to the origin of physical record */
456[[nodiscard]] rec_t *rec_convert_dtuple_to_rec(byte *buf,
457 const dict_index_t *index,
458 const dtuple_t *dtuple);
459
460/** Returns the extra size of an old-style physical record if we know its
461 data size and number of fields.
462 @param[in] data_size data size
463 @param[in] n_fields number of fields
464 @param[in] has_ext true if tuple has ext fields
465 @return extra size */
467 ulint n_fields, bool has_ext);
468
469/** Determines the size of a data tuple prefix in ROW_FORMAT=COMPACT.
470@param[in] index record descriptor
471@param[in] fields array of data fields
472@param[in] n_fields number of data fields
473@param[out] extra extra size
474@return total size */
476 const dict_index_t *index, const dfield_t *fields, ulint n_fields,
477 ulint *extra);
478
479/** Determines the size of a data tuple in ROW_FORMAT=COMPACT.
480@param[in] index record descriptor; dict_table_is_comp() is
481 assumed to hold, even if it does not
482@param[in] status status bits of the record
483@param[in] fields array of data fields
484@param[in] n_fields number of data fields
485@param[out] extra extra size
486@return total size */
488 const dfield_t *fields, ulint n_fields,
489 ulint *extra);
490
491/** The following function returns the size of a data tuple when converted to
492a physical record.
493@param[in] index record descriptor
494@param[in] dtuple data tuple
495@return size */
496[[nodiscard]] static inline ulint rec_get_converted_size(
497 const dict_index_t *index, const dtuple_t *dtuple);
498
499#ifndef UNIV_HOTBACKUP
500/** Copies the first n fields of a physical record to a data tuple.
501The fields are copied to the memory heap.
502@param[out] tuple data tuple
503@param[in] rec physical record
504@param[in] index record descriptor
505@param[in] n_fields number of fields to copy
506@param[in] heap memory heap */
507void rec_copy_prefix_to_dtuple(dtuple_t *tuple, const rec_t *rec,
508 const dict_index_t *index, ulint n_fields,
509 mem_heap_t *heap);
510#endif /* !UNIV_HOTBACKUP */
511
512/** Get the length of the number of fields for any new style record.
513@param[in] n_fields number of fields in the record
514@return length of specified number of fields */
515static inline uint8_t rec_get_n_fields_length(ulint n_fields);
516
517/** Set the row version on one new style leaf page record.
518This is only needed for table after instant ADD/DROP COLUMN.
519@param[in,out] rec leaf page record
520@param[in] version row version */
523
524/** Set the row version on one old style leaf page record.
525This is only needed for table after instant ADD/DROP COLUMN.
526@param[in,out] rec leaf page record
527@param[in] version row version */
530
531/** Validates the consistency of a physical record.
532@param[in] rec physical record
533@param[in] offsets array returned by rec_get_offsets()
534@return true if ok */
535bool rec_validate(const rec_t *rec, const ulint *offsets);
536
537/** Prints an old-style physical record.
538@param[in] file File where to print
539@param[in] rec Physical record */
540void rec_print_old(FILE *file, const rec_t *rec);
541
542#ifndef UNIV_HOTBACKUP
543
544/** Prints a spatial index record.
545@param[in] file File where to print
546@param[in] rec Physical record
547@param[in] offsets Array returned by rec_get_offsets() */
548void rec_print_mbr_rec(FILE *file, const rec_t *rec, const ulint *offsets);
549
550/** Prints a physical record.
551@param[in] file file where to print
552@param[in] rec physical record
553@param[in] offsets array returned by rec_get_offsets() */
554void rec_print_new(FILE *file, const rec_t *rec, const ulint *offsets);
555
556/** Prints a physical record.
557@param[in] file File where to print
558@param[in] rec Physical record
559@param[in] index Record descriptor */
560void rec_print(FILE *file, const rec_t *rec, const dict_index_t *index);
561
562/** Pretty-print a record.
563@param[in,out] o output stream
564@param[in] rec physical record
565@param[in] info rec_get_info_bits(rec)
566@param[in] offsets rec_get_offsets(rec) */
567void rec_print(std::ostream &o, const rec_t *rec, ulint info,
568 const ulint *offsets);
569
570/** Wrapper for pretty-printing a record */
572 /** Constructor */
573 rec_index_print(const rec_t *rec, const dict_index_t *index)
574 : m_rec(rec), m_index(index) {}
575
576 /** Record */
577 const rec_t *m_rec;
578 /** Index */
580};
581
582/** Display a record.
583@param[in,out] o output stream
584@param[in] r record to display
585@return the output stream */
586std::ostream &operator<<(std::ostream &o, const rec_index_print &r);
587
588/** Wrapper for pretty-printing a record */
590 /** Constructor */
591 rec_offsets_print(const rec_t *rec, const ulint *offsets)
592 : m_rec(rec), m_offsets(offsets) {}
593
594 /** Record */
595 const rec_t *m_rec;
596 /** Offsets to each field */
598};
599
600/** Display a record.
601@param[in,out] o output stream
602@param[in] r record to display
603@return the output stream */
604std::ostream &operator<<(std::ostream &o, const rec_offsets_print &r);
605
606#ifdef UNIV_DEBUG
607/** Pretty-printer of records and tuples */
609 public:
610 /** Construct a pretty-printed record.
611 @param rec record with header
612 @param offsets rec_get_offsets(rec, ...) */
613 rec_printer(const rec_t *rec, const ulint *offsets) : std::ostringstream() {
614 rec_print(*this, rec, rec_get_info_bits(rec, rec_offs_comp(offsets)),
615 offsets);
616 }
617
618 /** Construct a pretty-printed record.
619 @param rec record, possibly lacking header
620 @param info rec_get_info_bits(rec)
621 @param offsets rec_get_offsets(rec, ...) */
622 rec_printer(const rec_t *rec, ulint info, const ulint *offsets)
623 : std::ostringstream() {
624 rec_print(*this, rec, info, offsets);
625 }
626
627 /** Construct a pretty-printed tuple.
628 @param tuple data tuple */
630 dtuple_print(*this, tuple);
631 }
632
633 /** Construct a pretty-printed tuple.
634 @param field array of data tuple fields
635 @param n number of fields */
637 dfield_print(*this, field, n);
638 }
639
640 /** Destructor */
641 virtual ~rec_printer() = default;
642
643 private:
644 /** Copy constructor */
646 /** Assignment operator */
648};
649#endif /* UNIV_DEBUG */
650
651/** Reads the DB_TRX_ID of a clustered index record.
652@param[in] rec record
653@param[in] index clustered index
654@return the value of DB_TRX_ID */
655[[nodiscard]] trx_id_t rec_get_trx_id(const rec_t *rec,
656 const dict_index_t *index);
657#endif /* UNIV_HOTBACKUP */
658
659/* Maximum lengths for the data in a physical record if the offsets
660are given in one byte (resp. two byte) format. */
661constexpr ulint REC_1BYTE_OFFS_LIMIT = 0x7FUL;
662constexpr ulint REC_2BYTE_OFFS_LIMIT = 0x7FFFUL;
663
664/* The data size of record must be smaller than this because we reserve
665two upmost bits in a two byte offset for special purposes */
666constexpr ulint REC_MAX_DATA_SIZE = 16384;
667
668/** For a given clustered index, version is to be stored on physical record.
669@param[in] index clustered index
670@param[in] n_tuple_fields number of fields in tuple
671@return true, if version is to be stored */
672bool is_store_version(const dict_index_t *index, size_t n_tuple_fields);
673
674/* A temp record, generated for a REDUNDANT row record, will have info bits
675iff table has INSTANT ADD columns. And if record has row version, then it will
676also be stored on temp record header. Following function finds the number of
677more bytes needed in record header to store this info.
678@param[in] index record descriptor
679@param[in] valid_version true if record has version
680@return number of bytes NULL pointer should be adjusted. */
682 bool valid_version);
683#include "rem0rec.ic"
684
685#endif
A helper RAII wrapper for otherwise difficult to use sequence of:
Definition: rem0rec.h:292
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:334
~Rec_offsets()
Deallocated dynamically allocated memory, if any.
Definition: rem0rec.h:316
Rec_offsets()
Prepares offsets to initially point to the fixed-size buffer, and marks the memory as allocated,...
Definition: rem0rec.h:297
ulint * m_offsets
Definition: rem0rec.h:341
mem_heap_t * m_heap
Pointer to heap used by rec_get_offsets().
Definition: rem0rec.h:330
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:309
Pretty-printer of records and tuples.
Definition: rem0rec.h:608
rec_printer(const dfield_t *field, ulint n)
Construct a pretty-printed tuple.
Definition: rem0rec.h:636
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:613
rec_printer(const rec_t *rec, ulint info, const ulint *offsets)
Construct a pretty-printed record.
Definition: rem0rec.h:622
rec_printer(const dtuple_t *tuple)
Construct a pretty-printed tuple.
Definition: rem0rec.h:629
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: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:2872
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 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:1779
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: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:265
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:666
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:1156
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:1191
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: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 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.
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:1182
constexpr ulint REC_2BYTE_OFFS_LIMIT
Definition: rem0rec.h:662
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.
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:661
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:617
Data structure for an index.
Definition: dict0mem.h:1041
Structure for an SQL data tuple of fields (logical record)
Definition: data0data.h:696
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:571
const dict_index_t * m_index
Index.
Definition: rem0rec.h:579
const rec_t * m_rec
Record.
Definition: rem0rec.h:577
rec_index_print(const rec_t *rec, const dict_index_t *index)
Constructor.
Definition: rem0rec.h:573
Wrapper for pretty-printing a record.
Definition: rem0rec.h:589
const rec_t * m_rec
Record.
Definition: rem0rec.h:595
const ulint * m_offsets
Offsets to each field.
Definition: rem0rec.h:597
rec_offsets_print(const rec_t *rec, const ulint *offsets)
Constructor.
Definition: rem0rec.h:591
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