diff options
author | Alexey Botchkov <holyfoot@askmonty.org> | 2016-09-06 14:42:33 +0400 |
---|---|---|
committer | Alexey Botchkov <holyfoot@askmonty.org> | 2016-09-06 14:42:33 +0400 |
commit | 225440047d145bbe6a92bff05c5d4aa33e0aca91 (patch) | |
tree | 96d93f29a84df1fe66bdabfcc8fd20c9fc326013 /sql | |
parent | 00dfe27f7c5a0382d16cac832e879ae9f1cc45e9 (diff) | |
download | mariadb-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.txt | 4 | ||||
-rw-r--r-- | sql/sql_alter.h | 2 | ||||
-rw-r--r-- | sql/sql_lex.h | 5 | ||||
-rw-r--r-- | sql/sql_table.cc | 49 | ||||
-rw-r--r-- | sql/sql_yacc.yy | 7 |
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 { |