Commit 021652ba authored by Marko Mäkelä's avatar Marko Mäkelä

MDEV-15872 Crash in online ALTER TABLE...ADD PRIMARY KEY after instant ADD COLUMN...NULL

row_log_table_get_pk_col(): Replace a condition that was inadvertently
removed in MDEV-16365. PRIMARY KEY columns are never allowed to be NULL,
and failure to enforce the constraint caused a null pointer to be
dereferenced in mem_heap_dup().
parent e10ca66b
...@@ -205,12 +205,35 @@ INSERT INTO t1 SET a=1; ...@@ -205,12 +205,35 @@ INSERT INTO t1 SET a=1;
INSERT INTO t1 SET a=2,b=3,c=4; INSERT INTO t1 SET a=2,b=3,c=4;
SET DEBUG_SYNC = 'now SIGNAL logged'; SET DEBUG_SYNC = 'now SIGNAL logged';
connection ddl; connection ddl;
disconnect ddl;
connection default; connection default;
SET DEBUG_SYNC = RESET; SET DEBUG_SYNC = RESET;
SELECT * FROM t1; SELECT * FROM t1;
a b c a b c
1 2 NULL 1 2 NULL
2 3 4 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; DROP TABLE t1;
SET GLOBAL innodb_purge_rseg_truncate_frequency = @save_frequency; SET GLOBAL innodb_purge_rseg_truncate_frequency = @save_frequency;
...@@ -234,6 +234,32 @@ SET DEBUG_SYNC = 'now SIGNAL logged'; ...@@ -234,6 +234,32 @@ SET DEBUG_SYNC = 'now SIGNAL logged';
connection ddl; connection ddl;
reap; 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; disconnect ddl;
connection default; connection default;
......
...@@ -1164,7 +1164,6 @@ row_log_table_get_pk_col( ...@@ -1164,7 +1164,6 @@ row_log_table_get_pk_col(
field = rec_get_nth_field(rec, offsets, i, &len); field = rec_get_nth_field(rec, offsets, i, &len);
if (len == UNIV_SQL_NULL) { if (len == UNIV_SQL_NULL) {
if (!log->allow_not_null) { if (!log->allow_not_null) {
return(DB_INVALID_NULL); return(DB_INVALID_NULL);
} }
...@@ -1173,6 +1172,9 @@ row_log_table_get_pk_col( ...@@ -1173,6 +1172,9 @@ row_log_table_get_pk_col(
field = static_cast<const byte*>( field = static_cast<const byte*>(
log->defaults->fields[n_default_cols].data); log->defaults->fields[n_default_cols].data);
if (!field) {
return(DB_INVALID_NULL);
}
len = log->defaults->fields[i - DATA_N_SYS_COLS].len; len = log->defaults->fields[i - DATA_N_SYS_COLS].len;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment