~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to plugin/innobase/include/btr0cur.h

  • Committer: Brian Aker
  • Date: 2009-08-18 07:20:29 UTC
  • mfrom: (1117.1.9 merge)
  • Revision ID: brian@gaz-20090818072029-s9ch5lcmltxwidn7
Merge of Brian

Show diffs side-by-side

added added

removed removed

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