@@ -215,27 +215,6 @@ class PCursor {
215215 PCursor (btr_pcur_t *pcur, mtr_t *mtr, size_t read_level)
216216 : m_mtr(mtr), m_pcur(pcur), m_read_level(read_level) {}
217217
218- /* *
219- Restore position of cursor created from Scan_ctx::Range object.
220- Adjust it if starting record of range has been purged.
221- */
222- void restore_position_for_range () noexcept {
223- /*
224- Restore position on the record or its predecessor if the record
225- was purged meanwhile. In the latter case we need to adjust position by
226- moving one step forward as predecessor belongs to another range.
227-
228- We rely on return value from restore_position() to detect this scenario.
229- This can be done when saved position points to user record which is
230- always the case for saved start of Scan_ctx::Range.
231- */
232- ut_ad (m_pcur->m_rel_pos == BTR_PCUR_ON);
233-
234- if (!m_pcur->restore_position (BTR_SEARCH_LEAF, m_mtr, UT_LOCATION_HERE)) {
235- page_cur_move_to_next (m_pcur->get_page_cur ());
236- }
237- }
238-
239218 /* * Create a savepoint and commit the mini-transaction.*/
240219 void savepoint () noexcept ;
241220
@@ -247,6 +226,65 @@ class PCursor {
247226 @return DB_SUCCESS or error code. */
248227 [[nodiscard]] dberr_t move_to_next_block (dict_index_t *index);
249228
229+ /* * Restore the cursor position. */
230+ void restore_position () noexcept {
231+ constexpr auto MODE = BTR_SEARCH_LEAF;
232+ const auto relative = m_pcur->m_rel_pos ;
233+ auto equal = m_pcur->restore_position (MODE, m_mtr, UT_LOCATION_HERE);
234+
235+ #ifdef UNIV_DEBUG
236+ if (m_pcur->m_pos_state == BTR_PCUR_IS_POSITIONED_OPTIMISTIC) {
237+ ut_ad (m_pcur->m_rel_pos == BTR_PCUR_BEFORE ||
238+ m_pcur->m_rel_pos == BTR_PCUR_AFTER);
239+ } else {
240+ ut_ad (m_pcur->m_pos_state == BTR_PCUR_IS_POSITIONED);
241+ ut_ad ((m_pcur->m_rel_pos == BTR_PCUR_ON) == m_pcur->is_on_user_rec ());
242+ }
243+ #endif /* UNIV_DEBUG */
244+
245+ switch (relative) {
246+ case BTR_PCUR_ON:
247+ if (!equal) {
248+ page_cur_move_to_next (m_pcur->get_page_cur ());
249+ }
250+ break ;
251+
252+ case BTR_PCUR_UNSET:
253+ case BTR_PCUR_BEFORE_FIRST_IN_TREE:
254+ ut_error;
255+ break ;
256+
257+ case BTR_PCUR_AFTER:
258+ case BTR_PCUR_AFTER_LAST_IN_TREE:
259+ break ;
260+
261+ case BTR_PCUR_BEFORE:
262+ /* For non-optimistic restoration:
263+ The position is now set to the record before pcur->old_rec.
264+
265+ For optimistic restoration:
266+ The position also needs to take the previous search_mode into
267+ consideration. */
268+ switch (m_pcur->m_pos_state ) {
269+ case BTR_PCUR_IS_POSITIONED_OPTIMISTIC:
270+ m_pcur->m_pos_state = BTR_PCUR_IS_POSITIONED;
271+ /* The cursor always moves "up" ie. in ascending order. */
272+ break ;
273+
274+ case BTR_PCUR_IS_POSITIONED:
275+ if (m_pcur->is_on_user_rec ()) {
276+ m_pcur->move_to_next (m_mtr);
277+ }
278+ break ;
279+
280+ case BTR_PCUR_NOT_POSITIONED:
281+ case BTR_PCUR_WAS_POSITIONED:
282+ ut_error;
283+ }
284+ break ;
285+ }
286+ }
287+
250288 /* * @return the current page cursor. */
251289 [[nodiscard]] page_cur_t *get_page_cursor () noexcept {
252290 return m_pcur->get_page_cur ();
@@ -310,7 +348,7 @@ void PCursor::resume() noexcept {
310348 /* Restore position on the record, or its predecessor if the record
311349 was purged meanwhile. */
312350
313- m_pcur-> restore_position (BTR_SEARCH_LEAF, m_mtr, UT_LOCATION_HERE );
351+ restore_position ();
314352
315353 if (!m_pcur->is_after_last_on_page ()) {
316354 /* Move to the successor of the saved record. */
@@ -588,7 +626,7 @@ dberr_t Parallel_reader::Ctx::traverse() {
588626 auto &from = m_range.first ;
589627
590628 PCursor pcursor (from->m_pcur , &mtr, m_scan_ctx->m_config .m_read_level );
591- pcursor.restore_position_for_range ();
629+ pcursor.restore_position ();
592630
593631 dberr_t err{DB_SUCCESS};
594632
0 commit comments