summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--mysql-test/r/alter_table.result49
-rw-r--r--mysql-test/t/alter_table.test17
-rw-r--r--sql/sql_table.cc58
-rw-r--r--sql/sql_yacc.yy9
4 files changed, 131 insertions, 2 deletions
diff --git a/mysql-test/r/alter_table.result b/mysql-test/r/alter_table.result
index dcee72e44f7..f243d244486 100644
--- a/mysql-test/r/alter_table.result
+++ b/mysql-test/r/alter_table.result
@@ -2456,5 +2456,54 @@ ERROR 23000: Duplicate entry '1' for key 'i'
UNLOCK TABLES;
DROP TABLE t1;
#
+# MDEV-17599 ALTER TABLE DROP CONSTRAINT does not work for foreign keys.
+#
+CREATE TABLE t1(id INT PRIMARY KEY, c1 INT) ENGINE= INNODB;
+CREATE TABLE t2(id INT PRIMARY KEY, c1 INT, c2 INT NOT NULL,
+CONSTRAINT sid FOREIGN KEY (`c1`) REFERENCES t1 (`id`) ON DELETE NO ACTION ON UPDATE NO ACTION,
+CONSTRAINT UNIQUE `ui`(c2)) ENGINE= INNODB;
+SHOW CREATE TABLE t2;
+Table Create Table
+t2 CREATE TABLE `t2` (
+ `id` int(11) NOT NULL,
+ `c1` int(11) DEFAULT NULL,
+ `c2` int(11) NOT NULL,
+ PRIMARY KEY (`id`),
+ UNIQUE KEY `ui` (`c2`),
+ KEY `sid` (`c1`),
+ CONSTRAINT `sid` FOREIGN KEY (`c1`) REFERENCES `t1` (`id`) ON DELETE NO ACTION ON UPDATE NO ACTION
+) ENGINE=InnoDB DEFAULT CHARSET=latin1
+ALTER TABLE t2 DROP CONSTRAINT sid;
+SHOW CREATE TABLE t2;
+Table Create Table
+t2 CREATE TABLE `t2` (
+ `id` int(11) NOT NULL,
+ `c1` int(11) DEFAULT NULL,
+ `c2` int(11) NOT NULL,
+ PRIMARY KEY (`id`),
+ UNIQUE KEY `ui` (`c2`),
+ KEY `sid` (`c1`)
+) ENGINE=InnoDB DEFAULT CHARSET=latin1
+ALTER TABLE t2 DROP CONSTRAINT ui;
+SHOW CREATE TABLE t2;
+Table Create Table
+t2 CREATE TABLE `t2` (
+ `id` int(11) NOT NULL,
+ `c1` int(11) DEFAULT NULL,
+ `c2` int(11) NOT NULL,
+ PRIMARY KEY (`id`),
+ KEY `sid` (`c1`)
+) ENGINE=InnoDB DEFAULT CHARSET=latin1
+ALTER TABLE t2 DROP CONSTRAINT PRIMARY KEY;
+SHOW CREATE TABLE t2;
+Table Create Table
+t2 CREATE TABLE `t2` (
+ `id` int(11) NOT NULL,
+ `c1` int(11) DEFAULT NULL,
+ `c2` int(11) NOT NULL,
+ KEY `sid` (`c1`)
+) ENGINE=InnoDB DEFAULT CHARSET=latin1
+DROP TABLE t2, t1;
+#
# End of 10.2 tests
#
diff --git a/mysql-test/t/alter_table.test b/mysql-test/t/alter_table.test
index df077c800d2..e6caadcc52c 100644
--- a/mysql-test/t/alter_table.test
+++ b/mysql-test/t/alter_table.test
@@ -2013,5 +2013,22 @@ DROP TABLE t1;
--echo #
+--echo # MDEV-17599 ALTER TABLE DROP CONSTRAINT does not work for foreign keys.
+--echo #
+
+CREATE TABLE t1(id INT PRIMARY KEY, c1 INT) ENGINE= INNODB;
+CREATE TABLE t2(id INT PRIMARY KEY, c1 INT, c2 INT NOT NULL,
+ CONSTRAINT sid FOREIGN KEY (`c1`) REFERENCES t1 (`id`) ON DELETE NO ACTION ON UPDATE NO ACTION,
+ CONSTRAINT UNIQUE `ui`(c2)) ENGINE= INNODB;
+SHOW CREATE TABLE t2;
+ALTER TABLE t2 DROP CONSTRAINT sid;
+SHOW CREATE TABLE t2;
+ALTER TABLE t2 DROP CONSTRAINT ui;
+SHOW CREATE TABLE t2;
+ALTER TABLE t2 DROP CONSTRAINT PRIMARY KEY;
+SHOW CREATE TABLE t2;
+DROP TABLE t2, t1;
+
+--echo #
--echo # End of 10.2 tests
--echo #
diff --git a/sql/sql_table.cc b/sql/sql_table.cc
index f27b61092d2..1227f144348 100644
--- a/sql/sql_table.cc
+++ b/sql/sql_table.cc
@@ -8979,6 +8979,64 @@ bool mysql_alter_table(THD *thd,char *new_db, char *new_name,
THD_STAGE_INFO(thd, stage_setup);
+ if (alter_info->flags & Alter_info::ALTER_DROP_CHECK_CONSTRAINT)
+ {
+ /*
+ ALTER TABLE DROP CONSTRAINT
+ should be replaced with ... DROP [FOREIGN] KEY
+ if the constraint is the FOREIGN KEY or UNIQUE one.
+ */
+
+ List_iterator<Alter_drop> drop_it(alter_info->drop_list);
+ Alter_drop *drop;
+ List <FOREIGN_KEY_INFO> fk_child_key_list;
+ table->file->get_foreign_key_list(thd, &fk_child_key_list);
+
+ alter_info->flags&= ~Alter_info::ALTER_DROP_CHECK_CONSTRAINT;
+
+ while ((drop= drop_it++))
+ {
+ if (drop->type == Alter_drop::CHECK_CONSTRAINT)
+ {
+ {
+ /* Test if there is a FOREIGN KEY with this name. */
+ FOREIGN_KEY_INFO *f_key;
+ List_iterator<FOREIGN_KEY_INFO> fk_key_it(fk_child_key_list);
+
+ while ((f_key= fk_key_it++))
+ {
+ if (my_strcasecmp(system_charset_info, f_key->foreign_id->str,
+ drop->name) == 0)
+ {
+ drop->type= Alter_drop::FOREIGN_KEY;
+ alter_info->flags|= Alter_info::DROP_FOREIGN_KEY;
+ goto do_continue;
+ }
+ }
+ }
+
+ {
+ /* Test if there is an UNIQUE with this name. */
+ uint n_key;
+
+ for (n_key=0; n_key < table->s->keys; n_key++)
+ {
+ if ((table->key_info[n_key].flags & HA_NOSAME) &&
+ my_strcasecmp(system_charset_info,
+ drop->name, table->key_info[n_key].name) == 0)
+ {
+ drop->type= Alter_drop::KEY;
+ alter_info->flags|= Alter_info::ALTER_DROP_INDEX;
+ goto do_continue;
+ }
+ }
+ }
+ }
+ alter_info->flags|= Alter_info::ALTER_DROP_CHECK_CONSTRAINT;
+do_continue:;
+ }
+ }
+
handle_if_exists_options(thd, table, alter_info);
/*
diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy
index 480c2e9bacb..14d084e7022 100644
--- a/sql/sql_yacc.yy
+++ b/sql/sql_yacc.yy
@@ -1741,7 +1741,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize);
IDENT_sys TEXT_STRING_sys TEXT_STRING_literal
NCHAR_STRING opt_component key_cache_name
sp_opt_label BIN_NUM label_ident TEXT_STRING_filesystem ident_or_empty
- opt_constraint constraint opt_ident ident_table_alias
+ opt_constraint opt_constraint_no_id constraint opt_ident ident_table_alias
%type <lex_str_ptr>
opt_table_alias
@@ -6123,6 +6123,11 @@ check_constraint:
}
;
+opt_constraint_no_id:
+ /* Empty */ {}
+ | CONSTRAINT {}
+ ;
+
opt_constraint:
/* empty */ { $$= null_lex_str; }
| constraint { $$= $1; }
@@ -7653,7 +7658,7 @@ alter_list_item:
lex->alter_info.drop_list.push_back(ad, thd->mem_root);
lex->alter_info.flags|= Alter_info::DROP_FOREIGN_KEY;
}
- | DROP PRIMARY_SYM KEY_SYM
+ | DROP opt_constraint_no_id PRIMARY_SYM KEY_SYM
{
LEX *lex=Lex;
Alter_drop *ad= (new (thd->mem_root)