diff --git a/mysql-test/main/check_constraint.result b/mysql-test/main/check_constraint.result index e3986dcf75b86..1dd12b69a1b90 100644 --- a/mysql-test/main/check_constraint.result +++ b/mysql-test/main/check_constraint.result @@ -83,7 +83,6 @@ t2 CREATE TABLE `t2` ( CONSTRAINT `CONSTRAINT_1` CHECK (`a` + `b` + `c` < 500) ) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci alter table t2 drop constraint c; -ERROR 42000: Can't DROP CONSTRAINT `c`; check that it exists alter table t2 drop constraint if exists c; Warnings: Note 1091 Can't DROP CONSTRAINT `c`; check that it exists @@ -93,7 +92,7 @@ Table Create Table t2 CREATE TABLE `t2` ( `a` int(11) DEFAULT NULL CHECK (`a` > 10), `b` int(11) DEFAULT NULL CHECK (`b` > 20), - `c` int(11) DEFAULT 0 CHECK (`c` < 10), + `c` int(11) DEFAULT 0, CONSTRAINT `max` CHECK (`a` + `b` < 500), CONSTRAINT `CONSTRAINT_1` CHECK (`a` + `b` + `c` < 500) ) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci @@ -317,6 +316,109 @@ insert t1 (a) values (1); insert t1 (a) values (-1); ERROR 23000: CONSTRAINT `t1.b` failed for `test`.`t1` drop table t1; +# MDEV-30899: Fail to drop CHECK constraint +# +CREATE TABLE t0 (c1 INT CHECK ( c1 > 0 ), +constraint checkme check(c1>3), +constraint checkme2 check (c1<21) ); +show create table t0; +Table Create Table +t0 CREATE TABLE `t0` ( + `c1` int(11) DEFAULT NULL CHECK (`c1` > 0), + CONSTRAINT `checkme` CHECK (`c1` > 3), + CONSTRAINT `checkme2` CHECK (`c1` < 21) +) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci +SELECT * from INFORMATION_SCHEMA.TABLE_CONSTRAINTS WHERE +CONSTRAINT_SCHEMA = 'test'; +CONSTRAINT_CATALOG CONSTRAINT_SCHEMA CONSTRAINT_NAME TABLE_SCHEMA TABLE_NAME CONSTRAINT_TYPE +def test c1 test t0 CHECK +def test checkme test t0 CHECK +def test checkme2 test t0 CHECK +SELECT * from INFORMATION_SCHEMA.CHECK_CONSTRAINTS WHERE +CONSTRAINT_SCHEMA = 'test'; +CONSTRAINT_CATALOG CONSTRAINT_SCHEMA TABLE_NAME CONSTRAINT_NAME CHECK_CLAUSE +def test t0 c1 `c1` > 0 +def test t0 checkme `c1` > 3 +def test t0 checkme2 `c1` < 21 +ALTER TABLE t0 DROP CONSTRAINT c1; +show create table t0; +Table Create Table +t0 CREATE TABLE `t0` ( + `c1` int(11) DEFAULT NULL, + CONSTRAINT `checkme` CHECK (`c1` > 3), + CONSTRAINT `checkme2` CHECK (`c1` < 21) +) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci +SELECT * from INFORMATION_SCHEMA.CHECK_CONSTRAINTS WHERE +CONSTRAINT_SCHEMA = 'test'; +CONSTRAINT_CATALOG CONSTRAINT_SCHEMA TABLE_NAME CONSTRAINT_NAME CHECK_CLAUSE +def test t0 checkme `c1` > 3 +def test t0 checkme2 `c1` < 21 +SELECT * from INFORMATION_SCHEMA.CHECK_CONSTRAINTS WHERE +CONSTRAINT_SCHEMA = 'test'; +CONSTRAINT_CATALOG CONSTRAINT_SCHEMA TABLE_NAME CONSTRAINT_NAME CHECK_CLAUSE +def test t0 checkme `c1` > 3 +def test t0 checkme2 `c1` < 21 +alter table t0 add c2 int check (c2 < 3.14); +show create table t0; +Table Create Table +t0 CREATE TABLE `t0` ( + `c1` int(11) DEFAULT NULL, + `c2` int(11) DEFAULT NULL CHECK (`c2` < 3.14), + CONSTRAINT `checkme` CHECK (`c1` > 3), + CONSTRAINT `checkme2` CHECK (`c1` < 21) +) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci +SELECT * from INFORMATION_SCHEMA.CHECK_CONSTRAINTS WHERE +CONSTRAINT_SCHEMA = 'test'; +CONSTRAINT_CATALOG CONSTRAINT_SCHEMA TABLE_NAME CONSTRAINT_NAME CHECK_CLAUSE +def test t0 c2 `c2` < 3.14 +def test t0 checkme `c1` > 3 +def test t0 checkme2 `c1` < 21 +SELECT * from INFORMATION_SCHEMA.CHECK_CONSTRAINTS WHERE +CONSTRAINT_SCHEMA = 'test'; +CONSTRAINT_CATALOG CONSTRAINT_SCHEMA TABLE_NAME CONSTRAINT_NAME CHECK_CLAUSE +def test t0 c2 `c2` < 3.14 +def test t0 checkme `c1` > 3 +def test t0 checkme2 `c1` < 21 +ALTER TABLE t0 DROP CONSTRAINT IF EXISTS c2; +SELECT * from INFORMATION_SCHEMA.CHECK_CONSTRAINTS WHERE +CONSTRAINT_SCHEMA = 'test'; +CONSTRAINT_CATALOG CONSTRAINT_SCHEMA TABLE_NAME CONSTRAINT_NAME CHECK_CLAUSE +def test t0 checkme `c1` > 3 +def test t0 checkme2 `c1` < 21 +SELECT * from INFORMATION_SCHEMA.CHECK_CONSTRAINTS WHERE +CONSTRAINT_SCHEMA = 'test'; +CONSTRAINT_CATALOG CONSTRAINT_SCHEMA TABLE_NAME CONSTRAINT_NAME CHECK_CLAUSE +def test t0 checkme `c1` > 3 +def test t0 checkme2 `c1` < 21 +ALTER TABLE t0 DROP CONSTRAINT IF EXISTS c2; +Warnings: +Note 1091 Can't DROP CONSTRAINT `c2`; check that it exists +ALTER TABLE t0 MODIFY COLUMN c1 INT; +show create table t0; +Table Create Table +t0 CREATE TABLE `t0` ( + `c1` int(11) DEFAULT NULL, + `c2` int(11) DEFAULT NULL, + CONSTRAINT `checkme` CHECK (`c1` > 3), + CONSTRAINT `checkme2` CHECK (`c1` < 21) +) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci +ALTER TABLE t0 ADD CONSTRAINT CHECK (c1<0); +show create table t0; +Table Create Table +t0 CREATE TABLE `t0` ( + `c1` int(11) DEFAULT NULL, + `c2` int(11) DEFAULT NULL, + CONSTRAINT `checkme` CHECK (`c1` > 3), + CONSTRAINT `checkme2` CHECK (`c1` < 21), + CONSTRAINT `CONSTRAINT_1` CHECK (`c1` < 0) +) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci +SELECT * from INFORMATION_SCHEMA.CHECK_CONSTRAINTS WHERE +CONSTRAINT_SCHEMA = 'test'; +CONSTRAINT_CATALOG CONSTRAINT_SCHEMA TABLE_NAME CONSTRAINT_NAME CHECK_CLAUSE +def test t0 checkme `c1` > 3 +def test t0 checkme2 `c1` < 21 +def test t0 CONSTRAINT_1 `c1` < 0 +drop table t0; # # End of 10.4 tests # diff --git a/mysql-test/main/check_constraint.test b/mysql-test/main/check_constraint.test index e12468e901392..250f7708ecf56 100644 --- a/mysql-test/main/check_constraint.test +++ b/mysql-test/main/check_constraint.test @@ -45,7 +45,6 @@ select * from t1; create table t2 like t1; show create table t2; ---error ER_CANT_DROP_FIELD_OR_KEY alter table t2 drop constraint c; alter table t2 drop constraint if exists c; alter table t2 drop constraint min; @@ -243,6 +242,52 @@ insert t1 (a) values (1); --error ER_CONSTRAINT_FAILED insert t1 (a) values (-1); drop table t1; +--echo # MDEV-30899: Fail to drop CHECK constraint +--echo # +--source include/have_innodb.inc + +CREATE TABLE t0 (c1 INT CHECK ( c1 > 0 ), + constraint checkme check(c1>3), + constraint checkme2 check (c1<21) ); +show create table t0; +SELECT * from INFORMATION_SCHEMA.TABLE_CONSTRAINTS WHERE +CONSTRAINT_SCHEMA = 'test'; +SELECT * from INFORMATION_SCHEMA.CHECK_CONSTRAINTS WHERE +CONSTRAINT_SCHEMA = 'test'; + +# Drop field constraint +ALTER TABLE t0 DROP CONSTRAINT c1; +show create table t0; +SELECT * from INFORMATION_SCHEMA.CHECK_CONSTRAINTS WHERE +CONSTRAINT_SCHEMA = 'test'; +SELECT * from INFORMATION_SCHEMA.CHECK_CONSTRAINTS WHERE +CONSTRAINT_SCHEMA = 'test'; + +# Add new field check constraint and drop it and drop it if exists +alter table t0 add c2 int check (c2 < 3.14); +show create table t0; +SELECT * from INFORMATION_SCHEMA.CHECK_CONSTRAINTS WHERE +CONSTRAINT_SCHEMA = 'test'; +SELECT * from INFORMATION_SCHEMA.CHECK_CONSTRAINTS WHERE +CONSTRAINT_SCHEMA = 'test'; +ALTER TABLE t0 DROP CONSTRAINT IF EXISTS c2; +SELECT * from INFORMATION_SCHEMA.CHECK_CONSTRAINTS WHERE +CONSTRAINT_SCHEMA = 'test'; +SELECT * from INFORMATION_SCHEMA.CHECK_CONSTRAINTS WHERE +CONSTRAINT_SCHEMA = 'test'; +ALTER TABLE t0 DROP CONSTRAINT IF EXISTS c2; + +# Before only way to drop column constraint is to modify column without constraint +ALTER TABLE t0 MODIFY COLUMN c1 INT; +show create table t0; + +# Add constraints, adds table constraints. +ALTER TABLE t0 ADD CONSTRAINT CHECK (c1<0); +show create table t0; +SELECT * from INFORMATION_SCHEMA.CHECK_CONSTRAINTS WHERE +CONSTRAINT_SCHEMA = 'test'; +drop table t0; + --echo # --echo # End of 10.4 tests diff --git a/sql/sql_table.cc b/sql/sql_table.cc index 4a4d6f9cca225..8489a1237b82c 100644 --- a/sql/sql_table.cc +++ b/sql/sql_table.cc @@ -6495,7 +6495,7 @@ handle_if_exists_options(THD *thd, TABLE *table, Alter_info *alter_info, } else if (drop->type == Alter_drop::CHECK_CONSTRAINT) { - for (uint i=table->s->field_check_constraints; + for (uint i=0; i < table->s->table_check_constraints; i++) { @@ -8358,7 +8358,7 @@ mysql_prepare_alter_table(THD *thd, TABLE *table, create_info->option_list, thd->mem_root); /* - First collect all fields from table which isn't in drop_list + First collect all fields from table which aren't in drop_list */ bitmap_clear_all(&table->tmp_set); for (f_ptr=table->field ; (field= *f_ptr) ; f_ptr++) @@ -8368,16 +8368,26 @@ mysql_prepare_alter_table(THD *thd, TABLE *table, Alter_drop *drop; if (field->type() == MYSQL_TYPE_VARCHAR) create_info->varchar= TRUE; - /* Check if field should be dropped */ + /* Check if field should be dropped. + Check if there is field check constraint that should be dropped*/ drop_it.rewind(); while ((drop=drop_it++)) { if (drop->type == Alter_drop::COLUMN && !my_strcasecmp(system_charset_info,field->field_name.str, drop->name)) break; + if (drop->type == Alter_drop::CHECK_CONSTRAINT && field->check_constraint) + { + if (!my_strcasecmp(system_charset_info, field->check_constraint->name.str, + drop->name)) + { + field->check_constraint= NULL; + drop_it.remove(); + } + } } /* - DROP COLULMN xxx + DROP COLUMN xxx 1. it does not see INVISIBLE_SYSTEM columns 2. otherwise, normally a column is dropped 3. unless it's a system versioning column (but see below). @@ -8434,7 +8444,6 @@ mysql_prepare_alter_table(THD *thd, TABLE *table, // Force reopen because new column name is on thd->mem_root table->mark_table_for_reopen(); } - /* Check if field is changed */ def_it.rewind(); while ((def=def_it++)) @@ -8716,7 +8725,7 @@ mysql_prepare_alter_table(THD *thd, TABLE *table, } /* - Collect all keys which isn't in drop list. Add only those + Collect all keys which aren't in drop list. Add only those for which some fields exists. */ for (uint i=0 ; i < table->s->keys ; i++,key_info++)