From 706a8bcb5b128c30ea59bae5ad940541918aaf21 Mon Sep 17 00:00:00 2001 From: Aleksey Midenkov Date: Tue, 8 Oct 2024 13:08:10 +0300 Subject: [PATCH] MDEV-33470 Unique hash index is broken on DML for system-versioned table Hash index is vcol-based wrapper (MDEV-371). row_end is added to unique index. So when row_end is updated unique hash index must be recalculated via vcol_update_fields(). DELETE did not update virtual fields, so DELETE HISTORY was getting wrong hash value. The fix does update_virtual_fields() on vers_update_end() so in every case row_end is updated virtual fields are updated as well. --- mysql-test/suite/versioning/r/delete_history.result | 11 +++++++++++ mysql-test/suite/versioning/t/delete_history.test | 13 +++++++++++++ sql/sql_insert.cc | 4 ---- sql/table.cc | 2 ++ 4 files changed, 26 insertions(+), 4 deletions(-) diff --git a/mysql-test/suite/versioning/r/delete_history.result b/mysql-test/suite/versioning/r/delete_history.result index d07c71ee9f5..5b279b12f33 100644 --- a/mysql-test/suite/versioning/r/delete_history.result +++ b/mysql-test/suite/versioning/r/delete_history.result @@ -224,3 +224,14 @@ ERROR HY000: The target table v1 of the DELETE is not updatable DROP VIEW v1; DROP TABLE t1; # End of 10.4 tests +# +# MDEV-33470 Unique hash index is broken on DML for system-versioned table +# +create or replace table t ( +c int, unique (c) using hash) +with system versioning; +insert into t values (0); +delete from t; +delete history from t; +drop table t; +# End of 10.5 tests diff --git a/mysql-test/suite/versioning/t/delete_history.test b/mysql-test/suite/versioning/t/delete_history.test index 042670bcfec..7e051ac4be3 100644 --- a/mysql-test/suite/versioning/t/delete_history.test +++ b/mysql-test/suite/versioning/t/delete_history.test @@ -232,4 +232,17 @@ DROP TABLE t1; --echo # End of 10.4 tests +--echo # +--echo # MDEV-33470 Unique hash index is broken on DML for system-versioned table +--echo # +create or replace table t ( + c int, unique (c) using hash) +with system versioning; +insert into t values (0); +delete from t; +delete history from t; +drop table t; + +--echo # End of 10.5 tests + --source suite/versioning/common_finish.inc diff --git a/sql/sql_insert.cc b/sql/sql_insert.cc index a189d1da86e..a66b0579f4a 100644 --- a/sql/sql_insert.cc +++ b/sql/sql_insert.cc @@ -1810,10 +1810,6 @@ 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 f0020deb519..31a5afdb125 100644 --- a/sql/table.cc +++ b/sql/table.cc @@ -9078,6 +9078,8 @@ void TABLE::vers_update_end() in_use->query_start_sec_part())) DBUG_ASSERT(0); vers_end_field()->set_has_explicit_value(); + if (vfield) + update_virtual_fields(file, VCOL_UPDATE_FOR_WRITE); } /**