summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--mysql-test/suite/innodb/r/alter_table.result10
-rw-r--r--mysql-test/suite/innodb/t/alter_table.test11
-rw-r--r--storage/innobase/btr/btr0bulk.cc4
3 files changed, 24 insertions, 1 deletions
diff --git a/mysql-test/suite/innodb/r/alter_table.result b/mysql-test/suite/innodb/r/alter_table.result
index 0cfd3096f3f..1e7e55494d4 100644
--- a/mysql-test/suite/innodb/r/alter_table.result
+++ b/mysql-test/suite/innodb/r/alter_table.result
@@ -68,3 +68,13 @@ t2 CREATE TABLE `t2` (
alter table t1 engine=innodb;
alter table t1 add column b int;
drop table t1,t2;
+#
+# MDEV-21748 ASAN use-after-poison in PageBulk::insertPage()
+#
+CREATE TABLE t1 (pk TIMESTAMP PRIMARY KEY, a TIMESTAMP NULL UNIQUE)
+ENGINE=InnoDB;
+INSERT INTO t1 VALUES
+('2020-03-10 10:21:00', NULL),
+('0000-00-00 00:00:00', '0000-00-00 00:00:00');
+ALTER TABLE t1 FORCE, ALGORITHM=INPLACE;
+DROP TABLE t1;
diff --git a/mysql-test/suite/innodb/t/alter_table.test b/mysql-test/suite/innodb/t/alter_table.test
index a8b52732c91..4827e3440e1 100644
--- a/mysql-test/suite/innodb/t/alter_table.test
+++ b/mysql-test/suite/innodb/t/alter_table.test
@@ -71,3 +71,14 @@ show create table t2;
alter table t1 engine=innodb;
alter table t1 add column b int;
drop table t1,t2;
+
+--echo #
+--echo # MDEV-21748 ASAN use-after-poison in PageBulk::insertPage()
+--echo #
+CREATE TABLE t1 (pk TIMESTAMP PRIMARY KEY, a TIMESTAMP NULL UNIQUE)
+ENGINE=InnoDB;
+INSERT INTO t1 VALUES
+ ('2020-03-10 10:21:00', NULL),
+ ('0000-00-00 00:00:00', '0000-00-00 00:00:00');
+ALTER TABLE t1 FORCE, ALGORITHM=INPLACE;
+DROP TABLE t1;
diff --git a/storage/innobase/btr/btr0bulk.cc b/storage/innobase/btr/btr0bulk.cc
index aeeb5850713..1171de544a7 100644
--- a/storage/innobase/btr/btr0bulk.cc
+++ b/storage/innobase/btr/btr0bulk.cc
@@ -270,9 +270,11 @@ no_data:
byte *bd= insert_rec;
const byte *rd= rec;
/* Skip any unchanged prefix of the record. */
- for (; *bd == *rd; cd++, bd++, rd++)
+ for (;; cd++, bd++, rd++)
if (bd == insert_rec_end)
goto no_data;
+ else if (*bd != *rd)
+ break;
/* Try to copy any data bytes of the preceding record. */
if (c_end - cd > 2)