Skip to content

Commit

Permalink
MDEV-26778 row_start is not updated in current row for InnoDB
Browse files Browse the repository at this point in the history
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 3789692. 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.
  • Loading branch information
midenok committed Jan 13, 2022
1 parent 7c61fb2 commit 241ac79
Show file tree
Hide file tree
Showing 4 changed files with 32 additions and 4 deletions.
11 changes: 11 additions & 0 deletions mysql-test/suite/versioning/r/update.result
Original file line number Diff line number Diff line change
Expand Up @@ -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;
10 changes: 10 additions & 0 deletions mysql-test/suite/versioning/t/update.test
Original file line number Diff line number Diff line change
Expand Up @@ -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;
13 changes: 9 additions & 4 deletions sql/table.cc
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand All @@ -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();
}

/**
Expand Down
2 changes: 2 additions & 0 deletions sql/table.h
Original file line number Diff line number Diff line change
Expand Up @@ -1665,7 +1665,9 @@ struct TABLE
bool vers_check_update(List<Item> &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 */
Expand Down

0 comments on commit 241ac79

Please sign in to comment.