diff options
author | Eugene Kosov <claprix@yandex.ru> | 2019-05-19 23:15:55 +0300 |
---|---|---|
committer | Marko Mäkelä <marko.makela@mariadb.com> | 2019-05-20 10:23:17 +0300 |
commit | 48a662dae5cd5dcc2d3cd9cd03104b5152c1d23c (patch) | |
tree | e2d5bb33510f1022e84a46a8e80ccc6dcd429604 /storage | |
parent | 7056812ed15abb398089b9c6aa6d7bf5c3cb8c0e (diff) | |
download | mariadb-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.cc | 22 | ||||
-rw-r--r-- | storage/innobase/row/row0upd.cc | 6 |
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), |