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
This diff is collapsed.
This diff is collapsed.
......@@ -262,9 +262,10 @@ btr_pcur_restore_position(
heap = mem_heap_create(256);
offsets1 = rec_get_offsets(cursor->old_rec,
index, ULINT_UNDEFINED, heap);
offsets2 = rec_get_offsets(rec,
index, ULINT_UNDEFINED, heap);
index, NULL,
cursor->old_n_fields, &heap);
offsets2 = rec_get_offsets(rec, index, NULL,
cursor->old_n_fields, &heap);
ut_ad(cmp_rec_rec(cursor->old_rec,
rec, offsets1, offsets2,
......@@ -310,7 +311,7 @@ btr_pcur_restore_position(
&& 0 == cmp_dtuple_rec(tuple, btr_pcur_get_rec(cursor),
rec_get_offsets(btr_pcur_get_rec(cursor),
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
the cursor can now be on a different page! But we can retain
......
......@@ -419,7 +419,9 @@ btr_search_update_hash_ref(
&& (block->curr_n_fields == info->n_fields)
&& (block->curr_n_bytes == info->n_bytes)
&& (block->curr_side == info->side)) {
mem_heap_t* heap;
mem_heap_t* heap = NULL;
ulint offsets_[100] = { 100, };
rec = btr_cur_get_rec(cursor);
if (!page_rec_is_user_rec(rec)) {
......@@ -428,11 +430,13 @@ btr_search_update_hash_ref(
}
tree_id = ((cursor->index)->tree)->id;
heap = mem_heap_create(100);
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);
if (heap) {
mem_heap_free(heap);
}
#ifdef UNIV_SYNC_DEBUG
ut_ad(rw_lock_own(&btr_search_latch, RW_LOCK_EX));
#endif /* UNIV_SYNC_DEBUG */
......@@ -547,8 +551,10 @@ btr_search_check_guess(
ulint match;
ulint bytes;
int cmp;
mem_heap_t* heap = mem_heap_create(100);
ulint* offsets = NULL;
mem_heap_t* heap = NULL;
ulint offsets_[100] = { 100, };
ulint* offsets = offsets_;
ibool success = FALSE;
n_unique = dict_index_get_n_unique_in_tree(cursor->index);
......@@ -560,47 +566,43 @@ btr_search_check_guess(
match = 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,
offsets, &match, &bytes);
if (mode == PAGE_CUR_GE) {
if (cmp == 1) {
mem_heap_free(heap);
return(FALSE);
goto exit_func;
}
cursor->up_match = match;
if (match >= n_unique) {
mem_heap_free(heap);
return(TRUE);
success = TRUE;
goto exit_func;
}
} else if (mode == PAGE_CUR_LE) {
if (cmp == -1) {
mem_heap_free(heap);
return(FALSE);
goto exit_func;
}
cursor->low_match = match;
} else if (mode == PAGE_CUR_G) {
if (cmp != -1) {
mem_heap_free(heap);
return(FALSE);
goto exit_func;
}
} else if (mode == PAGE_CUR_L) {
if (cmp != 1) {
mem_heap_free(heap);
return(FALSE);
goto exit_func;
}
}
if (can_only_compare_to_cursor_rec) {
/* Since we could not determine if our guess is right just by
looking at the record under the cursor, return FALSE */
mem_heap_free(heap);
return(FALSE);
goto exit_func;
}
match = 0;
......@@ -613,28 +615,21 @@ btr_search_check_guess(
prev_rec = page_rec_get_prev(rec);
if (prev_rec == page_get_infimum_rec(page)) {
mem_heap_free(heap);
return(btr_page_get_prev(page, mtr) == FIL_NULL);
success = btr_page_get_prev(page, mtr) == FIL_NULL;
goto exit_func;
}
offsets = rec_reget_offsets(prev_rec, cursor->index,
offsets, n_unique, heap);
offsets = rec_get_offsets(prev_rec, cursor->index, offsets,
n_unique, &heap);
cmp = page_cmp_dtuple_rec_with_match(tuple, prev_rec,
offsets, &match, &bytes);
mem_heap_free(heap);
if (mode == PAGE_CUR_GE) {
if (cmp != 1) {
return(FALSE);
}
success = cmp == 1;
} else {
if (cmp == -1) {
return(FALSE);
}
success = cmp != -1;
}
return(TRUE);
goto exit_func;
}
ut_ad(rec != page_get_supremum_rec(page));
......@@ -642,39 +637,30 @@ btr_search_check_guess(
next_rec = page_rec_get_next(rec);
if (next_rec == page_get_supremum_rec(page)) {
mem_heap_free(heap);
if (btr_page_get_next(page, mtr) == FIL_NULL) {
cursor->up_match = 0;
return(TRUE);
success = TRUE;
}
return(FALSE);
goto exit_func;
}
offsets = rec_reget_offsets(next_rec, cursor->index,
offsets, n_unique, heap);
offsets = rec_get_offsets(next_rec, cursor->index, offsets,
n_unique, &heap);
cmp = page_cmp_dtuple_rec_with_match(tuple, next_rec,
offsets, &match, &bytes);
mem_heap_free(heap);
if (mode == PAGE_CUR_LE) {
if (cmp != -1) {
return(FALSE);
}
success = cmp == -1;
cursor->up_match = match;
} else {
if (cmp == 1) {
return(FALSE);
success = cmp != 1;
}
exit_func:
if (heap) {
mem_heap_free(heap);
}
return(TRUE);
return(success);
}
/**********************************************************************
......@@ -997,14 +983,14 @@ btr_search_drop_page_hash_index(
prev_fold = 0;
heap = mem_heap_create(100);
heap = NULL;
offsets = NULL;
while (rec != sup) {
/* FIXME: in a mixed tree, not all records may have enough
ordering fields: */
offsets = rec_reget_offsets(rec, block->index,
offsets, n_fields + (n_bytes > 0), heap);
offsets = rec_get_offsets(rec, block->index,
offsets, n_fields + (n_bytes > 0), &heap);
fold = rec_fold(rec, offsets, n_fields, n_bytes, tree_id);
if (fold == prev_fold && prev_fold != 0) {
......@@ -1022,7 +1008,9 @@ next_rec:
prev_fold = fold;
}
if (heap) {
mem_heap_free(heap);
}
rw_lock_x_lock(&btr_search_latch);
......@@ -1109,8 +1097,9 @@ btr_search_build_page_hash_index(
ulint* folds;
rec_t** recs;
ulint i;
mem_heap_t* heap;
ulint* offsets;
mem_heap_t* heap = NULL;
ulint offsets_[100] = { 100, };
ulint* offsets = offsets_;
ut_ad(index);
......@@ -1161,7 +1150,6 @@ btr_search_build_page_hash_index(
folds = mem_alloc(n_recs * sizeof(ulint));
recs = mem_alloc(n_recs * sizeof(rec_t*));
heap = mem_heap_create(100);
n_cached = 0;
......@@ -1172,7 +1160,8 @@ btr_search_build_page_hash_index(
rec = page_get_infimum_rec(page);
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) {
ut_a(n_fields <= rec_offs_n_fields(offsets));
......@@ -1208,8 +1197,8 @@ btr_search_build_page_hash_index(
break;
}
offsets = rec_reget_offsets(next_rec, index,
offsets, n_fields + (n_bytes > 0), heap);
offsets = rec_get_offsets(next_rec, index, offsets,
n_fields + (n_bytes > 0), &heap);
next_fold = rec_fold(next_rec, offsets, n_fields,
n_bytes, tree_id);
......@@ -1260,7 +1249,9 @@ exit_func:
mem_free(folds);
mem_free(recs);
if (heap) {
mem_heap_free(heap);
}
}
/************************************************************************
......@@ -1350,7 +1341,8 @@ btr_search_update_hash_on_delete(
ulint fold;
dulint tree_id;
ibool found;
mem_heap_t* heap;
ulint offsets_[100] = { 100, };
mem_heap_t* heap = NULL;
rec = btr_cur_get_rec(cursor);
......@@ -1371,11 +1363,12 @@ btr_search_update_hash_on_delete(
table = btr_search_sys->hash_index;
tree_id = cursor->index->tree->id;
heap = mem_heap_create(100);
fold = rec_fold(rec, rec_get_offsets(rec, cursor->index,
ULINT_UNDEFINED, heap), block->curr_n_fields,
fold = rec_fold(rec, rec_get_offsets(rec, cursor->index, offsets_,
ULINT_UNDEFINED, &heap), block->curr_n_fields,
block->curr_n_bytes, tree_id);
if (heap) {
mem_heap_free(heap);
}
rw_lock_x_lock(&btr_search_latch);
found = ha_search_and_delete_if_found(table, fold, rec);
......@@ -1458,8 +1451,9 @@ btr_search_update_hash_on_insert(
ulint n_bytes;
ulint side;
ibool locked = FALSE;
mem_heap_t* heap;
ulint* offsets;
mem_heap_t* heap = NULL;
ulint offsets_[100] = { 100, };
ulint* offsets = offsets_;
table = btr_search_sys->hash_index;
......@@ -1490,21 +1484,20 @@ btr_search_update_hash_on_insert(
next_rec = page_rec_get_next(ins_rec);
page = buf_frame_align(rec);
heap = mem_heap_create(100);
offsets = rec_get_offsets(ins_rec, cursor->index,
ULINT_UNDEFINED, heap);
offsets = rec_get_offsets(ins_rec, cursor->index, offsets,
ULINT_UNDEFINED, &heap);
ins_fold = rec_fold(ins_rec, offsets, n_fields, n_bytes, tree_id);
if (next_rec != page_get_supremum_rec(page)) {
offsets = rec_reget_offsets(next_rec, cursor->index,
offsets, n_fields + (n_bytes > 0), heap);
offsets = rec_get_offsets(next_rec, cursor->index, offsets,
n_fields + (n_bytes > 0), &heap);
next_fold = rec_fold(next_rec, offsets, n_fields,
n_bytes, tree_id);
}
if (rec != page_get_infimum_rec(page)) {
offsets = rec_reget_offsets(rec, cursor->index,
offsets, n_fields + (n_bytes > 0), heap);
offsets = rec_get_offsets(rec, cursor->index, offsets,
n_fields + (n_bytes > 0), &heap);
fold = rec_fold(rec, offsets, n_fields, n_bytes, tree_id);
} else {
if (side == BTR_SEARCH_LEFT_SIDE) {
......@@ -1575,7 +1568,9 @@ check_next_rec:
}
function_exit:
if (heap) {
mem_heap_free(heap);
}
if (locked) {
rw_lock_x_unlock(&btr_search_latch);
}
......@@ -1595,8 +1590,9 @@ btr_search_validate(void)
ulint n_page_dumps = 0;
ibool ok = TRUE;
ulint i;
mem_heap_t* heap = mem_heap_create(100);
ulint* offsets = NULL;
mem_heap_t* heap = NULL;
ulint offsets_[100] = { 100, };
ulint* offsets = offsets_;
rw_lock_x_lock(&btr_search_latch);
......@@ -1606,10 +1602,10 @@ btr_search_validate(void)
while (node != NULL) {
block = buf_block_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->curr_n_fields
+ (block->curr_n_bytes > 0), heap);
+ (block->curr_n_bytes > 0), &heap);
if (!block->is_hashed
|| node->fold != rec_fold((rec_t*)(node->data),
......@@ -1635,7 +1631,8 @@ btr_search_validate(void)
btr_page_get_index_id(page)));
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."
"Page mem address %p, is hashed %lu, n fields %lu, n bytes %lu\n"
"side %lu\n",
......@@ -1659,7 +1656,9 @@ btr_search_validate(void)
}
rw_lock_x_unlock(&btr_search_latch);
if (heap) {
mem_heap_free(heap);
}
return(ok);
}
......@@ -67,6 +67,16 @@ rec_get_n_fields_old(
/* out: number of data fields */
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
owned by the previous directory record. */
UNIV_INLINE
......@@ -188,45 +198,28 @@ rec_get_1byte_offs_flag(
rec_t* rec); /* in: physical record */
/**********************************************************
The following function determines the offsets to each field
in the record. The offsets are returned in an array of
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. */
in the record. It can reuse a previously allocated array. */
ulint*
rec_get_offsets(
/*============*/
/* 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(
/*==============*/
rec_get_offsets_func(
/*=================*/
/* 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* 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_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
ibool
rec_offs_validate(
......@@ -234,8 +227,7 @@ rec_offs_validate(
/* out: TRUE if valid */
rec_t* rec, /* in: record or NULL */
dict_index_t* index, /* in: record descriptor or NULL */
const ulint* offsets);/* in: array returned by rec_get_offsets()
or rec_reget_offsets() */
const ulint* offsets);/* in: array returned by rec_get_offsets() */
/****************************************************************
Updates debug data in offsets, in order to avoid bogus
rec_offs_validate() failures. */
......@@ -243,10 +235,9 @@ UNIV_INLINE
void
rec_offs_make_valid(
/*================*/
const rec_t* rec, /* in: record */
const dict_index_t* index,/* in: record descriptor */
ulint* offsets);/* in: array returned by rec_get_offsets()
or rec_reget_offsets() */
rec_t* rec, /* in: record */
dict_index_t* index,/* in: record descriptor */
ulint* offsets);/* in: array returned by rec_get_offsets() */
/****************************************************************
The following function is used to get a pointer to the nth
......@@ -551,7 +542,15 @@ rec_print_old(
/*==========*/
FILE* file, /* in: file where to print */
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. */
......@@ -560,7 +559,7 @@ rec_print(
/*======*/
FILE* file, /* in: file where to print */
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 */
......
......@@ -681,9 +681,11 @@ rec_2_get_field_end_info(
}
#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 */
# define REC_OFFS_HEADER_SIZE 1
/* Length of the rec_get_offsets() header */
# define REC_OFFS_HEADER_SIZE 2
#endif /* UNIV_DEBUG */
/* 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
the fields. */
#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
ibool
rec_offs_validate(
......@@ -705,16 +739,16 @@ rec_offs_validate(
ulint i = rec_offs_n_fields(offsets);
ulint last = ULINT_MAX;
ibool comp = (*rec_offs_base(offsets) & REC_OFFS_COMPACT) != 0;
ut_a(offsets);
if (rec) {
ut_ad((ulint) rec == offsets[1]);
ut_ad((ulint) rec == offsets[2]);
if (!comp) {
ut_a(rec_get_n_fields_old(rec) >= i);
}
}
if (index) {
ulint max_n_fields;
ut_ad((ulint) index == offsets[2]);
ut_ad((ulint) index == offsets[3]);
max_n_fields = ut_max(
dict_index_get_n_fields(index),
dict_index_get_n_unique_in_tree(index) + 1);
......@@ -734,7 +768,9 @@ rec_offs_validate(
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--) {
ulint curr = rec_offs_base(offsets)[1 + i] & REC_OFFS_MASK;
......@@ -750,17 +786,17 @@ UNIV_INLINE
void
rec_offs_make_valid(
/*================*/
const rec_t* rec __attribute__((unused)),
rec_t* rec __attribute__((unused)),
/* in: record */
const dict_index_t* index __attribute__((unused)),
dict_index_t* index __attribute__((unused)),
/* in: record descriptor */
ulint* offsets __attribute__((unused)))
/* in: array returned by rec_get_offsets()
or rec_reget_offsets() */
/* in: array returned by rec_get_offsets() */
{
#ifdef UNIV_DEBUG
offsets[1] = (ulint) rec;
offsets[2] = (ulint) index;
ut_ad(rec_get_n_fields(rec, index) >= rec_offs_n_fields(offsets));
offsets[2] = (ulint) rec;
offsets[3] = (ulint) index;
#endif /* UNIV_DEBUG */
}
......@@ -1146,12 +1182,31 @@ rec_offs_n_fields(
{
ulint n_fields;
ut_ad(offsets);
n_fields = offsets[0];
n_fields = offsets[1];
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));
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
record, that is the sum of field lengths. SQL null fields
......
......@@ -424,7 +424,7 @@ lock_check_trx_id_sanity(
/* out: TRUE if ok */
dulint trx_id, /* in: trx id */
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) */
ibool has_kernel_mutex)/* in: TRUE if the caller owns the
kernel mutex */
......@@ -445,7 +445,7 @@ lock_check_trx_id_sanity(
fputs(" InnoDB: Error: transaction id associated"
" with record\n",
stderr);
rec_print(stderr, rec, offsets);
rec_print_new(stderr, rec, offsets);
fputs("InnoDB: in ", stderr);
dict_index_name_print(stderr, NULL, index);
fprintf(stderr, "\n"
......@@ -4073,10 +4073,9 @@ lock_rec_print(
ulint page_no;
ulint i;
mtr_t mtr;
mem_heap_t* heap;
ulint* offsets = NULL;
heap = mem_heap_create(100);
mem_heap_t* heap = NULL;
ulint offsets_[100] = { 100, };
ulint* offsets = offsets_;
#ifdef UNIV_SYNC_DEBUG
ut_ad(mutex_own(&kernel_mutex));
......@@ -4157,9 +4156,9 @@ lock_rec_print(
if (page) {
rec_t* rec
= page_find_rec_with_heap_no(page, i);
offsets = rec_reget_offsets(rec, lock->index,
offsets, ULINT_UNDEFINED, heap);
rec_print(file, rec, offsets);
offsets = rec_get_offsets(rec, lock->index,
offsets, ULINT_UNDEFINED, &heap);
rec_print_new(file, rec, offsets);
}
putc('\n', file);
......@@ -4167,7 +4166,9 @@ lock_rec_print(
}
mtr_commit(&mtr);
if (heap) {
mem_heap_free(heap);
}
}
/*************************************************************************
......@@ -4566,8 +4567,9 @@ lock_rec_validate_page(
ulint nth_bit = 0;
ulint i;
mtr_t mtr;
mem_heap_t* heap = mem_heap_create(100);
ulint* offsets = NULL;
mem_heap_t* heap = NULL;
ulint offsets_[100] = { 100, };
ulint* offsets = offsets_;
#ifdef UNIV_SYNC_DEBUG
ut_ad(!mutex_own(&kernel_mutex));
......@@ -4607,8 +4609,8 @@ loop:
index = lock->index;
rec = page_find_rec_with_heap_no(page, i);
offsets = rec_reget_offsets(rec, index,
offsets, ULINT_UNDEFINED, heap);
offsets = rec_get_offsets(rec, index, offsets,
ULINT_UNDEFINED, &heap);
fprintf(stderr,
"Validating %lu %lu\n", (ulong) space, (ulong) page_no);
......@@ -4635,7 +4637,9 @@ function_exit:
mtr_commit(&mtr);
if (heap) {
mem_heap_free(heap);
}
return(TRUE);
}
......@@ -4811,12 +4815,16 @@ lock_rec_insert_check_and_lock(
#ifdef UNIV_DEBUG
{
mem_heap_t* heap = mem_heap_create(100);
const ulint* offsets = rec_get_offsets(next_rec, index,
ULINT_UNDEFINED, heap);
mem_heap_t* heap = NULL;
ulint offsets_[100] = { 100, };
const ulint* offsets = rec_get_offsets(
next_rec, index, offsets_,
ULINT_UNDEFINED, &heap);
ut_ad(lock_rec_queue_validate(next_rec, index, offsets));
if (heap) {
mem_heap_free(heap);
}
}
#endif /* UNIV_DEBUG */
return(err);
......@@ -4954,12 +4962,15 @@ lock_sec_rec_modify_check_and_lock(
#ifdef UNIV_DEBUG
{
mem_heap_t* heap = mem_heap_create(100);
const ulint* offsets = rec_get_offsets(rec, index,
ULINT_UNDEFINED, heap);
mem_heap_t* heap = NULL;
ulint offsets_[100] = { 100, };
const ulint* offsets = rec_get_offsets(
rec, index, offsets_, ULINT_UNDEFINED, &heap);
ut_ad(lock_rec_queue_validate(rec, index, offsets));
if (heap) {
mem_heap_free(heap);
}
}
#endif /* UNIV_DEBUG */
if (err == DB_SUCCESS) {
......@@ -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(gap_mode == LOCK_ORDINARY || gap_mode == LOCK_GAP
|| gap_mode == LOCK_REC_NOT_GAP);
ut_ad(index->type & DICT_CLUSTERED);
ut_ad(rec_offs_validate(rec, index, offsets));
if (flags & BTR_NO_LOCKING_FLAG) {
......
......@@ -29,6 +29,7 @@ UNIV_INLINE
ibool
page_cur_try_search_shortcut(
/*=========================*/
/* out: TRUE on success */
page_t* page, /* in: index page */
dict_index_t* index, /* in: record descriptor */
dtuple_t* tuple, /* in: data tuple */
......@@ -56,14 +57,15 @@ page_cur_try_search_shortcut(
#ifdef UNIV_SEARCH_DEBUG
page_cur_t cursor2;
#endif
mem_heap_t* heap;
ulint* offsets;
ibool success = FALSE;
mem_heap_t* heap = NULL;
ulint offsets_[100] = { 100, };
ulint* offsets = offsets_;
ut_ad(dtuple_check_typed(tuple));
rec = page_header_get_ptr(page, PAGE_LAST_INSERT);
heap = mem_heap_create(100);
offsets = rec_get_offsets(rec, index,
dtuple_get_n_fields(tuple), heap);
offsets = rec_get_offsets(rec, index, offsets,
dtuple_get_n_fields(tuple), &heap);
ut_ad(rec);
ut_ad(page_rec_is_user_rec(rec));
......@@ -78,21 +80,17 @@ page_cur_try_search_shortcut(
cmp = page_cmp_dtuple_rec_with_match(tuple, rec, offsets, &low_match,
&low_bytes);
if (cmp == -1) {
mem_heap_free(heap);
return(FALSE);
goto exit_func;
}
next_rec = page_rec_get_next(rec);
offsets = rec_reget_offsets(next_rec, index, offsets,
dtuple_get_n_fields(tuple), heap);
offsets = rec_get_offsets(next_rec, index, offsets,
dtuple_get_n_fields(tuple), &heap);
cmp = page_cmp_dtuple_rec_with_match(tuple, next_rec, offsets,
&up_match, &up_bytes);
if (cmp != -1) {
mem_heap_free(heap);
return(FALSE);
goto exit_func;
}
cursor->rec = rec;
......@@ -127,8 +125,12 @@ page_cur_try_search_shortcut(
#ifdef UNIV_SEARCH_PERF_STAT
page_cur_short_succ++;
#endif
success = TRUE;
exit_func:
if (heap) {
mem_heap_free(heap);
return(TRUE);
}
return(success);
}
#endif
......@@ -226,8 +228,9 @@ page_cur_search_with_match(
ulint dbg_matched_fields;
ulint dbg_matched_bytes;
#endif
mem_heap_t* heap;
ulint* offsets = NULL;
mem_heap_t* heap = NULL;
ulint offsets_[100] = { 100, };
ulint* offsets = offsets_;
ut_ad(page && tuple && iup_matched_fields && iup_matched_bytes
&& ilow_matched_fields && ilow_matched_bytes && cursor);
......@@ -262,8 +265,6 @@ page_cur_search_with_match(
/*#endif */
#endif
heap = mem_heap_create(100);
/* The following flag does not work for non-latin1 char sets because
cmp_full_field does not tell how many bytes matched */
ut_a(mode != PAGE_CUR_LE_OR_EXTENDS);
......@@ -298,8 +299,8 @@ page_cur_search_with_match(
low_matched_fields, low_matched_bytes,
up_matched_fields, up_matched_bytes);
offsets = rec_reget_offsets(mid_rec, index, offsets,
dtuple_get_n_fields_cmp(tuple), heap);
offsets = rec_get_offsets(mid_rec, index, offsets,
dtuple_get_n_fields_cmp(tuple), &heap);
cmp = cmp_dtuple_rec_with_match(tuple, mid_rec, offsets,
&cur_matched_fields,
......@@ -310,8 +311,8 @@ page_cur_search_with_match(
low_matched_bytes = cur_matched_bytes;
} else if (cmp == -1) {
offsets = rec_reget_offsets(mid_rec, index,
offsets, dtuple_get_n_fields_cmp(tuple), heap);
offsets = rec_get_offsets(mid_rec, index, offsets,
dtuple_get_n_fields_cmp(tuple), &heap);
if (mode == PAGE_CUR_LE_OR_EXTENDS
&& page_cur_rec_field_extends(tuple, mid_rec,
......@@ -353,8 +354,8 @@ page_cur_search_with_match(
low_matched_fields, low_matched_bytes,
up_matched_fields, up_matched_bytes);
offsets = rec_reget_offsets(mid_rec, index,
offsets, dtuple_get_n_fields_cmp(tuple), heap);
offsets = rec_get_offsets(mid_rec, index, offsets,
dtuple_get_n_fields_cmp(tuple), &heap);
cmp = cmp_dtuple_rec_with_match(tuple, mid_rec, offsets,
&cur_matched_fields,
......@@ -365,8 +366,8 @@ page_cur_search_with_match(
low_matched_bytes = cur_matched_bytes;
} else if (cmp == -1) {
offsets = rec_reget_offsets(mid_rec, index,
offsets, dtuple_get_n_fields_cmp(tuple), heap);
offsets = rec_get_offsets(mid_rec, index, offsets,
dtuple_get_n_fields_cmp(tuple), &heap);
if (mode == PAGE_CUR_LE_OR_EXTENDS
&& page_cur_rec_field_extends(tuple, mid_rec,
......@@ -398,8 +399,8 @@ page_cur_search_with_match(
dbg_matched_fields = 0;
dbg_matched_bytes = 0;
offsets = rec_reget_offsets(low_rec, index,
offsets, ULINT_UNDEFINED, heap);
offsets = rec_get_offsets(low_rec, index, offsets,
ULINT_UNDEFINED, &heap);
dbg_cmp = page_cmp_dtuple_rec_with_match(tuple, low_rec, offsets,
&dbg_matched_fields,
&dbg_matched_bytes);
......@@ -422,8 +423,8 @@ page_cur_search_with_match(
dbg_matched_fields = 0;
dbg_matched_bytes = 0;
offsets = rec_reget_offsets(up_rec, index,
offsets, ULINT_UNDEFINED, heap);
offsets = rec_get_offsets(up_rec, index, offsets,
ULINT_UNDEFINED, &heap);
dbg_cmp = page_cmp_dtuple_rec_with_match(tuple, up_rec, offsets,
&dbg_matched_fields,
&dbg_matched_bytes);
......@@ -453,7 +454,9 @@ page_cur_search_with_match(
*iup_matched_bytes = up_matched_bytes;
*ilow_matched_fields = low_matched_fields;
*ilow_matched_bytes = low_matched_bytes;
if (heap) {
mem_heap_free(heap);
}
}
/***************************************************************
......@@ -519,23 +522,27 @@ page_cur_insert_rec_write_log(
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* ins_offs;
heap = mem_heap_create(100);
cur_offs = rec_get_offsets(cursor_rec, index,
ULINT_UNDEFINED, heap);
ins_offs = rec_get_offsets(insert_rec, index,
ULINT_UNDEFINED, heap);
cur_offs = rec_get_offsets(cursor_rec, index, cur_offs_,
ULINT_UNDEFINED, &heap);
ins_offs = rec_get_offsets(insert_rec, index, ins_offs_,
ULINT_UNDEFINED, &heap);
extra_size = rec_offs_extra_size(ins_offs);
cur_extra_size = rec_offs_extra_size(cur_offs);
ut_ad(rec_size == rec_offs_size(ins_offs));
cur_rec_size = rec_offs_size(cur_offs);
if (heap) {
mem_heap_free(heap);
}
}
ins_ptr = insert_rec - extra_size;
......@@ -668,8 +675,9 @@ page_cur_parse_insert_rec(
byte* ptr2 = ptr;
ulint info_bits = 0; /* remove warning */
page_cur_t cursor;
mem_heap_t* heap;
ulint* offsets;
mem_heap_t* heap = NULL;
ulint offsets_[100] = { 100, };
ulint* offsets = offsets_;
if (!is_short) {
/* Read the cursor rec offset as a 2-byte ulint */
......@@ -756,8 +764,8 @@ page_cur_parse_insert_rec(
cursor_rec = page + offset;
}
heap = mem_heap_create(100);
offsets = rec_get_offsets(cursor_rec, index, ULINT_UNDEFINED, heap);
offsets = rec_get_offsets(cursor_rec, index, offsets,
ULINT_UNDEFINED, &heap);
if (extra_info_yes == 0) {
info_bits = rec_get_info_bits(cursor_rec, index->table->comp);
......@@ -816,6 +824,10 @@ page_cur_parse_insert_rec(
mem_free(buf);
}
if (heap) {
mem_heap_free(heap);
}
return(ptr + end_seg_len);
}
......@@ -850,8 +862,9 @@ page_cur_insert_rec_low(
inserted record */
rec_t* owner_rec;
ulint n_owned;
mem_heap_t* heap;
ulint* offsets;
mem_heap_t* heap = NULL;
ulint offsets_[100] = { 100, };
ulint* offsets = offsets_;
ibool comp = index->table->comp;
ut_ad(cursor && mtr);
......@@ -865,14 +878,12 @@ page_cur_insert_rec_low(
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 */
if (tuple != NULL) {
offsets = NULL;
rec_size = rec_get_converted_size(index, tuple);
} 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);
}
......@@ -880,7 +891,9 @@ page_cur_insert_rec_low(
insert_buf = page_mem_alloc(page, rec_size, index, &heap_no);
if (insert_buf == NULL) {
if (heap) {
mem_heap_free(heap);
}
return(NULL);
}
......@@ -888,13 +901,15 @@ page_cur_insert_rec_low(
if (tuple != NULL) {
insert_rec = rec_convert_dtuple_to_rec(insert_buf,
index, tuple);
offsets = rec_get_offsets(insert_rec, index, offsets,
ULINT_UNDEFINED, &heap);
} else {
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);
offsets = rec_reget_offsets(insert_rec, index,
offsets, ULINT_UNDEFINED, heap);
ut_ad(rec_size == rec_offs_size(offsets));
/* 4. Insert the record in the linked list of records */
......@@ -966,7 +981,9 @@ page_cur_insert_rec_low(
page_cur_insert_rec_write_log(insert_rec, rec_size, current_rec,
index, mtr);
if (heap) {
mem_heap_free(heap);
}
return(insert_rec);
}
......@@ -1069,8 +1086,9 @@ page_copy_rec_list_end_to_created_page(
byte* log_ptr;
ulint log_data_len;
ibool comp = page_is_comp(page);
mem_heap_t* heap;
ulint* offsets = NULL;
mem_heap_t* heap = NULL;
ulint offsets_[100] = { 100, };
ulint* offsets = offsets_;
ut_ad(page_dir_get_n_heap(new_page) == 2);
ut_ad(page != new_page);
......@@ -1117,8 +1135,8 @@ page_copy_rec_list_end_to_created_page(
/* should be do ... until, comment by Jani */
while (rec != page_get_supremum_rec(page)) {
offsets = rec_reget_offsets(rec, index,
offsets, ULINT_UNDEFINED, heap);
offsets = rec_get_offsets(rec, index, offsets,
ULINT_UNDEFINED, &heap);
insert_rec = rec_copy(heap_top, rec, offsets);
rec_set_next_offs(prev_rec, comp, insert_rec - new_page);
......@@ -1170,7 +1188,9 @@ page_copy_rec_list_end_to_created_page(
slot_index--;
}
if (heap) {
mem_heap_free(heap);
}
log_data_len = dyn_array_get_data_size(&(mtr->log)) - log_data_len;
......
......@@ -227,10 +227,12 @@ page_mem_alloc(
rec = page_header_get_ptr(page, PAGE_FREE);
if (rec) {
mem_heap_t* heap
= mem_heap_create(100);
const ulint* offsets
= rec_get_offsets(rec, index, ULINT_UNDEFINED, heap);
mem_heap_t* heap = NULL;
ulint offsets_[100] = { 100, };
ulint* offsets = offsets_;
offsets = rec_get_offsets(rec, index, offsets,
ULINT_UNDEFINED, &heap);
if (rec_offs_size(offsets) >= need) {
page_header_set_ptr(page, PAGE_FREE,
......@@ -245,12 +247,16 @@ page_mem_alloc(
*heap_no = rec_get_heap_no(rec, page_is_comp(page));
block = rec_get_start(rec, offsets);
if (heap) {
mem_heap_free(heap);
}
return(block);
}
if (heap) {
mem_heap_free(heap);
}
}
/* Could not find space from the free list, try top of heap */
......@@ -374,7 +380,8 @@ page_create(
rec_set_n_owned(infimum_rec, comp, 1);
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);
......@@ -396,8 +403,8 @@ page_create(
rec_set_n_owned(supremum_rec, comp, 1);
rec_set_heap_no(supremum_rec, comp, 1);
offsets = rec_reget_offsets(supremum_rec, index,
offsets, ULINT_UNDEFINED, heap);
offsets = rec_get_offsets(supremum_rec, index, offsets,
ULINT_UNDEFINED, &heap);
heap_top = rec_get_end(supremum_rec, offsets);
ut_ad(heap_top ==
......@@ -711,8 +718,9 @@ page_delete_rec_list_end(
last_rec = page_rec_get_prev(sup);
if ((size == ULINT_UNDEFINED) || (n_recs == ULINT_UNDEFINED)) {
mem_heap_t* heap = mem_heap_create(100);
ulint* offsets = NULL;
mem_heap_t* heap = NULL;
ulint offsets_[100] = { 100, };
ulint* offsets = offsets_;
/* Calculate the sum of sizes and the number of records */
size = 0;
n_recs = 0;
......@@ -720,8 +728,8 @@ page_delete_rec_list_end(
while (rec2 != sup) {
ulint s;
offsets = rec_reget_offsets(rec2, index,
offsets, ULINT_UNDEFINED, heap);
offsets = rec_get_offsets(rec2, index, offsets,
ULINT_UNDEFINED, &heap);
s = rec_offs_size(offsets);
ut_ad(rec2 - page + s - rec_offs_extra_size(offsets)
< UNIV_PAGE_SIZE);
......@@ -732,8 +740,10 @@ page_delete_rec_list_end(
rec2 = page_rec_get_next(rec2);
}
if (heap) {
mem_heap_free(heap);
}
}
ut_ad(size < UNIV_PAGE_SIZE);
......@@ -1213,7 +1223,7 @@ page_rec_print(
ibool comp = page_is_comp(buf_frame_align(rec));
ut_a(comp == rec_offs_comp(offsets));
rec_print(stderr, rec, offsets);
rec_print_new(stderr, rec, offsets);
fprintf(stderr,
" n_owned: %lu; heap_no: %lu; next rec: %lu\n",
(ulong) rec_get_n_owned(rec, comp),
......@@ -1276,11 +1286,11 @@ page_print_list(
page_cur_t cur;
ulint count;
ulint n_recs;
mem_heap_t* heap;
ulint* offsets = NULL;
mem_heap_t* heap = NULL;
ulint offsets_[100] = { 100, };
ulint* offsets = offsets_;
ut_a(page_is_comp(page) == index->table->comp);
heap = mem_heap_create(100);
fprintf(stderr,
"--------------------------------\n"
......@@ -1292,8 +1302,8 @@ page_print_list(
page_cur_set_before_first(page, &cur);
count = 0;
for (;;) {
offsets = rec_reget_offsets(cur.rec, index,
offsets, ULINT_UNDEFINED, heap);
offsets = rec_get_offsets(cur.rec, index, offsets,
ULINT_UNDEFINED, &heap);
page_rec_print(cur.rec, offsets);
if (count == pr_n) {
......@@ -1314,8 +1324,8 @@ page_print_list(
page_cur_move_to_next(&cur);
if (count + pr_n >= n_recs) {
offsets = rec_reget_offsets(cur.rec, index,
offsets, ULINT_UNDEFINED, heap);
offsets = rec_get_offsets(cur.rec, index, offsets,
ULINT_UNDEFINED, &heap);
page_rec_print(cur.rec, offsets);
}
count++;
......@@ -1326,7 +1336,9 @@ page_print_list(
"--------------------------------\n",
(ulong) (count + 1));
if (heap) {
mem_heap_free(heap);
}
}
/*******************************************************************
......@@ -1680,7 +1692,7 @@ page_validate(
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
records in the page record heap do not overlap */
......@@ -1720,8 +1732,8 @@ page_validate(
for (;;) {
rec = cur.rec;
offsets = rec_reget_offsets(rec, index,
offsets, ULINT_UNDEFINED, heap);
offsets = rec_get_offsets(rec, index, offsets,
ULINT_UNDEFINED, &heap);
if (comp && page_rec_is_user_rec(rec)
&& rec_get_node_ptr_flag(rec)
......@@ -1744,9 +1756,9 @@ page_validate(
(ulong) buf_frame_get_page_no(page));
dict_index_name_print(stderr, NULL, index);
fputs("\nInnoDB: previous record ", stderr);
rec_print(stderr, old_rec, old_offsets);
rec_print_new(stderr, old_rec, old_offsets);
fputs("\nInnoDB: record ", stderr);
rec_print(stderr, rec, offsets);
rec_print_new(stderr, rec, offsets);
putc('\n', stderr);
goto func_exit;
......@@ -1852,8 +1864,8 @@ page_validate(
rec = page_header_get_ptr(page, PAGE_FREE);
while (rec != NULL) {
offsets = rec_reget_offsets(rec, index,
offsets, ULINT_UNDEFINED, heap);
offsets = rec_get_offsets(rec, index, offsets,
ULINT_UNDEFINED, &heap);
if (!page_rec_validate(rec, offsets)) {
goto func_exit;
......
......@@ -284,28 +284,25 @@ rec_init_offsets(
/**********************************************************
The following function determines the offsets to each field
in the record. The offsets are returned in an array of
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. */
in the record. It can reuse a previously returned array. */
ulint*
rec_get_offsets(
/*============*/
/* out: the offsets */
rec_get_offsets_func(
/*=================*/
/* out: the new offsets */
rec_t* rec, /* in: physical record */
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_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 size;
ut_ad(rec);
ut_ad(index);
......@@ -336,71 +333,18 @@ rec_get_offsets(
n = n_fields;
}
offsets = mem_heap_alloc(heap,
(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);
}
size = (n + (1 + REC_OFFS_HEADER_SIZE)) * sizeof(ulint);
if (n_fields < n) {
n = n_fields;
if (!offsets || rec_offs_get_n_alloc(offsets) < size) {
if (!*heap) {
*heap = mem_heap_create_func(size,
NULL, MEM_HEAP_DYNAMIC, file, line);
}
if (!offsets || rec_offs_n_fields(offsets) < n) {
offsets = mem_heap_alloc(heap,
(n + (1 + REC_OFFS_HEADER_SIZE)) * sizeof(ulint));
offsets = mem_heap_alloc(*heap, size);
rec_offs_set_n_alloc(offsets, size);
}
offsets[0] = n;
rec_offs_set_n_fields(offsets, n);
rec_init_offsets(rec, index, offsets);
return(offsets);
}
......@@ -722,14 +666,16 @@ rec_get_size(
rec_t* rec, /* in: physical record */
dict_index_t* index) /* in: record descriptor */
{
mem_heap_t* heap
= mem_heap_create(100);
ulint* offsets
= rec_get_offsets(rec, index, ULINT_UNDEFINED, heap);
ulint size
= rec_offs_size(offsets);
mem_heap_t* heap = NULL;
ulint offsets_[100 + REC_OFFS_HEADER_SIZE]
= { 100, };
ulint* offsets = rec_get_offsets(rec, index, offsets_,
ULINT_UNDEFINED, &heap);
ulint size = rec_offs_size(offsets);
if (heap) {
mem_heap_free(heap);
}
return(size);
}
......@@ -1032,11 +978,16 @@ rec_convert_dtuple_to_rec(
#ifdef UNIV_DEBUG
{
mem_heap_t* heap = mem_heap_create(100);
ut_ad(rec_validate(rec,
rec_get_offsets(rec, index, ULINT_UNDEFINED, heap)));
mem_heap_t* heap = NULL;
ulint offsets_[100 + REC_OFFS_HEADER_SIZE]
= { 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);
}
}
#endif /* UNIV_DEBUG */
return(rec);
}
......@@ -1059,9 +1010,11 @@ rec_copy_prefix_to_dtuple(
ulint len;
byte* buf = NULL;
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(dtuple_check_typed(tuple));
......@@ -1406,8 +1359,8 @@ rec_print_old(
Prints a physical record. */
void
rec_print(
/*======*/
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() */
......@@ -1416,6 +1369,8 @@ rec_print(
ulint len;
ulint i;
ut_ad(rec_offs_validate(rec, NULL, offsets));
if (!rec_offs_comp(offsets)) {
rec_print_old(file, rec);
return;
......@@ -1453,3 +1408,30 @@ rec_print(
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(
fputs(", in index ", ef);
ut_print_name(ef, trx, foreign->foreign_index->name);
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);
rec_print(ef, rec, offsets);
mem_heap_free(heap);
rec_print(ef, rec, foreign->foreign_index);
} else {
fputs(", the record is not available\n", ef);
}
......@@ -654,16 +646,7 @@ row_ins_foreign_report_add_err(
}
if (rec) {
mem_heap_t* heap;
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);
rec_print(ef, rec, foreign->foreign_index);
}
putc('\n', ef);
......@@ -734,7 +717,8 @@ row_ins_foreign_check_on_constraint(
ulint i;
trx_t* trx;
mem_heap_t* tmp_heap = NULL;
ulint* offsets;
ulint offsets_[100] = { 100, };
ulint* offsets = offsets_;
ut_a(thr && foreign && pcur && mtr);
......@@ -880,14 +864,10 @@ row_ins_foreign_check_on_constraint(
fputs("\n"
"InnoDB: record ", stderr);
offsets = rec_get_offsets(rec, index,
ULINT_UNDEFINED, tmp_heap);
rec_print(stderr, rec, offsets);
rec_print(stderr, rec, index);
fputs("\n"
"InnoDB: clustered record ", stderr);
offsets = rec_reget_offsets(clust_rec, clust_index,
offsets, ULINT_UNDEFINED, tmp_heap);
rec_print(stderr, clust_rec, offsets);
rec_print(stderr, clust_rec, clust_index);
fputs("\n"
"InnoDB: Submit a detailed bug report to http://bugs.mysql.com\n", stderr);
......@@ -906,11 +886,8 @@ row_ins_foreign_check_on_constraint(
we already have a normal shared lock on the appropriate
gap if the search criterion was not unique */
if (!tmp_heap) {
tmp_heap = mem_heap_create(256);
}
offsets = rec_get_offsets(clust_rec, clust_index,
ULINT_UNDEFINED, tmp_heap);
offsets = rec_get_offsets(clust_rec, clust_index, offsets,
ULINT_UNDEFINED, &tmp_heap);
err = lock_clust_rec_read_check_and_lock(0, clust_rec,
clust_index, offsets, LOCK_X, LOCK_REC_NOT_GAP, thr);
}
......@@ -1153,10 +1130,9 @@ row_ins_check_foreign_constraint(
ulint i;
mtr_t mtr;
trx_t* trx = thr_get_trx(thr);
mem_heap_t* heap;
ulint* offsets = NULL;
heap = mem_heap_create(100);
mem_heap_t* heap = NULL;
ulint offsets_[100] = { 100, };
ulint* offsets = offsets_;
run_again:
#ifdef UNIV_SYNC_DEBUG
......@@ -1168,8 +1144,7 @@ run_again:
if (trx->check_foreigns == FALSE) {
/* The user has suppressed foreign key checks currently for
this session */
mem_heap_free(heap);
return(DB_SUCCESS);
goto exit_func;
}
/* If any of the foreign key fields in entry is SQL NULL, we
......@@ -1180,8 +1155,7 @@ run_again:
if (UNIV_SQL_NULL == dfield_get_len(
dtuple_get_nth_field(entry, i))) {
mem_heap_free(heap);
return(DB_SUCCESS);
goto exit_func;
}
}
......@@ -1205,8 +1179,7 @@ run_again:
another, and the user has problems predicting in
which order they are performed. */
mem_heap_free(heap);
return(DB_SUCCESS);
goto exit_func;
}
}
......@@ -1219,8 +1192,6 @@ run_again:
}
if (check_table == NULL) {
mem_heap_free(heap);
if (check_ref) {
FILE* ef = dict_foreign_err_file;
mutex_enter(&dict_foreign_err_mutex);
......@@ -1242,10 +1213,10 @@ run_again:
fputs(" does not currently exist!\n", ef);
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);
......@@ -1291,8 +1262,8 @@ run_again:
goto next_rec;
}
offsets = rec_reget_offsets(rec, check_index,
offsets, ULINT_UNDEFINED, heap);
offsets = rec_get_offsets(rec, check_index,
offsets, ULINT_UNDEFINED, &heap);
if (rec == page_get_supremum_rec(buf_frame_align(rec))) {
......@@ -1424,7 +1395,10 @@ do_possible_lock_wait:
err = trx->error_state;
}
exit_func:
if (heap) {
mem_heap_free(heap);
}
return(err);
}
......@@ -1565,8 +1539,9 @@ row_ins_scan_sec_index_for_duplicate(
ibool moved;
mtr_t mtr;
trx_t* trx;
mem_heap_t* heap;
ulint* offsets = NULL;
mem_heap_t* heap = NULL;
ulint offsets_[100] = { 100, };
ulint* offsets = offsets_;
n_unique = dict_index_get_n_unique(index);
......@@ -1582,7 +1557,6 @@ row_ins_scan_sec_index_for_duplicate(
}
}
heap = mem_heap_create(100);
mtr_start(&mtr);
/* Store old value on n_fields_cmp */
......@@ -1608,8 +1582,8 @@ row_ins_scan_sec_index_for_duplicate(
trx = thr_get_trx(thr);
ut_ad(trx);
offsets = rec_reget_offsets(rec, index,
offsets, ULINT_UNDEFINED, heap);
offsets = rec_get_offsets(rec, index, offsets,
ULINT_UNDEFINED, &heap);
if (innobase_query_is_replace()) {
......@@ -1662,7 +1636,9 @@ next_rec:
}
}
if (heap) {
mem_heap_free(heap);
}
mtr_commit(&mtr);
/* Restore old value */
......@@ -1693,6 +1669,10 @@ row_ins_duplicate_error_in_clust(
page_t* page;
ulint n_unique;
trx_t* trx = thr_get_trx(thr);
mem_heap_t*heap = NULL;
ulint offsets_[100] = { 100, };
ulint* offsets = offsets_;
UT_NOT_USED(mtr);
......@@ -1720,12 +1700,8 @@ row_ins_duplicate_error_in_clust(
page = buf_frame_align(rec);
if (rec != page_get_infimum_rec(page)) {
mem_heap_t* heap;
ulint* offsets;
heap = mem_heap_create(100);
offsets = rec_get_offsets(rec, cursor->index,
ULINT_UNDEFINED, heap);
offsets = rec_get_offsets(rec, cursor->index, offsets,
ULINT_UNDEFINED, &heap);
/* We set a lock on the possible duplicate: this
is needed in logical logging of MySQL to make
......@@ -1750,17 +1726,15 @@ row_ins_duplicate_error_in_clust(
}
if (err != DB_SUCCESS) {
mem_heap_free(heap);
return(err);
goto func_exit;
}
if (row_ins_dupl_error_with_rec(rec, entry,
cursor->index, offsets)) {
trx->error_info = cursor->index;
mem_heap_free(heap);
return(DB_DUPLICATE_KEY);
err = DB_DUPLICATE_KEY;
goto func_exit;
}
mem_heap_free(heap);
}
}
......@@ -1770,12 +1744,8 @@ row_ins_duplicate_error_in_clust(
page = buf_frame_align(rec);
if (rec != page_get_supremum_rec(page)) {
mem_heap_t* heap;
ulint* offsets;
heap = mem_heap_create(100);
offsets = rec_get_offsets(rec, cursor->index,
ULINT_UNDEFINED, heap);
offsets = rec_get_offsets(rec, cursor->index, offsets,
ULINT_UNDEFINED, &heap);
/* The manual defines the REPLACE semantics that it
is either an INSERT or DELETE(s) for duplicate key
......@@ -1795,15 +1765,14 @@ row_ins_duplicate_error_in_clust(
}
if (err != DB_SUCCESS) {
mem_heap_free(heap);
return(err);
goto func_exit;
}
if (row_ins_dupl_error_with_rec(rec, entry,
cursor->index, offsets)) {
trx->error_info = cursor->index;
mem_heap_free(heap);
return(DB_DUPLICATE_KEY);
err = DB_DUPLICATE_KEY;
goto func_exit;
}
mem_heap_free(heap);
}
......@@ -1812,7 +1781,9 @@ row_ins_duplicate_error_in_clust(
/* This should never happen */
}
return(DB_SUCCESS);
err = DB_SUCCESS;
func_exit:
return(err);
}
/*******************************************************************
......@@ -1894,8 +1865,9 @@ row_ins_index_entry_low(
ulint n_unique;
big_rec_t* big_rec = NULL;
mtr_t mtr;
mem_heap_t* heap = mem_heap_create(100);
ulint* offsets = NULL;
mem_heap_t* heap = NULL;
ulint offsets_[100] = { 100, };
ulint* offsets = offsets_;
log_free_check();
......@@ -2023,8 +1995,8 @@ function_exit:
btr_cur_search_to_nth_level(index, 0, entry, PAGE_CUR_LE,
BTR_MODIFY_TREE, &cursor, 0, &mtr);
rec = btr_cur_get_rec(&cursor);
offsets = rec_reget_offsets(rec, index,
offsets, ULINT_UNDEFINED, heap);
offsets = rec_get_offsets(rec, index, offsets,
ULINT_UNDEFINED, &heap);
err = btr_store_big_rec_extern_fields(index, rec,
offsets, big_rec, &mtr);
......@@ -2038,7 +2010,9 @@ function_exit:
mtr_commit(&mtr);
}
if (heap) {
mem_heap_free(heap);
}
return(err);
}
......
......@@ -3215,7 +3215,6 @@ row_scan_and_check_index(
ulint* n_rows) /* out: number of entries seen in the
current consistent read */
{
mem_heap_t* heap;
dtuple_t* prev_entry = NULL;
ulint matched_fields;
ulint matched_bytes;
......@@ -3226,7 +3225,9 @@ row_scan_and_check_index(
int cmp;
ibool contains_null;
ulint i;
ulint* offsets = NULL;
mem_heap_t* heap = NULL;
ulint offsets_[100] = { 100, };
ulint* offsets = offsets_;
*n_rows = 0;
......@@ -3268,8 +3269,8 @@ loop:
matched_fields = 0;
matched_bytes = 0;
offsets = rec_reget_offsets(rec, index,
offsets, ULINT_UNDEFINED, heap);
offsets = rec_get_offsets(rec, index, offsets,
ULINT_UNDEFINED, &heap);
cmp = cmp_dtuple_rec_with_match(prev_entry, rec, offsets,
&matched_fields,
&matched_bytes);
......@@ -3299,7 +3300,7 @@ loop:
dtuple_print(stderr, prev_entry);
fputs("\n"
"InnoDB: record ", stderr);
rec_print(stderr, rec, offsets);
rec_print_new(stderr, rec, offsets);
putc('\n', stderr);
is_ok = FALSE;
} else if ((index->type & DICT_UNIQUE)
......@@ -3313,7 +3314,7 @@ loop:
}
mem_heap_empty(heap);
offsets = NULL;
offsets = offsets_;
prev_entry = row_rec_to_index_entry(ROW_COPY_DATA, index, rec, heap);
......
......@@ -100,7 +100,8 @@ row_purge_remove_clust_if_poss_low(
ulint err;
mtr_t mtr;
rec_t* rec;
mem_heap_t* heap;
mem_heap_t* heap = NULL;
ulint offsets_[100] = { 100, };
index = dict_table_get_first_index(node->table);
......@@ -120,19 +121,22 @@ row_purge_remove_clust_if_poss_low(
}
rec = btr_pcur_get_rec(pcur);
heap = mem_heap_create(100);
if (0 != ut_dulint_cmp(node->roll_ptr,
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);
}
/* Someone else has modified the record later: do not remove */
btr_pcur_commit_specify_mtr(pcur, &mtr);
return(TRUE);
}
if (heap) {
mem_heap_free(heap);
}
if (mode == BTR_MODIFY_LEAF) {
success = btr_cur_optimistic_delete(btr_cur, &mtr);
......
......@@ -202,17 +202,16 @@ row_build(
ulint row_len;
byte* buf;
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->type & DICT_CLUSTERED);
if (!offsets) {
tmp_heap = mem_heap_create(100);
offsets = rec_get_offsets(rec, index,
ULINT_UNDEFINED, tmp_heap);
offsets = rec_get_offsets(rec, index, offsets_,
ULINT_UNDEFINED, &tmp_heap);
} else {
tmp_heap = NULL;
ut_ad(rec_offs_validate(rec, index, offsets));
}
......@@ -296,13 +295,14 @@ row_rec_to_index_entry(
ulint len;
ulint rec_len;
byte* buf;
mem_heap_t* tmp_heap;
ulint* offsets;
mem_heap_t* tmp_heap = NULL;
ulint offsets_[100] = { 100, };
ulint* offsets = offsets_;
ut_ad(rec && heap && index);
tmp_heap = mem_heap_create(100);
offsets = rec_get_offsets(rec, index, ULINT_UNDEFINED, tmp_heap);
offsets = rec_get_offsets(rec, index, offsets,
ULINT_UNDEFINED, &tmp_heap);
if (type == ROW_COPY_DATA) {
/* Take a copy of rec to heap */
......@@ -334,7 +334,9 @@ row_rec_to_index_entry(
}
ut_ad(dtuple_check_typed(entry));
if (tmp_heap) {
mem_heap_free(tmp_heap);
}
return(entry);
}
......@@ -374,13 +376,14 @@ row_build_row_ref(
byte* buf;
ulint clust_col_prefix_len;
ulint i;
mem_heap_t* tmp_heap;
ulint* offsets;
mem_heap_t* tmp_heap = NULL;
ulint offsets_[100] = { 100, };
ulint* offsets = offsets_;
ut_ad(index && rec && heap);
tmp_heap = mem_heap_create(100);
offsets = rec_get_offsets(rec, index, ULINT_UNDEFINED, tmp_heap);
offsets = rec_get_offsets(rec, index, offsets,
ULINT_UNDEFINED, &tmp_heap);
if (type == ROW_COPY_DATA) {
/* Take a copy of rec to heap */
......@@ -433,7 +436,9 @@ row_build_row_ref(
}
ut_ad(dtuple_check_typed(ref));
if (tmp_heap) {
mem_heap_free(tmp_heap);
}
return(ref);
}
......@@ -464,8 +469,9 @@ row_build_row_ref_in_tuple(
ulint pos;
ulint clust_col_prefix_len;
ulint i;
mem_heap_t* heap;
ulint* offsets;
mem_heap_t* heap = NULL;
ulint offsets_[100] = { 100, };
ulint* offsets = offsets_;
ut_a(ref && index && rec);
......@@ -486,8 +492,7 @@ row_build_row_ref_in_tuple(
goto notfound;
}
heap = mem_heap_create(100);
offsets = rec_get_offsets(rec, index, ULINT_UNDEFINED, heap);
offsets = rec_get_offsets(rec, index, offsets, ULINT_UNDEFINED, &heap);
ref_len = dict_index_get_n_unique(clust_index);
......@@ -526,7 +531,9 @@ row_build_row_ref_in_tuple(
}
ut_ad(dtuple_check_typed(ref));
if (heap) {
mem_heap_free(heap);
}
}
/***********************************************************************
......
This diff is collapsed.
......@@ -430,7 +430,6 @@ row_undo_mod_del_unmark_sec_and_undo_update(
found = row_search_index_entry(index, entry, mode, &pcur, &mtr);
if (!found) {
heap = mem_heap_create(100);
fputs("InnoDB: error in sec index entry del undo in\n"
"InnoDB: ", stderr);
dict_index_name_print(stderr, trx, index);
......@@ -439,14 +438,11 @@ row_undo_mod_del_unmark_sec_and_undo_update(
dtuple_print(stderr, entry);
fputs("\n"
"InnoDB: record ", stderr);
rec_print(stderr, btr_pcur_get_rec(&pcur),
rec_get_offsets(btr_pcur_get_rec(&pcur),
index, ULINT_UNDEFINED, heap));
rec_print(stderr, btr_pcur_get_rec(&pcur), index);
putc('\n', stderr);
trx_print(stderr, trx);
fputs("\n"
"InnoDB: Submit a detailed bug report to http://bugs.mysql.com\n", stderr);
mem_heap_free(heap);
} else {
btr_cur_t* btr_cur = btr_pcur_get_btr_cur(&pcur);
......
......@@ -151,8 +151,9 @@ row_undo_search_clust_to_pcur(
mtr_t mtr;
ibool ret;
rec_t* rec;
mem_heap_t* heap;
const ulint* offsets;
mem_heap_t* heap = NULL;
ulint offsets_[100] = { 100, };
ulint* offsets = offsets_;
mtr_start(&mtr);
......@@ -163,8 +164,8 @@ row_undo_search_clust_to_pcur(
rec = btr_pcur_get_rec(&(node->pcur));
heap = mem_heap_create(100);
offsets = rec_get_offsets(rec, clust_index, ULINT_UNDEFINED, heap);
offsets = rec_get_offsets(rec, clust_index, offsets,
ULINT_UNDEFINED, &heap);
if (!found || 0 != ut_dulint_cmp(node->roll_ptr,
row_get_rec_roll_ptr(rec, clust_index, offsets))) {
......@@ -188,6 +189,9 @@ row_undo_search_clust_to_pcur(
btr_pcur_commit_specify_mtr(&(node->pcur), &mtr);
if (heap) {
mem_heap_free(heap);
}
return(ret);
}
......
......@@ -700,6 +700,7 @@ row_upd_build_sec_rec_difference_binary(
upd_t* update;
ulint n_diff;
ulint i;
ulint offsets_[10] = { 10, };
const ulint* offsets;
/* This function is used only for a secondary index */
......@@ -708,7 +709,8 @@ row_upd_build_sec_rec_difference_binary(
update = upd_create(dtuple_get_n_fields(entry), heap);
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++) {
......@@ -775,6 +777,7 @@ row_upd_build_difference_binary(
ulint trx_id_pos;
ibool extern_bit;
ulint i;
ulint offsets_[100] = { 100, };
const ulint* offsets;
/* This function is used only for a clustered index */
......@@ -787,7 +790,8 @@ row_upd_build_difference_binary(
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);
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++) {
......@@ -1182,7 +1186,8 @@ row_upd_store_row(
dict_index_t* clust_index;
upd_t* update;
rec_t* rec;
mem_heap_t* heap;
mem_heap_t* heap = NULL;
ulint offsets_[100] = { 100, };
const ulint* offsets;
ut_ad(node->pcur->latch_mode != BTR_NO_LATCHES);
......@@ -1196,8 +1201,8 @@ row_upd_store_row(
rec = btr_pcur_get_rec(node->pcur);
heap = mem_heap_create(100);
offsets = rec_get_offsets(rec, clust_index, ULINT_UNDEFINED, heap);
offsets = rec_get_offsets(rec, clust_index, offsets_,
ULINT_UNDEFINED, &heap);
node->row = row_build(ROW_COPY_DATA, clust_index, rec, offsets,
node->heap);
node->ext_vec = mem_heap_alloc(node->heap, sizeof(ulint)
......@@ -1210,7 +1215,9 @@ row_upd_store_row(
node->n_ext_vec = btr_push_update_extern_fields(node->ext_vec,
offsets, update);
if (heap) {
mem_heap_free(heap);
}
}
/***************************************************************
......@@ -1263,8 +1270,7 @@ row_upd_sec_index_entry(
dtuple_print(stderr, entry);
fputs("\n"
"InnoDB: record ", stderr);
rec_print(stderr, rec,
rec_get_offsets(rec, index, ULINT_UNDEFINED, heap));
rec_print(stderr, rec, index);
putc('\n', stderr);
trx_print(stderr, trx);
......@@ -1364,7 +1370,7 @@ row_upd_clust_rec_by_insert(
a foreign key constraint */
mtr_t* mtr) /* in: mtr; gets committed here */
{
mem_heap_t* heap;
mem_heap_t* heap = NULL;
btr_pcur_t* pcur;
btr_cur_t* btr_cur;
trx_t* trx;
......@@ -1379,15 +1385,14 @@ row_upd_clust_rec_by_insert(
table = node->table;
pcur = node->pcur;
btr_cur = btr_pcur_get_btr_cur(pcur);
heap = mem_heap_create(500);
if (node->state != UPD_NODE_INSERT_CLUSTERED) {
ulint offsets_[100] = { 100, };
err = btr_cur_del_mark_set_clust_rec(BTR_NO_LOCKING_FLAG,
btr_cur, TRUE, thr, mtr);
if (err != DB_SUCCESS) {
mtr_commit(mtr);
mem_heap_free(heap);
return(err);
}
......@@ -1398,8 +1403,8 @@ row_upd_clust_rec_by_insert(
btr_cur_mark_extern_inherited_fields(btr_cur_get_rec(btr_cur),
rec_get_offsets(btr_cur_get_rec(btr_cur),
dict_table_get_first_index(table),
ULINT_UNDEFINED, heap), node->update, mtr);
dict_table_get_first_index(table), offsets_,
ULINT_UNDEFINED, &heap), node->update, mtr);
if (check_ref) {
/* NOTE that the following call loses
the position of pcur ! */
......@@ -1408,7 +1413,9 @@ row_upd_clust_rec_by_insert(
index, thr, mtr);
if (err != DB_SUCCESS) {
mtr_commit(mtr);
if (heap) {
mem_heap_free(heap);
}
return(err);
}
}
......@@ -1417,6 +1424,9 @@ row_upd_clust_rec_by_insert(
mtr_commit(mtr);
if (!heap) {
heap = mem_heap_create(500);
}
node->state = UPD_NODE_INSERT_CLUSTERED;
entry = row_build_index_entry(node->row, index, heap);
......@@ -1516,17 +1526,20 @@ row_upd_clust_rec(
mtr_commit(mtr);
if (err == DB_SUCCESS && big_rec) {
mem_heap_t* heap;
mem_heap_t* heap = NULL;
ulint offsets_[100] = { 100, };
rec_t* rec;
mtr_start(mtr);
heap = mem_heap_create(100);
rec = btr_cur_get_rec(btr_cur);
ut_a(btr_pcur_restore_position(BTR_MODIFY_TREE, pcur, mtr));
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);
if (heap) {
mem_heap_free(heap);
}
mtr_commit(mtr);
}
......@@ -1611,7 +1624,8 @@ row_upd_clust_step(
mtr_t* mtr;
mtr_t mtr_buf;
rec_t* rec;
mem_heap_t* heap;
mem_heap_t* heap = NULL;
ulint offsets_[100] = { 100, };
const ulint* offsets;
index = dict_table_get_first_index(node->table);
......@@ -1670,33 +1684,31 @@ row_upd_clust_step(
}
rec = btr_pcur_get_rec(pcur);
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 (!node->has_clust_rec_x_lock) {
err = lock_clust_rec_modify_check_and_lock(0,
rec, index, offsets, thr);
if (err != DB_SUCCESS) {
mtr_commit(mtr);
mem_heap_free(heap);
return(err);
goto exit_func;
}
}
/* NOTE: the following function calls will also commit mtr */
if (node->is_delete) {
mem_heap_free(heap);
err = row_upd_del_mark_clust_rec(node, index, thr, check_ref,
mtr);
if (err != DB_SUCCESS) {
return(err);
}
if (err == DB_SUCCESS) {
node->state = UPD_NODE_UPDATE_ALL_SEC;
node->index = dict_table_get_next_index(index);
}
exit_func:
if (heap) {
mem_heap_free(heap);
}
return(err);
}
......@@ -1711,12 +1723,13 @@ row_upd_clust_step(
row_upd_eval_new_vals(node->update);
}
if (heap) {
mem_heap_free(heap);
}
if (node->cmpl_info & UPD_NODE_NO_ORD_CHANGE) {
err = row_upd_clust_rec(node, index, thr, mtr);
return(err);
}
......@@ -1968,7 +1981,8 @@ row_upd_in_place_in_select(
btr_pcur_t* pcur;
btr_cur_t* btr_cur;
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->latch_mode == BTR_MODIFY_LEAF);
......@@ -1984,11 +1998,13 @@ row_upd_in_place_in_select(
/* Copy the necessary columns from clust_rec and calculate the new
values to set */
heap = mem_heap_create(100);
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));
if (heap) {
mem_heap_free(heap);
}
row_upd_eval_new_vals(node->update);
ut_ad(!rec_get_deleted_flag(btr_pcur_get_rec(pcur),
......
......@@ -100,32 +100,25 @@ row_vers_impl_x_locked_off_kernel(
}
heap = mem_heap_create(1024);
clust_offsets = rec_get_offsets(clust_rec, clust_index,
ULINT_UNDEFINED, heap);
clust_offsets = rec_get_offsets(clust_rec, clust_index, NULL,
ULINT_UNDEFINED, &heap);
trx_id = row_get_rec_trx_id(clust_rec, clust_index, clust_offsets);
mtr_s_lock(&(purge_sys->latch), &mtr);
mutex_enter(&kernel_mutex);
trx = NULL;
if (!trx_is_active(trx_id)) {
/* The transaction that modified or inserted clust_rec is no
longer active: no implicit lock on rec */
mem_heap_free(heap);
mtr_commit(&mtr);
return(NULL);
goto exit_func;
}
if (!lock_check_trx_id_sanity(trx_id, clust_rec, clust_index,
clust_offsets, TRUE)) {
/* Corruption noticed: try to avoid a crash by returning */
mem_heap_free(heap);
mtr_commit(&mtr);
return(NULL);
goto exit_func;
}
comp = index->table->comp;
......@@ -166,7 +159,8 @@ row_vers_impl_x_locked_off_kernel(
if (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,
prev_version, clust_offsets, heap);
entry = row_build_index_entry(row, index, heap);
......@@ -250,6 +244,7 @@ row_vers_impl_x_locked_off_kernel(
version = prev_version;
}/* for (;;) */
exit_func:
mtr_commit(&mtr);
mem_heap_free(heap);
......@@ -330,8 +325,8 @@ row_vers_old_has_index_entry(
comp = index->table->comp;
ut_ad(comp == page_is_comp(buf_frame_align(rec)));
heap = mem_heap_create(1024);
clust_offsets = rec_get_offsets(rec, clust_index,
ULINT_UNDEFINED, heap);
clust_offsets = rec_get_offsets(rec, clust_index, NULL,
ULINT_UNDEFINED, &heap);
if (also_curr && !rec_get_deleted_flag(rec, comp)) {
row = row_build(ROW_COPY_POINTERS, clust_index,
......@@ -371,7 +366,7 @@ row_vers_old_has_index_entry(
}
clust_offsets = rec_get_offsets(prev_version, clust_index,
ULINT_UNDEFINED, heap);
NULL, ULINT_UNDEFINED, &heap);
if (!rec_get_deleted_flag(prev_version, comp)) {
row = row_build(ROW_COPY_POINTERS, clust_index,
......@@ -438,7 +433,7 @@ row_vers_build_for_consistent_read(
#endif /* UNIV_SYNC_DEBUG */
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,
row_get_rec_trx_id(rec, index, offsets)));
......@@ -466,8 +461,8 @@ row_vers_build_for_consistent_read(
break;
}
offsets = rec_get_offsets(prev_version, index,
ULINT_UNDEFINED, heap);
offsets = rec_get_offsets(prev_version, index, NULL,
ULINT_UNDEFINED, &heap);
prev_trx_id = row_get_rec_trx_id(prev_version, index, offsets);
if (read_view_sees_trx_id(view, prev_trx_id)) {
......
......@@ -1010,8 +1010,9 @@ trx_undo_report_row_operation(
ibool is_insert;
trx_rseg_t* rseg;
mtr_t mtr;
mem_heap_t* heap;
ulint* offsets = NULL;
mem_heap_t* heap = NULL;
ulint offsets_[100] = { 100, };
ulint* offsets = offsets_;
ut_a(index->type & DICT_CLUSTERED);
......@@ -1066,8 +1067,6 @@ trx_undo_report_row_operation(
mtr_start(&mtr);
heap = mem_heap_create(100);
for (;;) {
undo_page = buf_page_get_gen(undo->space, page_no,
RW_X_LATCH, undo->guess_page,
......@@ -1084,8 +1083,8 @@ trx_undo_report_row_operation(
index, clust_entry,
&mtr);
} else {
offsets = rec_reget_offsets(rec, index,
offsets, ULINT_UNDEFINED, heap);
offsets = rec_get_offsets(rec, index, offsets,
ULINT_UNDEFINED, &heap);
offset = trx_undo_page_report_modify(undo_page, trx,
index, rec, offsets, update, cmpl_info, &mtr);
}
......@@ -1129,7 +1128,9 @@ trx_undo_report_row_operation(
mutex_exit(&(trx->undo_mutex));
mtr_commit(&mtr);
if (heap) {
mem_heap_free(heap);
}
return(DB_OUT_OF_FILE_SPACE);
}
}
......@@ -1146,7 +1147,9 @@ trx_undo_report_row_operation(
*roll_ptr = trx_undo_build_roll_ptr(is_insert, rseg->id, page_no,
offset);
if (heap) {
mem_heap_free(heap);
}
return(DB_SUCCESS);
}
......@@ -1266,7 +1269,6 @@ trx_undo_prev_version_build(
ibool dummy_extern;
byte* buf;
ulint err;
ulint* index_offsets = NULL;
#ifdef UNIV_SYNC_DEBUG
ut_ad(rw_lock_own(&(purge_sys->latch), RW_LOCK_SHARED));
#endif /* UNIV_SYNC_DEBUG */
......@@ -1282,12 +1284,10 @@ trx_undo_prev_version_build(
"InnoDB: Submit a detailed bug report to"
" http://bugs.mysql.com\n"
"InnoDB: index record ", index->name);
index_offsets = rec_get_offsets(index_rec, index,
ULINT_UNDEFINED, heap);
rec_print(stderr, index_rec, index_offsets);
rec_print(stderr, index_rec, index);
fputs("\n"
"InnoDB: record version ", stderr);
rec_print(stderr, rec, offsets);
rec_print_new(stderr, rec, offsets);
putc('\n', stderr);
return(DB_ERROR);
}
......@@ -1353,12 +1353,10 @@ trx_undo_prev_version_build(
ut_print_buf(stderr, undo_rec, 150);
fputs("\n"
"InnoDB: index record ", stderr);
index_offsets = rec_get_offsets(index_rec, index,
ULINT_UNDEFINED, heap);
rec_print(stderr, index_rec, index_offsets);
rec_print(stderr, index_rec, index);
fputs("\n"
"InnoDB: record version ", stderr);
rec_print(stderr, rec, offsets);
rec_print_new(stderr, rec, offsets);
fprintf(stderr, "\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",
......
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