diff --git a/mysql-test/suite/innodb/r/instant_alter_debug.result b/mysql-test/suite/innodb/r/instant_alter_debug.result index 3c0a1600029..72e42763569 100644 --- a/mysql-test/suite/innodb/r/instant_alter_debug.result +++ b/mysql-test/suite/innodb/r/instant_alter_debug.result @@ -205,12 +205,35 @@ INSERT INTO t1 SET a=1; INSERT INTO t1 SET a=2,b=3,c=4; SET DEBUG_SYNC = 'now SIGNAL logged'; connection ddl; -disconnect ddl; connection default; SET DEBUG_SYNC = RESET; SELECT * FROM t1; a b c 1 2 NULL 2 3 4 +# +# MDEV-15872 Crash in online ALTER TABLE...ADD PRIMARY KEY +# after instant ADD COLUMN ... NULL +# +ALTER TABLE t1 ADD COLUMN d INT, ALGORITHM=INSTANT; +UPDATE t1 SET d=1; +connection ddl; +SET DEBUG_SYNC='row_log_table_apply1_before SIGNAL copied WAIT_FOR logged'; +ALTER IGNORE TABLE t1 DROP PRIMARY KEY, ADD PRIMARY KEY (a,d); +connection default; +SET DEBUG_SYNC = 'now WAIT_FOR copied'; +BEGIN; +INSERT INTO t1 SET a=3; +ROLLBACK; +SET DEBUG_SYNC = 'now SIGNAL logged'; +connection ddl; +ERROR 22004: Invalid use of NULL value +disconnect ddl; +connection default; +SET DEBUG_SYNC = RESET; +SELECT * FROM t1; +a b c d +1 2 NULL 1 +2 3 4 1 DROP TABLE t1; SET GLOBAL innodb_purge_rseg_truncate_frequency = @save_frequency; diff --git a/mysql-test/suite/innodb/t/instant_alter_debug.test b/mysql-test/suite/innodb/t/instant_alter_debug.test index 5a73ed65d72..cab9decd3d0 100644 --- a/mysql-test/suite/innodb/t/instant_alter_debug.test +++ b/mysql-test/suite/innodb/t/instant_alter_debug.test @@ -234,6 +234,32 @@ SET DEBUG_SYNC = 'now SIGNAL logged'; connection ddl; reap; + +connection default; +SET DEBUG_SYNC = RESET; +SELECT * FROM t1; + +--echo # +--echo # MDEV-15872 Crash in online ALTER TABLE...ADD PRIMARY KEY +--echo # after instant ADD COLUMN ... NULL +--echo # +ALTER TABLE t1 ADD COLUMN d INT, ALGORITHM=INSTANT; +UPDATE t1 SET d=1; + +connection ddl; +SET DEBUG_SYNC='row_log_table_apply1_before SIGNAL copied WAIT_FOR logged'; +send ALTER IGNORE TABLE t1 DROP PRIMARY KEY, ADD PRIMARY KEY (a,d); + +connection default; +SET DEBUG_SYNC = 'now WAIT_FOR copied'; +BEGIN; +INSERT INTO t1 SET a=3; +ROLLBACK; +SET DEBUG_SYNC = 'now SIGNAL logged'; + +connection ddl; +--error ER_INVALID_USE_OF_NULL +reap; disconnect ddl; connection default; diff --git a/storage/innobase/row/row0log.cc b/storage/innobase/row/row0log.cc index 386bd2786a0..a6e35744446 100644 --- a/storage/innobase/row/row0log.cc +++ b/storage/innobase/row/row0log.cc @@ -1164,7 +1164,6 @@ row_log_table_get_pk_col( field = rec_get_nth_field(rec, offsets, i, &len); if (len == UNIV_SQL_NULL) { - if (!log->allow_not_null) { return(DB_INVALID_NULL); } @@ -1173,6 +1172,9 @@ row_log_table_get_pk_col( field = static_cast( log->defaults->fields[n_default_cols].data); + if (!field) { + return(DB_INVALID_NULL); + } len = log->defaults->fields[i - DATA_N_SYS_COLS].len; }