summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAleksey Midenkov <midenok@gmail.com>2019-11-20 13:18:54 +0300
committerAleksey Midenkov <midenok@gmail.com>2019-11-20 13:18:54 +0300
commitdaabc5cc68440fe7871b7c570e114a6a0d119bfb (patch)
tree00b3e0b5802d54326e2c9987c40d40ef1a459b1e
parent5130f5206c150ba1e8a723aae63884ff64408012 (diff)
downloadmariadb-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.
m---------libmariadb0
-rw-r--r--mysql-test/main/foreign_key.result2
-rw-r--r--mysql-test/main/foreign_key.test2
-rw-r--r--mysql-test/suite/funcs_1/r/is_statistics.result1
-rw-r--r--mysql-test/suite/funcs_1/r/is_statistics_mysql.result1
-rw-r--r--mysql-test/suite/funcs_1/r/is_statistics_mysql_embedded.result2
-rw-r--r--mysql-test/suite/gcol/inc/gcol_column_def_options.inc6
-rw-r--r--mysql-test/suite/gcol/r/gcol_column_def_options_innodb.result4
-rw-r--r--mysql-test/suite/gcol/r/gcol_column_def_options_myisam.result4
-rw-r--r--mysql-test/suite/innodb/r/foreign_key.result44
-rw-r--r--mysql-test/suite/innodb/t/foreign_key.test23
-rw-r--r--mysql-test/suite/vcol/inc/vcol_column_def_options.inc6
-rw-r--r--mysql-test/suite/vcol/r/vcol_column_def_options_innodb.result6
-rw-r--r--mysql-test/suite/vcol/r/vcol_column_def_options_myisam.result6
-rw-r--r--mysql-test/suite/versioning/r/foreign.result38
-rw-r--r--mysql-test/suite/versioning/t/foreign.test43
-rw-r--r--sql/sql_lex.cc68
-rw-r--r--sql/sql_lex.h9
-rw-r--r--sql/sql_yacc.yy36
-rw-r--r--sql/sql_yacc_ora.yy36
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;
}
;