~drizzle-trunk/drizzle/development

1 by brian
clean slate
1
/******************************************************
2
The index tree persistent cursor
3
4
(c) 1996 Innobase Oy
5
6
Created 2/23/1996 Heikki Tuuri
7
*******************************************************/
8
9
#ifndef btr0pcur_h
10
#define btr0pcur_h
11
12
#include "univ.i"
13
#include "dict0dict.h"
14
#include "data0data.h"
15
#include "mtr0mtr.h"
16
#include "page0cur.h"
17
#include "btr0cur.h"
18
#include "btr0btr.h"
19
#include "btr0types.h"
20
21
/* Relative positions for a stored cursor position */
22
#define BTR_PCUR_ON			1
23
#define BTR_PCUR_BEFORE			2
24
#define BTR_PCUR_AFTER			3
25
/* Note that if the tree is not empty, btr_pcur_store_position does not
26
use the following, but only uses the above three alternatives, where the
27
position is stored relative to a specific record: this makes implementation
28
of a scroll cursor easier */
29
#define BTR_PCUR_BEFORE_FIRST_IN_TREE	4	/* in an empty tree */
30
#define BTR_PCUR_AFTER_LAST_IN_TREE	5	/* in an empty tree */
31
32
/******************************************************************
33
Allocates memory for a persistent cursor object and initializes the cursor. */
34
35
btr_pcur_t*
36
btr_pcur_create_for_mysql(void);
37
/*============================*/
38
				/* out, own: persistent cursor */
39
/******************************************************************
40
Frees the memory for a persistent cursor object. */
41
42
void
43
btr_pcur_free_for_mysql(
44
/*====================*/
45
	btr_pcur_t*	cursor);	/* in, own: persistent cursor */
46
/******************************************************************
47
Copies the stored position of a pcur to another pcur. */
48
49
void
50
btr_pcur_copy_stored_position(
51
/*==========================*/
52
	btr_pcur_t*	pcur_receive,	/* in: pcur which will receive the
53
					position info */
54
	btr_pcur_t*	pcur_donate);	/* in: pcur from which the info is
55
					copied */
56
/******************************************************************
57
Sets the old_rec_buf field to NULL. */
58
UNIV_INLINE
59
void
60
btr_pcur_init(
61
/*==========*/
62
	btr_pcur_t*	pcur);	/* in: persistent cursor */
63
/******************************************************************
64
Initializes and opens a persistent cursor to an index tree. It should be
65
closed with btr_pcur_close. */
66
UNIV_INLINE
67
void
68
btr_pcur_open(
69
/*==========*/
70
	dict_index_t*	index,	/* in: index */
71
	dtuple_t*	tuple,	/* in: tuple on which search done */
72
	ulint		mode,	/* in: PAGE_CUR_L, ...;
73
				NOTE that if the search is made using a unique
74
				prefix of a record, mode should be
75
				PAGE_CUR_LE, not PAGE_CUR_GE, as the latter
76
				may end up on the previous page from the
77
				record! */
78
	ulint		latch_mode,/* in: BTR_SEARCH_LEAF, ... */
79
	btr_pcur_t*	cursor, /* in: memory buffer for persistent cursor */
80
	mtr_t*		mtr);	/* in: mtr */
81
/******************************************************************
82
Opens an persistent cursor to an index tree without initializing the
83
cursor. */
84
UNIV_INLINE
85
void
86
btr_pcur_open_with_no_init(
87
/*=======================*/
88
	dict_index_t*	index,	/* in: index */
89
	dtuple_t*	tuple,	/* in: tuple on which search done */
90
	ulint		mode,	/* in: PAGE_CUR_L, ...;
91
				NOTE that if the search is made using a unique
92
				prefix of a record, mode should be
93
				PAGE_CUR_LE, not PAGE_CUR_GE, as the latter
94
				may end up on the previous page of the
95
				record! */
96
	ulint		latch_mode,/* in: BTR_SEARCH_LEAF, ...;
97
				NOTE that if has_search_latch != 0 then
98
				we maybe do not acquire a latch on the cursor
99
				page, but assume that the caller uses his
100
				btr search latch to protect the record! */
101
	btr_pcur_t*	cursor, /* in: memory buffer for persistent cursor */
102
	ulint		has_search_latch,/* in: latch mode the caller
103
				currently has on btr_search_latch:
104
				RW_S_LATCH, or 0 */
105
	mtr_t*		mtr);	/* in: mtr */
106
/*********************************************************************
107
Opens a persistent cursor at either end of an index. */
108
UNIV_INLINE
109
void
110
btr_pcur_open_at_index_side(
111
/*========================*/
112
	ibool		from_left,	/* in: TRUE if open to the low end,
113
					FALSE if to the high end */
114
	dict_index_t*	index,		/* in: index */
115
	ulint		latch_mode,	/* in: latch mode */
116
	btr_pcur_t*	pcur,		/* in: cursor */
117
	ibool		do_init,	/* in: TRUE if should be initialized */
118
	mtr_t*		mtr);		/* in: mtr */
119
/******************************************************************
120
Gets the up_match value for a pcur after a search. */
121
UNIV_INLINE
122
ulint
123
btr_pcur_get_up_match(
124
/*==================*/
125
				/* out: number of matched fields at the cursor
126
				or to the right if search mode was PAGE_CUR_GE,
127
				otherwise undefined */
128
	btr_pcur_t*	cursor); /* in: memory buffer for persistent cursor */
129
/******************************************************************
130
Gets the low_match value for a pcur after a search. */
131
UNIV_INLINE
132
ulint
133
btr_pcur_get_low_match(
134
/*===================*/
135
				/* out: number of matched fields at the cursor
136
				or to the right if search mode was PAGE_CUR_LE,
137
				otherwise undefined */
138
	btr_pcur_t*	cursor); /* in: memory buffer for persistent cursor */
139
/******************************************************************
140
If mode is PAGE_CUR_G or PAGE_CUR_GE, opens a persistent cursor on the first
141
user record satisfying the search condition, in the case PAGE_CUR_L or
142
PAGE_CUR_LE, on the last user record. If no such user record exists, then
143
in the first case sets the cursor after last in tree, and in the latter case
144
before first in tree. The latching mode must be BTR_SEARCH_LEAF or
145
BTR_MODIFY_LEAF. */
146
147
void
148
btr_pcur_open_on_user_rec(
149
/*======================*/
150
	dict_index_t*	index,		/* in: index */
151
	dtuple_t*	tuple,		/* in: tuple on which search done */
152
	ulint		mode,		/* in: PAGE_CUR_L, ... */
153
	ulint		latch_mode,	/* in: BTR_SEARCH_LEAF or
154
					BTR_MODIFY_LEAF */
155
	btr_pcur_t*	cursor,		/* in: memory buffer for persistent
156
					cursor */
157
	mtr_t*		mtr);		/* in: mtr */
158
/**************************************************************************
159
Positions a cursor at a randomly chosen position within a B-tree. */
160
UNIV_INLINE
161
void
162
btr_pcur_open_at_rnd_pos(
163
/*=====================*/
164
	dict_index_t*	index,		/* in: index */
165
	ulint		latch_mode,	/* in: BTR_SEARCH_LEAF, ... */
166
	btr_pcur_t*	cursor,		/* in/out: B-tree pcur */
167
	mtr_t*		mtr);		/* in: mtr */
168
/******************************************************************
169
Frees the possible old_rec_buf buffer of a persistent cursor and sets the
170
latch mode of the persistent cursor to BTR_NO_LATCHES. */
171
UNIV_INLINE
172
void
173
btr_pcur_close(
174
/*===========*/
175
	btr_pcur_t*	cursor);	/* in: persistent cursor */
176
/******************************************************************
177
The position of the cursor is stored by taking an initial segment of the
178
record the cursor is positioned on, before, or after, and copying it to the
179
cursor data structure, or just setting a flag if the cursor id before the
180
first in an EMPTY tree, or after the last in an EMPTY tree. NOTE that the
181
page where the cursor is positioned must not be empty if the index tree is
182
not totally empty! */
183
184
void
185
btr_pcur_store_position(
186
/*====================*/
187
	btr_pcur_t*	cursor, /* in: persistent cursor */
188
	mtr_t*		mtr);	/* in: mtr */
189
/******************************************************************
190
Restores the stored position of a persistent cursor bufferfixing the page and
191
obtaining the specified latches. If the cursor position was saved when the
192
(1) cursor was positioned on a user record: this function restores the position
193
to the last record LESS OR EQUAL to the stored record;
194
(2) cursor was positioned on a page infimum record: restores the position to
195
the last record LESS than the user record which was the successor of the page
196
infimum;
197
(3) cursor was positioned on the page supremum: restores to the first record
198
GREATER than the user record which was the predecessor of the supremum.
199
(4) cursor was positioned before the first or after the last in an empty tree:
200
restores to before first or after the last in the tree. */
201
202
ibool
203
btr_pcur_restore_position(
204
/*======================*/
205
					/* out: TRUE if the cursor position
206
					was stored when it was on a user record
207
					and it can be restored on a user record
208
					whose ordering fields are identical to
209
					the ones of the original user record */
210
	ulint		latch_mode,	/* in: BTR_SEARCH_LEAF, ... */
211
	btr_pcur_t*	cursor,		/* in: detached persistent cursor */
212
	mtr_t*		mtr);		/* in: mtr */
213
/******************************************************************
214
If the latch mode of the cursor is BTR_LEAF_SEARCH or BTR_LEAF_MODIFY,
215
releases the page latch and bufferfix reserved by the cursor.
216
NOTE! In the case of BTR_LEAF_MODIFY, there should not exist changes
217
made by the current mini-transaction to the data protected by the
218
cursor latch, as then the latch must not be released until mtr_commit. */
219
220
void
221
btr_pcur_release_leaf(
222
/*==================*/
223
	btr_pcur_t*	cursor, /* in: persistent cursor */
224
	mtr_t*		mtr);	/* in: mtr */
225
/*************************************************************
226
Gets the rel_pos field for a cursor whose position has been stored. */
227
UNIV_INLINE
228
ulint
229
btr_pcur_get_rel_pos(
230
/*=================*/
231
				/* out: BTR_PCUR_ON, ... */
232
	btr_pcur_t*	cursor);/* in: persistent cursor */
233
/*************************************************************
234
Sets the mtr field for a pcur. */
235
UNIV_INLINE
236
void
237
btr_pcur_set_mtr(
238
/*=============*/
239
	btr_pcur_t*	cursor,	/* in: persistent cursor */
240
	mtr_t*		mtr);	/* in, own: mtr */
241
/*************************************************************
242
Gets the mtr field for a pcur. */
243
UNIV_INLINE
244
mtr_t*
245
btr_pcur_get_mtr(
246
/*=============*/
247
				/* out: mtr */
248
	btr_pcur_t*	cursor);	/* in: persistent cursor */
249
/******************************************************************
250
Commits the pcur mtr and sets the pcur latch mode to BTR_NO_LATCHES,
251
that is, the cursor becomes detached. If there have been modifications
252
to the page where pcur is positioned, this can be used instead of
253
btr_pcur_release_leaf. Function btr_pcur_store_position should be used
254
before calling this, if restoration of cursor is wanted later. */
255
UNIV_INLINE
256
void
257
btr_pcur_commit(
258
/*============*/
259
	btr_pcur_t*	pcur);	/* in: persistent cursor */
260
/******************************************************************
261
Differs from btr_pcur_commit in that we can specify the mtr to commit. */
262
UNIV_INLINE
263
void
264
btr_pcur_commit_specify_mtr(
265
/*========================*/
266
	btr_pcur_t*	pcur,	/* in: persistent cursor */
267
	mtr_t*		mtr);	/* in: mtr to commit */
268
/******************************************************************
269
Tests if a cursor is detached: that is the latch mode is BTR_NO_LATCHES. */
270
UNIV_INLINE
271
ibool
272
btr_pcur_is_detached(
273
/*=================*/
274
				/* out: TRUE if detached */
275
	btr_pcur_t*	pcur);	/* in: persistent cursor */
276
/*************************************************************
277
Moves the persistent cursor to the next record in the tree. If no records are
278
left, the cursor stays 'after last in tree'. */
279
UNIV_INLINE
280
ibool
281
btr_pcur_move_to_next(
282
/*==================*/
283
				/* out: TRUE if the cursor was not after last
284
				in tree */
285
	btr_pcur_t*	cursor,	/* in: persistent cursor; NOTE that the
286
				function may release the page latch */
287
	mtr_t*		mtr);	/* in: mtr */
288
/*************************************************************
289
Moves the persistent cursor to the previous record in the tree. If no records
290
are left, the cursor stays 'before first in tree'. */
291
292
ibool
293
btr_pcur_move_to_prev(
294
/*==================*/
295
				/* out: TRUE if the cursor was not before first
296
				in tree */
297
	btr_pcur_t*	cursor,	/* in: persistent cursor; NOTE that the
298
				function may release the page latch */
299
	mtr_t*		mtr);	/* in: mtr */
300
/*************************************************************
301
Moves the persistent cursor to the last record on the same page. */
302
UNIV_INLINE
303
void
304
btr_pcur_move_to_last_on_page(
305
/*==========================*/
306
	btr_pcur_t*	cursor,	/* in: persistent cursor */
307
	mtr_t*		mtr);	/* in: mtr */
308
/*************************************************************
309
Moves the persistent cursor to the next user record in the tree. If no user
310
records are left, the cursor ends up 'after last in tree'. */
311
UNIV_INLINE
312
ibool
313
btr_pcur_move_to_next_user_rec(
314
/*===========================*/
315
				/* out: TRUE if the cursor moved forward,
316
				ending on a user record */
317
	btr_pcur_t*	cursor,	/* in: persistent cursor; NOTE that the
318
				function may release the page latch */
319
	mtr_t*		mtr);	/* in: mtr */
320
/*************************************************************
321
Moves the persistent cursor to the first record on the next page.
322
Releases the latch on the current page, and bufferunfixes it.
323
Note that there must not be modifications on the current page,
324
as then the x-latch can be released only in mtr_commit. */
325
326
void
327
btr_pcur_move_to_next_page(
328
/*=======================*/
329
	btr_pcur_t*	cursor,	/* in: persistent cursor; must be on the
330
				last record of the current page */
331
	mtr_t*		mtr);	/* in: mtr */
332
/*************************************************************
333
Moves the persistent cursor backward if it is on the first record
334
of the page. Releases the latch on the current page, and bufferunfixes
335
it. Note that to prevent a possible deadlock, the operation first
336
stores the position of the cursor, releases the leaf latch, acquires
337
necessary latches and restores the cursor position again before returning.
338
The alphabetical position of the cursor is guaranteed to be sensible
339
on return, but it may happen that the cursor is not positioned on the
340
last record of any page, because the structure of the tree may have
341
changed while the cursor had no latches. */
342
343
void
344
btr_pcur_move_backward_from_page(
345
/*=============================*/
346
	btr_pcur_t*	cursor,	/* in: persistent cursor, must be on the
347
				first record of the current page */
348
	mtr_t*		mtr);	/* in: mtr */
349
/*************************************************************
350
Returns the btr cursor component of a persistent cursor. */
351
UNIV_INLINE
352
btr_cur_t*
353
btr_pcur_get_btr_cur(
354
/*=================*/
355
				/* out: pointer to btr cursor component */
356
	btr_pcur_t*	cursor);	/* in: persistent cursor */
357
/*************************************************************
358
Returns the page cursor component of a persistent cursor. */
359
UNIV_INLINE
360
page_cur_t*
361
btr_pcur_get_page_cur(
362
/*==================*/
363
				/* out: pointer to page cursor component */
364
	btr_pcur_t*	cursor);	/* in: persistent cursor */
365
/*************************************************************
366
Returns the page of a persistent cursor. */
367
UNIV_INLINE
368
page_t*
369
btr_pcur_get_page(
370
/*==============*/
371
				/* out: pointer to the page */
372
	btr_pcur_t*	cursor);/* in: persistent cursor */
373
/*************************************************************
374
Returns the record of a persistent cursor. */
375
UNIV_INLINE
376
rec_t*
377
btr_pcur_get_rec(
378
/*=============*/
379
				/* out: pointer to the record */
380
	btr_pcur_t*	cursor);/* in: persistent cursor */
381
/*************************************************************
382
Checks if the persistent cursor is on a user record. */
383
UNIV_INLINE
384
ibool
385
btr_pcur_is_on_user_rec(
386
/*====================*/
387
	btr_pcur_t*	cursor,	/* in: persistent cursor */
388
	mtr_t*		mtr);	/* in: mtr */
389
/*************************************************************
390
Checks if the persistent cursor is after the last user record on
391
a page. */
392
UNIV_INLINE
393
ibool
394
btr_pcur_is_after_last_on_page(
395
/*===========================*/
396
	btr_pcur_t*	cursor,	/* in: persistent cursor */
397
	mtr_t*		mtr);	/* in: mtr */
398
/*************************************************************
399
Checks if the persistent cursor is before the first user record on
400
a page. */
401
UNIV_INLINE
402
ibool
403
btr_pcur_is_before_first_on_page(
404
/*=============================*/
405
	btr_pcur_t*	cursor,	/* in: persistent cursor */
406
	mtr_t*		mtr);	/* in: mtr */
407
/*************************************************************
408
Checks if the persistent cursor is before the first user record in
409
the index tree. */
410
UNIV_INLINE
411
ibool
412
btr_pcur_is_before_first_in_tree(
413
/*=============================*/
414
	btr_pcur_t*	cursor,	/* in: persistent cursor */
415
	mtr_t*		mtr);	/* in: mtr */
416
/*************************************************************
417
Checks if the persistent cursor is after the last user record in
418
the index tree. */
419
UNIV_INLINE
420
ibool
421
btr_pcur_is_after_last_in_tree(
422
/*===========================*/
423
	btr_pcur_t*	cursor,	/* in: persistent cursor */
424
	mtr_t*		mtr);	/* in: mtr */
425
/*************************************************************
426
Moves the persistent cursor to the next record on the same page. */
427
UNIV_INLINE
428
void
429
btr_pcur_move_to_next_on_page(
430
/*==========================*/
431
	btr_pcur_t*	cursor,	/* in: persistent cursor */
432
	mtr_t*		mtr);	/* in: mtr */
433
/*************************************************************
434
Moves the persistent cursor to the previous record on the same page. */
435
UNIV_INLINE
436
void
437
btr_pcur_move_to_prev_on_page(
438
/*==========================*/
439
	btr_pcur_t*	cursor,	/* in: persistent cursor */
440
	mtr_t*		mtr);	/* in: mtr */
441
442
443
/* The persistent B-tree cursor structure. This is used mainly for SQL
444
selects, updates, and deletes. */
445
446
struct btr_pcur_struct{
447
	btr_cur_t	btr_cur;	/* a B-tree cursor */
448
	ulint		latch_mode;	/* see TODO note below!
449
					BTR_SEARCH_LEAF, BTR_MODIFY_LEAF,
450
					BTR_MODIFY_TREE, or BTR_NO_LATCHES,
451
					depending on the latching state of
452
					the page and tree where the cursor is
453
					positioned; the last value means that
454
					the cursor is not currently positioned:
455
					we say then that the cursor is
456
					detached; it can be restored to
457
					attached if the old position was
458
					stored in old_rec */
459
	ulint		old_stored;	/* BTR_PCUR_OLD_STORED
460
					or BTR_PCUR_OLD_NOT_STORED */
461
	rec_t*		old_rec;	/* if cursor position is stored,
462
					contains an initial segment of the
463
					latest record cursor was positioned
464
					either on, before, or after */
465
	ulint		old_n_fields;	/* number of fields in old_rec */
466
	ulint		rel_pos;	/* BTR_PCUR_ON, BTR_PCUR_BEFORE, or
467
					BTR_PCUR_AFTER, depending on whether
468
					cursor was on, before, or after the
469
					old_rec record */
470
	buf_block_t*	block_when_stored;/* buffer block when the position was
471
					stored; note that if AWE is on, frames
472
					may move */
473
	dulint		modify_clock;	/* the modify clock value of the
474
					buffer block when the cursor position
475
					was stored */
476
	ulint		pos_state;	/* see TODO note below!
477
					BTR_PCUR_IS_POSITIONED,
478
					BTR_PCUR_WAS_POSITIONED,
479
					BTR_PCUR_NOT_POSITIONED */
480
	ulint		search_mode;	/* PAGE_CUR_G, ... */
481
	trx_t*		trx_if_known;	/* the transaction, if we know it;
482
					otherwise this field is not defined;
483
					can ONLY BE USED in error prints in
484
					fatal assertion failures! */
485
	/*-----------------------------*/
486
	/* NOTE that the following fields may possess dynamically allocated
487
	memory which should be freed if not needed anymore! */
488
489
	mtr_t*		mtr;		/* NULL, or this field may contain
490
					a mini-transaction which holds the
491
					latch on the cursor page */
492
	byte*		old_rec_buf;	/* NULL, or a dynamically allocated
493
					buffer for old_rec */
494
	ulint		buf_size;	/* old_rec_buf size if old_rec_buf
495
					is not NULL */
496
};
497
498
#define BTR_PCUR_IS_POSITIONED	1997660512	/* TODO: currently, the state
499
						can be BTR_PCUR_IS_POSITIONED,
500
						though it really should be
501
						BTR_PCUR_WAS_POSITIONED,
502
						because we have no obligation
503
						to commit the cursor with
504
						mtr; similarly latch_mode may
505
						be out of date. This can
506
						lead to problems if btr_pcur
507
						is not used the right way;
508
						all current code should be
509
						ok. */
510
#define BTR_PCUR_WAS_POSITIONED	1187549791
511
#define BTR_PCUR_NOT_POSITIONED 1328997689
512
513
#define BTR_PCUR_OLD_STORED	908467085
514
#define BTR_PCUR_OLD_NOT_STORED	122766467
515
516
#ifndef UNIV_NONINL
517
#include "btr0pcur.ic"
518
#endif
519
520
#endif