MySQL 8.0.31
Source Code Documentation
btr0pcur.h
Go to the documentation of this file.
1/*****************************************************************************
2
3Copyright (c) 1996, 2022, Oracle and/or its affiliates.
4
5This program is free software; you can redistribute it and/or modify it under
6the terms of the GNU General Public License, version 2.0, as published by the
7Free Software Foundation.
8
9This program is also distributed with certain software (including but not
10limited to OpenSSL) that is licensed under separate terms, as designated in a
11particular file or component or in included license documentation. The authors
12of MySQL hereby grant you an additional permission to link the program and
13your derivative works with the separately licensed software that they have
14included with MySQL.
15
16This program is distributed in the hope that it will be useful, but WITHOUT
17ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
18FOR A PARTICULAR PURPOSE. See the GNU General Public License, version 2.0,
19for more details.
20
21You should have received a copy of the GNU General Public License along with
22this program; if not, write to the Free Software Foundation, Inc.,
2351 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
24
25*****************************************************************************/
26
27/** @file include/btr0pcur.h
28 The index tree persistent cursor
29
30 Created 2/23/1996 Heikki Tuuri
31 *******************************************************/
32
33#ifndef btr0pcur_h
34#define btr0pcur_h
35
36#include "btr0btr.h"
37#include "btr0cur.h"
38#include "btr0types.h"
39#include "buf0block_hint.h"
40#include "data0data.h"
41#include "dict0dict.h"
42#include "mtr0mtr.h"
43#include "page0cur.h"
44#include "univ.i"
45#ifndef UNIV_HOTBACKUP
46#include "gis0rtree.h"
47#endif /* UNIV_HOTBACKUP */
48
49/** Relative positions for a stored cursor position */
55 /* Note that if the tree is not empty, btr_pcur::store_position does
56 not use the following, but only uses the above three alternatives,
57 where the position is stored relative to a specific record: this makes
58 implementation of a scroll cursor easier */
59 BTR_PCUR_BEFORE_FIRST_IN_TREE = 4, /* in an empty tree */
60 BTR_PCUR_AFTER_LAST_IN_TREE = 5 /* in an empty tree */
61};
62
63/** Position state of persistent B-tree cursor. */
65
66 /** The persistent cursor is not positioned. */
68
69 /** The persistent cursor was previously positioned.
70 TODO: currently, the state can be BTR_PCUR_IS_POSITIONED,
71 though it really should be BTR_PCUR_WAS_POSITIONED,
72 because we have no obligation to commit the cursor with
73 mtr; similarly latch_mode may be out of date. This can
74 lead to problems if btr_pcur is not used the right way;
75 all current code should be ok. */
77
78 /** The persistent cursor is positioned by optimistic get to the same
79 record as it was positioned at. Not used for rel_pos == BTR_PCUR_ON.
80 It may need adjustment depending on previous/current search direction
81 and rel_pos. */
83
84 /** The persistent cursor is positioned by index search.
85 Or optimistic get for rel_pos == BTR_PCUR_ON. */
87};
88
89/* Import tablespace context for persistent B-tree cursor. */
91 /* true if cursor fails to move to the next page during import. */
92 bool is_error{false};
93};
94
95/* The persistent B-tree cursor structure. This is used mainly for SQL
96selects, updates, and deletes. */
97
98struct btr_pcur_t {
99 /** Sets the old_rec_buf field to nullptr.
100 @param[in] read_level read level where the cursor would be positioned or
101 re-positioned. */
102 void init(size_t read_level = 0);
103
104 /** @return the index of this persistent cursor */
106
107 /** Positions a cursor at a randomly chosen position within a B-tree.
108 @param[in] index Index to position on.
109 @param[in] latch_mode BTR_SEARCH_LEAF, ...
110 @param[in,out] mtr Mini-transaction.
111 @param[in] location Location from where called.
112 @return true if the index is available and we have put the cursor, false
113 if the index is unavailable */
114 bool set_random_position(dict_index_t *index, ulint latch_mode, mtr_t *mtr,
115 ut::Location location);
116
117 /** Opens a persistent cursor at either end of an index.
118 @param[in] from_left True if open to the low end, false
119 if to the high end.
120 @param[in] index Index
121 @param[in] latch_mode Latch mode
122 @param[in] init_pcur Whether to initialize pcur.
123 @param[in] level Level to search for (0=leaf).
124 @param[in,out] mtr Mini-transaction */
125 void open_at_side(bool from_left, dict_index_t *index, ulint latch_mode,
126 bool init_pcur, ulint level, mtr_t *mtr);
127
128 /** Opens a persistent cursor at first leaf page (low end). It will not call
129 init().
130 @param[in] index Index
131 @param[in] latch_mode Latch mode
132 @param[in,out] mtr Mini-transaction */
133 void begin_leaf(dict_index_t *index, ulint latch_mode, mtr_t *mtr) {
134 open_at_side(true, index, latch_mode, false, 0, mtr);
135 }
136
137 /** Opens an persistent cursor to an index tree without initializing
138 the cursor.
139 @param[in] index Index.
140 @param[in] tuple Tuple on which search done.
141 @param[in] mode PAGE_CUR_L, ...;
142 NOTE that if the search is made using a unique
143 prefix of a record, mode should be
144 PAGE_CUR_LE, not PAGE_CUR_GE, as the latter
145 may end up on the previous page of the
146 record!
147 @param[in] latch_mode BTR_SEARCH_LEAF, ...;
148 NOTE that if has_search_latch != 0 then
149 we maybe do not acquire a latch on the cursor
150 page, but assume that the caller uses his
151 btr search latch to protect the record!
152 @param[in] has_search_latch latch mode the caller
153 currently has on search system: RW_S_LATCH, or 0
154 @param[in] mtr Mini-transaction
155 @param[in] location Location where called */
156 void open_no_init(dict_index_t *index, const dtuple_t *tuple,
157 page_cur_mode_t mode, ulint latch_mode,
158 ulint has_search_latch, mtr_t *mtr, ut::Location location);
159
160 /** If mode is PAGE_CUR_G or PAGE_CUR_GE, opens a persistent cursor
161 on the first user record satisfying the search condition, in the case
162 PAGE_CUR_L or PAGE_CUR_LE, on the last user record. If no such user
163 record exists, then in the first case sets the cursor after last in
164 tree, and in the latter case before first in tree. The latching mode
165 must be BTR_SEARCH_LEAF or BTR_MODIFY_LEAF.
166 @param[in] index Index
167 @param[in] tuple Tuple on which search done.
168 @param[in] mode PAGE_CUR_L, ...
169 @param[in] latch_mode BTR_SEARCH_LEAF or BTR_MODIFY_LEAF
170 @param[in] mtr Mini-transaction.
171 @param[in] location Location in file from where called.*/
172 void open_on_user_rec(dict_index_t *index, const dtuple_t *tuple,
173 page_cur_mode_t mode, ulint latch_mode, mtr_t *mtr,
174 ut::Location location);
175
176 /** Allows setting the persistent cursor manually.
177 @param[in] cursor Page cursor where positioned.
178 @param[in] mode PAGE_CUR_L, ...
179 @param[in] latch_mode BTR_SEARCH_LEAF or BTR_MODIFY_LEAF */
181 ulint latch_mode);
182
183 /** Initializes and opens a persistent cursor to an index tree
184 It should be closed with btr_pcur::close.
185 @param[in] index Index.
186 @param[in] level Level in the btree.
187 @param[in] tuple Tuple on which search done.
188 @param[in] mode PAGE_CUR_L, ...; NOTE that if the search
189 is made using a unique prefix of a record, mode should be PAGE_CUR_LE, not
190 PAGE_CUR_GE, as the latter may end up on the previous page from the record!
191 @param[in] latch_mode BTR_SEARCH_LEAF, ...
192 @param[in] mtr Mini-transaction.
193 @param[in] location Location where called. */
194 void open(dict_index_t *index, ulint level, const dtuple_t *tuple,
195 page_cur_mode_t mode, ulint latch_mode, mtr_t *mtr,
196 ut::Location location);
197
198 /** Restores the stored position of a persistent cursor bufferfixing
199 the page and obtaining the specified latches. If the cursor position
200 was saved when the
201 (1) cursor was positioned on a user record: this function restores
202 the position to the last record LESS OR EQUAL to the stored record;
203 (2) cursor was positioned on a page infimum record: restores the
204 position to the last record LESS than the user record which was the
205 successor of the page infimum;
206 (3) cursor was positioned on the page supremum: restores to the first
207 record GREATER than the user record which was the predecessor of the
208 supremum.
209 (4) cursor was positioned before the first or after the last in an
210 empty tree: restores to before first or after the last in the tree.
211 @param[in] latch_mode BTR_SEARCH_LEAF, ...
212 @param[in,out] mtr Mini-transaction
213 @param[in] location Location where called.
214 @return true if the cursor position was stored when it was on a user
215 record and it can be restored on a user record whose ordering
216 fields are identical to the ones of the original user record */
217 bool restore_position(ulint latch_mode, mtr_t *mtr, ut::Location location);
218
219 /** Frees the possible memory heap of a persistent cursor and
220 sets the latch mode of the persistent cursor to BTR_NO_LATCHES.
221 WARNING: this function does not release the latch on the page where the
222 cursor is currently positioned. The latch is acquired by the
223 "move to next/previous" family of functions. Since recursive shared
224 locks are not allowed, you must take care (if using the cursor in
225 S-mode) to manually release the latch by either calling
226 btr_leaf_page_release(pcur.get_block(), pcur.latch_mode, mtr)
227 or by committing the mini-transaction right after btr_pcur::close().
228 A subsequent attempt to crawl the same page in the same mtr would
229 cause an assertion failure. */
230 void close();
231
232 /** Free old_rec_buf. */
235 m_old_rec_buf = nullptr;
236 }
237
238#ifndef UNIV_HOTBACKUP
239
240 /** Gets the rel_pos field for a cursor whose position has been stored.
241 @return BTR_PCUR_ON, ... */
242 ulint get_rel_pos() const;
243
244#endif /* !UNIV_HOTBACKUP */
245
246 /** @return the btree cursor (const version). */
247 const btr_cur_t *get_btr_cur() const;
248
249 /** @return the btree cursor (non const version). */
251
252 /** @return the btree page cursor (non const version). */
254
255 /** @return the btree cursor (const version). */
256 const page_cur_t *get_page_cur() const;
257
258 /** Returns the page of a persistent pcur (non const version).
259 @return pointer to the page */
260 page_t *get_page();
261
262 /** Returns the page of a persistent pcur (const version).
263 @return pointer to the page */
264 const page_t *get_page() const;
265
266 /** Returns the current buffer block (non const version).
267 @return pointer to the block */
269
270 /** Returns the current buffer block (const version).
271 @return pointer to the block */
272 const buf_block_t *get_block() const;
273
274 /** Returns the current record (non const version).
275 @return pointer to the record */
276 rec_t *get_rec();
277
278 /** Returns the current record (const version).
279 @return pointer to the record */
280 const rec_t *get_rec() const;
281
282#ifndef UNIV_HOTBACKUP
283 /** Gets the up_match value for a pcur after a search.
284 @return number of matched fields at the cursor or to the right if
285 search mode was PAGE_CUR_GE, otherwise undefined */
286 ulint get_up_match() const;
287
288 /** Gets the low_match value for a pcur after a search.
289 @return number of matched fields at the cursor or to the right if
290 search mode was PAGE_CUR_LE, otherwise undefined */
291 ulint get_low_match() const;
292
293 /** Checks if the persistent cursor is after the last user record
294 on a page.
295 @return true if after last on page. */
296 bool is_after_last_on_page() const;
297
298 /** Checks if the persistent cursor is before the first user record
299 on a page.
300 @return true if before first on page. */
301 bool is_before_first_on_page() const;
302
303 /** Checks if the persistent cursor is on a user record.
304 @return true if on user record. */
305 bool is_on_user_rec() const;
306
307 /** Checks if the persistent cursor is before the first user record
308 in the index tree.
309 @param[in,out] mtr Mini-transaction.
310 @return true if is before first in tree. */
311 bool is_before_first_in_tree(mtr_t *mtr) const;
312
313 /** Checks if the persistent cursor is after the last user record in
314 the index tree.
315 @param[in,out] mtr Mini-transaction.
316 @return is after last in tree. */
317 bool is_after_last_in_tree(mtr_t *mtr) const;
318
319 /** Moves the persistent cursor to the next record on the same page. */
321
322 /** Moves the persistent cursor to the prev record on the same page. */
324
325 /** Moves the persistent cursor to the last record on the same page.
326 @param[in,out] mtr Mini-transaction. */
327 void move_to_last_on_page(mtr_t *mtr);
328
329 /** Moves the persistent cursor to the next user record in the tree.
330 If no user records are left, the cursor ends up 'after last in tree'.
331 @param[in,out] mtr Mini-transaction.
332 @return DB_SUCCESS or DB_END_OF_INDEX. */
334
335 /** Moves the persistent cursor to the next record in the tree. If no
336 records are left, the cursor stays 'after last in tree'.
337 Note: Function may release the page latch.
338 @param[in,out] mtr Mini-transaction.
339 @return true if the cursor was not after last in tree */
340 bool move_to_next(mtr_t *mtr);
341
342 /** Moves the persistent cursor to the previous record in the tree.
343 If no records are left, the cursor stays 'before first in tree'.
344 Note: Function may release the page latch.
345 @param[in,out] mtr Mini-transaction.
346 @return true if the cursor was not before first in tree */
347 bool move_to_prev(mtr_t *mtr);
348
349 /** Moves the persistent cursor to the first record on the next page.
350 Releases the latch on the current page, and bufferunfixes it.
351 Note that there must not be modifications on the current page, as
352 then the x-latch can be released only in mtr_commit.
353 @param[in,out] mtr Mini-transaction. */
354 void move_to_next_page(mtr_t *mtr);
355
356 /** Commits the mtr and sets the pcur latch mode to BTR_NO_LATCHES,
357 that is, the cursor becomes detached.
358 Function btr_pcur::store_position should be used before calling this,
359 if restoration of cursor is wanted later.
360 @param[in,out] mtr Mini-transaction. */
361 void commit_specify_mtr(mtr_t *mtr);
362
363 /** Moves the persistent cursor to the infimum record on the same page. */
365#endif /* !UNIV_HOTBACKUP */
366
367 /** The position of the cursor is stored by taking an initial segment
368 of the record the cursor is positioned on, before, or after, and
369 copying it to the cursor data structure, or just setting a flag if
370 the cursor id before the first in an EMPTY tree, or after the last
371 in an EMPTY tree. NOTE that the page where the cursor is positioned
372 must not be empty if the index tree is not totally empty!
373 @param[in,out] mtr Mini-transaction. */
374 void store_position(mtr_t *mtr);
375
376 /** @return true if the cursor is positioned. */
377 bool is_positioned() const {
380 }
381
382 /** @return true if the cursor is for a clustered index. */
383 bool is_clustered() const { return (m_btr_cur.index->is_clustered()); }
384
385 /** Resets a persistent cursor object, freeing "::old_rec_buf" if it is
386 allocated and resetting the other members to their initial values. */
387 void reset();
388
389 /** Copies the stored position of a pcur to another pcur.
390 @param[in,out] dst Which will receive the position
391 info.
392 @param[in] src From which the info is copied */
393 static void copy_stored_position(btr_pcur_t *dst, const btr_pcur_t *src);
394
395 /** Allocates memory for a persistent cursor object and initializes
396 the cursor.
397 @return own: persistent cursor */
399 auto pcur = ut::new_withkey<btr_pcur_t>(UT_NEW_THIS_FILE_PSI_KEY);
400
401 pcur->m_btr_cur.index = nullptr;
402
403 pcur->init();
404
405 return (pcur);
406 }
407
408 /** Frees the memory for a persistent cursor object and the cursor itself.
409 @param[in,out] pcur Cursor to free. */
410 static void free_for_mysql(btr_pcur_t *&pcur) {
411 pcur->free_rec_buf();
412
413 ut::delete_(pcur);
414
415 pcur = nullptr;
416 }
417
418 /** Set the cursor access type: Normal or Scan.
419 @param[in] fetch_mode One of Page_fetch::NORMAL or Page_fetch::SCAN.
420 @return the old fetch mode. */
422 ut_ad(fetch_mode == Page_fetch::NORMAL || fetch_mode == Page_fetch::SCAN);
423
424 auto old_fetch_mode = m_btr_cur.m_fetch_mode;
425
426 m_btr_cur.m_fetch_mode = fetch_mode;
427
428 return (old_fetch_mode);
429 }
430
431 private:
432 /** Moves the persistent cursor backward if it is on the first record
433 of the page. Commits mtr. Note that to prevent a possible deadlock, the
434 operation first stores the position of the cursor, commits mtr, acquires
435 the necessary latches and restores the cursor position again before
436 returning. The alphabetical position of the cursor is guaranteed to
437 be sensible on return, but it may happen that the cursor is not
438 positioned on the last record of any page, because the structure
439 of the tree may have changed during the time when the cursor had
440 no latches.
441 @param[in,out] mtr Mini-tranaction. */
443
444 public:
445 /** a B-tree cursor */
447
448 /** see TODO note below!
449 BTR_SEARCH_LEAF, BTR_MODIFY_LEAF, BTR_MODIFY_TREE or BTR_NO_LATCHES,
450 depending on the latching state of the page and tree where the cursor
451 is positioned; BTR_NO_LATCHES means that the cursor is not currently
452 positioned:
453 we say then that the cursor is detached; it can be restored to
454 attached if the old position was stored in old_rec */
456
457 /** true if old_rec is stored */
458 bool m_old_stored{false};
459
460 /** if cursor position is stored, contains an initial segment of the
461 latest record cursor was positioned either on, before or after */
462 rec_t *m_old_rec{nullptr};
463
464 /** number of fields in old_rec */
466
467 /** BTR_PCUR_ON, BTR_PCUR_BEFORE, or BTR_PCUR_AFTER, depending on
468 whether cursor was on, before, or after the old_rec record */
470
471 /** buffer block when the position was stored */
473
474 /** the modify clock value of the buffer block when the cursor position
475 was stored */
476 uint64_t m_modify_clock{0};
477
478 /** position() and restore_position() state. */
480
481 /** PAGE_CUR_G, ... */
483
484 /** the transaction, if we know it; otherwise this field is not defined;
485 can ONLY BE USED in error prints in fatal assertion failures! */
487
488 /* NOTE that the following fields may possess dynamically allocated
489 memory which should be freed if not needed anymore! */
490
491 /** nullptr, or a dynamically allocated buffer for old_rec */
492 byte *m_old_rec_buf{nullptr};
493
494 /** old_rec_buf size if old_rec_buf is not nullptr */
495 size_t m_buf_size{0};
496
497 /** Read level where the cursor would be positioned or re-positioned. */
499
500 /* NOTE that the following field is initialized only during import
501 tablespace, otherwise undefined */
503};
504
505inline void btr_pcur_t::init(size_t read_level) {
507
508 m_old_stored = false;
509 m_old_rec_buf = nullptr;
510 m_old_rec = nullptr;
511 m_btr_cur.rtr_info = nullptr;
512 m_read_level = read_level;
513 import_ctx = nullptr;
515}
516
517inline void btr_pcur_t::open(dict_index_t *index, ulint level,
518 const dtuple_t *tuple, page_cur_mode_t mode,
519 ulint latch_mode, mtr_t *mtr,
520 ut::Location location) {
521 init();
522
525
526 /* Search with the tree cursor */
527
528 auto cur = get_btr_cur();
529
531
532 if (index->table->is_intrinsic()) {
533 ut_ad((latch_mode & BTR_MODIFY_LEAF) || (latch_mode & BTR_SEARCH_LEAF) ||
534 (latch_mode & BTR_MODIFY_TREE));
535
537 index, level, tuple, mode, cur, location.filename, location.line, mtr,
538 (((latch_mode & BTR_MODIFY_LEAF) || (latch_mode & BTR_MODIFY_TREE))
539 ? true
540 : false));
541 } else {
542 btr_cur_search_to_nth_level(index, level, tuple, mode, latch_mode, cur, 0,
543 location.filename, location.line, mtr);
544 }
545
547
548 m_trx_if_known = nullptr;
549}
550
551inline void btr_pcur_t::open_at_side(bool from_left, dict_index_t *index,
552 ulint latch_mode, bool init_pcur,
553 ulint level, mtr_t *mtr) {
555
556 m_search_mode = from_left ? PAGE_CUR_G : PAGE_CUR_L;
557
558 if (init_pcur) {
559 init();
560 }
561
562 if (index->table->is_intrinsic()) {
564 level, UT_LOCATION_HERE, mtr);
565 } else {
566 btr_cur_open_at_index_side(from_left, index, latch_mode, get_btr_cur(),
567 level, UT_LOCATION_HERE, mtr);
568 }
569
571
572 m_old_stored = false;
573
574 m_trx_if_known = nullptr;
575}
576
578 ulint latch_mode, mtr_t *mtr,
579 ut::Location location) {
580 m_latch_mode = latch_mode;
582
583 init();
584
585 auto positioned = btr_cur_open_at_rnd_pos(
586 index, latch_mode, get_btr_cur(), location.filename, location.line, mtr);
587
588 m_old_stored = false;
589
590 m_trx_if_known = nullptr;
591
593
594 return (positioned);
595}
596
597inline void btr_pcur_t::open_no_init(dict_index_t *index, const dtuple_t *tuple,
598 page_cur_mode_t mode, ulint latch_mode,
599 ulint has_search_latch, mtr_t *mtr,
600 ut::Location location) {
602
604
605 /* Search with the tree cursor */
606
607 auto cur = get_btr_cur();
608
609 if (index->table->is_intrinsic()) {
610 ut_ad((latch_mode & BTR_MODIFY_LEAF) || (latch_mode & BTR_SEARCH_LEAF));
611
613 index, m_read_level, tuple, mode, cur, location.filename, location.line,
614 mtr, ((latch_mode & BTR_MODIFY_LEAF) ? true : false));
615 } else {
617 cur, has_search_latch, location.filename,
618 location.line, mtr);
619 }
620
622
623 m_old_stored = false;
624
625 m_trx_if_known = nullptr;
626}
627
628inline const btr_cur_t *btr_pcur_t::get_btr_cur() const { return (&m_btr_cur); }
629
631 return (const_cast<btr_cur_t *>(&m_btr_cur));
632}
633
634#ifdef UNIV_DEBUG
637}
638
641}
642
645
646 return (btr_cur_get_page(get_btr_cur()));
647}
648
649inline const page_t *btr_pcur_t::get_page() const {
651
652 return (btr_cur_get_page(const_cast<btr_pcur_t *>(this)->get_btr_cur()));
653}
654
657
658 return (btr_cur_get_block(get_btr_cur()));
659}
660
661inline const buf_block_t *btr_pcur_t::get_block() const {
663
664 return (btr_cur_get_block(get_btr_cur()));
665}
666
670
671 return (btr_cur_get_rec(get_btr_cur()));
672}
673
674inline const rec_t *btr_pcur_t::get_rec() const {
677
678 return (btr_cur_get_rec(get_btr_cur()));
679}
680#else
681
683
684inline const page_cur_t *btr_pcur_t::get_page_cur() const {
685 return (&m_btr_cur.page_cur);
686}
687
689 return (m_btr_cur.page_cur.block->frame);
690}
691
692inline const page_t *btr_pcur_t::get_page() const {
693 return (m_btr_cur.page_cur.block->frame);
694}
695
697 return (m_btr_cur.page_cur.block);
698}
699
700inline const buf_block_t *btr_pcur_t::get_block() const {
701 return (m_btr_cur.page_cur.block);
702}
703
704inline rec_t *btr_pcur_t::get_rec() { return (m_btr_cur.page_cur.rec); }
705
706inline const rec_t *btr_pcur_t::get_rec() const {
707 return (m_btr_cur.page_cur.rec);
708}
709
710#endif /* UNIV_DEBUG */
711
712#ifndef UNIV_HOTBACKUP
713
715 ut_ad(m_old_rec != nullptr);
719
720 return (m_rel_pos);
721}
722
723inline void btr_pcur_t::close() {
724 free_rec_buf();
725
726 if (m_btr_cur.rtr_info != nullptr) {
728 m_btr_cur.rtr_info = nullptr;
729 }
730
731 m_old_rec = nullptr;
732 m_btr_cur.page_cur.rec = nullptr;
733 m_btr_cur.page_cur.block = nullptr;
734
735 m_old_rec = nullptr;
736 m_old_stored = false;
737
740
741 m_trx_if_known = nullptr;
742}
743
747
748 const auto cur = get_btr_cur();
749
750 ut_ad(cur->up_match != ULINT_UNDEFINED);
751
752 return (cur->up_match);
753}
754
758
759 const auto cur = get_btr_cur();
760
761 ut_ad(cur->low_match != ULINT_UNDEFINED);
762
763 return (cur->low_match);
764}
765
769
771}
772
776
778}
779
780inline bool btr_pcur_t::is_on_user_rec() const {
783
785}
786
790
791 if (btr_page_get_prev(get_page(), mtr) != FIL_NULL) {
792 return (false);
793 }
794
796}
797
801
802 if (btr_page_get_next(get_page(), mtr) != FIL_NULL) {
803 return (false);
804 }
805
807}
808
812
814
815 m_old_stored = false;
816}
817
821
823
824 m_old_stored = false;
825}
826
828 UT_NOT_USED(mtr);
830
832
833 m_old_stored = false;
834}
835
839
840 for (;;) {
841 m_old_stored = false;
842
843 if (is_after_last_on_page()) {
844 if (is_after_last_in_tree(mtr)) {
845 return (DB_END_OF_INDEX);
846 }
847
849 } else {
851 }
852
853 if (is_on_user_rec()) {
854 return (DB_SUCCESS);
855 }
856 }
857}
858
862
863 m_old_stored = false;
864
865 if (is_after_last_on_page()) {
866 if (is_after_last_in_tree(mtr)) {
867 return (false);
868 }
869
871
872 return (true);
873 }
874
876
877 return (true);
878}
879
882
884
885 mtr_commit(mtr);
886
888}
889
892
894
895 m_old_stored = false;
896}
897
898inline void btr_pcur_t::reset() {
899 free_rec_buf();
900
901 m_old_rec_buf = nullptr;
902 m_btr_cur.index = nullptr;
903 m_btr_cur.page_cur.rec = nullptr;
904 m_old_rec = nullptr;
905 m_old_n_fields = 0;
906 m_old_stored = false;
907
910}
911
912#endif /* !UNIV_HOTBACKUP */
913
914#endif /* !btr0pcur_h */
The B-tree.
constexpr ulint BTR_LATCH_MODE_WITHOUT_FLAGS(ulint latch_mode)
Definition: btr0btr.h:130
@ BTR_MODIFY_TREE
Start modifying the entire B-tree.
Definition: btr0btr.h:69
@ BTR_MODIFY_LEAF
(Prepare to) modify a record on a leaf page and X-latch it.
Definition: btr0btr.h:65
@ BTR_NO_LATCHES
Obtain no latches.
Definition: btr0btr.h:67
@ BTR_SEARCH_LEAF
Search a record on a leaf page and S-latch it.
Definition: btr0btr.h:63
ulint BTR_LATCH_MODE_WITHOUT_INTENTION(ulint latch_mode)
Definition: btr0btr.h:138
static page_no_t btr_page_get_prev(const page_t *page, mtr_t *mtr)
Gets the previous index page number.
static page_no_t btr_page_get_next(const page_t *page, mtr_t *mtr)
Gets the next index page number.
void btr_cur_open_at_index_side(bool from_left, dict_index_t *index, ulint latch_mode, btr_cur_t *cursor, ulint level, ut::Location location, mtr_t *mtr)
Opens a cursor at either end of an index.
Definition: btr0cur.cc:1852
bool btr_cur_open_at_rnd_pos(dict_index_t *index, ulint latch_mode, btr_cur_t *cursor, const char *file, ulint line, mtr_t *mtr)
Positions a cursor at a randomly chosen position within a B-tree.
Definition: btr0cur.cc:2255
void btr_cur_search_to_nth_level(dict_index_t *index, ulint level, const dtuple_t *tuple, page_cur_mode_t mode, ulint latch_mode, btr_cur_t *cursor, ulint has_search_latch, const char *file, ulint line, mtr_t *mtr)
Searches an index tree and positions a tree cursor on a given level.
Definition: btr0cur.cc:618
void btr_cur_open_at_index_side_with_no_latch(bool from_left, dict_index_t *index, btr_cur_t *cursor, ulint level, ut::Location location, mtr_t *mtr)
Opens a cursor at either end of an index.
Definition: btr0cur.cc:2169
void btr_cur_search_to_nth_level_with_no_latch(dict_index_t *index, ulint level, const dtuple_t *tuple, page_cur_mode_t mode, btr_cur_t *cursor, const char *file, ulint line, mtr_t *mtr, bool mark_dirty)
Searches an index tree and positions a tree cursor on a given level.
Definition: btr0cur.cc:1717
The index tree cursor.
static rec_t * btr_cur_get_rec(const btr_cur_t *cursor)
Returns the record pointer of a tree cursor.
static page_cur_t * btr_cur_get_page_cur(const btr_cur_t *cursor)
Returns the page cursor component of a tree cursor.
static page_t * btr_cur_get_page(btr_cur_t *cursor)
Returns the page of a tree cursor.
static buf_block_t * btr_cur_get_block(const btr_cur_t *cursor)
Returns the buffer block on which the tree cursor is positioned.
pcur_pos_t
Position state of persistent B-tree cursor.
Definition: btr0pcur.h:64
@ BTR_PCUR_IS_POSITIONED_OPTIMISTIC
The persistent cursor is positioned by optimistic get to the same record as it was positioned at.
Definition: btr0pcur.h:82
@ BTR_PCUR_IS_POSITIONED
The persistent cursor is positioned by index search.
Definition: btr0pcur.h:86
@ BTR_PCUR_NOT_POSITIONED
The persistent cursor is not positioned.
Definition: btr0pcur.h:67
@ BTR_PCUR_WAS_POSITIONED
The persistent cursor was previously positioned.
Definition: btr0pcur.h:76
btr_pcur_pos_t
Relative positions for a stored cursor position.
Definition: btr0pcur.h:50
@ BTR_PCUR_AFTER_LAST_IN_TREE
Definition: btr0pcur.h:60
@ BTR_PCUR_ON
Definition: btr0pcur.h:52
@ BTR_PCUR_BEFORE_FIRST_IN_TREE
Definition: btr0pcur.h:59
@ BTR_PCUR_UNSET
Definition: btr0pcur.h:51
@ BTR_PCUR_AFTER
Definition: btr0pcur.h:54
@ BTR_PCUR_BEFORE
Definition: btr0pcur.h:53
The index tree general types.
Page_fetch
Definition: buf0buf.h:57
@ NORMAL
Get always.
@ SCAN
Same as NORMAL, but hint that the fetch is part of a large scan.
Definition: buf0block_hint.h:31
void clear()
Clears currently stored pointer.
Definition: buf0block_hint.cc:37
SQL data field and tuple.
dberr_t
Definition: db0err.h:38
@ DB_SUCCESS
Definition: db0err.h:42
@ DB_END_OF_INDEX
Definition: db0err.h:214
Data dictionary system.
static ulint dict_index_is_spatial(const dict_index_t *index)
Check whether the index is a Spatial Index.
constexpr page_no_t FIL_NULL
'null' (undefined) page offset in the context of file spaces
Definition: fil0fil.h:1122
R-tree header file.
void rtr_clean_rtr_info(rtr_info_t *rtr_info, bool free_all)
Clean up R-Tree search structure.
Definition: gis0sea.cc:935
Mini-transaction buffer.
#define mtr_commit(m)
Commit a mini-transaction.
Definition: mtr0mtr.h:58
mode
Definition: file_handle.h:59
void delete_(T *ptr) noexcept
Releases storage which has been dynamically allocated through any of the ut::new*() variants.
Definition: ut0new.h:807
void free(void *ptr) noexcept
Releases storage which has been dynamically allocated through any of the ut::malloc*(),...
Definition: ut0new.h:715
The page cursor.
static bool page_cur_is_after_last(const page_cur_t *cur)
Returns true if the cursor is after last user record.
static void page_cur_set_after_last(const buf_block_t *block, page_cur_t *cur)
Sets the cursor object to point after the last user record on the page.
static void page_cur_move_to_prev(page_cur_t *cur)
Moves the cursor to the previous record on page.
static void page_cur_set_before_first(const buf_block_t *block, page_cur_t *cur)
Sets the cursor object to point before the first user record on the page.
static void page_cur_move_to_next(page_cur_t *cur)
Moves the cursor to the next record on page.
static bool page_cur_is_before_first(const page_cur_t *cur)
Returns true if the cursor is before first user record on page.
page_cur_mode_t
Definition: page0types.h:175
@ PAGE_CUR_G
Definition: page0types.h:177
@ PAGE_CUR_UNSUPP
Definition: page0types.h:176
@ PAGE_CUR_L
Definition: page0types.h:179
byte page_t
Type of the index page.
Definition: page0types.h:151
byte rec_t
Definition: rem0types.h:40
The tree cursor: the definition appears here only for the compiler to know struct size!
Definition: btr0cur.h:667
dict_index_t * index
Index on which the cursor is positioned.
Definition: btr0cur.h:669
page_cur_t page_cur
Page cursor.
Definition: btr0cur.h:671
rtr_info_t * rtr_info
rtree search info.
Definition: btr0cur.h:726
Page_fetch m_fetch_mode
If cursor is used in a scan or simple page fetch.
Definition: btr0cur.h:732
Definition: btr0pcur.h:98
bool restore_position(ulint latch_mode, mtr_t *mtr, ut::Location location)
Restores the stored position of a persistent cursor bufferfixing the page and obtaining the specified...
Definition: btr0pcur.cc:146
import_ctx_t * import_ctx
Definition: btr0pcur.h:502
bool move_to_prev(mtr_t *mtr)
Moves the persistent cursor to the previous record in the tree.
Definition: btr0pcur.cc:413
void move_to_prev_on_page()
Moves the persistent cursor to the prev record on the same page.
Definition: btr0pcur.h:818
void open_at_side(bool from_left, dict_index_t *index, ulint latch_mode, bool init_pcur, ulint level, mtr_t *mtr)
Opens a persistent cursor at either end of an index.
Definition: btr0pcur.h:551
void free_rec_buf()
Free old_rec_buf.
Definition: btr0pcur.h:233
bool is_clustered() const
Definition: btr0pcur.h:383
pcur_pos_t m_pos_state
position() and restore_position() state.
Definition: btr0pcur.h:479
bool m_old_stored
true if old_rec is stored
Definition: btr0pcur.h:458
void open_no_init(dict_index_t *index, const dtuple_t *tuple, page_cur_mode_t mode, ulint latch_mode, ulint has_search_latch, mtr_t *mtr, ut::Location location)
Opens an persistent cursor to an index tree without initializing the cursor.
Definition: btr0pcur.h:597
btr_pcur_pos_t m_rel_pos
BTR_PCUR_ON, BTR_PCUR_BEFORE, or BTR_PCUR_AFTER, depending on whether cursor was on,...
Definition: btr0pcur.h:469
static btr_pcur_t * create_for_mysql()
Allocates memory for a persistent cursor object and initializes the cursor.
Definition: btr0pcur.h:398
dict_index_t * index()
Definition: btr0pcur.h:105
bool set_random_position(dict_index_t *index, ulint latch_mode, mtr_t *mtr, ut::Location location)
Positions a cursor at a randomly chosen position within a B-tree.
Definition: btr0pcur.h:577
dberr_t move_to_next_user_rec(mtr_t *mtr)
Moves the persistent cursor to the next user record in the tree.
Definition: btr0pcur.h:836
ulint get_low_match() const
Gets the low_match value for a pcur after a search.
Definition: btr0pcur.h:755
bool is_after_last_on_page() const
Checks if the persistent cursor is after the last user record on a page.
Definition: btr0pcur.h:766
ulint get_rel_pos() const
Gets the rel_pos field for a cursor whose position has been stored.
Definition: btr0pcur.h:714
bool move_to_next(mtr_t *mtr)
Moves the persistent cursor to the next record in the tree.
Definition: btr0pcur.h:859
buf_block_t * get_block()
Returns the current buffer block (non const version).
Definition: btr0pcur.h:655
bool is_positioned() const
Definition: btr0pcur.h:377
ulint m_latch_mode
see TODO note below! BTR_SEARCH_LEAF, BTR_MODIFY_LEAF, BTR_MODIFY_TREE or BTR_NO_LATCHES,...
Definition: btr0pcur.h:455
page_cur_mode_t m_search_mode
PAGE_CUR_G, ...
Definition: btr0pcur.h:482
static void copy_stored_position(btr_pcur_t *dst, const btr_pcur_t *src)
Copies the stored position of a pcur to another pcur.
Definition: btr0pcur.cc:115
void open_on_user_rec(dict_index_t *index, const dtuple_t *tuple, page_cur_mode_t mode, ulint latch_mode, mtr_t *mtr, ut::Location location)
If mode is PAGE_CUR_G or PAGE_CUR_GE, opens a persistent cursor on the first user record satisfying t...
Definition: btr0pcur.cc:434
static void free_for_mysql(btr_pcur_t *&pcur)
Frees the memory for a persistent cursor object and the cursor itself.
Definition: btr0pcur.h:410
void begin_leaf(dict_index_t *index, ulint latch_mode, mtr_t *mtr)
Opens a persistent cursor at first leaf page (low end).
Definition: btr0pcur.h:133
void move_to_next_page(mtr_t *mtr)
Moves the persistent cursor to the first record on the next page.
Definition: btr0pcur.cc:295
uint64_t m_modify_clock
the modify clock value of the buffer block when the cursor position was stored
Definition: btr0pcur.h:476
size_t m_buf_size
old_rec_buf size if old_rec_buf is not nullptr
Definition: btr0pcur.h:495
void move_to_next_on_page()
Moves the persistent cursor to the next record on the same page.
Definition: btr0pcur.h:809
void close()
Frees the possible memory heap of a persistent cursor and sets the latch mode of the persistent curso...
Definition: btr0pcur.h:723
void commit_specify_mtr(mtr_t *mtr)
Commits the mtr and sets the pcur latch mode to BTR_NO_LATCHES, that is, the cursor becomes detached.
Definition: btr0pcur.h:880
void move_to_last_on_page(mtr_t *mtr)
Moves the persistent cursor to the last record on the same page.
Definition: btr0pcur.h:827
Page_fetch set_fetch_type(Page_fetch fetch_mode)
Set the cursor access type: Normal or Scan.
Definition: btr0pcur.h:421
void move_backward_from_page(mtr_t *mtr)
Moves the persistent cursor backward if it is on the first record of the page.
Definition: btr0pcur.cc:355
void init(size_t read_level=0)
Sets the old_rec_buf field to nullptr.
Definition: btr0pcur.h:505
ulint m_old_n_fields
number of fields in old_rec
Definition: btr0pcur.h:465
void move_before_first_on_page()
Moves the persistent cursor to the infimum record on the same page.
Definition: btr0pcur.h:890
ulint get_up_match() const
Gets the up_match value for a pcur after a search.
Definition: btr0pcur.h:744
bool is_before_first_on_page() const
Checks if the persistent cursor is before the first user record on a page.
Definition: btr0pcur.h:773
bool is_before_first_in_tree(mtr_t *mtr) const
Checks if the persistent cursor is before the first user record in the index tree.
Definition: btr0pcur.h:787
page_t * get_page()
Returns the page of a persistent pcur (non const version).
Definition: btr0pcur.h:643
void open(dict_index_t *index, ulint level, const dtuple_t *tuple, page_cur_mode_t mode, ulint latch_mode, mtr_t *mtr, ut::Location location)
Initializes and opens a persistent cursor to an index tree It should be closed with btr_pcur::close.
Definition: btr0pcur.h:517
page_cur_t * get_page_cur()
Definition: btr0pcur.h:635
bool is_on_user_rec() const
Checks if the persistent cursor is on a user record.
Definition: btr0pcur.h:780
const btr_cur_t * get_btr_cur() const
Definition: btr0pcur.h:628
trx_t * m_trx_if_known
the transaction, if we know it; otherwise this field is not defined; can ONLY BE USED in error prints...
Definition: btr0pcur.h:486
void reset()
Resets a persistent cursor object, freeing "::old_rec_buf" if it is allocated and resetting the other...
Definition: btr0pcur.h:898
rec_t * m_old_rec
if cursor position is stored, contains an initial segment of the latest record cursor was positioned ...
Definition: btr0pcur.h:462
btr_cur_t m_btr_cur
a B-tree cursor
Definition: btr0pcur.h:446
void store_position(mtr_t *mtr)
The position of the cursor is stored by taking an initial segment of the record the cursor is positio...
Definition: btr0pcur.cc:41
ulint m_read_level
Read level where the cursor would be positioned or re-positioned.
Definition: btr0pcur.h:498
buf::Block_hint m_block_when_stored
buffer block when the position was stored
Definition: btr0pcur.h:472
byte * m_old_rec_buf
nullptr, or a dynamically allocated buffer for old_rec
Definition: btr0pcur.h:492
bool is_after_last_in_tree(mtr_t *mtr) const
Checks if the persistent cursor is after the last user record in the index tree.
Definition: btr0pcur.h:798
rec_t * get_rec()
Returns the current record (non const version).
Definition: btr0pcur.h:667
The buffer control block structure.
Definition: buf0buf.h:1664
byte * frame
pointer to buffer frame which is of size UNIV_PAGE_SIZE, and aligned to an address divisible by UNIV_...
Definition: buf0buf.h:1680
Data structure for an index.
Definition: dict0mem.h:1021
bool is_clustered() const
Definition: dict0mem.h:1286
dict_table_t * table
back pointer to table
Definition: dict0mem.h:1035
bool is_intrinsic() const
Determine whether the table is intrinsic.
Definition: dict0mem.h:2667
Structure for an SQL data tuple of fields (logical record)
Definition: data0data.h:681
Definition: btr0pcur.h:90
bool is_error
Definition: btr0pcur.h:92
Mini-transaction handle and buffer.
Definition: mtr0mtr.h:181
Index page cursor.
Definition: page0cur.h:310
buf_block_t * block
Pointer to the current block containing rec.
Definition: page0cur.h:321
rec_t * rec
pointer to a record on page
Definition: page0cur.h:315
Definition: trx0trx.h:680
Definition: ut0core.h:32
const char * filename
Definition: ut0core.h:33
size_t line
Definition: ut0core.h:34
Version control for database, common definitions, and include files.
unsigned long int ulint
Definition: univ.i:407
constexpr ulint ULINT_UNDEFINED
The 'undefined' value for a ulint.
Definition: univ.i:421
#define UT_LOCATION_HERE
Definition: ut0core.h:46
#define ut_ad(EXPR)
Debug assertion.
Definition: ut0dbg.h:68
#define UT_NOT_USED(A)
Silence warnings about an unused variable by doing a null assignment.
Definition: ut0dbg.h:105
#define UT_NEW_THIS_FILE_PSI_KEY
Definition: ut0new.h:562