summaryrefslogtreecommitdiff
path: root/storage/innobase/row
diff options
context:
space:
mode:
authorNikita Malyavin <nikitamalyavin@gmail.com>2021-10-27 18:37:33 +0300
committerMarko Mäkelä <marko.makela@mariadb.com>2021-10-28 07:32:27 +0300
commit1f5ca66e53b165c29ea733acd0fab79975a43eda (patch)
tree2552b55cb6a1e16cfa2a8648520adba9160c525a /storage/innobase/row
parent3a9967d7579a31e5a43606d563584335348caaa5 (diff)
downloadmariadb-git-1f5ca66e53b165c29ea733acd0fab79975a43eda.tar.gz
MDEV-26866 FOREIGN KEY…SET NULL corrupts an index on a virtual column
The initial test case for MySQL Bug #33053297 is based on mysql/mysql-server@27130e25078864b010d81266f9613d389d4a229b. innobase_get_field_from_update_vector is not a suitable function to fetch updated row info, as well as parent table's update vector is not always suitable. For instance, in case of DELETE it contains undefined data. castade->update vector seems to be good enough to fetch all base columns update data, and besides faster, and less error-prone.
Diffstat (limited to 'storage/innobase/row')
-rw-r--r--storage/innobase/row/row0ins.cc15
-rw-r--r--storage/innobase/row/row0merge.cc4
-rw-r--r--storage/innobase/row/row0sel.cc2
-rw-r--r--storage/innobase/row/row0upd.cc5
-rw-r--r--storage/innobase/row/row0vers.cc2
5 files changed, 13 insertions, 15 deletions
diff --git a/storage/innobase/row/row0ins.cc b/storage/innobase/row/row0ins.cc
index 929d3683ce6..cbe6577c02a 100644
--- a/storage/innobase/row/row0ins.cc
+++ b/storage/innobase/row/row0ins.cc
@@ -898,7 +898,6 @@ row_ins_invalidate_query_cache(
innobase_invalidate_query_cache(thr_get_trx(thr), name, len);
}
-
/** Fill virtual column information in cascade node for the child table.
@param[out] cascade child update node
@param[in] rec clustered rec of child table
@@ -945,6 +944,11 @@ row_ins_foreign_fill_virtual(
if (!record) {
return DB_OUT_OF_MEMORY;
}
+ ut_ad(!node->is_delete
+ || (foreign->type & DICT_FOREIGN_ON_DELETE_SET_NULL));
+ ut_ad(foreign->type & (DICT_FOREIGN_ON_DELETE_SET_NULL
+ | DICT_FOREIGN_ON_UPDATE_SET_NULL
+ | DICT_FOREIGN_ON_UPDATE_CASCADE));
for (ulint i = 0; i < n_v_fld; i++) {
@@ -960,7 +964,7 @@ row_ins_foreign_fill_virtual(
dfield_t* vfield = innobase_get_computed_value(
update->old_vrow, col, index,
&vc.heap, update->heap, NULL, thd, mysql_table,
- record, NULL, NULL, NULL);
+ record, NULL, NULL);
if (vfield == NULL) {
return DB_COMPUTE_VALUE_FAILED;
@@ -976,16 +980,11 @@ row_ins_foreign_fill_virtual(
upd_field_set_v_field_no(upd_field, i, index);
- bool set_null =
- node->is_delete
- ? (foreign->type & DICT_FOREIGN_ON_DELETE_SET_NULL)
- : (foreign->type & DICT_FOREIGN_ON_UPDATE_SET_NULL);
-
dfield_t* new_vfield = innobase_get_computed_value(
update->old_vrow, col, index,
&vc.heap, update->heap, NULL, thd,
mysql_table, record, NULL,
- set_null ? update : node->update, foreign);
+ update);
if (new_vfield == NULL) {
return DB_COMPUTE_VALUE_FAILED;
diff --git a/storage/innobase/row/row0merge.cc b/storage/innobase/row/row0merge.cc
index 9e6179585b1..faa148cca24 100644
--- a/storage/innobase/row/row0merge.cc
+++ b/storage/innobase/row/row0merge.cc
@@ -600,8 +600,8 @@ error:
row_field = innobase_get_computed_value(
row, v_col, clust_index,
v_heap, NULL, ifield, trx->mysql_thd,
- my_table, vcol_storage.innobase_record,
- old_table, NULL, NULL);
+ my_table, vcol_storage.innobase_record,
+ old_table, NULL);
if (row_field == NULL) {
*err = DB_COMPUTE_VALUE_FAILED;
diff --git a/storage/innobase/row/row0sel.cc b/storage/innobase/row/row0sel.cc
index 83bf18ab9b8..87c67edff4b 100644
--- a/storage/innobase/row/row0sel.cc
+++ b/storage/innobase/row/row0sel.cc
@@ -328,7 +328,7 @@ row_sel_sec_rec_is_for_clust_rec(
&heap, NULL, NULL,
thr_get_trx(thr)->mysql_thd,
thr->prebuilt->m_mysql_table,
- record, NULL, NULL, NULL);
+ record, NULL, NULL);
if (vfield == NULL) {
innobase_report_computed_value_failed(row);
diff --git a/storage/innobase/row/row0upd.cc b/storage/innobase/row/row0upd.cc
index a58c3993e90..0a79225da8c 100644
--- a/storage/innobase/row/row0upd.cc
+++ b/storage/innobase/row/row0upd.cc
@@ -1149,7 +1149,7 @@ row_upd_build_difference_binary(
dfield_t* vfield = innobase_get_computed_value(
update->old_vrow, col, index,
&vc.heap, heap, NULL, thd, mysql_table, record,
- NULL, NULL, NULL);
+ NULL, NULL);
if (vfield == NULL) {
*error = DB_COMPUTE_VALUE_FAILED;
return(NULL);
@@ -2175,8 +2175,7 @@ row_upd_store_v_row(
node->row, col, index,
&vc.heap, node->heap,
NULL, thd, mysql_table,
- record, NULL, NULL,
- NULL);
+ record, NULL, NULL);
if (vfield == NULL) {
return false;
}
diff --git a/storage/innobase/row/row0vers.cc b/storage/innobase/row/row0vers.cc
index b9bc8418366..bf229966525 100644
--- a/storage/innobase/row/row0vers.cc
+++ b/storage/innobase/row/row0vers.cc
@@ -491,7 +491,7 @@ row_vers_build_clust_v_col(
dfield_t *vfield = innobase_get_computed_value(
row, col, clust_index, &vc.heap,
heap, NULL, thd, maria_table, record, NULL,
- NULL, NULL);
+ NULL);
if (vfield == NULL) {
innobase_report_computed_value_failed(row);
ut_ad(0);