summaryrefslogtreecommitdiff
path: root/innobase/row
diff options
context:
space:
mode:
authorunknown <marko@hundin.mysql.fi>2005-06-21 07:36:18 +0300
committerunknown <marko@hundin.mysql.fi>2005-06-21 07:36:18 +0300
commit2fb07495ed6aded3a3c9bdbd9456bbe692362bc2 (patch)
tree767c26a535c75a55034463ff090808d95891c741 /innobase/row
parentc2e9730818d9b4a3aa2c237085d3cd41e3001414 (diff)
parent3236060592757ec84b4abcd9e617009dd68555e1 (diff)
downloadmariadb-git-2fb07495ed6aded3a3c9bdbd9456bbe692362bc2.tar.gz
Merge hundin.mysql.fi:/home/marko/mysql-5.0
into hundin.mysql.fi:/home/marko/mysql-5.0-current innobase/dict/dict0dict.c: Auto merged innobase/fil/fil0fil.c: Auto merged innobase/include/lock0lock.h: Auto merged innobase/lock/lock0lock.c: Auto merged innobase/os/os0file.c: Auto merged innobase/row/row0ins.c: Auto merged innobase/row/row0mysql.c: Auto merged innobase/srv/srv0start.c: Auto merged innobase/trx/trx0trx.c: Auto merged sql/ha_innodb.cc: Auto merged sql/ha_innodb.h: Auto merged sql/mysqld.cc: Auto merged
Diffstat (limited to 'innobase/row')
-rw-r--r--innobase/row/row0ins.c108
-rw-r--r--innobase/row/row0mysql.c55
-rw-r--r--innobase/row/row0purge.c4
-rw-r--r--innobase/row/row0row.c10
-rw-r--r--innobase/row/row0sel.c373
-rw-r--r--innobase/row/row0undo.c2
-rw-r--r--innobase/row/row0upd.c27
-rw-r--r--innobase/row/row0vers.c18
8 files changed, 303 insertions, 294 deletions
diff --git a/innobase/row/row0ins.c b/innobase/row/row0ins.c
index 303fe5749bc..776094d0de5 100644
--- a/innobase/row/row0ins.c
+++ b/innobase/row/row0ins.c
@@ -478,7 +478,7 @@ row_ins_cascade_calc_update_vec(
if (parent_ufield->field_no == parent_field_no) {
- ulint fixed_size;
+ ulint min_size;
/* A field in the parent index record is
updated. Let us make the update vector
@@ -508,10 +508,13 @@ row_ins_cascade_calc_update_vec(
column, do not allow the update */
if (ufield->new_val.len != UNIV_SQL_NULL
- && ufield->new_val.len
- > dtype_get_len(type)) {
+ && dtype_get_at_most_n_mbchars(
+ type, dtype_get_len(type),
+ ufield->new_val.len,
+ ufield->new_val.data)
+ < ufield->new_val.len) {
- return(ULINT_UNDEFINED);
+ return(ULINT_UNDEFINED);
}
/* If the parent column type has a different
@@ -519,29 +522,46 @@ row_ins_cascade_calc_update_vec(
need to pad with spaces the new value of the
child column */
- fixed_size = dtype_get_fixed_size(type);
-
- /* TODO: pad in UCS-2 with 0x0020.
- TODO: How does the special truncation of
- UTF-8 CHAR cols affect this? */
+ min_size = dtype_get_min_size(type);
- if (fixed_size
+ if (min_size
&& ufield->new_val.len != UNIV_SQL_NULL
- && ufield->new_val.len < fixed_size) {
+ && ufield->new_val.len < min_size) {
+ char* pad_start;
+ const char* pad_end;
ufield->new_val.data =
mem_heap_alloc(heap,
- fixed_size);
- ufield->new_val.len = fixed_size;
- ut_a(dtype_get_pad_char(type)
- != ULINT_UNDEFINED);
-
- memset(ufield->new_val.data,
- (byte)dtype_get_pad_char(type),
- fixed_size);
+ min_size);
+ pad_start = ufield->new_val.data
+ + ufield->new_val.len;
+ pad_end = ufield->new_val.data
+ + min_size;
+ ufield->new_val.len = min_size;
ut_memcpy(ufield->new_val.data,
parent_ufield->new_val.data,
parent_ufield->new_val.len);
+
+ switch (UNIV_EXPECT(
+ dtype_get_mbminlen(type), 1)) {
+ default:
+ ut_error;
+ case 1:
+ /* space=0x20 */
+ memset(pad_start, 0x20,
+ pad_end - pad_start);
+ break;
+ case 2:
+ /* space=0x0020 */
+ ut_a(!(ufield->new_val.len
+ % 2));
+ ut_a(!(min_size % 2));
+ do {
+ *pad_start++ = 0x00;
+ *pad_start++ = 0x20;
+ } while (pad_start < pad_end);
+ break;
+ }
}
ufield->extern_storage = FALSE;
@@ -1255,9 +1275,11 @@ run_again:
/* Scan index records and check if there is a matching record */
for (;;) {
+ page_t* page;
rec = btr_pcur_get_rec(&pcur);
+ page = buf_frame_align(rec);
- if (rec == page_get_infimum_rec(buf_frame_align(rec))) {
+ if (rec == page_get_infimum_rec(page)) {
goto next_rec;
}
@@ -1265,7 +1287,7 @@ run_again:
offsets = rec_get_offsets(rec, check_index,
offsets, ULINT_UNDEFINED, &heap);
- if (rec == page_get_supremum_rec(buf_frame_align(rec))) {
+ if (rec == page_get_supremum_rec(page)) {
err = row_ins_set_shared_rec_lock(LOCK_ORDINARY, rec,
check_index, offsets, thr);
@@ -1392,7 +1414,7 @@ do_possible_lock_wait:
}
exit_func:
- if (heap) {
+ if (UNIV_LIKELY_NULL(heap)) {
mem_heap_free(heap);
}
return(err);
@@ -1529,12 +1551,7 @@ row_ins_dupl_error_with_rec(
}
}
- if (!rec_get_deleted_flag(rec, index->table->comp)) {
-
- return(TRUE);
- }
-
- return(FALSE);
+ return(!rec_get_deleted_flag(rec, rec_offs_comp(offsets)));
}
/*******************************************************************
@@ -1629,7 +1646,7 @@ row_ins_scan_sec_index_for_duplicate(
break;
}
- if (rec == page_get_supremum_rec(buf_frame_align(rec))) {
+ if (page_rec_is_supremum(rec)) {
goto next_rec;
}
@@ -1660,7 +1677,7 @@ next_rec:
}
}
- if (heap) {
+ if (UNIV_LIKELY_NULL(heap)) {
mem_heap_free(heap);
}
mtr_commit(&mtr);
@@ -1697,7 +1714,6 @@ row_ins_duplicate_error_in_clust(
#ifndef UNIV_HOTBACKUP
ulint err;
rec_t* rec;
- page_t* page;
ulint n_unique;
trx_t* trx = thr_get_trx(thr);
mem_heap_t*heap = NULL;
@@ -1728,9 +1744,8 @@ row_ins_duplicate_error_in_clust(
if (cursor->low_match >= n_unique) {
rec = btr_cur_get_rec(cursor);
- page = buf_frame_align(rec);
- if (rec != page_get_infimum_rec(page)) {
+ if (!page_rec_is_infimum(rec)) {
offsets = rec_get_offsets(rec, cursor->index, offsets,
ULINT_UNDEFINED, &heap);
@@ -1772,9 +1787,8 @@ row_ins_duplicate_error_in_clust(
if (cursor->up_match >= n_unique) {
rec = page_rec_get_next(btr_cur_get_rec(cursor));
- page = buf_frame_align(rec);
- if (rec != page_get_supremum_rec(page)) {
+ if (!page_rec_is_supremum(rec)) {
offsets = rec_get_offsets(rec, cursor->index, offsets,
ULINT_UNDEFINED, &heap);
@@ -1842,7 +1856,6 @@ row_ins_must_modify(
{
ulint enough_match;
rec_t* rec;
- page_t* page;
/* NOTE: (compare to the note in row_ins_duplicate_error) Because node
pointers on upper levels of the B-tree may match more to entry than
@@ -1856,9 +1869,8 @@ row_ins_must_modify(
if (cursor->low_match >= enough_match) {
rec = btr_cur_get_rec(cursor);
- page = buf_frame_align(rec);
- if (rec != page_get_infimum_rec(page)) {
+ if (!page_rec_is_infimum(rec)) {
return(ROW_INS_PREV);
}
@@ -1897,7 +1909,6 @@ row_ins_index_entry_low(
ulint modify = 0; /* remove warning */
rec_t* insert_rec;
rec_t* rec;
- rec_t* first_rec;
ulint err;
ulint n_unique;
big_rec_t* big_rec = NULL;
@@ -1932,15 +1943,20 @@ row_ins_index_entry_low(
err = DB_SUCCESS;
goto function_exit;
- }
-
- first_rec = page_rec_get_next(page_get_infimum_rec(
- buf_frame_align(btr_cur_get_rec(&cursor))));
+ }
+
+#ifdef UNIV_DEBUG
+ {
+ page_t* page = btr_cur_get_page(&cursor);
+ rec_t* first_rec = page_rec_get_next(
+ page_get_infimum_rec(page));
- if (!page_rec_is_supremum(first_rec)) {
- ut_a(rec_get_n_fields(first_rec, index)
+ if (UNIV_LIKELY(first_rec != page_get_supremum_rec(page))) {
+ ut_a(rec_get_n_fields(first_rec, index)
== dtuple_get_n_fields(entry));
+ }
}
+#endif
n_unique = dict_index_get_n_unique(index);
@@ -2048,7 +2064,7 @@ function_exit:
mtr_commit(&mtr);
}
- if (heap) {
+ if (UNIV_LIKELY_NULL(heap)) {
mem_heap_free(heap);
}
return(err);
diff --git a/innobase/row/row0mysql.c b/innobase/row/row0mysql.c
index fafbef4c999..eb50b83a4d5 100644
--- a/innobase/row/row0mysql.c
+++ b/innobase/row/row0mysql.c
@@ -265,7 +265,7 @@ row_mysql_store_col_in_innobase_format(
necessarily the length of the actual
payload data; if the column is a true
VARCHAR then this is irrelevant */
- ibool comp) /* in: TRUE = compact format */
+ ulint comp) /* in: nonzero=compact format */
{
byte* ptr = mysql_data;
dtype_t* dtype;
@@ -971,25 +971,6 @@ run_again:
}
/*************************************************************************
-Unlocks all table locks explicitly requested by trx (with LOCK TABLES,
-lock type LOCK_TABLE_EXP). */
-
-void
-row_unlock_tables_for_mysql(
-/*========================*/
- trx_t* trx) /* in: transaction */
-{
- if (!trx->n_lock_table_exp) {
-
- return;
- }
-
- mutex_enter(&kernel_mutex);
- lock_release_tables_off_kernel(trx);
- mutex_exit(&kernel_mutex);
-}
-
-/*************************************************************************
Sets a table lock on the table mentioned in prebuilt. */
int
@@ -1000,9 +981,10 @@ row_lock_table_for_mysql(
table handle */
dict_table_t* table, /* in: table to lock, or NULL
if prebuilt->table should be
- locked or a
+ locked as
prebuilt->select_lock_type */
- ulint mode) /* in: lock mode of table */
+ ulint mode) /* in: lock mode of table
+ (ignored if table==NULL) */
{
trx_t* trx = prebuilt->trx;
que_thr_t* thr;
@@ -1038,14 +1020,8 @@ run_again:
if (table) {
err = lock_table(0, table, mode, thr);
} else {
- if (mode == LOCK_TABLE_TRANSACTIONAL) {
- err = lock_table(LOCK_TABLE_TRANSACTIONAL,
- prebuilt->table,
- prebuilt->select_lock_type, thr);
- } else {
- err = lock_table(LOCK_TABLE_EXP, prebuilt->table,
- prebuilt->select_lock_type, thr);
- }
+ err = lock_table(0, prebuilt->table,
+ prebuilt->select_lock_type, thr);
}
trx->error_state = err;
@@ -3858,7 +3834,7 @@ funct_exit:
que_graph_free(graph);
}
- if (heap) {
+ if (UNIV_LIKELY_NULL(heap)) {
mem_heap_free(heap);
}
@@ -3893,6 +3869,7 @@ row_scan_and_check_index(
int cmp;
ibool contains_null;
ulint i;
+ ulint cnt;
mem_heap_t* heap = NULL;
ulint offsets_[REC_OFFS_NORMAL_SIZE];
ulint* offsets = offsets_;
@@ -3915,11 +3892,19 @@ row_scan_and_check_index(
dtuple_set_n_fields(prebuilt->search_tuple, 0);
prebuilt->select_lock_type = LOCK_NONE;
+ cnt = 1000;
ret = row_search_for_mysql(buf, PAGE_CUR_G, prebuilt, 0, 0);
loop:
+ /* Check thd->killed every 1,000 scanned rows */
+ if (--cnt == 0) {
+ if (trx_is_interrupted(prebuilt->trx)) {
+ goto func_exit;
+ }
+ cnt = 1000;
+ }
if (ret != DB_SUCCESS) {
-
+ func_exit:
mem_free(buf);
mem_heap_free(heap);
@@ -4046,7 +4031,7 @@ row_check_table_for_mysql(
ut_print_name(stderr, index->name);
putc('\n', stderr); */
- if (!btr_validate_tree(index->tree)) {
+ if (!btr_validate_tree(index->tree, prebuilt->trx)) {
ret = DB_ERROR;
} else {
if (!row_scan_and_check_index(prebuilt,
@@ -4054,6 +4039,10 @@ row_check_table_for_mysql(
ret = DB_ERROR;
}
+ if (trx_is_interrupted(prebuilt->trx)) {
+ break;
+ }
+
/* fprintf(stderr, "%lu entries in index %s\n", n_rows,
index->name); */
diff --git a/innobase/row/row0purge.c b/innobase/row/row0purge.c
index 5893e016011..abcf97110d9 100644
--- a/innobase/row/row0purge.c
+++ b/innobase/row/row0purge.c
@@ -126,7 +126,7 @@ row_purge_remove_clust_if_poss_low(
if (0 != ut_dulint_cmp(node->roll_ptr,
row_get_rec_roll_ptr(rec, index, rec_get_offsets(
rec, index, offsets_, ULINT_UNDEFINED, &heap)))) {
- if (heap) {
+ if (UNIV_LIKELY_NULL(heap)) {
mem_heap_free(heap);
}
/* Someone else has modified the record later: do not remove */
@@ -135,7 +135,7 @@ row_purge_remove_clust_if_poss_low(
return(TRUE);
}
- if (heap) {
+ if (UNIV_LIKELY_NULL(heap)) {
mem_heap_free(heap);
}
diff --git a/innobase/row/row0row.c b/innobase/row/row0row.c
index a6d3f1d5ab0..9a74397dc08 100644
--- a/innobase/row/row0row.c
+++ b/innobase/row/row0row.c
@@ -535,7 +535,7 @@ row_build_row_ref_in_tuple(
}
ut_ad(dtuple_check_typed(ref));
- if (heap) {
+ if (UNIV_LIKELY_NULL(heap)) {
mem_heap_free(heap);
}
}
@@ -616,7 +616,6 @@ row_search_on_row_ref(
ulint low_match;
rec_t* rec;
dict_index_t* index;
- page_t* page;
ut_ad(dtuple_check_typed(ref));
@@ -629,9 +628,8 @@ row_search_on_row_ref(
low_match = btr_pcur_get_low_match(pcur);
rec = btr_pcur_get_rec(pcur);
- page = buf_frame_align(rec);
- if (rec == page_get_infimum_rec(page)) {
+ if (page_rec_is_infimum(rec)) {
return(FALSE);
}
@@ -702,7 +700,6 @@ row_search_index_entry(
{
ulint n_fields;
ulint low_match;
- page_t* page;
rec_t* rec;
ut_ad(dtuple_check_typed(entry));
@@ -711,11 +708,10 @@ row_search_index_entry(
low_match = btr_pcur_get_low_match(pcur);
rec = btr_pcur_get_rec(pcur);
- page = buf_frame_align(rec);
n_fields = dtuple_get_n_fields(entry);
- if (rec == page_get_infimum_rec(page)) {
+ if (page_rec_is_infimum(rec)) {
return(FALSE);
}
diff --git a/innobase/row/row0sel.c b/innobase/row/row0sel.c
index 94cf82d6a3d..c7a548fe448 100644
--- a/innobase/row/row0sel.c
+++ b/innobase/row/row0sel.c
@@ -125,7 +125,7 @@ row_sel_sec_rec_is_for_clust_rec(
}
func_exit:
- if (heap) {
+ if (UNIV_LIKELY_NULL(heap)) {
mem_heap_free(heap);
}
return(is_equal);
@@ -630,6 +630,8 @@ row_sel_get_clust_rec(
ulint* offsets = offsets_;
*offsets_ = (sizeof offsets_) / sizeof *offsets_;
+ *out_rec = NULL;
+
offsets = rec_get_offsets(rec,
btr_pcur_get_btr_cur(&plan->pcur)->index,
offsets, ULINT_UNDEFINED, &heap);
@@ -663,8 +665,6 @@ row_sel_get_clust_rec(
clustered index record did not exist in the read view of
trx. */
- clust_rec = NULL;
-
goto func_exit;
}
@@ -733,7 +733,6 @@ row_sel_get_clust_rec(
if ((old_vers || rec_get_deleted_flag(rec, plan->table->comp))
&& !row_sel_sec_rec_is_for_clust_rec(rec, plan->index,
clust_rec, index)) {
- clust_rec = NULL;
goto func_exit;
}
}
@@ -742,11 +741,11 @@ row_sel_get_clust_rec(
row_sel_fetch_columns(index, clust_rec, offsets,
UT_LIST_GET_FIRST(plan->columns));
-func_exit:
*out_rec = clust_rec;
+func_exit:
err = DB_SUCCESS;
err_exit:
- if (heap) {
+ if (UNIV_LIKELY_NULL(heap)) {
mem_heap_free(heap);
}
return(err);
@@ -1066,7 +1065,7 @@ row_sel_try_search_shortcut(
plan->n_rows_fetched++;
func_exit:
- if (heap) {
+ if (UNIV_LIKELY_NULL(heap)) {
mem_heap_free(heap);
}
return(SEL_FOUND);
@@ -1261,7 +1260,7 @@ rec_loop:
/* PHASE 1: Set a lock if specified */
if (!node->asc && cursor_just_opened
- && (rec != page_get_supremum_rec(buf_frame_align(rec)))) {
+ && !page_rec_is_supremum(rec)) {
/* When we open a cursor for a descending search, we must set
a next-key lock on the successor record: otherwise it would
@@ -1299,7 +1298,7 @@ rec_loop:
}
}
- if (rec == page_get_infimum_rec(buf_frame_align(rec))) {
+ if (page_rec_is_infimum(rec)) {
/* The infimum record on a page cannot be in the result set,
and neither can a record lock be placed on it: we skip such
@@ -1337,7 +1336,7 @@ rec_loop:
}
}
- if (rec == page_get_supremum_rec(buf_frame_align(rec))) {
+ if (page_rec_is_supremum(rec)) {
/* A page supremum record cannot be in the result set: skip
it now when we have placed a possible lock on it */
@@ -1780,7 +1779,7 @@ lock_wait_or_error:
ut_ad(sync_thread_levels_empty_gen(TRUE));
func_exit:
- if (heap) {
+ if (UNIV_LIKELY_NULL(heap)) {
mem_heap_free(heap);
}
return(err);
@@ -2416,14 +2415,12 @@ row_sel_store_mysql_rec(
mem_heap_t* extern_field_heap = NULL;
byte* data;
ulint len;
- byte* blob_buf;
- int pad_char;
ulint i;
ut_ad(prebuilt->mysql_template);
ut_ad(rec_offs_validate(rec, NULL, offsets));
- if (prebuilt->blob_heap != NULL) {
+ if (UNIV_LIKELY_NULL(prebuilt->blob_heap)) {
mem_heap_free(prebuilt->blob_heap);
prebuilt->blob_heap = NULL;
}
@@ -2435,7 +2432,8 @@ row_sel_store_mysql_rec(
data = rec_get_nth_field(rec, offsets,
templ->rec_field_no, &len);
- if (rec_offs_nth_extern(offsets, templ->rec_field_no)) {
+ if (UNIV_UNLIKELY(rec_offs_nth_extern(offsets,
+ templ->rec_field_no))) {
/* Copy an externally stored field to the temporary
heap */
@@ -2456,7 +2454,7 @@ row_sel_store_mysql_rec(
}
if (len != UNIV_SQL_NULL) {
- if (templ->type == DATA_BLOB) {
+ if (UNIV_UNLIKELY(templ->type == DATA_BLOB)) {
ut_a(prebuilt->templ_contains_blob);
@@ -2465,8 +2463,9 @@ row_sel_store_mysql_rec(
of 1000000 bytes. Since the test takes some
CPU time, we do not use it for small BLOBs. */
- if (len > 2000000
- && !ut_test_malloc(len + 1000000)) {
+ if (UNIV_UNLIKELY(len > 2000000)
+ && UNIV_UNLIKELY(!ut_test_malloc(
+ len + 1000000))) {
ut_print_timestamp(stderr);
fprintf(stderr,
@@ -2492,11 +2491,9 @@ row_sel_store_mysql_rec(
mem_heap_create(len);
}
- blob_buf = mem_heap_alloc(prebuilt->blob_heap,
- len);
- ut_memcpy(blob_buf, data, len);
-
- data = blob_buf;
+ data = memcpy(mem_heap_alloc(
+ prebuilt->blob_heap, len),
+ data, len);
}
row_sel_field_store_in_mysql_format(
@@ -2521,41 +2518,45 @@ row_sel_store_mysql_rec(
account caused seg faults with NULL BLOB fields, and
bug number 154 in the MySQL bug database: GROUP BY
and DISTINCT could treat NULL values inequal. */
+ int pad_char;
mysql_rec[templ->mysql_null_byte_offset] |=
(byte) (templ->mysql_null_bit_mask);
- if (templ->type == DATA_VARCHAR
- || templ->type == DATA_CHAR
- || templ->type == DATA_BINARY
- || templ->type == DATA_FIXBINARY
- || templ->type == DATA_MYSQL
- || templ->type == DATA_VARMYSQL) {
+ switch (templ->type) {
+ case DATA_VARCHAR:
+ case DATA_CHAR:
+ case DATA_BINARY:
+ case DATA_FIXBINARY:
+ case DATA_MYSQL:
+ case DATA_VARMYSQL:
/* MySQL pads all non-BLOB and non-TEXT
string types with space ' ' */
-
- pad_char = ' ';
- } else {
- pad_char = '\0';
+ if (UNIV_UNLIKELY(templ->mbminlen == 2)) {
+ /* Treat UCS2 as a special case. */
+ data = mysql_rec
+ + templ->mysql_col_offset;
+ len = templ->mysql_col_len;
+ /* There are two UCS2 bytes per char,
+ so the length has to be even. */
+ ut_a(!(len & 1));
+ /* Pad with 0x0020. */
+ while (len) {
+ *data++ = 0x00;
+ *data++ = 0x20;
+ len -= 2;
+ }
+ continue;
+ }
+ pad_char = 0x20;
+ break;
+ default:
+ pad_char = 0x00;
+ break;
}
- /* Handle UCS2 strings differently. */
- if (pad_char != '\0' && templ->mbminlen == 2) {
- /* There are two bytes per char, so the length
- has to be an even number. */
- ut_a(!(templ->mysql_col_len & 1));
- data = mysql_rec + templ->mysql_col_offset;
- len = templ->mysql_col_len;
- /* Pad with 0x0020. */
- while (len >= 2) {
- *data++ = 0x00;
- *data++ = 0x20;
- len -= 2;
- }
- } else {
- ut_ad(!pad_char || templ->mbminlen == 1);
- memset(mysql_rec + templ->mysql_col_offset,
+ ut_ad(!pad_char || templ->mbminlen == 1);
+ memset(mysql_rec + templ->mysql_col_offset,
pad_char, templ->mysql_col_len);
- }
}
}
@@ -2849,8 +2850,9 @@ row_sel_pop_cached_row_for_mysql(
mysql_row_templ_t* templ;
byte* cached_rec;
ut_ad(prebuilt->n_fetch_cached > 0);
+ ut_ad(prebuilt->mysql_prefix_len <= prebuilt->mysql_row_len);
- if (prebuilt->keep_other_fields_on_keyread)
+ if (UNIV_UNLIKELY(prebuilt->keep_other_fields_on_keyread))
{
/* Copy cache record field by field, don't touch fields that
are not covered by current key */
@@ -2877,7 +2879,7 @@ row_sel_pop_cached_row_for_mysql(
else
{
ut_memcpy(buf, prebuilt->fetch_cache[prebuilt->fetch_cache_first],
- prebuilt->mysql_row_len);
+ prebuilt->mysql_prefix_len);
}
prebuilt->n_fetch_cached--;
prebuilt->fetch_cache_first++;
@@ -2925,9 +2927,9 @@ row_sel_push_cache_row_for_mysql(
ut_ad(prebuilt->fetch_cache_first == 0);
- if (!row_sel_store_mysql_rec(
+ if (UNIV_UNLIKELY(!row_sel_store_mysql_rec(
prebuilt->fetch_cache[prebuilt->n_fetch_cached],
- prebuilt, rec, offsets)) {
+ prebuilt, rec, offsets))) {
ut_error;
}
@@ -3048,11 +3050,7 @@ row_search_for_mysql(
rec_t* index_rec;
rec_t* clust_rec;
rec_t* old_vers;
- ulint err = DB_SUCCESS;
- ibool moved;
- ibool cons_read_requires_clust_rec;
- ibool was_lock_wait;
- ulint shortcut;
+ ulint err = DB_SUCCESS;
ibool unique_search = FALSE;
ibool unique_search_from_clust_index = FALSE;
ibool mtr_has_extra_clust_latch = FALSE;
@@ -3062,9 +3060,9 @@ row_search_for_mysql(
locking SELECT, and the isolation
level is <= TRX_ISO_READ_COMMITTED,
then this is set to FALSE */
- ibool success;
- ibool comp;
+#ifdef UNIV_SEARCH_DEBUG
ulint cnt = 0;
+#endif /* UNIV_SEARCH_DEBUG */
ulint next_offs;
mtr_t mtr;
mem_heap_t* heap = NULL;
@@ -3075,7 +3073,7 @@ row_search_for_mysql(
ut_ad(index && pcur && search_tuple);
ut_ad(trx->mysql_thread_id == os_thread_get_curr_id());
- if (prebuilt->table->ibd_file_missing) {
+ if (UNIV_UNLIKELY(prebuilt->table->ibd_file_missing)) {
ut_print_timestamp(stderr);
fprintf(stderr, " InnoDB: Error:\n"
"InnoDB: MySQL is trying to use a table handle but the .ibd file for\n"
@@ -3089,7 +3087,7 @@ row_search_for_mysql(
return(DB_ERROR);
}
- if (prebuilt->magic_n != ROW_PREBUILT_ALLOCATED) {
+ if (UNIV_UNLIKELY(prebuilt->magic_n != ROW_PREBUILT_ALLOCATED)) {
fprintf(stderr,
"InnoDB: Error: trying to free a corrupt\n"
"InnoDB: table handle. Magic n %lu, table name ",
@@ -3103,7 +3101,7 @@ row_search_for_mysql(
}
if (trx->n_mysql_tables_in_use == 0
- && prebuilt->select_lock_type == LOCK_NONE) {
+ && UNIV_UNLIKELY(prebuilt->select_lock_type == LOCK_NONE)) {
/* Note that if MySQL uses an InnoDB temp table that it
created inside LOCK TABLES, then n_mysql_tables_in_use can
be zero; in that case select_lock_type is set to LOCK_X in
@@ -3126,8 +3124,8 @@ row_search_for_mysql(
/* PHASE 0: Release a possible s-latch we are holding on the
adaptive hash index latch if there is someone waiting behind */
- if (trx->has_search_latch
- && btr_search_latch.writer != RW_LOCK_NOT_LOCKED) {
+ if (UNIV_UNLIKELY(btr_search_latch.writer != RW_LOCK_NOT_LOCKED)
+ && trx->has_search_latch) {
/* There is an x-latch request on the adaptive hash index:
release the s-latch to reduce starvation and wait for
@@ -3143,7 +3141,7 @@ row_search_for_mysql(
/*-------------------------------------------------------------*/
/* PHASE 1: Try to pop the row from the prefetch cache */
- if (direction == 0) {
+ if (UNIV_UNLIKELY(direction == 0)) {
trx->op_info = "starting index read";
prebuilt->n_rows_fetched = 0;
@@ -3161,8 +3159,8 @@ row_search_for_mysql(
prebuilt->fetch_direction = direction;
}
- if (direction != prebuilt->fetch_direction) {
- if (prebuilt->n_fetch_cached > 0) {
+ if (UNIV_UNLIKELY(direction != prebuilt->fetch_direction)) {
+ if (UNIV_UNLIKELY(prebuilt->n_fetch_cached > 0)) {
ut_error;
/* TODO: scrollable cursor: restore cursor to
the place of the latest returned row,
@@ -3174,7 +3172,7 @@ row_search_for_mysql(
prebuilt->n_fetch_cached = 0;
prebuilt->fetch_cache_first = 0;
- } else if (prebuilt->n_fetch_cached > 0) {
+ } else if (UNIV_LIKELY(prebuilt->n_fetch_cached > 0)) {
row_sel_pop_cached_row_for_mysql(buf, prebuilt);
prebuilt->n_rows_fetched++;
@@ -3234,7 +3232,8 @@ row_search_for_mysql(
1 column. Return immediately if this is not a HANDLER
command. */
- if (direction != 0 && !prebuilt->used_in_HANDLER) {
+ if (UNIV_UNLIKELY(direction != 0 &&
+ !prebuilt->used_in_HANDLER)) {
err = DB_RECORD_NOT_FOUND;
goto func_exit;
@@ -3252,9 +3251,9 @@ row_search_for_mysql(
cannot use the adaptive hash index in a search in the case the row
may be long and there may be externally stored fields */
- if (unique_search
+ if (UNIV_UNLIKELY(direction == 0)
+ && unique_search
&& index->type & DICT_CLUSTERED
- && direction == 0
&& !prebuilt->templ_contains_blob
&& !prebuilt->used_in_HANDLER
&& (prebuilt->mysql_row_len < UNIV_PAGE_SIZE / 8)) {
@@ -3286,9 +3285,9 @@ row_search_for_mysql(
trx->has_search_latch = TRUE;
}
#endif
- shortcut = row_sel_try_search_shortcut_for_mysql(&rec,
- prebuilt, &offsets, &heap, &mtr);
- if (shortcut == SEL_FOUND) {
+ switch (row_sel_try_search_shortcut_for_mysql(&rec,
+ prebuilt, &offsets, &heap, &mtr)) {
+ case SEL_FOUND:
#ifdef UNIV_SEARCH_DEBUG
ut_a(0 == cmp_dtuple_rec(search_tuple,
rec, offsets));
@@ -3322,9 +3321,8 @@ row_search_for_mysql(
position */
err = DB_SUCCESS;
goto func_exit;
-
- } else if (shortcut == SEL_EXHAUSTED) {
+ case SEL_EXHAUSTED:
mtr_commit(&mtr);
/* ut_print_name(stderr, index->name);
@@ -3367,6 +3365,7 @@ shortcut_fails_too_big_rec:
/* Scan the MySQL query string; check if SELECT is the first
word there */
+ ibool success;
dict_accept(*trx->mysql_query_str, "SELECT", &success);
@@ -3382,7 +3381,7 @@ shortcut_fails_too_big_rec:
naturally moves upward (in fetch next) in alphabetical order,
otherwise downward */
- if (direction == 0) {
+ if (UNIV_UNLIKELY(direction == 0)) {
if (mode == PAGE_CUR_GE || mode == PAGE_CUR_G) {
moves_up = TRUE;
}
@@ -3396,10 +3395,9 @@ shortcut_fails_too_big_rec:
clust_index = dict_table_get_first_index(index->table);
- if (direction != 0) {
- moved = sel_restore_position_for_mysql(BTR_SEARCH_LEAF, pcur,
- moves_up, &mtr);
- if (!moved) {
+ if (UNIV_LIKELY(direction != 0)) {
+ if (!sel_restore_position_for_mysql(BTR_SEARCH_LEAF, pcur,
+ moves_up, &mtr)) {
goto next_rec;
}
@@ -3440,11 +3438,13 @@ shortcut_fails_too_big_rec:
trx_assign_read_view(trx);
prebuilt->sql_stat_start = FALSE;
} else {
+ ulint lock_mode;
if (prebuilt->select_lock_type == LOCK_S) {
- err = lock_table(0, index->table, LOCK_IS, thr);
+ lock_mode = LOCK_IS;
} else {
- err = lock_table(0, index->table, LOCK_IX, thr);
+ lock_mode = LOCK_IX;
}
+ err = lock_table(0, index->table, lock_mode, thr);
if (err != DB_SUCCESS) {
@@ -3458,8 +3458,8 @@ rec_loop:
/* PHASE 4: Look for matching records in a loop */
rec = btr_pcur_get_rec(pcur);
- comp = index->table->comp;
- ut_ad(comp == page_is_comp(buf_frame_align(rec)));
+ ut_ad(!!page_rec_is_comp(rec) == index->table->comp);
+#ifdef UNIV_SEARCH_DEBUG
/*
fputs("Using ", stderr);
dict_index_name_print(stderr, index);
@@ -3467,7 +3467,9 @@ rec_loop:
buf_frame_get_page_no(buf_frame_align(rec)));
rec_print(rec);
*/
- if (rec == page_get_infimum_rec(buf_frame_align(rec))) {
+#endif /* UNIV_SEARCH_DEBUG */
+
+ if (page_rec_is_infimum(rec)) {
/* The infimum record on a page cannot be in the result set,
and neither can a record lock be placed on it: we skip such
@@ -3476,10 +3478,11 @@ rec_loop:
goto next_rec;
}
- if (rec == page_get_supremum_rec(buf_frame_align(rec))) {
+ if (page_rec_is_supremum(rec)) {
- if (prebuilt->select_lock_type != LOCK_NONE
- && set_also_gap_locks) {
+ if (set_also_gap_locks
+ && !srv_locks_unsafe_for_binlog
+ && prebuilt->select_lock_type != LOCK_NONE) {
/* Try to place a lock on the index record */
@@ -3487,18 +3490,16 @@ rec_loop:
we do not lock gaps. Supremum record is really
a gap and therefore we do not set locks there. */
- if (!srv_locks_unsafe_for_binlog) {
- offsets = rec_get_offsets(rec, index, offsets,
- ULINT_UNDEFINED, &heap);
- err = sel_set_rec_lock(rec, index, offsets,
- prebuilt->select_lock_type,
- LOCK_ORDINARY, thr);
- if (err != DB_SUCCESS) {
+ offsets = rec_get_offsets(rec, index, offsets,
+ ULINT_UNDEFINED, &heap);
+ err = sel_set_rec_lock(rec, index, offsets,
+ prebuilt->select_lock_type,
+ LOCK_ORDINARY, thr);
- goto lock_wait_or_error;
- }
- }
+ if (err != DB_SUCCESS) {
+ goto lock_wait_or_error;
+ }
}
/* A page supremum record cannot be in the result set: skip
it now that we have placed a possible lock on it */
@@ -3510,12 +3511,19 @@ rec_loop:
/* Do sanity checks in case our cursor has bumped into page
corruption */
- next_offs = rec_get_next_offs(rec, comp);
-
- if (next_offs >= UNIV_PAGE_SIZE
- || next_offs <
- (ulint) (comp ? PAGE_NEW_SUPREMUM : PAGE_OLD_SUPREMUM)) {
-
+ if (page_rec_is_comp(rec)) {
+ next_offs = rec_get_next_offs(rec, TRUE);
+ if (UNIV_UNLIKELY(next_offs < PAGE_NEW_SUPREMUM)) {
+ goto wrong_offs;
+ }
+ } else {
+ next_offs = rec_get_next_offs(rec, FALSE);
+ if (UNIV_UNLIKELY(next_offs < PAGE_OLD_SUPREMUM)) {
+ goto wrong_offs;
+ }
+ }
+ if (UNIV_UNLIKELY(next_offs >= UNIV_PAGE_SIZE - PAGE_DIR)) {
+ wrong_offs:
if (srv_force_recovery == 0 || moves_up == FALSE) {
ut_print_timestamp(stderr);
buf_page_print(buf_frame_align(rec));
@@ -3528,7 +3536,7 @@ rec_loop:
fprintf(stderr,
"InnoDB: Index corruption: rec offs %lu next offs %lu, page no %lu,\n"
"InnoDB: ",
- (ulong) (rec - buf_frame_align(rec)),
+ (ulong) ut_align_offset(rec, UNIV_PAGE_SIZE),
(ulong) next_offs,
(ulong) buf_frame_get_page_no(rec));
dict_index_name_print(stderr, trx, index);
@@ -3546,7 +3554,7 @@ rec_loop:
fprintf(stderr,
"InnoDB: Index corruption: rec offs %lu next offs %lu, page no %lu,\n"
"InnoDB: ",
- (ulong) (rec - buf_frame_align(rec)),
+ (ulong) ut_align_offset(rec, UNIV_PAGE_SIZE),
(ulong) next_offs,
(ulong) buf_frame_get_page_no(rec));
dict_index_name_print(stderr, trx, index);
@@ -3561,13 +3569,13 @@ rec_loop:
offsets = rec_get_offsets(rec, index, offsets, ULINT_UNDEFINED, &heap);
- if (srv_force_recovery > 0) {
+ if (UNIV_UNLIKELY(srv_force_recovery > 0)) {
if (!rec_validate(rec, offsets)
|| !btr_index_rec_validate(rec, index, FALSE)) {
fprintf(stderr,
"InnoDB: Index corruption: rec offs %lu next offs %lu, page no %lu,\n"
"InnoDB: ",
- (ulong) (rec - buf_frame_align(rec)),
+ (ulong) ut_align_offset(rec, UNIV_PAGE_SIZE),
(ulong) next_offs,
(ulong) buf_frame_get_page_no(rec));
dict_index_name_print(stderr, trx, index);
@@ -3593,25 +3601,22 @@ rec_loop:
if (0 != cmp_dtuple_rec(search_tuple, rec, offsets)) {
- if (prebuilt->select_lock_type != LOCK_NONE
- && set_also_gap_locks) {
+ if (set_also_gap_locks
+ && !srv_locks_unsafe_for_binlog
+ && prebuilt->select_lock_type != LOCK_NONE) {
/* Try to place a gap lock on the index
record only if innodb_locks_unsafe_for_binlog
option is not set */
- if (srv_locks_unsafe_for_binlog == FALSE) {
-
- err = sel_set_rec_lock(rec, index,
- offsets,
+ err = sel_set_rec_lock(rec, index, offsets,
prebuilt->select_lock_type,
LOCK_GAP, thr);
- if (err != DB_SUCCESS) {
- goto lock_wait_or_error;
- }
- }
+ if (err != DB_SUCCESS) {
+ goto lock_wait_or_error;
+ }
}
btr_pcur_store_position(pcur, &mtr);
@@ -3627,25 +3632,22 @@ rec_loop:
if (!cmp_dtuple_is_prefix_of_rec(search_tuple, rec, offsets)) {
- if (prebuilt->select_lock_type != LOCK_NONE
- && set_also_gap_locks) {
+ if (set_also_gap_locks
+ && !srv_locks_unsafe_for_binlog
+ && prebuilt->select_lock_type != LOCK_NONE) {
/* Try to place a gap lock on the index
record only if innodb_locks_unsafe_for_binlog
option is not set */
- if (srv_locks_unsafe_for_binlog == FALSE) {
-
- err = sel_set_rec_lock(rec, index,
- offsets,
+ err = sel_set_rec_lock(rec, index, offsets,
prebuilt->select_lock_type,
LOCK_GAP, thr);
- if (err != DB_SUCCESS) {
- goto lock_wait_or_error;
- }
- }
+ if (err != DB_SUCCESS) {
+ goto lock_wait_or_error;
+ }
}
btr_pcur_store_position(pcur, &mtr);
@@ -3661,29 +3663,25 @@ rec_loop:
/* We are ready to look at a possible new index entry in the result
set: the cursor is now placed on a user record */
- cons_read_requires_clust_rec = FALSE;
-
if (prebuilt->select_lock_type != LOCK_NONE) {
/* Try to place a lock on the index record; note that delete
marked records are a special case in a unique search. If there
is a non-delete marked record, then it is enough to lock its
existence with LOCK_REC_NOT_GAP. */
+ /* If innodb_locks_unsafe_for_binlog option is used,
+ we lock only the record, i.e., next-key locking is
+ not used. */
+
ulint lock_type;
if (!set_also_gap_locks
- || (unique_search && !rec_get_deleted_flag(rec, comp))) {
- lock_type = LOCK_REC_NOT_GAP;
+ || srv_locks_unsafe_for_binlog
+ || (unique_search && !UNIV_UNLIKELY(rec_get_deleted_flag(
+ rec, page_rec_is_comp(rec))))) {
+ goto no_gap_lock;
} else {
- /* If innodb_locks_unsafe_for_binlog option is used,
- we lock only the record, i.e., next-key locking is
- not used. */
-
- if (srv_locks_unsafe_for_binlog) {
- lock_type = LOCK_REC_NOT_GAP;
- } else {
- lock_type = LOCK_ORDINARY;
- }
+ lock_type = LOCK_ORDINARY;
}
/* If we are doing a 'greater or equal than a primary key
@@ -3703,7 +3701,7 @@ rec_loop:
&& dtuple_get_n_fields_cmp(search_tuple)
== dict_index_get_n_unique(index)
&& 0 == cmp_dtuple_rec(search_tuple, rec, offsets)) {
-
+ no_gap_lock:
lock_type = LOCK_REC_NOT_GAP;
}
@@ -3731,7 +3729,7 @@ rec_loop:
high force recovery level set, we try to avoid crashes
by skipping this lookup */
- if (srv_force_recovery < 5
+ if (UNIV_LIKELY(srv_force_recovery < 5)
&& !lock_clust_rec_cons_read_sees(rec, index,
offsets, trx->read_view)) {
@@ -3762,13 +3760,15 @@ rec_loop:
have to look also into the clustered index: this
is necessary, because we can only get the undo
information via the clustered index record. */
-
- cons_read_requires_clust_rec = TRUE;
+
+ /* Get the clustered index record if needed */
+ index_rec = rec;
+ ut_ad(index != clust_index);
+ goto requires_clust_rec;
}
}
- if (rec_get_deleted_flag(rec, comp)
- && !cons_read_requires_clust_rec) {
+ if (UNIV_UNLIKELY(rec_get_deleted_flag(rec, page_rec_is_comp(rec)))) {
/* The record is delete-marked: we can skip it if this is
not a consistent read which might see an earlier version
@@ -3782,14 +3782,14 @@ rec_loop:
index_rec = rec;
- /* Before and after the following "if" block, "offsets" will be
- related to "rec", which may be in "index", a secondary index or
- the clustered index ("clust_index"). However, after this "if" block,
- "rec" may be pointing to "clust_rec" of "clust_index". */
- ut_ad(rec_offs_validate(rec, index, offsets));
-
- if (index != clust_index && (cons_read_requires_clust_rec
- || prebuilt->need_to_access_clustered)) {
+ if (index != clust_index && prebuilt->need_to_access_clustered) {
+ requires_clust_rec:
+ /* Before and after this "if" block, "offsets" will be
+ related to "rec", which may be in a secondary index "index" or
+ the clustered index ("clust_index"). However, after this
+ "if" block, "rec" may be pointing to
+ "clust_rec" of "clust_index". */
+ ut_ad(rec_offs_validate(rec, index, offsets));
/* It was a non-clustered index and we must fetch also the
clustered index record */
@@ -3811,7 +3811,8 @@ rec_loop:
goto next_rec;
}
- if (rec_get_deleted_flag(clust_rec, comp)) {
+ if (UNIV_UNLIKELY(rec_get_deleted_flag(clust_rec,
+ page_rec_is_comp(clust_rec)))) {
/* The record is delete marked: we can skip it */
@@ -3832,7 +3833,8 @@ rec_loop:
rec == clust_rec ? clust_index : index,
offsets));
- if (prebuilt->n_rows_fetched >= MYSQL_FETCH_CACHE_THRESHOLD
+ if ((match_mode == ROW_SEL_EXACT
+ || prebuilt->n_rows_fetched >= MYSQL_FETCH_CACHE_THRESHOLD)
&& prebuilt->select_lock_type == LOCK_NONE
&& !prebuilt->templ_contains_blob
&& !prebuilt->clust_index_was_generated
@@ -3907,7 +3909,7 @@ next_rec:
/*-------------------------------------------------------------*/
/* PHASE 5: Move the cursor to the next index record */
- if (mtr_has_extra_clust_latch) {
+ if (UNIV_UNLIKELY(mtr_has_extra_clust_latch)) {
/* We must commit mtr if we are moving to the next
non-clustered index record, because we could break the
latching order if we would access a different clustered
@@ -3919,34 +3921,38 @@ next_rec:
mtr_has_extra_clust_latch = FALSE;
mtr_start(&mtr);
- moved = sel_restore_position_for_mysql(BTR_SEARCH_LEAF, pcur,
- moves_up, &mtr);
- if (moved) {
+ if (sel_restore_position_for_mysql(BTR_SEARCH_LEAF, pcur,
+ moves_up, &mtr)) {
+#ifdef UNIV_SEARCH_DEBUG
cnt++;
+#endif /* UNIV_SEARCH_DEBUG */
goto rec_loop;
}
}
if (moves_up) {
- moved = btr_pcur_move_to_next(pcur, &mtr);
- } else {
- moved = btr_pcur_move_to_prev(pcur, &mtr);
- }
+ if (UNIV_UNLIKELY(!btr_pcur_move_to_next(pcur, &mtr))) {
+ not_moved:
+ btr_pcur_store_position(pcur, &mtr);
- if (!moved) {
- btr_pcur_store_position(pcur, &mtr);
+ if (match_mode != 0) {
+ err = DB_RECORD_NOT_FOUND;
+ } else {
+ err = DB_END_OF_INDEX;
+ }
- if (match_mode != 0) {
- err = DB_RECORD_NOT_FOUND;
- } else {
- err = DB_END_OF_INDEX;
+ goto normal_return;
+ }
+ } else {
+ if (UNIV_UNLIKELY(!btr_pcur_move_to_prev(pcur, &mtr))) {
+ goto not_moved;
}
-
- goto normal_return;
}
+#ifdef UNIV_SEARCH_DEBUG
cnt++;
+#endif /* UNIV_SEARCH_DEBUG */
goto rec_loop;
@@ -3964,11 +3970,10 @@ lock_wait_or_error:
que_thr_stop_for_mysql(thr);
- thr->lock_state= QUE_THR_LOCK_ROW;
- was_lock_wait = row_mysql_handle_errors(&err, trx, thr, NULL);
- thr->lock_state= QUE_THR_LOCK_NOLOCK;
+ thr->lock_state = QUE_THR_LOCK_ROW;
- if (was_lock_wait) {
+ if (row_mysql_handle_errors(&err, trx, thr, NULL)) {
+ thr->lock_state = QUE_THR_LOCK_NOLOCK;
mtr_start(&mtr);
sel_restore_position_for_mysql(BTR_SEARCH_LEAF, pcur,
@@ -3978,9 +3983,13 @@ lock_wait_or_error:
goto rec_loop;
}
+ thr->lock_state = QUE_THR_LOCK_NOLOCK;
+
+#ifdef UNIV_SEARCH_DEBUG
/* fputs("Using ", stderr);
dict_index_name_print(stderr, index);
fprintf(stderr, " cnt %lu ret value %lu err\n", cnt, err); */
+#endif /* UNIV_SEARCH_DEBUG */
goto func_exit;
normal_return:
@@ -3995,16 +4004,18 @@ normal_return:
err = DB_SUCCESS;
}
+#ifdef UNIV_SEARCH_DEBUG
/* fputs("Using ", stderr);
dict_index_name_print(stderr, index);
fprintf(stderr, " cnt %lu ret value %lu err\n", cnt, err); */
+#endif /* UNIV_SEARCH_DEBUG */
if (err == DB_SUCCESS) {
srv_n_rows_read++;
}
func_exit:
trx->op_info = "";
- if (heap) {
+ if (UNIV_LIKELY_NULL(heap)) {
mem_heap_free(heap);
}
return(err);
diff --git a/innobase/row/row0undo.c b/innobase/row/row0undo.c
index abe73cbe705..435c0279dbb 100644
--- a/innobase/row/row0undo.c
+++ b/innobase/row/row0undo.c
@@ -190,7 +190,7 @@ row_undo_search_clust_to_pcur(
btr_pcur_commit_specify_mtr(&(node->pcur), &mtr);
- if (heap) {
+ if (UNIV_LIKELY_NULL(heap)) {
mem_heap_free(heap);
}
return(ret);
diff --git a/innobase/row/row0upd.c b/innobase/row/row0upd.c
index 3305724a89b..cf2b8db5d32 100644
--- a/innobase/row/row0upd.c
+++ b/innobase/row/row0upd.c
@@ -815,9 +815,10 @@ row_upd_build_difference_binary(
goto skip_compare;
}
- extern_bit = rec_offs_nth_extern(offsets, i);
+ extern_bit = upd_ext_vec_contains(ext_vec, n_ext_vec, i);
- if (extern_bit != upd_ext_vec_contains(ext_vec, n_ext_vec, i)
+ if (UNIV_UNLIKELY(extern_bit ==
+ !rec_offs_nth_extern(offsets, i))
|| !dfield_data_is_binary_equal(dfield, len, data)) {
upd_field = upd_get_nth_field(update, n_diff);
@@ -826,12 +827,8 @@ row_upd_build_difference_binary(
upd_field_set_field_no(upd_field, i, index, trx);
- if (upd_ext_vec_contains(ext_vec, n_ext_vec, i)) {
- upd_field->extern_storage = TRUE;
- } else {
- upd_field->extern_storage = FALSE;
- }
-
+ upd_field->extern_storage = extern_bit;
+
n_diff++;
}
skip_compare:
@@ -1224,7 +1221,7 @@ row_upd_store_row(
node->n_ext_vec = btr_push_update_extern_fields(node->ext_vec,
offsets, update);
- if (heap) {
+ if (UNIV_LIKELY_NULL(heap)) {
mem_heap_free(heap);
}
}
@@ -1270,7 +1267,7 @@ row_upd_sec_index_entry(
rec = btr_cur_get_rec(btr_cur);
- if (!found) {
+ if (UNIV_UNLIKELY(!found)) {
fputs("InnoDB: error in sec index entry update in\n"
"InnoDB: ", stderr);
dict_index_name_print(stderr, trx, index);
@@ -1423,7 +1420,7 @@ row_upd_clust_rec_by_insert(
index, thr, mtr);
if (err != DB_SUCCESS) {
mtr_commit(mtr);
- if (heap) {
+ if (UNIV_LIKELY_NULL(heap)) {
mem_heap_free(heap);
}
return(err);
@@ -1549,7 +1546,7 @@ row_upd_clust_rec(
rec_get_offsets(rec, index, offsets_,
ULINT_UNDEFINED, &heap),
big_rec, mtr);
- if (heap) {
+ if (UNIV_LIKELY_NULL(heap)) {
mem_heap_free(heap);
}
mtr_commit(mtr);
@@ -1719,7 +1716,7 @@ row_upd_clust_step(
node->index = dict_table_get_next_index(index);
}
exit_func:
- if (heap) {
+ if (UNIV_LIKELY_NULL(heap)) {
mem_heap_free(heap);
}
return(err);
@@ -1736,7 +1733,7 @@ row_upd_clust_step(
row_upd_eval_new_vals(node->update);
}
- if (heap) {
+ if (UNIV_LIKELY_NULL(heap)) {
mem_heap_free(heap);
}
@@ -2016,7 +2013,7 @@ row_upd_in_place_in_select(
btr_pcur_get_rec(pcur), btr_cur->index, offsets_,
ULINT_UNDEFINED, &heap),
UT_LIST_GET_FIRST(node->columns));
- if (heap) {
+ if (UNIV_LIKELY_NULL(heap)) {
mem_heap_free(heap);
}
row_upd_eval_new_vals(node->update);
diff --git a/innobase/row/row0vers.c b/innobase/row/row0vers.c
index 36f6c27636d..8e747423047 100644
--- a/innobase/row/row0vers.c
+++ b/innobase/row/row0vers.c
@@ -57,11 +57,11 @@ row_vers_impl_x_locked_off_kernel(
dtuple_t* entry = NULL; /* assignment to eliminate compiler
warning */
trx_t* trx;
- ibool vers_del;
- ibool rec_del;
+ ulint vers_del;
+ ulint rec_del;
ulint err;
mtr_t mtr;
- ibool comp;
+ ulint comp;
#ifdef UNIV_SYNC_DEBUG
ut_ad(mutex_own(&kernel_mutex));
@@ -121,10 +121,10 @@ row_vers_impl_x_locked_off_kernel(
goto exit_func;
}
- comp = index->table->comp;
+ comp = page_rec_is_comp(rec);
ut_ad(index->table == clust_index->table);
- ut_ad(comp == page_is_comp(buf_frame_align(rec)));
- ut_ad(comp == page_is_comp(buf_frame_align(clust_rec)));
+ ut_ad(!!comp == index->table->comp);
+ ut_ad(!comp == !page_rec_is_comp(clust_rec));
/* We look up if some earlier version, which was modified by the trx_id
transaction, of the clustered index record would require rec to be in
@@ -310,7 +310,7 @@ row_vers_old_has_index_entry(
dtuple_t* row;
dtuple_t* entry;
ulint err;
- ibool comp;
+ ulint comp;
ut_ad(mtr_memo_contains(mtr, buf_block_align(rec), MTR_MEMO_PAGE_X_FIX)
|| mtr_memo_contains(mtr, buf_block_align(rec),
@@ -322,8 +322,8 @@ row_vers_old_has_index_entry(
clust_index = dict_table_get_first_index(index->table);
- comp = index->table->comp;
- ut_ad(comp == page_is_comp(buf_frame_align(rec)));
+ comp = page_rec_is_comp(rec);
+ ut_ad(!index->table->comp == !comp);
heap = mem_heap_create(1024);
clust_offsets = rec_get_offsets(rec, clust_index, NULL,
ULINT_UNDEFINED, &heap);