diff --git a/mysql-test/suite/gcol/r/innodb_virtual_purge.result b/mysql-test/suite/gcol/r/innodb_virtual_purge.result index ee88527ec2e..82f3523428c 100644 --- a/mysql-test/suite/gcol/r/innodb_virtual_purge.result +++ b/mysql-test/suite/gcol/r/innodb_virtual_purge.result @@ -159,4 +159,18 @@ UNIQUE(pk), KEY(e) ) ENGINE=InnoDB; DROP TABLE t1, t2; +# +# MDEV-30024 InnoDB: tried to purge non-delete-marked record +# of an index on a virtual column prefix +# +CREATE TABLE t(a BINARY(8), b CHAR(8) AS (a) VIRTUAL, KEY(b(4))) +CHARACTER SET utf8 ENGINE=InnoDB; +INSERT INTO t (a) VALUES (''),(''); +UPDATE t SET a = 'x'; +UPDATE t SET a = ''; +SET GLOBAL innodb_max_purge_lag_wait=0; +CHECK TABLE t EXTENDED; +Table Op Msg_type Msg_text +test.t check status OK +DROP TABLE t; SET GLOBAL innodb_purge_rseg_truncate_frequency = @saved_frequency; diff --git a/mysql-test/suite/gcol/t/innodb_virtual_purge.test b/mysql-test/suite/gcol/t/innodb_virtual_purge.test index c79a817dd4e..49ec48c1c64 100644 --- a/mysql-test/suite/gcol/t/innodb_virtual_purge.test +++ b/mysql-test/suite/gcol/t/innodb_virtual_purge.test @@ -172,5 +172,19 @@ dec $n; DROP TABLE t1, t2; +--echo # +--echo # MDEV-30024 InnoDB: tried to purge non-delete-marked record +--echo # of an index on a virtual column prefix +--echo # + +CREATE TABLE t(a BINARY(8), b CHAR(8) AS (a) VIRTUAL, KEY(b(4))) +CHARACTER SET utf8 ENGINE=InnoDB; +INSERT INTO t (a) VALUES (''),(''); +UPDATE t SET a = 'x'; +UPDATE t SET a = ''; +SET GLOBAL innodb_max_purge_lag_wait=0; +CHECK TABLE t EXTENDED; +DROP TABLE t; + --source include/wait_until_count_sessions.inc SET GLOBAL innodb_purge_rseg_truncate_frequency = @saved_frequency; diff --git a/storage/innobase/row/row0vers.cc b/storage/innobase/row/row0vers.cc index 9d2e6654c46..1a156ed997c 100644 --- a/storage/innobase/row/row0vers.cc +++ b/storage/innobase/row/row0vers.cc @@ -739,9 +739,16 @@ row_vers_vc_matches_cluster( && (!compare[v_col->v_pos])) { if (ind_field->prefix_len != 0 - && !dfield_is_null(field2) - && field2->len > ind_field->prefix_len) { - field2->len = ind_field->prefix_len; + && !dfield_is_null(field2)) { + field2->len = unsigned( + dtype_get_at_most_n_mbchars( + field2->type.prtype, + field2->type.mbminlen, + field2->type.mbmaxlen, + ind_field->prefix_len, + field2->len, + static_cast + (field2->data))); } /* The index field mismatch */