diff options
author | Aleksey Midenkov <midenok@gmail.com> | 2019-11-20 13:18:54 +0300 |
---|---|---|
committer | Aleksey Midenkov <midenok@gmail.com> | 2019-11-20 13:18:54 +0300 |
commit | daabc5cc68440fe7871b7c570e114a6a0d119bfb (patch) | |
tree | 00b3e0b5802d54326e2c9987c40d40ef1a459b1e | |
parent | 5130f5206c150ba1e8a723aae63884ff64408012 (diff) | |
download | mariadb-git-daabc5cc68440fe7871b7c570e114a6a0d119bfb.tar.gz |
MDEV-20729 Fix REFERENCES constraint in column definition
Add support of referential constraints directly in column defininions:
create table t1 (id1 int primary key);
create table t2 (id2 int references t1(id1));
Referenced field name can be omitted if equal to foreign field name:
create table t1 (id int primary key);
create table t2 (id int references t1);
Until 10.5 this syntax was understood by the parser but was silently
ignored.
In case of generated columns this syntax is disabled at parser level
by ER_PARSE_ERROR. Note that separate FOREIGN KEY clause for generated
columns is disabled at storage engine level.
20 files changed, 273 insertions, 64 deletions
diff --git a/libmariadb b/libmariadb -Subproject 980f2dbea6586091333057bb2994b1874746694 +Subproject 261a5c435581c8d6c6341afac95bcc5c96d1435 diff --git a/mysql-test/main/foreign_key.result b/mysql-test/main/foreign_key.result index a82151ddec0..ea8f0f8ec84 100644 --- a/mysql-test/main/foreign_key.result +++ b/mysql-test/main/foreign_key.result @@ -1,7 +1,7 @@ drop table if exists t1,t2; create table t1 ( a int not null references t2, -b int not null references t2 (c), +b int not null constraint t2_c references t2 (c), primary key (a,b), foreign key (a) references t3 match full, foreign key (a) references t3 match partial, diff --git a/mysql-test/main/foreign_key.test b/mysql-test/main/foreign_key.test index 17c93332cb3..99c5272f307 100644 --- a/mysql-test/main/foreign_key.test +++ b/mysql-test/main/foreign_key.test @@ -10,7 +10,7 @@ drop table if exists t1,t2; create table t1 ( a int not null references t2, - b int not null references t2 (c), + b int not null constraint t2_c references t2 (c), primary key (a,b), foreign key (a) references t3 match full, foreign key (a) references t3 match partial, diff --git a/mysql-test/suite/funcs_1/r/is_statistics.result b/mysql-test/suite/funcs_1/r/is_statistics.result index bacc106a1be..5cd3805cfab 100644 --- a/mysql-test/suite/funcs_1/r/is_statistics.result +++ b/mysql-test/suite/funcs_1/r/is_statistics.result @@ -109,6 +109,7 @@ def mysql help_category mysql name def mysql help_category mysql PRIMARY def mysql help_keyword mysql name def mysql help_keyword mysql PRIMARY +def mysql help_relation mysql help_topic_id def mysql help_relation mysql PRIMARY def mysql help_relation mysql PRIMARY def mysql help_topic mysql name diff --git a/mysql-test/suite/funcs_1/r/is_statistics_mysql.result b/mysql-test/suite/funcs_1/r/is_statistics_mysql.result index c01c456edf8..40d5e125c0d 100644 --- a/mysql-test/suite/funcs_1/r/is_statistics_mysql.result +++ b/mysql-test/suite/funcs_1/r/is_statistics_mysql.result @@ -30,6 +30,7 @@ def mysql help_category 0 mysql name 1 name A #CARD# NULL NULL BTREE def mysql help_category 0 mysql PRIMARY 1 help_category_id A #CARD# NULL NULL BTREE def mysql help_keyword 0 mysql name 1 name A #CARD# NULL NULL BTREE def mysql help_keyword 0 mysql PRIMARY 1 help_keyword_id A #CARD# NULL NULL BTREE +def mysql help_relation 1 mysql help_topic_id 1 help_topic_id A #CARD# NULL NULL BTREE def mysql help_relation 0 mysql PRIMARY 1 help_keyword_id A #CARD# NULL NULL BTREE def mysql help_relation 0 mysql PRIMARY 2 help_topic_id A #CARD# NULL NULL BTREE def mysql help_topic 0 mysql name 1 name A #CARD# NULL NULL BTREE diff --git a/mysql-test/suite/funcs_1/r/is_statistics_mysql_embedded.result b/mysql-test/suite/funcs_1/r/is_statistics_mysql_embedded.result index b7bd3ec2e23..01a98e413da 100644 --- a/mysql-test/suite/funcs_1/r/is_statistics_mysql_embedded.result +++ b/mysql-test/suite/funcs_1/r/is_statistics_mysql_embedded.result @@ -30,6 +30,7 @@ def mysql help_category 0 mysql name 1 name A #CARD# NULL NULL BTREE def mysql help_category 0 mysql PRIMARY 1 help_category_id A #CARD# NULL NULL BTREE def mysql help_keyword 0 mysql name 1 name A #CARD# NULL NULL BTREE def mysql help_keyword 0 mysql PRIMARY 1 help_keyword_id A #CARD# NULL NULL BTREE +def mysql help_relation 1 mysql help_topic_id 1 help_topic_id A #CARD# NULL NULL BTREE def mysql help_relation 0 mysql PRIMARY 1 help_keyword_id A #CARD# NULL NULL BTREE def mysql help_relation 0 mysql PRIMARY 2 help_topic_id A #CARD# NULL NULL BTREE def mysql help_topic 0 mysql name 1 name A #CARD# NULL NULL BTREE @@ -110,6 +111,7 @@ def mysql help_category 0 mysql name 1 name A #CARD# NULL NULL BTREE def mysql help_category 0 mysql PRIMARY 1 help_category_id A #CARD# NULL NULL BTREE def mysql help_keyword 0 mysql name 1 name A #CARD# NULL NULL BTREE def mysql help_keyword 0 mysql PRIMARY 1 help_keyword_id A #CARD# NULL NULL BTREE +def mysql help_relation 1 mysql help_topic_id 1 help_topic_id A #CARD# NULL NULL BTREE def mysql help_relation 0 mysql PRIMARY 1 help_keyword_id A #CARD# NULL NULL BTREE def mysql help_relation 0 mysql PRIMARY 2 help_topic_id A #CARD# NULL NULL BTREE def mysql help_topic 0 mysql name 1 name A #CARD# NULL NULL BTREE diff --git a/mysql-test/suite/gcol/inc/gcol_column_def_options.inc b/mysql-test/suite/gcol/inc/gcol_column_def_options.inc index 28c854c44f4..482b183db1e 100644 --- a/mysql-test/suite/gcol/inc/gcol_column_def_options.inc +++ b/mysql-test/suite/gcol/inc/gcol_column_def_options.inc @@ -134,12 +134,16 @@ drop table t1; create table t2 (a int); +--error ER_PARSE_ERROR create table t1 (a int, b int generated always as (a % 2) stored references t2(a)); +create table t1 (a int, b int generated always as (a % 2) stored); show create table t1; drop table t1; create table t1 (a int, b int generated always as (a % 2) virtual); ---error 1064 +--error ER_PARSE_ERROR alter table t1 modify b int generated always as (a % 2) stored references t2(a); +--error ER_UNSUPPORTED_ACTION_ON_GENERATED_COLUMN +alter table t1 modify b int generated always as (a % 2) stored; show create table t1; drop table t1; drop table t2; diff --git a/mysql-test/suite/gcol/r/gcol_column_def_options_innodb.result b/mysql-test/suite/gcol/r/gcol_column_def_options_innodb.result index a98652248f8..6dfb64a4abe 100644 --- a/mysql-test/suite/gcol/r/gcol_column_def_options_innodb.result +++ b/mysql-test/suite/gcol/r/gcol_column_def_options_innodb.result @@ -154,6 +154,8 @@ a b drop table t1; create table t2 (a int); create table t1 (a int, b int generated always as (a % 2) stored references t2(a)); +ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near ')' at line 1 +create table t1 (a int, b int generated always as (a % 2) stored); show create table t1; Table Create Table t1 CREATE TABLE `t1` ( @@ -164,6 +166,8 @@ drop table t1; create table t1 (a int, b int generated always as (a % 2) virtual); alter table t1 modify b int generated always as (a % 2) stored references t2(a); ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near 'references t2(a)' at line 1 +alter table t1 modify b int generated always as (a % 2) stored; +ERROR HY000: This is not yet supported for generated columns show create table t1; Table Create Table t1 CREATE TABLE `t1` ( diff --git a/mysql-test/suite/gcol/r/gcol_column_def_options_myisam.result b/mysql-test/suite/gcol/r/gcol_column_def_options_myisam.result index 82a879be3f7..d8f94822b06 100644 --- a/mysql-test/suite/gcol/r/gcol_column_def_options_myisam.result +++ b/mysql-test/suite/gcol/r/gcol_column_def_options_myisam.result @@ -154,6 +154,8 @@ a b drop table t1; create table t2 (a int); create table t1 (a int, b int generated always as (a % 2) stored references t2(a)); +ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near ')' at line 1 +create table t1 (a int, b int generated always as (a % 2) stored); show create table t1; Table Create Table t1 CREATE TABLE `t1` ( @@ -164,6 +166,8 @@ drop table t1; create table t1 (a int, b int generated always as (a % 2) virtual); alter table t1 modify b int generated always as (a % 2) stored references t2(a); ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near 'references t2(a)' at line 1 +alter table t1 modify b int generated always as (a % 2) stored; +ERROR HY000: This is not yet supported for generated columns show create table t1; Table Create Table t1 CREATE TABLE `t1` ( diff --git a/mysql-test/suite/innodb/r/foreign_key.result b/mysql-test/suite/innodb/r/foreign_key.result index 869a66a0e1b..5fd49b3dd82 100644 --- a/mysql-test/suite/innodb/r/foreign_key.result +++ b/mysql-test/suite/innodb/r/foreign_key.result @@ -522,3 +522,47 @@ test.t1 check status OK DROP TABLE t1; SET GLOBAL innodb_purge_rseg_truncate_frequency = @saved_frequency; # End of 10.2 tests +# +# MDEV-20729 Fix REFERENCES constraint in column definition +# +set default_storage_engine= innodb; +create table t1 (x int primary key, y int unique); +create table t2 (x int references t1(x), y int constraint fk references t1(y)); +show create table t2; +Table Create Table +t2 CREATE TABLE `t2` ( + `x` int(11) DEFAULT NULL, + `y` int(11) DEFAULT NULL, + KEY `x` (`x`), + KEY `fk` (`y`), + CONSTRAINT `fk` FOREIGN KEY (`y`) REFERENCES `t1` (`y`), + CONSTRAINT `t2_ibfk_1` FOREIGN KEY (`x`) REFERENCES `t1` (`x`) +) ENGINE=InnoDB DEFAULT CHARSET=latin1 +create table t3 (z int); +alter table t3 add x int references t1(x), add y int constraint fk2 references t1(y); +show create table t3; +Table Create Table +t3 CREATE TABLE `t3` ( + `z` int(11) DEFAULT NULL, + `x` int(11) DEFAULT NULL, + `y` int(11) DEFAULT NULL, + KEY `x` (`x`), + KEY `fk2` (`y`), + CONSTRAINT `fk2` FOREIGN KEY (`y`) REFERENCES `t1` (`y`), + CONSTRAINT `t3_ibfk_1` FOREIGN KEY (`x`) REFERENCES `t1` (`x`) +) ENGINE=InnoDB DEFAULT CHARSET=latin1 +drop tables t3, t2, t1; +create table t1 (id int primary key); +create table t2 (id2 int references t1); +ERROR HY000: Can't create table `test`.`t2` (errno: 150 "Foreign key constraint is incorrectly formed") +create table t2 (id int references t1); +show create table t2; +Table Create Table +t2 CREATE TABLE `t2` ( + `id` int(11) DEFAULT NULL, + KEY `id` (`id`), + CONSTRAINT `t2_ibfk_1` FOREIGN KEY (`id`) REFERENCES `t1` (`id`) +) ENGINE=InnoDB DEFAULT CHARSET=latin1 +drop tables t2, t1; +set default_storage_engine= default; +# End of 10.5 tests diff --git a/mysql-test/suite/innodb/t/foreign_key.test b/mysql-test/suite/innodb/t/foreign_key.test index 06cab983656..35136f7bca7 100644 --- a/mysql-test/suite/innodb/t/foreign_key.test +++ b/mysql-test/suite/innodb/t/foreign_key.test @@ -498,4 +498,27 @@ SET GLOBAL innodb_purge_rseg_truncate_frequency = @saved_frequency; --echo # End of 10.2 tests +--echo # +--echo # MDEV-20729 Fix REFERENCES constraint in column definition +--echo # +set default_storage_engine= innodb; +create table t1 (x int primary key, y int unique); +create table t2 (x int references t1(x), y int constraint fk references t1(y)); +show create table t2; +create table t3 (z int); +alter table t3 add x int references t1(x), add y int constraint fk2 references t1(y); +show create table t3; +drop tables t3, t2, t1; + +create table t1 (id int primary key); +--error ER_CANT_CREATE_TABLE +create table t2 (id2 int references t1); +create table t2 (id int references t1); +show create table t2; +drop tables t2, t1; + +set default_storage_engine= default; + +--echo # End of 10.5 tests + --source include/wait_until_count_sessions.inc diff --git a/mysql-test/suite/vcol/inc/vcol_column_def_options.inc b/mysql-test/suite/vcol/inc/vcol_column_def_options.inc index 2f28136ad63..61eac0014bc 100644 --- a/mysql-test/suite/vcol/inc/vcol_column_def_options.inc +++ b/mysql-test/suite/vcol/inc/vcol_column_def_options.inc @@ -103,11 +103,11 @@ drop table t1; create table t2 (a int); -create table t1 (a int, b int as (a % 2) persistent references t2(a)); +create table t1 (a int, b int as (a % 2) persistent); show create table t1; drop table t1; create table t1 (a int, b int as (a % 2)); ---error ER_PARSE_ERROR -alter table t1 modify b int as (a % 2) persistent references t2(a); +--error ER_UNSUPPORTED_ACTION_ON_GENERATED_COLUMN +alter table t1 modify b int as (a % 2) persistent; show create table t1; drop table t1; diff --git a/mysql-test/suite/vcol/r/vcol_column_def_options_innodb.result b/mysql-test/suite/vcol/r/vcol_column_def_options_innodb.result index 0f80365f6a7..f6c58e63e59 100644 --- a/mysql-test/suite/vcol/r/vcol_column_def_options_innodb.result +++ b/mysql-test/suite/vcol/r/vcol_column_def_options_innodb.result @@ -126,7 +126,7 @@ a b 2 0 drop table t1; create table t2 (a int); -create table t1 (a int, b int as (a % 2) persistent references t2(a)); +create table t1 (a int, b int as (a % 2) persistent); show create table t1; Table Create Table t1 CREATE TABLE `t1` ( @@ -135,8 +135,8 @@ t1 CREATE TABLE `t1` ( ) ENGINE=InnoDB DEFAULT CHARSET=latin1 drop table t1; create table t1 (a int, b int as (a % 2)); -alter table t1 modify b int as (a % 2) persistent references t2(a); -ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near 'references t2(a)' at line 1 +alter table t1 modify b int as (a % 2) persistent; +ERROR HY000: This is not yet supported for generated columns show create table t1; Table Create Table t1 CREATE TABLE `t1` ( diff --git a/mysql-test/suite/vcol/r/vcol_column_def_options_myisam.result b/mysql-test/suite/vcol/r/vcol_column_def_options_myisam.result index e53a7594663..204ce1d880c 100644 --- a/mysql-test/suite/vcol/r/vcol_column_def_options_myisam.result +++ b/mysql-test/suite/vcol/r/vcol_column_def_options_myisam.result @@ -126,7 +126,7 @@ a b 2 0 drop table t1; create table t2 (a int); -create table t1 (a int, b int as (a % 2) persistent references t2(a)); +create table t1 (a int, b int as (a % 2) persistent); show create table t1; Table Create Table t1 CREATE TABLE `t1` ( @@ -135,8 +135,8 @@ t1 CREATE TABLE `t1` ( ) ENGINE=MyISAM DEFAULT CHARSET=latin1 drop table t1; create table t1 (a int, b int as (a % 2)); -alter table t1 modify b int as (a % 2) persistent references t2(a); -ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near 'references t2(a)' at line 1 +alter table t1 modify b int as (a % 2) persistent; +ERROR HY000: This is not yet supported for generated columns show create table t1; Table Create Table t1 CREATE TABLE `t1` ( diff --git a/mysql-test/suite/versioning/r/foreign.result b/mysql-test/suite/versioning/r/foreign.result index 1b9925b1e62..5234a1ad616 100644 --- a/mysql-test/suite/versioning/r/foreign.result +++ b/mysql-test/suite/versioning/r/foreign.result @@ -429,3 +429,41 @@ insert into t2 values (1), (1); # DELETE from foreign table is allowed delete from t2; drop tables t2, t1; +# +# MDEV-20729 Fix REFERENCES constraint in column definition +# +create or replace table t1( +id int +); +# system fields can't be foreign keys: +create or replace table t2( +x int, +sys_start SYS_DATATYPE as row start references t1(id), +sys_end SYS_DATATYPE as row end, +period for system_time(sys_start, sys_end) +) engine innodb with system versioning; +Got one of the listed errors +create or replace table t2( +x int, +sys_start SYS_DATATYPE as row start, +sys_end SYS_DATATYPE as row end references t1(id), +period for system_time(sys_start, sys_end) +) engine innodb with system versioning; +Got one of the listed errors +create or replace table t2( +x int, +sys_start SYS_DATATYPE as row start, +sys_end SYS_DATATYPE as row end, +period for system_time(sys_start, sys_end), +foreign key (sys_start) references t1(id) +) engine innodb with system versioning; +ERROR HY000: Can't create table `test`.`t2` (errno: 150 "Foreign key constraint is incorrectly formed") +create or replace table t2( +x int, +sys_start SYS_DATATYPE as row start, +sys_end SYS_DATATYPE as row end, +period for system_time(sys_start, sys_end), +foreign key (sys_end) references t1(id) +) engine innodb with system versioning; +ERROR HY000: Can't create table `test`.`t2` (errno: 150 "Foreign key constraint is incorrectly formed") +drop table t1; diff --git a/mysql-test/suite/versioning/t/foreign.test b/mysql-test/suite/versioning/t/foreign.test index 453ddd34034..831ba518337 100644 --- a/mysql-test/suite/versioning/t/foreign.test +++ b/mysql-test/suite/versioning/t/foreign.test @@ -458,4 +458,47 @@ insert into t2 values (1), (1); delete from t2; drop tables t2, t1; +--echo # +--echo # MDEV-20729 Fix REFERENCES constraint in column definition +--echo # +create or replace table t1( + id int +); +--echo # system fields can't be foreign keys: +--replace_result $sys_datatype_expl SYS_DATATYPE +--error ER_PARSE_ERROR,ER_PARSE_ERROR +eval create or replace table t2( + x int, + sys_start $sys_datatype_expl as row start references t1(id), + sys_end $sys_datatype_expl as row end, + period for system_time(sys_start, sys_end) +) engine innodb with system versioning; +--replace_result $sys_datatype_expl SYS_DATATYPE +--error ER_PARSE_ERROR,ER_PARSE_ERROR +eval create or replace table t2( + x int, + sys_start $sys_datatype_expl as row start, + sys_end $sys_datatype_expl as row end references t1(id), + period for system_time(sys_start, sys_end) +) engine innodb with system versioning; +--replace_result $sys_datatype_expl SYS_DATATYPE +--error ER_CANT_CREATE_TABLE +eval create or replace table t2( + x int, + sys_start $sys_datatype_expl as row start, + sys_end $sys_datatype_expl as row end, + period for system_time(sys_start, sys_end), + foreign key (sys_start) references t1(id) +) engine innodb with system versioning; +--replace_result $sys_datatype_expl SYS_DATATYPE +--error ER_CANT_CREATE_TABLE +eval create or replace table t2( + x int, + sys_start $sys_datatype_expl as row start, + sys_end $sys_datatype_expl as row end, + period for system_time(sys_start, sys_end), + foreign key (sys_end) references t1(id) +) engine innodb with system versioning; +drop table t1; + --source suite/versioning/common_finish.inc diff --git a/sql/sql_lex.cc b/sql/sql_lex.cc index a7e6ecd3387..7ff3e8f6a75 100644 --- a/sql/sql_lex.cc +++ b/sql/sql_lex.cc @@ -11168,3 +11168,71 @@ sp_condition_value *LEX::stmt_signal_value(const Lex_ident_sys_st &ident) } return cond; } + + +bool LEX::add_table_foreign_key(const LEX_CSTRING *name, + const LEX_CSTRING *constraint_name, + Table_ident *ref_table_name, + DDL_options ddl_options) +{ + Key *key= new (thd->mem_root) Foreign_key(name, + &last_key->columns, + constraint_name, + &ref_table_name->db, + &ref_table_name->table, + &ref_list, + fk_delete_opt, + fk_update_opt, + fk_match_option, + ddl_options); + if (unlikely(key == NULL)) + return true; + + /* + handle_if_exists_options() expects the two keys in this order: + the Foreign_key, followed by its auto-generated Key. + */ + alter_info.key_list.push_back(key, thd->mem_root); + alter_info.key_list.push_back(last_key, thd->mem_root); + + option_list= NULL; + + /* Only used for ALTER TABLE. Ignored otherwise. */ + alter_info.flags|= ALTER_ADD_FOREIGN_KEY; + + return false; +} + + +bool LEX::add_column_foreign_key(const LEX_CSTRING *name, + const LEX_CSTRING *constraint_name, + Table_ident *ref_table_name, + DDL_options ddl_options) +{ + if (last_field->vcol_info || last_field->vers_sys_field()) + { + thd->parse_error(); + return true; + } + if (unlikely(!(last_key= (new (thd->mem_root) + Key(Key::MULTIPLE, constraint_name, + HA_KEY_ALG_UNDEF, true, ddl_options))))) + return true; + Key_part_spec *key= new (thd->mem_root) Key_part_spec(name, 0); + if (unlikely(key == NULL)) + return true; + last_key->columns.push_back(key, thd->mem_root); + if (ref_list.is_empty()) + { + ref_list.push_back(key, thd->mem_root); + } + if (unlikely(add_table_foreign_key(constraint_name, constraint_name, + ref_table_name, ddl_options))) + return true; + option_list= NULL; + + /* Only used for ALTER TABLE. Ignored otherwise. */ + alter_info.flags|= ALTER_ADD_FOREIGN_KEY; + + return false; +} diff --git a/sql/sql_lex.h b/sql/sql_lex.h index 4abc7dde940..0c3108e8ebe 100644 --- a/sql/sql_lex.h +++ b/sql/sql_lex.h @@ -4613,6 +4613,15 @@ public: const LEX_CSTRING &name); void mark_first_table_as_inserting(); + + bool add_table_foreign_key(const LEX_CSTRING *name, + const LEX_CSTRING *constraint_name, + Table_ident *table_name, + DDL_options ddl_options); + bool add_column_foreign_key(const LEX_CSTRING *name, + const LEX_CSTRING *constraint_name, + Table_ident *ref_table_name, + DDL_options ddl_options); }; diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy index 448e2b4c152..92f62ac98b8 100644 --- a/sql/sql_yacc.yy +++ b/sql/sql_yacc.yy @@ -5713,8 +5713,13 @@ field_list_item: column_def: field_spec { $$= $1; } - | field_spec references - { $$= $1; } + | field_spec opt_constraint references + { + if (unlikely(Lex->add_column_foreign_key(&($1->field_name), &$2, + $3, DDL_options()))) + MYSQL_YYABORT; + $$= $1; + } ; key_def: @@ -5775,30 +5780,9 @@ key_def: } '(' key_list ')' references { - LEX *lex=Lex; - Key *key= (new (thd->mem_root) - Foreign_key($5.str ? &$5 : &$1, - &lex->last_key->columns, - $1.str ? &$1 : &$5, - &$10->db, - &$10->table, - &lex->ref_list, - lex->fk_delete_opt, - lex->fk_update_opt, - lex->fk_match_option, - $4)); - if (unlikely(key == NULL)) - MYSQL_YYABORT; - /* - handle_if_exists_options() expectes the two keys in this order: - the Foreign_key, followed by its auto-generated Key. - */ - lex->alter_info.key_list.push_back(key, thd->mem_root); - lex->alter_info.key_list.push_back(Lex->last_key, thd->mem_root); - lex->option_list= NULL; - - /* Only used for ALTER TABLE. Ignored otherwise. */ - lex->alter_info.flags|= ALTER_ADD_FOREIGN_KEY; + if (unlikely(Lex->add_table_foreign_key($5.str ? &$5 : &$1, + $1.str ? &$1 : &$5, $10, $4))) + MYSQL_YYABORT; } ; diff --git a/sql/sql_yacc_ora.yy b/sql/sql_yacc_ora.yy index f066e33e6e0..5eb6ac52a96 100644 --- a/sql/sql_yacc_ora.yy +++ b/sql/sql_yacc_ora.yy @@ -5712,8 +5712,13 @@ field_list_item: column_def: field_spec { $$= $1; } - | field_spec references - { $$= $1; } + | field_spec opt_constraint references + { + if (unlikely(Lex->add_column_foreign_key(&($1->field_name), &$2, + $3, DDL_options()))) + MYSQL_YYABORT; + $$= $1; + } ; key_def: @@ -5774,30 +5779,9 @@ key_def: } '(' key_list ')' references { - LEX *lex=Lex; - Key *key= (new (thd->mem_root) - Foreign_key($5.str ? &$5 : &$1, - &lex->last_key->columns, - $1.str ? &$1 : &$5, - &$10->db, - &$10->table, - &lex->ref_list, - lex->fk_delete_opt, - lex->fk_update_opt, - lex->fk_match_option, - $4)); - if (unlikely(key == NULL)) - MYSQL_YYABORT; - /* - handle_if_exists_options() expectes the two keys in this order: - the Foreign_key, followed by its auto-generated Key. - */ - lex->alter_info.key_list.push_back(key, thd->mem_root); - lex->alter_info.key_list.push_back(Lex->last_key, thd->mem_root); - lex->option_list= NULL; - - /* Only used for ALTER TABLE. Ignored otherwise. */ - lex->alter_info.flags|= ALTER_ADD_FOREIGN_KEY; + if (unlikely(Lex->add_table_foreign_key($5.str ? &$5 : &$1, + $1.str ? &$1 : &$5, $10, $4))) + MYSQL_YYABORT; } ; |