From 1cae1af6f9286ca6695206ce20c63bb639c60310 Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Mon, 7 Nov 2016 22:35:02 +0100 Subject: [PATCH] MDEV-5800 InnoDB support for indexed vcols * remove old 5.2+ InnoDB support for virtual columns * enable corresponding parts of the innodb-5.7 sources * copy corresponding test cases from 5.7 * copy detailed Alter_inplace_info::HA_ALTER_FLAGS flags from 5.7 - and more detailed detection of changes in fill_alter_inplace_info() * more "innodb compatibility hooks" in sql_class.cc to - create/destroy/reset a THD (used by background purge threads) - find a prelocked table by name - open a table (from a background purge thread) * different from 5.7: - new service thread "thd_destructor_proxy" to make sure all THDs are destroyed at the correct point in time during the server shutdown - proper opening/closing of tables for vcol evaluations in + FK checks (use already opened prelocked tables) + purge threads (open the table, MDLock it, add it to tdc, close when not needed) - cache open tables in vc_templ - avoid unnecessary allocations, reuse table->record[0] and table->s->default_values - not needed in 5.7, because it overcalculates: + tell the server to calculate vcols for an on-going inline ADD INDEX + calculate vcols for correct error messages * update other engines (mroonga/tokudb) accordingly --- mysql-test/include/have_innodb.combinations | 8 + .../gcol/inc/gcol_column_def_options.inc | 2 +- .../suite/gcol/inc/innodb_v_large_col.inc | 53 + mysql-test/suite/gcol/r/gcol_bugfixes.result | 330 ++-- .../r/gcol_column_def_options_innodb.result | 170 +- .../suite/gcol/r/gcol_ins_upd_myisam.result | 4 + mysql-test/suite/gcol/r/gcol_rollback.result | 14 +- .../suite/gcol/r/gcol_select_innodb.result | 2 + .../suite/gcol/r/innodb_partition.result | 26 + .../gcol/r/innodb_prefix_index_check.result | 15 + .../suite/gcol/r/innodb_virtual_basic.result | 1562 +++++++++++++++++ .../suite/gcol/r/innodb_virtual_blob.result | 12 + .../suite/gcol/r/innodb_virtual_debug.result | 227 +++ .../gcol/r/innodb_virtual_debug_purge.result | 141 ++ .../suite/gcol/r/innodb_virtual_fk.result | 590 +++++++ .../gcol/r/innodb_virtual_fk_restart.result | 44 + .../suite/gcol/r/innodb_virtual_index.result | 196 +++ .../suite/gcol/r/innodb_virtual_purge.result | 140 ++ mysql-test/suite/gcol/r/innodb_wl8114.result | 52 + .../suite/gcol/r/main_alter_table.result | 52 + mysql-test/suite/gcol/r/main_mysqldump.result | 49 + mysql-test/suite/gcol/t/gcol_bugfixes.test | 273 ++- .../t/gcol_column_def_options_innodb.test | 2 +- mysql-test/suite/gcol/t/gcol_rollback.test | 4 +- mysql-test/suite/gcol/t/innodb_partition.test | 30 + .../gcol/t/innodb_prefix_index_check.test | 22 + .../suite/gcol/t/innodb_virtual_basic.test | 1474 ++++++++++++++++ .../suite/gcol/t/innodb_virtual_blob.test | 16 + .../suite/gcol/t/innodb_virtual_debug.test | 240 +++ .../gcol/t/innodb_virtual_debug_purge.test | 174 ++ .../suite/gcol/t/innodb_virtual_fk.test | 492 ++++++ .../gcol/t/innodb_virtual_fk_restart.test | 42 + .../suite/gcol/t/innodb_virtual_index.test | 220 +++ .../suite/gcol/t/innodb_virtual_purge.test | 138 ++ mysql-test/suite/gcol/t/innodb_wl8114.test | 42 + mysql-test/suite/gcol/t/main_alter_table.test | 50 + mysql-test/suite/gcol/t/main_mysqldump.test | 44 + .../suite/innodb/r/innodb_bug12400341.result | 6 +- .../suite/innodb/t/innodb_bug12400341.test | 6 +- .../suite/perfschema/r/threads_innodb.result | 1 + .../suite/vcol/r/vcol_keys_innodb.result | 18 +- mysql-test/suite/vcol/t/vcol_keys_innodb.test | 1 + sql/handler.cc | 1 + sql/handler.h | 101 +- sql/sql_class.cc | 87 + sql/sql_class.h | 3 +- sql/sql_parse.cc | 15 +- sql/sql_table.cc | 141 +- storage/innobase/handler/ha_innodb.cc | 567 +++--- storage/innobase/handler/ha_innodb.h | 18 +- storage/innobase/handler/handler0alter.cc | 422 ++--- storage/innobase/include/dict0dict.ic | 1 - storage/innobase/include/dict0mem.h | 11 +- storage/innobase/include/ha_prototypes.h | 16 +- storage/innobase/log/log0log.cc | 7 + storage/innobase/row/row0ins.cc | 6 - storage/innobase/row/row0merge.cc | 5 - storage/innobase/row/row0mysql.cc | 2 - storage/innobase/row/row0purge.cc | 4 +- storage/innobase/row/row0sel.cc | 2 - storage/innobase/row/row0upd.cc | 6 - storage/innobase/row/row0vers.cc | 6 - storage/innobase/srv/srv0srv.cc | 44 +- storage/mroonga/ha_mroonga.cpp | 4 +- storage/tokudb/ha_tokudb_alter_56.cc | 20 +- 65 files changed, 7367 insertions(+), 1106 deletions(-) create mode 100644 mysql-test/suite/gcol/inc/innodb_v_large_col.inc create mode 100644 mysql-test/suite/gcol/r/innodb_partition.result create mode 100644 mysql-test/suite/gcol/r/innodb_prefix_index_check.result create mode 100644 mysql-test/suite/gcol/r/innodb_virtual_basic.result create mode 100644 mysql-test/suite/gcol/r/innodb_virtual_blob.result create mode 100644 mysql-test/suite/gcol/r/innodb_virtual_debug.result create mode 100644 mysql-test/suite/gcol/r/innodb_virtual_debug_purge.result create mode 100644 mysql-test/suite/gcol/r/innodb_virtual_fk.result create mode 100644 mysql-test/suite/gcol/r/innodb_virtual_fk_restart.result create mode 100644 mysql-test/suite/gcol/r/innodb_virtual_index.result create mode 100644 mysql-test/suite/gcol/r/innodb_virtual_purge.result create mode 100644 mysql-test/suite/gcol/r/innodb_wl8114.result create mode 100644 mysql-test/suite/gcol/r/main_alter_table.result create mode 100644 mysql-test/suite/gcol/r/main_mysqldump.result create mode 100644 mysql-test/suite/gcol/t/innodb_partition.test create mode 100644 mysql-test/suite/gcol/t/innodb_prefix_index_check.test create mode 100644 mysql-test/suite/gcol/t/innodb_virtual_basic.test create mode 100644 mysql-test/suite/gcol/t/innodb_virtual_blob.test create mode 100644 mysql-test/suite/gcol/t/innodb_virtual_debug.test create mode 100644 mysql-test/suite/gcol/t/innodb_virtual_debug_purge.test create mode 100644 mysql-test/suite/gcol/t/innodb_virtual_fk.test create mode 100644 mysql-test/suite/gcol/t/innodb_virtual_fk_restart.test create mode 100644 mysql-test/suite/gcol/t/innodb_virtual_index.test create mode 100644 mysql-test/suite/gcol/t/innodb_virtual_purge.test create mode 100644 mysql-test/suite/gcol/t/innodb_wl8114.test create mode 100644 mysql-test/suite/gcol/t/main_alter_table.test create mode 100644 mysql-test/suite/gcol/t/main_mysqldump.test diff --git a/mysql-test/include/have_innodb.combinations b/mysql-test/include/have_innodb.combinations index e893da0a313..7e9e6b9e3b0 100644 --- a/mysql-test/include/have_innodb.combinations +++ b/mysql-test/include/have_innodb.combinations @@ -9,9 +9,13 @@ innodb-locks innodb-buffer-pool-stats innodb-buffer-page innodb-buffer-page-lru +innodb-sys-columns +innodb-sys-fields innodb-sys-foreign innodb-sys-foreign-cols +innodb-sys-indexes innodb-sys-tables +innodb-sys-virtual innodb-metrics [xtradb_plugin] @@ -54,6 +58,10 @@ innodb-metrics innodb-buffer-pool-stats innodb-buffer-page innodb-buffer-page-lru +innodb-sys-columns +innodb-sys-fields innodb-sys-foreign innodb-sys-foreign-cols +innodb-sys-indexes innodb-sys-tables +innodb-sys-virtual diff --git a/mysql-test/suite/gcol/inc/gcol_column_def_options.inc b/mysql-test/suite/gcol/inc/gcol_column_def_options.inc index 935a20503bf..c975cfe22fe 100644 --- a/mysql-test/suite/gcol/inc/gcol_column_def_options.inc +++ b/mysql-test/suite/gcol/inc/gcol_column_def_options.inc @@ -395,7 +395,7 @@ ALTER TABLE t CHANGE c c varchar(10) as ('a'); ALTER TABLE t CHANGE dd d varchar(10); if ($support_virtual_index) { - +# no RENAME INDEX yet #ALTER TABLE t ADD INDEX idx(a), ADD INDEX idx1(c); #ALTER TABLE t RENAME INDEX idx TO idx2, RENAME INDEX idx1 TO idx3; #ALTER TABLE t DROP INDEX idx2, DROP INDEX idx3; diff --git a/mysql-test/suite/gcol/inc/innodb_v_large_col.inc b/mysql-test/suite/gcol/inc/innodb_v_large_col.inc new file mode 100644 index 00000000000..70e188635fa --- /dev/null +++ b/mysql-test/suite/gcol/inc/innodb_v_large_col.inc @@ -0,0 +1,53 @@ +--source include/have_innodb.inc + +eval CREATE TABLE `t` ( +`a` VARCHAR(10000), `b` VARCHAR(3000), +`c` VARCHAR(14000) GENERATED ALWAYS AS (CONCAT(a,b)) VIRTUAL, +`d` VARCHAR(5000) GENERATED ALWAYS AS (b) VIRTUAL, +`e` INT(11) GENERATED ALWAYS AS (10) VIRTUAL, +`h` INT(11) NOT NULL, +PRIMARY KEY (`h`) ) ROW_FORMAT=$row_format ENGINE=InnoDB; + +SHOW CREATE TABLE t; + +INSERT INTO t VALUES (REPEAT('g', 10000), REPEAT('x', 2800), DEFAULT, DEFAULT, DEFAULT, 1); + +INSERT INTO t VALUES (REPEAT('a', 9000), REPEAT('b', 2000), DEFAULT, DEFAULT, DEFAULT, 2); +INSERT INTO t VALUES (REPEAT('m', 8000), REPEAT('n', 3000), DEFAULT, DEFAULT, DEFAULT, 3); +CREATE INDEX idx ON t(c(100), d(20)); +UPDATE t SET a = REPEAT(CAST(1 AS CHAR), 2000) WHERE h = 1; + +delimiter |; +CREATE PROCEDURE UPDATE_t() +begin + DECLARE i INT DEFAULT 1; + WHILE (i <= 100) DO + UPDATE t SET a = REPEAT(CAST(i AS CHAR), 2000) WHERE h = 1; + SET i = i + 1; + END WHILE; +END| + +CREATE PROCEDURE DELETE_insert_t() +begin + DECLARE i INT DEFAULT 1; + WHILE (i <= 100) DO + DELETE FROM t WHERE h = 1; + INSERT INTO t VALUES (REPEAT(CAST(i AS CHAR), 2000) , REPEAT('b', 2000), DEFAULT, DEFAULT, DEFAULT, 1); + SET i = i + 1; + END WHILE; +END| +delimiter ;| + +CALL UPDATE_t(); + +CALL DELETE_insert_t(); + +UPDATE t SET a = NULL WHERE h=1; + +START TRANSACTION; +CALL UPDATE_t(); +ROLLBACK; + +DROP PROCEDURE DELETE_insert_t; +DROP PROCEDURE UPDATE_t; +DROP TABLE t; diff --git a/mysql-test/suite/gcol/r/gcol_bugfixes.result b/mysql-test/suite/gcol/r/gcol_bugfixes.result index 3ee376bd146..fa0badff96d 100644 --- a/mysql-test/suite/gcol/r/gcol_bugfixes.result +++ b/mysql-test/suite/gcol/r/gcol_bugfixes.result @@ -59,189 +59,147 @@ DROP TABLE t1; # CREATE TABLE c ( pk INTEGER AUTO_INCREMENT, -col_int_nokey INTEGER /*! NULL */, -col_int_key INTEGER GENERATED ALWAYS AS -(col_int_nokey + col_int_nokey) VIRTUAL not null, -col_date_nokey DATE /*! NULL */, -col_date_key DATE GENERATED ALWAYS AS -(DATE_ADD(col_date_nokey,interval 30 day)) VIRTUAL not null, -col_datetime_nokey DATETIME /*! NULL */, -col_time_nokey TIME /*! NULL */, -col_datetime_key DATETIME GENERATED ALWAYS AS -(ADDTIME(col_datetime_nokey, col_time_nokey)) VIRTUAL not null, -col_time_key TIME GENERATED ALWAYS AS -(ADDTIME(col_datetime_nokey, col_time_nokey)) VIRTUAL not null, -col_varchar_nokey VARCHAR(1) /*! NULL */, -col_varchar_key VARCHAR(2) GENERATED ALWAYS AS -(CONCAT(col_varchar_nokey, col_varchar_nokey)) VIRTUAL not null, +col_int_nokey INTEGER, +gcol_int_key INTEGER GENERATED ALWAYS AS (col_int_nokey + col_int_nokey) VIRTUAL, +col_date_nokey DATE, +gcol_date_key DATE GENERATED ALWAYS AS (DATE_ADD(col_date_nokey,interval 30 day)) VIRTUAL, +col_datetime_nokey DATETIME, +col_time_nokey TIME, +gcol_datetime_key DATETIME GENERATED ALWAYS AS (ADDTIME(col_datetime_nokey, col_time_nokey)) VIRTUAL, +gcol_time_key TIME GENERATED ALWAYS AS (ADDTIME(col_datetime_nokey, col_time_nokey)) VIRTUAL, +col_varchar_nokey VARCHAR(1), +gcol_varchar_key VARCHAR(2) GENERATED ALWAYS AS (CONCAT(col_varchar_nokey, col_varchar_nokey)) VIRTUAL, PRIMARY KEY (pk), -UNIQUE KEY (col_int_key), -UNIQUE KEY (col_varchar_key), -UNIQUE KEY (col_date_key), -KEY (col_time_key), -KEY (col_datetime_key), -UNIQUE KEY (col_int_key, col_varchar_key), -KEY (col_int_key, col_int_nokey), -KEY(col_int_key,col_date_key), -KEY(col_int_key, col_time_key), -KEY(col_int_key, col_datetime_key), -UNIQUE -KEY(col_date_key,col_time_key,col_datetime_key), -UNIQUE KEY (col_varchar_key, col_varchar_nokey), -UNIQUE KEY (col_int_key, col_varchar_key, -col_date_key, col_time_key, col_datetime_key) +UNIQUE KEY (gcol_int_key), +UNIQUE KEY (gcol_varchar_key), +UNIQUE KEY (gcol_date_key), +KEY (gcol_time_key), +KEY (gcol_datetime_key), +UNIQUE KEY (gcol_int_key, gcol_varchar_key), +KEY (gcol_int_key, col_int_nokey), +KEY(gcol_int_key,gcol_date_key), +KEY(gcol_int_key, gcol_time_key), +KEY(gcol_int_key, gcol_datetime_key), +UNIQUE KEY(gcol_date_key,gcol_time_key,gcol_datetime_key), +UNIQUE KEY (gcol_varchar_key, col_varchar_nokey), +UNIQUE KEY (gcol_int_key, gcol_varchar_key, gcol_date_key, gcol_time_key, gcol_datetime_key) ) ENGINE=INNODB; -INSERT /*! IGNORE */ INTO c ( -col_int_nokey, -col_date_nokey, -col_time_nokey, -col_datetime_nokey, -col_varchar_nokey -) VALUES (7, '2004-04-09', '14:03:03.042673', -'2001-11-28 00:50:27.051028', 'c'),(1, '2006-05-13', '01:46:09.016386', -'2007-10-09 19:53:04.008332', NULL); +INSERT IGNORE INTO c ( col_int_nokey, col_date_nokey, col_time_nokey, col_datetime_nokey, col_varchar_nokey) +VALUES (7, '2004-04-09', '14:03:03.042673', '2001-11-28 00:50:27.051028', 'c'), +(1, '2006-05-13', '01:46:09.016386', '2007-10-09 19:53:04.008332', NULL); Warnings: -Warning 1048 Column 'col_varchar_key' cannot be null +Note 1265 Data truncated for column 'gcol_time_key' at row 1 +Note 1265 Data truncated for column 'gcol_time_key' at row 2 CREATE TABLE bb ( pk INTEGER AUTO_INCREMENT, -col_int_nokey INTEGER /*! NULL */, -col_int_key INTEGER GENERATED ALWAYS AS -(col_int_nokey + col_int_nokey) VIRTUAL not null, -col_date_nokey DATE /*! NULL */, -col_date_key DATE GENERATED ALWAYS AS -(DATE_ADD(col_date_nokey,interval 30 day)) VIRTUAL not null, -col_datetime_nokey DATETIME /*! NULL */, -col_time_nokey TIME /*! NULL */, -col_datetime_key DATETIME GENERATED ALWAYS AS -(ADDTIME(col_datetime_nokey, col_time_nokey)) VIRTUAL not null, -col_time_key TIME GENERATED ALWAYS AS -(ADDTIME(col_datetime_nokey, col_time_nokey)) VIRTUAL not null, -col_varchar_nokey VARCHAR(1) /*! NULL */, -col_varchar_key VARCHAR(2) GENERATED ALWAYS AS -(CONCAT(col_varchar_nokey, col_varchar_nokey)) VIRTUAL not null, +col_int_nokey INTEGER, +gcol_int_key INTEGER GENERATED ALWAYS AS (col_int_nokey + col_int_nokey) VIRTUAL, +col_date_nokey DATE, +gcol_date_key DATE GENERATED ALWAYS AS (DATE_ADD(col_date_nokey,interval 30 day)) VIRTUAL, +col_datetime_nokey DATETIME, +col_time_nokey TIME, +gcol_datetime_key DATETIME GENERATED ALWAYS AS (ADDTIME(col_datetime_nokey, col_time_nokey)) VIRTUAL, +gcol_time_key TIME GENERATED ALWAYS AS (ADDTIME(col_datetime_nokey, col_time_nokey)) VIRTUAL, +col_varchar_nokey VARCHAR(1), +gcol_varchar_key VARCHAR(2) GENERATED ALWAYS AS (CONCAT(col_varchar_nokey, col_varchar_nokey)) VIRTUAL, PRIMARY KEY (pk), -UNIQUE KEY (col_int_key), -UNIQUE KEY (col_varchar_key), -UNIQUE KEY (col_date_key), -KEY (col_time_key), -KEY (col_datetime_key), -UNIQUE KEY (col_int_key, col_varchar_key), -KEY (col_int_key, col_int_nokey), -KEY(col_int_key,col_date_key), -KEY(col_int_key, col_time_key), -KEY(col_int_key, col_datetime_key), -UNIQUE -KEY(col_date_key,col_time_key,col_datetime_key), -UNIQUE KEY (col_varchar_key, col_varchar_nokey), -UNIQUE KEY (col_int_key, col_varchar_key, -col_date_key, col_time_key, col_datetime_key) +UNIQUE KEY (gcol_int_key), +UNIQUE KEY (gcol_varchar_key), +UNIQUE KEY (gcol_date_key), +KEY (gcol_time_key), +KEY (gcol_datetime_key), +UNIQUE KEY (gcol_int_key, gcol_varchar_key), +KEY (gcol_int_key, col_int_nokey), +KEY(gcol_int_key,gcol_date_key), +KEY(gcol_int_key, gcol_time_key), +KEY(gcol_int_key, gcol_datetime_key), +UNIQUE KEY(gcol_date_key,gcol_time_key,gcol_datetime_key), +UNIQUE KEY (gcol_varchar_key, col_varchar_nokey), +UNIQUE KEY (gcol_int_key, gcol_varchar_key, gcol_date_key, gcol_time_key, gcol_datetime_key) ) AUTO_INCREMENT=10 ENGINE=INNODB; -INSERT /*! IGNORE */ INTO bb ( -col_int_nokey, -col_date_nokey, -col_time_nokey, -col_datetime_nokey, -col_varchar_nokey -) VALUES (0, '2003-08-04', '01:48:05.048577', -'2006-11-03 00:00:00', 'p'),(2, '2007-11-06', '00:00:00', '2009-11-26 19:28:11.005115', 'n'); +INSERT IGNORE INTO bb ( col_int_nokey, col_date_nokey, col_time_nokey, col_datetime_nokey, col_varchar_nokey) +VALUES (0, '2003-08-04', '01:48:05.048577', '2006-11-03 00:00:00', 'p'), +(2, '2007-11-06', '00:00:00', '2009-11-26 19:28:11.005115', 'n'); +Warnings: +Note 1265 Data truncated for column 'gcol_time_key' at row 1 +Note 1265 Data truncated for column 'gcol_time_key' at row 2 CREATE TABLE cc ( pk INTEGER AUTO_INCREMENT, -col_int_nokey INTEGER /*! NULL */, -col_int_key INTEGER GENERATED ALWAYS AS -(col_int_nokey + col_int_nokey) VIRTUAL not null, -col_date_nokey DATE /*! NULL */, -col_date_key DATE GENERATED ALWAYS AS -(DATE_ADD(col_date_nokey,interval 30 day)) VIRTUAL not null, -col_datetime_nokey DATETIME /*! NULL */, -col_time_nokey TIME /*! NULL */, -col_datetime_key DATETIME GENERATED ALWAYS AS -(ADDTIME(col_datetime_nokey, col_time_nokey)) VIRTUAL not null, -col_time_key TIME GENERATED ALWAYS AS -(ADDTIME(col_datetime_nokey, col_time_nokey)) VIRTUAL not null, -col_varchar_nokey VARCHAR(1) /*! NULL */, -col_varchar_key VARCHAR(2) GENERATED ALWAYS AS -(CONCAT(col_varchar_nokey, col_varchar_nokey)) VIRTUAL not null, +col_int_nokey INTEGER, +gcol_int_key INTEGER GENERATED ALWAYS AS (col_int_nokey + col_int_nokey) VIRTUAL, +col_date_nokey DATE, +gcol_date_key DATE GENERATED ALWAYS AS (DATE_ADD(col_date_nokey,interval 30 day)) VIRTUAL, +col_datetime_nokey DATETIME, +col_time_nokey TIME, +gcol_datetime_key DATETIME GENERATED ALWAYS AS (ADDTIME(col_datetime_nokey, col_time_nokey)) VIRTUAL, +gcol_time_key TIME GENERATED ALWAYS AS (ADDTIME(col_datetime_nokey, col_time_nokey)) VIRTUAL, +col_varchar_nokey VARCHAR(1), +gcol_varchar_key VARCHAR(2) GENERATED ALWAYS AS (CONCAT(col_varchar_nokey, col_varchar_nokey)) VIRTUAL, PRIMARY KEY (pk), -UNIQUE KEY (col_int_key), -UNIQUE KEY (col_varchar_key), -UNIQUE KEY (col_date_key), -KEY (col_time_key), -KEY (col_datetime_key), -UNIQUE KEY (col_int_key, col_varchar_key), -KEY (col_int_key, col_int_nokey), -KEY(col_int_key,col_date_key), -KEY(col_int_key, col_time_key), -KEY(col_int_key, col_datetime_key), -UNIQUE -KEY(col_date_key,col_time_key,col_datetime_key), -UNIQUE KEY (col_varchar_key, col_varchar_nokey), -UNIQUE KEY (col_int_key, col_varchar_key, -col_date_key, col_time_key, col_datetime_key) +UNIQUE KEY (gcol_int_key), +UNIQUE KEY (gcol_varchar_key), +UNIQUE KEY (gcol_date_key), +KEY (gcol_time_key), +KEY (gcol_datetime_key), +UNIQUE KEY (gcol_int_key, gcol_varchar_key), +KEY (gcol_int_key, col_int_nokey), +KEY(gcol_int_key,gcol_date_key), +KEY(gcol_int_key, gcol_time_key), +KEY(gcol_int_key, gcol_datetime_key), +UNIQUE KEY(gcol_date_key,gcol_time_key,gcol_datetime_key), +UNIQUE KEY (gcol_varchar_key, col_varchar_nokey), +UNIQUE KEY (gcol_int_key, gcol_varchar_key, gcol_date_key, gcol_time_key, gcol_datetime_key) ) AUTO_INCREMENT=10 ENGINE=INNODB; -INSERT /*! IGNORE */ INTO cc ( -col_int_nokey, -col_date_nokey, -col_time_nokey, -col_datetime_nokey, -col_varchar_nokey -) VALUES (172, '2009-04-23', '00:00:00', '2000-12-07 10:17:40.013275', 'h'),(NULL, '2002-10-06', '00:50:49.017545', NULL, 'm'); +INSERT IGNORE INTO cc (col_int_nokey, col_date_nokey, col_time_nokey, col_datetime_nokey, col_varchar_nokey) +VALUES (172, '2009-04-23', '00:00:00', '2000-12-07 10:17:40.013275', 'h'), +(NULL, '2002-10-06', '00:50:49.017545', NULL, 'm'); Warnings: -Warning 1048 Column 'col_int_key' cannot be null -Warning 1048 Column 'col_datetime_key' cannot be null -Warning 1048 Column 'col_time_key' cannot be null +Note 1265 Data truncated for column 'gcol_time_key' at row 1 EXPLAIN SELECT -gp1 . col_datetime_key AS g1 -FROM cc AS gp1 LEFT JOIN c AS gp2 ON ( gp2 . col_datetime_key <> gp1 . +gp1 . gcol_datetime_key AS g1 +FROM cc AS gp1 LEFT JOIN c AS gp2 ON ( gp2 . gcol_datetime_key <> gp1 . col_time_nokey ) WHERE gp1 . col_varchar_nokey IN ( SELECT -DISTINCT p1 . col_varchar_key AS p1 +DISTINCT p1 . gcol_varchar_key AS p1 FROM bb AS p1 LEFT JOIN bb AS p2 -ON ( p1 . col_int_key = p2 . pk ) +ON ( p1 . gcol_int_key = p2 . pk ) ) AND gp1 . col_varchar_nokey = 'b' HAVING g1 > 6; -id select_type table partitions type possible_keys key key_len ref rows filtered Extra -1 SIMPLE gp1 NULL ALL NULL NULL NULL NULL 2 50.00 Using where -1 SIMPLE p1 NULL const col_varchar_key,col_varchar_key_2 col_varchar_key 4 const 1 100.00 NULL -1 SIMPLE p2 NULL eq_ref PRIMARY PRIMARY 4 test.p1.col_int_key 1 100.00 Using index; FirstMatch(gp1) -1 SIMPLE gp2 NULL index NULL col_datetime_key 5 NULL 2 100.00 Using where; Using index; Using join buffer (Block Nested Loop) -Warnings: -Warning 1292 Incorrect datetime value: '6' for column 'col_datetime_key' at row 1 -Note 1003 /* select#1 */ select `test`.`gp1`.`col_datetime_key` AS `g1` from `test`.`cc` `gp1` semi join (`test`.`bb` `p1` left join `test`.`bb` `p2` on((`test`.`p1`.`col_int_key` = `test`.`p2`.`pk`))) left join `test`.`c` `gp2` on((`test`.`gp2`.`col_datetime_key` <> `test`.`gp1`.`col_time_nokey`)) where ((`test`.`gp1`.`col_varchar_nokey` = 'b') and ('b' = `test`.`p1`.`col_varchar_key`)) having (`g1` > 6) +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables SELECT -gp1 . col_datetime_key AS g1 -FROM cc AS gp1 LEFT JOIN c AS gp2 ON ( gp2 . col_datetime_key <> gp1 . +gp1 . gcol_datetime_key AS g1 +FROM cc AS gp1 LEFT JOIN c AS gp2 ON ( gp2 . gcol_datetime_key <> gp1 . col_time_nokey ) WHERE gp1 . col_varchar_nokey IN ( SELECT -DISTINCT p1 . col_varchar_key AS p1 +DISTINCT p1 . gcol_varchar_key AS p1 FROM bb AS p1 LEFT JOIN bb AS p2 -ON ( p1 . col_int_key = p2 . pk ) +ON ( p1 . gcol_int_key = p2 . pk ) ) AND gp1 . col_varchar_nokey = 'b' HAVING g1 > 6; g1 -Warnings: -Warning 1292 Incorrect datetime value: '6' for column 'col_datetime_key' at row 1 DROP TABLE bb, c, cc; # Bug#21284646: Assertion !(table || table->read_set || bitmap_is_set()) CREATE TABLE c ( pk INTEGER AUTO_INCREMENT, col_int_nokey INTEGER NOT NULL, -col_int_key INTEGER GENERATED ALWAYS AS (col_int_nokey + col_int_nokey) VIRTUAL not null, +col_int_key INTEGER GENERATED ALWAYS AS (col_int_nokey + col_int_nokey) VIRTUAL, col_date_nokey DATE NOT NULL, -col_date_key DATE GENERATED ALWAYS AS (DATE_ADD(col_date_nokey,interval 30 day)) VIRTUAL not null, +col_date_key DATE GENERATED ALWAYS AS (DATE_ADD(col_date_nokey,interval 30 day)) VIRTUAL, col_datetime_nokey DATETIME NOT NULL, col_time_nokey TIME NOT NULL, -col_datetime_key DATETIME GENERATED ALWAYS AS (ADDTIME(col_datetime_nokey, col_time_nokey)) VIRTUAL not null, -col_time_key TIME GENERATED ALWAYS AS (ADDTIME(col_datetime_nokey, col_time_nokey)) VIRTUAL not null, +col_datetime_key DATETIME GENERATED ALWAYS AS (ADDTIME(col_datetime_nokey, col_time_nokey)) VIRTUAL, +col_time_key TIME GENERATED ALWAYS AS (ADDTIME(col_datetime_nokey, col_time_nokey)) VIRTUAL, col_varchar_nokey VARCHAR(1) NOT NULL, -col_varchar_key VARCHAR(2) GENERATED ALWAYS AS (CONCAT(col_varchar_nokey, col_varchar_nokey)) VIRTUAL not null, +col_varchar_key VARCHAR(2) GENERATED ALWAYS AS (CONCAT(col_varchar_nokey, col_varchar_nokey)) VIRTUAL, PRIMARY KEY (pk,col_int_nokey), UNIQUE KEY (col_int_key), UNIQUE KEY (col_varchar_key), @@ -264,6 +222,13 @@ INSERT INTO c (col_int_nokey, col_date_nokey, col_time_nokey, col_datetime_nokey (6, '2006-05-25', '19:47:59.011283', '2001-02-15 03:08:38.035426', 'y'), (2, '2002-10-13', '00:00:00', '1900-01-01 00:00:00', 's'), (4, '1900-01-01', '15:57:25.019666', '2005-08-15 00:00:00', 'r'); +Warnings: +Note 1265 Data truncated for column 'col_time_key' at row 1 +Note 1265 Data truncated for column 'col_time_key' at row 2 +Note 1265 Data truncated for column 'col_time_key' at row 3 +Note 1265 Data truncated for column 'col_time_key' at row 4 +Note 1265 Data truncated for column 'col_time_key' at row 5 +Note 1265 Data truncated for column 'col_time_key' at row 6 ANALYZE TABLE c; Table Op Msg_type Msg_text test.c analyze status OK @@ -274,10 +239,8 @@ col_int_nokey <> 9 AND pk >= 8 HAVING x > '2000-02-06' ORDER BY col_time_nokey, pk; -id select_type table partitions type possible_keys key key_len ref rows filtered Extra -1 SIMPLE c NULL index_merge PRIMARY,col_varchar_key,col_int_key_2,col_varchar_key_2,col_int_key_7 col_varchar_key,PRIMARY 4,4 NULL 2 100.00 Using sort_union(col_varchar_key,PRIMARY); Using where -Warnings: -Note 1003 /* select#1 */ select count(distinct `test`.`c`.`col_varchar_key`) AS `x` from `test`.`c` where ((`test`.`c`.`col_varchar_key` in ('rr','rr')) or ((`test`.`c`.`col_int_nokey` <> 9) and (`test`.`c`.`pk` >= 8))) having (`x` > '2000-02-06') +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE c ALL PRIMARY,col_varchar_key,col_varchar_key_2 NULL NULL NULL 6 Using where SELECT COUNT(DISTINCT col_varchar_key) AS x FROM c WHERE col_varchar_key IN ('rr', 'rr') OR @@ -292,15 +255,15 @@ DROP TABLE c; # Bug#21341044: Conditional jump at sort_param::make_sort_key CREATE TABLE t1 ( pk INTEGER AUTO_INCREMENT, -col_int_nokey INTEGER /*! NULL */, +col_int_nokey INTEGER, col_int_key INTEGER GENERATED ALWAYS AS (col_int_nokey + col_int_nokey) VIRTUAL, -col_blob_nokey BLOB /*! NULL */, +col_blob_nokey BLOB, col_blob_key BLOB GENERATED ALWAYS AS (REPEAT(col_blob_nokey,15)) VIRTUAL, -col_longblob_nokey LONGBLOB /*! NULL */, -col_longtext_nokey LONGTEXT /*! NULL */, +col_longblob_nokey LONGBLOB, +col_longtext_nokey LONGTEXT, col_longblob_key LONGBLOB GENERATED ALWAYS AS (REPEAT(col_longblob_nokey, 20)) VIRTUAL, col_longtext_key LONGTEXT GENERATED ALWAYS AS (REPEAT(col_longblob_nokey, 18)) VIRTUAL, -col_text_nokey TEXT /*! NULL */, +col_text_nokey TEXT, col_text_key TEXT GENERATED ALWAYS AS (REPEAT(col_text_nokey, 30)) VIRTUAL, PRIMARY KEY (pk), KEY (col_int_key), @@ -350,7 +313,7 @@ CREATE TABLE t(a int); ALTER TABLE t ADD COLUMN b int GENERATED ALWAYS AS ( date_sub(a,interval a month)) VIRTUAL; ALTER TABLE t ADD COLUMN c int GENERATED ALWAYS AS (sum(a)); -ERROR HY000: Invalid use of group function +ERROR HY000: Function or expression 'sum()' cannot be used in the GENERATED ALWAYS AS clause of `c` DROP TABLE t; # # Bug#21628840: CRASH/MEMORY CORRUPTION ADDING INDEXES TO VIRTUAL COLUMN @@ -368,10 +331,8 @@ test.t1 analyze status OK # Make sure the index is correct. That's kinda important. EXPLAIN SELECT c FROM t1; -id select_type table partitions type possible_keys key key_len ref rows filtered Extra -1 SIMPLE t1 NULL index NULL c 5 NULL 5 100.00 Using index -Warnings: -Note 1003 /* select#1 */ select `test`.`t1`.`c` AS `c` from `test`.`t1` +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 index NULL c 5 NULL 5 Using index SELECT c FROM t1; c 1 @@ -408,20 +369,16 @@ b CHAR(2) GENERATED ALWAYS AS (a IN (1)) VIRTUAL, KEY(c,b(1))); INSERT INTO v (a,c) VALUES (1,1); EXPLAIN SELECT 1 FROM t WHERE ( SELECT 1 FROM t ) >=ANY( SELECT c FROM v ); -id select_type table partitions type possible_keys key key_len ref rows filtered Extra -1 PRIMARY NULL NULL NULL NULL NULL NULL NULL NULL NULL Impossible WHERE -3 SUBQUERY NULL NULL NULL NULL NULL NULL NULL NULL NULL Select tables optimized away -2 SUBQUERY t NULL ALL NULL NULL NULL NULL 1 100.00 NULL -Warnings: -Note 1003 /* select#1 */ select 1 AS `1` from `test`.`t` where 0 +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY NULL NULL NULL NULL NULL NULL NULL Impossible WHERE +3 SUBQUERY NULL NULL NULL NULL NULL NULL NULL Select tables optimized away +2 SUBQUERY NULL NULL NULL NULL NULL NULL NULL no matching row in const table SELECT 1 FROM t WHERE ( SELECT 1 FROM t ) >=ANY( SELECT c FROM v ); 1 EXPLAIN SELECT (SELECT MAX(c) FROM v); -id select_type table partitions type possible_keys key key_len ref rows filtered Extra -1 PRIMARY NULL NULL NULL NULL NULL NULL NULL NULL NULL No tables used -2 SUBQUERY NULL NULL NULL NULL NULL NULL NULL NULL NULL Select tables optimized away -Warnings: -Note 1003 /* select#1 */ select (/* select#2 */ select max(`test`.`v`.`c`) from `test`.`v`) AS `(SELECT MAX(c) FROM v)` +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY NULL NULL NULL NULL NULL NULL NULL No tables used +2 SUBQUERY NULL NULL NULL NULL NULL NULL NULL Select tables optimized away SELECT (SELECT MAX(c) FROM v); (SELECT MAX(c) FROM v) 1 @@ -479,13 +436,18 @@ PRIMARY KEY(c1), UNIQUE KEY(c13) ); INSERT INTO C (c8,c9) VALUES('1970-01-01',0),('1970-01-01',1); +Warnings: +Note 1265 Data truncated for column 'c11' at row 1 +Note 1265 Data truncated for column 'c13' at row 1 +Note 1265 Data truncated for column 'c11' at row 2 +Note 1265 Data truncated for column 'c13' at row 2 CREATE VIEW view_C AS SELECT * FROM C; SELECT /*+ NO_BNL(t1) */ t1.c13 FROM C AS t2 STRAIGHT_JOIN C AS t1 FORCE INDEX(c13); c13 00:00:00 -00:00:01 00:00:00 00:00:01 +00:00:01 SELECT DISTINCT t1.c13 FROM C AS t1, view_C AS t2; c13 00:00:00 @@ -493,17 +455,6 @@ c13 DROP TABLE C; DROP VIEW view_C; # -# Bug #21808680: JSON + GENERATED COLUMN CORRUPTS TABLE CACHE -# MEMORY, CRASHES -# -CREATE TABLE t (a INT, b JSON, c TEXT GENERATED ALWAYS AS (REPEAT(a=b, 2))); -INSERT INTO t (a, b) VALUES (1, '2'), (3, '3'); -SELECT * FROM t; -a b c -1 2 00 -3 3 11 -DROP TABLE t; -# # Bug#21810529: CRASH IN ITEM_FUNC::WALK WHEN CODE JUMPS TO GARBAGE # LOCATION # @@ -522,10 +473,10 @@ DROP TABLE t; # CREATE TABLE t(b BLOB); ALTER TABLE t ADD COLUMN c INT GENERATED ALWAYS AS ((1,1)) VIRTUAL; -ERROR HY000: Expression of generated column 'c' contains a disallowed function. +ERROR 21000: Operand should contain 1 column(s) DROP TABLE t; CREATE TABLE t(b BLOB, c INT GENERATED ALWAYS AS ((1,1)) VIRTUAL); -ERROR HY000: Expression of generated column 'c' contains a disallowed function. +ERROR 21000: Operand should contain 1 column(s) # # Bug#21929967 GCOLS: GCOL VALUE CHANGES WHEN SESSION CHANGES SQL_MODE # @@ -536,14 +487,12 @@ t1 CREATE TABLE `t1` ( `a` char(1) DEFAULT NULL, `b` char(1) DEFAULT NULL, `c` char(2) GENERATED ALWAYS AS ((`a` or `b`)) VIRTUAL -) ENGINE=InnoDB DEFAULT CHARSET=latin1 +) ENGINE=MyISAM DEFAULT CHARSET=latin1 INSERT INTO t1 (a,b) VALUES('1','1'); SELECT * FROM t1; a b c 1 1 1 SET SQL_MODE=PIPES_AS_CONCAT; -Warnings: -Warning 3090 Changing sql mode 'NO_AUTO_CREATE_USER' is deprecated. It will be removed in a future release. SELECT * FROM t1; a b c 1 1 1 @@ -559,7 +508,7 @@ t1 CREATE TABLE `t1` ( `a` char(1) DEFAULT NULL, `b` char(1) DEFAULT NULL, `c` char(2) GENERATED ALWAYS AS (concat(`a`,`b`)) VIRTUAL -) ENGINE=InnoDB DEFAULT CHARSET=latin1 +) ENGINE=MyISAM DEFAULT CHARSET=latin1 INSERT INTO t1 (a,b) VALUES('1','1'); SELECT * FROM t1; a b c @@ -576,17 +525,18 @@ DROP TABLE t1; # Bug#22018999: gcols: assertion failed: !error SET @save_old_sql_mode= @@sql_mode; SET sql_mode=""; -Warnings: -Warning 3090 Changing sql mode 'NO_AUTO_CREATE_USER' is deprecated. It will be removed in a future release. CREATE TABLE t (a INTEGER AS (SUBSTR('','a',1))) engine=innodb; -ERROR 22007: Truncated incorrect INTEGER value: 'a' +Warnings: +Warning 1292 Truncated incorrect INTEGER value: 'a' +DROP TABLE t; CREATE TABLE t (a INTEGER) engine=innodb; ALTER TABLE t ADD b INTEGER AS (SUBSTR('','a',1)); -ERROR 22007: Truncated incorrect INTEGER value: 'a' +Warnings: +Warning 1292 Truncated incorrect INTEGER value: 'a' +Warning 1292 Truncated incorrect INTEGER value: 'a' +Warning 1292 Truncated incorrect INTEGER value: 'a' DROP TABLE t; set sql_mode= @save_old_sql_mode; -Warnings: -Warning 3090 Changing sql mode 'NO_AUTO_CREATE_USER' is deprecated. It will be removed in a future release. # Bug#21875520 Problems with virtual column indexes CREATE TABLE t( a TIMESTAMP, diff --git a/mysql-test/suite/gcol/r/gcol_column_def_options_innodb.result b/mysql-test/suite/gcol/r/gcol_column_def_options_innodb.result index e750bf01d7d..6a738685a5d 100644 --- a/mysql-test/suite/gcol/r/gcol_column_def_options_innodb.result +++ b/mysql-test/suite/gcol/r/gcol_column_def_options_innodb.result @@ -22,11 +22,11 @@ drop table t1; create table t1 (a int); insert into t1 values(1); alter table t1 add column (b int generated always as (a+1) virtual, c int); -affected rows: 0 -info: Records: 0 Duplicates: 0 Warnings: 0 +affected rows: 1 +info: Records: 1 Duplicates: 0 Warnings: 0 alter table t1 add column (d int, e int generated always as (a+1) virtual); -affected rows: 0 -info: Records: 0 Duplicates: 0 Warnings: 0 +affected rows: 1 +info: Records: 1 Duplicates: 0 Warnings: 0 alter table t1 add column (f int generated always as (a+1) virtual, g int as(5) stored); affected rows: 1 info: Records: 1 Duplicates: 0 Warnings: 0 @@ -49,13 +49,21 @@ alter table t1 add column b int generated always as (a+1) virtual AUTO_INCREMENT ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near 'AUTO_INCREMENT' at line 1 drop table t1; # [PRIMARY] KEY +create table t1 (a int, b int generated always as (a+1) virtual key); +ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near 'key)' at line 1 create table t1 (a int, b int generated always as (a+1) stored key); ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near 'key)' at line 1 +create table t1 (a int, b int generated always as (a+1) virtual primary key); +ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near 'primary key)' at line 1 create table t1 (a int, b int generated always as (a+1) stored primary key); ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near 'primary key)' at line 1 create table t1 (a int); +alter table t1 add column b int generated always as (a+1) virtual key; +ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near 'key' at line 1 alter table t1 add column b int generated always as (a+1) stored key; ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near 'key' at line 1 +alter table t1 add column c int generated always as (a+2) virtual primary key; +ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near 'primary key' at line 1 show create table t1; Table Create Table t1 CREATE TABLE `t1` ( @@ -265,14 +273,6 @@ a b c 1 -1 0 2 -2 -1 drop table t1,tt; -# Bug#20769299: INCORRECT KEY ERROR WHEN TRYING TO CREATE INDEX ON -# VIRTUAL GC FOR MYISAM -CREATE TABLE A ( -pk INTEGER, -col_int_nokey INTEGER, -col_int_key INTEGER GENERATED ALWAYS AS (pk + col_int_nokey) VIRTUAL, KEY -(col_int_key)); -ERROR HY000: Key/Index cannot be defined on a non-stored computed column # Bug#20745142: GENERATED COLUMNS: ASSERTION FAILED: # THD->CHANGE_LIST.IS_EMPTY() # @@ -369,6 +369,36 @@ SELECT * FROM t1; c2 c1 5 2 1 5 DROP TABLE t1, t2; +# Bug#21074624:i WL8149:SIG 11 INNOBASE_GET_COMPUTED_VALUE | +# INNOBASE/HANDLER/HA_INNODB.CC:19082 +CREATE TABLE t1 ( +col1 int(11) NOT NULL, +col2 int(11) DEFAULT NULL, +col3 int(11) NOT NULL, +col4 int(11) DEFAULT NULL, +col5 int(11) GENERATED ALWAYS AS (col2 % col4) VIRTUAL, +col6 int(11) GENERATED ALWAYS AS (col3 + col3) VIRTUAL, +col7 int(11) GENERATED ALWAYS AS (col5 / col5) VIRTUAL, +col8 int(11) GENERATED ALWAYS AS (col6 / col5) VIRTUAL, +col9 text, +extra int(11) DEFAULT NULL, +KEY idx (col5) +); +INSERT INTO t1(col1,col2,col3,col4,col9,extra) +VALUES(0,6,3,4,REPEAT(4,1000),0); +ALTER TABLE t1 DROP COLUMN col1; +DROP TABLE t1; +# Bug#21390605:VALGRIND ERROR ON DELETE FROM TABLE CONTAINING +# AN INDEXED VIRTUAL COLUMN +CREATE TABLE t1 ( +a INTEGER, +b INTEGER GENERATED ALWAYS AS (a) VIRTUAL, +c INTEGER GENERATED ALWAYS AS (b) VIRTUAL, +INDEX idx (b,c) +); +INSERT INTO t1 (a) VALUES (42); +DELETE FROM t1 WHERE c = 42; +DROP TABLE t1; # Bug#20757211: GENERATED COLUMNS: ALTER TABLE CRASHES # IN FIND_FIELD_IN_TABLE # @@ -426,11 +456,11 @@ INSERT INTO t(a,b) VALUES(1,2); # Mixed drop/add/rename virtual with non-virtual columns, # ALGORITHM=INPLACE is not supported for InnoDB ALTER TABLE t DROP d, ADD e varchar(10); -affected rows: 0 -info: Records: 0 Duplicates: 0 Warnings: 0 +affected rows: 1 +info: Records: 1 Duplicates: 0 Warnings: 0 ALTER TABLE t ADD d int, ADD f char(10) AS ('aaa'); -affected rows: 0 -info: Records: 0 Duplicates: 0 Warnings: 0 +affected rows: 1 +info: Records: 1 Duplicates: 0 Warnings: 0 ALTER TABLE t CHANGE d dd int, CHANGE f ff varchar(10) AS ('bbb'); affected rows: 1 info: Records: 1 Duplicates: 0 Warnings: 0 @@ -446,11 +476,11 @@ affected rows: 0 info: Records: 0 Duplicates: 0 Warnings: 0 # Change order should be ALGORITHM=INPLACE on Innodb ALTER TABLE t CHANGE c c int(11) as (a) after f; -affected rows: 0 -info: Records: 0 Duplicates: 0 Warnings: 0 +affected rows: 1 +info: Records: 1 Duplicates: 0 Warnings: 0 ALTER TABLE t CHANGE b b int(11) after c; -affected rows: 0 -info: Records: 0 Duplicates: 0 Warnings: 0 +affected rows: 1 +info: Records: 1 Duplicates: 0 Warnings: 0 # TODO: Changing virtual column type should be ALGORITHM=INPLACE on InnoDB, current it goes only with COPY method ALTER TABLE t CHANGE c c varchar(10) as ('a'); affected rows: 1 @@ -459,6 +489,12 @@ info: Records: 1 Duplicates: 0 Warnings: 0 ALTER TABLE t CHANGE dd d varchar(10); affected rows: 1 info: Records: 1 Duplicates: 0 Warnings: 0 +ALTER TABLE t ADD INDEX idx(c), ADD INDEX idx1(d); +affected rows: 0 +info: Records: 0 Duplicates: 0 Warnings: 0 +ALTER TABLE t DROP INDEX idx, DROP INDEX idx1; +affected rows: 0 +info: Records: 0 Duplicates: 0 Warnings: 0 DROP TABLE t; # Bug#21854004: GCOLS:INNODB: FAILING ASSERTION: I < TABLE->N_DEF CREATE TABLE t1( @@ -487,19 +523,34 @@ col1 col2 col3 col4 vgc1 sgc1 2 20 200 NULL 4000 0 ALTER TABLE t1 MODIFY COLUMN vgc1 INTEGER AS (col2 + col3) VIRTUAL; ALTER TABLE t1 MODIFY COLUMN sgc1 INTEGER AS (col2 - col3) STORED; +ALTER TABLE t1 ADD INDEX vgc1 (vgc1); ALTER TABLE t1 ADD INDEX sgc1 (sgc1); +ALTER TABLE t1 MODIFY COLUMN vgc1 INTEGER AS (col2 * col3) VIRTUAL; +SELECT * FROM t1 order by col1; +col1 col2 col3 col4 vgc1 sgc1 +1 10 100 NULL 1000 -90 +2 20 200 NULL 4000 -180 +SELECT vgc1 FROM t1 order by vgc1; +vgc1 +1000 +4000 ALTER TABLE t1 MODIFY COLUMN sgc1 INTEGER AS (col2 / col3) STORED; SELECT * FROM t1 order by col1; col1 col2 col3 col4 vgc1 sgc1 -1 10 100 NULL 110 0 -2 20 200 NULL 220 0 +1 10 100 NULL 1000 0 +2 20 200 NULL 4000 0 SELECT sgc1 FROM t1 order by sgc1; sgc1 0 0 +ALTER TABLE t1 DROP INDEX vgc1; ALTER TABLE t1 DROP INDEX sgc1; +ALTER TABLE t1 MODIFY COLUMN vgc1 INTEGER AS (col2 + col3) VIRTUAL; +ALTER TABLE t1 ADD UNIQUE INDEX vgc1 (vgc1); ALTER TABLE t1 MODIFY COLUMN sgc1 INTEGER AS (col2 - col3) STORED; ALTER TABLE t1 ADD UNIQUE INDEX sgc1 (sgc1); +ALTER TABLE t1 MODIFY COLUMN vgc1 INTEGER AS (col2 / col3) VIRTUAL; +ERROR 23000: Duplicate entry '0' for key 'vgc1' ALTER TABLE t1 MODIFY COLUMN sgc1 INTEGER AS (col2 / col3) STORED; ERROR 23000: Duplicate entry '0' for key 'sgc1' ALTER TABLE t1 MODIFY COLUMN vgc1 INTEGER AS (col2 * col3) VIRTUAL; @@ -536,9 +587,72 @@ col1 col2 col3 col4 vgc1 sgc1 2 20 200 222 4000 4000 DROP TABLE t1; # +# bug#22018979: RECORD NOT FOUND ON UPDATE, +# VIRTUAL COLUMN, ASSERTION 0 +SET @sql_mode_save= @@sql_mode; +SET sql_mode= 'ANSI'; +CREATE TABLE t1 ( +a INT, +b VARCHAR(10), +c CHAR(3) GENERATED ALWAYS AS (substr(b,1,3)) VIRTUAL, +PRIMARY KEY (a), +KEY c(c) +); +INSERT INTO t1(a, b) values(1, 'bbbb'), (2, 'cc'); +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE "t1" ( + "a" int(11) NOT NULL, + "b" varchar(10) DEFAULT NULL, + "c" char(3) AS (substr(b,1,3)) VIRTUAL, + PRIMARY KEY ("a"), + KEY "c" ("c") +) +SELECT * FROM t1 order by a; +a b c +1 bbbb bbb +2 cc cc +SET sql_mode= ''; +FLUSH TABLE t1; +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` int(11) NOT NULL, + `b` varchar(10) DEFAULT NULL, + `c` char(3) AS (substr(b,1,3)) VIRTUAL, + PRIMARY KEY (`a`), + KEY `c` (`c`) +) ENGINE=InnoDB DEFAULT CHARSET=latin1 +SELECT * FROM t1 order by a; +a b c +1 bbbb bbb +2 cc cc +DELETE FROM t1 where a= 2; +SET sql_mode= @sql_mode_save; +DROP TABLE t1; +# # Bug#22680839: DEFAULT IS NOT DETERMINISTIC AND SHOULD NOT BE # ALLOWED IN GENERATED COLUMNS # +CREATE TABLE tzz(a INT DEFAULT 5, +gc1 INT AS (a+DEFAULT(a)) VIRTUAL, +gc2 INT AS (a+DEFAULT(a)) STORED, +KEY k1(gc1)); +INSERT INTO tzz(A) VALUES (1); +SELECT * FROM tzz; +a gc1 gc2 +1 6 6 +SELECT gc1 FROM tzz; +gc1 +6 +ALTER TABLE tzz MODIFY COLUMN a INT DEFAULT 6; +SELECT * FROM tzz; +a gc1 gc2 +1 7 7 +SELECT gc1 FROM tzz; +gc1 +7 +DROP TABLE tzz; # Test 1: ALTER DEFAULT # CREATE TABLE t1(a INT PRIMARY KEY DEFAULT 5, @@ -546,11 +660,11 @@ b INT AS (1 + DEFAULT(a)) STORED, c INT AS (1 + DEFAULT(a)) VIRTUAL); INSERT INTO t1 VALUES (); ALTER TABLE t1 ALTER COLUMN a SET DEFAULT 7; -affected rows: 0 -info: Records: 0 Duplicates: 0 Warnings: 0 +affected rows: 1 +info: Records: 1 Duplicates: 0 Warnings: 0 ALTER TABLE t1 MODIFY COLUMN a INT DEFAULT 8; -affected rows: 0 -info: Records: 0 Duplicates: 0 Warnings: 0 +affected rows: 1 +info: Records: 1 Duplicates: 0 Warnings: 0 ALTER TABLE t1 CHANGE COLUMN a a DOUBLE DEFAULT 5; affected rows: 1 info: Records: 1 Duplicates: 0 Warnings: 0 @@ -565,8 +679,8 @@ affected rows: 1 info: Records: 1 Duplicates: 0 Warnings: 0 ALTER TABLE t1 ALTER COLUMN a SET DEFAULT 7, ADD COLUMN c1 INT AS (1 + DEFAULT(a)) VIRTUAL; -affected rows: 0 -info: Records: 0 Duplicates: 0 Warnings: 0 +affected rows: 1 +info: Records: 1 Duplicates: 0 Warnings: 0 ALTER TABLE t1 ALTER COLUMN a SET DEFAULT 7, ADD COLUMN b INT AS (1 + DEFAULT(a)) STORED, ADD COLUMN c INT AS (1 + DEFAULT(a)) VIRTUAL; diff --git a/mysql-test/suite/gcol/r/gcol_ins_upd_myisam.result b/mysql-test/suite/gcol/r/gcol_ins_upd_myisam.result index 121978e2ec7..12e296972eb 100644 --- a/mysql-test/suite/gcol/r/gcol_ins_upd_myisam.result +++ b/mysql-test/suite/gcol/r/gcol_ins_upd_myisam.result @@ -550,6 +550,10 @@ b TIMESTAMP(4) GENERATED ALWAYS AS ('') VIRTUAL, KEY (a(183),b) ); INSERT INTO t VALUES(), (), (); +Warnings: +Warning 1265 Data truncated for column 'b' at row 1 +Warning 1265 Data truncated for column 'b' at row 2 +Warning 1265 Data truncated for column 'b' at row 3 DELETE IGNORE FROM t; DROP TABLE t; # diff --git a/mysql-test/suite/gcol/r/gcol_rollback.result b/mysql-test/suite/gcol/r/gcol_rollback.result index 006c8408a84..3fe40d1eccd 100644 --- a/mysql-test/suite/gcol/r/gcol_rollback.result +++ b/mysql-test/suite/gcol/r/gcol_rollback.result @@ -18,7 +18,6 @@ a b 9 9 BEGIN; INSERT INTO t (a) VALUES (10); -# Kill and restart SELECT * FROM t; a b 9 9 @@ -32,8 +31,11 @@ INSERT INTO t (a,c) VALUES (9, 10); SELECT * FROM t; a b c 9 9 10 +connect con1,localhost,root,,; +connection con1; SET DEBUG_SYNC = 'row_log_apply_after SIGNAL created WAIT_FOR dml_done'; ALTER TABLE t ADD KEY(b(57)), ALGORITHM=INPLACE; +connection default; SET DEBUG_SYNC = 'now WAIT_FOR created'; BEGIN; INSERT INTO t (a,c) VALUES (10, 12); @@ -43,6 +45,9 @@ a b c 10 10 12 ROLLBACK; SET DEBUG_SYNC = 'now SIGNAL dml_done'; +connection con1; +disconnect con1; +connection default; SELECT * FROM t; a b c 9 9 10 @@ -58,8 +63,11 @@ INSERT INTO t (a,b) VALUES (9, 10); SELECT * FROM t; a b c d 9 10 19 29 +connect con1,localhost,root,,; +connection con1; SET DEBUG_SYNC = 'row_log_apply_after SIGNAL created WAIT_FOR dml_done'; ALTER TABLE t DROP COLUMN c, ALGORITHM=INPLACE; +connection default; SET DEBUG_SYNC = 'now WAIT_FOR created'; BEGIN; INSERT INTO t (a,b) VALUES (10, 12); @@ -69,7 +77,11 @@ a b c d 10 12 22 34 ROLLBACK; SET DEBUG_SYNC = 'now SIGNAL dml_done'; +connection con1; +disconnect con1; +connection default; SELECT * FROM t; a b d 9 10 29 DROP TABLE t; +SET DEBUG_SYNC = 'RESET'; diff --git a/mysql-test/suite/gcol/r/gcol_select_innodb.result b/mysql-test/suite/gcol/r/gcol_select_innodb.result index e815cfcbe8e..24daadb0d5b 100644 --- a/mysql-test/suite/gcol/r/gcol_select_innodb.result +++ b/mysql-test/suite/gcol/r/gcol_select_innodb.result @@ -563,6 +563,8 @@ id select_type table type possible_keys key key_len ref rows Extra SELECT /*+ bka() */ 1 AS c FROM t AS b RIGHT JOIN t AS c ON b.a > c.c WHERE b.b>c.a; c +Warnings: +Warning 1292 Truncated incorrect DOUBLE value: 'cccc' DROP TABLE t; set @optimizer_switch_save = @@optimizer_switch; set optimizer_switch='mrr_cost_based=off'; diff --git a/mysql-test/suite/gcol/r/innodb_partition.result b/mysql-test/suite/gcol/r/innodb_partition.result new file mode 100644 index 00000000000..8cdf8d41a7a --- /dev/null +++ b/mysql-test/suite/gcol/r/innodb_partition.result @@ -0,0 +1,26 @@ +# +# Bug#22444530 - GCOLS + PARTITIONED TABLE, CRASH IN +# +set sql_mode=''; +create table t ( +a int not null, +b int generated always as (1) virtual, +c int generated always as (1) virtual, +key (c) +) engine=innodb partition by key (a) partitions 2; +insert into t(a) values(1); +select b from t group by c; +b +1 +drop table t; +create table t ( +a int not null, +b blob generated always as ("a") virtual, +c int generated always as (1) virtual, +key (c) +) engine=innodb partition by key (a) partitions 2; +insert into t(a) values(1); +select b from t group by c; +b +a +drop table t; diff --git a/mysql-test/suite/gcol/r/innodb_prefix_index_check.result b/mysql-test/suite/gcol/r/innodb_prefix_index_check.result new file mode 100644 index 00000000000..01dbe4a6592 --- /dev/null +++ b/mysql-test/suite/gcol/r/innodb_prefix_index_check.result @@ -0,0 +1,15 @@ +#Bug #22445211 GCOLS: SIMPLE DML, FAILING ASSERTION: +#!CURSOR->INDEX->IS_COMMITTED() +#Create and alter table examples for virtual column for full +#column index followed by prefix index. +CREATE TABLE t1( +f1 INT DEFAULT NULL, +f2 CHAR(2) GENERATED ALWAYS AS ('11') VIRTUAL, +f3 INT, +UNIQUE KEY(f1), +UNIQUE KEY(f3,f1), +KEY(f2,f1), +key(f1,f2(1)) +)ENGINE=INNODB; +REPLACE INTO t1(f3) VALUES (1),(1); +DROP TABLE t1; diff --git a/mysql-test/suite/gcol/r/innodb_virtual_basic.result b/mysql-test/suite/gcol/r/innodb_virtual_basic.result new file mode 100644 index 00000000000..bcd969c84fb --- /dev/null +++ b/mysql-test/suite/gcol/r/innodb_virtual_basic.result @@ -0,0 +1,1562 @@ +call mtr.add_suppression("\\[Warning\\] InnoDB: Compute virtual"); +set default_storage_engine=innodb; +CREATE TABLE t (a INT, b INT GENERATED ALWAYS AS (a), c CHAR(10), d CHAR(20), e CHAR(10) GENERATED ALWAYS AS (c), g INT); +INSERT INTO t VALUES(10, DEFAULT, "aa", "bb", DEFAULT, 20); +INSERT INTO t VALUES(11, DEFAULT, "jj", "kk", DEFAULT, 21); +CREATE INDEX idx ON t(e) algorithm=inplace; +INSERT INTO t VALUES(12, DEFAULT, 'mm', "nn", DEFAULT, 22); +SELECT e FROM t; +e +aa +jj +mm +DROP TABLE t; +CREATE TABLE t (a INT, b INT, c INT GENERATED ALWAYS AS(a+b), h VARCHAR(10)); +INSERT INTO t VALUES (11, 3, DEFAULT, 'mm'); +INSERT INTO t VALUES (18, 1, DEFAULT, 'mm'); +INSERT INTO t VALUES (28, 1, DEFAULT, 'mm'); +INSERT INTO t VALUES (null, null, DEFAULT, 'mm'); +CREATE INDEX idx ON t(c); +SELECT c FROM t; +c +NULL +14 +19 +29 +UPDATE t SET a = 10 WHERE a = 11; +SELECT c FROM t; +c +NULL +13 +19 +29 +SELECT * FROM t; +a b c h +10 3 13 mm +18 1 19 mm +28 1 29 mm +NULL NULL NULL mm +DELETE FROM t WHERE a = 18; +SELECT c FROM t; +c +NULL +13 +29 +START TRANSACTION; +INSERT INTO t VALUES (128, 22, DEFAULT, "xx"); +INSERT INTO t VALUES (1290, 212, DEFAULT, "xmx"); +ROLLBACK; +SELECT c FROM t; +c +NULL +13 +29 +SELECT * FROM t; +a b c h +10 3 13 mm +28 1 29 mm +NULL NULL NULL mm +DROP TABLE t; +CREATE TABLE t (a INT, b INT, c INT GENERATED ALWAYS AS(a+b), h VARCHAR(10), j INT, m INT GENERATED ALWAYS AS(b + j), n VARCHAR(10), p VARCHAR(20) GENERATED ALWAYS AS(CONCAT(n, h)), INDEX idx1(c), INDEX idx2 (m), INDEX idx3(p)); +INSERT INTO t VALUES(11, 22, DEFAULT, "AAA", 8, DEFAULT, "XXX", DEFAULT); +INSERT INTO t VALUES(1, 2, DEFAULT, "uuu", 9, DEFAULT, "uu", DEFAULT); +INSERT INTO t VALUES(3, 4, DEFAULT, "uooo", 1, DEFAULT, "umm", DEFAULT); +SELECT c FROM t; +c +3 +7 +33 +SELECT m FROM t; +m +5 +11 +30 +SELECT p FROM t; +p +ummuooo +uuuuu +XXXAAA +SELECT * FROM t; +a b c h j m n p +11 22 33 AAA 8 30 XXX XXXAAA +1 2 3 uuu 9 11 uu uuuuu +3 4 7 uooo 1 5 umm ummuooo +update t set a = 13 where a =11; +delete from t where a =13; +DROP INDEX idx1 ON t; +DROP INDEX idx2 ON t; +DROP TABLE t; +/* Test large BLOB data */ +CREATE TABLE `t` ( +`a` BLOB, +`b` BLOB, +`c` BLOB GENERATED ALWAYS AS (CONCAT(a,b)) VIRTUAL, +`h` VARCHAR(10) DEFAULT NULL +) ENGINE=InnoDB; +INSERT INTO t VALUES (REPEAT('g', 16000), REPEAT('x', 16000), DEFAULT, "kk"); +CREATE INDEX idx ON t(c(100)); +SELECT length(c) FROM t; +length(c) +32000 +START TRANSACTION; +INSERT INTO t VALUES (REPEAT('a', 16000), REPEAT('b', 16000), DEFAULT, 'mm'); +ROLLBACK; +INSERT INTO t VALUES (REPEAT('a', 16000), REPEAT('b', 16000), DEFAULT, 'mm'); +START TRANSACTION; +UPDATE t SET a = REPEAT('m', 16000) WHERE a like "aaa%"; +ROLLBACK; +SELECT COUNT(*) FROM t WHERE c like "aaa%"; +COUNT(*) +1 +DROP TABLE t; +CREATE TABLE t (a INT, b INT, c INT GENERATED ALWAYS AS(a+b), h VARCHAR(10)); +INSERT INTO t VALUES (11, 3, DEFAULT, 'mm'); +INSERT INTO t VALUES (18, 1, DEFAULT, 'mm'); +INSERT INTO t VALUES (28, 1, DEFAULT, 'mm'); +CREATE INDEX idx ON t(c); +START TRANSACTION; +UPDATE t SET a = 100 WHERE a = 11; +UPDATE t SET a =22 WHERE a = 18; +UPDATE t SET a = 33 WHERE a = 22; +SELECT c FROM t; +c +29 +34 +103 +ROLLBACK; +SELECT c FROM t; +c +14 +19 +29 +DROP TABLE t; +CREATE TABLE t (a INT, b INT, c INT GENERATED ALWAYS AS(a+b), h VARCHAR(10)); +INSERT INTO t VALUES (11, 3, DEFAULT, 'mm'); +INSERT INTO t VALUES (18, 1, DEFAULT, 'mm'); +INSERT INTO t VALUES (28, 1, DEFAULT, 'mm'); +CREATE INDEX idx ON t(c); +SELECT c FROM t; +c +14 +19 +29 +connect con1,localhost,root,,test; +START TRANSACTION; +SELECT c FROM t; +c +14 +19 +29 +connection default; +UPDATE t SET a = 19 WHERE a = 11; +connection con1; +SELECT c FROM t; +c +14 +19 +29 +ROLLBACK; +SELECT c FROM t; +c +19 +22 +29 +connection default; +disconnect con1; +DROP TABLE t; +CREATE TABLE t (a INT, b INT, c INT GENERATED ALWAYS AS(a+b), h VARCHAR(10), j INT, m INT GENERATED ALWAYS AS(b + x), n VARCHAR(10), p VARCHAR(20) GENERATED ALWAYS AS(CONCAT(n, y)), x INT, y CHAR(20), z INT, INDEX idx1(c), INDEX idx2 (m), INDEX idx3(p)); +INSERT INTO t VALUES(1, 2, DEFAULT, "hhh", 3, DEFAULT, "nnn", DEFAULT, 4, "yyy", 5); +INSERT INTO t VALUES(2, 3, DEFAULT, "hhha", 4, DEFAULT, "nnna", DEFAULT, 5, "yyya", 6); +INSERT INTO t VALUES(12, 13, DEFAULT, "hhhb", 14, DEFAULT, "nnnb", DEFAULT, 15, "yyyb", 16); +CREATE INDEX idx6 ON t(p, c); +SELECT p, c FROM t; +p c +nnnayyya 5 +nnnbyyyb 25 +nnnyyy 3 +START TRANSACTION; +INSERT INTO t VALUES(32, 33, DEFAULT, "hhhb", 34, DEFAULT, "nnnb", DEFAULT, 35, "yyyb", 36); +ROLLBACK; +UPDATE t SET a = 100 WHERE a = 1; +START TRANSACTION; +UPDATE t SET a = 1 WHERE a = 100; +ROLLBACK; +DROP TABLE t; +CREATE TABLE t1(a INT); +ALTER TABLE t1 add COLUMN (b INT generated always as (a+1) virtual, c INT as(5) virtual); +ALTER TABLE t1 add COLUMN (d INT generated always as (a+1) virtual, e INT as(5) virtual); +SELECT pos, base_pos FROM informatiON_schema.innodb_sys_virtual; +pos base_pos +65537 0 +196611 0 +ALTER TABLE t1 add COLUMN (f INT generated always as (a+1) virtual, g INT as(5) virtual), DROP COLUMN e; +SELECT pos, base_pos FROM informatiON_schema.innodb_sys_virtual; +pos base_pos +65537 0 +196611 0 +262148 0 +DROP TABLE t1; +CREATE TABLE t1(a INT); +INSERT INTO t1 VALUES(1); +ALTER TABLE t1 add COLUMN (f INT generated always as (a+1) virtual, g INT ); +ALTER TABLE t1 add COLUMN (h INT generated always as (a+1) virtual), add INDEX idx (h), algorithm=inplace; +ALTER TABLE t1 add COLUMN (h1 INT generated always as (a+1) virtual), add INDEX idx1 (h1); +affected rows: 0 +info: Records: 0 Duplicates: 0 Warnings: 0 +ALTER TABLE t1 DROP COLUMN h1, DROP INDEX idx; +DROP TABLE t1; +CREATE TABLE t1(a INT); +CREATE INDEX idx ON t1(a); +CREATE TABLE t3(a INT, b INT , INDEX(b), CONSTRAINT x FOREIGN KEY(b) REFERENCES t1(a)); +CREATE TABLE t2(a INT, b INT generated always as (a+1) virtual, INDEX(b), CONSTRAINT x FOREIGN KEY(b) REFERENCES t1(a)); +ERROR HY000: Can't create table `test`.`t2` (errno: 150 "Foreign key constraint is incorrectly formed") +CREATE TABLE t2(a INT, b INT generated always as (a+1) virtual, INDEX(b)); +DROP TABLE t3; +DROP TABLE t2; +DROP TABLE t1; +CREATE TABLE t1(a INT); +ALTER TABLE t1 add COLUMN (b INT generated always as (a+1) virtual, c INT as(5) virtual); +ALTER TABLE t1 change b x INT generated always as (a+1) virtual; +SELECT pos, base_pos FROM informatiON_schema.innodb_sys_virtual; +pos base_pos +65537 0 +DROP TABLE t1; +CREATE TABLE t (a TEXT, b TEXT GENERATED ALWAYS AS (a), fulltext INDEX idx (b)); +ERROR HY000: This is not yet supported for computed columns +CREATE TABLE t (a TEXT, b TEXT GENERATED ALWAYS AS (a)); +ALTER TABLE t ADD FULLTEXT INDEX (b); +ERROR HY000: This is not yet supported for computed columns +DROP TABLE t; +CREATE TABLE t (a geometry not null, b geometry GENERATED ALWAYS AS (a), spatial INDEX idx (b)); +ERROR 42000: All parts of a SPATIAL index must be NOT NULL +CREATE TABLE t (a geometry not null, b geometry GENERATED ALWAYS AS (a)); +ALTER TABLE t ADD SPATIAL INDEX (b); +ERROR 42000: All parts of a SPATIAL index must be NOT NULL +DROP TABLE t; +CREATE TABLE t (a INT DEFAULT 1, b INT DEFAULT 2, c INT GENERATED ALWAYS AS(a+b), h VARCHAR(10)); +CREATE INDEX idx ON t(c); +INSERT INTO t(h)VALUES ('mm'); +SELECT c FROM t; +c +3 +CREATE unique INDEX idx1 ON t(c); +INSERT INTO t(h)VALUES ('mm'); +ERROR 23000: Duplicate entry '3' for key 'idx1' +DROP TABLE t; +CREATE TABLE `t1` ( `a` INT(11) DEFAULT NULL, `b` INT(11) DEFAULT NULL, `c` INT(11) GENERATED ALWAYS AS (a+b) VIRTUAL, `x` INT(11) NOT NULL, `h` VARCHAR(10) DEFAULT NULL, PRIMARY KEY (`x`), KEY `idx` (`c`) ) ENGINE=InnoDB DEFAULT CHARSET=latin1; +INSERT INTO t1 VALUES (1, 2, DEFAULT, 3, 'mm'); +INSERT INTO t1 VALUES (11, 22, DEFAULT, 23, 'mm'); +connect con1,localhost,root,,test; +UPDATE t1 SET x = 4 WHERE x =3; +DROP TABLE t1; +CREATE TABLE `t1` ( `a` INT(11) DEFAULT NULL, `b` INT(11) DEFAULT NULL, `c` INT(11) GENERATED ALWAYS AS (a+b) VIRTUAL, `x` INT(11) NOT NULL, `h` VARCHAR(10) DEFAULT NULL, KEY `idx` (`c`) ) ENGINE=InnoDB DEFAULT CHARSET=latin1; +INSERT INTO t1 VALUES (1, 2, DEFAULT, 3, 'mm'); +INSERT INTO t1 VALUES (11, 22, DEFAULT, 23, 'mm'); +START TRANSACTION; +SELECT * FROM t1; +a b c x h +1 2 3 3 mm +11 22 33 23 mm +connection con1; +START TRANSACTION; +UPDATE t1 SET x = 15 WHERE x = 3; +UPDATE t1 SET b = 10 WHERE b=2; +ROLLBACK; +connection default; +SELECT c FROM t1; +c +3 +33 +disconnect con1; +DROP TABLE t1; +CREATE TABLE `t` ( +`a` INT(11) DEFAULT NULL, +`b` INT(11) DEFAULT NULL, +`c` INT(11) GENERATED ALWAYS AS (a+b) VIRTUAL, +`d` INT(11) GENERATED ALWAYS AS (a) VIRTUAL, +`h` INT(11) NOT NULL, +PRIMARY KEY (`h`), +KEY `idx` (`c`) +) ENGINE=InnoDB; +INSERT INTO t VALUES (11, 3, DEFAULT, DEFAULT, 1); +INSERT INTO t VALUES (18, 1, DEFAULT, DEFAULT, 2); +INSERT INTO t VALUES (28, 1, DEFAULT, DEFAULT, 3); +INSERT INTO t VALUES (null, null, DEFAULT, DEFAULT, 4); +CREATE PROCEDURE UPDATE_t() +begin +DECLARE i INT DEFAULT 1; +WHILE (i <= 2000) DO +UPDATE t SET a = 100 + i WHERE h = 1; +SET i = i + 1; +END WHILE; +END| +CREATE PROCEDURE DELETE_insert_t() +begin +DECLARE i INT DEFAULT 1; +WHILE (i <= 2000) DO +UPDATE t SET a = 100 + i WHERE h = 1; +SET i = i + 1; +END WHILE; +END| +CALL UPDATE_t(); +SELECT c FROM t; +c +NULL +19 +29 +2103 +CALL DELETE_insert_t(); +SELECT c FROM t; +c +NULL +19 +29 +2103 +DROP INDEX idx ON t; +CALL UPDATE_t(); +SELECT c FROM t; +c +2103 +19 +29 +NULL +DROP PROCEDURE DELETE_insert_t; +DROP PROCEDURE UPDATE_t; +DROP TABLE t; +# Bug#20767937: WL8149:ASSERTION FAILED IN ROW_UPD_SEC_INDEX_ENTRY +CREATE TABLE b ( +col_INT_nokey INTEGER NOT NULL, +col_INT_key INTEGER GENERATED ALWAYS AS (col_INT_nokey) VIRTUAL, +col_date_nokey DATE, +col_date_key DATE GENERATED ALWAYS AS (DATE_ADD(col_date_nokey, +INTerval 30 day)) VIRTUAL, +col_datetime_nokey DATETIME NOT NULL, +col_time_nokey TIME NOT NULL, +col_datetime_key DATETIME GENERATED ALWAYS AS (ADDTIME(col_datetime_nokey, +col_time_nokey)), +col_time_key TIME GENERATED ALWAYS AS (ADDTIME(col_datetime_nokey, +col_time_nokey)), +col_VARCHAR_nokey VARCHAR(1) NOT NULL, +col_VARCHAR_key VARCHAR(2) GENERATED ALWAYS AS(CONCAT(col_VARCHAR_nokey, +col_VARCHAR_nokey)), +KEY (col_INT_key), +KEY (col_VARCHAR_key), +KEY (col_date_key), +KEY (col_time_key), +KEY (col_datetime_key), +KEY (col_INT_key, col_VARCHAR_key), +KEY (col_INT_key, col_VARCHAR_key, col_date_key, +col_time_key, col_datetime_key) +); +INSERT INTO b ( +col_INT_nokey, +col_date_nokey, +col_time_nokey, +col_datetime_nokey, +col_VARCHAR_nokey +) VALUES +(0, NULL, '21:22:34.025509', '2002-02-13 17:30:06.013935', 'j'), +(8, '2004-09-18', '10:50:38.059966', '2008-09-27 +00:34:58.026613', 'v'); +Warnings: +Note 1265 Data truncated for column 'col_time_key' at row 1 +Note 1265 Data truncated for column 'col_time_key' at row 2 +EXPLAIN SELECT col_INT_key FROM b; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE b index NULL col_INT_key 5 NULL 2 Using index +SELECT col_INT_key FROM b; +col_INT_key +0 +8 +SELECT col_INT_nokey, col_INT_key FROM b; +col_INT_nokey col_INT_key +0 0 +8 8 +DELETE FROM b; +DROP TABLE b; +CREATE TABLE `t` ( +`a` VARCHAR(10000), `b` VARCHAR(3000), +`c` VARCHAR(14000) GENERATED ALWAYS AS (CONCAT(a,b)) VIRTUAL, +`d` VARCHAR(5000) GENERATED ALWAYS AS (b) VIRTUAL, +`e` INT(11) GENERATED ALWAYS AS (10) VIRTUAL, +`h` INT(11) NOT NULL, +PRIMARY KEY (`h`) ) ROW_FORMAT=COMPACT ENGINE=InnoDB; +SHOW CREATE TABLE t; +Table Create Table +t CREATE TABLE `t` ( + `a` varchar(10000) DEFAULT NULL, + `b` varchar(3000) DEFAULT NULL, + `c` varchar(14000) AS (concat(`a`,`b`)) VIRTUAL, + `d` varchar(5000) AS (`b`) VIRTUAL, + `e` int(11) AS (10) VIRTUAL, + `h` int(11) NOT NULL, + PRIMARY KEY (`h`) +) ENGINE=InnoDB DEFAULT CHARSET=latin1 ROW_FORMAT=COMPACT +INSERT INTO t VALUES (REPEAT('g', 10000), REPEAT('x', 2800), DEFAULT, DEFAULT, DEFAULT, 1); +INSERT INTO t VALUES (REPEAT('a', 9000), REPEAT('b', 2000), DEFAULT, DEFAULT, DEFAULT, 2); +INSERT INTO t VALUES (REPEAT('m', 8000), REPEAT('n', 3000), DEFAULT, DEFAULT, DEFAULT, 3); +CREATE INDEX idx ON t(c(100), d(20)); +UPDATE t SET a = REPEAT(CAST(1 AS CHAR), 2000) WHERE h = 1; +CREATE PROCEDURE UPDATE_t() +begin +DECLARE i INT DEFAULT 1; +WHILE (i <= 100) DO +UPDATE t SET a = REPEAT(CAST(i AS CHAR), 2000) WHERE h = 1; +SET i = i + 1; +END WHILE; +END| +CREATE PROCEDURE DELETE_insert_t() +begin +DECLARE i INT DEFAULT 1; +WHILE (i <= 100) DO +DELETE FROM t WHERE h = 1; +INSERT INTO t VALUES (REPEAT(CAST(i AS CHAR), 2000) , REPEAT('b', 2000), DEFAULT, DEFAULT, DEFAULT, 1); +SET i = i + 1; +END WHILE; +END| +CALL UPDATE_t(); +CALL DELETE_insert_t(); +UPDATE t SET a = NULL WHERE h=1; +START TRANSACTION; +CALL UPDATE_t(); +ROLLBACK; +DROP PROCEDURE DELETE_insert_t; +DROP PROCEDURE UPDATE_t; +DROP TABLE t; +CREATE TABLE `t` ( +`a` BLOB, +`b` BLOB, +`c` BLOB GENERATED ALWAYS AS (CONCAT(a,b)) VIRTUAL, +`d` BLOB GENERATED ALWAYS AS (b) VIRTUAL, +`e` INT(11) GENERATED ALWAYS AS (10) VIRTUAL, +`h` INT(11) NOT NULL, +PRIMARY KEY (`h`) +) ENGINE=InnoDB; +INSERT INTO t VALUES (REPEAT('g', 16000), REPEAT('x', 16000), DEFAULT, DEFAULT, DEFAULT, 1); +INSERT INTO t VALUES (REPEAT('a', 32000), REPEAT('b', 11000), DEFAULT, DEFAULT, DEFAULT, 2); +INSERT INTO t VALUES (REPEAT('m', 18000), REPEAT('n', 46000), DEFAULT, DEFAULT, DEFAULT, 3); +CREATE INDEX idx ON t(c(100), d(20)); +UPDATE t SET a = NULL WHERE h=1; +UPDATE t SET a = REPEAT(CAST(1 AS CHAR), 2000) WHERE h = 1; +UPDATE t SET a = REPEAT(CAST(1 AS CHAR), 1000) WHERE h = 1; +CREATE PROCEDURE UPDATE_t() +begin +DECLARE i INT DEFAULT 1; +WHILE (i <= 200) DO +UPDATE t SET a = REPEAT(CAST(i AS CHAR), 2000) WHERE h = 1; +SET i = i + 1; +END WHILE; +END| +CREATE PROCEDURE DELETE_insert_t() +begin +DECLARE i INT DEFAULT 1; +WHILE (i <= 200) DO +DELETE FROM t WHERE h = 1; +INSERT INTO t VALUES (REPEAT(CAST(i AS CHAR), 2000) , REPEAT('b', 2000), DEFAULT, DEFAULT, DEFAULT, 1); +SET i = i + 1; +END WHILE; +END| +CALL UPDATE_t(); +CALL DELETE_insert_t(); +UPDATE t SET a = NULL WHERE h=1; +DROP PROCEDURE DELETE_insert_t; +DROP PROCEDURE UPDATE_t; +DROP TABLE t; +CREATE TABLE `t` ( +`m1` INT(11) DEFAULT NULL, +`m2` INT(11) DEFAULT NULL, +`m3` INT(11) GENERATED ALWAYS AS (m1 + m2) VIRTUAL, +`m4` INT(11) DEFAULT NULL, +`m5` CHAR(10) DEFAULT NULL, +`m6` CHAR(12) GENERATED ALWAYS AS (m5) VIRTUAL, +`a` VARCHAR(10000) DEFAULT NULL, +`b` VARCHAR(3000) DEFAULT NULL, +`c` VARCHAR(14000) GENERATED ALWAYS AS (CONCAT(a,b)) VIRTUAL, +`d` VARCHAR(5000) GENERATED ALWAYS AS (b) VIRTUAL, +`e` INT(11) GENERATED ALWAYS AS (10) VIRTUAL, +`h` INT(11) NOT NULL, +PRIMARY KEY (`h`), +KEY `m3` (`m3`), +KEY `c` (`c`(100)), +KEY `e` (`e`,`d`(20)) +) ENGINE=InnoDB; +INSERT INTO t VALUES (1, 2, DEFAULT, 3, "aaa", DEFAULT, REPEAT('g', 10000), REPEAT('x', 2800), DEFAULT, DEFAULT, DEFAULT, 1); +INSERT INTO t VALUES (11, 21, DEFAULT, 31, "bbb", DEFAULT, REPEAT('a', 9000), REPEAT('b', 2000), DEFAULT, DEFAULT, DEFAULT, 2); +INSERT INTO t VALUES (21, 31, DEFAULT, 41, "zzz", DEFAULT, REPEAT('m', 8000), REPEAT('n', 3000), DEFAULT, DEFAULT, DEFAULT, 3); +ALTER TABLE t DROP COLUMN c; +DELETE FROM t; +DROP TABLE t; +CREATE TABLE t (a INT, b INT, c INT GENERATED ALWAYS AS(a+b), h VARCHAR(10)); +INSERT INTO t VALUES (11, 3, DEFAULT, 'mm'); +INSERT INTO t VALUES (18, 1, DEFAULT, 'mm'); +INSERT INTO t VALUES (28, 1, DEFAULT, 'mm'); +INSERT INTO t VALUES (null, null, DEFAULT, 'mm'); +CREATE INDEX idx ON t(a, c); +SELECT a, c FROM t; +a c +NULL NULL +11 14 +18 19 +28 29 +START TRANSACTION; +UPDATE t SET a = 13 where a = 11; +ROLLBACK; +DELETE FROM t; +DROP TABLE t; +CREATE TABLE t (a INT, b INT, c INT GENERATED ALWAYS AS(a+b), h VARCHAR(10), m int); +INSERT INTO t VALUES (11, 3, DEFAULT, "a", 1); +INSERT INTO t VALUES (18, 1, DEFAULT, "b", 2); +INSERT INTO t VALUES (28, 1, DEFAULT, "c", 3 ); +INSERT INTO t VALUES (null, null, DEFAULT, "d", 4); +CREATE INDEX idx ON t(a, c, h); +SELECT a, c FROM t; +a c +NULL NULL +11 14 +18 19 +28 29 +START TRANSACTION; +UPDATE t SET m =10 WHERE m = 1; +UPDATE t SET h = "e" WHERE h="a"; +ROLLBACK; +SELECT a, c, h FROM t; +a c h +NULL NULL d +11 14 a +18 19 b +28 29 c +DROP TABLE t; +CREATE TABLE `t1` ( +`col1` int(11) NOT NULL, +`col2` int(11) NOT NULL, +`col3` int(11) NOT NULL, +`col4` int(11) DEFAULT NULL, +`col5` int(11) GENERATED ALWAYS AS (col2 % col3) VIRTUAL, +`col7` int(11) GENERATED ALWAYS AS (col5 * col5) VIRTUAL, +`col8` int(11) GENERATED ALWAYS AS (col5 % col5) VIRTUAL, +`col9` text, +`extra` int(11) DEFAULT NULL, +UNIQUE KEY `uidx` (`col5`) +) ENGINE=InnoDB DEFAULT CHARSET=latin1; +ALTER TABLE t1 CHANGE COLUMN extra col6 INT; +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `col1` int(11) NOT NULL, + `col2` int(11) NOT NULL, + `col3` int(11) NOT NULL, + `col4` int(11) DEFAULT NULL, + `col5` int(11) AS ((`col2` % `col3`)) VIRTUAL, + `col7` int(11) AS ((`col5` * `col5`)) VIRTUAL, + `col8` int(11) AS ((`col5` % `col5`)) VIRTUAL, + `col9` text DEFAULT NULL, + `col6` int(11) DEFAULT NULL, + UNIQUE KEY `uidx` (`col5`) +) ENGINE=InnoDB DEFAULT CHARSET=latin1 +DROP TABLE t1; +CREATE TABLE t (a INT, b INT GENERATED ALWAYS AS (a), c point, d point GENERATED ALWAYS AS (c), spatial index idx (d)); +ERROR 42000: All parts of a SPATIAL index must be NOT NULL +CREATE TABLE t (a INT, b INT GENERATED ALWAYS AS (a), c CHAR(10), d char(20) GENERATED ALWAYS AS (c), fulltext index idx (d)); +ERROR HY000: This is not yet supported for computed columns +CREATE TABLE t (a INT, b INT, c INT GENERATED ALWAYS AS(a+b), h VARCHAR(10), j INT, m INT GENERATED ALWAYS AS(b + j), n VARCHAR(10), p VARCHAR(20) GENERATED ALWAYS AS(CONCAT(n, h)), INDEX idx1(c), INDEX idx2 (m), INDEX idx3(p)); +INSERT INTO t VALUES(11, 22, DEFAULT, "AAA", 8, DEFAULT, "XXX", DEFAULT); +INSERT INTO t VALUES(1, 2, DEFAULT, "uuu", 9, DEFAULT, "uu", DEFAULT); +INSERT INTO t VALUES(3, 4, DEFAULT, "uooo", 1, DEFAULT, "umm", DEFAULT); +alter table t add x int, add xx int generated ALWAYS AS(x); +DROP TABLE t; +CREATE TABLE t (a INT, b INT, c INT GENERATED ALWAYS AS(a+b), h VARCHAR(10), j INT, m INT GENERATED ALWAYS AS(b + j), n VARCHAR(10), p VARCHAR(20) GENERATED ALWAYS AS(CONCAT(n, h)), INDEX idx1(c), INDEX idx2 (m), INDEX idx3(p)); +INSERT INTO t VALUES(11, 22, DEFAULT, "AAA", 8, DEFAULT, "XXX", DEFAULT); +INSERT INTO t VALUES(1, 2, DEFAULT, "uuu", 9, DEFAULT, "uu", DEFAULT); +INSERT INTO t VALUES(3, 4, DEFAULT, "uooo", 1, DEFAULT, "umm", DEFAULT); +ALTER TABLE t DROP COLUMN c, algorithm=inplace; +ALTER TABLE t DROP COLUMN p, ADD COLUMN s VARCHAR(20) GENERATED ALWAYS AS(CONCAT(n, h)), algorithm=inplace; +SELECT s FROM t; +s +XXXAAA +uuuuu +ummuooo +ALTER TABLE t ADD x VARCHAR(20) GENERATED ALWAYS AS(CONCAT(n, h)), ADD INDEX idx (x), algorithm=inplace; +DROP TABLE t; +CREATE TABLE `t1` ( +`col1` int(11) DEFAULT NULL, +`col2` int(11) DEFAULT NULL, +`col3` int(11) DEFAULT NULL, +`col4` int(11) DEFAULT NULL, +`col5` int(11) GENERATED ALWAYS AS (col4 * col2) VIRTUAL, +`col6` int(11) GENERATED ALWAYS AS (col2 % col4) VIRTUAL, +`col7` int(11) GENERATED ALWAYS AS (col5 / col6) VIRTUAL, +`col8` int(11) GENERATED ALWAYS AS (col5 + col5) VIRTUAL, +`col9` text, +`extra` int(11) DEFAULT NULL +) ENGINE=InnoDB DEFAULT CHARSET=latin1; +ALTER TABLE t1 DROP COLUMN col7; +DROP TABLE t1; +CREATE TABLE t1 ( +col1 INTEGER NOT NULL, +gv_col INTEGER GENERATED ALWAYS AS (col1) VIRTUAL, +txt1 TEXT, +FULLTEXT INDEX fi(txt1) +); +select * from t1; +col1 gv_col txt1 +DROP TABLE t1; +CREATE TABLE t1 ( +col1 INTEGER NOT NULL, +col2 INTEGER NOT NULL, +col3 INTEGER DEFAULT NULL, +col4 INTEGER DEFAULT NULL, +col5 INTEGER DEFAULT NULL, +col6 INTEGER DEFAULT NULL, +col7 INTEGER DEFAULT NULL, +col8 INTEGER DEFAULT NULL, +col9 INTEGER DEFAULT NULL, +col10 INTEGER DEFAULT NULL, +col11 INTEGER DEFAULT NULL, +col12 INTEGER DEFAULT NULL, +col13 INTEGER DEFAULT NULL, +col14 INTEGER DEFAULT NULL, +col15 INTEGER DEFAULT NULL, +col16 INTEGER DEFAULT NULL, +col17 INTEGER DEFAULT NULL, +col18 INTEGER DEFAULT NULL, +col19 INTEGER DEFAULT NULL, +col20 INTEGER DEFAULT NULL, +col21 INTEGER DEFAULT NULL, +col22 INTEGER DEFAULT NULL, +col23 INTEGER DEFAULT NULL, +col24 INTEGER DEFAULT NULL, +col25 INTEGER DEFAULT NULL, +col26 INTEGER DEFAULT NULL, +col27 INTEGER DEFAULT NULL, +col28 INTEGER DEFAULT NULL, +col29 INTEGER DEFAULT NULL, +col30 INTEGER DEFAULT NULL, +col31 INTEGER DEFAULT NULL, +col32 INTEGER DEFAULT NULL, +col33 INTEGER DEFAULT NULL, +gcol1 INTEGER GENERATED ALWAYS AS (col1 + col2) VIRTUAL, +KEY idx1 (gcol1) +); +INSERT INTO t1 (col1, col2) +VALUES (0,1), (1,2), (2,3), (3,4), (4,5); +SELECT gcol1 FROM t1 FORCE INDEX(idx1); +gcol1 +1 +3 +5 +7 +9 +ALTER TABLE t1 ADD COLUMN extra INTEGER; +SELECT gcol1 FROM t1 FORCE INDEX(idx1); +gcol1 +1 +3 +5 +7 +9 +DROP TABLE t1; +CREATE TABLE t1 ( +id INT NOT NULL, +store_id INT NOT NULL, +x INT GENERATED ALWAYS AS (id + store_id) +) +PARTITION BY RANGE (store_id) ( +PARTITION p0 VALUES LESS THAN (6), +PARTITION p1 VALUES LESS THAN (11), +PARTITION p2 VALUES LESS THAN (16), +PARTITION p3 VALUES LESS THAN (21) +); +INSERT INTO t1 VALUES(1, 2, default); +INSERT INTO t1 VALUES(3, 4, default); +INSERT INTO t1 VALUES(3, 12, default); +INSERT INTO t1 VALUES(4, 18, default); +CREATE INDEX idx ON t1(x); +SELECT x FROM t1; +x +3 +7 +15 +22 +DROP TABLE t1; +CREATE TABLE t1 ( +id INT NOT NULL, +store_id INT NOT NULL, +x INT GENERATED ALWAYS AS (id + store_id) +) +PARTITION BY RANGE (x) ( +PARTITION p0 VALUES LESS THAN (6), +PARTITION p1 VALUES LESS THAN (11), +PARTITION p2 VALUES LESS THAN (16), +PARTITION p3 VALUES LESS THAN (21) +); +insert into t1 values(1, 2, default); +insert into t1 values(3, 4, default); +insert into t1 values(3, 12, default); +insert into t1 values(4, 18, default); +ERROR HY000: Table has no partition for value 22 +CREATE INDEX idx ON t1(x); +SELECT x FROM t1; +x +3 +7 +15 +DROP TABLE t1; +CREATE TABLE t1 (a INT, b INT GENERATED ALWAYS AS (a+1) ,c int) PARTITION BY RANGE (b) ( +PARTITION p0 VALUES LESS THAN (6), +PARTITION p1 VALUES LESS THAN (11), +PARTITION p2 VALUES LESS THAN (16), +PARTITION p3 VALUES LESS THAN (21) ); +INSERT INTO t1 VALUES (10,DEFAULT,2); +INSERT INTO t1 VALUES (19,DEFAULT,8); +CREATE INDEX idx ON t1 (b); +INSERT INTO t1 VALUES (5,DEFAULT,9); +SELECT * FROM t1; +a b c +5 6 9 +10 11 2 +19 20 8 +ALTER TABLE t1 REMOVE PARTITIONING; +DROP TABLE t1; +CREATE TABLE `t#P#1` (a INT, bt INT GENERATED ALWAYS AS (a+1) ,c int) +PARTITION BY RANGE (bt) +subpartition by hash (bt) +( +PARTITION p0 VALUES LESS THAN (6) ( +SUBPARTITION s0, +SUBPARTITION s1), +PARTITION p1 VALUES LESS THAN (11) ( +SUBPARTITION s2, +SUBPARTITION s3), +PARTITION p2 VALUES LESS THAN (16) ( +SUBPARTITION s4, +SUBPARTITION s5), +PARTITION p3 VALUES LESS THAN (21) ( +SUBPARTITION s6, +SUBPARTITION s7) +); +insert into `t#P#1` values (10,DEFAULT,2); +insert into `t#P#1` values (19,DEFAULT,8); +create index idx on `t#P#1` (bt); +insert into `t#P#1` values (5,DEFAULT,9); +select * from `t#P#1`; +a bt c +5 6 9 +10 11 2 +19 20 8 +alter table `t#P#1` remove partitioning; +drop table `t#P#1`; +CREATE TABLE `t` ( +`a` VARCHAR(10000), `b` VARCHAR(3000), +`c` VARCHAR(14000) GENERATED ALWAYS AS (CONCAT(a,b)) VIRTUAL, +`d` VARCHAR(5000) GENERATED ALWAYS AS (b) VIRTUAL, +`e` INT(11) GENERATED ALWAYS AS (10) VIRTUAL, +`h` INT(11) NOT NULL, +PRIMARY KEY (`h`) ) ROW_FORMAT=DYNAMIC ENGINE=InnoDB; +SHOW CREATE TABLE t; +Table Create Table +t CREATE TABLE `t` ( + `a` varchar(10000) DEFAULT NULL, + `b` varchar(3000) DEFAULT NULL, + `c` varchar(14000) AS (concat(`a`,`b`)) VIRTUAL, + `d` varchar(5000) AS (`b`) VIRTUAL, + `e` int(11) AS (10) VIRTUAL, + `h` int(11) NOT NULL, + PRIMARY KEY (`h`) +) ENGINE=InnoDB DEFAULT CHARSET=latin1 ROW_FORMAT=DYNAMIC +INSERT INTO t VALUES (REPEAT('g', 10000), REPEAT('x', 2800), DEFAULT, DEFAULT, DEFAULT, 1); +INSERT INTO t VALUES (REPEAT('a', 9000), REPEAT('b', 2000), DEFAULT, DEFAULT, DEFAULT, 2); +INSERT INTO t VALUES (REPEAT('m', 8000), REPEAT('n', 3000), DEFAULT, DEFAULT, DEFAULT, 3); +CREATE INDEX idx ON t(c(100), d(20)); +UPDATE t SET a = REPEAT(CAST(1 AS CHAR), 2000) WHERE h = 1; +CREATE PROCEDURE UPDATE_t() +begin +DECLARE i INT DEFAULT 1; +WHILE (i <= 100) DO +UPDATE t SET a = REPEAT(CAST(i AS CHAR), 2000) WHERE h = 1; +SET i = i + 1; +END WHILE; +END| +CREATE PROCEDURE DELETE_insert_t() +begin +DECLARE i INT DEFAULT 1; +WHILE (i <= 100) DO +DELETE FROM t WHERE h = 1; +INSERT INTO t VALUES (REPEAT(CAST(i AS CHAR), 2000) , REPEAT('b', 2000), DEFAULT, DEFAULT, DEFAULT, 1); +SET i = i + 1; +END WHILE; +END| +CALL UPDATE_t(); +CALL DELETE_insert_t(); +UPDATE t SET a = NULL WHERE h=1; +START TRANSACTION; +CALL UPDATE_t(); +ROLLBACK; +DROP PROCEDURE DELETE_insert_t; +DROP PROCEDURE UPDATE_t; +DROP TABLE t; +CREATE TABLE `t` ( +`a` VARCHAR(10000), `b` VARCHAR(3000), +`c` VARCHAR(14000) GENERATED ALWAYS AS (CONCAT(a,b)) VIRTUAL, +`d` VARCHAR(5000) GENERATED ALWAYS AS (b) VIRTUAL, +`e` INT(11) GENERATED ALWAYS AS (10) VIRTUAL, +`h` INT(11) NOT NULL, +PRIMARY KEY (`h`) ) ROW_FORMAT=REDUNDANT ENGINE=InnoDB; +SHOW CREATE TABLE t; +Table Create Table +t CREATE TABLE `t` ( + `a` varchar(10000) DEFAULT NULL, + `b` varchar(3000) DEFAULT NULL, + `c` varchar(14000) AS (concat(`a`,`b`)) VIRTUAL, + `d` varchar(5000) AS (`b`) VIRTUAL, + `e` int(11) AS (10) VIRTUAL, + `h` int(11) NOT NULL, + PRIMARY KEY (`h`) +) ENGINE=InnoDB DEFAULT CHARSET=latin1 ROW_FORMAT=REDUNDANT +INSERT INTO t VALUES (REPEAT('g', 10000), REPEAT('x', 2800), DEFAULT, DEFAULT, DEFAULT, 1); +INSERT INTO t VALUES (REPEAT('a', 9000), REPEAT('b', 2000), DEFAULT, DEFAULT, DEFAULT, 2); +INSERT INTO t VALUES (REPEAT('m', 8000), REPEAT('n', 3000), DEFAULT, DEFAULT, DEFAULT, 3); +CREATE INDEX idx ON t(c(100), d(20)); +UPDATE t SET a = REPEAT(CAST(1 AS CHAR), 2000) WHERE h = 1; +CREATE PROCEDURE UPDATE_t() +begin +DECLARE i INT DEFAULT 1; +WHILE (i <= 100) DO +UPDATE t SET a = REPEAT(CAST(i AS CHAR), 2000) WHERE h = 1; +SET i = i + 1; +END WHILE; +END| +CREATE PROCEDURE DELETE_insert_t() +begin +DECLARE i INT DEFAULT 1; +WHILE (i <= 100) DO +DELETE FROM t WHERE h = 1; +INSERT INTO t VALUES (REPEAT(CAST(i AS CHAR), 2000) , REPEAT('b', 2000), DEFAULT, DEFAULT, DEFAULT, 1); +SET i = i + 1; +END WHILE; +END| +CALL UPDATE_t(); +CALL DELETE_insert_t(); +UPDATE t SET a = NULL WHERE h=1; +START TRANSACTION; +CALL UPDATE_t(); +ROLLBACK; +DROP PROCEDURE DELETE_insert_t; +DROP PROCEDURE UPDATE_t; +DROP TABLE t; +CREATE TABLE `t` ( +`a` VARCHAR(10000), `b` VARCHAR(3000), +`c` VARCHAR(14000) GENERATED ALWAYS AS (CONCAT(a,b)) VIRTUAL, +`d` VARCHAR(5000) GENERATED ALWAYS AS (b) VIRTUAL, +`e` INT(11) GENERATED ALWAYS AS (10) VIRTUAL, +`h` INT(11) NOT NULL, +PRIMARY KEY (`h`) ) ROW_FORMAT=COMPRESSED ENGINE=InnoDB; +SHOW CREATE TABLE t; +Table Create Table +t CREATE TABLE `t` ( + `a` varchar(10000) DEFAULT NULL, + `b` varchar(3000) DEFAULT NULL, + `c` varchar(14000) AS (concat(`a`,`b`)) VIRTUAL, + `d` varchar(5000) AS (`b`) VIRTUAL, + `e` int(11) AS (10) VIRTUAL, + `h` int(11) NOT NULL, + PRIMARY KEY (`h`) +) ENGINE=InnoDB DEFAULT CHARSET=latin1 ROW_FORMAT=COMPRESSED +INSERT INTO t VALUES (REPEAT('g', 10000), REPEAT('x', 2800), DEFAULT, DEFAULT, DEFAULT, 1); +INSERT INTO t VALUES (REPEAT('a', 9000), REPEAT('b', 2000), DEFAULT, DEFAULT, DEFAULT, 2); +INSERT INTO t VALUES (REPEAT('m', 8000), REPEAT('n', 3000), DEFAULT, DEFAULT, DEFAULT, 3); +CREATE INDEX idx ON t(c(100), d(20)); +UPDATE t SET a = REPEAT(CAST(1 AS CHAR), 2000) WHERE h = 1; +CREATE PROCEDURE UPDATE_t() +begin +DECLARE i INT DEFAULT 1; +WHILE (i <= 100) DO +UPDATE t SET a = REPEAT(CAST(i AS CHAR), 2000) WHERE h = 1; +SET i = i + 1; +END WHILE; +END| +CREATE PROCEDURE DELETE_insert_t() +begin +DECLARE i INT DEFAULT 1; +WHILE (i <= 100) DO +DELETE FROM t WHERE h = 1; +INSERT INTO t VALUES (REPEAT(CAST(i AS CHAR), 2000) , REPEAT('b', 2000), DEFAULT, DEFAULT, DEFAULT, 1); +SET i = i + 1; +END WHILE; +END| +CALL UPDATE_t(); +CALL DELETE_insert_t(); +UPDATE t SET a = NULL WHERE h=1; +START TRANSACTION; +CALL UPDATE_t(); +ROLLBACK; +DROP PROCEDURE DELETE_insert_t; +DROP PROCEDURE UPDATE_t; +DROP TABLE t; +CREATE TABLE t(a TEXT CHARSET UTF8)ENGINE=INNODB; +ALTER TABLE t ADD COLUMN b BLOB GENERATED ALWAYS AS (a) VIRTUAL ; +ALTER TABLE t ADD FULLTEXT INDEX (a) ; +Warnings: +Warning 124 InnoDB rebuilding table to add column FTS_DOC_ID +ALTER TABLE t ADD INDEX (b(1)) ; +DROP TABLE t; +CREATE TABLE t(a TEXT CHARSET UTF8, FULLTEXT INDEX(a))ENGINE=INNODB; +ALTER TABLE t ADD COLUMN b BLOB GENERATED ALWAYS AS (a) VIRTUAL ; +ALTER TABLE t ADD INDEX (b(1)) ; +DROP TABLE t; +CREATE TABLE t(a TEXT CHARSET UTF8)ENGINE=INNODB; +ALTER TABLE t ADD COLUMN FTS_DOC_ID BLOB GENERATED ALWAYS AS (a) VIRTUAL ; +ALTER TABLE t ADD FULLTEXT INDEX (a) ; +ERROR HY000: Column 'FTS_DOC_ID' is of wrong type for an InnoDB FULLTEXT index +DROP TABLE t; +create table t (a int,b int,c int,d int,e int, +f int generated always as (a+b) virtual, +g int,h blob,i int,unique key (d,h(25))) engine=innodb; +select h from t where d is null; +h +drop table t; +create table t(a blob not null) engine=innodb; +alter table t add column b int; +alter table t add column c varbinary (1000) generated always as (a) virtual; +alter table t add unique index (c(39)); +replace into t set a = 'a',b =1; +replace into t set a = 'a',b =1; +drop table t; +CREATE TABLE t (a INT, b INT, h VARCHAR(10)); +INSERT INTO t VALUES (12, 3, "ss"); +INSERT INTO t VALUES (13, 4, "ss"); +INSERT INTO t VALUES (14, 0, "ss"); +alter table t add c INT GENERATED ALWAYS AS(a/b); +create index idx on t(c); +DROP TABLE t; +CREATE TABLE t ( +pk INTEGER AUTO_INCREMENT, +col_int_nokey INTEGER /*! NULL */, +col_int INT GENERATED ALWAYS AS (col_int_nokey + col_int_nokey) STORED, +col_int_key INTEGER GENERATED ALWAYS AS (col_int + col_int_nokey) VIRTUAL, +col_date_nokey DATE /*! NULL */, +col_date DATE GENERATED ALWAYS AS (DATE_ADD(col_date_nokey,interval 30 day)) STORED, +col_date_key DATE GENERATED ALWAYS AS (DATE_ADD(col_date,interval 30 day)) VIRTUAL, +col_datetime_nokey DATETIME /*! NULL */, +col_time_nokey TIME /*! NULL */, +col_datetime DATETIME GENERATED ALWAYS AS (ADDTIME(col_datetime_nokey, col_time_nokey)) STORED, +col_time TIME GENERATED ALWAYS AS (ADDTIME(col_datetime_nokey, col_time_nokey)) STORED, +col_datetime_key DATETIME GENERATED ALWAYS AS (ADDTIME(col_datetime, col_time_nokey)) VIRTUAL, +col_time_key TIME GENERATED ALWAYS AS (ADDTIME(col_datetime_nokey, col_time)) VIRTUAL, +col_varchar_nokey VARCHAR(1) /*! NULL */, +col_varchar VARCHAR(2) GENERATED ALWAYS AS (CONCAT(col_varchar_nokey,col_varchar_nokey)) STORED, +col_varchar_key VARCHAR(2) GENERATED ALWAYS AS (CONCAT(col_varchar, 'x')) VIRTUAL, +unique KEY (pk,col_int_key), +KEY(col_int), +KEY(col_date), +KEY(col_datetime), +KEY(col_time), +KEY(col_varchar), +UNIQUE KEY (col_int_key), +KEY (col_time_key), +KEY (col_datetime_key), +UNIQUE KEY (col_int_key, col_varchar_key), +KEY (col_int_key, col_int_nokey), +KEY(col_int_key,col_date_key), +KEY(col_int_key, col_time_key), +KEY(col_int_key, col_datetime_key), +KEY(col_date_key,col_time_key,col_datetime_key), +KEY (col_varchar_key, col_varchar_nokey), +UNIQUE KEY (col_int_key, col_varchar_key, col_date_key, col_time_key, col_datetime_key) +) AUTO_INCREMENT=10 ENGINE=INNODB PARTITION BY KEY(col_int_key) PARTITIONS 3; +ALTER TABLE t DROP COLUMN `pk`; +SHOW CREATE TABLE t; +Table Create Table +t CREATE TABLE `t` ( + `col_int_nokey` int(11) DEFAULT NULL, + `col_int` int(11) AS ((`col_int_nokey` + `col_int_nokey`)) PERSISTENT, + `col_int_key` int(11) AS ((`col_int` + `col_int_nokey`)) VIRTUAL, + `col_date_nokey` date DEFAULT NULL, + `col_date` date AS ((`col_date_nokey` + interval 30 day)) PERSISTENT, + `col_date_key` date AS ((`col_date` + interval 30 day)) VIRTUAL, + `col_datetime_nokey` datetime DEFAULT NULL, + `col_time_nokey` time DEFAULT NULL, + `col_datetime` datetime AS (addtime(`col_datetime_nokey`,`col_time_nokey`)) PERSISTENT, + `col_time` time AS (addtime(`col_datetime_nokey`,`col_time_nokey`)) PERSISTENT, + `col_datetime_key` datetime AS (addtime(`col_datetime`,`col_time_nokey`)) VIRTUAL, + `col_time_key` time AS (addtime(`col_datetime_nokey`,`col_time`)) VIRTUAL, + `col_varchar_nokey` varchar(1) DEFAULT NULL, + `col_varchar` varchar(2) AS (concat(`col_varchar_nokey`,`col_varchar_nokey`)) PERSISTENT, + `col_varchar_key` varchar(2) AS (concat(`col_varchar`,'x')) VIRTUAL, + UNIQUE KEY `pk` (`col_int_key`), + UNIQUE KEY `col_int_key` (`col_int_key`), + UNIQUE KEY `col_int_key_2` (`col_int_key`,`col_varchar_key`), + UNIQUE KEY `col_int_key_7` (`col_int_key`,`col_varchar_key`,`col_date_key`,`col_time_key`,`col_datetime_key`), + KEY `col_int` (`col_int`), + KEY `col_date` (`col_date`), + KEY `col_datetime` (`col_datetime`), + KEY `col_time` (`col_time`), + KEY `col_varchar` (`col_varchar`), + KEY `col_time_key` (`col_time_key`), + KEY `col_datetime_key` (`col_datetime_key`), + KEY `col_int_key_3` (`col_int_key`,`col_int_nokey`), + KEY `col_int_key_4` (`col_int_key`,`col_date_key`), + KEY `col_int_key_5` (`col_int_key`,`col_time_key`), + KEY `col_int_key_6` (`col_int_key`,`col_datetime_key`), + KEY `col_date_key` (`col_date_key`,`col_time_key`,`col_datetime_key`), + KEY `col_varchar_key` (`col_varchar_key`,`col_varchar_nokey`) +) ENGINE=InnoDB DEFAULT CHARSET=latin1 + PARTITION BY KEY (col_int_key) +PARTITIONS 3 +DROP TABLE t; +CREATE TABLE t (a INT, b INT, c INT GENERATED ALWAYS AS(a+b), h VARCHAR(10)); +INSERT INTO t VALUES (11, 3, DEFAULT, 'mm'); +INSERT INTO t VALUES (18, 1, DEFAULT, 'mm'); +INSERT INTO t VALUES (28, 1, DEFAULT, 'mm'); +INSERT INTO t VALUES (null, null, DEFAULT, 'mm'); +ALTER TABLE t ADD COLUMN xs INT GENERATED ALWAYS AS(a+b), ADD COLUMN mm INT +GENERATED ALWAYS AS(a+b) STORED, ALGORITHM = INPLACE; +ERROR 0A000: ALGORITHM=INPLACE is not supported for this operation. Try ALGORITHM=COPY +ALTER TABLE t ADD COLUMN x INT GENERATED ALWAYS AS(a+b), ALGORITHM = INPLACE; +ALTER TABLE t DROP COLUMN x, ALGORITHM = INPLACE; +ALTER TABLE t ADD COLUMN x1 INT GENERATED ALWAYS AS(a+b), DROP COLUMN c, +ALGORITHM = INPLACE; +DROP TABLE t; +CREATE TABLE t (a INT GENERATED ALWAYS AS(1) VIRTUAL,KEY(a)) ENGINE=INNODB; +INSERT INTO t VALUES(default); +SELECT a FROM t FOR UPDATE; +a +1 +DROP TABLE t; +CREATE TABLE t (a INT, b INT, c INT GENERATED ALWAYS AS(a+b), h VARCHAR(10)); +INSERT INTO t VALUES (11, 3, DEFAULT, 'mm'); +INSERT INTO t VALUES (18, 1, DEFAULT, 'mm'); +INSERT INTO t VALUES (28, 1, DEFAULT, 'mm'); +INSERT INTO t VALUES (null, null, DEFAULT, 'mm'); +ALTER TABLE t ADD COLUMN x INT GENERATED ALWAYS AS(a+b), ADD INDEX idx (x); +affected rows: 0 +info: Records: 0 Duplicates: 0 Warnings: 0 +SELECT x FROM t; +x +NULL +14 +19 +29 +DROP TABLE t; +CREATE TABLE t1 (a INT, b INT, c INT GENERATED ALWAYS AS(a+b), h VARCHAR(10)); +INSERT INTO t1 VALUES (11, 3, DEFAULT, 'mm'); +INSERT INTO t1 VALUES (18, 1, DEFAULT, 'mm'); +INSERT INTO t1 VALUES (28, 1, DEFAULT, 'mm'); +ALTER TABLE t1 ADD INDEX idx12 (c) , FORCE, LOCK=NONE; +ALTER TABLE t1 DROP COLUMN h, ADD INDEX idx (c) , FORCE, LOCK=NONE; +Warnings: +Note 1831 Duplicate index 'idx' defined on the table 'test.t1'. This is deprecated and will be disallowed in a future release +DROP TABLE t1 ; +CREATE TABLE t1 (a INT, b INT, c INT GENERATED ALWAYS AS(a+b), d INT GENERATED ALWAYS AS(a+b), h VARCHAR(10)); +INSERT INTO t1 VALUES (11, 3, DEFAULT, DEFAULT, 'mm'); +INSERT INTO t1 VALUES (18, 1, DEFAULT, DEFAULT, 'mm'); +INSERT INTO t1 VALUES (28, 1, DEFAULT, DEFAULT, 'mm'); +ALTER TABLE t1 CHANGE d d INT GENERATED ALWAYS AS(a+b) FIRST, ALGORITHM = INPLACE; +ERROR 0A000: ALGORITHM=INPLACE is not supported. Reason: INPLACE ADD or DROP of virtual columns cannot be combined with other ALTER TABLE actions. Try ALGORITHM=COPY +ALTER TABLE t1 CHANGE d d VARCHAR(10) GENERATED ALWAYS AS(h), ALGORITHM = INPLACE; +ERROR 0A000: ALGORITHM=INPLACE is not supported for this operation. Try ALGORITHM=COPY +ALTER TABLE t1 CHANGE d d INT GENERATED ALWAYS AS(a+b) FIRST; +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `d` int(11) AS ((`a` + `b`)) VIRTUAL, + `a` int(11) DEFAULT NULL, + `b` int(11) DEFAULT NULL, + `c` int(11) AS ((`a` + `b`)) VIRTUAL, + `h` varchar(10) DEFAULT NULL +) ENGINE=InnoDB DEFAULT CHARSET=latin1 +DROP TABLE t1; +CREATE TABLE parent (id INT PRIMARY KEY) ENGINE=INNODB; +CREATE TABLE child ( +id INT, +parent_id INT, +x int(11) GENERATED ALWAYS AS (parent_id+1), +INDEX par_ind (parent_id), +FOREIGN KEY (parent_id) +REFERENCES parent(id) +ON DELETE CASCADE +) ENGINE=INNODB; +ALTER TABLE child ADD INDEX `i1` (x); +CREATE TABLE child_1 ( +id INT, +parent_id INT, +x int(11) GENERATED ALWAYS AS (parent_id+1), +INDEX par_ind (parent_id), +FOREIGN KEY (parent_id) +REFERENCES parent(id) +) ENGINE=INNODB; +ALTER TABLE child_1 ADD INDEX `i1` (x); +DROP TABLE child_1; +DROP TABLE child; +CREATE TABLE child ( +id INT, +parent_id INT, +x int(11) GENERATED ALWAYS AS (parent_id+1), +INDEX par_ind (parent_id), +INDEX i1 (x), +FOREIGN KEY (parent_id) +REFERENCES parent(id) +ON DELETE CASCADE +) ENGINE=INNODB; +DROP TABLE child; +CREATE TABLE child ( +id INT, +parent_id INT, +x int(11) GENERATED ALWAYS AS (parent_id+1), +INDEX par_ind (parent_id), +INDEX `i1` (x) +) ENGINE=INNODB; +ALTER TABLE child ADD FOREIGN KEY (parent_id) +REFERENCES parent(id) +ON DELETE CASCADE; +SET foreign_key_checks = 0; +ALTER TABLE child ADD FOREIGN KEY (parent_id) +REFERENCES parent(id) +ON DELETE CASCADE; +ALTER TABLE child ADD FOREIGN KEY (parent_id) +REFERENCES parent(id) +ON DELETE SET NULL; +ALTER TABLE child ADD FOREIGN KEY (parent_id) +REFERENCES parent(id) +ON UPDATE CASCADE; +ALTER TABLE child ADD FOREIGN KEY (parent_id) +REFERENCES parent(id); +SET foreign_key_checks = 1; +DROP TABLE child; +DROP TABLE parent; +CREATE TABLE `ibstd_16` ( +`a` int(11) DEFAULT NULL, +`d` int(11) DEFAULT NULL, +`b` varchar(198) DEFAULT NULL, +`c` char(179) DEFAULT NULL, +`vadcol` int(11) GENERATED ALWAYS AS (a+length(d)) STORED, +`vbcol` char(2) GENERATED ALWAYS AS (substr(b,2,2)) VIRTUAL, +`vbidxcol` char(3) GENERATED ALWAYS AS (substr(b,1,3)) VIRTUAL, +UNIQUE KEY `b` (`b`(10),`d`), +KEY `d` (`d`), +KEY `a` (`a`), +KEY `c` (`c`(99),`b`(33)), +KEY `b_2` (`b`(5),`c`(10),`a`), +KEY `vbidxcol` (`vbidxcol`), +KEY `a_2` (`a`,`vbidxcol`), +KEY `vbidxcol_2` (`vbidxcol`,`d`) +) ENGINE=INNODB; +CREATE TABLE `ibstd_16_fk` ( +`a` int(11) DEFAULT NULL, +`d` int(11) DEFAULT NULL, +`b` varchar(198) DEFAULT NULL, +`c` char(179) DEFAULT NULL, +`vadcol` int(11) GENERATED ALWAYS AS (a+length(d)) STORED, +`vbcol` char(2) GENERATED ALWAYS AS (substr(b,2,2)) VIRTUAL, +`vbidxcol` char(3) GENERATED ALWAYS AS (substr(b,1,3)) VIRTUAL, +UNIQUE KEY `b` (`b`(10),`a`,`d`), +KEY `d` (`d`), +KEY `a` (`a`), +KEY `c` (`c`(99),`b`(33)), +KEY `b_2` (`b`(5),`c`(10),`a`), +KEY `vbidxcol` (`vbidxcol`), +KEY `a_2` (`a`,`vbidxcol`), +KEY `vbidxcol_2` (`vbidxcol`,`d`), +CONSTRAINT `fk_16` FOREIGN KEY (`a`) REFERENCES `ibstd_16` (`a`) ON DELETE SET NULL +) ENGINE=InnoDB; +DROP TABLE ibstd_16_fk; +CREATE TABLE `ibstd_16_fk` ( +`a` int(11) DEFAULT NULL, +`d` int(11) DEFAULT NULL, +`b` varchar(198) DEFAULT NULL, +`c` char(179) DEFAULT NULL, +`vbcol` char(2) GENERATED ALWAYS AS (substr(b,2,2)) VIRTUAL, +`vbidxcol` char(3) GENERATED ALWAYS AS (substr(b,1,3)) VIRTUAL, +UNIQUE KEY `b` (`b`(10),`a`,`d`), +KEY `d` (`d`), +KEY `a` (`a`), +KEY `c` (`c`(99),`b`(33)), +KEY `b_2` (`b`(5),`c`(10),`a`), +KEY `vbidxcol` (`vbidxcol`), +KEY `vbidxcol_2` (`vbidxcol`,`d`), +CONSTRAINT `fk_16` FOREIGN KEY (`a`) REFERENCES `ibstd_16` (`a`) ON DELETE SET NULL +) ENGINE=InnoDB; +ALTER TABLE ibstd_16_fk ADD INDEX `a_2` (`a`,`vbidxcol`); +DROP TABLE ibstd_16_fk; +CREATE TABLE `ibstd_16_fk` ( +`a` int(11) DEFAULT NULL, +`d` int(11) DEFAULT NULL, +`b` varchar(198) DEFAULT NULL, +`c` char(179) DEFAULT NULL, +`vbcol` char(2) GENERATED ALWAYS AS (substr(b,2,2)) VIRTUAL, +`vbidxcol` char(3) GENERATED ALWAYS AS (substr(b,1,3)) VIRTUAL, +UNIQUE KEY `b` (`b`(10),`a`,`d`), +KEY `d` (`d`), +KEY `a` (`a`), +KEY `c` (`c`(99),`b`(33)), +KEY `b_2` (`b`(5),`c`(10),`a`), +KEY `vbidxcol` (`vbidxcol`), +KEY `a_2` (`a`,`vbidxcol`), +KEY `vbidxcol_2` (`vbidxcol`,`d`) +) ENGINE=InnoDB; +ALTER TABLE `ibstd_16_fk` ADD CONSTRAINT `fk_16` FOREIGN KEY (`a`) REFERENCES `ibstd_16` (`a`) ON DELETE SET NULL; +DROP INDEX a_2 ON ibstd_16_fk; +INSERT INTO ibstd_16 VALUES (1, 2, "aaa", "bbb", default, default, default); +INSERT INTO ibstd_16_fk VALUES(1, 3, "mmm", "SSS", default, default); +DELETE FROM ibstd_16 WHERE a = 1; +DROP TABLE ibstd_16_fk; +DROP TABLE ibstd_16; +create table t(a int) engine=innodb; +insert into t set a=1; +alter table t add column c int generated always as (1) virtual; +insert into t set a=2; +alter table t add unique index(c); +ERROR 23000: Duplicate entry '1' for key 'c' +insert into t set a=1; +drop table t; +create table t ( +x int, +a int generated always as (x) virtual, +b int generated always as (1) stored, +c int not null, +unique (b), +unique (a,b) +) engine=innodb; +insert into t(x, c) values(1, 3); +replace into t(x, c) values(1, 0); +drop table t; +CREATE TABLE t( +c7c CHAR(1)GENERATED ALWAYS AS (c3) VIRTUAL, +c1 int(1), +c2 int(1), +c3 int(1), +c4 int(1), +c5 int(1)GENERATED ALWAYS AS ((c2 - c4)) VIRTUAL, +UNIQUE KEY c5_9(c5) +)ENGINE=InnoDB DEFAULT CHARSET=latin1; +ALTER TABLE t CHANGE COLUMN c5 c5 INT(1) GENERATED ALWAYS AS(c2 - +c4)VIRTUAL AFTER c3,ALGORITHM=INPLACE; +ERROR 0A000: ALGORITHM=INPLACE is not supported for this operation. Try ALGORITHM=COPY +ALTER TABLE t CHANGE COLUMN c7c c7c INT(1) GENERATED ALWAYS AS(c3) +VIRTUAL AFTER c5,ALGORITHM=INPLACE; +ERROR 0A000: ALGORITHM=INPLACE is not supported for this operation. Try ALGORITHM=COPY +ALTER TABLE t DROP COLUMN c7c,ADD COLUMN c5c INT GENERATED ALWAYS AS(c4/ +c3)VIRTUAL AFTER c3,ALGORITHM=INPLACE; +ERROR 0A000: ALGORITHM=INPLACE is not supported. Reason: INPLACE ADD or DROP of virtual columns cannot be combined with other ALTER TABLE actions. Try ALGORITHM=COPY +DROP TABLE t; +CREATE TABLE `t` ( +`col1` int(11) DEFAULT NULL, +`col2` int(11) DEFAULT NULL, +`col4` int(11) DEFAULT NULL, +`col5` int(11) GENERATED ALWAYS AS ((`col2` % `col4`)) VIRTUAL, +`col6` int(11) GENERATED ALWAYS AS ((`col2` - `col2`)) VIRTUAL, +`col5x` int(11) GENERATED ALWAYS AS ((`col1` / `col1`)) VIRTUAL, +`col6x` int(11) GENERATED ALWAYS AS ((`col2` / `col4`)) VIRTUAL, +`col7x` int(11) GENERATED ALWAYS AS ((`col6` % `col6x`)) VIRTUAL, +`col8x` int(11) GENERATED ALWAYS AS ((`col6` / `col6`)) VIRTUAL, +`col9` text, +`col7c` int(11) GENERATED ALWAYS AS ((`col6x` % `col6x`)) VIRTUAL, +`col1b` varchar(20) GENERATED ALWAYS AS (`col1`) VIRTUAL, +`col3` int(11) DEFAULT NULL, +`col7` int(11) DEFAULT NULL, +`col5c` int(11) GENERATED ALWAYS AS ((`col5x` * `col6`)) VIRTUAL, +`col6c` varchar(20) GENERATED ALWAYS AS (`col5x`) VIRTUAL, +`col3b` bigint(20) GENERATED ALWAYS AS ((`col6x` * `col6`)) VIRTUAL, +`col1a` varchar(20) GENERATED ALWAYS AS (`col1`) VIRTUAL, +`col8` int(11) DEFAULT NULL, +UNIQUE KEY `col5` (`col5`), +UNIQUE KEY `col6x` (`col6x`), +UNIQUE KEY `col5_2` (`col5`), +KEY `idx2` (`col9`(10)), +KEY `idx4` (`col2`), +KEY `idx8` (`col9`(10),`col5`), +KEY `idx9` (`col6`), +KEY `idx6` (`col6`) +) ENGINE=InnoDB DEFAULT CHARSET=latin1; +Warnings: +Note 1831 Duplicate index 'col5_2' defined on the table 'test.t'. This is deprecated and will be disallowed in a future release +Note 1831 Duplicate index 'idx6' defined on the table 'test.t'. This is deprecated and will be disallowed in a future release +ALTER TABLE t CHANGE COLUMN col3b col8a BIGINT GENERATED ALWAYS AS +(col6x * col6) VIRTUAL, ADD UNIQUE KEY uidx ( col8a ); +DROP TABLE t; +# +# Bug 22141031 - GCOLS: PURGED THREAD DIES: TRIED TO PURGE +# NON-DELETE-MARKED RECORD IN INDEX +# +create table t ( +a int,b int,c text,d int,e int,f int,g int, +h text generated always as ('1') virtual, +i int,j int,k int,l int,m int, +primary key (c(1)),unique key (c(1)), +key (i),key (h(1)) +) engine=innodb default charset latin1; +replace into t(c) values (''); +replace into t(c) values (''); +alter table t drop column d ; +drop table t; +# +# Bug 22139917 - ASSERTION: DICT_TABLE_GET_NTH_COL(USER_TABLE, NTH_COL) +# ->LEN < NEW_LEN +# +create table t ( +a int generated always as (1) virtual, +b varbinary(1), +c varbinary(1) generated always as (b) virtual +) engine=innodb; +alter table t change column b b varbinary(2), algorithm=inplace; +alter table t change column c c varbinary(2) generated always as (b) virtual, algorithm=inplace; +drop table t; +SET @@SESSION.sql_mode=0; +CREATE TABLE t( +c1 INT AUTO_INCREMENT, +c2 INT, +c3 INT GENERATED ALWAYS AS(c2 + c2)VIRTUAL, +c3k INT GENERATED ALWAYS AS(c2 + c3)VIRTUAL, +c4 DATE, +c5 DATE GENERATED ALWAYS AS(DATE_ADD(c4,interval 30 day)) VIRTUAL, +c5k DATE GENERATED ALWAYS AS(DATE_ADD(c4,interval 30 day)) VIRTUAL, +c5time_gckey DATE, +c6 TIME, +c5time DATE GENERATED ALWAYS AS(ADDTIME(c5time_gckey,c6)) VIRTUAL, +c7 TIME GENERATED ALWAYS AS(ADDTIME(c5time_gckey,c6)) VIRTUAL, +c5timek DATE GENERATED ALWAYS AS(ADDTIME(c5time_gckey,c7)) VIRTUAL, +c7k TIME GENERATED ALWAYS AS(ADDTIME(c5time,c6)) VIRTUAL, +c8 CHAR(10), +c9 CHAR(20)GENERATED ALWAYS AS (CONCAT(c8,c8)) VIRTUAL, +c9k CHAR(15)GENERATED ALWAYS AS (CONCAT(c8,0)) VIRTUAL, +PRIMARY KEY(c1), +KEY(c3), +KEY(c9(10)), +UNIQUE KEY(c9k), +UNIQUE KEY(c3k,c9k(5),c5k,c7k,c5timek,c3,c9(5),c5,c7,c5time) +)ENGINE=INNODB; +INSERT INTO +t(c2,c4,c6,c5time_gckey,c8)VALUES(1,0,0,0,0),(0,0,0,0,'ityzg'),(0,0,1,0,'tyzgk +t'),(0,1,0,1,'yzgktb'),(0,0,0,0,'zgktb'),(0,0,0,0,'gktbkj'),(0,0,0,0,0),(0,0,1 +,0,1),(0,0,0,0,1),(0,0,0,0,'tbkjrkm'),(0,0,0,0,'bkjr'),(0,0,0,0,0),(0,0,0,0,0) +,(0,0,0,0,'rk'),(0,0,0,0,'kmqmknbtoe'),(1,0,0,0,'mqmknbt'),(0,1,0,0,'qmknb'),( +0,0,0,0,'mkn'),(0,0,0,0,'knbtoervql'),(0,0,1,0,1),(0,0,0,0,'nbtoerv'),(0,0,0,0 +,'btoerv'),(0,0,1,0,'toer'),(1,0,0,0,0),(0,0,0,0,'ervq'),(0,0,0,0,'rvqlzsvasu' +),(0,0,0,0,'vqlzs'),(0,0,0,0,0),(0,1,0,0,'lzsvasu'),(0,0,0,0,'zsvasurq'); +ERROR 23000: Duplicate entry '00' for key 'c9k' +SELECT +DISTINCT * FROM t +FORCE KEY(PRIMARY,c3k,c3,c9k,c9) +WHERE +(c9 IS NULL AND (c9=0)) +OR( +(c9k NOT IN ('ixfq','xfq','New Mexico','fq')OR c9 IS NULL) +) +OR(c9 BETWEEN 'hwstqua' AND 'wstquadcji' OR (c9k=0)) +AND(c3 IS NULL OR c3 IN (0,0,0)); +c1 c2 c3 c3k c4 c5 c5k c5time_gckey c6 c5time c7 c5timek c7k c8 c9 c9k +drop table t; +CREATE TABLE t (a INT, b INT, c INT GENERATED ALWAYS AS(a+b), d INT +GENERATED ALWAYS AS(a+b+b), e INT GENERATED ALWAYS AS(a), h VARCHAR(10)); +INSERT INTO t VALUES (11, 3, DEFAULT, DEFAULT, DEFAULT, 'mm'); +INSERT INTO t VALUES (18, 1, DEFAULT, DEFAULT, DEFAULT, 'mm'); +INSERT INTO t VALUES (28, 1, DEFAULT, DEFAULT, DEFAULT, 'mm'); +INSERT INTO t VALUES (null, null, DEFAULT, DEFAULT, DEFAULT, 'mm'); +CREATE INDEX idx ON t(c, d); +CREATE INDEX idx1 ON t(c); +CREATE INDEX idx2 ON t(e, c, d); +ALTER TABLE t DROP COLUMN c, ALGORITHM=INPLACE; +SELECT d FROM t; +d +NULL +17 +20 +30 +SHOW CREATE TABLE t; +Table Create Table +t CREATE TABLE `t` ( + `a` int(11) DEFAULT NULL, + `b` int(11) DEFAULT NULL, + `d` int(11) AS (((`a` + `b`) + `b`)) VIRTUAL, + `e` int(11) AS (`a`) VIRTUAL, + `h` varchar(10) DEFAULT NULL, + KEY `idx` (`d`), + KEY `idx2` (`e`,`d`) +) ENGINE=InnoDB DEFAULT CHARSET=latin1 +ALTER TABLE t DROP COLUMN d, ADD COLUMN c INT GENERATED ALWAYS AS(a+b), ADD INDEX idx (c), ALGORITHM=INPLACE; +ERROR 0A000: ALGORITHM=INPLACE is not supported. Reason: INPLACE ADD or DROP of virtual columns cannot be combined with other ALTER TABLE actions. Try ALGORITHM=COPY +ALTER TABLE t DROP COLUMN d, ADD COLUMN c INT GENERATED ALWAYS AS(a+b), ADD INDEX idx (e), ALGORITHM=INPLACE, LOCK=NONE; +Warnings: +Note 1831 Duplicate index 'idx' defined on the table 'test.t'. This is deprecated and will be disallowed in a future release +SHOW CREATE TABLE t; +Table Create Table +t CREATE TABLE `t` ( + `a` int(11) DEFAULT NULL, + `b` int(11) DEFAULT NULL, + `e` int(11) AS (`a`) VIRTUAL, + `h` varchar(10) DEFAULT NULL, + `c` int(11) AS ((`a` + `b`)) VIRTUAL, + KEY `idx2` (`e`), + KEY `idx` (`e`) +) ENGINE=InnoDB DEFAULT CHARSET=latin1 +ALTER TABLE t ADD INDEX idx4(c, e), ADD COLUMN x VARCHAR(10) GENERATED ALWAYS AS(h), DROP INDEX idx, ALGORITHM=INPLACE, LOCK=NONE; +SHOW CREATE TABLE t; +Table Create Table +t CREATE TABLE `t` ( + `a` int(11) DEFAULT NULL, + `b` int(11) DEFAULT NULL, + `e` int(11) AS (`a`) VIRTUAL, + `h` varchar(10) DEFAULT NULL, + `c` int(11) AS ((`a` + `b`)) VIRTUAL, + `x` varchar(10) AS (`h`) VIRTUAL, + KEY `idx2` (`e`), + KEY `idx4` (`c`,`e`) +) ENGINE=InnoDB DEFAULT CHARSET=latin1 +ALTER TABLE t ADD COLUMN i INT GENERATED ALWAYS AS(a+a+b), ADD COLUMN j INT, ALGORITHM=INPLACE; +ERROR 0A000: ALGORITHM=INPLACE is not supported. Reason: INPLACE ADD or DROP of virtual columns cannot be combined with other ALTER TABLE actions. Try ALGORITHM=COPY +ALTER TABLE t ADD INDEX (x), ADD COLUMN j INT, ALGORITHM=INPLACE, LOCK=NONE; +SHOW CREATE TABLE t; +Table Create Table +t CREATE TABLE `t` ( + `a` int(11) DEFAULT NULL, + `b` int(11) DEFAULT NULL, + `e` int(11) AS (`a`) VIRTUAL, + `h` varchar(10) DEFAULT NULL, + `c` int(11) AS ((`a` + `b`)) VIRTUAL, + `x` varchar(10) AS (`h`) VIRTUAL, + `j` int(11) DEFAULT NULL, + KEY `idx2` (`e`), + KEY `idx4` (`c`,`e`), + KEY `x` (`x`) +) ENGINE=InnoDB DEFAULT CHARSET=latin1 +ALTER TABLE t ADD COLUMN i INT GENERATED ALWAYS AS(a+a+b), ADD INDEX (i), ALGORITHM=INPLACE, LOCK=NONE; +ERROR 0A000: LOCK=NONE is not supported. Reason: INPLACE ADD or DROP of virtual columns cannot be combined with other ALTER TABLE actions. Try LOCK=SHARED +ALTER TABLE t ADD COLUMN i INT GENERATED ALWAYS AS(a+a+b), ADD INDEX (i), ALGORITHM=INPLACE, LOCK=SHARED; +SHOW CREATE TABLE t; +Table Create Table +t CREATE TABLE `t` ( + `a` int(11) DEFAULT NULL, + `b` int(11) DEFAULT NULL, + `e` int(11) AS (`a`) VIRTUAL, + `h` varchar(10) DEFAULT NULL, + `c` int(11) AS ((`a` + `b`)) VIRTUAL, + `x` varchar(10) AS (`h`) VIRTUAL, + `j` int(11) DEFAULT NULL, + `i` int(11) AS (((`a` + `a`) + `b`)) VIRTUAL, + KEY `idx2` (`e`), + KEY `idx4` (`c`,`e`), + KEY `x` (`x`), + KEY `i` (`i`) +) ENGINE=InnoDB DEFAULT CHARSET=latin1 +SELECT i FROM t; +i +NULL +25 +37 +57 +SELECT * FROM t; +a b e h c x j i +11 3 11 mm 14 mm NULL 25 +18 1 18 mm 19 mm NULL 37 +28 1 28 mm 29 mm NULL 57 +NULL NULL NULL mm NULL mm NULL NULL +DROP TABLE t; +CREATE TABLE t ( +a INT, +b INT, +c INT GENERATED ALWAYS AS(a+b), +d INT GENERATED ALWAYS AS(a+b+b), +KEY vidx (c, d) +)ENGINE=INNODB; +INSERT INTO t (a,b) VALUES (0, 0), (1, NULL), (NULL, 2), (NULL, NULL); +SELECT c, d FROM t; +c d +NULL NULL +NULL NULL +NULL NULL +0 0 +SELECT * FROM t; +a b c d +0 0 0 0 +1 NULL NULL NULL +NULL 2 NULL NULL +NULL NULL NULL NULL +ALTER TABLE t DROP COLUMN c, ALGORITHM=INPLACE; +SELECT d FROM t; +d +NULL +NULL +NULL +0 +SELECT * FROM t; +a b d +0 0 0 +1 NULL NULL +NULL 2 NULL +NULL NULL NULL +DROP TABLE t; +CREATE TABLE t ( +a INT, +b INT, +c INT GENERATED ALWAYS AS(a+b), +d INT GENERATED ALWAYS AS(a+b+b) +)ENGINE=INNODB; +INSERT INTO t (a,b) VALUES (0, 0), (1, NULL), (NULL, 2), (NULL, NULL); +SELECT * FROM t; +a b c d +0 0 0 0 +1 NULL NULL NULL +NULL 2 NULL NULL +NULL NULL NULL NULL +ALTER TABLE t DROP COLUMN c, ADD INDEX vidx(d), ALGORITHM=INPLACE; +SELECT d FROM t; +d +NULL +NULL +NULL +0 +SELECT * FROM t; +a b d +0 0 0 +1 NULL NULL +NULL 2 NULL +NULL NULL NULL +DROP TABLE t; +# +# Bug #22162200 MEMORY LEAK IN HA_INNOPART_SHARE +# ::SET_V_TEMPL PARTITIONED ON VIRTUAL COLUMN +# +create table t ( +c tinyint, +d longblob generated always as (c) virtual +) engine=innodb partition by key (c) partitions 2; +select d in(select d from t)from t group by d; +d in(select d from t) +drop table t; +# +# BUG#23052231 - ASSERTION FAILURE: ROW0MERGE.CC:2100:ADD_AUTOINC +# < DICT_TABLE_GET_N_USER_COLS +# +CREATE TABLE `t` ( +`a` int(11) NOT NULL, +`d` int(11) NOT NULL, +`b` varchar(198) NOT NULL, +`c` char(177) DEFAULT NULL, +`vadcol` int(11) GENERATED ALWAYS AS ((`a` + length(`d`))) STORED, +`vbcol` char(2) GENERATED ALWAYS AS (substr(`b`,2,2)) VIRTUAL, +`vbidxcol` char(3) GENERATED ALWAYS AS (substr(`b`,1,3)) VIRTUAL, +PRIMARY KEY (`b`(10),`a`,`d`), +KEY `d` (`d`), +KEY `a` (`a`), +KEY `c_renamed` (`c`(99),`b`(35)), +KEY `b` (`b`(5),`c`(10),`a`), +KEY `vbidxcol` (`vbidxcol`), +KEY `a_2` (`a`,`vbidxcol`), +KEY `vbidxcol_2` (`vbidxcol`,`d`) +) ENGINE=InnoDB DEFAULT CHARSET=latin1; +INSERT INTO t values (11, 1, "11", "aa", default, default, default); +ALTER TABLE t ADD COLUMN nc01128 BIGINT AUTO_INCREMENT NOT NULL, ADD KEY auto_nc01128(nc01128); +DROP TABLE t; +# +#Bug #22965271 NEEDS REBUILD FOR COLUMN LENGTH CHANGE THAT IS +#PART OF VIRTUAL INDEX. +# +CREATE TABLE t1( +a VARCHAR(45) CHARACTER SET LATIN1, +b VARCHAR(115) CHARACTER SET UTF8 GENERATED ALWAYS AS ('f1') VIRTUAL, +UNIQUE KEY (b,a))ENGINE=INNODB; +INSERT INTO t1(a) VALUES (''); +ALTER TABLE t1 CHANGE COLUMN a a VARCHAR(85); +SELECT * FROM t1; +a b + f1 +DROP TABLE t1; diff --git a/mysql-test/suite/gcol/r/innodb_virtual_blob.result b/mysql-test/suite/gcol/r/innodb_virtual_blob.result new file mode 100644 index 00000000000..f44716ea04f --- /dev/null +++ b/mysql-test/suite/gcol/r/innodb_virtual_blob.result @@ -0,0 +1,12 @@ +# +# Bug#22046353 ALTER: ASSERT PAGE_SIZE.EQUALS_TO(SPACE_PAGE_SIZE), +# BTR_COPY_BLOB_PREFIX +# +CREATE TABLE t1 +( f1 int primary key, f2 blob, +f3 blob generated always as (f2)) +row_format=compressed, engine=innodb; +insert into t1 (f1, f2) values (1, repeat('&', 50000)); +alter table t1 add index i1 (f3(200)) ; +alter table t1 row_format=compact; +drop table t1; diff --git a/mysql-test/suite/gcol/r/innodb_virtual_debug.result b/mysql-test/suite/gcol/r/innodb_virtual_debug.result new file mode 100644 index 00000000000..a54eda60c2d --- /dev/null +++ b/mysql-test/suite/gcol/r/innodb_virtual_debug.result @@ -0,0 +1,227 @@ +set default_storage_engine=innodb; +CREATE TABLE `t` ( +`a` VARCHAR(100), +`b` VARCHAR(100), +`c` VARCHAR(200) GENERATED ALWAYS AS (CONCAT(a,b)) VIRTUAL, +`h` VARCHAR(10) DEFAULT NULL, +`i` int +) ENGINE=InnoDB; +INSERT INTO t VALUES (REPEAT('g', 100), REPEAT('x', 10), DEFAULT, "kk", 1); +INSERT INTO t VALUES (REPEAT('a', 100), REPEAT('b', 100), DEFAULT, "mm", 2); +CREATE INDEX idx ON t(c(100)); +SET session debug_dbug="+d,ib_alter_add_virtual_fail"; +ALTER TABLE t ADD COLUMN x VARCHAR(200) GENERATED ALWAYS AS (a) VIRTUAL, +ALGORITHM = INPLACE; +ERROR 42000: The storage engine InnoDB can't index column `x` +ALTER TABLE t DROP COLUMN c, ALGORITHM = INPLACE; +ERROR 42000: The storage engine InnoDB can't index column `c` +SET session debug_dbug=""; +DROP TABLE t; +CREATE TABLE t (a INT, b INT, c INT GENERATED ALWAYS AS(a+b), h VARCHAR(10)); +INSERT INTO t VALUES (11, 3, DEFAULT, 'mm'); +INSERT INTO t VALUES (18, 1, DEFAULT, 'mm'); +INSERT INTO t VALUES (28, 1, DEFAULT, 'mm'); +INSERT INTO t VALUES (null, null, DEFAULT, "mx"); +SET DEBUG_SYNC = 'innodb_inplace_alter_table_enter SIGNAL start_create WAIT_FOR go_ahead'; +CREATE INDEX idx ON t(c); +connect con1,localhost,root,,; +SET DEBUG_SYNC = 'now WAIT_FOR start_create'; +update t set a=0 where a = 11; +start transaction; +update t set a=1 where a = 0; +ROLLBACK; +SET DEBUG_SYNC = 'now SIGNAL go_ahead'; +connection default; +SELECT c FROM t; +c +NULL +3 +19 +29 +SHOW CREATE TABLE t; +Table Create Table +t CREATE TABLE `t` ( + `a` int(11) DEFAULT NULL, + `b` int(11) DEFAULT NULL, + `c` int(11) AS ((`a` + `b`)) VIRTUAL, + `h` varchar(10) DEFAULT NULL, + KEY `idx` (`c`) +) ENGINE=InnoDB DEFAULT CHARSET=latin1 +SELECT * FROM t; +a b c h +0 3 3 mm +18 1 19 mm +28 1 29 mm +NULL NULL NULL mx +SET DEBUG_SYNC = 'innodb_inplace_alter_table_enter SIGNAL start_create WAIT_FOR go_ahead'; +ALTER TABLE t ADD COLUMN x INT; +connection con1; +SET DEBUG_SYNC = 'now WAIT_FOR start_create'; +start transaction; +update t set a=1 where a = 0; +rollback; +start transaction; +delete from t; +insert into t values(1,null,default,null); +rollback; +start transaction; +update t set b=b+1; +rollback; +SET DEBUG_SYNC = 'now SIGNAL go_ahead'; +connection default; +check table t; +Table Op Msg_type Msg_text +test.t check status OK +SELECT c FROM t; +c +NULL +3 +19 +29 +SET DEBUG_SYNC = 'innodb_inplace_alter_table_enter SIGNAL start_create WAIT_FOR go_ahead'; +ALTER TABLE t ADD COLUMN x2 INT; +connection con1; +SET DEBUG_SYNC = 'now WAIT_FOR start_create'; +start transaction; +DELETE FROM t WHERE a = 0; +ROLLBACK; +DELETE FROM t WHERE a = 0; +SET DEBUG_SYNC = 'now SIGNAL go_ahead'; +connection default; +SELECT c FROM t; +c +NULL +19 +29 +disconnect con1; +DROP TABLE t; +SET DEBUG_SYNC = 'RESET'; +CREATE TABLE t (a INT, b INT, c INT GENERATED ALWAYS AS(a+b), h VARCHAR(10)); +INSERT INTO t VALUES (11, 3, DEFAULT, 'mm'); +INSERT INTO t VALUES (18, 1, DEFAULT, 'mm'); +INSERT INTO t VALUES (28, 1, DEFAULT, 'mm'); +INSERT INTO t VALUES (null, null, DEFAULT, 'mm'); +CREATE INDEX idx_1 on t(c); +SET SESSION debug_dbug="+d,create_index_fail"; +ALTER TABLE t ADD COLUMN x INT GENERATED ALWAYS AS(a+b), ADD INDEX idx (x); +ERROR 23000: Duplicate entry '' for key '*UNKNOWN*' +SET SESSION debug_dbug=""; +affected rows: 0 +SHOW CREATE TABLE t; +Table Create Table +t CREATE TABLE `t` ( + `a` int(11) DEFAULT NULL, + `b` int(11) DEFAULT NULL, + `c` int(11) AS ((`a` + `b`)) VIRTUAL, + `h` varchar(10) DEFAULT NULL, + KEY `idx_1` (`c`) +) ENGINE=InnoDB DEFAULT CHARSET=latin1 +SELECT c FROM t; +c +NULL +14 +19 +29 +DROP TABLE t; +# +# Bug#22018532 ASSERTION WHEN ONLINE REAPPLY REBUILD LOG ON +# MULTIPLE INDEXED VIRTUAL COLUMNS +# +create table t ( +a int as (1) virtual, +b int, +c int as (1) virtual, +unique(b), +unique(c), +key(a) +) engine=innodb; +insert ignore into t values(); +SET DEBUG_SYNC = 'innodb_inplace_alter_table_enter SIGNAL start_create WAIT_FOR go_ahead'; +optimize table t; +connect con1,localhost,root,,; +SET DEBUG_SYNC = 'now WAIT_FOR start_create'; +insert ignore into t values(); +Warnings: +Warning 1062 Duplicate entry '1' for key 'c' +SET DEBUG_SYNC = 'now SIGNAL go_ahead'; +connection default; +/* connection default */ optimize table t; +Table Op Msg_type Msg_text +test.t optimize note Table does not support optimize, doing recreate + analyze instead +test.t optimize error Duplicate entry '1' for key 'a' +test.t optimize status Operation failed +Warnings: +Error 1062 Duplicate entry '1' for key 'a' +SELECT c FROM t; +c +1 +SHOW CREATE TABLE t; +Table Create Table +t CREATE TABLE `t` ( + `a` int(11) AS (1) VIRTUAL, + `b` int(11) DEFAULT NULL, + `c` int(11) AS (1) VIRTUAL, + UNIQUE KEY `b` (`b`), + UNIQUE KEY `c` (`c`), + KEY `a` (`a`) +) ENGINE=InnoDB DEFAULT CHARSET=latin1 +SELECT * FROM t; +a b c +1 NULL 1 +DROP TABLE t; +CREATE TABLE t (a INT, b INT, c INT GENERATED ALWAYS AS(a+b), h VARCHAR(10)); +INSERT INTO t VALUES (11, 3, DEFAULT, 'mm'); +INSERT INTO t VALUES (18, 1, DEFAULT, 'mm'); +INSERT INTO t VALUES (28, 1, DEFAULT, 'mm'); +INSERT INTO t VALUES (null, null, DEFAULT, 'mm'); +CREATE INDEX idx ON t(c); +SET DEBUG_SYNC = 'innodb_inplace_alter_table_enter SIGNAL start_rebuild WAIT_FOR go_ahead'; +optimize table t; +connection con1; +SET DEBUG_SYNC = 'now WAIT_FOR start_rebuild'; +INSERT INTO t VALUES (48, 2, DEFAULT, 'xx'); +INSERT INTO t VALUES (68, 3, DEFAULT, 'sx'); +SET DEBUG_SYNC = 'now SIGNAL go_ahead'; +connection default; +/* connection default */ optimize table t; +Table Op Msg_type Msg_text +test.t optimize note Table does not support optimize, doing recreate + analyze instead +test.t optimize status OK +SELECT c FROM t; +c +NULL +14 +19 +29 +50 +71 +disconnect con1; +DROP TABLE t; +# +# Bug#22951879 - ASSERTS RELATED TO ONLINE DDL AND GCOL +# +create table ibstd_14 (a int not null, d int not null, b varchar(198) not null, c char(181), vadcol int as (a+length(d)) stored, vbcol char(2) as (substr(b,2,2)) virtual, vbidxcol char(3) as (substr(b,1,3)) virtual , index(d), index(a), index(vbidxcol), index(a,vbidxcol), index(vbidxcol,d), unique key (b(10), a, d), index(c(99), b(31)), index(b(5), c(10), a) , index(a,d)) engine=InnoDB stats_persistent=1 row_format=dynamic; +SET DEBUG_SYNC = 'innodb_inplace_alter_table_enter SIGNAL start_create WAIT_FOR go_ahead'; +alter table ibstd_14 row_format=compressed key_block_size=4,add key kn3 (d,c,vbcol,b); +connect con1,localhost,root; +SET DEBUG_SYNC = 'now WAIT_FOR start_create'; +insert into ibstd_14 (a,d,b,c, vbidxcol, vbcol) values ('118','6',repeat('oacolaarlruoacuroauurloraarucoooarcooauoolacalllaulrruarrrucruuooclacuoouccarrcoocloccorrrrarourcooalloocooccouruolaorlcaocualolc','1'),repeat('lolrrlalcocroraaulauclaaucolcorcuooaolruaooooluooooouaoorlarucorullalcrrloccououaooaorluorraclrcooouuolocoaolcocaaculruoocucoocoooauuolarcoraraocaoolulolarru','1'),default,default); +insert into ibstd_14 (a,d,b,c, vbidxcol, vbcol) values ('118','6', 'aaaa', 'lll', default, default); +update ibstd_14 set b='11111' where b='aaaa'; +SET DEBUG_SYNC = 'now SIGNAL go_ahead'; +connection default; +select * from ibstd_14; +a d b c vadcol vbcol vbidxcol +118 6 oacolaarlruoacuroauurloraarucoooarcooauoolacalllaulrruarrrucruuooclacuoouccarrcoocloccorrrrarourcooalloocooccouruolaorlcaocualolc lolrrlalcocroraaulauclaaucolcorcuooaolruaooooluooooouaoorlarucorullalcrrloccououaooaorluorraclrcooouuolocoaolcocaaculruoocucoocoooauuolarcoraraocaoolulolarru 119 ac oac +118 6 11111 lll 119 11 111 +select d,c,vbcol,b from ibstd_14; +d c vbcol b +6 lll 11 11111 +6 lolrrlalcocroraaulauclaaucolcorcuooaolruaooooluooooouaoorlarucorullalcrrloccououaooaorluorraclrcooouuolocoaolcocaaculruoocucoocoooauuolarcoraraocaoolulolarru ac oacolaarlruoacuroauurloraarucoooarcooauoolacalllaulrruarrrucruuooclacuoouccarrcoocloccorrrrarourcooalloocooccouruolaorlcaocualolc +select vbcol from ibstd_14; +vbcol +11 +ac +drop table ibstd_14; +disconnect con1; +SET DEBUG_SYNC = 'RESET'; diff --git a/mysql-test/suite/gcol/r/innodb_virtual_debug_purge.result b/mysql-test/suite/gcol/r/innodb_virtual_debug_purge.result new file mode 100644 index 00000000000..82513c5c5ca --- /dev/null +++ b/mysql-test/suite/gcol/r/innodb_virtual_debug_purge.result @@ -0,0 +1,141 @@ +set default_storage_engine=innodb; +set @old_dbug=@@global.debug_dbug; +CREATE TABLE `t` ( +`a` BLOB, +`b` BLOB, +`c` BLOB GENERATED ALWAYS AS (CONCAT(a,b)) VIRTUAL, +`h` VARCHAR(10) DEFAULT NULL, +`i` int +) ENGINE=InnoDB; +INSERT INTO t VALUES (REPEAT('g', 16000), REPEAT('x', 16000), DEFAULT, "kk", 1); +INSERT INTO t VALUES (REPEAT('a', 16000), REPEAT('b', 16000), DEFAULT, "mm", 2); +CREATE INDEX idx ON t(c(100)); +SET global debug_dbug="+d,ib_purge_virtual_index_callback"; +UPDATE t SET a = REPEAT('m', 16000) WHERE a like "aaa%"; +select sleep(3); +sleep(3) +0 +SET global debug_dbug=@old_dbug; +DROP TABLE t; +CREATE TABLE t ( +a TINYBLOB, +b TINYBLOB, +c TINYBLOB GENERATED ALWAYS AS (CONCAT(a,b)) VIRTUAL, +h VARCHAR(10) DEFAULT NULL, +i INT +) ROW_FORMAT=COMPACT ENGINE=InnoDB; +INSERT INTO t VALUES (REPEAT('g', 100), REPEAT('x', 100), DEFAULT, "kk", 1); +INSERT INTO t VALUES (REPEAT('a', 100), REPEAT('b', 100), DEFAULT, "mm", 2); +CREATE INDEX idx ON t(c(100)); +SET global debug_dbug="+d,ib_purge_virtual_index_callback"; +UPDATE t SET a = REPEAT('m', 100) WHERE a like "aaa%"; +select sleep(3); +sleep(3) +0 +SET global debug_dbug=@old_dbug; +DROP TABLE t; +CREATE TABLE t1 ( +id INT NOT NULL, +store_id INT NOT NULL, +x INT GENERATED ALWAYS AS (id + store_id) +) +PARTITION BY RANGE (store_id) ( +PARTITION p0 VALUES LESS THAN (6), +PARTITION p1 VALUES LESS THAN (11), +PARTITION p2 VALUES LESS THAN (16), +PARTITION p3 VALUES LESS THAN (21) +); +insert into t1 values(1, 2, default); +insert into t1 values(3, 4, default); +insert into t1 values(3, 12, default); +insert into t1 values(4, 18, default); +CREATE INDEX idx ON t1(x); +SET global debug_dbug="+d,ib_purge_virtual_index_callback"; +UPDATE t1 SET id = 10 WHERE id = 1; +select sleep(3); +sleep(3) +0 +SET global debug_dbug=@old_dbug; +DROP TABLE t1; +connect con1,localhost,root,,; +connection default; +CREATE TABLE t1 (a INT, b INT); +INSERT INTO t1(a, b) VALUES (1, 1), (2, 2), (3, 3); +connection con1; +# disable purge +CREATE TABLE t0 (a INT) ENGINE=InnoDB; +BEGIN; +SELECT * FROM t0; +a +connection default; +DELETE FROM t1 WHERE a = 1; +UPDATE t1 SET a = 4, b = 4 WHERE a = 3; +INSERT INTO t1(a, b) VALUES (5, 5); +SET DEBUG_SYNC= 'inplace_after_index_build SIGNAL uncommitted WAIT_FOR purged'; +ALTER TABLE t1 ADD COLUMN c INT GENERATED ALWAYS AS(a+b), ADD INDEX idx (c), ALGORITHM=INPLACE, LOCK=NONE; +ERROR 0A000: LOCK=NONE is not supported. Reason: INPLACE ADD or DROP of virtual columns cannot be combined with other ALTER TABLE actions. Try LOCK=SHARED +ALTER TABLE t1 ADD COLUMN c INT GENERATED ALWAYS AS(a+b), ADD INDEX idx (c), ALGORITHM=INPLACE, LOCK=SHARED; +connection con1; +SET DEBUG_SYNC= 'now WAIT_FOR uncommitted'; +# enable purge +COMMIT; +# wait for purge to process the deleted records. +Timeout in wait_innodb_all_purged.inc for INNODB_PURGE_TRX_ID_AGE = 3 +SET DEBUG_SYNC= 'now SIGNAL purged'; +connection default; +/* connection default */ ALTER TABLE t1 ADD COLUMN c INT GENERATED ALWAYS AS(a+b), ADD INDEX idx (c), ALGORITHM=INPLACE, LOCK=SHARED; +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` int(11) DEFAULT NULL, + `b` int(11) DEFAULT NULL, + `c` int(11) AS ((`a` + `b`)) VIRTUAL, + KEY `idx` (`c`) +) ENGINE=InnoDB DEFAULT CHARSET=latin1 +SELECT * FROM t1; +a b c +2 2 4 +4 4 8 +5 5 10 +DROP TABLE t1; +CREATE TABLE t1 (a INT, b INT, c INT GENERATED ALWAYS AS(a+b)); +INSERT INTO t1(a, b) VALUES (1, 1), (2, 2), (3, 3), (4, 4); +connection con1; +# disable purge +BEGIN; +SELECT * FROM t0; +a +connection default; +DELETE FROM t1 WHERE a = 1; +UPDATE t1 SET a = 2, b = 2 WHERE a = 5; +INSERT INTO t1(a, b) VALUES (6, 6); +SET DEBUG_SYNC= 'inplace_after_index_build SIGNAL uncommitted WAIT_FOR purged'; +ALTER TABLE t1 ADD INDEX idx (c), ALGORITHM=INPLACE, LOCK=NONE; +connection con1; +SET DEBUG_SYNC= 'now WAIT_FOR uncommitted'; +DELETE FROM t1 WHERE a = 3; +UPDATE t1 SET a = 7, b = 7 WHERE a = 4; +INSERT INTO t1(a, b) VALUES (8, 8); +# enable purge +COMMIT; +# wait for purge to process the deleted/updated records. +SET DEBUG_SYNC= 'now SIGNAL purged'; +disconnect con1; +connection default; +/* connection default */ ALTER TABLE t1 ADD INDEX idx (c), ALGORITHM=INPLACE, LOCK=NONE; +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` int(11) DEFAULT NULL, + `b` int(11) DEFAULT NULL, + `c` int(11) AS ((`a` + `b`)) VIRTUAL, + KEY `idx` (`c`) +) ENGINE=InnoDB DEFAULT CHARSET=latin1 +SELECT * FROM t1; +a b c +2 2 4 +7 7 14 +6 6 12 +8 8 16 +DROP TABLE t0, t1; +set debug_sync=reset; diff --git a/mysql-test/suite/gcol/r/innodb_virtual_fk.result b/mysql-test/suite/gcol/r/innodb_virtual_fk.result new file mode 100644 index 00000000000..38a13edd8fa --- /dev/null +++ b/mysql-test/suite/gcol/r/innodb_virtual_fk.result @@ -0,0 +1,590 @@ +set default_storage_engine=innodb; +# +# Bug#22469130: FOREIGN KEY ON DELETE CASCADE NOT ALLOWED +# WHEN A VIRTUAL INDEX EXISTS. +# UPDATE CASCADE +CREATE TABLE t1(fld1 INT NOT NULL PRIMARY KEY); +CREATE TABLE t2(fld1 INT NOT NULL, fld2 INT AS (fld1) VIRTUAL, KEY(fld2), +FOREIGN KEY(fld1) REFERENCES t1(fld1) ON UPDATE CASCADE); +INSERT INTO t1 VALUES(1); +INSERT INTO t2 VALUES(1, DEFAULT); +UPDATE t1 SET fld1= 2; +SELECT fld2 FROM t2; +fld2 +2 +SELECT * FROM t2; +fld1 fld2 +2 2 +DROP TABLE t2, t1; +# UPDATE SET NULL +CREATE TABLE t1(fld1 INT NOT NULL, fld2 INT NOT NULL PRIMARY KEY, +KEY(fld1)); +CREATE TABLE t2(fld1 INT, fld2 INT AS (fld1) VIRTUAL, KEY(fld2), +FOREIGN KEY(fld1) REFERENCES t1(fld1) ON UPDATE SET NULL); +INSERT INTO t1 VALUES(1, 2); +INSERT INTO t2 VALUES(1, DEFAULT); +UPDATE t1 SET fld1= 2; +SELECT fld2 FROM t2; +fld2 +NULL +SELECT * FROM t2; +fld1 fld2 +NULL NULL +DROP TABLE t2, t1; +# DELETE CASCADE +CREATE TABLE t1(fld1 INT NOT NULL PRIMARY KEY); +CREATE TABLE t2(fld1 INT, fld2 INT AS (fld1) VIRTUAL, KEY(fld2), +FOREIGN KEY(fld1) REFERENCES t1(fld1) ON DELETE CASCADE); +INSERT INTO t1 VALUES(1); +INSERT INTO t1 VALUES(2); +INSERT INTO t2 VALUES(1, DEFAULT); +INSERT INTO t2 VALUES(2, DEFAULT); +DELETE FROM t1 WHERE fld1= 1; +SELECT fld2 FROM t2; +fld2 +2 +SELECT * FROM t2; +fld1 fld2 +2 2 +DROP TABLE t2, t1; +# DELETE SET NULL +CREATE TABLE t1(fld1 INT NOT NULL, fld2 INT NOT NULL PRIMARY KEY, KEY(fld1)); +CREATE TABLE t2(fld1 INT, fld2 INT AS (fld1) VIRTUAL, KEY(fld2), +FOREIGN KEY(fld1) REFERENCES t1(fld1) ON DELETE SET NULL); +INSERT INTO t1 VALUES(1, 1); +INSERT INTO t1 VALUES(2, 2); +INSERT INTO t2 VALUES(1, DEFAULT); +INSERT INTO t2 VALUES(2, DEFAULT); +DELETE FROM t1 WHERE fld1= 1; +SELECT fld2 FROM t2; +fld2 +NULL +2 +SELECT * FROM t2; +fld1 fld2 +NULL NULL +2 2 +DROP TABLE t2, t1; +# VIRTUAL INDEX CONTAINS FK CONSTRAINT COLUMN +CREATE TABLE t1(fld1 INT NOT NULL PRIMARY KEY); +CREATE TABLE t2(fld1 INT NOT NULL, fld2 INT, fld3 INT AS (fld2) VIRTUAL, +KEY(fld3, fld1), +FOREIGN KEY(fld1) REFERENCES t1(fld1) ON UPDATE CASCADE); +INSERT INTO t1(fld1) VALUES(1); +INSERT INTO t2(fld1, fld2) VALUES(1, 3); +UPDATE t1 SET fld1= 2; +SELECT fld3, fld1 FROM t2; +fld3 fld1 +3 2 +SELECT * FROM t2; +fld1 fld2 fld3 +2 3 3 +DROP TABLE t2, t1; +# Multiple level of VIRTUAL columns. +CREATE TABLE t1(fld1 INT NOT NULL PRIMARY KEY); +CREATE TABLE t2(fld1 INT NOT NULL, fld2 INT AS (fld1) VIRTUAL, +fld3 INT AS (fld2) VIRTUAL, KEY(fld3), KEY(fld2), +FOREIGN KEY(fld1) REFERENCES t1(fld1) ON UPDATE CASCADE); +INSERT INTO t1(fld1) VALUES(1); +INSERT INTO t2(fld1) VALUES(1); +UPDATE t1 SET fld1= 2; +SELECT fld2 FROM t2; +fld2 +2 +SELECT fld3 FROM t2; +fld3 +2 +SELECT * FROM t2; +fld1 fld2 fld3 +2 2 2 +DROP TABLE t2, t1; +# Drop the VIRTUAL INDEX using alter copy ALGORITHM +CREATE TABLE t1(fld1 INT NOT NULL PRIMARY KEY); +CREATE TABLE t2(fld1 INT NOT NULL, fld2 INT AS (fld1) VIRTUAL, KEY vk(fld2), +KEY(fld1), FOREIGN KEY(fld1) REFERENCES t1(fld1) +ON UPDATE CASCADE); +INSERT INTO t1(fld1) VALUES(1); +INSERT INTO t2(fld1) VALUES(1); +UPDATE t1 SET fld1= 2; +SELECT fld2, fld1 FROM t2; +fld2 fld1 +2 2 +ALTER TABLE t2 DROP INDEX vk, ALGORITHM= COPY; +UPDATE t1 SET fld1= 3; +SELECT fld2, fld1 FROM t2; +fld2 fld1 +3 3 +DROP TABLE t2, t1; +# Drop the VIRTUAL INDEX using INPLACE alter ALGORITHM +CREATE TABLE t1(fld1 INT NOT NULL PRIMARY KEY); +CREATE TABLE t2(fld1 INT NOT NULL, fld2 INT AS (fld1) VIRTUAL, +KEY vk(fld2), KEY(fld1), FOREIGN KEY(fld1) REFERENCES t1(fld1) +ON UPDATE CASCADE); +INSERT INTO t1(fld1) VALUES(1); +INSERT INTO t2(fld1) VALUES(1); +UPDATE t1 SET fld1= 2; +SELECT fld2, fld1 FROM t2; +fld2 fld1 +2 2 +ALTER TABLE t2 DROP INDEX vk, ALGORITHM= COPY; +UPDATE t1 SET fld1= 3; +SELECT fld2, fld1 FROM t2; +fld2 fld1 +3 3 +DROP TABLE t2, t1; +# Add the VIRTUAL INDEX using COPY alter ALGORITHM +CREATE TABLE t1(fld1 INT NOT NULL PRIMARY KEY); +CREATE TABLE t2(fld1 INT NOT NULL, fld2 INT AS (fld1) VIRTUAL, +KEY(fld1), FOREIGN KEY(fld1) REFERENCES t1(fld1) +ON UPDATE CASCADE); +INSERT INTO t1(fld1) VALUES(1); +INSERT INTO t2(fld1) VALUES(1); +UPDATE t1 SET fld1= 2; +SELECT fld2, fld1 FROM t2; +fld2 fld1 +2 2 +ALTER TABLE t2 ADD INDEX vk(fld2), ALGORITHM= COPY; +UPDATE t1 SET fld1= 3; +SELECT fld2, fld1 FROM t2; +fld2 fld1 +3 3 +DROP TABLE t2, t1; +# Add the VIRTUAL INDEX using INPLACE alter ALGORITHM +CREATE TABLE t1(fld1 INT NOT NULL PRIMARY KEY); +CREATE TABLE t2(fld1 INT NOT NULL,fld2 INT AS (fld1) VIRTUAL, +KEY(fld1), FOREIGN KEY(fld1) REFERENCES t1(fld1) +ON UPDATE CASCADE); +INSERT INTO t1(fld1) VALUES(1); +INSERT INTO t2(fld1) VALUES(1); +UPDATE t1 SET fld1= 2; +SELECT fld2, fld1 FROM t2; +fld2 fld1 +2 2 +ALTER TABLE t2 ADD INDEX vk(fld2), ALGORITHM= INPLACE; +UPDATE t1 SET fld1= 3; +SELECT fld2, fld1 FROM t2; +fld2 fld1 +3 3 +DROP TABLE t2, t1; +# Drop the VIRTUAL INDEX contains fk constraint column +# using alter copy ALGORITHM +CREATE TABLE t1(fld1 INT NOT NULL PRIMARY KEY); +CREATE TABLE t2(fld1 INT NOT NULL, fld2 INT NOT NULL, +fld3 INT AS (fld2) VIRTUAL, KEY vk(fld3, fld1), +KEY(fld1), FOREIGN KEY(fld1) REFERENCES t1(fld1) +ON UPDATE CASCADE); +INSERT INTO t1(fld1) VALUES(1); +INSERT INTO t2(fld1, fld2) VALUES(1, 2); +UPDATE t1 SET fld1= 2; +SELECT fld3, fld1 FROM t2; +fld3 fld1 +2 2 +ALTER TABLE t2 DROP INDEX vk, ALGORITHM= COPY; +UPDATE t1 SET fld1= 3; +SELECT fld3, fld1 FROM t2; +fld3 fld1 +2 3 +DROP TABLE t2, t1; +# Drop the VIRTUAL INDEX which contains fk constraint column +# using INPLACE alter operation +CREATE TABLE t1(fld1 INT NOT NULL PRIMARY KEY); +CREATE TABLE t2(fld1 INT NOT NULL, fld2 INT NOT NULL, +fld3 INT AS (fld2) VIRTUAL, KEY vk(fld3, fld1), +KEY(fld1), FOREIGN KEY(fld1) REFERENCES t1(fld1) +ON UPDATE CASCADE); +INSERT INTO t1(fld1) VALUES(1); +INSERT INTO t2(fld1, fld2) VALUES(1, 2); +UPDATE t1 SET fld1= 2; +SELECT fld3, fld1 FROM t2; +fld3 fld1 +2 2 +alter TABLE t2 DROP INDEX vk, ALGORITHM= INPLACE; +UPDATE t1 SET fld1= 3; +SELECT fld3, fld1 FROM t2; +fld3 fld1 +2 3 +DROP TABLE t2, t1; +# Add the VIRTUAL INDEX contains fk constraint column +# using copy alter operatiON +CREATE TABLE t1(fld1 INT NOT NULL PRIMARY KEY); +CREATE TABLE t2(fld1 INT NOT NULL, fld2 INT NOT NULL, +fld3 INT AS (fld2) VIRTUAL, KEY(fld1), +FOREIGN KEY(fld1) REFERENCES t1(fld1) ON UPDATE CASCADE); +INSERT INTO t1(fld1) VALUES(1); +INSERT INTO t2(fld1, fld2) VALUES(1, 2); +UPDATE t1 SET fld1= 2; +SELECT fld3, fld1 FROM t2; +fld3 fld1 +2 2 +alter TABLE t2 ADD INDEX vk(fld3, fld1), ALGORITHM= COPY; +UPDATE t1 SET fld1= 3; +SELECT fld3, fld1 FROM t2; +fld3 fld1 +2 3 +DROP TABLE t2, t1; +# Cascading UPDATEs and DELETEs for the multiple +# fk dependent TABLEs +CREATE TABLE t1(fld1 INT NOT NULL PRIMARY KEY); +CREATE TABLE t2(fld1 INT NOT NULL, fld2 INT AS (fld1) VIRTUAL, +KEY(fld1), KEY(fld2, fld1), +FOREIGN KEY(fld1) REFERENCES t1(fld1) ON UPDATE CASCADE); +CREATE TABLE t3(fld1 INT NOT NULL, fld2 INT AS (fld1) VIRTUAL, +KEY(fld2, fld1), +FOREIGN KEY(fld1) REFERENCES t2(fld1) ON UPDATE CASCADE); +INSERT INTO t1 VALUES(1), (2); +INSERT INTO t2(fld1) VALUES(1), (2); +INSERT INTO t3(fld1) VALUES(1), (2); +UPDATE t1 SET fld1= 4 WHERE fld1= 1; +SELECT fld2, fld1 FROM t2; +fld2 fld1 +2 2 +4 4 +SELECT fld2, fld1 FROM t3; +fld2 fld1 +2 2 +4 4 +DROP TABLE t3, t2, t1; +CREATE TABLE t1(fld1 INT NOT NULL PRIMARY KEY); +CREATE TABLE t2(fld1 INT NOT NULL, fld2 INT NOT NULL, +fld3 INT AS (fld2) VIRTUAL, KEY(fld3, fld1), KEY(fld1), +FOREIGN KEY(fld1) REFERENCES t1(fld1) ON UPDATE CASCADE); +CREATE TABLE t3(fld1 INT NOT NULL, fld2 INT NOT NULL, +fld3 INT AS (fld2) VIRTUAL, KEY(fld3, fld1), +FOREIGN KEY(fld1) REFERENCES t2(fld1) ON UPDATE CASCADE); +INSERT INTO t1 VALUES(1), (2); +INSERT INTO t2 VALUES(1, 1, DEFAULT), (2, 2, default); +INSERT INTO t3 VALUES(1, 1, DEFAULT), (2, 2, default); +UPDATE t1 SET fld1= 4 WHERE fld1= 1; +SELECT fld3, fld1 FROM t2; +fld3 fld1 +1 4 +2 2 +SELECT fld3, fld1 FROM t3; +fld3 fld1 +1 4 +2 2 +DROP TABLE t3, t2, t1; +CREATE TABLE t1(fld1 INT NOT NULL PRIMARY KEY); +CREATE TABLE t2(fld1 INT NOT NULL, fld2 INT AS (fld1) VIRTUAL, +KEY(fld1), KEY(fld2, fld1), +FOREIGN KEY(fld1) REFERENCES t1(fld1) ON DELETE CASCADE); +CREATE TABLE t3(fld1 INT NOT NULL, fld2 INT AS (fld1) VIRTUAL, +KEY(fld2, fld1), FOREIGN KEY(fld1) REFERENCES t2(fld1) +ON DELETE CASCADE); +INSERT INTO t1 VALUES(1), (2); +INSERT INTO t2(fld1) VALUES(1), (2); +INSERT INTO t3(fld1) VALUES(1), (2); +DELETE FROM t1 WHERE fld1= 1; +SELECT fld2, fld1 FROM t2; +fld2 fld1 +2 2 +SELECT fld2, fld1 FROM t3; +fld2 fld1 +2 2 +DROP TABLE t3, t2, t1; +CREATE TABLE t1(fld1 INT NOT NULL PRIMARY KEY); +CREATE TABLE t2(fld1 INT NOT NULL, fld2 INT NOT NULL, +fld3 INT AS (fld2) VIRTUAL, +KEY(fld3, fld1), KEY(fld1), +FOREIGN KEY(fld1) REFERENCES t1(fld1) +ON DELETE CASCADE); +CREATE TABLE t3(fld1 INT NOT NULL, fld2 INT NOT NULL, +fld3 INT AS (fld2) VIRTUAL, KEY(fld3, fld1), +FOREIGN KEY(fld1) REFERENCES t2(fld1) +ON DELETE CASCADE); +INSERT INTO t1 VALUES(1), (2); +INSERT INTO t2 VALUES(1, 1, DEFAULT), (2, 2, default); +INSERT INTO t3 VALUES(1, 1, DEFAULT), (2, 2, default); +DELETE FROM t1 WHERE fld1= 1; +SELECT fld3, fld1 FROM t2; +fld3 fld1 +2 2 +SELECT fld3, fld1 FROM t3; +fld3 fld1 +2 2 +DROP TABLE t3, t2, t1; +# RENAME TABLE +CREATE TABLE t1(fld1 INT NOT NULL PRIMARY KEY); +CREATE TABLE t2(fld1 INT NOT NULL, +fld2 INT AS (fld1) VIRTUAL, +KEY(fld2, fld1), +FOREIGN KEY(fld1) REFERENCES t1(fld1) +ON DELETE CASCADE); +INSERT INTO t1 VALUES(1), (2); +INSERT INTO t2 VALUES(1, DEFAULT), (2, default); +RENAME TABLE t2 to t3; +DELETE FROM t1 WHERE fld1= 1; +SELECT fld2, fld1 FROM t3; +fld2 fld1 +2 2 +DROP TABLE t3, t1; +# FOREIGN_KEY_CHECKS disabled DURING INPLACE ALTER +CREATE TABLE t1(fld1 INT NOT NULL PRIMARY KEY); +CREATE TABLE t2(fld1 INT NOT NULL, +fld2 INT AS (fld1) VIRTUAL, +FOREIGN KEY(fld1) REFERENCES t1(fld1) +ON UPDATE CASCADE); +INSERT INTO t1 VALUES(1), (2); +INSERT INTO t2 VALUES(1, DEFAULT), (2, default); +SET foreign_key_checks = 0; +ALTER TABLE t2 ADD INDEX vk(fld2), ALGORITHM=INPLACE; +SET foreign_key_checks = 1; +UPDATE t1 SET fld1= 3 WHERE fld1= 2; +SELECT fld2 FROM t2; +fld2 +1 +3 +DROP TABLE t2, t1; +# GENERATED COLUMN COMPUTATION FAILS when SQL_MODE +# is set to ERROR_FOR_DIVISION_BY_ZERO +CREATE TABLE t1(fld1 INT NOT NULL PRIMARY KEY); +CREATE TABLE t2(fld1 INT NOT NULL, +fld2 INT AS (100/fld1) VIRTUAL, +KEY(fld2), +FOREIGN KEY(fld1) REFERENCES t1(fld1) +ON UPDATE CASCADE); +INSERT INTO t1 VALUES(1), (2); +INSERT INTO t2 VALUES(1, DEFAULT), (2, default); +UPDATE t1 SET fld1= 0 WHERE fld1= 2; +SELECT fld2 FROM t2; +fld2 +NULL +100 +DROP TABLE t2, t1; +# CHANGE SQL_MODE and try the ERROR_FOR_DIVISION_BY_ZERO +SET sql_mode = STRICT_ALL_TABLES; +CREATE TABLE t1(fld1 INT NOT NULL PRIMARY KEY); +CREATE TABLE t2(fld1 INT NOT NULL, +fld2 INT AS (100/fld1) VIRTUAL, +KEY(fld2), +FOREIGN KEY(fld1) REFERENCES t1(fld1) +ON UPDATE CASCADE); +INSERT INTO t1 VALUES(1), (2); +INSERT INTO t2 VALUES(1, DEFAULT), (2, default); +UPDATE t1 SET fld1= 0 WHERE fld1= 2; +SELECT fld2 FROM t2; +fld2 +NULL +100 +SELECT * FROM t2; +fld1 fld2 +1 100 +0 NULL +DROP TABLE t2, t1; +SET sql_mode = default; +# ADD FOREIGN CONSTRAINT USING COPY +CREATE TABLE t1(fld1 INT NOT NULL PRIMARY KEY); +CREATE TABLE t2(fld1 INT NOT NULL, +fld2 INT AS (fld1) VIRTUAL, KEY(fld2)); +ALTER TABLE t2 ADD FOREIGN KEY (fld1) +REFERENCES t1(fld1) ON UPDATE CASCADE, +ALGORITHM=copy; +INSERT INTO t1 VALUES(1); +INSERT INTO t2 VALUES(1, DEFAULT); +UPDATE t1 SET fld1= 2; +SELECT fld2 FROM t2; +fld2 +2 +SELECT * FROM t2; +fld1 fld2 +2 2 +DROP TABLE t2, t1; +# ADD FOREIGN CONSTRAINT USING INPLACE +CREATE TABLE t1(fld1 INT NOT NULL PRIMARY KEY); +CREATE TABLE t2(fld1 INT NOT NULL, +fld2 INT AS (fld1) VIRTUAL, KEY(fld2)); +SET foreign_key_checks = 0; +ALTER TABLE t2 ADD FOREIGN KEY (fld1) +REFERENCES t1(fld1) ON UPDATE CASCADE, +ALGORITHM=inplace; +SET foreign_key_checks = 1; +INSERT INTO t1 VALUES(1); +INSERT INTO t2 VALUES(1, DEFAULT); +UPDATE t1 SET fld1= 2; +SELECT fld2 FROM t2; +fld2 +2 +SELECT * FROM t2; +fld1 fld2 +2 2 +DROP TABLE t2, t1; +# DROP FOREIGN CONSTRAINT USING COPY +CREATE TABLE t1(fld1 INT NOT NULL PRIMARY KEY); +CREATE TABLE t2(fld1 INT NOT NULL, +fld2 INT AS (fld1) VIRTUAL, KEY(fld2), +CONSTRAINT fidx FOREIGN KEY (fld1) REFERENCES t1(fld1) +ON UPDATE CASCADE); +INSERT INTO t1 VALUES(1); +INSERT INTO t2 VALUES(1, DEFAULT); +ALTER TABLE t2 DROP FOREIGN KEY fidx, ALGORITHM=COPY; +UPDATE t1 SET fld1= 2; +SELECT fld2 FROM t2; +fld2 +1 +SELECT * FROM t2; +fld1 fld2 +1 1 +DROP TABLE t2, t1; +# DROP FOREIGN CONSTRAINT USING INPLACE +CREATE TABLE t1(fld1 INT NOT NULL PRIMARY KEY); +CREATE TABLE t2(fld1 INT NOT NULL, +fld2 INT AS (fld1) VIRTUAL, KEY(fld2), +CONSTRAINT fidx FOREIGN KEY (fld1) REFERENCES t1(fld1) +ON UPDATE CASCADE); +SET foreign_key_checks = 0; +ALTER TABLE t2 DROP FOREIGN KEY fidx, ALGORITHM=INPLACE; +SET foreign_key_checks = 1; +INSERT INTO t1 VALUES(1); +INSERT INTO t2 VALUES(1, DEFAULT); +UPDATE t1 SET fld1= 2; +SELECT fld2 FROM t2; +fld2 +1 +SELECT * FROM t2; +fld1 fld2 +1 1 +DROP TABLE t2, t1; +# ADD VC INDEX and ADD FK IN SAME COPY ALTER +CREATE TABLE t1(fld1 INT NOT NULL PRIMARY KEY); +CREATE TABLE t2(fld1 INT NOT NULL, +fld2 INT AS (fld1) VIRTUAL); +INSERT INTO t1 VALUES(1); +INSERT INTO t2 VALUES(1, DEFAULT); +ALTER TABLE t2 ADD INDEX(fld2), ADD FOREIGN KEY (fld1) REFERENCES t1(fld1) +ON UPDATE CASCADE, ALGORITHM=copy; +UPDATE t1 SET fld1= 2; +SELECT fld2 FROM t2; +fld2 +2 +SELECT * FROM t2; +fld1 fld2 +2 2 +DROP TABLE t2, t1; +# ADD VC INDEX and ADD FK IN SAME INPLACE ALTER +CREATE TABLE t1(fld1 INT NOT NULL PRIMARY KEY); +CREATE TABLE t2(fld1 INT NOT NULL, +fld2 INT AS (fld1) VIRTUAL); +INSERT INTO t1 VALUES(1); +INSERT INTO t2 VALUES(1, DEFAULT); +SET foreign_key_checks = 0; +ALTER TABLE t2 ADD INDEX(fld2), ADD FOREIGN KEY (fld1) REFERENCES t1(fld1) +ON UPDATE CASCADE, ALGORITHM=inplace; +SET foreign_key_checks = 1; +UPDATE t1 SET fld1= 2; +SELECT fld2 FROM t2; +fld2 +2 +SELECT * FROM t2; +fld1 fld2 +2 2 +DROP TABLE t2, t1; +# ADD VC INDEX and DROP FK IN SAME COPY ALTER +CREATE TABLE t1(fld1 INT NOT NULL PRIMARY KEY); +CREATE TABLE t2(fld1 INT NOT NULL, +fld2 INT AS (fld1) VIRTUAL, +CONSTRAINT fidx FOREIGN KEY(fld1) REFERENCES t1(fld1) +ON UPDATE CASCADE); +INSERT INTO t1 VALUES(1); +INSERT INTO t2 VALUES(1, DEFAULT); +ALTER TABLE t2 ADD INDEX(fld2), DROP FOREIGN KEY fidx, ALGORITHM=copy; +UPDATE t1 SET fld1= 2; +SELECT fld2 FROM t2; +fld2 +1 +SELECT * FROM t2; +fld1 fld2 +1 1 +DROP TABLE t2, t1; +# ADD VC INDEX and DROP FK IN SAME INPLACE ALTER +CREATE TABLE t1(fld1 INT NOT NULL PRIMARY KEY); +CREATE TABLE t2(fld1 INT NOT NULL, +fld2 INT AS (fld1) VIRTUAL, +CONSTRAINT fidx FOREIGN KEY(fld1) REFERENCES t1(fld1) +ON UPDATE CASCADE); +INSERT INTO t1 VALUES(1); +INSERT INTO t2 VALUES(1, DEFAULT); +SET foreign_key_checks = 0; +ALTER TABLE t2 ADD INDEX(fld2), DROP FOREIGN KEY fidx, ALGORITHM=inplace; +SET foreign_key_checks = 1; +UPDATE t1 SET fld1= 2; +SELECT fld2 FROM t2; +fld2 +1 +SELECT * FROM t2; +fld1 fld2 +1 1 +DROP TABLE t2, t1; +# DROP VC INDEX and ADD FK IN SAME COPY ALTER +CREATE TABLE t1(fld1 INT NOT NULL PRIMARY KEY); +CREATE TABLE t2(fld1 INT NOT NULL, +fld2 INT AS (fld1) VIRTUAL, +KEY idx(fld2)); +INSERT INTO t1 VALUES(1); +INSERT INTO t2 VALUES(1, DEFAULT); +ALTER TABLE t2 DROP INDEX idx, ADD FOREIGN KEY (fld1) REFERENCES t1(fld1) +ON UPDATE CASCADE, ALGORITHM=COPY; +UPDATE t1 SET fld1= 2; +SELECT fld2 FROM t2; +fld2 +2 +SELECT * FROM t2; +fld1 fld2 +2 2 +DROP TABLE t2, t1; +# DROP VC INDEX and ADD FK IN SAME INPLACE ALTER +CREATE TABLE t1(fld1 INT NOT NULL PRIMARY KEY); +CREATE TABLE t2(fld1 INT NOT NULL, +fld2 INT AS (fld1) VIRTUAL, +KEY idx(fld2)); +INSERT INTO t1 VALUES(1); +INSERT INTO t2 VALUES(1, DEFAULT); +SET foreign_key_checks = 0; +ALTER TABLE t2 DROP INDEX idx, ADD FOREIGN KEY (fld1) REFERENCES t1(fld1) +ON UPDATE CASCADE, ALGORITHM=INPLACE; +SET foreign_key_checks = 1; +UPDATE t1 SET fld1= 2; +SELECT fld2 FROM t2; +fld2 +2 +SELECT * FROM t2; +fld1 fld2 +2 2 +DROP TABLE t2, t1; +# DROP VC INDEX and DROP FK IN SAME COPY ALTER +CREATE TABLE t1(fld1 INT NOT NULL PRIMARY KEY); +CREATE TABLE t2(fld1 INT NOT NULL, +fld2 INT AS (fld1) VIRTUAL, +KEY idx(fld2), +CONSTRAINT fidx FOREIGN KEY(fld1) REFERENCES t1(fld1) +ON UPDATE CASCADE); +INSERT INTO t1 VALUES(1); +INSERT INTO t2 VALUES(1, DEFAULT); +ALTER TABLE t2 DROP KEY idx, DROP FOREIGN KEY fidx, ALGORITHM=COPY; +UPDATE t1 SET fld1= 2; +SELECT fld2 FROM t2; +fld2 +1 +SELECT * FROM t2; +fld1 fld2 +1 1 +DROP TABLE t2, t1; +# DROP VC INDEX and DROP FK IN SAME INPLACE ALTER +CREATE TABLE t1(fld1 INT NOT NULL PRIMARY KEY); +CREATE TABLE t2(fld1 INT NOT NULL, +fld2 INT AS (fld1) VIRTUAL, +KEY idx(fld2), +CONSTRAINT fidx FOREIGN KEY(fld1) REFERENCES t1(fld1) +ON UPDATE CASCADE); +INSERT INTO t1 VALUES(1); +INSERT INTO t2 VALUES(1, DEFAULT); +SET foreign_key_checks = 0; +ALTER TABLE t2 DROP KEY idx, DROP FOREIGN KEY fidx, ALGORITHM=INPLACE; +SET foreign_key_checks = 1; +UPDATE t1 SET fld1= 2; +SELECT fld2 FROM t2; +fld2 +1 +SELECT * FROM t2; +fld1 fld2 +1 1 +DROP TABLE t2, t1; diff --git a/mysql-test/suite/gcol/r/innodb_virtual_fk_restart.result b/mysql-test/suite/gcol/r/innodb_virtual_fk_restart.result new file mode 100644 index 00000000000..25faeaf4e84 --- /dev/null +++ b/mysql-test/suite/gcol/r/innodb_virtual_fk_restart.result @@ -0,0 +1,44 @@ +# +# Bug#22469130: FOREIGN KEY ON DELETE CASCADE NOT ALLOWED +# WHEN A VIRTUAL INDEX EXISTS. +# Add the VIRTUAL INDEX contains fk constraINT column +# using INPLACE alter operatiON +CREATE TABLE t1(fld1 INT NOT NULL PRIMARY KEY) engine=innodb; +CREATE TABLE t2(fld1 INT NOT NULL, fld2 INT NOT NULL, +fld3 INT AS (fld2) VIRTUAL, KEY(fld1), +FOREIGN KEY(fld1) REFERENCES t1(fld1) ON UPDATE CASCADE) engine=innodb; +INSERT INTO t1(fld1) VALUES(1); +INSERT INTO t2(fld1, fld2) VALUES(1, 2); +UPDATE t1 SET fld1= 2; +SELECT fld3, fld1 FROM t2; +fld3 fld1 +2 2 +alter TABLE t2 ADD INDEX vk(fld3, fld1), ALGORITHM=INPLACE; +UPDATE t1 SET fld1=3; +SELECT fld3, fld1 FROM t2; +fld3 fld1 +2 3 +DROP TABLE t2, t1; +# TEMPORARY TABLE NAME and CHILD TABLE NAME are same +CREATE TABLE t1(fld1 INT NOT NULL PRIMARY KEY) engine=innodb; +CREATE TABLE t2(fld1 INT NOT NULL, +fld2 INT AS (fld1) VIRTUAL, +KEY(fld2), +FOREIGN KEY(fld1) REFERENCES t1(fld1) +ON UPDATE CASCADE) engine=innodb; +INSERT INTO t1 VALUES(1), (2); +INSERT INTO t2 VALUES(1, DEFAULT), (2, default); +CREATE TEMPORARY TABLE t2 (fld1 INT NOT NULL)ENGINE=INNODB; +UPDATE t1 SET fld1= 3 WHERE fld1= 2; +connect con1,localhost,root,,test; +SELECT fld2 FROM t2; +fld2 +1 +3 +CHECK TABLE t2; +Table Op Msg_type Msg_text +test.t2 check status OK +connection default; +disconnect con1; +DROP TABLE t2; +DROP TABLE t2, t1; diff --git a/mysql-test/suite/gcol/r/innodb_virtual_index.result b/mysql-test/suite/gcol/r/innodb_virtual_index.result new file mode 100644 index 00000000000..b20c2085541 --- /dev/null +++ b/mysql-test/suite/gcol/r/innodb_virtual_index.result @@ -0,0 +1,196 @@ +# +# Bug 21922176 - PREBUILT->SEARCH_TUPLE CREATED WITHOUT INCLUDING +# THE NUMBER OF VIRTUAL COLUMNS +# +CREATE TABLE t1 (a INT, a1 INT GENERATED ALWAYS AS (a) VIRTUAL, a2 INT +GENERATED ALWAYS AS (a) VIRTUAL, a3 INT GENERATED ALWAYS AS (a) VIRTUAL, a4 +INT GENERATED ALWAYS AS (a) VIRTUAL, a5 INT GENERATED ALWAYS AS (a) VIRTUAL, +a6 INT GENERATED ALWAYS AS (a) VIRTUAL, a7 INT GENERATED ALWAYS AS (a) +VIRTUAL, a8 INT GENERATED ALWAYS AS (a) VIRTUAL, a9 INT GENERATED ALWAYS AS +(a) VIRTUAL, INDEX(a1, a2, a3, a4, a5, a6, a7, a8, a9)) ; +INSERT INTO t1(a) VALUES(10); +SELECT * FROM t1 WHERE a1=10 AND a2 = 10 AND a3 =10 AND a4 = 10 AND a5=10 AND +a6=10 AND a7=10 AND a8=10 AND a9=10; +a a1 a2 a3 a4 a5 a6 a7 a8 a9 +10 10 10 10 10 10 10 10 10 10 +DROP TABLE t1; +# +# Bug 22572997 - GCOL:INNODB: FAILING ASSERTION: N < REC_OFFS_N_FIELDS( +# OFFSETS) +# +SET @@SESSION.sql_mode=0; +CREATE TABLE t1( +c1 int(1)AUTO_INCREMENT, +c2 int(1), +c3 int(1)GENERATED ALWAYS AS ((c2 + c2)) VIRTUAL, +c4 int(1)GENERATED ALWAYS AS ((c3 + c2)) VIRTUAL, +c5 date, +c6 date GENERATED ALWAYS AS((c5 + interval 30 day)) VIRTUAL, +c7 DATE, +c8 time, +c9 DATE GENERATED ALWAYS AS(addtime(c7,c8)) VIRTUAL, +c10 time GENERATED ALWAYS AS(addtime(c7,c8)) VIRTUAL, +c11 DATE GENERATED ALWAYS AS(addtime(c9,c8)) VIRTUAL, +c12 CHAR(1), +c13 CHAR(1)GENERATED ALWAYS AS (concat(c12,c12)) VIRTUAL, +c14 CHAR(2)GENERATED ALWAYS AS (concat(c13,'x')) VIRTUAL, +PRIMARY KEY(c1), +KEY c4_6(c4,c11) +)ENGINE=InnoDB DEFAULT CHARSET=latin1; +CREATE TABLE t2( +c1 int(1)AUTO_INCREMENT, +c2 int(1), +c3 int(1)GENERATED ALWAYS AS ((c2 + c2)) VIRTUAL, +c4 int(1)GENERATED ALWAYS AS ((c3 + c2)) VIRTUAL, +c5 date, +c6 date GENERATED ALWAYS AS((c5 + interval 30 day)) VIRTUAL, +c6a date GENERATED ALWAYS AS((c6 + interval 30 day)) VIRTUAL, +c7 DATE, +c8 time, +c9 DATE GENERATED ALWAYS AS(addtime(c7,c8)) VIRTUAL, +c10 time GENERATED ALWAYS AS(addtime(c7,c8)) VIRTUAL, +c11 DATE GENERATED ALWAYS AS(addtime(c9,c8)) VIRTUAL, +c11a time GENERATED ALWAYS AS(addtime(c7,c10)) VIRTUAL, +c12 CHAR(1), +c13 CHAR(2)GENERATED ALWAYS AS (concat(c12,c12)) VIRTUAL, +c14 CHAR(4)GENERATED ALWAYS AS (concat(c13,'x')) VIRTUAL, +PRIMARY KEY(c1), +KEY c13(c13), +KEY c4_6(c4,c11) +)ENGINE=InnoDB DEFAULT CHARSET=latin1; +INSERT INTO t2(c1,c2,c5,c7,c8,c12)VALUES (0,0,0,0,0,'v'); +CREATE TABLE t3( +c1 int(1)AUTO_INCREMENT, +c2 int(1), +c3 int(1)GENERATED ALWAYS AS ((c2 + c2)) VIRTUAL, +c4 int(1)GENERATED ALWAYS AS ((c3 + c2)) VIRTUAL, +c5 date, +c7 DATE, +c8 time, +c9 DATE GENERATED ALWAYS AS(addtime(c7,c8)) VIRTUAL, +c11 DATE GENERATED ALWAYS AS(addtime(c9,c8)) VIRTUAL, +c12 CHAR(1), +PRIMARY KEY(c1), +KEY c4_6(c4,c11) +)ENGINE=InnoDB DEFAULT CHARSET=latin1; +INSERT INTO t3(c1,c2,c5,c7,c8,c12)VALUES +(0,0,0,0,0,'q'),(0,0,0,0,0,'g'),(0,0,0,0,0,'l'),(0,0,0,0,0,1),(0,0,0,0,0,'v'), +(0,1,0,0,0,'c'),(0,0,0,0,0,'x'); +UPDATE +t2 AS O1,t3 AS O2 +SET O1.c12=1 +WHERE O1.c14 NOT IN +( +SELECT +DISTINCT I1.c14 AS y +FROM t1 AS I1 +ORDER BY I1.c14); +SET @@SESSION.sql_mode=default; +DROP TABLE t1, t2, t3; +# +# Bug 22650296 - ASSERTION IN INNOBASE_BUILD_COL_MAP, ALTER +# +CREATE TABLE `ibstd_08` ( +`nc00577` tinyint(4) DEFAULT NULL, +`nc07844` varchar(41) DEFAULT NULL, +`gc01908` point NOT NULL, +`nc04156` char(17) DEFAULT NULL, +`nc09536` longblob NOT NULL, +`nc09231` decimal(10,0) NOT NULL, +`a` int(11) NOT NULL, +`b` varchar(198) NOT NULL, +`nc04560` mediumtext, +`c` char(187) DEFAULT NULL, +`vbidxcol` char(3) GENERATED ALWAYS AS (substr(`b`,1,3)) VIRTUAL, +`gc00881` polygon NOT NULL, +`nc05121` int(11) NOT NULL DEFAULT '85941481', +KEY `a` (`a`), +KEY `b` (`b`(3),`a`), +KEY `c` (`c`(99),`b`(25)), +KEY `b_2` (`b`(5),`c`(10),`a`), +KEY `vbidxcol` (`vbidxcol`), +KEY `a_2` (`a`,`vbidxcol`), +KEY `vbidxcol_2` (`vbidxcol`), +FULLTEXT KEY `ftsic` (`c`,`b`) +) ENGINE=InnoDB; +Warnings: +Note 1831 Duplicate index 'vbidxcol_2' defined on the table 'test.ibstd_08'. This is deprecated and will be disallowed in a future release +ALTER TABLE ibstd_08 ADD COLUMN nc07006 BIGINT AUTO_INCREMENT NOT NULL , ADD KEY auto_nc07006(nc07006); +Warnings: +Warning 124 InnoDB rebuilding table to add column FTS_DOC_ID +DROP TABLE ibstd_08; +# +# Bug 22899305 - GCOLS: FAILING ASSERTION: !(COL->PRTYPE & 256) +# AND SEGFAULT +# +set sql_mode=""; +create table t (a int) engine=innodb; +create table s ( +b int generated always as (1) virtual, +c int, +d int generated always as (1) virtual, +key (d) +) engine=innodb; +insert into t(a) values ((select d from s for update)); +insert into s(c) values (''); +Warnings: +Warning 1366 Incorrect integer value: '' for column 'c' at row 1 +SET sql_mode = default; +drop table if exists t,s; +# +# Bug 23014521 - GCOL:INNODB: FAILING ASSERTION: !IS_V +# +CREATE TABLE t1 ( +col1 int(11) NOT NULL, +col2 int(11) DEFAULT NULL, +col3 int(11) NOT NULL, +col4 int(11) DEFAULT NULL, +col5 int(11) GENERATED ALWAYS AS ((col1 % col4)) VIRTUAL, +col6 int(11) GENERATED ALWAYS AS ((col2 - col4)) VIRTUAL, +col5x int(11) GENERATED ALWAYS AS ((col3 / col2)) VIRTUAL, +col6b varchar(20) GENERATED ALWAYS AS (col2) VIRTUAL, +col6x int(11) GENERATED ALWAYS AS ((col2 % col1)) VIRTUAL, +col7 int(11) GENERATED ALWAYS AS ((col6x + col5x)) VIRTUAL, +col8 int(11) GENERATED ALWAYS AS ((col5x / col5)) VIRTUAL, +col7x int(11) GENERATED ALWAYS AS ((col5x + col5)) VIRTUAL, +col8x int(11) GENERATED ALWAYS AS ((col5 / col5x)) VIRTUAL, +col9 text, +col2b varchar(20) GENERATED ALWAYS AS (col4) VIRTUAL, +col8a int(11) GENERATED ALWAYS AS (col2) VIRTUAL, +col4b varchar(20) GENERATED ALWAYS AS (col4) VIRTUAL, +col1c int(11) GENERATED ALWAYS AS ((col2 * col1)) VIRTUAL, +extra int(11) DEFAULT NULL, +col5c int(11) GENERATED ALWAYS AS ((col1 / col1)) VIRTUAL, +col6a bigint(20) GENERATED ALWAYS AS ((col3 / col1)) VIRTUAL, +col1a varchar(20) GENERATED ALWAYS AS (col6) VIRTUAL, +col6c int(11) GENERATED ALWAYS AS ((col2 % col2)) VIRTUAL, +col7c bigint(20) GENERATED ALWAYS AS ((col2 / col1)) VIRTUAL, +col2c int(11) GENERATED ALWAYS AS ((col5 % col5)) VIRTUAL, +col1b int(11) GENERATED ALWAYS AS ((col1 / col2)) VIRTUAL, +col3b bigint(20) GENERATED ALWAYS AS ((col6x % col6)) VIRTUAL, +UNIQUE KEY idx7 (col1,col3,col2), +UNIQUE KEY uidx (col9(10)), +KEY idx15 (col9(10) DESC,col2 DESC), +KEY idx10 (col9(10) DESC,col1 DESC), +KEY idx11 (col6x DESC), +KEY idx6 (col9(10) DESC,col7 DESC), +KEY idx14 (col6 DESC) +) ENGINE=InnoDB DEFAULT CHARSET=latin1; +ALTER TABLE t1 ADD COLUMN col7a INT GENERATED ALWAYS AS (col5x % col6x) +VIRTUAL, ADD FULLTEXT KEY ftidx ( col9 ), algorithm=inplace; +ERROR 0A000: ALGORITHM=INPLACE is not supported. Reason: INPLACE ADD or DROP of virtual columns cannot be combined with other ALTER TABLE actions. Try ALGORITHM=COPY +CREATE FULLTEXT INDEX idx ON t1(col9); +Warnings: +Warning 124 InnoDB rebuilding table to add column FTS_DOC_ID +ALTER TABLE t1 ADD COLUMN col7a INT GENERATED ALWAYS AS (col5x % col6x) +VIRTUAL, ADD FULLTEXT KEY ftidx ( col9 ), algorithm=inplace; +DROP TABLE t1; +CREATE TABLE t1 ( +col1 int(11) NOT NULL, +col2 int(11) DEFAULT NULL, +col3 int(11) NOT NULL, +col4 int(11) DEFAULT NULL) engine=innodb; +ALTER TABLE t1 ADD COLUMN col7a INT GENERATED ALWAYS AS (col1 % col2) +VIRTUAL, ADD UNIQUE index idx (col1), algorithm=inplace; +ERROR 0A000: ALGORITHM=INPLACE is not supported. Reason: INPLACE ADD or DROP of virtual columns cannot be combined with other ALTER TABLE actions. Try ALGORITHM=COPY +DROP TABLE t1; diff --git a/mysql-test/suite/gcol/r/innodb_virtual_purge.result b/mysql-test/suite/gcol/r/innodb_virtual_purge.result new file mode 100644 index 00000000000..658f49b4b31 --- /dev/null +++ b/mysql-test/suite/gcol/r/innodb_virtual_purge.result @@ -0,0 +1,140 @@ +# +# Bug#21869656 UNDO LOG DOES NOT CONTAIN ENOUGH INFORMATION +# ON INDEXED VIRTUAL COLUMNS +# +CREATE TABLE t1 (a INT, b INT, +a1 INT GENERATED ALWAYS AS (a) VIRTUAL, INDEX(a1) +) ENGINE=InnoDB; +INSERT INTO t1 (a,b) VALUES(1,1); +connect con1,localhost,root,,; +CREATE TABLE t0 (a INT) ENGINE=InnoDB; +BEGIN; +SELECT * FROM t0; +a +connection default; +UPDATE t1 SET a=0; +ALTER TABLE t1 DROP COLUMN a1, ALGORITHM=INPLACE; +ALTER TABLE t1 ADD COLUMN b1 INT GENERATED ALWAYS AS (b) VIRTUAL, ADD +INDEX(b1), +ALGORITHM=INPLACE; +connection con1; +COMMIT; +UPDATE t1 SET a=1; +connection default; +CHECK TABLE t1; +Table Op Msg_type Msg_text +test.t1 check status OK +SELECT b1 FROM t1; +b1 +1 +ALTER TABLE t1 +ADD COLUMN a1 INT GENERATED ALWAYS AS (a) VIRTUAL, +ADD COLUMN a2 INT GENERATED ALWAYS AS (a + b) VIRTUAL, +ADD COLUMN a3 INT GENERATED ALWAYS AS (a - b) VIRTUAL, +ADD COLUMN a4 INT GENERATED ALWAYS AS (a - b) VIRTUAL, +ADD INDEX(a1), ADD INDEX(a2), ADD INDEX(a3), ALGORITHM=INPLACE; +CREATE TABLE t2 ( +a BLOB, +b BLOB, +c BLOB GENERATED ALWAYS AS (CONCAT(a,b)) VIRTUAL, +h VARCHAR(10) DEFAULT NULL +) ENGINE=InnoDB; +INSERT INTO t2 VALUES (REPEAT('g', 16000), REPEAT('x', 16000), DEFAULT, 'kk'); +INSERT INTO t2 VALUES (REPEAT('a', 16000), REPEAT('b', 16000), DEFAULT, 'mm'); +CREATE INDEX idx ON t2(c(100)); +INSERT INTO t1 (a, b) VALUES(1,1); +connection con1; +BEGIN; +SELECT * FROM t0; +a +connection default; +UPDATE t1 SET a=0; +affected rows: 2 +info: Rows matched: 2 Changed: 2 Warnings: 0 +UPDATE t1 SET b=0; +affected rows: 2 +info: Rows matched: 2 Changed: 2 Warnings: 0 +ALTER TABLE t1 DROP COLUMN a3, ALGORITHM=INPLACE; +affected rows: 0 +info: Records: 0 Duplicates: 0 Warnings: 0 +UPDATE t1 SET a=2; +affected rows: 2 +info: Rows matched: 2 Changed: 2 Warnings: 0 +ALTER TABLE t1 DROP COLUMN a2, ALGORITHM=INPLACE; +affected rows: 0 +info: Records: 0 Duplicates: 0 Warnings: 0 +UPDATE t1 SET b=3; +affected rows: 2 +info: Rows matched: 2 Changed: 2 Warnings: 0 +ALTER TABLE t1 ADD COLUMN b2 INT GENERATED ALWAYS AS (b) VIRTUAL, +ADD INDEX(b2), ALGORITHM=INPLACE; +affected rows: 0 +info: Records: 0 Duplicates: 0 Warnings: 0 +UPDATE t1 SET b=9; +affected rows: 2 +info: Rows matched: 2 Changed: 2 Warnings: 0 +ALTER TABLE t1 ADD COLUMN b3 INT GENERATED ALWAYS AS (a) VIRTUAL, +ADD INDEX(b3), ALGORITHM=INPLACE; +affected rows: 0 +info: Records: 0 Duplicates: 0 Warnings: 0 +UPDATE t1 SET b=10; +affected rows: 2 +info: Rows matched: 2 Changed: 2 Warnings: 0 +ALTER TABLE t2 DROP COLUMN c; +affected rows: 0 +info: Records: 0 Duplicates: 0 Warnings: 0 +UPDATE t2 SET a = REPEAT('s', 6000) WHERE a like 'aaa%'; +affected rows: 1 +info: Rows matched: 1 Changed: 1 Warnings: 0 +ALTER TABLE t2 ADD COLUMN x1 BLOB GENERATED ALWAYS AS (CONCAT(a,b)) VIRTUAL, +ADD COLUMN x2 BLOB GENERATED ALWAYS AS (CONCAT(a,b)) VIRTUAL, +ADD INDEX(x1(100), x2(120)), ADD INDEX (x1(20)); +affected rows: 0 +info: Records: 0 Duplicates: 0 Warnings: 0 +UPDATE t1 SET a=5; +affected rows: 2 +info: Rows matched: 2 Changed: 2 Warnings: 0 +UPDATE t2 SET a = REPEAT('m', 16000) WHERE a like 'sss%'; +affected rows: 1 +info: Rows matched: 1 Changed: 1 Warnings: 0 +ALTER TABLE t1 DROP COLUMN b2, ALGORITHM=INPLACE; +affected rows: 0 +info: Records: 0 Duplicates: 0 Warnings: 0 +UPDATE t1 SET a=6; +affected rows: 2 +info: Rows matched: 2 Changed: 2 Warnings: 0 +ALTER TABLE t2 DROP COLUMN x1, DROP COLUMN x2, ALGORITHM=INPLACE; +affected rows: 0 +info: Records: 0 Duplicates: 0 Warnings: 0 +UPDATE t2 SET a = REPEAT('x', 1000) WHERE a like 'mmm%'; +affected rows: 1 +info: Rows matched: 1 Changed: 1 Warnings: 0 +ALTER TABLE t1 DROP INDEX b3; +affected rows: 0 +info: Records: 0 Duplicates: 0 Warnings: 0 +UPDATE t1 SET a=100; +affected rows: 2 +info: Rows matched: 2 Changed: 2 Warnings: 0 +connection con1; +COMMIT; +disconnect con1; +connection default; +CHECK TABLE t1; +Table Op Msg_type Msg_text +test.t1 check status OK +SELECT b1 FROM t1; +b1 +10 +10 +SELECT * FROM t1; +a b b1 a1 a4 b3 +100 10 10 100 90 100 +100 10 10 100 90 100 +CHECK TABLE t2; +Table Op Msg_type Msg_text +test.t2 check status OK +DROP TABLE t2, t1, t0; +CREATE TABLE t1 (a VARCHAR(30), b INT, a2 VARCHAR(30) GENERATED ALWAYS AS (a) VIRTUAL); +CREATE INDEX idx ON t1(a2(10), b, a2(20)); +ERROR 42S21: Duplicate column name 'a2' +DROP TABLE t1; diff --git a/mysql-test/suite/gcol/r/innodb_wl8114.result b/mysql-test/suite/gcol/r/innodb_wl8114.result new file mode 100644 index 00000000000..42e65101365 --- /dev/null +++ b/mysql-test/suite/gcol/r/innodb_wl8114.result @@ -0,0 +1,52 @@ +CREATE TABLE t_8114 (a int) ENGINE = INNODB; +ALTER TABLE t_8114 ADD b INT GENERATED ALWAYS AS (a) VIRTUAL; +SELECT NAME FROM INFORMATION_SCHEMA.INNODB_SYS_TABLES WHERE NAME LIKE "%t_8114"; +NAME +test/t_8114 +SELECT NAME, POS, MTYPE, PRTYPE, LEN FROM INFORMATION_SCHEMA.INNODB_SYS_COLUMNS WHERE TABLE_ID IN (SELECT TABLE_ID FROM INFORMATION_SCHEMA.INNODB_SYS_TABLES WHERE NAME LIKE "%t_8114"); +NAME POS MTYPE PRTYPE LEN +a 0 6 1027 4 +b 65537 6 9219 4 +INSERT INTO t_8114 VALUES (9, default); +INSERT INTO t_8114 VALUES (3, default); +INSERT INTO t_8114 VALUES (1, default); +INSERT INTO t_8114 VALUES (5, default); +SELECT * FROM t_8114; +a b +9 9 +3 3 +1 1 +5 5 +DROP TABLE t_8114; +CREATE TABLE t_8114 (Column_1 CHAR(5) GENERATED ALWAYS AS (PI()+5), Column_2 CHAR(5)) engine=innodb; +SELECT NAME, FLAG, N_COLS FROM INFORMATION_SCHEMA.INNODB_SYS_TABLES WHERE NAME LIKE "%t_8114"; +NAME FLAG N_COLS +test/t_8114 33 4 +SELECT NAME, POS, MTYPE, PRTYPE, LEN FROM INFORMATION_SCHEMA.INNODB_SYS_COLUMNS WHERE TABLE_ID IN (SELECT TABLE_ID FROM INFORMATION_SCHEMA.INNODB_SYS_TABLES WHERE NAME LIKE "%t_8114"); +NAME POS MTYPE PRTYPE LEN +Column_2 0 2 524542 5 +Column_1 65536 2 532734 5 +INSERT INTO t_8114 VALUES (default, "aa"); +INSERT INTO t_8114 VALUES (default, "bb"); +INSERT INTO t_8114 VALUES (default, "ee"); +INSERT INTO t_8114 VALUES (default, "pp"); +SELECT * FROM t_8114; +Column_1 Column_2 +8.142 aa +8.142 bb +8.142 ee +8.142 pp +ALTER TABLE t_8114 DROP Column_1; +SELECT NAME FROM INFORMATION_SCHEMA.INNODB_SYS_TABLES WHERE NAME LIKE "%t_8114"; +NAME +test/t_8114 +SELECT NAME, POS, MTYPE, PRTYPE, LEN FROM INFORMATION_SCHEMA.INNODB_SYS_COLUMNS WHERE TABLE_ID IN (SELECT TABLE_ID FROM INFORMATION_SCHEMA.INNODB_SYS_TABLES WHERE NAME LIKE "%t_8114"); +NAME POS MTYPE PRTYPE LEN +Column_2 0 2 524542 5 +SELECT * FROM t_8114; +Column_2 +aa +bb +ee +pp +DROP TABLE t_8114; diff --git a/mysql-test/suite/gcol/r/main_alter_table.result b/mysql-test/suite/gcol/r/main_alter_table.result new file mode 100644 index 00000000000..864169ee16c --- /dev/null +++ b/mysql-test/suite/gcol/r/main_alter_table.result @@ -0,0 +1,52 @@ +# +# Bug#22017616: ASSERTION FAILED: TABLE_SHARE->IS_MISSING_PRIMARY_KEY() +# == M_PREBUILT->CLUST_IND +# +# Ensure that adding indexes with virtual columns are not promoted to +# primary keys +# +# Base line with normal column - should be promoted +CREATE TABLE t0(a INT NOT NULL) ENGINE=INNODB; +ALTER TABLE t0 ADD UNIQUE INDEX (a); +# Case a: Create table with virtual unique not null column +CREATE TABLE t1(a POINT GENERATED ALWAYS AS (POINT(1,1)) VIRTUAL UNIQUE) ENGINE=INNODB; +SELECT * FROM t1; +a +# Case b: Create table with index on virtual point column +CREATE TABLE t2(a POINT GENERATED ALWAYS AS (POINT(1,1)) VIRTUAL, UNIQUE INDEX no_pk(a(1))) ENGINE=INNODB; +SELECT * FROM t2; +a +# Case c: Add unique index on virtual point column +CREATE TABLE t3(a POINT GENERATED ALWAYS AS (POINT(1,1)) VIRTUAL) +ENGINE=INNODB; +ALTER TABLE t3 ADD UNIQUE INDEX (a(1)); +SELECT * FROM t3; +a +# Case d: Add unique index on virtual blob column +CREATE TABLE t4 (a BLOB, b BLOB GENERATED ALWAYS AS (a) VIRTUAL) ENGINE=INNODB; +ALTER TABLE t4 ADD UNIQUE INDEX (b(1)); +SELECT * FROM t4; +a b +# Query I_S to verify that 'a' is promoted to pk only when it +# isn't virtual +SELECT T.NAME AS TABLE_NAME, I.NAME AS INDEX_NAME, +CASE (I.TYPE & 3) +WHEN 3 THEN "yes" + ELSE "no" END AS IS_PRIMARY_KEY, +F.NAME AS FIELD_NAME, F.POS AS FIELD_POS FROM +INFORMATION_SCHEMA.INNODB_SYS_TABLES AS T JOIN +INFORMATION_SCHEMA.INNODB_SYS_INDEXES AS I JOIN +INFORMATION_SCHEMA.INNODB_SYS_FIELDS AS F +ON I.INDEX_ID = F.INDEX_ID AND I.TABLE_ID = T.TABLE_ID +WHERE T.NAME LIKE 'test/%'; +TABLE_NAME INDEX_NAME IS_PRIMARY_KEY FIELD_NAME FIELD_POS +test/t0 a yes a 0 +test/t1 a no a 0 +test/t2 no_pk no a 0 +test/t3 a no a 0 +test/t4 b no b 0 +DROP TABLE t0; +DROP TABLE t1; +DROP TABLE t2; +DROP TABLE t3; +DROP TABLE t4; diff --git a/mysql-test/suite/gcol/r/main_mysqldump.result b/mysql-test/suite/gcol/r/main_mysqldump.result new file mode 100644 index 00000000000..78d99a0bdb0 --- /dev/null +++ b/mysql-test/suite/gcol/r/main_mysqldump.result @@ -0,0 +1,49 @@ +CREATE DATABASE dump_generated; +USE dump_generated; +CREATE TABLE t1 (pk INTEGER, a INTEGER, b INTEGER, c VARCHAR(16), +sum INTEGER GENERATED ALWAYS AS (a+b), +sub VARCHAR(4) GENERATED ALWAYS AS (SUBSTRING(c, 1, 4)), +key k1(sum), +key k2(sub) +) engine=innodb; +INSERT INTO t1(pk, a, b, c) VALUES (1, 11, 12, 'oneone'), (2, 21, 22, 'twotwo'); +SELECT * FROM t1; +pk a b c sum sub +1 11 12 oneone 23 oneo +2 21 22 twotwo 43 twot +DELETE FROM t1; +SELECT * FROM t1; +pk a b c sum sub +1 11 12 oneone 23 oneo +2 21 22 twotwo 43 twot +DELETE FROM t1; +LOAD DATA INFILE 'MYSQLTEST_VARDIR/tmp/t1.txt' INTO TABLE t1; +SELECT * FROM t1; +pk a b c sum sub +1 11 12 oneone 23 oneo +2 21 22 twotwo 43 twot +DROP TABLE t1; +# A table with regular columns after generated +CREATE TABLE t2 (pk INTEGER, a INTEGER, b INTEGER, +sum INTEGER GENERATED ALWAYS AS (a+b), +c VARCHAR(16), +key k1(sum) +) engine=innodb; +INSERT INTO t2(pk, a, b, c) VALUES (1, 11, 12, 'oneone'), (2, 21, 22, 'twotwo'); +SELECT * FROM t2; +pk a b sum c +1 11 12 23 oneone +2 21 22 43 twotwo +DELETE FROM t2; +SELECT * FROM t2; +pk a b sum c +1 11 12 23 oneone +2 21 22 43 twotwo +DELETE FROM t2; +LOAD DATA INFILE 'MYSQLTEST_VARDIR/tmp/t2.txt' INTO TABLE t2; +SELECT * FROM t2; +pk a b sum c +1 11 12 23 oneone +2 21 22 43 twotwo +DROP TABLE t2; +DROP DATABASE dump_generated; diff --git a/mysql-test/suite/gcol/t/gcol_bugfixes.test b/mysql-test/suite/gcol/t/gcol_bugfixes.test index 8c084d0b54a..c4a566c3c62 100644 --- a/mysql-test/suite/gcol/t/gcol_bugfixes.test +++ b/mysql-test/suite/gcol/t/gcol_bugfixes.test @@ -80,164 +80,113 @@ DROP TABLE t1; --echo # CREATE TABLE c ( - pk INTEGER AUTO_INCREMENT, - col_int_nokey INTEGER /*! NULL */, - col_int_key INTEGER GENERATED ALWAYS AS -(col_int_nokey + col_int_nokey) VIRTUAL not null, + pk INTEGER AUTO_INCREMENT, + col_int_nokey INTEGER, + gcol_int_key INTEGER GENERATED ALWAYS AS (col_int_nokey + col_int_nokey) VIRTUAL, + col_date_nokey DATE, + gcol_date_key DATE GENERATED ALWAYS AS (DATE_ADD(col_date_nokey,interval 30 day)) VIRTUAL, + col_datetime_nokey DATETIME, + col_time_nokey TIME, + gcol_datetime_key DATETIME GENERATED ALWAYS AS (ADDTIME(col_datetime_nokey, col_time_nokey)) VIRTUAL, + gcol_time_key TIME GENERATED ALWAYS AS (ADDTIME(col_datetime_nokey, col_time_nokey)) VIRTUAL, + col_varchar_nokey VARCHAR(1), + gcol_varchar_key VARCHAR(2) GENERATED ALWAYS AS (CONCAT(col_varchar_nokey, col_varchar_nokey)) VIRTUAL, + PRIMARY KEY (pk), + UNIQUE KEY (gcol_int_key), + UNIQUE KEY (gcol_varchar_key), + UNIQUE KEY (gcol_date_key), + KEY (gcol_time_key), + KEY (gcol_datetime_key), + UNIQUE KEY (gcol_int_key, gcol_varchar_key), + KEY (gcol_int_key, col_int_nokey), + KEY(gcol_int_key,gcol_date_key), + KEY(gcol_int_key, gcol_time_key), + KEY(gcol_int_key, gcol_datetime_key), + UNIQUE KEY(gcol_date_key,gcol_time_key,gcol_datetime_key), + UNIQUE KEY (gcol_varchar_key, col_varchar_nokey), + UNIQUE KEY (gcol_int_key, gcol_varchar_key, gcol_date_key, gcol_time_key, gcol_datetime_key) +) ENGINE=INNODB; - col_date_nokey DATE /*! NULL */, - col_date_key DATE GENERATED ALWAYS AS -(DATE_ADD(col_date_nokey,interval 30 day)) VIRTUAL not null, - - col_datetime_nokey DATETIME /*! NULL */, - col_time_nokey TIME /*! NULL */, - - col_datetime_key DATETIME GENERATED ALWAYS AS -(ADDTIME(col_datetime_nokey, col_time_nokey)) VIRTUAL not null, - col_time_key TIME GENERATED ALWAYS AS -(ADDTIME(col_datetime_nokey, col_time_nokey)) VIRTUAL not null, - - col_varchar_nokey VARCHAR(1) /*! NULL */, - col_varchar_key VARCHAR(2) GENERATED ALWAYS AS -(CONCAT(col_varchar_nokey, col_varchar_nokey)) VIRTUAL not null, - - PRIMARY KEY (pk), - UNIQUE KEY (col_int_key), - UNIQUE KEY (col_varchar_key), - UNIQUE KEY (col_date_key), - KEY (col_time_key), - KEY (col_datetime_key), - UNIQUE KEY (col_int_key, col_varchar_key), - KEY (col_int_key, col_int_nokey), - KEY(col_int_key,col_date_key), - KEY(col_int_key, col_time_key), - KEY(col_int_key, col_datetime_key), - UNIQUE -KEY(col_date_key,col_time_key,col_datetime_key), - UNIQUE KEY (col_varchar_key, col_varchar_nokey), - UNIQUE KEY (col_int_key, col_varchar_key, -col_date_key, col_time_key, col_datetime_key) - ) ENGINE=INNODB; - -INSERT /*! IGNORE */ INTO c ( - col_int_nokey, - col_date_nokey, - col_time_nokey, - col_datetime_nokey, - col_varchar_nokey - ) VALUES (7, '2004-04-09', '14:03:03.042673', -'2001-11-28 00:50:27.051028', 'c'),(1, '2006-05-13', '01:46:09.016386', -'2007-10-09 19:53:04.008332', NULL); +INSERT IGNORE INTO c ( col_int_nokey, col_date_nokey, col_time_nokey, col_datetime_nokey, col_varchar_nokey) +VALUES (7, '2004-04-09', '14:03:03.042673', '2001-11-28 00:50:27.051028', 'c'), + (1, '2006-05-13', '01:46:09.016386', '2007-10-09 19:53:04.008332', NULL); CREATE TABLE bb ( - pk INTEGER AUTO_INCREMENT, - col_int_nokey INTEGER /*! NULL */, - col_int_key INTEGER GENERATED ALWAYS AS -(col_int_nokey + col_int_nokey) VIRTUAL not null, + pk INTEGER AUTO_INCREMENT, + col_int_nokey INTEGER, + gcol_int_key INTEGER GENERATED ALWAYS AS (col_int_nokey + col_int_nokey) VIRTUAL, + col_date_nokey DATE, + gcol_date_key DATE GENERATED ALWAYS AS (DATE_ADD(col_date_nokey,interval 30 day)) VIRTUAL, + col_datetime_nokey DATETIME, + col_time_nokey TIME, + gcol_datetime_key DATETIME GENERATED ALWAYS AS (ADDTIME(col_datetime_nokey, col_time_nokey)) VIRTUAL, + gcol_time_key TIME GENERATED ALWAYS AS (ADDTIME(col_datetime_nokey, col_time_nokey)) VIRTUAL, + col_varchar_nokey VARCHAR(1), + gcol_varchar_key VARCHAR(2) GENERATED ALWAYS AS (CONCAT(col_varchar_nokey, col_varchar_nokey)) VIRTUAL, + PRIMARY KEY (pk), + UNIQUE KEY (gcol_int_key), + UNIQUE KEY (gcol_varchar_key), + UNIQUE KEY (gcol_date_key), + KEY (gcol_time_key), + KEY (gcol_datetime_key), + UNIQUE KEY (gcol_int_key, gcol_varchar_key), + KEY (gcol_int_key, col_int_nokey), + KEY(gcol_int_key,gcol_date_key), + KEY(gcol_int_key, gcol_time_key), + KEY(gcol_int_key, gcol_datetime_key), + UNIQUE KEY(gcol_date_key,gcol_time_key,gcol_datetime_key), + UNIQUE KEY (gcol_varchar_key, col_varchar_nokey), + UNIQUE KEY (gcol_int_key, gcol_varchar_key, gcol_date_key, gcol_time_key, gcol_datetime_key) +) AUTO_INCREMENT=10 ENGINE=INNODB; - col_date_nokey DATE /*! NULL */, - col_date_key DATE GENERATED ALWAYS AS -(DATE_ADD(col_date_nokey,interval 30 day)) VIRTUAL not null, - - col_datetime_nokey DATETIME /*! NULL */, - col_time_nokey TIME /*! NULL */, - - col_datetime_key DATETIME GENERATED ALWAYS AS -(ADDTIME(col_datetime_nokey, col_time_nokey)) VIRTUAL not null, - col_time_key TIME GENERATED ALWAYS AS -(ADDTIME(col_datetime_nokey, col_time_nokey)) VIRTUAL not null, - - col_varchar_nokey VARCHAR(1) /*! NULL */, - col_varchar_key VARCHAR(2) GENERATED ALWAYS AS -(CONCAT(col_varchar_nokey, col_varchar_nokey)) VIRTUAL not null, - - PRIMARY KEY (pk), - UNIQUE KEY (col_int_key), - UNIQUE KEY (col_varchar_key), - UNIQUE KEY (col_date_key), - KEY (col_time_key), - KEY (col_datetime_key), - UNIQUE KEY (col_int_key, col_varchar_key), - KEY (col_int_key, col_int_nokey), - KEY(col_int_key,col_date_key), - KEY(col_int_key, col_time_key), - KEY(col_int_key, col_datetime_key), - UNIQUE -KEY(col_date_key,col_time_key,col_datetime_key), - UNIQUE KEY (col_varchar_key, col_varchar_nokey), - UNIQUE KEY (col_int_key, col_varchar_key, -col_date_key, col_time_key, col_datetime_key) - ) AUTO_INCREMENT=10 ENGINE=INNODB; - -INSERT /*! IGNORE */ INTO bb ( - col_int_nokey, - col_date_nokey, - col_time_nokey, - col_datetime_nokey, - col_varchar_nokey - ) VALUES (0, '2003-08-04', '01:48:05.048577', -'2006-11-03 00:00:00', 'p'),(2, '2007-11-06', '00:00:00', '2009-11-26 19:28:11.005115', 'n'); +INSERT IGNORE INTO bb ( col_int_nokey, col_date_nokey, col_time_nokey, col_datetime_nokey, col_varchar_nokey) + VALUES (0, '2003-08-04', '01:48:05.048577', '2006-11-03 00:00:00', 'p'), + (2, '2007-11-06', '00:00:00', '2009-11-26 19:28:11.005115', 'n'); CREATE TABLE cc ( - pk INTEGER AUTO_INCREMENT, - col_int_nokey INTEGER /*! NULL */, - col_int_key INTEGER GENERATED ALWAYS AS -(col_int_nokey + col_int_nokey) VIRTUAL not null, + pk INTEGER AUTO_INCREMENT, + col_int_nokey INTEGER, + gcol_int_key INTEGER GENERATED ALWAYS AS (col_int_nokey + col_int_nokey) VIRTUAL, + col_date_nokey DATE, + gcol_date_key DATE GENERATED ALWAYS AS (DATE_ADD(col_date_nokey,interval 30 day)) VIRTUAL, + col_datetime_nokey DATETIME, + col_time_nokey TIME, + gcol_datetime_key DATETIME GENERATED ALWAYS AS (ADDTIME(col_datetime_nokey, col_time_nokey)) VIRTUAL, + gcol_time_key TIME GENERATED ALWAYS AS (ADDTIME(col_datetime_nokey, col_time_nokey)) VIRTUAL, + col_varchar_nokey VARCHAR(1), + gcol_varchar_key VARCHAR(2) GENERATED ALWAYS AS (CONCAT(col_varchar_nokey, col_varchar_nokey)) VIRTUAL, + PRIMARY KEY (pk), + UNIQUE KEY (gcol_int_key), + UNIQUE KEY (gcol_varchar_key), + UNIQUE KEY (gcol_date_key), + KEY (gcol_time_key), + KEY (gcol_datetime_key), + UNIQUE KEY (gcol_int_key, gcol_varchar_key), + KEY (gcol_int_key, col_int_nokey), + KEY(gcol_int_key,gcol_date_key), + KEY(gcol_int_key, gcol_time_key), + KEY(gcol_int_key, gcol_datetime_key), + UNIQUE KEY(gcol_date_key,gcol_time_key,gcol_datetime_key), + UNIQUE KEY (gcol_varchar_key, col_varchar_nokey), + UNIQUE KEY (gcol_int_key, gcol_varchar_key, gcol_date_key, gcol_time_key, gcol_datetime_key) +) AUTO_INCREMENT=10 ENGINE=INNODB; - col_date_nokey DATE /*! NULL */, - col_date_key DATE GENERATED ALWAYS AS -(DATE_ADD(col_date_nokey,interval 30 day)) VIRTUAL not null, - - col_datetime_nokey DATETIME /*! NULL */, - col_time_nokey TIME /*! NULL */, - - col_datetime_key DATETIME GENERATED ALWAYS AS -(ADDTIME(col_datetime_nokey, col_time_nokey)) VIRTUAL not null, - col_time_key TIME GENERATED ALWAYS AS -(ADDTIME(col_datetime_nokey, col_time_nokey)) VIRTUAL not null, - - col_varchar_nokey VARCHAR(1) /*! NULL */, - col_varchar_key VARCHAR(2) GENERATED ALWAYS AS -(CONCAT(col_varchar_nokey, col_varchar_nokey)) VIRTUAL not null, - - PRIMARY KEY (pk), - UNIQUE KEY (col_int_key), - UNIQUE KEY (col_varchar_key), - UNIQUE KEY (col_date_key), - KEY (col_time_key), - KEY (col_datetime_key), - UNIQUE KEY (col_int_key, col_varchar_key), - KEY (col_int_key, col_int_nokey), - KEY(col_int_key,col_date_key), - KEY(col_int_key, col_time_key), - KEY(col_int_key, col_datetime_key), - UNIQUE -KEY(col_date_key,col_time_key,col_datetime_key), - UNIQUE KEY (col_varchar_key, col_varchar_nokey), - UNIQUE KEY (col_int_key, col_varchar_key, -col_date_key, col_time_key, col_datetime_key) - ) AUTO_INCREMENT=10 ENGINE=INNODB; - -INSERT /*! IGNORE */ INTO cc ( - col_int_nokey, - col_date_nokey, - col_time_nokey, - col_datetime_nokey, - col_varchar_nokey - ) VALUES (172, '2009-04-23', '00:00:00', '2000-12-07 10:17:40.013275', 'h'),(NULL, '2002-10-06', '00:50:49.017545', NULL, 'm'); +INSERT IGNORE INTO cc (col_int_nokey, col_date_nokey, col_time_nokey, col_datetime_nokey, col_varchar_nokey) + VALUES (172, '2009-04-23', '00:00:00', '2000-12-07 10:17:40.013275', 'h'), + (NULL, '2002-10-06', '00:50:49.017545', NULL, 'm'); let $query= SELECT -gp1 . col_datetime_key AS g1 -FROM cc AS gp1 LEFT JOIN c AS gp2 ON ( gp2 . col_datetime_key <> gp1 . +gp1 . gcol_datetime_key AS g1 +FROM cc AS gp1 LEFT JOIN c AS gp2 ON ( gp2 . gcol_datetime_key <> gp1 . col_time_nokey ) WHERE gp1 . col_varchar_nokey IN ( SELECT -DISTINCT p1 . col_varchar_key AS p1 +DISTINCT p1 . gcol_varchar_key AS p1 FROM bb AS p1 LEFT JOIN bb AS p2 -ON ( p1 . col_int_key = p2 . pk ) +ON ( p1 . gcol_int_key = p2 . pk ) ) AND gp1 . col_varchar_nokey = 'b' HAVING g1 > 6; @@ -251,15 +200,15 @@ DROP TABLE bb, c, cc; CREATE TABLE c ( pk INTEGER AUTO_INCREMENT, col_int_nokey INTEGER NOT NULL, - col_int_key INTEGER GENERATED ALWAYS AS (col_int_nokey + col_int_nokey) VIRTUAL not null, + col_int_key INTEGER GENERATED ALWAYS AS (col_int_nokey + col_int_nokey) VIRTUAL, col_date_nokey DATE NOT NULL, - col_date_key DATE GENERATED ALWAYS AS (DATE_ADD(col_date_nokey,interval 30 day)) VIRTUAL not null, + col_date_key DATE GENERATED ALWAYS AS (DATE_ADD(col_date_nokey,interval 30 day)) VIRTUAL, col_datetime_nokey DATETIME NOT NULL, col_time_nokey TIME NOT NULL, - col_datetime_key DATETIME GENERATED ALWAYS AS (ADDTIME(col_datetime_nokey, col_time_nokey)) VIRTUAL not null, - col_time_key TIME GENERATED ALWAYS AS (ADDTIME(col_datetime_nokey, col_time_nokey)) VIRTUAL not null, + col_datetime_key DATETIME GENERATED ALWAYS AS (ADDTIME(col_datetime_nokey, col_time_nokey)) VIRTUAL, + col_time_key TIME GENERATED ALWAYS AS (ADDTIME(col_datetime_nokey, col_time_nokey)) VIRTUAL, col_varchar_nokey VARCHAR(1) NOT NULL, - col_varchar_key VARCHAR(2) GENERATED ALWAYS AS (CONCAT(col_varchar_nokey, col_varchar_nokey)) VIRTUAL not null, + col_varchar_key VARCHAR(2) GENERATED ALWAYS AS (CONCAT(col_varchar_nokey, col_varchar_nokey)) VIRTUAL, PRIMARY KEY (pk,col_int_nokey), UNIQUE KEY (col_int_key), UNIQUE KEY (col_varchar_key), @@ -303,15 +252,15 @@ DROP TABLE c; CREATE TABLE t1 ( pk INTEGER AUTO_INCREMENT, - col_int_nokey INTEGER /*! NULL */, + col_int_nokey INTEGER, col_int_key INTEGER GENERATED ALWAYS AS (col_int_nokey + col_int_nokey) VIRTUAL, - col_blob_nokey BLOB /*! NULL */, + col_blob_nokey BLOB, col_blob_key BLOB GENERATED ALWAYS AS (REPEAT(col_blob_nokey,15)) VIRTUAL, - col_longblob_nokey LONGBLOB /*! NULL */, - col_longtext_nokey LONGTEXT /*! NULL */, + col_longblob_nokey LONGBLOB, + col_longtext_nokey LONGTEXT, col_longblob_key LONGBLOB GENERATED ALWAYS AS (REPEAT(col_longblob_nokey, 20)) VIRTUAL, col_longtext_key LONGTEXT GENERATED ALWAYS AS (REPEAT(col_longblob_nokey, 18)) VIRTUAL, - col_text_nokey TEXT /*! NULL */, + col_text_nokey TEXT, col_text_key TEXT GENERATED ALWAYS AS (REPEAT(col_text_nokey, 30)) VIRTUAL, PRIMARY KEY (pk), KEY (col_int_key), @@ -339,7 +288,6 @@ VALUES (5, 'bjjv', 'bjjv', 'bjjv', 'bjjv'), (0, 'jjvvkymalu', 'jjvvkymalu', 'jjvvkymalu', 'jjvvkymalu'), (3, 'j', 'j', 'j', 'j'); - SELECT alias1.pk AS field1 FROM t1 AS alias1 LEFT OUTER JOIN t1 AS alias2 ON alias1.col_int_key = alias2.col_int_key @@ -357,7 +305,7 @@ DROP TABLE t1; CREATE TABLE t(a int); ALTER TABLE t ADD COLUMN b int GENERATED ALWAYS AS ( date_sub(a,interval a month)) VIRTUAL; ---error 1111 +--error ER_VIRTUAL_COLUMN_FUNCTION_IS_NOT_ALLOWED ALTER TABLE t ADD COLUMN c int GENERATED ALWAYS AS (sum(a)); DROP TABLE t; @@ -487,16 +435,6 @@ SELECT DISTINCT t1.c13 FROM C AS t1, view_C AS t2; DROP TABLE C; DROP VIEW view_C; ---echo # ---echo # Bug #21808680: JSON + GENERATED COLUMN CORRUPTS TABLE CACHE ---echo # MEMORY, CRASHES ---echo # -CREATE TABLE t (a INT, b JSON, c TEXT GENERATED ALWAYS AS (REPEAT(a=b, 2))); -INSERT INTO t (a, b) VALUES (1, '2'), (3, '3'); -# The next statement used to crash. -SELECT * FROM t; -DROP TABLE t; - --echo # --echo # Bug#21810529: CRASH IN ITEM_FUNC::WALK WHEN CODE JUMPS TO GARBAGE --echo # LOCATION @@ -517,10 +455,10 @@ DROP TABLE t; --echo # CREATE TABLE t(b BLOB); ---error ER_GENERATED_COLUMN_FUNCTION_IS_NOT_ALLOWED +--error ER_OPERAND_COLUMNS ALTER TABLE t ADD COLUMN c INT GENERATED ALWAYS AS ((1,1)) VIRTUAL; DROP TABLE t; ---error ER_GENERATED_COLUMN_FUNCTION_IS_NOT_ALLOWED +--error ER_OPERAND_COLUMNS CREATE TABLE t(b BLOB, c INT GENERATED ALWAYS AS ((1,1)) VIRTUAL); --echo # @@ -552,12 +490,11 @@ DROP TABLE t1; SET @save_old_sql_mode= @@sql_mode; SET sql_mode=""; ---error ER_TRUNCATED_WRONG_VALUE CREATE TABLE t (a INTEGER AS (SUBSTR('','a',1))) engine=innodb; +DROP TABLE t; CREATE TABLE t (a INTEGER) engine=innodb; ---error ER_TRUNCATED_WRONG_VALUE ALTER TABLE t ADD b INTEGER AS (SUBSTR('','a',1)); DROP TABLE t; diff --git a/mysql-test/suite/gcol/t/gcol_column_def_options_innodb.test b/mysql-test/suite/gcol/t/gcol_column_def_options_innodb.test index 285974d1ccc..68931cd0706 100644 --- a/mysql-test/suite/gcol/t/gcol_column_def_options_innodb.test +++ b/mysql-test/suite/gcol/t/gcol_column_def_options_innodb.test @@ -36,7 +36,7 @@ eval SET @@session.default_storage_engine = 'InnoDB'; #------------------------------------------------------------------------------# # Execute the tests to be applied to all storage engines -let $support_virtual_index= 0; +let $support_virtual_index= 1; --source suite/gcol/inc/gcol_column_def_options.inc #------------------------------------------------------------------------------# diff --git a/mysql-test/suite/gcol/t/gcol_rollback.test b/mysql-test/suite/gcol/t/gcol_rollback.test index 5109012b2e2..4cd1fcc46ac 100644 --- a/mysql-test/suite/gcol/t/gcol_rollback.test +++ b/mysql-test/suite/gcol/t/gcol_rollback.test @@ -26,7 +26,8 @@ SELECT * FROM t; BEGIN; INSERT INTO t (a) VALUES (10); ---source include/kill_and_restart_mysqld.inc +--let $shutdown_timeout= 0 +--source include/restart_mysqld.inc SELECT * FROM t; DROP TABLE t; @@ -103,6 +104,7 @@ connection default; SELECT * FROM t; DROP TABLE t; +SET DEBUG_SYNC = 'RESET'; # Wait till all disconnects are completed --source include/wait_until_count_sessions.inc diff --git a/mysql-test/suite/gcol/t/innodb_partition.test b/mysql-test/suite/gcol/t/innodb_partition.test new file mode 100644 index 00000000000..268a8c7c083 --- /dev/null +++ b/mysql-test/suite/gcol/t/innodb_partition.test @@ -0,0 +1,30 @@ +--source include/have_innodb.inc +--source include/have_partition.inc + +--echo # +--echo # Bug#22444530 - GCOLS + PARTITIONED TABLE, CRASH IN +--echo # +set sql_mode=''; +create table t ( + a int not null, + b int generated always as (1) virtual, + c int generated always as (1) virtual, + key (c) +) engine=innodb partition by key (a) partitions 2; +insert into t(a) values(1); +select b from t group by c; + +drop table t; + +# Make column b a BLOB +create table t ( + a int not null, + b blob generated always as ("a") virtual, + c int generated always as (1) virtual, + key (c) +) engine=innodb partition by key (a) partitions 2; +insert into t(a) values(1); +select b from t group by c; + +drop table t; + diff --git a/mysql-test/suite/gcol/t/innodb_prefix_index_check.test b/mysql-test/suite/gcol/t/innodb_prefix_index_check.test new file mode 100644 index 00000000000..4923ead91ac --- /dev/null +++ b/mysql-test/suite/gcol/t/innodb_prefix_index_check.test @@ -0,0 +1,22 @@ +--source include/have_innodb.inc + +--echo #Bug #22445211 GCOLS: SIMPLE DML, FAILING ASSERTION: +--echo #!CURSOR->INDEX->IS_COMMITTED() + +--echo #Create and alter table examples for virtual column for full +--echo #column index followed by prefix index. + +CREATE TABLE t1( +f1 INT DEFAULT NULL, +f2 CHAR(2) GENERATED ALWAYS AS ('11') VIRTUAL, +f3 INT, +UNIQUE KEY(f1), +UNIQUE KEY(f3,f1), +KEY(f2,f1), +key(f1,f2(1)) +)ENGINE=INNODB; + +REPLACE INTO t1(f3) VALUES (1),(1); + +DROP TABLE t1; + diff --git a/mysql-test/suite/gcol/t/innodb_virtual_basic.test b/mysql-test/suite/gcol/t/innodb_virtual_basic.test new file mode 100644 index 00000000000..342d9e42976 --- /dev/null +++ b/mysql-test/suite/gcol/t/innodb_virtual_basic.test @@ -0,0 +1,1474 @@ +--source include/have_innodb.inc +--source include/have_partition.inc + +call mtr.add_suppression("\\[Warning\\] InnoDB: Compute virtual"); + +set default_storage_engine=innodb; + +CREATE TABLE t (a INT, b INT GENERATED ALWAYS AS (a), c CHAR(10), d CHAR(20), e CHAR(10) GENERATED ALWAYS AS (c), g INT); +INSERT INTO t VALUES(10, DEFAULT, "aa", "bb", DEFAULT, 20); +INSERT INTO t VALUES(11, DEFAULT, "jj", "kk", DEFAULT, 21); + +CREATE INDEX idx ON t(e) algorithm=inplace; +INSERT INTO t VALUES(12, DEFAULT, 'mm', "nn", DEFAULT, 22); + +SELECT e FROM t; + +DROP TABLE t; + +CREATE TABLE t (a INT, b INT, c INT GENERATED ALWAYS AS(a+b), h VARCHAR(10)); + +INSERT INTO t VALUES (11, 3, DEFAULT, 'mm'); +INSERT INTO t VALUES (18, 1, DEFAULT, 'mm'); +INSERT INTO t VALUES (28, 1, DEFAULT, 'mm'); +INSERT INTO t VALUES (null, null, DEFAULT, 'mm'); + +CREATE INDEX idx ON t(c); +SELECT c FROM t; + +UPDATE t SET a = 10 WHERE a = 11; +SELECT c FROM t; + +SELECT * FROM t; + +DELETE FROM t WHERE a = 18; + +SELECT c FROM t; + +START TRANSACTION; + +INSERT INTO t VALUES (128, 22, DEFAULT, "xx"); +INSERT INTO t VALUES (1290, 212, DEFAULT, "xmx"); +ROLLBACK; + +SELECT c FROM t; +SELECT * FROM t; + +DROP TABLE t; + +CREATE TABLE t (a INT, b INT, c INT GENERATED ALWAYS AS(a+b), h VARCHAR(10), j INT, m INT GENERATED ALWAYS AS(b + j), n VARCHAR(10), p VARCHAR(20) GENERATED ALWAYS AS(CONCAT(n, h)), INDEX idx1(c), INDEX idx2 (m), INDEX idx3(p)); + +INSERT INTO t VALUES(11, 22, DEFAULT, "AAA", 8, DEFAULT, "XXX", DEFAULT); +INSERT INTO t VALUES(1, 2, DEFAULT, "uuu", 9, DEFAULT, "uu", DEFAULT); +INSERT INTO t VALUES(3, 4, DEFAULT, "uooo", 1, DEFAULT, "umm", DEFAULT); + +SELECT c FROM t; +SELECT m FROM t; +SELECT p FROM t; +SELECT * FROM t; + +update t set a = 13 where a =11; + +delete from t where a =13; + +DROP INDEX idx1 ON t; +DROP INDEX idx2 ON t; +DROP TABLE t; + +/* Test large BLOB data */ +CREATE TABLE `t` ( + `a` BLOB, + `b` BLOB, + `c` BLOB GENERATED ALWAYS AS (CONCAT(a,b)) VIRTUAL, + `h` VARCHAR(10) DEFAULT NULL +) ENGINE=InnoDB; + +INSERT INTO t VALUES (REPEAT('g', 16000), REPEAT('x', 16000), DEFAULT, "kk"); + +CREATE INDEX idx ON t(c(100)); + +SELECT length(c) FROM t; + +START TRANSACTION; + +INSERT INTO t VALUES (REPEAT('a', 16000), REPEAT('b', 16000), DEFAULT, 'mm'); + +ROLLBACK; + +INSERT INTO t VALUES (REPEAT('a', 16000), REPEAT('b', 16000), DEFAULT, 'mm'); + +START TRANSACTION; + +UPDATE t SET a = REPEAT('m', 16000) WHERE a like "aaa%"; + +ROLLBACK; + +# This SELECT did not give correct answer, even though InnoDB return +# all qualified rows +SELECT COUNT(*) FROM t WHERE c like "aaa%"; + +DROP TABLE t; + +CREATE TABLE t (a INT, b INT, c INT GENERATED ALWAYS AS(a+b), h VARCHAR(10)); + +INSERT INTO t VALUES (11, 3, DEFAULT, 'mm'); +INSERT INTO t VALUES (18, 1, DEFAULT, 'mm'); +INSERT INTO t VALUES (28, 1, DEFAULT, 'mm'); +CREATE INDEX idx ON t(c); + +START TRANSACTION; + +UPDATE t SET a = 100 WHERE a = 11; + +UPDATE t SET a =22 WHERE a = 18; + +UPDATE t SET a = 33 WHERE a = 22; + +SELECT c FROM t; + +ROLLBACK; + +SELECT c FROM t; +DROP TABLE t; + +CREATE TABLE t (a INT, b INT, c INT GENERATED ALWAYS AS(a+b), h VARCHAR(10)); + +INSERT INTO t VALUES (11, 3, DEFAULT, 'mm'); +INSERT INTO t VALUES (18, 1, DEFAULT, 'mm'); +INSERT INTO t VALUES (28, 1, DEFAULT, 'mm'); +CREATE INDEX idx ON t(c); +SELECT c FROM t; + +connect(con1,localhost,root,,test); +START TRANSACTION; +SELECT c FROM t; + +connection default; +UPDATE t SET a = 19 WHERE a = 11; + +# this should report the same value as previous one (14, 19, 29). +connection con1; +SELECT c FROM t; + +ROLLBACK; + +SELECT c FROM t; + +connection default; +disconnect con1; + +DROP TABLE t; + +# CREATE a more complex TABLE +CREATE TABLE t (a INT, b INT, c INT GENERATED ALWAYS AS(a+b), h VARCHAR(10), j INT, m INT GENERATED ALWAYS AS(b + x), n VARCHAR(10), p VARCHAR(20) GENERATED ALWAYS AS(CONCAT(n, y)), x INT, y CHAR(20), z INT, INDEX idx1(c), INDEX idx2 (m), INDEX idx3(p)); + +INSERT INTO t VALUES(1, 2, DEFAULT, "hhh", 3, DEFAULT, "nnn", DEFAULT, 4, "yyy", 5); + +INSERT INTO t VALUES(2, 3, DEFAULT, "hhha", 4, DEFAULT, "nnna", DEFAULT, 5, "yyya", 6); + +INSERT INTO t VALUES(12, 13, DEFAULT, "hhhb", 14, DEFAULT, "nnnb", DEFAULT, 15, "yyyb", 16); + +# CREATE an INDEX ON multiple virtual COLUMN +CREATE INDEX idx6 ON t(p, c); + +SELECT p, c FROM t; + +START TRANSACTION; +INSERT INTO t VALUES(32, 33, DEFAULT, "hhhb", 34, DEFAULT, "nnnb", DEFAULT, 35, "yyyb", 36); +ROLLBACK; + +UPDATE t SET a = 100 WHERE a = 1; + +START TRANSACTION; +UPDATE t SET a = 1 WHERE a = 100; +ROLLBACK; + +DROP TABLE t; + +CREATE TABLE t1(a INT); +ALTER TABLE t1 add COLUMN (b INT generated always as (a+1) virtual, c INT as(5) virtual); +ALTER TABLE t1 add COLUMN (d INT generated always as (a+1) virtual, e INT as(5) virtual); + +SELECT pos, base_pos FROM informatiON_schema.innodb_sys_virtual; + +#--error ER_UNSUPPORTED_ACTION_ON_VIRTUAL_COLUMN +ALTER TABLE t1 add COLUMN (f INT generated always as (a+1) virtual, g INT as(5) virtual), DROP COLUMN e; + +SELECT pos, base_pos FROM informatiON_schema.innodb_sys_virtual; + +DROP TABLE t1; + +CREATE TABLE t1(a INT); +INSERT INTO t1 VALUES(1); + +ALTER TABLE t1 add COLUMN (f INT generated always as (a+1) virtual, g INT ); + +# Inplace ADD/DROP virtual COLUMNs can only go with their own for +# inplace algorithm, not to combine with other operations, except create index +ALTER TABLE t1 add COLUMN (h INT generated always as (a+1) virtual), add INDEX idx (h), algorithm=inplace; + +--enable_info +ALTER TABLE t1 add COLUMN (h1 INT generated always as (a+1) virtual), add INDEX idx1 (h1); +--disable_info + +ALTER TABLE t1 DROP COLUMN h1, DROP INDEX idx; + +DROP TABLE t1; + +# Virtual COLUMN cannot be INDEXed +CREATE TABLE t1(a INT); +CREATE INDEX idx ON t1(a); +CREATE TABLE t3(a INT, b INT , INDEX(b), CONSTRAINT x FOREIGN KEY(b) REFERENCES t1(a)); +--error ER_CANT_CREATE_TABLE +CREATE TABLE t2(a INT, b INT generated always as (a+1) virtual, INDEX(b), CONSTRAINT x FOREIGN KEY(b) REFERENCES t1(a)); +CREATE TABLE t2(a INT, b INT generated always as (a+1) virtual, INDEX(b)); +DROP TABLE t3; +DROP TABLE t2; +DROP TABLE t1; + +CREATE TABLE t1(a INT); +ALTER TABLE t1 add COLUMN (b INT generated always as (a+1) virtual, c INT as(5) virtual); + +ALTER TABLE t1 change b x INT generated always as (a+1) virtual; + +SELECT pos, base_pos FROM informatiON_schema.innodb_sys_virtual; + +DROP TABLE t1; + +# We do not support Fulltext or Spatial INDEX ON Virtual Columns +--error ER_UNSUPPORTED_ACTION_ON_VIRTUAL_COLUMN +CREATE TABLE t (a TEXT, b TEXT GENERATED ALWAYS AS (a), fulltext INDEX idx (b)); +CREATE TABLE t (a TEXT, b TEXT GENERATED ALWAYS AS (a)); +--error ER_UNSUPPORTED_ACTION_ON_VIRTUAL_COLUMN +ALTER TABLE t ADD FULLTEXT INDEX (b); +DROP TABLE t; + +--error ER_SPATIAL_CANT_HAVE_NULL +CREATE TABLE t (a geometry not null, b geometry GENERATED ALWAYS AS (a), spatial INDEX idx (b)); +CREATE TABLE t (a geometry not null, b geometry GENERATED ALWAYS AS (a)); +--error ER_SPATIAL_CANT_HAVE_NULL +ALTER TABLE t ADD SPATIAL INDEX (b); +DROP TABLE t; + +#test DEFAULT value +CREATE TABLE t (a INT DEFAULT 1, b INT DEFAULT 2, c INT GENERATED ALWAYS AS(a+b), h VARCHAR(10)); +CREATE INDEX idx ON t(c); +INSERT INTO t(h)VALUES ('mm'); +SELECT c FROM t; + +CREATE unique INDEX idx1 ON t(c); + +--error ER_DUP_ENTRY +INSERT INTO t(h)VALUES ('mm'); + +DROP TABLE t; + +CREATE TABLE `t1` ( `a` INT(11) DEFAULT NULL, `b` INT(11) DEFAULT NULL, `c` INT(11) GENERATED ALWAYS AS (a+b) VIRTUAL, `x` INT(11) NOT NULL, `h` VARCHAR(10) DEFAULT NULL, PRIMARY KEY (`x`), KEY `idx` (`c`) ) ENGINE=InnoDB DEFAULT CHARSET=latin1; + +INSERT INTO t1 VALUES (1, 2, DEFAULT, 3, 'mm'); +INSERT INTO t1 VALUES (11, 22, DEFAULT, 23, 'mm'); + +connect(con1,localhost,root,,test); +UPDATE t1 SET x = 4 WHERE x =3; +DROP TABLE t1; + +CREATE TABLE `t1` ( `a` INT(11) DEFAULT NULL, `b` INT(11) DEFAULT NULL, `c` INT(11) GENERATED ALWAYS AS (a+b) VIRTUAL, `x` INT(11) NOT NULL, `h` VARCHAR(10) DEFAULT NULL, KEY `idx` (`c`) ) ENGINE=InnoDB DEFAULT CHARSET=latin1; + +INSERT INTO t1 VALUES (1, 2, DEFAULT, 3, 'mm'); +INSERT INTO t1 VALUES (11, 22, DEFAULT, 23, 'mm'); + +START TRANSACTION; +SELECT * FROM t1; + +connection con1; +START TRANSACTION; +UPDATE t1 SET x = 15 WHERE x = 3; + +UPDATE t1 SET b = 10 WHERE b=2; +ROLLBACK; + +connection default; +SELECT c FROM t1; + +disconnect con1; + +DROP TABLE t1; + +CREATE TABLE `t` ( + `a` INT(11) DEFAULT NULL, + `b` INT(11) DEFAULT NULL, + `c` INT(11) GENERATED ALWAYS AS (a+b) VIRTUAL, + `d` INT(11) GENERATED ALWAYS AS (a) VIRTUAL, + `h` INT(11) NOT NULL, + PRIMARY KEY (`h`), + KEY `idx` (`c`) +) ENGINE=InnoDB; + +INSERT INTO t VALUES (11, 3, DEFAULT, DEFAULT, 1); +INSERT INTO t VALUES (18, 1, DEFAULT, DEFAULT, 2); +INSERT INTO t VALUES (28, 1, DEFAULT, DEFAULT, 3); +INSERT INTO t VALUES (null, null, DEFAULT, DEFAULT, 4); + +delimiter |; +CREATE PROCEDURE UPDATE_t() +begin + DECLARE i INT DEFAULT 1; + WHILE (i <= 2000) DO + UPDATE t SET a = 100 + i WHERE h = 1; + SET i = i + 1; + END WHILE; +END| + +CREATE PROCEDURE DELETE_insert_t() +begin + DECLARE i INT DEFAULT 1; + WHILE (i <= 2000) DO + UPDATE t SET a = 100 + i WHERE h = 1; + SET i = i + 1; + END WHILE; +END| +delimiter ;| + +CALL UPDATE_t(); +SELECT c FROM t; + +CALL DELETE_insert_t(); +SELECT c FROM t; + +DROP INDEX idx ON t; +CALL UPDATE_t(); +SELECT c FROM t; + +DROP PROCEDURE DELETE_insert_t; +DROP PROCEDURE UPDATE_t; + +DROP TABLE t; + +--echo # Bug#20767937: WL8149:ASSERTION FAILED IN ROW_UPD_SEC_INDEX_ENTRY +CREATE TABLE b ( +col_INT_nokey INTEGER NOT NULL, +col_INT_key INTEGER GENERATED ALWAYS AS (col_INT_nokey) VIRTUAL, +col_date_nokey DATE, +col_date_key DATE GENERATED ALWAYS AS (DATE_ADD(col_date_nokey, + INTerval 30 day)) VIRTUAL, + +col_datetime_nokey DATETIME NOT NULL, +col_time_nokey TIME NOT NULL, + +col_datetime_key DATETIME GENERATED ALWAYS AS (ADDTIME(col_datetime_nokey, + col_time_nokey)), +col_time_key TIME GENERATED ALWAYS AS (ADDTIME(col_datetime_nokey, + col_time_nokey)), + +col_VARCHAR_nokey VARCHAR(1) NOT NULL, +col_VARCHAR_key VARCHAR(2) GENERATED ALWAYS AS(CONCAT(col_VARCHAR_nokey, + col_VARCHAR_nokey)), + +KEY (col_INT_key), +KEY (col_VARCHAR_key), +KEY (col_date_key), +KEY (col_time_key), +KEY (col_datetime_key), +KEY (col_INT_key, col_VARCHAR_key), +KEY (col_INT_key, col_VARCHAR_key, col_date_key, +col_time_key, col_datetime_key) +); +INSERT INTO b ( + col_INT_nokey, + col_date_nokey, + col_time_nokey, + col_datetime_nokey, + col_VARCHAR_nokey +) VALUES +(0, NULL, '21:22:34.025509', '2002-02-13 17:30:06.013935', 'j'), +(8, '2004-09-18', '10:50:38.059966', '2008-09-27 +00:34:58.026613', 'v'); + +EXPLAIN SELECT col_INT_key FROM b; +SELECT col_INT_key FROM b; +SELECT col_INT_nokey, col_INT_key FROM b; +DELETE FROM b; + +DROP TABLE b; + +let $row_format=COMPACT; +--source inc/innodb_v_large_col.inc + +CREATE TABLE `t` ( + `a` BLOB, + `b` BLOB, + `c` BLOB GENERATED ALWAYS AS (CONCAT(a,b)) VIRTUAL, + `d` BLOB GENERATED ALWAYS AS (b) VIRTUAL, + `e` INT(11) GENERATED ALWAYS AS (10) VIRTUAL, + `h` INT(11) NOT NULL, + PRIMARY KEY (`h`) +) ENGINE=InnoDB; + +INSERT INTO t VALUES (REPEAT('g', 16000), REPEAT('x', 16000), DEFAULT, DEFAULT, DEFAULT, 1); +INSERT INTO t VALUES (REPEAT('a', 32000), REPEAT('b', 11000), DEFAULT, DEFAULT, DEFAULT, 2); +INSERT INTO t VALUES (REPEAT('m', 18000), REPEAT('n', 46000), DEFAULT, DEFAULT, DEFAULT, 3); + +CREATE INDEX idx ON t(c(100), d(20)); + +UPDATE t SET a = NULL WHERE h=1; + +UPDATE t SET a = REPEAT(CAST(1 AS CHAR), 2000) WHERE h = 1; + +UPDATE t SET a = REPEAT(CAST(1 AS CHAR), 1000) WHERE h = 1; + +delimiter |; + +CREATE PROCEDURE UPDATE_t() +begin + DECLARE i INT DEFAULT 1; + WHILE (i <= 200) DO + UPDATE t SET a = REPEAT(CAST(i AS CHAR), 2000) WHERE h = 1; + SET i = i + 1; + END WHILE; +END| + +CREATE PROCEDURE DELETE_insert_t() +begin + DECLARE i INT DEFAULT 1; + WHILE (i <= 200) DO + DELETE FROM t WHERE h = 1; + INSERT INTO t VALUES (REPEAT(CAST(i AS CHAR), 2000) , REPEAT('b', 2000), DEFAULT, DEFAULT, DEFAULT, 1); + SET i = i + 1; + END WHILE; +END| +delimiter ;| + +CALL UPDATE_t(); +CALL DELETE_insert_t(); + +UPDATE t SET a = NULL WHERE h=1; + +DROP PROCEDURE DELETE_insert_t; +DROP PROCEDURE UPDATE_t; +DROP TABLE t; + +CREATE TABLE `t` ( + `m1` INT(11) DEFAULT NULL, + `m2` INT(11) DEFAULT NULL, + `m3` INT(11) GENERATED ALWAYS AS (m1 + m2) VIRTUAL, + `m4` INT(11) DEFAULT NULL, + `m5` CHAR(10) DEFAULT NULL, + `m6` CHAR(12) GENERATED ALWAYS AS (m5) VIRTUAL, + `a` VARCHAR(10000) DEFAULT NULL, + `b` VARCHAR(3000) DEFAULT NULL, + `c` VARCHAR(14000) GENERATED ALWAYS AS (CONCAT(a,b)) VIRTUAL, + `d` VARCHAR(5000) GENERATED ALWAYS AS (b) VIRTUAL, + `e` INT(11) GENERATED ALWAYS AS (10) VIRTUAL, + `h` INT(11) NOT NULL, + PRIMARY KEY (`h`), + KEY `m3` (`m3`), + KEY `c` (`c`(100)), + KEY `e` (`e`,`d`(20)) +) ENGINE=InnoDB; + +INSERT INTO t VALUES (1, 2, DEFAULT, 3, "aaa", DEFAULT, REPEAT('g', 10000), REPEAT('x', 2800), DEFAULT, DEFAULT, DEFAULT, 1); + +INSERT INTO t VALUES (11, 21, DEFAULT, 31, "bbb", DEFAULT, REPEAT('a', 9000), REPEAT('b', 2000), DEFAULT, DEFAULT, DEFAULT, 2); + +INSERT INTO t VALUES (21, 31, DEFAULT, 41, "zzz", DEFAULT, REPEAT('m', 8000), REPEAT('n', 3000), DEFAULT, DEFAULT, DEFAULT, 3); + +ALTER TABLE t DROP COLUMN c; + +DELETE FROM t; + +DROP TABLE t; + +CREATE TABLE t (a INT, b INT, c INT GENERATED ALWAYS AS(a+b), h VARCHAR(10)); + +INSERT INTO t VALUES (11, 3, DEFAULT, 'mm'); +INSERT INTO t VALUES (18, 1, DEFAULT, 'mm'); +INSERT INTO t VALUES (28, 1, DEFAULT, 'mm'); +INSERT INTO t VALUES (null, null, DEFAULT, 'mm'); + +CREATE INDEX idx ON t(a, c); +SELECT a, c FROM t; + +START TRANSACTION; + +UPDATE t SET a = 13 where a = 11; + +ROLLBACK; +DELETE FROM t; + +DROP TABLE t; + +CREATE TABLE t (a INT, b INT, c INT GENERATED ALWAYS AS(a+b), h VARCHAR(10), m int); + +INSERT INTO t VALUES (11, 3, DEFAULT, "a", 1); +INSERT INTO t VALUES (18, 1, DEFAULT, "b", 2); +INSERT INTO t VALUES (28, 1, DEFAULT, "c", 3 ); +INSERT INTO t VALUES (null, null, DEFAULT, "d", 4); + +CREATE INDEX idx ON t(a, c, h); +SELECT a, c FROM t; + +START TRANSACTION; +UPDATE t SET m =10 WHERE m = 1; +UPDATE t SET h = "e" WHERE h="a"; +ROLLBACK; +SELECT a, c, h FROM t; + +DROP TABLE t; + +# bug#21065137 - WL8149:FAILING ASSERTION: NAME_OFS < FULL_LEN +CREATE TABLE `t1` ( + `col1` int(11) NOT NULL, + `col2` int(11) NOT NULL, + `col3` int(11) NOT NULL, + `col4` int(11) DEFAULT NULL, + `col5` int(11) GENERATED ALWAYS AS (col2 % col3) VIRTUAL, + `col7` int(11) GENERATED ALWAYS AS (col5 * col5) VIRTUAL, + `col8` int(11) GENERATED ALWAYS AS (col5 % col5) VIRTUAL, + `col9` text, + `extra` int(11) DEFAULT NULL, + UNIQUE KEY `uidx` (`col5`) +) ENGINE=InnoDB DEFAULT CHARSET=latin1; + +ALTER TABLE t1 CHANGE COLUMN extra col6 INT; + +SHOW CREATE TABLE t1; +DROP TABLE t1; + +# No spatial and FTS index on virtual columns +--error ER_SPATIAL_CANT_HAVE_NULL +CREATE TABLE t (a INT, b INT GENERATED ALWAYS AS (a), c point, d point GENERATED ALWAYS AS (c), spatial index idx (d)); + +--error ER_UNSUPPORTED_ACTION_ON_VIRTUAL_COLUMN +CREATE TABLE t (a INT, b INT GENERATED ALWAYS AS (a), c CHAR(10), d char(20) GENERATED ALWAYS AS (c), fulltext index idx (d)); + +CREATE TABLE t (a INT, b INT, c INT GENERATED ALWAYS AS(a+b), h VARCHAR(10), j INT, m INT GENERATED ALWAYS AS(b + j), n VARCHAR(10), p VARCHAR(20) GENERATED ALWAYS AS(CONCAT(n, h)), INDEX idx1(c), INDEX idx2 (m), INDEX idx3(p)); + +INSERT INTO t VALUES(11, 22, DEFAULT, "AAA", 8, DEFAULT, "XXX", DEFAULT); +INSERT INTO t VALUES(1, 2, DEFAULT, "uuu", 9, DEFAULT, "uu", DEFAULT); +INSERT INTO t VALUES(3, 4, DEFAULT, "uooo", 1, DEFAULT, "umm", DEFAULT); + +alter table t add x int, add xx int generated ALWAYS AS(x); + +DROP TABLE t; + +CREATE TABLE t (a INT, b INT, c INT GENERATED ALWAYS AS(a+b), h VARCHAR(10), j INT, m INT GENERATED ALWAYS AS(b + j), n VARCHAR(10), p VARCHAR(20) GENERATED ALWAYS AS(CONCAT(n, h)), INDEX idx1(c), INDEX idx2 (m), INDEX idx3(p)); + +INSERT INTO t VALUES(11, 22, DEFAULT, "AAA", 8, DEFAULT, "XXX", DEFAULT); +INSERT INTO t VALUES(1, 2, DEFAULT, "uuu", 9, DEFAULT, "uu", DEFAULT); +INSERT INTO t VALUES(3, 4, DEFAULT, "uooo", 1, DEFAULT, "umm", DEFAULT); + +ALTER TABLE t DROP COLUMN c, algorithm=inplace; +ALTER TABLE t DROP COLUMN p, ADD COLUMN s VARCHAR(20) GENERATED ALWAYS AS(CONCAT(n, h)), algorithm=inplace; + +# This should fail +#ALTER TABLE t ADD x INT, DROP COLUMN m, algorithm=inplace; +SELECT s FROM t; + +ALTER TABLE t ADD x VARCHAR(20) GENERATED ALWAYS AS(CONCAT(n, h)), ADD INDEX idx (x), algorithm=inplace; +DROP TABLE t; + +CREATE TABLE `t1` ( + `col1` int(11) DEFAULT NULL, + `col2` int(11) DEFAULT NULL, + `col3` int(11) DEFAULT NULL, + `col4` int(11) DEFAULT NULL, + `col5` int(11) GENERATED ALWAYS AS (col4 * col2) VIRTUAL, + `col6` int(11) GENERATED ALWAYS AS (col2 % col4) VIRTUAL, + `col7` int(11) GENERATED ALWAYS AS (col5 / col6) VIRTUAL, + `col8` int(11) GENERATED ALWAYS AS (col5 + col5) VIRTUAL, + `col9` text, + `extra` int(11) DEFAULT NULL +) ENGINE=InnoDB DEFAULT CHARSET=latin1; + +ALTER TABLE t1 DROP COLUMN col7; + +DROP TABLE t1; + +CREATE TABLE t1 ( + col1 INTEGER NOT NULL, + gv_col INTEGER GENERATED ALWAYS AS (col1) VIRTUAL, + txt1 TEXT, + FULLTEXT INDEX fi(txt1) +); + +select * from t1; + +DROP TABLE t1; + +CREATE TABLE t1 ( + col1 INTEGER NOT NULL, + col2 INTEGER NOT NULL, + col3 INTEGER DEFAULT NULL, + col4 INTEGER DEFAULT NULL, + col5 INTEGER DEFAULT NULL, + col6 INTEGER DEFAULT NULL, + col7 INTEGER DEFAULT NULL, + col8 INTEGER DEFAULT NULL, + col9 INTEGER DEFAULT NULL, + col10 INTEGER DEFAULT NULL, + col11 INTEGER DEFAULT NULL, + col12 INTEGER DEFAULT NULL, + col13 INTEGER DEFAULT NULL, + col14 INTEGER DEFAULT NULL, + col15 INTEGER DEFAULT NULL, + col16 INTEGER DEFAULT NULL, + col17 INTEGER DEFAULT NULL, + col18 INTEGER DEFAULT NULL, + col19 INTEGER DEFAULT NULL, + col20 INTEGER DEFAULT NULL, + col21 INTEGER DEFAULT NULL, + col22 INTEGER DEFAULT NULL, + col23 INTEGER DEFAULT NULL, + col24 INTEGER DEFAULT NULL, + col25 INTEGER DEFAULT NULL, + col26 INTEGER DEFAULT NULL, + col27 INTEGER DEFAULT NULL, + col28 INTEGER DEFAULT NULL, + col29 INTEGER DEFAULT NULL, + col30 INTEGER DEFAULT NULL, + col31 INTEGER DEFAULT NULL, + col32 INTEGER DEFAULT NULL, + col33 INTEGER DEFAULT NULL, + gcol1 INTEGER GENERATED ALWAYS AS (col1 + col2) VIRTUAL, + KEY idx1 (gcol1) +); + +INSERT INTO t1 (col1, col2) + VALUES (0,1), (1,2), (2,3), (3,4), (4,5); + +SELECT gcol1 FROM t1 FORCE INDEX(idx1); + +ALTER TABLE t1 ADD COLUMN extra INTEGER; + +SELECT gcol1 FROM t1 FORCE INDEX(idx1); + +DROP TABLE t1; + +CREATE TABLE t1 ( + id INT NOT NULL, + store_id INT NOT NULL, + x INT GENERATED ALWAYS AS (id + store_id) +) +PARTITION BY RANGE (store_id) ( + PARTITION p0 VALUES LESS THAN (6), + PARTITION p1 VALUES LESS THAN (11), + PARTITION p2 VALUES LESS THAN (16), + PARTITION p3 VALUES LESS THAN (21) +); + +INSERT INTO t1 VALUES(1, 2, default); +INSERT INTO t1 VALUES(3, 4, default); + +INSERT INTO t1 VALUES(3, 12, default); +INSERT INTO t1 VALUES(4, 18, default); + +CREATE INDEX idx ON t1(x); + +SELECT x FROM t1; + +DROP TABLE t1; + +CREATE TABLE t1 ( + id INT NOT NULL, + store_id INT NOT NULL, + x INT GENERATED ALWAYS AS (id + store_id) +) +PARTITION BY RANGE (x) ( + PARTITION p0 VALUES LESS THAN (6), + PARTITION p1 VALUES LESS THAN (11), + PARTITION p2 VALUES LESS THAN (16), + PARTITION p3 VALUES LESS THAN (21) +); + +insert into t1 values(1, 2, default); +insert into t1 values(3, 4, default); + +insert into t1 values(3, 12, default); +--error ER_NO_PARTITION_FOR_GIVEN_VALUE +insert into t1 values(4, 18, default); + +CREATE INDEX idx ON t1(x); +SELECT x FROM t1; +DROP TABLE t1; + +CREATE TABLE t1 (a INT, b INT GENERATED ALWAYS AS (a+1) ,c int) PARTITION BY RANGE (b) ( +PARTITION p0 VALUES LESS THAN (6), +PARTITION p1 VALUES LESS THAN (11), +PARTITION p2 VALUES LESS THAN (16), +PARTITION p3 VALUES LESS THAN (21) ); + +INSERT INTO t1 VALUES (10,DEFAULT,2); +INSERT INTO t1 VALUES (19,DEFAULT,8); + +CREATE INDEX idx ON t1 (b); + +INSERT INTO t1 VALUES (5,DEFAULT,9); + +SELECT * FROM t1; + +ALTER TABLE t1 REMOVE PARTITIONING; + +DROP TABLE t1; + +CREATE TABLE `t#P#1` (a INT, bt INT GENERATED ALWAYS AS (a+1) ,c int) +PARTITION BY RANGE (bt) +subpartition by hash (bt) + ( + PARTITION p0 VALUES LESS THAN (6) ( + SUBPARTITION s0, + SUBPARTITION s1), + PARTITION p1 VALUES LESS THAN (11) ( + SUBPARTITION s2, + SUBPARTITION s3), + PARTITION p2 VALUES LESS THAN (16) ( + SUBPARTITION s4, + SUBPARTITION s5), + PARTITION p3 VALUES LESS THAN (21) ( + SUBPARTITION s6, + SUBPARTITION s7) + ); +insert into `t#P#1` values (10,DEFAULT,2); +insert into `t#P#1` values (19,DEFAULT,8); +create index idx on `t#P#1` (bt); +insert into `t#P#1` values (5,DEFAULT,9); +select * from `t#P#1`; +alter table `t#P#1` remove partitioning; +drop table `t#P#1`; + +let $row_format=DYNAMIC; +--source inc/innodb_v_large_col.inc + +let $row_format=REDUNDANT; +--source inc/innodb_v_large_col.inc + +let $row_format=COMPRESSED; +--source inc/innodb_v_large_col.inc + +# Make sure FTS_DOC_ID for FULLTEXT index set with correct column id with +# virtual columns +CREATE TABLE t(a TEXT CHARSET UTF8)ENGINE=INNODB; +ALTER TABLE t ADD COLUMN b BLOB GENERATED ALWAYS AS (a) VIRTUAL ; +ALTER TABLE t ADD FULLTEXT INDEX (a) ; +ALTER TABLE t ADD INDEX (b(1)) ; + +DROP TABLE t; + +CREATE TABLE t(a TEXT CHARSET UTF8, FULLTEXT INDEX(a))ENGINE=INNODB; +ALTER TABLE t ADD COLUMN b BLOB GENERATED ALWAYS AS (a) VIRTUAL ; +ALTER TABLE t ADD INDEX (b(1)) ; +DROP TABLE t; + +# Virtual column cannot be used as DOC ID column for FULLTEXT index +CREATE TABLE t(a TEXT CHARSET UTF8)ENGINE=INNODB; +ALTER TABLE t ADD COLUMN FTS_DOC_ID BLOB GENERATED ALWAYS AS (a) VIRTUAL ; +--error ER_INNODB_FT_WRONG_DOCID_COLUMN +ALTER TABLE t ADD FULLTEXT INDEX (a) ; +DROP TABLE t; + +# Test uses ICP on column h and d +create table t (a int,b int,c int,d int,e int, +f int generated always as (a+b) virtual, +g int,h blob,i int,unique key (d,h(25))) engine=innodb; + +select h from t where d is null; +drop table t; + +# Test Add virtual column of MySQL long true type +create table t(a blob not null) engine=innodb; +alter table t add column b int; +alter table t add column c varbinary (1000) generated always as (a) virtual; +alter table t add unique index (c(39)); +replace into t set a = 'a',b =1; +replace into t set a = 'a',b =1; +drop table t; + +CREATE TABLE t (a INT, b INT, h VARCHAR(10)); +INSERT INTO t VALUES (12, 3, "ss"); +INSERT INTO t VALUES (13, 4, "ss"); +INSERT INTO t VALUES (14, 0, "ss"); +alter table t add c INT GENERATED ALWAYS AS(a/b); +create index idx on t(c); +DROP TABLE t; + +CREATE TABLE t ( + pk INTEGER AUTO_INCREMENT, + col_int_nokey INTEGER /*! NULL */, + col_int INT GENERATED ALWAYS AS (col_int_nokey + col_int_nokey) STORED, + col_int_key INTEGER GENERATED ALWAYS AS (col_int + col_int_nokey) VIRTUAL, + col_date_nokey DATE /*! NULL */, + col_date DATE GENERATED ALWAYS AS (DATE_ADD(col_date_nokey,interval 30 day)) STORED, + col_date_key DATE GENERATED ALWAYS AS (DATE_ADD(col_date,interval 30 day)) VIRTUAL, + col_datetime_nokey DATETIME /*! NULL */, + col_time_nokey TIME /*! NULL */, + col_datetime DATETIME GENERATED ALWAYS AS (ADDTIME(col_datetime_nokey, col_time_nokey)) STORED, + col_time TIME GENERATED ALWAYS AS (ADDTIME(col_datetime_nokey, col_time_nokey)) STORED, + col_datetime_key DATETIME GENERATED ALWAYS AS (ADDTIME(col_datetime, col_time_nokey)) VIRTUAL, + col_time_key TIME GENERATED ALWAYS AS (ADDTIME(col_datetime_nokey, col_time)) VIRTUAL, + col_varchar_nokey VARCHAR(1) /*! NULL */, + col_varchar VARCHAR(2) GENERATED ALWAYS AS (CONCAT(col_varchar_nokey,col_varchar_nokey)) STORED, + col_varchar_key VARCHAR(2) GENERATED ALWAYS AS (CONCAT(col_varchar, 'x')) VIRTUAL, + unique KEY (pk,col_int_key), + KEY(col_int), + KEY(col_date), + KEY(col_datetime), + KEY(col_time), + KEY(col_varchar), + UNIQUE KEY (col_int_key), + KEY (col_time_key), + KEY (col_datetime_key), + UNIQUE KEY (col_int_key, col_varchar_key), + KEY (col_int_key, col_int_nokey), + KEY(col_int_key,col_date_key), + KEY(col_int_key, col_time_key), + KEY(col_int_key, col_datetime_key), + KEY(col_date_key,col_time_key,col_datetime_key), + KEY (col_varchar_key, col_varchar_nokey), + UNIQUE KEY (col_int_key, col_varchar_key, col_date_key, col_time_key, col_datetime_key) +) AUTO_INCREMENT=10 ENGINE=INNODB PARTITION BY KEY(col_int_key) PARTITIONS 3; + +ALTER TABLE t DROP COLUMN `pk`; + +SHOW CREATE TABLE t; + +DROP TABLE t; + +CREATE TABLE t (a INT, b INT, c INT GENERATED ALWAYS AS(a+b), h VARCHAR(10)); + +INSERT INTO t VALUES (11, 3, DEFAULT, 'mm'); +INSERT INTO t VALUES (18, 1, DEFAULT, 'mm'); +INSERT INTO t VALUES (28, 1, DEFAULT, 'mm'); +INSERT INTO t VALUES (null, null, DEFAULT, 'mm'); + +--error ER_ALTER_OPERATION_NOT_SUPPORTED +ALTER TABLE t ADD COLUMN xs INT GENERATED ALWAYS AS(a+b), ADD COLUMN mm INT +GENERATED ALWAYS AS(a+b) STORED, ALGORITHM = INPLACE; + +ALTER TABLE t ADD COLUMN x INT GENERATED ALWAYS AS(a+b), ALGORITHM = INPLACE; + +ALTER TABLE t DROP COLUMN x, ALGORITHM = INPLACE; + +ALTER TABLE t ADD COLUMN x1 INT GENERATED ALWAYS AS(a+b), DROP COLUMN c, +ALGORITHM = INPLACE; + +DROP TABLE t; + +if (0) { +# Some test on virtual/stored column numbering for spatial indexing +CREATE TABLE `t` ( + `a` INT GENERATED ALWAYS AS (1) VIRTUAL, + `b` INT GENERATED ALWAYS AS (1) VIRTUAL, + `c` INT GENERATED ALWAYS AS (1) VIRTUAL, + `d` INT GENERATED ALWAYS AS (1) VIRTUAL, + `e` POINT GENERATED ALWAYS AS (1) STORED +) ENGINE=INNODB; +ALTER TABLE t ADD SPATIAL INDEX (`e`); +DROP TABLE t; +CREATE TABLE `t` ( + `a` INT GENERATED ALWAYS AS (1) VIRTUAL, + `b` INT GENERATED ALWAYS AS (1) VIRTUAL, + `c` INT GENERATED ALWAYS AS (1) VIRTUAL, + `d` INT GENERATED ALWAYS AS (1) VIRTUAL, + `e` POINT GENERATED ALWAYS AS (1) STORED, + SPATIAL INDEX (`e`) +) ENGINE=INNODB; +DROP TABLE t; +CREATE TABLE `t` ( + `a` INT GENERATED ALWAYS AS (1) VIRTUAL, + `b` INT GENERATED ALWAYS AS (1) VIRTUAL, + `c` INT GENERATED ALWAYS AS (1) VIRTUAL, + `d` INT GENERATED ALWAYS AS (1) VIRTUAL, + `e2` POINT GENERATED ALWAYS AS (1) STORED, + `e` POINT GENERATED ALWAYS AS (1) STORED +) ENGINE=INNODB; +ALTER TABLE t ADD SPATIAL INDEX (`e`); +DROP TABLE t; +CREATE TABLE `t` ( + `a` INT GENERATED ALWAYS AS (1) VIRTUAL, + `b` INT GENERATED ALWAYS AS (1) VIRTUAL, + `c` INT GENERATED ALWAYS AS (1) VIRTUAL, + `d` INT GENERATED ALWAYS AS (1) VIRTUAL, + `e2` POINT GENERATED ALWAYS AS (1) STORED, + `d2` INT GENERATED ALWAYS AS (1) VIRTUAL, + `e` POINT GENERATED ALWAYS AS (1) STORED +) ENGINE=INNODB; +ALTER TABLE t ADD SPATIAL INDEX (`e`); +DROP TABLE t; +CREATE TABLE `t` ( + `a` INT GENERATED ALWAYS AS (1) VIRTUAL, + `b` INT GENERATED ALWAYS AS (1) VIRTUAL, + `c` INT GENERATED ALWAYS AS (1) VIRTUAL, + `d` INT GENERATED ALWAYS AS (1) VIRTUAL, + `e2` POINT GENERATED ALWAYS AS (1) STORED, + `d2` INT GENERATED ALWAYS AS (1) VIRTUAL, + `e` int +) ENGINE=INNODB; +ALTER TABLE t ADD INDEX (`e`); +DROP TABLE t; +} + +CREATE TABLE t (a INT GENERATED ALWAYS AS(1) VIRTUAL,KEY(a)) ENGINE=INNODB; +INSERT INTO t VALUES(default); +SELECT a FROM t FOR UPDATE; +DROP TABLE t; + +# Test add virtual column and add index at the same time +CREATE TABLE t (a INT, b INT, c INT GENERATED ALWAYS AS(a+b), h VARCHAR(10)); + +INSERT INTO t VALUES (11, 3, DEFAULT, 'mm'); + +INSERT INTO t VALUES (18, 1, DEFAULT, 'mm'); + +INSERT INTO t VALUES (28, 1, DEFAULT, 'mm'); + +INSERT INTO t VALUES (null, null, DEFAULT, 'mm'); + +--enable_info +ALTER TABLE t ADD COLUMN x INT GENERATED ALWAYS AS(a+b), ADD INDEX idx (x); +--disable_info + +SELECT x FROM t; + +DROP TABLE t; + +CREATE TABLE t1 (a INT, b INT, c INT GENERATED ALWAYS AS(a+b), h VARCHAR(10)); + +INSERT INTO t1 VALUES (11, 3, DEFAULT, 'mm'); + +INSERT INTO t1 VALUES (18, 1, DEFAULT, 'mm'); + +INSERT INTO t1 VALUES (28, 1, DEFAULT, 'mm'); + +ALTER TABLE t1 ADD INDEX idx12 (c) , FORCE, LOCK=NONE; +ALTER TABLE t1 DROP COLUMN h, ADD INDEX idx (c) , FORCE, LOCK=NONE; + +DROP TABLE t1 ; + +# Check ALTER TABLE CHANGE VIRTUAL COLUMN TYPE and ORDER +CREATE TABLE t1 (a INT, b INT, c INT GENERATED ALWAYS AS(a+b), d INT GENERATED ALWAYS AS(a+b), h VARCHAR(10)); + +INSERT INTO t1 VALUES (11, 3, DEFAULT, DEFAULT, 'mm'); + +INSERT INTO t1 VALUES (18, 1, DEFAULT, DEFAULT, 'mm'); + +INSERT INTO t1 VALUES (28, 1, DEFAULT, DEFAULT, 'mm'); + +--error ER_ALTER_OPERATION_NOT_SUPPORTED_REASON +ALTER TABLE t1 CHANGE d d INT GENERATED ALWAYS AS(a+b) FIRST, ALGORITHM = INPLACE; + +# Change column type is not allow for inplace also +--error ER_ALTER_OPERATION_NOT_SUPPORTED +ALTER TABLE t1 CHANGE d d VARCHAR(10) GENERATED ALWAYS AS(h), ALGORITHM = INPLACE; + +ALTER TABLE t1 CHANGE d d INT GENERATED ALWAYS AS(a+b) FIRST; + +SHOW CREATE TABLE t1; + +DROP TABLE t1; + +# Test foreign key which could be a base column of indexed virtual column +CREATE TABLE parent (id INT PRIMARY KEY) ENGINE=INNODB; + +CREATE TABLE child ( + id INT, + parent_id INT, + x int(11) GENERATED ALWAYS AS (parent_id+1), + INDEX par_ind (parent_id), + FOREIGN KEY (parent_id) + REFERENCES parent(id) + ON DELETE CASCADE +) ENGINE=INNODB; + +ALTER TABLE child ADD INDEX `i1` (x); + +# If foreign constrain does not have cascade clause, or with "no action" clause +# the index can still be created +CREATE TABLE child_1 ( + id INT, + parent_id INT, + x int(11) GENERATED ALWAYS AS (parent_id+1), + INDEX par_ind (parent_id), + FOREIGN KEY (parent_id) + REFERENCES parent(id) +) ENGINE=INNODB; + +# This should be successful +ALTER TABLE child_1 ADD INDEX `i1` (x); + +DROP TABLE child_1; + +DROP TABLE child; + +CREATE TABLE child ( + id INT, + parent_id INT, + x int(11) GENERATED ALWAYS AS (parent_id+1), + INDEX par_ind (parent_id), + INDEX i1 (x), + + FOREIGN KEY (parent_id) + REFERENCES parent(id) + ON DELETE CASCADE +) ENGINE=INNODB; + +DROP TABLE child; + +CREATE TABLE child ( + id INT, + parent_id INT, + x int(11) GENERATED ALWAYS AS (parent_id+1), + INDEX par_ind (parent_id), + INDEX `i1` (x) +) ENGINE=INNODB; + +ALTER TABLE child ADD FOREIGN KEY (parent_id) +REFERENCES parent(id) +ON DELETE CASCADE; + +# Check inplace option +SET foreign_key_checks = 0; + +ALTER TABLE child ADD FOREIGN KEY (parent_id) +REFERENCES parent(id) +ON DELETE CASCADE; + +ALTER TABLE child ADD FOREIGN KEY (parent_id) +REFERENCES parent(id) +ON DELETE SET NULL; + +ALTER TABLE child ADD FOREIGN KEY (parent_id) +REFERENCES parent(id) +ON UPDATE CASCADE; + +# this should be successful +ALTER TABLE child ADD FOREIGN KEY (parent_id) +REFERENCES parent(id); + +SET foreign_key_checks = 1; + +DROP TABLE child; + +DROP TABLE parent; + +# Test for Bug 21890816 - ASSERT UPDATE->OLD_VROW, VIRTUAL COLUMNS +CREATE TABLE `ibstd_16` ( + `a` int(11) DEFAULT NULL, + `d` int(11) DEFAULT NULL, + `b` varchar(198) DEFAULT NULL, + `c` char(179) DEFAULT NULL, + `vadcol` int(11) GENERATED ALWAYS AS (a+length(d)) STORED, + `vbcol` char(2) GENERATED ALWAYS AS (substr(b,2,2)) VIRTUAL, + `vbidxcol` char(3) GENERATED ALWAYS AS (substr(b,1,3)) VIRTUAL, + UNIQUE KEY `b` (`b`(10),`d`), + KEY `d` (`d`), + KEY `a` (`a`), + KEY `c` (`c`(99),`b`(33)), + KEY `b_2` (`b`(5),`c`(10),`a`), + KEY `vbidxcol` (`vbidxcol`), + KEY `a_2` (`a`,`vbidxcol`), + KEY `vbidxcol_2` (`vbidxcol`,`d`) +) ENGINE=INNODB; + +# Block when FK constraint on base column of stored column. +#--error ER_CANNOT_ADD_FOREIGN +CREATE TABLE `ibstd_16_fk` ( + `a` int(11) DEFAULT NULL, + `d` int(11) DEFAULT NULL, + `b` varchar(198) DEFAULT NULL, + `c` char(179) DEFAULT NULL, + `vadcol` int(11) GENERATED ALWAYS AS (a+length(d)) STORED, + `vbcol` char(2) GENERATED ALWAYS AS (substr(b,2,2)) VIRTUAL, + `vbidxcol` char(3) GENERATED ALWAYS AS (substr(b,1,3)) VIRTUAL, + UNIQUE KEY `b` (`b`(10),`a`,`d`), + KEY `d` (`d`), + KEY `a` (`a`), + KEY `c` (`c`(99),`b`(33)), + KEY `b_2` (`b`(5),`c`(10),`a`), + KEY `vbidxcol` (`vbidxcol`), + KEY `a_2` (`a`,`vbidxcol`), + KEY `vbidxcol_2` (`vbidxcol`,`d`), + CONSTRAINT `fk_16` FOREIGN KEY (`a`) REFERENCES `ibstd_16` (`a`) ON DELETE SET NULL +) ENGINE=InnoDB; +DROP TABLE ibstd_16_fk; + +# Take out "KEY `a_2` (`a`,`vbidxcol`)", this should then be successful +CREATE TABLE `ibstd_16_fk` ( + `a` int(11) DEFAULT NULL, + `d` int(11) DEFAULT NULL, + `b` varchar(198) DEFAULT NULL, + `c` char(179) DEFAULT NULL, + `vbcol` char(2) GENERATED ALWAYS AS (substr(b,2,2)) VIRTUAL, + `vbidxcol` char(3) GENERATED ALWAYS AS (substr(b,1,3)) VIRTUAL, + UNIQUE KEY `b` (`b`(10),`a`,`d`), + KEY `d` (`d`), + KEY `a` (`a`), + KEY `c` (`c`(99),`b`(33)), + KEY `b_2` (`b`(5),`c`(10),`a`), + KEY `vbidxcol` (`vbidxcol`), + KEY `vbidxcol_2` (`vbidxcol`,`d`), + CONSTRAINT `fk_16` FOREIGN KEY (`a`) REFERENCES `ibstd_16` (`a`) ON DELETE SET NULL +) ENGINE=InnoDB; + +ALTER TABLE ibstd_16_fk ADD INDEX `a_2` (`a`,`vbidxcol`); + +# Now try to add a table with virtual index, and then add constraint +DROP TABLE ibstd_16_fk; + +# Create a table without constraint +CREATE TABLE `ibstd_16_fk` ( + `a` int(11) DEFAULT NULL, + `d` int(11) DEFAULT NULL, + `b` varchar(198) DEFAULT NULL, + `c` char(179) DEFAULT NULL, + `vbcol` char(2) GENERATED ALWAYS AS (substr(b,2,2)) VIRTUAL, + `vbidxcol` char(3) GENERATED ALWAYS AS (substr(b,1,3)) VIRTUAL, + UNIQUE KEY `b` (`b`(10),`a`,`d`), + KEY `d` (`d`), + KEY `a` (`a`), + KEY `c` (`c`(99),`b`(33)), + KEY `b_2` (`b`(5),`c`(10),`a`), + KEY `vbidxcol` (`vbidxcol`), + KEY `a_2` (`a`,`vbidxcol`), + KEY `vbidxcol_2` (`vbidxcol`,`d`) +) ENGINE=InnoDB; + +ALTER TABLE `ibstd_16_fk` ADD CONSTRAINT `fk_16` FOREIGN KEY (`a`) REFERENCES `ibstd_16` (`a`) ON DELETE SET NULL; + +# DROP the index +DROP INDEX a_2 ON ibstd_16_fk; + +INSERT INTO ibstd_16 VALUES (1, 2, "aaa", "bbb", default, default, default); +INSERT INTO ibstd_16_fk VALUES(1, 3, "mmm", "SSS", default, default); + +# Cascading delete/update on column non-related to virtual column or virtual +# index will be fine +DELETE FROM ibstd_16 WHERE a = 1; + +DROP TABLE ibstd_16_fk; +DROP TABLE ibstd_16; + +# Bug 21941320 - GCOLS: FAILING ASSERTION: N_IDX > 0 +create table t(a int) engine=innodb; +insert into t set a=1; +alter table t add column c int generated always as (1) virtual; +insert into t set a=2; + +# Following will cause create index fail, we need to make sure the column +# ord_part is reset +--error ER_DUP_ENTRY +alter table t add unique index(c); +insert into t set a=1; +drop table t; + +# Bug 21875974 - VCOL : READ OF FREED MEMORY IN DTUPLE_GET_N_FIELDS +# CAUSE CRASH + +create table t ( + x int, + a int generated always as (x) virtual, + b int generated always as (1) stored, + c int not null, + unique (b), + unique (a,b) +) engine=innodb; + +insert into t(x, c) values(1, 3); + +# This will exercise row_vers_impl_x_locked_low() for virtual columns +replace into t(x, c) values(1, 0); + +drop table t; + +# Bug22123674 VCOL:INNODB: FAILING ASSERTION: !UT_STRCMP(NAME, +# FIELD->FIELD_NAME) + +CREATE TABLE t( +c7c CHAR(1)GENERATED ALWAYS AS (c3) VIRTUAL, +c1 int(1), +c2 int(1), +c3 int(1), +c4 int(1), +c5 int(1)GENERATED ALWAYS AS ((c2 - c4)) VIRTUAL, +UNIQUE KEY c5_9(c5) +)ENGINE=InnoDB DEFAULT CHARSET=latin1; + +--error ER_ALTER_OPERATION_NOT_SUPPORTED +ALTER TABLE t CHANGE COLUMN c5 c5 INT(1) GENERATED ALWAYS AS(c2 - +c4)VIRTUAL AFTER c3,ALGORITHM=INPLACE; + +--error ER_ALTER_OPERATION_NOT_SUPPORTED +ALTER TABLE t CHANGE COLUMN c7c c7c INT(1) GENERATED ALWAYS AS(c3) +VIRTUAL AFTER c5,ALGORITHM=INPLACE; + +--error ER_ALTER_OPERATION_NOT_SUPPORTED_REASON +ALTER TABLE t DROP COLUMN c7c,ADD COLUMN c5c INT GENERATED ALWAYS AS(c4/ +c3)VIRTUAL AFTER c3,ALGORITHM=INPLACE; + +DROP TABLE t; + +# Bug22111464 VCOL:INNODB: FAILING ASSERTION: I < TABLE->N_DEF + +CREATE TABLE `t` ( + `col1` int(11) DEFAULT NULL, + `col2` int(11) DEFAULT NULL, + `col4` int(11) DEFAULT NULL, + `col5` int(11) GENERATED ALWAYS AS ((`col2` % `col4`)) VIRTUAL, + `col6` int(11) GENERATED ALWAYS AS ((`col2` - `col2`)) VIRTUAL, + `col5x` int(11) GENERATED ALWAYS AS ((`col1` / `col1`)) VIRTUAL, + `col6x` int(11) GENERATED ALWAYS AS ((`col2` / `col4`)) VIRTUAL, + `col7x` int(11) GENERATED ALWAYS AS ((`col6` % `col6x`)) VIRTUAL, + `col8x` int(11) GENERATED ALWAYS AS ((`col6` / `col6`)) VIRTUAL, + `col9` text, + `col7c` int(11) GENERATED ALWAYS AS ((`col6x` % `col6x`)) VIRTUAL, + `col1b` varchar(20) GENERATED ALWAYS AS (`col1`) VIRTUAL, + `col3` int(11) DEFAULT NULL, + `col7` int(11) DEFAULT NULL, + `col5c` int(11) GENERATED ALWAYS AS ((`col5x` * `col6`)) VIRTUAL, + `col6c` varchar(20) GENERATED ALWAYS AS (`col5x`) VIRTUAL, + `col3b` bigint(20) GENERATED ALWAYS AS ((`col6x` * `col6`)) VIRTUAL, + `col1a` varchar(20) GENERATED ALWAYS AS (`col1`) VIRTUAL, + `col8` int(11) DEFAULT NULL, + UNIQUE KEY `col5` (`col5`), + UNIQUE KEY `col6x` (`col6x`), + UNIQUE KEY `col5_2` (`col5`), + KEY `idx2` (`col9`(10)), + KEY `idx4` (`col2`), + KEY `idx8` (`col9`(10),`col5`), + KEY `idx9` (`col6`), + KEY `idx6` (`col6`) +) ENGINE=InnoDB DEFAULT CHARSET=latin1; + +ALTER TABLE t CHANGE COLUMN col3b col8a BIGINT GENERATED ALWAYS AS +(col6x * col6) VIRTUAL, ADD UNIQUE KEY uidx ( col8a ); + +DROP TABLE t; + +--echo # +--echo # Bug 22141031 - GCOLS: PURGED THREAD DIES: TRIED TO PURGE +--echo # NON-DELETE-MARKED RECORD IN INDEX +--echo # +create table t ( + a int,b int,c text,d int,e int,f int,g int, + h text generated always as ('1') virtual, + i int,j int,k int,l int,m int, + primary key (c(1)),unique key (c(1)), + key (i),key (h(1)) +) engine=innodb default charset latin1; + +replace into t(c) values (''); +replace into t(c) values (''); +alter table t drop column d ; + +drop table t; + +--echo # +--echo # Bug 22139917 - ASSERTION: DICT_TABLE_GET_NTH_COL(USER_TABLE, NTH_COL) +--echo # ->LEN < NEW_LEN +--echo # + +create table t ( + a int generated always as (1) virtual, + b varbinary(1), + c varbinary(1) generated always as (b) virtual +) engine=innodb; +alter table t change column b b varbinary(2), algorithm=inplace; +alter table t change column c c varbinary(2) generated always as (b) virtual, algorithm=inplace; + +drop table t; + +# Bug22202788 GCOL:ASSERTION:0 IN ROW_SEL_GET_CLUST_REC_FOR_MYSQL AT +# ROW0SEL.CC +SET @@SESSION.sql_mode=0; + +CREATE TABLE t( + c1 INT AUTO_INCREMENT, + c2 INT, + c3 INT GENERATED ALWAYS AS(c2 + c2)VIRTUAL, + c3k INT GENERATED ALWAYS AS(c2 + c3)VIRTUAL, + c4 DATE, + c5 DATE GENERATED ALWAYS AS(DATE_ADD(c4,interval 30 day)) VIRTUAL, + c5k DATE GENERATED ALWAYS AS(DATE_ADD(c4,interval 30 day)) VIRTUAL, + c5time_gckey DATE, + c6 TIME, + c5time DATE GENERATED ALWAYS AS(ADDTIME(c5time_gckey,c6)) VIRTUAL, + c7 TIME GENERATED ALWAYS AS(ADDTIME(c5time_gckey,c6)) VIRTUAL, + c5timek DATE GENERATED ALWAYS AS(ADDTIME(c5time_gckey,c7)) VIRTUAL, + c7k TIME GENERATED ALWAYS AS(ADDTIME(c5time,c6)) VIRTUAL, + c8 CHAR(10), + c9 CHAR(20)GENERATED ALWAYS AS (CONCAT(c8,c8)) VIRTUAL, + c9k CHAR(15)GENERATED ALWAYS AS (CONCAT(c8,0)) VIRTUAL, + PRIMARY KEY(c1), + KEY(c3), + KEY(c9(10)), + UNIQUE KEY(c9k), + UNIQUE KEY(c3k,c9k(5),c5k,c7k,c5timek,c3,c9(5),c5,c7,c5time) +)ENGINE=INNODB; + +--error ER_DUP_ENTRY +INSERT INTO +t(c2,c4,c6,c5time_gckey,c8)VALUES(1,0,0,0,0),(0,0,0,0,'ityzg'),(0,0,1,0,'tyzgk +t'),(0,1,0,1,'yzgktb'),(0,0,0,0,'zgktb'),(0,0,0,0,'gktbkj'),(0,0,0,0,0),(0,0,1 +,0,1),(0,0,0,0,1),(0,0,0,0,'tbkjrkm'),(0,0,0,0,'bkjr'),(0,0,0,0,0),(0,0,0,0,0) +,(0,0,0,0,'rk'),(0,0,0,0,'kmqmknbtoe'),(1,0,0,0,'mqmknbt'),(0,1,0,0,'qmknb'),( +0,0,0,0,'mkn'),(0,0,0,0,'knbtoervql'),(0,0,1,0,1),(0,0,0,0,'nbtoerv'),(0,0,0,0 +,'btoerv'),(0,0,1,0,'toer'),(1,0,0,0,0),(0,0,0,0,'ervq'),(0,0,0,0,'rvqlzsvasu' +),(0,0,0,0,'vqlzs'),(0,0,0,0,0),(0,1,0,0,'lzsvasu'),(0,0,0,0,'zsvasurq'); + +SELECT +DISTINCT * FROM t +FORCE KEY(PRIMARY,c3k,c3,c9k,c9) +WHERE +(c9 IS NULL AND (c9=0)) +OR( +(c9k NOT IN ('ixfq','xfq','New Mexico','fq')OR c9 IS NULL) +) +OR(c9 BETWEEN 'hwstqua' AND 'wstquadcji' OR (c9k=0)) +AND(c3 IS NULL OR c3 IN (0,0,0)); + +drop table t; + +# +# BUG#22082762 RE-ENABLE SUPPORT FOR ADDING VIRTUAL INDEX WHILE DROPPING VIRTUAL COLUMN +# + +CREATE TABLE t (a INT, b INT, c INT GENERATED ALWAYS AS(a+b), d INT +GENERATED ALWAYS AS(a+b+b), e INT GENERATED ALWAYS AS(a), h VARCHAR(10)); + +INSERT INTO t VALUES (11, 3, DEFAULT, DEFAULT, DEFAULT, 'mm'); +INSERT INTO t VALUES (18, 1, DEFAULT, DEFAULT, DEFAULT, 'mm'); +INSERT INTO t VALUES (28, 1, DEFAULT, DEFAULT, DEFAULT, 'mm'); +INSERT INTO t VALUES (null, null, DEFAULT, DEFAULT, DEFAULT, 'mm'); +CREATE INDEX idx ON t(c, d); +CREATE INDEX idx1 ON t(c); +CREATE INDEX idx2 ON t(e, c, d); + +# This will drop column c, drop index idx1 on column c, and build index +# idx and idx2, so they become idx(d) and idx2(e, d) respectively. +ALTER TABLE t DROP COLUMN c, ALGORITHM=INPLACE; + +SELECT d FROM t; + +SHOW CREATE TABLE t; + +# Drop a column, adding a new column and also adding a index on this new column +# is not allowed for INPLACE algorithm +--error ER_ALTER_OPERATION_NOT_SUPPORTED_REASON +ALTER TABLE t DROP COLUMN d, ADD COLUMN c INT GENERATED ALWAYS AS(a+b), ADD INDEX idx (c), ALGORITHM=INPLACE; + +# Add an index on existing column along with dropping a column is allowed +ALTER TABLE t DROP COLUMN d, ADD COLUMN c INT GENERATED ALWAYS AS(a+b), ADD INDEX idx (e), ALGORITHM=INPLACE, LOCK=NONE; +SHOW CREATE TABLE t; + +# Add an index on existing column along with adding a virtual column and droping a virtual index +ALTER TABLE t ADD INDEX idx4(c, e), ADD COLUMN x VARCHAR(10) GENERATED ALWAYS AS(h), DROP INDEX idx, ALGORITHM=INPLACE, LOCK=NONE; +SHOW CREATE TABLE t; + +--error ER_ALTER_OPERATION_NOT_SUPPORTED_REASON +ALTER TABLE t ADD COLUMN i INT GENERATED ALWAYS AS(a+a+b), ADD COLUMN j INT, ALGORITHM=INPLACE; + +# Add an index along with adding a regular column is allowed. +ALTER TABLE t ADD INDEX (x), ADD COLUMN j INT, ALGORITHM=INPLACE, LOCK=NONE; +SHOW CREATE TABLE t; + +# Online add an index on newly added virtual column is not allowed. +--error ER_ALTER_OPERATION_NOT_SUPPORTED_REASON +ALTER TABLE t ADD COLUMN i INT GENERATED ALWAYS AS(a+a+b), ADD INDEX (i), ALGORITHM=INPLACE, LOCK=NONE; + +ALTER TABLE t ADD COLUMN i INT GENERATED ALWAYS AS(a+a+b), ADD INDEX (i), ALGORITHM=INPLACE, LOCK=SHARED; +SHOW CREATE TABLE t; + +SELECT i FROM t; + +SELECT * FROM t; + +DROP TABLE t; + +# +# BUG#22469459 WRONG VALUES IN ADDED INDEX WHILE DROPPING VIRTUAL COLUMN +# + +# Drop column with existing index on it. +CREATE TABLE t ( + a INT, + b INT, + c INT GENERATED ALWAYS AS(a+b), + d INT GENERATED ALWAYS AS(a+b+b), + KEY vidx (c, d) +)ENGINE=INNODB; + +INSERT INTO t (a,b) VALUES (0, 0), (1, NULL), (NULL, 2), (NULL, NULL); + +SELECT c, d FROM t; + +SELECT * FROM t; + +ALTER TABLE t DROP COLUMN c, ALGORITHM=INPLACE; + +SELECT d FROM t; + +SELECT * FROM t; + +DROP TABLE t; + +# Drop column with a new index. +CREATE TABLE t ( + a INT, + b INT, + c INT GENERATED ALWAYS AS(a+b), + d INT GENERATED ALWAYS AS(a+b+b) +)ENGINE=INNODB; + +INSERT INTO t (a,b) VALUES (0, 0), (1, NULL), (NULL, 2), (NULL, NULL); + +SELECT * FROM t; + +ALTER TABLE t DROP COLUMN c, ADD INDEX vidx(d), ALGORITHM=INPLACE; + +SELECT d FROM t; + +SELECT * FROM t; + +DROP TABLE t; + +--echo # +--echo # Bug #22162200 MEMORY LEAK IN HA_INNOPART_SHARE +--echo # ::SET_V_TEMPL PARTITIONED ON VIRTUAL COLUMN +--echo # +create table t ( + c tinyint, + d longblob generated always as (c) virtual +) engine=innodb partition by key (c) partitions 2; + +select d in(select d from t)from t group by d; +drop table t; + +--echo # +--echo # BUG#23052231 - ASSERTION FAILURE: ROW0MERGE.CC:2100:ADD_AUTOINC +--echo # < DICT_TABLE_GET_N_USER_COLS +--echo # +CREATE TABLE `t` ( + `a` int(11) NOT NULL, + `d` int(11) NOT NULL, + `b` varchar(198) NOT NULL, + `c` char(177) DEFAULT NULL, + `vadcol` int(11) GENERATED ALWAYS AS ((`a` + length(`d`))) STORED, + `vbcol` char(2) GENERATED ALWAYS AS (substr(`b`,2,2)) VIRTUAL, + `vbidxcol` char(3) GENERATED ALWAYS AS (substr(`b`,1,3)) VIRTUAL, + PRIMARY KEY (`b`(10),`a`,`d`), + KEY `d` (`d`), + KEY `a` (`a`), + KEY `c_renamed` (`c`(99),`b`(35)), + KEY `b` (`b`(5),`c`(10),`a`), + KEY `vbidxcol` (`vbidxcol`), + KEY `a_2` (`a`,`vbidxcol`), + KEY `vbidxcol_2` (`vbidxcol`,`d`) +) ENGINE=InnoDB DEFAULT CHARSET=latin1; + +INSERT INTO t values (11, 1, "11", "aa", default, default, default); + +ALTER TABLE t ADD COLUMN nc01128 BIGINT AUTO_INCREMENT NOT NULL, ADD KEY auto_nc01128(nc01128); + +DROP TABLE t; + +--echo # +--echo #Bug #22965271 NEEDS REBUILD FOR COLUMN LENGTH CHANGE THAT IS +--echo #PART OF VIRTUAL INDEX. +--echo # + +CREATE TABLE t1( +a VARCHAR(45) CHARACTER SET LATIN1, +b VARCHAR(115) CHARACTER SET UTF8 GENERATED ALWAYS AS ('f1') VIRTUAL, +UNIQUE KEY (b,a))ENGINE=INNODB; +INSERT INTO t1(a) VALUES (''); +ALTER TABLE t1 CHANGE COLUMN a a VARCHAR(85); +SELECT * FROM t1; +DROP TABLE t1; diff --git a/mysql-test/suite/gcol/t/innodb_virtual_blob.test b/mysql-test/suite/gcol/t/innodb_virtual_blob.test new file mode 100644 index 00000000000..a97992d81e7 --- /dev/null +++ b/mysql-test/suite/gcol/t/innodb_virtual_blob.test @@ -0,0 +1,16 @@ +--source include/have_innodb.inc + +--echo # +--echo # Bug#22046353 ALTER: ASSERT PAGE_SIZE.EQUALS_TO(SPACE_PAGE_SIZE), +--echo # BTR_COPY_BLOB_PREFIX +--echo # + +CREATE TABLE t1 +( f1 int primary key, f2 blob, + f3 blob generated always as (f2)) + row_format=compressed, engine=innodb; +insert into t1 (f1, f2) values (1, repeat('&', 50000)); +alter table t1 add index i1 (f3(200)) ; +alter table t1 row_format=compact; +drop table t1; + diff --git a/mysql-test/suite/gcol/t/innodb_virtual_debug.test b/mysql-test/suite/gcol/t/innodb_virtual_debug.test new file mode 100644 index 00000000000..72be27775ed --- /dev/null +++ b/mysql-test/suite/gcol/t/innodb_virtual_debug.test @@ -0,0 +1,240 @@ +--source include/have_innodb.inc +--source include/have_debug_sync.inc +--source include/have_debug.inc +--source include/count_sessions.inc + +set default_storage_engine=innodb; +CREATE TABLE `t` ( + `a` VARCHAR(100), + `b` VARCHAR(100), + `c` VARCHAR(200) GENERATED ALWAYS AS (CONCAT(a,b)) VIRTUAL, + `h` VARCHAR(10) DEFAULT NULL, + `i` int +) ENGINE=InnoDB; + +INSERT INTO t VALUES (REPEAT('g', 100), REPEAT('x', 10), DEFAULT, "kk", 1); +INSERT INTO t VALUES (REPEAT('a', 100), REPEAT('b', 100), DEFAULT, "mm", 2); + +CREATE INDEX idx ON t(c(100)); + +SET session debug_dbug="+d,ib_alter_add_virtual_fail"; +--error ER_WRONG_KEY_COLUMN +ALTER TABLE t ADD COLUMN x VARCHAR(200) GENERATED ALWAYS AS (a) VIRTUAL, +ALGORITHM = INPLACE; +--error ER_WRONG_KEY_COLUMN +ALTER TABLE t DROP COLUMN c, ALGORITHM = INPLACE; +SET session debug_dbug=""; +DROP TABLE t; + +#online test +CREATE TABLE t (a INT, b INT, c INT GENERATED ALWAYS AS(a+b), h VARCHAR(10)); + +INSERT INTO t VALUES (11, 3, DEFAULT, 'mm'); +INSERT INTO t VALUES (18, 1, DEFAULT, 'mm'); +INSERT INTO t VALUES (28, 1, DEFAULT, 'mm'); +INSERT INTO t VALUES (null, null, DEFAULT, "mx"); + +SET DEBUG_SYNC = 'innodb_inplace_alter_table_enter SIGNAL start_create WAIT_FOR go_ahead'; +--send CREATE INDEX idx ON t(c) + +connect (con1,localhost,root,,); + +SET DEBUG_SYNC = 'now WAIT_FOR start_create'; +update t set a=0 where a = 11; +start transaction; +update t set a=1 where a = 0; +ROLLBACK; +SET DEBUG_SYNC = 'now SIGNAL go_ahead'; + +connection default; +reap; + +SELECT c FROM t; +SHOW CREATE TABLE t; +SELECT * FROM t; + +SET DEBUG_SYNC = 'innodb_inplace_alter_table_enter SIGNAL start_create WAIT_FOR go_ahead'; +--send ALTER TABLE t ADD COLUMN x INT + +connection con1; + +SET DEBUG_SYNC = 'now WAIT_FOR start_create'; +start transaction; +update t set a=1 where a = 0; +rollback; +start transaction; +delete from t; +insert into t values(1,null,default,null); +rollback; +start transaction; +update t set b=b+1; +rollback; +SET DEBUG_SYNC = 'now SIGNAL go_ahead'; + +connection default; +reap; + +check table t; +SELECT c FROM t; + +SET DEBUG_SYNC = 'innodb_inplace_alter_table_enter SIGNAL start_create WAIT_FOR go_ahead'; +--send ALTER TABLE t ADD COLUMN x2 INT + +connection con1; + +SET DEBUG_SYNC = 'now WAIT_FOR start_create'; +start transaction; +DELETE FROM t WHERE a = 0; +ROLLBACK; +DELETE FROM t WHERE a = 0; +SET DEBUG_SYNC = 'now SIGNAL go_ahead'; + +connection default; +reap; + +SELECT c FROM t; + +disconnect con1; +DROP TABLE t; + +SET DEBUG_SYNC = 'RESET'; + + +# Test add virtual column and add index at the same time +# introduce some error + +CREATE TABLE t (a INT, b INT, c INT GENERATED ALWAYS AS(a+b), h VARCHAR(10)); + +INSERT INTO t VALUES (11, 3, DEFAULT, 'mm'); + +INSERT INTO t VALUES (18, 1, DEFAULT, 'mm'); + +INSERT INTO t VALUES (28, 1, DEFAULT, 'mm'); + +INSERT INTO t VALUES (null, null, DEFAULT, 'mm'); + +CREATE INDEX idx_1 on t(c); + +SET SESSION debug_dbug="+d,create_index_fail"; + +--enable_info +--error ER_DUP_ENTRY +ALTER TABLE t ADD COLUMN x INT GENERATED ALWAYS AS(a+b), ADD INDEX idx (x); +SET SESSION debug_dbug=""; +--disable_info + +SHOW CREATE TABLE t; + +SELECT c FROM t; + +DROP TABLE t; + + +--echo # +--echo # Bug#22018532 ASSERTION WHEN ONLINE REAPPLY REBUILD LOG ON +--echo # MULTIPLE INDEXED VIRTUAL COLUMNS +--echo # + +create table t ( + a int as (1) virtual, + b int, + c int as (1) virtual, + unique(b), + unique(c), + key(a) +) engine=innodb; + +insert ignore into t values(); + +SET DEBUG_SYNC = 'innodb_inplace_alter_table_enter SIGNAL start_create WAIT_FOR go_ahead'; +--send optimize table t + +connect (con1,localhost,root,,); + +SET DEBUG_SYNC = 'now WAIT_FOR start_create'; +insert ignore into t values(); +SET DEBUG_SYNC = 'now SIGNAL go_ahead'; + +connection default; +--echo /* connection default */ optimize table t; +reap; +SELECT c FROM t; +SHOW CREATE TABLE t; +SELECT * FROM t; +DROP TABLE t; + +# Do another test without duplicate error + +CREATE TABLE t (a INT, b INT, c INT GENERATED ALWAYS AS(a+b), h VARCHAR(10)); + +INSERT INTO t VALUES (11, 3, DEFAULT, 'mm'); +INSERT INTO t VALUES (18, 1, DEFAULT, 'mm'); +INSERT INTO t VALUES (28, 1, DEFAULT, 'mm'); +INSERT INTO t VALUES (null, null, DEFAULT, 'mm'); + +CREATE INDEX idx ON t(c); + +SET DEBUG_SYNC = 'innodb_inplace_alter_table_enter SIGNAL start_rebuild WAIT_FOR go_ahead'; +--send optimize table t + +connection con1; +SET DEBUG_SYNC = 'now WAIT_FOR start_rebuild'; +INSERT INTO t VALUES (48, 2, DEFAULT, 'xx'); +INSERT INTO t VALUES (68, 3, DEFAULT, 'sx'); +SET DEBUG_SYNC = 'now SIGNAL go_ahead'; + +connection default; +--echo /* connection default */ optimize table t; +reap; + +SELECT c FROM t; + +disconnect con1; + +DROP TABLE t; + +--echo # +--echo # Bug#22951879 - ASSERTS RELATED TO ONLINE DDL AND GCOL +--echo # + +# Create a table with 2 virtual column, one (vbidxcol) is indexed and +# the other one (vbcol) is not +create table ibstd_14 (a int not null, d int not null, b varchar(198) not null, c char(181), vadcol int as (a+length(d)) stored, vbcol char(2) as (substr(b,2,2)) virtual, vbidxcol char(3) as (substr(b,1,3)) virtual , index(d), index(a), index(vbidxcol), index(a,vbidxcol), index(vbidxcol,d), unique key (b(10), a, d), index(c(99), b(31)), index(b(5), c(10), a) , index(a,d)) engine=InnoDB stats_persistent=1 row_format=dynamic; + +# Do an alter table rebuild table and also create a new index on this +# non-indexed virtual column +SET DEBUG_SYNC = 'innodb_inplace_alter_table_enter SIGNAL start_create WAIT_FOR go_ahead'; +--send alter table ibstd_14 row_format=compressed key_block_size=4,add key kn3 (d,c,vbcol,b) + +# Do a concurrent insert, and make sure this newly indexed virtual column +# is also logged +connect (con1,localhost,root); +SET DEBUG_SYNC = 'now WAIT_FOR start_create'; +insert into ibstd_14 (a,d,b,c, vbidxcol, vbcol) values ('118','6',repeat('oacolaarlruoacuroauurloraarucoooarcooauoolacalllaulrruarrrucruuooclacuoouccarrcoocloccorrrrarourcooalloocooccouruolaorlcaocualolc','1'),repeat('lolrrlalcocroraaulauclaaucolcorcuooaolruaooooluooooouaoorlarucorullalcrrloccououaooaorluorraclrcooouuolocoaolcocaaculruoocucoocoooauuolarcoraraocaoolulolarru','1'),default,default); + +insert into ibstd_14 (a,d,b,c, vbidxcol, vbcol) values ('118','6', 'aaaa', 'lll', default, default); + +# Also do an concurrent update, make sure this is performed +update ibstd_14 set b='11111' where b='aaaa'; + +SET DEBUG_SYNC = 'now SIGNAL go_ahead'; + +connection default; +reap; + +select * from ibstd_14; + +# This will use the newly added "kn3" index, to check materialized vbcol +# after log reapply +select d,c,vbcol,b from ibstd_14; + +# check the value is inserted into the index +select vbcol from ibstd_14; + +drop table ibstd_14; + +disconnect con1; + +SET DEBUG_SYNC = 'RESET'; + +--source include/wait_until_count_sessions.inc diff --git a/mysql-test/suite/gcol/t/innodb_virtual_debug_purge.test b/mysql-test/suite/gcol/t/innodb_virtual_debug_purge.test new file mode 100644 index 00000000000..d2634aa1ee8 --- /dev/null +++ b/mysql-test/suite/gcol/t/innodb_virtual_debug_purge.test @@ -0,0 +1,174 @@ +--source include/have_innodb.inc +--source include/have_debug_sync.inc +--source include/have_debug.inc +--source include/have_partition.inc + +set default_storage_engine=innodb; +set @old_dbug=@@global.debug_dbug; + +CREATE TABLE `t` ( + `a` BLOB, + `b` BLOB, + `c` BLOB GENERATED ALWAYS AS (CONCAT(a,b)) VIRTUAL, + `h` VARCHAR(10) DEFAULT NULL, + `i` int +) ENGINE=InnoDB; + +INSERT INTO t VALUES (REPEAT('g', 16000), REPEAT('x', 16000), DEFAULT, "kk", 1); +INSERT INTO t VALUES (REPEAT('a', 16000), REPEAT('b', 16000), DEFAULT, "mm", 2); + +CREATE INDEX idx ON t(c(100)); + +SET global debug_dbug="+d,ib_purge_virtual_index_callback"; +UPDATE t SET a = REPEAT('m', 16000) WHERE a like "aaa%"; +select sleep(3); +SET global debug_dbug=@old_dbug; +DROP TABLE t; + + +CREATE TABLE t ( + a TINYBLOB, + b TINYBLOB, + c TINYBLOB GENERATED ALWAYS AS (CONCAT(a,b)) VIRTUAL, + h VARCHAR(10) DEFAULT NULL, + i INT +) ROW_FORMAT=COMPACT ENGINE=InnoDB; + +INSERT INTO t VALUES (REPEAT('g', 100), REPEAT('x', 100), DEFAULT, "kk", 1); +INSERT INTO t VALUES (REPEAT('a', 100), REPEAT('b', 100), DEFAULT, "mm", 2); + +CREATE INDEX idx ON t(c(100)); + +SET global debug_dbug="+d,ib_purge_virtual_index_callback"; +UPDATE t SET a = REPEAT('m', 100) WHERE a like "aaa%"; +select sleep(3); +SET global debug_dbug=@old_dbug; +DROP TABLE t; + + +CREATE TABLE t1 ( + id INT NOT NULL, + store_id INT NOT NULL, + x INT GENERATED ALWAYS AS (id + store_id) +) +PARTITION BY RANGE (store_id) ( + PARTITION p0 VALUES LESS THAN (6), + PARTITION p1 VALUES LESS THAN (11), + PARTITION p2 VALUES LESS THAN (16), + PARTITION p3 VALUES LESS THAN (21) +); + +insert into t1 values(1, 2, default); +insert into t1 values(3, 4, default); + +insert into t1 values(3, 12, default); +insert into t1 values(4, 18, default); + +CREATE INDEX idx ON t1(x); + +SET global debug_dbug="+d,ib_purge_virtual_index_callback"; +UPDATE t1 SET id = 10 WHERE id = 1; +select sleep(3); +SET global debug_dbug=@old_dbug; +DROP TABLE t1; + +# +# BUG#22082762 RE-ENABLE SUPPORT FOR ADDING VIRTUAL INDEX WHILE DROPPING VIRTUAL COLUMN +# +--source include/count_sessions.inc + +connect (con1,localhost,root,,); +connection default; + +# Test adding virtual index on newly added virtual column +CREATE TABLE t1 (a INT, b INT); + +INSERT INTO t1(a, b) VALUES (1, 1), (2, 2), (3, 3); + +connection con1; +--echo # disable purge +CREATE TABLE t0 (a INT) ENGINE=InnoDB; +BEGIN; SELECT * FROM t0; + +connection default; +DELETE FROM t1 WHERE a = 1; + +UPDATE t1 SET a = 4, b = 4 WHERE a = 3; + +INSERT INTO t1(a, b) VALUES (5, 5); + +SET DEBUG_SYNC= 'inplace_after_index_build SIGNAL uncommitted WAIT_FOR purged'; +--error ER_ALTER_OPERATION_NOT_SUPPORTED_REASON +ALTER TABLE t1 ADD COLUMN c INT GENERATED ALWAYS AS(a+b), ADD INDEX idx (c), ALGORITHM=INPLACE, LOCK=NONE; +send ALTER TABLE t1 ADD COLUMN c INT GENERATED ALWAYS AS(a+b), ADD INDEX idx (c), ALGORITHM=INPLACE, LOCK=SHARED; + +connection con1; +SET DEBUG_SYNC= 'now WAIT_FOR uncommitted'; + +--echo # enable purge +COMMIT; + +--echo # wait for purge to process the deleted records. +--source include/wait_innodb_all_purged.inc + +SET DEBUG_SYNC= 'now SIGNAL purged'; + +connection default; +--echo /* connection default */ ALTER TABLE t1 ADD COLUMN c INT GENERATED ALWAYS AS(a+b), ADD INDEX idx (c), ALGORITHM=INPLACE, LOCK=SHARED; +--reap +SHOW CREATE TABLE t1; + +SELECT * FROM t1; + +DROP TABLE t1; + +# Test adding virutal index on existing virtual column +CREATE TABLE t1 (a INT, b INT, c INT GENERATED ALWAYS AS(a+b)); + +INSERT INTO t1(a, b) VALUES (1, 1), (2, 2), (3, 3), (4, 4); + +connection con1; +--echo # disable purge +BEGIN; SELECT * FROM t0; + +connection default; +DELETE FROM t1 WHERE a = 1; + +UPDATE t1 SET a = 2, b = 2 WHERE a = 5; + +INSERT INTO t1(a, b) VALUES (6, 6); + +SET DEBUG_SYNC= 'inplace_after_index_build SIGNAL uncommitted WAIT_FOR purged'; +send ALTER TABLE t1 ADD INDEX idx (c), ALGORITHM=INPLACE, LOCK=NONE; + +connection con1; +SET DEBUG_SYNC= 'now WAIT_FOR uncommitted'; + +DELETE FROM t1 WHERE a = 3; + +UPDATE t1 SET a = 7, b = 7 WHERE a = 4; + +INSERT INTO t1(a, b) VALUES (8, 8); + +--echo # enable purge +COMMIT; + +--echo # wait for purge to process the deleted/updated records. +--source include/wait_innodb_all_purged.inc + +SET DEBUG_SYNC= 'now SIGNAL purged'; + +disconnect con1; + +connection default; +--echo /* connection default */ ALTER TABLE t1 ADD INDEX idx (c), ALGORITHM=INPLACE, LOCK=NONE; +--reap +SHOW CREATE TABLE t1; + +SELECT * FROM t1; + +DROP TABLE t0, t1; + +--source include/wait_until_count_sessions.inc + +set debug_sync=reset; diff --git a/mysql-test/suite/gcol/t/innodb_virtual_fk.test b/mysql-test/suite/gcol/t/innodb_virtual_fk.test new file mode 100644 index 00000000000..bd8f3664839 --- /dev/null +++ b/mysql-test/suite/gcol/t/innodb_virtual_fk.test @@ -0,0 +1,492 @@ +-- source include/have_innodb.inc + +set default_storage_engine=innodb; + +--echo # +--echo # Bug#22469130: FOREIGN KEY ON DELETE CASCADE NOT ALLOWED +--echo # WHEN A VIRTUAL INDEX EXISTS. + + +--echo # UPDATE CASCADE +CREATE TABLE t1(fld1 INT NOT NULL PRIMARY KEY); +CREATE TABLE t2(fld1 INT NOT NULL, fld2 INT AS (fld1) VIRTUAL, KEY(fld2), + FOREIGN KEY(fld1) REFERENCES t1(fld1) ON UPDATE CASCADE); +INSERT INTO t1 VALUES(1); +INSERT INTO t2 VALUES(1, DEFAULT); +UPDATE t1 SET fld1= 2; +SELECT fld2 FROM t2; +SELECT * FROM t2; +DROP TABLE t2, t1; + +--echo # UPDATE SET NULL +CREATE TABLE t1(fld1 INT NOT NULL, fld2 INT NOT NULL PRIMARY KEY, + KEY(fld1)); +CREATE TABLE t2(fld1 INT, fld2 INT AS (fld1) VIRTUAL, KEY(fld2), + FOREIGN KEY(fld1) REFERENCES t1(fld1) ON UPDATE SET NULL); +INSERT INTO t1 VALUES(1, 2); +INSERT INTO t2 VALUES(1, DEFAULT); +UPDATE t1 SET fld1= 2; +SELECT fld2 FROM t2; +SELECT * FROM t2; +DROP TABLE t2, t1; + +--echo # DELETE CASCADE +CREATE TABLE t1(fld1 INT NOT NULL PRIMARY KEY); +CREATE TABLE t2(fld1 INT, fld2 INT AS (fld1) VIRTUAL, KEY(fld2), + FOREIGN KEY(fld1) REFERENCES t1(fld1) ON DELETE CASCADE); +INSERT INTO t1 VALUES(1); +INSERT INTO t1 VALUES(2); +INSERT INTO t2 VALUES(1, DEFAULT); +INSERT INTO t2 VALUES(2, DEFAULT); +DELETE FROM t1 WHERE fld1= 1; +SELECT fld2 FROM t2; +SELECT * FROM t2; +DROP TABLE t2, t1; + +--echo # DELETE SET NULL +CREATE TABLE t1(fld1 INT NOT NULL, fld2 INT NOT NULL PRIMARY KEY, KEY(fld1)); +CREATE TABLE t2(fld1 INT, fld2 INT AS (fld1) VIRTUAL, KEY(fld2), + FOREIGN KEY(fld1) REFERENCES t1(fld1) ON DELETE SET NULL); +INSERT INTO t1 VALUES(1, 1); +INSERT INTO t1 VALUES(2, 2); +INSERT INTO t2 VALUES(1, DEFAULT); +INSERT INTO t2 VALUES(2, DEFAULT); +DELETE FROM t1 WHERE fld1= 1; +SELECT fld2 FROM t2; +SELECT * FROM t2; +DROP TABLE t2, t1; + +--echo # VIRTUAL INDEX CONTAINS FK CONSTRAINT COLUMN +CREATE TABLE t1(fld1 INT NOT NULL PRIMARY KEY); +CREATE TABLE t2(fld1 INT NOT NULL, fld2 INT, fld3 INT AS (fld2) VIRTUAL, + KEY(fld3, fld1), + FOREIGN KEY(fld1) REFERENCES t1(fld1) ON UPDATE CASCADE); +INSERT INTO t1(fld1) VALUES(1); +INSERT INTO t2(fld1, fld2) VALUES(1, 3); +UPDATE t1 SET fld1= 2; +SELECT fld3, fld1 FROM t2; +SELECT * FROM t2; +DROP TABLE t2, t1; + +--echo # Multiple level of VIRTUAL columns. + +CREATE TABLE t1(fld1 INT NOT NULL PRIMARY KEY); +CREATE TABLE t2(fld1 INT NOT NULL, fld2 INT AS (fld1) VIRTUAL, + fld3 INT AS (fld2) VIRTUAL, KEY(fld3), KEY(fld2), + FOREIGN KEY(fld1) REFERENCES t1(fld1) ON UPDATE CASCADE); +INSERT INTO t1(fld1) VALUES(1); +INSERT INTO t2(fld1) VALUES(1); +UPDATE t1 SET fld1= 2; +SELECT fld2 FROM t2; +SELECT fld3 FROM t2; +SELECT * FROM t2; +DROP TABLE t2, t1; + +--echo # Drop the VIRTUAL INDEX using alter copy ALGORITHM +CREATE TABLE t1(fld1 INT NOT NULL PRIMARY KEY); +CREATE TABLE t2(fld1 INT NOT NULL, fld2 INT AS (fld1) VIRTUAL, KEY vk(fld2), + KEY(fld1), FOREIGN KEY(fld1) REFERENCES t1(fld1) + ON UPDATE CASCADE); +INSERT INTO t1(fld1) VALUES(1); +INSERT INTO t2(fld1) VALUES(1); +UPDATE t1 SET fld1= 2; +SELECT fld2, fld1 FROM t2; +ALTER TABLE t2 DROP INDEX vk, ALGORITHM= COPY; +UPDATE t1 SET fld1= 3; +SELECT fld2, fld1 FROM t2; +DROP TABLE t2, t1; + +--echo # Drop the VIRTUAL INDEX using INPLACE alter ALGORITHM +CREATE TABLE t1(fld1 INT NOT NULL PRIMARY KEY); +CREATE TABLE t2(fld1 INT NOT NULL, fld2 INT AS (fld1) VIRTUAL, + KEY vk(fld2), KEY(fld1), FOREIGN KEY(fld1) REFERENCES t1(fld1) + ON UPDATE CASCADE); +INSERT INTO t1(fld1) VALUES(1); +INSERT INTO t2(fld1) VALUES(1); +UPDATE t1 SET fld1= 2; +SELECT fld2, fld1 FROM t2; +ALTER TABLE t2 DROP INDEX vk, ALGORITHM= COPY; +UPDATE t1 SET fld1= 3; +SELECT fld2, fld1 FROM t2; +DROP TABLE t2, t1; + +--echo # Add the VIRTUAL INDEX using COPY alter ALGORITHM +CREATE TABLE t1(fld1 INT NOT NULL PRIMARY KEY); +CREATE TABLE t2(fld1 INT NOT NULL, fld2 INT AS (fld1) VIRTUAL, + KEY(fld1), FOREIGN KEY(fld1) REFERENCES t1(fld1) + ON UPDATE CASCADE); +INSERT INTO t1(fld1) VALUES(1); +INSERT INTO t2(fld1) VALUES(1); +UPDATE t1 SET fld1= 2; +SELECT fld2, fld1 FROM t2; +ALTER TABLE t2 ADD INDEX vk(fld2), ALGORITHM= COPY; +UPDATE t1 SET fld1= 3; +SELECT fld2, fld1 FROM t2; +DROP TABLE t2, t1; + +--echo # Add the VIRTUAL INDEX using INPLACE alter ALGORITHM +CREATE TABLE t1(fld1 INT NOT NULL PRIMARY KEY); +CREATE TABLE t2(fld1 INT NOT NULL,fld2 INT AS (fld1) VIRTUAL, + KEY(fld1), FOREIGN KEY(fld1) REFERENCES t1(fld1) + ON UPDATE CASCADE); +INSERT INTO t1(fld1) VALUES(1); +INSERT INTO t2(fld1) VALUES(1); +UPDATE t1 SET fld1= 2; +SELECT fld2, fld1 FROM t2; +ALTER TABLE t2 ADD INDEX vk(fld2), ALGORITHM= INPLACE; +UPDATE t1 SET fld1= 3; +SELECT fld2, fld1 FROM t2; +DROP TABLE t2, t1; + +--echo # Drop the VIRTUAL INDEX contains fk constraint column +--echo # using alter copy ALGORITHM +CREATE TABLE t1(fld1 INT NOT NULL PRIMARY KEY); +CREATE TABLE t2(fld1 INT NOT NULL, fld2 INT NOT NULL, + fld3 INT AS (fld2) VIRTUAL, KEY vk(fld3, fld1), + KEY(fld1), FOREIGN KEY(fld1) REFERENCES t1(fld1) + ON UPDATE CASCADE); +INSERT INTO t1(fld1) VALUES(1); +INSERT INTO t2(fld1, fld2) VALUES(1, 2); +UPDATE t1 SET fld1= 2; +SELECT fld3, fld1 FROM t2; +ALTER TABLE t2 DROP INDEX vk, ALGORITHM= COPY; +UPDATE t1 SET fld1= 3; +SELECT fld3, fld1 FROM t2; +DROP TABLE t2, t1; + +--echo # Drop the VIRTUAL INDEX which contains fk constraint column +--echo # using INPLACE alter operation +CREATE TABLE t1(fld1 INT NOT NULL PRIMARY KEY); +CREATE TABLE t2(fld1 INT NOT NULL, fld2 INT NOT NULL, + fld3 INT AS (fld2) VIRTUAL, KEY vk(fld3, fld1), + KEY(fld1), FOREIGN KEY(fld1) REFERENCES t1(fld1) + ON UPDATE CASCADE); +INSERT INTO t1(fld1) VALUES(1); +INSERT INTO t2(fld1, fld2) VALUES(1, 2); +UPDATE t1 SET fld1= 2; +SELECT fld3, fld1 FROM t2; +alter TABLE t2 DROP INDEX vk, ALGORITHM= INPLACE; +UPDATE t1 SET fld1= 3; +SELECT fld3, fld1 FROM t2; +DROP TABLE t2, t1; + +--echo # Add the VIRTUAL INDEX contains fk constraint column +--echo # using copy alter operatiON +CREATE TABLE t1(fld1 INT NOT NULL PRIMARY KEY); +CREATE TABLE t2(fld1 INT NOT NULL, fld2 INT NOT NULL, + fld3 INT AS (fld2) VIRTUAL, KEY(fld1), + FOREIGN KEY(fld1) REFERENCES t1(fld1) ON UPDATE CASCADE); +INSERT INTO t1(fld1) VALUES(1); +INSERT INTO t2(fld1, fld2) VALUES(1, 2); +UPDATE t1 SET fld1= 2; +SELECT fld3, fld1 FROM t2; +alter TABLE t2 ADD INDEX vk(fld3, fld1), ALGORITHM= COPY; +UPDATE t1 SET fld1= 3; +SELECT fld3, fld1 FROM t2; +DROP TABLE t2, t1; + +--echo # Cascading UPDATEs and DELETEs for the multiple +--echo # fk dependent TABLEs + +CREATE TABLE t1(fld1 INT NOT NULL PRIMARY KEY); +CREATE TABLE t2(fld1 INT NOT NULL, fld2 INT AS (fld1) VIRTUAL, + KEY(fld1), KEY(fld2, fld1), + FOREIGN KEY(fld1) REFERENCES t1(fld1) ON UPDATE CASCADE); +CREATE TABLE t3(fld1 INT NOT NULL, fld2 INT AS (fld1) VIRTUAL, + KEY(fld2, fld1), + FOREIGN KEY(fld1) REFERENCES t2(fld1) ON UPDATE CASCADE); +INSERT INTO t1 VALUES(1), (2); +INSERT INTO t2(fld1) VALUES(1), (2); +INSERT INTO t3(fld1) VALUES(1), (2); +UPDATE t1 SET fld1= 4 WHERE fld1= 1; +SELECT fld2, fld1 FROM t2; +SELECT fld2, fld1 FROM t3; +DROP TABLE t3, t2, t1; + +CREATE TABLE t1(fld1 INT NOT NULL PRIMARY KEY); +CREATE TABLE t2(fld1 INT NOT NULL, fld2 INT NOT NULL, + fld3 INT AS (fld2) VIRTUAL, KEY(fld3, fld1), KEY(fld1), + FOREIGN KEY(fld1) REFERENCES t1(fld1) ON UPDATE CASCADE); +CREATE TABLE t3(fld1 INT NOT NULL, fld2 INT NOT NULL, + fld3 INT AS (fld2) VIRTUAL, KEY(fld3, fld1), + FOREIGN KEY(fld1) REFERENCES t2(fld1) ON UPDATE CASCADE); +INSERT INTO t1 VALUES(1), (2); +INSERT INTO t2 VALUES(1, 1, DEFAULT), (2, 2, default); +INSERT INTO t3 VALUES(1, 1, DEFAULT), (2, 2, default); +UPDATE t1 SET fld1= 4 WHERE fld1= 1; +SELECT fld3, fld1 FROM t2; +SELECT fld3, fld1 FROM t3; +DROP TABLE t3, t2, t1; + +CREATE TABLE t1(fld1 INT NOT NULL PRIMARY KEY); +CREATE TABLE t2(fld1 INT NOT NULL, fld2 INT AS (fld1) VIRTUAL, + KEY(fld1), KEY(fld2, fld1), + FOREIGN KEY(fld1) REFERENCES t1(fld1) ON DELETE CASCADE); +CREATE TABLE t3(fld1 INT NOT NULL, fld2 INT AS (fld1) VIRTUAL, + KEY(fld2, fld1), FOREIGN KEY(fld1) REFERENCES t2(fld1) + ON DELETE CASCADE); +INSERT INTO t1 VALUES(1), (2); +INSERT INTO t2(fld1) VALUES(1), (2); +INSERT INTO t3(fld1) VALUES(1), (2); +DELETE FROM t1 WHERE fld1= 1; +SELECT fld2, fld1 FROM t2; +SELECT fld2, fld1 FROM t3; +DROP TABLE t3, t2, t1; + +CREATE TABLE t1(fld1 INT NOT NULL PRIMARY KEY); +CREATE TABLE t2(fld1 INT NOT NULL, fld2 INT NOT NULL, + fld3 INT AS (fld2) VIRTUAL, + KEY(fld3, fld1), KEY(fld1), + FOREIGN KEY(fld1) REFERENCES t1(fld1) + ON DELETE CASCADE); +CREATE TABLE t3(fld1 INT NOT NULL, fld2 INT NOT NULL, + fld3 INT AS (fld2) VIRTUAL, KEY(fld3, fld1), + FOREIGN KEY(fld1) REFERENCES t2(fld1) + ON DELETE CASCADE); +INSERT INTO t1 VALUES(1), (2); +INSERT INTO t2 VALUES(1, 1, DEFAULT), (2, 2, default); +INSERT INTO t3 VALUES(1, 1, DEFAULT), (2, 2, default); +DELETE FROM t1 WHERE fld1= 1; +SELECT fld3, fld1 FROM t2; +SELECT fld3, fld1 FROM t3; +DROP TABLE t3, t2, t1; + +--echo # RENAME TABLE +CREATE TABLE t1(fld1 INT NOT NULL PRIMARY KEY); +CREATE TABLE t2(fld1 INT NOT NULL, + fld2 INT AS (fld1) VIRTUAL, + KEY(fld2, fld1), + FOREIGN KEY(fld1) REFERENCES t1(fld1) + ON DELETE CASCADE); +INSERT INTO t1 VALUES(1), (2); +INSERT INTO t2 VALUES(1, DEFAULT), (2, default); +RENAME TABLE t2 to t3; +DELETE FROM t1 WHERE fld1= 1; +SELECT fld2, fld1 FROM t3; +DROP TABLE t3, t1; + +--echo # FOREIGN_KEY_CHECKS disabled DURING INPLACE ALTER +CREATE TABLE t1(fld1 INT NOT NULL PRIMARY KEY); +CREATE TABLE t2(fld1 INT NOT NULL, + fld2 INT AS (fld1) VIRTUAL, + FOREIGN KEY(fld1) REFERENCES t1(fld1) + ON UPDATE CASCADE); +INSERT INTO t1 VALUES(1), (2); +INSERT INTO t2 VALUES(1, DEFAULT), (2, default); +SET foreign_key_checks = 0; +ALTER TABLE t2 ADD INDEX vk(fld2), ALGORITHM=INPLACE; +SET foreign_key_checks = 1; +UPDATE t1 SET fld1= 3 WHERE fld1= 2; +SELECT fld2 FROM t2; +DROP TABLE t2, t1; + +--echo # GENERATED COLUMN COMPUTATION FAILS when SQL_MODE +--echo # is set to ERROR_FOR_DIVISION_BY_ZERO +CREATE TABLE t1(fld1 INT NOT NULL PRIMARY KEY); +CREATE TABLE t2(fld1 INT NOT NULL, + fld2 INT AS (100/fld1) VIRTUAL, + KEY(fld2), + FOREIGN KEY(fld1) REFERENCES t1(fld1) + ON UPDATE CASCADE); +INSERT INTO t1 VALUES(1), (2); +INSERT INTO t2 VALUES(1, DEFAULT), (2, default); +#--error ER_DIVISION_BY_ZERO +UPDATE t1 SET fld1= 0 WHERE fld1= 2; +SELECT fld2 FROM t2; +DROP TABLE t2, t1; + +--echo # CHANGE SQL_MODE and try the ERROR_FOR_DIVISION_BY_ZERO +SET sql_mode = STRICT_ALL_TABLES; +CREATE TABLE t1(fld1 INT NOT NULL PRIMARY KEY); +CREATE TABLE t2(fld1 INT NOT NULL, + fld2 INT AS (100/fld1) VIRTUAL, + KEY(fld2), + FOREIGN KEY(fld1) REFERENCES t1(fld1) + ON UPDATE CASCADE); +INSERT INTO t1 VALUES(1), (2); +INSERT INTO t2 VALUES(1, DEFAULT), (2, default); +UPDATE t1 SET fld1= 0 WHERE fld1= 2; +SELECT fld2 FROM t2; +SELECT * FROM t2; +DROP TABLE t2, t1; +SET sql_mode = default; + +--echo # ADD FOREIGN CONSTRAINT USING COPY +CREATE TABLE t1(fld1 INT NOT NULL PRIMARY KEY); +CREATE TABLE t2(fld1 INT NOT NULL, + fld2 INT AS (fld1) VIRTUAL, KEY(fld2)); +ALTER TABLE t2 ADD FOREIGN KEY (fld1) + REFERENCES t1(fld1) ON UPDATE CASCADE, + ALGORITHM=copy; +INSERT INTO t1 VALUES(1); +INSERT INTO t2 VALUES(1, DEFAULT); +UPDATE t1 SET fld1= 2; +SELECT fld2 FROM t2; +SELECT * FROM t2; +DROP TABLE t2, t1; + +--echo # ADD FOREIGN CONSTRAINT USING INPLACE +CREATE TABLE t1(fld1 INT NOT NULL PRIMARY KEY); +CREATE TABLE t2(fld1 INT NOT NULL, + fld2 INT AS (fld1) VIRTUAL, KEY(fld2)); +SET foreign_key_checks = 0; +ALTER TABLE t2 ADD FOREIGN KEY (fld1) + REFERENCES t1(fld1) ON UPDATE CASCADE, + ALGORITHM=inplace; +SET foreign_key_checks = 1; +INSERT INTO t1 VALUES(1); +INSERT INTO t2 VALUES(1, DEFAULT); +UPDATE t1 SET fld1= 2; +SELECT fld2 FROM t2; +SELECT * FROM t2; +DROP TABLE t2, t1; + +--echo # DROP FOREIGN CONSTRAINT USING COPY +CREATE TABLE t1(fld1 INT NOT NULL PRIMARY KEY); +CREATE TABLE t2(fld1 INT NOT NULL, + fld2 INT AS (fld1) VIRTUAL, KEY(fld2), + CONSTRAINT fidx FOREIGN KEY (fld1) REFERENCES t1(fld1) + ON UPDATE CASCADE); +INSERT INTO t1 VALUES(1); +INSERT INTO t2 VALUES(1, DEFAULT); +ALTER TABLE t2 DROP FOREIGN KEY fidx, ALGORITHM=COPY; +UPDATE t1 SET fld1= 2; +SELECT fld2 FROM t2; +SELECT * FROM t2; +DROP TABLE t2, t1; + +--echo # DROP FOREIGN CONSTRAINT USING INPLACE +CREATE TABLE t1(fld1 INT NOT NULL PRIMARY KEY); +CREATE TABLE t2(fld1 INT NOT NULL, + fld2 INT AS (fld1) VIRTUAL, KEY(fld2), + CONSTRAINT fidx FOREIGN KEY (fld1) REFERENCES t1(fld1) + ON UPDATE CASCADE); +SET foreign_key_checks = 0; +ALTER TABLE t2 DROP FOREIGN KEY fidx, ALGORITHM=INPLACE; +SET foreign_key_checks = 1; +INSERT INTO t1 VALUES(1); +INSERT INTO t2 VALUES(1, DEFAULT); +UPDATE t1 SET fld1= 2; +SELECT fld2 FROM t2; +SELECT * FROM t2; +DROP TABLE t2, t1; + +--echo # ADD VC INDEX and ADD FK IN SAME COPY ALTER +CREATE TABLE t1(fld1 INT NOT NULL PRIMARY KEY); +CREATE TABLE t2(fld1 INT NOT NULL, + fld2 INT AS (fld1) VIRTUAL); +INSERT INTO t1 VALUES(1); +INSERT INTO t2 VALUES(1, DEFAULT); +ALTER TABLE t2 ADD INDEX(fld2), ADD FOREIGN KEY (fld1) REFERENCES t1(fld1) + ON UPDATE CASCADE, ALGORITHM=copy; +UPDATE t1 SET fld1= 2; +SELECT fld2 FROM t2; +SELECT * FROM t2; +DROP TABLE t2, t1; + +--echo # ADD VC INDEX and ADD FK IN SAME INPLACE ALTER +CREATE TABLE t1(fld1 INT NOT NULL PRIMARY KEY); +CREATE TABLE t2(fld1 INT NOT NULL, + fld2 INT AS (fld1) VIRTUAL); +INSERT INTO t1 VALUES(1); +INSERT INTO t2 VALUES(1, DEFAULT); +SET foreign_key_checks = 0; +ALTER TABLE t2 ADD INDEX(fld2), ADD FOREIGN KEY (fld1) REFERENCES t1(fld1) + ON UPDATE CASCADE, ALGORITHM=inplace; +SET foreign_key_checks = 1; +UPDATE t1 SET fld1= 2; +SELECT fld2 FROM t2; +SELECT * FROM t2; +DROP TABLE t2, t1; + +--echo # ADD VC INDEX and DROP FK IN SAME COPY ALTER +CREATE TABLE t1(fld1 INT NOT NULL PRIMARY KEY); +CREATE TABLE t2(fld1 INT NOT NULL, + fld2 INT AS (fld1) VIRTUAL, + CONSTRAINT fidx FOREIGN KEY(fld1) REFERENCES t1(fld1) + ON UPDATE CASCADE); +INSERT INTO t1 VALUES(1); +INSERT INTO t2 VALUES(1, DEFAULT); +ALTER TABLE t2 ADD INDEX(fld2), DROP FOREIGN KEY fidx, ALGORITHM=copy; +UPDATE t1 SET fld1= 2; +SELECT fld2 FROM t2; +SELECT * FROM t2; +DROP TABLE t2, t1; + +--echo # ADD VC INDEX and DROP FK IN SAME INPLACE ALTER +CREATE TABLE t1(fld1 INT NOT NULL PRIMARY KEY); +CREATE TABLE t2(fld1 INT NOT NULL, + fld2 INT AS (fld1) VIRTUAL, + CONSTRAINT fidx FOREIGN KEY(fld1) REFERENCES t1(fld1) + ON UPDATE CASCADE); +INSERT INTO t1 VALUES(1); +INSERT INTO t2 VALUES(1, DEFAULT); +SET foreign_key_checks = 0; +ALTER TABLE t2 ADD INDEX(fld2), DROP FOREIGN KEY fidx, ALGORITHM=inplace; +SET foreign_key_checks = 1; +UPDATE t1 SET fld1= 2; +SELECT fld2 FROM t2; +SELECT * FROM t2; +DROP TABLE t2, t1; + +--echo # DROP VC INDEX and ADD FK IN SAME COPY ALTER +CREATE TABLE t1(fld1 INT NOT NULL PRIMARY KEY); +CREATE TABLE t2(fld1 INT NOT NULL, + fld2 INT AS (fld1) VIRTUAL, + KEY idx(fld2)); +INSERT INTO t1 VALUES(1); +INSERT INTO t2 VALUES(1, DEFAULT); +ALTER TABLE t2 DROP INDEX idx, ADD FOREIGN KEY (fld1) REFERENCES t1(fld1) + ON UPDATE CASCADE, ALGORITHM=COPY; +UPDATE t1 SET fld1= 2; +SELECT fld2 FROM t2; +SELECT * FROM t2; +DROP TABLE t2, t1; + +--echo # DROP VC INDEX and ADD FK IN SAME INPLACE ALTER +CREATE TABLE t1(fld1 INT NOT NULL PRIMARY KEY); +CREATE TABLE t2(fld1 INT NOT NULL, + fld2 INT AS (fld1) VIRTUAL, + KEY idx(fld2)); +INSERT INTO t1 VALUES(1); +INSERT INTO t2 VALUES(1, DEFAULT); +SET foreign_key_checks = 0; +ALTER TABLE t2 DROP INDEX idx, ADD FOREIGN KEY (fld1) REFERENCES t1(fld1) + ON UPDATE CASCADE, ALGORITHM=INPLACE; +SET foreign_key_checks = 1; +UPDATE t1 SET fld1= 2; +SELECT fld2 FROM t2; +SELECT * FROM t2; +DROP TABLE t2, t1; + +--echo # DROP VC INDEX and DROP FK IN SAME COPY ALTER +CREATE TABLE t1(fld1 INT NOT NULL PRIMARY KEY); +CREATE TABLE t2(fld1 INT NOT NULL, + fld2 INT AS (fld1) VIRTUAL, + KEY idx(fld2), + CONSTRAINT fidx FOREIGN KEY(fld1) REFERENCES t1(fld1) + ON UPDATE CASCADE); +INSERT INTO t1 VALUES(1); +INSERT INTO t2 VALUES(1, DEFAULT); +ALTER TABLE t2 DROP KEY idx, DROP FOREIGN KEY fidx, ALGORITHM=COPY; +UPDATE t1 SET fld1= 2; +SELECT fld2 FROM t2; +SELECT * FROM t2; +DROP TABLE t2, t1; + +--echo # DROP VC INDEX and DROP FK IN SAME INPLACE ALTER +CREATE TABLE t1(fld1 INT NOT NULL PRIMARY KEY); +CREATE TABLE t2(fld1 INT NOT NULL, + fld2 INT AS (fld1) VIRTUAL, + KEY idx(fld2), + CONSTRAINT fidx FOREIGN KEY(fld1) REFERENCES t1(fld1) + ON UPDATE CASCADE); +INSERT INTO t1 VALUES(1); +INSERT INTO t2 VALUES(1, DEFAULT); +SET foreign_key_checks = 0; +ALTER TABLE t2 DROP KEY idx, DROP FOREIGN KEY fidx, ALGORITHM=INPLACE; +SET foreign_key_checks = 1; +UPDATE t1 SET fld1= 2; +SELECT fld2 FROM t2; +SELECT * FROM t2; +DROP TABLE t2, t1; diff --git a/mysql-test/suite/gcol/t/innodb_virtual_fk_restart.test b/mysql-test/suite/gcol/t/innodb_virtual_fk_restart.test new file mode 100644 index 00000000000..61d330036ea --- /dev/null +++ b/mysql-test/suite/gcol/t/innodb_virtual_fk_restart.test @@ -0,0 +1,42 @@ +-- source include/have_innodb.inc +-- source include/not_embedded.inc + +--echo # +--echo # Bug#22469130: FOREIGN KEY ON DELETE CASCADE NOT ALLOWED +--echo # WHEN A VIRTUAL INDEX EXISTS. + +--echo # Add the VIRTUAL INDEX contains fk constraINT column +--echo # using INPLACE alter operatiON +CREATE TABLE t1(fld1 INT NOT NULL PRIMARY KEY) engine=innodb; +CREATE TABLE t2(fld1 INT NOT NULL, fld2 INT NOT NULL, + fld3 INT AS (fld2) VIRTUAL, KEY(fld1), + FOREIGN KEY(fld1) REFERENCES t1(fld1) ON UPDATE CASCADE) engine=innodb; +INSERT INTO t1(fld1) VALUES(1); +INSERT INTO t2(fld1, fld2) VALUES(1, 2); +--source include/restart_mysqld.inc +UPDATE t1 SET fld1= 2; +SELECT fld3, fld1 FROM t2; +alter TABLE t2 ADD INDEX vk(fld3, fld1), ALGORITHM=INPLACE; +UPDATE t1 SET fld1=3; +SELECT fld3, fld1 FROM t2; +DROP TABLE t2, t1; + +--echo # TEMPORARY TABLE NAME and CHILD TABLE NAME are same +CREATE TABLE t1(fld1 INT NOT NULL PRIMARY KEY) engine=innodb; +CREATE TABLE t2(fld1 INT NOT NULL, + fld2 INT AS (fld1) VIRTUAL, + KEY(fld2), + FOREIGN KEY(fld1) REFERENCES t1(fld1) + ON UPDATE CASCADE) engine=innodb; +INSERT INTO t1 VALUES(1), (2); +INSERT INTO t2 VALUES(1, DEFAULT), (2, default); +--source include/restart_mysqld.inc +CREATE TEMPORARY TABLE t2 (fld1 INT NOT NULL)ENGINE=INNODB; +UPDATE t1 SET fld1= 3 WHERE fld1= 2; +--connect(con1,localhost,root,,test) +SELECT fld2 FROM t2; +CHECK TABLE t2; +connection default; +disconnect con1; +DROP TABLE t2; +DROP TABLE t2, t1; diff --git a/mysql-test/suite/gcol/t/innodb_virtual_index.test b/mysql-test/suite/gcol/t/innodb_virtual_index.test new file mode 100644 index 00000000000..4c4cb2a2d05 --- /dev/null +++ b/mysql-test/suite/gcol/t/innodb_virtual_index.test @@ -0,0 +1,220 @@ +--source include/have_innodb.inc + +--echo # +--echo # Bug 21922176 - PREBUILT->SEARCH_TUPLE CREATED WITHOUT INCLUDING +--echo # THE NUMBER OF VIRTUAL COLUMNS +--echo # + +CREATE TABLE t1 (a INT, a1 INT GENERATED ALWAYS AS (a) VIRTUAL, a2 INT +GENERATED ALWAYS AS (a) VIRTUAL, a3 INT GENERATED ALWAYS AS (a) VIRTUAL, a4 +INT GENERATED ALWAYS AS (a) VIRTUAL, a5 INT GENERATED ALWAYS AS (a) VIRTUAL, +a6 INT GENERATED ALWAYS AS (a) VIRTUAL, a7 INT GENERATED ALWAYS AS (a) +VIRTUAL, a8 INT GENERATED ALWAYS AS (a) VIRTUAL, a9 INT GENERATED ALWAYS AS +(a) VIRTUAL, INDEX(a1, a2, a3, a4, a5, a6, a7, a8, a9)) ; + +INSERT INTO t1(a) VALUES(10); + +SELECT * FROM t1 WHERE a1=10 AND a2 = 10 AND a3 =10 AND a4 = 10 AND a5=10 AND +a6=10 AND a7=10 AND a8=10 AND a9=10; + +DROP TABLE t1; + +--echo # +--echo # Bug 22572997 - GCOL:INNODB: FAILING ASSERTION: N < REC_OFFS_N_FIELDS( +--echo # OFFSETS) +--echo # +SET @@SESSION.sql_mode=0; + +CREATE TABLE t1( +c1 int(1)AUTO_INCREMENT, + c2 int(1), + c3 int(1)GENERATED ALWAYS AS ((c2 + c2)) VIRTUAL, + c4 int(1)GENERATED ALWAYS AS ((c3 + c2)) VIRTUAL, + c5 date, + c6 date GENERATED ALWAYS AS((c5 + interval 30 day)) VIRTUAL, + c7 DATE, + c8 time, + c9 DATE GENERATED ALWAYS AS(addtime(c7,c8)) VIRTUAL, + c10 time GENERATED ALWAYS AS(addtime(c7,c8)) VIRTUAL, + c11 DATE GENERATED ALWAYS AS(addtime(c9,c8)) VIRTUAL, + c12 CHAR(1), + c13 CHAR(1)GENERATED ALWAYS AS (concat(c12,c12)) VIRTUAL, + c14 CHAR(2)GENERATED ALWAYS AS (concat(c13,'x')) VIRTUAL, + PRIMARY KEY(c1), + KEY c4_6(c4,c11) +)ENGINE=InnoDB DEFAULT CHARSET=latin1; + +CREATE TABLE t2( + c1 int(1)AUTO_INCREMENT, + c2 int(1), + c3 int(1)GENERATED ALWAYS AS ((c2 + c2)) VIRTUAL, + c4 int(1)GENERATED ALWAYS AS ((c3 + c2)) VIRTUAL, + c5 date, + c6 date GENERATED ALWAYS AS((c5 + interval 30 day)) VIRTUAL, + c6a date GENERATED ALWAYS AS((c6 + interval 30 day)) VIRTUAL, + c7 DATE, + c8 time, + c9 DATE GENERATED ALWAYS AS(addtime(c7,c8)) VIRTUAL, + c10 time GENERATED ALWAYS AS(addtime(c7,c8)) VIRTUAL, + c11 DATE GENERATED ALWAYS AS(addtime(c9,c8)) VIRTUAL, + c11a time GENERATED ALWAYS AS(addtime(c7,c10)) VIRTUAL, + c12 CHAR(1), + c13 CHAR(2)GENERATED ALWAYS AS (concat(c12,c12)) VIRTUAL, + c14 CHAR(4)GENERATED ALWAYS AS (concat(c13,'x')) VIRTUAL, + PRIMARY KEY(c1), + KEY c13(c13), + KEY c4_6(c4,c11) +)ENGINE=InnoDB DEFAULT CHARSET=latin1; +INSERT INTO t2(c1,c2,c5,c7,c8,c12)VALUES (0,0,0,0,0,'v'); + +CREATE TABLE t3( + c1 int(1)AUTO_INCREMENT, + c2 int(1), + c3 int(1)GENERATED ALWAYS AS ((c2 + c2)) VIRTUAL, + c4 int(1)GENERATED ALWAYS AS ((c3 + c2)) VIRTUAL, + c5 date, + c7 DATE, + c8 time, + c9 DATE GENERATED ALWAYS AS(addtime(c7,c8)) VIRTUAL, + c11 DATE GENERATED ALWAYS AS(addtime(c9,c8)) VIRTUAL, + c12 CHAR(1), + PRIMARY KEY(c1), + KEY c4_6(c4,c11) +)ENGINE=InnoDB DEFAULT CHARSET=latin1; +INSERT INTO t3(c1,c2,c5,c7,c8,c12)VALUES +(0,0,0,0,0,'q'),(0,0,0,0,0,'g'),(0,0,0,0,0,'l'),(0,0,0,0,0,1),(0,0,0,0,0,'v'), +(0,1,0,0,0,'c'),(0,0,0,0,0,'x'); + +UPDATE +t2 AS O1,t3 AS O2 +SET O1.c12=1 +WHERE O1.c14 NOT IN +( +SELECT +DISTINCT I1.c14 AS y +FROM t1 AS I1 +ORDER BY I1.c14); + +SET @@SESSION.sql_mode=default; + +DROP TABLE t1, t2, t3; + +--echo # +--echo # Bug 22650296 - ASSERTION IN INNOBASE_BUILD_COL_MAP, ALTER +--echo # +CREATE TABLE `ibstd_08` ( + `nc00577` tinyint(4) DEFAULT NULL, + `nc07844` varchar(41) DEFAULT NULL, + `gc01908` point NOT NULL, + `nc04156` char(17) DEFAULT NULL, + `nc09536` longblob NOT NULL, + `nc09231` decimal(10,0) NOT NULL, + `a` int(11) NOT NULL, + `b` varchar(198) NOT NULL, + `nc04560` mediumtext, + `c` char(187) DEFAULT NULL, + `vbidxcol` char(3) GENERATED ALWAYS AS (substr(`b`,1,3)) VIRTUAL, + `gc00881` polygon NOT NULL, + `nc05121` int(11) NOT NULL DEFAULT '85941481', + KEY `a` (`a`), + KEY `b` (`b`(3),`a`), + KEY `c` (`c`(99),`b`(25)), + KEY `b_2` (`b`(5),`c`(10),`a`), + KEY `vbidxcol` (`vbidxcol`), + KEY `a_2` (`a`,`vbidxcol`), + KEY `vbidxcol_2` (`vbidxcol`), + FULLTEXT KEY `ftsic` (`c`,`b`) +) ENGINE=InnoDB; + + +ALTER TABLE ibstd_08 ADD COLUMN nc07006 BIGINT AUTO_INCREMENT NOT NULL , ADD KEY auto_nc07006(nc07006); + +DROP TABLE ibstd_08; + +--echo # +--echo # Bug 22899305 - GCOLS: FAILING ASSERTION: !(COL->PRTYPE & 256) +--echo # AND SEGFAULT +--echo # +set sql_mode=""; +create table t (a int) engine=innodb; +create table s ( +b int generated always as (1) virtual, +c int, +d int generated always as (1) virtual, +key (d) +) engine=innodb; + +insert into t(a) values ((select d from s for update)); +insert into s(c) values (''); + +SET sql_mode = default; +drop table if exists t,s; + +--echo # +--echo # Bug 23014521 - GCOL:INNODB: FAILING ASSERTION: !IS_V +--echo # +CREATE TABLE t1 ( + col1 int(11) NOT NULL, + col2 int(11) DEFAULT NULL, + col3 int(11) NOT NULL, + col4 int(11) DEFAULT NULL, + col5 int(11) GENERATED ALWAYS AS ((col1 % col4)) VIRTUAL, + col6 int(11) GENERATED ALWAYS AS ((col2 - col4)) VIRTUAL, + col5x int(11) GENERATED ALWAYS AS ((col3 / col2)) VIRTUAL, + col6b varchar(20) GENERATED ALWAYS AS (col2) VIRTUAL, + col6x int(11) GENERATED ALWAYS AS ((col2 % col1)) VIRTUAL, + col7 int(11) GENERATED ALWAYS AS ((col6x + col5x)) VIRTUAL, + col8 int(11) GENERATED ALWAYS AS ((col5x / col5)) VIRTUAL, + col7x int(11) GENERATED ALWAYS AS ((col5x + col5)) VIRTUAL, + col8x int(11) GENERATED ALWAYS AS ((col5 / col5x)) VIRTUAL, + col9 text, + col2b varchar(20) GENERATED ALWAYS AS (col4) VIRTUAL, + col8a int(11) GENERATED ALWAYS AS (col2) VIRTUAL, + col4b varchar(20) GENERATED ALWAYS AS (col4) VIRTUAL, + col1c int(11) GENERATED ALWAYS AS ((col2 * col1)) VIRTUAL, + extra int(11) DEFAULT NULL, + col5c int(11) GENERATED ALWAYS AS ((col1 / col1)) VIRTUAL, + col6a bigint(20) GENERATED ALWAYS AS ((col3 / col1)) VIRTUAL, + col1a varchar(20) GENERATED ALWAYS AS (col6) VIRTUAL, + col6c int(11) GENERATED ALWAYS AS ((col2 % col2)) VIRTUAL, + col7c bigint(20) GENERATED ALWAYS AS ((col2 / col1)) VIRTUAL, + col2c int(11) GENERATED ALWAYS AS ((col5 % col5)) VIRTUAL, + col1b int(11) GENERATED ALWAYS AS ((col1 / col2)) VIRTUAL, + col3b bigint(20) GENERATED ALWAYS AS ((col6x % col6)) VIRTUAL, + UNIQUE KEY idx7 (col1,col3,col2), + UNIQUE KEY uidx (col9(10)), + KEY idx15 (col9(10) DESC,col2 DESC), + KEY idx10 (col9(10) DESC,col1 DESC), + KEY idx11 (col6x DESC), + KEY idx6 (col9(10) DESC,col7 DESC), + KEY idx14 (col6 DESC) + ) ENGINE=InnoDB DEFAULT CHARSET=latin1; + +# Cannot add virtual column along with create FULLTEXT index with +# adding a hidden FTS_DOC_ID column (which require a table rebuild) +--error ER_ALTER_OPERATION_NOT_SUPPORTED_REASON +ALTER TABLE t1 ADD COLUMN col7a INT GENERATED ALWAYS AS (col5x % col6x) +VIRTUAL, ADD FULLTEXT KEY ftidx ( col9 ), algorithm=inplace; + +# This will add a hidden FTS_DOC_ID column +CREATE FULLTEXT INDEX idx ON t1(col9); + +# Since there is no table rebuild needed, now the alter would be sucessful +ALTER TABLE t1 ADD COLUMN col7a INT GENERATED ALWAYS AS (col5x % col6x) +VIRTUAL, ADD FULLTEXT KEY ftidx ( col9 ), algorithm=inplace; + +DROP TABLE t1; + +CREATE TABLE t1 ( + col1 int(11) NOT NULL, + col2 int(11) DEFAULT NULL, + col3 int(11) NOT NULL, + col4 int(11) DEFAULT NULL) engine=innodb; + +# This secondary key idx will be coverted to a new Primary Key, thus a table +# rebuild. It is blocked since there is an adding of virtual columns +--error ER_ALTER_OPERATION_NOT_SUPPORTED_REASON +ALTER TABLE t1 ADD COLUMN col7a INT GENERATED ALWAYS AS (col1 % col2) +VIRTUAL, ADD UNIQUE index idx (col1), algorithm=inplace; + +DROP TABLE t1; diff --git a/mysql-test/suite/gcol/t/innodb_virtual_purge.test b/mysql-test/suite/gcol/t/innodb_virtual_purge.test new file mode 100644 index 00000000000..f9fd02d970b --- /dev/null +++ b/mysql-test/suite/gcol/t/innodb_virtual_purge.test @@ -0,0 +1,138 @@ +--source include/have_innodb.inc +--source include/count_sessions.inc + +--echo # +--echo # Bug#21869656 UNDO LOG DOES NOT CONTAIN ENOUGH INFORMATION +--echo # ON INDEXED VIRTUAL COLUMNS +--echo # + +CREATE TABLE t1 (a INT, b INT, + a1 INT GENERATED ALWAYS AS (a) VIRTUAL, INDEX(a1) +) ENGINE=InnoDB; + +INSERT INTO t1 (a,b) VALUES(1,1); + +connect (con1,localhost,root,,); +# disable purge +CREATE TABLE t0 (a INT) ENGINE=InnoDB; +BEGIN; SELECT * FROM t0; + +connection default; +# write the problematic update_undo log record +UPDATE t1 SET a=0; + +ALTER TABLE t1 DROP COLUMN a1, ALGORITHM=INPLACE; +ALTER TABLE t1 ADD COLUMN b1 INT GENERATED ALWAYS AS (b) VIRTUAL, ADD +INDEX(b1), +ALGORITHM=INPLACE; + +connection con1; +# enable purge +COMMIT; +UPDATE t1 SET a=1; + +connection default; +# wait for purge to process the update_undo record. +--source include/wait_innodb_all_purged.inc + +CHECK TABLE t1; +SELECT b1 FROM t1; + + +# Create multi-virtual column, more ADD/DROP to test it +ALTER TABLE t1 +ADD COLUMN a1 INT GENERATED ALWAYS AS (a) VIRTUAL, +ADD COLUMN a2 INT GENERATED ALWAYS AS (a + b) VIRTUAL, +ADD COLUMN a3 INT GENERATED ALWAYS AS (a - b) VIRTUAL, +ADD COLUMN a4 INT GENERATED ALWAYS AS (a - b) VIRTUAL, +ADD INDEX(a1), ADD INDEX(a2), ADD INDEX(a3), ALGORITHM=INPLACE; + +CREATE TABLE t2 ( + a BLOB, + b BLOB, + c BLOB GENERATED ALWAYS AS (CONCAT(a,b)) VIRTUAL, + h VARCHAR(10) DEFAULT NULL +) ENGINE=InnoDB; + +INSERT INTO t2 VALUES (REPEAT('g', 16000), REPEAT('x', 16000), DEFAULT, 'kk'); + +INSERT INTO t2 VALUES (REPEAT('a', 16000), REPEAT('b', 16000), DEFAULT, 'mm'); + +CREATE INDEX idx ON t2(c(100)); + +INSERT INTO t1 (a, b) VALUES(1,1); + +connection con1; +# disable purge +BEGIN; SELECT * FROM t0; + +connection default; +--enable_info + +# write the problematic update_undo log record +UPDATE t1 SET a=0; +UPDATE t1 SET b=0; + +ALTER TABLE t1 DROP COLUMN a3, ALGORITHM=INPLACE; + +UPDATE t1 SET a=2; +ALTER TABLE t1 DROP COLUMN a2, ALGORITHM=INPLACE; +UPDATE t1 SET b=3; + +ALTER TABLE t1 ADD COLUMN b2 INT GENERATED ALWAYS AS (b) VIRTUAL, +ADD INDEX(b2), ALGORITHM=INPLACE; +UPDATE t1 SET b=9; + +ALTER TABLE t1 ADD COLUMN b3 INT GENERATED ALWAYS AS (a) VIRTUAL, +ADD INDEX(b3), ALGORITHM=INPLACE; + +UPDATE t1 SET b=10; + +ALTER TABLE t2 DROP COLUMN c; + +UPDATE t2 SET a = REPEAT('s', 6000) WHERE a like 'aaa%'; + +ALTER TABLE t2 ADD COLUMN x1 BLOB GENERATED ALWAYS AS (CONCAT(a,b)) VIRTUAL, +ADD COLUMN x2 BLOB GENERATED ALWAYS AS (CONCAT(a,b)) VIRTUAL, +ADD INDEX(x1(100), x2(120)), ADD INDEX (x1(20)); + +UPDATE t1 SET a=5; + +UPDATE t2 SET a = REPEAT('m', 16000) WHERE a like 'sss%'; + +ALTER TABLE t1 DROP COLUMN b2, ALGORITHM=INPLACE; + +UPDATE t1 SET a=6; + +ALTER TABLE t2 DROP COLUMN x1, DROP COLUMN x2, ALGORITHM=INPLACE; + +UPDATE t2 SET a = REPEAT('x', 1000) WHERE a like 'mmm%'; + +ALTER TABLE t1 DROP INDEX b3; +UPDATE t1 SET a=100; +--disable_info + +connection con1; +# enable purge +COMMIT; +disconnect con1; + +connection default; +# wait for purge to process the update_undo record. +--source include/wait_innodb_all_purged.inc + +CHECK TABLE t1; +SELECT b1 FROM t1; + +SELECT * FROM t1; +CHECK TABLE t2; +DROP TABLE t2, t1, t0; + +CREATE TABLE t1 (a VARCHAR(30), b INT, a2 VARCHAR(30) GENERATED ALWAYS AS (a) VIRTUAL); + +--error ER_DUP_FIELDNAME +CREATE INDEX idx ON t1(a2(10), b, a2(20)); + +DROP TABLE t1; + +--source include/wait_until_count_sessions.inc diff --git a/mysql-test/suite/gcol/t/innodb_wl8114.test b/mysql-test/suite/gcol/t/innodb_wl8114.test new file mode 100644 index 00000000000..bed8375328c --- /dev/null +++ b/mysql-test/suite/gcol/t/innodb_wl8114.test @@ -0,0 +1,42 @@ +--source include/have_innodb.inc + +# Test alter table add column +CREATE TABLE t_8114 (a int) ENGINE = INNODB; + +ALTER TABLE t_8114 ADD b INT GENERATED ALWAYS AS (a) VIRTUAL; + +SELECT NAME FROM INFORMATION_SCHEMA.INNODB_SYS_TABLES WHERE NAME LIKE "%t_8114"; + +SELECT NAME, POS, MTYPE, PRTYPE, LEN FROM INFORMATION_SCHEMA.INNODB_SYS_COLUMNS WHERE TABLE_ID IN (SELECT TABLE_ID FROM INFORMATION_SCHEMA.INNODB_SYS_TABLES WHERE NAME LIKE "%t_8114"); + +INSERT INTO t_8114 VALUES (9, default); +INSERT INTO t_8114 VALUES (3, default); +INSERT INTO t_8114 VALUES (1, default); +INSERT INTO t_8114 VALUES (5, default); + +SELECT * FROM t_8114; + +DROP TABLE t_8114; + +CREATE TABLE t_8114 (Column_1 CHAR(5) GENERATED ALWAYS AS (PI()+5), Column_2 CHAR(5)) engine=innodb; + +SELECT NAME, FLAG, N_COLS FROM INFORMATION_SCHEMA.INNODB_SYS_TABLES WHERE NAME LIKE "%t_8114"; + +SELECT NAME, POS, MTYPE, PRTYPE, LEN FROM INFORMATION_SCHEMA.INNODB_SYS_COLUMNS WHERE TABLE_ID IN (SELECT TABLE_ID FROM INFORMATION_SCHEMA.INNODB_SYS_TABLES WHERE NAME LIKE "%t_8114"); + +INSERT INTO t_8114 VALUES (default, "aa"); +INSERT INTO t_8114 VALUES (default, "bb"); +INSERT INTO t_8114 VALUES (default, "ee"); +INSERT INTO t_8114 VALUES (default, "pp"); + +SELECT * FROM t_8114; + +ALTER TABLE t_8114 DROP Column_1; + +SELECT NAME FROM INFORMATION_SCHEMA.INNODB_SYS_TABLES WHERE NAME LIKE "%t_8114"; + +SELECT NAME, POS, MTYPE, PRTYPE, LEN FROM INFORMATION_SCHEMA.INNODB_SYS_COLUMNS WHERE TABLE_ID IN (SELECT TABLE_ID FROM INFORMATION_SCHEMA.INNODB_SYS_TABLES WHERE NAME LIKE "%t_8114"); + +SELECT * FROM t_8114; + +DROP TABLE t_8114; diff --git a/mysql-test/suite/gcol/t/main_alter_table.test b/mysql-test/suite/gcol/t/main_alter_table.test new file mode 100644 index 00000000000..bbd87350cb1 --- /dev/null +++ b/mysql-test/suite/gcol/t/main_alter_table.test @@ -0,0 +1,50 @@ +--source include/have_innodb.inc + +--echo # +--echo # Bug#22017616: ASSERTION FAILED: TABLE_SHARE->IS_MISSING_PRIMARY_KEY() +--echo # == M_PREBUILT->CLUST_IND +--echo # +--echo # Ensure that adding indexes with virtual columns are not promoted to +--echo # primary keys +--echo # +--echo # Base line with normal column - should be promoted +CREATE TABLE t0(a INT NOT NULL) ENGINE=INNODB; +ALTER TABLE t0 ADD UNIQUE INDEX (a); + +--echo # Case a: Create table with virtual unique not null column +CREATE TABLE t1(a POINT GENERATED ALWAYS AS (POINT(1,1)) VIRTUAL UNIQUE) ENGINE=INNODB; +SELECT * FROM t1; + +--echo # Case b: Create table with index on virtual point column +CREATE TABLE t2(a POINT GENERATED ALWAYS AS (POINT(1,1)) VIRTUAL, UNIQUE INDEX no_pk(a(1))) ENGINE=INNODB; +SELECT * FROM t2; + +--echo # Case c: Add unique index on virtual point column +CREATE TABLE t3(a POINT GENERATED ALWAYS AS (POINT(1,1)) VIRTUAL) +ENGINE=INNODB; +ALTER TABLE t3 ADD UNIQUE INDEX (a(1)); +SELECT * FROM t3; + +--echo # Case d: Add unique index on virtual blob column +CREATE TABLE t4 (a BLOB, b BLOB GENERATED ALWAYS AS (a) VIRTUAL) ENGINE=INNODB; +ALTER TABLE t4 ADD UNIQUE INDEX (b(1)); +SELECT * FROM t4; + +--echo # Query I_S to verify that 'a' is promoted to pk only when it +--echo # isn't virtual +SELECT T.NAME AS TABLE_NAME, I.NAME AS INDEX_NAME, + CASE (I.TYPE & 3) + WHEN 3 THEN "yes" + ELSE "no" END AS IS_PRIMARY_KEY, + F.NAME AS FIELD_NAME, F.POS AS FIELD_POS FROM + INFORMATION_SCHEMA.INNODB_SYS_TABLES AS T JOIN + INFORMATION_SCHEMA.INNODB_SYS_INDEXES AS I JOIN + INFORMATION_SCHEMA.INNODB_SYS_FIELDS AS F + ON I.INDEX_ID = F.INDEX_ID AND I.TABLE_ID = T.TABLE_ID + WHERE T.NAME LIKE 'test/%'; + +DROP TABLE t0; +DROP TABLE t1; +DROP TABLE t2; +DROP TABLE t3; +DROP TABLE t4; diff --git a/mysql-test/suite/gcol/t/main_mysqldump.test b/mysql-test/suite/gcol/t/main_mysqldump.test new file mode 100644 index 00000000000..c2b4efd09c3 --- /dev/null +++ b/mysql-test/suite/gcol/t/main_mysqldump.test @@ -0,0 +1,44 @@ +--source include/have_innodb.inc +--source include/not_embedded.inc + +CREATE DATABASE dump_generated; +USE dump_generated; +CREATE TABLE t1 (pk INTEGER, a INTEGER, b INTEGER, c VARCHAR(16), + sum INTEGER GENERATED ALWAYS AS (a+b), + sub VARCHAR(4) GENERATED ALWAYS AS (SUBSTRING(c, 1, 4)), + key k1(sum), + key k2(sub) +) engine=innodb; +INSERT INTO t1(pk, a, b, c) VALUES (1, 11, 12, 'oneone'), (2, 21, 22, 'twotwo'); +SELECT * FROM t1; +--exec $MYSQL_DUMP dump_generated t1 > $MYSQLTEST_VARDIR/tmp/t1.sql +DELETE FROM t1; +--exec $MYSQL dump_generated < $MYSQLTEST_VARDIR/tmp/t1.sql +SELECT * FROM t1; +--exec $MYSQL_DUMP dump_generated t1 --tab=$MYSQLTEST_VARDIR/tmp/ +DELETE FROM t1; +--replace_result $MYSQLTEST_VARDIR MYSQLTEST_VARDIR +--eval LOAD DATA INFILE '$MYSQLTEST_VARDIR/tmp/t1.txt' INTO TABLE t1 +SELECT * FROM t1; +DROP TABLE t1; + +--echo # A table with regular columns after generated +CREATE TABLE t2 (pk INTEGER, a INTEGER, b INTEGER, + sum INTEGER GENERATED ALWAYS AS (a+b), + c VARCHAR(16), + key k1(sum) +) engine=innodb; +INSERT INTO t2(pk, a, b, c) VALUES (1, 11, 12, 'oneone'), (2, 21, 22, 'twotwo'); +SELECT * FROM t2; +--exec $MYSQL_DUMP dump_generated t2 > $MYSQLTEST_VARDIR/tmp/t2.sql +DELETE FROM t2; +--exec $MYSQL dump_generated < $MYSQLTEST_VARDIR/tmp/t2.sql +SELECT * FROM t2; +--exec $MYSQL_DUMP dump_generated t2 --tab=$MYSQLTEST_VARDIR/tmp/ +DELETE FROM t2; +--replace_result $MYSQLTEST_VARDIR MYSQLTEST_VARDIR +--eval LOAD DATA INFILE '$MYSQLTEST_VARDIR/tmp/t2.txt' INTO TABLE t2 +SELECT * FROM t2; +DROP TABLE t2; + +DROP DATABASE dump_generated; diff --git a/mysql-test/suite/innodb/r/innodb_bug12400341.result b/mysql-test/suite/innodb/r/innodb_bug12400341.result index 3bb786c4654..b402af84231 100644 --- a/mysql-test/suite/innodb/r/innodb_bug12400341.result +++ b/mysql-test/suite/innodb/r/innodb_bug12400341.result @@ -14,17 +14,17 @@ innodb_file_per_table ON drop database if exists mysqltest; create database mysqltest; CREATE TABLE mysqltest.transtable (id int unsigned NOT NULL PRIMARY KEY, val int DEFAULT 0) ENGINE=InnoDB; -select count(*) from information_schema.processlist; +select count(*) from information_schema.processlist where command != 'Daemon'; count(*) 33 connection default; CREATE TABLE mysqltest.testtable (id int unsigned not null primary key) ENGINE=InnoDB; ERROR HY000: Can't create table `mysqltest`.`testtable` (errno: 177 "Too many active concurrent transactions") -select count(*) from information_schema.processlist; +select count(*) from information_schema.processlist where command != 'Daemon'; count(*) 33 connection default; -select count(*) from information_schema.processlist; +select count(*) from information_schema.processlist where command != 'Daemon'; count(*) 33 drop database mysqltest; diff --git a/mysql-test/suite/innodb/t/innodb_bug12400341.test b/mysql-test/suite/innodb/t/innodb_bug12400341.test index 9a96f29fc3b..2cacefc6595 100644 --- a/mysql-test/suite/innodb/t/innodb_bug12400341.test +++ b/mysql-test/suite/innodb/t/innodb_bug12400341.test @@ -59,7 +59,7 @@ while ($c) } --enable_query_log -select count(*) from information_schema.processlist; +select count(*) from information_schema.processlist where command != 'Daemon'; # # fill the all undo slots @@ -80,7 +80,7 @@ connection default; --error ER_CANT_CREATE_TABLE CREATE TABLE mysqltest.testtable (id int unsigned not null primary key) ENGINE=InnoDB; -select count(*) from information_schema.processlist; +select count(*) from information_schema.processlist where command != 'Daemon'; --disable_query_log let $c = 32; @@ -93,7 +93,7 @@ while ($c) --enable_query_log connection default; -select count(*) from information_schema.processlist; +select count(*) from information_schema.processlist where command != 'Daemon'; --disable_query_log let $c = 32; diff --git a/mysql-test/suite/perfschema/r/threads_innodb.result b/mysql-test/suite/perfschema/r/threads_innodb.result index 3fb469ad00b..2229d972038 100644 --- a/mysql-test/suite/perfschema/r/threads_innodb.result +++ b/mysql-test/suite/perfschema/r/threads_innodb.result @@ -15,3 +15,4 @@ thread/innodb/srv_lock_timeout_thread BACKGROUND NULL NULL NULL NULL NULL NULL N thread/innodb/srv_master_thread BACKGROUND NULL NULL NULL NULL NULL NULL NULL NULL NULL YES thread/innodb/srv_monitor_thread BACKGROUND NULL NULL NULL NULL NULL NULL NULL NULL NULL YES thread/innodb/srv_purge_thread BACKGROUND NULL NULL NULL NULL NULL NULL NULL NULL NULL YES +thread/innodb/thd_destructor_thread BACKGROUND NULL NULL NULL NULL NULL NULL NULL 1 NULL YES diff --git a/mysql-test/suite/vcol/r/vcol_keys_innodb.result b/mysql-test/suite/vcol/r/vcol_keys_innodb.result index 6c7429b2a03..79450d41684 100644 --- a/mysql-test/suite/vcol/r/vcol_keys_innodb.result +++ b/mysql-test/suite/vcol/r/vcol_keys_innodb.result @@ -7,7 +7,7 @@ SET @@session.storage_engine = 'InnoDB'; # - CHECK (allowed but not used) # UNIQUE create table t1 (a int, b int as (a*2) unique); -ERROR HY000: Key/Index cannot be defined on a non-stored computed column +drop table t1; create table t1 (a int, b int as (a*2) persistent unique); show create table t1; Table Create Table @@ -22,7 +22,7 @@ a int(11) YES NULL b int(11) YES UNI NULL PERSISTENT drop table t1; create table t1 (a int, b int as (a*2), unique key (b)); -ERROR HY000: Key/Index cannot be defined on a non-stored computed column +drop table t1; create table t1 (a int, b int as (a*2) persistent, unique (b)); show create table t1; Table Create Table @@ -38,7 +38,6 @@ b int(11) YES UNI NULL PERSISTENT drop table t1; create table t1 (a int, b int as (a*2)); alter table t1 add unique key (b); -ERROR HY000: Key/Index cannot be defined on a non-stored computed column drop table t1; create table t1 (a int, b int as (a*2) persistent); alter table t1 add unique key (b); @@ -50,9 +49,9 @@ drop table t1; # # INDEX create table t1 (a int, b int as (a*2), index (b)); -ERROR HY000: Key/Index cannot be defined on a non-stored computed column +drop table t1; create table t1 (a int, b int as (a*2), index (a,b)); -ERROR HY000: Key/Index cannot be defined on a non-stored computed column +drop table t1; create table t1 (a int, b int as (a*2) persistent, index (b)); show create table t1; Table Create Table @@ -81,9 +80,7 @@ b int(11) YES NULL PERSISTENT drop table t1; create table t1 (a int, b int as (a*2)); alter table t1 add index (b); -ERROR HY000: Key/Index cannot be defined on a non-stored computed column alter table t1 add index (a,b); -ERROR HY000: Key/Index cannot be defined on a non-stored computed column drop table t1; create table t1 (a int, b int as (a*2) persistent); alter table t1 add index (b); @@ -125,12 +122,11 @@ ERROR HY000: Cannot define foreign key with ON UPDATE CASCADE clause on a comput alter table t1 add foreign key (b) references t2(a) on delete set null; ERROR HY000: Cannot define foreign key with ON DELETE SET NULL clause on a computed column drop table t1; -create table t1 (a int, b int as (a+1), -foreign key (b) references t2(a)); -ERROR HY000: Key/Index cannot be defined on a non-stored computed column +create table t1 (a int, b int as (a+1), foreign key (b) references t2(a)); +ERROR HY000: Can't create table `test`.`t1` (errno: 150 "Foreign key constraint is incorrectly formed") create table t1 (a int, b int as (a+1)); alter table t1 add foreign key (b) references t2(a); -ERROR HY000: Key/Index cannot be defined on a non-stored computed column +ERROR HY000: Can't create table `test`.`#sql-temporary` (errno: 150 "Foreign key constraint is incorrectly formed") drop table t1; # Allowed FK options. create table t2 (a int primary key, b char(5)); diff --git a/mysql-test/suite/vcol/t/vcol_keys_innodb.test b/mysql-test/suite/vcol/t/vcol_keys_innodb.test index 34efc6e1f30..8eeef96b43f 100644 --- a/mysql-test/suite/vcol/t/vcol_keys_innodb.test +++ b/mysql-test/suite/vcol/t/vcol_keys_innodb.test @@ -41,6 +41,7 @@ SET @@session.storage_engine = 'InnoDB'; #------------------------------------------------------------------------------# # Execute the tests to be applied to all storage engines +let $with_foreign_keys = 1; --source suite/vcol/inc/vcol_keys.inc #------------------------------------------------------------------------------# diff --git a/sql/handler.cc b/sql/handler.cc index 4155057ebe8..37e60f5c9bd 100644 --- a/sql/handler.cc +++ b/sql/handler.cc @@ -4242,6 +4242,7 @@ handler::check_if_supported_inplace_alter(TABLE *altered_table, Alter_inplace_info::ALTER_COLUMN_OPTION | Alter_inplace_info::CHANGE_CREATE_OPTION | Alter_inplace_info::ALTER_PARTITIONED | + Alter_inplace_info::ALTER_VIRTUAL_GCOL_EXPR | Alter_inplace_info::ALTER_RENAME; /* Is there at least one operation that requires copy algorithm? */ diff --git a/sql/handler.h b/sql/handler.h index 112b9212e93..d7fa5061e87 100644 --- a/sql/handler.h +++ b/sql/handler.h @@ -1838,34 +1838,50 @@ public: typedef ulonglong HA_ALTER_FLAGS; // Add non-unique, non-primary index - static const HA_ALTER_FLAGS ADD_INDEX = 1L << 0; + static const HA_ALTER_FLAGS ADD_INDEX = 1ULL << 0; + // + // Adds a spatial index. At the moment all engines treat it + // identically to the ADD_INDEX, so it gets the same code + static const HA_ALTER_FLAGS ADD_SPATIAL_INDEX = ADD_INDEX; // Drop non-unique, non-primary index - static const HA_ALTER_FLAGS DROP_INDEX = 1L << 1; + static const HA_ALTER_FLAGS DROP_INDEX = 1ULL << 1; // Add unique, non-primary index - static const HA_ALTER_FLAGS ADD_UNIQUE_INDEX = 1L << 2; + static const HA_ALTER_FLAGS ADD_UNIQUE_INDEX = 1ULL << 2; // Drop unique, non-primary index - static const HA_ALTER_FLAGS DROP_UNIQUE_INDEX = 1L << 3; + static const HA_ALTER_FLAGS DROP_UNIQUE_INDEX = 1ULL << 3; // Add primary index - static const HA_ALTER_FLAGS ADD_PK_INDEX = 1L << 4; + static const HA_ALTER_FLAGS ADD_PK_INDEX = 1ULL << 4; // Drop primary index - static const HA_ALTER_FLAGS DROP_PK_INDEX = 1L << 5; + static const HA_ALTER_FLAGS DROP_PK_INDEX = 1ULL << 5; - // Add column - static const HA_ALTER_FLAGS ADD_COLUMN = 1L << 6; + // Virtual generated column + static const HA_ALTER_FLAGS ADD_VIRTUAL_COLUMN = 1ULL << 6; + // Stored base (non-generated) column + static const HA_ALTER_FLAGS ADD_STORED_BASE_COLUMN = 1ULL << 7; + // Stored generated column + static const HA_ALTER_FLAGS ADD_STORED_GENERATED_COLUMN= 1ULL << 8; + // Add generic column (convience constant). + static const HA_ALTER_FLAGS ADD_COLUMN= ADD_VIRTUAL_COLUMN | + ADD_STORED_BASE_COLUMN | + ADD_STORED_GENERATED_COLUMN; // Drop column - static const HA_ALTER_FLAGS DROP_COLUMN = 1L << 7; + static const HA_ALTER_FLAGS DROP_VIRTUAL_COLUMN = 1ULL << 9; + static const HA_ALTER_FLAGS DROP_STORED_COLUMN = 1ULL << 10; + static const HA_ALTER_FLAGS DROP_COLUMN= DROP_VIRTUAL_COLUMN | + DROP_STORED_COLUMN; // Rename column - static const HA_ALTER_FLAGS ALTER_COLUMN_NAME = 1L << 8; + static const HA_ALTER_FLAGS ALTER_COLUMN_NAME = 1ULL << 11; // Change column datatype - static const HA_ALTER_FLAGS ALTER_COLUMN_TYPE = 1L << 9; + static const HA_ALTER_FLAGS ALTER_VIRTUAL_COLUMN_TYPE = 1ULL << 12; + static const HA_ALTER_FLAGS ALTER_STORED_COLUMN_TYPE = 1ULL << 13; /** Change column datatype in such way that new type has compatible @@ -1873,83 +1889,94 @@ public: possible to perform change by only updating data dictionary without changing table rows. */ - static const HA_ALTER_FLAGS ALTER_COLUMN_EQUAL_PACK_LENGTH = 1L << 10; + static const HA_ALTER_FLAGS ALTER_COLUMN_EQUAL_PACK_LENGTH = 1ULL << 14; // Reorder column - static const HA_ALTER_FLAGS ALTER_COLUMN_ORDER = 1L << 11; + static const HA_ALTER_FLAGS ALTER_STORED_COLUMN_ORDER = 1ULL << 15; + + // Reorder column + static const HA_ALTER_FLAGS ALTER_VIRTUAL_COLUMN_ORDER = 1ULL << 16; // Change column from NOT NULL to NULL - static const HA_ALTER_FLAGS ALTER_COLUMN_NULLABLE = 1L << 12; + static const HA_ALTER_FLAGS ALTER_COLUMN_NULLABLE = 1ULL << 17; // Change column from NULL to NOT NULL - static const HA_ALTER_FLAGS ALTER_COLUMN_NOT_NULLABLE = 1L << 13; + static const HA_ALTER_FLAGS ALTER_COLUMN_NOT_NULLABLE = 1ULL << 18; // Set or remove default column value - static const HA_ALTER_FLAGS ALTER_COLUMN_DEFAULT = 1L << 14; + static const HA_ALTER_FLAGS ALTER_COLUMN_DEFAULT = 1ULL << 19; + // Change column generation expression + static const HA_ALTER_FLAGS ALTER_VIRTUAL_GCOL_EXPR = 1ULL << 20; + static const HA_ALTER_FLAGS ALTER_STORED_GCOL_EXPR = 1ULL << 21; + // // Add foreign key - static const HA_ALTER_FLAGS ADD_FOREIGN_KEY = 1L << 15; + static const HA_ALTER_FLAGS ADD_FOREIGN_KEY = 1ULL << 22; // Drop foreign key - static const HA_ALTER_FLAGS DROP_FOREIGN_KEY = 1L << 16; + static const HA_ALTER_FLAGS DROP_FOREIGN_KEY = 1ULL << 23; // table_options changed, see HA_CREATE_INFO::used_fields for details. - static const HA_ALTER_FLAGS CHANGE_CREATE_OPTION = 1L << 17; + static const HA_ALTER_FLAGS CHANGE_CREATE_OPTION = 1ULL << 24; // Table is renamed - static const HA_ALTER_FLAGS ALTER_RENAME = 1L << 18; + static const HA_ALTER_FLAGS ALTER_RENAME = 1ULL << 25; // column's engine options changed, something in field->option_struct - static const HA_ALTER_FLAGS ALTER_COLUMN_OPTION = 1L << 19; + static const HA_ALTER_FLAGS ALTER_COLUMN_OPTION = 1ULL << 26; // MySQL alias for the same thing: - static const HA_ALTER_FLAGS ALTER_COLUMN_STORAGE_TYPE = 1L << 19; + static const HA_ALTER_FLAGS ALTER_COLUMN_STORAGE_TYPE = 1ULL << 26; // Change the column format of column - static const HA_ALTER_FLAGS ALTER_COLUMN_COLUMN_FORMAT = 1L << 20; + static const HA_ALTER_FLAGS ALTER_COLUMN_COLUMN_FORMAT = 1ULL << 27; // Add partition - static const HA_ALTER_FLAGS ADD_PARTITION = 1L << 21; + static const HA_ALTER_FLAGS ADD_PARTITION = 1ULL << 28; // Drop partition - static const HA_ALTER_FLAGS DROP_PARTITION = 1L << 22; + static const HA_ALTER_FLAGS DROP_PARTITION = 1ULL << 29; // Changing partition options - static const HA_ALTER_FLAGS ALTER_PARTITION = 1L << 23; + static const HA_ALTER_FLAGS ALTER_PARTITION = 1ULL << 30; // Coalesce partition - static const HA_ALTER_FLAGS COALESCE_PARTITION = 1L << 24; + static const HA_ALTER_FLAGS COALESCE_PARTITION = 1ULL << 31; // Reorganize partition ... into - static const HA_ALTER_FLAGS REORGANIZE_PARTITION = 1L << 25; + static const HA_ALTER_FLAGS REORGANIZE_PARTITION = 1ULL << 32; // Reorganize partition - static const HA_ALTER_FLAGS ALTER_TABLE_REORG = 1L << 26; + static const HA_ALTER_FLAGS ALTER_TABLE_REORG = 1ULL << 33; // Remove partitioning - static const HA_ALTER_FLAGS ALTER_REMOVE_PARTITIONING = 1L << 27; + static const HA_ALTER_FLAGS ALTER_REMOVE_PARTITIONING = 1ULL << 34; // Partition operation with ALL keyword - static const HA_ALTER_FLAGS ALTER_ALL_PARTITION = 1L << 28; + static const HA_ALTER_FLAGS ALTER_ALL_PARTITION = 1ULL << 35; /** Recreate the table for ALTER TABLE FORCE, ALTER TABLE ENGINE and OPTIMIZE TABLE operations. */ - static const HA_ALTER_FLAGS RECREATE_TABLE = 1L << 29; + static const HA_ALTER_FLAGS RECREATE_TABLE = 1ULL << 36; - // Virtual columns changed - static const HA_ALTER_FLAGS ALTER_COLUMN_VCOL = 1L << 30; + /** + Changes in generated columns that affect storage, + for example, when a vcol type or expression changes + and this vcol is indexed or used in a partitioning expression + */ + static const HA_ALTER_FLAGS ALTER_COLUMN_VCOL = 1ULL << 37; /** ALTER TABLE for a partitioned table. The engine needs to commit online alter of all partitions atomically (using group_commit_ctx) */ - static const HA_ALTER_FLAGS ALTER_PARTITIONED = 1L << 31; + static const HA_ALTER_FLAGS ALTER_PARTITIONED = 1ULL << 38; - static const HA_ALTER_FLAGS ALTER_ADD_CHECK_CONSTRAINT = 1LL << 32; + static const HA_ALTER_FLAGS ALTER_ADD_CHECK_CONSTRAINT = 1ULL << 39; - static const HA_ALTER_FLAGS ALTER_DROP_CHECK_CONSTRAINT= 1LL << 33; + static const HA_ALTER_FLAGS ALTER_DROP_CHECK_CONSTRAINT= 1ULL << 40; /** Create options (like MAX_ROWS) for the new version of table. diff --git a/sql/sql_class.cc b/sql/sql_class.cc index ac337afb65d..343511d665c 100644 --- a/sql/sql_class.cc +++ b/sql/sql_class.cc @@ -4383,6 +4383,93 @@ extern "C" int thd_is_connected(MYSQL_THD thd) #ifdef INNODB_COMPATIBILITY_HOOKS + +/** open a table and add it to thd->open_tables + + @note At the moment this is used in innodb background purge threads + *only*.There should be no table locks, because the background purge does not + change the table as far as LOCK TABLES is concerned. MDL locks are + still needed, though. + + To make sure no table stays open for long, this helper allows the thread to + have only one table open at any given time. +*/ +TABLE *open_purge_table(THD *thd, const char *db, size_t dblen, + const char *tb, size_t tblen) +{ + DBUG_ENTER("open_purge_table"); + DBUG_ASSERT(thd->open_tables == NULL); + DBUG_ASSERT(thd->locked_tables_mode < LTM_PRELOCKED); + + Open_table_context ot_ctx(thd, 0); + TABLE_LIST *tl= (TABLE_LIST*)thd->alloc(sizeof(TABLE_LIST)); + + tl->init_one_table(db, dblen, tb, tblen, tb, TL_READ); + tl->i_s_requested_object= OPEN_TABLE_ONLY; + + bool error= open_table(thd, tl, &ot_ctx); + + /* we don't recover here */ + DBUG_ASSERT(!error || !ot_ctx.can_recover_from_failed_open()); + + if (error) + close_thread_tables(thd); + + DBUG_RETURN(error ? NULL : tl->table); +} + +/** Find an open table in the list of prelocked tabled + + Used for foreign key actions, for example, in UPDATE t1 SET a=1; + where a child table t2 has a KB on t1.a. + + But only when virtual columns are involved, otherwise InnoDB + does not need an open TABLE. +*/ +TABLE *find_fk_open_table(THD *thd, const char *db, size_t db_len, + const char *table, size_t table_len) +{ + for (TABLE *t= thd->open_tables; t; t= t->next) + { + if (t->s->db.length == db_len && t->s->table_name.length == table_len && + !strcmp(t->s->db.str, db) && !strcmp(t->s->table_name.str, table) && + t->pos_in_table_list->prelocking_placeholder == TABLE_LIST::FK) + return t; + } + return NULL; +} + +/* the following three functions are used in background purge threads */ + +MYSQL_THD create_thd() +{ + THD *thd= new THD(next_thread_id()); + thd->thread_stack= (char*) &thd; + thd->store_globals(); + thd->set_command(COM_DAEMON); + thd->system_thread= SYSTEM_THREAD_GENERIC; + add_to_active_threads(thd); + return thd; +} + +void destroy_thd(MYSQL_THD thd) +{ + delete_running_thd(thd); +} + +void reset_thd(MYSQL_THD thd) +{ + close_thread_tables(thd); + thd->mdl_context.release_transactional_locks(); + thd->free_items(); + free_root(thd->mem_root, MYF(MY_KEEP_PREALLOC)); +} + +unsigned long long thd_get_query_id(const MYSQL_THD thd) +{ + return((unsigned long long)thd->query_id); +} + extern "C" const struct charset_info_st *thd_charset(MYSQL_THD thd) { return(thd->charset()); diff --git a/sql/sql_class.h b/sql/sql_class.h index 9beee19eae0..f2e6f131f5f 100644 --- a/sql/sql_class.h +++ b/sql/sql_class.h @@ -1622,7 +1622,8 @@ enum enum_thread_type SYSTEM_THREAD_EVENT_SCHEDULER= 8, SYSTEM_THREAD_EVENT_WORKER= 16, SYSTEM_THREAD_BINLOG_BACKGROUND= 32, - SYSTEM_THREAD_SLAVE_BACKGROUND= 64 + SYSTEM_THREAD_SLAVE_BACKGROUND= 64, + SYSTEM_THREAD_GENERIC= 128 }; inline char const * diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index d80706e6796..6dc91928ded 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -1085,20 +1085,11 @@ void do_handle_bootstrap(THD *thd) end: in_bootstrap= FALSE; delete thd; - if (!opt_bootstrap) - { - /* - We need to wake up main thread in case of read_init_file(). - This is not done by THD::~THD() when there are other threads running - (binlog background thread, for example). So do it here again. - */ - mysql_mutex_lock(&LOCK_thread_count); - mysql_cond_broadcast(&COND_thread_count); - mysql_mutex_unlock(&LOCK_thread_count); - } + mysql_mutex_lock(&LOCK_thread_count); + mysql_cond_broadcast(&COND_thread_count); + mysql_mutex_unlock(&LOCK_thread_count); #ifndef EMBEDDED_LIBRARY - DBUG_ASSERT(!opt_bootstrap || thread_count == 0); my_thread_end(); pthread_exit(0); #endif diff --git a/sql/sql_table.cc b/sql/sql_table.cc index 16c8214438b..5e93fac1ddd 100644 --- a/sql/sql_table.cc +++ b/sql/sql_table.cc @@ -6216,17 +6216,6 @@ static int compare_uint(const uint *s, const uint *t) } -/* - Check if the column is computed and either - is stored or is used in the partitioning expression. -*/ -static bool vcol_affecting_storage(const Virtual_column_info* vcol, - bool indexed) -{ - return vcol && - (vcol->is_stored() || vcol->is_in_partitioning_expr() || indexed); -} - /** Compare original and new versions of a table and fill Alter_inplace_info describing differences between those versions. @@ -6291,11 +6280,6 @@ static bool fill_alter_inplace_info(THD *thd, alter_info->key_list.elements))) DBUG_RETURN(true); - /* First we setup ha_alter_flags based on what was detected by parser. */ - if (alter_info->flags & Alter_info::ALTER_ADD_COLUMN) - ha_alter_info->handler_flags|= Alter_inplace_info::ADD_COLUMN; - if (alter_info->flags & Alter_info::ALTER_DROP_COLUMN) - ha_alter_info->handler_flags|= Alter_inplace_info::DROP_COLUMN; /* Comparing new and old default values of column is cumbersome. So instead of using such a comparison for detecting if default @@ -6343,7 +6327,7 @@ static bool fill_alter_inplace_info(THD *thd, upgrading VARCHAR column types. */ if (table->s->frm_version < FRM_VER_TRUE_VARCHAR && varchar) - ha_alter_info->handler_flags|= Alter_inplace_info::ALTER_COLUMN_TYPE; + ha_alter_info->handler_flags|= Alter_inplace_info::ALTER_STORED_COLUMN_TYPE; /* Go through fields in old version of table and detect changes to them. @@ -6357,20 +6341,23 @@ static bool fill_alter_inplace_info(THD *thd, about nature of changes than those provided from parser. */ bool maybe_alter_vcol= false; - for (f_ptr= table->field; (field= *f_ptr); f_ptr++) + uint field_stored_index= 0; + for (f_ptr= table->field; (field= *f_ptr); f_ptr++, + field_stored_index+= field->stored_in_db()) { /* Clear marker for renamed or dropped field which we are going to set later. */ field->flags&= ~(FIELD_IS_RENAMED | FIELD_IS_DROPPED); /* Use transformed info to evaluate flags for storage engine. */ - uint new_field_index= 0; + uint new_field_index= 0, new_field_stored_index= 0; new_field_it.init(alter_info->create_list); while ((new_field= new_field_it++)) { if (new_field->field == field) break; new_field_index++; + new_field_stored_index+= new_field->stored_in_db(); } if (new_field) @@ -6385,7 +6372,12 @@ static bool fill_alter_inplace_info(THD *thd, { case IS_EQUAL_NO: /* New column type is incompatible with old one. */ - ha_alter_info->handler_flags|= Alter_inplace_info::ALTER_COLUMN_TYPE; + if (field->stored_in_db()) + ha_alter_info->handler_flags|= + Alter_inplace_info::ALTER_STORED_COLUMN_TYPE; + else + ha_alter_info->handler_flags|= + Alter_inplace_info::ALTER_VIRTUAL_COLUMN_TYPE; if (table->s->tmp_table == NO_TMP_TABLE) { delete_statistics_for_column(thd, table, field); @@ -6430,31 +6422,57 @@ static bool fill_alter_inplace_info(THD *thd, default: DBUG_ASSERT(0); /* Safety. */ - ha_alter_info->handler_flags|= Alter_inplace_info::ALTER_COLUMN_TYPE; + ha_alter_info->handler_flags|= + Alter_inplace_info::ALTER_STORED_COLUMN_TYPE; } - if (vcol_affecting_storage(field->vcol_info, - field->flags & PART_KEY_FLAG) || - vcol_affecting_storage(new_field->vcol_info, false)) + if (field->vcol_info || new_field->vcol_info) { - if (is_equal == IS_EQUAL_NO || - !field->vcol_info || !new_field->vcol_info || - !field->vcol_info->is_equal(new_field->vcol_info)) - ha_alter_info->handler_flags|= Alter_inplace_info::ALTER_COLUMN_VCOL; - else + /* base <-> virtual or stored <-> virtual */ + if (field->stored_in_db() != new_field->stored_in_db()) + ha_alter_info->handler_flags|= + Alter_inplace_info::ALTER_STORED_COLUMN_TYPE | + Alter_inplace_info::ALTER_VIRTUAL_COLUMN_TYPE; + if (field->vcol_info && new_field->vcol_info) { - if (!(ha_alter_info->handler_flags & Alter_inplace_info::ALTER_COLUMN_VCOL) && - (ha_alter_info->handler_flags & Alter_inplace_info::ALTER_COLUMN_DEFAULT)) + bool value_changes= is_equal == IS_EQUAL_NO; + Alter_inplace_info::HA_ALTER_FLAGS alter_expr= field->stored_in_db() + ? Alter_inplace_info::ALTER_STORED_GCOL_EXPR + : Alter_inplace_info::ALTER_VIRTUAL_GCOL_EXPR; + if (!field->vcol_info->is_equal(new_field->vcol_info)) + { + ha_alter_info->handler_flags|= alter_expr; + value_changes= true; + } + + if ((ha_alter_info->handler_flags & Alter_inplace_info::ALTER_COLUMN_DEFAULT) + && !(ha_alter_info->handler_flags & alter_expr)) { /* - a DEFAULT value of a some column was changed. - see if this vcol uses DEFAULT() function + a DEFAULT value of a some column was changed. see if this vcol + uses DEFAULT() function. The check is kind of expensive, so don't + do it if ALTER_COLUMN_VCOL is already set. */ if (field->vcol_info->expr_item->walk( &Item::check_func_default_processor, 0, 0)) - ha_alter_info->handler_flags|= Alter_inplace_info::ALTER_COLUMN_VCOL; + { + ha_alter_info->handler_flags|= alter_expr; + value_changes= true; + } + } + + if (field->vcol_info->is_in_partitioning_expr() || + field->flags & PART_KEY_FLAG) + { + if (value_changes) + ha_alter_info->handler_flags|= + Alter_inplace_info::ALTER_COLUMN_VCOL; + else + maybe_alter_vcol= true; } } - maybe_alter_vcol= true; + else /* base <-> stored */ + ha_alter_info->handler_flags|= + Alter_inplace_info::ALTER_STORED_COLUMN_TYPE; } /* Check if field was renamed */ @@ -6487,8 +6505,18 @@ static bool fill_alter_inplace_info(THD *thd, /* Detect changes in column order. */ - if (field->field_index != new_field_index) - ha_alter_info->handler_flags|= Alter_inplace_info::ALTER_COLUMN_ORDER; + if (field->stored_in_db()) + { + if (field_stored_index != new_field_stored_index) + ha_alter_info->handler_flags|= + Alter_inplace_info::ALTER_STORED_COLUMN_ORDER; + } + else + { + if (field->field_index != new_field_index) + ha_alter_info->handler_flags|= + Alter_inplace_info::ALTER_VIRTUAL_COLUMN_ORDER; + } /* Detect changes in storage type of column */ if (new_field->field_storage_type() != field->field_storage_type()) @@ -6511,12 +6539,12 @@ static bool fill_alter_inplace_info(THD *thd, } else { - /* - Field is not present in new version of table and therefore was dropped. - Corresponding storage engine flag should be already set. - */ - DBUG_ASSERT(ha_alter_info->handler_flags & Alter_inplace_info::DROP_COLUMN); + // Field is not present in new version of table and therefore was dropped. field->flags|= FIELD_IS_DROPPED; + if (field->stored_in_db()) + ha_alter_info->handler_flags|= Alter_inplace_info::DROP_STORED_COLUMN; + else + ha_alter_info->handler_flags|= Alter_inplace_info::DROP_VIRTUAL_COLUMN; } } @@ -6529,9 +6557,10 @@ static bool fill_alter_inplace_info(THD *thd, column was altered. */ if (ha_alter_info->handler_flags & - ( Alter_inplace_info::ALTER_COLUMN_TYPE - | Alter_inplace_info::ALTER_COLUMN_NOT_NULLABLE - | Alter_inplace_info::ALTER_COLUMN_OPTION )) + ( Alter_inplace_info::ALTER_STORED_COLUMN_TYPE + | Alter_inplace_info::ALTER_VIRTUAL_COLUMN_TYPE + | Alter_inplace_info::ALTER_COLUMN_NOT_NULLABLE + | Alter_inplace_info::ALTER_COLUMN_OPTION )) ha_alter_info->handler_flags|= Alter_inplace_info::ALTER_COLUMN_VCOL; } @@ -6540,17 +6569,17 @@ static bool fill_alter_inplace_info(THD *thd, { if (! new_field->field) { - /* - Field is not present in old version of table and therefore was added. - Again corresponding storage engine flag should be already set. - */ - DBUG_ASSERT(ha_alter_info->handler_flags & Alter_inplace_info::ADD_COLUMN); - - if (new_field->vcol_info && - (new_field->stored_in_db() || new_field->vcol_info->is_in_partitioning_expr())) - { - ha_alter_info->handler_flags|= Alter_inplace_info::ALTER_COLUMN_VCOL; - } + // Field is not present in old version of table and therefore was added. + if (new_field->vcol_info) + if (new_field->stored_in_db()) + ha_alter_info->handler_flags|= + Alter_inplace_info::ADD_STORED_GENERATED_COLUMN; + else + ha_alter_info->handler_flags|= + Alter_inplace_info::ADD_VIRTUAL_COLUMN; + else + ha_alter_info->handler_flags|= + Alter_inplace_info::ADD_STORED_BASE_COLUMN; } } diff --git a/storage/innobase/handler/ha_innodb.cc b/storage/innobase/handler/ha_innodb.cc index 598047e31d6..a235195ae91 100644 --- a/storage/innobase/handler/ha_innodb.cc +++ b/storage/innobase/handler/ha_innodb.cc @@ -126,6 +126,14 @@ this program; if not, write to the Free Software Foundation, Inc., #define thd_get_trx_isolation(X) ((enum_tx_isolation)thd_tx_isolation(X)) extern "C" void thd_mark_transaction_to_rollback(MYSQL_THD thd, bool all); +unsigned long long thd_get_query_id(const MYSQL_THD thd); +TABLE *find_fk_open_table(THD *thd, const char *db, size_t db_len, + const char *table, size_t table_len); +MYSQL_THD create_thd(); +void destroy_thd(MYSQL_THD thd); +void reset_thd(MYSQL_THD thd); +TABLE *open_purge_table(THD *thd, const char *db, size_t dblen, + const char *tb, size_t tblen); #ifdef MYSQL_DYNAMIC_PLUGIN #define tc_size 400 @@ -300,6 +308,45 @@ is_partition( #endif /* _WIN32 */ } +/** Service thread that waits for the server shutdown and stops purge threads. +Purge workers have THDs that are needed to calculate virtual columns. +This THDs must be destroyed rather early in the server shutdown sequence. +This service thread creates a THD and idly waits for it to get a signal to +die. Then it notifies all purge workers to shutdown. +*/ +st_my_thread_var *thd_destructor_myvar= NULL; +mysql_cond_t thd_destructor_cond; +pthread_t thd_destructor_thread; + +pthread_handler_t +thd_destructor_proxy(void *) +{ + mysql_mutex_t thd_destructor_mutex; + + my_thread_init(); + mysql_mutex_init(PSI_NOT_INSTRUMENTED, &thd_destructor_mutex, 0); + mysql_cond_init(PSI_NOT_INSTRUMENTED, &thd_destructor_cond, 0); + + thd_destructor_myvar = _my_thread_var(); + THD *thd= create_thd(); + + mysql_mutex_lock(&thd_destructor_mutex); + thd_destructor_myvar->current_mutex = &thd_destructor_mutex; + thd_destructor_myvar->current_cond = &thd_destructor_cond; + /* wait until the server wakes the THD to abort and die */ + while (!thd_destructor_myvar->abort) + mysql_cond_wait(&thd_destructor_cond, &thd_destructor_mutex); + mysql_mutex_unlock(&thd_destructor_mutex); + thd_destructor_myvar = NULL; + + srv_purge_wakeup(); + + destroy_thd(thd); + mysql_cond_destroy(&thd_destructor_cond); + mysql_mutex_destroy(&thd_destructor_mutex); + my_thread_end(); + return 0; +} /** Return the InnoDB ROW_FORMAT enum value @param[in] row_format row_format from "innodb_default_row_format" @@ -473,6 +520,7 @@ static mysql_pfs_key_t innobase_share_mutex_key; static mysql_pfs_key_t commit_cond_mutex_key; static mysql_pfs_key_t commit_cond_key; static mysql_pfs_key_t pending_checkpoint_mutex_key; +static mysql_pfs_key_t thd_destructor_thread_key; static PSI_mutex_info all_pthread_mutexes[] = { PSI_KEY(commit_cond_mutex), @@ -601,6 +649,7 @@ static PSI_thread_info all_innodb_threads[] = { PSI_KEY(srv_purge_thread), PSI_KEY(srv_worker_thread), PSI_KEY(trx_rollback_clean_thread), + PSI_KEY(thd_destructor_thread), }; # endif /* UNIV_PFS_THREAD */ @@ -1718,6 +1767,55 @@ thd_trx_is_read_only( return(thd != 0 && thd_tx_is_read_only(thd)); } +static MYSQL_THDVAR_BOOL(background_thread, + PLUGIN_VAR_NOCMDOPT | PLUGIN_VAR_NOSYSVAR, + "Internal (not user visible) flag to mark " + "background purge threads", NULL, NULL, 0); + +/** Create a MYSQL_THD for background purge threads and mark it as such. +@returns new MYSQL_THD */ +MYSQL_THD +innobase_create_background_thd() +/*============================*/ +{ + MYSQL_THD thd= create_thd(); + THDVAR(thd, background_thread) = true; + return thd; +} + + +/** Destroy a background purge thread THD. +@param[in] thd MYSQL_THD to destroy */ +void +innobase_destroy_background_thd( +/*============================*/ + MYSQL_THD thd) +{ + /* need to close the connection explicitly, the server won't do it + if innodb is in the PLUGIN_IS_DYING state */ + innobase_close_connection(innodb_hton_ptr, thd); + thd_set_ha_data(thd, innodb_hton_ptr, NULL); + destroy_thd(thd); +} + +/** Close opened tables, free memory, delete items for a MYSQL_THD. +@param[in] thd MYSQL_THD to reset */ +void +innobase_reset_background_thd(MYSQL_THD thd) +{ + if (!thd) { + thd = current_thd; + } + + ut_ad(thd); + ut_ad(THDVAR(thd, background_thread)); + + /* background purge thread */ + reset_thd(thd); + thd_proc_info(thd, ""); +} + + #if 0 /** Check if the transaction can be rolled back @@ -3252,6 +3350,7 @@ ha_innobase::ha_innobase( | HA_CAN_VIRTUAL_COLUMNS | HA_CAN_INDEX_BLOBS | HA_CAN_SQL_HANDLER + | HA_REQUIRES_KEY_COLUMNS_FOR_DELETE | HA_PRIMARY_KEY_REQUIRED_FOR_POSITION | HA_PRIMARY_KEY_IN_READ_INDEX | HA_BINLOG_ROW_CAPABLE @@ -4582,6 +4681,12 @@ innobase_change_buffering_inited_ok: } */ + if (!srv_read_only_mode) { + mysql_thread_create(thd_destructor_thread_key, + &thd_destructor_thread, + NULL, thd_destructor_proxy, NULL); + } + /* Since we in this module access directly the fields of a trx struct, and due to different headers and flags it might happen that ib_mutex_t has a different size in this module and in InnoDB @@ -4716,6 +4821,13 @@ innobase_end( #ifdef MYSQL_ENCRYPTION mutex_free(&master_key_id_mutex); #endif + + if (!abort_loop && thd_destructor_myvar) { + // may be UNINSTALL PLUGIN statement + thd_destructor_myvar->abort = 1; + mysql_cond_broadcast(thd_destructor_myvar->current_cond); + } + if (innobase_shutdown_for_mysql() != DB_SUCCESS) { err = 1; } @@ -5838,6 +5950,36 @@ ha_innobase::keys_to_use_for_scanning() return(&key_map_full); } +/****************************************************************//** +Ensures that if there's a concurrent inplace ADD INDEX, being-indexed virtual +columns are computed. They are not marked as indexed in the old table, so the +server won't add them to the vcol_set automatically */ +void +ha_innobase::column_bitmaps_signal() +/*================================*/ +{ + if (!table->vfield || table->current_lock != F_WRLCK) { + return; + } + + dict_index_t* clust_index = dict_table_get_first_index(m_prebuilt->table); + uint num_v = 0; + for (uint j = 0; j < table->s->virtual_fields; j++) { + if (table->vfield[j]->stored_in_db()) { + continue; + } + + dict_col_t* col = &m_prebuilt->table->v_cols[num_v].m_col; + if (col->ord_part || + (dict_index_is_online_ddl(clust_index) && + row_log_col_is_indexed(clust_index, num_v))) { + table->mark_virtual_col(table->vfield[j]); + } + num_v++; + } +} + + /****************************************************************//** Determines if table caching is supported. @return HA_CACHE_TBL_ASKTRANSACT */ @@ -6168,7 +6310,6 @@ innobase_match_index_columns( DBUG_RETURN(TRUE); } -#ifdef MYSQL_VIRTUAL_COLUMNS /** Build a template for a base column for a virtual column @param[in] table MySQL TABLE @param[in] clust_index InnoDB clustered index @@ -6228,21 +6369,6 @@ innobase_vcol_build_templ( templ->is_unsigned = col->prtype & DATA_UNSIGNED; } -/** callback used by MySQL server layer to initialize -the table virtual columns' template -@param[in] table MySQL TABLE -@param[in,out] ib_table InnoDB table */ -void -innobase_build_v_templ_callback( - const TABLE* table, - void* ib_table) -{ - const dict_table_t* t_table = static_cast(ib_table); - - innobase_build_v_templ(table, t_table, t_table->vc_templ, NULL, - true, NULL); -} - /** Build template for the virtual columns and their base columns. This is done when the table first opened. @param[in] table MySQL TABLE @@ -6250,16 +6376,14 @@ is done when the table first opened. @param[in,out] s_templ InnoDB template structure @param[in] add_v new virtual columns added along with add index call -@param[in] locked true if dict_sys mutex is held -@param[in] share_tbl_name original MySQL table name */ +@param[in] locked true if dict_sys mutex is held */ void innobase_build_v_templ( const TABLE* table, const dict_table_t* ib_table, dict_vcol_templ_t* s_templ, const dict_add_v_col_t* add_v, - bool locked, - const char* share_tbl_name) + bool locked) { ulint ncol = ib_table->n_cols - DATA_N_SYS_COLS; ulint n_v_col = ib_table->n_v_cols; @@ -6291,15 +6415,8 @@ innobase_build_v_templ( * sizeof *s_templ->vtempl)); s_templ->n_col = ncol; s_templ->n_v_col = n_v_col; - s_templ->rec_len = table->s->stored_rec_length; - // JAN: MySQL 5.6 - // s_templ->default_rec = table->s->default_values; - - s_templ->default_rec = static_cast( - ut_malloc_nokey(table->s->stored_rec_length)); - memcpy(s_templ->default_rec, table->s->default_values, - table->s->stored_rec_length); - + s_templ->rec_len = table->s->reclength; + s_templ->default_rec = table->s->default_values; /* Mark those columns could be base columns */ for (ulint i = 0; i < ib_table->n_v_cols; i++) { @@ -6399,12 +6516,7 @@ innobase_build_v_templ( s_templ->db_name = table->s->db.str; s_templ->tb_name = table->s->table_name.str; - - if (share_tbl_name) { - s_templ->share_name = share_tbl_name; - } } -#endif /* MYSQL_VIRTUAL_COLUMNS */ /*******************************************************************//** This function builds a translation table in INNOBASE_SHARE @@ -6774,14 +6886,14 @@ ha_innobase::open( if (ib_table != NULL && ((!DICT_TF2_FLAG_IS_SET(ib_table, DICT_TF2_FTS_HAS_DOC_ID) - && table->s->stored_fields != dict_table_get_n_tot_u_cols(ib_table)) + && table->s->fields != dict_table_get_n_tot_u_cols(ib_table)) || (DICT_TF2_FLAG_IS_SET(ib_table, DICT_TF2_FTS_HAS_DOC_ID) - && (table->s->stored_fields + && (table->s->fields != dict_table_get_n_tot_u_cols(ib_table) - 1)))) { ib::warn() << "Table " << norm_name << " contains " << dict_table_get_n_user_cols(ib_table) << " user" - " defined columns in InnoDB, but " << table->s->stored_fields + " defined columns in InnoDB, but " << table->s->fields << " columns in MariaDB. Please check" " INFORMATION_SCHEMA.INNODB_SYS_COLUMNS and " REFMAN "innodb-troubleshooting.html for how to resolve the" @@ -6927,7 +7039,7 @@ ha_innobase::open( DBUG_RETURN(ret_err); } - m_prebuilt = row_create_prebuilt(ib_table, table->s->stored_rec_length); + m_prebuilt = row_create_prebuilt(ib_table, table->s->reclength); m_prebuilt->default_rec = table->s->default_values; ut_ad(m_prebuilt->default_rec); @@ -6939,12 +7051,10 @@ ha_innobase::open( key_used_on_scan = m_primary_key; -#ifdef MYSQL_VIRTUAL_COLUMNS if (ib_table->n_v_cols) { mutex_enter(&dict_sys->mutex); if (ib_table->vc_templ == NULL) { ib_table->vc_templ = UT_NEW_NOKEY(dict_vcol_templ_t()); - ib_table->vc_templ->vtempl = NULL; } else if (ib_table->get_ref_count() == 1) { /* Clean and refresh the template if no one else get hold on it */ @@ -6955,12 +7065,11 @@ ha_innobase::open( if (ib_table->vc_templ->vtempl == NULL) { innobase_build_v_templ( table, ib_table, ib_table->vc_templ, NULL, - true, m_share->table_name); + true); } mutex_exit(&dict_sys->mutex); } -#endif /* MYSQL_VIRTUAL_COLUMNS */ if (!innobase_build_index_translation(table, ib_table, m_share)) { sql_print_error("Build InnoDB index translation table for" @@ -8058,10 +8167,9 @@ build_template_needs_field( dict_index_t* index, /*!< in: InnoDB index to use */ const TABLE* table, /*!< in: MySQL table object */ ulint i, /*!< in: field index in InnoDB table */ - ulint sql_idx, /*!< in: field index in SQL table */ ulint num_v) /*!< in: num virtual column so far */ { - const Field* field = table->field[sql_idx]; + const Field* field = table->field[i]; if (!index_contains) { if (read_just_key) { @@ -8076,8 +8184,8 @@ build_template_needs_field( return(field); } - if (bitmap_is_set(table->read_set, static_cast(sql_idx)) - || bitmap_is_set(table->write_set, static_cast(sql_idx))) { + if (bitmap_is_set(table->read_set, static_cast(i)) + || bitmap_is_set(table->write_set, static_cast(i))) { /* This field is needed in the query */ return(field); @@ -8259,10 +8367,10 @@ ha_innobase::build_template( { dict_index_t* index; dict_index_t* clust_index; - ulint n_stored_fields; + ulint n_fields; ibool fetch_all_in_key = FALSE; ibool fetch_primary_key_cols = FALSE; - ulint i, sql_idx; + ulint i; if (m_prebuilt->select_lock_type == LOCK_X) { /* We always retrieve the whole clustered index record if we @@ -8315,12 +8423,11 @@ ha_innobase::build_template( /* Below we check column by column if we need to access the clustered index. */ - /* number of stored columns */ - n_stored_fields= (ulint)table->s->stored_fields; + n_fields = (ulint) table->s->fields; /* number of columns */ if (!m_prebuilt->mysql_template) { m_prebuilt->mysql_template = (mysql_row_templ_t*) - ut_malloc_nokey(n_stored_fields * sizeof(mysql_row_templ_t)); + ut_malloc_nokey(n_fields * sizeof(mysql_row_templ_t)); } m_prebuilt->template_type = whole_row @@ -8342,14 +8449,10 @@ ha_innobase::build_template( ulint num_v = 0; /* Push down an index condition or an end_range check. */ - for (i = 0, sql_idx = 0; i < n_stored_fields; i++, sql_idx++) { + for (i = 0; i < n_fields; i++) { ibool index_contains; - while (!table->field[sql_idx]->stored_in_db()) { - sql_idx++; - } - - if (innobase_is_v_fld(table->field[sql_idx])) { + if (innobase_is_v_fld(table->field[i])) { index_contains = dict_index_contains_col_or_prefix( index, num_v, true); } else { @@ -8372,8 +8475,7 @@ ha_innobase::build_template( the subset field->part_of_key.is_set(active_index) which would be acceptable if end_range==NULL. */ - bool is_v = innobase_is_v_fld(table->field[sql_idx]); - + bool is_v = innobase_is_v_fld(table->field[i]); if (build_template_needs_field_in_icp( index, m_prebuilt, index_contains, is_v ? num_v : i - num_v, is_v)) { @@ -8382,17 +8484,17 @@ ha_innobase::build_template( mysql_row_templ_t* templ; if (whole_row) { - field = table->field[sql_idx]; + field = table->field[i]; } else { field = build_template_needs_field( index_contains, m_prebuilt->read_just_key, fetch_all_in_key, fetch_primary_key_cols, - index, table, i, sql_idx, num_v); + index, table, i, num_v); if (!field) { if (innobase_is_v_fld( - table->field[sql_idx])) { + table->field[i])) { num_v++; } continue; @@ -8474,7 +8576,7 @@ ha_innobase::build_template( < m_prebuilt->index->n_uniq); */ } - if (innobase_is_v_fld(table->field[sql_idx])) { + if (innobase_is_v_fld(table->field[i])) { num_v++; } } @@ -8486,15 +8588,11 @@ ha_innobase::build_template( /* Include the fields that are not needed in index condition pushdown. */ - for (i = 0, sql_idx = 0; i < n_stored_fields; i++, sql_idx++) { + for (i = 0; i < n_fields; i++) { mysql_row_templ_t* templ; ibool index_contains; - while (!table->field[sql_idx]->stored_in_db()) { - sql_idx++; - } - - if (innobase_is_v_fld(table->field[sql_idx])) { + if (innobase_is_v_fld(table->field[i])) { index_contains = dict_index_contains_col_or_prefix( index, num_v, true); } else { @@ -8502,7 +8600,7 @@ ha_innobase::build_template( index, i - num_v, false); } - bool is_v = innobase_is_v_fld(table->field[sql_idx]); + bool is_v = innobase_is_v_fld(table->field[i]); if (!build_template_needs_field_in_icp( index, m_prebuilt, index_contains, @@ -8511,16 +8609,16 @@ ha_innobase::build_template( const Field* field; if (whole_row) { - field = table->field[sql_idx]; + field = table->field[i]; } else { field = build_template_needs_field( index_contains, m_prebuilt->read_just_key, fetch_all_in_key, fetch_primary_key_cols, - index, table, i, sql_idx, num_v); + index, table, i, num_v); if (!field) { - if (innobase_is_v_fld(table->field[sql_idx])) { + if (innobase_is_v_fld(table->field[i])) { num_v++; } continue; @@ -8544,13 +8642,9 @@ ha_innobase::build_template( /* No index condition pushdown */ m_prebuilt->idx_cond = NULL; - for (i = 0, sql_idx = 0; i < n_stored_fields; i++, sql_idx++) { + for (i = 0; i < n_fields; i++) { const Field* field; - while (!table->field[sql_idx]->stored_in_db()) { - sql_idx++; - } - if (whole_row) { /* Even this is whole_row, if the seach is on a virtual column, and read_just_key is @@ -8558,7 +8652,7 @@ ha_innobase::build_template( will not try to fill the value since they are not stored in such index nor in the cluster index. */ - if (innobase_is_v_fld(table->field[sql_idx]) + if (innobase_is_v_fld(table->field[i]) && m_prebuilt->read_just_key && !dict_index_contains_col_or_prefix( m_prebuilt->index, num_v, true)) @@ -8570,11 +8664,11 @@ ha_innobase::build_template( continue; } - field = table->field[sql_idx]; + field = table->field[i]; } else { ibool contain; - if (innobase_is_v_fld(table->field[sql_idx])) { + if (innobase_is_v_fld(table->field[i])) { contain = dict_index_contains_col_or_prefix( index, num_v, true); } else { @@ -8583,16 +8677,14 @@ ha_innobase::build_template( false); } - field = build_template_needs_field( contain, m_prebuilt->read_just_key, fetch_all_in_key, fetch_primary_key_cols, - index, table, i, sql_idx, num_v); - + index, table, i, num_v); if (!field) { - if (innobase_is_v_fld(table->field[sql_idx])) { + if (innobase_is_v_fld(table->field[i])) { num_v++; } continue; @@ -9177,7 +9269,7 @@ calc_row_difference( ulint n_changed = 0; dfield_t dfield; dict_index_t* clust_index; - uint sql_idx,i, innodb_idx= 0; + uint i; ibool changes_fts_column = FALSE; ibool changes_fts_doc_col = FALSE; trx_t* trx = thd_to_trx(thd); @@ -9192,19 +9284,15 @@ calc_row_difference( /* We use upd_buff to convert changed fields */ buf = (byte*) upd_buff; - for (sql_idx = 0,i=0; i < n_fields; i++, sql_idx++) { - field = table->field[sql_idx]; + for (i = 0; i < n_fields; i++) { + field = table->field[i]; bool is_virtual = innobase_is_v_fld(field); dict_col_t* col; - if (!field->stored_in_db()) { - continue; - } - if (is_virtual) { col = &prebuilt->table->v_cols[num_v].m_col; } else { - col = &prebuilt->table->cols[innodb_idx - num_v]; + col = &prebuilt->table->cols[i - num_v]; } o_ptr = (const byte*) old_row + get_field_offset(table, field); @@ -9419,7 +9507,7 @@ calc_row_difference( num_v++; } else { ufield->field_no = dict_col_get_clust_pos( - &prebuilt->table->cols[innodb_idx - num_v], + &prebuilt->table->cols[i - num_v], clust_index); ufield->old_v_val = NULL; } @@ -9465,10 +9553,6 @@ calc_row_difference( ut_ad(col->ord_part || online_ord_part); num_v++; } - - if (field->stored_in_db()) { - innodb_idx++; - } } /* If the update changes a column with an FTS index on it, we @@ -9669,12 +9753,11 @@ ha_innobase::update_row( ut_ad(m_upd_buf_size == 0); /* Create a buffer for packing the fields of a record. Why - table->stored_rec_length did not work here? Obviously, - because char fields when packed actually became 1 byte - longer, when we also stored the string length as the first - byte. */ + table->reclength did not work here? Obviously, because char + fields when packed actually became 1 byte longer, when we also + stored the string length as the first byte. */ - m_upd_buf_size = table->s->stored_rec_length + table->s->max_key_length + m_upd_buf_size = table->s->reclength + table->s->max_key_length + MAX_REF_PARTS * 3; m_upd_buf = reinterpret_cast( @@ -11704,7 +11787,43 @@ create_table_check_doc_id_col( return(false); } -#ifdef MYSQL_VIRTUAL_COLUMNS + +/** Finds all base columns needed to compute a given generated column. +This is returned as a bitmap, in field->table->tmp_set. +Works for both dict_v_col_t and dict_s_col_t columns. +@param[in] table InnoDB table +@param[in] field MySQL field +@param[in,out] col virtual or stored column */ +template +void +prepare_vcol_for_base_setup( +/*========================*/ + const dict_table_t* table, + const Field* field, + T* col) +{ + ut_ad(col->num_base == 0); + ut_ad(col->base_col == NULL); + + MY_BITMAP *old_read_set = field->table->read_set; + MY_BITMAP *old_vcol_set = field->table->vcol_set; + + field->table->read_set = field->table->vcol_set = &field->table->tmp_set; + + bitmap_clear_all(&field->table->tmp_set); + field->vcol_info->expr_item->walk( + &Item::register_field_in_read_map, 1, field->table); + col->num_base= bitmap_bits_set(&field->table->tmp_set); + if (col->num_base != 0) { + col->base_col = static_cast(mem_heap_zalloc( + table->heap, col->num_base * sizeof( + * col->base_col))); + } + field->table->read_set= old_read_set; + field->table->vcol_set= old_vcol_set; +} + + /** Set up base columns for virtual column @param[in] table InnoDB table @param[in] field MySQL field @@ -11717,10 +11836,12 @@ innodb_base_col_setup( { int n = 0; + prepare_vcol_for_base_setup(table, field, v_col); + for (uint i= 0; i < field->table->s->fields; ++i) { const Field* base_field = field->table->field[i]; - if (!base_field->is_virtual_gcol() - && bitmap_is_set(&field->gcol_info->base_columns_map, i)) { + if (base_field->stored_in_db() + && bitmap_is_set(&field->table->tmp_set, i)) { ulint z; for (z = 0; z < table->n_cols; z++) { @@ -11738,10 +11859,9 @@ innodb_base_col_setup( n++; } } + v_col->num_base= n; } -#endif /* MYSQL_VIRTUAL_COLUMNS */ -#ifdef MYSQL_VIRTUAL_COLUMNS /** Set up base columns for stored column @param[in] table InnoDB table @param[in] field MySQL field @@ -11754,12 +11874,14 @@ innodb_base_col_setup_for_stored( { ulint n = 0; + prepare_vcol_for_base_setup(table, field, s_col); + for (uint i= 0; i < field->table->s->fields; ++i) { const Field* base_field = field->table->field[i]; if (!innobase_is_s_fld(base_field) && !innobase_is_v_fld(base_field) - && bitmap_is_set(&field->gcol_info->base_columns_map, + && bitmap_is_set(&field->table->tmp_set, i)) { ulint z; for (z = 0; z < table->n_cols; z++) { @@ -11781,8 +11903,8 @@ innodb_base_col_setup_for_stored( } } } + s_col->num_base= n; } -#endif /** Create a table definition to an InnoDB database. @return ER_* level error */ @@ -11792,7 +11914,6 @@ create_table_info_t::create_table_def() { dict_table_t* table; ulint n_cols; - ulint s_cols; ulint col_type; ulint col_len; ulint nulls_allowed; @@ -11801,6 +11922,7 @@ create_table_info_t::create_table_def() ulint long_true_varchar; ulint charset_no; ulint i; + ulint j = 0; ulint doc_id_col = 0; ibool has_doc_id_col = FALSE; mem_heap_t* heap; @@ -11837,9 +11959,7 @@ create_table_info_t::create_table_def() } n_cols = m_form->s->fields; - s_cols = m_form->s->stored_fields; -#ifdef MYSQL_VIRTUAL_COLUMNS /* Find out any virtual column */ for (i = 0; i < n_cols; i++) { Field* field = m_form->field[i]; @@ -11848,7 +11968,6 @@ create_table_info_t::create_table_def() num_v++; } } -#endif /* MYSQL_VIRTUAL_COLUMNS */ ut_ad(trx_state_eq(m_trx, TRX_STATE_NOT_STARTED)); @@ -11874,8 +11993,7 @@ create_table_info_t::create_table_def() } /* Adjust the number of columns for the FTS hidden field */ - actual_n_cols = m_form->s->stored_fields; - + actual_n_cols = n_cols; if (m_flags2 & DICT_TF2_FTS && !has_doc_id_col) { actual_n_cols += 1; } @@ -11886,7 +12004,7 @@ create_table_info_t::create_table_def() /* Set the hidden doc_id column. */ if (m_flags2 & DICT_TF2_FTS) { table->fts->doc_col = has_doc_id_col - ? doc_id_col : s_cols; + ? doc_id_col : n_cols - num_v; } if (strlen(m_temp_path) != 0) { @@ -11915,12 +12033,9 @@ create_table_info_t::create_table_def() for (i = 0; i < n_cols; i++) { ulint is_virtual; - bool is_stored MY_ATTRIBUTE((unused)); - Field* field = m_form->field[i]; + bool is_stored = false; - if (!field->stored_in_db()) { - continue; - } + Field* field = m_form->field[i]; col_type = get_innobase_type_from_mysql_type( &unsigned_type, field); @@ -12019,7 +12134,6 @@ err_col: charset_no), col_len); } else { -#ifdef MYSQL_VIRTUAL_COLUMNS dict_mem_table_add_v_col(table, heap, field->field_name, col_type, dtype_form_prtype( @@ -12028,26 +12142,18 @@ err_col: | binary_type | long_true_varchar | is_virtual, charset_no), - col_len, i, - 0); + col_len, i, 0); + } - field->gcol_info->non_virtual_base_columns()); -#endif - } - -#ifdef MYSQL_VIRTUAL_COLUMNS if (is_stored) { ut_ad(!is_virtual); /* Added stored column in m_s_cols list. */ dict_mem_table_add_s_col( - table, - field->gcol_info->non_virtual_base_columns()); + table, 0); } -#endif } -#ifdef MYSQL_VIRTUAL_COLUMNS + if (num_v) { - ulint j = 0; for (i = 0; i < n_cols; i++) { dict_v_col_t* v_col; @@ -12088,7 +12194,6 @@ err_col: } } } -#endif /* MYSQL_VIRTUAL_COLUMNS */ /* Add the FTS doc_id hidden column. */ if (m_flags2 & DICT_TF2_FTS && !has_doc_id_col) { @@ -12121,7 +12226,6 @@ err_col: my_error(ER_TABLESPACE_CANNOT_ENCRYPT, MYF(0)); err = DB_UNSUPPORTED; dict_mem_table_free(table); - */ } else { #endif /* MYSQL_COMPRESSION */ /* Get a new table ID */ @@ -13833,6 +13937,30 @@ create_table_info_t::initialize() } +/** Check if a virtual column is part of a fulltext or spatial index. */ +bool +create_table_info_t::gcols_in_fulltext_or_spatial() +{ + for (ulint i = 0; i < m_form->s->keys; i++) { + const KEY* key = m_form->key_info + i; + if (key->flags & (HA_SPATIAL | HA_FULLTEXT)) { + for (ulint j = 0; j < key->user_defined_key_parts; j++) { + const KEY_PART_INFO* key_part = key->key_part + j; + + /* We do not support special (Fulltext or + Spatial) index on virtual columns */ + if (innobase_is_v_fld(key_part->field)) { + my_error(ER_UNSUPPORTED_ACTION_ON_VIRTUAL_COLUMN, MYF(0)); + return true; + } + } + } + + } + return false; +} + + /** Prepare to create a new table to an InnoDB database. @param[in] name Table name @return error number */ @@ -13874,6 +14002,10 @@ create_table_info_t::prepare_create_table( DBUG_RETURN(HA_ERR_TABLE_READONLY); } + if (gcols_in_fulltext_or_spatial()) { + DBUG_RETURN(HA_ERR_UNSUPPORTED); + } + DBUG_RETURN(parse_table_name(name)); } @@ -14040,19 +14172,15 @@ create_table_info_t::create_table() " table where referencing columns appear" " as the first columns.\n", m_table_name); break; -#ifdef MYSQL_VIRTUAL_COLUMNS - case DB_NO_FK_ON_V_BASE_COL: + case DB_NO_FK_ON_S_BASE_COL: push_warning_printf( m_thd, Sql_condition::WARN_LEVEL_WARN, HA_ERR_CANNOT_ADD_FOREIGN, "Create table '%s' with foreign key constraint" " failed. Cannot add foreign key constraint" - " placed on the base column of indexed" - " virtual column, or constraint placed" - " on columns being part of virtual index.\n", + " placed on the base column of stored" + " column. \n", m_table_name); - break; -#endif default: break; } @@ -14647,8 +14775,7 @@ validate_create_tablespace_info( THD* thd, st_alter_tablespace* alter_info) { - - int error = 0; + ulint space_id; /* The parser ensures that these fields are provided. */ ut_a(alter_info->tablespace_name); @@ -15427,6 +15554,7 @@ ha_innobase::records( DBUG_RETURN(HA_ERR_QUERY_INTERRUPTED); } + *num_rows= n_rows; DBUG_RETURN(0); } #endif /* MYSQL_57_SELECT_COUNT_OPTIMIZATION */ @@ -23203,6 +23331,7 @@ static struct st_mysql_sys_var* innobase_system_variables[]= { #endif MYSQL_SYSVAR(instrument_semaphores), MYSQL_SYSVAR(buf_dump_status_frequency), + MYSQL_SYSVAR(background_thread), NULL }; @@ -23377,29 +23506,29 @@ innobase_index_cond( return handler_index_cond_check(file); } -#ifdef MYSQL_VIRTUAL_COLUMNS -/** Get the computed value by supplying the base column values. -@param[in,out] table the table whose virtual column template to be built */ -void -innobase_init_vc_templ( + +/** Find or open a mysql table for the virtual column template +@param[in] thd mysql thread handle +@param[in,out] table InnoDB table whose virtual column template is to be updated +@return TABLE if successful or NULL */ +static TABLE * +innobase_find_mysql_table_for_vc( +/*=============================*/ + THD* thd, dict_table_t* table) { - char dbname[MAX_DATABASE_NAME_LEN + 1]; - char tbname[MAX_TABLE_NAME_LEN + 1]; - char* name = table->name.m_name; - ulint dbnamelen = dict_get_db_name_len(name); - ulint tbnamelen = strlen(name) - dbnamelen - 1; - char t_dbname[MAX_DATABASE_NAME_LEN + 1]; - char t_tbname[MAX_TABLE_NAME_LEN + 1]; - - mutex_enter(&dict_sys->mutex); - - if (table->vc_templ != NULL) { - mutex_exit(&dict_sys->mutex); - - return; + if (table->vc_templ->mysql_table_query_id == thd_get_query_id(thd)) { + return table->vc_templ->mysql_table; } + char dbname[MAX_DATABASE_NAME_LEN + 1]; + char tbname[MAX_TABLE_NAME_LEN + 1]; + char* name = table->name.m_name; + uint dbnamelen = dict_get_db_name_len(name); + uint tbnamelen = strlen(name) - dbnamelen - 1; + char t_dbname[MAX_DATABASE_NAME_LEN + 1]; + char t_tbname[MAX_TABLE_NAME_LEN + 1]; + strncpy(dbname, name, dbnamelen); dbname[dbnamelen] = 0; strncpy(tbname, name + dbnamelen + 1, tbnamelen); @@ -23407,32 +23536,53 @@ innobase_init_vc_templ( /* For partition table, remove the partition name and use the "main" table name to build the template */ - char* is_part = is_partition(tbname); + char* is_part = is_partition(tbname); if (is_part != NULL) { *is_part = '\0'; tbnamelen = is_part - tbname; } - table->vc_templ = UT_NEW_NOKEY(dict_vcol_templ_t()); - table->vc_templ->vtempl = NULL; - dbnamelen = filename_to_tablename(dbname, t_dbname, MAX_DATABASE_NAME_LEN + 1); tbnamelen = filename_to_tablename(tbname, t_tbname, MAX_TABLE_NAME_LEN + 1); -#ifdef UNIV_DEBUG - // bool ret = -#endif /* UNIV_DEBUG */ + TABLE *mysql_table = find_fk_open_table(thd, t_dbname, dbnamelen, + t_tbname, tbnamelen); - /* JAN: TODO: MySQL: 5.7 virtual columsn - handler::my_prepare_gcolumn_template( - thd, t_dbname, t_tbname, - &innobase_build_v_templ_callback, - static_cast(table)); - ut_ad(!ret); - */ + if (!mysql_table && THDVAR(thd, background_thread)) { + /* only open the table in background purge threads */ + mysql_table = open_purge_table(thd, t_dbname, dbnamelen, + t_tbname, tbnamelen); + } + + table->vc_templ->mysql_table = mysql_table; + table->vc_templ->mysql_table_query_id = thd_get_query_id(thd); + return mysql_table; +} + +/** Get the computed value by supplying the base column values. +@param[in,out] table table whose virtual column template to be built */ +void +innobase_init_vc_templ( + dict_table_t* table) +{ + if (table->vc_templ != NULL) { + return; + } + + table->vc_templ = UT_NEW_NOKEY(dict_vcol_templ_t()); + + TABLE *mysql_table= innobase_find_mysql_table_for_vc(current_thd, table); + + ut_ad(mysql_table); + if (!mysql_table) { + return; + } + + mutex_enter(&dict_sys->mutex); + innobase_build_v_templ(mysql_table, table, table->vc_templ, NULL, true); mutex_exit(&dict_sys->mutex); } @@ -23542,7 +23692,6 @@ innobase_get_computed_value( upd_t* parent_update, dict_foreign_t* foreign) { - byte rec_buf1[REC_VERSION_56_MAX_INDEX_COL_LEN]; byte rec_buf2[REC_VERSION_56_MAX_INDEX_COL_LEN]; byte* mysql_rec; byte* buf; @@ -23568,15 +23717,20 @@ innobase_get_computed_value( *local_heap = mem_heap_create(UNIV_PAGE_SIZE); } - mysql_rec = static_cast(mem_heap_alloc( - *local_heap, index->table->vc_templ->rec_len)); buf = static_cast(mem_heap_alloc( *local_heap, index->table->vc_templ->rec_len)); } else { - mysql_rec = rec_buf1; buf = rec_buf2; } + if (!mysql_table) { + mysql_table = innobase_find_mysql_table_for_vc(thd, index->table); + } + + ut_ad(mysql_table); + + mysql_rec = mysql_table->record[0]; + for (ulint i = 0; i < col->num_base; i++) { dict_col_t* base_col = col->base_col[i]; const dfield_t* row_field = NULL; @@ -23635,46 +23789,11 @@ innobase_get_computed_value( field = dtuple_get_nth_v_field(row, col->v_pos); - /* Bitmap for specifying which virtual columns the server - should evaluate */ - MY_BITMAP column_map; - my_bitmap_map col_map_storage[bitmap_buffer_size(REC_MAX_N_FIELDS)]; - - bitmap_init(&column_map, col_map_storage, REC_MAX_N_FIELDS, false); - - /* Specify the column the server should evaluate */ - bitmap_set_bit(&column_map, col->m_col.ind); - - if (mysql_table == NULL) { - if (vctempl->type == DATA_BLOB) { - ulint max_len; - - if (vctempl->mysql_col_len - 8 == 1) { - /* This is for TINYBLOB only, which needs - only 1 byte, other BLOBs won't be affected */ - max_len = 255; - } else { - max_len = DICT_MAX_FIELD_LEN_BY_FORMAT( - index->table) + 1; - } - - byte* blob_mem = static_cast( - mem_heap_alloc(heap, max_len)); - - row_mysql_store_blob_ref( - mysql_rec + vctempl->mysql_col_offset, - vctempl->mysql_col_len, blob_mem, max_len); - } - - ret = handler::my_eval_gcolumn_expr_with_open( - thd, index->table->vc_templ->db_name.c_str(), - index->table->vc_templ->tb_name.c_str(), &column_map, - (uchar *)mysql_rec); - } else { - ret = handler::my_eval_gcolumn_expr( - thd, mysql_table, &column_map, - (uchar *)mysql_rec); - } + my_bitmap_map* old_write_set = dbug_tmp_use_all_columns(mysql_table, mysql_table->write_set); + my_bitmap_map* old_read_set = dbug_tmp_use_all_columns(mysql_table, mysql_table->read_set); + ret = mysql_table->update_virtual_field(mysql_table->field[col->m_col.ind]); + dbug_tmp_restore_column_map(mysql_table->read_set, old_read_set); + dbug_tmp_restore_column_map(mysql_table->write_set, old_write_set); if (ret != 0) { #ifdef INNODB_VIRTUAL_DEBUG @@ -23725,7 +23844,7 @@ innobase_get_computed_value( return(field); } -#endif /* MYSQL_VIRTUAL_COLUMNS */ + /** Attempt to push down an index condition. @param[in] keyno MySQL key number diff --git a/storage/innobase/handler/ha_innodb.h b/storage/innobase/handler/ha_innodb.h index a78925d94e1..99d50d82fd1 100644 --- a/storage/innobase/handler/ha_innodb.h +++ b/storage/innobase/handler/ha_innodb.h @@ -119,6 +119,8 @@ public: const key_map* keys_to_use_for_scanning(); + void column_bitmaps_signal(); + /** Opens dictionary table object using table name. For partition, we need to try alternative lower/upper case names to support moving data files across platforms. @@ -781,6 +783,8 @@ public: @return NULL if valid, string name of bad option if not. */ const char* create_options_are_invalid(); + bool gcols_in_fulltext_or_spatial(); + /** Validates engine specific table options not handled by SQL-parser. @return NULL if valid, string name of bad option if not. */ @@ -1037,13 +1041,9 @@ innodb_base_col_setup_for_stored( dict_s_col_t* s_col); /** whether this is a stored column */ -// JAN: TODO: MySQL 5.7 virtual fields -//#define innobase_is_s_fld(field) ((field)->gcol_info && (field)->stored_in_db) -#define innobase_is_s_fld(field) (field == NULL) -// JAN: TODO: MySQL 5.7 virtual fields +#define innobase_is_s_fld(field) ((field)->vcol_info && (field)->stored_in_db()) /** whether this is a computed virtual column */ -//#define innobase_is_v_fld(field) ((field)->gcol_info && !(field)->stored_in_db) -#define innobase_is_v_fld(field) (field == NULL) +#define innobase_is_v_fld(field) ((field)->vcol_info && !(field)->stored_in_db()) /** Release temporary latches. Call this function when mysqld passes control to the client. That is to @@ -1120,16 +1120,14 @@ innodb_rec_per_key( @param[in,out] s_templ InnoDB template structure @param[in] add_v new virtual columns added along with add index call -@param[in] locked true if innobase_share_mutex is held -@param[in] share_tbl_name original MySQL table name */ +@param[in] locked true if innobase_share_mutex is held */ void innobase_build_v_templ( const TABLE* table, const dict_table_t* ib_table, dict_vcol_templ_t* s_templ, const dict_add_v_col_t* add_v, - bool locked, - const char* share_tbl_name); + bool locked); /** callback used by MySQL server layer to initialized the table virtual columns' template diff --git a/storage/innobase/handler/handler0alter.cc b/storage/innobase/handler/handler0alter.cc index 3da543d246e..51aef715ee2 100644 --- a/storage/innobase/handler/handler0alter.cc +++ b/storage/innobase/handler/handler0alter.cc @@ -59,6 +59,10 @@ Smart ALTER TABLE #include // PROCESS_ACL #endif +static const char *MSG_UNSUPPORTED_ALTER_ONLINE_ON_VIRTUAL_COLUMN= + "INPLACE ADD or DROP of virtual columns cannot be " + "combined with other ALTER TABLE actions"; + /* For supporting Native InnoDB Partitioning. */ /* JAN: TODO: MySQL 5.7 #include "partition_info.h" @@ -67,7 +71,8 @@ Smart ALTER TABLE /** Operations for creating secondary indexes (no rebuild needed) */ static const Alter_inplace_info::HA_ALTER_FLAGS INNOBASE_ONLINE_CREATE = Alter_inplace_info::ADD_INDEX - | Alter_inplace_info::ADD_UNIQUE_INDEX; + | Alter_inplace_info::ADD_UNIQUE_INDEX + | Alter_inplace_info::ADD_SPATIAL_INDEX; /** Operations for rebuilding a table in place */ static const Alter_inplace_info::HA_ALTER_FLAGS INNOBASE_ALTER_REBUILD @@ -77,17 +82,12 @@ static const Alter_inplace_info::HA_ALTER_FLAGS INNOBASE_ALTER_REBUILD /* CHANGE_CREATE_OPTION needs to check innobase_need_rebuild() */ | Alter_inplace_info::ALTER_COLUMN_NULLABLE | Alter_inplace_info::ALTER_COLUMN_NOT_NULLABLE - | Alter_inplace_info::ALTER_COLUMN_ORDER - | Alter_inplace_info::DROP_COLUMN - | Alter_inplace_info::ADD_COLUMN -#ifdef MYSQL_VIRTUAL_COLUMNS | Alter_inplace_info::ALTER_STORED_COLUMN_ORDER | Alter_inplace_info::DROP_STORED_COLUMN | Alter_inplace_info::ADD_STORED_BASE_COLUMN - | Alter_inplace_info::ALTER_STORED_COLUMN_TYPE -#endif | Alter_inplace_info::RECREATE_TABLE /* + | Alter_inplace_info::ALTER_STORED_COLUMN_TYPE */ ; @@ -101,9 +101,7 @@ static const Alter_inplace_info::HA_ALTER_FLAGS INNOBASE_INPLACE_IGNORE | Alter_inplace_info::ALTER_PARTITIONED | Alter_inplace_info::ALTER_COLUMN_COLUMN_FORMAT | Alter_inplace_info::ALTER_COLUMN_STORAGE_TYPE -#ifdef MYSQL_VIRTUAL_COLUMNS | Alter_inplace_info::ALTER_VIRTUAL_GCOL_EXPR -#endif | Alter_inplace_info::ALTER_RENAME; /** Operations on foreign key definitions (changing the schema only) */ @@ -121,15 +119,12 @@ static const Alter_inplace_info::HA_ALTER_FLAGS INNOBASE_ALTER_NOREBUILD | Alter_inplace_info::RENAME_INDEX #endif | Alter_inplace_info::ALTER_COLUMN_NAME - | Alter_inplace_info::ALTER_COLUMN_EQUAL_PACK_LENGTH; -#ifdef MYSQL_VIRTUAL_COLUMNS - | Alter_inplace_info::ALTER_INDEX_COMMENT + | Alter_inplace_info::ALTER_COLUMN_EQUAL_PACK_LENGTH + //| Alter_inplace_info::ALTER_INDEX_COMMENT | Alter_inplace_info::ADD_VIRTUAL_COLUMN | Alter_inplace_info::DROP_VIRTUAL_COLUMN - | Alter_inplace_info::ALTER_VIRTUAL_COLUMN_ORDER - | Alter_inplace_info::ALTER_VIRTUAL_COLUMN_TYPE -#endif - ; + | Alter_inplace_info::ALTER_VIRTUAL_COLUMN_ORDER; + struct ha_innobase_inplace_ctx : public inplace_alter_handler_ctx { /** Dummy query graph */ @@ -453,7 +448,6 @@ innobase_need_rebuild( return(!!(ha_alter_info->handler_flags & INNOBASE_ALTER_REBUILD)); } -#ifdef MYSQL_VIRTUAL_COLUMNS /** Check if virtual column in old and new table are in order, excluding those dropped column. This is needed because when we drop a virtual column, ALTER_VIRTUAL_COLUMN_ORDER is also turned on, so we can't decide if this @@ -484,7 +478,7 @@ check_v_col_in_order( cf_it.rewind(); while (const Create_field* new_field = cf_it++) { - if (!new_field->is_virtual_gcol()) { + if (!innobase_is_v_fld(new_field)) { continue; } @@ -510,11 +504,9 @@ check_v_col_in_order( } for (ulint i = 0; i < table->s->fields; i++) { - Field* field = table->s->field[i]; - bool dropped = false; - Alter_drop* drop; + Field* field = table->field[i]; - if (field->stored_in_db) { + if (field->stored_in_db()) { continue; } @@ -529,7 +521,7 @@ check_v_col_in_order( while (j < altered_table->s->fields) { Field* new_field = altered_table->s->field[j]; - if (new_field->stored_in_db) { + if (new_field->stored_in_db()) { j++; continue; } @@ -555,7 +547,6 @@ check_v_col_in_order( return(true); } -#endif /* MYSQL_VIRTUAL_COLUMNS */ /** Check if InnoDB supports a particular alter table in-place @param altered_table TABLE object for new version of table. @@ -590,7 +581,7 @@ ha_innobase::check_if_supported_inplace_alter( DBUG_RETURN(HA_ALTER_INPLACE_NOT_SUPPORTED); } - if (altered_table->s->stored_fields > REC_MAX_N_USER_FIELDS) { + if (altered_table->s->fields > REC_MAX_N_USER_FIELDS) { /* Deny the inplace ALTER TABLE. MySQL will try to re-create the table and ha_innobase::create() will return an error too. This is how we effectively @@ -646,14 +637,11 @@ ha_innobase::check_if_supported_inplace_alter( | INNOBASE_ALTER_NOREBUILD | INNOBASE_ALTER_REBUILD)) { -#ifdef MYSQL_VIRTUAL_COLUMNS if (ha_alter_info->handler_flags & Alter_inplace_info::ALTER_STORED_COLUMN_TYPE) { ha_alter_info->unsupported_reason = innobase_get_err_msg( ER_ALTER_OPERATION_NOT_SUPPORTED_REASON_COLUMN_TYPE); } -#endif - DBUG_RETURN(HA_ALTER_INPLACE_NOT_SUPPORTED); } @@ -794,8 +782,8 @@ ha_innobase::check_if_supported_inplace_alter( DBUG_RETURN(HA_ALTER_INPLACE_NOT_SUPPORTED); } -#ifdef MYSQL_VIRTUAL_COLUMNS - // JAN: TODO: MySQL 5.7 Virtual columns + bool add_drop_v_cols = false; + /* If there is add or drop virtual columns, we will support operations with these 2 options alone with inplace interface for now */ @@ -812,8 +800,8 @@ ha_innobase::check_if_supported_inplace_alter( | Alter_inplace_info::DROP_VIRTUAL_COLUMN | Alter_inplace_info::ALTER_VIRTUAL_COLUMN_ORDER | Alter_inplace_info::ALTER_VIRTUAL_GCOL_EXPR + | Alter_inplace_info::ALTER_COLUMN_VCOL /* - | Alter_inplace_info::ALTER_STORED_COLUMN_ORDER | Alter_inplace_info::ADD_STORED_BASE_COLUMN | Alter_inplace_info::DROP_STORED_COLUMN | Alter_inplace_info::ALTER_STORED_COLUMN_ORDER @@ -828,14 +816,12 @@ ha_innobase::check_if_supported_inplace_alter( || (!check_v_col_in_order( this->table, altered_table, ha_alter_info))) { ha_alter_info->unsupported_reason = - innobase_get_err_msg( - ER_UNSUPPORTED_ALTER_INPLACE_ON_VIRTUAL_COLUMN); + MSG_UNSUPPORTED_ALTER_ONLINE_ON_VIRTUAL_COLUMN; DBUG_RETURN(HA_ALTER_INPLACE_NOT_SUPPORTED); } add_drop_v_cols = true; } -#endif /* MYSQL_VIRTUAL_COLUMNS */ /* We should be able to do the operation in-place. See if we can do it online (LOCK=NONE). */ @@ -850,18 +836,15 @@ ha_innobase::check_if_supported_inplace_alter( + ha_alter_info->key_count; new_key++) { -#ifdef MYSQL_VIRTUAL_COLUMNS /* Do not support adding/droping a virtual column, while there is a table rebuild caused by adding a new FTS_DOC_ID */ if ((new_key->flags & HA_FULLTEXT) && add_drop_v_cols && !DICT_TF2_FLAG_IS_SET(m_prebuilt->table, DICT_TF2_FTS_HAS_DOC_ID)) { ha_alter_info->unsupported_reason = - innobase_get_err_msg( - ER_UNSUPPORTED_ALTER_INPLACE_ON_VIRTUAL_COLUMN); + MSG_UNSUPPORTED_ALTER_ONLINE_ON_VIRTUAL_COLUMN; DBUG_RETURN(HA_ALTER_INPLACE_NOT_SUPPORTED); } -#endif /* MYSQL_VIRTUAL_COLUMNS */ for (KEY_PART_INFO* key_part = new_key->key_part; key_part < new_key->key_part + new_key->user_defined_key_parts; @@ -928,31 +911,27 @@ ha_innobase::check_if_supported_inplace_alter( online = false; } -#ifdef MYSQL_VIRTUAL_COLUMNS - if (key_part->field->is_virtual_gcol()) { + if (innobase_is_v_fld(key_part->field)) { /* Do not support adding index on newly added virtual column, while there is also a drop virtual column in the same clause */ if (ha_alter_info->handler_flags & Alter_inplace_info::DROP_VIRTUAL_COLUMN) { ha_alter_info->unsupported_reason = - innobase_get_err_msg( - ER_UNSUPPORTED_ALTER_INPLACE_ON_VIRTUAL_COLUMN); + MSG_UNSUPPORTED_ALTER_ONLINE_ON_VIRTUAL_COLUMN; DBUG_RETURN(HA_ALTER_INPLACE_NOT_SUPPORTED); } ha_alter_info->unsupported_reason = - innobase_get_err_msg( - ER_UNSUPPORTED_ALTER_ONLINE_ON_VIRTUAL_COLUMN); + MSG_UNSUPPORTED_ALTER_ONLINE_ON_VIRTUAL_COLUMN; online = false; } -#endif /* MYSQL_VIRTUAL_COLUMNS */ } } DBUG_ASSERT(!m_prebuilt->table->fts || m_prebuilt->table->fts->doc_col - <= table->s->stored_fields); + <= table->s->fields); DBUG_ASSERT(!m_prebuilt->table->fts || m_prebuilt->table->fts->doc_col < dict_table_get_n_user_cols(m_prebuilt->table)); @@ -1356,8 +1335,6 @@ next_rec: return(NULL); } -#ifdef MYSQL_VIRTUAL_COLUMNS - /** Check whether given column is a base of stored column. @param[in] col_name column name @param[in] table table @@ -1419,7 +1396,6 @@ innobase_check_fk_stored( return(false); } -#endif /* MYSQL_VIRTUAL_COLUMNS */ /** Create InnoDB foreign key structure from MySQL alter_info @param[in] ha_alter_info alter table info @@ -1667,13 +1643,14 @@ innobase_get_foreign_key_info( goto err_exit; } -#ifdef MYSQL_VIRTUAL_COLUMNS if (innobase_check_fk_stored( add_fk[num_fk], table, s_cols)) { - my_error(ER_CANNOT_ADD_FOREIGN_BASE_COL_STORED, MYF(0)); + my_printf_error( + HA_ERR_UNSUPPORTED, + "Cannot add foreign key on the base column " + "of stored column", MYF(0)); goto err_exit; } -#endif num_fk++; } @@ -1794,24 +1771,19 @@ innobase_rec_to_mysql( const ulint* offsets)/*!< in: rec_get_offsets( rec, index, ...) */ { - uint n_fields = table->s->stored_fields; - uint sql_idx = 0; + uint n_fields = table->s->fields; ut_ad(n_fields == dict_table_get_n_user_cols(index->table) - !!(DICT_TF2_FLAG_IS_SET(index->table, DICT_TF2_FTS_HAS_DOC_ID))); - for (uint i = 0; i < n_fields; i++, sql_idx++) { - Field* field; + for (uint i = 0; i < n_fields; i++) { + Field* field = table->field[i]; ulint ipos; ulint ilen; const uchar* ifield; ulint prefix_col; - while (!((field= table->field[sql_idx])->stored_in_db())) { - sql_idx++; - } - field->reset(); ipos = dict_index_get_nth_col_or_prefix_pos( @@ -1852,8 +1824,7 @@ innobase_fields_to_mysql( const dict_index_t* index, /*!< in: InnoDB index */ const dfield_t* fields) /*!< in: InnoDB index fields */ { - uint n_fields = table->s->stored_fields; - uint sql_idx = 0; + uint n_fields = table->s->fields; ulint num_v = 0; ut_ad(n_fields == dict_table_get_n_user_cols(index->table) @@ -1861,16 +1832,12 @@ innobase_fields_to_mysql( - !!(DICT_TF2_FLAG_IS_SET(index->table, DICT_TF2_FTS_HAS_DOC_ID))); - for (uint i = 0; i < n_fields; i++, sql_idx++) { - Field* field; + for (uint i = 0; i < n_fields; i++) { + Field* field = table->field[i]; ulint ipos; ulint col_n; ulint prefix_col; - while (!((field= table->field[sql_idx])->stored_in_db())) { - sql_idx++; - } - field->reset(); if (innobase_is_v_fld(field)) { @@ -1914,9 +1881,8 @@ innobase_row_to_mysql( const dict_table_t* itab, /*!< in: InnoDB table */ const dtuple_t* row) /*!< in: InnoDB row */ { - uint n_fields = table->s->stored_fields; - uint sql_idx = 0; - uint num_v = 0; + uint n_fields = table->s->fields; + ulint num_v = 0; /* The InnoDB row may contain an extra FTS_DOC_ID column at the end. */ ut_ad(row->n_fields == dict_table_get_n_cols(itab)); @@ -1924,12 +1890,8 @@ innobase_row_to_mysql( + dict_table_get_n_v_cols(itab) - !!(DICT_TF2_FLAG_IS_SET(itab, DICT_TF2_FTS_HAS_DOC_ID))); - for (uint i = 0; i < n_fields; i++, sql_idx++) { - Field* field; - - while (!((field= table->field[sql_idx])->stored_in_db())) { - sql_idx++; - } + for (uint i = 0; i < n_fields; i++) { + Field* field = table->field[i]; field->reset(); @@ -1953,6 +1915,11 @@ innobase_row_to_mysql( dfield_get_len(df), field); } } + if (table->vfield) { + my_bitmap_map* old_vcol_set = tmp_use_all_columns(table, table->vcol_set); + table->update_virtual_fields(VCOL_UPDATE_FOR_READ_WRITE); + tmp_restore_column_map(table->vcol_set, old_vcol_set); + } } /*************************************************************//** @@ -2129,22 +2096,19 @@ name_ok: is not being created @param[in] key_part MySQL key definition @param[in,out] index_field index field -@param[in] new_clustered new cluster -@param[in] fields MySQL table fields*/ +@param[in] new_clustered new cluster */ static void innobase_create_index_field_def( const TABLE* altered_table, const KEY_PART_INFO* key_part, index_field_t* index_field, - bool new_clustered, - const Field** fields) + bool new_clustered) { const Field* field; ibool is_unsigned; ulint col_type; ulint num_v = 0; - ulint num_m_v = 0; DBUG_ENTER("innobase_create_index_field_def"); @@ -2157,33 +2121,21 @@ innobase_create_index_field_def( ut_a(field); for (ulint i = 0; i < key_part->fieldnr; i++) { - const Field* ifield = altered_table->field[i]; - if (innobase_is_v_fld(ifield)) { + if (innobase_is_v_fld(altered_table->field[i])) { num_v++; } - - if (!ifield->stored_in_db()) { - num_m_v++; - } } col_type = get_innobase_type_from_mysql_type( &is_unsigned, field); -#ifdef MYSQL_VIRTUAL_COLUMNS - if (!field->stored_in_db && field->gcol_info) { - if (!field->stored_in_db && false) { - index_field->is_v_col = true; - index_field->col_no = num_v; - } else { - index_field->is_v_col = false; - index_field->col_no = key_part->fieldnr - num_v; - } + if (innobase_is_v_fld(field)) { + index_field->is_v_col = true; + index_field->col_no = num_v; + } else { + index_field->is_v_col = false; + index_field->col_no = key_part->fieldnr - num_v; } -#else - index_field->is_v_col = false; - index_field->col_no = key_part->fieldnr - num_m_v; -#endif /* MYSQL_VIRTUAL_COLUMNS */ if (DATA_LARGE_MTYPE(col_type) || (key_part->length < field->pack_length() @@ -2218,8 +2170,7 @@ innobase_create_index_def( bool new_clustered, bool key_clustered, index_def_t* index, - mem_heap_t* heap, - const Field** fields) + mem_heap_t* heap) { const KEY* key = &keys[key_number]; ulint i; @@ -2298,21 +2249,16 @@ innobase_create_index_def( index->fields[0].prefix_len = 0; index->fields[0].is_v_col = false; - #ifdef MYSQL_VIRTUAL_COLUMNS - if (!key->key_part[0].field->stored_in_db - && key->key_part[0].field->gcol_info) { + if (innobase_is_v_fld(key->key_part[0].field)) { /* Currently, the spatial index cannot be created on virtual columns. It is blocked in server layer */ - ut_ad(0); index->fields[0].is_v_col = true; } else { - index->fields[0].is_v_col = false; } -#endif /* MYSQL_VIRTUAL_COLUMNS */ } else { index->ind_type = (key->flags & HA_NOSAME) ? DICT_UNIQUE : 0; } @@ -2321,7 +2267,7 @@ innobase_create_index_def( for (i = 0; i < n_fields; i++) { innobase_create_index_field_def( altered_table, &key->key_part[i], - &index->fields[i], new_clustered, fields); + &index->fields[i], new_clustered); if (index->fields[i].is_v_col) { index->ind_type |= DICT_VIRTUAL; @@ -2352,18 +2298,13 @@ innobase_fts_check_doc_id_col( { *fts_doc_col_no = ULINT_UNDEFINED; - const uint n_cols = altered_table->s->stored_fields; - uint sql_idx = 0; + const uint n_cols = altered_table->s->fields; ulint i; *num_v = 0; - for (i = 0; i < n_cols; i++, sql_idx++) { - const Field* field; - - while (!((field= altered_table->field[sql_idx])->stored_in_db())) { - sql_idx++; - } + for (i = 0; i < n_cols; i++) { + const Field* field = altered_table->field[i]; if (innobase_is_v_fld(field)) { (*num_v)++; @@ -2676,7 +2617,7 @@ innobase_create_key_defs( /* Create the PRIMARY key index definition */ innobase_create_index_def( altered_table, key_info, primary_key_number, - TRUE, TRUE, indexdef++, heap, (const Field **)altered_table->field); + true, true, indexdef++, heap); created_clustered: n_add = 1; @@ -2688,7 +2629,7 @@ created_clustered: /* Copy the index definitions. */ innobase_create_index_def( altered_table, key_info, i, true, - false, indexdef, heap, (const Field **)altered_table->field); + false, indexdef, heap); if (indexdef->ind_type & DICT_FTS) { n_fts_add++; @@ -2705,8 +2646,7 @@ created_clustered: && !innobase_fts_check_doc_id_col( NULL, altered_table, &fts_doc_id_col, &num_v)) { - fts_doc_id_col = - altered_table->s->stored_fields; + fts_doc_id_col = altered_table->s->fields - num_v; add_fts_doc_id = true; } @@ -2735,7 +2675,7 @@ created_clustered: for (ulint i = 0; i < n_add; i++) { innobase_create_index_def( altered_table, key_info, add[i], - false, false, indexdef, heap, (const Field **)altered_table->field); + false, false, indexdef, heap); if (indexdef->ind_type & DICT_FTS) { n_fts_add++; @@ -3136,16 +3076,15 @@ innobase_build_col_map( dtuple_t* add_cols, mem_heap_t* heap) { - uint old_i, old_innobase_i; DBUG_ENTER("innobase_build_col_map"); DBUG_ASSERT(altered_table != table); DBUG_ASSERT(new_table != old_table); DBUG_ASSERT(dict_table_get_n_cols(new_table) + dict_table_get_n_v_cols(new_table) - >= altered_table->s->stored_fields + DATA_N_SYS_COLS); + >= altered_table->s->fields + DATA_N_SYS_COLS); DBUG_ASSERT(dict_table_get_n_cols(old_table) + dict_table_get_n_v_cols(old_table) - >= table->s->stored_fields + DATA_N_SYS_COLS); + >= table->s->fields + DATA_N_SYS_COLS); DBUG_ASSERT(!!add_cols == !!(ha_alter_info->handler_flags & Alter_inplace_info::ADD_COLUMN)); DBUG_ASSERT(!add_cols || dtuple_get_n_fields(add_cols) @@ -3158,14 +3097,13 @@ innobase_build_col_map( List_iterator_fast cf_it( ha_alter_info->alter_info->create_list); - uint i = 0, sql_idx = 0; + uint i = 0; uint num_v = 0; /* Any dropped columns will map to ULINT_UNDEFINED. */ - for (old_innobase_i = 0; - old_innobase_i + DATA_N_SYS_COLS < old_table->n_cols; - old_innobase_i++) { - col_map[old_innobase_i] = ULINT_UNDEFINED; + for (uint old_i = 0; old_i + DATA_N_SYS_COLS < old_table->n_cols; + old_i++) { + col_map[old_i] = ULINT_UNDEFINED; } for (uint old_i = 0; old_i < old_table->n_v_cols; old_i++) { @@ -3181,21 +3119,8 @@ innobase_build_col_map( ulint num_old_v = 0; - if (!new_field->stored_in_db()) - { - sql_idx++; - continue; - } - - for (old_i = 0, old_innobase_i= 0; - table->field[old_i]; - old_i++) { + for (uint old_i = 0; table->field[old_i]; old_i++) { const Field* field = table->field[old_i]; - - if (!table->field[old_i]->stored_in_db()) { - continue; - } - if (innobase_is_v_fld(field)) { if (is_v && new_field->field == field) { col_map[old_table->n_cols + num_v] @@ -3208,30 +3133,27 @@ innobase_build_col_map( } if (new_field->field == field) { - col_map[old_innobase_i] = i; + col_map[old_i - num_old_v] = i; goto found_col; } - old_innobase_i++; } ut_ad(!is_v); innobase_build_col_map_add( heap, dtuple_get_nth_field(add_cols, i), - altered_table->field[sql_idx], + altered_table->field[i + num_v], dict_table_is_comp(new_table)); found_col: if (is_v) { num_v++; } else { i++; - sql_idx++; } } - DBUG_ASSERT(i == altered_table->s->stored_fields - num_v); + DBUG_ASSERT(i == altered_table->s->fields - num_v); - i = table->s->stored_fields; - //i = table->s->fields - old_table->n_v_cols; + i = table->s->fields - old_table->n_v_cols; /* Add the InnoDB hidden FTS_DOC_ID column, if any. */ if (i + DATA_N_SYS_COLS < old_table->n_cols) { @@ -3241,21 +3163,21 @@ found_col: DICT_TF2_FTS_HAS_DOC_ID)); DBUG_ASSERT(i + DATA_N_SYS_COLS + 1 == old_table->n_cols); DBUG_ASSERT(!strcmp(dict_table_get_col_name( - old_table, table->s->stored_fields), + old_table, i), FTS_DOC_ID_COL_NAME)); - if (altered_table->s->stored_fields + DATA_N_SYS_COLS + if (altered_table->s->fields + DATA_N_SYS_COLS - new_table->n_v_cols < new_table->n_cols) { DBUG_ASSERT(DICT_TF2_FLAG_IS_SET( new_table, DICT_TF2_FTS_HAS_DOC_ID)); - DBUG_ASSERT(altered_table->s->stored_fields + DBUG_ASSERT(altered_table->s->fields + DATA_N_SYS_COLS + 1 - == new_table->n_cols); - col_map[i] = altered_table->s->stored_fields; - /* col_map[i] = altered_table->s->fields + == static_cast( + new_table->n_cols + + new_table->n_v_cols)); + col_map[i] = altered_table->s->fields - new_table->n_v_cols; - */ } else { DBUG_ASSERT(!DICT_TF2_FLAG_IS_SET( new_table, @@ -3671,8 +3593,6 @@ innobase_check_gis_columns( DBUG_RETURN(DB_SUCCESS); } -#ifdef MYSQL_VIRTUAL_COLUMNS - /** Collect virtual column info for its addition @param[in] ha_alter_info Data used during in-place alter @param[in] altered_table MySQL table that is being altered to @@ -3738,10 +3658,8 @@ prepare_inplace_add_virtual( &is_unsigned, field); - if (!field->gcol_info || field->stored_in_db) { - my_error(ER_WRONG_KEY_COLUMN, MYF(0), - field->field_name); - return(true); + if (!innobase_is_v_fld(field)) { + continue; } col_len = field->pack_length(); @@ -3798,13 +3716,9 @@ prepare_inplace_add_virtual( ctx->add_vcol[j].m_col.len = col_len; ctx->add_vcol[j].m_col.ind = i - 1; - /* ctx->add_vcol[j].num_base = - field->gcol_info->non_virtual_base_columns(); - */ + ctx->add_vcol[j].num_base = 0; ctx->add_vcol_name[j] = field->field_name; - ctx->add_vcol[j].base_col = static_cast( - mem_heap_alloc(ctx->heap, ctx->add_vcol[j].num_base - * sizeof *(ctx->add_vcol[j].base_col))); + ctx->add_vcol[j].base_col = NULL; ctx->add_vcol[j].v_pos = ctx->old_table->n_v_cols - ctx->num_to_drop_vcol + j; @@ -3833,12 +3747,17 @@ prepare_inplace_drop_virtual( ha_innobase_inplace_ctx* ctx; ulint i = 0; ulint j = 0; - Alter_drop *drop; ctx = static_cast (ha_alter_info->handler_ctx); - ctx->num_to_drop_vcol = ha_alter_info->alter_info->drop_list.elements; + ctx->num_to_drop_vcol = 0; + for (i = 0; table->field[i]; i++) { + const Field* field = table->field[i]; + if (field->flags & FIELD_IS_DROPPED && !field->stored_in_db()) { + ctx->num_to_drop_vcol++; + } + } ctx->drop_vcol = static_cast( mem_heap_alloc(ctx->heap, ctx->num_to_drop_vcol @@ -3847,26 +3766,9 @@ prepare_inplace_drop_virtual( mem_heap_alloc(ctx->heap, ctx->num_to_drop_vcol * sizeof *ctx->drop_vcol_name)); - List_iterator_fast cf_it( - ha_alter_info->alter_info->drop_list); - - while ((drop = (cf_it++)) != NULL) { - const Field* field; - ulint old_i; - - ut_ad(drop->type == Alter_drop::COLUMN); - - for (old_i = 0; table->field[old_i]; old_i++) { - const Field* n_field = table->field[old_i]; - if (!my_strcasecmp(system_charset_info, - n_field->field_name, drop->name)) { - break; - } - } - - i++; - - if (!table->field[old_i]) { + for (i = 0; table->field[i]; i++) { + Field *field = table->field[i]; + if (!(field->flags & FIELD_IS_DROPPED) || field->stored_in_db()) { continue; } @@ -3875,19 +3777,10 @@ prepare_inplace_drop_virtual( ulint field_type; ulint charset_no; - field = table->field[old_i]; - ulint col_type = get_innobase_type_from_mysql_type( &is_unsigned, field); - - if (!field->gcol_info || field->stored_in_db) { - my_error(ER_WRONG_KEY_COLUMN, MYF(0), - field->field_name); - return(true); - } - col_len = field->pack_length(); field_type = (ulint) field->type(); @@ -3941,12 +3834,12 @@ prepare_inplace_drop_virtual( ctx->drop_vcol[j].m_col.len = col_len; - ctx->drop_vcol[j].m_col.ind = old_i; + ctx->drop_vcol[j].m_col.ind = i; ctx->drop_vcol_name[j] = field->field_name; dict_v_col_t* v_col = dict_table_get_nth_v_col_mysql( - ctx->old_table, old_i); + ctx->old_table, i); ctx->drop_vcol[j].v_pos = v_col->v_pos; j++; } @@ -4404,7 +4297,7 @@ innodb_v_adjust_idx_col( /* Found the field in the new table */ while (const Create_field* new_field = cf_it++) { - if (!new_field->is_virtual_gcol()) { + if (!innobase_is_v_fld(new_field)) { continue; } @@ -4424,7 +4317,7 @@ innodb_v_adjust_idx_col( ut_a(0); } - ut_ad(field->is_virtual_gcol()); + ut_ad(innobase_is_v_fld(field)); num_v = 0; @@ -4438,7 +4331,7 @@ innodb_v_adjust_idx_col( break; } - if (old_table->field[old_i]->is_virtual_gcol()) { + if (innobase_is_v_fld(old_table->field[old_i])) { num_v++; } } @@ -4446,7 +4339,6 @@ innodb_v_adjust_idx_col( ut_ad(col_found); } } -#endif /* MYSQL_VIRTUAL_COLUMNS */ /** Update internal structures with concurrent writes blocked, while preparing ALTER TABLE. @@ -4511,7 +4403,6 @@ prepare_inplace_alter_table_dict( trx_start_if_not_started_xa(ctx->prebuilt->trx, true); -#ifdef MYSQL_VIRTUAL_COLUMNS if (ha_alter_info->handler_flags & Alter_inplace_info::DROP_VIRTUAL_COLUMN) { if (prepare_inplace_drop_virtual( @@ -4543,7 +4434,6 @@ prepare_inplace_alter_table_dict( /* There should be no order change for virtual columns coming in here */ ut_ad(check_v_col_in_order(old_table, altered_table, ha_alter_info)); -#endif /* MYSQL_VIRTUAL_COLUMNS */ /* Create a background transaction for the operations on the data dictionary tables. */ @@ -4658,9 +4548,9 @@ prepare_inplace_alter_table_dict( ctx->new_table->id); ulint n_cols = 0; ulint n_v_cols = 0; - ulint n_mv_cols = 0; dtuple_t* add_cols; ulint space_id = 0; + ulint z = 0; ulint key_id = FIL_DEFAULT_ENCRYPTION_KEY; fil_encryption_t mode = FIL_SPACE_ENCRYPTION_DEFAULT; const char* compression=NULL; @@ -4684,15 +4574,11 @@ prepare_inplace_alter_table_dict( if (innobase_is_v_fld(field)) { n_v_cols++; } else { - if (field->stored_in_db()) { n_cols++; - } else { - n_mv_cols++; - } } } - ut_ad(n_cols + n_v_cols + n_mv_cols == altered_table->s->fields); + ut_ad(n_cols + n_v_cols == altered_table->s->fields); if (add_fts_doc_id) { n_cols++; @@ -4744,21 +4630,17 @@ prepare_inplace_alter_table_dict( user_table->data_dir_path); } - for (uint i = 0, sql_idx=0; i < altered_table->s->stored_fields; i++, sql_idx++) { - Field* field; + for (uint i = 0; i < altered_table->s->fields; i++) { + const Field* field = altered_table->field[i]; ulint is_unsigned; - ulint charset_no; - ulint col_len; - - while (!((field= altered_table->field[sql_idx])->stored_in_db())) { - sql_idx++; - } - - ulint field_type = (ulint) field->type(); - bool is_virtual = innobase_is_v_fld(field); + ulint field_type + = (ulint) field->type(); ulint col_type = get_innobase_type_from_mysql_type( &is_unsigned, field); + ulint charset_no; + ulint col_len; + bool is_virtual = innobase_is_v_fld(field); /* we assume in dtype_form_prtype() that this fits in two bytes */ @@ -4825,7 +4707,6 @@ prepare_inplace_alter_table_dict( } if (is_virtual) { -#ifdef MYSQL_VIRTUAL_COLUMNS dict_mem_table_add_v_col( ctx->new_table, ctx->heap, field->field_name, @@ -4833,9 +4714,7 @@ prepare_inplace_alter_table_dict( dtype_form_prtype( field_type, charset_no) | DATA_VIRTUAL, - col_len, i, - field->gcol_info->non_virtual_base_columns()); -#endif /* MYSQL_VIRTUAL_COLUMNS */ + col_len, i, 0); } else { dict_mem_table_add_col( ctx->new_table, ctx->heap, @@ -4847,9 +4726,6 @@ prepare_inplace_alter_table_dict( } } -#ifdef MYSQL_VIRTUAL_COLUMNS - ulint z = 0; - if (n_v_cols) { for (uint i = 0; i < altered_table->s->fields; i++) { dict_v_col_t* v_col; @@ -4865,15 +4741,12 @@ prepare_inplace_alter_table_dict( ctx->new_table, field, v_col); } } -#endif /* MYSQL_VIRTUAL_COLUMNS */ if (add_fts_doc_id) { fts_add_doc_id_column(ctx->new_table, ctx->heap); ctx->new_table->fts->doc_col = fts_doc_id_col; ut_ad(fts_doc_id_col - == altered_table->s->stored_fields - n_v_cols); - ut_ad(fts_doc_id_col == altered_table->s->stored_fields); - + == altered_table->s->fields - n_v_cols); } else if (ctx->new_table->fts) { ctx->new_table->fts->doc_col = fts_doc_id_col; } @@ -5023,14 +4896,12 @@ new_clustered_failed: for (ulint a = 0; a < ctx->num_to_add_index; a++) { -#ifdef MYSQL_VIRTUAL_COLUMNS if (index_defs[a].ind_type & DICT_VIRTUAL && ctx->num_to_drop_vcol > 0 && !new_clustered) { innodb_v_adjust_idx_col(ha_alter_info, old_table, ctx->num_to_drop_vcol, &index_defs[a]); } -#endif /* MYSQL_VIRTUAL_COLUMNS */ ctx->add_index[a] = row_merge_create_index( ctx->trx, ctx->new_table, @@ -5601,7 +5472,6 @@ rename_indexes_in_cache( } #endif /* MYSQL_RENAME_INDEX */ -#ifdef MYSQL_VIRTUAL_COLUMNS /** Fill the stored column information in s_cols list. @param[in] altered_table mysql table object @param[in] table innodb table object @@ -5626,7 +5496,7 @@ alter_fill_stored_column( continue; } - ulint num_base = field->gcol_info->non_virtual_base_columns(); + ulint num_base = 0; dict_col_t* col = dict_table_get_nth_col(table, i); s_col.m_col = col; @@ -5649,7 +5519,7 @@ alter_fill_stored_column( (*s_cols)->push_back(s_col); } } -#endif /* MYSQL_VIRTUAL_COLUMNS */ + /** Allows InnoDB to update internal structures with concurrent writes blocked (provided that check_if_supported_inplace_alter() @@ -5790,6 +5660,12 @@ ha_innobase::prepare_inplace_alter_table( info.set_tablespace_type(is_file_per_table); + if (ha_alter_info->handler_flags & Alter_inplace_info::ADD_INDEX) { + if (info.gcols_in_fulltext_or_spatial()) { + goto err_exit_no_heap; + } + } + if (ha_alter_info->handler_flags & Alter_inplace_info::CHANGE_CREATE_OPTION) { const char* invalid_opt = info.create_options_are_invalid(); @@ -6228,10 +6104,9 @@ check_if_can_drop_indexes: & Alter_inplace_info::ADD_FOREIGN_KEY) { ut_ad(!m_prebuilt->trx->check_foreigns); -#ifdef MYSQL_VIRTUAL_COLUMNS alter_fill_stored_column(altered_table, m_prebuilt->table, &s_cols, &s_heap); -#endif + add_fk = static_cast( mem_heap_zalloc( heap, @@ -6302,7 +6177,6 @@ err_exit: } -#ifdef MYSQL_VIRTUAL_COLUMNS if ((ha_alter_info->handler_flags & Alter_inplace_info::DROP_VIRTUAL_COLUMN) && prepare_inplace_drop_virtual( @@ -6316,7 +6190,6 @@ err_exit: ha_alter_info, altered_table, table)) { DBUG_RETURN(true); } -#endif /* MYSQL_VIRTUAL_COLUMNS */ DBUG_RETURN(false); } @@ -6332,7 +6205,7 @@ err_exit: m_prebuilt->table, altered_table, &fts_doc_col_no, &num_v)) { - fts_doc_col_no = altered_table->s->stored_fields; + fts_doc_col_no = altered_table->s->fields - num_v; add_fts_doc_id = true; add_fts_doc_id_idx = true; @@ -6360,36 +6233,24 @@ err_exit: DBUG_ASSERT( doc_col_no == fts_doc_col_no || doc_col_no == ULINT_UNDEFINED - || (ha_alter_info->handler_flags)); - /* JAN: TODO: MySQL 5.7 Virtual columns + || (ha_alter_info->handler_flags & (Alter_inplace_info::ALTER_STORED_COLUMN_ORDER | Alter_inplace_info::DROP_STORED_COLUMN - | - Alter_inplace_info::ADD_STORED_COLUMN))); - */ + | Alter_inplace_info::ADD_STORED_BASE_COLUMN))); } } /* See if an AUTO_INCREMENT column was added. */ - uint i = 0, innodb_idx= 0; + uint i = 0; ulint num_v = 0; List_iterator_fast cf_it( ha_alter_info->alter_info->create_list); while (const Create_field* new_field = cf_it++) { const Field* field; - if (!new_field->stored_in_db()) { - i++; - continue; - } DBUG_ASSERT(i < altered_table->s->fields); - DBUG_ASSERT(innodb_idx < altered_table->s->stored_fields); for (uint old_i = 0; table->field[old_i]; old_i++) { - if (!table->field[old_i]->stored_in_db()) { - continue; - } - if (new_field->field == table->field[old_i]) { goto found_col; } @@ -6413,12 +6274,10 @@ err_exit: my_error(ER_WRONG_AUTO_KEY, MYF(0)); goto err_exit; } - add_autoinc_col_no = innodb_idx; - /* JAN: TODO: MySQL 5.7 - autoinc_col_max_value = - field->get_max_int_value(); - */ + /* Get the col no of the old table non-virtual column array */ + add_autoinc_col_no = i - num_v; + autoinc_col_max_value = innobase_get_int_col_max_value(field); } found_col: @@ -6427,7 +6286,6 @@ found_col: } i++; - innodb_idx++; } DBUG_ASSERT(heap); @@ -6601,7 +6459,6 @@ ok_exit: && alter_templ_needs_rebuild( altered_table, ha_alter_info, ctx->new_table)); -#ifdef MYSQL_VIRTUAL_COLUMNS if ((ctx->new_table->n_v_cols > 0) && rebuild_templ) { /* Save the templ if isn't NULL so as to restore the original state in case of alter operation failures. */ @@ -6609,11 +6466,9 @@ ok_exit: old_templ = ctx->new_table->vc_templ; } s_templ = UT_NEW_NOKEY(dict_vcol_templ_t()); - s_templ->vtempl = NULL; innobase_build_v_templ( - altered_table, ctx->new_table, s_templ, - NULL, false, NULL); + altered_table, ctx->new_table, s_templ, NULL, false); ctx->new_table->vc_templ = s_templ; } else if (ctx->num_to_add_vcol > 0 && ctx->num_to_drop_vcol == 0) { @@ -6630,11 +6485,8 @@ ok_exit: add_v->v_col = ctx->add_vcol; add_v->v_col_name = ctx->add_vcol_name; - s_templ->vtempl = NULL; - innobase_build_v_templ( - altered_table, ctx->new_table, s_templ, - add_v, false, NULL); + altered_table, ctx->new_table, s_templ, add_v, false); old_templ = ctx->new_table->vc_templ; ctx->new_table->vc_templ = s_templ; } @@ -6645,7 +6497,6 @@ ok_exit: if (!ctx->need_rebuild() && ctx->num_to_drop_vcol > 0) { eval_table = table; } -#endif /* MYSQL_VIRTUAL_COLUMNS */ /* Read the clustered index of the table and build indexes based on this information using temporary @@ -7452,14 +7303,13 @@ innobase_enlarge_columns_try( List_iterator_fast cf_it( ha_alter_info->alter_info->create_list); ulint i = 0; - bool is_v=false; + ulint num_v = 0; + bool is_v; for (Field** fp = table->field; *fp; fp++, i++) { ulint idx; -#ifdef MYSQL_VIRTUAL_COLUMNS - ulint num_v = 0; - if ((*fp)->is_virtual_gcol()) { + if (innobase_is_v_fld(*fp)) { is_v = true; idx = num_v; num_v++; @@ -7467,10 +7317,6 @@ innobase_enlarge_columns_try( idx = i - num_v; is_v = false; } -#else - idx = i; - is_v = false; -#endif cf_it.rewind(); while (Create_field* cf = cf_it++) { @@ -7614,8 +7460,6 @@ commit_get_autoinc( ulonglong offset; col_max_value = innobase_get_int_col_max_value(autoinc_field); - // JAN: TODO: MySQL 5.7 - //col_max_value = autoinc_field->get_max_int_value(); offset = ctx->prebuilt->autoinc_offset; max_autoinc = innobase_next_autoinc( @@ -8213,7 +8057,6 @@ commit_try_norebuild( } #endif /* MYSQL_RENAME_INDEX */ -#ifdef MYSQL_VIRTUAL_COLUMNS if ((ha_alter_info->handler_flags & Alter_inplace_info::DROP_VIRTUAL_COLUMN) && innobase_drop_virtual_try( @@ -8229,7 +8072,6 @@ commit_try_norebuild( ctx->old_table, trx)) { DBUG_RETURN(true); } -#endif /* MYSQL_VIRTUAL_COLUMNS */ DBUG_RETURN(false); } diff --git a/storage/innobase/include/dict0dict.ic b/storage/innobase/include/dict0dict.ic index 5e5fbae9081..c44dc156aaa 100644 --- a/storage/innobase/include/dict0dict.ic +++ b/storage/innobase/include/dict0dict.ic @@ -1984,7 +1984,6 @@ dict_free_vc_templ( ut_free(vc_templ->vtempl[i]); } } - ut_free(vc_templ->default_rec); ut_free(vc_templ->vtempl); vc_templ->vtempl = NULL; } diff --git a/storage/innobase/include/dict0mem.h b/storage/innobase/include/dict0mem.h index 019e20680e5..c81d893ed5a 100644 --- a/storage/innobase/include/dict0mem.h +++ b/storage/innobase/include/dict0mem.h @@ -1328,14 +1328,19 @@ struct dict_vcol_templ_t { /** table name */ std::string tb_name; - /** share->table_name */ - std::string share_name; - /** MySQL record length */ ulint rec_len; /** default column value if any */ byte* default_rec; + + /** cached MySQL TABLE object */ + TABLE* mysql_table; + + /** when mysql_table was cached */ + uint64_t mysql_table_query_id; + + dict_vcol_templ_t() : vtempl(0), mysql_table_query_id(-1) {} }; /* This flag is for sync SQL DDL and memcached DML. diff --git a/storage/innobase/include/ha_prototypes.h b/storage/innobase/include/ha_prototypes.h index f3641f93681..116ca781726 100644 --- a/storage/innobase/include/ha_prototypes.h +++ b/storage/innobase/include/ha_prototypes.h @@ -52,7 +52,6 @@ struct fts_string_t; #undef MYSQL_SPATIAL_INDEX #undef MYSQL_STORE_FTS_DOC_ID #undef MYSQL_TABLESPACES -#undef MYSQL_VIRTUAL_COLUMNS /*********************************************************************//** Wrapper around MySQL's copy_and_convert function. @@ -654,5 +653,20 @@ buffer pool size. void innodb_set_buf_pool_size(ulonglong buf_pool_size); +/** Create a MYSQL_THD for background purge threads and mark it as such. +@returns new MYSQL_THD */ +MYSQL_THD +innobase_create_background_thd(); + +/** Destroy a background purge thread THD. +@param[in] thd MYSQL_THD to destroy */ +void +innobase_destroy_background_thd(MYSQL_THD); + +/** Close opened tables, free memory, delete items for a MYSQL_THD. +@param[in] thd MYSQL_THD to reset */ +void +innobase_reset_background_thd(MYSQL_THD); + #endif /* !UNIV_HOTBACKUP && !UNIV_INNOCHECKSUM */ #endif /* HA_INNODB_PROTOTYPES_H */ diff --git a/storage/innobase/log/log0log.cc b/storage/innobase/log/log0log.cc index bc421774320..0a5e3b27bc0 100644 --- a/storage/innobase/log/log0log.cc +++ b/storage/innobase/log/log0log.cc @@ -2195,6 +2195,13 @@ loop: count = 0; } + /* Wake up purge threads to die - they have MYSQL_THD's and + thus might keep open transactions. In particular, this is + needed in embedded server and when one uses UNINSTALL PLUGIN. + In the normal server shutdown purge threads should've been + already notified by the thd_destructor_proxy thread. */ + srv_purge_wakeup(); + goto loop; } diff --git a/storage/innobase/row/row0ins.cc b/storage/innobase/row/row0ins.cc index 20c64a4288c..271d70d4da9 100644 --- a/storage/innobase/row/row0ins.cc +++ b/storage/innobase/row/row0ins.cc @@ -931,7 +931,6 @@ row_ins_invalidate_query_cache( innobase_invalidate_query_cache(thr_get_trx(thr), name, len); } -#ifdef MYSQL_VIRTUAL_COLUMNS /** Fill virtual column information in cascade node for the child table. @param[out] cascade child update node @@ -1042,7 +1041,6 @@ func_exit: mem_heap_free(v_heap); } } -#endif /* MYSQL_VIRTUAL_COLUMNS */ #ifdef WITH_WSREP dberr_t wsrep_append_foreign_key(trx_t *trx, @@ -1338,7 +1336,6 @@ row_ins_foreign_check_on_constraint( cascade->fts_doc_id = doc_id; } -#ifdef MYSQL_VIRTUAL_COLUMNS if (foreign->v_cols != NULL && foreign->v_cols->size() > 0) { row_ins_foreign_fill_virtual( @@ -1349,7 +1346,6 @@ row_ins_foreign_check_on_constraint( goto nonstandard_exit_func; } } -#endif /* MYSQL_VIRTUAL_COLUMNS */ } else if (table->fts && cascade->is_delete) { /* DICT_FOREIGN_ON_DELETE_CASCADE case */ for (i = 0; i < foreign->n_fields; i++) { @@ -1379,7 +1375,6 @@ row_ins_foreign_check_on_constraint( trx, &fts_col_affacted, cascade); -#ifdef MYSQL_VIRTUAL_COLUMNS if (foreign->v_cols != NULL && foreign->v_cols->size() > 0) { row_ins_foreign_fill_virtual( @@ -1390,7 +1385,6 @@ row_ins_foreign_check_on_constraint( goto nonstandard_exit_func; } } -#endif /* MYSQL_VIRTUAL_COLUMNS */ if (n_to_update == ULINT_UNDEFINED) { err = DB_ROW_IS_REFERENCED; diff --git a/storage/innobase/row/row0merge.cc b/storage/innobase/row/row0merge.cc index d302b493f21..7a8b74279f5 100644 --- a/storage/innobase/row/row0merge.cc +++ b/storage/innobase/row/row0merge.cc @@ -655,13 +655,10 @@ row_merge_buf_add( const dfield_t* row_field; col = ifield->col; - -#ifdef MYSQL_VIRTUAL_COLUMNS const dict_v_col_t* v_col = NULL; if (dict_col_is_virtual(col)) { v_col = reinterpret_cast(col); } -#endif /* MYSQL_VIRTUAL_COLUMNS */ col_no = dict_col_get_no(col); @@ -687,7 +684,6 @@ row_merge_buf_add( } else { /* Use callback to get the virtual column value */ if (dict_col_is_virtual(col)) { - #ifdef MYSQL_VIRTUAL_COLUMN dict_index_t* clust_index = dict_table_get_first_index(new_table); @@ -701,7 +697,6 @@ row_merge_buf_add( DBUG_RETURN(0); } dfield_copy(field, row_field); -#endif /* MYSQL_VIRTUAL_COLUMN */ } else { row_field = dtuple_get_nth_field(row, col_no); dfield_copy(field, row_field); diff --git a/storage/innobase/row/row0mysql.cc b/storage/innobase/row/row0mysql.cc index 5b38b7c6c01..100e1bcb708 100644 --- a/storage/innobase/row/row0mysql.cc +++ b/storage/innobase/row/row0mysql.cc @@ -5034,14 +5034,12 @@ end: goto funct_exit; } -#ifdef MYSQL_VIRTUAL_COLUMNS /* In case of copy alter, template db_name and table_name should be renamed only for newly created table. */ if (table->vc_templ != NULL && !new_is_tmp) { innobase_rename_vc_templ(table); } -#endif /* We only want to switch off some of the type checking in an ALTER TABLE...ALGORITHM=COPY, not in a RENAME. */ diff --git a/storage/innobase/row/row0purge.cc b/storage/innobase/row/row0purge.cc index bac55694056..23e08c38cdd 100644 --- a/storage/innobase/row/row0purge.cc +++ b/storage/innobase/row/row0purge.cc @@ -868,7 +868,6 @@ try_again: goto err_exit; } -#ifdef MYSQL_VIRTUAL_COLUMNS if (node->table->n_v_cols && !node->table->vc_templ && dict_table_has_indexed_v_cols(node->table)) { /* Need server fully up for virtual column computation */ @@ -886,7 +885,6 @@ try_again: /* Initialize the template for the table */ innobase_init_vc_templ(node->table); } -#endif /* MYSQL_VIRTUAL_COLUMNS */ /* Disable purging for temp-tables as they are short-lived and no point in re-organzing such short lived tables */ @@ -1120,6 +1118,8 @@ row_purge_step( row_purge_end(thr); } + innobase_reset_background_thd(thr_get_trx(thr)->mysql_thd); + return(thr); } diff --git a/storage/innobase/row/row0sel.cc b/storage/innobase/row/row0sel.cc index 62fd18d027b..5daa26319a5 100644 --- a/storage/innobase/row/row0sel.cc +++ b/storage/innobase/row/row0sel.cc @@ -221,7 +221,6 @@ row_sel_sec_rec_is_for_clust_rec( /* For virtual column, its value will need to be reconstructed from base column in cluster index */ if (is_virtual) { -#ifdef MYSQL_VIRTUAL_COLUMNS const dict_v_col_t* v_col; const dtuple_t* row; dfield_t* vfield; @@ -243,7 +242,6 @@ row_sel_sec_rec_is_for_clust_rec( clust_len = vfield->len; clust_field = static_cast(vfield->data); -#endif /* MYSQL_VIRTUAL_COLUMNS */ } else { clust_pos = dict_col_get_clust_pos(col, clust_index); diff --git a/storage/innobase/row/row0upd.cc b/storage/innobase/row/row0upd.cc index 759bfb57428..2a990904242 100644 --- a/storage/innobase/row/row0upd.cc +++ b/storage/innobase/row/row0upd.cc @@ -1076,7 +1076,6 @@ row_upd_build_difference_binary( } } -#ifdef MYSQL_VIRTUAL_COLUMNS /* Check the virtual columns updates. Even if there is no non-virtual column (base columns) change, we will still need to build the indexed virtual column value so that undo log would log them ( @@ -1141,7 +1140,6 @@ row_upd_build_difference_binary( mem_heap_free(v_heap); } } -#endif /* MYSQL_VIRTUAL_COLUMNS */ update->n_fields = n_diff; ut_ad(update->validate()); @@ -2061,7 +2059,6 @@ row_upd_eval_new_vals( } } -#ifdef MYSQL_VIRTUAL_COLUMNS /** Stores to the heap the virtual columns that need for any indexes @param[in,out] node row update node @param[in] update an update vector if it is update @@ -2140,7 +2137,6 @@ row_upd_store_v_row( mem_heap_free(heap); } } -#endif /* MYSQL_VIRTUAL_COLUMNS */ /** Stores to the heap the row on which the node->pcur is positioned. @param[in] node row update node @@ -2190,12 +2186,10 @@ row_upd_store_row( node->row = row_build(ROW_COPY_DATA, clust_index, rec, offsets, NULL, NULL, NULL, ext, node->heap); -#ifdef MYSQL_VIRTUAL_COLUMNS if (node->table->n_v_cols) { row_upd_store_v_row(node, node->is_delete ? NULL : node->update, thd, mysql_table); } -#endif /* MYSQL_VIRTUAL_COLUMNS */ if (node->is_delete) { node->upd_row = NULL; diff --git a/storage/innobase/row/row0vers.cc b/storage/innobase/row/row0vers.cc index fd17683fb48..f21b1ebbb85 100644 --- a/storage/innobase/row/row0vers.cc +++ b/storage/innobase/row/row0vers.cc @@ -467,7 +467,6 @@ row_vers_non_vc_match( return(ret); } -#ifdef MYSQL_VIRTUAL_COLUMNS /** build virtual column value from current cluster index record data @param[in,out] row the cluster index row in dtuple form @param[in] clust_index clustered index @@ -841,7 +840,6 @@ row_vers_build_cur_vrow( ULINT_UNDEFINED, &heap); return(cur_vrow); } -#endif /* MYSQL_VIRTUAL_COLUMNS */ /*****************************************************************//** Finds out if a version of the record, where the version >= the current @@ -913,7 +911,6 @@ row_vers_old_has_index_entry( if (dict_index_has_virtual(index)) { -#ifdef MYSQL_VIRTUAL_COLUMNS #ifdef DBUG_OFF # define dbug_v_purge false @@ -963,7 +960,6 @@ row_vers_old_has_index_entry( } clust_offsets = rec_get_offsets(rec, clust_index, NULL, ULINT_UNDEFINED, &heap); -#endif /* MYSQL_VIRTUAL_COLUMNS */ } else { entry = row_build_index_entry( @@ -1001,7 +997,6 @@ row_vers_old_has_index_entry( } } } else if (dict_index_has_virtual(index)) { -#ifdef MYSQL_VIRTUAL_COLUMNS /* The current cluster index record could be deleted, but the previous version of it might not. We will need to get the virtual column data from undo record @@ -1009,7 +1004,6 @@ row_vers_old_has_index_entry( cur_vrow = row_vers_build_cur_vrow( also_curr, rec, clust_index, &clust_offsets, index, ientry, roll_ptr, trx_id, heap, v_heap, mtr); -#endif /* MYSQL_VIRTUAL_COLUMNS */ } version = rec; diff --git a/storage/innobase/srv/srv0srv.cc b/storage/innobase/srv/srv0srv.cc index d2f13ad9b37..2e9e3b7ea8a 100644 --- a/storage/innobase/srv/srv0srv.cc +++ b/storage/innobase/srv/srv0srv.cc @@ -2664,8 +2664,13 @@ Check if purge should stop. static bool srv_purge_should_exit( + MYSQL_THD thd, ulint n_purged) /*!< in: pages purged in last batch */ { + if (thd_kill_level(thd)) { + return(true); + } + switch (srv_shutdown_state) { case SRV_SHUTDOWN_NONE: /* Normal operation. */ @@ -2736,8 +2741,7 @@ DECLARE_THREAD(srv_worker_thread)( ut_ad(!srv_read_only_mode); ut_a(srv_force_recovery < SRV_FORCE_NO_BACKGROUND); my_thread_init(); - // JAN: TODO: MySQL 5.7 - // THD *thd= create_thd(false, true, true); + THD* thd = innobase_create_background_thd(); #ifdef UNIV_DEBUG_THREAD_CREATION ib::info() << "Worker thread starting, id " @@ -2781,7 +2785,7 @@ DECLARE_THREAD(srv_worker_thread)( ut_a(!purge_sys->running); ut_a(purge_sys->state == PURGE_STATE_EXIT); - ut_a(srv_shutdown_state > SRV_SHUTDOWN_NONE); + ut_a(srv_shutdown_state > SRV_SHUTDOWN_NONE || thd_kill_level(thd)); rw_lock_x_unlock(&purge_sys->latch); @@ -2790,9 +2794,8 @@ DECLARE_THREAD(srv_worker_thread)( << os_thread_pf(os_thread_get_curr_id()); #endif /* UNIV_DEBUG_THREAD_CREATION */ - // JAN: TODO: MySQL 5.7 - // destroy_thd(thd); - my_thread_end(); + innobase_destroy_background_thd(thd); + my_thread_end(); /* We count the number of threads in os_thread_exit(). A created thread should always use that to exit and not use return() to exit. */ os_thread_exit(); @@ -2807,6 +2810,7 @@ static ulint srv_do_purge( /*=========*/ + MYSQL_THD thd, ulint n_threads, /*!< in: number of threads to use */ ulint* n_total_purged) /*!< in/out: total pages purged */ { @@ -2877,7 +2881,7 @@ srv_do_purge( *n_total_purged += n_pages_purged; - } while (!srv_purge_should_exit(n_pages_purged) + } while (!srv_purge_should_exit(thd, n_pages_purged) && n_pages_purged > 0 && purge_sys->state == PURGE_STATE_RUN); @@ -2890,6 +2894,7 @@ static void srv_purge_coordinator_suspend( /*==========================*/ + MYSQL_THD thd, srv_slot_t* slot, /*!< in/out: Purge coordinator thread slot */ ulint rseg_history_len) /*!< in: history list length @@ -2977,7 +2982,7 @@ srv_purge_coordinator_suspend( } } - } while (stop); + } while (stop && !thd_kill_level(thd)); srv_sys_mutex_enter(); @@ -3001,8 +3006,7 @@ DECLARE_THREAD(srv_purge_coordinator_thread)( required by os_thread_create */ { my_thread_init(); - // JAN: TODO: MySQL 5.7 - // THD *thd= create_thd(false, true, true); + THD* thd = innobase_create_background_thd(); srv_slot_t* slot; ulint n_total_purged = ULINT_UNDEFINED; @@ -3036,13 +3040,14 @@ DECLARE_THREAD(srv_purge_coordinator_thread)( purge didn't purge any records then wait for activity. */ if (srv_shutdown_state == SRV_SHUTDOWN_NONE + && !thd_kill_level(thd) && (purge_sys->state == PURGE_STATE_STOP || n_total_purged == 0)) { - srv_purge_coordinator_suspend(slot, rseg_history_len); + srv_purge_coordinator_suspend(thd, slot, rseg_history_len); } - if (srv_purge_should_exit(n_total_purged)) { + if (srv_purge_should_exit(thd, n_total_purged)) { ut_a(!slot->suspended); break; } @@ -3050,14 +3055,14 @@ DECLARE_THREAD(srv_purge_coordinator_thread)( n_total_purged = 0; rseg_history_len = srv_do_purge( - srv_n_purge_threads, &n_total_purged); + thd, srv_n_purge_threads, &n_total_purged); - } while (!srv_purge_should_exit(n_total_purged)); + } while (!srv_purge_should_exit(thd, n_total_purged)); /* Ensure that we don't jump out of the loop unless the exit condition is satisfied. */ - ut_a(srv_purge_should_exit(n_total_purged)); + ut_a(srv_purge_should_exit(thd, n_total_purged)); ulint n_pages_purged = ULINT_MAX; @@ -3068,12 +3073,6 @@ DECLARE_THREAD(srv_purge_coordinator_thread)( n_pages_purged = trx_purge(1, srv_purge_batch_size, false); } -#ifdef UNIV_DEBUG - if (srv_fast_shutdown == 0) { - trx_commit_disallowed = true; - } -#endif /* UNIV_DEBUG */ - /* This trx_purge is called to remove any undo records (added by background threads) after completion of the above loop. When srv_fast_shutdown != 0, a large batch size can cause significant @@ -3116,8 +3115,7 @@ DECLARE_THREAD(srv_purge_coordinator_thread)( srv_release_threads(SRV_WORKER, srv_n_purge_threads - 1); } - // JAN: TODO: MYSQL 5.7 - // destroy_thd(thd); + innobase_destroy_background_thd(thd); my_thread_end(); /* We count the number of threads in os_thread_exit(). A created thread should always use that to exit and not use return() to exit. */ diff --git a/storage/mroonga/ha_mroonga.cpp b/storage/mroonga/ha_mroonga.cpp index cb902f976fa..27a3e7b3294 100644 --- a/storage/mroonga/ha_mroonga.cpp +++ b/storage/mroonga/ha_mroonga.cpp @@ -13969,8 +13969,8 @@ enum_alter_inplace_result ha_mroonga::wrapper_check_if_supported_inplace_alter( ( Alter_inplace_info::ADD_COLUMN | Alter_inplace_info::DROP_COLUMN | - Alter_inplace_info::ALTER_COLUMN_TYPE | - Alter_inplace_info::ALTER_COLUMN_ORDER | + Alter_inplace_info::ALTER_STORED_COLUMN_TYPE | + Alter_inplace_info::ALTER_STORED_COLUMN_ORDER | Alter_inplace_info::ALTER_COLUMN_NULLABLE | Alter_inplace_info::ALTER_COLUMN_NOT_NULLABLE | Alter_inplace_info::ALTER_COLUMN_STORAGE_TYPE | diff --git a/storage/tokudb/ha_tokudb_alter_56.cc b/storage/tokudb/ha_tokudb_alter_56.cc index 00a4602b554..ba1afbf091a 100644 --- a/storage/tokudb/ha_tokudb_alter_56.cc +++ b/storage/tokudb/ha_tokudb_alter_56.cc @@ -216,11 +216,11 @@ static ulong fix_handler_flags( handler_flags &= ~Alter_inplace_info::TOKU_ALTER_RENAME; } - // ALTER_COLUMN_TYPE may be set when no columns have been changed, + // ALTER_STORED_COLUMN_TYPE may be set when no columns have been changed, // so turn off the flag - if (handler_flags & Alter_inplace_info::ALTER_COLUMN_TYPE) { + if (handler_flags & Alter_inplace_info::ALTER_STORED_COLUMN_TYPE) { if (all_fields_are_same_type(table, altered_table)) { - handler_flags &= ~Alter_inplace_info::ALTER_COLUMN_TYPE; + handler_flags &= ~Alter_inplace_info::ALTER_STORED_COLUMN_TYPE; } } @@ -358,7 +358,7 @@ enum_alter_inplace_result ha_tokudb::check_if_supported_inplace_alter( // but let's do some more checks // we will only allow an hcr if there are no changes - // in column positions (ALTER_COLUMN_ORDER is not set) + // in column positions (ALTER_STORED_COLUMN_ORDER is not set) // now need to verify that one and only one column // has changed only its name. If we find anything to @@ -369,7 +369,7 @@ enum_alter_inplace_result ha_tokudb::check_if_supported_inplace_alter( table, altered_table, (ctx->handler_flags & - Alter_inplace_info::ALTER_COLUMN_ORDER) != 0); + Alter_inplace_info::ALTER_STORED_COLUMN_ORDER) != 0); if (cr_supported) result = HA_ALTER_INPLACE_EXCLUSIVE_LOCK; } @@ -377,7 +377,7 @@ enum_alter_inplace_result ha_tokudb::check_if_supported_inplace_alter( only_flags( ctx->handler_flags, Alter_inplace_info::ADD_COLUMN + - Alter_inplace_info::ALTER_COLUMN_ORDER) && + Alter_inplace_info::ALTER_STORED_COLUMN_ORDER) && setup_kc_info(altered_table, ctx->altered_table_kc_info) == 0) { // add column @@ -407,7 +407,7 @@ enum_alter_inplace_result ha_tokudb::check_if_supported_inplace_alter( only_flags( ctx->handler_flags, Alter_inplace_info::DROP_COLUMN + - Alter_inplace_info::ALTER_COLUMN_ORDER) && + Alter_inplace_info::ALTER_STORED_COLUMN_ORDER) && setup_kc_info(altered_table, ctx->altered_table_kc_info) == 0) { // drop column @@ -452,10 +452,10 @@ enum_alter_inplace_result ha_tokudb::check_if_supported_inplace_alter( ha_alter_info, ctx)) { result = HA_ALTER_INPLACE_EXCLUSIVE_LOCK; } - } else if ((ctx->handler_flags & Alter_inplace_info::ALTER_COLUMN_TYPE) && + } else if ((ctx->handler_flags & Alter_inplace_info::ALTER_STORED_COLUMN_TYPE) && only_flags( ctx->handler_flags, - Alter_inplace_info::ALTER_COLUMN_TYPE + + Alter_inplace_info::ALTER_STORED_COLUMN_TYPE + Alter_inplace_info::ALTER_COLUMN_DEFAULT) && table->s->fields == altered_table->s->fields && find_changed_fields( @@ -1578,7 +1578,7 @@ static bool change_field_type_is_supported( return false; } else if (old_type == MYSQL_TYPE_VARCHAR) { // varchar(X) -> varchar(Y) and varbinary(X) -> varbinary(Y) expansion - // where X < 256 <= Y the ALTER_COLUMN_TYPE handler flag is set for + // where X < 256 <= Y the ALTER_STORED_COLUMN_TYPE handler flag is set for // these cases return change_varchar_length_is_supported( old_field,