MySQL  8.0.22
Source Code Documentation
btr0pcur.h
Go to the documentation of this file.
1 /*****************************************************************************
2 
3 Copyright (c) 1996, 2020, Oracle and/or its affiliates. All Rights Reserved.
4 
5 This program is free software; you can redistribute it and/or modify it under
6 the terms of the GNU General Public License, version 2.0, as published by the
7 Free Software Foundation.
8 
9 This program is also distributed with certain software (including but not
10 limited to OpenSSL) that is licensed under separate terms, as designated in a
11 particular file or component or in included license documentation. The authors
12 of MySQL hereby grant you an additional permission to link the program and
13 your derivative works with the separately licensed software that they have
14 included with MySQL.
15 
16 This program is distributed in the hope that it will be useful, but WITHOUT
17 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
18 FOR A PARTICULAR PURPOSE. See the GNU General Public License, version 2.0,
19 for more details.
20 
21 You should have received a copy of the GNU General Public License along with
22 this program; if not, write to the Free Software Foundation, Inc.,
23 51 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 #define btr_pcur_create_for_mysql() btr_pcur_t::create_for_mysql()
64 #define btr_pcur_free_for_mysql(p) btr_pcur_t::free_for_mysql(p)
65 
66 #define btr_pcur_reset(p) (p)->reset();
67 
68 #define btr_pcur_copy_stored_position(d, s) \
69  btr_pcur_t::copy_stored_position(d, s)
70 
71 #define btr_pcur_free(p) (p)->free_rec_buf()
72 
73 #define btr_pcur_open(i, t, md, l, p, m) \
74  (p)->open((i), 0, (t), (md), (l), m, __FILE__, __LINE__)
75 
76 #define btr_pcur_init(p) (p)->init()
77 #define btr_pcur_close(p) (p)->close()
78 
79 #define btr_pcur_open_at_rnd_pos(i, l, p, m) \
80  (p)->set_random_position((i), (l), (m), __FILE__, __LINE__)
81 
82 #define btr_pcur_open_low(i, lv, md, lm, p, f, ln, mr) \
83  (p)->open((i), (lv), (t), (md), (lm), (mr), (f), (l))
84 
85 #define btr_pcur_open_at_index_side(e, i, lm, p, ip, lv, m) \
86  (p)->open_at_side((e), (i), (lm), (ip), (lv), (m))
87 
88 #define btr_pcur_open_on_user_rec(i, t, md, l, p, m) \
89  (p)->open_on_user_rec((i), (t), (md), (l), (m), __FILE__, __LINE__)
90 
91 #define btr_pcur_open_with_no_init(i, t, md, l, p, has, m) \
92  (p)->open_no_init((i), (t), (md), (l), (has), (m), __FILE__, __LINE__)
93 
94 #define btr_pcur_restore_position(l, p, mtr) \
95  (p)->restore_position(l, mtr, __FILE__, __LINE__)
96 
97 #define btr_pcur_store_position(p, m) (p)->store_position(m)
98 
99 #define btr_pcur_get_rel_pos(p) (p)->get_rel_pos()
100 
101 #define btr_pcur_commit_specify_mtr(p, m) (p)->commit_specify_mtr(m)
102 
103 #define btr_pcur_move_to_next(p, m) (p)->move_to_next(m)
104 #define btr_pcur_move_to_prev(p, m) (p)->move_to_prev(m)
105 
106 #define btr_pcur_move_to_last_on_page(p, m) (p)->move_to_last_on_page(m)
107 
108 #define btr_pcur_move_to_next_user_rec(p, m) \
109  ((p)->move_to_next_user_rec(m) == DB_SUCCESS)
110 
111 #define btr_pcur_move_to_next_page(p, m) (p)->move_to_next_page(m)
112 
113 #define btr_pcur_get_btr_cur(p) (p)->get_btr_cur()
114 
115 #define btr_pcur_get_page_cur(p) (p)->get_page_cur()
116 
117 #define btr_pcur_get_page(p) (p)->get_page()
118 
119 #define btr_pcur_get_block(p) (p)->get_block()
120 
121 #define btr_pcur_get_rec(p) (p)->get_rec()
122 
123 #define btr_pcur_is_on_user_rec(p) (p)->is_on_user_rec()
124 
125 #define btr_pcur_is_after_last_on_page(p) (p)->is_after_last_on_page()
126 
127 #define btr_pcur_is_before_first_on_page(p) (p)->is_before_first_on_page()
128 
129 #define btr_pcur_is_before_first_in_tree(p, m) (p)->is_before_first_in_tree(m)
130 
131 #define btr_pcur_is_after_last_in_tree(p, m) (p)->is_after_last_in_tree(m)
132 
133 #define btr_pcur_move_to_next_on_page(p) (p)->move_to_next_on_page()
134 
135 #define btr_pcur_move_to_prev_on_page(p) (p)->move_to_prev_on_page()
136 
137 #define btr_pcur_move_before_first_on_page(p) (p)->move_before_first_on_page()
138 
139 #define btr_pcur_get_low_match(p) (p)->get_low_match()
140 
141 #define btr_pcur_get_up_match(p) (p)->get_up_match()
142 
143 /** Position state of persistent B-tree cursor. */
145 
146  /** The persistent cursor is not positioned. */
148 
149  /** The persistent cursor was previously positioned.
150  TODO: currently, the state can be BTR_PCUR_IS_POSITIONED,
151  though it really should be BTR_PCUR_WAS_POSITIONED,
152  because we have no obligation to commit the cursor with
153  mtr; similarly latch_mode may be out of date. This can
154  lead to problems if btr_pcur is not used the right way;
155  all current code should be ok. */
157 
158  /** The persistent cursor is positioned by optimistic get to the same
159  record as it was positioned at. Not used for rel_pos == BTR_PCUR_ON.
160  It may need adjustment depending on previous/current search direction
161  and rel_pos. */
163 
164  /** The persistent cursor is positioned by index search.
165  Or optimistic get for rel_pos == BTR_PCUR_ON. */
167 };
168 
169 /* Import tablespace context for persistent B-tree cursor. */
170 struct import_ctx_t {
171  /* true if cursor fails to move to the next page during import. */
172  bool is_error{false};
173 };
174 
175 /* The persistent B-tree cursor structure. This is used mainly for SQL
176 selects, updates, and deletes. */
177 
178 struct btr_pcur_t {
179  /** Sets the old_rec_buf field to nullptr.
180  @param[in] read_level read level where the cursor would be positioned or
181  re-positioned. */
182  void init(size_t read_level = 0);
183 
184  /** @return the index of this persistent cursor */
185  dict_index_t *index() { return (m_btr_cur.index); }
186 
187  /** Positions a cursor at a randomly chosen position within a B-tree.
188  @param[in] index Index to position on.
189  @param[in] latch_mode BTR_SEARCH_LEAF, ...
190  @param[in,out] mtr Mini-transaction.
191  @param[in] file File name from where called.
192  @param[in] line Line number within filename
193  @return true if the index is available and we have put the cursor, false
194  if the index is unavailable */
195  bool set_random_position(dict_index_t *index, ulint latch_mode, mtr_t *mtr,
196  const char *file, ulint line);
197 
198  /** Opens a persistent cursor at either end of an index.
199  @param[in] from_left True if open to the low end, false
200  if to the high end.
201  @param[in] index Index
202  @param[in] latch_mode Latch mode
203  @param[in] init_pcur Whether to initialize pcur.
204  @param[in] level Level to search for (0=leaf).
205  @param[in,out] mtr Mini-transaction */
206  void open_at_side(bool from_left, dict_index_t *index, ulint latch_mode,
207  bool init_pcur, ulint level, mtr_t *mtr);
208 
209  /** Opens a persistent cursor at first leaf page (low end). It will not call
210  init().
211  @param[in] index Index
212  @param[in] latch_mode Latch mode
213  @param[in,out] mtr Mini-transaction */
214  void begin_leaf(dict_index_t *index, ulint latch_mode, mtr_t *mtr) {
215  open_at_side(true, index, latch_mode, false, 0, mtr);
216  }
217 
218  /** Opens an persistent cursor to an index tree without initializing
219  the cursor.
220  @param[in] index Index.
221  @param[in] tuple Tuple on which search done.
222  @param[in] mode PAGE_CUR_L, ...;
223  NOTE that if the search is made using a unique
224  prefix of a record, mode should be
225  PAGE_CUR_LE, not PAGE_CUR_GE, as the latter
226  may end up on the previous page of the
227  record!
228  @param[in] latch_mode BTR_SEARCH_LEAF, ...;
229  NOTE that if has_search_latch != 0 then
230  we maybe do not acquire a latch on the cursor
231  page, but assume that the caller uses his
232  btr search latch to protect the record!
233  @param[in] has_search_latch latch mode the caller
234  currently has on search system: RW_S_LATCH, or 0
235  @param[in] mtr Mini-transaction
236  @param[in] file File name.
237  @param[in] line Line where called */
238  void open_no_init(dict_index_t *index, const dtuple_t *tuple,
239  page_cur_mode_t mode, ulint latch_mode,
240  ulint has_search_latch, mtr_t *mtr, const char *file,
241  ulint line);
242 
243  /** If mode is PAGE_CUR_G or PAGE_CUR_GE, opens a persistent cursor
244  on the first user record satisfying the search condition, in the case
245  PAGE_CUR_L or PAGE_CUR_LE, on the last user record. If no such user
246  record exists, then in the first case sets the cursor after last in
247  tree, and in the latter case before first in tree. The latching mode
248  must be BTR_SEARCH_LEAF or BTR_MODIFY_LEAF.
249  @param[in] index Index
250  @param[in] tuple Tuple on which search done.
251  @param[in] mode PAGE_CUR_L, ...
252  @param[in] latch_mode BTR_SEARCH_LEAF or BTR_MODIFY_LEAF
253  @param[in] mtr Mini-transaction.
254  @param[in] file File name from where called.
255  @param[in] line Line number in file from where
256  called.*/
257  void open_on_user_rec(dict_index_t *index, const dtuple_t *tuple,
258  page_cur_mode_t mode, ulint latch_mode, mtr_t *mtr,
259  const char *file, ulint line);
260 
261  /** Allows setting the persistent cursor manually.
262  @param[in] cursor Page cursor where positioned.
263  @param[in] mode PAGE_CUR_L, ...
264  @param[in] latch_mode BTR_SEARCH_LEAF or BTR_MODIFY_LEAF */
265  void open_on_user_rec(const page_cur_t &cursor, page_cur_mode_t mode,
266  ulint latch_mode);
267 
268  /** Initializes and opens a persistent cursor to an index tree
269  It should be closed with close().
270  @param[in] index Index.
271  @param[in] level Level in the btree.
272  @param[in] tuple Tuple on which search done.
273  @param[in] mode PAGE_CUR_L, ...;
274  NOTE that if the search is made using
275  a unique prefix of a record, mode
276  should be PAGE_CUR_LE, not PAGE_CUR_GE,
277  as the latter may end up on the
278  previous page from the record!
279  @param[in] latch_mode BTR_SEARCH_LEAF, ...
280  @param[in] mtr Mini-transaction.
281  @param[in] file File name
282  @param[in] line Line in file, from where called. */
283  void open(dict_index_t *index, ulint level, const dtuple_t *tuple,
284  page_cur_mode_t mode, ulint latch_mode, mtr_t *mtr,
285  const char *file, ulint line);
286 
287  /** Restores the stored position of a persistent cursor bufferfixing
288  the page and obtaining the specified latches. If the cursor position
289  was saved when the
290  (1) cursor was positioned on a user record: this function restores
291  the position to the last record LESS OR EQUAL to the stored record;
292  (2) cursor was positioned on a page infimum record: restores the
293  position to the last record LESS than the user record which was the
294  successor of the page infimum;
295  (3) cursor was positioned on the page supremum: restores to the first
296  record GREATER than the user record which was the predecessor of the
297  supremum.
298  (4) cursor was positioned before the first or after the last in an
299  empty tree: restores to before first or after the last in the tree.
300  @param[in] latch_mode BTR_SEARCH_LEAF, ...
301  @param[in,out] mtr Mini-transaction
302  @param[in] file File name.
303  @param[in] line Line where called.
304  @return true if the cursor position was stored when it was on a user
305  record and it can be restored on a user record whose ordering
306  fields are identical to the ones of the original user record */
307  bool restore_position(ulint latch_mode, mtr_t *mtr, const char *file,
308  ulint line);
309 
310  /** Frees the possible memory heap of a persistent cursor and
311  sets the latch mode of the persistent cursor to BTR_NO_LATCHES.
312  WARNING: this function does not release the latch on the page where the
313  cursor is currently positioned. The latch is acquired by the
314  "move to next/previous" family of functions. Since recursive shared
315  locks are not allowed, you must take care (if using the cursor in
316  S-mode) to manually release the latch by either calling
317  btr_leaf_page_release(btr_pcur_get_block(&pcur), pcur.latch_mode, mtr)
318  or by committing the mini-transaction right after btr_pcur_close().
319  A subsequent attempt to crawl the same page in the same mtr would
320  cause an assertion failure. */
321  void close();
322 
323  /** Free old_rec_buf. */
324  void free_rec_buf() {
325  ut_free(m_old_rec_buf);
326  m_old_rec_buf = nullptr;
327  }
328 
329 #ifndef UNIV_HOTBACKUP
330 
331  /** Gets the rel_pos field for a cursor whose position has been stored.
332  @return BTR_PCUR_ON, ... */
333  ulint get_rel_pos() const;
334 
335 #endif /* !UNIV_HOTBACKUP */
336 
337  /** @return the btree cursor (const version). */
338  const btr_cur_t *get_btr_cur() const;
339 
340  /** @return the btree cursor (non const version). */
341  btr_cur_t *get_btr_cur();
342 
343  /** @return the btree page cursor (non const version). */
344  page_cur_t *get_page_cur();
345 
346  /** @return the btree cursor (const version). */
347  const page_cur_t *get_page_cur() const;
348 
349  /** Returns the page of a persistent pcur (non const version).
350  @return pointer to the page */
351  page_t *get_page();
352 
353  /** Returns the page of a persistent pcur (const version).
354  @return pointer to the page */
355  const page_t *get_page() const;
356 
357  /** Returns the current buffer block (non const version).
358  @return pointer to the block */
359  buf_block_t *get_block();
360 
361  /** Returns the current buffer block (const version).
362  @return pointer to the block */
363  const buf_block_t *get_block() const;
364 
365  /** Returns the current record (non const version).
366  @return pointer to the record */
367  rec_t *get_rec();
368 
369  /** Returns the current record (const version).
370  @return pointer to the record */
371  const rec_t *get_rec() const;
372 
373 #ifndef UNIV_HOTBACKUP
374  /** Gets the up_match value for a pcur after a search.
375  @return number of matched fields at the cursor or to the right if
376  search mode was PAGE_CUR_GE, otherwise undefined */
377  ulint get_up_match() const;
378 
379  /** Gets the low_match value for a pcur after a search.
380  @return number of matched fields at the cursor or to the right if
381  search mode was PAGE_CUR_LE, otherwise undefined */
382  ulint get_low_match() const;
383 
384  /** Checks if the persistent cursor is after the last user record
385  on a page.
386  @return true if after last on page. */
387  bool is_after_last_on_page() const;
388 
389  /** Checks if the persistent cursor is before the first user record
390  on a page.
391  @return true if before first on page. */
392  bool is_before_first_on_page() const;
393 
394  /** Checks if the persistent cursor is on a user record.
395  @return true if on user record. */
396  bool is_on_user_rec() const;
397 
398  /** Checks if the persistent cursor is before the first user record
399  in the index tree.
400  @param[in,out] mtr Mini-transaction.
401  @return true if is before first in tree. */
402  bool is_before_first_in_tree(mtr_t *mtr) const;
403 
404  /** Checks if the persistent cursor is after the last user record in
405  the index tree.
406  @param[in,out] mtr Mini-transaction.
407  @return is after last in tree. */
408  bool is_after_last_in_tree(mtr_t *mtr) const;
409 
410  /** Moves the persistent cursor to the next record on the same page. */
411  void move_to_next_on_page();
412 
413  /** Moves the persistent cursor to the prev record on the same page. */
414  void move_to_prev_on_page();
415 
416  /** Moves the persistent cursor to the last record on the same page.
417  @param[in,out] mtr Mini-transaction. */
418  void move_to_last_on_page(mtr_t *mtr);
419 
420  /** Moves the persistent cursor to the next user record in the tree.
421  If no user records are left, the cursor ends up 'after last in tree'.
422  @param[in,out] mtr Mini-transaction.
423  @return DB_SUCCESS or DB_END_OF_INDEX. */
424  dberr_t move_to_next_user_rec(mtr_t *mtr);
425 
426  /** Moves the persistent cursor to the next record in the tree. If no
427  records are left, the cursor stays 'after last in tree'.
428  Note: Function may release the page latch.
429  @param[in,out] mtr Mini-transaction.
430  @return true if the cursor was not after last in tree */
431  bool move_to_next(mtr_t *mtr);
432 
433  /** Moves the persistent cursor to the previous record in the tree.
434  If no records are left, the cursor stays 'before first in tree'.
435  Note: Function may release the page latch.
436  @param[in,out] mtr Mini-transaction.
437  @return true if the cursor was not before first in tree */
438  bool move_to_prev(mtr_t *mtr);
439 
440  /** Moves the persistent cursor to the first record on the next page.
441  Releases the latch on the current page, and bufferunfixes it.
442  Note that there must not be modifications on the current page, as
443  then the x-latch can be released only in mtr_commit.
444  @param[in,out] mtr Mini-transaction. */
445  void move_to_next_page(mtr_t *mtr);
446 
447  /** Commits the mtr and sets the pcur latch mode to BTR_NO_LATCHES,
448  that is, the cursor becomes detached.
449  Function btr_pcur_store_position should be used before calling this,
450  if restoration of cursor is wanted later.
451  @param[in,out] mtr Mini-transaction. */
452  void commit_specify_mtr(mtr_t *mtr);
453 
454  /** Moves the persistent cursor to the infimum record on the same page. */
455  void move_before_first_on_page();
456 #endif /* !UNIV_HOTBACKUP */
457 
458  /** The position of the cursor is stored by taking an initial segment
459  of the record the cursor is positioned on, before, or after, and
460  copying it to the cursor data structure, or just setting a flag if
461  the cursor id before the first in an EMPTY tree, or after the last
462  in an EMPTY tree. NOTE that the page where the cursor is positioned
463  must not be empty if the index tree is not totally empty!
464  @param[in,out] mtr Mini-transaction. */
465  void store_position(mtr_t *mtr);
466 
467  /** @return true if the cursor is positioned. */
468  bool is_positioned() const {
469  return (m_old_stored && (m_pos_state == BTR_PCUR_IS_POSITIONED ||
470  m_pos_state == BTR_PCUR_WAS_POSITIONED));
471  }
472 
473  /** @return true if the cursor is for a clustered index. */
474  bool is_clustered() const { return (m_btr_cur.index->is_clustered()); }
475 
476  /** Resets a persistent cursor object, freeing "::old_rec_buf" if it is
477  allocated and resetting the other members to their initial values. */
478  void reset();
479 
480  /** Copies the stored position of a pcur to another pcur.
481  @param[in,out] dst Which will receive the position
482  info.
483  @param[in] src From which the info is copied */
484  static void copy_stored_position(btr_pcur_t *dst, const btr_pcur_t *src);
485 
486  /** Allocates memory for a persistent cursor object and initializes
487  the cursor.
488  @return own: persistent cursor */
490  auto pcur = UT_NEW_NOKEY(btr_pcur_t());
491 
492  pcur->m_btr_cur.index = nullptr;
493 
494  pcur->init();
495 
496  return (pcur);
497  }
498 
499  /** Frees the memory for a persistent cursor object and the cursor itself.
500  @param[in,out] pcur Cursor to free. */
501  static void free_for_mysql(btr_pcur_t *&pcur) {
502  pcur->free_rec_buf();
503 
504  UT_DELETE(pcur);
505 
506  pcur = nullptr;
507  }
508 
509  /** Set the cursor access type: Normal or Scan.
510  @param[in] fetch_mode One of Page_fetch::NORMAL or Page_fetch::SCAN.
511  @return the old fetch mode. */
513  ut_ad(fetch_mode == Page_fetch::NORMAL || fetch_mode == Page_fetch::SCAN);
514 
515  auto old_fetch_mode = m_btr_cur.m_fetch_mode;
516 
517  m_btr_cur.m_fetch_mode = fetch_mode;
518 
519  return (old_fetch_mode);
520  }
521 
522  private:
523  /** Moves the persistent cursor backward if it is on the first record
524  of the page. Commits mtr. Note that to prevent a possible deadlock, the
525  operation first stores the position of the cursor, commits mtr, acquires
526  the necessary latches and restores the cursor position again before
527  returning. The alphabetical position of the cursor is guaranteed to
528  be sensible on return, but it may happen that the cursor is not
529  positioned on the last record of any page, because the structure
530  of the tree may have changed during the time when the cursor had
531  no latches.
532  @param[in,out] mtr Mini-tranaction. */
533  void move_backward_from_page(mtr_t *mtr);
534 
535  public:
536  /** a B-tree cursor */
538 
539  /** see TODO note below!
540  BTR_SEARCH_LEAF, BTR_MODIFY_LEAF, BTR_MODIFY_TREE or BTR_NO_LATCHES,
541  depending on the latching state of the page and tree where the cursor
542  is positioned; BTR_NO_LATCHES means that the cursor is not currently
543  positioned:
544  we say then that the cursor is detached; it can be restored to
545  attached if the old position was stored in old_rec */
546  ulint m_latch_mode{0};
547 
548  /** true if old_rec is stored */
549  bool m_old_stored{false};
550 
551  /** if cursor position is stored, contains an initial segment of the
552  latest record cursor was positioned either on, before or after */
553  rec_t *m_old_rec{nullptr};
554 
555  /** number of fields in old_rec */
556  ulint m_old_n_fields{0};
557 
558  /** BTR_PCUR_ON, BTR_PCUR_BEFORE, or BTR_PCUR_AFTER, depending on
559  whether cursor was on, before, or after the old_rec record */
561 
562  /** buffer block when the position was stored */
564 
565  /** the modify clock value of the buffer block when the cursor position
566  was stored */
567  uint64_t m_modify_clock{0};
568 
569  /** position() and restore_position() state. */
571 
572  /** PAGE_CUR_G, ... */
574 
575  /** the transaction, if we know it; otherwise this field is not defined;
576  can ONLY BE USED in error prints in fatal assertion failures! */
577  trx_t *m_trx_if_known{nullptr};
578 
579  /* NOTE that the following fields may possess dynamically allocated
580  memory which should be freed if not needed anymore! */
581 
582  /** nullptr, or a dynamically allocated buffer for old_rec */
583  byte *m_old_rec_buf{nullptr};
584 
585  /** old_rec_buf size if old_rec_buf is not nullptr */
586  size_t m_buf_size{0};
587 
588  /** Read level where the cursor would be positioned or re-positioned. */
589  ulint m_read_level{0};
590 
591  /* NOTE that the following field is initialized only during import
592  tablespace, otherwise undefined */
593  import_ctx_t *import_ctx{nullptr};
594 };
595 
596 inline void btr_pcur_t::init(size_t read_level) {
597  set_fetch_type(Page_fetch::NORMAL);
598 
599  m_old_stored = false;
600  m_old_rec_buf = nullptr;
601  m_old_rec = nullptr;
602  m_btr_cur.rtr_info = nullptr;
603  m_read_level = read_level;
604  import_ctx = nullptr;
605  m_block_when_stored.clear();
606 }
607 
608 /** Initializes and opens a persistent cursor to an index tree
609 It should be closed with btr_pcur_close.
610 @param[in] index Index.
611 @param[in] level Level in the btree.
612 @param[in] tuple Tuple on which search done.
613 @param[in] mode PAGE_CUR_L, ...; NOTE that if
614 the search is made using a unique prefix of a record, mode should be
615 PAGE_CUR_LE, not PAGE_CUR_GE, as the latter may end up on the previous page from
616 the record!
617 @param[in] latch_mode BTR_SEARCH_LEAF, ...
618 @param[in] mtr Mini-transaction.
619 @param[in] file File name
620 @param[in] line Line in file, from where called. */
621 inline void btr_pcur_t::open(dict_index_t *index, ulint level,
622  const dtuple_t *tuple, page_cur_mode_t mode,
623  ulint latch_mode, mtr_t *mtr, const char *file,
624  ulint line) {
625  init();
626 
627  m_search_mode = mode;
628  m_latch_mode = BTR_LATCH_MODE_WITHOUT_FLAGS(latch_mode);
629 
630  /* Search with the tree cursor */
631 
632  auto cur = get_btr_cur();
633 
634  ut_ad(!dict_index_is_spatial(index));
635 
636  if (index->table->is_intrinsic()) {
637  ut_ad((latch_mode & BTR_MODIFY_LEAF) || (latch_mode & BTR_SEARCH_LEAF) ||
638  (latch_mode & BTR_MODIFY_TREE));
639 
641  index, level, tuple, mode, cur, file, line, mtr,
642  (((latch_mode & BTR_MODIFY_LEAF) || (latch_mode & BTR_MODIFY_TREE))
643  ? true
644  : false));
645  } else {
646  btr_cur_search_to_nth_level(index, level, tuple, mode, latch_mode, cur, 0,
647  file, line, mtr);
648  }
649 
650  m_pos_state = BTR_PCUR_IS_POSITIONED;
651 
652  m_trx_if_known = nullptr;
653 }
654 
655 inline void btr_pcur_t::open_at_side(bool from_left, dict_index_t *index,
656  ulint latch_mode, bool init_pcur,
657  ulint level, mtr_t *mtr) {
658  m_latch_mode = BTR_LATCH_MODE_WITHOUT_FLAGS(latch_mode);
659 
660  m_search_mode = from_left ? PAGE_CUR_G : PAGE_CUR_L;
661 
662  if (init_pcur) {
663  init();
664  }
665 
666  if (index->table->is_intrinsic()) {
667  btr_cur_open_at_index_side_with_no_latch(from_left, index, get_btr_cur(),
668  level, mtr);
669  } else {
670  btr_cur_open_at_index_side(from_left, index, latch_mode, get_btr_cur(),
671  level, mtr);
672  }
673 
674  m_pos_state = BTR_PCUR_IS_POSITIONED;
675 
676  m_old_stored = false;
677 
678  m_trx_if_known = nullptr;
679 }
680 
682  ulint latch_mode, mtr_t *mtr,
683  const char *file, ulint line) {
684  m_latch_mode = latch_mode;
685  m_search_mode = PAGE_CUR_G;
686 
687  init();
688 
689  auto positioned = btr_cur_open_at_rnd_pos_func(
690  index, latch_mode, get_btr_cur(), file, line, mtr);
691 
692  m_old_stored = false;
693 
694  m_trx_if_known = nullptr;
695 
696  m_pos_state = BTR_PCUR_IS_POSITIONED;
697 
698  return (positioned);
699 }
700 
701 inline void btr_pcur_t::open_no_init(dict_index_t *index, const dtuple_t *tuple,
702  page_cur_mode_t mode, ulint latch_mode,
703  ulint has_search_latch, mtr_t *mtr,
704  const char *file, ulint line) {
705  m_latch_mode = BTR_LATCH_MODE_WITHOUT_INTENTION(latch_mode);
706 
707  m_search_mode = mode;
708 
709  /* Search with the tree cursor */
710 
711  auto cur = get_btr_cur();
712 
713  if (index->table->is_intrinsic()) {
714  ut_ad((latch_mode & BTR_MODIFY_LEAF) || (latch_mode & BTR_SEARCH_LEAF));
715 
717  index, m_read_level, tuple, mode, cur, file, line, mtr,
718  ((latch_mode & BTR_MODIFY_LEAF) ? true : false));
719  } else {
720  btr_cur_search_to_nth_level(index, m_read_level, tuple, mode, latch_mode,
721  cur, has_search_latch, file, line, mtr);
722  }
723 
724  m_pos_state = BTR_PCUR_IS_POSITIONED;
725 
726  m_old_stored = false;
727 
728  m_trx_if_known = nullptr;
729 }
730 
731 inline const btr_cur_t *btr_pcur_t::get_btr_cur() const { return (&m_btr_cur); }
732 
734  return (const_cast<btr_cur_t *>(&m_btr_cur));
735 }
736 
737 #ifdef UNIV_DEBUG
739  return (btr_cur_get_page_cur(get_btr_cur()));
740 }
741 
742 inline const page_cur_t *btr_pcur_t::get_page_cur() const {
743  return (btr_cur_get_page_cur(get_btr_cur()));
744 }
745 
747  ut_ad(m_pos_state == BTR_PCUR_IS_POSITIONED);
748 
749  return (btr_cur_get_page(get_btr_cur()));
750 }
751 
752 inline const page_t *btr_pcur_t::get_page() const {
753  ut_ad(m_pos_state == BTR_PCUR_IS_POSITIONED);
754 
755  return (btr_cur_get_page(const_cast<btr_pcur_t *>(this)->get_btr_cur()));
756 }
757 
759  ut_ad(m_pos_state == BTR_PCUR_IS_POSITIONED);
760 
761  return (btr_cur_get_block(get_btr_cur()));
762 }
763 
764 inline const buf_block_t *btr_pcur_t::get_block() const {
765  ut_ad(m_pos_state == BTR_PCUR_IS_POSITIONED);
766 
767  return (btr_cur_get_block(get_btr_cur()));
768 }
769 
771  ut_ad(m_pos_state == BTR_PCUR_IS_POSITIONED);
772  ut_ad(m_latch_mode != BTR_NO_LATCHES);
773 
774  return (btr_cur_get_rec(get_btr_cur()));
775 }
776 
777 inline const rec_t *btr_pcur_t::get_rec() const {
778  ut_ad(m_pos_state == BTR_PCUR_IS_POSITIONED);
779  ut_ad(m_latch_mode != BTR_NO_LATCHES);
780 
781  return (btr_cur_get_rec(get_btr_cur()));
782 }
783 #else
784 
785 inline page_cur_t *btr_pcur_t::get_page_cur() { return (&m_btr_cur.page_cur); }
786 
787 inline const page_cur_t *btr_pcur_t::get_page_cur() const {
788  return (&m_btr_cur.page_cur);
789 }
790 
791 inline page_t *btr_pcur_t::get_page() {
792  return (m_btr_cur.page_cur.block->frame);
793 }
794 
795 inline const page_t *btr_pcur_t::get_page() const {
796  return (m_btr_cur.page_cur.block->frame);
797 }
798 
800  return (m_btr_cur.page_cur.block);
801 }
802 
803 inline const buf_block_t *btr_pcur_t::get_block() const {
804  return (m_btr_cur.page_cur.block);
805 }
806 
807 inline rec_t *btr_pcur_t::get_rec() { return (m_btr_cur.page_cur.rec); }
808 
809 inline const rec_t *btr_pcur_t::get_rec() const {
810  return (m_btr_cur.page_cur.rec);
811 }
812 
813 #endif /* UNIV_DEBUG */
814 
815 #ifndef UNIV_HOTBACKUP
816 
817 inline ulint btr_pcur_t::get_rel_pos() const {
818  ut_ad(m_old_rec != nullptr);
819  ut_ad(m_old_stored);
820  ut_ad(m_pos_state == BTR_PCUR_WAS_POSITIONED ||
821  m_pos_state == BTR_PCUR_IS_POSITIONED);
822 
823  return (m_rel_pos);
824 }
825 
826 inline void btr_pcur_t::close() {
827  free_rec_buf();
828 
829  if (m_btr_cur.rtr_info != nullptr) {
830  rtr_clean_rtr_info(m_btr_cur.rtr_info, true);
831  m_btr_cur.rtr_info = nullptr;
832  }
833 
834  m_old_rec = nullptr;
835  m_btr_cur.page_cur.rec = nullptr;
836  m_btr_cur.page_cur.block = nullptr;
837 
838  m_old_rec = nullptr;
839  m_old_stored = false;
840 
841  m_latch_mode = BTR_NO_LATCHES;
842  m_pos_state = BTR_PCUR_NOT_POSITIONED;
843 
844  m_trx_if_known = nullptr;
845 }
846 
847 inline ulint btr_pcur_t::get_up_match() const {
848  ut_ad(m_pos_state == BTR_PCUR_WAS_POSITIONED ||
849  m_pos_state == BTR_PCUR_IS_POSITIONED);
850 
851  const auto cur = get_btr_cur();
852 
853  ut_ad(cur->up_match != ULINT_UNDEFINED);
854 
855  return (cur->up_match);
856 }
857 
858 inline ulint btr_pcur_t::get_low_match() const {
859  ut_ad(m_pos_state == BTR_PCUR_WAS_POSITIONED ||
860  m_pos_state == BTR_PCUR_IS_POSITIONED);
861 
862  const auto cur = get_btr_cur();
863 
864  ut_ad(cur->low_match != ULINT_UNDEFINED);
865 
866  return (cur->low_match);
867 }
868 
870  ut_ad(m_pos_state == BTR_PCUR_IS_POSITIONED);
871  ut_ad(m_latch_mode != BTR_NO_LATCHES);
872 
873  return (page_cur_is_after_last(get_page_cur()));
874 }
875 
877  ut_ad(m_pos_state == BTR_PCUR_IS_POSITIONED);
878  ut_ad(m_latch_mode != BTR_NO_LATCHES);
879 
880  return (page_cur_is_before_first(get_page_cur()));
881 }
882 
883 inline bool btr_pcur_t::is_on_user_rec() const {
884  ut_ad(m_pos_state == BTR_PCUR_IS_POSITIONED);
885  ut_ad(m_latch_mode != BTR_NO_LATCHES);
886 
887  return (!is_before_first_on_page() && !is_after_last_on_page());
888 }
889 
891  ut_ad(m_pos_state == BTR_PCUR_IS_POSITIONED);
892  ut_ad(m_latch_mode != BTR_NO_LATCHES);
893 
894  if (btr_page_get_prev(get_page(), mtr) != FIL_NULL) {
895  return (false);
896  }
897 
898  return (page_cur_is_before_first(get_page_cur()));
899 }
900 
901 inline bool btr_pcur_t::is_after_last_in_tree(mtr_t *mtr) const {
902  ut_ad(m_pos_state == BTR_PCUR_IS_POSITIONED);
903  ut_ad(m_latch_mode != BTR_NO_LATCHES);
904 
905  if (btr_page_get_next(get_page(), mtr) != FIL_NULL) {
906  return (false);
907  }
908 
909  return (page_cur_is_after_last(get_page_cur()));
910 }
911 
913  ut_ad(m_pos_state == BTR_PCUR_IS_POSITIONED);
914  ut_ad(m_latch_mode != BTR_NO_LATCHES);
915 
916  page_cur_move_to_next(get_page_cur());
917 
918  m_old_stored = false;
919 }
920 
922  ut_ad(m_pos_state == BTR_PCUR_IS_POSITIONED);
923  ut_ad(m_latch_mode != BTR_NO_LATCHES);
924 
925  page_cur_move_to_prev(get_page_cur());
926 
927  m_old_stored = false;
928 }
929 
931  UT_NOT_USED(mtr);
932  ut_ad(m_latch_mode != BTR_NO_LATCHES);
933 
934  page_cur_set_after_last(get_block(), get_page_cur());
935 
936  m_old_stored = false;
937 }
938 
940  ut_ad(m_pos_state == BTR_PCUR_IS_POSITIONED);
941  ut_ad(m_latch_mode != BTR_NO_LATCHES);
942 
943  for (;;) {
944  m_old_stored = false;
945 
946  if (is_after_last_on_page()) {
947  if (is_after_last_in_tree(mtr)) {
948  return (DB_END_OF_INDEX);
949  }
950 
951  move_to_next_page(mtr);
952  } else {
953  move_to_next_on_page();
954  }
955 
956  if (is_on_user_rec()) {
957  return (DB_SUCCESS);
958  }
959  }
960 }
961 
962 inline bool btr_pcur_t::move_to_next(mtr_t *mtr) {
963  ut_ad(m_pos_state == BTR_PCUR_IS_POSITIONED);
964  ut_ad(m_latch_mode != BTR_NO_LATCHES);
965 
966  m_old_stored = false;
967 
968  if (is_after_last_on_page()) {
969  if (is_after_last_in_tree(mtr)) {
970  return (false);
971  }
972 
973  move_to_next_page(mtr);
974 
975  return (true);
976  }
977 
978  move_to_next_on_page();
979 
980  return (true);
981 }
982 
984  ut_ad(m_pos_state == BTR_PCUR_IS_POSITIONED);
985 
986  m_latch_mode = BTR_NO_LATCHES;
987 
988  mtr_commit(mtr);
989 
990  m_pos_state = BTR_PCUR_WAS_POSITIONED;
991 }
992 
994  ut_ad(m_latch_mode != BTR_NO_LATCHES);
995 
996  page_cur_set_before_first(get_block(), get_page_cur());
997 
998  m_old_stored = false;
999 }
1000 
1001 inline void btr_pcur_t::reset() {
1002  free_rec_buf();
1003 
1004  m_old_rec_buf = nullptr;
1005  m_btr_cur.index = nullptr;
1006  m_btr_cur.page_cur.rec = nullptr;
1007  m_old_rec = nullptr;
1008  m_old_n_fields = 0;
1009  m_old_stored = false;
1010 
1011  m_latch_mode = BTR_NO_LATCHES;
1012  m_pos_state = BTR_PCUR_NOT_POSITIONED;
1013 }
1014 
1015 #endif /* !UNIV_HOTBACKUP */
1016 
1017 #endif /* !btr0pcur_h */
#define BTR_LATCH_MODE_WITHOUT_FLAGS(latch_mode)
Definition: btr0btr.h:130
Definition: db0err.h:42
The B-tree.
void free_rec_buf()
Free old_rec_buf.
Definition: btr0pcur.h:324
Definition: btr0pcur.h:60
void move_to_last_on_page(mtr_t *mtr)
Moves the persistent cursor to the last record on the same page.
Definition: btr0pcur.h:930
void move_before_first_on_page()
Moves the persistent cursor to the infimum record on the same page.
Definition: btr0pcur.h:993
Obtain no latches.
Definition: btr0btr.h:67
static btr_pcur_t * create_for_mysql()
Allocates memory for a persistent cursor object and initializes the cursor.
Definition: btr0pcur.h:489
void open(dict_index_t *index, ulint level, const dtuple_t *tuple, page_cur_mode_t mode, ulint latch_mode, mtr_t *mtr, const char *file, ulint line)
Initializes and opens a persistent cursor to an index tree It should be closed with close()...
Definition: btr0pcur.h:621
void move_to_next_on_page()
Moves the persistent cursor to the next record on the same page.
Definition: btr0pcur.h:912
buf_block_t * get_block()
Returns the current buffer block (non const version).
Definition: btr0pcur.h:758
page_cur_t * get_page_cur()
Definition: btr0pcur.h:738
R-tree header file.
#define BTR_LATCH_MODE_WITHOUT_INTENTION(latch_mode)
Definition: btr0btr.h:137
Definition: trx0trx.h:833
bool is_before_first_on_page() const
Checks if the persistent cursor is before the first user record on a page.
Definition: btr0pcur.h:876
The buffer control block structure.
Definition: buf0buf.h:1324
The persistent cursor is positioned by optimistic get to the same record as it was positioned at...
Definition: btr0pcur.h:162
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:214
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:1709
void close()
Frees the possible memory heap of a persistent cursor and sets the latch mode of the persistent curso...
Definition: btr0pcur.h:826
const btr_cur_t * get_btr_cur() const
Definition: btr0pcur.h:731
mode
Definition: file_handle.h:59
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:939
Start modifying the entire B-tree.
Definition: btr0btr.h:69
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:983
Definition: page0types.h:174
The tree cursor: the definition appears here only for the compiler to know struct size! ...
Definition: btr0cur.h:698
UNIV_INLINE buf_block_t * btr_cur_get_block(const btr_cur_t *cursor)
Returns the buffer block on which the tree cursor is positioned.
UNIV_INLINE ibool page_cur_is_before_first(const page_cur_t *cur)
Returns TRUE if the cursor is before first user record on page.
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:611
void rtr_clean_rtr_info(rtr_info_t *rtr_info, bool free_all)
Clean up R-Tree search structure.
Definition: gis0sea.cc:936
(Prepare to) modify a record on a leaf page and X-latch it.
Definition: btr0btr.h:65
UNIV_INLINE 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.
Definition: page0types.h:177
#define close(s)
Definition: win32.h:103
ulint get_rel_pos() const
Gets the rel_pos field for a cursor whose position has been stored.
Definition: btr0pcur.h:817
Definition: btr0pcur.h:178
UNIV_INLINE page_t * btr_cur_get_page(btr_cur_t *cursor)
Returns the page of a tree cursor.
SQL data field and tuple.
page_t * get_page()
Returns the page of a persistent pcur (non const version).
Definition: btr0pcur.h:746
static mysql_service_status_t init()
Component initialization.
Definition: audit_api_message_emit.cc:570
bool is_error
Definition: btr0pcur.h:172
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:901
Definition: btr0pcur.h:59
Definition: btr0pcur.h:170
dict_index_t * index()
Definition: btr0pcur.h:185
The index tree general types.
bool set_random_position(dict_index_t *index, ulint latch_mode, mtr_t *mtr, const char *file, ulint line)
Positions a cursor at a randomly chosen position within a B-tree.
Definition: btr0pcur.h:681
Page_fetch
Definition: buf0buf.h:57
dict_table_t * table
back pointer to table
Definition: dict0mem.h:891
Data dictionary system.
UNIV_INLINE page_no_t btr_page_get_prev(const page_t *page, mtr_t *mtr)
Gets the previous index page number.
bool is_intrinsic() const
Determine whether the table is intrinsic.
Definition: dict0mem.h:2211
btr_pcur_pos_t
Relative positions for a stored cursor position.
Definition: btr0pcur.h:50
#define UT_DELETE(ptr)
Destroy, deallocate and trace the deallocation of an object created by UT_NEW() or UT_NEW_NOKEY()...
Definition: ut0new.h:1022
UNIV_INLINE page_cur_t * btr_cur_get_page_cur(const btr_cur_t *cursor)
Returns the page cursor component of a tree cursor.
bool move_to_next(mtr_t *mtr)
Moves the persistent cursor to the next record in the tree.
Definition: btr0pcur.h:962
The page cursor.
byte rec_t
Definition: rem0types.h:39
Structure for an SQL data tuple of fields (logical record)
Definition: data0data.h:711
UNIV_INLINE rec_t * btr_cur_get_rec(const btr_cur_t *cursor)
Returns the record pointer of a tree cursor.
#define UT_NEW_NOKEY(expr)
Allocate, trace the allocation and construct an object.
Definition: ut0new.h:1016
void move_to_prev_on_page()
Moves the persistent cursor to the prev record on the same page.
Definition: btr0pcur.h:921
UNIV_INLINE ibool page_cur_is_after_last(const page_cur_t *cur)
Returns TRUE if the cursor is after last user record.
dberr_t
Definition: db0err.h:38
page_cur_mode_t
Definition: page0types.h:173
The persistent cursor was previously positioned.
Definition: btr0pcur.h:156
Definition: btr0pcur.h:53
The persistent cursor is not positioned.
Definition: btr0pcur.h:147
Definition: buf0block_hint.h:31
ulint get_low_match() const
Gets the low_match value for a pcur after a search.
Definition: btr0pcur.h:858
UNIV_INLINE page_no_t btr_page_get_next(const page_t *page, mtr_t *mtr)
Gets the next index page number.
rec_t * get_rec()
Returns the current record (non const version).
Definition: btr0pcur.h:770
UNIV_INLINE void page_cur_move_to_next(page_cur_t *cur)
Moves the cursor to the next record on page.
#define UT_NOT_USED(A)
Silence warnings about an unused variable by doing a null assignment.
Definition: ut0dbg.h:102
Definition: btr0pcur.h:52
pcur_pos_t
Position state of persistent B-tree cursor.
Definition: btr0pcur.h:144
void init(size_t read_level=0)
Sets the old_rec_buf field to nullptr.
Definition: btr0pcur.h:596
bool is_on_user_rec() const
Checks if the persistent cursor is on a user record.
Definition: btr0pcur.h:883
Search a record on a leaf page and S-latch it.
Definition: btr0btr.h:63
std::string HARNESS_EXPORT reset()
get &#39;reset attributes&#39; ESC sequence.
Definition: vt100.cc:36
Page_fetch set_fetch_type(Page_fetch fetch_mode)
Set the cursor access type: Normal or Scan.
Definition: btr0pcur.h:512
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:655
#define ut_ad(EXPR)
Debug assertion.
Definition: ut0dbg.h:66
bool btr_cur_open_at_rnd_pos_func(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:2247
#define mtr_commit(m)
Commit a mini-transaction.
Definition: mtr0mtr.h:59
stdx::expected< int, std::error_code > open(const char *fname, int flags, mode_t mode) noexcept
Definition: file_handle.cc:81
#define btr_cur_open_at_index_side_with_no_latch(f, i, c, lv, m)
Definition: btr0cur.h:228
ulint get_up_match() const
Gets the up_match value for a pcur after a search.
Definition: btr0pcur.h:847
buf::Block_hint m_block_when_stored
buffer block when the position was stored
Definition: btr0pcur.h:563
UNIV_INLINE ulint dict_index_is_spatial(const dict_index_t *index)
Check whether the index is a Spatial Index.
void reset()
Resets a persistent cursor object, freeing "::old_rec_buf" if it is allocated and resetting the other...
Definition: btr0pcur.h:1001
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, const char *file, ulint line)
Opens an persistent cursor to an index tree without initializing the cursor.
Definition: btr0pcur.h:701
btr_cur_t m_btr_cur
a B-tree cursor
Definition: btr0pcur.h:537
#define ut_free(ptr)
Definition: ut0new.h:1122
byte page_t
Type of the index page.
Definition: page0types.h:148
Mini-transaction buffer.
Definition: os0file.h:85
#define btr_cur_open_at_index_side(f, i, l, c, lv, m)
Definition: btr0cur.h:210
constexpr page_no_t FIL_NULL
&#39;null&#39; (undefined) page offset in the context of file spaces
Definition: fil0fil.h:928
UNIV_INLINE 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.
Definition: btr0pcur.h:51
bool is_after_last_on_page() const
Checks if the persistent cursor is after the last user record on a page.
Definition: btr0pcur.h:869
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:890
bool is_positioned() const
Definition: btr0pcur.h:468
Definition: btr0pcur.h:54
Get always.
Definition: db0err.h:208
The index tree cursor.
Index page cursor.
Definition: page0cur.h:314
unsigned char byte
Blob class.
Definition: common.h:159
UNIV_INLINE void page_cur_move_to_prev(page_cur_t *cur)
Moves the cursor to the previous record on page.
Mini-transaction handle and buffer.
Definition: mtr0mtr.h:169
The persistent cursor is positioned by index search.
Definition: btr0pcur.h:166
static void free_for_mysql(btr_pcur_t *&pcur)
Frees the memory for a persistent cursor object and the cursor itself.
Definition: btr0pcur.h:501
Same as NORMAL, but hint that the fetch is part of a large scan.
Definition: page0types.h:175
bool is_clustered() const
Definition: btr0pcur.h:474
Data structure for an index.
Definition: dict0mem.h:886