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; ...@@ -688,3 +688,55 @@ SELECT f1, f3 FROM t2;
f1 f3 f1 f3
3 2 3 2
DROP TABLE t2, t1; 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; ...@@ -576,3 +576,34 @@ UPDATE t1 SET f1 = 3;
EXPLAIN SELECT f1, f3 FROM t2; EXPLAIN SELECT f1, f3 FROM t2;
SELECT f1, f3 FROM t2; SELECT f1, f3 FROM t2;
DROP TABLE t2, t1; 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( ...@@ -4401,8 +4401,10 @@ dict_foreign_push_index_error(
const char* col_name; const char* col_name;
field = dict_index_get_nth_field(err_index, err_col); field = dict_index_get_nth_field(err_index, err_col);
col_name = dict_table_get_col_name( col_name = dict_col_is_virtual(field->col)
table, dict_col_get_no(field->col)); ? "(null)"
: dict_table_get_col_name(
table, dict_col_get_no(field->col));
fprintf(ef, fprintf(ef,
"%s table %s with foreign key constraint" "%s table %s with foreign key constraint"
" failed. Field type or character set for column '%s' " " failed. Field type or character set for column '%s' "
...@@ -6982,10 +6984,6 @@ dict_foreign_qualify_index( ...@@ -6982,10 +6984,6 @@ dict_foreign_qualify_index(
return(false); 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)) { if (dict_col_is_virtual(field->col)) {
for (ulint j = 0; j < table->n_v_def; j++) { for (ulint j = 0; j < table->n_v_def; j++) {
col_name = dict_table_get_v_col_name(table, j); col_name = dict_table_get_v_col_name(table, j);
...@@ -6993,6 +6991,10 @@ dict_foreign_qualify_index( ...@@ -6993,6 +6991,10 @@ dict_foreign_qualify_index(
break; 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)) { 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