Uploaded image for project: 'MariaDB Server'
  1. MariaDB Server
  2. MDEV-41720

Stored generated column over row_end is stale in history row after DELETE; vers_update_end() ignores vcol errors

    XMLWordPrintable

Details

    Description

      TABLE::vers_update_end() (sql/table.cc) sets row_end of the history row and recomputes generated columns with update_virtual_fields(VCOL_UPDATE_FOR_WRITE), but:

      1. update_virtual_fields() only computes generated columns in read_set. A stored generated column that depends on row_end but is not in read_set keeps the value of the current row (row_end = max) in the history row written by DELETE.
      2. The return value of update_virtual_fields() is discarded (vers_update_end() is void), so an error in a generated column expression is silently ignored in DELETE, REPLACE and vers_insert_history_row().

      --source include/have_innodb.inc
      create table t1 (id int primary key, x int,
        rs timestamp(6) as row start, re timestamp(6) as row end,
        period for system_time (rs, re),
        v int as (year(re)) stored) engine=innodb with system versioning;
      insert t1 (id, x) values (1, 1), (2, 2), (3, 3);
      delete from t1 where id = 3;
      replace t1 (id, x) values (2, 20);
      select id, x, v, v = year(re) as v_ok
      from t1 for system_time all order by id, re;
      drop table t1;

      Result (10.11 5e25284ed5e, also with the MDEV-39306 patch, PR #5863 961f1155ae9):

      id	x	v	v_ok
      1	1	2038	1
      2	2	2026	1
      2	20	2038	1
      3	3	2038	0

      The history row of the deleted id=3 has v=2038 while year(re)=2026. The history row written by REPLACE (id=2) is correct. With binlog_format=ROW and a full row image the result is correct, since read_set covers all columns then.

      Expected: the stored generated column in the history row is computed from the final row_end, and an error from the computation is returned to the caller.

      Found during review of MDEV-39306 (PR #5863, finding I5); it was left out of that fix as pre-existing. Fixing it means making vers_update_end() return an error and handling it in TABLE::delete_row() and vers_insert_history_row(), and making sure generated columns depending on row_end are in read_set (or are computed regardless of it).

      Attachments

        Issue Links

          Activity

            People

              midenok Aleksey Midenkov
              sanja Oleksandr Byelkin
              Votes:
              0 Vote for this issue
              Watchers:
              1 Start watching this issue

              Dates

                Created:
                Updated:

                Git Integration

                  Error rendering 'com.xiplink.jira.git.jira_git_plugin:git-issue-webpanel'. Please contact your Jira administrators.