summaryrefslogtreecommitdiff
path: root/innobase/btr/btr0pcur.c
diff options
context:
space:
mode:
Diffstat (limited to 'innobase/btr/btr0pcur.c')
-rw-r--r--innobase/btr/btr0pcur.c70
1 files changed, 52 insertions, 18 deletions
diff --git a/innobase/btr/btr0pcur.c b/innobase/btr/btr0pcur.c
index 5e625553929..8ca3d41f7f9 100644
--- a/innobase/btr/btr0pcur.c
+++ b/innobase/btr/btr0pcur.c
@@ -62,8 +62,10 @@ btr_pcur_free_for_mysql(
/******************************************************************
The position of the cursor is stored by taking an initial segment of the
record the cursor is positioned on, before, or after, and copying it to the
-cursor data structure. NOTE that the page where the cursor is positioned
-must not be empty! */
+cursor data structure, or just setting a flag if the cursor id before the
+first in an EMPTY tree, or after the last in an EMPTY tree. NOTE that the
+page where the cursor is positioned must not be empty if the index tree is
+not totally empty! */
void
btr_pcur_store_position(
@@ -93,9 +95,21 @@ btr_pcur_store_position(
ut_a(cursor->latch_mode != BTR_NO_LATCHES);
if (page_get_n_recs(page) == 0) {
+ /* It must be an empty index tree */
- /* Cannot store position! */
- btr_pcur_close(cursor);
+ ut_a(btr_page_get_next(page, mtr) == FIL_NULL
+ && btr_page_get_prev(page, mtr) == FIL_NULL);
+
+ if (rec == page_get_supremum_rec(page)) {
+
+ cursor->rel_pos = BTR_PCUR_AFTER_LAST_IN_TREE;
+ cursor->old_stored = BTR_PCUR_OLD_STORED;
+
+ return;
+ }
+
+ cursor->rel_pos = BTR_PCUR_BEFORE_FIRST_IN_TREE;
+ cursor->old_stored = BTR_PCUR_OLD_STORED;
return;
}
@@ -140,13 +154,15 @@ btr_pcur_copy_stored_position(
ut_memcpy((byte*)pcur_receive, (byte*)pcur_donate, sizeof(btr_pcur_t));
- pcur_receive->old_rec_buf = mem_alloc(pcur_donate->buf_size);
+ if (pcur_donate->old_rec_buf) {
+
+ pcur_receive->old_rec_buf = mem_alloc(pcur_donate->buf_size);
- ut_memcpy(pcur_receive->old_rec_buf, pcur_donate->old_rec_buf,
+ ut_memcpy(pcur_receive->old_rec_buf, pcur_donate->old_rec_buf,
pcur_donate->buf_size);
- pcur_receive->old_rec = pcur_receive->old_rec_buf
+ pcur_receive->old_rec = pcur_receive->old_rec_buf
+ (pcur_donate->old_rec - pcur_donate->old_rec_buf);
-
+ }
}
/******************************************************************
@@ -158,7 +174,9 @@ to the last record LESS OR EQUAL to the stored record;
the last record LESS than the user record which was the successor of the page
infimum;
(3) cursor was positioned on the page supremum: restores to the first record
-GREATER than the user record which was the predecessor of the supremum. */
+GREATER than the user record which was the predecessor of the supremum.
+(4) cursor was positioned before the first or after the last in an empty tree:
+restores to before first or after the last in the tree. */
ibool
btr_pcur_restore_position(
@@ -177,17 +195,33 @@ btr_pcur_restore_position(
dtuple_t* tuple;
ulint mode;
ulint old_mode;
+ ibool from_left;
mem_heap_t* heap;
- ut_a((cursor->pos_state == BTR_PCUR_WAS_POSITIONED)
- || (cursor->pos_state == BTR_PCUR_IS_POSITIONED));
+ ut_a(cursor->pos_state == BTR_PCUR_WAS_POSITIONED
+ || cursor->pos_state == BTR_PCUR_IS_POSITIONED);
ut_a(cursor->old_stored == BTR_PCUR_OLD_STORED);
+
+ if (cursor->rel_pos == BTR_PCUR_AFTER_LAST_IN_TREE
+ || cursor->rel_pos == BTR_PCUR_BEFORE_FIRST_IN_TREE) {
+
+ if (cursor->rel_pos == BTR_PCUR_BEFORE_FIRST_IN_TREE) {
+ from_left = TRUE;
+ } else {
+ from_left = FALSE;
+ }
+
+ btr_cur_open_at_index_side(from_left,
+ btr_pcur_get_btr_cur(cursor)->index, latch_mode,
+ btr_pcur_get_btr_cur(cursor), mtr);
+ return(FALSE);
+ }
+
ut_a(cursor->old_rec);
page = btr_cur_get_page(btr_pcur_get_btr_cur(cursor));
- if ((latch_mode == BTR_SEARCH_LEAF)
- || (latch_mode == BTR_MODIFY_LEAF)) {
+ if (latch_mode == BTR_SEARCH_LEAF || latch_mode == BTR_MODIFY_LEAF) {
/* Try optimistic restoration */
if (buf_page_optimistic_get(latch_mode, page,
@@ -242,16 +276,15 @@ btr_pcur_restore_position(
/* Restore the old search mode */
cursor->search_mode = old_mode;
- if ((cursor->rel_pos == BTR_PCUR_ON)
- && btr_pcur_is_on_user_rec(cursor, mtr)
- && (0 == cmp_dtuple_rec(tuple, btr_pcur_get_rec(cursor)))) {
+ if (cursor->rel_pos == BTR_PCUR_ON
+ && btr_pcur_is_on_user_rec(cursor, mtr)
+ && 0 == cmp_dtuple_rec(tuple, btr_pcur_get_rec(cursor))) {
/* We have to store the NEW value for the modify clock, since
the cursor can now be on a different page! */
cursor->modify_clock = buf_frame_get_modify_clock(
- buf_frame_align(
- btr_pcur_get_rec(cursor)));
+ buf_frame_align(btr_pcur_get_rec(cursor)));
mem_heap_free(heap);
return(TRUE);
@@ -366,6 +399,7 @@ btr_pcur_move_backward_from_page(
latch_mode2 = BTR_MODIFY_PREV;
} else {
+ latch_mode2 = 0; /* To eliminate compiler warning */
ut_error;
}