rem0rec.h 28.5 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
/*****************************************************************************

Copyright (c) 1994, 2009, Innobase Oy. All Rights Reserved.

This program is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free Software
Foundation; version 2 of the License.

This program is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.

You should have received a copy of the GNU General Public License along with
this program; if not, write to the Free Software Foundation, Inc., 59 Temple
Place, Suite 330, Boston, MA 02111-1307 USA

*****************************************************************************/

19 20
/********************************************************************//**
@file include/rem0rec.h
osku's avatar
osku committed
21 22 23 24 25 26 27 28 29 30 31 32
Record manager

Created 5/30/1994 Heikki Tuuri
*************************************************************************/

#ifndef rem0rec_h
#define rem0rec_h

#include "univ.i"
#include "data0data.h"
#include "rem0types.h"
#include "mtr0types.h"
marko's avatar
marko committed
33
#include "page0types.h"
osku's avatar
osku committed
34

35 36 37 38
/* Info bit denoting the predefined minimum record: this bit is set
if and only if the record is the first user record on a non-leaf
B-tree page that is the leftmost page on its level
(PAGE_LEVEL is nonzero and FIL_PAGE_PREV is FIL_NULL). */
osku's avatar
osku committed
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 */
osku's avatar
osku committed
43 44 45 46 47 48 49 50 51 52 53 54 55 56

/* Number of extra bytes in an old-style record,
in addition to the data and the offsets */
#define REC_N_OLD_EXTRA_BYTES	6
/* Number of extra bytes in a new-style record,
in addition to the data and the offsets */
#define REC_N_NEW_EXTRA_BYTES	5

/* Record status values */
#define REC_STATUS_ORDINARY	0
#define REC_STATUS_NODE_PTR	1
#define REC_STATUS_INFIMUM	2
#define REC_STATUS_SUPREMUM	3

57 58
/* The following four constants are needed in page0zip.c in order to
efficiently compress and decompress pages. */
59 60 61 62 63 64 65

/* The offset of heap_no in a compact record */
#define REC_NEW_HEAP_NO		4
/* The shift of heap_no in a compact record.
The status is stored in the low-order bits. */
#define	REC_HEAP_NO_SHIFT	3

66 67 68 69 70 71 72 73 74 75 76
/* Length of a B-tree node pointer, in bytes */
#define REC_NODE_PTR_SIZE	4

#ifdef UNIV_DEBUG
/* Length of the rec_get_offsets() header */
# define REC_OFFS_HEADER_SIZE	4
#else /* UNIV_DEBUG */
/* Length of the rec_get_offsets() header */
# define REC_OFFS_HEADER_SIZE	2
#endif /* UNIV_DEBUG */

osku's avatar
osku committed
77 78 79 80 81
/* Number of elements that should be initially allocated for the
offsets[] array, first passed to rec_get_offsets() */
#define REC_OFFS_NORMAL_SIZE	100
#define REC_OFFS_SMALL_SIZE	10

82
/******************************************************//**
83
The following function is used to get the pointer of the next chained record
84 85
on the same page.
@return	pointer to the next chained record, or NULL if none */
86 87 88 89
UNIV_INLINE
const rec_t*
rec_get_next_ptr_const(
/*===================*/
90 91
	const rec_t*	rec,	/*!< in: physical record */
	ulint		comp);	/*!< in: nonzero=compact page format */
92
/******************************************************//**
marko's avatar
marko committed
93
The following function is used to get the pointer of the next chained record
94 95
on the same page.
@return	pointer to the next chained record, or NULL if none */
marko's avatar
marko committed
96 97 98 99
UNIV_INLINE
rec_t*
rec_get_next_ptr(
/*=============*/
100 101
	rec_t*	rec,	/*!< in: physical record */
	ulint	comp);	/*!< in: nonzero=compact page format */
102
/******************************************************//**
osku's avatar
osku committed
103
The following function is used to get the offset of the
104 105
next chained record on the same page.
@return	the page offset of the next chained record, or 0 if none */
osku's avatar
osku committed
106
UNIV_INLINE
107
ulint
osku's avatar
osku committed
108 109
rec_get_next_offs(
/*==============*/
110 111
	const rec_t*	rec,	/*!< in: physical record */
	ulint		comp);	/*!< in: nonzero=compact page format */
112
/******************************************************//**
osku's avatar
osku committed
113
The following function is used to set the next record offset field
marko's avatar
marko committed
114
of an old-style record. */
osku's avatar
osku committed
115 116
UNIV_INLINE
void
marko's avatar
marko committed
117 118
rec_set_next_offs_old(
/*==================*/
119 120
	rec_t*	rec,	/*!< in: old-style physical record */
	ulint	next);	/*!< in: offset of the next record */
121
/******************************************************//**
marko's avatar
marko committed
122 123 124 125 126 127
The following function is used to set the next record offset field
of a new-style record. */
UNIV_INLINE
void
rec_set_next_offs_new(
/*==================*/
128 129
	rec_t*	rec,	/*!< in/out: new-style physical record */
	ulint	next);	/*!< in: offset of the next record */
130
/******************************************************//**
osku's avatar
osku committed
131
The following function is used to get the number of fields
132 133
in an old-style record.
@return	number of data fields */
osku's avatar
osku committed
134 135 136 137
UNIV_INLINE
ulint
rec_get_n_fields_old(
/*=================*/
138
	const rec_t*	rec);	/*!< in: physical record */
139
/******************************************************//**
osku's avatar
osku committed
140
The following function is used to get the number of fields
141 142
in a record.
@return	number of data fields */
osku's avatar
osku committed
143 144 145 146
UNIV_INLINE
ulint
rec_get_n_fields(
/*=============*/
147 148
	const rec_t*		rec,	/*!< in: physical record */
	const dict_index_t*	index);	/*!< in: record descriptor */
149
/******************************************************//**
marko's avatar
marko committed
150
The following function is used to get the number of records owned by the
151 152
previous directory record.
@return	number of owned records */
osku's avatar
osku committed
153 154
UNIV_INLINE
ulint
marko's avatar
marko committed
155 156
rec_get_n_owned_old(
/*================*/
157
	const rec_t*	rec);	/*!< in: old-style physical record */
158
/******************************************************//**
marko's avatar
marko committed
159
The following function is used to set the number of owned records. */
osku's avatar
osku committed
160 161
UNIV_INLINE
void
marko's avatar
marko committed
162 163
rec_set_n_owned_old(
/*================*/
164 165
	rec_t*	rec,		/*!< in: old-style physical record */
	ulint	n_owned);	/*!< in: the number of owned */
166
/******************************************************//**
marko's avatar
marko committed
167
The following function is used to get the number of records owned by the
168 169
previous directory record.
@return	number of owned records */
marko's avatar
marko committed
170 171 172 173
UNIV_INLINE
ulint
rec_get_n_owned_new(
/*================*/
174
	const rec_t*	rec);	/*!< in: new-style physical record */
175
/******************************************************//**
marko's avatar
marko committed
176 177 178 179 180
The following function is used to set the number of owned records. */
UNIV_INLINE
void
rec_set_n_owned_new(
/*================*/
181 182 183
	rec_t*		rec,	/*!< in/out: new-style physical record */
	page_zip_des_t*	page_zip,/*!< in/out: compressed page, or NULL */
	ulint		n_owned);/*!< in: the number of owned */
184
/******************************************************//**
osku's avatar
osku committed
185
The following function is used to retrieve the info bits of
186 187
a record.
@return	info bits */
osku's avatar
osku committed
188 189 190 191
UNIV_INLINE
ulint
rec_get_info_bits(
/*==============*/
192 193
	const rec_t*	rec,	/*!< in: physical record */
	ulint		comp);	/*!< in: nonzero=compact page format */
194
/******************************************************//**
osku's avatar
osku committed
195 196 197
The following function is used to set the info bits of a record. */
UNIV_INLINE
void
marko's avatar
marko committed
198 199
rec_set_info_bits_old(
/*==================*/
200 201
	rec_t*	rec,	/*!< in: old-style physical record */
	ulint	bits);	/*!< in: info bits */
202
/******************************************************//**
marko's avatar
marko committed
203 204 205 206 207
The following function is used to set the info bits of a record. */
UNIV_INLINE
void
rec_set_info_bits_new(
/*==================*/
208 209
	rec_t*	rec,	/*!< in/out: new-style physical record */
	ulint	bits);	/*!< in: info bits */
210
/******************************************************//**
211 212
The following function retrieves the status bits of a new-style record.
@return	status bits */
osku's avatar
osku committed
213 214 215 216
UNIV_INLINE
ulint
rec_get_status(
/*===========*/
217
	const rec_t*	rec);	/*!< in: physical record */
osku's avatar
osku committed
218

219
/******************************************************//**
osku's avatar
osku committed
220 221 222 223 224
The following function is used to set the status bits of a new-style record. */
UNIV_INLINE
void
rec_set_status(
/*===========*/
225 226
	rec_t*	rec,	/*!< in/out: physical record */
	ulint	bits);	/*!< in: info bits */
osku's avatar
osku committed
227

228
/******************************************************//**
osku's avatar
osku committed
229
The following function is used to retrieve the info and status
230 231
bits of a record.  (Only compact records have status bits.)
@return	info bits */
osku's avatar
osku committed
232 233 234 235
UNIV_INLINE
ulint
rec_get_info_and_status_bits(
/*=========================*/
236 237
	const rec_t*	rec,	/*!< in: physical record */
	ulint		comp);	/*!< in: nonzero=compact page format */
238
/******************************************************//**
osku's avatar
osku committed
239 240 241 242 243 244
The following function is used to set the info and status
bits of a record.  (Only compact records have status bits.) */
UNIV_INLINE
void
rec_set_info_and_status_bits(
/*=========================*/
245 246
	rec_t*	rec,	/*!< in/out: compact physical record */
	ulint	bits);	/*!< in: info bits */
osku's avatar
osku committed
247

248
/******************************************************//**
249 250
The following function tells if record is delete marked.
@return	nonzero if delete marked */
osku's avatar
osku committed
251 252 253 254
UNIV_INLINE
ulint
rec_get_deleted_flag(
/*=================*/
255 256
	const rec_t*	rec,	/*!< in: physical record */
	ulint		comp);	/*!< in: nonzero=compact page format */
257
/******************************************************//**
osku's avatar
osku committed
258 259 260
The following function is used to set the deleted bit. */
UNIV_INLINE
void
marko's avatar
marko committed
261 262
rec_set_deleted_flag_old(
/*=====================*/
263 264
	rec_t*	rec,	/*!< in: old-style physical record */
	ulint	flag);	/*!< in: nonzero if delete marked */
265
/******************************************************//**
marko's avatar
marko committed
266 267 268 269 270
The following function is used to set the deleted bit. */
UNIV_INLINE
void
rec_set_deleted_flag_new(
/*=====================*/
271 272 273
	rec_t*		rec,	/*!< in/out: new-style physical record */
	page_zip_des_t*	page_zip,/*!< in/out: compressed page, or NULL */
	ulint		flag);	/*!< in: nonzero if delete marked */
274
/******************************************************//**
275 276
The following function tells if a new-style record is a node pointer.
@return	TRUE if node pointer */
osku's avatar
osku committed
277 278 279
UNIV_INLINE
ibool
rec_get_node_ptr_flag(
marko's avatar
marko committed
280
/*==================*/
281
	const rec_t*	rec);	/*!< in: physical record */
282
/******************************************************//**
osku's avatar
osku committed
283
The following function is used to get the order number
284 285
of an old-style record in the heap of the index page.
@return	heap order number */
osku's avatar
osku committed
286 287
UNIV_INLINE
ulint
marko's avatar
marko committed
288 289
rec_get_heap_no_old(
/*================*/
290
	const rec_t*	rec);	/*!< in: physical record */
291
/******************************************************//**
osku's avatar
osku committed
292
The following function is used to set the heap number
marko's avatar
marko committed
293
field in an old-style record. */
osku's avatar
osku committed
294 295
UNIV_INLINE
void
marko's avatar
marko committed
296 297
rec_set_heap_no_old(
/*================*/
298 299
	rec_t*	rec,	/*!< in: physical record */
	ulint	heap_no);/*!< in: the heap number */
300
/******************************************************//**
marko's avatar
marko committed
301
The following function is used to get the order number
302 303
of a new-style record in the heap of the index page.
@return	heap order number */
marko's avatar
marko committed
304 305 306 307
UNIV_INLINE
ulint
rec_get_heap_no_new(
/*================*/
308
	const rec_t*	rec);	/*!< in: physical record */
309
/******************************************************//**
marko's avatar
marko committed
310 311 312 313 314 315
The following function is used to set the heap number
field in a new-style record. */
UNIV_INLINE
void
rec_set_heap_no_new(
/*================*/
316 317
	rec_t*	rec,	/*!< in/out: physical record */
	ulint	heap_no);/*!< in: the heap number */
318
/******************************************************//**
osku's avatar
osku committed
319
The following function is used to test whether the data offsets
320 321
in the record are stored in one-byte or two-byte format.
@return	TRUE if 1-byte form */
osku's avatar
osku committed
322 323 324 325
UNIV_INLINE
ibool
rec_get_1byte_offs_flag(
/*====================*/
326
	const rec_t*	rec);	/*!< in: physical record */
327

328
/******************************************************//**
329
Determine how many of the first n columns in a compact
330 331
physical record are stored externally.
@return	number of externally stored columns */
332
UNIV_INTERN
333 334 335
ulint
rec_get_n_extern_new(
/*=================*/
336 337 338
	const rec_t*	rec,	/*!< in: compact physical record */
	dict_index_t*	index,	/*!< in: record descriptor */
	ulint		n);	/*!< in: number of columns to scan */
339

340
/******************************************************//**
osku's avatar
osku committed
341
The following function determines the offsets to each field
342 343
in the record.	It can reuse a previously allocated array.
@return	the new offsets */
344
UNIV_INTERN
osku's avatar
osku committed
345 346 347
ulint*
rec_get_offsets_func(
/*=================*/
348 349 350
	const rec_t*		rec,	/*!< in: physical record */
	const dict_index_t*	index,	/*!< in: record descriptor */
	ulint*			offsets,/*!< in/out: array consisting of
351 352 353
					offsets[0] allocated elements,
					or an array from rec_get_offsets(),
					or NULL */
354
	ulint			n_fields,/*!< in: maximum number of
355 356
					initialized fields
					 (ULINT_UNDEFINED if all fields) */
357 358 359
	mem_heap_t**		heap,	/*!< in/out: memory heap */
	const char*		file,	/*!< in: file name where called */
	ulint			line);	/*!< in: line number where called */
osku's avatar
osku committed
360 361 362 363

#define rec_get_offsets(rec,index,offsets,n,heap)	\
	rec_get_offsets_func(rec,index,offsets,n,heap,__FILE__,__LINE__)

364
/******************************************************//**
365 366 367
Determine the offset to each field in a leaf-page record
in ROW_FORMAT=COMPACT.  This is a special case of
rec_init_offsets() and rec_get_offsets_func(). */
368
UNIV_INTERN
369 370 371
void
rec_init_offsets_comp_ordinary(
/*===========================*/
372
	const rec_t*		rec,	/*!< in: physical record in
373
					ROW_FORMAT=COMPACT */
374
	ulint			extra,	/*!< in: number of bytes to reserve
375 376 377
					between the record header and
					the data payload
					(usually REC_N_NEW_EXTRA_BYTES) */
378 379
	const dict_index_t*	index,	/*!< in: record descriptor */
	ulint*			offsets);/*!< in/out: array of offsets;
380
					in: n=rec_offs_n_fields(offsets) */
381

382
/******************************************************//**
383 384
The following function determines the offsets to each field
in the record.  It can reuse a previously allocated array. */
385
UNIV_INTERN
386 387 388
void
rec_get_offsets_reverse(
/*====================*/
389
	const byte*		extra,	/*!< in: the extra bytes of a
390 391 392
					compact record in reverse order,
					excluding the fixed-size
					REC_N_NEW_EXTRA_BYTES */
393 394
	const dict_index_t*	index,	/*!< in: record descriptor */
	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 401
Validates offsets returned by rec_get_offsets().
@return	TRUE if valid */
osku's avatar
osku committed
402 403 404 405
UNIV_INLINE
ibool
rec_offs_validate(
/*==============*/
406 407 408
	const rec_t*		rec,	/*!< in: record or NULL */
	const dict_index_t*	index,	/*!< in: record descriptor or NULL */
	const ulint*		offsets);/*!< in: array returned by
409
					rec_get_offsets() */
410
#ifdef UNIV_DEBUG
411
/************************************************************//**
osku's avatar
osku committed
412 413 414 415 416 417
Updates debug data in offsets, in order to avoid bogus
rec_offs_validate() failures. */
UNIV_INLINE
void
rec_offs_make_valid(
/*================*/
418 419 420
	const rec_t*		rec,	/*!< in: record */
	const dict_index_t*	index,	/*!< in: record descriptor */
	ulint*			offsets);/*!< in: array returned by
421
					rec_get_offsets() */
422 423 424
#else
# define rec_offs_make_valid(rec, index, offsets) ((void) 0)
#endif /* UNIV_DEBUG */
osku's avatar
osku committed
425

426
/************************************************************//**
427
The following function is used to get the offset to the nth
428 429
data field in an old-style record.
@return	offset to the field */
430
UNIV_INTERN
431 432 433
ulint
rec_get_nth_field_offs_old(
/*=======================*/
434 435 436
	const rec_t*	rec,	/*!< in: record */
	ulint		n,	/*!< in: index of the field */
	ulint*		len);	/*!< out: length of the field; UNIV_SQL_NULL
437 438 439
				if SQL null */
#define rec_get_nth_field_old(rec, n, len) \
((rec) + rec_get_nth_field_offs_old(rec, n, len))
440
/************************************************************//**
osku's avatar
osku committed
441 442
Gets the physical size of an old-style field.
Also an SQL null may have a field of size > 0,
443 444
if the data type is of a fixed size.
@return	field size in bytes */
osku's avatar
osku committed
445 446 447 448
UNIV_INLINE
ulint
rec_get_nth_field_size(
/*===================*/
449 450
	const rec_t*	rec,	/*!< in: record */
	ulint		n);	/*!< in: index of the field */
451
/************************************************************//**
452
The following function is used to get an offset to the nth
453 454
data field in a record.
@return	offset from the origin of rec */
osku's avatar
osku committed
455
UNIV_INLINE
456 457 458
ulint
rec_get_nth_field_offs(
/*===================*/
459 460 461
	const ulint*	offsets,/*!< in: array returned by rec_get_offsets() */
	ulint		n,	/*!< in: index of the field */
	ulint*		len);	/*!< out: length of the field; UNIV_SQL_NULL
osku's avatar
osku committed
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
/******************************************************//**
osku's avatar
osku committed
466
Determine if the offsets are for a record in the new
467 468
compact format.
@return	nonzero if compact format */
osku's avatar
osku committed
469 470 471 472
UNIV_INLINE
ulint
rec_offs_comp(
/*==========*/
473
	const ulint*	offsets);/*!< in: array returned by rec_get_offsets() */
474
/******************************************************//**
475
Determine if the offsets are for a record containing
476 477
externally stored columns.
@return	nonzero if externally stored */
478 479 480 481
UNIV_INLINE
ulint
rec_offs_any_extern(
/*================*/
482
	const ulint*	offsets);/*!< in: array returned by rec_get_offsets() */
483
/******************************************************//**
484 485
Returns nonzero if the extern bit is set in nth field of rec.
@return	nonzero if externally stored */
osku's avatar
osku committed
486 487 488 489
UNIV_INLINE
ulint
rec_offs_nth_extern(
/*================*/
490 491
	const ulint*	offsets,/*!< in: array returned by rec_get_offsets() */
	ulint		n);	/*!< in: nth field */
492
/******************************************************//**
493 494
Returns nonzero if the SQL NULL bit is set in nth field of rec.
@return	nonzero if SQL NULL */
osku's avatar
osku committed
495 496 497 498
UNIV_INLINE
ulint
rec_offs_nth_sql_null(
/*==================*/
499 500
	const ulint*	offsets,/*!< in: array returned by rec_get_offsets() */
	ulint		n);	/*!< in: nth field */
501
/******************************************************//**
502 503
Gets the physical size of a field.
@return	length of field */
osku's avatar
osku committed
504 505 506 507
UNIV_INLINE
ulint
rec_offs_nth_size(
/*==============*/
508 509
	const ulint*	offsets,/*!< in: array returned by rec_get_offsets() */
	ulint		n);	/*!< in: nth field */
osku's avatar
osku committed
510

511
/******************************************************//**
512 513
Returns the number of extern bits set in a record.
@return	number of externally stored fields */
514 515 516 517
UNIV_INLINE
ulint
rec_offs_n_extern(
/*==============*/
518
	const ulint*	offsets);/*!< in: array returned by rec_get_offsets() */
519
/***********************************************************//**
osku's avatar
osku committed
520 521
This is used to modify the value of an already existing field in a record.
The previous value must have exactly the same size as the new value. If len
522 523 524
is UNIV_SQL_NULL then the field is treated as an SQL null.
For records in ROW_FORMAT=COMPACT (new-style records), len must not be
UNIV_SQL_NULL unless the field already is SQL null. */
osku's avatar
osku committed
525 526 527 528
UNIV_INLINE
void
rec_set_nth_field(
/*==============*/
529 530 531 532 533
	rec_t*		rec,	/*!< in: record */
	const ulint*	offsets,/*!< in: array returned by rec_get_offsets() */
	ulint		n,	/*!< in: index number of the field */
	const void*	data,	/*!< in: pointer to the data if not SQL null */
	ulint		len);	/*!< in: length of the data or UNIV_SQL_NULL */
534
/**********************************************************//**
osku's avatar
osku committed
535 536 537
The following function returns the data size of an old-style physical
record, that is the sum of field lengths. SQL null fields
are counted as length 0 fields. The value returned by the function
538 539
is the distance from record origin to record end in bytes.
@return	size */
osku's avatar
osku committed
540 541 542 543
UNIV_INLINE
ulint
rec_get_data_size_old(
/*==================*/
544
	const rec_t*	rec);	/*!< in: physical record */
545
/**********************************************************//**
546
The following function returns the number of allocated elements
547 548
for an array of offsets.
@return	number of elements */
549 550 551 552
UNIV_INLINE
ulint
rec_offs_get_n_alloc(
/*=================*/
553
	const ulint*	offsets);/*!< in: array for rec_get_offsets() */
554
/**********************************************************//**
555 556 557 558 559 560
The following function sets the number of allocated elements
for an array of offsets. */
UNIV_INLINE
void
rec_offs_set_n_alloc(
/*=================*/
561
	ulint*	offsets,	/*!< out: array for rec_get_offsets(),
562
				must be allocated */
563
	ulint	n_alloc);	/*!< in: number of elements */
564 565
#define rec_offs_init(offsets) \
	rec_offs_set_n_alloc(offsets, (sizeof offsets) / sizeof *offsets)
566
/**********************************************************//**
567 568
The following function returns the number of fields in a record.
@return	number of fields */
osku's avatar
osku committed
569 570 571
UNIV_INLINE
ulint
rec_offs_n_fields(
572
/*==============*/
573
	const ulint*	offsets);/*!< in: array returned by rec_get_offsets() */
574
/**********************************************************//**
osku's avatar
osku committed
575 576 577
The following function returns the data size of a physical
record, that is the sum of field lengths. SQL null fields
are counted as length 0 fields. The value returned by the function
578 579
is the distance from record origin to record end in bytes.
@return	size */
osku's avatar
osku committed
580 581 582 583
UNIV_INLINE
ulint
rec_offs_data_size(
/*===============*/
584
	const ulint*	offsets);/*!< in: array returned by rec_get_offsets() */
585
/**********************************************************//**
osku's avatar
osku committed
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 589
start to record origin in bytes.
@return	size */
osku's avatar
osku committed
590 591 592 593
UNIV_INLINE
ulint
rec_offs_extra_size(
/*================*/
594
	const ulint*	offsets);/*!< in: array returned by rec_get_offsets() */
595
/**********************************************************//**
596 597
Returns the total size of a physical record.
@return	size */
osku's avatar
osku committed
598 599 600 601
UNIV_INLINE
ulint
rec_offs_size(
/*==========*/
602
	const ulint*	offsets);/*!< in: array returned by rec_get_offsets() */
603
/**********************************************************//**
604 605
Returns a pointer to the start of the record.
@return	pointer to start */
osku's avatar
osku committed
606 607 608 609
UNIV_INLINE
byte*
rec_get_start(
/*==========*/
610 611
	rec_t*		rec,	/*!< in: pointer to record */
	const ulint*	offsets);/*!< in: array returned by rec_get_offsets() */
612
/**********************************************************//**
613 614
Returns a pointer to the end of the record.
@return	pointer to end */
osku's avatar
osku committed
615 616 617 618
UNIV_INLINE
byte*
rec_get_end(
/*========*/
619 620
	rec_t*		rec,	/*!< in: pointer to record */
	const ulint*	offsets);/*!< in: array returned by rec_get_offsets() */
621
/***************************************************************//**
622 623
Copies a physical record to a buffer.
@return	pointer to the origin of the copy */
osku's avatar
osku committed
624 625 626 627
UNIV_INLINE
rec_t*
rec_copy(
/*=====*/
628 629 630
	void*		buf,	/*!< in: buffer */
	const rec_t*	rec,	/*!< in: physical record */
	const ulint*	offsets);/*!< in: array returned by rec_get_offsets() */
631
#ifndef UNIV_HOTBACKUP
632
/**************************************************************//**
osku's avatar
osku committed
633
Copies the first n fields of a physical record to a new physical record in
634 635
a buffer.
@return	own: copied record */
636
UNIV_INTERN
osku's avatar
osku committed
637 638 639
rec_t*
rec_copy_prefix_to_buf(
/*===================*/
640 641 642
	const rec_t*		rec,		/*!< in: physical record */
	const dict_index_t*	index,		/*!< in: record descriptor */
	ulint			n_fields,	/*!< in: number of fields
643
						to copy */
644
	byte**			buf,		/*!< in/out: memory buffer
645 646
						for the copied prefix,
						or NULL */
647
	ulint*			buf_size);	/*!< in/out: buffer size */
648
/************************************************************//**
649 650
Folds a prefix of a physical record to a ulint.
@return	the folded value */
osku's avatar
osku committed
651 652 653 654
UNIV_INLINE
ulint
rec_fold(
/*=====*/
655 656
	const rec_t*	rec,		/*!< in: the physical record */
	const ulint*	offsets,	/*!< in: array returned by
osku's avatar
osku committed
657
					rec_get_offsets() */
658
	ulint		n_fields,	/*!< in: number of complete
osku's avatar
osku committed
659
					fields to fold */
660
	ulint		n_bytes,	/*!< in: number of bytes to fold
osku's avatar
osku committed
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 670
rec_convert_dtuple_to_rec_comp(
/*===========================*/
671 672
	rec_t*			rec,	/*!< in: origin of record */
	ulint			extra,	/*!< in: number of bytes to
673 674 675
					reserve between the record
					header and the data payload
					(normally REC_N_NEW_EXTRA_BYTES) */
676 677 678 679
	const dict_index_t*	index,	/*!< in: record descriptor */
	ulint			status,	/*!< in: status bits of the record */
	const dfield_t*		fields,	/*!< in: array of data fields */
	ulint			n_fields);/*!< in: number of data fields */
680
/*********************************************************//**
marko's avatar
marko committed
681
Builds a physical record out of a data tuple and
682 683
stores it into the given buffer.
@return	pointer to the origin of physical record */
684
UNIV_INTERN
685
rec_t*
osku's avatar
osku committed
686
rec_convert_dtuple_to_rec(
687
/*======================*/
688
	byte*			buf,	/*!< in: start address of the
689
					physical record */
690 691 692
	const dict_index_t*	index,	/*!< in: record descriptor */
	const dtuple_t*		dtuple,	/*!< in: data tuple */
	ulint			n_ext);	/*!< in: number of
693
					externally stored columns */
694
/**********************************************************//**
osku's avatar
osku committed
695
Returns the extra size of an old-style physical record if we know its
696 697
data size and number of fields.
@return	extra size */
osku's avatar
osku committed
698 699 700 701
UNIV_INLINE
ulint
rec_get_converted_extra_size(
/*=========================*/
702 703 704
	ulint	data_size,	/*!< in: data size */
	ulint	n_fields,	/*!< in: number of fields */
	ulint	n_ext)		/*!< in: number of externally stored columns */
osku's avatar
osku committed
705
		__attribute__((const));
706
/**********************************************************//**
707 708
Determines the size of a data tuple prefix in ROW_FORMAT=COMPACT.
@return	total size */
709 710 711 712
UNIV_INTERN
ulint
rec_get_converted_size_comp_prefix(
/*===============================*/
713
	const dict_index_t*	index,	/*!< in: record descriptor;
714 715 716
					dict_table_is_comp() is
					assumed to hold, even if
					it does not */
717 718 719
	const dfield_t*		fields,	/*!< in: array of data fields */
	ulint			n_fields,/*!< in: number of data fields */
	ulint*			extra);	/*!< out: extra size */
720
/**********************************************************//**
721 722
Determines the size of a data tuple in ROW_FORMAT=COMPACT.
@return	total size */
723
UNIV_INTERN
724 725 726
ulint
rec_get_converted_size_comp(
/*========================*/
727
	const dict_index_t*	index,	/*!< in: record descriptor;
728 729 730
					dict_table_is_comp() is
					assumed to hold, even if
					it does not */
731 732 733 734
	ulint			status,	/*!< in: status bits of the record */
	const dfield_t*		fields,	/*!< in: array of data fields */
	ulint			n_fields,/*!< in: number of data fields */
	ulint*			extra);	/*!< out: extra size */
735
/**********************************************************//**
osku's avatar
osku committed
736
The following function returns the size of a data tuple when converted to
737 738
a physical record.
@return	size */
osku's avatar
osku committed
739 740 741 742
UNIV_INLINE
ulint
rec_get_converted_size(
/*===================*/
743 744 745
	dict_index_t*	index,	/*!< in: record descriptor */
	const dtuple_t*	dtuple,	/*!< in: data tuple */
	ulint		n_ext);	/*!< in: number of externally stored columns */
746
#ifndef UNIV_HOTBACKUP
747
/**************************************************************//**
osku's avatar
osku committed
748 749
Copies the first n fields of a physical record to a data tuple.
The fields are copied to the memory heap. */
750
UNIV_INTERN
osku's avatar
osku committed
751 752 753
void
rec_copy_prefix_to_dtuple(
/*======================*/
754 755 756 757
	dtuple_t*		tuple,		/*!< out: data tuple */
	const rec_t*		rec,		/*!< in: physical record */
	const dict_index_t*	index,		/*!< in: record descriptor */
	ulint			n_fields,	/*!< in: number of fields
758
						to copy */
759
	mem_heap_t*		heap);		/*!< in: memory heap */
760
#endif /* !UNIV_HOTBACKUP */
761
/***************************************************************//**
762 763
Validates the consistency of a physical record.
@return	TRUE if ok */
764
UNIV_INTERN
osku's avatar
osku committed
765 766 767
ibool
rec_validate(
/*=========*/
768 769
	const rec_t*	rec,	/*!< in: physical record */
	const ulint*	offsets);/*!< in: array returned by rec_get_offsets() */
770
/***************************************************************//**
osku's avatar
osku committed
771
Prints an old-style physical record. */
772
UNIV_INTERN
osku's avatar
osku committed
773 774 775
void
rec_print_old(
/*==========*/
776 777
	FILE*		file,	/*!< in: file where to print */
	const rec_t*	rec);	/*!< in: physical record */
778
#ifndef UNIV_HOTBACKUP
779
/***************************************************************//**
780 781
Prints a physical record in ROW_FORMAT=COMPACT.  Ignores the
record header. */
782
UNIV_INTERN
783 784 785
void
rec_print_comp(
/*===========*/
786 787 788
	FILE*		file,	/*!< in: file where to print */
	const rec_t*	rec,	/*!< in: physical record */
	const ulint*	offsets);/*!< in: array returned by rec_get_offsets() */
789
/***************************************************************//**
osku's avatar
osku committed
790
Prints a physical record. */
791
UNIV_INTERN
osku's avatar
osku committed
792 793 794
void
rec_print_new(
/*==========*/
795 796 797
	FILE*		file,	/*!< in: file where to print */
	const rec_t*	rec,	/*!< in: physical record */
	const ulint*	offsets);/*!< in: array returned by rec_get_offsets() */
798
/***************************************************************//**
osku's avatar
osku committed
799
Prints a physical record. */
800
UNIV_INTERN
osku's avatar
osku committed
801 802 803
void
rec_print(
/*======*/
804 805 806
	FILE*		file,	/*!< in: file where to print */
	const rec_t*	rec,	/*!< in: physical record */
	dict_index_t*	index);	/*!< in: record descriptor */
807
#endif /* UNIV_HOTBACKUP */
osku's avatar
osku committed
808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824

#define REC_INFO_BITS		6	/* This is single byte bit-field */

/* Maximum lengths for the data in a physical record if the offsets
are given in one byte (resp. two byte) format. */
#define REC_1BYTE_OFFS_LIMIT	0x7FUL
#define REC_2BYTE_OFFS_LIMIT	0x7FFFUL

/* The data size of record must be smaller than this because we reserve
two upmost bits in a two byte offset for special purposes */
#define REC_MAX_DATA_SIZE	(16 * 1024)

#ifndef UNIV_NONINL
#include "rem0rec.ic"
#endif

#endif