MDEV-16201 CREATE TABLE creates extra transaction

InnoDB does not allow FOREIGN KEY constraints to exist for TEMPORARY TABLE.
InnoDB introduced a dedicated tablespace for temporary tables, and actually
stopped creating persistent metadata and data for temporary tables.

row_table_add_foreign_constraints(): Do not create a persistent
transaction.

dict_create_foreign_constraints_low(): Add the persistent transaction to
the update the foreign key relation in dictionary.

dict_create_foreign_constraints_low(): Remove a duplicated check for
partitioned tables.
parent 15425767
CREATE TABLE t1(a INT, b VARCHAR(10), INDEX(a))ENGINE=InnoDB
PARTITION BY RANGE(a)
(PARTITION pa VALUES LESS THAN (3),
PARTITION pb VALUES LESS THAN (5));
CREATE TABLE t2(a INT, FOREIGN KEY(a) REFERENCES t1(a))ENGINE=INNODB
PARTITION BY RANGE(a)
(PARTITION pa VALUES LESS THAN (2),
PARTITION pb VALUES LESS THAN (4));
ERROR HY000: Foreign key clause is not yet supported in conjunction with partitioning
DROP TABLE t1;
......@@ -650,3 +650,11 @@ SELECT * FROM t1;
f1
0
DROP TABLE t1;
#
# MDEV-15874 CREATE TABLE creates extra transaction
#
call mtr.add_suppression("Warning 150 Create table `mysqld.1`.`t1` with foreign key constraint failed. Temporary tables can't have foreign key constraints.*");
SET FOREIGN_KEY_CHECKS = 0;
CREATE TEMPORARY TABLE t1(f1 INT NOT NULL,
FOREIGN KEY(f1) REFERENCES t0(f1))ENGINE=InnoDB;
ERROR HY000: Can't create table `test`.`t1` (errno: 150 "Foreign key constraint is incorrectly formed")
--source include/have_innodb.inc
--source include/have_partition.inc
CREATE TABLE t1(a INT, b VARCHAR(10), INDEX(a))ENGINE=InnoDB
PARTITION BY RANGE(a)
(PARTITION pa VALUES LESS THAN (3),
PARTITION pb VALUES LESS THAN (5));
--error ER_FOREIGN_KEY_ON_PARTITIONED
CREATE TABLE t2(a INT, FOREIGN KEY(a) REFERENCES t1(a))ENGINE=INNODB
PARTITION BY RANGE(a)
(PARTITION pa VALUES LESS THAN (2),
PARTITION pb VALUES LESS THAN (4));
DROP TABLE t1;
......@@ -476,3 +476,12 @@ UPDATE t1 SET f1 = 0;
ROLLBACK;
SELECT * FROM t1;
DROP TABLE t1;
--echo #
--echo # MDEV-15874 CREATE TABLE creates extra transaction
--echo #
call mtr.add_suppression("Warning 150 Create table `mysqld.1`.`t1` with foreign key constraint failed. Temporary tables can't have foreign key constraints.*");
SET FOREIGN_KEY_CHECKS = 0;
--error ER_CANT_CREATE_TABLE
CREATE TEMPORARY TABLE t1(f1 INT NOT NULL,
FOREIGN KEY(f1) REFERENCES t0(f1))ENGINE=InnoDB;
......@@ -4635,6 +4635,11 @@ dict_create_foreign_constraints_low(
/**********************************************************/
/* The following call adds the foreign key constraints
to the data dictionary system tables on disk */
trx->op_info = "adding foreign keys";
trx_start_if_not_started_xa(trx, true);
trx_set_dict_operation(trx, TRX_DICT_OP_TABLE);
error = dict_create_add_foreigns_to_dictionary(
local_fk_set, table, trx);
......@@ -4849,23 +4854,6 @@ dict_create_foreign_constraints_low(
return(DB_CANNOT_ADD_CONSTRAINT);
}
/* Don't allow foreign keys on partitioned tables yet. */
ptr1 = dict_scan_to(ptr, "PARTITION");
if (ptr1) {
ptr1 = dict_accept(cs, ptr1, "PARTITION", &success);
if (success && my_isspace(cs, *ptr1)) {
ptr2 = dict_accept(cs, ptr1, "BY", &success);
if (success) {
my_error(ER_FOREIGN_KEY_ON_PARTITIONED,MYF(0));
return(DB_CANNOT_ADD_CONSTRAINT);
}
}
}
if (dict_table_is_partition(table)) {
my_error(ER_FOREIGN_KEY_ON_PARTITIONED,MYF(0));
return(DB_CANNOT_ADD_CONSTRAINT);
}
/* Let us create a constraint struct */
foreign = dict_mem_foreign_create();
......
......@@ -2651,12 +2651,6 @@ row_table_add_foreign_constraints(
ut_ad(rw_lock_own(dict_operation_lock, RW_LOCK_X));
ut_a(sql_string);
trx->op_info = "adding foreign keys";
trx_start_if_not_started_xa(trx, true);
trx_set_dict_operation(trx, TRX_DICT_OP_TABLE);
err = dict_create_foreign_constraints(
trx, sql_string, sql_length, name, reject_fks);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment