Commit 4fde1361 authored by Marko Mäkelä's avatar Marko Mäkelä

MDEV-15553 Assertion failed in dict_table_get_col_name

dict_foreign_qualify_index(): Avoid a redundant and harmful
computation of col_name of a virtual column. This fixes the
assertion failure.

dict_foreign_push_index_error(): Do not call dict_table_get_col_name()
on a virtual column. (It is unclear if this condition is actually
reachable.)
parent bc250145
......@@ -688,3 +688,55 @@ SELECT f1, f3 FROM t2;
f1 f3
3 2
DROP TABLE t2, t1;
#
# MDEV-15553 Assertion failed in dict_table_get_col_name
#
CREATE TABLE t1 (
c1 TIMESTAMP,
c2 YEAR,
c3 TIME,
c4 CHAR(10),
v1 TIMESTAMP AS (c1) VIRTUAL,
v2 YEAR AS (c2) VIRTUAL,
v3 TIME AS (c3) VIRTUAL,
v4 CHAR(10) AS (c4) VIRTUAL
) ENGINE=InnoDB;
ALTER TABLE t1 ADD CONSTRAINT fk FOREIGN KEY (v4) REFERENCES nosuch(col);
ERROR HY000: Can't create table `test`.`#sql-temporary` (errno: 150 "Foreign key constraint is incorrectly formed")
SET foreign_key_checks=0;
ALTER TABLE t1 ADD CONSTRAINT fk FOREIGN KEY (v4) REFERENCES nosuch(col);
ERROR HY000: Failed to add the foreign key constaint. Missing index for constraint 'fk' in the foreign table 't1'
ALTER TABLE t1 ADD INDEX(v4);
ALTER TABLE t1 ADD CONSTRAINT fk FOREIGN KEY (v4) REFERENCES nosuch(col);
SET foreign_key_checks=1;
SHOW CREATE TABLE t1;
Table Create Table
t1 CREATE TABLE `t1` (
`c1` timestamp NOT NULL DEFAULT current_timestamp() ON UPDATE current_timestamp(),
`c2` year(4) DEFAULT NULL,
`c3` time DEFAULT NULL,
`c4` char(10) DEFAULT NULL,
`v1` timestamp GENERATED ALWAYS AS (`c1`) VIRTUAL,
`v2` year(4) GENERATED ALWAYS AS (`c2`) VIRTUAL,
`v3` time GENERATED ALWAYS AS (`c3`) VIRTUAL,
`v4` char(10) GENERATED ALWAYS AS (`c4`) VIRTUAL,
KEY `v4` (`v4`),
CONSTRAINT `fk` FOREIGN KEY (`v4`) REFERENCES `nosuch` (`col`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1
ALTER TABLE t1 DROP FOREIGN KEY fk;
ALTER TABLE t1 ADD CONSTRAINT fk FOREIGN KEY (v4) REFERENCES nosuch(col);
ERROR HY000: Can't create table `test`.`#sql-temporary` (errno: 150 "Foreign key constraint is incorrectly formed")
SHOW CREATE TABLE t1;
Table Create Table
t1 CREATE TABLE `t1` (
`c1` timestamp NOT NULL DEFAULT current_timestamp() ON UPDATE current_timestamp(),
`c2` year(4) DEFAULT NULL,
`c3` time DEFAULT NULL,
`c4` char(10) DEFAULT NULL,
`v1` timestamp GENERATED ALWAYS AS (`c1`) VIRTUAL,
`v2` year(4) GENERATED ALWAYS AS (`c2`) VIRTUAL,
`v3` time GENERATED ALWAYS AS (`c3`) VIRTUAL,
`v4` char(10) GENERATED ALWAYS AS (`c4`) VIRTUAL,
KEY `v4` (`v4`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1
DROP TABLE t1;
......@@ -576,3 +576,34 @@ UPDATE t1 SET f1 = 3;
EXPLAIN SELECT f1, f3 FROM t2;
SELECT f1, f3 FROM t2;
DROP TABLE t2, t1;
--echo #
--echo # MDEV-15553 Assertion failed in dict_table_get_col_name
--echo #
CREATE TABLE t1 (
c1 TIMESTAMP,
c2 YEAR,
c3 TIME,
c4 CHAR(10),
v1 TIMESTAMP AS (c1) VIRTUAL,
v2 YEAR AS (c2) VIRTUAL,
v3 TIME AS (c3) VIRTUAL,
v4 CHAR(10) AS (c4) VIRTUAL
) ENGINE=InnoDB;
--replace_regex /#sql-[0-9a-f_]*/#sql-temporary/
--error ER_CANT_CREATE_TABLE
ALTER TABLE t1 ADD CONSTRAINT fk FOREIGN KEY (v4) REFERENCES nosuch(col);
SET foreign_key_checks=0;
--error ER_FK_NO_INDEX_CHILD
ALTER TABLE t1 ADD CONSTRAINT fk FOREIGN KEY (v4) REFERENCES nosuch(col);
ALTER TABLE t1 ADD INDEX(v4);
ALTER TABLE t1 ADD CONSTRAINT fk FOREIGN KEY (v4) REFERENCES nosuch(col);
SET foreign_key_checks=1;
SHOW CREATE TABLE t1;
ALTER TABLE t1 DROP FOREIGN KEY fk;
--replace_regex /#sql-[0-9a-f_]*/#sql-temporary/
--error ER_CANT_CREATE_TABLE
ALTER TABLE t1 ADD CONSTRAINT fk FOREIGN KEY (v4) REFERENCES nosuch(col);
SHOW CREATE TABLE t1;
# Cleanup
DROP TABLE t1;
......@@ -4401,8 +4401,10 @@ dict_foreign_push_index_error(
const char* col_name;
field = dict_index_get_nth_field(err_index, err_col);
col_name = dict_table_get_col_name(
table, dict_col_get_no(field->col));
col_name = dict_col_is_virtual(field->col)
? "(null)"
: dict_table_get_col_name(
table, dict_col_get_no(field->col));
fprintf(ef,
"%s table %s with foreign key constraint"
" failed. Field type or character set for column '%s' "
......@@ -6982,10 +6984,6 @@ dict_foreign_qualify_index(
return(false);
}
col_name = col_names
? col_names[col_no]
: dict_table_get_col_name(table, col_no);
if (dict_col_is_virtual(field->col)) {
for (ulint j = 0; j < table->n_v_def; j++) {
col_name = dict_table_get_v_col_name(table, j);
......@@ -6993,6 +6991,10 @@ dict_foreign_qualify_index(
break;
}
}
} else {
col_name = col_names
? col_names[col_no]
: dict_table_get_col_name(table, col_no);
}
if (0 != innobase_strcasecmp(columns[i], col_name)) {
......
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