summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlexander Barkov <bar@mariadb.com>2019-08-29 12:35:19 +0400
committerAlexander Barkov <bar@mariadb.com>2019-09-03 09:51:35 +0400
commitef00ac4c86daf3294c46a45358da636763fb0049 (patch)
tree833c4c4696dfe423eea4531b436b5080a0cb6077
parentdc719597ee0b11da722e9813639e8b48018a8c10 (diff)
downloadmariadb-git-ef00ac4c86daf3294c46a45358da636763fb0049.tar.gz
Part2: MDEV-18156 Assertion `0' failed or `btr_validate_index(index, 0, false)' in row_upd_sec_index_entry or error code 126: Index is corrupted upon DELETE with PAD_CHAR_TO_FULL_LENGTH
This patch allows the server to open old tables that have "bad" generated columns (i.e. indexed virtual generated columns, persistent generated columns) that depend on sql_mode, for general things like SELECT, INSERT, DROP, etc. Warning are issued in such cases. Only these commands are now disallowed and return an error: - CREATE TABLE introducing a "bad" generated column - ALTER TABLE introducing a "bad" generated column - CREATE INDEX introdicing a "bad" generated column (i.e. adding an index on a virtual generated column that depends on sql_mode). Note, these commands are allowed: - ALTER TABLE removing a "bad" generate column - ALTER TABLE removing an index from a "bad" virtual generated column - DROP INDEX removing an index from a "bad" virtual generated column but only if the table does not have any "bad" columns as a result.
-rw-r--r--mysql-test/std_data/vcol_upgrade/maria100226_char_to_vchar_stored.MYDbin0 -> 60 bytes
-rw-r--r--mysql-test/std_data/vcol_upgrade/maria100226_char_to_vchar_stored.MYIbin0 -> 1024 bytes
-rw-r--r--mysql-test/std_data/vcol_upgrade/maria100226_char_to_vchar_stored.frmbin0 -> 483 bytes
-rw-r--r--mysql-test/std_data/vcol_upgrade/maria100226_char_to_vchar_virtual.MYDbin0 -> 60 bytes
-rw-r--r--mysql-test/std_data/vcol_upgrade/maria100226_char_to_vchar_virtual.MYIbin0 -> 2048 bytes
-rw-r--r--mysql-test/std_data/vcol_upgrade/maria100226_char_to_vchar_virtual.frmbin0 -> 972 bytes
-rw-r--r--mysql-test/suite/vcol/r/vcol_sql_mode.result6
-rw-r--r--mysql-test/suite/vcol/r/vcol_sql_mode_upgrade.result336
-rw-r--r--mysql-test/suite/vcol/t/vcol_sql_mode.test3
-rw-r--r--mysql-test/suite/vcol/t/vcol_sql_mode_upgrade.test193
-rw-r--r--sql/field.cc13
-rw-r--r--sql/field.h5
-rw-r--r--sql/sql_insert.cc3
-rw-r--r--sql/table.cc22
-rw-r--r--sql/table.h16
15 files changed, 585 insertions, 12 deletions
diff --git a/mysql-test/std_data/vcol_upgrade/maria100226_char_to_vchar_stored.MYD b/mysql-test/std_data/vcol_upgrade/maria100226_char_to_vchar_stored.MYD
new file mode 100644
index 00000000000..3b511e3b8fa
--- /dev/null
+++ b/mysql-test/std_data/vcol_upgrade/maria100226_char_to_vchar_stored.MYD
Binary files differ
diff --git a/mysql-test/std_data/vcol_upgrade/maria100226_char_to_vchar_stored.MYI b/mysql-test/std_data/vcol_upgrade/maria100226_char_to_vchar_stored.MYI
new file mode 100644
index 00000000000..b039d02f2e0
--- /dev/null
+++ b/mysql-test/std_data/vcol_upgrade/maria100226_char_to_vchar_stored.MYI
Binary files differ
diff --git a/mysql-test/std_data/vcol_upgrade/maria100226_char_to_vchar_stored.frm b/mysql-test/std_data/vcol_upgrade/maria100226_char_to_vchar_stored.frm
new file mode 100644
index 00000000000..85f142070e9
--- /dev/null
+++ b/mysql-test/std_data/vcol_upgrade/maria100226_char_to_vchar_stored.frm
Binary files differ
diff --git a/mysql-test/std_data/vcol_upgrade/maria100226_char_to_vchar_virtual.MYD b/mysql-test/std_data/vcol_upgrade/maria100226_char_to_vchar_virtual.MYD
new file mode 100644
index 00000000000..e770e42b6bf
--- /dev/null
+++ b/mysql-test/std_data/vcol_upgrade/maria100226_char_to_vchar_virtual.MYD
Binary files differ
diff --git a/mysql-test/std_data/vcol_upgrade/maria100226_char_to_vchar_virtual.MYI b/mysql-test/std_data/vcol_upgrade/maria100226_char_to_vchar_virtual.MYI
new file mode 100644
index 00000000000..aff7d10ce18
--- /dev/null
+++ b/mysql-test/std_data/vcol_upgrade/maria100226_char_to_vchar_virtual.MYI
Binary files differ
diff --git a/mysql-test/std_data/vcol_upgrade/maria100226_char_to_vchar_virtual.frm b/mysql-test/std_data/vcol_upgrade/maria100226_char_to_vchar_virtual.frm
new file mode 100644
index 00000000000..d7258bc4af3
--- /dev/null
+++ b/mysql-test/std_data/vcol_upgrade/maria100226_char_to_vchar_virtual.frm
Binary files differ
diff --git a/mysql-test/suite/vcol/r/vcol_sql_mode.result b/mysql-test/suite/vcol/r/vcol_sql_mode.result
index 50aec76cb8d..11b3400ee5e 100644
--- a/mysql-test/suite/vcol/r/vcol_sql_mode.result
+++ b/mysql-test/suite/vcol/r/vcol_sql_mode.result
@@ -400,6 +400,12 @@ SHOW WARNINGS;
Level Code Message
Error 1901 Function or expression '`c`' cannot be used in the GENERATED ALWAYS AS clause of `v`
Warning 1105 Expression depends on the @@sql_mode value PAD_CHAR_TO_FULL_LENGTH
+CREATE INDEX v ON t1 (v);
+ERROR HY000: Function or expression '`c`' cannot be used in the GENERATED ALWAYS AS clause of `v`
+SHOW WARNINGS;
+Level Code Message
+Error 1901 Function or expression '`c`' cannot be used in the GENERATED ALWAYS AS clause of `v`
+Warning 1105 Expression depends on the @@sql_mode value PAD_CHAR_TO_FULL_LENGTH
DROP TABLE t1;
# A virtual column on the second position in an index - cannot depend on sql_mode
CREATE TABLE t1 (id int, a CHAR(5), v TEXT AS (a) VIRTUAL, KEY(id, v(100)));
diff --git a/mysql-test/suite/vcol/r/vcol_sql_mode_upgrade.result b/mysql-test/suite/vcol/r/vcol_sql_mode_upgrade.result
new file mode 100644
index 00000000000..d3954770c7b
--- /dev/null
+++ b/mysql-test/suite/vcol/r/vcol_sql_mode_upgrade.result
@@ -0,0 +1,336 @@
+call mtr.add_suppression("Table rebuild required");
+#
+# Opening a Maria-10.2.26 table with a stored VARCHAR column
+#
+# Copying maria100226_char_to_vchar_stored.* to MYSQLD_DATADIR
+SHOW CREATE TABLE t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `a` char(5) DEFAULT NULL,
+ `v` varchar(5) GENERATED ALWAYS AS (`a`) STORED
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+Warnings:
+Warning 1901 Function or expression '`a`' cannot be used in the GENERATED ALWAYS AS clause of `v`
+Warning 1105 Expression depends on the @@sql_mode value PAD_CHAR_TO_FULL_LENGTH
+SHOW CREATE TABLE t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `a` char(5) DEFAULT NULL,
+ `v` varchar(5) GENERATED ALWAYS AS (`a`) STORED
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+FLUSH TABLES;
+SHOW CREATE TABLE t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `a` char(5) DEFAULT NULL,
+ `v` varchar(5) GENERATED ALWAYS AS (`a`) STORED
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+Warnings:
+Warning 1901 Function or expression '`a`' cannot be used in the GENERATED ALWAYS AS clause of `v`
+Warning 1105 Expression depends on the @@sql_mode value PAD_CHAR_TO_FULL_LENGTH
+FLUSH TABLES;
+SELECT * FROM t1;
+a v
+1 1
+2 2
+3 3
+Warnings:
+Warning 1901 Function or expression '`a`' cannot be used in the GENERATED ALWAYS AS clause of `v`
+Warning 1105 Expression depends on the @@sql_mode value PAD_CHAR_TO_FULL_LENGTH
+SELECT * FROM t1;
+a v
+1 1
+2 2
+3 3
+FLUSH TABLES;
+SELECT * FROM t1;
+a v
+1 1
+2 2
+3 3
+Warnings:
+Warning 1901 Function or expression '`a`' cannot be used in the GENERATED ALWAYS AS clause of `v`
+Warning 1105 Expression depends on the @@sql_mode value PAD_CHAR_TO_FULL_LENGTH
+CREATE TABLE t2 LIKE t1;
+ERROR HY000: Function or expression '`a`' cannot be used in the GENERATED ALWAYS AS clause of `v`
+FLUSH TABLES;
+CREATE TABLE t2 LIKE t1;
+ERROR HY000: Function or expression '`a`' cannot be used in the GENERATED ALWAYS AS clause of `v`
+SHOW CREATE TABLE t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `a` char(5) DEFAULT NULL,
+ `v` varchar(5) GENERATED ALWAYS AS (`a`) STORED
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+Warnings:
+Warning 1901 Function or expression '`a`' cannot be used in the GENERATED ALWAYS AS clause of `v`
+Warning 1105 Expression depends on the @@sql_mode value PAD_CHAR_TO_FULL_LENGTH
+ALTER TABLE t1 ADD b INT DEFAULT a;
+ERROR HY000: Function or expression '`a`' cannot be used in the GENERATED ALWAYS AS clause of `v`
+SHOW CREATE TABLE t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `a` char(5) DEFAULT NULL,
+ `v` varchar(5) GENERATED ALWAYS AS (`a`) STORED
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+SELECT * FROM t1;
+a v
+1 1
+2 2
+3 3
+FLUSH TABLES;
+ALTER TABLE t1 ADD c INT DEFAULT a;
+ERROR HY000: Function or expression '`a`' cannot be used in the GENERATED ALWAYS AS clause of `v`
+SELECT * FROM t1;
+a v
+1 1
+2 2
+3 3
+DROP TABLE t1;
+#
+# Fixing a Maria-10.2.26 table with a stored VARCHAR column
+#
+# Fixing by dropping the generated stored column
+# Copying maria100226_char_to_vchar_stored.* to MYSQLD_DATADIR
+ALTER TABLE t1 DROP v;
+Warnings:
+Warning 1901 Function or expression '`a`' cannot be used in the GENERATED ALWAYS AS clause of `v`
+Warning 1105 Expression depends on the @@sql_mode value PAD_CHAR_TO_FULL_LENGTH
+SELECT * FROM t1;
+a
+1
+2
+3
+DROP TABLE t1;
+# Fixing by altering the generation expression of the stored column
+# Copying maria100226_char_to_vchar_stored.* to MYSQLD_DATADIR
+SHOW CREATE TABLE t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `a` char(5) DEFAULT NULL,
+ `v` varchar(5) GENERATED ALWAYS AS (`a`) STORED
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+Warnings:
+Warning 1901 Function or expression '`a`' cannot be used in the GENERATED ALWAYS AS clause of `v`
+Warning 1105 Expression depends on the @@sql_mode value PAD_CHAR_TO_FULL_LENGTH
+ALTER TABLE t1 MODIFY v VARCHAR(5) AS (RTRIM(a)) PERSISTENT;
+SHOW CREATE TABLE t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `a` char(5) DEFAULT NULL,
+ `v` varchar(5) GENERATED ALWAYS AS (rtrim(`a`)) STORED
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+DROP TABLE t1;
+#
+# Opening a Maria-10.2.26 table with a virtual VARCHAR column
+#
+# Copying maria100226_char_to_vchar_virtual.* to MYSQLD_DATADIR
+SHOW CREATE TABLE t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `a` char(5) DEFAULT NULL,
+ `v` varchar(5) GENERATED ALWAYS AS (`a`) VIRTUAL,
+ KEY `v` (`v`)
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+Warnings:
+Warning 1901 Function or expression '`a`' cannot be used in the GENERATED ALWAYS AS clause of `v`
+Warning 1105 Expression depends on the @@sql_mode value PAD_CHAR_TO_FULL_LENGTH
+SHOW CREATE TABLE t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `a` char(5) DEFAULT NULL,
+ `v` varchar(5) GENERATED ALWAYS AS (`a`) VIRTUAL,
+ KEY `v` (`v`)
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+FLUSH TABLES;
+SHOW CREATE TABLE t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `a` char(5) DEFAULT NULL,
+ `v` varchar(5) GENERATED ALWAYS AS (`a`) VIRTUAL,
+ KEY `v` (`v`)
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+Warnings:
+Warning 1901 Function or expression '`a`' cannot be used in the GENERATED ALWAYS AS clause of `v`
+Warning 1105 Expression depends on the @@sql_mode value PAD_CHAR_TO_FULL_LENGTH
+FLUSH TABLES;
+SELECT * FROM t1;
+a v
+1 1
+2 2
+3 3
+Warnings:
+Warning 1901 Function or expression '`a`' cannot be used in the GENERATED ALWAYS AS clause of `v`
+Warning 1105 Expression depends on the @@sql_mode value PAD_CHAR_TO_FULL_LENGTH
+SELECT * FROM t1;
+a v
+1 1
+2 2
+3 3
+FLUSH TABLES;
+SELECT * FROM t1;
+a v
+1 1
+2 2
+3 3
+Warnings:
+Warning 1901 Function or expression '`a`' cannot be used in the GENERATED ALWAYS AS clause of `v`
+Warning 1105 Expression depends on the @@sql_mode value PAD_CHAR_TO_FULL_LENGTH
+CREATE TABLE t2 LIKE t1;
+ERROR HY000: Function or expression '`a`' cannot be used in the GENERATED ALWAYS AS clause of `v`
+FLUSH TABLES;
+CREATE TABLE t2 LIKE t1;
+ERROR HY000: Function or expression '`a`' cannot be used in the GENERATED ALWAYS AS clause of `v`
+SHOW CREATE TABLE t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `a` char(5) DEFAULT NULL,
+ `v` varchar(5) GENERATED ALWAYS AS (`a`) VIRTUAL,
+ KEY `v` (`v`)
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+Warnings:
+Warning 1901 Function or expression '`a`' cannot be used in the GENERATED ALWAYS AS clause of `v`
+Warning 1105 Expression depends on the @@sql_mode value PAD_CHAR_TO_FULL_LENGTH
+ALTER TABLE t1 ADD b INT DEFAULT a;
+ERROR HY000: Function or expression '`a`' cannot be used in the GENERATED ALWAYS AS clause of `v`
+FLUSH TABLES;
+ALTER TABLE t1 ADD c INT DEFAULT a;
+ERROR HY000: Function or expression '`a`' cannot be used in the GENERATED ALWAYS AS clause of `v`
+SELECT * FROM t1;
+a v
+1 1
+2 2
+3 3
+DROP TABLE t1;
+#
+# Fixing a Maria-10.2.26 table with a virtual VARCHAR column
+#
+# Fixing by dropping the virtual column
+# Copying maria100226_char_to_vchar_virtual.* to MYSQLD_DATADIR
+SHOW CREATE TABLE t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `a` char(5) DEFAULT NULL,
+ `v` varchar(5) GENERATED ALWAYS AS (`a`) VIRTUAL,
+ KEY `v` (`v`)
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+Warnings:
+Warning 1901 Function or expression '`a`' cannot be used in the GENERATED ALWAYS AS clause of `v`
+Warning 1105 Expression depends on the @@sql_mode value PAD_CHAR_TO_FULL_LENGTH
+ALTER TABLE t1 DROP v;
+SELECT * FROM t1;
+a
+1
+2
+3
+DROP TABLE t1;
+# Fixing by dropping a key on a virtual column, using ALTER TABLE
+# Copying maria100226_char_to_vchar_virtual.* to MYSQLD_DATADIR
+SHOW CREATE TABLE t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `a` char(5) DEFAULT NULL,
+ `v` varchar(5) GENERATED ALWAYS AS (`a`) VIRTUAL,
+ KEY `v` (`v`)
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+Warnings:
+Warning 1901 Function or expression '`a`' cannot be used in the GENERATED ALWAYS AS clause of `v`
+Warning 1105 Expression depends on the @@sql_mode value PAD_CHAR_TO_FULL_LENGTH
+ALTER TABLE t1 DROP KEY v;
+SHOW CREATE TABLE t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `a` char(5) DEFAULT NULL,
+ `v` varchar(5) GENERATED ALWAYS AS (`a`) VIRTUAL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+SELECT * FROM t1;
+a v
+1 1
+2 2
+3 3
+DROP TABLE t1;
+# Fixing by dropping a key on a virtual column, using DROP INDEX
+# Copying maria100226_char_to_vchar_virtual.* to MYSQLD_DATADIR
+DROP INDEX v ON t1;
+Warnings:
+Warning 1901 Function or expression '`a`' cannot be used in the GENERATED ALWAYS AS clause of `v`
+Warning 1105 Expression depends on the @@sql_mode value PAD_CHAR_TO_FULL_LENGTH
+SHOW CREATE TABLE t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `a` char(5) DEFAULT NULL,
+ `v` varchar(5) GENERATED ALWAYS AS (`a`) VIRTUAL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+SELECT * FROM t1;
+a v
+1 1
+2 2
+3 3
+DROP TABLE t1;
+# Fixing by altering the generation expression of a virtual column
+# Copying maria100226_char_to_vchar_virtual.* to MYSQLD_DATADIR
+SHOW CREATE TABLE t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `a` char(5) DEFAULT NULL,
+ `v` varchar(5) GENERATED ALWAYS AS (`a`) VIRTUAL,
+ KEY `v` (`v`)
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+Warnings:
+Warning 1901 Function or expression '`a`' cannot be used in the GENERATED ALWAYS AS clause of `v`
+Warning 1105 Expression depends on the @@sql_mode value PAD_CHAR_TO_FULL_LENGTH
+ALTER TABLE t1 MODIFY v VARCHAR(5) AS(RTRIM(a)) VIRTUAL;
+SHOW CREATE TABLE t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `a` char(5) DEFAULT NULL,
+ `v` varchar(5) GENERATED ALWAYS AS (rtrim(`a`)) VIRTUAL,
+ KEY `v` (`v`)
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+SELECT * FROM t1;
+a v
+1 1
+2 2
+3 3
+CREATE TABLE t2 LIKE t1;
+SHOW CREATE TABLE t2;
+Table Create Table
+t2 CREATE TABLE `t2` (
+ `a` char(5) DEFAULT NULL,
+ `v` varchar(5) GENERATED ALWAYS AS (rtrim(`a`)) VIRTUAL,
+ KEY `v` (`v`)
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+DROP TABLE t2;
+DROP TABLE t1;
+#
+# Upgrading a Maria-10.2.26 table with a stored column
+#
+# Copying maria100226_char_to_varchar.* to MYSQLD_DATADIR
+CHECK TABLE t1 FOR UPGRADE;
+Table Op Msg_type Msg_text
+test.t1 check Warning Function or expression '`a`' cannot be used in the GENERATED ALWAYS AS clause of `v`
+test.t1 check Warning Expression depends on the @@sql_mode value PAD_CHAR_TO_FULL_LENGTH
+test.t1 check status OK
+FLUSH TABLES;
+CHECK TABLE t1 FOR UPGRADE;
+Table Op Msg_type Msg_text
+test.t1 check Warning Function or expression '`a`' cannot be used in the GENERATED ALWAYS AS clause of `v`
+test.t1 check Warning Expression depends on the @@sql_mode value PAD_CHAR_TO_FULL_LENGTH
+test.t1 check status OK
+DROP TABLE t1;
+#
+# Upgrading a Maria-10.2.26 table with a virtual column
+#
+# Copying maria100226_char_to_varchar.* to MYSQLD_DATADIR
+CHECK TABLE t1 FOR UPGRADE;
+Table Op Msg_type Msg_text
+test.t1 check Warning Function or expression '`a`' cannot be used in the GENERATED ALWAYS AS clause of `v`
+test.t1 check Warning Expression depends on the @@sql_mode value PAD_CHAR_TO_FULL_LENGTH
+test.t1 check status OK
+FLUSH TABLES;
+CHECK TABLE t1 FOR UPGRADE;
+Table Op Msg_type Msg_text
+test.t1 check Warning Function or expression '`a`' cannot be used in the GENERATED ALWAYS AS clause of `v`
+test.t1 check Warning Expression depends on the @@sql_mode value PAD_CHAR_TO_FULL_LENGTH
+test.t1 check status OK
+DROP TABLE t1;
diff --git a/mysql-test/suite/vcol/t/vcol_sql_mode.test b/mysql-test/suite/vcol/t/vcol_sql_mode.test
index 5fb7ec8331d..e4cc6d21718 100644
--- a/mysql-test/suite/vcol/t/vcol_sql_mode.test
+++ b/mysql-test/suite/vcol/t/vcol_sql_mode.test
@@ -294,6 +294,9 @@ CREATE TABLE t1 (
--error ER_GENERATED_COLUMN_FUNCTION_IS_NOT_ALLOWED
ALTER TABLE t1 ADD KEY(v);
SHOW WARNINGS;
+--error ER_GENERATED_COLUMN_FUNCTION_IS_NOT_ALLOWED
+CREATE INDEX v ON t1 (v);
+SHOW WARNINGS;
DROP TABLE t1;
diff --git a/mysql-test/suite/vcol/t/vcol_sql_mode_upgrade.test b/mysql-test/suite/vcol/t/vcol_sql_mode_upgrade.test
new file mode 100644
index 00000000000..71e34231ac1
--- /dev/null
+++ b/mysql-test/suite/vcol/t/vcol_sql_mode_upgrade.test
@@ -0,0 +1,193 @@
+-- source include/mysql_upgrade_preparation.inc
+call mtr.add_suppression("Table rebuild required");
+
+let $MYSQLD_DATADIR= `select @@datadir`;
+
+--enable_prepare_warnings
+
+--echo #
+--echo # Opening a Maria-10.2.26 table with a stored VARCHAR column
+--echo #
+
+--echo # Copying maria100226_char_to_vchar_stored.* to MYSQLD_DATADIR
+--copy_file std_data/vcol_upgrade/maria100226_char_to_vchar_stored.frm $MYSQLD_DATADIR/test/t1.frm
+--copy_file std_data/vcol_upgrade/maria100226_char_to_vchar_stored.MYD $MYSQLD_DATADIR/test/t1.MYD
+--copy_file std_data/vcol_upgrade/maria100226_char_to_vchar_stored.MYI $MYSQLD_DATADIR/test/t1.MYI
+
+SHOW CREATE TABLE t1;
+SHOW CREATE TABLE t1;
+FLUSH TABLES;
+SHOW CREATE TABLE t1;
+
+FLUSH TABLES;
+SELECT * FROM t1;
+SELECT * FROM t1;
+FLUSH TABLES;
+SELECT * FROM t1;
+
+--error ER_GENERATED_COLUMN_FUNCTION_IS_NOT_ALLOWED
+CREATE TABLE t2 LIKE t1;
+FLUSH TABLES;
+--error ER_GENERATED_COLUMN_FUNCTION_IS_NOT_ALLOWED
+CREATE TABLE t2 LIKE t1;
+
+SHOW CREATE TABLE t1;
+--error ER_GENERATED_COLUMN_FUNCTION_IS_NOT_ALLOWED
+ALTER TABLE t1 ADD b INT DEFAULT a;
+SHOW CREATE TABLE t1;
+SELECT * FROM t1;
+FLUSH TABLES;
+--error ER_GENERATED_COLUMN_FUNCTION_IS_NOT_ALLOWED
+ALTER TABLE t1 ADD c INT DEFAULT a;
+SELECT * FROM t1;
+DROP TABLE t1;
+
+
+--echo #
+--echo # Fixing a Maria-10.2.26 table with a stored VARCHAR column
+--echo #
+
+--echo # Fixing by dropping the generated stored column
+--echo # Copying maria100226_char_to_vchar_stored.* to MYSQLD_DATADIR
+--copy_file std_data/vcol_upgrade/maria100226_char_to_vchar_stored.frm $MYSQLD_DATADIR/test/t1.frm
+--copy_file std_data/vcol_upgrade/maria100226_char_to_vchar_stored.MYD $MYSQLD_DATADIR/test/t1.MYD
+--copy_file std_data/vcol_upgrade/maria100226_char_to_vchar_stored.MYI $MYSQLD_DATADIR/test/t1.MYI
+
+ALTER TABLE t1 DROP v;
+SELECT * FROM t1;
+DROP TABLE t1;
+
+--echo # Fixing by altering the generation expression of the stored column
+--echo # Copying maria100226_char_to_vchar_stored.* to MYSQLD_DATADIR
+--copy_file std_data/vcol_upgrade/maria100226_char_to_vchar_stored.frm $MYSQLD_DATADIR/test/t1.frm
+--copy_file std_data/vcol_upgrade/maria100226_char_to_vchar_stored.MYD $MYSQLD_DATADIR/test/t1.MYD
+--copy_file std_data/vcol_upgrade/maria100226_char_to_vchar_stored.MYI $MYSQLD_DATADIR/test/t1.MYI
+
+SHOW CREATE TABLE t1;
+ALTER TABLE t1 MODIFY v VARCHAR(5) AS (RTRIM(a)) PERSISTENT;
+SHOW CREATE TABLE t1;
+DROP TABLE t1;
+
+
+
+--echo #
+--echo # Opening a Maria-10.2.26 table with a virtual VARCHAR column
+--echo #
+
+--echo # Copying maria100226_char_to_vchar_virtual.* to MYSQLD_DATADIR
+--copy_file std_data/vcol_upgrade/maria100226_char_to_vchar_virtual.frm $MYSQLD_DATADIR/test/t1.frm
+--copy_file std_data/vcol_upgrade/maria100226_char_to_vchar_virtual.MYD $MYSQLD_DATADIR/test/t1.MYD
+--copy_file std_data/vcol_upgrade/maria100226_char_to_vchar_virtual.MYI $MYSQLD_DATADIR/test/t1.MYI
+
+SHOW CREATE TABLE t1;
+SHOW CREATE TABLE t1;
+FLUSH TABLES;
+SHOW CREATE TABLE t1;
+
+FLUSH TABLES;
+SELECT * FROM t1;
+SELECT * FROM t1;
+FLUSH TABLES;
+SELECT * FROM t1;
+
+--error ER_GENERATED_COLUMN_FUNCTION_IS_NOT_ALLOWED
+CREATE TABLE t2 LIKE t1;
+FLUSH TABLES;
+--error ER_GENERATED_COLUMN_FUNCTION_IS_NOT_ALLOWED
+CREATE TABLE t2 LIKE t1;
+
+
+SHOW CREATE TABLE t1;
+--error ER_GENERATED_COLUMN_FUNCTION_IS_NOT_ALLOWED
+ALTER TABLE t1 ADD b INT DEFAULT a;
+FLUSH TABLES;
+--error ER_GENERATED_COLUMN_FUNCTION_IS_NOT_ALLOWED
+ALTER TABLE t1 ADD c INT DEFAULT a;
+SELECT * FROM t1;
+DROP TABLE t1;
+
+
+--echo #
+--echo # Fixing a Maria-10.2.26 table with a virtual VARCHAR column
+--echo #
+
+--echo # Fixing by dropping the virtual column
+--echo # Copying maria100226_char_to_vchar_virtual.* to MYSQLD_DATADIR
+--copy_file std_data/vcol_upgrade/maria100226_char_to_vchar_virtual.frm $MYSQLD_DATADIR/test/t1.frm
+--copy_file std_data/vcol_upgrade/maria100226_char_to_vchar_virtual.MYD $MYSQLD_DATADIR/test/t1.MYD
+--copy_file std_data/vcol_upgrade/maria100226_char_to_vchar_virtual.MYI $MYSQLD_DATADIR/test/t1.MYI
+
+SHOW CREATE TABLE t1;
+ALTER TABLE t1 DROP v;
+SELECT * FROM t1;
+DROP TABLE t1;
+
+--echo # Fixing by dropping a key on a virtual column, using ALTER TABLE
+--echo # Copying maria100226_char_to_vchar_virtual.* to MYSQLD_DATADIR
+--copy_file std_data/vcol_upgrade/maria100226_char_to_vchar_virtual.frm $MYSQLD_DATADIR/test/t1.frm
+--copy_file std_data/vcol_upgrade/maria100226_char_to_vchar_virtual.MYD $MYSQLD_DATADIR/test/t1.MYD
+--copy_file std_data/vcol_upgrade/maria100226_char_to_vchar_virtual.MYI $MYSQLD_DATADIR/test/t1.MYI
+
+SHOW CREATE TABLE t1;
+ALTER TABLE t1 DROP KEY v;
+SHOW CREATE TABLE t1;
+SELECT * FROM t1;
+DROP TABLE t1;
+
+
+--echo # Fixing by dropping a key on a virtual column, using DROP INDEX
+--echo # Copying maria100226_char_to_vchar_virtual.* to MYSQLD_DATADIR
+--copy_file std_data/vcol_upgrade/maria100226_char_to_vchar_virtual.frm $MYSQLD_DATADIR/test/t1.frm
+--copy_file std_data/vcol_upgrade/maria100226_char_to_vchar_virtual.MYD $MYSQLD_DATADIR/test/t1.MYD
+--copy_file std_data/vcol_upgrade/maria100226_char_to_vchar_virtual.MYI $MYSQLD_DATADIR/test/t1.MYI
+
+DROP INDEX v ON t1;
+SHOW CREATE TABLE t1;
+SELECT * FROM t1;
+DROP TABLE t1;
+
+
+--echo # Fixing by altering the generation expression of a virtual column
+--echo # Copying maria100226_char_to_vchar_virtual.* to MYSQLD_DATADIR
+--copy_file std_data/vcol_upgrade/maria100226_char_to_vchar_virtual.frm $MYSQLD_DATADIR/test/t1.frm
+--copy_file std_data/vcol_upgrade/maria100226_char_to_vchar_virtual.MYD $MYSQLD_DATADIR/test/t1.MYD
+--copy_file std_data/vcol_upgrade/maria100226_char_to_vchar_virtual.MYI $MYSQLD_DATADIR/test/t1.MYI
+
+SHOW CREATE TABLE t1;
+ALTER TABLE t1 MODIFY v VARCHAR(5) AS(RTRIM(a)) VIRTUAL;
+SHOW CREATE TABLE t1;
+SELECT * FROM t1;
+CREATE TABLE t2 LIKE t1;
+SHOW CREATE TABLE t2;
+DROP TABLE t2;
+DROP TABLE t1;
+
+
+--echo #
+--echo # Upgrading a Maria-10.2.26 table with a stored column
+--echo #
+
+--echo # Copying maria100226_char_to_varchar.* to MYSQLD_DATADIR
+--copy_file std_data/vcol_upgrade/maria100226_char_to_vchar_stored.frm $MYSQLD_DATADIR/test/t1.frm
+--copy_file std_data/vcol_upgrade/maria100226_char_to_vchar_stored.MYD $MYSQLD_DATADIR/test/t1.MYD
+--copy_file std_data/vcol_upgrade/maria100226_char_to_vchar_stored.MYI $MYSQLD_DATADIR/test/t1.MYI
+
+CHECK TABLE t1 FOR UPGRADE;
+FLUSH TABLES;
+CHECK TABLE t1 FOR UPGRADE;
+DROP TABLE t1;
+
+
+--echo #
+--echo # Upgrading a Maria-10.2.26 table with a virtual column
+--echo #
+
+--echo # Copying maria100226_char_to_varchar.* to MYSQLD_DATADIR
+--copy_file std_data/vcol_upgrade/maria100226_char_to_vchar_virtual.frm $MYSQLD_DATADIR/test/t1.frm
+--copy_file std_data/vcol_upgrade/maria100226_char_to_vchar_virtual.MYD $MYSQLD_DATADIR/test/t1.MYD
+--copy_file std_data/vcol_upgrade/maria100226_char_to_vchar_virtual.MYI $MYSQLD_DATADIR/test/t1.MYI
+
+CHECK TABLE t1 FOR UPGRADE;
+FLUSH TABLES;
+CHECK TABLE t1 FOR UPGRADE;
+DROP TABLE t1;
diff --git a/sql/field.cc b/sql/field.cc
index e5359a7520e..30edee0e386 100644
--- a/sql/field.cc
+++ b/sql/field.cc
@@ -1428,14 +1428,16 @@ void Field::load_data_set_value(const char *pos, uint length,
}
-void Field::error_generated_column_function_is_not_allowed(THD *thd) const
+void Field::error_generated_column_function_is_not_allowed(THD *thd,
+ bool error) const
{
StringBuffer<64> tmp;
vcol_info->expr->print(&tmp, (enum_query_type)
(QT_TO_SYSTEM_CHARSET |
QT_ITEM_IDENT_SKIP_DB_NAMES |
QT_ITEM_IDENT_SKIP_TABLE_NAMES));
- my_error(ER_GENERATED_COLUMN_FUNCTION_IS_NOT_ALLOWED, MYF(0),
+ my_error(ER_GENERATED_COLUMN_FUNCTION_IS_NOT_ALLOWED,
+ MYF(error ? 0 : ME_JUST_WARNING),
tmp.c_ptr(), vcol_info->get_vcol_type_name(),
const_cast<const char*>(field_name));
}
@@ -1446,7 +1448,7 @@ void Field::error_generated_column_function_is_not_allowed(THD *thd) const
that it cannot handle.
See sql_mode.h for details.
*/
-bool Field::check_vcol_sql_mode_dependency(THD *thd) const
+bool Field::check_vcol_sql_mode_dependency(THD *thd, vcol_init_mode mode) const
{
DBUG_ASSERT(vcol_info);
if ((flags & PART_KEY_FLAG) != 0 || stored_in_db())
@@ -1456,9 +1458,10 @@ bool Field::check_vcol_sql_mode_dependency(THD *thd) const
Sql_mode_dependency(~0, ~can_handle_sql_mode_dependency_on_store());
if (dep)
{
- error_generated_column_function_is_not_allowed(thd);
+ bool error= (mode & VCOL_INIT_DEPENDENCY_FAILURE_IS_ERROR) != 0;
+ error_generated_column_function_is_not_allowed(thd, error);
dep.push_dependency_warnings(thd);
- return true;
+ return error;
}
}
return false;
diff --git a/sql/field.h b/sql/field.h
index 9333d1492fd..c82febd956e 100644
--- a/sql/field.h
+++ b/sql/field.h
@@ -697,7 +697,8 @@ protected:
val_str(&result);
return to->store(result.ptr(), result.length(), charset());
}
- void error_generated_column_function_is_not_allowed(THD *thd) const;
+ void error_generated_column_function_is_not_allowed(THD *thd, bool error)
+ const;
static void do_field_int(Copy_field *copy);
static void do_field_real(Copy_field *copy);
static void do_field_string(Copy_field *copy);
@@ -1175,7 +1176,7 @@ public:
}
bool stored_in_db() const { return !vcol_info || vcol_info->stored_in_db; }
- bool check_vcol_sql_mode_dependency(THD *) const;
+ bool check_vcol_sql_mode_dependency(THD *, vcol_init_mode mode) const;
virtual sql_mode_t value_depends_on_sql_mode() const
{
diff --git a/sql/sql_insert.cc b/sql/sql_insert.cc
index 3169efbefe6..78564f28c31 100644
--- a/sql/sql_insert.cc
+++ b/sql/sql_insert.cc
@@ -2529,7 +2529,8 @@ TABLE *Delayed_insert::get_local_table(THD* client_thd)
sizeof(MY_BITMAP))))
goto error;
- if (parse_vcol_defs(client_thd, client_thd->mem_root, copy, &error_reported))
+ if (parse_vcol_defs(client_thd, client_thd->mem_root, copy, &error_reported,
+ VCOL_INIT_DEPENDENCY_FAILURE_IS_WARNING))
goto error;
}
diff --git a/sql/table.cc b/sql/table.cc
index 62449ebcc06..07858ab270a 100644
--- a/sql/table.cc
+++ b/sql/table.cc
@@ -989,7 +989,7 @@ static void mysql57_calculate_null_position(TABLE_SHARE *share,
expression
*/
bool parse_vcol_defs(THD *thd, MEM_ROOT *mem_root, TABLE *table,
- bool *error_reported)
+ bool *error_reported, vcol_init_mode mode)
{
CHARSET_INFO *save_character_set_client= thd->variables.character_set_client;
CHARSET_INFO *save_collation= thd->variables.collation_connection;
@@ -1073,7 +1073,7 @@ bool parse_vcol_defs(THD *thd, MEM_ROOT *mem_root, TABLE *table,
vcol= unpack_vcol_info_from_frm(thd, mem_root, table, &expr_str,
&((*field_ptr)->vcol_info), error_reported);
*(vfield_ptr++)= *field_ptr;
- if (vcol && field_ptr[0]->check_vcol_sql_mode_dependency(thd))
+ if (vcol && field_ptr[0]->check_vcol_sql_mode_dependency(thd, mode))
{
DBUG_ASSERT(thd->is_error());
*error_reported= true;
@@ -3223,7 +3223,23 @@ enum open_frm_error open_table_from_share(THD *thd, TABLE_SHARE *share,
if (share->table_check_constraints || share->field_check_constraints)
outparam->check_constraints= check_constraint_ptr;
- if (parse_vcol_defs(thd, &outparam->mem_root, outparam, &error_reported))
+ vcol_init_mode mode= VCOL_INIT_DEPENDENCY_FAILURE_IS_WARNING;
+ switch (thd->lex->sql_command)
+ {
+ case SQLCOM_CREATE_TABLE:
+ mode= VCOL_INIT_DEPENDENCY_FAILURE_IS_ERROR;
+ break;
+ case SQLCOM_ALTER_TABLE:
+ case SQLCOM_CREATE_INDEX:
+ case SQLCOM_DROP_INDEX:
+ if ((ha_open_flags & HA_OPEN_FOR_ALTER) == 0)
+ mode= VCOL_INIT_DEPENDENCY_FAILURE_IS_ERROR;
+ break;
+ default:
+ break;
+ }
+ if (parse_vcol_defs(thd, &outparam->mem_root, outparam,
+ &error_reported, mode))
{
error= OPEN_FRM_CORRUPTED;
goto err;
diff --git a/sql/table.h b/sql/table.h
index 7786679982f..8f6a9e7aa86 100644
--- a/sql/table.h
+++ b/sql/table.h
@@ -325,6 +325,20 @@ enum tmp_table_type
};
enum release_type { RELEASE_NORMAL, RELEASE_WAIT_FOR_DROP };
+
+enum vcol_init_mode
+{
+ VCOL_INIT_DEPENDENCY_FAILURE_IS_WARNING= 1,
+ VCOL_INIT_DEPENDENCY_FAILURE_IS_ERROR= 2
+ /*
+ There may be new flags here.
+ e.g. to automatically remove sql_mode dependency:
+ GENERATED ALWAYS AS (char_col) ->
+ GENERATED ALWAYS AS (RTRIM(char_col))
+ */
+};
+
+
enum enum_vcol_update_mode
{
VCOL_UPDATE_FOR_READ= 0,
@@ -2736,7 +2750,7 @@ bool fix_session_vcol_expr(THD *thd, Virtual_column_info *vcol);
bool fix_session_vcol_expr_for_read(THD *thd, Field *field,
Virtual_column_info *vcol);
bool parse_vcol_defs(THD *thd, MEM_ROOT *mem_root, TABLE *table,
- bool *error_reported);
+ bool *error_reported, vcol_init_mode expr);
TABLE_SHARE *alloc_table_share(const char *db, const char *table_name,
const char *key, uint key_length);
void init_tmp_table_share(THD *thd, TABLE_SHARE *share, const char *key,