rem0rec.h 20 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14
/************************************************************************
Record manager

(c) 1994-1996 Innobase Oy

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

#ifndef rem0rec_h
#define rem0rec_h

#include "univ.i"
#include "data0data.h"
#include "rem0types.h"
15
#include "mtr0types.h"
16 17 18 19 20 21 22 23

/* Maximum values for various fields (for non-blob tuples) */
#define REC_MAX_N_FIELDS	(1024 - 1)
#define REC_MAX_HEAP_NO		(2 * 8192 - 1)
#define REC_MAX_N_OWNED		(16 - 1)

/* Flag denoting the predefined minimum record: this bit is ORed in the 4
info bits of a record */
unknown's avatar
unknown committed
24
#define REC_INFO_MIN_REC_FLAG	0x10UL
25

unknown's avatar
unknown committed
26 27 28 29 30 31 32 33 34 35 36 37
/* 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
38 39 40 41 42 43 44 45 46 47

/**********************************************************
The following function is used to get the offset of the
next chained record on the same page. */
UNIV_INLINE
ulint 
rec_get_next_offs(
/*==============*/
			/* out: the page offset of the next 
			chained record */
unknown's avatar
unknown committed
48 49
	rec_t*	rec,	/* in: physical record */
	ibool	comp);	/* in: TRUE=compact page format */
50 51 52 53 54 55 56 57
/**********************************************************
The following function is used to set the next record offset field
of the record. */
UNIV_INLINE
void
rec_set_next_offs(
/*==============*/
	rec_t*	rec,	/* in: physical record */
unknown's avatar
unknown committed
58
	ibool	comp,	/* in: TRUE=compact page format */
59 60 61
	ulint	next);	/* in: offset of the next record */
/**********************************************************
The following function is used to get the number of fields
unknown's avatar
unknown committed
62
in an old-style record. */
63 64
UNIV_INLINE
ulint
unknown's avatar
unknown committed
65 66
rec_get_n_fields_old(
/*=================*/
67 68 69
			/* out: number of data fields */
	rec_t*	rec);	/* in: physical record */
/**********************************************************
70 71 72 73 74 75 76 77 78 79
The following function is used to get the number of fields
in a record. */
UNIV_INLINE
ulint
rec_get_n_fields(
/*=============*/
				/* out: number of data fields */
	rec_t*		rec,	/* in: physical record */
	dict_index_t*	index);	/* in: record descriptor */
/**********************************************************
80 81 82 83 84 85 86
The following function is used to get the number of records
owned by the previous directory record. */
UNIV_INLINE
ulint
rec_get_n_owned(
/*============*/
			/* out: number of owned records */
unknown's avatar
unknown committed
87 88
	rec_t*	rec,	/* in: physical record */
	ibool	comp);	/* in: TRUE=compact page format */
89 90 91 92 93 94 95 96
/**********************************************************
The following function is used to set the number of owned
records. */
UNIV_INLINE
void
rec_set_n_owned(
/*============*/
	rec_t*	rec,		/* in: physical record */
unknown's avatar
unknown committed
97
	ibool	comp,		/* in: TRUE=compact page format */
98 99 100 101 102 103 104 105 106
	ulint	n_owned);	/* in: the number of owned */
/**********************************************************
The following function is used to retrieve the info bits of
a record. */
UNIV_INLINE
ulint
rec_get_info_bits(
/*==============*/
			/* out: info bits */
unknown's avatar
unknown committed
107 108
	rec_t*	rec,	/* in: physical record */
	ibool	comp);	/* in: TRUE=compact page format */
109 110 111 112 113 114 115
/**********************************************************
The following function is used to set the info bits of a record. */
UNIV_INLINE
void
rec_set_info_bits(
/*==============*/
	rec_t*	rec,	/* in: physical record */
unknown's avatar
unknown committed
116
	ibool	comp,	/* in: TRUE=compact page format */
117 118
	ulint	bits);	/* in: info bits */
/**********************************************************
unknown's avatar
unknown committed
119
The following function retrieves the status bits of a new-style record. */
120
UNIV_INLINE
unknown's avatar
unknown committed
121 122 123 124 125 126 127 128 129 130 131 132 133 134 135
ulint
rec_get_status(
/*===========*/
			/* out: status bits */
	rec_t*	rec);	/* in: physical record */

/**********************************************************
The following function is used to set the status bits of a new-style record. */
UNIV_INLINE
void
rec_set_status(
/*===========*/
	rec_t*	rec,	/* in: physical record */
	ulint	bits);	/* in: info bits */

136 137 138 139 140 141
/**********************************************************
The following function is used to retrieve the info and status
bits of a record.  (Only compact records have status bits.) */
UNIV_INLINE
ulint
rec_get_info_and_status_bits(
unknown's avatar
unknown committed
142
/*=========================*/
143 144 145 146 147 148 149 150 151
			/* out: info bits */
	rec_t*	rec,	/* in: physical record */
	ibool	comp);	/* in: TRUE=compact page format */
/**********************************************************
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(
unknown's avatar
unknown committed
152
/*=========================*/
153 154 155 156
	rec_t*	rec,	/* in: physical record */
	ibool	comp,	/* in: TRUE=compact page format */
	ulint	bits);	/* in: info bits */

157 158 159 160 161 162 163
/**********************************************************
The following function tells if record is delete marked. */
UNIV_INLINE
ibool
rec_get_deleted_flag(
/*=================*/
			/* out: TRUE if delete marked */
unknown's avatar
unknown committed
164 165
	rec_t*	rec,	/* in: physical record */
	ibool	comp);	/* in: TRUE=compact page format */
166 167 168 169 170 171 172
/**********************************************************
The following function is used to set the deleted bit. */
UNIV_INLINE
void
rec_set_deleted_flag(
/*=================*/
	rec_t*	rec,	/* in: physical record */
unknown's avatar
unknown committed
173
	ibool	comp,	/* in: TRUE=compact page format */
174 175
	ibool	flag);	/* in: TRUE if delete marked */
/**********************************************************
unknown's avatar
unknown committed
176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191
The following function tells if a new-style record is a node pointer. */
UNIV_INLINE
ibool
rec_get_node_ptr_flag(
/*=================*/
			/* out: TRUE if node pointer */
	rec_t*	rec);	/* in: physical record */
/**********************************************************
The following function is used to flag a record as a node pointer. */
UNIV_INLINE
void
rec_set_node_ptr_flag(
/*=================*/
	rec_t*	rec,	/* in: physical record */
	ibool	flag);	/* in: TRUE if the record is a node pointer */
/**********************************************************
192 193 194 195 196 197 198
The following function is used to get the order number
of the record in the heap of the index page. */
UNIV_INLINE
ulint
rec_get_heap_no(
/*=============*/
			/* out: heap order number */
unknown's avatar
unknown committed
199 200
	rec_t*	rec,	/* in: physical record */
	ibool	comp);	/* in: TRUE=compact page format */
201 202 203 204 205 206 207 208
/**********************************************************
The following function is used to set the heap number
field in the record. */
UNIV_INLINE
void
rec_set_heap_no(
/*=============*/
	rec_t*	rec,	/* in: physical record */
unknown's avatar
unknown committed
209
	ibool	comp,	/* in: TRUE=compact page format */
210 211 212 213 214 215 216 217 218 219
	ulint	heap_no);/* in: the heap number */
/**********************************************************
The following function is used to test whether the data offsets
in the record are stored in one-byte or two-byte format. */
UNIV_INLINE
ibool
rec_get_1byte_offs_flag(
/*====================*/
			/* out: TRUE if 1-byte form */
	rec_t*	rec);	/* in: physical record */
unknown's avatar
unknown committed
220 221
/**********************************************************
The following function determines the offsets to each field
222
in the record.  It can reuse a previously allocated array. */
unknown's avatar
unknown committed
223 224

ulint*
225 226
rec_get_offsets_func(
/*=================*/
unknown's avatar
unknown committed
227 228 229
				/* out: the new offsets */
	rec_t*		rec,	/* in: physical record */
	dict_index_t*	index,	/* in: record descriptor */
230 231 232
	ulint*		offsets,/* in: array consisting of offsets[0]
				allocated elements, or an array from
				rec_get_offsets(), or NULL */
unknown's avatar
unknown committed
233 234
	ulint		n_fields,/* in: maximum number of initialized fields
				(ULINT_UNDEFINED if all fields) */
235 236 237 238 239 240
	mem_heap_t**	heap,	/* in/out: memory heap */
	const char*	file,	/* in: file name where called */
	ulint		line);	/* in: line number where called */

#define rec_get_offsets(rec,index,offsets,n,heap)	\
	rec_get_offsets_func(rec,index,offsets,n,heap,__FILE__,__LINE__)
unknown's avatar
unknown committed
241 242

/****************************************************************
243
Validates offsets returned by rec_get_offsets(). */
unknown's avatar
unknown committed
244 245 246 247 248 249 250
UNIV_INLINE
ibool
rec_offs_validate(
/*==============*/
				/* out: TRUE if valid */
	rec_t*		rec,	/* in: record or NULL */
	dict_index_t*	index,	/* in: record descriptor or NULL */
251
	const ulint*	offsets);/* in: array returned by rec_get_offsets() */
unknown's avatar
unknown committed
252 253 254 255 256 257 258
/****************************************************************
Updates debug data in offsets, in order to avoid bogus
rec_offs_validate() failures. */
UNIV_INLINE
void
rec_offs_make_valid(
/*================*/
259 260 261
	rec_t*		rec,	/* in: record */
	dict_index_t*	index,/* in: record descriptor */
	ulint*		offsets);/* in: array returned by rec_get_offsets() */
unknown's avatar
unknown committed
262

263 264
/****************************************************************
The following function is used to get a pointer to the nth
unknown's avatar
unknown committed
265
data field in an old-style record. */
266 267

byte*
unknown's avatar
unknown committed
268 269
rec_get_nth_field_old(
/*==================*/
unknown's avatar
unknown committed
270
 			/* out: pointer to the field */
271 272 273 274 275
 	rec_t*	rec, 	/* in: record */
 	ulint	n,	/* in: index of the field */
	ulint*	len);	/* out: length of the field; UNIV_SQL_NULL 
			if SQL null */
/****************************************************************
unknown's avatar
unknown committed
276 277 278
Gets the physical size of an old-style field.
Also an SQL null may have a field of size > 0,
if the data type is of a fixed size. */
279 280 281 282 283 284 285
UNIV_INLINE
ulint
rec_get_nth_field_size(
/*===================*/
			/* out: field size in bytes */
 	rec_t*	rec, 	/* in: record */
 	ulint	n);	/* in: index of the field */
unknown's avatar
unknown committed
286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301
/****************************************************************
The following function is used to get a pointer to the nth
data field in an old-style record. */
UNIV_INLINE
byte*
rec_get_nth_field(
/*==============*/
	 			/* out: pointer to the field */
	rec_t*		rec, 	/* in: record */
	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
				if SQL null */
/**********************************************************
Determine if the offsets are for a record in the new
compact format. */
302 303
UNIV_INLINE
ibool
unknown's avatar
unknown committed
304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335
rec_offs_comp(
/*==========*/
				/* out: TRUE if compact format */
	const ulint*	offsets);/* in: array returned by rec_get_offsets() */
/**********************************************************
Returns TRUE if the nth field of rec is SQL NULL. */
UNIV_INLINE
ibool
rec_offs_nth_null(
/*==============*/
				/* out: TRUE if SQL NULL */
	const ulint*	offsets,/* in: array returned by rec_get_offsets() */
	ulint		n);	/* in: nth field */
/**********************************************************
Returns TRUE if the extern bit is set in nth field of rec. */
UNIV_INLINE
ibool
rec_offs_nth_extern(
/*================*/
				/* out: TRUE if externally stored */
	const ulint*	offsets,/* in: array returned by rec_get_offsets() */
	ulint		n);	/* in: nth field */
/**********************************************************
Gets the physical size of a field. */
UNIV_INLINE
ulint
rec_offs_nth_size(
/*==============*/
				/* out: length of field */
	const ulint*	offsets,/* in: array returned by rec_get_offsets() */
	ulint		n);	/* in: nth field */

336 337 338 339 340
/**********************************************************
Returns TRUE if the extern bit is set in any of the fields
of rec. */
UNIV_INLINE
ibool
unknown's avatar
unknown committed
341 342 343 344
rec_offs_any_extern(
/*================*/
				/* out: TRUE if a field is stored externally */
	const ulint*	offsets);/* in: array returned by rec_get_offsets() */
345 346
/***************************************************************
Sets the value of the ith field extern storage bit. */
unknown's avatar
unknown committed
347
UNIV_INLINE
348 349 350
void
rec_set_nth_field_extern_bit(
/*=========================*/
unknown's avatar
unknown committed
351 352 353 354 355 356 357
	rec_t*		rec,	/* in: record */
	dict_index_t*	index,	/* in: record descriptor */
	ulint		i,	/* in: ith field */
	ibool		val,	/* in: value to set */
	mtr_t*		mtr);	/* in: mtr holding an X-latch to the page
				where rec is, or NULL; in the NULL case
				we do not write to log about the change */
358 359 360 361 362 363
/***************************************************************
Sets TRUE the extern storage bits of fields mentioned in an array. */

void
rec_set_field_extern_bits(
/*======================*/
unknown's avatar
unknown committed
364 365 366 367 368 369 370
	rec_t*		rec,	/* in: record */
	dict_index_t*	index,	/* in: record descriptor */
	const ulint*	vec,	/* in: array of field numbers */
	ulint		n_fields,/* in: number of fields numbers */
	mtr_t*		mtr);	/* in: mtr holding an X-latch to the page
				where rec is, or NULL; in the NULL case
				we do not write to log about the change */
371
/*************************************************************** 
unknown's avatar
unknown committed
372 373 374 375
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
is UNIV_SQL_NULL then the field is treated as an SQL null for old-style
records. For new-style records, len must not be UNIV_SQL_NULL. */
376 377 378 379
UNIV_INLINE
void
rec_set_nth_field(
/*==============*/
unknown's avatar
unknown committed
380 381 382 383 384 385 386 387 388
	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.
				If not SQL null, must have the same
				length as the previous value.
				If SQL null, previous value must be
				SQL null. */
389
/************************************************************** 
unknown's avatar
unknown committed
390
The following function returns the data size of an old-style physical
391 392 393 394 395
record, that is the sum of field lengths. SQL null fields
are counted as length 0 fields. The value returned by the function
is the distance from record origin to record end in bytes. */
UNIV_INLINE
ulint
unknown's avatar
unknown committed
396 397 398
rec_get_data_size_old(
/*==================*/
				/* out: size */
399 400
	rec_t*	rec);	/* in: physical record */
/************************************************************** 
unknown's avatar
unknown committed
401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419
The following function returns the number of fields in a record. */
UNIV_INLINE
ulint
rec_offs_n_fields(
/*===============*/
				/* out: number of fields */
	const ulint*	offsets);/* in: array returned by rec_get_offsets() */
/**************************************************************
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
is the distance from record origin to record end in bytes. */
UNIV_INLINE
ulint
rec_offs_data_size(
/*===============*/
				/* out: size */
	const ulint*	offsets);/* in: array returned by rec_get_offsets() */
/**************************************************************
420 421 422 423 424
Returns the total size of record minus data size of record.
The value returned by the function is the distance from record 
start to record origin in bytes. */
UNIV_INLINE
ulint
unknown's avatar
unknown committed
425 426 427 428 429
rec_offs_extra_size(
/*================*/
				/* out: size */
	const ulint*	offsets);/* in: array returned by rec_get_offsets() */
/**************************************************************
430 431
Returns the total size of a physical record.  */
UNIV_INLINE
unknown's avatar
unknown committed
432 433 434 435 436 437 438 439
ulint
rec_offs_size(
/*==========*/
				/* out: size */
	const ulint*	offsets);/* in: array returned by rec_get_offsets() */
/**************************************************************
Returns the total size of a physical record.  */

440 441 442
ulint
rec_get_size(
/*=========*/
unknown's avatar
unknown committed
443 444 445
				/* out: size */
	rec_t*		rec,	/* in: physical record */
	dict_index_t*	index);	/* in: record descriptor */
446 447 448 449 450 451
/**************************************************************
Returns a pointer to the start of the record. */
UNIV_INLINE
byte*
rec_get_start(
/*==========*/
unknown's avatar
unknown committed
452 453 454
				/* out: pointer to start */
	rec_t*		rec,	/* in: pointer to record */
	const ulint*	offsets);/* in: array returned by rec_get_offsets() */
455 456 457 458 459 460
/**************************************************************
Returns a pointer to the end of the record. */
UNIV_INLINE
byte*
rec_get_end(
/*========*/
unknown's avatar
unknown committed
461 462 463
				/* out: pointer to end */
	rec_t*		rec,	/* in: pointer to record */
	const ulint*	offsets);/* in: array returned by rec_get_offsets() */
464 465 466 467 468 469
/*******************************************************************
Copies a physical record to a buffer. */
UNIV_INLINE
rec_t*
rec_copy(
/*=====*/
unknown's avatar
unknown committed
470 471 472 473
				/* out: pointer to the origin of the copy */
	void*		buf,	/* in: buffer */
	const rec_t*	rec,	/* in: physical record */
	const ulint*	offsets);/* in: array returned by rec_get_offsets() */
474 475 476 477 478 479 480
/******************************************************************
Copies the first n fields of a physical record to a new physical record in
a buffer. */

rec_t*
rec_copy_prefix_to_buf(
/*===================*/
unknown's avatar
unknown committed
481 482 483 484 485 486 487
					/* out, own: copied record */
	rec_t*		rec,		/* in: physical record */
	dict_index_t*	index,		/* in: record descriptor */
	ulint		n_fields,	/* in: number of fields to copy */
	byte**		buf,		/* in/out: memory buffer
					for the copied prefix, or NULL */
	ulint*		buf_size);	/* in/out: buffer size */
488 489 490 491 492 493
/****************************************************************
Folds a prefix of a physical record to a ulint. */
UNIV_INLINE
ulint
rec_fold(
/*=====*/
unknown's avatar
unknown committed
494 495 496 497 498 499 500 501 502
					/* out: the folded value */
	rec_t*		rec,		/* in: the physical record */
	const ulint*	offsets,	/* in: array returned by
					rec_get_offsets() */
	ulint		n_fields,	/* in: number of complete
					fields to fold */
	ulint		n_bytes,	/* in: number of bytes to fold
					in an incomplete last field */
	dulint		tree_id);	/* in: index tree id */
503 504 505
/*************************************************************
Builds a physical record out of a data tuple and stores it beginning from
address destination. */
unknown's avatar
unknown committed
506

507 508 509
rec_t* 	
rec_convert_dtuple_to_rec(
/*======================*/			
unknown's avatar
unknown committed
510 511 512 513 514 515
				/* out: pointer to the origin
				of physical record */
	byte*		buf,	/* in: start address of the
				physical record */
	dict_index_t*	index,	/* in: record descriptor */
	dtuple_t*	dtuple);/* in: data tuple */
516
/**************************************************************
unknown's avatar
unknown committed
517
Returns the extra size of an old-style physical record if we know its
518 519 520 521 522 523 524
data size and number of fields. */
UNIV_INLINE
ulint
rec_get_converted_extra_size(
/*=========================*/
				/* out: extra size */
	ulint	data_size,	/* in: data size */
unknown's avatar
unknown committed
525 526
	ulint	n_fields)	/* in: number of fields */
		__attribute__((const));
527 528 529 530 531 532 533 534
/**************************************************************
The following function returns the size of a data tuple when converted to
a physical record. */
UNIV_INLINE
ulint
rec_get_converted_size(
/*===================*/
				/* out: size */
unknown's avatar
unknown committed
535
	dict_index_t*	index,	/* in: record descriptor */
536 537 538 539 540 541 542 543 544 545
	dtuple_t*	dtuple);/* in: data tuple */
/******************************************************************
Copies the first n fields of a physical record to a data tuple.
The fields are copied to the memory heap. */

void
rec_copy_prefix_to_dtuple(
/*======================*/
	dtuple_t*	tuple,		/* in: data tuple */
	rec_t*		rec,		/* in: physical record */
unknown's avatar
unknown committed
546
	dict_index_t*	index,		/* in: record descriptor */
547 548 549 550 551 552 553 554
	ulint		n_fields,	/* in: number of fields to copy */
	mem_heap_t*	heap);		/* in: memory heap */
/*******************************************************************
Validates the consistency of a physical record. */

ibool
rec_validate(
/*=========*/
unknown's avatar
unknown committed
555 556 557 558 559 560 561 562 563 564 565
				/* out: TRUE if ok */
	rec_t*		rec,	/* in: physical record */
	const ulint*	offsets);/* in: array returned by rec_get_offsets() */
/*******************************************************************
Prints an old-style physical record. */

void
rec_print_old(
/*==========*/
	FILE*		file,	/* in: file where to print */
	rec_t*		rec);	/* in: physical record */
566 567
/*******************************************************************
Prints a physical record. */
unknown's avatar
unknown committed
568

569 570 571 572 573 574
void
rec_print_new(
/*==========*/
	FILE*		file,	/* in: file where to print */
	rec_t*		rec,	/* in: physical record */
	const ulint*	offsets);/* in: array returned by rec_get_offsets() */
575 576 577 578 579 580
/*******************************************************************
Prints a physical record. */

void
rec_print(
/*======*/
unknown's avatar
unknown committed
581 582
	FILE*		file,	/* in: file where to print */
	rec_t*		rec,	/* in: physical record */
583
	dict_index_t*	index);	/* in: record descriptor */
584 585 586

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

587 588
/* Maximum lengths for the data in a physical record if the offsets
are given in one byte (resp. two byte) format. */
unknown's avatar
unknown committed
589 590
#define REC_1BYTE_OFFS_LIMIT	0x7FUL
#define REC_2BYTE_OFFS_LIMIT	0x7FFFUL
591 592 593 594 595

/* 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)

596 597 598 599 600
#ifndef UNIV_NONINL
#include "rem0rec.ic"
#endif

#endif