~ubuntu-branches/ubuntu/trusty/drizzle/trusty

« back to all changes in this revision

Viewing changes to plugin/innobase/include/rem0rec.h

  • Committer: Bazaar Package Importer
  • Author(s): Monty Taylor
  • Date: 2010-03-18 12:12:31 UTC
  • Revision ID: james.westby@ubuntu.com-20100318121231-k6g1xe6cshbwa0f8
Tags: upstream-2010.03.1347
ImportĀ upstreamĀ versionĀ 2010.03.1347

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*****************************************************************************
 
2
 
 
3
Copyright (c) 1994, 2009, Innobase Oy. All Rights Reserved.
 
4
 
 
5
This program is free software; you can redistribute it and/or modify it under
 
6
the terms of the GNU General Public License as published by the Free Software
 
7
Foundation; version 2 of the License.
 
8
 
 
9
This program is distributed in the hope that it will be useful, but WITHOUT
 
10
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
 
11
FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
 
12
 
 
13
You should have received a copy of the GNU General Public License along with
 
14
this program; if not, write to the Free Software Foundation, Inc., 59 Temple
 
15
Place, Suite 330, Boston, MA 02111-1307 USA
 
16
 
 
17
*****************************************************************************/
 
18
 
 
19
/********************************************************************//**
 
20
@file include/rem0rec.h
 
21
Record manager
 
22
 
 
23
Created 5/30/1994 Heikki Tuuri
 
24
*************************************************************************/
 
25
 
 
26
#ifndef rem0rec_h
 
27
#define rem0rec_h
 
28
 
 
29
#include "univ.i"
 
30
#include "data0data.h"
 
31
#include "rem0types.h"
 
32
#include "mtr0types.h"
 
33
#include "page0types.h"
 
34
 
 
35
/* Info bit denoting the predefined minimum record: this bit is set
 
36
if and only if the record is the first user record on a non-leaf
 
37
B-tree page that is the leftmost page on its level
 
38
(PAGE_LEVEL is nonzero and FIL_PAGE_PREV is FIL_NULL). */
 
39
#define REC_INFO_MIN_REC_FLAG   0x10UL
 
40
/* The deleted flag in info bits */
 
41
#define REC_INFO_DELETED_FLAG   0x20UL  /* when bit is set to 1, it means the
 
42
                                        record has been delete marked */
 
43
 
 
44
/* Number of extra bytes in an old-style record,
 
45
in addition to the data and the offsets */
 
46
#define REC_N_OLD_EXTRA_BYTES   6
 
47
/* Number of extra bytes in a new-style record,
 
48
in addition to the data and the offsets */
 
49
#define REC_N_NEW_EXTRA_BYTES   5
 
50
 
 
51
/* Record status values */
 
52
#define REC_STATUS_ORDINARY     0
 
53
#define REC_STATUS_NODE_PTR     1
 
54
#define REC_STATUS_INFIMUM      2
 
55
#define REC_STATUS_SUPREMUM     3
 
56
 
 
57
/* The following four constants are needed in page0zip.c in order to
 
58
efficiently compress and decompress pages. */
 
59
 
 
60
/* The offset of heap_no in a compact record */
 
61
#define REC_NEW_HEAP_NO         4
 
62
/* The shift of heap_no in a compact record.
 
63
The status is stored in the low-order bits. */
 
64
#define REC_HEAP_NO_SHIFT       3
 
65
 
 
66
/* Length of a B-tree node pointer, in bytes */
 
67
#define REC_NODE_PTR_SIZE       4
 
68
 
 
69
#ifdef UNIV_DEBUG
 
70
/* Length of the rec_get_offsets() header */
 
71
# define REC_OFFS_HEADER_SIZE   4
 
72
#else /* UNIV_DEBUG */
 
73
/* Length of the rec_get_offsets() header */
 
74
# define REC_OFFS_HEADER_SIZE   2
 
75
#endif /* UNIV_DEBUG */
 
76
 
 
77
/* Number of elements that should be initially allocated for the
 
78
offsets[] array, first passed to rec_get_offsets() */
 
79
#define REC_OFFS_NORMAL_SIZE    100
 
80
#define REC_OFFS_SMALL_SIZE     10
 
81
 
 
82
/******************************************************//**
 
83
The following function is used to get the pointer of the next chained record
 
84
on the same page.
 
85
@return pointer to the next chained record, or NULL if none */
 
86
UNIV_INLINE
 
87
const rec_t*
 
88
rec_get_next_ptr_const(
 
89
/*===================*/
 
90
        const rec_t*    rec,    /*!< in: physical record */
 
91
        ulint           comp);  /*!< in: nonzero=compact page format */
 
92
/******************************************************//**
 
93
The following function is used to get the pointer of the next chained record
 
94
on the same page.
 
95
@return pointer to the next chained record, or NULL if none */
 
96
UNIV_INLINE
 
97
rec_t*
 
98
rec_get_next_ptr(
 
99
/*=============*/
 
100
        rec_t*  rec,    /*!< in: physical record */
 
101
        ulint   comp);  /*!< in: nonzero=compact page format */
 
102
/******************************************************//**
 
103
The following function is used to get the offset of the
 
104
next chained record on the same page.
 
105
@return the page offset of the next chained record, or 0 if none */
 
106
UNIV_INLINE
 
107
ulint
 
108
rec_get_next_offs(
 
109
/*==============*/
 
110
        const rec_t*    rec,    /*!< in: physical record */
 
111
        ulint           comp);  /*!< in: nonzero=compact page format */
 
112
/******************************************************//**
 
113
The following function is used to set the next record offset field
 
114
of an old-style record. */
 
115
UNIV_INLINE
 
116
void
 
117
rec_set_next_offs_old(
 
118
/*==================*/
 
119
        rec_t*  rec,    /*!< in: old-style physical record */
 
120
        ulint   next);  /*!< in: offset of the next record */
 
121
/******************************************************//**
 
122
The following function is used to set the next record offset field
 
123
of a new-style record. */
 
124
UNIV_INLINE
 
125
void
 
126
rec_set_next_offs_new(
 
127
/*==================*/
 
128
        rec_t*  rec,    /*!< in/out: new-style physical record */
 
129
        ulint   next);  /*!< in: offset of the next record */
 
130
/******************************************************//**
 
131
The following function is used to get the number of fields
 
132
in an old-style record.
 
133
@return number of data fields */
 
134
UNIV_INLINE
 
135
ulint
 
136
rec_get_n_fields_old(
 
137
/*=================*/
 
138
        const rec_t*    rec);   /*!< in: physical record */
 
139
/******************************************************//**
 
140
The following function is used to get the number of fields
 
141
in a record.
 
142
@return number of data fields */
 
143
UNIV_INLINE
 
144
ulint
 
145
rec_get_n_fields(
 
146
/*=============*/
 
147
        const rec_t*            rec,    /*!< in: physical record */
 
148
        const dict_index_t*     index); /*!< in: record descriptor */
 
149
/******************************************************//**
 
150
The following function is used to get the number of records owned by the
 
151
previous directory record.
 
152
@return number of owned records */
 
153
UNIV_INLINE
 
154
ulint
 
155
rec_get_n_owned_old(
 
156
/*================*/
 
157
        const rec_t*    rec);   /*!< in: old-style physical record */
 
158
/******************************************************//**
 
159
The following function is used to set the number of owned records. */
 
160
UNIV_INLINE
 
161
void
 
162
rec_set_n_owned_old(
 
163
/*================*/
 
164
        rec_t*  rec,            /*!< in: old-style physical record */
 
165
        ulint   n_owned);       /*!< in: the number of owned */
 
166
/******************************************************//**
 
167
The following function is used to get the number of records owned by the
 
168
previous directory record.
 
169
@return number of owned records */
 
170
UNIV_INLINE
 
171
ulint
 
172
rec_get_n_owned_new(
 
173
/*================*/
 
174
        const rec_t*    rec);   /*!< in: new-style physical record */
 
175
/******************************************************//**
 
176
The following function is used to set the number of owned records. */
 
177
UNIV_INLINE
 
178
void
 
179
rec_set_n_owned_new(
 
180
/*================*/
 
181
        rec_t*          rec,    /*!< in/out: new-style physical record */
 
182
        page_zip_des_t* page_zip,/*!< in/out: compressed page, or NULL */
 
183
        ulint           n_owned);/*!< in: the number of owned */
 
184
/******************************************************//**
 
185
The following function is used to retrieve the info bits of
 
186
a record.
 
187
@return info bits */
 
188
UNIV_INLINE
 
189
ulint
 
190
rec_get_info_bits(
 
191
/*==============*/
 
192
        const rec_t*    rec,    /*!< in: physical record */
 
193
        ulint           comp);  /*!< in: nonzero=compact page format */
 
194
/******************************************************//**
 
195
The following function is used to set the info bits of a record. */
 
196
UNIV_INLINE
 
197
void
 
198
rec_set_info_bits_old(
 
199
/*==================*/
 
200
        rec_t*  rec,    /*!< in: old-style physical record */
 
201
        ulint   bits);  /*!< in: info bits */
 
202
/******************************************************//**
 
203
The following function is used to set the info bits of a record. */
 
204
UNIV_INLINE
 
205
void
 
206
rec_set_info_bits_new(
 
207
/*==================*/
 
208
        rec_t*  rec,    /*!< in/out: new-style physical record */
 
209
        ulint   bits);  /*!< in: info bits */
 
210
/******************************************************//**
 
211
The following function retrieves the status bits of a new-style record.
 
212
@return status bits */
 
213
UNIV_INLINE
 
214
ulint
 
215
rec_get_status(
 
216
/*===========*/
 
217
        const rec_t*    rec);   /*!< in: physical record */
 
218
 
 
219
/******************************************************//**
 
220
The following function is used to set the status bits of a new-style record. */
 
221
UNIV_INLINE
 
222
void
 
223
rec_set_status(
 
224
/*===========*/
 
225
        rec_t*  rec,    /*!< in/out: physical record */
 
226
        ulint   bits);  /*!< in: info bits */
 
227
 
 
228
/******************************************************//**
 
229
The following function is used to retrieve the info and status
 
230
bits of a record.  (Only compact records have status bits.)
 
231
@return info bits */
 
232
UNIV_INLINE
 
233
ulint
 
234
rec_get_info_and_status_bits(
 
235
/*=========================*/
 
236
        const rec_t*    rec,    /*!< in: physical record */
 
237
        ulint           comp);  /*!< in: nonzero=compact page format */
 
238
/******************************************************//**
 
239
The following function is used to set the info and status
 
240
bits of a record.  (Only compact records have status bits.) */
 
241
UNIV_INLINE
 
242
void
 
243
rec_set_info_and_status_bits(
 
244
/*=========================*/
 
245
        rec_t*  rec,    /*!< in/out: compact physical record */
 
246
        ulint   bits);  /*!< in: info bits */
 
247
 
 
248
/******************************************************//**
 
249
The following function tells if record is delete marked.
 
250
@return nonzero if delete marked */
 
251
UNIV_INLINE
 
252
ulint
 
253
rec_get_deleted_flag(
 
254
/*=================*/
 
255
        const rec_t*    rec,    /*!< in: physical record */
 
256
        ulint           comp);  /*!< in: nonzero=compact page format */
 
257
/******************************************************//**
 
258
The following function is used to set the deleted bit. */
 
259
UNIV_INLINE
 
260
void
 
261
rec_set_deleted_flag_old(
 
262
/*=====================*/
 
263
        rec_t*  rec,    /*!< in: old-style physical record */
 
264
        ulint   flag);  /*!< in: nonzero if delete marked */
 
265
/******************************************************//**
 
266
The following function is used to set the deleted bit. */
 
267
UNIV_INLINE
 
268
void
 
269
rec_set_deleted_flag_new(
 
270
/*=====================*/
 
271
        rec_t*          rec,    /*!< in/out: new-style physical record */
 
272
        page_zip_des_t* page_zip,/*!< in/out: compressed page, or NULL */
 
273
        ulint           flag);  /*!< in: nonzero if delete marked */
 
274
/******************************************************//**
 
275
The following function tells if a new-style record is a node pointer.
 
276
@return TRUE if node pointer */
 
277
UNIV_INLINE
 
278
ibool
 
279
rec_get_node_ptr_flag(
 
280
/*==================*/
 
281
        const rec_t*    rec);   /*!< in: physical record */
 
282
/******************************************************//**
 
283
The following function is used to get the order number
 
284
of an old-style record in the heap of the index page.
 
285
@return heap order number */
 
286
UNIV_INLINE
 
287
ulint
 
288
rec_get_heap_no_old(
 
289
/*================*/
 
290
        const rec_t*    rec);   /*!< in: physical record */
 
291
/******************************************************//**
 
292
The following function is used to set the heap number
 
293
field in an old-style record. */
 
294
UNIV_INLINE
 
295
void
 
296
rec_set_heap_no_old(
 
297
/*================*/
 
298
        rec_t*  rec,    /*!< in: physical record */
 
299
        ulint   heap_no);/*!< in: the heap number */
 
300
/******************************************************//**
 
301
The following function is used to get the order number
 
302
of a new-style record in the heap of the index page.
 
303
@return heap order number */
 
304
UNIV_INLINE
 
305
ulint
 
306
rec_get_heap_no_new(
 
307
/*================*/
 
308
        const rec_t*    rec);   /*!< in: physical record */
 
309
/******************************************************//**
 
310
The following function is used to set the heap number
 
311
field in a new-style record. */
 
312
UNIV_INLINE
 
313
void
 
314
rec_set_heap_no_new(
 
315
/*================*/
 
316
        rec_t*  rec,    /*!< in/out: physical record */
 
317
        ulint   heap_no);/*!< in: the heap number */
 
318
/******************************************************//**
 
319
The following function is used to test whether the data offsets
 
320
in the record are stored in one-byte or two-byte format.
 
321
@return TRUE if 1-byte form */
 
322
UNIV_INLINE
 
323
ibool
 
324
rec_get_1byte_offs_flag(
 
325
/*====================*/
 
326
        const rec_t*    rec);   /*!< in: physical record */
 
327
 
 
328
/******************************************************//**
 
329
Determine how many of the first n columns in a compact
 
330
physical record are stored externally.
 
331
@return number of externally stored columns */
 
332
UNIV_INTERN
 
333
ulint
 
334
rec_get_n_extern_new(
 
335
/*=================*/
 
336
        const rec_t*    rec,    /*!< in: compact physical record */
 
337
        dict_index_t*   index,  /*!< in: record descriptor */
 
338
        ulint           n);     /*!< in: number of columns to scan */
 
339
 
 
340
/******************************************************//**
 
341
The following function determines the offsets to each field
 
342
in the record.  It can reuse a previously allocated array.
 
343
@return the new offsets */
 
344
UNIV_INTERN
 
345
ulint*
 
346
rec_get_offsets_func(
 
347
/*=================*/
 
348
        const rec_t*            rec,    /*!< in: physical record */
 
349
        const dict_index_t*     index,  /*!< in: record descriptor */
 
350
        ulint*                  offsets,/*!< in/out: array consisting of
 
351
                                        offsets[0] allocated elements,
 
352
                                        or an array from rec_get_offsets(),
 
353
                                        or NULL */
 
354
        ulint                   n_fields,/*!< in: maximum number of
 
355
                                        initialized fields
 
356
                                         (ULINT_UNDEFINED if all fields) */
 
357
        mem_heap_t**            heap,   /*!< in/out: memory heap */
 
358
        const char*             file,   /*!< in: file name where called */
 
359
        ulint                   line);  /*!< in: line number where called */
 
360
 
 
361
#define rec_get_offsets(rec,index,offsets,n,heap)       \
 
362
        rec_get_offsets_func(rec,index,offsets,n,heap,__FILE__,__LINE__)
 
363
 
 
364
/******************************************************//**
 
365
Determine the offset to each field in a leaf-page record
 
366
in ROW_FORMAT=COMPACT.  This is a special case of
 
367
rec_init_offsets() and rec_get_offsets_func(). */
 
368
UNIV_INTERN
 
369
void
 
370
rec_init_offsets_comp_ordinary(
 
371
/*===========================*/
 
372
        const rec_t*            rec,    /*!< in: physical record in
 
373
                                        ROW_FORMAT=COMPACT */
 
374
        ulint                   extra,  /*!< in: number of bytes to reserve
 
375
                                        between the record header and
 
376
                                        the data payload
 
377
                                        (usually REC_N_NEW_EXTRA_BYTES) */
 
378
        const dict_index_t*     index,  /*!< in: record descriptor */
 
379
        ulint*                  offsets);/*!< in/out: array of offsets;
 
380
                                        in: n=rec_offs_n_fields(offsets) */
 
381
 
 
382
/******************************************************//**
 
383
The following function determines the offsets to each field
 
384
in the record.  It can reuse a previously allocated array. */
 
385
UNIV_INTERN
 
386
void
 
387
rec_get_offsets_reverse(
 
388
/*====================*/
 
389
        const byte*             extra,  /*!< in: the extra bytes of a
 
390
                                        compact record in reverse order,
 
391
                                        excluding the fixed-size
 
392
                                        REC_N_NEW_EXTRA_BYTES */
 
393
        const dict_index_t*     index,  /*!< in: record descriptor */
 
394
        ulint                   node_ptr,/*!< in: nonzero=node pointer,
 
395
                                        0=leaf node */
 
396
        ulint*                  offsets);/*!< in/out: array consisting of
 
397
                                        offsets[0] allocated elements */
 
398
 
 
399
/************************************************************//**
 
400
Validates offsets returned by rec_get_offsets().
 
401
@return TRUE if valid */
 
402
UNIV_INLINE
 
403
ibool
 
404
rec_offs_validate(
 
405
/*==============*/
 
406
        const rec_t*            rec,    /*!< in: record or NULL */
 
407
        const dict_index_t*     index,  /*!< in: record descriptor or NULL */
 
408
        const ulint*            offsets);/*!< in: array returned by
 
409
                                        rec_get_offsets() */
 
410
#ifdef UNIV_DEBUG
 
411
/************************************************************//**
 
412
Updates debug data in offsets, in order to avoid bogus
 
413
rec_offs_validate() failures. */
 
414
UNIV_INLINE
 
415
void
 
416
rec_offs_make_valid(
 
417
/*================*/
 
418
        const rec_t*            rec,    /*!< in: record */
 
419
        const dict_index_t*     index,  /*!< in: record descriptor */
 
420
        ulint*                  offsets);/*!< in: array returned by
 
421
                                        rec_get_offsets() */
 
422
#else
 
423
# define rec_offs_make_valid(rec, index, offsets) ((void) 0)
 
424
#endif /* UNIV_DEBUG */
 
425
 
 
426
/************************************************************//**
 
427
The following function is used to get the offset to the nth
 
428
data field in an old-style record.
 
429
@return offset to the field */
 
430
UNIV_INTERN
 
431
ulint
 
432
rec_get_nth_field_offs_old(
 
433
/*=======================*/
 
434
        const rec_t*    rec,    /*!< in: record */
 
435
        ulint           n,      /*!< in: index of the field */
 
436
        ulint*          len);   /*!< out: length of the field; UNIV_SQL_NULL
 
437
                                if SQL null */
 
438
#define rec_get_nth_field_old(rec, n, len) \
 
439
((rec) + rec_get_nth_field_offs_old(rec, n, len))
 
440
/************************************************************//**
 
441
Gets the physical size of an old-style field.
 
442
Also an SQL null may have a field of size > 0,
 
443
if the data type is of a fixed size.
 
444
@return field size in bytes */
 
445
UNIV_INLINE
 
446
ulint
 
447
rec_get_nth_field_size(
 
448
/*===================*/
 
449
        const rec_t*    rec,    /*!< in: record */
 
450
        ulint           n);     /*!< in: index of the field */
 
451
/************************************************************//**
 
452
The following function is used to get an offset to the nth
 
453
data field in a record.
 
454
@return offset from the origin of rec */
 
455
UNIV_INLINE
 
456
ulint
 
457
rec_get_nth_field_offs(
 
458
/*===================*/
 
459
        const ulint*    offsets,/*!< in: array returned by rec_get_offsets() */
 
460
        ulint           n,      /*!< in: index of the field */
 
461
        ulint*          len);   /*!< out: length of the field; UNIV_SQL_NULL
 
462
                                if SQL null */
 
463
#define rec_get_nth_field(rec, offsets, n, len) \
 
464
((rec) + rec_get_nth_field_offs(offsets, n, len))
 
465
/******************************************************//**
 
466
Determine if the offsets are for a record in the new
 
467
compact format.
 
468
@return nonzero if compact format */
 
469
UNIV_INLINE
 
470
ulint
 
471
rec_offs_comp(
 
472
/*==========*/
 
473
        const ulint*    offsets);/*!< in: array returned by rec_get_offsets() */
 
474
/******************************************************//**
 
475
Determine if the offsets are for a record containing
 
476
externally stored columns.
 
477
@return nonzero if externally stored */
 
478
UNIV_INLINE
 
479
ulint
 
480
rec_offs_any_extern(
 
481
/*================*/
 
482
        const ulint*    offsets);/*!< in: array returned by rec_get_offsets() */
 
483
/******************************************************//**
 
484
Returns nonzero if the extern bit is set in nth field of rec.
 
485
@return nonzero if externally stored */
 
486
UNIV_INLINE
 
487
ulint
 
488
rec_offs_nth_extern(
 
489
/*================*/
 
490
        const ulint*    offsets,/*!< in: array returned by rec_get_offsets() */
 
491
        ulint           n);     /*!< in: nth field */
 
492
/******************************************************//**
 
493
Returns nonzero if the SQL NULL bit is set in nth field of rec.
 
494
@return nonzero if SQL NULL */
 
495
UNIV_INLINE
 
496
ulint
 
497
rec_offs_nth_sql_null(
 
498
/*==================*/
 
499
        const ulint*    offsets,/*!< in: array returned by rec_get_offsets() */
 
500
        ulint           n);     /*!< in: nth field */
 
501
/******************************************************//**
 
502
Gets the physical size of a field.
 
503
@return length of field */
 
504
UNIV_INLINE
 
505
ulint
 
506
rec_offs_nth_size(
 
507
/*==============*/
 
508
        const ulint*    offsets,/*!< in: array returned by rec_get_offsets() */
 
509
        ulint           n);     /*!< in: nth field */
 
510
 
 
511
/******************************************************//**
 
512
Returns the number of extern bits set in a record.
 
513
@return number of externally stored fields */
 
514
UNIV_INLINE
 
515
ulint
 
516
rec_offs_n_extern(
 
517
/*==============*/
 
518
        const ulint*    offsets);/*!< in: array returned by rec_get_offsets() */
 
519
/***********************************************************//**
 
520
This is used to modify the value of an already existing field in a record.
 
521
The previous value must have exactly the same size as the new value. If len
 
522
is UNIV_SQL_NULL then the field is treated as an SQL null.
 
523
For records in ROW_FORMAT=COMPACT (new-style records), len must not be
 
524
UNIV_SQL_NULL unless the field already is SQL null. */
 
525
UNIV_INLINE
 
526
void
 
527
rec_set_nth_field(
 
528
/*==============*/
 
529
        rec_t*          rec,    /*!< in: record */
 
530
        const ulint*    offsets,/*!< in: array returned by rec_get_offsets() */
 
531
        ulint           n,      /*!< in: index number of the field */
 
532
        const void*     data,   /*!< in: pointer to the data if not SQL null */
 
533
        ulint           len);   /*!< in: length of the data or UNIV_SQL_NULL */
 
534
/**********************************************************//**
 
535
The following function returns the data size of an old-style physical
 
536
record, that is the sum of field lengths. SQL null fields
 
537
are counted as length 0 fields. The value returned by the function
 
538
is the distance from record origin to record end in bytes.
 
539
@return size */
 
540
UNIV_INLINE
 
541
ulint
 
542
rec_get_data_size_old(
 
543
/*==================*/
 
544
        const rec_t*    rec);   /*!< in: physical record */
 
545
/**********************************************************//**
 
546
The following function returns the number of allocated elements
 
547
for an array of offsets.
 
548
@return number of elements */
 
549
UNIV_INLINE
 
550
ulint
 
551
rec_offs_get_n_alloc(
 
552
/*=================*/
 
553
        const ulint*    offsets);/*!< in: array for rec_get_offsets() */
 
554
/**********************************************************//**
 
555
The following function sets the number of allocated elements
 
556
for an array of offsets. */
 
557
UNIV_INLINE
 
558
void
 
559
rec_offs_set_n_alloc(
 
560
/*=================*/
 
561
        ulint*  offsets,        /*!< out: array for rec_get_offsets(),
 
562
                                must be allocated */
 
563
        ulint   n_alloc);       /*!< in: number of elements */
 
564
#define rec_offs_init(offsets) \
 
565
        rec_offs_set_n_alloc(offsets, (sizeof offsets) / sizeof *offsets)
 
566
/**********************************************************//**
 
567
The following function returns the number of fields in a record.
 
568
@return number of fields */
 
569
UNIV_INLINE
 
570
ulint
 
571
rec_offs_n_fields(
 
572
/*==============*/
 
573
        const ulint*    offsets);/*!< in: array returned by rec_get_offsets() */
 
574
/**********************************************************//**
 
575
The following function returns the data size of a physical
 
576
record, that is the sum of field lengths. SQL null fields
 
577
are counted as length 0 fields. The value returned by the function
 
578
is the distance from record origin to record end in bytes.
 
579
@return size */
 
580
UNIV_INLINE
 
581
ulint
 
582
rec_offs_data_size(
 
583
/*===============*/
 
584
        const ulint*    offsets);/*!< in: array returned by rec_get_offsets() */
 
585
/**********************************************************//**
 
586
Returns the total size of record minus data size of record.
 
587
The value returned by the function is the distance from record
 
588
start to record origin in bytes.
 
589
@return size */
 
590
UNIV_INLINE
 
591
ulint
 
592
rec_offs_extra_size(
 
593
/*================*/
 
594
        const ulint*    offsets);/*!< in: array returned by rec_get_offsets() */
 
595
/**********************************************************//**
 
596
Returns the total size of a physical record.
 
597
@return size */
 
598
UNIV_INLINE
 
599
ulint
 
600
rec_offs_size(
 
601
/*==========*/
 
602
        const ulint*    offsets);/*!< in: array returned by rec_get_offsets() */
 
603
/**********************************************************//**
 
604
Returns a pointer to the start of the record.
 
605
@return pointer to start */
 
606
UNIV_INLINE
 
607
byte*
 
608
rec_get_start(
 
609
/*==========*/
 
610
        rec_t*          rec,    /*!< in: pointer to record */
 
611
        const ulint*    offsets);/*!< in: array returned by rec_get_offsets() */
 
612
/**********************************************************//**
 
613
Returns a pointer to the end of the record.
 
614
@return pointer to end */
 
615
UNIV_INLINE
 
616
byte*
 
617
rec_get_end(
 
618
/*========*/
 
619
        rec_t*          rec,    /*!< in: pointer to record */
 
620
        const ulint*    offsets);/*!< in: array returned by rec_get_offsets() */
 
621
/***************************************************************//**
 
622
Copies a physical record to a buffer.
 
623
@return pointer to the origin of the copy */
 
624
UNIV_INLINE
 
625
rec_t*
 
626
rec_copy(
 
627
/*=====*/
 
628
        void*           buf,    /*!< in: buffer */
 
629
        const rec_t*    rec,    /*!< in: physical record */
 
630
        const ulint*    offsets);/*!< in: array returned by rec_get_offsets() */
 
631
#ifndef UNIV_HOTBACKUP
 
632
/**************************************************************//**
 
633
Copies the first n fields of a physical record to a new physical record in
 
634
a buffer.
 
635
@return own: copied record */
 
636
UNIV_INTERN
 
637
rec_t*
 
638
rec_copy_prefix_to_buf(
 
639
/*===================*/
 
640
        const rec_t*            rec,            /*!< in: physical record */
 
641
        const dict_index_t*     index,          /*!< in: record descriptor */
 
642
        ulint                   n_fields,       /*!< in: number of fields
 
643
                                                to copy */
 
644
        byte**                  buf,            /*!< in/out: memory buffer
 
645
                                                for the copied prefix,
 
646
                                                or NULL */
 
647
        ulint*                  buf_size);      /*!< in/out: buffer size */
 
648
/************************************************************//**
 
649
Folds a prefix of a physical record to a ulint.
 
650
@return the folded value */
 
651
UNIV_INLINE
 
652
ulint
 
653
rec_fold(
 
654
/*=====*/
 
655
        const rec_t*    rec,            /*!< in: the physical record */
 
656
        const ulint*    offsets,        /*!< in: array returned by
 
657
                                        rec_get_offsets() */
 
658
        ulint           n_fields,       /*!< in: number of complete
 
659
                                        fields to fold */
 
660
        ulint           n_bytes,        /*!< in: number of bytes to fold
 
661
                                        in an incomplete last field */
 
662
        dulint          tree_id)        /*!< in: index tree id */
 
663
        __attribute__((pure));
 
664
#endif /* !UNIV_HOTBACKUP */
 
665
/*********************************************************//**
 
666
Builds a ROW_FORMAT=COMPACT record out of a data tuple. */
 
667
UNIV_INTERN
 
668
void
 
669
rec_convert_dtuple_to_rec_comp(
 
670
/*===========================*/
 
671
        rec_t*                  rec,    /*!< in: origin of record */
 
672
        ulint                   extra,  /*!< in: number of bytes to
 
673
                                        reserve between the record
 
674
                                        header and the data payload
 
675
                                        (normally REC_N_NEW_EXTRA_BYTES) */
 
676
        const dict_index_t*     index,  /*!< in: record descriptor */
 
677
        ulint                   status, /*!< in: status bits of the record */
 
678
        const dfield_t*         fields, /*!< in: array of data fields */
 
679
        ulint                   n_fields);/*!< in: number of data fields */
 
680
/*********************************************************//**
 
681
Builds a physical record out of a data tuple and
 
682
stores it into the given buffer.
 
683
@return pointer to the origin of physical record */
 
684
UNIV_INTERN
 
685
rec_t*
 
686
rec_convert_dtuple_to_rec(
 
687
/*======================*/
 
688
        byte*                   buf,    /*!< in: start address of the
 
689
                                        physical record */
 
690
        const dict_index_t*     index,  /*!< in: record descriptor */
 
691
        const dtuple_t*         dtuple, /*!< in: data tuple */
 
692
        ulint                   n_ext); /*!< in: number of
 
693
                                        externally stored columns */
 
694
/**********************************************************//**
 
695
Returns the extra size of an old-style physical record if we know its
 
696
data size and number of fields.
 
697
@return extra size */
 
698
UNIV_INLINE
 
699
ulint
 
700
rec_get_converted_extra_size(
 
701
/*=========================*/
 
702
        ulint   data_size,      /*!< in: data size */
 
703
        ulint   n_fields,       /*!< in: number of fields */
 
704
        ulint   n_ext)          /*!< in: number of externally stored columns */
 
705
                __attribute__((const));
 
706
/**********************************************************//**
 
707
Determines the size of a data tuple prefix in ROW_FORMAT=COMPACT.
 
708
@return total size */
 
709
UNIV_INTERN
 
710
ulint
 
711
rec_get_converted_size_comp_prefix(
 
712
/*===============================*/
 
713
        const dict_index_t*     index,  /*!< in: record descriptor;
 
714
                                        dict_table_is_comp() is
 
715
                                        assumed to hold, even if
 
716
                                        it does not */
 
717
        const dfield_t*         fields, /*!< in: array of data fields */
 
718
        ulint                   n_fields,/*!< in: number of data fields */
 
719
        ulint*                  extra); /*!< out: extra size */
 
720
/**********************************************************//**
 
721
Determines the size of a data tuple in ROW_FORMAT=COMPACT.
 
722
@return total size */
 
723
UNIV_INTERN
 
724
ulint
 
725
rec_get_converted_size_comp(
 
726
/*========================*/
 
727
        const dict_index_t*     index,  /*!< in: record descriptor;
 
728
                                        dict_table_is_comp() is
 
729
                                        assumed to hold, even if
 
730
                                        it does not */
 
731
        ulint                   status, /*!< in: status bits of the record */
 
732
        const dfield_t*         fields, /*!< in: array of data fields */
 
733
        ulint                   n_fields,/*!< in: number of data fields */
 
734
        ulint*                  extra); /*!< out: extra size */
 
735
/**********************************************************//**
 
736
The following function returns the size of a data tuple when converted to
 
737
a physical record.
 
738
@return size */
 
739
UNIV_INLINE
 
740
ulint
 
741
rec_get_converted_size(
 
742
/*===================*/
 
743
        dict_index_t*   index,  /*!< in: record descriptor */
 
744
        const dtuple_t* dtuple, /*!< in: data tuple */
 
745
        ulint           n_ext); /*!< in: number of externally stored columns */
 
746
#ifndef UNIV_HOTBACKUP
 
747
/**************************************************************//**
 
748
Copies the first n fields of a physical record to a data tuple.
 
749
The fields are copied to the memory heap. */
 
750
UNIV_INTERN
 
751
void
 
752
rec_copy_prefix_to_dtuple(
 
753
/*======================*/
 
754
        dtuple_t*               tuple,          /*!< out: data tuple */
 
755
        const rec_t*            rec,            /*!< in: physical record */
 
756
        const dict_index_t*     index,          /*!< in: record descriptor */
 
757
        ulint                   n_fields,       /*!< in: number of fields
 
758
                                                to copy */
 
759
        mem_heap_t*             heap);          /*!< in: memory heap */
 
760
#endif /* !UNIV_HOTBACKUP */
 
761
/***************************************************************//**
 
762
Validates the consistency of a physical record.
 
763
@return TRUE if ok */
 
764
UNIV_INTERN
 
765
ibool
 
766
rec_validate(
 
767
/*=========*/
 
768
        const rec_t*    rec,    /*!< in: physical record */
 
769
        const ulint*    offsets);/*!< in: array returned by rec_get_offsets() */
 
770
/***************************************************************//**
 
771
Prints an old-style physical record. */
 
772
UNIV_INTERN
 
773
void
 
774
rec_print_old(
 
775
/*==========*/
 
776
        FILE*           file,   /*!< in: file where to print */
 
777
        const rec_t*    rec);   /*!< in: physical record */
 
778
#ifndef UNIV_HOTBACKUP
 
779
/***************************************************************//**
 
780
Prints a physical record in ROW_FORMAT=COMPACT.  Ignores the
 
781
record header. */
 
782
UNIV_INTERN
 
783
void
 
784
rec_print_comp(
 
785
/*===========*/
 
786
        FILE*           file,   /*!< in: file where to print */
 
787
        const rec_t*    rec,    /*!< in: physical record */
 
788
        const ulint*    offsets);/*!< in: array returned by rec_get_offsets() */
 
789
/***************************************************************//**
 
790
Prints a physical record. */
 
791
UNIV_INTERN
 
792
void
 
793
rec_print_new(
 
794
/*==========*/
 
795
        FILE*           file,   /*!< in: file where to print */
 
796
        const rec_t*    rec,    /*!< in: physical record */
 
797
        const ulint*    offsets);/*!< in: array returned by rec_get_offsets() */
 
798
/***************************************************************//**
 
799
Prints a physical record. */
 
800
UNIV_INTERN
 
801
void
 
802
rec_print(
 
803
/*======*/
 
804
        FILE*           file,   /*!< in: file where to print */
 
805
        const rec_t*    rec,    /*!< in: physical record */
 
806
        dict_index_t*   index); /*!< in: record descriptor */
 
807
#endif /* UNIV_HOTBACKUP */
 
808
 
 
809
#define REC_INFO_BITS           6       /* This is single byte bit-field */
 
810
 
 
811
/* Maximum lengths for the data in a physical record if the offsets
 
812
are given in one byte (resp. two byte) format. */
 
813
#define REC_1BYTE_OFFS_LIMIT    0x7FUL
 
814
#define REC_2BYTE_OFFS_LIMIT    0x7FFFUL
 
815
 
 
816
/* The data size of record must be smaller than this because we reserve
 
817
two upmost bits in a two byte offset for special purposes */
 
818
#define REC_MAX_DATA_SIZE       (16 * 1024)
 
819
 
 
820
#ifndef UNIV_NONINL
 
821
#include "rem0rec.ic"
 
822
#endif
 
823
 
 
824
#endif