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