summaryrefslogtreecommitdiff
path: root/sql
diff options
context:
space:
mode:
authorAlexey Botchkov <holyfoot@askmonty.org>2016-09-06 14:42:33 +0400
committerAlexey Botchkov <holyfoot@askmonty.org>2016-09-06 14:42:33 +0400
commit225440047d145bbe6a92bff05c5d4aa33e0aca91 (patch)
tree96d93f29a84df1fe66bdabfcc8fd20c9fc326013 /sql
parent00dfe27f7c5a0382d16cac832e879ae9f1cc45e9 (diff)
downloadmariadb-git-225440047d145bbe6a92bff05c5d4aa33e0aca91.tar.gz
MDEV-10421 duplicate CHECK CONSTRAINTs.
mysql_prepare_create_table fixed so it doesn't let duplicating constraint names. Syntax for CONSTRAINT IF NOT EXISTS added and handled in mysql_alter_table.
Diffstat (limited to 'sql')
-rw-r--r--sql/share/errmsg-utf8.txt4
-rw-r--r--sql/sql_alter.h2
-rw-r--r--sql/sql_lex.h5
-rw-r--r--sql/sql_table.cc49
-rw-r--r--sql/sql_yacc.yy7
5 files changed, 63 insertions, 4 deletions
diff --git a/sql/share/errmsg-utf8.txt b/sql/share/errmsg-utf8.txt
index 43de678e1c2..37012c17bfb 100644
--- a/sql/share/errmsg-utf8.txt
+++ b/sql/share/errmsg-utf8.txt
@@ -6762,8 +6762,8 @@ ER_FK_CANNOT_OPEN_PARENT
ER_FK_INCORRECT_OPTION
eng "Failed to add the foreign key constraint on table '%s'. Incorrect options in FOREIGN KEY constraint '%s'"
-ER_FK_DUP_NAME
- eng "Duplicate foreign key constraint name '%s'"
+ER_DUP_CONSTRAINT_NAME
+ eng "Duplicate %s constraint name '%s'"
ER_PASSWORD_FORMAT
eng "The password hash doesn't have the expected format. Check if the correct password algorithm is being used with the PASSWORD() function."
diff --git a/sql/sql_alter.h b/sql/sql_alter.h
index 9e5fbaa425f..faba3a14a1b 100644
--- a/sql/sql_alter.h
+++ b/sql/sql_alter.h
@@ -174,6 +174,8 @@ public:
List<Key> key_list;
// List of columns, used by both CREATE and ALTER TABLE.
List<Create_field> create_list;
+
+ static const uint CHECK_CONSTRAINT_IF_NOT_EXISTS= 1;
List<Virtual_column_info> check_constraint_list;
// Type of ALTER TABLE operation.
uint flags;
diff --git a/sql/sql_lex.h b/sql/sql_lex.h
index e03446010b6..af461d05036 100644
--- a/sql/sql_lex.h
+++ b/sql/sql_lex.h
@@ -3003,9 +3003,12 @@ public:
return false;
}
// Add a constraint as a part of CREATE TABLE or ALTER TABLE
- bool add_constraint(LEX_STRING *name, Virtual_column_info *constr)
+ bool add_constraint(LEX_STRING *name, Virtual_column_info *constr,
+ bool if_not_exists)
{
constr->name= *name;
+ constr->flags= if_not_exists ?
+ Alter_info::CHECK_CONSTRAINT_IF_NOT_EXISTS : 0;
alter_info.check_constraint_list.push_back(constr);
return false;
}
diff --git a/sql/sql_table.cc b/sql/sql_table.cc
index 7784a2b188a..80fadde714f 100644
--- a/sql/sql_table.cc
+++ b/sql/sql_table.cc
@@ -4201,6 +4201,22 @@ mysql_prepare_create_table(THD *thd, HA_CREATE_INFO *create_info,
make_unique_constraint_name(thd, &check->name,
&alter_info->check_constraint_list,
&nr);
+ {
+ /* Check that there's no repeating constraint names. */
+ List_iterator_fast<Virtual_column_info>
+ dup_it(alter_info->check_constraint_list);
+ Virtual_column_info *dup_check;
+ while ((dup_check= dup_it++) && dup_check != check)
+ {
+ if (check->name.length == dup_check->name.length &&
+ my_strcasecmp(system_charset_info,
+ check->name.str, dup_check->name.str) == 0)
+ {
+ my_error(ER_DUP_CONSTRAINT_NAME, MYF(0), "CHECK", check->name);
+ DBUG_RETURN(TRUE);
+ }
+ }
+ }
if (check_string_char_length(&check->name, 0, NAME_CHAR_LEN,
system_charset_info, 1))
@@ -6153,6 +6169,39 @@ remove_key:
}
#endif /*WITH_PARTITION_STORAGE_ENGINE*/
+ /* ADD CONSTRAINT IF NOT EXISTS. */
+ {
+ List_iterator<Virtual_column_info> it(alter_info->check_constraint_list);
+ Virtual_column_info *check;
+ TABLE_SHARE *share= table->s;
+ uint c;
+ while ((check=it++))
+ {
+ if ((!check->flags & Alter_info::CHECK_CONSTRAINT_IF_NOT_EXISTS) &&
+ check->name.length)
+ continue;
+ check->flags= 0;
+ for (c= share->field_check_constraints;
+ c < share->table_check_constraints ; c++)
+ {
+ Virtual_column_info *dup= table->check_constraints[c];
+ if (dup->name.length == check->name.length &&
+ my_strcasecmp(system_charset_info,
+ check->name.str, dup->name.str) == 0)
+ {
+ push_warning_printf(thd, Sql_condition::WARN_LEVEL_NOTE,
+ ER_DUP_CONSTRAINT_NAME, ER_THD(thd, ER_DUP_CONSTRAINT_NAME),
+ "CHECK", check->name.str);
+ it.remove();
+ if (alter_info->check_constraint_list.elements == 0)
+ alter_info->flags&= ~Alter_info::ALTER_ADD_CHECK_CONSTRAINT;
+
+ break;
+ }
+ }
+ }
+ }
+
DBUG_VOID_RETURN;
}
diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy
index 63ba77caa22..5908c7d3cb8 100644
--- a/sql/sql_yacc.yy
+++ b/sql/sql_yacc.yy
@@ -6073,7 +6073,7 @@ key_def:
constraint_def:
opt_constraint check_constraint
{
- Lex->add_constraint(&$1, $2);
+ Lex->add_constraint(&$1, $2, FALSE);
}
;
@@ -7560,6 +7560,11 @@ alter_list_item:
{
Lex->alter_info.flags|= Alter_info::ALTER_ADD_CHECK_CONSTRAINT;
}
+ | ADD CONSTRAINT IF_SYM not EXISTS field_ident check_constraint
+ {
+ Lex->alter_info.flags|= Alter_info::ALTER_ADD_CHECK_CONSTRAINT;
+ Lex->add_constraint(&$6, $7, TRUE);
+ }
| CHANGE opt_column opt_if_exists_table_element field_ident
field_spec opt_place
{