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