1
/************************************************************************
4
(c) 1994-1996 Innobase Oy
6
Created 5/30/1994 Heikki Tuuri
7
*************************************************************************/
13
#include "data0data.h"
14
#include "rem0types.h"
15
#include "mtr0types.h"
17
/* Info bit denoting the predefined minimum record: this bit is set
18
if and only if the record is the first user record on a non-leaf
19
B-tree page that is the leftmost page on its level
20
(PAGE_LEVEL is nonzero and FIL_PAGE_PREV is FIL_NULL). */
21
#define REC_INFO_MIN_REC_FLAG 0x10UL
23
/* Number of extra bytes in an old-style record,
24
in addition to the data and the offsets */
25
#define REC_N_OLD_EXTRA_BYTES 6
26
/* Number of extra bytes in a new-style record,
27
in addition to the data and the offsets */
28
#define REC_N_NEW_EXTRA_BYTES 5
30
/* Record status values */
31
#define REC_STATUS_ORDINARY 0
32
#define REC_STATUS_NODE_PTR 1
33
#define REC_STATUS_INFIMUM 2
34
#define REC_STATUS_SUPREMUM 3
36
/* Number of elements that should be initially allocated for the
37
offsets[] array, first passed to rec_get_offsets() */
38
#define REC_OFFS_NORMAL_SIZE 100
39
#define REC_OFFS_SMALL_SIZE 10
41
/**********************************************************
42
The following function is used to get the offset of the
43
next chained record on the same page. */
48
/* out: the page offset of the next
50
rec_t* rec, /* in: physical record */
51
ulint comp); /* in: nonzero=compact page format */
52
/**********************************************************
53
The following function is used to set the next record offset field
59
rec_t* rec, /* in: physical record */
60
ulint comp, /* in: nonzero=compact page format */
61
ulint next); /* in: offset of the next record */
62
/**********************************************************
63
The following function is used to get the number of fields
64
in an old-style record. */
69
/* out: number of data fields */
70
rec_t* rec); /* in: physical record */
71
/**********************************************************
72
The following function is used to get the number of fields
78
/* out: number of data fields */
79
rec_t* rec, /* in: physical record */
80
dict_index_t* index); /* in: record descriptor */
81
/**********************************************************
82
The following function is used to get the number of records
83
owned by the previous directory record. */
88
/* out: number of owned records */
89
rec_t* rec, /* in: physical record */
90
ulint comp); /* in: nonzero=compact page format */
91
/**********************************************************
92
The following function is used to set the number of owned
98
rec_t* rec, /* in: physical record */
99
ulint comp, /* in: nonzero=compact page format */
100
ulint n_owned); /* in: the number of owned */
101
/**********************************************************
102
The following function is used to retrieve the info bits of
109
rec_t* rec, /* in: physical record */
110
ulint comp); /* in: nonzero=compact page format */
111
/**********************************************************
112
The following function is used to set the info bits of a record. */
117
rec_t* rec, /* in: physical record */
118
ulint comp, /* in: nonzero=compact page format */
119
ulint bits); /* in: info bits */
120
/**********************************************************
121
The following function retrieves the status bits of a new-style record. */
126
/* out: status bits */
127
rec_t* rec); /* in: physical record */
129
/**********************************************************
130
The following function is used to set the status bits of a new-style record. */
135
rec_t* rec, /* in: physical record */
136
ulint bits); /* in: info bits */
138
/**********************************************************
139
The following function is used to retrieve the info and status
140
bits of a record. (Only compact records have status bits.) */
143
rec_get_info_and_status_bits(
144
/*=========================*/
146
rec_t* rec, /* in: physical record */
147
ulint comp); /* in: nonzero=compact page format */
148
/**********************************************************
149
The following function is used to set the info and status
150
bits of a record. (Only compact records have status bits.) */
153
rec_set_info_and_status_bits(
154
/*=========================*/
155
rec_t* rec, /* in: physical record */
156
ulint comp, /* in: nonzero=compact page format */
157
ulint bits); /* in: info bits */
159
/**********************************************************
160
The following function tells if record is delete marked. */
163
rec_get_deleted_flag(
164
/*=================*/
165
/* out: nonzero if delete marked */
166
rec_t* rec, /* in: physical record */
167
ulint comp); /* in: nonzero=compact page format */
168
/**********************************************************
169
The following function is used to set the deleted bit. */
172
rec_set_deleted_flag(
173
/*=================*/
174
rec_t* rec, /* in: physical record */
175
ulint comp, /* in: nonzero=compact page format */
176
ulint flag); /* in: nonzero if delete marked */
177
/**********************************************************
178
The following function tells if a new-style record is a node pointer. */
181
rec_get_node_ptr_flag(
182
/*==================*/
183
/* out: TRUE if node pointer */
184
rec_t* rec); /* in: physical record */
185
/**********************************************************
186
The following function is used to get the order number
187
of the record in the heap of the index page. */
192
/* out: heap order number */
193
rec_t* rec, /* in: physical record */
194
ulint comp); /* in: nonzero=compact page format */
195
/**********************************************************
196
The following function is used to set the heap number
197
field in the record. */
202
rec_t* rec, /* in: physical record */
203
ulint comp, /* in: nonzero=compact page format */
204
ulint heap_no);/* in: the heap number */
205
/**********************************************************
206
The following function is used to test whether the data offsets
207
in the record are stored in one-byte or two-byte format. */
210
rec_get_1byte_offs_flag(
211
/*====================*/
212
/* out: TRUE if 1-byte form */
213
rec_t* rec); /* in: physical record */
214
/**********************************************************
215
The following function determines the offsets to each field
216
in the record. It can reuse a previously allocated array. */
219
rec_get_offsets_func(
220
/*=================*/
221
/* out: the new offsets */
222
rec_t* rec, /* in: physical record */
223
dict_index_t* index, /* in: record descriptor */
224
ulint* offsets,/* in: array consisting of offsets[0]
225
allocated elements, or an array from
226
rec_get_offsets(), or NULL */
227
ulint n_fields,/* in: maximum number of initialized fields
228
(ULINT_UNDEFINED if all fields) */
229
mem_heap_t** heap, /* in/out: memory heap */
230
const char* file, /* in: file name where called */
231
ulint line); /* in: line number where called */
233
#define rec_get_offsets(rec,index,offsets,n,heap) \
234
rec_get_offsets_func(rec,index,offsets,n,heap,__FILE__,__LINE__)
236
/****************************************************************
237
Validates offsets returned by rec_get_offsets(). */
242
/* out: TRUE if valid */
243
rec_t* rec, /* in: record or NULL */
244
dict_index_t* index, /* in: record descriptor or NULL */
245
const ulint* offsets);/* in: array returned by rec_get_offsets() */
246
/****************************************************************
247
Updates debug data in offsets, in order to avoid bogus
248
rec_offs_validate() failures. */
253
rec_t* rec, /* in: record */
254
dict_index_t* index,/* in: record descriptor */
255
ulint* offsets);/* in: array returned by rec_get_offsets() */
257
/****************************************************************
258
The following function is used to get a pointer to the nth
259
data field in an old-style record. */
262
rec_get_nth_field_old(
263
/*==================*/
264
/* out: pointer to the field */
265
rec_t* rec, /* in: record */
266
ulint n, /* in: index of the field */
267
ulint* len); /* out: length of the field; UNIV_SQL_NULL
269
/****************************************************************
270
Gets the physical size of an old-style field.
271
Also an SQL null may have a field of size > 0,
272
if the data type is of a fixed size. */
275
rec_get_nth_field_size(
276
/*===================*/
277
/* out: field size in bytes */
278
rec_t* rec, /* in: record */
279
ulint n); /* in: index of the field */
280
/****************************************************************
281
The following function is used to get a pointer to the nth
282
data field in a record. */
287
/* out: pointer to the field */
288
rec_t* rec, /* in: record */
289
const ulint* offsets,/* in: array returned by rec_get_offsets() */
290
ulint n, /* in: index of the field */
291
ulint* len); /* out: length of the field; UNIV_SQL_NULL
293
/**********************************************************
294
Determine if the offsets are for a record in the new
300
/* out: nonzero if compact format */
301
const ulint* offsets);/* in: array returned by rec_get_offsets() */
302
/**********************************************************
303
Returns nonzero if the extern bit is set in nth field of rec. */
308
/* out: nonzero if externally stored */
309
const ulint* offsets,/* in: array returned by rec_get_offsets() */
310
ulint n); /* in: nth field */
311
/**********************************************************
312
Returns nonzero if the SQL NULL bit is set in nth field of rec. */
315
rec_offs_nth_sql_null(
316
/*==================*/
317
/* out: nonzero if SQL NULL */
318
const ulint* offsets,/* in: array returned by rec_get_offsets() */
319
ulint n); /* in: nth field */
320
/**********************************************************
321
Gets the physical size of a field. */
326
/* out: length of field */
327
const ulint* offsets,/* in: array returned by rec_get_offsets() */
328
ulint n); /* in: nth field */
330
/**********************************************************
331
Returns TRUE if the extern bit is set in any of the fields
337
/* out: TRUE if a field is stored externally */
338
const ulint* offsets);/* in: array returned by rec_get_offsets() */
339
/***************************************************************
340
Sets the value of the ith field extern storage bit. */
343
rec_set_nth_field_extern_bit(
344
/*=========================*/
345
rec_t* rec, /* in: record */
346
dict_index_t* index, /* in: record descriptor */
347
ulint i, /* in: ith field */
348
ibool val, /* in: value to set */
349
mtr_t* mtr); /* in: mtr holding an X-latch to the page
350
where rec is, or NULL; in the NULL case
351
we do not write to log about the change */
352
/***************************************************************
353
Sets TRUE the extern storage bits of fields mentioned in an array. */
356
rec_set_field_extern_bits(
357
/*======================*/
358
rec_t* rec, /* in: record */
359
dict_index_t* index, /* in: record descriptor */
360
const ulint* vec, /* in: array of field numbers */
361
ulint n_fields,/* in: number of fields numbers */
362
mtr_t* mtr); /* in: mtr holding an X-latch to the page
363
where rec is, or NULL; in the NULL case
364
we do not write to log about the change */
365
/***************************************************************
366
This is used to modify the value of an already existing field in a record.
367
The previous value must have exactly the same size as the new value. If len
368
is UNIV_SQL_NULL then the field is treated as an SQL null for old-style
369
records. For new-style records, len must not be UNIV_SQL_NULL. */
374
rec_t* rec, /* in: record */
375
const ulint* offsets,/* in: array returned by rec_get_offsets() */
376
ulint n, /* in: index number of the field */
377
const void* data, /* in: pointer to the data if not SQL null */
378
ulint len); /* in: length of the data or UNIV_SQL_NULL.
379
If not SQL null, must have the same
380
length as the previous value.
381
If SQL null, previous value must be
383
/**************************************************************
384
The following function returns the data size of an old-style physical
385
record, that is the sum of field lengths. SQL null fields
386
are counted as length 0 fields. The value returned by the function
387
is the distance from record origin to record end in bytes. */
390
rec_get_data_size_old(
391
/*==================*/
393
rec_t* rec); /* in: physical record */
394
/**************************************************************
395
The following function returns the number of fields in a record. */
400
/* out: number of fields */
401
const ulint* offsets);/* in: array returned by rec_get_offsets() */
402
/**************************************************************
403
The following function returns the data size of a physical
404
record, that is the sum of field lengths. SQL null fields
405
are counted as length 0 fields. The value returned by the function
406
is the distance from record origin to record end in bytes. */
412
const ulint* offsets);/* in: array returned by rec_get_offsets() */
413
/**************************************************************
414
Returns the total size of record minus data size of record.
415
The value returned by the function is the distance from record
416
start to record origin in bytes. */
422
const ulint* offsets);/* in: array returned by rec_get_offsets() */
423
/**************************************************************
424
Returns the total size of a physical record. */
430
const ulint* offsets);/* in: array returned by rec_get_offsets() */
431
/**************************************************************
432
Returns a pointer to the start of the record. */
437
/* out: pointer to start */
438
rec_t* rec, /* in: pointer to record */
439
const ulint* offsets);/* in: array returned by rec_get_offsets() */
440
/**************************************************************
441
Returns a pointer to the end of the record. */
446
/* out: pointer to end */
447
rec_t* rec, /* in: pointer to record */
448
const ulint* offsets);/* in: array returned by rec_get_offsets() */
449
/*******************************************************************
450
Copies a physical record to a buffer. */
455
/* out: pointer to the origin of the copy */
456
void* buf, /* in: buffer */
457
const rec_t* rec, /* in: physical record */
458
const ulint* offsets);/* in: array returned by rec_get_offsets() */
459
/******************************************************************
460
Copies the first n fields of a physical record to a new physical record in
464
rec_copy_prefix_to_buf(
465
/*===================*/
466
/* out, own: copied record */
467
rec_t* rec, /* in: physical record */
468
dict_index_t* index, /* in: record descriptor */
469
ulint n_fields, /* in: number of fields to copy */
470
byte** buf, /* in/out: memory buffer
471
for the copied prefix, or NULL */
472
ulint* buf_size); /* in/out: buffer size */
473
/****************************************************************
474
Folds a prefix of a physical record to a ulint. */
479
/* out: the folded value */
480
rec_t* rec, /* in: the physical record */
481
const ulint* offsets, /* in: array returned by
483
ulint n_fields, /* in: number of complete
485
ulint n_bytes, /* in: number of bytes to fold
486
in an incomplete last field */
487
dulint tree_id); /* in: index tree id */
488
/*************************************************************
489
Builds a physical record out of a data tuple and stores it beginning from
490
address destination. */
493
rec_convert_dtuple_to_rec(
494
/*======================*/
495
/* out: pointer to the origin
496
of physical record */
497
byte* buf, /* in: start address of the
499
dict_index_t* index, /* in: record descriptor */
500
dtuple_t* dtuple);/* in: data tuple */
501
/**************************************************************
502
Returns the extra size of an old-style physical record if we know its
503
data size and number of fields. */
506
rec_get_converted_extra_size(
507
/*=========================*/
508
/* out: extra size */
509
ulint data_size, /* in: data size */
510
ulint n_fields) /* in: number of fields */
511
__attribute__((const));
512
/**************************************************************
513
The following function returns the size of a data tuple when converted to
514
a physical record. */
517
rec_get_converted_size(
518
/*===================*/
520
dict_index_t* index, /* in: record descriptor */
521
dtuple_t* dtuple);/* in: data tuple */
522
/******************************************************************
523
Copies the first n fields of a physical record to a data tuple.
524
The fields are copied to the memory heap. */
527
rec_copy_prefix_to_dtuple(
528
/*======================*/
529
dtuple_t* tuple, /* in: data tuple */
530
rec_t* rec, /* in: physical record */
531
dict_index_t* index, /* in: record descriptor */
532
ulint n_fields, /* in: number of fields to copy */
533
mem_heap_t* heap); /* in: memory heap */
534
/*******************************************************************
535
Validates the consistency of a physical record. */
540
/* out: TRUE if ok */
541
rec_t* rec, /* in: physical record */
542
const ulint* offsets);/* in: array returned by rec_get_offsets() */
543
/*******************************************************************
544
Prints an old-style physical record. */
549
FILE* file, /* in: file where to print */
550
rec_t* rec); /* in: physical record */
551
/*******************************************************************
552
Prints a physical record. */
557
FILE* file, /* in: file where to print */
558
rec_t* rec, /* in: physical record */
559
const ulint* offsets);/* in: array returned by rec_get_offsets() */
560
/*******************************************************************
561
Prints a physical record. */
566
FILE* file, /* in: file where to print */
567
rec_t* rec, /* in: physical record */
568
dict_index_t* index); /* in: record descriptor */
570
#define REC_INFO_BITS 6 /* This is single byte bit-field */
572
/* Maximum lengths for the data in a physical record if the offsets
573
are given in one byte (resp. two byte) format. */
574
#define REC_1BYTE_OFFS_LIMIT 0x7FUL
575
#define REC_2BYTE_OFFS_LIMIT 0x7FFFUL
577
/* The data size of record must be smaller than this because we reserve
578
two upmost bits in a two byte offset for special purposes */
579
#define REC_MAX_DATA_SIZE (16 * 1024)
582
#include "rem0rec.ic"