summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAleksey Midenkov <midenok@gmail.com>2020-06-06 10:44:32 +0300
committerAleksey Midenkov <midenok@gmail.com>2020-06-07 13:25:52 +0300
commitffecaa0c77e93573b2c2205c66710cc3a359993b (patch)
treefc51f7f4330086acd51288d643256eeaac828a20
parent95ac7902969d31550768007b3062013db175d8cf (diff)
downloadmariadb-git-bb-10.4-midenok2.tar.gz
MDEV-20661 Virtual fields are not recalculated on system fields value assignmentbb-10.4-midenok2
-rw-r--r--sql/sql_insert.cc4
-rw-r--r--sql/table.cc28
-rw-r--r--storage/innobase/include/row0upd.h22
-rw-r--r--storage/innobase/row/row0mysql.cc23
-rw-r--r--storage/innobase/row/row0upd.cc16
5 files changed, 77 insertions, 16 deletions
diff --git a/sql/sql_insert.cc b/sql/sql_insert.cc
index 807dd94c6f0..8d0e08d8c8c 100644
--- a/sql/sql_insert.cc
+++ b/sql/sql_insert.cc
@@ -1682,6 +1682,10 @@ int vers_insert_history_row(TABLE *table)
if (row_start->cmp(row_start->ptr, row_end->ptr) >= 0)
return 0;
+ if (table->vfield &&
+ table->update_virtual_fields(table->file, VCOL_UPDATE_FOR_READ))
+ return HA_ERR_GENERIC;
+
return table->file->ha_write_row(table->record[0]);
}
diff --git a/sql/table.cc b/sql/table.cc
index a4de5d9c930..a6dfa409975 100644
--- a/sql/table.cc
+++ b/sql/table.cc
@@ -8547,29 +8547,27 @@ void TABLE::vers_update_fields()
bitmap_set_bit(write_set, vers_start_field()->field_index);
bitmap_set_bit(write_set, vers_end_field()->field_index);
- if (versioned(VERS_TIMESTAMP))
+ if (!vers_write)
{
- if (!vers_write)
- {
- file->column_bitmaps_signal();
- return;
- }
- if (vers_start_field()->store_timestamp(in_use->query_start(),
- in_use->query_start_sec_part()))
- DBUG_ASSERT(0);
+ file->column_bitmaps_signal();
+ return;
}
- else
+
+ if (versioned(VERS_TIMESTAMP) &&
+ vers_start_field()->store_timestamp(in_use->query_start(),
+ in_use->query_start_sec_part()))
{
- if (!vers_write)
- {
- file->column_bitmaps_signal();
- return;
- }
+ DBUG_ASSERT(0);
}
vers_end_field()->set_max();
bitmap_set_bit(read_set, vers_end_field()->field_index);
file->column_bitmaps_signal();
+ if (vfield &&
+ update_virtual_fields(file, VCOL_UPDATE_FOR_READ))
+ {
+ DBUG_ASSERT(0);
+ }
}
diff --git a/storage/innobase/include/row0upd.h b/storage/innobase/include/row0upd.h
index 677af76c561..a367ae7d3eb 100644
--- a/storage/innobase/include/row0upd.h
+++ b/storage/innobase/include/row0upd.h
@@ -429,6 +429,28 @@ struct upd_t{
fields[n_fields++] = field;
}
+ void remove_element(ulint i)
+ {
+ ut_ad(n_fields > 0);
+ ut_ad(i < n_fields);
+ while (i < n_fields - 1) {
+ fields[i] = fields[i + 1];
+ i++;
+ }
+ n_fields--;
+ }
+
+ bool remove(const ulint field_no)
+ {
+ for (ulint i = 0; i < n_fields; ++i) {
+ if (field_no == fields[i].field_no) {
+ remove_element(i);
+ return true;
+ }
+ }
+ return false;
+ }
+
/** Determine if the given field_no is modified.
@return true if modified, false otherwise. */
bool is_modified(const ulint field_no) const
diff --git a/storage/innobase/row/row0mysql.cc b/storage/innobase/row/row0mysql.cc
index 4a273cd635e..914641aecfd 100644
--- a/storage/innobase/row/row0mysql.cc
+++ b/storage/innobase/row/row0mysql.cc
@@ -69,6 +69,8 @@ Created 9/17/2000 Heikki Tuuri
#include <algorithm>
#include <deque>
#include <vector>
+// FIXME: remove
+#include <table.h>
#ifdef WITH_WSREP
#include "mysql/service_wsrep.h"
@@ -1441,6 +1443,27 @@ row_insert_for_mysql(
set_tuple_col_8(node->row, table->vers_start, trx->id,
node->vers_start_buf);
}
+ dict_index_t* clust_index = dict_table_get_first_index(table);
+ THD *thd= trx->mysql_thd;
+ TABLE *mysql_table = prebuilt->m_mysql_table;
+ mem_heap_t* local_heap = NULL;
+ for (ulint col_no = 0; col_no < dict_table_get_n_v_cols(table);
+ col_no++) {
+
+ const dict_v_col_t* v_col
+ = dict_table_get_nth_v_col(table, col_no);
+ for (ulint i = 0; i < unsigned{v_col->num_base}; i++) {
+ dict_col_t* base_col = v_col->base_col[i];
+ if (base_col->ind == table->vers_end) {
+ innobase_get_computed_value(
+ node->row, v_col, clust_index, &local_heap, table->heap, NULL, thd,
+ mysql_table, mysql_table->record[0], NULL, NULL, NULL);
+ }
+ }
+ }
+ if (local_heap) {
+ mem_heap_free(local_heap);
+ }
}
savept = trx_savept_take(trx);
diff --git a/storage/innobase/row/row0upd.cc b/storage/innobase/row/row0upd.cc
index b7d396bd5cb..41372c324b4 100644
--- a/storage/innobase/row/row0upd.cc
+++ b/storage/innobase/row/row0upd.cc
@@ -3503,5 +3503,19 @@ void upd_node_t::make_versioned_helper(const trx_t* trx, ulint idx)
}
dfield_set_data(&ufield->new_val, update->vers_sys_value, col->len);
-}
+ for (ulint col_no = 0; col_no < dict_table_get_n_v_cols(table);
+ col_no++) {
+ const dict_v_col_t* v_col
+ = dict_table_get_nth_v_col(table, col_no);
+ for (ulint i = 0; i < unsigned{v_col->num_base}; i++) {
+ dict_col_t* base_col = v_col->base_col[i];
+ if (base_col->ind == col->ind) {
+ /* Virtual column depends on system field value which we updated above.
+ Remove it from update vector, so it is recalculated in row_upd_store_v_row() (see !update branch). */
+ update->remove(v_col->v_pos);
+ break;
+ }
+ }
+ }
+}