diff options
author | Sergei Golubchik <sergii@pisem.net> | 2011-10-19 21:45:18 +0200 |
---|---|---|
committer | Sergei Golubchik <sergii@pisem.net> | 2011-10-19 21:45:18 +0200 |
commit | 76f0b94bb0b2994d639353530c5b251d0f1a204b (patch) | |
tree | 9ed50628aac34f89a37637bab2fc4915b86b5eb4 /mysql-test/t | |
parent | 4e46d8e5bff140f2549841167dc4b65a3c0a645d (diff) | |
parent | 5dc1a2231f55bacc9aaf0e24816f3d9c2ee1f21d (diff) | |
download | mariadb-git-76f0b94bb0b2994d639353530c5b251d0f1a204b.tar.gz |
merge with 5.3
sql/sql_insert.cc:
CREATE ... IF NOT EXISTS may do nothing, but
it is still not a failure. don't forget to my_ok it.
******
CREATE ... IF NOT EXISTS may do nothing, but
it is still not a failure. don't forget to my_ok it.
sql/sql_table.cc:
small cleanup
******
small cleanup
Diffstat (limited to 'mysql-test/t')
142 files changed, 13375 insertions, 1449 deletions
diff --git a/mysql-test/t/alter_table_online.test b/mysql-test/t/alter_table_online.test new file mode 100644 index 00000000000..19096efe0fa --- /dev/null +++ b/mysql-test/t/alter_table_online.test @@ -0,0 +1,108 @@ +# +# Test of alter online table +# + +--source include/have_innodb.inc +--disable_warnings +drop table if exists t1,t2,t3; +--enable_warnings +# +# Test of things that can be done online +# + +create table t1 (a int not null primary key, b int, c varchar(80), e enum('a','b')); +insert into t1 (a) values (1),(2),(3); + +alter online table t1 modify b int default 5; +alter online table t1 change b new_name int; +alter online table t1 modify e enum('a','b','c'); +alter online table t1 comment "new comment"; +alter online table t1 rename to t2; +alter online table t2 rename to t1; + +drop table t1; + +# +# temporary tables always require a copy +# + +create temporary table t1 (a int not null primary key, b int, c varchar(80), e enum('a','b')); +insert into t1 (a) values (1),(2),(3); + +--error ER_CANT_DO_ONLINE +alter online table t1 modify b int default 5; +--error ER_CANT_DO_ONLINE +alter online table t1 change b new_name int; +--error ER_CANT_DO_ONLINE +alter online table t1 modify e enum('a','b','c'); +--error ER_CANT_DO_ONLINE +alter online table t1 comment "new comment"; +--error ER_CANT_DO_ONLINE +alter online table t1 rename to t2; + +drop table t1; + +# +# Test of things that is not possible to do online +# + +create table t1 (a int not null primary key, b int, c varchar(80), e enum('a','b')); +insert into t1 (a) values (1),(2),(3); + +--error ER_CANT_DO_ONLINE +alter online table t1 drop column b, add b int; +--error ER_CANT_DO_ONLINE +alter online table t1 modify b bigint; +--error ER_CANT_DO_ONLINE +alter online table t1 modify e enum('c','a','b'); +--error ER_CANT_DO_ONLINE +alter online table t1 modify c varchar(50); +--error ER_CANT_DO_ONLINE +alter online table t1 modify c varchar(100); +--error ER_CANT_DO_ONLINE +alter online table t1 add f int; +--error ER_CANT_DO_ONLINE +alter online table t1 engine=memory; + +alter table t1 engine=innodb; +alter table t1 add index (b); +--error ER_CANT_DO_ONLINE +alter online table t1 add index c (c); +--error ER_CANT_DO_ONLINE +alter online table t1 drop index b; +drop table t1; + +create temporary table t1 (a int not null primary key, b int, c varchar(80), e enum('a','b')); +insert into t1 (a) values (1),(2),(3); + +--error ER_CANT_DO_ONLINE +alter online table t1 drop column b, add b int; +--error ER_CANT_DO_ONLINE +alter online table t1 modify b bigint; +--error ER_CANT_DO_ONLINE +alter online table t1 modify e enum('c','a','b'); +--error ER_CANT_DO_ONLINE +alter online table t1 modify c varchar(50); +--error ER_CANT_DO_ONLINE +alter online table t1 modify c varchar(100); +--error ER_CANT_DO_ONLINE +alter online table t1 add f int; +--error ER_CANT_DO_ONLINE +alter online table t1 engine=memory; + +alter table t1 engine=innodb; +alter table t1 add index (b); +--error ER_CANT_DO_ONLINE +alter online table t1 add index c (c); +--error ER_CANT_DO_ONLINE +alter online table t1 drop index b; +drop table t1; + +# +# Test merge tables +# +create table t1 (a int not null primary key, b int, c varchar(80)); +create table t2 (a int not null primary key, b int, c varchar(80)); +create table t3 (a int not null primary key, b int, c varchar(80)) engine=merge UNION=(t1); +alter online table t3 union=(t1,t2); +drop table t1,t2,t3; diff --git a/mysql-test/t/archive.test b/mysql-test/t/archive.test index 9167dbf86e6..bb6b4ec9c17 100644 --- a/mysql-test/t/archive.test +++ b/mysql-test/t/archive.test @@ -6,6 +6,7 @@ -- source include/have_binlog_format_mixed_or_statement.inc CALL mtr.add_suppression("Unsafe statement written to the binary log using statement format since BINLOG_FORMAT = STATEMENT"); +call mtr.add_suppression("Table 't1' is marked as crashed and should be repaired"); --disable_warnings DROP TABLE if exists t1,t2,t3,t4,t5,t6; @@ -1644,6 +1645,11 @@ DROP TABLE t1,t2; # BUG#47012 archive tables are not upgradeable, and server crashes on any access # let $MYSQLD_DATADIR= `SELECT @@datadir`; + +# Remove files to handle possible restart of test +flush tables; +remove_files_wildcard $MYSQLD_DATADIR/test t1.*; + copy_file std_data/bug47012.frm $MYSQLD_DATADIR/test/t1.frm; copy_file std_data/bug47012.ARZ $MYSQLD_DATADIR/test/t1.ARZ; copy_file std_data/bug47012.ARM $MYSQLD_DATADIR/test/t1.ARM; diff --git a/mysql-test/t/archive_plugin.test b/mysql-test/t/archive_plugin.test index 7d9b0ea065f..b1126ab0c87 100644 --- a/mysql-test/t/archive_plugin.test +++ b/mysql-test/t/archive_plugin.test @@ -1,20 +1,17 @@ ---source include/not_windows.inc ---source include/have_archive_plugin.inc - -# When running in parallel we get -# Warning 1620 Plugin is busy and will be uninstalled on shutdown ---source include/not_parallel.inc +if (!$HA_ARCHIVE_SO) { + --skip Need example plugin +} CREATE TABLE t1(a int) ENGINE=ARCHIVE; DROP TABLE t1; -INSTALL PLUGIN archive SONAME 'ha_archive.so'; +eval INSTALL PLUGIN archive SONAME '$HA_ARCHIVE_SO'; --error 1125 -INSTALL PLUGIN ARCHIVE SONAME 'ha_archive.so'; +eval INSTALL PLUGIN ARCHIVE SONAME '$HA_ARCHIVE_SO'; UNINSTALL PLUGIN archive; -INSTALL PLUGIN archive SONAME 'ha_archive.so'; +eval INSTALL PLUGIN archive SONAME '$HA_ARCHIVE_SO'; CREATE TABLE t1(a int) ENGINE=ARCHIVE; diff --git a/mysql-test/t/blackhole_plugin.test b/mysql-test/t/blackhole_plugin.test index 448104bed2b..e598c3f1b11 100644 --- a/mysql-test/t/blackhole_plugin.test +++ b/mysql-test/t/blackhole_plugin.test @@ -1,20 +1,17 @@ ---source include/not_windows.inc ---source include/have_blackhole_plugin.inc - -# When running in parallel we get -# Warning 1620 Plugin is busy and will be uninstalled on shutdown ---source include/not_parallel.inc +if (!$HA_BLACKHOLE_SO) { + --skip Need blackhole plugin +} CREATE TABLE t1(a int) ENGINE=BLACKHOLE; DROP TABLE t1; -eval INSTALL PLUGIN blackhole SONAME 'ha_blackhole.so'; +eval INSTALL PLUGIN blackhole SONAME '$HA_BLACKHOLE_SO'; --error 1125 -eval INSTALL PLUGIN BLACKHOLE SONAME 'ha_blackhole.so'; +eval INSTALL PLUGIN BLACKHOLE SONAME '$HA_BLACKHOLE_SO'; UNINSTALL PLUGIN blackhole; -eval INSTALL PLUGIN blackhole SONAME 'ha_blackhole.so'; +eval INSTALL PLUGIN blackhole SONAME '$HA_BLACKHOLE_SO'; CREATE TABLE t1(a int) ENGINE=BLACKHOLE; diff --git a/mysql-test/t/cast.test b/mysql-test/t/cast.test index a922cc9aaf7..522007f6079 100644 --- a/mysql-test/t/cast.test +++ b/mysql-test/t/cast.test @@ -9,14 +9,60 @@ select cast(-5 as unsigned) | 1, cast(-5 as unsigned) & -1; select cast(-5 as unsigned) -1, cast(-5 as unsigned) + 1; select ~5, cast(~5 as signed); explain extended select ~5, cast(~5 as signed); +select cast(18446744073709551615 as signed); select cast(5 as unsigned) -6.0; select cast(NULL as signed), cast(1/0 as signed); +select cast(1 as double(5,2)); +select cast("5.2222" as double(5,2)); +select cast(12.444 as double(5,2)); +select cast(cast(12.444 as decimal(10,3)) as double(5,2)); +select cast(null as double(5,2)); +select cast(12.444 as double); +select cast(cast("20:01:01" as time) as datetime); +select cast(cast("8:46:06.23434" AS time) as decimal(32,10)); +select cast(cast("2011-04-05 8:46:06.23434" AS datetime) as decimal(32,6)); + +--echo # +--echo # Check handling of cast with microseconds +--echo # +select cast(cast(20010203101112.121314 as double) as datetime); +select cast(cast(010203101112.12 as double) as datetime); +select cast(cast(20010203101112.121314 as decimal(32,6)) as datetime); +select cast(20010203101112.121314 as datetime); +select cast(110203101112.121314 as datetime); +select cast(cast(010203101112.12 as double) as datetime); + +select cast("2011-02-03 10:11:12.123456" as datetime); +select cast("2011-02-03 10:11:12.123456" as datetime(0)); +select cast("2011-02-03 10:11:12.123456" as datetime(5)); +select cast("2011-02-03 10:11:12.123456" as datetime(6)); +select cast("2011-02-03 10:11:12" as datetime(6)); +select cast(cast(20010203101112.1 as double) as datetime(1)); +select cast(cast(010203101112.12 as double) as datetime(2)); +select cast(cast(20010203101112.121314 as decimal(32,6)) as datetime(6)); +select cast(20010203101112.121314 as datetime(6)); +select cast(110203101112.121314 as datetime(6)); +select cast(cast(010203101112.12 as double) as datetime(6)); + +select cast("2011-02-03 10:11:12.123456" as time); +select cast("2011-02-03 10:11:12.123456" as time(6)); +select cast("10:11:12.123456" as time); +select cast("10:11:12.123456" as time(0)); +select cast("10:11:12.123456" as time(5)); +select cast("10:11:12.123456" as time(6)); +select cast("10:11:12" as time(6)); +select cast(cast("2011-04-05 8:46:06.123456" AS datetime) as time); +select cast(cast("2011-04-05 8:46:06.123456" AS datetime) as time(6)); +select cast(cast("2011-04-05 8:46:06.123456" AS datetime(6)) as time); +select cast(cast("2011-04-05 8:46:06.123456" AS datetime(6)) as time(6)); + # # Bug #28250: Run-Time Check Failure #3 - The variable 'value' is being used # without being def # # The following line causes Run-Time Check Failure on # binaries built with Visual C++ 2005 +# select cast(NULL as unsigned), cast(1/0 as unsigned); select cast("A" as binary) = "a", cast(BINARY "a" as CHAR) = "A"; select cast("2001-1-1" as DATE), cast("2001-1-1" as DATETIME); @@ -42,6 +88,44 @@ select cast('a10' as unsigned integer); select 10+'a'; select 10.0+cast('a' as decimal); select 10E+0+'a'; +select cast("a" as double(5,2)); +select cast(1000 as decimal(5,2)); +select cast(-1000 as decimal(5,2)); +select cast(1000 as double(5,2)); +select cast(-1000 as double(5,2)); +select cast(010203101112.121314 as datetime); +select cast(120010203101112.121314 as datetime); +select cast(cast(1.1 as decimal) as datetime); +select cast(cast(-1.1 as decimal) as datetime); +select cast('0' as date); +select cast('' as date); +select cast('0' as datetime); +select cast('' as datetime); +select cast('0' as time); +select cast('' as time); +select cast(NULL as DATE); +select cast(NULL as DATETIME); +select cast(NULL as TIME); +select cast(NULL as BINARY); + +# +# We have to disable warnings for these as the printed double value is +# not portable +# +--disable_warnings +select cast(cast(120010203101112.121314 as double) as datetime); +select cast(cast(1.1 as double) as datetime); +select cast(cast(-1.1 as double) as datetime); +--enable_warnings + + +# +# Some EXPLAIN EXTENDED to ensure the print functions are correct +# + +explain extended select cast(10 as double(5,2)); +explain extended select cast(10 as double); +explain extended select cast(10 as decimal(5,2)); # out-of-range cases select cast('18446744073709551616' as unsigned); @@ -52,6 +136,20 @@ select cast('abc' as signed); select cast('1a' as signed); select cast('' as signed); +--error ER_M_BIGGER_THAN_D +select cast(1 as double(5,6)); +--error ER_M_BIGGER_THAN_D +select cast(1 as decimal(5,6)); +--error ER_TOO_BIG_PRECISION +select cast(1 as double(66,6)); +--error ER_TOO_BIG_PRECISION +select cast(1 as decimal(66,6)); +--error ER_TOO_BIG_SCALE +select cast(1 as decimal(64,63)); +--error ER_TOO_BIG_SCALE +select cast(1 as double(64,63)); + + # # Character set conversion # @@ -124,8 +222,6 @@ set names binary; select cast("2001-1-1" as date) = "2001-01-01"; select cast("2001-1-1" as datetime) = "2001-01-01 00:00:00"; select cast("1:2:3" as TIME) = "1:02:03"; -select cast(NULL as DATE); -select cast(NULL as BINARY); # # Bug #5228 ORDER BY CAST(enumcol) sorts incorrectly under certain conditions @@ -172,6 +268,14 @@ select cast(repeat('1',20) as signed); select cast(1.0e+300 as signed int); # +# Test that we create the correct types with create ... select cast() +# + +create table t1 select cast(1 as unsigned), cast(1 as signed), cast(1 as double(5,2)), cast(1 as decimal(5,3)), cast("A" as binary), cast("A" as char(100)), cast("2001-1-1" as DATE), cast("2001-1-1" as DATETIME), cast("1:2:3" as TIME); +show create table t1; +drop table t1; + +# # Bugs: #15098: CAST(column double TO signed int), wrong result # CREATE TABLE t1 (f1 double); @@ -296,3 +400,22 @@ disconnect newconn; SET @@GLOBAL.max_allowed_packet=default; --echo End of 5.1 tests + +select cast("2101-00-01 02:03:04" as datetime); +select cast(cast("2101-00-01 02:03:04" as datetime) as time); +SELECT CAST(CAST('20:05:05' AS TIME) as date); +set sql_mode= TRADITIONAL; +select cast("2101-00-01 02:03:04" as datetime); +select cast(cast("2101-00-01 02:03:04" as datetime) as time); +SELECT CAST(CAST('20:05:05' AS TIME) as date); +set sql_mode=DEFAULT; + +# +# lp:737458 Casting dates and times into integers works differently +# in 5.1-micro +# +create table t1 (f1 time, f2 date, f3 datetime); +insert into t1 values ('11:22:33','2011-12-13','2011-12-13 11:22:33'); +select cast(f1 as unsigned), cast(f2 as unsigned), cast(f3 as unsigned) from t1; +drop table t1; + diff --git a/mysql-test/t/connect.test b/mysql-test/t/connect.test index a8c8b659c3c..e5c6e8371bf 100644 --- a/mysql-test/t/connect.test +++ b/mysql-test/t/connect.test @@ -320,6 +320,31 @@ if ($error) --echo # -- Success: more than --extra-max-connections + 1 normal connections not possible } +########################################################################### + +--echo # +--echo # -- Bug#49752: 2469.126.2 unintentionally breaks authentication +--echo # against MySQL 5.1 server +--echo # + +GRANT ALL ON test.* TO 'Azundris12345678'@'localhost' IDENTIFIED BY 'test123'; + +FLUSH PRIVILEGES; + +--replace_result $MASTER_MYSOCK MASTER_SOCKET $MASTER_MYPORT MASTER_PORT +connect (con1,localhost,Azundris123456789,test123,test); +disconnect con1; + +connection default; + +DROP USER 'Azundris12345678'@'localhost'; + +FLUSH PRIVILEGES; + +--echo # +--echo # -- End of Bug#49752 +--echo # + --echo # ------------------------------------------------------------------ --echo # -- End of 5.1 tests --echo # ------------------------------------------------------------------ @@ -352,6 +377,19 @@ connection pcon4; select user(), current_user(); disconnect pcon4; +# +# lpbug#683112 Maria 5.2 incorrectly reports "(using password: NO)" +# even when password is specified +# +# test "access denied" error for nonexisting user with and without a password +# +--replace_result $MASTER_MYSOCK MASTER_SOCKET $MASTER_MYPORT MASTER_PORT +--error ER_ACCESS_DENIED_ERROR +connect(pcon5,localhost,mysqltest_nouser,newpw,,$MASTER_MYPORT,); +--replace_result $MASTER_MYSOCK MASTER_SOCKET $MASTER_MYPORT MASTER_PORT +--error ER_ACCESS_DENIED_ERROR +connect(pcon5,localhost,mysqltest_nouser,,,$MASTER_MYPORT,); + connection default; DROP USER mysqltest_up1@'%'; DROP USER mysqltest_up2@'%'; diff --git a/mysql-test/t/create.test b/mysql-test/t/create.test index 4467de9a278..3545d190f06 100644 --- a/mysql-test/t/create.test +++ b/mysql-test/t/create.test @@ -1558,6 +1558,31 @@ drop table t1,t2,t3; --echo --echo # -- End of Bug#45829 +# +--echo # new table creation/renaming blocked if old encoded table present +# +let $MYSQLD_DATADIR= `select @@datadir`; +create table `t-1` (a int) engine=myisam; +insert into `t-1` values (1); +show tables; +flush tables; +--echo convert table files in mysql 5.0 file name encoding +--copy_file $MYSQLD_DATADIR/test/t@002d1.MYD $MYSQLD_DATADIR/test/t-1.MYD +--copy_file $MYSQLD_DATADIR/test/t@002d1.MYI $MYSQLD_DATADIR/test/t-1.MYI +--copy_file $MYSQLD_DATADIR/test/t@002d1.frm $MYSQLD_DATADIR/test/t-1.frm +--remove_file $MYSQLD_DATADIR/test/t@002d1.MYD +--remove_file $MYSQLD_DATADIR/test/t@002d1.MYI +--remove_file $MYSQLD_DATADIR/test/t@002d1.frm +show tables; +--error ER_TABLE_EXISTS_ERROR +create table `t-1` (a int); +create table t1 (a int); +--error ER_TABLE_EXISTS_ERROR +alter table t1 rename `t-1`; +--error ER_TABLE_EXISTS_ERROR +rename table t1 to `t-1`; +drop table `#mysql50#t-1`, t1; + --echo --echo End of 5.1 tests @@ -1743,7 +1768,7 @@ INSERT INTO t1 VALUES (1), (1); INSERT INTO t2 VALUES (2), (2); CREATE VIEW v1 AS SELECT id FROM t2; -CREATE TABLE IF NOT EXISTS v1(a int, b int) SELECT id, id FROM t1; +CREATE TABLE IF NOT EXISTS v1(a int, b int) SELECT id, id as di FROM t1; SHOW CREATE TABLE v1; SELECT * FROM t2; SELECT * FROM v1; diff --git a/mysql-test/t/csv.test b/mysql-test/t/csv.test index 028b6453a04..148964d8d96 100644 --- a/mysql-test/t/csv.test +++ b/mysql-test/t/csv.test @@ -4,6 +4,9 @@ --source include/have_csv.inc +call mtr.add_suppression("Table 'test_repair_table2' is marked as crashed and should be repaired"); +call mtr.add_suppression("Table 'test_repair_table4' is marked as crashed and should be repaired"); + # # Simple select test # diff --git a/mysql-test/t/ctype_cp932_binlog_stm.test b/mysql-test/t/ctype_cp932_binlog_stm.test index c36dcf4dc2d..6140178c0f4 100644 --- a/mysql-test/t/ctype_cp932_binlog_stm.test +++ b/mysql-test/t/ctype_cp932_binlog_stm.test @@ -35,8 +35,13 @@ delimiter ;| # # #28436: Incorrect position in SHOW BINLOG EVENTS causes server coredump +# Note: 364 is a magic position (found experimentally, depends on +# the log's contents) that caused the server crash. + +call mtr.add_suppression("Error in Log_event::read_log_event\\\(\\\): 'Found invalid"); + --error 1220 -SHOW BINLOG EVENTS FROM 490; +SHOW BINLOG EVENTS FROM 504; --echo Bug#44352 UPPER/LOWER function doesn't work correctly on cp932 and sjis environment. CREATE TABLE t1 (a varchar(16)) character set cp932; diff --git a/mysql-test/t/date_formats.test b/mysql-test/t/date_formats.test index 669a66bc6c5..7e6990f4754 100644 --- a/mysql-test/t/date_formats.test +++ b/mysql-test/t/date_formats.test @@ -123,12 +123,9 @@ ORDER BY variable_name; # Test of str_to_date # -# PS doesn't support fractions of a second ---disable_ps_protocol select str_to_date(concat('15-01-2001',' 2:59:58.999'), concat('%d-%m-%Y',' ','%H:%i:%s.%f')); select STR_TO_DATE('2004.12.12 22.30.61','%Y.%m.%d %T'); ---enable_ps_protocol create table t1 (date char(30), format char(30) not null); insert into t1 values @@ -164,8 +161,6 @@ insert into t1 values ('15-01-20', '%d-%m-%y'), ('15-2001-1', '%d-%Y-%c'); -# PS doesn't support fractional seconds ---disable_ps_protocol select date,format,str_to_date(date, format) as str_to_date from t1; # Use as a string select date,format,concat('',str_to_date(date, format)) as con from t1; @@ -212,7 +207,6 @@ select date,format,str_to_date(date, format) as str_to_date from t1; select date,format,concat(str_to_date(date, format),'') as con from t1; drop table t1; ---enable_ps_protocol # # Test of get_format diff --git a/mysql-test/t/deprecated_features.test b/mysql-test/t/deprecated_features.test index 002f4ad1122..a9c5a5ae5ff 100644 --- a/mysql-test/t/deprecated_features.test +++ b/mysql-test/t/deprecated_features.test @@ -17,8 +17,6 @@ load data from master; --error ER_PARSE_ERROR SHOW INNODB STATUS; --error ER_PARSE_ERROR -create table t1 (t6 timestamp(6)); ---error ER_PARSE_ERROR create table t1 (t6 timestamp) type=myisam; --error ER_PARSE_ERROR show table types; diff --git a/mysql-test/t/derived.test b/mysql-test/t/derived.test index a2681b82d26..6cc3db739f6 100644 --- a/mysql-test/t/derived.test +++ b/mysql-test/t/derived.test @@ -332,8 +332,9 @@ CREATE algorithm=temptable VIEW v1 AS CREATE algorithm=temptable VIEW v2 AS SELECT 1 FROM t2; # This caused the assert to be triggered. ---error ER_SUBQUERY_NO_1_ROW EXPLAIN SELECT 1 FROM t1 JOIN v1 ON 1 > (SELECT 1 FROM v2); +--error ER_SUBQUERY_NO_1_ROW +SELECT 1 FROM t1 JOIN v1 ON 1 > (SELECT 1 FROM v2); DROP TABLE t1, t2; DROP VIEW v1, v2; diff --git a/mysql-test/t/derived_opt.test b/mysql-test/t/derived_opt.test new file mode 100644 index 00000000000..42f3ce296e1 --- /dev/null +++ b/mysql-test/t/derived_opt.test @@ -0,0 +1,206 @@ +# Initialize +--disable_warnings +drop table if exists t1,t2,t3; +--enable_warnings + +set @exit_optimizer_switch=@@optimizer_switch; +set optimizer_switch='derived_merge=on,derived_with_keys=on'; +# The 'default' value within the scope of this test: +set @save_optimizer_switch=@@optimizer_switch; + +CREATE TABLE t1 (a int not null, b char (10) not null); +insert into t1 values(1,'a'),(2,'b'),(3,'c'),(3,'c'); +CREATE TABLE t2 (a int not null, b char (10) not null); +insert into t2 values (3,'c'),(4,'d'),(5,'f'),(6,'e'); +CREATE TABLE t3 (a int not null, b char (10) not null); +insert into t3 values (3,'f'),(4,'y'),(5,'z'),(6,'c'); +select * from t1 as x1, (select * from t1) as x2; +explain select * from t1 as x1, (select * from t1) as x2; +drop table if exists t2,t3; + +CREATE TABLE t2 (a int not null); +insert into t2 values(1); +select * from (select t1.*, t2.a as t2a from t1,t2 where t1.a=t2.a) t1; +explain select * from (select t1.*, t2.a as t2a from t1,t2 where t1.a=t2.a) t1; +drop table t1, t2; + +create table t1(a int not null, t char(8), index(a)); +--disable_query_log +begin; +let $1 = 10000; +while ($1) + { + eval insert into t1 values ($1,'$1'); + dec $1; + } +commit; +--enable_query_log +SELECT * FROM (SELECT * FROM t1) as b ORDER BY a ASC LIMIT 0,20; +explain select count(*) from t1 as tt1, (select * from t1) as tt2; +drop table t1; + +# +# test->used_keys test for derived tables +# +create table t1 (mat_id MEDIUMINT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY, matintnum CHAR(6) NOT NULL, test MEDIUMINT UNSIGNED NULL); +create table t2 (mat_id MEDIUMINT UNSIGNED NOT NULL, pla_id MEDIUMINT UNSIGNED NOT NULL); +insert into t1 values (NULL, 'a', 1), (NULL, 'b', 2), (NULL, 'c', 3), (NULL, 'd', 4), (NULL, 'e', 5), (NULL, 'f', 6), (NULL, 'g', 7), (NULL, 'h', 8), (NULL, 'i', 9); +insert into t2 values (1, 100), (1, 101), (1, 102), (2, 100), (2, 103), (2, 104), (3, 101), (3, 102), (3, 105); + +SELECT STRAIGHT_JOIN d.pla_id, m2.mat_id FROM t1 m2 INNER JOIN (SELECT mp.pla_id, MIN(m1.matintnum) AS matintnum FROM t2 mp INNER JOIN t1 m1 ON mp.mat_id=m1.mat_id GROUP BY mp.pla_id) d ON d.matintnum=m2.matintnum; +SELECT STRAIGHT_JOIN d.pla_id, m2.test FROM t1 m2 INNER JOIN (SELECT mp.pla_id, MIN(m1.matintnum) AS matintnum FROM t2 mp INNER JOIN t1 m1 ON mp.mat_id=m1.mat_id GROUP BY mp.pla_id) d ON d.matintnum=m2.matintnum; + +explain SELECT STRAIGHT_JOIN d.pla_id, m2.mat_id FROM t1 m2 INNER JOIN (SELECT mp.pla_id, MIN(m1.matintnum) AS matintnum FROM t2 mp INNER JOIN t1 m1 ON mp.mat_id=m1.mat_id GROUP BY mp.pla_id) d ON d.matintnum=m2.matintnum; +explain SELECT STRAIGHT_JOIN d.pla_id, m2.test FROM t1 m2 INNER JOIN (SELECT mp.pla_id, MIN(m1.matintnum) AS matintnum FROM t2 mp INNER JOIN t1 m1 ON mp.mat_id=m1.mat_id GROUP BY mp.pla_id) d ON d.matintnum=m2.matintnum; +drop table t1,t2; + +# +# deived tables with subquery inside all by one table +# +create table t1 (E1 INTEGER UNSIGNED NOT NULL, E2 INTEGER UNSIGNED NOT NULL, E3 INTEGER UNSIGNED NOT NULL, PRIMARY KEY(E1) +); +insert into t1 VALUES(1,1,1), (2,2,1); +select count(*) from t1 INNER JOIN (SELECT A.E1, A.E2, A.E3 FROM t1 AS A WHERE A.E3 = (SELECT MAX(B.E3) FROM t1 AS B WHERE A.E2 = B.E2)) AS THEMAX ON t1.E1 = THEMAX.E2 AND t1.E1 = t1.E2; +explain select count(*) from t1 INNER JOIN (SELECT A.E1, A.E2, A.E3 FROM t1 AS A WHERE A.E3 = (SELECT MAX(B.E3) FROM t1 AS B WHERE A.E2 = B.E2)) AS THEMAX ON t1.E1 = THEMAX.E2 AND t1.E1 = t1.E2; +drop table t1; + +create table t1 (a int); +insert into t1 values (1),(2); +select * from ( select * from t1 union select * from t1) a,(select * from t1 union select * from t1) b; +explain select * from ( select * from t1 union select * from t1) a,(select * from t1 union select * from t1) b; +drop table t1; + +# +# "Using index" in explain +# +create table t2 (a int, b int, primary key (a)); +insert into t2 values (1,7),(2,7); +explain select a from t2 where a>1; +explain select a from (select a from t2 where a>1) tt; +drop table t2; + +# +# prepared EXPLAIN +# +create table t1 +( + c1 tinyint, c2 smallint, c3 mediumint, c4 int, + c5 integer, c6 bigint, c7 float, c8 double, + c9 double precision, c10 real, c11 decimal(7, 4), c12 numeric(8, 4), + c13 date, c14 datetime, c15 timestamp, c16 time, + c17 year, c18 bit, c19 bool, c20 char, + c21 char(10), c22 varchar(30), c23 tinyblob, c24 tinytext, + c25 blob, c26 text, c27 mediumblob, c28 mediumtext, + c29 longblob, c30 longtext, c31 enum('one', 'two', 'three'), + c32 set('monday', 'tuesday', 'wednesday') +) engine = MYISAM ; +create table t2 like t1; + +set @save_optimizer_switch=@@optimizer_switch; +set @@optimizer_switch="partial_match_rowid_merge=off,partial_match_table_scan=off"; + +set @stmt= ' explain SELECT (SELECT SUM(c1 + c12 + 0.0) FROM t2 where (t1.c2 - 0e-3) = t2.c2 GROUP BY t1.c15 LIMIT 1) as scalar_s, exists (select 1.0e+0 from t2 where t2.c3 * 9.0000000000 = t1.c4) as exists_s, c5 * 4 in (select c6 + 0.3e+1 from t2) as in_s, (c7 - 4, c8 - 4) in (select c9 + 4.0, c10 + 40e-1 from t2) as in_row_s FROM t1, (select c25 x, c32 y from t2) tt WHERE x * 1 = c25 ' ; +prepare stmt1 from @stmt ; +execute stmt1 ; +execute stmt1 ; +explain SELECT (SELECT SUM(c1 + c12 + 0.0) FROM t2 where (t1.c2 - 0e-3) = t2.c2 GROUP BY t1.c15 LIMIT 1) as scalar_s, exists (select 1.0e+0 from t2 where t2.c3 * 9.0000000000 = t1.c4) as exists_s, c5 * 4 in (select c6 + 0.3e+1 from t2) as in_s, (c7 - 4, c8 - 4) in (select c9 + 4.0, c10 + 40e-1 from t2) as in_row_s FROM t1, (select c25 x, c32 y from t2) tt WHERE x * 1 = c25; +deallocate prepare stmt1; +drop tables t1,t2; + +set @@optimizer_switch=@save_optimizer_switch; + +--echo # +--echo # LP bug #793436: query with a derived table for which optimizer proves +--echo # that it contains not more than 1 row +--echo # + +CREATE TABLE t1 (a int, KEY (a)) ; +INSERT INTO t1 VALUES (3), (1); +CREATE TABLE t2 (a int); +INSERT INTO t2 VALUES (3); + +EXPLAIN +SELECT * FROM (SELECT DISTINCT * FROM t2) t, t1 WHERE t1.a = t.a; +SELECT * FROM (SELECT DISTINCT * FROM t2) t, t1 WHERE t1.a = t.a; + +DROP TABLE t1,t2; + +--echo # +--echo # LP bug #800518: crash with a query over a derived table +--echo # when a min/max optimization is applied +--echo # + +CREATE TABLE t1 (a int, b int, c varchar(10), INDEX idx(a,b)) ; +INSERT INTO t1 VALUES + (100, 3, 'xxx'), (200, 7, 'yyyyyyy'), (100, 1, 't'), + (200, 4, 'aaaa'), (100, 3, 'eee'), (100, 5, 'zzzzz'); + +EXPLAIN +SELECT MAX(b) FROM (SELECT * FROM t1) AS t WHERE a = 100; +SELECT MAX(b) FROM (SELECT * FROM t1) AS t WHERE a = 100; + +DROP TABLE t1; + +--echo # +--echo # LP bug #799499: query over a materialized view +--echo # accessed by a key +--echo # + +CREATE TABLE t1 (a int) ; +INSERT INTO t1 VALUES (8); + +CREATE TABLE t2 (a int, b int) ; +INSERT INTO t2 VALUES + (262, NULL), (253, 190), (260, NULL), (250, 163), (188, 8), + (257,200), (256, NULL), (255, 8), (249, NULL), (259, 7); + +CREATE VIEW v1 AS SELECT a, MIN(b) AS b FROM t2 GROUP BY a; + +EXPLAIN +SELECT * FROM v1, t1 WHERE v1.b=t1.a ORDER BY v1.a; +SELECT * FROM v1, t1 WHERE v1.b=t1.a ORDER BY v1.a; + +DROP VIEW v1; +DROP TABLE t1,t2; + +--echo # +--echo # LP bug #800085: crash with a query using a simple derived table +--echo # (fixed by the patch for bug 798621) +--echo # + +CREATE TABLE t1 (f1 int, f2 varchar(32)) ; +INSERT INTO t1 VALUES (NULL,'j'), (8,'c'); + +CREATE TABLE t2 (f1 int); +INSERT INTO t2 VALUES (1), (5); + +SELECT DISTINCT t.f1 FROM (SELECT * FROM t1) AS t, t2 + WHERE t.f2='s' AND t.f2 LIKE '%a%' OR t.f1<>0 ORDER BY t.f2; + +DROP TABLE t1, t2; + +--echo # +--echo # BUG##806524: Assertion `join->best_read < 1.7976931348623157e+308 with table_elimination=on and derived_merge=on +--echo # +CREATE TABLE t1 ( f4 int) ; +CREATE TABLE t2 ( f4 int) ; +CREATE TABLE t3 ( f1 int NOT NULL , PRIMARY KEY (f1)) ; +CREATE TABLE t4 ( f2 int, f4 int) ; + +SELECT * +FROM ( SELECT * FROM t1 ) AS alias1 +RIGHT JOIN ( + t2 AS alias2 + LEFT JOIN ( + SELECT t4.* + FROM ( SELECT * FROM t3 ) AS SQ1_alias1 + RIGHT JOIN t4 + ON t4.f2 = SQ1_alias1.f1 + ) AS alias3 + ON alias3.f4 != 0 +) ON alias3.f4 != 0; + +drop table t1,t2,t3,t4; + +# The following command must be the last one the file +set optimizer_switch=@exit_optimizer_switch; diff --git a/mysql-test/t/derived_view.test b/mysql-test/t/derived_view.test new file mode 100644 index 00000000000..72719ec9786 --- /dev/null +++ b/mysql-test/t/derived_view.test @@ -0,0 +1,787 @@ +--disable_warnings +drop table if exists t1,t2; +drop view if exists v1,v2,v3,v4; +--enable_warnings + +set @exit_optimizer_switch=@@optimizer_switch; +set optimizer_switch='derived_merge=on,derived_with_keys=on'; +# The 'default' value within the scope of this test: +set @save_optimizer_switch=@@optimizer_switch; + +create table t1(f1 int, f11 int); +create table t2(f2 int, f22 int); +insert into t1 values(1,1),(2,2),(3,3),(5,5),(9,9),(7,7); +insert into t1 values(17,17),(13,13),(11,11),(15,15),(19,19); +insert into t2 values(1,1),(3,3),(2,2),(4,4),(8,8),(6,6); +insert into t2 values(12,12),(14,14),(10,10),(18,18),(16,16); + +--echo Tests: + +--echo for merged derived tables +--echo explain for simple derived +explain select * from (select * from t1) tt; +select * from (select * from t1) tt; +--echo explain for multitable derived +explain extended select * from (select * from t1 join t2 on f1=f2) tt; +select * from (select * from t1 join t2 on f1=f2) tt; +--echo explain for derived with where +explain extended + select * from (select * from t1 where f1 in (2,3)) tt where f11=2; +select * from (select * from t1 where f1 in (2,3)) tt where f11=2; +--echo join of derived +explain extended + select * from (select * from t1 where f1 in (2,3)) tt join + (select * from t1 where f1 in (1,2)) aa on tt.f1=aa.f1; +select * from (select * from t1 where f1 in (2,3)) tt join + (select * from t1 where f1 in (1,2)) aa on tt.f1=aa.f1; + +flush status; +explain extended + select * from (select * from t1 where f1 in (2,3)) tt where f11=2; +show status like 'Handler_read%'; +flush status; +select * from (select * from t1 where f1 in (2,3)) tt where f11=2; +show status like 'Handler_read%'; + +--echo for merged views +create view v1 as select * from t1; +create view v2 as select * from t1 join t2 on f1=f2; +create view v3 as select * from t1 where f1 in (2,3); +create view v4 as select * from t2 where f2 in (2,3); +--echo explain for simple views +explain extended select * from v1; +select * from v1; +--echo explain for multitable views +explain extended select * from v2; +select * from v2; +--echo explain for views with where +explain extended select * from v3 where f11 in (1,3); +select * from v3 where f11 in (1,3); +--echo explain for joined views +explain extended + select * from v3 join v4 on f1=f2; +select * from v3 join v4 on f1=f2; + +flush status; +explain extended select * from v4 where f2 in (1,3); +show status like 'Handler_read%'; +flush status; +select * from v4 where f2 in (1,3); +show status like 'Handler_read%'; + +--echo for materialized derived tables +--echo explain for simple derived +explain extended select * from (select * from t1 group by f1) tt; +select * from (select * from t1 having f1=f1) tt; +--echo explain showing created indexes +explain extended + select * from t1 join (select * from t2 group by f2) tt on f1=f2; +select * from t1 join (select * from t2 group by f2) tt on f1=f2; +--echo explain showing late materialization +flush status; +explain select * from t1 join (select * from t2 group by f2) tt on f1=f2; +show status like 'Handler_read%'; +flush status; +select * from t1 join (select * from t2 group by f2) tt on f1=f2; +show status like 'Handler_read%'; + +--echo for materialized views +drop view v1,v2,v3; +create view v1 as select * from t1 group by f1; +create view v2 as select * from t2 group by f2; +create view v3 as select t1.f1,t1.f11 from t1 join t1 as t11 where t1.f1=t11.f1 + having t1.f1<100; +--echo explain for simple derived +explain extended select * from v1; +select * from v1; +--echo explain showing created indexes +explain extended select * from t1 join v2 on f1=f2; +select * from t1 join v2 on f1=f2; +explain extended + select * from t1,v3 as v31,v3 where t1.f1=v31.f1 and t1.f1=v3.f1; +flush status; +select * from t1,v3 as v31,v3 where t1.f1=v31.f1 and t1.f1=v3.f1; +show status like 'Handler_read%'; +--echo explain showing late materialization +flush status; +explain select * from t1 join v2 on f1=f2; +show status like 'Handler_read%'; +flush status; +select * from t1 join v2 on f1=f2; +show status like 'Handler_read%'; + +explain extended select * from v1 join v4 on f1=f2; +select * from v1 join v4 on f1=f2; + +--echo merged derived in merged derived +explain extended select * from (select * from + (select * from t1 where f1 < 7) tt where f1 > 2) zz; +select * from (select * from + (select * from t1 where f1 < 7) tt where f1 > 2) zz; + +--echo materialized derived in merged derived +explain extended select * from (select * from + (select * from t1 where f1 < 7 group by f1) tt where f1 > 2) zz; +select * from (select * from + (select * from t1 where f1 < 7 group by f1) tt where f1 > 2) zz; + +--echo merged derived in materialized derived +explain extended select * from (select * from + (select * from t1 where f1 < 7) tt where f1 > 2 group by f1) zz; +select * from (select * from + (select * from t1 where f1 < 7) tt where f1 > 2 group by f1) zz; + +--echo materialized derived in materialized derived +explain extended select * from (select * from + (select * from t1 where f1 < 7 group by f1) tt where f1 > 2 group by f1) zz; +select * from (select * from + (select * from t1 where f1 < 7 group by f1) tt where f1 > 2 group by f1) zz; + +--echo mat in merged derived join mat in merged derived +explain extended select * from + (select * from (select * from t1 where f1 < 7 group by f1) tt where f1 > 2) x +join + (select * from (select * from t1 where f1 < 7 group by f1) tt where f1 > 2) z + on x.f1 = z.f1; + +flush status; +select * from + (select * from (select * from t1 where f1 < 7 group by f1) tt where f1 > 2) x +join + (select * from (select * from t1 where f1 < 7 group by f1) tt where f1 > 2) z + on x.f1 = z.f1; +show status like 'Handler_read%'; +flush status; + +--echo merged in merged derived join merged in merged derived +explain extended select * from + (select * from + (select * from t1 where f1 < 7 ) tt where f1 > 2 ) x +join + (select * from + (select * from t1 where f1 < 7 ) tt where f1 > 2 ) z + on x.f1 = z.f1; + +select * from + (select * from + (select * from t1 where f1 < 7 ) tt where f1 > 2 ) x +join + (select * from + (select * from t1 where f1 < 7 ) tt where f1 > 2 ) z + on x.f1 = z.f1; + +--echo materialized in materialized derived join +--echo materialized in materialized derived +explain extended select * from + (select * from + (select * from t1 where f1 < 7 group by f1) tt where f1 > 2 group by f1) x +join + (select * from + (select * from t1 where f1 < 7 group by f1) tt where f1 > 2 group by f1) z + on x.f1 = z.f1; + +select * from + (select * from + (select * from t1 where f1 < 7 group by f1) tt where f1 > 2 group by f1) x +join + (select * from + (select * from t1 where f1 < 7 group by f1) tt where f1 > 2 group by f1) z + on x.f1 = z.f1; + +--echo merged view in materialized derived +explain extended +select * from (select * from v4 group by 1) tt; +select * from (select * from v4 group by 1) tt; + +--echo materialized view in merged derived +explain extended +select * from ( select * from v1 where f1 < 7) tt; +select * from ( select * from v1 where f1 < 7) tt; + +--echo merged view in a merged view in a merged derived +create view v6 as select * from v4 where f2 < 7; +explain extended select * from (select * from v6) tt; +select * from (select * from v6) tt; + +--echo materialized view in a merged view in a materialized derived +create view v7 as select * from v1; +explain extended select * from (select * from v7 group by 1) tt; +select * from (select * from v7 group by 1) tt; + +--echo join of above two +explain extended select * from v6 join v7 on f2=f1; +select * from v6 join v7 on f2=f1; + +--echo test two keys +explain select * from t1 join (select * from t2 group by f2) tt on t1.f1=tt.f2 join t1 xx on tt.f22=xx.f1; +select * from t1 join (select * from t2 group by f2) tt on t1.f1=tt.f2 join t1 xx on tt.f22=xx.f1; + + +--echo TODO: Add test with 64 tables mergeable view to test fall back to +--echo materialization on tables > MAX_TABLES merge +drop table t1,t2; +drop view v1,v2,v3,v4,v6,v7; + +--echo # +--echo # LP bug #794909: crash when defining possible keys for +--echo # a materialized view/derived_table +--echo # + +CREATE TABLE t1 (f1 int) ; +INSERT INTO t1 VALUES (149), (150), (224), (29); + +CREATE TABLE t2 (f1 int, KEY (f1)); +INSERT INTO t2 VALUES (149), (NULL), (224); + +CREATE ALGORITHM=TEMPTABLE VIEW v1 AS SELECT * FROM t1; + +EXPLAIN +SELECT * FROM v1 JOIN t2 ON v1.f1 = t2.f1; +SELECT * FROM v1 JOIN t2 ON v1.f1 = t2.f1; + +DROP VIEW v1; +DROP TABLE t1,t2; + +--echo # +--echo # LP bug #794890: abort failure on multi-update with view +--echo # + +CREATE TABLE t1 (a int); +INSERT INTO t1 VALUES (20), (7); +CREATE TABLE t2 (a int); +INSERT INTO t2 VALUES (7), (9), (7); + +CREATE ALGORITHM=TEMPTABLE VIEW v1 AS SELECT a FROM t1; + +CREATE VIEW v2 AS SELECT t2.a FROM t2, v1 WHERE t2.a=t2.a; +UPDATE v2 SET a = 2; +SELECT * FROM t2; + +UPDATE t1,v2 SET t1.a = 3; +SELECT * FROM t1; + +DELETE t1 FROM t1,v2; +SELECT * FROM t1; + +DROP VIEW v1,v2; +DROP TABLE t1,t2; + +--echo # +--echo # LP bug #802023: MIN/MAX optimization +--echo # for mergeable derived tables and views +--echo # + +CREATE TABLE t1 (a int, b int, c varchar(32), INDEX idx(a,b)); +INSERT INTO t1 VALUES + (7, 74, 'yyyyyyy'), (9, 97, 'aaaaaaaaa'), (2, 23, 'tt'), + (5, 55, 'ddddd'), (2, 27, 'ss'), (7, 76, 'xxxxxxx'), + (7, 79, 'zzzzzzz'), (9, 92, 'bbbbbbbbb'), (2, 25, 'pp'), + (5, 53, 'eeeee'), (2, 23, 'qq'), (7, 76,'wwwwwww'), + (7, 74, 'uuuuuuu'), (9, 92, 'ccccccccc'), (2, 25, 'oo'); + +CREATE VIEW v1 AS SELECT * FROM t1; + +SELECT MIN(a) FROM t1 WHERE a >= 5; +EXPLAIN +SELECT MIN(a) FROM t1 WHERE a >= 5; + +SELECT MIN(a) FROM (SELECT * FROM t1) t WHERE a >= 5; +EXPLAIN +SELECT MIN(a) FROM(SELECT * FROM t1) t WHERE a >= 5; + +SELECT MIN(a) FROM v1 WHERE a >= 5; +EXPLAIN +SELECT MIN(a) FROM v1 WHERE a >= 5; + +SELECT MAX(b) FROM t1 WHERE a=7 AND b<75; +EXPLAIN +SELECT MAX(b) FROM t1 WHERE a=7 AND b<75; + +SELECT MAX(b) FROM (SELECT * FROM t1) t WHERE a=7 AND b<75; +EXPLAIN +SELECT MAX(b) FROM (SELECT * FROM t1) t WHERE a=7 AND b<75; + +SELECT MAX(b) FROM v1 WHERE a=7 AND b<75; +EXPLAIN +SELECT MAX(b) FROM v1 WHERE a=7 AND b<75; + +DROP VIEW v1; +DROP TABLE t1; + + +--echo # +--echo # LP bug #800535: GROUP BY query with nested left join +--echo # and a derived table in the nest +--echo # + +CREATE TABLE t1 (a int) ; +INSERT INTO t1 VALUES (1), (2); + +CREATE TABLE t2 (a int NOT NULL); +INSERT INTO t2 VALUES (1), (2); + +CREATE TABLE t3 (a int, b int); +INSERT INTO t3 VALUES (3,3), (4,4); + +EXPLAIN EXTENDED +SELECT t.a FROM t1 LEFT JOIN + (t2 t JOIN t3 ON t3.b > 5) ON t.a >= 1 + GROUP BY t.a; +SELECT t.a FROM t1 LEFT JOIN + (t2 t JOIN t3 ON t3.b > 5) ON t.a >= 1 + GROUP BY t.a; + +EXPLAIN EXTENDED +SELECT t.a FROM t1 LEFT JOIN + (( SELECT * FROM t2 ) t JOIN t3 ON t3.b > 5) ON t.a >= 1 + GROUP BY t.a; +SELECT t.a FROM t1 LEFT JOIN + (( SELECT * FROM t2 ) t JOIN t3 ON t3.b > 5) ON t.a >= 1 + GROUP BY t.a; + +CREATE VIEW v1 AS SELECT * FROM t2; + +EXPLAIN EXTENDED +SELECT t.a FROM t1 LEFT JOIN + (v1 t JOIN t3 ON t3.b > 5) ON t.a >= 1 + GROUP BY t.a; +SELECT t.a FROM t1 LEFT JOIN + (v1 t JOIN t3 ON t3.b > 5) ON t.a >= 1 + GROUP BY t.a; + +DROP VIEW v1; +DROP TABLE t1,t2,t3; + +--echo # +--echo # LP bug #803410: materialized view/dt accessed by two-component key +--echo # + +CREATE TABLE t1 (a varchar(1)); +INSERT INTO t1 VALUES ('c'); + +CREATE TABLE t2 (a varchar(1) , KEY (a)) ; +INSERT INTO t2 VALUES ('c'), (NULL), ('r'); + +CREATE TABLE t3 (a varchar(1), b varchar(1)); +INSERT INTO t3 VALUES ('e', 'c'), ('c', 'c'), ('c', 'r'); + +CREATE VIEW v1 AS SELECT a, MIN(b) AS b FROM t3 GROUP BY a; + +EXPLAIN +SELECT * FROM t1, t2, v1 WHERE t2.a=t1.a AND t2.a=v1.a AND t2.a=v1.b; +SELECT * FROM t1, t2, v1 WHERE t2.a=t1.a AND t2.a=v1.a AND t2.a=v1.b; + +DROP VIEW v1; +DROP TABLE t1,t2,t3; + + +--echo # +--echo # LP bug #802845: select from derived table with limit 0 +--echo # + +SELECT * FROM (SELECT 1 LIMIT 0) t; + +CREATE TABLE t1 (a int); +INSERT INTO t1 VALUES (7), (1), (3); + +SELECT * FROM (SELECT * FROM t1 LIMIT 0) t; + +DROP TABLE t1; + +--echo # +--echo # LP bug #803851: materialized view + IN->EXISTS +--echo # + +SET SESSION optimizer_switch='semijoin=off,derived_with_keys=on'; + +CREATE TABLE t1 (a int, b int); +INSERT INTO t1 VALUES (2,2), (3,3), (1,1); + +CREATE TABLE t2 (a int); +INSERT INTO t2 VALUES (1), (2), (1); + +CREATE TABLE t3 (a int); +INSERT INTO t3 VALUES (3), (1), (2), (1); + +CREATE VIEW v1 AS SELECT a, MAX(b) AS b FROM t1 GROUP BY a; + +EXPLAIN EXTENDED +SELECT * FROM t3 + WHERE t3.a IN (SELECT v1.a FROM v1, t2 WHERE t2.a = v1.b); +SELECT * FROM t3 + WHERE t3.a IN (SELECT v1.a FROM v1, t2 WHERE t2.a = v1.b); + +SET SESSION optimizer_switch=@save_optimizer_switch; + +DROP VIEW v1; +DROP TABLE t1,t2,t3; + +--echo # +--echo # LP bug #804515: materialized derived + ORDER BY +--echo # + +CREATE TABLE t1 (f1 varchar(1), f2 varchar(1), KEY (f2)); +INSERT INTO t1 VALUES + ('r','x'), ('x','d'), ('x','r'), ('r','f'), ('x','x'); + +CREATE TABLE t2 (f1 varchar(1), f2 varchar(1)); +INSERT INTO t2 VALUES ('s','x'); + +CREATE TABLE t3 (f1 varchar(1), f2 varchar(1), KEY (f2)); +INSERT INTO t3 VALUES + (NULL,'x'), (NULL,'f'), ('t','p'), (NULL,'j'), ('g','c'); + +CREATE TABLE t4 (f1 int, f2 varchar(1), KEY (f2,f1)) ; +INSERT INTO t4 VALUES (1,'x'), (5,'r'); + +EXPLAIN +SELECT t.f1 AS f + FROM (SELECT DISTINCT t1.* FROM t1,t2 WHERE t2.f2 = t1.f2) t,t3,t4 + WHERE t4.f2 = t3.f2 AND t4.f2 = t.f1 ORDER BY f; +SELECT t.f1 AS f + FROM (SELECT DISTINCT t1.* FROM t1,t2 WHERE t2.f2 = t1.f2) t,t3,t4 + WHERE t4.f2 = t3.f2 AND t4.f2 = t.f1 ORDER BY f; + +DROP TABLE t1,t2,t3,t4; + +--echo # +--echo # LP bug #806431: join over materialized derived with key +--echo # + +CREATE TABLE t1 (a int, b int); +INSERT INTO t1 VALUES (0,0),(3,0),(1,0); + +CREATE ALGORITHM=TEMPTABLE VIEW v1 AS SELECT a,b FROM t1 ; + +SET SESSION optimizer_switch='derived_with_keys=off'; +SELECT * FROM t1 AS t JOIN v1 AS v WHERE t.a = v.b AND t.b = v.b; +SET SESSION optimizer_switch='derived_with_keys=on'; +EXPLAIN +SELECT * FROM t1 AS t JOIN v1 AS v WHERE t.a = v.b AND t.b = v.b; +SELECT * FROM t1 AS t JOIN v1 AS v WHERE t.a = v.b AND t.b = v.b; + +SET SESSION optimizer_switch=@save_optimizer_switch; + +DROP VIEW v1; +DROP TABLE t1; + +--echo # +--echo # LP bug #806477: left join over merged join with +--echo # where condition containing f=f +--echo # + +CREATE TABLE t1 (a int NOT NULL); +INSERT INTO t1 VALUES (1), (50), (0); + +CREATE TABLE t2 (a int); + +CREATE TABLE t3 (a int, b int); +INSERT INTO t3 VALUES (76,2), (1,NULL); + +CREATE VIEW v1 AS SELECT * FROM t1; + +SELECT t3.b, v1.a + FROM t3 LEFT JOIN (t2, v1) ON t3.a <> 0 + WHERE v1.a = v1.a OR t3.b <> 0; +EXPLAIN EXTENDED +SELECT t3.b, v1.a + FROM t3 LEFT JOIN (t2, v1) ON t3.a <> 0 + WHERE v1.a = v1.a OR t3.b <> 0; + +DROP VIEW v1; +DROP TABLE t1,t2,t3; + +--echo # +--echo # LP bug #806510: subquery with outer reference +--echo # to a derived_table/view +--echo # + +CREATE TABLE t1 (a int) ; +INSERT INTO t1 VALUES (4), (NULL); + +CREATE TABLE t2 (a int) ; +INSERT INTO t2 VALUES (8), (0); + +CREATE TABLE t3 (a int, b int) ; +INSERT INTO t3 VALUES (7,8); + +CREATE VIEW v1 AS SELECT * FROM t1; + +SELECT * FROM t1 t + WHERE EXISTS (SELECT t3.a FROM t3, t2 + WHERE t2.a = t3.b AND t.a != 0); +EXPLAIN +SELECT * FROM t1 t + WHERE EXISTS (SELECT t3.a FROM t3, t2 + WHERE t2.a = t3.b AND t.a != 0); + +SELECT * FROM (SELECT * FROM t1) t + WHERE EXISTS (SELECT t3.a FROM t3, t2 + WHERE t2.a = t3.b AND t.a != 0); +EXPLAIN +SELECT * FROM (SELECT * FROM t1) t + WHERE EXISTS (SELECT t3.a FROM t3, t2 + WHERE t2.a = t3.b AND t.a != 0); + +SELECT * FROM v1 t + WHERE EXISTS (SELECT t3.a FROM t3, t2 + WHERE t2.a = t3.b AND t.a != 0); +EXPLAIN +SELECT * FROM v1 t + WHERE EXISTS (SELECT t3.a FROM t3, t2 + WHERE t2.a = t3.b AND t.a != 0); + +DROP VIEW v1; +DROP TABLE t1,t2,t3; + +--echo # +--echo # LP bug #806097: left join over a view + DISTINCT +--echo # + +CREATE TABLE t1 (a int, b int); +INSERT INTO t1 VALUES (252,6), (232,0), (174,232); + +CREATE TABLE t2 (a int); +INSERT INTO t2 VALUES (232), (174); + +CREATE TABLE t3 (c int); +INSERT INTO t3 VALUES (1), (2); + +CREATE VIEW v1 AS SELECT t2.a FROM t3,t2; + +SELECT v1.a FROM t1 LEFT JOIN v1 ON t1.b = 0; + +SELECT DISTINCT t2.a FROM t1 LEFT JOIN (t3,t2) ON t1.b = 0; +EXPLAIN +SELECT DISTINCT t2.a FROM t1 LEFT JOIN (t3,t2) ON t1.b = 0; + +SELECT DISTINCT v1.a FROM t1 LEFT JOIN v1 ON t1.b = 0; +EXPLAIN +SELECT DISTINCT v1.a FROM t1 LEFT JOIN v1 ON t1.b = 0; + +DROP VIEW v1; +DROP TABLE t1,t2,t3; + +--echo # +--echo # LP bug #806504: right join over a view/derived table +--echo # + +CREATE TABLE t1 (a int, b int) ; +INSERT INTO t1 VALUES (0,0); + +CREATE TABLE t2 (a int) ; +INSERT INTO t2 VALUES (0), (0); + +CREATE VIEW v1 AS SELECT * FROM t1; + +SELECT * FROM t2 RIGHT JOIN (SELECT * FROM t1) AS t ON t.a != 0 + WHERE t.a IN (SELECT b FROM t1); +EXPLAIN EXTENDED +SELECT * FROM t2 RIGHT JOIN (SELECT * FROM t1) AS t ON t.a != 0 + WHERE t.a IN (SELECT b FROM t1); + +SELECT * FROM t2 RIGHT JOIN v1 AS t ON t.a != 0 + WHERE t.a IN (SELECT b FROM t1); +EXPLAIN EXTENDED +SELECT * FROM t2 RIGHT JOIN v1 AS t ON t.a != 0 + WHERE t.a IN (SELECT b FROM t1); + +DROP VIEW v1; +DROP TABLE t1,t2; + +--echo # +--echo # LP bug #809206: DISTINCT in derived table / view +--echo # + +CREATE TABLE t1 (a int) ; +INSERT INTO t1 VALUES (0); + +CREATE TABLE t2 (a varchar(32), b int, KEY (a)) ; +INSERT INTO t2 VALUES + ('j',28), ('c',29), ('i',26), ('c',29), ('k',27), + ('j',28), ('c',29), ('i',25), ('d',26), ('k',27); + +CREATE TABLE t3 (a varchar(32)); +INSERT INTO t3 VALUES ('j'), ('c'); + +CREATE VIEW v1 AS SELECT DISTINCT t2.b FROM t1,t2,t3 WHERE t3.a = t2.a; + +SELECT DISTINCT t2.b FROM t1,t2,t3 WHERE t3.a = t2.a; +EXPLAIN +SELECT DISTINCT t2.b FROM t1,t2,t3 WHERE t3.a = t2.a; + +SELECT * FROM (SELECT DISTINCT t2.b FROM t1,t2,t3 WHERE t3.a = t2.a) t; +EXPLAIN +SELECT * FROM (SELECT DISTINCT t2.b FROM t1,t2,t3 WHERE t3.a = t2.a) t; + +SELECT * FROM v1; +EXPLAIN +SELECT * FROM v1; + +DROP VIEW v1; +DROP TABLE t1,t2,t3; + +--echo # +--echo # LP bug #809179: right join over a derived table / view +--echo # + +CREATE TABLE t1 (a int, b int); +INSERT INTO t1 VALUES (6,5); + +CREATE TABLE t2 (a int, b int); +INSERT INTO t2 VALUES (1,0); + +CREATE TABLE t3 (a int, b int); +INSERT INTO t3 VALUES (6,5); + +CREATE VIEW v1 AS SELECT * FROM t1; + +SELECT t.a,t.b FROM t3 RIGHT JOIN (t1 AS t, t2) ON t2.b != 0 + WHERE (t.a,t.b) NOT IN (SELECT 7, 5); +EXPLAIN EXTENDED +SELECT t.a,t.b FROM t3 RIGHT JOIN (t1 AS t, t2) ON t2.b != 0 + WHERE (t.a,t.b) NOT IN (SELECT 7, 5); + +SELECT t.a,t.b FROM t3 RIGHT JOIN ((SELECT * FROM t1) AS t, t2) ON t2.b != 0 + WHERE (t.a,t.b) NOT IN (SELECT 7, 5); +EXPLAIN EXTENDED +SELECT t.a,t.b FROM t3 RIGHT JOIN ((SELECT * FROM t1) AS t, t2) ON t2.b != 0 + WHERE (t.a,t.b) NOT IN (SELECT 7, 5); + +SELECT t.a,t.b FROM t3 RIGHT JOIN (v1 AS t, t2) ON t2.b != 0 + WHERE (t.a,t.b) NOT IN (SELECT 7, 5); +EXPLAIN EXTENDED +SELECT t.a,t.b FROM t3 RIGHT JOIN (v1 AS t, t2) ON t2.b != 0 + WHERE (t.a,t.b) NOT IN (SELECT 7, 5); + +DROP VIEW v1; +DROP TABLE t1,t2,t3; + +--echo # +--echo # LP bug #794901: insert into a multi-table view +--echo # + +CREATE TABLE t1 (a int); +CREATE TABLE t2 (a int); +CREATE TABLE t3 (a int); + +CREATE VIEW v1 AS SELECT t1.a FROM t1,t2; +CREATE VIEW v2 AS SELECT a FROM t2 GROUP BY a; +CREATE VIEW v3 AS SELECT v1.a FROM v1,v2; + +-- error ER_NON_INSERTABLE_TABLE +INSERT INTO v3(a) VALUES (1); + +DROP VIEW v1,v2,v3; +DROP TABLE t1,t2,t3; + +--echo # +--echo # LP bug #793448: materialized view accessed by two-component key +--echo # + +CREATE TABLE t1 (a int, b int); +INSERT INTO t1 VALUES (9,3), (2,5); + +CREATE TABLE t2 (a int, b int); +INSERT INTO t2 VALUES (9,3), (3,7), (9,1), (2,5), (2,4), (3,8); + +CREATE TABLE t3 (a int, b int); +INSERT INTO t3 VALUES (10,3), (9,7), (9,1), (2,4); + +CREATE VIEW v1(a,b) AS SELECT a, MAX(b) FROM t2 GROUP BY a; +CREATE VIEW v2(a,b) AS SELECT a,b FROM t2 UNION SELECT a,b FROM t3; + +SELECT * FROM v1; +SELECT a FROM t1 WHERE (a,b) IN (SELECT * FROM v1); +EXPLAIN +SELECT a FROM t1 WHERE (a,b) IN (SELECT * FROM v1); + +SELECT * FROM v2; +SELECT a FROM t1 WHERE (a,b) IN (SELECT * FROM v2); +EXPLAIN +SELECT a FROM t1 WHERE (a,b) IN (SELECT * FROM v2); + +DROP VIEW v1,v2; +DROP TABLE t1,t2,t3; + +--echo # +--echo # LP bug #804686: query over a derived table using a view +--echo # with a degenerated where condition +--echo # + +CREATE TABLE t1 (a int, b int); +INSERT INTO t1 VALUES (0,0), (1,0), (0,0), (1,1), (1,0); +CREATE VIEW v1 AS SELECT a,b FROM t1; +CREATE VIEW v2 AS SELECT a, MAX(b) AS b FROM t1 GROUP BY a; + +SELECT * FROM (SELECT b FROM v1 WHERE b = 0) t WHERE b<>0; +SELECT * FROM (SELECT b FROM v2 WHERE b = 0) t WHERE b<>0; +SELECT * FROM (SELECT b FROM v1 WHERE b = 0) t WHERE b; +SELECT * FROM (SELECT b FROM v2 WHERE b = 0) t WHERE b; +EXPLAIN EXTENDED +SELECT * FROM (SELECT b FROM v1 WHERE b = 0) t WHERE b; +EXPLAIN EXTENDED +SELECT * FROM (SELECT b FROM v2 WHERE b = 0) t WHERE b; + +DROP VIEW v1,v2; +DROP TABLE t1; + +--echo # +--echo # LP bug #819716: crash with embedded tableless materialized derived +--echo # with a variable +--echo # + +set optimizer_switch='derived_merge=off'; +EXPLAIN +SELECT * FROM (SELECT * FROM (SELECT @b) AS t) AS s; +SELECT * FROM (SELECT * FROM (SELECT @b) AS t) AS s; +set optimizer_switch='derived_merge=on'; + +--echo # +--echo # LP bug #823826: view over join + IS NULL in WHERE +--echo # + +CREATE TABLE t1 (a int) ; +INSERT INTO t1 VALUES (1), (1); + +CREATE TABLE t2 (b int) ; +INSERT INTO t2 VALUES (9), (NULL), (7); + +CREATE VIEW v1 AS SELECT * FROM t1,t2; + +EXPLAIN +SELECT * FROM (SELECT * FROM t1,t2) t WHERE b IS NULL; +SELECT * FROM (SELECT * FROM t1,t2) t WHERE b IS NULL; + +EXPLAIN +SELECT * FROM v1 WHERE b IS NULL; +SELECT * FROM v1 WHERE b IS NULL; + +DROP VIEW v1; +DROP TABLE t1,t2; + +--echo # +--echo # LP bug #823835: a duplicate of #823189 with derived table +--echo # + +CREATE TABLE t1 (a varchar(32)) ; +INSERT INTO t1 VALUES ('r'), ('p'); + +CREATE TABLE t2 (a int NOT NULL, b varchar(32)) ; +INSERT INTO t2 VALUES (28,'j'); + +CREATE TABLE t3 (a int); +INSERT INTO t3 VALUES (0), (0); + +EXPLAIN EXTENDED +SELECT * FROM (SELECT * FROM t1) AS t +WHERE EXISTS (SELECT t2.a FROM t3 RIGHT JOIN t2 ON (t3.a = t2.a) + WHERE t2.b < t.a); +SELECT * FROM (SELECT * FROM t1) AS t +WHERE EXISTS (SELECT t2.a FROM t3 RIGHT JOIN t2 ON (t3.a = t2.a) + WHERE t2.b < t.a); + +DROP TABLE t1,t2,t3; + +# The following command must be the last one the file +set optimizer_switch=@exit_optimizer_switch; diff --git a/mysql-test/t/disabled.def b/mysql-test/t/disabled.def index 52b23e62dcb..0bbb6bc29d3 100644 --- a/mysql-test/t/disabled.def +++ b/mysql-test/t/disabled.def @@ -9,8 +9,8 @@ # Do not use any TAB characters for whitespace. # ############################################################################## -main.events_time_zone : Test is not predictable as it depends on precise timing. -table_elim : sergeyp to reapply 2643.26.4 in Item_sum::update_used_tables +events_time_zone : Test is not predictable as it depends on precise timing. +table_elim : sergeyp to reapply 2643.26.4 in Item_sum::update_used_tables lowercase_table3 : Bug#11762269 2010-06-30 alik main.lowercase_table3 on Mac OSX read_many_rows_innodb : Bug#11748886 2010-11-15 mattiasj report already exists sum_distinct-big : Bug#11764126 2010-11-15 mattiasj was not tested @@ -19,4 +19,10 @@ create-big : Bug#11748731 2010-11-15 mattiasj was not tested archive-big : Bug#11817185 2011-03-10 Anitha Disabled since this leads to timeout on Solaris Sparc log_tables-big : Bug#11756699 2010-11-15 mattiasj report already exists mysql_embedded : Bug#12561297 2011-06-15 New test failing on all platforms -tablespace : disabled in MariaDB +tablespace : disabled in MariaDB (no TABLESPACE table attribute) +derived_view : SergeyP +subselect4 : SergeyP +subselect_mat : SergeyP +subselect_sj_mat : SergeyP +subselect_sj2_mat : SergeyP +subselect_sj_nonmerged : SergeyP diff --git a/mysql-test/t/distinct.test b/mysql-test/t/distinct.test index 84073d15109..a7eefad5ca5 100644 --- a/mysql-test/t/distinct.test +++ b/mysql-test/t/distinct.test @@ -615,6 +615,42 @@ SET @@max_heap_table_size = @old_max_heap_table_size; --echo End of 5.1 tests +# +# test_if_equality_guarantees_uniqueness() and dates +# +create table t1 (a varchar(100)); +insert t1 values ('2010-10-10'), ('20101010'); +select * from t1 where a = DATE('2010-10-10'); +select distinct a from t1 where a = DATE('2010-10-10'); +explain select distinct a from t1 where a = DATE('2010-10-10'); +drop table t1; +# +# test_if_equality_guarantees_uniqueness() and different type combinations +# +--echo # date = string +create table t1 (a date); +insert t1 values ('2010-10-10'), ('20101010'); +explain select distinct a from t1 where a = '2010-10-10'; +drop table t1; +--echo # double = string +create table t1 (a double); +insert t1 values (2), (2); +explain select distinct a from t1 where a = '2'; +--echo # double = int +explain select distinct a from t1 where a = 2; +--echo # string = double +alter table t1 modify a varchar(100); +explain select distinct a from t1 where a = 2e0; +drop table t1; + +# +# lp:731124 Loss of precision on DISTINCT +# +create table t1 (f1 varchar(40)); +insert into t1 values ('2010-10-10 00:00:00.0001'),('2010-10-10 00:00:00.0002'),('2010-10-10 00:00:00.0003'); +select time(f1) from t1 ; +select distinct time(f1) from t1 ; +drop table t1; --echo # --echo # Bug #11744875: 4082: integer lengths cause truncation with distinct concat and innodb @@ -625,5 +661,4 @@ INSERT INTO t1 VALUES (1111, 2222), (3333, 4444); SELECT DISTINCT CONCAT(a,b) AS c FROM t1 ORDER BY 1; DROP TABLE t1; - --echo End of 5.5 tests diff --git a/mysql-test/t/dyncol.test b/mysql-test/t/dyncol.test new file mode 100644 index 00000000000..1901a998732 --- /dev/null +++ b/mysql-test/t/dyncol.test @@ -0,0 +1,548 @@ +# +# Dynamic column function test +# + +--echo # +--echo # column create +--echo # +select hex(COLUMN_CREATE(1, NULL AS char character set utf8)); +select hex(COLUMN_CREATE(1, "afaf" AS char character set utf8)); +select hex(COLUMN_CREATE(1, 1212 AS char character set utf8)); +select hex(COLUMN_CREATE(1, 12.12 AS char character set utf8)); +select hex(COLUMN_CREATE(1, 99999999999999999999999999999 AS char character set utf8)); +select hex(COLUMN_CREATE(1, NULL AS unsigned int)); +select hex(COLUMN_CREATE(1, 1212 AS unsigned int)); +select hex(COLUMN_CREATE(1, 7 AS unsigned int)); +select hex(COLUMN_CREATE(1, 8 AS unsigned int)); +select hex(COLUMN_CREATE(1, 127 AS unsigned int)); +select hex(COLUMN_CREATE(1, 128 AS unsigned int)); +select hex(COLUMN_CREATE(1, 12.12 AS unsigned int)); +select hex(COLUMN_CREATE(1, ~0)); +select hex(COLUMN_CREATE(1, -1)); +select hex(COLUMN_CREATE(1, 99999999999999999999999999999 AS unsigned int)); +select hex(COLUMN_CREATE(1, NULL AS int)); +select hex(COLUMN_CREATE(1, 1212 AS int)); +select hex(COLUMN_CREATE(1, 7 AS int)); +select hex(COLUMN_CREATE(1, 8 AS int)); +select hex(COLUMN_CREATE(1, 127 AS int)); +select hex(COLUMN_CREATE(1, 128 AS int)); +select hex(COLUMN_CREATE(1, 12.12 AS int)); +select hex(COLUMN_CREATE(1, 99999999999999999999999999999 AS int)); +select hex(COLUMN_CREATE(1, NULL AS double)); +select hex(COLUMN_CREATE(1, 1212 AS double)); +select hex(COLUMN_CREATE(1, 12.12 AS double)); +select hex(COLUMN_CREATE(1, 99999999999999999999999999999 AS double)); +select hex(COLUMN_CREATE(1, NULL AS decimal)); +select hex(COLUMN_CREATE(1, 1212 AS decimal)); +select hex(COLUMN_CREATE(1, 7 AS decimal)); +select hex(COLUMN_CREATE(1, 8 AS decimal)); +select hex(COLUMN_CREATE(1, 127 AS decimal)); +select hex(COLUMN_CREATE(1, 128 AS decimal)); +select hex(COLUMN_CREATE(1, 12.12 AS decimal)); +select hex(COLUMN_CREATE(1, 99999999999999999999999999999 AS decimal)); +select hex(COLUMN_CREATE(1, NULL AS date)); +select hex(COLUMN_CREATE(1, "2011-04-05" AS date)); +select hex(COLUMN_CREATE(1, NULL AS time)); +select hex(COLUMN_CREATE(1, "0:45:49.000001" AS time)); +select hex(COLUMN_CREATE(1, NULL AS datetime)); +select hex(COLUMN_CREATE(1, "2011-04-05 0:45:49.000001" AS datetime)); +select hex(COLUMN_CREATE(1, "afaf" AS char character set utf8, + 2, 1212 AS unsigned int, + 3, 1212 AS int, + 4, 12.12 AS double, + 4+1, 12.12 AS decimal, + 6, "2011-04-05" AS date, + 7, "- 0:45:49.000001" AS time, + 8, "2011-04-05 0:45:49.000001" AS datetime)); +explain extended +select hex(COLUMN_CREATE(1, "afaf" AS char character set utf8, + 2, 1212 AS unsigned int, + 3, 1212 AS int, + 4, 12.12 AS double, + 4+1, 12.12 AS decimal, + 6, "2011-04-05" AS date, + 7, "- 0:45:49.000001" AS time, + 8, "2011-04-05 0:45:49.000001" AS datetime)); +select hex(column_create(1, 0.0 AS decimal)); +select hex(column_create(1, 1.0 AS decimal)); + +--echo # +--echo # column get uint +--echo # +select column_get(column_create(1, 1212 AS unsigned int), 1 as unsigned int); +explain extended +select column_get(column_create(1, 1212 AS unsigned int), 1 as unsigned int); +explain extended +select column_get(column_create(1, 1212 AS unsigned int), 1 as unsigned); +select column_get(column_create(1, 1212 AS decimal), 1 as unsigned int); +select column_get(column_create(1, 1212 AS double), 1 as unsigned int); +select column_get(column_create(1, 1212 AS int), 1 as unsigned int); +select column_get(column_create(1, "1212" AS char), 1 as unsigned int); +select column_get(column_create(1, "2011-04-05" AS date), 1 as unsigned int); +select column_get(column_create(1, "8:46:06.23434" AS time), 1 as unsigned int); +select column_get(column_create(1, "2011-04-05 8:46:06.23434" AS datetime), 1 as unsigned int); +select column_get(column_create(1, NULL AS unsigned int), 1 as unsigned int); +--echo # column geint truncation & warnings +select column_get(column_create(1, -1212 AS int), 1 as unsigned int); +select column_get(column_create(1, 99999999999999999999999999999 AS decimal), 1 as unsigned int); +select column_get(column_create(1, 999.9999999999999999 AS decimal), 1 as unsigned int); +select column_get(column_create(1, -1 AS decimal), 1 as unsigned int); +--replace_result e+029 e+29 +select column_get(column_create(1, 99999999999999999999999999999 AS double), 1 as unsigned int); +select column_get(column_create(1, 999.9 AS double), 1 as unsigned int); +select column_get(column_create(1, -1 AS double), 1 as unsigned int); +select column_get(column_create(1, "1212III" AS char), 1 as unsigned int); + +--echo # +--echo # column get int +--echo # +select column_get(column_create(1, 1212 AS int), 1 as int); +explain extended +select column_get(column_create(1, 1212 AS int), 1 as int); +explain extended +select column_get(column_create(1, 1212 AS int), 1 as signed int); +select column_get(column_create(1, -1212 AS int), 1 as int); +select column_get(column_create(1, 1212 AS decimal), 1 as int); +select column_get(column_create(1, 1212 AS double), 1 as int); +select column_get(column_create(1, 1212 AS unsigned int), 1 as int); +select column_get(column_create(1, "1212" AS char), 1 as int); +select column_get(column_create(1, "-1212" AS char), 1 as int); +select column_get(column_create(1, "2011-04-05" AS date), 1 as int); +select column_get(column_create(1, "8:46:06.23434" AS time), 1 as int); +select column_get(column_create(1, "8:46:06.23434" AS time(6)), 1 as int); +select column_get(column_create(1, "-808:46:06.23434" AS time(6)), 1 as int); +select column_get(column_create(1, "2011-04-05 8:46:06.23434" AS datetime(6)), 1 as int); +select column_get(column_create(1, NULL AS int), 1 as int); +--echo #column gett truncation & warnings +select column_get(column_create(1, 18446744073709551615 AS unsigned int), 1 as int); +select column_get(column_create(1, 99999999999999999999999999999 AS decimal), 1 as int); +select column_get(column_create(1, -99999999999999999999999999999 AS decimal), 1 as int); +select column_get(column_create(1, 999.9999999999999999 AS decimal), 1 as int); +select column_get(column_create(1, 999.9 AS double), 1 as int); +--replace_result e+029 e+29 +select column_get(column_create(1, -99999999999999999999999999999 AS double), 1 as int); +select column_get(column_create(1, "-1212III" AS char), 1 as int); +select column_get(column_create(1, "1212III" AS char), 1 as int); +select column_get(COLUMN_CREATE(1, ~0), 1 as signed); +select column_get(COLUMN_CREATE(1, ~0), 1 as unsigned); +select column_get(COLUMN_CREATE(1, -1), 1 as signed); +select column_get(COLUMN_CREATE(1, -1), 1 as unsigned); + +--echo # +--echo #column get char +--echo # +select column_get(column_create(1, "1212" AS char charset utf8), 1 as char charset utf8); +explain extended +select column_get(column_create(1, "1212" AS char charset utf8), 1 as char charset utf8); +select column_get(column_create(1, 1212 AS unsigned int), 1 as char charset utf8); +select column_get(column_create(1, 18446744073709551615 AS unsigned int), 1 as char charset utf8); +select column_get(column_create(1, 1212 AS int), 1 as char charset utf8); +select column_get(column_create(1, -1212 AS int), 1 as char charset utf8); +select column_get(column_create(1, 9223372036854775807 AS int), 1 as char charset utf8); +select column_get(column_create(1, -9223372036854775808 AS int), 1 as char charset utf8); +select column_get(column_create(1, 1212.12 AS decimal), 1 as char charset utf8); +select column_get(column_create(1, 1212.12 AS double), 1 as char charset utf8); +select column_get(column_create(1, "2011-04-05" AS date), 1 as char charset utf8); +select column_get(column_create(1, "8:46:06.23434" AS time), 1 as char charset utf8); +select column_get(column_create(1, "8:46:06.23434" AS time(0)), 1 as char charset utf8); +select column_get(column_create(1, "8:46:06.23434" AS time(6)), 1 as char charset utf8); +select column_get(column_create(1, "-808:46:06.23434" AS time(6)), 1 as char charset utf8); +select column_get(column_create(1, "2011-04-05 8:46:06.23434" AS datetime), 1 as char charset utf8); +select column_get(column_create(1, "2011-04-05 8:46:06.23434" AS datetime(0)), 1 as char charset utf8); +select column_get(column_create(1, "2011-04-05 8:46:06.23434" AS datetime(6)), 1 as char charset utf8); +select column_get(column_create(1, NULL AS char charset utf8), 1 as char charset utf8); +select column_get(column_create(1, "1212" AS char charset utf8), 1 as char charset binary); +explain extended +select column_get(column_create(1, "1212" AS char charset utf8), 1 as char charset binary); + +--echo # +--echo # column get real +--echo # +select column_get(column_create(1, 1212.12 AS double), 1 as double); +explain extended +select column_get(column_create(1, 1212.12 AS double), 1 as double); +explain extended +select column_get(column_create(1, 1212.12 AS double), 1 as double(6,2)); +select column_get(column_create(1, 18446744073709551615 AS unsigned int), 1 as double); +select column_get(column_create(1, 9223372036854775807 AS int), 1 as double); +select column_get(column_create(1, -9223372036854775808 AS int), 1 as double); +select column_get(column_create(1, 99999999999999999999999999999 AS decimal), 1 as double); +select column_get(column_create(1, -99999999999999999999999999999 AS decimal), 1 as double); +select column_get(column_create(1, "2011-04-05" AS date), 1 as double); +select column_get(column_create(1, "8:46:06.23434" AS time), 1 as double); +select column_get(column_create(1, "8:46:06.23434" AS time(6)), 1 as double); +select column_get(column_create(1, "-808:46:06.23434" AS time(6)), 1 as double); +select column_get(column_create(1, "2011-04-05 8:46:06.23434" AS datetime), 1 as double); +select column_get(column_create(1, "2011-04-05 8:46:06.23434" AS datetime(6)), 1 as double); +# The replace result is needed for windows. +select round(column_get(column_create(1, "2011-04-05 8:46:06.23434" AS datetime), 1 as double(20,6)),3); +select column_get(column_create(1, NULL AS double), 1 as double); + +-- echo # column get real truncation & warnings +select column_get(column_create(1, "1223.5aa" AS char), 1 as double); +select column_get(column_create(1, "aa" AS char), 1 as double); +select column_get(column_create(1, "1223.5555" AS double), 1 as double(5,2)); +select column_get(column_create(1, "1223.5555" AS double), 1 as double(3,2)); + +--echo # +--echo # column get decimal +--echo # +select column_get(column_create(1, 1212.12 AS double), 1 as decimal); +select column_get(column_create(1, 1212.12 AS double), 1 as decimal(6,2)); +explain extended +select column_get(column_create(1, 1212.12 AS double), 1 as decimal); +explain extended +select column_get(column_create(1, 1212.12 AS double), 1 as decimal(6,2)); +select column_get(column_create(1, 18446744073709551615 AS unsigned int), 1 as decimal(20,0)); +select column_get(column_create(1, 9223372036854775807 AS int), 1 as decimal(32,0)); +select column_get(column_create(1, -9223372036854775808 AS int), 1 as decimal(32,0)); +select column_get(column_create(1, -99999999999999999999999999999 AS decimal), 1 as decimal(40,10)); +select column_get(column_create(1, "2011-04-05" AS date), 1 as decimal(32,6)); +select column_get(column_create(1, "8:46:06.23434" AS time), 1 as decimal(32,6)); +select column_get(column_create(1, "8:46:06.23434" AS time(6)), 1 as decimal(32,6)); +select column_get(column_create(1, "-808:46:06.23434" AS time(6)), 1 as decimal(32,6)); +select column_get(column_create(1, "2011-04-05 8:46:06.123456" AS datetime), 1 as decimal(32,6)); +select column_get(column_create(1, "2011-04-05 8:46:06.123456" AS datetime(6)), 1 as decimal(32,6)); +select column_get(column_create(1, "2011-04-05 8:46:06.12345678" AS datetime(6)), 1 as decimal(32,8)); +select column_get(column_create(1, NULL as decimal), 1 as decimal(32,10)); +select column_get(column_create(1, "1223.5555" as decimal(10,5)), 1 as decimal(6,2)); + +-- echo # column get decimal truncation & warnings +select column_get(column_create(1, "1223.5aa" AS char), 1 as decimal(32,10)); +select column_get(column_create(1, "aa" AS char), 1 as decimal(32,10)); +select column_get(column_create(1, 18446744073709551615 AS unsigned int), 1 as decimal); +select column_get(column_create(1, 9223372036854775807 AS int), 1 as decimal); +select column_get(column_create(1, -9223372036854775808 AS int), 1 as decimal); +select column_get(column_create(1, 99999999999999999999999999999 AS decimal(32,10)), 1 as decimal); +select column_get(column_create(1, "2011-04-05 8:46:06.23434" AS datetime), 1 as decimal); +select column_get(column_create(1, "1223.5555" as double), 1 as decimal(5,2)); +select column_get(column_create(1, "-1223.5555" as double), 1 as decimal(5,2)); +select column_get(column_create(1, "1223.5555" AS double), 1 as decimal(3,2)); +select column_get(column_create(1, "1223.5555" AS decimal(10,5)), 1 as decimal(3,2)); +select column_get(column_create(1, 0.0 AS decimal,2, 0.0 as decimal), 1 as decimal); + +--echo # +--echo # column get datetime +--echo # +select column_get(column_create(1, 20010203101112.121314 as double), 1 as datetime); +select column_get(column_create(1, 20010203101112.121314 as decimal), 1 as datetime); +select column_get(column_create(1, 20010203101112 as unsigned int), 1 as datetime); +select column_get(column_create(1, 20010203101112 as int), 1 as datetime); +select column_get(column_create(1, "20010203101112" as char), 1 as datetime); +select column_get(column_create(1, "2001-02-03 10:11:12" as char), 1 as datetime); +select column_get(column_create(1, "2001-02-03 10:11:12.121314" as char), 1 as datetime); +select column_get(column_create(1, "2001-02-03 10:11:12.121314"), 1 as datetime); +select column_get(column_create(1, "2011-04-05 8:46:06.23434" AS datetime), 1 as datetime); +select column_get(column_create(1, "2011-04-05 8:46:06.23434" AS datetime), 1 as datetime(0)); +select column_get(column_create(1, "2011-04-05 8:46:06.23434" AS datetime), 1 as datetime(6)); +select column_get(column_create(1, "2011-00-00 8:46:06.23434" AS CHAR), 1 as datetime); +select column_get(column_create(1, "2011-00-01 8:46:06.23434" AS CHAR), 1 as datetime); + +select column_get(column_create(1, 20010203 as unsigned int), 1 as datetime); +select column_get(column_create(1, 20010203 as int), 1 as datetime); +select column_get(column_create(1, 20010203), 1 as datetime); +select column_get(column_create(1, 20010203.0), 1 as datetime); +select column_get(column_create(1, 20010203.0 as double), 1 as datetime); +select column_get(column_create(1, "2001-02-03"), 1 as datetime); +select column_get(column_create(1, "20010203"), 1 as datetime); +select column_get(column_create(1, 0), 1 as datetime); +select column_get(column_create(1, "2001021"), 1 as datetime); + +select column_get(column_create(1, "8:46:06.23434" AS time), 1 as datetime); +select column_get(column_create(1, "-808:46:06.23434" AS time), 1 as datetime); + +set @@sql_mode="allow_invalid_dates"; +select column_get(column_create(1, "2011-02-30 18:46:06.23434" AS CHAR), 1 as datetime); +select column_get(column_create(1, "0000-00-000" AS CHAR), 1 as datetime); +select column_get(column_create(1, "2001-00-02" AS CHAR), 1 as datetime); +set @@sql_mode=""; + +-- echo # column get datetime truncation & warnings +select column_get(column_create(1, "1223.5aa" AS char), 1 as datetime); +--replace_result e+019 e+19 +select column_get(column_create(1, 18446744073709551615 AS unsigned int), 1 as datetime); +select column_get(column_create(1, 9223372036854775807 AS int), 1 as datetime); +select column_get(column_create(1, -9223372036854775808 AS int), 1 as datetime); +select column_get(column_create(1, 99999999999999999999999999999 AS decimal(32,10)), 1 as datetime); +--replace_result e+029 e+29 +select column_get(column_create(1, 99999999999999999999999999999 AS double), 1 as datetime); +select column_get(column_create(1, "2011-02-32 8:46:06.23434" AS CHAR), 1 as datetime); +select column_get(column_create(1, "2011-13-01 8:46:06.23434" AS CHAR), 1 as datetime); +select column_get(column_create(1, "2011-02-30 8:46:06.23434" AS CHAR), 1 as datetime); +select column_get(column_create(1, "20010231"), 1 as datetime); +select column_get(column_create(1, "0" AS CHAR), 1 as datetime); + + +--echo # +--echo # column get date +--echo # +select column_get(column_create(1, 20010203101112.121314 as double), 1 as date); +select column_get(column_create(1, 20010203101112.121314 as decimal), 1 as date); +select column_get(column_create(1, 20010203101112 as unsigned int), 1 as date); +select column_get(column_create(1, 20010203101112 as int), 1 as date); +select column_get(column_create(1, "20010203101112" as char), 1 as date); +select column_get(column_create(1, "2001-02-03 10:11:12" as char), 1 as date); +select column_get(column_create(1, "2001-02-03 10:11:12.121314" as char), 1 as date); +select column_get(column_create(1, "2001-02-03 10:11:12.121314"), 1 as date); +select column_get(column_create(1, "2011-04-05 8:46:06.23434" AS datetime), 1 as date); +select column_get(column_create(1, "2011-00-00 8:46:06.23434" AS CHAR), 1 as date); +select column_get(column_create(1, "2011-00-01 8:46:06.23434" AS CHAR), 1 as date); + +select column_get(column_create(1, 20010203 as unsigned int), 1 as date); +select column_get(column_create(1, 20010203 as int), 1 as date); +select column_get(column_create(1, 20010203), 1 as date); +select column_get(column_create(1, 20010203.0), 1 as date); +select column_get(column_create(1, 20010203.0 as double), 1 as date); +select column_get(column_create(1, "2001-02-03"), 1 as date); +select column_get(column_create(1, "20010203"), 1 as date); +select column_get(column_create(1, 0), 1 as date); +select column_get(column_create(1, "2001021"), 1 as date); + +set @@sql_mode="allow_invalid_dates"; +select column_get(column_create(1, "2011-02-30 18:46:06.23434" AS CHAR), 1 as date); +select column_get(column_create(1, "0000-00-000" AS CHAR), 1 as date); +select column_get(column_create(1, "2001-00-02" AS CHAR), 1 as date); +set @@sql_mode=""; + +-- echo # column get date truncation & warnings +select column_get(column_create(1, "1223.5aa" AS char), 1 as date); +--replace_result e+019 e+19 +select column_get(column_create(1, 18446744073709551615 AS unsigned int), 1 as date); +select column_get(column_create(1, 9223372036854775807 AS int), 1 as date); +select column_get(column_create(1, -9223372036854775808 AS int), 1 as date); +select column_get(column_create(1, 99999999999999999999999999999 AS decimal(32,10)), 1 as date); +--replace_result e+029 e+29 +select column_get(column_create(1, 99999999999999999999999999999 AS double), 1 as date); +select column_get(column_create(1, "2011-02-32 8:46:06.23434" AS CHAR), 1 as date); +select column_get(column_create(1, "2011-13-01 8:46:06.23434" AS CHAR), 1 as date); +select column_get(column_create(1, "2011-02-30 8:46:06.23434" AS CHAR), 1 as date); +select column_get(column_create(1, "20010231"), 1 as date); +select column_get(column_create(1, "0" AS CHAR), 1 as date); + +--echo # +--echo # column get time +--echo # +select column_get(column_create(1, 20010203101112.121314 as double), 1 as time); +select column_get(column_create(1, 20010203101112.121314 as decimal), 1 as time); +select column_get(column_create(1, 20010203101112 as unsigned int), 1 as time); +select column_get(column_create(1, 8080102 as unsigned int), 1 as time); +select column_get(column_create(1, 20010203101112 as int), 1 as time); +select column_get(column_create(1, -8080102 as int), 1 as time); +select column_get(column_create(1, "20010203101112" as char), 1 as time); +select column_get(column_create(1, "2001-02-03 10:11:12" as char), 1 as time); +select column_get(column_create(1, "2001-02-03 10:11:12.121314" as char), 1 as time); +select column_get(column_create(1, "2001-02-03 10:11:12.121314" as char), 1 as time(6)); +select column_get(column_create(1, "2001-02-03 10:11:12.121314"), 1 as time); +select column_get(column_create(1, "2011-04-05 8:46:06.23434" AS datetime), 1 as time(6)); +select column_get(column_create(1, "2011-00-00 8:46:06.23434" AS CHAR), 1 as time(6)); +select column_get(column_create(1, "2011-00-01 8:46:06.23434" AS CHAR), 1 as time(6)); +select column_get(column_create(1, "830:46:06.23434" AS CHAR), 1 as time(6)); +select column_get(column_create(1, "830:46:06" AS CHAR), 1 as time(6)); +select cast("-830:46:06.23434" AS time(6)); +select 1,cast("-830:46:06.23434" AS time(6)); +select hex(column_create(1, "-830:46:06.23434" AS CHAR)); +select column_get(column_create(1, "-830:46:06.23434" AS CHAR), 1 as time(6)); +select column_get(column_create(1, "0" AS CHAR), 1 as time); +select column_get(column_create(1, "6" AS CHAR), 1 as time); +select column_get(column_create(1, "1:6" AS CHAR), 1 as time); +select column_get(column_create(1, "2:1:6" AS CHAR), 1 as time); + +select column_get(column_create(1, 0), 1 as time); +select column_get(column_create(1, "2001021"), 1 as time); + +set @@sql_mode="allow_invalid_dates"; +select column_get(column_create(1, "2011-02-30 18:46:06.23434" AS CHAR), 1 as time); +set @@sql_mode=""; + +-- echo # column get date truncation & warnings +select column_get(column_create(1, "1223.5aa" AS char), 1 as time); +select column_get(column_create(1, "1223.5aa" AS char), 1 as time(3)); +--replace_result e+019 e+19 +select column_get(column_create(1, 18446744073709551615 AS unsigned int), 1 as time); +select column_get(column_create(1, 9223372036854775807 AS int), 1 as time); +select column_get(column_create(1, -9223372036854775808 AS int), 1 as time); +select column_get(column_create(1, 99999999999999999999999999999 AS decimal(32,10)), 1 as time); +--replace_result e+029 e+29 +select column_get(column_create(1, 99999999999999999999999999999 AS double), 1 as time); +select column_get(column_create(1, "2011-02-32 8:46:06.23434" AS CHAR), 1 as time); +select column_get(column_create(1, "2011-13-01 8:46:06.23434" AS CHAR), 1 as time); +select column_get(column_create(1, "2011-02-30 8:46:06.23434" AS CHAR), 1 as time); +select column_get(column_create(1, "2001-02-03"), 1 as time); +select column_get(column_create(1, "20010203"), 1 as time); + + +-- echo # column add +select hex(column_add(column_create(1, 1212 as integer), 2, 1212 as integer)); +select hex(column_add(column_create(1, 1212 as integer), 1, 1212 as integer)); +select hex(column_add(column_create(1, 1212 as integer), 1, NULL as integer)); +select hex(column_add(column_create(1, 1212 as integer), 2, NULL as integer)); +select hex(column_add(column_create(1, 1212 as integer), 2, 1212 as integer, 1, 11 as integer)); +select column_get(column_add(column_create(1, 1212 as integer), 2, 1212 as integer, 1, 11 as integer), 1 as integer); +select column_get(column_add(column_create(1, 1212 as integer), 2, 1212 as integer, 1, 11 as integer), 2 as integer); +select hex(column_add(column_create(1, 1212 as integer), 1, 1212 as integer, 2, 11 as integer)); +select hex(column_add(column_create(1, NULL as integer), 1, 1212 as integer, 2, 11 as integer)); +select hex(column_add(column_create(1, 1212 as integer, 2, 1212 as integer), 1, 11 as integer)); +select hex(column_add(column_create(1, 1), 1, null)); +select column_list(column_add(column_create(1, 1), 1, null)); +select column_list(column_add(column_create(1, 1), 1, "")); +select hex(column_add("", 1, 1)); + +-- echo # column delete +select hex(column_delete(column_create(1, 1212 as integer, 2, 1212 as integer), 1)); +select hex(column_delete(column_create(1, 1 as integer, 2, 2 as integer, 3, 3 as integer), 2)); +select hex(column_delete(column_create(1, 1 as integer, 2, 2 as integer, 3, 3 as integer), 3)); +select hex(column_delete(column_create(1, 1 as integer, 2, 2 as integer, 3, 3 as integer), 4)); +select hex(column_delete(column_create(1, 1 as integer, 2, 2 as integer, 3, 3 as integer), 2, 1)); +select hex(column_delete(column_create(1, 1 as integer, 2, 2 as integer, 3, 3 as integer), 2, 3)); +select hex(column_delete(column_create(1, 1 as integer, 2, 2 as integer, 3, 3 as integer), 1, 2, 3)); +select hex(column_delete(column_create(1, 1 as integer, 2, 2 as integer, 3, 3 as integer), 1, 2, 3, 10)); +select hex(column_delete(column_create(1, 1), 1)); +select hex(column_delete("", 1)); + +-- echo # column exists +select column_exists(column_create(1, 1212 as integer, 2, 1212 as integer), 1); +select column_exists(column_create(1, 1212 as integer, 2, 1212 as integer), 4); + +-- echo # column list +select column_list(column_create(1, 1212 as integer, 2, 1212 as integer)); +select column_list(column_create(1, 1212 as integer)); +select column_list(column_create(1, NULL as integer)); + +--echo # +--echo # check error handling +--echo # +--error ER_DYN_COL_DATA +select HEX(COLUMN_CREATE(1, 5, 1, 5)); +--error 1064 +select HEX(COLUMN_CREATE("", 1, 5, 1, 5)); +--error ER_DYN_COL_WRONG_FORMAT +select COLUMN_LIST("a"); +--error ER_DYN_COL_WRONG_FORMAT +select column_delete("a", 1); +select hex(column_delete("", 1)); +--error ER_DYN_COL_DATA +select hex(column_delete("", -1)); +--error ER_DYN_COL_DATA +select hex(column_create(-1, 1)); +--error ER_DYN_COL_DATA +select hex(column_create(65536, 1)); +--error ER_DYN_COL_DATA +select hex(column_add("", -1, 1)); +--error ER_DYN_COL_DATA +select hex(column_add("", 65536, 1)); +select hex(column_get("", -1 as int)); + +--echo # +--echo # Test with table +--echo # + +# create table with 'str' to hold a set of dynamic columns +create table t1 (id int primary key, str mediumblob); +insert into t1 values (1, ''), (2, ''), (3, ''), (4, ''), (5, null); + +# Selecting a non existing column +select id, str, column_get(str, 1 as int) from t1; + +# Add some dynamic columns. One and do it with create or add. +update t1 set str=column_create(1, id, 2, "a") where id < 3; +update t1 set str=column_add(str, 1, id, 2, "b") where id >= 4; + +# Show some data, if it exists +select id, column_get(str, 1 as int), column_get(str, 2 as char) from t1 where column_exists(str,1) or column_exists(str,2); + +# Add data to row 5 and 6 +update t1 set str=column_create(1, id, 10, "test") where id = 5; +insert into t1 values (6, column_create(10, "test2")); + +# Update some of the columns and add a new column 3 +update t1 set str=column_add(str, 2, 'c', 1, column_get(str, 1 as int) + 1, 3, 100) where id > 2; + +# Check data +select id, length(str), column_get(str, 1 as int), column_get(str, 2 as char), column_get(str, 3 as int) from t1; + +# You can do anything with the columns, like SUM() or GROUP +select column_get(str, 2 as char), sum(column_get(str, 1 as int)) from t1 group by column_get(str, 2 as char); +select column_get(str, 2 as char), sum(column_get(str, 1 as int)) from t1 where column_exists(str, 2) <> 0 group by 1; +select sum(column_get(str, 1 as int)) from t1 group by column_get(str, 2 as char) order by sum(column_get(str, 1 as int)) desc; +select sum(column_get(str, 1 as int)) from t1 group by column_get(str, 2 as char) having sum(column_get(str, 1 as int)) > 2; +select sum(column_get(str, 1 as int)) from t1 where column_get(str, 3 as int) > 50 group by column_get(str, 2 as char); + +# Deleting of column +select id, column_list(str) from t1 where id= 5; +update t1 set str=column_delete(str, 3, 4, 2) where id= 5; + +select id, length(str), column_list(str), column_get(str, 1 as int), column_get(str, 2 as char), column_get(str, 3 as int) from t1; + +update t1 set str=column_add(str, 4, 45 as char, 2, 'c') where id= 5; +select id, length(str), column_list(str), column_get(str, 1 as int), column_get(str, 2 as char), column_get(str, 3 as int) from t1 where id = 5; + +# Check which column exists +select id, length(str), column_list(str), column_exists(str, 4) from t1; +select sum(column_get(str, 1 as int)), column_list(str) from t1 group by 2; +select id, hex(str) from t1; + +# Check with a bit larger strings + +update t1 set str=column_add(str, 4, repeat("a", 100000)) where id=5; +select id from t1 where column_get(str,4 as char(100000)) = repeat("a", 100000); +select id from t1 where column_get(str,4 as char(100)) = repeat("a", 100); +update t1 set str=column_add(str, 4, repeat("b", 10000)) where id=5; +select id from t1 where column_get(str,4 as char(100000)) = repeat("b", 10000); +update t1 set str=column_add(str, 4, repeat("c", 100)) where id=5; +select id from t1 where column_get(str,4 as char(100000)) = repeat("c", 100); +update t1 set str=column_add(str, 4, repeat("d", 10000)) where id=5; +select id from t1 where column_get(str,4 as char(100000)) = repeat("d", 10000); +update t1 set str=column_add(str, 4, repeat("e", 10), 5, repeat("f", 100000)) where id=5; +select id from t1 where column_get(str,5 as char(100000)) = repeat("f", 100000); +select id, column_list(str), length(str) from t1 where id=5; +update t1 set str=column_delete(str, 5) where id=5; +select id, column_list(str), length(str) from t1 where id=5; + +drop table t1; + +--echo # +--echo # LP#778905: Assertion `value->year <= 9999' failed in +--echo # dynamic_column_date_store +--echo # + +--error ER_DYN_COL_WRONG_FORMAT +SELECT COLUMN_GET( 'a' , 2 AS DATE ); +--error ER_DYN_COL_WRONG_FORMAT +SELECT COLUMN_CREATE( 1 , COLUMN_GET( 'a' , 2 AS DATE ) ); + +--echo # +--echo # LP#778912: Assertion `field_pos < field_count' failed in +--echo # Protocol_text::store in maria-5.3-mwl34 +--echo # + +CREATE TABLE t1 ( f1 blob ); +INSERT INTO t1 VALUES (NULL); +INSERT INTO t1 SET f1 = COLUMN_CREATE( 2 , 'cde' ); +SELECT HEX(COLUMN_ADD(f1, 1, 'abc')), COLUMN_LIST(f1) FROM t1; + +# Don't print strange characters on screen +--disable_result_log +SELECT COLUMN_ADD(f1, 1, 'abc'), COLUMN_LIST(f1) FROM t1; +--enable_result_log +DROP TABLE t1; + +--echo # +--echo # Some dynamic strings that caused crashes in the past +--echo # + +set @a=0x0102000200030004000F0D086B74697A6A7176746F6B687563726A746E7A746A666163726C6F7A6B62636B6B756B666779666977617369796F67756C726D62677A72756E63626D78636D7077706A6F736C6D636464696770786B6371637A6A6A6463737A6A676879716462637178646C666E6B6C726A637677696E7271746C616D646368687A6C707869786D666F666261797470616A63797673737A796D74747475666B717573687A79696E7276706F796A6E767361796A6F6D646F6378677A667074746363736A796D67746C786F697873686464616265616A7A6F7168707A6B776B6376737A6B72666C6F666C69636163686F6B666D627166786A71616F; +--error ER_DYN_COL_WRONG_FORMAT +select column_add(@a, 3, "a"); + +--echo # +--echo # LP#781233 mysqld: decimal.c:1459: decimal_bin_size: +--echo # Assertion `scale >= 0 && precision > 0 && scale <= precision' ... +--echo # + +set @a=0x00020008000009000C2C010080; +select COLUMN_GET(@a, 9 AS DECIMAL); +select hex(COLUMN_CREATE(0, COLUMN_GET(@a, 9 AS DECIMAL))); +select hex(COLUMN_CREATE(0, COLUMN_GET(@a, 9 AS DECIMAL(19,0)))); + +select hex(COLUMN_CREATE(0, COLUMN_GET(COLUMN_CREATE(0, 0.0 as decimal), 0 as decimal))); +select hex(COLUMN_CREATE(0, 0.0 as decimal)); diff --git a/mysql-test/t/explain.test b/mysql-test/t/explain.test index 8376fdf1ad1..2fb0fb8fac7 100644 --- a/mysql-test/t/explain.test +++ b/mysql-test/t/explain.test @@ -158,7 +158,10 @@ SELECT @@session.sql_mode INTO @old_sql_mode; SET SESSION sql_mode='ONLY_FULL_GROUP_BY'; # EXPLAIN EXTENDED (with subselect). used to crash. should give NOTICE. ---error ER_MIX_OF_GROUP_FUNC_AND_FIELDS +# Before moving max/min optimization to optimize phase this statement +# generated error, but as far as original query do not contain aggregate +# function user should not see error +# --error ER_MIX_OF_GROUP_FUNC_AND_FIELDS EXPLAIN EXTENDED SELECT 1 FROM t1 WHERE f1 > ALL( SELECT t.f1 FROM t1,t1 AS t ); SHOW WARNINGS; @@ -296,3 +299,16 @@ DEALLOCATE PREPARE s; DROP TABLE t1; --echo # +--echo # Bug#776295: EXPLAIN EXTENDED with always false multiple equality +--echo # in the WHERE condition of a derived table +--echo # + +CREATE TABLE t1 (a int) ; + +CREATE TABLE t2 (a int) ; +INSERT INTO t2 VALUES (8); + +EXPLAIN EXTENDED +SELECT * FROM ( SELECT t1.a FROM t1,t2 WHERE t2.a = t1.a ) AS t; + +DROP TABLE t1,t2; diff --git a/mysql-test/t/flush.test b/mysql-test/t/flush.test index 52ee6d2cf87..de23cf02c38 100644 --- a/mysql-test/t/flush.test +++ b/mysql-test/t/flush.test @@ -28,7 +28,7 @@ enable_query_log; connection con1; select * from t1; connection con2; -flush tables with read lock; +flush tables with read lock and disable checkpoint; --error 1223 drop table t2; connection con1; diff --git a/mysql-test/t/func_group.test b/mysql-test/t/func_group.test index e8309d68830..77b2fd67ffa 100644 --- a/mysql-test/t/func_group.test +++ b/mysql-test/t/func_group.test @@ -1063,7 +1063,8 @@ insert into t1 values (02,2002,20020101,"2002-01-01 23:59:59"), (60,2060,20600101,"2060-01-01 11:11:11"), (70,1970,19700101,"1970-11-11 22:22:22"), - (NULL,NULL,NULL,NULL); + (NULL,NULL,NULL,NULL), + (71,1971,19710101,"1971-11-11 22:22:22"); select min(f1),max(f1) from t1; select min(f2),max(f2) from t1; select min(f3),max(f3) from t1; @@ -1142,6 +1143,142 @@ DROP TABLE t1; --echo # --echo End of 5.1 tests +--echo # +--echo # BUG#46680 - Assertion failed in file item_subselect.cc, +--echo # line 305 crashing on HAVING subquery +--echo # + +--echo # Create tables +--echo # + +CREATE TABLE t1 ( + pk INT, + v VARCHAR(1) DEFAULT NULL, + PRIMARY KEY(pk) +); +CREATE TABLE t2 LIKE t1; +CREATE TABLE t3 LIKE t1; +CREATE TABLE empty1 (a int); + +INSERT INTO t1 VALUES (1,'c'),(2,NULL); +INSERT INTO t2 VALUES (3,'m'),(4,NULL); +INSERT INTO t3 VALUES (1,'n'); + +set @save_optimizer_switch=@@optimizer_switch; +set @@optimizer_switch='materialization=on,in_to_exists=off,semijoin=off'; + +--echo +--echo # +--echo # 1) Test that subquery materialization is setup for query with +--echo # premature optimize() exit due to "Impossible WHERE" +--echo # +SELECT MIN(t2.pk) +FROM t2 JOIN t1 ON t1.pk=t2.pk +WHERE 'j' +HAVING ('m') IN ( +SELECT v +FROM t2); + +--echo +EXPLAIN +SELECT MIN(t2.pk) +FROM t2 JOIN t1 ON t1.pk=t2.pk +WHERE 'j' +HAVING ('m') IN ( +SELECT v +FROM t2); + +--echo +--echo # +--echo # 2) Test that subquery materialization is setup for query with +--echo # premature optimize() exit due to "No matching min/max row" +--echo # +SELECT MIN(t2.pk) +FROM t2 +WHERE t2.pk>10 +HAVING ('m') IN ( +SELECT v +FROM t2); + +--echo +EXPLAIN +SELECT MIN(t2.pk) +FROM t2 +WHERE t2.pk>10 +HAVING ('m') IN ( +SELECT v +FROM t2); + +--echo +--echo # +--echo # 3) Test that subquery materialization is setup for query with +--echo # premature optimize() exit due to "Select tables optimized away" +--echo # +SELECT MIN(pk) +FROM t1 +WHERE pk=NULL +HAVING ('m') IN ( +SELECT v +FROM t2); + +--echo +EXPLAIN +SELECT MIN(pk) +FROM t1 +WHERE pk=NULL +HAVING ('m') IN ( +SELECT v +FROM t2); + +--echo +--echo # +--echo # 4) Test that subquery materialization is setup for query with +--echo # premature optimize() exit due to "No matching row in const table" +--echo # +--echo +SELECT MIN(a) +FROM (SELECT a FROM empty1) tt +HAVING ('m') IN ( +SELECT v +FROM t2); + +--echo +EXPLAIN +SELECT MIN(a) +FROM (SELECT a FROM empty1) tt +HAVING ('m') IN ( +SELECT v +FROM t2); + +--echo +--echo # +--echo # 5) Test that subquery materialization is setup for query with +--echo # premature optimize() exit due to "Impossible WHERE noticed +--echo # after reading const tables" +--echo # +SELECT min(t1.pk) +FROM t1 +WHERE t1.pk IN (SELECT 1 from t3 where pk>10) +HAVING ('m') IN ( +SELECT v +FROM t2); + +--echo +EXPLAIN +SELECT min(t1.pk) +FROM t1 +WHERE t1.pk IN (SELECT 1 from t3 where pk>10) +HAVING ('m') IN ( +SELECT v +FROM t2); + +set @@optimizer_switch=@save_optimizer_switch; + +--echo # +--echo # Cleanup for BUG#46680 +--echo # +DROP TABLE IF EXISTS t1,t2,t3,empty1; + ### --echo # --echo # Bug#52123 Assertion failed: aggregator == aggr->Aggrtype(), diff --git a/mysql-test/t/func_if.test b/mysql-test/t/func_if.test index f0ac0190cb3..a67bb088faa 100644 --- a/mysql-test/t/func_if.test +++ b/mysql-test/t/func_if.test @@ -161,8 +161,9 @@ DROP TABLE t1; # CREATE TABLE t1 (c LONGTEXT); -INSERT INTO t1 VALUES(1), (2), (3), (4), ('12345678901234567890'); +INSERT INTO t1 VALUES(1), (2), (3), (4), ('1234567890123456789'); +SELECT IF(1, CAST(c AS UNSIGNED), 0) FROM t1; SELECT * FROM (SELECT MAX(IF(1, CAST(c AS UNSIGNED), 0)) FROM t1) AS te; SELECT * FROM (SELECT MAX(IFNULL(CAST(c AS UNSIGNED), 0)) FROM t1) AS te; diff --git a/mysql-test/t/func_sapdb.test b/mysql-test/t/func_sapdb.test index 89eae5955aa..51bdebbec6d 100644 --- a/mysql-test/t/func_sapdb.test +++ b/mysql-test/t/func_sapdb.test @@ -91,8 +91,8 @@ select microsecond("1997-12-31 23:59:59.000001"); create table t1 select makedate(1997,1) as f1, - addtime(cast("1997-12-31 23:59:59.000001" as datetime), "1 1:1:1.000002") as f2, - addtime(cast("23:59:59.999999" as time) , "1 1:1:1.000002") as f3, + addtime(cast("1997-12-31 23:59:59.000001" as datetime(6)), "1 1:1:1.000002") as f2, + addtime(cast("23:59:59.999999" as time(6)) , "1 1:1:1.000002") as f3, timediff("1997-12-31 23:59:59.000001","1997-12-30 01:01:01.000002") as f4, timediff("1997-12-30 23:59:59.000001","1997-12-31 23:59:59.000002") as f5, maketime(10,11,12) as f6, diff --git a/mysql-test/t/func_time.test b/mysql-test/t/func_time.test index a9980a0c8eb..cdac95523e5 100644 --- a/mysql-test/t/func_time.test +++ b/mysql-test/t/func_time.test @@ -15,7 +15,12 @@ select now()-now(),weekday(curdate())-weekday(now()),unix_timestamp()-unix_times select from_unixtime(unix_timestamp("1994-03-02 10:11:12")),from_unixtime(unix_timestamp("1994-03-02 10:11:12"),"%Y-%m-%d %h:%i:%s"),from_unixtime(unix_timestamp("1994-03-02 10:11:12"))+0; select sec_to_time(9001),sec_to_time(9001)+0,time_to_sec("15:12:22"), sec_to_time(time_to_sec("0:30:47")/6.21); +select sec_to_time(9001.1), time_to_sec('15:12:22.123456'), time_to_sec(15.5566778899); select sec_to_time(time_to_sec('-838:59:59')); +select sec_to_time('9001.1'), sec_to_time('1234567890123.123'); +--replace_result e+042 e+42 +select sec_to_time(90011e-1), sec_to_time(1234567890123e30); +select sec_to_time(1234567890123), sec_to_time('99999999999999999999999999999'); select now()-curdate()*1000000-curtime(); select strcmp(current_timestamp(),concat(current_date()," ",current_time())); select strcmp(localtime(),concat(current_date()," ",current_time())); @@ -27,6 +32,7 @@ select month("1997-01-02"),year("98-02-03"),dayofyear("1997-12-31"); select month("2001-02-00"),year("2001-00-00"); select DAYOFYEAR("1997-03-03"), WEEK("1998-03-03"), QUARTER(980303); select HOUR("1997-03-03 23:03:22"), MINUTE("23:03:22"), SECOND(230322); +select TIME(230322), TIME(230322.33), TIME("230322.33"); # Test of week and yearweek select week(19980101),week(19970101),week(19980101,1),week(19970101,1); @@ -66,10 +72,10 @@ select date_format('1999-12-31','%x-%v'),date_format('2000-01-01','%x-%v'); select dayname("1962-03-03"),dayname("1962-03-03")+0; select monthname("1972-03-04"),monthname("1972-03-04")+0; -select time_format(19980131000000,'%H|%I|%k|%l|%i|%p|%r|%S|%T'); -select time_format(19980131010203,'%H|%I|%k|%l|%i|%p|%r|%S|%T'); -select time_format(19980131131415,'%H|%I|%k|%l|%i|%p|%r|%S|%T'); -select time_format(19980131010015,'%H|%I|%k|%l|%i|%p|%r|%S|%T'); +select time_format(000000,'%H|%I|%k|%l|%i|%p|%r|%S|%T'),date_format(19980131000000,'%H|%I|%k|%l|%i|%p|%r|%S|%T'); +select time_format(010203,'%H|%I|%k|%l|%i|%p|%r|%S|%T'),date_format(19980131010203,'%H|%I|%k|%l|%i|%p|%r|%S|%T'); +select time_format(131415,'%H|%I|%k|%l|%i|%p|%r|%S|%T'),date_format(19980131131415,'%H|%I|%k|%l|%i|%p|%r|%S|%T'); +select time_format(010015,'%H|%I|%k|%l|%i|%p|%r|%S|%T'),date_format(19980131010015,'%H|%I|%k|%l|%i|%p|%r|%S|%T'); select date_format(concat('19980131',131415),'%H|%I|%k|%l|%i|%p|%r|%S|%T| %M|%W|%D|%Y|%y|%a|%b|%j|%m|%d|%h|%s|%w'); select date_format(19980021000000,'%H|%I|%k|%l|%i|%p|%r|%S|%T| %M|%W|%D|%Y|%y|%a|%b|%j|%m|%d|%h|%s|%w'); select date_add("1997-12-31 23:59:59",INTERVAL 1 SECOND); @@ -531,6 +537,7 @@ DROP TABLE t1; # Bug #20927: sec_to_time treats big unsigned as signed # # check if SEC_TO_TIME() handles BIGINT UNSIGNED values correctly +--replace_regex /'1.8446.*e.*19'/'1.84467440737096e+19'/ SELECT SEC_TO_TIME(CAST(-1 AS UNSIGNED)); # @@ -712,6 +719,7 @@ set time_zone= @@global.time_zone; # select str_to_date('10:00 PM', '%h:%i %p') + INTERVAL 10 MINUTE; +select str_to_date("1997-00-04 22:23:00","%Y-%m-%D") + interval 10 minute; # # Bug #21103: DATE column not compared as DATE @@ -809,7 +817,7 @@ select date_add('1000-01-01 00:00:00', interval '1.02' day_microsecond); --disable_result_log SET TIMESTAMP=-147490000; SELECT UTC_TIMESTAMP(); ---error ER_WRONG_VALUE_FOR_VAR +--error 0,ER_WRONG_VALUE_FOR_VAR SET TIMESTAMP=2147483648; SELECT UTC_TIMESTAMP(); SET TIMESTAMP=2147483646; SELECT UTC_TIMESTAMP(); SET TIMESTAMP=2147483647; SELECT UTC_TIMESTAMP(); @@ -886,7 +894,9 @@ SELECT FORMAT(YEAR(STR_TO_DATE('',GET_FORMAT(TIME,''))),1); --echo # Bug#11766126 59166: ANOTHER DATETIME VALGRIND UNINITIALIZED WARNING --echo # +--disable_result_log SELECT CAST((MONTH(FROM_UNIXTIME(@@GLOBAL.SQL_MODE))) AS BINARY(1025)); +--enable_result_log --echo # --echo # Bug#11766124 59164: VALGRIND: UNINITIALIZED VALUE IN NUMBER_TO_DATETIME @@ -944,3 +954,137 @@ create table t1(a time); insert into t1 values ('00:00:00'),('00:01:00'); select 1 from t1 where 1 < some (select cast(a as datetime) from t1); drop table t1; + +select time('10:10:10') > 10; +select time('10:10:10') > 1010; +select time('10:10:09') > 101010; +select time('10:10:10') > 101010; +select time('10:10:11') > 101010; + +select time(' 1 02:03:04') + interval 9 microsecond; +select time(' 1 02:03:04') - interval 9 microsecond; +select time('-1 02:03:04') + interval 9 microsecond; +select time('-1 02:03:04') - interval 9 microsecond; +select time(' 1 02:03:04') + interval '4:4:4' hour_second; +select time(' 1 02:03:04') - interval '4:4:4' hour_second; +select time('-1 02:03:04') + interval '4:4:4' hour_second; +select time('-1 02:03:04') - interval '4:4:4' hour_second; +select time(' 1 02:03:04') + interval 2 day; +select time(' 1 02:03:04') - interval 2 day; +select time('-1 02:03:04') + interval 2 day; +select time('-1 02:03:04') - interval 2 day; + +select time('10 02:03:04') + interval 30 day; +select time('10 02:03:04') + interval 1 year; + +# specially constructed queries to reach obscure places in the code +# not touched by the more "normal" queries (and to increase the coverage) +select cast('131415.123e0' as time); +select cast('2010-01-02 03:04:05' as datetime) between null and '2010-01-02 03:04:04'; +select least(time('1:2:3'), '01:02:04', null) div 1; +select truncate(least(time('1:2:3'), '01:02:04', null), 6); +select cast(least(time('1:2:3'), '01:02:04', null) as decimal(3,1)); +select unix_timestamp(null); +select truncate(date('2010-40-10'), 6); +select extract(month from '2010-40-50'); +select subtime('0000-00-10 10:10:10', '30 10:00:00'); + +# +# lp:730637 Valgrind warnings in 5.1-micro +# +select cast(str_to_date(NULL, '%H:%i:%s') as time); + +create table t1 (f1 datetime, key (f1)); +insert into t1 values ('2000-09-12 00:00:00'), ('2007-04-25 05:08:49'); +select * from t1 where f1 > time('-23:00:06'); +drop table t1; + +# +# lp:730627 TIME_to_ulonglong: Assertion `0' failed in 5.1-micro on wrong argument to MAKETIME +# +select maketime(20,61,10)+0; + +# +# lp:731103 Assertion `maybe_null && item->null_value' failed with ORDER BY LAST_DAY() +# +create table t1 (f2 int not null) ; +insert into t1 values (0),(0); +select last_day(f2) from t1; +select last_day(f2) from t1 where last_day(f2) is null; +select * from t1 order by last_day (f2); +drop table t1; + +# +# lp:731815 Crash/valgrind warning Item::send with 5.1-micro +# +select convert_tz(timediff('0000-00-00 00:00:00', cast('2008-03-26 07:09:06' as datetime)), 'UTC', 'Europe/Moscow'); + +# +# lp:736370 Datetime functions in subquery context cause wrong result and bogus warnings in mysql-5.1-micr +# +create table t1 (f1 integer, f2 date); +insert into t1 values (1,'2011-05-05'),(2,'2011-05-05'),(3,'2011-05-05'),(4,'2011-05-05'),(5,'2011-05-05'),(6, '2011-05-06'); +select * from t1 where 1 and concat(f2)=MAKEDATE(2011, 125); +drop table t1; + +# +# lp:736791 Crash in make_truncated_value_warning with LEAST()/GREATEST/COALESCE +# +create table t1 (f1 timestamp); +insert into t1 values ('0000-00-00 00:00:00'); +select least(1, f1) from t1; +drop table t1; + +# +# lp:737092 Assertion `item->null_value' failed in get_datetime_value in 5.1-micro +# +select now() > coalesce(time('21:43:24'), date('2010-05-03')); + +# +# lp:737104 Crash in DTCollation::set in 5.1-micro +# +create table t1 (f1 timestamp); +select * from t1 where f1 > f1 and f1 <=> timestampadd(hour, 9 , '2010-01-01 16:55:35'); +drop table t1; + +# +# lp:737111 Different behavior for TIMESTAMPADD with 0000-00-00 argument in 5.1-micro +# +create table t1 (f1 date); +insert into t1 values ('0000-00-00'); +select timestampadd(week, 1, f1) from t1; +select timestampadd(week, 1, date("0000-00-00")); +drop table t1; + +# +# lp:737450 Second Assertion `item->null_value' failed in 5.1-micro +# +create table t1 (f2 time not null, f3 datetime, f4 int not null, f5 timestamp); +insert ignore t1 values ('04:38:11','0000-00-00 00:00:00',0,'0000-00-00 00:00:00'); +select least(greatest(f3, f2, f4), f5) from t1; +drop table t1; + +# +# lp:737474 Wrong result with DAY(COALESCE(NULL)) in 5.1-micro +# +select day(coalesce(null)); + +# +# lp:738067 Crash in get_datetime_value() in 5.1-micro +# +select timestamp(greatest('2002-08-20', '0000-00-00 00:00:00')); + +# +# lp:738091 cast(timestamp() AS time returns NULL for 0000-00-00 00:00:00 in 5.1-micro +# +create table t1 (f1 datetime); +insert into t1 values ('0000-00-00 00:00:00'); +select cast(f1 AS time) from t1; +drop table t1; + +select greatest(cast("0-0-0" as date), cast("10:20:05" as time)); +select greatest(cast("0-0-0" as date), cast("10:20:05" as time)) = '0000-00-00'; +select cast(greatest(cast("0-0-0" as date), cast("10:20:05" as time)) as datetime(6)); + +select microsecond('12:00:00.123456'), microsecond('2009-12-31 23:59:59.000010'); + diff --git a/mysql-test/t/func_time_hires.test b/mysql-test/t/func_time_hires.test new file mode 100644 index 00000000000..4dcd51a85ba --- /dev/null +++ b/mysql-test/t/func_time_hires.test @@ -0,0 +1,108 @@ +# +# Test of timestamp with hires resolution; + +set time_zone='+03:00'; +set timestamp=unix_timestamp('2011-01-01 01:01:01.123456'); + +--vertical_results +select sec_to_time(12345), sec_to_time(12345.6789), sec_to_time(1234567e-2); +select now(), curtime(0), utc_timestamp(1), utc_time(2), current_time(3), + current_timestamp(4), localtime(5), localtimestamp(6), time_to_sec('12:34:56'), + time_to_sec('12:34:56.789'); +select sec_to_time(time_to_sec('1:2:3')), sec_to_time(time_to_sec('2:3:4.567890')); +select time_to_sec(sec_to_time(11111)), time_to_sec(sec_to_time(11111.22222)); +--horizontal_results +--error ER_TOO_BIG_PRECISION +select current_timestamp(7); +--error ER_TOO_BIG_PRECISION +select curtime(7); + +--disable_warnings +drop table if exists t1; +--enable_warnings + +create table t1 select sec_to_time(12345), sec_to_time(12345.6789), + sec_to_time(1234567e-2), now(), curtime(0), + utc_timestamp(1), utc_time(2), current_time(3), + current_timestamp(4), localtime(5), localtimestamp(6), + time_to_sec(123456), time_to_sec('12:34:56.789'); +show create table t1; +--query_vertical select * from t1 +drop table t1; + +--query_vertical select unix_timestamp('2011-01-01 01:01:01'), unix_timestamp('2011-01-01 01:01:01.123456'), unix_timestamp(cast('2011-01-01 01:01:01.123456' as datetime(0))), unix_timestamp(cast('2011-01-01 01:01:01.123456' as datetime(4))); +--query_vertical select from_unixtime(unix_timestamp('2011/1/1 1:1:1')), from_unixtime(unix_timestamp('2011/1/1 1:1:1.123456')), from_unixtime(unix_timestamp(cast('2011/1/1 1:1:1.123456' as datetime(0)))), from_unixtime(unix_timestamp(cast('2011/1/1 1:1:1.123456' as datetime(4)))); + +select sec_to_time(3020399.99999), sec_to_time(3020399.999999), sec_to_time(3020399.9999999); +select sec_to_time(-3020399.99999), sec_to_time(-3020399.999999), sec_to_time(-3020399.9999999); +select 20010101000203.000000004 + interval 1 day; +select 20010101000203.4 + interval 1 day; +# +# precision of expressions +# +set @a=cast('2011-01-02 12:13:14' as datetime); +select @a + interval 1 minute; +select @a + interval 10 microsecond; +select @a + interval 10 microsecond + interval 999990 microsecond; + +# +# CAST +# +set @a='2011-01-02 12:13:14.123456'; +create table t1 select CAST(@a AS DATETIME) as dauto, + CAST(@a AS DATETIME(0)) as d0, + CAST(@a AS DATETIME(1)) as d1, + CAST(@a AS DATETIME(2)) as d2, + CAST(@a AS DATETIME(3)) as d3, + CAST(@a AS DATETIME(4)) as d4, + CAST(@a AS DATETIME(5)) as d5, + CAST(@a AS DATETIME(6)) as d6, + CAST(@a AS TIME) as tauto, + CAST(@a AS TIME(0)) as t0, + CAST(@a AS TIME(1)) as t1, + CAST(@a AS TIME(2)) as t2, + CAST(@a AS TIME(3)) as t3, + CAST(@a AS TIME(4)) as t4, + CAST(@a AS TIME(5)) as t5, + CAST(@a AS TIME(6)) as t6; +show create table t1; +--query_vertical select * from t1 +drop table t1; +explain extended select cast(cast(@a as datetime(4)) as time(0)); +select cast(cast(@a as time(2)) as time(6)); + +--error ER_TOO_BIG_PRECISION +select CAST(@a AS DATETIME(7)); + +# +# CONVERT_TZ +# +SELECT CONVERT_TZ('2011-01-02 12:00:00', '+00:00', '+03:00'); +SELECT CONVERT_TZ('2011-01-02 12:00:00.123', '+00:00', '+03:00'); +SELECT CONVERT_TZ('2011-01-02 12:00:00.123456', '+00:00', '+03:00'); +SELECT CONVERT_TZ(CAST('2010-10-10 10:10:10.123456' AS DATETIME(4)), '+00:00', '+03:00'); + +# +# Field::store_time() +# +create table t1 (a varchar(200)); +insert t1 values (now(6)); +select * from t1; +drop table t1; + +# +# lp:736358 Unexpected increased timestamp resolution with UNION +# +# timestamp(6) case is fixed: +create table t1 (f1 timestamp(6)); +insert into t1 values ('2002-07-15 21:00:00'); +select time(f1) from t1; +select time(f1) from t1 union all select time(f1 + interval 1 second) from t1; +alter table t1 modify f1 timestamp; +select time(f1) from t1; +select time(f1) from t1 union all select time(f1 + interval 1 second) from t1; +# but the effect cannot be eliminated completely: +alter table t1 modify f1 varchar(100); +select time(f1) from t1; +select time(f1) from t1 union all select time(f1 + interval 1 second) from t1; +drop table t1; diff --git a/mysql-test/t/group_by.test b/mysql-test/t/group_by.test index 7f227398a95..f739870ca07 100644 --- a/mysql-test/t/group_by.test +++ b/mysql-test/t/group_by.test @@ -1043,10 +1043,6 @@ EXPLAIN SELECT a, SUM(b) FROM t2 IGNORE INDEX (a) GROUP BY a LIMIT 2; EXPLAIN SELECT 1 FROM t2 WHERE a IN (SELECT a FROM t1 USE INDEX (i2) IGNORE INDEX (i2)); -SHOW VARIABLES LIKE 'old'; ---error ER_INCORRECT_GLOBAL_LOCAL_VAR -SET @@old = off; - DROP TABLE t1, t2; # diff --git a/mysql-test/t/group_min_max.test b/mysql-test/t/group_min_max.test index fa52da63195..9258207050e 100644 --- a/mysql-test/t/group_min_max.test +++ b/mysql-test/t/group_min_max.test @@ -406,11 +406,61 @@ explain select a1,a2,b,min(c),max(c) from t1 where exists ( select * from t2 where t2.c = t1.c ) group by a1,a2,b; +select a1,a2,b,min(c),max(c) from t1 +where exists ( select * from t2 where t2.c = t1.c ) +group by a1,a2,b; + # the sub-select is unrelated to MIN/MAX explain select a1,a2,b,min(c),max(c) from t1 where exists ( select * from t2 where t2.c > 'b1' ) group by a1,a2,b; +select a1,a2,b,min(c),max(c) from t1 +where exists ( select * from t2 where t2.c > 'b1' ) +group by a1,a2,b; + +# correlated subselect that doesn't reference the min/max argument +explain select a1,a2,b,c,min(c), max(c) from t1 +where exists ( select * from t2 where t1.b > 'a' and t2.c > 'b1' ) +group by a1,a2,b; + +select a1,a2,b,c,min(c), max(c) from t1 +where exists ( select * from t2 where t1.b > 'a' and t2.c > 'b1' ) +group by a1,a2,b; + +explain select a1,a2,b,c,min(c), max(c) from t1 +where exists ( select * from t2 + where t2.c in (select c from t3 where t3.c > t1.b) and + t2.c > 'b1' ) +group by a1,a2,b; + +select a1,a2,b,c,min(c), max(c) from t1 +where exists ( select * from t2 + where t2.c in (select c from t3 where t3.c > t1.b) and + t2.c > 'b1' ) +group by a1,a2,b; + +# correlated subselect that references the min/max argument +explain select a1,a2,b,c,min(c), max(c) from t1 +where exists ( select * from t2 where t1.c > 'a' and t2.c > 'b1' ) +group by a1,a2,b; + +select a1,a2,b,c,min(c), max(c) from t1 +where exists ( select * from t2 where t1.c > 'a' and t2.c > 'b1' ) +group by a1,a2,b; + +explain select a1,a2,b,c,min(c), max(c) from t1 +where exists ( select * from t2 + where t2.c in (select c from t3 where t3.c > t1.c) and + t2.c > 'b1' ) +group by a1,a2,b; + +select a1,a2,b,c,min(c), max(c) from t1 +where exists ( select * from t2 + where t2.c in (select c from t3 where t3.c > t1.c) and + t2.c > 'b1' ) +group by a1,a2,b; + # A,B,C) Predicates referencing mixed classes of attributes # plans diff --git a/mysql-test/t/handler_innodb.test b/mysql-test/t/handler_innodb.test deleted file mode 100644 index 02982716f78..00000000000 --- a/mysql-test/t/handler_innodb.test +++ /dev/null @@ -1,20 +0,0 @@ -# t/handler_innodb.test -# -# test of HANDLER ... -# -# Last update: -# 2006-07-31 ML test refactored (MySQL 5.1) -# code of t/handler.test and t/innodb_handler.test united -# main testing code put into include/handler.inc -# rename t/innodb_handler.test to t/handler_innodb.test -# - -# should work in embedded server after mysqltest is fixed ---source include/not_embedded.inc - ---source include/have_innodb.inc -let $engine_type= InnoDB; -let $other_engine_type= MEMORY; -let $other_handler_engine_type= MyISAM; - ---source include/handler.inc diff --git a/mysql-test/t/handler_myisam.test b/mysql-test/t/handler_myisam.test deleted file mode 100644 index e78072ef8a0..00000000000 --- a/mysql-test/t/handler_myisam.test +++ /dev/null @@ -1,100 +0,0 @@ -# t/handler_myisam.test -# -# test of HANDLER ... -# -# Last update: -# 2006-07-31 ML test refactored (MySQL 5.1) -# code of t/handler.test and t/innodb_handler.test united -# main testing code put into include/handler.inc -# rename t/handler.test to t/handler_myisam.test -# - -# should work in embedded server after mysqltest is fixed ---source include/not_embedded.inc - -let $engine_type= MyISAM; -let $other_engine_type= MEMORY; -# There is unfortunately no other all time available storage engine -# which supports the handler interface -let $other_handler_engine_type= MyISAM; - ---source include/handler.inc - ---echo # ---echo # BUG #46456: HANDLER OPEN + TRUNCATE + DROP (temporary) TABLE, crash ---echo # -CREATE TABLE t1 AS SELECT 1 AS f1; -HANDLER t1 OPEN; -TRUNCATE t1; ---error ER_UNKNOWN_TABLE -HANDLER t1 READ FIRST; -DROP TABLE t1; - -CREATE TEMPORARY TABLE t1 AS SELECT 1 AS f1; -HANDLER t1 OPEN; -TRUNCATE t1; ---error ER_UNKNOWN_TABLE -HANDLER t1 READ FIRST; -DROP TABLE t1; - ---echo # ---echo # BUG#51877 - HANDLER interface causes invalid memory read ---echo # -CREATE TABLE t1(a INT, KEY(a)); -HANDLER t1 OPEN; -HANDLER t1 READ a FIRST; -INSERT INTO t1 VALUES(1); -HANDLER t1 READ a NEXT; -HANDLER t1 CLOSE; -DROP TABLE t1; - - ---echo # ---echo # Bug #54007: assert in ha_myisam::index_next , HANDLER ---echo # -CREATE TABLE t1(a INT, b INT, PRIMARY KEY(a), KEY b(b), KEY ab(a, b)); - -HANDLER t1 OPEN; -HANDLER t1 READ FIRST; -HANDLER t1 READ `PRIMARY` NEXT; -HANDLER t1 READ ab NEXT; -HANDLER t1 READ b NEXT; -HANDLER t1 READ NEXT; -HANDLER t1 CLOSE; - -INSERT INTO t1 VALUES (2, 20), (1, 10), (4, 40), (3, 30); -HANDLER t1 OPEN; -HANDLER t1 READ FIRST; -HANDLER t1 READ NEXT; -HANDLER t1 READ `PRIMARY` NEXT; -HANDLER t1 READ `PRIMARY` NEXT; -HANDLER t1 READ ab NEXT; -HANDLER t1 READ ab NEXT; -HANDLER t1 READ b NEXT; -HANDLER t1 READ b NEXT; -HANDLER t1 READ b NEXT; -HANDLER t1 READ b NEXT; -HANDLER t1 READ b NEXT; -HANDLER t1 READ NEXT; -HANDLER t1 READ NEXT; -HANDLER t1 READ NEXT; -HANDLER t1 CLOSE; - -HANDLER t1 OPEN; -HANDLER t1 READ FIRST; -HANDLER t1 READ `PRIMARY` PREV; -HANDLER t1 READ `PRIMARY` PREV; -HANDLER t1 READ b PREV; -HANDLER t1 READ b PREV; -HANDLER t1 CLOSE; - -HANDLER t1 OPEN; -HANDLER t1 READ FIRST; -HANDLER t1 READ `PRIMARY` PREV LIMIT 3; -HANDLER t1 READ b NEXT LIMIT 5; -HANDLER t1 CLOSE; - -DROP TABLE t1; - - ---echo End of 5.1 tests diff --git a/mysql-test/t/handlersocket.test b/mysql-test/t/handlersocket.test new file mode 100644 index 00000000000..6a7b65797c5 --- /dev/null +++ b/mysql-test/t/handlersocket.test @@ -0,0 +1,10 @@ +--source include/not_windows_embedded.inc + +if (`select length('$HANDLERSOCKET_SO') = 0`) { + skip handlersocket plugin is not built; +} + +install plugin handlersocket soname 'handlersocket.so'; +--query_vertical select plugin_name, plugin_version, plugin_status, plugin_type, plugin_library, plugin_library_version, plugin_author, plugin_description plugin_license, plugin_maturity, plugin_auth_version from information_schema.plugins where plugin_name = 'handlersocket' +uninstall plugin handlersocket; + diff --git a/mysql-test/t/having.test b/mysql-test/t/having.test index 2ed8b40b858..01342fdf5fa 100644 --- a/mysql-test/t/having.test +++ b/mysql-test/t/having.test @@ -591,3 +591,28 @@ DROP TABLE t1,t2; --echo End of 5.1 tests + +--echo # +--echo # LP bug #791761: MAX over an empty join + HAVING +--echo # + +CREATE TABLE t1 (a int, b int , KEY (b)) ; +INSERT INTO t1 VALUES (3,1); + +CREATE TABLE t2 (a int NOT NULL ) ; +INSERT INTO t2 VALUES (29); + +SELECT MAX(t1.b) FROM t1,t2 WHERE t2.a > 0 HAVING MAX(t1.b) <> 6; +SELECT MAX(t1.b) FROM t1,t2 WHERE t2.a > 0 HAVING MAX(t1.b) IS NULL; + +EXPLAIN +SELECT MAX(t1.b) FROM t1,t2 WHERE t2.a < 0 HAVING MAX(t1.b) <> 6; +SELECT MAX(t1.b) FROM t1,t2 WHERE t2.a < 0 HAVING MAX(t1.b) <> 6; + +CREATE TABLE t3 ( f3 int) ; +INSERT INTO t3 VALUES (NULL); + +SELECT MAX(t1.b) AS f FROM t1 JOIN t2 ON t2.a != 0 + WHERE (SELECT f3 FROM t3) <> 0 HAVING f <> 6 ; + +DROP TABLE t1,t2,t3; diff --git a/mysql-test/t/heap_btree.test b/mysql-test/t/heap_btree.test index 637c6ba1c81..02c09f52263 100644 --- a/mysql-test/t/heap_btree.test +++ b/mysql-test/t/heap_btree.test @@ -263,3 +263,19 @@ DELETE a1 FROM t1 AS a1, t1 AS a2 WHERE a1.a=a2.a; DROP TABLE t1; --echo End of 5.0 tests +-- echo # bit index in heap tables + +create table t1 (a bit(63) not null) engine=heap; +insert into t1 values (869751),(736494),(226312),(802616),(728912); +alter table t1 add unique uniq_id using BTREE (a); +select 0+a from t1 where a > 736494; +explain select 0+a from t1 where a > 736494; +select 0+a from t1 where a = 736494; +explain select 0+a from t1 where a = 736494; +select 0+a from t1 where a=869751 or a=736494; +explain select 0+a from t1 where a=869751 or a=736494; +select 0+a from t1 where a in (869751,736494,226312,802616); +explain select 0+a from t1 where a in (869751,736494,226312,802616); +drop table t1; + +--echo End of 5.3 tests diff --git a/mysql-test/t/heap_hash.test b/mysql-test/t/heap_hash.test index 748347021fc..80ae01e9547 100644 --- a/mysql-test/t/heap_hash.test +++ b/mysql-test/t/heap_hash.test @@ -285,6 +285,23 @@ DROP TABLE t1; --echo End of 5.0 tests +-- echo # bit index in heap tables + +create table t1 (a bit(63) not null) engine=heap; +insert into t1 values (869751),(736494),(226312),(802616),(728912); +alter table t1 add unique uniq_id using HASH (a); +select 0+a from t1 where a > 736494; +explain select 0+a from t1 where a > 736494; +select 0+a from t1 where a = 736494; +explain select 0+a from t1 where a = 736494; +select 0+a from t1 where a=869751 or a=736494; +explain select 0+a from t1 where a=869751 or a=736494; +select 0+a from t1 where a in (869751,736494,226312,802616); +explain select 0+a from t1 where a in (869751,736494,226312,802616); +drop table t1; + +--echo End of 5.3 tests + --echo # --echo # Bug #55472: Assertion failed in heap_rfirst function of hp_rfirst.c --echo # on DELETE statement @@ -300,4 +317,3 @@ DELETE FROM t1 WHERE col_int_nokey = 5 ORDER BY col_int_key LIMIT 2; DROP TABLE t1; --echo End of 5.5 tests - diff --git a/mysql-test/t/index_intersect.test b/mysql-test/t/index_intersect.test new file mode 100644 index 00000000000..c2834e685eb --- /dev/null +++ b/mysql-test/t/index_intersect.test @@ -0,0 +1,453 @@ +--disable_warnings +DROP TABLE IF EXISTS t1,t2,t3,t4; +DROP DATABASE IF EXISTS world; +--enable_warnings + +set names utf8; + +CREATE DATABASE world; + +use world; + +--source include/world_schema.inc + +--disable_query_log +--disable_result_log +--disable_warnings +--source include/world.inc +--enable_warnings +--enable_result_log +--enable_query_log + +SELECT COUNT(*) FROM Country; +SELECT COUNT(*) FROM City; +SELECT COUNT(*) FROM CountryLanguage; + +CREATE INDEX Name ON City(Name); + +--disable_query_log +--disable_result_log +--disable_warnings +ANALYZE TABLE City; +--enable_warnings +--enable_result_log +--enable_query_log + +SET SESSION optimizer_switch='index_merge_sort_intersection=on'; + +SELECT COUNT(*) FROM City; + +# The output of the next 6 queries tells us about selectivities +# of the conditions utilized in 4 queries following after them + +SELECT COUNT(*) FROM City WHERE Name LIKE 'C%'; +SELECT COUNT(*) FROM City WHERE Name LIKE 'M%'; +SELECT COUNT(*) FROM City WHERE Population > 1000000; +SELECT COUNT(*) FROM City WHERE Population > 1500000; +SELECT COUNT(*) FROM City WHERE Population > 300000; +SELECT COUNT(*) FROM City WHERE Population > 7000000; + +# The pattern of the WHERE condition used in the following 4 queries is +# range(key1) AND range(key2) +# Varying values of the constants in the conjuncts of the condition +# we can get either an index intersection retrieval over key1 and key2 +# or a range index scan for one of these indexes + +--replace_column 9 # +EXPLAIN +SELECT * FROM City WHERE + Name LIKE 'C%' AND Population > 1000000; + +--replace_column 9 # +EXPLAIN +SELECT * FROM City WHERE + Name LIKE 'M%' AND Population > 1500000; + +--replace_column 9 # +EXPLAIN +SELECT * FROM City + WHERE Name LIKE 'M%' AND Population > 300000; + +--replace_column 9 # +EXPLAIN +SELECT * FROM City + WHERE Name LIKE 'M%' AND Population > 7000000; + + +# The following 8 queries check that +# the previous 4 plans are valid and return +# the correct results when executed + +--sorted_result +SELECT * FROM City USE INDEX () + WHERE Name LIKE 'C%' AND Population > 1000000; +--sorted_result +SELECT * FROM City + WHERE Name LIKE 'C%' AND Population > 1000000; + +--sorted_result +SELECT * FROM City USE INDEX () + WHERE Name LIKE 'M%' AND Population > 1500000; +--sorted_result +SELECT * FROM City + WHERE Name LIKE 'M%' AND Population > 1500000; + +--sorted_result +SELECT * FROM City USE INDEX () + WHERE Name LIKE 'M%' AND Population > 300000; +--sorted_result +SELECT * FROM City + WHERE Name LIKE 'M%' AND Population > 300000; + + +SELECT * FROM City USE INDEX () + WHERE Name LIKE 'M%' AND Population > 7000000; + +SELECT * FROM City + WHERE Name LIKE 'M%' AND Population > 7000000; + + +# The output of the next 7 queries tells us about selectivities +# of the conditions utilized in 3 queries following after them + +SELECT COUNT(*) FROM City WHERE Name BETWEEN 'M' AND 'N'; +SELECT COUNT(*) FROM City WHERE Name BETWEEN 'G' AND 'J'; +SELECT COUNT(*) FROM City WHERE Name BETWEEN 'G' AND 'K'; +SELECT COUNT(*) FROM City WHERE Population > 1000000; +SELECT COUNT(*) FROM City WHERE Population > 500000; +SELECT COUNT(*) FROM City WHERE Country LIKE 'C%'; +SELECT COUNT(*) FROM City WHERE Country LIKE 'B%'; + + +# The pattern of the WHERE condition used in the following 3 queries is +# range(key1) AND range(key2) AND range(key3) +# Varying values of the constants in the conjuncts of the condition +# we can get index intersection over different pairs of keys: +# over(key1,key2), over(key1,key3) and over(key2,key3) + + +--replace_column 9 # +EXPLAIN +SELECT * FROM City + WHERE Name BETWEEN 'M' AND 'N' AND Population > 1000000 AND Country LIKE 'C%'; + +--replace_column 9 # +EXPLAIN +SELECT * FROM City + WHERE Name BETWEEN 'G' AND 'J' AND Population > 1000000 AND Country LIKE 'B%'; + +--replace_column 7 # 9 # +--replace_result Population,Country,Name Population,Name,Country +EXPLAIN +SELECT * FROM City + WHERE Name BETWEEN 'G' AND 'K' AND Population > 500000 AND Country LIKE 'C%'; + + +# The following 6 queries check that +# the previous 3 plans are valid and return +# the correct results when executed + + +SELECT * FROM City USE INDEX () + WHERE Name BETWEEN 'M' AND 'N' AND Population > 1000000 AND Country LIKE 'C%'; + +SELECT * FROM City + WHERE Name BETWEEN 'M' AND 'N' AND Population > 1000000 AND Country LIKE 'C%'; + + +SELECT * FROM City USE INDEX () + WHERE Name BETWEEN 'G' AND 'J' AND Population > 1000000 AND Country LIKE 'B%'; + +SELECT * FROM City + WHERE Name BETWEEN 'G' AND 'J' AND Population > 1000000 AND Country LIKE 'B%'; + + +SELECT * FROM City USE INDEX () + WHERE Name BETWEEN 'G' AND 'K' AND Population > 500000 AND Country LIKE 'C%'; + +SELECT * FROM City + WHERE Name BETWEEN 'G' AND 'K' AND Population > 500000 AND Country LIKE 'C%'; + + +# The output of the next 12 queries tells us about selectivities +# of the conditions utilized in 5 queries following after them + +SELECT COUNT(*) FROM City WHERE ID BETWEEN 501 AND 1000; +SELECT COUNT(*) FROM City WHERE ID BETWEEN 1 AND 500; +SELECT COUNT(*) FROM City WHERE ID BETWEEN 2001 AND 2500; +SELECT COUNT(*) FROM City WHERE ID BETWEEN 3701 AND 4000; +SELECT COUNT(*) FROM City WHERE Population > 700000; +SELECT COUNT(*) FROM City WHERE Population > 1000000; +SELECT COUNT(*) FROM City WHERE Population > 300000; +SELECT COUNT(*) FROM City WHERE Population > 600000; +SELECT COUNT(*) FROM City WHERE Country LIKE 'C%'; +SELECT COUNT(*) FROM City WHERE Country LIKE 'A%'; +SELECT COUNT(*) FROM City WHERE Country LIKE 'H%'; +SELECT COUNT(*) FROM City WHERE Country BETWEEN 'S' AND 'Z'; + + +# The pattern of the WHERE condition used in the following 5 queries is +# range(key1) AND range(key2) AND range(key3) +# with key1 happens to be a primary key (it matters only for InnoDB) +# Varying values of the constants in the conjuncts of the condition +# we can get index intersection either over all three keys, or over +# different pairs, or a range scan over one of these keys. +# Bear in mind that the condition (Country LIKE 'A%') is actually +# equivalent to the condition (Country BETWEEN 'A' AND 'B') for the +# tested instance the table City. + + +--replace_column 9 # +EXPLAIN +SELECT * FROM City + WHERE ID BETWEEN 501 AND 1000 AND Population > 700000 AND Country LIKE 'C%'; + +--replace_column 9 # +EXPLAIN +SELECT * FROM City + WHERE ID BETWEEN 1 AND 500 AND Population > 1000000 AND Country LIKE 'A%'; + +--replace_column 9 # +EXPLAIN +SELECT * FROM City + WHERE ID BETWEEN 2001 AND 2500 AND Population > 300000 AND Country LIKE 'H%'; + +--replace_column 9 # +EXPLAIN +SELECT * FROM City + WHERE ID BETWEEN 3701 AND 4000 AND Population > 1000000 + AND Country BETWEEN 'S' AND 'Z'; + +--replace_column 9 # +EXPLAIN +SELECT * FROM City + WHERE ID BETWEEN 3001 AND 4000 AND Population > 600000 + AND Country BETWEEN 'S' AND 'Z' ; + + +# The following 10 queries check that +# the previous 5 plans are valid and return +# the correct results when executed + + +SELECT * FROM City USE INDEX () + WHERE ID BETWEEN 501 AND 1000 AND Population > 700000 AND Country LIKE 'C%'; + +SELECT * FROM City + WHERE ID BETWEEN 501 AND 1000 AND Population > 700000 AND Country LIKE 'C%'; + +--sorted_result +SELECT * FROM City USE INDEX () + WHERE ID BETWEEN 1 AND 500 AND Population > 1000000 AND Country LIKE 'A%'; +--sorted_result +SELECT * FROM City + WHERE ID BETWEEN 1 AND 500 AND Population > 1000000 AND Country LIKE 'A%'; + + +SELECT * FROM City USE INDEX () + WHERE ID BETWEEN 2001 AND 2500 AND Population > 300000 AND Country LIKE 'H%'; + +SELECT * FROM City + WHERE ID BETWEEN 2001 AND 2500 AND Population > 300000 AND Country LIKE 'H%'; + +--sorted_result +SELECT * FROM City USE INDEX () + WHERE ID BETWEEN 3701 AND 4000 AND Population > 700000 + AND Country BETWEEN 'S' AND 'Z'; +--sorted_result +SELECT * FROM City + WHERE ID BETWEEN 3701 AND 4000 AND Population > 700000 + AND Country BETWEEN 'S' AND 'Z'; + +--sorted_result +SELECT * FROM City USE INDEX () + WHERE ID BETWEEN 3001 AND 4000 AND Population > 600000 + AND Country BETWEEN 'S' AND 'Z' ; +--sorted_result +SELECT * FROM City + WHERE ID BETWEEN 3001 AND 4000 AND Population > 600000 + AND Country BETWEEN 'S' AND 'Z' ; + + +SET SESSION sort_buffer_size = 2048; + + +# The following EXPLAIN command demonstrate that the execution plans +# may be different if sort_buffer_size is set to a small value + + +--replace_column 9 # +EXPLAIN +SELECT * FROM City WHERE + Name LIKE 'C%' AND Population > 1000000; + +--replace_column 9 # +EXPLAIN +SELECT * FROM City WHERE + Name LIKE 'M%' AND Population > 1500000; + + +--replace_column 9 # +EXPLAIN +SELECT * FROM City + WHERE Name BETWEEN 'G' AND 'J' AND Population > 1000000 AND Country LIKE 'B%'; + +--replace_column 9 # +EXPLAIN +SELECT * FROM City + WHERE Name BETWEEN 'G' AND 'J' AND Population > 500000 AND Country LIKE 'C%'; + + +--replace_column 9 # +EXPLAIN +SELECT * FROM City + WHERE ID BETWEEN 1 AND 500 AND Population > 1000000 AND Country LIKE 'A%'; + +--replace_column 9 # +EXPLAIN +SELECT * FROM City + WHERE ID BETWEEN 3001 AND 4000 AND Population > 600000 + AND Country BETWEEN 'S' AND 'Z'; + + +#Yet the query themselves return the correct results in this case as well + +--sorted_result +SELECT * FROM City WHERE + Name LIKE 'C%' AND Population > 1000000; + +SELECT * FROM City WHERE + Name LIKE 'M%' AND Population > 1500000; + + +SELECT * FROM City + WHERE Name BETWEEN 'G' AND 'J' AND Population > 700000 AND Country LIKE 'B%'; + +SELECT * FROM City + WHERE Name BETWEEN 'G' AND 'J' AND Population > 500000 AND Country LIKE 'C%'; + + +SELECT * FROM City + WHERE ID BETWEEN 1 AND 500 AND Population > 1000000 AND Country LIKE 'A%'; +--sorted_result +SELECT * FROM City + WHERE ID BETWEEN 3001 AND 4000 AND Population > 600000 + AND Country BETWEEN 'S' AND 'Z'; + + +SET SESSION sort_buffer_size = default; + +# Instead of the index on the column Country create two compound indexes +# including this column as the first component + +DROP INDEX Country ON City; + +CREATE INDEX CountryID ON City(Country,ID); +CREATE INDEX CountryName ON City(Country,Name); + +--disable_query_log +--disable_result_log +--disable_warnings +ANALYZE TABLE City; +--enable_warnings +--enable_result_log +--enable_query_log + +# Check that the first component of a compound index can be used for +# index intersection, even in the cases when we have a ref access +# for this component + +--replace_column 9 # +EXPLAIN +SELECT * FROM City + WHERE Country LIKE 'M%' AND Population > 1000000; + +--replace_column 9 # +EXPLAIN +SELECT * FROM City + WHERE Country='CHN' AND Population > 1500000; + +--replace_column 9 # +EXPLAIN +SELECT * FROM City + WHERE Country='CHN' AND Population > 1500000 AND Name LIKE 'C%'; + + +# Check that the previous 3 plans return the right results when executed + +--sorted_result +SELECT * FROM City USE INDEX () + WHERE Country LIKE 'M%' AND Population > 1000000; +--sorted_result +SELECT * FROM City + WHERE Country LIKE 'M%' AND Population > 1000000; + +--sorted_result +SELECT * FROM City USE INDEX () + WHERE Country='CHN' AND Population > 1500000; +--sorted_result +SELECT * FROM City + WHERE Country='CHN' AND Population > 1500000; + + +SELECT * FROM City USE INDEX () + WHERE Country='CHN' AND Population > 1500000 AND Name LIKE 'C%'; + +SELECT * FROM City + WHERE Country='CHN' AND Population > 1500000 AND Name LIKE 'C%'; + + +# +# Bug #754521: wrong cost of index intersection leading +# to the choice of a suboptimal execution plan +# + +--replace_column 9 # +EXPLAIN +SELECT * FROM City, Country + WHERE City.Name LIKE 'C%' AND City.Population > 1000000 AND + Country.Code=City.Country; + +DROP DATABASE world; + +use test; + +# +# Bug #684086: crash with EXPLAIN in InnoDB for index intersection +# of two indexes one of which is primary +# + +CREATE TABLE t1 ( + f1 int, + f4 varchar(32), + f5 int, + PRIMARY KEY (f1), + KEY (f4) +) ENGINE=InnoDB; + +INSERT INTO t1 VALUES + (5,'H',1), (9,'g',0), (527,'i',0), (528,'y',1), (529,'S',6), + (530,'m',7), (531,'b',2), (532,'N',1), (533,'V',NULL), (534,'l',1), + (535,'M',0), (536,'w',1), (537,'j',5), (538,'l',0), (539,'n',2), + (540,'m',2), (541,'r',2), (542,'l',2), (543,'h',3),(544,'o',0), + (956,'h',0), (957,'g',0), (958,'W',5), (959,'s',3), (960,'w',0), + (961,'q',0), (962,'e',NULL), (963,'u',7), (964,'q',1), (965,'N',NULL), + (966,'e',0), (967,'t',3), (968,'e',6), (969,'f',NULL), (970,'j',0), + (971,'s',3), (972,'I',0), (973,'h',4), (974,'g',1), (975,'s',0), + (976,'r',3), (977,'x',1), (978,'v',8), (979,'j',NULL), (980,'z',7), + (981,'t',9), (982,'j',5), (983,'u',NULL), (984,'g',6), (985,'w',1), + (986,'h',1), (987,'v',0), (988,'v',0), (989,'c',2), (990,'b',7), + (991,'z',0), (992,'M',1), (993,'u',2), (994,'r',2), (995,'b',4), + (996,'A',2), (997,'u',0), (998,'a',0), (999,'j',2), (1,'I',2); + +--replace_column 9 # +EXPLAIN +SELECT * FROM t1 +WHERE (f1 < 535 OR f1 > 985) AND ( f4='r' OR f4 LIKE 'a%' ) ; + +SELECT * FROM t1 +WHERE (f1 < 535 OR f1 > 985) AND ( f4='r' OR f4 LIKE 'a%' ) ; + +DROP TABLE t1; + +SET SESSION optimizer_switch='index_merge_sort_intersection=on'; diff --git a/mysql-test/t/index_intersect_innodb.test b/mysql-test/t/index_intersect_innodb.test new file mode 100644 index 00000000000..22c0e807558 --- /dev/null +++ b/mysql-test/t/index_intersect_innodb.test @@ -0,0 +1,7 @@ +--source include/have_innodb.inc + +SET SESSION STORAGE_ENGINE='InnoDB'; + +--source t/index_intersect.test + +SET SESSION STORAGE_ENGINE=DEFAULT; diff --git a/mysql-test/t/index_merge_innodb.test b/mysql-test/t/index_merge_innodb.test index 94a4090978a..e2aa5f45a2b 100644 --- a/mysql-test/t/index_merge_innodb.test +++ b/mysql-test/t/index_merge_innodb.test @@ -15,19 +15,21 @@ --source include/have_innodb.inc let $engine_type= InnoDB; -# According to Oracle: "InnoDB's estimate for the index cardinality -# depends on a pseudo random number generator (it picks up random -# pages to sample). After an optimization that was made in r2625 two -# EXPLAINs started returning a different number of rows (3 instead of -# 4)", so: -let $index_merge_random_rows_in_EXPLAIN = 1; # InnoDB does not support Merge tables (affects include/index_merge1.inc) let $merge_table_support= 0; -# -- [DISABLED Bug#45727] +set @optimizer_switch_save= @@optimizer_switch; +set optimizer_switch='index_merge_sort_intersection=off'; + +# The first two tests are disabled because of non deterministic explain output. +# If include/index_merge1.inc can be enabled for InnoDB and all other +# storage engines, please remove the subtest for Bug#21277 from +# include/index_merge2.inc. +# This test exists already in include/index_merge1.inc. # --source include/index_merge1.inc # --source include/index_merge_ror.inc -# --source include/index_merge2.inc +#the next one is disabled in MySQL too: Bug#45727 +--source include/index_merge2.inc --source include/index_merge_2sweeps.inc --source include/index_merge_ror_cpk.inc @@ -66,12 +68,14 @@ INSERT INTO t1 VALUES (1000000, 0, 0); SET SESSION sort_buffer_size = 1024*36; +# We have to use FORCE INDEX here as Innodb gives inconsistent estimates +# which causes different query plans. EXPLAIN SELECT COUNT(*) FROM - (SELECT * FROM t1 + (SELECT * FROM t1 FORCE INDEX(primary,idx) WHERE a BETWEEN 2 AND 7 OR pk=1000000) AS t; SELECT COUNT(*) FROM - (SELECT * FROM t1 + (SELECT * FROM t1 FORCE INDEX(primary,idx) WHERE a BETWEEN 2 AND 7 OR pk=1000000) AS t; --replace_column 9 # @@ -84,3 +88,38 @@ SELECT COUNT(*) FROM WHERE a BETWEEN 2 AND 7 OR pk=1000000) AS t; DROP TABLE t1; + +--echo # +--echo # Testcase Backport: BUG#48093: 6.0 Server not processing equivalent IN clauses properly +--echo # with Innodb tables +--echo # + +CREATE TABLE t1 ( + i int(11) DEFAULT NULL, + v1 varchar(1) DEFAULT NULL, + v2 varchar(20) DEFAULT NULL, + KEY i (i), + KEY v (v1,i) +) ENGINE=innodb; + +INSERT INTO t1 VALUES (1,'f','no'); +INSERT INTO t1 VALUES (2,'u','yes-u'); +INSERT INTO t1 VALUES (2,'h','yes-h'); +INSERT INTO t1 VALUES (3,'d','no'); + +--echo +SELECT v2 +FROM t1 +WHERE v1 IN ('f', 'd', 'h', 'u' ) AND i = 2; + +--echo +--echo # Should not use index_merge +EXPLAIN +SELECT v2 +FROM t1 +WHERE v1 IN ('f', 'd', 'h', 'u' ) AND i = 2; + +DROP TABLE t1; + +set optimizer_switch= @optimizer_switch_save; + diff --git a/mysql-test/t/index_merge_myisam.test b/mysql-test/t/index_merge_myisam.test index b3514e3f053..5431c6dba2b 100644 --- a/mysql-test/t/index_merge_myisam.test +++ b/mysql-test/t/index_merge_myisam.test @@ -14,6 +14,10 @@ let $engine_type= MyISAM; # MyISAM supports Merge tables let $merge_table_support= 1; +set @optimizer_switch_save= @@optimizer_switch; + +set optimizer_switch='index_merge_sort_intersection=off'; + --source include/index_merge1.inc --source include/index_merge_ror.inc --source include/index_merge2.inc @@ -92,7 +96,7 @@ set optimizer_switch='default,index_merge=off'; explain select * from t1 where a=10 and b=10; --echo No intersect if it is disabled: -set optimizer_switch='default,index_merge_intersection=off'; +set optimizer_switch='default,index_merge_sort_intersection=off,index_merge_intersection=off'; explain select * from t1 where a=10 and b=10; --echo Do intersect when union was disabled @@ -121,3 +125,5 @@ set optimizer_switch=default; drop table t0, t1; +set optimizer_switch= @optimizer_switch_save; + diff --git a/mysql-test/t/information_schema_all_engines-master.opt b/mysql-test/t/information_schema_all_engines-master.opt new file mode 100644 index 00000000000..9104e73e554 --- /dev/null +++ b/mysql-test/t/information_schema_all_engines-master.opt @@ -0,0 +1 @@ +--loose-skip-safemalloc --loose-mutex-deadlock-detector=0 diff --git a/mysql-test/t/information_schema_parameters.test b/mysql-test/t/information_schema_parameters.test index 254daa5d314..3f0b11cba5f 100644 --- a/mysql-test/t/information_schema_parameters.test +++ b/mysql-test/t/information_schema_parameters.test @@ -32,7 +32,7 @@ USE INFORMATION_SCHEMA; SHOW CREATE TABLE INFORMATION_SCHEMA.PARAMETERS; # embedded server does not display privileges ---replace_column 18 # +--replace_column 19 # query_vertical SELECT * FROM information_schema.columns WHERE table_schema = 'information_schema' AND table_name = 'parameters' diff --git a/mysql-test/t/information_schema_routines.test b/mysql-test/t/information_schema_routines.test index 2d80f67fb72..c578176a85d 100644 --- a/mysql-test/t/information_schema_routines.test +++ b/mysql-test/t/information_schema_routines.test @@ -60,7 +60,7 @@ USE INFORMATION_SCHEMA; SHOW CREATE TABLE INFORMATION_SCHEMA.ROUTINES; # embedded server does not display privileges ---replace_column 18 # +--replace_column 19 # query_vertical SELECT * FROM information_schema.columns WHERE table_schema = 'information_schema' AND table_name = 'routines' @@ -84,7 +84,7 @@ USE i_s_routines_test; --error ER_PARSE_ERROR CREATE FUNCTION test_func1 (s char(20) RETURNS CHAR(50) RETURN CONCAT('Hello', ,s,'!'); ---replace_column 23 <created> 24 <modified> +--replace_column 24 <created> 25 <modified> SELECT * FROM INFORMATION_SCHEMA.ROUTINES WHERE ROUTINE_SCHEMA = 'i_s_routines_test' AND ROUTINE_NAME = 'test_func1'; @@ -103,11 +103,11 @@ USE i_s_routines_test; CREATE FUNCTION test_func1 (s char(20)) RETURNS CHAR(50) RETURN CONCAT('Hello, ',s,'!'); ---replace_column 23 <created> 24 <modified> +--replace_column 24 <created> 25 <modified> SELECT * FROM INFORMATION_SCHEMA.ROUTINES WHERE ROUTINE_SCHEMA = 'i_s_routines_test' AND ROUTINE_NAME = 'test_func1'; DROP FUNCTION test_func1; ---replace_column 23 <created> 24 <modified> +--replace_column 24 <created> 25 <modified> SELECT * FROM INFORMATION_SCHEMA.ROUTINES WHERE ROUTINE_SCHEMA = 'i_s_routines_test' AND ROUTINE_NAME = 'test_func1'; @@ -131,7 +131,7 @@ CREATE PROCEDURE testproc (OUT param1 INT) END; // delimiter ;// ---replace_column 23 <created> 24 <modified> +--replace_column 24 <created> 25 <modified> SELECT * FROM INFORMATION_SCHEMA.ROUTINES WHERE ROUTINE_SCHEMA = 'i_s_routines_test' AND ROUTINE_NAME = 'testproc'; @@ -153,7 +153,7 @@ USE i_s_routines_test; CREATE FUNCTION test_func1 (s char(20)) RETURNS CHAR(50) RETURN CONCAT('Hello, ',s,'!'); ---replace_column 23 <created> 24 <modified> +--replace_column 24 <created> 25 <modified> SELECT * FROM INFORMATION_SCHEMA.ROUTINES WHERE ROUTINE_SCHEMA = 'i_s_routines_test' AND ROUTINE_NAME = 'test_func1'; @@ -175,7 +175,7 @@ CREATE DATABASE i_s_routines_test; USE i_s_routines_test; CREATE FUNCTION test_func2 (s int) RETURNS INT RETURN s*2; ---replace_column 23 <created> 24 <modified> +--replace_column 24 <created> 25 <modified> SELECT * FROM INFORMATION_SCHEMA.ROUTINES WHERE ROUTINE_SCHEMA = 'i_s_routines_test' AND ROUTINE_NAME = 'test_func2'; @@ -195,7 +195,7 @@ USE i_s_routines_test; CREATE FUNCTION test_func5 (s date) RETURNS TIMESTAMP RETURN CURRENT_TIMESTAMP; ---replace_column 23 <created> 24 <modified> +--replace_column 24 <created> 25 <modified> SELECT * FROM INFORMATION_SCHEMA.ROUTINES WHERE ROUTINE_SCHEMA = 'i_s_routines_test' AND ROUTINE_NAME = 'test_func5'; @@ -214,11 +214,11 @@ USE i_s_routines_test; CREATE FUNCTION test_func5 (s date) RETURNS TIMESTAMP RETURN CURRENT_TIMESTAMP; ---replace_column 23 <created> 24 <modified> +--replace_column 24 <created> 25 <modified> SELECT * FROM INFORMATION_SCHEMA.ROUTINES WHERE ROUTINE_SCHEMA = 'i_s_routines_test' AND ROUTINE_NAME = 'test_func5'; ALTER FUNCTION test_func5 COMMENT 'new comment added'; ---replace_column 23 <created> 24 <modified> +--replace_column 24 <created> 25 <modified> SELECT * FROM INFORMATION_SCHEMA.ROUTINES WHERE ROUTINE_SCHEMA = 'i_s_routines_test' AND ROUTINE_NAME = 'test_func5'; @@ -239,7 +239,7 @@ USE i_s_routines_test; CREATE FUNCTION test_func5 (s CHAR(20)) RETURNS VARCHAR(30) RETURN CONCAT('XYZ, ' ,s); ---replace_column 23 <created> 24 <modified> +--replace_column 24 <created> 25 <modified> SELECT * FROM INFORMATION_SCHEMA.ROUTINES WHERE ROUTINE_SCHEMA = 'i_s_routines_test' AND ROUTINE_NAME = 'test_func5'; diff --git a/mysql-test/t/innodb_icp.test b/mysql-test/t/innodb_icp.test new file mode 100644 index 00000000000..0fb42355f96 --- /dev/null +++ b/mysql-test/t/innodb_icp.test @@ -0,0 +1,17 @@ +# +# ICP/InnoDB tests (Index Condition Pushdown) +# + +--source include/have_innodb.inc + +set @save_storage_engine= @@storage_engine; +set storage_engine=InnoDB; + +set @innodb_icp_tmp=@@optimizer_switch; +set optimizer_switch='mrr=on,mrr_sort_keys=on,index_condition_pushdown=on'; + +--source include/icp_tests.inc + +set optimizer_switch=@innodb_icp_tmp; +set storage_engine= @save_storage_engine; + diff --git a/mysql-test/t/innodb_mrr_cpk.test b/mysql-test/t/innodb_mrr_cpk.test new file mode 100644 index 00000000000..a157ddd792f --- /dev/null +++ b/mysql-test/t/innodb_mrr_cpk.test @@ -0,0 +1,141 @@ +# +# Tests for DS-MRR over clustered primary key. The only engine that supports +# this is InnoDB/XtraDB. +# +# Basic idea about testing +# - DS-MRR/CPK works only with BKA +# - Should also test index condition pushdown +# - Should also test whatever uses RANGE_SEQ_IF::skip_record() for filtering +# - Also test access using prefix of primary key +# +# - Forget about cost model, BKA's multi_range_read_info() call passes 10 for +# #rows, the call is there at all only for applicability check +# +-- source include/have_innodb.inc + +--disable_warnings +drop table if exists t0,t1,t2,t3; +--enable_warnings + +set @innodb_mrr_cpk_tmp=@@optimizer_switch; +set optimizer_switch='mrr=on,mrr_sort_keys=on,index_condition_pushdown=on'; + +set @save_join_cache_level=@@join_cache_level; +set join_cache_level=6; + +set @save_storage_engine=@@storage_engine; +set storage_engine=innodb; + +create table t0(a int); +insert into t0 values (0),(1),(2),(3),(4),(5),(6),(7),(8),(9); +create table t1(a char(8), b char(8), filler char(100), primary key(a)); +show create table t1; + +insert into t1 select + concat('a-', 1000 + A.a + B.a*10 + C.a*100, '=A'), + concat('b-', 1000 + A.a + B.a*10 + C.a*100, '=B'), + 'filler' +from t0 A, t0 B, t0 C; + +create table t2 (a char(8)); +insert into t2 values ('a-1010=A'), ('a-1030=A'), ('a-1020=A'); + +--echo This should use join buffer: +explain select * from t1, t2 where t1.a=t2.a; + +--echo This output must be sorted by value of t1.a: +select * from t1, t2 where t1.a=t2.a; +drop table t1, t2; + +# Try multi-column indexes +create table t1( + a char(8) character set utf8, b int, filler char(100), + primary key(a,b) +); + +insert into t1 select + concat('a-', 1000 + A.a + B.a*10 + C.a*100, '=A'), + 1000 + A.a + B.a*10 + C.a*100, + 'filler' +from t0 A, t0 B, t0 C; + +create table t2 (a char(8) character set utf8, b int); +insert into t2 values ('a-1010=A', 1010), ('a-1030=A', 1030), ('a-1020=A', 1020); +explain select * from t1, t2 where t1.a=t2.a and t1.b=t2.b; +select * from t1, t2 where t1.a=t2.a and t1.b=t2.b; + +# Try with dataset that causes identical lookup keys: +insert into t2 values ('a-1030=A', 1030), ('a-1020=A', 1020); +explain select * from t1, t2 where t1.a=t2.a and t1.b=t2.b; +select * from t1, t2 where t1.a=t2.a and t1.b=t2.b; + +drop table t1, t2; + +create table t1( + a varchar(8) character set utf8, b int, filler char(100), + primary key(a,b) +); + +insert into t1 select + concat('a-', 1000 + A.a + B.a*10 + C.a*100, '=A'), + 1000 + A.a + B.a*10 + C.a*100, + 'filler' +from t0 A, t0 B, t0 C; + +create table t2 (a char(8) character set utf8, b int); +insert into t2 values ('a-1010=A', 1010), ('a-1030=A', 1030), ('a-1020=A', 1020); +explain select * from t1, t2 where t1.a=t2.a and t1.b=t2.b; +select * from t1, t2 where t1.a=t2.a and t1.b=t2.b; + +# +# Try scanning on a CPK prefix +# +explain select * from t1, t2 where t1.a=t2.a; +select * from t1, t2 where t1.a=t2.a; +drop table t1, t2; + +# +# The above example is not very interesting, as CPK prefix has +# only one match. Create a dataset where scan on CPK prefix +# would produce multiple matches: +# +create table t1 (a int, b int, c int, filler char(100), primary key(a,b,c)); +insert into t1 select A.a, B.a, C.a, 'filler' from t0 A, t0 B, t0 C; + +insert into t1 values (11, 11, 11, 'filler'); +insert into t1 values (11, 11, 12, 'filler'); +insert into t1 values (11, 11, 13, 'filler'); +insert into t1 values (11, 22, 1234, 'filler'); +insert into t1 values (11, 33, 124, 'filler'); +insert into t1 values (11, 33, 125, 'filler'); + +create table t2 (a int, b int); +insert into t2 values (11,33), (11,22), (11,11); + +explain select * from t1, t2 where t1.a=t2.a and t1.b=t2.b; +select * from t1, t2 where t1.a=t2.a and t1.b=t2.b; + +# Check a real resultset for comaprison: +set join_cache_level=0; +select * from t1, t2 where t1.a=t2.a and t1.b=t2.b; +set join_cache_level=6; + + +# +# Check that Index Condition Pushdown (BKA) actually works: +# +explain select * from t1, t2 where t1.a=t2.a and t2.b + t1.b > 100; +select * from t1, t2 where t1.a=t2.a and t2.b + t1.b > 100; + +set optimizer_switch='index_condition_pushdown=off'; +explain select * from t1, t2 where t1.a=t2.a and t2.b + t1.b > 100; +select * from t1, t2 where t1.a=t2.a and t2.b + t1.b > 100; +set optimizer_switch='index_condition_pushdown=on'; + +drop table t1,t2; + +set @@join_cache_level= @save_join_cache_level; +set storage_engine=@save_storage_engine; +set optimizer_switch=@innodb_mrr_cpk_tmp; +drop table t0; + diff --git a/mysql-test/t/innodb_mysql_lock-master.opt b/mysql-test/t/innodb_mysql_lock-master.opt index 0041949b829..ec82f2755af 100644 --- a/mysql-test/t/innodb_mysql_lock-master.opt +++ b/mysql-test/t/innodb_mysql_lock-master.opt @@ -1 +1 @@ ---innodb_lock_wait_timeout=300 +--loose-innodb_lock_wait_timeout=300 diff --git a/mysql-test/t/join.test b/mysql-test/t/join.test index 05d630edfb2..c4f2b6cb61f 100644 --- a/mysql-test/t/join.test +++ b/mysql-test/t/join.test @@ -2,6 +2,7 @@ # Initialization --disable_warnings drop table if exists t1,t2,t3; +drop view if exists v1,v2; --enable_warnings # @@ -921,4 +922,96 @@ EXECUTE stmt; DEALLOCATE PREPARE stmt; DROP TABLE t1; +--echo # +--echo # Bug LP:798597: Incorrect "Duplicate entry" error with views and +--echo # GROUP BY +--echo # + +CREATE TABLE t1 ( f1 int NOT NULL , f2 int NOT NULL ) ; +INSERT INTO t1 VALUES (214,0),(6,6); +CREATE TABLE t2 ( f2 int) ; +INSERT INTO t2 VALUES (88),(88); +CREATE ALGORITHM=MERGE VIEW v1 AS SELECT t1.f1, t2.f2 FROM (t2 LEFT JOIN t1 ON (t2.f2 <> t1.f1)) WHERE (t1.f2 <= 0) ; +CREATE ALGORITHM=MERGE VIEW v2 AS SELECT t1.f1, t2.f2 FROM (t2 LEFT JOIN t1 ON (t2.f2 <> t1.f1)) WHERE (t1.f2 <= 0 or t1.f2 is null) ; +SELECT f1 , MIN(f2) FROM v1 GROUP BY f1; +SELECT f1 , MIN(f2) FROM v2 GROUP BY f1; +drop table t1,t2; +drop view v1,v2; + + +--echo # +--echo # BUG#47217 Lost optimization caused slowdown & wrong result. +--echo # +CREATE TABLE t1 (pk INT, v VARCHAR(2), PRIMARY KEY(pk)); +CREATE INDEX ix1 ON t1(v); +CREATE TABLE t2 (pk INT, v VARCHAR(2), PRIMARY KEY(pk)); +CREATE INDEX ix2 ON t2(v); +INSERT INTO t1 VALUES (1,'a'),(2,NULL); +INSERT INTO t2 VALUES (1,NULL); +EXPLAIN SELECT * FROM t1 JOIN t2 ON t1.v = t2.v ORDER BY 1; +EXPLAIN SELECT * FROM t1 JOIN t2 ON t1.v = t2.v; +INSERT INTO t1 VALUES (3,'b'),(4,NULL),(5,'c'),(6,'cc'),(7,'d'), + (8,'dd'),(9,'e'),(10,'ee'); +INSERT INTO t2 VALUES (2,NULL); +FLUSH STATUS; +SELECT * FROM t1 JOIN t2 ON t1.v = t2.v WHERE t2.v IS NULL ORDER BY 1; +SHOW STATUS LIKE 'Handler_read_%'; +DROP TABLE t1, t2; + --echo End of 5.1 tests + +--echo # +--echo # BUG#724275: Crash in JOIN::optimize in maria-5.3 +--echo # + +create table t1 (a int); +insert into t1 values (1),(2); +insert into t1 select * from t1; + +create table t2 (a int, b int, key(a,b)); +insert into t2 values (1,1),(1,2),(1,3),(1,4),(2,5),(2,6),(2,7),(2,8),(2,9); +insert into t2 select * from t2; +insert into t2 select * from t2; +insert into t2 select * from t2; + +create table t3 (a int, b int, key(a)); +insert into t3 values (1,1),(2,2); +select * from + t3 straight_join t1 straight_join t2 force index(a) +where t2.a=1 and t2.b=t1.a and t1.a=t3.b and t3.a=1; + +drop table t1,t2,t3; + +--echo # +--echo # BUG#729067/730466: unexpected 'Range checked for each record' +--echo # for queries with OR in WHERE clause +--echo # + +CREATE TABLE t1 (f1 int, f2 int) ; +INSERT INTO t1 VALUES (4,0),(5,1); + +CREATE TABLE t2 (f1 int, f2 int, KEY (f2)) ; +INSERT INTO t2 VALUES (5,7), (8,9); + +EXPLAIN +SELECT * FROM t1 STRAIGHT_JOIN t2 ON t2.f1 = t1.f1 + WHERE t1.f1<>0 OR t1.f2<>0 AND t1.f1 = t2.f2; +SELECT * FROM t1 STRAIGHT_JOIN t2 ON t2.f1 = t1.f1 + WHERE t1.f1<>0 OR t1.f2<>0 AND t1.f1 = t2.f2; + +DROP TABLE t1,t2; + +CREATE TABLE t1(f1 int PRIMARY KEY, f2 int) ; +INSERT INTO t1 VALUES (9,4), (10,9); + +CREATE TABLE t2(f1 int PRIMARY KEY, f2 int) ; +INSERT INTO t2 VALUES (9,4), (10,9); + +EXPLAIN +SELECT STRAIGHT_JOIN * FROM t1 JOIN t2 ON t2.f2 = t1.f1 + WHERE t1.f1 IN (SELECT f1 FROM t1) AND t1.f1 = t2.f1 OR t1.f1 = 9; +SELECT STRAIGHT_JOIN * FROM t1 JOIN t2 ON t2.f2 = t1.f1 + WHERE t1.f1 IN (SELECT f1 FROM t1) AND t1.f1 = t2.f1 OR t1.f1 = 9; + +DROP TABLE t1,t2; + diff --git a/mysql-test/t/join_cache.test b/mysql-test/t/join_cache.test index 0cb1c139161..ca0d10c3ee1 100644 --- a/mysql-test/t/join_cache.test +++ b/mysql-test/t/join_cache.test @@ -3,6 +3,14 @@ DROP TABLE IF EXISTS t1,t2,t3,t4,t5,t6,t7,t8,t9,t10,t11; DROP DATABASE IF EXISTS world; --enable_warnings +set @save_optimizer_switch=@@optimizer_switch; +set @@optimizer_switch='optimize_join_buffer_size=on'; +set optimizer_switch='semijoin=on,firstmatch=on,loosescan=on'; +set @@optimizer_switch='semijoin_with_cache=on'; +set @@optimizer_switch='outer_join_with_cache=on'; +set optimizer_switch='mrr=on,mrr_sort_keys=on,index_condition_pushdown=on'; + +set @local_join_cache_test_optimizer_switch_default=@@optimizer_switch; set names utf8; CREATE DATABASE world; @@ -42,14 +50,16 @@ SELECT City.Name, Country.Name, CountryLanguage.Language WHERE City.Country=Country.Code AND CountryLanguage.Country=Country.Code AND City.Name LIKE 'L%' AND Country.Population > 3000000 AND - CountryLanguage.Percentage > 50; + CountryLanguage.Percentage > 50 AND + LENGTH(Language) < LENGTH(City.Name) - 2; SELECT City.Name, Country.Name, CountryLanguage.Language FROM City,Country,CountryLanguage WHERE City.Country=Country.Code AND CountryLanguage.Country=Country.Code AND City.Name LIKE 'L%' AND Country.Population > 3000000 AND - CountryLanguage.Percentage > 50; + CountryLanguage.Percentage > 50 AND + LENGTH(Language) < LENGTH(City.Name) - 2; set join_cache_level=2; show variables like 'join_cache_level'; @@ -69,14 +79,122 @@ SELECT City.Name, Country.Name, CountryLanguage.Language WHERE City.Country=Country.Code AND CountryLanguage.Country=Country.Code AND City.Name LIKE 'L%' AND Country.Population > 3000000 AND - CountryLanguage.Percentage > 50; + CountryLanguage.Percentage > 50 AND + LENGTH(Language) < LENGTH(City.Name) - 2; SELECT City.Name, Country.Name, CountryLanguage.Language FROM City,Country,CountryLanguage WHERE City.Country=Country.Code AND CountryLanguage.Country=Country.Code AND City.Name LIKE 'L%' AND Country.Population > 3000000 AND - CountryLanguage.Percentage > 50; + CountryLanguage.Percentage > 50 AND + LENGTH(Language) < LENGTH(City.Name) - 2; + +set join_cache_level=3; +show variables like 'join_cache_level'; + +EXPLAIN +SELECT City.Name, Country.Name FROM City,Country + WHERE City.Country=Country.Code AND + Country.Name LIKE 'L%' AND City.Population > 100000; + +SELECT City.Name, Country.Name FROM City,Country + WHERE City.Country=Country.Code AND + Country.Name LIKE 'L%' AND City.Population > 100000; + +EXPLAIN +SELECT City.Name, Country.Name, CountryLanguage.Language + FROM City,Country,CountryLanguage + WHERE City.Country=Country.Code AND + CountryLanguage.Country=Country.Code AND + City.Name LIKE 'L%' AND Country.Population > 3000000 AND + CountryLanguage.Percentage > 50 AND + LENGTH(Language) < LENGTH(City.Name) - 2; + + +SELECT City.Name, Country.Name, CountryLanguage.Language + FROM City,Country,CountryLanguage + WHERE City.Country=Country.Code AND + CountryLanguage.Country=Country.Code AND + City.Name LIKE 'L%' AND Country.Population > 3000000 AND + CountryLanguage.Percentage > 50 AND + LENGTH(Language) < LENGTH(City.Name) - 2; + + +set join_cache_level=4; +show variables like 'join_cache_level'; + +EXPLAIN +SELECT City.Name, Country.Name FROM City,Country + WHERE City.Country=Country.Code AND + Country.Name LIKE 'L%' AND City.Population > 100000; + +SELECT City.Name, Country.Name FROM City,Country + WHERE City.Country=Country.Code AND + Country.Name LIKE 'L%' AND City.Population > 100000; + +EXPLAIN +SELECT City.Name, Country.Name, CountryLanguage.Language + FROM City,Country,CountryLanguage + WHERE City.Country=Country.Code AND + CountryLanguage.Country=Country.Code AND + City.Name LIKE 'L%' AND Country.Population > 3000000 AND + CountryLanguage.Percentage > 50 AND + LENGTH(Language) < LENGTH(City.Name) - 2; + +SELECT City.Name, Country.Name, CountryLanguage.Language + FROM City,Country,CountryLanguage + WHERE City.Country=Country.Code AND + CountryLanguage.Country=Country.Code AND + City.Name LIKE 'L%' AND Country.Population > 3000000 AND + CountryLanguage.Percentage > 50 AND + LENGTH(Language) < LENGTH(City.Name) - 2; + + +SELECT Country.Name, Country.Population, City.Name, City.Population + FROM Country LEFT JOIN City + ON City.Country=Country.Code AND City.Population > 5000000 + WHERE Country.Name LIKE 'C%' AND Country.Population > 10000000; + +SELECT Country.Name, Country.Population, City.Name, City.Population + FROM Country LEFT JOIN City + ON City.Country=Country.Code AND + (City.Population > 5000000 OR City.Name LIKE 'Za%') + WHERE Country.Name LIKE 'C%' AND Country.Population > 10000000; + +CREATE INDEX City_Population ON City(Population); +CREATE INDEX City_Name ON City(Name); + +--disable_result_log +ANALYZE TABLE City; +--enable_result_log + +EXPLAIN +SELECT Country.Name, Country.Population, City.Name, City.Population + FROM Country LEFT JOIN City + ON City.Country=Country.Code AND City.Population > 5000000 + WHERE Country.Name LIKE 'C%' AND Country.Population > 10000000; + +SELECT Country.Name, Country.Population, City.Name, City.Population + FROM Country LEFT JOIN City + ON City.Country=Country.Code AND City.Population > 5000000 + WHERE Country.Name LIKE 'C%' AND Country.Population > 10000000; + +EXPLAIN +SELECT Country.Name, Country.Population, City.Name, City.Population + FROM Country LEFT JOIN City + ON City.Country=Country.Code AND + (City.Population > 5000000 OR City.Name LIKE 'Za%') + WHERE Country.Name LIKE 'C%' AND Country.Population > 10000000; + +SELECT Country.Name, Country.Population, City.Name, City.Population + FROM Country LEFT JOIN City + ON City.Country=Country.Code AND + (City.Population > 5000000 OR City.Name LIKE 'Za%') + WHERE Country.Name LIKE 'C%' AND Country.Population > 10000000; + +DROP INDEX City_Population ON City; +DROP INDEX City_Name ON City; set join_cache_level=default; @@ -100,14 +218,16 @@ SELECT City.Name, Country.Name, CountryLanguage.Language WHERE City.Country=Country.Code AND CountryLanguage.Country=Country.Code AND City.Name LIKE 'L%' AND Country.Population > 3000000 AND - CountryLanguage.Percentage > 50; + CountryLanguage.Percentage > 50 AND + LENGTH(Language) < LENGTH(City.Name) - 2; SELECT City.Name, Country.Name, CountryLanguage.Language FROM City,Country,CountryLanguage WHERE City.Country=Country.Code AND CountryLanguage.Country=Country.Code AND City.Name LIKE 'L%' AND Country.Population > 3000000 AND - CountryLanguage.Percentage > 50; + CountryLanguage.Percentage > 50 AND + LENGTH(Language) < LENGTH(City.Name) - 2; set join_cache_level=2; show variables like 'join_cache_level'; @@ -127,14 +247,74 @@ SELECT City.Name, Country.Name, CountryLanguage.Language WHERE City.Country=Country.Code AND CountryLanguage.Country=Country.Code AND City.Name LIKE 'L%' AND Country.Population > 3000000 AND - CountryLanguage.Percentage > 50; + CountryLanguage.Percentage > 50 AND + LENGTH(Language) < LENGTH(City.Name) - 2; SELECT City.Name, Country.Name, CountryLanguage.Language FROM City,Country,CountryLanguage WHERE City.Country=Country.Code AND CountryLanguage.Country=Country.Code AND City.Name LIKE 'L%' AND Country.Population > 3000000 AND - CountryLanguage.Percentage > 50; + CountryLanguage.Percentage > 50 AND + LENGTH(Language) < LENGTH(City.Name) - 2; + +set join_cache_level=3; +show variables like 'join_cache_level'; + +EXPLAIN +SELECT City.Name, Country.Name FROM City,Country + WHERE City.Country=Country.Code AND + Country.Name LIKE 'L%' AND City.Population > 100000; + +SELECT City.Name, Country.Name FROM City,Country + WHERE City.Country=Country.Code AND + Country.Name LIKE 'L%' AND City.Population > 100000; + +EXPLAIN +SELECT City.Name, Country.Name, CountryLanguage.Language + FROM City,Country,CountryLanguage + WHERE City.Country=Country.Code AND + CountryLanguage.Country=Country.Code AND + City.Name LIKE 'L%' AND Country.Population > 3000000 AND + CountryLanguage.Percentage > 50 AND + LENGTH(Language) < LENGTH(City.Name) - 2; + +SELECT City.Name, Country.Name, CountryLanguage.Language + FROM City,Country,CountryLanguage + WHERE City.Country=Country.Code AND + CountryLanguage.Country=Country.Code AND + City.Name LIKE 'L%' AND Country.Population > 3000000 AND + CountryLanguage.Percentage > 50 AND + LENGTH(Language) < LENGTH(City.Name) - 2; + +set join_cache_level=4; +show variables like 'join_cache_level'; + +EXPLAIN +SELECT City.Name, Country.Name FROM City,Country + WHERE City.Country=Country.Code AND + Country.Name LIKE 'L%' AND City.Population > 100000; + +SELECT City.Name, Country.Name FROM City,Country + WHERE City.Country=Country.Code AND + Country.Name LIKE 'L%' AND City.Population > 100000; + +EXPLAIN +SELECT City.Name, Country.Name, CountryLanguage.Language + FROM City,Country,CountryLanguage + WHERE City.Country=Country.Code AND + CountryLanguage.Country=Country.Code AND + City.Name LIKE 'L%' AND Country.Population > 3000000 AND + CountryLanguage.Percentage > 50 AND + LENGTH(Language) < LENGTH(City.Name) - 2; + +SELECT City.Name, Country.Name, CountryLanguage.Language + FROM City,Country,CountryLanguage + WHERE City.Country=Country.Code AND + CountryLanguage.Country=Country.Code AND + City.Name LIKE 'L%' AND Country.Population > 3000000 AND + CountryLanguage.Percentage > 50 AND + LENGTH(Language) < LENGTH(City.Name) - 2; set join_cache_level=default; set join_buffer_size=default; @@ -160,7 +340,7 @@ use world; --enable_query_log show variables like 'join_buffer_size'; -set join_cache_level=5; +set join_cache_level=3; show variables like 'join_cache_level'; EXPLAIN @@ -178,23 +358,68 @@ SELECT City.Name, Country.Name, CountryLanguage.Language WHERE City.Country=Country.Code AND CountryLanguage.Country=Country.Code AND City.Name LIKE 'L%' AND Country.Population > 3000000 AND - CountryLanguage.Percentage > 50; + CountryLanguage.Percentage > 50 AND + LENGTH(Language) < LENGTH(City.Name) - 2; SELECT City.Name, Country.Name, CountryLanguage.Language FROM City,Country,CountryLanguage WHERE City.Country=Country.Code AND CountryLanguage.Country=Country.Code AND City.Name LIKE 'L%' AND Country.Population > 3000000 AND - CountryLanguage.Percentage > 50; + CountryLanguage.Percentage > 50 AND + LENGTH(Language) < LENGTH(City.Name) - 2; ---echo # !!!NB igor: after backporting the SJ code the following should return ---echo # EXPLAIN ---echo # SELECT Name FROM City ---echo # WHERE City.Country IN (SELECT Code FROM Country WHERE Country.Name LIKE 'L%') AND ---echo # City.Population > 100000; ---echo # id select_type table type possible_keys key key_len ref rows Extra ---echo # 1 PRIMARY Country range PRIMARY,Name Name 52 NULL 10 Using index condition; Using MRR ---echo # 1 PRIMARY City ref Population,Country Country 3 world.Country.Code 18 Using where; Using join buffer +EXPLAIN +SELECT Name FROM City + WHERE City.Country IN (SELECT Code FROM Country WHERE Country.Name LIKE 'L%') AND + City.Population > 100000; + +SELECT Name FROM City + WHERE City.Country IN (SELECT Code FROM Country WHERE Country.Name LIKE 'L%') AND + City.Population > 100000; + +EXPLAIN +SELECT Country.Name, IF(ISNULL(CountryLanguage.Country), NULL, CountryLanguage.Percentage) + FROM Country LEFT JOIN CountryLanguage ON + (CountryLanguage.Country=Country.Code AND Language='English') + WHERE + Country.Population > 10000000; + +SELECT Country.Name, IF(ISNULL(CountryLanguage.Country), NULL, CountryLanguage.Percentage) + FROM Country LEFT JOIN CountryLanguage ON + (CountryLanguage.Country=Country.Code AND Language='English') + WHERE + Country.Population > 10000000; + +show variables like 'join_buffer_size'; +set join_cache_level=4; +show variables like 'join_cache_level'; + +EXPLAIN +SELECT City.Name, Country.Name FROM City,Country + WHERE City.Country=Country.Code AND + Country.Name LIKE 'L%' AND City.Population > 100000; + +SELECT City.Name, Country.Name FROM City,Country + WHERE City.Country=Country.Code AND + Country.Name LIKE 'L%' AND City.Population > 100000; + +EXPLAIN +SELECT City.Name, Country.Name, CountryLanguage.Language + FROM City,Country,CountryLanguage + WHERE City.Country=Country.Code AND + CountryLanguage.Country=Country.Code AND + City.Name LIKE 'L%' AND Country.Population > 3000000 AND + CountryLanguage.Percentage > 50 AND + LENGTH(Language) < LENGTH(City.Name) - 2; + +SELECT City.Name, Country.Name, CountryLanguage.Language + FROM City,Country,CountryLanguage + WHERE City.Country=Country.Code AND + CountryLanguage.Country=Country.Code AND + City.Name LIKE 'L%' AND Country.Population > 3000000 AND + CountryLanguage.Percentage > 50 AND + LENGTH(Language) < LENGTH(City.Name) - 2; EXPLAIN SELECT Name FROM City @@ -218,7 +443,38 @@ SELECT Country.Name, IF(ISNULL(CountryLanguage.Country), NULL, CountryLanguage.P WHERE Country.Population > 10000000; -set join_cache_level=6; + +--replace_column 9 # +EXPLAIN +SELECT Country.Name, Country.Population, City.Name, City.Population + FROM Country LEFT JOIN City + ON City.Country=Country.Code AND City.Population > 5000000 + WHERE Country.Name LIKE 'C%' AND Country.Population > 10000000; + +SELECT Country.Name, Country.Population, City.Name, City.Population + FROM Country LEFT JOIN City + ON City.Country=Country.Code AND City.Population > 5000000 + WHERE Country.Name LIKE 'C%' AND Country.Population > 10000000; + +CREATE INDEX City_Name ON City(Name); + +EXPLAIN +SELECT Country.Name, Country.Population, City.Name, City.Population + FROM Country LEFT JOIN City + ON City.Country=Country.Code AND + (City.Population > 5000000 OR City.Name LIKE 'Za%') + WHERE Country.Name LIKE 'C%' AND Country.Population > 10000000; + +SELECT Country.Name, Country.Population, City.Name, City.Population + FROM Country LEFT JOIN City + ON City.Country=Country.Code AND + (City.Population > 5000000 OR City.Name LIKE 'Za%') + WHERE Country.Name LIKE 'C%' AND Country.Population > 10000000; + +DROP INDEX City_Name ON City; + +show variables like 'join_buffer_size'; +set join_cache_level=5; show variables like 'join_cache_level'; EXPLAIN @@ -236,23 +492,67 @@ SELECT City.Name, Country.Name, CountryLanguage.Language WHERE City.Country=Country.Code AND CountryLanguage.Country=Country.Code AND City.Name LIKE 'L%' AND Country.Population > 3000000 AND - CountryLanguage.Percentage > 50; + CountryLanguage.Percentage > 50 AND + LENGTH(Language) < LENGTH(City.Name) - 2; + +SELECT City.Name, Country.Name, CountryLanguage.Language + FROM City,Country,CountryLanguage + WHERE City.Country=Country.Code AND + CountryLanguage.Country=Country.Code AND + City.Name LIKE 'L%' AND Country.Population > 3000000 AND + CountryLanguage.Percentage > 50 AND + LENGTH(Language) < LENGTH(City.Name) - 2; + +EXPLAIN +SELECT Name FROM City + WHERE City.Country IN (SELECT Code FROM Country WHERE Country.Name LIKE 'L%') AND + City.Population > 100000; + +SELECT Name FROM City + WHERE City.Country IN (SELECT Code FROM Country WHERE Country.Name LIKE 'L%') AND + City.Population > 100000; + +EXPLAIN +SELECT Country.Name, IF(ISNULL(CountryLanguage.Country), NULL, CountryLanguage.Percentage) + FROM Country LEFT JOIN CountryLanguage ON + (CountryLanguage.Country=Country.Code AND Language='English') + WHERE + Country.Population > 10000000; + +SELECT Country.Name, IF(ISNULL(CountryLanguage.Country), NULL, CountryLanguage.Percentage) + FROM Country LEFT JOIN CountryLanguage ON + (CountryLanguage.Country=Country.Code AND Language='English') + WHERE + Country.Population > 10000000; + +set join_cache_level=6; +show variables like 'join_cache_level'; + +EXPLAIN +SELECT City.Name, Country.Name FROM City,Country + WHERE City.Country=Country.Code AND + Country.Name LIKE 'L%' AND City.Population > 100000; + +SELECT City.Name, Country.Name FROM City,Country + WHERE City.Country=Country.Code AND + Country.Name LIKE 'L%' AND City.Population > 100000; +EXPLAIN SELECT City.Name, Country.Name, CountryLanguage.Language FROM City,Country,CountryLanguage WHERE City.Country=Country.Code AND CountryLanguage.Country=Country.Code AND City.Name LIKE 'L%' AND Country.Population > 3000000 AND - CountryLanguage.Percentage > 50; + CountryLanguage.Percentage > 50 AND + LENGTH(Language) < LENGTH(City.Name) - 2; ---echo # !!!NB igor: after backporting the SJ code the following should return ---echo # EXPLAIN ---echo # SELECT Name FROM City ---echo # WHERE City.Country IN (SELECT Code FROM Country WHERE Country.Name LIKE 'L%') AND ---echo # City.Population > 100000; ---echo # id select_type table type possible_keys key key_len ref rows Extra ---echo # 1 PRIMARY Country range PRIMARY,Name Name 52 NULL 10 Using index condition; Using MRR ---echo # 1 PRIMARY City ref Population,Country Country 3 world.Country.Code 18 Using where; Using join buffer +SELECT City.Name, Country.Name, CountryLanguage.Language + FROM City,Country,CountryLanguage + WHERE City.Country=Country.Code AND + CountryLanguage.Country=Country.Code AND + City.Name LIKE 'L%' AND Country.Population > 3000000 AND + CountryLanguage.Percentage > 50 AND + LENGTH(Language) < LENGTH(City.Name) - 2; EXPLAIN SELECT Name FROM City @@ -294,23 +594,16 @@ SELECT City.Name, Country.Name, CountryLanguage.Language WHERE City.Country=Country.Code AND CountryLanguage.Country=Country.Code AND City.Name LIKE 'L%' AND Country.Population > 3000000 AND - CountryLanguage.Percentage > 50; + CountryLanguage.Percentage > 50 AND + LENGTH(Language) < LENGTH(City.Name) - 2; SELECT City.Name, Country.Name, CountryLanguage.Language FROM City,Country,CountryLanguage WHERE City.Country=Country.Code AND CountryLanguage.Country=Country.Code AND City.Name LIKE 'L%' AND Country.Population > 3000000 AND - CountryLanguage.Percentage > 50; - ---echo # !!!NB igor: after backporting the SJ code the following should return ---echo # EXPLAIN ---echo # SELECT Name FROM City ---echo # WHERE City.Country IN (SELECT Code FROM Country WHERE Country.Name LIKE 'L%') AND ---echo # City.Population > 100000; ---echo # id select_type table type possible_keys key key_len ref rows Extra ---echo # 1 PRIMARY Country range PRIMARY,Name Name 52 NULL 10 Using index condition; Using MRR ---echo # 1 PRIMARY City ref Population,Country Country 3 world.Country.Code 18 Using where; Using join buffer + CountryLanguage.Percentage > 50 AND + LENGTH(Language) < LENGTH(City.Name) - 2; EXPLAIN SELECT Name FROM City @@ -352,23 +645,16 @@ SELECT City.Name, Country.Name, CountryLanguage.Language WHERE City.Country=Country.Code AND CountryLanguage.Country=Country.Code AND City.Name LIKE 'L%' AND Country.Population > 3000000 AND - CountryLanguage.Percentage > 50; + CountryLanguage.Percentage > 50 AND + LENGTH(Language) < LENGTH(City.Name) - 2; SELECT City.Name, Country.Name, CountryLanguage.Language FROM City,Country,CountryLanguage WHERE City.Country=Country.Code AND CountryLanguage.Country=Country.Code AND City.Name LIKE 'L%' AND Country.Population > 3000000 AND - CountryLanguage.Percentage > 50; - ---echo # !!!NB igor: after backporting the SJ code the following should return ---echo # EXPLAIN ---echo # SELECT Name FROM City ---echo # WHERE City.Country IN (SELECT Code FROM Country WHERE Country.Name LIKE 'L%') AND ---echo # City.Population > 100000; ---echo # id select_type table type possible_keys key key_len ref rows Extra ---echo # 1 PRIMARY Country range PRIMARY,Name Name 52 NULL 10 Using index condition; Using MRR ---echo # 1 PRIMARY City ref Population,Country Country 3 world.Country.Code 18 Using where; Using join buffer + CountryLanguage.Percentage > 50 AND + LENGTH(Language) < LENGTH(City.Name) - 2; EXPLAIN SELECT Name FROM City @@ -395,7 +681,7 @@ SELECT Country.Name, IF(ISNULL(CountryLanguage.Country), NULL, CountryLanguage.P set join_buffer_size=256; show variables like 'join_buffer_size'; -set join_cache_level=5; +set join_cache_level=3; show variables like 'join_cache_level'; EXPLAIN @@ -413,23 +699,54 @@ SELECT City.Name, Country.Name, CountryLanguage.Language WHERE City.Country=Country.Code AND CountryLanguage.Country=Country.Code AND City.Name LIKE 'L%' AND Country.Population > 3000000 AND - CountryLanguage.Percentage > 50; + CountryLanguage.Percentage > 50 AND + LENGTH(Language) < LENGTH(City.Name) - 2; SELECT City.Name, Country.Name, CountryLanguage.Language FROM City,Country,CountryLanguage WHERE City.Country=Country.Code AND CountryLanguage.Country=Country.Code AND City.Name LIKE 'L%' AND Country.Population > 3000000 AND - CountryLanguage.Percentage > 50; + CountryLanguage.Percentage > 50 AND + LENGTH(Language) < LENGTH(City.Name) - 2; + +EXPLAIN +SELECT Name FROM City + WHERE City.Country IN (SELECT Code FROM Country WHERE Country.Name LIKE 'L%') AND + City.Population > 100000; + +SELECT Name FROM City + WHERE City.Country IN (SELECT Code FROM Country WHERE Country.Name LIKE 'L%') AND + City.Population > 100000; + +set join_cache_level=4; +show variables like 'join_cache_level'; ---echo # !!!NB igor: after backporting the SJ code the following should return ---echo # EXPLAIN ---echo # SELECT Name FROM City ---echo # WHERE City.Country IN (SELECT Code FROM Country WHERE Country.Name LIKE 'L%') AND ---echo # City.Population > 100000; ---echo # id select_type table type possible_keys key key_len ref rows Extra ---echo # 1 PRIMARY Country range PRIMARY,Name Name 52 NULL 10 Using index condition; Using MRR ---echo # 1 PRIMARY City ref Population,Country Country 3 world.Country.Code 18 Using where; Using join buffer +EXPLAIN +SELECT City.Name, Country.Name FROM City,Country + WHERE City.Country=Country.Code AND + Country.Name LIKE 'L%' AND City.Population > 100000; + +SELECT City.Name, Country.Name FROM City,Country + WHERE City.Country=Country.Code AND + Country.Name LIKE 'L%' AND City.Population > 100000; + +EXPLAIN +SELECT City.Name, Country.Name, CountryLanguage.Language + FROM City,Country,CountryLanguage + WHERE City.Country=Country.Code AND + CountryLanguage.Country=Country.Code AND + City.Name LIKE 'L%' AND Country.Population > 3000000 AND + CountryLanguage.Percentage > 50 AND + LENGTH(Language) < LENGTH(City.Name) - 2; + +SELECT City.Name, Country.Name, CountryLanguage.Language + FROM City,Country,CountryLanguage + WHERE City.Country=Country.Code AND + CountryLanguage.Country=Country.Code AND + City.Name LIKE 'L%' AND Country.Population > 3000000 AND + CountryLanguage.Percentage > 50 AND + LENGTH(Language) < LENGTH(City.Name) - 2; EXPLAIN SELECT Name FROM City @@ -440,7 +757,7 @@ SELECT Name FROM City WHERE City.Country IN (SELECT Code FROM Country WHERE Country.Name LIKE 'L%') AND City.Population > 100000; -set join_cache_level=6; +set join_cache_level=5; show variables like 'join_cache_level'; EXPLAIN @@ -458,23 +775,54 @@ SELECT City.Name, Country.Name, CountryLanguage.Language WHERE City.Country=Country.Code AND CountryLanguage.Country=Country.Code AND City.Name LIKE 'L%' AND Country.Population > 3000000 AND - CountryLanguage.Percentage > 50; + CountryLanguage.Percentage > 50 AND + LENGTH(Language) < LENGTH(City.Name) - 2; SELECT City.Name, Country.Name, CountryLanguage.Language FROM City,Country,CountryLanguage WHERE City.Country=Country.Code AND CountryLanguage.Country=Country.Code AND City.Name LIKE 'L%' AND Country.Population > 3000000 AND - CountryLanguage.Percentage > 50; + CountryLanguage.Percentage > 50 AND + LENGTH(Language) < LENGTH(City.Name) - 2; + +EXPLAIN +SELECT Name FROM City + WHERE City.Country IN (SELECT Code FROM Country WHERE Country.Name LIKE 'L%') AND + City.Population > 100000; + +SELECT Name FROM City + WHERE City.Country IN (SELECT Code FROM Country WHERE Country.Name LIKE 'L%') AND + City.Population > 100000; ---echo # !!!NB igor: after backporting the SJ code the following should return ---echo # EXPLAIN ---echo # SELECT Name FROM City ---echo # WHERE City.Country IN (SELECT Code FROM Country WHERE Country.Name LIKE 'L%') AND ---echo # City.Population > 100000; ---echo # id select_type table type possible_keys key key_len ref rows Extra ---echo # 1 PRIMARY Country range PRIMARY,Name Name 52 NULL 10 Using index condition; Using MRR ---echo # 1 PRIMARY City ref Population,Country Country 3 world.Country.Code 18 Using where; Using join buffer +set join_cache_level=6; +show variables like 'join_cache_level'; + +EXPLAIN +SELECT City.Name, Country.Name FROM City,Country + WHERE City.Country=Country.Code AND + Country.Name LIKE 'L%' AND City.Population > 100000; + +SELECT City.Name, Country.Name FROM City,Country + WHERE City.Country=Country.Code AND + Country.Name LIKE 'L%' AND City.Population > 100000; + +EXPLAIN +SELECT City.Name, Country.Name, CountryLanguage.Language + FROM City,Country,CountryLanguage + WHERE City.Country=Country.Code AND + CountryLanguage.Country=Country.Code AND + City.Name LIKE 'L%' AND Country.Population > 3000000 AND + CountryLanguage.Percentage > 50 AND + LENGTH(Language) < LENGTH(City.Name) - 2; + +SELECT City.Name, Country.Name, CountryLanguage.Language + FROM City,Country,CountryLanguage + WHERE City.Country=Country.Code AND + CountryLanguage.Country=Country.Code AND + City.Name LIKE 'L%' AND Country.Population > 3000000 AND + CountryLanguage.Percentage > 50 AND + LENGTH(Language) < LENGTH(City.Name) - 2; EXPLAIN SELECT Name FROM City @@ -503,23 +851,16 @@ SELECT City.Name, Country.Name, CountryLanguage.Language WHERE City.Country=Country.Code AND CountryLanguage.Country=Country.Code AND City.Name LIKE 'L%' AND Country.Population > 3000000 AND - CountryLanguage.Percentage > 50; + CountryLanguage.Percentage > 50 AND + LENGTH(Language) < LENGTH(City.Name) - 2; SELECT City.Name, Country.Name, CountryLanguage.Language FROM City,Country,CountryLanguage WHERE City.Country=Country.Code AND CountryLanguage.Country=Country.Code AND City.Name LIKE 'L%' AND Country.Population > 3000000 AND - CountryLanguage.Percentage > 50; - ---echo # !!!NB igor: after backporting the SJ code the following should return ---echo # EXPLAIN ---echo # SELECT Name FROM City ---echo # WHERE City.Country IN (SELECT Code FROM Country WHERE Country.Name LIKE 'L%') AND ---echo # City.Population > 100000; ---echo # id select_type table type possible_keys key key_len ref rows Extra ---echo # 1 PRIMARY Country range PRIMARY,Name Name 52 NULL 10 Using index condition; Using MRR ---echo # 1 PRIMARY City ref Population,Country Country 3 world.Country.Code 18 Using where; Using join buffer + CountryLanguage.Percentage > 50 AND + LENGTH(Language) < LENGTH(City.Name) - 2; EXPLAIN SELECT Name FROM City @@ -548,23 +889,16 @@ SELECT City.Name, Country.Name, CountryLanguage.Language WHERE City.Country=Country.Code AND CountryLanguage.Country=Country.Code AND City.Name LIKE 'L%' AND Country.Population > 3000000 AND - CountryLanguage.Percentage > 50; + CountryLanguage.Percentage > 50 AND + LENGTH(Language) < LENGTH(City.Name) - 2; SELECT City.Name, Country.Name, CountryLanguage.Language FROM City,Country,CountryLanguage WHERE City.Country=Country.Code AND CountryLanguage.Country=Country.Code AND City.Name LIKE 'L%' AND Country.Population > 3000000 AND - CountryLanguage.Percentage > 50; - ---echo # !!!NB igor: after backporting the SJ code the following should return ---echo # EXPLAIN ---echo # SELECT Name FROM City ---echo # WHERE City.Country IN (SELECT Code FROM Country WHERE Country.Name LIKE 'L%') AND ---echo # City.Population > 100000; ---echo # id select_type table type possible_keys key key_len ref rows Extra ---echo # 1 PRIMARY Country range PRIMARY,Name Name 52 NULL 10 Using index condition; Using MRR ---echo # 1 PRIMARY City ref Population,Country Country 3 world.Country.Code 18 Using where; Using join buffer + CountryLanguage.Percentage > 50 AND + LENGTH(Language) < LENGTH(City.Name) - 2; EXPLAIN SELECT Name FROM City @@ -587,13 +921,14 @@ SELECT City.Name, Country.Name FROM City,Country WHERE City.Country=Country.Code AND City.Population > 3000000; set join_cache_level=8; -set join_buffer_size=256; +set join_buffer_size=384; --replace_column 9 # EXPLAIN SELECT City.Name, Country.Name FROM City,Country WHERE City.Country=Country.Code AND City.Population > 3000000; +--sorted_result SELECT City.Name, Country.Name FROM City,Country WHERE City.Country=Country.Code AND City.Population > 3000000; @@ -997,7 +1332,7 @@ select * from t1 left join t2 on (1=0); explain select * from t1 left join t2 on (1=0) where a=40; select * from t1 left join t2 on (1=0) where a=40; -set join_cache_level=1; +set join_cache_level=0; explain select * from t1 left join t2 on (1=0); set join_cache_level=default; @@ -1131,6 +1466,8 @@ INSERT INTO t3(a,b) VALUES (5,30), (5,40), (5,50), (5,60), (5,70), (5,80), (7,30), (7,40), (7,50), (7,60), (7,70), (7,80); +set join_cache_level=0; + SELECT t1.a, t2.a, t3.a, t2.b, t3.b, t3.val FROM (t1,t2) LEFT JOIN t3 ON (t1.a=t3.a AND t2.b=t3.b) WHERE t1.a=t2.a; @@ -1148,7 +1485,7 @@ SELECT t1.a, t2.a, t3.a, t2.b, t3.b, t3.val WHERE t1.a=t2.a; DROP INDEX idx ON t3; -set join_cache_level=4; +set join_cache_level=2; EXPLAIN SELECT t1.a, t2.a, t3.a, t2.b, t3.b, t3.val @@ -1847,3 +2184,958 @@ select t1.* from t1,t2,t3; set join_cache_level=default; drop table t1,t2,t3; + +--echo # +--echo # Bug #52394: using join buffer for 3 table join with ref access +--echo # LP #623209: and no references to the columns of the middle table +--echo # + + +set join_cache_level=6; + +CREATE TABLE t1 (a int(11), b varchar(1)); +INSERT INTO t1 VALUES (6,'r'),(27,'o'); + +CREATE TABLE t2(a int); +INSERT INTO t2 VALUES(1),(2),(3),(4),(5); + +CREATE TABLE t3 (a int(11) primary key, b varchar(1)); +INSERT INTO t3 VALUES +(14,'d'),(15,'z'),(16,'e'),(17,'h'),(18,'b'),(19,'s'),(20,'e'), +(21,'j'),(22,'e'),(23,'f'),(24,'v'),(25,'x'),(26,'m'),(27,'o'); + +EXPLAIN +SELECT t3.a FROM t1,t2,t3 WHERE t1.a = t3.a AND t1.b = t3.b; +SELECT t3.a FROM t1,t2,t3 WHERE t1.a = t3.a AND t1.b = t3.b; + +DROP TABLE t1,t2,t3; + +set join_cache_level=default; + +--echo # +--echo # Bug #51084: Batched key access crashes for SELECT with +--echo # derived table and LEFT JOIN +--echo # + +CREATE TABLE t1 ( + carrier int, + id int PRIMARY KEY +); +INSERT INTO t1 VALUES (1,11),(1,12),(2,13); + +CREATE TABLE t2 ( + scan_date int, + package_id int +); +INSERT INTO t2 VALUES (2008,21),(2008,22); + +CREATE TABLE t3 ( + carrier int PRIMARY KEY, + id int +); +INSERT INTO t3 VALUES (1,31); + +CREATE TABLE t4 ( + carrier_id int, + INDEX carrier_id(carrier_id) +); +INSERT INTO t4 VALUES (31),(32); + +SET join_cache_level=8; + +SELECT COUNT(*) + FROM (t2 JOIN t1) LEFT JOIN (t3 JOIN t4 ON t3.id = t4.carrier_id) + ON t3.carrier = t1.carrier; + +EXPLAIN +SELECT COUNT(*) + FROM (t2 JOIN t1) LEFT JOIN (t3 JOIN t4 ON t3.id = t4.carrier_id) + ON t3.carrier = t1.carrier; + +SET join_cache_level=default; + +DROP TABLE t1,t2,t3,t4; + +--echo # +--echo # Bug #52636: allowing JOINs on NULL values w/ join_cache_level = 5-8 +--echo # + +CREATE TABLE t1 (b int); +INSERT INTO t1 VALUES (NULL),(3); + +CREATE TABLE t2 (a int, b int, KEY (b)); +INSERT INTO t2 VALUES (100,NULL),(150,200); + +set join_cache_level = 5; +explain SELECT t2.a FROM t1 LEFT JOIN t2 ON t2.b = t1.b; +--sorted_result +SELECT t2.a FROM t1 LEFT JOIN t2 ON t2.b = t1.b; + +set join_cache_level = 8; +explain SELECT t2.a FROM t1 LEFT JOIN t2 ON t2.b = t1.b; +--sorted_result +SELECT t2.a FROM t1 LEFT JOIN t2 ON t2.b = t1.b; + +# test crash when no key is worth collecting by BKA for t2's ref +delete from t1; +INSERT INTO t1 VALUES (NULL),(NULL); +set join_cache_level = 5; +explain SELECT t2.a FROM t1 LEFT JOIN t2 ON t2.b = t1.b; +--sorted_result +SELECT t2.a FROM t1 LEFT JOIN t2 ON t2.b = t1.b; + +DROP TABLE t1,t2; + +# test varchar keys +CREATE TABLE t1 (b varchar(100)); +INSERT INTO t1 VALUES (NULL),("some varchar"); + +CREATE TABLE t2 (a int, b varchar(100), KEY (b)); +INSERT INTO t2 VALUES (100,NULL),(150,"varchar"),(200,NULL),(250,"long long varchar"); + +set join_cache_level = 5; +explain SELECT t2.a FROM t1 LEFT JOIN t2 ON t2.b = t1.b; +--sorted_result +SELECT t2.a FROM t1 LEFT JOIN t2 ON t2.b = t1.b; + +set join_cache_level = 8; +explain SELECT t2.a FROM t1 LEFT JOIN t2 ON t2.b = t1.b; +--sorted_result +SELECT t2.a FROM t1 LEFT JOIN t2 ON t2.b = t1.b; + +set join_cache_level = default; +DROP TABLE t1,t2; + +--echo # +--echo # Bug #54359: Extra rows with join_cache_level=7,8 and two joins +--echo # and multi-column index" +--echo # + +CREATE TABLE t1 ( + pk int NOT NULL, + a int DEFAULT NULL, + b varchar(16) DEFAULT NULL, + c varchar(16) DEFAULT NULL, + INDEX idx (b,a)) +; + +INSERT INTO t1 VALUES (4,9,'k','k'); +INSERT INTO t1 VALUES (12,5,'k','k'); + +set join_cache_level = 8; + +EXPLAIN +SELECT t.a FROM t1 t, t1 s FORCE INDEX(idx) + WHERE s.pk AND s.a >= t.pk AND s.b = t.c; + +SELECT t.a FROM t1 t, t1 s FORCE INDEX(idx) + WHERE s.pk AND s.a >= t.pk AND s.b = t.c; + +set join_cache_level = default; +DROP TABLE t1; + +--echo # +--echo # Bug #54235: Extra rows with join_cache_level=6,8 and two LEFT JOINs +--echo # + +CREATE TABLE t1 (a int); +CREATE TABLE t2 (a int); +CREATE TABLE t3 (a int); +CREATE TABLE t4 (a int); + +INSERT INTO t1 VALUES (null), (2), (null), (1); + +set join_cache_level = 6; +EXPLAIN +SELECT t1.a + FROM t1 LEFT JOIN (t2 LEFT JOIN t3 ON t2.a) ON 0 + WHERE t1.a OR t3.a; +SELECT t1.a + FROM t1 LEFT JOIN (t2 LEFT JOIN t3 ON t2.a) ON 0 + WHERE t1.a OR t3.a; + +EXPLAIN +SELECT t1.a + FROM t1 LEFT JOIN (t2 LEFT JOIN (t3 LEFT JOIN t4 ON 1) ON t2.a) ON 0 + WHERE t1.a OR t4.a; +SELECT t1.a + FROM t1 LEFT JOIN (t2 LEFT JOIN (t3 LEFT JOIN t4 ON 1) ON t2.a) ON 0 + WHERE t1.a OR t4.a; + +set join_cache_level = default; +DROP TABLE t1,t2,t3,t4; + +--echo # +--echo # Bug #663840: Memory overwrite causing crash with hash join +--echo # + +SET SESSION join_cache_level=3; +SET SESSION join_buffer_size=100; + +CREATE TABLE t3 ( + i int NOT NULL, + j int NOT NULL, + d date NOT NULL, + t time NOT NULL, + v varchar(1) NOT NULL, + u varchar(1) NOT NULL, + INDEX idx (v) +) COLLATE=latin1_bin; + +INSERT INTO t3 VALUES + (3,8,'2008-12-04','00:00:00','v','v'), (3,8,'2009-03-28','00:00:00','f','f'), + (3,5,'1900-01-01','00:55:47','v','v'), (2,8,'2009-10-02','00:00:00','s','s'), + (1,8,'1900-01-01','20:51:59','a','a'), (0,6,'2008-06-04','09:47:27','p','p'), + (8,7,'2009-01-13','21:58:29','z','z'), (5,2,'1900-01-01','22:45:53','a','a'), + (9,5,'2008-01-28','14:06:48','h','h'), (5,7,'2004-09-18','22:17:16','h','h'), + (4,2,'2006-10-14','14:59:37','v','v'), (2,9,'1900-01-01','23:37:40','v','v'), + (33,142,'2000-11-28','14:14:01','b','b'), (5,3,'2008-04-04','02:54:19','y','y'), + (1,0,'2002-07-13','06:34:26','v','v'), (9,3,'2003-01-03','18:07:38','m','m'), + (1,5,'2006-04-02','13:55:23','z','z'), (3,9,'2006-10-19','20:32:28','n','n'), + (8,1,'2005-06-08','11:57:44','d','d'), (231,107,'2006-12-26','03:10:35','a','a'); + +CREATE TABLE t1 SELECT * FROM t3; +DELETE FROM t1 WHERE i > 8; +CREATE TABLE t2 SELECT * FROM t3; +DELETE FROM t2 WHERE j > 10; + +EXPLAIN +SELECT t1.i, t1.d, t1.v, t2.i, t2.d, t2.t, t2.v FROM t1,t2,t3 + WHERE t3.u <='a' AND t2.j < 5 AND t3.v = t2.u; + +--sorted_result +SELECT t1.i, t1.d, t1.v, t2.i, t2.d, t2.t, t2.v FROM t1,t2,t3 + WHERE t3.u <='a' AND t2.j < 5 AND t3.v = t2.u; + +DROP TABLE t1,t2,t3; + +SET SESSION join_cache_level=DEFAULT; +SET SESSION join_buffer_size=DEFAULT; + + +--echo # +--echo # Bug #664508: 'Simple' GROUP BY + ORDER BY +--echo # when join buffers are used +--echo # + +CREATE TABLE t1 ( + pk int NOT NULL, i int NOT NULL, v varchar(1) NOT NULL, + PRIMARY KEY (pk), INDEX idx1(i), INDEX idx2 (v,i) +) COLLATE latin1_bin; +INSERT INTO t1 VALUES + (10,8,'v'), (11,8,'f'), (12,5,'v'), (13,8,'s'), (14,8,'a'), + (15,6,'p'), (16,7,'z'), (17,2,'a'), (18,5,'h'), (19,7,'h'), + (25,3,'m'), (26,5,'z'), (27,9,'n'), (28,1,'d'), (29,107,'a'); + +CREATE TABLE t2 ( + pk int NOT NULL, i int NOT NULL, v varchar(1) NOT NULL, + PRIMARY KEY (pk), INDEX idx1(i), INDEX idx2(v,i) +) COLLATE latin1_bin; +INSERT INTO t2 VALUES + (10,8,'v'), (11,8,'f'), (12,5,'v'), (13,8,'s'), (14,8,'a'), + (15,6,'p'), (16,7,'z'), (17,2,'a'), (18,5,'h'), (19,7,'h'), + (20,2,'v'), (21,9,'v'), (22,142,'b'), (23,3,'y'), (24,0,'v'), + (25,3,'m'), (26,5,'z'), (27,9,'n'), (28,1,'d'), (29,107,'a'); + +CREATE TABLE t3 ( + pk int NOT NULL, i int NOT NULL, v varchar(1) NOT NULL, + PRIMARY KEY (pk), INDEX idx1(i), INDEX idx2(v,i) +) COLLATE latin1_bin; +INSERT INTO t3 VALUES + (1,9,'x'), (2,5,'g'), (3,1,'o'), (4,0,'g'), (5,1,'v'), + (6,190,'m'), (7,6,'x'), (8,3,'c'), (9,4,'z'), (10,3,'i'), + (11,186,'x'), (12,1,'g'), (13,8,'q'), (14,226,'m'), (15,133,'p'), + (16,6,'e'), (17,3,'t'), (18,8,'j'), (19,5,'h'), (20,7,'w'); + +SET SESSION join_cache_level=1; +EXPLAIN +SELECT t2.v FROM t1, t2, t3 WHERE t3.v <> t2.v AND t3.pk = t2.i AND t1.v = t3.v + GROUP BY t2.v ORDER BY t1.pk,t2.v; +SELECT t2.v FROM t1, t2, t3 WHERE t3.v <> t2.v AND t3.pk = t2.i AND t1.v = t3.v + GROUP BY t2.v ORDER BY t1.pk,t2.v; + +SET SESSION join_cache_level=6; +EXPLAIN +SELECT t2.v FROM t1, t2, t3 WHERE t3.v <> t2.v AND t3.pk = t2.i AND t1.v = t3.v + GROUP BY t2.v ORDER BY t1.pk,t2.v; +SELECT t2.v FROM t1, t2, t3 WHERE t3.v <> t2.v AND t3.pk = t2.i AND t1.v = t3.v + GROUP BY t2.v ORDER BY t1.pk,t2.v; + +SET SESSION join_cache_level=4; +EXPLAIN +SELECT t2.v FROM t1, t2, t3 WHERE t3.v <> t2.v AND t3.pk = t2.i AND t1.v = t3.v + GROUP BY t2.v ORDER BY t1.pk,t2.v; +SELECT t2.v FROM t1, t2, t3 WHERE t3.v <> t2.v AND t3.pk = t2.i AND t1.v = t3.v + GROUP BY t2.v ORDER BY t1.pk,t2.v; + +DROP TABLE t1,t2,t3; + +SET SESSION join_cache_level=DEFAULT; + +--echo # +--echo # Bug #668290: hash join with non-binary collations +--echo # + +CREATE TABLE t1 ( + i int DEFAULT NULL, + cl varchar(10) CHARACTER SET latin1 DEFAULT NULL, + cu varchar(10) CHARACTER SET utf8 DEFAULT NULL, + INDEX cl (cl), + INDEX cu (cu) +); +INSERT INTO t1 VALUES + (650903552,'cmxffkpsel','z'), (535298048,'tvtjrcmxff','y'), + (1626865664,'when','for'), (39649280,'rcvljitvtj','ercvljitvt'), + (792068096,'ttercvljit','jttercvlji'); +INSERT INTO t1 SELECT * FROM t1; + +CREATE TABLE t2 ( + cu varchar(10) CHARACTER SET utf8 DEFAULT NULL, + i int DEFAULT NULL, + cl varchar(10) CHARACTER SET latin1 DEFAULT NULL, + INDEX cu (cu), + INDEX cl (cl) +); +INSERT INTO t2 VALUES + ('g',7,'like'), ('fujttercvl',6,'y'), + ('s',2,'e'), ('didn\'t',0,'v'), + ('gvdrodpedk',8,'chogvdrodp'), ('jichogvdro',7,'will'); + +EXPLAIN +SELECT t2.i FROM t1,t2 WHERE t1.cu = t2.cl ; +SELECT t2.i FROM t1,t2 WHERE t1.cu = t2.cl ; + +SET SESSION join_cache_level = 4; + +EXPLAIN +SELECT t2.i FROM t1,t2 WHERE t1.cu = t2.cl ; +SELECT t2.i FROM t1,t2 WHERE t1.cu = t2.cl ; + +SET SESSION join_cache_level = DEFAULT; + +DROP TABLE t1,t2; + +--echo # +--echo # Bug #669382: hash join using a ref with constant key parts +--echo # + +CREATE TABLE t1 (a int); +INSERT INTO t1 VALUES + (9), (11), (7), (8), (4), (1), (12), (3), (5); +INSERT INTO t1 SELECT * FROM t1; +INSERT INTO t1 SELECT * FROM t1; + +CREATE TABLE t2 (a int, b int, c int, INDEX idx (a,b)); +INSERT INTO t2 VALUES + (8, 80, 800), (1, 10, 100), (1, 11, 101), (3, 30, 300), + (1, 12, 102), (8, 81, 801), (7, 70, 700), (12, 120, 1200), + (8, 82, 802), (1, 13, 103), (1, 14, 104), (3, 31, 301), + (1, 15, 105), (8, 83, 803), (7, 71, 701); + +SET SESSION join_cache_level = 4; +SET SESSION join_buffer_size = 256; + +EXPLAIN +SELECT t1.a, t2.c FROM t1,t2 WHERE t1.a=t2.a AND t2.b=99; +SELECT t1.a, t2.c FROM t1,t2 WHERE t1.a=t2.a AND t2.b=99; + +SET SESSION join_cache_level = DEFAULT; +SET SESSION join_buffer_size = DEFAULT; + +DROP TABLE t1,t2; + +--echo # +--echo # Bug #671901: hash join using a ref to a varchar field +--echo # + +CREATE TABLE t1 ( + v varchar(10) CHARACTER SET latin1 COLLATE latin1_bin DEFAULT NULL, + i int DEFAULT NULL +); +INSERT INTO t1 VALUES + ('k',8), ('abcdefjh',-575340544), ('f',77), ('because', 2), ('f',-517472256), + ('abcdefjhj',5), ('z',7); + +CREATE TABLE t2 ( + v varchar(10) CHARACTER SET latin1 COLLATE latin1_bin DEFAULT NULL, + i int DEFAULT NULL, + INDEX idx (v) +); +INSERT INTO t2 VALUES + ('did',5), ('was',-1631322112), ('are',3), ('abcdefjhjk',3), + ('abcdefjhjk',4), ('tell',-824573952), ('t',0),('v',-1711013888), + ('abcdefjhjk',1015414784), ('or',4), ('now',0), ('abcdefjhjk',-32702464), + ('abcdefjhjk',4), ('time',1078394880), ('f',4), ('m',-1845559296), + ('ff', 5), ('abcdefjhjk',-1074397184); + +EXPLAIN +SELECT t1.v,t2.i FROM t1,t2 WHERE t2.v = t1.v; +SELECT t1.v,t2.i FROM t1,t2 WHERE t2.v = t1.v; +EXPLAIN +SELECT t1.v,t2.i FROM t1,t2 WHERE t2.v = concat(t1.v, t1.v); +SELECT t1.v,t2.i FROM t1,t2 WHERE t2.v = concat(t1.v, t1.v); + +SET SESSION join_cache_level = 4; +EXPLAIN +SELECT t1.v,t2.i FROM t1,t2 WHERE t2.v = t1.v; +SELECT t1.v,t2.i FROM t1,t2 WHERE t2.v = t1.v; +EXPLAIN +SELECT t1.v,t2.i FROM t1,t2 WHERE t2.v = concat(t1.v, t1.v); +SELECT t1.v,t2.i FROM t1,t2 WHERE t2.v = concat(t1.v, t1.v); + +SET SESSION join_cache_level = DEFAULT; + +DROP TABLE t1,t2; + +#--echo # +--echo # Bug #672497: 3 way join with tiny incremental join buffer with +--echo # and a ref access from the first table +--echo # + +CREATE TABLE t1 ( + pk int PRIMARY KEY, + v varchar(10) CHARACTER SET latin1 COLLATE latin1_bin DEFAULT NULL, + INDEX idx (v) +); +INSERT INTO t1 VALUES + (1,'abcdefjhjk'), (2,'i'),(3,'abcdefjhjk'), (4,'well'), (5,'abcdefjhjk'), + (6,'abcdefjhjk'), (7,'that'); + +CREATE TABLE t2 ( + pk int PRIMARY KEY, + i int DEFAULT NULL, + v varchar(1000) CHARACTER SET latin1 COLLATE latin1_bin DEFAULT NULL, + INDEX idx (v) +); +INSERT INTO t2 VALUES + (1,6,'yes'), (2,NULL,'will'), (3,NULL,'o'), (4,NULL,'k'), (5,NULL,'she'), + (6,-1450835968,'abcdefjhjkl'), (7,-975831040,'abcdefjhjkl'), (8,NULL,'z'), + (10,-343932928,'t'), + (11,6,'yes'), (12,NULL,'will'), (13,NULL,'o'), (14,NULL,'k'), (15,NULL,'she'), + (16,-1450835968,'abcdefjhjkl'), (17,-975831040,'abcdefjhjkl'), (18,NULL,'z'), + (19,-343932928,'t'); + +CREATE TABLE t3 ( + pk int NOT NULL PRIMARY KEY, + i int, + v varchar(1024) CHARACTER SET utf8 COLLATE utf8_bin DEFAULT NULL, + INDEX idx (v(333)) +); +INSERT INTO t3 VALUES +(1,7,'abcdefjhjkl'),(2,6,'y'), (3,NULL,'to'),(4,7,'n'),(5,7,'look'), (6,NULL,'all'), +(7,1443168256,'c'), (8,1427046400,'right'), +(11,7,'abcdefjhjkl'), (12,6,'y'), (13,NULL,'to'), (14,7,'n'), (15,7,'look'), +(16,NULL,'all'), (17,1443168256,'c'), (18,1427046400,'right'), +(21,7,'abcdefjhjkl'), (22,6,'y'), (23,NULL,'to'), (24,7,'n'), (25,7,'look'), +(26,NULL,'all'), (27,1443168256,'c'), (28,1427046400,'right'), +(31,7,'abcdefjhjkl'), (32,6,'y'), (33,NULL,'to'), (34,7,'n'), (35,7,'look'), +(36,NULL,'all'), (37,1443168256,'c'), (38,1427046400,'right'); + +SET SESSION join_buffer_size = 256; + +SET SESSION join_cache_level = 4; +EXPLAIN +SELECT t3.i FROM t1,t2,t3 + WHERE t1.v = t2.v AND t3.v = t1.v AND t2.i <> 0; +SELECT t3.i FROM t1,t2,t3 + WHERE t1.v = t2.v AND t3.v = t1.v AND t2.i <> 0; + +SET SESSION join_cache_level = DEFAULT; +SET SESSION join_buffer_size = DEFAULT; + +DROP TABLE t1,t2,t3; + +--echo # +--echo # Bug #672551: hash join over a long varchar field +--echo # + +CREATE TABLE t1 ( + pk int PRIMARY KEY, + a varchar(512) CHARSET latin1 COLLATE latin1_bin DEFAULT NULL, + INDEX idx (a) +); +INSERT INTO t1 VALUES (2, 'aa'), (5, 'ccccccc'), (3, 'bb'); + +CREATE TABLE t2( + pk int PRIMARY KEY, + a varchar(512) CHARSET latin1 COLLATE latin1_bin DEFAULT NULL, + INDEX idx (a) +); +INSERT INTO t2 VALUES + (10, 'a'), (20, 'c'), (30, 'aa'), (4, 'bb'), + (11, 'a'), (21, 'c'), (31, 'aa'), (41, 'cc'), + (12, 'a'), (22, 'c'), (32, 'bb'), (42, 'aa'); + +SELECT * FROM t1,t2 WHERE t2.a=t1.a; + +SET SESSION join_cache_level = 4; +EXPLAIN +SELECT * FROM t1,t2 WHERE t2.a=t1.a; +SELECT * FROM t1,t2 WHERE t2.a=t1.a; + +SET SESSION join_cache_level = DEFAULT; + +DROP TABLE t1,t2; + +--echo # +--echo # Bug #674431: nested outer join when join_cache_level is set to 7 +--echo # + +CREATE TABLE t1 (a int, b varchar(32)) ; +INSERT INTO t1 VALUES (5,'h'), (NULL,'j'); +CREATE TABLE t2 (a int, b varchar(32), c int) ; +INSERT INTO t2 VALUES (5,'h',100), (NULL,'j',200); +CREATE TABLE t3 (a int, b varchar(32), INDEX idx(b)); +INSERT INTO t3 VALUES (77,'h'), (88,'g'); + +SET SESSION optimizer_switch = 'outer_join_with_cache=on'; +SET SESSION join_cache_level = 7; +SELECT t3.a + FROM t1 LEFT JOIN + (t2 LEFT OUTER JOIN t3 ON t2.b = t3.b) ON t2.a = t1.b + WHERE t3.a BETWEEN 3 AND 11 OR t1.a <= t2.c; + +SET SESSION optimizer_switch = 'outer_join_with_cache=off'; +SET SESSION join_cache_level = DEFAULT; + +DROP TABLE t1,t2,t3; + +--echo # +--echo # Bug #52540: nested outer join when join_cache_level is set to 3 +--echo # + +CREATE TABLE t1 (a int); +INSERT INTO t1 VALUES (2); +CREATE TABLE t2 (a varchar(10)); +INSERT INTO t2 VALUES ('f'),('x'); +CREATE TABLE t3 (pk int(11) PRIMARY KEY); +INSERT INTO t3 VALUES (2); +CREATE TABLE t4 (a varchar(10)); + +SET SESSION optimizer_switch = 'outer_join_with_cache=on'; +SET SESSION join_cache_level = 3; + +SELECT * + FROM t2 LEFT JOIN + ((t1 JOIN t3 ON t1.a = t3.pk) LEFT JOIN t4 ON 1) ON 1; + +SET SESSION optimizer_switch = 'outer_join_with_cache=off'; +SET SESSION join_cache_level = DEFAULT; + +DROP TABLE t1,t2,t3,t4; + +--echo # +--echo # Bug #674423: outer join with ON expression over only outer tables +--echo # + +CREATE TABLE t1 (a int) ; +INSERT INTO t1 VALUES ('9'); + +CREATE TABLE t2 (pk int, a int) ; +INSERT INTO t2 VALUES ('9',NULL), ('1',NULL); + +SET SESSION optimizer_switch = 'outer_join_with_cache=on'; + +SET SESSION join_cache_level = 0; +EXPLAIN +SELECT * FROM t2 LEFT JOIN t1 ON t2.a <> 0 WHERE t1.a <> 0 OR t2.pk < 9; +SELECT * FROM t2 LEFT JOIN t1 ON t2.a <> 0 WHERE t1.a <>0 OR t2.pk < 9; + +SET SESSION join_cache_level = 1; +EXPLAIN +SELECT * FROM t2 LEFT JOIN t1 ON t2.a <> 0 WHERE t1.a <> 0 OR t2.pk < 9; +SELECT * FROM t2 LEFT JOIN t1 ON t2.a <> 0 WHERE t1.a <> 0 OR t2.pk < 9; + +SET SESSION optimizer_switch = 'outer_join_with_cache=off'; +SET SESSION join_cache_level = DEFAULT; + +DROP TABLE t1,t2; + +--echo # +--echo # Bug #675095: nested outer join using join buffer +--echo # + +CREATE TABLE t1 (pk int, a1 int) ; +INSERT IGNORE INTO t1 VALUES (2,NULL), (8,0); + +CREATE TABLE t2 (pk int, a2 int, c2 int, d2 int) ; +INSERT IGNORE INTO t2 VALUES (9,0,0,2), (1,0,0,7); + +CREATE TABLE t3 (pk int, a3 int, c3 int, d3 int) ; +INSERT IGNORE INTO t3 VALUES (9,0,0,2), (1,0,0,7); + +CREATE TABLE t4 (pk int, a4 int, INDEX idx(a4)) ; +INSERT IGNORE INTO t4 VALUES (2,NULL), (8,0); + +CREATE TABLE t5 (pk int, a5 int) ; +INSERT IGNORE INTO t5 VALUES (2,0), (8,0); + + +SET SESSION optimizer_switch = 'outer_join_with_cache=on'; + +SET SESSION join_cache_level = 0; + +EXPLAIN EXTENDED +SELECT * + FROM ((t1 LEFT JOIN (t2 JOIN t3 ON t2.c2 = t3.a3) ON t1.pk = t2.d2) + LEFT JOIN t4 ON t1.a1 = t4.a4) LEFT JOIN t5 ON t3.a3 = t5.a5; +SELECT * + FROM ((t1 LEFT JOIN (t2 JOIN t3 ON t2.c2 = t3.a3) ON t1.pk = t2.d2) + LEFT JOIN t4 ON t1.a1 = t4.a4) LEFT JOIN t5 ON t3.a3 = t5.a5; + +SET SESSION join_cache_level = 2; + +EXPLAIN EXTENDED +SELECT * + FROM ((t1 LEFT JOIN (t2 JOIN t3 ON t2.c2 = t3.a3) ON t1.pk = t2.d2) + LEFT JOIN t4 ON t1.a1 = t4.a4) LEFT JOIN t5 ON t3.a3 = t5.a5; +SELECT * + FROM ((t1 LEFT JOIN (t2 JOIN t3 ON t2.c2 = t3.a3) ON t1.pk = t2.d2) + LEFT JOIN t4 ON t1.a1 = t4.a4) LEFT JOIN t5 ON t3.a3 = t5.a5; + +SET SESSION join_cache_level = 1; + +EXPLAIN EXTENDED +SELECT * + FROM ((t1 LEFT JOIN (t2 JOIN t3 ON t2.c2 = t3.a3) ON t1.pk = t2.d2) + LEFT JOIN t4 ON t1.a1 = t4.a4) LEFT JOIN t5 ON t3.a3 = t5.a5; +SELECT * + FROM ((t1 LEFT JOIN (t2 JOIN t3 ON t2.c2 = t3.a3) ON t1.pk = t2.d2) + LEFT JOIN t4 ON t1.a1 = t4.a4) LEFT JOIN t5 ON t3.a3 = t5.a5; + +SET SESSION optimizer_switch = 'outer_join_with_cache=off'; +SET SESSION join_cache_level = DEFAULT; + +DROP TABLE t1,t2,t3,t4,t5; + +--echo # +--echo # Bug #675516: nested outer join with 3 tables in the nest +--echo # using BNL + BNLH +--echo # + +CREATE TABLE t1 (a1 int, b1 int, c1 int) ; +INSERT INTO t1 VALUES (7,8,0), (6,4,0); + +CREATE TABLE t2 (a2 int) ; +INSERT INTO t2 VALUES (5); + +CREATE TABLE t3 (a3 int, b3 int, c3 int, PRIMARY KEY (b3)) ; +INSERT INTO t3 VALUES (2,5,0); + +CREATE TABLE t4 (a4 int, b4 int, c4 int) ; +INSERT INTO t4 VALUES (7,8,0); + +SET SESSION optimizer_switch = 'outer_join_with_cache=on'; + +SET SESSION join_cache_level = 4; +EXPLAIN +SELECT * FROM + t1 LEFT JOIN + ((t2 JOIN t3 ON t2.a2 = t3.b3) JOIN t4 ON t4.b4 <> 0) ON t1.c1 = t3.c3 + WHERE t3.a3 IS NULL; +SELECT * FROM + t1 LEFT JOIN + ((t2 JOIN t3 ON t2.a2 = t3.b3) JOIN t4 ON t4.b4 <> 0) ON t1.c1 = t3.c3 + WHERE t3.a3 IS NULL; + +SET SESSION join_cache_level = 0; +EXPLAIN +SELECT * FROM + t1 LEFT JOIN + ((t2 JOIN t3 ON t2.a2 = t3.b3) JOIN t4 ON t4.b4 <> 0) ON t1.c1 = t3.c3 + WHERE t3.a3 IS NULL; +SELECT * FROM + t1 LEFT JOIN + ((t2 JOIN t3 ON t2.a2 = t3.b3) JOIN t4 ON t4.b4 <> 0) ON t1.c1 = t3.c3 + WHERE t3.a3 IS NULL; + +SET SESSION optimizer_switch = 'outer_join_with_cache=off'; +SET SESSION join_cache_level = DEFAULT; + +DROP TABLE t1,t2,t3,t4; + +--echo # +--echo # Bug #660963: nested outer join with join_cache_level set to 5 +--echo # + +CREATE TABLE t1 (a1 int) ; +INSERT INTO t1 VALUES (0),(0); + +CREATE TABLE t2 (a2 int, b2 int, PRIMARY KEY (a2)) ; +INSERT INTO t2 VALUES (2,1); + +CREATE TABLE t3 (a3 int, b3 int, PRIMARY KEY (a3)) ; +INSERT INTO t3 VALUES (2,1); + +SET SESSION optimizer_switch = 'outer_join_with_cache=on'; + +SET SESSION join_cache_level = 6; +EXPLAIN +SELECT * FROM t1 LEFT JOIN t2 JOIN t3 ON t3.a3 = t2.a2 ON t3.b3 <> 0; +SELECT * FROM t1 LEFT JOIN t2 JOIN t3 ON t3.a3 = t2.a2 ON t3.b3 <> 0; + +SET SESSION join_cache_level = 5; +EXPLAIN +SELECT * FROM t1 LEFT JOIN t2 JOIN t3 ON t3.a3 = t2.a2 ON t3.b3 <> 0; +SELECT * FROM t1 LEFT JOIN t2 JOIN t3 ON t3.a3 = t2.a2 ON t3.b3 <> 0; + +SET SESSION optimizer_switch = 'outer_join_with_cache=off'; +SET SESSION join_cache_level = DEFAULT; + +DROP TABLE t1,t2,t3; + +--echo # +--echo # Bug #675922: incremental buffer for BKA with access from previous +--echo # buffers from non-nullable columns whose values may be null +--echo # + +CREATE TABLE t1 (a1 varchar(32)) ; +INSERT INTO t1 VALUES ('s'),('k'); + +CREATE TABLE t2 (a2 int PRIMARY KEY, b2 varchar(32)) ; +INSERT INTO t2 VALUES (7,'s'); + +CREATE TABLE t3 (a3 int PRIMARY KEY, b3 varchar(32)) ; +INSERT INTO t3 VALUES (7,'s'); + +CREATE TABLE t4 (a4 int) ; +INSERT INTO t4 VALUES (9); + +CREATE TABLE t5(a5 int PRIMARY KEY, b5 int) ; +INSERT INTO t5 VALUES (7,0); + +SET SESSION optimizer_switch = 'outer_join_with_cache=on'; + +SET SESSION join_cache_level = 0; +EXPLAIN +SELECT t4.a4, t5.b5 + FROM ((t1 LEFT JOIN (t2 JOIN t3 ON t2.a2 = t3.a3) ON t2.b2 = t1.a1) + LEFT JOIN t4 ON t4.a4 <> 0) LEFT JOIN t5 ON t5.a5 = t2.a2; +SELECT t4.a4, t5.b5 + FROM ((t1 LEFT JOIN (t2 JOIN t3 ON t2.a2 = t3.a3) ON t2.b2 = t1.a1) + LEFT JOIN t4 ON t4.a4 <> 0) LEFT JOIN t5 ON t5.a5 = t2.a2; + +SET SESSION join_cache_level = 6; +EXPLAIN +SELECT t4.a4, t5.b5 + FROM ((t1 LEFT JOIN (t2 JOIN t3 ON t2.a2 = t3.a3) ON t2.b2 = t1.a1) + LEFT JOIN t4 ON t4.a4 <> 0) LEFT JOIN t5 ON t5.a5 = t2.a2; +SELECT t4.a4, t5.b5 + FROM ((t1 LEFT JOIN (t2 JOIN t3 ON t2.a2 = t3.a3) ON t2.b2 = t1.a1) + LEFT JOIN t4 ON t4.a4 <> 0) LEFT JOIN t5 ON t5.a5 = t2.a2; + +SET SESSION optimizer_switch = 'outer_join_with_cache=off'; +SET SESSION join_cache_level = DEFAULT; + +DROP TABLE t1,t2,t3,t4,t5; + +--echo # +--echo # Bug #670380: hash join for non-binary collation +--echo # + + +CREATE TABLE t1 (pk int PRIMARY KEY, a varchar(32)); +CREATE TABLE t2 (pk int PRIMARY KEY, a varchar(32), INDEX idx(a)); +INSERT INTO t1 VALUES + (10,'AAA'), (20,'BBBB'), (30,'Cc'), (40,'DD'), (50,'ee'); +INSERT INTO t2 VALUES + (1,'Bbbb'), (2,'BBB'), (3,'bbbb'), (4,'AaA'), (5,'CC'), + (6,'cC'), (7,'CCC'), (8,'AAA'), (9,'bBbB'), (10,'aaaa'), + (11,'a'), (12,'dd'), (13,'EE'), (14,'ee'), (15,'D'); + +SET SESSION join_cache_level = 4; + +EXPLAIN +SELECT * FROM t1,t2 WHERE t1.a=t2.a; +SELECT * FROM t1,t2 WHERE t1.a=t2.a; + +SET SESSION join_cache_level = DEFAULT; + +DROP TABLE t1,t2; + +--echo # +--echo # Bug #694092: incorrect detection of index only pushdown conditions +--echo # + +CREATE TABLE t1 ( + f1 varchar(10), f3 int(11), PRIMARY KEY (f3) +); +INSERT INTO t1 VALUES ('y',1),('or',5); + +CREATE TABLE t2 ( + f3 int(11), f2 varchar(1024), f4 varchar(10), PRIMARY KEY (f3) +); +INSERT INTO t2 VALUES (6,'RPOYT','y'),(10,'JINQE','m'); + +SET SESSION join_cache_level = 1; + +SET SESSION optimizer_switch = 'index_condition_pushdown=off'; +EXPLAIN +SELECT * FROM t1,t2 + WHERE t1.f1 = t2.f4 AND (t1.f3 = 1 AND t2.f3 = 4 OR t1.f3 = 2 AND t2.f3 = 6); +SELECT * FROM t1,t2 + WHERE t1.f1 = t2.f4 AND (t1.f3 = 1 AND t2.f3 = 4 OR t1.f3 = 2 AND t2.f3 = 6); + +SET SESSION optimizer_switch = 'index_condition_pushdown=on'; +EXPLAIN +SELECT * FROM t1,t2 + WHERE t1.f1 = t2.f4 AND (t1.f3 = 1 AND t2.f3 = 4 OR t1.f3 = 2 AND t2.f3 = 6); +SELECT * FROM t1,t2 + WHERE t1.f1 = t2.f4 AND (t1.f3 = 1 AND t2.f3 = 4 OR t1.f3 = 2 AND t2.f3 = 6); + +SET SESSION join_cache_level = DEFAULT; +SET SESSION optimizer_switch = @local_join_cache_test_optimizer_switch_default; + +DROP TABLE t1,t2; + +# The same cause of the problem but no join buffer is used (see bug #695442) + +CREATE TABLE t1 (f1 int, f2 varchar(10), KEY (f1), KEY (f2)) ; +INSERT INTO t1 VALUES + (4,'e'), (891879424,'l'), (-243400704,'ectlyqupbk'), (1851981824,'of'), + (-1495203840,'you'), (4,'no'), (-1436942336,'c'), (891420672,'DQQYO'), + (608698368,'qergldqmec'), (1,'x'); + +CREATE TABLE t2 (f3 varchar(64), KEY (f3)); +INSERT INTO t2 VALUES + ('d'), ('UALLN'), ('d'), ('z'), ('r'), ('YVAKV'), ('d'), ('TNGZK'), ('e'), + ('xucupaxdyythsgiw'), ('why'), ('ttugkxucupaxdyyt'), ('l'), ('LHTKN'), + ('d'), ('o'), ('v'), ('KGLCJ'), ('your'); + + +SET SESSION optimizer_switch='index_merge_sort_intersection=off'; + +SET SESSION optimizer_switch = 'index_condition_pushdown=off'; +EXPLAIN SELECT * FROM t1,t2 + WHERE t2.f3 = t1.f2 AND t1.f1 IN (9, 0, 100) ORDER BY t1.f2 LIMIT 1; +SELECT * FROM t1,t2 + WHERE t2.f3 = t1.f2 AND t1.f1 IN (9, 0 ,100) ORDER BY t1.f2 LIMIT 1; +SET SESSION optimizer_switch = @local_join_cache_test_optimizer_switch_default; + +SET SESSION optimizer_switch = 'index_condition_pushdown=on'; +EXPLAIN SELECT * FROM t1,t2 + WHERE t2.f3 = t1.f2 AND t1.f1 IN (9, 0 ,100) ORDER BY t1.f2 LIMIT 1; +SELECT * FROM t1,t2 + WHERE t2.f3 = t1.f2 AND t1.f1 IN (9, 0 ,100) ORDER BY t1.f2 LIMIT 1; + +SET SESSION optimizer_switch = @local_join_cache_test_optimizer_switch_default; + +DROP TABLE t1,t2; + +--echo # +--echo # Bug #694443: hash join using IS NULL the an equi-join condition +--echo # + +CREATE TABLE t1 (a int PRIMARY KEY); +INSERT INTO t1 VALUES + (7), (4), (9), (1), (3), (8), (2); + +CREATE TABLE t2 (a int, b int, INDEX idx (a)); +INSERT INTO t2 VALUES + (NULL,10), (4,80), (7,70), (6,11), (7,90), (NULL,40), + (4,77), (4,50), (NULL,41), (7,99), (7,88), (8,12), + (1,21), (4,90), (7,91), (8,22), (6,92), (NULL,42), + (2,78), (2,51), (1,43), (5,97), (5,89); + +SET SESSION join_cache_level = 1; +EXPLAIN +SELECT * FROM t1,t2 WHERE t1.a < 3 and t2.a IS NULL; +SELECT * FROM t1,t2 WHERE t1.a < 3 and t2.a IS NULL; + +SET SESSION join_cache_level = 4; +EXPLAIN +SELECT * FROM t1,t2 WHERE t1.a < 3 and t2.a IS NULL; +SELECT * FROM t1,t2 WHERE t1.a < 3 and t2.a IS NULL; + + +SET SESSION join_cache_level = DEFAULT; + +DROP TABLE t1,t2; + +--echo # +--echo # Bug #697557: hash join on a varchar field +--echo # + +CREATE TABLE t1 ( f1 varchar(10) , f2 int(11) , KEY (f1)); +INSERT INTO t1 VALUES ('r',1), ('m',2); + +CREATE TABLE t2 ( f1 varchar(10) , f2 int(11) , KEY (f1)); +INSERT INTO t2 VALUES + ('hgtofubn',1), ('GDOXZ',91), ('n',2), ('fggxgalh',88), + ('hgtofu',1), ('GDO',101), ('n',3), ('fggxga',55), + ('hgtofu',3), ('GDO',33), ('nn',3), ('fggxgarrr',77); + +SET SESSION join_cache_level=3; + +EXPLAIN +SELECT * FROM t1,t2 WHERE t2.f1 = t1.f1; +SELECT * FROM t1,t2 WHERE t2.f1 = t1.f1; + +SET SESSION join_cache_level = DEFAULT; + +DROP TABLE t1,t2; + +--echo # +--echo # Bug #707827: hash join on varchar column with NULLs +--echo # + +CREATE TABLE t1 (v varchar(1)); +INSERT INTO t1 VALUES ('o'), ('u'); + +CREATE TABLE t2 (a int, v varchar(1), INDEX idx (v)) ; +INSERT INTO t2 VALUES + (8,NULL), (10,'b'), (5,'k'), (4,NULL), + (1,NULL), (11,'u'), (7,NULL), (2,'d'); + +SET SESSION join_buffer_size = 256; + +SET SESSION join_cache_level = 4; +EXPLAIN +SELECT a FROM t1,t2 WHERE t2.v = t1.v ; +SELECT a FROM t1,t2 WHERE t2.v = t1.v ; + +SET SESSION join_cache_level = 1; +EXPLAIN +SELECT a FROM t1,t2 WHERE t2.v = t1.v ; +SELECT a FROM t1,t2 WHERE t2.v = t1.v ; + +SET SESSION join_cache_level = DEFAULT; +SET SESSION join_buffer_size = DEFAULT; + +DROP TABLE t1,t2; + +--echo # +--echo # Bug #802860: crash on join cache + derived + duplicate_weedout +--echo # + +SET SESSION optimizer_switch= + 'semijoin=on,materialization=off,firstmatch=off,loosescan=off,derived_with_keys=on'; + +CREATE TABLE t1 (a int) ; +INSERT IGNORE INTO t1 VALUES (0), (1), (0); + +CREATE TABLE t2 (a int) ; +INSERT IGNORE INTO t2 VALUES (0), (3), (0), (2); + +SET SESSION join_cache_level = 0; + +EXPLAIN +SELECT * FROM (SELECT DISTINCT * FROM t1) t + WHERE t.a IN (SELECT t2.a FROM t2); +SELECT * FROM (SELECT DISTINCT * FROM t1) t + WHERE t.a IN (SELECT t2.a FROM t2); + +SET SESSION join_cache_level = 1; + +EXPLAIN +SELECT * FROM (SELECT DISTINCT * FROM t1) t + WHERE t.a IN (SELECT t2.a FROM t2); +SELECT * FROM (SELECT DISTINCT * FROM t1) t + WHERE t.a IN (SELECT t2.a FROM t2); + +SET SESSION join_cache_level = DEFAULT; + +DROP TABLE t1, t2; + +# this must be the last command in the file +set @@optimizer_switch=@save_optimizer_switch; diff --git a/mysql-test/t/join_nested.test b/mysql-test/t/join_nested.test index 166aab99ccd..deda56eb8ee 100644 --- a/mysql-test/t/join_nested.test +++ b/mysql-test/t/join_nested.test @@ -462,7 +462,6 @@ SELECT t2.a,t2.b,t3.a,t3.b,t4.a,t4.b LEFT JOIN (t1,t2) ON t3.a=1 AND t3.b=t2.b AND t2.b=t4.b; - SELECT t2.a,t2.b,t3.a,t3.b,t4.a,t4.b FROM (t3,t4) LEFT JOIN @@ -1196,9 +1195,6 @@ SELECT COUNT(*) DROP TABLE t1,t2,t3,t4,t5; -# !!!Remove the following if brackets after having merged the code of MWL#128 -if (`SELECT @@join_cache_level=1`) -{ # # BUG#49322: Nested left joins + not-exist optimization # @@ -1238,7 +1234,37 @@ SELECT t1.pk, t1.a, t2.pk, t2.a,t3.pk, t3.a WHERE t3.pk IS NULL; DROP TABLE t1, t2, t3; -} + + +# +# LP BUG#817360: Nested left joins + not-exist optimization +# + +CREATE TABLE t1 (a int NOT NULL ); +INSERT INTO t1 VALUES (9), (9); + +CREATE TABLE t2 (a int NOT NULL ); +INSERT INTO t2 VALUES (9); + +CREATE TABLE t3 (a int NOT NULL, b int); +INSERT INTO t3 VALUES (19,9); + +CREATE TABLE t4 (b int) ; + +SELECT * FROM t1 LEFT JOIN + ((t2 LEFT JOIN t3 ON t2.a=t3.b) LEFT JOIN t4 ON t3.a=t4.b) + ON t1.a=t2.a; +SELECT * FROM t1 LEFT JOIN + ((t2 LEFT JOIN t3 ON t2.a=t3.b) LEFT JOIN t4 ON t3.a=t4.b) + ON t1.a=t2.a + WHERE t3.a IS NULL; +EXPLAIN EXTENDED +SELECT * FROM t1 LEFT JOIN + ((t2 LEFT JOIN t3 ON t2.a=t3.b) LEFT JOIN t4 ON t3.a=t4.b) + ON t1.a=t2.a + WHERE t3.a IS NULL; + +DROP TABLE t1,t2,t3,t4; --echo End of 5.0 tests diff --git a/mysql-test/t/join_nested_jcl6.test b/mysql-test/t/join_nested_jcl6.test index caa656ecd87..6b04d8d58b5 100644 --- a/mysql-test/t/join_nested_jcl6.test +++ b/mysql-test/t/join_nested_jcl6.test @@ -2,6 +2,12 @@ # Run join_nested.test with BKA enabled # +set @save_optimizer_switch_jcl6=@@optimizer_switch; +set @@optimizer_switch='optimize_join_buffer_size=on'; +set @@optimizer_switch='semijoin_with_cache=on'; +set @@optimizer_switch='outer_join_with_cache=on'; +set @@optimizer_switch='mrr=on,mrr_sort_keys=on,index_condition_pushdown=on'; + set join_cache_level=6; show variables like 'join_cache_level'; @@ -93,3 +99,5 @@ DROP TABLE t5,t6,t7,t8; set join_cache_level=default; show variables like 'join_cache_level'; + +set @@optimizer_switch=@save_optimizer_switch_jcl6; diff --git a/mysql-test/t/join_outer.test b/mysql-test/t/join_outer.test index 54d3b8d997d..f98dbcdf7ac 100644 --- a/mysql-test/t/join_outer.test +++ b/mysql-test/t/join_outer.test @@ -1,3 +1,5 @@ +--source include/long_test.inc + # # test of left outer join # @@ -1295,4 +1297,125 @@ select t2.pk, drop table t1,t2,t3,t4; +--echo # +--echo # Bug#57024: Poor performance when conjunctive condition over the outer +--echo # table is used in the on condition of an outer join +--echo # + +create table t1 (a int); +insert into t1 values (NULL), (NULL), (NULL), (NULL); +insert into t1 select * from t1; +insert into t1 select * from t1; +insert into t1 select * from t1; +insert into t1 select * from t1; +insert into t1 select * from t1; +insert into t1 select * from t1; +insert into t1 select * from t1; +insert into t1 select * from t1; +insert into t1 select * from t1; +insert into t1 select * from t1; +insert into t1 select * from t1; +insert into t1 select * from t1; +insert into t1 select * from t1; +insert into t1 select * from t1; +insert into t1 select * from t1; +insert into t1 select * from t1; +insert into t1 select * from t1; +insert into t1 select * from t1; +insert into t1 values (4), (2), (1), (3); + +create table t2 like t1; +insert into t2 select if(t1.a is null, 10, t1.a) from t1; + +create table t3 (a int, b int, index idx(a)); +insert into t3 values (1, 100), (3, 301), (4, 402), (1, 102), (1, 101); + +analyze table t1,t2,t3; + +flush status; +select sum(t3.b) from t1 left join t3 on t3.a=t1.a and t1.a is not null; +show status like "handler_read%"; +flush status; +select sum(t3.b) from t2 left join t3 on t3.a=t2.a and t2.a <> 10; +show status like "handler_read%"; + +drop table t1,t2,t3; + +--echo # +--echo # Bug#57688 Assertion `!table || (!table->write_set || bitmap_is_set(table->write_set, field +--echo # + +CREATE TABLE t1 (f1 INT NOT NULL, PRIMARY KEY (f1)); +CREATE TABLE t2 (f1 INT NOT NULL, f2 INT NOT NULL, PRIMARY KEY (f1, f2)); + +INSERT INTO t1 VALUES (4); +INSERT INTO t2 VALUES (3, 3); +INSERT INTO t2 VALUES (7, 7); + +EXPLAIN SELECT * FROM t1 LEFT JOIN t2 ON t2.f1 = t1.f1 +WHERE t1.f1 = 4 +GROUP BY t2.f1, t2.f2; + +SELECT * FROM t1 LEFT JOIN t2 ON t2.f1 = t1.f1 +WHERE t1.f1 = 4 +GROUP BY t2.f1, t2.f2; + +EXPLAIN SELECT * FROM t1 LEFT JOIN t2 ON t2.f1 = t1.f1 +WHERE t1.f1 = 4 AND t2.f1 IS NOT NULL AND t2.f2 IS NOT NULL +GROUP BY t2.f1, t2.f2; + +SELECT * FROM t1 LEFT JOIN t2 ON t2.f1 = t1.f1 +WHERE t1.f1 = 4 AND t2.f1 IS NOT NULL AND t2.f2 IS NOT NULL +GROUP BY t2.f1, t2.f2; + +DROP TABLE t1,t2; + --echo End of 5.1 tests + +--echo # +--echo # LP bug #813447: LEFT JOIN with single-row inner table and +--echo # a subquery in ON expression +--echo # + +CREATE TABLE t1 (a int); +INSERT INTO t1 VALUES (0); + +CREATE TABLE t2 (a int); +INSERT INTO t2 VALUES (0); + +CREATE TABLE t3 (a int); +INSERT INTO t3 VALUES (0), (0); + +SELECT t2.a FROM t1 LEFT JOIN t2 ON (6) IN (SELECT a FROM t3); +EXPLAIN EXTENDED +SELECT t2.a FROM t1 LEFT JOIN t2 ON (6) IN (SELECT a FROM t3); + +DROP TABLE t1,t2,t3; + +--echo # +--echo # LP bug #817384 Wrong result with outer join + subquery in ON +--echo # clause +unique key +--echo # + +CREATE TABLE t1 ( c int NOT NULL , b char(1) NOT NULL ) ; +INSERT INTO t1 VALUES (1,'b'); + +CREATE TABLE t2 ( a int NOT NULL , b char(1) NOT NULL , PRIMARY KEY (a)) ; +INSERT INTO t2 VALUES (1,'a'); + +create table t3 (c1 char(1), c2 char(2)); +insert into t3 values ('c','d'); +insert into t3 values ('c','d'); + + +EXPLAIN SELECT t2.b +FROM t1 LEFT JOIN t2 ON t1.c = t2.a AND ( t2.b , t1.b ) IN (SELECT * from t3); +SELECT t2.b +FROM t1 LEFT JOIN t2 ON t1.c = t2.a AND ( t2.b , t1.b ) IN (SELECT * from t3); + +EXPLAIN SELECT t2.b +FROM t1 LEFT JOIN t2 ON (t2.b) IN (SELECT c2 from t3) AND t2.a = 1; +SELECT t2.b +FROM t1 LEFT JOIN t2 ON (t2.b) IN (SELECT c2 from t3) AND t2.a = 1; + +DROP TABLE t1,t2,t3; diff --git a/mysql-test/t/join_outer_jcl6.test b/mysql-test/t/join_outer_jcl6.test index 16543296f27..025e44493af 100644 --- a/mysql-test/t/join_outer_jcl6.test +++ b/mysql-test/t/join_outer_jcl6.test @@ -2,6 +2,12 @@ # Run join_outer.test with BKA enabled # +set @save_optimizer_switch_jcl6=@@optimizer_switch; +set @@optimizer_switch='optimize_join_buffer_size=on'; +set @@optimizer_switch='semijoin_with_cache=on'; +set @@optimizer_switch='outer_join_with_cache=on'; +set optimizer_switch='mrr=on,mrr_sort_keys=on,index_condition_pushdown=on'; + set join_cache_level=6; show variables like 'join_cache_level'; @@ -9,3 +15,5 @@ show variables like 'join_cache_level'; set join_cache_level=default; show variables like 'join_cache_level'; + +set @@optimizer_switch=@save_optimizer_switch_jcl6; diff --git a/mysql-test/t/lock.test b/mysql-test/t/lock.test index 824af06cf69..78f0e2ecf8d 100644 --- a/mysql-test/t/lock.test +++ b/mysql-test/t/lock.test @@ -584,3 +584,27 @@ disconnect con2; # Check that all connections opened by test cases in this file are really # gone so execution of other tests won't be affected by their presence. --source include/wait_until_count_sessions.inc +# +# Test concurrent lock and read locks +# This gave a warning: +# Warning at 'read lock with old write lock' for lock: 5: +# Found lock of type 8 that is write and read locked. Read_no_write_count: 1 +# +create table t1 (a int) engine=myisam; +lock tables t1 write concurrent, t1 as t2 read; +connect (con1,localhost,root,,); +connection con1; +lock tables t1 read local; +unlock tables; +connection default; +unlock tables; +connection con1; +lock tables t1 read local; +connection default; +lock tables t1 write concurrent, t1 as t2 read; +unlock tables; +connection con1; +unlock tables; +disconnect con1; +connection default; +drop table t1; diff --git a/mysql-test/t/lock_multi.test b/mysql-test/t/lock_multi.test index 5bab5e647ab..b180ac9abd5 100644 --- a/mysql-test/t/lock_multi.test +++ b/mysql-test/t/lock_multi.test @@ -529,22 +529,6 @@ unlock tables; connection default; drop table t1; -# -# Bug#25856 HANDLER table OPEN in one connection lock DROP TABLE in another one -# ---disable_warnings -drop table if exists t1; ---enable_warnings -create table t1 (a int) ENGINE=MEMORY; ---echo --> client 2 -connection locker; ---error ER_ILLEGAL_HA -handler t1 open; ---echo --> client 1 -connection default; -drop table t1; - - # Disconnect sessions used in many subtests above disconnect locker; disconnect locker2; diff --git a/mysql-test/t/lock_multi_bug38499.test b/mysql-test/t/lock_multi_bug38499.test index 3d3f084ba5f..b812984e516 100644 --- a/mysql-test/t/lock_multi_bug38499.test +++ b/mysql-test/t/lock_multi_bug38499.test @@ -16,7 +16,9 @@ connect (writer,localhost,root,,); DROP TABLE IF EXISTS t1; --enable_warnings CREATE TABLE t1( a INT, b INT ); +CREATE TABLE t2( a INT, b INT ); INSERT INTO t1 VALUES (1, 1), (2, 2), (3, 3), (4, 4); +INSERT INTO t2 VALUES (1, 1), (2, 2), (3, 3), (4, 4); --echo # 1. test regular tables --echo # 1.1. test altering of columns that multiupdate doesn't use @@ -28,7 +30,7 @@ while ($i) { --dec $i --connection writer - send UPDATE t1, (SELECT 1 FROM t1 t1i) d SET a = 0 WHERE 1=0; + send UPDATE t1, (SELECT 1 FROM t2 t1i) d SET a = 0 WHERE 1=0; --connection locker ALTER TABLE t1 ADD COLUMN (c INT); @@ -41,7 +43,7 @@ while ($i) { --echo # 1.1.2. PS mode --connection writer -PREPARE stmt FROM 'UPDATE t1, (SELECT 1 FROM t1 t1i) d SET a = 0 WHERE 1=0'; +PREPARE stmt FROM 'UPDATE t1, (SELECT 1 FROM t2 t1i) d SET a = 0 WHERE 1=0'; let $i = 100; while ($i) { @@ -75,7 +77,7 @@ while ($i) { UPDATE t1 SET a=b; --connection writer ---send UPDATE t1, (SELECT 1 FROM t1 t1i) d SET a = 0 WHERE 1=0; +--send UPDATE t1, (SELECT 1 FROM t2 t1i) d SET a = 0 WHERE 1=0; --connection locker --error 0,ER_CANT_DROP_FIELD_OR_KEY @@ -100,7 +102,7 @@ while ($i) { UPDATE t1 SET a=b; --connection writer - PREPARE stmt FROM 'UPDATE t1, (SELECT 1 FROM t1 t1i) d SET a = 0 WHERE 1=0'; + PREPARE stmt FROM 'UPDATE t1, (SELECT 1 FROM t2 t1i) d SET a = 0 WHERE 1=0'; --send EXECUTE stmt --connection locker @@ -210,7 +212,7 @@ while ($i) { } --enable_query_log --connection default -DROP TABLE t1; +DROP TABLE t1,t2; # Close connections diff --git a/mysql-test/t/log_tables.test b/mysql-test/t/log_tables.test index 5b6be217d9d..eb652946672 100644 --- a/mysql-test/t/log_tables.test +++ b/mysql-test/t/log_tables.test @@ -290,7 +290,7 @@ drop table mysql.slow_log; use mysql; CREATE TABLE `general_log` ( - `event_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP + `event_time` timestamp(6) NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, `user_host` mediumtext NOT NULL, `thread_id` int(11) NOT NULL, @@ -300,11 +300,11 @@ CREATE TABLE `general_log` ( ) ENGINE=CSV DEFAULT CHARSET=utf8 COMMENT='General log'; CREATE TABLE `slow_log` ( - `start_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP + `start_time` timestamp(6) NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, `user_host` mediumtext NOT NULL, - `query_time` time NOT NULL, - `lock_time` time NOT NULL, + `query_time` time(6) NOT NULL, + `lock_time` time(6) NOT NULL, `rows_sent` int(11) NOT NULL, `rows_examined` int(11) NOT NULL, `db` varchar(512) NOT NULL, @@ -717,10 +717,10 @@ DROP DATABASE IF EXISTS `db_17876`; CREATE DATABASE db_17876; CREATE TABLE `db_17876.slow_log_data` ( - `start_time` timestamp default CURRENT_TIMESTAMP on update CURRENT_TIMESTAMP, + `start_time` timestamp(6) default CURRENT_TIMESTAMP on update CURRENT_TIMESTAMP, `user_host` mediumtext , - `query_time` time , - `lock_time` time , + `query_time` time(6) , + `lock_time` time(6) , `rows_sent` int(11) , `rows_examined` int(11) , `db` varchar(512) default NULL, @@ -731,7 +731,7 @@ CREATE TABLE `db_17876.slow_log_data` ( ); CREATE TABLE `db_17876.general_log_data` ( - `event_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, + `event_time` timestamp(6) NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, `user_host` mediumtext, `thread_id` int(11) DEFAULT NULL, `server_id` int(11) DEFAULT NULL, @@ -743,7 +743,7 @@ DELIMITER //; CREATE procedure `db_17876.archiveSlowLog`() BEGIN - DECLARE start_time, query_time, lock_time CHAR(20); + DECLARE start_time, query_time, lock_time CHAR(28); DECLARE user_host MEDIUMTEXT; DECLARE rows_set, rows_examined, last_insert_id, insert_id, server_id INT; DECLARE dbname MEDIUMTEXT; @@ -783,7 +783,7 @@ END // CREATE procedure `db_17876.archiveGeneralLog`() BEGIN - DECLARE event_time CHAR(20); + DECLARE event_time CHAR(28); DECLARE user_host, argument MEDIUMTEXT; DECLARE thread_id, server_id INT; DECLARE sql_text BLOB; diff --git a/mysql-test/t/maria_icp.test b/mysql-test/t/maria_icp.test new file mode 100644 index 00000000000..d8af34daf2e --- /dev/null +++ b/mysql-test/t/maria_icp.test @@ -0,0 +1,17 @@ +# +# ICP/Maria tests (Index Condition Pushdown) +# + +--source include/have_maria.inc + +set @save_storage_engine= @@storage_engine; +set storage_engine=Maria; +set @maria_icp_tmp=@@optimizer_switch; +set optimizer_switch='mrr=on,mrr_sort_keys=on,index_condition_pushdown=on'; + +--source include/icp_tests.inc + +set storage_engine= @save_storage_engine; +set optimizer_switch=@maria_icp_tmp; + + diff --git a/mysql-test/t/maria_mrr.test b/mysql-test/t/maria_mrr.test index 5f6036d6aea..9d26a01d5e0 100644 --- a/mysql-test/t/maria_mrr.test +++ b/mysql-test/t/maria_mrr.test @@ -1,16 +1,54 @@ -- source include/have_maria.inc +# +# MRR/Maria tests. +# --disable_warnings drop table if exists t1,t2,t3,t4; --enable_warnings +set @maria_mrr_tmp=@@optimizer_switch; +set optimizer_switch='mrr=on,mrr_sort_keys=on,index_condition_pushdown=on'; + +set @mrr_buffer_size_save= @@mrr_buffer_size; + set @save_storage_engine= @@storage_engine; set storage_engine=aria; --source include/mrr_tests.inc - set storage_engine= @save_storage_engine; +set @@mrr_buffer_size= @mrr_buffer_size_save; + +--echo # +--echo # Crash in quick_range_seq_next() in maria-5.3-dsmrr-cpk with join_cache_level = {8,1} +--echo # +set @save_join_cache_level= @@join_cache_level; +SET SESSION join_cache_level = 8; +CREATE TABLE `t1` ( + `col_int_key` int(11) DEFAULT NULL, + `col_datetime_key` datetime DEFAULT NULL, + `col_varchar_key` varchar(1) DEFAULT NULL, + `col_varchar_nokey` varchar(1) DEFAULT NULL, + KEY `col_varchar_key` (`col_varchar_key`,`col_int_key`) +) ENGINE=MARIA DEFAULT CHARSET=latin1 PAGE_CHECKSUM=1; +INSERT INTO `t1` VALUES (6,'2005-10-07 00:00:00','e','e'); +INSERT INTO `t1` VALUES (51,'2000-07-15 05:00:34','f','f'); +CREATE TABLE `t2` ( + `col_int_key` int(11) DEFAULT NULL, + `col_datetime_key` datetime DEFAULT NULL, + `col_varchar_key` varchar(1) DEFAULT NULL, + `col_varchar_nokey` varchar(1) DEFAULT NULL, + KEY `col_varchar_key` (`col_varchar_key`,`col_int_key`) +) ENGINE=MARIA DEFAULT CHARSET=latin1 PAGE_CHECKSUM=1; +INSERT INTO `t2` VALUES (2,'2004-10-11 18:13:16','w','w'); +INSERT INTO `t2` VALUES (2,'1900-01-01 00:00:00','d','d'); +SELECT table2 .`col_datetime_key` +FROM t2 JOIN ( t1 table2 JOIN t2 table3 ON table3 .`col_varchar_key` < table2 .`col_varchar_key` ) ON table3 .`col_varchar_nokey` ; + +drop table t1, t2; +set join_cache_level=@save_join_cache_level; + # # Bug #665049: index condition pushdown with Maria # @@ -53,76 +91,119 @@ EXPLAIN DROP TABLE t1,t2,t3; --echo # ---echo # Bug #669420: MRR for Range checked for each record +--echo # BUG#671361: virtual int Mrr_ordered_index_reader::refill_buffer(): Assertion `!know_key_tuple_params +--echo # (works only on Maria because we need 1024-byte long key) --echo # +SET SESSION join_cache_level = 6; +SET SESSION join_buffer_size = 1024; CREATE TABLE t1 ( - pk int NOT NULL PRIMARY KEY, - j int NOT NULL, - i int NOT NULL, - v varchar(1) CHARACTER SET latin1 COLLATE latin1_bin NOT NULL, - INDEX i (i), - INDEX vi (v,i) -) ENGINE=ARIA; -INSERT INTO t1 VALUES (10,3,8,'v'),(11,3,8,'f'); + pk int(11) NOT NULL AUTO_INCREMENT, + col_varchar_1024_latin1_key varchar(1024) DEFAULT NULL, + PRIMARY KEY (pk), + KEY col_varchar_1024_latin1_key (col_varchar_1024_latin1_key) +) ENGINE=Aria; + +INSERT INTO t1 VALUES +(1,'z'), +(2,'abcdefjhjkl'), +(3,'in'), +(4,'abcdefjhjkl'), +(6,'abcdefjhjkl'); CREATE TABLE t2 ( - pk int NOT NULL PRIMARY KEY, - j int NOT NULL, - i int NOT NULL, - v varchar(1) CHARACTER SET latin1 COLLATE latin1_bin NOT NULL, - INDEX i (i), - INDEX vi (v,i) -) ENGINE=ARIA; -INSERT INTO t2 VALUES (10,9,3,'i'),(11,101,186,'x'),(12,0,1,'g'); + col_varchar_10_latin1 varchar(10) DEFAULT NULL +) ENGINE=Aria; +INSERT INTO t2 VALUES ('foo'), ('foo'); -SET SESSION join_cache_level=0; +EXPLAIN SELECT count(*) +FROM t1 AS table1, t2 AS table2 +WHERE + table1.col_varchar_1024_latin1_key = table2.col_varchar_10_latin1 AND table1.pk<>0 ; -EXPLAIN -SELECT t1.i, t2.i, t2.v, t3.pk, t3.v FROM t1, t2, t2 t3 - WHERE t2.i != 0 AND t3.pk >= t2.i AND t3.v >= t2.v; -SELECT t1.i, t2.i, t2.v, t3.pk, t3.v FROM t1, t2, t2 t3 - WHERE t2.i != 0 AND t3.pk >= t2.i AND t3.v >= t2.v; +SELECT count(*) +FROM t1 AS table1, t2 AS table2 +WHERE + table1.col_varchar_1024_latin1_key = table2.col_varchar_10_latin1 AND table1.pk<>0 ; -SET SESSION join_cache_level=1; - -EXPLAIN -SELECT t1.i, t2.i, t2.v, t3.pk, t3.v FROM t1, t2, t2 t3 - WHERE t2.i != 0 AND t3.pk >= t2.i AND t3.v >= t2.v; -SELECT t1.i, t2.i, t2.v, t3.pk, t3.v FROM t1, t2, t2 t3 - WHERE t2.i != 0 AND t3.pk >= t2.i AND t3.v >= t2.v; +drop table t1, t2; -SET SESSION join_cache_level=DEFAULT; +--echo # +--echo # BUG#693747: Assertion multi_range_read.cc:908: int DsMrr_impl::dsmrr_init( +--echo # +set @_save_join_cache_level= @@join_cache_level; +set @_save_join_buffer_size= @@join_buffer_size; -DROP TABLE t1,t2; +set join_cache_level=8; +set join_buffer_size=10240; CREATE TABLE t1 ( - pk int NOT NULL PRIMARY KEY, - j int NOT NULL, - i int NOT NULL, - v varchar(1) CHARACTER SET latin1 COLLATE latin1_bin NOT NULL, - INDEX i (i) -) ENGINE=ARIA; -INSERT INTO t1 VALUES - (10,3,8,'v'),(11,3,8,'f'),(12,3,5,'v'),(13,2,8,'s'),(14,1,8,'a'), - (15,0,6,'p'),(16,8,7,'z'),(17,5,2,'a'),(18,9,5,'h'),(19,5,7,'h'), - (20,4,2,'v'),(21,2,9,'v'),(22,33,142,'b'),(23,5,3,'y'),(24,1,0,'v'), - (25,9,3,'m'),(26,1,5,'z'),(27,3,9,'n'),(28,8,1,'d'),(29,231,107,'a'); - -SET SESSION join_cache_level = 0; - -EXPLAIN -SELECT s.i f FROM t1 t, t1 s WHERE s.i >= t.i AND s.pk < t.j; -SELECT s.i f FROM t1 t, t1 s WHERE s.i >= t.i AND s.pk < t.j; - -EXPLAIN -SELECT s.i f FROM t1 t, t1 s WHERE s.i >= t.i AND s.pk < t.j GROUP BY f; -SELECT s.i f FROM t1 t, t1 s WHERE s.i >= t.i AND s.pk < t.j GROUP BY f; - -EXPLAIN -SELECT s.i f FROM t1 t, t1 s WHERE s.i >= t.i AND s.pk < t.j GROUP BY f LIMIT 1; -SELECT s.i f FROM t1 t, t1 s WHERE s.i >= t.i AND s.pk < t.j GROUP BY f LIMIT 1; - -SET SESSION join_cache_level=DEFAULT; - -DROP TABLE t1; + f2 varchar(32) COLLATE latin1_swedish_ci, + f3 int(11), + f4 varchar(1024) COLLATE utf8_bin, + f5 varchar(1024) COLLATE latin1_bin, + KEY (f5) +) ENGINE=Aria TRANSACTIONAL=0 ; + +--echo # Fill the table with some data +--disable_query_log +INSERT IGNORE INTO t1 VALUES +('cueikuirqr','0','f4-data','hcueikuirqrzflno'),('her','0','f4-data','ehcueikuirqrzfln'), +('YKAOE','0','f4-data','qieehcueikuirqrz'),('youre','0','f4-data','nkqieehcueikuirq'), +('b','0','f4-data','the'),('MGUDG','0','f4-data','m'), +('UXAGU','0','f4-data','HZXVA'),('bwbgsnkqie','0','f4-data','something'), +('s','0','f4-data','slelfhjawbwbgsnk'),('the','0','f4-data','if'), +('TDLKE','0','f4-data','MGWNJ'),('do','0','f4-data','see'), +('why','0','f4-data','mean'),('THKCG','0','f4-data','YFLDY'), +('x','0','f4-data','e'),('yncitaeysb','0','f4-data','tgyncitaeysbgucs'), +('ZEOXX','0','f4-data','jawbwbgsnkqieehc'),('hjawbwbgsn','0','f4-data','fhjawbwbgsnkqiee'), +('all','0','f4-data','sbgucsgqslelfhja'),('the','0','f4-data','would'), +('mtgyncitae','0','f4-data','ISNQQ'),('KNCUI','0','f4-data','want'), +('is','0','f4-data','i'),('out','0','f4-data','jvcmjlmtgyncitae'), +('it','0','f4-data','you'),('LHDIH','0','f4-data','txmtxyjvcmjlmtgy'), +('z','0','f4-data','ntxmtxyjvcmjlmtg'),('vyhnmvgmcn','0','f4-data','AIGQK'), +('ytvyhnmvgm','0','f4-data','z'),('t','0','f4-data','on'), +('xqegbytvyh','0','f4-data','ixqegbytvyhnmvgm'),('WGVRU','0','f4-data','h'), +('b','0','f4-data','z'),('who','0','f4-data','gddixqegbytvy'), +('PMLFL','0','f4-data','vgmcntxmtxyjvcmj'),('back','0','f4-data','n'), +('i','0','f4-data','PZGUB'),('f','0','f4-data','the'), +('PNXVP','0','f4-data','v'),('MAKKL','0','f4-data','CGCWF'), +('RMDAV','0','f4-data','v'),('l','0','f4-data','n'), +('rhnoypgddi','0','f4-data','VIZNE'),('t','0','f4-data','a'), +('like','0','f4-data','JSHPZ'),('pskeywslmk','0','f4-data','q'), +('QZZJJ','0','f4-data','c'),('atlxepskey','0','f4-data','YJRMA'), +('YUVOU','0','f4-data','eywslmkdrhnoypgd'),('some','0','f4-data','r'), +('c','0','f4-data','her'),('o','0','f4-data','EMURT'), +('if','0','f4-data','had'),('when','0','f4-data','CLVWT'), +('blfufrcdjm','0','f4-data','IZCZN'),('vutblfufrc','0','f4-data','how'), +('why','0','f4-data','I'),('IXLYQ','0','f4-data','weuwuvutblfufrcd'), +('here','0','f4-data','m'),('ZOCTJ','0','f4-data','IDSFD'), +('kqsweuwuvu','0','f4-data','oh'),('ykqsweuwuv','0','f4-data','zykqsweuwuvutblf'), +('zezykqsweu','0','f4-data','t'),('q','0','f4-data','o'), +('IBKAU','0','f4-data','oh'),('ivjisuzezy','0','f4-data','XHXKE'), +('xsivjisuze','0','f4-data','plxsivjisuzezykq'),('have','0','f4-data','uvplxsivjisuzezy'), +('on','0','f4-data','me'),('ijkfuvplxs','0','f4-data','OGEHV'), +('u','0','f4-data','okay'),('i','0','f4-data','pajzbbojshnijkfu'), +('of','0','f4-data','g'),('for','0','f4-data','Im'), +('or','0','f4-data','ZOJHX'),('n','0','f4-data','you'), +('that','0','f4-data','just'),('bbojshnijk','0','f4-data','JYGSJ'), +('k','0','f4-data','y'),('k','0','f4-data','y'), +('be','0','f4-data','m'),('fnbmxwicrk','0','f4-data','t'), +('yaffpegvav','0','f4-data','have'),('crkdymahya','0','f4-data','QQWQI'), +('t','0','f4-data','hnijkfuvplxsivji'),('dgxpajzbbo','0','f4-data','vavdgxpajzbbojsh'), +('g','0','f4-data','pegvavdgxpajzbbo'),('Im','0','f4-data','ffpegvavdgxpajzb'); +--enable_query_log + + +SELECT alias2.* , alias1.f2 +FROM + t1 AS alias1 + LEFT JOIN t1 AS alias2 ON alias1.f2 = alias2.f5 +WHERE + alias2.f3 < 0; + +set join_cache_level=@_save_join_cache_level; +set join_buffer_size=@_save_join_buffer_size; +set optimizer_switch=@maria_mrr_tmp; + +drop table t1; diff --git a/mysql-test/t/merge.test b/mysql-test/t/merge.test index e45813ff616..ca2f5ebb4d7 100644 --- a/mysql-test/t/merge.test +++ b/mysql-test/t/merge.test @@ -1976,21 +1976,6 @@ SELECT f1() FROM (SELECT 1 UNION SELECT 1) c1; DROP FUNCTION f1; DROP TABLE tm1, t1, t2; # -CREATE TEMPORARY TABLE t1 (c1 INT); -INSERT INTO t1 (c1) VALUES (1); -CREATE TEMPORARY TABLE tm1 (c1 INT) ENGINE=MRG_MYISAM UNION=(t1); -DELIMITER |; ---error ER_SP_BADSTATEMENT -CREATE FUNCTION f1() RETURNS INT -BEGIN - CREATE TEMPORARY TABLE t2 (c1 INT); - ALTER TEMPORARY TABLE tm1 UNION=(t1,t2); - INSERT INTO t2 (c1) VALUES (2); - RETURN (SELECT MAX(c1) FROM tm1); -END| -DELIMITER ;| -DROP TABLE tm1, t1; -# # Base table. No LOCK TABLES, no functions/triggers. # CREATE TABLE t1 (c1 INT) ENGINE=MyISAM; diff --git a/mysql-test/t/metadata.test b/mysql-test/t/metadata.test index 4653864a6c0..a859f39e51d 100644 --- a/mysql-test/t/metadata.test +++ b/mysql-test/t/metadata.test @@ -200,3 +200,10 @@ select * from t1; --disable_metadata drop table t1; + +# +# lp:740173 5.1-micro reports incorrect Length metadata for TIME expressions +# +--enable_metadata +select cast('01:01:01' as time), cast('01:01:01' as time(2)); +--disable_metadata diff --git a/mysql-test/t/mrr_icp_extra.test b/mysql-test/t/mrr_icp_extra.test new file mode 100644 index 00000000000..2d0fd527dcf --- /dev/null +++ b/mysql-test/t/mrr_icp_extra.test @@ -0,0 +1,238 @@ + +set @mrr_icp_extra_tmp=@@optimizer_switch; +set optimizer_switch='mrr=on,mrr_sort_keys=on,index_condition_pushdown=on'; +SET NAMES latin1; +CREATE TABLE t1 +(s1 char(10) COLLATE latin1_german1_ci, + s2 char(10) COLLATE latin1_swedish_ci, + KEY(s1), + KEY(s2)); + +INSERT INTO t1 VALUES ('a','a'); +INSERT INTO t1 VALUES ('b','b'); +INSERT INTO t1 VALUES ('c','c'); +INSERT INTO t1 VALUES ('d','d'); +INSERT INTO t1 VALUES ('e','e'); +INSERT INTO t1 VALUES ('f','f'); +INSERT INTO t1 VALUES ('g','g'); +INSERT INTO t1 VALUES ('h','h'); +INSERT INTO t1 VALUES ('i','i'); +INSERT INTO t1 VALUES ('j','j'); + +EXPLAIN SELECT * FROM t1 WHERE s1='a'; +EXPLAIN SELECT * FROM t1 WHERE s2='a'; +EXPLAIN SELECT * FROM t1 WHERE s1='a' COLLATE latin1_german1_ci; +EXPLAIN SELECT * FROM t1 WHERE s2='a' COLLATE latin1_german1_ci; + +EXPLAIN SELECT * FROM t1 WHERE s1 BETWEEN 'a' AND 'b' COLLATE latin1_german1_ci; +EXPLAIN SELECT * FROM t1 WHERE s2 BETWEEN 'a' AND 'b' COLLATE latin1_german1_ci; + +EXPLAIN SELECT * FROM t1 WHERE s1 IN ('a','b' COLLATE latin1_german1_ci); +EXPLAIN SELECT * FROM t1 WHERE s2 IN ('a','b' COLLATE latin1_german1_ci); + +EXPLAIN SELECT * FROM t1 WHERE s1 LIKE 'a' COLLATE latin1_german1_ci; +EXPLAIN SELECT * FROM t1 WHERE s2 LIKE 'a' COLLATE latin1_german1_ci; + +DROP TABLE t1; + +--echo # +--echo # + +CREATE TABLE t2 (a varchar(32), b int(11), c float, d double, +UNIQUE KEY a (a,b,c), KEY b (b), KEY c (c)); +CREATE TABLE t1 (a varchar(32), b char(3), UNIQUE KEY a (a,b), KEY b (b)); +CREATE TABLE t3 (a varchar(32), b char(3), UNIQUE KEY a (a,b)); +INSERT INTO t3 SELECT * FROM t1; +EXPLAIN +SELECT d FROM t1, t2 +WHERE t2.b=14 AND t2.a=t1.a AND 5.1<t2.c AND t1.b='DE' +ORDER BY t2.c LIMIT 1; +SELECT d FROM t1, t2 +WHERE t2.b=14 AND t2.a=t1.a AND 5.1<t2.c AND t1.b='DE' +ORDER BY t2.c LIMIT 1; + +DROP TABLE t1,t2,t3; + +--echo # +--echo # +create table t1(a int, b int, index(b)); +insert into t1 values (2, 1), (1, 1), (4, NULL), (3, NULL), (6, 2), (5, 2); +explain select * from t1 where b=1 or b is null order by a; +select * from t1 where b=1 or b is null order by a; +explain select * from t1 where b=2 or b is null order by a; +select * from t1 where b=2 or b is null order by a; +drop table t1; + +--echo # +--echo # +CREATE TABLE t1 ( +FieldKey varchar(36) NOT NULL default '', +LongVal bigint(20) default NULL, +StringVal mediumtext, +KEY FieldKey (FieldKey), +KEY LongField (FieldKey,LongVal), +KEY StringField (FieldKey,StringVal(32)) +); +INSERT INTO t1 VALUES ('0',3,'0'),('0',2,'1'),('0',1,'2'),('1',2,'1'),('1',1,'3'), ('1',0,'2'),('2',3,'0'),('2',2,'1'),('2',1,'2'),('2',3,'0'),('2',2,'1'),('2',1,'2'),('3',2,'1'),('3',1,'2'),('3','3','3'); +EXPLAIN SELECT * FROM t1 IGNORE INDEX (LongField, StringField) WHERE FieldKey > '2' ORDER BY LongVal; +EXPLAIN SELECT * FROM t1 IGNORE INDEX (FieldKey, LongField) WHERE FieldKey > '2' ORDER BY LongVal; +SELECT * FROM t1 WHERE FieldKey > '2' ORDER BY LongVal; +DROP TABLE t1; +--echo # +--echo # +CREATE TABLE t1 (a int not null, b int, c int, key(b), key(c), key(a,b), key(c,a)); +INSERT into t1 values (0, null, 0), (0, null, 1), (0, null, 2), (0, null,3), (1,1,4); +create table t2 (a int not null, b int, c int, key(b), key(c), key(a)); +INSERT into t2 values (1,1,1), (2,2,2); +optimize table t1; +explain select * from t1 force index (a) where a=0 or a=2; +select * from t1 force index (a) where a=0 or a=2; +drop table t1; +--echo # +--echo # +create table t1 +( + pk1 int not null, + pk2 int not null, + + key1 int not null, + key2 int not null, + + pktail1ok int not null, + pktail2ok int not null, + pktail3bad int not null, + pktail4bad int not null, + pktail5bad int not null, + + pk2copy int not null, + badkey int not null, + + filler1 char (200), + filler2 char (200), + key (key1), + key (key2), + + /* keys with tails from CPK members */ + key (pktail1ok, pk1), + key (pktail2ok, pk1, pk2), + key (pktail3bad, pk2, pk1), + key (pktail4bad, pk1, pk2copy), + key (pktail5bad, pk1, pk2, pk2copy), + + primary key (pk1, pk2) +); + +--disable_query_log +set autocommit=0; +let $1=10000; +while ($1) +{ + eval insert into t1 values ($1 div 10,$1 mod 100, $1/100,$1/100, $1/100,$1/100,$1/100,$1/100,$1/100, $1 mod 100, $1/1000,'filler-data-$1','filler2'); + dec $1; +} +set autocommit=1; +--enable_query_log +explain select * from t1 where pk1 = 1 and pk2 < 80 and key1=0; +select * from t1 where pk1 = 1 and pk2 < 80 and key1=0; +drop table t1; + +--echo # +--echo # +CREATE TABLE t1 ( +f1 int, +f4 varchar(32), +f5 int, +PRIMARY KEY (f1), +KEY (f4) +); +INSERT INTO t1 VALUES +(5,'H',1), (9,'g',0), (527,'i',0), (528,'y',1), (529,'S',6), +(530,'m',7), (531,'b',2), (532,'N',1), (533,'V',NULL), (534,'l',1), +(535,'M',0), (536,'w',1), (537,'j',5), (538,'l',0), (539,'n',2), +(540,'m',2), (541,'r',2), (542,'l',2), (543,'h',3),(544,'o',0), +(956,'h',0), (957,'g',0), (958,'W',5), (959,'s',3), (960,'w',0), +(961,'q',0), (962,'e',NULL), (963,'u',7), (964,'q',1), (965,'N',NULL), +(966,'e',0), (967,'t',3), (968,'e',6), (969,'f',NULL), (970,'j',0), +(971,'s',3), (972,'I',0), (973,'h',4), (974,'g',1), (975,'s',0), +(976,'r',3), (977,'x',1), (978,'v',8), (979,'j',NULL), (980,'z',7), +(981,'t',9), (982,'j',5), (983,'u',NULL), (984,'g',6), (985,'w',1), +(986,'h',1), (987,'v',0), (988,'v',0), (989,'c',2), (990,'b',7), +(991,'z',0), (992,'M',1), (993,'u',2), (994,'r',2), (995,'b',4), +(996,'A',2), (997,'u',0), (998,'a',0), (999,'j',2), (1,'I',2); +EXPLAIN +SELECT * FROM t1 +WHERE (f1 < 535 OR f1 > 985) AND ( f4='r' OR f4 LIKE 'a%' ) ; +SELECT * FROM t1 +WHERE (f1 < 535 OR f1 > 985) AND ( f4='r' OR f4 LIKE 'a%' ) ; +drop table t1; + +--echo # +--echo # +--source include/varchar.inc + +--echo # +--echo # +--disable_warnings +drop database if exists world; +--enable_warnings +CREATE DATABASE world; + +use world; + +--source include/world_schema.inc + +--disable_query_log +--disable_result_log +--disable_warnings +--source include/world.inc +--enable_warnings +--enable_result_log +--enable_query_log + +SELECT * FROM City +WHERE ((Name > 'Ca' AND Name < 'Cf') OR (Country > 'E' AND Country < 'F')) +AND (Population > 101000 AND Population < 102000); + +--replace_column 9 # +explain +SELECT * FROM City +WHERE ((Name > 'Ca' AND Name < 'Cf') OR (Country > 'E' AND Country < 'F')) +AND (Population > 101000 AND Population < 102000); + +--replace_column 9 # +explain +SELECT * FROM City +WHERE (Name < 'Ac' AND (Country > 'A' AND Country < 'B')) OR +(Name BETWEEN 'P' AND 'Pb' AND (Population > 101000 AND Population < 110000)); + +SELECT * FROM City +WHERE (Name < 'Ac' AND (Country > 'A' AND Country < 'B')) OR +(Name BETWEEN 'P' AND 'Pb' AND (Population > 101000 AND Population < 110000)); + +SELECT * FROM City +WHERE Name LIKE 'M%' AND Population > 7000000; + +--replace_column 9 # +explain +SELECT * FROM City +WHERE Name LIKE 'M%' AND Population > 7000000; + +--replace_column 6 # 7 # 9 # +explain +SELECT * FROM City +WHERE Name BETWEEN 'G' AND 'K' AND Population > 500000 AND Country LIKE 'C%'; +SELECT * FROM City +WHERE Name BETWEEN 'G' AND 'K' AND Population > 500000 AND Country LIKE 'C%'; + +--replace_column 6 # 7 # 9 # +explain +SELECT * FROM City +WHERE Name BETWEEN 'G' AND 'J' AND Population > 500000 AND Country LIKE 'C%'; +SELECT * FROM City +WHERE Name BETWEEN 'G' AND 'J' AND Population > 500000 AND Country LIKE 'C%'; + +drop database world; +use test; + +set @mrr_icp_extra_tmp=@@optimizer_switch; + diff --git a/mysql-test/t/multi_update.test b/mysql-test/t/multi_update.test index 1af5f5fa423..51bb64bd31d 100644 --- a/mysql-test/t/multi_update.test +++ b/mysql-test/t/multi_update.test @@ -684,6 +684,9 @@ CREATE FUNCTION f1 () RETURNS BLOB RETURN 1; CREATE TABLE t1 (f1 DATE); INSERT INTO t1 VALUES('2001-01-01'); UPDATE (SELECT 1 FROM t1 WHERE f1 = (SELECT f1() FROM t1)) x, t1 SET f1 = 1; +CREATE view v1 as SELECT f1() FROM t1; +UPDATE (SELECT 1 FROM t1 WHERE f1 = (select * from v1)) x, t1 SET f1 = 1; +DROP VIEW v1; DROP FUNCTION f1; DROP TABLE t1; diff --git a/mysql-test/t/multi_update2.test b/mysql-test/t/multi_update2.test index 9c5078efb6f..a0f17fabec4 100644 --- a/mysql-test/t/multi_update2.test +++ b/mysql-test/t/multi_update2.test @@ -1,3 +1,5 @@ +--source include/long_test.inc + # # Test of update statement that uses many tables. # diff --git a/mysql-test/t/myisam.test b/mysql-test/t/myisam.test index 3b307497fc3..cab06a03498 100644 --- a/mysql-test/t/myisam.test +++ b/mysql-test/t/myisam.test @@ -1696,7 +1696,6 @@ SET myisam_repair_threads=@@global.myisam_repair_threads; --echo End of 5.1 tests - --echo # --echo # Bug#51327 MyISAM table is automatically repaired on ALTER --echo # even if myisam-recover is OFF @@ -1727,3 +1726,9 @@ ALTER TABLE t1 ENGINE = MyISAM; CHECK TABLE t1; DROP TABLE t1; + +# +# Check some variables +# +show variables like 'myisam_block_size'; +select @@global.myisam_block_size; diff --git a/mysql-test/t/myisam_icp.test b/mysql-test/t/myisam_icp.test new file mode 100644 index 00000000000..66ffbfa3821 --- /dev/null +++ b/mysql-test/t/myisam_icp.test @@ -0,0 +1,212 @@ +# +# ICP/MyISAM tests (Index Condition Pushdown) +# + +--source include/icp_tests.inc + +set @myisam_icp_tmp=@@optimizer_switch; +set optimizer_switch='mrr=on,mrr_sort_keys=on,index_condition_pushdown=on'; + +--disable_warnings +drop table if exists t0, t1, t1i, t1m; +--enable_warnings + +# +# BUG#711565 Index Condition Pushdown can make a thread hold MyISAM locks as well as be unKILLable for long time +# This is not a ready mysqltest testcase but rather a set of queries that +# allow to check the bug[fix] manually. Making this testcase automatic is +# difficult because +# - big tables are involved +# - it's difficult to have automatic checks of whether the query could be +# KILLed that would reliably work on fast/slow buildslaves, etc. + +--disable_parsing + + create table t0 (a int); + insert into t0 values (0),(1),(2),(3),(4),(5),(6),(7),(8),(9); + + create table t1 ( + kp1 int, kp2 int, + filler char(100), + col int, + key(kp1, kp2) + ); + + set myisam_sort_buffer_size=32*1000*1000; + insert into t1 + select + 1000 + A.a + 10*B.a + 100*C.a + 1000*D.a + 10000 * F.a, + 1, + 'filler-data filler-data filler-data filler-data filler-data', + 1 + from + t0 A, t0 B, t0 C, t0 D, t0 E, t0 F, t0 G + ; + + insert into t1 values (990, 100, 'a record to test index_next checks',100); + + update t1 set kp2=10 where kp1 between 20000+100 and 28000; + + update t1 set kp1=20000 where kp1 between 20000 and 28000; + + insert into t1 values (20000, 100, 'last-20K-record',1); + + create table t1i like t1; + alter table t1i engine=innodb; + insert into t1i select * from t1; + + create table t1m like t1; + alter table t1m engine=maria; + insert into t1m select * from t1; + +# +# XtraDB has one check for all kinds of ranges. +# + explain + select * from t1i + where + kp1 < 8000 and + concat(repeat('foo-bar-', 100000), kp2) like '%bar-1%' and + concat(repeat('foo-bar-', 100000), kp2) like '%bar-1%' and + concat(repeat('foo-bar-', 100000), kp2) like '%bar-1%' and + concat(repeat('foo-bar-', 100000), kp2) like '%bar-1%' and + kp2 +1 > 10; + + +# +# MyISAM, check range access + mi_rnext(): +# (will return HA_ERR_END_OF_FILE) + explain + select * from t1 + where + kp1 < 10000 and + concat(repeat('foo-bar-', 100000), kp2) like '%bar-1%' and + concat(repeat('foo-bar-', 100000), kp2) like '%bar-1%' and + concat(repeat('foo-bar-', 100000), kp2) like '%bar-1%' and + concat(repeat('foo-bar-', 100000), kp2) like '%bar-1%' and + kp2 +1 > 10; + + +# +# MyISAM, check range access + mi_rkey(): +# (will return HA_ERR_END_OF_FILE) + explain + select * from t1 + where + kp1 >= 999 and kp1 < 10000 and + concat(repeat('foo-bar-', 100000), kp2) like '%bar-1%' and + concat(repeat('foo-bar-', 100000), kp2) like '%bar-1%' and + concat(repeat('foo-bar-', 100000), kp2) like '%bar-1%' and + concat(repeat('foo-bar-', 100000), kp2) like '%bar-1%' and + kp2 +1 > 10; + + + +# +# MyISAM, check mi_rnext_same: +# + + explain + select * from t1 + where + kp1 = 20000 and + concat(repeat('foo-bar-', 100000), kp2) like '%bar-1%' and + concat(repeat('foo-bar-', 100000), kp2) like '%bar-1%' and + concat(repeat('foo-bar-', 100000), kp2) like '%bar-1%' and + concat(repeat('foo-bar-', 100000), kp2) like '%bar-1%' and + kp2 +1 < 10; + + +# +# MyISAM, check mi_rprev: +# + + explain + select * from t1 + where + kp1 = 20000 and + concat(repeat('foo-bar-', 100000), kp2) like '%bar-1%' and + concat(repeat('foo-bar-', 100000), kp2) like '%bar-1%' and + concat(repeat('foo-bar-', 100000), kp2) like '%bar-1%' and + concat(repeat('foo-bar-', 100000), kp2) like '%bar-1%' and + kp2 +1 > 20 + order by kp1, kp2 desc; + + + +# +# Maria, check range access + maria_rkey(): +# + explain + select * from t1m + where + kp1 >= 999 and kp1 < 10000 and + concat(repeat('foo-bar-', 100000), kp2) like '%bar-1%' and + concat(repeat('foo-bar-', 100000), kp2) like '%bar-1%' and + concat(repeat('foo-bar-', 100000), kp2) like '%bar-1%' and + concat(repeat('foo-bar-', 100000), kp2) like '%bar-1%' and + kp2 +1 > 10; + + + +# +# Maria, check range access + maria_rnext(): +# + explain + select * from t1m + where + kp1 < 10000 and + concat(repeat('foo-bar-', 100000), kp2) like '%bar-1%' and + concat(repeat('foo-bar-', 100000), kp2) like '%bar-1%' and + concat(repeat('foo-bar-', 100000), kp2) like '%bar-1%' and + concat(repeat('foo-bar-', 100000), kp2) like '%bar-1%' and + kp2 +1 > 10; + + +# +# Maria, check maria_rnext_same: +# + + explain + select * from t1m + where + kp1 = 20000 and + concat(repeat('foo-bar-', 100000), kp2) like '%bar-1%' and + concat(repeat('foo-bar-', 100000), kp2) like '%bar-1%' and + concat(repeat('foo-bar-', 100000), kp2) like '%bar-1%' and + concat(repeat('foo-bar-', 100000), kp2) like '%bar-1%' and + kp2 +1 > 100; + +# +# Maria, check maria_rprev: +# + + explain + select * from t1m + where + kp1 = 20000 and + concat(repeat('foo-bar-', 100000), kp2) like '%bar-1%' and + concat(repeat('foo-bar-', 100000), kp2) like '%bar-1%' and + concat(repeat('foo-bar-', 100000), kp2) like '%bar-1%' and + concat(repeat('foo-bar-', 100000), kp2) like '%bar-1%' and + kp2 +1 > 20 + order by kp1, kp2 desc; + +drop table t0, t1, t1i, t1m; + +--enable_parsing + +--echo # +--echo # BUG#826935 Assertion `!table || (!table->read_set || bitmap_is_set(table->read_set, field_index))' failed +--echo # +CREATE TABLE t1 ( a int, b varchar(1024), c int, KEY (c), KEY (c,a)) ; +INSERT INTO t1 VALUES + (NULL,'x','-678428672'), + (NULL,'ok',NULL), + (796262400,'byluovkgwoukfxedyeffsedajyqkyhpaqqpozn', NULL), + (7,'STQUF',146014208), + (955711488,'WWVOR','-1515388928'); +SELECT b FROM t1 WHERE a != 1 AND c IS NULL ORDER BY 1; +DROP TABLE t1; + +set optimizer_switch=@myisam_icp_tmp; diff --git a/mysql-test/t/myisam_mrr.test b/mysql-test/t/myisam_mrr.test index d9afdf3140d..9c4c7be4fa2 100644 --- a/mysql-test/t/myisam_mrr.test +++ b/mysql-test/t/myisam_mrr.test @@ -3,9 +3,11 @@ # --disable_warnings -drop table if exists t1, t2, t3; +drop table if exists t0, t1, t2, t3; --enable_warnings +set @myisam_mrr_tmp=@@optimizer_switch; +set optimizer_switch='mrr=on,mrr_sort_keys=on,index_condition_pushdown=on'; set @mrr_buffer_size_save= @@mrr_buffer_size; set mrr_buffer_size=79; @@ -123,4 +125,99 @@ explain select * from t1 where a < 20; set optimizer_switch=@save_optimizer_switch; + +--echo # +--echo # BUG#629684: Unreachable code in multi_range_read.cc in maria-5.3-dsmrr-cpk +--echo # + +delete from t0 where a > 2; +insert into t0 values (NULL),(NULL); +insert into t1 values (NULL, 1234), (NULL, 5678); + +set @save_join_cache_level=@@join_cache_level; +set @@join_cache_level=6; +explain +select * from t0, t1 where t0.a<=>t1.a; +select * from t0, t1 where t0.a<=>t1.a; + +set @@join_cache_level=@save_join_cache_level; drop table t0, t1; + +--echo # +--echo # BUG#625841: Assertion `!table || (!table->read_set || bitmap_is_set +--echo # (table->read_set, field_index))' on REPLACE ... SELECT with MRR +--echo # +create table t0 (a int); +insert into t0 values (0),(1),(2),(3),(4),(5),(6),(7),(8),(9); + +create table t1 ( + key1 varchar(10), + col1 char(255), col2 char(255), + col3 char(244), col4 char(255), + key(key1) +); +create table t2 like t1; + +insert into t1 +select + 1000+A.a+100*B.a + 10*C.a, + 'col1val', 'col2val', + 'col3val', 'col4val' +from t0 A, t0 B, t0 C; + +REPLACE INTO t2(col2,col3,col4) +SELECT col2,col3,col4 +FROM t1 +WHERE `key1` LIKE CONCAT( LEFT( '1' , 7 ) , '%' ) +ORDER BY col1 LIMIT 7; +drop table t0, t1, t2; + +--echo # +--echo # BUG#670417: Diverging results in maria-5.3-mwl128-dsmrr-cpk with join buffer (incremental, BKA join) +--echo # + +set @save_join_cache_level = @@join_cache_level; +set join_cache_level = 6; +set @save_join_buffer_size=@@join_buffer_size; +--disable_warnings +set join_buffer_size = 136; +--enable_warnings + +CREATE TABLE t1 ( + pk int(11) NOT NULL AUTO_INCREMENT, + col_int_key int(11) NOT NULL, + col_varchar_key varchar(1) NOT NULL, + col_varchar_nokey varchar(1) NOT NULL, + PRIMARY KEY (pk), + KEY col_varchar_key (col_varchar_key,col_int_key) +); +INSERT INTO t1 VALUES + (10,8,'v','v'),(11,8,'f','f'), (12,5,'v','v'), + (13,8,'s','s'),(14,8,'a','a'),(15,6,'p','p'), + (16,7,'z','z'),(17,2,'a','a'),(18,5,'h','h'), + (19,7,'h','h'),(20,2,'v','v'),(21,9,'v','v'), + (22,142,'b','b'),(23,3,'y','y'),(24,0,'v','v'), + (25,3,'m','m'),(26,5,'z','z'),(27,9,'n','n'), + (28,1,'d','d'),(29,107,'a','a'); + +SELECT COUNT(*) +FROM + t1 AS table2, t1 AS table3 +where + table3.col_varchar_key = table2.col_varchar_key AND + table3.col_varchar_key = table2.col_varchar_nokey AND + table3.pk<>0; + +EXPLAIN SELECT COUNT(*) +FROM + t1 AS table2, t1 AS table3 +where + table3.col_varchar_key = table2.col_varchar_key AND + table3.col_varchar_key = table2.col_varchar_nokey AND + table3.pk<>0; + +set join_cache_level= @save_join_cache_level; +set join_buffer_size= @save_join_buffer_size; +set optimizer_switch= @myisam_mrr_tmp; +drop table t1; + diff --git a/mysql-test/t/mysqlbinlog-innodb.test b/mysql-test/t/mysqlbinlog-innodb.test new file mode 100644 index 00000000000..49702e8db38 --- /dev/null +++ b/mysql-test/t/mysqlbinlog-innodb.test @@ -0,0 +1,31 @@ +-- source include/have_binlog_format_statement.inc +-- source include/have_log_bin.inc +-- source include/have_innodb.inc + +# +# MBug#702303: Spurious `use` statements in output from mysqlbinlog --rewrite-db="a->b" +# +let $MYSQLD_DATADIR= `select @@datadir`; +SET TIMESTAMP=1000000000; +CREATE TABLE t1 (a INT PRIMARY KEY) ENGINE=innodb; +CREATE DATABASE test2; + +RESET MASTER; +USE test2; +BEGIN; +USE test; +INSERT INTO t1 VALUES (1); +USE test2; +COMMIT; +BEGIN; +USE test; +INSERT INTO t1 VALUES (2); +USE test2; +COMMIT; +USE test; +SELECT * FROM t1 ORDER BY a; +FLUSH LOGS; +--exec $MYSQL_BINLOG $MYSQLD_DATADIR/master-bin.000001 --short-form +--exec $MYSQL_BINLOG $MYSQLD_DATADIR/master-bin.000001 --short-form --rewrite-db="test->foo" --rewrite-db="test2->bar" +DROP DATABASE test2; +DROP TABLE t1; diff --git a/mysql-test/t/mysqlbinlog.test b/mysql-test/t/mysqlbinlog.test index f64d8b502ae..e8ce861dd53 100644 --- a/mysql-test/t/mysqlbinlog.test +++ b/mysql-test/t/mysqlbinlog.test @@ -3,6 +3,7 @@ -- source include/have_binlog_format_statement.inc -- source include/have_log_bin.inc +-- source include/binlog_start_pos.inc --disable_query_log CALL mtr.add_suppression("Unsafe statement written to the binary log using statement format since BINLOG_FORMAT = STATEMENT"); @@ -30,14 +31,16 @@ insert into t2 values (); # test for load data and load data distributed among the several # files (we need to fill up first binlog) -load data infile '../../std_data/words.dat' into table t1; -load data infile '../../std_data/words.dat' into table t1; -load data infile '../../std_data/words.dat' into table t1; -load data infile '../../std_data/words.dat' into table t1; -load data infile '../../std_data/words.dat' into table t1; +load data infile '../../std_data/words3.dat' into table t1; +load data infile '../../std_data/words3.dat' into table t1; +load data infile '../../std_data/words3.dat' into table t1; +load data infile '../../std_data/words3.dat' into table t1; +load data infile '../../std_data/words3.dat' into table t1; # simple query to show more in second binlog --let $binlog_start_pos=query_get_value(SHOW MASTER STATUS, Position, 1) insert into t1 values ("Alas"); + +### Starting master-bin.000003 flush logs; # delimiters are for easier debugging in future @@ -51,7 +54,7 @@ select "--- Local --" as ""; # let $MYSQLD_DATADIR= `select @@datadir`; --replace_result $MYSQLTEST_VARDIR MYSQLTEST_VARDIR ---replace_regex /SQL_LOAD_MB-[0-9]-[0-9]/SQL_LOAD_MB-#-#/ +--replace_regex /SQL_LOAD_MB-[0-9a-f]+-[0-9a-f]+/SQL_LOAD_MB-#-#/ --exec $MYSQL_BINLOG --short-form --local-load=$MYSQLTEST_VARDIR/tmp/ $MYSQLD_DATADIR/master-bin.000001 # this should not fail but shouldn't produce any working statements @@ -59,7 +62,7 @@ let $MYSQLD_DATADIR= `select @@datadir`; select "--- Broken LOAD DATA --" as ""; --enable_query_log --replace_result $MYSQLTEST_VARDIR MYSQLTEST_VARDIR ---replace_regex /SQL_LOAD_MB-[0-9]-[0-9]/SQL_LOAD_MB-#-#/ +--replace_regex /SQL_LOAD_MB-[0-9a-f]+-[0-9a-f]+/SQL_LOAD_MB-#-#/ --exec $MYSQL_BINLOG --short-form --local-load=$MYSQLTEST_VARDIR/tmp/ $MYSQLD_DATADIR/master-bin.000002 2> /dev/null # this should show almost nothing @@ -67,7 +70,7 @@ select "--- Broken LOAD DATA --" as ""; select "--- --database --" as ""; --enable_query_log --replace_result $MYSQLTEST_VARDIR MYSQLTEST_VARDIR ---replace_regex /SQL_LOAD_MB-[0-9]-[0-9]/SQL_LOAD_MB-#-#/ +--replace_regex /SQL_LOAD_MB-[0-9a-f]+-[0-9a-f]+/SQL_LOAD_MB-#-#/ --exec $MYSQL_BINLOG --short-form --local-load=$MYSQLTEST_VARDIR/tmp/ --database=nottest $MYSQLD_DATADIR/master-bin.000001 2> /dev/null # this test for start-position option @@ -75,7 +78,7 @@ select "--- --database --" as ""; select "--- --start-position --" as ""; --enable_query_log --replace_result $MYSQLTEST_VARDIR MYSQLTEST_VARDIR ---replace_regex /SQL_LOAD_MB-[0-9]-[0-9]/SQL_LOAD_MB-#-#/ +--replace_regex /SQL_LOAD_MB-[0-9a-f]+-[0-9a-f]+/SQL_LOAD_MB-#-#/ --exec $MYSQL_BINLOG --short-form --local-load=$MYSQLTEST_VARDIR/tmp/ --start-position=$binlog_start_pos $MYSQLD_DATADIR/master-bin.000002 # These are tests for remote binlog. @@ -87,7 +90,7 @@ select "--- Remote --" as ""; # This is broken now --replace_result $MYSQLTEST_VARDIR MYSQLTEST_VARDIR ---replace_regex /SQL_LOAD_MB-[0-9]-[0-9]/SQL_LOAD_MB-#-#/ +--replace_regex /SQL_LOAD_MB-[0-9a-f]+-[0-9a-f]+/SQL_LOAD_MB-#-#/ --exec $MYSQL_BINLOG --short-form --local-load=$MYSQLTEST_VARDIR/tmp/ --read-from-remote-server --user=root --host=127.0.0.1 --port=$MASTER_MYPORT master-bin.000001 # This is broken too @@ -95,7 +98,7 @@ select "--- Remote --" as ""; select "--- Broken LOAD DATA --" as ""; --enable_query_log --replace_result $MYSQLTEST_VARDIR MYSQLTEST_VARDIR ---replace_regex /SQL_LOAD_MB-[0-9]-[0-9]/SQL_LOAD_MB-#-#/ +--replace_regex /SQL_LOAD_MB-[0-9a-f]+-[0-9a-f]+/SQL_LOAD_MB-#-#/ --exec $MYSQL_BINLOG --short-form --local-load=$MYSQLTEST_VARDIR/tmp/ --read-from-remote-server --user=root --host=127.0.0.1 --port=$MASTER_MYPORT master-bin.000002 2> /dev/null # And this too ! (altough it is documented) @@ -103,7 +106,7 @@ select "--- Broken LOAD DATA --" as ""; select "--- --database --" as ""; --enable_query_log --replace_result $MYSQLTEST_VARDIR MYSQLTEST_VARDIR ---replace_regex /SQL_LOAD_MB-[0-9]-[0-9]/SQL_LOAD_MB-#-#/ +--replace_regex /SQL_LOAD_MB-[0-9a-f]+-[0-9a-f]+/SQL_LOAD_MB-#-#/ --exec $MYSQL_BINLOG --short-form --local-load=$MYSQLTEST_VARDIR/tmp/ --read-from-remote-server --user=root --host=127.0.0.1 --port=$MASTER_MYPORT --database=nottest master-bin.000001 2> /dev/null # Strangely but this works @@ -111,7 +114,7 @@ select "--- --database --" as ""; select "--- --start-position --" as ""; --enable_query_log --replace_result $MYSQLTEST_VARDIR MYSQLTEST_VARDIR ---replace_regex /SQL_LOAD_MB-[0-9]-[0-9]/SQL_LOAD_MB-#-#/ +--replace_regex /SQL_LOAD_MB-[0-9a-f]+-[0-9a-f]+/SQL_LOAD_MB-#-#/ --exec $MYSQL_BINLOG --short-form --local-load=$MYSQLTEST_VARDIR/tmp/ --read-from-remote-server --start-position=$binlog_start_pos --user=root --host=127.0.0.1 --port=$MASTER_MYPORT master-bin.000002 # Bug#7853 mysqlbinlog does not accept input from stdin @@ -119,11 +122,11 @@ select "--- --start-position --" as ""; select "--- reading stdin --" as ""; --enable_query_log --replace_result $MYSQL_TEST_DIR MYSQL_TEST_DIR ---replace_regex /SQL_LOAD_MB-[0-9]-[0-9]/SQL_LOAD_MB-#-#/ +--replace_regex /SQL_LOAD_MB-[0-9a-f]+-[0-9a-f]+/SQL_LOAD_MB-#-#/ --exec $MYSQL_BINLOG --short-form - < $MYSQL_TEST_DIR/std_data/trunc_binlog.000001 --replace_result $MYSQL_TEST_DIR MYSQL_TEST_DIR ---replace_regex /SQL_LOAD_MB-[0-9]-[0-9]/SQL_LOAD_MB-#-#/ +--replace_regex /SQL_LOAD_MB-[0-9a-f]+-[0-9a-f]+/SQL_LOAD_MB-#-#/ # postion is constant to correspond to an event in pre-recorded binlog --let $binlog_start_pos=79 --exec $MYSQL_BINLOG --short-form --start-position=$binlog_start_pos - < $MYSQL_TEST_DIR/std_data/trunc_binlog.000001 @@ -132,7 +135,9 @@ drop table t1,t2; # # Bug#14157 utf8 encoding in binlog without set character_set_client # +### Starting master-bin.000004 flush logs; + --write_file $MYSQLTEST_VARDIR/tmp/bug14157.sql create table if not exists t5 (a int); set names latin1; @@ -146,6 +151,8 @@ EOF # resulted binlog, parly consisting of multi-byte utf8 chars, # must be digestable for both client and server. In 4.1 the client # should use default-character-set same as the server. + +### Starting master-bin.000005 flush logs; # Due to BUG#18337 that wrongly suppresses the BINLOG EVENTS when # --short-form is used, the "insert into t5 select * from `äöüÄÖÜ`" @@ -163,6 +170,8 @@ drop table t5; # Check that a dump created by mysqlbinlog reproduces # lc_time_names dependent values correctly # + +### Starting master-bin.000006 flush logs; create table t5 (c1 int, c2 varchar(128) character set latin1 not null); insert into t5 values (1, date_format('2001-01-01','%W')); @@ -171,7 +180,10 @@ insert into t5 values (2, date_format('2001-01-01','%W')); set lc_time_names=en_US; insert into t5 values (3, date_format('2001-01-01','%W')); select * from t5 order by c1; + +### Starting master-bin.000007 flush logs; + drop table t5; --exec $MYSQL_BINLOG --short-form $MYSQLD_DATADIR/master-bin.000006 | $MYSQL select * from t5 order by c1; @@ -183,7 +195,10 @@ drop table t5; --disable_warnings drop procedure if exists p1; --enable_warnings + +### Starting master-bin.000008 flush logs; + delimiter //; create procedure p1() begin @@ -191,12 +206,15 @@ select 1; end; // delimiter ;// + +### Starting master-bin.000009 flush logs; + call p1(); drop procedure p1; --error ER_SP_DOES_NOT_EXIST call p1(); ---replace_regex /SQL_LOAD_MB-[0-9]-[0-9]/SQL_LOAD_MB-#-#/ +--replace_regex /SQL_LOAD_MB-[0-9a-f]+-[0-9a-f]+/SQL_LOAD_MB-#-#/ --exec $MYSQL_BINLOG --short-form $MYSQLD_DATADIR/master-bin.000008 --exec $MYSQL_BINLOG --short-form $MYSQLD_DATADIR/master-bin.000008 | $MYSQL call p1(); @@ -215,7 +233,9 @@ drop procedure p1; # (LOAD DATA INFILE need it) # +### Starting master-bin.000010 flush logs; + create table t1 (a varchar(64) character set utf8); load data infile '../../std_data/loaddata6.dat' into table t1; set character_set_database=koi8r; @@ -230,9 +250,12 @@ load data infile '../../std_data/loaddata6.dat' into table t1; load data infile '../../std_data/loaddata6.dat' into table t1 character set koi8r; select hex(a) from t1; drop table t1; + +### Starting master-bin.000011 flush logs; + --replace_result $MYSQLTEST_VARDIR MYSQLTEST_VARDIR ---replace_regex /SQL_LOAD_MB-[0-9]-[0-9]/SQL_LOAD_MB-#-#/ +--replace_regex /SQL_LOAD_MB-[0-9a-f]+-[0-9a-f]+/SQL_LOAD_MB-#-#/ --exec $MYSQL_BINLOG --short-form --local-load=$MYSQLTEST_VARDIR/tmp/ $MYSQLD_DATADIR/master-bin.000010 # @@ -242,9 +265,14 @@ flush logs; CREATE TABLE t1 (c1 CHAR(10)); # we need this for getting fixed timestamps inside of this test +### Starting master-bin.000012 FLUSH LOGS; + INSERT INTO t1 VALUES ('0123456789'); + +### Starting master-bin.000013 FLUSH LOGS; + DROP TABLE t1; # We create a table, patch, and load the output into it @@ -255,6 +283,7 @@ DROP TABLE t1; --disable_query_log CREATE TABLE patch (a BLOB); --exec $MYSQL_BINLOG --hexdump --local-load=$MYSQLTEST_VARDIR/tmp/ $MYSQLD_DATADIR/master-bin.000012 > $MYSQLTEST_VARDIR/tmp/mysqlbinlog_tmp.dat +### Starting master-bin.000014 eval LOAD DATA LOCAL INFILE '$MYSQLTEST_VARDIR/tmp/mysqlbinlog_tmp.dat' INTO TABLE patch FIELDS TERMINATED BY '' LINES STARTING BY '#'; --remove_file $MYSQLTEST_VARDIR/tmp/mysqlbinlog_tmp.dat @@ -270,11 +299,16 @@ DROP TABLE patch; # # Bug#29928 incorrect connection_id() restoring from mysqlbinlog out # +### Starting master-bin.000015 FLUSH LOGS; + CREATE TABLE t1(a INT); INSERT INTO t1 VALUES(connection_id()); let $a= `SELECT a FROM t1`; + +### Starting master-bin.000016 FLUSH LOGS; + let $outfile= $MYSQLTEST_VARDIR/tmp/bug29928.sql; --exec $MYSQL_BINLOG $MYSQLD_DATADIR/master-bin.000015 > $outfile DROP TABLE t1; @@ -294,11 +328,12 @@ error 1; exec $MYSQL_BINLOG $MYSQL_TEST_DIR/std_data/corrupt-relay-bin.000624 > $MYSQLTEST_VARDIR/tmp/bug31793.sql; --remove_file $MYSQLTEST_VARDIR/tmp/bug31793.sql - # # Test --disable-force-if-open and --force-if-open # +### Starting master-bin.000017 FLUSH LOGS; + --error 1 --exec $MYSQL_BINLOG $MYSQLD_DATADIR/master-bin.000017 >/dev/null 2>/dev/null --exec $MYSQL_BINLOG --force-if-open $MYSQLD_DATADIR/master-bin.000017 >/dev/null 2>/dev/null @@ -313,8 +348,13 @@ GRANT SELECT ON mysqltest1.* TO untrusted@localhost; SHOW GRANTS FOR untrusted@localhost; USE mysqltest1; CREATE TABLE t1 (a INT, b CHAR(64)); + +### Starting master-bin.000018 flush logs; + INSERT INTO t1 VALUES (1,USER()); + +### Starting master-bin.000019 flush logs; echo mysqlbinlog var/log/master-bin.000018 > var/tmp/bug31611.sql; exec $MYSQL_BINLOG $MYSQLD_DATADIR/master-bin.000018 > $MYSQLTEST_VARDIR/tmp/bug31611.sql; @@ -339,14 +379,20 @@ DROP USER untrusted@localhost; connection default; USE test; SET BINLOG_FORMAT = STATEMENT; + +### Starting master-bin.000020 FLUSH LOGS; + CREATE TABLE t1 (a_real FLOAT, an_int INT, a_decimal DECIMAL(5,2), a_string CHAR(32)); SET @a_real = rand(20) * 1000; SET @an_int = 1000; SET @a_decimal = CAST(rand(19) * 999 AS DECIMAL(5,2)); SET @a_string = 'Just a test'; INSERT INTO t1 VALUES (@a_real, @an_int, @a_decimal, @a_string); + +### Starting master-bin.000021 FLUSH LOGS; + query_vertical SELECT * FROM t1; DROP TABLE t1; @@ -370,6 +416,7 @@ eval SET @@global.server_id= $s_id_max; RESET MASTER; FLUSH LOGS; + --exec $MYSQL_BINLOG $MYSQLD_DATADIR/master-bin.000001 > $binlog_file --replace_result $MYSQLTEST_VARDIR MYSQLTEST_VARDIR eval SELECT diff --git a/mysql-test/t/mysqlbinlog2.test b/mysql-test/t/mysqlbinlog2.test index dcd92262a83..740c4078f20 100644 --- a/mysql-test/t/mysqlbinlog2.test +++ b/mysql-test/t/mysqlbinlog2.test @@ -3,7 +3,7 @@ # TODO: Need to look at making row based version once new binlog client is complete. -- source include/have_binlog_format_mixed_or_statement.inc - +-- source include/binlog_start_pos.inc --disable_warnings drop table if exists t1; @@ -54,15 +54,19 @@ select "--- offset --" as ""; --disable_query_log select "--- start-position --" as ""; --enable_query_log ---exec $MYSQL_BINLOG --short-form --start-position=$binlog_pos_760 $MYSQLD_DATADIR/master-bin.000001 +let $start_pos= `select @binlog_start_pos + 653`; +--exec $MYSQL_BINLOG --short-form --start-position=$start_pos $MYSQLD_DATADIR/master-bin.000001 --disable_query_log select "--- stop-position --" as ""; --enable_query_log ---exec $MYSQL_BINLOG --short-form --stop-position=$binlog_pos_760 $MYSQLD_DATADIR/master-bin.000001 +let $stop_pos= `select @binlog_start_pos + 653`; +--exec $MYSQL_BINLOG --short-form --stop-position=$stop_pos $MYSQLD_DATADIR/master-bin.000001 --disable_query_log select "--- start and stop positions ---" as ""; --enable_query_log ---exec $MYSQL_BINLOG --short-form --start-position=$binlog_pos_760 --stop-position=$binlog_pos_951 $MYSQLD_DATADIR/master-bin.000001 +let $start_pos= `select @binlog_start_pos + 653`; +let $stop_pos= `select @binlog_start_pos + 770`; +--exec $MYSQL_BINLOG --short-form --start-position=$start_pos --stop-position=$stop_pos $MYSQLD_DATADIR/master-bin.000001 --disable_query_log select "--- start-datetime --" as ""; --enable_query_log @@ -88,11 +92,13 @@ select "--- offset --" as ""; --disable_query_log select "--- start-position --" as ""; --enable_query_log ---exec $MYSQL_BINLOG --short-form --start-position=$binlog_pos_760 $MYSQLD_DATADIR/master-bin.000001 $MYSQLD_DATADIR/master-bin.000002 +let $start_pos= `select @binlog_start_pos + 653`; +--exec $MYSQL_BINLOG --short-form --start-position=$start_pos $MYSQLD_DATADIR/master-bin.000001 $MYSQLD_DATADIR/master-bin.000002 --disable_query_log select "--- stop-position --" as ""; --enable_query_log ---exec $MYSQL_BINLOG --short-form --stop-position=$binlog_pos_203 $MYSQLD_DATADIR/master-bin.000001 $MYSQLD_DATADIR/master-bin.000002 +let $stop_pos= `select @binlog_start_pos + 69`; +--exec $MYSQL_BINLOG --short-form --stop-position=$stop_pos $MYSQLD_DATADIR/master-bin.000001 $MYSQLD_DATADIR/master-bin.000002 --disable_query_log select "--- start-datetime --" as ""; --enable_query_log @@ -115,15 +121,19 @@ select "--- offset --" as ""; --disable_query_log select "--- start-position --" as ""; --enable_query_log ---exec $MYSQL_BINLOG --short-form --start-position=$binlog_pos_760 --read-from-remote-server --user=root --host=127.0.0.1 --port=$MASTER_MYPORT master-bin.000001 +let $start_pos= `select @binlog_start_pos + 653`; +--exec $MYSQL_BINLOG --short-form --start-position=$start_pos --read-from-remote-server --user=root --host=127.0.0.1 --port=$MASTER_MYPORT master-bin.000001 --disable_query_log select "--- stop-position --" as ""; --enable_query_log ---exec $MYSQL_BINLOG --short-form --stop-position=$binlog_pos_760 --read-from-remote-server --user=root --host=127.0.0.1 --port=$MASTER_MYPORT master-bin.000001 +let $stop_pos= `select @binlog_start_pos + 653`; +--exec $MYSQL_BINLOG --short-form --stop-position=$stop_pos --read-from-remote-server --user=root --host=127.0.0.1 --port=$MASTER_MYPORT master-bin.000001 --disable_query_log select "--- start and stop positions ---" as ""; --enable_query_log ---exec $MYSQL_BINLOG --short-form --start-position=$binlog_pos_760 --stop-position=$binlog_pos_951 --read-from-remote-server --user=root --host=127.0.0.1 --port=$MASTER_MYPORT master-bin.000001 +let $start_pos= `select @binlog_start_pos + 653`; +let $stop_pos= `select @binlog_start_pos + 770`; +--exec $MYSQL_BINLOG --short-form --start-position=$start_pos --stop-position $stop_pos --read-from-remote-server --user=root --host=127.0.0.1 --port=$MASTER_MYPORT master-bin.000001 --disable_query_log select "--- start-datetime --" as ""; --enable_query_log @@ -146,11 +156,13 @@ select "--- offset --" as ""; --disable_query_log select "--- start-position --" as ""; --enable_query_log ---exec $MYSQL_BINLOG --short-form --start-position=$binlog_pos_760 --read-from-remote-server --user=root --host=127.0.0.1 --port=$MASTER_MYPORT master-bin.000001 master-bin.000002 +let $start_pos= `select @binlog_start_pos + 653`; +--exec $MYSQL_BINLOG --short-form --start-position=$start_pos --read-from-remote-server --user=root --host=127.0.0.1 --port=$MASTER_MYPORT master-bin.000001 master-bin.000002 --disable_query_log select "--- stop-position --" as ""; --enable_query_log ---exec $MYSQL_BINLOG --short-form --stop-position=$binlog_pos_135 --read-from-remote-server --user=root --host=127.0.0.1 --port=$MASTER_MYPORT master-bin.000001 master-bin.000002 +let $stop_pos= `select @binlog_start_pos + 28`; +--exec $MYSQL_BINLOG --short-form --stop-position=$stop_pos --read-from-remote-server --user=root --host=127.0.0.1 --port=$MASTER_MYPORT master-bin.000001 master-bin.000002 --disable_query_log select "--- start-datetime --" as ""; --enable_query_log diff --git a/mysql-test/t/mysqlcheck.test b/mysql-test/t/mysqlcheck.test index 8f93ac7b864..ef88b89e8d8 100644 --- a/mysql-test/t/mysqlcheck.test +++ b/mysql-test/t/mysqlcheck.test @@ -144,6 +144,7 @@ DROP TABLE `@`; CREATE TABLE `Ñ` (a INT) engine=myisam; SET NAMES DEFAULT; +call mtr.add_suppression("@003f.frm' \\(errno: 22\\)"); --echo mysqlcheck --default-character-set="latin1" --databases test # Error returned depends on platform, replace it with "Table doesn't exist" --replace_result "Can't find file: './test/@003f.frm' (errno: 22)" "Table doesn't exist" "Table 'test.?' doesn't exist" "Table doesn't exist" diff --git a/mysql-test/t/mysqldump-max.test b/mysql-test/t/mysqldump-max.test index 1e8b9647503..27c1a3ce20c 100644 --- a/mysql-test/t/mysqldump-max.test +++ b/mysql-test/t/mysqldump-max.test @@ -2,6 +2,7 @@ --source include/not_embedded.inc --source include/have_innodb.inc --source include/have_archive.inc +--source include/have_log_bin.inc --disable_warnings drop table if exists t1, t2, t3, t4, t5, t6; @@ -1124,3 +1125,84 @@ DROP VIEW v1; DROP TABLE t1; SET GLOBAL storage_engine=@old_engine; + +# Test fully non-locking mysqldump with consistent binlog position (MWL#136). + +connect(c1,127.0.0.1,root,,test,$MASTER_MYPORT,); +connect(c2,127.0.0.1,root,,test,$MASTER_MYPORT,); +connect(c3,127.0.0.1,root,,test,$MASTER_MYPORT,); + +connection default; +--echo # Connection default +SET binlog_format= mixed; +RESET MASTER; +CREATE TABLE t1 (a INT PRIMARY KEY) ENGINE=InnoDB; +INSERT INTO t1 VALUES (1),(2); +CREATE TABLE t2 (a INT PRIMARY KEY, b INT) ENGINE=InnoDB; +INSERT INTO t2 VALUES (1,0), (2,0); +SELECT GET_LOCK("block_queries_1", 120); + +connection c3; +--echo # Connection c3 +SELECT GET_LOCK("block_queries_2", 120); + +# Start two queries that will be running on the tables during mysqldump +connection c1; +--echo # Connection c1 +SET @c= 0; +send SELECT IF(@c<1, @c:=@c+1, GET_LOCK("block_queries_1", 120)) FROM t1 ORDER BY a; + +connection c2; +--echo # Connection c2 +SET binlog_format="row"; +SET @d= 10; +send UPDATE t2 SET b=IF(@d<=10, @d:=@d+1, GET_LOCK("block_queries_2", 120)) ORDER BY a; + +connection default; +--echo # Connection default +--echo # Make sure other queries are running (and waiting). +let $wait_condition= + SELECT COUNT(*) FROM information_schema.processlist + WHERE state = "User lock" AND info LIKE 'SELECT%block_queries_1%'; +--source include/wait_condition.inc +let $wait_condition= + SELECT COUNT(*) FROM information_schema.processlist + WHERE state = "User lock" AND info LIKE 'UPDATE%block_queries_2%'; +--source include/wait_condition.inc + +--exec $MYSQL_DUMP --master-data=2 --single-transaction test t1 t2 > $MYSQLTEST_VARDIR/tmp/mwl136.sql + +SELECT RELEASE_LOCK("block_queries_1"); + +connection c3; +--echo # Connection c3 +SELECT RELEASE_LOCK("block_queries_2"); + +connection c1; +--echo # Connection c1 +reap; + +connection c2; +--echo # Connection c2 +reap; + +connection default; +--echo # Connection default +SELECT * FROM t2 ORDER BY a; +DROP TABLE t1; +DROP TABLE t2; +--exec $MYSQL test < $MYSQLTEST_VARDIR/tmp/mwl136.sql + +--replace_regex /\/\* xid=.* \*\//\/* XID *\// /Server ver: .*, Binlog ver: .*/Server ver: #, Binlog ver: #/ /table_id: [0-9]+/table_id: #/ +SHOW BINLOG EVENTS LIMIT 6,3; +--perl +my $f= "$ENV{MYSQLTEST_VARDIR}/tmp/mwl136.sql"; +open F, '<', $f or die "Failed to open $f: $!\n"; +while (<F>) { + print if /CHANGE MASTER TO/; +} +EOF +SELECT * FROM t1 ORDER BY a; +SELECT * FROM t2 ORDER BY a; + +DROP TABLE t1,t2; diff --git a/mysql-test/t/mysqldump.test b/mysql-test/t/mysqldump.test index 3d0e2d47617..19d47a9dac3 100644 --- a/mysql-test/t/mysqldump.test +++ b/mysql-test/t/mysqldump.test @@ -6,6 +6,10 @@ call mtr.add_suppression("@003f.frm' \\(errno: 22\\)"); # Binlog is required --source include/have_log_bin.inc +# utf8 is required +let collation=utf8_unicode_ci; +--source include/have_collation.inc + # Save the initial number of concurrent sessions --source include/count_sessions.inc @@ -657,6 +661,10 @@ a int(10), b varchar(30), c datetime, d blob, e text); insert into t1 values (NULL), (10), (20); insert into t2 (a, b) values (NULL, NULL),(10, NULL),(NULL, "twenty"),(30, "thirty"); --exec $MYSQL_DUMP --skip-comments --xml --no-create-info test + +# Test if UNIQUE_CHECK is done correctly +--exec $MYSQL_DUMP --skip-comments --no-create-info test +--exec $MYSQL_DUMP --skip-comments test drop table t1, t2; diff --git a/mysql-test/t/negation_elimination.test b/mysql-test/t/negation_elimination.test index 0e0d8891e1f..312be8ccdb4 100644 --- a/mysql-test/t/negation_elimination.test +++ b/mysql-test/t/negation_elimination.test @@ -65,6 +65,35 @@ select * from t1 where not((a < 5 and a < 10) and (not(a > 16) or a > 17)); explain select * from t1 where ((a between 5 and 15) and (not(a like 10))); select * from t1 where ((a between 5 and 15) and (not(a like 10))); +--echo # XOR (Note: XOR is negated by negating one of the operands) + +--echo # Should return 6,7 +SELECT * FROM t1 WHERE ((a > 5) XOR (a > 7)); + +--echo # Should return 0..5,8..19 +SELECT * FROM t1 WHERE ((NOT (a > 5)) XOR (a > 7)); +SELECT * FROM t1 WHERE ((a > 5) XOR (NOT (a > 7))); +SELECT * FROM t1 WHERE NOT ((a > 5) XOR (a > 7)); + +--echo # Should return 6,7 +SELECT * FROM t1 WHERE NOT ((NOT (a > 5)) XOR (a > 7)); +SELECT * FROM t1 WHERE NOT ((a > 5) XOR (NOT (a > 7))); + +--echo # Should return 0..5,8..19 +SELECT * FROM t1 WHERE NOT ((NOT (a > 5)) XOR (NOT (a > 7))); + +--echo # Should have empty result +SELECT * FROM t1 WHERE (NULL XOR (a > 7)); +SELECT * FROM t1 WHERE NOT (NULL XOR (a > 7)); + +--echo # Should be simplified to "...WHERE (a XOR a) +EXPLAIN EXTENDED SELECT * FROM t1 WHERE NOT ((NOT a) XOR (a)); + +--echo # Should be simplified to "...WHERE (a XOR a) +EXPLAIN EXTENDED SELECT * FROM t1 WHERE NOT (a XOR (NOT a)); + +--echo # End XOR + delete from t1 where a > 3; select a, not(not(a)) from t1; explain extended select a, not(not(a)), not(a <= 2 and not(a)), not(a not like "1"), not (a not in (1,2)), not(a != 2) from t1 where not(not(a)) having not(not(a)); diff --git a/mysql-test/t/null_key.test b/mysql-test/t/null_key.test index 1400c643203..695b2835610 100644 --- a/mysql-test/t/null_key.test +++ b/mysql-test/t/null_key.test @@ -263,3 +263,16 @@ SELECT * FROM t2 inner join t1 WHERE ( t1.a = 0 OR t1.a IS NULL) AND t2.a = 3 AN drop table t1, t2; -- echo End of 5.0 tests +--echo # +--echo # BUG#727667 Wrong result with OR + NOT NULL in maria-5.3 +--echo # + +CREATE TABLE t1 ( + f3 int(11), + f10 varchar(1), + KEY (f3) +); +INSERT INTO t1 VALUES ('9','k'),(NULL,'r'); +SELECT * FROM t1 WHERE (f3 = 83) OR (f10 = 'z' AND f3 IS NULL); +DROP TABLE t1; + diff --git a/mysql-test/t/old-mode.test b/mysql-test/t/old-mode.test index 6d0fe64bbb8..cf2167c8027 100644 --- a/mysql-test/t/old-mode.test +++ b/mysql-test/t/old-mode.test @@ -15,3 +15,13 @@ checksum table t1, t2; checksum table t1, t2 quick; checksum table t1, t2 extended; drop table t1,t2; + +# +# Test that SHOW PROCESSLIST doesn't have the Progress column +# + +--replace_column 1 <Id> 3 <Host> 6 <Time> +# Embedded server is hardcoded to show "Writing to net" as STATE. +--replace_result "Writing to net" "NULL" +--replace_regex /localhost[:0-9]*/localhost/ +SHOW PROCESSLIST; diff --git a/mysql-test/t/openssl_1.test b/mysql-test/t/openssl_1.test index 4b16f9ba699..926d2474ff2 100644 --- a/mysql-test/t/openssl_1.test +++ b/mysql-test/t/openssl_1.test @@ -73,6 +73,8 @@ drop table t1; # a different cacert # --exec echo "this query should not execute;" > $MYSQLTEST_VARDIR/tmp/test.sql +# Handle that openssl gives different error messages from YaSSL. +--replace_regex /error:00000005:lib\(0\):func\(0\):DH lib/ASN: bad other signature confirmation/ --error 1 --exec $MYSQL_TEST --ssl-ca=$MYSQL_TEST_DIR/std_data/untrusted-cacert.pem --max-connect-retries=1 < $MYSQLTEST_VARDIR/tmp/test.sql 2>&1 @@ -80,6 +82,7 @@ drop table t1; # Test that we can't open connection to server if we are using # a blank ca # +--replace_regex /error:00000005:lib\(0\):func\(0\):DH lib/ASN: bad other signature confirmation/ --error 1 --exec $MYSQL_TEST --ssl-ca= --max-connect-retries=1 < $MYSQLTEST_VARDIR/tmp/test.sql 2>&1 @@ -87,6 +90,7 @@ drop table t1; # Test that we can't open connection to server if we are using # a nonexistent ca file # +--replace_regex /error:00000005:lib\(0\):func\(0\):DH lib/ASN: bad other signature confirmation/ --error 1 --exec $MYSQL_TEST --ssl-ca=nonexisting_file.pem --max-connect-retries=1 < $MYSQLTEST_VARDIR/tmp/test.sql 2>&1 diff --git a/mysql-test/t/order_by.test b/mysql-test/t/order_by.test index 12673314c11..d820f1c03bd 100644 --- a/mysql-test/t/order_by.test +++ b/mysql-test/t/order_by.test @@ -1,11 +1,17 @@ # -# Bug with order by +# Testing ORDER BY # --disable_warnings drop table if exists t1,t2,t3; --enable_warnings +call mtr.add_suppression("Out of sort memory; increase server sort buffer size"); + +# +# Test old ORDER BY bug +# + CREATE TABLE t1 ( id int(6) DEFAULT '0' NOT NULL, idservice int(5), @@ -847,13 +853,13 @@ DROP TABLE t1; --echo # create table t1(a int, b tinytext); insert into t1 values (1,2),(3,2); -set session sort_buffer_size= 30000; +set session sort_buffer_size= 1000; set session max_sort_length= 2180; CALL mtr.add_suppression("Out of sort memory"); --error ER_OUT_OF_SORTMEMORY select * from t1 order by b; drop table t1; -call mtr.add_suppression("Out of sort memory; increase server sort buffer size"); + --echo # --echo # Bug #39844: Query Crash Mysql Server 5.0.67 --echo # @@ -1368,6 +1374,14 @@ SELECT d FROM t3 AS t1, t2 AS t2 WHERE t2.b=14 AND t2.a=t1.a AND 5.1<t2.c AND t1.b='DE' ORDER BY t2.c LIMIT 1; +SELECT t1.*,t2.* FROM t1, t2 +WHERE t2.b=14 AND t2.a=t1.a AND 5.1<t2.c AND t1.b='DE' +ORDER BY t2.c LIMIT 5; + +SELECT t1.*, t2.* FROM t3 AS t1, t2 AS t2 +WHERE t2.b=14 AND t2.a=t1.a AND 5.1<t2.c AND t1.b='DE' +ORDER BY t2.c LIMIT 5; + DROP TABLE t1,t2,t3; @@ -1497,6 +1511,24 @@ LIMIT 2; DROP TABLE t1, t2; +--echo # +--echo # Bug #707848: WHERE condition with OR + ORDER BY + field substitution +--echo # + +CREATE TABLE t1 (a int PRIMARY KEY); +INSERT INTO t1 VALUES + (9), (7), (11), (15), (2), (4), (1), (5), (14), (54), (3), (8); + +EXPLAIN EXTENDED +SELECT * FROM t1 r JOIN t1 s ON r.a = s.a + WHERE s.a IN (2,9) OR s.a < 100 AND s.a != 0 + ORDER BY 1 LIMIT 10; + +SELECT * FROM t1 r JOIN t1 s ON r.a = s.a + WHERE s.a IN (2,9) OR s.a < 100 AND s.a != 0 + ORDER BY 1 LIMIT 10; + +DROP TABLE t1; --echo # --echo # Bug #59110: Memory leak of QUICK_SELECT_I allocated memory diff --git a/mysql-test/t/parser_precedence.test b/mysql-test/t/parser_precedence.test index 484c8759779..7b69bc9c6da 100644 --- a/mysql-test/t/parser_precedence.test +++ b/mysql-test/t/parser_precedence.test @@ -3,6 +3,8 @@ drop table if exists t1_30237_bool; --enable_warnings +set sql_mode=NO_UNSIGNED_SUBTRACTION; + create table t1_30237_bool(A boolean, B boolean, C boolean); insert into t1_30237_bool values diff --git a/mysql-test/t/partition.test b/mysql-test/t/partition.test index e5861322213..3224f4d4081 100644 --- a/mysql-test/t/partition.test +++ b/mysql-test/t/partition.test @@ -2401,3 +2401,20 @@ SELECT * FROM t1_part; # Cleanup DROP VIEW v1; DROP TABLE t1_part; + +--echo # +--echo # BUG#598247: partition.test produces valgrind errors in 5.3-based branches +--echo # +CREATE TABLE t1 ( + a INT DEFAULT NULL, + b DOUBLE DEFAULT NULL, + c INT DEFAULT NULL, + KEY idx2(b,a) +) engine=myisam PARTITION BY HASH(c) PARTITIONS 3; + +INSERT INTO t1 VALUES (6,8,9); +INSERT INTO t1 VALUES (6,8,10); + +SELECT 1 FROM t1 JOIN t1 AS t2 USING (a); + +drop table t1; diff --git a/mysql-test/t/partition_binlog_stmt.test b/mysql-test/t/partition_binlog_stmt.test index c426de9f303..cc57222dc3c 100644 --- a/mysql-test/t/partition_binlog_stmt.test +++ b/mysql-test/t/partition_binlog_stmt.test @@ -8,7 +8,7 @@ DROP TABLE IF EXISTS t1; --echo # --echo # Bug#51851: Server with SBR locks mutex twice on LOAD DATA into --echo # partitioned MyISAM table ---write_file init_file.txt +--write_file $MYSQLTEST_VARDIR/tmp/init_file.txt abcd EOF @@ -19,8 +19,9 @@ CREATE TABLE t1 INDEX namelocs (name(255))) ENGINE = MyISAM PARTITION BY HASH(id) PARTITIONS 2; -LOAD DATA LOCAL INFILE 'init_file.txt' +--replace_result $MYSQLTEST_VARDIR MYSQLTEST_VARDIR +eval LOAD DATA LOCAL INFILE '$MYSQLTEST_VARDIR/tmp/init_file.txt' INTO TABLE t1 (name); ---remove_file init_file.txt +--remove_file $MYSQLTEST_VARDIR/tmp/init_file.txt DROP TABLE t1; diff --git a/mysql-test/t/partition_datatype.test b/mysql-test/t/partition_datatype.test index 967e1cddb4e..a6035fcb592 100644 --- a/mysql-test/t/partition_datatype.test +++ b/mysql-test/t/partition_datatype.test @@ -248,13 +248,13 @@ ENGINE = MyISAM; CREATE TABLE t2 LIKE t1; ALTER TABLE t2 PARTITION BY RANGE (UNIX_TIMESTAMP(a)) (PARTITION `p0` VALUES LESS THAN (0), - PARTITION `p-2000` VALUES LESS THAN (UNIX_TIMESTAMP('2000-01-01')), - PARTITION `p-2011-MSK` VALUES LESS THAN (UNIX_TIMESTAMP('2011-03-26 23:00:00')), - PARTITION `p-2011-MSD-1` VALUES LESS THAN (UNIX_TIMESTAMP('2011-10-29 22:00:00')), - PARTITION `p-2011-MSD-2` VALUES LESS THAN (UNIX_TIMESTAMP('2011-10-29 23:00:00')), - PARTITION `p-2012-MSK-1` VALUES LESS THAN (UNIX_TIMESTAMP('2011-10-30 00:00:00')), - PARTITION `p-2012-MSK-2` VALUES LESS THAN (UNIX_TIMESTAMP('2012-03-24 23:00:00')), - PARTITION `pEnd` VALUES LESS THAN (UNIX_TIMESTAMP('2038-01-19 03:14:07')), + PARTITION `p-2000` VALUES LESS THAN (UNIX_TIMESTAMP(20000101)), + PARTITION `p-2011-MSK` VALUES LESS THAN (UNIX_TIMESTAMP(20110326230000)), + PARTITION `p-2011-MSD-1` VALUES LESS THAN (UNIX_TIMESTAMP(20111029220000)), + PARTITION `p-2011-MSD-2` VALUES LESS THAN (UNIX_TIMESTAMP(20111029230000)), + PARTITION `p-2012-MSK-1` VALUES LESS THAN (UNIX_TIMESTAMP(20111030000000)), + PARTITION `p-2012-MSK-2` VALUES LESS THAN (UNIX_TIMESTAMP(20120324230000)), + PARTITION `pEnd` VALUES LESS THAN (UNIX_TIMESTAMP(20380119031407)), PARTITION `pMax` VALUES LESS THAN MAXVALUE); diff --git a/mysql-test/t/partition_error.test b/mysql-test/t/partition_error.test index 536935420a4..19bd922e78f 100644 --- a/mysql-test/t/partition_error.test +++ b/mysql-test/t/partition_error.test @@ -732,7 +732,7 @@ PARTITION BY RANGE (UNIX_TIMESTAMP(c)) CREATE TABLE t1 (c TIMESTAMP) PARTITION BY RANGE (UNIX_TIMESTAMP(c)) -(PARTITION p0 VALUES LESS THAN (UNIX_TIMESTAMP('2000-01-01 00:00:00')), +(PARTITION p0 VALUES LESS THAN (UNIX_TIMESTAMP(20000101000000)), PARTITION p1 VALUES LESS THAN (MAXVALUE)); DROP TABLE t1; diff --git a/mysql-test/t/partition_innodb_semi_consistent.test b/mysql-test/t/partition_innodb_semi_consistent.test index 7f6b3d48c63..7ab2527f0a5 100644 --- a/mysql-test/t/partition_innodb_semi_consistent.test +++ b/mysql-test/t/partition_innodb_semi_consistent.test @@ -119,7 +119,17 @@ INSERT INTO t1 VALUES (1,'init'); DELIMITER |; CREATE PROCEDURE p1() BEGIN - UPDATE t1 SET b = CONCAT(b, '+con2') WHERE a = 1; + # retry the UPDATE in case it times out the lock before con1 has time + # to COMMIT. + DECLARE do_retry INT DEFAULT 0; + DECLARE CONTINUE HANDLER FOR SQLEXCEPTION SET do_retry = 1; + retry_loop:LOOP + UPDATE t1 SET b = CONCAT(b, '+con2') WHERE a = 1; + IF do_retry = 0 THEN + LEAVE retry_loop; + END IF; + SET do_retry = 0; + END LOOP; INSERT INTO t2 VALUES (); END| DELIMITER ;| diff --git a/mysql-test/t/partition_myisam.test b/mysql-test/t/partition_myisam.test index c3766430275..49c5d793169 100644 --- a/mysql-test/t/partition_myisam.test +++ b/mysql-test/t/partition_myisam.test @@ -1,4 +1,5 @@ ---source include/have_partition.inc +-- source include/have_partition.inc + --disable_warnings DROP TABLE IF EXISTS t1, t2; --enable_warnings diff --git a/mysql-test/t/plugin.test b/mysql-test/t/plugin.test index 406821e7a7c..6b0308cfc32 100644 --- a/mysql-test/t/plugin.test +++ b/mysql-test/t/plugin.test @@ -81,7 +81,7 @@ set session sql_mode=@old_sql_mode; # finally, show that conditions that already raised an error are not # adversely affected (error was already sent, do nothing) ---error ER_INCORRECT_GLOBAL_LOCAL_VAR +--error ER_WRONG_VALUE_FOR_VAR set session old=bla; ############################################################### diff --git a/mysql-test/t/plugin_innodb.test b/mysql-test/t/plugin_innodb.test new file mode 100644 index 00000000000..fb5dd84b997 --- /dev/null +++ b/mysql-test/t/plugin_innodb.test @@ -0,0 +1,27 @@ +--source include/not_embedded.inc +--source include/have_example_plugin.inc +--source include/have_innodb.inc + +if (!`select count(*) from information_schema.plugins + where plugin_name = 'innodb' and plugin_status = 'active' and + plugin_library is null`) { + skip Need compiled-in InnoDB; +} + + +--replace_regex /\.dll/.so/ +eval install plugin example soname '$HA_EXAMPLE_SO'; +create table t1(a int) engine=example; +drop table t1; + +alter table mysql.plugin engine=innodb; +--echo restart +--source include/restart_mysqld.inc + +create table t1(a int) engine=example; +select * from t1; +drop table t1; + +alter table mysql.plugin engine=myisam; +uninstall plugin example; + diff --git a/mysql-test/t/pool_of_threads.test b/mysql-test/t/pool_of_threads.test index e71b16e1f89..530038cee91 100644 --- a/mysql-test/t/pool_of_threads.test +++ b/mysql-test/t/pool_of_threads.test @@ -4,6 +4,7 @@ -- source include/have_pool_of_threads.inc # Slow test, don't run during staging part -- source include/not_staging.inc +-- source include/long_test.inc -- source include/common-tests.inc diff --git a/mysql-test/t/ps.test b/mysql-test/t/ps.test index f53e72defcd..18329a1aa75 100644 --- a/mysql-test/t/ps.test +++ b/mysql-test/t/ps.test @@ -3369,3 +3369,13 @@ FROM (SELECT 1 UNION SELECT 2) t; --echo # End of 5.5 tests. ########################################################################### +# +# restoring of the Item tree in BETWEEN with dates +# +prepare stmt from "select date('2010-10-10') between '2010-09-09' and ?"; +set @a='2010-11-11'; +execute stmt using @a; +execute stmt using @a; +set @a='2010-08-08'; +execute stmt using @a; +execute stmt using @a; diff --git a/mysql-test/t/ps_ddl.test b/mysql-test/t/ps_ddl.test index 00035f065e6..fb194c6b5b9 100644 --- a/mysql-test/t/ps_ddl.test +++ b/mysql-test/t/ps_ddl.test @@ -712,7 +712,7 @@ execute stmt; call p_verify_reprepare_count(0); drop view t1; -# Since the IS table has been substituted in, the statement still works +--error 1146 execute stmt; call p_verify_reprepare_count(0); diff --git a/mysql-test/t/query_cache.test b/mysql-test/t/query_cache.test index 56ea4e7c268..aad02219215 100644 --- a/mysql-test/t/query_cache.test +++ b/mysql-test/t/query_cache.test @@ -1,4 +1,5 @@ -- source include/have_query_cache.inc +-- source include/long_test.inc # # Tests with query cache @@ -1239,6 +1240,7 @@ set GLOBAL query_cache_type=default; set GLOBAL query_cache_limit=default; set GLOBAL query_cache_min_res_unit=default; set GLOBAL query_cache_size=default; +set local query_cache_type=default; # # Bug#33756 - query cache with concurrent_insert=0 appears broken @@ -1564,7 +1566,6 @@ DROP TABLE t1; --echo End of 5.1 tests - --echo # --echo # Bug#51336 Assert in reload_acl_and_cache during RESET QUERY CACHE --echo # @@ -1582,3 +1583,23 @@ RESET QUERY CACHE; COMMIT; DROP TABLE t1; +--echo New query cache switching OFF mechanism test +set global query_cache_size=1024*1024*20; +set global query_cache_type=on; +select @@query_cache_size, @@global.query_cache_type, @@local.query_cache_type; +set global query_cache_size=0; +select @@query_cache_size, @@global.query_cache_type, @@local.query_cache_type; +set global query_cache_size=1024*1024*20; +select @@query_cache_size, @@global.query_cache_type, @@local.query_cache_type; +set global query_cache_type=off; +select @@query_cache_size, @@global.query_cache_type, @@local.query_cache_type; +set global query_cache_type=on; +select @@query_cache_size, @@global.query_cache_type, @@local.query_cache_type; +set local query_cache_type= on; +select @@query_cache_size, @@global.query_cache_type, @@local.query_cache_type; + + +--echo restore defaults +SET GLOBAL query_cache_type= default; +SET GLOBAL query_cache_size= default; +SET LOCAL query_cache_type= default; diff --git a/mysql-test/t/query_cache_debug.test b/mysql-test/t/query_cache_debug.test index 70b3c81168d..2f85813d1ef 100644 --- a/mysql-test/t/query_cache_debug.test +++ b/mysql-test/t/query_cache_debug.test @@ -208,17 +208,7 @@ SET DEBUG_SYNC="now WAIT_FOR parked1_2"; --echo ** until a broadcast signal reaches them causing both threads to --echo ** come alive and check the condition. SET DEBUG_SYNC="now SIGNAL go2"; ---echo ** Wait for thd2 to receive the signal -let $wait_condition= - SELECT COUNT(*) = 1 FROM information_schema.processlist - WHERE state = "Waiting for query cache lock"; ---source include/wait_condition.inc SET DEBUG_SYNC="now SIGNAL go3"; ---echo ** Wait for thd3 to receive the signal -let $wait_condition= - SELECT COUNT(*) = 2 FROM information_schema.processlist - WHERE state = "Waiting for query cache lock"; ---source include/wait_condition.inc --echo ** --echo ** Finally signal the DELETE statement on THD1 one last time. diff --git a/mysql-test/t/query_cache_disabled-master.opt b/mysql-test/t/query_cache_disabled-master.opt deleted file mode 100644 index d7d47164883..00000000000 --- a/mysql-test/t/query_cache_disabled-master.opt +++ /dev/null @@ -1 +0,0 @@ ---query_cache_type=0 diff --git a/mysql-test/t/query_cache_disabled.test b/mysql-test/t/query_cache_disabled.test deleted file mode 100644 index cbc98bd94d6..00000000000 --- a/mysql-test/t/query_cache_disabled.test +++ /dev/null @@ -1,15 +0,0 @@ --- source include/have_query_cache.inc -# -# Bug#38551 query cache can still consume [very little] cpu time even when it is off. -# -SHOW GLOBAL VARIABLES LIKE 'query_cache_type'; ---error ER_QUERY_CACHE_DISABLED -SET GLOBAL query_cache_type=ON; ---error ER_QUERY_CACHE_DISABLED -SET GLOBAL query_cache_type=DEMAND; ---error ER_QUERY_CACHE_DISABLED -SET GLOBAL query_cache_type=OFF; -SET GLOBAL query_cache_size=1024*1024; -SHOW GLOBAL VARIABLES LIKE 'query_cache_size'; -SET GLOBAL query_cache_size=0; - diff --git a/mysql-test/t/range.test b/mysql-test/t/range.test index 6c9320b708a..0a34bac32ba 100644 --- a/mysql-test/t/range.test +++ b/mysql-test/t/range.test @@ -3,7 +3,7 @@ # --disable_warnings -drop table if exists t1, t2, t3; +drop table if exists t1, t2, t3, t10, t100; --enable_warnings CREATE TABLE t1 ( @@ -1393,3 +1393,58 @@ SELECT * FROM t1, t1 as t2 WHERE t1.i4 BETWEEN t2.pk AND t2.pk; DROP TABLE t1; --echo End of 5.1 tests + +# +# lp:750117 Bogus warning with aggregate and datetime column +# +create table t1 (f1 datetime, key (f1)); +insert into t1 values ('2000-03-09 15:56:59'),('2000-05-05 23:24:28'),('2000-06-13 13:12:06'); +select min(f1) from t1 where f1 >= '2006-05-25 07:00:20' and f1 between '2003-11-23 10:00:09' and '2010-01-01 01:01:01' and f1 > '2001-01-01 01:01:01'; +drop table t1; + +--echo # +--echo # BUG#11765831: 'RANGE ACCESS' MAY INCORRECTLY FILTER +--echo # AWAY QUALIFYING ROWS +--echo # + +CREATE TABLE t10( + K INT NOT NULL AUTO_INCREMENT, + I INT, J INT, + PRIMARY KEY(K), + KEY(I,J) +); +INSERT INTO t10(I,J) VALUES (6,1),(6,2),(6,3),(6,4),(6,5), + (6,6),(6,7),(6,8),(6,9),(6,0); + +CREATE TABLE t100 LIKE t10; +INSERT INTO t100(I,J) SELECT X.I, X.K+(10*Y.K) FROM t10 AS X,t10 AS Y; + +# Insert offending value: +INSERT INTO t100(I,J) VALUES(8,26); + +let $query= SELECT * FROM t100 WHERE I <> 6 OR (I <> 8 AND J = 5); + +#Verify that 'range' access will be used +--echo +--eval EXPLAIN $query + +# Only row 101,8,26 should be returned +--echo +--eval $query + +DROP TABLE t10,t100; + +--echo # +--echo # lp:817363: Wrong result with sort_union and multipart key in maria-5.3 +--echo # +CREATE TABLE t1 (a int NOT NULL , b int, c int, d varchar(32), KEY (d,b), PRIMARY KEY (a)) ; +INSERT INTO t1 VALUES (7,7,NULL,'e'),(8,1,0,'p'),(9,7,1,'s'),(10,1,1,'j'),(12,2,0,'c'),(13,0,0,'a'),(14,1,1,'q'); + +SELECT c FROM t1 WHERE d='q' OR d>='q' OR a > 97 OR (d IN ('j','s','i') AND b = 102); +SELECT c FROM t1 ignore index (d) WHERE d='q' OR d>='q' OR a > 97 OR (d IN ('j','s','i') AND b = 102); + +SELECT * FROM t1 ignore index(d) WHERE d = 'q' OR d >= 'q' OR (d IN ( 'j' , 's' , 'i' ) AND ( b = 102 )); +SELECT * FROM t1 force index(d) WHERE d = 'q' OR d >= 'q' OR (d IN ( 'j' , 's' , 'i' ) AND ( b = 102 )); + +DROP TABLE t1; + diff --git a/mysql-test/t/range_mrr_icp.test b/mysql-test/t/range_mrr_icp.test new file mode 100644 index 00000000000..724da8aea3b --- /dev/null +++ b/mysql-test/t/range_mrr_icp.test @@ -0,0 +1,7 @@ +set @mrr_icp_extra_tmp=@@optimizer_switch; +set optimizer_switch='mrr=on,mrr_sort_keys=on,index_condition_pushdown=on'; + +--source t/range.test + +set optimizer_switch=@mrr_icp_extra_tmp; + diff --git a/mysql-test/t/range_vs_index_merge.test b/mysql-test/t/range_vs_index_merge.test new file mode 100755 index 00000000000..1f7065dcb0a --- /dev/null +++ b/mysql-test/t/range_vs_index_merge.test @@ -0,0 +1,1033 @@ +--disable_warnings +DROP TABLE IF EXISTS t1,t2,t3,t4; +DROP DATABASE IF EXISTS world; +--enable_warnings + +set names utf8; + +CREATE DATABASE world; + +use world; + +--source include/world_schema.inc + +--disable_query_log +--disable_result_log +--disable_warnings +--source include/world.inc +--enable_warnings +--enable_result_log +--enable_query_log + +SELECT COUNT(*) FROM Country; +SELECT COUNT(*) FROM City; +SELECT COUNT(*) FROM CountryLanguage; + +CREATE INDEX Name ON City(Name); + +--disable_query_log +--disable_result_log +--disable_warnings +ANALYZE TABLE City; +--enable_warnings +--enable_result_log +--enable_query_log + +set session optimizer_switch='index_merge_sort_intersection=off'; + +# The following 4 queries are added for code coverage + +#the exptected # of rows differ on 32-bit and 64-bit platforms for innodb +--replace_column 9 4079 +EXPLAIN +SELECT * FROM City + WHERE (Population >= 100000 OR Name LIKE 'P%' OR Population < 100000); + +EXPLAIN +SELECT * FROM City + WHERE (Population >= 100000 OR Name LIKE 'P%') AND Country='CAN' OR + (Population < 100000 OR Name Like 'T%') AND Country='ARG'; + +EXPLAIN +SELECT * FROM City + WHERE Population < 200000 AND Name LIKE 'P%' AND + (Population > 300000 OR Name LIKE 'T%') AND + (Population < 100000 OR Name LIKE 'Pa%'); + +EXPLAIN +SELECT * FROM City + WHERE Population > 100000 AND Name LIKE 'Aba%' OR + Country IN ('CAN', 'ARG') AND ID < 3800 OR + Country < 'U' AND Name LIKE 'Zhu%' OR + ID BETWEEN 3800 AND 3810; + +# The output of the next 3 commands tells us about selectivities +# of the conditions utilized in 2 queries following after them + +EXPLAIN +SELECT * FROM City + WHERE (Population > 101000 AND Population < 115000); + +EXPLAIN +SELECT * FROM City + WHERE (Population > 101000 AND Population < 102000); + +EXPLAIN +SELECT * FROM City + WHERE ((Name > 'Ca' AND Name < 'Cf') OR (Country > 'E' AND Country < 'F')); + +# The pattern of the WHERE condition used in the following 2 queries is +# (range(key1) OR range(key2)) AND range(key3) +# Varying values of the constants in the second conjunct of the condition +# we can get either a plan with range index scan for key3 or a plan with +# an index merge retrieval over key2 and key3 + +EXPLAIN +SELECT * FROM City + WHERE ((Name > 'Ca' AND Name < 'Cf') OR (Country > 'E' AND Country < 'F')) + AND (Population > 101000 AND Population < 115000); + +EXPLAIN +SELECT * FROM City + WHERE ((Name > 'Ca' AND Name < 'Cf') OR (Country > 'E' AND Country < 'F')) + AND (Population > 101000 AND Population < 102000); + +# The following 4 queries check that the plans +# for the previous 2 plans are valid + +SELECT * FROM City USE INDEX () + WHERE ((Name > 'Ca' AND Name < 'Cf') OR (Country > 'E' AND Country < 'F')) + AND (Population > 101000 AND Population < 115000); + +SELECT * FROM City + WHERE ((Name > 'Ca' AND Name < 'Cf') OR (Country > 'E' AND Country < 'F')) + AND (Population > 101000 AND Population < 115000); + +SELECT * FROM City USE INDEX () + WHERE ((Name > 'Ca' AND Name < 'Cf') OR (Country > 'E' AND Country < 'F')) + AND (Population > 101000 AND Population < 102000); + +SELECT * FROM City + WHERE ((Name > 'Ca' AND Name < 'Cf') OR (Country > 'E' AND Country < 'F')) + AND (Population > 101000 AND Population < 102000); + +# The output of the next 7 commands tells us about selectivities +# of the conditions utilized in 4 queries following after them + +EXPLAIN +SELECT * FROM City WHERE (Name < 'Ac'); +EXPLAIN +SELECT * FROM City WHERE (Name < 'Bb'); +EXPLAIN +SELECT * FROM City WHERE (Country > 'A' AND Country < 'B'); +EXPLAIN +SELECT * FROM City WHERE (Name BETWEEN 'P' AND 'Pb'); +EXPLAIN +SELECT * FROM City WHERE (Name BETWEEN 'P' AND 'S'); +EXPLAIN +SELECT * FROM City WHERE (Population > 101000 AND Population < 110000); +EXPLAIN +SELECT * FROM City WHERE (Population > 103000 AND Population < 104000); + +# The pattern of the WHERE condition used in the following 4 queries is +# (range1(key1) AND range(key2)) OR (range2(key1) AND range(key3) +# Varying values of the constants in the range conjuncts of the condition +# we can get: +# 1. a plan with range index over key1 +# index merge retrievals over: +# 2. key1 and key3 +# 3. key2 and key1 +# 4. key2 and key3 + +EXPLAIN +SELECT * FROM City + WHERE (Name < 'Ac' AND (Country > 'A' AND Country < 'B')) OR + (Name BETWEEN 'P' AND 'Pb' AND (Population > 101000 AND Population < 110000)); + +EXPLAIN +SELECT * FROM City + WHERE (Name < 'Ac' AND (Country > 'A' AND Country < 'B')) OR + (Name BETWEEN 'P' AND 'S' AND (Population > 103000 AND Population < 104000)); + +EXPLAIN +SELECT * FROM City + WHERE (Name < 'Bb' AND (Country > 'A' AND Country < 'B')) OR + (Name BETWEEN 'P' AND 'Pb' AND (Population > 101000 AND Population < 110000)); + +EXPLAIN +SELECT * FROM City + WHERE (Name < 'Bb' AND (Country > 'A' AND Country < 'B')) OR + (Name BETWEEN 'P' AND 'S' AND (Population > 103000 AND Population < 104000)); + +# The following 8 queries check that the plans +# for the previous 4 plans are valid + +SELECT * FROM City USE INDEX () + WHERE (Name < 'Ac' AND (Country > 'A' AND Country < 'B')) OR + (Name BETWEEN 'P' AND 'Pb' AND (Population > 101000 AND Population < 110000)); + +SELECT * FROM City + WHERE (Name < 'Ac' AND (Country > 'A' AND Country < 'B')) OR + (Name BETWEEN 'P' AND 'Pb' AND (Population > 101000 AND Population < 110000)); + +SELECT * FROM City USE INDEX () + WHERE (Name < 'Ac' AND (Country > 'A' AND Country < 'B')) OR + (Name BETWEEN 'P' AND 'S' AND (Population > 103000 AND Population < 104000)); + +SELECT * FROM City + WHERE (Name < 'Ac' AND (Country > 'A' AND Country < 'B')) OR + (Name BETWEEN 'P' AND 'S' AND (Population > 103000 AND Population < 104000)); + +SELECT * FROM City USE INDEX () + WHERE (Name < 'Bb' AND (Country > 'A' AND Country < 'B')) OR + (Name BETWEEN 'P' AND 'Pb' AND (Population > 101000 AND Population < 110000)); + +SELECT * FROM City + WHERE (Name < 'Bb' AND (Country > 'A' AND Country < 'B')) OR + (Name BETWEEN 'P' AND 'Pb' AND (Population > 101000 AND Population < 110000)); + +SELECT * FROM City USE INDEX () + WHERE (Name < 'Bb' AND (Country > 'A' AND Country < 'B')) OR + (Name BETWEEN 'P' AND 'S' AND (Population > 103000 AND Population < 104000)); + +SELECT * FROM City + WHERE (Name < 'Bb' AND (Country > 'A' AND Country < 'B')) OR + (Name BETWEEN 'P' AND 'S' AND (Population > 103000 AND Population < 104000)); + + +# The output of the next 6 commands tells us about selectivities +# of the conditions utilized in 3 queries following after them + +EXPLAIN +SELECT * FROM City WHERE (ID < 10) OR (ID BETWEEN 100 AND 110); +EXPLAIN +SELECT * FROM City WHERE (ID < 200) OR (ID BETWEEN 100 AND 200); +EXPLAIN +SELECT * FROM City WHERE (ID < 600) OR (ID BETWEEN 900 AND 1500); +EXPLAIN +SELECT * FROM City WHERE Country > 'A' AND Country < 'ARG'; +EXPLAIN +SELECT * FROM City WHERE Name LIKE 'H%' OR Name LIKE 'P%' ; +EXPLAIN +SELECT * FROM City WHERE Name LIKE 'Ha%' OR Name LIKE 'Pa%' ; + +# The pattern of the WHERE condition used in the following 3 queries is +# (range1(key1) AND (range1(key2) OR range(key3)) OR +# (range2(key1) AND (range2(key2) OR range(key4)) +# Varying values of the constants in the range predicates of the condition +# we can get: +# 1. a plan with range index over key1 +# 2. an index merge retrieval over key1, key2 and key3 + +EXPLAIN +SELECT * FROM City + WHERE ((ID < 10) AND (Name LIKE 'H%' OR (Country > 'A' AND Country < 'ARG'))) + OR ((ID BETWEEN 100 AND 110) AND + (Name LIKE 'P%' OR (Population > 103000 AND Population < 104000))); + +EXPLAIN +SELECT * FROM City + WHERE ((ID < 800) AND (Name LIKE 'Ha%' OR (Country > 'A' AND Country < 'ARG'))) + OR ((ID BETWEEN 900 AND 1500) AND + (Name LIKE 'Pa%' OR (Population > 103000 AND Population < 104000))); + +EXPLAIN +SELECT * FROM City + WHERE ((ID < 200) AND (Name LIKE 'Ha%' OR (Country > 'A' AND Country < 'ARG'))) + OR ((ID BETWEEN 100 AND 200) AND + (Name LIKE 'Pa%' OR (Population > 103000 AND Population < 104000))); + + +# The following 6 queries check that the plans +# for the previous 3 plans are valid + +SELECT * FROM City USE INDEX () + WHERE ((ID < 10) AND (Name LIKE 'H%' OR (Country > 'A' AND Country < 'ARG'))) + OR ((ID BETWEEN 100 AND 110) AND + (Name LIKE 'P%' OR (Population > 103000 AND Population < 104000))); + +SELECT * FROM City + WHERE ((ID < 10) AND (Name LIKE 'H%' OR (Country > 'A' AND Country < 'ARG'))) + OR ((ID BETWEEN 100 AND 110) AND + (Name LIKE 'P%' OR (Population > 103000 AND Population < 104000))); + +SELECT * FROM City USE INDEX() + WHERE ((ID < 800) AND (Name LIKE 'Ha%' OR (Country > 'A' AND Country < 'ARG'))) + OR ((ID BETWEEN 900 AND 1500) AND + (Name LIKE 'Pa%' OR (Population > 103000 AND Population < 104000))); + +SELECT * FROM City + WHERE ((ID < 800) AND (Name LIKE 'Ha%' OR (Country > 'A' AND Country < 'ARG'))) + OR ((ID BETWEEN 900 AND 1500) AND + (Name LIKE 'Pa%' OR (Population > 103000 AND Population < 104000))); + +SELECT * FROM City USE INDEX () + WHERE ((ID < 200) AND (Name LIKE 'Ha%' OR (Country > 'A' AND Country < 'ARG'))) + OR ((ID BETWEEN 100 AND 200) AND + (Name LIKE 'Pa%' OR (Population > 103000 AND Population < 104000))); + +SELECT * FROM City + WHERE ((ID < 200) AND (Name LIKE 'Ha%' OR (Country > 'A' AND Country < 'ARG'))) + OR ((ID BETWEEN 100 AND 200) AND + (Name LIKE 'Pa%' OR (Population > 103000 AND Population < 104000))); + + +# The output of the next 8 commands tells us about selectivities +# of the conditions utilized in 2 queries following after them + +EXPLAIN +SELECT * FROM City WHERE Population > 101000 AND Population < 102000; +EXPLAIN +SELECT * FROM City WHERE Population > 101000 AND Population < 110000; +EXPLAIN +SELECT * FROM City WHERE Country < 'C'; +EXPLAIN +SELECT * FROM City WHERE Country < 'AGO'; +EXPLAIN +SELECT * FROM City WHERE Name BETWEEN 'P' AND 'S'; +EXPLAIN +SELECT * FROM City WHERE Name BETWEEN 'P' AND 'Pb'; +EXPLAIN +SELECT * FROM City WHERE ID BETWEEN 3400 AND 3800; +EXPLAIN +SELECT * FROM City WHERE ID BETWEEN 3790 AND 3800; +EXPLAIN +SELECT * FROM City WHERE Name LIKE 'P%'; + +# The pattern of the WHERE condition used in the following 2 queries is +# (range(key1) AND (range1(key2) OR range1(key3)) OR +# (range(key4) AND (range2(key2) OR range2(key3)) +# Varying values of the constants in the range predicates of the condition +# we can get: +# index merge retrievals over: +# 1. key1, key2 and key3 +# 2. key4, key2 and key3 + +EXPLAIN +SELECT * FROM City + WHERE ((Population > 101000 AND Population < 102000) AND + (Country < 'C' OR Name BETWEEN 'P' AND 'S')) OR + ((ID BETWEEN 3400 AND 3800) AND + (Country < 'AGO' OR Name LIKE 'Pa%')); + +EXPLAIN +SELECT * FROM City + WHERE ((Population > 101000 AND Population < 110000) AND + (Country < 'AGO' OR Name BETWEEN 'P' AND 'Pb')) OR + ((ID BETWEEN 3790 AND 3800) AND + (Country < 'C' OR Name LIKE 'P%')); + +# The following 4 queries check that the plans +# for the previous 2 plans are valid + +SELECT * FROM City USE INDEX () + WHERE ((Population > 101000 AND Population < 102000) AND + (Country < 'C' OR Name BETWEEN 'P' AND 'S')) OR + ((ID BETWEEN 3400 AND 3800) AND + (Country < 'AGO' OR Name LIKE 'Pa%')); + +SELECT * FROM City + WHERE ((Population > 101000 AND Population < 102000) AND + (Country < 'C' OR Name BETWEEN 'P' AND 'S')) OR + ((ID BETWEEN 3400 AND 3800) AND + (Country < 'AGO' OR Name LIKE 'Pa%')); + +SELECT * FROM City USE INDEX () + WHERE ((Population > 101000 AND Population < 110000) AND + (Country < 'AGO' OR Name BETWEEN 'P' AND 'Pb')) OR + ((ID BETWEEN 3790 AND 3800) AND + (Country < 'C' OR Name LIKE 'P%')); + +SELECT * FROM City + WHERE ((Population > 101000 AND Population < 110000) AND + (Country < 'AGO' OR Name BETWEEN 'P' AND 'Pb')) OR + ((ID BETWEEN 3790 AND 3800) AND + (Country < 'C' OR Name LIKE 'P%')); + + +CREATE INDEX CountryPopulation ON City(Country,Population); + +--disable_query_log +--disable_result_log +--disable_warnings +ANALYZE TABLE City; +--enable_warnings +--enable_result_log +--enable_query_log + +# The output of the next 5 commands tells us about selectivities +# of the conditions utilized in 2 queries following after them + +EXPLAIN +SELECT * FROM City WHERE Name LIKE 'Pas%'; +EXPLAIN +SELECT * FROM City WHERE Name LIKE 'P%'; +EXPLAIN +SELECT * FROM City WHERE (Population > 101000 AND Population < 103000); +EXPLAIN +SELECT * FROM City WHERE Country='USA'; +EXPLAIN +SELECT * FROM City WHERE Country='FIN'; + +# The pattern of the WHERE condition used in the following 3 queries is +# (range(key1_p2) OR (range(key2)) AND key1_p1=c +# Varying values of the constants in the range predicates of the condition +# we can get: +# 1. a plan with range index over key1_p1 +# 2. an index merge retrieval over: key1 and key2 + +EXPLAIN +SELECT * FROM City + WHERE ((Population > 101000 AND Population < 103000) OR Name LIKE 'Pas%') + AND Country='USA'; + +EXPLAIN +SELECT * FROM City + WHERE ((Population > 101000 AND Population < 103000) OR Name LIKE 'P%') + AND Country='FIN'; + +# The following 4 queries check that the plans +# for the previous 2 plans are valid + +SELECT * FROM City + WHERE ((Population > 101000 AND Population < 103000) OR Name LIKE 'Pas%') + AND Country='USA'; + +SELECT * FROM City USE INDEX () + WHERE ((Population > 101000 AND Population < 103000) OR Name LIKE 'Pas%') + AND Country='USA'; + +SELECT * FROM City + WHERE ((Population > 101000 AND Population < 103000) OR Name LIKE 'P%') + AND Country='FIN'; + +SELECT * FROM City USE INDEX () + WHERE ((Population > 101000 AND Population < 103000) OR Name LIKE 'P%') + AND Country='FIN'; + + +CREATE INDEX CountryName ON City(Country,Name); + +--disable_query_log +--disable_result_log +--disable_warnings +ANALYZE TABLE City; +--enable_warnings +--enable_result_log +--enable_query_log + +# The output of the next 12 commands tells us about selectivities +# of the conditions utilized in 3 queries following after them + +EXPLAIN +SELECT * FROM City WHERE Country='USA'; +EXPLAIN +SELECT * FROM City WHERE Country='FIN'; +EXPLAIN +SELECT * FROM City WHERE Country='BRA'; +EXPLAIN +SELECT * FROM City WHERE ID BETWEEN 3790 AND 3800; +EXPLAIN +SELECT * FROM City WHERE ID BETWEEN 4025 AND 4035; +EXPLAIN +SELECT * FROM City WHERE ID BETWEEN 4028 AND 4032; +EXPLAIN +SELECT * FROM City WHERE ID BETWEEN 3500 AND 3800; +EXPLAIN +SELECT * FROM City WHERE ID BETWEEN 4000 AND 4300; +EXPLAIN +SELECT * FROM City WHERE ID BETWEEN 250 and 260 ; +EXPLAIN +SELECT * FROM City WHERE (Population > 101000 AND Population < 102000); +EXPLAIN +SELECT * FROM City WHERE (Population > 101000 AND Population < 103000); +EXPLAIN +SELECT * FROM City WHERE Name LIKE 'Pa%'; + +# The pattern of the WHERE condition used in the following 3 queries is +# (range(key1_p2) OR range1(key3)) AND +# range(key1|2_p1=c) AND +# (range(key2_p2) OR range2(key3)) +# Varying values of the constants in the range conjuncts of the condition +# we can get: +# 1. a plan with range index over key1|2_p1 +# index merge retrievals over: +# 2. key1 and key3 +# 3. key2 and key3 + +EXPLAIN +SELECT * FROM City + WHERE ((Population > 101000 AND Population < 102000) OR + ID BETWEEN 3790 AND 3800) AND Country='USA' + AND (Name LIKE 'Pa%' OR ID BETWEEN 4025 AND 4035); + +EXPLAIN +SELECT * FROM City + WHERE ((Population > 101000 AND Population < 103000) OR + ID BETWEEN 3790 AND 3800) AND Country='USA' + AND (Name LIKE 'Pa%' OR ID BETWEEN 4028 AND 4032); + +EXPLAIN +SELECT * FROM City + WHERE ((Population > 101000 AND Population < 110000) OR + ID BETWEEN 3500 AND 3800) AND Country='FIN' + AND (Name BETWEEN 'P' AND 'T' OR ID BETWEEN 4000 AND 4300); + +# The following 6 queries check that the plans +# for the previous 3 plans are valid + +SELECT * FROM City USE INDEX () + WHERE ((Population > 101000 AND Population < 102000) OR + ID BETWEEN 3790 AND 3800) AND Country='USA' + AND (Name LIKE 'Pa%' OR ID BETWEEN 4025 AND 4035); + +SELECT * FROM City + WHERE ((Population > 101000 AND Population < 102000) OR + ID BETWEEN 3790 AND 3800) AND Country='USA' + AND (Name LIKE 'Pa%' OR ID BETWEEN 4025 AND 4035); + +SELECT * FROM City USE INDEX () + WHERE ((Population > 101000 AND Population < 102000) OR + ID BETWEEN 3790 AND 3800) AND Country='USA' + AND (Name LIKE 'Pa%' OR ID BETWEEN 4028 AND 4032); + +SELECT * FROM City + WHERE ((Population > 101000 AND Population < 102000) OR + ID BETWEEN 3790 AND 3800) AND Country='USA' + AND (Name LIKE 'Pa%' OR ID BETWEEN 4028 AND 4032); + +SELECT * FROM City USE INDEX () + WHERE ((Population > 101000 AND Population < 102000) OR + ID BETWEEN 3790 AND 3800) AND Country='FIN' + AND (Name LIKE 'Pa%' OR ID BETWEEN 4025 AND 4035); + +SELECT * FROM City + WHERE ((Population > 101000 AND Population < 102000) OR + ID BETWEEN 3790 AND 3800) AND Country='FIN' + AND (Name LIKE 'Pa%' OR ID BETWEEN 4025 AND 4035); + + +# The pattern of the WHERE condition used in the following query is +# (range(key1_p2) OR range1(key3)) AND range(key1|2_p1=c1) AND +# (range(key2_p2) OR range1(key3)) AND range(key1|2_p1=c2) +# We get an index merge retrieval over key1, key2 and key3 for it + +EXPLAIN +SELECT * FROM City + WHERE ((Population > 101000 and Population < 102000) OR + ID BETWEEN 3790 AND 3800) AND Country='USA' + OR (Name LIKE 'Pa%' OR ID BETWEEN 250 AND 260) AND Country='BRA'; + +# The following 2 queries check that the plans +# for the previous plan is valid + +SELECT * FROM City USE INDEX () + WHERE ((Population > 101000 and Population < 102000) OR + ID BETWEEN 3790 AND 3800) AND Country='USA' + OR (Name LIKE 'Pa%' OR ID BETWEEN 250 AND 260) AND Country='BRA'; + +SELECT * FROM City + WHERE ((Population > 101000 and Population < 102000) OR + ID BETWEEN 3790 AND 3800) AND Country='USA' + OR (Name LIKE 'Pa%' OR ID BETWEEN 250 AND 260) AND Country='BRA'; + +# The pattern of the WHERE condition used in the following query is +# (impossible_range(key1_p2) OR range1(key3)) AND +# range(key1|2_p1=c1) AND +# (range(key2_p2) OR range2(key3)) +# where range1(key3) and range2(key3) are disjoint +# Varying values of the constant in range predicates we get plans: +# 1. with an index scan over key2 +# 2. with an index scan over key4=key2_p2 + +EXPLAIN +SELECT * FROM City + WHERE ((Population > 101000 AND Population < 11000) OR + ID BETWEEN 3500 AND 3800) AND Country='USA' + AND (Name LIKE 'P%' OR ID BETWEEN 4000 AND 4300); + +EXPLAIN +SELECT * FROM City + WHERE ((Population > 101000 AND Population < 11000) OR + ID BETWEEN 3500 AND 3800) AND Country='USA' + AND (Name LIKE 'Pho%' OR ID BETWEEN 4000 AND 4300); + +# The following 4 queries check that the plans +# for the previous 2 plans are valid + +SELECT * FROM City USE INDEX () + WHERE ((Population > 101000 AND Population < 11000) OR + ID BETWEEN 3500 AND 3800) AND Country='USA' + AND (Name LIKE 'P%' OR ID BETWEEN 4000 AND 4300); + +SELECT * FROM City + WHERE ((Population > 101000 AND Population < 11000) OR + ID BETWEEN 3500 AND 3800) AND Country='USA' + AND (Name LIKE 'P%' OR ID BETWEEN 4000 AND 4300); + +SELECT * FROM City USE INDEX () + WHERE ((Population > 101000 AND Population < 11000) OR + ID BETWEEN 3500 AND 3800) AND Country='USA' + AND (Name LIKE 'Pho%' OR ID BETWEEN 4000 AND 4300); + +SELECT * FROM City + WHERE ((Population > 101000 AND Population < 11000) OR + ID BETWEEN 3500 AND 3800) AND Country='USA' + AND (Name LIKE 'Pho%' OR ID BETWEEN 4000 AND 4300); + + +DROP INDEX Population ON City; +DROP INDEX Name ON City; + +# The pattern of the WHERE condition used in the following query is +# (key1|2_p1=c AND range(key1_p2)) OR (key1|2_p1=c AND range(key2_p2)) +# We get an index merge retrieval over key1, key2 for it + +EXPLAIN +SELECT * FROM City + WHERE Country='USA' AND Population BETWEEN 101000 AND 102000 OR + Country='USA' AND Name LIKE 'Pa%'; + +# The following 2 queries check that the plans +# for the previous plan is valid + +SELECT * FROM City USE INDEX() + WHERE Country='USA' AND Population BETWEEN 101000 AND 102000 OR + Country='USA' AND Name LIKE 'Pa%'; + +SELECT * FROM City + WHERE Country='USA' AND Population BETWEEN 101000 AND 102000 OR + Country='USA' AND Name LIKE 'Pa%'; + + +# The pattern of the WHERE condition used in the following query is +# key1|2_p1=c AND (range(key1_p2) OR range(key2_p2)) +# We get an index merge retrieval over key1, key2 for it + +EXPLAIN +SELECT * FROM City + WHERE Country='USA' AND + (Population BETWEEN 101000 AND 102000 OR Name LIKE 'Pa%'); + +# The following 2 queries check that the plans +# for the previous plan is valid + +SELECT * FROM City + WHERE Country='USA' AND + (Population BETWEEN 101000 AND 102000 OR Name LIKE 'Pa%'); + +SELECT * FROM City + WHERE Country='USA' AND + (Population BETWEEN 101000 AND 102000 OR Name LIKE 'Pa%'); + + +DROP DATABASE world; + +use test; + +# +# Bug #17259: a bad range scan and a good index merge plan +# + +CREATE TABLE t1 ( + id int(10) unsigned NOT NULL auto_increment, + account_id int(10) unsigned NOT NULL, + first_name varchar(50) default NULL, + middle_name varchar(50) default NULL, + last_name varchar(100) default NULL, + home_address_1 varchar(150) default NULL, + home_city varchar(75) default NULL, + home_state char(2) default NULL, + home_postal_code varchar(50) default NULL, + home_county varchar(75) default NULL, + home_country char(3) default NULL, + work_address_1 varchar(150) default NULL, + work_city varchar(75) default NULL, + work_state char(2) default NULL, + work_postal_code varchar(50) default NULL, + work_county varchar(75) default NULL, + work_country char(3) default NULL, + login varchar(50) NOT NULL, + PRIMARY KEY (id), + KEY login (login,account_id), + KEY account_id (account_id), + KEY user_home_country_indx (home_country), + KEY user_work_country_indx (work_country), + KEY user_home_state_indx (home_state), + KEY user_work_state_indx (work_state), + KEY user_home_city_indx (home_city), + KEY user_work_city_indx (work_city), + KEY user_first_name_indx (first_name), + KEY user_last_name_indx (last_name) +); + +insert into t1(account_id, login, home_state, work_state) values + (1, 'pw', 'ia', 'ia'), (1, 'pw', 'ia', 'ia'), (1, 'pw', 'ia', 'ia'), + (1, 'pw', 'ia', 'ia'), (1, 'pw', 'ia', 'ia'), (1, 'pw', 'ia', 'ia'); +insert into t1(account_id, login, home_state, work_state) + select 1, 'pw', 'ak', 'ak' from t1; +insert into t1(account_id, login, home_state, work_state) + select 1, 'pw', 'ak', 'ak' from t1; +insert into t1(account_id, login, home_state, work_state) + select 1, 'pw', 'ak', 'ak' from t1; +insert into t1(account_id, login, home_state, work_state) + select 1, 'pw', 'ak', 'ak' from t1; +insert into t1(account_id, login, home_state, work_state) + select 1, 'pw', 'ak', 'ak' from t1; +insert into t1(account_id, login, home_state, work_state) + select 1, 'pw', 'ak', 'ak' from t1; +insert into t1(account_id, login, home_state, work_state) + select 1, 'pw', 'ak', 'ak' from t1; +insert into t1(account_id, login, home_state, work_state) + select 1, 'pw', 'ak', 'ak' from t1; +insert into t1(account_id, login, home_state, work_state) + select 1, 'pw', 'ak', 'ak' from t1; + +analyze table t1; + +select count(*) from t1 where account_id = 1; + +select * from t1 + where (home_state = 'ia' or work_state='ia') and account_id = 1; + +explain +select * from t1 + where (home_state = 'ia' or work_state='ia') and account_id = 1; + +drop table t1; + +# +# Bug #17673: no index merge plan if the condition for the last used +# index component is factored out of the or formula +# + +CREATE TABLE t1 ( + c1 int(11) NOT NULL auto_increment, + c2 decimal(10,0) default NULL, + c3 decimal(10,0) default NULL, + c4 decimal(10,0) default NULL, + c5 decimal(10,0) default NULL, + cp decimal(1,0) default NULL, + ce decimal(10,0) default NULL, + cdata char(20), + PRIMARY KEY (c1), + KEY k1 (c2,c3,cp,ce), + KEY k2 (c4,c5,cp,ce) +); + +insert into t1 (c2, c3, c4, c5, cp) values(1,1,1,1,1); +insert into t1 (c2, c3, c4, c5, cp) values(2,1,1,1,4); +insert into t1 (c2, c3, c4, c5, cp) values(2,1,2,1,1); +insert into t1 (c2, c3, c4, c5, cp) values(2,1,3,1,4); +insert into t1 (c2, c3, c4, c5, cp) values(3,1,4,1,4); + +insert into t1 (c2, c3, c4, c5, cp) + select c2, c3, c4, c5, cp from t1 where cp = 4; +insert into t1 (c2, c3, c4, c5, cp) + select c2, c3, c4, c5, cp from t1 where cp = 4; +insert into t1 (c2, c3, c4, c5, cp) + select c2, c3, c4, c5, cp from t1 where cp = 4; +insert into t1 (c2, c3, c4, c5, cp) + select c2, c3, c4, c5, cp from t1 where cp = 4; +insert into t1 (c2, c3, c4, c5, cp) + select c2, c3, c4, c5, cp from t1 where cp = 4; +insert into t1 (c2, c3, c4, c5, cp) + select c2, c3, c4, c5, cp from t1 where cp = 4; +insert into t1 (c2, c3, c4, c5, cp) + select c2, c3, c4, c5, cp from t1 where cp = 4; +insert into t1 (c2, c3, c4, c5, cp) + select c2, c3, c4, c5, cp from t1 where cp = 4; +insert into t1 (c2, c3, c4, c5, cp) + select c2, c3, c4, c5, cp from t1 where cp = 4; +insert into t1 (c2, c3, c4, c5, cp) + select c2, c3, c4, c5, cp from t1 where cp = 4; +insert into t1 (c2, c3, c4, c5, cp) + select c2, c3, c4, c5, cp from t1 where cp = 4; + +analyze table t1; + +explain + select * from t1 where (c2=1 and c3=1) or (c4=2 and c5=1); + +explain + select * from t1 + where (c2=1 and c3=1 and cp=1) or (c4=2 and c5=1 and cp=1); + +explain + select * from t1 + where ((c2=1 and c3=1) or (c4=2 and c5=1)) and cp=1; + +select * from t1 + where (c2=1 and c3=1 and cp=1) or (c4=2 and c5=1 and cp=1); + +select * from t1 + where ((c2=1 and c3=1) or (c4=2 and c5=1)) and cp=1; + +drop table t1; + +# +# Bug #23322: a bad range scan and a good index merge plan +# + +create table t1 ( + c1 int auto_increment primary key, + c2 char(20), + c3 char (20), + c4 int +); +alter table t1 add key k1 (c2); +alter table t1 add key k2 (c3); +alter table t1 add key k3 (c4); + +insert into t1 values(null, 'a', 'b', 0); +insert into t1 values(null, 'c', 'b', 0); +insert into t1 values(null, 'a', 'd', 0); +insert into t1 values(null, 'ccc', 'qqq', 0); + +insert into t1 (c2,c3) select c2,c3 from t1 where c2 != 'a'; +insert into t1 (c2,c3) select c2,c3 from t1 where c2 != 'a'; +insert into t1 (c2,c3) select c2,c3 from t1 where c2 != 'a'; +insert into t1 (c2,c3) select c2,c3 from t1 where c2 != 'a'; +insert into t1 (c2,c3) select c2,c3 from t1 where c2 != 'a'; +insert into t1 (c2,c3) select c2,c3 from t1 where c2 != 'a'; +insert into t1 (c2,c3) select c2,c3 from t1 where c2 != 'a'; + +insert into t1 (c2,c3,c4) select c2,c3,1 from t1 where c2 != 'a'; +insert into t1 (c2,c3,c4) select c2,c3,2 from t1 where c2 != 'a'; +insert into t1 (c2,c3,c4) select c2,c3,3 from t1 where c2 != 'a'; +insert into t1 (c2,c3,c4) select c2,c3,4 from t1 where c2 != 'a'; + +analyze table t1; + +select count(*) from t1 where (c2='e' OR c3='q'); +select count(*) from t1 where c4 != 0; + +explain + select distinct c1 from t1 where (c2='e' OR c3='q'); + +explain + select distinct c1 from t1 where (c4!= 0) AND (c2='e' OR c3='q'); + +drop table t1; + +# +# Bug #30151: a bad range scan and a good index merge plan +# + +create table t1 ( + id int unsigned auto_increment primary key, + c1 char(12), + c2 char(15), + c3 char(1) +); + +insert into t1 (c3) values ('1'), ('2'); + +insert into t1 (c3) select c3 from t1; +insert into t1 (c3) select c3 from t1; +insert into t1 (c3) select c3 from t1; +insert into t1 (c3) select c3 from t1; +insert into t1 (c3) select c3 from t1; +insert into t1 (c3) select c3 from t1; +insert into t1 (c3) select c3 from t1; +insert into t1 (c3) select c3 from t1; +insert into t1 (c3) select c3 from t1; +insert into t1 (c3) select c3 from t1; +insert into t1 (c3) select c3 from t1; +insert into t1 (c3) select c3 from t1; + +update t1 set c1=lpad(id+1000, 12, ' '), c2=lpad(id+10000, 15, ' '); + +alter table t1 add unique index (c1), add unique index (c2), add index (c3); + +analyze table t1; + +explain + select * from t1 where (c1=' 100000' or c2=' 2000000'); +explain + select * from t1 where (c1=' 100000' or c2=' 2000000') and c3='2'; + +select * from t1 where (c1=' 100000' or c2=' 2000000'); +select * from t1 where (c1=' 100000' or c2=' 2000000') and c3='2'; + +drop table t1; + +# +# Bug #637978: invalid index merge access plan causes to wrong results +# + +CREATE TABLE t1 ( + a smallint DEFAULT NULL, + pk int NOT NULL AUTO_INCREMENT PRIMARY KEY, + b varchar(10) DEFAULT NULL, + c varchar(64) DEFAULT NULL, + INDEX idx1 (a), + INDEX idx2 (b), + INDEX idx3 (c) +); +--disable_query_log +--disable_result_log +INSERT INTO t1 VALUES +(30371,99001,'dl','e'),(3,99002,'Ohio','t'),(9,99003,'Delaware','xb'), +(0,99004,'Pennsylvan','i'),(-199,99005,'y','d'),(0,99006,'with','Rhode Island'), +(3,99007,'km','qkmiimdxbdljsejtsfrvwlrgacinbmfuosflnenlpomkmvbig'), +(22860,99008,'ovqkmiimdx','uovqkmiimdxbdljsejtsfrvwlrgacinbmfuosflnenlpomkmvbig'), +(212,99009,'f','p'),(NULL,99010,'i','k'),(20426,99011,'Vermont','New York'), +(0,99012,'Oregon','w'),(31831,99013,'s','isrcijpuovqkmiimdxbdljsejtsfrvwl'), +(123,99014,'t','p'),(32767,99015,'q','Maine'), +(NULL,99016,'know','qqqpisrcijpuovqkmiimdxbdljsejtsfrvwlrgacinbmfuosflnenlpo'), +(1,99017,'going','North Carolina'),(-717,99018,'ad','Indiana'), +(32767,99019,'Maryland','aa'),(31280,99020,'Nebraska','Colorado'), +(0,99021,'q','Ohio'), +(5989,99022,'rovaadtqqq','lrovaadtqqqpisrcijpuovqkmiimdxbdljsejtsfrvwlrgacinb'), +(89,99023,'n','Pennsylvania'),(0,99024,'Florida','c'),(97,99025,'Maine','y'), +(149,99026,'xaemnl','Idaho'),(NULL,99027,'h','y'),(26276,99028,'going','New York'), +(242,99029,'bdhxaemnlr','sbdhxaemnlrovaadtqqqpisrcijpuovqkmiimdxb'), +(32767,99030,'if','a'),(26581,99031,'Arizona','q'),(45,99032,'ysazsbdhxa','f'), +(0,99033,'qv','s'),(NULL,99034,'Louisiana','lqvfysazsbdhxaemnlrovaadtqqqpisrc'), +(160,99035,'Connecticu','x'),(23241,99036,'lx','q'),(0,99037,'u','Colorado'), +(-19141,99038,'w','h'),(218,99039,'s','uo'),(4,99040,'Montana','Oklahoma'), +(97,99041,'r','ls'),(32767,99042,'q','v'),(7,99043,'mlsuownlnl','did'), +(NULL,99044,'ui','i'),(2,99045,'to','I\'ll'),(0,99046,'Nevada','g'), +(3251,99047,'y','New York'),(0,99048,'wyttuimlsu','you\'re'), +(7,99049,'he','South Carolina'),(32767,99050,'s','right'), +(172,99051,'Arizona','e'),(0,99052,'x','lxmvwyttuimlsuownlnlxklq'), +(NULL,99053,'f','wfjlxmvwyttuimlsuownlnlxklqvfysazs'),(44,99054,'s','n'), +(-17561,99055,'me','wm'),(88,99056,'y','my'),(7313,99057,'jx','New Hampshire'), +(63,99058,'zl','South Carolina'),(9,99059,'ma','Illinois'), +(6,99060,'lamazljxpg','like'),(17021,99061,'x','v'),(0,99062,'New Mexico','j'), +(179,99427,'fliq','because'), +(107,99063,'Virginia','Mississippi'), +(0,99064,'si','to'),(113,99065,'Illinois','Kansas'),(20808,99066,'tsi','d'), +(-15372,99067,'d','vdftsidjtvulamazljxpgiwmbnmwfjlxmvwyttuimlsuownlnl'), +(0,99068,'y','then'),(2,99069,'all','b'),(NULL,99070,'by','Wisconsin'), +(4,99071,'about','right'),(5,99072,'m','s'),(0,99073,'e','Pennsylvania'), +(-28284,99074,'x','f'),(1,99075,'Rhode Isla','Georgia'),(NULL,99076,'p','was'), +(168,99077,'Tennessee','Minnesota'),(18349,99078,'x','Rhode Island'), +(5,99079,'as','d'),(12217,99080,'c','i'),(0,99081,'rdvdxboydm','s'), +(19132,99082,'her','jerdvdxboydmpefbiesqbyyvdftsidjtvulamazljxpgiwmbn'), +(0,99083,'all','jhjerdvdxboydmpefbiesqbyyvdftsidjtvulamazljx'), +(32767,99084,'s','flj'),(-4947,99085,'something','Vermont'), +(0,99086,'cjfljhjerd','Washington'); +--enable_query_log +--enable_result_log + +SELECT COUNT(*) FROM t1 IGNORE INDEX (idx2,idx3) + WHERE c = 'i' OR b IN ( 'Arkansas' , 'd' , 'pdib' , 'can' ) OR + (pk BETWEEN 120 AND 79 + 255 OR a IN ( 4 , 179 , 1 ) ) AND a > 8 ; +SELECT COUNT(*) FROM t1 + WHERE c = 'i' OR b IN ( 'Arkansas' , 'd' , 'pdib' , 'can' ) OR + (pk BETWEEN 120 AND 79 + 255 OR a IN ( 4 , 179 , 1 ) ) AND a > 8 ; +EXPLAIN +SELECT COUNT(*) FROM t1 + WHERE c = 'i' OR b IN ( 'Arkansas' , 'd' , 'pdib' , 'can' ) OR + (pk BETWEEN 120 AND 79 + 255 OR a IN ( 4 , 179 , 1 ) ) AND a > 8 ; + +DROP TABLE t1; + +# +# Bug #684117: ORing of two index merge that caused a crash +# + +CREATE TABLE t1 ( + f1 int, f2 int, f3 int, f4 int, f5 int, + PRIMARY KEY (f4), KEY (f1), KEY (f2), KEY (f3) +) ; +INSERT INTO t1 VALUES (0,0,NULL,9,5), (0,0,1,9425,NULL); + +SELECT f5 FROM t1 + WHERE f2 != 1 OR f1 IS NULL OR f4 = 4 OR + f2 AND (f4 BETWEEN 6 AND 255 OR f3 IS NULL); + +DROP TABLE t1; + +# +# Bug #685952: An invalid index merge union plan +# + +CREATE TABLE t1 ( + f1 int, f2 int, f3 int, f4 int, + PRIMARY KEY (f1), KEY (f3), KEY (f4) +); + +INSERT INTO t1 VALUES (9,0,2,6), (9930,0,0,NULL); + +SET SESSION optimizer_switch='index_merge_intersection=off'; +SET SESSION optimizer_switch='index_merge_sort_union=off'; + +SET SESSION optimizer_switch='index_merge_union=off'; + +EXPLAIN +SELECT * FROM t1 FORCE KEY (PRIMARY,f3,f4) + WHERE ( f3 = 1 OR f1 = 7 ) AND f1 < 10 + OR f3 BETWEEN 2 AND 2 AND ( f3 = 1 OR f4 != 1 ); + +SELECT * FROM t1 FORCE KEY (PRIMARY,f3,f4) + WHERE ( f3 = 1 OR f1 = 7 ) AND f1 < 10 + OR f3 BETWEEN 2 AND 2 AND ( f3 = 1 OR f4 != 1 ); + +SET SESSION optimizer_switch='index_merge_union=on'; + +EXPLAIN +SELECT * FROM t1 FORCE KEY (PRIMARY,f3,f4) + WHERE ( f3 = 1 OR f1 = 7 ) AND f1 < 10 + OR f3 BETWEEN 2 AND 2 AND ( f3 = 1 OR f4 != 1 ); + +SELECT * FROM t1 FORCE KEY (PRIMARY,f3,f4) + WHERE ( f3 = 1 OR f1 = 7 ) AND f1 < 10 + OR f3 BETWEEN 2 AND 2 AND ( f3 = 1 OR f4 != 1 ); + + +INSERT INTO t1 VALUES + (93,0,3,6), (9933,0,3,3), (94,0,4,6), (9934,0,4,4), + (95,0,5,6), (9935,0,5,5), (96,0,6,6), (9936,0,6,6), + (97,0,7,6), (9937,0,7,7), (98,0,8,6), (9938,0,8,8), + (99,0,9,6), (9939,0,9,9); + +SET SESSION optimizer_switch='index_merge_union=off'; + +EXPLAIN +SELECT * FROM t1 FORCE KEY (PRIMARY,f3,f4) + WHERE ( f3 = 1 OR f1 = 7 ) AND f1 < 10 + OR f3 BETWEEN 2 AND 2 AND ( f3 = 1 OR f4 != 1 ); + +SELECT * FROM t1 FORCE KEY (PRIMARY,f3,f4) + WHERE ( f3 = 1 OR f1 = 7 ) AND f1 < 10 + OR f3 BETWEEN 2 AND 2 AND ( f3 = 1 OR f4 != 1 ); + +SET SESSION optimizer_switch='index_merge_union=on'; + +EXPLAIN +SELECT * FROM t1 FORCE KEY (PRIMARY,f3,f4) + WHERE ( f3 = 1 OR f1 = 7 ) AND f1 < 10 + OR f3 BETWEEN 2 AND 2 AND ( f3 = 1 OR f4 != 1 ); + +SELECT * FROM t1 FORCE KEY (PRIMARY,f3,f4) + WHERE ( f3 = 1 OR f1 = 7 ) AND f1 < 10 + OR f3 BETWEEN 2 AND 2 AND ( f3 = 1 OR f4 != 1 ); + +SET SESSION optimizer_switch=DEFAULT; + +DROP TABLE t1; + +# +# Bug #752353: valgrind complain on a jump depending +# on an uninitialised value +# + +CREATE TABLE t1 (f1 int) ; +INSERT INTO t1 VALUES (0), (0); + +CREATE TABLE t2 (f1 int, f2 int, f3 int, f4 int, INDEX idx (f3,f2)) ; +INSERT INTO t2 VALUES (5,6,0,0), (0,4,0,0); + +CREATE TABLE t3 (f1 int, f2 int, INDEX idx1 (f2,f1) , INDEX idx2 (f1)) ; +INSERT INTO t3 VALUES (6,0),( 4,0); + +SELECT * FROM t1,t2,t3 + WHERE (t2.f3 = 1 OR t3.f1=t2.f1) AND t3.f1 <> t2.f2 AND t3.f2 = t2.f4; + +DROP TABLE t1,t2,t3; + +#the following command must be the last one in the file +set session optimizer_switch='index_merge_sort_intersection=default'; diff --git a/mysql-test/t/range_vs_index_merge_innodb.test b/mysql-test/t/range_vs_index_merge_innodb.test new file mode 100755 index 00000000000..e85cd044ece --- /dev/null +++ b/mysql-test/t/range_vs_index_merge_innodb.test @@ -0,0 +1,7 @@ +--source include/have_innodb.inc + +SET SESSION STORAGE_ENGINE='InnoDB'; + +--source t/range_vs_index_merge.test + +SET SESSION STORAGE_ENGINE=DEFAULT; diff --git a/mysql-test/t/select.test b/mysql-test/t/select.test index 534f39d631b..e9ae69826e5 100644 --- a/mysql-test/t/select.test +++ b/mysql-test/t/select.test @@ -3528,6 +3528,7 @@ DROP VIEW v1; select str_to_date('2007-10-09','%Y-%m-%d') between '2007/10/01 00:00:00 GMT' and '2007/10/20 00:00:00 GMT'; select str_to_date('2007-10-09','%Y-%m-%d') > '2007/10/01 00:00:00 GMT-6'; +select str_to_date('2007-10-09','%Y-%m-%d') <= '2007/10/20 00:00:00 GMT-6'; select str_to_date('2007-10-09','%Y-%m-%d') <= '2007/10/2000:00:00 GMT-6'; # We have all we need -- and trailing garbage: @@ -3577,10 +3578,12 @@ select str_to_date('1','%Y-%m-%d') = '1'; select str_to_date('1','%Y-%m-%d') = '1'; select str_to_date('','%Y-%m-%d') = ''; -# these three should work! -select str_to_date('1000-01-01','%Y-%m-%d') between '0000-00-00' and NULL; -select str_to_date('1000-01-01','%Y-%m-%d') between NULL and '2000-00-00'; -select str_to_date('1000-01-01','%Y-%m-%d') between NULL and NULL; +select str_to_date('2000-01-01','%Y-%m-%d') between '1000-01-01' and '2001-01-01'; +select str_to_date('2000-01-01','%Y-%m-%d') between '1000-01-01' and NULL; +select str_to_date('2000-01-01','%Y-%m-%d') between NULL and '2001-01-01'; +select str_to_date('2000-01-01','%Y-%m-%d') between '2001-01-01' and NULL; +select str_to_date('2000-01-01','%Y-%m-%d') between NULL and '1000-01-01'; +select str_to_date('2000-01-01','%Y-%m-%d') between NULL and NULL; # # Bug #30666: Incorrect order when using range conditions on 2 tables or more @@ -3908,9 +3911,9 @@ DROP TABLE t1; # Field_varstring::store # -CREATE TABLE A (date_key date); +CREATE TABLE t1 (date_key date); -CREATE TABLE C ( +CREATE TABLE t2 ( pk int, int_nokey int, int_key int, @@ -3919,20 +3922,20 @@ CREATE TABLE C ( varchar_key varchar(1) ); -INSERT INTO C VALUES +INSERT INTO t2 VALUES (1,1,1,'0000-00-00',NULL,NULL), (1,1,1,'0000-00-00',NULL,NULL); -SELECT 1 FROM C WHERE pk > ANY (SELECT 1 FROM C); +SELECT 1 FROM t2 WHERE pk > ANY (SELECT 1 FROM t2); -SELECT COUNT(DISTINCT 1) FROM C - WHERE date_key = (SELECT 1 FROM A WHERE C.date_key IS NULL) GROUP BY pk; -SELECT date_nokey FROM C - WHERE int_key IN (SELECT 1 FROM A) +SELECT COUNT(DISTINCT 1) FROM t2 + WHERE date_key = (SELECT 1 FROM t1 WHERE t2.date_key IS NULL) GROUP BY pk; +SELECT date_nokey FROM t2 + WHERE int_key IN (SELECT 1 FROM t1) HAVING date_nokey = '10:41:7' ORDER BY date_key; -DROP TABLE A,C; +DROP TABLE t1,t2; # # Bug #42957: no results from @@ -4135,6 +4138,129 @@ EXPLAIN SELECT 1 FROM t1 ORDER BY a COLLATE latin1_german2_ci; SELECT 1 FROM t1 ORDER BY a COLLATE latin1_german2_ci; DROP TABLE t1; +--echo # +--echo # Bug #702310: usage of 2 join buffers after ref access to an empty table +--echo # + +CREATE TABLE t1 (f1 int) ; +INSERT INTO t1 VALUES (9); + +CREATE TABLE t2 (f1 int); +INSERT INTO t2 VALUES (3),(7),(18); +INSERT INTO t2 VALUES (3),(7),(18); +INSERT INTO t2 VALUES (3),(7),(18); +INSERT INTO t2 VALUES (3),(7),(18); + +CREATE TABLE t3 (f1 int); +INSERT INTO t3 VALUES (17); + +CREATE TABLE t4 (f1 int PRIMARY KEY, f2 varchar(1024)) ; + +CREATE TABLE t5 (f1 int) ; +INSERT INTO t5 VALUES (20),(5); + +CREATE TABLE t6(f1 int); +INSERT INTO t6 VALUES (9),(7); + +SET SESSION join_buffer_size = 2048; + +EXPLAIN +SELECT STRAIGHT_JOIN * FROM t2, (t1 LEFT JOIN (t3,t4) ON t1.f1 = t4.f1), t5, t6; +SELECT STRAIGHT_JOIN * FROM t2, (t1 LEFT JOIN (t3,t4) ON t1.f1 = t4.f1), t5, t6; + +SET SESSION join_buffer_size = DEFAULT; + +DROP TABLE t1,t2,t3,t4,t5,t6; + +--echo # +--echo # Bug #698882: best equality substitution not applied to ref +--echo # + +CREATE TABLE t1 (a1 int NOT NULL, b1 char(10), INDEX idx (a1)); +CREATE TABLE t2 (a2 int NOT NULL, b2 char(10), INDEX idx (a2)); +CREATE TABLE t3 (a3 int NOT NULL, b3 char(10), INDEX idx (a3)); +INSERT INTO t1 VALUES (2,'xx'), (1,'xxx'), (11,'xxxxxxx'); +INSERT INTO t2 VALUES + (7,'yyyy'), (2,'y'), (3,'yyy'), (1,'yy'), (1,'yyyyy'), + (3,'yy'), (1,'y'), (4,'yyy'), (7,'y'), (4,'yyyyy'), (7,'yyy'), + (7,'yyyy'), (2,'yy'), (3,'yyy'), (1,'yyyyyyyy'), (1,'yyyyy'), + (3,'yy'), (1,'yyy'), (4,'yyy'), (7,'y'), (4,'yyyyy'), (7,'yyy'); +INSERT INTO t3 VALUES + (9,'zzzzzzz'), (2,'zzzzz'), (1,'z'), (9,'zz'), (1,'zz'), (5,'zzzzzzz'), + (4,'zz'), (3,'z'), (5,'zzzzzz'), (3,'zz'), (4,'zzzz'), (3,'z'), + (9,'zzzzzzzz'), (2,'zz'), (1,'zz'), (9,'zzz'), (1,'zzz'), (5,'zzzzzzzz'), + (4,'zzz'), (3,'zz'), (5,'zzzzzzz'), (3,'zzz'), (4,'zzzzz'), (3,'zz'), + (9,'zzzzzz'), (2,'zzzz'), (1,'zzz'), (9,'z'), (1,'z'), (5,'zzzzzz'), + (4,'z'), (3,'zzz'), (5,'zzzzz'), (3,'z'), (4,'zzz'), (3,'zzzz'), + (9,'zzzzz'), (2,'zzz'), (1,'zzzz'), (9,'zzz'), (1,'zzzz'), (5,'zzzzz'), + (4,'zzz'), (3,'zzzz'), (5,'zzzz'), (3,'zzz'), (4,'zz'), (3,'zzzzz'); + +set @tmp= @@optimizer_switch; +SET SESSION optimizer_switch='index_condition_pushdown=off'; + +EXPLAIN SELECT * from t1,t2,t3 WHERE t3.a3=t1.a1 AND t2.a2=t1.a1; +EXPLAIN SELECT * FROM t1,t2,t3 WHERE t2.a2=t1.a1 AND t3.a3=t1.a1; +EXPLAIN SELECT * FROM t1,t2,t3 WHERE t2.a2=t1.a1 AND t3.a3=t2.a2; + +--sorted_result +SELECT * from t1,t2,t3 + WHERE t3.a3=t1.a1 AND t2.a2=t1.a1 AND + LENGTH(CONCAT(CONCAT(t1.b1,t2.b2),t3.b3)) <= 7; +--sorted_result +SELECT * FROM t1,t2,t3 + WHERE t2.a2=t1.a1 AND t3.a3=t1.a1 AND + LENGTH(CONCAT(CONCAT(t1.b1,t2.b2),t3.b3)) <= 7; +--sorted_result +SELECT * FROM t1,t2,t3 + WHERE t2.a2=t1.a1 AND t3.a3=t2.a2 AND + LENGTH(CONCAT(CONCAT(t1.b1,t2.b2),t3.b3)) <= 7; + +SET SESSION optimizer_switch=@tmp; + +DROP TABLE t1,t2,t3; + + +--echo # +--echo # Bug #707555: crash with equality substitution in ref +--echo # + +CREATE TABLE t1 (f11 int, f12 int, PRIMARY KEY (f11), KEY (f12)) ; +INSERT INTO t1 VALUES (1,NULL), (8,NULL); + +CREATE TABLE t2 (f21 int, f22 int, f23 int, KEY (f22)) ; +INSERT INTO t2 VALUES (1,NULL,3), (2,7,8); + +CREATE TABLE t3 (f31 int, f32 int(11), PRIMARY KEY (f31), KEY (f32)) ; +INSERT INTO t3 VALUES (1,494862336); + +CREATE TABLE t4 (f41 int, f42 int, PRIMARY KEY (f41), KEY (f42)) ; +INSERT INTO t4 VALUES (1,NULL), (8,NULL); + +CREATE TABLE t5 (f51 int, PRIMARY KEY (f51)) ; +INSERT IGNORE INTO t5 VALUES (100); + +CREATE TABLE t6 (f61 int, f62 int, KEY (f61)) ; +INSERT INTO t6 VALUES (NULL,1), (3,10); + +CREATE TABLE t7 (f71 int, f72 int, KEY (f72)) ; +INSERT INTO t7 VALUES (1,NULL), (2,7); + +EXPLAIN +SELECT t2.f23 FROM + (t1 LEFT JOIN (t2 JOIN t3 ON t2.f22=t3.f32) ON t1.f11=t3.f31) + LEFT JOIN + (((t4 JOIN t5 ON t4.f42=t5.f51) LEFT JOIN t6 ON t6.f62>0) JOIN t7 ON t6.f61>0) + ON t3.f31 = t6.f61 + WHERE t7.f71>0; + +SELECT t2.f23 FROM + (t1 LEFT JOIN (t2 JOIN t3 ON t2.f22=t3.f32) ON t1.f11=t3.f31) + LEFT JOIN + (((t4 JOIN t5 ON t4.f42=t5.f51) LEFT JOIN t6 ON t6.f62>0) JOIN t7 ON t6.f61>0) + ON t3.f31 = t6.f61 + WHERE t7.f71>0; + +DROP TABLE t1,t2,t3,t4,t5,t6,t7; --echo # @@ -4208,6 +4334,19 @@ DROP TABLE t1,t2,t_empty; --echo End of 5.1 tests +--echo # +--echo # BUG#776274: substitution of a single row table +--echo # + +CREATE TABLE t1 (a int NOT NULL , b int); +INSERT INTO t1 VALUES (2,2); + +SELECT * FROM t1 WHERE a = b; +EXPLAIN +SELECT * FROM t1 WHERE a = b; + +DROP TABLE t1; + --echo # --echo # Bug#54515: Crash in opt_range.cc::get_best_group_min_max on --echo # SELECT from VIEW with GROUP BY @@ -4249,3 +4388,4 @@ GROUP BY t2.a ORDER BY t1.a; DROP TABLE t1; --echo # End of test BUG#57203 + diff --git a/mysql-test/t/select_debug.test b/mysql-test/t/select_debug.test new file mode 100644 index 00000000000..16e8425efc4 --- /dev/null +++ b/mysql-test/t/select_debug.test @@ -0,0 +1,19 @@ +--source include/have_debug.inc + +--echo # +--echo # Bug #725050: print keyuse info when hash join is used +--echo # + +create table t1 (a int, b int); +insert into t1 values (2,2), (1,1); +create table t2 (a int); +insert into t2 values (2), (3); + +set session join_cache_level=3; +set @@debug = 'd:t:O,/tmp/trace.out'; + +explain select t1.b from t1,t2 where t1.b=t2.a; +select t1.b from t1,t2 where t1.b=t2.a; + +set session join_cache_level=default; +drop table t1,t2; diff --git a/mysql-test/t/select_jcl6.test b/mysql-test/t/select_jcl6.test index 3247ab6e343..295efa632db 100644 --- a/mysql-test/t/select_jcl6.test +++ b/mysql-test/t/select_jcl6.test @@ -2,6 +2,12 @@ # Run select.test with BKA enabled # +set @save_optimizer_switch_jcl6=@@optimizer_switch; +set @@optimizer_switch='optimize_join_buffer_size=on'; +set @@optimizer_switch='semijoin_with_cache=on'; +set @@optimizer_switch='outer_join_with_cache=on'; +set @@optimizer_switch='mrr=on,mrr_sort_keys=on,index_condition_pushdown=on'; + set join_cache_level=6; show variables like 'join_cache_level'; @@ -9,3 +15,5 @@ show variables like 'join_cache_level'; set join_cache_level=default; show variables like 'join_cache_level'; + +set @@optimizer_switch=@save_optimizer_switch_jcl6; diff --git a/mysql-test/t/signal.test b/mysql-test/t/signal.test index 4c8e6159371..af0aa17f232 100644 --- a/mysql-test/t/signal.test +++ b/mysql-test/t/signal.test @@ -738,9 +738,12 @@ SIGNAL SQLSTATE 'HY000' SET MYSQL_ERRNO = 0; --error ER_PARSE_ERROR SIGNAL SQLSTATE 'HY000' SET MYSQL_ERRNO = -1; ---error 65535 +--error ER_WRONG_VALUE_FOR_VAR SIGNAL SQLSTATE 'HY000' SET MYSQL_ERRNO = 65535; +--error 65534 +SIGNAL SQLSTATE 'HY000' SET MYSQL_ERRNO = 65534; + --echo # --echo # RESIGNAL can also appear in a query --echo # @@ -767,10 +770,10 @@ create procedure test_signal() begin # max range DECLARE foo CONDITION FOR SQLSTATE 'AABBB'; - SIGNAL foo SET MYSQL_ERRNO = 65535; + SIGNAL foo SET MYSQL_ERRNO = 65534; end $$ ---error 65535 +--error 65534 call test_signal() $$ drop procedure test_signal $$ @@ -1340,7 +1343,7 @@ begin COLUMN_NAME = iii, CURSOR_NAME = jjj, MESSAGE_TEXT = kkk, - MYSQL_ERRNO = 65535; + MYSQL_ERRNO = 65534; end $$ call test_signal() $$ diff --git a/mysql-test/t/sp.test b/mysql-test/t/sp.test index eea16d5d174..2b83e9a10dc 100644 --- a/mysql-test/t/sp.test +++ b/mysql-test/t/sp.test @@ -3749,15 +3749,25 @@ begin return @x; end| -set @qcs1 = @@query_cache_size| -set global query_cache_size = 102400| +--disable_query_log +--echo # Set query cache size, if we have query cache +if (`select @@have_query_cache='YES'`) { + set @qcs1 = @@query_cache_size| + set global query_cache_size = 102400| +} +--enable_query_log set @x = 1| insert into t1 values ("qc", 42)| select bug9902() from t1| select bug9902() from t1| select @x| -set global query_cache_size = @qcs1| +--echo # Restore the old query cache size +--disable_query_log +if (`select @@have_query_cache='YES'`) { + set global query_cache_size = @qcs1| +} +--enable_query_log delete from t1| drop function bug9902| diff --git a/mysql-test/t/status.test b/mysql-test/t/status.test index 26c7a89bf5c..76769e78d90 100644 --- a/mysql-test/t/status.test +++ b/mysql-test/t/status.test @@ -354,6 +354,23 @@ DROP FUNCTION f1; # End of 5.1 tests +# +# Test of internal temporary table status variables +# + +flush status; +create table t1 (a int not null auto_increment primary key, g int, b blob); +insert into t1 (g,b) values (1,'a'), (2, 'b'), (3, 'b'), (1, 'c'); +select * from t1; +select b, count(*) from t1 group by b; +select g, count(*) from t1 group by g; +show status like 'Row%'; +show status like 'Handler%'; +show status like '%tmp%'; +drop table t1; + +# End of 5.3 tests + # Restore global concurrent_insert value. Keep in the end of the test file. --connection default set @@global.concurrent_insert= @old_concurrent_insert; diff --git a/mysql-test/t/status_user.test b/mysql-test/t/status_user.test index 8b017767e37..9a51d0e1020 100644 --- a/mysql-test/t/status_user.test +++ b/mysql-test/t/status_user.test @@ -85,5 +85,25 @@ select connected_time <> 0, busy_time <> 0, bytes_received <> 0, bytes_sent <> 0, binlog_bytes_written <> 0 from information_schema.client_statistics; +# +# Test of in transaction +# + +create table t1 (a int) engine=innodb; +select @@in_transaction; +begin; +select @@in_transaction; +insert into t1 values (1); +select @@in_transaction; +commit; +select @@in_transaction; +set @@autocommit=0; +select @@in_transaction; +insert into t1 values (2); +select @@in_transaction; +set @@autocommit=1; +select @@in_transaction; +drop table t1; + # Cleanup set @@global.general_log=@save_general_log; diff --git a/mysql-test/t/strict.test b/mysql-test/t/strict.test index fc522a69a3c..f6080de6c2c 100644 --- a/mysql-test/t/strict.test +++ b/mysql-test/t/strict.test @@ -367,6 +367,8 @@ INSERT INTO t1 (col1) VALUES(CONVERT('0000-10-31' , DATE)); INSERT INTO t1 (col1) VALUES(CONVERT('2004-10-0' , DATE)); --error 1292 INSERT INTO t1 (col1) VALUES(CONVERT('2004-0-10' , DATE)); +--error 1292 +INSERT INTO t1 (col1) VALUES('2004-0-10'); # deactivated because of Bug#8294 # Bug#8294 Traditional: Misleading error message for invalid CAST to DATE diff --git a/mysql-test/t/subselect.test b/mysql-test/t/subselect.test index 9fdedd3cdec..7444af790e5 100644 --- a/mysql-test/t/subselect.test +++ b/mysql-test/t/subselect.test @@ -12,8 +12,10 @@ drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t11,t12; drop view if exists v2; --enable_warnings -set @save_optimizer_switch=@@optimizer_switch; -set @@optimizer_switch="partial_match_rowid_merge=off,partial_match_table_scan=off"; +set @subselect_tmp=@@optimizer_switch; +set @@optimizer_switch=ifnull(@optimizer_switch_for_subselect_test, + "semijoin=on,firstmatch=on,loosescan=on,partial_match_rowid_merge=off,partial_match_table_scan=off"); +set optimizer_switch='mrr=on,mrr_sort_keys=on,index_condition_pushdown=on'; select (select 2); explain extended select (select 2); @@ -260,6 +262,7 @@ INSERT INTO t1 (numeropost,maxnumrep) VALUES (1,0),(2,1); select numeropost as a FROM t1 GROUP BY (SELECT 1 FROM t1 HAVING a=1); -- error ER_SUBQUERY_NO_1_ROW select numeropost as a FROM t1 ORDER BY (SELECT 1 FROM t1 HAVING a=1); +show warnings; drop table t1; create table t1 (a int); @@ -322,7 +325,7 @@ insert into t2 values (1, 21),(2, 12),(3, 23); select * from t1; select * from t1 where b = (select b from t2 where t1.a = t2.a); -- error ER_UPDATE_TABLE_USED -delete from t1 where b = (select b from t1); +delete from t1 where b in (select b from t1); -- error ER_SUBQUERY_NO_1_ROW delete from t1 where b = (select b from t2); delete from t1 where b = (select b from t2 where t1.a = t2.a); @@ -2078,7 +2081,7 @@ SELECT b, MAX(c) FROM t2 GROUP BY b, (SELECT c FROM t2 WHERE b > 2); --error ER_SUBQUERY_NO_1_ROW SELECT b, MAX(c) FROM t2 GROUP BY b, (SELECT c FROM t2 WHERE b > 1); - +--sorted_result SELECT a FROM t1 GROUP BY a HAVING IFNULL((SELECT b FROM t2 WHERE b > 2), (SELECT c FROM t2 WHERE c=a AND b > 2 ORDER BY b)) > 3; @@ -2086,7 +2089,7 @@ SELECT a FROM t1 GROUP BY a SELECT a FROM t1 GROUP BY a HAVING IFNULL((SELECT b FROM t2 WHERE b > 1), (SELECT c FROM t2 WHERE c=a AND b > 2 ORDER BY b)) > 3; - +--sorted_result SELECT a FROM t1 GROUP BY a HAVING IFNULL((SELECT b FROM t2 WHERE b > 4), (SELECT c FROM t2 WHERE c=a AND b > 2 ORDER BY b)) > 3; @@ -2094,7 +2097,7 @@ SELECT a FROM t1 GROUP BY a SELECT a FROM t1 GROUP BY a HAVING IFNULL((SELECT b FROM t2 WHERE b > 4), (SELECT c FROM t2 WHERE c=a AND b > 1 ORDER BY b)) > 3; - +--sorted_result SELECT a FROM t1 ORDER BY IFNULL((SELECT b FROM t2 WHERE b > 2), (SELECT c FROM t2 WHERE c=a AND b > 2 ORDER BY b)); @@ -2102,7 +2105,7 @@ SELECT a FROM t1 SELECT a FROM t1 ORDER BY IFNULL((SELECT b FROM t2 WHERE b > 1), (SELECT c FROM t2 WHERE c=a AND b > 1 ORDER BY b)); - +--sorted_result SELECT a FROM t1 ORDER BY IFNULL((SELECT b FROM t2 WHERE b > 4), (SELECT c FROM t2 WHERE c=a AND b > 2 ORDER BY b)); @@ -4289,7 +4292,7 @@ SELECT 1 FROM t1 GROUP BY (SELECT LAST_INSERT_ID() FROM t1 ORDER BY MIN(a) ASC LIMIT 1); DROP TABLE t1; -set @@optimizer_switch=@save_optimizer_switch; +#Seems to be not needed here: set @@optimizer_switch=@subselect_tmp; --echo # --echo # Bug #49512 : subquery with aggregate function crash --echo # subselect_single_select_engine::exec() @@ -4479,6 +4482,45 @@ SELECT * FROM t1 DROP TABLE t1,t1s,t2s; +--echo # LP BUG#675248 - select->prep_where references on freed memory + +CREATE TABLE t1 (a int, b int); +insert into t1 values (1,1),(0,0); + +CREATE TABLE t2 (c int); +insert into t2 values (1),(2); + +prepare stmt1 from "select sum(a),(select sum(c) from t2 where table1.b) as sub +from t1 as table1 group by sub"; + +execute stmt1; + +deallocate prepare stmt1; + +prepare stmt1 from "select sum(a),(select sum(c) from t2 having table1.b) as sub +from t1 as table1"; + +execute stmt1; + +deallocate prepare stmt1; + +drop table t1,t2; + +--echo # +--echo # Bug LP#693935/#58727: Assertion failure with +--echo # a single row subquery returning more than one row +--echo # + +create table t1 (a char(1) charset utf8); +insert into t1 values ('a'), ('b'); +create table t2 (a binary(1)); +insert into t2 values ('x'), ('y'); + +-- error ER_SUBQUERY_NO_1_ROW +select * from t2 where a=(select a from t1) and a='x'; + +drop table t1,t2; + --echo End of 5.1 tests --echo # @@ -4538,3 +4580,251 @@ select * from t3 where k in (select j from v2); drop table t1,t2,t3; drop view v2; + +--echo # +--echo # Bug#52068: Optimizer generates invalid semijoin materialization plan +--echo # +--disable_warnings +drop table if exists ot1, ot2, it1, it2; +--enable_warnings +CREATE TABLE ot1(a INTEGER); +INSERT INTO ot1 VALUES(5), (8); +CREATE TABLE it2(a INTEGER); +INSERT INTO it2 VALUES(9), (5), (1), (8); +CREATE TABLE it3(a INTEGER); +INSERT INTO it3 VALUES(7), (1), (0), (5), (1), (4); +CREATE TABLE ot4(a INTEGER); +INSERT INTO ot4 VALUES(1), (3), (5), (7), (9), (7), (3), (1); + +let $query= +SELECT * FROM ot1,ot4 +WHERE (ot1.a,ot4.a) IN (SELECT it2.a,it3.a + FROM it2,it3); + +eval $query; +eval explain $query; + +DROP TABLE IF EXISTS ot1, ot4, it2, it3; + + +--echo # +--echo # Bug#729039: NULL keys used to evaluate subquery +--echo # + +CREATE TABLE t1 (a int) ; +INSERT INTO t1 VALUES (NULL), (1), (NULL), (2); + +CREATE TABLE t2 (a int, INDEX idx(a)) ; +INSERT INTO t2 VALUES (NULL), (1), (NULL); + +SELECT * FROM t1 + WHERE EXISTS (SELECT a FROM t2 USE INDEX () WHERE t2.a = t1.a); +EXPLAIN +SELECT * FROM t1 + WHERE EXISTS (SELECT a FROM t2 USE INDEX() WHERE t2.a = t1.a); + +SELECT * FROM t1 + WHERE EXISTS (SELECT a FROM t2 WHERE t2.a = t1.a); +EXPLAIN +SELECT * FROM t1 + WHERE EXISTS (SELECT a FROM t2 WHERE t2.a = t1.a); + +DROP TABLE t1,t2; + +--echo # +--echo # BUG#752992: Wrong results for a subquery with 'semijoin=on' +--echo # +CREATE TABLE t1 (pk INTEGER PRIMARY KEY, i INTEGER NOT NULL); +INSERT INTO t1 VALUES (11,0); +INSERT INTO t1 VALUES (12,5); +INSERT INTO t1 VALUES (15,0); +CREATE TABLE t2 (pk INTEGER PRIMARY KEY, i INTEGER NOT NULL); +INSERT INTO t2 VALUES (11,1); +INSERT INTO t2 VALUES (12,2); +INSERT INTO t2 VALUES (15,4); + +EXPLAIN SELECT * FROM t1 WHERE pk IN (SELECT it.pk FROM t2 JOIN t2 AS it ON 1); +SELECT * FROM t1 WHERE pk IN (SELECT it.pk FROM t2 JOIN t2 AS it ON 1); + +DROP table t1,t2; + +--echo # +--echo # Bug#751350: crash with pushed condition for outer references when +--echo # there should be none of such conditions +--echo # + +CREATE TABLE t1 (a int, b int) ; +INSERT INTO t1 VALUES (0,0),(0,0); + +EXPLAIN +SELECT b FROM t1 + WHERE ('0') IN ( SELECT a FROM t1 GROUP BY a ) + GROUP BY b; + +SELECT b FROM t1 + WHERE ('0') IN ( SELECT a FROM t1 GROUP BY a ) + GROUP BY b; + +DROP TABLE t1; + +--echo # +--echo # Bug #11765713 58705: +--echo # OPTIMIZER LET ENGINE DEPEND ON UNINITIALIZED VALUES +--echo # CREATED BY OPT_SUM_QUERY +--echo # + +CREATE TABLE t1(a INT NOT NULL, KEY (a)); +INSERT INTO t1 VALUES (0), (1); + +--error ER_SUBQUERY_NO_1_ROW +SELECT 1 as foo FROM t1 WHERE a < SOME + (SELECT a FROM t1 WHERE a <=> + (SELECT a FROM t1) + ); + +SELECT 1 as foo FROM t1 WHERE a < SOME + (SELECT a FROM t1 WHERE a <=> + (SELECT a FROM t1 where a is null) + ); + +DROP TABLE t1; + +--echo # +--echo # BUG#779885: Crash in eliminate_item_equal with materialization=on in +--echo # maria-5.3 +--echo # + +CREATE TABLE t1 ( f1 int ); +INSERT INTO t1 VALUES (19), (20); + +CREATE TABLE t2 ( f10 varchar(32) ); +INSERT INTO t2 VALUES ('c'),('d'); + +CREATE TABLE t3 ( f10 varchar(32) ); +INSERT INTO t3 VALUES ('a'),('b'); + +SELECT * +FROM t1 +WHERE +( 't' ) IN ( + SELECT t3.f10 + FROM t3 + JOIN t2 + ON t2.f10 = t3.f10 +); +DROP TABLE t1,t2,t3; + +--echo # +--echo # Fix of LP BUG#780386 (NULL left part with empty ALL subquery). +--echo # +CREATE TABLE t1 ( f11 int) ; +INSERT IGNORE INTO t1 VALUES (0),(0); + +CREATE TABLE t2 ( f3 int, f10 int, KEY (f10,f3)) ; +INSERT IGNORE INTO t2 VALUES (NULL,NULL),(5,0); + +DROP TABLE IF EXISTS t3; +CREATE TABLE t3 ( f3 int) ; +INSERT INTO t3 VALUES (0),(0); + +SELECT a1.f3 AS r FROM t2 AS a1 , t1 WHERE a1.f3 < ALL ( SELECT f3 FROM t3 WHERE f3 = 1 ) ; +DROP TABLE t1, t2, t3; + +--echo End of 5.3 tests + +--echo End of 5.5 tests. + +--echo # +--echo # Bug#12763207 - ASSERT IN SUBSELECT::SINGLE_VALUE_TRANSFORMER +--echo # + +CREATE TABLE t1(a1 int); +INSERT INTO t1 VALUES (1),(2); + +CREATE TABLE t2(a1 int); +INSERT INTO t2 VALUES (3); + +SELECT @@session.sql_mode INTO @old_sql_mode; +SET SESSION sql_mode='ONLY_FULL_GROUP_BY'; + +## All these are subject to the transformation +## '1 < some (...)' => '1 < max(...)' +SELECT 1 FROM t1 WHERE 1 < SOME (SELECT 2 FROM t2); +SELECT 1 FROM t1 WHERE 1 < SOME (SELECT 2.0 FROM t2); +SELECT 1 FROM t1 WHERE 1 < SOME (SELECT 'a' FROM t2); +SELECT 1 FROM t1 WHERE 1 < SOME (SELECT a1 FROM t2); + +SET SESSION sql_mode=@old_sql_mode; + +DROP TABLE t1, t2; + +--echo # +--echo # BUG#50257: Missing info in REF column of the EXPLAIN +--echo # lines for subselects +--echo # + +CREATE TABLE t1 (a INT, b INT, INDEX (a)); +INSERT INTO t1 VALUES (3, 10), (2, 20), (7, 10), (5, 20); + +--echo +EXPLAIN SELECT * FROM (SELECT * FROM t1 WHERE a=7) t; +--echo +EXPLAIN SELECT * FROM t1 WHERE EXISTS (SELECT * FROM t1 WHERE a=7); + +--echo +DROP TABLE t1; + +--echo # +--echo # Bug 11765699 - 58690: !TABLE || (!TABLE->READ_SET || +--echo # BITMAP_IS_SET(TABLE->READ_SET, FIELD_INDEX +--echo # + +CREATE TABLE t1(a INT); +INSERT INTO t1 VALUES (0), (1); + +CREATE TABLE t2( + b TEXT, + c INT, + PRIMARY KEY (b(1)) +); +INSERT INTO t2 VALUES ('a', 2), ('b', 3); + +SELECT 1 FROM t1 WHERE a = + (SELECT 1 FROM t2 WHERE b = + (SELECT 1 FROM t1 t11 WHERE c = 1 OR t1.a = 1 AND 1 = 2) + ORDER BY b + ); + +SELECT 1 FROM t1 WHERE a = + (SELECT 1 FROM t2 WHERE b = + (SELECT 1 FROM t1 t11 WHERE c = 1 OR t1.a = 1 AND 1 = 2) + GROUP BY b + ); + +DROP TABLE t1, t2; + +--echo # +--echo # BUG#12616253 - WRONG RESULT WITH EXISTS(SUBQUERY) (MISSING ROWS) +--echo # + +CREATE TABLE t1 (f1 varchar(1)); +INSERT INTO t1 VALUES ('v'),('s'); + +CREATE TABLE t2 (f1_key varchar(1), KEY (f1_key)); +INSERT INTO t2 VALUES ('j'),('v'),('c'),('m'),('d'), +('d'),('y'),('t'),('d'),('s'); + +let $query=SELECT table1.f1, table2.f1_key +FROM t1 AS table1, t2 AS table2 +WHERE EXISTS +( +SELECT DISTINCT f1_key +FROM t2 +WHERE f1_key != table2.f1_key AND f1_key >= table1.f1 ); + +eval $query; +eval explain $query; + +DROP TABLE t1,t2; + +set optimizer_switch=@subselect_tmp; diff --git a/mysql-test/t/subselect2.test b/mysql-test/t/subselect2.test index 162bdd0d90a..5f819ed39ba 100644 --- a/mysql-test/t/subselect2.test +++ b/mysql-test/t/subselect2.test @@ -8,6 +8,9 @@ drop table if exists t1, t2, t3, t4; --enable_warnings +set @subselect2_test_tmp=@@optimizer_switch; +set optimizer_switch='semijoin=on,firstmatch=on,mrr=on,mrr_sort_keys=on,index_condition_pushdown=on'; + CREATE TABLE t1 ( DOCID VARCHAR(32)BINARY NOT NULL @@ -168,3 +171,6 @@ SELECT t1.* FROM t1 WHERE (SELECT COUNT(*) FROM t3,t2 WHERE t3.c=t2.a and t2.a='1' AND t1.a=t3.b) > 0; DROP TABLE t1,t2,t3; + +set optimizer_switch=@subselect2_test_tmp; + diff --git a/mysql-test/t/subselect3.test b/mysql-test/t/subselect3.test index 9000f75fca0..1e92a147bcd 100644 --- a/mysql-test/t/subselect3.test +++ b/mysql-test/t/subselect3.test @@ -2,6 +2,9 @@ drop table if exists t0, t1, t2, t3, t4, t5, t11, t12, t21, t22; --enable_warnings +set @subselect3_tmp= @@optimizer_switch; +set optimizer_switch='semijoin=on,firstmatch=on,loosescan=on'; + # # 1. Subquery with GROUP/HAVING # @@ -536,7 +539,6 @@ SELECT a, MAX(b), DROP TABLE t1, t2; # The next three test cases must be executed with the IN=>EXISTS strategy -set @save_optimizer_switch=@@optimizer_switch; set @@optimizer_switch="partial_match_rowid_merge=off,partial_match_table_scan=off"; # @@ -681,7 +683,8 @@ SELECT a, ROW(11, 12) = (SELECT a, 12), ROW(11, 12) IN (SELECT a, 12) FROM t1; # The x alias is used below to workaround bug #40674. # Regression tests for sum function on outer column in subselect from dual: SELECT a AS x, ROW(11, 12) = (SELECT MAX(x), 22), ROW(11, 12) IN (SELECT MAX(x), 22) FROM t1; ---echo # 2nd and 3rd columns should be same for x == 11 only +--echo # 2nd and 3rd columns should be same +EXPLAIN SELECT a AS x, ROW(11, 12) = (SELECT MAX(x), 12), ROW(11, 12) IN (SELECT MAX(x), 12) FROM t1; SELECT a AS x, ROW(11, 12) = (SELECT MAX(x), 12), ROW(11, 12) IN (SELECT MAX(x), 12) FROM t1; DROP TABLE t1; @@ -888,7 +891,7 @@ set @@optimizer_switch='firstmatch=off'; explain select (select max(Y.a) from t1 Y where a in (select a from t1 Z) and a < X.a) as subq from t1 X; select (select max(Y.a) from t1 Y where a in (select a from t1 Z) and a < X.a) as subq from t1 X; -set @@optimizer_switch=default; +set @@optimizer_switch=@save_optimizer_switch; drop table t1; @@ -903,10 +906,11 @@ set @@optimizer_switch='firstmatch=off,materialization=off'; insert into t0 values(2); explain select * from t1 where 2 in (select a from t0); select * from t1 where 2 in (select a from t0); -set @@optimizer_switch='default,materialization=off'; +set @@optimizer_switch=@save_optimizer_switch; +set @@optimizer_switch='materialization=off'; explain select * from t1 where 2 in (select a from t0); select * from t1 where 2 in (select a from t0); -set @@optimizer_switch=default; +set @@optimizer_switch=@save_optimizer_switch; # @@ -947,12 +951,12 @@ set @save_max_heap_table_size=@@max_heap_table_size; set @@optimizer_switch='firstmatch=off,materialization=off'; set @@max_heap_table_size= 16384; -explain select count(*) from t0 A, t0 B, t0 C, t0 D where D.a in (select a from t1 E); +explain select count(*) from t0 A, t0 B, t0 C, t0 D where D.a in (select a from t1 E where a+1 < 10000 + A.a + B.a +C.a+D.a); flush status; -select count(*) from t0 A, t0 B, t0 C, t0 D where D.a in (select a from t1 E); +select count(*) from t0 A, t0 B, t0 C, t0 D where D.a in (select a from t1 E where a+1 < 10000 + A.a + B.a +C.a+D.a); show status like 'Created_tmp_disk_tables'; set @save_max_heap_table_size=@@max_heap_table_size; -set @@optimizer_switch=default; +set @@optimizer_switch=@save_optimizer_switch; drop table t0, t1; # @@ -990,7 +994,7 @@ create table t1 (a decimal); insert into t1 values (1),(2); explain select * from t1 where a in (select a from t1); drop table t1; -set @@optimizer_switch=default; +set @@optimizer_switch=@save_optimizer_switch; # # SJ-Materialization-scan for non-first table @@ -1051,7 +1055,7 @@ set @save_optimizer_search_depth=@@optimizer_search_depth; set @@optimizer_search_depth=63; explain select * from t1 where (a,b) in (select a,b from t2); set @@optimizer_search_depth=@save_optimizer_search_depth; -set @@optimizer_switch=default; +set @@optimizer_switch=@save_optimizer_switch; drop table t0, t1, t2; @@ -1157,7 +1161,7 @@ drop table t1,t2,t3; --echo # BUG#47367 Crash in Name_resolution_context::process_error --echo # -SET SESSION optimizer_switch = 'default,semijoin=off'; +SET SESSION optimizer_switch = 'semijoin=off'; CREATE TABLE t1 (f1 INTEGER); CREATE TABLE t2 LIKE t1; delimiter |; @@ -1230,3 +1234,6 @@ FROM t2; DROP TABLE t1,t2; --echo End of 5.6 tests + +# The following command must be the last one in the file +set @@optimizer_switch=@subselect3_tmp; diff --git a/mysql-test/t/subselect3_jcl6.test b/mysql-test/t/subselect3_jcl6.test index 9ee23288d99..8d880809476 100644 --- a/mysql-test/t/subselect3_jcl6.test +++ b/mysql-test/t/subselect3_jcl6.test @@ -2,6 +2,12 @@ # Run subselect3.test with BKA enabled # +set @save_optimizer_switch=@@optimizer_switch; +set @@optimizer_switch='optimize_join_buffer_size=on'; +set @@optimizer_switch='semijoin_with_cache=on'; +set @@optimizer_switch='outer_join_with_cache=on'; +set optimizer_switch='mrr=on,mrr_sort_keys=on,index_condition_pushdown=on'; + set join_cache_level=6; show variables like 'join_cache_level'; @@ -9,3 +15,5 @@ show variables like 'join_cache_level'; set join_cache_level=default; show variables like 'join_cache_level'; + +set @@optimizer_switch=@save_optimizer_switch; diff --git a/mysql-test/t/subselect4.test b/mysql-test/t/subselect4.test index c480fc9b0d2..1e8dd73fec6 100644 --- a/mysql-test/t/subselect4.test +++ b/mysql-test/t/subselect4.test @@ -1,5 +1,13 @@ # General purpose bug fix tests go here : subselect.test too large +--disable_warnings +drop table if exists t1,t2,t3,t4,t5,t6; +drop view if exists v1, v2; +--enable_warnings + +set @subselect4_tmp= @@optimizer_switch; +set optimizer_switch='semijoin=on,firstmatch=on,loosescan=on'; +set optimizer_switch='mrr=on,mrr_sort_keys=on,index_condition_pushdown=on'; --echo # --echo # Bug #46791: Assertion failed:(table->key_read==0),function unknown @@ -216,11 +224,9 @@ CREATE TABLE `t1` ( INSERT INTO `t1` VALUES (10,'00:00:00','i','i'),(11,'00:00:00','',''); set @old_optimizer_switch = @@session.optimizer_switch, - @old_optimizer_use_mrr = @@session.optimizer_use_mrr, @old_engine_condition_pushdown = @@session.engine_condition_pushdown; -SET SESSION OPTIMIZER_SWITCH = 'materialization=off,semijoin=off,loosescan=off,firstmatch=off'; -SET SESSION optimizer_use_mrr = 'force'; +SET SESSION OPTIMIZER_SWITCH = 'materialization=off,semijoin=off,loosescan=off,firstmatch=off,mrr=on'; SET SESSION engine_condition_pushdown = 1; SELECT `time_nokey` G1 FROM t1 WHERE ( `varchar_nokey` , `varchar_key` ) IN ( @@ -228,7 +234,6 @@ SELECT `varchar_nokey` , `varchar_nokey` ) AND `varchar_key` >= 'c' HAVING G BY `pk` ; set @@session.optimizer_switch = @old_optimizer_switch, - @@session.optimizer_use_mrr = @old_optimizer_use_mrr, @@session.engine_condition_pushdown = @old_engine_condition_pushdown; DROP TABLE t1; @@ -318,7 +323,7 @@ INSERT INTO t3 VALUES ('E4','P5',80); SET @old_optimizer_switch = @@session.optimizer_switch; SET @old_join_cache_level = @@session.join_cache_level; -SET SESSION optimizer_switch = 'firstmatch=on,loosescan=on,materialization=on,semijoin=on'; +SET SESSION optimizer_switch = 'firstmatch=on,loosescan=on,materialization=on,in_to_exists=off,semijoin=on'; SET SESSION join_cache_level = 1; CREATE UNIQUE INDEX t1_IDX ON t1(EMPNUM); @@ -476,3 +481,1115 @@ WHERE ( 1, 2 ) IN ( SELECT SUBQUERY1_t1.pk AS SUBQUERY1_field1, drop table t1; +--echo # +--echo # BUG#716293: "Range checked for each record" is not used if condition refers to outside of subquery +--echo # + +create table t1 (a int); +insert into t1 values (0),(1),(2),(3),(4),(5),(6),(7),(8),(9); +create table t2 (a int, b int, `filler` char(200), key(a), key (b)); +insert into t2 + select A.a + 10*B.a + 100 * C.a, A.a + 10*B.a + 100 * C.a, 'filler' from t1 A, t1 B, t1 C; + +--echo # The following must use "Range checked for each record" for table B +explain +select a, + (select sum(X.a+B.b) from t1 X, t2 B where B.a=A.a or B.b=A.a) +from t1 A; +drop table t1, t2; + + +--echo # +--echo # BUG#723822: Crash in get_constant_key_infix with EXISTS ( SELECT .. DISTINCT ) +--echo # +CREATE TABLE t1 ( f1 int(11), f3 varchar(1)) ; +INSERT INTO t1 VALUES ('8','c'),('5','f'); + +ALTER TABLE t1 ADD KEY (f3,f1); + +CREATE TABLE t2 ( f4 varchar(1)) ; +INSERT INTO t2 VALUES ('f'),('d'); + +SELECT * FROM t2 +WHERE EXISTS ( + SELECT DISTINCT f3 + FROM t1 + WHERE f3 <= t2.f4 +); + +drop table t1,t2; + +--echo # +--echo # LP BUG#718763 Second crash in select_describe() and materialization +--echo # + +CREATE TABLE t1 ( f1 int(11), f3 int(11), f10 varchar(1), KEY (f3)) ; +INSERT INTO t1 VALUES ('28','6','m'),('29','4','c'); + +CREATE TABLE t2 (f11 varchar(1)) ; +INSERT INTO t2 VALUES ('f'),('d'); + +SET @old_optimizer_switch = @@session.optimizer_switch; +SET SESSION optimizer_switch = 'materialization=on,in_to_exists=off'; + +EXPLAIN +SELECT * FROM t1 +WHERE f3 = ( + SELECT t1.f3 FROM t1 + WHERE ( t1.f10 ) IN ( SELECT f11 FROM t2 GROUP BY f11 )); +SELECT * FROM t1 +WHERE f3 = ( + SELECT t1.f3 FROM t1 + WHERE ( t1.f10 ) IN ( SELECT f11 FROM t2 GROUP BY f11 )); + +EXPLAIN +SELECT * FROM t1 +WHERE f3 = ( + SELECT f3 FROM t1 + WHERE ( f10, f10 ) IN ( SELECT f11, f11 FROM t2 GROUP BY f11 )); +SELECT * FROM t1 +WHERE f3 = ( + SELECT f3 FROM t1 + WHERE ( f10, f10 ) IN ( SELECT f11, f11 FROM t2 GROUP BY f11 )); + +SET SESSION optimizer_switch = @old_optimizer_switch; +drop table t1,t2; + +--echo # +--echo # LP BUG#715738: Wrong result with implicit grouping and empty result set +--echo # + +CREATE TABLE t1 (f1 int, f2 int); +CREATE TABLE t2 (f3 int, f4 int not null, PRIMARY KEY (f3)); + +set @save_optimizer_switch=@@optimizer_switch; + +SET @@optimizer_switch = 'materialization=on,in_to_exists=off,semijoin=off'; + +EXPLAIN +SELECT * FROM t1 WHERE (2, 0) NOT IN (SELECT f3, min(f4) FROM t2); +SELECT * FROM t1 WHERE (2, 0) NOT IN (SELECT f3, min(f4) FROM t2); + +EXPLAIN +SELECT * FROM t1 WHERE (2, 0) NOT IN (SELECT f3+f4, min(f4) FROM t2); +SELECT * FROM t1 WHERE (2, 0) NOT IN (SELECT f3+f4, min(f4) FROM t2); + +EXPLAIN +SELECT * FROM t1 WHERE (2, 0) NOT IN (SELECT f3, min(f4)+max(f4) FROM t2); +SELECT * FROM t1 WHERE (2, 0) NOT IN (SELECT f3, min(f4)+max(f4) FROM t2); + +EXPLAIN +SELECT (2, 0) NOT IN (SELECT f3, min(f4) FROM t2) as not_in; +SELECT (2, 0) NOT IN (SELECT f3, min(f4) FROM t2) as not_in; + +EXPLAIN +SELECT * FROM t1 WHERE (2, 0) NOT IN (SELECT f3, count(f4) FROM t2); +SELECT * FROM t1 WHERE (2, 0) NOT IN (SELECT f3, count(f4) FROM t2); + +EXPLAIN +SELECT * FROM t1 WHERE (2, 0) NOT IN (SELECT f3, f3 + count(f4) FROM t2); +SELECT * FROM t1 WHERE (2, 0) NOT IN (SELECT f3, f3 + count(f4) FROM t2); + +EXPLAIN +SELECT (2, 0) NOT IN (SELECT f3, count(f4) FROM t2) as not_in; +SELECT (2, 0) NOT IN (SELECT f3, count(f4) FROM t2) as not_in; + +EXPLAIN +SELECT (2, 0) NOT IN (SELECT f3, count(f4) FROM t2 HAVING max(f4) > 7) as not_in; +SELECT (2, 0) NOT IN (SELECT f3, count(f4) FROM t2 HAVING max(f4) > 7) as not_in; + +EXPLAIN +SELECT (2, 0) NOT IN (SELECT f3, count(f4) FROM t2 HAVING max(f4) is null) as not_in; +SELECT (2, 0) NOT IN (SELECT f3, count(f4) FROM t2 HAVING max(f4) is null) as not_in; + +EXPLAIN +SELECT (2, 0) NOT IN (SELECT max(f3+f3), count(f4) FROM t2) as not_in; +SELECT (2, 0) NOT IN (SELECT max(f3+f3), count(f4) FROM t2) as not_in; + +EXPLAIN +SELECT (2, 0) NOT IN (SELECT max(f3+f3), count(f4)+f3 FROM t2) as not_in; +SELECT (2, 0) NOT IN (SELECT max(f3+f3), count(f4)+f3 FROM t2) as not_in; + +EXPLAIN +SELECT * FROM t1 WHERE (2, 0) NOT IN (SELECT min(f3)+f3, min(f4)+f3+max(f4) FROM t2); +SELECT * FROM t1 WHERE (2, 0) NOT IN (SELECT min(f3)+f3, min(f4)+f3+max(f4) FROM t2); + + +SET @@optimizer_switch = 'materialization=off,in_to_exists=on,semijoin=off'; + + +EXPLAIN +SELECT * FROM t1 WHERE (2, 0) NOT IN (SELECT f3, min(f4) FROM t2); +SELECT * FROM t1 WHERE (2, 0) NOT IN (SELECT f3, min(f4) FROM t2); + +EXPLAIN +SELECT * FROM t1 WHERE (2, 0) NOT IN (SELECT f3+f4, min(f4) FROM t2); +SELECT * FROM t1 WHERE (2, 0) NOT IN (SELECT f3+f4, min(f4) FROM t2); + +EXPLAIN +SELECT * FROM t1 WHERE (2, 0) NOT IN (SELECT f3, min(f4)+max(f4) FROM t2); +SELECT * FROM t1 WHERE (2, 0) NOT IN (SELECT f3, min(f4)+max(f4) FROM t2); + +EXPLAIN +SELECT (2, 0) NOT IN (SELECT f3, min(f4) FROM t2) as not_in; +SELECT (2, 0) NOT IN (SELECT f3, min(f4) FROM t2) as not_in; + +EXPLAIN +SELECT * FROM t1 WHERE (2, 0) NOT IN (SELECT f3, count(f4) FROM t2); +SELECT * FROM t1 WHERE (2, 0) NOT IN (SELECT f3, count(f4) FROM t2); + +EXPLAIN +SELECT * FROM t1 WHERE (2, 0) NOT IN (SELECT f3, f3 + count(f4) FROM t2); +SELECT * FROM t1 WHERE (2, 0) NOT IN (SELECT f3, f3 + count(f4) FROM t2); + +EXPLAIN +SELECT (2, 0) NOT IN (SELECT f3, count(f4) FROM t2) as not_in; +SELECT (2, 0) NOT IN (SELECT f3, count(f4) FROM t2) as not_in; + +EXPLAIN +SELECT (2, 0) NOT IN (SELECT f3, count(f4) FROM t2 HAVING max(f4) > 7) as not_in; +SELECT (2, 0) NOT IN (SELECT f3, count(f4) FROM t2 HAVING max(f4) > 7) as not_in; + +EXPLAIN +SELECT (2, 0) NOT IN (SELECT f3, count(f4) FROM t2 HAVING max(f4) is null) as not_in; +SELECT (2, 0) NOT IN (SELECT f3, count(f4) FROM t2 HAVING max(f4) is null) as not_in; + +EXPLAIN +SELECT (2, 0) NOT IN (SELECT max(f3+f3), count(f4) FROM t2) as not_in; +SELECT (2, 0) NOT IN (SELECT max(f3+f3), count(f4) FROM t2) as not_in; + +EXPLAIN +SELECT (2, 0) NOT IN (SELECT max(f3+f3), count(f4)+f3 FROM t2) as not_in; +SELECT (2, 0) NOT IN (SELECT max(f3+f3), count(f4)+f3 FROM t2) as not_in; + +EXPLAIN +SELECT * FROM t1 WHERE (2, 0) NOT IN (SELECT min(f3)+f3, min(f4)+f3+max(f4) FROM t2); +SELECT * FROM t1 WHERE (2, 0) NOT IN (SELECT min(f3)+f3, min(f4)+f3+max(f4) FROM t2); + + +INSERT INTO t1 VALUES (1, 2); +INSERT INTO t1 VALUES (3, 4); +INSERT INTO t2 VALUES (5, 6); +INSERT INTO t2 VALUES (7, 8); + +SET @@optimizer_switch = 'materialization=on,in_to_exists=off,semijoin=off'; + +EXPLAIN +SELECT * FROM t1 WHERE (2, 0) NOT IN (SELECT f3, min(f4) FROM t2 WHERE f3 > 10); +SELECT * FROM t1 WHERE (2, 0) NOT IN (SELECT f3, min(f4) FROM t2 WHERE f3 > 10); + +EXPLAIN +SELECT * FROM t1 WHERE (2, 0) NOT IN (SELECT f3+f4, min(f4) FROM t2 WHERE f3 > 10); +SELECT * FROM t1 WHERE (2, 0) NOT IN (SELECT f3+f4, min(f4) FROM t2 WHERE f3 > 10); + +EXPLAIN +SELECT * FROM t1 WHERE (2, 0) NOT IN (SELECT f3, min(f4)+max(f4) FROM t2 WHERE f3 > 10); +SELECT * FROM t1 WHERE (2, 0) NOT IN (SELECT f3, min(f4)+max(f4) FROM t2 WHERE f3 > 10); + +EXPLAIN +SELECT (2, 0) NOT IN (SELECT f3, min(f4) FROM t2 WHERE f3 > 10) as not_in; +SELECT (2, 0) NOT IN (SELECT f3, min(f4) FROM t2 WHERE f3 > 10) as not_in; + +EXPLAIN +SELECT * FROM t1 WHERE (2, 0) NOT IN (SELECT f3, count(f4) FROM t2 WHERE f3 > 10); +SELECT * FROM t1 WHERE (2, 0) NOT IN (SELECT f3, count(f4) FROM t2 WHERE f3 > 10); + +EXPLAIN +SELECT * FROM t1 WHERE (2, 0) NOT IN (SELECT f3, f3 + count(f4) FROM t2 WHERE f3 > 10); +SELECT * FROM t1 WHERE (2, 0) NOT IN (SELECT f3, f3 + count(f4) FROM t2 WHERE f3 > 10); + +EXPLAIN +SELECT (2, 0) NOT IN (SELECT f3, count(f4) FROM t2 WHERE f3 > 10) as not_in; +SELECT (2, 0) NOT IN (SELECT f3, count(f4) FROM t2 WHERE f3 > 10) as not_in; + +EXPLAIN +SELECT (2, 0) NOT IN (SELECT f3, count(f4) FROM t2 WHERE f3 > 10 HAVING max(f4) > 7) as not_in; +SELECT (2, 0) NOT IN (SELECT f3, count(f4) FROM t2 WHERE f3 > 10 HAVING max(f4) > 7) as not_in; + +EXPLAIN +SELECT (2, 0) NOT IN (SELECT f3, count(f4) FROM t2 WHERE f3 > 10 HAVING max(f4) is null) as not_in; +SELECT (2, 0) NOT IN (SELECT f3, count(f4) FROM t2 WHERE f3 > 10 HAVING max(f4) is null) as not_in; + +EXPLAIN +SELECT (2, 0) NOT IN (SELECT max(f3+f3), count(f4) FROM t2 WHERE f3 > 10) as not_in; +SELECT (2, 0) NOT IN (SELECT max(f3+f3), count(f4) FROM t2 WHERE f3 > 10) as not_in; + +EXPLAIN +SELECT (2, 0) NOT IN (SELECT max(f3+f3), count(f4)+f3 FROM t2 WHERE f3 > 10) as not_in; +SELECT (2, 0) NOT IN (SELECT max(f3+f3), count(f4)+f3 FROM t2 WHERE f3 > 10) as not_in; + +EXPLAIN +SELECT * FROM t1 WHERE (2, 0) NOT IN (SELECT min(f3)+f3, min(f4)+f3+max(f4) FROM t2 WHERE f3 > 10); +SELECT * FROM t1 WHERE (2, 0) NOT IN (SELECT min(f3)+f3, min(f4)+f3+max(f4) FROM t2 WHERE f3 > 10); + +SET @@optimizer_switch = 'materialization=off,in_to_exists=on,semijoin=off'; + +EXPLAIN +SELECT * FROM t1 WHERE (2, 0) NOT IN (SELECT f3, min(f4) FROM t2 WHERE f3 > 10); +SELECT * FROM t1 WHERE (2, 0) NOT IN (SELECT f3, min(f4) FROM t2 WHERE f3 > 10); + +EXPLAIN +SELECT * FROM t1 WHERE (2, 0) NOT IN (SELECT f3+f4, min(f4) FROM t2 WHERE f3 > 10); +SELECT * FROM t1 WHERE (2, 0) NOT IN (SELECT f3+f4, min(f4) FROM t2 WHERE f3 > 10); + +EXPLAIN +SELECT * FROM t1 WHERE (2, 0) NOT IN (SELECT f3, min(f4)+max(f4) FROM t2 WHERE f3 > 10); +SELECT * FROM t1 WHERE (2, 0) NOT IN (SELECT f3, min(f4)+max(f4) FROM t2 WHERE f3 > 10); + +EXPLAIN +SELECT (2, 0) NOT IN (SELECT f3, min(f4) FROM t2 WHERE f3 > 10) as not_in; +SELECT (2, 0) NOT IN (SELECT f3, min(f4) FROM t2 WHERE f3 > 10) as not_in; + +EXPLAIN +SELECT * FROM t1 WHERE (2, 0) NOT IN (SELECT f3, count(f4) FROM t2 WHERE f3 > 10); +SELECT * FROM t1 WHERE (2, 0) NOT IN (SELECT f3, count(f4) FROM t2 WHERE f3 > 10); + +EXPLAIN +SELECT * FROM t1 WHERE (2, 0) NOT IN (SELECT f3, f3 + count(f4) FROM t2 WHERE f3 > 10); +SELECT * FROM t1 WHERE (2, 0) NOT IN (SELECT f3, f3 + count(f4) FROM t2 WHERE f3 > 10); + +EXPLAIN +SELECT (2, 0) NOT IN (SELECT f3, count(f4) FROM t2 WHERE f3 > 10) as not_in; +SELECT (2, 0) NOT IN (SELECT f3, count(f4) FROM t2 WHERE f3 > 10) as not_in; + +EXPLAIN +SELECT (2, 0) NOT IN (SELECT f3, count(f4) FROM t2 WHERE f3 > 10 HAVING max(f4) > 7) as not_in; +SELECT (2, 0) NOT IN (SELECT f3, count(f4) FROM t2 WHERE f3 > 10 HAVING max(f4) > 7) as not_in; + +EXPLAIN +SELECT (2, 0) NOT IN (SELECT f3, count(f4) FROM t2 WHERE f3 > 10 HAVING max(f4) is null) as not_in; +SELECT (2, 0) NOT IN (SELECT f3, count(f4) FROM t2 WHERE f3 > 10 HAVING max(f4) is null) as not_in; + +EXPLAIN +SELECT (2, 0) NOT IN (SELECT max(f3+f3), count(f4) FROM t2 WHERE f3 > 10) as not_in; +SELECT (2, 0) NOT IN (SELECT max(f3+f3), count(f4) FROM t2 WHERE f3 > 10) as not_in; + +EXPLAIN +SELECT (2, 0) NOT IN (SELECT max(f3+f3), count(f4)+f3 FROM t2 WHERE f3 > 10) as not_in; +SELECT (2, 0) NOT IN (SELECT max(f3+f3), count(f4)+f3 FROM t2 WHERE f3 > 10) as not_in; + +EXPLAIN +SELECT * FROM t1 WHERE (2, 0) NOT IN (SELECT min(f3)+f3, min(f4)+f3+max(f4) FROM t2 WHERE f3 > 10); +SELECT * FROM t1 WHERE (2, 0) NOT IN (SELECT min(f3)+f3, min(f4)+f3+max(f4) FROM t2 WHERE f3 > 10); + +set @@optimizer_switch=@save_optimizer_switch; + +drop table t1,t2; + +--echo # +--echo # LP BUG#613029 Wrong result with materialization and semijoin, and +--echo # valgrind warnings in Protocol::net_store_data with materialization +--echo # for implicit grouping +--echo # + +CREATE TABLE t1 ( + pk int(11) NOT NULL AUTO_INCREMENT, + f2 int(11) NOT NULL, + f3 varchar(1) NOT NULL, + PRIMARY KEY (pk), + KEY f2 (f2)); + +INSERT INTO t1 VALUES (1,9,'x'); +INSERT INTO t1 VALUES (2,5,'g'); + +CREATE TABLE t2 ( + pk int(11) NOT NULL AUTO_INCREMENT, + f2 int(11) NOT NULL, + f3 varchar(1) NOT NULL, + PRIMARY KEY (pk), + KEY f2 (f2)); + +INSERT INTO t2 VALUES (1,7,'p'); + +set @save_optimizer_switch=@@optimizer_switch; + +set @@optimizer_switch='materialization=off,in_to_exists=on,semijoin=off'; + +EXPLAIN +SELECT t1.f3, MAX(t1.f2) +FROM t1, t2 +WHERE (t2.pk = t1.pk) AND t2.pk IN (SELECT f2 FROM t1); + +SELECT t1.f3, MAX(t1.f2) +FROM t1, t2 +WHERE (t2.pk = t1.pk) AND t2.pk IN (SELECT f2 FROM t1); + +set @@optimizer_switch='materialization=on,in_to_exists=off,semijoin=off'; + +EXPLAIN +SELECT t1.f3, MAX(t1.f2) +FROM t1, t2 +WHERE (t2.pk = t1.pk) AND t2.pk IN (SELECT f2 FROM t1); + +SELECT t1.f3, MAX(t1.f2) +FROM t1, t2 +WHERE (t2.pk = t1.pk) AND t2.pk IN (SELECT f2 FROM t1); + +-- echo TODO: add a test case for semijoin when the wrong result is fixed +-- echo set @@optimizer_switch='materialization=off,semijoin=on'; + + +set @@optimizer_switch=@save_optimizer_switch; + +drop table t1, t2; + + +--echo # +--echo # LP BUG#777691 Wrong result with subqery in select list and subquery cache=off in maria-5.3 +--echo # + +CREATE TABLE t1 ( f1 varchar(32)) ; +INSERT INTO t1 VALUES ('b'),('x'),('c'),('x'); + +CREATE TABLE t2 ( f2 int, f3 varchar(32)) ; +INSERT INTO t2 VALUES (1,'x'); + +set @save_optimizer_switch=@@optimizer_switch; +set @@optimizer_switch='materialization=off,in_to_exists=on,subquery_cache=off'; + +EXPLAIN +SELECT t1.f1, ( SELECT MAX( f2 ) FROM t2 WHERE t2.f3 = t1.f1 ) as max_f2 FROM t1; +SELECT t1.f1, ( SELECT MAX( f2 ) FROM t2 WHERE t2.f3 = t1.f1 ) as max_f2 FROM t1; + +set @@optimizer_switch='materialization=on,in_to_exists=off,subquery_cache=off'; +EXPLAIN +SELECT t1.f1, ( SELECT MAX( f2 ) FROM t2 WHERE t2.f3 = t1.f1 ) as max_f2 FROM t1; +SELECT t1.f1, ( SELECT MAX( f2 ) FROM t2 WHERE t2.f3 = t1.f1 ) as max_f2 FROM t1; + +set @@optimizer_switch='materialization=off,in_to_exists=on,subquery_cache=off'; +--echo Even when t2 is not constant table, the result must be the same. +INSERT INTO t2 VALUES (2,'y'); +EXPLAIN +SELECT t1.f1, ( SELECT MAX( f2 ) FROM t2 WHERE t2.f3 = t1.f1 ) as max_f2 FROM t1; +SELECT t1.f1, ( SELECT MAX( f2 ) FROM t2 WHERE t2.f3 = t1.f1 ) as max_f2 FROM t1; + +set @@optimizer_switch=@save_optimizer_switch; + +drop table t1, t2; + +--echo # +--echo # LP BUG#641203 Query returns rows where no result is expected (impossible WHERE) +--echo # + +CREATE TABLE t1 (c1 varchar(1) DEFAULT NULL); +CREATE TABLE t2 (c1 varchar(1) DEFAULT NULL); +INSERT INTO t2 VALUES ('k'), ('d'); +CREATE TABLE t3 (c1 varchar(1) DEFAULT NULL); +INSERT INTO t3 VALUES ('a'), ('b'), ('c'); +CREATE TABLE t4 (c1 varchar(1) primary key); +INSERT INTO t4 VALUES ('k'), ('d'); + +EXPLAIN +SELECT * FROM t1 RIGHT JOIN t2 ON t1.c1 WHERE 's' IN (SELECT c1 FROM t2); +SELECT * FROM t1 RIGHT JOIN t2 ON t1.c1 WHERE 's' IN (SELECT c1 FROM t2); +EXPLAIN +SELECT * FROM t2 LEFT JOIN t1 ON t1.c1 WHERE 's' IN (SELECT c1 FROM t2); +SELECT * FROM t2 LEFT JOIN t1 ON t1.c1 WHERE 's' IN (SELECT c1 FROM t2); +EXPLAIN +SELECT * FROM (t2 LEFT JOIN t1 ON t1.c1) LEFT JOIN t3 on t3.c1 WHERE 's' IN (SELECT c1 FROM t2); +SELECT * FROM (t2 LEFT JOIN t1 ON t1.c1) LEFT JOIN t3 on t3.c1 WHERE 's' IN (SELECT c1 FROM t2); +EXPLAIN +SELECT * FROM t4 LEFT JOIN t2 ON t4.c1 WHERE 's' IN (SELECT c1 FROM t2); +SELECT * FROM t4 LEFT JOIN t2 ON t4.c1 WHERE 's' IN (SELECT c1 FROM t2); +drop table t1, t2, t3, t4; + +--echo # +--echo # LP BUG#675981 Assertion `cache != __null' failed in sub_select_cache() +--echo # on EXPLAIN +--echo # + +CREATE TABLE t1 (f1 int,f2 int) ; +INSERT IGNORE INTO t1 VALUES ('2','5'),('2',NULL); + +CREATE TABLE t2 (f1 int, f5 int) ; +INSERT IGNORE INTO t2 VALUES (1,0); + +CREATE TABLE t3 (f4 int) ; +INSERT IGNORE INTO t3 VALUES (0),(0); + +set @@optimizer_switch='in_to_exists=on,materialization=off,semijoin=off'; +EXPLAIN +SELECT * FROM t2 +WHERE f1 IN (SELECT t1.f2 FROM t1 JOIN t3 ON t3.f4); + +drop table t1, t2, t3; + +--echo # +--echo # LP BUG#680005 Second assertion `cache != __null' failed in +--echo # sub_select_cache() on EXPLAIN +--echo # + +CREATE TABLE t1 (f1 int,f2 int,f4 int,f6 int,KEY (f4)) ; +INSERT IGNORE INTO t1 VALUES +('1','5','1','0'),('2','1','1','0'),('2','2','2','0'),('0',NULL,'0','0'), +('2','1','2','0'),('2','0','0','0'),('2','2','2','0'),('2','8','2','0'), +('2','7','2','0'),('2','5','2','0'),('2',NULL,'1','0'); + +CREATE TABLE t2 (f3 int) ; +INSERT IGNORE INTO t2 VALUES ('7'); + +CREATE TABLE t3 (f3 int) ; +INSERT IGNORE INTO t3 VALUES ('2'); + +EXPLAIN +SELECT t1.f4 +FROM t2 JOIN t1 ON t1.f6 +WHERE +( t1.f2 ) IN (SELECT SUBQUERY2_t1.f3 + FROM t3 AS SUBQUERY2_t1 + JOIN + (t1 AS SUBQUERY2_t2 + JOIN + t1 AS SUBQUERY2_t3 ON SUBQUERY2_t3.f1) + ON SUBQUERY2_t3.f2) +GROUP BY t1.f4 ORDER BY t1.f1 LIMIT 10; + +drop table t1, t2, t3; + +--echo # +--echo # LP BUG#680038 bool close_thread_table(THD*, TABLE**): +--echo # Assertion `table->key_read == 0' failed in EXPLAIN +--echo # + +CREATE TABLE t1 (f1 int,f3 int,f4 int) ; +INSERT IGNORE INTO t1 VALUES (NULL,1,0); + +CREATE TABLE t2 (f2 int,f4 int,f5 int) ; +INSERT IGNORE INTO t2 VALUES (8,0,0),(5,0,0); + +CREATE TABLE t3 (f4 int,KEY (f4)) ; +INSERT IGNORE INTO t3 VALUES (0),(0); + +set @@optimizer_switch='semijoin=off'; + +EXPLAIN +SELECT * FROM t1 WHERE +(SELECT f2 FROM t2 + WHERE f4 <= ALL + (SELECT SQ1_t1.f4 + FROM t3 AS SQ1_t1 JOIN t3 AS SQ1_t3 ON SQ1_t3.f4 + GROUP BY SQ1_t1.f4)); + +drop table t1, t2, t3; + +--echo # +--echo # BUG#52317: Assertion failing in Field_varstring::store() +--echo # at field.cc:6833 +--echo # + +CREATE TABLE t1 (i INTEGER); +INSERT INTO t1 VALUES (1); +CREATE TABLE t2 (i INTEGER, KEY k(i)); +INSERT INTO t2 VALUES (1), (2); + +EXPLAIN +SELECT i FROM t1 WHERE (1) NOT IN (SELECT i FROM t2); + +DROP TABLE t2; +DROP TABLE t1; + +--echo # +--echo # LP BUG#680846: Crash in clear_tables() with subqueries +--echo # + +CREATE TABLE t1 (f3 int) ; +INSERT IGNORE INTO t1 VALUES (0),(0); + +CREATE TABLE t2 (f1 int,f3 int,f4 varchar(32)) ; +INSERT IGNORE INTO t2 VALUES (1,0,'f'); + +EXPLAIN +SELECT COUNT(t2.f3), + (SELECT COUNT(f3) FROM t1 WHERE t2.f1) AS f9 +FROM t2 JOIN t1 ON t1.f3 +WHERE ('v') IN (SELECT f4 FROM t2) +GROUP BY f9; + +SELECT COUNT(t2.f3), + (SELECT COUNT(f3) FROM t1 WHERE t2.f1) AS f9 +FROM t2 JOIN t1 ON t1.f3 +WHERE ('v') IN (SELECT f4 FROM t2) +GROUP BY f9; + +EXPLAIN +SELECT COUNT(t2.f3), + (SELECT COUNT(f3) FROM t1 WHERE t2.f1) AS f9 +FROM t2 JOIN t1 ON t1.f3 +WHERE ('v') IN (SELECT f4 FROM t2) +ORDER BY f9; + +SELECT COUNT(t2.f3), + (SELECT COUNT(f3) FROM t1 WHERE t2.f1) AS f9 +FROM t2 JOIN t1 ON t1.f3 +WHERE ('v') IN (SELECT f4 FROM t2) +ORDER BY f9; + +# these queries are like the ones above, but without the ON clause, +# resulting in a different crash (failed assert) +EXPLAIN +SELECT COUNT(t2.f3), + (SELECT t2.f1 FROM t1 limit 1) AS f9 +FROM t2 JOIN t1 +WHERE ('v') IN (SELECT f4 FROM t2) +GROUP BY f9; + +SELECT COUNT(t2.f3), + (SELECT t2.f1 FROM t1 limit 1) AS f9 +FROM t2 JOIN t1 +WHERE ('v') IN (SELECT f4 FROM t2) +GROUP BY f9; + +EXPLAIN +SELECT COUNT(t2.f3), + (SELECT t2.f1 FROM t1 limit 1) AS f9 +FROM t2 JOIN t1 +WHERE ('v') IN (SELECT f4 FROM t2) +ORDER BY f9; + +SELECT COUNT(t2.f3), + (SELECT t2.f1 FROM t1 limit 1) AS f9 +FROM t2 JOIN t1 +WHERE ('v') IN (SELECT f4 FROM t2) +ORDER BY f9; + +drop table t1,t2; + +--echo # +--echo # LP BUG#682683 Crash in create_tmp_table called from +--echo # JOIN::init_execution +--echo # + +CREATE TABLE t2 (f1 int) ; +INSERT INTO t2 VALUES (1),(2); + +CREATE TABLE t1 (f1 int) ; + +EXPLAIN +SELECT (SELECT f1 FROM t1) AS field1 FROM t2 GROUP BY field1; +SELECT (SELECT f1 FROM t1) AS field1 FROM t2 GROUP BY field1; +EXPLAIN +SELECT (SELECT f1 FROM t1) AS field1 FROM t2 ORDER BY field1; +SELECT (SELECT f1 FROM t1) AS field1 FROM t2 ORDER BY field1; + +INSERT INTO t1 VALUES (1),(2); + +EXPLAIN +SELECT (SELECT f1 FROM t1) AS field1 FROM t2 GROUP BY field1; +--error ER_SUBQUERY_NO_1_ROW +SELECT (SELECT f1 FROM t1) AS field1 FROM t2 GROUP BY field1; +EXPLAIN +SELECT (SELECT f1 FROM t1) AS field1 FROM t2 ORDER BY field1; +--error ER_SUBQUERY_NO_1_ROW +SELECT (SELECT f1 FROM t1) AS field1 FROM t2 ORDER BY field1; + +drop table t1,t2; + +--echo # +--echo # LP BUG#680943 Assertion `!table || (!table->read_set || +--echo # bitmap_is_set(table->read_set, field_index))' failed with subquery +--echo # + +CREATE TABLE t1 (f1 int,f3 int) ; +INSERT IGNORE INTO t1 VALUES ('6','0'),('4','0'); + +CREATE TABLE t2 (f1 int,f2 int,f3 int) ; +INSERT IGNORE INTO t2 VALUES ('6','0','0'),('2','0','0'); + +SELECT f2 +FROM (SELECT * FROM t2) AS alias1 +WHERE (SELECT SQ2_t2.f1 + FROM t1 JOIN t1 AS SQ2_t2 ON SQ2_t2.f3 + WHERE SQ2_t2.f3 AND alias1.f1) +ORDER BY f3 ; + +drop table t1,t2; + +--echo # +--echo # LP BUG#715062: Wrong result with VIEW + UNION + subquery in maria-5.3-mwl89 +--echo # + +create table t1 (f1 int); +create table t2 (f2 int); +create table t3 (f3 int); +insert into t1 values (2); +insert into t2 values (2); +insert into t3 values (7); + +CREATE VIEW v1 AS SELECT 2 UNION SELECT 2 ; +CREATE VIEW v2 AS SELECT * from t1 UNION SELECT * from t2 ; + +set @save_optimizer_switch=@@optimizer_switch; +SET @@optimizer_switch = 'in_to_exists=off,semijoin=off,materialization=on'; + +EXPLAIN +SELECT 'bug' FROM DUAL WHERE ( 5 ) IN ( SELECT * FROM v1 ); +SELECT 'bug' FROM DUAL WHERE ( 5 ) IN ( SELECT * FROM v1 ); + +EXPLAIN +SELECT ( 5 ) IN ( SELECT * FROM v1 ); +SELECT ( 5 ) IN ( SELECT * FROM v1 ); + +EXPLAIN +SELECT 'bug' FROM DUAL WHERE ( 5 ) IN (SELECT * FROM v2); +SELECT 'bug' FROM DUAL WHERE ( 5 ) IN (SELECT * FROM v2); + +EXPLAIN +SELECT 'bug' FROM t3 WHERE ( 5 ) IN (SELECT * FROM v2); +SELECT 'bug' FROM t3 WHERE ( 5 ) IN (SELECT * FROM v2); + +EXPLAIN +SELECT ( 5 ) IN ( SELECT * FROM v2 ); +SELECT ( 5 ) IN ( SELECT * FROM v2 ); + +SET @@optimizer_switch = 'in_to_exists=on,semijoin=off,materialization=off'; + +EXPLAIN +SELECT 'bug' FROM DUAL WHERE ( 5 ) IN ( SELECT * FROM v1 ); +SELECT 'bug' FROM DUAL WHERE ( 5 ) IN ( SELECT * FROM v1 ); + +EXPLAIN +SELECT ( 5 ) IN ( SELECT * FROM v1 ); +SELECT ( 5 ) IN ( SELECT * FROM v1 ); + +EXPLAIN +SELECT 'bug' FROM DUAL WHERE ( 5 ) IN (SELECT * FROM v2); +SELECT 'bug' FROM DUAL WHERE ( 5 ) IN (SELECT * FROM v2); + +EXPLAIN +SELECT 'bug' FROM t3 WHERE ( 5 ) IN (SELECT * FROM v2); +SELECT 'bug' FROM t3 WHERE ( 5 ) IN (SELECT * FROM v2); + +EXPLAIN +SELECT ( 5 ) IN ( SELECT * FROM v2 ); +SELECT ( 5 ) IN ( SELECT * FROM v2 ); + +set @@optimizer_switch=@save_optimizer_switch; + +drop table t1,t2,t3; +drop view v1,v2; + +--echo # +--echo # LP BUG#715069 Wrong result with GROUP BY inside subquery and materialization=off +--echo # + +CREATE TABLE t0 ( f1 int(11), f2 int(11), f10 varchar(1), PRIMARY KEY (f1)) ; +INSERT INTO t0 VALUES (8,8,'u'),(10,5,'o'); + +CREATE TABLE t1 (f1a int, f2a int not null, f3a varchar(3) not null, PRIMARY KEY (f1a)) ; +INSERT INTO t1 VALUES +(8,8,'a1a'), +(10,5,'b1b'); + +CREATE TABLE t2 (f1b int, f2b int not null, f3b varchar(3) not null, PRIMARY KEY (f1b)) ; +INSERT INTO t2 VALUES +(10,5,'d1d'); + +set @save_optimizer_switch=@@optimizer_switch; +set @@optimizer_switch = 'materialization=off'; + +EXPLAIN +SELECT alias2.f1 , alias2.f2 +FROM t0 AS alias1 +RIGHT JOIN t0 AS alias2 ON alias2.f10 +WHERE ( alias2.f1 , alias2.f2 ) IN ( SELECT f2 , f1 FROM t0 GROUP BY f2 , f1 ); + +SELECT alias2.f1 , alias2.f2 +FROM t0 AS alias1 +RIGHT JOIN t0 AS alias2 ON alias2.f10 +WHERE ( alias2.f1 , alias2.f2 ) IN ( SELECT f2 , f1 FROM t0 GROUP BY f2 , f1 ); + +EXPLAIN +SELECT * FROM t2 WHERE (f1b, f2b) IN (SELECT f1a, f2a FROM t1 GROUP BY f1a, f2a); +SELECT * FROM t2 WHERE (f1b, f2b) IN (SELECT f1a, f2a FROM t1 GROUP BY f1a, f2a); + +EXPLAIN +SELECT * FROM t2 WHERE (f1b) IN (SELECT f1a FROM t1 GROUP BY f1a, f2a); +SELECT * FROM t2 WHERE (f1b) IN (SELECT f1a FROM t1 GROUP BY f1a, f2a); + +SET @@optimizer_switch = 'materialization=on'; + +EXPLAIN +SELECT alias2.f1 , alias2.f2 +FROM t0 AS alias1 +RIGHT JOIN t0 AS alias2 ON alias2.f10 +WHERE ( alias2.f1 , alias2.f2 ) IN ( SELECT f2 , f1 FROM t0 GROUP BY f2 , f1 ); + +SELECT alias2.f1 , alias2.f2 +FROM t0 AS alias1 +RIGHT JOIN t0 AS alias2 ON alias2.f10 +WHERE ( alias2.f1 , alias2.f2 ) IN ( SELECT f2 , f1 FROM t0 GROUP BY f2 , f1 ); + +EXPLAIN +SELECT * FROM t2 WHERE (f1b, f2b) IN (SELECT f1a, f2a FROM t1 GROUP BY f1a, f2a); +SELECT * FROM t2 WHERE (f1b, f2b) IN (SELECT f1a, f2a FROM t1 GROUP BY f1a, f2a); + +EXPLAIN +SELECT * FROM t2 WHERE (f1b) IN (SELECT f1a FROM t1 GROUP BY f1a, f2a); +SELECT * FROM t2 WHERE (f1b) IN (SELECT f1a FROM t1 GROUP BY f1a, f2a); + +set @@optimizer_switch=@save_optimizer_switch; + +drop table t0,t1,t2; + + +--echo # +--echo # LP BUG#715759 Wrong result with in_to_exists=on in maria-5.3-mwl89 +--echo # + +set @save_optimizer_switch=@@optimizer_switch; +CREATE TABLE t1 (a1 int, a2 int) ; +INSERT INTO t1 VALUES (1, 2); +INSERT INTO t1 VALUES (3, 4); + +CREATE TABLE t2 (b1 int, b2 int) ; +INSERT INTO t2 VALUES (1, 2); + +SET @@optimizer_switch = 'in_to_exists=on,materialization=off,semijoin=off'; + +EXPLAIN SELECT * FROM t1 WHERE a1 IN (SELECT b1 FROM t2 WHERE b1 = b2); +SELECT * FROM t1 WHERE a1 IN (SELECT b1 FROM t2 WHERE b1 = b2); + +set @@optimizer_switch=@save_optimizer_switch; +drop table t1, t2; + +--echo # +--echo # LP BUG#772309 join_tab_cmp_straight(): Assertion `!jt2->emb_sj_nest' failed in maria-5.3-mwl89 with semijoin +--echo # + +CREATE TABLE t1 ( f2 int) ; +INSERT INTO t1 VALUES (0),(0); + +CREATE TABLE t2 ( f1 int NOT NULL ) ; +INSERT INTO t2 VALUES (0),(0); + +CREATE TABLE t3 ( f1 int NOT NULL , f2 int) ; +INSERT INTO t3 VALUES (0,0), (0,0); + +EXPLAIN SELECT STRAIGHT_JOIN ( + SELECT f2 FROM t1 WHERE ( f2 ) IN ( SELECT t3.f2 FROM t3 JOIN t2 ON t2.f1 = 1 ) +); +SELECT STRAIGHT_JOIN ( + SELECT f2 FROM t1 WHERE ( f2 ) IN ( SELECT t3.f2 FROM t3 JOIN t2 ON t2.f1 = 1 ) +); + +drop table t1, t2, t3; + + +--echo # +--echo # LP BUG#777597 Wrong result with multipart keys, in_to_exists=on, NOT IN in MWL#89 +--echo # + +CREATE TABLE t1 ( f4 int); +INSERT IGNORE INTO t1 VALUES (2),(2); + +CREATE TABLE t2 ( f3 int, f10 int, KEY (f10,f3) ); +INSERT IGNORE INTO t2 VALUES (6, 1), (6, 1); + +CREATE TABLE t3 ( f10 int ); +INSERT IGNORE INTO t3 VALUES (1); + +SET SESSION optimizer_switch='in_to_exists=on,materialization=off'; + +EXPLAIN +SELECT * FROM t1 WHERE ( 6 ) NOT IN ( SELECT t2.f3 FROM t2 JOIN t3 ON t3.f10 = t2.f10); +SELECT * FROM t1 WHERE ( 6 ) NOT IN ( SELECT t2.f3 FROM t2 JOIN t3 ON t3.f10 = t2.f10); + +drop table t1,t2,t3; + + +--echo # +--echo # LP BUG#778413 Third crash in select_describe() in maria-5.3-mwl89 +--echo # + +CREATE TABLE t1 ( f11 int) ; +INSERT INTO t1 VALUES (1),(1); + +CREATE TABLE t2 ( f1 int NOT NULL) ; +INSERT INTO t2 VALUES (20); + +CREATE TABLE t3 (f3 int) ; +INSERT INTO t3 VALUES (2),(2); + +EXPLAIN SELECT * FROM t2 +WHERE t2.f1 = ( + SELECT MAX( f3 ) FROM t3 + WHERE EXISTS ( + SELECT DISTINCT f11 + FROM t1)); + +drop table t1, t2, t3; + +--echo # +--echo # LP BUG#802979 Assertion `table->key_read == 0' in close_thread_table +--echo # + +CREATE TABLE t1 ( f1 int, f2 int , KEY (f1)) ; +INSERT IGNORE INTO t1 VALUES (1,0),(5,0); +CREATE TABLE t2 ( f1 int, f2 int , KEY (f1)) ; +INSERT IGNORE INTO t2 VALUES (1,0),(5,0); +CREATE TABLE t3 ( f1 int, f2 int , KEY (f1)) ; +INSERT IGNORE INTO t3 VALUES (1,0),(5,0); +CREATE TABLE t4 ( f1 int, f2 int , KEY (f1)) ; +INSERT IGNORE INTO t4 VALUES (1,0),(5,0); + +EXPLAIN +SELECT * +FROM t1, t2 +WHERE t2.f2 = (SELECT f2 FROM t3 + WHERE EXISTS (SELECT DISTINCT f1 FROM t4)) + AND t2.f2 = t1.f1; + +-- error ER_SUBQUERY_NO_1_ROW +SELECT * +FROM t1, t2 +WHERE t2.f2 = (SELECT f2 FROM t3 + WHERE EXISTS (SELECT DISTINCT f1 FROM t4)) + AND t2.f2 = t1.f1; + +EXPLAIN +SELECT * +FROM t1, t2 +WHERE t2.f2 = (SELECT f2 FROM t3 + WHERE EXISTS (SELECT DISTINCT f1 FROM t4) LIMIT 1) + AND t2.f2 = t1.f1; + +SELECT * +FROM t1, t2 +WHERE t2.f2 = (SELECT f2 FROM t3 + WHERE EXISTS (SELECT DISTINCT f1 FROM t4) LIMIT 1) + AND t2.f2 = t1.f1; + +drop table t1,t2,t3,t4; + +--echo # +--echo # LP BUG#806943 Second crash with select_describe with nested subqueries in maria-5.3 +--echo # + +CREATE TABLE t1 ( f4 int) ; +INSERT INTO t1 VALUES (0),(0); + +CREATE TABLE t2 ( f2 int) ; + +CREATE TABLE t3 ( f1 int NOT NULL ); + +CREATE TABLE t4 ( f2 int, f3 int) ; +INSERT INTO t4 VALUES (8,0),(3,0); + +EXPLAIN SELECT * +FROM t2, t3 +WHERE t3.f1 = ( + SELECT SUM( f2 ) + FROM t4 + WHERE EXISTS ( + SELECT DISTINCT f4 + FROM t1)); +SELECT * +FROM t2, t3 +WHERE t3.f1 = ( + SELECT SUM( f2 ) + FROM t4 + WHERE EXISTS ( + SELECT DISTINCT f4 + FROM t1)); + +drop table t1, t2, t3, t4; + +--echo # +--echo # LP BUG#611690 Crash in select_describe() with nested subqueries +--echo # + +CREATE TABLE t1 ( + col_int_key int(11) DEFAULT NULL, + col_varchar_key varchar(1) DEFAULT NULL, + col_varchar_nokey varchar(1) DEFAULT NULL, + KEY col_int_key (col_int_key), + KEY col_varchar_key (col_varchar_key,col_int_key) +) ENGINE=MyISAM DEFAULT CHARSET=latin1; +INSERT INTO t1 VALUES (8,'v','v'); +INSERT INTO t1 VALUES (9,'r','r'); + +CREATE TABLE t2 ( + col_int_key int(11) DEFAULT NULL, + col_varchar_key varchar(1) DEFAULT NULL, + col_varchar_nokey varchar(1) DEFAULT NULL, + KEY col_int_key (col_int_key), + KEY col_varchar_key (col_varchar_key,col_int_key) +) ENGINE=MyISAM DEFAULT CHARSET=latin1; +INSERT INTO t2 VALUES (2,'w','w'); +INSERT INTO t2 VALUES (9,'m','m'); + +set @old_optimizer_switch = @@optimizer_switch; + +set @@optimizer_switch='subquery_cache=off,materialization=on,in_to_exists=off,semijoin=off'; +EXPLAIN +SELECT col_int_key +FROM t2 +WHERE (SELECT SUBQUERY2_t1.col_int_key + FROM t1 SUBQUERY2_t1 STRAIGHT_JOIN t1 SUBQUERY2_t2 + ON SUBQUERY2_t2.col_varchar_key + WHERE SUBQUERY2_t2.col_varchar_nokey IN + (SELECT col_varchar_nokey FROM t1 GROUP BY col_varchar_nokey)); +SELECT col_int_key +FROM t2 +WHERE (SELECT SUBQUERY2_t1.col_int_key + FROM t1 SUBQUERY2_t1 STRAIGHT_JOIN t1 SUBQUERY2_t2 + ON SUBQUERY2_t2.col_varchar_key + WHERE SUBQUERY2_t2.col_varchar_nokey IN + (SELECT col_varchar_nokey FROM t1 GROUP BY col_varchar_nokey)); + +set @@optimizer_switch='subquery_cache=off,materialization=off,in_to_exists=on,semijoin=off'; +EXPLAIN +SELECT col_int_key +FROM t2 +WHERE (SELECT SUBQUERY2_t1.col_int_key + FROM t1 SUBQUERY2_t1 STRAIGHT_JOIN t1 SUBQUERY2_t2 + ON SUBQUERY2_t2.col_varchar_key + WHERE SUBQUERY2_t2.col_varchar_nokey IN + (SELECT col_varchar_nokey FROM t1 GROUP BY col_varchar_nokey)); +SELECT col_int_key +FROM t2 +WHERE (SELECT SUBQUERY2_t1.col_int_key + FROM t1 SUBQUERY2_t1 STRAIGHT_JOIN t1 SUBQUERY2_t2 + ON SUBQUERY2_t2.col_varchar_key + WHERE SUBQUERY2_t2.col_varchar_nokey IN + (SELECT col_varchar_nokey FROM t1 GROUP BY col_varchar_nokey)); + +drop table t1, t2; + +set @@optimizer_switch = @old_optimizer_switch; + + +--echo # +--echo # LP BUG#612543 Crash in Item_field::used_tables() with view + subquery + prepared statements +--echo # + +CREATE TABLE t1 ( f1 int(11), f2 varchar(1)); +CREATE TABLE t2 ( f3 varchar(1)); +insert into t1 values (2,'x'), (5,'y'); +insert into t2 values ('x'), ('z'); +CREATE VIEW v2 AS SELECT * FROM t2; + +set @old_optimizer_switch = @@optimizer_switch; + +set @@optimizer_switch='materialization=on,in_to_exists=off,semijoin=off,subquery_cache=off'; +EXPLAIN SELECT * FROM t1 JOIN v2 ON t1.f2 > 'a' WHERE v2.f3 IN ( SELECT f2 FROM t1 ); +PREPARE st1 FROM "SELECT * FROM t1 JOIN v2 ON t1.f2 > 'a' WHERE v2.f3 IN ( SELECT f2 FROM t1 )"; +EXECUTE st1; +EXECUTE st1; + +set @@optimizer_switch='materialization=off,in_to_exists=on,semijoin=off,subquery_cache=off'; +EXPLAIN SELECT * FROM t1 JOIN v2 ON t1.f2 > 'a' WHERE v2.f3 IN ( SELECT f2 FROM t1 ); +PREPARE st2 FROM "SELECT * FROM t1 JOIN v2 ON t1.f2 > 'a' WHERE v2.f3 IN ( SELECT f2 FROM t1 )"; +EXECUTE st2; +EXECUTE st2; + +set @@optimizer_switch='materialization=on,in_to_exists=on,semijoin=off,subquery_cache=off'; +EXPLAIN SELECT * FROM t1 JOIN v2 ON t1.f2 > 'a' WHERE v2.f3 IN ( SELECT f2 FROM t1 ); +PREPARE st3 FROM "SELECT * FROM t1 JOIN v2 ON t1.f2 > 'a' WHERE v2.f3 IN ( SELECT f2 FROM t1 )"; +EXECUTE st3; +EXECUTE st3; + +set @@optimizer_switch = @old_optimizer_switch; + +drop table t1, t2; +drop view v2; + + +--echo # +--echo # LP BUG#611396 RQG: crash in Item_field::register_field_in_read_map with semijoin=off +--echo # and prepared statements and materialization + +CREATE TABLE t1 ( f1 int(11), f2 int(11)) ; +CREATE TABLE t2 ( f1 int(11), f4 varchar(1), PRIMARY KEY (f1)) ; +INSERT INTO t2 VALUES ('23','j'),('24','e'); +CREATE TABLE t3 ( f1 int(11), f4 varchar(1)) ; +INSERT INTO t3 VALUES ('8','j'); + +set @old_optimizer_switch = @@optimizer_switch; +set @@optimizer_switch='materialization=on,in_to_exists=off,semijoin=off'; + +EXPLAIN +SELECT t2.f1, (SELECT f2 FROM t1 WHERE (7) IN (SELECT f1 FROM t1)) +FROM t2 JOIN t3 ON t3.f4 = t2.f4 +WHERE t3.f1 = 8 +GROUP BY 1, 2; + +PREPARE st1 FROM " +SELECT t2.f1, (SELECT f2 FROM t1 WHERE (7) IN (SELECT f1 FROM t1)) +FROM t2 JOIN t3 ON t3.f4 = t2.f4 +WHERE t3.f1 = 8 +GROUP BY 1, 2"; + +EXECUTE st1; +EXECUTE st1; + +set @@optimizer_switch = @old_optimizer_switch; + +drop table t1, t2, t3; + + +--echo # +--echo # LP BUG#611382 RQG: Query returns extra rows when executed with materialization=on +--echo # + +CREATE TABLE t1 ( f4 varchar(1)) ENGINE=MyISAM; +INSERT INTO t1 VALUES (NULL); +CREATE TABLE t2 ( f2 date, f3 varchar(1), f4 varchar(1)) ; +INSERT INTO t2 VALUES ('2005-05-03','c','c'),('1900-01-01','d','d'); +CREATE TABLE t3 ( f3 varchar(1)) ; +INSERT INTO t3 VALUES ('c'); + +set @old_optimizer_switch = @@optimizer_switch; + +set @@optimizer_switch = 'materialization=on,in_to_exists=off,semijoin=off'; + +EXPLAIN SELECT t1.f4 +FROM t1 JOIN ( t2 JOIN t3 ON t3.f3 = t2.f4 ) ON t3.f3 = t2.f3 +WHERE t1.f4 IN ( SELECT f4 FROM t2 ) ; + +SELECT t1.f4 +FROM t1 JOIN ( t2 JOIN t3 ON t3.f3 = t2.f4 ) ON t3.f3 = t2.f3 +WHERE t1.f4 IN ( SELECT f4 FROM t2 ) ; + +set @@optimizer_switch = 'materialization=off,in_to_exists=on,semijoin=off'; + +EXPLAIN SELECT t1.f4 +FROM t1 JOIN ( t2 JOIN t3 ON t3.f3 = t2.f4 ) ON t3.f3 = t2.f3 +WHERE t1.f4 IN ( SELECT f4 FROM t2 ) ; + +SELECT t1.f4 +FROM t1 JOIN ( t2 JOIN t3 ON t3.f3 = t2.f4 ) ON t3.f3 = t2.f3 +WHERE t1.f4 IN ( SELECT f4 FROM t2 ) ; + +set @@optimizer_switch = @old_optimizer_switch; + +drop table t1, t2, t3; + + +--echo # +--echo # LP BUG#782305: Wrong result/valgrind warning in Item_sum_hybrid::any_value() +--echo # + +CREATE TABLE t1 ( f1 int) ; +INSERT INTO t1 VALUES (2),(3); +CREATE TABLE t2 (f2 int) ; +INSERT INTO t2 VALUES (2),(3); + +PREPARE st1 FROM ' +SELECT * FROM t2 +WHERE f2 <= SOME ( SELECT f1 FROM t1 ); +'; +EXECUTE st1; +EXECUTE st1; + +PREPARE st2 FROM ' +SELECT * FROM t2 +WHERE f2 <= SOME (SELECT f1-2 FROM t1 UNION SELECT f1-1 FROM t1); +'; +EXECUTE st2; +EXECUTE st2; + +drop table t1, t2; + + +set optimizer_switch=@subselect4_tmp; diff --git a/mysql-test/t/subselect_cache.test b/mysql-test/t/subselect_cache.test index b83ab27e03e..47cf50e63d2 100644 --- a/mysql-test/t/subselect_cache.test +++ b/mysql-test/t/subselect_cache.test @@ -1566,6 +1566,7 @@ FROM t2 ) AND table1 .`col_varchar_key` OR table1 .`pk` ; drop table t1,t2; set @@optimizer_switch= default; +set optimizer_switch='subquery_cache=on'; # --echo # LP BUG#615378 (incorrect NULL result returning in Item_cache) # @@ -1597,6 +1598,8 @@ CREATE TABLE `t3` ( ) DEFAULT CHARSET=latin1; INSERT INTO `t3` VALUES (1,'w'); +# We may get warnings about 'h' not beeing a double here +--disable_warnings SELECT SUM( DISTINCT table2 . `pk` ) AS field2 , (SELECT SUM( SUBQUERY1_t2 . `pk` ) AS SUBQUERY1_field1 FROM t2 AS SUBQUERY1_t2 STRAIGHT_JOIN @@ -1609,5 +1612,56 @@ FROM ( t1 AS table1 LEFT JOIN WHERE ( table1 . `pk` < 5 ) OR ( table1 . `col_varchar_key` IS NOT NULL) GROUP BY field3 HAVING (field3 <= 'h' AND field2 != 4) ; +--enable_warnings +drop tables t1, t2, t3; + +--echo # +--echo # Test aggregate functions as parameters to subquery cache +--echo # + +CREATE TABLE t1 ( a INT, b INT, c INT, KEY (a, b)); + +INSERT INTO t1 VALUES + ( 1, 1, 1 ), + ( 1, 2, 2 ), + ( 1, 3, 3 ), + ( 1, 4, 6 ), + ( 1, 5, 5 ), + ( 1, 9, 13 ), + + ( 2, 1, 6 ), + ( 2, 2, 7 ), + ( 2, 3, 8 ); + +SELECT a, AVG(t1.b), +(SELECT t11.c FROM t1 t11 WHERE t11.a = t1.a AND t11.b = AVG(t1.b)) AS t11c +FROM t1 GROUP BY a; + +DROP TABLE t1; + +--echo # +--echo # Test of LP BUG#800696 (deleting list of Items (OR arguments) +--echo # in optimization) +--echo # + +set optimizer_switch='subquery_cache=on,in_to_exists=on'; +CREATE TABLE t1 ( f3 int) ; +INSERT INTO t1 VALUES (0),(0); + +CREATE TABLE t3 ( f3 int) ; +INSERT INTO t3 VALUES (0),(0); + +CREATE TABLE t2 ( f1 int, f2 int, f3 int) ; +INSERT INTO t2 VALUES (7,0,0); + +SELECT * +FROM t2, t3 +WHERE t2.f2 OR t3.f3 IN +( +SELECT t2.f2 +FROM t1 +WHERE t2.f1 OR t2.f3 ); drop tables t1, t2, t3; +--echo # restore default +set @@optimizer_switch= default; diff --git a/mysql-test/t/subselect_extra.test b/mysql-test/t/subselect_extra.test new file mode 100644 index 00000000000..466f254e6ad --- /dev/null +++ b/mysql-test/t/subselect_extra.test @@ -0,0 +1,278 @@ +# +# This file is for tests for other features that happen to use +# subqueries. The idea is that one should be able to run +# +# ./mysql-test-run t/subselect*.test +# +# and get as much subquery testing as possible. +# + +--disable_warnings +drop table if exists t1,t2,t3,t4; +--enable_warnings + +set @subselect_extra_tmp=@@optimizer_switch; +set optimizer_switch='semijoin=on,firstmatch=on,loosescan=on'; + + +--echo # From explain.test: +--echo # +--echo # Bug#37870: Usage of uninitialized value caused failed assertion. +--echo # +create table t1 (dt datetime not null, t time not null); +create table t2 (dt datetime not null); +insert into t1 values ('2001-01-01 1:1:1', '1:1:1'), +('2001-01-01 1:1:1', '1:1:1'); +insert into t2 values ('2001-01-01 1:1:1'), ('2001-01-01 1:1:1'); +flush tables; +EXPLAIN SELECT OUTR.dt FROM t1 AS OUTR WHERE OUTR.dt IN (SELECT INNR.dt FROM t2 AS INNR WHERE OUTR.dt IS NULL ); +flush tables; +SELECT OUTR.dt FROM t1 AS OUTR WHERE OUTR.dt IN (SELECT INNR.dt FROM t2 AS INNR WHERE OUTR.dt IS NULL ); +flush tables; +EXPLAIN SELECT OUTR.dt FROM t1 AS OUTR WHERE OUTR.dt IN ( SELECT INNR.dt FROM t2 AS INNR WHERE OUTR.t < '2005-11-13 7:41:31' ); +flush tables; +SELECT OUTR.dt FROM t1 AS OUTR WHERE OUTR.dt IN ( SELECT INNR.dt FROM t2 AS INNR WHERE OUTR.t < '2005-11-13 7:41:31' ); +drop tables t1, t2; + +--echo # From type_datetime.test: +--echo # +--echo # Bug #32694: NOT NULL table field in a subquery produces invalid results +--echo # +create table t1 (id int(10) not null, cur_date datetime not null); +create table t2 (id int(10) not null, cur_date date not null); +insert into t1 (id, cur_date) values (1, '2007-04-25 18:30:22'); +insert into t2 (id, cur_date) values (1, '2007-04-25'); + +explain extended +select * from t1 +where id in (select id from t1 as x1 where (t1.cur_date is null)); +select * from t1 +where id in (select id from t1 as x1 where (t1.cur_date is null)); + +explain extended +select * from t2 +where id in (select id from t2 as x1 where (t2.cur_date is null)); +select * from t2 +where id in (select id from t2 as x1 where (t2.cur_date is null)); + +insert into t1 (id, cur_date) values (2, '2007-04-26 18:30:22'); +insert into t2 (id, cur_date) values (2, '2007-04-26'); + +explain extended +select * from t1 +where id in (select id from t1 as x1 where (t1.cur_date is null)); +select * from t1 +where id in (select id from t1 as x1 where (t1.cur_date is null)); + +explain extended +select * from t2 +where id in (select id from t2 as x1 where (t2.cur_date is null)); +select * from t2 +where id in (select id from t2 as x1 where (t2.cur_date is null)); + +drop table t1,t2; + +--echo # +--echo # From group_min_max.test +--echo # +create table t1 ( + a1 char(64), a2 char(64), b char(16), c char(16) not null, d char(16), dummy char(64) default ' ' +); + +insert into t1 (a1, a2, b, c, d) values +('a','a','a','a111','xy1'),('a','a','a','b111','xy2'),('a','a','a','c111','xy3'),('a','a','a','d111','xy4'), +('a','a','b','e112','xy1'),('a','a','b','f112','xy2'),('a','a','b','g112','xy3'),('a','a','b','h112','xy4'), +('a','b','a','i121','xy1'),('a','b','a','j121','xy2'),('a','b','a','k121','xy3'),('a','b','a','l121','xy4'), +('a','b','b','m122','xy1'),('a','b','b','n122','xy2'),('a','b','b','o122','xy3'),('a','b','b','p122','xy4'), +('b','a','a','a211','xy1'),('b','a','a','b211','xy2'),('b','a','a','c211','xy3'),('b','a','a','d211','xy4'), +('b','a','b','e212','xy1'),('b','a','b','f212','xy2'),('b','a','b','g212','xy3'),('b','a','b','h212','xy4'), +('b','b','a','i221','xy1'),('b','b','a','j221','xy2'),('b','b','a','k221','xy3'),('b','b','a','l221','xy4'), +('b','b','b','m222','xy1'),('b','b','b','n222','xy2'),('b','b','b','o222','xy3'),('b','b','b','p222','xy4'), +('c','a','a','a311','xy1'),('c','a','a','b311','xy2'),('c','a','a','c311','xy3'),('c','a','a','d311','xy4'), +('c','a','b','e312','xy1'),('c','a','b','f312','xy2'),('c','a','b','g312','xy3'),('c','a','b','h312','xy4'), +('c','b','a','i321','xy1'),('c','b','a','j321','xy2'),('c','b','a','k321','xy3'),('c','b','a','l321','xy4'), +('c','b','b','m322','xy1'),('c','b','b','n322','xy2'),('c','b','b','o322','xy3'),('c','b','b','p322','xy4'), +('d','a','a','a411','xy1'),('d','a','a','b411','xy2'),('d','a','a','c411','xy3'),('d','a','a','d411','xy4'), +('d','a','b','e412','xy1'),('d','a','b','f412','xy2'),('d','a','b','g412','xy3'),('d','a','b','h412','xy4'), +('d','b','a','i421','xy1'),('d','b','a','j421','xy2'),('d','b','a','k421','xy3'),('d','b','a','l421','xy4'), +('d','b','b','m422','xy1'),('d','b','b','n422','xy2'),('d','b','b','o422','xy3'),('d','b','b','p422','xy4'), +('a','a','a','a111','xy1'),('a','a','a','b111','xy2'),('a','a','a','c111','xy3'),('a','a','a','d111','xy4'), +('a','a','b','e112','xy1'),('a','a','b','f112','xy2'),('a','a','b','g112','xy3'),('a','a','b','h112','xy4'), +('a','b','a','i121','xy1'),('a','b','a','j121','xy2'),('a','b','a','k121','xy3'),('a','b','a','l121','xy4'), +('a','b','b','m122','xy1'),('a','b','b','n122','xy2'),('a','b','b','o122','xy3'),('a','b','b','p122','xy4'), +('b','a','a','a211','xy1'),('b','a','a','b211','xy2'),('b','a','a','c211','xy3'),('b','a','a','d211','xy4'), +('b','a','b','e212','xy1'),('b','a','b','f212','xy2'),('b','a','b','g212','xy3'),('b','a','b','h212','xy4'), +('b','b','a','i221','xy1'),('b','b','a','j221','xy2'),('b','b','a','k221','xy3'),('b','b','a','l221','xy4'), +('b','b','b','m222','xy1'),('b','b','b','n222','xy2'),('b','b','b','o222','xy3'),('b','b','b','p222','xy4'), +('c','a','a','a311','xy1'),('c','a','a','b311','xy2'),('c','a','a','c311','xy3'),('c','a','a','d311','xy4'), +('c','a','b','e312','xy1'),('c','a','b','f312','xy2'),('c','a','b','g312','xy3'),('c','a','b','h312','xy4'), +('c','b','a','i321','xy1'),('c','b','a','j321','xy2'),('c','b','a','k321','xy3'),('c','b','a','l321','xy4'), +('c','b','b','m322','xy1'),('c','b','b','n322','xy2'),('c','b','b','o322','xy3'),('c','b','b','p322','xy4'), +('d','a','a','a411','xy1'),('d','a','a','b411','xy2'),('d','a','a','c411','xy3'),('d','a','a','d411','xy4'), +('d','a','b','e412','xy1'),('d','a','b','f412','xy2'),('d','a','b','g412','xy3'),('d','a','b','h412','xy4'), +('d','b','a','i421','xy1'),('d','b','a','j421','xy2'),('d','b','a','k421','xy3'),('d','b','a','l421','xy4'), +('d','b','b','m422','xy1'),('d','b','b','n422','xy2'),('d','b','b','o422','xy3'),('d','b','b','p422','xy4'); + +create index idx_t1_0 on t1 (a1); +create index idx_t1_1 on t1 (a1,a2,b,c); +create index idx_t1_2 on t1 (a1,a2,b); +analyze table t1; + +# t2 is the same as t1, but with some NULLs in the MIN/MAX column, and +# one more nullable attribute + +create table t2 ( + a1 char(64), a2 char(64) not null, b char(16), c char(16), d char(16), dummy char(64) default ' ' +); +insert into t2 select * from t1; +# add few rows with NULL's in the MIN/MAX column +insert into t2 (a1, a2, b, c, d) values +('a','a',NULL,'a777','xyz'),('a','a',NULL,'a888','xyz'),('a','a',NULL,'a999','xyz'), +('a','a','a',NULL,'xyz'), +('a','a','b',NULL,'xyz'), +('a','b','a',NULL,'xyz'), +('c','a',NULL,'c777','xyz'),('c','a',NULL,'c888','xyz'),('c','a',NULL,'c999','xyz'), +('d','b','b',NULL,'xyz'), +('e','a','a',NULL,'xyz'),('e','a','a',NULL,'xyz'),('e','a','a',NULL,'xyz'),('e','a','a',NULL,'xyz'), +('e','a','b',NULL,'xyz'),('e','a','b',NULL,'xyz'),('e','a','b',NULL,'xyz'),('e','a','b',NULL,'xyz'), +('a','a',NULL,'a777','xyz'),('a','a',NULL,'a888','xyz'),('a','a',NULL,'a999','xyz'), +('a','a','a',NULL,'xyz'), +('a','a','b',NULL,'xyz'), +('a','b','a',NULL,'xyz'), +('c','a',NULL,'c777','xyz'),('c','a',NULL,'c888','xyz'),('c','a',NULL,'c999','xyz'), +('d','b','b',NULL,'xyz'), +('e','a','a',NULL,'xyz'),('e','a','a',NULL,'xyz'),('e','a','a',NULL,'xyz'),('e','a','a',NULL,'xyz'), +('e','a','b',NULL,'xyz'),('e','a','b',NULL,'xyz'),('e','a','b',NULL,'xyz'),('e','a','b',NULL,'xyz'); + +create index idx_t2_0 on t2 (a1); +create index idx_t2_1 on t2 (a1,a2,b,c); +create index idx_t2_2 on t2 (a1,a2,b); +analyze table t2; + +# Table t3 is the same as t1, but with smaller column lenghts. +# This allows to test different branches of the cost computation procedure +# when the number of keys per block are less than the number of keys in the +# sub-groups formed by predicates over non-group attributes. + +create table t3 ( + a1 char(1), a2 char(1), b char(1), c char(4) not null, d char(3), dummy char(1) default ' ' +); + +insert into t3 (a1, a2, b, c, d) values +('a','a','a','a111','xy1'),('a','a','a','b111','xy2'),('a','a','a','c111','xy3'),('a','a','a','d111','xy4'), +('a','a','b','e112','xy1'),('a','a','b','f112','xy2'),('a','a','b','g112','xy3'),('a','a','b','h112','xy4'), +('a','b','a','i121','xy1'),('a','b','a','j121','xy2'),('a','b','a','k121','xy3'),('a','b','a','l121','xy4'), +('a','b','b','m122','xy1'),('a','b','b','n122','xy2'),('a','b','b','o122','xy3'),('a','b','b','p122','xy4'), +('b','a','a','a211','xy1'),('b','a','a','b211','xy2'),('b','a','a','c211','xy3'),('b','a','a','d211','xy4'), +('b','a','b','e212','xy1'),('b','a','b','f212','xy2'),('b','a','b','g212','xy3'),('b','a','b','h212','xy4'), +('b','b','a','i221','xy1'),('b','b','a','j221','xy2'),('b','b','a','k221','xy3'),('b','b','a','l221','xy4'), +('b','b','b','m222','xy1'),('b','b','b','n222','xy2'),('b','b','b','o222','xy3'),('b','b','b','p222','xy4'), +('c','a','a','a311','xy1'),('c','a','a','b311','xy2'),('c','a','a','c311','xy3'),('c','a','a','d311','xy4'), +('c','a','b','e312','xy1'),('c','a','b','f312','xy2'),('c','a','b','g312','xy3'),('c','a','b','h312','xy4'), +('c','b','a','i321','xy1'),('c','b','a','j321','xy2'),('c','b','a','k321','xy3'),('c','b','a','l321','xy4'), +('c','b','b','m322','xy1'),('c','b','b','n322','xy2'),('c','b','b','o322','xy3'),('c','b','b','p322','xy4'); +insert into t3 (a1, a2, b, c, d) values +('a','a','a','a111','xy1'),('a','a','a','b111','xy2'),('a','a','a','c111','xy3'),('a','a','a','d111','xy4'), +('a','a','b','e112','xy1'),('a','a','b','f112','xy2'),('a','a','b','g112','xy3'),('a','a','b','h112','xy4'), +('a','b','a','i121','xy1'),('a','b','a','j121','xy2'),('a','b','a','k121','xy3'),('a','b','a','l121','xy4'), +('a','b','b','m122','xy1'),('a','b','b','n122','xy2'),('a','b','b','o122','xy3'),('a','b','b','p122','xy4'), +('b','a','a','a211','xy1'),('b','a','a','b211','xy2'),('b','a','a','c211','xy3'),('b','a','a','d211','xy4'), +('b','a','b','e212','xy1'),('b','a','b','f212','xy2'),('b','a','b','g212','xy3'),('b','a','b','h212','xy4'), +('b','b','a','i221','xy1'),('b','b','a','j221','xy2'),('b','b','a','k221','xy3'),('b','b','a','l221','xy4'), +('b','b','b','m222','xy1'),('b','b','b','n222','xy2'),('b','b','b','o222','xy3'),('b','b','b','p222','xy4'), +('c','a','a','a311','xy1'),('c','a','a','b311','xy2'),('c','a','a','c311','xy3'),('c','a','a','d311','xy4'), +('c','a','b','e312','xy1'),('c','a','b','f312','xy2'),('c','a','b','g312','xy3'),('c','a','b','h312','xy4'), +('c','b','a','i321','xy1'),('c','b','a','j321','xy2'),('c','b','a','k321','xy3'),('c','b','a','l321','xy4'), +('c','b','b','m322','xy1'),('c','b','b','n322','xy2'),('c','b','b','o322','xy3'),('c','b','b','p322','xy4'); +insert into t3 (a1, a2, b, c, d) values +('a','a','a','a111','xy1'),('a','a','a','b111','xy2'),('a','a','a','c111','xy3'),('a','a','a','d111','xy4'), +('a','a','b','e112','xy1'),('a','a','b','f112','xy2'),('a','a','b','g112','xy3'),('a','a','b','h112','xy4'), +('a','b','a','i121','xy1'),('a','b','a','j121','xy2'),('a','b','a','k121','xy3'),('a','b','a','l121','xy4'), +('a','b','b','m122','xy1'),('a','b','b','n122','xy2'),('a','b','b','o122','xy3'),('a','b','b','p122','xy4'), +('b','a','a','a211','xy1'),('b','a','a','b211','xy2'),('b','a','a','c211','xy3'),('b','a','a','d211','xy4'), +('b','a','b','e212','xy1'),('b','a','b','f212','xy2'),('b','a','b','g212','xy3'),('b','a','b','h212','xy4'), +('b','b','a','i221','xy1'),('b','b','a','j221','xy2'),('b','b','a','k221','xy3'),('b','b','a','l221','xy4'), +('b','b','b','m222','xy1'),('b','b','b','n222','xy2'),('b','b','b','o222','xy3'),('b','b','b','p222','xy4'), +('c','a','a','a311','xy1'),('c','a','a','b311','xy2'),('c','a','a','c311','xy3'),('c','a','a','d311','xy4'), +('c','a','b','e312','xy1'),('c','a','b','f312','xy2'),('c','a','b','g312','xy3'),('c','a','b','h312','xy4'), +('c','b','a','i321','xy1'),('c','b','a','j321','xy2'),('c','b','a','k321','xy3'),('c','b','a','l321','xy4'), +('c','b','b','m322','xy1'),('c','b','b','n322','xy2'),('c','b','b','o322','xy3'),('c','b','b','p322','xy4'); +insert into t3 (a1, a2, b, c, d) values +('a','a','a','a111','xy1'),('a','a','a','b111','xy2'),('a','a','a','c111','xy3'),('a','a','a','d111','xy4'), +('a','a','b','e112','xy1'),('a','a','b','f112','xy2'),('a','a','b','g112','xy3'),('a','a','b','h112','xy4'), +('a','b','a','i121','xy1'),('a','b','a','j121','xy2'),('a','b','a','k121','xy3'),('a','b','a','l121','xy4'), +('a','b','b','m122','xy1'),('a','b','b','n122','xy2'),('a','b','b','o122','xy3'),('a','b','b','p122','xy4'), +('b','a','a','a211','xy1'),('b','a','a','b211','xy2'),('b','a','a','c211','xy3'),('b','a','a','d211','xy4'), +('b','a','b','e212','xy1'),('b','a','b','f212','xy2'),('b','a','b','g212','xy3'),('b','a','b','h212','xy4'), +('b','b','a','i221','xy1'),('b','b','a','j221','xy2'),('b','b','a','k221','xy3'),('b','b','a','l221','xy4'), +('b','b','b','m222','xy1'),('b','b','b','n222','xy2'),('b','b','b','o222','xy3'),('b','b','b','p222','xy4'), +('c','a','a','a311','xy1'),('c','a','a','b311','xy2'),('c','a','a','c311','xy3'),('c','a','a','d311','xy4'), +('c','a','b','e312','xy1'),('c','a','b','f312','xy2'),('c','a','b','g312','xy3'),('c','a','b','h312','xy4'), +('c','b','a','i321','xy1'),('c','b','a','j321','xy2'),('c','b','a','k321','xy3'),('c','b','a','l321','xy4'), +('c','b','b','m322','xy1'),('c','b','b','n322','xy2'),('c','b','b','o322','xy3'),('c','b','b','p322','xy4'); + +create index idx_t3_0 on t3 (a1); +create index idx_t3_1 on t3 (a1,a2,b,c); +create index idx_t3_2 on t3 (a1,a2,b); +analyze table t3; + + +explain select a1,a2,b,c,min(c), max(c) from t1 +where exists ( select * from t2 + where t2.c in (select c from t3 where t3.c > t1.b) and + t2.c > 'b1' ) +group by a1,a2,b; + +select a1,a2,b,c,min(c), max(c) from t1 +where exists ( select * from t2 + where t2.c in (select c from t3 where t3.c > t1.b) and + t2.c > 'b1' ) +group by a1,a2,b; + +explain select a1,a2,b,c,min(c), max(c) from t1 +where exists ( select * from t2 + where t2.c in (select c from t3 where t3.c > t1.c) and + t2.c > 'b1' ) +group by a1,a2,b; + +select a1,a2,b,c,min(c), max(c) from t1 +where exists ( select * from t2 + where t2.c in (select c from t3 where t3.c > t1.c) and + t2.c > 'b1' ) +group by a1,a2,b; + +drop table t1, t2, t3; + +--echo # +--echo # From group_by.test +--echo # + +--echo # Bug #21174: Index degrades sort performance and +--echo # optimizer does not honor IGNORE INDEX. +--echo # a.k.a WL3527. +--echo # +CREATE TABLE t1 (a INT, b INT, + PRIMARY KEY (a), + KEY i2(a,b)); +INSERT INTO t1 VALUES (1,1),(2,2),(3,3),(4,4),(5,5),(6,6),(7,7),(8,8); +INSERT INTO t1 SELECT a + 8,b FROM t1; +INSERT INTO t1 SELECT a + 16,b FROM t1; +INSERT INTO t1 SELECT a + 32,b FROM t1; +INSERT INTO t1 SELECT a + 64,b FROM t1; +INSERT INTO t1 SELECT a + 128,b FROM t1 limit 16; +ANALYZE TABLE t1; +EXPLAIN SELECT 1 FROM t1 WHERE a IN + (SELECT a FROM t1 USE INDEX (i2) IGNORE INDEX (i2)); + +CREATE TABLE t2 (a INT, b INT, KEY(a)); +INSERT INTO t2 VALUES (1, 1), (2, 2), (3,3), (4,4); +EXPLAIN SELECT a, SUM(b) FROM t2 GROUP BY a LIMIT 2; +EXPLAIN SELECT a, SUM(b) FROM t2 IGNORE INDEX (a) GROUP BY a LIMIT 2; + +EXPLAIN SELECT 1 FROM t2 WHERE a IN + (SELECT a FROM t1 USE INDEX (i2) IGNORE INDEX (i2)); +DROP TABLE t1, t2; + + +set optimizer_switch= @subselect_extra_tmp; + diff --git a/mysql-test/t/subselect_innodb.test b/mysql-test/t/subselect_innodb.test index 73491417e0c..3e2914eaef4 100644 --- a/mysql-test/t/subselect_innodb.test +++ b/mysql-test/t/subselect_innodb.test @@ -1,5 +1,7 @@ -- source include/have_innodb.inc +set @subselect_innodb_tmp=@@optimizer_switch; +set optimizer_switch='mrr=on,mrr_sort_keys=on,index_condition_pushdown=on'; --disable_warnings drop table if exists t1,t2,t3; --enable_warnings @@ -247,3 +249,6 @@ CREATE TABLE t1(a date, b int, unique(b), unique(a), key(b)) engine=innodb; INSERT INTO t1 VALUES ('2011-05-13', 0); SELECT * FROM t1 WHERE b < (SELECT CAST(a as date) FROM t1 GROUP BY a); DROP TABLE t1; + +# Cleanups +set optimizer_switch=@subselect_innodb_tmp; diff --git a/mysql-test/t/subselect_mat.test b/mysql-test/t/subselect_mat.test index 0209bf66a57..a70fb4783c5 100644 --- a/mysql-test/t/subselect_mat.test +++ b/mysql-test/t/subselect_mat.test @@ -3,873 +3,102 @@ # (WL#1110: Subquery optimization: materialization) # ---disable_warnings -drop table if exists t1, t2, t3, t1i, t2i, t3i; -drop view if exists v1, v2, v1m, v2m; ---enable_warnings - -create table t1 (a1 char(8), a2 char(8)); -create table t2 (b1 char(8), b2 char(8)); -create table t3 (c1 char(8), c2 char(8)); - -insert into t1 values ('1 - 00', '2 - 00'); -insert into t1 values ('1 - 01', '2 - 01'); -insert into t1 values ('1 - 02', '2 - 02'); - -insert into t2 values ('1 - 01', '2 - 01'); -insert into t2 values ('1 - 01', '2 - 01'); -insert into t2 values ('1 - 02', '2 - 02'); -insert into t2 values ('1 - 02', '2 - 02'); -insert into t2 values ('1 - 03', '2 - 03'); - -insert into t3 values ('1 - 01', '2 - 01'); -insert into t3 values ('1 - 02', '2 - 02'); -insert into t3 values ('1 - 03', '2 - 03'); -insert into t3 values ('1 - 04', '2 - 04'); - -# Indexed columns -create table t1i (a1 char(8), a2 char(8)); -create table t2i (b1 char(8), b2 char(8)); -create table t3i (c1 char(8), c2 char(8)); -create index it1i1 on t1i (a1); -create index it1i2 on t1i (a2); -create index it1i3 on t1i (a1, a2); - -create index it2i1 on t2i (b1); -create index it2i2 on t2i (b2); -create index it2i3 on t2i (b1, b2); - -create index it3i1 on t3i (c1); -create index it3i2 on t3i (c2); -create index it3i3 on t3i (c1, c2); - -insert into t1i select * from t1; -insert into t2i select * from t2; -insert into t3i select * from t3; # force the use of materialization -set @@optimizer_switch='semijoin=off'; - -/****************************************************************************** -* Simple tests. -******************************************************************************/ -# non-indexed nullable fields -explain extended -select * from t1 where a1 in (select b1 from t2 where b1 > '0'); -select * from t1 where a1 in (select b1 from t2 where b1 > '0'); - -explain extended -select * from t1 where a1 in (select b1 from t2 where b1 > '0' group by b1); -select * from t1 where a1 in (select b1 from t2 where b1 > '0' group by b1); - -explain extended -select * from t1 where (a1, a2) in (select b1, b2 from t2 where b1 > '0' group by b1, b2); -select * from t1 where (a1, a2) in (select b1, b2 from t2 where b1 > '0' group by b1, b2); - -explain extended -select * from t1 where (a1, a2) in (select b1, min(b2) from t2 where b1 > '0' group by b1); -select * from t1 where (a1, a2) in (select b1, min(b2) from t2 where b1 > '0' group by b1); - -# indexed columns -explain extended -select * from t1i where a1 in (select b1 from t2i where b1 > '0'); -select * from t1i where a1 in (select b1 from t2i where b1 > '0'); - -explain extended -select * from t1i where a1 in (select b1 from t2i where b1 > '0' group by b1); -select * from t1i where a1 in (select b1 from t2i where b1 > '0' group by b1); - -explain extended -select * from t1i where (a1, a2) in (select b1, b2 from t2i where b1 > '0'); -select * from t1i where (a1, a2) in (select b1, b2 from t2i where b1 > '0'); - -explain extended -select * from t1i where (a1, a2) in (select b1, b2 from t2i where b1 > '0' group by b1, b2); -select * from t1i where (a1, a2) in (select b1, b2 from t2i where b1 > '0' group by b1, b2); - -explain extended -select * from t1i where (a1, a2) in (select b1, min(b2) from t2i where b1 > '0' group by b1); -select * from t1i where (a1, a2) in (select b1, min(b2) from t2i where b1 > '0' group by b1); - -# BUG#31639: Wrong plan for uncorrelated subquery when loose scan is applicable. -explain extended -select * from t1 where (a1, a2) in (select b1, max(b2) from t2i group by b1); -select * from t1 where (a1, a2) in (select b1, max(b2) from t2i group by b1); - -prepare st1 from "explain select * from t1 where (a1, a2) in (select b1, max(b2) from t2i group by b1)"; -execute st1; -execute st1; -prepare st2 from "select * from t1 where (a1, a2) in (select b1, max(b2) from t2i group by b1)"; -execute st2; -execute st2; - -explain extended -select * from t1 where (a1, a2) in (select b1, min(b2) from t2i where b1 > '0' group by b1); -select * from t1 where (a1, a2) in (select b1, min(b2) from t2i where b1 > '0' group by b1); --- error 1235 -select * from t1 where (a1, a2) in (select b1, min(b2) from t2i limit 1,1); - -# test re-optimization/re-execution with different execution methods -# prepare once, exec with different modes -set @@optimizer_switch='default,semijoin=off'; -prepare st1 from -"select * from t1 where (a1, a2) in (select b1, min(b2) from t2 where b1 > '0' group by b1)"; -set @@optimizer_switch='default,materialization=off'; -execute st1; -set @@optimizer_switch='default,semijoin=off'; -execute st1; - -set @@optimizer_switch='default,materialization=off'; -prepare st1 from -"select * from t1 where (a1, a2) in (select b1, min(b2) from t2 where b1 > '0' group by b1)"; -set @@optimizer_switch='default,semijoin=off'; -execute st1; -set @@optimizer_switch='default,materialization=off'; -execute st1; -set @@optimizer_switch='default,semijoin=off'; - -# materialize the result of ORDER BY -# non-indexed fields -explain extended -select * from t1 where (a1, a2) in (select b1, b2 from t2 order by b1, b2); -select * from t1 where (a1, a2) in (select b1, b2 from t2 order by b1, b2); -# indexed fields -explain extended -select * from t1i where (a1, a2) in (select b1, b2 from t2i order by b1, b2); -select * from t1i where (a1, a2) in (select b1, b2 from t2i order by b1, b2); - -/****************************************************************************** -* Views, UNIONs, several levels of nesting. -******************************************************************************/ -# materialize the result of subquery over temp-table view - -create algorithm=merge view v1 as -select b1, c2 from t2, t3 where b2 > c2; - -create algorithm=merge view v2 as -select b1, c2 from t2, t3 group by b2, c2; - -create algorithm=temptable view v1m as -select b1, c2 from t2, t3 where b2 > c2; - -create algorithm=temptable view v2m as -select b1, c2 from t2, t3 group by b2, c2; - -select * from v1 where (c2, b1) in (select c2, b1 from v2 where b1 is not null); -select * from v1 where (c2, b1) in (select distinct c2, b1 from v2 where b1 is not null); - -select * from v1m where (c2, b1) in (select c2, b1 from v2m where b1 is not null); -select * from v1m where (c2, b1) in (select distinct c2, b1 from v2m where b1 is not null); - -drop view v1, v2, v1m, v2m; - -# nested subqueries, views -explain extended -select * from t1 -where (a1, a2) in (select b1, b2 from t2 where b1 > '0') and - (a1, a2) in (select c1, c2 from t3 - where (c1, c2) in (select b1, b2 from t2i where b2 > '0')); -select * from t1 -where (a1, a2) in (select b1, b2 from t2 where b1 > '0') and - (a1, a2) in (select c1, c2 from t3 - where (c1, c2) in (select b1, b2 from t2i where b2 > '0')); - -explain extended -select * from t1i -where (a1, a2) in (select b1, b2 from t2i where b1 > '0') and - (a1, a2) in (select c1, c2 from t3i - where (c1, c2) in (select b1, b2 from t2i where b2 > '0')); -select * from t1i -where (a1, a2) in (select b1, b2 from t2i where b1 > '0') and - (a1, a2) in (select c1, c2 from t3i - where (c1, c2) in (select b1, b2 from t2i where b2 > '0')); - -explain extended -select * from t1 -where (a1, a2) in (select b1, b2 from t2 - where b2 in (select c2 from t3 where c2 LIKE '%02') or - b2 in (select c2 from t3 where c2 LIKE '%03')) and - (a1, a2) in (select c1, c2 from t3 - where (c1, c2) in (select b1, b2 from t2i where b2 > '0')); -select * from t1 -where (a1, a2) in (select b1, b2 from t2 - where b2 in (select c2 from t3 where c2 LIKE '%02') or - b2 in (select c2 from t3 where c2 LIKE '%03')) and - (a1, a2) in (select c1, c2 from t3 - where (c1, c2) in (select b1, b2 from t2i where b2 > '0')); - -# as above with correlated innermost subquery -explain extended -select * from t1 -where (a1, a2) in (select b1, b2 from t2 - where b2 in (select c2 from t3 t3a where c1 = a1) or - b2 in (select c2 from t3 t3b where c2 LIKE '%03')) and - (a1, a2) in (select c1, c2 from t3 t3c - where (c1, c2) in (select b1, b2 from t2i where b2 > '0')); -select * from t1 -where (a1, a2) in (select b1, b2 from t2 - where b2 in (select c2 from t3 t3a where c1 = a1) or - b2 in (select c2 from t3 t3b where c2 LIKE '%03')) and - (a1, a2) in (select c1, c2 from t3 t3c - where (c1, c2) in (select b1, b2 from t2i where b2 > '0')); - - -# multiple levels of nesting subqueries, unions -explain extended -(select * from t1 -where (a1, a2) in (select b1, b2 from t2 - where b2 in (select c2 from t3 where c2 LIKE '%02') or - b2 in (select c2 from t3 where c2 LIKE '%03') - group by b1, b2) and - (a1, a2) in (select c1, c2 from t3 - where (c1, c2) in (select b1, b2 from t2i where b2 > '0'))) -UNION -(select * from t1i -where (a1, a2) in (select b1, b2 from t2i where b1 > '0') and - (a1, a2) in (select c1, c2 from t3i - where (c1, c2) in (select b1, b2 from t2i where b2 > '0'))); - -(select * from t1 -where (a1, a2) in (select b1, b2 from t2 - where b2 in (select c2 from t3 where c2 LIKE '%02') or - b2 in (select c2 from t3 where c2 LIKE '%03') - group by b1, b2) and - (a1, a2) in (select c1, c2 from t3 - where (c1, c2) in (select b1, b2 from t2i where b2 > '0'))) -UNION -(select * from t1i -where (a1, a2) in (select b1, b2 from t2i where b1 > '0') and - (a1, a2) in (select c1, c2 from t3i - where (c1, c2) in (select b1, b2 from t2i where b2 > '0'))); - - -# UNION of subqueries as a subquery (thus it is not computed via materialization) -explain extended -select * from t1 -where (a1, a2) in (select * from t1 where a1 > '0' UNION select * from t2 where b1 < '9') and - (a1, a2) in (select c1, c2 from t3 - where (c1, c2) in (select b1, b2 from t2i where b2 > '0')); -select * from t1 -where (a1, a2) in (select * from t1 where a1 > '0' UNION select * from t2 where b1 < '9') and - (a1, a2) in (select c1, c2 from t3 - where (c1, c2) in (select b1, b2 from t2i where b2 > '0')); -# as above, with a join conditon between the outer references -explain extended -select * from t1, t3 -where (a1, a2) in (select * from t1 where a1 > '0' UNION select * from t2 where b1 < '9') and - (c1, c2) in (select c1, c2 from t3 - where (c1, c2) in (select b1, b2 from t2i where b2 > '0')) and - a1 = c1; -select * from t1, t3 -where (a1, a2) in (select * from t1 where a1 > '0' UNION select * from t2 where b1 < '9') and - (c1, c2) in (select c1, c2 from t3 - where (c1, c2) in (select b1, b2 from t2i where b2 > '0')) and - a1 = c1; - - -/****************************************************************************** -* Negative tests, where materialization should not be applied. -******************************************************************************/ -# UNION in a subquery -explain extended -select * from t3 -where c1 in (select a1 from t1 where a1 > '0' UNION select b1 from t2 where b1 < '9'); -select * from t3 -where c1 in (select a1 from t1 where a1 > '0' UNION select b1 from t2 where b1 < '9'); - -# correlation -explain extended -select * from t1 -where (a1, a2) in (select b1, b2 from t2 - where b2 in (select c2 from t3 t3a where c1 = a1) or - b2 in (select c2 from t3 t3b where c2 LIKE '%03')) and - (a1, a2) in (select c1, c2 from t3 t3c - where (c1, c2) in (select b1, b2 from t2i where b2 > '0' or b2 = a2)); - -# subquery has no tables -explain extended -select * from t1 where (a1, a2) in (select '1 - 01', '2 - 01'); -select * from t1 where (a1, a2) in (select '1 - 01', '2 - 01'); -explain extended -select * from t1 where (a1, a2) in (select '1 - 01', '2 - 01' from dual); -select * from t1 where (a1, a2) in (select '1 - 01', '2 - 01' from dual); - - -/****************************************************************************** -* Subqueries in other uncovered clauses. -******************************************************************************/ - -/* SELECT clause */ -select ((a1,a2) IN (select * from t2 where b2 > '0')) IS NULL from t1; - -/* GROUP BY clause */ -create table columns (col int key); -insert into columns values (1), (2); - -explain extended -select * from t1 group by (select col from columns limit 1); -select * from t1 group by (select col from columns limit 1); - -explain extended -select * from t1 group by (a1 in (select col from columns)); -select * from t1 group by (a1 in (select col from columns)); - -/* ORDER BY clause */ -explain extended -select * from t1 order by (select col from columns limit 1); -select * from t1 order by (select col from columns limit 1); - -/****************************************************************************** -* Column types/sizes that affect materialization. -******************************************************************************/ - -/* - Test that BLOBs are not materialized (except when arguments of some functions). -*/ -# force materialization to be always considered -set @@optimizer_switch='semijoin=off'; -set @prefix_len = 6; - -# BLOB == 16 (small blobs that could be stored in HEAP tables) -set @blob_len = 16; -set @suffix_len = @blob_len - @prefix_len; - -create table t1_16 (a1 blob(16), a2 blob(16)); -create table t2_16 (b1 blob(16), b2 blob(16)); -create table t3_16 (c1 blob(16), c2 blob(16)); - -insert into t1_16 values - (concat('1 - 00', repeat('x', @suffix_len)), concat('2 - 00', repeat('x', @suffix_len))); -insert into t1_16 values - (concat('1 - 01', repeat('x', @suffix_len)), concat('2 - 01', repeat('x', @suffix_len))); -insert into t1_16 values - (concat('1 - 02', repeat('x', @suffix_len)), concat('2 - 02', repeat('x', @suffix_len))); - -insert into t2_16 values - (concat('1 - 01', repeat('x', @suffix_len)), concat('2 - 01', repeat('x', @suffix_len))); -insert into t2_16 values - (concat('1 - 02', repeat('x', @suffix_len)), concat('2 - 02', repeat('x', @suffix_len))); -insert into t2_16 values - (concat('1 - 03', repeat('x', @suffix_len)), concat('2 - 03', repeat('x', @suffix_len))); - -insert into t3_16 values - (concat('1 - 01', repeat('x', @suffix_len)), concat('2 - 01', repeat('x', @suffix_len))); -insert into t3_16 values - (concat('1 - 02', repeat('x', @suffix_len)), concat('2 - 02', repeat('x', @suffix_len))); -insert into t3_16 values - (concat('1 - 03', repeat('x', @suffix_len)), concat('2 - 03', repeat('x', @suffix_len))); -insert into t3_16 values - (concat('1 - 04', repeat('x', @suffix_len)), concat('2 - 04', repeat('x', @suffix_len))); - -# single value transformer -explain extended select left(a1,7), left(a2,7) -from t1_16 -where a1 in (select b1 from t2_16 where b1 > '0'); - -select left(a1,7), left(a2,7) -from t1_16 -where a1 in (select b1 from t2_16 where b1 > '0'); - -# row value transformer -explain extended select left(a1,7), left(a2,7) -from t1_16 -where (a1,a2) in (select b1, b2 from t2_16 where b1 > '0'); - -select left(a1,7), left(a2,7) -from t1_16 -where (a1,a2) in (select b1, b2 from t2_16 where b1 > '0'); - -# string function with a blob argument, the return type may be != blob -explain extended select left(a1,7), left(a2,7) -from t1_16 -where a1 in (select substring(b1,1,16) from t2_16 where b1 > '0'); - -select left(a1,7), left(a2,7) -from t1_16 -where a1 in (select substring(b1,1,16) from t2_16 where b1 > '0'); - -# group_concat with a blob argument - depends on -# the variable group_concat_max_len, and -# convert_blob_length == max_len*collation->mbmaxlen > CONVERT_IF_BIGGER_TO_BLOB -explain extended select left(a1,7), left(a2,7) -from t1_16 -where a1 in (select group_concat(b1) from t2_16 group by b2); - -select left(a1,7), left(a2,7) -from t1_16 -where a1 in (select group_concat(b1) from t2_16 group by b2); - -set @@group_concat_max_len = 256; # anything < (CONVERT_IF_BIGGER_TO_BLOB = 512) - -explain extended select left(a1,7), left(a2,7) -from t1_16 -where a1 in (select group_concat(b1) from t2_16 group by b2); - -select left(a1,7), left(a2,7) -from t1_16 -where a1 in (select group_concat(b1) from t2_16 group by b2); - -# BLOB column at the second (intermediate) level of nesting -explain extended -select * from t1 -where concat(a1,'x') IN - (select left(a1,8) from t1_16 - where (a1, a2) IN - (select t2_16.b1, t2_16.b2 from t2_16, t2 - where t2.b2 = substring(t2_16.b2,1,6) and - t2.b1 IN (select c1 from t3 where c2 > '0'))); - - -drop table t1_16, t2_16, t3_16; - - -# BLOB == 512 (CONVERT_IF_BIGGER_TO_BLOB == 512) -set @blob_len = 512; -set @suffix_len = @blob_len - @prefix_len; - -create table t1_512 (a1 blob(512), a2 blob(512)); -create table t2_512 (b1 blob(512), b2 blob(512)); -create table t3_512 (c1 blob(512), c2 blob(512)); - -insert into t1_512 values - (concat('1 - 00', repeat('x', @suffix_len)), concat('2 - 00', repeat('x', @suffix_len))); -insert into t1_512 values - (concat('1 - 01', repeat('x', @suffix_len)), concat('2 - 01', repeat('x', @suffix_len))); -insert into t1_512 values - (concat('1 - 02', repeat('x', @suffix_len)), concat('2 - 02', repeat('x', @suffix_len))); - -insert into t2_512 values - (concat('1 - 01', repeat('x', @suffix_len)), concat('2 - 01', repeat('x', @suffix_len))); -insert into t2_512 values - (concat('1 - 02', repeat('x', @suffix_len)), concat('2 - 02', repeat('x', @suffix_len))); -insert into t2_512 values - (concat('1 - 03', repeat('x', @suffix_len)), concat('2 - 03', repeat('x', @suffix_len))); - -insert into t3_512 values - (concat('1 - 01', repeat('x', @suffix_len)), concat('2 - 01', repeat('x', @suffix_len))); -insert into t3_512 values - (concat('1 - 02', repeat('x', @suffix_len)), concat('2 - 02', repeat('x', @suffix_len))); -insert into t3_512 values - (concat('1 - 03', repeat('x', @suffix_len)), concat('2 - 03', repeat('x', @suffix_len))); -insert into t3_512 values - (concat('1 - 04', repeat('x', @suffix_len)), concat('2 - 04', repeat('x', @suffix_len))); - -# single value transformer -explain extended select left(a1,7), left(a2,7) -from t1_512 -where a1 in (select b1 from t2_512 where b1 > '0'); - -select left(a1,7), left(a2,7) -from t1_512 -where a1 in (select b1 from t2_512 where b1 > '0'); - -# row value transformer -explain extended select left(a1,7), left(a2,7) -from t1_512 -where (a1,a2) in (select b1, b2 from t2_512 where b1 > '0'); - -select left(a1,7), left(a2,7) -from t1_512 -where (a1,a2) in (select b1, b2 from t2_512 where b1 > '0'); - -# string function with a blob argument, the return type may be != blob -explain extended select left(a1,7), left(a2,7) -from t1_512 -where a1 in (select substring(b1,1,512) from t2_512 where b1 > '0'); - -select left(a1,7), left(a2,7) -from t1_512 -where a1 in (select substring(b1,1,512) from t2_512 where b1 > '0'); - -# group_concat with a blob argument - depends on -# the variable group_concat_max_len, and -# convert_blob_length == max_len*collation->mbmaxlen > CONVERT_IF_BIGGER_TO_BLOB -explain extended select left(a1,7), left(a2,7) -from t1_512 -where a1 in (select group_concat(b1) from t2_512 group by b2); - -select left(a1,7), left(a2,7) -from t1_512 -where a1 in (select group_concat(b1) from t2_512 group by b2); - -set @@group_concat_max_len = 256; # anything < (CONVERT_IF_BIGGER_TO_BLOB = 512) - -explain extended select left(a1,7), left(a2,7) -from t1_512 -where a1 in (select group_concat(b1) from t2_512 group by b2); - -select left(a1,7), left(a2,7) -from t1_512 -where a1 in (select group_concat(b1) from t2_512 group by b2); - -drop table t1_512, t2_512, t3_512; - - -# BLOB == 1024 (group_concat_max_len == 1024) -set @blob_len = 1024; -set @suffix_len = @blob_len - @prefix_len; - -create table t1_1024 (a1 blob(1024), a2 blob(1024)); -create table t2_1024 (b1 blob(1024), b2 blob(1024)); -create table t3_1024 (c1 blob(1024), c2 blob(1024)); - -insert into t1_1024 values - (concat('1 - 00', repeat('x', @suffix_len)), concat('2 - 00', repeat('x', @suffix_len))); -insert into t1_1024 values - (concat('1 - 01', repeat('x', @suffix_len)), concat('2 - 01', repeat('x', @suffix_len))); -insert into t1_1024 values - (concat('1 - 02', repeat('x', @suffix_len)), concat('2 - 02', repeat('x', @suffix_len))); - -insert into t2_1024 values - (concat('1 - 01', repeat('x', @suffix_len)), concat('2 - 01', repeat('x', @suffix_len))); -insert into t2_1024 values - (concat('1 - 02', repeat('x', @suffix_len)), concat('2 - 02', repeat('x', @suffix_len))); -insert into t2_1024 values - (concat('1 - 03', repeat('x', @suffix_len)), concat('2 - 03', repeat('x', @suffix_len))); - -insert into t3_1024 values - (concat('1 - 01', repeat('x', @suffix_len)), concat('2 - 01', repeat('x', @suffix_len))); -insert into t3_1024 values - (concat('1 - 02', repeat('x', @suffix_len)), concat('2 - 02', repeat('x', @suffix_len))); -insert into t3_1024 values - (concat('1 - 03', repeat('x', @suffix_len)), concat('2 - 03', repeat('x', @suffix_len))); -insert into t3_1024 values - (concat('1 - 04', repeat('x', @suffix_len)), concat('2 - 04', repeat('x', @suffix_len))); - -# single value transformer -explain extended select left(a1,7), left(a2,7) -from t1_1024 -where a1 in (select b1 from t2_1024 where b1 > '0'); - -select left(a1,7), left(a2,7) -from t1_1024 -where a1 in (select b1 from t2_1024 where b1 > '0'); - -# row value transformer -explain extended select left(a1,7), left(a2,7) -from t1_1024 -where (a1,a2) in (select b1, b2 from t2_1024 where b1 > '0'); - -select left(a1,7), left(a2,7) -from t1_1024 -where (a1,a2) in (select b1, b2 from t2_1024 where b1 > '0'); - -# string function with a blob argument, the return type may be != blob -explain extended select left(a1,7), left(a2,7) -from t1_1024 -where a1 in (select substring(b1,1,1024) from t2_1024 where b1 > '0'); - -select left(a1,7), left(a2,7) -from t1_1024 -where a1 in (select substring(b1,1,1024) from t2_1024 where b1 > '0'); - -# group_concat with a blob argument - depends on -# the variable group_concat_max_len, and -# convert_blob_length == max_len*collation->mbmaxlen > CONVERT_IF_BIGGER_TO_BLOB -explain extended select left(a1,7), left(a2,7) -from t1_1024 -where a1 in (select group_concat(b1) from t2_1024 group by b2); - -select left(a1,7), left(a2,7) -from t1_1024 -where a1 in (select group_concat(b1) from t2_1024 group by b2); - -set @@group_concat_max_len = 256; # anything < (CONVERT_IF_BIGGER_TO_BLOB = 1024) - -explain extended select left(a1,7), left(a2,7) -from t1_1024 -where a1 in (select group_concat(b1) from t2_1024 group by b2); - -select left(a1,7), left(a2,7) -from t1_1024 -where a1 in (select group_concat(b1) from t2_1024 group by b2); - -drop table t1_1024, t2_1024, t3_1024; - - -# BLOB == 1025 -set @blob_len = 1025; -set @suffix_len = @blob_len - @prefix_len; - -create table t1_1025 (a1 blob(1025), a2 blob(1025)); -create table t2_1025 (b1 blob(1025), b2 blob(1025)); -create table t3_1025 (c1 blob(1025), c2 blob(1025)); - -insert into t1_1025 values - (concat('1 - 00', repeat('x', @suffix_len)), concat('2 - 00', repeat('x', @suffix_len))); -insert into t1_1025 values - (concat('1 - 01', repeat('x', @suffix_len)), concat('2 - 01', repeat('x', @suffix_len))); -insert into t1_1025 values - (concat('1 - 02', repeat('x', @suffix_len)), concat('2 - 02', repeat('x', @suffix_len))); - -insert into t2_1025 values - (concat('1 - 01', repeat('x', @suffix_len)), concat('2 - 01', repeat('x', @suffix_len))); -insert into t2_1025 values - (concat('1 - 02', repeat('x', @suffix_len)), concat('2 - 02', repeat('x', @suffix_len))); -insert into t2_1025 values - (concat('1 - 03', repeat('x', @suffix_len)), concat('2 - 03', repeat('x', @suffix_len))); - -insert into t3_1025 values - (concat('1 - 01', repeat('x', @suffix_len)), concat('2 - 01', repeat('x', @suffix_len))); -insert into t3_1025 values - (concat('1 - 02', repeat('x', @suffix_len)), concat('2 - 02', repeat('x', @suffix_len))); -insert into t3_1025 values - (concat('1 - 03', repeat('x', @suffix_len)), concat('2 - 03', repeat('x', @suffix_len))); -insert into t3_1025 values - (concat('1 - 04', repeat('x', @suffix_len)), concat('2 - 04', repeat('x', @suffix_len))); - -# single value transformer -explain extended select left(a1,7), left(a2,7) -from t1_1025 -where a1 in (select b1 from t2_1025 where b1 > '0'); - -select left(a1,7), left(a2,7) -from t1_1025 -where a1 in (select b1 from t2_1025 where b1 > '0'); - -# row value transformer -explain extended select left(a1,7), left(a2,7) -from t1_1025 -where (a1,a2) in (select b1, b2 from t2_1025 where b1 > '0'); - -select left(a1,7), left(a2,7) -from t1_1025 -where (a1,a2) in (select b1, b2 from t2_1025 where b1 > '0'); - -# string function with a blob argument, the return type may be != blob -explain extended select left(a1,7), left(a2,7) -from t1_1025 -where a1 in (select substring(b1,1,1025) from t2_1025 where b1 > '0'); - -select left(a1,7), left(a2,7) -from t1_1025 -where a1 in (select substring(b1,1,1025) from t2_1025 where b1 > '0'); - -# group_concat with a blob argument - depends on -# the variable group_concat_max_len, and -# convert_blob_length == max_len*collation->mbmaxlen > CONVERT_IF_BIGGER_TO_BLOB -explain extended select left(a1,7), left(a2,7) -from t1_1025 -where a1 in (select group_concat(b1) from t2_1025 group by b2); - -select left(a1,7), left(a2,7) -from t1_1025 -where a1 in (select group_concat(b1) from t2_1025 group by b2); - -set @@group_concat_max_len = 256; # anything < (CONVERT_IF_BIGGER_TO_BLOB = 1025) - -explain extended select left(a1,7), left(a2,7) -from t1_1025 -where a1 in (select group_concat(b1) from t2_1025 group by b2); - -select left(a1,7), left(a2,7) -from t1_1025 -where a1 in (select group_concat(b1) from t2_1025 group by b2); - -drop table t1_1025, t2_1025, t3_1025; - -# test for BIT fields -create table t1bit (a1 bit(3), a2 bit(3)); -create table t2bit (b1 bit(3), b2 bit(3)); - -insert into t1bit values (b'000', b'100'); -insert into t1bit values (b'001', b'101'); -insert into t1bit values (b'010', b'110'); - -insert into t2bit values (b'001', b'101'); -insert into t2bit values (b'010', b'110'); -insert into t2bit values (b'110', b'111'); +set @subselect_mat_test_optimizer_switch_value='materialization=on,in_to_exists=off,semijoin=off'; -set @@optimizer_switch='semijoin=off'; +--source t/subselect_sj_mat.test +set @subselect_mat_test_optimizer_switch_value=null; -explain extended select bin(a1), bin(a2) -from t1bit -where (a1, a2) in (select b1, b2 from t2bit); +set @@optimizer_switch='materialization=on,in_to_exists=off,semijoin=off'; +set optimizer_switch='mrr=on,mrr_sort_keys=on,index_condition_pushdown=on'; +# +# Test that the contents of the temp table of a materialized subquery is +# cleaned up between PS re-executions. +# -select bin(a1), bin(a2) -from t1bit -where (a1, a2) in (select b1, b2 from t2bit); +create table t0 (a int); +insert into t0 values (0),(1),(2); +create table t1 (a int); +insert into t1 values (0),(1),(2); +explain select a, a in (select a from t1) from t0; +select a, a in (select a from t1) from t0; +prepare s from 'select a, a in (select a from t1) from t0'; +execute s; +update t1 set a=123; +execute s; +drop table t0, t1; -drop table t1bit, t2bit; -# test mixture of BIT and BLOB -create table t1bb (a1 bit(3), a2 blob(3)); -create table t2bb (b1 bit(3), b2 blob(3)); +--echo # +--echo # LPBUG#609121: RQG: wrong result on aggregate + NOT IN + HAVING and +--echo # partial_match_table_scan=on +--echo # -insert into t1bb values (b'000', '100'); -insert into t1bb values (b'001', '101'); -insert into t1bb values (b'010', '110'); +create table t1 (c1 int); +create table t2 (c2 int); +insert into t1 values (1); +insert into t2 values (2); -insert into t2bb values (b'001', '101'); -insert into t2bb values (b'010', '110'); -insert into t2bb values (b'110', '111'); +set @@optimizer_switch='semijoin=off'; -explain extended select bin(a1), a2 -from t1bb -where (a1, a2) in (select b1, b2 from t2bb); +EXPLAIN +SELECT SUM(c1) c1_sum FROM t1 WHERE c1 IN (SELECT c2 FROM t2); +SELECT SUM(c1) c1_sum FROM t1 WHERE c1 IN (SELECT c2 FROM t2); +EXPLAIN +SELECT SUM(c1) c1_sum FROM t1 WHERE c1 IN (SELECT c2 FROM t2) HAVING c1_sum; +SELECT SUM(c1) c1_sum FROM t1 WHERE c1 IN (SELECT c2 FROM t2) HAVING c1_sum; -select bin(a1), a2 -from t1bb -where (a1, a2) in (select b1, b2 from t2bb); +drop table t1, t2; -drop table t1bb, t2bb; -drop table t1, t2, t3, t1i, t2i, t3i, columns; +--echo # +--echo # BUG#52344 - Subquery materialization: +--echo # Assertion if subquery in on-clause of outer join +--echo # -/****************************************************************************** -* Test the cache of the left operand of IN. -******************************************************************************/ set @@optimizer_switch='semijoin=off'; -# Test that default values of Cached_item are not used for comparison -create table t1 (s1 int); -create table t2 (s2 int); -insert into t1 values (5),(1),(0); -insert into t2 values (0), (1); -select s2 from t2 where s2 in (select s1 from t1); -drop table t1, t2; +CREATE TABLE t1 (i INTEGER); +INSERT INTO t1 VALUES (10); -create table t1 (a int not null, b int not null); -create table t2 (c int not null, d int not null); -create table t3 (e int not null); - -# the first outer row has no matching inner row -insert into t1 values (1,10); -insert into t1 values (1,20); -insert into t1 values (2,10); -insert into t1 values (2,20); -insert into t1 values (2,30); -insert into t1 values (3,20); -insert into t1 values (4,40); - -insert into t2 values (2,10); -insert into t2 values (2,20); -insert into t2 values (2,40); -insert into t2 values (3,20); -insert into t2 values (4,10); -insert into t2 values (5,10); - -insert into t3 values (10); -insert into t3 values (10); -insert into t3 values (20); -insert into t3 values (30); - -explain extended -select a from t1 where a in (select c from t2 where d >= 20); -select a from t1 where a in (select c from t2 where d >= 20); - -create index it1a on t1(a); - -explain extended -select a from t1 where a in (select c from t2 where d >= 20); -select a from t1 where a in (select c from t2 where d >= 20); - -# the first outer row has a matching inner row -insert into t2 values (1,10); - -explain extended -select a from t1 where a in (select c from t2 where d >= 20); -select a from t1 where a in (select c from t2 where d >= 20); - -# cacheing for IN predicates inside a having clause - here the cached -# items are changed to point to temporary tables. -explain extended -select a from t1 group by a having a in (select c from t2 where d >= 20); -select a from t1 group by a having a in (select c from t2 where d >= 20); - -# create an index that can be used for the outer query GROUP BY -create index iab on t1(a, b); -explain extended -select a from t1 group by a having a in (select c from t2 where d >= 20); -select a from t1 group by a having a in (select c from t2 where d >= 20); - -explain extended -select a from t1 group by a -having a in (select c from t2 where d >= some(select e from t3 where max(b)=e)); -select a from t1 group by a -having a in (select c from t2 where d >= some(select e from t3 where max(b)=e)); -explain extended -select a from t1 -where a in (select c from t2 where d >= some(select e from t3 where b=e)); -select a from t1 -where a in (select c from t2 where d >= some(select e from t3 where b=e)); +CREATE TABLE t2 (j INTEGER); +INSERT INTO t2 VALUES (5); -drop table t1, t2, t3; +CREATE TABLE t3 (k INTEGER); -# -# BUG#36133 "Assertion `exec_method != MATERIALIZATION || (exec_method == MATERIALIZATION &&" -# -create table t2 (a int, b int, key(a), key(b)); -insert into t2 values (3,3),(3,3),(3,3); -select 1 from t2 where - t2.a > 1 - or - t2.a = 3 and not t2.a not in (select t2.b from t2); -drop table t2; +EXPLAIN +SELECT i FROM t1 LEFT JOIN t2 ON (j) IN (SELECT k FROM t3); +SELECT i FROM t1 LEFT JOIN t2 ON (j) IN (SELECT k FROM t3); -# -# BUG#37896 Assertion on entry of Item_in_subselect::exec on subquery with AND NOT -# -create table t1 (a1 int key); -create table t2 (b1 int); -insert into t1 values (5); - -# Query with group by, executed via materialization -explain select min(a1) from t1 where 7 in (select b1 from t2 group by b1); -select min(a1) from t1 where 7 in (select b1 from t2 group by b1); -# Query with group by, executed via IN=>EXISTS -set @@optimizer_switch='default,materialization=off'; -explain select min(a1) from t1 where 7 in (select b1 from t2 group by b1); -select min(a1) from t1 where 7 in (select b1 from t2 group by b1); - -# Executed with materialization -set @@optimizer_switch='default,semijoin=off'; -explain select min(a1) from t1 where 7 in (select b1 from t2); -select min(a1) from t1 where 7 in (select b1 from t2); -# Executed with semi-join. Notice, this time we get a different result (NULL). -# This is the only correct result of all four queries. This difference is -# filed as BUG#40037. -set @@optimizer_switch='default,materialization=off'; -explain select min(a1) from t1 where 7 in (select b1 from t2); -select min(a1) from t1 where 7 in (select b1 from t2); -drop table t1,t2; +EXPLAIN +SELECT i FROM t1 LEFT JOIN t2 ON (j) IN (SELECT max(k) FROM t3); +SELECT i FROM t1 LEFT JOIN t2 ON (j) IN (SELECT max(k) FROM t3); -# -# BUG#36752 "subquery materialization produces wrong results when comparing different types" -# -create table t1 (a char(2), b varchar(10)); -insert into t1 values ('a', 'aaa'); -insert into t1 values ('aa', 'aaaa'); - -set @@optimizer_switch='default,semijoin=off'; -explain select a,b from t1 where b in (select a from t1); -select a,b from t1 where b in (select a from t1); -prepare st1 from "select a,b from t1 where b in (select a from t1)"; -execute st1; -execute st1; -drop table t1; +DROP TABLE t1, t2, t3; -# -# Bug #44303 Assertion failures in Field_new_decimal::store_decimal -# when executing materialized InsideOut semijoin -# -CREATE TABLE t1 (f1 INT, f2 DECIMAL(5,3)) ENGINE=MyISAM; -INSERT INTO t1 (f1, f2) VALUES (1, 1.789); -INSERT INTO t1 (f1, f2) VALUES (13, 1.454); -INSERT INTO t1 (f1, f2) VALUES (10, 1.668); +--echo # +--echo # LPBUG#611622/BUG#52344: Subquery materialization: Assertion +--echo # if subquery in on-clause of outer join +--echo # -CREATE TABLE t2 LIKE t1; -INSERT INTO t2 VALUES (1, 1.789); -INSERT INTO t2 VALUES (13, 1.454); +CREATE TABLE t1 (c1 int); +INSERT INTO t1 VALUES (1),(2); -SET @@optimizer_switch='default,semijoin=on,materialization=on'; -EXPLAIN SELECT COUNT(*) FROM t1 WHERE (f1,f2) IN (SELECT f1,f2 FROM t2); -SELECT COUNT(*) FROM t1 WHERE (f1,f2) IN (SELECT f1,f2 FROM t2); +CREATE TABLE t2 (c2 int); +INSERT INTO t2 VALUES (10); + +PREPARE st1 FROM " +SELECT * +FROM t2 LEFT JOIN t2 t3 ON (8, 4) IN (SELECT c1, c1 FROM t1)"; + +EXECUTE st1; +EXECUTE st1; DROP TABLE t1, t2; -# -# BUG#46548 IN-subqueries return 0 rows with materialization=on -# +--echo # +--echo # Testcase backport: BUG#46548 IN-subqueries return 0 rows with materialization=on +--echo # CREATE TABLE t1 ( pk int, a varchar(1), @@ -889,57 +118,111 @@ SELECT pk FROM t1 WHERE (a) IN (SELECT a FROM t2 WHERE pk > 0); SELECT pk FROM t1 WHERE (b,c,d) IN (SELECT b,c,d FROM t2 WHERE pk > 0); DROP TABLE t1, t2; + +-- echo # +-- echo # BUG#724228: Wrong result with materialization=on and three aggregates in maria-5.3-mwl90 +-- echo # +CREATE TABLE t1 ( f2 int(11)) ; +INSERT IGNORE INTO t1 VALUES ('7'),('9'),('7'),('4'),('2'),('6'),('8'),('5'),('6'),('188'),('2'),('1'),('1'),('0'),('9'),('4'); + +CREATE TABLE t2 ( f1 int(11), f2 int(11)) ENGINE=MyISAM; +INSERT IGNORE INTO t2 VALUES ('1','1'); + +CREATE TABLE t3 ( f1 int(11), f2 int(11), f3 int(11), PRIMARY KEY (f1)) ; +INSERT IGNORE INTO t3 VALUES ('16','6','1'),('18','3','4'),('19',NULL,'9'),('20','0','6'),('41','2','0'),('42','2','5'),('43','9','6'),('44','7','4'),('45','1','4'),('46','222','238'),('47','3','6'),('48','6','6'),('49',NULL,'1'),('50','5','1'); + +SET @_save_join_cache_level = @@join_cache_level; +SET @_save_optimizer_switch = @@optimizer_switch; + +SET join_cache_level = 1; +SET optimizer_switch='materialization=on'; + +SELECT f1 FROM t3 +WHERE + f1 NOT IN (SELECT MAX(f2) FROM t1) AND + f3 IN (SELECT MIN(f1) FROM t2) AND + f1 IN (SELECT COUNT(f2) FROM t1); + +SET @@join_cache_level = @_save_join_cache_level; +SET @@optimizer_switch = @_save_optimizer_switch; + +drop table t1, t2, t3; + --echo # ---echo # BUG#50019: Wrong result for IN-subquery with materialization +--echo # LPBUG#719198 Ordered_key::cmp_key_with_search_key(rownum_t): Assertion `!compare_pred[i]->null_value' +--echo # failed with subquery on both sides of NOT IN and materialization --echo # -create table t1(i int); -insert into t1 values (1), (2), (3), (4), (5), (6), (7), (8), (9), (10); -create table t2(i int); -insert into t2 values (1), (2), (3), (4), (5), (6), (7), (8), (9), (10); -create table t3(i int); -insert into t3 values (1), (2), (3), (4), (5), (6), (7), (8), (9), (10); -select * from t1 where t1.i in (select t2.i from t2 join t3 where t2.i + t3.i = 5); -set @save_optimizer_switch=@@optimizer_switch; -set session optimizer_switch='materialization=off'; -select * from t1 where t1.i in (select t2.i from t2 join t3 where t2.i + t3.i = 5); -set session optimizer_switch=@save_optimizer_switch; -drop table t1, t2, t3; -# -# Test that the contents of the temp table of a materialized subquery is -# cleaned up between PS re-executions. -# +CREATE TABLE t1 (f1a int, f1b int) ; +INSERT IGNORE INTO t1 VALUES (1,1),(2,2); +CREATE TABLE t2 ( f2 int); +INSERT IGNORE INTO t2 VALUES (3),(4); +CREATE TABLE t3 (f3a int, f3b int); -create table t0 (a int); -insert into t0 values (0),(1),(2); -create table t1 (a int); -insert into t1 values (0),(1),(2); -explain select a, a in (select a from t1) from t0; -select a, a in (select a from t1) from t0; -prepare s from 'select a, a in (select a from t1) from t0'; -execute s; -update t1 set a=123; -execute s; -drop table t0, t1; +set @@optimizer_switch='materialization=on,partial_match_rowid_merge=on,partial_match_table_scan=off,in_to_exists=off'; + +EXPLAIN +SELECT * FROM t2 WHERE (SELECT f3a FROM t3) NOT IN (SELECT f1a FROM t1); +SELECT * FROM t2 WHERE (SELECT f3a FROM t3) NOT IN (SELECT f1a FROM t1); +EXPLAIN +SELECT (SELECT f3a FROM t3) NOT IN (SELECT f1a FROM t1); +SELECT (SELECT f3a FROM t3) NOT IN (SELECT f1a FROM t1); + +EXPLAIN +SELECT * FROM t2 WHERE (SELECT f3a, f3b FROM t3) NOT IN (SELECT f1a, f1b FROM t1); +SELECT * FROM t2 WHERE (SELECT f3a, f3b FROM t3) NOT IN (SELECT f1a, f1b FROM t1); + +EXPLAIN +SELECT (SELECT f3a, f3b FROM t3) NOT IN (SELECT f1a, f1b FROM t1); +SELECT (SELECT f3a, f3b FROM t3) NOT IN (SELECT f1a, f1b FROM t1); + +drop table t1, t2, t3; --echo # ---echo # LPBUG#609121: RQG: wrong result on aggregate + NOT IN + HAVING and ---echo # partial_match_table_scan=on +--echo # LPBUG#730604 Assertion `bit < (map)->n_bits' failed in maria-5.3 with +--echo # partial_match_rowid_merge --echo # -create table t1 (c1 int); -create table t2 (c2 int); -insert into t1 values (1); -insert into t2 values (2); +CREATE TABLE t1 (f1 int NOT NULL, f2 int, f3 int) ; +CREATE TABLE t2 (f1 int NOT NULL, f2 int, f3 int) ; -set @@optimizer_switch='semijoin=off'; +INSERT INTO t1 VALUES (60, 3, null), (61, null, 77); +INSERT INTO t2 VALUES (1000,6,2); + +set @@optimizer_switch='materialization=on,partial_match_rowid_merge=on,partial_match_table_scan=off,in_to_exists=off'; EXPLAIN -SELECT SUM(c1) c1_sum FROM t1 WHERE c1 IN (SELECT c2 FROM t2); -SELECT SUM(c1) c1_sum FROM t1 WHERE c1 IN (SELECT c2 FROM t2); -EXPLAIN -SELECT SUM(c1) c1_sum FROM t1 WHERE c1 IN (SELECT c2 FROM t2) HAVING c1_sum; -SELECT SUM(c1) c1_sum FROM t1 WHERE c1 IN (SELECT c2 FROM t2) HAVING c1_sum; +SELECT (f1, f2, f3) NOT IN + (SELECT COUNT(DISTINCT f2), f1, f3 FROM t1 GROUP BY f1, f3) +FROM t2; + +SELECT (f1, f2, f3) NOT IN + (SELECT COUNT(DISTINCT f2), f1, f3 FROM t1 GROUP BY f1, f3) +FROM t2; drop table t1, t2; + +--echo # +--echo # LPBUG#702301: MAX in select + always false WHERE with SQ +--echo # + +CREATE TABLE t1 (a int, b int, KEY (b)); +INSERT INTO t1 VALUES (3,1), (4,2); +CREATE TABLE t2 (a int); +INSERT INTO t2 VALUES (7), (8); + +set @@optimizer_switch='materialization=on,in_to_exists=off,semijoin=off'; + +SELECT MAX(t1.b) AS max_res FROM t1 WHERE (9) IN (SELECT a FROM t2); +EXPLAIN EXTENDED +SELECT MAX(t1.b) AS max_res FROM t1 WHERE (9) IN (SELECT a FROM t2); + +set @@optimizer_switch='materialization=off,in_to_exists=on,semijoin=off'; + +SELECT MAX(t1.b) AS max_res FROM t1 WHERE (9) IN (SELECT a FROM t2); +EXPLAIN EXTENDED +SELECT MAX(t1.b) AS max_res FROM t1 WHERE (9) IN (SELECT a FROM t2); + +DROP TABLE t1,t2; + diff --git a/mysql-test/t/subselect_mat_cost.test b/mysql-test/t/subselect_mat_cost.test new file mode 100644 index 00000000000..8a0d1ac702d --- /dev/null +++ b/mysql-test/t/subselect_mat_cost.test @@ -0,0 +1,422 @@ +# +# Tests of cost-based choice between the materialization and in-to-exists +# subquery execution strategies (MWL#89) +# +# The test file is divided into two groups of tests: +# A. Typical cases when either of the two strategies is selected: +# 1. Subquery in disjunctive WHERE clause of the outer query. +# 2. NOT IN subqueries +# 3. Subqueries with GROUP BY, HAVING, and aggregate functions +# 4. Subqueries in the SELECT and HAVING clauses +# 5. Subqueries with UNION +# B. Reasonably exhaustive tests of the various combinations of optimizer +# switches, data distribution, available indexes, and typical queries. +# + +set @subselect_mat_cost=@@optimizer_switch; +set optimizer_switch='mrr=on,mrr_sort_keys=on,index_condition_pushdown=on'; + + +-- echo TEST GROUP 1: +-- echo Typical cases of in-to-exists and materialization subquery strategies +-- echo ===================================================================== + +--disable_warnings +drop database if exists world; +--enable_warnings + +set names utf8; + +create database world; +use world; + +--source include/world_schema.inc +--disable_query_log +--disable_result_log +--disable_warnings +--source include/world.inc +--enable_warnings +--enable_result_log +--enable_query_log + +-- echo Make the schema and data more diverse by adding more indexes, nullable +-- echo columns, and NULL data. +create index SurfaceArea on Country(SurfaceArea); +create index Language on CountryLanguage(Language); +create index CityName on City(Name); +alter table City change population population int(11) null default 0; + +select max(id) from City into @max_city_id; +insert into City values (@max_city_id + 1,'Kilifarevo','BGR',NULL); + + +SELECT COUNT(*) FROM Country; +SELECT COUNT(*) FROM City; +SELECT COUNT(*) FROM CountryLanguage; + +set @@optimizer_switch = 'in_to_exists=on,semijoin=on,materialization=on,partial_match_rowid_merge=on,partial_match_table_scan=on,subquery_cache=on'; + +-- echo +-- echo 1. Subquery in a disjunctive WHERE clause of the outer query. +-- echo + +-- echo +-- echo Q1.1m: +-- echo MATERIALIZATION: there are too many rows in the outer query +-- echo to be looked up in the inner table. +EXPLAIN +SELECT Name FROM Country +WHERE (Code IN (select Country from City where City.Population > 100000) OR + Name LIKE 'L%') AND + surfacearea > 1000000; + +SELECT Name FROM Country +WHERE (Code IN (select Country from City where City.Population > 100000) OR + Name LIKE 'L%') AND + surfacearea > 1000000; + +-- echo Q1.1e: +-- echo IN-EXISTS: the materialization cost is the same as above, but +-- echo there are much fewer outer rows to be looked up, thus the +-- echo materialization cost is too high to compensate for fast lookups. +EXPLAIN +SELECT Name FROM Country +WHERE (Code IN (select Country from City where City.Population > 100000) OR + Name LIKE 'L%') AND + surfacearea > 10*1000000; + +SELECT Name FROM Country +WHERE (Code IN (select Country from City where City.Population > 100000) OR + Name LIKE 'L%') AND + surfacearea > 10*1000000; + +-- echo +-- echo Q1.2m: +-- echo MATERIALIZATION: the IN predicate is pushed (attached) to the last table +-- echo in the join order (Country, City), therefore there are too many row +-- echo combinations to filter by re-executing the subquery for each combination. +EXPLAIN +SELECT * + FROM Country, City + WHERE City.Country = Country.Code AND + Country.SurfaceArea < 3000 AND Country.SurfaceArea > 10 AND + (City.Name IN + (select Language from CountryLanguage where Percentage > 50) OR + City.name LIKE '%Island%'); + +SELECT * + FROM Country, City + WHERE City.Country = Country.Code AND + Country.SurfaceArea < 3000 AND Country.SurfaceArea > 10 AND + (City.Name IN + (select Language from CountryLanguage where Percentage > 50) OR + City.name LIKE '%Island%'); + +-- echo Q1.2e: +-- echo IN_EXISTS: join order is the same, but the left IN operand refers to +-- echo only the first table in the join order (Country), so there are much +-- echo fewer rows to filter by subquery re-execution. +EXPLAIN +SELECT * + FROM Country, City + WHERE City.Country = Country.Code AND + Country.SurfaceArea < 3000 AND Country.SurfaceArea > 10 AND + (Country.Name IN + (select Language from CountryLanguage where Percentage > 50) OR + Country.name LIKE '%Island%'); + +SELECT * + FROM Country, City + WHERE City.Country = Country.Code AND + Country.SurfaceArea < 3000 AND Country.SurfaceArea > 10 AND + (Country.Name IN + (select Language from CountryLanguage where Percentage > 50) OR + Country.name LIKE '%Island%'); + + +-- echo +-- echo Q1.3: +-- echo For the same reasons as in Q2 IN-EXISTS and MATERIALIZATION chosen +-- echo for each respective subquery. +EXPLAIN +SELECT City.Name, Country.Name + FROM City,Country + WHERE City.Country = Country.Code AND + Country.SurfaceArea < 30000 AND Country.SurfaceArea > 10 AND + ((Country.Code, Country.Name) IN + (select Country, Language from CountryLanguage where Percentage > 50) AND + Country.Population > 3000000 + OR + (Country.Code, City.Name) IN + (select Country, Language from CountryLanguage)); + +SELECT City.Name, Country.Name + FROM City,Country + WHERE City.Country = Country.Code AND + Country.SurfaceArea < 30000 AND Country.SurfaceArea > 10 AND + ((Country.Code, Country.Name) IN + (select Country, Language from CountryLanguage where Percentage > 50) AND + Country.Population > 3000000 + OR + (Country.Code, City.Name) IN + (select Country, Language from CountryLanguage)); + + +-- echo +-- echo 2. NOT IN subqueries +-- echo + +-- echo +-- echo Q2.1: +-- echo Number of cities that are not capitals in countries with small population. +-- echo MATERIALIZATION is 50 times faster because the cost of each subquery +-- echo re-execution is much higher than the cost of index lookups into the +-- echo materialized subquery. + +EXPLAIN +select count(*) from City +where City.id not in (select capital from Country + where capital is not null and population < 100000); + +-- echo +-- echo Q2.2e: +-- echo Countries that speak French, but do not speak English +-- echo IN-EXISTS because the outer query filters many rows, thus +-- echo there are few lookups to make. +EXPLAIN +SELECT Country.Name +FROM Country, CountryLanguage +WHERE Code NOT IN (SELECT Country FROM CountryLanguage WHERE Language = 'English') + AND CountryLanguage.Language = 'French' + AND Code = Country; + +SELECT Country.Name +FROM Country, CountryLanguage +WHERE Code NOT IN (SELECT Country FROM CountryLanguage WHERE Language = 'English') + AND CountryLanguage.Language = 'French' + AND Code = Country; + +-- echo Q2.2m: +-- echo Countries that speak French OR Spanish, but do not speak English +-- echo MATERIALIZATION because the outer query filters less rows than Q5-a, +-- echo so there are more lookups. +EXPLAIN +SELECT Country.Name +FROM Country, CountryLanguage +WHERE Code NOT IN (SELECT Country FROM CountryLanguage WHERE Language = 'English') + AND (CountryLanguage.Language = 'French' OR CountryLanguage.Language = 'Spanish') + AND Code = Country; + +SELECT Country.Name +FROM Country, CountryLanguage +WHERE Code NOT IN (SELECT Country FROM CountryLanguage WHERE Language = 'English') + AND (CountryLanguage.Language = 'French' OR CountryLanguage.Language = 'Spanish') + AND Code = Country; + +-- echo +-- echo Q2.3e: +-- echo Not a very meaningful query that tests NOT IN. +-- echo IN-EXISTS because the outer query is cheap enough to reexecute many times. +EXPLAIN +select count(*) +from CountryLanguage +where (Language, Country) NOT IN + (SELECT City.Name, Country.Code + FROM City LEFT JOIN Country ON (Country = Code and City.Population < 10000)); + +select count(*) +from CountryLanguage +where (Language, Country) NOT IN + (SELECT City.Name, Country.Code + FROM City LEFT JOIN Country ON (Country = Code and City.Population < 10000)); + +-- echo Q2.3m: +-- echo MATERIALIZATION with the PARTIAL_MATCH_MERGE strategy, because the HAVING +-- echo clause prevents the use of the index on City(Name), and in practice reduces +-- echo radically the size of the temp table. +EXPLAIN +select count(*) +from CountryLanguage +where (Language, Country) NOT IN + (SELECT City.Name, Country.Code + FROM City LEFT JOIN Country ON (Country = Code) + HAVING City.Name LIKE "Santa%"); + +select count(*) +from CountryLanguage +where (Language, Country) NOT IN + (SELECT City.Name, Country.Code + FROM City LEFT JOIN Country ON (Country = Code) + HAVING City.Name LIKE "Santa%"); + + +-- echo +-- echo 3. Subqueries with GROUP BY, HAVING, and aggregate functions +-- echo + +-- echo Q3.1: +-- echo Languages that are spoken in countries with 10 or 11 languages +-- echo MATERIALIZATION is about 100 times faster than IN-EXISTS. + +EXPLAIN +select count(*) +from CountryLanguage +where +(Country, 10) IN (SELECT Code, COUNT(*) FROM CountryLanguage, Country + WHERE Code = Country GROUP BY Code) +OR +(Country, 11) IN (SELECT Code, COUNT(*) FROM CountryLanguage, Country + WHERE Code = Country GROUP BY Code) +order by Country; + +select count(*) +from CountryLanguage +where +(Country, 10) IN (SELECT Code, COUNT(*) FROM CountryLanguage, Country + WHERE Code = Country GROUP BY Code) +OR +(Country, 11) IN (SELECT Code, COUNT(*) FROM CountryLanguage, Country + WHERE Code = Country GROUP BY Code) +order by Country; + + +-- echo +-- echo Q3.2: +-- echo Countries whose capital is a city name that names more than one +-- echo cities. +-- echo MATERIALIZATION because the cost of single subquery execution is +-- echo close to that of materializing the subquery. + +EXPLAIN +select * from Country, City +where capital = id and + (City.name in (SELECT name FROM City + GROUP BY name HAVING Count(*) > 2) OR + capital is null); + +select * from Country, City +where capital = id and + (City.name in (SELECT name FROM City + GROUP BY name HAVING Count(*) > 2) OR + capital is null); + +-- echo +-- echo Q3.3: MATERIALIZATION is 25 times faster than IN-EXISTS + +EXPLAIN +SELECT Name +FROM Country +WHERE Country.Code NOT IN + (SELECT Country FROM City GROUP BY Name HAVING COUNT(Name) = 1); + +SELECT Name +FROM Country +WHERE Country.Code NOT IN + (SELECT Country FROM City GROUP BY Name HAVING COUNT(Name) = 1); + + +-- echo +-- echo 4. Subqueries in the SELECT and HAVING clauses +-- echo + +-- echo Q4.1m: +-- echo Capital information about very big cities +-- echo MATERIALIZATION +EXPLAIN +select Name, City.id in (select capital from Country where capital is not null) as is_capital +from City +where City.population > 10000000; + +select Name, City.id in (select capital from Country where capital is not null) as is_capital +from City +where City.population > 10000000; + +-- echo Q4.1e: +-- echo IN-TO-EXISTS after adding an index to make the subquery re-execution +-- echo efficient. + +create index CountryCapital on Country(capital); + +EXPLAIN +select Name, City.id in (select capital from Country where capital is not null) as is_capital +from City +where City.population > 10000000; + +select Name, City.id in (select capital from Country where capital is not null) as is_capital +from City +where City.population > 10000000; + +drop index CountryCapital on Country; + +-- echo +-- echo Q4.2: +-- echo MATERIALIZATION +# TODO: the cost estimates for subqueries in the HAVING clause need to be changed +# to take into account that the subquery predicate is executed #times ~ to the +# number of groups, not number of rows +EXPLAIN +SELECT City.Name, City.Population +FROM City JOIN Country ON City.Country = Country.Code +GROUP BY City.Name +HAVING City.Name IN (select Name from Country where population < 1000000); + +SELECT City.Name, City.Population +FROM City JOIN Country ON City.Country = Country.Code +GROUP BY City.Name +HAVING City.Name IN (select Name from Country where population < 1000000); + + +-- echo +-- echo 5. Subqueries with UNION +-- echo + +-- echo Q5.1: +EXPLAIN +SELECT * from City where (Name, 91) in +(SELECT Name, round(Population/1000) + FROM City + WHERE Country = "IND" AND Population > 2500000 +UNION + SELECT Name, round(Population/1000) + FROM City + WHERE Country = "IND" AND Population < 100000); + +SELECT * from City where (Name, 91) in +(SELECT Name, round(Population/1000) + FROM City + WHERE Country = "IND" AND Population > 2500000 +UNION + SELECT Name, round(Population/1000) + FROM City + WHERE Country = "IND" AND Population < 100000); + +set @@optimizer_switch='default'; +drop database world; +-- echo + + +-- echo +-- echo TEST GROUP 2: +-- echo Tests of various combinations of optimizer switches, types of queries, +-- echo available indexes, column nullability, constness of tables/predicates. +-- echo ===================================================================== + + +#TODO From Igor's review: +# +#2.1 Please add a case when two subqueries are used in the where clause +#(or in select) of a 2-way join. +#The first subquery is accessed after the first table, while the second +#is accessed after the second table. +# +#2.2. Please add a test case when one non-correlated subquery contains +#another non-correlated subquery. +#Consider 4 subcases: +# both subqueries are materialized +# IN_EXIST transformations are applied to both subqueries +# outer subquery is materialized while the inner subquery is not +#(IN_EXIST transformation is applied to it) +# inner subqyery is materialized while the outer subquery is not ( +#IN_EXIST transformation is applied to it) + +set optimizer_switch=@subselect_mat_cost; diff --git a/mysql-test/t/subselect_mat_cost_bugs.test b/mysql-test/t/subselect_mat_cost_bugs.test new file mode 100644 index 00000000000..37c7b617760 --- /dev/null +++ b/mysql-test/t/subselect_mat_cost_bugs.test @@ -0,0 +1,351 @@ +# +# Test cases for bugs related to the implementation of +# MWL#89 cost-based choice between the materialization and in-to-exists +# + +--echo # +--echo # LP BUG#643424 valgrind warning in choose_subquery_plan() +--echo # + +CREATE TABLE t1 ( + pk int(11) NOT NULL AUTO_INCREMENT, + c1 int(11) DEFAULT NULL, + c2 int(11) DEFAULT NULL, + PRIMARY KEY (pk), + KEY c2 (c2)); + +INSERT INTO t1 VALUES (1,NULL,2); +INSERT INTO t1 VALUES (2,7,9); +INSERT INTO t1 VALUES (9,NULL,8); + +CREATE TABLE t2 ( + pk int(11) NOT NULL AUTO_INCREMENT, + c1 int(11) DEFAULT NULL, + c2 int(11) DEFAULT NULL, + PRIMARY KEY (pk), + KEY c2 (c2)); + +INSERT INTO t2 VALUES (1,1,7); + +set @save_optimizer_switch=@@optimizer_switch; +set @@optimizer_switch='materialization=on,in_to_exists=on,semijoin=off'; + +SELECT pk FROM t1 WHERE (c2, c1) IN (SELECT c2, c2 FROM t2); + +set session optimizer_switch=@save_optimizer_switch; + +drop table t1, t2; + + +--echo # +--echo # LP BUG#652727 Crash in create_ref_for_key() +--echo # + +CREATE TABLE t2 ( + pk int(11) NOT NULL AUTO_INCREMENT, + c1 int(11) DEFAULT NULL, + PRIMARY KEY (pk)); + +INSERT INTO t2 VALUES (10,7); +INSERT INTO t2 VALUES (11,1); +INSERT INTO t2 VALUES (17,NULL); + +CREATE TABLE t1 ( + pk int(11) NOT NULL AUTO_INCREMENT, + c1 int(11) DEFAULT NULL, + PRIMARY KEY (pk)); + +INSERT INTO t1 VALUES (15,1); +INSERT INTO t1 VALUES (19,NULL); + +CREATE TABLE t3 (c2 int(11) DEFAULT NULL, KEY c2 (c2)); +INSERT INTO t3 VALUES (1); + +set @save_optimizer_switch=@@optimizer_switch; +set @@optimizer_switch='materialization=on,in_to_exists=on,semijoin=off'; + +SELECT c2 +FROM t3 +WHERE (2, 6) IN (SELECT t1.c1, t1.c1 FROM t1 STRAIGHT_JOIN t2 ON t2.pk = t1.pk); + +set session optimizer_switch=@save_optimizer_switch; +drop table t1, t2, t3; + + +--echo # +--echo # LP BUG#641245 Crash in Item_equal::contains +--echo # + +CREATE TABLE t1 ( + pk int(11) NOT NULL AUTO_INCREMENT, + c1 int(11) DEFAULT NULL, + c2 int(11) DEFAULT NULL, + c3 varchar(1) DEFAULT NULL, + c4 varchar(1) DEFAULT NULL, + PRIMARY KEY (pk), + KEY c2 (c2), + KEY c3 (c3,c2)); + +INSERT INTO t1 VALUES (10,7,8,'v','v'); +INSERT INTO t1 VALUES (11,1,9,'r','r'); +INSERT INTO t1 VALUES (12,5,9,'a','a'); + +create table t1a like t1; +insert into t1a select * from t1; + +create table t1b like t1; +insert into t1b select * from t1; + +CREATE TABLE t2 ( + pk int(11) NOT NULL AUTO_INCREMENT, + c1 int(11) DEFAULT NULL, + c2 int(11) DEFAULT NULL, + c3 varchar(1) DEFAULT NULL, + c4 varchar(1) DEFAULT NULL, + PRIMARY KEY (pk), + KEY c2 (c2), + KEY c3 (c3,c2)); + +INSERT INTO t2 VALUES (1,NULL,2,'w','w'); +INSERT INTO t2 VALUES (2,7,9,'m','m'); + +set @@optimizer_switch='materialization=off,in_to_exists=on,semijoin=off'; + +let $query= +SELECT pk +FROM t1 +WHERE c1 IN + (SELECT t1a.c1 + FROM (t1b JOIN t2 ON t2.c3 = t1b.c4) LEFT JOIN + t1a ON (t1a.c2 = t1b.pk AND 2) + WHERE t1.pk) ; +eval EXPLAIN EXTENDED $query; +eval $query; + +DROP TABLE t1, t1a, t1b, t2; + +--echo # +--echo # LP BUG#714808 Assertion `outer_lookup_keys <= outer_record_count' +--echo # failed with materialization + +CREATE TABLE t1 ( pk int(11), PRIMARY KEY (pk)) ; +CREATE TABLE t2 ( f2 int(11)) ; +CREATE TABLE t3 ( f1 int(11), f3 varchar(1), KEY (f1)) ; +INSERT INTO t3 VALUES (7,'f'); + +set @@optimizer_switch='materialization=on,in_to_exists=on,semijoin=off'; + +EXPLAIN +SELECT t1.* +FROM t3 RIGHT JOIN t1 ON t1.pk = t3.f1 +WHERE t3.f3 OR ( 3 ) IN ( SELECT f2 FROM t2 ); + +SELECT t1.* +FROM t3 RIGHT JOIN t1 ON t1.pk = t3.f1 +WHERE t3.f3 OR ( 3 ) IN ( SELECT f2 FROM t2 ); + +drop table t1,t2,t3; + +--echo # +--echo # LP BUG#714999 Second crash in select_describe() with nested subqueries +--echo # + +CREATE TABLE t1 ( pk int(11)) ; +INSERT INTO t1 VALUES (29); + +CREATE TABLE t2 ( f1 varchar(1)) ; +INSERT INTO t2 VALUES ('f'),('d'); + +CREATE TABLE t3 ( f2 varchar(1)) ; + +EXPLAIN SELECT f2 FROM t3 WHERE ( + SELECT MAX( pk ) FROM t1 + WHERE EXISTS ( + SELECT DISTINCT f1 + FROM t2 + ) +) IS NULL ; + +drop table t1, t2, t3; + +--echo # +--echo # LP BUG#715034 Item_sum_distinct::clear(): Assertion `tree != 0' failed +--echo # + +CREATE TABLE t2 ( f2 int(11)) ; + +CREATE TABLE t1 ( f3 int(11), KEY (f3)) ; +INSERT INTO t1 VALUES (6),(4); + +EXPLAIN +SELECT * FROM (SELECT * FROM t2) AS a2 +WHERE (SELECT distinct SUM(distinct f3 ) FROM t1); + +insert into t2 values (1),(2); +EXPLAIN +SELECT * FROM (SELECT * FROM t2) AS a2 +WHERE (SELECT distinct SUM(distinct f3 ) FROM t1); + +drop table t1,t2; + +--echo # +--echo # LP BUG#715027 Assertion `!table || (!table->read_set || bitmap_is_set(table->read_set, field_index))' failed +--echo # + +CREATE TABLE t1 ( f1 int(11), PRIMARY KEY (f1)) ; +INSERT INTO t1 VALUES (28),(29); + +CREATE TABLE t2 ( f2 int(11), f3 int(11), f10 varchar(1)) ; +INSERT INTO t2 VALUES (NULL,6,'f'),(4,2,'d'); + +EXPLAIN +SELECT alias2.f2 AS field1 +FROM t1 AS alias1 JOIN ( SELECT * FROM t2 ) AS alias2 ON alias2.f3 = alias1.f1 +WHERE ( + SELECT t2.f2 + FROM t2 JOIN t1 ON t1.f1 + WHERE t1.f1 AND alias2.f10 +) +ORDER BY field1 ; + +SELECT alias2.f2 AS field1 +FROM t1 AS alias1 JOIN ( SELECT * FROM t2 ) AS alias2 ON alias2.f3 = alias1.f1 +WHERE ( + SELECT t2.f2 + FROM t2 JOIN t1 ON t1.f1 + WHERE t1.f1 AND alias2.f10 +) +ORDER BY field1 ; + +drop table t1,t2; + +--echo # +--echo # LP BUG#718578 Yet another Assertion `!table || +--echo # (!table->read_set || bitmap_is_set(table->read_set, field_index))' + +CREATE TABLE t1 ( f1 int(11), f2 int(11), f3 int(11)) ; +INSERT IGNORE INTO t1 VALUES (28,5,6),(29,NULL,4); + +CREATE TABLE t2 ( f10 varchar(1) ); +INSERT IGNORE INTO t2 VALUES (NULL); + +SELECT f1 AS field1 +FROM ( SELECT * FROM t1 ) AS alias1 +WHERE (SELECT t1.f1 + FROM t2 JOIN t1 ON t1.f2 + WHERE alias1.f3 AND t1.f3) AND f2 +ORDER BY field1; + +drop table t1,t2; + +--echo # +--echo # LP BUG#601124 Bug in eliminate_item_equal +--echo # leads to crash in Item_func::Item_func + +CREATE TABLE t1 ( f1 int(11), f3 varchar(1)) ; +INSERT INTO t1 VALUES (5,'m'),(NULL,'c'); + +CREATE TABLE t2 ( f2 int(11), f3 varchar(1)) ; +INSERT INTO t2 VALUES (6,'f'),(2,'d'); + +CREATE TABLE t3 ( f2 int(11), f3 varchar(1)) ; +INSERT INTO t3 VALUES (6,'f'),(2,'d'); + +SELECT * FROM t3 +WHERE ( f2 ) IN (SELECT t1.f1 + FROM t1 STRAIGHT_JOIN t2 ON t2.f3 = t1.f3 + WHERE t2.f3 = 'c'); +drop table t1,t2,t3; + + +--echo # +--echo # LP BUG#718593 Crash in substitute_for_best_equal_field -> eliminate_item_equal -> +--echo # Item_field::find_item_equal -> Item_equal::contains +--echo # + +set @save_optimizer_switch=@@optimizer_switch; +SET @@optimizer_switch = 'semijoin=off'; + +CREATE TABLE t1 ( f3 int(11), f10 varchar(1), f11 varchar(1)) ; +INSERT IGNORE INTO t1 VALUES (6,'f','f'),(2,'d','d'); + +CREATE TABLE t2 ( f12 int(11), f13 int(11)) ; +insert into t2 values (1,2), (3,4); + +EXPLAIN +SELECT * FROM t2 +WHERE ( f12 ) IN ( + SELECT alias2.f3 + FROM t1 AS alias1 JOIN t1 AS alias2 ON alias2.f10 = alias1.f11 + WHERE alias1.f11 OR alias1.f3 = 50 AND alias1.f10 +); +SELECT * FROM t2 +WHERE ( f12 ) IN ( + SELECT alias2.f3 + FROM t1 AS alias1 JOIN t1 AS alias2 ON alias2.f10 = alias1.f11 + WHERE alias1.f11 OR alias1.f3 = 50 AND alias1.f10 +); + +EXPLAIN +SELECT * FROM t2 +WHERE ( f12 ) IN ( + SELECT alias2.f3 + FROM t1 AS alias1, t1 AS alias2 + WHERE (alias2.f10 = alias1.f11) AND (alias1.f11 OR alias1.f3 = 50 AND alias1.f10)); +SELECT * FROM t2 +WHERE ( f12 ) IN ( + SELECT alias2.f3 + FROM t1 AS alias1, t1 AS alias2 + WHERE (alias2.f10 = alias1.f11) AND (alias1.f11 OR alias1.f3 = 50 AND alias1.f10)); + +set @@optimizer_switch=@save_optimizer_switch; +drop table t1, t2; + + +--echo # +--echo # MWL#89: test introduced after Sergey Petrunia's review - test that +--echo # keyparts wihtout index prefix are used with the IN-EXISTS strategy. +--echo # + +create table t1 (c1 int); +insert into t1 values (1), (2), (3); + +create table t2 (kp1 int, kp2 int, c2 int, filler char(100)); +insert into t2 values (0,0,0,'filler'),(0,1,1,'filler'),(0,2,2,'filler'),(0,3,3,'filler'); + +create index key1 on t2 (kp1, kp2); +create index key2 on t2 (kp1); +create index key3 on t2 (kp2); + +set session optimizer_switch='default'; + +analyze table t2; + +explain +select c1 from t1 where c1 in (select kp1 from t2 where kp2 = 10 and c2 = 4) or c1 > 7; +select c1 from t1 where c1 in (select kp1 from t2 where kp2 = 10 and c2 = 4) or c1 > 7; + +drop table t1, t2; + +--echo # +--echo # LP BUG#800679: Assertion `outer_join->table_count > 0' failed in +--echo # JOIN::choose_subquery_plan() with materialization=on,semijoin=off +--echo # + +CREATE TABLE t1 ( f1 int); +insert into t1 values (1),(2); +CREATE TABLE t2 ( f1 int); +insert into t2 values (1),(2); + +SET @@optimizer_switch='materialization=on,semijoin=off'; + +EXPLAIN +SELECT * FROM t1 +WHERE (f1) IN (SELECT f1 FROM t2) +LIMIT 0; + +SELECT * FROM t1 +WHERE (f1) IN (SELECT f1 FROM t2) +LIMIT 0; + +drop table t1, t2; diff --git a/mysql-test/t/subselect_no_mat.test b/mysql-test/t/subselect_no_mat.test index 5fbbef5caed..0265ec91e88 100644 --- a/mysql-test/t/subselect_no_mat.test +++ b/mysql-test/t/subselect_no_mat.test @@ -3,6 +3,7 @@ # select @@optimizer_switch like '%materialization=on%'; set optimizer_switch='materialization=off'; +set optimizer_switch='mrr=on,mrr_sort_keys=on,index_condition_pushdown=on'; --source t/subselect.test diff --git a/mysql-test/t/subselect_no_opts.test b/mysql-test/t/subselect_no_opts.test index a26e8dd4c0d..005b2f041fa 100644 --- a/mysql-test/t/subselect_no_opts.test +++ b/mysql-test/t/subselect_no_opts.test @@ -1,9 +1,10 @@ # -# Run subselect.test without semi-join optimization (test materialize) -# -set optimizer_switch='materialization=off,semijoin=off'; +# Run subselect.test without semi-join and materialization optimizations +# (test in-to-exists) + +set @optimizer_switch_for_subselect_test='materialization=off,semijoin=off,mrr=on,mrr_sort_keys=on,index_condition_pushdown=on'; --source t/subselect.test -set optimizer_switch=default; +set @optimizer_switch_for_subselect_test=null; diff --git a/mysql-test/t/subselect_no_semijoin.test b/mysql-test/t/subselect_no_semijoin.test index e9f2e0654ce..c836c12ec50 100644 --- a/mysql-test/t/subselect_no_semijoin.test +++ b/mysql-test/t/subselect_no_semijoin.test @@ -1,8 +1,8 @@ # # Run subselect.test without semi-join optimization (test materialize) # -set optimizer_switch='semijoin=off'; +set @optimizer_switch_for_subselect_test='semijoin=off,mrr=on,mrr_sort_keys=on,index_condition_pushdown=on'; --source t/subselect.test -set optimizer_switch=default; +set @optimizer_switch_for_subselect_test=null; diff --git a/mysql-test/t/subselect_partial_match.test b/mysql-test/t/subselect_partial_match.test index 5e48fc7d9f7..8d1fbd9b8d7 100644 --- a/mysql-test/t/subselect_partial_match.test +++ b/mysql-test/t/subselect_partial_match.test @@ -3,6 +3,221 @@ # MWL#68: Subquery optimization: Efficient NOT IN execution with NULLs # +set @save_optimizer_switch=@@optimizer_switch; + +--echo ------------------------------- +--echo Part 1: Feature tests. +--echo ------------------------------- + +--echo Default for all tests. +set @@optimizer_switch="materialization=on,in_to_exists=off,semijoin=off,subquery_cache=off"; + +--echo +--echo Schema requires partial matching, but data analysis discoveres there is +--echo no need. This is possible only if all outer columns are not NULL. +--echo + +create table t1 (a1 char(8) not null, a2 char(8) not null); +create table t2 (b1 char(8), b2 char(8)); + +insert into t1 values ('1 - 00', '2 - 00'); +insert into t1 values ('1 - 01', '2 - 01'); + +insert into t2 values ('1 - 00', '2 - 00'); +insert into t2 values ('1 - 01', NULL ); +insert into t2 values (NULL , '2 - 02'); +insert into t2 values (NULL , NULL ); +insert into t2 values ('1 - 02', '2 - 02'); + +select * from t1 +where (a1, a2) not in (select * from t2 where b1 is not null and b2 is not null); + +select a1, a2, (a1, a2) not in (select * from t2) as in_res from t1; + +drop table t1, t2; + +--echo +--echo NULLs in the outer columns, no NULLs in the suqbuery +--echo + +create table t1 (a1 char(8), a2 char(8)); +create table t2 (b1 char(8) not null, b2 char(8) not null); + +insert into t1 values (NULL , '2 - 00'); +insert into t1 values ('1 - 01', '2 - 01'); +insert into t1 values (NULL , NULL ); + +insert into t2 values ('1 - 00', '2 - 00'); +insert into t2 values ('1 - 01', '2 - 01'); +insert into t2 values ('1 - 02', '2 - 00'); + +select * from t1 +where (a1, a2) not in (select * from t2 where b1 is not null and b2 is not null); + +select a1, a2, (a1, a2) not in (select * from t2) as in_res from t1; + +select * from t1 +where (a1, a2) in (select * from t2 where b1 is not null and b2 is not null); + +select a1, a2, (a1, a2) in (select * from t2) as in_res from t1; + +drop table t1, t2; + +--echo +--echo All columns require partial matching (no non-null columns) +--echo + +--echo TODO + +--echo +--echo Both non-NULL columns and columns with NULLs +--echo + +--echo TODO + +--echo +--echo Covering NULL rows +--echo + +create table t1 (a1 char(8), a2 char(8)); +create table t2 (b1 char(8), b2 char(8)); + +insert into t1 values ('1 - 00', '2 - 00'); +insert into t1 values ('1 - 01', '2 - 01'); + +insert into t2 values ('1 - 01', NULL ); +insert into t2 values (NULL , '2 - 02'); +insert into t2 values (NULL , NULL ); +insert into t2 values ('1 - 02', '2 - 02'); + +select * from t1 +where (a1, a2) not in (select * from t2); + +select a1, a2, (a1, a2) not in (select * from t2) as in_res from t1; + +insert into t2 values ('1 - 01', '2 - 01'); + +select * from t1 +where (a1, a2) not in (select * from t2); + +select a1, a2, (a1, a2) not in (select * from t2) as in_res from t1; + +select * from t1 +where (a1, a2) in (select * from t2); + +select a1, a2, (a1, a2) in (select * from t2) as in_res from t1; + + +drop table t1, t2; + +--echo +--echo Covering NULL columns +--echo + +--echo this case affects only the rowid-merge algorithm +set @@optimizer_switch="partial_match_rowid_merge=on,partial_match_table_scan=off"; + +create table t1 (a1 char(8) not null, a2 char(8), a3 char(8) not null); +create table t2 (b1 char(8) not null, b2 char(8), b3 char(8) not null); + +insert into t1 values ('1 - 00', '2 - 00', '3 - 00'); +insert into t1 values ('1 - 01', '2 - 01', '3 - 01'); + +insert into t2 values ('1 - 01', NULL, '3 - x1'); +insert into t2 values ('1 - 02', NULL, '3 - 02'); +insert into t2 values ('1 - 00', NULL, '3 - 00'); + +select * from t1 +where (a1, a2, a3) not in (select * from t2); + +select *, (a1, a2, a3) not in (select * from t2) as in_res from t1; + +select * from t1 +where (a1, a2, a3) in (select * from t2); + +select *, (a1, a2, a3) in (select * from t2) as in_res from t1; + +drop table t1, t2; + +create table t1 (a1 char(8), a2 char(8), a3 char(8) not null); +create table t2 (b1 char(8), b2 char(8), b3 char(8) not null); + +insert into t1 values ('1 - 00', '2 - 00', '3 - 00'); +insert into t1 values ('1 - 01', '2 - 01', '3 - 01'); + +insert into t2 values (NULL, NULL, '3 - x1'); +insert into t2 values (NULL, NULL, '3 - 02'); +insert into t2 values (NULL, NULL, '3 - 00'); + +select * from t1 +where (a1, a2, a3) not in (select * from t2); + +select *, (a1, a2, a3) not in (select * from t2) as in_res from t1; + +select * from t1 +where (a1, a2, a3) in (select * from t2); + +select *, (a1, a2, a3) in (select * from t2) as in_res from t1; + +drop table t1, t2; + +--echo +--echo Covering NULL row, and a NULL column +--echo + +create table t1 (a1 char(8) not null, a2 char(8), a3 char(8)); +create table t2 (b1 char(8), b2 char(8), b3 char(8)); + +insert into t1 values ('1 - 00', '2 - 00', '3 - 00'); +insert into t1 values ('1 - 01', '2 - 01', '3 - 01'); + +insert into t2 values ('1 - 01', NULL, '3 - x1'); +insert into t2 values (NULL , NULL, NULL ); +insert into t2 values ('1 - 00', NULL, '3 - 00'); + +select * from t1 +where (a1, a2, a3) not in (select * from t2); + +select *, (a1, a2, a3) not in (select * from t2) as in_res from t1; + +select * from t1 +where (a1, a2, a3) in (select * from t2); + +select *, (a1, a2, a3) in (select * from t2) as in_res from t1; + +drop table t1, t2; + + +--echo +--echo Covering NULL row, and covering NULL columns +--echo + +create table t1 (a1 char(8) not null, a2 char(8), a3 char(8)); +create table t2 (b1 char(8), b2 char(8), b3 char(8)); + +insert into t1 values ('1 - 00', '2 - 00', '3 - 00'); +insert into t1 values ('1 - 01', '2 - 01', '3 - 01'); + +insert into t2 values (NULL, NULL, NULL); +insert into t2 values (NULL, NULL, NULL); + +select * from t1 +where (a1, a2, a3) not in (select * from t2); + +select *, (a1, a2, a3) not in (select * from t2) as in_res from t1; + +select * from t1 +where (a1, a2, a3) in (select * from t2); + +select *, (a1, a2, a3) in (select * from t2) as in_res from t1; + +drop table t1, t2; + + +--echo ------------------------------- +--echo Part 2: Test cases for bugs. +--echo ------------------------------- + --disable_warnings drop table if exists t1, t2; --enable_warnings @@ -10,7 +225,6 @@ drop table if exists t1, t2; --echo # --echo # LP BUG#608744 --echo # -set @save_optimizer_switch=@@optimizer_switch; set @@optimizer_switch="materialization=on,semijoin=off,partial_match_rowid_merge=on,partial_match_table_scan=off"; create table t1 (a1 char(1), a2 char(1)); insert into t1 values (NULL, 'b'); @@ -18,7 +232,6 @@ create table t2 (b1 char(1), b2 char(2)); insert into t2 values ('a','b'), ('c', 'd'); select * from t1 where (a1, a2) NOT IN (select b1, b2 from t2); drop table t1,t2; -set @@optimizer_switch=@save_optimizer_switch; --echo # @@ -32,20 +245,17 @@ CREATE TABLE t2 (b1 int DEFAULT NULL, b2 int DEFAULT NULL); INSERT INTO t2 VALUES (6,NULL); INSERT INTO t2 VALUES (NULL,0); -set @save_optimizer_switch=@@optimizer_switch; set @@optimizer_switch='materialization=on,semijoin=off,partial_match_rowid_merge=on,partial_match_table_scan=on'; EXPLAIN EXTENDED SELECT * FROM (SELECT * FROM t1 WHERE a1 NOT IN (SELECT b2 FROM t2)) table1; DROP TABLE t1, t2; -set @@optimizer_switch=@save_optimizer_switch; --echo # --echo # LP BUG#613009 Crash in Ordered_key::get_field_idx --echo # -set @save_optimizer_switch=@@optimizer_switch; set @@optimizer_switch='materialization=on,semijoin=off,partial_match_rowid_merge=on,partial_match_table_scan=off'; create table t1 (a1 char(3) DEFAULT NULL, a2 char(3) DEFAULT NULL); @@ -53,4 +263,95 @@ insert into t1 values (NULL, 'a21'), (NULL, 'a22'); explain select * from t1 where (a1, a2) not in (select a1, a2 from t1); select * from t1 where (a1, a2) not in (select a1, a2 from t1); drop table t1; + +--echo # +--echo # LP BUG#680058 void Ordered_key::add_key(rownum_t): +--echo # Assertion `key_buff_elements && cur_key_idx < key_buff_elements' failed +--echo # + +create table t1 (f1 char(1), f2 char(1)); +insert into t1 values ('t', '0'), ('0', 't'); +create table t2 (f3 char(1), f4 char(1)); +insert into t2 values ('t', NULL), ('t', NULL), ('d', 'y'); + +set @@optimizer_switch='materialization=on,partial_match_rowid_merge=on,partial_match_table_scan=off,semijoin=off'; +select * from t1 where (f1, f2) not in (select * from t2); +drop table t1, t2; + + +--echo # +--echo # LP BUG#809245 Second assertion `bit < (map)->n_bits' with partial_match_merge +--echo # + +CREATE TABLE t1 (d varchar(32)) ; +INSERT INTO t1 VALUES ('r'); + +CREATE TABLE t2 ( a int, c varchar(32)) ; +INSERT INTO t2 VALUES (5,'r'); + +CREATE TABLE t3 ( a int NOT NULL , d varchar(32)) ; +INSERT INTO t3 VALUES (10,'g'); + +set @@optimizer_switch='materialization=on,partial_match_rowid_merge=on,partial_match_table_scan=off,in_to_exists=off'; + +EXPLAIN SELECT * +FROM t1 +WHERE (t1.d , t1.d) NOT IN ( + SELECT t3.d , t2.c + FROM t3 LEFT JOIN t2 ON t3.a = t2.a); + +SELECT * +FROM t1 +WHERE (t1.d , t1.d) NOT IN ( + SELECT t3.d , t2.c + FROM t3 LEFT JOIN t2 ON t3.a = t2.a); + +set @@optimizer_switch='materialization=off,in_to_exists=on'; + +EXPLAIN SELECT * +FROM t1 +WHERE (t1.d , t1.d) NOT IN ( + SELECT t3.d , t2.c + FROM t3 LEFT JOIN t2 ON t3.a = t2.a); + +SELECT * +FROM t1 +WHERE (t1.d , t1.d) NOT IN ( + SELECT t3.d , t2.c + FROM t3 LEFT JOIN t2 ON t3.a = t2.a); + +drop table t1, t2, t3; + +--echo # +--echo # LP BUG#809266 Diverging results with partial_match_rowid_merge=on +--echo # + +CREATE TABLE t1 (c int) ; +INSERT INTO t1 VALUES (0),(0); + +CREATE TABLE t2 (a int, b int) ; +INSERT INTO t2 VALUES (6,3), (9,NULL); + +set @@optimizer_switch='materialization=on,partial_match_rowid_merge=on,partial_match_table_scan=off,in_to_exists=off'; + +EXPLAIN +SELECT * FROM t1 WHERE (6, 4 ) NOT IN (SELECT b, a FROM t2); +SELECT * FROM t1 WHERE (6, 4 ) NOT IN (SELECT b, a FROM t2); + +EXPLAIN +SELECT * FROM t1 WHERE (6, 4 ) NOT IN (SELECT a, b FROM t2); +SELECT * FROM t1 WHERE (6, 4 ) NOT IN (SELECT a, b FROM t2); + +set @@optimizer_switch='materialization=off,in_to_exists=on'; + +EXPLAIN +SELECT * FROM t1 WHERE (6, 4 ) NOT IN (SELECT b, a FROM t2); +SELECT * FROM t1 WHERE (6, 4 ) NOT IN (SELECT b, a FROM t2); + +EXPLAIN +SELECT * FROM t1 WHERE (6, 4 ) NOT IN (SELECT a, b FROM t2); +SELECT * FROM t1 WHERE (6, 4 ) NOT IN (SELECT a, b FROM t2); + +drop table t1, t2; + set @@optimizer_switch=@save_optimizer_switch; diff --git a/mysql-test/t/subselect_scache.test b/mysql-test/t/subselect_scache.test new file mode 100644 index 00000000000..0032b148643 --- /dev/null +++ b/mysql-test/t/subselect_scache.test @@ -0,0 +1,11 @@ +# +# Run subselect.test without semi-join optimization (test materialize) +# +select @@optimizer_switch like '%subquery_cache=on%'; +set optimizer_switch='subquery_cache=on'; + +--source t/subselect.test + +set optimizer_switch=default; +select @@optimizer_switch like '%subquery_cache=on%'; + diff --git a/mysql-test/t/subselect_sj.test b/mysql-test/t/subselect_sj.test index 33f3e936482..66c7b1bc549 100644 --- a/mysql-test/t/subselect_sj.test +++ b/mysql-test/t/subselect_sj.test @@ -3,8 +3,16 @@ # --disable_warnings drop table if exists t0, t1, t2, t3, t4, t10, t11, t12; +drop view if exists v1, v2, v3, v4; +drop procedure if exists p1; --enable_warnings +set @subselect_sj_tmp= @@optimizer_switch; +set optimizer_switch='semijoin=on,firstmatch=on,loosescan=on'; +set optimizer_switch='mrr=on,mrr_sort_keys=on,index_condition_pushdown=on'; +# The 'default' value within the scope of this test: +set @save_optimizer_switch=@@optimizer_switch; + # # 1. Subqueries that are converted into semi-joins # @@ -224,7 +232,8 @@ INSERT INTO WORKS VALUES ('E4','P2',20); INSERT INTO WORKS VALUES ('E4','P4',40); INSERT INTO WORKS VALUES ('E4','P5',80); -set optimizer_switch='default,materialization=off'; +set optimizer_switch=@save_optimizer_switch; +set optimizer_switch='materialization=off'; explain SELECT EMPNUM, EMPNAME FROM STAFF @@ -240,7 +249,7 @@ WHERE EMPNUM IN WHERE PNUM IN (SELECT PNUM FROM PROJ)); -set optimizer_switch='default'; +set optimizer_switch=@save_optimizer_switch; drop table STAFF,WORKS,PROJ; @@ -308,7 +317,7 @@ FROM t0 WHERE varchar_nokey IN ( SELECT t1 .varchar_key from t1 ); - +--disable_parsing # wrong duplicate results - LP BUG#702374 SELECT t0.int_key FROM t0 WHERE t0.varchar_nokey IN ( @@ -322,7 +331,7 @@ WHERE t0.varchar_nokey IN ( SELECT t1_1 .varchar_key FROM t1 AS t1_1 JOIN t1 AS t1_2 ON t1_1 .int_key ); - +--enable_parsing DROP TABLE t0, t1, t2; --echo # End of bug#46550 @@ -359,7 +368,7 @@ drop table t1, t2; drop view v1; drop procedure p1; -set SESSION optimizer_switch='default'; +set SESSION optimizer_switch=@save_optimizer_switch; --echo # End of bug#46744 @@ -526,7 +535,7 @@ DROP TABLE t1,t2; DROP VIEW v1,v2; DROP PROCEDURE p1; -set SESSION optimizer_switch='default'; +set SESSION optimizer_switch=@save_optimizer_switch; --echo # End of BUG#48834 @@ -640,6 +649,7 @@ CREATE TABLE it1 ( ); INSERT INTO it1 VALUES (9,5), (0,4); +--sorted_result SELECT int_key FROM ot1 WHERE int_nokey IN (SELECT it2.int_key FROM it1 LEFT JOIN it2 ON it2.datetime_key); @@ -935,3 +945,631 @@ DROP TABLE t2; DROP TABLE t3; --echo # End of Bug#48623 + +--echo # +--echo # LPBUG#602574: RQG: sql_select.cc:5385: bool greedy_search(JOIN*, table_map, uint, +--echo # uint): Assertion `join->best_read < +--echo # +set @save_optimizer_switch=@@optimizer_switch; +set optimizer_switch='materialization=off'; +CREATE TABLE t1 ( + varchar_key varchar(1) DEFAULT NULL, + KEY varchar_key (varchar_key) +); + +CREATE TABLE t2 ( + varchar_key varchar(1) DEFAULT NULL, + KEY varchar_key (varchar_key) +); +INSERT INTO t2 VALUES + (NULL),(NULL),(NULL),(NULL),('a'),('a'),('a'),('b'),('b'),('b'),('b'),('c'), + ('c'),('c'),('c'),('c'),('c'),('c'),('d'),('d'),('d'),('d'),('d'),('d'),('e'), + ('e'),('e'),('e'),('e'),('e'),('f'),('f'),('f'),('g'),('g'),('h'),('h'),('h'), + ('h'),('i'),('j'),('j'),('j'),('k'),('k'),('l'),('l'),('m'),('m'),('m'),('m'), + ('n'),('n'),('n'),('o'),('o'),('o'),('p'),('p'),('p'),('q'),('q'),('q'),('r'), + ('r'),('r'),('r'),('s'),('s'),('s'),('s'),('t'),('t'),('t'),('t'),('u'),('u'), + ('u'),('u'),('v'),('v'),('v'),('v'),('w'),('w'),('w'),('w'),('w'),('w'),('x'), + ('x'),('x'),('y'),('y'),('y'),('y'),('z'),('z'),('z'),('z'); + +CREATE TABLE t3 ( + varchar_key varchar(1) DEFAULT NULL, + KEY varchar_key (varchar_key) +) ENGINE=MyISAM DEFAULT CHARSET=latin1; +INSERT INTO t3 VALUES + (NULL),('c'),('d'),('e'),('f'),('h'),('j'),('k'),('k'),('m'),('m'),('m'), + ('n'),('o'),('r'),('t'),('t'),('u'),('w'),('y'); + +SELECT varchar_key FROM t3 +WHERE (SELECT varchar_key FROM t3 + WHERE (varchar_key,varchar_key) + IN (SELECT t1.varchar_key, t2 .varchar_key + FROM t1 RIGHT JOIN t2 ON t1.varchar_key + ) + ); +set optimizer_switch=@save_optimizer_switch; +DROP TABLE t1, t2, t3; + +--echo # +--echo # Bug#46692 "Crash occurring on queries with nested FROM subqueries +--echo # using materialization." +--echo # +CREATE TABLE t1 ( + pk INTEGER PRIMARY KEY, + int_key INTEGER, + KEY int_key(int_key) +); +INSERT INTO t1 VALUES (10,186),(11,NULL),(12,2),(13,3),(14,0),(15,133),(16,1); + +CREATE TABLE t2 ( + pk INTEGER PRIMARY KEY, + int_key INTEGER, + KEY int_key(int_key) +); +INSERT INTO t2 VALUES (1,7),(2,2); + +SELECT * FROM t1 WHERE (140, 4) IN + (SELECT t2.int_key, t2 .pk FROM t2 STRAIGHT_JOIN t1 ON t2.int_key); + +DROP TABLE t1, t2; + +--echo # +--echo # Bug#42353 "SELECT ... WHERE oe IN (SELECT w/ LEFT JOIN) query +--echo # causes crash." +--echo # +CREATE TABLE t1 ( + pk INTEGER PRIMARY KEY, + int_nokey INTEGER, + int_key INTEGER, + date_key DATE, + datetime_nokey DATETIME, + varchar_nokey VARCHAR(1) +); + +CREATE TABLE t2 ( + date_nokey DATE +); + +CREATE TABLE t3 ( + pk INTEGER PRIMARY KEY, + int_nokey INTEGER, + date_key date, + varchar_key VARCHAR(1), + varchar_nokey VARCHAR(1), + KEY date_key (date_key) +); + +SELECT date_key FROM t1 +WHERE (int_key, int_nokey) + IN (SELECT t3.int_nokey, t3.pk + FROM t2 LEFT JOIN t3 ON (t2.date_nokey < t3.date_key) + WHERE t3.varchar_key <= t3.varchar_nokey OR t3.int_nokey <= t3.pk + ) + AND (varchar_nokey <> 'f' OR NOT int_key < 7); + + +--echo # +--echo # Bug#45933 "Crash in optimize_semijoin_nests on JOIN in subquery +--echo # + AND in outer query". +--echo # +INSERT INTO t1 VALUES (10,7,5,'2009-06-16','2002-04-10 14:25:30','w'), + (11,7,0,'0000-00-00','0000-00-00 00:00:00','s'), + (12,4,0,'2003-07-14','2006-09-14 04:01:02','y'), + (13,0,4,'2002-07-25','0000-00-00 00:00:00','c'), + (14,1,8,'2007-07-03','0000-00-00 00:00:00','q'), + (15,6,5,'2001-11-12','0000-00-00 00:00:00',''), + (16,2,9,'0000-00-00','0000-00-00 00:00:00','j'), + (29,9,1,'0000-00-00','2003-08-11 00:00:00','m'); +INSERT INTO t3 VALUES (1,9,'0000-00-00','b','b'), + (2,2,'2002-09-17','h','h'); + +SELECT t1.varchar_nokey FROM t1 JOIN t3 ON t1.datetime_nokey +WHERE t1.varchar_nokey + IN (SELECT varchar_nokey FROM t1 + WHERE (pk) + IN (SELECT t3.int_nokey + FROM t3 LEFT JOIN t1 ON t1.varchar_nokey + WHERE t3.date_key BETWEEN '2008-06-07' AND '2006-06-26' + ) + ); + +DROP TABLE t1, t2, t3; + +--echo # +--echo # Bug#45219 "Crash on SELECT DISTINCT query containing a +--echo # LEFT JOIN in subquery" +--echo # + +CREATE TABLE t1 ( + pk INTEGER NOT NULL, + int_nokey INTEGER NOT NULL, + datetime_key DATETIME NOT NULL, + varchar_key VARCHAR(1) NOT NULL, + PRIMARY KEY (pk), + KEY datetime_key (datetime_key), + KEY varchar_key (varchar_key) +); +INSERT INTO t1 VALUES +(1,9,'0000-00-00 00:00:00','p'),(2,0,'2002-02-09 07:38:13','v'), +(3,8,'2001-05-03 12:08:14','t'),(4,3,'0000-00-00 00:00:00','u'), +(5,7,'2009-07-28 03:43:30','n'),(6,0,'2009-08-04 00:00:00','l'), +(7,1,'0000-00-00 00:00:00','h'),(8,9,'0000-00-00 00:00:00','u'), +(9,0,'2005-08-02 17:16:54','n'),(10,9,'2002-12-21 00:00:00','j'), +(11,0,'2005-08-15 12:37:35','k'),(12,5,'0000-00-00 00:00:00','e'), +(13,0,'2006-03-10 00:00:00','i'),(14,8,'2005-05-16 11:02:36','u'), +(15,8,'2008-11-02 00:00:00','n'),(16,5,'2006-03-15 00:00:00','b'), +(17,1,'0000-00-00 00:00:00','x'),(18,7,'0000-00-00 00:00:00',''), +(19,0,'2008-12-17 20:15:40','q'),(20,9,'0000-00-00 00:00:00','u'); + +CREATE TABLE t2 LIKE t1; +INSERT INTO t2 VALUES +(10,0,'2006-07-07 07:26:28','q'),(11,5,'2002-09-23 00:00:00','m'), +(12,7,'0000-00-00 00:00:00','j'),(13,1,'2006-06-07 00:00:00','z'), +(14,8,'2000-09-16 12:15:34','a'),(15,2,'2007-08-05 15:47:52',''), +(16,1,'0000-00-00 00:00:00','e'),(17,8,'2005-12-02 19:34:26','t'), +(18,5,'0000-00-00 00:00:00','q'),(19,4,'0000-00-00 00:00:00','b'), +(20,5,'2007-12-28 00:00:00','w'),(21,3,'2004-08-02 11:48:43','m'), +(22,0,'0000-00-00 00:00:00','x'),(23,8,'2004-04-19 12:18:43',''), +(24,0,'2009-04-27 00:00:00','w'),(25,4,'2006-10-20 14:52:15','x'), +(26,0,'0000-00-00 00:00:00','e'),(27,0,'2002-03-22 11:48:37','e'), +(28,2,'0000-00-00 00:00:00','p'),(29,0,'2001-01-04 03:55:07','x'); + +CREATE TABLE t3 LIKE t1; +INSERT INTO t3 VALUES +(10,8,'2007-08-19 08:08:38','i'),(11,0,'2000-05-21 03:51:51',''); + +SELECT DISTINCT datetime_key FROM t1 +WHERE (int_nokey, pk) + IN (SELECT t3.pk, t3.pk FROM t2 LEFT JOIN t3 ON t3.varchar_key) + AND pk = 9; + +DROP TABLE t1, t2, t3; + +--echo # +--echo # BUG#784723: Wrong result with semijoin + nested subqueries in maria-5.3 +--echo # +CREATE TABLE t1 ( t1field integer, primary key (t1field)); +CREATE TABLE t2 ( t2field integer, primary key (t2field)); +INSERT INTO t1 VALUES (1),(2),(3); +INSERT INTO t2 VALUES (2),(3),(4); +explain +SELECT * FROM t1 A +WHERE + A.t1field IN (SELECT A.t1field FROM t2 B) AND + A.t1field IN (SELECT C.t2field FROM t2 C + WHERE C.t2field IN (SELECT D.t2field FROM t2 D)); +SELECT * FROM t1 A +WHERE + A.t1field IN (SELECT A.t1field FROM t2 B) AND + A.t1field IN (SELECT C.t2field FROM t2 C + WHERE C.t2field IN (SELECT D.t2field FROM t2 D)); +drop table t1,t2; + +--echo # +--echo # BUG#787299: Valgrind complains on a join query with two IN subqueries +--echo # +create table t1 (a int); +insert into t1 values (1), (2), (3); +create table t2 as select * from t1; +select * from t1 A, t1 B + where A.a = B.a and A.a in (select a from t2 C) and B.a in (select a from t2 D); +explain +select * from t1 A, t1 B + where A.a = B.a and A.a in (select a from t2 C) and B.a in (select a from t2 D); +drop table t1, t2; + +--echo # +--echo # BUG#784441: Abort on semijoin with a view as the inner table +--echo # + +CREATE TABLE t1 (a int) ; +INSERT INTO t1 VALUES (1), (1); + +CREATE TABLE t2 (a int) ; +INSERT INTO t2 VALUES (1), (1); + +CREATE VIEW v1 AS SELECT 1; + +EXPLAIN +SELECT * FROM t1 INNER JOIN t2 ON t2.a != 0 AND t2.a IN (SELECT * FROM v1); +SELECT * FROM t1 INNER JOIN t2 ON t2.a != 0 AND t2.a IN (SELECT * FROM v1); + +DROP VIEW v1; +DROP TABLE t1,t2; + +--echo # +--echo # BUG#751439 Assertion `!table->file || table->file->inited == handler::NONE' failed with subquery +--echo # +CREATE TABLE t1 ( f10 int, f11 int) ; +INSERT IGNORE INTO t1 VALUES (0,0),(0,0); + +CREATE TABLE t2 ( f11 int); +INSERT IGNORE INTO t2 VALUES (0),(0); + +CREATE TABLE t3 ( f11 int) ; +INSERT IGNORE INTO t3 VALUES (0); + +SELECT alias1.f11 AS field2 +FROM ( t3 AS alias2 JOIN t1 AS alias3 ON alias3.f10 = 1) +LEFT JOIN ( t2 AS alias1 ) ON alias3.f11 = 1 +WHERE alias2.f11 IN ( SELECT f11 FROM t2 ) +GROUP BY field2 ; + +drop table t1, t2, t3; + +--echo # +--echo # BUG#778406 Crash in hp_movelink with Aria engine and subqueries +--echo # +CREATE TABLE t4 (f10 varchar(32) , KEY (f10)) ENGINE=Aria; +INSERT INTO t4 VALUES ('x'),('m'),('c'); + +CREATE TABLE t1 (f11 int) ENGINE=Aria; +INSERT INTO t1 VALUES (0),(0),(0); + +CREATE TABLE t2 ( f10 int) ENGINE=Aria; +INSERT INTO t2 VALUES (0),(0),(0); + +CREATE TABLE t3 ( f10 int, f11 int) ENGINE=Aria; + +SELECT * +FROM t4 +WHERE f10 IN +( SELECT t1.f11 +FROM t1 +LEFT JOIN t2 JOIN t3 ON t3.f10 = t2.f10 ON t3.f11 != 0 ); + +drop table t1,t2,t3,t4; + +--echo # +--echo # BUG#751484: Valgrind warning / sporadic crash in evaluate_join_record sql_select.cc:14099 with semijoin +--echo # + +CREATE TABLE t1 ( f10 int, f11 int, KEY (f10)); +INSERT IGNORE INTO t1 VALUES (0, 0),(0, 0); + +CREATE TABLE t3 ( f10 int); +INSERT IGNORE INTO t3 VALUES (0); + +set @tmp_751484= @@optimizer_switch; +set optimizer_switch='materialization=on'; +SELECT * FROM t1 +WHERE f11 IN ( + SELECT C_SQ1_alias1.f11 + FROM t1 AS C_SQ1_alias1 + JOIN t3 AS C_SQ1_alias2 + ON C_SQ1_alias2.f10 = C_SQ1_alias1.f10 +); +set optimizer_switch='materialization=off'; +SELECT * FROM t1 +WHERE f11 IN ( + SELECT C_SQ1_alias1.f11 + FROM t1 AS C_SQ1_alias1 + JOIN t3 AS C_SQ1_alias2 + ON C_SQ1_alias2.f10 = C_SQ1_alias1.f10 +); +set optimizer_switch=@tmp_751484; +drop table t1, t3; + +# +--echo # BUG#795530 Wrong result with subquery semijoin materialization and outer join +--echo # Simplified testcase that uses DuplicateElimination +--echo # +create table t1 (a int); +create table t2 (a int, b char(10)); + +insert into t1 values (1),(2); +insert into t2 values (1, 'one'), (3, 'three'); + +create table t3 (b char(10)); +insert into t3 values('three'),( 'four'); +insert into t3 values('three'),( 'four'); +insert into t3 values('three'),( 'four'); +insert into t3 values('three'),( 'four'); +explain select * from t3 where t3.b in (select t2.b from t1 left join t2 on t1.a=t2.a); +select * from t3 where t3.b in (select t2.b from t1 left join t2 on t1.a=t2.a); +drop table t1, t2, t3; + +--echo # +--echo # BUG#600958 RQG: Crash in optimize_semijoin_nests +--echo # +CREATE TABLE t1 ( + pk int(11) NOT NULL AUTO_INCREMENT, + col_int_key int(11) DEFAULT NULL, + col_date_key date DEFAULT NULL, + col_varchar_key varchar(1) DEFAULT NULL, + PRIMARY KEY (pk), + KEY col_int_key (col_int_key), + KEY col_date_key (col_date_key), + KEY col_varchar_key (col_varchar_key,col_int_key) +) ENGINE=MyISAM AUTO_INCREMENT=11 DEFAULT CHARSET=latin1; +INSERT INTO t1 VALUES (10,8,'2002-02-21',NULL); +CREATE TABLE t2 ( + pk int(11) NOT NULL AUTO_INCREMENT, + col_int_key int(11) DEFAULT NULL, + col_date_key date DEFAULT NULL, + col_varchar_key varchar(1) DEFAULT NULL, + PRIMARY KEY (pk), + KEY col_int_key (col_int_key), + KEY col_date_key (col_date_key), + KEY col_varchar_key (col_varchar_key,col_int_key) +) ENGINE=MyISAM AUTO_INCREMENT=2 DEFAULT CHARSET=latin1; +INSERT INTO t2 VALUES (1,7,'1900-01-01','f'); + +SELECT col_date_key FROM t1 +WHERE 5 IN ( + SELECT SUBQUERY3_t1 .col_int_key + FROM t2 SUBQUERY3_t1 + LEFT JOIN t1 SUBQUERY3_t2 ON SUBQUERY3_t1 .col_varchar_key +); +drop table t2, t1; + + +--echo # +--echo # No BUG#: Duplicate weedout check is not done for outer joins +--echo # +create table t1 (a int); +create table t2 (a int); + +insert into t1 values (1),(1),(2),(2); +insert into t2 values (1); + +create table t0 (a int); +insert into t0 values (1),(2); + +set @tmp_20110622= @@optimizer_switch; +set optimizer_switch='firstmatch=off,loosescan=off,materialization=off'; +--echo # Check DuplicateWeedout + join buffer +explain +select * from t0 where a in (select t1.a from t1 left join t2 on t1.a=t2.a); +select * from t0 where a in (select t1.a from t1 left join t2 on t1.a=t2.a); + +--echo # Check DuplicateWeedout without join buffer +set @tmp_jcl_20110622= @@join_cache_level; +set join_cache_level= 0; +explain +select * from t0 where a in (select t1.a from t1 left join t2 on t1.a=t2.a); +select * from t0 where a in (select t1.a from t1 left join t2 on t1.a=t2.a); + + +--echo # Check FirstMatch without join buffer: +set optimizer_switch='firstmatch=on'; +explain +select * from t0 where a in (select t1.a from t1 left join t2 on t1.a=t2.a); +select * from t0 where a in (select t1.a from t1 left join t2 on t1.a=t2.a); + +--echo # +--echo # Now, check the same for multiple inner tables: +alter table t2 add b int; +update t2 set b=a; +create table t3 as select * from t2; + +set optimizer_switch='firstmatch=off'; +set join_cache_level= 0; +--echo # DuplicateWeedout without join buffer +explain +select * from t0 +where a in (select t1.a from t1 left join (t3 join t2 on t3.b=t2.b) on t1.a=t3.a); + +select * from t0 +where a in (select t1.a from t1 left join (t3 join t2 on t3.b=t2.b) on t1.a=t3.a); + +set @@join_cache_level=@tmp_jcl_20110622; +--echo # DuplicateWeedout + join buffer +explain +select * from t0 +where a in (select t1.a from t1 left join (t3 join t2 on t3.b=t2.b) on t1.a=t3.a); + +select * from t0 +where a in (select t1.a from t1 left join (t3 join t2 on t3.b=t2.b) on t1.a=t3.a); + +--echo # Now, let the inner join side have a 'partial' match +select * from t3; +insert into t3 values(2,2); + +explain +select * from t0 +where a in (select t1.a from t1 left join (t3 join t2 on t3.b=t2.b) on t1.a=t3.a); + +select * from t0 +where a in (select t1.a from t1 left join (t3 join t2 on t3.b=t2.b) on t1.a=t3.a); + +set @@optimizer_switch=@tmp_20110622; + +drop table t0, t1, t2, t3; + +--echo # +--echo # BUG#802965: Crash in do_copy_not_null with semijoin=on in maria-5.3 +--echo # +set @save_802965= @@optimizer_switch; +set optimizer_switch='semijoin=on,materialization=off,firstmatch=off,loosescan=off'; + +CREATE TABLE t2 ( f1 int NOT NULL , PRIMARY KEY (f1)) ; +INSERT IGNORE INTO t2 VALUES (19),(20); + +CREATE TABLE t1 ( f1 int NOT NULL , PRIMARY KEY (f1)) ; +INSERT IGNORE INTO t1 VALUES (21),(22),(23),(24); + +SELECT * +FROM t2 , t1 +WHERE t2.f1 IN +( + SELECT SQ1_alias1.f1 + FROM t1 AS SQ1_alias1 LEFT JOIN t2 AS SQ1_alias2 JOIN t2 AS SQ1_alias3 ON SQ1_alias3.f1 ON SQ1_alias3.f1 +) +AND t1.f1 = t2.f1 ; + +DROP TABLE t1, t2; +set optimizer_switch=@save_802965; + +--echo # +--echo # BUG#803365: Crash in pull_out_semijoin_tables with outer join + semijoin + derived tables in maria-5.3 with WL#106 +--echo # +CREATE TABLE t1 ( f1 int) ; +INSERT INTO t1 VALUES (1),(1); + +CREATE TABLE t2 ( f2 int) ; +INSERT INTO t2 VALUES (1),(1); + +CREATE TABLE t3 ( f3 int) ; +INSERT INTO t3 VALUES (1),(1); + +SELECT * +FROM t1 +WHERE t1.f1 IN ( + SELECT t2.f2 + FROM t2 + LEFT JOIN ( + SELECT * + FROM t3 + ) AS alias1 + ON alias1.f3 = t2.f2 +); + +DROP TABLE t1,t2,t3; + + +--echo # +--echo # BUG#611704: Crash in replace_where_subcondition with nested subquery and semijoin=on +--echo # + +CREATE TABLE t1 ( f1 int) ; +CREATE TABLE t2 ( f1 int) ; +CREATE TABLE t3 ( f1 int) ; + +SELECT * FROM ( + SELECT t3.* + FROM t2 STRAIGHT_JOIN t3 + ON t3.f1 + AND (t3.f1 ) IN ( + SELECT t1.f1 + FROM t1 + ) +) AS alias1; +DROP TABLE t1,t2,t3; + +--echo # BUG#611704: another testcase: +CREATE TABLE t1 ( f1 int(11), f3 varchar(1), f4 varchar(1)) ; +CREATE TABLE t2 ( f2 int(11), KEY (f2)); +CREATE TABLE t3 ( f4 varchar(1)) ; + +PREPARE st1 FROM ' +SELECT * +FROM t1 +STRAIGHT_JOIN ( t2 STRAIGHT_JOIN t3 ON t2.f2 ) +ON (t1.f3) IN ( SELECT f4 FROM t1 ) +'; +EXECUTE st1; +DROP TABLE t1,t2,t3; + +--echo # +--echo # BUG#803457: Wrong result with semijoin + view + outer join in maria-5.3-subqueries-mwl90 +--echo # (Original testcase) +--echo # + +CREATE TABLE t1 (f1 int, f2 int ); +INSERT INTO t1 VALUES (2,0),(4,0),(0,NULL); + +CREATE TABLE t2 (f2 int, f3 int ); +INSERT INTO t2 VALUES (NULL,NULL),(0,0); + +CREATE TABLE t3 ( f1 int, f3 int ); +INSERT INTO t3 VALUES (2,0),(4,0),(0,NULL),(4,0),(8,0); + +CREATE TABLE t4 ( f2 int, KEY (f2) ); +INSERT INTO t4 VALUES (0),(NULL); + +CREATE VIEW v4 AS SELECT DISTINCT f2 FROM t4 ; + +--echo # The following must not have outer joins: +explain extended +SELECT * FROM t1 NATURAL LEFT JOIN (t2, t3) WHERE t2.f3 IN (SELECT * FROM t4); +SELECT * FROM t1 NATURAL LEFT JOIN (t2, t3) WHERE t2.f3 IN (SELECT * FROM t4); + +drop view v4; +drop table t1, t2, t3, t4; + +--echo # +--echo # BUG#803303: Wrong result with semijoin=on, outer join in maria-5.3-subqueries-mwl90 +--echo # + +--echo # Testcase#1: +set @tmp803303= @@optimizer_switch; +set optimizer_switch = 'semijoin=on,materialization=off,firstmatch=off,loosescan=off'; +CREATE TABLE t2 ( f1 int) ; +INSERT IGNORE INTO t2 VALUES (6),(8); +CREATE TABLE t1 ( f1 int, f2 int, f3 int) ; +INSERT IGNORE INTO t1 VALUES (8,0,0),(7,0,0),(9,0,0); +SELECT alias2.f1 +FROM t2 AS alias1 +LEFT JOIN ( t1 AS alias2 JOIN t1 AS alias3 ON alias3.f2 = alias2.f3 ) +ON alias3.f2 = alias2.f2 +WHERE alias2.f1 IN ( SELECT f1 FROM t2 AS alias4 ) ; +drop table t1,t2; +set optimizer_switch= @tmp803303; + +--echo # Testcase #2: +CREATE TABLE t1 ( f10 int) ; +INSERT INTO t1 VALUES (0),(0); + +CREATE TABLE t2 ( f10 int, f11 varchar(1)) ; +INSERT INTO t2 VALUES (0,'a'),(0,'b'); + +CREATE TABLE t3 ( f10 int) ; +INSERT INTO t3 VALUES (0),(0),(0),(0),(0); + +CREATE TABLE t4 ( f10 varchar(1), f11 int) ; +INSERT INTO t4 VALUES ('a',0),('b',0); + +SELECT * FROM t1 +LEFT JOIN ( t2 JOIN t3 ON t3.f10 = t2.f10 ) ON t1.f10 = t2.f10 +WHERE t2.f10 IN ( + SELECT t4.f11 + FROM t4 + WHERE t4.f10 != t2.f11 +); + +drop table t1,t2,t3,t4; + +--echo # +--echo # BUG#803457: Wrong result with semijoin + view + outer join in maria-5.3-subqueries-mwl90 +--echo # +set @tmp803457=@@optimizer_switch; +set optimizer_switch='materialization=off'; +CREATE TABLE t1 (f1 int, f2 int ); +INSERT INTO t1 VALUES (2,0),(4,0),(0,NULL); + +CREATE TABLE t2 (f2 int, f3 int ); +INSERT INTO t2 VALUES (NULL,NULL),(0,0); + +CREATE TABLE t3 ( f1 int, f3 int ); +INSERT INTO t3 VALUES (2,0),(4,0),(0,NULL),(4,0),(8,0); + +CREATE TABLE t4 ( f2 int); +INSERT INTO t4 VALUES (0),(NULL); + +--echo # The following uses Duplicate Weedout, and "End temporary" must not be +--echo # in the middle of the inner side of an outer join: +explain +SELECT * FROM t1 NATURAL LEFT JOIN (t2, t3) WHERE IFNULL(t2.f3,'foo') IN (SELECT * FROM t4); +SELECT * FROM t1 NATURAL LEFT JOIN (t2, t3 ) WHERE IFNULL(t2.f3,'foo') IN (SELECT * FROM t4); + +DROP TABLE t1, t2, t3, t4; +set @tmp803457=@@optimizer_switch; + +--echo # +--echo # BUG#818280: crash in do_copy_not_null() in maria-5.3 with semijoin +--echo # +CREATE TABLE t1 ( c1 int NOT NULL , c2 int NOT NULL, PRIMARY KEY (c1)) ; +INSERT IGNORE INTO t1 VALUES (2,7),(1,3),(5,6); + +CREATE TABLE t3 ( c1 int NOT NULL , c2 int NOT NULL, PRIMARY KEY (c1)) ; +INSERT IGNORE INTO t3 VALUES (2,7),(1,3),(5,6); + +CREATE TABLE t2 ( c1 int NOT NULL , c5 int NOT NULL ); +INSERT IGNORE INTO t2 VALUES (2,2),(2,2),(5,6); + +SELECT * FROM t1 WHERE c1 IN ( SELECT t3.c1 FROM t3 LEFT JOIN t2 ON t2 .c1 = t3 .c1 WHERE t2.c5 != 0 ); + +DROP TABLE t1, t2, t3; + +# The following command must be the last one the file +set optimizer_switch=@subselect_sj_tmp; diff --git a/mysql-test/t/subselect_sj2.test b/mysql-test/t/subselect_sj2.test index 0b5cb947588..7972ff50450 100644 --- a/mysql-test/t/subselect_sj2.test +++ b/mysql-test/t/subselect_sj2.test @@ -2,6 +2,10 @@ # DuplicateElimination strategy test # --source include/have_innodb.inc + +set @subselect_sj2_tmp= @@optimizer_switch; +set optimizer_switch='semijoin=on,firstmatch=on,loosescan=on'; +set optimizer_switch='mrr=on,mrr_sort_keys=on,index_condition_pushdown=on'; --disable_warnings drop table if exists t0, t1, t2, t3; drop view if exists v1; @@ -232,6 +236,9 @@ INSERT INTO t3 VALUES ('BEL','Dutch',59.2),('BLZ','English',50.8); --enable_query_log +# Disable materialization to avoid races between query plans +set @bug35674_save_optimizer_switch=@@optimizer_switch; +set optimizer_switch='materialization=off'; EXPLAIN SELECT Name FROM t2 WHERE t2.Code IN (SELECT Country FROM t1 WHERE Population > 5000000) @@ -239,6 +246,7 @@ SELECT Name FROM t2 t2.Code IN (SELECT Country FROM t3 WHERE Language='English' AND Percentage > 10 AND t2.Population > 100000); +set optimizer_switch=@bug35674_save_optimizer_switch; DROP TABLE t1,t2,t3; @@ -493,6 +501,12 @@ drop table t1, t2; # Bug#33062: subquery in stored routine cause crash # +--disable_warnings +drop procedure if exists p1; +drop procedure if exists p2; +drop procedure if exists p3; +drop procedure if exists p4; +--enable_warnings CREATE TABLE t1(a INT); CREATE TABLE t2(c INT); @@ -905,3 +919,32 @@ explain select 1 from t2 where c1 in (select convert(c6,char(1)) from t2); drop table t2, t3; + +--echo # +--echo # BUG#761598: InnoDB: Error: row_search_for_mysql() is called without ha_innobase::external_lock() in maria-5.3 +--echo # + +CREATE TABLE t1 ( f1 int NOT NULL , f10 int) ; +INSERT IGNORE INTO t1 VALUES (25,0),(29,0); + +CREATE TABLE t2 ( f10 int) ENGINE=InnoDB; + +CREATE TABLE t3 ( f11 int) ; +INSERT IGNORE INTO t3 VALUES (0); + +SELECT alias1.f10 AS field2 +FROM t2 AS alias1 +JOIN ( + t3 AS alias2 + JOIN t1 AS alias3 + ON alias3.f10 +) ON alias3.f1 +WHERE alias2.f11 IN ( + SELECT SQ4_alias1.f10 + FROM t1 AS SQ4_alias1 + LEFT JOIN t2 AS SQ4_alias3 ON SQ4_alias3.f10 +) +GROUP BY field2; +drop table t1, t2, t3; + +set optimizer_switch=@subselect_sj2_tmp; diff --git a/mysql-test/t/subselect_sj2_jcl6.test b/mysql-test/t/subselect_sj2_jcl6.test index 202ea139e5f..e4ae249c711 100644 --- a/mysql-test/t/subselect_sj2_jcl6.test +++ b/mysql-test/t/subselect_sj2_jcl6.test @@ -2,6 +2,12 @@ # Run subselect_sj2.test with BKA enabled # +set @save_optimizer_switch_jcl6=@@optimizer_switch; +set @@optimizer_switch='optimize_join_buffer_size=on'; +set @@optimizer_switch='semijoin_with_cache=on'; +set @@optimizer_switch='outer_join_with_cache=on'; +set optimizer_switch='mrr=on,mrr_sort_keys=on,index_condition_pushdown=on'; + set join_cache_level=6; show variables like 'join_cache_level'; @@ -9,3 +15,6 @@ show variables like 'join_cache_level'; set join_cache_level=default; show variables like 'join_cache_level'; + +set @@optimizer_switch=@save_optimizer_switch_jcl6; + diff --git a/mysql-test/t/subselect_sj2_mat.test b/mysql-test/t/subselect_sj2_mat.test new file mode 100644 index 00000000000..fdfa0f311d3 --- /dev/null +++ b/mysql-test/t/subselect_sj2_mat.test @@ -0,0 +1,10 @@ +# +# Run subselect_sj2.test with subquery materialization. +# +set optimizer_switch='materialization=on'; +set optimizer_switch='mrr=on,mrr_sort_keys=on,index_condition_pushdown=on'; + +--source t/subselect_sj2.test + +set optimizer_switch=default; +select @@optimizer_switch like '%materialization=on%'; diff --git a/mysql-test/t/subselect_sj_jcl6.test b/mysql-test/t/subselect_sj_jcl6.test index f821e1864be..44ee52686b3 100644 --- a/mysql-test/t/subselect_sj_jcl6.test +++ b/mysql-test/t/subselect_sj_jcl6.test @@ -2,6 +2,14 @@ # Run subselect_sj.test with BKA enabled # +set @save_optimizer_switch_jcl6=@@optimizer_switch; +set @@optimizer_switch='optimize_join_buffer_size=on'; +set @@optimizer_switch='semijoin=on,firstmatch=on,loosescan=on'; +set @@optimizer_switch='semijoin_with_cache=on'; +set @@optimizer_switch='outer_join_with_cache=on'; +set @@optimizer_switch='join_cache_hashed=off'; +set optimizer_switch='mrr=on,mrr_sort_keys=on,index_condition_pushdown=on'; + set join_cache_level=6; show variables like 'join_cache_level'; @@ -37,3 +45,5 @@ drop table t0, t1, t2; set join_cache_level=default; show variables like 'join_cache_level'; + +set @@optimizer_switch=@save_optimizer_switch_jcl6; diff --git a/mysql-test/t/subselect_sj_mat.test b/mysql-test/t/subselect_sj_mat.test new file mode 100644 index 00000000000..0ea1c3873eb --- /dev/null +++ b/mysql-test/t/subselect_sj_mat.test @@ -0,0 +1,1246 @@ +# +# Hash semi-join regression tests +# (WL#1110: Subquery optimization: materialization) +# + +set @subselect_sj_mat_tmp= @@optimizer_switch; +set optimizer_switch=ifnull(@subselect_mat_test_optimizer_switch_value, 'semijoin=on,firstmatch=on,loosescan=on'); +set optimizer_switch='mrr=on,mrr_sort_keys=on,index_condition_pushdown=on'; +set @optimizer_switch_local_default= @@optimizer_switch; + +--disable_warnings +drop table if exists t1, t2, t3, t1i, t2i, t3i; +drop table if exists columns; +drop table if exists t1_16, t2_16, t3_16; +drop view if exists v1, v2, v1m, v2m; +--enable_warnings + +create table t1 (a1 char(8), a2 char(8)); +create table t2 (b1 char(8), b2 char(8)); +create table t3 (c1 char(8), c2 char(8)); + +insert into t1 values ('1 - 00', '2 - 00'); +insert into t1 values ('1 - 01', '2 - 01'); +insert into t1 values ('1 - 02', '2 - 02'); + +insert into t2 values ('1 - 01', '2 - 01'); +insert into t2 values ('1 - 01', '2 - 01'); +insert into t2 values ('1 - 02', '2 - 02'); +insert into t2 values ('1 - 02', '2 - 02'); +insert into t2 values ('1 - 03', '2 - 03'); + +insert into t3 values ('1 - 01', '2 - 01'); +insert into t3 values ('1 - 02', '2 - 02'); +insert into t3 values ('1 - 03', '2 - 03'); +insert into t3 values ('1 - 04', '2 - 04'); + +# Indexed columns +create table t1i (a1 char(8), a2 char(8)); +create table t2i (b1 char(8), b2 char(8)); +create table t3i (c1 char(8), c2 char(8)); +create index it1i1 on t1i (a1); +create index it1i2 on t1i (a2); +create index it1i3 on t1i (a1, a2); + +create index it2i1 on t2i (b1); +create index it2i2 on t2i (b2); +create index it2i3 on t2i (b1, b2); + +create index it3i1 on t3i (c1); +create index it3i2 on t3i (c2); +create index it3i3 on t3i (c1, c2); + +insert into t1i select * from t1; +insert into t2i select * from t2; +insert into t3i select * from t3; + +# force the use of materialization +set @@optimizer_switch='materialization=on,in_to_exists=off,firstmatch=off'; + +/****************************************************************************** +* Simple tests. +******************************************************************************/ +# non-indexed nullable fields +explain extended +select * from t1 where a1 in (select b1 from t2 where b1 > '0'); +select * from t1 where a1 in (select b1 from t2 where b1 > '0'); + +explain extended +select * from t1 where a1 in (select b1 from t2 where b1 > '0' group by b1); +select * from t1 where a1 in (select b1 from t2 where b1 > '0' group by b1); + +explain extended +select * from t1 where (a1, a2) in (select b1, b2 from t2 where b1 > '0' group by b1, b2); +select * from t1 where (a1, a2) in (select b1, b2 from t2 where b1 > '0' group by b1, b2); + +explain extended +select * from t1 where (a1, a2) in (select b1, min(b2) from t2 where b1 > '0' group by b1); +select * from t1 where (a1, a2) in (select b1, min(b2) from t2 where b1 > '0' group by b1); + +# indexed columns +--replace_column 7 # +--replace_regex /it1.*/_it1_idx/ /test.t2i.*/_ref_/ /Using index$// /Using where$// +explain extended +select * from t1i where a1 in (select b1 from t2i where b1 > '0'); +select * from t1i where a1 in (select b1 from t2i where b1 > '0'); + +--replace_column 6 # 8 # 11 # +explain extended +select * from t1i where a1 in (select b1 from t2i where b1 > '0' group by b1); +select * from t1i where a1 in (select b1 from t2i where b1 > '0' group by b1); + +--replace_column 7 # +--replace_regex /it1.*/_it1_idx/ /test.t2i.*/_ref_/ /Using index$// /Using where$// +explain extended +select * from t1i where (a1, a2) in (select b1, b2 from t2i where b1 > '0'); +select * from t1i where (a1, a2) in (select b1, b2 from t2i where b1 > '0'); + +--replace_column 6 # 7 # 8 # 11 # +explain extended +select * from t1i where (a1, a2) in (select b1, b2 from t2i where b1 > '0' group by b1, b2); +select * from t1i where (a1, a2) in (select b1, b2 from t2i where b1 > '0' group by b1, b2); + +--replace_column 6 # 7 # 8 # 11 # +explain extended +select * from t1i where (a1, a2) in (select b1, min(b2) from t2i where b1 > '0' group by b1); +select * from t1i where (a1, a2) in (select b1, min(b2) from t2i where b1 > '0' group by b1); + +# BUG#31639: Wrong plan for uncorrelated subquery when loose scan is applicable. +explain extended +select * from t1 where (a1, a2) in (select b1, max(b2) from t2i group by b1); +select * from t1 where (a1, a2) in (select b1, max(b2) from t2i group by b1); + +prepare st1 from "explain select * from t1 where (a1, a2) in (select b1, max(b2) from t2i group by b1)"; +execute st1; +execute st1; +prepare st2 from "select * from t1 where (a1, a2) in (select b1, max(b2) from t2i group by b1)"; +execute st2; +execute st2; + +explain extended +select * from t1 where (a1, a2) in (select b1, min(b2) from t2i where b1 > '0' group by b1); +select * from t1 where (a1, a2) in (select b1, min(b2) from t2i where b1 > '0' group by b1); +-- error 1235 +select * from t1 where (a1, a2) in (select b1, min(b2) from t2i limit 1,1); + +# test re-optimization/re-execution with different execution methods +# prepare once, exec with different modes +set @save_optimizer_switch=@@optimizer_switch; +set @@optimizer_switch=@optimizer_switch_local_default; +set @@optimizer_switch='semijoin=off'; +prepare st1 from +"select * from t1 where (a1, a2) in (select b1, min(b2) from t2 where b1 > '0' group by b1)"; +set @@optimizer_switch=@optimizer_switch_local_default; +set @@optimizer_switch='materialization=off,in_to_exists=on'; +execute st1; +set @@optimizer_switch=@optimizer_switch_local_default; +set @@optimizer_switch='semijoin=off'; +execute st1; + +set @@optimizer_switch=@optimizer_switch_local_default; +set @@optimizer_switch='materialization=off,in_to_exists=on'; +prepare st1 from +"select * from t1 where (a1, a2) in (select b1, min(b2) from t2 where b1 > '0' group by b1)"; +set @@optimizer_switch=@optimizer_switch_local_default; +set @@optimizer_switch='semijoin=off'; +execute st1; +set @@optimizer_switch=@optimizer_switch_local_default; +set @@optimizer_switch='materialization=off,in_to_exists=on'; +execute st1; +set @@optimizer_switch=@save_optimizer_switch; + +# materialize the result of ORDER BY +# non-indexed fields +explain extended +select * from t1 where (a1, a2) in (select b1, b2 from t2 order by b1, b2); +select * from t1 where (a1, a2) in (select b1, b2 from t2 order by b1, b2); +# indexed fields +explain extended +select * from t1i where (a1, a2) in (select b1, b2 from t2i order by b1, b2); +select * from t1i where (a1, a2) in (select b1, b2 from t2i order by b1, b2); + +/****************************************************************************** +* Views, UNIONs, several levels of nesting. +******************************************************************************/ +# materialize the result of subquery over temp-table view + +create algorithm=merge view v1 as +select b1, c2 from t2, t3 where b2 > c2; + +create algorithm=merge view v2 as +select b1, c2 from t2, t3 group by b2, c2; + +create algorithm=temptable view v1m as +select b1, c2 from t2, t3 where b2 > c2; + +create algorithm=temptable view v2m as +select b1, c2 from t2, t3 group by b2, c2; + +select * from v1 where (c2, b1) in (select c2, b1 from v2 where b1 is not null); +select * from v1 where (c2, b1) in (select distinct c2, b1 from v2 where b1 is not null); + +select * from v1m where (c2, b1) in (select c2, b1 from v2m where b1 is not null); +select * from v1m where (c2, b1) in (select distinct c2, b1 from v2m where b1 is not null); + +drop view v1, v2, v1m, v2m; + +# nested subqueries, views +explain extended +select * from t1 +where (a1, a2) in (select b1, b2 from t2 where b1 > '0') and + (a1, a2) in (select c1, c2 from t3 + where (c1, c2) in (select b1, b2 from t2i where b2 > '0')); +select * from t1 +where (a1, a2) in (select b1, b2 from t2 where b1 > '0') and + (a1, a2) in (select c1, c2 from t3 + where (c1, c2) in (select b1, b2 from t2i where b2 > '0')); + +--replace_column 6 # 7 # 8 # 11 # +explain extended +select * from t1i +where (a1, a2) in (select b1, b2 from t2i where b1 > '0') and + (a1, a2) in (select c1, c2 from t3i + where (c1, c2) in (select b1, b2 from t2i where b2 > '0')); +select * from t1i +where (a1, a2) in (select b1, b2 from t2i where b1 > '0') and + (a1, a2) in (select c1, c2 from t3i + where (c1, c2) in (select b1, b2 from t2i where b2 > '0')); + +explain extended +select * from t1 +where (a1, a2) in (select b1, b2 from t2 + where b2 in (select c2 from t3 where c2 LIKE '%02') or + b2 in (select c2 from t3 where c2 LIKE '%03')) and + (a1, a2) in (select c1, c2 from t3 + where (c1, c2) in (select b1, b2 from t2i where b2 > '0')); +select * from t1 +where (a1, a2) in (select b1, b2 from t2 + where b2 in (select c2 from t3 where c2 LIKE '%02') or + b2 in (select c2 from t3 where c2 LIKE '%03')) and + (a1, a2) in (select c1, c2 from t3 + where (c1, c2) in (select b1, b2 from t2i where b2 > '0')); + +# as above with correlated innermost subquery +explain extended +select * from t1 +where (a1, a2) in (select b1, b2 from t2 + where b2 in (select c2 from t3 t3a where c1 = a1) or + b2 in (select c2 from t3 t3b where c2 LIKE '%03')) and + (a1, a2) in (select c1, c2 from t3 t3c + where (c1, c2) in (select b1, b2 from t2i where b2 > '0')); +select * from t1 +where (a1, a2) in (select b1, b2 from t2 + where b2 in (select c2 from t3 t3a where c1 = a1) or + b2 in (select c2 from t3 t3b where c2 LIKE '%03')) and + (a1, a2) in (select c1, c2 from t3 t3c + where (c1, c2) in (select b1, b2 from t2i where b2 > '0')); + + +# multiple levels of nesting subqueries, unions +--replace_column 6 # 7 # 8 # 11 # +explain extended +(select * from t1 +where (a1, a2) in (select b1, b2 from t2 + where b2 in (select c2 from t3 where c2 LIKE '%02') or + b2 in (select c2 from t3 where c2 LIKE '%03') + group by b1, b2) and + (a1, a2) in (select c1, c2 from t3 + where (c1, c2) in (select b1, b2 from t2i where b2 > '0'))) +UNION +(select * from t1i +where (a1, a2) in (select b1, b2 from t2i where b1 > '0') and + (a1, a2) in (select c1, c2 from t3i + where (c1, c2) in (select b1, b2 from t2i where b2 > '0'))); + +(select * from t1 +where (a1, a2) in (select b1, b2 from t2 + where b2 in (select c2 from t3 where c2 LIKE '%02') or + b2 in (select c2 from t3 where c2 LIKE '%03') + group by b1, b2) and + (a1, a2) in (select c1, c2 from t3 + where (c1, c2) in (select b1, b2 from t2i where b2 > '0'))) +UNION +(select * from t1i +where (a1, a2) in (select b1, b2 from t2i where b1 > '0') and + (a1, a2) in (select c1, c2 from t3i + where (c1, c2) in (select b1, b2 from t2i where b2 > '0'))); + + +# UNION of subqueries as a subquery (thus it is not computed via materialization) +explain extended +select * from t1 +where (a1, a2) in (select * from t1 where a1 > '0' UNION select * from t2 where b1 < '9') and + (a1, a2) in (select c1, c2 from t3 + where (c1, c2) in (select b1, b2 from t2i where b2 > '0')); +select * from t1 +where (a1, a2) in (select * from t1 where a1 > '0' UNION select * from t2 where b1 < '9') and + (a1, a2) in (select c1, c2 from t3 + where (c1, c2) in (select b1, b2 from t2i where b2 > '0')); +# as above, with a join conditon between the outer references +explain extended +select * from t1, t3 +where (a1, a2) in (select * from t1 where a1 > '0' UNION select * from t2 where b1 < '9') and + (c1, c2) in (select c1, c2 from t3 + where (c1, c2) in (select b1, b2 from t2i where b2 > '0')) and + a1 = c1; +select * from t1, t3 +where (a1, a2) in (select * from t1 where a1 > '0' UNION select * from t2 where b1 < '9') and + (c1, c2) in (select c1, c2 from t3 + where (c1, c2) in (select b1, b2 from t2i where b2 > '0')) and + a1 = c1; + + +/****************************************************************************** +* Negative tests, where materialization should not be applied. +******************************************************************************/ +# UNION in a subquery +explain extended +select * from t3 +where c1 in (select a1 from t1 where a1 > '0' UNION select b1 from t2 where b1 < '9'); +select * from t3 +where c1 in (select a1 from t1 where a1 > '0' UNION select b1 from t2 where b1 < '9'); + +# correlation +explain extended +select * from t1 +where (a1, a2) in (select b1, b2 from t2 + where b2 in (select c2 from t3 t3a where c1 = a1) or + b2 in (select c2 from t3 t3b where c2 LIKE '%03')) and + (a1, a2) in (select c1, c2 from t3 t3c + where (c1, c2) in (select b1, b2 from t2i where b2 > '0' or b2 = a2)); + +# subquery has no tables +explain extended +select * from t1 where (a1, a2) in (select '1 - 01', '2 - 01'); +select * from t1 where (a1, a2) in (select '1 - 01', '2 - 01'); +explain extended +select * from t1 where (a1, a2) in (select '1 - 01', '2 - 01' from dual); +select * from t1 where (a1, a2) in (select '1 - 01', '2 - 01' from dual); + + +/****************************************************************************** +* Subqueries in other uncovered clauses. +******************************************************************************/ + +/* SELECT clause */ +select ((a1,a2) IN (select * from t2 where b2 > '0')) IS NULL from t1; + +/* GROUP BY clause */ +create table columns (col int key); +insert into columns values (1), (2); + +explain extended +select * from t1 group by (select col from columns limit 1); +select * from t1 group by (select col from columns limit 1); + +explain extended +select * from t1 group by (a1 in (select col from columns)); +select * from t1 group by (a1 in (select col from columns)); + +/* ORDER BY clause */ +explain extended +select * from t1 order by (select col from columns limit 1); +select * from t1 order by (select col from columns limit 1); + +/****************************************************************************** +* Column types/sizes that affect materialization. +******************************************************************************/ + +/* + Test that BLOBs are not materialized (except when arguments of some functions). +*/ +# force materialization to be always considered +set @prefix_len = 6; + +# BLOB == 16 (small blobs that could be stored in HEAP tables) +set @blob_len = 16; +set @suffix_len = @blob_len - @prefix_len; + +create table t1_16 (a1 blob(16), a2 blob(16)); +create table t2_16 (b1 blob(16), b2 blob(16)); +create table t3_16 (c1 blob(16), c2 blob(16)); + +insert into t1_16 values + (concat('1 - 00', repeat('x', @suffix_len)), concat('2 - 00', repeat('x', @suffix_len))); +insert into t1_16 values + (concat('1 - 01', repeat('x', @suffix_len)), concat('2 - 01', repeat('x', @suffix_len))); +insert into t1_16 values + (concat('1 - 02', repeat('x', @suffix_len)), concat('2 - 02', repeat('x', @suffix_len))); + +insert into t2_16 values + (concat('1 - 01', repeat('x', @suffix_len)), concat('2 - 01', repeat('x', @suffix_len))); +insert into t2_16 values + (concat('1 - 02', repeat('x', @suffix_len)), concat('2 - 02', repeat('x', @suffix_len))); +insert into t2_16 values + (concat('1 - 03', repeat('x', @suffix_len)), concat('2 - 03', repeat('x', @suffix_len))); + +insert into t3_16 values + (concat('1 - 01', repeat('x', @suffix_len)), concat('2 - 01', repeat('x', @suffix_len))); +insert into t3_16 values + (concat('1 - 02', repeat('x', @suffix_len)), concat('2 - 02', repeat('x', @suffix_len))); +insert into t3_16 values + (concat('1 - 03', repeat('x', @suffix_len)), concat('2 - 03', repeat('x', @suffix_len))); +insert into t3_16 values + (concat('1 - 04', repeat('x', @suffix_len)), concat('2 - 04', repeat('x', @suffix_len))); + +# single value transformer +explain extended select left(a1,7), left(a2,7) +from t1_16 +where a1 in (select b1 from t2_16 where b1 > '0'); + +select left(a1,7), left(a2,7) +from t1_16 +where a1 in (select b1 from t2_16 where b1 > '0'); + +# row value transformer +explain extended select left(a1,7), left(a2,7) +from t1_16 +where (a1,a2) in (select b1, b2 from t2_16 where b1 > '0'); + +select left(a1,7), left(a2,7) +from t1_16 +where (a1,a2) in (select b1, b2 from t2_16 where b1 > '0'); + +# string function with a blob argument, the return type may be != blob +explain extended select left(a1,7), left(a2,7) +from t1_16 +where a1 in (select substring(b1,1,16) from t2_16 where b1 > '0'); + +select left(a1,7), left(a2,7) +from t1_16 +where a1 in (select substring(b1,1,16) from t2_16 where b1 > '0'); + +# group_concat with a blob argument - depends on +# the variable group_concat_max_len, and +# convert_blob_length == max_len*collation->mbmaxlen > CONVERT_IF_BIGGER_TO_BLOB +explain extended select left(a1,7), left(a2,7) +from t1_16 +where a1 in (select group_concat(b1) from t2_16 group by b2); + +select left(a1,7), left(a2,7) +from t1_16 +where a1 in (select group_concat(b1) from t2_16 group by b2); + +set @@group_concat_max_len = 256; # anything < (CONVERT_IF_BIGGER_TO_BLOB = 512) + +explain extended select left(a1,7), left(a2,7) +from t1_16 +where a1 in (select group_concat(b1) from t2_16 group by b2); + +select left(a1,7), left(a2,7) +from t1_16 +where a1 in (select group_concat(b1) from t2_16 group by b2); + +# BLOB column at the second (intermediate) level of nesting +explain extended +select * from t1 +where concat(a1,'x') IN + (select left(a1,8) from t1_16 + where (a1, a2) IN + (select t2_16.b1, t2_16.b2 from t2_16, t2 + where t2.b2 = substring(t2_16.b2,1,6) and + t2.b1 IN (select c1 from t3 where c2 > '0'))); + + +drop table t1_16, t2_16, t3_16; + + +# BLOB == 512 (CONVERT_IF_BIGGER_TO_BLOB == 512) +set @blob_len = 512; +set @suffix_len = @blob_len - @prefix_len; + +create table t1_512 (a1 blob(512), a2 blob(512)); +create table t2_512 (b1 blob(512), b2 blob(512)); +create table t3_512 (c1 blob(512), c2 blob(512)); + +insert into t1_512 values + (concat('1 - 00', repeat('x', @suffix_len)), concat('2 - 00', repeat('x', @suffix_len))); +insert into t1_512 values + (concat('1 - 01', repeat('x', @suffix_len)), concat('2 - 01', repeat('x', @suffix_len))); +insert into t1_512 values + (concat('1 - 02', repeat('x', @suffix_len)), concat('2 - 02', repeat('x', @suffix_len))); + +insert into t2_512 values + (concat('1 - 01', repeat('x', @suffix_len)), concat('2 - 01', repeat('x', @suffix_len))); +insert into t2_512 values + (concat('1 - 02', repeat('x', @suffix_len)), concat('2 - 02', repeat('x', @suffix_len))); +insert into t2_512 values + (concat('1 - 03', repeat('x', @suffix_len)), concat('2 - 03', repeat('x', @suffix_len))); + +insert into t3_512 values + (concat('1 - 01', repeat('x', @suffix_len)), concat('2 - 01', repeat('x', @suffix_len))); +insert into t3_512 values + (concat('1 - 02', repeat('x', @suffix_len)), concat('2 - 02', repeat('x', @suffix_len))); +insert into t3_512 values + (concat('1 - 03', repeat('x', @suffix_len)), concat('2 - 03', repeat('x', @suffix_len))); +insert into t3_512 values + (concat('1 - 04', repeat('x', @suffix_len)), concat('2 - 04', repeat('x', @suffix_len))); + +# single value transformer +explain extended select left(a1,7), left(a2,7) +from t1_512 +where a1 in (select b1 from t2_512 where b1 > '0'); + +select left(a1,7), left(a2,7) +from t1_512 +where a1 in (select b1 from t2_512 where b1 > '0'); + +# row value transformer +explain extended select left(a1,7), left(a2,7) +from t1_512 +where (a1,a2) in (select b1, b2 from t2_512 where b1 > '0'); + +select left(a1,7), left(a2,7) +from t1_512 +where (a1,a2) in (select b1, b2 from t2_512 where b1 > '0'); + +# string function with a blob argument, the return type may be != blob +explain extended select left(a1,7), left(a2,7) +from t1_512 +where a1 in (select substring(b1,1,512) from t2_512 where b1 > '0'); + +select left(a1,7), left(a2,7) +from t1_512 +where a1 in (select substring(b1,1,512) from t2_512 where b1 > '0'); + +# group_concat with a blob argument - depends on +# the variable group_concat_max_len, and +# convert_blob_length == max_len*collation->mbmaxlen > CONVERT_IF_BIGGER_TO_BLOB +explain extended select left(a1,7), left(a2,7) +from t1_512 +where a1 in (select group_concat(b1) from t2_512 group by b2); + +select left(a1,7), left(a2,7) +from t1_512 +where a1 in (select group_concat(b1) from t2_512 group by b2); + +set @@group_concat_max_len = 256; # anything < (CONVERT_IF_BIGGER_TO_BLOB = 512) + +explain extended select left(a1,7), left(a2,7) +from t1_512 +where a1 in (select group_concat(b1) from t2_512 group by b2); + +select left(a1,7), left(a2,7) +from t1_512 +where a1 in (select group_concat(b1) from t2_512 group by b2); + +drop table t1_512, t2_512, t3_512; + + +# BLOB == 1024 (group_concat_max_len == 1024) +set @blob_len = 1024; +set @suffix_len = @blob_len - @prefix_len; + +create table t1_1024 (a1 blob(1024), a2 blob(1024)); +create table t2_1024 (b1 blob(1024), b2 blob(1024)); +create table t3_1024 (c1 blob(1024), c2 blob(1024)); + +insert into t1_1024 values + (concat('1 - 00', repeat('x', @suffix_len)), concat('2 - 00', repeat('x', @suffix_len))); +insert into t1_1024 values + (concat('1 - 01', repeat('x', @suffix_len)), concat('2 - 01', repeat('x', @suffix_len))); +insert into t1_1024 values + (concat('1 - 02', repeat('x', @suffix_len)), concat('2 - 02', repeat('x', @suffix_len))); + +insert into t2_1024 values + (concat('1 - 01', repeat('x', @suffix_len)), concat('2 - 01', repeat('x', @suffix_len))); +insert into t2_1024 values + (concat('1 - 02', repeat('x', @suffix_len)), concat('2 - 02', repeat('x', @suffix_len))); +insert into t2_1024 values + (concat('1 - 03', repeat('x', @suffix_len)), concat('2 - 03', repeat('x', @suffix_len))); + +insert into t3_1024 values + (concat('1 - 01', repeat('x', @suffix_len)), concat('2 - 01', repeat('x', @suffix_len))); +insert into t3_1024 values + (concat('1 - 02', repeat('x', @suffix_len)), concat('2 - 02', repeat('x', @suffix_len))); +insert into t3_1024 values + (concat('1 - 03', repeat('x', @suffix_len)), concat('2 - 03', repeat('x', @suffix_len))); +insert into t3_1024 values + (concat('1 - 04', repeat('x', @suffix_len)), concat('2 - 04', repeat('x', @suffix_len))); + +# single value transformer +explain extended select left(a1,7), left(a2,7) +from t1_1024 +where a1 in (select b1 from t2_1024 where b1 > '0'); + +select left(a1,7), left(a2,7) +from t1_1024 +where a1 in (select b1 from t2_1024 where b1 > '0'); + +# row value transformer +explain extended select left(a1,7), left(a2,7) +from t1_1024 +where (a1,a2) in (select b1, b2 from t2_1024 where b1 > '0'); + +select left(a1,7), left(a2,7) +from t1_1024 +where (a1,a2) in (select b1, b2 from t2_1024 where b1 > '0'); + +# string function with a blob argument, the return type may be != blob +explain extended select left(a1,7), left(a2,7) +from t1_1024 +where a1 in (select substring(b1,1,1024) from t2_1024 where b1 > '0'); + +select left(a1,7), left(a2,7) +from t1_1024 +where a1 in (select substring(b1,1,1024) from t2_1024 where b1 > '0'); + +# group_concat with a blob argument - depends on +# the variable group_concat_max_len, and +# convert_blob_length == max_len*collation->mbmaxlen > CONVERT_IF_BIGGER_TO_BLOB +explain extended select left(a1,7), left(a2,7) +from t1_1024 +where a1 in (select group_concat(b1) from t2_1024 group by b2); + +select left(a1,7), left(a2,7) +from t1_1024 +where a1 in (select group_concat(b1) from t2_1024 group by b2); + +set @@group_concat_max_len = 256; # anything < (CONVERT_IF_BIGGER_TO_BLOB = 1024) + +explain extended select left(a1,7), left(a2,7) +from t1_1024 +where a1 in (select group_concat(b1) from t2_1024 group by b2); + +select left(a1,7), left(a2,7) +from t1_1024 +where a1 in (select group_concat(b1) from t2_1024 group by b2); + +drop table t1_1024, t2_1024, t3_1024; + + +# BLOB == 1025 +set @blob_len = 1025; +set @suffix_len = @blob_len - @prefix_len; + +create table t1_1025 (a1 blob(1025), a2 blob(1025)); +create table t2_1025 (b1 blob(1025), b2 blob(1025)); +create table t3_1025 (c1 blob(1025), c2 blob(1025)); + +insert into t1_1025 values + (concat('1 - 00', repeat('x', @suffix_len)), concat('2 - 00', repeat('x', @suffix_len))); +insert into t1_1025 values + (concat('1 - 01', repeat('x', @suffix_len)), concat('2 - 01', repeat('x', @suffix_len))); +insert into t1_1025 values + (concat('1 - 02', repeat('x', @suffix_len)), concat('2 - 02', repeat('x', @suffix_len))); + +insert into t2_1025 values + (concat('1 - 01', repeat('x', @suffix_len)), concat('2 - 01', repeat('x', @suffix_len))); +insert into t2_1025 values + (concat('1 - 02', repeat('x', @suffix_len)), concat('2 - 02', repeat('x', @suffix_len))); +insert into t2_1025 values + (concat('1 - 03', repeat('x', @suffix_len)), concat('2 - 03', repeat('x', @suffix_len))); + +insert into t3_1025 values + (concat('1 - 01', repeat('x', @suffix_len)), concat('2 - 01', repeat('x', @suffix_len))); +insert into t3_1025 values + (concat('1 - 02', repeat('x', @suffix_len)), concat('2 - 02', repeat('x', @suffix_len))); +insert into t3_1025 values + (concat('1 - 03', repeat('x', @suffix_len)), concat('2 - 03', repeat('x', @suffix_len))); +insert into t3_1025 values + (concat('1 - 04', repeat('x', @suffix_len)), concat('2 - 04', repeat('x', @suffix_len))); + +# single value transformer +explain extended select left(a1,7), left(a2,7) +from t1_1025 +where a1 in (select b1 from t2_1025 where b1 > '0'); + +select left(a1,7), left(a2,7) +from t1_1025 +where a1 in (select b1 from t2_1025 where b1 > '0'); + +# row value transformer +explain extended select left(a1,7), left(a2,7) +from t1_1025 +where (a1,a2) in (select b1, b2 from t2_1025 where b1 > '0'); + +select left(a1,7), left(a2,7) +from t1_1025 +where (a1,a2) in (select b1, b2 from t2_1025 where b1 > '0'); + +# string function with a blob argument, the return type may be != blob +explain extended select left(a1,7), left(a2,7) +from t1_1025 +where a1 in (select substring(b1,1,1025) from t2_1025 where b1 > '0'); + +select left(a1,7), left(a2,7) +from t1_1025 +where a1 in (select substring(b1,1,1025) from t2_1025 where b1 > '0'); + +# group_concat with a blob argument - depends on +# the variable group_concat_max_len, and +# convert_blob_length == max_len*collation->mbmaxlen > CONVERT_IF_BIGGER_TO_BLOB +explain extended select left(a1,7), left(a2,7) +from t1_1025 +where a1 in (select group_concat(b1) from t2_1025 group by b2); + +select left(a1,7), left(a2,7) +from t1_1025 +where a1 in (select group_concat(b1) from t2_1025 group by b2); + +set @@group_concat_max_len = 256; # anything < (CONVERT_IF_BIGGER_TO_BLOB = 1025) + +explain extended select left(a1,7), left(a2,7) +from t1_1025 +where a1 in (select group_concat(b1) from t2_1025 group by b2); + +select left(a1,7), left(a2,7) +from t1_1025 +where a1 in (select group_concat(b1) from t2_1025 group by b2); + +drop table t1_1025, t2_1025, t3_1025; + +# test for BIT fields +create table t1bit (a1 bit(3), a2 bit(3)); +create table t2bit (b1 bit(3), b2 bit(3)); + +insert into t1bit values (b'000', b'100'); +insert into t1bit values (b'001', b'101'); +insert into t1bit values (b'010', b'110'); + +insert into t2bit values (b'001', b'101'); +insert into t2bit values (b'010', b'110'); +insert into t2bit values (b'110', b'111'); + +explain extended select bin(a1), bin(a2) +from t1bit +where (a1, a2) in (select b1, b2 from t2bit); + +select bin(a1), bin(a2) +from t1bit +where (a1, a2) in (select b1, b2 from t2bit); + +drop table t1bit, t2bit; + +# test mixture of BIT and BLOB +create table t1bb (a1 bit(3), a2 blob(3)); +create table t2bb (b1 bit(3), b2 blob(3)); + +insert into t1bb values (b'000', '100'); +insert into t1bb values (b'001', '101'); +insert into t1bb values (b'010', '110'); + +insert into t2bb values (b'001', '101'); +insert into t2bb values (b'010', '110'); +insert into t2bb values (b'110', '111'); + +explain extended select bin(a1), a2 +from t1bb +where (a1, a2) in (select b1, b2 from t2bb); + +select bin(a1), a2 +from t1bb +where (a1, a2) in (select b1, b2 from t2bb); + +drop table t1bb, t2bb; +drop table t1, t2, t3, t1i, t2i, t3i, columns; + +/****************************************************************************** +* Test the cache of the left operand of IN. +******************************************************************************/ + +# Test that default values of Cached_item are not used for comparison +create table t1 (s1 int); +create table t2 (s2 int); +insert into t1 values (5),(1),(0); +insert into t2 values (0), (1); +select s2 from t2 where s2 in (select s1 from t1); +drop table t1, t2; + +create table t1 (a int not null, b int not null); +create table t2 (c int not null, d int not null); +create table t3 (e int not null); + +# the first outer row has no matching inner row +insert into t1 values (1,10); +insert into t1 values (1,20); +insert into t1 values (2,10); +insert into t1 values (2,20); +insert into t1 values (2,30); +insert into t1 values (3,20); +insert into t1 values (4,40); + +insert into t2 values (2,10); +insert into t2 values (2,20); +insert into t2 values (2,40); +insert into t2 values (3,20); +insert into t2 values (4,10); +insert into t2 values (5,10); + +insert into t3 values (10); +insert into t3 values (10); +insert into t3 values (20); +insert into t3 values (30); + +explain extended +select a from t1 where a in (select c from t2 where d >= 20); +select a from t1 where a in (select c from t2 where d >= 20); + +create index it1a on t1(a); + +explain extended +select a from t1 where a in (select c from t2 where d >= 20); +select a from t1 where a in (select c from t2 where d >= 20); + +# the first outer row has a matching inner row +insert into t2 values (1,10); + +explain extended +select a from t1 where a in (select c from t2 where d >= 20); +select a from t1 where a in (select c from t2 where d >= 20); + +# cacheing for IN predicates inside a having clause - here the cached +# items are changed to point to temporary tables. +explain extended +select a from t1 group by a having a in (select c from t2 where d >= 20); +select a from t1 group by a having a in (select c from t2 where d >= 20); + +# create an index that can be used for the outer query GROUP BY +create index iab on t1(a, b); +explain extended +select a from t1 group by a having a in (select c from t2 where d >= 20); +select a from t1 group by a having a in (select c from t2 where d >= 20); + +explain extended +select a from t1 group by a +having a in (select c from t2 where d >= some(select e from t3 where max(b)=e)); +select a from t1 group by a +having a in (select c from t2 where d >= some(select e from t3 where max(b)=e)); +explain extended +select a from t1 +where a in (select c from t2 where d >= some(select e from t3 where b=e)); +select a from t1 +where a in (select c from t2 where d >= some(select e from t3 where b=e)); + +drop table t1, t2, t3; + +# +# BUG#36133 "Assertion `exec_method != MATERIALIZATION || (exec_method == MATERIALIZATION &&" +# +create table t2 (a int, b int, key(a), key(b)); +insert into t2 values (3,3),(3,3),(3,3); +select 1 from t2 where + t2.a > 1 + or + t2.a = 3 and not t2.a not in (select t2.b from t2); +drop table t2; + +# +# BUG#37896 Assertion on entry of Item_in_subselect::exec on subquery with AND NOT +# +create table t1 (a1 int key); +create table t2 (b1 int); +insert into t1 values (5); + +# Query with group by, executed via materialization +explain select min(a1) from t1 where 7 in (select b1 from t2 group by b1); +select min(a1) from t1 where 7 in (select b1 from t2 group by b1); +# Query with group by, executed via IN=>EXISTS +set @save_optimizer_switch=@@optimizer_switch; +set @@optimizer_switch=@optimizer_switch_local_default; +set @@optimizer_switch='materialization=off,in_to_exists=on'; +explain select min(a1) from t1 where 7 in (select b1 from t2 group by b1); +select min(a1) from t1 where 7 in (select b1 from t2 group by b1); + +# Executed with materialization +set @@optimizer_switch=@optimizer_switch_local_default; +set @@optimizer_switch='semijoin=off'; +explain select min(a1) from t1 where 7 in (select b1 from t2); +select min(a1) from t1 where 7 in (select b1 from t2); +# Executed with semi-join. Notice, this time we get a different result (NULL). +# This is the only correct result of all four queries. This difference is +# filed as BUG#40037. +set @@optimizer_switch=@optimizer_switch_local_default; +set @@optimizer_switch='materialization=off,in_to_exists=on'; +-- echo # with MariaDB and MWL#90, this particular case is solved: +explain select min(a1) from t1 where 7 in (select b1 from t2); +select min(a1) from t1 where 7 in (select b1 from t2); +-- echo # but when we go around MWL#90 code, the problem still shows up: +explain select min(a1) from t1 where 7 in (select b1 from t2) or 2> 4; +select min(a1) from t1 where 7 in (select b1 from t2) or 2> 4; +set @@optimizer_switch= @save_optimizer_switch; +drop table t1,t2; + +# +# BUG#36752 "subquery materialization produces wrong results when comparing different types" +# +create table t1 (a char(2), b varchar(10)); +insert into t1 values ('a', 'aaa'); +insert into t1 values ('aa', 'aaaa'); + +explain select a,b from t1 where b in (select a from t1); +select a,b from t1 where b in (select a from t1); +prepare st1 from "select a,b from t1 where b in (select a from t1)"; +execute st1; +execute st1; +drop table t1; + +--echo # +--echo # BUG#49630: Segfault in select_describe() with double +--echo # nested subquery and materialization +--echo # + +CREATE TABLE t1 (t1i int); +CREATE TABLE t2 (t2i int); +CREATE TABLE t3 (t3i int); +CREATE TABLE t4 (t4i int); + +INSERT INTO t1 VALUES (1); # Note: t1 must be const table +INSERT INTO t2 VALUES (1),(2); +INSERT INTO t3 VALUES (1),(2); +INSERT INTO t4 VALUES (1),(2); + +--echo +EXPLAIN +SELECT t1i +FROM t1 JOIN t4 ON t1i=t4i +WHERE (t1i) IN ( + SELECT t2i + FROM t2 + WHERE (t2i) IN ( + SELECT t3i + FROM t3 + GROUP BY t3i + ) + ); + +DROP TABLE t1,t2,t3,t4; + + +# +# Bug #52538 Valgrind bug: Item_in_subselect::init_left_expr_cache() +# +CREATE TABLE t1 ( + pk INTEGER AUTO_INCREMENT, + col_int_nokey INTEGER, + col_int_key INTEGER, + + col_varchar_key VARCHAR(1), + + PRIMARY KEY (pk), + KEY (col_int_key), + KEY (col_varchar_key, col_int_key) +) +; + +INSERT INTO t1 ( + col_int_key, col_int_nokey, col_varchar_key +) +VALUES +(2, NULL, 'w'), +(9, 7, 'm'), +(3, 9, 'm'), +(9, 7, 'k'), +(NULL, 4, 'r'), +(9, 2, 't'), +(3, 6, 'j'), +(8, 8, 'u'), +(8, NULL, 'h'), +(53, 5, 'o'), +(0, NULL, NULL), +(5, 6, 'k'), +(166, 188, 'e'), +(3, 2, 'n'), +(0, 1, 't'), +(1, 1, 'c'), +(9, 0, 'm'), +(5, 9, 'y'), +(6, NULL, 'f'), +(2, 4, 'd') +; + +SELECT table2.col_varchar_key AS field1, + table2.col_int_nokey AS field2 +FROM ( t1 AS table1 LEFT OUTER JOIN t1 AS table2 + ON (table2.col_varchar_key = table1.col_varchar_key ) ) +WHERE table1.pk = 6 +HAVING ( field2 ) IN +( SELECT SUBQUERY2_t2.col_int_nokey AS SUBQUERY2_field2 + FROM ( t1 AS SUBQUERY2_t1 JOIN t1 AS SUBQUERY2_t2 + ON (SUBQUERY2_t2.col_varchar_key = SUBQUERY2_t1.col_varchar_key ) ) ) +ORDER BY field2 +; + +drop table t1; + + +--echo # +--echo # BUG#53103: MTR test ps crashes in optimize_cond() +--echo # when running with --debug +--echo # + +CREATE TABLE t1(track varchar(15)); + +INSERT INTO t1 VALUES ('CAD'), ('CAD'); + +PREPARE STMT FROM +"SELECT 1 FROM t1 + WHERE + track IN (SELECT track FROM t1 + GROUP BY track + HAVING track>='CAD')"; +EXECUTE STMT ; +EXECUTE STMT ; + +DEALLOCATE PREPARE STMT; +DROP TABLE t1; + +--echo # End of BUG#53103 + +--echo # +--echo # BUG#54511 - Assertion failed: cache != 0L in file +--echo # sql_select.cc::sub_select_cache on HAVING +--echo # + +CREATE TABLE t1 (i int(11)); +CREATE TABLE t2 (c char(1)); +CREATE TABLE t3 (c char(1)); + +# These records are needed for the test to fail with MyISAM. The test +# fails with InnoDB without these (difference due to optimization of +# aggregates available only in MyISAM) +INSERT INTO t1 VALUES (1), (2); +INSERT INTO t2 VALUES ('a'), ('b'); +INSERT INTO t3 VALUES ('x'), ('y'); + +SELECT COUNT( i ),i +FROM t1 +HAVING ('c') + IN (SELECT t2.c FROM (t2 JOIN t3)); + +DROP TABLE t1,t2,t3; + +--echo # End BUG#54511 + +--echo # +--echo # BUG#56367 - Assertion exec_method != EXEC_MATERIALIZATION... +--echo # on subquery in FROM +--echo # + +CREATE TABLE t1 (a INTEGER); + +CREATE TABLE t2 (b INTEGER); +INSERT INTO t2 VALUES (1); + +let $query = +SELECT a FROM ( + SELECT t1.* FROM t1 LEFT JOIN t2 ON t1.a > 3 OR t2.b IN (SELECT a FROM t1) +) table1; +eval explain $query; +eval $query; + +DROP TABLE t1, t2; + +--echo # End BUG#56367 + +--echo # +--echo # Bug#59833 - materialization=on/off leads to different result set +--echo # when using IN +--echo # + +CREATE TABLE t1 ( + pk int NOT NULL, + f1 int DEFAULT NULL, + PRIMARY KEY (pk) +) ENGINE=MyISAM; + +CREATE TABLE t2 ( + pk int NOT NULL, + f1 int DEFAULT NULL, + PRIMARY KEY (pk) +) ENGINE=MyISAM; + +INSERT INTO t1 VALUES (10,0); +INSERT INTO t2 VALUES (10,0),(11,0); + +let $query= +SELECT * FROM t1 JOIN t2 USING (f1) +WHERE t1.f1 IN (SELECT t1.pk FROM t1 ORDER BY t1.f1); + +eval explain $query; +eval $query; + +DROP TABLE t1, t2; + +--echo # End Bug#59833 + +--echo # +--echo # Bug#11852644 - CRASH IN ITEM_REF::SAVE_IN_FIELD ON SELECT DISTINCT +--echo # + +CREATE TABLE t1 ( + col_varchar_key varchar(1) DEFAULT NULL, + col_varchar_nokey varchar(1) DEFAULT NULL, + KEY col_varchar_key (col_varchar_key)) +; + +INSERT INTO t1 VALUES +('v','v'),('r','r'); + +CREATE TABLE t2 ( + col_varchar_key varchar(1) DEFAULT NULL, + col_varchar_nokey varchar(1) DEFAULT NULL, + KEY col_varchar_key(col_varchar_key)) +; + +INSERT INTO t2 VALUES +('r','r'),('c','c'); + +CREATE VIEW v3 AS SELECT * FROM t2; + +SELECT DISTINCT alias2.col_varchar_key +FROM t1 AS alias1 JOIN v3 AS alias2 +ON alias2.col_varchar_key = alias1.col_varchar_key +HAVING col_varchar_key IN (SELECT col_varchar_nokey FROM t2) +; + +DROP TABLE t1, t2; +DROP VIEW v3; + +--echo # End Bug#11852644 + +--echo +--echo # Bug#12668294 - GROUP BY ON EMPTY RESULT GIVES EMPTY ROW +--echo # INSTEAD OF NULL WHEN MATERIALIZATION ON +--echo + +CREATE TABLE t1 (col_int_nokey INT) ENGINE=MEMORY; +CREATE TABLE t2 (col_int_nokey INT) ENGINE=MEMORY; +INSERT INTO t2 VALUES (8),(7); +CREATE TABLE t3 (col_int_nokey INT) ENGINE=MEMORY; +INSERT INTO t3 VALUES (7); + +SELECT MIN(t3.col_int_nokey),t1.col_int_nokey AS field3 +FROM t3 + LEFT JOIN t1 + ON t1.col_int_nokey +WHERE (194, 200) IN ( + SELECT SQ4_alias1.col_int_nokey, + SQ4_alias2.col_int_nokey + FROM t2 AS SQ4_alias1 + JOIN + t2 AS SQ4_alias2 + ON SQ4_alias2.col_int_nokey = 5 + ) +GROUP BY field3 ; + +DROP TABLE t1; +DROP TABLE t2; +DROP TABLE t3; + +# +# Bug #44303 Assertion failures in Field_new_decimal::store_decimal +# when executing materialized InsideOut semijoin +# +CREATE TABLE t1 (f1 INT, f2 DECIMAL(5,3)) ENGINE=MyISAM; +INSERT INTO t1 (f1, f2) VALUES (1, 1.789); +INSERT INTO t1 (f1, f2) VALUES (13, 1.454); +INSERT INTO t1 (f1, f2) VALUES (10, 1.668); + +CREATE TABLE t2 LIKE t1; +INSERT INTO t2 VALUES (1, 1.789); +INSERT INTO t2 VALUES (13, 1.454); + +set @save_optimizer_switch=@@optimizer_switch; +set @@optimizer_switch=@optimizer_switch_local_default; +SET @@optimizer_switch='semijoin=on,materialization=on'; +EXPLAIN SELECT COUNT(*) FROM t1 WHERE (f1,f2) IN (SELECT f1,f2 FROM t2); +SELECT COUNT(*) FROM t1 WHERE (f1,f2) IN (SELECT f1,f2 FROM t2); +set @@optimizer_switch= @save_optimizer_switch; + +DROP TABLE t1, t2; + +# +# BUG#46548 IN-subqueries return 0 rows with materialization=on +# +CREATE TABLE t1 ( + pk int, + a varchar(1), + b varchar(4), + c varchar(4), + d varchar(4), + PRIMARY KEY (pk) +); +INSERT INTO t1 VALUES (1,'o','ffff','ffff','ffoo'),(2,'f','ffff','ffff','ffff'); + +CREATE TABLE t2 LIKE t1; +INSERT INTO t2 VALUES (1,'i','iiii','iiii','iiii'),(2,'f','ffff','ffff','ffff'); + +set @save_optimizer_switch=@@optimizer_switch; +set @@optimizer_switch=@optimizer_switch_local_default; +SET @@optimizer_switch='semijoin=on,materialization=on'; +EXPLAIN SELECT pk FROM t1 WHERE (a) IN (SELECT a FROM t2 WHERE pk > 0); +SELECT pk FROM t1 WHERE (a) IN (SELECT a FROM t2 WHERE pk > 0); +SELECT pk FROM t1 WHERE (b,c,d) IN (SELECT b,c,d FROM t2 WHERE pk > 0); +DROP TABLE t1, t2; +set optimizer_switch=@save_optimizer_switch; + +--echo # +--echo # BUG#50019: Wrong result for IN-subquery with materialization +--echo # +create table t1(i int); +insert into t1 values (1), (2), (3), (4), (5), (6), (7), (8), (9), (10); +create table t2(i int); +insert into t2 values (1), (2), (3), (4), (5), (6), (7), (8), (9), (10); +create table t3(i int); +insert into t3 values (1), (2), (3), (4), (5), (6), (7), (8), (9), (10); +select * from t1 where t1.i in (select t2.i from t2 join t3 where t2.i + t3.i = 5); +set @save_optimizer_switch=@@optimizer_switch; +set session optimizer_switch='materialization=off,in_to_exists=on'; +select * from t1 where t1.i in (select t2.i from t2 join t3 where t2.i + t3.i = 5); +set session optimizer_switch=@save_optimizer_switch; +drop table t1, t2, t3; + +# +# Test that the contents of the temp table of a materialized subquery is +# cleaned up between PS re-executions. +# + +create table t0 (a int); +insert into t0 values (0),(1),(2); +create table t1 (a int); +insert into t1 values (0),(1),(2); +explain select a, a in (select a from t1) from t0; +select a, a in (select a from t1) from t0; +prepare s from 'select a, a in (select a from t1) from t0'; +execute s; +update t1 set a=123; +execute s; +drop table t0, t1; +set optimizer_switch='firstmatch=on'; + +--echo # +--echo # MWL#90, review feedback: check what happens when the subquery +--echo # looks like candidate for MWL#90 checking at the first glance +--echo # but then subselect_hash_sj_engine::init_permanent() discovers +--echo # that it's not possible to perform duplicate removal for the +--echo # selected datatypes, and so materialization isn't applicable after +--echo # all. +--echo # +set @blob_len = 1024; +set @suffix_len = @blob_len - @prefix_len; + +create table t1_1024 (a1 blob(1024), a2 blob(1024)); +create table t2_1024 (b1 blob(1024), b2 blob(1024)); + +insert into t1_1024 values + (concat('1 - 00', repeat('x', @suffix_len)), concat('2 - 00', repeat('x', @suffix_len))); +insert into t1_1024 values + (concat('1 - 01', repeat('x', @suffix_len)), concat('2 - 01', repeat('x', @suffix_len))); +insert into t1_1024 values + (concat('1 - 02', repeat('x', @suffix_len)), concat('2 - 02', repeat('x', @suffix_len))); + +insert into t2_1024 values + (concat('1 - 01', repeat('x', @suffix_len)), concat('2 - 01', repeat('x', @suffix_len))); +insert into t2_1024 values + (concat('1 - 02', repeat('x', @suffix_len)), concat('2 - 02', repeat('x', @suffix_len))); +insert into t2_1024 values + (concat('1 - 03', repeat('x', @suffix_len)), concat('2 - 03', repeat('x', @suffix_len))); + +explain select left(a1,7), left(a2,7) from t1_1024 where (a1,3) in (select substring(b1,1,1024), count(*) from t2_1024 where b1 > '0'); +select left(a1,7), left(a2,7) from t1_1024 where (a1,3) in (select substring(b1,1,1024), count(*) from t2_1024 where b1 > '0'); + +drop table t1_1024, t2_1024; + +set optimizer_switch=@subselect_sj_mat_tmp; + diff --git a/mysql-test/t/subselect_sj_nonmerged.test b/mysql-test/t/subselect_sj_nonmerged.test new file mode 100644 index 00000000000..4f50b4cbc4d --- /dev/null +++ b/mysql-test/t/subselect_sj_nonmerged.test @@ -0,0 +1,115 @@ +# +# Tests for non-merged semi-joins +# +--disable_warnings +drop table if exists t0, t1, t2, t3, t4; +--enable_warnings + +set @save_optimizer_switch=@@optimizer_switch; +set optimizer_switch='semijoin=on,materialization=on'; +set optimizer_switch='mrr=on,mrr_sort_keys=on,index_condition_pushdown=on'; + +create table t0 (a int); +insert into t0 values (0),(1),(2),(3),(4),(5),(6),(7),(8),(9); + + +# Check the case of subquery having agggregates but not having grouping + +create table t1 as select * from t0; +--echo # The following should use full scan on <subquery2> and it must scan 1 row: +explain select * from t0 where a in (select max(a) from t1); +select * from t0 where a in (select max(a) from t1); + +# Ok, now check the trivial match/no-match/NULL on the left/NULL on the right cases +insert into t1 values (11); +select * from t0 where a in (select max(a) from t1); +delete from t1 where a=11; + +insert into t0 values (NULL); +select * from t0 where a in (select max(a) from t1); +delete from t0 where a is NULL; + +delete from t1; +select * from t0 where a in (select max(a) from t1); + +insert into t0 values (NULL); +select * from t0 where a in (select max(a) from t1); +delete from t0 where a is NULL; + +drop table t1; + +# +# Try with join subqueries +# + +create table t1 (a int, b int); +insert into t1 select a,a from t0; # 10 rows +create table t2 as select * from t1 where a<5; # 5 rows +create table t3 as select (A.a + 10*B.a) as a from t0 A, t0 B; # 100 rows +alter table t3 add primary key(a); + +--echo # The following should have do a full scan on <subquery2> and scan 5 rows +--echo # (despite that subquery's join output estimate is 50 rows) +explain select * from t3 where a in (select max(t2.a) from t1, t2 group by t2.b); + +--echo # Compare to this which really will have 50 record combinations: +explain select * from t3 where a in (select max(t2.a) from t1, t2 group by t2.b, t1.b); + +--echo # Outer joins also work: +explain select * from t3 +where a in (select max(t2.a) from t1 left join t2 on t1.a=t2.a group by t2.b, t1.b); + +# +# Check if joins on the outer side also work +# +create table t4 (a int, b int, filler char(20), unique key(a,b)); +insert into t4 select A.a + 10*B.a, A.a + 10*B.a, 'filler' from t0 A, t0 B; # 100 rows +explain select * from t0, t4 where + t4.b=t0.a and t4.a in (select max(t2.a) from t1, t2 group by t2.b); + +insert into t4 select 100 + (B.a *100 + A.a), 100 + (B.a*100 + A.a), 'filler' from t4 A, t0 B; +explain select * from t4 where + t4.a in (select max(t2.a) from t1, t2 group by t2.b) and + t4.b in (select max(t2.a) from t1, t2 group by t2.b); + +drop table t1,t2,t3,t4; + +drop table t0; + +--echo # +--echo # BUG#780359: Crash with get_fanout_with_deps in maria-5.3-mwl90 +--echo # +CREATE TABLE t1 (f1 int); +INSERT INTO t1 VALUES (2),(2); + +CREATE TABLE t2 (f3 int); +INSERT INTO t2 VALUES (2),(2); + +SELECT * +FROM t1 +WHERE ( f1 ) IN ( + SELECT t2.f3 + FROM t2 + WHERE t2.f3 = 97 + AND t2.f3 = 50 + GROUP BY 1 +); + +DROP TABLE t1, t2; + +--echo # +--echo # BUG#727183: WL#90 does not trigger with non-comma joins +--echo # +create table t0 (a int); +insert into t0 values (0),(1),(2),(3),(4),(5),(6),(7),(8),(9); + +create table t1(a int, key(a)); +insert into t1 select A.a + 10*B.a + 100*C.a from t0 A, t0 B, t0 C; + +--echo # The following must use non-merged SJ-Materialization: +explain select * from t1 X join t0 Y on X.a < Y.a where X.a in (select max(a) from t0); + +drop table t0, t1; + +set optimizer_switch=@save_optimizer_switch; + diff --git a/mysql-test/t/table_elim.test b/mysql-test/t/table_elim.test index 7ad69d5bf37..5576362b396 100644 --- a/mysql-test/t/table_elim.test +++ b/mysql-test/t/table_elim.test @@ -467,3 +467,35 @@ HAVING field4 != 6; drop table t0,t1,t2,t3,t4,t5,t6; + +--echo # +--echo # BUG#675118: Elimination of a table results in an invalid execution plan +--echo # +CREATE TABLE t1 (f1 int(11), PRIMARY KEY (f1)) ; + +CREATE TABLE t2 (f4 varchar(1024), KEY (f4)) ; +INSERT IGNORE INTO t2 VALUES ('xcddwntkbxyorzdv'), + ('cnxxcddwntkbxyor'),('r'),('r'), ('did'),('I'),('when'), + ('hczkfqjeggivdvac'),('e'),('okay'),('up'); + +CREATE TABLE t3 (f4 varchar(1024), f1 int(11), f2 int(11)) ; +INSERT IGNORE INTO t3 VALUES ('f','4','0'),('n','5','-996540416'); + +CREATE TABLE t4 (f1 int(11), f3 varchar(10)) ; +INSERT IGNORE INTO t4 VALUES ('8','n'),('9','nwzcerzsgx'),('10','c'); + +CREATE TABLE t5 (f5 int(11), KEY (f5)) ; + +EXPLAIN +SELECT t3.f2 +FROM t2 +LEFT JOIN t3 +LEFT JOIN t4 +LEFT JOIN t1 ON t4.f1 = t1.f1 +JOIN t5 ON t4.f3 ON t3.f1 = t5.f5 ON t2.f4 = t3.f4 +WHERE t3.f2 ; +--echo # ^^ The above must not produce a QEP of t3,t5,t2,t4 +--echo # as that violates the "no interleaving of outer join nests" rule. + +DROP TABLE t1,t2,t3,t4,t5; + diff --git a/mysql-test/t/timezone.test b/mysql-test/t/timezone.test index 157b18f57fa..a41e806a40e 100644 --- a/mysql-test/t/timezone.test +++ b/mysql-test/t/timezone.test @@ -60,4 +60,6 @@ select unix_timestamp('1970-01-01 01:00:00'), unix_timestamp('2038-01-19 04:14:07'), unix_timestamp('2038-01-19 04:14:08'); +select unix_timestamp('1969-12-31 23:59:59'), unix_timestamp('1970-01-01 00:00:00'), unix_timestamp('1970-01-01 00:59:59'); + # End of 4.1 tests diff --git a/mysql-test/t/type_blob.test b/mysql-test/t/type_blob.test index fa67afa48e8..66dd71d2305 100644 --- a/mysql-test/t/type_blob.test +++ b/mysql-test/t/type_blob.test @@ -534,6 +534,17 @@ DROP TABLE b15776; --error ER_PARSE_ERROR CREATE TABLE b15776 (a year(-2)); +## For timestamp, we silently rewrite widths to 14 or 19. +--error ER_TOO_BIG_PRECISION +CREATE TABLE b15776 (a timestamp(4294967294)); +--error ER_TOO_BIG_PRECISION +CREATE TABLE b15776 (a timestamp(4294967295)); +--error ER_TOO_BIG_DISPLAYWIDTH +CREATE TABLE b15776 (a timestamp(4294967296)); +--error ER_PARSE_ERROR +CREATE TABLE b15776 (a timestamp(-1)); +--error ER_PARSE_ERROR +CREATE TABLE b15776 (a timestamp(-2)); # We've already tested the case, but this should visually show that # widths that are too large to be interpreted cause DISPLAYWIDTH errors. @@ -631,3 +642,12 @@ DROP FUNCTION f1; DROP TABLE t1; --echo End of 5.1 tests + +# +# Problem when comparing blobs #778901 +# + +CREATE TABLE t1 ( f1 blob, f2 blob ); +INSERT INTO t1 VALUES ('',''); +SELECT f1,f2,"found row" FROM t1 WHERE f1 = f2 ; +DROP TABLE t1; diff --git a/mysql-test/t/type_date.test b/mysql-test/t/type_date.test index 9a21d8b370d..22b1eb97dad 100644 --- a/mysql-test/t/type_date.test +++ b/mysql-test/t/type_date.test @@ -280,6 +280,13 @@ DROP TABLE t1; --echo End of 5.1 tests +# +# lp:737496 Field_temporal::store_TIME_with_warning() in 5.1-micro +# +create table t1 (f1 date, key (f1)); +insert t1 values ('2010-10-10 15:foobar'); +drop table t1; + --echo # --echo # Bug #33629: last_day function can return null, but has 'not null' --echo # flag set for result @@ -303,5 +310,3 @@ set @a=(select min(makedate('111','1'))) ; select @a; --echo # - ---echo End of 6.0 tests diff --git a/mysql-test/t/type_datetime.test b/mysql-test/t/type_datetime.test index 81e032751ca..46c0d2d56d5 100644 --- a/mysql-test/t/type_datetime.test +++ b/mysql-test/t/type_datetime.test @@ -137,9 +137,9 @@ DROP TABLE t1; # Bug 19491 (CAST DATE AS DECIMAL returns incorrect result # SELECT CAST(CAST('2006-08-10' AS DATE) AS DECIMAL(20,6)); -SELECT CAST(CAST('2006-08-10 10:11:12' AS DATETIME) AS DECIMAL(20,6)); -SELECT CAST(CAST('2006-08-10 10:11:12' AS DATETIME) + INTERVAL 14 MICROSECOND AS DECIMAL(20,6)); -SELECT CAST(CAST('10:11:12.098700' AS TIME) AS DECIMAL(20,6)); +SELECT CAST(CAST('2006-08-10 10:11:12' AS DATETIME(6)) AS DECIMAL(20,6)); +SELECT CAST(CAST('2006-08-10 10:11:12' AS DATETIME(6)) + INTERVAL 14 MICROSECOND AS DECIMAL(20,6)); +SELECT CAST(CAST('10:11:12.098700' AS TIME(6)) AS DECIMAL(20,6)); # @@ -432,18 +432,18 @@ set @@sql_mode= @org_mode; # Bug #42146 - DATETIME fractional seconds parse error # # show we trucate microseconds from the right -- special case: leftmost is 0 -SELECT CAST(CAST('2006-08-10 10:11:12.0123450' AS DATETIME) AS DECIMAL(30,7)); +SELECT CAST(CAST('2006-08-10 10:11:12.0123450' AS DATETIME(6)) AS DECIMAL(30,7)); # show that we ignore leading zeroes for all other fields -SELECT CAST(CAST('00000002006-000008-0000010 000010:0000011:00000012.0123450' AS DATETIME) AS DECIMAL(30,7)); +SELECT CAST(CAST('00000002006-000008-0000010 000010:0000011:00000012.0123450' AS DATETIME(6)) AS DECIMAL(30,7)); # once more with feeling (but no warnings) -SELECT CAST(CAST('00000002006-000008-0000010 000010:0000011:00000012.012345' AS DATETIME) AS DECIMAL(30,7)); +SELECT CAST(CAST('00000002006-000008-0000010 000010:0000011:00000012.012345' AS DATETIME(6)) AS DECIMAL(30,7)); # # Bug #38435 - LONG Microseconds cause MySQL to fail a CAST to DATETIME or DATE # # show we truncate microseconds from the right -SELECT CAST(CAST('2008-07-29T10:42:51.1234567' AS DateTime) AS DECIMAL(30,7)); +SELECT CAST(CAST('2008-07-29T10:42:51.1234567' AS DateTime(6)) AS DECIMAL(30,7)); --echo # --echo # Bug#59173: Failure to handle DATE(TIME) values where Year, Month or diff --git a/mysql-test/t/type_datetime_hires.test b/mysql-test/t/type_datetime_hires.test new file mode 100644 index 00000000000..74f686d4157 --- /dev/null +++ b/mysql-test/t/type_datetime_hires.test @@ -0,0 +1,71 @@ + +--source include/have_partition.inc + +let type=datetime; +--source include/type_hrtime.inc + +# +# partitioning +# +eval CREATE TABLE t1 ( + taken $type(5) NOT NULL DEFAULT '0000-00-00 00:00:00', + id int(11) NOT NULL DEFAULT '0', + PRIMARY KEY (id,taken), + KEY taken (taken) +) +PARTITION BY RANGE (to_days(taken)) +( +PARTITION p01 VALUES LESS THAN (732920), +PARTITION p02 VALUES LESS THAN (732950), +PARTITION p03 VALUES LESS THAN MAXVALUE); + +INSERT INTO t1 VALUES +('2006-09-27 21:50:01.123456',0), +('2006-09-27 21:50:01.123456',1), +('2006-09-27 21:50:01.123456',2), +('2006-09-28 21:50:01.123456',3), +('2006-09-29 21:50:01.123456',4), +('2006-09-29 21:50:01.123456',5), +('2006-09-30 21:50:01.123456',6), +('2006-10-01 21:50:01.123456',7), +('2006-10-02 21:50:01.123456',8), +('2006-10-02 21:50:01.123456',9); + +SELECT id,to_days(taken) FROM t1 order by 2; + +eval CREATE TABLE t2 ( + taken $type(5) NOT NULL DEFAULT '0000-00-00 00:00:00', + id int(11) NOT NULL DEFAULT '0', + PRIMARY KEY (id,taken), + KEY taken (taken) +) +PARTITION BY RANGE (extract(microsecond from taken)) +( +PARTITION p01 VALUES LESS THAN (123000), +PARTITION p02 VALUES LESS THAN (500000), +PARTITION p03 VALUES LESS THAN MAXVALUE); + +INSERT INTO t2 VALUES +('2006-09-27 21:50:01',0), +('2006-09-27 21:50:01.1',1), +('2006-09-27 21:50:01.12',2), +('2006-09-28 21:50:01.123',3), +('2006-09-29 21:50:01.1234',4), +('2006-09-29 21:50:01.12345',5), +('2006-09-30 21:50:01.123456',6), +('2006-10-01 21:50:01.56',7), +('2006-10-02 21:50:01.567',8), +('2006-10-02 21:50:01.5678',9); + +select table_name,partition_name,partition_method,partition_expression,partition_description,table_rows from information_schema.partitions where table_name in ('t1', 't2'); + +drop table t1, t2; + +create table t1 (a datetime, b datetime(6)); +insert t1 values ('2010-01-02 03:04:05.678912', '2010-01-02 03:04:05.678912'); +update t1 set b=a; +select * from t1; +alter table t1 modify b datetime, modify a datetime(6); +select * from t1; +drop table t1; + diff --git a/mysql-test/t/type_time.test b/mysql-test/t/type_time.test index 84d6f58dea1..2ddb6f9dffc 100644 --- a/mysql-test/t/type_time.test +++ b/mysql-test/t/type_time.test @@ -101,6 +101,28 @@ DROP TABLE t1; --echo End of 5.1 tests +create table t1 (a time); +insert t1 values (-131415); +select * from t1; +drop table t1; + +# +# lp:731229 Different results depending on table access method with TIME column and CURDATE() +# +create table t1 (f1 time , f2 varchar(5), key(f1)); +insert into t1 values ('00:20:01','a'),('00:20:03','b'); +select * from t1 force key (f1) where f1 < curdate(); +select * from t1 ignore key (f1) where f1 < curdate(); +drop table t1; + +# +# comparison of time and datetime: +# +create table t1(f1 time); +insert into t1 values ('23:38:57'); +select f1, f1 = '2010-10-11 23:38:57' from t1; +drop table t1; + # # Bug#42664 - Sign ignored for TIME types when not comparing as longlong # @@ -117,4 +139,3 @@ SELECT CAST('-24:00:00' AS TIME) = (SELECT f1 FROM t1); SELECT '-24:00:00' = (SELECT f1 FROM t1); DROP TABLE t1; ---echo End of 6.0 tests diff --git a/mysql-test/t/type_time_hires.test b/mysql-test/t/type_time_hires.test new file mode 100644 index 00000000000..3785a23f1eb --- /dev/null +++ b/mysql-test/t/type_time_hires.test @@ -0,0 +1,12 @@ + +let type=time; +--source include/type_hrtime.inc + +create table t1 (a time(4) not null, key(a)); +insert into t1 values ('1:2:3.001'),('1:2:3'), ('-00:00:00.6'),('-00:00:00.7'),('-00:00:00.8'),('-00:00:00.9'),('-00:00:01.0'),('-00:00:01.1'),('-00:00:01.000000'),('-00:00:01.100001'),('-00:00:01.000002'),('-00:00:01.090000'); +select * from t1 order by a; +select * from t1 order by a desc; +select min(a - interval 1 hour), max(a - interval 1 hour) from t1 where a < 0; +drop table t1; + +select cast(1e-6 as time(6)); diff --git a/mysql-test/t/type_timestamp.test b/mysql-test/t/type_timestamp.test index cd4ba18455b..f2704ec1203 100644 --- a/mysql-test/t/type_timestamp.test +++ b/mysql-test/t/type_timestamp.test @@ -287,7 +287,7 @@ drop table t1; # mode regardless of whether a display width is given. # set sql_mode='maxdb'; -create table t1 (a timestamp, b timestamp); +create table t1 (a timestamp, b timestamp(5)); show create table t1; # restore default mode set sql_mode=''; diff --git a/mysql-test/t/type_timestamp_hires.test b/mysql-test/t/type_timestamp_hires.test new file mode 100644 index 00000000000..8e1f8586956 --- /dev/null +++ b/mysql-test/t/type_timestamp_hires.test @@ -0,0 +1,16 @@ + +let type=timestamp; +--source include/type_hrtime.inc + +set time_zone='+03:00'; +set timestamp=unix_timestamp('2011-01-01 01:01:01') + 0.123456; + +create table t1 (a timestamp(5)); +# +# CREATE ... DEFAULT NOW(X) +# + +insert t1 values (); +select * from t1; +drop table t1; + diff --git a/mysql-test/t/type_year.test b/mysql-test/t/type_year.test index 1a9e66478e1..de38306e88f 100644 --- a/mysql-test/t/type_year.test +++ b/mysql-test/t/type_year.test @@ -157,6 +157,7 @@ CREATE TABLE t1(c1 YEAR(4)); INSERT INTO t1 VALUES (1901),(2155),(0000); SELECT * FROM t1; SELECT COUNT(*) AS total_rows, MIN(c1) AS min_value, MAX(c1) FROM t1; +SELECT COUNT(*) AS total_rows, MIN(c1+0) AS min_value, MAX(c1+0) FROM t1; DROP TABLE t1; --echo # diff --git a/mysql-test/t/union.test b/mysql-test/t/union.test index c6599517e90..db7f8397c7b 100644 --- a/mysql-test/t/union.test +++ b/mysql-test/t/union.test @@ -1115,6 +1115,14 @@ SELECT * FROM t2 UNION SELECT * FROM t2 DROP TABLE t1,t2; +# +# lp:732124 union + limit returns wrong result +# +create table t1 (a int); +insert into t1 values (10),(10),(10),(2),(3),(4),(5),(6),(7),(8),(9),(1),(10); +--sorted_result +select a from t1 where false UNION select a from t1 limit 8; +drop table t1; --echo End of 5.1 tests diff --git a/mysql-test/t/upgrade.test b/mysql-test/t/upgrade.test index 400ce07b7fd..a8c875ef764 100644 --- a/mysql-test/t/upgrade.test +++ b/mysql-test/t/upgrade.test @@ -41,11 +41,9 @@ create table `txu#p#p1` (s1 int); insert into `txu#p#p1` values (1); --error 1146 select * from `txu@0023p@0023p1`; +--error ER_TABLE_EXISTS_ERROR create table `txu@0023p@0023p1` (s1 int); -insert into `txu@0023p@0023p1` values (2); -select * from `txu@0023p@0023p1`; select * from `txu#p#p1`; -drop table `txu@0023p@0023p1`; drop table `txu#p#p1`; --echo # diff --git a/mysql-test/t/variables-big.test b/mysql-test/t/variables-big.test index 15cbe27c759..60d83e92c0a 100644 --- a/mysql-test/t/variables-big.test +++ b/mysql-test/t/variables-big.test @@ -3,6 +3,10 @@ # --source include/big_test.inc +# The test would allocate and initialize 5GB of memory +# if compiled with debug. It can take a lot of time +# of for paging/swapping. +--source include/not_debug.inc # # Bug#27322 failure to allocate transaction_prealloc_size causes crash @@ -41,22 +45,32 @@ SET SESSION transaction_prealloc_size=1024*1024*1024*1; # Embedded server is hardcoded to show "Writing to net" as STATE. --replace_result "Writing to net" "NULL" --replace_column 1 <Id> 3 <Host> 6 <Time> +# Embedded server is hardcoded to show "Writing to net" as STATE. +--replace_result "Writing to net" "NULL" +--replace_regex /localhost[:0-9]*/localhost/ SHOW PROCESSLIST; SET SESSION transaction_prealloc_size=1024*1024*1024*2; --replace_result "Writing to net" "NULL" --replace_column 1 <Id> 3 <Host> 6 <Time> +--replace_result "Writing to net" "NULL" +--replace_regex /localhost[:0-9]*/localhost/ SHOW PROCESSLIST; SET SESSION transaction_prealloc_size=1024*1024*1024*3; --replace_result "Writing to net" "NULL" --replace_column 1 <Id> 3 <Host> 6 <Time> +--replace_result "Writing to net" "NULL" +--replace_regex /localhost[:0-9]*/localhost/ SHOW PROCESSLIST; SET SESSION transaction_prealloc_size=1024*1024*1024*4; --replace_result "Writing to net" "NULL" --replace_column 1 <Id> 3 <Host> 6 <Time> +--replace_result "Writing to net" "NULL" +--replace_regex /localhost[:0-9]*/localhost/ SHOW PROCESSLIST; SET SESSION transaction_prealloc_size=1024*1024*1024*5; --replace_result "Writing to net" "NULL" --replace_column 1 <Id> 3 <Host> 6 <Time> +--replace_result "Writing to net" "NULL" SHOW PROCESSLIST; --enable_warnings diff --git a/mysql-test/t/variables.test b/mysql-test/t/variables.test index 5d38be1dd54..3f7c4541a43 100644 --- a/mysql-test/t/variables.test +++ b/mysql-test/t/variables.test @@ -724,6 +724,7 @@ select * from information_schema.session_variables where variable_name like 'tmp # Bug #19606: make ssl settings available via SHOW VARIABLES and @@variables # # Don't actually output, since it depends on the system +set sort_buffer_size=1024*8; --replace_column 1 # 2 # 3 # 4 # 5 # select @@ssl_ca, @@ssl_capath, @@ssl_cert, @@ssl_cipher, @@ssl_key; --replace_column 2 # @@ -1273,31 +1274,51 @@ SET @@global.max_join_size=0; SET @@global.key_buffer_size=0; SET @@global.key_cache_block_size=0; +# Restore variables +SET @@global.max_binlog_cache_size=DEFAULT; +SET @@global.max_join_size=DEFAULT; +SET @@global.key_buffer_size=@kbs; +SET @@global.key_cache_block_size=@kcbs; + # # Bug#56976: added new start-up parameter # select @@max_long_data_size; --echo # ---echo # Bug#11766424 59527: DECIMAL_BIN_SIZE: ASSERTION `SCALE >= 0 && PRECISION > 0 && SCALE <= PRE +--echo # Bug#11766424 59527: +--echo # Assert in DECIMAL_BIN_SIZE: +--echo # `SCALE >= 0 && PRECISION > 0 && SCALE <= PRE +--echo # This test also exposed a bug with sql_buffer_result --echo # CREATE TABLE t1(f1 DECIMAL(1,1) UNSIGNED); INSERT INTO t1 VALUES (0.2),(0.1); -SELECT 1 FROM t1 GROUP BY @a:= (SELECT ROUND(f1) FROM t1 WHERE @a=f1); +set @a=NULL; +set sql_buffer_result=0; +SELECT 1 as 'one' FROM t1 GROUP BY @a:= ROUND(f1); + +explain SELECT 1 as 'one' FROM t1 GROUP BY @a:= (SELECT ROUND(f1) FROM t1 WHERE f1 = 0); +SELECT 1 as 'one' FROM t1 GROUP BY @a:= (SELECT ROUND(f1) FROM t1 WHERE f1 = 0); +SELECT 1 as 'one' FROM t1 GROUP BY @a:= (SELECT ROUND(f1) FROM t1 WHERE @a=f1); + +set sql_buffer_result=1; +explain SELECT 1 as 'one' FROM t1 GROUP BY @a:= (SELECT ROUND(f1) FROM t1 WHERE f1 = 0); +SELECT 1 as 'one' FROM t1 GROUP BY @a:= (SELECT ROUND(f1) FROM t1 WHERE f1 = 0); +SELECT 1 as 'one' FROM t1 GROUP BY @a:= (SELECT ROUND(f1) FROM t1 WHERE @a=f1); + DROP TABLE t1; +set sql_buffer_result=0; + +# +# Test of CREATE ... CAST +# + CREATE TABLE t1 AS SELECT @a:= CAST(1 AS UNSIGNED) AS a; SHOW CREATE TABLE t1; DROP TABLE t1; -# cleanup -SET @@global.max_binlog_cache_size=DEFAULT; -SET @@global.max_join_size=DEFAULT; -SET @@global.key_buffer_size=@kbs; -SET @@global.key_cache_block_size=@kcbs; - - --echo End of 5.1 tests ########################################################################### diff --git a/mysql-test/t/view.test b/mysql-test/t/view.test index 0fc64e26217..f464239b81e 100644 --- a/mysql-test/t/view.test +++ b/mysql-test/t/view.test @@ -2787,6 +2787,7 @@ DROP VIEW IF EXISTS v1; # # Bug#21261 Wrong access rights was required for an insert to a view # + CREATE DATABASE bug21261DB; USE bug21261DB; connect (root,localhost,root,,bug21261DB); @@ -3991,10 +3992,339 @@ SELECT * FROM v1; DROP VIEW v1; DROP TABLE t1; +--echo # +--echo # LP BUG#777809 (a retrograded condition for view ON) +--echo # + +CREATE TABLE t1 ( f1 int NOT NULL , f6 int NOT NULL ) ; +INSERT IGNORE INTO t1 VALUES (20, 2); + +CREATE TABLE t2 ( f3 int NOT NULL ) ; +INSERT IGNORE INTO t2 VALUES (7); + +CREATE OR REPLACE VIEW v2 AS SELECT * FROM t2; + +PREPARE prep_stmt FROM 'SELECT t1.f6 FROM t1 RIGHT JOIN v2 ON v2.f3 WHERE t1.f1 != 0'; + +EXECUTE prep_stmt; +EXECUTE prep_stmt; + +drop view v2; +drop table t1,t2; + --echo # ----------------------------------------------------------------- --echo # -- End of 5.1 tests. --echo # ----------------------------------------------------------------- +--echo # +--echo # Bug #59696 Optimizer does not use equalities for conditions over view +--echo # + +CREATE TABLE t1 (a int NOT NULL); +INSERT INTO t1 VALUES + (9), (2), (8), (1), (3), (4), (2), (5), + (9), (2), (8), (1), (3), (4), (2), (5); + +CREATE TABLE t2 (pk int PRIMARY KEY, c int NOT NULL); +INSERT INTO t2 VALUES + (9,90), (16, 160), (11,110), (1,10), (18,180), (2,20), + (14,140), (15, 150), (12,120), (3,30), (17,170), (19,190); + +EXPLAIN EXTENDED +SELECT t1.a,t2.c FROM t1,t2 WHERE t2.pk = t1.a AND t2.pk > 8; +FLUSH STATUS; +SELECT t1.a,t2.c FROM t1,t2 WHERE t2.pk = t1.a AND t2.pk > 8; +SHOW STATUS LIKE 'Handler_read_%'; + +CREATE VIEW v AS SELECT * FROM t2; +EXPLAIN EXTENDED +SELECT t1.a,v.c FROM t1,v WHERE v.pk = t1.a AND v.pk > 8; +FLUSH STATUS; +SELECT t1.a,v.c FROM t1,v WHERE v.pk = t1.a AND v.pk > 8; +SHOW STATUS LIKE 'Handler_read_%'; +DROP VIEW v; + +DROP TABLE t1, t2; + +--echo # +--echo # Bug#702403: crash with multiple equalities and a view +--echo # + +CREATE TABLE t1 (a int); +INSERT INTO t1 VALUES (10); + +CREATE TABLE t2 (pk int PRIMARY KEY, b int, INDEX idx (b)); +INSERT INTO t2 VALUES (1,2), (3,4); +CREATE TABLE t3 (pk int PRIMARY KEY, b int, INDEX idx (b)); +INSERT INTO t3 VALUES (1,2), (3,4); + +CREATE VIEW v1 AS SELECT * FROM t1; + +EXPLAIN +SELECT * FROM v1, t2, t3 + WHERE t3.pk = v1.a AND t2.b = 1 AND t2.b = t3.pk AND v1.a BETWEEN 2 AND 5; + +SELECT * FROM v1, t2, t3 + WHERE t3.pk = v1.a AND t2.b = 1 AND t2.b = t3.pk AND v1.a BETWEEN 2 AND 5; + +DROP VIEW v1; +DROP TABLE t1, t2, t3; + +--echo # +--echo # Bug#717577: substitution for best field in a query over a view and +--echo # with OR in the WHERE condition +--echo # + +create table t1 (a int, b int); +insert into t1 values (2,4), (1,3); +create table t2 (c int); +insert into t2 values (6), (4), (1), (3), (8), (3), (4), (2); + +select * from t1,t2 where t2.c=t1.a and t2.c < 3 or t2.c=t1.b and t2.c >=4; +explain extended +select * from t1,t2 where t2.c=t1.a and t2.c < 3 or t2.c=t1.b and t2.c >=4; + +create view v1 as select * from t2; +select * from t1,v1 where v1.c=t1.a and v1.c < 3 or v1.c=t1.b and v1.c >=4; +explain extended +select * from t1,v1 where v1.c=t1.a and v1.c < 3 or v1.c=t1.b and v1.c >=4; + +create view v2 as select * from v1; +select * from t1,v2 where v2.c=t1.a and v2.c < 3 or v2.c=t1.b and v2.c >=4; +explain extended +select * from t1,v2 where v2.c=t1.a and v2.c < 3 or v2.c=t1.b and v2.c >=4; + +create view v3 as select * from t1; +select * from v3,v2 where v2.c=v3.a and v2.c < 3 or v2.c=v3.b and v2.c >=4; +explain extended +select * from v3,v2 where v2.c=v3.a and v2.c < 3 or v2.c=v3.b and v2.c >=4; + +drop view v1,v2,v3; +drop table t1,t2; + +--echo # +--echo # Bug#724942: substitution of the constant into a view field +--echo # + +CREATE TABLE t1 (a int); +INSERT INTO t1 VALUES (2), (9), (9), (6), (5), (4), (7); + +CREATE VIEW v1 AS SELECT * FROM t1; + +SELECT * FROM v1 WHERE a > -1 OR a > 6 AND a = 3; +EXPLAIN EXTENDED +SELECT * FROM v1 WHERE a > -1 OR a > 6 AND a = 3; + +SELECT * FROM v1 WHERE a > -1 OR a AND a = 0; +EXPLAIN EXTENDED +SELECT * FROM v1 WHERE a > -1 OR a AND a = 0; + +CREATE VIEW v2 AS SELECT * FROM v1; + +SELECT * FROM v2 WHERE a > -1 OR a AND a = 0; +EXPLAIN EXTENDED +SELECT * FROM v2 WHERE a > -1 OR a AND a = 0; + +DROP VIEW v1,v2; +DROP TABLE t1; + +CREATE TABLE t1 (a varchar(10), KEY (a)) ; +INSERT INTO t1 VALUES + ('DD'), ('ZZ'), ('ZZ'), ('KK'), ('FF'), ('HH'),('MM'); + +CREATE VIEW v1 AS SELECT * FROM t1; + +SELECT * FROM v1 WHERE a > 'JJ' OR a <> 0 AND a = 'VV'; +EXPLAIN EXTENDED +SELECT * FROM v1 WHERE a > 'JJ' OR a <> 0 AND a = 'VV'; + +SELECT * FROM v1 WHERE a > 'JJ' OR a AND a = 'VV'; +EXPLAIN EXTENDED +SELECT * FROM v1 WHERE a > 'JJ' OR a AND a = 'VV'; + +DROP VIEW v1; +DROP TABLE t1; + +--echo # +--echo # Bug#777745: crash with equality propagation +--echo # over view fields +--echo # + +CREATE TABLE t1 (a int NOT NULL ) ; +INSERT INTO t1 VALUES (2), (1); + +CREATE TABLE t2 (a int NOT NULL , b int NOT NULL) ; +INSERT INTO t2 VALUES (2,20),(2,30); + +CREATE VIEW v2 AS SELECT * FROM t2; + +EXPLAIN +SELECT * FROM t1,v2 + WHERE v2.a = t1.a AND v2.a = 2 AND v2.a IS NULL AND t1.a != 0; +SELECT * FROM t1,v2 + WHERE v2.a = t1.a AND v2.a = 2 AND v2.a IS NULL AND t1.a != 0; + +EXPLAIN +SELECT * FROM t1,v2 + WHERE v2.a = t1.a AND v2.a = 2 AND v2.a+1 > 2 AND t1.a != 0; +SELECT * FROM t1,v2 + WHERE v2.a = t1.a AND v2.a = 2 AND v2.a+1 > 2 AND t1.a != 0; + +DROP VIEW v2; +DROP TABLE t1,t2; + +--echo # +--echo # Bug#794038: crash with INSERT/UPDATE/DELETE +--echo # over a non-updatable view +--echo # + +CREATE TABLE t1 (a int); +CREATE ALGORITHM = TEMPTABLE VIEW v1 AS SELECT * FROM t1; +CREATE ALGORITHM = MERGE VIEW v2 AS SELECT * FROM v1; +CREATE ALGORITHM = TEMPTABLE VIEW v3 AS SELECT * FROM v2; + +-- error ER_NON_INSERTABLE_TABLE +INSERT INTO v3 VALUES (1); +-- error ER_NON_UPDATABLE_TABLE +UPDATE v3 SET a=0; +-- error ER_NON_UPDATABLE_TABLE +DELETE FROM v3; + +DROP VIEW v1,v2,v3; +DROP TABLE t1; + +--echo # +--echo # Bug#798621: crash with a view string field equal +--echo # to a constant +--echo # + +CREATE TABLE t1 (a varchar(32), b int) ; +INSERT INTO t1 VALUES ('j', NULL), ('c', 8), ('c', 1); +CREATE VIEW v1 AS SELECT * FROM t1; + +CREATE TABLE t2 (a varchar(32)) ; +INSERT INTO t2 VALUES ('j'), ('c'); + +SELECT * FROM v1 LEFT JOIN t2 ON t2.a = v1.a + WHERE v1.b = 1 OR v1.a = 'a' AND LENGTH(v1.a) >= v1.b; +EXPLAIN EXTENDED +SELECT * FROM v1 LEFT JOIN t2 ON t2.a = v1.a + WHERE v1.b = 1 OR v1.a = 'a' AND LENGTH(v1.a) >= v1.b; + +DROP VIEW v1; +DROP TABLE t1,t2; + +--echo # Bug#798625: duplicate of the previous one, but without crash + +CREATE TABLE t1 (f1 int NOT NULL, f2 int, f3 int, f4 varchar(32), f5 int) ; +INSERT INTO t1 VALUES (20,5,2,'r', 0); + +CREATE VIEW v1 AS SELECT * FROM t1; + +SELECT v1.f4 FROM v1 + WHERE f1<>0 OR f2<>0 AND f4='v' AND (f2<>0 OR f3<>0 AND f5<>0 OR f4 LIKE '%b%'); +EXPLAIN EXTENDED +SELECT v1.f4 FROM v1 + WHERE f1<>0 OR f2<>0 AND f4='v' AND (f2<>0 OR f3<>0 AND f5<>0 OR f4 LIKE '%b%'); + +DROP VIEW v1; +DROP TABLE t1; + +--echo # +--echo # Bug#798576: abort on a GROUP BY query over a view with left join +--echo # that can be converted to inner join +--echo # + +CREATE TABLE t1 (a int NOT NULL , b int NOT NULL) ; +INSERT INTO t1 VALUES (214,0), (6,6), (6,0), (7,0); + +CREATE TABLE t2 (b int) ; +INSERT INTO t2 VALUES (88), (78), (6); + +CREATE ALGORITHM=MERGE VIEW v1 AS + SELECT t1.a, t2.b FROM (t2 LEFT JOIN t1 ON t2.b > t1.a) WHERE t1.b <= 0; + +SELECT * FROM v1; +SELECT a, MIN(b) FROM v1 GROUP BY a; + +DROP VIEW v1; +DROP TABLE t1,t2; + +--echo # +--echo # LP bug #793386: unexpected 'Duplicate column name ''' error +--echo # at the second execution of a PS using a view +--echo # + +CREATE TABLE t1 (f1 int, f2 int, f3 int, f4 int); + +CREATE VIEW v1 AS + SELECT t.f1, t.f2, s.f3, s.f4 FROM t1 t, t1 s + WHERE t.f4 >= s.f2 AND s.f3 < 0; + +PREPARE stmt1 FROM + "SELECT s.f1 AS f1, s.f2 AS f2, s.f3 AS f3, t.f4 AS f4 + FROM v1 AS t LEFT JOIN v1 AS s ON t.f4=s.f4 WHERE t.f2 <> 1225"; +EXECUTE stmt1; +EXECUTE stmt1; + +DEALLOCATE PREPARE stmt1; + +DROP VIEW v1; +DROP TABLE t1; + +--echo # +--echo # LP BUG#806071 (2 views with ORDER BY) +--echo # + +CREATE TABLE t1 (f1 int); +INSERT INTO t1 VALUES (1),(1); + +CREATE ALGORITHM=TEMPTABLE VIEW v1 AS SELECT f1 FROM t1; +CREATE ALGORITHM=MERGE VIEW v2 AS SELECT f1 FROM v1 ORDER BY f1; + +SELECT * FROM v2 AS a1, v2 AS a2; +EXPLAIN EXTENDED SELECT * FROM v2 AS a1, v2 AS a2; + +DROP VIEW v1, v2; +DROP TABLE t1; + +--echo # +--echo # LP bug #823189: dependent subquery with RIGHT JOIN +--echo # referencing view in WHERE +--echo # + +CREATE TABLE t1 (a varchar(32)); +INSERT INTO t1 VALUES ('y'), ('w'); + +CREATE TABLE t2 (a int); +INSERT INTO t2 VALUES (10); + +CREATE TABLE t3 (a varchar(32), b int); + +CREATE TABLE t4 (a varchar(32)); +INSERT INTO t4 VALUES ('y'), ('w'); + +CREATE VIEW v1 AS SELECT * FROM t1; + +EXPLAIN EXTENDED +SELECT * FROM t1, t2 + WHERE t2.a NOT IN (SELECT t3.b FROM t3 RIGHT JOIN t4 ON (t4.a = t3.a) + WHERE t4.a >= t1.a); +SELECT * FROM t1, t2 + WHERE t2.a NOT IN (SELECT t3.b FROM t3 RIGHT JOIN t4 ON (t4.a = t3.a) + WHERE t4.a >= t1.a); + +EXPLAIN EXTENDED +SELECT * FROM v1, t2 + WHERE t2.a NOT IN (SELECT t3.b FROM t3 RIGHT JOIN t4 ON (t4.a = t3.a) + WHERE t4.a >= v1.a); +SELECT * FROM v1, t2 + WHERE t2.a NOT IN (SELECT t3.b FROM t3 RIGHT JOIN t4 ON (t4.a = t3.a) + WHERE t4.a >= v1.a); + +DROP VIEW v1; +DROP TABLE t1,t2,t3,t4; + # # Bug#9801 (Views: imperfect error message) # diff --git a/mysql-test/t/xa_binlog.test b/mysql-test/t/xa_binlog.test new file mode 100644 index 00000000000..48f1dc6dfaa --- /dev/null +++ b/mysql-test/t/xa_binlog.test @@ -0,0 +1,32 @@ +--source include/have_innodb.inc +--source include/have_log_bin.inc + +CREATE TABLE t1 (a INT PRIMARY KEY) ENGINE=InnoDB; + +# Fix binlog format (otherwise SHOW BINLOG EVENTS will fluctuate). +SET binlog_format= mixed; + +RESET MASTER; + +XA START 'xatest'; +INSERT INTO t1 VALUES (1); +XA END 'xatest'; +XA PREPARE 'xatest'; +XA COMMIT 'xatest'; + +XA START 'xatest'; +INSERT INTO t1 VALUES (2); +XA END 'xatest'; +XA COMMIT 'xatest' ONE PHASE; + +BEGIN; +INSERT INTO t1 VALUES (3); +COMMIT; + +SELECT * FROM t1 ORDER BY a; + +--replace_column 2 # 5 # +--replace_regex /xid=[0-9]+/xid=XX/ +SHOW BINLOG EVENTS LIMIT 1,9; + +DROP TABLE t1; diff --git a/mysql-test/t/xtradb_mrr.test b/mysql-test/t/xtradb_mrr.test index 62b46152cf0..0653f9859c3 100644 --- a/mysql-test/t/xtradb_mrr.test +++ b/mysql-test/t/xtradb_mrr.test @@ -7,6 +7,9 @@ drop table if exists t1,t2,t3,t4; set @save_storage_engine= @@storage_engine; set storage_engine=InnoDB; +set @innodb_mrr_tmp=@@optimizer_switch; +set optimizer_switch='mrr=on,mrr_sort_keys=on,index_condition_pushdown=on'; + --source include/mrr_tests.inc set storage_engine= @save_storage_engine; @@ -123,3 +126,336 @@ SELECT id FROM t1 WHERE parent_id IS NOT NULL ORDER BY id DESC LIMIT 1; explain SELECT * FROM t1 FORCE INDEX (PRIMARY) WHERE parent_id IS NOT NULL ORDER BY id DESC LIMIT 1; SELECT * FROM t1 WHERE parent_id IS NOT NULL ORDER BY id DESC LIMIT 1; drop table t1; + + +-- echo # +-- echo # BUG#628785: multi_range_read.cc:430: int DsMrr_impl::dsmrr_init(): Assertion `do_sort_keys || do_rowid_fetch' failed +-- echo # +set @save_join_cache_level= @@join_cache_level; +set @save_optimizer_switch= @@optimizer_switch; +SET SESSION join_cache_level=9; +SET SESSION optimizer_switch='mrr_sort_keys=off'; + +CREATE TABLE `t1` ( + `pk` int(11) NOT NULL AUTO_INCREMENT, + `col_int_nokey` int(11) DEFAULT NULL, + `col_int_key` int(11) DEFAULT NULL, + `col_varchar_key` varchar(1) DEFAULT NULL, + `col_varchar_nokey` varchar(1) DEFAULT NULL, + PRIMARY KEY (`pk`), + KEY `col_varchar_key` (`col_varchar_key`,`col_int_key`) +) ENGINE=InnoDB AUTO_INCREMENT=101 DEFAULT CHARSET=latin1; +INSERT INTO `t1` VALUES (1,6,NULL,'r','r'); +INSERT INTO `t1` VALUES (2,8,0,'c','c'); +INSERT INTO `t1` VALUES (97,7,0,'z','z'); +INSERT INTO `t1` VALUES (98,1,1,'j','j'); +INSERT INTO `t1` VALUES (99,7,8,'c','c'); +INSERT INTO `t1` VALUES (100,2,5,'f','f'); +SELECT table1 .`col_varchar_key` +FROM t1 table1 STRAIGHT_JOIN ( t1 table3 JOIN t1 table4 ON table4 .`pk` = table3 .`col_int_nokey` ) ON table4 .`col_varchar_nokey` ; +DROP TABLE t1; +set join_cache_level=@save_join_cache_level; +set optimizer_switch=@save_optimizer_switch; + +--echo # +--echo # BUG#623300: Query with join_cache_level = 6 returns extra rows in maria-5.3-dsmrr-cpk +--echo # +CREATE TABLE t1 ( + pk int(11) NOT NULL AUTO_INCREMENT, + col_int_nokey int(11) DEFAULT NULL, + PRIMARY KEY (pk) +) ENGINE=InnoDB; + +INSERT INTO t1 VALUES (10,7); +INSERT INTO t1 VALUES (11,1); +INSERT INTO t1 VALUES (12,5); +INSERT INTO t1 VALUES (13,3); +INSERT INTO t1 VALUES (14,6); +INSERT INTO t1 VALUES (15,92); +INSERT INTO t1 VALUES (16,7); +INSERT INTO t1 VALUES (17,NULL); +INSERT INTO t1 VALUES (18,3); +INSERT INTO t1 VALUES (19,5); +INSERT INTO t1 VALUES (20,1); +INSERT INTO t1 VALUES (21,2); +INSERT INTO t1 VALUES (22,NULL); +INSERT INTO t1 VALUES (23,1); +INSERT INTO t1 VALUES (24,0); +INSERT INTO t1 VALUES (25,210); +INSERT INTO t1 VALUES (26,8); +INSERT INTO t1 VALUES (27,7); +INSERT INTO t1 VALUES (28,5); +INSERT INTO t1 VALUES (29,NULL); + +CREATE TABLE t2 ( + pk int(11) NOT NULL AUTO_INCREMENT, + col_int_nokey int(11) DEFAULT NULL, + PRIMARY KEY (pk) +) ENGINE=InnoDB; +INSERT INTO t2 VALUES (1,NULL); +INSERT INTO t2 VALUES (2,7); +INSERT INTO t2 VALUES (3,9); +INSERT INTO t2 VALUES (4,7); +INSERT INTO t2 VALUES (5,4); +INSERT INTO t2 VALUES (6,2); +INSERT INTO t2 VALUES (7,6); +INSERT INTO t2 VALUES (8,8); +INSERT INTO t2 VALUES (9,NULL); +INSERT INTO t2 VALUES (10,5); +INSERT INTO t2 VALUES (11,NULL); +INSERT INTO t2 VALUES (12,6); +INSERT INTO t2 VALUES (13,188); +INSERT INTO t2 VALUES (14,2); +INSERT INTO t2 VALUES (15,1); +INSERT INTO t2 VALUES (16,1); +INSERT INTO t2 VALUES (17,0); +INSERT INTO t2 VALUES (18,9); +INSERT INTO t2 VALUES (19,NULL); +INSERT INTO t2 VALUES (20,4); + +set @my_save_join_cache_level= @@join_cache_level; +SET join_cache_level = 0; + +--sorted_result +SELECT table2.col_int_nokey +FROM t1 table1 JOIN t2 table2 ON table2.pk = table1.col_int_nokey +WHERE table1.pk ; + +SET join_cache_level = 6; + +--sorted_result +SELECT table2.col_int_nokey +FROM t1 table1 JOIN t2 table2 ON table2.pk = table1.col_int_nokey +WHERE table1.pk ; + +set join_cache_level= @my_save_join_cache_level; +drop table t1, t2; + +--echo # +--echo # BUG#623315: Query returns less rows when run with join_cache_level=6 on maria-5.3-dsmrr-cpk +--echo # +CREATE TABLE t1 ( + pk int(11) NOT NULL AUTO_INCREMENT, + col_int_nokey int(11) DEFAULT NULL, + col_int_key int(11) DEFAULT NULL, + col_varchar_key varchar(1) DEFAULT NULL, + PRIMARY KEY (pk), + KEY col_int_key (col_int_key), + KEY col_varchar_key (col_varchar_key,col_int_key) +) ENGINE=InnoDB; +INSERT INTO t1 VALUES (10,7,8,'v'); +INSERT INTO t1 VALUES (11,1,9,'r'); +INSERT INTO t1 VALUES (12,5,9,'a'); +INSERT INTO t1 VALUES (13,3,186,'m'); +INSERT INTO t1 VALUES (14,6,NULL,'y'); +INSERT INTO t1 VALUES (15,92,2,'j'); +INSERT INTO t1 VALUES (16,7,3,'d'); +INSERT INTO t1 VALUES (17,NULL,0,'z'); +INSERT INTO t1 VALUES (18,3,133,'e'); +INSERT INTO t1 VALUES (19,5,1,'h'); +INSERT INTO t1 VALUES (20,1,8,'b'); +INSERT INTO t1 VALUES (21,2,5,'s'); +INSERT INTO t1 VALUES (22,NULL,5,'e'); +INSERT INTO t1 VALUES (23,1,8,'j'); +INSERT INTO t1 VALUES (24,0,6,'e'); +INSERT INTO t1 VALUES (25,210,51,'f'); +INSERT INTO t1 VALUES (26,8,4,'v'); +INSERT INTO t1 VALUES (27,7,7,'x'); +INSERT INTO t1 VALUES (28,5,6,'m'); +INSERT INTO t1 VALUES (29,NULL,4,'c'); + +set @my_save_join_cache_level= @@join_cache_level; +SET join_cache_level=6; +select count(*) from +(SELECT table2.pk FROM + t1 LEFT JOIN t1 table2 JOIN t1 table3 ON table3.col_varchar_key = table2.col_varchar_key + ON table3.col_int_nokey) foo; + +SET join_cache_level=0; +select count(*) from +(SELECT table2.pk FROM + t1 LEFT JOIN t1 table2 JOIN t1 table3 ON table3.col_varchar_key = table2.col_varchar_key + ON table3.col_int_nokey) foo; + +set join_cache_level= @my_save_join_cache_level; +drop table t1; + + +--echo # +--echo # BUG#671340: Diverging results in with mrr_sort_keys=ON|OFF and join_cache_level=5 +--echo # +CREATE TABLE t1 ( + pk int(11) NOT NULL AUTO_INCREMENT, + col_int_key int(11) NOT NULL, + col_varchar_key varchar(1) NOT NULL, + col_varchar_nokey varchar(1) NOT NULL, + PRIMARY KEY (pk), + KEY col_int_key (col_int_key), + KEY col_varchar_key (col_varchar_key,col_int_key) +) ENGINE=InnoDB; +INSERT INTO t1 VALUES + (10,8,'v','v'), + (11,8,'f','f'), + (12,5,'v','v'), + (13,8,'s','s'), + (14,8,'a','a'), + (15,6,'p','p'), + (16,7,'z','z'), + (17,2,'a','a'), + (18,5,'h','h'), + (19,7,'h','h'), + (20,2,'v','v'), + (21,9,'v','v'), + (22,142,'b','b'), + (23,3,'y','y'), + (24,0,'v','v'), + (25,3,'m','m'), + (26,5,'z','z'), + (27,9,'n','n'), + (28,1,'d','d'), + (29,107,'a','a'); + +CREATE TABLE t2 ( + pk int(11) NOT NULL AUTO_INCREMENT, + col_int_key int(11) NOT NULL, + col_varchar_key varchar(1) NOT NULL, + col_varchar_nokey varchar(1) NOT NULL, + PRIMARY KEY (pk), + KEY col_int_key (col_int_key), + KEY col_varchar_key (col_varchar_key,col_int_key) +) ENGINE=InnoDB; +INSERT INTO t2 VALUES + (1,9,'x','x'), + (2,5,'g','g'), + (3,1,'o','o'), + (4,0,'g','g'), + (5,1,'v','v'), + (6,190,'m','m'), + (7,6,'x','x'), + (8,3,'c','c'), + (9,4,'z','z'), + (10,3,'i','i'), + (11,186,'x','x'), + (12,1,'g','g'), + (13,8,'q','q'), + (14,226,'m','m'), + (15,133,'p','p'), + (16,6,'e','e'), + (17,3,'t','t'), + (18,8,'j','j'), + (19,5,'h','h'), + (20,7,'w','w'); + +SELECT count(*), sum(table1.col_int_key*table2.pk) +FROM + t2 AS table1, t1 AS table2, t2 AS table3 +WHERE + table3.col_varchar_nokey = table2.col_varchar_key AND table3.pk > table2.col_varchar_nokey ; + +set @my_save_join_cache_level= @@join_cache_level; +set @my_save_join_buffer_size= @@join_buffer_size; +set join_cache_level=6; +set join_buffer_size=1536; + +SELECT count(*), sum(table1.col_int_key*table2.pk) +FROM + t2 AS table1, t1 AS table2, t2 AS table3 +WHERE + table3.col_varchar_nokey = table2.col_varchar_key AND table3.pk > table2.col_varchar_nokey ; + +drop table t1,t2; +set join_cache_level=@my_save_join_cache_level; +set join_buffer_size=@my_save_join_buffer_size; + + +--echo # +--echo # BUG#665669: Result differences on query re-execution +--echo # +create table t1 (pk int primary key, b int, c int default 0, index idx(b)) engine=innodb; +insert into t1(pk,b) values (3, 30), (2, 20), (9, 90), (7, 70), (4, 40), (5, 50), (10, 100), (12, 120); +set @bug665669_tmp=@@optimizer_switch; +set optimizer_switch='mrr=off'; +explain select * from t1 where b > 1000; +--echo # The following two must produce indentical results: +select * from t1 where pk < 2 or pk between 3 and 4; +select * from t1 where pk < 2 or pk between 3 and 4; +drop table t1; +set optimizer_switch = @bug665669_tmp; +--echo # +--echo # Bug#43360 - Server crash with a simple multi-table update +--echo # +CREATE TABLE t1 ( + a CHAR(2) NOT NULL PRIMARY KEY, + b VARCHAR(20) NOT NULL, + KEY (b) +) ENGINE=InnoDB; + +CREATE TABLE t2 ( + a CHAR(2) NOT NULL PRIMARY KEY, + b VARCHAR(20) NOT NULL, + KEY (b) +) ENGINE=InnoDB; + +INSERT INTO t1 VALUES +('AB','MySQLAB'), +('JA','Sun Microsystems'), +('MS','Microsoft'), +('IB','IBM- Inc.'), +('GO','Google Inc.'); + +INSERT INTO t2 VALUES +('AB','Sweden'), +('JA','USA'), +('MS','United States of America'), +('IB','North America'), +('GO','South America'); + +UPDATE t1,t2 SET t1.b=UPPER(t1.b) WHERE t1.b LIKE 'United%'; + +SELECT * FROM t1; + +SELECT * FROM t2; + +DROP TABLE t1,t2; + +--echo # +--echo # Testcase backport: Bug#43249 +--echo # +CREATE TABLE t1(c1 TIME NOT NULL, c2 TIME NULL, c3 DATE, PRIMARY KEY(c1), UNIQUE INDEX(c2)) engine=innodb; +INSERT INTO t1 VALUES('8:29:45',NULL,'2009-02-01'); +# first time, good results: +SELECT * FROM t1 WHERE c2 <=> NULL ORDER BY c2 LIMIT 2; +# second time, bad results: +SELECT * FROM t1 WHERE c2 <=> NULL ORDER BY c2 LIMIT 2; +drop table `t1`; + +--echo # +--echo # BUG#707925: Wrong result with join_cache_level=6 optimizer_use_mrr = +--echo # force (incremental, BKA join) +--echo # +set @_save_join_cache_level= @@join_cache_level; +set join_cache_level = 6; +CREATE TABLE t1 ( + f1 int(11), f2 int(11), f3 varchar(1), f4 varchar(1), + PRIMARY KEY (f1), + KEY (f3), + KEY (f2) +) ENGINE=InnoDB; +INSERT INTO t1 VALUES ('11','8','f','f'),('12','5','v','v'),('13','8','s','s'), +('14','8','a','a'),('15','6','p','p'),('16','7','z','z'),('17','2','a','a'), +('18','5','h','h'),('19','7','h','h'),('20','2','v','v'),('21','9','v','v'), +('22','142','b','b'),('23','3','y','y'),('24','0','v','v'),('25','3','m','m'), +('26','5','z','z'),('27','9','n','n'),('28','1','d','d'),('29','107','a','a'); + +select count(*) from ( + SELECT alias1.f2 + FROM + t1 AS alias1 JOIN ( + t1 AS alias2 FORCE KEY (f3) JOIN + t1 AS alias3 FORCE KEY (f2) ON alias3.f2 = alias2.f2 AND alias3.f4 = alias2.f3 + ) ON alias3.f1 <= alias2.f1 +) X; + +set join_cache_level=@_save_join_cache_level; +set optimizer_switch= @innodb_mrr_tmp; +drop table t1; |