diff options
-rw-r--r-- | mysql-test/suite/gcol/r/innodb_virtual_index.result | 32 | ||||
-rw-r--r-- | mysql-test/suite/gcol/t/innodb_virtual_index.test | 31 | ||||
-rw-r--r-- | storage/innobase/row/row0row.cc | 4 | ||||
-rw-r--r-- | storage/innobase/row/row0upd.cc | 2 |
4 files changed, 67 insertions, 2 deletions
diff --git a/mysql-test/suite/gcol/r/innodb_virtual_index.result b/mysql-test/suite/gcol/r/innodb_virtual_index.result index a1faac8e1e8..1e3b4127f8f 100644 --- a/mysql-test/suite/gcol/r/innodb_virtual_index.result +++ b/mysql-test/suite/gcol/r/innodb_virtual_index.result @@ -211,3 +211,35 @@ t1 CREATE TABLE `t1` ( KEY `n` (`col2`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 DROP TABLE t1; +# +# Bug #27968952 INNODB CRASH/CORRUPTION WITH TEXT PREFIX INDEXES +# +CREATE TABLE t1( +a INT NOT NULL UNIQUE, +b INT NOT NULL, +c TEXT GENERATED ALWAYS AS (a <> b) VIRTUAL, +d TEXT NOT NULL, +UNIQUE KEY (c(1)), KEY(d(1)) +) ENGINE=InnoDB ROW_FORMAT=DYNAMIC; +SET @t = REPEAT('t',@@innodb_page_size); +INSERT INTO t1 (a,b,d) VALUES (1,0,@t), (0,0,@t); +UPDATE t1 SET b = a; +ERROR 23000: Duplicate entry '0' for key 'c' +REPLACE INTO t1 SET a = 0, b = 1, d = 'd'; +SELECT * FROM t1; +a b c d +0 1 1 d +CHECK TABLE t1; +Table Op Msg_type Msg_text +test.t1 check status OK +DROP TABLE t1; +CREATE TABLE t1( +a VARCHAR(1000) GENERATED ALWAYS AS ('1') VIRTUAL, +b VARCHAR(1000) NOT NULL, +c VARCHAR(1000) GENERATED ALWAYS AS (b) STORED, +KEY (b(1)), +KEY (a(1)) +) ENGINE=InnoDB ROW_FORMAT=COMPRESSED KEY_BLOCK_SIZE=1; +INSERT INTO t1(b) VALUES(REPEAT('b',1000)); +DELETE FROM t1; +DROP TABLE t1; diff --git a/mysql-test/suite/gcol/t/innodb_virtual_index.test b/mysql-test/suite/gcol/t/innodb_virtual_index.test index 6604a6d94f4..8f4e09fdf31 100644 --- a/mysql-test/suite/gcol/t/innodb_virtual_index.test +++ b/mysql-test/suite/gcol/t/innodb_virtual_index.test @@ -232,3 +232,34 @@ CREATE TABLE t1 (col1 int(10)) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; ALTER TABLE t1 ADD col2 char(21) AS (col1 * col1), ADD INDEX n (col2); SHOW CREATE TABLE t1; DROP TABLE t1; + +--echo # +--echo # Bug #27968952 INNODB CRASH/CORRUPTION WITH TEXT PREFIX INDEXES +--echo # + +CREATE TABLE t1( + a INT NOT NULL UNIQUE, + b INT NOT NULL, + c TEXT GENERATED ALWAYS AS (a <> b) VIRTUAL, + d TEXT NOT NULL, + UNIQUE KEY (c(1)), KEY(d(1)) +) ENGINE=InnoDB ROW_FORMAT=DYNAMIC; +SET @t = REPEAT('t',@@innodb_page_size); +INSERT INTO t1 (a,b,d) VALUES (1,0,@t), (0,0,@t); +--error ER_DUP_ENTRY +UPDATE t1 SET b = a; +REPLACE INTO t1 SET a = 0, b = 1, d = 'd'; +SELECT * FROM t1; +CHECK TABLE t1; +DROP TABLE t1; + +CREATE TABLE t1( + a VARCHAR(1000) GENERATED ALWAYS AS ('1') VIRTUAL, + b VARCHAR(1000) NOT NULL, + c VARCHAR(1000) GENERATED ALWAYS AS (b) STORED, + KEY (b(1)), + KEY (a(1)) +) ENGINE=InnoDB ROW_FORMAT=COMPRESSED KEY_BLOCK_SIZE=1; +INSERT INTO t1(b) VALUES(REPEAT('b',1000)); +DELETE FROM t1; +DROP TABLE t1; diff --git a/storage/innobase/row/row0row.cc b/storage/innobase/row/row0row.cc index ad4991fb4e9..4c88130334e 100644 --- a/storage/innobase/row/row0row.cc +++ b/storage/innobase/row/row0row.cc @@ -1,6 +1,6 @@ /***************************************************************************** -Copyright (c) 1996, 2016, Oracle and/or its affiliates. All Rights Reserved. +Copyright (c) 1996, 2018, Oracle and/or its affiliates. All Rights Reserved. Copyright (c) 2018, MariaDB Corporation. This program is free software; you can redistribute it and/or modify it under @@ -295,7 +295,7 @@ row_build_index_entry_low( stored off-page. */ ut_ad(col->ord_part); - if (ext) { + if (ext && !col->is_virtual()) { /* See if the column is stored externally. */ const byte* buf = row_ext_lookup(ext, col_no, &len); diff --git a/storage/innobase/row/row0upd.cc b/storage/innobase/row/row0upd.cc index 171e06894ca..28658428e98 100644 --- a/storage/innobase/row/row0upd.cc +++ b/storage/innobase/row/row0upd.cc @@ -2157,6 +2157,7 @@ row_upd_store_v_row( } dfield_copy_data(dfield, upd_field->old_v_val); + dfield_dup(dfield, node->heap); break; } @@ -2177,6 +2178,7 @@ row_upd_store_v_row( update->old_vrow, col_no); dfield_copy_data(dfield, vfield); + dfield_dup(dfield, node->heap); } } else { /* Need to compute, this happens when |