diff options
author | Sergei Golubchik <serg@mariadb.org> | 2016-11-23 17:33:40 +0100 |
---|---|---|
committer | Sergei Golubchik <serg@mariadb.org> | 2016-12-12 20:27:36 +0100 |
commit | d137b4dbbac1ce53906ca15817334e3a4daa2655 (patch) | |
tree | 14d421c0a6327365d584942b1e9164a7ee5ca379 | |
parent | a418c9920047d5222a0d065343347312127b780f (diff) | |
download | mariadb-git-d137b4dbbac1ce53906ca15817334e3a4daa2655.tar.gz |
MDEV-5800 MyISAM support for indexed vcols
* don't issue an error for ER_KEY_BASED_ON_GENERATED_VIRTUAL_COLUMN
* support keyread on vcols
* callback into the server to compute vcol values from mi_check/mi_repair
* DMLs just work. Automatically.
26 files changed, 1680 insertions, 86 deletions
diff --git a/include/my_bitmap.h b/include/my_bitmap.h index 9c9550e3141..3e242280be4 100644 --- a/include/my_bitmap.h +++ b/include/my_bitmap.h @@ -58,6 +58,7 @@ extern my_bool bitmap_is_overlapping(const MY_BITMAP *map1, extern my_bool bitmap_test_and_set(MY_BITMAP *map, uint bitmap_bit); extern my_bool bitmap_test_and_clear(MY_BITMAP *map, uint bitmap_bit); extern my_bool bitmap_fast_test_and_set(MY_BITMAP *map, uint bitmap_bit); +extern my_bool bitmap_fast_test_and_clear(MY_BITMAP *map, uint bitmap_bit); extern my_bool bitmap_union_is_set_all(const MY_BITMAP *map1, const MY_BITMAP *map2); extern my_bool bitmap_exists_intersection(const MY_BITMAP **bitmap_array, diff --git a/include/myisamchk.h b/include/myisamchk.h index e833a816b05..643241d84e5 100644 --- a/include/myisamchk.h +++ b/include/myisamchk.h @@ -58,6 +58,7 @@ typedef enum MI_STATS_METHOD_IGNORE_NULLS } enum_handler_stats_method; +struct st_myisam_info; typedef struct st_handler_check_param { @@ -114,6 +115,8 @@ typedef struct st_handler_check_param uint progress_counter; /* How often to call _report_progress() */ ulonglong progress, max_progress; + int (*fix_record)(struct st_myisam_info *info, uchar *record, int keynum); + mysql_mutex_t print_msg_mutex; my_bool need_print_msg_lock; myf malloc_flags; diff --git a/mysql-test/suite/gcol/inc/gcol_ins_upd.inc b/mysql-test/suite/gcol/inc/gcol_ins_upd.inc index 951cf5ff0e5..4b3431eea2e 100644 --- a/mysql-test/suite/gcol/inc/gcol_ins_upd.inc +++ b/mysql-test/suite/gcol/inc/gcol_ins_upd.inc @@ -399,6 +399,7 @@ INSERT INTO t VALUES (); UPDATE t t1, t t2 SET t1.x = 1, t2.y = 2; SELECT * FROM t; SELECT gc FROM t; +CHECK TABLE t; DROP TABLE t; } diff --git a/mysql-test/suite/gcol/inc/gcol_keys.inc b/mysql-test/suite/gcol/inc/gcol_keys.inc index aaba019ec4c..cd5ae4ea2dd 100644 --- a/mysql-test/suite/gcol/inc/gcol_keys.inc +++ b/mysql-test/suite/gcol/inc/gcol_keys.inc @@ -16,6 +16,7 @@ if (!$support_virtual_index) { let $skip_spatial_index_check=1; + let $skip_foreign_key_check=1; } --echo # - UNIQUE KEY @@ -118,10 +119,10 @@ drop table t1; if (!$skip_spatial_index_check) { --echo # Error "All parts of a SPATIAL index must be geometrical" - --error 1687 + --error ER_WRONG_ARGUMENTS create table t1 (a int, b int generated always as (a+1) stored, spatial index (b)); create table t1 (a int, b int generated always as (a+1) stored); - --error 1687 + --error ER_WRONG_ARGUMENTS alter table t1 add spatial index (b); drop table t1; } @@ -148,7 +149,7 @@ alter table t1 add foreign key (b) references t2(a) on update cascade; alter table t1 add foreign key (b) references t2(a) on delete set null; drop table t1; -if($support_virtual_index) +if(!$skip_foreign_key_check) { --error ER_CANT_CREATE_TABLE create table t1 (a int, b int generated always as (a+1) virtual, @@ -317,7 +318,7 @@ CREATE TABLE t1 ( UNIQUE KEY col_int_key (col_int_key) ); -ALTER TABLE t1 add unique index idx(pk), algorithm=inplace; +ALTER TABLE t1 add unique index idx(pk); DESC t1; DROP TABLE t1; diff --git a/mysql-test/suite/gcol/r/gcol_column_def_options_myisam.result b/mysql-test/suite/gcol/r/gcol_column_def_options_myisam.result index dff8208591d..f5f8afcc353 100644 --- a/mysql-test/suite/gcol/r/gcol_column_def_options_myisam.result +++ b/mysql-test/suite/gcol/r/gcol_column_def_options_myisam.result @@ -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 # @@ -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: 1 +info: Records: 1 Duplicates: 0 Warnings: 0 +ALTER TABLE t DROP INDEX idx, DROP INDEX idx1; +affected rows: 1 +info: Records: 1 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=MyISAM 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 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 a7db5508384..121978e2ec7 100644 --- a/mysql-test/suite/gcol/r/gcol_ins_upd_myisam.result +++ b/mysql-test/suite/gcol/r/gcol_ins_upd_myisam.result @@ -357,6 +357,26 @@ select * from t1; a b c d set sql_warnings = 0; drop table t1; +Bug#20797344: WL#8149: ALLOCATED SPACE FOR INDEXED BLOB VGC CAN BE +OVERWRITTEN FOR UPDATE +# +CREATE TABLE t (a varchar(100), 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), key(c(20))); +INSERT INTO t(a,b,h) VALUES('aaaaaaa','1111111', 11); +INSERT INTO t(a,b,h) VALUES('bbbbbbb','2222222', 22); +SELECT c FROM t; +c +aaaaaaa1111111 +bbbbbbb2222222 +UPDATE t SET a='ccccccc'; +SELECT c FROM t; +c +ccccccc1111111 +ccccccc2222222 +DROP TABLE t; # Bug#21081742: ASSERTION !TABLE || (!TABLE->WRITE_SET || # BITMAP_IS_SET(TABLE->WRITE_SET # @@ -413,6 +433,21 @@ SELECT * FROM t; x y gc 2 1 3 DROP TABLE t; +CREATE TABLE t ( +x INT, y INT, gc INT GENERATED ALWAYS AS (x+1), KEY (x,gc) +); +INSERT INTO t VALUES (); +UPDATE t t1, t t2 SET t1.x = 1, t2.y = 2; +SELECT * FROM t; +x y gc +1 2 2 +SELECT gc FROM t; +gc +2 +CHECK TABLE t; +Table Op Msg_type Msg_text +test.t check status OK +DROP TABLE t; # stored CREATE TABLE C ( col_varchar_nokey VARCHAR(1), @@ -474,6 +509,95 @@ SELECT * from C; col_varchar_nokey col_varchar_key a aa DROP TABLE C; +# virtual, indexed +CREATE TABLE C ( +col_varchar_nokey VARCHAR(1), +col_varchar_key VARCHAR(2) GENERATED ALWAYS AS +(CONCAT(col_varchar_nokey, col_varchar_nokey)) VIRTUAL, +KEY (col_varchar_key, col_varchar_nokey) +); +INSERT INTO C (col_varchar_nokey) VALUES ('c'); +EXPLAIN UPDATE C AS OUTR1, C AS OUTR2 +SET OUTR1.`col_varchar_nokey` = 'f', +OUTR2.`col_varchar_nokey` = "a"; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE OUTR1 system NULL NULL NULL NULL 1 +1 SIMPLE OUTR2 system NULL NULL NULL NULL 1 +UPDATE C AS OUTR1, C AS OUTR2 +SET OUTR1.`col_varchar_nokey` = 'f', +OUTR2.`col_varchar_nokey` = "a"; +SELECT * from C; +col_varchar_nokey col_varchar_key +a aa +DROP TABLE C; +# +# Bug #21530366 CRASH/ASSERTION, CORRUPTION WITH INDEXES + +# VIRTUAL COLUMNS, BLOB +# +CREATE TABLE t ( +a INTEGER, +b BLOB GENERATED ALWAYS AS (a) VIRTUAL, +INDEX (b(57)) +); +INSERT INTO t (a) VALUES (9); +UPDATE t SET a = 10; +DELETE FROM t WHERE a = 10; +DROP TABLE t; +# Bug#21807818: Generated columns not updated with empty insert list +CREATE TABLE t ( +a BLOB GENERATED ALWAYS AS ('') VIRTUAL, +b TIMESTAMP(4) GENERATED ALWAYS AS ('') VIRTUAL, +KEY (a(183),b) +); +INSERT INTO t VALUES(), (), (); +DELETE IGNORE FROM t; +DROP TABLE t; +# +# Bug#22195458:GCOLS: ASSERTION 0 AND CORRUPTION... +# +CREATE TABLE t ( +a INT, +b YEAR GENERATED ALWAYS AS ('a') VIRTUAL, +c YEAR GENERATED ALWAYS AS ('aaaa') VIRTUAL, +b1 YEAR GENERATED ALWAYS AS ('a') STORED, +c1 YEAR GENERATED ALWAYS AS ('aaaa') STORED, +UNIQUE(b), +UNIQUE(b1) +); +INSERT INTO t VALUES(); +SELECT b from t; +b +2000 +SELECT b1 from t; +b1 +0000 +SELECT * from t; +a b c b1 c1 +NULL 2000 0000 0000 0000 +DELETE FROM t; +CHECK TABLE t EXTENDED; +Table Op Msg_type Msg_text +test.t check status OK +DROP TABLE t; +# Bug#22195364:GCOLS: FAILING ASSERTION: +# DFIELD_IS_NULL(DFIELD2) || DFIELD2->DATA +CREATE TABLE t ( +a INT, +c BLOB GENERATED ALWAYS AS ('') VIRTUAL, +UNIQUE KEY(c(1),a) +); +INSERT INTO t(a) VALUES(1) ON DUPLICATE KEY UPDATE a=2; +SELECT * FROM t; +a c +1 +INSERT INTO t(a) VALUES(1) ON DUPLICATE KEY UPDATE a=2; +SELECT * FROM t; +a c +2 +SELECT GROUP_CONCAT(c ORDER BY c) FROM t; +GROUP_CONCAT(c ORDER BY c) + +DROP TABLE t; #Bug#21929967:GCOLS:GCOL VALUE CHANGES WHEN SESSION CHANGES SQL_MODE CREATE TABLE t(c1 INT GENERATED ALWAYS AS (1) VIRTUAL, c2 INT GENERATED ALWAYS AS(2) STORED); @@ -515,6 +639,32 @@ i1 i2 5 10 5 10 DROP TABLE t1,t2; +# +# Bug#22070021 GCOL:ASSERTION `!TABLE || (!TABLE->WRITE_SET || +# BITMAP_IS_SET(TABLE->WRITE_SET, +# +CREATE TABLE t1( +c1 INT, +c2 INT GENERATED ALWAYS AS (c1 + c1) VIRTUAL, +KEY(c2) +); +INSERT INTO t1(c1) VALUES(0); +DELETE O1.* FROM t1 AS O1, t1 AS O2; +SELECT * FROM t1; +c1 c2 +DROP TABLE t1; +# +# Bug#21944199 SIMPLE DELETE QUERY CAUSES INNODB: FAILING ASSERTION: 0 +# & DATA CORRUPTION +# +CREATE TEMPORARY TABLE t1 ( +a INTEGER NOT NULL, +b INTEGER GENERATED ALWAYS AS (a+1) VIRTUAL +); +INSERT INTO t1 (a) VALUES (0), (0), (0); +ALTER TABLE t1 ADD INDEX idx (b); +DELETE FROM t1; +DROP TEMPORARY TABLE t1; DROP VIEW IF EXISTS v1,v2; DROP TABLE IF EXISTS t1,t2,t3; DROP PROCEDURE IF EXISTS p1; diff --git a/mysql-test/suite/gcol/r/gcol_keys_myisam.result b/mysql-test/suite/gcol/r/gcol_keys_myisam.result index f6a4ffe6c60..162035c999e 100644 --- a/mysql-test/suite/gcol/r/gcol_keys_myisam.result +++ b/mysql-test/suite/gcol/r/gcol_keys_myisam.result @@ -6,6 +6,19 @@ SET @@session.default_storage_engine = 'MyISAM'; # - FOREIGN INDEX (partially supported) # - CHECK (allowed but not used) # UNIQUE +create table t1 (a int, b int generated always as (a*2) virtual unique); +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` int(11) DEFAULT NULL, + `b` int(11) AS (a*2) VIRTUAL, + UNIQUE KEY `b` (`b`) +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +describe t1; +Field Type Null Key Default Extra +a int(11) YES NULL +b int(11) YES UNI NULL VIRTUAL +drop table t1; create table t1 (a int, b int generated always as (a*2) stored unique); show create table t1; Table Create Table @@ -19,6 +32,19 @@ Field Type Null Key Default Extra a int(11) YES NULL b int(11) YES UNI NULL PERSISTENT drop table t1; +create table t1 (a int, b int generated always as (a*2) virtual, unique key (b)); +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` int(11) DEFAULT NULL, + `b` int(11) AS (a*2) VIRTUAL, + UNIQUE KEY `b` (`b`) +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +describe t1; +Field Type Null Key Default Extra +a int(11) YES NULL +b int(11) YES UNI NULL VIRTUAL +drop table t1; create table t1 (a int, b int generated always as (a*2) stored, unique (b)); show create table t1; Table Create Table @@ -32,6 +58,9 @@ Field Type Null Key Default Extra a int(11) YES NULL b int(11) YES UNI NULL PERSISTENT drop table t1; +create table t1 (a int, b int generated always as (a*2) virtual); +alter table t1 add unique key (b); +drop table t1; create table t1 (a int, b int generated always as (a*2) stored); alter table t1 add unique key (b); drop table t1; @@ -41,6 +70,21 @@ drop table t1; # - gcol_select.inc # # INDEX +create table t1 (a int, b int generated always as (a*2) virtual, index (b)); +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` int(11) DEFAULT NULL, + `b` int(11) AS (a*2) VIRTUAL, + KEY `b` (`b`) +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +describe t1; +Field Type Null Key Default Extra +a int(11) YES NULL +b int(11) YES MUL NULL VIRTUAL +drop table t1; +create table t1 (a int, b int generated always as (a*2) virtual, index (a,b)); +drop table t1; create table t1 (a int, b int generated always as (a*2) stored, index (b)); show create table t1; Table Create Table @@ -67,6 +111,10 @@ Field Type Null Key Default Extra a int(11) YES MUL NULL b int(11) YES NULL PERSISTENT drop table t1; +create table t1 (a int, b int generated always as (a*2) virtual); +alter table t1 add index (b); +alter table t1 add index (a,b); +drop table t1; create table t1 (a int, b int generated always as (a*2) stored); alter table t1 add index (b); drop table t1; @@ -81,6 +129,13 @@ drop table t1; # # TODO: FULLTEXT INDEX # SPATIAL INDEX +# Error "All parts of a SPATIAL index must be geometrical" +create table t1 (a int, b int generated always as (a+1) stored, spatial index (b)); +ERROR HY000: Incorrect arguments to SPATIAL INDEX +create table t1 (a int, b int generated always as (a+1) stored); +alter table t1 add spatial index (b); +ERROR HY000: Incorrect arguments to SPATIAL INDEX +drop table t1; # FOREIGN KEY # Rejected FK options. create table t1 (a int, b int generated always as (a+1) stored, @@ -117,6 +172,185 @@ drop table t1; create table t1 (a int, b int generated always as (a % 10) stored, foreign key (b) references t2(a) on delete no action); drop table t1,t2; +# +# Bug#20553262: WL8149: ASSERTION `DELSUM+(INT) Y/4-TEMP >= 0' FAILED +# +CREATE TABLE c ( +pk integer AUTO_INCREMENT, +col_datetime_nokey DATETIME /*! NULL */, +col_time_nokey TIME /*! 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) /*! NULL */, +PRIMARY KEY (pk), +KEY (col_time_key), +KEY (col_datetime_key)); +INSERT INTO c ( col_time_nokey,col_datetime_nokey,col_varchar_nokey) values +('14:03:03.042673','2001-11-28 00:50:27.051028', 'c'), +('01:46:09.016386','2007-10-09 19:53:04.008332', NULL), +('16:21:18.052408','2001-11-08 21:02:12.009395', 'x'), +('18:56:33.027423','2003-04-01 00:00:00', 'i'); +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 +EXPLAIN SELECT +outr.col_time_key AS x +FROM c as outr +WHERE +outr.col_varchar_nokey in ('c', 'x', 'i') +AND (outr.col_time_key IS NULL OR +outr.col_datetime_key = '2009-09-27'); +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE outr ALL col_time_key,col_datetime_key NULL NULL NULL 4 x +SELECT +outr.col_time_key AS x +FROM c AS outr +WHERE +outr.col_varchar_nokey in ('c', 'x', 'i') +AND (outr.col_time_key IS NULL OR +outr.col_datetime_key = '2009-09-27'); +x +DROP TABLE c; +# +# Bug#20913803: WL8149: SIG 11 IN DFIELD_DUP | +# INNOBASE/INCLUDE/DATA0DATA.IC:253 +# +CREATE TABLE A ( +col_varchar_nokey TEXT , +col_varchar_key TEXT GENERATED ALWAYS AS (REPEAT(col_varchar_nokey, 1000)), +KEY (col_varchar_key(50)) +); +INSERT INTO A (col_varchar_nokey) VALUES (''); +CREATE TABLE D ( +pk INTEGER AUTO_INCREMENT, +col_date_nokey BLOB, +col_date_key BLOB GENERATED ALWAYS AS (REPEAT(col_date_nokey,1000)) VIRTUAL, +col_datetime_nokey LONGBLOB, +col_time_nokey LONGTEXT, +col_datetime_key LONGBLOB GENERATED ALWAYS AS (REPEAT(col_datetime_nokey, 1000)), +col_time_key LONGTEXT GENERATED ALWAYS AS (REPEAT(col_datetime_nokey, 1000)), +col_varchar_nokey TEXT, +col_varchar_key TEXT GENERATED ALWAYS AS (REPEAT(col_varchar_nokey, 1000)), +PRIMARY KEY (pk), +KEY (col_varchar_key(50)), +KEY (col_date_key(20)), +KEY (col_time_key(20)), +KEY (col_datetime_key(20)), +KEY (col_varchar_key(10), col_date_key(10), col_time_key(5), col_datetime_key(5)) +); +INSERT INTO D ( +col_date_nokey, +col_time_nokey, +col_datetime_nokey, +col_varchar_nokey +) VALUES ('', '', '', ''),('', '', '', ''); +DELETE FROM OUTR1.* USING D AS OUTR1 RIGHT JOIN A AS OUTR2 ON +( OUTR1 . `col_varchar_nokey` = OUTR2 . `col_varchar_nokey` ); +DROP TABLE IF EXISTS A,D; +# +# Bug#21024896: SIG 11 INNOBASE_ADD_ONE_VIRTUAL | +# INNOBASE/HANDLER/HANDLER0ALTER.CC +# +CREATE TABLE t1 ( +col1 int(11) DEFAULT NULL, +col2 int(11) DEFAULT NULL, +col3 int(11) NOT NULL, +col4 int(11) DEFAULT NULL, +col5 int(11) GENERATED ALWAYS AS (col2 / col2) VIRTUAL, +col7 int(11) GENERATED ALWAYS AS (col5 + col5) VIRTUAL, +col8 int(11) GENERATED ALWAYS AS (col5 * col5) VIRTUAL, +col9 text, +col6 int(11) DEFAULT NULL, +PRIMARY KEY (`col3`), +UNIQUE KEY uidx (`col2`), +KEY idx (`col5`) +); +INSERT INTO t1(col1,col2,col3,col4,col9,col6) +VALUES(1,1,0,1,REPEAT(col1,1000),0), (3,2,1,1,REPEAT(col1,1000),NULL); +ALTER TABLE t1 ADD COLUMN extra INT; +DROP TABLE t1; +# +# Bug#21316860: WL8149:INNODB: FAILING ASSERTION: +# TEMPL->CLUST_REC_FIELD_NO != ULINT_UNDEFINED +# +CREATE TABLE t1 ( +pk int(11) NOT NULL, +col_int_nokey int(11), +col_int_key int(11) GENERATED ALWAYS AS (col_int_nokey) VIRTUAL, +col_date_nokey date, +col_date_key date GENERATED ALWAYS AS (col_date_nokey) VIRTUAL, +PRIMARY KEY (pk), +UNIQUE KEY col_int_key (col_int_key) +); +ALTER TABLE t1 DROP COLUMN pk; +DROP TABLE t1; +# Remove the impact on PK choose by index on virtual generated column +CREATE TABLE t1 ( +pk int(11) NOT NULL, +col_int_nokey int(11) DEFAULT NULL, +col_int_key int(11) GENERATED ALWAYS AS (col_int_nokey) VIRTUAL, +UNIQUE KEY col_int_key (col_int_key) +); +ALTER TABLE t1 add unique index idx(pk); +DESC t1; +Field Type Null Key Default Extra +pk int(11) NO PRI NULL +col_int_nokey int(11) YES NULL +col_int_key int(11) YES UNI NULL VIRTUAL +DROP TABLE t1; +# +# Bug#21346132: WL8149:INNODB: FAILING ASSERTION: +# PRIMARY_KEY_NO == -1 || PRIMARY_KEY_NO == 0 +# +CREATE TABLE t1 ( +col_int_nokey int(11) NOT NULL, +col_int_key int(11) GENERATED ALWAYS AS (col_int_nokey), +col_varchar_nokey varchar(1) NOT NULL, +col_varchar_key varchar(2) GENERATED ALWAYS AS (col_varchar_nokey), +UNIQUE KEY col_int_key (col_int_key), +UNIQUE KEY col_varchar_key (col_varchar_key), +UNIQUE KEY col_int_key_2 (col_int_key,col_varchar_key), +UNIQUE KEY col_varchar_key_2 (col_varchar_key,col_varchar_nokey), +KEY col_int_key_3 (col_int_key,col_int_nokey) +); +ALTER TABLE t1 DROP COLUMN col_varchar_key; +DROP TABLE t1; +# +# Bug#21320151 WL8149: WRONG RESULT WITH INDEX SCAN +# +CREATE TABLE t1 ( +id INTEGER NOT NULL, +b INTEGER GENERATED ALWAYS AS (id+1) VIRTUAL, +UNIQUE KEY (b) +); +INSERT INTO t1 (id) VALUES (2),(3),(4),(5),(6),(7),(8),(9),(10); +EXPLAIN SELECT b FROM t1 FORCE INDEX(b); +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 index NULL b 5 NULL 9 Using index +SELECT b FROM t1 FORCE INDEX(b); +b +3 +4 +5 +6 +7 +8 +9 +10 +11 +EXPLAIN SELECT b FROM t1 FORCE INDEX(b) WHERE b BETWEEN 1 AND 5; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 range b b 5 NULL 3 Using where; Using index +SELECT b FROM t1 FORCE INDEX(b) WHERE b BETWEEN 1 AND 5; +b +3 +4 +5 +DROP TABLE t1; # Testing data manipulation operations involving FOREIGN KEY # on generated columns can be found in: @@ -297,6 +531,201 @@ id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE table2 system PRIMARY NULL NULL NULL 1 DROP TABLE t1; # +# Bug#21391781 ASSERT WHEN RUNNING ALTER TABLE ON A TABLE WITH INDEX +# ON VIRTUAL COLUMN +# +CREATE TABLE t1 ( +col1 INTEGER NOT NULL, +col2 INTEGER NOT NULL, +gcol1 INTEGER GENERATED ALWAYS AS (col1 + col2) VIRTUAL, +col3 INTEGER NOT NULL, +col4 INTEGER NOT 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, +col34 INTEGER DEFAULT NULL, +col35 INTEGER DEFAULT NULL, +col36 INTEGER DEFAULT NULL, +col37 INTEGER DEFAULT NULL, +col38 INTEGER DEFAULT NULL, +col39 INTEGER DEFAULT NULL, +col40 INTEGER DEFAULT NULL, +col41 INTEGER DEFAULT NULL, +col42 INTEGER DEFAULT NULL, +col43 INTEGER DEFAULT NULL, +col44 INTEGER DEFAULT NULL, +col45 INTEGER DEFAULT NULL, +col46 INTEGER DEFAULT NULL, +col47 INTEGER DEFAULT NULL, +col48 INTEGER DEFAULT NULL, +col49 INTEGER DEFAULT NULL, +col50 INTEGER DEFAULT NULL, +col51 INTEGER DEFAULT NULL, +col52 INTEGER DEFAULT NULL, +col53 INTEGER DEFAULT NULL, +col54 INTEGER DEFAULT NULL, +col55 INTEGER DEFAULT NULL, +col56 INTEGER DEFAULT NULL, +col57 INTEGER DEFAULT NULL, +col58 INTEGER DEFAULT NULL, +col59 INTEGER DEFAULT NULL, +col60 INTEGER DEFAULT NULL, +col61 INTEGER DEFAULT NULL, +col62 INTEGER DEFAULT NULL, +col63 INTEGER DEFAULT NULL, +col64 INTEGER DEFAULT NULL, +col65 INTEGER DEFAULT NULL, +gcol2 INTEGER GENERATED ALWAYS AS (col3 / col4) VIRTUAL, +KEY idx1 (gcol1) +); +INSERT INTO t1 (col1, col2, col3, col4) +VALUES (1,1,1,1), (2,2,2,2), (3,3,3,3), (4,4,4,4), (5,5,5,5); +ALTER TABLE t1 ADD COLUMN extra INTEGER; +SELECT gcol1 FROM t1 FORCE INDEX(idx1); +gcol1 +2 +4 +6 +8 +10 +DROP TABLE t1; +CREATE TABLE t1 ( +col1 INTEGER NOT NULL, +col2 INTEGER NOT NULL, +gcol1 INTEGER GENERATED ALWAYS AS (col1 + col2) VIRTUAL, +col3 INTEGER NOT NULL, +col4 INTEGER NOT 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, +col34 INTEGER DEFAULT NULL, +col35 INTEGER DEFAULT NULL, +col36 INTEGER DEFAULT NULL, +col37 INTEGER DEFAULT NULL, +col38 INTEGER DEFAULT NULL, +col39 INTEGER DEFAULT NULL, +col40 INTEGER DEFAULT NULL, +col41 INTEGER DEFAULT NULL, +col42 INTEGER DEFAULT NULL, +col43 INTEGER DEFAULT NULL, +col44 INTEGER DEFAULT NULL, +col45 INTEGER DEFAULT NULL, +col46 INTEGER DEFAULT NULL, +col47 INTEGER DEFAULT NULL, +col48 INTEGER DEFAULT NULL, +col49 INTEGER DEFAULT NULL, +col50 INTEGER DEFAULT NULL, +col51 INTEGER DEFAULT NULL, +col52 INTEGER DEFAULT NULL, +col53 INTEGER DEFAULT NULL, +col54 INTEGER DEFAULT NULL, +col55 INTEGER DEFAULT NULL, +col56 INTEGER DEFAULT NULL, +col57 INTEGER DEFAULT NULL, +col58 INTEGER DEFAULT NULL, +col59 INTEGER DEFAULT NULL, +col60 INTEGER DEFAULT NULL, +col61 INTEGER DEFAULT NULL, +col62 INTEGER DEFAULT NULL, +col63 INTEGER DEFAULT NULL, +col64 INTEGER DEFAULT NULL, +col65 INTEGER DEFAULT NULL, +gcol2 INTEGER GENERATED ALWAYS AS (col3 / col4) VIRTUAL, +KEY idx1 (gcol2) +); +INSERT INTO t1 (col1, col2, col3, col4) +VALUES (1,1,1,1), (2,2,2,2), (3,3,3,3), (4,4,4,4), (5,5,5,5); +ALTER TABLE t1 ADD COLUMN extra INTEGER; +SELECT gcol2 FROM t1 FORCE INDEX(idx1); +gcol2 +1 +1 +1 +1 +1 +DROP TABLE t1; +# +# Bug#21628161 CRASH/MEMORY CORRUPTION ADDING INDEXES TO VIRTUAL COLUMN +# +CREATE TABLE t (a INT, +b BOOLEAN GENERATED ALWAYS AS (a+10000) VIRTUAL, +c BLOB GENERATED ALWAYS AS (b=2) VIRTUAL); +INSERT INTO t(a) VALUES (1); +SELECT * FROM t WHERE c = '0'; +a b c +1 127 0 +ALTER TABLE t ADD UNIQUE INDEX (c(1)); +Warnings: +Warning 1264 Out of range value for column 'b' at row 1 +SELECT * FROM t WHERE c = '0'; +a b c +1 127 0 +DROP TABLE t; +# +# Bug#21688115 VIRTUAL COLUMN COMPUTATION SAVE_IN_FIELD() +# DID NOT RETURN TRUE WITH DIVIDE 0 +# +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) VIRTUAL; +CREATE INDEX idx ON t(c); +CALL mtr.add_suppression("\\[Warning\\] InnoDB: Compute virtual column values failed"); +DROP TABLE t; +# # Bug#21770798 OPTIMIZER DOES NOT USE INDEX FOR GENERATED EXPRESSIONS # WITH LOGICAL OPERATORS # diff --git a/mysql-test/suite/gcol/r/gcol_select_myisam.result b/mysql-test/suite/gcol/r/gcol_select_myisam.result index 5a2af800a91..d5e4bdabb38 100644 --- a/mysql-test/suite/gcol/r/gcol_select_myisam.result +++ b/mysql-test/suite/gcol/r/gcol_select_myisam.result @@ -431,6 +431,595 @@ AND table3.col_varchar_key != table1.col_varchar_key ORDER BY table1.col_varchar_key , field1 , field2; field1 field2 DROP TABLE A,CC; +# +# Bug#20573302: WL8149: SEGV IN HA_INNOBASE:: +# BUILD_TEMPLATE AT INNOBASE/HANDLER/HA_INNODB.CC:665 +# +CREATE TABLE c ( +pk INTEGER AUTO_INCREMENT, +col_int_nokey INTEGER NOT NULL, +col_int_key INTEGER GENERATED ALWAYS AS (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, +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)), +PRIMARY KEY (pk), +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 /*! IGNORE */ INTO c ( +col_int_nokey, +col_date_nokey, +col_time_nokey, +col_datetime_nokey, +col_varchar_nokey +) VALUES +(1, '2009-12-01', '00:21:38.058143', '2007-05-28 00:00:00', 'c'), +(8, '2004-12-17', '04:08:02.046897', '2009-07-25 09:21:20.064099', 'm'), +(9, '2000-03-14', '16:25:11.040240', '2002-01-16 00:00:00', 'd'), +(24, '2000-10-08', '10:14:58.018534', '2006-10-12 04:32:53.031976', 'd'), +(6, '2006-05-25', '19:47:59.011283', '2001-02-15 03:08:38.035426', 'y'), +(1, '2008-01-23', '11:14:24.032949', '2004-10-02 20:31:15.022553', 't'), +(6, '2007-06-18', NULL, '2002-08-20 22:48:00.035785', 'd'), +(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'), +(8, NULL, '07:05:51.006712', '1900-01-01 00:00:00', 'm'), +(4, '2006-03-09', '19:22:21.057406', '2008-05-16 08:09:06.002924', 'b'), +(4, '2001-06-05', '03:53:16.001370', '2001-01-20 12:47:23.022022', 'x'), +(7, '2006-05-28', '09:16:38.034570', '2008-07-02 00:00:00', 'g'), +(4, '2001-04-19', '15:37:26.028315', '1900-01-01 00:00:00', 'p'), +(1, '1900-01-01', '00:00:00', '2002-12-08 11:34:58.001571', 'q'), +(9, '2004-08-20', '05:03:03.047452', '1900-01-01 00:00:00', 'w'), +(4, '2004-10-10', '02:59:24.063764', '1900-01-01 00:00:00', 'd'), +(8, '2000-04-02', '00:01:58.064243', '2002-08-25 20:35:06.064634', 'e'), +(4, '2006-11-02', '00:00:00', '2001-10-22 11:13:24.048128', 'b'), +(8, '2009-01-28', '02:20:16.024931', '2003-03-12 02:00:34.029335', 'y'); +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 +Warning 1048 Column 'col_time_nokey' cannot be null +Note 1265 Data truncated for column 'col_time_key' at row 7 +Note 1265 Data truncated for column 'col_time_key' at row 8 +Note 1265 Data truncated for column 'col_time_key' at row 9 +Warning 1048 Column 'col_date_nokey' cannot be null +Warning 1292 Incorrect datetime value: '0000-00-00' +Note 1265 Data truncated for column 'col_time_key' at row 10 +Note 1265 Data truncated for column 'col_time_key' at row 11 +Note 1265 Data truncated for column 'col_time_key' at row 12 +Note 1265 Data truncated for column 'col_time_key' at row 13 +Note 1265 Data truncated for column 'col_time_key' at row 14 +Note 1265 Data truncated for column 'col_time_key' at row 15 +Note 1265 Data truncated for column 'col_time_key' at row 16 +Note 1265 Data truncated for column 'col_time_key' at row 17 +Note 1265 Data truncated for column 'col_time_key' at row 18 +Note 1265 Data truncated for column 'col_time_key' at row 19 +Note 1265 Data truncated for column 'col_time_key' at row 20 +CREATE TABLE cc ( +pk INTEGER AUTO_INCREMENT, +col_int_nokey INTEGER NOT NULL, +col_int_key INTEGER GENERATED ALWAYS AS (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, +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)), +PRIMARY KEY (pk), +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 /*! IGNORE */ INTO cc ( +col_int_nokey, +col_date_nokey, +col_time_nokey, +col_datetime_nokey, +col_varchar_nokey +) VALUES +(0, '2003-02-06', '22:02:09.059926', '2003-08-07 14:43:09.011144', 'x'), +(0, '2005-04-16', '19:33:15.014160', '2005-12-11 00:00:00', 'n'), +(1, '2005-07-23', '22:03:16.058787', '2005-12-26 20:48:07.043628', 'w'), +(7, '2001-11-15', '06:31:23.027263', '2008-06-12 06:41:21.012493', 's'), +(0, '2006-03-24', '02:19:08.013275', '2007-10-11 18:46:28.030000', 'a'), +(4, '2008-07-10', NULL, '2006-04-04 22:22:40.057947', 'd'), +(1, '2009-12-07', NULL, '2002-08-10 20:52:58.035137', 'w'), +(1, '2008-05-01', '10:28:01.038587', '2008-10-03 11:17:23.005299', 'j'), +(1, '2008-06-22', '00:00:00', '2009-01-06 20:11:01.034339', 'm'), +(4, '2001-11-11', '15:02:50.048785', '2009-09-19 00:00:00', 'k'), +(7, '2000-12-21', '05:29:13.012729', '2007-09-02 12:14:27.029187', 't'), +(4, '2007-09-03', '23:45:33.048507', '2003-09-26 00:00:00', 'k'), +(2, '2003-02-18', '19:10:53.057455', '2001-11-18 18:10:16.063189', 'e'), +(0, '2008-12-01', '01:45:27.037313', '2005-02-15 04:08:17.015554', 'i'), +(1, '2008-10-18', '03:56:03.060218', '2009-06-13 23:04:40.013006', 't'), +(91, '2004-08-28', '12:43:17.023797', '1900-01-01 00:00:00', 'm'), +(6, '2006-10-05', '13:33:46.053634', '2005-03-20 02:48:24.045653', 'z'), +(3, '2003-05-16', NULL, '2002-03-16 11:47:27.045297', 'c'), +(6, '2008-10-10', NULL, '2000-05-22 00:00:00', 'i'), +(8, '2002-01-19', '05:18:40.006865', '2009-02-12 00:00:00', '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 +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 +Warning 1048 Column 'col_time_nokey' cannot be null +Note 1265 Data truncated for column 'col_time_key' at row 6 +Warning 1048 Column 'col_time_nokey' cannot be null +Note 1265 Data truncated for column 'col_time_key' at row 7 +Note 1265 Data truncated for column 'col_time_key' at row 8 +Note 1265 Data truncated for column 'col_time_key' at row 9 +Note 1265 Data truncated for column 'col_time_key' at row 10 +Note 1265 Data truncated for column 'col_time_key' at row 11 +Note 1265 Data truncated for column 'col_time_key' at row 12 +Note 1265 Data truncated for column 'col_time_key' at row 13 +Note 1265 Data truncated for column 'col_time_key' at row 14 +Note 1265 Data truncated for column 'col_time_key' at row 15 +Note 1265 Data truncated for column 'col_time_key' at row 16 +Note 1265 Data truncated for column 'col_time_key' at row 17 +Warning 1048 Column 'col_time_nokey' cannot be null +Note 1265 Data truncated for column 'col_time_key' at row 18 +Warning 1048 Column 'col_time_nokey' cannot be null +Note 1265 Data truncated for column 'col_time_key' at row 19 +Note 1265 Data truncated for column 'col_time_key' at row 20 +EXPLAIN +SELECT subquery2_t2.col_int_key AS subquery2_field1 +FROM (c AS subquery2_t1 RIGHT JOIN +(c AS subquery2_t2 LEFT JOIN cc AS subquery2_t3 ON +(subquery2_t3.col_int_nokey = subquery2_t2.col_int_key )) ON +(subquery2_t3.col_varchar_key = subquery2_t2.col_varchar_key)) +ORDER BY subquery2_field1; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE subquery2_t2 index NULL col_int_key_2 10 NULL 20 # +1 SIMPLE subquery2_t3 ALL NULL NULL NULL NULL 20 # +1 SIMPLE subquery2_t1 index NULL PRIMARY 4 NULL 20 # +SELECT subquery2_t2.col_int_key AS subquery2_field1 +FROM (c AS subquery2_t1 RIGHT JOIN +(c AS subquery2_t2 LEFT JOIN cc AS subquery2_t3 ON +(subquery2_t3.col_int_nokey = subquery2_t2.col_int_key )) ON +(subquery2_t3.col_varchar_key = subquery2_t2.col_varchar_key)) +ORDER BY subquery2_field1; +subquery2_field1 +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 +2 +4 +4 +4 +4 +4 +4 +4 +4 +4 +4 +4 +4 +4 +4 +4 +4 +4 +4 +4 +4 +4 +4 +4 +4 +4 +4 +4 +4 +4 +4 +4 +4 +4 +4 +4 +4 +4 +6 +6 +6 +6 +7 +7 +8 +8 +8 +8 +9 +9 +24 +SELECT subquery2_t2.col_int_key AS subquery2_field1 +FROM (c AS subquery2_t1 RIGHT JOIN +(c AS subquery2_t2 LEFT JOIN cc AS subquery2_t3 ON +(subquery2_t3.col_int_nokey = subquery2_t2.col_int_key )) ON +(subquery2_t3.col_varchar_key = subquery2_t2.col_varchar_key)) +ORDER BY subquery2_field1; +subquery2_field1 +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 +2 +4 +4 +4 +4 +4 +4 +4 +4 +4 +4 +4 +4 +4 +4 +4 +4 +4 +4 +4 +4 +4 +4 +4 +4 +4 +4 +4 +4 +4 +4 +4 +4 +4 +4 +4 +4 +4 +6 +6 +6 +6 +7 +7 +8 +8 +8 +8 +9 +9 +24 +DROP TABLE c,cc; +# +# Bug#2081065: WL8149:RESULT DIFF SEEN FOR SIMPLE +# RANGE QUERIES WITH ORDER BY +# +CREATE TABLE cc ( +pk INTEGER AUTO_INCREMENT, +col_int_nokey INTEGER NOT NULL, +col_int_key INTEGER GENERATED ALWAYS AS +(col_int_nokey + col_int_nokey) VIRTUAL, +PRIMARY KEY (pk), +KEY (col_int_key) +); +INSERT INTO cc (col_int_nokey) VALUES (0),(1),(7),(0),(4),(5); +EXPLAIN SELECT pk FROM cc WHERE col_int_key > 3; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE cc ALL col_int_key NULL NULL NULL 6 # +SELECT pk FROM cc WHERE col_int_key > 3; +pk +3 +5 +6 +EXPLAIN SELECT pk FROM cc WHERE col_int_key > 3 ORDER BY 1; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE cc ALL col_int_key NULL NULL NULL 6 # +SELECT pk FROM cc WHERE col_int_key > 3 ORDER BY 1; +pk +3 +5 +6 +DROP TABLE cc; +# +# Bug#20849676 :WL8149:ASSERTION `!TABLE || (!TABLE->READ_SET +# || BITMAP_IS_SET(TABLE->READ_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, +col_varchar_nokey VARCHAR(1) NOT NULL, +col_varchar_key VARCHAR(2) GENERATED ALWAYS AS +(CONCAT(col_varchar_nokey, col_varchar_nokey)), +PRIMARY KEY (pk), +KEY (col_int_key), +KEY (col_varchar_key), +KEY (col_int_key, col_varchar_key) +) ; +INSERT INTO c (col_int_nokey, col_varchar_nokey) VALUES +(1, 'c'),(8, 'm'),(9, 'd'),(24, 'd'),(6, 'y'),(1, 't'),(6, 'd'), +(2, 'r'),(8, 'm'),(4, 'b'),(4, 'x'),(7, 'g'),(4, 'p'),(1, 'q'), +(9, 'w'),(4, 'd'),(8, 'e'),(4, 'b'),(8, 'y'); +CREATE TABLE a ( +pk INTEGER AUTO_INCREMENT, +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)), +PRIMARY KEY (pk), +KEY (col_varchar_key), +KEY (col_time_key), +KEY (col_datetime_key), +KEY (col_varchar_key, col_time_key, col_datetime_key) +); +INSERT INTO a ( +col_time_nokey, +col_datetime_nokey, +col_varchar_nokey) VALUES +('04:08:02.046897', '2001-11-04 19:07:55.051133', 'k'); +Warnings: +Note 1265 Data truncated for column 'col_time_key' at row 1 +ANALYZE TABLE a, c; +Table Op Msg_type Msg_text +test.a analyze status OK +test.c analyze status OK +EXPLAIN +SELECT +table1.pk AS field1 , +table1.col_datetime_key AS field2 +FROM +( a AS table1 LEFT JOIN ( ( c AS table2 STRAIGHT_JOIN ( SELECT +SUBQUERY1_t1.* FROM ( c AS SUBQUERY1_t1 INNER JOIN ( c AS SUBQUERY1_t2 +STRAIGHT_JOIN c AS SUBQUERY1_t3 ON (SUBQUERY1_t3.col_varchar_key = +SUBQUERY1_t2.col_varchar_key ) ) +ON (SUBQUERY1_t3.pk = SUBQUERY1_t2.col_int_key +OR SUBQUERY1_t1.col_int_key <> 1 ) ) +WHERE SUBQUERY1_t2.pk >= 9 ) AS table3 +ON (table3.col_int_key = table2.col_int_key ) ) ) +ON (table3.col_int_nokey = table2.pk ) ) +GROUP BY field1, field2; +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY table1 system NULL NULL NULL NULL 1 # +1 PRIMARY table2 ALL PRIMARY,col_int_key,col_int_key_2 NULL NULL NULL 19 # +1 PRIMARY <derived2> ref key0 key0 9 test.table2.pk,test.table2.col_int_key 10 # +2 DERIVED SUBQUERY1_t2 ALL PRIMARY,col_int_key,col_varchar_key,col_int_key_2 NULL NULL NULL 19 # +2 DERIVED SUBQUERY1_t3 ref PRIMARY,col_varchar_key col_varchar_key 5 test.SUBQUERY1_t2.col_varchar_key 1 # +2 DERIVED SUBQUERY1_t1 ALL col_int_key,col_int_key_2 NULL NULL NULL 19 # +SELECT +table1.pk AS field1 , +table1.col_datetime_key AS field2 +FROM +( a AS table1 LEFT JOIN ( ( c AS table2 STRAIGHT_JOIN ( SELECT +SUBQUERY1_t1.* FROM ( c AS SUBQUERY1_t1 INNER JOIN ( c AS SUBQUERY1_t2 +STRAIGHT_JOIN c AS SUBQUERY1_t3 ON (SUBQUERY1_t3.col_varchar_key = +SUBQUERY1_t2.col_varchar_key ) ) +ON (SUBQUERY1_t3.pk = SUBQUERY1_t2.col_int_key +OR SUBQUERY1_t1.col_int_key <> 1 ) ) +WHERE SUBQUERY1_t2.pk >= 9 ) AS table3 +ON (table3.col_int_key = table2.col_int_key ) ) ) +ON (table3.col_int_nokey = table2.pk ) ) +GROUP BY field1, field2; +field1 field2 +1 2001-11-04 23:15:57 +DROP TABLE IF EXISTS c,a; +CREATE TABLE c ( +col_int_nokey INTEGER NOT NULL, +col_int_key INTEGER GENERATED ALWAYS AS +(col_int_nokey + col_int_nokey) VIRTUAL, +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_int_key, col_varchar_key) +) ; +INSERT INTO c ( +col_int_nokey, +col_varchar_nokey +) VALUES (1, 'c'),(8, 'm'),(9, 'd'),(24, 'd'),(6, 'y'),(1, 't'), +(6, 'd'),(2, 's'),(4, 'r'),(8, 'm'),(4, 'b'),(4, 'x'),(7, 'g'),(4, 'p'), +(1, 'q'),(9, 'w'),(4, 'd'),(8, 'e'),(4, 'b'),(8, 'y'); +CREATE TABLE cc ( +col_int_nokey INTEGER, +col_int_key INTEGER GENERATED ALWAYS AS +(col_int_nokey + col_int_nokey) VIRTUAL, +col_varchar_nokey VARCHAR(1), +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_int_key, col_varchar_key), +KEY (col_int_key, col_int_nokey), +KEY (col_varchar_key, col_varchar_nokey) +); +INSERT INTO cc ( +col_int_nokey, +col_varchar_nokey +) VALUES (8, 'p'),(9, 'g'),(9, 'i'),(4, 'p'),(7, 'h'),(1, 'e'),(8, 'e'),(6, 'u'), +(6, 'j'),(6, 'e'),(1, 'z'),(227, 'w'),(NULL, 't'),(9, 'i'),(1, 'i'),(8, 'i'), +(5, 'b'),(8,'m'),(7, 'j'),(2, 'v'); +ANALYZE TABLE c, cc; +Table Op Msg_type Msg_text +test.c analyze status OK +test.cc analyze status OK +EXPLAIN SELECT +alias2 . col_varchar_key AS field1 +FROM ( cc AS alias1 , cc AS alias2 ) +WHERE +( alias2 . col_int_key , alias1 . col_int_nokey ) +NOT IN +( +SELECT +DISTINCT SQ1_alias2 . col_int_nokey AS SQ1_field1 , +SQ1_alias1 . col_int_key AS SQ1_field2 +FROM ( cc AS SQ1_alias1 , c AS SQ1_alias2 ) +GROUP BY SQ1_field1 , SQ1_field2 +) +GROUP BY field1; +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY alias1 index NULL col_int_key_3 10 NULL 20 # +1 PRIMARY alias2 index NULL col_int_key_2 10 NULL 20 # +2 MATERIALIZED SQ1_alias1 index col_int_key,col_int_key_2,col_int_key_3 col_int_key 5 NULL 20 # +2 MATERIALIZED SQ1_alias2 ALL NULL NULL NULL NULL 20 # +SELECT +alias2 . col_varchar_key AS field1 +FROM ( cc AS alias1 , cc AS alias2 ) +WHERE +( alias2 . col_int_key , alias1 . col_int_nokey ) +NOT IN +( +SELECT +DISTINCT SQ1_alias2 . col_int_nokey AS SQ1_field1 , +SQ1_alias1 . col_int_key AS SQ1_field2 +FROM ( cc AS SQ1_alias1 , c AS SQ1_alias2 ) +GROUP BY SQ1_field1 , SQ1_field2 +) +GROUP BY field1; +field1 +bb +ee +gg +hh +ii +jj +mm +pp +uu +ww +DROP TABLE IF EXISTS c,cc; +SET @save_old_sql_mode= @@sql_mode; +SET sql_mode=""; +CREATE TABLE d ( +col_int int(11) DEFAULT NULL, +col_varchar_10_utf8 varchar(10) CHARACTER SET utf8 DEFAULT NULL, +pk int(11) NOT NULL AUTO_INCREMENT, +col_int_key int(11) GENERATED ALWAYS AS (col_int+col_int) VIRTUAL, +col_varchar_10_utf8_key varchar(10) CHARACTER SET utf8 GENERATED ALWAYS AS (REPEAT(SUBSTRING(col_varchar_10_utf8, -1), 5)) VIRTUAL, +PRIMARY KEY (pk), +KEY col_int_key (col_int_key), +KEY col_varchar_10_utf8_key (col_varchar_10_utf8_key), +KEY cover_key1 (col_int_key, col_varchar_10_utf8_key) +); +INSERT INTO d (col_int, col_varchar_10_utf8) VALUES ('qhlhtrovam',1),('how',2),('htrovamzqr',3),('rovamzqrdc',4),('well',5),('g',6),('rdcenchyhu',7),('want',8); +SELECT table1.pk AS field1 FROM d AS table1 LEFT JOIN d AS table2 ON table1.col_varchar_10_utf8_key = table2.col_varchar_10_utf8_key WHERE table1.col_int_key IS NULL GROUP BY table1.pk ; +field1 +DROP TABLE d; +# +# Bug#21153237: WL8149: QUERIES USING FILESORT +# ON VIRTUAL GC HAVING INDEX GIVES WRONG RESULTS +# +CREATE TABLE j ( +col_int int(11), +pk int(11) NOT NULL, +col_varchar_10_utf8 varchar(10) CHARACTER SET utf8 DEFAULT NULL, +col_varchar_255_utf8_key varchar(255) CHARACTER SET utf8 GENERATED ALWAYS AS +(col_varchar_10_utf8) VIRTUAL, +PRIMARY KEY (pk), +KEY cover_key1 (col_int, col_varchar_255_utf8_key)); +INSERT INTO j(col_int, pk, col_varchar_10_utf8) VALUES(9, 1, '951910400'), +(-1934295040, 2, '1235025920'),(-584581120, 3, '-1176633344'),(3, 4, '1074462720'); +EXPLAIN SELECT col_varchar_255_utf8_key FROM j ORDER BY 1; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE j index NULL cover_key1 773 NULL 4 # +SELECT col_varchar_255_utf8_key FROM j ORDER BY col_varchar_255_utf8_key; +col_varchar_255_utf8_key +-117663334 +1074462720 +1235025920 +951910400 +DROP TABLE j; +set sql_mode= @save_old_sql_mode; CREATE TABLE cc ( pk int(11) NOT NULL AUTO_INCREMENT, col_int_nokey int(11) NOT NULL, @@ -497,6 +1086,35 @@ a b 1 2 2 3 DROP TABLE t; +# +# Testing a few index-based accesses on the virtual column +# +CREATE TABLE t1 ( +id int(11) NOT NULL, +b int(11) GENERATED ALWAYS AS (id+1) VIRTUAL, +UNIQUE KEY (b) ); +INSERT INTO t1 (id) VALUES(NULL); +ERROR 23000: Column 'id' cannot be null +INSERT INTO t1 (id) VALUES(2),(3); +EXPLAIN SELECT * FROM t1 FORCE INDEX(b) WHERE b=3; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 const b b 5 const 1 +EXPLAIN SELECT * FROM t1 AS t2 STRAIGHT_JOIN t1 FORCE INDEX(b) WHERE t1.b=t2.b; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t2 ALL b NULL NULL NULL 2 Using where +1 SIMPLE t1 ref b b 5 test.t2.b 2 +EXPLAIN SELECT b FROM t1 FORCE INDEX(b); +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 index NULL b 5 NULL 2 Using index +INSERT INTO t1 (id) VALUES(4),(5),(6),(7),(8),(9),(10); +EXPLAIN SELECT b FROM t1 FORCE INDEX(b) WHERE b BETWEEN 1 AND 5; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 range b b 5 NULL 3 Using where; Using index +EXPLAIN SELECT * FROM t2 AS t1 WHERE b NOT IN (SELECT b FROM t1 FORCE INDEX(b)); +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 system NULL NULL NULL NULL 1 +2 SUBQUERY t1 index_subquery b b 5 func 2 Using index; Full scan on NULL key +DROP TABLE t1; DROP TABLE t2, t3; # # Bug#21317507:GC: STORED COLUMN REJECTED, BUT VIRTUAL IS ACCEPTED @@ -615,10 +1233,11 @@ pk i1 i2 v1 v2 843 43 43 44 1 942 42 42 43 1 943 43 43 44 1 +ALTER TABLE t1 ADD INDEX idx2(v1); EXPLAIN SELECT * FROM t1 WHERE v1 > 41 AND v1 <= 43; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 ALL NULL NULL NULL NULL # Using where +1 SIMPLE t1 range idx2 idx2 5 NULL # Using index condition SELECT * FROM t1 WHERE v1 > 41 AND v1 <= 43; pk i1 i2 v1 v2 @@ -670,6 +1289,9 @@ i1 INTEGER, i2_key INTEGER GENERATED ALWAYS AS (i1 + i1) VIRTUAL, PRIMARY KEY (pk) ); +# Add a covering index. The reason for this index being covering is that +# secondary indexes in InnoDB include the primary key. +ALTER TABLE t3 ADD INDEX v_idx (i2_key); INSERT INTO t3 (pk, i1) VALUES (1, 1), (2, 48), (3, 228), (4, 3), (5, 5), (6, 39), (7, 6), (8, 8), (9, 3); @@ -698,7 +1320,7 @@ AND t1.i1 <= t3.i2_key; id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY <subquery2> ALL distinct_key NULL NULL NULL 3 1 PRIMARY t1 ALL NULL NULL NULL NULL 4 Using join buffer (flat, BNL join) -1 PRIMARY t3 eq_ref PRIMARY PRIMARY 4 test.t4.i1 1 Using where +1 PRIMARY t3 eq_ref PRIMARY,v_idx PRIMARY 4 test.t4.i1 1 Using where 1 PRIMARY t2 ALL NULL NULL NULL NULL 5 Using join buffer (flat, BNL join) 2 MATERIALIZED t4 ALL NULL NULL NULL NULL 3 Using where SELECT /*+ NO_SEMIJOIN(@subq1) */ t1.c1, t2.i1 @@ -740,6 +1362,7 @@ t 9 # # Test 2: Two alternative covering indexes for the range scan # +ALTER TABLE t3 ADD INDEX v_idx2 (i2_key, i1); EXPLAIN SELECT /*+ NO_SEMIJOIN(@subq1) */ t1.c1, t2.i1 FROM t1 STRAIGHT_JOIN t3 STRAIGHT_JOIN t2 WHERE ( t3.pk IN @@ -753,7 +1376,7 @@ AND t1.i1 <= t3.i2_key; id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY <subquery2> ALL distinct_key NULL NULL NULL 3 1 PRIMARY t1 ALL NULL NULL NULL NULL 4 Using join buffer (flat, BNL join) -1 PRIMARY t3 eq_ref PRIMARY PRIMARY 4 test.t4.i1 1 Using where +1 PRIMARY t3 eq_ref PRIMARY,v_idx,v_idx2 PRIMARY 4 test.t4.i1 1 Using where 1 PRIMARY t2 ALL NULL NULL NULL NULL 5 Using join buffer (flat, BNL join) 2 MATERIALIZED t4 ALL NULL NULL NULL NULL 3 Using where SELECT /*+ NO_SEMIJOIN(@subq1) */ t1.c1, t2.i1 @@ -796,6 +1419,8 @@ t 9 # Test 3: One covering index including the base column for the virtual # column # +# Drop the index with only the virtual column +ALTER TABLE t3 DROP INDEX v_idx; EXPLAIN SELECT /*+ NO_SEMIJOIN(@subq1) */ t1.c1, t2.i1 FROM t1 STRAIGHT_JOIN t3 STRAIGHT_JOIN t2 WHERE ( t3.pk IN @@ -809,7 +1434,7 @@ AND t1.i1 <= t3.i2_key; id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY <subquery2> ALL distinct_key NULL NULL NULL 3 1 PRIMARY t1 ALL NULL NULL NULL NULL 4 Using join buffer (flat, BNL join) -1 PRIMARY t3 eq_ref PRIMARY PRIMARY 4 test.t4.i1 1 Using where +1 PRIMARY t3 eq_ref PRIMARY,v_idx2 PRIMARY 4 test.t4.i1 1 Using where 1 PRIMARY t2 ALL NULL NULL NULL NULL 5 Using join buffer (flat, BNL join) 2 MATERIALIZED t4 ALL NULL NULL NULL NULL 3 Using where SELECT /*+ NO_SEMIJOIN(@subq1) */ t1.c1, t2.i1 @@ -851,6 +1476,9 @@ t 9 # # Test 4: One non-covering index # +# Drop the index on two columns, add index on just one virtual column +ALTER TABLE t3 DROP INDEX v_idx2; +ALTER TABLE t3 ADD INDEX v_idx (i2_key); # Add more data to the table so that it will run the dynamic range scan # as both table scan and range scan (the purpose of this is to make the # table scan more expensive). @@ -873,7 +1501,7 @@ AND t1.i1 <= t3.i2_key; id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY <subquery2> ALL distinct_key NULL NULL NULL 3 1 PRIMARY t1 ALL NULL NULL NULL NULL 4 Using join buffer (flat, BNL join) -1 PRIMARY t3 eq_ref PRIMARY PRIMARY 4 test.t4.i1 1 Using where +1 PRIMARY t3 eq_ref PRIMARY,v_idx PRIMARY 4 test.t4.i1 1 Using where 1 PRIMARY t2 ALL NULL NULL NULL NULL 5 Using join buffer (flat, BNL join) 2 MATERIALIZED t4 ALL NULL NULL NULL NULL 3 Using where SELECT /*+ NO_SEMIJOIN(@subq1) */ t1.c1, t2.i1, t3.i1 @@ -929,7 +1557,7 @@ AND t1.i1 <= t3.i2_key; id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY t4 ALL NULL NULL NULL NULL 3 Using where; Start temporary 1 PRIMARY t1 ALL NULL NULL NULL NULL 4 Using join buffer (flat, BNL join) -1 PRIMARY t3 eq_ref PRIMARY PRIMARY 4 test.t4.i1 1 Using where +1 PRIMARY t3 eq_ref PRIMARY,v_idx PRIMARY 4 test.t4.i1 1 Using where 1 PRIMARY t2 ALL NULL NULL NULL NULL 5 Using where; End temporary; Using join buffer (flat, BNL join) SELECT /*+ NO_SEMIJOIN(@subq1) */ t1.c1, t2.i1 FROM t1 STRAIGHT_JOIN t3 STRAIGHT_JOIN t2 diff --git a/mysql-test/suite/gcol/t/gcol_column_def_options_myisam.test b/mysql-test/suite/gcol/t/gcol_column_def_options_myisam.test index 4f91b0021bc..6f04ecf3865 100644 --- a/mysql-test/suite/gcol/t/gcol_column_def_options_myisam.test +++ b/mysql-test/suite/gcol/t/gcol_column_def_options_myisam.test @@ -35,8 +35,7 @@ eval SET @@session.default_storage_engine = 'MyISAM'; #------------------------------------------------------------------------------# # Execute the tests to be applied to all storage engines -let $support_virtual_index= 0; -let $support_virtual_foreign= 0; +let $support_virtual_index= 1; --source suite/gcol/inc/gcol_column_def_options.inc #------------------------------------------------------------------------------# diff --git a/mysql-test/suite/gcol/t/gcol_ins_upd_myisam.test b/mysql-test/suite/gcol/t/gcol_ins_upd_myisam.test index 168321caab9..d54a6ae6f02 100644 --- a/mysql-test/suite/gcol/t/gcol_ins_upd_myisam.test +++ b/mysql-test/suite/gcol/t/gcol_ins_upd_myisam.test @@ -35,7 +35,7 @@ eval SET @@session.default_storage_engine = 'MyISAM'; #------------------------------------------------------------------------------# # 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_ins_upd.inc #------------------------------------------------------------------------------# diff --git a/mysql-test/suite/gcol/t/gcol_keys_myisam.test b/mysql-test/suite/gcol/t/gcol_keys_myisam.test index bbe27b90c7e..9cd89107126 100644 --- a/mysql-test/suite/gcol/t/gcol_keys_myisam.test +++ b/mysql-test/suite/gcol/t/gcol_keys_myisam.test @@ -35,7 +35,8 @@ eval SET @@session.default_storage_engine = 'MyISAM'; #------------------------------------------------------------------------------# # Execute the tests to be applied to all storage engines -let $support_virtual_index= 0; +let $support_virtual_index= 1; +let $skip_foreign_key_check=1; --source suite/gcol/inc/gcol_keys.inc #------------------------------------------------------------------------------# diff --git a/mysql-test/suite/gcol/t/gcol_select_myisam.test b/mysql-test/suite/gcol/t/gcol_select_myisam.test index bb2b46a4fa3..e078efbad0c 100644 --- a/mysql-test/suite/gcol/t/gcol_select_myisam.test +++ b/mysql-test/suite/gcol/t/gcol_select_myisam.test @@ -40,7 +40,7 @@ eval SET optimizer_switch='derived_merge=off'; #------------------------------------------------------------------------------# # 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_select.inc #------------------------------------------------------------------------------# diff --git a/mysql-test/suite/vcol/inc/vcol_keys.inc b/mysql-test/suite/vcol/inc/vcol_keys.inc index 6d859a4b0c3..95fd8a6488d 100644 --- a/mysql-test/suite/vcol/inc/vcol_keys.inc +++ b/mysql-test/suite/vcol/inc/vcol_keys.inc @@ -23,22 +23,21 @@ --echo # - CHECK (allowed but not used) --echo # UNIQUE ---error ER_KEY_BASED_ON_GENERATED_VIRTUAL_COLUMN create table t1 (a int, b int as (a*2) unique); +drop table t1; create table t1 (a int, b int as (a*2) persistent unique); show create table t1; describe t1; drop table t1; ---error ER_KEY_BASED_ON_GENERATED_VIRTUAL_COLUMN create table t1 (a int, b int as (a*2), unique key (b)); +drop table t1; create table t1 (a int, b int as (a*2) persistent, unique (b)); show create table t1; describe t1; drop table t1; create table t1 (a int, b int as (a*2)); ---error ER_KEY_BASED_ON_GENERATED_VIRTUAL_COLUMN alter table t1 add unique key (b); drop table t1; create table t1 (a int, b int as (a*2) persistent); @@ -52,10 +51,10 @@ drop table t1; --echo # --echo # INDEX ---error ER_KEY_BASED_ON_GENERATED_VIRTUAL_COLUMN create table t1 (a int, b int as (a*2), index (b)); ---error ER_KEY_BASED_ON_GENERATED_VIRTUAL_COLUMN +drop table t1; create table t1 (a int, b int as (a*2), index (a,b)); +drop table t1; create table t1 (a int, b int as (a*2) persistent, index (b)); show create table t1; @@ -68,9 +67,7 @@ describe t1; drop table t1; create table t1 (a int, b int as (a*2)); ---error ER_KEY_BASED_ON_GENERATED_VIRTUAL_COLUMN alter table t1 add index (b); ---error ER_KEY_BASED_ON_GENERATED_VIRTUAL_COLUMN alter table t1 add index (a,b); drop table t1; @@ -125,14 +122,16 @@ alter table t1 add foreign key (b) references t2(a) on update cascade; alter table t1 add foreign key (b) references t2(a) on delete set null; drop table t1; ---error ER_KEY_BASED_ON_GENERATED_VIRTUAL_COLUMN -create table t1 (a int, b int as (a+1), - foreign key (b) references t2(a)); +if ($with_foreign_keys) { +--error ER_CANT_CREATE_TABLE +create table t1 (a int, b int as (a+1), foreign key (b) references t2(a)); create table t1 (a int, b int as (a+1)); ---error ER_KEY_BASED_ON_GENERATED_VIRTUAL_COLUMN +--replace_regex /`#sql-.*`/`#sql-temporary`/ +--error ER_CANT_CREATE_TABLE alter table t1 add foreign key (b) references t2(a); drop table t1; +} --echo # Allowed FK options. create table t2 (a int primary key, b char(5)); diff --git a/mysql-test/suite/vcol/r/vcol_keys_myisam.result b/mysql-test/suite/vcol/r/vcol_keys_myisam.result index dccdf7f73e5..a62fc2ffda0 100644 --- a/mysql-test/suite/vcol/r/vcol_keys_myisam.result +++ b/mysql-test/suite/vcol/r/vcol_keys_myisam.result @@ -1,3 +1,119 @@ +create table t1 (a int, b int as (a+1), c int, index(b)); +insert t1 (a,c) values (0x7890abcd, 0x76543210); +insert t1 (a,c) select seq, sin(seq)*10000 from seq_1_to_1000; +explain select * from t1 where b=10; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 ref b b 5 const 1 +select * from t1 where b=10; +a b c +9 10 4121 + +MyISAM file: datadir/test/t1 +Record format: Fixed length +Character set: latin1_swedish_ci (8) +Data records: 1001 Deleted blocks: 0 +Recordlength: 9 + +table description: +Key Start Len Index Type +1 10 4 multip. long NULL +update t1 set a=20 where b=10; +select * from t1 where b=10; +a b c +select * from t1 where b=21; +a b c +20 21 4121 +20 21 9129 +delete from t1 where b=21; +select * from t1 where b=21; +a b c +alter table t1 add column d char(20) as (concat(a,c)); +select * from t1 where b=11; +a b c d +10 11 -5440 10-5440 +create index i on t1 (d); +check table t1; +Table Op Msg_type Msg_text +test.t1 check status OK +select * from t1 where b=11; +a b c d +10 11 -5440 10-5440 +check table t1 quick; +Table Op Msg_type Msg_text +test.t1 check status OK +select * from t1 where b=11; +a b c d +10 11 -5440 10-5440 +check table t1 medium; +Table Op Msg_type Msg_text +test.t1 check status OK +select * from t1 where b=11; +a b c d +10 11 -5440 10-5440 +check table t1 extended; +Table Op Msg_type Msg_text +test.t1 check status OK +show keys from t1; +Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment Index_comment +t1 1 b 1 b A 999 NULL NULL YES BTREE +t1 1 i 1 d A 999 NULL NULL YES BTREE +select * from t1 where b=11; +a b c d +10 11 -5440 10-5440 +delete from t1 where b=12; +analyze table t1; +Table Op Msg_type Msg_text +test.t1 analyze status OK +show keys from t1; +Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment Index_comment +t1 1 b 1 b A 998 NULL NULL YES BTREE +t1 1 i 1 d A 998 NULL NULL YES BTREE +select * from t1 where b=11; +a b c d +10 11 -5440 10-5440 +optimize table t1; +Table Op Msg_type Msg_text +test.t1 optimize status OK +show keys from t1; +Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment Index_comment +t1 1 b 1 b A 998 NULL NULL YES BTREE +t1 1 i 1 d A 998 NULL NULL YES BTREE +select * from t1 where b=11; +a b c d +10 11 -5440 10-5440 +repair table t1; +Table Op Msg_type Msg_text +test.t1 repair status OK +select * from t1 where b=11; +a b c d +10 11 -5440 10-5440 +repair table t1 quick; +Table Op Msg_type Msg_text +test.t1 repair status OK +select * from t1 where b=11; +a b c d +10 11 -5440 10-5440 +repair table t1 extended; +Table Op Msg_type Msg_text +test.t1 repair status OK +select * from t1 where b=11; +a b c d +10 11 -5440 10-5440 +repair table t1 use_frm; +Table Op Msg_type Msg_text +test.t1 repair warning Number of rows changed from 0 to 998 +test.t1 repair status OK +select * from t1 where b=11; +a b c d +10 11 -5440 10-5440 +update t1 set a=30 where b=11; +select * from t1 where b=11; +a b c d +select * from t1 where b=31; +a b c d +30 31 -5440 30-5440 +30 31 -9880 30-9880 +drop table t1; SET @@session.storage_engine = 'MyISAM'; # - UNIQUE KEY # - INDEX @@ -7,7 +123,7 @@ SET @@session.storage_engine = 'MyISAM'; # - 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 +138,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 +154,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 +165,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 +196,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,13 +238,6 @@ 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)); -alter table t1 add foreign key (b) references t2(a); -ERROR HY000: Key/Index cannot be defined on a non-stored computed column -drop table t1; # Allowed FK options. create table t2 (a int primary key, b char(5)); create table t1 (a int, b int as (a % 10) persistent, diff --git a/mysql-test/suite/vcol/t/vcol_keys_myisam.test b/mysql-test/suite/vcol/t/vcol_keys_myisam.test index 26f4a2c5ae1..68fd7e1731b 100644 --- a/mysql-test/suite/vcol/t/vcol_keys_myisam.test +++ b/mysql-test/suite/vcol/t/vcol_keys_myisam.test @@ -1,3 +1,57 @@ + +--source include/have_sequence.inc +--let $datadir= `select @@datadir` + +create table t1 (a int, b int as (a+1), c int, index(b)); +insert t1 (a,c) values (0x7890abcd, 0x76543210); +insert t1 (a,c) select seq, sin(seq)*10000 from seq_1_to_1000; +explain select * from t1 where b=10; +select * from t1 where b=10; +--replace_result $datadir datadir +--exec $MYISAMCHK -d $datadir/test/t1 +update t1 set a=20 where b=10; +select * from t1 where b=10; +select * from t1 where b=21; +delete from t1 where b=21; +select * from t1 where b=21; +alter table t1 add column d char(20) as (concat(a,c)); +select * from t1 where b=11; +create index i on t1 (d); +check table t1; +select * from t1 where b=11; +check table t1 quick; +select * from t1 where b=11; +check table t1 medium; +select * from t1 where b=11; +check table t1 extended; +show keys from t1; +select * from t1 where b=11; +delete from t1 where b=12; +analyze table t1; +show keys from t1; +select * from t1 where b=11; +optimize table t1; +show keys from t1; +select * from t1 where b=11; +repair table t1; +select * from t1 where b=11; +repair table t1 quick; +select * from t1 where b=11; +repair table t1 extended; +select * from t1 where b=11; +repair table t1 use_frm; +select * from t1 where b=11; +update t1 set a=30 where b=11; +select * from t1 where b=11; +select * from t1 where b=31; + +--error 1 +--exec $MYISAMCHK $datadir/test/t1 +--error 1 +--exec $MYISAMCHK -r $datadir/test/t1 + +drop table t1; + ################################################################################ # t/vcol_keys_myisam.test # # # diff --git a/mysys/my_bitmap.c b/mysys/my_bitmap.c index 0eaf1a88aa1..a0c1a23d63c 100644 --- a/mysys/my_bitmap.c +++ b/mysys/my_bitmap.c @@ -168,7 +168,7 @@ static inline uint get_first_set(my_bitmap_map value, uint word_pos) my_bool my_bitmap_init(MY_BITMAP *map, my_bitmap_map *buf, uint n_bits, - my_bool thread_safe __attribute__((unused))) + my_bool thread_safe) { DBUG_ENTER("my_bitmap_init"); if (!buf) diff --git a/sql/field.h b/sql/field.h index 8644037d13a..2cdbd50e278 100644 --- a/sql/field.h +++ b/sql/field.h @@ -1175,6 +1175,11 @@ public: ptr=ptr_arg; null_ptr=null_ptr_arg; null_bit=null_bit_arg; } inline void move_field(uchar *ptr_arg) { ptr=ptr_arg; } + inline uchar *record_ptr() // record[0] or wherever the field was moved to + { + my_ptrdiff_t offset= table->s->field[field_index]->ptr - table->s->default_values; + return ptr - offset; + } virtual void move_field_offset(my_ptrdiff_t ptr_diff) { ptr=ADD_TO_PTR(ptr,ptr_diff, uchar*); diff --git a/sql/sql_table.cc b/sql/sql_table.cc index ccd9288cfb7..7b18322662a 100644 --- a/sql/sql_table.cc +++ b/sql/sql_table.cc @@ -3916,12 +3916,6 @@ mysql_prepare_create_table(THD *thd, HA_CREATE_INFO *create_info, } } #endif - if (!sql_field->stored_in_db()) - { - /* Key fields must always be physically stored. */ - my_error(ER_KEY_BASED_ON_GENERATED_VIRTUAL_COLUMN, MYF(0)); - DBUG_RETURN(TRUE); - } if (key->type == Key::PRIMARY && sql_field->vcol_info) { my_error(ER_PRIMARY_KEY_BASED_ON_VIRTUAL_COLUMN, MYF(0)); @@ -6226,9 +6220,11 @@ 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) +static bool vcol_affecting_storage(const Virtual_column_info* vcol, + bool indexed) { - return vcol && (vcol->is_stored() || vcol->is_in_partitioning_expr()); + return vcol && + (vcol->is_stored() || vcol->is_in_partitioning_expr() || indexed); } /** @@ -6437,15 +6433,28 @@ static bool fill_alter_inplace_info(THD *thd, ha_alter_info->handler_flags|= Alter_inplace_info::ALTER_COLUMN_TYPE; } - if (vcol_affecting_storage(field->vcol_info) || - vcol_affecting_storage(new_field->vcol_info)) + if (vcol_affecting_storage(field->vcol_info, + field->flags & PART_KEY_FLAG) || + vcol_affecting_storage(new_field->vcol_info, false)) { 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 - maybe_alter_vcol= true; + { + if (!(ha_alter_info->handler_flags & Alter_inplace_info::ALTER_COLUMN_VCOL) && + (ha_alter_info->handler_flags & Alter_inplace_info::ALTER_COLUMN_DEFAULT)) + { /* + a DEFAULT value of a some column was changed. + see if this vcol uses DEFAULT() function + */ + 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; + } + } + maybe_alter_vcol= true; } /* Check if field was renamed */ @@ -6514,10 +6523,10 @@ static bool fill_alter_inplace_info(THD *thd, if (maybe_alter_vcol) { /* - No virtual column was altered, but perhaps one of the other columns was, - and that column was part of the vcol expression? - We don't detect this correctly (FIXME), so let's just say that a vcol - *might* be affected if any other column was altered. + What if one of the normal columns was altered and it was part of the some + virtual column expression? Currently we don't detect this correctly + (FIXME), so let's just say that a vcol *might* be affected if any other + column was altered. */ if (ha_alter_info->handler_flags & ( Alter_inplace_info::ALTER_COLUMN_TYPE diff --git a/sql/sql_update.cc b/sql/sql_update.cc index 1ae90a31ebf..da0e6cd2116 100644 --- a/sql/sql_update.cc +++ b/sql/sql_update.cc @@ -254,7 +254,7 @@ int mysql_update(THD *thd, ha_rows *found_return, ha_rows *updated_return) { bool using_limit= limit != HA_POS_ERROR; - bool safe_update= MY_TEST(thd->variables.option_bits & OPTION_SAFE_UPDATES); + bool safe_update= thd->variables.option_bits & OPTION_SAFE_UPDATES; bool used_key_is_modified= FALSE, transactional_table, will_batch; bool can_compare_record; int res; @@ -2383,6 +2383,9 @@ int multi_update::do_updates() field_num++; } while ((tbl= check_opt_it++)); + if (table->vfield && table->update_virtual_fields(VCOL_UPDATE_INDEXED)) + goto err2; + table->status|= STATUS_UPDATED; store_record(table,record[1]); diff --git a/sql/table.cc b/sql/table.cc index 7c47aff078e..2c972446da3 100644 --- a/sql/table.cc +++ b/sql/table.cc @@ -6211,7 +6211,11 @@ void TABLE::mark_columns_needed_for_delete() for (reg_field= field ; *reg_field ; reg_field++) { if ((*reg_field)->flags & PART_KEY_FLAG) + { bitmap_set_bit(read_set, (*reg_field)->field_index); + if ((*reg_field)->vcol_info) + mark_virtual_col(*reg_field); + } } need_signal= true; } @@ -6544,7 +6548,8 @@ bool TABLE::mark_virtual_columns_for_write(bool insert_fl) tmp_vfield= *vfield_ptr; if (bitmap_is_set(write_set, tmp_vfield->field_index)) bitmap_updated= mark_virtual_col(tmp_vfield); - else if (tmp_vfield->vcol_info->stored_in_db) + else if (tmp_vfield->vcol_info->stored_in_db || + (tmp_vfield->flags & PART_KEY_FLAG)) { if (insert_fl) { @@ -7311,11 +7316,16 @@ int TABLE::update_virtual_fields(enum_vcol_update_mode update_mode) } case VCOL_UPDATE_FOR_READ: update= !vcol_info->stored_in_db + && !(key_read && vf->part_of_key.is_set(file->active_index)) && bitmap_is_set(vcol_set, vf->field_index); break; case VCOL_UPDATE_FOR_WRITE: update= triggers || bitmap_is_set(vcol_set, vf->field_index); break; + case VCOL_UPDATE_INDEXED: + update= !vcol_info->stored_in_db && (vf->flags & PART_KEY_FLAG) + && bitmap_is_set(vcol_set, vf->field_index); + break; } if (update) diff --git a/sql/table.h b/sql/table.h index 34da450fe44..27439670a22 100644 --- a/sql/table.h +++ b/sql/table.h @@ -327,7 +327,8 @@ enum enum_vcol_update_mode { VCOL_UPDATE_FOR_READ= 0, VCOL_UPDATE_FOR_READ_WRITE, - VCOL_UPDATE_FOR_WRITE + VCOL_UPDATE_FOR_WRITE, + VCOL_UPDATE_INDEXED }; diff --git a/storage/myisam/ha_myisam.cc b/storage/myisam/ha_myisam.cc index dbb72eac4c5..61f7fd37486 100644 --- a/storage/myisam/ha_myisam.cc +++ b/storage/myisam/ha_myisam.cc @@ -574,7 +574,6 @@ int check_definition(MI_KEYDEF *t1_keyinfo, MI_COLUMNDEF *t1_recinfo, DBUG_RETURN(0); } - extern "C" { int killed_ptr(HA_CHECK *param) @@ -661,6 +660,25 @@ my_bool mi_killed_in_mariadb(MI_INFO *info) return (((TABLE*) (info->external_ref))->in_use->killed != 0); } +static int compute_vcols(MI_INFO *info, uchar *record, int keynum) +{ + TABLE *table= (TABLE*)(info->external_ref); + table->move_fields(table->field, record, table->field[0]->record_ptr()); + if (keynum == -1) // update all vcols + return table->update_virtual_fields(VCOL_UPDATE_INDEXED); + + // update only one key + KEY *key= table->key_info + keynum; + KEY_PART_INFO *kp= key->key_part, *end= kp + key->ext_key_parts; + for (; kp < end; kp++) + { + Field *f= table->field[kp->fieldnr - 1]; + if (f->vcol_info) + table->update_virtual_field(f); + } + return 0; +} + } ha_myisam::ha_myisam(handlerton *hton, TABLE_SHARE *table_arg) @@ -668,6 +686,7 @@ ha_myisam::ha_myisam(handlerton *hton, TABLE_SHARE *table_arg) int_table_flags(HA_NULL_IN_KEY | HA_CAN_FULLTEXT | HA_CAN_SQL_HANDLER | HA_BINLOG_ROW_CAPABLE | HA_BINLOG_STMT_CAPABLE | HA_CAN_VIRTUAL_COLUMNS | HA_CAN_EXPORT | + HA_REQUIRES_KEY_COLUMNS_FOR_DELETE | HA_DUPLICATE_POS | HA_CAN_INDEX_BLOBS | HA_AUTO_PART_KEY | HA_FILE_BASED | HA_CAN_GEOMETRY | HA_NO_TRANSACTIONS | HA_CAN_INSERT_DELAYED | HA_CAN_BIT_FIELD | HA_CAN_RTREEKEYS | @@ -868,6 +887,27 @@ int ha_myisam::write_row(uchar *buf) return mi_write(file,buf); } +void ha_myisam::setup_vcols_for_repair(HA_CHECK *param) +{ + if (file->s->base.reclength < file->s->vreclength) + { + param->fix_record= compute_vcols; + table->use_all_columns(); + table->vcol_set= &table->s->all_set; + } + else + DBUG_ASSERT(file->s->base.reclength == file->s->vreclength); +} + +void ha_myisam::restore_vcos_after_repair() +{ + if (file->s->base.reclength < file->s->vreclength) + { + table->move_fields(table->field, table->record[0], table->field[0]->record_ptr()); + table->default_column_bitmaps(); + } +} + int ha_myisam::check(THD* thd, HA_CHECK_OPT* check_opt) { if (!file) return HA_ADMIN_INTERNAL_ERROR; @@ -901,6 +941,8 @@ int ha_myisam::check(THD* thd, HA_CHECK_OPT* check_opt) (uint) (share->global_changed ? 1 : 0))))) return HA_ADMIN_ALREADY_DONE; + setup_vcols_for_repair(¶m); + error = chk_status(¶m, file); // Not fatal error = chk_size(¶m, file); if (!error) @@ -953,6 +995,8 @@ int ha_myisam::check(THD* thd, HA_CHECK_OPT* check_opt) file->update |= HA_STATE_CHANGED | HA_STATE_ROW_CHANGED; } + restore_vcos_after_repair(); + thd_proc_info(thd, old_proc_info); return error ? HA_ADMIN_CORRUPT : HA_ADMIN_OK; } @@ -986,6 +1030,8 @@ int ha_myisam::analyze(THD *thd, HA_CHECK_OPT* check_opt) if (!(share->state.changed & STATE_NOT_ANALYZED)) return HA_ADMIN_ALREADY_DONE; + setup_vcols_for_repair(¶m); + error = chk_key(¶m, file); if (!error) { @@ -995,6 +1041,9 @@ int ha_myisam::analyze(THD *thd, HA_CHECK_OPT* check_opt) } else if (!mi_is_crashed(file) && !thd->killed) mi_mark_crashed(file); + + restore_vcos_after_repair(); + return error ? HA_ADMIN_CORRUPT : HA_ADMIN_OK; } @@ -1017,6 +1066,9 @@ int ha_myisam::repair(THD* thd, HA_CHECK_OPT *check_opt) param.sort_buffer_length= THDVAR(thd, sort_buffer_size); param.backup_time= check_opt->start_time; start_records=file->state->records; + + setup_vcols_for_repair(¶m); + while ((error=repair(thd,param,0)) && param.retry_repair) { param.retry_repair=0; @@ -1040,6 +1092,9 @@ int ha_myisam::repair(THD* thd, HA_CHECK_OPT *check_opt) } break; } + + restore_vcos_after_repair(); + if (!error && start_records != file->state->records && !(check_opt->flags & T_VERY_SILENT)) { @@ -1066,6 +1121,9 @@ int ha_myisam::optimize(THD* thd, HA_CHECK_OPT *check_opt) T_REP_BY_SORT | T_STATISTICS | T_SORT_INDEX); param.tmpfile_createflag= O_RDWR | O_TRUNC; param.sort_buffer_length= THDVAR(thd, sort_buffer_size); + + setup_vcols_for_repair(¶m); + if ((error= repair(thd,param,1)) && param.retry_repair) { sql_print_warning("Warning: Optimize table got errno %d on %s.%s, retrying", @@ -1073,6 +1131,9 @@ int ha_myisam::optimize(THD* thd, HA_CHECK_OPT *check_opt) param.testflag&= ~T_REP_BY_SORT; error= repair(thd,param,1); } + + restore_vcos_after_repair(); + return error; } @@ -1482,6 +1543,9 @@ int ha_myisam::enable_indexes(uint mode) param.sort_buffer_length= THDVAR(thd, sort_buffer_size); param.stats_method= (enum_handler_stats_method)THDVAR(thd, stats_method); param.tmpdir=&mysql_tmpdir_list; + + setup_vcols_for_repair(¶m); + if ((error= (repair(thd,param,0) != HA_ADMIN_OK)) && param.retry_repair) { sql_print_warning("Warning: Enabling keys got errno %d on %s.%s, retrying", @@ -1507,6 +1571,8 @@ int ha_myisam::enable_indexes(uint mode) } info(HA_STATUS_CONST); thd_proc_info(thd, save_proc_info); + + restore_vcos_after_repair(); } else { @@ -2012,14 +2078,14 @@ int ha_myisam::create(const char *name, register TABLE *table_arg, TABLE_SHARE *share= table_arg->s; uint options= share->db_options_in_use; DBUG_ENTER("ha_myisam::create"); - for (i= 0; i < share->keys; i++) - { + + for (i= 0; i < share->virtual_fields && !create_flags; i++) + if (table_arg->vfield[i]->flags & PART_KEY_FLAG) + create_flags|= HA_CREATE_RELIES_ON_SQL_LAYER; + for (i= 0; i < share->keys && !create_flags; i++) if (table_arg->key_info[i].flags & HA_USES_PARSER) - { create_flags|= HA_CREATE_RELIES_ON_SQL_LAYER; - break; - } - } + if ((error= table2myisam(table_arg, &keydef, &recinfo, &record_count))) DBUG_RETURN(error); /* purecov: inspected */ bzero((char*) &create_info, sizeof(create_info)); diff --git a/storage/myisam/ha_myisam.h b/storage/myisam/ha_myisam.h index 63fb0ea5a2a..bb1a36e089b 100644 --- a/storage/myisam/ha_myisam.h +++ b/storage/myisam/ha_myisam.h @@ -48,6 +48,8 @@ class ha_myisam: public handler char *data_file_name, *index_file_name; bool can_enable_indexes; int repair(THD *thd, HA_CHECK ¶m, bool optimize); + void setup_vcols_for_repair(HA_CHECK *param); + void restore_vcos_after_repair(); public: ha_myisam(handlerton *hton, TABLE_SHARE *table_arg); diff --git a/storage/myisam/mi_check.c b/storage/myisam/mi_check.c index c8e6bc3cd76..8de200f5e72 100644 --- a/storage/myisam/mi_check.c +++ b/storage/myisam/mi_check.c @@ -1190,6 +1190,8 @@ int chk_data_link(HA_CHECK *param, MI_INFO *info, my_bool extend) DBUG_ASSERT(0); /* Impossible */ break; } /* switch */ + if (param->fix_record) + param->fix_record(info, record, -1); if (! got_error) { intern_record_checksum+=(ha_checksum) start_recpos; @@ -3646,6 +3648,10 @@ static int sort_get_next_record(MI_SORT_PARAM *sort_param) finish: if (sort_param->calc_checksum) param->glob_crc+= info->checksum; + if (param->fix_record) + param->fix_record(info, sort_param->record, + param->testflag & T_REP_BY_SORT ? (int)sort_param->key + : -1); DBUG_RETURN(0); } diff --git a/storage/myisam/mi_open.c b/storage/myisam/mi_open.c index 6bf16f6a426..776594a6409 100644 --- a/storage/myisam/mi_open.c +++ b/storage/myisam/mi_open.c @@ -328,6 +328,7 @@ MI_INFO *mi_open(const char *name, int mode, uint open_flags) strmov(share->index_file_name, index_name); strmov(share->data_file_name, data_name); + share->vreclength= share->base.reclength; share->blocksize=MY_MIN(IO_SIZE,myisam_block_size); { HA_KEYSEG *pos=share->keyparts; @@ -335,6 +336,7 @@ MI_INFO *mi_open(const char *name, int mode, uint open_flags) for (i=0 ; i < keys ; i++) { MI_KEYDEF *keyinfo= share->keyinfo + i; + uint sp_segs; keyinfo->share= share; disk_pos=mi_keydef_read(disk_pos, keyinfo); disk_pos_assert(disk_pos + keyinfo->keysegs * HA_KEYSEG_SIZE, end_pos); @@ -342,7 +344,11 @@ MI_INFO *mi_open(const char *name, int mode, uint open_flags) have_rtree=1; set_if_smaller(share->blocksize, keyinfo->block_length); keyinfo->seg= pos; - for (j=0 ; j < keyinfo->keysegs; j++,pos++) + if (keyinfo->flag & HA_SPATIAL) + sp_segs= 2*SPDIMS; + else + sp_segs= 0; + for (j=0 ; j < keyinfo->keysegs; j++, pos++) { disk_pos=mi_keyseg_read(disk_pos, pos); if (pos->flag & HA_BLOB_PART && @@ -366,17 +372,16 @@ MI_INFO *mi_open(const char *name, int mode, uint open_flags) } else if (pos->type == HA_KEYTYPE_BINARY) pos->charset= &my_charset_bin; - if (!(keyinfo->flag & HA_SPATIAL) && - pos->start > share->base.reclength) + if (j < keyinfo->keysegs - sp_segs) { - my_errno= HA_ERR_CRASHED; - goto err; + uint real_length= pos->flag & HA_BLOB_PART ? pos->bit_start + : pos->length; + set_if_bigger(share->vreclength, pos->start + real_length); } } if (keyinfo->flag & HA_SPATIAL) { #ifdef HAVE_SPATIAL - uint sp_segs= SPDIMS*2; keyinfo->seg= pos - sp_segs; DBUG_ASSERT(keyinfo->keysegs == sp_segs + 1); keyinfo->keysegs= sp_segs; diff --git a/storage/myisam/myisamdef.h b/storage/myisam/myisamdef.h index 336f1170d29..f467d44bcb9 100644 --- a/storage/myisam/myisamdef.h +++ b/storage/myisam/myisamdef.h @@ -199,6 +199,7 @@ typedef struct st_mi_isam_share ulong max_pack_length; ulong state_diff_length; uint rec_reflength; /* rec_reflength in use now */ + ulong vreclength; /* full reclength, including vcols */ uint unique_name_length; uint32 ftkeys; /* Number of full-text keys + 1 */ File kfile; /* Shared keyfile */ |