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