~drizzle-trunk/drizzle/development

« back to all changes in this revision

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

  • Committer: Brian Aker
  • Date: 2009-04-27 14:36:40 UTC
  • Revision ID: brian@gaz-20090427143640-f6zjmtt9vm55qgm2
Patch on show processlist from  davi@apache.org

Show diffs side-by-side

added added

removed removed

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