summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSergei Golubchik <serg@mariadb.org>2022-07-15 09:08:52 +0200
committerNikita Malyavin <nikitamalyavin@gmail.com>2023-04-18 00:29:50 +0300
commita7536d2c4504c03a79f69017d00bf8d1b6234589 (patch)
tree313e109e17d2b41795b8ab6a06c67fe60073651e
parent1733f22cbf4851b787ceb4bc06bb7a1d9587d177 (diff)
downloadmariadb-git-a7536d2c4504c03a79f69017d00bf8d1b6234589.tar.gz
MDEV-29067 Online alter ignores check constraint violation
-rw-r--r--mysql-test/main/alter_table_online_debug.result138
-rw-r--r--mysql-test/main/alter_table_online_debug.test104
-rw-r--r--sql/rpl_record.cc6
3 files changed, 248 insertions, 0 deletions
diff --git a/mysql-test/main/alter_table_online_debug.result b/mysql-test/main/alter_table_online_debug.result
index ccbee5ea478..4d5992e2e99 100644
--- a/mysql-test/main/alter_table_online_debug.result
+++ b/mysql-test/main/alter_table_online_debug.result
@@ -578,6 +578,39 @@ set debug_sync= 'reset';
drop table t1;
drop table t2;
drop table t3;
+create table t1 (a char(6), b int) engine=innodb;
+insert t1 values ('abcde1',1),('abcde2',2);
+set debug_sync= 'now wait_for downgraded';
+connection con2;
+set sql_mode='';
+set debug_sync= 'alter_table_online_downgraded signal downgraded wait_for goforit';
+alter table t1 modify a char(4), algorithm=copy, lock=none;
+connection default;
+update t1 set b=b+10 where a='abcde2';
+select * from t1;
+a b
+abcde1 1
+abcde2 12
+set debug_sync= 'now signal goforit';
+connection con2;
+Warnings:
+Warning 1265 Data truncated for column 'a' at row 1
+Warning 1265 Data truncated for column 'a' at row 2
+Warning 1265 Data truncated for column 'a' at row 3
+set sql_mode=default;
+connection default;
+show create table t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `a` char(4) DEFAULT NULL,
+ `b` int(11) DEFAULT NULL
+) ENGINE=InnoDB DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci
+select * from t1;
+a b
+abcd 1
+abcd 12
+drop table t1;
+set debug_sync= 'reset';
#
# MDEV-28930 ALTER TABLE Deadlocks with parallel TL_WRITE
#
@@ -747,5 +780,110 @@ connection default;
drop table t1;
set debug_sync= reset;
#
+# MDEV-29067 Online alter ignores check constraint violation
+#
+## CHECK, INSERT
+create table t1 (a int);
+insert t1 values (1),(2);
+set debug_sync= 'now wait_for downgraded';
+connection con2;
+set debug_sync= 'alter_table_online_downgraded signal downgraded wait_for goforit';
+alter table t1 add check (a<10), algorithm=copy, lock=none;
+connection default;
+insert t1 values (11),(12);
+set debug_sync= 'now signal goforit';
+connection con2;
+ERROR 23000: CONSTRAINT `CONSTRAINT_1` failed for `test`.`t1`
+connection default;
+show create table t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `a` int(11) DEFAULT NULL
+) ENGINE=InnoDB DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci
+select * from t1;
+a
+1
+2
+11
+12
+drop table t1;
+## DEFAULT, INSERT
+create table t1 (a int);
+insert t1 values (1),(2);
+set debug_sync= 'now wait_for downgraded';
+connection con2;
+set debug_sync= 'alter_table_online_downgraded signal downgraded wait_for goforit';
+alter table t1 add b int default(a+10), algorithm=copy, lock=none;
+connection default;
+insert t1 values (11),(12);
+set debug_sync= 'now signal goforit';
+connection con2;
+connection default;
+show create table t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `a` int(11) DEFAULT NULL,
+ `b` int(11) DEFAULT (`a` + 10)
+) ENGINE=InnoDB DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci
+select * from t1;
+a b
+1 11
+2 12
+11 21
+12 22
+drop table t1;
+set debug_sync= 'reset';
+## CHECK, UPDATE
+create table t1 (a int) engine=innodb;
+insert t1 values (1),(2),(3),(4);
+set debug_sync= 'now wait_for downgraded';
+connection con2;
+set debug_sync= 'alter_table_online_downgraded signal downgraded wait_for goforit';
+alter table t1 add check (a<10), algorithm=copy, lock=none;
+connection default;
+update t1 set a=a+10 where a > 2;
+set debug_sync= 'now signal goforit';
+connection con2;
+ERROR 23000: CONSTRAINT `CONSTRAINT_1` failed for `test`.`t1`
+connection default;
+show create table t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `a` int(11) DEFAULT NULL
+) ENGINE=InnoDB DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci
+select * from t1;
+a
+1
+2
+13
+14
+drop table t1;
+## DEFAULT, UPDATE
+create table t1 (a int) engine=innodb;
+insert t1 values (1),(2),(3),(4);
+set debug_sync= 'now wait_for downgraded';
+connection con2;
+set debug_sync= 'alter_table_online_downgraded signal downgraded wait_for goforit';
+alter table t1 add b int default(a+10), algorithm=copy, lock=none;
+connection default;
+update t1 set a=a+10 where a > 2;
+set debug_sync= 'now signal goforit';
+connection con2;
+connection default;
+show create table t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `a` int(11) DEFAULT NULL,
+ `b` int(11) DEFAULT (`a` + 10)
+) ENGINE=InnoDB DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci
+select * from t1;
+a b
+1 11
+2 12
+13 23
+14 24
+drop table t1;
+set debug_sync= 'reset';
+#
# End of 10.10 tests
#
diff --git a/mysql-test/main/alter_table_online_debug.test b/mysql-test/main/alter_table_online_debug.test
index 858b56e53eb..7cc6279044c 100644
--- a/mysql-test/main/alter_table_online_debug.test
+++ b/mysql-test/main/alter_table_online_debug.test
@@ -717,6 +717,30 @@ drop table t1;
drop table t2;
drop table t3;
+#
+# Lossy alter, Update_row_log_event cannot find 'abcde2' in the new table
+#
+create table t1 (a char(6), b int) engine=innodb;
+insert t1 values ('abcde1',1),('abcde2',2);
+--send set debug_sync= 'now wait_for downgraded'
+--connection con2
+set sql_mode='';
+set debug_sync= 'alter_table_online_downgraded signal downgraded wait_for goforit';
+--send alter table t1 modify a char(4), algorithm=copy, lock=none
+--connection default
+--reap
+update t1 set b=b+10 where a='abcde2';
+select * from t1;
+set debug_sync= 'now signal goforit';
+--connection con2
+--reap
+set sql_mode=default;
+--connection default
+show create table t1;
+select * from t1;
+drop table t1;
+set debug_sync= 'reset';
+
--echo #
--echo # MDEV-28930 ALTER TABLE Deadlocks with parallel TL_WRITE
--echo #
@@ -931,5 +955,85 @@ drop table t1;
set debug_sync= reset;
--echo #
+--echo # MDEV-29067 Online alter ignores check constraint violation
+--echo #
+
+--echo ## CHECK, INSERT
+create table t1 (a int);
+insert t1 values (1),(2);
+--send set debug_sync= 'now wait_for downgraded'
+--connection con2
+set debug_sync= 'alter_table_online_downgraded signal downgraded wait_for goforit';
+--send alter table t1 add check (a<10), algorithm=copy, lock=none
+--connection default
+--reap
+insert t1 values (11),(12);
+set debug_sync= 'now signal goforit';
+--connection con2
+--error ER_CONSTRAINT_FAILED
+--reap
+--connection default
+show create table t1;
+select * from t1;
+drop table t1;
+
+--echo ## DEFAULT, INSERT
+create table t1 (a int);
+insert t1 values (1),(2);
+--send set debug_sync= 'now wait_for downgraded'
+--connection con2
+set debug_sync= 'alter_table_online_downgraded signal downgraded wait_for goforit';
+--send alter table t1 add b int default(a+10), algorithm=copy, lock=none
+--connection default
+--reap
+insert t1 values (11),(12);
+set debug_sync= 'now signal goforit';
+--connection con2
+--reap
+--connection default
+show create table t1;
+select * from t1;
+drop table t1;
+set debug_sync= 'reset';
+
+--echo ## CHECK, UPDATE
+create table t1 (a int) engine=innodb;
+insert t1 values (1),(2),(3),(4);
+--send set debug_sync= 'now wait_for downgraded'
+--connection con2
+set debug_sync= 'alter_table_online_downgraded signal downgraded wait_for goforit';
+--send alter table t1 add check (a<10), algorithm=copy, lock=none
+--connection default
+--reap
+update t1 set a=a+10 where a > 2;
+set debug_sync= 'now signal goforit';
+--connection con2
+--error ER_CONSTRAINT_FAILED
+--reap
+--connection default
+show create table t1;
+select * from t1;
+drop table t1;
+
+--echo ## DEFAULT, UPDATE
+create table t1 (a int) engine=innodb;
+insert t1 values (1),(2),(3),(4);
+--send set debug_sync= 'now wait_for downgraded'
+--connection con2
+set debug_sync= 'alter_table_online_downgraded signal downgraded wait_for goforit';
+--send alter table t1 add b int default(a+10), algorithm=copy, lock=none
+--connection default
+--reap
+update t1 set a=a+10 where a > 2;
+set debug_sync= 'now signal goforit';
+--connection con2
+--reap
+--connection default
+show create table t1;
+select * from t1;
+drop table t1;
+set debug_sync= 'reset';
+
+--echo #
--echo # End of 10.10 tests
--echo #
diff --git a/sql/rpl_record.cc b/sql/rpl_record.cc
index d6e22474de5..1dfb00046f3 100644
--- a/sql/rpl_record.cc
+++ b/sql/rpl_record.cc
@@ -387,6 +387,12 @@ int unpack_row(rpl_group_info *rgi, TABLE *table, uint const colcnt,
{
copy->do_copy(copy);
}
+ /* we only check constraints for ALTER TABLE */
+ DBUG_ASSERT(table->in_use->lex->ignore == FALSE);
+ error= table->verify_constraints(false);
+ DBUG_ASSERT(error != VIEW_CHECK_SKIP);
+ if (error)
+ DBUG_RETURN(HA_ERR_GENERIC);
}
if (table->default_field)