~ubuntu-43/undrop-for-innodb/pierre

« back to all changes in this revision

Viewing changes to include/btr0cur.h

  • Committer: root
  • Date: 2014-06-22 09:59:20 UTC
  • Revision ID: root@twindb-dev-20140622095920-0atlkgy80imht7hj
daily commit

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/******************************************************
 
2
The index tree cursor
 
3
 
 
4
(c) 1994-1996 Innobase Oy
 
5
 
 
6
Created 10/16/1994 Heikki Tuuri
 
7
*******************************************************/
 
8
 
 
9
#ifndef btr0cur_h
 
10
#define btr0cur_h
 
11
 
 
12
#include "univ.i"
 
13
#include "dict0dict.h"
 
14
#include "data0data.h"
 
15
#include "page0cur.h"
 
16
#include "btr0types.h"
 
17
#include "que0types.h"
 
18
#include "row0types.h"
 
19
#include "ha0ha.h"
 
20
 
 
21
/* Mode flags for btr_cur operations; these can be ORed */
 
22
#define BTR_NO_UNDO_LOG_FLAG    1       /* do no undo logging */
 
23
#define BTR_NO_LOCKING_FLAG     2       /* do no record lock checking */
 
24
#define BTR_KEEP_SYS_FLAG       4       /* sys fields will be found from the
 
25
                                        update vector or inserted entry */
 
26
 
 
27
#define BTR_CUR_ADAPT
 
28
#define BTR_CUR_HASH_ADAPT
 
29
 
 
30
/*************************************************************
 
31
Returns the page cursor component of a tree cursor. */
 
32
UNIV_INLINE
 
33
page_cur_t*
 
34
btr_cur_get_page_cur(
 
35
/*=================*/
 
36
                                /* out: pointer to page cursor component */
 
37
        btr_cur_t*      cursor);/* in: tree cursor */
 
38
/*************************************************************
 
39
Returns the record pointer of a tree cursor. */
 
40
UNIV_INLINE
 
41
rec_t*
 
42
btr_cur_get_rec(
 
43
/*============*/
 
44
                                /* out: pointer to record */
 
45
        btr_cur_t*      cursor);/* in: tree cursor */
 
46
/*************************************************************
 
47
Invalidates a tree cursor by setting record pointer to NULL. */
 
48
UNIV_INLINE
 
49
void
 
50
btr_cur_invalidate(
 
51
/*===============*/
 
52
        btr_cur_t*      cursor);/* in: tree cursor */
 
53
/*************************************************************
 
54
Returns the page of a tree cursor. */
 
55
UNIV_INLINE
 
56
page_t*
 
57
btr_cur_get_page(
 
58
/*=============*/
 
59
                                /* out: pointer to page */
 
60
        btr_cur_t*      cursor);/* in: tree cursor */
 
61
/*************************************************************
 
62
Returns the tree of a cursor. */
 
63
UNIV_INLINE
 
64
dict_tree_t*
 
65
btr_cur_get_tree(
 
66
/*=============*/
 
67
                                /* out: tree */
 
68
        btr_cur_t*      cursor);/* in: tree cursor */
 
69
/*************************************************************
 
70
Positions a tree cursor at a given record. */
 
71
UNIV_INLINE
 
72
void
 
73
btr_cur_position(
 
74
/*=============*/
 
75
        dict_index_t*   index,  /* in: index */
 
76
        rec_t*          rec,    /* in: record in tree */
 
77
        btr_cur_t*      cursor);/* in: cursor */
 
78
/************************************************************************
 
79
Searches an index tree and positions a tree cursor on a given level.
 
80
NOTE: n_fields_cmp in tuple must be set so that it cannot be compared
 
81
to node pointer page number fields on the upper levels of the tree!
 
82
Note that if mode is PAGE_CUR_LE, which is used in inserts, then
 
83
cursor->up_match and cursor->low_match both will have sensible values.
 
84
If mode is PAGE_CUR_GE, then up_match will a have a sensible value. */
 
85
 
 
86
void
 
87
btr_cur_search_to_nth_level(
 
88
/*========================*/
 
89
        dict_index_t*   index,  /* in: index */
 
90
        ulint           level,  /* in: the tree level of search */
 
91
        dtuple_t*       tuple,  /* in: data tuple; NOTE: n_fields_cmp in
 
92
                                tuple must be set so that it cannot get
 
93
                                compared to the node ptr page number field! */
 
94
        ulint           mode,   /* in: PAGE_CUR_L, ...;
 
95
                                NOTE that if the search is made using a unique
 
96
                                prefix of a record, mode should be PAGE_CUR_LE,
 
97
                                not PAGE_CUR_GE, as the latter may end up on
 
98
                                the previous page of the record! Inserts
 
99
                                should always be made using PAGE_CUR_LE to
 
100
                                search the position! */
 
101
        ulint           latch_mode, /* in: BTR_SEARCH_LEAF, ..., ORed with
 
102
                                BTR_INSERT and BTR_ESTIMATE;
 
103
                                cursor->left_page is used to store a pointer
 
104
                                to the left neighbor page, in the cases
 
105
                                BTR_SEARCH_PREV and BTR_MODIFY_PREV;
 
106
                                NOTE that if has_search_latch
 
107
                                is != 0, we maybe do not have a latch set
 
108
                                on the cursor page, we assume
 
109
                                the caller uses his search latch
 
110
                                to protect the record! */
 
111
        btr_cur_t*      cursor, /* in/out: tree cursor; the cursor page is
 
112
                                s- or x-latched, but see also above! */
 
113
        ulint           has_search_latch,/* in: latch mode the caller
 
114
                                currently has on btr_search_latch:
 
115
                                RW_S_LATCH, or 0 */
 
116
        mtr_t*          mtr);   /* in: mtr */
 
117
/*********************************************************************
 
118
Opens a cursor at either end of an index. */
 
119
 
 
120
void
 
121
btr_cur_open_at_index_side(
 
122
/*=======================*/
 
123
        ibool           from_left,      /* in: TRUE if open to the low end,
 
124
                                        FALSE if to the high end */
 
125
        dict_index_t*   index,          /* in: index */
 
126
        ulint           latch_mode,     /* in: latch mode */
 
127
        btr_cur_t*      cursor,         /* in: cursor */
 
128
        mtr_t*          mtr);           /* in: mtr */
 
129
/**************************************************************************
 
130
Positions a cursor at a randomly chosen position within a B-tree. */
 
131
 
 
132
void
 
133
btr_cur_open_at_rnd_pos(
 
134
/*====================*/
 
135
        dict_index_t*   index,          /* in: index */
 
136
        ulint           latch_mode,     /* in: BTR_SEARCH_LEAF, ... */
 
137
        btr_cur_t*      cursor,         /* in/out: B-tree cursor */
 
138
        mtr_t*          mtr);           /* in: mtr */
 
139
/*****************************************************************
 
140
Tries to perform an insert to a page in an index tree, next to cursor.
 
141
It is assumed that mtr holds an x-latch on the page. The operation does
 
142
not succeed if there is too little space on the page. If there is just
 
143
one record on the page, the insert will always succeed; this is to
 
144
prevent trying to split a page with just one record. */
 
145
 
 
146
ulint
 
147
btr_cur_optimistic_insert(
 
148
/*======================*/
 
149
                                /* out: DB_SUCCESS, DB_WAIT_LOCK,
 
150
                                DB_FAIL, or error number */
 
151
        ulint           flags,  /* in: undo logging and locking flags: if not
 
152
                                zero, the parameters index and thr should be
 
153
                                specified */
 
154
        btr_cur_t*      cursor, /* in: cursor on page after which to insert;
 
155
                                cursor stays valid */
 
156
        dtuple_t*       entry,  /* in: entry to insert */
 
157
        rec_t**         rec,    /* out: pointer to inserted record if
 
158
                                succeed */
 
159
        big_rec_t**     big_rec,/* out: big rec vector whose fields have to
 
160
                                be stored externally by the caller, or
 
161
                                NULL */
 
162
        que_thr_t*      thr,    /* in: query thread or NULL */
 
163
        mtr_t*          mtr);   /* in: mtr */
 
164
/*****************************************************************
 
165
Performs an insert on a page of an index tree. It is assumed that mtr
 
166
holds an x-latch on the tree and on the cursor page. If the insert is
 
167
made on the leaf level, to avoid deadlocks, mtr must also own x-latches
 
168
to brothers of page, if those brothers exist. */
 
169
 
 
170
ulint
 
171
btr_cur_pessimistic_insert(
 
172
/*=======================*/
 
173
                                /* out: DB_SUCCESS or error number */
 
174
        ulint           flags,  /* in: undo logging and locking flags: if not
 
175
                                zero, the parameter thr should be
 
176
                                specified; if no undo logging is specified,
 
177
                                then the caller must have reserved enough
 
178
                                free extents in the file space so that the
 
179
                                insertion will certainly succeed */
 
180
        btr_cur_t*      cursor, /* in: cursor after which to insert;
 
181
                                cursor stays valid */
 
182
        dtuple_t*       entry,  /* in: entry to insert */
 
183
        rec_t**         rec,    /* out: pointer to inserted record if
 
184
                                succeed */
 
185
        big_rec_t**     big_rec,/* out: big rec vector whose fields have to
 
186
                                be stored externally by the caller, or
 
187
                                NULL */
 
188
        que_thr_t*      thr,    /* in: query thread or NULL */
 
189
        mtr_t*          mtr);   /* in: mtr */
 
190
/*****************************************************************
 
191
Updates a record when the update causes no size changes in its fields. */
 
192
 
 
193
ulint
 
194
btr_cur_update_in_place(
 
195
/*====================*/
 
196
                                /* out: DB_SUCCESS or error number */
 
197
        ulint           flags,  /* in: undo logging and locking flags */
 
198
        btr_cur_t*      cursor, /* in: cursor on the record to update;
 
199
                                cursor stays valid and positioned on the
 
200
                                same record */
 
201
        upd_t*          update, /* in: update vector */
 
202
        ulint           cmpl_info,/* in: compiler info on secondary index
 
203
                                updates */
 
204
        que_thr_t*      thr,    /* in: query thread */
 
205
        mtr_t*          mtr);   /* in: mtr */
 
206
/*****************************************************************
 
207
Tries to update a record on a page in an index tree. It is assumed that mtr
 
208
holds an x-latch on the page. The operation does not succeed if there is too
 
209
little space on the page or if the update would result in too empty a page,
 
210
so that tree compression is recommended. */
 
211
 
 
212
ulint
 
213
btr_cur_optimistic_update(
 
214
/*======================*/
 
215
                                /* out: DB_SUCCESS, or DB_OVERFLOW if the
 
216
                                updated record does not fit, DB_UNDERFLOW
 
217
                                if the page would become too empty */
 
218
        ulint           flags,  /* in: undo logging and locking flags */
 
219
        btr_cur_t*      cursor, /* in: cursor on the record to update;
 
220
                                cursor stays valid and positioned on the
 
221
                                same record */
 
222
        upd_t*          update, /* in: update vector; this must also
 
223
                                contain trx id and roll ptr fields */
 
224
        ulint           cmpl_info,/* in: compiler info on secondary index
 
225
                                updates */
 
226
        que_thr_t*      thr,    /* in: query thread */
 
227
        mtr_t*          mtr);   /* in: mtr */
 
228
/*****************************************************************
 
229
Performs an update of a record on a page of a tree. It is assumed
 
230
that mtr holds an x-latch on the tree and on the cursor page. If the
 
231
update is made on the leaf level, to avoid deadlocks, mtr must also
 
232
own x-latches to brothers of page, if those brothers exist. */
 
233
 
 
234
ulint
 
235
btr_cur_pessimistic_update(
 
236
/*=======================*/
 
237
                                /* out: DB_SUCCESS or error code */
 
238
        ulint           flags,  /* in: undo logging, locking, and rollback
 
239
                                flags */
 
240
        btr_cur_t*      cursor, /* in: cursor on the record to update */
 
241
        big_rec_t**     big_rec,/* out: big rec vector whose fields have to
 
242
                                be stored externally by the caller, or NULL */
 
243
        upd_t*          update, /* in: update vector; this is allowed also
 
244
                                contain trx id and roll ptr fields, but
 
245
                                the values in update vector have no effect */
 
246
        ulint           cmpl_info,/* in: compiler info on secondary index
 
247
                                updates */
 
248
        que_thr_t*      thr,    /* in: query thread */
 
249
        mtr_t*          mtr);   /* in: mtr */
 
250
/***************************************************************
 
251
Marks a clustered index record deleted. Writes an undo log record to
 
252
undo log on this delete marking. Writes in the trx id field the id
 
253
of the deleting transaction, and in the roll ptr field pointer to the
 
254
undo log record created. */
 
255
 
 
256
ulint
 
257
btr_cur_del_mark_set_clust_rec(
 
258
/*===========================*/
 
259
                                /* out: DB_SUCCESS, DB_LOCK_WAIT, or error
 
260
                                number */
 
261
        ulint           flags,  /* in: undo logging and locking flags */
 
262
        btr_cur_t*      cursor, /* in: cursor */
 
263
        ibool           val,    /* in: value to set */
 
264
        que_thr_t*      thr,    /* in: query thread */
 
265
        mtr_t*          mtr);   /* in: mtr */
 
266
/***************************************************************
 
267
Sets a secondary index record delete mark to TRUE or FALSE. */
 
268
 
 
269
ulint
 
270
btr_cur_del_mark_set_sec_rec(
 
271
/*=========================*/
 
272
                                /* out: DB_SUCCESS, DB_LOCK_WAIT, or error
 
273
                                number */
 
274
        ulint           flags,  /* in: locking flag */
 
275
        btr_cur_t*      cursor, /* in: cursor */
 
276
        ibool           val,    /* in: value to set */
 
277
        que_thr_t*      thr,    /* in: query thread */
 
278
        mtr_t*          mtr);   /* in: mtr */
 
279
/***************************************************************
 
280
Sets a secondary index record delete mark to FALSE. This function is
 
281
only used by the insert buffer insert merge mechanism. */
 
282
 
 
283
void
 
284
btr_cur_del_unmark_for_ibuf(
 
285
/*========================*/
 
286
        rec_t*          rec,    /* in: record to delete unmark */
 
287
        mtr_t*          mtr);   /* in: mtr */
 
288
/*****************************************************************
 
289
Tries to compress a page of the tree on the leaf level. It is assumed
 
290
that mtr holds an x-latch on the tree and on the cursor page. To avoid
 
291
deadlocks, mtr must also own x-latches to brothers of page, if those
 
292
brothers exist. NOTE: it is assumed that the caller has reserved enough
 
293
free extents so that the compression will always succeed if done! */
 
294
 
 
295
void
 
296
btr_cur_compress(
 
297
/*=============*/
 
298
        btr_cur_t*      cursor, /* in: cursor on the page to compress;
 
299
                                cursor does not stay valid */
 
300
        mtr_t*          mtr);   /* in: mtr */
 
301
/*****************************************************************
 
302
Tries to compress a page of the tree if it seems useful. It is assumed
 
303
that mtr holds an x-latch on the tree and on the cursor page. To avoid
 
304
deadlocks, mtr must also own x-latches to brothers of page, if those
 
305
brothers exist. NOTE: it is assumed that the caller has reserved enough
 
306
free extents so that the compression will always succeed if done! */
 
307
 
 
308
ibool
 
309
btr_cur_compress_if_useful(
 
310
/*=======================*/
 
311
                                /* out: TRUE if compression occurred */
 
312
        btr_cur_t*      cursor, /* in: cursor on the page to compress;
 
313
                                cursor does not stay valid if compression
 
314
                                occurs */
 
315
        mtr_t*          mtr);   /* in: mtr */
 
316
/***********************************************************
 
317
Removes the record on which the tree cursor is positioned. It is assumed
 
318
that the mtr has an x-latch on the page where the cursor is positioned,
 
319
but no latch on the whole tree. */
 
320
 
 
321
ibool
 
322
btr_cur_optimistic_delete(
 
323
/*======================*/
 
324
                                /* out: TRUE if success, i.e., the page
 
325
                                did not become too empty */
 
326
        btr_cur_t*      cursor, /* in: cursor on the record to delete;
 
327
                                cursor stays valid: if deletion succeeds,
 
328
                                on function exit it points to the successor
 
329
                                of the deleted record */
 
330
        mtr_t*          mtr);   /* in: mtr */
 
331
/*****************************************************************
 
332
Removes the record on which the tree cursor is positioned. Tries
 
333
to compress the page if its fillfactor drops below a threshold
 
334
or if it is the only page on the level. It is assumed that mtr holds
 
335
an x-latch on the tree and on the cursor page. To avoid deadlocks,
 
336
mtr must also own x-latches to brothers of page, if those brothers
 
337
exist. */
 
338
 
 
339
ibool
 
340
btr_cur_pessimistic_delete(
 
341
/*=======================*/
 
342
                                /* out: TRUE if compression occurred */
 
343
        ulint*          err,    /* out: DB_SUCCESS or DB_OUT_OF_FILE_SPACE;
 
344
                                the latter may occur because we may have
 
345
                                to update node pointers on upper levels,
 
346
                                and in the case of variable length keys
 
347
                                these may actually grow in size */
 
348
        ibool           has_reserved_extents, /* in: TRUE if the
 
349
                                caller has already reserved enough free
 
350
                                extents so that he knows that the operation
 
351
                                will succeed */
 
352
        btr_cur_t*      cursor, /* in: cursor on the record to delete;
 
353
                                if compression does not occur, the cursor
 
354
                                stays valid: it points to successor of
 
355
                                deleted record on function exit */
 
356
        ibool           in_rollback,/* in: TRUE if called in rollback */
 
357
        mtr_t*          mtr);   /* in: mtr */
 
358
/***************************************************************
 
359
Parses a redo log record of updating a record in-place. */
 
360
 
 
361
byte*
 
362
btr_cur_parse_update_in_place(
 
363
/*==========================*/
 
364
                                /* out: end of log record or NULL */
 
365
        byte*           ptr,    /* in: buffer */
 
366
        byte*           end_ptr,/* in: buffer end */
 
367
        page_t*         page,   /* in: page or NULL */
 
368
        dict_index_t*   index); /* in: index corresponding to page */
 
369
/********************************************************************
 
370
Parses the redo log record for delete marking or unmarking of a clustered
 
371
index record. */
 
372
 
 
373
byte*
 
374
btr_cur_parse_del_mark_set_clust_rec(
 
375
/*=================================*/
 
376
                                /* out: end of log record or NULL */
 
377
        byte*           ptr,    /* in: buffer */
 
378
        byte*           end_ptr,/* in: buffer end */
 
379
        dict_index_t*   index,  /* in: index corresponding to page */
 
380
        page_t*         page);  /* in: page or NULL */
 
381
/********************************************************************
 
382
Parses the redo log record for delete marking or unmarking of a secondary
 
383
index record. */
 
384
 
 
385
byte*
 
386
btr_cur_parse_del_mark_set_sec_rec(
 
387
/*===============================*/
 
388
                                /* out: end of log record or NULL */
 
389
        byte*           ptr,    /* in: buffer */
 
390
        byte*           end_ptr,/* in: buffer end */
 
391
        page_t*         page);  /* in: page or NULL */
 
392
/***********************************************************************
 
393
Estimates the number of rows in a given index range. */
 
394
 
 
395
ib_longlong
 
396
btr_estimate_n_rows_in_range(
 
397
/*=========================*/
 
398
                                /* out: estimated number of rows */
 
399
        dict_index_t*   index,  /* in: index */
 
400
        dtuple_t*       tuple1, /* in: range start, may also be empty tuple */
 
401
        ulint           mode1,  /* in: search mode for range start */
 
402
        dtuple_t*       tuple2, /* in: range end, may also be empty tuple */
 
403
        ulint           mode2); /* in: search mode for range end */
 
404
/***********************************************************************
 
405
Estimates the number of different key values in a given index, for
 
406
each n-column prefix of the index where n <= dict_index_get_n_unique(index).
 
407
The estimates are stored in the array index->stat_n_diff_key_vals. */
 
408
 
 
409
void
 
410
btr_estimate_number_of_different_key_vals(
 
411
/*======================================*/
 
412
        dict_index_t*   index); /* in: index */
 
413
/***********************************************************************
 
414
Marks not updated extern fields as not-owned by this record. The ownership
 
415
is transferred to the updated record which is inserted elsewhere in the
 
416
index tree. In purge only the owner of externally stored field is allowed
 
417
to free the field. */
 
418
 
 
419
void
 
420
btr_cur_mark_extern_inherited_fields(
 
421
/*=================================*/
 
422
        rec_t*          rec,    /* in: record in a clustered index */
 
423
        const ulint*    offsets,/* in: array returned by rec_get_offsets() */
 
424
        upd_t*          update, /* in: update vector */
 
425
        mtr_t*          mtr);   /* in: mtr */
 
426
/***********************************************************************
 
427
The complement of the previous function: in an update entry may inherit
 
428
some externally stored fields from a record. We must mark them as inherited
 
429
in entry, so that they are not freed in a rollback. */
 
430
 
 
431
void
 
432
btr_cur_mark_dtuple_inherited_extern(
 
433
/*=================================*/
 
434
        dtuple_t*       entry,          /* in: updated entry to be inserted to
 
435
                                        clustered index */
 
436
        ulint*          ext_vec,        /* in: array of extern fields in the
 
437
                                        original record */
 
438
        ulint           n_ext_vec,      /* in: number of elements in ext_vec */
 
439
        upd_t*          update);        /* in: update vector */
 
440
/***********************************************************************
 
441
Marks all extern fields in a dtuple as owned by the record. */
 
442
 
 
443
void
 
444
btr_cur_unmark_dtuple_extern_fields(
 
445
/*================================*/
 
446
        dtuple_t*       entry,          /* in: clustered index entry */
 
447
        ulint*          ext_vec,        /* in: array of numbers of fields
 
448
                                        which have been stored externally */
 
449
        ulint           n_ext_vec);     /* in: number of elements in ext_vec */
 
450
/***********************************************************************
 
451
Stores the fields in big_rec_vec to the tablespace and puts pointers to
 
452
them in rec. The fields are stored on pages allocated from leaf node
 
453
file segment of the index tree. */
 
454
 
 
455
ulint
 
456
btr_store_big_rec_extern_fields(
 
457
/*============================*/
 
458
                                        /* out: DB_SUCCESS or error */
 
459
        dict_index_t*   index,          /* in: index of rec; the index tree
 
460
                                        MUST be X-latched */
 
461
        rec_t*          rec,            /* in: record */
 
462
        const ulint*    offsets,        /* in: rec_get_offsets(rec, index);
 
463
                                        the "external storage" flags in offsets
 
464
                                        will not correspond to rec when
 
465
                                        this function returns */
 
466
        big_rec_t*      big_rec_vec,    /* in: vector containing fields
 
467
                                        to be stored externally */
 
468
        mtr_t*          local_mtr);     /* in: mtr containing the latch to
 
469
                                        rec and to the tree */
 
470
/***********************************************************************
 
471
Frees the space in an externally stored field to the file space
 
472
management if the field in data is owned the externally stored field,
 
473
in a rollback we may have the additional condition that the field must
 
474
not be inherited. */
 
475
 
 
476
void
 
477
btr_free_externally_stored_field(
 
478
/*=============================*/
 
479
        dict_index_t*   index,          /* in: index of the data, the index
 
480
                                        tree MUST be X-latched; if the tree
 
481
                                        height is 1, then also the root page
 
482
                                        must be X-latched! (this is relevant
 
483
                                        in the case this function is called
 
484
                                        from purge where 'data' is located on
 
485
                                        an undo log page, not an index
 
486
                                        page) */
 
487
        byte*           data,           /* in: internally stored data
 
488
                                        + reference to the externally
 
489
                                        stored part */
 
490
        ulint           local_len,      /* in: length of data */
 
491
        ibool           do_not_free_inherited,/* in: TRUE if called in a
 
492
                                        rollback and we do not want to free
 
493
                                        inherited fields */
 
494
        mtr_t*          local_mtr);     /* in: mtr containing the latch to
 
495
                                        data an an X-latch to the index
 
496
                                        tree */
 
497
/***************************************************************
 
498
Frees the externally stored fields for a record. */
 
499
 
 
500
void
 
501
btr_rec_free_externally_stored_fields(
 
502
/*==================================*/
 
503
        dict_index_t*   index,  /* in: index of the data, the index
 
504
                                tree MUST be X-latched */
 
505
        rec_t*          rec,    /* in: record */
 
506
        const ulint*    offsets,/* in: rec_get_offsets(rec, index) */
 
507
        ibool           do_not_free_inherited,/* in: TRUE if called in a
 
508
                                rollback and we do not want to free
 
509
                                inherited fields */
 
510
        mtr_t*          mtr);   /* in: mini-transaction handle which contains
 
511
                                an X-latch to record page and to the index
 
512
                                tree */
 
513
/***********************************************************************
 
514
Copies an externally stored field of a record to mem heap. */
 
515
 
 
516
byte*
 
517
btr_rec_copy_externally_stored_field(
 
518
/*=================================*/
 
519
                                /* out: the field copied to heap */
 
520
        rec_t*          rec,    /* in: record */
 
521
        const ulint*    offsets,/* in: array returned by rec_get_offsets() */
 
522
        ulint           no,     /* in: field number */
 
523
        ulint*          len,    /* out: length of the field */
 
524
        mem_heap_t*     heap);  /* in: mem heap */
 
525
/***********************************************************************
 
526
Copies an externally stored field of a record to mem heap. Parameter
 
527
data contains a pointer to 'internally' stored part of the field:
 
528
possibly some data, and the reference to the externally stored part in
 
529
the last 20 bytes of data. */
 
530
 
 
531
byte*
 
532
btr_copy_externally_stored_field(
 
533
/*=============================*/
 
534
                                /* out: the whole field copied to heap */
 
535
        ulint*          len,    /* out: length of the whole field */
 
536
        byte*           data,   /* in: 'internally' stored part of the
 
537
                                field containing also the reference to
 
538
                                the external part */
 
539
        ulint           local_len,/* in: length of data */
 
540
        mem_heap_t*     heap);  /* in: mem heap */
 
541
/***********************************************************************
 
542
Stores the positions of the fields marked as extern storage in the update
 
543
vector, and also those fields who are marked as extern storage in rec
 
544
and not mentioned in updated fields. We use this function to remember
 
545
which fields we must mark as extern storage in a record inserted for an
 
546
update. */
 
547
 
 
548
ulint
 
549
btr_push_update_extern_fields(
 
550
/*==========================*/
 
551
                                /* out: number of values stored in ext_vect */
 
552
        ulint*          ext_vect,/* in: array of ulints, must be preallocated
 
553
                                to have space for all fields in rec */
 
554
        const ulint*    offsets,/* in: array returned by rec_get_offsets() */
 
555
        upd_t*          update);/* in: update vector or NULL */
 
556
        
 
557
 
 
558
/*######################################################################*/
 
559
 
 
560
/* In the pessimistic delete, if the page data size drops below this
 
561
limit, merging it to a neighbor is tried */
 
562
 
 
563
#define BTR_CUR_PAGE_COMPRESS_LIMIT     (UNIV_PAGE_SIZE / 2)
 
564
 
 
565
/* A slot in the path array. We store here info on a search path down the
 
566
tree. Each slot contains data on a single level of the tree. */
 
567
 
 
568
typedef struct btr_path_struct  btr_path_t;
 
569
struct btr_path_struct{
 
570
        ulint   nth_rec;        /* index of the record
 
571
                                where the page cursor stopped on
 
572
                                this level (index in alphabetical
 
573
                                order); value ULINT_UNDEFINED
 
574
                                denotes array end */
 
575
        ulint   n_recs;         /* number of records on the page */
 
576
};
 
577
 
 
578
#define BTR_PATH_ARRAY_N_SLOTS  250     /* size of path array (in slots) */
 
579
 
 
580
/* The tree cursor: the definition appears here only for the compiler
 
581
to know struct size! */
 
582
 
 
583
struct btr_cur_struct {
 
584
        dict_index_t*   index;          /* index where positioned */
 
585
        page_cur_t      page_cur;       /* page cursor */
 
586
        page_t*         left_page;      /* this field is used to store a pointer
 
587
                                        to the left neighbor page, in the cases
 
588
                                        BTR_SEARCH_PREV and BTR_MODIFY_PREV */
 
589
        /*------------------------------*/
 
590
        que_thr_t*      thr;            /* this field is only used when
 
591
                                        btr_cur_search_... is called for an
 
592
                                        index entry insertion: the calling
 
593
                                        query thread is passed here to be
 
594
                                        used in the insert buffer */
 
595
        /*------------------------------*/
 
596
        /* The following fields are used in btr_cur_search... to pass
 
597
        information: */
 
598
        ulint           flag;           /* BTR_CUR_HASH, BTR_CUR_HASH_FAIL,
 
599
                                        BTR_CUR_BINARY, or
 
600
                                        BTR_CUR_INSERT_TO_IBUF */
 
601
        ulint           tree_height;    /* Tree height if the search is done
 
602
                                        for a pessimistic insert or update
 
603
                                        operation */
 
604
        ulint           up_match;       /* If the search mode was PAGE_CUR_LE,
 
605
                                        the number of matched fields to the
 
606
                                        the first user record to the right of
 
607
                                        the cursor record after
 
608
                                        btr_cur_search_...;
 
609
                                        for the mode PAGE_CUR_GE, the matched
 
610
                                        fields to the first user record AT THE
 
611
                                        CURSOR or to the right of it;
 
612
                                        NOTE that the up_match and low_match
 
613
                                        values may exceed the correct values
 
614
                                        for comparison to the adjacent user
 
615
                                        record if that record is on a
 
616
                                        different leaf page! (See the note in
 
617
                                        row_ins_duplicate_key.) */
 
618
        ulint           up_bytes;       /* number of matched bytes to the
 
619
                                        right at the time cursor positioned;
 
620
                                        only used internally in searches: not
 
621
                                        defined after the search */
 
622
        ulint           low_match;      /* if search mode was PAGE_CUR_LE,
 
623
                                        the number of matched fields to the
 
624
                                        first user record AT THE CURSOR or
 
625
                                        to the left of it after
 
626
                                        btr_cur_search_...;
 
627
                                        NOT defined for PAGE_CUR_GE or any
 
628
                                        other search modes; see also the NOTE
 
629
                                        in up_match! */
 
630
        ulint           low_bytes;      /* number of matched bytes to the
 
631
                                        right at the time cursor positioned;
 
632
                                        only used internally in searches: not
 
633
                                        defined after the search */
 
634
        ulint           n_fields;       /* prefix length used in a hash
 
635
                                        search if hash_node != NULL */
 
636
        ulint           n_bytes;        /* hash prefix bytes if hash_node !=
 
637
                                        NULL */
 
638
        ulint           fold;           /* fold value used in the search if
 
639
                                        flag is BTR_CUR_HASH */
 
640
        /*------------------------------*/
 
641
        btr_path_t*     path_arr;       /* in estimating the number of
 
642
                                        rows in range, we store in this array
 
643
                                        information of the path through
 
644
                                        the tree */
 
645
};
 
646
 
 
647
/* Values for the flag documenting the used search method */
 
648
#define BTR_CUR_HASH            1       /* successful shortcut using the hash
 
649
                                        index */
 
650
#define BTR_CUR_HASH_FAIL       2       /* failure using hash, success using
 
651
                                        binary search: the misleading hash
 
652
                                        reference is stored in the field
 
653
                                        hash_node, and might be necessary to
 
654
                                        update */
 
655
#define BTR_CUR_BINARY          3       /* success using the binary search */
 
656
#define BTR_CUR_INSERT_TO_IBUF  4       /* performed the intended insert to
 
657
                                        the insert buffer */
 
658
 
 
659
/* If pessimistic delete fails because of lack of file space,
 
660
there is still a good change of success a little later: try this many times,
 
661
and sleep this many microseconds in between */
 
662
#define BTR_CUR_RETRY_DELETE_N_TIMES    100
 
663
#define BTR_CUR_RETRY_SLEEP_TIME        50000
 
664
 
 
665
/* The reference in a field for which data is stored on a different page.
 
666
The reference is at the end of the 'locally' stored part of the field.
 
667
'Locally' means storage in the index record.
 
668
We store locally a long enough prefix of each column so that we can determine
 
669
the ordering parts of each index record without looking into the externally
 
670
stored part. */
 
671
 
 
672
/*--------------------------------------*/
 
673
#define BTR_EXTERN_SPACE_ID             0       /* space id where stored */
 
674
#define BTR_EXTERN_PAGE_NO              4       /* page no where stored */
 
675
#define BTR_EXTERN_OFFSET               8       /* offset of BLOB header
 
676
                                                on that page */
 
677
#define BTR_EXTERN_LEN                  12      /* 8 bytes containing the
 
678
                                                length of the externally
 
679
                                                stored part of the BLOB.
 
680
                                                The 2 highest bits are
 
681
                                                reserved to the flags below. */
 
682
/*--------------------------------------*/
 
683
#define BTR_EXTERN_FIELD_REF_SIZE       20
 
684
 
 
685
/* The highest bit of BTR_EXTERN_LEN (i.e., the highest bit of the byte
 
686
at lowest address) is set to 1 if this field does not 'own' the externally
 
687
stored field; only the owner field is allowed to free the field in purge!
 
688
If the 2nd highest bit is 1 then it means that the externally stored field
 
689
was inherited from an earlier version of the row. In rollback we are not
 
690
allowed to free an inherited external field. */
 
691
 
 
692
#define BTR_EXTERN_OWNER_FLAG           128
 
693
#define BTR_EXTERN_INHERITED_FLAG       64
 
694
 
 
695
extern ulint    btr_cur_n_non_sea;
 
696
extern ulint    btr_cur_n_sea;
 
697
extern ulint    btr_cur_n_non_sea_old;
 
698
extern ulint    btr_cur_n_sea_old;
 
699
 
 
700
#ifndef UNIV_NONINL
 
701
#include "btr0cur.ic"
 
702
#endif
 
703
                                
 
704
#endif