summaryrefslogtreecommitdiff
path: root/storage/innobase/row
diff options
context:
space:
mode:
Diffstat (limited to 'storage/innobase/row')
-rw-r--r--storage/innobase/row/row0ins.cc8
-rw-r--r--storage/innobase/row/row0merge.cc3
-rw-r--r--storage/innobase/row/row0mysql.cc3
-rw-r--r--storage/innobase/row/row0purge.cc42
-rw-r--r--storage/innobase/row/row0sel.cc23
-rw-r--r--storage/innobase/row/row0umod.cc4
-rw-r--r--storage/innobase/row/row0upd.cc31
-rw-r--r--storage/innobase/row/row0vers.cc3
8 files changed, 76 insertions, 41 deletions
diff --git a/storage/innobase/row/row0ins.cc b/storage/innobase/row/row0ins.cc
index 123566132f4..b0401485bab 100644
--- a/storage/innobase/row/row0ins.cc
+++ b/storage/innobase/row/row0ins.cc
@@ -970,11 +970,9 @@ row_ins_foreign_fill_virtual(
innobase_init_vc_templ(index->table);
}
- if (innobase_allocate_row_for_vcol(thd, index, &v_heap,
- &mysql_table,
- &record, &vcol_storage)) {
- if (v_heap) mem_heap_free(v_heap);
- *err = DB_OUT_OF_MEMORY;
+ if ((*err = innobase_allocate_row_for_vcol(thd, index, v_heap,
+ &mysql_table,
+ &record, &vcol_storage))) {
goto func_exit;
}
diff --git a/storage/innobase/row/row0merge.cc b/storage/innobase/row/row0merge.cc
index 8c8f1674374..99f866a732d 100644
--- a/storage/innobase/row/row0merge.cc
+++ b/storage/innobase/row/row0merge.cc
@@ -595,8 +595,7 @@ row_merge_buf_add(
= dict_table_get_first_index(new_table);
if (!vcol_storage &&
- innobase_allocate_row_for_vcol(trx->mysql_thd, clust_index, v_heap, &my_table, &record, &vcol_storage)) {
- *err = DB_OUT_OF_MEMORY;
+ (*err = innobase_allocate_row_for_vcol(trx->mysql_thd, clust_index, *v_heap, &my_table, &record, &vcol_storage))) {
goto error;
}
diff --git a/storage/innobase/row/row0mysql.cc b/storage/innobase/row/row0mysql.cc
index 9bbd531cb9a..5fc14c7fad2 100644
--- a/storage/innobase/row/row0mysql.cc
+++ b/storage/innobase/row/row0mysql.cc
@@ -781,6 +781,9 @@ handle_new_error:
<< FK_MAX_CASCADE_DEL << ". Please drop excessive"
" foreign constraints and try again";
goto rollback_to_savept;
+ case DB_OUT_OF_MEMORY:
+ ib::fatal() << "Out of memory";
+ break;
default:
ib::fatal() << "Unknown error code " << err << ": "
<< ut_strerr(err);
diff --git a/storage/innobase/row/row0purge.cc b/storage/innobase/row/row0purge.cc
index f4fd617f154..8f9756bdc53 100644
--- a/storage/innobase/row/row0purge.cc
+++ b/storage/innobase/row/row0purge.cc
@@ -284,6 +284,7 @@ row_purge_poss_sec(
purge_node_t* node,
dict_index_t* index,
const dtuple_t* entry,
+ dberr_t& err,
btr_pcur_t* sec_pcur,
mtr_t* sec_mtr,
bool is_tree)
@@ -318,7 +319,10 @@ retry_purge_sec:
btr_pcur_get_rec(&node->pcur),
&mtr, index, entry,
node->roll_ptr, node->trx_id,
- &node->vcol_info);
+ err, &node->vcol_info);
+ if (err) {
+ return false;
+ }
if (node->vcol_info.is_first_fetch()) {
ut_ad(store_cur);
@@ -375,11 +379,11 @@ row_purge_remove_sec_if_poss_tree(
/*==============================*/
purge_node_t* node, /*!< in: row purge node */
dict_index_t* index, /*!< in: index */
- const dtuple_t* entry) /*!< in: index entry */
+ const dtuple_t* entry, /*!< in: index entry */
+ dberr_t& err)
{
btr_pcur_t pcur;
ibool success = TRUE;
- dberr_t err;
mtr_t mtr;
enum row_search_result search_result;
@@ -442,7 +446,7 @@ row_purge_remove_sec_if_poss_tree(
which cannot be purged yet, requires its existence. If some requires,
we should do nothing. */
- if (row_purge_poss_sec(node, index, entry, &pcur, &mtr, true)) {
+ if (row_purge_poss_sec(node, index, entry, err, &pcur, &mtr, true)) {
/* Remove the index record, which should have been
marked for deletion. */
@@ -476,6 +480,8 @@ row_purge_remove_sec_if_poss_tree(
default:
ut_error;
}
+ } else {
+ success = false;
}
if (node->vcol_op_failed()) {
@@ -510,6 +516,7 @@ row_purge_remove_sec_if_poss_leaf(
btr_pcur_t pcur;
enum btr_latch_mode mode;
enum row_search_result search_result;
+ dberr_t err = DB_SUCCESS;
bool success = true;
log_free_check();
@@ -576,7 +583,7 @@ row_purge_remove_sec_if_poss_leaf(
case ROW_FOUND:
/* Before attempting to purge a record, check
if it is safe to do so. */
- if (row_purge_poss_sec(node, index, entry, &pcur, &mtr, false)) {
+ if (row_purge_poss_sec(node, index, entry, err, &pcur, &mtr, false)) {
btr_cur_t* btr_cur = btr_pcur_get_btr_cur(&pcur);
/* Only delete-marked records should be purged. */
@@ -643,7 +650,7 @@ row_purge_remove_sec_if_poss_leaf(
}
}
- if (node->vcol_op_failed()) {
+ if (err || node->vcol_op_failed()) {
btr_pcur_close(&pcur);
return false;
}
@@ -670,7 +677,7 @@ func_exit_no_pcur:
/***********************************************************//**
Removes a secondary index entry if possible. */
UNIV_INLINE MY_ATTRIBUTE((nonnull(1,2)))
-void
+dberr_t
row_purge_remove_sec_if_poss(
/*=========================*/
purge_node_t* node, /*!< in: row purge node */
@@ -678,6 +685,7 @@ row_purge_remove_sec_if_poss(
const dtuple_t* entry) /*!< in: index entry */
{
ibool success;
+ dberr_t err = DB_SUCCESS;
ulint n_tries = 0;
/* fputs("Purge: Removing secondary record\n", stderr); */
@@ -686,19 +694,19 @@ row_purge_remove_sec_if_poss(
/* The node->row must have lacked some fields of this
index. This is possible when the undo log record was
written before this index was created. */
- return;
+ return err;
}
if (row_purge_remove_sec_if_poss_leaf(node, index, entry)) {
- return;
+ return err;
}
retry:
if (node->vcol_op_failed()) {
- return;
+ return err;
}
- success = row_purge_remove_sec_if_poss_tree(node, index, entry);
+ success = row_purge_remove_sec_if_poss_tree(node, index, entry, err);
/* The delete operation may fail if we have little
file space left: TODO: easiest to crash the database
and restart with more file space */
@@ -712,7 +720,8 @@ retry:
goto retry;
}
- ut_a(success);
+ ut_a(success || err);
+ return err;
}
/** Skip uncommitted virtual indexes on newly added virtual column.
@@ -763,9 +772,10 @@ row_purge_del_mark(
dtuple_t* entry = row_build_index_entry_low(
node->row, NULL, node->index,
heap, ROW_BUILD_FOR_PURGE);
- row_purge_remove_sec_if_poss(node, node->index, entry);
- if (node->vcol_op_failed()) {
+
+ if (row_purge_remove_sec_if_poss(node, node->index, entry)
+ || node->vcol_op_failed()) {
mem_heap_free(heap);
return false;
}
@@ -823,9 +833,9 @@ row_purge_upd_exist_or_extern_func(
dtuple_t* entry = row_build_index_entry_low(
node->row, NULL, node->index,
heap, ROW_BUILD_FOR_PURGE);
- row_purge_remove_sec_if_poss(node, node->index, entry);
- if (node->vcol_op_failed()) {
+ if (row_purge_remove_sec_if_poss(node, node->index, entry)
+ || node->vcol_op_failed()) {
ut_ad(!node->table);
mem_heap_free(heap);
return;
diff --git a/storage/innobase/row/row0sel.cc b/storage/innobase/row/row0sel.cc
index 15486500b37..74b48bd799c 100644
--- a/storage/innobase/row/row0sel.cc
+++ b/storage/innobase/row/row0sel.cc
@@ -164,6 +164,7 @@ row_sel_sec_rec_is_for_clust_rec(
dict_index_t* sec_index,
const rec_t* clust_rec,
dict_index_t* clust_index,
+ dberr_t& err,
que_thr_t* thr)
{
const byte* sec_field;
@@ -179,6 +180,7 @@ row_sel_sec_rec_is_for_clust_rec(
ibool is_equal = TRUE;
VCOL_STORAGE* vcol_storage= 0;
byte* record;
+ err = DB_SUCCESS;
rec_offs_init(clust_offsets_);
rec_offs_init(sec_offsets_);
@@ -228,12 +230,15 @@ row_sel_sec_rec_is_for_clust_rec(
if (!vcol_storage)
{
TABLE *mysql_table= thr->prebuilt->m_mysql_table;
- innobase_allocate_row_for_vcol(thr_get_trx(thr)->mysql_thd,
+ err = innobase_allocate_row_for_vcol(thr_get_trx(thr)->mysql_thd,
clust_index,
- &heap,
+ heap,
&mysql_table,
&record,
&vcol_storage);
+ if (err) {
+ return false;
+ }
}
v_col = reinterpret_cast<const dict_v_col_t*>(col);
@@ -1035,8 +1040,12 @@ row_sel_get_clust_rec(
plan->table)))
&& !row_sel_sec_rec_is_for_clust_rec(rec, plan->index,
clust_rec, index,
- thr)) {
- goto func_exit;
+ err, thr)) {
+ if (!err) {
+ goto func_exit;
+ } else {
+ goto err_exit;
+ }
}
}
@@ -3581,8 +3590,12 @@ Row_sel_get_clust_rec_for_mysql::operator()(
|| rec_get_deleted_flag(rec, dict_table_is_comp(
sec_index->table)))
&& !row_sel_sec_rec_is_for_clust_rec(
- rec, sec_index, clust_rec, clust_index, thr)) {
+ rec, sec_index, clust_rec, clust_index, err, thr)) {
clust_rec = NULL;
+ if (err) {
+ goto err_exit;
+ }
+
}
err = DB_SUCCESS;
diff --git a/storage/innobase/row/row0umod.cc b/storage/innobase/row/row0umod.cc
index ac4500f5c3e..8b5c7aad8a3 100644
--- a/storage/innobase/row/row0umod.cc
+++ b/storage/innobase/row/row0umod.cc
@@ -511,11 +511,11 @@ row_undo_mod_del_mark_or_remove_sec_low(
if (dict_table_is_temporary(node->table)
|| row_vers_old_has_index_entry(
false, btr_pcur_get_rec(&(node->pcur)),
- &mtr_vers, index, entry, 0, 0)) {
+ &mtr_vers, index, entry, 0, 0, err)) {
err = btr_cur_del_mark_set_sec_rec(BTR_NO_LOCKING_FLAG,
btr_cur, TRUE, thr, &mtr);
ut_ad(err == DB_SUCCESS);
- } else {
+ } else if (!err) {
/* Remove the index record */
if (dict_index_is_spatial(index)) {
diff --git a/storage/innobase/row/row0upd.cc b/storage/innobase/row/row0upd.cc
index a316041ed0e..1a47d27affc 100644
--- a/storage/innobase/row/row0upd.cc
+++ b/storage/innobase/row/row0upd.cc
@@ -1130,9 +1130,9 @@ row_upd_build_difference_binary(
ut_ad(!update->old_vrow);
- innobase_allocate_row_for_vcol(thd, index, &v_heap,
- &mysql_table,
- &record, &vcol_storage);
+ *error = innobase_allocate_row_for_vcol(thd, index, v_heap,
+ &mysql_table,
+ &record, &vcol_storage);
for (i = 0; i < n_v_fld; i++) {
const dict_v_col_t* col
@@ -2117,7 +2117,7 @@ row_upd_eval_new_vals(
@param[in] thd mysql thread handle
@param[in,out] mysql_table mysql table object */
static
-void
+dberr_t
row_upd_store_v_row(
upd_node_t* node,
const upd_t* update,
@@ -2129,9 +2129,13 @@ row_upd_store_v_row(
byte* record= 0;
VCOL_STORAGE *vcol_storage= 0;
- if (!update)
- innobase_allocate_row_for_vcol(thd, index, &heap, &mysql_table,
+ if (!update) {
+ dberr_t err = innobase_allocate_row_for_vcol(thd, index, heap, &mysql_table,
&record, &vcol_storage);
+ if (err) {
+ return err;
+ }
+ }
for (ulint col_no = 0; col_no < dict_table_get_n_v_cols(node->table);
col_no++) {
@@ -2198,7 +2202,7 @@ row_upd_store_v_row(
innobase_free_row_for_vcol(vcol_storage);
mem_heap_free(heap);
}
-
+ return DB_SUCCESS;
}
/** Stores to the heap the row on which the node->pcur is positioned.
@@ -2207,7 +2211,7 @@ row_upd_store_v_row(
@param[in,out] mysql_table NULL, or mysql table object when
user thread invokes dml */
static
-void
+dberr_t
row_upd_store_row(
upd_node_t* node,
THD* thd,
@@ -2219,6 +2223,7 @@ row_upd_store_row(
row_ext_t** ext;
rec_offs offsets_[REC_OFFS_NORMAL_SIZE];
const rec_offs* offsets;
+ dberr_t err = DB_SUCCESS;
rec_offs_init(offsets_);
ut_ad(node->pcur->latch_mode != BTR_NO_LATCHES);
@@ -2251,8 +2256,11 @@ row_upd_store_row(
NULL, NULL, NULL, ext, node->heap);
if (node->table->n_v_cols) {
- row_upd_store_v_row(node, node->is_delete ? NULL : node->update,
+ err = row_upd_store_v_row(node, node->is_delete ? NULL : node->update,
thd, mysql_table);
+ if (err) {
+ goto err_exit;
+ }
}
if (node->is_delete) {
@@ -2264,9 +2272,12 @@ row_upd_store_row(
clust_index, node->update, node->heap);
}
+
+err_exit:
if (UNIV_LIKELY_NULL(heap)) {
mem_heap_free(heap);
}
+ return err;
}
/***********************************************************//**
@@ -2982,7 +2993,7 @@ row_upd_del_mark_clust_rec(
/* Store row because we have to build also the secondary index
entries */
- row_upd_store_row(node, trx->mysql_thd,
+ err = row_upd_store_row(node, trx->mysql_thd,
thr->prebuilt && thr->prebuilt->table == node->table
? thr->prebuilt->m_mysql_table : NULL);
diff --git a/storage/innobase/row/row0vers.cc b/storage/innobase/row/row0vers.cc
index 3627c659231..544c9aad313 100644
--- a/storage/innobase/row/row0vers.cc
+++ b/storage/innobase/row/row0vers.cc
@@ -470,7 +470,7 @@ row_vers_build_clust_v_col(
}
innobase_allocate_row_for_vcol(thd, index,
- &local_heap,
+ local_heap,
&maria_table,
&record,
&vcol_storage);
@@ -887,6 +887,7 @@ row_vers_old_has_index_entry(
const dtuple_t* ientry,
roll_ptr_t roll_ptr,
trx_id_t trx_id,
+ dberr_t& err,
purge_vcol_info_t* vcol_info)
{
const rec_t* version;