Commit 7506ca1b authored by marko@hundin.mysql.fi's avatar marko@hundin.mysql.fi

InnoDB: Changed interface to rec_get_offsets(), to reduce the use of

memory heaps.  This changeset plugs also a few memory leaks that
were introduced with the compact InnoDB table format.
parent 3f806c3b
...@@ -567,7 +567,8 @@ btr_page_get_father_for_rec( ...@@ -567,7 +567,8 @@ btr_page_get_father_for_rec(
btr_cur_t cursor; btr_cur_t cursor;
rec_t* node_ptr; rec_t* node_ptr;
dict_index_t* index; dict_index_t* index;
ulint* offsets; ulint offsets_[100] = { 100, };
ulint* offsets = offsets_;
ut_ad(mtr_memo_contains(mtr, dict_tree_get_lock(tree), ut_ad(mtr_memo_contains(mtr, dict_tree_get_lock(tree),
MTR_MEMO_X_LOCK)); MTR_MEMO_X_LOCK));
...@@ -591,7 +592,8 @@ btr_page_get_father_for_rec( ...@@ -591,7 +592,8 @@ btr_page_get_father_for_rec(
BTR_CONT_MODIFY_TREE, &cursor, 0, mtr); BTR_CONT_MODIFY_TREE, &cursor, 0, mtr);
node_ptr = btr_cur_get_rec(&cursor); node_ptr = btr_cur_get_rec(&cursor);
offsets = rec_get_offsets(node_ptr, index, ULINT_UNDEFINED, heap); offsets = rec_get_offsets(node_ptr, index, offsets,
ULINT_UNDEFINED, &heap);
if (btr_node_ptr_get_child_page_no(node_ptr, offsets) != if (btr_node_ptr_get_child_page_no(node_ptr, offsets) !=
buf_frame_get_page_no(page)) { buf_frame_get_page_no(page)) {
...@@ -609,13 +611,13 @@ btr_page_get_father_for_rec( ...@@ -609,13 +611,13 @@ btr_page_get_father_for_rec(
(ulong) (ulong)
btr_node_ptr_get_child_page_no(node_ptr, offsets), btr_node_ptr_get_child_page_no(node_ptr, offsets),
(ulong) buf_frame_get_page_no(page)); (ulong) buf_frame_get_page_no(page));
offsets = rec_reget_offsets(page_rec_get_next( offsets = rec_get_offsets(page_rec_get_next(
page_get_infimum_rec(page)), index, page_get_infimum_rec(page)), index,
offsets, ULINT_UNDEFINED, heap); offsets, ULINT_UNDEFINED, &heap);
page_rec_print(page_rec_get_next(page_get_infimum_rec(page)), page_rec_print(page_rec_get_next(page_get_infimum_rec(page)),
offsets); offsets);
offsets = rec_reget_offsets(node_ptr, index, offsets, offsets = rec_get_offsets(node_ptr, index, offsets,
ULINT_UNDEFINED, heap); ULINT_UNDEFINED, &heap);
page_rec_print(node_ptr, offsets); page_rec_print(node_ptr, offsets);
fputs( fputs(
...@@ -1231,7 +1233,7 @@ btr_page_get_sure_split_rec( ...@@ -1231,7 +1233,7 @@ btr_page_get_sure_split_rec(
ins_rec = btr_cur_get_rec(cursor); ins_rec = btr_cur_get_rec(cursor);
rec = page_get_infimum_rec(page); rec = page_get_infimum_rec(page);
heap = mem_heap_create(100); heap = NULL;
offsets = NULL; offsets = NULL;
/* We start to include records to the left half, and when the /* We start to include records to the left half, and when the
...@@ -1256,8 +1258,8 @@ btr_page_get_sure_split_rec( ...@@ -1256,8 +1258,8 @@ btr_page_get_sure_split_rec(
/* Include tuple */ /* Include tuple */
incl_data += insert_size; incl_data += insert_size;
} else { } else {
offsets = rec_reget_offsets(rec, cursor->index, offsets = rec_get_offsets(rec, cursor->index,
offsets, ULINT_UNDEFINED, heap); offsets, ULINT_UNDEFINED, &heap);
incl_data += rec_offs_size(offsets); incl_data += rec_offs_size(offsets);
} }
...@@ -1280,12 +1282,16 @@ btr_page_get_sure_split_rec( ...@@ -1280,12 +1282,16 @@ btr_page_get_sure_split_rec(
next_rec = page_rec_get_next(rec); next_rec = page_rec_get_next(rec);
} }
if (next_rec != page_get_supremum_rec(page)) { if (next_rec != page_get_supremum_rec(page)) {
if (heap) {
mem_heap_free(heap); mem_heap_free(heap);
}
return(next_rec); return(next_rec);
} }
} }
if (heap) {
mem_heap_free(heap); mem_heap_free(heap);
}
return(rec); return(rec);
} }
} }
...@@ -1367,8 +1373,8 @@ btr_page_insert_fits( ...@@ -1367,8 +1373,8 @@ btr_page_insert_fits(
/* In this loop we calculate the amount of reserved /* In this loop we calculate the amount of reserved
space after rec is removed from page. */ space after rec is removed from page. */
offs = rec_reget_offsets(rec, cursor->index, offs, offs = rec_get_offsets(rec, cursor->index, offs,
ULINT_UNDEFINED, heap); ULINT_UNDEFINED, &heap);
total_data -= rec_offs_size(offs); total_data -= rec_offs_size(offs);
total_n_recs--; total_n_recs--;
...@@ -1459,7 +1465,7 @@ btr_attach_half_pages( ...@@ -1459,7 +1465,7 @@ btr_attach_half_pages(
ut_a(page_is_comp(page) == page_is_comp(new_page)); ut_a(page_is_comp(page) == page_is_comp(new_page));
/* Create a memory heap where the data tuple is stored */ /* Create a memory heap where the data tuple is stored */
heap = mem_heap_create(100); heap = mem_heap_create(1024);
/* Based on split direction, decide upper and lower pages */ /* Based on split direction, decide upper and lower pages */
if (direction == FSP_DOWN) { if (direction == FSP_DOWN) {
...@@ -1478,7 +1484,7 @@ btr_attach_half_pages( ...@@ -1478,7 +1484,7 @@ btr_attach_half_pages(
btr_node_ptr_set_child_page_no(node_ptr, btr_node_ptr_set_child_page_no(node_ptr,
rec_get_offsets(node_ptr, rec_get_offsets(node_ptr,
UT_LIST_GET_FIRST(tree->tree_indexes), UT_LIST_GET_FIRST(tree->tree_indexes),
ULINT_UNDEFINED, heap), NULL, ULINT_UNDEFINED, &heap),
lower_page_no, mtr); lower_page_no, mtr);
mem_heap_empty(heap); mem_heap_empty(heap);
} else { } else {
...@@ -1656,8 +1662,8 @@ func_start: ...@@ -1656,8 +1662,8 @@ func_start:
thus reducing the tree latch contention. */ thus reducing the tree latch contention. */
if (split_rec) { if (split_rec) {
offsets = rec_reget_offsets(split_rec, cursor->index, offsets = rec_get_offsets(split_rec, cursor->index, offsets,
offsets, n_uniq, heap); n_uniq, &heap);
insert_will_fit = btr_page_insert_fits(cursor, insert_will_fit = btr_page_insert_fits(cursor,
split_rec, offsets, tuple, heap); split_rec, offsets, tuple, heap);
...@@ -1700,8 +1706,8 @@ func_start: ...@@ -1700,8 +1706,8 @@ func_start:
insert_page = right_page; insert_page = right_page;
} else { } else {
offsets = rec_reget_offsets(first_rec, cursor->index, offsets = rec_get_offsets(first_rec, cursor->index,
offsets, n_uniq, heap); offsets, n_uniq, &heap);
if (cmp_dtuple_rec(tuple, first_rec, offsets) >= 0) { if (cmp_dtuple_rec(tuple, first_rec, offsets) >= 0) {
...@@ -2091,14 +2097,18 @@ btr_compress( ...@@ -2091,14 +2097,18 @@ btr_compress(
if (is_left) { if (is_left) {
btr_node_ptr_delete(tree, page, mtr); btr_node_ptr_delete(tree, page, mtr);
} else { } else {
mem_heap_t* heap = mem_heap_create(100); mem_heap_t* heap = NULL;
ulint offsets_[100] = { 100, };
/* Replace the address of the old child node (= page) with the /* Replace the address of the old child node (= page) with the
address of the merge page to the right */ address of the merge page to the right */
btr_node_ptr_set_child_page_no(node_ptr, btr_node_ptr_set_child_page_no(node_ptr,
rec_get_offsets(node_ptr, cursor->index, rec_get_offsets(node_ptr, cursor->index,
ULINT_UNDEFINED, heap), right_page_no, mtr); offsets_, ULINT_UNDEFINED, &heap),
right_page_no, mtr);
if (heap) {
mem_heap_free(heap); mem_heap_free(heap);
}
btr_node_ptr_delete(tree, merge_page, mtr); btr_node_ptr_delete(tree, merge_page, mtr);
} }
...@@ -2312,8 +2322,8 @@ btr_print_recursive( ...@@ -2312,8 +2322,8 @@ btr_print_recursive(
page_t* page, /* in: index page */ page_t* page, /* in: index page */
ulint width, /* in: print this many entries from start ulint width, /* in: print this many entries from start
and end */ and end */
mem_heap_t* heap, /* in: heap for rec_reget_offsets() */ mem_heap_t** heap, /* in/out: heap for rec_get_offsets() */
ulint** offsets,/* in/out: buffer for rec_reget_offsets() */ ulint** offsets,/* in/out: buffer for rec_get_offsets() */
mtr_t* mtr) /* in: mtr */ mtr_t* mtr) /* in: mtr */
{ {
page_cur_t cursor; page_cur_t cursor;
...@@ -2350,8 +2360,8 @@ btr_print_recursive( ...@@ -2350,8 +2360,8 @@ btr_print_recursive(
node_ptr = page_cur_get_rec(&cursor); node_ptr = page_cur_get_rec(&cursor);
*offsets = rec_reget_offsets(node_ptr, index, *offsets = rec_get_offsets(node_ptr, index, *offsets,
*offsets, ULINT_UNDEFINED, heap); ULINT_UNDEFINED, heap);
child = btr_node_ptr_get_child(node_ptr, child = btr_node_ptr_get_child(node_ptr,
*offsets, &mtr2); *offsets, &mtr2);
btr_print_recursive(tree, child, width, btr_print_recursive(tree, child, width,
...@@ -2362,8 +2372,6 @@ btr_print_recursive( ...@@ -2362,8 +2372,6 @@ btr_print_recursive(
page_cur_move_to_next(&cursor); page_cur_move_to_next(&cursor);
i++; i++;
} }
mem_heap_free(heap);
} }
/****************************************************************** /******************************************************************
...@@ -2378,8 +2386,10 @@ btr_print_tree( ...@@ -2378,8 +2386,10 @@ btr_print_tree(
{ {
mtr_t mtr; mtr_t mtr;
page_t* root; page_t* root;
mem_heap_t* heap = mem_heap_create(100); mem_heap_t* heap = NULL;
ulint* offsets = NULL; ulint offsets_[100]
= { 100, };
ulint* offsets = offsets_;
fputs("--------------------------\n" fputs("--------------------------\n"
"INDEX TREE PRINT\n", stderr); "INDEX TREE PRINT\n", stderr);
...@@ -2388,8 +2398,10 @@ btr_print_tree( ...@@ -2388,8 +2398,10 @@ btr_print_tree(
root = btr_root_get(tree, &mtr); root = btr_root_get(tree, &mtr);
btr_print_recursive(tree, root, width, heap, &offsets, &mtr); btr_print_recursive(tree, root, width, &heap, &offsets, &mtr);
if (heap) {
mem_heap_free(heap); mem_heap_free(heap);
}
mtr_commit(&mtr); mtr_commit(&mtr);
...@@ -2435,7 +2447,7 @@ btr_check_node_ptr( ...@@ -2435,7 +2447,7 @@ btr_check_node_ptr(
ut_a(cmp_dtuple_rec(node_ptr_tuple, node_ptr, ut_a(cmp_dtuple_rec(node_ptr_tuple, node_ptr,
rec_get_offsets(node_ptr, rec_get_offsets(node_ptr,
dict_tree_find_index(tree, node_ptr), dict_tree_find_index(tree, node_ptr),
ULINT_UNDEFINED, heap)) == 0); NULL, ULINT_UNDEFINED, &heap)) == 0);
mem_heap_free(heap); mem_heap_free(heap);
...@@ -2476,8 +2488,10 @@ btr_index_rec_validate( ...@@ -2476,8 +2488,10 @@ btr_index_rec_validate(
ulint n; ulint n;
ulint i; ulint i;
page_t* page; page_t* page;
mem_heap_t* heap; mem_heap_t* heap = NULL;
ulint* offsets; ulint offsets_[100]
= { 100, };
ulint* offsets = offsets_;
page = buf_frame_align(rec); page = buf_frame_align(rec);
...@@ -2496,22 +2510,17 @@ btr_index_rec_validate( ...@@ -2496,22 +2510,17 @@ btr_index_rec_validate(
fprintf(stderr, "InnoDB: has %lu fields, should have %lu\n", fprintf(stderr, "InnoDB: has %lu fields, should have %lu\n",
(ulong) rec_get_n_fields_old(rec), (ulong) n); (ulong) rec_get_n_fields_old(rec), (ulong) n);
if (!dump_on_error) { if (dump_on_error) {
return(FALSE);
}
buf_page_print(page); buf_page_print(page);
fputs("InnoDB: corrupt record ", stderr); fputs("InnoDB: corrupt record ", stderr);
rec_print_old(stderr, rec); rec_print_old(stderr, rec);
putc('\n', stderr); putc('\n', stderr);
}
return(FALSE); return(FALSE);
} }
heap = mem_heap_create(100); offsets = rec_get_offsets(rec, index, offsets, ULINT_UNDEFINED, &heap);
offsets = rec_get_offsets(rec, index, ULINT_UNDEFINED, heap);
for (i = 0; i < n; i++) { for (i = 0; i < n; i++) {
dtype_t* type = dict_index_get_nth_type(index, i); dtype_t* type = dict_index_get_nth_type(index, i);
...@@ -2536,23 +2545,23 @@ btr_index_rec_validate( ...@@ -2536,23 +2545,23 @@ btr_index_rec_validate(
"InnoDB: field %lu len is %lu, should be %lu\n", "InnoDB: field %lu len is %lu, should be %lu\n",
(ulong) i, (ulong) len, (ulong) dtype_get_fixed_size(type)); (ulong) i, (ulong) len, (ulong) dtype_get_fixed_size(type));
if (!dump_on_error) { if (dump_on_error) {
mem_heap_free(heap);
return(FALSE);
}
buf_page_print(page); buf_page_print(page);
fputs("InnoDB: corrupt record ", stderr); fputs("InnoDB: corrupt record ", stderr);
rec_print(stderr, rec, offsets); rec_print_new(stderr, rec, offsets);
putc('\n', stderr); putc('\n', stderr);
}
if (heap) {
mem_heap_free(heap); mem_heap_free(heap);
}
return(FALSE); return(FALSE);
} }
} }
if (heap) {
mem_heap_free(heap); mem_heap_free(heap);
}
return(TRUE); return(TRUE);
} }
...@@ -2677,8 +2686,8 @@ btr_validate_level( ...@@ -2677,8 +2686,8 @@ btr_validate_level(
page_cur_move_to_next(&cursor); page_cur_move_to_next(&cursor);
node_ptr = page_cur_get_rec(&cursor); node_ptr = page_cur_get_rec(&cursor);
offsets = rec_reget_offsets(node_ptr, index, offsets = rec_get_offsets(node_ptr, index, offsets,
offsets, ULINT_UNDEFINED, heap); ULINT_UNDEFINED, &heap);
page = btr_node_ptr_get_child(node_ptr, offsets, &mtr); page = btr_node_ptr_get_child(node_ptr, offsets, &mtr);
} }
...@@ -2722,10 +2731,10 @@ loop: ...@@ -2722,10 +2731,10 @@ loop:
rec = page_rec_get_prev(page_get_supremum_rec(page)); rec = page_rec_get_prev(page_get_supremum_rec(page));
right_rec = page_rec_get_next( right_rec = page_rec_get_next(
page_get_infimum_rec(right_page)); page_get_infimum_rec(right_page));
offsets = rec_reget_offsets(rec, index, offsets = rec_get_offsets(rec, index,
offsets, ULINT_UNDEFINED, heap); offsets, ULINT_UNDEFINED, &heap);
offsets2 = rec_reget_offsets(right_rec, index, offsets2 = rec_get_offsets(right_rec, index,
offsets2, ULINT_UNDEFINED, heap); offsets2, ULINT_UNDEFINED, &heap);
if (cmp_rec_rec(rec, right_rec, offsets, offsets2, if (cmp_rec_rec(rec, right_rec, offsets, offsets2,
dict_index_get_n_fields(index), dict_index_get_n_fields(index),
index) >= 0) { index) >= 0) {
...@@ -2740,16 +2749,12 @@ loop: ...@@ -2740,16 +2749,12 @@ loop:
fputs("InnoDB: record ", stderr); fputs("InnoDB: record ", stderr);
rec = page_rec_get_prev(page_get_supremum_rec(page)); rec = page_rec_get_prev(page_get_supremum_rec(page));
offsets = rec_reget_offsets(rec, index, rec_print(stderr, rec, index);
offsets, ULINT_UNDEFINED, heap);
rec_print(stderr, rec, offsets);
putc('\n', stderr); putc('\n', stderr);
fputs("InnoDB: record ", stderr); fputs("InnoDB: record ", stderr);
rec = page_rec_get_next(page_get_infimum_rec( rec = page_rec_get_next(page_get_infimum_rec(
right_page)); right_page));
offsets = rec_reget_offsets(rec, index, rec_print(stderr, rec, index);
offsets, ULINT_UNDEFINED, heap);
rec_print(stderr, rec, offsets);
putc('\n', stderr); putc('\n', stderr);
ret = FALSE; ret = FALSE;
...@@ -2768,8 +2773,8 @@ loop: ...@@ -2768,8 +2773,8 @@ loop:
node_ptr = btr_page_get_father_node_ptr(tree, page, &mtr); node_ptr = btr_page_get_father_node_ptr(tree, page, &mtr);
father_page = buf_frame_align(node_ptr); father_page = buf_frame_align(node_ptr);
offsets = rec_reget_offsets(node_ptr, index, offsets = rec_get_offsets(node_ptr, index,
offsets, ULINT_UNDEFINED, heap); offsets, ULINT_UNDEFINED, &heap);
if (btr_node_ptr_get_child_page_no(node_ptr, offsets) != if (btr_node_ptr_get_child_page_no(node_ptr, offsets) !=
buf_frame_get_page_no(page) buf_frame_get_page_no(page)
...@@ -2785,7 +2790,7 @@ loop: ...@@ -2785,7 +2790,7 @@ loop:
buf_page_print(page); buf_page_print(page);
fputs("InnoDB: node ptr ", stderr); fputs("InnoDB: node ptr ", stderr);
rec_print(stderr, node_ptr, offsets); rec_print_new(stderr, node_ptr, offsets);
fprintf(stderr, "\n" fprintf(stderr, "\n"
"InnoDB: node ptr child page n:o %lu\n", "InnoDB: node ptr child page n:o %lu\n",
...@@ -2796,9 +2801,7 @@ loop: ...@@ -2796,9 +2801,7 @@ loop:
rec = btr_page_get_father_for_rec(tree, page, rec = btr_page_get_father_for_rec(tree, page,
page_rec_get_prev(page_get_supremum_rec(page)), page_rec_get_prev(page_get_supremum_rec(page)),
&mtr); &mtr);
offsets = rec_reget_offsets(rec, index, rec_print(stderr, rec, index);
offsets, ULINT_UNDEFINED, heap);
rec_print(stderr, rec, offsets);
putc('\n', stderr); putc('\n', stderr);
ret = FALSE; ret = FALSE;
...@@ -2806,8 +2809,8 @@ loop: ...@@ -2806,8 +2809,8 @@ loop:
} }
if (btr_page_get_level(page, &mtr) > 0) { if (btr_page_get_level(page, &mtr) > 0) {
offsets = rec_reget_offsets(node_ptr, index, offsets = rec_get_offsets(node_ptr, index,
offsets, ULINT_UNDEFINED, heap); offsets, ULINT_UNDEFINED, &heap);
node_ptr_tuple = dict_tree_build_node_ptr( node_ptr_tuple = dict_tree_build_node_ptr(
tree, tree,
...@@ -2829,11 +2832,9 @@ loop: ...@@ -2829,11 +2832,9 @@ loop:
fputs("InnoDB: Error: node ptrs differ" fputs("InnoDB: Error: node ptrs differ"
" on levels > 0\n" " on levels > 0\n"
"InnoDB: node ptr ", stderr); "InnoDB: node ptr ", stderr);
rec_print(stderr, node_ptr, offsets); rec_print_new(stderr, node_ptr, offsets);
fputs("InnoDB: first rec ", stderr); fputs("InnoDB: first rec ", stderr);
offsets = rec_reget_offsets(first_rec, index, rec_print(stderr, first_rec, index);
offsets, ULINT_UNDEFINED, heap);
rec_print(stderr, first_rec, offsets);
putc('\n', stderr); putc('\n', stderr);
ret = FALSE; ret = FALSE;
......
...@@ -274,8 +274,9 @@ btr_cur_search_to_nth_level( ...@@ -274,8 +274,9 @@ btr_cur_search_to_nth_level(
#ifdef BTR_CUR_ADAPT #ifdef BTR_CUR_ADAPT
btr_search_t* info; btr_search_t* info;
#endif #endif
mem_heap_t* heap; mem_heap_t* heap = NULL;
ulint* offsets; ulint offsets_[100] = { 100, };
ulint* offsets = offsets_;
/* Currently, PAGE_CUR_LE is the only search mode used for searches /* Currently, PAGE_CUR_LE is the only search mode used for searches
ending to upper levels */ ending to upper levels */
...@@ -395,8 +396,6 @@ btr_cur_search_to_nth_level( ...@@ -395,8 +396,6 @@ btr_cur_search_to_nth_level(
break; break;
} }
heap = mem_heap_create(100);
offsets = NULL;
/* Loop and search until we arrive at the desired level */ /* Loop and search until we arrive at the desired level */
for (;;) { for (;;) {
...@@ -431,7 +430,9 @@ retry_page_get: ...@@ -431,7 +430,9 @@ retry_page_get:
cursor->thr)) { cursor->thr)) {
/* Insertion to the insert buffer succeeded */ /* Insertion to the insert buffer succeeded */
cursor->flag = BTR_CUR_INSERT_TO_IBUF; cursor->flag = BTR_CUR_INSERT_TO_IBUF;
if (heap) {
mem_heap_free(heap); mem_heap_free(heap);
}
return; return;
} }
...@@ -517,13 +518,15 @@ retry_page_get: ...@@ -517,13 +518,15 @@ retry_page_get:
guess = NULL; guess = NULL;
node_ptr = page_cur_get_rec(page_cursor); node_ptr = page_cur_get_rec(page_cursor);
offsets = rec_reget_offsets(node_ptr, cursor->index, offsets = rec_get_offsets(node_ptr, cursor->index, offsets,
offsets, ULINT_UNDEFINED, heap); ULINT_UNDEFINED, &heap);
/* Go to the child node */ /* Go to the child node */
page_no = btr_node_ptr_get_child_page_no(node_ptr, offsets); page_no = btr_node_ptr_get_child_page_no(node_ptr, offsets);
} }
if (heap) {
mem_heap_free(heap); mem_heap_free(heap);
}
if (level == 0) { if (level == 0) {
cursor->low_match = low_match; cursor->low_match = low_match;
...@@ -574,8 +577,9 @@ btr_cur_open_at_index_side( ...@@ -574,8 +577,9 @@ btr_cur_open_at_index_side(
rec_t* node_ptr; rec_t* node_ptr;
ulint estimate; ulint estimate;
ulint savepoint; ulint savepoint;
mem_heap_t* heap; mem_heap_t* heap = NULL;
ulint* offsets = NULL; ulint offsets_[100] = { 100, };
ulint* offsets = offsets_;
estimate = latch_mode & BTR_ESTIMATE; estimate = latch_mode & BTR_ESTIMATE;
latch_mode = latch_mode & ~BTR_ESTIMATE; latch_mode = latch_mode & ~BTR_ESTIMATE;
...@@ -600,7 +604,6 @@ btr_cur_open_at_index_side( ...@@ -600,7 +604,6 @@ btr_cur_open_at_index_side(
page_no = dict_tree_get_page(tree); page_no = dict_tree_get_page(tree);
height = ULINT_UNDEFINED; height = ULINT_UNDEFINED;
heap = mem_heap_create(100);
for (;;) { for (;;) {
page = buf_page_get_gen(space, page_no, RW_NO_LATCH, NULL, page = buf_page_get_gen(space, page_no, RW_NO_LATCH, NULL,
...@@ -670,13 +673,15 @@ btr_cur_open_at_index_side( ...@@ -670,13 +673,15 @@ btr_cur_open_at_index_side(
height--; height--;
node_ptr = page_cur_get_rec(page_cursor); node_ptr = page_cur_get_rec(page_cursor);
offsets = rec_reget_offsets(node_ptr, cursor->index, offsets = rec_get_offsets(node_ptr, cursor->index, offsets,
offsets, ULINT_UNDEFINED, heap); ULINT_UNDEFINED, &heap);
/* Go to the child node */ /* Go to the child node */
page_no = btr_node_ptr_get_child_page_no(node_ptr, offsets); page_no = btr_node_ptr_get_child_page_no(node_ptr, offsets);
} }
if (heap) {
mem_heap_free(heap); mem_heap_free(heap);
}
} }
/************************************************************************** /**************************************************************************
...@@ -697,8 +702,9 @@ btr_cur_open_at_rnd_pos( ...@@ -697,8 +702,9 @@ btr_cur_open_at_rnd_pos(
ulint space; ulint space;
ulint height; ulint height;
rec_t* node_ptr; rec_t* node_ptr;
mem_heap_t* heap = mem_heap_create(100); mem_heap_t* heap = NULL;
ulint* offsets = NULL; ulint offsets_[100] = { 100, };
ulint* offsets = offsets_;
tree = index->tree; tree = index->tree;
...@@ -747,13 +753,15 @@ btr_cur_open_at_rnd_pos( ...@@ -747,13 +753,15 @@ btr_cur_open_at_rnd_pos(
height--; height--;
node_ptr = page_cur_get_rec(page_cursor); node_ptr = page_cur_get_rec(page_cursor);
offsets = rec_reget_offsets(node_ptr, cursor->index, offsets = rec_get_offsets(node_ptr, cursor->index, offsets,
offsets, ULINT_UNDEFINED, heap); ULINT_UNDEFINED, &heap);
/* Go to the child node */ /* Go to the child node */
page_no = btr_node_ptr_get_child_page_no(node_ptr, offsets); page_no = btr_node_ptr_get_child_page_no(node_ptr, offsets);
} }
if (heap) {
mem_heap_free(heap); mem_heap_free(heap);
}
} }
/*==================== B-TREE INSERT =========================*/ /*==================== B-TREE INSERT =========================*/
...@@ -1242,11 +1250,14 @@ btr_cur_upd_lock_and_undo( ...@@ -1242,11 +1250,14 @@ btr_cur_upd_lock_and_undo(
err = DB_SUCCESS; err = DB_SUCCESS;
if (!(flags & BTR_NO_LOCKING_FLAG)) { if (!(flags & BTR_NO_LOCKING_FLAG)) {
mem_heap_t* heap = mem_heap_create(100); mem_heap_t* heap = NULL;
ulint offsets_[100] = { 100, };
err = lock_clust_rec_modify_check_and_lock(flags, rec, index, err = lock_clust_rec_modify_check_and_lock(flags, rec, index,
rec_get_offsets(rec, index, ULINT_UNDEFINED, heap), rec_get_offsets(rec, index, offsets_,
thr); ULINT_UNDEFINED, &heap), thr);
if (heap) {
mem_heap_free(heap); mem_heap_free(heap);
}
if (err != DB_SUCCESS) { if (err != DB_SUCCESS) {
return(err); return(err);
...@@ -1374,7 +1385,7 @@ btr_cur_parse_update_in_place( ...@@ -1374,7 +1385,7 @@ btr_cur_parse_update_in_place(
/* We do not need to reserve btr_search_latch, as the page is only /* We do not need to reserve btr_search_latch, as the page is only
being recovered, and there cannot be a hash index to it. */ being recovered, and there cannot be a hash index to it. */
offsets = rec_get_offsets(rec, index, ULINT_UNDEFINED, heap); offsets = rec_get_offsets(rec, index, NULL, ULINT_UNDEFINED, &heap);
if (!(flags & BTR_KEEP_SYS_FLAG)) { if (!(flags & BTR_KEEP_SYS_FLAG)) {
row_upd_rec_sys_fields_in_recovery(rec, offsets, row_upd_rec_sys_fields_in_recovery(rec, offsets,
...@@ -1413,18 +1424,19 @@ btr_cur_update_in_place( ...@@ -1413,18 +1424,19 @@ btr_cur_update_in_place(
dulint roll_ptr = ut_dulint_zero; dulint roll_ptr = ut_dulint_zero;
trx_t* trx; trx_t* trx;
ibool was_delete_marked; ibool was_delete_marked;
mem_heap_t* heap; mem_heap_t* heap = NULL;
const ulint* offsets; ulint offsets_[100] = { 100, };
ulint* offsets = offsets_;
rec = btr_cur_get_rec(cursor); rec = btr_cur_get_rec(cursor);
index = cursor->index; index = cursor->index;
trx = thr_get_trx(thr); trx = thr_get_trx(thr);
heap = mem_heap_create(100); heap = mem_heap_create(100);
offsets = rec_get_offsets(rec, index, ULINT_UNDEFINED, heap); offsets = rec_get_offsets(rec, index, offsets, ULINT_UNDEFINED, &heap);
if (btr_cur_print_record_ops && thr) { if (btr_cur_print_record_ops && thr) {
btr_cur_trx_report(trx, index, "update "); btr_cur_trx_report(trx, index, "update ");
rec_print(stderr, rec, offsets); rec_print_new(stderr, rec, offsets);
} }
/* Do lock checking and undo logging */ /* Do lock checking and undo logging */
...@@ -1432,7 +1444,9 @@ btr_cur_update_in_place( ...@@ -1432,7 +1444,9 @@ btr_cur_update_in_place(
thr, &roll_ptr); thr, &roll_ptr);
if (err != DB_SUCCESS) { if (err != DB_SUCCESS) {
if (heap) {
mem_heap_free(heap); mem_heap_free(heap);
}
return(err); return(err);
} }
...@@ -1477,7 +1491,9 @@ btr_cur_update_in_place( ...@@ -1477,7 +1491,9 @@ btr_cur_update_in_place(
btr_cur_unmark_extern_fields(rec, mtr, offsets); btr_cur_unmark_extern_fields(rec, mtr, offsets);
} }
if (heap) {
mem_heap_free(heap); mem_heap_free(heap);
}
return(DB_SUCCESS); return(DB_SUCCESS);
} }
...@@ -1526,11 +1542,11 @@ btr_cur_optimistic_update( ...@@ -1526,11 +1542,11 @@ btr_cur_optimistic_update(
index = cursor->index; index = cursor->index;
heap = mem_heap_create(1024); heap = mem_heap_create(1024);
offsets = rec_get_offsets(rec, index, ULINT_UNDEFINED, heap); offsets = rec_get_offsets(rec, index, NULL, ULINT_UNDEFINED, &heap);
if (btr_cur_print_record_ops && thr) { if (btr_cur_print_record_ops && thr) {
btr_cur_trx_report(thr_get_trx(thr), index, "update "); btr_cur_trx_report(thr_get_trx(thr), index, "update ");
rec_print(stderr, rec, offsets); rec_print_new(stderr, rec, offsets);
} }
ut_ad(mtr_memo_contains(mtr, buf_block_align(page), ut_ad(mtr_memo_contains(mtr, buf_block_align(page),
...@@ -1646,8 +1662,8 @@ btr_cur_optimistic_update( ...@@ -1646,8 +1662,8 @@ btr_cur_optimistic_update(
/* The new inserted record owns its possible externally /* The new inserted record owns its possible externally
stored fields */ stored fields */
offsets = rec_reget_offsets(rec, index, offsets = rec_get_offsets(rec, index, offsets,
offsets, ULINT_UNDEFINED, heap); ULINT_UNDEFINED, &heap);
btr_cur_unmark_extern_fields(rec, mtr, offsets); btr_cur_unmark_extern_fields(rec, mtr, offsets);
} }
...@@ -1801,7 +1817,7 @@ btr_cur_pessimistic_update( ...@@ -1801,7 +1817,7 @@ btr_cur_pessimistic_update(
} }
heap = mem_heap_create(1024); heap = mem_heap_create(1024);
offsets = rec_get_offsets(rec, index, ULINT_UNDEFINED, heap); offsets = rec_get_offsets(rec, index, NULL, ULINT_UNDEFINED, &heap);
trx = thr_get_trx(thr); trx = thr_get_trx(thr);
...@@ -1836,8 +1852,8 @@ btr_cur_pessimistic_update( ...@@ -1836,8 +1852,8 @@ btr_cur_pessimistic_update(
ext_vect = mem_heap_alloc(heap, sizeof(ulint) ext_vect = mem_heap_alloc(heap, sizeof(ulint)
* dict_index_get_n_fields(index)); * dict_index_get_n_fields(index));
ut_ad(!cursor->index->table->comp || !rec_get_node_ptr_flag(rec)); ut_ad(!cursor->index->table->comp || !rec_get_node_ptr_flag(rec));
offsets = rec_reget_offsets(rec, index, offsets = rec_get_offsets(rec, index, offsets,
offsets, ULINT_UNDEFINED, heap); ULINT_UNDEFINED, &heap);
n_ext_vect = btr_push_update_extern_fields(ext_vect, offsets, update); n_ext_vect = btr_push_update_extern_fields(ext_vect, offsets, update);
if (rec_get_converted_size(index, new_entry) >= if (rec_get_converted_size(index, new_entry) >=
...@@ -1877,8 +1893,8 @@ btr_cur_pessimistic_update( ...@@ -1877,8 +1893,8 @@ btr_cur_pessimistic_update(
ut_a(rec || optim_err != DB_UNDERFLOW); ut_a(rec || optim_err != DB_UNDERFLOW);
if (rec) { if (rec) {
offsets = rec_reget_offsets(rec, index, offsets = rec_get_offsets(rec, index, offsets,
offsets, ULINT_UNDEFINED, heap); ULINT_UNDEFINED, &heap);
lock_rec_restore_from_page_infimum(rec, page); lock_rec_restore_from_page_infimum(rec, page);
rec_set_field_extern_bits(rec, index, rec_set_field_extern_bits(rec, index,
...@@ -1918,8 +1934,7 @@ btr_cur_pessimistic_update( ...@@ -1918,8 +1934,7 @@ btr_cur_pessimistic_update(
ut_a(dummy_big_rec == NULL); ut_a(dummy_big_rec == NULL);
rec_set_field_extern_bits(rec, index, ext_vect, n_ext_vect, mtr); rec_set_field_extern_bits(rec, index, ext_vect, n_ext_vect, mtr);
offsets = rec_reget_offsets(rec, index, offsets = rec_get_offsets(rec, index, offsets, ULINT_UNDEFINED, &heap);
offsets, ULINT_UNDEFINED, heap);
if (!rec_get_deleted_flag(rec, rec_offs_comp(offsets))) { if (!rec_get_deleted_flag(rec, rec_offs_comp(offsets))) {
/* The new inserted record owns its possible externally /* The new inserted record owns its possible externally
...@@ -2048,13 +2063,16 @@ btr_cur_parse_del_mark_set_clust_rec( ...@@ -2048,13 +2063,16 @@ btr_cur_parse_del_mark_set_clust_rec(
rec = page + offset; rec = page + offset;
if (!(flags & BTR_KEEP_SYS_FLAG)) { if (!(flags & BTR_KEEP_SYS_FLAG)) {
mem_heap_t* heap = mem_heap_create(100); mem_heap_t* heap = NULL;
ulint offsets_[100] = { 100, };
row_upd_rec_sys_fields_in_recovery(rec, row_upd_rec_sys_fields_in_recovery(rec,
rec_get_offsets(rec, index, rec_get_offsets(rec, index, offsets_,
ULINT_UNDEFINED, heap), ULINT_UNDEFINED, &heap),
pos, trx_id, roll_ptr); pos, trx_id, roll_ptr);
if (heap) {
mem_heap_free(heap); mem_heap_free(heap);
} }
}
/* We do not need to reserve btr_search_latch, as the page /* We do not need to reserve btr_search_latch, as the page
is only being recovered, and there cannot be a hash index to is only being recovered, and there cannot be a hash index to
...@@ -2089,17 +2107,17 @@ btr_cur_del_mark_set_clust_rec( ...@@ -2089,17 +2107,17 @@ btr_cur_del_mark_set_clust_rec(
ulint err; ulint err;
rec_t* rec; rec_t* rec;
trx_t* trx; trx_t* trx;
mem_heap_t* heap; mem_heap_t* heap = NULL;
const ulint* offsets; ulint offsets_[100] = { 100, };
ulint* offsets = offsets_;
rec = btr_cur_get_rec(cursor); rec = btr_cur_get_rec(cursor);
index = cursor->index; index = cursor->index;
heap = mem_heap_create(100); offsets = rec_get_offsets(rec, index, offsets, ULINT_UNDEFINED, &heap);
offsets = rec_get_offsets(rec, index, ULINT_UNDEFINED, heap);
if (btr_cur_print_record_ops && thr) { if (btr_cur_print_record_ops && thr) {
btr_cur_trx_report(thr_get_trx(thr), index, "del mark "); btr_cur_trx_report(thr_get_trx(thr), index, "del mark ");
rec_print(stderr, rec, offsets); rec_print_new(stderr, rec, offsets);
} }
ut_ad(index->type & DICT_CLUSTERED); ut_ad(index->type & DICT_CLUSTERED);
...@@ -2110,7 +2128,9 @@ btr_cur_del_mark_set_clust_rec( ...@@ -2110,7 +2128,9 @@ btr_cur_del_mark_set_clust_rec(
if (err != DB_SUCCESS) { if (err != DB_SUCCESS) {
if (heap) {
mem_heap_free(heap); mem_heap_free(heap);
}
return(err); return(err);
} }
...@@ -2119,7 +2139,9 @@ btr_cur_del_mark_set_clust_rec( ...@@ -2119,7 +2139,9 @@ btr_cur_del_mark_set_clust_rec(
&roll_ptr); &roll_ptr);
if (err != DB_SUCCESS) { if (err != DB_SUCCESS) {
if (heap) {
mem_heap_free(heap); mem_heap_free(heap);
}
return(err); return(err);
} }
...@@ -2143,7 +2165,9 @@ btr_cur_del_mark_set_clust_rec( ...@@ -2143,7 +2165,9 @@ btr_cur_del_mark_set_clust_rec(
btr_cur_del_mark_set_clust_rec_log(flags, rec, index, val, trx, btr_cur_del_mark_set_clust_rec_log(flags, rec, index, val, trx,
roll_ptr, mtr); roll_ptr, mtr);
if (heap) {
mem_heap_free(heap); mem_heap_free(heap);
}
return(DB_SUCCESS); return(DB_SUCCESS);
} }
...@@ -2246,12 +2270,9 @@ btr_cur_del_mark_set_sec_rec( ...@@ -2246,12 +2270,9 @@ btr_cur_del_mark_set_sec_rec(
rec = btr_cur_get_rec(cursor); rec = btr_cur_get_rec(cursor);
if (btr_cur_print_record_ops && thr) { if (btr_cur_print_record_ops && thr) {
mem_heap_t* heap = mem_heap_create(100);
btr_cur_trx_report(thr_get_trx(thr), cursor->index, btr_cur_trx_report(thr_get_trx(thr), cursor->index,
"del mark "); "del mark ");
rec_print(stderr, rec, rec_get_offsets(rec, cursor->index, rec_print(stderr, rec, cursor->index);
ULINT_UNDEFINED, heap));
mem_heap_free(heap);
} }
err = lock_sec_rec_modify_check_and_lock(flags, rec, cursor->index, err = lock_sec_rec_modify_check_and_lock(flags, rec, cursor->index,
...@@ -2375,9 +2396,10 @@ btr_cur_optimistic_delete( ...@@ -2375,9 +2396,10 @@ btr_cur_optimistic_delete(
{ {
page_t* page; page_t* page;
ulint max_ins_size; ulint max_ins_size;
mem_heap_t* heap;
rec_t* rec; rec_t* rec;
const ulint* offsets; mem_heap_t* heap = NULL;
ulint offsets_[100] = { 100, };
ulint* offsets = offsets_;
ut_ad(mtr_memo_contains(mtr, buf_block_align(btr_cur_get_page(cursor)), ut_ad(mtr_memo_contains(mtr, buf_block_align(btr_cur_get_page(cursor)),
MTR_MEMO_PAGE_X_FIX)); MTR_MEMO_PAGE_X_FIX));
...@@ -2387,9 +2409,9 @@ btr_cur_optimistic_delete( ...@@ -2387,9 +2409,9 @@ btr_cur_optimistic_delete(
ut_ad(btr_page_get_level(page, mtr) == 0); ut_ad(btr_page_get_level(page, mtr) == 0);
heap = mem_heap_create(100);
rec = btr_cur_get_rec(cursor); rec = btr_cur_get_rec(cursor);
offsets = rec_get_offsets(rec, cursor->index, ULINT_UNDEFINED, heap); offsets = rec_get_offsets(rec, cursor->index, offsets,
ULINT_UNDEFINED, &heap);
if (!rec_offs_any_extern(offsets) if (!rec_offs_any_extern(offsets)
&& btr_cur_can_delete_without_compress( && btr_cur_can_delete_without_compress(
...@@ -2406,11 +2428,15 @@ btr_cur_optimistic_delete( ...@@ -2406,11 +2428,15 @@ btr_cur_optimistic_delete(
ibuf_update_free_bits_low(cursor->index, page, max_ins_size, ibuf_update_free_bits_low(cursor->index, page, max_ins_size,
mtr); mtr);
if (heap) {
mem_heap_free(heap); mem_heap_free(heap);
}
return(TRUE); return(TRUE);
} }
if (heap) {
mem_heap_free(heap); mem_heap_free(heap);
}
return(FALSE); return(FALSE);
} }
...@@ -2487,8 +2513,9 @@ btr_cur_pessimistic_delete( ...@@ -2487,8 +2513,9 @@ btr_cur_pessimistic_delete(
: !rec_get_1byte_offs_flag(rec)) { : !rec_get_1byte_offs_flag(rec)) {
btr_rec_free_externally_stored_fields(cursor->index, btr_rec_free_externally_stored_fields(cursor->index,
rec, rec_get_offsets(rec, cursor->index, rec, rec_get_offsets(rec, cursor->index,
ULINT_UNDEFINED, heap), NULL, ULINT_UNDEFINED, &heap),
in_rollback, mtr); in_rollback, mtr);
mem_heap_empty(heap);
} }
if ((page_get_n_recs(page) < 2) if ((page_get_n_recs(page) < 2)
...@@ -2772,13 +2799,14 @@ btr_estimate_number_of_different_key_vals( ...@@ -2772,13 +2799,14 @@ btr_estimate_number_of_different_key_vals(
ulint j; ulint j;
ulint add_on; ulint add_on;
mtr_t mtr; mtr_t mtr;
mem_heap_t* heap; mem_heap_t* heap = NULL;
ulint* offsets1 = 0; ulint offsets1_[100] = { 100, };
ulint* offsets2 = 0; ulint offsets2_[100] = { 100, };
ulint* offsets1 = offsets1_;
ulint* offsets2 = offsets2_;
n_cols = dict_index_get_n_unique(index); n_cols = dict_index_get_n_unique(index);
heap = mem_heap_create(100);
n_diff = mem_alloc((n_cols + 1) * sizeof(ib_longlong)); n_diff = mem_alloc((n_cols + 1) * sizeof(ib_longlong));
for (j = 0; j <= n_cols; j++) { for (j = 0; j <= n_cols; j++) {
...@@ -2813,10 +2841,10 @@ btr_estimate_number_of_different_key_vals( ...@@ -2813,10 +2841,10 @@ btr_estimate_number_of_different_key_vals(
rec_t* next_rec = page_rec_get_next(rec); rec_t* next_rec = page_rec_get_next(rec);
matched_fields = 0; matched_fields = 0;
matched_bytes = 0; matched_bytes = 0;
offsets1 = rec_reget_offsets(rec, index, offsets1 = rec_get_offsets(rec, index, offsets1,
offsets1, ULINT_UNDEFINED, heap); ULINT_UNDEFINED, &heap);
offsets2 = rec_reget_offsets(next_rec, index, offsets2 = rec_get_offsets(next_rec, index, offsets2,
offsets2, n_cols, heap); n_cols, &heap);
cmp_rec_rec_with_match(rec, next_rec, cmp_rec_rec_with_match(rec, next_rec,
offsets1, offsets2, offsets1, offsets2,
...@@ -2856,8 +2884,8 @@ btr_estimate_number_of_different_key_vals( ...@@ -2856,8 +2884,8 @@ btr_estimate_number_of_different_key_vals(
} }
} }
offsets1 = rec_reget_offsets(rec, index, offsets1 = rec_get_offsets(rec, index, offsets1,
offsets1, ULINT_UNDEFINED, heap); ULINT_UNDEFINED, &heap);
total_external_size += total_external_size +=
btr_rec_get_externally_stored_len(rec, btr_rec_get_externally_stored_len(rec,
offsets1); offsets1);
...@@ -2901,7 +2929,9 @@ btr_estimate_number_of_different_key_vals( ...@@ -2901,7 +2929,9 @@ btr_estimate_number_of_different_key_vals(
} }
mem_free(n_diff); mem_free(n_diff);
if (heap) {
mem_heap_free(heap); mem_heap_free(heap);
}
} }
/*================== EXTERNAL STORAGE OF BIG FIELDS ===================*/ /*================== EXTERNAL STORAGE OF BIG FIELDS ===================*/
......
...@@ -262,9 +262,10 @@ btr_pcur_restore_position( ...@@ -262,9 +262,10 @@ btr_pcur_restore_position(
heap = mem_heap_create(256); heap = mem_heap_create(256);
offsets1 = rec_get_offsets(cursor->old_rec, offsets1 = rec_get_offsets(cursor->old_rec,
index, ULINT_UNDEFINED, heap); index, NULL,
offsets2 = rec_get_offsets(rec, cursor->old_n_fields, &heap);
index, ULINT_UNDEFINED, heap); offsets2 = rec_get_offsets(rec, index, NULL,
cursor->old_n_fields, &heap);
ut_ad(cmp_rec_rec(cursor->old_rec, ut_ad(cmp_rec_rec(cursor->old_rec,
rec, offsets1, offsets2, rec, offsets1, offsets2,
...@@ -310,7 +311,7 @@ btr_pcur_restore_position( ...@@ -310,7 +311,7 @@ btr_pcur_restore_position(
&& 0 == cmp_dtuple_rec(tuple, btr_pcur_get_rec(cursor), && 0 == cmp_dtuple_rec(tuple, btr_pcur_get_rec(cursor),
rec_get_offsets(btr_pcur_get_rec(cursor), rec_get_offsets(btr_pcur_get_rec(cursor),
btr_pcur_get_btr_cur(cursor)->index, btr_pcur_get_btr_cur(cursor)->index,
ULINT_UNDEFINED, heap))) { NULL, ULINT_UNDEFINED, &heap))) {
/* We have to store the NEW value for the modify clock, since /* We have to store the NEW value for the modify clock, since
the cursor can now be on a different page! But we can retain the cursor can now be on a different page! But we can retain
......
...@@ -419,7 +419,9 @@ btr_search_update_hash_ref( ...@@ -419,7 +419,9 @@ btr_search_update_hash_ref(
&& (block->curr_n_fields == info->n_fields) && (block->curr_n_fields == info->n_fields)
&& (block->curr_n_bytes == info->n_bytes) && (block->curr_n_bytes == info->n_bytes)
&& (block->curr_side == info->side)) { && (block->curr_side == info->side)) {
mem_heap_t* heap; mem_heap_t* heap = NULL;
ulint offsets_[100] = { 100, };
rec = btr_cur_get_rec(cursor); rec = btr_cur_get_rec(cursor);
if (!page_rec_is_user_rec(rec)) { if (!page_rec_is_user_rec(rec)) {
...@@ -428,11 +430,13 @@ btr_search_update_hash_ref( ...@@ -428,11 +430,13 @@ btr_search_update_hash_ref(
} }
tree_id = ((cursor->index)->tree)->id; tree_id = ((cursor->index)->tree)->id;
heap = mem_heap_create(100);
fold = rec_fold(rec, rec_get_offsets(rec, cursor->index, fold = rec_fold(rec, rec_get_offsets(rec, cursor->index,
ULINT_UNDEFINED, heap), block->curr_n_fields, offsets_, ULINT_UNDEFINED, &heap),
block->curr_n_fields,
block->curr_n_bytes, tree_id); block->curr_n_bytes, tree_id);
if (heap) {
mem_heap_free(heap); mem_heap_free(heap);
}
#ifdef UNIV_SYNC_DEBUG #ifdef UNIV_SYNC_DEBUG
ut_ad(rw_lock_own(&btr_search_latch, RW_LOCK_EX)); ut_ad(rw_lock_own(&btr_search_latch, RW_LOCK_EX));
#endif /* UNIV_SYNC_DEBUG */ #endif /* UNIV_SYNC_DEBUG */
...@@ -547,8 +551,10 @@ btr_search_check_guess( ...@@ -547,8 +551,10 @@ btr_search_check_guess(
ulint match; ulint match;
ulint bytes; ulint bytes;
int cmp; int cmp;
mem_heap_t* heap = mem_heap_create(100); mem_heap_t* heap = NULL;
ulint* offsets = NULL; ulint offsets_[100] = { 100, };
ulint* offsets = offsets_;
ibool success = FALSE;
n_unique = dict_index_get_n_unique_in_tree(cursor->index); n_unique = dict_index_get_n_unique_in_tree(cursor->index);
...@@ -560,47 +566,43 @@ btr_search_check_guess( ...@@ -560,47 +566,43 @@ btr_search_check_guess(
match = 0; match = 0;
bytes = 0; bytes = 0;
offsets = rec_get_offsets(rec, cursor->index, n_unique, heap); offsets = rec_get_offsets(rec, cursor->index, offsets,
n_unique, &heap);
cmp = page_cmp_dtuple_rec_with_match(tuple, rec, cmp = page_cmp_dtuple_rec_with_match(tuple, rec,
offsets, &match, &bytes); offsets, &match, &bytes);
if (mode == PAGE_CUR_GE) { if (mode == PAGE_CUR_GE) {
if (cmp == 1) { if (cmp == 1) {
mem_heap_free(heap); goto exit_func;
return(FALSE);
} }
cursor->up_match = match; cursor->up_match = match;
if (match >= n_unique) { if (match >= n_unique) {
mem_heap_free(heap); success = TRUE;
return(TRUE); goto exit_func;
} }
} else if (mode == PAGE_CUR_LE) { } else if (mode == PAGE_CUR_LE) {
if (cmp == -1) { if (cmp == -1) {
mem_heap_free(heap); goto exit_func;
return(FALSE);
} }
cursor->low_match = match; cursor->low_match = match;
} else if (mode == PAGE_CUR_G) { } else if (mode == PAGE_CUR_G) {
if (cmp != -1) { if (cmp != -1) {
mem_heap_free(heap); goto exit_func;
return(FALSE);
} }
} else if (mode == PAGE_CUR_L) { } else if (mode == PAGE_CUR_L) {
if (cmp != 1) { if (cmp != 1) {
mem_heap_free(heap); goto exit_func;
return(FALSE);
} }
} }
if (can_only_compare_to_cursor_rec) { if (can_only_compare_to_cursor_rec) {
/* Since we could not determine if our guess is right just by /* Since we could not determine if our guess is right just by
looking at the record under the cursor, return FALSE */ looking at the record under the cursor, return FALSE */
mem_heap_free(heap); goto exit_func;
return(FALSE);
} }
match = 0; match = 0;
...@@ -613,28 +615,21 @@ btr_search_check_guess( ...@@ -613,28 +615,21 @@ btr_search_check_guess(
prev_rec = page_rec_get_prev(rec); prev_rec = page_rec_get_prev(rec);
if (prev_rec == page_get_infimum_rec(page)) { if (prev_rec == page_get_infimum_rec(page)) {
mem_heap_free(heap); success = btr_page_get_prev(page, mtr) == FIL_NULL;
return(btr_page_get_prev(page, mtr) == FIL_NULL); goto exit_func;
} }
offsets = rec_reget_offsets(prev_rec, cursor->index, offsets = rec_get_offsets(prev_rec, cursor->index, offsets,
offsets, n_unique, heap); n_unique, &heap);
cmp = page_cmp_dtuple_rec_with_match(tuple, prev_rec, cmp = page_cmp_dtuple_rec_with_match(tuple, prev_rec,
offsets, &match, &bytes); offsets, &match, &bytes);
mem_heap_free(heap);
if (mode == PAGE_CUR_GE) { if (mode == PAGE_CUR_GE) {
if (cmp != 1) { success = cmp == 1;
return(FALSE);
}
} else { } else {
if (cmp == -1) { success = cmp != -1;
return(FALSE);
}
} }
return(TRUE); goto exit_func;
} }
ut_ad(rec != page_get_supremum_rec(page)); ut_ad(rec != page_get_supremum_rec(page));
...@@ -642,39 +637,30 @@ btr_search_check_guess( ...@@ -642,39 +637,30 @@ btr_search_check_guess(
next_rec = page_rec_get_next(rec); next_rec = page_rec_get_next(rec);
if (next_rec == page_get_supremum_rec(page)) { if (next_rec == page_get_supremum_rec(page)) {
mem_heap_free(heap);
if (btr_page_get_next(page, mtr) == FIL_NULL) { if (btr_page_get_next(page, mtr) == FIL_NULL) {
cursor->up_match = 0; cursor->up_match = 0;
success = TRUE;
return(TRUE);
} }
return(FALSE); goto exit_func;
} }
offsets = rec_reget_offsets(next_rec, cursor->index, offsets = rec_get_offsets(next_rec, cursor->index, offsets,
offsets, n_unique, heap); n_unique, &heap);
cmp = page_cmp_dtuple_rec_with_match(tuple, next_rec, cmp = page_cmp_dtuple_rec_with_match(tuple, next_rec,
offsets, &match, &bytes); offsets, &match, &bytes);
mem_heap_free(heap);
if (mode == PAGE_CUR_LE) { if (mode == PAGE_CUR_LE) {
if (cmp != -1) { success = cmp == -1;
return(FALSE);
}
cursor->up_match = match; cursor->up_match = match;
} else { } else {
if (cmp == 1) { success = cmp != 1;
return(FALSE);
} }
exit_func:
if (heap) {
mem_heap_free(heap);
} }
return(success);
return(TRUE);
} }
/********************************************************************** /**********************************************************************
...@@ -997,14 +983,14 @@ btr_search_drop_page_hash_index( ...@@ -997,14 +983,14 @@ btr_search_drop_page_hash_index(
prev_fold = 0; prev_fold = 0;
heap = mem_heap_create(100); heap = NULL;
offsets = NULL; offsets = NULL;
while (rec != sup) { while (rec != sup) {
/* FIXME: in a mixed tree, not all records may have enough /* FIXME: in a mixed tree, not all records may have enough
ordering fields: */ ordering fields: */
offsets = rec_reget_offsets(rec, block->index, offsets = rec_get_offsets(rec, block->index,
offsets, n_fields + (n_bytes > 0), heap); offsets, n_fields + (n_bytes > 0), &heap);
fold = rec_fold(rec, offsets, n_fields, n_bytes, tree_id); fold = rec_fold(rec, offsets, n_fields, n_bytes, tree_id);
if (fold == prev_fold && prev_fold != 0) { if (fold == prev_fold && prev_fold != 0) {
...@@ -1022,7 +1008,9 @@ next_rec: ...@@ -1022,7 +1008,9 @@ next_rec:
prev_fold = fold; prev_fold = fold;
} }
if (heap) {
mem_heap_free(heap); mem_heap_free(heap);
}
rw_lock_x_lock(&btr_search_latch); rw_lock_x_lock(&btr_search_latch);
...@@ -1109,8 +1097,9 @@ btr_search_build_page_hash_index( ...@@ -1109,8 +1097,9 @@ btr_search_build_page_hash_index(
ulint* folds; ulint* folds;
rec_t** recs; rec_t** recs;
ulint i; ulint i;
mem_heap_t* heap; mem_heap_t* heap = NULL;
ulint* offsets; ulint offsets_[100] = { 100, };
ulint* offsets = offsets_;
ut_ad(index); ut_ad(index);
...@@ -1161,7 +1150,6 @@ btr_search_build_page_hash_index( ...@@ -1161,7 +1150,6 @@ btr_search_build_page_hash_index(
folds = mem_alloc(n_recs * sizeof(ulint)); folds = mem_alloc(n_recs * sizeof(ulint));
recs = mem_alloc(n_recs * sizeof(rec_t*)); recs = mem_alloc(n_recs * sizeof(rec_t*));
heap = mem_heap_create(100);
n_cached = 0; n_cached = 0;
...@@ -1172,7 +1160,8 @@ btr_search_build_page_hash_index( ...@@ -1172,7 +1160,8 @@ btr_search_build_page_hash_index(
rec = page_get_infimum_rec(page); rec = page_get_infimum_rec(page);
rec = page_rec_get_next(rec); rec = page_rec_get_next(rec);
offsets = rec_get_offsets(rec, index, n_fields + (n_bytes > 0), heap); offsets = rec_get_offsets(rec, index, offsets,
n_fields + (n_bytes > 0), &heap);
if (rec != sup) { if (rec != sup) {
ut_a(n_fields <= rec_offs_n_fields(offsets)); ut_a(n_fields <= rec_offs_n_fields(offsets));
...@@ -1208,8 +1197,8 @@ btr_search_build_page_hash_index( ...@@ -1208,8 +1197,8 @@ btr_search_build_page_hash_index(
break; break;
} }
offsets = rec_reget_offsets(next_rec, index, offsets = rec_get_offsets(next_rec, index, offsets,
offsets, n_fields + (n_bytes > 0), heap); n_fields + (n_bytes > 0), &heap);
next_fold = rec_fold(next_rec, offsets, n_fields, next_fold = rec_fold(next_rec, offsets, n_fields,
n_bytes, tree_id); n_bytes, tree_id);
...@@ -1260,7 +1249,9 @@ exit_func: ...@@ -1260,7 +1249,9 @@ exit_func:
mem_free(folds); mem_free(folds);
mem_free(recs); mem_free(recs);
if (heap) {
mem_heap_free(heap); mem_heap_free(heap);
}
} }
/************************************************************************ /************************************************************************
...@@ -1350,7 +1341,8 @@ btr_search_update_hash_on_delete( ...@@ -1350,7 +1341,8 @@ btr_search_update_hash_on_delete(
ulint fold; ulint fold;
dulint tree_id; dulint tree_id;
ibool found; ibool found;
mem_heap_t* heap; ulint offsets_[100] = { 100, };
mem_heap_t* heap = NULL;
rec = btr_cur_get_rec(cursor); rec = btr_cur_get_rec(cursor);
...@@ -1371,11 +1363,12 @@ btr_search_update_hash_on_delete( ...@@ -1371,11 +1363,12 @@ btr_search_update_hash_on_delete(
table = btr_search_sys->hash_index; table = btr_search_sys->hash_index;
tree_id = cursor->index->tree->id; tree_id = cursor->index->tree->id;
heap = mem_heap_create(100); fold = rec_fold(rec, rec_get_offsets(rec, cursor->index, offsets_,
fold = rec_fold(rec, rec_get_offsets(rec, cursor->index, ULINT_UNDEFINED, &heap), block->curr_n_fields,
ULINT_UNDEFINED, heap), block->curr_n_fields,
block->curr_n_bytes, tree_id); block->curr_n_bytes, tree_id);
if (heap) {
mem_heap_free(heap); mem_heap_free(heap);
}
rw_lock_x_lock(&btr_search_latch); rw_lock_x_lock(&btr_search_latch);
found = ha_search_and_delete_if_found(table, fold, rec); found = ha_search_and_delete_if_found(table, fold, rec);
...@@ -1458,8 +1451,9 @@ btr_search_update_hash_on_insert( ...@@ -1458,8 +1451,9 @@ btr_search_update_hash_on_insert(
ulint n_bytes; ulint n_bytes;
ulint side; ulint side;
ibool locked = FALSE; ibool locked = FALSE;
mem_heap_t* heap; mem_heap_t* heap = NULL;
ulint* offsets; ulint offsets_[100] = { 100, };
ulint* offsets = offsets_;
table = btr_search_sys->hash_index; table = btr_search_sys->hash_index;
...@@ -1490,21 +1484,20 @@ btr_search_update_hash_on_insert( ...@@ -1490,21 +1484,20 @@ btr_search_update_hash_on_insert(
next_rec = page_rec_get_next(ins_rec); next_rec = page_rec_get_next(ins_rec);
page = buf_frame_align(rec); page = buf_frame_align(rec);
heap = mem_heap_create(100); offsets = rec_get_offsets(ins_rec, cursor->index, offsets,
offsets = rec_get_offsets(ins_rec, cursor->index, ULINT_UNDEFINED, &heap);
ULINT_UNDEFINED, heap);
ins_fold = rec_fold(ins_rec, offsets, n_fields, n_bytes, tree_id); ins_fold = rec_fold(ins_rec, offsets, n_fields, n_bytes, tree_id);
if (next_rec != page_get_supremum_rec(page)) { if (next_rec != page_get_supremum_rec(page)) {
offsets = rec_reget_offsets(next_rec, cursor->index, offsets = rec_get_offsets(next_rec, cursor->index, offsets,
offsets, n_fields + (n_bytes > 0), heap); n_fields + (n_bytes > 0), &heap);
next_fold = rec_fold(next_rec, offsets, n_fields, next_fold = rec_fold(next_rec, offsets, n_fields,
n_bytes, tree_id); n_bytes, tree_id);
} }
if (rec != page_get_infimum_rec(page)) { if (rec != page_get_infimum_rec(page)) {
offsets = rec_reget_offsets(rec, cursor->index, offsets = rec_get_offsets(rec, cursor->index, offsets,
offsets, n_fields + (n_bytes > 0), heap); n_fields + (n_bytes > 0), &heap);
fold = rec_fold(rec, offsets, n_fields, n_bytes, tree_id); fold = rec_fold(rec, offsets, n_fields, n_bytes, tree_id);
} else { } else {
if (side == BTR_SEARCH_LEFT_SIDE) { if (side == BTR_SEARCH_LEFT_SIDE) {
...@@ -1575,7 +1568,9 @@ check_next_rec: ...@@ -1575,7 +1568,9 @@ check_next_rec:
} }
function_exit: function_exit:
if (heap) {
mem_heap_free(heap); mem_heap_free(heap);
}
if (locked) { if (locked) {
rw_lock_x_unlock(&btr_search_latch); rw_lock_x_unlock(&btr_search_latch);
} }
...@@ -1595,8 +1590,9 @@ btr_search_validate(void) ...@@ -1595,8 +1590,9 @@ btr_search_validate(void)
ulint n_page_dumps = 0; ulint n_page_dumps = 0;
ibool ok = TRUE; ibool ok = TRUE;
ulint i; ulint i;
mem_heap_t* heap = mem_heap_create(100); mem_heap_t* heap = NULL;
ulint* offsets = NULL; ulint offsets_[100] = { 100, };
ulint* offsets = offsets_;
rw_lock_x_lock(&btr_search_latch); rw_lock_x_lock(&btr_search_latch);
...@@ -1606,10 +1602,10 @@ btr_search_validate(void) ...@@ -1606,10 +1602,10 @@ btr_search_validate(void)
while (node != NULL) { while (node != NULL) {
block = buf_block_align(node->data); block = buf_block_align(node->data);
page = buf_frame_align(node->data); page = buf_frame_align(node->data);
offsets = rec_reget_offsets((rec_t*) node->data, offsets = rec_get_offsets((rec_t*) node->data,
block->index, offsets, block->index, offsets,
block->curr_n_fields block->curr_n_fields
+ (block->curr_n_bytes > 0), heap); + (block->curr_n_bytes > 0), &heap);
if (!block->is_hashed if (!block->is_hashed
|| node->fold != rec_fold((rec_t*)(node->data), || node->fold != rec_fold((rec_t*)(node->data),
...@@ -1635,7 +1631,8 @@ btr_search_validate(void) ...@@ -1635,7 +1631,8 @@ btr_search_validate(void)
btr_page_get_index_id(page))); btr_page_get_index_id(page)));
fputs("InnoDB: Record ", stderr); fputs("InnoDB: Record ", stderr);
rec_print(stderr, (rec_t*)node->data, offsets); rec_print_new(stderr, (rec_t*)node->data,
offsets);
fprintf(stderr, "\nInnoDB: on that page." fprintf(stderr, "\nInnoDB: on that page."
"Page mem address %p, is hashed %lu, n fields %lu, n bytes %lu\n" "Page mem address %p, is hashed %lu, n fields %lu, n bytes %lu\n"
"side %lu\n", "side %lu\n",
...@@ -1659,7 +1656,9 @@ btr_search_validate(void) ...@@ -1659,7 +1656,9 @@ btr_search_validate(void)
} }
rw_lock_x_unlock(&btr_search_latch); rw_lock_x_unlock(&btr_search_latch);
if (heap) {
mem_heap_free(heap); mem_heap_free(heap);
}
return(ok); return(ok);
} }
...@@ -67,6 +67,16 @@ rec_get_n_fields_old( ...@@ -67,6 +67,16 @@ rec_get_n_fields_old(
/* out: number of data fields */ /* out: number of data fields */
rec_t* rec); /* in: physical record */ rec_t* rec); /* in: physical record */
/********************************************************** /**********************************************************
The following function is used to get the number of fields
in a record. */
UNIV_INLINE
ulint
rec_get_n_fields(
/*=============*/
/* out: number of data fields */
rec_t* rec, /* in: physical record */
dict_index_t* index); /* in: record descriptor */
/**********************************************************
The following function is used to get the number of records The following function is used to get the number of records
owned by the previous directory record. */ owned by the previous directory record. */
UNIV_INLINE UNIV_INLINE
...@@ -188,45 +198,28 @@ rec_get_1byte_offs_flag( ...@@ -188,45 +198,28 @@ rec_get_1byte_offs_flag(
rec_t* rec); /* in: physical record */ rec_t* rec); /* in: physical record */
/********************************************************** /**********************************************************
The following function determines the offsets to each field The following function determines the offsets to each field
in the record. The offsets are returned in an array of in the record. It can reuse a previously allocated array. */
ulint, with [0] being the number of fields (n), [1] being the
extra size (if REC_OFFS_COMPACT is set, the record is in the new
format), and [2]..[n+1] being the offsets past the end of
fields 0..n, or to the beginning of fields 1..n+1. When the
high-order bit of the offset at [n+1] is set (REC_OFFS_SQL_NULL),
the field n is NULL. When the second high-order bit of the offset
at [n+1] is set (REC_OFFS_EXTERNAL), the field n is being stored
externally. */
ulint* ulint*
rec_get_offsets( rec_get_offsets_func(
/*============*/ /*=================*/
/* out: the offsets */
rec_t* rec, /* in: physical record */
dict_index_t* index, /* in: record descriptor */
ulint n_fields,/* in: maximum number of initialized fields
(ULINT_UNDEFINED if all fields) */
mem_heap_t* heap); /* in: memory heap */
/**********************************************************
The following function determines the offsets to each field
in the record. It differs from rec_get_offsets() by trying to
reuse a previously returned array. */
ulint*
rec_reget_offsets(
/*==============*/
/* out: the new offsets */ /* out: the new offsets */
rec_t* rec, /* in: physical record */ rec_t* rec, /* in: physical record */
dict_index_t* index, /* in: record descriptor */ dict_index_t* index, /* in: record descriptor */
ulint* offsets,/* in: array of offsets ulint* offsets,/* in: array consisting of offsets[0]
from rec_get_offsets() allocated elements, or an array from
or rec_reget_offsets(), or NULL */ rec_get_offsets(), or NULL */
ulint n_fields,/* in: maximum number of initialized fields ulint n_fields,/* in: maximum number of initialized fields
(ULINT_UNDEFINED if all fields) */ (ULINT_UNDEFINED if all fields) */
mem_heap_t* heap); /* in: memory heap */ mem_heap_t** heap, /* in/out: memory heap */
const char* file, /* in: file name where called */
ulint line); /* in: line number where called */
#define rec_get_offsets(rec,index,offsets,n,heap) \
rec_get_offsets_func(rec,index,offsets,n,heap,__FILE__,__LINE__)
/**************************************************************** /****************************************************************
Validates offsets returned by rec_get_offsets() or rec_reget_offsets(). */ Validates offsets returned by rec_get_offsets(). */
UNIV_INLINE UNIV_INLINE
ibool ibool
rec_offs_validate( rec_offs_validate(
...@@ -234,8 +227,7 @@ rec_offs_validate( ...@@ -234,8 +227,7 @@ rec_offs_validate(
/* out: TRUE if valid */ /* out: TRUE if valid */
rec_t* rec, /* in: record or NULL */ rec_t* rec, /* in: record or NULL */
dict_index_t* index, /* in: record descriptor or NULL */ dict_index_t* index, /* in: record descriptor or NULL */
const ulint* offsets);/* in: array returned by rec_get_offsets() const ulint* offsets);/* in: array returned by rec_get_offsets() */
or rec_reget_offsets() */
/**************************************************************** /****************************************************************
Updates debug data in offsets, in order to avoid bogus Updates debug data in offsets, in order to avoid bogus
rec_offs_validate() failures. */ rec_offs_validate() failures. */
...@@ -243,10 +235,9 @@ UNIV_INLINE ...@@ -243,10 +235,9 @@ UNIV_INLINE
void void
rec_offs_make_valid( rec_offs_make_valid(
/*================*/ /*================*/
const rec_t* rec, /* in: record */ rec_t* rec, /* in: record */
const dict_index_t* index,/* in: record descriptor */ dict_index_t* index,/* in: record descriptor */
ulint* offsets);/* in: array returned by rec_get_offsets() ulint* offsets);/* in: array returned by rec_get_offsets() */
or rec_reget_offsets() */
/**************************************************************** /****************************************************************
The following function is used to get a pointer to the nth The following function is used to get a pointer to the nth
...@@ -551,7 +542,15 @@ rec_print_old( ...@@ -551,7 +542,15 @@ rec_print_old(
/*==========*/ /*==========*/
FILE* file, /* in: file where to print */ FILE* file, /* in: file where to print */
rec_t* rec); /* in: physical record */ rec_t* rec); /* in: physical record */
/*******************************************************************
Prints a physical record. */
void
rec_print_new(
/*==========*/
FILE* file, /* in: file where to print */
rec_t* rec, /* in: physical record */
const ulint* offsets);/* in: array returned by rec_get_offsets() */
/******************************************************************* /*******************************************************************
Prints a physical record. */ Prints a physical record. */
...@@ -560,7 +559,7 @@ rec_print( ...@@ -560,7 +559,7 @@ rec_print(
/*======*/ /*======*/
FILE* file, /* in: file where to print */ FILE* file, /* in: file where to print */
rec_t* rec, /* in: physical record */ rec_t* rec, /* in: physical record */
const ulint* offsets);/* in: array returned by rec_get_offsets() */ dict_index_t* index); /* in: record descriptor */
#define REC_INFO_BITS 6 /* This is single byte bit-field */ #define REC_INFO_BITS 6 /* This is single byte bit-field */
......
...@@ -681,9 +681,11 @@ rec_2_get_field_end_info( ...@@ -681,9 +681,11 @@ rec_2_get_field_end_info(
} }
#ifdef UNIV_DEBUG #ifdef UNIV_DEBUG
# define REC_OFFS_HEADER_SIZE 3 /* Length of the rec_get_offsets() header */
# define REC_OFFS_HEADER_SIZE 4
#else /* UNIV_DEBUG */ #else /* UNIV_DEBUG */
# define REC_OFFS_HEADER_SIZE 1 /* Length of the rec_get_offsets() header */
# define REC_OFFS_HEADER_SIZE 2
#endif /* UNIV_DEBUG */ #endif /* UNIV_DEBUG */
/* Get the base address of offsets. The extra_size is stored at /* Get the base address of offsets. The extra_size is stored at
...@@ -691,8 +693,40 @@ this position, and following positions hold the end offsets of ...@@ -691,8 +693,40 @@ this position, and following positions hold the end offsets of
the fields. */ the fields. */
#define rec_offs_base(offsets) (offsets + REC_OFFS_HEADER_SIZE) #define rec_offs_base(offsets) (offsets + REC_OFFS_HEADER_SIZE)
/**************************************************************
The following function returns the number of allocated elements
for an array of offsets. */
UNIV_INLINE
ulint
rec_offs_get_n_alloc(
/*=================*/
/* out: number of elements */
const ulint* offsets)/* in: array for rec_get_offsets() */
{
ulint n_alloc;
ut_ad(offsets);
n_alloc = offsets[0];
ut_ad(n_alloc > 0);
return(n_alloc);
}
/**************************************************************
The following function sets the number of allocated elements
for an array of offsets. */
UNIV_INLINE
void
rec_offs_set_n_alloc(
/*=================*/
ulint* offsets, /* in: array for rec_get_offsets() */
ulint n_alloc) /* in: number of elements */
{
ut_ad(offsets);
ut_ad(n_alloc > 0);
offsets[0] = n_alloc;
}
/**************************************************************** /****************************************************************
Validates offsets returned by rec_get_offsets() or rec_reget_offsets(). */ Validates offsets returned by rec_get_offsets(). */
UNIV_INLINE UNIV_INLINE
ibool ibool
rec_offs_validate( rec_offs_validate(
...@@ -705,16 +739,16 @@ rec_offs_validate( ...@@ -705,16 +739,16 @@ rec_offs_validate(
ulint i = rec_offs_n_fields(offsets); ulint i = rec_offs_n_fields(offsets);
ulint last = ULINT_MAX; ulint last = ULINT_MAX;
ibool comp = (*rec_offs_base(offsets) & REC_OFFS_COMPACT) != 0; ibool comp = (*rec_offs_base(offsets) & REC_OFFS_COMPACT) != 0;
ut_a(offsets);
if (rec) { if (rec) {
ut_ad((ulint) rec == offsets[1]); ut_ad((ulint) rec == offsets[2]);
if (!comp) { if (!comp) {
ut_a(rec_get_n_fields_old(rec) >= i); ut_a(rec_get_n_fields_old(rec) >= i);
} }
} }
if (index) { if (index) {
ulint max_n_fields; ulint max_n_fields;
ut_ad((ulint) index == offsets[2]); ut_ad((ulint) index == offsets[3]);
max_n_fields = ut_max( max_n_fields = ut_max(
dict_index_get_n_fields(index), dict_index_get_n_fields(index),
dict_index_get_n_unique_in_tree(index) + 1); dict_index_get_n_unique_in_tree(index) + 1);
...@@ -734,7 +768,9 @@ rec_offs_validate( ...@@ -734,7 +768,9 @@ rec_offs_validate(
ut_error; ut_error;
} }
} }
ut_a(i <= max_n_fields); /* index->n_def == 0 for dummy indexes if !comp */
ut_a(!comp || index->n_def);
ut_a(!index->n_def || i <= max_n_fields);
} }
while (i--) { while (i--) {
ulint curr = rec_offs_base(offsets)[1 + i] & REC_OFFS_MASK; ulint curr = rec_offs_base(offsets)[1 + i] & REC_OFFS_MASK;
...@@ -750,17 +786,17 @@ UNIV_INLINE ...@@ -750,17 +786,17 @@ UNIV_INLINE
void void
rec_offs_make_valid( rec_offs_make_valid(
/*================*/ /*================*/
const rec_t* rec __attribute__((unused)), rec_t* rec __attribute__((unused)),
/* in: record */ /* in: record */
const dict_index_t* index __attribute__((unused)), dict_index_t* index __attribute__((unused)),
/* in: record descriptor */ /* in: record descriptor */
ulint* offsets __attribute__((unused))) ulint* offsets __attribute__((unused)))
/* in: array returned by rec_get_offsets() /* in: array returned by rec_get_offsets() */
or rec_reget_offsets() */
{ {
#ifdef UNIV_DEBUG #ifdef UNIV_DEBUG
offsets[1] = (ulint) rec; ut_ad(rec_get_n_fields(rec, index) >= rec_offs_n_fields(offsets));
offsets[2] = (ulint) index; offsets[2] = (ulint) rec;
offsets[3] = (ulint) index;
#endif /* UNIV_DEBUG */ #endif /* UNIV_DEBUG */
} }
...@@ -1146,12 +1182,31 @@ rec_offs_n_fields( ...@@ -1146,12 +1182,31 @@ rec_offs_n_fields(
{ {
ulint n_fields; ulint n_fields;
ut_ad(offsets); ut_ad(offsets);
n_fields = offsets[0]; n_fields = offsets[1];
ut_ad(n_fields > 0); ut_ad(n_fields > 0);
ut_ad(n_fields <= REC_MAX_N_FIELDS); ut_ad(n_fields <= REC_MAX_N_FIELDS);
ut_ad(n_fields + REC_OFFS_HEADER_SIZE
<= rec_offs_get_n_alloc(offsets));
return(n_fields); return(n_fields);
} }
/**************************************************************
The following function sets the number of fields in offsets. */
UNIV_INLINE
void
rec_offs_set_n_fields(
/*==================*/
ulint* offsets, /* in: array returned by rec_get_offsets() */
ulint n_fields) /* in: number of fields */
{
ut_ad(offsets);
ut_ad(n_fields > 0);
ut_ad(n_fields <= REC_MAX_N_FIELDS);
ut_ad(n_fields + REC_OFFS_HEADER_SIZE
<= rec_offs_get_n_alloc(offsets));
offsets[1] = n_fields;
}
/************************************************************** /**************************************************************
The following function returns the data size of a physical The following function returns the data size of a physical
record, that is the sum of field lengths. SQL null fields record, that is the sum of field lengths. SQL null fields
......
...@@ -424,7 +424,7 @@ lock_check_trx_id_sanity( ...@@ -424,7 +424,7 @@ lock_check_trx_id_sanity(
/* out: TRUE if ok */ /* out: TRUE if ok */
dulint trx_id, /* in: trx id */ dulint trx_id, /* in: trx id */
rec_t* rec, /* in: user record */ rec_t* rec, /* in: user record */
dict_index_t* index, /* in: clustered index */ dict_index_t* index, /* in: index */
const ulint* offsets, /* in: rec_get_offsets(rec, index) */ const ulint* offsets, /* in: rec_get_offsets(rec, index) */
ibool has_kernel_mutex)/* in: TRUE if the caller owns the ibool has_kernel_mutex)/* in: TRUE if the caller owns the
kernel mutex */ kernel mutex */
...@@ -445,7 +445,7 @@ lock_check_trx_id_sanity( ...@@ -445,7 +445,7 @@ lock_check_trx_id_sanity(
fputs(" InnoDB: Error: transaction id associated" fputs(" InnoDB: Error: transaction id associated"
" with record\n", " with record\n",
stderr); stderr);
rec_print(stderr, rec, offsets); rec_print_new(stderr, rec, offsets);
fputs("InnoDB: in ", stderr); fputs("InnoDB: in ", stderr);
dict_index_name_print(stderr, NULL, index); dict_index_name_print(stderr, NULL, index);
fprintf(stderr, "\n" fprintf(stderr, "\n"
...@@ -4073,10 +4073,9 @@ lock_rec_print( ...@@ -4073,10 +4073,9 @@ lock_rec_print(
ulint page_no; ulint page_no;
ulint i; ulint i;
mtr_t mtr; mtr_t mtr;
mem_heap_t* heap; mem_heap_t* heap = NULL;
ulint* offsets = NULL; ulint offsets_[100] = { 100, };
ulint* offsets = offsets_;
heap = mem_heap_create(100);
#ifdef UNIV_SYNC_DEBUG #ifdef UNIV_SYNC_DEBUG
ut_ad(mutex_own(&kernel_mutex)); ut_ad(mutex_own(&kernel_mutex));
...@@ -4157,9 +4156,9 @@ lock_rec_print( ...@@ -4157,9 +4156,9 @@ lock_rec_print(
if (page) { if (page) {
rec_t* rec rec_t* rec
= page_find_rec_with_heap_no(page, i); = page_find_rec_with_heap_no(page, i);
offsets = rec_reget_offsets(rec, lock->index, offsets = rec_get_offsets(rec, lock->index,
offsets, ULINT_UNDEFINED, heap); offsets, ULINT_UNDEFINED, &heap);
rec_print(file, rec, offsets); rec_print_new(file, rec, offsets);
} }
putc('\n', file); putc('\n', file);
...@@ -4167,7 +4166,9 @@ lock_rec_print( ...@@ -4167,7 +4166,9 @@ lock_rec_print(
} }
mtr_commit(&mtr); mtr_commit(&mtr);
if (heap) {
mem_heap_free(heap); mem_heap_free(heap);
}
} }
/************************************************************************* /*************************************************************************
...@@ -4566,8 +4567,9 @@ lock_rec_validate_page( ...@@ -4566,8 +4567,9 @@ lock_rec_validate_page(
ulint nth_bit = 0; ulint nth_bit = 0;
ulint i; ulint i;
mtr_t mtr; mtr_t mtr;
mem_heap_t* heap = mem_heap_create(100); mem_heap_t* heap = NULL;
ulint* offsets = NULL; ulint offsets_[100] = { 100, };
ulint* offsets = offsets_;
#ifdef UNIV_SYNC_DEBUG #ifdef UNIV_SYNC_DEBUG
ut_ad(!mutex_own(&kernel_mutex)); ut_ad(!mutex_own(&kernel_mutex));
...@@ -4607,8 +4609,8 @@ loop: ...@@ -4607,8 +4609,8 @@ loop:
index = lock->index; index = lock->index;
rec = page_find_rec_with_heap_no(page, i); rec = page_find_rec_with_heap_no(page, i);
offsets = rec_reget_offsets(rec, index, offsets = rec_get_offsets(rec, index, offsets,
offsets, ULINT_UNDEFINED, heap); ULINT_UNDEFINED, &heap);
fprintf(stderr, fprintf(stderr,
"Validating %lu %lu\n", (ulong) space, (ulong) page_no); "Validating %lu %lu\n", (ulong) space, (ulong) page_no);
...@@ -4635,7 +4637,9 @@ function_exit: ...@@ -4635,7 +4637,9 @@ function_exit:
mtr_commit(&mtr); mtr_commit(&mtr);
if (heap) {
mem_heap_free(heap); mem_heap_free(heap);
}
return(TRUE); return(TRUE);
} }
...@@ -4811,12 +4815,16 @@ lock_rec_insert_check_and_lock( ...@@ -4811,12 +4815,16 @@ lock_rec_insert_check_and_lock(
#ifdef UNIV_DEBUG #ifdef UNIV_DEBUG
{ {
mem_heap_t* heap = mem_heap_create(100); mem_heap_t* heap = NULL;
const ulint* offsets = rec_get_offsets(next_rec, index, ulint offsets_[100] = { 100, };
ULINT_UNDEFINED, heap); const ulint* offsets = rec_get_offsets(
next_rec, index, offsets_,
ULINT_UNDEFINED, &heap);
ut_ad(lock_rec_queue_validate(next_rec, index, offsets)); ut_ad(lock_rec_queue_validate(next_rec, index, offsets));
if (heap) {
mem_heap_free(heap); mem_heap_free(heap);
} }
}
#endif /* UNIV_DEBUG */ #endif /* UNIV_DEBUG */
return(err); return(err);
...@@ -4954,12 +4962,15 @@ lock_sec_rec_modify_check_and_lock( ...@@ -4954,12 +4962,15 @@ lock_sec_rec_modify_check_and_lock(
#ifdef UNIV_DEBUG #ifdef UNIV_DEBUG
{ {
mem_heap_t* heap = mem_heap_create(100); mem_heap_t* heap = NULL;
const ulint* offsets = rec_get_offsets(rec, index, ulint offsets_[100] = { 100, };
ULINT_UNDEFINED, heap); const ulint* offsets = rec_get_offsets(
rec, index, offsets_, ULINT_UNDEFINED, &heap);
ut_ad(lock_rec_queue_validate(rec, index, offsets)); ut_ad(lock_rec_queue_validate(rec, index, offsets));
if (heap) {
mem_heap_free(heap); mem_heap_free(heap);
} }
}
#endif /* UNIV_DEBUG */ #endif /* UNIV_DEBUG */
if (err == DB_SUCCESS) { if (err == DB_SUCCESS) {
...@@ -5067,7 +5078,6 @@ lock_clust_rec_read_check_and_lock( ...@@ -5067,7 +5078,6 @@ lock_clust_rec_read_check_and_lock(
ut_ad(page_rec_is_user_rec(rec) || page_rec_is_supremum(rec)); ut_ad(page_rec_is_user_rec(rec) || page_rec_is_supremum(rec));
ut_ad(gap_mode == LOCK_ORDINARY || gap_mode == LOCK_GAP ut_ad(gap_mode == LOCK_ORDINARY || gap_mode == LOCK_GAP
|| gap_mode == LOCK_REC_NOT_GAP); || gap_mode == LOCK_REC_NOT_GAP);
ut_ad(index->type & DICT_CLUSTERED);
ut_ad(rec_offs_validate(rec, index, offsets)); ut_ad(rec_offs_validate(rec, index, offsets));
if (flags & BTR_NO_LOCKING_FLAG) { if (flags & BTR_NO_LOCKING_FLAG) {
......
...@@ -29,6 +29,7 @@ UNIV_INLINE ...@@ -29,6 +29,7 @@ UNIV_INLINE
ibool ibool
page_cur_try_search_shortcut( page_cur_try_search_shortcut(
/*=========================*/ /*=========================*/
/* out: TRUE on success */
page_t* page, /* in: index page */ page_t* page, /* in: index page */
dict_index_t* index, /* in: record descriptor */ dict_index_t* index, /* in: record descriptor */
dtuple_t* tuple, /* in: data tuple */ dtuple_t* tuple, /* in: data tuple */
...@@ -56,14 +57,15 @@ page_cur_try_search_shortcut( ...@@ -56,14 +57,15 @@ page_cur_try_search_shortcut(
#ifdef UNIV_SEARCH_DEBUG #ifdef UNIV_SEARCH_DEBUG
page_cur_t cursor2; page_cur_t cursor2;
#endif #endif
mem_heap_t* heap; ibool success = FALSE;
ulint* offsets; mem_heap_t* heap = NULL;
ulint offsets_[100] = { 100, };
ulint* offsets = offsets_;
ut_ad(dtuple_check_typed(tuple)); ut_ad(dtuple_check_typed(tuple));
rec = page_header_get_ptr(page, PAGE_LAST_INSERT); rec = page_header_get_ptr(page, PAGE_LAST_INSERT);
heap = mem_heap_create(100); offsets = rec_get_offsets(rec, index, offsets,
offsets = rec_get_offsets(rec, index, dtuple_get_n_fields(tuple), &heap);
dtuple_get_n_fields(tuple), heap);
ut_ad(rec); ut_ad(rec);
ut_ad(page_rec_is_user_rec(rec)); ut_ad(page_rec_is_user_rec(rec));
...@@ -78,21 +80,17 @@ page_cur_try_search_shortcut( ...@@ -78,21 +80,17 @@ page_cur_try_search_shortcut(
cmp = page_cmp_dtuple_rec_with_match(tuple, rec, offsets, &low_match, cmp = page_cmp_dtuple_rec_with_match(tuple, rec, offsets, &low_match,
&low_bytes); &low_bytes);
if (cmp == -1) { if (cmp == -1) {
goto exit_func;
mem_heap_free(heap);
return(FALSE);
} }
next_rec = page_rec_get_next(rec); next_rec = page_rec_get_next(rec);
offsets = rec_reget_offsets(next_rec, index, offsets, offsets = rec_get_offsets(next_rec, index, offsets,
dtuple_get_n_fields(tuple), heap); dtuple_get_n_fields(tuple), &heap);
cmp = page_cmp_dtuple_rec_with_match(tuple, next_rec, offsets, cmp = page_cmp_dtuple_rec_with_match(tuple, next_rec, offsets,
&up_match, &up_bytes); &up_match, &up_bytes);
if (cmp != -1) { if (cmp != -1) {
goto exit_func;
mem_heap_free(heap);
return(FALSE);
} }
cursor->rec = rec; cursor->rec = rec;
...@@ -127,8 +125,12 @@ page_cur_try_search_shortcut( ...@@ -127,8 +125,12 @@ page_cur_try_search_shortcut(
#ifdef UNIV_SEARCH_PERF_STAT #ifdef UNIV_SEARCH_PERF_STAT
page_cur_short_succ++; page_cur_short_succ++;
#endif #endif
success = TRUE;
exit_func:
if (heap) {
mem_heap_free(heap); mem_heap_free(heap);
return(TRUE); }
return(success);
} }
#endif #endif
...@@ -226,8 +228,9 @@ page_cur_search_with_match( ...@@ -226,8 +228,9 @@ page_cur_search_with_match(
ulint dbg_matched_fields; ulint dbg_matched_fields;
ulint dbg_matched_bytes; ulint dbg_matched_bytes;
#endif #endif
mem_heap_t* heap; mem_heap_t* heap = NULL;
ulint* offsets = NULL; ulint offsets_[100] = { 100, };
ulint* offsets = offsets_;
ut_ad(page && tuple && iup_matched_fields && iup_matched_bytes ut_ad(page && tuple && iup_matched_fields && iup_matched_bytes
&& ilow_matched_fields && ilow_matched_bytes && cursor); && ilow_matched_fields && ilow_matched_bytes && cursor);
...@@ -262,8 +265,6 @@ page_cur_search_with_match( ...@@ -262,8 +265,6 @@ page_cur_search_with_match(
/*#endif */ /*#endif */
#endif #endif
heap = mem_heap_create(100);
/* The following flag does not work for non-latin1 char sets because /* The following flag does not work for non-latin1 char sets because
cmp_full_field does not tell how many bytes matched */ cmp_full_field does not tell how many bytes matched */
ut_a(mode != PAGE_CUR_LE_OR_EXTENDS); ut_a(mode != PAGE_CUR_LE_OR_EXTENDS);
...@@ -298,8 +299,8 @@ page_cur_search_with_match( ...@@ -298,8 +299,8 @@ page_cur_search_with_match(
low_matched_fields, low_matched_bytes, low_matched_fields, low_matched_bytes,
up_matched_fields, up_matched_bytes); up_matched_fields, up_matched_bytes);
offsets = rec_reget_offsets(mid_rec, index, offsets, offsets = rec_get_offsets(mid_rec, index, offsets,
dtuple_get_n_fields_cmp(tuple), heap); dtuple_get_n_fields_cmp(tuple), &heap);
cmp = cmp_dtuple_rec_with_match(tuple, mid_rec, offsets, cmp = cmp_dtuple_rec_with_match(tuple, mid_rec, offsets,
&cur_matched_fields, &cur_matched_fields,
...@@ -310,8 +311,8 @@ page_cur_search_with_match( ...@@ -310,8 +311,8 @@ page_cur_search_with_match(
low_matched_bytes = cur_matched_bytes; low_matched_bytes = cur_matched_bytes;
} else if (cmp == -1) { } else if (cmp == -1) {
offsets = rec_reget_offsets(mid_rec, index, offsets = rec_get_offsets(mid_rec, index, offsets,
offsets, dtuple_get_n_fields_cmp(tuple), heap); dtuple_get_n_fields_cmp(tuple), &heap);
if (mode == PAGE_CUR_LE_OR_EXTENDS if (mode == PAGE_CUR_LE_OR_EXTENDS
&& page_cur_rec_field_extends(tuple, mid_rec, && page_cur_rec_field_extends(tuple, mid_rec,
...@@ -353,8 +354,8 @@ page_cur_search_with_match( ...@@ -353,8 +354,8 @@ page_cur_search_with_match(
low_matched_fields, low_matched_bytes, low_matched_fields, low_matched_bytes,
up_matched_fields, up_matched_bytes); up_matched_fields, up_matched_bytes);
offsets = rec_reget_offsets(mid_rec, index, offsets = rec_get_offsets(mid_rec, index, offsets,
offsets, dtuple_get_n_fields_cmp(tuple), heap); dtuple_get_n_fields_cmp(tuple), &heap);
cmp = cmp_dtuple_rec_with_match(tuple, mid_rec, offsets, cmp = cmp_dtuple_rec_with_match(tuple, mid_rec, offsets,
&cur_matched_fields, &cur_matched_fields,
...@@ -365,8 +366,8 @@ page_cur_search_with_match( ...@@ -365,8 +366,8 @@ page_cur_search_with_match(
low_matched_bytes = cur_matched_bytes; low_matched_bytes = cur_matched_bytes;
} else if (cmp == -1) { } else if (cmp == -1) {
offsets = rec_reget_offsets(mid_rec, index, offsets = rec_get_offsets(mid_rec, index, offsets,
offsets, dtuple_get_n_fields_cmp(tuple), heap); dtuple_get_n_fields_cmp(tuple), &heap);
if (mode == PAGE_CUR_LE_OR_EXTENDS if (mode == PAGE_CUR_LE_OR_EXTENDS
&& page_cur_rec_field_extends(tuple, mid_rec, && page_cur_rec_field_extends(tuple, mid_rec,
...@@ -398,8 +399,8 @@ page_cur_search_with_match( ...@@ -398,8 +399,8 @@ page_cur_search_with_match(
dbg_matched_fields = 0; dbg_matched_fields = 0;
dbg_matched_bytes = 0; dbg_matched_bytes = 0;
offsets = rec_reget_offsets(low_rec, index, offsets = rec_get_offsets(low_rec, index, offsets,
offsets, ULINT_UNDEFINED, heap); ULINT_UNDEFINED, &heap);
dbg_cmp = page_cmp_dtuple_rec_with_match(tuple, low_rec, offsets, dbg_cmp = page_cmp_dtuple_rec_with_match(tuple, low_rec, offsets,
&dbg_matched_fields, &dbg_matched_fields,
&dbg_matched_bytes); &dbg_matched_bytes);
...@@ -422,8 +423,8 @@ page_cur_search_with_match( ...@@ -422,8 +423,8 @@ page_cur_search_with_match(
dbg_matched_fields = 0; dbg_matched_fields = 0;
dbg_matched_bytes = 0; dbg_matched_bytes = 0;
offsets = rec_reget_offsets(up_rec, index, offsets = rec_get_offsets(up_rec, index, offsets,
offsets, ULINT_UNDEFINED, heap); ULINT_UNDEFINED, &heap);
dbg_cmp = page_cmp_dtuple_rec_with_match(tuple, up_rec, offsets, dbg_cmp = page_cmp_dtuple_rec_with_match(tuple, up_rec, offsets,
&dbg_matched_fields, &dbg_matched_fields,
&dbg_matched_bytes); &dbg_matched_bytes);
...@@ -453,7 +454,9 @@ page_cur_search_with_match( ...@@ -453,7 +454,9 @@ page_cur_search_with_match(
*iup_matched_bytes = up_matched_bytes; *iup_matched_bytes = up_matched_bytes;
*ilow_matched_fields = low_matched_fields; *ilow_matched_fields = low_matched_fields;
*ilow_matched_bytes = low_matched_bytes; *ilow_matched_bytes = low_matched_bytes;
if (heap) {
mem_heap_free(heap); mem_heap_free(heap);
}
} }
/*************************************************************** /***************************************************************
...@@ -519,23 +522,27 @@ page_cur_insert_rec_write_log( ...@@ -519,23 +522,27 @@ page_cur_insert_rec_write_log(
ut_a(rec_size < UNIV_PAGE_SIZE); ut_a(rec_size < UNIV_PAGE_SIZE);
{ {
mem_heap_t* heap; mem_heap_t* heap = NULL;
ulint cur_offs_[100] = { 100, };
ulint ins_offs_[100] = { 100, };
ulint* cur_offs; ulint* cur_offs;
ulint* ins_offs; ulint* ins_offs;
heap = mem_heap_create(100); cur_offs = rec_get_offsets(cursor_rec, index, cur_offs_,
cur_offs = rec_get_offsets(cursor_rec, index, ULINT_UNDEFINED, &heap);
ULINT_UNDEFINED, heap); ins_offs = rec_get_offsets(insert_rec, index, ins_offs_,
ins_offs = rec_get_offsets(insert_rec, index, ULINT_UNDEFINED, &heap);
ULINT_UNDEFINED, heap);
extra_size = rec_offs_extra_size(ins_offs); extra_size = rec_offs_extra_size(ins_offs);
cur_extra_size = rec_offs_extra_size(cur_offs); cur_extra_size = rec_offs_extra_size(cur_offs);
ut_ad(rec_size == rec_offs_size(ins_offs)); ut_ad(rec_size == rec_offs_size(ins_offs));
cur_rec_size = rec_offs_size(cur_offs); cur_rec_size = rec_offs_size(cur_offs);
if (heap) {
mem_heap_free(heap); mem_heap_free(heap);
} }
}
ins_ptr = insert_rec - extra_size; ins_ptr = insert_rec - extra_size;
...@@ -668,8 +675,9 @@ page_cur_parse_insert_rec( ...@@ -668,8 +675,9 @@ page_cur_parse_insert_rec(
byte* ptr2 = ptr; byte* ptr2 = ptr;
ulint info_bits = 0; /* remove warning */ ulint info_bits = 0; /* remove warning */
page_cur_t cursor; page_cur_t cursor;
mem_heap_t* heap; mem_heap_t* heap = NULL;
ulint* offsets; ulint offsets_[100] = { 100, };
ulint* offsets = offsets_;
if (!is_short) { if (!is_short) {
/* Read the cursor rec offset as a 2-byte ulint */ /* Read the cursor rec offset as a 2-byte ulint */
...@@ -756,8 +764,8 @@ page_cur_parse_insert_rec( ...@@ -756,8 +764,8 @@ page_cur_parse_insert_rec(
cursor_rec = page + offset; cursor_rec = page + offset;
} }
heap = mem_heap_create(100); offsets = rec_get_offsets(cursor_rec, index, offsets,
offsets = rec_get_offsets(cursor_rec, index, ULINT_UNDEFINED, heap); ULINT_UNDEFINED, &heap);
if (extra_info_yes == 0) { if (extra_info_yes == 0) {
info_bits = rec_get_info_bits(cursor_rec, index->table->comp); info_bits = rec_get_info_bits(cursor_rec, index->table->comp);
...@@ -816,6 +824,10 @@ page_cur_parse_insert_rec( ...@@ -816,6 +824,10 @@ page_cur_parse_insert_rec(
mem_free(buf); mem_free(buf);
} }
if (heap) {
mem_heap_free(heap);
}
return(ptr + end_seg_len); return(ptr + end_seg_len);
} }
...@@ -850,8 +862,9 @@ page_cur_insert_rec_low( ...@@ -850,8 +862,9 @@ page_cur_insert_rec_low(
inserted record */ inserted record */
rec_t* owner_rec; rec_t* owner_rec;
ulint n_owned; ulint n_owned;
mem_heap_t* heap; mem_heap_t* heap = NULL;
ulint* offsets; ulint offsets_[100] = { 100, };
ulint* offsets = offsets_;
ibool comp = index->table->comp; ibool comp = index->table->comp;
ut_ad(cursor && mtr); ut_ad(cursor && mtr);
...@@ -865,14 +878,12 @@ page_cur_insert_rec_low( ...@@ -865,14 +878,12 @@ page_cur_insert_rec_low(
ut_ad(cursor->rec != page_get_supremum_rec(page)); ut_ad(cursor->rec != page_get_supremum_rec(page));
heap = mem_heap_create(100);
/* 1. Get the size of the physical record in the page */ /* 1. Get the size of the physical record in the page */
if (tuple != NULL) { if (tuple != NULL) {
offsets = NULL;
rec_size = rec_get_converted_size(index, tuple); rec_size = rec_get_converted_size(index, tuple);
} else { } else {
offsets = rec_get_offsets(rec, index, ULINT_UNDEFINED, heap); offsets = rec_get_offsets(rec, index, offsets,
ULINT_UNDEFINED, &heap);
rec_size = rec_offs_size(offsets); rec_size = rec_offs_size(offsets);
} }
...@@ -880,7 +891,9 @@ page_cur_insert_rec_low( ...@@ -880,7 +891,9 @@ page_cur_insert_rec_low(
insert_buf = page_mem_alloc(page, rec_size, index, &heap_no); insert_buf = page_mem_alloc(page, rec_size, index, &heap_no);
if (insert_buf == NULL) { if (insert_buf == NULL) {
if (heap) {
mem_heap_free(heap); mem_heap_free(heap);
}
return(NULL); return(NULL);
} }
...@@ -888,13 +901,15 @@ page_cur_insert_rec_low( ...@@ -888,13 +901,15 @@ page_cur_insert_rec_low(
if (tuple != NULL) { if (tuple != NULL) {
insert_rec = rec_convert_dtuple_to_rec(insert_buf, insert_rec = rec_convert_dtuple_to_rec(insert_buf,
index, tuple); index, tuple);
offsets = rec_get_offsets(insert_rec, index, offsets,
ULINT_UNDEFINED, &heap);
} else { } else {
insert_rec = rec_copy(insert_buf, rec, offsets); insert_rec = rec_copy(insert_buf, rec, offsets);
ut_ad(rec_offs_validate(rec, index, offsets));
rec_offs_make_valid(insert_rec, index, offsets);
} }
ut_ad(insert_rec); ut_ad(insert_rec);
offsets = rec_reget_offsets(insert_rec, index,
offsets, ULINT_UNDEFINED, heap);
ut_ad(rec_size == rec_offs_size(offsets)); ut_ad(rec_size == rec_offs_size(offsets));
/* 4. Insert the record in the linked list of records */ /* 4. Insert the record in the linked list of records */
...@@ -966,7 +981,9 @@ page_cur_insert_rec_low( ...@@ -966,7 +981,9 @@ page_cur_insert_rec_low(
page_cur_insert_rec_write_log(insert_rec, rec_size, current_rec, page_cur_insert_rec_write_log(insert_rec, rec_size, current_rec,
index, mtr); index, mtr);
if (heap) {
mem_heap_free(heap); mem_heap_free(heap);
}
return(insert_rec); return(insert_rec);
} }
...@@ -1069,8 +1086,9 @@ page_copy_rec_list_end_to_created_page( ...@@ -1069,8 +1086,9 @@ page_copy_rec_list_end_to_created_page(
byte* log_ptr; byte* log_ptr;
ulint log_data_len; ulint log_data_len;
ibool comp = page_is_comp(page); ibool comp = page_is_comp(page);
mem_heap_t* heap; mem_heap_t* heap = NULL;
ulint* offsets = NULL; ulint offsets_[100] = { 100, };
ulint* offsets = offsets_;
ut_ad(page_dir_get_n_heap(new_page) == 2); ut_ad(page_dir_get_n_heap(new_page) == 2);
ut_ad(page != new_page); ut_ad(page != new_page);
...@@ -1117,8 +1135,8 @@ page_copy_rec_list_end_to_created_page( ...@@ -1117,8 +1135,8 @@ page_copy_rec_list_end_to_created_page(
/* should be do ... until, comment by Jani */ /* should be do ... until, comment by Jani */
while (rec != page_get_supremum_rec(page)) { while (rec != page_get_supremum_rec(page)) {
offsets = rec_reget_offsets(rec, index, offsets = rec_get_offsets(rec, index, offsets,
offsets, ULINT_UNDEFINED, heap); ULINT_UNDEFINED, &heap);
insert_rec = rec_copy(heap_top, rec, offsets); insert_rec = rec_copy(heap_top, rec, offsets);
rec_set_next_offs(prev_rec, comp, insert_rec - new_page); rec_set_next_offs(prev_rec, comp, insert_rec - new_page);
...@@ -1170,7 +1188,9 @@ page_copy_rec_list_end_to_created_page( ...@@ -1170,7 +1188,9 @@ page_copy_rec_list_end_to_created_page(
slot_index--; slot_index--;
} }
if (heap) {
mem_heap_free(heap); mem_heap_free(heap);
}
log_data_len = dyn_array_get_data_size(&(mtr->log)) - log_data_len; log_data_len = dyn_array_get_data_size(&(mtr->log)) - log_data_len;
......
...@@ -227,10 +227,12 @@ page_mem_alloc( ...@@ -227,10 +227,12 @@ page_mem_alloc(
rec = page_header_get_ptr(page, PAGE_FREE); rec = page_header_get_ptr(page, PAGE_FREE);
if (rec) { if (rec) {
mem_heap_t* heap mem_heap_t* heap = NULL;
= mem_heap_create(100); ulint offsets_[100] = { 100, };
const ulint* offsets ulint* offsets = offsets_;
= rec_get_offsets(rec, index, ULINT_UNDEFINED, heap);
offsets = rec_get_offsets(rec, index, offsets,
ULINT_UNDEFINED, &heap);
if (rec_offs_size(offsets) >= need) { if (rec_offs_size(offsets) >= need) {
page_header_set_ptr(page, PAGE_FREE, page_header_set_ptr(page, PAGE_FREE,
...@@ -245,12 +247,16 @@ page_mem_alloc( ...@@ -245,12 +247,16 @@ page_mem_alloc(
*heap_no = rec_get_heap_no(rec, page_is_comp(page)); *heap_no = rec_get_heap_no(rec, page_is_comp(page));
block = rec_get_start(rec, offsets); block = rec_get_start(rec, offsets);
if (heap) {
mem_heap_free(heap); mem_heap_free(heap);
}
return(block); return(block);
} }
if (heap) {
mem_heap_free(heap); mem_heap_free(heap);
} }
}
/* Could not find space from the free list, try top of heap */ /* Could not find space from the free list, try top of heap */
...@@ -374,7 +380,8 @@ page_create( ...@@ -374,7 +380,8 @@ page_create(
rec_set_n_owned(infimum_rec, comp, 1); rec_set_n_owned(infimum_rec, comp, 1);
rec_set_heap_no(infimum_rec, comp, 0); rec_set_heap_no(infimum_rec, comp, 0);
offsets = rec_get_offsets(infimum_rec, index, ULINT_UNDEFINED, heap); offsets = rec_get_offsets(infimum_rec, index, NULL,
ULINT_UNDEFINED, &heap);
heap_top = rec_get_end(infimum_rec, offsets); heap_top = rec_get_end(infimum_rec, offsets);
...@@ -396,8 +403,8 @@ page_create( ...@@ -396,8 +403,8 @@ page_create(
rec_set_n_owned(supremum_rec, comp, 1); rec_set_n_owned(supremum_rec, comp, 1);
rec_set_heap_no(supremum_rec, comp, 1); rec_set_heap_no(supremum_rec, comp, 1);
offsets = rec_reget_offsets(supremum_rec, index, offsets = rec_get_offsets(supremum_rec, index, offsets,
offsets, ULINT_UNDEFINED, heap); ULINT_UNDEFINED, &heap);
heap_top = rec_get_end(supremum_rec, offsets); heap_top = rec_get_end(supremum_rec, offsets);
ut_ad(heap_top == ut_ad(heap_top ==
...@@ -711,8 +718,9 @@ page_delete_rec_list_end( ...@@ -711,8 +718,9 @@ page_delete_rec_list_end(
last_rec = page_rec_get_prev(sup); last_rec = page_rec_get_prev(sup);
if ((size == ULINT_UNDEFINED) || (n_recs == ULINT_UNDEFINED)) { if ((size == ULINT_UNDEFINED) || (n_recs == ULINT_UNDEFINED)) {
mem_heap_t* heap = mem_heap_create(100); mem_heap_t* heap = NULL;
ulint* offsets = NULL; ulint offsets_[100] = { 100, };
ulint* offsets = offsets_;
/* Calculate the sum of sizes and the number of records */ /* Calculate the sum of sizes and the number of records */
size = 0; size = 0;
n_recs = 0; n_recs = 0;
...@@ -720,8 +728,8 @@ page_delete_rec_list_end( ...@@ -720,8 +728,8 @@ page_delete_rec_list_end(
while (rec2 != sup) { while (rec2 != sup) {
ulint s; ulint s;
offsets = rec_reget_offsets(rec2, index, offsets = rec_get_offsets(rec2, index, offsets,
offsets, ULINT_UNDEFINED, heap); ULINT_UNDEFINED, &heap);
s = rec_offs_size(offsets); s = rec_offs_size(offsets);
ut_ad(rec2 - page + s - rec_offs_extra_size(offsets) ut_ad(rec2 - page + s - rec_offs_extra_size(offsets)
< UNIV_PAGE_SIZE); < UNIV_PAGE_SIZE);
...@@ -732,8 +740,10 @@ page_delete_rec_list_end( ...@@ -732,8 +740,10 @@ page_delete_rec_list_end(
rec2 = page_rec_get_next(rec2); rec2 = page_rec_get_next(rec2);
} }
if (heap) {
mem_heap_free(heap); mem_heap_free(heap);
} }
}
ut_ad(size < UNIV_PAGE_SIZE); ut_ad(size < UNIV_PAGE_SIZE);
...@@ -1213,7 +1223,7 @@ page_rec_print( ...@@ -1213,7 +1223,7 @@ page_rec_print(
ibool comp = page_is_comp(buf_frame_align(rec)); ibool comp = page_is_comp(buf_frame_align(rec));
ut_a(comp == rec_offs_comp(offsets)); ut_a(comp == rec_offs_comp(offsets));
rec_print(stderr, rec, offsets); rec_print_new(stderr, rec, offsets);
fprintf(stderr, fprintf(stderr,
" n_owned: %lu; heap_no: %lu; next rec: %lu\n", " n_owned: %lu; heap_no: %lu; next rec: %lu\n",
(ulong) rec_get_n_owned(rec, comp), (ulong) rec_get_n_owned(rec, comp),
...@@ -1276,11 +1286,11 @@ page_print_list( ...@@ -1276,11 +1286,11 @@ page_print_list(
page_cur_t cur; page_cur_t cur;
ulint count; ulint count;
ulint n_recs; ulint n_recs;
mem_heap_t* heap; mem_heap_t* heap = NULL;
ulint* offsets = NULL; ulint offsets_[100] = { 100, };
ulint* offsets = offsets_;
ut_a(page_is_comp(page) == index->table->comp); ut_a(page_is_comp(page) == index->table->comp);
heap = mem_heap_create(100);
fprintf(stderr, fprintf(stderr,
"--------------------------------\n" "--------------------------------\n"
...@@ -1292,8 +1302,8 @@ page_print_list( ...@@ -1292,8 +1302,8 @@ page_print_list(
page_cur_set_before_first(page, &cur); page_cur_set_before_first(page, &cur);
count = 0; count = 0;
for (;;) { for (;;) {
offsets = rec_reget_offsets(cur.rec, index, offsets = rec_get_offsets(cur.rec, index, offsets,
offsets, ULINT_UNDEFINED, heap); ULINT_UNDEFINED, &heap);
page_rec_print(cur.rec, offsets); page_rec_print(cur.rec, offsets);
if (count == pr_n) { if (count == pr_n) {
...@@ -1314,8 +1324,8 @@ page_print_list( ...@@ -1314,8 +1324,8 @@ page_print_list(
page_cur_move_to_next(&cur); page_cur_move_to_next(&cur);
if (count + pr_n >= n_recs) { if (count + pr_n >= n_recs) {
offsets = rec_reget_offsets(cur.rec, index, offsets = rec_get_offsets(cur.rec, index, offsets,
offsets, ULINT_UNDEFINED, heap); ULINT_UNDEFINED, &heap);
page_rec_print(cur.rec, offsets); page_rec_print(cur.rec, offsets);
} }
count++; count++;
...@@ -1326,7 +1336,9 @@ page_print_list( ...@@ -1326,7 +1336,9 @@ page_print_list(
"--------------------------------\n", "--------------------------------\n",
(ulong) (count + 1)); (ulong) (count + 1));
if (heap) {
mem_heap_free(heap); mem_heap_free(heap);
}
} }
/******************************************************************* /*******************************************************************
...@@ -1680,7 +1692,7 @@ page_validate( ...@@ -1680,7 +1692,7 @@ page_validate(
goto func_exit2; goto func_exit2;
} }
heap = mem_heap_create(UNIV_PAGE_SIZE); heap = mem_heap_create(UNIV_PAGE_SIZE + 200);
/* The following buffer is used to check that the /* The following buffer is used to check that the
records in the page record heap do not overlap */ records in the page record heap do not overlap */
...@@ -1720,8 +1732,8 @@ page_validate( ...@@ -1720,8 +1732,8 @@ page_validate(
for (;;) { for (;;) {
rec = cur.rec; rec = cur.rec;
offsets = rec_reget_offsets(rec, index, offsets = rec_get_offsets(rec, index, offsets,
offsets, ULINT_UNDEFINED, heap); ULINT_UNDEFINED, &heap);
if (comp && page_rec_is_user_rec(rec) if (comp && page_rec_is_user_rec(rec)
&& rec_get_node_ptr_flag(rec) && rec_get_node_ptr_flag(rec)
...@@ -1744,9 +1756,9 @@ page_validate( ...@@ -1744,9 +1756,9 @@ page_validate(
(ulong) buf_frame_get_page_no(page)); (ulong) buf_frame_get_page_no(page));
dict_index_name_print(stderr, NULL, index); dict_index_name_print(stderr, NULL, index);
fputs("\nInnoDB: previous record ", stderr); fputs("\nInnoDB: previous record ", stderr);
rec_print(stderr, old_rec, old_offsets); rec_print_new(stderr, old_rec, old_offsets);
fputs("\nInnoDB: record ", stderr); fputs("\nInnoDB: record ", stderr);
rec_print(stderr, rec, offsets); rec_print_new(stderr, rec, offsets);
putc('\n', stderr); putc('\n', stderr);
goto func_exit; goto func_exit;
...@@ -1852,8 +1864,8 @@ page_validate( ...@@ -1852,8 +1864,8 @@ page_validate(
rec = page_header_get_ptr(page, PAGE_FREE); rec = page_header_get_ptr(page, PAGE_FREE);
while (rec != NULL) { while (rec != NULL) {
offsets = rec_reget_offsets(rec, index, offsets = rec_get_offsets(rec, index, offsets,
offsets, ULINT_UNDEFINED, heap); ULINT_UNDEFINED, &heap);
if (!page_rec_validate(rec, offsets)) { if (!page_rec_validate(rec, offsets)) {
goto func_exit; goto func_exit;
......
...@@ -284,28 +284,25 @@ rec_init_offsets( ...@@ -284,28 +284,25 @@ rec_init_offsets(
/********************************************************** /**********************************************************
The following function determines the offsets to each field The following function determines the offsets to each field
in the record. The offsets are returned in an array of in the record. It can reuse a previously returned array. */
ulint, with [0] being the number of fields (n), [1] being the
extra size (if REC_OFFS_COMPACT is set, the record is in the new
format), and [2]..[n+1] being the offsets past the end of
fields 0..n, or to the beginning of fields 1..n+1. When the
high-order bit of the offset at [n+1] is set (REC_OFFS_SQL_NULL),
the field n is NULL. When the second high-order bit of the offset
at [n+1] is set (REC_OFFS_EXTERNAL), the field n is being stored
externally. */
ulint* ulint*
rec_get_offsets( rec_get_offsets_func(
/*============*/ /*=================*/
/* out: the offsets */ /* out: the new offsets */
rec_t* rec, /* in: physical record */ rec_t* rec, /* in: physical record */
dict_index_t* index, /* in: record descriptor */ dict_index_t* index, /* in: record descriptor */
ulint* offsets,/* in: array consisting of offsets[0]
allocated elements, or an array from
rec_get_offsets(), or NULL */
ulint n_fields,/* in: maximum number of initialized fields ulint n_fields,/* in: maximum number of initialized fields
(ULINT_UNDEFINED if all fields) */ (ULINT_UNDEFINED if all fields) */
mem_heap_t* heap) /* in: memory heap */ mem_heap_t** heap, /* in/out: memory heap */
const char* file, /* in: file name where called */
ulint line) /* in: line number where called */
{ {
ulint* offsets;
ulint n; ulint n;
ulint size;
ut_ad(rec); ut_ad(rec);
ut_ad(index); ut_ad(index);
...@@ -336,71 +333,18 @@ rec_get_offsets( ...@@ -336,71 +333,18 @@ rec_get_offsets(
n = n_fields; n = n_fields;
} }
offsets = mem_heap_alloc(heap, size = (n + (1 + REC_OFFS_HEADER_SIZE)) * sizeof(ulint);
(n + (1 + REC_OFFS_HEADER_SIZE)) * sizeof(ulint));
offsets[0] = n;
rec_init_offsets(rec, index, offsets);
return(offsets);
}
/**********************************************************
The following function determines the offsets to each field
in the record. It differs from rec_get_offsets() by trying to
reuse a previously returned array. */
ulint*
rec_reget_offsets(
/*==============*/
/* out: the new offsets */
rec_t* rec, /* in: physical record */
dict_index_t* index, /* in: record descriptor */
ulint* offsets,/* in: array of offsets
from rec_get_offsets()
or rec_reget_offsets(), or NULL */
ulint n_fields,/* in: maximum number of initialized fields
(ULINT_UNDEFINED if all fields) */
mem_heap_t* heap) /* in: memory heap */
{
ulint n;
ut_ad(rec);
ut_ad(index);
ut_ad(heap);
if (index->table->comp) {
switch (rec_get_status(rec)) {
case REC_STATUS_ORDINARY:
n = dict_index_get_n_fields(index);
break;
case REC_STATUS_NODE_PTR:
n = dict_index_get_n_unique_in_tree(index) + 1;
break;
case REC_STATUS_INFIMUM:
case REC_STATUS_SUPREMUM:
/* infimum or supremum record */
n = 1;
break;
default:
ut_error;
return(NULL);
}
} else {
n = rec_get_n_fields_old(rec);
}
if (n_fields < n) { if (!offsets || rec_offs_get_n_alloc(offsets) < size) {
n = n_fields; if (!*heap) {
*heap = mem_heap_create_func(size,
NULL, MEM_HEAP_DYNAMIC, file, line);
} }
offsets = mem_heap_alloc(*heap, size);
if (!offsets || rec_offs_n_fields(offsets) < n) { rec_offs_set_n_alloc(offsets, size);
offsets = mem_heap_alloc(heap,
(n + (1 + REC_OFFS_HEADER_SIZE)) * sizeof(ulint));
} }
offsets[0] = n; rec_offs_set_n_fields(offsets, n);
rec_init_offsets(rec, index, offsets); rec_init_offsets(rec, index, offsets);
return(offsets); return(offsets);
} }
...@@ -722,14 +666,16 @@ rec_get_size( ...@@ -722,14 +666,16 @@ rec_get_size(
rec_t* rec, /* in: physical record */ rec_t* rec, /* in: physical record */
dict_index_t* index) /* in: record descriptor */ dict_index_t* index) /* in: record descriptor */
{ {
mem_heap_t* heap mem_heap_t* heap = NULL;
= mem_heap_create(100); ulint offsets_[100 + REC_OFFS_HEADER_SIZE]
ulint* offsets = { 100, };
= rec_get_offsets(rec, index, ULINT_UNDEFINED, heap); ulint* offsets = rec_get_offsets(rec, index, offsets_,
ulint size ULINT_UNDEFINED, &heap);
= rec_offs_size(offsets); ulint size = rec_offs_size(offsets);
if (heap) {
mem_heap_free(heap); mem_heap_free(heap);
}
return(size); return(size);
} }
...@@ -1032,11 +978,16 @@ rec_convert_dtuple_to_rec( ...@@ -1032,11 +978,16 @@ rec_convert_dtuple_to_rec(
#ifdef UNIV_DEBUG #ifdef UNIV_DEBUG
{ {
mem_heap_t* heap = mem_heap_create(100); mem_heap_t* heap = NULL;
ut_ad(rec_validate(rec, ulint offsets_[100 + REC_OFFS_HEADER_SIZE]
rec_get_offsets(rec, index, ULINT_UNDEFINED, heap))); = { 100, };
const ulint* offsets = rec_get_offsets(rec, index,
offsets_, ULINT_UNDEFINED, &heap);
ut_ad(rec_validate(rec, offsets));
if (heap) {
mem_heap_free(heap); mem_heap_free(heap);
} }
}
#endif /* UNIV_DEBUG */ #endif /* UNIV_DEBUG */
return(rec); return(rec);
} }
...@@ -1059,9 +1010,11 @@ rec_copy_prefix_to_dtuple( ...@@ -1059,9 +1010,11 @@ rec_copy_prefix_to_dtuple(
ulint len; ulint len;
byte* buf = NULL; byte* buf = NULL;
ulint i; ulint i;
ulint* offsets; ulint offsets_[100 + REC_OFFS_HEADER_SIZE]
= { 100, };
ulint* offsets = offsets_;
offsets = rec_get_offsets(rec, index, n_fields, heap); offsets = rec_get_offsets(rec, index, offsets, n_fields, &heap);
ut_ad(rec_validate(rec, offsets)); ut_ad(rec_validate(rec, offsets));
ut_ad(dtuple_check_typed(tuple)); ut_ad(dtuple_check_typed(tuple));
...@@ -1406,8 +1359,8 @@ rec_print_old( ...@@ -1406,8 +1359,8 @@ rec_print_old(
Prints a physical record. */ Prints a physical record. */
void void
rec_print( rec_print_new(
/*======*/ /*==========*/
FILE* file, /* in: file where to print */ FILE* file, /* in: file where to print */
rec_t* rec, /* in: physical record */ rec_t* rec, /* in: physical record */
const ulint* offsets)/* in: array returned by rec_get_offsets() */ const ulint* offsets)/* in: array returned by rec_get_offsets() */
...@@ -1416,6 +1369,8 @@ rec_print( ...@@ -1416,6 +1369,8 @@ rec_print(
ulint len; ulint len;
ulint i; ulint i;
ut_ad(rec_offs_validate(rec, NULL, offsets));
if (!rec_offs_comp(offsets)) { if (!rec_offs_comp(offsets)) {
rec_print_old(file, rec); rec_print_old(file, rec);
return; return;
...@@ -1453,3 +1408,30 @@ rec_print( ...@@ -1453,3 +1408,30 @@ rec_print(
rec_validate(rec, offsets); rec_validate(rec, offsets);
} }
/*******************************************************************
Prints a physical record. */
void
rec_print(
/*======*/
FILE* file, /* in: file where to print */
rec_t* rec, /* in: physical record */
dict_index_t* index) /* in: record descriptor */
{
ut_ad(index);
if (!index->table->comp) {
rec_print_old(file, rec);
return;
} else {
mem_heap_t* heap = NULL;
ulint offsets_[100 + REC_OFFS_HEADER_SIZE]
= { 100, };
rec_print_new(file, rec, rec_get_offsets(rec, index, offsets_,
ULINT_UNDEFINED, &heap));
if (heap) {
mem_heap_free(heap);
}
}
}
...@@ -590,16 +590,8 @@ row_ins_foreign_report_err( ...@@ -590,16 +590,8 @@ row_ins_foreign_report_err(
fputs(", in index ", ef); fputs(", in index ", ef);
ut_print_name(ef, trx, foreign->foreign_index->name); ut_print_name(ef, trx, foreign->foreign_index->name);
if (rec) { if (rec) {
mem_heap_t* heap;
ulint* offsets;
heap = mem_heap_create(100);
offsets = rec_get_offsets(rec, foreign->foreign_index,
ULINT_UNDEFINED, heap);
fputs(", there is a record:\n", ef); fputs(", there is a record:\n", ef);
rec_print(ef, rec, offsets); rec_print(ef, rec, foreign->foreign_index);
mem_heap_free(heap);
} else { } else {
fputs(", the record is not available\n", ef); fputs(", the record is not available\n", ef);
} }
...@@ -654,16 +646,7 @@ row_ins_foreign_report_add_err( ...@@ -654,16 +646,7 @@ row_ins_foreign_report_add_err(
} }
if (rec) { if (rec) {
mem_heap_t* heap; rec_print(ef, rec, foreign->foreign_index);
ulint* offsets;
heap = mem_heap_create(100);
offsets = rec_get_offsets(rec, foreign->foreign_index,
ULINT_UNDEFINED, heap);
rec_print(ef, rec, offsets);
mem_heap_free(heap);
} }
putc('\n', ef); putc('\n', ef);
...@@ -734,7 +717,8 @@ row_ins_foreign_check_on_constraint( ...@@ -734,7 +717,8 @@ row_ins_foreign_check_on_constraint(
ulint i; ulint i;
trx_t* trx; trx_t* trx;
mem_heap_t* tmp_heap = NULL; mem_heap_t* tmp_heap = NULL;
ulint* offsets; ulint offsets_[100] = { 100, };
ulint* offsets = offsets_;
ut_a(thr && foreign && pcur && mtr); ut_a(thr && foreign && pcur && mtr);
...@@ -880,14 +864,10 @@ row_ins_foreign_check_on_constraint( ...@@ -880,14 +864,10 @@ row_ins_foreign_check_on_constraint(
fputs("\n" fputs("\n"
"InnoDB: record ", stderr); "InnoDB: record ", stderr);
offsets = rec_get_offsets(rec, index, rec_print(stderr, rec, index);
ULINT_UNDEFINED, tmp_heap);
rec_print(stderr, rec, offsets);
fputs("\n" fputs("\n"
"InnoDB: clustered record ", stderr); "InnoDB: clustered record ", stderr);
offsets = rec_reget_offsets(clust_rec, clust_index, rec_print(stderr, clust_rec, clust_index);
offsets, ULINT_UNDEFINED, tmp_heap);
rec_print(stderr, clust_rec, offsets);
fputs("\n" fputs("\n"
"InnoDB: Submit a detailed bug report to http://bugs.mysql.com\n", stderr); "InnoDB: Submit a detailed bug report to http://bugs.mysql.com\n", stderr);
...@@ -906,11 +886,8 @@ row_ins_foreign_check_on_constraint( ...@@ -906,11 +886,8 @@ row_ins_foreign_check_on_constraint(
we already have a normal shared lock on the appropriate we already have a normal shared lock on the appropriate
gap if the search criterion was not unique */ gap if the search criterion was not unique */
if (!tmp_heap) { offsets = rec_get_offsets(clust_rec, clust_index, offsets,
tmp_heap = mem_heap_create(256); ULINT_UNDEFINED, &tmp_heap);
}
offsets = rec_get_offsets(clust_rec, clust_index,
ULINT_UNDEFINED, tmp_heap);
err = lock_clust_rec_read_check_and_lock(0, clust_rec, err = lock_clust_rec_read_check_and_lock(0, clust_rec,
clust_index, offsets, LOCK_X, LOCK_REC_NOT_GAP, thr); clust_index, offsets, LOCK_X, LOCK_REC_NOT_GAP, thr);
} }
...@@ -1153,10 +1130,9 @@ row_ins_check_foreign_constraint( ...@@ -1153,10 +1130,9 @@ row_ins_check_foreign_constraint(
ulint i; ulint i;
mtr_t mtr; mtr_t mtr;
trx_t* trx = thr_get_trx(thr); trx_t* trx = thr_get_trx(thr);
mem_heap_t* heap; mem_heap_t* heap = NULL;
ulint* offsets = NULL; ulint offsets_[100] = { 100, };
ulint* offsets = offsets_;
heap = mem_heap_create(100);
run_again: run_again:
#ifdef UNIV_SYNC_DEBUG #ifdef UNIV_SYNC_DEBUG
...@@ -1168,8 +1144,7 @@ run_again: ...@@ -1168,8 +1144,7 @@ run_again:
if (trx->check_foreigns == FALSE) { if (trx->check_foreigns == FALSE) {
/* The user has suppressed foreign key checks currently for /* The user has suppressed foreign key checks currently for
this session */ this session */
mem_heap_free(heap); goto exit_func;
return(DB_SUCCESS);
} }
/* If any of the foreign key fields in entry is SQL NULL, we /* If any of the foreign key fields in entry is SQL NULL, we
...@@ -1180,8 +1155,7 @@ run_again: ...@@ -1180,8 +1155,7 @@ run_again:
if (UNIV_SQL_NULL == dfield_get_len( if (UNIV_SQL_NULL == dfield_get_len(
dtuple_get_nth_field(entry, i))) { dtuple_get_nth_field(entry, i))) {
mem_heap_free(heap); goto exit_func;
return(DB_SUCCESS);
} }
} }
...@@ -1205,8 +1179,7 @@ run_again: ...@@ -1205,8 +1179,7 @@ run_again:
another, and the user has problems predicting in another, and the user has problems predicting in
which order they are performed. */ which order they are performed. */
mem_heap_free(heap); goto exit_func;
return(DB_SUCCESS);
} }
} }
...@@ -1219,8 +1192,6 @@ run_again: ...@@ -1219,8 +1192,6 @@ run_again:
} }
if (check_table == NULL) { if (check_table == NULL) {
mem_heap_free(heap);
if (check_ref) { if (check_ref) {
FILE* ef = dict_foreign_err_file; FILE* ef = dict_foreign_err_file;
mutex_enter(&dict_foreign_err_mutex); mutex_enter(&dict_foreign_err_mutex);
...@@ -1242,10 +1213,10 @@ run_again: ...@@ -1242,10 +1213,10 @@ run_again:
fputs(" does not currently exist!\n", ef); fputs(" does not currently exist!\n", ef);
mutex_exit(&dict_foreign_err_mutex); mutex_exit(&dict_foreign_err_mutex);
return(DB_NO_REFERENCED_ROW); err = DB_NO_REFERENCED_ROW;
} }
return(DB_SUCCESS); goto exit_func;
} }
ut_a(check_table && check_index); ut_a(check_table && check_index);
...@@ -1291,8 +1262,8 @@ run_again: ...@@ -1291,8 +1262,8 @@ run_again:
goto next_rec; goto next_rec;
} }
offsets = rec_reget_offsets(rec, check_index, offsets = rec_get_offsets(rec, check_index,
offsets, ULINT_UNDEFINED, heap); offsets, ULINT_UNDEFINED, &heap);
if (rec == page_get_supremum_rec(buf_frame_align(rec))) { if (rec == page_get_supremum_rec(buf_frame_align(rec))) {
...@@ -1424,7 +1395,10 @@ do_possible_lock_wait: ...@@ -1424,7 +1395,10 @@ do_possible_lock_wait:
err = trx->error_state; err = trx->error_state;
} }
exit_func:
if (heap) {
mem_heap_free(heap); mem_heap_free(heap);
}
return(err); return(err);
} }
...@@ -1565,8 +1539,9 @@ row_ins_scan_sec_index_for_duplicate( ...@@ -1565,8 +1539,9 @@ row_ins_scan_sec_index_for_duplicate(
ibool moved; ibool moved;
mtr_t mtr; mtr_t mtr;
trx_t* trx; trx_t* trx;
mem_heap_t* heap; mem_heap_t* heap = NULL;
ulint* offsets = NULL; ulint offsets_[100] = { 100, };
ulint* offsets = offsets_;
n_unique = dict_index_get_n_unique(index); n_unique = dict_index_get_n_unique(index);
...@@ -1582,7 +1557,6 @@ row_ins_scan_sec_index_for_duplicate( ...@@ -1582,7 +1557,6 @@ row_ins_scan_sec_index_for_duplicate(
} }
} }
heap = mem_heap_create(100);
mtr_start(&mtr); mtr_start(&mtr);
/* Store old value on n_fields_cmp */ /* Store old value on n_fields_cmp */
...@@ -1608,8 +1582,8 @@ row_ins_scan_sec_index_for_duplicate( ...@@ -1608,8 +1582,8 @@ row_ins_scan_sec_index_for_duplicate(
trx = thr_get_trx(thr); trx = thr_get_trx(thr);
ut_ad(trx); ut_ad(trx);
offsets = rec_reget_offsets(rec, index, offsets = rec_get_offsets(rec, index, offsets,
offsets, ULINT_UNDEFINED, heap); ULINT_UNDEFINED, &heap);
if (innobase_query_is_replace()) { if (innobase_query_is_replace()) {
...@@ -1662,7 +1636,9 @@ next_rec: ...@@ -1662,7 +1636,9 @@ next_rec:
} }
} }
if (heap) {
mem_heap_free(heap); mem_heap_free(heap);
}
mtr_commit(&mtr); mtr_commit(&mtr);
/* Restore old value */ /* Restore old value */
...@@ -1693,6 +1669,10 @@ row_ins_duplicate_error_in_clust( ...@@ -1693,6 +1669,10 @@ row_ins_duplicate_error_in_clust(
page_t* page; page_t* page;
ulint n_unique; ulint n_unique;
trx_t* trx = thr_get_trx(thr); trx_t* trx = thr_get_trx(thr);
mem_heap_t*heap = NULL;
ulint offsets_[100] = { 100, };
ulint* offsets = offsets_;
UT_NOT_USED(mtr); UT_NOT_USED(mtr);
...@@ -1720,12 +1700,8 @@ row_ins_duplicate_error_in_clust( ...@@ -1720,12 +1700,8 @@ row_ins_duplicate_error_in_clust(
page = buf_frame_align(rec); page = buf_frame_align(rec);
if (rec != page_get_infimum_rec(page)) { if (rec != page_get_infimum_rec(page)) {
mem_heap_t* heap; offsets = rec_get_offsets(rec, cursor->index, offsets,
ulint* offsets; ULINT_UNDEFINED, &heap);
heap = mem_heap_create(100);
offsets = rec_get_offsets(rec, cursor->index,
ULINT_UNDEFINED, heap);
/* We set a lock on the possible duplicate: this /* We set a lock on the possible duplicate: this
is needed in logical logging of MySQL to make is needed in logical logging of MySQL to make
...@@ -1750,17 +1726,15 @@ row_ins_duplicate_error_in_clust( ...@@ -1750,17 +1726,15 @@ row_ins_duplicate_error_in_clust(
} }
if (err != DB_SUCCESS) { if (err != DB_SUCCESS) {
mem_heap_free(heap); goto func_exit;
return(err);
} }
if (row_ins_dupl_error_with_rec(rec, entry, if (row_ins_dupl_error_with_rec(rec, entry,
cursor->index, offsets)) { cursor->index, offsets)) {
trx->error_info = cursor->index; trx->error_info = cursor->index;
mem_heap_free(heap); err = DB_DUPLICATE_KEY;
return(DB_DUPLICATE_KEY); goto func_exit;
} }
mem_heap_free(heap);
} }
} }
...@@ -1770,12 +1744,8 @@ row_ins_duplicate_error_in_clust( ...@@ -1770,12 +1744,8 @@ row_ins_duplicate_error_in_clust(
page = buf_frame_align(rec); page = buf_frame_align(rec);
if (rec != page_get_supremum_rec(page)) { if (rec != page_get_supremum_rec(page)) {
mem_heap_t* heap; offsets = rec_get_offsets(rec, cursor->index, offsets,
ulint* offsets; ULINT_UNDEFINED, &heap);
heap = mem_heap_create(100);
offsets = rec_get_offsets(rec, cursor->index,
ULINT_UNDEFINED, heap);
/* The manual defines the REPLACE semantics that it /* The manual defines the REPLACE semantics that it
is either an INSERT or DELETE(s) for duplicate key is either an INSERT or DELETE(s) for duplicate key
...@@ -1795,15 +1765,14 @@ row_ins_duplicate_error_in_clust( ...@@ -1795,15 +1765,14 @@ row_ins_duplicate_error_in_clust(
} }
if (err != DB_SUCCESS) { if (err != DB_SUCCESS) {
mem_heap_free(heap); goto func_exit;
return(err);
} }
if (row_ins_dupl_error_with_rec(rec, entry, if (row_ins_dupl_error_with_rec(rec, entry,
cursor->index, offsets)) { cursor->index, offsets)) {
trx->error_info = cursor->index; trx->error_info = cursor->index;
mem_heap_free(heap); err = DB_DUPLICATE_KEY;
return(DB_DUPLICATE_KEY); goto func_exit;
} }
mem_heap_free(heap); mem_heap_free(heap);
} }
...@@ -1812,7 +1781,9 @@ row_ins_duplicate_error_in_clust( ...@@ -1812,7 +1781,9 @@ row_ins_duplicate_error_in_clust(
/* This should never happen */ /* This should never happen */
} }
return(DB_SUCCESS); err = DB_SUCCESS;
func_exit:
return(err);
} }
/******************************************************************* /*******************************************************************
...@@ -1894,8 +1865,9 @@ row_ins_index_entry_low( ...@@ -1894,8 +1865,9 @@ row_ins_index_entry_low(
ulint n_unique; ulint n_unique;
big_rec_t* big_rec = NULL; big_rec_t* big_rec = NULL;
mtr_t mtr; mtr_t mtr;
mem_heap_t* heap = mem_heap_create(100); mem_heap_t* heap = NULL;
ulint* offsets = NULL; ulint offsets_[100] = { 100, };
ulint* offsets = offsets_;
log_free_check(); log_free_check();
...@@ -2023,8 +1995,8 @@ function_exit: ...@@ -2023,8 +1995,8 @@ function_exit:
btr_cur_search_to_nth_level(index, 0, entry, PAGE_CUR_LE, btr_cur_search_to_nth_level(index, 0, entry, PAGE_CUR_LE,
BTR_MODIFY_TREE, &cursor, 0, &mtr); BTR_MODIFY_TREE, &cursor, 0, &mtr);
rec = btr_cur_get_rec(&cursor); rec = btr_cur_get_rec(&cursor);
offsets = rec_reget_offsets(rec, index, offsets = rec_get_offsets(rec, index, offsets,
offsets, ULINT_UNDEFINED, heap); ULINT_UNDEFINED, &heap);
err = btr_store_big_rec_extern_fields(index, rec, err = btr_store_big_rec_extern_fields(index, rec,
offsets, big_rec, &mtr); offsets, big_rec, &mtr);
...@@ -2038,7 +2010,9 @@ function_exit: ...@@ -2038,7 +2010,9 @@ function_exit:
mtr_commit(&mtr); mtr_commit(&mtr);
} }
if (heap) {
mem_heap_free(heap); mem_heap_free(heap);
}
return(err); return(err);
} }
......
...@@ -3215,7 +3215,6 @@ row_scan_and_check_index( ...@@ -3215,7 +3215,6 @@ row_scan_and_check_index(
ulint* n_rows) /* out: number of entries seen in the ulint* n_rows) /* out: number of entries seen in the
current consistent read */ current consistent read */
{ {
mem_heap_t* heap;
dtuple_t* prev_entry = NULL; dtuple_t* prev_entry = NULL;
ulint matched_fields; ulint matched_fields;
ulint matched_bytes; ulint matched_bytes;
...@@ -3226,7 +3225,9 @@ row_scan_and_check_index( ...@@ -3226,7 +3225,9 @@ row_scan_and_check_index(
int cmp; int cmp;
ibool contains_null; ibool contains_null;
ulint i; ulint i;
ulint* offsets = NULL; mem_heap_t* heap = NULL;
ulint offsets_[100] = { 100, };
ulint* offsets = offsets_;
*n_rows = 0; *n_rows = 0;
...@@ -3268,8 +3269,8 @@ loop: ...@@ -3268,8 +3269,8 @@ loop:
matched_fields = 0; matched_fields = 0;
matched_bytes = 0; matched_bytes = 0;
offsets = rec_reget_offsets(rec, index, offsets = rec_get_offsets(rec, index, offsets,
offsets, ULINT_UNDEFINED, heap); ULINT_UNDEFINED, &heap);
cmp = cmp_dtuple_rec_with_match(prev_entry, rec, offsets, cmp = cmp_dtuple_rec_with_match(prev_entry, rec, offsets,
&matched_fields, &matched_fields,
&matched_bytes); &matched_bytes);
...@@ -3299,7 +3300,7 @@ loop: ...@@ -3299,7 +3300,7 @@ loop:
dtuple_print(stderr, prev_entry); dtuple_print(stderr, prev_entry);
fputs("\n" fputs("\n"
"InnoDB: record ", stderr); "InnoDB: record ", stderr);
rec_print(stderr, rec, offsets); rec_print_new(stderr, rec, offsets);
putc('\n', stderr); putc('\n', stderr);
is_ok = FALSE; is_ok = FALSE;
} else if ((index->type & DICT_UNIQUE) } else if ((index->type & DICT_UNIQUE)
...@@ -3313,7 +3314,7 @@ loop: ...@@ -3313,7 +3314,7 @@ loop:
} }
mem_heap_empty(heap); mem_heap_empty(heap);
offsets = NULL; offsets = offsets_;
prev_entry = row_rec_to_index_entry(ROW_COPY_DATA, index, rec, heap); prev_entry = row_rec_to_index_entry(ROW_COPY_DATA, index, rec, heap);
......
...@@ -100,7 +100,8 @@ row_purge_remove_clust_if_poss_low( ...@@ -100,7 +100,8 @@ row_purge_remove_clust_if_poss_low(
ulint err; ulint err;
mtr_t mtr; mtr_t mtr;
rec_t* rec; rec_t* rec;
mem_heap_t* heap; mem_heap_t* heap = NULL;
ulint offsets_[100] = { 100, };
index = dict_table_get_first_index(node->table); index = dict_table_get_first_index(node->table);
...@@ -120,19 +121,22 @@ row_purge_remove_clust_if_poss_low( ...@@ -120,19 +121,22 @@ row_purge_remove_clust_if_poss_low(
} }
rec = btr_pcur_get_rec(pcur); rec = btr_pcur_get_rec(pcur);
heap = mem_heap_create(100);
if (0 != ut_dulint_cmp(node->roll_ptr, if (0 != ut_dulint_cmp(node->roll_ptr,
row_get_rec_roll_ptr(rec, index, rec_get_offsets( row_get_rec_roll_ptr(rec, index, rec_get_offsets(
rec, index, ULINT_UNDEFINED, heap)))) { rec, index, offsets_, ULINT_UNDEFINED, &heap)))) {
if (heap) {
mem_heap_free(heap); mem_heap_free(heap);
}
/* Someone else has modified the record later: do not remove */ /* Someone else has modified the record later: do not remove */
btr_pcur_commit_specify_mtr(pcur, &mtr); btr_pcur_commit_specify_mtr(pcur, &mtr);
return(TRUE); return(TRUE);
} }
if (heap) {
mem_heap_free(heap); mem_heap_free(heap);
}
if (mode == BTR_MODIFY_LEAF) { if (mode == BTR_MODIFY_LEAF) {
success = btr_cur_optimistic_delete(btr_cur, &mtr); success = btr_cur_optimistic_delete(btr_cur, &mtr);
......
...@@ -202,17 +202,16 @@ row_build( ...@@ -202,17 +202,16 @@ row_build(
ulint row_len; ulint row_len;
byte* buf; byte* buf;
ulint i; ulint i;
mem_heap_t* tmp_heap; mem_heap_t* tmp_heap = NULL;
ulint offsets_[100] = { 100, };
ut_ad(index && rec && heap); ut_ad(index && rec && heap);
ut_ad(index->type & DICT_CLUSTERED); ut_ad(index->type & DICT_CLUSTERED);
if (!offsets) { if (!offsets) {
tmp_heap = mem_heap_create(100); offsets = rec_get_offsets(rec, index, offsets_,
offsets = rec_get_offsets(rec, index, ULINT_UNDEFINED, &tmp_heap);
ULINT_UNDEFINED, tmp_heap);
} else { } else {
tmp_heap = NULL;
ut_ad(rec_offs_validate(rec, index, offsets)); ut_ad(rec_offs_validate(rec, index, offsets));
} }
...@@ -296,13 +295,14 @@ row_rec_to_index_entry( ...@@ -296,13 +295,14 @@ row_rec_to_index_entry(
ulint len; ulint len;
ulint rec_len; ulint rec_len;
byte* buf; byte* buf;
mem_heap_t* tmp_heap; mem_heap_t* tmp_heap = NULL;
ulint* offsets; ulint offsets_[100] = { 100, };
ulint* offsets = offsets_;
ut_ad(rec && heap && index); ut_ad(rec && heap && index);
tmp_heap = mem_heap_create(100); offsets = rec_get_offsets(rec, index, offsets,
offsets = rec_get_offsets(rec, index, ULINT_UNDEFINED, tmp_heap); ULINT_UNDEFINED, &tmp_heap);
if (type == ROW_COPY_DATA) { if (type == ROW_COPY_DATA) {
/* Take a copy of rec to heap */ /* Take a copy of rec to heap */
...@@ -334,7 +334,9 @@ row_rec_to_index_entry( ...@@ -334,7 +334,9 @@ row_rec_to_index_entry(
} }
ut_ad(dtuple_check_typed(entry)); ut_ad(dtuple_check_typed(entry));
if (tmp_heap) {
mem_heap_free(tmp_heap); mem_heap_free(tmp_heap);
}
return(entry); return(entry);
} }
...@@ -374,13 +376,14 @@ row_build_row_ref( ...@@ -374,13 +376,14 @@ row_build_row_ref(
byte* buf; byte* buf;
ulint clust_col_prefix_len; ulint clust_col_prefix_len;
ulint i; ulint i;
mem_heap_t* tmp_heap; mem_heap_t* tmp_heap = NULL;
ulint* offsets; ulint offsets_[100] = { 100, };
ulint* offsets = offsets_;
ut_ad(index && rec && heap); ut_ad(index && rec && heap);
tmp_heap = mem_heap_create(100); offsets = rec_get_offsets(rec, index, offsets,
offsets = rec_get_offsets(rec, index, ULINT_UNDEFINED, tmp_heap); ULINT_UNDEFINED, &tmp_heap);
if (type == ROW_COPY_DATA) { if (type == ROW_COPY_DATA) {
/* Take a copy of rec to heap */ /* Take a copy of rec to heap */
...@@ -433,7 +436,9 @@ row_build_row_ref( ...@@ -433,7 +436,9 @@ row_build_row_ref(
} }
ut_ad(dtuple_check_typed(ref)); ut_ad(dtuple_check_typed(ref));
if (tmp_heap) {
mem_heap_free(tmp_heap); mem_heap_free(tmp_heap);
}
return(ref); return(ref);
} }
...@@ -464,8 +469,9 @@ row_build_row_ref_in_tuple( ...@@ -464,8 +469,9 @@ row_build_row_ref_in_tuple(
ulint pos; ulint pos;
ulint clust_col_prefix_len; ulint clust_col_prefix_len;
ulint i; ulint i;
mem_heap_t* heap; mem_heap_t* heap = NULL;
ulint* offsets; ulint offsets_[100] = { 100, };
ulint* offsets = offsets_;
ut_a(ref && index && rec); ut_a(ref && index && rec);
...@@ -486,8 +492,7 @@ row_build_row_ref_in_tuple( ...@@ -486,8 +492,7 @@ row_build_row_ref_in_tuple(
goto notfound; goto notfound;
} }
heap = mem_heap_create(100); offsets = rec_get_offsets(rec, index, offsets, ULINT_UNDEFINED, &heap);
offsets = rec_get_offsets(rec, index, ULINT_UNDEFINED, heap);
ref_len = dict_index_get_n_unique(clust_index); ref_len = dict_index_get_n_unique(clust_index);
...@@ -526,7 +531,9 @@ row_build_row_ref_in_tuple( ...@@ -526,7 +531,9 @@ row_build_row_ref_in_tuple(
} }
ut_ad(dtuple_check_typed(ref)); ut_ad(dtuple_check_typed(ref));
if (heap) {
mem_heap_free(heap); mem_heap_free(heap);
}
} }
/*********************************************************************** /***********************************************************************
......
...@@ -78,14 +78,19 @@ row_sel_sec_rec_is_for_clust_rec( ...@@ -78,14 +78,19 @@ row_sel_sec_rec_is_for_clust_rec(
ulint n; ulint n;
ulint i; ulint i;
dtype_t* cur_type; dtype_t* cur_type;
mem_heap_t* heap; mem_heap_t* heap = NULL;
ulint* clust_offs; ulint clust_offsets_[100]
ulint* sec_offs; = { 100, };
ulint sec_offsets_[10]
heap = mem_heap_create(100); = { 10, };
clust_offs = rec_get_offsets(clust_rec, clust_index, ulint* clust_offs = clust_offsets_;
ULINT_UNDEFINED, heap); ulint* sec_offs = sec_offsets_;
sec_offs = rec_get_offsets(sec_rec, sec_index, ULINT_UNDEFINED, heap); ibool is_equal = TRUE;
clust_offs = rec_get_offsets(clust_rec, clust_index, clust_offs,
ULINT_UNDEFINED, &heap);
sec_offs = rec_get_offsets(sec_rec, sec_index, sec_offs,
ULINT_UNDEFINED, &heap);
n = dict_index_get_n_ordering_defined_by_user(sec_index); n = dict_index_get_n_ordering_defined_by_user(sec_index);
...@@ -113,13 +118,16 @@ row_sel_sec_rec_is_for_clust_rec( ...@@ -113,13 +118,16 @@ row_sel_sec_rec_is_for_clust_rec(
if (0 != cmp_data_data(dict_col_get_type(col), if (0 != cmp_data_data(dict_col_get_type(col),
clust_field, clust_len, clust_field, clust_len,
sec_field, sec_len)) { sec_field, sec_len)) {
mem_heap_free(heap); is_equal = FALSE;
return(FALSE); goto func_exit;
} }
} }
func_exit:
if (heap) {
mem_heap_free(heap); mem_heap_free(heap);
return(TRUE); }
return(is_equal);
} }
/************************************************************************* /*************************************************************************
...@@ -612,13 +620,13 @@ row_sel_get_clust_rec( ...@@ -612,13 +620,13 @@ row_sel_get_clust_rec(
rec_t* clust_rec; rec_t* clust_rec;
rec_t* old_vers; rec_t* old_vers;
ulint err; ulint err;
mem_heap_t* heap; mem_heap_t* heap = NULL;
ulint* offsets; ulint offsets_[100] = { 100, };
ulint* offsets = offsets_;
heap = mem_heap_create(100);
offsets = rec_get_offsets(rec, offsets = rec_get_offsets(rec,
btr_pcur_get_btr_cur(&plan->pcur)->index, btr_pcur_get_btr_cur(&plan->pcur)->index,
ULINT_UNDEFINED, heap); offsets, ULINT_UNDEFINED, &heap);
row_build_row_ref_fast(plan->clust_ref, plan->clust_map, rec, offsets); row_build_row_ref_fast(plan->clust_ref, plan->clust_map, rec, offsets);
...@@ -654,8 +662,8 @@ row_sel_get_clust_rec( ...@@ -654,8 +662,8 @@ row_sel_get_clust_rec(
goto func_exit; goto func_exit;
} }
offsets = rec_reget_offsets(clust_rec, index, offsets = rec_get_offsets(clust_rec, index, offsets,
offsets, ULINT_UNDEFINED, heap); ULINT_UNDEFINED, &heap);
if (!node->read_view) { if (!node->read_view) {
/* Try to place a lock on the index record */ /* Try to place a lock on the index record */
...@@ -677,8 +685,7 @@ row_sel_get_clust_rec( ...@@ -677,8 +685,7 @@ row_sel_get_clust_rec(
if (err != DB_SUCCESS) { if (err != DB_SUCCESS) {
mem_heap_free(heap); goto err_exit;
return(err);
} }
} else { } else {
/* This is a non-locking consistent read: if necessary, fetch /* This is a non-locking consistent read: if necessary, fetch
...@@ -693,8 +700,7 @@ row_sel_get_clust_rec( ...@@ -693,8 +700,7 @@ row_sel_get_clust_rec(
clust_rec, &old_vers, mtr); clust_rec, &old_vers, mtr);
if (err != DB_SUCCESS) { if (err != DB_SUCCESS) {
mem_heap_free(heap); goto err_exit;
return(err);
} }
clust_rec = old_vers; clust_rec = old_vers;
...@@ -731,9 +737,12 @@ row_sel_get_clust_rec( ...@@ -731,9 +737,12 @@ row_sel_get_clust_rec(
UT_LIST_GET_FIRST(plan->columns)); UT_LIST_GET_FIRST(plan->columns));
func_exit: func_exit:
*out_rec = clust_rec; *out_rec = clust_rec;
err = DB_SUCCESS;
err_exit:
if (heap) {
mem_heap_free(heap); mem_heap_free(heap);
return(DB_SUCCESS); }
return(err);
} }
/************************************************************************* /*************************************************************************
...@@ -975,8 +984,10 @@ row_sel_try_search_shortcut( ...@@ -975,8 +984,10 @@ row_sel_try_search_shortcut(
{ {
dict_index_t* index; dict_index_t* index;
rec_t* rec; rec_t* rec;
mem_heap_t* heap; mem_heap_t* heap = NULL;
ulint* offsets; ulint offsets_[100] = { 100, };
ulint* offsets = offsets_;
ulint ret;
index = plan->index; index = plan->index;
...@@ -1010,43 +1021,46 @@ row_sel_try_search_shortcut( ...@@ -1010,43 +1021,46 @@ row_sel_try_search_shortcut(
/* This is a non-locking consistent read: if necessary, fetch /* This is a non-locking consistent read: if necessary, fetch
a previous version of the record */ a previous version of the record */
heap = mem_heap_create(100); offsets = rec_get_offsets(rec, index, offsets, ULINT_UNDEFINED, &heap);
offsets = rec_get_offsets(rec, index, ULINT_UNDEFINED, heap);
if (index->type & DICT_CLUSTERED) { if (index->type & DICT_CLUSTERED) {
if (!lock_clust_rec_cons_read_sees(rec, index, offsets, if (!lock_clust_rec_cons_read_sees(rec, index, offsets,
node->read_view)) { node->read_view)) {
mem_heap_free(heap); ret = SEL_RETRY;
return(SEL_RETRY); goto func_exit;
} }
} else if (!lock_sec_rec_cons_read_sees(rec, index, node->read_view)) { } else if (!lock_sec_rec_cons_read_sees(rec, index, node->read_view)) {
mem_heap_free(heap); ret = SEL_RETRY;
return(SEL_RETRY); goto func_exit;
} }
/* Test deleted flag. Fetch the columns needed in test conditions. */ /* Test deleted flag. Fetch the columns needed in test conditions. */
row_sel_fetch_columns(index, rec, offsets, row_sel_fetch_columns(index, rec, offsets,
UT_LIST_GET_FIRST(plan->columns)); UT_LIST_GET_FIRST(plan->columns));
mem_heap_free(heap);
if (rec_get_deleted_flag(rec, plan->table->comp)) { if (rec_get_deleted_flag(rec, plan->table->comp)) {
return(SEL_EXHAUSTED); ret = SEL_EXHAUSTED;
goto func_exit;
} }
/* Test the rest of search conditions */ /* Test the rest of search conditions */
if (!row_sel_test_other_conds(plan)) { if (!row_sel_test_other_conds(plan)) {
return(SEL_EXHAUSTED); ret = SEL_EXHAUSTED;
goto func_exit;
} }
ut_ad(plan->pcur.latch_mode == node->latch_mode); ut_ad(plan->pcur.latch_mode == node->latch_mode);
plan->n_rows_fetched++; plan->n_rows_fetched++;
func_exit:
if (heap) {
mem_heap_free(heap);
}
return(SEL_FOUND); return(SEL_FOUND);
} }
...@@ -1095,8 +1109,9 @@ row_sel( ...@@ -1095,8 +1109,9 @@ row_sel(
to the next non-clustered record */ to the next non-clustered record */
ulint found_flag; ulint found_flag;
ulint err; ulint err;
mem_heap_t* heap = mem_heap_create(100); mem_heap_t* heap = NULL;
ulint* offsets = NULL; ulint offsets_[100] = { 100, };
ulint* offsets = offsets_;
ut_ad(thr->run_node == node); ut_ad(thr->run_node == node);
...@@ -1253,8 +1268,8 @@ rec_loop: ...@@ -1253,8 +1268,8 @@ rec_loop:
rec_t* next_rec = page_rec_get_next(rec); rec_t* next_rec = page_rec_get_next(rec);
ulint lock_type; ulint lock_type;
offsets = rec_reget_offsets(next_rec, index, offsets = rec_get_offsets(next_rec, index, offsets,
offsets, ULINT_UNDEFINED, heap); ULINT_UNDEFINED, &heap);
if (srv_locks_unsafe_for_binlog) { if (srv_locks_unsafe_for_binlog) {
lock_type = LOCK_REC_NOT_GAP; lock_type = LOCK_REC_NOT_GAP;
...@@ -1295,8 +1310,8 @@ rec_loop: ...@@ -1295,8 +1310,8 @@ rec_loop:
not used. */ not used. */
ulint lock_type; ulint lock_type;
offsets = rec_reget_offsets(rec, index, offsets = rec_get_offsets(rec, index, offsets,
offsets, ULINT_UNDEFINED, heap); ULINT_UNDEFINED, &heap);
if (srv_locks_unsafe_for_binlog) { if (srv_locks_unsafe_for_binlog) {
lock_type = LOCK_REC_NOT_GAP; lock_type = LOCK_REC_NOT_GAP;
...@@ -1369,8 +1384,7 @@ rec_loop: ...@@ -1369,8 +1384,7 @@ rec_loop:
/* PHASE 3: Get previous version in a consistent read */ /* PHASE 3: Get previous version in a consistent read */
cons_read_requires_clust_rec = FALSE; cons_read_requires_clust_rec = FALSE;
offsets = rec_reget_offsets(rec, index, offsets = rec_get_offsets(rec, index, offsets, ULINT_UNDEFINED, &heap);
offsets, ULINT_UNDEFINED, heap);
if (consistent_read) { if (consistent_read) {
/* This is a non-locking consistent read: if necessary, fetch /* This is a non-locking consistent read: if necessary, fetch
...@@ -1403,8 +1417,8 @@ rec_loop: ...@@ -1403,8 +1417,8 @@ rec_loop:
} }
rec = old_vers; rec = old_vers;
offsets = rec_reget_offsets(rec, index, offsets = rec_get_offsets(rec, index, offsets,
offsets, ULINT_UNDEFINED, heap); ULINT_UNDEFINED, &heap);
} }
} else if (!lock_sec_rec_cons_read_sees(rec, index, } else if (!lock_sec_rec_cons_read_sees(rec, index,
node->read_view)) { node->read_view)) {
...@@ -1635,8 +1649,8 @@ next_table_no_mtr: ...@@ -1635,8 +1649,8 @@ next_table_no_mtr:
rw_lock_s_unlock(&btr_search_latch); rw_lock_s_unlock(&btr_search_latch);
} }
mem_heap_free(heap); err = DB_SUCCESS;
return(DB_SUCCESS); goto func_exit;
} }
node->fetch_table++; node->fetch_table++;
...@@ -1669,7 +1683,7 @@ table_exhausted: ...@@ -1669,7 +1683,7 @@ table_exhausted:
table_exhausted_no_mtr: table_exhausted_no_mtr:
if (node->fetch_table == 0) { if (node->fetch_table == 0) {
mem_heap_free(heap); err = DB_SUCCESS;
if (node->is_aggregate && !node->aggregate_already_fetched) { if (node->is_aggregate && !node->aggregate_already_fetched) {
...@@ -1683,7 +1697,7 @@ table_exhausted_no_mtr: ...@@ -1683,7 +1697,7 @@ table_exhausted_no_mtr:
rw_lock_s_unlock(&btr_search_latch); rw_lock_s_unlock(&btr_search_latch);
} }
return(DB_SUCCESS); goto func_exit;
} }
node->state = SEL_NODE_NO_MORE_ROWS; node->state = SEL_NODE_NO_MORE_ROWS;
...@@ -1694,7 +1708,7 @@ table_exhausted_no_mtr: ...@@ -1694,7 +1708,7 @@ table_exhausted_no_mtr:
rw_lock_s_unlock(&btr_search_latch); rw_lock_s_unlock(&btr_search_latch);
} }
return(DB_SUCCESS); goto func_exit;
} }
node->fetch_table--; node->fetch_table--;
...@@ -1718,8 +1732,8 @@ stop_for_a_while: ...@@ -1718,8 +1732,8 @@ stop_for_a_while:
mtr_commit(&mtr); mtr_commit(&mtr);
ut_ad(sync_thread_levels_empty_gen(TRUE)); ut_ad(sync_thread_levels_empty_gen(TRUE));
mem_heap_free(heap); err = DB_SUCCESS;
return(DB_SUCCESS); goto func_exit;
commit_mtr_for_a_while: commit_mtr_for_a_while:
/* Stores the cursor position and commits &mtr; this is used if /* Stores the cursor position and commits &mtr; this is used if
...@@ -1754,7 +1768,10 @@ lock_wait_or_error: ...@@ -1754,7 +1768,10 @@ lock_wait_or_error:
ut_ad(sync_thread_levels_empty_gen(TRUE)); ut_ad(sync_thread_levels_empty_gen(TRUE));
func_exit:
if (heap) {
mem_heap_free(heap); mem_heap_free(heap);
}
return(err); return(err);
} }
...@@ -2197,7 +2214,7 @@ row_sel_store_row_id_to_prebuilt( ...@@ -2197,7 +2214,7 @@ row_sel_store_row_id_to_prebuilt(
fprintf(stderr, "\n" fprintf(stderr, "\n"
"InnoDB: Field number %lu, record:\n", "InnoDB: Field number %lu, record:\n",
(ulong) dict_index_get_sys_col_pos(index, DATA_ROW_ID)); (ulong) dict_index_get_sys_col_pos(index, DATA_ROW_ID));
rec_print(stderr, index_rec, offsets); rec_print_new(stderr, index_rec, offsets);
putc('\n', stderr); putc('\n', stderr);
ut_error; ut_error;
} }
...@@ -2496,8 +2513,9 @@ row_sel_get_clust_rec_for_mysql( ...@@ -2496,8 +2513,9 @@ row_sel_get_clust_rec_for_mysql(
rec_t* old_vers; rec_t* old_vers;
ulint err; ulint err;
trx_t* trx; trx_t* trx;
mem_heap_t* heap = mem_heap_create(100); mem_heap_t* heap = NULL;
ulint* offsets = NULL; ulint offsets_[100] = { 100, };
ulint* offsets = offsets_;
*out_rec = NULL; *out_rec = NULL;
trx = thr_get_trx(thr); trx = thr_get_trx(thr);
...@@ -2537,14 +2555,10 @@ row_sel_get_clust_rec_for_mysql( ...@@ -2537,14 +2555,10 @@ row_sel_get_clust_rec_for_mysql(
dict_index_name_print(stderr, trx, sec_index); dict_index_name_print(stderr, trx, sec_index);
fputs("\n" fputs("\n"
"InnoDB: sec index record ", stderr); "InnoDB: sec index record ", stderr);
offsets = rec_get_offsets(rec, sec_index, rec_print(stderr, rec, sec_index);
ULINT_UNDEFINED, heap);
rec_print(stderr, rec, offsets);
fputs("\n" fputs("\n"
"InnoDB: clust index record ", stderr); "InnoDB: clust index record ", stderr);
offsets = rec_reget_offsets(clust_rec, clust_index, rec_print(stderr, clust_rec, clust_index);
offsets, ULINT_UNDEFINED, heap);
rec_print(stderr, clust_rec, offsets);
putc('\n', stderr); putc('\n', stderr);
trx_print(stderr, trx); trx_print(stderr, trx);
...@@ -2557,8 +2571,8 @@ row_sel_get_clust_rec_for_mysql( ...@@ -2557,8 +2571,8 @@ row_sel_get_clust_rec_for_mysql(
goto func_exit; goto func_exit;
} }
offsets = rec_get_offsets(clust_rec, clust_index, offsets = rec_get_offsets(clust_rec, clust_index, offsets,
ULINT_UNDEFINED, heap); ULINT_UNDEFINED, &heap);
if (prebuilt->select_lock_type != LOCK_NONE) { if (prebuilt->select_lock_type != LOCK_NONE) {
/* Try to place a lock on the index record; we are searching /* Try to place a lock on the index record; we are searching
...@@ -2571,8 +2585,7 @@ row_sel_get_clust_rec_for_mysql( ...@@ -2571,8 +2585,7 @@ row_sel_get_clust_rec_for_mysql(
LOCK_REC_NOT_GAP, thr); LOCK_REC_NOT_GAP, thr);
if (err != DB_SUCCESS) { if (err != DB_SUCCESS) {
mem_heap_free(heap); goto err_exit;
return(err);
} }
} else { } else {
/* This is a non-locking consistent read: if necessary, fetch /* This is a non-locking consistent read: if necessary, fetch
...@@ -2594,8 +2607,7 @@ row_sel_get_clust_rec_for_mysql( ...@@ -2594,8 +2607,7 @@ row_sel_get_clust_rec_for_mysql(
if (err != DB_SUCCESS) { if (err != DB_SUCCESS) {
mem_heap_free(heap); goto err_exit;
return(err);
} }
clust_rec = old_vers; clust_rec = old_vers;
...@@ -2637,8 +2649,12 @@ func_exit: ...@@ -2637,8 +2649,12 @@ func_exit:
btr_pcur_store_position(prebuilt->clust_pcur, mtr); btr_pcur_store_position(prebuilt->clust_pcur, mtr);
} }
err = DB_SUCCESS;
err_exit:
if (heap) {
mem_heap_free(heap); mem_heap_free(heap);
return(DB_SUCCESS); }
return(err);
} }
/************************************************************************ /************************************************************************
...@@ -2809,8 +2825,8 @@ row_sel_try_search_shortcut_for_mysql( ...@@ -2809,8 +2825,8 @@ row_sel_try_search_shortcut_for_mysql(
/* out: SEL_FOUND, SEL_EXHAUSTED, SEL_RETRY */ /* out: SEL_FOUND, SEL_EXHAUSTED, SEL_RETRY */
rec_t** out_rec,/* out: record if found */ rec_t** out_rec,/* out: record if found */
row_prebuilt_t* prebuilt,/* in: prebuilt struct */ row_prebuilt_t* prebuilt,/* in: prebuilt struct */
ulint** offsets,/* in/out: for rec_reget_offsets(*out_rec) */ ulint** offsets,/* in/out: for rec_get_offsets(*out_rec) */
mem_heap_t* heap, /* in: heap for rec_reget_offsets() */ mem_heap_t** heap, /* in/out: heap for rec_get_offsets() */
mtr_t* mtr) /* in: started mtr */ mtr_t* mtr) /* in: started mtr */
{ {
dict_index_t* index = prebuilt->index; dict_index_t* index = prebuilt->index;
...@@ -2849,8 +2865,8 @@ row_sel_try_search_shortcut_for_mysql( ...@@ -2849,8 +2865,8 @@ row_sel_try_search_shortcut_for_mysql(
/* This is a non-locking consistent read: if necessary, fetch /* This is a non-locking consistent read: if necessary, fetch
a previous version of the record */ a previous version of the record */
*offsets = rec_reget_offsets(rec, index, *offsets = rec_get_offsets(rec, index, *offsets,
*offsets, ULINT_UNDEFINED, heap); ULINT_UNDEFINED, heap);
if (!lock_clust_rec_cons_read_sees(rec, index, if (!lock_clust_rec_cons_read_sees(rec, index,
*offsets, trx->read_view)) { *offsets, trx->read_view)) {
...@@ -2915,7 +2931,6 @@ row_search_for_mysql( ...@@ -2915,7 +2931,6 @@ row_search_for_mysql(
ibool moved; ibool moved;
ibool cons_read_requires_clust_rec; ibool cons_read_requires_clust_rec;
ibool was_lock_wait; ibool was_lock_wait;
ulint ret;
ulint shortcut; ulint shortcut;
ibool unique_search = FALSE; ibool unique_search = FALSE;
ibool unique_search_from_clust_index = FALSE; ibool unique_search_from_clust_index = FALSE;
...@@ -2931,8 +2946,9 @@ row_search_for_mysql( ...@@ -2931,8 +2946,9 @@ row_search_for_mysql(
ulint cnt = 0; ulint cnt = 0;
ulint next_offs; ulint next_offs;
mtr_t mtr; mtr_t mtr;
mem_heap_t* heap; mem_heap_t* heap = NULL;
ulint* offsets = NULL; ulint offsets_[100] = { 100, };
ulint* offsets = offsets_;
ut_ad(index && pcur && search_tuple); ut_ad(index && pcur && search_tuple);
ut_ad(trx->mysql_thread_id == os_thread_get_curr_id()); ut_ad(trx->mysql_thread_id == os_thread_get_curr_id());
...@@ -3023,9 +3039,8 @@ row_search_for_mysql( ...@@ -3023,9 +3039,8 @@ row_search_for_mysql(
prebuilt->n_rows_fetched++; prebuilt->n_rows_fetched++;
srv_n_rows_read++; srv_n_rows_read++;
trx->op_info = ""; err = DB_SUCCESS;
goto func_exit;
return(DB_SUCCESS);
} }
if (prebuilt->fetch_cache_first > 0 if (prebuilt->fetch_cache_first > 0
...@@ -3035,8 +3050,8 @@ row_search_for_mysql( ...@@ -3035,8 +3050,8 @@ row_search_for_mysql(
cache, but the cache was not full at the time of the cache, but the cache was not full at the time of the
popping: no more rows can exist in the result set */ popping: no more rows can exist in the result set */
trx->op_info = ""; err = DB_RECORD_NOT_FOUND;
return(DB_RECORD_NOT_FOUND); goto func_exit;
} }
prebuilt->n_rows_fetched++; prebuilt->n_rows_fetched++;
...@@ -3080,13 +3095,12 @@ row_search_for_mysql( ...@@ -3080,13 +3095,12 @@ row_search_for_mysql(
if (direction != 0 && !prebuilt->used_in_HANDLER) { if (direction != 0 && !prebuilt->used_in_HANDLER) {
trx->op_info = ""; err = DB_RECORD_NOT_FOUND;
return(DB_RECORD_NOT_FOUND); goto func_exit;
} }
} }
mtr_start(&mtr); mtr_start(&mtr);
heap = mem_heap_create(100);
/*-------------------------------------------------------------*/ /*-------------------------------------------------------------*/
/* PHASE 2: Try fast adaptive hash index search if possible */ /* PHASE 2: Try fast adaptive hash index search if possible */
...@@ -3132,7 +3146,7 @@ row_search_for_mysql( ...@@ -3132,7 +3146,7 @@ row_search_for_mysql(
} }
#endif #endif
shortcut = row_sel_try_search_shortcut_for_mysql(&rec, shortcut = row_sel_try_search_shortcut_for_mysql(&rec,
prebuilt, &offsets, heap, &mtr); prebuilt, &offsets, &heap, &mtr);
if (shortcut == SEL_FOUND) { if (shortcut == SEL_FOUND) {
#ifdef UNIV_SEARCH_DEBUG #ifdef UNIV_SEARCH_DEBUG
ut_a(0 == cmp_dtuple_rec(search_tuple, ut_a(0 == cmp_dtuple_rec(search_tuple,
...@@ -3163,12 +3177,10 @@ row_search_for_mysql( ...@@ -3163,12 +3177,10 @@ row_search_for_mysql(
trx->has_search_latch = FALSE; trx->has_search_latch = FALSE;
} }
trx->op_info = "";
/* NOTE that we do NOT store the cursor /* NOTE that we do NOT store the cursor
position */ position */
mem_heap_free(heap); err = DB_SUCCESS;
return(DB_SUCCESS); goto func_exit;
} else if (shortcut == SEL_EXHAUSTED) { } else if (shortcut == SEL_EXHAUSTED) {
...@@ -3186,13 +3198,11 @@ row_search_for_mysql( ...@@ -3186,13 +3198,11 @@ row_search_for_mysql(
trx->has_search_latch = FALSE; trx->has_search_latch = FALSE;
} }
trx->op_info = "";
/* NOTE that we do NOT store the cursor /* NOTE that we do NOT store the cursor
position */ position */
mem_heap_free(heap); err = DB_RECORD_NOT_FOUND;
return(DB_RECORD_NOT_FOUND); goto func_exit;
} }
shortcut_fails_too_big_rec: shortcut_fails_too_big_rec:
mtr_commit(&mtr); mtr_commit(&mtr);
...@@ -3334,9 +3344,9 @@ rec_loop: ...@@ -3334,9 +3344,9 @@ rec_loop:
we do not lock gaps. Supremum record is really we do not lock gaps. Supremum record is really
a gap and therefore we do not set locks there. */ a gap and therefore we do not set locks there. */
if (srv_locks_unsafe_for_binlog == FALSE) { if (!srv_locks_unsafe_for_binlog) {
offsets = rec_reget_offsets(rec, index, offsets = rec_get_offsets(rec, index, offsets,
offsets, ULINT_UNDEFINED, heap); ULINT_UNDEFINED, &heap);
err = sel_set_rec_lock(rec, index, offsets, err = sel_set_rec_lock(rec, index, offsets,
prebuilt->select_lock_type, prebuilt->select_lock_type,
LOCK_ORDINARY, thr); LOCK_ORDINARY, thr);
...@@ -3406,8 +3416,7 @@ rec_loop: ...@@ -3406,8 +3416,7 @@ rec_loop:
} }
} }
offsets = rec_reget_offsets(rec, index, offsets = rec_get_offsets(rec, index, offsets, ULINT_UNDEFINED, &heap);
offsets, ULINT_UNDEFINED, heap);
if (srv_force_recovery > 0) { if (srv_force_recovery > 0) {
if (!rec_validate(rec, offsets) if (!rec_validate(rec, offsets)
...@@ -3464,7 +3473,7 @@ rec_loop: ...@@ -3464,7 +3473,7 @@ rec_loop:
btr_pcur_store_position(pcur, &mtr); btr_pcur_store_position(pcur, &mtr);
ret = DB_RECORD_NOT_FOUND; err = DB_RECORD_NOT_FOUND;
/* ut_print_name(stderr, index->name); /* ut_print_name(stderr, index->name);
fputs(" record not found 3\n", stderr); */ fputs(" record not found 3\n", stderr); */
...@@ -3498,7 +3507,7 @@ rec_loop: ...@@ -3498,7 +3507,7 @@ rec_loop:
btr_pcur_store_position(pcur, &mtr); btr_pcur_store_position(pcur, &mtr);
ret = DB_RECORD_NOT_FOUND; err = DB_RECORD_NOT_FOUND;
/* ut_print_name(stderr, index->name); /* ut_print_name(stderr, index->name);
fputs(" record not found 4\n", stderr); */ fputs(" record not found 4\n", stderr); */
...@@ -3644,11 +3653,11 @@ rec_loop: ...@@ -3644,11 +3653,11 @@ rec_loop:
if (prebuilt->need_to_access_clustered) { if (prebuilt->need_to_access_clustered) {
ut_ad(rec == clust_rec || index == clust_index); ut_ad(rec == clust_rec || index == clust_index);
offsets = rec_reget_offsets(rec, clust_index, offsets = rec_get_offsets(rec, clust_index, offsets,
offsets, ULINT_UNDEFINED, heap); ULINT_UNDEFINED, &heap);
} else { } else {
offsets = rec_reget_offsets(rec, index, offsets = rec_get_offsets(rec, index, offsets,
offsets, ULINT_UNDEFINED, heap); ULINT_UNDEFINED, &heap);
} }
/* We found a qualifying row */ /* We found a qualifying row */
...@@ -3694,8 +3703,8 @@ rec_loop: ...@@ -3694,8 +3703,8 @@ rec_loop:
} }
if (prebuilt->clust_index_was_generated) { if (prebuilt->clust_index_was_generated) {
offsets = rec_reget_offsets(index_rec, index, offsets, offsets = rec_get_offsets(index_rec, index, offsets,
ULINT_UNDEFINED, heap); ULINT_UNDEFINED, &heap);
row_sel_store_row_id_to_prebuilt(prebuilt, index_rec, row_sel_store_row_id_to_prebuilt(prebuilt, index_rec,
index, offsets); index, offsets);
} }
...@@ -3717,7 +3726,7 @@ got_row: ...@@ -3717,7 +3726,7 @@ got_row:
btr_pcur_store_position(pcur, &mtr); btr_pcur_store_position(pcur, &mtr);
} }
ret = DB_SUCCESS; err = DB_SUCCESS;
goto normal_return; goto normal_return;
...@@ -3756,9 +3765,9 @@ next_rec: ...@@ -3756,9 +3765,9 @@ next_rec:
btr_pcur_store_position(pcur, &mtr); btr_pcur_store_position(pcur, &mtr);
if (match_mode != 0) { if (match_mode != 0) {
ret = DB_RECORD_NOT_FOUND; err = DB_RECORD_NOT_FOUND;
} else { } else {
ret = DB_END_OF_INDEX; err = DB_END_OF_INDEX;
} }
goto normal_return; goto normal_return;
...@@ -3797,10 +3806,7 @@ lock_wait_or_error: ...@@ -3797,10 +3806,7 @@ lock_wait_or_error:
/* fputs("Using ", stderr); /* fputs("Using ", stderr);
dict_index_name_print(stderr, index); dict_index_name_print(stderr, index);
fprintf(stderr, " cnt %lu ret value %lu err\n", cnt, err); */ fprintf(stderr, " cnt %lu ret value %lu err\n", cnt, err); */
trx->op_info = ""; goto func_exit;
mem_heap_free(heap);
return(err);
normal_return: normal_return:
/*-------------------------------------------------------------*/ /*-------------------------------------------------------------*/
...@@ -3811,20 +3817,22 @@ normal_return: ...@@ -3811,20 +3817,22 @@ normal_return:
if (prebuilt->n_fetch_cached > 0) { if (prebuilt->n_fetch_cached > 0) {
row_sel_pop_cached_row_for_mysql(buf, prebuilt); row_sel_pop_cached_row_for_mysql(buf, prebuilt);
ret = DB_SUCCESS; err = DB_SUCCESS;
} }
/* fputs("Using ", stderr); /* fputs("Using ", stderr);
dict_index_name_print(stderr, index); dict_index_name_print(stderr, index);
fprintf(stderr, " cnt %lu ret value %lu err\n", cnt, err); */ fprintf(stderr, " cnt %lu ret value %lu err\n", cnt, err); */
if (ret == DB_SUCCESS) { if (err == DB_SUCCESS) {
srv_n_rows_read++; srv_n_rows_read++;
} }
func_exit:
trx->op_info = ""; trx->op_info = "";
if (heap) {
mem_heap_free(heap); mem_heap_free(heap);
return(ret); }
return(err);
} }
/*********************************************************************** /***********************************************************************
......
...@@ -430,7 +430,6 @@ row_undo_mod_del_unmark_sec_and_undo_update( ...@@ -430,7 +430,6 @@ row_undo_mod_del_unmark_sec_and_undo_update(
found = row_search_index_entry(index, entry, mode, &pcur, &mtr); found = row_search_index_entry(index, entry, mode, &pcur, &mtr);
if (!found) { if (!found) {
heap = mem_heap_create(100);
fputs("InnoDB: error in sec index entry del undo in\n" fputs("InnoDB: error in sec index entry del undo in\n"
"InnoDB: ", stderr); "InnoDB: ", stderr);
dict_index_name_print(stderr, trx, index); dict_index_name_print(stderr, trx, index);
...@@ -439,14 +438,11 @@ row_undo_mod_del_unmark_sec_and_undo_update( ...@@ -439,14 +438,11 @@ row_undo_mod_del_unmark_sec_and_undo_update(
dtuple_print(stderr, entry); dtuple_print(stderr, entry);
fputs("\n" fputs("\n"
"InnoDB: record ", stderr); "InnoDB: record ", stderr);
rec_print(stderr, btr_pcur_get_rec(&pcur), rec_print(stderr, btr_pcur_get_rec(&pcur), index);
rec_get_offsets(btr_pcur_get_rec(&pcur),
index, ULINT_UNDEFINED, heap));
putc('\n', stderr); putc('\n', stderr);
trx_print(stderr, trx); trx_print(stderr, trx);
fputs("\n" fputs("\n"
"InnoDB: Submit a detailed bug report to http://bugs.mysql.com\n", stderr); "InnoDB: Submit a detailed bug report to http://bugs.mysql.com\n", stderr);
mem_heap_free(heap);
} else { } else {
btr_cur_t* btr_cur = btr_pcur_get_btr_cur(&pcur); btr_cur_t* btr_cur = btr_pcur_get_btr_cur(&pcur);
......
...@@ -151,8 +151,9 @@ row_undo_search_clust_to_pcur( ...@@ -151,8 +151,9 @@ row_undo_search_clust_to_pcur(
mtr_t mtr; mtr_t mtr;
ibool ret; ibool ret;
rec_t* rec; rec_t* rec;
mem_heap_t* heap; mem_heap_t* heap = NULL;
const ulint* offsets; ulint offsets_[100] = { 100, };
ulint* offsets = offsets_;
mtr_start(&mtr); mtr_start(&mtr);
...@@ -163,8 +164,8 @@ row_undo_search_clust_to_pcur( ...@@ -163,8 +164,8 @@ row_undo_search_clust_to_pcur(
rec = btr_pcur_get_rec(&(node->pcur)); rec = btr_pcur_get_rec(&(node->pcur));
heap = mem_heap_create(100); offsets = rec_get_offsets(rec, clust_index, offsets,
offsets = rec_get_offsets(rec, clust_index, ULINT_UNDEFINED, heap); ULINT_UNDEFINED, &heap);
if (!found || 0 != ut_dulint_cmp(node->roll_ptr, if (!found || 0 != ut_dulint_cmp(node->roll_ptr,
row_get_rec_roll_ptr(rec, clust_index, offsets))) { row_get_rec_roll_ptr(rec, clust_index, offsets))) {
...@@ -188,6 +189,9 @@ row_undo_search_clust_to_pcur( ...@@ -188,6 +189,9 @@ row_undo_search_clust_to_pcur(
btr_pcur_commit_specify_mtr(&(node->pcur), &mtr); btr_pcur_commit_specify_mtr(&(node->pcur), &mtr);
if (heap) {
mem_heap_free(heap);
}
return(ret); return(ret);
} }
......
...@@ -700,6 +700,7 @@ row_upd_build_sec_rec_difference_binary( ...@@ -700,6 +700,7 @@ row_upd_build_sec_rec_difference_binary(
upd_t* update; upd_t* update;
ulint n_diff; ulint n_diff;
ulint i; ulint i;
ulint offsets_[10] = { 10, };
const ulint* offsets; const ulint* offsets;
/* This function is used only for a secondary index */ /* This function is used only for a secondary index */
...@@ -708,7 +709,8 @@ row_upd_build_sec_rec_difference_binary( ...@@ -708,7 +709,8 @@ row_upd_build_sec_rec_difference_binary(
update = upd_create(dtuple_get_n_fields(entry), heap); update = upd_create(dtuple_get_n_fields(entry), heap);
n_diff = 0; n_diff = 0;
offsets = rec_get_offsets(rec, index, ULINT_UNDEFINED, heap); offsets = rec_get_offsets(rec, index, offsets_,
ULINT_UNDEFINED, &heap);
for (i = 0; i < dtuple_get_n_fields(entry); i++) { for (i = 0; i < dtuple_get_n_fields(entry); i++) {
...@@ -775,6 +777,7 @@ row_upd_build_difference_binary( ...@@ -775,6 +777,7 @@ row_upd_build_difference_binary(
ulint trx_id_pos; ulint trx_id_pos;
ibool extern_bit; ibool extern_bit;
ulint i; ulint i;
ulint offsets_[100] = { 100, };
const ulint* offsets; const ulint* offsets;
/* This function is used only for a clustered index */ /* This function is used only for a clustered index */
...@@ -787,7 +790,8 @@ row_upd_build_difference_binary( ...@@ -787,7 +790,8 @@ row_upd_build_difference_binary(
roll_ptr_pos = dict_index_get_sys_col_pos(index, DATA_ROLL_PTR); roll_ptr_pos = dict_index_get_sys_col_pos(index, DATA_ROLL_PTR);
trx_id_pos = dict_index_get_sys_col_pos(index, DATA_TRX_ID); trx_id_pos = dict_index_get_sys_col_pos(index, DATA_TRX_ID);
offsets = rec_get_offsets(rec, index, ULINT_UNDEFINED, heap); offsets = rec_get_offsets(rec, index, offsets_,
ULINT_UNDEFINED, &heap);
for (i = 0; i < dtuple_get_n_fields(entry); i++) { for (i = 0; i < dtuple_get_n_fields(entry); i++) {
...@@ -1182,7 +1186,8 @@ row_upd_store_row( ...@@ -1182,7 +1186,8 @@ row_upd_store_row(
dict_index_t* clust_index; dict_index_t* clust_index;
upd_t* update; upd_t* update;
rec_t* rec; rec_t* rec;
mem_heap_t* heap; mem_heap_t* heap = NULL;
ulint offsets_[100] = { 100, };
const ulint* offsets; const ulint* offsets;
ut_ad(node->pcur->latch_mode != BTR_NO_LATCHES); ut_ad(node->pcur->latch_mode != BTR_NO_LATCHES);
...@@ -1196,8 +1201,8 @@ row_upd_store_row( ...@@ -1196,8 +1201,8 @@ row_upd_store_row(
rec = btr_pcur_get_rec(node->pcur); rec = btr_pcur_get_rec(node->pcur);
heap = mem_heap_create(100); offsets = rec_get_offsets(rec, clust_index, offsets_,
offsets = rec_get_offsets(rec, clust_index, ULINT_UNDEFINED, heap); ULINT_UNDEFINED, &heap);
node->row = row_build(ROW_COPY_DATA, clust_index, rec, offsets, node->row = row_build(ROW_COPY_DATA, clust_index, rec, offsets,
node->heap); node->heap);
node->ext_vec = mem_heap_alloc(node->heap, sizeof(ulint) node->ext_vec = mem_heap_alloc(node->heap, sizeof(ulint)
...@@ -1210,7 +1215,9 @@ row_upd_store_row( ...@@ -1210,7 +1215,9 @@ row_upd_store_row(
node->n_ext_vec = btr_push_update_extern_fields(node->ext_vec, node->n_ext_vec = btr_push_update_extern_fields(node->ext_vec,
offsets, update); offsets, update);
if (heap) {
mem_heap_free(heap); mem_heap_free(heap);
}
} }
/*************************************************************** /***************************************************************
...@@ -1263,8 +1270,7 @@ row_upd_sec_index_entry( ...@@ -1263,8 +1270,7 @@ row_upd_sec_index_entry(
dtuple_print(stderr, entry); dtuple_print(stderr, entry);
fputs("\n" fputs("\n"
"InnoDB: record ", stderr); "InnoDB: record ", stderr);
rec_print(stderr, rec, rec_print(stderr, rec, index);
rec_get_offsets(rec, index, ULINT_UNDEFINED, heap));
putc('\n', stderr); putc('\n', stderr);
trx_print(stderr, trx); trx_print(stderr, trx);
...@@ -1364,7 +1370,7 @@ row_upd_clust_rec_by_insert( ...@@ -1364,7 +1370,7 @@ row_upd_clust_rec_by_insert(
a foreign key constraint */ a foreign key constraint */
mtr_t* mtr) /* in: mtr; gets committed here */ mtr_t* mtr) /* in: mtr; gets committed here */
{ {
mem_heap_t* heap; mem_heap_t* heap = NULL;
btr_pcur_t* pcur; btr_pcur_t* pcur;
btr_cur_t* btr_cur; btr_cur_t* btr_cur;
trx_t* trx; trx_t* trx;
...@@ -1379,15 +1385,14 @@ row_upd_clust_rec_by_insert( ...@@ -1379,15 +1385,14 @@ row_upd_clust_rec_by_insert(
table = node->table; table = node->table;
pcur = node->pcur; pcur = node->pcur;
btr_cur = btr_pcur_get_btr_cur(pcur); btr_cur = btr_pcur_get_btr_cur(pcur);
heap = mem_heap_create(500);
if (node->state != UPD_NODE_INSERT_CLUSTERED) { if (node->state != UPD_NODE_INSERT_CLUSTERED) {
ulint offsets_[100] = { 100, };
err = btr_cur_del_mark_set_clust_rec(BTR_NO_LOCKING_FLAG, err = btr_cur_del_mark_set_clust_rec(BTR_NO_LOCKING_FLAG,
btr_cur, TRUE, thr, mtr); btr_cur, TRUE, thr, mtr);
if (err != DB_SUCCESS) { if (err != DB_SUCCESS) {
mtr_commit(mtr); mtr_commit(mtr);
mem_heap_free(heap);
return(err); return(err);
} }
...@@ -1398,8 +1403,8 @@ row_upd_clust_rec_by_insert( ...@@ -1398,8 +1403,8 @@ row_upd_clust_rec_by_insert(
btr_cur_mark_extern_inherited_fields(btr_cur_get_rec(btr_cur), btr_cur_mark_extern_inherited_fields(btr_cur_get_rec(btr_cur),
rec_get_offsets(btr_cur_get_rec(btr_cur), rec_get_offsets(btr_cur_get_rec(btr_cur),
dict_table_get_first_index(table), dict_table_get_first_index(table), offsets_,
ULINT_UNDEFINED, heap), node->update, mtr); ULINT_UNDEFINED, &heap), node->update, mtr);
if (check_ref) { if (check_ref) {
/* NOTE that the following call loses /* NOTE that the following call loses
the position of pcur ! */ the position of pcur ! */
...@@ -1408,7 +1413,9 @@ row_upd_clust_rec_by_insert( ...@@ -1408,7 +1413,9 @@ row_upd_clust_rec_by_insert(
index, thr, mtr); index, thr, mtr);
if (err != DB_SUCCESS) { if (err != DB_SUCCESS) {
mtr_commit(mtr); mtr_commit(mtr);
if (heap) {
mem_heap_free(heap);
}
return(err); return(err);
} }
} }
...@@ -1417,6 +1424,9 @@ row_upd_clust_rec_by_insert( ...@@ -1417,6 +1424,9 @@ row_upd_clust_rec_by_insert(
mtr_commit(mtr); mtr_commit(mtr);
if (!heap) {
heap = mem_heap_create(500);
}
node->state = UPD_NODE_INSERT_CLUSTERED; node->state = UPD_NODE_INSERT_CLUSTERED;
entry = row_build_index_entry(node->row, index, heap); entry = row_build_index_entry(node->row, index, heap);
...@@ -1516,17 +1526,20 @@ row_upd_clust_rec( ...@@ -1516,17 +1526,20 @@ row_upd_clust_rec(
mtr_commit(mtr); mtr_commit(mtr);
if (err == DB_SUCCESS && big_rec) { if (err == DB_SUCCESS && big_rec) {
mem_heap_t* heap; mem_heap_t* heap = NULL;
ulint offsets_[100] = { 100, };
rec_t* rec; rec_t* rec;
mtr_start(mtr); mtr_start(mtr);
heap = mem_heap_create(100);
rec = btr_cur_get_rec(btr_cur); rec = btr_cur_get_rec(btr_cur);
ut_a(btr_pcur_restore_position(BTR_MODIFY_TREE, pcur, mtr)); ut_a(btr_pcur_restore_position(BTR_MODIFY_TREE, pcur, mtr));
err = btr_store_big_rec_extern_fields(index, rec, err = btr_store_big_rec_extern_fields(index, rec,
rec_get_offsets(rec, index, ULINT_UNDEFINED, heap), rec_get_offsets(rec, index, offsets_,
ULINT_UNDEFINED, &heap),
big_rec, mtr); big_rec, mtr);
if (heap) {
mem_heap_free(heap); mem_heap_free(heap);
}
mtr_commit(mtr); mtr_commit(mtr);
} }
...@@ -1611,7 +1624,8 @@ row_upd_clust_step( ...@@ -1611,7 +1624,8 @@ row_upd_clust_step(
mtr_t* mtr; mtr_t* mtr;
mtr_t mtr_buf; mtr_t mtr_buf;
rec_t* rec; rec_t* rec;
mem_heap_t* heap; mem_heap_t* heap = NULL;
ulint offsets_[100] = { 100, };
const ulint* offsets; const ulint* offsets;
index = dict_table_get_first_index(node->table); index = dict_table_get_first_index(node->table);
...@@ -1670,33 +1684,31 @@ row_upd_clust_step( ...@@ -1670,33 +1684,31 @@ row_upd_clust_step(
} }
rec = btr_pcur_get_rec(pcur); rec = btr_pcur_get_rec(pcur);
heap = mem_heap_create(100); offsets = rec_get_offsets(rec, index, offsets_,
offsets = rec_get_offsets(rec, index, ULINT_UNDEFINED, heap); ULINT_UNDEFINED, &heap);
if (!node->has_clust_rec_x_lock) { if (!node->has_clust_rec_x_lock) {
err = lock_clust_rec_modify_check_and_lock(0, err = lock_clust_rec_modify_check_and_lock(0,
rec, index, offsets, thr); rec, index, offsets, thr);
if (err != DB_SUCCESS) { if (err != DB_SUCCESS) {
mtr_commit(mtr); mtr_commit(mtr);
mem_heap_free(heap); goto exit_func;
return(err);
} }
} }
/* NOTE: the following function calls will also commit mtr */ /* NOTE: the following function calls will also commit mtr */
if (node->is_delete) { if (node->is_delete) {
mem_heap_free(heap);
err = row_upd_del_mark_clust_rec(node, index, thr, check_ref, err = row_upd_del_mark_clust_rec(node, index, thr, check_ref,
mtr); mtr);
if (err != DB_SUCCESS) { if (err == DB_SUCCESS) {
return(err);
}
node->state = UPD_NODE_UPDATE_ALL_SEC; node->state = UPD_NODE_UPDATE_ALL_SEC;
node->index = dict_table_get_next_index(index); node->index = dict_table_get_next_index(index);
}
exit_func:
if (heap) {
mem_heap_free(heap);
}
return(err); return(err);
} }
...@@ -1711,12 +1723,13 @@ row_upd_clust_step( ...@@ -1711,12 +1723,13 @@ row_upd_clust_step(
row_upd_eval_new_vals(node->update); row_upd_eval_new_vals(node->update);
} }
if (heap) {
mem_heap_free(heap); mem_heap_free(heap);
}
if (node->cmpl_info & UPD_NODE_NO_ORD_CHANGE) { if (node->cmpl_info & UPD_NODE_NO_ORD_CHANGE) {
err = row_upd_clust_rec(node, index, thr, mtr); err = row_upd_clust_rec(node, index, thr, mtr);
return(err); return(err);
} }
...@@ -1968,7 +1981,8 @@ row_upd_in_place_in_select( ...@@ -1968,7 +1981,8 @@ row_upd_in_place_in_select(
btr_pcur_t* pcur; btr_pcur_t* pcur;
btr_cur_t* btr_cur; btr_cur_t* btr_cur;
ulint err; ulint err;
mem_heap_t* heap; mem_heap_t* heap = NULL;
ulint offsets_[100] = { 100, };
ut_ad(sel_node->select_will_do_update); ut_ad(sel_node->select_will_do_update);
ut_ad(sel_node->latch_mode == BTR_MODIFY_LEAF); ut_ad(sel_node->latch_mode == BTR_MODIFY_LEAF);
...@@ -1984,11 +1998,13 @@ row_upd_in_place_in_select( ...@@ -1984,11 +1998,13 @@ row_upd_in_place_in_select(
/* Copy the necessary columns from clust_rec and calculate the new /* Copy the necessary columns from clust_rec and calculate the new
values to set */ values to set */
heap = mem_heap_create(100);
row_upd_copy_columns(btr_pcur_get_rec(pcur), rec_get_offsets( row_upd_copy_columns(btr_pcur_get_rec(pcur), rec_get_offsets(
btr_pcur_get_rec(pcur), btr_cur->index, ULINT_UNDEFINED, heap), btr_pcur_get_rec(pcur), btr_cur->index, offsets_,
ULINT_UNDEFINED, &heap),
UT_LIST_GET_FIRST(node->columns)); UT_LIST_GET_FIRST(node->columns));
if (heap) {
mem_heap_free(heap); mem_heap_free(heap);
}
row_upd_eval_new_vals(node->update); row_upd_eval_new_vals(node->update);
ut_ad(!rec_get_deleted_flag(btr_pcur_get_rec(pcur), ut_ad(!rec_get_deleted_flag(btr_pcur_get_rec(pcur),
......
...@@ -100,32 +100,25 @@ row_vers_impl_x_locked_off_kernel( ...@@ -100,32 +100,25 @@ row_vers_impl_x_locked_off_kernel(
} }
heap = mem_heap_create(1024); heap = mem_heap_create(1024);
clust_offsets = rec_get_offsets(clust_rec, clust_index, clust_offsets = rec_get_offsets(clust_rec, clust_index, NULL,
ULINT_UNDEFINED, heap); ULINT_UNDEFINED, &heap);
trx_id = row_get_rec_trx_id(clust_rec, clust_index, clust_offsets); trx_id = row_get_rec_trx_id(clust_rec, clust_index, clust_offsets);
mtr_s_lock(&(purge_sys->latch), &mtr); mtr_s_lock(&(purge_sys->latch), &mtr);
mutex_enter(&kernel_mutex); mutex_enter(&kernel_mutex);
trx = NULL;
if (!trx_is_active(trx_id)) { if (!trx_is_active(trx_id)) {
/* The transaction that modified or inserted clust_rec is no /* The transaction that modified or inserted clust_rec is no
longer active: no implicit lock on rec */ longer active: no implicit lock on rec */
goto exit_func;
mem_heap_free(heap);
mtr_commit(&mtr);
return(NULL);
} }
if (!lock_check_trx_id_sanity(trx_id, clust_rec, clust_index, if (!lock_check_trx_id_sanity(trx_id, clust_rec, clust_index,
clust_offsets, TRUE)) { clust_offsets, TRUE)) {
/* Corruption noticed: try to avoid a crash by returning */ /* Corruption noticed: try to avoid a crash by returning */
goto exit_func;
mem_heap_free(heap);
mtr_commit(&mtr);
return(NULL);
} }
comp = index->table->comp; comp = index->table->comp;
...@@ -166,7 +159,8 @@ row_vers_impl_x_locked_off_kernel( ...@@ -166,7 +159,8 @@ row_vers_impl_x_locked_off_kernel(
if (prev_version) { if (prev_version) {
clust_offsets = rec_get_offsets(prev_version, clust_offsets = rec_get_offsets(prev_version,
clust_index, ULINT_UNDEFINED, heap); clust_index, NULL,
ULINT_UNDEFINED, &heap);
row = row_build(ROW_COPY_POINTERS, clust_index, row = row_build(ROW_COPY_POINTERS, clust_index,
prev_version, clust_offsets, heap); prev_version, clust_offsets, heap);
entry = row_build_index_entry(row, index, heap); entry = row_build_index_entry(row, index, heap);
...@@ -250,6 +244,7 @@ row_vers_impl_x_locked_off_kernel( ...@@ -250,6 +244,7 @@ row_vers_impl_x_locked_off_kernel(
version = prev_version; version = prev_version;
}/* for (;;) */ }/* for (;;) */
exit_func:
mtr_commit(&mtr); mtr_commit(&mtr);
mem_heap_free(heap); mem_heap_free(heap);
...@@ -330,8 +325,8 @@ row_vers_old_has_index_entry( ...@@ -330,8 +325,8 @@ row_vers_old_has_index_entry(
comp = index->table->comp; comp = index->table->comp;
ut_ad(comp == page_is_comp(buf_frame_align(rec))); ut_ad(comp == page_is_comp(buf_frame_align(rec)));
heap = mem_heap_create(1024); heap = mem_heap_create(1024);
clust_offsets = rec_get_offsets(rec, clust_index, clust_offsets = rec_get_offsets(rec, clust_index, NULL,
ULINT_UNDEFINED, heap); ULINT_UNDEFINED, &heap);
if (also_curr && !rec_get_deleted_flag(rec, comp)) { if (also_curr && !rec_get_deleted_flag(rec, comp)) {
row = row_build(ROW_COPY_POINTERS, clust_index, row = row_build(ROW_COPY_POINTERS, clust_index,
...@@ -371,7 +366,7 @@ row_vers_old_has_index_entry( ...@@ -371,7 +366,7 @@ row_vers_old_has_index_entry(
} }
clust_offsets = rec_get_offsets(prev_version, clust_index, clust_offsets = rec_get_offsets(prev_version, clust_index,
ULINT_UNDEFINED, heap); NULL, ULINT_UNDEFINED, &heap);
if (!rec_get_deleted_flag(prev_version, comp)) { if (!rec_get_deleted_flag(prev_version, comp)) {
row = row_build(ROW_COPY_POINTERS, clust_index, row = row_build(ROW_COPY_POINTERS, clust_index,
...@@ -438,7 +433,7 @@ row_vers_build_for_consistent_read( ...@@ -438,7 +433,7 @@ row_vers_build_for_consistent_read(
#endif /* UNIV_SYNC_DEBUG */ #endif /* UNIV_SYNC_DEBUG */
heap = mem_heap_create(1024); heap = mem_heap_create(1024);
offsets = rec_get_offsets(rec, index, ULINT_UNDEFINED, heap); offsets = rec_get_offsets(rec, index, NULL, ULINT_UNDEFINED, &heap);
ut_ad(!read_view_sees_trx_id(view, ut_ad(!read_view_sees_trx_id(view,
row_get_rec_trx_id(rec, index, offsets))); row_get_rec_trx_id(rec, index, offsets)));
...@@ -466,8 +461,8 @@ row_vers_build_for_consistent_read( ...@@ -466,8 +461,8 @@ row_vers_build_for_consistent_read(
break; break;
} }
offsets = rec_get_offsets(prev_version, index, offsets = rec_get_offsets(prev_version, index, NULL,
ULINT_UNDEFINED, heap); ULINT_UNDEFINED, &heap);
prev_trx_id = row_get_rec_trx_id(prev_version, index, offsets); prev_trx_id = row_get_rec_trx_id(prev_version, index, offsets);
if (read_view_sees_trx_id(view, prev_trx_id)) { if (read_view_sees_trx_id(view, prev_trx_id)) {
......
...@@ -1010,8 +1010,9 @@ trx_undo_report_row_operation( ...@@ -1010,8 +1010,9 @@ trx_undo_report_row_operation(
ibool is_insert; ibool is_insert;
trx_rseg_t* rseg; trx_rseg_t* rseg;
mtr_t mtr; mtr_t mtr;
mem_heap_t* heap; mem_heap_t* heap = NULL;
ulint* offsets = NULL; ulint offsets_[100] = { 100, };
ulint* offsets = offsets_;
ut_a(index->type & DICT_CLUSTERED); ut_a(index->type & DICT_CLUSTERED);
...@@ -1066,8 +1067,6 @@ trx_undo_report_row_operation( ...@@ -1066,8 +1067,6 @@ trx_undo_report_row_operation(
mtr_start(&mtr); mtr_start(&mtr);
heap = mem_heap_create(100);
for (;;) { for (;;) {
undo_page = buf_page_get_gen(undo->space, page_no, undo_page = buf_page_get_gen(undo->space, page_no,
RW_X_LATCH, undo->guess_page, RW_X_LATCH, undo->guess_page,
...@@ -1084,8 +1083,8 @@ trx_undo_report_row_operation( ...@@ -1084,8 +1083,8 @@ trx_undo_report_row_operation(
index, clust_entry, index, clust_entry,
&mtr); &mtr);
} else { } else {
offsets = rec_reget_offsets(rec, index, offsets = rec_get_offsets(rec, index, offsets,
offsets, ULINT_UNDEFINED, heap); ULINT_UNDEFINED, &heap);
offset = trx_undo_page_report_modify(undo_page, trx, offset = trx_undo_page_report_modify(undo_page, trx,
index, rec, offsets, update, cmpl_info, &mtr); index, rec, offsets, update, cmpl_info, &mtr);
} }
...@@ -1129,7 +1128,9 @@ trx_undo_report_row_operation( ...@@ -1129,7 +1128,9 @@ trx_undo_report_row_operation(
mutex_exit(&(trx->undo_mutex)); mutex_exit(&(trx->undo_mutex));
mtr_commit(&mtr); mtr_commit(&mtr);
if (heap) {
mem_heap_free(heap); mem_heap_free(heap);
}
return(DB_OUT_OF_FILE_SPACE); return(DB_OUT_OF_FILE_SPACE);
} }
} }
...@@ -1146,7 +1147,9 @@ trx_undo_report_row_operation( ...@@ -1146,7 +1147,9 @@ trx_undo_report_row_operation(
*roll_ptr = trx_undo_build_roll_ptr(is_insert, rseg->id, page_no, *roll_ptr = trx_undo_build_roll_ptr(is_insert, rseg->id, page_no,
offset); offset);
if (heap) {
mem_heap_free(heap); mem_heap_free(heap);
}
return(DB_SUCCESS); return(DB_SUCCESS);
} }
...@@ -1266,7 +1269,6 @@ trx_undo_prev_version_build( ...@@ -1266,7 +1269,6 @@ trx_undo_prev_version_build(
ibool dummy_extern; ibool dummy_extern;
byte* buf; byte* buf;
ulint err; ulint err;
ulint* index_offsets = NULL;
#ifdef UNIV_SYNC_DEBUG #ifdef UNIV_SYNC_DEBUG
ut_ad(rw_lock_own(&(purge_sys->latch), RW_LOCK_SHARED)); ut_ad(rw_lock_own(&(purge_sys->latch), RW_LOCK_SHARED));
#endif /* UNIV_SYNC_DEBUG */ #endif /* UNIV_SYNC_DEBUG */
...@@ -1282,12 +1284,10 @@ trx_undo_prev_version_build( ...@@ -1282,12 +1284,10 @@ trx_undo_prev_version_build(
"InnoDB: Submit a detailed bug report to" "InnoDB: Submit a detailed bug report to"
" http://bugs.mysql.com\n" " http://bugs.mysql.com\n"
"InnoDB: index record ", index->name); "InnoDB: index record ", index->name);
index_offsets = rec_get_offsets(index_rec, index, rec_print(stderr, index_rec, index);
ULINT_UNDEFINED, heap);
rec_print(stderr, index_rec, index_offsets);
fputs("\n" fputs("\n"
"InnoDB: record version ", stderr); "InnoDB: record version ", stderr);
rec_print(stderr, rec, offsets); rec_print_new(stderr, rec, offsets);
putc('\n', stderr); putc('\n', stderr);
return(DB_ERROR); return(DB_ERROR);
} }
...@@ -1353,12 +1353,10 @@ trx_undo_prev_version_build( ...@@ -1353,12 +1353,10 @@ trx_undo_prev_version_build(
ut_print_buf(stderr, undo_rec, 150); ut_print_buf(stderr, undo_rec, 150);
fputs("\n" fputs("\n"
"InnoDB: index record ", stderr); "InnoDB: index record ", stderr);
index_offsets = rec_get_offsets(index_rec, index, rec_print(stderr, index_rec, index);
ULINT_UNDEFINED, heap);
rec_print(stderr, index_rec, index_offsets);
fputs("\n" fputs("\n"
"InnoDB: record version ", stderr); "InnoDB: record version ", stderr);
rec_print(stderr, rec, offsets); rec_print_new(stderr, rec, offsets);
fprintf(stderr, "\n" fprintf(stderr, "\n"
"InnoDB: Record trx id %lu %lu, update rec trx id %lu %lu\n" "InnoDB: Record trx id %lu %lu, update rec trx id %lu %lu\n"
"InnoDB: Roll ptr in rec %lu %lu, in update rec %lu %lu\n", "InnoDB: Roll ptr in rec %lu %lu, in update rec %lu %lu\n",
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment