summaryrefslogtreecommitdiff
path: root/storage
diff options
context:
space:
mode:
authorEugene Kosov <claprix@yandex.ru>2019-05-19 23:15:55 +0300
committerMarko Mäkelä <marko.makela@mariadb.com>2019-05-20 10:23:17 +0300
commit48a662dae5cd5dcc2d3cd9cd03104b5152c1d23c (patch)
treee2d5bb33510f1022e84a46a8e80ccc6dcd429604 /storage
parent7056812ed15abb398089b9c6aa6d7bf5c3cb8c0e (diff)
downloadmariadb-git-48a662dae5cd5dcc2d3cd9cd03104b5152c1d23c.tar.gz
MDEV-19486 Server crashes in row_upd or row_upd_del_mark_clust_rec on REPLACE into a versioned table
row_insert_for_mysql(): InnoDB sets values for row_start and row_end. And this function used to return those values to server in ha_innobase::write_row(). This buggy behavior was removed. Also, a piece of code in this function was reformatted. upd_node_t::make_versioned_helper(): Assert that the preallocated size of the update vector is not exceeded.
Diffstat (limited to 'storage')
-rw-r--r--storage/innobase/row/row0mysql.cc22
-rw-r--r--storage/innobase/row/row0upd.cc6
2 files changed, 14 insertions, 14 deletions
diff --git a/storage/innobase/row/row0mysql.cc b/storage/innobase/row/row0mysql.cc
index 50a1d7ae568..679aa63f9d5 100644
--- a/storage/innobase/row/row0mysql.cc
+++ b/storage/innobase/row/row0mysql.cc
@@ -1417,26 +1417,24 @@ row_insert_for_mysql(
row_mysql_convert_row_to_innobase(node->row, prebuilt, mysql_rec,
&blob_heap);
- if (ins_mode != ROW_INS_NORMAL)
- {
+ if (ins_mode != ROW_INS_NORMAL) {
ut_ad(table->vers_start != table->vers_end);
- /* Return back modified fields into mysql_rec, so that
- upper logic may benefit from it (f.ex. 'on duplicate key'). */
- const mysql_row_templ_t* t = prebuilt->get_template_by_col(table->vers_end);
+ const mysql_row_templ_t* t
+ = prebuilt->get_template_by_col(table->vers_end);
ut_ad(t);
ut_ad(t->mysql_col_len == 8);
if (ins_mode == ROW_INS_HISTORICAL) {
- set_tuple_col_8(node->row, table->vers_end, trx->id, node->vers_end_buf);
- }
- else /* ROW_INS_VERSIONED */ {
- set_tuple_col_8(node->row, table->vers_end, TRX_ID_MAX, node->vers_end_buf);
- int8store(&mysql_rec[t->mysql_col_offset], TRX_ID_MAX);
+ set_tuple_col_8(node->row, table->vers_end, trx->id,
+ node->vers_end_buf);
+ } else /* ROW_INS_VERSIONED */ {
+ set_tuple_col_8(node->row, table->vers_end, TRX_ID_MAX,
+ node->vers_end_buf);
t = prebuilt->get_template_by_col(table->vers_start);
ut_ad(t);
ut_ad(t->mysql_col_len == 8);
- set_tuple_col_8(node->row, table->vers_start, trx->id, node->vers_start_buf);
- int8store(&mysql_rec[t->mysql_col_offset], trx->id);
+ set_tuple_col_8(node->row, table->vers_start, trx->id,
+ node->vers_start_buf);
}
}
diff --git a/storage/innobase/row/row0upd.cc b/storage/innobase/row/row0upd.cc
index 234a33b844e..15f213d0711 100644
--- a/storage/innobase/row/row0upd.cc
+++ b/storage/innobase/row/row0upd.cc
@@ -3485,9 +3485,11 @@ void upd_node_t::make_versioned_helper(const trx_t* trx, ulint idx)
dict_index_t* clust_index = dict_table_get_first_index(table);
+ /* row_create_update_node_for_mysql() pre-allocated this much */
+ ut_ad(update->n_fields < table->n_cols + table->n_v_cols);
+
update->n_fields++;
- upd_field_t* ufield =
- upd_get_nth_field(update, upd_get_n_fields(update) - 1);
+ upd_field_t* ufield = upd_get_nth_field(update, update->n_fields - 1);
const dict_col_t* col = dict_table_get_nth_col(table, idx);
upd_field_set_field_no(ufield, dict_col_get_clust_pos(col, clust_index),