~drizzle-trunk/drizzle/development

1 by brian
clean slate
1
/************************************************************************
2
Record manager
3
4
(c) 1994-1996 Innobase Oy
5
6
Created 5/30/1994 Heikki Tuuri
7
*************************************************************************/
8
9
#ifndef rem0rec_h
10
#define rem0rec_h
11
12
#include "univ.i"
13
#include "data0data.h"
14
#include "rem0types.h"
15
#include "mtr0types.h"
16
17
/* Info bit denoting the predefined minimum record: this bit is set
18
if and only if the record is the first user record on a non-leaf
19
B-tree page that is the leftmost page on its level
20
(PAGE_LEVEL is nonzero and FIL_PAGE_PREV is FIL_NULL). */
21
#define REC_INFO_MIN_REC_FLAG	0x10UL
22
23
/* Number of extra bytes in an old-style record,
24
in addition to the data and the offsets */
25
#define REC_N_OLD_EXTRA_BYTES	6
26
/* Number of extra bytes in a new-style record,
27
in addition to the data and the offsets */
28
#define REC_N_NEW_EXTRA_BYTES	5
29
30
/* Record status values */
31
#define REC_STATUS_ORDINARY	0
32
#define REC_STATUS_NODE_PTR	1
33
#define REC_STATUS_INFIMUM	2
34
#define REC_STATUS_SUPREMUM	3
35
36
/* Number of elements that should be initially allocated for the
37
offsets[] array, first passed to rec_get_offsets() */
38
#define REC_OFFS_NORMAL_SIZE	100
39
#define REC_OFFS_SMALL_SIZE	10
40
41
/**********************************************************
42
The following function is used to get the offset of the
43
next chained record on the same page. */
44
UNIV_INLINE
45
ulint
46
rec_get_next_offs(
47
/*==============*/
48
			/* out: the page offset of the next
49
			chained record */
50
	rec_t*	rec,	/* in: physical record */
51
	ulint	comp);	/* in: nonzero=compact page format */
52
/**********************************************************
53
The following function is used to set the next record offset field
54
of the record. */
55
UNIV_INLINE
56
void
57
rec_set_next_offs(
58
/*==============*/
59
	rec_t*	rec,	/* in: physical record */
60
	ulint	comp,	/* in: nonzero=compact page format */
61
	ulint	next);	/* in: offset of the next record */
62
/**********************************************************
63
The following function is used to get the number of fields
64
in an old-style record. */
65
UNIV_INLINE
66
ulint
67
rec_get_n_fields_old(
68
/*=================*/
69
			/* out: number of data fields */
70
	rec_t*	rec);	/* in: physical record */
71
/**********************************************************
72
The following function is used to get the number of fields
73
in a record. */
74
UNIV_INLINE
75
ulint
76
rec_get_n_fields(
77
/*=============*/
78
				/* out: number of data fields */
79
	rec_t*		rec,	/* in: physical record */
80
	dict_index_t*	index);	/* in: record descriptor */
81
/**********************************************************
82
The following function is used to get the number of records
83
owned by the previous directory record. */
84
UNIV_INLINE
85
ulint
86
rec_get_n_owned(
87
/*============*/
88
			/* out: number of owned records */
89
	rec_t*	rec,	/* in: physical record */
90
	ulint	comp);	/* in: nonzero=compact page format */
91
/**********************************************************
92
The following function is used to set the number of owned
93
records. */
94
UNIV_INLINE
95
void
96
rec_set_n_owned(
97
/*============*/
98
	rec_t*	rec,		/* in: physical record */
99
	ulint	comp,		/* in: nonzero=compact page format */
100
	ulint	n_owned);	/* in: the number of owned */
101
/**********************************************************
102
The following function is used to retrieve the info bits of
103
a record. */
104
UNIV_INLINE
105
ulint
106
rec_get_info_bits(
107
/*==============*/
108
			/* out: info bits */
109
	rec_t*	rec,	/* in: physical record */
110
	ulint	comp);	/* in: nonzero=compact page format */
111
/**********************************************************
112
The following function is used to set the info bits of a record. */
113
UNIV_INLINE
114
void
115
rec_set_info_bits(
116
/*==============*/
117
	rec_t*	rec,	/* in: physical record */
118
	ulint	comp,	/* in: nonzero=compact page format */
119
	ulint	bits);	/* in: info bits */
120
/**********************************************************
121
The following function retrieves the status bits of a new-style record. */
122
UNIV_INLINE
123
ulint
124
rec_get_status(
125
/*===========*/
126
			/* out: status bits */
127
	rec_t*	rec);	/* in: physical record */
128
129
/**********************************************************
130
The following function is used to set the status bits of a new-style record. */
131
UNIV_INLINE
132
void
133
rec_set_status(
134
/*===========*/
135
	rec_t*	rec,	/* in: physical record */
136
	ulint	bits);	/* in: info bits */
137
138
/**********************************************************
139
The following function is used to retrieve the info and status
140
bits of a record.  (Only compact records have status bits.) */
141
UNIV_INLINE
142
ulint
143
rec_get_info_and_status_bits(
144
/*=========================*/
145
			/* out: info bits */
146
	rec_t*	rec,	/* in: physical record */
147
	ulint	comp);	/* in: nonzero=compact page format */
148
/**********************************************************
149
The following function is used to set the info and status
150
bits of a record.  (Only compact records have status bits.) */
151
UNIV_INLINE
152
void
153
rec_set_info_and_status_bits(
154
/*=========================*/
155
	rec_t*	rec,	/* in: physical record */
156
	ulint	comp,	/* in: nonzero=compact page format */
157
	ulint	bits);	/* in: info bits */
158
159
/**********************************************************
160
The following function tells if record is delete marked. */
161
UNIV_INLINE
162
ulint
163
rec_get_deleted_flag(
164
/*=================*/
165
			/* out: nonzero if delete marked */
166
	rec_t*	rec,	/* in: physical record */
167
	ulint	comp);	/* in: nonzero=compact page format */
168
/**********************************************************
169
The following function is used to set the deleted bit. */
170
UNIV_INLINE
171
void
172
rec_set_deleted_flag(
173
/*=================*/
174
	rec_t*	rec,	/* in: physical record */
175
	ulint	comp,	/* in: nonzero=compact page format */
176
	ulint	flag);	/* in: nonzero if delete marked */
177
/**********************************************************
178
The following function tells if a new-style record is a node pointer. */
179
UNIV_INLINE
180
ibool
181
rec_get_node_ptr_flag(
182
/*==================*/
183
			/* out: TRUE if node pointer */
184
	rec_t*	rec);	/* in: physical record */
185
/**********************************************************
186
The following function is used to get the order number
187
of the record in the heap of the index page. */
188
UNIV_INLINE
189
ulint
190
rec_get_heap_no(
191
/*============*/
192
			/* out: heap order number */
193
	rec_t*	rec,	/* in: physical record */
194
	ulint	comp);	/* in: nonzero=compact page format */
195
/**********************************************************
196
The following function is used to set the heap number
197
field in the record. */
198
UNIV_INLINE
199
void
200
rec_set_heap_no(
201
/*============*/
202
	rec_t*	rec,	/* in: physical record */
203
	ulint	comp,	/* in: nonzero=compact page format */
204
	ulint	heap_no);/* in: the heap number */
205
/**********************************************************
206
The following function is used to test whether the data offsets
207
in the record are stored in one-byte or two-byte format. */
208
UNIV_INLINE
209
ibool
210
rec_get_1byte_offs_flag(
211
/*====================*/
212
			/* out: TRUE if 1-byte form */
213
	rec_t*	rec);	/* in: physical record */
214
/**********************************************************
215
The following function determines the offsets to each field
216
in the record.	It can reuse a previously allocated array. */
217
218
ulint*
219
rec_get_offsets_func(
220
/*=================*/
221
				/* out: the new offsets */
222
	rec_t*		rec,	/* in: physical record */
223
	dict_index_t*	index,	/* in: record descriptor */
224
	ulint*		offsets,/* in: array consisting of offsets[0]
225
				allocated elements, or an array from
226
				rec_get_offsets(), or NULL */
227
	ulint		n_fields,/* in: maximum number of initialized fields
228
				(ULINT_UNDEFINED if all fields) */
229
	mem_heap_t**	heap,	/* in/out: memory heap */
230
	const char*	file,	/* in: file name where called */
231
	ulint		line);	/* in: line number where called */
232
233
#define rec_get_offsets(rec,index,offsets,n,heap)	\
234
	rec_get_offsets_func(rec,index,offsets,n,heap,__FILE__,__LINE__)
235
236
/****************************************************************
237
Validates offsets returned by rec_get_offsets(). */
238
UNIV_INLINE
239
ibool
240
rec_offs_validate(
241
/*==============*/
242
				/* out: TRUE if valid */
243
	rec_t*		rec,	/* in: record or NULL */
244
	dict_index_t*	index,	/* in: record descriptor or NULL */
245
	const ulint*	offsets);/* in: array returned by rec_get_offsets() */
246
/****************************************************************
247
Updates debug data in offsets, in order to avoid bogus
248
rec_offs_validate() failures. */
249
UNIV_INLINE
250
void
251
rec_offs_make_valid(
252
/*================*/
253
	rec_t*		rec,	/* in: record */
254
	dict_index_t*	index,/* in: record descriptor */
255
	ulint*		offsets);/* in: array returned by rec_get_offsets() */
256
257
/****************************************************************
258
The following function is used to get a pointer to the nth
259
data field in an old-style record. */
260
261
byte*
262
rec_get_nth_field_old(
263
/*==================*/
264
			/* out: pointer to the field */
265
	rec_t*	rec,	/* in: record */
266
	ulint	n,	/* in: index of the field */
267
	ulint*	len);	/* out: length of the field; UNIV_SQL_NULL
268
			if SQL null */
269
/****************************************************************
270
Gets the physical size of an old-style field.
271
Also an SQL null may have a field of size > 0,
272
if the data type is of a fixed size. */
273
UNIV_INLINE
274
ulint
275
rec_get_nth_field_size(
276
/*===================*/
277
			/* out: field size in bytes */
278
	rec_t*	rec,	/* in: record */
279
	ulint	n);	/* in: index of the field */
280
/****************************************************************
281
The following function is used to get a pointer to the nth
282
data field in a record. */
283
UNIV_INLINE
284
byte*
285
rec_get_nth_field(
286
/*==============*/
287
				/* out: pointer to the field */
288
	rec_t*		rec,	/* in: record */
289
	const ulint*	offsets,/* in: array returned by rec_get_offsets() */
290
	ulint		n,	/* in: index of the field */
291
	ulint*		len);	/* out: length of the field; UNIV_SQL_NULL
292
				if SQL null */
293
/**********************************************************
294
Determine if the offsets are for a record in the new
295
compact format. */
296
UNIV_INLINE
297
ulint
298
rec_offs_comp(
299
/*==========*/
300
				/* out: nonzero if compact format */
301
	const ulint*	offsets);/* in: array returned by rec_get_offsets() */
302
/**********************************************************
303
Returns nonzero if the extern bit is set in nth field of rec. */
304
UNIV_INLINE
305
ulint
306
rec_offs_nth_extern(
307
/*================*/
308
				/* out: nonzero if externally stored */
309
	const ulint*	offsets,/* in: array returned by rec_get_offsets() */
310
	ulint		n);	/* in: nth field */
311
/**********************************************************
312
Returns nonzero if the SQL NULL bit is set in nth field of rec. */
313
UNIV_INLINE
314
ulint
315
rec_offs_nth_sql_null(
316
/*==================*/
317
				/* out: nonzero if SQL NULL */
318
	const ulint*	offsets,/* in: array returned by rec_get_offsets() */
319
	ulint		n);	/* in: nth field */
320
/**********************************************************
321
Gets the physical size of a field. */
322
UNIV_INLINE
323
ulint
324
rec_offs_nth_size(
325
/*==============*/
326
				/* out: length of field */
327
	const ulint*	offsets,/* in: array returned by rec_get_offsets() */
328
	ulint		n);	/* in: nth field */
329
330
/**********************************************************
331
Returns TRUE if the extern bit is set in any of the fields
332
of rec. */
333
UNIV_INLINE
334
ibool
335
rec_offs_any_extern(
336
/*================*/
337
				/* out: TRUE if a field is stored externally */
338
	const ulint*	offsets);/* in: array returned by rec_get_offsets() */
339
/***************************************************************
340
Sets the value of the ith field extern storage bit. */
341
UNIV_INLINE
342
void
343
rec_set_nth_field_extern_bit(
344
/*=========================*/
345
	rec_t*		rec,	/* in: record */
346
	dict_index_t*	index,	/* in: record descriptor */
347
	ulint		i,	/* in: ith field */
348
	ibool		val,	/* in: value to set */
349
	mtr_t*		mtr);	/* in: mtr holding an X-latch to the page
350
				where rec is, or NULL; in the NULL case
351
				we do not write to log about the change */
352
/***************************************************************
353
Sets TRUE the extern storage bits of fields mentioned in an array. */
354
355
void
356
rec_set_field_extern_bits(
357
/*======================*/
358
	rec_t*		rec,	/* in: record */
359
	dict_index_t*	index,	/* in: record descriptor */
360
	const ulint*	vec,	/* in: array of field numbers */
361
	ulint		n_fields,/* in: number of fields numbers */
362
	mtr_t*		mtr);	/* in: mtr holding an X-latch to the page
363
				where rec is, or NULL; in the NULL case
364
				we do not write to log about the change */
365
/***************************************************************
366
This is used to modify the value of an already existing field in a record.
367
The previous value must have exactly the same size as the new value. If len
368
is UNIV_SQL_NULL then the field is treated as an SQL null for old-style
369
records. For new-style records, len must not be UNIV_SQL_NULL. */
370
UNIV_INLINE
371
void
372
rec_set_nth_field(
373
/*==============*/
374
	rec_t*		rec,	/* in: record */
375
	const ulint*	offsets,/* in: array returned by rec_get_offsets() */
376
	ulint		n,	/* in: index number of the field */
377
	const void*	data,	/* in: pointer to the data if not SQL null */
378
	ulint		len);	/* in: length of the data or UNIV_SQL_NULL.
379
				If not SQL null, must have the same
380
				length as the previous value.
381
				If SQL null, previous value must be
382
				SQL null. */
383
/**************************************************************
384
The following function returns the data size of an old-style physical
385
record, that is the sum of field lengths. SQL null fields
386
are counted as length 0 fields. The value returned by the function
387
is the distance from record origin to record end in bytes. */
388
UNIV_INLINE
389
ulint
390
rec_get_data_size_old(
391
/*==================*/
392
				/* out: size */
393
	rec_t*	rec);	/* in: physical record */
394
/**************************************************************
395
The following function returns the number of fields in a record. */
396
UNIV_INLINE
397
ulint
398
rec_offs_n_fields(
399
/*==============*/
400
				/* out: number of fields */
401
	const ulint*	offsets);/* in: array returned by rec_get_offsets() */
402
/**************************************************************
403
The following function returns the data size of a physical
404
record, that is the sum of field lengths. SQL null fields
405
are counted as length 0 fields. The value returned by the function
406
is the distance from record origin to record end in bytes. */
407
UNIV_INLINE
408
ulint
409
rec_offs_data_size(
410
/*===============*/
411
				/* out: size */
412
	const ulint*	offsets);/* in: array returned by rec_get_offsets() */
413
/**************************************************************
414
Returns the total size of record minus data size of record.
415
The value returned by the function is the distance from record
416
start to record origin in bytes. */
417
UNIV_INLINE
418
ulint
419
rec_offs_extra_size(
420
/*================*/
421
				/* out: size */
422
	const ulint*	offsets);/* in: array returned by rec_get_offsets() */
423
/**************************************************************
424
Returns the total size of a physical record.  */
425
UNIV_INLINE
426
ulint
427
rec_offs_size(
428
/*==========*/
429
				/* out: size */
430
	const ulint*	offsets);/* in: array returned by rec_get_offsets() */
431
/**************************************************************
432
Returns a pointer to the start of the record. */
433
UNIV_INLINE
434
byte*
435
rec_get_start(
436
/*==========*/
437
				/* out: pointer to start */
438
	rec_t*		rec,	/* in: pointer to record */
439
	const ulint*	offsets);/* in: array returned by rec_get_offsets() */
440
/**************************************************************
441
Returns a pointer to the end of the record. */
442
UNIV_INLINE
443
byte*
444
rec_get_end(
445
/*========*/
446
				/* out: pointer to end */
447
	rec_t*		rec,	/* in: pointer to record */
448
	const ulint*	offsets);/* in: array returned by rec_get_offsets() */
449
/*******************************************************************
450
Copies a physical record to a buffer. */
451
UNIV_INLINE
452
rec_t*
453
rec_copy(
454
/*=====*/
455
				/* out: pointer to the origin of the copy */
456
	void*		buf,	/* in: buffer */
457
	const rec_t*	rec,	/* in: physical record */
458
	const ulint*	offsets);/* in: array returned by rec_get_offsets() */
459
/******************************************************************
460
Copies the first n fields of a physical record to a new physical record in
461
a buffer. */
462
463
rec_t*
464
rec_copy_prefix_to_buf(
465
/*===================*/
466
					/* out, own: copied record */
467
	rec_t*		rec,		/* in: physical record */
468
	dict_index_t*	index,		/* in: record descriptor */
469
	ulint		n_fields,	/* in: number of fields to copy */
470
	byte**		buf,		/* in/out: memory buffer
471
					for the copied prefix, or NULL */
472
	ulint*		buf_size);	/* in/out: buffer size */
473
/****************************************************************
474
Folds a prefix of a physical record to a ulint. */
475
UNIV_INLINE
476
ulint
477
rec_fold(
478
/*=====*/
479
					/* out: the folded value */
480
	rec_t*		rec,		/* in: the physical record */
481
	const ulint*	offsets,	/* in: array returned by
482
					rec_get_offsets() */
483
	ulint		n_fields,	/* in: number of complete
484
					fields to fold */
485
	ulint		n_bytes,	/* in: number of bytes to fold
486
					in an incomplete last field */
487
	dulint		tree_id);	/* in: index tree id */
488
/*************************************************************
489
Builds a physical record out of a data tuple and stores it beginning from
490
address destination. */
491
492
rec_t*
493
rec_convert_dtuple_to_rec(
494
/*======================*/
495
				/* out: pointer to the origin
496
				of physical record */
497
	byte*		buf,	/* in: start address of the
498
				physical record */
499
	dict_index_t*	index,	/* in: record descriptor */
500
	dtuple_t*	dtuple);/* in: data tuple */
501
/**************************************************************
502
Returns the extra size of an old-style physical record if we know its
503
data size and number of fields. */
504
UNIV_INLINE
505
ulint
506
rec_get_converted_extra_size(
507
/*=========================*/
508
				/* out: extra size */
509
	ulint	data_size,	/* in: data size */
510
	ulint	n_fields)	/* in: number of fields */
511
		__attribute__((const));
512
/**************************************************************
513
The following function returns the size of a data tuple when converted to
514
a physical record. */
515
UNIV_INLINE
516
ulint
517
rec_get_converted_size(
518
/*===================*/
519
				/* out: size */
520
	dict_index_t*	index,	/* in: record descriptor */
521
	dtuple_t*	dtuple);/* in: data tuple */
522
/******************************************************************
523
Copies the first n fields of a physical record to a data tuple.
524
The fields are copied to the memory heap. */
525
526
void
527
rec_copy_prefix_to_dtuple(
528
/*======================*/
529
	dtuple_t*	tuple,		/* in: data tuple */
530
	rec_t*		rec,		/* in: physical record */
531
	dict_index_t*	index,		/* in: record descriptor */
532
	ulint		n_fields,	/* in: number of fields to copy */
533
	mem_heap_t*	heap);		/* in: memory heap */
534
/*******************************************************************
535
Validates the consistency of a physical record. */
536
537
ibool
538
rec_validate(
539
/*=========*/
540
				/* out: TRUE if ok */
541
	rec_t*		rec,	/* in: physical record */
542
	const ulint*	offsets);/* in: array returned by rec_get_offsets() */
543
/*******************************************************************
544
Prints an old-style physical record. */
545
546
void
547
rec_print_old(
548
/*==========*/
549
	FILE*		file,	/* in: file where to print */
550
	rec_t*		rec);	/* in: physical record */
551
/*******************************************************************
552
Prints a physical record. */
553
554
void
555
rec_print_new(
556
/*==========*/
557
	FILE*		file,	/* in: file where to print */
558
	rec_t*		rec,	/* in: physical record */
559
	const ulint*	offsets);/* in: array returned by rec_get_offsets() */
560
/*******************************************************************
561
Prints a physical record. */
562
563
void
564
rec_print(
565
/*======*/
566
	FILE*		file,	/* in: file where to print */
567
	rec_t*		rec,	/* in: physical record */
568
	dict_index_t*	index);	/* in: record descriptor */
569
570
#define REC_INFO_BITS		6	/* This is single byte bit-field */
571
572
/* Maximum lengths for the data in a physical record if the offsets
573
are given in one byte (resp. two byte) format. */
574
#define REC_1BYTE_OFFS_LIMIT	0x7FUL
575
#define REC_2BYTE_OFFS_LIMIT	0x7FFFUL
576
577
/* The data size of record must be smaller than this because we reserve
578
two upmost bits in a two byte offset for special purposes */
579
#define REC_MAX_DATA_SIZE	(16 * 1024)
580
581
#ifndef UNIV_NONINL
582
#include "rem0rec.ic"
583
#endif
584
585
#endif