diff options
author | Aleksey Midenkov <midenok@gmail.com> | 2020-12-22 03:33:53 +0300 |
---|---|---|
committer | Aleksey Midenkov <midenok@gmail.com> | 2020-12-22 03:33:53 +0300 |
commit | 7410ff436e95de09c2f3f0028e7af8b3a043028b (patch) | |
tree | f9a64e0059b0f16413cfd4ac11b8263072a0d705 /storage/innobase/row/row0mysql.cc | |
parent | d4258f3a8fba0f8972714325c0dc0ca925879b86 (diff) | |
download | mariadb-git-7410ff436e95de09c2f3f0028e7af8b3a043028b.tar.gz |
MDEV-21138 Assertion `col->ord_part' or `f.col->ord_part' failed in row_build_index_entry_low
First part (row0mysql.cc) fixes ins_node_set_new_row() usage workflow
as it is designed to operate on empty row (see row_get_prebuilt_insert_row()
for example).
Second part (row0ins.cc) fixes duplicate key error in FTS_DOC_ID_INDEX
since history rows must not generate entries in that index. We detect
FTS_DOC_ID_INDEX by a number of attributes and skip it if the row is
historical.
Misc fixes:
row_build_index_entry_low() does not accept non-NULL tuple
for FTS index (subject assertion fails), assertion (index->type !=
DICT_FTS) adds code understanding.
Now as historical_row is copied in row_update_vers_insert() there is
no need to copy the row twice: ROW_COPY_POINTERS is used to build
historical_row initially.
dbug_print_rec() debug functions.
Diffstat (limited to 'storage/innobase/row/row0mysql.cc')
-rw-r--r-- | storage/innobase/row/row0mysql.cc | 45 |
1 files changed, 38 insertions, 7 deletions
diff --git a/storage/innobase/row/row0mysql.cc b/storage/innobase/row/row0mysql.cc index dc88b41c6b4..848f60c47d0 100644 --- a/storage/innobase/row/row0mysql.cc +++ b/storage/innobase/row/row0mysql.cc @@ -2104,10 +2104,18 @@ row_mysql_unfreeze_data_dictionary( @param buf Buffer to hold start time data */ void thd_get_query_start_data(THD *thd, char *buf); -/** Function restores btr_pcur_t, creates dtuple_t from rec_t, -sets row_end = CURRENT_TIMESTAMP/trx->id, inserts it to a table and updates -table statistics. -This is used in UPDATE CASCADE/SET NULL of a system versioning table. +/** Insert history row when evaluating foreign key referential action. + +1. Create new dtuple_t 'row' from node->historical_row; +2. Update its row_end to current timestamp; +3. Insert it to a table; +4. Update table statistics. + +This is used in UPDATE CASCADE/SET NULL of a system versioned referenced table. + +node->historical_row: dtuple_t containing pointers of row changed by refertial +action. + @param[in] thr current query thread @param[in] node a node which just updated a row in a foreign table @return DB_SUCCESS or some error */ @@ -2119,9 +2127,16 @@ static dberr_t row_update_vers_insert(que_thr_t* thr, upd_node_t* node) dict_table_t* table = node->table; ut_ad(table->versioned()); - dtuple_t* row = node->historical_row; - ut_ad(row); - node->historical_row = NULL; + dtuple_t* row; + const ulint n_cols = dict_table_get_n_cols(table); + const ulint n_v_cols = dict_table_get_n_v_cols(table); + + ut_ad(n_cols == dtuple_get_n_fields(node->historical_row)); + ut_ad(n_v_cols == dtuple_get_n_v_fields(node->historical_row)); + + row = dtuple_create_with_vcol(node->historical_heap, n_cols, n_v_cols); + + dict_table_copy_types(row, table); ins_node_t* insert_node = ins_node_create(INS_DIRECT, table, node->historical_heap); @@ -2134,6 +2149,22 @@ static dberr_t row_update_vers_insert(que_thr_t* thr, upd_node_t* node) insert_node->common.parent = thr; ins_node_set_new_row(insert_node, row); + ut_ad(n_cols > DATA_N_SYS_COLS); + // Exclude DB_ROW_ID, DB_TRX_ID, DB_ROLL_PTR + for (ulint i = 0; i < n_cols - DATA_N_SYS_COLS; i++) { + dfield_t *dst= dtuple_get_nth_field(row, i); + dfield_t *src= dtuple_get_nth_field(node->historical_row, i); + dfield_copy(dst, src); + } + + for (ulint i = 0; i < n_v_cols; i++) { + dfield_t *dst= dtuple_get_nth_v_field(row, i); + dfield_t *src= dtuple_get_nth_v_field(node->historical_row, i); + dfield_copy(dst, src); + } + + node->historical_row = NULL; + row_end = dtuple_get_nth_field(row, table->vers_end); if (dict_table_get_nth_col(table, table->vers_end)->vers_native()) { mach_write_to_8(row_end_data, trx->id); |