summaryrefslogtreecommitdiff
path: root/storage/innobase/row/row0mysql.cc
diff options
context:
space:
mode:
authorAleksey Midenkov <midenok@gmail.com>2020-12-22 03:33:53 +0300
committerAleksey Midenkov <midenok@gmail.com>2020-12-22 03:33:53 +0300
commit7410ff436e95de09c2f3f0028e7af8b3a043028b (patch)
treef9a64e0059b0f16413cfd4ac11b8263072a0d705 /storage/innobase/row/row0mysql.cc
parentd4258f3a8fba0f8972714325c0dc0ca925879b86 (diff)
downloadmariadb-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.cc45
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);