From 241ac79e4994013ed3a9e847f0ac72dc1e3722b2 Mon Sep 17 00:00:00 2001 From: Aleksey Midenkov Date: Thu, 13 Jan 2022 23:35:17 +0300 Subject: [PATCH] MDEV-26778 row_start is not updated in current row for InnoDB Update was skipped (need_update was false) because compare_record() used HA_PARTIAL_COLUMN_READ branch and it skipped row_start check has_explicit_value() was false. When we set bit for row_start in has_value_set the row is updated with new row_start value. The bug was caused by combination of MDEV-23446 and 3789692d176. The latter one says: ... But generated columns that are written to the table are always deterministic and cannot change unless normal non-generated columns were changed. ... Since MDEV-23446 generated row_start can change while non-generated columns are not changed. Explicit value flag came from HAS_EXPLICIT_DEFAULT which was used to distinguish default-generated value from user-supplied one. --- mysql-test/suite/versioning/r/update.result | 11 +++++++++++ mysql-test/suite/versioning/t/update.test | 10 ++++++++++ sql/table.cc | 13 +++++++++---- sql/table.h | 2 ++ 4 files changed, 32 insertions(+), 4 deletions(-) diff --git a/mysql-test/suite/versioning/r/update.result b/mysql-test/suite/versioning/r/update.result index fbb9f541b06..d123331cc8c 100644 --- a/mysql-test/suite/versioning/r/update.result +++ b/mysql-test/suite/versioning/r/update.result @@ -399,3 +399,14 @@ a check_row(row_start, row_end) 1 HISTORICAL ROW 1 CURRENT ROW drop tables t1, t2, t3; +# +# MDEV-26778 row_start is not updated in current row for InnoDB +# +create or replace table t1 (x int) with system versioning; +insert t1 values (1); +update t1 set x= 1; +select row_start from t1 into @r; +select check_row_ts(row_start, row_end) from t1 for system_time all where row_start = @r; +check_row_ts(row_start, row_end) +CURRENT ROW +drop table t1; diff --git a/mysql-test/suite/versioning/t/update.test b/mysql-test/suite/versioning/t/update.test index 7f99e307942..058d2f4c865 100644 --- a/mysql-test/suite/versioning/t/update.test +++ b/mysql-test/suite/versioning/t/update.test @@ -326,4 +326,14 @@ select *, check_row(row_start, row_end) from t2 for system_time all order by row # cleanup drop tables t1, t2, t3; +--echo # +--echo # MDEV-26778 row_start is not updated in current row for InnoDB +--echo # +create or replace table t1 (x int) with system versioning; +insert t1 values (1); +update t1 set x= 1; +select row_start from t1 into @r; +select check_row_ts(row_start, row_end) from t1 for system_time all where row_start = @r; +drop table t1; + source suite/versioning/common_finish.inc; diff --git a/sql/table.cc b/sql/table.cc index ccc336962b6..130753be209 100644 --- a/sql/table.cc +++ b/sql/table.cc @@ -8147,14 +8147,18 @@ void TABLE::vers_update_fields() return; } - if (versioned(VERS_TIMESTAMP) && - vers_start_field()->store_timestamp(in_use->query_start(), - in_use->query_start_sec_part())) + if (versioned(VERS_TIMESTAMP)) { - DBUG_ASSERT(0); + if (vers_start_field()->store_timestamp(in_use->query_start(), + in_use->query_start_sec_part())) + { + DBUG_ASSERT(0); + } + vers_start_field()->set_has_explicit_value(); } vers_end_field()->set_max(); + vers_end_field()->set_has_explicit_value(); bitmap_set_bit(read_set, vers_end_field()->field_index); file->column_bitmaps_signal(); if (vfield) @@ -8167,6 +8171,7 @@ void TABLE::vers_update_end() if (vers_end_field()->store_timestamp(in_use->query_start(), in_use->query_start_sec_part())) DBUG_ASSERT(0); + vers_end_field()->set_has_explicit_value(); } /** diff --git a/sql/table.h b/sql/table.h index 8e036e5a8ab..21e89a2943e 100644 --- a/sql/table.h +++ b/sql/table.h @@ -1665,7 +1665,9 @@ public: bool vers_check_update(List &items); int delete_row(); + /* Used in majority of DML (called from fill_record()) */ void vers_update_fields(); + /* Used in DELETE, DUP REPLACE and insert history row */ void vers_update_end(); /** Number of additional fields used in versioned tables */