Skip to content

Commit 4428409

Browse files
author
Marc Alff
committed
Bug#34455 Ambiguous foreign keys syntax is accepted
Backport from 6.0 to 5.5
1 parent dba07c7 commit 4428409

File tree

4 files changed

+180
-31
lines changed

4 files changed

+180
-31
lines changed

mysql-test/r/foreign_key.result

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,3 +13,45 @@ foreign key (a,b) references t3 (c,d) on update set null);
1313
create index a on t1 (a);
1414
create unique index b on t1 (a,b);
1515
drop table t1;
16+
drop table if exists t_34455;
17+
create table t_34455 (
18+
a int not null,
19+
foreign key (a) references t3 (a) match full match partial);
20+
ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'match partial)' at line 3
21+
create table t_34455 (
22+
a int not null,
23+
foreign key (a) references t3 (a) on delete set default match full);
24+
ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'match full)' at line 3
25+
create table t_34455 (
26+
a int not null,
27+
foreign key (a) references t3 (a) on update set default match full);
28+
ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'match full)' at line 3
29+
create table t_34455 (
30+
a int not null,
31+
foreign key (a) references t3 (a)
32+
on delete set default on delete set default);
33+
ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'delete set default)' at line 4
34+
create table t_34455 (
35+
a int not null,
36+
foreign key (a) references t3 (a)
37+
on update set default on update set default);
38+
ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'update set default)' at line 4
39+
create table t_34455 (a int not null);
40+
alter table t_34455
41+
add foreign key (a) references t3 (a) match full match partial);
42+
ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'match partial)' at line 2
43+
alter table t_34455
44+
add foreign key (a) references t3 (a) on delete set default match full);
45+
ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'match full)' at line 2
46+
alter table t_34455
47+
add foreign key (a) references t3 (a) on update set default match full);
48+
ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'match full)' at line 2
49+
alter table t_34455
50+
add foreign key (a) references t3 (a)
51+
on delete set default on delete set default);
52+
ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'delete set default)' at line 3
53+
alter table t_34455
54+
add foreign key (a) references t3 (a)
55+
on update set default on update set default);
56+
ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'update set default)' at line 3
57+
drop table t_34455;

mysql-test/t/foreign_key.test

Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,3 +23,75 @@ create unique index b on t1 (a,b);
2323
drop table t1;
2424

2525
# End of 4.1 tests
26+
27+
#
28+
# Bug#34455 (Ambiguous foreign keys syntax is accepted)
29+
#
30+
31+
--disable_warnings
32+
drop table if exists t_34455;
33+
--enable_warnings
34+
35+
# 2 match clauses, illegal
36+
--error ER_PARSE_ERROR
37+
create table t_34455 (
38+
a int not null,
39+
foreign key (a) references t3 (a) match full match partial);
40+
41+
# match after on delete, illegal
42+
--error ER_PARSE_ERROR
43+
create table t_34455 (
44+
a int not null,
45+
foreign key (a) references t3 (a) on delete set default match full);
46+
47+
# match after on update, illegal
48+
--error ER_PARSE_ERROR
49+
create table t_34455 (
50+
a int not null,
51+
foreign key (a) references t3 (a) on update set default match full);
52+
53+
# 2 on delete clauses, illegal
54+
--error ER_PARSE_ERROR
55+
create table t_34455 (
56+
a int not null,
57+
foreign key (a) references t3 (a)
58+
on delete set default on delete set default);
59+
60+
# 2 on update clauses, illegal
61+
--error ER_PARSE_ERROR
62+
create table t_34455 (
63+
a int not null,
64+
foreign key (a) references t3 (a)
65+
on update set default on update set default);
66+
67+
create table t_34455 (a int not null);
68+
69+
# 2 match clauses, illegal
70+
--error ER_PARSE_ERROR
71+
alter table t_34455
72+
add foreign key (a) references t3 (a) match full match partial);
73+
74+
# match after on delete, illegal
75+
--error ER_PARSE_ERROR
76+
alter table t_34455
77+
add foreign key (a) references t3 (a) on delete set default match full);
78+
79+
# match after on update, illegal
80+
--error ER_PARSE_ERROR
81+
alter table t_34455
82+
add foreign key (a) references t3 (a) on update set default match full);
83+
84+
# 2 on delete clauses, illegal
85+
--error ER_PARSE_ERROR
86+
alter table t_34455
87+
add foreign key (a) references t3 (a)
88+
on delete set default on delete set default);
89+
90+
# 2 on update clauses, illegal
91+
--error ER_PARSE_ERROR
92+
alter table t_34455
93+
add foreign key (a) references t3 (a)
94+
on update set default on update set default);
95+
96+
drop table t_34455;
97+

sql/sql_lex.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1903,7 +1903,9 @@ struct LEX: public Query_tables_list
19031903
uint profile_options;
19041904
uint uint_geom_type;
19051905
uint grant, grant_tot_col, which_columns;
1906-
uint fk_delete_opt, fk_update_opt, fk_match_option;
1906+
enum Foreign_key::fk_match_opt fk_match_option;
1907+
enum Foreign_key::fk_option fk_update_opt;
1908+
enum Foreign_key::fk_option fk_delete_opt;
19071909
uint slave_thd_opt, start_transaction_opt;
19081910
int nest_level;
19091911
/*

sql/sql_yacc.yy

Lines changed: 63 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -756,6 +756,7 @@ static bool add_create_index (LEX *lex, Key::Keytype type,
756756
struct p_elem_val *p_elem_value;
757757
enum index_hint_type index_hint;
758758
enum enum_filetype filetype;
759+
enum Foreign_key::fk_option m_fk_option;
759760
Diag_condition_item_name diag_condition_item_name;
760761
}
761762

@@ -1422,14 +1423,17 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize);
14221423
type type_with_opt_collate int_type real_type order_dir lock_option
14231424
udf_type if_exists opt_local opt_table_options table_options
14241425
table_option opt_if_not_exists opt_no_write_to_binlog
1425-
delete_option opt_temporary all_or_any opt_distinct
1426+
opt_temporary all_or_any opt_distinct
14261427
opt_ignore_leaves fulltext_options spatial_type union_option
14271428
start_transaction_opts opt_chain opt_release
14281429
union_opt select_derived_init option_type2
14291430
opt_natural_language_mode opt_query_expansion
14301431
opt_ev_status opt_ev_on_completion ev_on_completion opt_ev_comment
14311432
ev_alter_on_schedule_completion opt_ev_rename_to opt_ev_sql_stmt
14321433

1434+
%type <m_fk_option>
1435+
delete_option
1436+
14331437
%type <ulong_num>
14341438
ulong_num real_ulong_num merge_insert_types
14351439

@@ -1544,7 +1548,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize);
15441548
opt_precision opt_ignore opt_column opt_restrict
15451549
grant revoke set lock unlock string_list field_options field_option
15461550
field_opt_list opt_binary ascii unicode table_lock_list table_lock
1547-
ref_list opt_on_delete opt_on_delete_list opt_on_delete_item use
1551+
ref_list opt_match_clause opt_on_update_delete use
15481552
opt_delete_options opt_delete_option varchar nchar nvarchar
15491553
opt_outer table_list table_name table_alias_ref_list table_alias_ref
15501554
opt_option opt_place
@@ -5833,21 +5837,20 @@ opt_primary:
58335837
;
58345838

58355839
references:
5836-
REFERENCES table_ident
5837-
{
5838-
LEX *lex=Lex;
5839-
lex->fk_delete_opt= lex->fk_update_opt= lex->fk_match_option= 0;
5840-
lex->ref_list.empty();
5841-
}
5840+
REFERENCES
5841+
table_ident
58425842
opt_ref_list
5843+
opt_match_clause
5844+
opt_on_update_delete
58435845
{
58445846
$$=$2;
58455847
}
58465848
;
58475849

58485850
opt_ref_list:
5849-
/* empty */ opt_on_delete {}
5850-
| '(' ref_list ')' opt_on_delete {}
5851+
/* empty */
5852+
{ Lex->ref_list.empty(); }
5853+
| '(' ref_list ')'
58515854
;
58525855

58535856
ref_list:
@@ -5863,34 +5866,64 @@ ref_list:
58635866
Key_part_spec *key= new Key_part_spec($1, 0);
58645867
if (key == NULL)
58655868
MYSQL_YYABORT;
5866-
Lex->ref_list.push_back(key);
5869+
LEX *lex= Lex;
5870+
lex->ref_list.empty();
5871+
lex->ref_list.push_back(key);
58675872
}
58685873
;
58695874

5870-
opt_on_delete:
5871-
/* empty */ {}
5872-
| opt_on_delete_list {}
5873-
;
5874-
5875-
opt_on_delete_list:
5876-
opt_on_delete_list opt_on_delete_item {}
5877-
| opt_on_delete_item {}
5875+
opt_match_clause:
5876+
/* empty */
5877+
{ Lex->fk_match_option= Foreign_key::FK_MATCH_UNDEF; }
5878+
| MATCH FULL
5879+
{ Lex->fk_match_option= Foreign_key::FK_MATCH_FULL; }
5880+
| MATCH PARTIAL
5881+
{ Lex->fk_match_option= Foreign_key::FK_MATCH_PARTIAL; }
5882+
| MATCH SIMPLE_SYM
5883+
{ Lex->fk_match_option= Foreign_key::FK_MATCH_SIMPLE; }
58785884
;
58795885

5880-
opt_on_delete_item:
5881-
ON DELETE_SYM delete_option { Lex->fk_delete_opt= $3; }
5882-
| ON UPDATE_SYM delete_option { Lex->fk_update_opt= $3; }
5883-
| MATCH FULL { Lex->fk_match_option= Foreign_key::FK_MATCH_FULL; }
5884-
| MATCH PARTIAL { Lex->fk_match_option= Foreign_key::FK_MATCH_PARTIAL; }
5885-
| MATCH SIMPLE_SYM { Lex->fk_match_option= Foreign_key::FK_MATCH_SIMPLE; }
5886+
opt_on_update_delete:
5887+
/* empty */
5888+
{
5889+
LEX *lex= Lex;
5890+
lex->fk_update_opt= Foreign_key::FK_OPTION_UNDEF;
5891+
lex->fk_delete_opt= Foreign_key::FK_OPTION_UNDEF;
5892+
}
5893+
| ON UPDATE_SYM delete_option
5894+
{
5895+
LEX *lex= Lex;
5896+
lex->fk_update_opt= $3;
5897+
lex->fk_delete_opt= Foreign_key::FK_OPTION_UNDEF;
5898+
}
5899+
| ON DELETE_SYM delete_option
5900+
{
5901+
LEX *lex= Lex;
5902+
lex->fk_update_opt= Foreign_key::FK_OPTION_UNDEF;
5903+
lex->fk_delete_opt= $3;
5904+
}
5905+
| ON UPDATE_SYM delete_option
5906+
ON DELETE_SYM delete_option
5907+
{
5908+
LEX *lex= Lex;
5909+
lex->fk_update_opt= $3;
5910+
lex->fk_delete_opt= $6;
5911+
}
5912+
| ON DELETE_SYM delete_option
5913+
ON UPDATE_SYM delete_option
5914+
{
5915+
LEX *lex= Lex;
5916+
lex->fk_update_opt= $6;
5917+
lex->fk_delete_opt= $3;
5918+
}
58865919
;
58875920

58885921
delete_option:
5889-
RESTRICT { $$= (int) Foreign_key::FK_OPTION_RESTRICT; }
5890-
| CASCADE { $$= (int) Foreign_key::FK_OPTION_CASCADE; }
5891-
| SET NULL_SYM { $$= (int) Foreign_key::FK_OPTION_SET_NULL; }
5892-
| NO_SYM ACTION { $$= (int) Foreign_key::FK_OPTION_NO_ACTION; }
5893-
| SET DEFAULT { $$= (int) Foreign_key::FK_OPTION_DEFAULT; }
5922+
RESTRICT { $$= Foreign_key::FK_OPTION_RESTRICT; }
5923+
| CASCADE { $$= Foreign_key::FK_OPTION_CASCADE; }
5924+
| SET NULL_SYM { $$= Foreign_key::FK_OPTION_SET_NULL; }
5925+
| NO_SYM ACTION { $$= Foreign_key::FK_OPTION_NO_ACTION; }
5926+
| SET DEFAULT { $$= Foreign_key::FK_OPTION_DEFAULT; }
58945927
;
58955928

58965929
normal_key_type:

0 commit comments

Comments
 (0)