Commit 7ae12371 authored by Marko Mäkelä's avatar Marko Mäkelä

MDEV-22817 Assertion idlen <= MAX_TABLE_NAME_LEN in create_table_info_t::create_foreign_keys()

create_table_info_t::create_foreign_keys(): Make the create_name buffer
long enough for both the database and table name. It is still not long
enough to hold partition or subpartition names. Because we do never
supported FOREIGN KEY constraints on partitions, we can simply skip
the call to innobase_convert_name() on CREATE TABLE.
parent a08a8bc1
...@@ -25,4 +25,45 @@ SUBPARTITIONS 2 ( ...@@ -25,4 +25,45 @@ SUBPARTITIONS 2 (
PARTITION çççççççççççççççççççççççççççççççççççççççççççççççççççççççççççç VALUES LESS THAN (1000) ENGINE = InnoDB, PARTITION çççççççççççççççççççççççççççççççççççççççççççççççççççççççççççç VALUES LESS THAN (1000) ENGINE = InnoDB,
PARTITION pmax VALUES LESS THAN MAXVALUE ENGINE = InnoDB); PARTITION pmax VALUES LESS THAN MAXVALUE ENGINE = InnoDB);
ERROR HY000: The path specified for @0n@0n@0n@0n@0n@0n@0n@0n@0n@0n@0n@0n@0n@0n@0n@0n@0n@0n@0n@0n@... is too long ERROR HY000: The path specified for @0n@0n@0n@0n@0n@0n@0n@0n@0n@0n@0n@0n@0n@0n@0n@0n@0n@0n@0n@0n@... is too long
SET @file_per_table=@@GLOBAL.innodb_file_per_table;
SET GLOBAL innodb_file_per_table=0;
CREATE TABLE mysqltest1.t1 (a INT) ENGINE=INNODB
PARTITION BY RANGE (a) SUBPARTITION BY HASH(a)
(PARTITION `$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$`
VALUES LESS THAN (10)
(SUBPARTITION
`--------------------------abcdef0123456789abcdef0123456789abcdef`,
SUBPARTITION
`0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef`)
);
SET GLOBAL innodb_file_per_table=@file_per_table;
SHOW CREATE TABLE mysqltest1.t1;
Table Create Table
t1 CREATE TABLE `t1` (
`a` int(11) DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=latin1
PARTITION BY RANGE (`a`)
SUBPARTITION BY HASH (`a`)
(PARTITION `$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$` VALUES LESS THAN (10)
(SUBPARTITION `--------------------------abcdef0123456789abcdef0123456789abcdef` ENGINE = InnoDB,
SUBPARTITION `0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef` ENGINE = InnoDB))
INSERT INTO mysqltest1.t1 VALUES(1);
DROP TABLE mysqltest1.`#mysql50#t1#P#@0024@0024@0024@0024@0024@0024@0024@0024@0024@0024@0024@0024@0024@0024@0024@0024@0024@0024@0024@0024@0024@0024@0024@0024@0024@0024@0024@0024@0024@0024@0024@0024@0024@0024@0024@0024@0024@0024@0024@0024@0024@0024@0024@0024@0024@0024@0024@0024@0024@0024@0024@0024@0024@0024@0024@0024@0024@0024@0024@0024@0024@0024@0024@0024#SP#0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef`;
ERROR 42000: Incorrect table name '#mysql50#t1#P#@0024@0024@0024@0024@0024@0024@0024@0024@0024@0024@0024@0024@0024@0024@0024@0024@0024@'
ALTER TABLE mysqltest1.t1 ADD FOREIGN KEY (a) REFERENCES
mysqltest1.test_jfg_table_name_with_64_chars_123456789012345678901234567890;
ERROR HY000: Partitioned tables do not support FOREIGN KEY
ALTER TABLE
mysqltest1.test_jfg_table_name_with_64_chars_123456789012345678901234567890
ADD FOREIGN KEY (a) REFERENCES mysqltest1.t1;
ERROR HY000: Partitioned tables do not support FOREIGN KEY
SELECT NAME FROM INFORMATION_SCHEMA.INNODB_SYS_TABLES
WHERE NAME LIKE 'mysqltest1%';
NAME
mysqltest1/t1#P#@0024@0024@0024@0024@0024@0024@0024@0024@0024@0024@0024@0024@0024@0024@0024@0024@0024@0024@0024@0024@0024@0024@0024@0024@0024@0024@0024@0024@0024@0024@0024@0024@0024@0024@0024@0024@0024@0024@0024@0024@0024@0024@0024@0024@0024@0024@0024@0024@0024@0024@0024@0024@0024@0024@0024@0024@0024@0024@0024@0024@0024@0024@0024@0024#SP#0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef
mysqltest1/t1#P#@0024@0024@0024@0024@0024@0024@0024@0024@0024@0024@0024@0024@0024@0024@0024@0024@0024@0024@0024@0024@0024@0024@0024@0024@0024@0024@0024@0024@0024@0024@0024@0024@0024@0024@0024@0024@0024@0024@0024@0024@0024@0024@0024@0024@0024@0024@0024@0024@0024@0024@0024@0024@0024@0024@0024@0024@0024@0024@0024@0024@0024@0024@0024@0024#SP#@002d@002d@002d@002d@002d@002d@002d@002d@002d@002d@002d@002d@002d@002d@002d@002d@002d@002d@002d@002d@002d@002d@002d@002d@002d@002dabcdef0123456789abcdef0123456789abcdef
mysqltest1/test_jfg_table_name_with_64_chars_123456789012345678901234567890#P#pmax#SP#pmaxsp0
mysqltest1/test_jfg_table_name_with_64_chars_123456789012345678901234567890#P#pmax#SP#pmaxsp1
mysqltest1/test_jfg_table_name_with_64_chars_123456789012345678901234567890#P#test_jfg_partition_name_with_60_chars_1234567890123456789012#SP#test_jfg_partition_name_with_60_chars_1234567890123456789012sp0
mysqltest1/test_jfg_table_name_with_64_chars_123456789012345678901234567890#P#test_jfg_partition_name_with_60_chars_1234567890123456789012#SP#test_jfg_partition_name_with_60_chars_1234567890123456789012sp1
drop database mysqltest1; drop database mysqltest1;
source include/have_innodb.inc; source include/have_innodb.inc;
source include/have_partition.inc; source include/have_partition.inc;
# The absolute path names in the embedded server hit the limit earlier.
source include/not_embedded.inc;
set names utf8; set names utf8;
create database mysqltest1; create database mysqltest1;
...@@ -29,4 +31,36 @@ PARTITION BY RANGE ( id ) ...@@ -29,4 +31,36 @@ PARTITION BY RANGE ( id )
PARTITION çççççççççççççççççççççççççççççççççççççççççççççççççççççççççççç VALUES LESS THAN (1000) ENGINE = InnoDB, PARTITION çççççççççççççççççççççççççççççççççççççççççççççççççççççççççççç VALUES LESS THAN (1000) ENGINE = InnoDB,
PARTITION pmax VALUES LESS THAN MAXVALUE ENGINE = InnoDB); PARTITION pmax VALUES LESS THAN MAXVALUE ENGINE = InnoDB);
SET @file_per_table=@@GLOBAL.innodb_file_per_table;
SET GLOBAL innodb_file_per_table=0;
CREATE TABLE mysqltest1.t1 (a INT) ENGINE=INNODB
PARTITION BY RANGE (a) SUBPARTITION BY HASH(a)
(PARTITION `$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$`
VALUES LESS THAN (10)
(SUBPARTITION
`--------------------------abcdef0123456789abcdef0123456789abcdef`,
SUBPARTITION
`0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef`)
);
SET GLOBAL innodb_file_per_table=@file_per_table;
SHOW CREATE TABLE mysqltest1.t1;
INSERT INTO mysqltest1.t1 VALUES(1);
--error ER_WRONG_TABLE_NAME
DROP TABLE mysqltest1.`#mysql50#t1#P#@0024@0024@0024@0024@0024@0024@0024@0024@0024@0024@0024@0024@0024@0024@0024@0024@0024@0024@0024@0024@0024@0024@0024@0024@0024@0024@0024@0024@0024@0024@0024@0024@0024@0024@0024@0024@0024@0024@0024@0024@0024@0024@0024@0024@0024@0024@0024@0024@0024@0024@0024@0024@0024@0024@0024@0024@0024@0024@0024@0024@0024@0024@0024@0024#SP#0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef`;
--error ER_FEATURE_NOT_SUPPORTED_WITH_PARTITIONING
ALTER TABLE mysqltest1.t1 ADD FOREIGN KEY (a) REFERENCES
mysqltest1.test_jfg_table_name_with_64_chars_123456789012345678901234567890;
--error ER_FEATURE_NOT_SUPPORTED_WITH_PARTITIONING
ALTER TABLE
mysqltest1.test_jfg_table_name_with_64_chars_123456789012345678901234567890
ADD FOREIGN KEY (a) REFERENCES mysqltest1.t1;
SELECT NAME FROM INFORMATION_SCHEMA.INNODB_SYS_TABLES
WHERE NAME LIKE 'mysqltest1%';
drop database mysqltest1; drop database mysqltest1;
...@@ -12159,7 +12159,8 @@ create_table_info_t::create_foreign_keys() ...@@ -12159,7 +12159,8 @@ create_table_info_t::create_foreign_keys()
static const unsigned MAX_COLS_PER_FK = 500; static const unsigned MAX_COLS_PER_FK = 500;
const char* column_names[MAX_COLS_PER_FK]; const char* column_names[MAX_COLS_PER_FK];
const char* ref_column_names[MAX_COLS_PER_FK]; const char* ref_column_names[MAX_COLS_PER_FK];
char create_name[MAX_TABLE_NAME_LEN + 1]; char create_name[MAX_DATABASE_NAME_LEN + 1 +
MAX_TABLE_NAME_LEN + 1];
dict_index_t* index = NULL; dict_index_t* index = NULL;
fkerr_t index_error = FK_SUCCESS; fkerr_t index_error = FK_SUCCESS;
dict_index_t* err_index = NULL; dict_index_t* err_index = NULL;
...@@ -12199,14 +12200,18 @@ create_table_info_t::create_foreign_keys() ...@@ -12199,14 +12200,18 @@ create_table_info_t::create_foreign_keys()
} }
char* bufend = innobase_convert_name( char* bufend = innobase_convert_name(
create_name, MAX_TABLE_NAME_LEN, n, strlen(n), m_thd); create_name, sizeof create_name, n, strlen(n), m_thd);
create_name[bufend - create_name] = '\0'; create_name[bufend - create_name] = '\0';
number = highest_id_so_far + 1; number = highest_id_so_far + 1;
mem_heap_free(heap); mem_heap_free(heap);
operation = "Alter "; operation = "Alter ";
} else if (strstr(name, "#P#") || strstr(name, "#p#")) {
/* Partitioned table */
create_name[0] = '\0';
} else { } else {
char* bufend = innobase_convert_name(create_name, char* bufend = innobase_convert_name(create_name,
MAX_TABLE_NAME_LEN, name, sizeof create_name,
name,
strlen(name), m_thd); strlen(name), m_thd);
create_name[bufend - create_name] = '\0'; create_name[bufend - create_name] = '\0';
} }
...@@ -12240,6 +12245,9 @@ create_table_info_t::create_foreign_keys() ...@@ -12240,6 +12245,9 @@ create_table_info_t::create_foreign_keys()
m_form->s->table_name.str); m_form->s->table_name.str);
return (DB_CANNOT_ADD_CONSTRAINT); return (DB_CANNOT_ADD_CONSTRAINT);
} else if (!*create_name) {
ut_ad("should be unreachable" == 0);
return DB_CANNOT_ADD_CONSTRAINT;
} }
Foreign_key* fk = static_cast<Foreign_key*>(key); Foreign_key* fk = static_cast<Foreign_key*>(key);
......
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