[Commits] ffb4823: MyRocks on windows: make bulk_load_unsorted pass.
by psergey@askmonty.org 10 May '18
by psergey@askmonty.org 10 May '18
10 May '18
revision-id: ffb48234df38630aeb3c34d72aba1473348c7076
parent(s): b0269816a52d7fb3d8893afbafc60b27aca30815
committer: Sergei Petrunia
branch nick: 10.2-r11
timestamp: 2018-05-10 20:16:15 +0300
message:
MyRocks on windows: make bulk_load_unsorted pass.
It produced warnings due to perl code printing \r\n into the text
file which is then used by LOAD DATA INFILE.
---
storage/rocksdb/mysql-test/rocksdb/include/bulk_load_unsorted.inc | 1 +
1 file changed, 1 insertion(+)
diff --git a/storage/rocksdb/mysql-test/rocksdb/include/bulk_load_unsorted.inc b/storage/rocksdb/mysql-test/rocksdb/include/bulk_load_unsorted.inc
index 4a3158e..151ec0c 100644
--- a/storage/rocksdb/mysql-test/rocksdb/include/bulk_load_unsorted.inc
+++ b/storage/rocksdb/mysql-test/rocksdb/include/bulk_load_unsorted.inc
@@ -83,6 +83,7 @@ eval CREATE TABLE t3(a INT, b INT, PRIMARY KEY(a) COMMENT "$pk_cf")
perl;
my $fn = $ENV{'ROCKSDB_INFILE'};
open(my $fh, '>', $fn) || die "perl open($fn): $!";
+binmode $fh;
my $max = 5000000;
my $sign = 1;
for (my $ii = 0; $ii < $max; $ii++)
1
0
[Commits] b026981: MyRocks: post-merge fixes for Windows: take into account FN_LIBCHAR2
by psergey@askmonty.org 10 May '18
by psergey@askmonty.org 10 May '18
10 May '18
revision-id: b0269816a52d7fb3d8893afbafc60b27aca30815
parent(s): 4d51009a772fdfffc6cc7ae87422a3b0b19fa06a
committer: Sergei Petrunia
branch nick: 10.2-r11
timestamp: 2018-05-10 19:05:13 +0300
message:
MyRocks: post-merge fixes for Windows: take into account FN_LIBCHAR2
Table name may be passed either as "./db/table" or as ".\\db\\table".
---
storage/rocksdb/ha_rocksdb.cc | 7 ++++++-
1 file changed, 6 insertions(+), 1 deletion(-)
diff --git a/storage/rocksdb/ha_rocksdb.cc b/storage/rocksdb/ha_rocksdb.cc
index 57efc71..46d9638 100644
--- a/storage/rocksdb/ha_rocksdb.cc
+++ b/storage/rocksdb/ha_rocksdb.cc
@@ -7141,13 +7141,18 @@ int rdb_normalize_tablename(const std::string &tablename,
std::string *const strbuf) {
DBUG_ASSERT(strbuf != nullptr);
- if (tablename.size() < 2 || tablename[0] != '.' || tablename[1] != FN_LIBCHAR) {
+ if (tablename.size() < 2 || tablename[0] != '.' ||
+ (tablename[1] != FN_LIBCHAR && tablename[1] != FN_LIBCHAR2)) {
DBUG_ASSERT(0); // We were not passed table name?
return HA_ERR_ROCKSDB_INVALID_TABLE;
}
size_t pos = tablename.find_first_of(FN_LIBCHAR, 2);
if (pos == std::string::npos) {
+ pos = tablename.find_first_of(FN_LIBCHAR2, 2);
+ }
+
+ if (pos == std::string::npos) {
DBUG_ASSERT(0); // We were not passed table name?
return HA_ERR_ROCKSDB_INVALID_TABLE;
}
1
0
[Commits] 5680d3f: Merge branch 'bb-10.3-mdev12387' into 10.4
by galina.shalygina@mariadb.com 10 May '18
by galina.shalygina@mariadb.com 10 May '18
10 May '18
revision-id: 5680d3fd621ad1cc360c82a90a7a92e1ac563c34 (mariadb-10.3.5-155-g5680d3f)
parent(s): eaaf004cc194d1f1fc422ebbd986ae69fc854d1c 79a7641b40c7b12dda4a6e30e7688b2f796e6a98
author: Galina Shalygina
committer: Galina Shalygina
timestamp: 2018-05-10 17:17:53 +0200
message:
Merge branch 'bb-10.3-mdev12387' into 10.4
mysql-test/main/derived.result | 2 +-
mysql-test/main/in_subq_cond_pushdown.result | 3801 ++++++++++++++++++++
mysql-test/main/in_subq_cond_pushdown.test | 759 ++++
mysql-test/main/mysqld--help.result | 5 +-
mysql-test/main/subselect_mat.result | 2 +-
mysql-test/main/subselect_sj_mat.result | 2 +-
.../suite/sys_vars/r/optimizer_switch_basic.result | 36 +-
.../sys_vars/r/sysvars_server_embedded.result | 8 +-
.../sys_vars/r/sysvars_server_notembedded.result | 8 +-
sql/item.cc | 250 +-
sql/item.h | 77 +-
sql/item_cmpfunc.h | 8 +-
sql/item_func.h | 5 +
sql/item_row.h | 5 +
sql/item_subselect.h | 13 +-
sql/opt_subselect.cc | 946 ++++-
sql/opt_subselect.h | 11 +-
sql/sql_derived.cc | 211 +-
sql/sql_lex.cc | 156 +-
sql/sql_lex.h | 29 +-
sql/sql_priv.h | 4 +-
sql/sql_select.cc | 56 +-
sql/sql_select.h | 18 +-
sql/sys_vars.cc | 1 +
sql/table.cc | 194 -
sql/table.h | 2 -
.../mysql-test/tokudb/r/ext_key_1_innodb.result | 2 +-
.../mysql-test/tokudb/r/ext_key_1_tokudb.result | 2 +-
.../mysql-test/tokudb/r/ext_key_2_innodb.result | 2 +-
.../mysql-test/tokudb/r/ext_key_2_tokudb.result | 2 +-
30 files changed, 6113 insertions(+), 504 deletions(-)
diff --cc mysql-test/main/derived.result
index ebbc08a,0000000..a1dd1a7
mode 100644,000000..100644
--- a/mysql-test/main/derived.result
+++ b/mysql-test/main/derived.result
@@@ -1,1164 -1,0 +1,1164 @@@
+drop table if exists t1,t2,t3;
+set @save_derived_optimizer_switch=@@optimizer_switch;
+set optimizer_switch='derived_merge=off,derived_with_keys=off';
+select * from (select 2 from DUAL) b;
+2
+2
+SELECT 1 as a FROM (SELECT 1 UNION SELECT a) b;
+ERROR 42S22: Unknown column 'a' in 'field list'
+SELECT 1 as a FROM (SELECT a UNION SELECT 1) b;
+ERROR 42S22: Unknown column 'a' in 'field list'
+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');
+select t1.a,t3.y from t1,(select a as y from t2 where b='c') as t3 where t1.a = t3.y;
+a y
+3 3
+3 3
+select t1.a,t3.a from t1,(select * from t2 where b='c') as t3 where t1.a = t3.a;
+a a
+3 3
+3 3
+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 t1.a,t4.y from t1,(select t2.a as y from t2,(select t3.b from t3 where t3.a>3) as t5 where t2.b=t5.b) as t4 where t1.a = t4.y;
+a y
+3 3
+3 3
+SELECT a FROM (SELECT 1 FROM (SELECT 1) a HAVING a=1) b;
+ERROR 42S22: Unknown column 'a' in 'having clause'
+SELECT a,b as a FROM (SELECT '1' as a,'2' as b) b HAVING a=1;
+ERROR 23000: Column 'a' in having clause is ambiguous
+SELECT a,2 as a FROM (SELECT '1' as a) b HAVING a=2;
+a a
+1 2
+SELECT a,2 as a FROM (SELECT '1' as a) b HAVING a=1;
+a a
+SELECT 1 FROM (SELECT 1) a WHERE a=2;
+ERROR 42S22: Unknown column 'a' in 'where clause'
+SELECT (SELECT 1) as a FROM (SELECT 1 FROM t1 HAVING a=1) as a;
+ERROR 42S22: Unknown column 'a' in 'having clause'
+select * from t1 as x1, (select * from t1) as x2;
+a b a b
+1 a 1 a
+2 b 1 a
+3 c 1 a
+3 c 1 a
+1 a 2 b
+2 b 2 b
+3 c 2 b
+3 c 2 b
+1 a 3 c
+2 b 3 c
+3 c 3 c
+3 c 3 c
+1 a 3 c
+2 b 3 c
+3 c 3 c
+3 c 3 c
+explain select * from t1 as x1, (select * from t1) as x2;
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY x1 ALL NULL NULL NULL NULL 4
+1 PRIMARY <derived2> ALL NULL NULL NULL NULL 4 Using join buffer (flat, BNL join)
+2 DERIVED t1 ALL NULL NULL NULL NULL 4
+drop table if exists t2,t3;
+select * from (select 1) as a;
+1
+1
+select a from (select 1 as a) as b;
+a
+1
+select 1 from (select 1) as a;
+1
+1
+select * from (select * from t1 union select * from t1) a;
+a b
+1 a
+2 b
+3 c
+select * from (select * from t1 union all select * from t1) a;
+a b
+1 a
+2 b
+3 c
+3 c
+1 a
+2 b
+3 c
+3 c
+select * from (select * from t1 union all select * from t1 limit 2) a;
+a b
+1 a
+2 b
+explain select * from (select * from t1 union select * from t1) a;
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY <derived2> ALL NULL NULL NULL NULL 8
+2 DERIVED t1 ALL NULL NULL NULL NULL 4
+3 UNION t1 ALL NULL NULL NULL NULL 4
+NULL UNION RESULT <union2,3> ALL NULL NULL NULL NULL NULL
+explain select * from (select * from t1 union all select * from t1) a;
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY <derived2> ALL NULL NULL NULL NULL 8
+2 DERIVED t1 ALL NULL NULL NULL NULL 4
+3 UNION t1 ALL NULL NULL NULL NULL 4
+CREATE TABLE t2 (a int not null);
+insert into t2 values(1);
+select * from (select * from t1 where t1.a=(select a from t2 where t2.a=t1.a)) a;
+a b
+1 a
+select * from (select * from t1 where t1.a=(select t2.a from t2 where t2.a=t1.a) union select t1.a, t1.b from t1) a;
+a b
+1 a
+2 b
+3 c
+explain select * from (select t1.*, t2.a as t2a from t1,t2 where t1.a=t2.a) t1;
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY <derived2> ALL NULL NULL NULL NULL 4
+2 DERIVED t2 system NULL NULL NULL NULL 1
+2 DERIVED t1 ALL NULL NULL NULL NULL 4 Using where
+drop table t1, t2;
+create table t1(a int not null, t char(8), index(a));
+SELECT * FROM (SELECT * FROM t1) as b ORDER BY a ASC LIMIT 0,20;
+a t
+1 1
+2 2
+3 3
+4 4
+5 5
+6 6
+7 7
+8 8
+9 9
+10 10
+11 11
+12 12
+13 13
+14 14
+15 15
+16 16
+17 17
+18 18
+19 19
+20 20
+explain select count(*) from t1 as tt1, (select * from t1) as tt2;
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY tt1 index NULL a 4 NULL 10000 Using index
+1 PRIMARY <derived2> ALL NULL NULL NULL NULL 10000 Using join buffer (flat, BNL join)
+2 DERIVED t1 ALL NULL NULL NULL NULL 10000
+drop table t1;
+SELECT * FROM (SELECT (SELECT * FROM (SELECT 1 as a) as a )) as b;
+(SELECT * FROM (SELECT 1 as a) as a )
+1
+select * from (select 1 as a) b left join (select 2 as a) c using(a);
+a
+1
+SELECT * FROM (SELECT 1 UNION SELECT a) b;
+ERROR 42S22: Unknown column 'a' in 'field list'
+SELECT 1 as a FROM (SELECT a UNION SELECT 1) b;
+ERROR 42S22: Unknown column 'a' in 'field list'
+SELECT 1 as a FROM (SELECT 1 UNION SELECT a) b;
+ERROR 42S22: Unknown column 'a' in 'field list'
+select 1 from (select 2) a order by 0;
+ERROR 42S22: Unknown column '0' in 'order clause'
+create table t1 (id int);
+insert into t1 values (1),(2),(3);
+describe select * from (select * from t1 group by id) bar;
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY <derived2> ALL NULL NULL NULL NULL 3
+2 DERIVED t1 ALL NULL NULL NULL NULL 3 Using temporary; Using filesort
+drop table t1;
+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;
+pla_id mat_id
+100 1
+101 1
+102 1
+103 2
+104 2
+105 3
+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;
+pla_id test
+100 1
+101 1
+102 1
+103 2
+104 2
+105 3
+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;
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY m2 ALL NULL NULL NULL NULL 9
+1 PRIMARY <derived2> ALL NULL NULL NULL NULL 9 Using where; Using join buffer (flat, BNL join)
+2 DERIVED mp ALL NULL NULL NULL NULL 9 Using temporary; Using filesort
+2 DERIVED m1 eq_ref PRIMARY PRIMARY 3 test.mp.mat_id 1
+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;
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY m2 ALL NULL NULL NULL NULL 9
+1 PRIMARY <derived2> ALL NULL NULL NULL NULL 9 Using where; Using join buffer (flat, BNL join)
+2 DERIVED mp ALL NULL NULL NULL NULL 9 Using temporary; Using filesort
+2 DERIVED m1 eq_ref PRIMARY PRIMARY 3 test.mp.mat_id 1
+drop table t1,t2;
+SELECT a.x FROM (SELECT 1 AS x) AS a HAVING a.x = 1;
+x
+1
+create user mysqltest_1;
+create table t1 select 1 as a;
+connect con1,localhost,mysqltest_1,,*NO-ONE*,$MASTER_MYPORT,$MASTER_MYSOCK;
+connection con1;
+set optimizer_switch='derived_merge=off,derived_with_keys=off';
+select 2 as a from (select * from t1) b;
+ERROR 3D000: No database selected
+use test;
+select 2 as a from (select * from t1) b;
+a
+2
+drop table t1;
+select mail_id, if(folder.f_description!='', folder.f_description, folder.f_name) as folder_name, date, address_id, phrase, address, subject from folder, (select mail.mail_id as mail_id, date_format(mail.h_date, '%b %e, %Y %h:%i') as date, mail.folder_id, sender.address_id as address_id, sender.phrase as phrase, sender.address as address, mail.h_subject as subject from mail left join mxa as mxa_sender on mail.mail_id=mxa_sender.mail_id and mxa_sender.type='from' left join address as sender on mxa_sender.address_id=sender.address_id mxa as mxa_recipient, address as recipient, where 1 and mail.mail_id=mxa_recipient.mail_id and mxa_recipient.address_id=recipient.address_id and mxa_recipient.type='to' and match(sender.phrase, sender.address, sender.comment) against ('jeremy' in boolean mode) and match(recipient.phrase, recipient.address, recipient.comment) against ('monty' in boolean mode) order by mail.h_date desc limit 0, 25 ) as query where quer
y.folder
_id=folder.folder_id;
+ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near 'mxa as mxa_recipient, address as recipient, where 1 and mail.mail_id=mxa_r' at line 1
+create table t1 (a int);
+insert into t1 values (1),(2),(3);
+update (select * from t1) as t1 set a = 5;
+ERROR HY000: The target table t1 of the UPDATE is not updatable
+delete from (select * from t1);
+ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near '(select * from t1)' at line 1
+insert into (select * from t1) values (5);
+ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near '(select * from t1) values (5)' at line 1
+drop table t1;
+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;
+count(*)
+2
+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;
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY <derived2> ALL NULL NULL NULL NULL 2
+1 PRIMARY t1 eq_ref PRIMARY PRIMARY 4 THEMAX.E2 1 Using where
+2 DERIVED A ALL NULL NULL NULL NULL 2 Using where
+3 DEPENDENT SUBQUERY B ALL NULL NULL NULL NULL 2 Using where
+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;
+a a
+1 1
+2 1
+1 2
+2 2
+explain select * from ( select * from t1 union select * from t1) a,(select * from t1 union select * from t1) b;
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY <derived2> ALL NULL NULL NULL NULL 4
+1 PRIMARY <derived4> ALL NULL NULL NULL NULL 4 Using join buffer (flat, BNL join)
+4 DERIVED t1 ALL NULL NULL NULL NULL 2
+5 UNION t1 ALL NULL NULL NULL NULL 2
+NULL UNION RESULT <union4,5> ALL NULL NULL NULL NULL NULL
+2 DERIVED t1 ALL NULL NULL NULL NULL 2
+3 UNION t1 ALL NULL NULL NULL NULL 2
+NULL UNION RESULT <union2,3> ALL NULL NULL NULL NULL NULL
+drop table t1;
+CREATE TABLE `t1` (
+`N` int(11) unsigned NOT NULL default '0',
+`M` tinyint(1) default '0'
+) ENGINE=MyISAM DEFAULT CHARSET=latin1;
+INSERT INTO `t1` (N, M) VALUES (1, 0),(1, 0),(1, 0),(2, 0),(2, 0),(3, 0);
+UPDATE `t1` AS P1 INNER JOIN (SELECT N FROM `t1` GROUP BY N HAVING Count(M) > 1) AS P2 ON P1.N = P2.N SET P1.M = 2;
+select * from t1;
+N M
+1 2
+1 2
+1 2
+2 2
+2 2
+3 0
+UPDATE `t1` AS P1 INNER JOIN (SELECT N FROM `t1` GROUP BY N HAVING Count(M) > 1) AS P2 ON P1.N = P2.N SET P1.M = 2, P2.N = 2;
+ERROR HY000: The target table P2 of the UPDATE is not updatable
+UPDATE `t1` AS P1 INNER JOIN (SELECT aaaa FROM `t1` GROUP BY N HAVING Count(M) > 1) AS P2 ON P1.N = P2.N SET P1.M = 2;
+ERROR 42S22: Unknown column 'aaaa' in 'field list'
+delete P1.* from `t1` AS P1 INNER JOIN (SELECT N FROM `t1` GROUP BY N HAVING Count(M) > 1) AS P2 ON P1.N = P2.N;
+select * from t1;
+N M
+3 0
+delete P1.*,p2.* from `t1` AS P1 INNER JOIN (SELECT N FROM `t1` GROUP BY N HAVING Count(M) > 1) AS p2 ON P1.N = p2.N;
+ERROR HY000: The target table p2 of the DELETE is not updatable
+delete P1.* from `t1` AS P1 INNER JOIN (SELECT aaa FROM `t1` GROUP BY N HAVING Count(M) > 1) AS P2 ON P1.N = P2.N;
+ERROR 42S22: Unknown column 'aaa' in 'field list'
+drop table t1;
+CREATE TABLE t1 (
+OBJECTID int(11) NOT NULL default '0',
+SORTORDER int(11) NOT NULL auto_increment,
+KEY t1_SortIndex (SORTORDER),
+KEY t1_IdIndex (OBJECTID)
+) ENGINE=MyISAM DEFAULT CHARSET=latin1;
+CREATE TABLE t2 (
+ID int(11) default NULL,
+PARID int(11) default NULL,
+UNIQUE KEY t2_ID_IDX (ID),
+KEY t2_PARID_IDX (PARID)
+) engine=MyISAM DEFAULT CHARSET=latin1;
+INSERT INTO t2 VALUES (1000,0),(1001,0),(1002,0),(1003,0),(1008,1),(1009,1),(1010,1),(1011,1),(1016,2);
+CREATE TABLE t3 (
+ID int(11) default NULL,
+DATA decimal(10,2) default NULL,
+UNIQUE KEY t3_ID_IDX (ID)
+) engine=MyISAM DEFAULT CHARSET=latin1;
+INSERT INTO t3 VALUES (1000,0.00),(1001,0.25),(1002,0.50),(1003,0.75),(1008,1.00),(1009,1.25),(1010,1.50),(1011,1.75);
+select 497, TMP.ID, NULL from (select 497 as ID, MAX(t3.DATA) as DATA from t1 join t2 on (t1.ObjectID = t2.ID) join t3 on (t1.ObjectID = t3.ID) group by t2.ParID order by DATA DESC) as TMP;
+497 ID NULL
+drop table t1, t2, t3;
+CREATE TABLE t1 (name char(1) default NULL, val int(5) default NULL);
+INSERT INTO t1 VALUES ('a',1), ('a',2), ('a',2), ('a',2), ('a',3), ('a',6), ('a',7), ('a',11), ('a',11), ('a',12), ('a',13), ('a',13), ('a',20), ('b',2), ('b',3), ('b',4), ('b',5);
+SELECT s.name, AVG(s.val) AS median FROM (SELECT x.name, x.val FROM t1 x, t1 y WHERE x.name=y.name GROUP BY x.name, x.val HAVING SUM(y.val <= x.val) >= COUNT(*)/2 AND SUM(y.val >= x.val) >= COUNT(*)/2) AS s GROUP BY s.name;
+name median
+a 7.0000
+b 3.5000
+explain SELECT s.name, AVG(s.val) AS median FROM (SELECT x.name, x.val FROM t1 x, t1 y WHERE x.name=y.name GROUP BY x.name, x.val HAVING SUM(y.val <= x.val) >= COUNT(*)/2 AND SUM(y.val >= x.val) >= COUNT(*)/2) AS s GROUP BY s.name;
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY <derived2> ALL NULL NULL NULL NULL 289 Using temporary; Using filesort
+2 DERIVED x ALL NULL NULL NULL NULL 17 Using temporary; Using filesort
+2 DERIVED y ALL NULL NULL NULL NULL 17 Using where; Using join buffer (flat, BNL join)
+drop table t1;
+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;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t2 index PRIMARY PRIMARY 4 NULL 2 Using where; Using index
+explain select a from (select a from t2 where a>1) tt;
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY <derived2> ALL NULL NULL NULL NULL 2
+2 DERIVED t2 index PRIMARY PRIMARY 4 NULL 2 Using where; Using index
+drop table t2;
+CREATE TABLE `t1` ( `itemid` int(11) NOT NULL default '0', `grpid` varchar(15) NOT NULL default '', `vendor` int(11) NOT NULL default '0', `date_` date NOT NULL default '0000-00-00', `price` decimal(12,2) NOT NULL default '0.00', PRIMARY KEY (`itemid`,`grpid`,`vendor`,`date_`), KEY `itemid` (`itemid`,`vendor`), KEY `itemid_2` (`itemid`,`date_`));
+insert into t1 values (128, 'rozn', 2, curdate(), 10),
+(128, 'rozn', 1, curdate(), 10);
+SELECT MIN(price) min, MAX(price) max, AVG(price) avg FROM (SELECT SUBSTRING( MAX(concat(date_,";",price)), 12) price FROM t1 WHERE itemid=128 AND grpid='rozn' GROUP BY itemid, grpid, vendor) lastprices;
+min max avg
+10.00 10.00 10
+DROP TABLE t1;
+create table t1 (a integer, b integer);
+insert into t1 values (1,4), (2,2),(2,2), (4,1),(4,1),(4,1),(4,1);
+select distinct sum(b) from t1 group by a;
+sum(b)
+4
+select distinct sum(b) from (select a,b from t1) y group by a;
+sum(b)
+4
+drop table t1;
+CREATE TABLE t1 (a char(10), b char(10));
+INSERT INTO t1 VALUES ('root','localhost'), ('root','%');
+SELECT * FROM (SELECT (SELECT a.a FROM t1 AS a WHERE a.a = b.a) FROM t1 AS b) AS c;
+ERROR 21000: Subquery returns more than 1 row
+DROP TABLE t1;
+create table t1(a int);
+create table t2(a int);
+create table t3(a int);
+insert into t1 values(1),(1);
+insert into t2 values(2),(2);
+insert into t3 values(3),(3);
+select * from t1 union distinct select * from t2 union all select * from t3;
+a
+1
+2
+3
+3
+select * from (select * from t1 union distinct select * from t2 union all select * from t3) X;
+a
+1
+2
+3
+3
+drop table t1, t2, t3;
+create table t1 (a int);
+create table t2 (a int);
+select * from (select * from t1,t2) foo;
+ERROR 42S21: Duplicate column name 'a'
+drop table t1,t2;
+create table t1 (ID int unsigned not null auto_increment,
+DATA varchar(5) not null, primary key (ID));
+create table t2 (ID int unsigned not null auto_increment,
+DATA varchar(5) not null, FID int unsigned not null,
+primary key (ID));
+select A.* from (t1 inner join (select * from t2) as A on t1.ID = A.FID);
+ID DATA FID
+select t2.* from ((select * from t1) as A inner join t2 on A.ID = t2.FID);
+ID DATA FID
+select t2.* from (select * from t1) as A inner join t2 on A.ID = t2.FID;
+ID DATA FID
+drop table t1, t2;
+connection con1;
+disconnect con1;
+connection default;
+drop user mysqltest_1;
+# End of 4.1 tests
+SELECT 0 FROM
+(SELECT 0) t01, (SELECT 0) t02, (SELECT 0) t03, (SELECT 0) t04, (SELECT 0) t05,
+(SELECT 0) t06, (SELECT 0) t07, (SELECT 0) t08, (SELECT 0) t09, (SELECT 0) t10,
+(SELECT 0) t11, (SELECT 0) t12, (SELECT 0) t13, (SELECT 0) t14, (SELECT 0) t15,
+(SELECT 0) t16, (SELECT 0) t17, (SELECT 0) t18, (SELECT 0) t19, (SELECT 0) t20,
+(SELECT 0) t21, (SELECT 0) t22, (SELECT 0) t23, (SELECT 0) t24, (SELECT 0) t25,
+(SELECT 0) t26, (SELECT 0) t27, (SELECT 0) t28, (SELECT 0) t29, (SELECT 0) t30,
+(SELECT 0) t31, (SELECT 0) t32, (SELECT 0) t33, (SELECT 0) t34, (SELECT 0) t35,
+(SELECT 0) t36, (SELECT 0) t37, (SELECT 0) t38, (SELECT 0) t39, (SELECT 0) t40,
+(SELECT 0) t41, (SELECT 0) t42, (SELECT 0) t43, (SELECT 0) t44, (SELECT 0) t45,
+(SELECT 0) t46, (SELECT 0) t47, (SELECT 0) t48, (SELECT 0) t49, (SELECT 0) t50,
+(SELECT 0) t51, (SELECT 0) t52, (SELECT 0) t53, (SELECT 0) t54, (SELECT 0) t55,
+(SELECT 0) t56, (SELECT 0) t57, (SELECT 0) t58, (SELECT 0) t59, (SELECT 0) t60,
+(SELECT 0) t61;
+0
+0
+#
+# A nested materialized derived table is used before being populated.
+# (addon for bug#19077)
+#
+CREATE TABLE t1 (i INT, j BIGINT);
+INSERT INTO t1 VALUES (1, 2), (2, 2), (3, 2);
+SELECT * FROM (SELECT MIN(i) FROM t1
+WHERE j = SUBSTRING('12', (SELECT * FROM (SELECT MIN(j) FROM t1) t2))) t3;
+MIN(i)
+1
+DROP TABLE t1;
+# End of 5.0 tests
+#
+# MDEV-5005: Subquery in Procedure somehow affecting temporary table
+#
+create temporary table if not exists t1 (id int not null);
+select A.* from ( select tt.* from t1 tt ) A;
+id
+prepare stmt from "select A.* from ( select tt.* from t1 tt ) A ";
+execute stmt;
+id
+deallocate prepare stmt;
+drop temporary table t1;
+CREATE PROCEDURE p ()
+BEGIN
+select A.* from ( select tt.* from t1 tt ) A ;
+END |
+create temporary table if not exists t1 (id int not null);
+CALL p();
+id
+CALL p();
+id
+drop procedure p;
+drop temporary table t1;
+#
+# MDEV-5143: update of a joined table with a nested subquery with
+# a syntax error crashes mysqld with signal 11
+#
+create table t1 (id int(11) not null auto_increment, val varchar(100) null,primary key (id));
+create table t2 (id int(11) not null auto_increment, val varchar(100) null,primary key (id));
+insert into t1 (val) values('a');
+insert into t2 (val) values('1');
+update
+(
+select
+val
+from
+(
+select
+v.val
+from
+t2 wrong_table_alias
+) t4
+) t3
+inner join t1 on
+t1.id=t3.val
+set
+t1.val=t3.val
+;
+ERROR 42S22: Unknown column 'v.val' in 'field list'
+drop table t1, t2;
+#
+# MDEV-5353: server crash on subselect if WHERE applied to some
+# result field
+#
+SELECT * FROM
+( SELECT 100 a, subsel.b FROM ( SELECT 200 b ) subsel ) tmp
+WHERE tmp.b;
+a b
+100 200
+SELECT * FROM
+( SELECT 100 a, subsel.b FROM ( SELECT 200 b ) subsel ) tmp
+WHERE tmp.a;
+a b
+100 200
+#
+# MDEV-5356: Server crashes in Item_equal::contains on 2nd
+# execution of a PS
+#
+CREATE TABLE t1 (a INT, b INT);
+INSERT INTO t1 VALUES (1,2),(3,4);
+CREATE TABLE t2 (c INT);
+INSERT INTO t2 VALUES (5),(6);
+CREATE TABLE t3 (d INT);
+INSERT INTO t3 VALUES (7),(8);
+CREATE PROCEDURE pr()
+UPDATE t3,
+(SELECT c FROM
+(SELECT 1 FROM t1 WHERE a=72 AND NOT b) sq,
+t2
+) sq2
+SET d=sq2.c;
+CALL pr();
+CALL pr();
+CALL pr();
+drop procedure pr;
+drop table t1,t2,t3;
+# End of 5.3 tests
+#
+# Bug#58730 Assertion failed: table->key_read == 0 in close_thread_table,
+# temptable views
+#
+CREATE TABLE t1 (a INT);
+CREATE TABLE t2 (b INT, KEY (b));
+INSERT INTO t1 VALUES (1),(1);
+INSERT INTO t2 VALUES (1),(1);
+CREATE algorithm=temptable VIEW v1 AS
+SELECT 1 FROM t1 LEFT JOIN t1 t3 ON 1 > (SELECT 1 FROM t1);
+CREATE algorithm=temptable VIEW v2 AS SELECT 1 FROM t2;
+EXPLAIN SELECT 1 FROM t1 JOIN v1 ON 1 > (SELECT 1 FROM v2);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t1 ALL NULL NULL NULL NULL 2
+1 PRIMARY <derived3> ALL NULL NULL NULL NULL 4 Using join buffer (flat, BNL join)
+3 DERIVED t1 ALL NULL NULL NULL NULL 2
+3 DERIVED t3 ALL NULL NULL NULL NULL 2 Using where; Using join buffer (flat, BNL join)
+4 SUBQUERY t1 ALL NULL NULL NULL NULL 2
+2 SUBQUERY <derived5> ALL NULL NULL NULL NULL 2
+5 DERIVED t2 index NULL b 5 NULL 2 Using index
+SELECT 1 FROM t1 JOIN v1 ON 1 > (SELECT 1 FROM v2);
+ERROR 21000: Subquery returns more than 1 row
+DROP TABLE t1, t2;
+DROP VIEW v1, v2;
+create table t1 (n bigint(20) unsigned, d1 datetime, d2 datetime, key (d1));
+insert t1 values (2085,'2012-01-01 00:00:00','2013-01-01 00:00:00');
+insert t1 values (2084,'2012-02-01 00:00:00','2013-01-01 00:00:00');
+insert t1 values (2088,'2012-03-01 00:00:00','2013-01-01 00:00:00');
+select * from (
+select n, d1, d2, @result := 0 as result
+from t1
+where d1 < '2012-12-12 12:12:12' and n in (2085, 2084) order by d2 asc
+) as calculated_result;
+n d1 d2 result
+2085 2012-01-01 00:00:00 2013-01-01 00:00:00 0
+2084 2012-02-01 00:00:00 2013-01-01 00:00:00 0
+drop table t1;
+set @save_derived_optimizer_switch_bug=@@optimizer_switch;
+SET optimizer_switch = 'derived_merge=on,derived_with_keys=on,in_to_exists=on';
+CREATE TABLE t1 (a INT) ENGINE=MyISAM;
+INSERT INTO t1 VALUES (8);
+CREATE TABLE t2 (b INT) ENGINE=MyISAM;
+INSERT INTO t2 VALUES (1),(7);
+EXPLAIN SELECT * FROM (SELECT * FROM t1) AS table1,
+(SELECT DISTINCT * FROM t2) AS table2 WHERE b = a AND a <> ANY (SELECT 9);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t1 system NULL NULL NULL NULL 1
+1 PRIMARY <derived3> ref key0 key0 5 const 0
+3 DERIVED t2 ALL NULL NULL NULL NULL 2 Using where; Using temporary
+Warnings:
+Note 1249 Select 4 was reduced during optimization
+DROP TABLE t1, t2;
+set optimizer_switch=@save_derived_optimizer_switch_bug;
+#
+# MDEV-6163: Error while executing an update query that has the
+# same table in a sub-query
+#
+set @save_derived_optimizer_switch_bug=@@optimizer_switch;
+SET optimizer_switch = 'derived_merge=on';
+create table t1 (balance float, accountId varchar(64), primary key (accountId));
+insert into t1 (accountId,balance) values
+('dealer-1',199354.0),('dealer-2',0),('dealer-3',0),('dealer-5',0),('FINANCE',-200000),('OPERATOR',0);
+update t1 set balance=(select sum(balance) from (SELECT balance FROM t1 where accountId like 'dealer%') AS copied) where accountId = 'OPERATOR';
+set optimizer_switch=@save_derived_optimizer_switch_bug;
+drop table t1;
+#
+# MDEV-6219:Server crashes in Bitmap<64u>::merge
+# (this=0x180, map2=...) on 2nd execution of PS with INSERT .. SELECT,
+# derived_merge
+#
+CREATE TABLE t1 (a VARCHAR(8)) ENGINE=MyISAM;
+INSERT INTO t1 VALUES ('foo'),('bar');
+create procedure p1()
+INSERT INTO t1 SELECT * FROM (
+SELECT * FROM t1
+) AS sq
+WHERE sq.a IN ( SELECT 'baz' FROM DUAL );
+call p1();
+call p1();
+drop procedure p1;
+PREPARE stmt FROM "
+ INSERT INTO t1 SELECT * FROM (
+ SELECT * FROM t1
+ ) AS sq
+ WHERE sq.a IN ( SELECT 'baz' FROM DUAL )
+";
+EXECUTE stmt;
+EXECUTE stmt;
+deallocate prepare stmt;
+drop table t1;
+#
+# MDEV-6892: WHERE does not apply
+#
+create table t1 (id int);
+create table t2 (id int);
+insert into t1 values(1),(2),(3);
+insert into t2 values(4),(5),(6);
+select x.id, message from (select id from t1) x left join
+(select id, 1 as message from t2) y on x.id=y.id
+where coalesce(message,0) <> 0;
+id message
+drop table t1,t2;
+#
+# MDEV-7827: Assertion `!table || (!table->read_set ||
+# bitmap_is_set(table->read_set, field_index))' failed
+# in Field_long::val_str on EXPLAIN EXTENDED
+#
+CREATE TABLE t1 (f1 INT, f2 INT, KEY(f2)) ENGINE=MyISAM;
+INSERT INTO t1 VALUES (6,9);
+CREATE TABLE t2 (f3 INT) ENGINE=MyISAM;
+INSERT INTO t2 VALUES (2),(0);
+EXPLAIN EXTENDED
+SELECT f1 FROM ( SELECT * FROM t1 ) AS sq
+WHERE f1 IN (
+SELECT f3 FROM t2 WHERE f2 IN (
+SELECT f3 FROM t2 HAVING f3 >= 8
+)
+);
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY <derived2> system NULL NULL NULL NULL 1 100.00
+1 PRIMARY <subquery4> eq_ref distinct_key distinct_key 4 const 1 100.00
+1 PRIMARY t2 ALL NULL NULL NULL NULL 2 100.00 Using where; FirstMatch(<subquery4>); Using join buffer (flat, BNL join)
+4 MATERIALIZED t2 ALL NULL NULL NULL NULL 2 100.00
+2 DERIVED t1 system NULL NULL NULL NULL 1 100.00
+Warnings:
+Note 1276 Field or reference 'sq.f2' of SELECT #3 was resolved in SELECT #1
- Note 1003 /* select#1 */ select 6 AS `f1` from <materialize> (/* select#4 */ select `test`.`t2`.`f3` from `test`.`t2` having `test`.`t2`.`f3` >= 8) semi join (`test`.`t2`) where `test`.`t2`.`f3` = 6 and `<subquery4>`.`f3` = 9
++Note 1003 /* select#1 */ select 6 AS `f1` from <materialize> (/* select#4 */ select `test`.`t2`.`f3` from `test`.`t2` having `test`.`t2`.`f3` >= 8) semi join (`test`.`t2`) where `<subquery4>`.`f3` = 9 and `test`.`t2`.`f3` = 6
+DROP TABLE t2,t1;
+#
+# MDEV-9462: Out of memory using explain on 2 empty tables
+#
+CREATE TABLE `t1` (
+`REC_GROUP` char(2) DEFAULT NULL,
+`CLIENT_INFO` text CHARACTER SET utf8,
+`NAME` text,
+`PHONE_NUMBER` text,
+`ATTENTION_NAME` text,
+`PAYMENT_TERM` text CHARACTER SET utf8,
+`CREDIT_LIMIT` decimal(12,2) DEFAULT NULL,
+`LAST_PAY_DATE` text CHARACTER SET utf8,
+`TOTAL` double DEFAULT NULL,
+`TOTAL_MCL` double DEFAULT NULL,
+`TOTAL_MFS` double DEFAULT NULL,
+`TOTAL_MIS` double DEFAULT NULL,
+`BEFORE_DUE_7_MCL` double DEFAULT NULL,
+`BEFORE_DUE_7_MFS` double DEFAULT NULL,
+`BEFORE_DUE_7_MIS` double DEFAULT NULL,
+`PER1_MCL` double DEFAULT NULL,
+`PER1_MFS` double DEFAULT NULL,
+`PER1_MIS` double DEFAULT NULL,
+`PER2_MCL` double DEFAULT NULL,
+`PER2_MFS` double DEFAULT NULL,
+`PER2_MIS` double DEFAULT NULL,
+`PER3_MCL` double DEFAULT NULL,
+`PER3_MFS` double DEFAULT NULL,
+`PER3_MIS` double DEFAULT NULL,
+`PER4_MCL` double DEFAULT NULL,
+`PER4_MFS` double DEFAULT NULL,
+`PER4_MIS` double DEFAULT NULL,
+`PER5_MCL` double DEFAULT NULL,
+`PER5_MFS` double DEFAULT NULL,
+`PER5_MIS` double DEFAULT NULL,
+`PER6_MCL` double DEFAULT NULL,
+`PER6_MFS` double DEFAULT NULL,
+`PER6_MIS` double DEFAULT NULL,
+`PER7_MCL` double DEFAULT NULL,
+`PER7_MFS` double DEFAULT NULL,
+`PER7_MIS` double DEFAULT NULL,
+`BEFORE_DUE_7` double DEFAULT NULL,
+`PER1` double DEFAULT NULL,
+`PER2` double DEFAULT NULL,
+`PER3` double DEFAULT NULL,
+`PER4` double DEFAULT NULL,
+`PER5` double DEFAULT NULL,
+`PER6` double DEFAULT NULL,
+`PER7` double DEFAULT NULL,
+`REF` varchar(30) DEFAULT NULL,
+`TYPE` varchar(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL
+);
+CREATE TABLE `t2` (
+`RECEIVABLE_GROUP` char(2) DEFAULT NULL,
+`CLIENT_NUMBER` varchar(35) DEFAULT NULL,
+`CLIENT_NAME` varchar(73) DEFAULT NULL,
+`PHONE_NUMBER` char(12) DEFAULT NULL,
+`ATTENTION_NAME` char(26) DEFAULT NULL,
+`PAYMENT_TERM` varchar(26) CHARACTER SET utf8 DEFAULT NULL,
+`CREDIT_LIMIT` decimal(12,2) DEFAULT NULL,
+`LAST_PAY_DATE` varchar(42) CHARACTER SET utf8 DEFAULT NULL,
+`TOTAL` decimal(12,2) DEFAULT NULL,
+`BEFORE_DUE_7` decimal(12,2) DEFAULT NULL,
+`PER1` decimal(12,2) DEFAULT NULL,
+`PER2` decimal(12,2) DEFAULT NULL,
+`PER3` decimal(12,2) DEFAULT NULL,
+`PER4` decimal(12,2) DEFAULT NULL,
+`PER5` decimal(12,2) DEFAULT NULL,
+`PER6` decimal(12,2) DEFAULT NULL,
+`PER7` decimal(12,2) DEFAULT NULL,
+`DIVISION` varchar(3) CHARACTER SET utf8 NOT NULL,
+`CLIENT_INFO` varchar(294) CHARACTER SET utf8 DEFAULT NULL,
+`EXCHANGE_RATE` double NOT NULL,
+`REF` varchar(30) DEFAULT NULL
+);
+explain
+SELECT A.RECEIVABLE_GROUP,A.CLIENT_INFO,A.CLIENT_NAME,A.PHONE_NUMBER,A.ATTENTION_NAME,A.PAYMENT_TERM,A.CREDIT_LIMIT,A.LAST_PAY_DATE,A.TOTAL,
+COALESCE(B.TOTAL_MCL,0) AS TOTAL_MCL,
+COALESCE(C.TOTAL_MFS,0) AS TOTAL_MFS,
+COALESCE(D.TOTAL_MIS,0) AS TOTAL_MIS,
+COALESCE(F.BEFORE_DUE_7_MCL,0) AS BEFORE_DUE_7_MCL,
+COALESCE(G.BEFORE_DUE_7_MFS,0) AS BEFORE_DUE_7_MFS,
+COALESCE(H.BEFORE_DUE_7_MIS,0) AS BEFORE_DUE_7_MIS,
+COALESCE(I.PER1_MCL,0) AS PER1_MCL,
+COALESCE(J.PER1_MFS,0) AS PER1_MFS,
+COALESCE(K.PER1_MIS,0) AS PER1_MIS,
+COALESCE(L.PER2_MCL,0) AS PER2_MCL,
+COALESCE(M.PER2_MFS,0) AS PER2_MFS,
+COALESCE(N.PER2_MIS,0) AS PER2_MIS,
+COALESCE(O.PER3_MCL,0) AS PER3_MCL,
+COALESCE(P.PER3_MFS,0) AS PER3_MFS,
+COALESCE(R.PER3_MIS,0) AS PER3_MIS,
+COALESCE(S.PER4_MCL,0) AS PER4_MCL,
+COALESCE(T.PER4_MFS,0) AS PER4_MFS,
+COALESCE(U.PER4_MIS,0) AS PER4_MIS,
+COALESCE(V.PER5_MCL,0) AS PER5_MCL,
+COALESCE(X.PER5_MFS,0) AS PER5_MFS,
+COALESCE(Z.PER5_MIS,0) AS PER5_MIS,
+COALESCE(Q.PER6_MCL,0) AS PER6_MCL,
+COALESCE(Y.PER6_MFS,0) AS PER6_MFS,
+COALESCE(W.PER6_MIS,0) AS PER6_MIS,
+COALESCE(A1.PER7_MCL,0) AS PER7_MCL,
+COALESCE(B1.PER7_MFS,0) AS PER7_MFS,
+COALESCE(C1.PER7_MIS,0) AS PER7_MIS,
+A.BEFORE_DUE_7,A.PER1,A.PER2,A.PER3,A.PER4,A.PER5,A.PER6,A.PER7,
+CONCAT(A.DIVISION,'-',A.CLIENT_NUMBER) AS REF,"2" AS TYPE FROM
+(SELECT RECEIVABLE_GROUP,DIVISION,CLIENT_NUMBER,
+GROUP_CONCAT(DISTINCT CLIENT_INFO SEPARATOR '<br>') AS CLIENT_INFO,
+GROUP_CONCAT(DISTINCT CLIENT_NAME SEPARATOR '<br>') AS CLIENT_NAME,
+GROUP_CONCAT( DISTINCT `PHONE_NUMBER` SEPARATOR '<br>' ) AS PHONE_NUMBER ,
+GROUP_CONCAT( DISTINCT `ATTENTION_NAME` SEPARATOR '<br>' ) AS ATTENTION_NAME,
+GROUP_CONCAT( DISTINCT `PAYMENT_TERM` SEPARATOR '<br>' ) AS PAYMENT_TERM,
+CREDIT_LIMIT ,
+GROUP_CONCAT( `LAST_PAY_DATE` SEPARATOR '<br>' ) AS LAST_PAY_DATE,
+SUM( `TOTAL`*EXCHANGE_RATE ) AS TOTAL,
+SUM( `BEFORE_DUE_7`*EXCHANGE_RATE ) AS BEFORE_DUE_7,
+SUM( `PER1`*EXCHANGE_RATE ) AS PER1,
+SUM( `PER2`*EXCHANGE_RATE ) AS PER2,
+SUM( `PER3`*EXCHANGE_RATE ) AS PER3,
+SUM( `PER4`*EXCHANGE_RATE ) AS PER4,
+SUM( `PER5`*EXCHANGE_RATE ) AS PER5,
+SUM( `PER6`*EXCHANGE_RATE ) AS PER6,
+SUM( `PER7`*EXCHANGE_RATE ) AS PER7
+FROM `t2`
+WHERE REF IS NULL GROUP BY RECEIVABLE_GROUP,DIVISION,CLIENT_NUMBER,CREDIT_LIMIT) AS A
+LEFT JOIN
+(SELECT RECEIVABLE_GROUP,DIVISION,CLIENT_NUMBER,CREDIT_LIMIT,SUM( `TOTAL`*EXCHANGE_RATE ) AS TOTAL_MCL
+FROM `t2`
+WHERE REF IS NULL AND DIVISION="MCL" GROUP BY RECEIVABLE_GROUP,DIVISION,CLIENT_NUMBER,CREDIT_LIMIT) AS B ON A.CLIENT_NUMBER=B.CLIENT_NUMBER AND
+A.DIVISION=B.DIVISION AND A.RECEIVABLE_GROUP=B.RECEIVABLE_GROUP AND A.CREDIT_LIMIT=B.CREDIT_LIMIT
+LEFT JOIN
+(SELECT RECEIVABLE_GROUP,DIVISION,CLIENT_NUMBER,CREDIT_LIMIT,SUM( `TOTAL`*EXCHANGE_RATE ) AS TOTAL_MFS
+FROM `t2`
+WHERE REF IS NULL AND DIVISION="MFS" GROUP BY RECEIVABLE_GROUP,DIVISION,CLIENT_NUMBER,CREDIT_LIMIT) AS C ON A.CLIENT_NUMBER=C.CLIENT_NUMBER
+AND
+A.DIVISION=C.DIVISION AND A.RECEIVABLE_GROUP=C.RECEIVABLE_GROUP AND A.CREDIT_LIMIT=C.CREDIT_LIMIT
+LEFT JOIN
+(SELECT RECEIVABLE_GROUP,DIVISION,CLIENT_NUMBER,CREDIT_LIMIT,SUM( `TOTAL`*EXCHANGE_RATE ) AS TOTAL_MIS
+FROM `t2`
+WHERE REF IS NULL AND DIVISION="MIS" GROUP BY RECEIVABLE_GROUP,DIVISION,CLIENT_NUMBER,CREDIT_LIMIT) AS D ON A.CLIENT_NUMBER=D.CLIENT_NUMBER AND
+A.DIVISION=D.DIVISION AND A.RECEIVABLE_GROUP=D.RECEIVABLE_GROUP AND A.CREDIT_LIMIT=D.CREDIT_LIMIT
+LEFT JOIN
+(SELECT RECEIVABLE_GROUP,DIVISION,CLIENT_NUMBER,CREDIT_LIMIT,SUM( BEFORE_DUE_7*EXCHANGE_RATE ) AS BEFORE_DUE_7_MCL
+FROM `t2`
+WHERE REF IS NULL AND DIVISION="MCL" GROUP BY RECEIVABLE_GROUP,DIVISION,CLIENT_NUMBER,CREDIT_LIMIT) AS F ON A.CLIENT_NUMBER=F.CLIENT_NUMBER AND
+A.DIVISION=F.DIVISION AND A.RECEIVABLE_GROUP=F.RECEIVABLE_GROUP AND A.CREDIT_LIMIT=F.CREDIT_LIMIT
+LEFT JOIN
+(SELECT RECEIVABLE_GROUP,DIVISION,CLIENT_NUMBER,CREDIT_LIMIT,SUM( BEFORE_DUE_7*EXCHANGE_RATE ) AS BEFORE_DUE_7_MFS
+FROM `t2`
+WHERE REF IS NULL AND DIVISION="MFS" GROUP BY RECEIVABLE_GROUP,DIVISION,CLIENT_NUMBER,CREDIT_LIMIT) AS G ON A.CLIENT_NUMBER=G.CLIENT_NUMBER AND
+A.DIVISION=G.DIVISION AND A.RECEIVABLE_GROUP=G.RECEIVABLE_GROUP AND A.CREDIT_LIMIT=G.CREDIT_LIMIT
+LEFT JOIN
+(SELECT RECEIVABLE_GROUP,DIVISION,CLIENT_NUMBER,CREDIT_LIMIT,SUM( BEFORE_DUE_7*EXCHANGE_RATE ) AS BEFORE_DUE_7_MIS
+FROM `t2`
+WHERE REF IS NULL AND DIVISION="MIS" GROUP BY RECEIVABLE_GROUP,DIVISION,CLIENT_NUMBER,CREDIT_LIMIT) AS H ON A.CLIENT_NUMBER=H.CLIENT_NUMBER AND
+A.DIVISION=H.DIVISION AND A.RECEIVABLE_GROUP=H.RECEIVABLE_GROUP AND A.CREDIT_LIMIT=H.CREDIT_LIMIT
+LEFT JOIN
+(SELECT RECEIVABLE_GROUP,DIVISION,CLIENT_NUMBER,CREDIT_LIMIT,SUM( PER1*EXCHANGE_RATE ) AS PER1_MCL
+FROM `t2`
+WHERE REF IS NULL AND DIVISION="MCL" GROUP BY RECEIVABLE_GROUP,DIVISION,CLIENT_NUMBER,CREDIT_LIMIT) AS I ON A.CLIENT_NUMBER=I.CLIENT_NUMBER AND
+A.DIVISION=I.DIVISION AND A.RECEIVABLE_GROUP=I.RECEIVABLE_GROUP AND A.CREDIT_LIMIT=I.CREDIT_LIMIT
+LEFT JOIN
+(SELECT RECEIVABLE_GROUP,DIVISION,CLIENT_NUMBER,CREDIT_LIMIT,SUM( PER1*EXCHANGE_RATE ) AS PER1_MFS
+FROM `t2`
+WHERE REF IS NULL AND DIVISION="MFS" GROUP BY RECEIVABLE_GROUP,DIVISION,CLIENT_NUMBER,CREDIT_LIMIT) AS J ON A.CLIENT_NUMBER=J.CLIENT_NUMBER AND
+A.DIVISION=J.DIVISION AND A.RECEIVABLE_GROUP=J.RECEIVABLE_GROUP AND A.CREDIT_LIMIT=J.CREDIT_LIMIT
+LEFT JOIN
+(SELECT RECEIVABLE_GROUP,DIVISION,CLIENT_NUMBER,CREDIT_LIMIT,SUM( PER1*EXCHANGE_RATE ) AS PER1_MIS
+FROM `t2`
+WHERE REF IS NULL AND DIVISION="MIS" GROUP BY RECEIVABLE_GROUP,DIVISION,CLIENT_NUMBER,CREDIT_LIMIT) AS K ON A.CLIENT_NUMBER=K.CLIENT_NUMBER AND
+A.DIVISION=K.DIVISION AND A.RECEIVABLE_GROUP=K.RECEIVABLE_GROUP AND A.CREDIT_LIMIT=K.CREDIT_LIMIT
+LEFT JOIN
+(SELECT RECEIVABLE_GROUP,DIVISION,CLIENT_NUMBER,CREDIT_LIMIT,SUM( PER2*EXCHANGE_RATE ) AS PER2_MCL
+FROM `t2`
+WHERE REF IS NULL AND DIVISION="MCL" GROUP BY RECEIVABLE_GROUP,DIVISION,CLIENT_NUMBER,CREDIT_LIMIT) AS L ON A.CLIENT_NUMBER=L.CLIENT_NUMBER AND
+A.DIVISION=L.DIVISION AND A.RECEIVABLE_GROUP=L.RECEIVABLE_GROUP AND A.CREDIT_LIMIT=L.CREDIT_LIMIT
+LEFT JOIN
+(SELECT RECEIVABLE_GROUP,DIVISION,CLIENT_NUMBER,CREDIT_LIMIT,SUM( PER2*EXCHANGE_RATE ) AS PER2_MFS
+FROM `t2`
+WHERE REF IS NULL AND DIVISION="MFS" GROUP BY RECEIVABLE_GROUP,DIVISION,CLIENT_NUMBER,CREDIT_LIMIT) AS M ON A.CLIENT_NUMBER=M.CLIENT_NUMBER AND
+A.DIVISION=M.DIVISION AND A.RECEIVABLE_GROUP=M.RECEIVABLE_GROUP AND A.CREDIT_LIMIT=M.CREDIT_LIMIT
+LEFT JOIN
+(SELECT RECEIVABLE_GROUP,DIVISION,CLIENT_NUMBER,CREDIT_LIMIT,SUM( PER2*EXCHANGE_RATE ) AS PER2_MIS
+FROM `t2`
+WHERE REF IS NULL AND DIVISION="MIS" GROUP BY RECEIVABLE_GROUP,DIVISION,CLIENT_NUMBER,CREDIT_LIMIT) AS N ON A.CLIENT_NUMBER=N.CLIENT_NUMBER AND
+A.DIVISION=N.DIVISION AND A.RECEIVABLE_GROUP=N.RECEIVABLE_GROUP AND A.CREDIT_LIMIT=N.CREDIT_LIMIT
+LEFT JOIN
+(SELECT RECEIVABLE_GROUP,DIVISION,CLIENT_NUMBER,CREDIT_LIMIT,SUM( PER3*EXCHANGE_RATE ) AS PER3_MCL
+FROM `t2`
+WHERE REF IS NULL AND DIVISION="MCL" GROUP BY RECEIVABLE_GROUP,DIVISION,CLIENT_NUMBER,CREDIT_LIMIT) AS O ON A.CLIENT_NUMBER=O.CLIENT_NUMBER AND
+A.DIVISION=O.DIVISION AND A.RECEIVABLE_GROUP=O.RECEIVABLE_GROUP AND A.CREDIT_LIMIT=O.CREDIT_LIMIT
+LEFT JOIN
+(SELECT RECEIVABLE_GROUP,DIVISION,CLIENT_NUMBER,CREDIT_LIMIT,SUM( PER3*EXCHANGE_RATE ) AS PER3_MFS
+FROM `t2`
+WHERE REF IS NULL AND DIVISION="MFS" GROUP BY RECEIVABLE_GROUP,DIVISION,CLIENT_NUMBER,CREDIT_LIMIT) AS P ON A.CLIENT_NUMBER=P.CLIENT_NUMBER AND
+A.DIVISION=P.DIVISION AND A.RECEIVABLE_GROUP=P.RECEIVABLE_GROUP AND A.CREDIT_LIMIT=P.CREDIT_LIMIT
+LEFT JOIN
+(SELECT RECEIVABLE_GROUP,DIVISION,CLIENT_NUMBER,CREDIT_LIMIT,SUM( PER3*EXCHANGE_RATE ) AS PER3_MIS
+FROM `t2`
+WHERE REF IS NULL AND DIVISION="MIS" GROUP BY RECEIVABLE_GROUP,DIVISION,CLIENT_NUMBER,CREDIT_LIMIT) AS R ON A.CLIENT_NUMBER=R.CLIENT_NUMBER AND
+A.DIVISION=R.DIVISION AND A.RECEIVABLE_GROUP=R.RECEIVABLE_GROUP AND A.CREDIT_LIMIT=R.CREDIT_LIMIT
+LEFT JOIN
+(SELECT RECEIVABLE_GROUP,DIVISION,CLIENT_NUMBER,CREDIT_LIMIT,SUM( PER4*EXCHANGE_RATE ) AS PER4_MCL
+FROM `t2`
+WHERE REF IS NULL AND DIVISION="MCL" GROUP BY RECEIVABLE_GROUP,DIVISION,CLIENT_NUMBER,CREDIT_LIMIT) AS S ON A.CLIENT_NUMBER=S.CLIENT_NUMBER AND
+A.DIVISION=S.DIVISION AND A.RECEIVABLE_GROUP=S.RECEIVABLE_GROUP AND A.CREDIT_LIMIT=S.CREDIT_LIMIT
+LEFT JOIN
+(SELECT RECEIVABLE_GROUP,DIVISION,CLIENT_NUMBER,CREDIT_LIMIT,SUM( PER4*EXCHANGE_RATE ) AS PER4_MFS
+FROM `t2`
+WHERE REF IS NULL AND DIVISION="MFS" GROUP BY RECEIVABLE_GROUP,DIVISION,CLIENT_NUMBER,CREDIT_LIMIT) AS T ON A.CLIENT_NUMBER=T.CLIENT_NUMBER AND
+A.DIVISION=T.DIVISION AND A.RECEIVABLE_GROUP=T.RECEIVABLE_GROUP AND A.CREDIT_LIMIT=T.CREDIT_LIMIT
+LEFT JOIN
+(SELECT RECEIVABLE_GROUP,DIVISION,CLIENT_NUMBER,CREDIT_LIMIT,SUM( PER4*EXCHANGE_RATE ) AS PER4_MIS
+FROM `t2`
+WHERE REF IS NULL AND DIVISION="MIS" GROUP BY RECEIVABLE_GROUP,DIVISION,CLIENT_NUMBER,CREDIT_LIMIT) AS U ON A.CLIENT_NUMBER=U.CLIENT_NUMBER AND
+A.DIVISION=U.DIVISION AND A.RECEIVABLE_GROUP=U.RECEIVABLE_GROUP AND A.CREDIT_LIMIT=U.CREDIT_LIMIT
+LEFT JOIN
+(SELECT RECEIVABLE_GROUP,DIVISION,CLIENT_NUMBER,CREDIT_LIMIT,SUM( PER5*EXCHANGE_RATE ) AS PER5_MCL
+FROM `t2`
+WHERE REF IS NULL AND DIVISION="MCL" GROUP BY RECEIVABLE_GROUP,DIVISION,CLIENT_NUMBER,CREDIT_LIMIT) AS V ON A.CLIENT_NUMBER=V.CLIENT_NUMBER AND
+A.DIVISION=V.DIVISION AND A.RECEIVABLE_GROUP=V.RECEIVABLE_GROUP AND A.CREDIT_LIMIT=V.CREDIT_LIMIT
+LEFT JOIN
+(SELECT RECEIVABLE_GROUP,DIVISION,CLIENT_NUMBER,CREDIT_LIMIT,SUM( PER5*EXCHANGE_RATE ) AS PER5_MFS
+FROM `t2`
+WHERE REF IS NULL AND DIVISION="MFS" GROUP BY RECEIVABLE_GROUP,DIVISION,CLIENT_NUMBER,CREDIT_LIMIT) AS X ON A.CLIENT_NUMBER=X.CLIENT_NUMBER AND
+A.DIVISION=X.DIVISION AND A.RECEIVABLE_GROUP=X.RECEIVABLE_GROUP AND A.CREDIT_LIMIT=X.CREDIT_LIMIT
+LEFT JOIN
+(SELECT RECEIVABLE_GROUP,DIVISION,CLIENT_NUMBER,CREDIT_LIMIT,SUM( PER5*EXCHANGE_RATE ) AS PER5_MIS
+FROM `t2`
+WHERE REF IS NULL AND DIVISION="MIS" GROUP BY RECEIVABLE_GROUP,DIVISION,CLIENT_NUMBER,CREDIT_LIMIT) AS Z ON A.CLIENT_NUMBER=Z.CLIENT_NUMBER AND
+A.DIVISION=Z.DIVISION AND A.RECEIVABLE_GROUP=Z.RECEIVABLE_GROUP AND A.CREDIT_LIMIT=Z.CREDIT_LIMIT
+LEFT JOIN
+(SELECT RECEIVABLE_GROUP,DIVISION,CLIENT_NUMBER,CREDIT_LIMIT,SUM( PER6*EXCHANGE_RATE ) AS PER6_MCL
+FROM `t2`
+WHERE REF IS NULL AND DIVISION="MCL" GROUP BY RECEIVABLE_GROUP,DIVISION,CLIENT_NUMBER,CREDIT_LIMIT) AS Q ON A.CLIENT_NUMBER=Q.CLIENT_NUMBER AND
+A.DIVISION=Q.DIVISION AND A.RECEIVABLE_GROUP=Q.RECEIVABLE_GROUP AND A.CREDIT_LIMIT=Q.CREDIT_LIMIT
+LEFT JOIN
+(SELECT RECEIVABLE_GROUP,DIVISION,CLIENT_NUMBER,CREDIT_LIMIT,SUM( PER6*EXCHANGE_RATE ) AS PER6_MFS
+FROM `t2`
+WHERE REF IS NULL AND DIVISION="MFS" GROUP BY RECEIVABLE_GROUP,DIVISION,CLIENT_NUMBER,CREDIT_LIMIT) AS Y ON A.CLIENT_NUMBER=Y.CLIENT_NUMBER AND
+A.DIVISION=Y.DIVISION AND A.RECEIVABLE_GROUP=Y.RECEIVABLE_GROUP AND A.CREDIT_LIMIT=Y.CREDIT_LIMIT
+LEFT JOIN
+(SELECT RECEIVABLE_GROUP,DIVISION,CLIENT_NUMBER,CREDIT_LIMIT,SUM( PER6*EXCHANGE_RATE ) AS PER6_MIS
+FROM `t2`
+WHERE REF IS NULL AND DIVISION="MIS" GROUP BY RECEIVABLE_GROUP,DIVISION,CLIENT_NUMBER,CREDIT_LIMIT) AS W ON A.CLIENT_NUMBER=W.CLIENT_NUMBER AND
+A.DIVISION=W.DIVISION AND A.RECEIVABLE_GROUP=W.RECEIVABLE_GROUP AND A.CREDIT_LIMIT=W.CREDIT_LIMIT
+LEFT JOIN
+(SELECT RECEIVABLE_GROUP,DIVISION,CLIENT_NUMBER,CREDIT_LIMIT,SUM( PER7*EXCHANGE_RATE ) AS PER7_MCL
+FROM `t2`
+WHERE REF IS NULL AND DIVISION="MCL" GROUP BY RECEIVABLE_GROUP,DIVISION,CLIENT_NUMBER,CREDIT_LIMIT) AS A1 ON A.CLIENT_NUMBER=A1.CLIENT_NUMBER AND
+A.DIVISION=A1.DIVISION AND A.RECEIVABLE_GROUP=A1.RECEIVABLE_GROUP AND A.CREDIT_LIMIT=A1.CREDIT_LIMIT
+LEFT JOIN
+(SELECT RECEIVABLE_GROUP,DIVISION,CLIENT_NUMBER,CREDIT_LIMIT,SUM( PER7*EXCHANGE_RATE ) AS PER7_MFS
+FROM `t2`
+WHERE REF IS NULL AND DIVISION="MFS" GROUP BY RECEIVABLE_GROUP,DIVISION,CLIENT_NUMBER,CREDIT_LIMIT) AS B1 ON A.CLIENT_NUMBER=B1.CLIENT_NUMBER AND
+A.DIVISION=B1.DIVISION AND A.RECEIVABLE_GROUP=B1.RECEIVABLE_GROUP AND A.CREDIT_LIMIT=B1.CREDIT_LIMIT
+LEFT JOIN
+(SELECT RECEIVABLE_GROUP,DIVISION,CLIENT_NUMBER,CREDIT_LIMIT,SUM( PER7*EXCHANGE_RATE ) AS PER7_MIS
+FROM `t2`
+WHERE REF IS NULL AND DIVISION="MIS" GROUP BY RECEIVABLE_GROUP,DIVISION,CLIENT_NUMBER,CREDIT_LIMIT) AS C1 ON A.CLIENT_NUMBER=C1.CLIENT_NUMBER AND
+A.DIVISION=C1.DIVISION AND A.RECEIVABLE_GROUP=C1.RECEIVABLE_GROUP AND A.CREDIT_LIMIT=C1.CREDIT_LIMIT
+ORDER BY TOTAL DESC;
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY <derived2> system NULL NULL NULL NULL 0 Const row not found
+1 PRIMARY <derived3> system NULL NULL NULL NULL 0 Const row not found
+1 PRIMARY <derived4> system NULL NULL NULL NULL 0 Const row not found
+1 PRIMARY <derived5> system NULL NULL NULL NULL 0 Const row not found
+1 PRIMARY <derived6> system NULL NULL NULL NULL 0 Const row not found
+1 PRIMARY <derived7> system NULL NULL NULL NULL 0 Const row not found
+1 PRIMARY <derived8> system NULL NULL NULL NULL 0 Const row not found
+1 PRIMARY <derived9> system NULL NULL NULL NULL 0 Const row not found
+1 PRIMARY <derived10> system NULL NULL NULL NULL 0 Const row not found
+1 PRIMARY <derived11> system NULL NULL NULL NULL 0 Const row not found
+1 PRIMARY <derived12> system NULL NULL NULL NULL 0 Const row not found
+1 PRIMARY <derived13> system NULL NULL NULL NULL 0 Const row not found
+1 PRIMARY <derived14> system NULL NULL NULL NULL 0 Const row not found
+1 PRIMARY <derived15> system NULL NULL NULL NULL 0 Const row not found
+1 PRIMARY <derived16> system NULL NULL NULL NULL 0 Const row not found
+1 PRIMARY <derived17> system NULL NULL NULL NULL 0 Const row not found
+1 PRIMARY <derived18> system NULL NULL NULL NULL 0 Const row not found
+1 PRIMARY <derived19> system NULL NULL NULL NULL 0 Const row not found
+1 PRIMARY <derived20> system NULL NULL NULL NULL 0 Const row not found
+1 PRIMARY <derived21> system NULL NULL NULL NULL 0 Const row not found
+1 PRIMARY <derived22> system NULL NULL NULL NULL 0 Const row not found
+1 PRIMARY <derived23> system NULL NULL NULL NULL 0 Const row not found
+1 PRIMARY <derived24> system NULL NULL NULL NULL 0 Const row not found
+1 PRIMARY <derived25> system NULL NULL NULL NULL 0 Const row not found
+1 PRIMARY <derived26> system NULL NULL NULL NULL 0 Const row not found
+1 PRIMARY <derived27> system NULL NULL NULL NULL 0 Const row not found
+1 PRIMARY <derived28> system NULL NULL NULL NULL 0 Const row not found
+1 PRIMARY <derived29> system NULL NULL NULL NULL 0 Const row not found
+29 DERIVED NULL NULL NULL NULL NULL NULL NULL no matching row in const table
+28 DERIVED NULL NULL NULL NULL NULL NULL NULL no matching row in const table
+27 DERIVED NULL NULL NULL NULL NULL NULL NULL no matching row in const table
+26 DERIVED NULL NULL NULL NULL NULL NULL NULL no matching row in const table
+25 DERIVED NULL NULL NULL NULL NULL NULL NULL no matching row in const table
+24 DERIVED NULL NULL NULL NULL NULL NULL NULL no matching row in const table
+23 DERIVED NULL NULL NULL NULL NULL NULL NULL no matching row in const table
+22 DERIVED NULL NULL NULL NULL NULL NULL NULL no matching row in const table
+21 DERIVED NULL NULL NULL NULL NULL NULL NULL no matching row in const table
+20 DERIVED NULL NULL NULL NULL NULL NULL NULL no matching row in const table
+19 DERIVED NULL NULL NULL NULL NULL NULL NULL no matching row in const table
+18 DERIVED NULL NULL NULL NULL NULL NULL NULL no matching row in const table
+17 DERIVED NULL NULL NULL NULL NULL NULL NULL no matching row in const table
+16 DERIVED NULL NULL NULL NULL NULL NULL NULL no matching row in const table
+15 DERIVED NULL NULL NULL NULL NULL NULL NULL no matching row in const table
+14 DERIVED NULL NULL NULL NULL NULL NULL NULL no matching row in const table
+13 DERIVED NULL NULL NULL NULL NULL NULL NULL no matching row in const table
+12 DERIVED NULL NULL NULL NULL NULL NULL NULL no matching row in const table
+11 DERIVED NULL NULL NULL NULL NULL NULL NULL no matching row in const table
+10 DERIVED NULL NULL NULL NULL NULL NULL NULL no matching row in const table
+9 DERIVED NULL NULL NULL NULL NULL NULL NULL no matching row in const table
+8 DERIVED NULL NULL NULL NULL NULL NULL NULL no matching row in const table
+7 DERIVED NULL NULL NULL NULL NULL NULL NULL no matching row in const table
+6 DERIVED NULL NULL NULL NULL NULL NULL NULL no matching row in const table
+5 DERIVED NULL NULL NULL NULL NULL NULL NULL no matching row in const table
+4 DERIVED NULL NULL NULL NULL NULL NULL NULL no matching row in const table
+3 DERIVED NULL NULL NULL NULL NULL NULL NULL no matching row in const table
+2 DERIVED NULL NULL NULL NULL NULL NULL NULL no matching row in const table
+DROP TABLES t1,t2;
+set optimizer_switch=@save_derived_optimizer_switch;
+#
+# MDEV-10663: Use of Inline table columns in HAVING clause
+# throws 1463 Error
+#
+set @save_sql_mode = @@sql_mode;
+set sql_mode='ONLY_FULL_GROUP_BY,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION';
+CREATE TABLE `example1463` (
+`Customer` varchar(255) NOT NULL,
+`DeliveryStatus` varchar(255) NOT NULL,
+`OrderSize` int(11) NOT NULL
+);
+INSERT INTO example1463 VALUES ('Charlie', 'Success', 100);
+INSERT INTO example1463 VALUES ('David', 'Success', 110);
+INSERT INTO example1463 VALUES ('Charlie', 'Failed', 200);
+INSERT INTO example1463 VALUES ('David', 'Success', 100);
+INSERT INTO example1463 VALUES ('David', 'Unknown', 100);
+INSERT INTO example1463 VALUES ('Edward', 'Success', 150);
+INSERT INTO example1463 VALUES ('Edward', 'Pending', 150);
+SELECT Customer, Success, SUM(OrderSize)
+FROM (SELECT Customer,
+CASE WHEN DeliveryStatus='Success' THEN 'Yes' ELSE 'No' END AS Success,
+OrderSize
+FROM example1463) as subQ
+GROUP BY Success, Customer
+WITH ROLLUP;
+Customer Success SUM(OrderSize)
+Charlie No 200
+David No 100
+Edward No 150
+NULL No 450
+Charlie Yes 100
+David Yes 210
+Edward Yes 150
+NULL Yes 460
+NULL NULL 910
+SELECT Customer, Success, SUM(OrderSize)
+FROM (SELECT Customer,
+CASE WHEN DeliveryStatus='Success' THEN 'Yes' ELSE 'No' END AS Success,
+OrderSize
+FROM example1463) as subQ
+GROUP BY Success, Customer;
+Customer Success SUM(OrderSize)
+Charlie No 200
+David No 100
+Edward No 150
+Charlie Yes 100
+David Yes 210
+Edward Yes 150
+SELECT Customer, Success, SUM(OrderSize)
+FROM (SELECT Customer,
+CASE WHEN DeliveryStatus='Success' THEN 'Yes' ELSE 'No' END AS Success,
+OrderSize
+FROM example1463) as subQ
+GROUP BY Success, Customer
+HAVING Success IS NOT NULL;
+Customer Success SUM(OrderSize)
+Charlie No 200
+David No 100
+Edward No 150
+Charlie Yes 100
+David Yes 210
+Edward Yes 150
+DROP TABLE example1463;
+set sql_mode= @save_sql_mode;
+#
+# MDEV-9028: SELECT DISTINCT constant column of derived table
+# used as the second operand of LEFT JOIN
+#
+create table t1 (id int, data varchar(255));
+insert into t1 values (1,'yes'),(2,'yes');
+select distinct t1.id, tt.id, tt.data
+from t1
+left join
+(select t1.id, 'yes' as data from t1) as tt
+on t1.id = tt.id;
+id id data
+1 1 yes
+2 2 yes
+select distinct t1.id, tt.id, tt.data
+from t1
+left join
+(select t1.id, 'yes' as data from t1 where id > 1) as tt
+on t1.id = tt.id;
+id id data
+2 2 yes
+1 NULL NULL
+drop table t1;
+#
+# MDEV-14241: Server crash in key_copy / get_matching_chain_by_join_key
+# or valgrind warnings
+#
+CREATE TABLE t1 (a VARCHAR(10)) ENGINE=MyISAM;
+CREATE OR REPLACE ALGORITHM=TEMPTABLE VIEW v1 AS SELECT * FROM t1;
+INSERT INTO t1 VALUES ('foo'),('bar');
+CREATE TABLE t2 (b integer auto_increment primary key) ENGINE=MyISAM;
+INSERT INTO t2 VALUES (NULL),(NULL);
+CREATE TABLE t3 (c VARCHAR(1024) CHARACTER SET utf8, d INT) ENGINE=MyISAM;
+CREATE OR REPLACE ALGORITHM=TEMPTABLE VIEW v3 AS SELECT * FROM t3;
+INSERT INTO t3 VALUES ('abc',NULL),('def',4);
+SET join_cache_level= 8;
+explain
+SELECT * FROM v1, t2, v3 WHERE a = c AND b = d;
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY <derived2> ALL NULL NULL NULL NULL 2
+1 PRIMARY <derived3> hash_ALL NULL #hash#$hj 3075 func 2 Using where; Using join buffer (flat, BNLH join)
+1 PRIMARY t2 eq_ref PRIMARY PRIMARY 4 v3.d 1 Using index
+3 DERIVED t3 ALL NULL NULL NULL NULL 2
+2 DERIVED t1 ALL NULL NULL NULL NULL 2
+SELECT * FROM v1, t2, v3 WHERE a = c AND b = d;
+a b c d
+DROP VIEW v1, v3;
+DROP TABLE t1, t2, t3;
+#
+# MDEV-14786: Server crashes in Item_cond::transform on 2nd
+# execution of SP querying from a view
+#
+create table t1 (i int, row_start timestamp(6) not null default now(),
+row_end timestamp(6) not null default '2030-01-01 0:0:0');
+create view v1 as select i from t1 where i < 5 and (row_end =
+TIMESTAMP'2030-01-01 0:0:0' or row_end is null);
+create procedure pr(x int) select i from v1;
+call pr(1);
+i
+call pr(2);
+i
+drop procedure pr;
+drop view v1;
+drop table t1;
+# end of 5.5
+#
+# Start of 10.1 tests
+#
+#
+# MDEV-8747 Wrong result for SELECT..WHERE derived_table_column='a' AND derived_table_column<>_latin1'A' COLLATE latin1_bin
+#
+CREATE TABLE t1 (a VARCHAR(10));
+INSERT INTO t1 VALUES ('a'),('A');
+SELECT * FROM t1 WHERE a='a' AND a <> _latin1'A' COLLATE latin1_bin;
+a
+a
+SELECT * FROM (SELECT * FROM t1) AS table1 WHERE a='a' AND a <> _latin1'A' COLLATE latin1_bin;
+a
+a
+DROP TABLE t1;
+CREATE TABLE t1 (a ENUM('5','6'));
+INSERT INTO t1 VALUES ('5'),('6');
+SELECT * FROM (SELECT * FROM t1) AS table1 WHERE a='5';
+a
+5
+SELECT * FROM (SELECT * FROM t1) AS table1 WHERE a=1;
+a
+5
+SELECT * FROM (SELECT * FROM t1) AS table1 WHERE a='5' AND a=1;
+a
+5
+DROP TABLE t1;
+#
+# MDEV-8749 Wrong result for SELECT..WHERE derived_table_enum_column='number' AND derived_table_enum_column OP number2
+#
+CREATE TABLE t1 (a ENUM('5','6'));
+INSERT INTO t1 VALUES ('5'),('6');
+SELECT * FROM (SELECT * FROM t1) AS table1 WHERE a='5';
+a
+5
+SELECT * FROM (SELECT * FROM t1) AS table1 WHERE a=1;
+a
+5
+SELECT * FROM (SELECT * FROM t1) AS table1 WHERE a='5' AND a=1;
+a
+5
+DROP TABLE t1;
+#
+# End of 10.1 tests
+#
+#
+# MDEV-10554: Assertion `!derived->first_select()->
+# exclude_from_table_unique_test || derived->outer_select()->
+# exclude_from_table_unique_test'
+# failed in TABLE_LIST::set_check_merged()
+#
+CREATE TABLE t1 (f INT);
+CREATE ALGORITHM = TEMPTABLE VIEW v1 AS SELECT * FROM ( SELECT * FROM t1 ) AS sq;
+PREPARE stmt FROM 'SELECT * FROM v1';
+EXECUTE stmt;
+f
+EXECUTE stmt;
+f
+drop view v1;
+drop table t1;
+#
+# MDEV-11363: Assertion `!derived->first_sel ect()->first_inner_unit() ||
+# derived->first_select()->first_inner_unit()->first_select()->
+# exclude_from_table_unique_test' failed in
+# TABLE_LIST::set_check_materialized()
+#
+CREATE TABLE t1 (f1 INT);
+CREATE TABLE t2 (f2 INT);
+CREATE TABLE t3 (f3 INT);
+CREATE VIEW v1 AS ( SELECT f1 AS f FROM t1 ) UNION ( SELECT f2 AS f FROM t2 );
+CREATE VIEW v2 AS SELECT f3 AS f FROM t3;
+CREATE VIEW v3 AS SELECT f FROM ( SELECT f3 AS f FROM v1, t3 ) AS sq;
+CREATE VIEW v4 AS SELECT COUNT(*) as f FROM v3;
+REPLACE INTO v2 ( SELECT * FROM v4 ) UNION ( SELECT f FROM v2 );
+drop view v1,v2,v3,v4;
+drop table t1,t2,t3;
+#
+# End of 10.2 tests
+#
diff --cc mysql-test/main/in_subq_cond_pushdown.result
index 0000000,0000000..d979ad0
new file mode 100644
--- /dev/null
+++ b/mysql-test/main/in_subq_cond_pushdown.result
@@@ -1,0 -1,0 +1,3801 @@@
++CREATE TABLE t1 (a INT, b INT, c INT, d INT);
++CREATE TABLE t2 (e INT, f INT, g INT);
++CREATE TABLE t3 (x INT, y INT);
++INSERT INTO t1 VALUES
++(1,1,18,1), (2,1,25,1), (1,3,40,1), (2,3,40,4),
++(4,2,24,4), (3,2,23,1), (1,2,40,2), (3,4,17,2),
++(5,5,65,1), (2,3,70,3), (1,4,35,3), (2,3,25,3),
++(2,2,40,4), (1,4,55,1), (5,3,72,4), (1,2,70,5);
++INSERT INTO t2 VALUES
++(1,2,38), (2,3,15), (1,3,40), (1,4,35),
++(2,2,70), (3,4,23), (5,5,12), (5,4,17),
++(3,3,17), (4,2,24), (2,5,25), (5,1,65);
++INSERT INTO t3 VALUES
++(1,25), (1,18), (2,15), (4,24),
++(1,35), (3,23), (3,17), (2,15);
++CREATE VIEW v1 AS
++(
++SELECT t3.x AS v1_x, t3.y AS v1_y FROM t3 WHERE t3.x<=3
++);
++CREATE VIEW v2 AS
++(
++SELECT t2.e, t2.f, MAX(t2.g) AS max_g
++FROM t2
++GROUP BY t2.e
++HAVING max_g>25
++);
++# conjunctive subformula : pushing into HAVING
++SET STATEMENT optimizer_switch='condition_pushdown_for_subquery=off' FOR SELECT * FROM t1
++WHERE t1.c<25 AND
++(t1.a,t1.c) IN (SELECT t2.e,MAX(t2.g) FROM t2 WHERE t2.e<5 GROUP BY t2.e);
++a b c d
++4 2 24 4
++3 2 23 1
++SELECT * FROM t1
++WHERE t1.c<25 AND
++(t1.a,t1.c) IN (SELECT t2.e,MAX(t2.g) FROM t2 WHERE t2.e<5 GROUP BY t2.e);
++a b c d
++4 2 24 4
++3 2 23 1
++EXPLAIN SELECT * FROM t1
++WHERE t1.c<25 AND
++(t1.a,t1.c) IN (SELECT t2.e,MAX(t2.g) FROM t2 WHERE t2.e<5 GROUP BY t2.e);
++id select_type table type possible_keys key key_len ref rows Extra
++1 PRIMARY t1 ALL NULL NULL NULL NULL 16 Using where
++1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 8 test.t1.a,test.t1.c 1
++2 MATERIALIZED t2 ALL NULL NULL NULL NULL 12 Using where; Using temporary
++EXPLAIN FORMAT=JSON SELECT * FROM t1
++WHERE t1.c<25 AND
++(t1.a,t1.c) IN (SELECT t2.e,MAX(t2.g) FROM t2 WHERE t2.e<5 GROUP BY t2.e);
++EXPLAIN
++{
++ "query_block": {
++ "select_id": 1,
++ "table": {
++ "table_name": "t1",
++ "access_type": "ALL",
++ "rows": 16,
++ "filtered": 100,
++ "attached_condition": "t1.c < 25 and t1.a is not null and t1.c is not null"
++ },
++ "table": {
++ "table_name": "<subquery2>",
++ "access_type": "eq_ref",
++ "possible_keys": ["distinct_key"],
++ "key": "distinct_key",
++ "key_length": "8",
++ "used_key_parts": ["e", "MAX(t2.g)"],
++ "ref": ["test.t1.a", "test.t1.c"],
++ "rows": 1,
++ "filtered": 100,
++ "materialized": {
++ "unique": 1,
++ "query_block": {
++ "select_id": 2,
++ "having_condition": "`MAX(t2.g)` < 25",
++ "temporary_table": {
++ "table": {
++ "table_name": "t2",
++ "access_type": "ALL",
++ "rows": 12,
++ "filtered": 100,
++ "attached_condition": "t2.e < 5"
++ }
++ }
++ }
++ }
++ }
++ }
++}
++# extracted AND formula : pushing into HAVING
++SET STATEMENT optimizer_switch='condition_pushdown_for_subquery=off' FOR SELECT * FROM t1
++WHERE t1.c>55 AND t1.b<4 AND
++(t1.a,t1.b,t1.c) IN
++(
++SELECT t2.e,t2.f,MAX(t2.g)
++FROM t2
++WHERE t2.e<5
++GROUP BY t2.e
++)
++;
++a b c d
++2 3 70 3
++SELECT * FROM t1
++WHERE t1.c>55 AND t1.b<4 AND
++(t1.a,t1.b,t1.c) IN
++(
++SELECT t2.e,t2.f,MAX(t2.g)
++FROM t2
++WHERE t2.e<5
++GROUP BY t2.e
++)
++;
++a b c d
++2 3 70 3
++EXPLAIN SELECT * FROM t1
++WHERE t1.c>55 AND t1.b<4 AND
++(t1.a,t1.b,t1.c) IN
++(
++SELECT t2.e,t2.f,MAX(t2.g)
++FROM t2
++WHERE t2.e<5
++GROUP BY t2.e
++)
++;
++id select_type table type possible_keys key key_len ref rows Extra
++1 PRIMARY t1 ALL NULL NULL NULL NULL 16 Using where
++1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 12 test.t1.a,test.t1.b,test.t1.c 1
++2 MATERIALIZED t2 ALL NULL NULL NULL NULL 12 Using where; Using temporary
++EXPLAIN FORMAT=JSON SELECT * FROM t1
++WHERE t1.c>55 AND t1.b<4 AND
++(t1.a,t1.b,t1.c) IN
++(
++SELECT t2.e,t2.f,MAX(t2.g)
++FROM t2
++WHERE t2.e<5
++GROUP BY t2.e
++)
++;
++EXPLAIN
++{
++ "query_block": {
++ "select_id": 1,
++ "table": {
++ "table_name": "t1",
++ "access_type": "ALL",
++ "rows": 16,
++ "filtered": 100,
++ "attached_condition": "t1.c > 55 and t1.b < 4 and t1.a is not null and t1.b is not null and t1.c is not null"
++ },
++ "table": {
++ "table_name": "<subquery2>",
++ "access_type": "eq_ref",
++ "possible_keys": ["distinct_key"],
++ "key": "distinct_key",
++ "key_length": "12",
++ "used_key_parts": ["e", "f", "MAX(t2.g)"],
++ "ref": ["test.t1.a", "test.t1.b", "test.t1.c"],
++ "rows": 1,
++ "filtered": 100,
++ "materialized": {
++ "unique": 1,
++ "query_block": {
++ "select_id": 2,
++ "having_condition": "`MAX(t2.g)` > 55 and t2.f < 4",
++ "temporary_table": {
++ "table": {
++ "table_name": "t2",
++ "access_type": "ALL",
++ "rows": 12,
++ "filtered": 100,
++ "attached_condition": "t2.e < 5"
++ }
++ }
++ }
++ }
++ }
++ }
++}
++# extracted OR formula : pushing into HAVING
++SET STATEMENT optimizer_switch='condition_pushdown_for_subquery=off' FOR SELECT * FROM t1
++WHERE (t1.c>60 OR t1.c<25) AND
++(t1.a,t1.b,t1.c) IN
++(
++SELECT t2.e,t2.f,MAX(t2.g)
++FROM t2
++WHERE t2.e<5
++GROUP BY t2.e
++)
++;
++a b c d
++4 2 24 4
++2 3 70 3
++SELECT * FROM t1
++WHERE (t1.c>60 OR t1.c<25) AND
++(t1.a,t1.b,t1.c) IN
++(
++SELECT t2.e,t2.f,MAX(t2.g)
++FROM t2
++WHERE t2.e<5
++GROUP BY t2.e
++)
++;
++a b c d
++4 2 24 4
++2 3 70 3
++EXPLAIN SELECT * FROM t1
++WHERE (t1.c>60 OR t1.c<25) AND
++(t1.a,t1.b,t1.c) IN
++(
++SELECT t2.e,t2.f,MAX(t2.g)
++FROM t2
++WHERE t2.e<5
++GROUP BY t2.e
++)
++;
++id select_type table type possible_keys key key_len ref rows Extra
++1 PRIMARY t1 ALL NULL NULL NULL NULL 16 Using where
++1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 12 test.t1.a,test.t1.b,test.t1.c 1
++2 MATERIALIZED t2 ALL NULL NULL NULL NULL 12 Using where; Using temporary
++EXPLAIN FORMAT=JSON SELECT * FROM t1
++WHERE (t1.c>60 OR t1.c<25) AND
++(t1.a,t1.b,t1.c) IN
++(
++SELECT t2.e,t2.f,MAX(t2.g)
++FROM t2
++WHERE t2.e<5
++GROUP BY t2.e
++)
++;
++EXPLAIN
++{
++ "query_block": {
++ "select_id": 1,
++ "table": {
++ "table_name": "t1",
++ "access_type": "ALL",
++ "rows": 16,
++ "filtered": 100,
++ "attached_condition": "(t1.c > 60 or t1.c < 25) and t1.a is not null and t1.b is not null and t1.c is not null"
++ },
++ "table": {
++ "table_name": "<subquery2>",
++ "access_type": "eq_ref",
++ "possible_keys": ["distinct_key"],
++ "key": "distinct_key",
++ "key_length": "12",
++ "used_key_parts": ["e", "f", "MAX(t2.g)"],
++ "ref": ["test.t1.a", "test.t1.b", "test.t1.c"],
++ "rows": 1,
++ "filtered": 100,
++ "materialized": {
++ "unique": 1,
++ "query_block": {
++ "select_id": 2,
++ "having_condition": "`MAX(t2.g)` > 60 or `MAX(t2.g)` < 25",
++ "temporary_table": {
++ "table": {
++ "table_name": "t2",
++ "access_type": "ALL",
++ "rows": 12,
++ "filtered": 100,
++ "attached_condition": "t2.e < 5"
++ }
++ }
++ }
++ }
++ }
++ }
++}
++# extracted AND-OR formula : pushing into HAVING
++SET STATEMENT optimizer_switch='condition_pushdown_for_subquery=off' FOR SELECT * FROM t1
++WHERE ((t1.c>60 OR t1.c<25) AND t1.b>2) AND
++(t1.a,t1.b,t1.c) IN
++(
++SELECT t2.e,t2.f,MAX(t2.g)
++FROM t2
++WHERE t2.e<5
++GROUP BY t2.e
++)
++;
++a b c d
++2 3 70 3
++SELECT * FROM t1
++WHERE ((t1.c>60 OR t1.c<25) AND t1.b>2) AND
++(t1.a,t1.b,t1.c) IN
++(
++SELECT t2.e,t2.f,MAX(t2.g)
++FROM t2
++WHERE t2.e<5
++GROUP BY t2.e
++)
++;
++a b c d
++2 3 70 3
++EXPLAIN SELECT * FROM t1
++WHERE ((t1.c>60 OR t1.c<25) AND t1.b>2) AND
++(t1.a,t1.b,t1.c) IN
++(
++SELECT t2.e,t2.f,MAX(t2.g)
++FROM t2
++WHERE t2.e<5
++GROUP BY t2.e
++)
++;
++id select_type table type possible_keys key key_len ref rows Extra
++1 PRIMARY t1 ALL NULL NULL NULL NULL 16 Using where
++1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 12 test.t1.a,test.t1.b,test.t1.c 1
++2 MATERIALIZED t2 ALL NULL NULL NULL NULL 12 Using where; Using temporary
++EXPLAIN FORMAT=JSON SELECT * FROM t1
++WHERE ((t1.c>60 OR t1.c<25) AND t1.b>2) AND
++(t1.a,t1.b,t1.c) IN
++(
++SELECT t2.e,t2.f,MAX(t2.g)
++FROM t2
++WHERE t2.e<5
++GROUP BY t2.e
++)
++;
++EXPLAIN
++{
++ "query_block": {
++ "select_id": 1,
++ "table": {
++ "table_name": "t1",
++ "access_type": "ALL",
++ "rows": 16,
++ "filtered": 100,
++ "attached_condition": "(t1.c > 60 or t1.c < 25) and t1.b > 2 and t1.a is not null and t1.b is not null and t1.c is not null"
++ },
++ "table": {
++ "table_name": "<subquery2>",
++ "access_type": "eq_ref",
++ "possible_keys": ["distinct_key"],
++ "key": "distinct_key",
++ "key_length": "12",
++ "used_key_parts": ["e", "f", "MAX(t2.g)"],
++ "ref": ["test.t1.a", "test.t1.b", "test.t1.c"],
++ "rows": 1,
++ "filtered": 100,
++ "materialized": {
++ "unique": 1,
++ "query_block": {
++ "select_id": 2,
++ "having_condition": "(`MAX(t2.g)` > 60 or `MAX(t2.g)` < 25) and t2.f > 2",
++ "temporary_table": {
++ "table": {
++ "table_name": "t2",
++ "access_type": "ALL",
++ "rows": 12,
++ "filtered": 100,
++ "attached_condition": "t2.e < 5"
++ }
++ }
++ }
++ }
++ }
++ }
++}
++# conjunctive subformula : pushing into HAVING
++SET STATEMENT optimizer_switch='condition_pushdown_for_subquery=off' FOR SELECT * FROM t1
++WHERE ((t1.a<2 OR t1.d>3) AND t1.b>1) AND
++(t1.a,t1.b,t1.c) IN
++(
++SELECT t2.e,t2.f,MAX(t2.g)
++FROM t2
++WHERE t2.e<5
++GROUP BY t2.e
++)
++;
++a b c d
++4 2 24 4
++1 2 40 2
++SELECT * FROM t1
++WHERE ((t1.a<2 OR t1.d>3) AND t1.b>1) AND
++(t1.a,t1.b,t1.c) IN
++(
++SELECT t2.e,t2.f,MAX(t2.g)
++FROM t2
++WHERE t2.e<5
++GROUP BY t2.e
++)
++;
++a b c d
++4 2 24 4
++1 2 40 2
++EXPLAIN SELECT * FROM t1
++WHERE ((t1.a<2 OR t1.d>3) AND t1.b>1) AND
++(t1.a,t1.b,t1.c) IN
++(
++SELECT t2.e,t2.f,MAX(t2.g)
++FROM t2
++WHERE t2.e<5
++GROUP BY t2.e
++)
++;
++id select_type table type possible_keys key key_len ref rows Extra
++1 PRIMARY t1 ALL NULL NULL NULL NULL 16 Using where
++1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 12 test.t1.a,test.t1.b,test.t1.c 1
++2 MATERIALIZED t2 ALL NULL NULL NULL NULL 12 Using where; Using temporary
++EXPLAIN FORMAT=JSON SELECT * FROM t1
++WHERE ((t1.a<2 OR t1.d>3) AND t1.b>1) AND
++(t1.a,t1.b,t1.c) IN
++(
++SELECT t2.e,t2.f,MAX(t2.g)
++FROM t2
++WHERE t2.e<5
++GROUP BY t2.e
++)
++;
++EXPLAIN
++{
++ "query_block": {
++ "select_id": 1,
++ "table": {
++ "table_name": "t1",
++ "access_type": "ALL",
++ "rows": 16,
++ "filtered": 100,
++ "attached_condition": "(t1.a < 2 or t1.d > 3) and t1.b > 1 and t1.a is not null and t1.b is not null and t1.c is not null"
++ },
++ "table": {
++ "table_name": "<subquery2>",
++ "access_type": "eq_ref",
++ "possible_keys": ["distinct_key"],
++ "key": "distinct_key",
++ "key_length": "12",
++ "used_key_parts": ["e", "f", "MAX(t2.g)"],
++ "ref": ["test.t1.a", "test.t1.b", "test.t1.c"],
++ "rows": 1,
++ "filtered": 100,
++ "materialized": {
++ "unique": 1,
++ "query_block": {
++ "select_id": 2,
++ "having_condition": "t2.f > 1",
++ "temporary_table": {
++ "table": {
++ "table_name": "t2",
++ "access_type": "ALL",
++ "rows": 12,
++ "filtered": 100,
++ "attached_condition": "t2.e < 5"
++ }
++ }
++ }
++ }
++ }
++ }
++}
++# using view IN subquery defINition : pushing into HAVING
++SET STATEMENT optimizer_switch='condition_pushdown_for_subquery=off' FOR SELECT * FROM t1
++WHERE t1.c>20 AND
++(t1.a,t1.c) IN
++(
++SELECT v1_x,MAX(v1_y)
++FROM v1
++WHERE v1_x>1
++GROUP BY v1_x
++)
++;
++a b c d
++3 2 23 1
++SELECT * FROM t1
++WHERE t1.c>20 AND
++(t1.a,t1.c) IN
++(
++SELECT v1_x,MAX(v1_y)
++FROM v1
++WHERE v1_x>1
++GROUP BY v1_x
++)
++;
++a b c d
++3 2 23 1
++EXPLAIN SELECT * FROM t1
++WHERE t1.c>20 AND
++(t1.a,t1.c) IN
++(
++SELECT v1_x,MAX(v1_y)
++FROM v1
++WHERE v1_x>1
++GROUP BY v1_x
++)
++;
++id select_type table type possible_keys key key_len ref rows Extra
++1 PRIMARY t1 ALL NULL NULL NULL NULL 16 Using where
++1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 8 test.t1.a,test.t1.c 1
++2 MATERIALIZED t3 ALL NULL NULL NULL NULL 8 Using where; Using temporary
++EXPLAIN FORMAT=JSON SELECT * FROM t1
++WHERE t1.c>20 AND
++(t1.a,t1.c) IN
++(
++SELECT v1_x,MAX(v1_y)
++FROM v1
++WHERE v1_x>1
++GROUP BY v1_x
++)
++;
++EXPLAIN
++{
++ "query_block": {
++ "select_id": 1,
++ "table": {
++ "table_name": "t1",
++ "access_type": "ALL",
++ "rows": 16,
++ "filtered": 100,
++ "attached_condition": "t1.c > 20 and t1.a is not null and t1.c is not null"
++ },
++ "table": {
++ "table_name": "<subquery2>",
++ "access_type": "eq_ref",
++ "possible_keys": ["distinct_key"],
++ "key": "distinct_key",
++ "key_length": "8",
++ "used_key_parts": ["v1_x", "MAX(v1_y)"],
++ "ref": ["test.t1.a", "test.t1.c"],
++ "rows": 1,
++ "filtered": 100,
++ "materialized": {
++ "unique": 1,
++ "query_block": {
++ "select_id": 2,
++ "having_condition": "`MAX(v1_y)` > 20",
++ "temporary_table": {
++ "table": {
++ "table_name": "t3",
++ "access_type": "ALL",
++ "rows": 8,
++ "filtered": 100,
++ "attached_condition": "t3.x > 1 and t3.x <= 3"
++ }
++ }
++ }
++ }
++ }
++ }
++}
++# using equality : pushing into WHERE
++SET STATEMENT optimizer_switch='condition_pushdown_for_subquery=off' FOR SELECT * FROM t1,v1
++WHERE t1.c>20 AND t1.c=v1_y AND
++(t1.a,t1.c) IN
++(
++SELECT t2.e,MAX(t2.g)
++FROM t2
++WHERE t2.e<5
++GROUP BY t2.e
++)
++;
++a b c d v1_x v1_y
++3 2 23 1 3 23
++SELECT * FROM t1,v1
++WHERE t1.c>20 AND t1.c=v1_y AND
++(t1.a,t1.c) IN
++(
++SELECT t2.e,MAX(t2.g)
++FROM t2
++WHERE t2.e<5
++GROUP BY t2.e
++)
++;
++a b c d v1_x v1_y
++3 2 23 1 3 23
++EXPLAIN SELECT * FROM t1,v1
++WHERE t1.c>20 AND t1.c=v1_y AND
++(t1.a,t1.c) IN
++(
++SELECT t2.e,MAX(t2.g)
++FROM t2
++WHERE t2.e<5
++GROUP BY t2.e
++)
++;
++id select_type table type possible_keys key key_len ref rows Extra
++1 PRIMARY t3 ALL NULL NULL NULL NULL 8 Using where
++1 PRIMARY t1 ALL NULL NULL NULL NULL 16 Using where; Using join buffer (flat, BNL join)
++1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 8 test.t1.a,test.t3.y 1
++2 MATERIALIZED t2 ALL NULL NULL NULL NULL 12 Using where; Using temporary
++EXPLAIN FORMAT=JSON SELECT * FROM t1,v1
++WHERE t1.c>20 AND t1.c=v1_y AND
++(t1.a,t1.c) IN
++(
++SELECT t2.e,MAX(t2.g)
++FROM t2
++WHERE t2.e<5
++GROUP BY t2.e
++)
++;
++EXPLAIN
++{
++ "query_block": {
++ "select_id": 1,
++ "table": {
++ "table_name": "t3",
++ "access_type": "ALL",
++ "rows": 8,
++ "filtered": 100,
++ "attached_condition": "t3.y > 20 and t3.x <= 3 and t3.y is not null"
++ },
++ "block-nl-join": {
++ "table": {
++ "table_name": "t1",
++ "access_type": "ALL",
++ "rows": 16,
++ "filtered": 100
++ },
++ "buffer_type": "flat",
++ "buffer_size": "256Kb",
++ "join_type": "BNL",
++ "attached_condition": "t1.c = t3.y and t1.a is not null"
++ },
++ "table": {
++ "table_name": "<subquery2>",
++ "access_type": "eq_ref",
++ "possible_keys": ["distinct_key"],
++ "key": "distinct_key",
++ "key_length": "8",
++ "used_key_parts": ["e", "MAX(t2.g)"],
++ "ref": ["test.t1.a", "test.t3.y"],
++ "rows": 1,
++ "filtered": 100,
++ "materialized": {
++ "unique": 1,
++ "query_block": {
++ "select_id": 2,
++ "having_condition": "`MAX(t2.g)` > 20",
++ "temporary_table": {
++ "table": {
++ "table_name": "t2",
++ "access_type": "ALL",
++ "rows": 12,
++ "filtered": 100,
++ "attached_condition": "t2.e < 5"
++ }
++ }
++ }
++ }
++ }
++ }
++}
++# conjunctive subformula : pushing into WHERE
++SET STATEMENT optimizer_switch='condition_pushdown_for_subquery=off' FOR SELECT * FROM t1
++WHERE t1.a<2 AND
++(t1.a,t1.c) IN
++(
++SELECT t2.e,MAX(t2.g)
++FROM t2
++WHERE t2.e<5
++GROUP BY t2.e
++)
++;
++a b c d
++1 3 40 1
++1 2 40 2
++SELECT * FROM t1
++WHERE t1.a<2 AND
++(t1.a,t1.c) IN
++(
++SELECT t2.e,MAX(t2.g)
++FROM t2
++WHERE t2.e<5
++GROUP BY t2.e
++)
++;
++a b c d
++1 3 40 1
++1 2 40 2
++EXPLAIN SELECT * FROM t1
++WHERE t1.a<2 AND
++(t1.a,t1.c) IN
++(
++SELECT t2.e,MAX(t2.g)
++FROM t2
++WHERE t2.e<5
++GROUP BY t2.e
++)
++;
++id select_type table type possible_keys key key_len ref rows Extra
++1 PRIMARY t1 ALL NULL NULL NULL NULL 16 Using where
++1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 8 test.t1.a,test.t1.c 1
++2 MATERIALIZED t2 ALL NULL NULL NULL NULL 12 Using where; Using temporary
++EXPLAIN FORMAT=JSON SELECT * FROM t1
++WHERE t1.a<2 AND
++(t1.a,t1.c) IN
++(
++SELECT t2.e,MAX(t2.g)
++FROM t2
++WHERE t2.e<5
++GROUP BY t2.e
++)
++;
++EXPLAIN
++{
++ "query_block": {
++ "select_id": 1,
++ "table": {
++ "table_name": "t1",
++ "access_type": "ALL",
++ "rows": 16,
++ "filtered": 100,
++ "attached_condition": "t1.a < 2 and t1.a is not null and t1.c is not null"
++ },
++ "table": {
++ "table_name": "<subquery2>",
++ "access_type": "eq_ref",
++ "possible_keys": ["distinct_key"],
++ "key": "distinct_key",
++ "key_length": "8",
++ "used_key_parts": ["e", "MAX(t2.g)"],
++ "ref": ["test.t1.a", "test.t1.c"],
++ "rows": 1,
++ "filtered": 100,
++ "materialized": {
++ "unique": 1,
++ "query_block": {
++ "select_id": 2,
++ "temporary_table": {
++ "table": {
++ "table_name": "t2",
++ "access_type": "ALL",
++ "rows": 12,
++ "filtered": 100,
++ "attached_condition": "t2.e < 5 and t2.e < 2"
++ }
++ }
++ }
++ }
++ }
++ }
++}
++# extracted AND formula : pushing into WHERE
++SET STATEMENT optimizer_switch='condition_pushdown_for_subquery=off' FOR SELECT * FROM t1
++WHERE t1.a>2 AND t1.a<5 AND
++(t1.a,t1.c) IN
++(
++SELECT t2.e,MAX(t2.g)
++FROM t2
++WHERE t2.e<5
++GROUP BY t2.e
++)
++;
++a b c d
++4 2 24 4
++3 2 23 1
++SELECT * FROM t1
++WHERE t1.a>2 AND t1.a<5 AND
++(t1.a,t1.c) IN
++(
++SELECT t2.e,MAX(t2.g)
++FROM t2
++WHERE t2.e<5
++GROUP BY t2.e
++)
++;
++a b c d
++4 2 24 4
++3 2 23 1
++EXPLAIN SELECT * FROM t1
++WHERE t1.a>2 AND t1.a<5 AND
++(t1.a,t1.c) IN
++(
++SELECT t2.e,MAX(t2.g)
++FROM t2
++WHERE t2.e<5
++GROUP BY t2.e
++)
++;
++id select_type table type possible_keys key key_len ref rows Extra
++1 PRIMARY t1 ALL NULL NULL NULL NULL 16 Using where
++1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 8 test.t1.a,test.t1.c 1
++2 MATERIALIZED t2 ALL NULL NULL NULL NULL 12 Using where; Using temporary
++EXPLAIN FORMAT=JSON SELECT * FROM t1
++WHERE t1.a>2 AND t1.a<5 AND
++(t1.a,t1.c) IN
++(
++SELECT t2.e,MAX(t2.g)
++FROM t2
++WHERE t2.e<5
++GROUP BY t2.e
++)
++;
++EXPLAIN
++{
++ "query_block": {
++ "select_id": 1,
++ "table": {
++ "table_name": "t1",
++ "access_type": "ALL",
++ "rows": 16,
++ "filtered": 100,
++ "attached_condition": "t1.a > 2 and t1.a < 5 and t1.a is not null and t1.c is not null"
++ },
++ "table": {
++ "table_name": "<subquery2>",
++ "access_type": "eq_ref",
++ "possible_keys": ["distinct_key"],
++ "key": "distinct_key",
++ "key_length": "8",
++ "used_key_parts": ["e", "MAX(t2.g)"],
++ "ref": ["test.t1.a", "test.t1.c"],
++ "rows": 1,
++ "filtered": 100,
++ "materialized": {
++ "unique": 1,
++ "query_block": {
++ "select_id": 2,
++ "temporary_table": {
++ "table": {
++ "table_name": "t2",
++ "access_type": "ALL",
++ "rows": 12,
++ "filtered": 100,
++ "attached_condition": "t2.e < 5 and t2.e > 2 and t2.e < 5"
++ }
++ }
++ }
++ }
++ }
++ }
++}
++# extracted OR formula : pushing into WHERE
++SET STATEMENT optimizer_switch='condition_pushdown_for_subquery=off' FOR SELECT * FROM t1
++WHERE (t1.a<2 OR t1.a>=4) AND
++(t1.a,t1.c) IN
++(
++SELECT t2.e,MAX(t2.g)
++FROM t2
++WHERE t2.e<5
++GROUP BY t2.e
++)
++;
++a b c d
++1 3 40 1
++4 2 24 4
++1 2 40 2
++SELECT * FROM t1
++WHERE (t1.a<2 OR t1.a>=4) AND
++(t1.a,t1.c) IN
++(
++SELECT t2.e,MAX(t2.g)
++FROM t2
++WHERE t2.e<5
++GROUP BY t2.e
++)
++;
++a b c d
++1 3 40 1
++4 2 24 4
++1 2 40 2
++EXPLAIN SELECT * FROM t1
++WHERE (t1.a<2 OR t1.a>=4) AND
++(t1.a,t1.c) IN
++(
++SELECT t2.e,MAX(t2.g)
++FROM t2
++WHERE t2.e<5
++GROUP BY t2.e
++)
++;
++id select_type table type possible_keys key key_len ref rows Extra
++1 PRIMARY t1 ALL NULL NULL NULL NULL 16 Using where
++1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 8 test.t1.a,test.t1.c 1
++2 MATERIALIZED t2 ALL NULL NULL NULL NULL 12 Using where; Using temporary
++EXPLAIN FORMAT=JSON SELECT * FROM t1
++WHERE (t1.a<2 OR t1.a>=4) AND
++(t1.a,t1.c) IN
++(
++SELECT t2.e,MAX(t2.g)
++FROM t2
++WHERE t2.e<5
++GROUP BY t2.e
++)
++;
++EXPLAIN
++{
++ "query_block": {
++ "select_id": 1,
++ "table": {
++ "table_name": "t1",
++ "access_type": "ALL",
++ "rows": 16,
++ "filtered": 100,
++ "attached_condition": "(t1.a < 2 or t1.a >= 4) and t1.a is not null and t1.c is not null"
++ },
++ "table": {
++ "table_name": "<subquery2>",
++ "access_type": "eq_ref",
++ "possible_keys": ["distinct_key"],
++ "key": "distinct_key",
++ "key_length": "8",
++ "used_key_parts": ["e", "MAX(t2.g)"],
++ "ref": ["test.t1.a", "test.t1.c"],
++ "rows": 1,
++ "filtered": 100,
++ "materialized": {
++ "unique": 1,
++ "query_block": {
++ "select_id": 2,
++ "temporary_table": {
++ "table": {
++ "table_name": "t2",
++ "access_type": "ALL",
++ "rows": 12,
++ "filtered": 100,
++ "attached_condition": "t2.e < 5 and (t2.e < 2 or t2.e >= 4)"
++ }
++ }
++ }
++ }
++ }
++ }
++}
++# extracted AND-OR formula : pushing into WHERE
++SET STATEMENT optimizer_switch='condition_pushdown_for_subquery=off' FOR SELECT * FROM t1
++WHERE ((t1.a<2 OR t1.a=5) AND t1.b>3) AND
++(t1.a,t1.b,t1.c) IN
++(
++SELECT t2.e,t2.f,MAX(t2.g)
++FROM t2
++WHERE t2.e<5
++GROUP BY t2.e,t2.f
++)
++;
++a b c d
++1 4 35 3
++SELECT * FROM t1
++WHERE ((t1.a<2 OR t1.a=5) AND t1.b>3) AND
++(t1.a,t1.b,t1.c) IN
++(
++SELECT t2.e,t2.f,MAX(t2.g)
++FROM t2
++WHERE t2.e<5
++GROUP BY t2.e,t2.f
++)
++;
++a b c d
++1 4 35 3
++EXPLAIN SELECT * FROM t1
++WHERE ((t1.a<2 OR t1.a=5) AND t1.b>3) AND
++(t1.a,t1.b,t1.c) IN
++(
++SELECT t2.e,t2.f,MAX(t2.g)
++FROM t2
++WHERE t2.e<5
++GROUP BY t2.e,t2.f
++)
++;
++id select_type table type possible_keys key key_len ref rows Extra
++1 PRIMARY t1 ALL NULL NULL NULL NULL 16 Using where
++1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 12 test.t1.a,test.t1.b,test.t1.c 1
++2 MATERIALIZED t2 ALL NULL NULL NULL NULL 12 Using where; Using temporary
++EXPLAIN FORMAT=JSON SELECT * FROM t1
++WHERE ((t1.a<2 OR t1.a=5) AND t1.b>3) AND
++(t1.a,t1.b,t1.c) IN
++(
++SELECT t2.e,t2.f,MAX(t2.g)
++FROM t2
++WHERE t2.e<5
++GROUP BY t2.e,t2.f
++)
++;
++EXPLAIN
++{
++ "query_block": {
++ "select_id": 1,
++ "table": {
++ "table_name": "t1",
++ "access_type": "ALL",
++ "rows": 16,
++ "filtered": 100,
++ "attached_condition": "(t1.a < 2 or t1.a = 5) and t1.b > 3 and t1.a is not null and t1.b is not null and t1.c is not null"
++ },
++ "table": {
++ "table_name": "<subquery2>",
++ "access_type": "eq_ref",
++ "possible_keys": ["distinct_key"],
++ "key": "distinct_key",
++ "key_length": "12",
++ "used_key_parts": ["e", "f", "MAX(t2.g)"],
++ "ref": ["test.t1.a", "test.t1.b", "test.t1.c"],
++ "rows": 1,
++ "filtered": 100,
++ "materialized": {
++ "unique": 1,
++ "query_block": {
++ "select_id": 2,
++ "temporary_table": {
++ "table": {
++ "table_name": "t2",
++ "access_type": "ALL",
++ "rows": 12,
++ "filtered": 100,
++ "attached_condition": "t2.e < 5 and (t2.e < 2 or t2.e = 5) and t2.f > 3"
++ }
++ }
++ }
++ }
++ }
++ }
++}
++# extracted AND-OR formula : pushing into WHERE
++SET STATEMENT optimizer_switch='condition_pushdown_for_subquery=off' FOR SELECT * FROM t1
++WHERE ((t1.a<2 OR t1.a=5) AND t1.b>3) AND
++(t1.a,t1.b,t1.c) IN
++(
++SELECT t2.e,t2.f,MAX(t2.g)
++FROM t2
++WHERE t2.e<5
++GROUP BY t2.e,t2.f
++)
++;
++a b c d
++1 4 35 3
++SELECT * FROM t1
++WHERE ((t1.a<2 OR t1.a=5) AND t1.b>3) AND
++(t1.a,t1.b,t1.c) IN
++(
++SELECT t2.e,t2.f,MAX(t2.g)
++FROM t2
++WHERE t2.e<5
++GROUP BY t2.e,t2.f
++)
++;
++a b c d
++1 4 35 3
++EXPLAIN SELECT * FROM t1
++WHERE ((t1.a<2 OR t1.a=5) AND t1.b>3) AND
++(t1.a,t1.b,t1.c) IN
++(
++SELECT t2.e,t2.f,MAX(t2.g)
++FROM t2
++WHERE t2.e<5
++GROUP BY t2.e,t2.f
++)
++;
++id select_type table type possible_keys key key_len ref rows Extra
++1 PRIMARY t1 ALL NULL NULL NULL NULL 16 Using where
++1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 12 test.t1.a,test.t1.b,test.t1.c 1
++2 MATERIALIZED t2 ALL NULL NULL NULL NULL 12 Using where; Using temporary
++EXPLAIN FORMAT=JSON SELECT * FROM t1
++WHERE ((t1.a<2 OR t1.a=5) AND t1.b>3) AND
++(t1.a,t1.b,t1.c) IN
++(
++SELECT t2.e,t2.f,MAX(t2.g)
++FROM t2
++WHERE t2.e<5
++GROUP BY t2.e,t2.f
++)
++;
++EXPLAIN
++{
++ "query_block": {
++ "select_id": 1,
++ "table": {
++ "table_name": "t1",
++ "access_type": "ALL",
++ "rows": 16,
++ "filtered": 100,
++ "attached_condition": "(t1.a < 2 or t1.a = 5) and t1.b > 3 and t1.a is not null and t1.b is not null and t1.c is not null"
++ },
++ "table": {
++ "table_name": "<subquery2>",
++ "access_type": "eq_ref",
++ "possible_keys": ["distinct_key"],
++ "key": "distinct_key",
++ "key_length": "12",
++ "used_key_parts": ["e", "f", "MAX(t2.g)"],
++ "ref": ["test.t1.a", "test.t1.b", "test.t1.c"],
++ "rows": 1,
++ "filtered": 100,
++ "materialized": {
++ "unique": 1,
++ "query_block": {
++ "select_id": 2,
++ "temporary_table": {
++ "table": {
++ "table_name": "t2",
++ "access_type": "ALL",
++ "rows": 12,
++ "filtered": 100,
++ "attached_condition": "t2.e < 5 and (t2.e < 2 or t2.e = 5) and t2.f > 3"
++ }
++ }
++ }
++ }
++ }
++ }
++}
++# conjunctive subformula : pushing into WHERE
++SET STATEMENT optimizer_switch='condition_pushdown_for_subquery=off' FOR SELECT * FROM t1
++WHERE ((t1.b<3 OR t1.d>2) AND t1.a<2) AND
++(t1.a,t1.b,t1.c) IN
++(
++SELECT t2.e,t2.f,MAX(t2.g)
++FROM t2
++WHERE t2.e<5
++GROUP BY t2.e
++)
++;
++a b c d
++1 2 40 2
++SELECT * FROM t1
++WHERE ((t1.b<3 OR t1.d>2) AND t1.a<2) AND
++(t1.a,t1.b,t1.c) IN
++(
++SELECT t2.e,t2.f,MAX(t2.g)
++FROM t2
++WHERE t2.e<5
++GROUP BY t2.e
++)
++;
++a b c d
++1 2 40 2
++EXPLAIN SELECT * FROM t1
++WHERE ((t1.b<3 OR t1.d>2) AND t1.a<2) AND
++(t1.a,t1.b,t1.c) IN
++(
++SELECT t2.e,t2.f,MAX(t2.g)
++FROM t2
++WHERE t2.e<5
++GROUP BY t2.e
++)
++;
++id select_type table type possible_keys key key_len ref rows Extra
++1 PRIMARY t1 ALL NULL NULL NULL NULL 16 Using where
++1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 12 test.t1.a,test.t1.b,test.t1.c 1
++2 MATERIALIZED t2 ALL NULL NULL NULL NULL 12 Using where; Using temporary
++EXPLAIN FORMAT=JSON SELECT * FROM t1
++WHERE ((t1.b<3 OR t1.d>2) AND t1.a<2) AND
++(t1.a,t1.b,t1.c) IN
++(
++SELECT t2.e,t2.f,MAX(t2.g)
++FROM t2
++WHERE t2.e<5
++GROUP BY t2.e
++)
++;
++EXPLAIN
++{
++ "query_block": {
++ "select_id": 1,
++ "table": {
++ "table_name": "t1",
++ "access_type": "ALL",
++ "rows": 16,
++ "filtered": 100,
++ "attached_condition": "(t1.b < 3 or t1.d > 2) and t1.a < 2 and t1.a is not null and t1.b is not null and t1.c is not null"
++ },
++ "table": {
++ "table_name": "<subquery2>",
++ "access_type": "eq_ref",
++ "possible_keys": ["distinct_key"],
++ "key": "distinct_key",
++ "key_length": "12",
++ "used_key_parts": ["e", "f", "MAX(t2.g)"],
++ "ref": ["test.t1.a", "test.t1.b", "test.t1.c"],
++ "rows": 1,
++ "filtered": 100,
++ "materialized": {
++ "unique": 1,
++ "query_block": {
++ "select_id": 2,
++ "temporary_table": {
++ "table": {
++ "table_name": "t2",
++ "access_type": "ALL",
++ "rows": 12,
++ "filtered": 100,
++ "attached_condition": "t2.e < 5 and t2.e < 2"
++ }
++ }
++ }
++ }
++ }
++ }
++}
++# using equalities : pushing into WHERE
++SET STATEMENT optimizer_switch='condition_pushdown_for_subquery=off' FOR SELECT * FROM t1
++WHERE t1.d=1 AND t1.a=t1.d AND
++(t1.a,t1.c) IN
++(
++SELECT t2.e,MAX(t2.g)
++FROM t2
++WHERE t2.e<5
++GROUP BY t2.e
++)
++;
++a b c d
++1 3 40 1
++SELECT * FROM t1
++WHERE t1.d=1 AND t1.a=t1.d AND
++(t1.a,t1.c) IN
++(
++SELECT t2.e,MAX(t2.g)
++FROM t2
++WHERE t2.e<5
++GROUP BY t2.e
++)
++;
++a b c d
++1 3 40 1
++EXPLAIN SELECT * FROM t1
++WHERE t1.d=1 AND t1.a=t1.d AND
++(t1.a,t1.c) IN
++(
++SELECT t2.e,MAX(t2.g)
++FROM t2
++WHERE t2.e<5
++GROUP BY t2.e
++)
++;
++id select_type table type possible_keys key key_len ref rows Extra
++1 PRIMARY t1 ALL NULL NULL NULL NULL 16 Using where
++1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 8 const,test.t1.c 1
++2 MATERIALIZED t2 ALL NULL NULL NULL NULL 12 Using where
++EXPLAIN FORMAT=JSON SELECT * FROM t1
++WHERE t1.d=1 AND t1.a=t1.d AND
++(t1.a,t1.c) IN
++(
++SELECT t2.e,MAX(t2.g)
++FROM t2
++WHERE t2.e<5
++GROUP BY t2.e
++)
++;
++EXPLAIN
++{
++ "query_block": {
++ "select_id": 1,
++ "table": {
++ "table_name": "t1",
++ "access_type": "ALL",
++ "rows": 16,
++ "filtered": 100,
++ "attached_condition": "t1.a = 1 and t1.d = 1 and t1.c is not null"
++ },
++ "table": {
++ "table_name": "<subquery2>",
++ "access_type": "eq_ref",
++ "possible_keys": ["distinct_key"],
++ "key": "distinct_key",
++ "key_length": "8",
++ "used_key_parts": ["e", "MAX(t2.g)"],
++ "ref": ["const", "test.t1.c"],
++ "rows": 1,
++ "filtered": 100,
++ "materialized": {
++ "unique": 1,
++ "query_block": {
++ "select_id": 2,
++ "table": {
++ "table_name": "t2",
++ "access_type": "ALL",
++ "rows": 12,
++ "filtered": 100,
++ "attached_condition": "t2.e = 1"
++ }
++ }
++ }
++ }
++ }
++}
++# using equality : pushing into WHERE
++SET STATEMENT optimizer_switch='condition_pushdown_for_subquery=off' FOR SELECT * FROM t1
++WHERE t1.d>1 AND t1.a=t1.d AND
++(t1.a,t1.c) IN
++(
++SELECT t2.e,MAX(t2.g)
++FROM t2
++WHERE t2.e<5
++GROUP BY t2.e
++)
++;
++a b c d
++4 2 24 4
++SELECT * FROM t1
++WHERE t1.d>1 AND t1.a=t1.d AND
++(t1.a,t1.c) IN
++(
++SELECT t2.e,MAX(t2.g)
++FROM t2
++WHERE t2.e<5
++GROUP BY t2.e
++)
++;
++a b c d
++4 2 24 4
++EXPLAIN SELECT * FROM t1
++WHERE t1.d>1 AND t1.a=t1.d AND
++(t1.a,t1.c) IN
++(
++SELECT t2.e,MAX(t2.g)
++FROM t2
++WHERE t2.e<5
++GROUP BY t2.e
++)
++;
++id select_type table type possible_keys key key_len ref rows Extra
++1 PRIMARY t1 ALL NULL NULL NULL NULL 16 Using where
++1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 8 test.t1.a,test.t1.c 1
++2 MATERIALIZED t2 ALL NULL NULL NULL NULL 12 Using where; Using temporary
++EXPLAIN FORMAT=JSON SELECT * FROM t1
++WHERE t1.d>1 AND t1.a=t1.d AND
++(t1.a,t1.c) IN
++(
++SELECT t2.e,MAX(t2.g)
++FROM t2
++WHERE t2.e<5
++GROUP BY t2.e
++)
++;
++EXPLAIN
++{
++ "query_block": {
++ "select_id": 1,
++ "table": {
++ "table_name": "t1",
++ "access_type": "ALL",
++ "rows": 16,
++ "filtered": 100,
++ "attached_condition": "t1.d = t1.a and t1.a > 1 and t1.a is not null and t1.c is not null"
++ },
++ "table": {
++ "table_name": "<subquery2>",
++ "access_type": "eq_ref",
++ "possible_keys": ["distinct_key"],
++ "key": "distinct_key",
++ "key_length": "8",
++ "used_key_parts": ["e", "MAX(t2.g)"],
++ "ref": ["test.t1.a", "test.t1.c"],
++ "rows": 1,
++ "filtered": 100,
++ "materialized": {
++ "unique": 1,
++ "query_block": {
++ "select_id": 2,
++ "temporary_table": {
++ "table": {
++ "table_name": "t2",
++ "access_type": "ALL",
++ "rows": 12,
++ "filtered": 100,
++ "attached_condition": "t2.e < 5 and t2.e > 1"
++ }
++ }
++ }
++ }
++ }
++ }
++}
++# using view IN subquery definition : pushing into WHERE
++SET STATEMENT optimizer_switch='condition_pushdown_for_subquery=off' FOR SELECT * FROM t1
++WHERE t1.a<3 AND
++(t1.a,t1.c) IN
++(
++SELECT v1_x,MAX(v1_y)
++FROM v1
++WHERE v1_x>1
++GROUP BY v1_x
++)
++;
++a b c d
++SELECT * FROM t1
++WHERE t1.a<3 AND
++(t1.a,t1.c) IN
++(
++SELECT v1_x,MAX(v1_y)
++FROM v1
++WHERE v1_x>1
++GROUP BY v1_x
++)
++;
++a b c d
++EXPLAIN SELECT * FROM t1
++WHERE t1.a<3 AND
++(t1.a,t1.c) IN
++(
++SELECT v1_x,MAX(v1_y)
++FROM v1
++WHERE v1_x>1
++GROUP BY v1_x
++)
++;
++id select_type table type possible_keys key key_len ref rows Extra
++1 PRIMARY t1 ALL NULL NULL NULL NULL 16 Using where
++1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 8 test.t1.a,test.t1.c 1
++2 MATERIALIZED t3 ALL NULL NULL NULL NULL 8 Using where; Using temporary
++EXPLAIN FORMAT=JSON SELECT * FROM t1
++WHERE t1.a<3 AND
++(t1.a,t1.c) IN
++(
++SELECT v1_x,MAX(v1_y)
++FROM v1
++WHERE v1_x>1
++GROUP BY v1_x
++)
++;
++EXPLAIN
++{
++ "query_block": {
++ "select_id": 1,
++ "table": {
++ "table_name": "t1",
++ "access_type": "ALL",
++ "rows": 16,
++ "filtered": 100,
++ "attached_condition": "t1.a < 3 and t1.a is not null and t1.c is not null"
++ },
++ "table": {
++ "table_name": "<subquery2>",
++ "access_type": "eq_ref",
++ "possible_keys": ["distinct_key"],
++ "key": "distinct_key",
++ "key_length": "8",
++ "used_key_parts": ["v1_x", "MAX(v1_y)"],
++ "ref": ["test.t1.a", "test.t1.c"],
++ "rows": 1,
++ "filtered": 100,
++ "materialized": {
++ "unique": 1,
++ "query_block": {
++ "select_id": 2,
++ "temporary_table": {
++ "table": {
++ "table_name": "t3",
++ "access_type": "ALL",
++ "rows": 8,
++ "filtered": 100,
++ "attached_condition": "t3.x > 1 and t3.x <= 3 and t3.x < 3"
++ }
++ }
++ }
++ }
++ }
++ }
++}
++# using equality : pushing into WHERE
++SET STATEMENT optimizer_switch='condition_pushdown_for_subquery=off' FOR SELECT * FROM t1,v1
++WHERE t1.a=v1_x AND v1_x<2 AND v1_y>30 AND
++(t1.a,t1.c) IN
++(
++SELECT t2.e,MAX(t2.g)
++FROM t2
++WHERE t2.e<5
++GROUP BY t2.e
++)
++;
++a b c d v1_x v1_y
++1 3 40 1 1 35
++1 2 40 2 1 35
++SELECT * FROM t1,v1
++WHERE t1.a=v1_x AND v1_x<2 AND v1_y>30 AND
++(t1.a,t1.c) IN
++(
++SELECT t2.e,MAX(t2.g)
++FROM t2
++WHERE t2.e<5
++GROUP BY t2.e
++)
++;
++a b c d v1_x v1_y
++1 3 40 1 1 35
++1 2 40 2 1 35
++EXPLAIN SELECT * FROM t1,v1
++WHERE t1.a=v1_x AND v1_x<2 AND v1_y>30 AND
++(t1.a,t1.c) IN
++(
++SELECT t2.e,MAX(t2.g)
++FROM t2
++WHERE t2.e<5
++GROUP BY t2.e
++)
++;
++id select_type table type possible_keys key key_len ref rows Extra
++1 PRIMARY t3 ALL NULL NULL NULL NULL 8 Using where
++1 PRIMARY t1 ALL NULL NULL NULL NULL 16 Using where; Using join buffer (flat, BNL join)
++1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 8 test.t3.x,test.t1.c 1
++2 MATERIALIZED t2 ALL NULL NULL NULL NULL 12 Using where; Using temporary
++EXPLAIN FORMAT=JSON SELECT * FROM t1,v1
++WHERE t1.a=v1_x AND v1_x<2 AND v1_y>30 AND
++(t1.a,t1.c) IN
++(
++SELECT t2.e,MAX(t2.g)
++FROM t2
++WHERE t2.e<5
++GROUP BY t2.e
++)
++;
++EXPLAIN
++{
++ "query_block": {
++ "select_id": 1,
++ "table": {
++ "table_name": "t3",
++ "access_type": "ALL",
++ "rows": 8,
++ "filtered": 100,
++ "attached_condition": "t3.x < 2 and t3.y > 30 and t3.x <= 3 and t3.x is not null"
++ },
++ "block-nl-join": {
++ "table": {
++ "table_name": "t1",
++ "access_type": "ALL",
++ "rows": 16,
++ "filtered": 100
++ },
++ "buffer_type": "flat",
++ "buffer_size": "256Kb",
++ "join_type": "BNL",
++ "attached_condition": "t1.a = t3.x and t1.c is not null"
++ },
++ "table": {
++ "table_name": "<subquery2>",
++ "access_type": "eq_ref",
++ "possible_keys": ["distinct_key"],
++ "key": "distinct_key",
++ "key_length": "8",
++ "used_key_parts": ["e", "MAX(t2.g)"],
++ "ref": ["test.t3.x", "test.t1.c"],
++ "rows": 1,
++ "filtered": 100,
++ "materialized": {
++ "unique": 1,
++ "query_block": {
++ "select_id": 2,
++ "temporary_table": {
++ "table": {
++ "table_name": "t2",
++ "access_type": "ALL",
++ "rows": 12,
++ "filtered": 100,
++ "attached_condition": "t2.e < 5 and t2.e <= 3"
++ }
++ }
++ }
++ }
++ }
++ }
++}
++# conjunctive subformula : pushing into WHERE
++# extracted OR formula : pushing into HAVING
++SET STATEMENT optimizer_switch='condition_pushdown_for_subquery=off' FOR SELECT * FROM t1
++WHERE ((t1.b<3 OR t1.b=4) AND t1.a<3) AND
++(t1.a,t1.b,t1.c) IN
++(
++SELECT t2.e,t2.f,MAX(t2.g)
++FROM t2
++WHERE t2.e<5
++GROUP BY t2.e
++)
++;
++a b c d
++1 2 40 2
++SELECT * FROM t1
++WHERE ((t1.b<3 OR t1.b=4) AND t1.a<3) AND
++(t1.a,t1.b,t1.c) IN
++(
++SELECT t2.e,t2.f,MAX(t2.g)
++FROM t2
++WHERE t2.e<5
++GROUP BY t2.e
++)
++;
++a b c d
++1 2 40 2
++EXPLAIN SELECT * FROM t1
++WHERE ((t1.b<3 OR t1.b=4) AND t1.a<3) AND
++(t1.a,t1.b,t1.c) IN
++(
++SELECT t2.e,t2.f,MAX(t2.g)
++FROM t2
++WHERE t2.e<5
++GROUP BY t2.e
++)
++;
++id select_type table type possible_keys key key_len ref rows Extra
++1 PRIMARY t1 ALL NULL NULL NULL NULL 16 Using where
++1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 12 test.t1.a,test.t1.b,test.t1.c 1
++2 MATERIALIZED t2 ALL NULL NULL NULL NULL 12 Using where; Using temporary
++EXPLAIN FORMAT=JSON SELECT * FROM t1
++WHERE ((t1.b<3 OR t1.b=4) AND t1.a<3) AND
++(t1.a,t1.b,t1.c) IN
++(
++SELECT t2.e,t2.f,MAX(t2.g)
++FROM t2
++WHERE t2.e<5
++GROUP BY t2.e
++)
++;
++EXPLAIN
++{
++ "query_block": {
++ "select_id": 1,
++ "table": {
++ "table_name": "t1",
++ "access_type": "ALL",
++ "rows": 16,
++ "filtered": 100,
++ "attached_condition": "(t1.b < 3 or t1.b = 4) and t1.a < 3 and t1.a is not null and t1.b is not null and t1.c is not null"
++ },
++ "table": {
++ "table_name": "<subquery2>",
++ "access_type": "eq_ref",
++ "possible_keys": ["distinct_key"],
++ "key": "distinct_key",
++ "key_length": "12",
++ "used_key_parts": ["e", "f", "MAX(t2.g)"],
++ "ref": ["test.t1.a", "test.t1.b", "test.t1.c"],
++ "rows": 1,
++ "filtered": 100,
++ "materialized": {
++ "unique": 1,
++ "query_block": {
++ "select_id": 2,
++ "having_condition": "t2.f < 3 or t2.f = 4",
++ "temporary_table": {
++ "table": {
++ "table_name": "t2",
++ "access_type": "ALL",
++ "rows": 12,
++ "filtered": 100,
++ "attached_condition": "t2.e < 5 and t2.e < 3"
++ }
++ }
++ }
++ }
++ }
++ }
++}
++# conjunctive subformula using addition : pushing into HAVING
++SET STATEMENT optimizer_switch='condition_pushdown_for_subquery=off' FOR SELECT * FROM t1
++WHERE (t1.a+t1.c>41) AND
++(t1.a,t1.c) IN
++(
++SELECT t2.e,MAX(t2.g)
++FROM t2
++WHERE t2.e<5
++GROUP BY t2.e
++)
++;
++a b c d
++2 3 70 3
++SELECT * FROM t1
++WHERE (t1.a+t1.c>41) AND
++(t1.a,t1.c) IN
++(
++SELECT t2.e,MAX(t2.g)
++FROM t2
++WHERE t2.e<5
++GROUP BY t2.e
++)
++;
++a b c d
++2 3 70 3
++EXPLAIN SELECT * FROM t1
++WHERE (t1.a+t1.c>41) AND
++(t1.a,t1.c) IN
++(
++SELECT t2.e,MAX(t2.g)
++FROM t2
++WHERE t2.e<5
++GROUP BY t2.e
++)
++;
++id select_type table type possible_keys key key_len ref rows Extra
++1 PRIMARY t1 ALL NULL NULL NULL NULL 16 Using where
++1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 8 test.t1.a,test.t1.c 1
++2 MATERIALIZED t2 ALL NULL NULL NULL NULL 12 Using where; Using temporary
++EXPLAIN FORMAT=JSON SELECT * FROM t1
++WHERE (t1.a+t1.c>41) AND
++(t1.a,t1.c) IN
++(
++SELECT t2.e,MAX(t2.g)
++FROM t2
++WHERE t2.e<5
++GROUP BY t2.e
++)
++;
++EXPLAIN
++{
++ "query_block": {
++ "select_id": 1,
++ "table": {
++ "table_name": "t1",
++ "access_type": "ALL",
++ "rows": 16,
++ "filtered": 100,
++ "attached_condition": "t1.a + t1.c > 41 and t1.a is not null and t1.c is not null"
++ },
++ "table": {
++ "table_name": "<subquery2>",
++ "access_type": "eq_ref",
++ "possible_keys": ["distinct_key"],
++ "key": "distinct_key",
++ "key_length": "8",
++ "used_key_parts": ["e", "MAX(t2.g)"],
++ "ref": ["test.t1.a", "test.t1.c"],
++ "rows": 1,
++ "filtered": 100,
++ "materialized": {
++ "unique": 1,
++ "query_block": {
++ "select_id": 2,
++ "having_condition": "t2.e + `MAX(t2.g)` > 41",
++ "temporary_table": {
++ "table": {
++ "table_name": "t2",
++ "access_type": "ALL",
++ "rows": 12,
++ "filtered": 100,
++ "attached_condition": "t2.e < 5"
++ }
++ }
++ }
++ }
++ }
++ }
++}
++# conjunctive subformula using substitution : pushing into HAVING
++SET STATEMENT optimizer_switch='condition_pushdown_for_subquery=off' FOR SELECT * FROM t1
++WHERE (t1.c-t1.a<35) AND
++(t1.a,t1.c) IN
++(
++SELECT t2.e,MAX(t2.g)
++FROM t2
++WHERE t2.e<5
++GROUP BY t2.e
++)
++;
++a b c d
++4 2 24 4
++3 2 23 1
++SELECT * FROM t1
++WHERE (t1.c-t1.a<35) AND
++(t1.a,t1.c) IN
++(
++SELECT t2.e,MAX(t2.g)
++FROM t2
++WHERE t2.e<5
++GROUP BY t2.e
++)
++;
++a b c d
++4 2 24 4
++3 2 23 1
++EXPLAIN SELECT * FROM t1
++WHERE (t1.c-t1.a<35) AND
++(t1.a,t1.c) IN
++(
++SELECT t2.e,MAX(t2.g)
++FROM t2
++WHERE t2.e<5
++GROUP BY t2.e
++)
++;
++id select_type table type possible_keys key key_len ref rows Extra
++1 PRIMARY t1 ALL NULL NULL NULL NULL 16 Using where
++1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 8 test.t1.a,test.t1.c 1
++2 MATERIALIZED t2 ALL NULL NULL NULL NULL 12 Using where; Using temporary
++EXPLAIN FORMAT=JSON SELECT * FROM t1
++WHERE (t1.c-t1.a<35) AND
++(t1.a,t1.c) IN
++(
++SELECT t2.e,MAX(t2.g)
++FROM t2
++WHERE t2.e<5
++GROUP BY t2.e
++)
++;
++EXPLAIN
++{
++ "query_block": {
++ "select_id": 1,
++ "table": {
++ "table_name": "t1",
++ "access_type": "ALL",
++ "rows": 16,
++ "filtered": 100,
++ "attached_condition": "t1.c - t1.a < 35 and t1.a is not null and t1.c is not null"
++ },
++ "table": {
++ "table_name": "<subquery2>",
++ "access_type": "eq_ref",
++ "possible_keys": ["distinct_key"],
++ "key": "distinct_key",
++ "key_length": "8",
++ "used_key_parts": ["e", "MAX(t2.g)"],
++ "ref": ["test.t1.a", "test.t1.c"],
++ "rows": 1,
++ "filtered": 100,
++ "materialized": {
++ "unique": 1,
++ "query_block": {
++ "select_id": 2,
++ "having_condition": "`MAX(t2.g)` - t2.e < 35",
++ "temporary_table": {
++ "table": {
++ "table_name": "t2",
++ "access_type": "ALL",
++ "rows": 12,
++ "filtered": 100,
++ "attached_condition": "t2.e < 5"
++ }
++ }
++ }
++ }
++ }
++ }
++}
++# conjunctive subformula using multiplication : pushing into HAVING
++SET STATEMENT optimizer_switch='condition_pushdown_for_subquery=off' FOR SELECT * FROM t1
++WHERE (t1.c*t1.a>100) AND
++(t1.a,t1.c) IN
++(
++SELECT t2.e,MAX(t2.g)
++FROM t2
++WHERE t2.e<5
++GROUP BY t2.e
++)
++;
++a b c d
++2 3 70 3
++SELECT * FROM t1
++WHERE (t1.c*t1.a>100) AND
++(t1.a,t1.c) IN
++(
++SELECT t2.e,MAX(t2.g)
++FROM t2
++WHERE t2.e<5
++GROUP BY t2.e
++)
++;
++a b c d
++2 3 70 3
++EXPLAIN SELECT * FROM t1
++WHERE (t1.c*t1.a>100) AND
++(t1.a,t1.c) IN
++(
++SELECT t2.e,MAX(t2.g)
++FROM t2
++WHERE t2.e<5
++GROUP BY t2.e
++)
++;
++id select_type table type possible_keys key key_len ref rows Extra
++1 PRIMARY t1 ALL NULL NULL NULL NULL 16 Using where
++1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 8 test.t1.a,test.t1.c 1
++2 MATERIALIZED t2 ALL NULL NULL NULL NULL 12 Using where; Using temporary
++EXPLAIN FORMAT=JSON SELECT * FROM t1
++WHERE (t1.c*t1.a>100) AND
++(t1.a,t1.c) IN
++(
++SELECT t2.e,MAX(t2.g)
++FROM t2
++WHERE t2.e<5
++GROUP BY t2.e
++)
++;
++EXPLAIN
++{
++ "query_block": {
++ "select_id": 1,
++ "table": {
++ "table_name": "t1",
++ "access_type": "ALL",
++ "rows": 16,
++ "filtered": 100,
++ "attached_condition": "t1.c * t1.a > 100 and t1.a is not null and t1.c is not null"
++ },
++ "table": {
++ "table_name": "<subquery2>",
++ "access_type": "eq_ref",
++ "possible_keys": ["distinct_key"],
++ "key": "distinct_key",
++ "key_length": "8",
++ "used_key_parts": ["e", "MAX(t2.g)"],
++ "ref": ["test.t1.a", "test.t1.c"],
++ "rows": 1,
++ "filtered": 100,
++ "materialized": {
++ "unique": 1,
++ "query_block": {
++ "select_id": 2,
++ "having_condition": "`MAX(t2.g)` * t2.e > 100",
++ "temporary_table": {
++ "table": {
++ "table_name": "t2",
++ "access_type": "ALL",
++ "rows": 12,
++ "filtered": 100,
++ "attached_condition": "t2.e < 5"
++ }
++ }
++ }
++ }
++ }
++ }
++}
++# conjunctive subformula using division : pushing into HAVING
++SET STATEMENT optimizer_switch='condition_pushdown_for_subquery=off' FOR SELECT * FROM t1
++WHERE (t1.c/t1.a>30) AND
++(t1.a,t1.c) IN
++(
++SELECT t2.e,MAX(t2.g)
++FROM t2
++WHERE t2.e<5
++GROUP BY t2.e
++)
++;
++a b c d
++1 3 40 1
++1 2 40 2
++2 3 70 3
++SELECT * FROM t1
++WHERE (t1.c/t1.a>30) AND
++(t1.a,t1.c) IN
++(
++SELECT t2.e,MAX(t2.g)
++FROM t2
++WHERE t2.e<5
++GROUP BY t2.e
++)
++;
++a b c d
++1 3 40 1
++1 2 40 2
++2 3 70 3
++EXPLAIN SELECT * FROM t1
++WHERE (t1.c/t1.a>30) AND
++(t1.a,t1.c) IN
++(
++SELECT t2.e,MAX(t2.g)
++FROM t2
++WHERE t2.e<5
++GROUP BY t2.e
++)
++;
++id select_type table type possible_keys key key_len ref rows Extra
++1 PRIMARY t1 ALL NULL NULL NULL NULL 16 Using where
++1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 8 test.t1.a,test.t1.c 1
++2 MATERIALIZED t2 ALL NULL NULL NULL NULL 12 Using where; Using temporary
++EXPLAIN FORMAT=JSON SELECT * FROM t1
++WHERE (t1.c/t1.a>30) AND
++(t1.a,t1.c) IN
++(
++SELECT t2.e,MAX(t2.g)
++FROM t2
++WHERE t2.e<5
++GROUP BY t2.e
++)
++;
++EXPLAIN
++{
++ "query_block": {
++ "select_id": 1,
++ "table": {
++ "table_name": "t1",
++ "access_type": "ALL",
++ "rows": 16,
++ "filtered": 100,
++ "attached_condition": "t1.c / t1.a > 30 and t1.a is not null and t1.c is not null"
++ },
++ "table": {
++ "table_name": "<subquery2>",
++ "access_type": "eq_ref",
++ "possible_keys": ["distinct_key"],
++ "key": "distinct_key",
++ "key_length": "8",
++ "used_key_parts": ["e", "MAX(t2.g)"],
++ "ref": ["test.t1.a", "test.t1.c"],
++ "rows": 1,
++ "filtered": 100,
++ "materialized": {
++ "unique": 1,
++ "query_block": {
++ "select_id": 2,
++ "having_condition": "`MAX(t2.g)` / t2.e > 30",
++ "temporary_table": {
++ "table": {
++ "table_name": "t2",
++ "access_type": "ALL",
++ "rows": 12,
++ "filtered": 100,
++ "attached_condition": "t2.e < 5"
++ }
++ }
++ }
++ }
++ }
++ }
++}
++# conjunctive subformula using BETWEEN : pushing into HAVING
++SET STATEMENT optimizer_switch='condition_pushdown_for_subquery=off' FOR SELECT * FROM t1
++WHERE (t1.c BETWEEN 50 AND 100) AND
++(t1.a,t1.c) IN
++(
++SELECT t2.e,MAX(t2.g)
++FROM t2
++WHERE t2.e<5
++GROUP BY t2.e
++)
++;
++a b c d
++2 3 70 3
++SELECT * FROM t1
++WHERE (t1.c BETWEEN 50 AND 100) AND
++(t1.a,t1.c) IN
++(
++SELECT t2.e,MAX(t2.g)
++FROM t2
++WHERE t2.e<5
++GROUP BY t2.e
++)
++;
++a b c d
++2 3 70 3
++EXPLAIN SELECT * FROM t1
++WHERE (t1.c BETWEEN 50 AND 100) AND
++(t1.a,t1.c) IN
++(
++SELECT t2.e,MAX(t2.g)
++FROM t2
++WHERE t2.e<5
++GROUP BY t2.e
++)
++;
++id select_type table type possible_keys key key_len ref rows Extra
++1 PRIMARY t1 ALL NULL NULL NULL NULL 16 Using where
++1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 8 test.t1.a,test.t1.c 1
++2 MATERIALIZED t2 ALL NULL NULL NULL NULL 12 Using where; Using temporary
++EXPLAIN FORMAT=JSON SELECT * FROM t1
++WHERE (t1.c BETWEEN 50 AND 100) AND
++(t1.a,t1.c) IN
++(
++SELECT t2.e,MAX(t2.g)
++FROM t2
++WHERE t2.e<5
++GROUP BY t2.e
++)
++;
++EXPLAIN
++{
++ "query_block": {
++ "select_id": 1,
++ "table": {
++ "table_name": "t1",
++ "access_type": "ALL",
++ "rows": 16,
++ "filtered": 100,
++ "attached_condition": "t1.c between 50 and 100 and t1.a is not null and t1.c is not null"
++ },
++ "table": {
++ "table_name": "<subquery2>",
++ "access_type": "eq_ref",
++ "possible_keys": ["distinct_key"],
++ "key": "distinct_key",
++ "key_length": "8",
++ "used_key_parts": ["e", "MAX(t2.g)"],
++ "ref": ["test.t1.a", "test.t1.c"],
++ "rows": 1,
++ "filtered": 100,
++ "materialized": {
++ "unique": 1,
++ "query_block": {
++ "select_id": 2,
++ "having_condition": "`MAX(t2.g)` between 50 and 100",
++ "temporary_table": {
++ "table": {
++ "table_name": "t2",
++ "access_type": "ALL",
++ "rows": 12,
++ "filtered": 100,
++ "attached_condition": "t2.e < 5"
++ }
++ }
++ }
++ }
++ }
++ }
++}
++# conjunctive subformula using addition : pushing into WHERE
++SET STATEMENT optimizer_switch='condition_pushdown_for_subquery=off' FOR SELECT * FROM t1
++WHERE (t1.a+t1.b > 5) AND
++(t1.a,t1.b,t1.c) IN
++(
++SELECT t2.e,t2.f,MAX(t2.g)
++FROM t2
++WHERE t2.e<5
++GROUP BY t2.e,t2.f
++)
++;
++a b c d
++4 2 24 4
++SELECT * FROM t1
++WHERE (t1.a+t1.b > 5) AND
++(t1.a,t1.b,t1.c) IN
++(
++SELECT t2.e,t2.f,MAX(t2.g)
++FROM t2
++WHERE t2.e<5
++GROUP BY t2.e,t2.f
++)
++;
++a b c d
++4 2 24 4
++EXPLAIN SELECT * FROM t1
++WHERE (t1.a+t1.b > 5) AND
++(t1.a,t1.b,t1.c) IN
++(
++SELECT t2.e,t2.f,MAX(t2.g)
++FROM t2
++WHERE t2.e<5
++GROUP BY t2.e,t2.f
++)
++;
++id select_type table type possible_keys key key_len ref rows Extra
++1 PRIMARY t1 ALL NULL NULL NULL NULL 16 Using where
++1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 12 test.t1.a,test.t1.b,test.t1.c 1
++2 MATERIALIZED t2 ALL NULL NULL NULL NULL 12 Using where; Using temporary
++EXPLAIN FORMAT=JSON SELECT * FROM t1
++WHERE (t1.a+t1.b > 5) AND
++(t1.a,t1.b,t1.c) IN
++(
++SELECT t2.e,t2.f,MAX(t2.g)
++FROM t2
++WHERE t2.e<5
++GROUP BY t2.e,t2.f
++)
++;
++EXPLAIN
++{
++ "query_block": {
++ "select_id": 1,
++ "table": {
++ "table_name": "t1",
++ "access_type": "ALL",
++ "rows": 16,
++ "filtered": 100,
++ "attached_condition": "t1.a + t1.b > 5 and t1.a is not null and t1.b is not null and t1.c is not null"
++ },
++ "table": {
++ "table_name": "<subquery2>",
++ "access_type": "eq_ref",
++ "possible_keys": ["distinct_key"],
++ "key": "distinct_key",
++ "key_length": "12",
++ "used_key_parts": ["e", "f", "MAX(t2.g)"],
++ "ref": ["test.t1.a", "test.t1.b", "test.t1.c"],
++ "rows": 1,
++ "filtered": 100,
++ "materialized": {
++ "unique": 1,
++ "query_block": {
++ "select_id": 2,
++ "temporary_table": {
++ "table": {
++ "table_name": "t2",
++ "access_type": "ALL",
++ "rows": 12,
++ "filtered": 100,
++ "attached_condition": "t2.e < 5 and t2.e + t2.f > 5"
++ }
++ }
++ }
++ }
++ }
++ }
++}
++# conjunctive subformula using substitution : pushing into WHERE
++SET STATEMENT optimizer_switch='condition_pushdown_for_subquery=off' FOR SELECT * FROM t1
++WHERE (t1.a-t1.b > 0) AND
++(t1.a,t1.b,t1.c) IN
++(
++SELECT t2.e,t2.f,MAX(t2.g)
++FROM t2
++WHERE t2.e<5
++GROUP BY t2.e,t2.f
++)
++;
++a b c d
++4 2 24 4
++SELECT * FROM t1
++WHERE (t1.a-t1.b > 0) AND
++(t1.a,t1.b,t1.c) IN
++(
++SELECT t2.e,t2.f,MAX(t2.g)
++FROM t2
++WHERE t2.e<5
++GROUP BY t2.e,t2.f
++)
++;
++a b c d
++4 2 24 4
++EXPLAIN SELECT * FROM t1
++WHERE (t1.a-t1.b > 0) AND
++(t1.a,t1.b,t1.c) IN
++(
++SELECT t2.e,t2.f,MAX(t2.g)
++FROM t2
++WHERE t2.e<5
++GROUP BY t2.e,t2.f
++)
++;
++id select_type table type possible_keys key key_len ref rows Extra
++1 PRIMARY t1 ALL NULL NULL NULL NULL 16 Using where
++1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 12 test.t1.a,test.t1.b,test.t1.c 1
++2 MATERIALIZED t2 ALL NULL NULL NULL NULL 12 Using where; Using temporary
++EXPLAIN FORMAT=JSON SELECT * FROM t1
++WHERE (t1.a-t1.b > 0) AND
++(t1.a,t1.b,t1.c) IN
++(
++SELECT t2.e,t2.f,MAX(t2.g)
++FROM t2
++WHERE t2.e<5
++GROUP BY t2.e,t2.f
++)
++;
++EXPLAIN
++{
++ "query_block": {
++ "select_id": 1,
++ "table": {
++ "table_name": "t1",
++ "access_type": "ALL",
++ "rows": 16,
++ "filtered": 100,
++ "attached_condition": "t1.a - t1.b > 0 and t1.a is not null and t1.b is not null and t1.c is not null"
++ },
++ "table": {
++ "table_name": "<subquery2>",
++ "access_type": "eq_ref",
++ "possible_keys": ["distinct_key"],
++ "key": "distinct_key",
++ "key_length": "12",
++ "used_key_parts": ["e", "f", "MAX(t2.g)"],
++ "ref": ["test.t1.a", "test.t1.b", "test.t1.c"],
++ "rows": 1,
++ "filtered": 100,
++ "materialized": {
++ "unique": 1,
++ "query_block": {
++ "select_id": 2,
++ "temporary_table": {
++ "table": {
++ "table_name": "t2",
++ "access_type": "ALL",
++ "rows": 12,
++ "filtered": 100,
++ "attached_condition": "t2.e < 5 and t2.e - t2.f > 0"
++ }
++ }
++ }
++ }
++ }
++ }
++}
++# conjunctive subformula using multiplication : pushing into WHERE
++SET STATEMENT optimizer_switch='condition_pushdown_for_subquery=off' FOR SELECT * FROM t1
++WHERE (t1.a*t1.b > 6) AND
++(t1.a,t1.b,t1.c) IN
++(
++SELECT t2.e,t2.f,MAX(t2.g)
++FROM t2
++WHERE t2.e<5
++GROUP BY t2.e,t2.f
++)
++;
++a b c d
++4 2 24 4
++SELECT * FROM t1
++WHERE (t1.a*t1.b > 6) AND
++(t1.a,t1.b,t1.c) IN
++(
++SELECT t2.e,t2.f,MAX(t2.g)
++FROM t2
++WHERE t2.e<5
++GROUP BY t2.e,t2.f
++)
++;
++a b c d
++4 2 24 4
++EXPLAIN SELECT * FROM t1
++WHERE (t1.a*t1.b > 6) AND
++(t1.a,t1.b,t1.c) IN
++(
++SELECT t2.e,t2.f,MAX(t2.g)
++FROM t2
++WHERE t2.e<5
++GROUP BY t2.e,t2.f
++)
++;
++id select_type table type possible_keys key key_len ref rows Extra
++1 PRIMARY t1 ALL NULL NULL NULL NULL 16 Using where
++1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 12 test.t1.a,test.t1.b,test.t1.c 1
++2 MATERIALIZED t2 ALL NULL NULL NULL NULL 12 Using where; Using temporary
++EXPLAIN FORMAT=JSON SELECT * FROM t1
++WHERE (t1.a*t1.b > 6) AND
++(t1.a,t1.b,t1.c) IN
++(
++SELECT t2.e,t2.f,MAX(t2.g)
++FROM t2
++WHERE t2.e<5
++GROUP BY t2.e,t2.f
++)
++;
++EXPLAIN
++{
++ "query_block": {
++ "select_id": 1,
++ "table": {
++ "table_name": "t1",
++ "access_type": "ALL",
++ "rows": 16,
++ "filtered": 100,
++ "attached_condition": "t1.a * t1.b > 6 and t1.a is not null and t1.b is not null and t1.c is not null"
++ },
++ "table": {
++ "table_name": "<subquery2>",
++ "access_type": "eq_ref",
++ "possible_keys": ["distinct_key"],
++ "key": "distinct_key",
++ "key_length": "12",
++ "used_key_parts": ["e", "f", "MAX(t2.g)"],
++ "ref": ["test.t1.a", "test.t1.b", "test.t1.c"],
++ "rows": 1,
++ "filtered": 100,
++ "materialized": {
++ "unique": 1,
++ "query_block": {
++ "select_id": 2,
++ "temporary_table": {
++ "table": {
++ "table_name": "t2",
++ "access_type": "ALL",
++ "rows": 12,
++ "filtered": 100,
++ "attached_condition": "t2.e < 5 and t2.e * t2.f > 6"
++ }
++ }
++ }
++ }
++ }
++ }
++}
++# conjunctive subformula using division : pushing into WHERE
++SET STATEMENT optimizer_switch='condition_pushdown_for_subquery=off' FOR SELECT * FROM t1
++WHERE (t1.b/t1.a > 2) AND
++(t1.a,t1.b,t1.c) IN
++(
++SELECT t2.e,t2.f,MAX(t2.g)
++FROM t2
++WHERE t2.e<5
++GROUP BY t2.e,t2.f
++)
++;
++a b c d
++1 3 40 1
++1 4 35 3
++SELECT * FROM t1
++WHERE (t1.b/t1.a > 2) AND
++(t1.a,t1.b,t1.c) IN
++(
++SELECT t2.e,t2.f,MAX(t2.g)
++FROM t2
++WHERE t2.e<5
++GROUP BY t2.e,t2.f
++)
++;
++a b c d
++1 3 40 1
++1 4 35 3
++EXPLAIN SELECT * FROM t1
++WHERE (t1.b/t1.a > 2) AND
++(t1.a,t1.b,t1.c) IN
++(
++SELECT t2.e,t2.f,MAX(t2.g)
++FROM t2
++WHERE t2.e<5
++GROUP BY t2.e,t2.f
++)
++;
++id select_type table type possible_keys key key_len ref rows Extra
++1 PRIMARY t1 ALL NULL NULL NULL NULL 16 Using where
++1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 12 test.t1.a,test.t1.b,test.t1.c 1
++2 MATERIALIZED t2 ALL NULL NULL NULL NULL 12 Using where; Using temporary
++EXPLAIN FORMAT=JSON SELECT * FROM t1
++WHERE (t1.b/t1.a > 2) AND
++(t1.a,t1.b,t1.c) IN
++(
++SELECT t2.e,t2.f,MAX(t2.g)
++FROM t2
++WHERE t2.e<5
++GROUP BY t2.e,t2.f
++)
++;
++EXPLAIN
++{
++ "query_block": {
++ "select_id": 1,
++ "table": {
++ "table_name": "t1",
++ "access_type": "ALL",
++ "rows": 16,
++ "filtered": 100,
++ "attached_condition": "t1.b / t1.a > 2 and t1.a is not null and t1.b is not null and t1.c is not null"
++ },
++ "table": {
++ "table_name": "<subquery2>",
++ "access_type": "eq_ref",
++ "possible_keys": ["distinct_key"],
++ "key": "distinct_key",
++ "key_length": "12",
++ "used_key_parts": ["e", "f", "MAX(t2.g)"],
++ "ref": ["test.t1.a", "test.t1.b", "test.t1.c"],
++ "rows": 1,
++ "filtered": 100,
++ "materialized": {
++ "unique": 1,
++ "query_block": {
++ "select_id": 2,
++ "temporary_table": {
++ "table": {
++ "table_name": "t2",
++ "access_type": "ALL",
++ "rows": 12,
++ "filtered": 100,
++ "attached_condition": "t2.e < 5 and t2.f / t2.e > 2"
++ }
++ }
++ }
++ }
++ }
++ }
++}
++# conjunctive subformula using BETWEEN : pushing into WHERE
++SET STATEMENT optimizer_switch='condition_pushdown_for_subquery=off' FOR SELECT * FROM t1
++WHERE (t1.a BETWEEN 1 AND 3) AND
++(t1.a,t1.c) IN
++(
++SELECT t2.e,MAX(t2.g)
++FROM t2
++WHERE t2.e<5
++GROUP BY t2.e
++)
++;
++a b c d
++1 3 40 1
++3 2 23 1
++1 2 40 2
++2 3 70 3
++SELECT * FROM t1
++WHERE (t1.a BETWEEN 1 AND 3) AND
++(t1.a,t1.c) IN
++(
++SELECT t2.e,MAX(t2.g)
++FROM t2
++WHERE t2.e<5
++GROUP BY t2.e
++)
++;
++a b c d
++1 3 40 1
++3 2 23 1
++1 2 40 2
++2 3 70 3
++EXPLAIN SELECT * FROM t1
++WHERE (t1.a BETWEEN 1 AND 3) AND
++(t1.a,t1.c) IN
++(
++SELECT t2.e,MAX(t2.g)
++FROM t2
++WHERE t2.e<5
++GROUP BY t2.e
++)
++;
++id select_type table type possible_keys key key_len ref rows Extra
++1 PRIMARY t1 ALL NULL NULL NULL NULL 16 Using where
++1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 8 test.t1.a,test.t1.c 1
++2 MATERIALIZED t2 ALL NULL NULL NULL NULL 12 Using where; Using temporary
++EXPLAIN FORMAT=JSON SELECT * FROM t1
++WHERE (t1.a BETWEEN 1 AND 3) AND
++(t1.a,t1.c) IN
++(
++SELECT t2.e,MAX(t2.g)
++FROM t2
++WHERE t2.e<5
++GROUP BY t2.e
++)
++;
++EXPLAIN
++{
++ "query_block": {
++ "select_id": 1,
++ "table": {
++ "table_name": "t1",
++ "access_type": "ALL",
++ "rows": 16,
++ "filtered": 100,
++ "attached_condition": "t1.a between 1 and 3 and t1.a is not null and t1.c is not null"
++ },
++ "table": {
++ "table_name": "<subquery2>",
++ "access_type": "eq_ref",
++ "possible_keys": ["distinct_key"],
++ "key": "distinct_key",
++ "key_length": "8",
++ "used_key_parts": ["e", "MAX(t2.g)"],
++ "ref": ["test.t1.a", "test.t1.c"],
++ "rows": 1,
++ "filtered": 100,
++ "materialized": {
++ "unique": 1,
++ "query_block": {
++ "select_id": 2,
++ "temporary_table": {
++ "table": {
++ "table_name": "t2",
++ "access_type": "ALL",
++ "rows": 12,
++ "filtered": 100,
++ "attached_condition": "t2.e < 5 and t2.e between 1 and 3"
++ }
++ }
++ }
++ }
++ }
++ }
++}
++# conjunctive subformula : pushing into HAVING of the IN subquery
++# conjunctive subformula : pushing into WHERE of the view from the IN subquery
++SET STATEMENT optimizer_switch='condition_pushdown_for_subquery=off' FOR SELECT * FROM t1
++WHERE t1.c>3 AND
++(t1.a,t1.b,t1.c) IN
++(
++SELECT v2.e,MAX(v2.f),v2.max_g
++FROM v2
++WHERE v2.e<5
++GROUP BY v2.e
++)
++;
++a b c d
++1 2 40 2
++2 3 70 3
++SELECT * FROM t1
++WHERE t1.c>3 AND
++(t1.a,t1.b,t1.c) IN
++(
++SELECT v2.e,MAX(v2.f),v2.max_g
++FROM v2
++WHERE v2.e<5
++GROUP BY v2.e
++)
++;
++a b c d
++1 2 40 2
++2 3 70 3
++EXPLAIN SELECT * FROM t1
++WHERE t1.c>3 AND
++(t1.a,t1.b,t1.c) IN
++(
++SELECT v2.e,MAX(v2.f),v2.max_g
++FROM v2
++WHERE v2.e<5
++GROUP BY v2.e
++)
++;
++id select_type table type possible_keys key key_len ref rows Extra
++1 PRIMARY t1 ALL NULL NULL NULL NULL 16 Using where
++1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 12 test.t1.a,test.t1.b,test.t1.c 1
++2 MATERIALIZED <derived3> ALL NULL NULL NULL NULL 12 Using where; Using temporary
++3 DERIVED t2 ALL NULL NULL NULL NULL 12 Using temporary; Using filesort
++EXPLAIN FORMAT=JSON SELECT * FROM t1
++WHERE t1.c>3 AND
++(t1.a,t1.b,t1.c) IN
++(
++SELECT v2.e,MAX(v2.f),v2.max_g
++FROM v2
++WHERE v2.e<5
++GROUP BY v2.e
++)
++;
++EXPLAIN
++{
++ "query_block": {
++ "select_id": 1,
++ "table": {
++ "table_name": "t1",
++ "access_type": "ALL",
++ "rows": 16,
++ "filtered": 100,
++ "attached_condition": "t1.c > 3 and t1.a is not null and t1.b is not null and t1.c is not null"
++ },
++ "table": {
++ "table_name": "<subquery2>",
++ "access_type": "eq_ref",
++ "possible_keys": ["distinct_key"],
++ "key": "distinct_key",
++ "key_length": "12",
++ "used_key_parts": ["e", "MAX(v2.f)", "max_g"],
++ "ref": ["test.t1.a", "test.t1.b", "test.t1.c"],
++ "rows": 1,
++ "filtered": 100,
++ "materialized": {
++ "unique": 1,
++ "query_block": {
++ "select_id": 2,
++ "having_condition": "v2.max_g > 3",
++ "temporary_table": {
++ "table": {
++ "table_name": "<derived3>",
++ "access_type": "ALL",
++ "rows": 12,
++ "filtered": 100,
++ "attached_condition": "v2.e < 5",
++ "materialized": {
++ "query_block": {
++ "select_id": 3,
++ "having_condition": "max_g > 25",
++ "filesort": {
++ "sort_key": "t2.e",
++ "temporary_table": {
++ "table": {
++ "table_name": "t2",
++ "access_type": "ALL",
++ "rows": 12,
++ "filtered": 100
++ }
++ }
++ }
++ }
++ }
++ }
++ }
++ }
++ }
++ }
++ }
++}
++# conjunctive subformula : pushing into WHERE of the IN subquery
++# conjunctive subformula : pushing into WHERE of the view
++# from the IN subquery
++SET STATEMENT optimizer_switch='condition_pushdown_for_subquery=off' FOR SELECT * FROM t1
++WHERE t1.a>1 AND
++(t1.a,t1.b,t1.c) IN
++(
++SELECT v2.e,MAX(v2.f),v2.max_g
++FROM v2
++WHERE v2.e<5
++GROUP BY v2.e
++)
++;
++a b c d
++2 3 70 3
++SELECT * FROM t1
++WHERE t1.a>1 AND
++(t1.a,t1.b,t1.c) IN
++(
++SELECT v2.e,MAX(v2.f),v2.max_g
++FROM v2
++WHERE v2.e<5
++GROUP BY v2.e
++)
++;
++a b c d
++2 3 70 3
++EXPLAIN SELECT * FROM t1
++WHERE t1.a>1 AND
++(t1.a,t1.b,t1.c) IN
++(
++SELECT v2.e,MAX(v2.f),v2.max_g
++FROM v2
++WHERE v2.e<5
++GROUP BY v2.e
++)
++;
++id select_type table type possible_keys key key_len ref rows Extra
++1 PRIMARY t1 ALL NULL NULL NULL NULL 16 Using where
++1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 12 test.t1.a,test.t1.b,test.t1.c 1
++2 MATERIALIZED <derived3> ALL NULL NULL NULL NULL 12 Using where; Using temporary
++3 DERIVED t2 ALL NULL NULL NULL NULL 12 Using temporary; Using filesort
++EXPLAIN FORMAT=JSON SELECT * FROM t1
++WHERE t1.a>1 AND
++(t1.a,t1.b,t1.c) IN
++(
++SELECT v2.e,MAX(v2.f),v2.max_g
++FROM v2
++WHERE v2.e<5
++GROUP BY v2.e
++)
++;
++EXPLAIN
++{
++ "query_block": {
++ "select_id": 1,
++ "table": {
++ "table_name": "t1",
++ "access_type": "ALL",
++ "rows": 16,
++ "filtered": 100,
++ "attached_condition": "t1.a > 1 and t1.a is not null and t1.b is not null and t1.c is not null"
++ },
++ "table": {
++ "table_name": "<subquery2>",
++ "access_type": "eq_ref",
++ "possible_keys": ["distinct_key"],
++ "key": "distinct_key",
++ "key_length": "12",
++ "used_key_parts": ["e", "MAX(v2.f)", "max_g"],
++ "ref": ["test.t1.a", "test.t1.b", "test.t1.c"],
++ "rows": 1,
++ "filtered": 100,
++ "materialized": {
++ "unique": 1,
++ "query_block": {
++ "select_id": 2,
++ "temporary_table": {
++ "table": {
++ "table_name": "<derived3>",
++ "access_type": "ALL",
++ "rows": 12,
++ "filtered": 100,
++ "attached_condition": "v2.e < 5 and v2.e > 1",
++ "materialized": {
++ "query_block": {
++ "select_id": 3,
++ "having_condition": "max_g > 25",
++ "filesort": {
++ "sort_key": "t2.e",
++ "temporary_table": {
++ "table": {
++ "table_name": "t2",
++ "access_type": "ALL",
++ "rows": 12,
++ "filtered": 100
++ }
++ }
++ }
++ }
++ }
++ }
++ }
++ }
++ }
++ }
++ }
++}
++# conjunctive subformula : pushing into WHERE and HAVING
++# of the IN subquery
++# conjunctive subformula : pushing into WHERE of the view
++# from the IN subquery
++SET STATEMENT optimizer_switch='condition_pushdown_for_subquery=off' FOR SELECT * FROM t1
++WHERE t1.a>1 AND t1.c<100 AND
++(t1.a,t1.b,t1.c) IN
++(
++SELECT v2.e,MAX(v2.f),v2.max_g
++FROM v2
++WHERE v2.e<5
++GROUP BY v2.e
++)
++;
++a b c d
++2 3 70 3
++SELECT * FROM t1
++WHERE t1.a>1 AND t1.c<100 AND
++(t1.a,t1.b,t1.c) IN
++(
++SELECT v2.e,MAX(v2.f),v2.max_g
++FROM v2
++WHERE v2.e<5
++GROUP BY v2.e
++)
++;
++a b c d
++2 3 70 3
++EXPLAIN SELECT * FROM t1
++WHERE t1.a>1 AND t1.c<100 AND
++(t1.a,t1.b,t1.c) IN
++(
++SELECT v2.e,MAX(v2.f),v2.max_g
++FROM v2
++WHERE v2.e<5
++GROUP BY v2.e
++)
++;
++id select_type table type possible_keys key key_len ref rows Extra
++1 PRIMARY t1 ALL NULL NULL NULL NULL 16 Using where
++1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 12 test.t1.a,test.t1.b,test.t1.c 1
++2 MATERIALIZED <derived3> ALL NULL NULL NULL NULL 12 Using where; Using temporary
++3 DERIVED t2 ALL NULL NULL NULL NULL 12 Using temporary; Using filesort
++EXPLAIN FORMAT=JSON SELECT * FROM t1
++WHERE t1.a>1 AND t1.c<100 AND
++(t1.a,t1.b,t1.c) IN
++(
++SELECT v2.e,MAX(v2.f),v2.max_g
++FROM v2
++WHERE v2.e<5
++GROUP BY v2.e
++)
++;
++EXPLAIN
++{
++ "query_block": {
++ "select_id": 1,
++ "table": {
++ "table_name": "t1",
++ "access_type": "ALL",
++ "rows": 16,
++ "filtered": 100,
++ "attached_condition": "t1.a > 1 and t1.c < 100 and t1.a is not null and t1.b is not null and t1.c is not null"
++ },
++ "table": {
++ "table_name": "<subquery2>",
++ "access_type": "eq_ref",
++ "possible_keys": ["distinct_key"],
++ "key": "distinct_key",
++ "key_length": "12",
++ "used_key_parts": ["e", "MAX(v2.f)", "max_g"],
++ "ref": ["test.t1.a", "test.t1.b", "test.t1.c"],
++ "rows": 1,
++ "filtered": 100,
++ "materialized": {
++ "unique": 1,
++ "query_block": {
++ "select_id": 2,
++ "having_condition": "v2.max_g < 100",
++ "temporary_table": {
++ "table": {
++ "table_name": "<derived3>",
++ "access_type": "ALL",
++ "rows": 12,
++ "filtered": 100,
++ "attached_condition": "v2.e < 5 and v2.e > 1",
++ "materialized": {
++ "query_block": {
++ "select_id": 3,
++ "having_condition": "max_g > 25",
++ "filesort": {
++ "sort_key": "t2.e",
++ "temporary_table": {
++ "table": {
++ "table_name": "t2",
++ "access_type": "ALL",
++ "rows": 12,
++ "filtered": 100
++ }
++ }
++ }
++ }
++ }
++ }
++ }
++ }
++ }
++ }
++ }
++}
++# conjunctive subformula : pushing into WHERE of the IN subquery
++# extracted AND formula : pushing into HAVING of the derived table
++# from the IN subquery
++SET STATEMENT optimizer_switch='condition_pushdown_for_subquery=off' FOR SELECT * FROM t1
++WHERE t1.a>1 AND
++(t1.a,t1.b,t1.c) IN
++(
++SELECT d_tab.e,MAX(d_tab.f),d_tab.max_g
++FROM
++(
++SELECT t2.e, t2.f, MAX(t2.g) AS max_g
++FROM t2
++GROUP BY t2.f
++HAVING max_g>25
++) as d_tab
++WHERE d_tab.e<5
++GROUP BY d_tab.e
++)
++;
++a b c d
++2 3 40 4
++SELECT * FROM t1
++WHERE t1.a>1 AND
++(t1.a,t1.b,t1.c) IN
++(
++SELECT d_tab.e,MAX(d_tab.f),d_tab.max_g
++FROM
++(
++SELECT t2.e, t2.f, MAX(t2.g) AS max_g
++FROM t2
++GROUP BY t2.f
++HAVING max_g>25
++) as d_tab
++WHERE d_tab.e<5
++GROUP BY d_tab.e
++)
++;
++a b c d
++2 3 40 4
++EXPLAIN SELECT * FROM t1
++WHERE t1.a>1 AND
++(t1.a,t1.b,t1.c) IN
++(
++SELECT d_tab.e,MAX(d_tab.f),d_tab.max_g
++FROM
++(
++SELECT t2.e, t2.f, MAX(t2.g) AS max_g
++FROM t2
++GROUP BY t2.f
++HAVING max_g>25
++) as d_tab
++WHERE d_tab.e<5
++GROUP BY d_tab.e
++)
++;
++id select_type table type possible_keys key key_len ref rows Extra
++1 PRIMARY t1 ALL NULL NULL NULL NULL 16 Using where
++1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 12 test.t1.a,test.t1.b,test.t1.c 1
++2 MATERIALIZED <derived3> ALL NULL NULL NULL NULL 12 Using where; Using temporary
++3 DERIVED t2 ALL NULL NULL NULL NULL 12 Using temporary; Using filesort
++EXPLAIN FORMAT=JSON SELECT * FROM t1
++WHERE t1.a>1 AND
++(t1.a,t1.b,t1.c) IN
++(
++SELECT d_tab.e,MAX(d_tab.f),d_tab.max_g
++FROM
++(
++SELECT t2.e, t2.f, MAX(t2.g) AS max_g
++FROM t2
++GROUP BY t2.f
++HAVING max_g>25
++) as d_tab
++WHERE d_tab.e<5
++GROUP BY d_tab.e
++)
++;
++EXPLAIN
++{
++ "query_block": {
++ "select_id": 1,
++ "table": {
++ "table_name": "t1",
++ "access_type": "ALL",
++ "rows": 16,
++ "filtered": 100,
++ "attached_condition": "t1.a > 1 and t1.a is not null and t1.b is not null and t1.c is not null"
++ },
++ "table": {
++ "table_name": "<subquery2>",
++ "access_type": "eq_ref",
++ "possible_keys": ["distinct_key"],
++ "key": "distinct_key",
++ "key_length": "12",
++ "used_key_parts": ["e", "MAX(d_tab.f)", "max_g"],
++ "ref": ["test.t1.a", "test.t1.b", "test.t1.c"],
++ "rows": 1,
++ "filtered": 100,
++ "materialized": {
++ "unique": 1,
++ "query_block": {
++ "select_id": 2,
++ "temporary_table": {
++ "table": {
++ "table_name": "<derived3>",
++ "access_type": "ALL",
++ "rows": 12,
++ "filtered": 100,
++ "attached_condition": "d_tab.e < 5 and d_tab.e > 1",
++ "materialized": {
++ "query_block": {
++ "select_id": 3,
++ "having_condition": "max_g > 25",
++ "filesort": {
++ "sort_key": "t2.f",
++ "temporary_table": {
++ "table": {
++ "table_name": "t2",
++ "access_type": "ALL",
++ "rows": 12,
++ "filtered": 100
++ }
++ }
++ }
++ }
++ }
++ }
++ }
++ }
++ }
++ }
++ }
++}
++# conjunctive subformula : pushing into HAVING of the derived table
++# conjunctive subformula : pushing into WHERE of the IN subquery from
++# the derived table
++SELECT *
++FROM t3,
++(
++SELECT t1.a,t1.b,max(t1.c) as max_c
++FROM t1
++WHERE t1.a>1 AND
++(t1.a,t1.b,t1.c) IN
++(
++SELECT t2.e,t2.f,MAX(t2.g)
++FROM t2
++WHERE t2.e<5
++GROUP BY t2.e
++)
++GROUP BY t1.a
++) AS d_tab
++WHERE d_tab.a=t3.x AND d_tab.b>2;
++x y a b max_c
++2 15 2 3 70
++2 15 2 3 70
++SET STATEMENT optimizer_switch='condition_pushdown_for_subquery=off' FOR SELECT * FROM t1
++WHERE t1.a>1 AND
++(t1.a,t1.b,t1.c) IN
++(
++SELECT d_tab.e,MAX(d_tab.f),d_tab.max_g
++FROM
++(
++SELECT t2.e, t2.f, MAX(t2.g) AS max_g
++FROM t2
++GROUP BY t2.f
++HAVING max_g>25
++) as d_tab
++WHERE d_tab.e<5
++GROUP BY d_tab.e
++)
++;
++a b c d
++2 3 40 4
++SELECT * FROM t1
++WHERE t1.a>1 AND
++(t1.a,t1.b,t1.c) IN
++(
++SELECT d_tab.e,MAX(d_tab.f),d_tab.max_g
++FROM
++(
++SELECT t2.e, t2.f, MAX(t2.g) AS max_g
++FROM t2
++GROUP BY t2.f
++HAVING max_g>25
++) as d_tab
++WHERE d_tab.e<5
++GROUP BY d_tab.e
++)
++;
++a b c d
++2 3 40 4
++EXPLAIN SELECT * FROM t1
++WHERE t1.a>1 AND
++(t1.a,t1.b,t1.c) IN
++(
++SELECT d_tab.e,MAX(d_tab.f),d_tab.max_g
++FROM
++(
++SELECT t2.e, t2.f, MAX(t2.g) AS max_g
++FROM t2
++GROUP BY t2.f
++HAVING max_g>25
++) as d_tab
++WHERE d_tab.e<5
++GROUP BY d_tab.e
++)
++;
++id select_type table type possible_keys key key_len ref rows Extra
++1 PRIMARY t1 ALL NULL NULL NULL NULL 16 Using where
++1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 12 test.t1.a,test.t1.b,test.t1.c 1
++2 MATERIALIZED <derived3> ALL NULL NULL NULL NULL 12 Using where; Using temporary
++3 DERIVED t2 ALL NULL NULL NULL NULL 12 Using temporary; Using filesort
++EXPLAIN FORMAT=JSON SELECT * FROM t1
++WHERE t1.a>1 AND
++(t1.a,t1.b,t1.c) IN
++(
++SELECT d_tab.e,MAX(d_tab.f),d_tab.max_g
++FROM
++(
++SELECT t2.e, t2.f, MAX(t2.g) AS max_g
++FROM t2
++GROUP BY t2.f
++HAVING max_g>25
++) as d_tab
++WHERE d_tab.e<5
++GROUP BY d_tab.e
++)
++;
++EXPLAIN
++{
++ "query_block": {
++ "select_id": 1,
++ "table": {
++ "table_name": "t1",
++ "access_type": "ALL",
++ "rows": 16,
++ "filtered": 100,
++ "attached_condition": "t1.a > 1 and t1.a is not null and t1.b is not null and t1.c is not null"
++ },
++ "table": {
++ "table_name": "<subquery2>",
++ "access_type": "eq_ref",
++ "possible_keys": ["distinct_key"],
++ "key": "distinct_key",
++ "key_length": "12",
++ "used_key_parts": ["e", "MAX(d_tab.f)", "max_g"],
++ "ref": ["test.t1.a", "test.t1.b", "test.t1.c"],
++ "rows": 1,
++ "filtered": 100,
++ "materialized": {
++ "unique": 1,
++ "query_block": {
++ "select_id": 2,
++ "temporary_table": {
++ "table": {
++ "table_name": "<derived3>",
++ "access_type": "ALL",
++ "rows": 12,
++ "filtered": 100,
++ "attached_condition": "d_tab.e < 5 and d_tab.e > 1",
++ "materialized": {
++ "query_block": {
++ "select_id": 3,
++ "having_condition": "max_g > 25",
++ "filesort": {
++ "sort_key": "t2.f",
++ "temporary_table": {
++ "table": {
++ "table_name": "t2",
++ "access_type": "ALL",
++ "rows": 12,
++ "filtered": 100
++ }
++ }
++ }
++ }
++ }
++ }
++ }
++ }
++ }
++ }
++ }
++}
++# conjunctive subformula : pushing into WHERE of the derived table
++# extracted AND formula : pushing into WHERE of the IN subquery from
++# the derived table
++SELECT *
++FROM t3,
++(
++SELECT t1.a,t1.b,max(t1.c) as max_c
++FROM t1
++WHERE t1.a>1 AND
++(t1.a,t1.b,t1.c) IN
++(
++SELECT t2.e,t2.f,MAX(t2.g)
++FROM t2
++GROUP BY t2.e
++HAVING t2.f<5
++)
++GROUP BY t1.a
++) AS d_tab
++WHERE d_tab.a=t3.x AND d_tab.a<5;
++x y a b max_c
++2 15 2 3 70
++4 24 4 2 24
++2 15 2 3 70
++SET STATEMENT optimizer_switch='condition_pushdown_for_subquery=off' FOR SELECT * FROM t1
++WHERE t1.a>1 AND
++(t1.a,t1.b,t1.c) IN
++(
++SELECT d_tab.e,MAX(d_tab.f),d_tab.max_g
++FROM
++(
++SELECT t2.e, t2.f, MAX(t2.g) AS max_g
++FROM t2
++GROUP BY t2.f
++HAVING max_g>25
++) as d_tab
++WHERE d_tab.e<5
++GROUP BY d_tab.e
++)
++;
++a b c d
++2 3 40 4
++SELECT * FROM t1
++WHERE t1.a>1 AND
++(t1.a,t1.b,t1.c) IN
++(
++SELECT d_tab.e,MAX(d_tab.f),d_tab.max_g
++FROM
++(
++SELECT t2.e, t2.f, MAX(t2.g) AS max_g
++FROM t2
++GROUP BY t2.f
++HAVING max_g>25
++) as d_tab
++WHERE d_tab.e<5
++GROUP BY d_tab.e
++)
++;
++a b c d
++2 3 40 4
++EXPLAIN SELECT * FROM t1
++WHERE t1.a>1 AND
++(t1.a,t1.b,t1.c) IN
++(
++SELECT d_tab.e,MAX(d_tab.f),d_tab.max_g
++FROM
++(
++SELECT t2.e, t2.f, MAX(t2.g) AS max_g
++FROM t2
++GROUP BY t2.f
++HAVING max_g>25
++) as d_tab
++WHERE d_tab.e<5
++GROUP BY d_tab.e
++)
++;
++id select_type table type possible_keys key key_len ref rows Extra
++1 PRIMARY t1 ALL NULL NULL NULL NULL 16 Using where
++1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 12 test.t1.a,test.t1.b,test.t1.c 1
++2 MATERIALIZED <derived3> ALL NULL NULL NULL NULL 12 Using where; Using temporary
++3 DERIVED t2 ALL NULL NULL NULL NULL 12 Using temporary; Using filesort
++EXPLAIN FORMAT=JSON SELECT * FROM t1
++WHERE t1.a>1 AND
++(t1.a,t1.b,t1.c) IN
++(
++SELECT d_tab.e,MAX(d_tab.f),d_tab.max_g
++FROM
++(
++SELECT t2.e, t2.f, MAX(t2.g) AS max_g
++FROM t2
++GROUP BY t2.f
++HAVING max_g>25
++) as d_tab
++WHERE d_tab.e<5
++GROUP BY d_tab.e
++)
++;
++EXPLAIN
++{
++ "query_block": {
++ "select_id": 1,
++ "table": {
++ "table_name": "t1",
++ "access_type": "ALL",
++ "rows": 16,
++ "filtered": 100,
++ "attached_condition": "t1.a > 1 and t1.a is not null and t1.b is not null and t1.c is not null"
++ },
++ "table": {
++ "table_name": "<subquery2>",
++ "access_type": "eq_ref",
++ "possible_keys": ["distinct_key"],
++ "key": "distinct_key",
++ "key_length": "12",
++ "used_key_parts": ["e", "MAX(d_tab.f)", "max_g"],
++ "ref": ["test.t1.a", "test.t1.b", "test.t1.c"],
++ "rows": 1,
++ "filtered": 100,
++ "materialized": {
++ "unique": 1,
++ "query_block": {
++ "select_id": 2,
++ "temporary_table": {
++ "table": {
++ "table_name": "<derived3>",
++ "access_type": "ALL",
++ "rows": 12,
++ "filtered": 100,
++ "attached_condition": "d_tab.e < 5 and d_tab.e > 1",
++ "materialized": {
++ "query_block": {
++ "select_id": 3,
++ "having_condition": "max_g > 25",
++ "filesort": {
++ "sort_key": "t2.f",
++ "temporary_table": {
++ "table": {
++ "table_name": "t2",
++ "access_type": "ALL",
++ "rows": 12,
++ "filtered": 100
++ }
++ }
++ }
++ }
++ }
++ }
++ }
++ }
++ }
++ }
++ }
++}
++# conjunctive subformula : pushing into WHERE and HAVING
++# of the derived table
++# extracted AND formula : pushing into WHERE of the IN subquery
++# from the derived table
++SET STATEMENT optimizer_switch='condition_pushdown_for_subquery=off' FOR SELECT *
++FROM t3,
++(
++SELECT t1.a,t1.b,max(t1.c) as max_c
++FROM t1
++WHERE t1.a>1 AND
++(t1.a,t1.b,t1.c) IN
++(
++SELECT t2.e,t2.f,MAX(t2.g)
++FROM t2
++GROUP BY t2.e
++HAVING t2.f<5
++)
++GROUP BY t1.a
++) AS d_tab
++WHERE d_tab.a=t3.x AND d_tab.a<5 AND d_tab.max_c<70;
++x y a b max_c
++4 24 4 2 24
++SELECT *
++FROM t3,
++(
++SELECT t1.a,t1.b,max(t1.c) as max_c
++FROM t1
++WHERE t1.a>1 AND
++(t1.a,t1.b,t1.c) IN
++(
++SELECT t2.e,t2.f,MAX(t2.g)
++FROM t2
++GROUP BY t2.e
++HAVING t2.f<5
++)
++GROUP BY t1.a
++) AS d_tab
++WHERE d_tab.a=t3.x AND d_tab.a<5 AND d_tab.max_c<70;
++x y a b max_c
++4 24 4 2 24
++EXPLAIN SELECT *
++FROM t3,
++(
++SELECT t1.a,t1.b,max(t1.c) as max_c
++FROM t1
++WHERE t1.a>1 AND
++(t1.a,t1.b,t1.c) IN
++(
++SELECT t2.e,t2.f,MAX(t2.g)
++FROM t2
++GROUP BY t2.e
++HAVING t2.f<5
++)
++GROUP BY t1.a
++) AS d_tab
++WHERE d_tab.a=t3.x AND d_tab.a<5 AND d_tab.max_c<70;
++id select_type table type possible_keys key key_len ref rows Extra
++1 PRIMARY t3 ALL NULL NULL NULL NULL 8 Using where
++1 PRIMARY <derived2> ref key0 key0 5 test.t3.x 2 Using where
++2 DERIVED t1 ALL NULL NULL NULL NULL 16 Using where; Using temporary; Using filesort
++2 DERIVED <subquery3> eq_ref distinct_key distinct_key 12 test.t1.a,test.t1.b,test.t1.c 1
++3 MATERIALIZED t2 ALL NULL NULL NULL NULL 12 Using where; Using temporary
++EXPLAIN FORMAT=JSON SELECT *
++FROM t3,
++(
++SELECT t1.a,t1.b,max(t1.c) as max_c
++FROM t1
++WHERE t1.a>1 AND
++(t1.a,t1.b,t1.c) IN
++(
++SELECT t2.e,t2.f,MAX(t2.g)
++FROM t2
++GROUP BY t2.e
++HAVING t2.f<5
++)
++GROUP BY t1.a
++) AS d_tab
++WHERE d_tab.a=t3.x AND d_tab.a<5 AND d_tab.max_c<70;
++EXPLAIN
++{
++ "query_block": {
++ "select_id": 1,
++ "table": {
++ "table_name": "t3",
++ "access_type": "ALL",
++ "rows": 8,
++ "filtered": 100,
++ "attached_condition": "t3.x < 5 and t3.x is not null"
++ },
++ "table": {
++ "table_name": "<derived2>",
++ "access_type": "ref",
++ "possible_keys": ["key0"],
++ "key": "key0",
++ "key_length": "5",
++ "used_key_parts": ["a"],
++ "ref": ["test.t3.x"],
++ "rows": 2,
++ "filtered": 100,
++ "attached_condition": "d_tab.max_c < 70",
++ "materialized": {
++ "query_block": {
++ "select_id": 2,
++ "having_condition": "max_c < 70",
++ "filesort": {
++ "sort_key": "t1.a",
++ "temporary_table": {
++ "table": {
++ "table_name": "t1",
++ "access_type": "ALL",
++ "rows": 16,
++ "filtered": 100,
++ "attached_condition": "t1.a > 1 and t1.a < 5 and t1.a is not null and t1.b is not null and t1.c is not null"
++ },
++ "table": {
++ "table_name": "<subquery3>",
++ "access_type": "eq_ref",
++ "possible_keys": ["distinct_key"],
++ "key": "distinct_key",
++ "key_length": "12",
++ "used_key_parts": ["e", "f", "MAX(t2.g)"],
++ "ref": ["test.t1.a", "test.t1.b", "test.t1.c"],
++ "rows": 1,
++ "filtered": 100,
++ "materialized": {
++ "unique": 1,
++ "query_block": {
++ "select_id": 3,
++ "having_condition": "t2.f < 5",
++ "temporary_table": {
++ "table": {
++ "table_name": "t2",
++ "access_type": "ALL",
++ "rows": 12,
++ "filtered": 100,
++ "attached_condition": "t2.e > 1 and t2.e < 5"
++ }
++ }
++ }
++ }
++ }
++ }
++ }
++ }
++ }
++ }
++ }
++}
++# conjunctive subformula : pushing into WHERE of the derived table
++# conjunctive subformula : pushing into HAVING of the IN subquery from
++# the derived table
++SELECT *
++FROM t3,
++(
++SELECT t1.a,t1.b,max(t1.c) as max_c
++FROM t1
++WHERE (t1.a,t1.b,t1.c) IN
++(
++SELECT t2.e,t2.f,MAX(t2.g)
++FROM t2
++WHERE t2.f<4
++GROUP BY t2.f
++)
++GROUP BY t1.a
++HAVING t1.b<5
++) AS d_tab
++WHERE d_tab.a=t3.x AND d_tab.a<5;
++x y a b max_c
++1 25 1 2 70
++1 18 1 2 70
++2 15 2 3 40
++1 35 1 2 70
++2 15 2 3 40
++SET STATEMENT optimizer_switch='condition_pushdown_for_subquery=off' FOR SELECT *
++FROM t3,
++(
++SELECT t1.a,t1.b,max(t1.c) as max_c
++FROM t1
++WHERE t1.a>1 AND
++(t1.a,t1.b,t1.c) IN
++(
++SELECT t2.e,t2.f,MAX(t2.g)
++FROM t2
++GROUP BY t2.e
++HAVING t2.f<5
++)
++GROUP BY t1.a
++) AS d_tab
++WHERE d_tab.a=t3.x AND d_tab.a<5 AND d_tab.max_c<70;
++x y a b max_c
++4 24 4 2 24
++SELECT *
++FROM t3,
++(
++SELECT t1.a,t1.b,max(t1.c) as max_c
++FROM t1
++WHERE t1.a>1 AND
++(t1.a,t1.b,t1.c) IN
++(
++SELECT t2.e,t2.f,MAX(t2.g)
++FROM t2
++GROUP BY t2.e
++HAVING t2.f<5
++)
++GROUP BY t1.a
++) AS d_tab
++WHERE d_tab.a=t3.x AND d_tab.a<5 AND d_tab.max_c<70;
++x y a b max_c
++4 24 4 2 24
++EXPLAIN SELECT *
++FROM t3,
++(
++SELECT t1.a,t1.b,max(t1.c) as max_c
++FROM t1
++WHERE t1.a>1 AND
++(t1.a,t1.b,t1.c) IN
++(
++SELECT t2.e,t2.f,MAX(t2.g)
++FROM t2
++GROUP BY t2.e
++HAVING t2.f<5
++)
++GROUP BY t1.a
++) AS d_tab
++WHERE d_tab.a=t3.x AND d_tab.a<5 AND d_tab.max_c<70;
++id select_type table type possible_keys key key_len ref rows Extra
++1 PRIMARY t3 ALL NULL NULL NULL NULL 8 Using where
++1 PRIMARY <derived2> ref key0 key0 5 test.t3.x 2 Using where
++2 DERIVED t1 ALL NULL NULL NULL NULL 16 Using where; Using temporary; Using filesort
++2 DERIVED <subquery3> eq_ref distinct_key distinct_key 12 test.t1.a,test.t1.b,test.t1.c 1
++3 MATERIALIZED t2 ALL NULL NULL NULL NULL 12 Using where; Using temporary
++EXPLAIN FORMAT=JSON SELECT *
++FROM t3,
++(
++SELECT t1.a,t1.b,max(t1.c) as max_c
++FROM t1
++WHERE t1.a>1 AND
++(t1.a,t1.b,t1.c) IN
++(
++SELECT t2.e,t2.f,MAX(t2.g)
++FROM t2
++GROUP BY t2.e
++HAVING t2.f<5
++)
++GROUP BY t1.a
++) AS d_tab
++WHERE d_tab.a=t3.x AND d_tab.a<5 AND d_tab.max_c<70;
++EXPLAIN
++{
++ "query_block": {
++ "select_id": 1,
++ "table": {
++ "table_name": "t3",
++ "access_type": "ALL",
++ "rows": 8,
++ "filtered": 100,
++ "attached_condition": "t3.x < 5 and t3.x is not null"
++ },
++ "table": {
++ "table_name": "<derived2>",
++ "access_type": "ref",
++ "possible_keys": ["key0"],
++ "key": "key0",
++ "key_length": "5",
++ "used_key_parts": ["a"],
++ "ref": ["test.t3.x"],
++ "rows": 2,
++ "filtered": 100,
++ "attached_condition": "d_tab.max_c < 70",
++ "materialized": {
++ "query_block": {
++ "select_id": 2,
++ "having_condition": "max_c < 70",
++ "filesort": {
++ "sort_key": "t1.a",
++ "temporary_table": {
++ "table": {
++ "table_name": "t1",
++ "access_type": "ALL",
++ "rows": 16,
++ "filtered": 100,
++ "attached_condition": "t1.a > 1 and t1.a < 5 and t1.a is not null and t1.b is not null and t1.c is not null"
++ },
++ "table": {
++ "table_name": "<subquery3>",
++ "access_type": "eq_ref",
++ "possible_keys": ["distinct_key"],
++ "key": "distinct_key",
++ "key_length": "12",
++ "used_key_parts": ["e", "f", "MAX(t2.g)"],
++ "ref": ["test.t1.a", "test.t1.b", "test.t1.c"],
++ "rows": 1,
++ "filtered": 100,
++ "materialized": {
++ "unique": 1,
++ "query_block": {
++ "select_id": 3,
++ "having_condition": "t2.f < 5",
++ "temporary_table": {
++ "table": {
++ "table_name": "t2",
++ "access_type": "ALL",
++ "rows": 12,
++ "filtered": 100,
++ "attached_condition": "t2.e > 1 and t2.e < 5"
++ }
++ }
++ }
++ }
++ }
++ }
++ }
++ }
++ }
++ }
++ }
++}
++# conjunctive subformula : pushing into WHERE
++# using WINDOW FUNCTIONS : using MAX function
++SET STATEMENT optimizer_switch='condition_pushdown_for_subquery=off' FOR SELECT * FROM t1
++WHERE (t1.b>1) AND
++(t1.b, t1.c) IN
++(
++SELECT t2.f, MAX(t2.g) OVER (PARTITION BY t2.f)
++FROM t2
++WHERE t2.e<5
++)
++;
++a b c d
++1 3 40 1
++2 3 40 4
++1 4 35 3
++1 2 70 5
++SELECT * FROM t1
++WHERE (t1.b>1) AND
++(t1.b, t1.c) IN
++(
++SELECT t2.f, MAX(t2.g) OVER (PARTITION BY t2.f)
++FROM t2
++WHERE t2.e<5
++)
++;
++a b c d
++1 3 40 1
++2 3 40 4
++1 4 35 3
++1 2 70 5
++EXPLAIN SELECT * FROM t1
++WHERE (t1.b>1) AND
++(t1.b, t1.c) IN
++(
++SELECT t2.f, MAX(t2.g) OVER (PARTITION BY t2.f)
++FROM t2
++WHERE t2.e<5
++)
++;
++id select_type table type possible_keys key key_len ref rows Extra
++1 PRIMARY t1 ALL NULL NULL NULL NULL 16 Using where
++1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 8 test.t1.b,test.t1.c 1
++2 MATERIALIZED t2 ALL NULL NULL NULL NULL 12 Using where; Using temporary
++EXPLAIN FORMAT=JSON SELECT * FROM t1
++WHERE (t1.b>1) AND
++(t1.b, t1.c) IN
++(
++SELECT t2.f, MAX(t2.g) OVER (PARTITION BY t2.f)
++FROM t2
++WHERE t2.e<5
++)
++;
++EXPLAIN
++{
++ "query_block": {
++ "select_id": 1,
++ "table": {
++ "table_name": "t1",
++ "access_type": "ALL",
++ "rows": 16,
++ "filtered": 100,
++ "attached_condition": "t1.b > 1 and t1.b is not null and t1.c is not null"
++ },
++ "table": {
++ "table_name": "<subquery2>",
++ "access_type": "eq_ref",
++ "possible_keys": ["distinct_key"],
++ "key": "distinct_key",
++ "key_length": "8",
++ "used_key_parts": ["f", "MAX(t2.g) OVER (PARTITION BY t2.f)"],
++ "ref": ["test.t1.b", "test.t1.c"],
++ "rows": 1,
++ "filtered": 100,
++ "materialized": {
++ "unique": 1,
++ "query_block": {
++ "select_id": 2,
++ "window_functions_computation": {
++ "sorts": {
++ "filesort": {
++ "sort_key": "t2.f"
++ }
++ },
++ "temporary_table": {
++ "table": {
++ "table_name": "t2",
++ "access_type": "ALL",
++ "rows": 12,
++ "filtered": 100,
++ "attached_condition": "t2.e < 5 and t2.f > 1"
++ }
++ }
++ }
++ }
++ }
++ }
++ }
++}
++# conjunctive subformula : pushing into WHERE
++# using WINDOW FUNCTIONS : using SUM function
++SET STATEMENT optimizer_switch='condition_pushdown_for_subquery=off' FOR SELECT * FROM t1
++WHERE (t1.b>1) AND
++(t1.b, t1.c) IN
++(
++SELECT t2.f, CAST(SUM(t2.g) OVER (PARTITION BY t2.f) AS INT)
++FROM t2
++WHERE t2.e<5
++)
++;
++a b c d
++5 3 72 4
++SELECT * FROM t1
++WHERE (t1.b>1) AND
++(t1.b, t1.c) IN
++(
++SELECT t2.f, CAST(SUM(t2.g) OVER (PARTITION BY t2.f) AS INT)
++FROM t2
++WHERE t2.e<5
++)
++;
++a b c d
++5 3 72 4
++EXPLAIN SELECT * FROM t1
++WHERE (t1.b>1) AND
++(t1.b, t1.c) IN
++(
++SELECT t2.f, CAST(SUM(t2.g) OVER (PARTITION BY t2.f) AS INT)
++FROM t2
++WHERE t2.e<5
++)
++;
++id select_type table type possible_keys key key_len ref rows Extra
++1 PRIMARY t1 ALL NULL NULL NULL NULL 16 Using where
++1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 12 test.t1.b,test.t1.c 1 Using where
++2 MATERIALIZED t2 ALL NULL NULL NULL NULL 12 Using where; Using temporary
++EXPLAIN FORMAT=JSON SELECT * FROM t1
++WHERE (t1.b>1) AND
++(t1.b, t1.c) IN
++(
++SELECT t2.f, CAST(SUM(t2.g) OVER (PARTITION BY t2.f) AS INT)
++FROM t2
++WHERE t2.e<5
++)
++;
++EXPLAIN
++{
++ "query_block": {
++ "select_id": 1,
++ "table": {
++ "table_name": "t1",
++ "access_type": "ALL",
++ "rows": 16,
++ "filtered": 100,
++ "attached_condition": "t1.b > 1 and t1.b is not null and t1.c is not null"
++ },
++ "table": {
++ "table_name": "<subquery2>",
++ "access_type": "eq_ref",
++ "possible_keys": ["distinct_key"],
++ "key": "distinct_key",
++ "key_length": "12",
++ "used_key_parts": ["f", "CAST(SUM(t2.g) OVER (PARTITION BY t2.f) AS INT)"],
++ "ref": ["test.t1.b", "test.t1.c"],
++ "rows": 1,
++ "filtered": 100,
++ "attached_condition": "t1.c = `<subquery2>`.`CAST(SUM(t2.g) OVER (PARTITION BY t2.f) AS INT)`",
++ "materialized": {
++ "unique": 1,
++ "query_block": {
++ "select_id": 2,
++ "window_functions_computation": {
++ "sorts": {
++ "filesort": {
++ "sort_key": "t2.f"
++ }
++ },
++ "temporary_table": {
++ "table": {
++ "table_name": "t2",
++ "access_type": "ALL",
++ "rows": 12,
++ "filtered": 100,
++ "attached_condition": "t2.e < 5 and t2.f > 1"
++ }
++ }
++ }
++ }
++ }
++ }
++ }
++}
++DROP TABLE t1,t2,t3;
++DROP VIEW v1,v2;
diff --cc mysql-test/main/in_subq_cond_pushdown.test
index 0000000,0000000..051521a
new file mode 100644
--- /dev/null
+++ b/mysql-test/main/in_subq_cond_pushdown.test
@@@ -1,0 -1,0 +1,759 @@@
++LET $no_pushdown=
++ SET STATEMENT optimizer_switch='condition_pushdown_for_subquery=off' FOR;
++
++CREATE TABLE t1 (a INT, b INT, c INT, d INT);
++CREATE TABLE t2 (e INT, f INT, g INT);
++CREATE TABLE t3 (x INT, y INT);
++
++INSERT INTO t1 VALUES
++(1,1,18,1), (2,1,25,1), (1,3,40,1), (2,3,40,4),
++(4,2,24,4), (3,2,23,1), (1,2,40,2), (3,4,17,2),
++(5,5,65,1), (2,3,70,3), (1,4,35,3), (2,3,25,3),
++(2,2,40,4), (1,4,55,1), (5,3,72,4), (1,2,70,5);
++
++INSERT INTO t2 VALUES
++(1,2,38), (2,3,15), (1,3,40), (1,4,35),
++(2,2,70), (3,4,23), (5,5,12), (5,4,17),
++(3,3,17), (4,2,24), (2,5,25), (5,1,65);
++
++INSERT INTO t3 VALUES
++(1,25), (1,18), (2,15), (4,24),
++(1,35), (3,23), (3,17), (2,15);
++
++CREATE VIEW v1 AS
++(
++ SELECT t3.x AS v1_x, t3.y AS v1_y FROM t3 WHERE t3.x<=3
++);
++
++CREATE VIEW v2 AS
++(
++ SELECT t2.e, t2.f, MAX(t2.g) AS max_g
++ FROM t2
++ GROUP BY t2.e
++ HAVING max_g>25
++);
++
++--echo # conjunctive subformula : pushing into HAVING
++LET $query=
++SELECT * FROM t1
++WHERE t1.c<25 AND
++ (t1.a,t1.c) IN (SELECT t2.e,MAX(t2.g) FROM t2 WHERE t2.e<5 GROUP BY t2.e);
++
++EVAL $no_pushdown $query;
++EVAL $query;
++EVAL EXPLAIN $query;
++EVAL EXPLAIN FORMAT=JSON $query;
++
++--echo # extracted AND formula : pushing into HAVING
++LET $query=
++SELECT * FROM t1
++WHERE t1.c>55 AND t1.b<4 AND
++ (t1.a,t1.b,t1.c) IN
++ (
++ SELECT t2.e,t2.f,MAX(t2.g)
++ FROM t2
++ WHERE t2.e<5
++ GROUP BY t2.e
++ )
++;
++
++EVAL $no_pushdown $query;
++EVAL $query;
++EVAL EXPLAIN $query;
++EVAL EXPLAIN FORMAT=JSON $query;
++
++--echo # extracted OR formula : pushing into HAVING
++LET $query=
++SELECT * FROM t1
++WHERE (t1.c>60 OR t1.c<25) AND
++ (t1.a,t1.b,t1.c) IN
++ (
++ SELECT t2.e,t2.f,MAX(t2.g)
++ FROM t2
++ WHERE t2.e<5
++ GROUP BY t2.e
++ )
++;
++
++EVAL $no_pushdown $query;
++EVAL $query;
++EVAL EXPLAIN $query;
++EVAL EXPLAIN FORMAT=JSON $query;
++
++--echo # extracted AND-OR formula : pushing into HAVING
++LET $query=
++SELECT * FROM t1
++WHERE ((t1.c>60 OR t1.c<25) AND t1.b>2) AND
++ (t1.a,t1.b,t1.c) IN
++ (
++ SELECT t2.e,t2.f,MAX(t2.g)
++ FROM t2
++ WHERE t2.e<5
++ GROUP BY t2.e
++ )
++;
++
++EVAL $no_pushdown $query;
++EVAL $query;
++EVAL EXPLAIN $query;
++EVAL EXPLAIN FORMAT=JSON $query;
++
++--echo # conjunctive subformula : pushing into HAVING
++LET $query=
++SELECT * FROM t1
++WHERE ((t1.a<2 OR t1.d>3) AND t1.b>1) AND
++ (t1.a,t1.b,t1.c) IN
++ (
++ SELECT t2.e,t2.f,MAX(t2.g)
++ FROM t2
++ WHERE t2.e<5
++ GROUP BY t2.e
++ )
++;
++
++EVAL $no_pushdown $query;
++EVAL $query;
++EVAL EXPLAIN $query;
++EVAL EXPLAIN FORMAT=JSON $query;
++
++--echo # using view IN subquery defINition : pushing into HAVING
++LET $query=
++SELECT * FROM t1
++WHERE t1.c>20 AND
++ (t1.a,t1.c) IN
++ (
++ SELECT v1_x,MAX(v1_y)
++ FROM v1
++ WHERE v1_x>1
++ GROUP BY v1_x
++ )
++;
++
++EVAL $no_pushdown $query;
++EVAL $query;
++EVAL EXPLAIN $query;
++EVAL EXPLAIN FORMAT=JSON $query;
++
++--echo # using equality : pushing into WHERE
++LET $query=
++SELECT * FROM t1,v1
++WHERE t1.c>20 AND t1.c=v1_y AND
++ (t1.a,t1.c) IN
++ (
++ SELECT t2.e,MAX(t2.g)
++ FROM t2
++ WHERE t2.e<5
++ GROUP BY t2.e
++ )
++;
++
++EVAL $no_pushdown $query;
++EVAL $query;
++EVAL EXPLAIN $query;
++EVAL EXPLAIN FORMAT=JSON $query;
++
++--echo # conjunctive subformula : pushing into WHERE
++LET $query=
++SELECT * FROM t1
++WHERE t1.a<2 AND
++ (t1.a,t1.c) IN
++ (
++ SELECT t2.e,MAX(t2.g)
++ FROM t2
++ WHERE t2.e<5
++ GROUP BY t2.e
++ )
++;
++
++EVAL $no_pushdown $query;
++EVAL $query;
++EVAL EXPLAIN $query;
++EVAL EXPLAIN FORMAT=JSON $query;
++
++--echo # extracted AND formula : pushing into WHERE
++LET $query=
++SELECT * FROM t1
++WHERE t1.a>2 AND t1.a<5 AND
++ (t1.a,t1.c) IN
++ (
++ SELECT t2.e,MAX(t2.g)
++ FROM t2
++ WHERE t2.e<5
++ GROUP BY t2.e
++ )
++;
++
++EVAL $no_pushdown $query;
++EVAL $query;
++EVAL EXPLAIN $query;
++EVAL EXPLAIN FORMAT=JSON $query;
++
++--echo # extracted OR formula : pushing into WHERE
++LET $query=
++SELECT * FROM t1
++WHERE (t1.a<2 OR t1.a>=4) AND
++ (t1.a,t1.c) IN
++ (
++ SELECT t2.e,MAX(t2.g)
++ FROM t2
++ WHERE t2.e<5
++ GROUP BY t2.e
++ )
++;
++
++EVAL $no_pushdown $query;
++EVAL $query;
++EVAL EXPLAIN $query;
++EVAL EXPLAIN FORMAT=JSON $query;
++
++--echo # extracted AND-OR formula : pushing into WHERE
++LET $query=
++SELECT * FROM t1
++WHERE ((t1.a<2 OR t1.a=5) AND t1.b>3) AND
++ (t1.a,t1.b,t1.c) IN
++ (
++ SELECT t2.e,t2.f,MAX(t2.g)
++ FROM t2
++ WHERE t2.e<5
++ GROUP BY t2.e,t2.f
++ )
++;
++
++EVAL $no_pushdown $query;
++EVAL $query;
++EVAL EXPLAIN $query;
++EVAL EXPLAIN FORMAT=JSON $query;
++
++--echo # extracted AND-OR formula : pushing into WHERE
++LET $query=
++SELECT * FROM t1
++WHERE ((t1.a<2 OR t1.a=5) AND t1.b>3) AND
++ (t1.a,t1.b,t1.c) IN
++ (
++ SELECT t2.e,t2.f,MAX(t2.g)
++ FROM t2
++ WHERE t2.e<5
++ GROUP BY t2.e,t2.f
++ )
++;
++
++EVAL $no_pushdown $query;
++EVAL $query;
++EVAL EXPLAIN $query;
++EVAL EXPLAIN FORMAT=JSON $query;
++
++--echo # conjunctive subformula : pushing into WHERE
++LET $query=
++SELECT * FROM t1
++WHERE ((t1.b<3 OR t1.d>2) AND t1.a<2) AND
++ (t1.a,t1.b,t1.c) IN
++ (
++ SELECT t2.e,t2.f,MAX(t2.g)
++ FROM t2
++ WHERE t2.e<5
++ GROUP BY t2.e
++ )
++;
++
++EVAL $no_pushdown $query;
++EVAL $query;
++EVAL EXPLAIN $query;
++EVAL EXPLAIN FORMAT=JSON $query;
++
++--echo # using equalities : pushing into WHERE
++LET $query=
++SELECT * FROM t1
++WHERE t1.d=1 AND t1.a=t1.d AND
++ (t1.a,t1.c) IN
++ (
++ SELECT t2.e,MAX(t2.g)
++ FROM t2
++ WHERE t2.e<5
++ GROUP BY t2.e
++ )
++;
++
++EVAL $no_pushdown $query;
++EVAL $query;
++EVAL EXPLAIN $query;
++EVAL EXPLAIN FORMAT=JSON $query;
++
++--echo # using equality : pushing into WHERE
++LET $query=
++SELECT * FROM t1
++WHERE t1.d>1 AND t1.a=t1.d AND
++ (t1.a,t1.c) IN
++ (
++ SELECT t2.e,MAX(t2.g)
++ FROM t2
++ WHERE t2.e<5
++ GROUP BY t2.e
++ )
++;
++
++EVAL $no_pushdown $query;
++EVAL $query;
++EVAL EXPLAIN $query;
++EVAL EXPLAIN FORMAT=JSON $query;
++
++--echo # using view IN subquery definition : pushing into WHERE
++LET $query=
++SELECT * FROM t1
++WHERE t1.a<3 AND
++ (t1.a,t1.c) IN
++ (
++ SELECT v1_x,MAX(v1_y)
++ FROM v1
++ WHERE v1_x>1
++ GROUP BY v1_x
++ )
++;
++
++EVAL $no_pushdown $query;
++EVAL $query;
++EVAL EXPLAIN $query;
++EVAL EXPLAIN FORMAT=JSON $query;
++
++--echo # using equality : pushing into WHERE
++LET $query=
++SELECT * FROM t1,v1
++WHERE t1.a=v1_x AND v1_x<2 AND v1_y>30 AND
++ (t1.a,t1.c) IN
++ (
++ SELECT t2.e,MAX(t2.g)
++ FROM t2
++ WHERE t2.e<5
++ GROUP BY t2.e
++ )
++;
++
++EVAL $no_pushdown $query;
++EVAL $query;
++EVAL EXPLAIN $query;
++EVAL EXPLAIN FORMAT=JSON $query;
++
++--echo # conjunctive subformula : pushing into WHERE
++--echo # extracted OR formula : pushing into HAVING
++LET $query=
++SELECT * FROM t1
++WHERE ((t1.b<3 OR t1.b=4) AND t1.a<3) AND
++ (t1.a,t1.b,t1.c) IN
++ (
++ SELECT t2.e,t2.f,MAX(t2.g)
++ FROM t2
++ WHERE t2.e<5
++ GROUP BY t2.e
++ )
++;
++
++EVAL $no_pushdown $query;
++EVAL $query;
++EVAL EXPLAIN $query;
++EVAL EXPLAIN FORMAT=JSON $query;
++
++--echo # conjunctive subformula using addition : pushing into HAVING
++LET $query=
++SELECT * FROM t1
++WHERE (t1.a+t1.c>41) AND
++ (t1.a,t1.c) IN
++ (
++ SELECT t2.e,MAX(t2.g)
++ FROM t2
++ WHERE t2.e<5
++ GROUP BY t2.e
++ )
++;
++
++EVAL $no_pushdown $query;
++EVAL $query;
++EVAL EXPLAIN $query;
++EVAL EXPLAIN FORMAT=JSON $query;
++
++--echo # conjunctive subformula using substitution : pushing into HAVING
++LET $query=
++SELECT * FROM t1
++WHERE (t1.c-t1.a<35) AND
++ (t1.a,t1.c) IN
++ (
++ SELECT t2.e,MAX(t2.g)
++ FROM t2
++ WHERE t2.e<5
++ GROUP BY t2.e
++ )
++;
++
++EVAL $no_pushdown $query;
++EVAL $query;
++EVAL EXPLAIN $query;
++EVAL EXPLAIN FORMAT=JSON $query;
++
++--echo # conjunctive subformula using multiplication : pushing into HAVING
++LET $query=
++SELECT * FROM t1
++WHERE (t1.c*t1.a>100) AND
++ (t1.a,t1.c) IN
++ (
++ SELECT t2.e,MAX(t2.g)
++ FROM t2
++ WHERE t2.e<5
++ GROUP BY t2.e
++ )
++;
++
++EVAL $no_pushdown $query;
++EVAL $query;
++EVAL EXPLAIN $query;
++EVAL EXPLAIN FORMAT=JSON $query;
++
++--echo # conjunctive subformula using division : pushing into HAVING
++LET $query=
++SELECT * FROM t1
++WHERE (t1.c/t1.a>30) AND
++ (t1.a,t1.c) IN
++ (
++ SELECT t2.e,MAX(t2.g)
++ FROM t2
++ WHERE t2.e<5
++ GROUP BY t2.e
++ )
++;
++
++EVAL $no_pushdown $query;
++EVAL $query;
++EVAL EXPLAIN $query;
++EVAL EXPLAIN FORMAT=JSON $query;
++
++--echo # conjunctive subformula using BETWEEN : pushing into HAVING
++LET $query=
++SELECT * FROM t1
++WHERE (t1.c BETWEEN 50 AND 100) AND
++ (t1.a,t1.c) IN
++ (
++ SELECT t2.e,MAX(t2.g)
++ FROM t2
++ WHERE t2.e<5
++ GROUP BY t2.e
++ )
++;
++
++EVAL $no_pushdown $query;
++EVAL $query;
++EVAL EXPLAIN $query;
++EVAL EXPLAIN FORMAT=JSON $query;
++
++--echo # conjunctive subformula using addition : pushing into WHERE
++LET $query=
++SELECT * FROM t1
++WHERE (t1.a+t1.b > 5) AND
++ (t1.a,t1.b,t1.c) IN
++ (
++ SELECT t2.e,t2.f,MAX(t2.g)
++ FROM t2
++ WHERE t2.e<5
++ GROUP BY t2.e,t2.f
++ )
++;
++
++EVAL $no_pushdown $query;
++EVAL $query;
++EVAL EXPLAIN $query;
++EVAL EXPLAIN FORMAT=JSON $query;
++
++--echo # conjunctive subformula using substitution : pushing into WHERE
++LET $query=
++SELECT * FROM t1
++WHERE (t1.a-t1.b > 0) AND
++ (t1.a,t1.b,t1.c) IN
++ (
++ SELECT t2.e,t2.f,MAX(t2.g)
++ FROM t2
++ WHERE t2.e<5
++ GROUP BY t2.e,t2.f
++ )
++;
++
++EVAL $no_pushdown $query;
++EVAL $query;
++EVAL EXPLAIN $query;
++EVAL EXPLAIN FORMAT=JSON $query;
++
++--echo # conjunctive subformula using multiplication : pushing into WHERE
++LET $query=
++SELECT * FROM t1
++WHERE (t1.a*t1.b > 6) AND
++ (t1.a,t1.b,t1.c) IN
++ (
++ SELECT t2.e,t2.f,MAX(t2.g)
++ FROM t2
++ WHERE t2.e<5
++ GROUP BY t2.e,t2.f
++ )
++;
++
++EVAL $no_pushdown $query;
++EVAL $query;
++EVAL EXPLAIN $query;
++EVAL EXPLAIN FORMAT=JSON $query;
++
++--echo # conjunctive subformula using division : pushing into WHERE
++LET $query=
++SELECT * FROM t1
++WHERE (t1.b/t1.a > 2) AND
++ (t1.a,t1.b,t1.c) IN
++ (
++ SELECT t2.e,t2.f,MAX(t2.g)
++ FROM t2
++ WHERE t2.e<5
++ GROUP BY t2.e,t2.f
++ )
++;
++
++EVAL $no_pushdown $query;
++EVAL $query;
++EVAL EXPLAIN $query;
++EVAL EXPLAIN FORMAT=JSON $query;
++
++--echo # conjunctive subformula using BETWEEN : pushing into WHERE
++LET $query=
++SELECT * FROM t1
++WHERE (t1.a BETWEEN 1 AND 3) AND
++ (t1.a,t1.c) IN
++ (
++ SELECT t2.e,MAX(t2.g)
++ FROM t2
++ WHERE t2.e<5
++ GROUP BY t2.e
++ )
++;
++
++EVAL $no_pushdown $query;
++EVAL $query;
++EVAL EXPLAIN $query;
++EVAL EXPLAIN FORMAT=JSON $query;
++
++--echo # conjunctive subformula : pushing into HAVING of the IN subquery
++--echo # conjunctive subformula : pushing into WHERE of the view from the IN subquery
++LET $query=
++SELECT * FROM t1
++WHERE t1.c>3 AND
++ (t1.a,t1.b,t1.c) IN
++ (
++ SELECT v2.e,MAX(v2.f),v2.max_g
++ FROM v2
++ WHERE v2.e<5
++ GROUP BY v2.e
++ )
++;
++
++EVAL $no_pushdown $query;
++EVAL $query;
++EVAL EXPLAIN $query;
++EVAL EXPLAIN FORMAT=JSON $query;
++
++--echo # conjunctive subformula : pushing into WHERE of the IN subquery
++--echo # conjunctive subformula : pushing into WHERE of the view
++--echo # from the IN subquery
++LET $query=
++SELECT * FROM t1
++WHERE t1.a>1 AND
++ (t1.a,t1.b,t1.c) IN
++ (
++ SELECT v2.e,MAX(v2.f),v2.max_g
++ FROM v2
++ WHERE v2.e<5
++ GROUP BY v2.e
++ )
++;
++
++EVAL $no_pushdown $query;
++EVAL $query;
++EVAL EXPLAIN $query;
++EVAL EXPLAIN FORMAT=JSON $query;
++
++--echo # conjunctive subformula : pushing into WHERE and HAVING
++--echo # of the IN subquery
++--echo # conjunctive subformula : pushing into WHERE of the view
++--echo # from the IN subquery
++LET $query=
++SELECT * FROM t1
++WHERE t1.a>1 AND t1.c<100 AND
++ (t1.a,t1.b,t1.c) IN
++ (
++ SELECT v2.e,MAX(v2.f),v2.max_g
++ FROM v2
++ WHERE v2.e<5
++ GROUP BY v2.e
++ )
++;
++
++EVAL $no_pushdown $query;
++EVAL $query;
++EVAL EXPLAIN $query;
++EVAL EXPLAIN FORMAT=JSON $query;
++
++--echo # conjunctive subformula : pushing into WHERE of the IN subquery
++--echo # extracted AND formula : pushing into HAVING of the derived table
++--echo # from the IN subquery
++LET $query=
++SELECT * FROM t1
++WHERE t1.a>1 AND
++ (t1.a,t1.b,t1.c) IN
++ (
++ SELECT d_tab.e,MAX(d_tab.f),d_tab.max_g
++ FROM
++ (
++ SELECT t2.e, t2.f, MAX(t2.g) AS max_g
++ FROM t2
++ GROUP BY t2.f
++ HAVING max_g>25
++ ) as d_tab
++ WHERE d_tab.e<5
++ GROUP BY d_tab.e
++ )
++;
++
++EVAL $no_pushdown $query;
++EVAL $query;
++EVAL EXPLAIN $query;
++EVAL EXPLAIN FORMAT=JSON $query;
++
++--echo # conjunctive subformula : pushing into HAVING of the derived table
++--echo # conjunctive subformula : pushing into WHERE of the IN subquery from
++--echo # the derived table
++SELECT *
++FROM t3,
++(
++ SELECT t1.a,t1.b,max(t1.c) as max_c
++ FROM t1
++ WHERE t1.a>1 AND
++ (t1.a,t1.b,t1.c) IN
++ (
++ SELECT t2.e,t2.f,MAX(t2.g)
++ FROM t2
++ WHERE t2.e<5
++ GROUP BY t2.e
++ )
++ GROUP BY t1.a
++) AS d_tab
++WHERE d_tab.a=t3.x AND d_tab.b>2;
++
++EVAL $no_pushdown $query;
++EVAL $query;
++EVAL EXPLAIN $query;
++EVAL EXPLAIN FORMAT=JSON $query;
++
++--echo # conjunctive subformula : pushing into WHERE of the derived table
++--echo # extracted AND formula : pushing into WHERE of the IN subquery from
++--echo # the derived table
++SELECT *
++FROM t3,
++(
++ SELECT t1.a,t1.b,max(t1.c) as max_c
++ FROM t1
++ WHERE t1.a>1 AND
++ (t1.a,t1.b,t1.c) IN
++ (
++ SELECT t2.e,t2.f,MAX(t2.g)
++ FROM t2
++ GROUP BY t2.e
++ HAVING t2.f<5
++ )
++ GROUP BY t1.a
++) AS d_tab
++WHERE d_tab.a=t3.x AND d_tab.a<5;
++
++EVAL $no_pushdown $query;
++EVAL $query;
++EVAL EXPLAIN $query;
++EVAL EXPLAIN FORMAT=JSON $query;
++
++--echo # conjunctive subformula : pushing into WHERE and HAVING
++--echo # of the derived table
++--echo # extracted AND formula : pushing into WHERE of the IN subquery
++--echo # from the derived table
++LET $query=
++SELECT *
++FROM t3,
++(
++ SELECT t1.a,t1.b,max(t1.c) as max_c
++ FROM t1
++ WHERE t1.a>1 AND
++ (t1.a,t1.b,t1.c) IN
++ (
++ SELECT t2.e,t2.f,MAX(t2.g)
++ FROM t2
++ GROUP BY t2.e
++ HAVING t2.f<5
++ )
++ GROUP BY t1.a
++) AS d_tab
++WHERE d_tab.a=t3.x AND d_tab.a<5 AND d_tab.max_c<70;
++
++EVAL $no_pushdown $query;
++EVAL $query;
++EVAL EXPLAIN $query;
++EVAL EXPLAIN FORMAT=JSON $query;
++
++--echo # conjunctive subformula : pushing into WHERE of the derived table
++--echo # conjunctive subformula : pushing into HAVING of the IN subquery from
++--echo # the derived table
++SELECT *
++FROM t3,
++(
++ SELECT t1.a,t1.b,max(t1.c) as max_c
++ FROM t1
++ WHERE (t1.a,t1.b,t1.c) IN
++ (
++ SELECT t2.e,t2.f,MAX(t2.g)
++ FROM t2
++ WHERE t2.f<4
++ GROUP BY t2.f
++ )
++ GROUP BY t1.a
++ HAVING t1.b<5
++) AS d_tab
++WHERE d_tab.a=t3.x AND d_tab.a<5;
++
++EVAL $no_pushdown $query;
++EVAL $query;
++EVAL EXPLAIN $query;
++EVAL EXPLAIN FORMAT=JSON $query;
++
++--echo # conjunctive subformula : pushing into WHERE
++--echo # using WINDOW FUNCTIONS : using MAX function
++LET $query=
++SELECT * FROM t1
++WHERE (t1.b>1) AND
++ (t1.b, t1.c) IN
++ (
++ SELECT t2.f, MAX(t2.g) OVER (PARTITION BY t2.f)
++ FROM t2
++ WHERE t2.e<5
++ )
++;
++
++EVAL $no_pushdown $query;
++EVAL $query;
++EVAL EXPLAIN $query;
++EVAL EXPLAIN FORMAT=JSON $query;
++
++--echo # conjunctive subformula : pushing into WHERE
++--echo # using WINDOW FUNCTIONS : using SUM function
++LET $query=
++SELECT * FROM t1
++WHERE (t1.b>1) AND
++ (t1.b, t1.c) IN
++ (
++ SELECT t2.f, CAST(SUM(t2.g) OVER (PARTITION BY t2.f) AS INT)
++ FROM t2
++ WHERE t2.e<5
++ )
++;
++
++EVAL $no_pushdown $query;
++EVAL $query;
++EVAL EXPLAIN $query;
++EVAL EXPLAIN FORMAT=JSON $query;
++
++DROP TABLE t1,t2,t3;
++DROP VIEW v1,v2;
diff --cc mysql-test/main/mysqld--help.result
index 6c997a9,0000000..3ab9b5a
mode 100644,000000..100644
--- a/mysql-test/main/mysqld--help.result
+++ b/mysql-test/main/mysqld--help.result
@@@ -1,1687 -1,0 +1,1688 @@@
+Windows bug: happens when a new line is exactly at the right offset.
+The following options may be given as the first argument:
+--print-defaults Print the program argument list and exit.
+--no-defaults Don't read default options from any option file.
+--defaults-file=# Only read default options from the given file #.
+--defaults-extra-file=# Read this file after the global files are read.
+
+ --allow-suspicious-udfs
+ Allows use of UDFs consisting of only one symbol xxx()
+ without corresponding xxx_init() or xxx_deinit(). That
+ also means that one can load any function from any
+ library, for example exit() from libc.so
+ -a, --ansi Use ANSI SQL syntax instead of MySQL syntax. This mode
+ will also set transaction isolation level 'serializable'.
+ --auto-increment-increment[=#]
+ Auto-increment columns are incremented by this
+ --auto-increment-offset[=#]
+ Offset added to Auto-increment columns. Used when
+ auto-increment-increment != 1
+ --autocommit Set default value for autocommit (0 or 1)
+ (Defaults to on; use --skip-autocommit to disable.)
+ --automatic-sp-privileges
+ Creating and dropping stored procedures alters ACLs
+ (Defaults to on; use --skip-automatic-sp-privileges to disable.)
+ --back-log=# The number of outstanding connection requests MariaDB can
+ have. This comes into play when the main MariaDB thread
+ gets very many connection requests in a very short time
+ (Automatically configured unless set explicitly)
+ -b, --basedir=name Path to installation directory. All paths are usually
+ resolved relative to this
+ --big-tables Old variable, which if set to 1, allows large result sets
+ by saving all temporary sets to disk, avoiding 'table
+ full' errors. No longer needed, as the server now handles
+ this automatically. sql_big_tables is a synonym.
+ --bind-address=name IP address to bind to.
+ --binlog-annotate-row-events
+ Tells the master to annotate RBR events with the
+ statement that caused these events
+ (Defaults to on; use --skip-binlog-annotate-row-events to disable.)
+ --binlog-cache-size=#
+ The size of the transactional cache for updates to
+ transactional engines for the binary log. If you often
+ use transactions containing many statements, you can
+ increase this to get more performance
+ --binlog-checksum=name
+ Type of BINLOG_CHECKSUM_ALG. Include checksum for log
+ events in the binary log. One of: NONE, CRC32
+ --binlog-commit-wait-count=#
+ If non-zero, binlog write will wait at most
+ binlog_commit_wait_usec microseconds for at least this
+ many commits to queue up for group commit to the binlog.
+ This can reduce I/O on the binlog and provide increased
+ opportunity for parallel apply on the slave, but too high
+ a value will decrease commit throughput.
+ --binlog-commit-wait-usec=#
+ Maximum time, in microseconds, to wait for more commits
+ to queue up for binlog group commit. Only takes effect if
+ the value of binlog_commit_wait_count is non-zero.
+ --binlog-direct-non-transactional-updates
+ Causes updates to non-transactional engines using
+ statement format to be written directly to binary log.
+ Before using this option make sure that there are no
+ dependencies between transactional and non-transactional
+ tables such as in the statement INSERT INTO t_myisam
+ SELECT * FROM t_innodb; otherwise, slaves may diverge
+ from the master.
+ --binlog-do-db=name Tells the master it should log updates for the specified
+ database, and exclude all others not explicitly
+ mentioned.
+ --binlog-file-cache-size=#
+ The size of file cache for the binary log
+ --binlog-format=name
+ What form of binary logging the master will use: either
+ ROW for row-based binary logging, STATEMENT for
+ statement-based binary logging, or MIXED. MIXED is
+ statement-based binary logging except for those
+ statements where only row-based is correct: those which
+ involve user-defined functions (i.e. UDFs) or the UUID()
+ function; for those, row-based binary logging is
+ automatically used.
+ --binlog-ignore-db=name
+ Tells the master that updates to the given database
+ should not be logged to the binary log.
+ --binlog-optimize-thread-scheduling
+ Run fast part of group commit in a single thread, to
+ optimize kernel thread scheduling. On by default. Disable
+ to run each transaction in group commit in its own
+ thread, which can be slower at very high concurrency.
+ This option is mostly for testing one algorithm versus
+ the other, and it should not normally be necessary to
+ change it.
+ (Defaults to on; use --skip-binlog-optimize-thread-scheduling to disable.)
+ --binlog-row-event-max-size=#
+ The maximum size of a row-based binary log event in
+ bytes. Rows will be grouped into events smaller than this
+ size if possible. The value has to be a multiple of 256.
+ --binlog-row-image=name
+ Controls whether rows should be logged in 'FULL',
+ 'NOBLOB' or 'MINIMAL' formats. 'FULL', means that all
+ columns in the before and after image are logged.
+ 'NOBLOB', means that mysqld avoids logging blob columns
+ whenever possible (eg, blob column was not changed or is
+ not part of primary key). 'MINIMAL', means that a PK
+ equivalent (PK columns or full row if there is no PK in
+ the table) is logged in the before image, and only
+ changed columns are logged in the after image. (Default:
+ FULL).
+ --binlog-stmt-cache-size=#
+ The size of the statement cache for updates to
+ non-transactional engines for the binary log. If you
+ often use statements updating a great number of rows, you
+ can increase this to get more performance.
+ --bootstrap Used by mysql installation scripts.
+ --bulk-insert-buffer-size=#
+ Size of tree cache used in bulk insert optimisation. Note
+ that this is a limit per thread!
+ --character-set-client-handshake
+ Don't ignore client side character set value sent during
+ handshake.
+ (Defaults to on; use --skip-character-set-client-handshake to disable.)
+ --character-set-filesystem=name
+ Set the filesystem character set.
+ -C, --character-set-server=name
+ Set the default character set.
+ --character-sets-dir=name
+ Directory where character sets are
+ -r, --chroot=name Chroot mysqld daemon during startup.
+ --collation-server=name
+ Set the default collation.
+ --column-compression-threshold=#
+ Minimum column data length eligible for compression
+ --column-compression-zlib-level=#
+ zlib compression level (1 gives best speed, 9 gives best
+ compression)
+ --column-compression-zlib-strategy=name
+ The strategy parameter is used to tune the compression
+ algorithm. Use the value DEFAULT_STRATEGY for normal
+ data, FILTERED for data produced by a filter (or
+ predictor), HUFFMAN_ONLY to force Huffman encoding only
+ (no string match), or RLE to limit match distances to one
+ (run-length encoding). Filtered data consists mostly of
+ small values with a somewhat random distribution. In this
+ case, the compression algorithm is tuned to compress them
+ better. The effect of FILTERED is to force more Huffman
+ coding and less string matching; it is somewhat
+ intermediate between DEFAULT_STRATEGY and HUFFMAN_ONLY.
+ RLE is designed to be almost as fast as HUFFMAN_ONLY, but
+ give better compression for PNG image data. The strategy
+ parameter only affects the compression ratio but not the
+ correctness of the compressed output even if it is not
+ set appropriately. FIXED prevents the use of dynamic
+ Huffman codes, allowing for a simpler decoder for special
+ applications.
+ --column-compression-zlib-wrap
+ Generate zlib header and trailer and compute adler32
+ check value. It can be used with storage engines that
+ don't provide data integrity verification to detect data
+ corruption.
+ --completion-type=name
+ The transaction completion type. One of: NO_CHAIN, CHAIN,
+ RELEASE
+ --concurrent-insert[=name]
+ Use concurrent insert with MyISAM. One of: NEVER, AUTO,
+ ALWAYS
+ --console Write error output on screen; don't remove the console
+ window on windows.
+ --core-file Write core on errors.
+ -h, --datadir=name Path to the database root directory
+ --date-format=name The DATE format (ignored)
+ --datetime-format=name
+ The DATETIME format (ignored)
+ --deadlock-search-depth-long=#
+ Long search depth for the two-step deadlock detection
+ --deadlock-search-depth-short=#
+ Short search depth for the two-step deadlock detection
+ --deadlock-timeout-long=#
+ Long timeout for the two-step deadlock detection (in
+ microseconds)
+ --deadlock-timeout-short=#
+ Short timeout for the two-step deadlock detection (in
+ microseconds)
+ --default-regex-flags=name
+ Default flags for the regex library. Any combination of:
+ DOTALL, DUPNAMES, EXTENDED, EXTRA, MULTILINE, UNGREEDY
+ --default-storage-engine=name
+ The default storage engine for new tables
+ --default-time-zone=name
+ Set the default time zone.
+ --default-tmp-storage-engine=name
+ The default storage engine for user-created temporary
+ tables
+ --default-week-format=#
+ The default week format used by WEEK() functions
+ --delay-key-write[=name]
+ Specifies how MyISAM tables handles CREATE TABLE
+ DELAY_KEY_WRITE. If set to ON, the default, any DELAY KEY
+ WRITEs are honored. The key buffer is then flushed only
+ when the table closes, speeding up writes. MyISAM tables
+ should be automatically checked upon startup in this
+ case, and --external locking should not be used, as it
+ can lead to index corruption. If set to OFF, DELAY KEY
+ WRITEs are ignored, while if set to ALL, all new opened
+ tables are treated as if created with DELAY KEY WRITEs
+ enabled.
+ --delayed-insert-limit=#
+ After inserting delayed_insert_limit rows, the INSERT
+ DELAYED handler will check if there are any SELECT
+ statements pending. If so, it allows these to execute
+ before continuing.
+ --delayed-insert-timeout=#
+ How long a INSERT DELAYED thread should wait for INSERT
+ statements before terminating
+ --delayed-queue-size=#
+ What size queue (in rows) should be allocated for
+ handling INSERT DELAYED. If the queue becomes full, any
+ client that does INSERT DELAYED will wait until there is
+ room in the queue again
+ --div-precision-increment=#
+ Precision of the result of '/' operator will be increased
+ on that value
+ --encrypt-binlog Encrypt binary logs (including relay logs)
+ --encrypt-tmp-disk-tables
+ Encrypt temporary on-disk tables (created as part of
+ query execution)
+ --encrypt-tmp-files Encrypt temporary files (created for filesort, binary log
+ cache, etc)
+ --enforce-storage-engine=name
+ Force the use of a storage engine for new tables
+ --event-scheduler[=name]
+ Enable the event scheduler. Possible values are ON, OFF,
+ and DISABLED (keep the event scheduler completely
+ deactivated, it cannot be activated run-time)
+ --expensive-subquery-limit=#
+ The maximum number of rows a subquery may examine in
+ order to be executed during optimization and used for
+ constant optimization
+ --expire-logs-days=#
+ If non-zero, binary logs will be purged after
+ expire_logs_days days; possible purges happen at startup
+ and at binary log rotation
+ --explicit-defaults-for-timestamp
+ This option causes CREATE TABLE to create all TIMESTAMP
+ columns as NULL with DEFAULT NULL attribute, Without this
+ option, TIMESTAMP columns are NOT NULL and have implicit
+ DEFAULT clauses.
+ --external-locking Use system (external) locking (disabled by default).
+ With this option enabled you can run myisamchk to test
+ (not repair) tables while the MySQL server is running.
+ Disable with --skip-external-locking.
+ --extra-max-connections=#
+ The number of connections on extra-port
+ --extra-port=# Extra port number to use for tcp connections in a
+ one-thread-per-connection manner. 0 means don't use
+ another port
+ --flashback Setup the server to use flashback. This enables binary
+ log in row mode and will enable extra logging for DDL's
+ needed by flashback feature
+ --flush Flush MyISAM tables to disk between SQL commands
+ --flush-time=# A dedicated thread is created to flush all tables at the
+ given interval
+ --ft-boolean-syntax=name
+ List of operators for MATCH ... AGAINST ( ... IN BOOLEAN
+ MODE)
+ --ft-max-word-len=# The maximum length of the word to be included in a
+ FULLTEXT index. Note: FULLTEXT indexes must be rebuilt
+ after changing this variable
+ --ft-min-word-len=# The minimum length of the word to be included in a
+ FULLTEXT index. Note: FULLTEXT indexes must be rebuilt
+ after changing this variable
+ --ft-query-expansion-limit=#
+ Number of best matches to use for query expansion
+ --ft-stopword-file=name
+ Use stopwords from this file instead of built-in list
+ --gdb Set up signals usable for debugging. Deprecated, use
+ --general-log Log connections and queries to a table or log file.
+ Defaults logging to a file 'hostname'.log or a table
+ mysql.general_logif --log-output=TABLE is used.
+ --general-log-file=name
+ Log connections and queries to given file
+ --getopt-prefix-matching
+ Recognize command-line options by their unambiguos
+ prefixes.
+ (Defaults to on; use --skip-getopt-prefix-matching to disable.)
+ --group-concat-max-len=#
+ The maximum length of the result of function
+ GROUP_CONCAT()
+ --gtid-domain-id=# Used with global transaction ID to identify logically
+ independent replication streams. When events can
+ propagate through multiple parallel paths (for example
+ multiple masters), each independent source server must
+ use a distinct domain_id. For simple tree-shaped
+ replication topologies, it can be left at its default, 0.
+ --gtid-ignore-duplicates
+ When set, different master connections in multi-source
+ replication are allowed to receive and process event
+ groups with the same GTID (when using GTID mode). Only
+ one will be applied, any others will be ignored. Within a
+ given replication domain, just the sequence number will
+ be used to decide whether a given GTID has been already
+ applied; this means it is the responsibility of the user
+ to ensure that GTID sequence numbers are strictly
+ increasing.
+ --gtid-pos-auto-engines=name
+ List of engines for which to automatically create a
+ mysql.gtid_slave_pos_ENGINE table, if a transaction using
+ that engine is replicated. This can be used to avoid
+ introducing cross-engine transactions, if engines are
+ used different from that used by table
+ mysql.gtid_slave_pos
+ --gtid-strict-mode Enforce strict seq_no ordering of events in the binary
+ log. Slave stops with an error if it encounters an event
+ that would cause it to generate an out-of-order binlog if
+ executed.
+ -?, --help Display this help and exit.
+ --histogram-size=# Number of bytes used for a histogram. If set to 0, no
+ histograms are created by ANALYZE.
+ --histogram-type=name
+ Specifies type of the histograms created by ANALYZE.
+ Possible values are: SINGLE_PREC_HB - single precision
+ height-balanced, DOUBLE_PREC_HB - double precision
+ height-balanced.
+ --host-cache-size=# How many host names should be cached to avoid resolving.
+ (Automatically configured unless set explicitly)
+ --idle-readonly-transaction-timeout=#
+ The number of seconds the server waits for read-only idle
+ transaction
+ --idle-transaction-timeout=#
+ The number of seconds the server waits for idle
+ transaction
+ --idle-write-transaction-timeout=#
+ The number of seconds the server waits for write idle
+ transaction
+ --ignore-builtin-innodb
+ Disable initialization of builtin InnoDB plugin
+ --ignore-db-dirs=name
+ Specifies a directory to add to the ignore list when
+ collecting database names from the datadir. Put a blank
+ argument to reset the list accumulated so far.
+ --init-connect=name Command(s) that are executed for each new connection
+ (unless the user has SUPER privilege)
+ --init-file=name Read SQL commands from this file at startup
+ --init-rpl-role=name
+ Set the replication role. One of: MASTER, SLAVE
+ --init-slave=name Command(s) that are executed by a slave server each time
+ the SQL thread starts
+ --interactive-timeout=#
+ The number of seconds the server waits for activity on an
+ interactive connection before closing it
+ --join-buffer-size=#
+ The size of the buffer that is used for joins
+ --join-buffer-space-limit=#
+ The limit of the space for all join buffers used by a
+ query
+ --join-cache-level=#
+ Controls what join operations can be executed with join
+ buffers. Odd numbers are used for plain join buffers
+ while even numbers are used for linked buffers
+ --keep-files-on-create
+ Don't overwrite stale .MYD and .MYI even if no directory
+ is specified
+ --key-buffer-size=# The size of the buffer used for index blocks for MyISAM
+ tables. Increase this to get better index handling (for
+ all reads and multiple writes) to as much as you can
+ afford
+ --key-cache-age-threshold=#
+ This characterizes the number of hits a hot block has to
+ be untouched until it is considered aged enough to be
+ downgraded to a warm block. This specifies the percentage
+ ratio of that number of hits to the total number of
+ blocks in key cache
+ --key-cache-block-size=#
+ The default size of key cache blocks
+ --key-cache-division-limit=#
+ The minimum percentage of warm blocks in key cache
+ --key-cache-file-hash-size=#
+ Number of hash buckets for open and changed files. If
+ you have a lot of MyISAM files open you should increase
+ this for faster flush of changes. A good value is
+ probably 1/10 of number of possible open MyISAM files.
+ --key-cache-segments=#
+ The number of segments in a key cache
+ -L, --language=name Client error messages in given language. May be given as
+ a full path. Deprecated. Use --lc-messages-dir instead.
+ --large-pages Enable support for large pages
+ --lc-messages=name Set the language used for the error messages.
+ -L, --lc-messages-dir=name
+ Directory where error messages are
+ --lc-time-names=name
+ Set the language used for the month names and the days of
+ the week.
+ --local-infile Enable LOAD DATA LOCAL INFILE
+ (Defaults to on; use --skip-local-infile to disable.)
+ --lock-wait-timeout=#
+ Timeout in seconds to wait for a lock before returning an
+ error.
+ --log-basename=name Basename for all log files and the .pid file. This sets
+ all log file names at once (in 'datadir') and is normally
+ the only option you need for specifying log files. Sets
+ names for --log-bin, --log-bin-index, --relay-log,
+ --relay-log-index, --general-log-file,
+ --log-slow-query-log-file, --log-error-file, and
+ --pid-file
+ --log-bin[=name] Log update queries in binary format. Optional argument
+ should be name for binary log. If not given
+ 'datadir'/'log-basename'-bin or 'datadir'/mysql-bin will
+ be used (the later if --log-basename is not specified).
+ We strongly recommend to use either --log-basename or
+ specify a filename to ensure that replication doesn't
+ stop if the real hostname of the computer changes.
+ --log-bin-compress Whether the binary log can be compressed
+ --log-bin-compress-min-len[=#]
+ Minimum length of sql statement(in statement mode) or
+ record(in row mode)that can be compressed.
+ --log-bin-index=name
+ File that holds the names for last binary log files.
+ --log-bin-trust-function-creators
+ If set to FALSE (the default), then when --log-bin is
+ used, creation of a stored function (or trigger) is
+ allowed only to users having the SUPER privilege and only
+ if this stored function (trigger) may not break binary
+ logging. Note that if ALL connections to this server
+ ALWAYS use row-based binary logging, the security issues
+ do not exist and the binary logging cannot break, so you
+ can safely set this to TRUE
+ --log-disabled-statements=name
+ Don't log certain types of statements to general log. Any
+ combination of: slave, sp
+ --log-error[=name] Log errors to file (instead of stdout). If file name is
+ not specified then 'datadir'/'log-basename'.err or the
+ 'pid-file' path with extension .err is used
+ --log-isam[=name] Log all MyISAM changes to file.
+ --log-output=name How logs should be written. Any combination of: NONE,
+ FILE, TABLE
+ --log-queries-not-using-indexes
+ Log queries that are executed without benefit of any
+ index to the slow log if it is open. Same as
+ log_slow_filter='not_using_index'
+ --log-short-format Don't log extra information to update and slow-query
+ logs.
+ --log-slave-updates Tells the slave to log the updates from the slave thread
+ to the binary log. You will need to turn it on if you
+ plan to daisy-chain the slaves.
+ --log-slow-admin-statements
+ Log slow OPTIMIZE, ANALYZE, ALTER and other
+ administrative statements to the slow log if it is open.
+ Resets or sets the option 'admin' in
+ log_slow_disabled_statements
+ --log-slow-disabled-statements=name
+ Don't log certain types of statements to slow log. Any
+ combination of: admin, call, slave, sp
+ --log-slow-filter=name
+ Log only certain types of queries to the slow log. If
+ variable empty alll kind of queries are logged. All
+ types are bound by slow_query_time, except
+ 'not_using_index' which is always logged if enabled. Any
+ combination of: admin, filesort, filesort_on_disk,
+ filesort_priority_queue, full_join, full_scan,
+ not_using_index, query_cache, query_cache_miss, tmp_table,
+ tmp_table_on_disk
+ --log-slow-rate-limit=#
+ Write to slow log every #th slow query. Set to 1 to log
+ everything. Increase it to reduce the size of the slow or
+ the performance impact of slow logging
+ --log-slow-slave-statements
+ Log slow statements executed by slave thread to the slow
+ log if it is open. Resets or sets the option 'slave' in
+ log_slow_disabled_statements
+ --log-slow-verbosity=name
+ Verbosity level for the slow log. Any combination of:
+ innodb, query_plan, explain
+ --log-tc=name Path to transaction coordinator log (used for
+ transactions that affect more than one storage engine,
+ when binary log is disabled).
+ --log-tc-size=# Size of transaction coordinator log.
+ -W, --log-warnings[=#]
+ Log some not critical warnings to the general log
+ file.Value can be between 0 and 11. Higher values mean
+ more verbosity
+ --long-query-time=# Log all queries that have taken more than long_query_time
+ seconds to execute to the slow query log file. The
+ argument will be treated as a decimal value with
+ microsecond precision
+ --low-priority-updates
+ INSERT/DELETE/UPDATE has lower priority than selects
+ --lower-case-table-names[=#]
+ If set to 1 table names are stored in lowercase on disk
+ and table names will be case-insensitive. Should be set
+ to 2 if you are using a case insensitive file system
+ --master-info-file=name
+ The location and name of the file that remembers the
+ master and where the I/O replication thread is in the
+ master's binlogs. Defaults to master.info
+ --master-retry-count=#
+ The number of tries the slave will make to connect to the
+ master before giving up.
+ --master-verify-checksum
+ Force checksum verification of logged events in the
+ binary log before sending them to slaves or printing them
+ in the output of SHOW BINLOG EVENTS
+ --max-allowed-packet=#
+ Max packet length to send to or receive from the server
+ --max-binlog-cache-size=#
+ Sets the total size of the transactional cache
+ --max-binlog-size=# Binary log will be rotated automatically when the size
+ exceeds this value.
+ --max-binlog-stmt-cache-size=#
+ Sets the total size of the statement cache
+ --max-connect-errors=#
+ If there is more than this number of interrupted
+ connections from a host this host will be blocked from
+ further connections
+ --max-connections=# The number of simultaneous clients allowed
+ --max-delayed-threads=#
+ Don't start more than this number of threads to handle
+ INSERT DELAYED statements. If set to zero INSERT DELAYED
+ will be not used
+ --max-digest-length=#
+ Maximum length considered for digest text.
+ --max-error-count=# Max number of errors/warnings to store for a statement
+ --max-heap-table-size=#
+ Don't allow creation of heap tables bigger than this
+ --max-join-size=# Joins that are probably going to read more than
+ max_join_size records return an error
+ --max-length-for-sort-data=#
+ Max number of bytes in sorted records
+ --max-long-data-size=#
+ The maximum BLOB length to send to server from
+ mysql_send_long_data API. Deprecated option; use
+ max_allowed_packet instead.
+ --max-prepared-stmt-count=#
+ Maximum number of prepared statements in the server
+ --max-recursive-iterations[=#]
+ Maximum number of iterations when executing recursive
+ queries
+ --max-relay-log-size=#
+ relay log will be rotated automatically when the size
+ exceeds this value. If 0 at startup, it's set to
+ max_binlog_size
+ --max-seeks-for-key=#
+ Limit assumed max number of seeks when looking up rows
+ based on a key
+ --max-session-mem-used=#
+ Amount of memory a single user session is allowed to
+ allocate. This limits the value of the session variable
+ MEM_USED
+ --max-sort-length=# The number of bytes to use when sorting BLOB or TEXT
+ values (only the first max_sort_length bytes of each
+ value are used; the rest are ignored)
+ --max-sp-recursion-depth[=#]
+ Maximum stored procedure recursion depth
+ --max-statement-time=#
+ A query that has taken more than max_statement_time
+ seconds will be aborted. The argument will be treated as
+ a decimal value with microsecond precision. A value of 0
+ (default) means no timeout
+ --max-tmp-tables=# Unused, will be removed.
+ --max-user-connections=#
+ The maximum number of active connections for a single
+ user (0 = no limit)
+ --max-write-lock-count=#
+ After this many write locks, allow some read locks to run
+ in between
+ --memlock Lock mysqld in memory.
+ --metadata-locks-cache-size=#
+ Unused
+ --metadata-locks-hash-instances=#
+ Unused
+ --min-examined-row-limit=#
+ Don't write queries to slow log that examine fewer rows
+ than that
+ --mrr-buffer-size=# Size of buffer to use when using MRR with range access
+ --multi-range-count=#
+ Ignored. Use mrr_buffer_size instead
+ --myisam-block-size=#
+ Block size to be used for MyISAM index pages
+ --myisam-data-pointer-size=#
+ Default pointer size to be used for MyISAM tables
+ --myisam-max-sort-file-size=#
+ Don't use the fast sort index method to created index if
+ the temporary file would get bigger than this
+ --myisam-mmap-size=#
+ Restricts the total memory used for memory mapping of
+ MySQL tables
+ --myisam-recover-options[=name]
+ Specifies how corrupted tables should be automatically
+ repaired. Any combination of: DEFAULT, BACKUP, FORCE,
+ QUICK, BACKUP_ALL, OFF
+ --myisam-repair-threads=#
+ If larger than 1, when repairing a MyISAM table all
+ indexes will be created in parallel, with one thread per
+ index. The value of 1 disables parallel repair
+ --myisam-sort-buffer-size=#
+ The buffer that is allocated when sorting the index when
+ doing a REPAIR or when creating indexes with CREATE INDEX
+ or ALTER TABLE
+ --myisam-stats-method=name
+ Specifies how MyISAM index statistics collection code
+ should treat NULLs. Possible values of name are
+ NULLS_UNEQUAL (default behavior for 4.1 and later),
+ NULLS_EQUAL (emulate 4.0 behavior), and NULLS_IGNORED
+ --myisam-use-mmap Use memory mapping for reading and writing MyISAM tables
+ --mysql56-temporal-format
+ Use MySQL-5.6 (instead of MariaDB-5.3) format for TIME,
+ DATETIME, TIMESTAMP columns.
+ (Defaults to on; use --skip-mysql56-temporal-format to disable.)
+ --net-buffer-length=#
+ Buffer length for TCP/IP and socket communication
+ --net-read-timeout=#
+ Number of seconds to wait for more data from a connection
+ before aborting the read
+ --net-retry-count=# If a read on a communication port is interrupted, retry
+ this many times before giving up
+ --net-write-timeout=#
+ Number of seconds to wait for a block to be written to a
+ connection before aborting the write
+ --old Use compatible behavior from previous MariaDB version.
+ See also --old-mode
+ --old-alter-table Use old, non-optimized alter table
+ --old-mode=name Used to emulate old behavior from earlier MariaDB or
+ MySQL versions. Any combination of:
+ NO_DUP_KEY_WARNINGS_WITH_IGNORE, NO_PROGRESS_INFO,
+ ZERO_DATE_TIME_CAST
+ --old-passwords Use old password encryption method (needed for 4.0 and
+ older clients)
+ --old-style-user-limits
+ Enable old-style user limits (before 5.0.3, user
+ resources were counted per each user+host vs. per
+ account).
+ --open-files-limit=#
+ If this is not 0, then mysqld will use this value to
+ reserve file descriptors to use with setrlimit(). If this
+ value is 0 or autoset then mysqld will reserve
+ max_connections*5 or max_connections + table_cache*2
+ (whichever is larger) number of file descriptors
+ (Automatically configured unless set explicitly)
+ --optimizer-prune-level=#
+ Controls the heuristic(s) applied during query
+ optimization to prune less-promising partial plans from
+ the optimizer search space. Meaning: 0 - do not apply any
+ heuristic, thus perform exhaustive search; 1 - prune
+ plans based on number of retrieved rows
+ --optimizer-search-depth=#
+ Maximum depth of search performed by the query optimizer.
+ Values larger than the number of relations in a query
+ result in better query plans, but take longer to compile
+ a query. Values smaller than the number of tables in a
+ relation result in faster optimization, but may produce
+ very bad query plans. If set to 0, the system will
+ automatically pick a reasonable value.
+ --optimizer-selectivity-sampling-limit=#
+ Controls number of record samples to check condition
+ selectivity
+ --optimizer-switch=name
+ Fine-tune the optimizer behavior. Takes a comma-separated
+ list of option=value pairs, where value is on, off, or
+ default, and options are: index_merge, index_merge_union,
+ index_merge_sort_union, index_merge_intersection,
+ index_merge_sort_intersection, engine_condition_pushdown,
+ index_condition_pushdown, derived_merge,
+ derived_with_keys, firstmatch, loosescan, materialization,
+ in_to_exists, semijoin, partial_match_rowid_merge,
+ partial_match_table_scan, subquery_cache, mrr,
+ mrr_cost_based, mrr_sort_keys, outer_join_with_cache,
+ semijoin_with_cache, join_cache_incremental,
+ join_cache_hashed, join_cache_bka,
+ optimize_join_buffer_size, table_elimination,
+ extended_keys, exists_to_in, orderby_uses_equalities,
- condition_pushdown_for_derived, split_materialized
++ condition_pushdown_for_derived, split_materialized,
++ condition_pushdown_for_subquery
+ --optimizer-use-condition-selectivity=#
+ Controls selectivity of which conditions the optimizer
+ takes into account to calculate cardinality of a partial
+ join when it searches for the best execution plan
+ Meaning: 1 - use selectivity of index backed range
+ conditions to calculate the cardinality of a partial join
+ if the last joined table is accessed by full table scan
+ or an index scan, 2 - use selectivity of index backed
+ range conditions to calculate the cardinality of a
+ partial join in any case, 3 - additionally always use
+ selectivity of range conditions that are not backed by
+ any index to calculate the cardinality of a partial join,
+ 4 - use histograms to calculate selectivity of range
+ conditions that are not backed by any index to calculate
+ the cardinality of a partial join.5 - additionally use
+ selectivity of certain non-range predicates calculated on
+ record samples
+ --performance-schema
+ Enable the performance schema.
+ --performance-schema-accounts-size=#
+ Maximum number of instrumented user@host accounts. Use 0
+ to disable, -1 for automated sizing.
+ --performance-schema-consumer-events-stages-current
+ Default startup value for the events_stages_current
+ consumer.
+ --performance-schema-consumer-events-stages-history
+ Default startup value for the events_stages_history
+ consumer.
+ --performance-schema-consumer-events-stages-history-long
+ Default startup value for the events_stages_history_long
+ consumer.
+ --performance-schema-consumer-events-statements-current
+ Default startup value for the events_statements_current
+ consumer.
+ (Defaults to on; use --skip-performance-schema-consumer-events-statements-current to disable.)
+ --performance-schema-consumer-events-statements-history
+ Default startup value for the events_statements_history
+ consumer.
+ --performance-schema-consumer-events-statements-history-long
+ Default startup value for the
+ events_statements_history_long consumer.
+ --performance-schema-consumer-events-waits-current
+ Default startup value for the events_waits_current
+ consumer.
+ --performance-schema-consumer-events-waits-history
+ Default startup value for the events_waits_history
+ consumer.
+ --performance-schema-consumer-events-waits-history-long
+ Default startup value for the events_waits_history_long
+ consumer.
+ --performance-schema-consumer-global-instrumentation
+ Default startup value for the global_instrumentation
+ consumer.
+ (Defaults to on; use --skip-performance-schema-consumer-global-instrumentation to disable.)
+ --performance-schema-consumer-statements-digest
+ Default startup value for the statements_digest consumer.
+ (Defaults to on; use --skip-performance-schema-consumer-statements-digest to disable.)
+ --performance-schema-consumer-thread-instrumentation
+ Default startup value for the thread_instrumentation
+ consumer.
+ (Defaults to on; use --skip-performance-schema-consumer-thread-instrumentation to disable.)
+ --performance-schema-digests-size=#
+ Size of the statement digest. Use 0 to disable, -1 for
+ automated sizing.
+ --performance-schema-events-stages-history-long-size=#
+ Number of rows in EVENTS_STAGES_HISTORY_LONG. Use 0 to
+ disable, -1 for automated sizing.
+ --performance-schema-events-stages-history-size=#
+ Number of rows per thread in EVENTS_STAGES_HISTORY. Use 0
+ to disable, -1 for automated sizing.
+ --performance-schema-events-statements-history-long-size=#
+ Number of rows in EVENTS_STATEMENTS_HISTORY_LONG. Use 0
+ to disable, -1 for automated sizing.
+ --performance-schema-events-statements-history-size=#
+ Number of rows per thread in EVENTS_STATEMENTS_HISTORY.
+ Use 0 to disable, -1 for automated sizing.
+ --performance-schema-events-waits-history-long-size=#
+ Number of rows in EVENTS_WAITS_HISTORY_LONG. Use 0 to
+ disable, -1 for automated sizing.
+ --performance-schema-events-waits-history-size=#
+ Number of rows per thread in EVENTS_WAITS_HISTORY. Use 0
+ to disable, -1 for automated sizing.
+ --performance-schema-hosts-size=#
+ Maximum number of instrumented hosts. Use 0 to disable,
+ -1 for automated sizing.
+ --performance-schema-instrument[=name]
+ Default startup value for a performance schema
+ instrument.
+ --performance-schema-max-cond-classes=#
+ Maximum number of condition instruments.
+ --performance-schema-max-cond-instances=#
+ Maximum number of instrumented condition objects. Use 0
+ to disable, -1 for automated sizing.
+ --performance-schema-max-digest-length=#
+ Maximum length considered for digest text, when stored in
+ performance_schema tables.
+ --performance-schema-max-file-classes=#
+ Maximum number of file instruments.
+ --performance-schema-max-file-handles=#
+ Maximum number of opened instrumented files.
+ --performance-schema-max-file-instances=#
+ Maximum number of instrumented files. Use 0 to disable,
+ -1 for automated sizing.
+ --performance-schema-max-mutex-classes=#
+ Maximum number of mutex instruments.
+ --performance-schema-max-mutex-instances=#
+ Maximum number of instrumented MUTEX objects. Use 0 to
+ disable, -1 for automated sizing.
+ --performance-schema-max-rwlock-classes=#
+ Maximum number of rwlock instruments.
+ --performance-schema-max-rwlock-instances=#
+ Maximum number of instrumented RWLOCK objects. Use 0 to
+ disable, -1 for automated sizing.
+ --performance-schema-max-socket-classes=#
+ Maximum number of socket instruments.
+ --performance-schema-max-socket-instances=#
+ Maximum number of opened instrumented sockets. Use 0 to
+ disable, -1 for automated sizing.
+ --performance-schema-max-stage-classes=#
+ Maximum number of stage instruments.
+ --performance-schema-max-statement-classes=#
+ Maximum number of statement instruments.
+ --performance-schema-max-table-handles=#
+ Maximum number of opened instrumented tables. Use 0 to
+ disable, -1 for automated sizing.
+ --performance-schema-max-table-instances=#
+ Maximum number of instrumented tables. Use 0 to disable,
+ -1 for automated sizing.
+ --performance-schema-max-thread-classes=#
+ Maximum number of thread instruments.
+ --performance-schema-max-thread-instances=#
+ Maximum number of instrumented threads. Use 0 to disable,
+ -1 for automated sizing.
+ --performance-schema-session-connect-attrs-size=#
+ Size of session attribute string buffer per thread. Use 0
+ to disable, -1 for automated sizing.
+ --performance-schema-setup-actors-size=#
+ Maximum number of rows in SETUP_ACTORS.
+ --performance-schema-setup-objects-size=#
+ Maximum number of rows in SETUP_OBJECTS.
+ --performance-schema-users-size=#
+ Maximum number of instrumented users. Use 0 to disable,
+ -1 for automated sizing.
+ --pid-file=name Pid file used by safe_mysqld
+ --plugin-dir=name Directory for plugins
+ --plugin-load=name Semicolon-separated list of plugins to load, where each
+ plugin is specified as ether a plugin_name=library_file
+ pair or only a library_file. If the latter case, all
+ plugins from a given library_file will be loaded.
+ --plugin-load-add=name
+ Optional semicolon-separated list of plugins to load.
+ This option adds to the list specified by --plugin-load
+ in an incremental way. It can be specified many times,
+ adding more plugins every time.
+ --plugin-maturity=name
+ The lowest desirable plugin maturity. Plugins less mature
+ than that will not be installed or loaded. One of:
+ unknown, experimental, alpha, beta, gamma, stable
+ -P, --port=# Port number to use for connection or 0 to default to,
+ my.cnf, $MYSQL_TCP_PORT, /etc/services, built-in default
+ (3306), whatever comes first
+ --port-open-timeout=#
+ Maximum time in seconds to wait for the port to become
+ free. (Default: No wait).
+ --preload-buffer-size=#
+ The size of the buffer that is allocated when preloading
+ indexes
+ --profiling-history-size=#
+ Number of statements about which profiling information is
+ maintained. If set to 0, no profiles are stored. See SHOW
+ PROFILES.
+ --progress-report-time=#
+ Seconds between sending progress reports to the client
+ for time-consuming statements. Set to 0 to disable
+ progress reporting.
+ --proxy-protocol-networks=name
+ Enable proxy protocol for these source networks. The
+ syntax is a comma separated list of IPv4 and IPv6
+ networks. If the network doesn't contain mask, it is
+ considered to be a single host. "*" represents all
+ networks and must the only directive on the line. String
+ "localhost" represents non-TCP local connections (Unix
+ domain socket, Windows named pipe or shared memory).
+ --query-alloc-block-size=#
+ Allocation block size for query parsing and execution
+ --query-cache-limit=#
+ Don't cache results that are bigger than this
+ --query-cache-min-res-unit=#
+ The minimum size for blocks allocated by the query cache
+ --query-cache-size=#
+ The memory allocated to store results from old queries
+ --query-cache-strip-comments
+ Strip all comments from a query before storing it in the
+ query cache
+ --query-cache-type=name
+ OFF = Don't cache or retrieve results. ON = Cache all
+ results except SELECT SQL_NO_CACHE ... queries. DEMAND =
+ Cache only SELECT SQL_CACHE ... queries
+ --query-cache-wlock-invalidate
+ Invalidate queries in query cache on LOCK for write
+ --query-prealloc-size=#
+ Persistent buffer for query parsing and execution
+ --range-alloc-block-size=#
+ Allocation block size for storing ranges during
+ optimization
+ --read-binlog-speed-limit=#
+ Maximum speed(KB/s) to read binlog from master (0 = no
+ limit)
+ --read-buffer-size=#
+ Each thread that does a sequential scan allocates a
+ buffer of this size for each table it scans. If you do
+ many sequential scans, you may want to increase this
+ value
+ --read-only Make all non-temporary tables read-only, with the
+ exception for replication (slave) threads and users with
+ the SUPER privilege
+ --read-rnd-buffer-size=#
+ When reading rows in sorted order after a sort, the rows
+ are read through this buffer to avoid a disk seeks
+ --relay-log=name The location and name to use for relay logs.
+ --relay-log-index=name
+ The location and name to use for the file that keeps a
+ list of the last relay logs
+ --relay-log-info-file=name
+ The location and name of the file that remembers where
+ the SQL replication thread is in the relay logs.
+ --relay-log-purge if disabled - do not purge relay logs. if enabled - purge
+ them as soon as they are no more needed.
+ (Defaults to on; use --skip-relay-log-purge to disable.)
+ --relay-log-recovery
+ Enables automatic relay log recovery right after the
+ database startup, which means that the IO Thread starts
+ re-fetching from the master right after the last
+ transaction processed.
+ --relay-log-space-limit=#
+ Maximum space to use for all relay logs
+ --replicate-annotate-row-events
+ Tells the slave to write annotate rows events received
+ from the master to its own binary log. Ignored if
+ log_slave_updates is not set
+ (Defaults to on; use --skip-replicate-annotate-row-events to disable.)
+ --replicate-do-db=name
+ Tells the slave thread to restrict replication to the
+ specified database. To specify more than one database,
+ use the directive multiple times, once for each database.
+ Note that this will only work if you do not use
+ cross-database queries such as UPDATE some_db.some_table
+ SET foo='bar' while having selected a different or no
+ database. If you need cross database updates to work,
+ make sure you have 3.23.28 or later, and use
+ replicate-wild-do-table=db_name.%.
+ --replicate-do-table=name
+ Tells the slave thread to restrict replication to the
+ specified table. To specify more than one table, use the
+ directive multiple times, once for each table. This will
+ work for cross-database updates, in contrast to
+ replicate-do-db.
+ --replicate-events-marked-for-skip=name
+ Whether the slave should replicate events that were
+ created with @@skip_replication=1 on the master. Default
+ REPLICATE (no events are skipped). Other values are
+ FILTER_ON_SLAVE (events will be sent by the master but
+ ignored by the slave) and FILTER_ON_MASTER (events marked
+ with @@skip_replication=1 will be filtered on the master
+ and never be sent to the slave).
+ --replicate-ignore-db=name
+ Tells the slave thread to not replicate to the specified
+ database. To specify more than one database to ignore,
+ use the directive multiple times, once for each database.
+ This option will not work if you use cross database
+ updates. If you need cross database updates to work, make
+ sure you have 3.23.28 or later, and use
+ replicate-wild-ignore-table=db_name.%.
+ --replicate-ignore-table=name
+ Tells the slave thread to not replicate to the specified
+ table. To specify more than one table to ignore, use the
+ directive multiple times, once for each table. This will
+ work for cross-database updates, in contrast to
+ replicate-ignore-db.
+ --replicate-rewrite-db=name
+ Updates to a database with a different name than the
+ original. Example:
+ replicate-rewrite-db=master_db_name->slave_db_name.
+ --replicate-same-server-id
+ In replication, if set to 1, do not skip events having
+ our server id. Default value is 0 (to break infinite
+ loops in circular replication). Can't be set to 1 if
+ --log-slave-updates is used.
+ --replicate-wild-do-table=name
+ Tells the slave thread to restrict replication to the
+ tables that match the specified wildcard pattern. To
+ specify more than one table, use the directive multiple
+ times, once for each table. This will work for
+ cross-database updates. Example:
+ replicate-wild-do-table=foo%.bar% will replicate only
+ updates to tables in all databases that start with foo
+ and whose table names start with bar.
+ --replicate-wild-ignore-table=name
+ Tells the slave thread to not replicate to the tables
+ that match the given wildcard pattern. To specify more
+ than one table to ignore, use the directive multiple
+ times, once for each table. This will work for
+ cross-database updates. Example:
+ replicate-wild-ignore-table=foo%.bar% will not do updates
+ to tables in databases that start with foo and whose
+ table names start with bar.
+ --report-host=name Hostname or IP of the slave to be reported to the master
+ during slave registration. Will appear in the output of
+ SHOW SLAVE HOSTS. Leave unset if you do not want the
+ slave to register itself with the master. Note that it is
+ not sufficient for the master to simply read the IP of
+ the slave off the socket once the slave connects. Due to
+ NAT and other routing issues, that IP may not be valid
+ for connecting to the slave from the master or other
+ hosts
+ --report-password=name
+ The account password of the slave to be reported to the
+ master during slave registration
+ --report-port=# Port for connecting to slave reported to the master
+ during slave registration. Set it only if the slave is
+ listening on a non-default port or if you have a special
+ tunnel from the master or other clients to the slave. If
+ not sure, leave this option unset
+ --report-user=name The account user name of the slave to be reported to the
+ master during slave registration
+ --rowid-merge-buff-size=#
+ The size of the buffers used [NOT] IN evaluation via
+ partial matching
+ --rpl-semi-sync-master-enabled
+ Enable semi-synchronous replication master (disabled by
+ default).
+ --rpl-semi-sync-master-timeout=#
+ The timeout value (in ms) for semi-synchronous
+ replication in the master
+ --rpl-semi-sync-master-trace-level=#
+ The tracing level for semi-sync replication.
+ --rpl-semi-sync-master-wait-no-slave
+ Wait until timeout when no semi-synchronous replication
+ slave available (enabled by default).
+ (Defaults to on; use --skip-rpl-semi-sync-master-wait-no-slave to disable.)
+ --rpl-semi-sync-master-wait-point=name
+ Should transaction wait for semi-sync ack after having
+ synced binlog, or after having committed in storage
+ engine.. One of: AFTER_SYNC, AFTER_COMMIT
+ --rpl-semi-sync-slave-delay-master
+ Only write master info file when ack is needed.
+ --rpl-semi-sync-slave-enabled
+ Enable semi-synchronous replication slave (disabled by
+ default).
+ --rpl-semi-sync-slave-kill-conn-timeout[=#]
+ Timeout for the mysql connection used to kill the slave
+ io_thread's connection on master. This timeout comes into
+ play when stop slave is executed.
+ --rpl-semi-sync-slave-trace-level=#
+ The tracing level for semi-sync replication.
+ --safe-mode Skip some optimize stages (for testing). Deprecated.
+ --safe-user-create Don't allow new user creation by the user who has no
+ write privileges to the mysql.user table.
+ --secure-auth Disallow authentication for accounts that have old
+ (pre-4.1) passwords
+ (Defaults to on; use --skip-secure-auth to disable.)
+ --secure-file-priv=name
+ Limit LOAD DATA, SELECT ... OUTFILE, and LOAD_FILE() to
+ files within specified directory
+ --server-id=# Uniquely identifies the server instance in the community
+ of replication partners
+ --session-track-schema
+ Track changes to the default schema.
+ (Defaults to on; use --skip-session-track-schema to disable.)
+ --session-track-state-change
+ Track changes to the session state.
+ --session-track-system-variables=name
+ Track changes in registered system variables.
+ --session-track-transaction-info=name
+ Track changes to the transaction attributes. OFF to
+ disable; STATE to track just transaction state (Is there
+ an active transaction? Does it have any data? etc.);
+ CHARACTERISTICS to track transaction state and report all
+ statements needed to start a transaction withthe same
+ characteristics (isolation level, read only/read
+ write,snapshot - but not any work done / data modified
+ within the transaction).
+ --show-slave-auth-info
+ Show user and password in SHOW SLAVE HOSTS on this
+ master.
+ --silent-startup Don't print [Note] to the error log during startup.
+ --skip-bdb Deprecated option; Exist only for compatibility with old
+ my.cnf files
+ --skip-grant-tables Start without grant tables. This gives all users FULL
+ ACCESS to all tables.
+ --skip-host-cache Don't cache host names.
+ --skip-name-resolve Don't resolve hostnames. All hostnames are IP's or
+ 'localhost'.
+ --skip-networking Don't allow connection with TCP/IP
+ --skip-show-database
+ Don't allow 'SHOW DATABASE' commands
+ --skip-slave-start If set, slave is not autostarted.
+ --slave-compressed-protocol
+ Use compression on master/slave protocol
+ --slave-ddl-exec-mode=name
+ How replication events should be executed. Legal values
+ are STRICT and IDEMPOTENT (default). In IDEMPOTENT mode,
+ replication will not stop for DDL operations that are
+ idempotent. This means that CREATE TABLE is treated as
+ CREATE TABLE OR REPLACE and DROP TABLE is treated as DROP
+ TABLE IF EXISTS.
+ --slave-domain-parallel-threads=#
+ Maximum number of parallel threads to use on slave for
+ events in a single replication domain. When using
+ multiple domains, this can be used to limit a single
+ domain from grabbing all threads and thus stalling other
+ domains. The default of 0 means to allow a domain to grab
+ as many threads as it wants, up to the value of
+ slave_parallel_threads.
+ --slave-exec-mode=name
+ How replication events should be executed. Legal values
+ are STRICT (default) and IDEMPOTENT. In IDEMPOTENT mode,
+ replication will not stop for operations that are
+ idempotent. For example, in row based replication
+ attempts to delete rows that doesn't exist will be
+ ignored. In STRICT mode, replication will stop on any
+ unexpected difference between the master and the slave.
+ --slave-load-tmpdir=name
+ The location where the slave should put its temporary
+ files when replicating a LOAD DATA INFILE command
+ --slave-max-allowed-packet=#
+ The maximum packet length to sent successfully from the
+ master to slave.
+ --slave-net-timeout=#
+ Number of seconds to wait for more data from any
+ master/slave connection before aborting the read
+ --slave-parallel-max-queued=#
+ Limit on how much memory SQL threads should use per
+ parallel replication thread when reading ahead in the
+ relay log looking for opportunities for parallel
+ replication. Only used when --slave-parallel-threads > 0.
+ --slave-parallel-mode=name
+ Controls what transactions are applied in parallel when
+ using --slave-parallel-threads. Possible values:
+ "optimistic" tries to apply most transactional DML in
+ parallel, and handles any conflicts with rollback and
+ retry. "conservative" limits parallelism in an effort to
+ avoid any conflicts. "aggressive" tries to maximise the
+ parallelism, possibly at the cost of increased conflict
+ rate. "minimal" only parallelizes the commit steps of
+ transactions. "none" disables parallel apply completely.
+ --slave-parallel-threads=#
+ If non-zero, number of threads to spawn to apply in
+ parallel events on the slave that were group-committed on
+ the master or were logged with GTID in different
+ replication domains. Note that these threads are in
+ addition to the IO and SQL threads, which are always
+ created by a replication slave
+ --slave-parallel-workers=#
+ Alias for slave_parallel_threads
+ --slave-run-triggers-for-rbr=name
+ Modes for how triggers in row-base replication on slave
+ side will be executed. Legal values are NO (default), YES
+ and LOGGING. NO means that trigger for RBR will not be
+ running on slave. YES and LOGGING means that triggers
+ will be running on slave, if there was not triggers
+ running on the master for the statement. LOGGING also
+ means results of that the executed triggers work will be
+ written to the binlog.
+ --slave-skip-errors=name
+ Tells the slave thread to continue replication when a
+ query event returns an error from the provided list
+ --slave-sql-verify-checksum
+ Force checksum verification of replication events after
+ reading them from relay log. Note: Events are always
+ checksum-verified by slave on receiving them from the
+ network before writing them to the relay log
+ (Defaults to on; use --skip-slave-sql-verify-checksum to disable.)
+ --slave-transaction-retries=#
+ Number of times the slave SQL thread will retry a
+ transaction in case it failed with a deadlock, elapsed
+ lock wait timeout or listed in
+ slave_transaction_retry_errors, before giving up and
+ stopping
+ --slave-transaction-retry-errors=name
+ Tells the slave thread to retry transaction for
+ replication when a query event returns an error from the
+ provided list. Deadlock and elapsed lock wait timeout
+ errors are automatically added to this list
+ --slave-transaction-retry-interval=#
+ Interval of the slave SQL thread will retry a transaction
+ in case it failed with a deadlock or elapsed lock wait
+ timeout or listed in slave_transaction_retry_errors
+ --slave-type-conversions=name
+ Set of slave type conversions that are enabled. If the
+ variable is empty, no conversions are allowed and it is
+ expected that the types match exactly. Any combination
+ of: ALL_LOSSY, ALL_NON_LOSSY
+ --slow-launch-time=#
+ If creating the thread takes longer than this value (in
+ seconds), the Slow_launch_threads counter will be
+ incremented
+ --slow-query-log Log slow queries to a table or log file. Defaults logging
+ to a file 'hostname'-slow.log or a table mysql.slow_log
+ if --log-output=TABLE is used. Must be enabled to
+ activate other slow log options.
+ --slow-query-log-file=name
+ Log slow queries to given log file. Defaults logging to
+ 'hostname'-slow.log. Must be enabled to activate other
+ slow log options
+ --socket=name Socket file to use for connection
+ --sort-buffer-size=#
+ Each thread that needs to do a sort allocates a buffer of
+ this size
+ --sql-mode=name Sets the sql mode. Any combination of: REAL_AS_FLOAT,
+ PIPES_AS_CONCAT, ANSI_QUOTES, IGNORE_SPACE,
+ IGNORE_BAD_TABLE_OPTIONS, ONLY_FULL_GROUP_BY,
+ NO_UNSIGNED_SUBTRACTION, NO_DIR_IN_CREATE, POSTGRESQL,
+ ORACLE, MSSQL, DB2, MAXDB, NO_KEY_OPTIONS,
+ NO_TABLE_OPTIONS, NO_FIELD_OPTIONS, MYSQL323, MYSQL40,
+ ANSI, NO_AUTO_VALUE_ON_ZERO, NO_BACKSLASH_ESCAPES,
+ STRICT_TRANS_TABLES, STRICT_ALL_TABLES, NO_ZERO_IN_DATE,
+ NO_ZERO_DATE, ALLOW_INVALID_DATES,
+ ERROR_FOR_DIVISION_BY_ZERO, TRADITIONAL,
+ NO_AUTO_CREATE_USER, HIGH_NOT_PRECEDENCE,
+ NO_ENGINE_SUBSTITUTION, PAD_CHAR_TO_FULL_LENGTH,
+ EMPTY_STRING_IS_NULL, SIMULTANEOUS_ASSIGNMENT
+ --stack-trace Print a symbolic stack trace on failure
+ (Defaults to on; use --skip-stack-trace to disable.)
+ --standard-compliant-cte
+ Allow only CTEs compliant to SQL standard
+ (Defaults to on; use --skip-standard-compliant-cte to disable.)
+ --stored-program-cache=#
+ The soft upper limit for number of cached stored routines
+ for one connection.
+ --strict-password-validation
+ When password validation plugins are enabled, reject
+ passwords that cannot be validated (passwords specified
+ as a hash)
+ (Defaults to on; use --skip-strict-password-validation to disable.)
+ -s, --symbolic-links
+ Enable symbolic link support.
+ --sync-binlog=# Synchronously flush binary log to disk after every #th
+ event. Use 0 (default) to disable synchronous flushing
+ --sync-frm Sync .frm files to disk on creation
+ (Defaults to on; use --skip-sync-frm to disable.)
+ --sync-master-info=#
+ Synchronously flush master info to disk after every #th
+ event. Use 0 to disable synchronous flushing
+ --sync-relay-log=# Synchronously flush relay log to disk after every #th
+ event. Use 0 to disable synchronous flushing
+ --sync-relay-log-info=#
+ Synchronously flush relay log info to disk after every
+ #th transaction. Use 0 to disable synchronous flushing
+ --sysdate-is-now Non-default option to alias SYSDATE() to NOW() to make it
+ safe-replicable. Since 5.0, SYSDATE() returns a `dynamic'
+ value different for different invocations, even within
+ the same statement.
+ --system-versioning-alter-history=name
+ Versioning ALTER TABLE mode. ERROR: Fail ALTER with
+ error; KEEP: Keep historical system rows and subject them
+ to ALTER;
+ --table-cache=# Deprecated; use --table-open-cache instead.
+ --table-definition-cache=#
+ The number of cached table definitions
+ --table-open-cache=#
+ The number of cached open tables
+ --table-open-cache-instances=#
+ Maximum number of table cache instances
+ --tc-heuristic-recover=name
+ Decision to use in heuristic recover process. One of: OFF,
+ COMMIT, ROLLBACK
+ --tcp-keepalive-interval=#
+ The interval, in seconds, between when successive
+ keep-alive packets are sent if no acknowledgement is
+ received.If set to 0, system dependent default is used.
+ (Automatically configured unless set explicitly)
+ --tcp-keepalive-probes=#
+ The number of unacknowledged probes to send before
+ considering the connection dead and notifying the
+ application layer.If set to 0, system dependent default
+ is used. (Automatically configured unless set explicitly)
+ --tcp-keepalive-time=#
+ Timeout, in milliseconds, with no activity until the
+ first TCP keep-alive packet is sent.If set to 0, system
+ dependent default is used. (Automatically configured
+ unless set explicitly)
+ --thread-cache-size=#
+ How many threads we should keep in a cache for reuse.
+ These are freed after 5 minutes of idle time
+ --thread-pool-idle-timeout=#
+ Timeout in seconds for an idle thread in the thread
+ pool.Worker thread will be shut down after timeout
+ --thread-pool-max-threads=#
+ Maximum allowed number of worker threads in the thread
+ pool
+ --thread-pool-oversubscribe=#
+ How many additional active worker threads in a group are
+ allowed.
+ --thread-pool-prio-kickup-timer=#
+ The number of milliseconds before a dequeued low-priority
+ statement is moved to the high-priority queue
+ --thread-pool-priority=name
+ Threadpool priority. High priority connections usually
+ start executing earlier than low priority.If priority set
+ to 'auto', the the actual priority(low or high) is
+ determined based on whether or not connection is inside
+ transaction.
+ --thread-pool-size=#
+ Number of thread groups in the pool. This parameter is
+ roughly equivalent to maximum number of concurrently
+ executing threads (threads in a waiting state do not
+ count as executing).
+ --thread-pool-stall-limit=#
+ Maximum query execution time in milliseconds,before an
+ executing non-yielding thread is considered stalled.If a
+ worker thread is stalled, additional worker thread may be
+ created to handle remaining clients.
+ --thread-stack=# The stack size for each thread
+ --time-format=name The TIME format (ignored)
+ --timed-mutexes Specify whether to time mutexes. Deprecated, has no
+ effect.
+ --tmp-disk-table-size=#
+ Max size for data for an internal temporary on-disk
+ MyISAM or Aria table.
+ --tmp-memory-table-size=#
+ If an internal in-memory temporary table exceeds this
+ size, MariaDB will automatically convert it to an on-disk
+ MyISAM or Aria table. Same as tmp_table_size.
+ --tmp-table-size=# Alias for tmp_memory_table_size. If an internal in-memory
+ temporary table exceeds this size, MariaDB will
+ automatically convert it to an on-disk MyISAM or Aria
+ table.
+ -t, --tmpdir=name Path for temporary files. Several paths may be specified,
+ separated by a colon (:), in this case they are used in a
+ round-robin fashion
+ --transaction-alloc-block-size=#
+ Allocation block size for transactions to be stored in
+ binary log
+ --transaction-isolation=name
+ Default transaction isolation level. One of:
+ READ-UNCOMMITTED, READ-COMMITTED, REPEATABLE-READ,
+ SERIALIZABLE
+ --transaction-prealloc-size=#
+ Persistent buffer for transactions to be stored in binary
+ log
+ --transaction-read-only
+ Default transaction access mode. True if transactions are
+ read-only.
+ --updatable-views-with-limit=name
+ YES = Don't issue an error message (warning only) if a
+ VIEW without presence of a key of the underlying table is
+ used in queries with a LIMIT clause for updating. NO =
+ Prohibit update of a VIEW, which does not contain a key
+ of the underlying table and the query uses a LIMIT clause
+ (usually get from GUI tools)
+ --use-stat-tables=name
+ Specifies how to use system statistics tables. One of:
+ NEVER, COMPLEMENTARY, PREFERABLY
+ -u, --user=name Run mysqld daemon as user.
+ --userstat Enables statistics gathering for USER_STATISTICS,
+ CLIENT_STATISTICS, INDEX_STATISTICS and TABLE_STATISTICS
+ tables in the INFORMATION_SCHEMA
+ -v, --verbose Used with --help option for detailed help.
+ -V, --version[=name]
+ Output version information and exit.
+ --wait-timeout=# The number of seconds the server waits for activity on a
+ connection before closing it
+
+Variables (--variable-name=value)
+allow-suspicious-udfs FALSE
+auto-increment-increment 1
+auto-increment-offset 1
+autocommit TRUE
+automatic-sp-privileges TRUE
+back-log 80
+big-tables FALSE
+bind-address (No default value)
+binlog-annotate-row-events TRUE
+binlog-cache-size 32768
+binlog-checksum CRC32
+binlog-commit-wait-count 0
+binlog-commit-wait-usec 100000
+binlog-direct-non-transactional-updates FALSE
+binlog-file-cache-size 16384
+binlog-format MIXED
+binlog-optimize-thread-scheduling TRUE
+binlog-row-event-max-size 8192
+binlog-row-image FULL
+binlog-stmt-cache-size 32768
+bulk-insert-buffer-size 8388608
+character-set-client-handshake TRUE
+character-set-filesystem binary
+character-sets-dir MYSQL_CHARSETSDIR/
+chroot (No default value)
+column-compression-threshold 100
+column-compression-zlib-level 6
+column-compression-zlib-strategy DEFAULT_STRATEGY
+column-compression-zlib-wrap FALSE
+completion-type NO_CHAIN
+concurrent-insert AUTO
+console TRUE
+date-format %Y-%m-%d
+datetime-format %Y-%m-%d %H:%i:%s
+deadlock-search-depth-long 15
+deadlock-search-depth-short 4
+deadlock-timeout-long 50000000
+deadlock-timeout-short 10000
+default-regex-flags
+default-storage-engine myisam
+default-time-zone (No default value)
+default-tmp-storage-engine (No default value)
+default-week-format 0
+delay-key-write ON
+delayed-insert-limit 100
+delayed-insert-timeout 300
+delayed-queue-size 1000
+div-precision-increment 4
+encrypt-binlog FALSE
+encrypt-tmp-disk-tables FALSE
+encrypt-tmp-files FALSE
+enforce-storage-engine (No default value)
+event-scheduler OFF
+expensive-subquery-limit 100
+expire-logs-days 0
+explicit-defaults-for-timestamp FALSE
+external-locking FALSE
+extra-max-connections 1
+extra-port 0
+flashback FALSE
+flush FALSE
+flush-time 0
+ft-boolean-syntax + -><()~*:""&|
+ft-max-word-len 84
+ft-min-word-len 4
+ft-query-expansion-limit 20
+ft-stopword-file (No default value)
+gdb FALSE
+general-log FALSE
+getopt-prefix-matching FALSE
+group-concat-max-len 1048576
+gtid-domain-id 0
+gtid-ignore-duplicates FALSE
+gtid-pos-auto-engines
+gtid-strict-mode FALSE
+help TRUE
+histogram-size 0
+histogram-type SINGLE_PREC_HB
+host-cache-size 279
+idle-readonly-transaction-timeout 0
+idle-transaction-timeout 0
+idle-write-transaction-timeout 0
+ignore-builtin-innodb FALSE
+ignore-db-dirs
+init-connect
+init-file (No default value)
+init-rpl-role MASTER
+init-slave
+interactive-timeout 28800
+join-buffer-size 262144
+join-buffer-space-limit 2097152
+join-cache-level 2
+keep-files-on-create FALSE
+key-buffer-size 134217728
+key-cache-age-threshold 300
+key-cache-block-size 1024
+key-cache-division-limit 100
+key-cache-file-hash-size 512
+key-cache-segments 0
+large-pages FALSE
+lc-messages en_US
+lc-messages-dir MYSQL_SHAREDIR/
+lc-time-names en_US
+local-infile TRUE
+lock-wait-timeout 86400
+log-bin (No default value)
+log-bin-compress FALSE
+log-bin-compress-min-len 256
+log-bin-index (No default value)
+log-bin-trust-function-creators FALSE
+log-disabled-statements sp
+log-error
+log-isam myisam.log
+log-output FILE
+log-queries-not-using-indexes FALSE
+log-short-format FALSE
+log-slave-updates FALSE
+log-slow-admin-statements TRUE
+log-slow-disabled-statements sp
+log-slow-filter admin,filesort,filesort_on_disk,filesort_priority_queue,full_join,full_scan,query_cache,query_cache_miss,tmp_table,tmp_table_on_disk
+log-slow-rate-limit 1
+log-slow-slave-statements TRUE
+log-slow-verbosity
+log-tc tc.log
+log-warnings 2
+long-query-time 10
+low-priority-updates FALSE
+lower-case-table-names 1
+master-info-file master.info
+master-retry-count 86400
+master-verify-checksum FALSE
+max-allowed-packet 16777216
+max-binlog-cache-size 18446744073709547520
+max-binlog-size 1073741824
+max-binlog-stmt-cache-size 18446744073709547520
+max-connect-errors 100
+max-connections 151
+max-delayed-threads 20
+max-digest-length 1024
+max-error-count 64
+max-heap-table-size 16777216
+max-join-size 18446744073709551615
+max-length-for-sort-data 1024
+max-long-data-size 16777216
+max-prepared-stmt-count 16382
+max-recursive-iterations 18446744073709551615
+max-relay-log-size 1073741824
+max-seeks-for-key 18446744073709551615
+max-session-mem-used 9223372036854775807
+max-sort-length 1024
+max-sp-recursion-depth 0
+max-statement-time 0
+max-tmp-tables 32
+max-user-connections 0
+max-write-lock-count 18446744073709551615
+memlock FALSE
+metadata-locks-cache-size 1024
+metadata-locks-hash-instances 8
+min-examined-row-limit 0
+mrr-buffer-size 262144
+multi-range-count 256
+myisam-block-size 1024
+myisam-data-pointer-size 6
+myisam-max-sort-file-size 9223372036853727232
+myisam-mmap-size 18446744073709551615
+myisam-recover-options BACKUP,QUICK
+myisam-repair-threads 1
+myisam-sort-buffer-size 134216704
+myisam-stats-method NULLS_UNEQUAL
+myisam-use-mmap FALSE
+mysql56-temporal-format TRUE
+net-buffer-length 16384
+net-read-timeout 30
+net-retry-count 10
+net-write-timeout 60
+old FALSE
+old-alter-table FALSE
+old-mode
+old-passwords FALSE
+old-style-user-limits FALSE
+optimizer-prune-level 1
+optimizer-search-depth 62
+optimizer-selectivity-sampling-limit 100
- optimizer-switch index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,index_merge_sort_intersection=off,engine_condition_pushdown=off,index_condition_pushdown=on,derived_merge=on,derived_with_keys=on,firstmatch=on,loosescan=on,materialization=on,in_to_exists=on,semijoin=on,partial_match_rowid_merge=on,partial_match_table_scan=on,subquery_cache=on,mrr=off,mrr_cost_based=off,mrr_sort_keys=off,outer_join_with_cache=on,semijoin_with_cache=on,join_cache_incremental=on,join_cache_hashed=on,join_cache_bka=on,optimize_join_buffer_size=off,table_elimination=on,extended_keys=on,exists_to_in=on,orderby_uses_equalities=on,condition_pushdown_for_derived=on,split_materialized=on
++optimizer-switch index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,index_merge_sort_intersection=off,engine_condition_pushdown=off,index_condition_pushdown=on,derived_merge=on,derived_with_keys=on,firstmatch=on,loosescan=on,materialization=on,in_to_exists=on,semijoin=on,partial_match_rowid_merge=on,partial_match_table_scan=on,subquery_cache=on,mrr=off,mrr_cost_based=off,mrr_sort_keys=off,outer_join_with_cache=on,semijoin_with_cache=on,join_cache_incremental=on,join_cache_hashed=on,join_cache_bka=on,optimize_join_buffer_size=off,table_elimination=on,extended_keys=on,exists_to_in=on,orderby_uses_equalities=on,condition_pushdown_for_derived=on,split_materialized=on,condition_pushdown_for_subquery=on
+optimizer-use-condition-selectivity 1
+performance-schema FALSE
+performance-schema-accounts-size -1
+performance-schema-consumer-events-stages-current FALSE
+performance-schema-consumer-events-stages-history FALSE
+performance-schema-consumer-events-stages-history-long FALSE
+performance-schema-consumer-events-statements-current TRUE
+performance-schema-consumer-events-statements-history FALSE
+performance-schema-consumer-events-statements-history-long FALSE
+performance-schema-consumer-events-waits-current FALSE
+performance-schema-consumer-events-waits-history FALSE
+performance-schema-consumer-events-waits-history-long FALSE
+performance-schema-consumer-global-instrumentation TRUE
+performance-schema-consumer-statements-digest TRUE
+performance-schema-consumer-thread-instrumentation TRUE
+performance-schema-digests-size -1
+performance-schema-events-stages-history-long-size -1
+performance-schema-events-stages-history-size -1
+performance-schema-events-statements-history-long-size -1
+performance-schema-events-statements-history-size -1
+performance-schema-events-waits-history-long-size -1
+performance-schema-events-waits-history-size -1
+performance-schema-hosts-size -1
+performance-schema-instrument
+performance-schema-max-cond-classes 80
+performance-schema-max-cond-instances -1
+performance-schema-max-digest-length 1024
+performance-schema-max-file-classes 50
+performance-schema-max-file-handles 32768
+performance-schema-max-file-instances -1
+performance-schema-max-mutex-classes 200
+performance-schema-max-mutex-instances -1
+performance-schema-max-rwlock-classes 40
+performance-schema-max-rwlock-instances -1
+performance-schema-max-socket-classes 10
+performance-schema-max-socket-instances -1
+performance-schema-max-stage-classes 160
+performance-schema-max-statement-classes 200
+performance-schema-max-table-handles -1
+performance-schema-max-table-instances -1
+performance-schema-max-thread-classes 50
+performance-schema-max-thread-instances -1
+performance-schema-session-connect-attrs-size -1
+performance-schema-setup-actors-size 100
+performance-schema-setup-objects-size 100
+performance-schema-users-size -1
+port 3306
+port-open-timeout 0
+preload-buffer-size 32768
+profiling-history-size 15
+progress-report-time 5
+protocol-version 10
+proxy-protocol-networks
+query-alloc-block-size 16384
+query-cache-limit 1048576
+query-cache-min-res-unit 4096
+query-cache-size 1048576
+query-cache-strip-comments FALSE
+query-cache-type OFF
+query-cache-wlock-invalidate FALSE
+query-prealloc-size 24576
+range-alloc-block-size 4096
+read-binlog-speed-limit 0
+read-buffer-size 131072
+read-only FALSE
+read-rnd-buffer-size 262144
+relay-log (No default value)
+relay-log-index (No default value)
+relay-log-info-file relay-log.info
+relay-log-purge TRUE
+relay-log-recovery FALSE
+relay-log-space-limit 0
+replicate-annotate-row-events TRUE
+replicate-events-marked-for-skip REPLICATE
+replicate-same-server-id FALSE
+report-host (No default value)
+report-password (No default value)
+report-port 0
+report-user (No default value)
+rowid-merge-buff-size 8388608
+rpl-semi-sync-master-enabled FALSE
+rpl-semi-sync-master-timeout 10000
+rpl-semi-sync-master-trace-level 32
+rpl-semi-sync-master-wait-no-slave TRUE
+rpl-semi-sync-master-wait-point AFTER_COMMIT
+rpl-semi-sync-slave-delay-master FALSE
+rpl-semi-sync-slave-enabled FALSE
+rpl-semi-sync-slave-kill-conn-timeout 5
+rpl-semi-sync-slave-trace-level 32
+safe-user-create FALSE
+secure-auth TRUE
+secure-file-priv (No default value)
+server-id 1
+session-track-schema TRUE
+session-track-state-change FALSE
+session-track-system-variables autocommit,character_set_client,character_set_connection,character_set_results,time_zone
+session-track-transaction-info OFF
+show-slave-auth-info FALSE
+silent-startup FALSE
+skip-grant-tables TRUE
+skip-name-resolve FALSE
+skip-networking FALSE
+skip-show-database FALSE
+skip-slave-start FALSE
+slave-compressed-protocol FALSE
+slave-ddl-exec-mode IDEMPOTENT
+slave-domain-parallel-threads 0
+slave-exec-mode STRICT
+slave-max-allowed-packet 1073741824
+slave-net-timeout 60
+slave-parallel-max-queued 131072
+slave-parallel-mode conservative
+slave-parallel-threads 0
+slave-parallel-workers 0
+slave-run-triggers-for-rbr NO
+slave-skip-errors OFF
+slave-sql-verify-checksum TRUE
+slave-transaction-retries 10
+slave-transaction-retry-errors 1213,1205
+slave-transaction-retry-interval 0
+slave-type-conversions
+slow-launch-time 2
+slow-query-log FALSE
+sort-buffer-size 2097152
+sql-mode STRICT_TRANS_TABLES,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION
+stack-trace TRUE
+standard-compliant-cte TRUE
+stored-program-cache 256
+strict-password-validation TRUE
+symbolic-links FALSE
+sync-binlog 0
+sync-frm FALSE
+sync-master-info 10000
+sync-relay-log 10000
+sync-relay-log-info 10000
+sysdate-is-now FALSE
+system-versioning-alter-history ERROR
+table-cache 421
+table-definition-cache 400
+table-open-cache 421
+table-open-cache-instances 8
+tc-heuristic-recover OFF
+tcp-keepalive-interval 0
+tcp-keepalive-probes 0
+tcp-keepalive-time 0
+thread-cache-size 151
+thread-pool-idle-timeout 60
+thread-pool-max-threads 65536
+thread-pool-oversubscribe 3
+thread-pool-prio-kickup-timer 1000
+thread-pool-priority auto
+thread-pool-stall-limit 500
+thread-stack 299008
+time-format %H:%i:%s
+timed-mutexes FALSE
+tmp-disk-table-size 18446744073709551615
+tmp-memory-table-size 16777216
+tmp-table-size 16777216
+transaction-alloc-block-size 8192
+transaction-isolation REPEATABLE-READ
+transaction-prealloc-size 4096
+transaction-read-only FALSE
+updatable-views-with-limit YES
+use-stat-tables NEVER
+userstat FALSE
+verbose TRUE
+wait-timeout 28800
+
+To see what values a running MySQL server is using, type
+'mysqladmin variables' instead of 'mysqld --verbose --help'.
diff --cc mysql-test/main/subselect_mat.result
index 4d425d0,0000000..463ec53
mode 100644,000000..100644
--- a/mysql-test/main/subselect_mat.result
+++ b/mysql-test/main/subselect_mat.result
@@@ -1,2788 -1,0 +1,2788 @@@
+set @subselect_mat_test_optimizer_switch_value='materialization=on,in_to_exists=off,semijoin=off';
+set @subselect_sj_mat_tmp= @@optimizer_switch;
+set optimizer_switch=ifnull(@subselect_mat_test_optimizer_switch_value, 'semijoin=on,firstmatch=on,loosescan=on,semijoin_with_cache=on');
+set optimizer_switch='mrr=on,mrr_sort_keys=on,index_condition_pushdown=on';
+set @optimizer_switch_local_default= @@optimizer_switch;
+set @save_join_cache_level=@@join_cache_level;
+set join_cache_level=1;
+drop table if exists t1, t2, t3, t4, t5, 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;
+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');
+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;
+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');
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY t1 ALL NULL NULL NULL NULL 3 100.00 Using where
+2 MATERIALIZED t2 ALL NULL NULL NULL NULL 5 100.00 Using where
+Warnings:
+Note 1003 /* select#1 */ select `test`.`t1`.`a1` AS `a1`,`test`.`t1`.`a2` AS `a2` from `test`.`t1` where <expr_cache><`test`.`t1`.`a1`>(<in_optimizer>(`test`.`t1`.`a1`,`test`.`t1`.`a1` in ( <materialize> (/* select#2 */ select `test`.`t2`.`b1` from `test`.`t2` where `test`.`t2`.`b1` > '0' ), <primary_index_lookup>(`test`.`t1`.`a1` in <temporary table> on distinct_key where `test`.`t1`.`a1` = `<subquery2>`.`b1`))))
+select * from t1 where a1 in (select b1 from t2 where b1 > '0');
+a1 a2
+1 - 01 2 - 01
+1 - 02 2 - 02
+explain extended
+select * from t1 where a1 in (select b1 from t2 where b1 > '0' group by b1);
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY t1 ALL NULL NULL NULL NULL 3 100.00 Using where
+2 MATERIALIZED t2 ALL NULL NULL NULL NULL 5 100.00 Using where
+Warnings:
+Note 1003 /* select#1 */ select `test`.`t1`.`a1` AS `a1`,`test`.`t1`.`a2` AS `a2` from `test`.`t1` where <expr_cache><`test`.`t1`.`a1`>(<in_optimizer>(`test`.`t1`.`a1`,`test`.`t1`.`a1` in ( <materialize> (/* select#2 */ select `test`.`t2`.`b1` from `test`.`t2` where `test`.`t2`.`b1` > '0' ), <primary_index_lookup>(`test`.`t1`.`a1` in <temporary table> on distinct_key where `test`.`t1`.`a1` = `<subquery2>`.`b1`))))
+select * from t1 where a1 in (select b1 from t2 where b1 > '0' group by b1);
+a1 a2
+1 - 01 2 - 01
+1 - 02 2 - 02
+explain extended
+select * from t1 where (a1, a2) in (select b1, b2 from t2 where b1 > '0' group by b1, b2);
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY t1 ALL NULL NULL NULL NULL 3 100.00 Using where
+2 MATERIALIZED t2 ALL NULL NULL NULL NULL 5 100.00 Using where
+Warnings:
+Note 1003 /* select#1 */ select `test`.`t1`.`a1` AS `a1`,`test`.`t1`.`a2` AS `a2` from `test`.`t1` where <expr_cache><`test`.`t1`.`a1`,`test`.`t1`.`a2`>(<in_optimizer>((`test`.`t1`.`a1`,`test`.`t1`.`a2`),(`test`.`t1`.`a1`,`test`.`t1`.`a2`) in ( <materialize> (/* select#2 */ select `test`.`t2`.`b1`,`test`.`t2`.`b2` from `test`.`t2` where `test`.`t2`.`b1` > '0' ), <primary_index_lookup>(`test`.`t1`.`a1` in <temporary table> on distinct_key where `test`.`t1`.`a1` = `<subquery2>`.`b1` and `test`.`t1`.`a2` = `<subquery2>`.`b2`))))
+select * from t1 where (a1, a2) in (select b1, b2 from t2 where b1 > '0' group by b1, b2);
+a1 a2
+1 - 01 2 - 01
+1 - 02 2 - 02
+explain extended
+select * from t1 where (a1, a2) in (select b1, min(b2) from t2 where b1 > '0' group by b1);
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY t1 ALL NULL NULL NULL NULL 3 100.00 Using where
+2 MATERIALIZED t2 ALL NULL NULL NULL NULL 5 100.00 Using where; Using temporary
+Warnings:
+Note 1003 /* select#1 */ select `test`.`t1`.`a1` AS `a1`,`test`.`t1`.`a2` AS `a2` from `test`.`t1` where <expr_cache><`test`.`t1`.`a1`,`test`.`t1`.`a2`>(<in_optimizer>((`test`.`t1`.`a1`,`test`.`t1`.`a2`),(`test`.`t1`.`a1`,`test`.`t1`.`a2`) in ( <materialize> (/* select#2 */ select `test`.`t2`.`b1`,min(`test`.`t2`.`b2`) from `test`.`t2` where `test`.`t2`.`b1` > '0' group by `test`.`t2`.`b1` ), <primary_index_lookup>(`test`.`t1`.`a1` in <temporary table> on distinct_key where `test`.`t1`.`a1` = `<subquery2>`.`b1` and `test`.`t1`.`a2` = `<subquery2>`.`min(b2)`))))
+select * from t1 where (a1, a2) in (select b1, min(b2) from t2 where b1 > '0' group by b1);
+a1 a2
+1 - 01 2 - 01
+1 - 02 2 - 02
+explain extended
+select * from t1i where a1 in (select b1 from t2i where b1 > '0');
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY t1i index NULL _it1_idx # NULL 3 100.00 Using where;
+2 MATERIALIZED t2i index it2i1,it2i3 it2i1 # NULL 5 100.00 Using where;
+Warnings:
+Note 1003 /* select#1 */ select `test`.`t1i`.`a1` AS `a1`,`test`.`t1i`.`a2` AS `a2` from `test`.`t1i` where <expr_cache><`test`.`t1i`.`a1`>(<in_optimizer>(`test`.`t1i`.`a1`,`test`.`t1i`.`a1` in ( <materialize> (/* select#2 */ select `test`.`t2i`.`b1` from `test`.`t2i` where `test`.`t2i`.`b1` > '0' ), <primary_index_lookup>(`test`.`t1i`.`a1` in <temporary table> on distinct_key where `test`.`t1i`.`a1` = `<subquery2>`.`b1`))))
+select * from t1i where a1 in (select b1 from t2i where b1 > '0');
+a1 a2
+1 - 01 2 - 01
+1 - 02 2 - 02
+explain extended
+select * from t1i where a1 in (select max(b1) from t2i where b1 > '0' group by b1);
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY t1i index NULL # 18 # 3 100.00 #
+2 MATERIALIZED t2i range it2i1,it2i3 # 9 # 5 100.00 #
+Warnings:
+Note 1003 /* select#1 */ select `test`.`t1i`.`a1` AS `a1`,`test`.`t1i`.`a2` AS `a2` from `test`.`t1i` where <expr_cache><`test`.`t1i`.`a1`>(<in_optimizer>(`test`.`t1i`.`a1`,`test`.`t1i`.`a1` in ( <materialize> (/* select#2 */ select max(`test`.`t2i`.`b1`) from `test`.`t2i` where `test`.`t2i`.`b1` > '0' group by `test`.`t2i`.`b1` ), <primary_index_lookup>(`test`.`t1i`.`a1` in <temporary table> on distinct_key where `test`.`t1i`.`a1` = `<subquery2>`.`max(b1)`))))
+select * from t1i where a1 in (select max(b1) from t2i where b1 > '0' group by b1);
+a1 a2
+1 - 01 2 - 01
+1 - 02 2 - 02
+explain extended
+select * from t1i where (a1, a2) in (select b1, b2 from t2i where b1 > '0');
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY t1i index NULL _it1_idx # NULL 3 100.00 Using where;
+2 MATERIALIZED t2i index it2i1,it2i3 it2i3 # NULL 5 100.00 Using where;
+Warnings:
+Note 1003 /* select#1 */ select `test`.`t1i`.`a1` AS `a1`,`test`.`t1i`.`a2` AS `a2` from `test`.`t1i` where <expr_cache><`test`.`t1i`.`a1`,`test`.`t1i`.`a2`>(<in_optimizer>((`test`.`t1i`.`a1`,`test`.`t1i`.`a2`),(`test`.`t1i`.`a1`,`test`.`t1i`.`a2`) in ( <materialize> (/* select#2 */ select `test`.`t2i`.`b1`,`test`.`t2i`.`b2` from `test`.`t2i` where `test`.`t2i`.`b1` > '0' ), <primary_index_lookup>(`test`.`t1i`.`a1` in <temporary table> on distinct_key where `test`.`t1i`.`a1` = `<subquery2>`.`b1` and `test`.`t1i`.`a2` = `<subquery2>`.`b2`))))
+select * from t1i where (a1, a2) in (select b1, b2 from t2i where b1 > '0');
+a1 a2
+1 - 01 2 - 01
+1 - 02 2 - 02
+explain extended
+select * from t1i where (a1, a2) in (select b1, max(b2) from t2i where b1 > '0' group by b1);
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY t1i index NULL # # # 3 100.00 #
+2 MATERIALIZED t2i range it2i1,it2i3 # # # 3 100.00 #
+Warnings:
+Note 1003 /* select#1 */ select `test`.`t1i`.`a1` AS `a1`,`test`.`t1i`.`a2` AS `a2` from `test`.`t1i` where <expr_cache><`test`.`t1i`.`a1`,`test`.`t1i`.`a2`>(<in_optimizer>((`test`.`t1i`.`a1`,`test`.`t1i`.`a2`),(`test`.`t1i`.`a1`,`test`.`t1i`.`a2`) in ( <materialize> (/* select#2 */ select `test`.`t2i`.`b1`,max(`test`.`t2i`.`b2`) from `test`.`t2i` where `test`.`t2i`.`b1` > '0' group by `test`.`t2i`.`b1` ), <primary_index_lookup>(`test`.`t1i`.`a1` in <temporary table> on distinct_key where `test`.`t1i`.`a1` = `<subquery2>`.`b1` and `test`.`t1i`.`a2` = `<subquery2>`.`max(b2)`))))
+select * from t1i where (a1, a2) in (select b1, max(b2) from t2i where b1 > '0' group by b1);
+a1 a2
+1 - 01 2 - 01
+1 - 02 2 - 02
+explain extended
+select * from t1i where (a1, a2) in (select b1, min(b2) from t2i where b1 > '0' group by b1);
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY t1i index NULL # # # 3 100.00 #
+2 MATERIALIZED t2i range it2i1,it2i3 # # # 3 100.00 #
+Warnings:
+Note 1003 /* select#1 */ select `test`.`t1i`.`a1` AS `a1`,`test`.`t1i`.`a2` AS `a2` from `test`.`t1i` where <expr_cache><`test`.`t1i`.`a1`,`test`.`t1i`.`a2`>(<in_optimizer>((`test`.`t1i`.`a1`,`test`.`t1i`.`a2`),(`test`.`t1i`.`a1`,`test`.`t1i`.`a2`) in ( <materialize> (/* select#2 */ select `test`.`t2i`.`b1`,min(`test`.`t2i`.`b2`) from `test`.`t2i` where `test`.`t2i`.`b1` > '0' group by `test`.`t2i`.`b1` ), <primary_index_lookup>(`test`.`t1i`.`a1` in <temporary table> on distinct_key where `test`.`t1i`.`a1` = `<subquery2>`.`b1` and `test`.`t1i`.`a2` = `<subquery2>`.`min(b2)`))))
+select * from t1i where (a1, a2) in (select b1, min(b2) from t2i where b1 > '0' group by b1);
+a1 a2
+1 - 01 2 - 01
+1 - 02 2 - 02
+explain extended
+select * from t1 where (a1, a2) in (select b1, max(b2) from t2i group by b1);
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY t1 ALL NULL NULL NULL NULL 3 100.00 Using where
+2 MATERIALIZED t2i range NULL it2i3 9 NULL 3 100.00 Using index for group-by
+Warnings:
+Note 1003 /* select#1 */ select `test`.`t1`.`a1` AS `a1`,`test`.`t1`.`a2` AS `a2` from `test`.`t1` where <expr_cache><`test`.`t1`.`a1`,`test`.`t1`.`a2`>(<in_optimizer>((`test`.`t1`.`a1`,`test`.`t1`.`a2`),(`test`.`t1`.`a1`,`test`.`t1`.`a2`) in ( <materialize> (/* select#2 */ select `test`.`t2i`.`b1`,max(`test`.`t2i`.`b2`) from `test`.`t2i` group by `test`.`t2i`.`b1` ), <primary_index_lookup>(`test`.`t1`.`a1` in <temporary table> on distinct_key where `test`.`t1`.`a1` = `<subquery2>`.`b1` and `test`.`t1`.`a2` = `<subquery2>`.`max(b2)`))))
+select * from t1 where (a1, a2) in (select b1, max(b2) from t2i group by b1);
+a1 a2
+1 - 01 2 - 01
+1 - 02 2 - 02
+prepare st1 from "explain select * from t1 where (a1, a2) in (select b1, max(b2) from t2i group by b1)";
+execute st1;
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t1 ALL NULL NULL NULL NULL 3 Using where
+2 MATERIALIZED t2i range NULL it2i3 9 NULL 3 Using index for group-by
+execute st1;
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t1 ALL NULL NULL NULL NULL 3 Using where
+2 MATERIALIZED t2i range NULL it2i3 9 NULL 3 Using index for group-by
+prepare st2 from "select * from t1 where (a1, a2) in (select b1, max(b2) from t2i group by b1)";
+execute st2;
+a1 a2
+1 - 01 2 - 01
+1 - 02 2 - 02
+execute st2;
+a1 a2
+1 - 01 2 - 01
+1 - 02 2 - 02
+explain extended
+select * from t1 where (a1, a2) in (select b1, min(b2) from t2i where b1 > '0' group by b1);
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY t1 ALL NULL NULL NULL NULL 3 100.00 Using where
+2 MATERIALIZED t2i range it2i1,it2i3 it2i3 18 NULL 3 100.00 Using where; Using index for group-by
+Warnings:
+Note 1003 /* select#1 */ select `test`.`t1`.`a1` AS `a1`,`test`.`t1`.`a2` AS `a2` from `test`.`t1` where <expr_cache><`test`.`t1`.`a1`,`test`.`t1`.`a2`>(<in_optimizer>((`test`.`t1`.`a1`,`test`.`t1`.`a2`),(`test`.`t1`.`a1`,`test`.`t1`.`a2`) in ( <materialize> (/* select#2 */ select `test`.`t2i`.`b1`,min(`test`.`t2i`.`b2`) from `test`.`t2i` where `test`.`t2i`.`b1` > '0' group by `test`.`t2i`.`b1` ), <primary_index_lookup>(`test`.`t1`.`a1` in <temporary table> on distinct_key where `test`.`t1`.`a1` = `<subquery2>`.`b1` and `test`.`t1`.`a2` = `<subquery2>`.`min(b2)`))))
+select * from t1 where (a1, a2) in (select b1, min(b2) from t2i where b1 > '0' group by b1);
+a1 a2
+1 - 01 2 - 01
+1 - 02 2 - 02
+select * from t1 where (a1, a2) in (select b1, min(b2) from t2i limit 1,1);
+ERROR 42000: This version of MariaDB doesn't yet support 'LIMIT & IN/ALL/ANY/SOME subquery'
+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;
+a1 a2
+1 - 01 2 - 01
+1 - 02 2 - 02
+set @@optimizer_switch=@optimizer_switch_local_default;
+set @@optimizer_switch='semijoin=off';
+execute st1;
+a1 a2
+1 - 01 2 - 01
+1 - 02 2 - 02
+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;
+a1 a2
+1 - 01 2 - 01
+1 - 02 2 - 02
+set @@optimizer_switch=@optimizer_switch_local_default;
+set @@optimizer_switch='materialization=off,in_to_exists=on';
+execute st1;
+a1 a2
+1 - 01 2 - 01
+1 - 02 2 - 02
+set @@optimizer_switch=@save_optimizer_switch;
+explain extended
+select * from t1 where (a1, a2) in (select b1, b2 from t2 order by b1, b2);
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY t1 ALL NULL NULL NULL NULL 3 100.00 Using where
+2 MATERIALIZED t2 ALL NULL NULL NULL NULL 5 100.00
+Warnings:
+Note 1003 /* select#1 */ select `test`.`t1`.`a1` AS `a1`,`test`.`t1`.`a2` AS `a2` from `test`.`t1` where <expr_cache><`test`.`t1`.`a1`,`test`.`t1`.`a2`>(<in_optimizer>((`test`.`t1`.`a1`,`test`.`t1`.`a2`),(`test`.`t1`.`a1`,`test`.`t1`.`a2`) in ( <materialize> (/* select#2 */ select `test`.`t2`.`b1`,`test`.`t2`.`b2` from `test`.`t2` order by `test`.`t2`.`b1`,`test`.`t2`.`b2` ), <primary_index_lookup>(`test`.`t1`.`a1` in <temporary table> on distinct_key where `test`.`t1`.`a1` = `<subquery2>`.`b1` and `test`.`t1`.`a2` = `<subquery2>`.`b2`))))
+select * from t1 where (a1, a2) in (select b1, b2 from t2 order by b1, b2);
+a1 a2
+1 - 01 2 - 01
+1 - 02 2 - 02
+explain extended
+select * from t1i where (a1, a2) in (select b1, b2 from t2i order by b1, b2);
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY t1i index NULL it1i3 18 NULL 3 100.00 Using where; Using index
+2 MATERIALIZED t2i index NULL it2i3 18 NULL 5 100.00 Using index
+Warnings:
+Note 1003 /* select#1 */ select `test`.`t1i`.`a1` AS `a1`,`test`.`t1i`.`a2` AS `a2` from `test`.`t1i` where <expr_cache><`test`.`t1i`.`a1`,`test`.`t1i`.`a2`>(<in_optimizer>((`test`.`t1i`.`a1`,`test`.`t1i`.`a2`),(`test`.`t1i`.`a1`,`test`.`t1i`.`a2`) in ( <materialize> (/* select#2 */ select `test`.`t2i`.`b1`,`test`.`t2i`.`b2` from `test`.`t2i` order by `test`.`t2i`.`b1`,`test`.`t2i`.`b2` ), <primary_index_lookup>(`test`.`t1i`.`a1` in <temporary table> on distinct_key where `test`.`t1i`.`a1` = `<subquery2>`.`b1` and `test`.`t1i`.`a2` = `<subquery2>`.`b2`))))
+select * from t1i where (a1, a2) in (select b1, b2 from t2i order by b1, b2);
+a1 a2
+1 - 01 2 - 01
+1 - 02 2 - 02
+/******************************************************************************
+* 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;
+Warnings:
+Warning 1354 View merge algorithm can't be used here for now (assumed undefined algorithm)
+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);
+b1 c2
+1 - 02 2 - 01
+1 - 02 2 - 01
+1 - 03 2 - 01
+1 - 03 2 - 02
+select * from v1 where (c2, b1) in (select distinct c2, b1 from v2 where b1 is not null);
+b1 c2
+1 - 02 2 - 01
+1 - 02 2 - 01
+1 - 03 2 - 01
+1 - 03 2 - 02
+select * from v1m where (c2, b1) in (select c2, b1 from v2m where b1 is not null);
+b1 c2
+1 - 02 2 - 01
+1 - 02 2 - 01
+1 - 03 2 - 01
+1 - 03 2 - 02
+select * from v1m where (c2, b1) in (select distinct c2, b1 from v2m where b1 is not null);
+b1 c2
+1 - 02 2 - 01
+1 - 02 2 - 01
+1 - 03 2 - 01
+1 - 03 2 - 02
+drop view v1, v2, v1m, v2m;
+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'));
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY t1 ALL NULL NULL NULL NULL 3 100.00 Using where
+3 MATERIALIZED t3 ALL NULL NULL NULL NULL 4 100.00 Using where
+4 MATERIALIZED t2i index it2i2 it2i3 18 NULL 5 100.00 Using where; Using index
+2 MATERIALIZED t2 ALL NULL NULL NULL NULL 5 100.00 Using where
+Warnings:
+Note 1003 /* select#1 */ select `test`.`t1`.`a1` AS `a1`,`test`.`t1`.`a2` AS `a2` from `test`.`t1` where <expr_cache><`test`.`t1`.`a1`,`test`.`t1`.`a2`>(<in_optimizer>((`test`.`t1`.`a1`,`test`.`t1`.`a2`),(`test`.`t1`.`a1`,`test`.`t1`.`a2`) in ( <materialize> (/* select#2 */ select `test`.`t2`.`b1`,`test`.`t2`.`b2` from `test`.`t2` where `test`.`t2`.`b1` > '0' ), <primary_index_lookup>(`test`.`t1`.`a1` in <temporary table> on distinct_key where `test`.`t1`.`a1` = `<subquery2>`.`b1` and `test`.`t1`.`a2` = `<subquery2>`.`b2`)))) and <expr_cache><`test`.`t1`.`a1`,`test`.`t1`.`a2`>(<in_optimizer>((`test`.`t1`.`a1`,`test`.`t1`.`a2`),(`test`.`t1`.`a1`,`test`.`t1`.`a2`) in ( <materialize> (/* select#3 */ select `test`.`t3`.`c1`,`test`.`t3`.`c2` from `test`.`t3` where <expr_cache><`test`.`t3`.`c1`,`test`.`t3`.`c2`>(<in_optimizer>((`test`.`t3`.`c1`,`test`.`t3`.`c2`),(`test`.`t3`.`c1`,`test`.`t3`.`c2`) in ( <materialize> (/* select#4 */ select `test`.`t2i`.`b1`,`test`.`t2i`.`b2` from
`test`.`
t2i` where `test`.`t2i`.`b2` > '0' ), <primary_index_lookup>(`test`.`t3`.`c1` in <temporary table> on distinct_key where `test`.`t3`.`c1` = `<subquery4>`.`b1` and `test`.`t3`.`c2` = `<subquery4>`.`b2`)))) ), <primary_index_lookup>(`test`.`t1`.`a1` in <temporary table> on distinct_key where `test`.`t1`.`a1` = `<subquery3>`.`c1` and `test`.`t1`.`a2` = `<subquery3>`.`c2`))))
+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'));
+a1 a2
+1 - 01 2 - 01
+1 - 02 2 - 02
+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'));
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY t1i index NULL # # # 3 100.00 #
+3 MATERIALIZED t3i index NULL # # # 4 100.00 #
+4 MATERIALIZED t2i index it2i2 # # # 5 100.00 #
+2 MATERIALIZED t2i index it2i1,it2i3 # # # 5 100.00 #
+Warnings:
+Note 1003 /* select#1 */ select `test`.`t1i`.`a1` AS `a1`,`test`.`t1i`.`a2` AS `a2` from `test`.`t1i` where <expr_cache><`test`.`t1i`.`a1`,`test`.`t1i`.`a2`>(<in_optimizer>((`test`.`t1i`.`a1`,`test`.`t1i`.`a2`),(`test`.`t1i`.`a1`,`test`.`t1i`.`a2`) in ( <materialize> (/* select#2 */ select `test`.`t2i`.`b1`,`test`.`t2i`.`b2` from `test`.`t2i` where `test`.`t2i`.`b1` > '0' ), <primary_index_lookup>(`test`.`t1i`.`a1` in <temporary table> on distinct_key where `test`.`t1i`.`a1` = `<subquery2>`.`b1` and `test`.`t1i`.`a2` = `<subquery2>`.`b2`)))) and <expr_cache><`test`.`t1i`.`a1`,`test`.`t1i`.`a2`>(<in_optimizer>((`test`.`t1i`.`a1`,`test`.`t1i`.`a2`),(`test`.`t1i`.`a1`,`test`.`t1i`.`a2`) in ( <materialize> (/* select#3 */ select `test`.`t3i`.`c1`,`test`.`t3i`.`c2` from `test`.`t3i` where <expr_cache><`test`.`t3i`.`c1`,`test`.`t3i`.`c2`>(<in_optimizer>((`test`.`t3i`.`c1`,`test`.`t3i`.`c2`),(`test`.`t3i`.`c1`,`test`.`t3i`.`c2`) in ( <materialize> (/* select#4 */ select `test`.`t2
i`.`b1`,
`test`.`t2i`.`b2` from `test`.`t2i` where `test`.`t2i`.`b2` > '0' ), <primary_index_lookup>(`test`.`t3i`.`c1` in <temporary table> on distinct_key where `test`.`t3i`.`c1` = `<subquery4>`.`b1` and `test`.`t3i`.`c2` = `<subquery4>`.`b2`)))) ), <primary_index_lookup>(`test`.`t1i`.`a1` in <temporary table> on distinct_key where `test`.`t1i`.`a1` = `<subquery3>`.`c1` and `test`.`t1i`.`a2` = `<subquery3>`.`c2`))))
+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'));
+a1 a2
+1 - 01 2 - 01
+1 - 02 2 - 02
+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'));
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY t1 ALL NULL NULL NULL NULL 3 100.00 Using where
+5 MATERIALIZED t3 ALL NULL NULL NULL NULL 4 100.00 Using where
+6 MATERIALIZED t2i index it2i2 it2i3 18 NULL 5 100.00 Using where; Using index
+2 MATERIALIZED t2 ALL NULL NULL NULL NULL 5 100.00 Using where
+4 MATERIALIZED t3 ALL NULL NULL NULL NULL 4 100.00 Using where
+3 MATERIALIZED t3 ALL NULL NULL NULL NULL 4 100.00 Using where
+Warnings:
+Note 1003 /* select#1 */ select `test`.`t1`.`a1` AS `a1`,`test`.`t1`.`a2` AS `a2` from `test`.`t1` where <expr_cache><`test`.`t1`.`a1`,`test`.`t1`.`a2`>(<in_optimizer>((`test`.`t1`.`a1`,`test`.`t1`.`a2`),(`test`.`t1`.`a1`,`test`.`t1`.`a2`) in ( <materialize> (/* select#2 */ select `test`.`t2`.`b1`,`test`.`t2`.`b2` from `test`.`t2` where <expr_cache><`test`.`t2`.`b2`>(<in_optimizer>(`test`.`t2`.`b2`,`test`.`t2`.`b2` in ( <materialize> (/* select#3 */ select `test`.`t3`.`c2` from `test`.`t3` where `test`.`t3`.`c2` like '%02' ), <primary_index_lookup>(`test`.`t2`.`b2` in <temporary table> on distinct_key where `test`.`t2`.`b2` = `<subquery3>`.`c2`)))) or <expr_cache><`test`.`t2`.`b2`>(<in_optimizer>(`test`.`t2`.`b2`,`test`.`t2`.`b2` in ( <materialize> (/* select#4 */ select `test`.`t3`.`c2` from `test`.`t3` where `test`.`t3`.`c2` like '%03' ), <primary_index_lookup>(`test`.`t2`.`b2` in <temporary table> on distinct_key where `test`.`t2`.`b2` = `<subquery4>`.`c2`)))) ), <primar
y_index_
lookup>(`test`.`t1`.`a1` in <temporary table> on distinct_key where `test`.`t1`.`a1` = `<subquery2>`.`b1` and `test`.`t1`.`a2` = `<subquery2>`.`b2`)))) and <expr_cache><`test`.`t1`.`a1`,`test`.`t1`.`a2`>(<in_optimizer>((`test`.`t1`.`a1`,`test`.`t1`.`a2`),(`test`.`t1`.`a1`,`test`.`t1`.`a2`) in ( <materialize> (/* select#5 */ select `test`.`t3`.`c1`,`test`.`t3`.`c2` from `test`.`t3` where <expr_cache><`test`.`t3`.`c1`,`test`.`t3`.`c2`>(<in_optimizer>((`test`.`t3`.`c1`,`test`.`t3`.`c2`),(`test`.`t3`.`c1`,`test`.`t3`.`c2`) in ( <materialize> (/* select#6 */ select `test`.`t2i`.`b1`,`test`.`t2i`.`b2` from `test`.`t2i` where `test`.`t2i`.`b2` > '0' ), <primary_index_lookup>(`test`.`t3`.`c1` in <temporary table> on distinct_key where `test`.`t3`.`c1` = `<subquery6>`.`b1` and `test`.`t3`.`c2` = `<subquery6>`.`b2`)))) ), <primary_index_lookup>(`test`.`t1`.`a1` in <temporary table> on distinct_key where `test`.`t1`.`a1` = `<subquery5>`.`c1` and `test`.`t1`.`a2` = `<subquery5>`.`c2`)))
)
+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'));
+a1 a2
+1 - 02 2 - 02
+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'));
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY t1 ALL NULL NULL NULL NULL 3 100.00 Using where
+5 MATERIALIZED t3c ALL NULL NULL NULL NULL 4 100.00 Using where
+6 MATERIALIZED t2i index it2i2 it2i3 18 NULL 5 100.00 Using where; Using index
+2 DEPENDENT SUBQUERY t2 ALL NULL NULL NULL NULL 5 100.00 Using where
+4 MATERIALIZED t3b ALL NULL NULL NULL NULL 4 100.00 Using where
+3 DEPENDENT SUBQUERY t3a ALL NULL NULL NULL NULL 4 100.00 Using where
+Warnings:
+Note 1276 Field or reference 'test.t1.a1' of SELECT #3 was resolved in SELECT #1
+Note 1003 /* select#1 */ select `test`.`t1`.`a1` AS `a1`,`test`.`t1`.`a2` AS `a2` from `test`.`t1` where <expr_cache><`test`.`t1`.`a1`,`test`.`t1`.`a2`>(<in_optimizer>((`test`.`t1`.`a1`,`test`.`t1`.`a2`),<exists>(/* select#2 */ select `test`.`t2`.`b1`,`test`.`t2`.`b2` from `test`.`t2` where (<expr_cache><`test`.`t2`.`b2`,`test`.`t1`.`a1`>(<in_optimizer>(`test`.`t2`.`b2`,<exists>(/* select#3 */ select `test`.`t3a`.`c2` from `test`.`t3` `t3a` where `test`.`t3a`.`c1` = `test`.`t1`.`a1` and <cache>(`test`.`t2`.`b2`) = `test`.`t3a`.`c2`))) or <expr_cache><`test`.`t2`.`b2`>(<in_optimizer>(`test`.`t2`.`b2`,`test`.`t2`.`b2` in ( <materialize> (/* select#4 */ select `test`.`t3b`.`c2` from `test`.`t3` `t3b` where `test`.`t3b`.`c2` like '%03' ), <primary_index_lookup>(`test`.`t2`.`b2` in <temporary table> on distinct_key where `test`.`t2`.`b2` = `<subquery4>`.`c2`))))) and <cache>(`test`.`t1`.`a1`) = `test`.`t2`.`b1` and <cache>(`test`.`t1`.`a2`) = `test`.`t2`.`b2`))) and <expr_cache>
<`test`.
`t1`.`a1`,`test`.`t1`.`a2`>(<in_optimizer>((`test`.`t1`.`a1`,`test`.`t1`.`a2`),(`test`.`t1`.`a1`,`test`.`t1`.`a2`) in ( <materialize> (/* select#5 */ select `test`.`t3c`.`c1`,`test`.`t3c`.`c2` from `test`.`t3` `t3c` where <expr_cache><`test`.`t3c`.`c1`,`test`.`t3c`.`c2`>(<in_optimizer>((`test`.`t3c`.`c1`,`test`.`t3c`.`c2`),(`test`.`t3c`.`c1`,`test`.`t3c`.`c2`) in ( <materialize> (/* select#6 */ select `test`.`t2i`.`b1`,`test`.`t2i`.`b2` from `test`.`t2i` where `test`.`t2i`.`b2` > '0' ), <primary_index_lookup>(`test`.`t3c`.`c1` in <temporary table> on distinct_key where `test`.`t3c`.`c1` = `<subquery6>`.`b1` and `test`.`t3c`.`c2` = `<subquery6>`.`b2`)))) ), <primary_index_lookup>(`test`.`t1`.`a1` in <temporary table> on distinct_key where `test`.`t1`.`a1` = `<subquery5>`.`c1` and `test`.`t1`.`a2` = `<subquery5>`.`c2`))))
+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'));
+a1 a2
+1 - 01 2 - 01
+1 - 02 2 - 02
+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')));
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY t1 ALL NULL # # # 3 100.00 #
+5 MATERIALIZED t3 ALL NULL # # # 4 100.00 #
+6 MATERIALIZED t2i index it2i2 # # # 5 100.00 #
+2 MATERIALIZED t2 ALL NULL # # # 5 100.00 #
+4 MATERIALIZED t3 ALL NULL # # # 4 100.00 #
+3 MATERIALIZED t3 ALL NULL # # # 4 100.00 #
+7 UNION t1i index NULL # # # 3 100.00 #
+9 MATERIALIZED t3i index NULL # # # 4 100.00 #
+10 MATERIALIZED t2i index it2i2 # # # 5 100.00 #
+8 MATERIALIZED t2i index it2i1,it2i3 # # # 5 100.00 #
+NULL UNION RESULT <union1,7> ALL NULL # # # NULL NULL #
+Warnings:
+Note 1003 (/* select#1 */ select `test`.`t1`.`a1` AS `a1`,`test`.`t1`.`a2` AS `a2` from `test`.`t1` where <expr_cache><`test`.`t1`.`a1`,`test`.`t1`.`a2`>(<in_optimizer>((`test`.`t1`.`a1`,`test`.`t1`.`a2`),(`test`.`t1`.`a1`,`test`.`t1`.`a2`) in ( <materialize> (/* select#2 */ select `test`.`t2`.`b1`,`test`.`t2`.`b2` from `test`.`t2` where <expr_cache><`test`.`t2`.`b2`>(<in_optimizer>(`test`.`t2`.`b2`,`test`.`t2`.`b2` in ( <materialize> (/* select#3 */ select `test`.`t3`.`c2` from `test`.`t3` where `test`.`t3`.`c2` like '%02' ), <primary_index_lookup>(`test`.`t2`.`b2` in <temporary table> on distinct_key where `test`.`t2`.`b2` = `<subquery3>`.`c2`)))) or <expr_cache><`test`.`t2`.`b2`>(<in_optimizer>(`test`.`t2`.`b2`,`test`.`t2`.`b2` in ( <materialize> (/* select#4 */ select `test`.`t3`.`c2` from `test`.`t3` where `test`.`t3`.`c2` like '%03' ), <primary_index_lookup>(`test`.`t2`.`b2` in <temporary table> on distinct_key where `test`.`t2`.`b2` = `<subquery4>`.`c2`)))) ), <prima
ry_index
_lookup>(`test`.`t1`.`a1` in <temporary table> on distinct_key where `test`.`t1`.`a1` = `<subquery2>`.`b1` and `test`.`t1`.`a2` = `<subquery2>`.`b2`)))) and <expr_cache><`test`.`t1`.`a1`,`test`.`t1`.`a2`>(<in_optimizer>((`test`.`t1`.`a1`,`test`.`t1`.`a2`),(`test`.`t1`.`a1`,`test`.`t1`.`a2`) in ( <materialize> (/* select#5 */ select `test`.`t3`.`c1`,`test`.`t3`.`c2` from `test`.`t3` where <expr_cache><`test`.`t3`.`c1`,`test`.`t3`.`c2`>(<in_optimizer>((`test`.`t3`.`c1`,`test`.`t3`.`c2`),(`test`.`t3`.`c1`,`test`.`t3`.`c2`) in ( <materialize> (/* select#6 */ select `test`.`t2i`.`b1`,`test`.`t2i`.`b2` from `test`.`t2i` where `test`.`t2i`.`b2` > '0' ), <primary_index_lookup>(`test`.`t3`.`c1` in <temporary table> on distinct_key where `test`.`t3`.`c1` = `<subquery6>`.`b1` and `test`.`t3`.`c2` = `<subquery6>`.`b2`)))) ), <primary_index_lookup>(`test`.`t1`.`a1` in <temporary table> on distinct_key where `test`.`t1`.`a1` = `<subquery5>`.`c1` and `test`.`t1`.`a2` = `<subquery5>`.`c2`))
))) unio
n (/* select#7 */ select `test`.`t1i`.`a1` AS `a1`,`test`.`t1i`.`a2` AS `a2` from `test`.`t1i` where <expr_cache><`test`.`t1i`.`a1`,`test`.`t1i`.`a2`>(<in_optimizer>((`test`.`t1i`.`a1`,`test`.`t1i`.`a2`),(`test`.`t1i`.`a1`,`test`.`t1i`.`a2`) in ( <materialize> (/* select#8 */ select `test`.`t2i`.`b1`,`test`.`t2i`.`b2` from `test`.`t2i` where `test`.`t2i`.`b1` > '0' ), <primary_index_lookup>(`test`.`t1i`.`a1` in <temporary table> on distinct_key where `test`.`t1i`.`a1` = `<subquery8>`.`b1` and `test`.`t1i`.`a2` = `<subquery8>`.`b2`)))) and <expr_cache><`test`.`t1i`.`a1`,`test`.`t1i`.`a2`>(<in_optimizer>((`test`.`t1i`.`a1`,`test`.`t1i`.`a2`),(`test`.`t1i`.`a1`,`test`.`t1i`.`a2`) in ( <materialize> (/* select#9 */ select `test`.`t3i`.`c1`,`test`.`t3i`.`c2` from `test`.`t3i` where <expr_cache><`test`.`t3i`.`c1`,`test`.`t3i`.`c2`>(<in_optimizer>((`test`.`t3i`.`c1`,`test`.`t3i`.`c2`),(`test`.`t3i`.`c1`,`test`.`t3i`.`c2`) in ( <materialize> (/* select#10 */ select `test`.`t2i`.`b1`
,`test`.
`t2i`.`b2` from `test`.`t2i` where `test`.`t2i`.`b2` > '0' ), <primary_index_lookup>(`test`.`t3i`.`c1` in <temporary table> on distinct_key where `test`.`t3i`.`c1` = `<subquery10>`.`b1` and `test`.`t3i`.`c2` = `<subquery10>`.`b2`)))) ), <primary_index_lookup>(`test`.`t1i`.`a1` in <temporary table> on distinct_key where `test`.`t1i`.`a1` = `<subquery9>`.`c1` and `test`.`t1i`.`a2` = `<subquery9>`.`c2`)))))
+(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')));
+a1 a2
+1 - 02 2 - 02
+1 - 01 2 - 01
+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'));
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY t1 ALL NULL NULL NULL NULL 3 100.00 Using where
+4 MATERIALIZED t3 ALL NULL NULL NULL NULL 4 100.00 Using where
+5 MATERIALIZED t2i index it2i2 it2i3 18 NULL 5 100.00 Using where; Using index
+2 DEPENDENT SUBQUERY t1 ALL NULL NULL NULL NULL 3 100.00 Using where
+3 DEPENDENT UNION t2 ALL NULL NULL NULL NULL 5 100.00 Using where
+NULL UNION RESULT <union2,3> ALL NULL NULL NULL NULL NULL NULL
+Warnings:
+Note 1003 /* select#1 */ select `test`.`t1`.`a1` AS `a1`,`test`.`t1`.`a2` AS `a2` from `test`.`t1` where <expr_cache><`test`.`t1`.`a1`,`test`.`t1`.`a2`>(<in_optimizer>((`test`.`t1`.`a1`,`test`.`t1`.`a2`),<exists>(/* select#2 */ select `test`.`t1`.`a1`,`test`.`t1`.`a2` from `test`.`t1` where `test`.`t1`.`a1` > '0' and <cache>(`test`.`t1`.`a1`) = `test`.`t1`.`a1` and <cache>(`test`.`t1`.`a2`) = `test`.`t1`.`a2` union /* select#3 */ select `test`.`t2`.`b1`,`test`.`t2`.`b2` from `test`.`t2` where `test`.`t2`.`b1` < '9' and <cache>(`test`.`t1`.`a1`) = `test`.`t2`.`b1` and <cache>(`test`.`t1`.`a2`) = `test`.`t2`.`b2`))) and <expr_cache><`test`.`t1`.`a1`,`test`.`t1`.`a2`>(<in_optimizer>((`test`.`t1`.`a1`,`test`.`t1`.`a2`),(`test`.`t1`.`a1`,`test`.`t1`.`a2`) in ( <materialize> (/* select#4 */ select `test`.`t3`.`c1`,`test`.`t3`.`c2` from `test`.`t3` where <expr_cache><`test`.`t3`.`c1`,`test`.`t3`.`c2`>(<in_optimizer>((`test`.`t3`.`c1`,`test`.`t3`.`c2`),(`test`.`t3`.`c1`,`test`.`t3`
.`c2`) i
n ( <materialize> (/* select#5 */ select `test`.`t2i`.`b1`,`test`.`t2i`.`b2` from `test`.`t2i` where `test`.`t2i`.`b2` > '0' ), <primary_index_lookup>(`test`.`t3`.`c1` in <temporary table> on distinct_key where `test`.`t3`.`c1` = `<subquery5>`.`b1` and `test`.`t3`.`c2` = `<subquery5>`.`b2`)))) ), <primary_index_lookup>(`test`.`t1`.`a1` in <temporary table> on distinct_key where `test`.`t1`.`a1` = `<subquery4>`.`c1` and `test`.`t1`.`a2` = `<subquery4>`.`c2`))))
+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'));
+a1 a2
+1 - 01 2 - 01
+1 - 02 2 - 02
+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;
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY t1 ALL NULL NULL NULL NULL 3 100.00 Using where
+1 PRIMARY t3 ALL NULL NULL NULL NULL 4 100.00 Using where; Using join buffer (flat, BNL join)
+4 MATERIALIZED t3 ALL NULL NULL NULL NULL 4 100.00 Using where
+5 MATERIALIZED t2i index it2i2 it2i3 18 NULL 5 100.00 Using where; Using index
+2 DEPENDENT SUBQUERY t1 ALL NULL NULL NULL NULL 3 100.00 Using where
+3 DEPENDENT UNION t2 ALL NULL NULL NULL NULL 5 100.00 Using where
+NULL UNION RESULT <union2,3> ALL NULL NULL NULL NULL NULL NULL
+Warnings:
+Note 1003 /* select#1 */ select `test`.`t1`.`a1` AS `a1`,`test`.`t1`.`a2` AS `a2`,`test`.`t3`.`c1` AS `c1`,`test`.`t3`.`c2` AS `c2` from `test`.`t1` join `test`.`t3` where `test`.`t3`.`c1` = `test`.`t1`.`a1` and <expr_cache><`test`.`t1`.`a1`,`test`.`t1`.`a2`>(<in_optimizer>((`test`.`t1`.`a1`,`test`.`t1`.`a2`),<exists>(/* select#2 */ select `test`.`t1`.`a1`,`test`.`t1`.`a2` from `test`.`t1` where `test`.`t1`.`a1` > '0' and <cache>(`test`.`t1`.`a1`) = `test`.`t1`.`a1` and <cache>(`test`.`t1`.`a2`) = `test`.`t1`.`a2` union /* select#3 */ select `test`.`t2`.`b1`,`test`.`t2`.`b2` from `test`.`t2` where `test`.`t2`.`b1` < '9' and <cache>(`test`.`t1`.`a1`) = `test`.`t2`.`b1` and <cache>(`test`.`t1`.`a2`) = `test`.`t2`.`b2`))) and <expr_cache><`test`.`t3`.`c1`,`test`.`t3`.`c2`>(<in_optimizer>((`test`.`t3`.`c1`,`test`.`t3`.`c2`),(`test`.`t3`.`c1`,`test`.`t3`.`c2`) in ( <materialize> (/* select#4 */ select `test`.`t3`.`c1`,`test`.`t3`.`c2` from `test`.`t3` where <expr_cache><`test`.`
t3`.`c1`
,`test`.`t3`.`c2`>(<in_optimizer>((`test`.`t3`.`c1`,`test`.`t3`.`c2`),(`test`.`t3`.`c1`,`test`.`t3`.`c2`) in ( <materialize> (/* select#5 */ select `test`.`t2i`.`b1`,`test`.`t2i`.`b2` from `test`.`t2i` where `test`.`t2i`.`b2` > '0' ), <primary_index_lookup>(`test`.`t3`.`c1` in <temporary table> on distinct_key where `test`.`t3`.`c1` = `<subquery5>`.`b1` and `test`.`t3`.`c2` = `<subquery5>`.`b2`)))) ), <primary_index_lookup>(`test`.`t3`.`c1` in <temporary table> on distinct_key where `test`.`t3`.`c1` = `<subquery4>`.`c1` and `test`.`t3`.`c2` = `<subquery4>`.`c2`))))
+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;
+a1 a2 c1 c2
+1 - 01 2 - 01 1 - 01 2 - 01
+1 - 02 2 - 02 1 - 02 2 - 02
+/******************************************************************************
+* 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');
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY t3 ALL NULL NULL NULL NULL 4 100.00 Using where
+2 DEPENDENT SUBQUERY t1 ALL NULL NULL NULL NULL 3 100.00 Using where
+3 DEPENDENT UNION t2 ALL NULL NULL NULL NULL 5 100.00 Using where
+NULL UNION RESULT <union2,3> ALL NULL NULL NULL NULL NULL NULL
+Warnings:
+Note 1003 /* select#1 */ select `test`.`t3`.`c1` AS `c1`,`test`.`t3`.`c2` AS `c2` from `test`.`t3` where <expr_cache><`test`.`t3`.`c1`>(<in_optimizer>(`test`.`t3`.`c1`,<exists>(/* select#2 */ select `test`.`t1`.`a1` from `test`.`t1` where `test`.`t1`.`a1` > '0' and <cache>(`test`.`t3`.`c1`) = `test`.`t1`.`a1` union /* select#3 */ select `test`.`t2`.`b1` from `test`.`t2` where `test`.`t2`.`b1` < '9' and <cache>(`test`.`t3`.`c1`) = `test`.`t2`.`b1`)))
+select * from t3
+where c1 in (select a1 from t1 where a1 > '0' UNION select b1 from t2 where b1 < '9');
+c1 c2
+1 - 01 2 - 01
+1 - 02 2 - 02
+1 - 03 2 - 03
+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));
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY t1 ALL NULL NULL NULL NULL 3 100.00 Using where
+5 DEPENDENT SUBQUERY t3c ALL NULL NULL NULL NULL 4 100.00 Using where
+6 DEPENDENT SUBQUERY t2i index_subquery it2i1,it2i2,it2i3 it2i3 18 func,func 2 100.00 Using index; Using where
+2 DEPENDENT SUBQUERY t2 ALL NULL NULL NULL NULL 5 100.00 Using where
+4 MATERIALIZED t3b ALL NULL NULL NULL NULL 4 100.00 Using where
+3 DEPENDENT SUBQUERY t3a ALL NULL NULL NULL NULL 4 100.00 Using where
+Warnings:
+Note 1276 Field or reference 'test.t1.a1' of SELECT #3 was resolved in SELECT #1
+Note 1276 Field or reference 'test.t1.a2' of SELECT #6 was resolved in SELECT #1
+Note 1003 /* select#1 */ select `test`.`t1`.`a1` AS `a1`,`test`.`t1`.`a2` AS `a2` from `test`.`t1` where <expr_cache><`test`.`t1`.`a1`,`test`.`t1`.`a2`>(<in_optimizer>((`test`.`t1`.`a1`,`test`.`t1`.`a2`),<exists>(/* select#2 */ select `test`.`t2`.`b1`,`test`.`t2`.`b2` from `test`.`t2` where (<expr_cache><`test`.`t2`.`b2`,`test`.`t1`.`a1`>(<in_optimizer>(`test`.`t2`.`b2`,<exists>(/* select#3 */ select `test`.`t3a`.`c2` from `test`.`t3` `t3a` where `test`.`t3a`.`c1` = `test`.`t1`.`a1` and <cache>(`test`.`t2`.`b2`) = `test`.`t3a`.`c2`))) or <expr_cache><`test`.`t2`.`b2`>(<in_optimizer>(`test`.`t2`.`b2`,`test`.`t2`.`b2` in ( <materialize> (/* select#4 */ select `test`.`t3b`.`c2` from `test`.`t3` `t3b` where `test`.`t3b`.`c2` like '%03' ), <primary_index_lookup>(`test`.`t2`.`b2` in <temporary table> on distinct_key where `test`.`t2`.`b2` = `<subquery4>`.`c2`))))) and <cache>(`test`.`t1`.`a1`) = `test`.`t2`.`b1` and <cache>(`test`.`t1`.`a2`) = `test`.`t2`.`b2`))) and <expr_cache>
<`test`.
`t1`.`a1`,`test`.`t1`.`a2`>(<in_optimizer>((`test`.`t1`.`a1`,`test`.`t1`.`a2`),<exists>(/* select#5 */ select `test`.`t3c`.`c1`,`test`.`t3c`.`c2` from `test`.`t3` `t3c` where <expr_cache><`test`.`t3c`.`c1`,`test`.`t3c`.`c2`,`test`.`t1`.`a2`>(<in_optimizer>((`test`.`t3c`.`c1`,`test`.`t3c`.`c2`),<exists>(<index_lookup>(<cache>(`test`.`t3c`.`c1`) in t2i on it2i3 where (`test`.`t2i`.`b2` > '0' or `test`.`t2i`.`b2` = `test`.`t1`.`a2`) and <cache>(`test`.`t3c`.`c1`) = `test`.`t2i`.`b1` and <cache>(`test`.`t3c`.`c2`) = `test`.`t2i`.`b2`)))) and <cache>(`test`.`t1`.`a1`) = `test`.`t3c`.`c1` and <cache>(`test`.`t1`.`a2`) = `test`.`t3c`.`c2`)))
+explain extended
+select * from t1 where (a1, a2) in (select '1 - 01', '2 - 01');
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY t1 ALL NULL NULL NULL NULL 3 100.00 Using where
+2 DEPENDENT SUBQUERY NULL NULL NULL NULL NULL NULL NULL NULL No tables used
+Warnings:
+Note 1003 /* select#1 */ select `test`.`t1`.`a1` AS `a1`,`test`.`t1`.`a2` AS `a2` from `test`.`t1` where <expr_cache><`test`.`t1`.`a1`,`test`.`t1`.`a2`>(<in_optimizer>((`test`.`t1`.`a1`,`test`.`t1`.`a2`),<exists>(/* select#2 */ select '1 - 01','2 - 01' having (<cache>(`test`.`t1`.`a1`) = '1 - 01' or '1 - 01' is null) and (<cache>(`test`.`t1`.`a2`) = '2 - 01' or '2 - 01' is null) and '1 - 01' is null and '2 - 01' is null)))
+select * from t1 where (a1, a2) in (select '1 - 01', '2 - 01');
+a1 a2
+1 - 01 2 - 01
+explain extended
+select * from t1 where (a1, a2) in (select '1 - 01', '2 - 01' from dual);
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY t1 ALL NULL NULL NULL NULL 3 100.00 Using where
+2 DEPENDENT SUBQUERY NULL NULL NULL NULL NULL NULL NULL NULL No tables used
+Warnings:
+Note 1003 /* select#1 */ select `test`.`t1`.`a1` AS `a1`,`test`.`t1`.`a2` AS `a2` from `test`.`t1` where <expr_cache><`test`.`t1`.`a1`,`test`.`t1`.`a2`>(<in_optimizer>((`test`.`t1`.`a1`,`test`.`t1`.`a2`),<exists>(/* select#2 */ select '1 - 01','2 - 01' having (<cache>(`test`.`t1`.`a1`) = '1 - 01' or '1 - 01' is null) and (<cache>(`test`.`t1`.`a2`) = '2 - 01' or '2 - 01' is null) and '1 - 01' is null and '2 - 01' is null)))
+select * from t1 where (a1, a2) in (select '1 - 01', '2 - 01' from dual);
+a1 a2
+1 - 01 2 - 01
+/******************************************************************************
+* Subqueries in other uncovered clauses.
+******************************************************************************/
+/* SELECT clause */
+select ((a1,a2) IN (select * from t2 where b2 > '0')) IS NULL from t1;
+((a1,a2) IN (select * from t2 where b2 > '0')) IS NULL
+0
+0
+0
+/* 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);
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY t1 ALL NULL NULL NULL NULL 3 100.00
+2 SUBQUERY columns index NULL PRIMARY 4 NULL 2 100.00 Using index
+Warnings:
+Note 1003 /* select#1 */ select `test`.`t1`.`a1` AS `a1`,`test`.`t1`.`a2` AS `a2` from `test`.`t1` group by (/* select#2 */ select `test`.`columns`.`col` from `test`.`columns` limit 1)
+select * from t1 group by (select col from columns limit 1);
+a1 a2
+1 - 00 2 - 00
+explain extended
+select * from t1 group by (a1 in (select col from columns));
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY t1 ALL NULL NULL NULL NULL 3 100.00 Using temporary; Using filesort
+2 DEPENDENT SUBQUERY columns unique_subquery PRIMARY PRIMARY 4 func 1 100.00 Using index; Using where; Full scan on NULL key
+Warnings:
+Note 1003 /* select#1 */ select `test`.`t1`.`a1` AS `a1`,`test`.`t1`.`a2` AS `a2` from `test`.`t1` group by <expr_cache><`test`.`t1`.`a1`>(<in_optimizer>(`test`.`t1`.`a1`,<exists>(<primary_index_lookup>(<cache>(`test`.`t1`.`a1`) in columns on PRIMARY where trigcond(<cache>(`test`.`t1`.`a1`) = `test`.`columns`.`col`)))))
+select * from t1 group by (a1 in (select col from columns));
+a1 a2
+1 - 00 2 - 00
+Warnings:
+Warning 1292 Truncated incorrect DOUBLE value: '1 - 00'
+Warning 1292 Truncated incorrect DOUBLE value: '1 - 01'
+Warning 1292 Truncated incorrect DOUBLE value: '1 - 02'
+/* ORDER BY clause */
+explain extended
+select * from t1 order by (select col from columns limit 1);
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY t1 ALL NULL NULL NULL NULL 3 100.00
+2 SUBQUERY columns index NULL PRIMARY 4 NULL 2 100.00 Using index
+Warnings:
+Note 1003 /* select#1 */ select `test`.`t1`.`a1` AS `a1`,`test`.`t1`.`a2` AS `a2` from `test`.`t1` order by (/* select#2 */ select `test`.`columns`.`col` from `test`.`columns` limit 1)
+select * from t1 order by (select col from columns limit 1);
+a1 a2
+1 - 00 2 - 00
+1 - 01 2 - 01
+1 - 02 2 - 02
+/******************************************************************************
+* 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;
+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)));
+explain extended select left(a1,7), left(a2,7)
+from t1_16
+where a1 in (select b1 from t2_16 where b1 > '0');
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY t1_16 ALL NULL NULL NULL NULL 3 100.00 Using where
+2 DEPENDENT SUBQUERY t2_16 ALL NULL NULL NULL NULL 3 100.00 Using where
+Warnings:
+Note 1003 /* select#1 */ select left(`test`.`t1_16`.`a1`,7) AS `left(a1,7)`,left(`test`.`t1_16`.`a2`,7) AS `left(a2,7)` from `test`.`t1_16` where <expr_cache><`test`.`t1_16`.`a1`>(<in_optimizer>(`test`.`t1_16`.`a1`,<exists>(/* select#2 */ select `test`.`t2_16`.`b1` from `test`.`t2_16` where `test`.`t2_16`.`b1` > '0' and <cache>(`test`.`t1_16`.`a1`) = `test`.`t2_16`.`b1`)))
+select left(a1,7), left(a2,7)
+from t1_16
+where a1 in (select b1 from t2_16 where b1 > '0');
+left(a1,7) left(a2,7)
+1 - 01x 2 - 01x
+1 - 02x 2 - 02x
+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');
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY t1_16 ALL NULL NULL NULL NULL 3 100.00 Using where
+2 DEPENDENT SUBQUERY t2_16 ALL NULL NULL NULL NULL 3 100.00 Using where
+Warnings:
+Note 1003 /* select#1 */ select left(`test`.`t1_16`.`a1`,7) AS `left(a1,7)`,left(`test`.`t1_16`.`a2`,7) AS `left(a2,7)` from `test`.`t1_16` where <expr_cache><`test`.`t1_16`.`a1`,`test`.`t1_16`.`a2`>(<in_optimizer>((`test`.`t1_16`.`a1`,`test`.`t1_16`.`a2`),<exists>(/* select#2 */ select `test`.`t2_16`.`b1`,`test`.`t2_16`.`b2` from `test`.`t2_16` where `test`.`t2_16`.`b1` > '0' and <cache>(`test`.`t1_16`.`a1`) = `test`.`t2_16`.`b1` and <cache>(`test`.`t1_16`.`a2`) = `test`.`t2_16`.`b2`)))
+select left(a1,7), left(a2,7)
+from t1_16
+where (a1,a2) in (select b1, b2 from t2_16 where b1 > '0');
+left(a1,7) left(a2,7)
+1 - 01x 2 - 01x
+1 - 02x 2 - 02x
+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');
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY t1_16 ALL NULL NULL NULL NULL 3 100.00 Using where
+2 MATERIALIZED t2_16 ALL NULL NULL NULL NULL 3 100.00 Using where
+Warnings:
+Note 1003 /* select#1 */ select left(`test`.`t1_16`.`a1`,7) AS `left(a1,7)`,left(`test`.`t1_16`.`a2`,7) AS `left(a2,7)` from `test`.`t1_16` where <expr_cache><`test`.`t1_16`.`a1`>(<in_optimizer>(`test`.`t1_16`.`a1`,`test`.`t1_16`.`a1` in ( <materialize> (/* select#2 */ select substr(`test`.`t2_16`.`b1`,1,16) from `test`.`t2_16` where `test`.`t2_16`.`b1` > '0' ), <primary_index_lookup>(`test`.`t1_16`.`a1` in <temporary table> on distinct_key where `test`.`t1_16`.`a1` = `<subquery2>`.`substring(b1,1,16)`))))
+select left(a1,7), left(a2,7)
+from t1_16
+where a1 in (select substring(b1,1,16) from t2_16 where b1 > '0');
+left(a1,7) left(a2,7)
+1 - 01x 2 - 01x
+1 - 02x 2 - 02x
+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);
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY t1_16 ALL NULL NULL NULL NULL 3 100.00 Using where
+2 DEPENDENT SUBQUERY t2_16 ALL NULL NULL NULL NULL 3 100.00 Using filesort
+Warnings:
+Note 1003 /* select#1 */ select left(`test`.`t1_16`.`a1`,7) AS `left(a1,7)`,left(`test`.`t1_16`.`a2`,7) AS `left(a2,7)` from `test`.`t1_16` where <expr_cache><`test`.`t1_16`.`a1`>(<in_optimizer>(`test`.`t1_16`.`a1`,<exists>(/* select#2 */ select group_concat(`test`.`t2_16`.`b1` separator ',') from `test`.`t2_16` group by `test`.`t2_16`.`b2` having <cache>(`test`.`t1_16`.`a1`) = <ref_null_helper>(group_concat(`test`.`t2_16`.`b1` separator ',')))))
+select left(a1,7), left(a2,7)
+from t1_16
+where a1 in (select group_concat(b1) from t2_16 group by b2);
+left(a1,7) left(a2,7)
+1 - 01x 2 - 01x
+1 - 02x 2 - 02x
+set @@group_concat_max_len = 256;
+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);
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY t1_16 ALL NULL NULL NULL NULL 3 100.00 Using where
+2 MATERIALIZED t2_16 ALL NULL NULL NULL NULL 3 100.00 Using filesort
+Warnings:
+Note 1003 /* select#1 */ select left(`test`.`t1_16`.`a1`,7) AS `left(a1,7)`,left(`test`.`t1_16`.`a2`,7) AS `left(a2,7)` from `test`.`t1_16` where <expr_cache><`test`.`t1_16`.`a1`>(<in_optimizer>(`test`.`t1_16`.`a1`,`test`.`t1_16`.`a1` in ( <materialize> (/* select#2 */ select group_concat(`test`.`t2_16`.`b1` separator ',') from `test`.`t2_16` group by `test`.`t2_16`.`b2` ), <primary_index_lookup>(`test`.`t1_16`.`a1` in <temporary table> on distinct_key where `test`.`t1_16`.`a1` = `<subquery2>`.`group_concat(b1)`))))
+select left(a1,7), left(a2,7)
+from t1_16
+where a1 in (select group_concat(b1) from t2_16 group by b2);
+left(a1,7) left(a2,7)
+1 - 01x 2 - 01x
+1 - 02x 2 - 02x
+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')));
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY t1 ALL NULL NULL NULL NULL 3 100.00 Using where
+2 DEPENDENT SUBQUERY t1_16 ALL NULL NULL NULL NULL 3 100.00 Using where
+3 DEPENDENT SUBQUERY t2_16 ALL NULL NULL NULL NULL 3 100.00 Using where
+3 DEPENDENT SUBQUERY t2 ALL NULL NULL NULL NULL 5 100.00 Using where; Using join buffer (flat, BNL join)
+4 MATERIALIZED t3 ALL NULL NULL NULL NULL 4 100.00 Using where
+Warnings:
+Note 1003 /* select#1 */ select `test`.`t1`.`a1` AS `a1`,`test`.`t1`.`a2` AS `a2` from `test`.`t1` where <expr_cache><concat(`test`.`t1`.`a1`,'x')>(<in_optimizer>(concat(`test`.`t1`.`a1`,'x'),<exists>(/* select#2 */ select left(`test`.`t1_16`.`a1`,8) from `test`.`t1_16` where <expr_cache><`test`.`t1_16`.`a1`,`test`.`t1_16`.`a2`>(<in_optimizer>((`test`.`t1_16`.`a1`,`test`.`t1_16`.`a2`),<exists>(/* select#3 */ select `test`.`t2_16`.`b1`,`test`.`t2_16`.`b2` from `test`.`t2_16` join `test`.`t2` where `test`.`t2`.`b2` = substr(`test`.`t2_16`.`b2`,1,6) and <expr_cache><`test`.`t2`.`b1`>(<in_optimizer>(`test`.`t2`.`b1`,`test`.`t2`.`b1` in ( <materialize> (/* select#4 */ select `test`.`t3`.`c1` from `test`.`t3` where `test`.`t3`.`c2` > '0' ), <primary_index_lookup>(`test`.`t2`.`b1` in <temporary table> on distinct_key where `test`.`t2`.`b1` = `<subquery4>`.`c1`)))) and <cache>(`test`.`t1_16`.`a1`) = `test`.`t2_16`.`b1` and <cache>(`test`.`t1_16`.`a2`) = `test`.`t2_16`.`b2`))) and <
cache>(c
oncat(`test`.`t1`.`a1`,'x')) = left(`test`.`t1_16`.`a1`,8))))
+drop table t1_16, t2_16, t3_16;
+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)));
+explain extended select left(a1,7), left(a2,7)
+from t1_512
+where a1 in (select b1 from t2_512 where b1 > '0');
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY t1_512 ALL NULL NULL NULL NULL 3 100.00 Using where
+2 DEPENDENT SUBQUERY t2_512 ALL NULL NULL NULL NULL 3 100.00 Using where
+Warnings:
+Note 1003 /* select#1 */ select left(`test`.`t1_512`.`a1`,7) AS `left(a1,7)`,left(`test`.`t1_512`.`a2`,7) AS `left(a2,7)` from `test`.`t1_512` where <expr_cache><`test`.`t1_512`.`a1`>(<in_optimizer>(`test`.`t1_512`.`a1`,<exists>(/* select#2 */ select `test`.`t2_512`.`b1` from `test`.`t2_512` where `test`.`t2_512`.`b1` > '0' and <cache>(`test`.`t1_512`.`a1`) = `test`.`t2_512`.`b1`)))
+select left(a1,7), left(a2,7)
+from t1_512
+where a1 in (select b1 from t2_512 where b1 > '0');
+left(a1,7) left(a2,7)
+1 - 01x 2 - 01x
+1 - 02x 2 - 02x
+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');
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY t1_512 ALL NULL NULL NULL NULL 3 100.00 Using where
+2 DEPENDENT SUBQUERY t2_512 ALL NULL NULL NULL NULL 3 100.00 Using where
+Warnings:
+Note 1003 /* select#1 */ select left(`test`.`t1_512`.`a1`,7) AS `left(a1,7)`,left(`test`.`t1_512`.`a2`,7) AS `left(a2,7)` from `test`.`t1_512` where <expr_cache><`test`.`t1_512`.`a1`,`test`.`t1_512`.`a2`>(<in_optimizer>((`test`.`t1_512`.`a1`,`test`.`t1_512`.`a2`),<exists>(/* select#2 */ select `test`.`t2_512`.`b1`,`test`.`t2_512`.`b2` from `test`.`t2_512` where `test`.`t2_512`.`b1` > '0' and <cache>(`test`.`t1_512`.`a1`) = `test`.`t2_512`.`b1` and <cache>(`test`.`t1_512`.`a2`) = `test`.`t2_512`.`b2`)))
+select left(a1,7), left(a2,7)
+from t1_512
+where (a1,a2) in (select b1, b2 from t2_512 where b1 > '0');
+left(a1,7) left(a2,7)
+1 - 01x 2 - 01x
+1 - 02x 2 - 02x
+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');
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY t1_512 ALL NULL NULL NULL NULL 3 100.00 Using where
+2 MATERIALIZED t2_512 ALL NULL NULL NULL NULL 3 100.00 Using where
+Warnings:
+Note 1003 /* select#1 */ select left(`test`.`t1_512`.`a1`,7) AS `left(a1,7)`,left(`test`.`t1_512`.`a2`,7) AS `left(a2,7)` from `test`.`t1_512` where <expr_cache><`test`.`t1_512`.`a1`>(<in_optimizer>(`test`.`t1_512`.`a1`,`test`.`t1_512`.`a1` in ( <materialize> (/* select#2 */ select substr(`test`.`t2_512`.`b1`,1,512) from `test`.`t2_512` where `test`.`t2_512`.`b1` > '0' ), <primary_index_lookup>(`test`.`t1_512`.`a1` in <temporary table> on distinct_key where `test`.`t1_512`.`a1` = `<subquery2>`.`substring(b1,1,512)`))))
+select left(a1,7), left(a2,7)
+from t1_512
+where a1 in (select substring(b1,1,512) from t2_512 where b1 > '0');
+left(a1,7) left(a2,7)
+1 - 01x 2 - 01x
+1 - 02x 2 - 02x
+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);
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY t1_512 ALL NULL NULL NULL NULL 3 100.00 Using where
+2 MATERIALIZED t2_512 ALL NULL NULL NULL NULL 3 100.00 Using filesort
+Warnings:
+Note 1003 /* select#1 */ select left(`test`.`t1_512`.`a1`,7) AS `left(a1,7)`,left(`test`.`t1_512`.`a2`,7) AS `left(a2,7)` from `test`.`t1_512` where <expr_cache><`test`.`t1_512`.`a1`>(<in_optimizer>(`test`.`t1_512`.`a1`,`test`.`t1_512`.`a1` in ( <materialize> (/* select#2 */ select group_concat(`test`.`t2_512`.`b1` separator ',') from `test`.`t2_512` group by `test`.`t2_512`.`b2` ), <primary_index_lookup>(`test`.`t1_512`.`a1` in <temporary table> on distinct_key where `test`.`t1_512`.`a1` = `<subquery2>`.`group_concat(b1)`))))
+select left(a1,7), left(a2,7)
+from t1_512
+where a1 in (select group_concat(b1) from t2_512 group by b2);
+left(a1,7) left(a2,7)
+Warnings:
+Warning 1260 Row 1 was cut by GROUP_CONCAT()
+Warning 1260 Row 2 was cut by GROUP_CONCAT()
+Warning 1260 Row 3 was cut by GROUP_CONCAT()
+set @@group_concat_max_len = 256;
+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);
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY t1_512 ALL NULL NULL NULL NULL 3 100.00 Using where
+2 MATERIALIZED t2_512 ALL NULL NULL NULL NULL 3 100.00 Using filesort
+Warnings:
+Note 1003 /* select#1 */ select left(`test`.`t1_512`.`a1`,7) AS `left(a1,7)`,left(`test`.`t1_512`.`a2`,7) AS `left(a2,7)` from `test`.`t1_512` where <expr_cache><`test`.`t1_512`.`a1`>(<in_optimizer>(`test`.`t1_512`.`a1`,`test`.`t1_512`.`a1` in ( <materialize> (/* select#2 */ select group_concat(`test`.`t2_512`.`b1` separator ',') from `test`.`t2_512` group by `test`.`t2_512`.`b2` ), <primary_index_lookup>(`test`.`t1_512`.`a1` in <temporary table> on distinct_key where `test`.`t1_512`.`a1` = `<subquery2>`.`group_concat(b1)`))))
+select left(a1,7), left(a2,7)
+from t1_512
+where a1 in (select group_concat(b1) from t2_512 group by b2);
+left(a1,7) left(a2,7)
+Warnings:
+Warning 1260 Row 1 was cut by GROUP_CONCAT()
+Warning 1260 Row 2 was cut by GROUP_CONCAT()
+Warning 1260 Row 3 was cut by GROUP_CONCAT()
+drop table t1_512, t2_512, t3_512;
+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)));
+explain extended select left(a1,7), left(a2,7)
+from t1_1024
+where a1 in (select b1 from t2_1024 where b1 > '0');
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY t1_1024 ALL NULL NULL NULL NULL 3 100.00 Using where
+2 DEPENDENT SUBQUERY t2_1024 ALL NULL NULL NULL NULL 3 100.00 Using where
+Warnings:
+Note 1003 /* select#1 */ select left(`test`.`t1_1024`.`a1`,7) AS `left(a1,7)`,left(`test`.`t1_1024`.`a2`,7) AS `left(a2,7)` from `test`.`t1_1024` where <expr_cache><`test`.`t1_1024`.`a1`>(<in_optimizer>(`test`.`t1_1024`.`a1`,<exists>(/* select#2 */ select `test`.`t2_1024`.`b1` from `test`.`t2_1024` where `test`.`t2_1024`.`b1` > '0' and <cache>(`test`.`t1_1024`.`a1`) = `test`.`t2_1024`.`b1`)))
+select left(a1,7), left(a2,7)
+from t1_1024
+where a1 in (select b1 from t2_1024 where b1 > '0');
+left(a1,7) left(a2,7)
+1 - 01x 2 - 01x
+1 - 02x 2 - 02x
+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');
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY t1_1024 ALL NULL NULL NULL NULL 3 100.00 Using where
+2 DEPENDENT SUBQUERY t2_1024 ALL NULL NULL NULL NULL 3 100.00 Using where
+Warnings:
+Note 1003 /* select#1 */ select left(`test`.`t1_1024`.`a1`,7) AS `left(a1,7)`,left(`test`.`t1_1024`.`a2`,7) AS `left(a2,7)` from `test`.`t1_1024` where <expr_cache><`test`.`t1_1024`.`a1`,`test`.`t1_1024`.`a2`>(<in_optimizer>((`test`.`t1_1024`.`a1`,`test`.`t1_1024`.`a2`),<exists>(/* select#2 */ select `test`.`t2_1024`.`b1`,`test`.`t2_1024`.`b2` from `test`.`t2_1024` where `test`.`t2_1024`.`b1` > '0' and <cache>(`test`.`t1_1024`.`a1`) = `test`.`t2_1024`.`b1` and <cache>(`test`.`t1_1024`.`a2`) = `test`.`t2_1024`.`b2`)))
+select left(a1,7), left(a2,7)
+from t1_1024
+where (a1,a2) in (select b1, b2 from t2_1024 where b1 > '0');
+left(a1,7) left(a2,7)
+1 - 01x 2 - 01x
+1 - 02x 2 - 02x
+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');
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY t1_1024 ALL NULL NULL NULL NULL 3 100.00 Using where
+2 DEPENDENT SUBQUERY t2_1024 ALL NULL NULL NULL NULL 3 100.00 Using where
+Warnings:
+Note 1003 /* select#1 */ select left(`test`.`t1_1024`.`a1`,7) AS `left(a1,7)`,left(`test`.`t1_1024`.`a2`,7) AS `left(a2,7)` from `test`.`t1_1024` where <expr_cache><`test`.`t1_1024`.`a1`>(<in_optimizer>(`test`.`t1_1024`.`a1`,<exists>(/* select#2 */ select substr(`test`.`t2_1024`.`b1`,1,1024) from `test`.`t2_1024` where `test`.`t2_1024`.`b1` > '0' and <cache>(`test`.`t1_1024`.`a1`) = substr(`test`.`t2_1024`.`b1`,1,1024))))
+select left(a1,7), left(a2,7)
+from t1_1024
+where a1 in (select substring(b1,1,1024) from t2_1024 where b1 > '0');
+left(a1,7) left(a2,7)
+1 - 01x 2 - 01x
+1 - 02x 2 - 02x
+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);
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY t1_1024 ALL NULL NULL NULL NULL 3 100.00 Using where
+2 MATERIALIZED t2_1024 ALL NULL NULL NULL NULL 3 100.00 Using filesort
+Warnings:
+Note 1003 /* select#1 */ select left(`test`.`t1_1024`.`a1`,7) AS `left(a1,7)`,left(`test`.`t1_1024`.`a2`,7) AS `left(a2,7)` from `test`.`t1_1024` where <expr_cache><`test`.`t1_1024`.`a1`>(<in_optimizer>(`test`.`t1_1024`.`a1`,`test`.`t1_1024`.`a1` in ( <materialize> (/* select#2 */ select group_concat(`test`.`t2_1024`.`b1` separator ',') from `test`.`t2_1024` group by `test`.`t2_1024`.`b2` ), <primary_index_lookup>(`test`.`t1_1024`.`a1` in <temporary table> on distinct_key where `test`.`t1_1024`.`a1` = `<subquery2>`.`group_concat(b1)`))))
+select left(a1,7), left(a2,7)
+from t1_1024
+where a1 in (select group_concat(b1) from t2_1024 group by b2);
+left(a1,7) left(a2,7)
+Warnings:
+Warning 1260 Row 1 was cut by GROUP_CONCAT()
+Warning 1260 Row 2 was cut by GROUP_CONCAT()
+Warning 1260 Row 3 was cut by GROUP_CONCAT()
+set @@group_concat_max_len = 256;
+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);
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY t1_1024 ALL NULL NULL NULL NULL 3 100.00 Using where
+2 MATERIALIZED t2_1024 ALL NULL NULL NULL NULL 3 100.00 Using filesort
+Warnings:
+Note 1003 /* select#1 */ select left(`test`.`t1_1024`.`a1`,7) AS `left(a1,7)`,left(`test`.`t1_1024`.`a2`,7) AS `left(a2,7)` from `test`.`t1_1024` where <expr_cache><`test`.`t1_1024`.`a1`>(<in_optimizer>(`test`.`t1_1024`.`a1`,`test`.`t1_1024`.`a1` in ( <materialize> (/* select#2 */ select group_concat(`test`.`t2_1024`.`b1` separator ',') from `test`.`t2_1024` group by `test`.`t2_1024`.`b2` ), <primary_index_lookup>(`test`.`t1_1024`.`a1` in <temporary table> on distinct_key where `test`.`t1_1024`.`a1` = `<subquery2>`.`group_concat(b1)`))))
+select left(a1,7), left(a2,7)
+from t1_1024
+where a1 in (select group_concat(b1) from t2_1024 group by b2);
+left(a1,7) left(a2,7)
+Warnings:
+Warning 1260 Row 1 was cut by GROUP_CONCAT()
+Warning 1260 Row 2 was cut by GROUP_CONCAT()
+Warning 1260 Row 3 was cut by GROUP_CONCAT()
+drop table t1_1024, t2_1024, t3_1024;
+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)));
+explain extended select left(a1,7), left(a2,7)
+from t1_1025
+where a1 in (select b1 from t2_1025 where b1 > '0');
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY t1_1025 ALL NULL NULL NULL NULL 3 100.00 Using where
+2 DEPENDENT SUBQUERY t2_1025 ALL NULL NULL NULL NULL 3 100.00 Using where
+Warnings:
+Note 1003 /* select#1 */ select left(`test`.`t1_1025`.`a1`,7) AS `left(a1,7)`,left(`test`.`t1_1025`.`a2`,7) AS `left(a2,7)` from `test`.`t1_1025` where <expr_cache><`test`.`t1_1025`.`a1`>(<in_optimizer>(`test`.`t1_1025`.`a1`,<exists>(/* select#2 */ select `test`.`t2_1025`.`b1` from `test`.`t2_1025` where `test`.`t2_1025`.`b1` > '0' and <cache>(`test`.`t1_1025`.`a1`) = `test`.`t2_1025`.`b1`)))
+select left(a1,7), left(a2,7)
+from t1_1025
+where a1 in (select b1 from t2_1025 where b1 > '0');
+left(a1,7) left(a2,7)
+1 - 01x 2 - 01x
+1 - 02x 2 - 02x
+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');
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY t1_1025 ALL NULL NULL NULL NULL 3 100.00 Using where
+2 DEPENDENT SUBQUERY t2_1025 ALL NULL NULL NULL NULL 3 100.00 Using where
+Warnings:
+Note 1003 /* select#1 */ select left(`test`.`t1_1025`.`a1`,7) AS `left(a1,7)`,left(`test`.`t1_1025`.`a2`,7) AS `left(a2,7)` from `test`.`t1_1025` where <expr_cache><`test`.`t1_1025`.`a1`,`test`.`t1_1025`.`a2`>(<in_optimizer>((`test`.`t1_1025`.`a1`,`test`.`t1_1025`.`a2`),<exists>(/* select#2 */ select `test`.`t2_1025`.`b1`,`test`.`t2_1025`.`b2` from `test`.`t2_1025` where `test`.`t2_1025`.`b1` > '0' and <cache>(`test`.`t1_1025`.`a1`) = `test`.`t2_1025`.`b1` and <cache>(`test`.`t1_1025`.`a2`) = `test`.`t2_1025`.`b2`)))
+select left(a1,7), left(a2,7)
+from t1_1025
+where (a1,a2) in (select b1, b2 from t2_1025 where b1 > '0');
+left(a1,7) left(a2,7)
+1 - 01x 2 - 01x
+1 - 02x 2 - 02x
+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');
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY t1_1025 ALL NULL NULL NULL NULL 3 100.00 Using where
+2 DEPENDENT SUBQUERY t2_1025 ALL NULL NULL NULL NULL 3 100.00 Using where
+Warnings:
+Note 1003 /* select#1 */ select left(`test`.`t1_1025`.`a1`,7) AS `left(a1,7)`,left(`test`.`t1_1025`.`a2`,7) AS `left(a2,7)` from `test`.`t1_1025` where <expr_cache><`test`.`t1_1025`.`a1`>(<in_optimizer>(`test`.`t1_1025`.`a1`,<exists>(/* select#2 */ select substr(`test`.`t2_1025`.`b1`,1,1025) from `test`.`t2_1025` where `test`.`t2_1025`.`b1` > '0' and <cache>(`test`.`t1_1025`.`a1`) = substr(`test`.`t2_1025`.`b1`,1,1025))))
+select left(a1,7), left(a2,7)
+from t1_1025
+where a1 in (select substring(b1,1,1025) from t2_1025 where b1 > '0');
+left(a1,7) left(a2,7)
+1 - 01x 2 - 01x
+1 - 02x 2 - 02x
+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);
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY t1_1025 ALL NULL NULL NULL NULL 3 100.00 Using where
+2 MATERIALIZED t2_1025 ALL NULL NULL NULL NULL 3 100.00 Using filesort
+Warnings:
+Note 1003 /* select#1 */ select left(`test`.`t1_1025`.`a1`,7) AS `left(a1,7)`,left(`test`.`t1_1025`.`a2`,7) AS `left(a2,7)` from `test`.`t1_1025` where <expr_cache><`test`.`t1_1025`.`a1`>(<in_optimizer>(`test`.`t1_1025`.`a1`,`test`.`t1_1025`.`a1` in ( <materialize> (/* select#2 */ select group_concat(`test`.`t2_1025`.`b1` separator ',') from `test`.`t2_1025` group by `test`.`t2_1025`.`b2` ), <primary_index_lookup>(`test`.`t1_1025`.`a1` in <temporary table> on distinct_key where `test`.`t1_1025`.`a1` = `<subquery2>`.`group_concat(b1)`))))
+select left(a1,7), left(a2,7)
+from t1_1025
+where a1 in (select group_concat(b1) from t2_1025 group by b2);
+left(a1,7) left(a2,7)
+Warnings:
+Warning 1260 Row 1 was cut by GROUP_CONCAT()
+Warning 1260 Row 2 was cut by GROUP_CONCAT()
+Warning 1260 Row 3 was cut by GROUP_CONCAT()
+set @@group_concat_max_len = 256;
+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);
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY t1_1025 ALL NULL NULL NULL NULL 3 100.00 Using where
+2 MATERIALIZED t2_1025 ALL NULL NULL NULL NULL 3 100.00 Using filesort
+Warnings:
+Note 1003 /* select#1 */ select left(`test`.`t1_1025`.`a1`,7) AS `left(a1,7)`,left(`test`.`t1_1025`.`a2`,7) AS `left(a2,7)` from `test`.`t1_1025` where <expr_cache><`test`.`t1_1025`.`a1`>(<in_optimizer>(`test`.`t1_1025`.`a1`,`test`.`t1_1025`.`a1` in ( <materialize> (/* select#2 */ select group_concat(`test`.`t2_1025`.`b1` separator ',') from `test`.`t2_1025` group by `test`.`t2_1025`.`b2` ), <primary_index_lookup>(`test`.`t1_1025`.`a1` in <temporary table> on distinct_key where `test`.`t1_1025`.`a1` = `<subquery2>`.`group_concat(b1)`))))
+select left(a1,7), left(a2,7)
+from t1_1025
+where a1 in (select group_concat(b1) from t2_1025 group by b2);
+left(a1,7) left(a2,7)
+Warnings:
+Warning 1260 Row 1 was cut by GROUP_CONCAT()
+Warning 1260 Row 2 was cut by GROUP_CONCAT()
+Warning 1260 Row 3 was cut by GROUP_CONCAT()
+drop table t1_1025, t2_1025, t3_1025;
+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);
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY t1bit ALL NULL NULL NULL NULL 3 100.00 Using where
+2 MATERIALIZED t2bit ALL NULL NULL NULL NULL 3 100.00
+Warnings:
+Note 1003 /* select#1 */ select conv(`test`.`t1bit`.`a1`,10,2) AS `bin(a1)`,conv(`test`.`t1bit`.`a2`,10,2) AS `bin(a2)` from `test`.`t1bit` where <expr_cache><`test`.`t1bit`.`a1`,`test`.`t1bit`.`a2`>(<in_optimizer>((`test`.`t1bit`.`a1`,`test`.`t1bit`.`a2`),(`test`.`t1bit`.`a1`,`test`.`t1bit`.`a2`) in ( <materialize> (/* select#2 */ select `test`.`t2bit`.`b1`,`test`.`t2bit`.`b2` from `test`.`t2bit` ), <primary_index_lookup>(`test`.`t1bit`.`a1` in <temporary table> on distinct_key where `test`.`t1bit`.`a1` = `<subquery2>`.`b1` and `test`.`t1bit`.`a2` = `<subquery2>`.`b2`))))
+select bin(a1), bin(a2)
+from t1bit
+where (a1, a2) in (select b1, b2 from t2bit);
+bin(a1) bin(a2)
+1 101
+10 110
+drop table t1bit, t2bit;
+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);
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY t1bb ALL NULL NULL NULL NULL 3 100.00 Using where
+2 DEPENDENT SUBQUERY t2bb ALL NULL NULL NULL NULL 3 100.00 Using where
+Warnings:
+Note 1003 /* select#1 */ select conv(`test`.`t1bb`.`a1`,10,2) AS `bin(a1)`,`test`.`t1bb`.`a2` AS `a2` from `test`.`t1bb` where <expr_cache><`test`.`t1bb`.`a1`,`test`.`t1bb`.`a2`>(<in_optimizer>((`test`.`t1bb`.`a1`,`test`.`t1bb`.`a2`),<exists>(/* select#2 */ select `test`.`t2bb`.`b1`,`test`.`t2bb`.`b2` from `test`.`t2bb` where <cache>(`test`.`t1bb`.`a1`) = `test`.`t2bb`.`b1` and <cache>(`test`.`t1bb`.`a2`) = `test`.`t2bb`.`b2`)))
+select bin(a1), a2
+from t1bb
+where (a1, a2) in (select b1, b2 from t2bb);
+bin(a1) a2
+1 101
+10 110
+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);
+s2
+0
+1
+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);
+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);
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY t1 ALL NULL NULL NULL NULL 7 100.00 Using where
+2 MATERIALIZED t2 ALL NULL NULL NULL NULL 6 100.00 Using where
+Warnings:
+Note 1003 /* select#1 */ select `test`.`t1`.`a` AS `a` from `test`.`t1` where <expr_cache><`test`.`t1`.`a`>(<in_optimizer>(`test`.`t1`.`a`,`test`.`t1`.`a` in ( <materialize> (/* select#2 */ select `test`.`t2`.`c` from `test`.`t2` where `test`.`t2`.`d` >= 20 ), <primary_index_lookup>(`test`.`t1`.`a` in <temporary table> on distinct_key where `test`.`t1`.`a` = `<subquery2>`.`c`))))
+select a from t1 where a in (select c from t2 where d >= 20);
+a
+2
+2
+2
+3
+create index it1a on t1(a);
+explain extended
+select a from t1 where a in (select c from t2 where d >= 20);
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY t1 index NULL it1a 4 NULL 7 100.00 Using where; Using index
+2 MATERIALIZED t2 ALL NULL NULL NULL NULL 6 100.00 Using where
+Warnings:
+Note 1003 /* select#1 */ select `test`.`t1`.`a` AS `a` from `test`.`t1` where <expr_cache><`test`.`t1`.`a`>(<in_optimizer>(`test`.`t1`.`a`,`test`.`t1`.`a` in ( <materialize> (/* select#2 */ select `test`.`t2`.`c` from `test`.`t2` where `test`.`t2`.`d` >= 20 ), <primary_index_lookup>(`test`.`t1`.`a` in <temporary table> on distinct_key where `test`.`t1`.`a` = `<subquery2>`.`c`))))
+select a from t1 where a in (select c from t2 where d >= 20);
+a
+2
+2
+2
+3
+insert into t2 values (1,10);
+explain extended
+select a from t1 where a in (select c from t2 where d >= 20);
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY t1 index NULL it1a 4 NULL 7 100.00 Using where; Using index
+2 MATERIALIZED t2 ALL NULL NULL NULL NULL 7 100.00 Using where
+Warnings:
+Note 1003 /* select#1 */ select `test`.`t1`.`a` AS `a` from `test`.`t1` where <expr_cache><`test`.`t1`.`a`>(<in_optimizer>(`test`.`t1`.`a`,`test`.`t1`.`a` in ( <materialize> (/* select#2 */ select `test`.`t2`.`c` from `test`.`t2` where `test`.`t2`.`d` >= 20 ), <primary_index_lookup>(`test`.`t1`.`a` in <temporary table> on distinct_key where `test`.`t1`.`a` = `<subquery2>`.`c`))))
+select a from t1 where a in (select c from t2 where d >= 20);
+a
+2
+2
+2
+3
+explain extended
+select a from t1 group by a having a in (select c from t2 where d >= 20);
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY t1 index NULL it1a 4 NULL 7 100.00 Using index
+2 MATERIALIZED t2 ALL NULL NULL NULL NULL 7 100.00 Using where
+Warnings:
+Note 1003 /* select#1 */ select `test`.`t1`.`a` AS `a` from `test`.`t1` group by `test`.`t1`.`a` having <expr_cache><`test`.`t1`.`a`>(<in_optimizer>(`test`.`t1`.`a`,`test`.`t1`.`a` in ( <materialize> (/* select#2 */ select `test`.`t2`.`c` from `test`.`t2` where `test`.`t2`.`d` >= 20 ), <primary_index_lookup>(`test`.`t1`.`a` in <temporary table> on distinct_key where `test`.`t1`.`a` = `<subquery2>`.`c`))))
+select a from t1 group by a having a in (select c from t2 where d >= 20);
+a
+2
+3
+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);
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY t1 index NULL it1a 4 NULL 7 100.00 Using index
+2 MATERIALIZED t2 ALL NULL NULL NULL NULL 7 100.00 Using where
+Warnings:
+Note 1003 /* select#1 */ select `test`.`t1`.`a` AS `a` from `test`.`t1` group by `test`.`t1`.`a` having <expr_cache><`test`.`t1`.`a`>(<in_optimizer>(`test`.`t1`.`a`,`test`.`t1`.`a` in ( <materialize> (/* select#2 */ select `test`.`t2`.`c` from `test`.`t2` where `test`.`t2`.`d` >= 20 ), <primary_index_lookup>(`test`.`t1`.`a` in <temporary table> on distinct_key where `test`.`t1`.`a` = `<subquery2>`.`c`))))
+select a from t1 group by a having a in (select c from t2 where d >= 20);
+a
+2
+3
+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));
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY t1 index NULL iab 8 NULL 7 100.00 Using index
+2 DEPENDENT SUBQUERY t2 ALL NULL NULL NULL NULL 7 100.00 Using where
+3 DEPENDENT SUBQUERY t3 ALL NULL NULL NULL NULL 4 100.00 Using where
+Warnings:
+Note 1276 Field or reference 'test.t1.b' of SELECT #3 was resolved in SELECT #1
+Note 1981 Aggregate function 'max()' of SELECT #3 belongs to SELECT #1
+Note 1003 /* select#1 */ select `test`.`t1`.`a` AS `a` from `test`.`t1` group by `test`.`t1`.`a` having <expr_cache><`test`.`t1`.`a`,`test`.`t1`.`b`,max(`test`.`t1`.`b`),max(`test`.`t1`.`b`)>(<in_optimizer>(`test`.`t1`.`a`,<exists>(/* select#2 */ select `test`.`t2`.`c` from `test`.`t2` where <nop>(<expr_cache><`test`.`t2`.`d`,`test`.`t1`.`b`,max(`test`.`t1`.`b`),max(`test`.`t1`.`b`)>(<in_optimizer>(`test`.`t2`.`d`,<exists>(/* select#3 */ select `test`.`t3`.`e` from `test`.`t3` where max(`test`.`t1`.`b`) = `test`.`t3`.`e` having <cache>(`test`.`t2`.`d`) >= <ref_null_helper>(`test`.`t3`.`e`))))) and <cache>(`test`.`t1`.`a`) = `test`.`t2`.`c`)))
+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));
+a
+2
+3
+explain extended
+select a from t1
+where a in (select c from t2 where d >= some(select e from t3 where b=e));
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY t1 index NULL iab 8 NULL 7 100.00 Using where; Using index
+2 DEPENDENT SUBQUERY t2 ALL NULL NULL NULL NULL 7 100.00 Using where
+3 DEPENDENT SUBQUERY t3 ALL NULL NULL NULL NULL 4 100.00 Using where
+Warnings:
+Note 1276 Field or reference 'test.t1.b' of SELECT #3 was resolved in SELECT #1
+Note 1003 /* select#1 */ select `test`.`t1`.`a` AS `a` from `test`.`t1` where <expr_cache><`test`.`t1`.`a`,`test`.`t1`.`b`>(<in_optimizer>(`test`.`t1`.`a`,<exists>(/* select#2 */ select `test`.`t2`.`c` from `test`.`t2` where <nop>(<expr_cache><`test`.`t2`.`d`,`test`.`t1`.`b`>(<in_optimizer>(`test`.`t2`.`d`,<exists>(/* select#3 */ select `test`.`t3`.`e` from `test`.`t3` where `test`.`t1`.`b` = `test`.`t3`.`e` and <cache>(`test`.`t2`.`d`) >= `test`.`t3`.`e`)))) and <cache>(`test`.`t1`.`a`) = `test`.`t2`.`c`)))
+select a from t1
+where a in (select c from t2 where d >= some(select e from t3 where b=e));
+a
+1
+2
+2
+2
+3
+drop table t1, t2, t3;
+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);
+1
+1
+1
+1
+drop table t2;
+create table t1 (a1 int key);
+create table t2 (b1 int);
+insert into t1 values (5);
+explain select min(a1) from t1 where 7 in (select max(b1) from t2 group by b1);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY NULL NULL NULL NULL NULL NULL NULL Impossible WHERE
+2 MATERIALIZED NULL NULL NULL NULL NULL NULL NULL no matching row in const table
+select min(a1) from t1 where 7 in (select max(b1) from t2 group by b1);
+min(a1)
+NULL
+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 max(b1) from t2 group by b1);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY NULL NULL NULL NULL NULL NULL NULL Impossible WHERE
+2 SUBQUERY NULL NULL NULL NULL NULL NULL NULL no matching row in const table
+select min(a1) from t1 where 7 in (select max(b1) from t2 group by b1);
+min(a1)
+NULL
+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);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY NULL NULL NULL NULL NULL NULL NULL Impossible WHERE
+2 MATERIALIZED NULL NULL NULL NULL NULL NULL NULL no matching row in const table
+select min(a1) from t1 where 7 in (select b1 from t2);
+min(a1)
+NULL
+set @@optimizer_switch=@optimizer_switch_local_default;
+set @@optimizer_switch='materialization=off,in_to_exists=on';
+# with MariaDB and MWL#90, this particular case is solved:
+explain select min(a1) from t1 where 7 in (select b1 from t2);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY NULL NULL NULL NULL NULL NULL NULL Impossible WHERE
+2 SUBQUERY NULL NULL NULL NULL NULL NULL NULL no matching row in const table
+select min(a1) from t1 where 7 in (select b1 from t2);
+min(a1)
+NULL
+# 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;
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY NULL NULL NULL NULL NULL NULL NULL Impossible WHERE
+2 SUBQUERY NULL NULL NULL NULL NULL NULL NULL no matching row in const table
+select min(a1) from t1 where 7 in (select b1 from t2) or 2> 4;
+min(a1)
+NULL
+set @@optimizer_switch= @save_optimizer_switch;
+drop table t1,t2;
+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);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t1 ALL NULL NULL NULL NULL 2 Using where
+2 MATERIALIZED t1 ALL NULL NULL NULL NULL 2
+select a,b from t1 where b in (select a from t1);
+a b
+prepare st1 from "select a,b from t1 where b in (select a from t1)";
+execute st1;
+a b
+execute st1;
+a b
+drop table t1;
+#
+# BUG#49630: Segfault in select_describe() with double
+# nested subquery and materialization
+#
+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);
+INSERT INTO t2 VALUES (1),(2);
+INSERT INTO t3 VALUES (1),(2);
+INSERT INTO t4 VALUES (1),(2);
+
+EXPLAIN
+SELECT t1i
+FROM t1 JOIN t4 ON t1i=t4i
+WHERE (t1i) IN (
+SELECT t2i
+FROM t2
+WHERE (t2i) IN (
+SELECT max(t3i)
+FROM t3
+GROUP BY t3i
+)
+);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t1 system NULL NULL NULL NULL 1
+1 PRIMARY t4 ALL NULL NULL NULL NULL 2 Using where
+2 MATERIALIZED t2 ALL NULL NULL NULL NULL 2 Using where
+3 MATERIALIZED t3 ALL NULL NULL NULL NULL 2 Using temporary
+DROP TABLE t1,t2,t3,t4;
+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
+;
+field1 field2
+t 1
+t 2
+drop table t1;
+#
+# BUG#53103: MTR test ps crashes in optimize_cond()
+# when running with --debug
+#
+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 ;
+1
+1
+1
+EXECUTE STMT ;
+1
+1
+1
+DEALLOCATE PREPARE STMT;
+DROP TABLE t1;
+# End of BUG#53103
+#
+# BUG#54511 - Assertion failed: cache != 0L in file
+# sql_select.cc::sub_select_cache on HAVING
+#
+CREATE TABLE t1 (i int(11));
+CREATE TABLE t2 (c char(1));
+CREATE TABLE t3 (c char(1));
+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));
+COUNT( i ) i
+DROP TABLE t1,t2,t3;
+# End BUG#54511
+#
+# BUG#56367 - Assertion exec_method != EXEC_MATERIALIZATION...
+# on subquery in FROM
+#
+CREATE TABLE t1 (a INTEGER);
+CREATE TABLE t2 (b INTEGER);
+INSERT INTO t2 VALUES (1);
+set @tmp_optimizer_switch=@@optimizer_switch;
+set optimizer_switch='derived_merge=off,derived_with_keys=off';
+explain SELECT a FROM (
+SELECT t1.* FROM t1 LEFT JOIN t2 ON t1.a > 3 OR t2.b IN (SELECT a FROM t1)
+) table1;
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY <derived2> ALL NULL NULL NULL NULL 2
+2 DERIVED NULL NULL NULL NULL NULL NULL NULL no matching row in const table
+3 MATERIALIZED NULL NULL NULL NULL NULL NULL NULL no matching row in const table
+SELECT a FROM (
+SELECT t1.* FROM t1 LEFT JOIN t2 ON t1.a > 3 OR t2.b IN (SELECT a FROM t1)
+) table1;
+a
+set optimizer_switch=@tmp_optimizer_switch;
+DROP TABLE t1, t2;
+# End BUG#56367
+#
+# Bug#59833 - materialization=on/off leads to different result set
+# when using IN
+#
+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);
+explain SELECT * FROM t1 JOIN t2 USING (f1)
+WHERE t1.f1 IN (SELECT t1.pk FROM t1 ORDER BY t1.f1);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t1 system NULL NULL NULL NULL 1
+1 PRIMARY t2 ALL NULL NULL NULL NULL 2 Using where
+2 MATERIALIZED t1 system NULL NULL NULL NULL 1
+SELECT * FROM t1 JOIN t2 USING (f1)
+WHERE t1.f1 IN (SELECT t1.pk FROM t1 ORDER BY t1.f1);
+f1 pk pk
+DROP TABLE t1, t2;
+# End Bug#59833
+#
+# Bug#11852644 - CRASH IN ITEM_REF::SAVE_IN_FIELD ON SELECT DISTINCT
+#
+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)
+;
+col_varchar_key
+r
+DROP TABLE t1, t2;
+DROP VIEW v3;
+# End Bug#11852644
+
+# Bug#12668294 - GROUP BY ON EMPTY RESULT GIVES EMPTY ROW
+# INSTEAD OF NULL WHEN MATERIALIZATION ON
+
+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 ;
+MIN(t3.col_int_nokey) field3
+DROP TABLE t1;
+DROP TABLE t2;
+DROP TABLE t3;
+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);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY <subquery2> ALL distinct_key NULL NULL NULL 2
+1 PRIMARY t1 ALL NULL NULL NULL NULL 3 Using where; Using join buffer (flat, BNL join)
+2 MATERIALIZED t2 ALL NULL NULL NULL NULL 2
+SELECT COUNT(*) FROM t1 WHERE (f1,f2) IN (SELECT f1,f2 FROM t2);
+COUNT(*)
+2
+set @@optimizer_switch= @save_optimizer_switch;
+DROP TABLE t1, t2;
+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);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t1 ALL NULL NULL NULL NULL 2
+1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 4 func 1
+2 MATERIALIZED t2 range PRIMARY PRIMARY 4 NULL 2 Using index condition; Using where; Rowid-ordered scan
+SELECT pk FROM t1 WHERE (a) IN (SELECT a FROM t2 WHERE pk > 0);
+pk
+2
+SELECT pk FROM t1 WHERE (b,c,d) IN (SELECT b,c,d FROM t2 WHERE pk > 0);
+pk
+2
+DROP TABLE t1, t2;
+set optimizer_switch=@save_optimizer_switch;
+#
+# BUG#50019: Wrong result for IN-subquery with materialization
+#
+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);
+i
+1
+2
+3
+4
+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);
+i
+1
+2
+3
+4
+set session optimizer_switch=@save_optimizer_switch;
+drop table t1, t2, t3;
+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;
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t0 ALL NULL NULL NULL NULL 3
+2 MATERIALIZED t1 ALL NULL NULL NULL NULL 3
+select a, a in (select a from t1) from t0;
+a a in (select a from t1)
+0 1
+1 1
+2 1
+prepare s from 'select a, a in (select a from t1) from t0';
+execute s;
+a a in (select a from t1)
+0 1
+1 1
+2 1
+update t1 set a=123;
+execute s;
+a a in (select a from t1)
+0 0
+1 0
+2 0
+drop table t0, t1;
+set optimizer_switch='firstmatch=on';
+#
+# MWL#90, review feedback: check what happens when the subquery
+# looks like candidate for MWL#90 checking at the first glance
+# but then subselect_hash_sj_engine::init_permanent() discovers
+# that it's not possible to perform duplicate removal for the
+# selected datatypes, and so materialization isn't applicable after
+# all.
+#
+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');
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t1_1024 ALL NULL NULL NULL NULL 3 Using where
+2 DEPENDENT SUBQUERY t2_1024 ALL NULL NULL NULL NULL 3 Using where
+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');
+left(a1,7) left(a2,7)
+1 - 01x 2 - 01x
+drop table t1_1024, t2_1024;
+#
+# BUG##836491: Crash in Item_field::Item_field from add_ref_to_table_cond() with semijoin+materialization
+#
+CREATE TABLE t1 (c int, d varchar(1), KEY(d)) ;
+INSERT INTO t1 VALUES (2,'x'),(2,'x'),(2,'j'),(2,'c');
+CREATE TABLE t2 (a int, d varchar(1)) ;
+INSERT INTO t2 VALUES (1,'x');
+CREATE TABLE t3 (d varchar(1)) ;
+INSERT INTO t3 VALUES ('x'),('x'),('j'),('c');
+SELECT t2.a, t1.c
+FROM t1, t2
+WHERE t2.d IN ( SELECT d FROM t3 )
+AND t1.d = t2.d
+GROUP BY 1 , 2;
+a c
+1 2
+drop table t1,t2,t3;
+#
+# BUG#836523: Crash in JOIN::get_partial_cost_and_fanout with semijoin+materialization
+#
+CREATE TABLE t1 (a varchar(1));
+INSERT INTO t1 VALUES ('a'),('a');
+CREATE TABLE t2 (a varchar(1));
+CREATE TABLE t3 (a int);
+INSERT INTO t3 VALUES (1),(2);
+CREATE TABLE t4 (a varchar(1));
+INSERT INTO t4 VALUES ('a'),('a');
+SELECT t1.a
+FROM t1
+WHERE t1.a IN (
+SELECT t2.a
+FROM t2, t3
+)
+HAVING a IN (
+SELECT a
+FROM t4
+);
+a
+DROP TABLE t1, t2, t3, t4;
+#
+# BUG#836507: Crash in setup_sj_materialization_part1() with semijoin+materialization
+#
+CREATE TABLE t1 (a int) ;
+INSERT IGNORE INTO t1 VALUES (1),(1);
+CREATE TABLE t2 (a int);
+INSERT INTO t2 VALUES (1);
+CREATE TABLE t3 (a int);
+CREATE TABLE t4 (a int);
+INSERT INTO t4 VALUES (2),(2);
+CREATE TABLE t5 (a int);
+INSERT INTO t5 VALUES (1);
+SELECT * FROM t1
+WHERE (a) IN (
+SELECT t5.a
+FROM (
+t2
+LEFT JOIN ( t3 , t4 )
+ON 1 = 1
+)
+JOIN t5
+);
+a
+1
+1
+DROP TABLE t1,t2,t3,t4,t5;
+#
+# BUG#836532: Crash in Item_equal_fields_iterator::get_curr_field with semijoin+materialization
+#
+CREATE TABLE t2 (a int);
+INSERT IGNORE INTO t2 VALUES ('a'),('a');
+Warnings:
+Warning 1366 Incorrect integer value: 'a' for column 'a' at row 1
+Warning 1366 Incorrect integer value: 'a' for column 'a' at row 2
+CREATE TABLE t4 (a varchar(1));
+INSERT INTO t4 VALUES ('m'),('o');
+CREATE TABLE t3 (a varchar(1) , b varchar(1) ) ;
+INSERT INTO t3 VALUES ('b','b');
+CREATE TABLE t5 (a varchar(1), KEY (a)) ;
+INSERT INTO t5 VALUES ('d'),('e');
+SELECT *
+FROM t2
+WHERE t2.a = ALL (
+SELECT t4.a
+FROM t4
+WHERE t4.a IN (
+SELECT t3.a
+FROM t3 , t5
+WHERE ( t5.a = t3.b )
+)
+);
+a
+0
+0
+DROP TABLE t2,t3,t4,t5;
+#
+# BUG#860300: Second crash with get_fanout_with_deps() with semijoin + materialization
+#
+set @tmp_860300=@@optimizer_switch;
+set optimizer_switch='semijoin=on,materialization=on,loosescan=off,firstmatch=off';
+CREATE TABLE t1 (f2 int);
+INSERT INTO t1 VALUES (9),(6);
+CREATE TABLE t3 (f4 int);
+CREATE TABLE t4 (f6 varchar(1));
+SELECT *
+FROM t3
+WHERE 'h' IN (SELECT f6
+FROM t4
+WHERE 5 IN (SELECT f2 FROM t1)
+GROUP BY t4.f6);
+f4
+DROP TABLE t1,t3,t4;
+set optimizer_switch=@tmp_860300;
+#
+# BUG#860535: Assertion `keypart_map' failed in mi_rkey with semijoin
+#
+set @tmp_860535=@@optimizer_switch;
+set optimizer_switch='semijoin=on,materialization=on,loosescan=off,firstmatch=off';
+CREATE TABLE t1 (f3 int) ;
+INSERT INTO t1 VALUES (1),(7);
+CREATE TABLE t2 (f3 int , f5 varchar(1), KEY (f3)) ;
+INSERT INTO t2 VALUES (7,'b');
+CREATE TABLE t3 (f3 int , f4 varchar(1) , KEY(f3), KEY (f4,f3)) ;
+INSERT INTO t3 VALUES (1,'t'),(7,'g');
+CREATE TABLE t4
+SELECT f3
+FROM t1 WHERE ( f3 ) NOT IN (
+SELECT f3
+FROM t2
+WHERE f5 IN (
+SELECT f4
+FROM t3
+WHERE t3.f3 < 3
+)
+);
+SELECT * FROM t4;
+f3
+1
+7
+DROP TABLE t1, t2, t3, t4;
+set optimizer_switch=@tmp_860535;
+#
+# BUG#860553: Crash in create_ref_for_key with semijoin + materialization
+#
+CREATE TABLE t1 (f1 int) ;
+CREATE TABLE t2 (f5 varchar(52) NOT NULL) ;
+CREATE TABLE t3 (f1 varchar(3), f4 varchar(52) , KEY (f4), PRIMARY KEY (f1));
+CREATE TABLE t4 (f3 int, KEY (f3));
+INSERT INTO t4 VALUES (17),(20);
+CREATE TABLE t5 (f2 int);
+INSERT INTO t5 VALUES (0),(0);
+SELECT *
+FROM t1
+JOIN t2
+ON ( t2.f5 ) IN (
+SELECT t3.f4
+FROM t3
+WHERE ( 1 ) IN (
+SELECT t4.f3
+FROM t4 , t5
+)
+);
+f1 f5
+DROP TABLE t1, t2, t3, t4, t5;
+#
+# BUG#868908: Crash in check_simple_equality() with semijoin + materialization + prepared statement
+#
+CREATE TABLE t1 ( a int );
+CREATE TABLE t3 ( b int, c int) ;
+CREATE TABLE t2 ( a int ) ;
+CREATE TABLE t4 ( a int , c int) ;
+PREPARE st1 FROM "
+SELECT STRAIGHT_JOIN *
+FROM t1
+WHERE ( 3 ) IN (
+ SELECT t3.b
+ FROM t3
+ LEFT JOIN (
+ t2 STRAIGHT_JOIN t4 ON ( t4.c = t2.a )
+ ) ON ( t4.a = t3.c )
+);
+";
+EXECUTE st1;
+a
+EXECUTE st1;
+a
+DROP TABLE t1,t2,t3,t4;
+#
+# BUG#901032: Wrong result for MIN/MAX on an indexed column with materialization and semijoin
+#
+CREATE TABLE t1 ( a INT, KEY(a) );
+INSERT INTO t1 VALUES (1);
+CREATE TABLE t2 ( b INT );
+INSERT INTO t2 VALUES (2);
+CREATE TABLE t3 ( c INT );
+INSERT INTO t3 VALUES (2);
+SELECT MIN(a) FROM t1, t2 WHERE b IN (SELECT c FROM t3 GROUP BY c);
+MIN(a)
+1
+DROP TABLE t1,t2,t3;
+#
+#
+# BUG#902632: Crash or invalid read at st_join_table::cleanup, st_table::disable_keyread
+#
+CREATE TABLE t1 ( a INT );
+INSERT INTO t1 VALUES (1), (2);
+CREATE TABLE t2 ( b INT );
+INSERT INTO t2 VALUES (3), (4);
+CREATE TABLE t3 ( c INT );
+INSERT INTO t3 VALUES (5), (6);
+SELECT * FROM t1 WHERE EXISTS (
+SELECT DISTINCT b FROM t2
+WHERE b <= a
+AND b IN ( SELECT c FROM t3 GROUP BY c )
+);
+a
+DROP TABLE t1,t2,t3;
+#
+# BUG#901506: Crash in TABLE_LIST::print on EXPLAIN EXTENDED
+#
+CREATE TABLE t1 ( a INT, KEY(a) );
+INSERT INTO t1 VALUES (8);
+EXPLAIN EXTENDED
+SELECT * FROM t1
+WHERE a IN ( SELECT MIN(a) FROM t1 );
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY t1 system NULL NULL NULL NULL 1 100.00
+2 SUBQUERY NULL NULL NULL NULL NULL NULL NULL NULL Select tables optimized away
+Warnings:
+Note 1003 /* select#1 */ select 8 AS `a` from dual where <expr_cache><8>(<in_optimizer>(8,<exists>(/* select#2 */ select min(`test`.`t1`.`a`) from `test`.`t1` having <cache>(8) = <ref_null_helper>(min(`test`.`t1`.`a`)))))
+DROP TABLE t1;
+#
+# BUG#904432: Wrong result with LEFT JOIN, constant table, semijoin=ON,materialization=ON
+#
+CREATE TABLE t1 ( a INT ) ENGINE=MyISAM;
+INSERT INTO t1 VALUES (4);
+CREATE TABLE t2 ( b INT NOT NULL, c INT );
+INSERT INTO t2 VALUES (4,2),(4,2),(4,4),(1,1);
+SELECT * FROM t1 LEFT JOIN t2 ON ( a = b )
+WHERE a IN ( SELECT c FROM t2 );
+a b c
+4 4 2
+4 4 2
+4 4 4
+DROP TABLE t1,t2;
+#
+# BUG#922254: Assertion `0' failed at item_cmpfunc.cc:5899: Item* Item_equal::get_first(JOIN_TAB*, Item*)
+#
+CREATE TABLE t1 ( a VARCHAR(3) );
+CREATE TABLE t2 ( b VARCHAR(3), c VARCHAR(8), KEY(c) );
+INSERT INTO t2 VALUES ('USA','Abilene'),('USA','Akron');
+EXPLAIN
+SELECT * FROM
+( SELECT * FROM t1 ) AS alias1,
+t2 AS alias2
+WHERE b = a AND a IN (
+SELECT alias3.c
+FROM t2 AS alias3, t2 AS alias4
+WHERE alias4.c = alias3.b
+);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables
+3 MATERIALIZED alias3 ALL NULL NULL NULL NULL 2
+3 MATERIALIZED alias4 index c c 11 NULL 2 Using where; Using index; Using join buffer (flat, BNL join)
+DROP TABLE t1,t2;
+#
+# BUG#928048: Query containing IN subquery with OR in the where clause returns a wrong result
+#
+create table t1 (a int, b int);
+insert into t1 values (7,5), (3,3), (5,4), (9,3);
+create table t2 (a int, b int, index i_a(a));
+insert into t2 values
+(4,2), (7,9), (7,4), (3,1), (5,3), (3,1), (9,4), (8,1);
+explain select * from t1 where t1.a in (select a from t2 where t2.a=7 or t2.b<=1);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t1 ALL NULL NULL NULL NULL 4 Using where
+2 MATERIALIZED t2 ALL i_a NULL NULL NULL 8 Using where
+select * from t1 where t1.a in (select a from t2 where t2.a=7 or t2.b<=1);
+a b
+7 5
+3 3
+drop table t1,t2;
+#
+# BUG#933407: Valgrind warnings in mark_as_null_row with materialization+semijoin, STRAIGHT_JOIN, impossible WHERE
+#
+CREATE TABLE t1 (a INT);
+INSERT INTO t1 VALUES (0),(8);
+SELECT STRAIGHT_JOIN MIN(a) FROM t1
+WHERE a IN (
+SELECT a FROM t1
+WHERE 'condition'='impossible'
+ );
+MIN(a)
+NULL
+DROP TABLE t1;
+#
+# BUG#938131: Subquery materialization is not used in CREATE TABLE SELECT
+#
+CREATE TABLE t1(a int);
+INSERT INTO t1 values(1),(2);
+CREATE TABLE t2(a int);
+INSERT INTO t2 values(1),(2);
+# Should use Materialization:
+EXPLAIN SELECT * FROM t1 WHERE a IN (SELECT * FROM t2 GROUP BY a HAVING a > 1);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t1 ALL NULL NULL NULL NULL 2 Using where
+2 MATERIALIZED t2 ALL NULL NULL NULL NULL 2 Using temporary
+flush status;
+CREATE TABLE t3 SELECT * FROM t1 WHERE a IN (SELECT * FROM t2 GROUP BY a HAVING a > 1);
+SHOW STATUS LIKE 'Created_tmp_tables';
+Variable_name Value
+Created_tmp_tables 3
+DROP TABLE t1,t2,t3;
+#
+# BUG#939009: Crash with aggregate function in IN subquery
+#
+SET @save_optimizer_switch=@@optimizer_switch;
+SET optimizer_switch='materialization=on,semijoin=on';
+CREATE TABLE t1 (a int, b int);
+INSERT INTO t1 VALUES (7,1), (4,2), (7,7);
+CREATE TABLE t2 ( c INT );
+INSERT INTO t2 VALUES (4), (7), (6);
+EXPLAIN EXTENDED
+SELECT * FROM t1
+WHERE a IN (SELECT MAX(c) FROM t2) AND b=7 AND (a IS NULL OR a=b);
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY <subquery2> const distinct_key distinct_key 4 const 1 100.00
+1 PRIMARY t1 ALL NULL NULL NULL NULL 3 100.00 Using where; Using join buffer (flat, BNL join)
+2 MATERIALIZED t2 ALL NULL NULL NULL NULL 3 100.00
+Warnings:
- Note 1003 /* select#1 */ select `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b` from <materialize> (/* select#2 */ select max(`test`.`t2`.`c`) from `test`.`t2`) join `test`.`t1` where `test`.`t1`.`b` = 7 and `test`.`t1`.`a` = `<subquery2>`.`MAX(c)` and (<cache>(`<subquery2>`.`MAX(c)` is null) or `<subquery2>`.`MAX(c)` = 7)
++Note 1003 /* select#1 */ select `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b` from <materialize> (/* select#2 */ select max(`test`.`t2`.`c`) from `test`.`t2` having `MAX(c)` is null or `MAX(c)` = 7) join `test`.`t1` where `test`.`t1`.`b` = 7 and `test`.`t1`.`a` = `<subquery2>`.`MAX(c)` and (<cache>(`<subquery2>`.`MAX(c)` is null) or `<subquery2>`.`MAX(c)` = 7)
+SELECT * FROM t1
+WHERE a IN (SELECT MAX(c) FROM t2) AND b=7 AND (a IS NULL OR a=b);
+a b
+7 7
+EXPLAIN
+SELECT * FROM t1
+WHERE a IN (SELECT MAX(c) FROM t2 WHERE c < 4) AND b=7 AND (a IS NULL OR a=b);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY <subquery2> const distinct_key distinct_key 4 const 1
+1 PRIMARY t1 ALL NULL NULL NULL NULL 3 Using where; Using join buffer (flat, BNL join)
+2 MATERIALIZED t2 ALL NULL NULL NULL NULL 3 Using where
+SELECT * FROM t1
+WHERE a IN (SELECT MAX(c) FROM t2 WHERE c < 4) AND b=7 AND (a IS NULL OR a=b);
+a b
+SET optimizer_switch=@save_optimizer_switch;
+DROP TABLE t1,t2;
+#
+# BUG#946055: Crash with semijoin IN subquery when hash join is used
+#
+CREATE TABLE t1 (a int);
+INSERT INTO t1 VALUES (7);
+CREATE TABLE t2 (b int, c int, d varchar(1), e varchar(1), KEY (c), KEY (d, c));
+INSERT INTO t2 VALUES
+(4,2,'v','v'), (6,1,'v','v'), (0,5,'x','x'), (7,1,'x','x'),
+(7,3,'i','i'), (7,1,'e','e'), (1,4,'p','p'), (1,2,'j','j');
+SET @save_optimizer_switch=@@optimizer_switch;
+SET @save_join_cache_level=@@join_cache_level;
+SET join_cache_level=2;
+EXPLAIN
+SELECT a, c FROM t1, t2
+WHERE (a, c) IN (SELECT s1.b, s1.c FROM t2 AS s1, t2 AS s2
+WHERE s2.d = s1.e AND s1.e = (SELECT MAX(e) FROM t2));
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t1 system NULL NULL NULL NULL 1
+1 PRIMARY t2 index NULL c 5 NULL 8 Using where; Using index
+2 MATERIALIZED s2 ref d d 4 const 2 Using where; Using index
+2 MATERIALIZED s1 ALL NULL NULL NULL NULL 8 Using where; Using join buffer (flat, BNL join)
+3 SUBQUERY t2 ALL NULL NULL NULL NULL 8
+SELECT a, c FROM t1, t2
+WHERE (a, c) IN (SELECT s1.b, s1.c FROM t2 AS s1, t2 AS s2
+WHERE s2.d = s1.e AND s1.e = (SELECT MAX(e) FROM t2));
+a c
+7 1
+7 1
+7 1
+SET optimizer_switch='join_cache_hashed=on';
+SET join_cache_level=4;
+EXPLAIN
+SELECT a, c FROM t1, t2
+WHERE (a, c) IN (SELECT s1.b, s1.c FROM t2 AS s1, t2 AS s2
+WHERE s2.d = s1.e AND s1.e = (SELECT MAX(e) FROM t2));
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t1 system NULL NULL NULL NULL 1
+1 PRIMARY t2 index NULL c 5 NULL 8 Using where; Using index
+2 MATERIALIZED s2 ref d d 4 const 2 Using where; Using index
+2 MATERIALIZED s1 ALL NULL NULL NULL NULL 8 Using where; Using join buffer (flat, BNL join)
+3 SUBQUERY t2 ALL NULL NULL NULL NULL 8
+SELECT a, c FROM t1, t2
+WHERE (a, c) IN (SELECT s1.b, s1.c FROM t2 AS s1, t2 AS s2
+WHERE s2.d = s1.e AND s1.e = (SELECT MAX(e) FROM t2));
+a c
+7 1
+7 1
+7 1
+SET optimizer_switch=@save_optimizer_switch;
+SET join_cache_level=@save_join_cache_level;
+DROP TABLE t1,t2;
+#
+# BUG#952297: Server crashes on 2nd execution of PS in Field::is_null with semijoin+materialization
+#
+CREATE TABLE t1 ( a VARCHAR(1) );
+INSERT INTO t1 VALUES ('y'),('z');
+CREATE TABLE t2 ( b VARCHAR(1), c VARCHAR(1) );
+INSERT INTO t2 VALUES ('v','v'),('v','v');
+CREATE VIEW v2 AS SELECT * FROM t2;
+PREPARE ps FROM '
+SELECT a FROM t1, v2
+WHERE ( c, b ) IN ( SELECT b, b FROM t2 )
+GROUP BY a ';
+EXECUTE ps;
+a
+y
+z
+EXECUTE ps;
+a
+y
+z
+DROP VIEW v2;
+DROP TABLE t1, t2;
+#
+# BUG#1000269: Wrong result (extra rows) with semijoin+materialization, IN subqueries, join_cache_level>0
+#
+CREATE TABLE t1 (a1 VARCHAR(1), a2 VARCHAR(1)) ENGINE=MyISAM;
+INSERT INTO t1 VALUES ('b','b'),('e','e');
+CREATE TABLE t2 (b1 VARCHAR(1), b2 VARCHAR(1), KEY(b1)) ENGINE=MyISAM;
+INSERT INTO t2 VALUES ('v','v'),('s','s'),('l','l'), ('y','y'),('c','c'),('i','i');
+SELECT * FROM t1, t2 WHERE b1 IN ( SELECT b2 FROM t2 WHERE b1 > 'o' ) AND ( b1 < 'l' OR a1 IN ('b','c') );
+a1 a2 b1 b2
+b b v v
+b b s s
+b b y y
+DROP TABLE t1,t2;
+#
+# MDEV-4465: Reproducible crash (mysqld got signal 11) in multi_delete::initialize_tables with semijoin+materialization
+#
+CREATE TABLE t1 (
+id int(11) NOT NULL
+);
+CREATE TABLE t2 (
+id int(11) NOT NULL,
+a_id int(11) DEFAULT NULL
+);
+insert into t1 values (1), (2), (3);
+insert into t2 values (1, 1), (2, 1), (3, 1), (4, 2), (5, 3), (6, 3), (7, 3);
+delete t2 from t2 where a_id in (select * from (select t1.id from t1 limit 2) as x);
+drop table t1,t2;
+# This must be at the end:
+set optimizer_switch=@subselect_sj_mat_tmp;
+set join_cache_level=@save_join_cache_level;
+#
+# MDEV-4908: Assertion `((Item_cond *) cond)->functype() ==
+# ((Item_cond *) new_item)->functype()' fails on a query with
+# IN and equal conditions, AND/OR, materialization+semijoin
+#
+SET @save_optimizer_switch=@@optimizer_switch;
+SET optimizer_switch = 'materialization=on,semijoin=on';
+CREATE TABLE t1 (pk INT, a INT, b INT, PRIMARY KEY(pk)) ENGINE=MyISAM;
+INSERT INTO t1 VALUES (1,3,5),(2,4,6);
+SELECT * FROM t1 WHERE 8 IN ( SELECT MIN(pk) FROM t1 ) AND ( pk = a OR pk = b );
+pk a b
+drop table t1;
+SET optimizer_switch=@save_optimizer_switch;
+#
+# MDEV-5011: ERROR Plugin 'MEMORY' has ref_count=1 after shutdown for SJM queries
+#
+CREATE TABLE t1 (pk INT, a INT, b INT, PRIMARY KEY(pk)) ENGINE=MyISAM;
+INSERT INTO t1 VALUES (1,3,5),(2,4,6);
+SELECT * FROM t1 WHERE 8 IN (SELECT MIN(pk) FROM t1) AND (pk = a OR pk = b);
+pk a b
+DROP TABLE t1;
+#
+# MDEV-5368: Server crashes in Item_in_subselect::optimize on 2nd
+# execution of PS with IN subqueries, materialization+semijoin
+#
+CREATE TABLE t1 (a INT) ENGINE=MyISAM;
+INSERT INTO t1 VALUES (1),(3);
+CREATE TABLE t2 (b INT) ENGINE=MyISAM;
+CREATE ALGORITHM=MERGE VIEW v2 AS SELECT * FROM t2;
+INSERT INTO t2 VALUES (8),(9);
+PREPARE stmt FROM "
+SELECT * FROM t1 WHERE 1 IN ( SELECT b FROM v2 WHERE 2 IN ( SELECT MAX(a) FROM t1 ) )
+";
+EXECUTE stmt;
+a
+EXECUTE stmt;
+a
+DROP TABLE t1, t2;
+DROP VIEW v2;
+#
+# MDEV-5811: Server crashes in best_access_path with materialization+semijoin and big_tables=ON
+#
+SET @tmp_mdev5811= @@big_tables;
+SET big_tables = ON;
+CREATE TABLE t1 (a INT);
+INSERT INTO t1 VALUES (1),(2);
+CREATE TABLE t2 (b INT);
+INSERT INTO t2 VALUES (3),(4);
+SELECT * FROM t1 AS t1_1, t1 AS t1_2
+WHERE ( t1_1.a, t1_2.a ) IN ( SELECT MAX(b), MIN(b) FROM t2 );
+a a
+DROP TABLE t1,t2;
+SET big_tables=@tmp_mdev5811;
+# End of 5.3 tests
+#
+# MDEV-5056: Wrong result (extra rows) with materialization+semijoin, IN subqueries
+#
+set @tmp_mdev5056=@@join_cache_level;
+SET join_cache_level = 2;
+CREATE TABLE t1 ( c1 VARCHAR(2), c2 VARCHAR(2), INDEX(c1) ) ENGINE=MyISAM;
+INSERT INTO t1 VALUES
+('JP','OM'),('VA','JP'),('CA','ML'),('ML','EG'),('DK','CA'),
+('DK','QA'),('YE','PL'),('TR','ZW'),('DK','SK'),('SK','DK'),
+('RO','ML'),('ML','BG'),('BG','ZW'),('ZW','GE'),('GE','JP'),
+('PL','EG'),('QA','YE'),('WF','DK'),('DK','JP'),('EG','OM');
+CREATE TABLE t2 ( c3 VARCHAR(2), c4 VARCHAR(2) ) ENGINE=MyISAM;
+INSERT INTO t2 VALUES ('CA','ML'),('IN','HU'),('HU','IN');
+SELECT * FROM t1 AS alias1, t1 AS alias2
+WHERE ( alias2.c2, alias1.c1 ) IN ( SELECT c4, c3 FROM t2 ) AND alias1.c1 IN ( SELECT c2 FROM t1 );
+c1 c2 c1 c2
+CA ML CA ML
+CA ML RO ML
+DROP TABLE t1,t2;
+set join_cache_level=@tmp_mdev5056;
+#
+# MDEV-5368: Server crashes in Item_in_subselect::optimize on 2nd
+# execution of PS with IN subqueries, materialization+semijoin
+#
+CREATE TABLE t1 (a INT) ENGINE=MyISAM;
+INSERT INTO t1 VALUES (1),(3);
+CREATE TABLE t2 (b INT) ENGINE=MyISAM;
+CREATE ALGORITHM=MERGE VIEW v2 AS SELECT * FROM t2;
+INSERT INTO t2 VALUES (8),(9);
+PREPARE stmt FROM "
+SELECT * FROM t1 WHERE 1 IN ( SELECT b FROM v2 WHERE 2 IN ( SELECT MAX(a) FROM t1 ) )
+";
+EXECUTE stmt;
+a
+EXECUTE stmt;
+a
+DROP TABLE t1, t2;
+DROP VIEW v2;
+#
+# MDEV-6289 : Unexpected results when querying information_schema
+#
+CREATE TABLE t1 (
+id int(11) unsigned NOT NULL AUTO_INCREMENT,
+db varchar(254) NOT NULL DEFAULT '',
+PRIMARY KEY (id),
+UNIQUE KEY db (db)
+) DEFAULT CHARSET=utf8;
+INSERT INTO t1 (db) VALUES ('mysqltest1'),('mysqltest2'),('mysqltest3'),('mysqltest4');
+drop database if exists mysqltest1;
+drop database if exists mysqltest2;
+drop database if exists mysqltest3;
+drop database if exists mysqltest4;
+create database mysqltest1;
+create database mysqltest2;
+create database mysqltest3;
+create database mysqltest4;
+SELECT db FROM t1 WHERE db IN (SELECT SCHEMA_NAME FROM information_schema.schemata) ORDER BY db DESC;
+db
+mysqltest4
+mysqltest3
+mysqltest2
+mysqltest1
+EXPLAIN EXTENDED
+SELECT db FROM t1 WHERE db IN (SELECT SCHEMA_NAME FROM information_schema.schemata) ORDER BY db DESC;
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY <subquery2> ALL distinct_key NULL NULL NULL 2 100.00 Using temporary; Using filesort
+1 PRIMARY t1 eq_ref db db 764 information_schema.schemata.SCHEMA_NAME 1 100.00 Using where; Using index
+2 MATERIALIZED schemata ALL NULL NULL NULL NULL NULL NULL
+Warnings:
+Note 1003 select `test`.`t1`.`db` AS `db` from `test`.`t1` semi join (`information_schema`.`schemata`) where `test`.`t1`.`db` = `information_schema`.`schemata`.`SCHEMA_NAME` order by `test`.`t1`.`db` desc
+drop table t1;
+drop database mysqltest1;
+drop database mysqltest2;
+drop database mysqltest3;
+drop database mysqltest4;
+#
+# MDEV-7810 Wrong result on execution of a query as a PS
+# (both 1st and further executions)
+CREATE TABLE t1 (a INT NOT NULL) ENGINE=MyISAM;
+INSERT INTO t1 VALUES (0),(8);
+SELECT a FROM (SELECT DISTINCT * FROM t1) AS sq WHERE a IN (SELECT MIN(t2.a) FROM (t1 AS t2));
+a
+0
+PREPARE stmt FROM "
+SELECT a FROM (SELECT DISTINCT * FROM t1) AS sq WHERE a IN (SELECT MIN(t2.a) FROM (t1 AS t2))
+";
+execute stmt;
+a
+0
+execute stmt;
+a
+0
+drop table t1;
+#
+# MDEV-12429: IN subquery used in WHERE of EXISTS subquery
+#
+CREATE TABLE t1 (
+pk INT, f1 INT NOT NULL, f2 VARCHAR(3), f3 INT NULL, PRIMARY KEY(pk)) ENGINE=MyISAM;
+INSERT INTO t1 VALUES (1,1,'foo',8), (2,5,'bar',7);
+SELECT sq1.f2 FROM t1 AS sq1
+WHERE EXISTS ( SELECT * FROM t1 AS sq2
+WHERE sq1.`pk` IN ( SELECT f1 FROM t1 ) AND sq2.f1 = sq1.f1 );
+f2
+foo
+set @save_optimizer_switch= @@optimizer_switch;
+set optimizer_switch='exists_to_in=off';
+EXPLAIN
+SELECT sq1.f2 FROM t1 AS sq1
+WHERE EXISTS ( SELECT * FROM t1 AS sq2
+WHERE sq1.`pk` IN ( SELECT f1 FROM t1 ) AND sq2.f1 = sq1.f1 );
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY sq1 ALL NULL NULL NULL NULL 2 Using where
+2 DEPENDENT SUBQUERY <subquery3> eq_ref distinct_key distinct_key 4 func 1
+2 DEPENDENT SUBQUERY sq2 ALL NULL NULL NULL NULL 2 Using where; Using join buffer (flat, BNL join)
+3 MATERIALIZED t1 ALL NULL NULL NULL NULL 2
+# this checks the result set above
+set optimizer_switch= 'materialization=off,semijoin=off';
+SELECT sq1.f2 FROM t1 AS sq1
+WHERE EXISTS ( SELECT * FROM t1 AS sq2
+WHERE sq1.`pk` IN ( SELECT f1 FROM t1 ) AND sq2.f1 = sq1.f1 );
+f2
+foo
+set optimizer_switch= @save_optimizer_switch;
+DROP TABLE t1;
+#
+# MDEV-12145: IN subquery used in WHERE of EXISTS subquery
+#
+CREATE TABLE t1 (f1 INT) ENGINE=MyISAM;
+INSERT INTO t1 VALUES (4),(6);
+CREATE TABLE t2 (i2 INT, KEY(i2)) ENGINE=MyISAM;
+INSERT INTO t2 VALUES (8),(7),(1);
+CREATE TABLE t3 (f3 INT, i3 INT, KEY(i3)) ENGINE=MyISAM;
+INSERT INTO t3 VALUES (8,0),(6,3),(2,8),(3,8),(1,6),(0,0),(1,0),(1,5);
+set @save_optimizer_switch= @@optimizer_switch;
+set optimizer_switch='exists_to_in=off';
+SELECT * FROM t1
+WHERE EXISTS ( SELECT * FROM t2, t3
+WHERE i3 = i2 AND f1 IN ( SELECT f3 FROM t3 ) );
+f1
+6
+EXPLAIN EXTENDED
+SELECT * FROM t1
+WHERE EXISTS ( SELECT * FROM t2, t3
+WHERE i3 = i2 AND f1 IN ( SELECT f3 FROM t3 ) );
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY t1 ALL NULL NULL NULL NULL 2 100.00 Using where
+2 DEPENDENT SUBQUERY <subquery3> eq_ref distinct_key distinct_key 4 func 1 100.00
+2 DEPENDENT SUBQUERY t2 index i2 i2 5 NULL 3 100.00 Using where; Using index; Using join buffer (flat, BNL join)
+2 DEPENDENT SUBQUERY t3 ref i3 i3 5 test.t2.i2 2 100.00 Using index
+3 MATERIALIZED t3 ALL NULL NULL NULL NULL 8 100.00
+Warnings:
+Note 1276 Field or reference 'test.t1.f1' of SELECT #2 was resolved in SELECT #1
+Note 1003 /* select#1 */ select `test`.`t1`.`f1` AS `f1` from `test`.`t1` where <expr_cache><`test`.`t1`.`f1`>(exists(/* select#2 */ select 1 from `test`.`t2` semi join (`test`.`t3`) join `test`.`t3` where `test`.`t3`.`i3` = `test`.`t2`.`i2` and `test`.`t1`.`f1` = `test`.`t3`.`f3`))
+# this checks the result set above
+set optimizer_switch= 'materialization=off,semijoin=off';
+SELECT * FROM t1
+WHERE EXISTS ( SELECT * FROM t2, t3
+WHERE i3 = i2 AND f1 IN ( SELECT f3 FROM t3 ) );
+f1
+6
+set optimizer_switch= @save_optimizer_switch;
+DROP TABLE t1,t2,t3;
+#
+# MDEV-9686: IN subquery used in WHERE of a subquery from select list
+#
+CREATE TABLE t1 (pk INT PRIMARY KEY, f1 INT);
+INSERT INTO t1 VALUES (1, 4),(2, 3),(3, 3),(4, 6),(5, 3);
+CREATE TABLE t2 (f2 INT);
+INSERT INTO t2 VALUES (1),(2),(3),(4),(5);
+# t1.pk is always IN ( SELECT f2 FROM t2 ),
+# so the IN condition should be true for every row,
+# and thus COUNT(*) should always return 5
+SELECT pk, f1, ( SELECT COUNT(*) FROM t2
+WHERE t1.pk IN ( SELECT f2 FROM t2 ) ) AS sq FROM t1;
+pk f1 sq
+1 4 5
+2 3 5
+3 3 5
+4 6 5
+5 3 5
+EXPLAIN EXTENDED
+SELECT pk, f1, ( SELECT COUNT(*) FROM t2
+WHERE t1.pk IN ( SELECT f2 FROM t2 ) ) AS sq FROM t1;
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY t1 ALL NULL NULL NULL NULL 5 100.00
+2 DEPENDENT SUBQUERY <subquery3> eq_ref distinct_key distinct_key 4 func 1 100.00
+2 DEPENDENT SUBQUERY t2 ALL NULL NULL NULL NULL 5 100.00 Using join buffer (flat, BNL join)
+3 MATERIALIZED t2 ALL NULL NULL NULL NULL 5 100.00
+Warnings:
+Note 1276 Field or reference 'test.t1.pk' of SELECT #2 was resolved in SELECT #1
+Note 1003 /* select#1 */ select `test`.`t1`.`pk` AS `pk`,`test`.`t1`.`f1` AS `f1`,<expr_cache><`test`.`t1`.`pk`>((/* select#2 */ select count(0) from `test`.`t2` semi join (`test`.`t2`) where `test`.`t1`.`pk` = `test`.`t2`.`f2`)) AS `sq` from `test`.`t1`
+# this checks the result set above
+set @save_optimizer_switch= @@optimizer_switch;
+set optimizer_switch= 'materialization=off,semijoin=off';
+SELECT pk, f1, ( SELECT COUNT(*) FROM t2
+WHERE t1.pk IN ( SELECT f2 FROM t2 ) ) AS sq FROM t1;
+pk f1 sq
+1 4 5
+2 3 5
+3 3 5
+4 6 5
+5 3 5
+set optimizer_switch= @save_optimizer_switch;
+DROP TABLE t1,t2;
+#
+# mdev-12838: scan of materialized of semi-join subquery in join
+#
+set @save_optimizer_switch=@@optimizer_switch;
+CREATE TABLE t1 (
+dispatch_group varchar(32),
+assignment_group varchar(32),
+sys_id char(32),
+PRIMARY KEY (sys_id),
+KEY idx1 (dispatch_group),
+KEY idx2 (assignment_group)
+) ENGINE=MyISAM;
+CREATE TABLE t2 (
+ugroup varchar(32),
+user varchar(32),
+sys_id char(32),
+PRIMARY KEY (sys_id),
+KEY idx3 (ugroup),
+KEY idx4 (user)
+) ENGINE=MyISAM;
+CREATE TABLE t3 (
+type mediumtext,
+sys_id char(32),
+PRIMARY KEY (sys_id)
+) ENGINE=MyISAM;
+set optimizer_switch='materialization=off';
+explain SELECT t1.assignment_group
+FROM t1, t3
+WHERE t1.assignment_group = t3.sys_id AND
+t1.dispatch_group IN
+(SELECT t2.ugroup
+FROM t2, t3 t3_i
+WHERE t2.ugroup = t3_i.sys_id AND
+t3_i.type LIKE '59e22fb137032000158bbfc8bcbe5d52' AND
+t2.user = '86826bf03710200044e0bfc8bcbe5d79');
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t2 ref idx3,idx4 idx4 35 const 2 Using index condition; Using where; Start temporary
+1 PRIMARY t3_i eq_ref PRIMARY PRIMARY 32 test.t2.ugroup 1 Using index condition; Using where
+1 PRIMARY t1 ref idx1,idx2 idx1 35 test.t3_i.sys_id 2 Using index condition; Using where; End temporary
+1 PRIMARY t3 eq_ref PRIMARY PRIMARY 32 test.t1.assignment_group 1 Using where; Using index
+SELECT t1.assignment_group
+FROM t1, t3
+WHERE t1.assignment_group = t3.sys_id AND
+t1.dispatch_group IN
+(SELECT t2.ugroup
+FROM t2, t3 t3_i
+WHERE t2.ugroup = t3_i.sys_id AND
+t3_i.type LIKE '59e22fb137032000158bbfc8bcbe5d52' AND
+t2.user = '86826bf03710200044e0bfc8bcbe5d79');
+assignment_group
+df50316637232000158bbfc8bcbe5d23
+e08fad2637232000158bbfc8bcbe5d39
+ec70316637232000158bbfc8bcbe5d60
+7b10fd2637232000158bbfc8bcbe5d30
+ebb4620037332000158bbfc8bcbe5d89
+set optimizer_switch='materialization=on';
+explain SELECT t1.assignment_group
+FROM t1, t3
+WHERE t1.assignment_group = t3.sys_id AND
+t1.dispatch_group IN
+(SELECT t2.ugroup
+FROM t2, t3 t3_i
+WHERE t2.ugroup = t3_i.sys_id AND
+t3_i.type LIKE '59e22fb137032000158bbfc8bcbe5d52' AND
+t2.user = '86826bf03710200044e0bfc8bcbe5d79');
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY <subquery2> ALL distinct_key NULL NULL NULL 2
+1 PRIMARY t1 ref idx1,idx2 idx1 35 test.t2.ugroup 2 Using where
+1 PRIMARY t3 eq_ref PRIMARY PRIMARY 32 test.t1.assignment_group 1 Using where; Using index
+2 MATERIALIZED t2 ref idx3,idx4 idx4 35 const 2 Using index condition; Using where
+2 MATERIALIZED t3_i eq_ref PRIMARY PRIMARY 32 test.t2.ugroup 1 Using index condition; Using where
+SELECT t1.assignment_group
+FROM t1, t3
+WHERE t1.assignment_group = t3.sys_id AND
+t1.dispatch_group IN
+(SELECT t2.ugroup
+FROM t2, t3 t3_i
+WHERE t2.ugroup = t3_i.sys_id AND
+t3_i.type LIKE '59e22fb137032000158bbfc8bcbe5d52' AND
+t2.user = '86826bf03710200044e0bfc8bcbe5d79');
+assignment_group
+df50316637232000158bbfc8bcbe5d23
+e08fad2637232000158bbfc8bcbe5d39
+ec70316637232000158bbfc8bcbe5d60
+7b10fd2637232000158bbfc8bcbe5d30
+ebb4620037332000158bbfc8bcbe5d89
+DROP TABLE t1,t2,t3;
+set optimizer_switch=@save_optimizer_switch;
+# End of 5.5 tests
+#
+# MDEV-7220: Materialization strategy is not used for REPLACE ... SELECT
+#
+create table t0(a int);
+insert into t0 values (0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
+create table t1 (a int, b int, c int);
+insert into t1
+select A.a+B.a*10+C.a*100, A.a+B.a*10+C.a*100, A.a+B.a*10+C.a*100
+from t0 A, t0 B, t0 C;
+create table t2 (a int, b int, c int);
+insert into t2 select A.a, A.a, A.a from t1 A;
+insert into t2 select * from t2;
+insert into t2 select * from t2;
+create table t3 as select * from t2 limit 1;
+# The testcase only makes sense if the following uses Materialization:
+explain
+select * from t1 where (a,b) in (select max(a),b from t2 group by b);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t1 ALL NULL NULL NULL NULL 1000 Using where
+1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 8 test.t1.a,test.t1.b 1
+2 MATERIALIZED t2 ALL NULL NULL NULL NULL 4000 Using temporary
+flush status;
+replace into t3
+select * from t1 where (a,b) in (select max(a),b from t2 group by b);
+# Sequential reads:
+# 1K is read from t1
+# 4K is read from t2
+# 1K groups is read from the tmp. table
+#
+# Lookups:
+# 4K lookups in group by table
+# 1K lookups in temp.table
+#
+# Writes:
+# 2x 1K writes to temporary tables (grouping table and subquery materialization table
+#
+# The point is that neither counter should be in the millions (this
+# will happen if Materialization is not used
+show status where Variable_name like 'Handler_read%' or Variable_name like 'Handler_%write%';
+Variable_name Value
+Handler_read_first 0
+Handler_read_key 5000
+Handler_read_last 0
+Handler_read_next 0
+Handler_read_prev 0
+Handler_read_retry 0
+Handler_read_rnd 0
+Handler_read_rnd_deleted 0
+Handler_read_rnd_next 6003
+Handler_tmp_write 2000
+Handler_write 1000
+drop table t0,t1,t2,t3;
+#
+# MDEV-7971: Assertion `name != __null' failed in ACL_internal_schema_registry::lookup
+# on 2nd execution os PS with multi-table update
+#
+CREATE TABLE t1 (f1 INT);
+INSERT INTO t1 VALUES (1),(2);
+CREATE TABLE t2 (f2 INT);
+INSERT INTO t2 VALUES (3),(4);
+CREATE TABLE t3 (f3 INT);
+INSERT INTO t3 VALUES (5),(6);
+PREPARE stmt FROM '
+ UPDATE t1, t2
+ SET f1 = 5
+ WHERE 8 IN ( SELECT MIN(f3) FROM t3 )
+';
+EXECUTE stmt;
+EXECUTE stmt;
+DROP TABLE t1,t2,t3;
+#
+# MDEV-10389: Query returns different results on a debug vs non-debug build of the same revision
+#
+CREATE TABLE t1 (i1 INT, i2 INT NOT NULL);
+INSERT INTO t1 VALUES (1,4),(2,6);
+SELECT * FROM t1 AS alias1
+WHERE alias1.i1 IN (
+SELECT i1 FROM t1 WHERE alias1.i2 IN ( SELECT i2 FROM t1 HAVING i2 <> 7 )
+);
+i1 i2
+1 4
+2 6
+DROP TABLE t1;
+set @subselect_mat_test_optimizer_switch_value=null;
+set @@optimizer_switch='materialization=on,in_to_exists=off,semijoin=off';
+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);
+create table t1 (a int);
+insert into t1 values (0),(1),(2);
+explain select a, a in (select a from t1) from t0;
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t0 ALL NULL NULL NULL NULL 3
+2 MATERIALIZED t1 ALL NULL NULL NULL NULL 3
+select a, a in (select a from t1) from t0;
+a a in (select a from t1)
+0 1
+1 1
+2 1
+prepare s from 'select a, a in (select a from t1) from t0';
+execute s;
+a a in (select a from t1)
+0 1
+1 1
+2 1
+update t1 set a=123;
+execute s;
+a a in (select a from t1)
+0 0
+1 0
+2 0
+drop table t0, t1;
+#
+# LPBUG#609121: RQG: wrong result on aggregate + NOT IN + HAVING and
+# partial_match_table_scan=on
+#
+create table t1 (c1 int);
+create table t2 (c2 int);
+insert into t1 values (1);
+insert into t2 values (2);
+set @@optimizer_switch='semijoin=off';
+EXPLAIN
+SELECT SUM(c1) c1_sum FROM t1 WHERE c1 IN (SELECT c2 FROM t2);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t1 system NULL NULL NULL NULL 1
+2 MATERIALIZED t2 system NULL NULL NULL NULL 1
+SELECT SUM(c1) c1_sum FROM t1 WHERE c1 IN (SELECT c2 FROM t2);
+c1_sum
+NULL
+EXPLAIN
+SELECT SUM(c1) c1_sum FROM t1 WHERE c1 IN (SELECT c2 FROM t2) HAVING c1_sum;
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t1 system NULL NULL NULL NULL 1
+2 MATERIALIZED t2 system NULL NULL NULL NULL 1
+SELECT SUM(c1) c1_sum FROM t1 WHERE c1 IN (SELECT c2 FROM t2) HAVING c1_sum;
+c1_sum
+drop table t1, t2;
+#
+# BUG#52344 - Subquery materialization:
+# Assertion if subquery in on-clause of outer join
+#
+set @@optimizer_switch='semijoin=off';
+CREATE TABLE t1 (i INTEGER);
+INSERT INTO t1 VALUES (10);
+CREATE TABLE t2 (j INTEGER);
+INSERT INTO t2 VALUES (5);
+CREATE TABLE t3 (k INTEGER);
+EXPLAIN
+SELECT i FROM t1 LEFT JOIN t2 ON (j) IN (SELECT k FROM t3);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t1 system NULL NULL NULL NULL 1
+1 PRIMARY t2 ALL NULL NULL NULL NULL 1 Using where
+2 MATERIALIZED t3 system NULL NULL NULL NULL 0 Const row not found
+SELECT i FROM t1 LEFT JOIN t2 ON (j) IN (SELECT k FROM t3);
+i
+10
+EXPLAIN
+SELECT i FROM t1 LEFT JOIN t2 ON (j) IN (SELECT max(k) FROM t3);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t1 system NULL NULL NULL NULL 1
+1 PRIMARY t2 ALL NULL NULL NULL NULL 1 Using where
+2 MATERIALIZED t3 system NULL NULL NULL NULL 0 Const row not found
+SELECT i FROM t1 LEFT JOIN t2 ON (j) IN (SELECT max(k) FROM t3);
+i
+10
+DROP TABLE t1, t2, t3;
+#
+# LPBUG#611622/BUG#52344: Subquery materialization: Assertion
+# if subquery in on-clause of outer join
+#
+CREATE TABLE t1 (c1 int);
+INSERT INTO t1 VALUES (1),(2);
+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;
+c2 c2
+10 NULL
+EXECUTE st1;
+c2 c2
+10 NULL
+DROP TABLE t1, t2;
+#
+# Testcase backport: 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 @@optimizer_switch='default,semijoin=on,materialization=on';
+EXPLAIN SELECT pk FROM t1 WHERE (a) IN (SELECT a FROM t2 WHERE pk > 0);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t1 ALL NULL NULL NULL NULL 2
+1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 4 func 1
+2 MATERIALIZED t2 range PRIMARY PRIMARY 4 NULL 2 Using index condition; Using where
+SELECT pk FROM t1 WHERE (a) IN (SELECT a FROM t2 WHERE pk > 0);
+pk
+2
+SELECT pk FROM t1 WHERE (b,c,d) IN (SELECT b,c,d FROM t2 WHERE pk > 0);
+pk
+2
+DROP TABLE t1, t2;
+#
+# BUG#724228: Wrong result with materialization=on and three aggregates in maria-5.3-mwl90
+#
+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);
+f1
+16
+SET @@join_cache_level = @_save_join_cache_level;
+SET @@optimizer_switch = @_save_optimizer_switch;
+drop table t1, t2, t3;
+#
+# LPBUG#719198 Ordered_key::cmp_key_with_search_key(rownum_t): Assertion `!compare_pred[i]->null_value'
+# failed with subquery on both sides of NOT IN and materialization
+#
+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);
+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);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY NULL NULL NULL NULL NULL NULL NULL Impossible WHERE
+3 MATERIALIZED t1 ALL NULL NULL NULL NULL 2
+2 SUBQUERY NULL NULL NULL NULL NULL NULL NULL no matching row in const table
+SELECT * FROM t2 WHERE (SELECT f3a FROM t3) NOT IN (SELECT f1a FROM t1);
+f2
+EXPLAIN
+SELECT (SELECT f3a FROM t3) NOT IN (SELECT f1a FROM t1);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY NULL NULL NULL NULL NULL NULL NULL No tables used
+3 SUBQUERY t1 ALL NULL NULL NULL NULL 2 Using where
+2 SUBQUERY NULL NULL NULL NULL NULL NULL NULL no matching row in const table
+SELECT (SELECT f3a FROM t3) NOT IN (SELECT f1a FROM t1);
+(SELECT f3a FROM t3) NOT IN (SELECT f1a FROM t1)
+NULL
+EXPLAIN
+SELECT * FROM t2 WHERE (SELECT f3a, f3b FROM t3) NOT IN (SELECT f1a, f1b FROM t1);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY NULL NULL NULL NULL NULL NULL NULL Impossible WHERE
+3 MATERIALIZED t1 ALL NULL NULL NULL NULL 2
+2 SUBQUERY NULL NULL NULL NULL NULL NULL NULL no matching row in const table
+SELECT * FROM t2 WHERE (SELECT f3a, f3b FROM t3) NOT IN (SELECT f1a, f1b FROM t1);
+f2
+EXPLAIN
+SELECT (SELECT f3a, f3b FROM t3) NOT IN (SELECT f1a, f1b FROM t1);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY NULL NULL NULL NULL NULL NULL NULL No tables used
+3 SUBQUERY t1 ALL NULL NULL NULL NULL 2 Using where
+2 SUBQUERY NULL NULL NULL NULL NULL NULL NULL no matching row in const table
+SELECT (SELECT f3a, f3b FROM t3) NOT IN (SELECT f1a, f1b FROM t1);
+(SELECT f3a, f3b FROM t3) NOT IN (SELECT f1a, f1b FROM t1)
+NULL
+drop table t1, t2, t3;
+#
+# LPBUG#730604 Assertion `bit < (map)->n_bits' failed in maria-5.3 with
+# partial_match_rowid_merge
+#
+CREATE TABLE t1 (f1 int NOT NULL, f2 int, f3 int) ;
+CREATE TABLE t2 (f1 int NOT NULL, f2 int, f3 int) ;
+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 (f1, f2, f3) NOT IN
+(SELECT COUNT(DISTINCT f2), f1, f3 FROM t1 GROUP BY f1, f3)
+FROM t2;
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t2 system NULL NULL NULL NULL 1
+2 MATERIALIZED t1 ALL NULL NULL NULL NULL 2 Using filesort
+SELECT (f1, f2, f3) NOT IN
+(SELECT COUNT(DISTINCT f2), f1, f3 FROM t1 GROUP BY f1, f3)
+FROM t2;
+(f1, f2, f3) NOT IN
+(SELECT COUNT(DISTINCT f2), f1, f3 FROM t1 GROUP BY f1, f3)
+1
+drop table t1, t2;
+#
+# LPBUG#702301: MAX in select + always false WHERE with SQ
+#
+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);
+max_res
+NULL
+EXPLAIN EXTENDED
+SELECT MAX(t1.b) AS max_res FROM t1 WHERE (9) IN (SELECT a FROM t2);
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY NULL NULL NULL NULL NULL NULL NULL NULL Impossible WHERE
+2 MATERIALIZED t2 ALL NULL NULL NULL NULL 2 100.00
+Warnings:
+Note 1003 /* select#1 */ select max(`test`.`t1`.`b`) AS `max_res` from `test`.`t1` where 0
+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);
+max_res
+NULL
+EXPLAIN EXTENDED
+SELECT MAX(t1.b) AS max_res FROM t1 WHERE (9) IN (SELECT a FROM t2);
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY NULL NULL NULL NULL NULL NULL NULL NULL Impossible WHERE
+2 SUBQUERY t2 ALL NULL NULL NULL NULL 2 100.00 Using where
+Warnings:
+Note 1003 /* select#1 */ select max(`test`.`t1`.`b`) AS `max_res` from `test`.`t1` where 0
+DROP TABLE t1,t2;
+#
+# LPBUG#825095: Wrong result with materialization and NOT IN with 2 expressions
+#
+CREATE TABLE t1 (a int,b int);
+INSERT INTO t1 VALUES (4,4),(4,2);
+CREATE TABLE t2 (b int, a int);
+INSERT INTO t2 VALUES (4,3),(8,4);
+set @@optimizer_switch='semijoin=off,in_to_exists=off,materialization=on,partial_match_rowid_merge=on,partial_match_table_scan=off';
+EXPLAIN SELECT *
+FROM t1
+WHERE (a, b) NOT IN (SELECT a, b FROM t2);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t1 ALL NULL NULL NULL NULL 2 Using where
+2 MATERIALIZED t2 ALL NULL NULL NULL NULL 2
+SELECT *
+FROM t1
+WHERE (a, b) NOT IN (SELECT a, b FROM t2);
+a b
+4 4
+4 2
+EXPLAIN
+SELECT a, b, (a, b) NOT IN (SELECT a, b FROM t2) as sq
+FROM t1;
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t1 ALL NULL NULL NULL NULL 2
+2 MATERIALIZED t2 ALL NULL NULL NULL NULL 2
+SELECT a, b, (a, b) NOT IN (SELECT a, b FROM t2) as sq
+FROM t1;
+a b sq
+4 4 1
+4 2 1
+drop table t1, t2;
+#
+# MDEV-15235: Assertion `length > 0' failed in create_ref_for_key
+#
+CREATE TABLE t1 (i INT);
+INSERT INTO t1 VALUES (1),(2);
+CREATE TABLE t2 (f CHAR(1));
+INSERT INTO t2 VALUES ('a'),('b');
+explain
+SELECT * FROM t2 WHERE f IN ( SELECT LEFT('foo',0) FROM t1 ORDER BY 1 );
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t2 ALL NULL NULL NULL NULL 2 Using where
+2 DEPENDENT SUBQUERY t1 ALL NULL NULL NULL NULL 2
+SELECT * FROM t2 WHERE f IN ( SELECT LEFT('foo',0) FROM t1 ORDER BY 1 );
+f
+DROP TABLE t1, t2;
+#
+# MDEV-9489: Assertion `0' failed in Protocol::end_statement() on
+# UNION ALL
+#
+CREATE TABLE t1 (f1 INT);
+CREATE TABLE t2 (f2 INT);
+INSERT INTO t1 VALUES (1),(2);
+( SELECT 1 FROM t1 WHERE f1 NOT IN ( SELECT f2 FROM t2 ) LIMIT 0 )
+UNION ALL
+( SELECT 1 FROM t1 WHERE f1 NOT IN ( SELECT f2 FROM t2 ) )
+;
+1
+1
+1
+drop table t1, t2;
diff --cc mysql-test/main/subselect_sj_mat.result
index 9e18708,0000000..6a4a1a4
mode 100644,000000..100644
--- a/mysql-test/main/subselect_sj_mat.result
+++ b/mysql-test/main/subselect_sj_mat.result
@@@ -1,2517 -1,0 +1,2517 @@@
+set @subselect_sj_mat_tmp= @@optimizer_switch;
+set optimizer_switch=ifnull(@subselect_mat_test_optimizer_switch_value, 'semijoin=on,firstmatch=on,loosescan=on,semijoin_with_cache=on');
+set optimizer_switch='mrr=on,mrr_sort_keys=on,index_condition_pushdown=on';
+set @optimizer_switch_local_default= @@optimizer_switch;
+set @save_join_cache_level=@@join_cache_level;
+set join_cache_level=1;
+drop table if exists t1, t2, t3, t4, t5, 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;
+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');
+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;
+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');
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY t1 ALL NULL NULL NULL NULL 3 100.00
+1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 8 func 1 100.00
+2 MATERIALIZED t2 ALL NULL NULL NULL NULL 5 100.00 Using where
+Warnings:
+Note 1003 select `test`.`t1`.`a1` AS `a1`,`test`.`t1`.`a2` AS `a2` from `test`.`t1` semi join (`test`.`t2`) where `test`.`t2`.`b1` > '0'
+select * from t1 where a1 in (select b1 from t2 where b1 > '0');
+a1 a2
+1 - 01 2 - 01
+1 - 02 2 - 02
+explain extended
+select * from t1 where a1 in (select b1 from t2 where b1 > '0' group by b1);
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY t1 ALL NULL NULL NULL NULL 3 100.00
+1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 8 func 1 100.00
+2 MATERIALIZED t2 ALL NULL NULL NULL NULL 5 100.00 Using where
+Warnings:
+Note 1003 select `test`.`t1`.`a1` AS `a1`,`test`.`t1`.`a2` AS `a2` from `test`.`t1` semi join (`test`.`t2`) where `test`.`t2`.`b1` > '0'
+select * from t1 where a1 in (select b1 from t2 where b1 > '0' group by b1);
+a1 a2
+1 - 01 2 - 01
+1 - 02 2 - 02
+explain extended
+select * from t1 where (a1, a2) in (select b1, b2 from t2 where b1 > '0' group by b1, b2);
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY t1 ALL NULL NULL NULL NULL 3 100.00
+1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 16 func,func 1 100.00
+2 MATERIALIZED t2 ALL NULL NULL NULL NULL 5 100.00 Using where
+Warnings:
+Note 1003 select `test`.`t1`.`a1` AS `a1`,`test`.`t1`.`a2` AS `a2` from `test`.`t1` semi join (`test`.`t2`) where `test`.`t2`.`b1` > '0'
+select * from t1 where (a1, a2) in (select b1, b2 from t2 where b1 > '0' group by b1, b2);
+a1 a2
+1 - 01 2 - 01
+1 - 02 2 - 02
+explain extended
+select * from t1 where (a1, a2) in (select b1, min(b2) from t2 where b1 > '0' group by b1);
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY t1 ALL NULL NULL NULL NULL 3 100.00 Using where
+1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 16 test.t1.a1,test.t1.a2 1 100.00
+2 MATERIALIZED t2 ALL NULL NULL NULL NULL 5 100.00 Using where; Using temporary
+Warnings:
+Note 1003 /* select#1 */ select `test`.`t1`.`a1` AS `a1`,`test`.`t1`.`a2` AS `a2` from <materialize> (/* select#2 */ select `test`.`t2`.`b1`,min(`test`.`t2`.`b2`) from `test`.`t2` where `test`.`t2`.`b1` > '0' group by `test`.`t2`.`b1`) join `test`.`t1` where `<subquery2>`.`b1` = `test`.`t1`.`a1` and `<subquery2>`.`min(b2)` = `test`.`t1`.`a2`
+select * from t1 where (a1, a2) in (select b1, min(b2) from t2 where b1 > '0' group by b1);
+a1 a2
+1 - 01 2 - 01
+1 - 02 2 - 02
+explain extended
+select * from t1i where a1 in (select b1 from t2i where b1 > '0');
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY t2i index it2i1,it2i3 it2i1 # NULL 5 50.00 Using where; Using index; LooseScan
+1 PRIMARY t1i ref _it1_idx _it1_idx # _ref_ 1 100.00
+Warnings:
+Note 1003 select `test`.`t1i`.`a1` AS `a1`,`test`.`t1i`.`a2` AS `a2` from `test`.`t1i` semi join (`test`.`t2i`) where `test`.`t1i`.`a1` = `test`.`t2i`.`b1` and `test`.`t2i`.`b1` > '0'
+select * from t1i where a1 in (select b1 from t2i where b1 > '0');
+a1 a2
+1 - 01 2 - 01
+1 - 02 2 - 02
+explain extended
+select * from t1i where a1 in (select max(b1) from t2i where b1 > '0' group by b1);
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY t1i index it1i1,it1i3 # 18 # 3 100.00 #
+1 PRIMARY <subquery2> eq_ref distinct_key # 8 # 1 100.00 #
+2 MATERIALIZED t2i range it2i1,it2i3 # 9 # 5 100.00 #
+Warnings:
+Note 1003 /* select#1 */ select `test`.`t1i`.`a1` AS `a1`,`test`.`t1i`.`a2` AS `a2` from <materialize> (/* select#2 */ select max(`test`.`t2i`.`b1`) from `test`.`t2i` where `test`.`t2i`.`b1` > '0' group by `test`.`t2i`.`b1`) join `test`.`t1i` where `<subquery2>`.`max(b1)` = `test`.`t1i`.`a1`
+select * from t1i where a1 in (select max(b1) from t2i where b1 > '0' group by b1);
+a1 a2
+1 - 01 2 - 01
+1 - 02 2 - 02
+explain extended
+select * from t1i where (a1, a2) in (select b1, b2 from t2i where b1 > '0');
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY t2i index it2i1,it2i2,it2i3 it2i3 # NULL 5 50.00 Using where; Using index; LooseScan
+1 PRIMARY t1i ref _it1_idx _it1_idx # _ref_ 1 100.00
+Warnings:
+Note 1003 select `test`.`t1i`.`a1` AS `a1`,`test`.`t1i`.`a2` AS `a2` from `test`.`t1i` semi join (`test`.`t2i`) where `test`.`t1i`.`a1` = `test`.`t2i`.`b1` and `test`.`t1i`.`a2` = `test`.`t2i`.`b2` and `test`.`t2i`.`b1` > '0'
+select * from t1i where (a1, a2) in (select b1, b2 from t2i where b1 > '0');
+a1 a2
+1 - 01 2 - 01
+1 - 02 2 - 02
+explain extended
+select * from t1i where (a1, a2) in (select b1, max(b2) from t2i where b1 > '0' group by b1);
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY t1i index it1i1,it1i2,it1i3 # # # 3 100.00 #
+1 PRIMARY <subquery2> eq_ref distinct_key # # # 1 100.00 #
+2 MATERIALIZED t2i range it2i1,it2i3 # # # 3 100.00 #
+Warnings:
+Note 1003 /* select#1 */ select `test`.`t1i`.`a1` AS `a1`,`test`.`t1i`.`a2` AS `a2` from <materialize> (/* select#2 */ select `test`.`t2i`.`b1`,max(`test`.`t2i`.`b2`) from `test`.`t2i` where `test`.`t2i`.`b1` > '0' group by `test`.`t2i`.`b1`) join `test`.`t1i` where `<subquery2>`.`b1` = `test`.`t1i`.`a1` and `<subquery2>`.`max(b2)` = `test`.`t1i`.`a2`
+select * from t1i where (a1, a2) in (select b1, max(b2) from t2i where b1 > '0' group by b1);
+a1 a2
+1 - 01 2 - 01
+1 - 02 2 - 02
+explain extended
+select * from t1i where (a1, a2) in (select b1, min(b2) from t2i where b1 > '0' group by b1);
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY t1i index it1i1,it1i2,it1i3 # # # 3 100.00 #
+1 PRIMARY <subquery2> eq_ref distinct_key # # # 1 100.00 #
+2 MATERIALIZED t2i range it2i1,it2i3 # # # 3 100.00 #
+Warnings:
+Note 1003 /* select#1 */ select `test`.`t1i`.`a1` AS `a1`,`test`.`t1i`.`a2` AS `a2` from <materialize> (/* select#2 */ select `test`.`t2i`.`b1`,min(`test`.`t2i`.`b2`) from `test`.`t2i` where `test`.`t2i`.`b1` > '0' group by `test`.`t2i`.`b1`) join `test`.`t1i` where `<subquery2>`.`b1` = `test`.`t1i`.`a1` and `<subquery2>`.`min(b2)` = `test`.`t1i`.`a2`
+select * from t1i where (a1, a2) in (select b1, min(b2) from t2i where b1 > '0' group by b1);
+a1 a2
+1 - 01 2 - 01
+1 - 02 2 - 02
+explain extended
+select * from t1 where (a1, a2) in (select b1, max(b2) from t2i group by b1);
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY t1 ALL NULL NULL NULL NULL 3 100.00 Using where
+1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 16 test.t1.a1,test.t1.a2 1 100.00
+2 MATERIALIZED t2i range NULL it2i3 9 NULL 3 100.00 Using index for group-by
+Warnings:
+Note 1003 /* select#1 */ select `test`.`t1`.`a1` AS `a1`,`test`.`t1`.`a2` AS `a2` from <materialize> (/* select#2 */ select `test`.`t2i`.`b1`,max(`test`.`t2i`.`b2`) from `test`.`t2i` group by `test`.`t2i`.`b1`) join `test`.`t1` where `<subquery2>`.`b1` = `test`.`t1`.`a1` and `<subquery2>`.`max(b2)` = `test`.`t1`.`a2`
+select * from t1 where (a1, a2) in (select b1, max(b2) from t2i group by b1);
+a1 a2
+1 - 01 2 - 01
+1 - 02 2 - 02
+prepare st1 from "explain select * from t1 where (a1, a2) in (select b1, max(b2) from t2i group by b1)";
+execute st1;
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t1 ALL NULL NULL NULL NULL 3 Using where
+1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 16 test.t1.a1,test.t1.a2 1
+2 MATERIALIZED t2i range NULL it2i3 9 NULL 3 Using index for group-by
+execute st1;
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t1 ALL NULL NULL NULL NULL 3 Using where
+1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 16 test.t1.a1,test.t1.a2 1
+2 MATERIALIZED t2i range NULL it2i3 9 NULL 3 Using index for group-by
+prepare st2 from "select * from t1 where (a1, a2) in (select b1, max(b2) from t2i group by b1)";
+execute st2;
+a1 a2
+1 - 01 2 - 01
+1 - 02 2 - 02
+execute st2;
+a1 a2
+1 - 01 2 - 01
+1 - 02 2 - 02
+explain extended
+select * from t1 where (a1, a2) in (select b1, min(b2) from t2i where b1 > '0' group by b1);
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY t1 ALL NULL NULL NULL NULL 3 100.00 Using where
+1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 16 test.t1.a1,test.t1.a2 1 100.00
+2 MATERIALIZED t2i range it2i1,it2i3 it2i3 18 NULL 3 100.00 Using where; Using index for group-by
+Warnings:
+Note 1003 /* select#1 */ select `test`.`t1`.`a1` AS `a1`,`test`.`t1`.`a2` AS `a2` from <materialize> (/* select#2 */ select `test`.`t2i`.`b1`,min(`test`.`t2i`.`b2`) from `test`.`t2i` where `test`.`t2i`.`b1` > '0' group by `test`.`t2i`.`b1`) join `test`.`t1` where `<subquery2>`.`b1` = `test`.`t1`.`a1` and `<subquery2>`.`min(b2)` = `test`.`t1`.`a2`
+select * from t1 where (a1, a2) in (select b1, min(b2) from t2i where b1 > '0' group by b1);
+a1 a2
+1 - 01 2 - 01
+1 - 02 2 - 02
+select * from t1 where (a1, a2) in (select b1, min(b2) from t2i limit 1,1);
+ERROR 42000: This version of MariaDB doesn't yet support 'LIMIT & IN/ALL/ANY/SOME subquery'
+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;
+a1 a2
+1 - 01 2 - 01
+1 - 02 2 - 02
+set @@optimizer_switch=@optimizer_switch_local_default;
+set @@optimizer_switch='semijoin=off';
+execute st1;
+a1 a2
+1 - 01 2 - 01
+1 - 02 2 - 02
+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;
+a1 a2
+1 - 01 2 - 01
+1 - 02 2 - 02
+set @@optimizer_switch=@optimizer_switch_local_default;
+set @@optimizer_switch='materialization=off,in_to_exists=on';
+execute st1;
+a1 a2
+1 - 01 2 - 01
+1 - 02 2 - 02
+set @@optimizer_switch=@save_optimizer_switch;
+explain extended
+select * from t1 where (a1, a2) in (select b1, b2 from t2 order by b1, b2);
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY t1 ALL NULL NULL NULL NULL 3 100.00 Using where
+1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 16 test.t1.a1,test.t1.a2 1 100.00
+2 MATERIALIZED t2 ALL NULL NULL NULL NULL 5 100.00
+Warnings:
+Note 1003 /* select#1 */ select `test`.`t1`.`a1` AS `a1`,`test`.`t1`.`a2` AS `a2` from <materialize> (/* select#2 */ select `test`.`t2`.`b1`,`test`.`t2`.`b2` from `test`.`t2` order by `test`.`t2`.`b1`,`test`.`t2`.`b2`) join `test`.`t1` where `<subquery2>`.`b1` = `test`.`t1`.`a1` and `<subquery2>`.`b2` = `test`.`t1`.`a2`
+select * from t1 where (a1, a2) in (select b1, b2 from t2 order by b1, b2);
+a1 a2
+1 - 01 2 - 01
+1 - 02 2 - 02
+explain extended
+select * from t1i where (a1, a2) in (select b1, b2 from t2i order by b1, b2);
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY t1i index it1i1,it1i2,it1i3 it1i3 18 NULL 3 100.00 Using where; Using index
+1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 16 test.t1i.a1,test.t1i.a2 1 100.00
+2 MATERIALIZED t2i index NULL it2i3 18 NULL 5 100.00 Using index
+Warnings:
+Note 1003 /* select#1 */ select `test`.`t1i`.`a1` AS `a1`,`test`.`t1i`.`a2` AS `a2` from <materialize> (/* select#2 */ select `test`.`t2i`.`b1`,`test`.`t2i`.`b2` from `test`.`t2i` order by `test`.`t2i`.`b1`,`test`.`t2i`.`b2`) join `test`.`t1i` where `<subquery2>`.`b1` = `test`.`t1i`.`a1` and `<subquery2>`.`b2` = `test`.`t1i`.`a2`
+select * from t1i where (a1, a2) in (select b1, b2 from t2i order by b1, b2);
+a1 a2
+1 - 01 2 - 01
+1 - 02 2 - 02
+/******************************************************************************
+* 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;
+Warnings:
+Warning 1354 View merge algorithm can't be used here for now (assumed undefined algorithm)
+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);
+b1 c2
+1 - 02 2 - 01
+1 - 02 2 - 01
+1 - 03 2 - 01
+1 - 03 2 - 02
+select * from v1 where (c2, b1) in (select distinct c2, b1 from v2 where b1 is not null);
+b1 c2
+1 - 02 2 - 01
+1 - 02 2 - 01
+1 - 03 2 - 01
+1 - 03 2 - 02
+select * from v1m where (c2, b1) in (select c2, b1 from v2m where b1 is not null);
+b1 c2
+1 - 02 2 - 01
+1 - 02 2 - 01
+1 - 03 2 - 01
+1 - 03 2 - 02
+select * from v1m where (c2, b1) in (select distinct c2, b1 from v2m where b1 is not null);
+b1 c2
+1 - 02 2 - 01
+1 - 02 2 - 01
+1 - 03 2 - 01
+1 - 03 2 - 02
+drop view v1, v2, v1m, v2m;
+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'));
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY t1 ALL NULL NULL NULL NULL 3 100.00
+1 PRIMARY <subquery3> eq_ref distinct_key distinct_key 16 func,func 1 100.00
+1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 16 func,func 1 100.00
+3 MATERIALIZED t3 ALL NULL NULL NULL NULL 4 100.00 Using where
+3 MATERIALIZED t2i index it2i1,it2i2,it2i3 it2i3 18 NULL 5 80.00 Using where; Using index; Using join buffer (flat, BNL join)
+2 MATERIALIZED t2 ALL NULL NULL NULL NULL 5 100.00 Using where
+Warnings:
+Note 1003 select `test`.`t1`.`a1` AS `a1`,`test`.`t1`.`a2` AS `a2` from `test`.`t1` semi join (`test`.`t2`) semi join (`test`.`t2i` join `test`.`t3`) where `test`.`t2i`.`b1` = `test`.`t3`.`c1` and `test`.`t2i`.`b2` = `test`.`t3`.`c2` and `test`.`t2`.`b1` > '0' and `test`.`t3`.`c2` > '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'));
+a1 a2
+1 - 01 2 - 01
+1 - 02 2 - 02
+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'));
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY t2i index it2i1,it2i2,it2i3 # # # 5 50.00 #
+1 PRIMARY t1i ref it1i1,it1i2,it1i3 # # # 1 100.00 #
+1 PRIMARY t3i ref it3i1,it3i2,it3i3 # # # 1 100.00 #
+1 PRIMARY t2i ref it2i1,it2i2,it2i3 # # # 2 100.00 #
+Warnings:
+Note 1003 select `test`.`t1i`.`a1` AS `a1`,`test`.`t1i`.`a2` AS `a2` from `test`.`t1i` semi join (`test`.`t2i`) semi join (`test`.`t2i` join `test`.`t3i`) where `test`.`t1i`.`a1` = `test`.`t2i`.`b1` and `test`.`t3i`.`c1` = `test`.`t2i`.`b1` and `test`.`t2i`.`b1` = `test`.`t2i`.`b1` and `test`.`t1i`.`a2` = `test`.`t2i`.`b2` and `test`.`t3i`.`c2` = `test`.`t2i`.`b2` and `test`.`t2i`.`b2` = `test`.`t2i`.`b2` and `test`.`t2i`.`b1` > '0' and `test`.`t2i`.`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'));
+a1 a2
+1 - 01 2 - 01
+1 - 02 2 - 02
+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'));
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY t1 ALL NULL NULL NULL NULL 3 100.00
+1 PRIMARY <subquery5> eq_ref distinct_key distinct_key 16 func,func 1 100.00
+1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 16 func,func 1 100.00
+5 MATERIALIZED t3 ALL NULL NULL NULL NULL 4 100.00 Using where
+5 MATERIALIZED t2i index it2i1,it2i2,it2i3 it2i3 18 NULL 5 80.00 Using where; Using index; Using join buffer (flat, BNL join)
+2 MATERIALIZED t2 ALL NULL NULL NULL NULL 5 100.00 Using where
+4 MATERIALIZED t3 ALL NULL NULL NULL NULL 4 100.00 Using where
+3 MATERIALIZED t3 ALL NULL NULL NULL NULL 4 100.00 Using where
+Warnings:
+Note 1003 /* select#1 */ select `test`.`t1`.`a1` AS `a1`,`test`.`t1`.`a2` AS `a2` from `test`.`t1` semi join (`test`.`t2`) semi join (`test`.`t2i` join `test`.`t3`) where `test`.`t2i`.`b1` = `test`.`t3`.`c1` and `test`.`t2i`.`b2` = `test`.`t3`.`c2` and (<expr_cache><`test`.`t2`.`b2`>(<in_optimizer>(`test`.`t2`.`b2`,`test`.`t2`.`b2` in ( <materialize> (/* select#3 */ select `test`.`t3`.`c2` from `test`.`t3` where `test`.`t3`.`c2` like '%02' ), <primary_index_lookup>(`test`.`t2`.`b2` in <temporary table> on distinct_key where `test`.`t2`.`b2` = `<subquery3>`.`c2`)))) or <expr_cache><`test`.`t2`.`b2`>(<in_optimizer>(`test`.`t2`.`b2`,`test`.`t2`.`b2` in ( <materialize> (/* select#4 */ select `test`.`t3`.`c2` from `test`.`t3` where `test`.`t3`.`c2` like '%03' ), <primary_index_lookup>(`test`.`t2`.`b2` in <temporary table> on distinct_key where `test`.`t2`.`b2` = `<subquery4>`.`c2`))))) and `test`.`t3`.`c2` > '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'));
+a1 a2
+1 - 02 2 - 02
+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'));
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY t1 ALL NULL NULL NULL NULL 3 100.00
+1 PRIMARY <subquery5> eq_ref distinct_key distinct_key 16 func,func 1 100.00
+1 PRIMARY t2 ALL NULL NULL NULL NULL 5 100.00 Using where; Start temporary; End temporary; Using join buffer (flat, BNL join)
+5 MATERIALIZED t3c ALL NULL NULL NULL NULL 4 100.00 Using where
+5 MATERIALIZED t2i index it2i1,it2i2,it2i3 it2i3 18 NULL 5 80.00 Using where; Using index; Using join buffer (flat, BNL join)
+4 MATERIALIZED t3b ALL NULL NULL NULL NULL 4 100.00 Using where
+3 DEPENDENT SUBQUERY t3a ALL NULL NULL NULL NULL 4 100.00 Using where
+Warnings:
+Note 1276 Field or reference 'test.t1.a1' of SELECT #3 was resolved in SELECT #1
+Note 1003 /* select#1 */ select `test`.`t1`.`a1` AS `a1`,`test`.`t1`.`a2` AS `a2` from `test`.`t1` semi join (`test`.`t2`) semi join (`test`.`t2i` join `test`.`t3` `t3c`) where `test`.`t2i`.`b1` = `test`.`t3c`.`c1` and `test`.`t2`.`b1` = `test`.`t1`.`a1` and `test`.`t2i`.`b2` = `test`.`t3c`.`c2` and `test`.`t2`.`b2` = `test`.`t1`.`a2` and (<expr_cache><`test`.`t2`.`b2`,`test`.`t1`.`a1`>(<in_optimizer>(`test`.`t2`.`b2`,<exists>(/* select#3 */ select `test`.`t3a`.`c2` from `test`.`t3` `t3a` where `test`.`t3a`.`c1` = `test`.`t1`.`a1` and <cache>(`test`.`t2`.`b2`) = `test`.`t3a`.`c2`))) or <expr_cache><`test`.`t2`.`b2`>(<in_optimizer>(`test`.`t2`.`b2`,`test`.`t2`.`b2` in ( <materialize> (/* select#4 */ select `test`.`t3b`.`c2` from `test`.`t3` `t3b` where `test`.`t3b`.`c2` like '%03' ), <primary_index_lookup>(`test`.`t2`.`b2` in <temporary table> on distinct_key where `test`.`t2`.`b2` = `<subquery4>`.`c2`))))) and `test`.`t3c`.`c2` > '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'));
+a1 a2
+1 - 01 2 - 01
+1 - 02 2 - 02
+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')));
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY t1 ALL NULL # # # 3 100.00 #
+1 PRIMARY <subquery5> eq_ref distinct_key # # # 1 100.00 #
+1 PRIMARY <subquery2> eq_ref distinct_key # # # 1 100.00 #
+5 MATERIALIZED t3 ALL NULL # # # 4 100.00 #
+5 MATERIALIZED t2i index it2i1,it2i2,it2i3 # # # 5 80.00 #
+2 MATERIALIZED t2 ALL NULL # # # 5 100.00 #
+4 MATERIALIZED t3 ALL NULL # # # 4 100.00 #
+3 MATERIALIZED t3 ALL NULL # # # 4 100.00 #
+7 UNION t2i index it2i1,it2i2,it2i3 # # # 5 50.00 #
+7 UNION t1i ref it1i1,it1i2,it1i3 # # # 1 100.00 #
+7 UNION t3i ref it3i1,it3i2,it3i3 # # # 1 100.00 #
+7 UNION t2i ref it2i1,it2i2,it2i3 # # # 2 100.00 #
+NULL UNION RESULT <union1,7> ALL NULL # # # NULL NULL #
+Warnings:
+Note 1003 (/* select#1 */ select `test`.`t1`.`a1` AS `a1`,`test`.`t1`.`a2` AS `a2` from `test`.`t1` semi join (`test`.`t2`) semi join (`test`.`t2i` join `test`.`t3`) where `test`.`t2i`.`b1` = `test`.`t3`.`c1` and `test`.`t2i`.`b2` = `test`.`t3`.`c2` and (<expr_cache><`test`.`t2`.`b2`>(<in_optimizer>(`test`.`t2`.`b2`,`test`.`t2`.`b2` in ( <materialize> (/* select#3 */ select `test`.`t3`.`c2` from `test`.`t3` where `test`.`t3`.`c2` like '%02' ), <primary_index_lookup>(`test`.`t2`.`b2` in <temporary table> on distinct_key where `test`.`t2`.`b2` = `<subquery3>`.`c2`)))) or <expr_cache><`test`.`t2`.`b2`>(<in_optimizer>(`test`.`t2`.`b2`,`test`.`t2`.`b2` in ( <materialize> (/* select#4 */ select `test`.`t3`.`c2` from `test`.`t3` where `test`.`t3`.`c2` like '%03' ), <primary_index_lookup>(`test`.`t2`.`b2` in <temporary table> on distinct_key where `test`.`t2`.`b2` = `<subquery4>`.`c2`))))) and `test`.`t3`.`c2` > '0') union (/* select#7 */ select `test`.`t1i`.`a1` AS `a1`,`test`.`t1
i`.`a2`
AS `a2` from `test`.`t1i` semi join (`test`.`t2i`) semi join (`test`.`t2i` join `test`.`t3i`) where `test`.`t1i`.`a1` = `test`.`t2i`.`b1` and `test`.`t3i`.`c1` = `test`.`t2i`.`b1` and `test`.`t2i`.`b1` = `test`.`t2i`.`b1` and `test`.`t1i`.`a2` = `test`.`t2i`.`b2` and `test`.`t3i`.`c2` = `test`.`t2i`.`b2` and `test`.`t2i`.`b2` = `test`.`t2i`.`b2` and `test`.`t2i`.`b1` > '0' and `test`.`t2i`.`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')));
+a1 a2
+1 - 02 2 - 02
+1 - 01 2 - 01
+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'));
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY t1 ALL NULL NULL NULL NULL 3 100.00 Using where
+1 PRIMARY <subquery4> eq_ref distinct_key distinct_key 16 func,func 1 100.00
+4 MATERIALIZED t3 ALL NULL NULL NULL NULL 4 100.00 Using where
+4 MATERIALIZED t2i index it2i1,it2i2,it2i3 it2i3 18 NULL 5 80.00 Using where; Using index; Using join buffer (flat, BNL join)
+2 DEPENDENT SUBQUERY t1 ALL NULL NULL NULL NULL 3 100.00 Using where
+3 DEPENDENT UNION t2 ALL NULL NULL NULL NULL 5 100.00 Using where
+NULL UNION RESULT <union2,3> ALL NULL NULL NULL NULL NULL NULL
+Warnings:
+Note 1003 /* select#1 */ select `test`.`t1`.`a1` AS `a1`,`test`.`t1`.`a2` AS `a2` from `test`.`t1` semi join (`test`.`t2i` join `test`.`t3`) where `test`.`t2i`.`b1` = `test`.`t3`.`c1` and `test`.`t2i`.`b2` = `test`.`t3`.`c2` and <expr_cache><`test`.`t1`.`a1`,`test`.`t1`.`a2`>(<in_optimizer>((`test`.`t1`.`a1`,`test`.`t1`.`a2`),<exists>(/* select#2 */ select `test`.`t1`.`a1`,`test`.`t1`.`a2` from `test`.`t1` where `test`.`t1`.`a1` > '0' and <cache>(`test`.`t1`.`a1`) = `test`.`t1`.`a1` and <cache>(`test`.`t1`.`a2`) = `test`.`t1`.`a2` union /* select#3 */ select `test`.`t2`.`b1`,`test`.`t2`.`b2` from `test`.`t2` where `test`.`t2`.`b1` < '9' and <cache>(`test`.`t1`.`a1`) = `test`.`t2`.`b1` and <cache>(`test`.`t1`.`a2`) = `test`.`t2`.`b2`))) and `test`.`t3`.`c2` > '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'));
+a1 a2
+1 - 01 2 - 01
+1 - 02 2 - 02
+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;
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY t1 ALL NULL NULL NULL NULL 3 100.00 Using where
+1 PRIMARY t3 ALL NULL NULL NULL NULL 4 100.00 Using where; Using join buffer (flat, BNL join)
+1 PRIMARY <subquery4> eq_ref distinct_key distinct_key 16 func,func 1 100.00
+4 MATERIALIZED t3 ALL NULL NULL NULL NULL 4 100.00 Using where
+4 MATERIALIZED t2i index it2i1,it2i2,it2i3 it2i3 18 NULL 5 80.00 Using where; Using index; Using join buffer (flat, BNL join)
+2 DEPENDENT SUBQUERY t1 ALL NULL NULL NULL NULL 3 100.00 Using where
+3 DEPENDENT UNION t2 ALL NULL NULL NULL NULL 5 100.00 Using where
+NULL UNION RESULT <union2,3> ALL NULL NULL NULL NULL NULL NULL
+Warnings:
+Note 1003 /* select#1 */ select `test`.`t1`.`a1` AS `a1`,`test`.`t1`.`a2` AS `a2`,`test`.`t3`.`c1` AS `c1`,`test`.`t3`.`c2` AS `c2` from `test`.`t1` semi join (`test`.`t2i` join `test`.`t3`) join `test`.`t3` where `test`.`t3`.`c1` = `test`.`t1`.`a1` and `test`.`t2i`.`b1` = `test`.`t3`.`c1` and `test`.`t2i`.`b2` = `test`.`t3`.`c2` and <expr_cache><`test`.`t1`.`a1`,`test`.`t1`.`a2`>(<in_optimizer>((`test`.`t1`.`a1`,`test`.`t1`.`a2`),<exists>(/* select#2 */ select `test`.`t1`.`a1`,`test`.`t1`.`a2` from `test`.`t1` where `test`.`t1`.`a1` > '0' and <cache>(`test`.`t1`.`a1`) = `test`.`t1`.`a1` and <cache>(`test`.`t1`.`a2`) = `test`.`t1`.`a2` union /* select#3 */ select `test`.`t2`.`b1`,`test`.`t2`.`b2` from `test`.`t2` where `test`.`t2`.`b1` < '9' and <cache>(`test`.`t1`.`a1`) = `test`.`t2`.`b1` and <cache>(`test`.`t1`.`a2`) = `test`.`t2`.`b2`))) and `test`.`t3`.`c2` > '0'
+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;
+a1 a2 c1 c2
+1 - 01 2 - 01 1 - 01 2 - 01
+1 - 02 2 - 02 1 - 02 2 - 02
+/******************************************************************************
+* 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');
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY t3 ALL NULL NULL NULL NULL 4 100.00 Using where
+2 DEPENDENT SUBQUERY t1 ALL NULL NULL NULL NULL 3 100.00 Using where
+3 DEPENDENT UNION t2 ALL NULL NULL NULL NULL 5 100.00 Using where
+NULL UNION RESULT <union2,3> ALL NULL NULL NULL NULL NULL NULL
+Warnings:
+Note 1003 /* select#1 */ select `test`.`t3`.`c1` AS `c1`,`test`.`t3`.`c2` AS `c2` from `test`.`t3` where <expr_cache><`test`.`t3`.`c1`>(<in_optimizer>(`test`.`t3`.`c1`,<exists>(/* select#2 */ select `test`.`t1`.`a1` from `test`.`t1` where `test`.`t1`.`a1` > '0' and <cache>(`test`.`t3`.`c1`) = `test`.`t1`.`a1` union /* select#3 */ select `test`.`t2`.`b1` from `test`.`t2` where `test`.`t2`.`b1` < '9' and <cache>(`test`.`t3`.`c1`) = `test`.`t2`.`b1`)))
+select * from t3
+where c1 in (select a1 from t1 where a1 > '0' UNION select b1 from t2 where b1 < '9');
+c1 c2
+1 - 01 2 - 01
+1 - 02 2 - 02
+1 - 03 2 - 03
+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));
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY t1 ALL NULL NULL NULL NULL 3 100.00 Using where
+1 PRIMARY t2i ref it2i1,it2i2,it2i3 it2i3 18 test.t1.a1,test.t1.a2 2 100.00 Using index; Start temporary
+1 PRIMARY t3c ALL NULL NULL NULL NULL 4 100.00 Using where; End temporary; Using join buffer (flat, BNL join)
+1 PRIMARY t2 ALL NULL NULL NULL NULL 5 100.00 Using where; Start temporary; End temporary; Using join buffer (flat, BNL join)
+4 MATERIALIZED t3b ALL NULL NULL NULL NULL 4 100.00 Using where
+3 DEPENDENT SUBQUERY t3a ALL NULL NULL NULL NULL 4 100.00 Using where
+Warnings:
+Note 1276 Field or reference 'test.t1.a1' of SELECT #3 was resolved in SELECT #1
+Note 1276 Field or reference 'test.t1.a2' of SELECT #6 was resolved in SELECT #1
+Note 1003 /* select#1 */ select `test`.`t1`.`a1` AS `a1`,`test`.`t1`.`a2` AS `a2` from `test`.`t1` semi join (`test`.`t2`) semi join (`test`.`t2i` join `test`.`t3` `t3c`) where `test`.`t2i`.`b1` = `test`.`t1`.`a1` and `test`.`t3c`.`c1` = `test`.`t1`.`a1` and `test`.`t2`.`b1` = `test`.`t1`.`a1` and `test`.`t2i`.`b2` = `test`.`t1`.`a2` and `test`.`t3c`.`c2` = `test`.`t1`.`a2` and `test`.`t2`.`b2` = `test`.`t1`.`a2` and (<expr_cache><`test`.`t2`.`b2`,`test`.`t1`.`a1`>(<in_optimizer>(`test`.`t2`.`b2`,<exists>(/* select#3 */ select `test`.`t3a`.`c2` from `test`.`t3` `t3a` where `test`.`t3a`.`c1` = `test`.`t1`.`a1` and <cache>(`test`.`t2`.`b2`) = `test`.`t3a`.`c2`))) or <expr_cache><`test`.`t2`.`b2`>(<in_optimizer>(`test`.`t2`.`b2`,`test`.`t2`.`b2` in ( <materialize> (/* select#4 */ select `test`.`t3b`.`c2` from `test`.`t3` `t3b` where `test`.`t3b`.`c2` like '%03' ), <primary_index_lookup>(`test`.`t2`.`b2` in <temporary table> on distinct_key where `test`.`t2`.`b2` = `<subquery4>
`.`c2`))
)))
+explain extended
+select * from t1 where (a1, a2) in (select '1 - 01', '2 - 01');
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY t1 ALL NULL NULL NULL NULL 3 100.00 Using where
+2 DEPENDENT SUBQUERY NULL NULL NULL NULL NULL NULL NULL NULL No tables used
+Warnings:
+Note 1003 /* select#1 */ select `test`.`t1`.`a1` AS `a1`,`test`.`t1`.`a2` AS `a2` from `test`.`t1` where <expr_cache><`test`.`t1`.`a1`,`test`.`t1`.`a2`>(<in_optimizer>((`test`.`t1`.`a1`,`test`.`t1`.`a2`),<exists>(/* select#2 */ select '1 - 01','2 - 01' having (<cache>(`test`.`t1`.`a1`) = '1 - 01' or '1 - 01' is null) and (<cache>(`test`.`t1`.`a2`) = '2 - 01' or '2 - 01' is null) and '1 - 01' is null and '2 - 01' is null)))
+select * from t1 where (a1, a2) in (select '1 - 01', '2 - 01');
+a1 a2
+1 - 01 2 - 01
+explain extended
+select * from t1 where (a1, a2) in (select '1 - 01', '2 - 01' from dual);
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY t1 ALL NULL NULL NULL NULL 3 100.00 Using where
+2 DEPENDENT SUBQUERY NULL NULL NULL NULL NULL NULL NULL NULL No tables used
+Warnings:
+Note 1003 /* select#1 */ select `test`.`t1`.`a1` AS `a1`,`test`.`t1`.`a2` AS `a2` from `test`.`t1` where <expr_cache><`test`.`t1`.`a1`,`test`.`t1`.`a2`>(<in_optimizer>((`test`.`t1`.`a1`,`test`.`t1`.`a2`),<exists>(/* select#2 */ select '1 - 01','2 - 01' having (<cache>(`test`.`t1`.`a1`) = '1 - 01' or '1 - 01' is null) and (<cache>(`test`.`t1`.`a2`) = '2 - 01' or '2 - 01' is null) and '1 - 01' is null and '2 - 01' is null)))
+select * from t1 where (a1, a2) in (select '1 - 01', '2 - 01' from dual);
+a1 a2
+1 - 01 2 - 01
+/******************************************************************************
+* Subqueries in other uncovered clauses.
+******************************************************************************/
+/* SELECT clause */
+select ((a1,a2) IN (select * from t2 where b2 > '0')) IS NULL from t1;
+((a1,a2) IN (select * from t2 where b2 > '0')) IS NULL
+0
+0
+0
+/* 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);
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY t1 ALL NULL NULL NULL NULL 3 100.00
+2 SUBQUERY columns index NULL PRIMARY 4 NULL 2 100.00 Using index
+Warnings:
+Note 1003 /* select#1 */ select `test`.`t1`.`a1` AS `a1`,`test`.`t1`.`a2` AS `a2` from `test`.`t1` group by (/* select#2 */ select `test`.`columns`.`col` from `test`.`columns` limit 1)
+select * from t1 group by (select col from columns limit 1);
+a1 a2
+1 - 00 2 - 00
+explain extended
+select * from t1 group by (a1 in (select col from columns));
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY t1 ALL NULL NULL NULL NULL 3 100.00 Using temporary; Using filesort
+2 DEPENDENT SUBQUERY columns unique_subquery PRIMARY PRIMARY 4 func 1 100.00 Using index; Using where; Full scan on NULL key
+Warnings:
+Note 1003 /* select#1 */ select `test`.`t1`.`a1` AS `a1`,`test`.`t1`.`a2` AS `a2` from `test`.`t1` group by <expr_cache><`test`.`t1`.`a1`>(<in_optimizer>(`test`.`t1`.`a1`,<exists>(<primary_index_lookup>(<cache>(`test`.`t1`.`a1`) in columns on PRIMARY where trigcond(<cache>(`test`.`t1`.`a1`) = `test`.`columns`.`col`)))))
+select * from t1 group by (a1 in (select col from columns));
+a1 a2
+1 - 00 2 - 00
+Warnings:
+Warning 1292 Truncated incorrect DOUBLE value: '1 - 00'
+Warning 1292 Truncated incorrect DOUBLE value: '1 - 01'
+Warning 1292 Truncated incorrect DOUBLE value: '1 - 02'
+/* ORDER BY clause */
+explain extended
+select * from t1 order by (select col from columns limit 1);
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY t1 ALL NULL NULL NULL NULL 3 100.00
+2 SUBQUERY columns index NULL PRIMARY 4 NULL 2 100.00 Using index
+Warnings:
+Note 1003 /* select#1 */ select `test`.`t1`.`a1` AS `a1`,`test`.`t1`.`a2` AS `a2` from `test`.`t1` order by (/* select#2 */ select `test`.`columns`.`col` from `test`.`columns` limit 1)
+select * from t1 order by (select col from columns limit 1);
+a1 a2
+1 - 00 2 - 00
+1 - 01 2 - 01
+1 - 02 2 - 02
+/******************************************************************************
+* 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;
+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)));
+explain extended select left(a1,7), left(a2,7)
+from t1_16
+where a1 in (select b1 from t2_16 where b1 > '0');
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY t1_16 ALL NULL NULL NULL NULL 3 100.00 Using where
+1 PRIMARY t2_16 ALL NULL NULL NULL NULL 3 100.00 Using where; Start temporary; End temporary; Using join buffer (flat, BNL join)
+Warnings:
+Note 1003 select left(`test`.`t1_16`.`a1`,7) AS `left(a1,7)`,left(`test`.`t1_16`.`a2`,7) AS `left(a2,7)` from `test`.`t1_16` semi join (`test`.`t2_16`) where `test`.`t2_16`.`b1` = `test`.`t1_16`.`a1` and `test`.`t1_16`.`a1` > '0'
+select left(a1,7), left(a2,7)
+from t1_16
+where a1 in (select b1 from t2_16 where b1 > '0');
+left(a1,7) left(a2,7)
+1 - 01x 2 - 01x
+1 - 02x 2 - 02x
+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');
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY t1_16 ALL NULL NULL NULL NULL 3 100.00 Using where
+1 PRIMARY t2_16 ALL NULL NULL NULL NULL 3 100.00 Using where; Start temporary; End temporary; Using join buffer (flat, BNL join)
+Warnings:
+Note 1003 select left(`test`.`t1_16`.`a1`,7) AS `left(a1,7)`,left(`test`.`t1_16`.`a2`,7) AS `left(a2,7)` from `test`.`t1_16` semi join (`test`.`t2_16`) where `test`.`t2_16`.`b1` = `test`.`t1_16`.`a1` and `test`.`t2_16`.`b2` = `test`.`t1_16`.`a2` and `test`.`t1_16`.`a1` > '0'
+select left(a1,7), left(a2,7)
+from t1_16
+where (a1,a2) in (select b1, b2 from t2_16 where b1 > '0');
+left(a1,7) left(a2,7)
+1 - 01x 2 - 01x
+1 - 02x 2 - 02x
+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');
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY t1_16 ALL NULL NULL NULL NULL 3 100.00
+1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 19 func 1 100.00 Using where
+2 MATERIALIZED t2_16 ALL NULL NULL NULL NULL 3 100.00 Using where
+Warnings:
+Note 1003 select left(`test`.`t1_16`.`a1`,7) AS `left(a1,7)`,left(`test`.`t1_16`.`a2`,7) AS `left(a2,7)` from `test`.`t1_16` semi join (`test`.`t2_16`) where `test`.`t2_16`.`b1` > '0' and `test`.`t1_16`.`a1` = substr(`test`.`t2_16`.`b1`,1,16)
+select left(a1,7), left(a2,7)
+from t1_16
+where a1 in (select substring(b1,1,16) from t2_16 where b1 > '0');
+left(a1,7) left(a2,7)
+1 - 01x 2 - 01x
+1 - 02x 2 - 02x
+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);
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY t1_16 ALL NULL NULL NULL NULL 3 100.00 Using where
+2 DEPENDENT SUBQUERY t2_16 ALL NULL NULL NULL NULL 3 100.00 Using filesort
+Warnings:
+Note 1003 /* select#1 */ select left(`test`.`t1_16`.`a1`,7) AS `left(a1,7)`,left(`test`.`t1_16`.`a2`,7) AS `left(a2,7)` from `test`.`t1_16` where <expr_cache><`test`.`t1_16`.`a1`>(<in_optimizer>(`test`.`t1_16`.`a1`,<exists>(/* select#2 */ select group_concat(`test`.`t2_16`.`b1` separator ',') from `test`.`t2_16` group by `test`.`t2_16`.`b2` having <cache>(`test`.`t1_16`.`a1`) = <ref_null_helper>(group_concat(`test`.`t2_16`.`b1` separator ',')))))
+select left(a1,7), left(a2,7)
+from t1_16
+where a1 in (select group_concat(b1) from t2_16 group by b2);
+left(a1,7) left(a2,7)
+1 - 01x 2 - 01x
+1 - 02x 2 - 02x
+set @@group_concat_max_len = 256;
+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);
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY t1_16 ALL NULL NULL NULL NULL 3 100.00 Using where
+1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 260 test.t1_16.a1 1 100.00 Using where
+2 MATERIALIZED t2_16 ALL NULL NULL NULL NULL 3 100.00 Using filesort
+Warnings:
+Note 1003 /* select#1 */ select left(`test`.`t1_16`.`a1`,7) AS `left(a1,7)`,left(`test`.`t1_16`.`a2`,7) AS `left(a2,7)` from <materialize> (/* select#2 */ select group_concat(`test`.`t2_16`.`b1` separator ',') from `test`.`t2_16` group by `test`.`t2_16`.`b2`) join `test`.`t1_16` where `test`.`t1_16`.`a1` = `<subquery2>`.`group_concat(b1)`
+select left(a1,7), left(a2,7)
+from t1_16
+where a1 in (select group_concat(b1) from t2_16 group by b2);
+left(a1,7) left(a2,7)
+1 - 01x 2 - 01x
+1 - 02x 2 - 02x
+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')));
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY t1 ALL NULL NULL NULL NULL 3 100.00
+1 PRIMARY t1_16 ALL NULL NULL NULL NULL 3 100.00 Using where; Start temporary; Using join buffer (flat, BNL join)
+1 PRIMARY t2_16 ALL NULL NULL NULL NULL 3 100.00 Using where; Using join buffer (flat, BNL join)
+1 PRIMARY t3 ALL NULL NULL NULL NULL 4 100.00 Using where; Using join buffer (flat, BNL join)
+1 PRIMARY t2 ALL NULL NULL NULL NULL 5 100.00 Using where; End temporary; Using join buffer (flat, BNL join)
+Warnings:
+Note 1003 select `test`.`t1`.`a1` AS `a1`,`test`.`t1`.`a2` AS `a2` from `test`.`t1` semi join (`test`.`t3` join `test`.`t2_16` join `test`.`t2` join `test`.`t1_16`) where `test`.`t2`.`b1` = `test`.`t3`.`c1` and `test`.`t2_16`.`b1` = `test`.`t1_16`.`a1` and `test`.`t2_16`.`b2` = `test`.`t1_16`.`a2` and `test`.`t2`.`b2` = substr(`test`.`t1_16`.`a2`,1,6) and `test`.`t3`.`c2` > '0' and concat(`test`.`t1`.`a1`,'x') = left(`test`.`t1_16`.`a1`,8)
+drop table t1_16, t2_16, t3_16;
+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)));
+explain extended select left(a1,7), left(a2,7)
+from t1_512
+where a1 in (select b1 from t2_512 where b1 > '0');
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY t1_512 ALL NULL NULL NULL NULL 3 100.00 Using where
+1 PRIMARY t2_512 ALL NULL NULL NULL NULL 3 100.00 Using where; Start temporary; End temporary; Using join buffer (flat, BNL join)
+Warnings:
+Note 1003 select left(`test`.`t1_512`.`a1`,7) AS `left(a1,7)`,left(`test`.`t1_512`.`a2`,7) AS `left(a2,7)` from `test`.`t1_512` semi join (`test`.`t2_512`) where `test`.`t2_512`.`b1` = `test`.`t1_512`.`a1` and `test`.`t1_512`.`a1` > '0'
+select left(a1,7), left(a2,7)
+from t1_512
+where a1 in (select b1 from t2_512 where b1 > '0');
+left(a1,7) left(a2,7)
+1 - 01x 2 - 01x
+1 - 02x 2 - 02x
+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');
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY t1_512 ALL NULL NULL NULL NULL 3 100.00 Using where
+1 PRIMARY t2_512 ALL NULL NULL NULL NULL 3 100.00 Using where; Start temporary; End temporary; Using join buffer (flat, BNL join)
+Warnings:
+Note 1003 select left(`test`.`t1_512`.`a1`,7) AS `left(a1,7)`,left(`test`.`t1_512`.`a2`,7) AS `left(a2,7)` from `test`.`t1_512` semi join (`test`.`t2_512`) where `test`.`t2_512`.`b1` = `test`.`t1_512`.`a1` and `test`.`t2_512`.`b2` = `test`.`t1_512`.`a2` and `test`.`t1_512`.`a1` > '0'
+select left(a1,7), left(a2,7)
+from t1_512
+where (a1,a2) in (select b1, b2 from t2_512 where b1 > '0');
+left(a1,7) left(a2,7)
+1 - 01x 2 - 01x
+1 - 02x 2 - 02x
+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');
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY t1_512 ALL NULL NULL NULL NULL 3 100.00
+1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 516 func 1 100.00 Using where
+2 MATERIALIZED t2_512 ALL NULL NULL NULL NULL 3 100.00 Using where
+Warnings:
+Note 1003 select left(`test`.`t1_512`.`a1`,7) AS `left(a1,7)`,left(`test`.`t1_512`.`a2`,7) AS `left(a2,7)` from `test`.`t1_512` semi join (`test`.`t2_512`) where `test`.`t2_512`.`b1` > '0' and `test`.`t1_512`.`a1` = substr(`test`.`t2_512`.`b1`,1,512)
+select left(a1,7), left(a2,7)
+from t1_512
+where a1 in (select substring(b1,1,512) from t2_512 where b1 > '0');
+left(a1,7) left(a2,7)
+1 - 01x 2 - 01x
+1 - 02x 2 - 02x
+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);
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY t1_512 ALL NULL NULL NULL NULL 3 100.00 Using where
+1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 260 test.t1_512.a1 1 100.00 Using where
+2 MATERIALIZED t2_512 ALL NULL NULL NULL NULL 3 100.00 Using filesort
+Warnings:
+Note 1003 /* select#1 */ select left(`test`.`t1_512`.`a1`,7) AS `left(a1,7)`,left(`test`.`t1_512`.`a2`,7) AS `left(a2,7)` from <materialize> (/* select#2 */ select group_concat(`test`.`t2_512`.`b1` separator ',') from `test`.`t2_512` group by `test`.`t2_512`.`b2`) join `test`.`t1_512` where `test`.`t1_512`.`a1` = `<subquery2>`.`group_concat(b1)`
+select left(a1,7), left(a2,7)
+from t1_512
+where a1 in (select group_concat(b1) from t2_512 group by b2);
+left(a1,7) left(a2,7)
+Warnings:
+Warning 1260 Row 1 was cut by GROUP_CONCAT()
+Warning 1260 Row 2 was cut by GROUP_CONCAT()
+Warning 1260 Row 3 was cut by GROUP_CONCAT()
+set @@group_concat_max_len = 256;
+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);
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY t1_512 ALL NULL NULL NULL NULL 3 100.00 Using where
+1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 260 test.t1_512.a1 1 100.00 Using where
+2 MATERIALIZED t2_512 ALL NULL NULL NULL NULL 3 100.00 Using filesort
+Warnings:
+Note 1003 /* select#1 */ select left(`test`.`t1_512`.`a1`,7) AS `left(a1,7)`,left(`test`.`t1_512`.`a2`,7) AS `left(a2,7)` from <materialize> (/* select#2 */ select group_concat(`test`.`t2_512`.`b1` separator ',') from `test`.`t2_512` group by `test`.`t2_512`.`b2`) join `test`.`t1_512` where `test`.`t1_512`.`a1` = `<subquery2>`.`group_concat(b1)`
+select left(a1,7), left(a2,7)
+from t1_512
+where a1 in (select group_concat(b1) from t2_512 group by b2);
+left(a1,7) left(a2,7)
+Warnings:
+Warning 1260 Row 1 was cut by GROUP_CONCAT()
+Warning 1260 Row 2 was cut by GROUP_CONCAT()
+Warning 1260 Row 3 was cut by GROUP_CONCAT()
+drop table t1_512, t2_512, t3_512;
+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)));
+explain extended select left(a1,7), left(a2,7)
+from t1_1024
+where a1 in (select b1 from t2_1024 where b1 > '0');
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY t1_1024 ALL NULL NULL NULL NULL 3 100.00 Using where
+1 PRIMARY t2_1024 ALL NULL NULL NULL NULL 3 100.00 Using where; Start temporary; End temporary; Using join buffer (flat, BNL join)
+Warnings:
+Note 1003 select left(`test`.`t1_1024`.`a1`,7) AS `left(a1,7)`,left(`test`.`t1_1024`.`a2`,7) AS `left(a2,7)` from `test`.`t1_1024` semi join (`test`.`t2_1024`) where `test`.`t2_1024`.`b1` = `test`.`t1_1024`.`a1` and `test`.`t1_1024`.`a1` > '0'
+select left(a1,7), left(a2,7)
+from t1_1024
+where a1 in (select b1 from t2_1024 where b1 > '0');
+left(a1,7) left(a2,7)
+1 - 01x 2 - 01x
+1 - 02x 2 - 02x
+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');
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY t1_1024 ALL NULL NULL NULL NULL 3 100.00 Using where
+1 PRIMARY t2_1024 ALL NULL NULL NULL NULL 3 100.00 Using where; Start temporary; End temporary; Using join buffer (flat, BNL join)
+Warnings:
+Note 1003 select left(`test`.`t1_1024`.`a1`,7) AS `left(a1,7)`,left(`test`.`t1_1024`.`a2`,7) AS `left(a2,7)` from `test`.`t1_1024` semi join (`test`.`t2_1024`) where `test`.`t2_1024`.`b1` = `test`.`t1_1024`.`a1` and `test`.`t2_1024`.`b2` = `test`.`t1_1024`.`a2` and `test`.`t1_1024`.`a1` > '0'
+select left(a1,7), left(a2,7)
+from t1_1024
+where (a1,a2) in (select b1, b2 from t2_1024 where b1 > '0');
+left(a1,7) left(a2,7)
+1 - 01x 2 - 01x
+1 - 02x 2 - 02x
+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');
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY t1_1024 ALL NULL NULL NULL NULL 3 100.00
+1 PRIMARY t2_1024 ALL NULL NULL NULL NULL 3 100.00 Using where; Start temporary; End temporary; Using join buffer (flat, BNL join)
+Warnings:
+Note 1003 select left(`test`.`t1_1024`.`a1`,7) AS `left(a1,7)`,left(`test`.`t1_1024`.`a2`,7) AS `left(a2,7)` from `test`.`t1_1024` semi join (`test`.`t2_1024`) where `test`.`t2_1024`.`b1` > '0' and `test`.`t1_1024`.`a1` = substr(`test`.`t2_1024`.`b1`,1,1024)
+select left(a1,7), left(a2,7)
+from t1_1024
+where a1 in (select substring(b1,1,1024) from t2_1024 where b1 > '0');
+left(a1,7) left(a2,7)
+1 - 01x 2 - 01x
+1 - 02x 2 - 02x
+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);
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY t1_1024 ALL NULL NULL NULL NULL 3 100.00 Using where
+1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 260 test.t1_1024.a1 1 100.00 Using where
+2 MATERIALIZED t2_1024 ALL NULL NULL NULL NULL 3 100.00 Using filesort
+Warnings:
+Note 1003 /* select#1 */ select left(`test`.`t1_1024`.`a1`,7) AS `left(a1,7)`,left(`test`.`t1_1024`.`a2`,7) AS `left(a2,7)` from <materialize> (/* select#2 */ select group_concat(`test`.`t2_1024`.`b1` separator ',') from `test`.`t2_1024` group by `test`.`t2_1024`.`b2`) join `test`.`t1_1024` where `test`.`t1_1024`.`a1` = `<subquery2>`.`group_concat(b1)`
+select left(a1,7), left(a2,7)
+from t1_1024
+where a1 in (select group_concat(b1) from t2_1024 group by b2);
+left(a1,7) left(a2,7)
+Warnings:
+Warning 1260 Row 1 was cut by GROUP_CONCAT()
+Warning 1260 Row 2 was cut by GROUP_CONCAT()
+Warning 1260 Row 3 was cut by GROUP_CONCAT()
+set @@group_concat_max_len = 256;
+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);
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY t1_1024 ALL NULL NULL NULL NULL 3 100.00 Using where
+1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 260 test.t1_1024.a1 1 100.00 Using where
+2 MATERIALIZED t2_1024 ALL NULL NULL NULL NULL 3 100.00 Using filesort
+Warnings:
+Note 1003 /* select#1 */ select left(`test`.`t1_1024`.`a1`,7) AS `left(a1,7)`,left(`test`.`t1_1024`.`a2`,7) AS `left(a2,7)` from <materialize> (/* select#2 */ select group_concat(`test`.`t2_1024`.`b1` separator ',') from `test`.`t2_1024` group by `test`.`t2_1024`.`b2`) join `test`.`t1_1024` where `test`.`t1_1024`.`a1` = `<subquery2>`.`group_concat(b1)`
+select left(a1,7), left(a2,7)
+from t1_1024
+where a1 in (select group_concat(b1) from t2_1024 group by b2);
+left(a1,7) left(a2,7)
+Warnings:
+Warning 1260 Row 1 was cut by GROUP_CONCAT()
+Warning 1260 Row 2 was cut by GROUP_CONCAT()
+Warning 1260 Row 3 was cut by GROUP_CONCAT()
+drop table t1_1024, t2_1024, t3_1024;
+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)));
+explain extended select left(a1,7), left(a2,7)
+from t1_1025
+where a1 in (select b1 from t2_1025 where b1 > '0');
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY t1_1025 ALL NULL NULL NULL NULL 3 100.00 Using where
+1 PRIMARY t2_1025 ALL NULL NULL NULL NULL 3 100.00 Using where; Start temporary; End temporary; Using join buffer (flat, BNL join)
+Warnings:
+Note 1003 select left(`test`.`t1_1025`.`a1`,7) AS `left(a1,7)`,left(`test`.`t1_1025`.`a2`,7) AS `left(a2,7)` from `test`.`t1_1025` semi join (`test`.`t2_1025`) where `test`.`t2_1025`.`b1` = `test`.`t1_1025`.`a1` and `test`.`t1_1025`.`a1` > '0'
+select left(a1,7), left(a2,7)
+from t1_1025
+where a1 in (select b1 from t2_1025 where b1 > '0');
+left(a1,7) left(a2,7)
+1 - 01x 2 - 01x
+1 - 02x 2 - 02x
+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');
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY t1_1025 ALL NULL NULL NULL NULL 3 100.00 Using where
+1 PRIMARY t2_1025 ALL NULL NULL NULL NULL 3 100.00 Using where; Start temporary; End temporary; Using join buffer (flat, BNL join)
+Warnings:
+Note 1003 select left(`test`.`t1_1025`.`a1`,7) AS `left(a1,7)`,left(`test`.`t1_1025`.`a2`,7) AS `left(a2,7)` from `test`.`t1_1025` semi join (`test`.`t2_1025`) where `test`.`t2_1025`.`b1` = `test`.`t1_1025`.`a1` and `test`.`t2_1025`.`b2` = `test`.`t1_1025`.`a2` and `test`.`t1_1025`.`a1` > '0'
+select left(a1,7), left(a2,7)
+from t1_1025
+where (a1,a2) in (select b1, b2 from t2_1025 where b1 > '0');
+left(a1,7) left(a2,7)
+1 - 01x 2 - 01x
+1 - 02x 2 - 02x
+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');
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY t1_1025 ALL NULL NULL NULL NULL 3 100.00
+1 PRIMARY t2_1025 ALL NULL NULL NULL NULL 3 100.00 Using where; Start temporary; End temporary; Using join buffer (flat, BNL join)
+Warnings:
+Note 1003 select left(`test`.`t1_1025`.`a1`,7) AS `left(a1,7)`,left(`test`.`t1_1025`.`a2`,7) AS `left(a2,7)` from `test`.`t1_1025` semi join (`test`.`t2_1025`) where `test`.`t2_1025`.`b1` > '0' and `test`.`t1_1025`.`a1` = substr(`test`.`t2_1025`.`b1`,1,1025)
+select left(a1,7), left(a2,7)
+from t1_1025
+where a1 in (select substring(b1,1,1025) from t2_1025 where b1 > '0');
+left(a1,7) left(a2,7)
+1 - 01x 2 - 01x
+1 - 02x 2 - 02x
+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);
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY t1_1025 ALL NULL NULL NULL NULL 3 100.00 Using where
+1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 260 test.t1_1025.a1 1 100.00 Using where
+2 MATERIALIZED t2_1025 ALL NULL NULL NULL NULL 3 100.00 Using filesort
+Warnings:
+Note 1003 /* select#1 */ select left(`test`.`t1_1025`.`a1`,7) AS `left(a1,7)`,left(`test`.`t1_1025`.`a2`,7) AS `left(a2,7)` from <materialize> (/* select#2 */ select group_concat(`test`.`t2_1025`.`b1` separator ',') from `test`.`t2_1025` group by `test`.`t2_1025`.`b2`) join `test`.`t1_1025` where `test`.`t1_1025`.`a1` = `<subquery2>`.`group_concat(b1)`
+select left(a1,7), left(a2,7)
+from t1_1025
+where a1 in (select group_concat(b1) from t2_1025 group by b2);
+left(a1,7) left(a2,7)
+Warnings:
+Warning 1260 Row 1 was cut by GROUP_CONCAT()
+Warning 1260 Row 2 was cut by GROUP_CONCAT()
+Warning 1260 Row 3 was cut by GROUP_CONCAT()
+set @@group_concat_max_len = 256;
+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);
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY t1_1025 ALL NULL NULL NULL NULL 3 100.00 Using where
+1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 260 test.t1_1025.a1 1 100.00 Using where
+2 MATERIALIZED t2_1025 ALL NULL NULL NULL NULL 3 100.00 Using filesort
+Warnings:
+Note 1003 /* select#1 */ select left(`test`.`t1_1025`.`a1`,7) AS `left(a1,7)`,left(`test`.`t1_1025`.`a2`,7) AS `left(a2,7)` from <materialize> (/* select#2 */ select group_concat(`test`.`t2_1025`.`b1` separator ',') from `test`.`t2_1025` group by `test`.`t2_1025`.`b2`) join `test`.`t1_1025` where `test`.`t1_1025`.`a1` = `<subquery2>`.`group_concat(b1)`
+select left(a1,7), left(a2,7)
+from t1_1025
+where a1 in (select group_concat(b1) from t2_1025 group by b2);
+left(a1,7) left(a2,7)
+Warnings:
+Warning 1260 Row 1 was cut by GROUP_CONCAT()
+Warning 1260 Row 2 was cut by GROUP_CONCAT()
+Warning 1260 Row 3 was cut by GROUP_CONCAT()
+drop table t1_1025, t2_1025, t3_1025;
+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);
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY t1bit ALL NULL NULL NULL NULL 3 100.00
+1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 8 func,func 1 100.00
+2 MATERIALIZED t2bit ALL NULL NULL NULL NULL 3 100.00
+Warnings:
+Note 1003 select conv(`test`.`t1bit`.`a1`,10,2) AS `bin(a1)`,conv(`test`.`t1bit`.`a2`,10,2) AS `bin(a2)` from `test`.`t1bit` semi join (`test`.`t2bit`) where 1
+select bin(a1), bin(a2)
+from t1bit
+where (a1, a2) in (select b1, b2 from t2bit);
+bin(a1) bin(a2)
+1 101
+10 110
+drop table t1bit, t2bit;
+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);
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY t1bb ALL NULL NULL NULL NULL 3 100.00
+1 PRIMARY t2bb ALL NULL NULL NULL NULL 3 100.00 Using where; Start temporary; End temporary; Using join buffer (flat, BNL join)
+Warnings:
+Note 1003 select conv(`test`.`t1bb`.`a1`,10,2) AS `bin(a1)`,`test`.`t1bb`.`a2` AS `a2` from `test`.`t1bb` semi join (`test`.`t2bb`) where `test`.`t2bb`.`b1` = `test`.`t1bb`.`a1` and `test`.`t2bb`.`b2` = `test`.`t1bb`.`a2`
+select bin(a1), a2
+from t1bb
+where (a1, a2) in (select b1, b2 from t2bb);
+bin(a1) a2
+1 101
+10 110
+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);
+s2
+0
+1
+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);
+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);
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY <subquery2> ALL distinct_key NULL NULL NULL 6 100.00
+1 PRIMARY t1 ALL NULL NULL NULL NULL 7 100.00 Using where; Using join buffer (flat, BNL join)
+2 MATERIALIZED t2 ALL NULL NULL NULL NULL 6 100.00 Using where
+Warnings:
+Note 1003 select `test`.`t1`.`a` AS `a` from `test`.`t1` semi join (`test`.`t2`) where `test`.`t1`.`a` = `test`.`t2`.`c` and `test`.`t2`.`d` >= 20
+select a from t1 where a in (select c from t2 where d >= 20);
+a
+2
+2
+2
+3
+create index it1a on t1(a);
+explain extended
+select a from t1 where a in (select c from t2 where d >= 20);
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY t1 index it1a it1a 4 NULL 7 100.00 Using index
+1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 4 func 1 100.00
+2 MATERIALIZED t2 ALL NULL NULL NULL NULL 6 100.00 Using where
+Warnings:
+Note 1003 select `test`.`t1`.`a` AS `a` from `test`.`t1` semi join (`test`.`t2`) where `test`.`t2`.`d` >= 20
+select a from t1 where a in (select c from t2 where d >= 20);
+a
+2
+2
+2
+3
+insert into t2 values (1,10);
+explain extended
+select a from t1 where a in (select c from t2 where d >= 20);
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY t1 index it1a it1a 4 NULL 7 100.00 Using index
+1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 4 func 1 100.00
+2 MATERIALIZED t2 ALL NULL NULL NULL NULL 7 100.00 Using where
+Warnings:
+Note 1003 select `test`.`t1`.`a` AS `a` from `test`.`t1` semi join (`test`.`t2`) where `test`.`t2`.`d` >= 20
+select a from t1 where a in (select c from t2 where d >= 20);
+a
+2
+2
+2
+3
+explain extended
+select a from t1 group by a having a in (select c from t2 where d >= 20);
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY t1 index NULL it1a 4 NULL 7 100.00 Using index
+2 MATERIALIZED t2 ALL NULL NULL NULL NULL 7 100.00 Using where
+Warnings:
+Note 1003 /* select#1 */ select `test`.`t1`.`a` AS `a` from `test`.`t1` group by `test`.`t1`.`a` having <expr_cache><`test`.`t1`.`a`>(<in_optimizer>(`test`.`t1`.`a`,`test`.`t1`.`a` in ( <materialize> (/* select#2 */ select `test`.`t2`.`c` from `test`.`t2` where `test`.`t2`.`d` >= 20 ), <primary_index_lookup>(`test`.`t1`.`a` in <temporary table> on distinct_key where `test`.`t1`.`a` = `<subquery2>`.`c`))))
+select a from t1 group by a having a in (select c from t2 where d >= 20);
+a
+2
+3
+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);
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY t1 index NULL it1a 4 NULL 7 100.00 Using index
+2 MATERIALIZED t2 ALL NULL NULL NULL NULL 7 100.00 Using where
+Warnings:
+Note 1003 /* select#1 */ select `test`.`t1`.`a` AS `a` from `test`.`t1` group by `test`.`t1`.`a` having <expr_cache><`test`.`t1`.`a`>(<in_optimizer>(`test`.`t1`.`a`,`test`.`t1`.`a` in ( <materialize> (/* select#2 */ select `test`.`t2`.`c` from `test`.`t2` where `test`.`t2`.`d` >= 20 ), <primary_index_lookup>(`test`.`t1`.`a` in <temporary table> on distinct_key where `test`.`t1`.`a` = `<subquery2>`.`c`))))
+select a from t1 group by a having a in (select c from t2 where d >= 20);
+a
+2
+3
+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));
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY t1 index NULL iab 8 NULL 7 100.00 Using index
+2 DEPENDENT SUBQUERY t2 ALL NULL NULL NULL NULL 7 100.00 Using where
+3 DEPENDENT SUBQUERY t3 ALL NULL NULL NULL NULL 4 100.00 Using where
+Warnings:
+Note 1276 Field or reference 'test.t1.b' of SELECT #3 was resolved in SELECT #1
+Note 1981 Aggregate function 'max()' of SELECT #3 belongs to SELECT #1
+Note 1003 /* select#1 */ select `test`.`t1`.`a` AS `a` from `test`.`t1` group by `test`.`t1`.`a` having <expr_cache><`test`.`t1`.`a`,`test`.`t1`.`b`,max(`test`.`t1`.`b`),max(`test`.`t1`.`b`)>(<in_optimizer>(`test`.`t1`.`a`,<exists>(/* select#2 */ select `test`.`t2`.`c` from `test`.`t2` where <nop>(<expr_cache><`test`.`t2`.`d`,`test`.`t1`.`b`,max(`test`.`t1`.`b`),max(`test`.`t1`.`b`)>(<in_optimizer>(`test`.`t2`.`d`,<exists>(/* select#3 */ select `test`.`t3`.`e` from `test`.`t3` where max(`test`.`t1`.`b`) = `test`.`t3`.`e` having <cache>(`test`.`t2`.`d`) >= <ref_null_helper>(`test`.`t3`.`e`))))) and <cache>(`test`.`t1`.`a`) = `test`.`t2`.`c`)))
+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));
+a
+2
+3
+explain extended
+select a from t1
+where a in (select c from t2 where d >= some(select e from t3 where b=e));
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY t2 ALL NULL NULL NULL NULL 7 100.00 Start temporary
+1 PRIMARY t1 ref it1a,iab iab 4 test.t2.c 1 100.00 Using where; Using index; End temporary
+3 DEPENDENT SUBQUERY t3 ALL NULL NULL NULL NULL 4 100.00 Using where
+Warnings:
+Note 1276 Field or reference 'test.t1.b' of SELECT #3 was resolved in SELECT #1
+Note 1003 /* select#1 */ select `test`.`t1`.`a` AS `a` from `test`.`t1` semi join (`test`.`t2`) where `test`.`t1`.`a` = `test`.`t2`.`c` and <nop>(<expr_cache><`test`.`t2`.`d`,`test`.`t1`.`b`>(<in_optimizer>(`test`.`t2`.`d`,<exists>(/* select#3 */ select `test`.`t3`.`e` from `test`.`t3` where `test`.`t1`.`b` = `test`.`t3`.`e` and <cache>(`test`.`t2`.`d`) >= `test`.`t3`.`e`))))
+select a from t1
+where a in (select c from t2 where d >= some(select e from t3 where b=e));
+a
+2
+2
+2
+3
+1
+drop table t1, t2, t3;
+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);
+1
+1
+1
+1
+drop table t2;
+create table t1 (a1 int key);
+create table t2 (b1 int);
+insert into t1 values (5);
+explain select min(a1) from t1 where 7 in (select max(b1) from t2 group by b1);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t1 system NULL NULL NULL NULL 1
+1 PRIMARY <subquery2> const distinct_key distinct_key 4 const 1
+2 MATERIALIZED NULL NULL NULL NULL NULL NULL NULL no matching row in const table
+select min(a1) from t1 where 7 in (select max(b1) from t2 group by b1);
+min(a1)
+NULL
+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 max(b1) from t2 group by b1);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY NULL NULL NULL NULL NULL NULL NULL Impossible WHERE
+2 SUBQUERY NULL NULL NULL NULL NULL NULL NULL no matching row in const table
+select min(a1) from t1 where 7 in (select max(b1) from t2 group by b1);
+min(a1)
+NULL
+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);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY NULL NULL NULL NULL NULL NULL NULL Impossible WHERE
+2 SUBQUERY NULL NULL NULL NULL NULL NULL NULL no matching row in const table
+select min(a1) from t1 where 7 in (select b1 from t2);
+min(a1)
+NULL
+set @@optimizer_switch=@optimizer_switch_local_default;
+set @@optimizer_switch='materialization=off,in_to_exists=on';
+# with MariaDB and MWL#90, this particular case is solved:
+explain select min(a1) from t1 where 7 in (select b1 from t2);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables
+select min(a1) from t1 where 7 in (select b1 from t2);
+min(a1)
+NULL
+# 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;
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY NULL NULL NULL NULL NULL NULL NULL Impossible WHERE
+2 SUBQUERY NULL NULL NULL NULL NULL NULL NULL no matching row in const table
+select min(a1) from t1 where 7 in (select b1 from t2) or 2> 4;
+min(a1)
+NULL
+set @@optimizer_switch= @save_optimizer_switch;
+drop table t1,t2;
+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);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t1 ALL NULL NULL NULL NULL 2
+1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 2 func 1 Using where
+2 MATERIALIZED t1 ALL NULL NULL NULL NULL 2
+select a,b from t1 where b in (select a from t1);
+a b
+prepare st1 from "select a,b from t1 where b in (select a from t1)";
+execute st1;
+a b
+execute st1;
+a b
+drop table t1;
+#
+# BUG#49630: Segfault in select_describe() with double
+# nested subquery and materialization
+#
+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);
+INSERT INTO t2 VALUES (1),(2);
+INSERT INTO t3 VALUES (1),(2);
+INSERT INTO t4 VALUES (1),(2);
+
+EXPLAIN
+SELECT t1i
+FROM t1 JOIN t4 ON t1i=t4i
+WHERE (t1i) IN (
+SELECT t2i
+FROM t2
+WHERE (t2i) IN (
+SELECT max(t3i)
+FROM t3
+GROUP BY t3i
+)
+);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t1 system NULL NULL NULL NULL 1
+1 PRIMARY <subquery3> eq_ref distinct_key distinct_key 4 const 1
+1 PRIMARY t2 ALL NULL NULL NULL NULL 2 Using where; Start temporary; End temporary; Using join buffer (flat, BNL join)
+1 PRIMARY t4 ALL NULL NULL NULL NULL 2 Using where; Using join buffer (flat, BNL join)
+3 MATERIALIZED t3 ALL NULL NULL NULL NULL 2 Using temporary
+DROP TABLE t1,t2,t3,t4;
+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
+;
+field1 field2
+t 1
+t 2
+drop table t1;
+#
+# BUG#53103: MTR test ps crashes in optimize_cond()
+# when running with --debug
+#
+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 ;
+1
+1
+1
+EXECUTE STMT ;
+1
+1
+1
+DEALLOCATE PREPARE STMT;
+DROP TABLE t1;
+# End of BUG#53103
+#
+# BUG#54511 - Assertion failed: cache != 0L in file
+# sql_select.cc::sub_select_cache on HAVING
+#
+CREATE TABLE t1 (i int(11));
+CREATE TABLE t2 (c char(1));
+CREATE TABLE t3 (c char(1));
+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));
+COUNT( i ) i
+DROP TABLE t1,t2,t3;
+# End BUG#54511
+#
+# BUG#56367 - Assertion exec_method != EXEC_MATERIALIZATION...
+# on subquery in FROM
+#
+CREATE TABLE t1 (a INTEGER);
+CREATE TABLE t2 (b INTEGER);
+INSERT INTO t2 VALUES (1);
+set @tmp_optimizer_switch=@@optimizer_switch;
+set optimizer_switch='derived_merge=off,derived_with_keys=off';
+explain SELECT a FROM (
+SELECT t1.* FROM t1 LEFT JOIN t2 ON t1.a > 3 OR t2.b IN (SELECT a FROM t1)
+) table1;
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY <derived2> ALL NULL NULL NULL NULL 2
+2 DERIVED NULL NULL NULL NULL NULL NULL NULL no matching row in const table
+3 MATERIALIZED NULL NULL NULL NULL NULL NULL NULL no matching row in const table
+SELECT a FROM (
+SELECT t1.* FROM t1 LEFT JOIN t2 ON t1.a > 3 OR t2.b IN (SELECT a FROM t1)
+) table1;
+a
+set optimizer_switch=@tmp_optimizer_switch;
+DROP TABLE t1, t2;
+# End BUG#56367
+#
+# Bug#59833 - materialization=on/off leads to different result set
+# when using IN
+#
+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);
+explain SELECT * FROM t1 JOIN t2 USING (f1)
+WHERE t1.f1 IN (SELECT t1.pk FROM t1 ORDER BY t1.f1);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t1 system NULL NULL NULL NULL 1
+1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 4 const 1
+1 PRIMARY t2 ALL NULL NULL NULL NULL 2 Using where; Using join buffer (flat, BNL join)
+2 MATERIALIZED t1 system NULL NULL NULL NULL 1
+SELECT * FROM t1 JOIN t2 USING (f1)
+WHERE t1.f1 IN (SELECT t1.pk FROM t1 ORDER BY t1.f1);
+f1 pk pk
+DROP TABLE t1, t2;
+# End Bug#59833
+#
+# Bug#11852644 - CRASH IN ITEM_REF::SAVE_IN_FIELD ON SELECT DISTINCT
+#
+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)
+;
+col_varchar_key
+r
+DROP TABLE t1, t2;
+DROP VIEW v3;
+# End Bug#11852644
+
+# Bug#12668294 - GROUP BY ON EMPTY RESULT GIVES EMPTY ROW
+# INSTEAD OF NULL WHEN MATERIALIZATION ON
+
+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 ;
+MIN(t3.col_int_nokey) field3
+DROP TABLE t1;
+DROP TABLE t2;
+DROP TABLE t3;
+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);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY <subquery2> ALL distinct_key NULL NULL NULL 2
+1 PRIMARY t1 ALL NULL NULL NULL NULL 3 Using where; Using join buffer (flat, BNL join)
+2 MATERIALIZED t2 ALL NULL NULL NULL NULL 2
+SELECT COUNT(*) FROM t1 WHERE (f1,f2) IN (SELECT f1,f2 FROM t2);
+COUNT(*)
+2
+set @@optimizer_switch= @save_optimizer_switch;
+DROP TABLE t1, t2;
+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);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t1 ALL NULL NULL NULL NULL 2
+1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 4 func 1
+2 MATERIALIZED t2 range PRIMARY PRIMARY 4 NULL 2 Using index condition; Using where; Rowid-ordered scan
+SELECT pk FROM t1 WHERE (a) IN (SELECT a FROM t2 WHERE pk > 0);
+pk
+2
+SELECT pk FROM t1 WHERE (b,c,d) IN (SELECT b,c,d FROM t2 WHERE pk > 0);
+pk
+2
+DROP TABLE t1, t2;
+set optimizer_switch=@save_optimizer_switch;
+#
+# BUG#50019: Wrong result for IN-subquery with materialization
+#
+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);
+i
+1
+2
+3
+4
+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);
+i
+4
+3
+2
+1
+set session optimizer_switch=@save_optimizer_switch;
+drop table t1, t2, t3;
+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;
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t0 ALL NULL NULL NULL NULL 3
+2 MATERIALIZED t1 ALL NULL NULL NULL NULL 3
+select a, a in (select a from t1) from t0;
+a a in (select a from t1)
+0 1
+1 1
+2 1
+prepare s from 'select a, a in (select a from t1) from t0';
+execute s;
+a a in (select a from t1)
+0 1
+1 1
+2 1
+update t1 set a=123;
+execute s;
+a a in (select a from t1)
+0 0
+1 0
+2 0
+drop table t0, t1;
+set optimizer_switch='firstmatch=on';
+#
+# MWL#90, review feedback: check what happens when the subquery
+# looks like candidate for MWL#90 checking at the first glance
+# but then subselect_hash_sj_engine::init_permanent() discovers
+# that it's not possible to perform duplicate removal for the
+# selected datatypes, and so materialization isn't applicable after
+# all.
+#
+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');
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t1_1024 ALL NULL NULL NULL NULL 3 Using where
+2 DEPENDENT SUBQUERY t2_1024 ALL NULL NULL NULL NULL 3 Using where
+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');
+left(a1,7) left(a2,7)
+1 - 01x 2 - 01x
+drop table t1_1024, t2_1024;
+#
+# BUG##836491: Crash in Item_field::Item_field from add_ref_to_table_cond() with semijoin+materialization
+#
+CREATE TABLE t1 (c int, d varchar(1), KEY(d)) ;
+INSERT INTO t1 VALUES (2,'x'),(2,'x'),(2,'j'),(2,'c');
+CREATE TABLE t2 (a int, d varchar(1)) ;
+INSERT INTO t2 VALUES (1,'x');
+CREATE TABLE t3 (d varchar(1)) ;
+INSERT INTO t3 VALUES ('x'),('x'),('j'),('c');
+SELECT t2.a, t1.c
+FROM t1, t2
+WHERE t2.d IN ( SELECT d FROM t3 )
+AND t1.d = t2.d
+GROUP BY 1 , 2;
+a c
+1 2
+drop table t1,t2,t3;
+#
+# BUG#836523: Crash in JOIN::get_partial_cost_and_fanout with semijoin+materialization
+#
+CREATE TABLE t1 (a varchar(1));
+INSERT INTO t1 VALUES ('a'),('a');
+CREATE TABLE t2 (a varchar(1));
+CREATE TABLE t3 (a int);
+INSERT INTO t3 VALUES (1),(2);
+CREATE TABLE t4 (a varchar(1));
+INSERT INTO t4 VALUES ('a'),('a');
+SELECT t1.a
+FROM t1
+WHERE t1.a IN (
+SELECT t2.a
+FROM t2, t3
+)
+HAVING a IN (
+SELECT a
+FROM t4
+);
+a
+DROP TABLE t1, t2, t3, t4;
+#
+# BUG#836507: Crash in setup_sj_materialization_part1() with semijoin+materialization
+#
+CREATE TABLE t1 (a int) ;
+INSERT IGNORE INTO t1 VALUES (1),(1);
+CREATE TABLE t2 (a int);
+INSERT INTO t2 VALUES (1);
+CREATE TABLE t3 (a int);
+CREATE TABLE t4 (a int);
+INSERT INTO t4 VALUES (2),(2);
+CREATE TABLE t5 (a int);
+INSERT INTO t5 VALUES (1);
+SELECT * FROM t1
+WHERE (a) IN (
+SELECT t5.a
+FROM (
+t2
+LEFT JOIN ( t3 , t4 )
+ON 1 = 1
+)
+JOIN t5
+);
+a
+1
+1
+DROP TABLE t1,t2,t3,t4,t5;
+#
+# BUG#836532: Crash in Item_equal_fields_iterator::get_curr_field with semijoin+materialization
+#
+CREATE TABLE t2 (a int);
+INSERT IGNORE INTO t2 VALUES ('a'),('a');
+Warnings:
+Warning 1366 Incorrect integer value: 'a' for column 'a' at row 1
+Warning 1366 Incorrect integer value: 'a' for column 'a' at row 2
+CREATE TABLE t4 (a varchar(1));
+INSERT INTO t4 VALUES ('m'),('o');
+CREATE TABLE t3 (a varchar(1) , b varchar(1) ) ;
+INSERT INTO t3 VALUES ('b','b');
+CREATE TABLE t5 (a varchar(1), KEY (a)) ;
+INSERT INTO t5 VALUES ('d'),('e');
+SELECT *
+FROM t2
+WHERE t2.a = ALL (
+SELECT t4.a
+FROM t4
+WHERE t4.a IN (
+SELECT t3.a
+FROM t3 , t5
+WHERE ( t5.a = t3.b )
+)
+);
+a
+0
+0
+DROP TABLE t2,t3,t4,t5;
+#
+# BUG#860300: Second crash with get_fanout_with_deps() with semijoin + materialization
+#
+set @tmp_860300=@@optimizer_switch;
+set optimizer_switch='semijoin=on,materialization=on,loosescan=off,firstmatch=off';
+CREATE TABLE t1 (f2 int);
+INSERT INTO t1 VALUES (9),(6);
+CREATE TABLE t3 (f4 int);
+CREATE TABLE t4 (f6 varchar(1));
+SELECT *
+FROM t3
+WHERE 'h' IN (SELECT f6
+FROM t4
+WHERE 5 IN (SELECT f2 FROM t1)
+GROUP BY t4.f6);
+f4
+DROP TABLE t1,t3,t4;
+set optimizer_switch=@tmp_860300;
+#
+# BUG#860535: Assertion `keypart_map' failed in mi_rkey with semijoin
+#
+set @tmp_860535=@@optimizer_switch;
+set optimizer_switch='semijoin=on,materialization=on,loosescan=off,firstmatch=off';
+CREATE TABLE t1 (f3 int) ;
+INSERT INTO t1 VALUES (1),(7);
+CREATE TABLE t2 (f3 int , f5 varchar(1), KEY (f3)) ;
+INSERT INTO t2 VALUES (7,'b');
+CREATE TABLE t3 (f3 int , f4 varchar(1) , KEY(f3), KEY (f4,f3)) ;
+INSERT INTO t3 VALUES (1,'t'),(7,'g');
+CREATE TABLE t4
+SELECT f3
+FROM t1 WHERE ( f3 ) NOT IN (
+SELECT f3
+FROM t2
+WHERE f5 IN (
+SELECT f4
+FROM t3
+WHERE t3.f3 < 3
+)
+);
+SELECT * FROM t4;
+f3
+1
+7
+DROP TABLE t1, t2, t3, t4;
+set optimizer_switch=@tmp_860535;
+#
+# BUG#860553: Crash in create_ref_for_key with semijoin + materialization
+#
+CREATE TABLE t1 (f1 int) ;
+CREATE TABLE t2 (f5 varchar(52) NOT NULL) ;
+CREATE TABLE t3 (f1 varchar(3), f4 varchar(52) , KEY (f4), PRIMARY KEY (f1));
+CREATE TABLE t4 (f3 int, KEY (f3));
+INSERT INTO t4 VALUES (17),(20);
+CREATE TABLE t5 (f2 int);
+INSERT INTO t5 VALUES (0),(0);
+SELECT *
+FROM t1
+JOIN t2
+ON ( t2.f5 ) IN (
+SELECT t3.f4
+FROM t3
+WHERE ( 1 ) IN (
+SELECT t4.f3
+FROM t4 , t5
+)
+);
+f1 f5
+DROP TABLE t1, t2, t3, t4, t5;
+#
+# BUG#868908: Crash in check_simple_equality() with semijoin + materialization + prepared statement
+#
+CREATE TABLE t1 ( a int );
+CREATE TABLE t3 ( b int, c int) ;
+CREATE TABLE t2 ( a int ) ;
+CREATE TABLE t4 ( a int , c int) ;
+PREPARE st1 FROM "
+SELECT STRAIGHT_JOIN *
+FROM t1
+WHERE ( 3 ) IN (
+ SELECT t3.b
+ FROM t3
+ LEFT JOIN (
+ t2 STRAIGHT_JOIN t4 ON ( t4.c = t2.a )
+ ) ON ( t4.a = t3.c )
+);
+";
+EXECUTE st1;
+a
+EXECUTE st1;
+a
+DROP TABLE t1,t2,t3,t4;
+#
+# BUG#901032: Wrong result for MIN/MAX on an indexed column with materialization and semijoin
+#
+CREATE TABLE t1 ( a INT, KEY(a) );
+INSERT INTO t1 VALUES (1);
+CREATE TABLE t2 ( b INT );
+INSERT INTO t2 VALUES (2);
+CREATE TABLE t3 ( c INT );
+INSERT INTO t3 VALUES (2);
+SELECT MIN(a) FROM t1, t2 WHERE b IN (SELECT c FROM t3 GROUP BY c);
+MIN(a)
+1
+DROP TABLE t1,t2,t3;
+#
+#
+# BUG#902632: Crash or invalid read at st_join_table::cleanup, st_table::disable_keyread
+#
+CREATE TABLE t1 ( a INT );
+INSERT INTO t1 VALUES (1), (2);
+CREATE TABLE t2 ( b INT );
+INSERT INTO t2 VALUES (3), (4);
+CREATE TABLE t3 ( c INT );
+INSERT INTO t3 VALUES (5), (6);
+SELECT * FROM t1 WHERE EXISTS (
+SELECT DISTINCT b FROM t2
+WHERE b <= a
+AND b IN ( SELECT c FROM t3 GROUP BY c )
+);
+a
+DROP TABLE t1,t2,t3;
+#
+# BUG#901506: Crash in TABLE_LIST::print on EXPLAIN EXTENDED
+#
+CREATE TABLE t1 ( a INT, KEY(a) );
+INSERT INTO t1 VALUES (8);
+EXPLAIN EXTENDED
+SELECT * FROM t1
+WHERE a IN ( SELECT MIN(a) FROM t1 );
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY t1 system a NULL NULL NULL 1 100.00
+1 PRIMARY <subquery2> system NULL NULL NULL NULL 1 100.00
+2 MATERIALIZED NULL NULL NULL NULL NULL NULL NULL NULL Select tables optimized away
+Warnings:
+Note 1003 /* select#1 */ select 8 AS `a` from dual where 1
+DROP TABLE t1;
+#
+# BUG#904432: Wrong result with LEFT JOIN, constant table, semijoin=ON,materialization=ON
+#
+CREATE TABLE t1 ( a INT ) ENGINE=MyISAM;
+INSERT INTO t1 VALUES (4);
+CREATE TABLE t2 ( b INT NOT NULL, c INT );
+INSERT INTO t2 VALUES (4,2),(4,2),(4,4),(1,1);
+SELECT * FROM t1 LEFT JOIN t2 ON ( a = b )
+WHERE a IN ( SELECT c FROM t2 );
+a b c
+4 4 2
+4 4 2
+4 4 4
+DROP TABLE t1,t2;
+#
+# BUG#922254: Assertion `0' failed at item_cmpfunc.cc:5899: Item* Item_equal::get_first(JOIN_TAB*, Item*)
+#
+CREATE TABLE t1 ( a VARCHAR(3) );
+CREATE TABLE t2 ( b VARCHAR(3), c VARCHAR(8), KEY(c) );
+INSERT INTO t2 VALUES ('USA','Abilene'),('USA','Akron');
+EXPLAIN
+SELECT * FROM
+( SELECT * FROM t1 ) AS alias1,
+t2 AS alias2
+WHERE b = a AND a IN (
+SELECT alias3.c
+FROM t2 AS alias3, t2 AS alias4
+WHERE alias4.c = alias3.b
+);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables
+DROP TABLE t1,t2;
+#
+# BUG#928048: Query containing IN subquery with OR in the where clause returns a wrong result
+#
+create table t1 (a int, b int);
+insert into t1 values (7,5), (3,3), (5,4), (9,3);
+create table t2 (a int, b int, index i_a(a));
+insert into t2 values
+(4,2), (7,9), (7,4), (3,1), (5,3), (3,1), (9,4), (8,1);
+explain select * from t1 where t1.a in (select a from t2 where t2.a=7 or t2.b<=1);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t1 ALL NULL NULL NULL NULL 4
+1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 4 func 1
+2 MATERIALIZED t2 ALL i_a NULL NULL NULL 8 Using where
+select * from t1 where t1.a in (select a from t2 where t2.a=7 or t2.b<=1);
+a b
+7 5
+3 3
+drop table t1,t2;
+#
+# BUG#933407: Valgrind warnings in mark_as_null_row with materialization+semijoin, STRAIGHT_JOIN, impossible WHERE
+#
+CREATE TABLE t1 (a INT);
+INSERT INTO t1 VALUES (0),(8);
+SELECT STRAIGHT_JOIN MIN(a) FROM t1
+WHERE a IN (
+SELECT a FROM t1
+WHERE 'condition'='impossible'
+ );
+MIN(a)
+NULL
+DROP TABLE t1;
+#
+# BUG#938131: Subquery materialization is not used in CREATE TABLE SELECT
+#
+CREATE TABLE t1(a int);
+INSERT INTO t1 values(1),(2);
+CREATE TABLE t2(a int);
+INSERT INTO t2 values(1),(2);
+# Should use Materialization:
+EXPLAIN SELECT * FROM t1 WHERE a IN (SELECT * FROM t2 GROUP BY a HAVING a > 1);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t1 ALL NULL NULL NULL NULL 2 Using where
+1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 4 test.t1.a 1
+2 MATERIALIZED t2 ALL NULL NULL NULL NULL 2 Using temporary
+flush status;
+CREATE TABLE t3 SELECT * FROM t1 WHERE a IN (SELECT * FROM t2 GROUP BY a HAVING a > 1);
+SHOW STATUS LIKE 'Created_tmp_tables';
+Variable_name Value
+Created_tmp_tables 2
+DROP TABLE t1,t2,t3;
+#
+# BUG#939009: Crash with aggregate function in IN subquery
+#
+SET @save_optimizer_switch=@@optimizer_switch;
+SET optimizer_switch='materialization=on,semijoin=on';
+CREATE TABLE t1 (a int, b int);
+INSERT INTO t1 VALUES (7,1), (4,2), (7,7);
+CREATE TABLE t2 ( c INT );
+INSERT INTO t2 VALUES (4), (7), (6);
+EXPLAIN EXTENDED
+SELECT * FROM t1
+WHERE a IN (SELECT MAX(c) FROM t2) AND b=7 AND (a IS NULL OR a=b);
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY <subquery2> const distinct_key distinct_key 4 const 1 100.00
+1 PRIMARY t1 ALL NULL NULL NULL NULL 3 100.00 Using where; Using join buffer (flat, BNL join)
+2 MATERIALIZED t2 ALL NULL NULL NULL NULL 3 100.00
+Warnings:
- Note 1003 /* select#1 */ select `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b` from <materialize> (/* select#2 */ select max(`test`.`t2`.`c`) from `test`.`t2`) join `test`.`t1` where `test`.`t1`.`b` = 7 and `test`.`t1`.`a` = `<subquery2>`.`MAX(c)` and (<cache>(`<subquery2>`.`MAX(c)` is null) or `<subquery2>`.`MAX(c)` = 7)
++Note 1003 /* select#1 */ select `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b` from <materialize> (/* select#2 */ select max(`test`.`t2`.`c`) from `test`.`t2` having `MAX(c)` is null or `MAX(c)` = 7) join `test`.`t1` where `test`.`t1`.`b` = 7 and `test`.`t1`.`a` = `<subquery2>`.`MAX(c)` and (<cache>(`<subquery2>`.`MAX(c)` is null) or `<subquery2>`.`MAX(c)` = 7)
+SELECT * FROM t1
+WHERE a IN (SELECT MAX(c) FROM t2) AND b=7 AND (a IS NULL OR a=b);
+a b
+7 7
+EXPLAIN
+SELECT * FROM t1
+WHERE a IN (SELECT MAX(c) FROM t2 WHERE c < 4) AND b=7 AND (a IS NULL OR a=b);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY <subquery2> const distinct_key distinct_key 4 const 1
+1 PRIMARY t1 ALL NULL NULL NULL NULL 3 Using where; Using join buffer (flat, BNL join)
+2 MATERIALIZED t2 ALL NULL NULL NULL NULL 3 Using where
+SELECT * FROM t1
+WHERE a IN (SELECT MAX(c) FROM t2 WHERE c < 4) AND b=7 AND (a IS NULL OR a=b);
+a b
+SET optimizer_switch=@save_optimizer_switch;
+DROP TABLE t1,t2;
+#
+# BUG#946055: Crash with semijoin IN subquery when hash join is used
+#
+CREATE TABLE t1 (a int);
+INSERT INTO t1 VALUES (7);
+CREATE TABLE t2 (b int, c int, d varchar(1), e varchar(1), KEY (c), KEY (d, c));
+INSERT INTO t2 VALUES
+(4,2,'v','v'), (6,1,'v','v'), (0,5,'x','x'), (7,1,'x','x'),
+(7,3,'i','i'), (7,1,'e','e'), (1,4,'p','p'), (1,2,'j','j');
+SET @save_optimizer_switch=@@optimizer_switch;
+SET @save_join_cache_level=@@join_cache_level;
+SET join_cache_level=2;
+EXPLAIN
+SELECT a, c FROM t1, t2
+WHERE (a, c) IN (SELECT s1.b, s1.c FROM t2 AS s1, t2 AS s2
+WHERE s2.d = s1.e AND s1.e = (SELECT MAX(e) FROM t2));
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t1 system NULL NULL NULL NULL 1
+1 PRIMARY t2 index c c 5 NULL 8 Using index
+1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 8 func,func 1
+2 MATERIALIZED s2 ref d d 4 const 2 Using where; Using index
+2 MATERIALIZED s1 ALL c NULL NULL NULL 8 Using where; Using join buffer (flat, BNL join)
+3 SUBQUERY t2 ALL NULL NULL NULL NULL 8
+SELECT a, c FROM t1, t2
+WHERE (a, c) IN (SELECT s1.b, s1.c FROM t2 AS s1, t2 AS s2
+WHERE s2.d = s1.e AND s1.e = (SELECT MAX(e) FROM t2));
+a c
+7 1
+7 1
+7 1
+SET optimizer_switch='join_cache_hashed=on';
+SET join_cache_level=4;
+EXPLAIN
+SELECT a, c FROM t1, t2
+WHERE (a, c) IN (SELECT s1.b, s1.c FROM t2 AS s1, t2 AS s2
+WHERE s2.d = s1.e AND s1.e = (SELECT MAX(e) FROM t2));
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t1 system NULL NULL NULL NULL 1
+1 PRIMARY t2 index c c 5 NULL 8 Using index
+1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 8 func,func 1
+2 MATERIALIZED s2 ref d d 4 const 2 Using where; Using index
+2 MATERIALIZED s1 hash_ALL c #hash#$hj 5 const 8 Using where; Using join buffer (flat, BNLH join)
+3 SUBQUERY t2 ALL NULL NULL NULL NULL 8
+SELECT a, c FROM t1, t2
+WHERE (a, c) IN (SELECT s1.b, s1.c FROM t2 AS s1, t2 AS s2
+WHERE s2.d = s1.e AND s1.e = (SELECT MAX(e) FROM t2));
+a c
+7 1
+7 1
+7 1
+SET optimizer_switch=@save_optimizer_switch;
+SET join_cache_level=@save_join_cache_level;
+DROP TABLE t1,t2;
+#
+# BUG#952297: Server crashes on 2nd execution of PS in Field::is_null with semijoin+materialization
+#
+CREATE TABLE t1 ( a VARCHAR(1) );
+INSERT INTO t1 VALUES ('y'),('z');
+CREATE TABLE t2 ( b VARCHAR(1), c VARCHAR(1) );
+INSERT INTO t2 VALUES ('v','v'),('v','v');
+CREATE VIEW v2 AS SELECT * FROM t2;
+PREPARE ps FROM '
+SELECT a FROM t1, v2
+WHERE ( c, b ) IN ( SELECT b, b FROM t2 )
+GROUP BY a ';
+EXECUTE ps;
+a
+y
+z
+EXECUTE ps;
+a
+y
+z
+DROP VIEW v2;
+DROP TABLE t1, t2;
+#
+# BUG#1000269: Wrong result (extra rows) with semijoin+materialization, IN subqueries, join_cache_level>0
+#
+CREATE TABLE t1 (a1 VARCHAR(1), a2 VARCHAR(1)) ENGINE=MyISAM;
+INSERT INTO t1 VALUES ('b','b'),('e','e');
+CREATE TABLE t2 (b1 VARCHAR(1), b2 VARCHAR(1), KEY(b1)) ENGINE=MyISAM;
+INSERT INTO t2 VALUES ('v','v'),('s','s'),('l','l'), ('y','y'),('c','c'),('i','i');
+SELECT * FROM t1, t2 WHERE b1 IN ( SELECT b2 FROM t2 WHERE b1 > 'o' ) AND ( b1 < 'l' OR a1 IN ('b','c') );
+a1 a2 b1 b2
+b b v v
+b b s s
+b b y y
+DROP TABLE t1,t2;
+#
+# MDEV-4465: Reproducible crash (mysqld got signal 11) in multi_delete::initialize_tables with semijoin+materialization
+#
+CREATE TABLE t1 (
+id int(11) NOT NULL
+);
+CREATE TABLE t2 (
+id int(11) NOT NULL,
+a_id int(11) DEFAULT NULL
+);
+insert into t1 values (1), (2), (3);
+insert into t2 values (1, 1), (2, 1), (3, 1), (4, 2), (5, 3), (6, 3), (7, 3);
+delete t2 from t2 where a_id in (select * from (select t1.id from t1 limit 2) as x);
+drop table t1,t2;
+# This must be at the end:
+set optimizer_switch=@subselect_sj_mat_tmp;
+set join_cache_level=@save_join_cache_level;
+#
+# MDEV-4908: Assertion `((Item_cond *) cond)->functype() ==
+# ((Item_cond *) new_item)->functype()' fails on a query with
+# IN and equal conditions, AND/OR, materialization+semijoin
+#
+SET @save_optimizer_switch=@@optimizer_switch;
+SET optimizer_switch = 'materialization=on,semijoin=on';
+CREATE TABLE t1 (pk INT, a INT, b INT, PRIMARY KEY(pk)) ENGINE=MyISAM;
+INSERT INTO t1 VALUES (1,3,5),(2,4,6);
+SELECT * FROM t1 WHERE 8 IN ( SELECT MIN(pk) FROM t1 ) AND ( pk = a OR pk = b );
+pk a b
+drop table t1;
+SET optimizer_switch=@save_optimizer_switch;
+#
+# MDEV-5011: ERROR Plugin 'MEMORY' has ref_count=1 after shutdown for SJM queries
+#
+CREATE TABLE t1 (pk INT, a INT, b INT, PRIMARY KEY(pk)) ENGINE=MyISAM;
+INSERT INTO t1 VALUES (1,3,5),(2,4,6);
+SELECT * FROM t1 WHERE 8 IN (SELECT MIN(pk) FROM t1) AND (pk = a OR pk = b);
+pk a b
+DROP TABLE t1;
+#
+# MDEV-5368: Server crashes in Item_in_subselect::optimize on 2nd
+# execution of PS with IN subqueries, materialization+semijoin
+#
+CREATE TABLE t1 (a INT) ENGINE=MyISAM;
+INSERT INTO t1 VALUES (1),(3);
+CREATE TABLE t2 (b INT) ENGINE=MyISAM;
+CREATE ALGORITHM=MERGE VIEW v2 AS SELECT * FROM t2;
+INSERT INTO t2 VALUES (8),(9);
+PREPARE stmt FROM "
+SELECT * FROM t1 WHERE 1 IN ( SELECT b FROM v2 WHERE 2 IN ( SELECT MAX(a) FROM t1 ) )
+";
+EXECUTE stmt;
+a
+EXECUTE stmt;
+a
+DROP TABLE t1, t2;
+DROP VIEW v2;
+#
+# MDEV-5811: Server crashes in best_access_path with materialization+semijoin and big_tables=ON
+#
+SET @tmp_mdev5811= @@big_tables;
+SET big_tables = ON;
+CREATE TABLE t1 (a INT);
+INSERT INTO t1 VALUES (1),(2);
+CREATE TABLE t2 (b INT);
+INSERT INTO t2 VALUES (3),(4);
+SELECT * FROM t1 AS t1_1, t1 AS t1_2
+WHERE ( t1_1.a, t1_2.a ) IN ( SELECT MAX(b), MIN(b) FROM t2 );
+a a
+DROP TABLE t1,t2;
+SET big_tables=@tmp_mdev5811;
+# End of 5.3 tests
+#
+# MDEV-5056: Wrong result (extra rows) with materialization+semijoin, IN subqueries
+#
+set @tmp_mdev5056=@@join_cache_level;
+SET join_cache_level = 2;
+CREATE TABLE t1 ( c1 VARCHAR(2), c2 VARCHAR(2), INDEX(c1) ) ENGINE=MyISAM;
+INSERT INTO t1 VALUES
+('JP','OM'),('VA','JP'),('CA','ML'),('ML','EG'),('DK','CA'),
+('DK','QA'),('YE','PL'),('TR','ZW'),('DK','SK'),('SK','DK'),
+('RO','ML'),('ML','BG'),('BG','ZW'),('ZW','GE'),('GE','JP'),
+('PL','EG'),('QA','YE'),('WF','DK'),('DK','JP'),('EG','OM');
+CREATE TABLE t2 ( c3 VARCHAR(2), c4 VARCHAR(2) ) ENGINE=MyISAM;
+INSERT INTO t2 VALUES ('CA','ML'),('IN','HU'),('HU','IN');
+SELECT * FROM t1 AS alias1, t1 AS alias2
+WHERE ( alias2.c2, alias1.c1 ) IN ( SELECT c4, c3 FROM t2 ) AND alias1.c1 IN ( SELECT c2 FROM t1 );
+c1 c2 c1 c2
+CA ML CA ML
+CA ML RO ML
+DROP TABLE t1,t2;
+set join_cache_level=@tmp_mdev5056;
+#
+# MDEV-5368: Server crashes in Item_in_subselect::optimize on 2nd
+# execution of PS with IN subqueries, materialization+semijoin
+#
+CREATE TABLE t1 (a INT) ENGINE=MyISAM;
+INSERT INTO t1 VALUES (1),(3);
+CREATE TABLE t2 (b INT) ENGINE=MyISAM;
+CREATE ALGORITHM=MERGE VIEW v2 AS SELECT * FROM t2;
+INSERT INTO t2 VALUES (8),(9);
+PREPARE stmt FROM "
+SELECT * FROM t1 WHERE 1 IN ( SELECT b FROM v2 WHERE 2 IN ( SELECT MAX(a) FROM t1 ) )
+";
+EXECUTE stmt;
+a
+EXECUTE stmt;
+a
+DROP TABLE t1, t2;
+DROP VIEW v2;
+#
+# MDEV-6289 : Unexpected results when querying information_schema
+#
+CREATE TABLE t1 (
+id int(11) unsigned NOT NULL AUTO_INCREMENT,
+db varchar(254) NOT NULL DEFAULT '',
+PRIMARY KEY (id),
+UNIQUE KEY db (db)
+) DEFAULT CHARSET=utf8;
+INSERT INTO t1 (db) VALUES ('mysqltest1'),('mysqltest2'),('mysqltest3'),('mysqltest4');
+drop database if exists mysqltest1;
+drop database if exists mysqltest2;
+drop database if exists mysqltest3;
+drop database if exists mysqltest4;
+create database mysqltest1;
+create database mysqltest2;
+create database mysqltest3;
+create database mysqltest4;
+SELECT db FROM t1 WHERE db IN (SELECT SCHEMA_NAME FROM information_schema.schemata) ORDER BY db DESC;
+db
+mysqltest4
+mysqltest3
+mysqltest2
+mysqltest1
+EXPLAIN EXTENDED
+SELECT db FROM t1 WHERE db IN (SELECT SCHEMA_NAME FROM information_schema.schemata) ORDER BY db DESC;
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY <subquery2> ALL distinct_key NULL NULL NULL 2 100.00 Using temporary; Using filesort
+1 PRIMARY t1 eq_ref db db 764 information_schema.schemata.SCHEMA_NAME 1 100.00 Using where; Using index
+2 MATERIALIZED schemata ALL NULL NULL NULL NULL NULL NULL
+Warnings:
+Note 1003 select `test`.`t1`.`db` AS `db` from `test`.`t1` semi join (`information_schema`.`schemata`) where `test`.`t1`.`db` = `information_schema`.`schemata`.`SCHEMA_NAME` order by `test`.`t1`.`db` desc
+drop table t1;
+drop database mysqltest1;
+drop database mysqltest2;
+drop database mysqltest3;
+drop database mysqltest4;
+#
+# MDEV-7810 Wrong result on execution of a query as a PS
+# (both 1st and further executions)
+CREATE TABLE t1 (a INT NOT NULL) ENGINE=MyISAM;
+INSERT INTO t1 VALUES (0),(8);
+SELECT a FROM (SELECT DISTINCT * FROM t1) AS sq WHERE a IN (SELECT MIN(t2.a) FROM (t1 AS t2));
+a
+0
+PREPARE stmt FROM "
+SELECT a FROM (SELECT DISTINCT * FROM t1) AS sq WHERE a IN (SELECT MIN(t2.a) FROM (t1 AS t2))
+";
+execute stmt;
+a
+0
+execute stmt;
+a
+0
+drop table t1;
+#
+# MDEV-12429: IN subquery used in WHERE of EXISTS subquery
+#
+CREATE TABLE t1 (
+pk INT, f1 INT NOT NULL, f2 VARCHAR(3), f3 INT NULL, PRIMARY KEY(pk)) ENGINE=MyISAM;
+INSERT INTO t1 VALUES (1,1,'foo',8), (2,5,'bar',7);
+SELECT sq1.f2 FROM t1 AS sq1
+WHERE EXISTS ( SELECT * FROM t1 AS sq2
+WHERE sq1.`pk` IN ( SELECT f1 FROM t1 ) AND sq2.f1 = sq1.f1 );
+f2
+foo
+set @save_optimizer_switch= @@optimizer_switch;
+set optimizer_switch='exists_to_in=off';
+EXPLAIN
+SELECT sq1.f2 FROM t1 AS sq1
+WHERE EXISTS ( SELECT * FROM t1 AS sq2
+WHERE sq1.`pk` IN ( SELECT f1 FROM t1 ) AND sq2.f1 = sq1.f1 );
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY sq1 ALL NULL NULL NULL NULL 2 Using where
+2 DEPENDENT SUBQUERY <subquery3> eq_ref distinct_key distinct_key 4 func 1
+2 DEPENDENT SUBQUERY sq2 ALL NULL NULL NULL NULL 2 Using where; Using join buffer (flat, BNL join)
+3 MATERIALIZED t1 ALL NULL NULL NULL NULL 2
+# this checks the result set above
+set optimizer_switch= 'materialization=off,semijoin=off';
+SELECT sq1.f2 FROM t1 AS sq1
+WHERE EXISTS ( SELECT * FROM t1 AS sq2
+WHERE sq1.`pk` IN ( SELECT f1 FROM t1 ) AND sq2.f1 = sq1.f1 );
+f2
+foo
+set optimizer_switch= @save_optimizer_switch;
+DROP TABLE t1;
+#
+# MDEV-12145: IN subquery used in WHERE of EXISTS subquery
+#
+CREATE TABLE t1 (f1 INT) ENGINE=MyISAM;
+INSERT INTO t1 VALUES (4),(6);
+CREATE TABLE t2 (i2 INT, KEY(i2)) ENGINE=MyISAM;
+INSERT INTO t2 VALUES (8),(7),(1);
+CREATE TABLE t3 (f3 INT, i3 INT, KEY(i3)) ENGINE=MyISAM;
+INSERT INTO t3 VALUES (8,0),(6,3),(2,8),(3,8),(1,6),(0,0),(1,0),(1,5);
+set @save_optimizer_switch= @@optimizer_switch;
+set optimizer_switch='exists_to_in=off';
+SELECT * FROM t1
+WHERE EXISTS ( SELECT * FROM t2, t3
+WHERE i3 = i2 AND f1 IN ( SELECT f3 FROM t3 ) );
+f1
+6
+EXPLAIN EXTENDED
+SELECT * FROM t1
+WHERE EXISTS ( SELECT * FROM t2, t3
+WHERE i3 = i2 AND f1 IN ( SELECT f3 FROM t3 ) );
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY t1 ALL NULL NULL NULL NULL 2 100.00 Using where
+2 DEPENDENT SUBQUERY <subquery3> eq_ref distinct_key distinct_key 4 func 1 100.00
+2 DEPENDENT SUBQUERY t2 index i2 i2 5 NULL 3 100.00 Using where; Using index; Using join buffer (flat, BNL join)
+2 DEPENDENT SUBQUERY t3 ref i3 i3 5 test.t2.i2 2 100.00 Using index
+3 MATERIALIZED t3 ALL NULL NULL NULL NULL 8 100.00
+Warnings:
+Note 1276 Field or reference 'test.t1.f1' of SELECT #2 was resolved in SELECT #1
+Note 1003 /* select#1 */ select `test`.`t1`.`f1` AS `f1` from `test`.`t1` where <expr_cache><`test`.`t1`.`f1`>(exists(/* select#2 */ select 1 from `test`.`t2` semi join (`test`.`t3`) join `test`.`t3` where `test`.`t3`.`i3` = `test`.`t2`.`i2` and `test`.`t1`.`f1` = `test`.`t3`.`f3`))
+# this checks the result set above
+set optimizer_switch= 'materialization=off,semijoin=off';
+SELECT * FROM t1
+WHERE EXISTS ( SELECT * FROM t2, t3
+WHERE i3 = i2 AND f1 IN ( SELECT f3 FROM t3 ) );
+f1
+6
+set optimizer_switch= @save_optimizer_switch;
+DROP TABLE t1,t2,t3;
+#
+# MDEV-9686: IN subquery used in WHERE of a subquery from select list
+#
+CREATE TABLE t1 (pk INT PRIMARY KEY, f1 INT);
+INSERT INTO t1 VALUES (1, 4),(2, 3),(3, 3),(4, 6),(5, 3);
+CREATE TABLE t2 (f2 INT);
+INSERT INTO t2 VALUES (1),(2),(3),(4),(5);
+# t1.pk is always IN ( SELECT f2 FROM t2 ),
+# so the IN condition should be true for every row,
+# and thus COUNT(*) should always return 5
+SELECT pk, f1, ( SELECT COUNT(*) FROM t2
+WHERE t1.pk IN ( SELECT f2 FROM t2 ) ) AS sq FROM t1;
+pk f1 sq
+1 4 5
+2 3 5
+3 3 5
+4 6 5
+5 3 5
+EXPLAIN EXTENDED
+SELECT pk, f1, ( SELECT COUNT(*) FROM t2
+WHERE t1.pk IN ( SELECT f2 FROM t2 ) ) AS sq FROM t1;
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY t1 ALL NULL NULL NULL NULL 5 100.00
+2 DEPENDENT SUBQUERY <subquery3> eq_ref distinct_key distinct_key 4 func 1 100.00
+2 DEPENDENT SUBQUERY t2 ALL NULL NULL NULL NULL 5 100.00 Using join buffer (flat, BNL join)
+3 MATERIALIZED t2 ALL NULL NULL NULL NULL 5 100.00
+Warnings:
+Note 1276 Field or reference 'test.t1.pk' of SELECT #2 was resolved in SELECT #1
+Note 1003 /* select#1 */ select `test`.`t1`.`pk` AS `pk`,`test`.`t1`.`f1` AS `f1`,<expr_cache><`test`.`t1`.`pk`>((/* select#2 */ select count(0) from `test`.`t2` semi join (`test`.`t2`) where `test`.`t1`.`pk` = `test`.`t2`.`f2`)) AS `sq` from `test`.`t1`
+# this checks the result set above
+set @save_optimizer_switch= @@optimizer_switch;
+set optimizer_switch= 'materialization=off,semijoin=off';
+SELECT pk, f1, ( SELECT COUNT(*) FROM t2
+WHERE t1.pk IN ( SELECT f2 FROM t2 ) ) AS sq FROM t1;
+pk f1 sq
+1 4 5
+2 3 5
+3 3 5
+4 6 5
+5 3 5
+set optimizer_switch= @save_optimizer_switch;
+DROP TABLE t1,t2;
+#
+# mdev-12838: scan of materialized of semi-join subquery in join
+#
+set @save_optimizer_switch=@@optimizer_switch;
+CREATE TABLE t1 (
+dispatch_group varchar(32),
+assignment_group varchar(32),
+sys_id char(32),
+PRIMARY KEY (sys_id),
+KEY idx1 (dispatch_group),
+KEY idx2 (assignment_group)
+) ENGINE=MyISAM;
+CREATE TABLE t2 (
+ugroup varchar(32),
+user varchar(32),
+sys_id char(32),
+PRIMARY KEY (sys_id),
+KEY idx3 (ugroup),
+KEY idx4 (user)
+) ENGINE=MyISAM;
+CREATE TABLE t3 (
+type mediumtext,
+sys_id char(32),
+PRIMARY KEY (sys_id)
+) ENGINE=MyISAM;
+set optimizer_switch='materialization=off';
+explain SELECT t1.assignment_group
+FROM t1, t3
+WHERE t1.assignment_group = t3.sys_id AND
+t1.dispatch_group IN
+(SELECT t2.ugroup
+FROM t2, t3 t3_i
+WHERE t2.ugroup = t3_i.sys_id AND
+t3_i.type LIKE '59e22fb137032000158bbfc8bcbe5d52' AND
+t2.user = '86826bf03710200044e0bfc8bcbe5d79');
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t2 ref idx3,idx4 idx4 35 const 2 Using index condition; Using where; Start temporary
+1 PRIMARY t3_i eq_ref PRIMARY PRIMARY 32 test.t2.ugroup 1 Using index condition; Using where
+1 PRIMARY t1 ref idx1,idx2 idx1 35 test.t3_i.sys_id 2 Using index condition; Using where; End temporary
+1 PRIMARY t3 eq_ref PRIMARY PRIMARY 32 test.t1.assignment_group 1 Using where; Using index
+SELECT t1.assignment_group
+FROM t1, t3
+WHERE t1.assignment_group = t3.sys_id AND
+t1.dispatch_group IN
+(SELECT t2.ugroup
+FROM t2, t3 t3_i
+WHERE t2.ugroup = t3_i.sys_id AND
+t3_i.type LIKE '59e22fb137032000158bbfc8bcbe5d52' AND
+t2.user = '86826bf03710200044e0bfc8bcbe5d79');
+assignment_group
+df50316637232000158bbfc8bcbe5d23
+e08fad2637232000158bbfc8bcbe5d39
+ec70316637232000158bbfc8bcbe5d60
+7b10fd2637232000158bbfc8bcbe5d30
+ebb4620037332000158bbfc8bcbe5d89
+set optimizer_switch='materialization=on';
+explain SELECT t1.assignment_group
+FROM t1, t3
+WHERE t1.assignment_group = t3.sys_id AND
+t1.dispatch_group IN
+(SELECT t2.ugroup
+FROM t2, t3 t3_i
+WHERE t2.ugroup = t3_i.sys_id AND
+t3_i.type LIKE '59e22fb137032000158bbfc8bcbe5d52' AND
+t2.user = '86826bf03710200044e0bfc8bcbe5d79');
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY <subquery2> ALL distinct_key NULL NULL NULL 2
+1 PRIMARY t1 ref idx1,idx2 idx1 35 test.t2.ugroup 2 Using where
+1 PRIMARY t3 eq_ref PRIMARY PRIMARY 32 test.t1.assignment_group 1 Using where; Using index
+2 MATERIALIZED t2 ref idx3,idx4 idx4 35 const 2 Using index condition; Using where
+2 MATERIALIZED t3_i eq_ref PRIMARY PRIMARY 32 test.t2.ugroup 1 Using index condition; Using where
+SELECT t1.assignment_group
+FROM t1, t3
+WHERE t1.assignment_group = t3.sys_id AND
+t1.dispatch_group IN
+(SELECT t2.ugroup
+FROM t2, t3 t3_i
+WHERE t2.ugroup = t3_i.sys_id AND
+t3_i.type LIKE '59e22fb137032000158bbfc8bcbe5d52' AND
+t2.user = '86826bf03710200044e0bfc8bcbe5d79');
+assignment_group
+df50316637232000158bbfc8bcbe5d23
+e08fad2637232000158bbfc8bcbe5d39
+ec70316637232000158bbfc8bcbe5d60
+7b10fd2637232000158bbfc8bcbe5d30
+ebb4620037332000158bbfc8bcbe5d89
+DROP TABLE t1,t2,t3;
+set optimizer_switch=@save_optimizer_switch;
+# End of 5.5 tests
+#
+# MDEV-7220: Materialization strategy is not used for REPLACE ... SELECT
+#
+create table t0(a int);
+insert into t0 values (0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
+create table t1 (a int, b int, c int);
+insert into t1
+select A.a+B.a*10+C.a*100, A.a+B.a*10+C.a*100, A.a+B.a*10+C.a*100
+from t0 A, t0 B, t0 C;
+create table t2 (a int, b int, c int);
+insert into t2 select A.a, A.a, A.a from t1 A;
+insert into t2 select * from t2;
+insert into t2 select * from t2;
+create table t3 as select * from t2 limit 1;
+# The testcase only makes sense if the following uses Materialization:
+explain
+select * from t1 where (a,b) in (select max(a),b from t2 group by b);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t1 ALL NULL NULL NULL NULL 1000 Using where
+1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 8 test.t1.a,test.t1.b 1
+2 MATERIALIZED t2 ALL NULL NULL NULL NULL 4000 Using temporary
+flush status;
+replace into t3
+select * from t1 where (a,b) in (select max(a),b from t2 group by b);
+# Sequential reads:
+# 1K is read from t1
+# 4K is read from t2
+# 1K groups is read from the tmp. table
+#
+# Lookups:
+# 4K lookups in group by table
+# 1K lookups in temp.table
+#
+# Writes:
+# 2x 1K writes to temporary tables (grouping table and subquery materialization table
+#
+# The point is that neither counter should be in the millions (this
+# will happen if Materialization is not used
+show status where Variable_name like 'Handler_read%' or Variable_name like 'Handler_%write%';
+Variable_name Value
+Handler_read_first 0
+Handler_read_key 5000
+Handler_read_last 0
+Handler_read_next 0
+Handler_read_prev 0
+Handler_read_retry 0
+Handler_read_rnd 0
+Handler_read_rnd_deleted 0
+Handler_read_rnd_next 6003
+Handler_tmp_write 2000
+Handler_write 1000
+drop table t0,t1,t2,t3;
+#
+# MDEV-7971: Assertion `name != __null' failed in ACL_internal_schema_registry::lookup
+# on 2nd execution os PS with multi-table update
+#
+CREATE TABLE t1 (f1 INT);
+INSERT INTO t1 VALUES (1),(2);
+CREATE TABLE t2 (f2 INT);
+INSERT INTO t2 VALUES (3),(4);
+CREATE TABLE t3 (f3 INT);
+INSERT INTO t3 VALUES (5),(6);
+PREPARE stmt FROM '
+ UPDATE t1, t2
+ SET f1 = 5
+ WHERE 8 IN ( SELECT MIN(f3) FROM t3 )
+';
+EXECUTE stmt;
+EXECUTE stmt;
+DROP TABLE t1,t2,t3;
+#
+# MDEV-10389: Query returns different results on a debug vs non-debug build of the same revision
+#
+CREATE TABLE t1 (i1 INT, i2 INT NOT NULL);
+INSERT INTO t1 VALUES (1,4),(2,6);
+SELECT * FROM t1 AS alias1
+WHERE alias1.i1 IN (
+SELECT i1 FROM t1 WHERE alias1.i2 IN ( SELECT i2 FROM t1 HAVING i2 <> 7 )
+);
+i1 i2
+1 4
+2 6
+DROP TABLE t1;
diff --cc mysql-test/suite/sys_vars/r/sysvars_server_embedded.result
index b81a1ac,49c3841..f740e45
--- a/mysql-test/suite/sys_vars/r/sysvars_server_embedded.result
+++ b/mysql-test/suite/sys_vars/r/sysvars_server_embedded.result
@@@ -2673,17 -2673,17 +2673,17 @@@ ENUM_VALUE_LIST NUL
READ_ONLY NO
COMMAND_LINE_ARGUMENT REQUIRED
VARIABLE_NAME OPTIMIZER_SWITCH
--SESSION_VALUE index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,index_merge_sort_intersection=off,engine_condition_pushdown=off,index_condition_pushdown=on,derived_merge=on,derived_with_keys=on,firstmatch=on,loosescan=on,materialization=on,in_to_exists=on,semijoin=on,partial_match_rowid_merge=on,partial_match_table_scan=on,subquery_cache=on,mrr=off,mrr_cost_based=off,mrr_sort_keys=off,outer_join_with_cache=on,semijoin_with_cache=on,join_cache_incremental=on,join_cache_hashed=on,join_cache_bka=on,optimize_join_buffer_size=off,table_elimination=on,extended_keys=on,exists_to_in=on,orderby_uses_equalities=on,condition_pushdown_for_derived=on,split_materialized=on
--GLOBAL_VALUE index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,index_merge_sort_intersection=off,engine_condition_pushdown=off,index_condition_pushdown=on,derived_merge=on,derived_with_keys=on,firstmatch=on,loosescan=on,materialization=on,in_to_exists=on,semijoin=on,partial_match_rowid_merge=on,partial_match_table_scan=on,subquery_cache=on,mrr=off,mrr_cost_based=off,mrr_sort_keys=off,outer_join_with_cache=on,semijoin_with_cache=on,join_cache_incremental=on,join_cache_hashed=on,join_cache_bka=on,optimize_join_buffer_size=off,table_elimination=on,extended_keys=on,exists_to_in=on,orderby_uses_equalities=on,condition_pushdown_for_derived=on,split_materialized=on
++SESSION_VALUE index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,index_merge_sort_intersection=off,engine_condition_pushdown=off,index_condition_pushdown=on,derived_merge=on,derived_with_keys=on,firstmatch=on,loosescan=on,materialization=on,in_to_exists=on,semijoin=on,partial_match_rowid_merge=on,partial_match_table_scan=on,subquery_cache=on,mrr=off,mrr_cost_based=off,mrr_sort_keys=off,outer_join_with_cache=on,semijoin_with_cache=on,join_cache_incremental=on,join_cache_hashed=on,join_cache_bka=on,optimize_join_buffer_size=off,table_elimination=on,extended_keys=on,exists_to_in=on,orderby_uses_equalities=on,condition_pushdown_for_derived=on,split_materialized=on,condition_pushdown_for_subquery=on
++GLOBAL_VALUE index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,index_merge_sort_intersection=off,engine_condition_pushdown=off,index_condition_pushdown=on,derived_merge=on,derived_with_keys=on,firstmatch=on,loosescan=on,materialization=on,in_to_exists=on,semijoin=on,partial_match_rowid_merge=on,partial_match_table_scan=on,subquery_cache=on,mrr=off,mrr_cost_based=off,mrr_sort_keys=off,outer_join_with_cache=on,semijoin_with_cache=on,join_cache_incremental=on,join_cache_hashed=on,join_cache_bka=on,optimize_join_buffer_size=off,table_elimination=on,extended_keys=on,exists_to_in=on,orderby_uses_equalities=on,condition_pushdown_for_derived=on,split_materialized=on,condition_pushdown_for_subquery=on
GLOBAL_VALUE_ORIGIN COMPILE-TIME
--DEFAULT_VALUE index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,index_merge_sort_intersection=off,engine_condition_pushdown=off,index_condition_pushdown=on,derived_merge=on,derived_with_keys=on,firstmatch=on,loosescan=on,materialization=on,in_to_exists=on,semijoin=on,partial_match_rowid_merge=on,partial_match_table_scan=on,subquery_cache=on,mrr=off,mrr_cost_based=off,mrr_sort_keys=off,outer_join_with_cache=on,semijoin_with_cache=on,join_cache_incremental=on,join_cache_hashed=on,join_cache_bka=on,optimize_join_buffer_size=off,table_elimination=on,extended_keys=on,exists_to_in=on,orderby_uses_equalities=on,condition_pushdown_for_derived=on,split_materialized=on
++DEFAULT_VALUE index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,index_merge_sort_intersection=off,engine_condition_pushdown=off,index_condition_pushdown=on,derived_merge=on,derived_with_keys=on,firstmatch=on,loosescan=on,materialization=on,in_to_exists=on,semijoin=on,partial_match_rowid_merge=on,partial_match_table_scan=on,subquery_cache=on,mrr=off,mrr_cost_based=off,mrr_sort_keys=off,outer_join_with_cache=on,semijoin_with_cache=on,join_cache_incremental=on,join_cache_hashed=on,join_cache_bka=on,optimize_join_buffer_size=off,table_elimination=on,extended_keys=on,exists_to_in=on,orderby_uses_equalities=on,condition_pushdown_for_derived=on,split_materialized=on,condition_pushdown_for_subquery=on
VARIABLE_SCOPE SESSION
VARIABLE_TYPE FLAGSET
VARIABLE_COMMENT Fine-tune the optimizer behavior
NUMERIC_MIN_VALUE NULL
NUMERIC_MAX_VALUE NULL
NUMERIC_BLOCK_SIZE NULL
--ENUM_VALUE_LIST index_merge,index_merge_union,index_merge_sort_union,index_merge_intersection,index_merge_sort_intersection,engine_condition_pushdown,index_condition_pushdown,derived_merge,derived_with_keys,firstmatch,loosescan,materialization,in_to_exists,semijoin,partial_match_rowid_merge,partial_match_table_scan,subquery_cache,mrr,mrr_cost_based,mrr_sort_keys,outer_join_with_cache,semijoin_with_cache,join_cache_incremental,join_cache_hashed,join_cache_bka,optimize_join_buffer_size,table_elimination,extended_keys,exists_to_in,orderby_uses_equalities,condition_pushdown_for_derived,split_materialized,default
++ENUM_VALUE_LIST index_merge,index_merge_union,index_merge_sort_union,index_merge_intersection,index_merge_sort_intersection,engine_condition_pushdown,index_condition_pushdown,derived_merge,derived_with_keys,firstmatch,loosescan,materialization,in_to_exists,semijoin,partial_match_rowid_merge,partial_match_table_scan,subquery_cache,mrr,mrr_cost_based,mrr_sort_keys,outer_join_with_cache,semijoin_with_cache,join_cache_incremental,join_cache_hashed,join_cache_bka,optimize_join_buffer_size,table_elimination,extended_keys,exists_to_in,orderby_uses_equalities,condition_pushdown_for_derived,split_materialized,condition_pushdown_for_subquery,default
READ_ONLY NO
COMMAND_LINE_ARGUMENT REQUIRED
VARIABLE_NAME OPTIMIZER_USE_CONDITION_SELECTIVITY
diff --cc sql/item.cc
index 56af69b,f5878c5..b7a921f
--- a/sql/item.cc
+++ b/sql/item.cc
@@@ -7635,6 -7530,222 +7635,229 @@@ Item *Item_field::update_value_transfor
}
+ /**
+ @brief
+ Prepare AND/OR formula for extraction of a pushable condition
+
+ @param checker the checker callback function to be applied to the nodes
+ of the tree of the object
+ @param arg parameter to be passed to the checker
+
+ @details
+ This method recursively traverses this AND/OR condition and for each
+ subformula of the condition it checks whether it can be usable for the
+ extraction of a pushable condition. The criteria of pushability of
+ a subformula is checked by the callback function 'checker' with one
+ parameter arg. The subformulas that are not usable are marked with
+ the flag NO_EXTRACTION_FL.
+ @note
+ This method is called before any call of build_pushable_cond.
+ The flag NO_EXTRACTION_FL set in a subformula allows to avoid building
+ clones for the subformulas that are not used in the pushable condition.
+ @note
+ This method is called for pushdown conditions into materialized
+ derived tables/views optimization.
+ Item::pushable_cond_checker_for_derived() is passed as the actual callback
+ function.
+ Also it is called for pushdown conditions in materialized IN subqueries.
+ Item::pushable_cond_checker_for_subquery is passed as the actual
+ callback function.
+ */
+
+ void Item::check_pushable_cond(Pushdown_checker checker, uchar *arg)
+ {
+ clear_extraction_flag();
+ if (type() == Item::COND_ITEM)
+ {
+ bool and_cond= ((Item_cond*) this)->functype() == Item_func::COND_AND_FUNC;
+ List_iterator<Item> li(*((Item_cond*) this)->argument_list());
+ uint count= 0;
+ Item *item;
+ while ((item=li++))
+ {
+ item->check_pushable_cond(checker, arg);
+ if (item->get_extraction_flag() != NO_EXTRACTION_FL)
+ count++;
+ else if (!and_cond)
+ break;
+ }
+ if ((and_cond && count == 0) || item)
+ {
+ set_extraction_flag(NO_EXTRACTION_FL);
+ if (and_cond)
+ li.rewind();
+ while ((item= li++))
+ item->clear_extraction_flag();
+ }
+ }
+ else if (!((this->*checker) (arg)))
+ set_extraction_flag(NO_EXTRACTION_FL);
+ }
+
+
+ /**
+ @brief
+ Build condition extractable from this condition for pushdown
+
+ @param thd the thread handle
+ @param checker the checker callback function to be applied to the
+ equal items of multiple equality items
+ @param arg parameter to be passed to the checker
+
+ @details
+ This method finds out what condition that can be pushed down can be
+ extracted from this condition. If such condition C exists the
+ method builds the item for it. The method uses the flag NO_EXTRACTION_FL
+ set by the preliminary call of the method check_pushable_cond() to figure
+ out whether a subformula is pushable or not.
+ In the case when this item is a multiple equality a checker method is
+ called to find the equal fields to build a new equality that can be
+ pushed down.
+ @note
+ The built condition C is always implied by the condition cond
+ (cond => C). The method tries to build the most restrictive such
+ condition (i.e. for any other condition C' such that cond => C'
+ we have C => C').
+ @note
+ The build item is not ready for usage: substitution for the field items
+ has to be done and it has to be re-fixed.
+ @note
+ This method is called for pushdown conditions into materialized
+ derived tables/views optimization.
+ Item::pushable_equality_checker_for_derived() is passed as the actual
+ callback function.
+ Also it is called for pushdown conditions into materialized IN subqueries.
+ Item::pushable_equality_checker_for_subquery() is passed as the actual
+ callback function.
+
+ @retval
+ the built condition pushable into if such a condition exists
+ NULL if there is no such a condition
+ */
+
+ Item *Item::build_pushable_cond(THD *thd,
+ Pushdown_checker checker,
+ uchar *arg)
+ {
+ bool is_multiple_equality= type() == Item::FUNC_ITEM &&
+ ((Item_func*) this)->functype() == Item_func::MULT_EQUAL_FUNC;
+
+ if (get_extraction_flag() == NO_EXTRACTION_FL)
+ return 0;
+
+ if (type() == Item::COND_ITEM)
+ {
+ bool cond_and= false;
+ Item_cond *new_cond;
+ if (((Item_cond*) this)->functype() == Item_func::COND_AND_FUNC)
+ {
+ cond_and= true;
+ new_cond= new (thd->mem_root) Item_cond_and(thd);
+ }
+ else
+ new_cond= new (thd->mem_root) Item_cond_or(thd);
+ if (!new_cond)
+ return 0;
+ List_iterator<Item> li(*((Item_cond*) this)->argument_list());
+ Item *item;
-
++ bool is_fix_needed= false;
+ while ((item=li++))
+ {
+ if (item->get_extraction_flag() == NO_EXTRACTION_FL)
+ {
+ if (!cond_and)
+ return 0;
+ continue;
+ }
+ Item *fix= item->build_pushable_cond(thd, checker, arg);
+ if (!fix && !cond_and)
+ return 0;
+ if (!fix)
+ continue;
++
++ if (fix->type() == Item::COND_ITEM &&
++ ((Item_cond*) fix)->functype() == Item_func::COND_AND_FUNC)
++ is_fix_needed= true;
++
+ if (new_cond->argument_list()->push_back(fix, thd->mem_root))
+ return 0;
+ }
++ if (is_fix_needed)
++ new_cond->fix_fields(thd, 0);
+
+ switch (new_cond->argument_list()->elements)
+ {
+ case 0:
+ return 0;
+ case 1:
+ return new_cond->argument_list()->head();
+ default:
+ return new_cond;
+ }
+ }
+ else if (is_multiple_equality)
+ {
+ Item *new_cond= NULL;
+ int i= 0;
+ Item_equal *item_equal= (Item_equal *) this;
+ Item *left_item = item_equal->get_const();
+ Item_equal_fields_iterator it(*item_equal);
+ Item *item;
+ Item *right_item;
+ if (!left_item)
+ {
+ while ((item=it++))
+ {
+ left_item= ((item->*checker) (arg)) ? item : NULL;
+ if (left_item)
+ break;
+ }
+ }
+ if (!left_item)
+ return 0;
+ while ((item=it++))
+ {
+ right_item= ((item->*checker) (arg)) ? item : NULL;
+ if (!right_item)
+ continue;
+ Item_func_eq *eq= 0;
+ Item *left_item_clone= left_item->build_clone(thd);
+ Item *right_item_clone= item->build_clone(thd);
+ if (left_item_clone && right_item_clone)
+ {
+ left_item_clone->set_item_equal(NULL);
+ right_item_clone->set_item_equal(NULL);
+ eq= new (thd->mem_root) Item_func_eq(thd, right_item_clone,
+ left_item_clone);
+ }
+ if (eq)
+ {
+ i++;
+ switch (i)
+ {
+ case 1:
+ new_cond= eq;
+ break;
+ case 2:
+ new_cond= new (thd->mem_root) Item_cond_and(thd, new_cond, eq);
+ break;
+ default:
+ ((Item_cond_and*)new_cond)->argument_list()->push_back(eq,
+ thd->mem_root);
+ break;
+ }
+ }
+ }
+ if (new_cond && new_cond->fix_fields(thd, &new_cond))
+ return 0;
+ return new_cond;
+ }
+ else if (get_extraction_flag() != NO_EXTRACTION_FL)
+ return build_clone(thd);
+ return 0;
+ }
+
+
static
Item *get_field_item_for_having(THD *thd, Item *item, st_select_lex *sel)
{
diff --cc sql/sql_lex.cc
index 19e5acf,bea9fa0..6f1d8b8
--- a/sql/sql_lex.cc
+++ b/sql/sql_lex.cc
@@@ -7697,63 -7497,126 +7696,188 @@@ bool SELECT_LEX::vers_push_field(THD *t
}
+Item *Lex_trim_st::make_item_func_trim_std(THD *thd) const
+{
+ if (m_remove)
+ {
+ switch (m_spec) {
+ case TRIM_BOTH:
+ return new (thd->mem_root) Item_func_trim(thd, m_source, m_remove);
+ case TRIM_LEADING:
+ return new (thd->mem_root) Item_func_ltrim(thd, m_source, m_remove);
+ case TRIM_TRAILING:
+ return new (thd->mem_root) Item_func_rtrim(thd, m_source, m_remove);
+ }
+ }
+
+ switch (m_spec) {
+ case TRIM_BOTH:
+ return new (thd->mem_root) Item_func_trim(thd, m_source);
+ case TRIM_LEADING:
+ return new (thd->mem_root) Item_func_ltrim(thd, m_source);
+ case TRIM_TRAILING:
+ return new (thd->mem_root) Item_func_rtrim(thd, m_source);
+ }
+ DBUG_ASSERT(0);
+ return NULL;
+}
+
+
+Item *Lex_trim_st::make_item_func_trim_oracle(THD *thd) const
+{
+ if (m_remove)
+ {
+ switch (m_spec) {
+ case TRIM_BOTH:
+ return new (thd->mem_root) Item_func_trim_oracle(thd, m_source, m_remove);
+ case TRIM_LEADING:
+ return new (thd->mem_root) Item_func_ltrim_oracle(thd, m_source, m_remove);
+ case TRIM_TRAILING:
+ return new (thd->mem_root) Item_func_rtrim_oracle(thd, m_source, m_remove);
+ }
+ }
+
+ switch (m_spec) {
+ case TRIM_BOTH:
+ return new (thd->mem_root) Item_func_trim_oracle(thd, m_source);
+ case TRIM_LEADING:
+ return new (thd->mem_root) Item_func_ltrim_oracle(thd, m_source);
+ case TRIM_TRAILING:
+ return new (thd->mem_root) Item_func_rtrim_oracle(thd, m_source);
+ }
+ DBUG_ASSERT(0);
+ return NULL;
+}
+
+
+Item *Lex_trim_st::make_item_func_trim(THD *thd) const
+{
+ return (thd->variables.sql_mode & MODE_ORACLE) ?
+ make_item_func_trim_oracle(thd) :
+ make_item_func_trim_std(thd);
+}
++
++
+ /**
+ @brief
+ Extract from given item a condition pushable into WHERE clause
+
+ @param thd the thread handle
+ @param cond the item to extract a condition to be pushed
+ into WHERE
+ @param remaining_cond the condition that will remain of cond after
+ the pushdown of its parts into the WHERE clause
+ @param transformer the transformer callback function to be
+ applied to the condition so it can be pushed
+ down into the WHERE clause of this select
+ @param arg parameter to be passed to the transformer
+
+ @details
+ This method checks if cond entirely or its parts can be
+ pushed into the WHERE clause of this select and prepares it for pushing.
+
+ First it checks wherever this select doesn't have any aggregation function
+ in its projection and GROUP BY clause. If so cond can be entirely
+ pushed into the WHERE clause of this select but before its fields should
+ be transformed with transformer_for_where to make it pushable.
+
+ Otherwise the method checks wherever any condition depending only on
+ grouping fields can be extracted from cond. If there is any it prepares it
+ for pushing using grouping_field_transformer_for_where and if it happens to
+ be a conjunct of cond it removes it from cond. It saves the result of
+ removal in remaining_cond.
+ The extracted condition is saved in cond_pushed_into_where of this select.
+
+ @note
+ When looking for pushable condition the method considers only the grouping
+ fields from the list grouping_tmp_fields whose elements are of the type
+ Field_pair. This list must be prepared before the call of the
+ function.
+
+ @note
+ This method is called for pushdown conditions into materialized
+ derived tables/views optimization.
+ Item::derived_field_transformer_for_where is passed as the actual
+ callback function.
+ Also it is called for pushdown conditions into materialized IN subqueries.
+ Item::in_subq_field_transformer_for_where is passed as the actual
+ callback function.
+ */
+
+ void st_select_lex::pushdown_cond_into_where_clause(THD *thd, Item *cond,
+ Item **remaining_cond,
+ Item_transformer transformer,
+ uchar *arg)
+ {
+ if (!cond_pushdown_is_allowed())
+ return;
+ thd->lex->current_select= this;
+ if (have_window_funcs())
+ {
+ Item *cond_over_partition_fields;
+ check_cond_extraction_for_grouping_fields(cond);
+ cond_over_partition_fields=
+ build_cond_for_grouping_fields(thd, cond, true);
+ if (cond_over_partition_fields)
+ cond_over_partition_fields= cond_over_partition_fields->transform(thd,
+ &Item::grouping_field_transformer_for_where,
+ (uchar*) this);
+ if (cond_over_partition_fields)
+ {
+ cond_over_partition_fields->walk(
+ &Item::cleanup_excluding_const_fields_processor, 0, 0);
+ cond_pushed_into_where= cond_over_partition_fields;
+ }
+
+ return;
+ }
+
+ if (!join->group_list && !with_sum_func)
+ {
+ cond=
+ cond->transform(thd, transformer, arg);
+ if (cond)
+ {
+ cond->walk(
+ &Item::cleanup_excluding_const_fields_processor, 0, 0);
+ cond_pushed_into_where= cond;
+ }
+
+ return;
+ }
+
+ /*
+ Figure out what can be extracted from cond
+ that could be pushed into the WHERE clause of this select
+ */
+ Item *cond_over_grouping_fields;
+ check_cond_extraction_for_grouping_fields(cond);
+ cond_over_grouping_fields=
+ build_cond_for_grouping_fields(thd, cond, true);
+
+ /*
+ Transform the references to the columns from the cond
+ pushed into the WHERE clause of this select to make them usable in
+ the new context
+ */
+ if (cond_over_grouping_fields)
+ cond_over_grouping_fields= cond_over_grouping_fields->transform(thd,
+ &Item::grouping_field_transformer_for_where,
+ (uchar*) this);
+
+ if (cond_over_grouping_fields)
+ {
+
+ /*
+ In cond remove top conjuncts that has been pushed into the WHERE
+ clause of this select
+ */
+ cond= remove_pushed_top_conjuncts(thd, cond);
+
+ cond_over_grouping_fields->walk(
+ &Item::cleanup_excluding_const_fields_processor, 0, 0);
+ cond_pushed_into_where= cond_over_grouping_fields;
+ }
+
+ *remaining_cond= cond;
+ }
1
0
[Commits] 318097b: MDEV-15480 Audit plugin does not respect QUERY_DML for audit plugin.
by holyfoot@askmonty.org 10 May '18
by holyfoot@askmonty.org 10 May '18
10 May '18
revision-id: 318097bb8f6e12c546b5dcd287416158209dbb39 (mariadb-5.5.60-8-g318097b)
parent(s): 1d58d184c2c4ddd8a3b2be6f86d76c4e57bbe14f
committer: Alexey Botchkov
timestamp: 2018-05-10 19:00:54 +0400
message:
MDEV-15480 Audit plugin does not respect QUERY_DML for audit plugin.
QUERY_DML_NO_SELECT flag added.
---
mysql-test/suite/plugins/r/server_audit.result | 12 +++++++++++
mysql-test/suite/plugins/t/server_audit.test | 7 +++++++
plugin/server_audit/server_audit.c | 29 ++++++++++++++++++++++----
3 files changed, 44 insertions(+), 4 deletions(-)
diff --git a/mysql-test/suite/plugins/r/server_audit.result b/mysql-test/suite/plugins/r/server_audit.result
index 80b4345..2e18a48 100644
--- a/mysql-test/suite/plugins/r/server_audit.result
+++ b/mysql-test/suite/plugins/r/server_audit.result
@@ -182,6 +182,17 @@ select 2;
2
2
drop table t1;
+set global server_audit_events='query_dml_no_select';
+create table t1(id int);
+insert into t1 values (1), (2);
+select * from t1;
+id
+1
+2
+select 2;
+2
+2
+drop table t1;
set global server_audit_events='';
set global server_audit_query_log_limit= 15;
select (1), (2), (3), (4);
@@ -332,6 +343,7 @@ TIME,HOSTNAME,root,localhost,ID,ID,QUERY,sa_db,'SET PASSWORD \n# comment\nFOR u1
TIME,HOSTNAME,root,localhost,ID,ID,QUERY,sa_db,'SET PASSWORD FOR u1=<secret>',ID
TIME,HOSTNAME,root,localhost,ID,ID,QUERY,sa_db,'CREATE USER u3 IDENTIFIED BY *****',0
TIME,HOSTNAME,root,localhost,ID,ID,QUERY,sa_db,'drop user u1, u2, u3',0
+TIME,HOSTNAME,root,localhost,ID,ID,QUERY,sa_db,'insert into t1 values (1), (2)',0
TIME,HOSTNAME,root,localhost,ID,ID,QUERY,sa_db,'set global server_audit_events=\'\'',0
TIME,HOSTNAME,root,localhost,ID,ID,QUERY,sa_db,'set global serv',0
TIME,HOSTNAME,root,localhost,ID,ID,QUERY,sa_db,'select (1), (2)',0
diff --git a/mysql-test/suite/plugins/t/server_audit.test b/mysql-test/suite/plugins/t/server_audit.test
index 6c5eaff..4af1ed8 100644
--- a/mysql-test/suite/plugins/t/server_audit.test
+++ b/mysql-test/suite/plugins/t/server_audit.test
@@ -121,6 +121,13 @@ select 2;
/*! select 2*/;
/*comment*/ select 2;
drop table t1;
+set global server_audit_events='query_dml_no_select';
+create table t1(id int);
+insert into t1 values (1), (2);
+select * from t1;
+select 2;
+drop table t1;
+
set global server_audit_events='';
set global server_audit_query_log_limit= 15;
diff --git a/plugin/server_audit/server_audit.c b/plugin/server_audit/server_audit.c
index 9a3418e..d27da28 100644
--- a/plugin/server_audit/server_audit.c
+++ b/plugin/server_audit/server_audit.c
@@ -15,7 +15,7 @@
#define PLUGIN_VERSION 0x104
-#define PLUGIN_STR_VERSION "1.4.3"
+#define PLUGIN_STR_VERSION "1.4.4"
#define _my_thread_var loc_thread_var
@@ -366,16 +366,17 @@ static MYSQL_SYSVAR_STR(excl_users, excl_users, PLUGIN_VAR_RQCMDARG,
/* bits in the event filter. */
#define EVENT_CONNECT 1
#define EVENT_QUERY_ALL 2
-#define EVENT_QUERY 58
+#define EVENT_QUERY 122
#define EVENT_TABLE 4
#define EVENT_QUERY_DDL 8
#define EVENT_QUERY_DML 16
#define EVENT_QUERY_DCL 32
+#define EVENT_QUERY_DML_NO_SELECT 64
static const char *event_names[]=
{
"CONNECT", "QUERY", "TABLE", "QUERY_DDL", "QUERY_DML", "QUERY_DCL",
- NULL
+ "QUERY_DML_NO_SELECT", NULL
};
static TYPELIB events_typelib=
{
@@ -383,7 +384,7 @@ static TYPELIB events_typelib=
};
static MYSQL_SYSVAR_SET(events, events, PLUGIN_VAR_RQCMDARG,
"Specifies the set of events to monitor. Can be CONNECT, QUERY, TABLE,"
- " QUERY_DDL, QUERY_DML, QUERY_DCL.",
+ " QUERY_DDL, QUERY_DML, QUERY_DML_NO_SELECT, QUERY_DCL.",
NULL, NULL, 0, &events_typelib);
#define OUTPUT_SYSLOG 0
#define OUTPUT_FILE 1
@@ -857,6 +858,21 @@ struct sa_keyword dml_keywords[]=
};
+struct sa_keyword dml_no_select_keywords[]=
+{
+ {2, "DO", 0, SQLCOM_DML},
+ {4, "CALL", 0, SQLCOM_DML},
+ {4, "LOAD", &data_word, SQLCOM_DML},
+ {4, "LOAD", &xml_word, SQLCOM_DML},
+ {6, "DELETE", 0, SQLCOM_DML},
+ {6, "INSERT", 0, SQLCOM_DML},
+ {6, "UPDATE", 0, SQLCOM_DML},
+ {7, "HANDLER", 0, SQLCOM_DML},
+ {7, "REPLACE", 0, SQLCOM_DML},
+ {0, NULL, 0, SQLCOM_DML}
+};
+
+
struct sa_keyword dcl_keywords[]=
{
{6, "CREATE", &user_word, SQLCOM_DCL},
@@ -1637,6 +1653,11 @@ static int log_statement_ex(const struct connection_info *cn,
if (filter_query_type(query, dml_keywords))
goto do_log_query;
}
+ if (events & EVENT_QUERY_DML_NO_SELECT)
+ {
+ if (filter_query_type(query, dml_no_select_keywords))
+ goto do_log_query;
+ }
if (events & EVENT_QUERY_DCL)
{
if (filter_query_type(query, dcl_keywords))
1
0
[Commits] eae5844ca04: MDEV-15576: Server crashed in Cached_item_str::cmp / sortcmp or Assertion `item->null_value' failed in Type_handler_temporal_result::make_sort_key upon SELECT with NULLIF and ROLLUP
by Oleksandr Byelkin 09 May '18
by Oleksandr Byelkin 09 May '18
09 May '18
revision-id: eae5844ca04c89823cc9ee88095cf89aa45cdb69 (mariadb-10.3.6-127-geae5844ca04)
parent(s): 4513de3127df61fa2030690110bb34b7e1c40849
author: Oleksandr Byelkin
committer: Oleksandr Byelkin
timestamp: 2018-05-09 13:39:13 +0200
message:
MDEV-15576: Server crashed in Cached_item_str::cmp / sortcmp or Assertion `item->null_value' failed in Type_handler_temporal_result::make_sort_key upon SELECT with NULLIF and ROLLUP
Fix Item_func_rollup_const::get_date to process correctly NULL value.
---
mysql-test/main/olap.result | 14 ++++++++++++++
mysql-test/main/olap.test | 17 +++++++++++++++++
sql/item_func.h | 4 +++-
3 files changed, 34 insertions(+), 1 deletion(-)
diff --git a/mysql-test/main/olap.result b/mysql-test/main/olap.result
index bcc96d4951d..6fdbe008016 100644
--- a/mysql-test/main/olap.result
+++ b/mysql-test/main/olap.result
@@ -816,3 +816,17 @@ a int(11) YES 0
b int(20) YES 0
DROP VIEW v1;
DROP TABLE t1;
+#
+# MDEV-15576: Server crashed in Cached_item_str::cmp / sortcmp or
+# Assertion `item->null_value' failed in
+# Type_handler_temporal_result::make_sort_key upon SELECT with NULLIF
+# and ROLLUP
+#
+CREATE TABLE t1 (i INT);
+INSERT INTO t1 VALUES (1),(2);
+SELECT NULLIF( CAST( 'foo' AS DATE ), NULL & 'bar' ) AS f FROM t1 GROUP BY f WITH ROLLUP;
+f
+NULL
+NULL
+DROP TABLE t1;
+# End of 10.3 Tests
diff --git a/mysql-test/main/olap.test b/mysql-test/main/olap.test
index 3da08581a87..74dbe8ba10b 100644
--- a/mysql-test/main/olap.test
+++ b/mysql-test/main/olap.test
@@ -447,3 +447,20 @@ DESC v1;
DROP VIEW v1;
DROP TABLE t1;
+
+--echo #
+--echo # MDEV-15576: Server crashed in Cached_item_str::cmp / sortcmp or
+--echo # Assertion `item->null_value' failed in
+--echo # Type_handler_temporal_result::make_sort_key upon SELECT with NULLIF
+--echo # and ROLLUP
+--echo #
+
+CREATE TABLE t1 (i INT);
+INSERT INTO t1 VALUES (1),(2);
+--disable_warnings
+SELECT NULLIF( CAST( 'foo' AS DATE ), NULL & 'bar' ) AS f FROM t1 GROUP BY f WITH ROLLUP;
+--enable_warnings
+DROP TABLE t1;
+
+
+--echo # End of 10.3 Tests
diff --git a/sql/item_func.h b/sql/item_func.h
index 29ff14f7b39..c203a21cc2b 100644
--- a/sql/item_func.h
+++ b/sql/item_func.h
@@ -1613,7 +1613,9 @@ class Item_func_rollup_const :public Item_func
my_decimal *val_decimal(my_decimal *dec) { return args[0]->val_decimal(dec); }
bool get_date(MYSQL_TIME *ltime, ulonglong fuzzydate)
{
- return args[0]->get_date(ltime, fuzzydate);
+ bool rc= args[0]->get_date(ltime, fuzzydate);
+ null_value= rc;
+ return rc;
}
const char *func_name() const { return "rollup_const"; }
bool const_item() const { return 0; }
1
0
[Commits] 38cfcd7de13: MDEV-15373 engine gtid_slave_pos table name disobeys lower-case-table-names
by andrei.elkin@pp.inet.fi 09 May '18
by andrei.elkin@pp.inet.fi 09 May '18
09 May '18
revision-id: 38cfcd7de138977a80e116bc3911190ac803af13 (mariadb-10.3.6-81-g38cfcd7de13)
parent(s): baa5a43d8cb2f747eeb70d394a362fb5f3fdd194
author: Andrei Elkin
committer: Andrei Elkin
timestamp: 2018-05-08 22:17:18 +0300
message:
MDEV-15373 engine gtid_slave_pos table name disobeys lower-case-table-names
Replicated transaction extra gtid statement on slave failed to specify
an engine gtid_slave_pos name correctly. In case lower-case-table-names > 0
the InnoDB table name was generated to reproduce the lower-case-table-names=0 version
which is of mixed cases.
In rpl.rpl_mdev12179 test run this triggered a failure to DROP table which
was due to the innodb table handle was not closed:
InnoDB: Waited XYZ seconds for ref-count on table: `mysql`.`gtid_slave_pos_innodb`
on windows.
The closing issue was caused by having the table registered twice in the table cache,
for its lower- and mixed- case name versions. The DROP-table handler closed only
only one of the cache item to leave the 2nd one active.
(On Linux a failure occurs earlier at attempt to open an expected lower-cased table:
Last_Error: Error during XID COMMIT: failed to update GTID state in mysql.gtid_slave_pos: 1146: Table 'mysql.gtid_slave_pos_InnoDB' doesn't exist
but the table's name as the message shows is not in the right case).
Fixed with consulting lower-case-table-names when the engine gtid-slave-pos table
is created.
Note the lower-case-table-names=a-value created table will not recognized when next
the lower case option changes to a different value.
---
mysql-test/suite/rpl/r/rpl_mdev12179.result | 21 +++++++++++-----
mysql-test/suite/rpl/t/rpl_mdev12179.test | 38 +++++++++++++++++++++++++++--
sql/rpl_rli.cc | 1 +
3 files changed, 52 insertions(+), 8 deletions(-)
diff --git a/mysql-test/suite/rpl/r/rpl_mdev12179.result b/mysql-test/suite/rpl/r/rpl_mdev12179.result
index 40059375356..08b1de083af 100644
--- a/mysql-test/suite/rpl/r/rpl_mdev12179.result
+++ b/mysql-test/suite/rpl/r/rpl_mdev12179.result
@@ -152,12 +152,12 @@ a
1
2
*** Verify that mysql.gtid_slave_pos_InnoDB is auto-created ***
-SELECT table_name, engine FROM information_schema.tables
+SELECT lower(table_name), engine FROM information_schema.tables
WHERE table_schema='mysql' AND table_name LIKE 'gtid_slave_pos%'
ORDER BY table_name;
-table_name engine
+lower(table_name) engine
gtid_slave_pos MyISAM
-gtid_slave_pos_InnoDB InnoDB
+gtid_slave_pos_innodb InnoDB
include/stop_slave.inc
SET sql_log_bin=0;
INSERT INTO mysql.gtid_slave_pos SELECT * FROM mysql.gtid_slave_pos_InnoDB;
@@ -245,15 +245,24 @@ a
3
4
*** Verify that mysql.gtid_slave_pos_InnoDB is auto-created ***
-SELECT table_name, engine FROM information_schema.tables
+SELECT lower(table_name), engine FROM information_schema.tables
WHERE table_schema='mysql' AND table_name LIKE 'gtid_slave_pos%'
ORDER BY table_name;
-table_name engine
+lower(table_name) engine
gtid_slave_pos MyISAM
-gtid_slave_pos_InnoDB InnoDB
+gtid_slave_pos_innodb InnoDB
SELECT domain_id, max(seq_no) FROM mysql.gtid_slave_pos GROUP BY domain_id;
domain_id max(seq_no)
0 13
+connection server_2;
+*** Restart the slave server to prove 'gtid_slave_pos_innodb' autodiscovery ***
+connection server_2;
+SELECT max(seq_no) FROM mysql.gtid_slave_pos_InnoDB into @seq_no;
+connection server_1;
+INSERT INTO t2(a) SELECT 1+MAX(a) FROM t2;
+include/save_master_gtid.inc
+connection server_2;
+include/sync_with_master_gtid.inc
include/stop_slave.inc
SET GLOBAL gtid_pos_auto_engines="";
SET sql_log_bin=0;
diff --git a/mysql-test/suite/rpl/t/rpl_mdev12179.test b/mysql-test/suite/rpl/t/rpl_mdev12179.test
index a9113c91797..dac1881f40a 100644
--- a/mysql-test/suite/rpl/t/rpl_mdev12179.test
+++ b/mysql-test/suite/rpl/t/rpl_mdev12179.test
@@ -161,7 +161,8 @@ let $wait_condition=
SELECT EXISTS (SELECT * FROM information_schema.tables
WHERE table_schema='mysql' AND table_name='gtid_slave_pos_InnoDB');
--source include/wait_condition.inc
-SELECT table_name, engine FROM information_schema.tables
+# MDEV-15373 lowercases 'table_name' to satisfy --lower-case-table-names options
+SELECT lower(table_name), engine FROM information_schema.tables
WHERE table_schema='mysql' AND table_name LIKE 'gtid_slave_pos%'
ORDER BY table_name;
@@ -225,7 +226,7 @@ let $wait_condition=
SELECT EXISTS (SELECT * FROM information_schema.tables
WHERE table_schema='mysql' AND table_name='gtid_slave_pos_InnoDB');
--source include/wait_condition.inc
-SELECT table_name, engine FROM information_schema.tables
+SELECT lower(table_name), engine FROM information_schema.tables
WHERE table_schema='mysql' AND table_name LIKE 'gtid_slave_pos%'
ORDER BY table_name;
SELECT domain_id, max(seq_no) FROM mysql.gtid_slave_pos GROUP BY domain_id;
@@ -265,6 +266,39 @@ while (!$done)
# Note that at this point, the contents of table t2, as well as the GTID
# position, is non-deterministic.
+# MDEV-15373 engine gtid_slave_pos table name disobeys lower-case-table-names
+# This snippet verifies that engine gtid_slave_pos table is found,
+# its data are up-to-date.
+--write_file $MYSQLTEST_VARDIR/tmp/mysqld.2.expect
+wait
+EOF
+--connection server_2
+--shutdown_server 30
+--source include/wait_until_disconnected.inc
+
+--echo *** Restart the slave server to prove 'gtid_slave_pos_innodb' autodiscovery ***
+--append_file $MYSQLTEST_VARDIR/tmp/mysqld.2.expect
+restart: --skip-slave-start=0
+EOF
+
+--connection server_2
+--enable_reconnect
+--source include/wait_until_connected_again.inc
+SELECT max(seq_no) FROM mysql.gtid_slave_pos_InnoDB into @seq_no;
+
+--connection server_1
+INSERT INTO t2(a) SELECT 1+MAX(a) FROM t2;
+--source include/save_master_gtid.inc
+
+--connection server_2
+--source include/sync_with_master_gtid.inc
+if (`SELECT max(seq_no) <> @seq_no + 1 FROM mysql.gtid_slave_pos_InnoDB`)
+{
+ SELECT * FROM mysql.gtid_slave_pos_InnoDB;
+ --die Inconsistent table
+}
+#
+# end of MDEV-15373
#--connection server_2
--source include/stop_slave.inc
diff --git a/sql/rpl_rli.cc b/sql/rpl_rli.cc
index 6229f3e1faf..350c3528f61 100644
--- a/sql/rpl_rli.cc
+++ b/sql/rpl_rli.cc
@@ -1782,6 +1782,7 @@ gtid_pos_auto_create_tables(rpl_slave_state::gtid_pos_table **list_ptr)
p= strmake(p, plugin_name(*auto_engines)->str, FN_REFLEN - (p - buf));
table_name.str= buf;
table_name.length= p - buf;
+ table_case_convert(const_cast<char*>(table_name.str), table_name.length);
entry= rpl_global_gtid_slave_state->alloc_gtid_pos_table
(&table_name, hton, rpl_slave_state::GTID_POS_AUTO_CREATE);
if (!entry)
1
0
[Commits] 0efb1e5: MDEV-16104 Server crash in JOIN::fix_all_splittings_in_plan
by IgorBabaev 09 May '18
by IgorBabaev 09 May '18
09 May '18
revision-id: 0efb1e502f2b77ae483cc7894beaeaab575e9b6f (mariadb-10.3.6-112-g0efb1e5)
parent(s): 0bfd45f63419c45b68448cbd210a6e73e5c1ab34
author: Igor Babaev
committer: Igor Babaev
timestamp: 2018-05-08 23:32:11 -0700
message:
MDEV-16104 Server crash in JOIN::fix_all_splittings_in_plan
upon select with view and subqueries
This bug occurred when a splittable materialized derived/view
were used inside another splittable materialized derived/view.
The bug happened because the function JOIN::fix_all_splittings_in_plan()
was called at the very beginning of the optimization phase 2 at
the moment when the plan structure of the embedding derived/view
were not valid. The proper position for this call is the very
end of the optimization phase 1.
---
mysql-test/main/derived_cond_pushdown.result | 33 ++++++++++++++++++++++++++++
mysql-test/main/derived_cond_pushdown.test | 23 +++++++++++++++++++
sql/sql_select.cc | 15 ++++++++++---
3 files changed, 68 insertions(+), 3 deletions(-)
diff --git a/mysql-test/main/derived_cond_pushdown.result b/mysql-test/main/derived_cond_pushdown.result
index 82f621c..e178ceb 100644
--- a/mysql-test/main/derived_cond_pushdown.result
+++ b/mysql-test/main/derived_cond_pushdown.result
@@ -15165,3 +15165,36 @@ id select_type table type possible_keys key key_len ref rows Extra
3 DERIVED t1 ALL NULL NULL NULL NULL 5 Using temporary
2 DERIVED t1 ALL NULL NULL NULL NULL 5 Using temporary; Using filesort
drop table t1;
+#
+# MDEV-16104: embedded splittable materialized derived/views
+#
+CREATE TABLE t1 (f int PRIMARY KEY) ENGINE=MyISAM;
+INSERT INTO t1
+VALUES (3), (7), (1), (4), (8), (5), (9);
+CREATE ALGORITHM=MERGE VIEW v1 AS
+SELECT a2.*
+FROM
+( SELECT f, COUNT(*) as c FROM t1 GROUP BY f ) AS a1
+JOIN
+t1 AS a2
+USING (f);
+EXPLAIN EXTENDED
+SELECT * FROM ( SELECT STRAIGHT_JOIN f, COUNT(*) as c FROM v1 GROUP BY f ) AS s;
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY <derived2> ALL NULL NULL NULL NULL 7 100.00
+2 DERIVED <derived4> ALL NULL NULL NULL NULL 7 100.00 Using temporary; Using filesort
+2 DERIVED a2 eq_ref PRIMARY PRIMARY 4 a1.f 1 100.00 Using index
+4 DERIVED t1 index PRIMARY PRIMARY 4 NULL 7 100.00 Using index; Using temporary; Using filesort
+Warnings:
+Note 1003 /* select#1 */ select `s`.`f` AS `f`,`s`.`c` AS `c` from (/* select#2 */ select straight_join `a2`.`f` AS `f`,count(0) AS `c` from ((/* select#4 */ select `test`.`t1`.`f` AS `f`,count(0) AS `c` from `test`.`t1` group by `test`.`t1`.`f`)) `a1` join `test`.`t1` `a2` where `a2`.`f` = `a1`.`f` group by `a2`.`f`) `s`
+SELECT * FROM ( SELECT STRAIGHT_JOIN f, COUNT(*) as c FROM v1 GROUP BY f ) AS s;
+f c
+1 1
+3 1
+4 1
+5 1
+7 1
+8 1
+9 1
+DROP VIEW v1;
+DROP TABLE t1;
diff --git a/mysql-test/main/derived_cond_pushdown.test b/mysql-test/main/derived_cond_pushdown.test
index 2e2ec69..5966412 100644
--- a/mysql-test/main/derived_cond_pushdown.test
+++ b/mysql-test/main/derived_cond_pushdown.test
@@ -2690,3 +2690,26 @@ eval $q;
eval explain $q;
drop table t1;
+
+--echo #
+--echo # MDEV-16104: embedded splittable materialized derived/views
+--echo #
+
+CREATE TABLE t1 (f int PRIMARY KEY) ENGINE=MyISAM;
+INSERT INTO t1
+ VALUES (3), (7), (1), (4), (8), (5), (9);
+
+CREATE ALGORITHM=MERGE VIEW v1 AS
+SELECT a2.*
+FROM
+ ( SELECT f, COUNT(*) as c FROM t1 GROUP BY f ) AS a1
+ JOIN
+ t1 AS a2
+ USING (f);
+
+EXPLAIN EXTENDED
+SELECT * FROM ( SELECT STRAIGHT_JOIN f, COUNT(*) as c FROM v1 GROUP BY f ) AS s;
+SELECT * FROM ( SELECT STRAIGHT_JOIN f, COUNT(*) as c FROM v1 GROUP BY f ) AS s;
+
+DROP VIEW v1;
+DROP TABLE t1;
diff --git a/sql/sql_select.cc b/sql/sql_select.cc
index 320e631..c45edf8 100644
--- a/sql/sql_select.cc
+++ b/sql/sql_select.cc
@@ -1852,6 +1852,18 @@ JOIN::optimize_inner()
DBUG_RETURN(1);
}
+ /*
+ If a splittable materialized derived/view dt_i is embedded into
+ into another splittable materialized derived/view dt_o then
+ splitting plans for dt_i and dt_o are evaluated independently.
+ First the optimizer looks for the best splitting plan sp_i for dt_i.
+ It happens when non-splitting plans for dt_o are evaluated.
+ The cost of sp_i is considered as the cost of materialization of dt_i
+ when evaluating any splitting plan for dt_o.
+ */
+ if (fix_all_splittings_in_plan())
+ DBUG_RETURN(1);
+
setup_subq_exit:
with_two_phase_optimization= check_two_phase_optimization(thd);
if (with_two_phase_optimization)
@@ -9370,9 +9382,6 @@ bool JOIN::get_best_combination()
full_join=0;
hash_join= FALSE;
- if (fix_all_splittings_in_plan())
- DBUG_RETURN(TRUE);
-
fix_semijoin_strategies_for_picked_join_order(this);
JOIN_TAB_RANGE *root_range;
1
0
09 May '18
revision-id: b2fc197b566eb178afa09dd527f8e77a2d9b28de (mariadb-10.1.32-86-gb2fc197b566)
parent(s): f98496da969ed2b65f944f11ac11163030bc44b1
author: Jan Lindström
committer: Jan Lindström
timestamp: 2018-05-09 09:16:20 +0300
message:
MDEV-15351: wsrep_sst_xtrabackup is broken in 10.1.31
Remove the setup_ports function call. This is related to
https://github.com/MariaDB/server/pull/717
Thanks to Daniel Black and Bart S.
---
scripts/wsrep_sst_xtrabackup.sh | 1 -
1 file changed, 1 deletion(-)
diff --git a/scripts/wsrep_sst_xtrabackup.sh b/scripts/wsrep_sst_xtrabackup.sh
index 628c1f8b06c..5bf380a8144 100644
--- a/scripts/wsrep_sst_xtrabackup.sh
+++ b/scripts/wsrep_sst_xtrabackup.sh
@@ -408,7 +408,6 @@ if [[ ! ${WSREP_SST_OPT_ROLE} == 'joiner' && ! ${WSREP_SST_OPT_ROLE} == 'donor'
fi
read_cnf
-setup_ports
get_stream
get_transfer
1
0
[Commits] ce96028: MDEV-16088: Pushdown into materialized views/derived tables doesn't
by galina.shalygina@mariadb.com 08 May '18
by galina.shalygina@mariadb.com 08 May '18
08 May '18
revision-id: ce96028f690db1a4371e3846dbfb584c399486cb (mariadb-10.2.14-79-gce96028)
parent(s): bd1d152d05ba75bd1bdd2d9bc0358d8508df307a
author: Galina Shalygina
committer: Galina Shalygina
timestamp: 2018-05-08 18:22:38 +0200
message:
MDEV-16088: Pushdown into materialized views/derived tables doesn't
work in the IN subqueries
The pushdown into the materialized derived table/view wasn't done because
optimize() for the derived was called before any conditions that can
be pushed down were extracted. So optimize() in
convert_join_subqueries_to_semijoins() method is called too early and is
unnecessary. The second optimize() call in mysql_handle_single_derived()
is enough.
---
mysql-test/r/derived_cond_pushdown.result | 413 ++++++++++++++++++++++++++++++
mysql-test/r/derived_view.result | 4 +-
mysql-test/r/subselect_extra.result | 4 +-
mysql-test/t/derived_cond_pushdown.test | 83 ++++++
sql/opt_subselect.cc | 2 -
5 files changed, 500 insertions(+), 6 deletions(-)
diff --git a/mysql-test/r/derived_cond_pushdown.result b/mysql-test/r/derived_cond_pushdown.result
index 8e74e09..09b3b52 100644
--- a/mysql-test/r/derived_cond_pushdown.result
+++ b/mysql-test/r/derived_cond_pushdown.result
@@ -9045,3 +9045,416 @@ select * from (select date('2018-01-01') as d) as t
where t.d between date ('2017-01-01') and date ('2019-01-01');
d
2018-01-01
+#
+# MDEV-16088: pushdown into derived defined in the IN subquery
+#
+CREATE TABLE t1 (a INT, b INT);
+CREATE TABLE t2 (e INT, f INT, g INT);
+INSERT INTO t1 VALUES (1,14),(2,13),(1,19),(2,32),(3,24);
+INSERT INTO t2 VALUES (1,19,2),(3,24,1),(1,12,2),(3,11,3),(2,32,1);
+SELECT * FROM t1
+WHERE (t1.a,t1.b) IN
+(
+SELECT d_tab.e,d_tab.max_f
+FROM (
+SELECT t2.e, MAX(t2.f) AS max_f
+FROM t2
+GROUP BY t2.e
+HAVING max_f>18
+) as d_tab
+WHERE d_tab.e>1
+)
+;
+a b
+2 32
+3 24
+EXPLAIN SELECT * FROM t1
+WHERE (t1.a,t1.b) IN
+(
+SELECT d_tab.e,d_tab.max_f
+FROM (
+SELECT t2.e, MAX(t2.f) AS max_f
+FROM t2
+GROUP BY t2.e
+HAVING max_f>18
+) as d_tab
+WHERE d_tab.e>1
+)
+;
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t1 ALL NULL NULL NULL NULL 5
+1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 8 func,func 1
+2 MATERIALIZED <derived3> ALL NULL NULL NULL NULL 5 Using where
+3 DERIVED t2 ALL NULL NULL NULL NULL 5 Using where; Using temporary; Using filesort
+EXPLAIN FORMAT=JSON SELECT * FROM t1
+WHERE (t1.a,t1.b) IN
+(
+SELECT d_tab.e,d_tab.max_f
+FROM (
+SELECT t2.e, MAX(t2.f) AS max_f
+FROM t2
+GROUP BY t2.e
+HAVING max_f>18
+) as d_tab
+WHERE d_tab.e>1
+)
+;
+EXPLAIN
+{
+ "query_block": {
+ "select_id": 1,
+ "table": {
+ "table_name": "t1",
+ "access_type": "ALL",
+ "rows": 5,
+ "filtered": 100
+ },
+ "table": {
+ "table_name": "<subquery2>",
+ "access_type": "eq_ref",
+ "possible_keys": ["distinct_key"],
+ "key": "distinct_key",
+ "key_length": "8",
+ "used_key_parts": ["e", "max_f"],
+ "ref": ["func", "func"],
+ "rows": 1,
+ "filtered": 100,
+ "materialized": {
+ "unique": 1,
+ "query_block": {
+ "select_id": 2,
+ "table": {
+ "table_name": "<derived3>",
+ "access_type": "ALL",
+ "rows": 5,
+ "filtered": 100,
+ "attached_condition": "d_tab.e > 1",
+ "materialized": {
+ "query_block": {
+ "select_id": 3,
+ "having_condition": "max_f > 18",
+ "filesort": {
+ "sort_key": "t2.e",
+ "temporary_table": {
+ "table": {
+ "table_name": "t2",
+ "access_type": "ALL",
+ "rows": 5,
+ "filtered": 100,
+ "attached_condition": "t2.e > 1"
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+}
+SELECT * FROM t1
+WHERE (t1.a,t1.b) IN
+(
+SELECT d_tab.e,d_tab.max_f
+FROM (
+SELECT t2.e, MAX(t2.f) AS max_f
+FROM t2
+GROUP BY t2.e
+HAVING max_f>18
+) as d_tab
+WHERE d_tab.max_f<25
+)
+;
+a b
+1 19
+3 24
+EXPLAIN SELECT * FROM t1
+WHERE (t1.a,t1.b) IN
+(
+SELECT d_tab.e,d_tab.max_f
+FROM (
+SELECT t2.e, MAX(t2.f) AS max_f
+FROM t2
+GROUP BY t2.e
+HAVING max_f>18
+) as d_tab
+WHERE d_tab.max_f<25
+)
+;
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t1 ALL NULL NULL NULL NULL 5
+1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 8 func,func 1
+2 MATERIALIZED <derived3> ALL NULL NULL NULL NULL 5 Using where
+3 DERIVED t2 ALL NULL NULL NULL NULL 5 Using temporary; Using filesort
+EXPLAIN FORMAT=JSON SELECT * FROM t1
+WHERE (t1.a,t1.b) IN
+(
+SELECT d_tab.e,d_tab.max_f
+FROM (
+SELECT t2.e, MAX(t2.f) AS max_f
+FROM t2
+GROUP BY t2.e
+HAVING max_f>18
+) as d_tab
+WHERE d_tab.max_f<25
+)
+;
+EXPLAIN
+{
+ "query_block": {
+ "select_id": 1,
+ "table": {
+ "table_name": "t1",
+ "access_type": "ALL",
+ "rows": 5,
+ "filtered": 100
+ },
+ "table": {
+ "table_name": "<subquery2>",
+ "access_type": "eq_ref",
+ "possible_keys": ["distinct_key"],
+ "key": "distinct_key",
+ "key_length": "8",
+ "used_key_parts": ["e", "max_f"],
+ "ref": ["func", "func"],
+ "rows": 1,
+ "filtered": 100,
+ "materialized": {
+ "unique": 1,
+ "query_block": {
+ "select_id": 2,
+ "table": {
+ "table_name": "<derived3>",
+ "access_type": "ALL",
+ "rows": 5,
+ "filtered": 100,
+ "attached_condition": "d_tab.max_f < 25",
+ "materialized": {
+ "query_block": {
+ "select_id": 3,
+ "having_condition": "max_f > 18 and max_f < 25",
+ "filesort": {
+ "sort_key": "t2.e",
+ "temporary_table": {
+ "table": {
+ "table_name": "t2",
+ "access_type": "ALL",
+ "rows": 5,
+ "filtered": 100
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+}
+SELECT * FROM t1
+WHERE (t1.a,t1.b) IN
+(
+SELECT d_tab.e, MAX(d_tab.max_f) AS max_f
+FROM (
+SELECT t2.e, MAX(t2.f) as max_f, t2.g
+FROM t2
+GROUP BY t2.e
+) as d_tab
+WHERE d_tab.e>1
+GROUP BY d_tab.g
+)
+;
+a b
+2 32
+EXPLAIN SELECT * FROM t1
+WHERE (t1.a,t1.b) IN
+(
+SELECT d_tab.e, MAX(d_tab.max_f) AS max_f
+FROM (
+SELECT t2.e, MAX(t2.f) as max_f, t2.g
+FROM t2
+GROUP BY t2.e
+) as d_tab
+WHERE d_tab.e>1
+GROUP BY d_tab.g
+)
+;
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t1 ALL NULL NULL NULL NULL 5 Using where
+1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 8 test.t1.a,test.t1.b 1
+2 MATERIALIZED <derived3> ALL NULL NULL NULL NULL 5 Using where; Using temporary
+3 DERIVED t2 ALL NULL NULL NULL NULL 5 Using where; Using temporary; Using filesort
+EXPLAIN FORMAT=JSON SELECT * FROM t1
+WHERE (t1.a,t1.b) IN
+(
+SELECT d_tab.e, MAX(d_tab.max_f) AS max_f
+FROM (
+SELECT t2.e, MAX(t2.f) as max_f, t2.g
+FROM t2
+GROUP BY t2.e
+) as d_tab
+WHERE d_tab.e>1
+GROUP BY d_tab.g
+)
+;
+EXPLAIN
+{
+ "query_block": {
+ "select_id": 1,
+ "table": {
+ "table_name": "t1",
+ "access_type": "ALL",
+ "rows": 5,
+ "filtered": 100,
+ "attached_condition": "t1.a is not null and t1.b is not null"
+ },
+ "table": {
+ "table_name": "<subquery2>",
+ "access_type": "eq_ref",
+ "possible_keys": ["distinct_key"],
+ "key": "distinct_key",
+ "key_length": "8",
+ "used_key_parts": ["e", "max_f"],
+ "ref": ["test.t1.a", "test.t1.b"],
+ "rows": 1,
+ "filtered": 100,
+ "materialized": {
+ "unique": 1,
+ "query_block": {
+ "select_id": 2,
+ "temporary_table": {
+ "table": {
+ "table_name": "<derived3>",
+ "access_type": "ALL",
+ "rows": 5,
+ "filtered": 100,
+ "attached_condition": "d_tab.e > 1",
+ "materialized": {
+ "query_block": {
+ "select_id": 3,
+ "filesort": {
+ "sort_key": "t2.e",
+ "temporary_table": {
+ "table": {
+ "table_name": "t2",
+ "access_type": "ALL",
+ "rows": 5,
+ "filtered": 100,
+ "attached_condition": "t2.e > 1"
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+}
+SELECT * FROM t1
+WHERE (t1.a,t1.b) IN
+(
+SELECT d_tab.e, MAX(d_tab.max_f) AS max_f
+FROM (
+SELECT t2.e, MAX(t2.f) as max_f, t2.g
+FROM t2
+GROUP BY t2.e
+) as d_tab
+WHERE d_tab.max_f>20
+GROUP BY d_tab.g
+)
+;
+a b
+2 32
+EXPLAIN SELECT * FROM t1
+WHERE (t1.a,t1.b) IN
+(
+SELECT d_tab.e, MAX(d_tab.max_f) AS max_f
+FROM (
+SELECT t2.e, MAX(t2.f) as max_f, t2.g
+FROM t2
+GROUP BY t2.e
+) as d_tab
+WHERE d_tab.max_f>20
+GROUP BY d_tab.g
+)
+;
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t1 ALL NULL NULL NULL NULL 5 Using where
+1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 8 test.t1.a,test.t1.b 1
+2 MATERIALIZED <derived3> ALL NULL NULL NULL NULL 5 Using where; Using temporary
+3 DERIVED t2 ALL NULL NULL NULL NULL 5 Using temporary; Using filesort
+EXPLAIN FORMAT=JSON SELECT * FROM t1
+WHERE (t1.a,t1.b) IN
+(
+SELECT d_tab.e, MAX(d_tab.max_f) AS max_f
+FROM (
+SELECT t2.e, MAX(t2.f) as max_f, t2.g
+FROM t2
+GROUP BY t2.e
+) as d_tab
+WHERE d_tab.max_f>20
+GROUP BY d_tab.g
+)
+;
+EXPLAIN
+{
+ "query_block": {
+ "select_id": 1,
+ "table": {
+ "table_name": "t1",
+ "access_type": "ALL",
+ "rows": 5,
+ "filtered": 100,
+ "attached_condition": "t1.a is not null and t1.b is not null"
+ },
+ "table": {
+ "table_name": "<subquery2>",
+ "access_type": "eq_ref",
+ "possible_keys": ["distinct_key"],
+ "key": "distinct_key",
+ "key_length": "8",
+ "used_key_parts": ["e", "max_f"],
+ "ref": ["test.t1.a", "test.t1.b"],
+ "rows": 1,
+ "filtered": 100,
+ "materialized": {
+ "unique": 1,
+ "query_block": {
+ "select_id": 2,
+ "temporary_table": {
+ "table": {
+ "table_name": "<derived3>",
+ "access_type": "ALL",
+ "rows": 5,
+ "filtered": 100,
+ "attached_condition": "d_tab.max_f > 20",
+ "materialized": {
+ "query_block": {
+ "select_id": 3,
+ "having_condition": "max_f > 20",
+ "filesort": {
+ "sort_key": "t2.e",
+ "temporary_table": {
+ "table": {
+ "table_name": "t2",
+ "access_type": "ALL",
+ "rows": 5,
+ "filtered": 100
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+}
+DROP TABLE t1,t2;
diff --git a/mysql-test/r/derived_view.result b/mysql-test/r/derived_view.result
index df6ba08..d2804ce 100644
--- a/mysql-test/r/derived_view.result
+++ b/mysql-test/r/derived_view.result
@@ -1841,7 +1841,7 @@ id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY t2 system NULL NULL NULL NULL 1
1 PRIMARY t3 ALL NULL NULL NULL NULL 2 Using where
1 PRIMARY <derived3> ALL NULL NULL NULL NULL 3 Using where; Start temporary; End temporary
-3 DERIVED t1 ALL NULL NULL NULL NULL 3
+3 DERIVED t1 ALL NULL NULL NULL NULL 3 Using where
SELECT * FROM t3
WHERE t3.b IN (SELECT v1.b FROM v1, t2
WHERE t2.c = v1.c AND t2.c = v1.b AND v1.b = t3.c);
@@ -1856,7 +1856,7 @@ id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY t2 system NULL NULL NULL NULL 1
1 PRIMARY <derived3> ref key1 key1 8 const,const 0 Start temporary
1 PRIMARY t3 ALL NULL NULL NULL NULL 2 Using where; End temporary; Using join buffer (flat, BNL join)
-3 DERIVED t1 ALL NULL NULL NULL NULL 3
+3 DERIVED t1 ALL NULL NULL NULL NULL 3 Using where
SELECT * FROM t3
WHERE t3.b IN (SELECT v1.b FROM v1, t2
WHERE t2.c = v1.c AND t2.c = v1.b AND v1.b = t3.c);
diff --git a/mysql-test/r/subselect_extra.result b/mysql-test/r/subselect_extra.result
index 73642c0..a3a0f1f 100644
--- a/mysql-test/r/subselect_extra.result
+++ b/mysql-test/r/subselect_extra.result
@@ -434,7 +434,7 @@ id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY t2 system NULL NULL NULL NULL 1
1 PRIMARY t3 ALL NULL NULL NULL NULL 2 Using where
1 PRIMARY <derived3> ALL NULL NULL NULL NULL 3 Using where; FirstMatch(t3); Using join buffer (flat, BNL join)
-3 DERIVED t1 ALL NULL NULL NULL NULL 3
+3 DERIVED t1 ALL NULL NULL NULL NULL 3 Using where
SELECT * FROM t3
WHERE t3.b IN (SELECT v1.b FROM v1, t2
WHERE t2.c = v1.c AND t2.c = v1.b AND v1.b = t3.c);
@@ -449,7 +449,7 @@ id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY t2 system NULL NULL NULL NULL 1
1 PRIMARY <derived3> ref key1 key1 8 const,const 0 Start temporary
1 PRIMARY t3 ALL NULL NULL NULL NULL 2 Using where; End temporary; Using join buffer (flat, BNL join)
-3 DERIVED t1 ALL NULL NULL NULL NULL 3
+3 DERIVED t1 ALL NULL NULL NULL NULL 3 Using where
SELECT * FROM t3
WHERE t3.b IN (SELECT v1.b FROM v1, t2
WHERE t2.c = v1.c AND t2.c = v1.b AND v1.b = t3.c);
diff --git a/mysql-test/t/derived_cond_pushdown.test b/mysql-test/t/derived_cond_pushdown.test
index 0b87738..e8f6e9c 100644
--- a/mysql-test/t/derived_cond_pushdown.test
+++ b/mysql-test/t/derived_cond_pushdown.test
@@ -1646,3 +1646,86 @@ select * from (select date('2018-01-01') as d
select * from (select date('2018-01-01') as d) as t
where t.d between date ('2017-01-01') and date ('2019-01-01');
+
+--echo #
+--echo # MDEV-16088: pushdown into derived defined in the IN subquery
+--echo #
+
+CREATE TABLE t1 (a INT, b INT);
+CREATE TABLE t2 (e INT, f INT, g INT);
+INSERT INTO t1 VALUES (1,14),(2,13),(1,19),(2,32),(3,24);
+INSERT INTO t2 VALUES (1,19,2),(3,24,1),(1,12,2),(3,11,3),(2,32,1);
+
+LET $query=
+SELECT * FROM t1
+WHERE (t1.a,t1.b) IN
+ (
+ SELECT d_tab.e,d_tab.max_f
+ FROM (
+ SELECT t2.e, MAX(t2.f) AS max_f
+ FROM t2
+ GROUP BY t2.e
+ HAVING max_f>18
+ ) as d_tab
+ WHERE d_tab.e>1
+ )
+;
+EVAL $query;
+EVAL EXPLAIN $query;
+EVAL EXPLAIN FORMAT=JSON $query;
+
+LET $query=
+SELECT * FROM t1
+WHERE (t1.a,t1.b) IN
+ (
+ SELECT d_tab.e,d_tab.max_f
+ FROM (
+ SELECT t2.e, MAX(t2.f) AS max_f
+ FROM t2
+ GROUP BY t2.e
+ HAVING max_f>18
+ ) as d_tab
+ WHERE d_tab.max_f<25
+ )
+;
+EVAL $query;
+EVAL EXPLAIN $query;
+EVAL EXPLAIN FORMAT=JSON $query;
+
+LET $query=
+SELECT * FROM t1
+WHERE (t1.a,t1.b) IN
+ (
+ SELECT d_tab.e, MAX(d_tab.max_f) AS max_f
+ FROM (
+ SELECT t2.e, MAX(t2.f) as max_f, t2.g
+ FROM t2
+ GROUP BY t2.e
+ ) as d_tab
+ WHERE d_tab.e>1
+ GROUP BY d_tab.g
+ )
+;
+EVAL $query;
+EVAL EXPLAIN $query;
+EVAL EXPLAIN FORMAT=JSON $query;
+
+LET $query=
+SELECT * FROM t1
+WHERE (t1.a,t1.b) IN
+ (
+ SELECT d_tab.e, MAX(d_tab.max_f) AS max_f
+ FROM (
+ SELECT t2.e, MAX(t2.f) as max_f, t2.g
+ FROM t2
+ GROUP BY t2.e
+ ) as d_tab
+ WHERE d_tab.max_f>20
+ GROUP BY d_tab.g
+ )
+;
+EVAL $query;
+EVAL EXPLAIN $query;
+EVAL EXPLAIN FORMAT=JSON $query;
+
+DROP TABLE t1,t2;
diff --git a/sql/opt_subselect.cc b/sql/opt_subselect.cc
index b28adae..5765278 100644
--- a/sql/opt_subselect.cc
+++ b/sql/opt_subselect.cc
@@ -1092,8 +1092,6 @@ bool convert_join_subqueries_to_semijoins(JOIN *join)
while ((in_subq= li++))
{
SELECT_LEX *subq_sel= in_subq->get_select_lex();
- if (subq_sel->handle_derived(thd->lex, DT_OPTIMIZE))
- DBUG_RETURN(1);
if (subq_sel->handle_derived(thd->lex, DT_MERGE))
DBUG_RETURN(TRUE);
subq_sel->update_used_tables();
1
0
[Commits] 46e0c8a9219: MDEV-11071: Assertion `thd->transaction.stmt.is_empty()' failed in Locked_tables_list::unlock_locked_table
by Oleksandr Byelkin 08 May '18
by Oleksandr Byelkin 08 May '18
08 May '18
revision-id: 46e0c8a921978e7b95adf3f17f3c85b18d9f9ef6 (mariadb-10.2.14-78-g46e0c8a9219)
parent(s): 9bcd0f5fea8ca26742b10d37b95a966c69909ff1
author: Oleksandr Byelkin
committer: Oleksandr Byelkin
timestamp: 2018-05-08 15:26:26 +0200
message:
MDEV-11071: Assertion `thd->transaction.stmt.is_empty()' failed in Locked_tables_list::unlock_locked_table
fix_length_and_dec now return result (error/OK)
---
mysql-test/r/alter_table.result | 11 +++
mysql-test/t/alter_table.test | 16 ++++
sql/item.h | 2 +-
sql/item_cmpfunc.cc | 106 ++++++++++++++++----------
sql/item_cmpfunc.h | 58 ++++++++------
sql/item_func.cc | 106 +++++++++++++++-----------
sql/item_func.h | 118 ++++++++++++++++-------------
sql/item_geofunc.cc | 9 ++-
sql/item_geofunc.h | 72 ++++++++++--------
sql/item_inetfunc.h | 12 ++-
sql/item_jsonfunc.cc | 57 +++++++++-----
sql/item_jsonfunc.h | 38 +++++-----
sql/item_strfunc.cc | 164 +++++++++++++++++++++++++---------------
sql/item_strfunc.h | 156 +++++++++++++++++++++++---------------
sql/item_subselect.cc | 19 +++--
sql/item_subselect.h | 8 +-
sql/item_sum.cc | 28 +++----
sql/item_sum.h | 30 ++++----
sql/item_timefunc.cc | 46 ++++++-----
sql/item_timefunc.h | 125 +++++++++++++++++-------------
sql/item_windowfunc.cc | 6 +-
sql/item_windowfunc.h | 9 ++-
sql/item_xmlfunc.cc | 13 ++--
sql/item_xmlfunc.h | 2 +-
sql/sql_select.cc | 3 +-
sql/sql_table.cc | 11 ++-
26 files changed, 734 insertions(+), 491 deletions(-)
diff --git a/mysql-test/r/alter_table.result b/mysql-test/r/alter_table.result
index 0845459f6b6..5f5586e2c21 100644
--- a/mysql-test/r/alter_table.result
+++ b/mysql-test/r/alter_table.result
@@ -2309,5 +2309,16 @@ t1 CREATE TABLE `t1` (
) ENGINE=MyISAM DEFAULT CHARSET=latin1
drop table t1;
#
+# MDEV-11071: Assertion `thd->transaction.stmt.is_empty()' failed
+# in Locked_tables_list::unlock_locked_tables
+#
+CREATE TABLE t1 (d DATETIME DEFAULT CURRENT_TIMESTAMP, i INT) ENGINE=InnoDB;
+INSERT INTO t1 (i) VALUES (1),(1);
+LOCK TABLE t1 WRITE;
+ALTER TABLE t1 ADD UNIQUE(i);
+ERROR 23000: Duplicate entry '1' for key 'i'
+UNLOCK TABLES;
+DROP TABLE t1;
+#
# End of 10.2 tests
#
diff --git a/mysql-test/t/alter_table.test b/mysql-test/t/alter_table.test
index 63d24c0740d..0a683b48338 100644
--- a/mysql-test/t/alter_table.test
+++ b/mysql-test/t/alter_table.test
@@ -1900,6 +1900,22 @@ alter table t1 change b new_b int not null, add column b char(1), add constraint
show create table t1;
drop table t1;
+--echo #
+--echo # MDEV-11071: Assertion `thd->transaction.stmt.is_empty()' failed
+--echo # in Locked_tables_list::unlock_locked_tables
+--echo #
+
+CREATE TABLE t1 (d DATETIME DEFAULT CURRENT_TIMESTAMP, i INT) ENGINE=InnoDB;
+INSERT INTO t1 (i) VALUES (1),(1);
+LOCK TABLE t1 WRITE;
+--error ER_DUP_ENTRY
+ALTER TABLE t1 ADD UNIQUE(i);
+
+# Cleanup
+UNLOCK TABLES;
+DROP TABLE t1;
+
+
--echo #
--echo # End of 10.2 tests
--echo #
diff --git a/sql/item.h b/sql/item.h
index 8921ee76f6a..e9713730a1c 100644
--- a/sql/item.h
+++ b/sql/item.h
@@ -4210,7 +4210,7 @@ class Item_func_or_sum: public Item_result_field,
also to make printing of items inherited from Item_sum uniform.
*/
virtual const char *func_name() const= 0;
- virtual void fix_length_and_dec()= 0;
+ virtual bool fix_length_and_dec()= 0;
bool const_item() const { return const_item_cache; }
table_map used_tables() const { return used_tables_cache; }
Item* build_clone(THD *thd, MEM_ROOT *mem_root);
diff --git a/sql/item_cmpfunc.cc b/sql/item_cmpfunc.cc
index 44cc4f3cae9..46cf412e229 100644
--- a/sql/item_cmpfunc.cc
+++ b/sql/item_cmpfunc.cc
@@ -526,7 +526,7 @@ bool Item_func::setup_args_and_comparator(THD *thd, Arg_comparator *cmp)
}
-void Item_bool_rowready_func2::fix_length_and_dec()
+bool Item_bool_rowready_func2::fix_length_and_dec()
{
max_length= 1; // Function returns 0 or 1
@@ -535,8 +535,9 @@ void Item_bool_rowready_func2::fix_length_and_dec()
we have to check for out of memory conditions here
*/
if (!args[0] || !args[1])
- return;
- setup_args_and_comparator(current_thd, &cmp);
+ return FALSE;
+ bool res= setup_args_and_comparator(current_thd, &cmp);
+ return res;
}
@@ -1156,12 +1157,13 @@ int Arg_comparator::compare_e_str_json()
}
-void Item_func_truth::fix_length_and_dec()
+bool Item_func_truth::fix_length_and_dec()
{
maybe_null= 0;
null_value= 0;
decimals= 0;
max_length= 1;
+ return FALSE;
}
@@ -1778,10 +1780,11 @@ longlong Item_func_eq::val_int()
/** Same as Item_func_eq, but NULL = NULL. */
-void Item_func_equal::fix_length_and_dec()
+bool Item_func_equal::fix_length_and_dec()
{
- Item_bool_rowready_func2::fix_length_and_dec();
+ bool rc= Item_bool_rowready_func2::fix_length_and_dec();
maybe_null=null_value=0;
+ return rc;
}
longlong Item_func_equal::val_int()
@@ -1878,7 +1881,7 @@ bool Item_func_interval::fix_fields(THD *thd, Item **ref)
}
-void Item_func_interval::fix_length_and_dec()
+bool Item_func_interval::fix_length_and_dec()
{
uint rows= row->cols();
@@ -1896,10 +1899,13 @@ void Item_func_interval::fix_length_and_dec()
not_null_consts&= el->const_item() && !el->is_null();
}
- if (not_null_consts &&
- (intervals= (interval_range*) current_thd->alloc(sizeof(interval_range) *
- (rows - 1))))
+ if (not_null_consts)
{
+ intervals= (interval_range*) current_thd->alloc(sizeof(interval_range) *
+ (rows - 1));
+ if (!intervals)
+ return TRUE;
+
if (use_decimal_comparison)
{
for (uint i= 1; i < rows; i++)
@@ -1939,6 +1945,7 @@ void Item_func_interval::fix_length_and_dec()
not_null_tables_cache= row->not_null_tables();
with_sum_func= with_sum_func || row->with_sum_func;
with_field= with_field || row->with_field;
+ return FALSE;
}
@@ -2099,7 +2106,7 @@ void Item_func_between::fix_after_pullout(st_select_lex *new_parent,
eval_not_null_tables(NULL);
}
-void Item_func_between::fix_length_and_dec()
+bool Item_func_between::fix_length_and_dec()
{
THD *thd= current_thd;
max_length= 1;
@@ -2110,13 +2117,13 @@ void Item_func_between::fix_length_and_dec()
we have to check for out of memory conditions here
*/
if (!args[0] || !args[1] || !args[2])
- return;
+ return TRUE;
if (agg_cmp_type(&m_compare_type, args, 3))
- return;
+ return TRUE;
if (m_compare_type == STRING_RESULT &&
agg_arg_charsets_for_comparison(cmp_collation, args, 3))
- return;
+ return TRUE;
/*
When comparing as date/time, we need to convert non-temporal values
@@ -2141,6 +2148,7 @@ void Item_func_between::fix_length_and_dec()
m_compare_type= INT_RESULT; // Works for all types.
}
}
+ return FALSE;
}
@@ -2438,7 +2446,7 @@ void Item_func_if::cache_type_info(Item *source)
}
-void
+bool
Item_func_if::fix_length_and_dec()
{
// Let IF(cond, expr, NULL) and IF(cond, NULL, expr) inherit type from expr.
@@ -2449,15 +2457,15 @@ Item_func_if::fix_length_and_dec()
// If both arguments are NULL, make resulting type BINARY(0).
if (args[2]->type() == NULL_ITEM)
set_handler_by_field_type(MYSQL_TYPE_STRING);
- return;
+ return FALSE;
}
if (args[2]->type() == NULL_ITEM)
{
cache_type_info(args[1]);
maybe_null= true;
- return;
+ return FALSE;
}
- Item_func_case_abbreviation2::fix_length_and_dec2(args + 1);
+ return Item_func_case_abbreviation2::fix_length_and_dec2(args + 1);
}
@@ -2571,7 +2579,7 @@ void Item_func_nullif::update_used_tables()
-void
+bool
Item_func_nullif::fix_length_and_dec()
{
/*
@@ -2721,6 +2729,8 @@ Item_func_nullif::fix_length_and_dec()
m_cache= args[0]->cmp_type() == STRING_RESULT ?
new (thd->mem_root) Item_cache_str_for_nullif(thd, args[0]) :
Item_cache::get_cache(thd, args[0]);
+ if (!m_cache)
+ return TRUE;
m_cache->setup(thd, args[0]);
m_cache->store(args[0]);
m_cache->set_used_tables(args[0]->used_tables());
@@ -2734,7 +2744,8 @@ Item_func_nullif::fix_length_and_dec()
fix_char_length(args[2]->max_char_length());
maybe_null=1;
m_arg0= args[0];
- setup_args_and_comparator(thd, &cmp);
+ if (setup_args_and_comparator(thd, &cmp))
+ return TRUE;
/*
A special code for EXECUTE..PREPARE.
@@ -2774,6 +2785,7 @@ Item_func_nullif::fix_length_and_dec()
*/
if (args[0] == m_arg0)
m_arg0= NULL;
+ return FALSE;
}
@@ -3155,7 +3167,7 @@ static void change_item_tree_if_needed(THD *thd, Item **place, Item *new_value)
}
-void Item_func_case::fix_length_and_dec()
+bool Item_func_case::fix_length_and_dec()
{
m_found_types= 0;
if (else_expr_num == -1 || args[else_expr_num]->maybe_null)
@@ -3172,7 +3184,7 @@ void Item_func_case::fix_length_and_dec()
if (Item_func_case::result_type() == STRING_RESULT)
{
if (count_string_result_length(Item_func_case::field_type(), rets, nrets))
- return;
+ return TRUE;
}
else
fix_attributes(rets, nrets);
@@ -3186,7 +3198,7 @@ void Item_func_case::fix_length_and_dec()
left_cmp_type= args[0]->cmp_type();
if (!(m_found_types= collect_cmp_types(args, nwhens + 1)))
- return;
+ return TRUE;
Item *date_arg= 0;
if (m_found_types & (1U << TIME_RESULT))
@@ -3219,7 +3231,7 @@ void Item_func_case::fix_length_and_dec()
CASE utf16_item WHEN CONVERT(latin1_item USING utf16) THEN ... END
*/
if (agg_arg_charsets_for_comparison(cmp_collation, args, nwhens + 1))
- return;
+ return TRUE;
}
for (uint i= 0; i <= (uint)TIME_RESULT; i++)
@@ -3230,10 +3242,11 @@ void Item_func_case::fix_length_and_dec()
if (!(cmp_items[i]=
cmp_item::get_comparator((Item_result)i, date_arg,
cmp_collation.collation)))
- return;
+ return TRUE;
}
}
}
+ return FALSE;
}
@@ -4114,7 +4127,7 @@ static int srtcmp_in(CHARSET_INFO *cs, const String *x,const String *y)
(uchar *) y->ptr(),y->length());
}
-void Item_func_in::fix_length_and_dec()
+bool Item_func_in::fix_length_and_dec()
{
Item **arg, **arg_end;
bool const_itm= 1;
@@ -4126,7 +4139,7 @@ void Item_func_in::fix_length_and_dec()
m_compare_type= STRING_RESULT;
left_cmp_type= args[0]->cmp_type();
if (!(found_types= collect_cmp_types(args, arg_count, true)))
- return;
+ return TRUE;
for (arg= args + 1, arg_end= args + arg_count; arg != arg_end ; arg++)
{
@@ -4175,7 +4188,7 @@ void Item_func_in::fix_length_and_dec()
{
if (m_compare_type == STRING_RESULT &&
agg_arg_charsets_for_comparison(cmp_collation, args, arg_count))
- return;
+ return TRUE;
arg_types_compatible= TRUE;
if (m_compare_type == ROW_RESULT)
@@ -4186,12 +4199,14 @@ void Item_func_in::fix_length_and_dec()
if (bisection_possible)
{
array= new (thd->mem_root) in_row(thd, arg_count-1, 0);
+ if (!array)
+ return TRUE;
cmp= &((in_row*)array)->tmp;
}
else
{
if (!(cmp= new (thd->mem_root) cmp_item_row))
- return;
+ return TRUE;
cmp_items[ROW_RESULT]= cmp;
}
cmp->n= cols;
@@ -4208,6 +4223,8 @@ void Item_func_in::fix_length_and_dec()
else
cmp= ((cmp_item_row*)cmp_items[ROW_RESULT])->comparators + col;
*cmp= new (thd->mem_root) cmp_item_datetime(date_arg);
+ if (!(*cmp))
+ return TRUE;
}
}
}
@@ -4270,7 +4287,7 @@ void Item_func_in::fix_length_and_dec()
break;
}
if (!array || thd->is_fatal_error) // OOM
- return;
+ return TRUE;
uint j=0;
for (uint i=1 ; i < arg_count ; i++)
{
@@ -4295,7 +4312,7 @@ void Item_func_in::fix_length_and_dec()
date_arg= find_date_time_item(thd, args, arg_count, 0, true);
if (found_types & (1U << STRING_RESULT) &&
agg_arg_charsets_for_comparison(cmp_collation, args, arg_count))
- return;
+ return TRUE;
for (i= 0; i <= (uint) TIME_RESULT; i++)
{
if (found_types & (1U << i) && !cmp_items[i])
@@ -4303,11 +4320,12 @@ void Item_func_in::fix_length_and_dec()
if (!cmp_items[i] && !(cmp_items[i]=
cmp_item::get_comparator((Item_result)i, date_arg,
cmp_collation.collation)))
- return;
+ return TRUE;
}
}
}
max_length= 1;
+ return FALSE;
}
@@ -4576,7 +4594,8 @@ Item_cond::fix_fields(THD *thd, Item **ref)
with_window_func|= item->with_window_func;
maybe_null|= item->maybe_null;
}
- fix_length_and_dec();
+ if (fix_length_and_dec())
+ return TRUE;
fixed= 1;
return FALSE;
}
@@ -5609,16 +5628,16 @@ bool Item_func_regex::fix_fields(THD *thd, Item **ref)
return Item_bool_func::fix_fields(thd, ref);
}
-void
+bool
Item_func_regex::fix_length_and_dec()
{
- Item_bool_func::fix_length_and_dec();
-
- if (agg_arg_charsets_for_comparison(cmp_collation, args, 2))
- return;
+ if (Item_bool_func::fix_length_and_dec() ||
+ agg_arg_charsets_for_comparison(cmp_collation, args, 2))
+ return TRUE;
re.init(cmp_collation.collation, 0);
re.fix_owner(this, args[0], args[1]);
+ return FALSE;
}
@@ -5642,14 +5661,15 @@ bool Item_func_regexp_instr::fix_fields(THD *thd, Item **ref)
}
-void
+bool
Item_func_regexp_instr::fix_length_and_dec()
{
if (agg_arg_charsets_for_comparison(cmp_collation, args, 2))
- return;
+ return TRUE;
re.init(cmp_collation.collation, 0);
re.fix_owner(this, args[0], args[1]);
+ return FALSE;
}
@@ -6591,7 +6611,8 @@ bool Item_equal::fix_fields(THD *thd, Item **ref)
}
if (prev_equal_field && last_equal_field != first_equal_field)
last_equal_field->next_equal_field= first_equal_field;
- fix_length_and_dec();
+ if (fix_length_and_dec())
+ return TRUE;
fixed= 1;
return FALSE;
}
@@ -6677,11 +6698,12 @@ longlong Item_equal::val_int()
}
-void Item_equal::fix_length_and_dec()
+bool Item_equal::fix_length_and_dec()
{
Item *item= get_first(NO_PARTICULAR_TAB, NULL);
eval_item= cmp_item::get_comparator(item->cmp_type(), item,
item->collation.collation);
+ return FALSE;
}
diff --git a/sql/item_cmpfunc.h b/sql/item_cmpfunc.h
index de1b27cff1a..5efb98bc81d 100644
--- a/sql/item_cmpfunc.h
+++ b/sql/item_cmpfunc.h
@@ -200,7 +200,7 @@ class Item_bool_func :public Item_int_func
Item_bool_func(THD *thd, Item_bool_func *item) :Item_int_func(thd, item) {}
bool is_bool_type() { return true; }
virtual CHARSET_INFO *compare_collation() const { return NULL; }
- void fix_length_and_dec() { decimals=0; max_length=1; }
+ bool fix_length_and_dec() { decimals=0; max_length=1; return FALSE; }
uint decimal_precision() const { return 1; }
bool need_parentheses_in_default() { return true; }
};
@@ -216,7 +216,7 @@ class Item_func_truth : public Item_bool_func
public:
virtual bool val_bool();
virtual longlong val_int();
- virtual void fix_length_and_dec();
+ virtual bool fix_length_and_dec();
virtual void print(String *str, enum_query_type query_type);
enum precedence precedence() const { return CMP_PRECEDENCE; }
@@ -501,7 +501,7 @@ class Item_bool_rowready_func2 :public Item_bool_func2_with_rev
cond);
return this;
}
- void fix_length_and_dec();
+ bool fix_length_and_dec();
int set_cmp_func()
{
return cmp.set_cmp_func(this, tmp_arg, tmp_arg + 1, true);
@@ -711,7 +711,7 @@ class Item_func_equal :public Item_bool_rowready_func2
Item_func_equal(THD *thd, Item *a, Item *b):
Item_bool_rowready_func2(thd, a, b) {}
longlong val_int();
- void fix_length_and_dec();
+ bool fix_length_and_dec();
table_map not_null_tables() const { return 0; }
enum Functype functype() const { return EQUAL_FUNC; }
enum Functype rev_functype() const { return EQUAL_FUNC; }
@@ -878,7 +878,7 @@ class Item_func_between :public Item_func_opt_neg
enum Functype functype() const { return BETWEEN; }
const char *func_name() const { return "between"; }
enum precedence precedence() const { return BETWEEN_PRECEDENCE; }
- void fix_length_and_dec();
+ bool fix_length_and_dec();
virtual void print(String *str, enum_query_type query_type);
bool eval_not_null_tables(void *opt_arg);
void fix_after_pullout(st_select_lex *new_parent, Item **ref, bool merge);
@@ -911,10 +911,12 @@ class Item_func_strcmp :public Item_int_func
longlong val_int();
uint decimal_precision() const { return 1; }
const char *func_name() const { return "strcmp"; }
- void fix_length_and_dec()
+ bool fix_length_and_dec()
{
- agg_arg_charsets_for_comparison(cmp_collation, args, 2);
+ if (agg_arg_charsets_for_comparison(cmp_collation, args, 2))
+ return TRUE;
fix_char_length(2); // returns "1" or "0" or "-1"
+ return FALSE;
}
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
{ return get_item_copy<Item_func_strcmp>(thd, mem_root, this); }
@@ -941,7 +943,7 @@ class Item_func_interval :public Item_int_func
}
bool fix_fields(THD *, Item **);
longlong val_int();
- void fix_length_and_dec();
+ bool fix_length_and_dec();
const char *func_name() const { return "interval"; }
uint decimal_precision() const { return 2; }
void print(String *str, enum_query_type query_type)
@@ -966,10 +968,11 @@ class Item_func_coalesce :public Item_func_hybrid_field_type
String *str_op(String *);
my_decimal *decimal_op(my_decimal *);
bool date_op(MYSQL_TIME *ltime,uint fuzzydate);
- void fix_length_and_dec()
+ bool fix_length_and_dec()
{
set_handler_by_field_type(agg_field_type(args, arg_count, true));
fix_attributes(args, arg_count);
+ return FALSE;
}
const char *func_name() const { return "coalesce"; }
table_map not_null_tables() const { return 0; }
@@ -986,10 +989,11 @@ class Item_func_coalesce :public Item_func_hybrid_field_type
class Item_func_case_abbreviation2 :public Item_func_hybrid_field_type
{
protected:
- void fix_length_and_dec2(Item **items)
+ bool fix_length_and_dec2(Item **items)
{
set_handler_by_field_type(agg_field_type(items, 2, true));
fix_attributes(items, 2);
+ return FALSE;
}
uint decimal_precision2(Item **args) const;
public:
@@ -1010,10 +1014,12 @@ class Item_func_ifnull :public Item_func_case_abbreviation2
String *str_op(String *str);
my_decimal *decimal_op(my_decimal *);
bool date_op(MYSQL_TIME *ltime,uint fuzzydate);
- void fix_length_and_dec()
+ bool fix_length_and_dec()
{
- Item_func_case_abbreviation2::fix_length_and_dec2(args);
+ if (Item_func_case_abbreviation2::fix_length_and_dec2(args))
+ return TRUE;
maybe_null= args[1]->maybe_null;
+ return FALSE;
}
const char *func_name() const { return "ifnull"; }
Field *create_field_for_create_select(TABLE *table)
@@ -1041,7 +1047,7 @@ class Item_func_if :public Item_func_case_abbreviation2
my_decimal *decimal_op(my_decimal *);
String *str_op(String *);
bool fix_fields(THD *, Item **);
- void fix_length_and_dec();
+ bool fix_length_and_dec();
uint decimal_precision() const
{
return Item_func_case_abbreviation2::decimal_precision2(args + 1);
@@ -1108,7 +1114,7 @@ class Item_func_nullif :public Item_func_hybrid_field_type
longlong int_op();
String *str_op(String *str);
my_decimal *decimal_op(my_decimal *);
- void fix_length_and_dec();
+ bool fix_length_and_dec();
bool walk(Item_processor processor, bool walk_subquery, void *arg);
uint decimal_precision() const { return args[2]->decimal_precision(); }
const char *func_name() const { return "nullif"; }
@@ -1570,7 +1576,7 @@ class Item_func_case :public Item_func_hybrid_field_type
my_decimal *decimal_op(my_decimal *);
bool date_op(MYSQL_TIME *ltime, uint fuzzydate);
bool fix_fields(THD *thd, Item **ref);
- void fix_length_and_dec();
+ bool fix_length_and_dec();
uint decimal_precision() const;
table_map not_null_tables() const { return 0; }
const char *func_name() const { return "case"; }
@@ -1648,7 +1654,7 @@ class Item_func_in :public Item_func_opt_neg
}
longlong val_int();
bool fix_fields(THD *, Item **);
- void fix_length_and_dec();
+ bool fix_length_and_dec();
void cleanup()
{
uint i;
@@ -1718,7 +1724,7 @@ class cmp_item_row :public cmp_item
int compare(cmp_item *arg);
cmp_item *make_same();
void store_value_by_template(THD *thd, cmp_item *tmpl, Item *);
- friend void Item_func_in::fix_length_and_dec();
+ friend bool Item_func_in::fix_length_and_dec();
cmp_item *get_comparator(uint i) { return comparators[i]; }
};
@@ -1731,7 +1737,7 @@ class in_row :public in_vector
~in_row();
void set(uint pos,Item *item);
uchar *get_value(Item *item);
- friend void Item_func_in::fix_length_and_dec();
+ friend bool Item_func_in::fix_length_and_dec();
Item_result result_type() { return ROW_RESULT; }
cmp_item *get_cmp_item() { return &tmp; }
};
@@ -1763,7 +1769,11 @@ class Item_func_null_predicate :public Item_bool_func
}
CHARSET_INFO *compare_collation() const
{ return args[0]->collation.collation; }
- void fix_length_and_dec() { decimals=0; max_length=1; maybe_null=0; }
+ bool fix_length_and_dec()
+ {
+ decimals=0; max_length=1; maybe_null=0;
+ return FALSE;
+ }
bool count_sargable_conds(void *arg);
};
@@ -1987,10 +1997,10 @@ class Item_func_like :public Item_bool_func2
const char *func_name() const { return "like"; }
enum precedence precedence() const { return CMP_PRECEDENCE; }
bool fix_fields(THD *thd, Item **ref);
- void fix_length_and_dec()
+ bool fix_length_and_dec()
{
max_length= 1;
- agg_arg_charsets_for_comparison(cmp_collation, args, 2);
+ return agg_arg_charsets_for_comparison(cmp_collation, args, 2);
}
void cleanup();
@@ -2111,7 +2121,7 @@ class Item_func_regex :public Item_bool_func
}
longlong val_int();
bool fix_fields(THD *thd, Item **ref);
- void fix_length_and_dec();
+ bool fix_length_and_dec();
const char *func_name() const { return "regexp"; }
enum precedence precedence() const { return CMP_PRECEDENCE; }
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
@@ -2149,7 +2159,7 @@ class Item_func_regexp_instr :public Item_int_func
}
longlong val_int();
bool fix_fields(THD *thd, Item **ref);
- void fix_length_and_dec();
+ bool fix_length_and_dec();
const char *func_name() const { return "regexp_instr"; }
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
{ return get_item_copy<Item_func_regexp_instr>(thd, mem_root, this); }
@@ -2385,7 +2395,7 @@ class Item_equal: public Item_bool_func
longlong val_int();
const char *func_name() const { return "multiple equal"; }
void sort(Item_field_cmpfunc compare, void *arg);
- void fix_length_and_dec();
+ bool fix_length_and_dec();
bool fix_fields(THD *thd, Item **ref);
void cleanup()
{
diff --git a/sql/item_func.cc b/sql/item_func.cc
index 0c239b54f30..255923d98dd 100644
--- a/sql/item_func.cc
+++ b/sql/item_func.cc
@@ -235,8 +235,7 @@ Item_func::fix_fields(THD *thd, Item **ref)
with_subselect|= item->has_subquery();
}
}
- fix_length_and_dec();
- if (thd->is_error()) // An error inside fix_length_and_dec occurred
+ if (fix_length_and_dec())
return TRUE;
fixed= 1;
return FALSE;
@@ -731,10 +730,12 @@ String *Item_int_func::val_str(String *str)
}
-void Item_func_connection_id::fix_length_and_dec()
+bool Item_func_connection_id::fix_length_and_dec()
{
- Item_int_func::fix_length_and_dec();
+ if (Item_int_func::fix_length_and_dec())
+ return TRUE;
max_length= 10;
+ return FALSE;
}
@@ -753,7 +754,7 @@ bool Item_func_connection_id::fix_fields(THD *thd, Item **ref)
function of two arguments.
*/
-void Item_num_op::fix_length_and_dec(void)
+bool Item_num_op::fix_length_and_dec(void)
{
DBUG_ENTER("Item_num_op::fix_length_and_dec");
DBUG_PRINT("info", ("name %s", func_name()));
@@ -789,7 +790,7 @@ void Item_num_op::fix_length_and_dec(void)
result_type() == DECIMAL_RESULT ? "DECIMAL_RESULT" :
result_type() == INT_RESULT ? "INT_RESULT" :
"--ILLEGAL!!!--")));
- DBUG_VOID_RETURN;
+ DBUG_RETURN(FALSE);
}
@@ -799,7 +800,7 @@ void Item_num_op::fix_length_and_dec(void)
type depends only on the first argument)
*/
-void Item_func_num1::fix_length_and_dec()
+bool Item_func_num1::fix_length_and_dec()
{
DBUG_ENTER("Item_func_num1::fix_length_and_dec");
DBUG_PRINT("info", ("name %s", func_name()));
@@ -830,7 +831,7 @@ void Item_func_num1::fix_length_and_dec()
result_type() == DECIMAL_RESULT ? "DECIMAL_RESULT" :
result_type() == INT_RESULT ? "INT_RESULT" :
"--ILLEGAL!!!--")));
- DBUG_VOID_RETURN;
+ DBUG_RETURN(FALSE);
}
@@ -1415,12 +1416,14 @@ void Item_func_additive_op::result_precision()
subtraction of UNSIGNED BIGINT to return negative values.
*/
-void Item_func_minus::fix_length_and_dec()
+bool Item_func_minus::fix_length_and_dec()
{
- Item_num_op::fix_length_and_dec();
+ if (Item_num_op::fix_length_and_dec())
+ return TRUE;
if (unsigned_flag &&
(current_thd->variables.sql_mode & MODE_NO_UNSIGNED_SUBTRACTION))
unsigned_flag=0;
+ return FALSE;
}
@@ -1718,11 +1721,12 @@ void Item_func_div::result_precision()
}
-void Item_func_div::fix_length_and_dec()
+bool Item_func_div::fix_length_and_dec()
{
DBUG_ENTER("Item_func_div::fix_length_and_dec");
prec_increment= current_thd->variables.div_precincrement;
- Item_num_op::fix_length_and_dec();
+ if (Item_num_op::fix_length_and_dec())
+ DBUG_RETURN(TRUE);
switch (Item_func_div::result_type()) {
case REAL_RESULT:
{
@@ -1753,7 +1757,7 @@ void Item_func_div::fix_length_and_dec()
DBUG_ASSERT(0);
}
maybe_null= 1; // devision by zero
- DBUG_VOID_RETURN;
+ DBUG_RETURN(FALSE);
}
@@ -1829,7 +1833,7 @@ longlong Item_func_int_div::val_int()
}
-void Item_func_int_div::fix_length_and_dec()
+bool Item_func_int_div::fix_length_and_dec()
{
Item_result argtype= args[0]->result_type();
/* use precision ony for the data type it is applicable for and valid */
@@ -1840,6 +1844,7 @@ void Item_func_int_div::fix_length_and_dec()
MY_INT64_NUM_DECIMAL_DIGITS : char_length);
maybe_null=1;
unsigned_flag=args[0]->unsigned_flag | args[1]->unsigned_flag;
+ return false;
}
@@ -1923,11 +1928,13 @@ void Item_func_mod::result_precision()
}
-void Item_func_mod::fix_length_and_dec()
+bool Item_func_mod::fix_length_and_dec()
{
- Item_num_op::fix_length_and_dec();
+ if (Item_num_op::fix_length_and_dec())
+ return true;
maybe_null= 1;
unsigned_flag= args[0]->unsigned_flag;
+ return false;
}
@@ -1974,10 +1981,11 @@ my_decimal *Item_func_neg::decimal_op(my_decimal *decimal_value)
}
-void Item_func_neg::fix_length_and_dec()
+bool Item_func_neg::fix_length_and_dec()
{
DBUG_ENTER("Item_func_neg::fix_length_and_dec");
- Item_func_num1::fix_length_and_dec();
+ if (Item_func_num1::fix_length_and_dec())
+ DBUG_RETURN(TRUE);
/* 1 add because sign can appear */
max_length= args[0]->max_length + 1;
@@ -2003,7 +2011,7 @@ void Item_func_neg::fix_length_and_dec()
}
}
unsigned_flag= 0;
- DBUG_VOID_RETURN;
+ DBUG_RETURN(FALSE);
}
@@ -2043,10 +2051,12 @@ my_decimal *Item_func_abs::decimal_op(my_decimal *decimal_value)
}
-void Item_func_abs::fix_length_and_dec()
+bool Item_func_abs::fix_length_and_dec()
{
- Item_func_num1::fix_length_and_dec();
+ if (Item_func_num1::fix_length_and_dec())
+ return TRUE;
unsigned_flag= args[0]->unsigned_flag;
+ return FALSE;
}
@@ -2278,7 +2288,7 @@ longlong Item_func_bit_neg::val_int()
// Conversion functions
-void Item_func_int_val::fix_length_and_dec()
+bool Item_func_int_val::fix_length_and_dec()
{
DBUG_ENTER("Item_func_int_val::fix_length_and_dec");
DBUG_PRINT("info", ("name %s", func_name()));
@@ -2326,7 +2336,7 @@ void Item_func_int_val::fix_length_and_dec()
result_type() == INT_RESULT ? "INT_RESULT" :
"--ILLEGAL!!!--")));
- DBUG_VOID_RETURN;
+ DBUG_RETURN(FALSE);
}
@@ -2424,7 +2434,7 @@ my_decimal *Item_func_floor::decimal_op(my_decimal *decimal_value)
}
-void Item_func_round::fix_length_and_dec()
+bool Item_func_round::fix_length_and_dec()
{
int decimals_to_set;
longlong val1;
@@ -2442,12 +2452,12 @@ void Item_func_round::fix_length_and_dec()
}
else
set_handler_by_result_type(REAL_RESULT);
- return;
+ return FALSE;
}
val1= args[1]->val_int();
if ((null_value= args[1]->null_value))
- return;
+ return FALSE;
val1_unsigned= args[1]->unsigned_flag;
if (val1 < 0)
@@ -2460,7 +2470,7 @@ void Item_func_round::fix_length_and_dec()
decimals= MY_MIN(decimals_to_set, NOT_FIXED_DEC);
max_length= float_length(decimals);
set_handler_by_result_type(REAL_RESULT);
- return;
+ return FALSE;
}
switch (args[0]->result_type()) {
@@ -2501,6 +2511,7 @@ void Item_func_round::fix_length_and_dec()
case TIME_RESULT:
DBUG_ASSERT(0); /* This result type isn't handled */
}
+ return FALSE;
}
double my_double_round(double value, longlong dec, bool dec_unsigned,
@@ -2725,7 +2736,7 @@ double Item_func_units::val_real()
}
-void Item_func_min_max::fix_length_and_dec()
+bool Item_func_min_max::fix_length_and_dec()
{
uint unsigned_count= 0;
int max_int_part=0;
@@ -2836,6 +2847,7 @@ void Item_func_min_max::fix_length_and_dec()
set_handler_by_field_type(MYSQL_TYPE_DOUBLE);
break;
}
+ return FALSE;
}
@@ -3086,10 +3098,10 @@ longlong Item_func_coercibility::val_int()
}
-void Item_func_locate::fix_length_and_dec()
+bool Item_func_locate::fix_length_and_dec()
{
max_length= MY_INT32_NUM_DECIMAL_DIGITS;
- agg_arg_charsets_for_comparison(cmp_collation, args, 2);
+ return agg_arg_charsets_for_comparison(cmp_collation, args, 2);
}
@@ -3206,14 +3218,15 @@ longlong Item_func_field::val_int()
}
-void Item_func_field::fix_length_and_dec()
+bool Item_func_field::fix_length_and_dec()
{
maybe_null=0; max_length=3;
cmp_type= args[0]->result_type();
for (uint i=1; i < arg_count ; i++)
cmp_type= item_cmp_type(cmp_type, args[i]->result_type());
if (cmp_type == STRING_RESULT)
- agg_arg_charsets_for_comparison(cmp_collation, args, arg_count);
+ return agg_arg_charsets_for_comparison(cmp_collation, args, arg_count);
+ return FALSE;
}
@@ -3260,7 +3273,7 @@ longlong Item_func_ord::val_int()
/* Returns number of found type >= 1 or 0 if not found */
/* This optimizes searching in enums to bit testing! */
-void Item_func_find_in_set::fix_length_and_dec()
+bool Item_func_find_in_set::fix_length_and_dec()
{
decimals=0;
max_length=3; // 1-999
@@ -3282,7 +3295,7 @@ void Item_func_find_in_set::fix_length_and_dec()
}
}
}
- agg_arg_charsets_for_comparison(cmp_collation, args, 2);
+ return agg_arg_charsets_for_comparison(cmp_collation, args, 2);
}
static const char separator=',';
@@ -3487,7 +3500,8 @@ udf_handler::fix_fields(THD *thd, Item_func_or_sum *func,
DBUG_RETURN(TRUE);
}
}
- func->fix_length_and_dec();
+ if (func->fix_length_and_dec())
+ DBUG_RETURN(TRUE);
initid.max_length=func->max_length;
initid.maybe_null=func->maybe_null;
initid.const_item=func->const_item_cache;
@@ -3825,13 +3839,13 @@ String *Item_func_udf_decimal::val_str(String *str)
/* Default max_length is max argument length */
-void Item_func_udf_str::fix_length_and_dec()
+bool Item_func_udf_str::fix_length_and_dec()
{
DBUG_ENTER("Item_func_udf_str::fix_length_and_dec");
max_length=0;
for (uint i = 0; i < arg_count; i++)
set_if_bigger(max_length,args[i]->max_length);
- DBUG_VOID_RETURN;
+ DBUG_RETURN(FALSE);
}
String *Item_func_udf_str::val_str(String *str)
@@ -4718,7 +4732,7 @@ bool Item_func_set_user_var::fix_fields(THD *thd, Item **ref)
}
-void
+bool
Item_func_set_user_var::fix_length_and_dec()
{
maybe_null=args[0]->maybe_null;
@@ -4732,6 +4746,7 @@ Item_func_set_user_var::fix_length_and_dec()
args[0]->collation.collation);
}
unsigned_flag= args[0]->unsigned_flag;
+ return FALSE;
}
@@ -5570,7 +5585,7 @@ get_var_with_binlog(THD *thd, enum_sql_command sql_command,
return 1;
}
-void Item_func_get_user_var::fix_length_and_dec()
+bool Item_func_get_user_var::fix_length_and_dec()
{
THD *thd=current_thd;
int error;
@@ -5620,6 +5635,7 @@ void Item_func_get_user_var::fix_length_and_dec()
set_handler_by_field_type(MYSQL_TYPE_LONG_BLOB);
max_length= MAX_BLOB_WIDTH;
}
+ return false;
}
@@ -5762,7 +5778,7 @@ void Item_func_get_system_var::update_null_value()
}
-void Item_func_get_system_var::fix_length_and_dec()
+bool Item_func_get_system_var::fix_length_and_dec()
{
char *cptr;
maybe_null= TRUE;
@@ -5774,7 +5790,7 @@ void Item_func_get_system_var::fix_length_and_dec()
{
my_error(ER_INCORRECT_GLOBAL_LOCAL_VAR, MYF(0),
var->name.str, var_type == OPT_GLOBAL ? "SESSION" : "GLOBAL");
- return;
+ return TRUE;
}
/* As there was no local variable, return the global value */
var_type= OPT_GLOBAL;
@@ -5838,6 +5854,7 @@ void Item_func_get_system_var::fix_length_and_dec()
my_error(ER_VAR_CANT_BE_READ, MYF(0), var->name.str);
break;
}
+ return FALSE;
}
@@ -6614,7 +6631,7 @@ bool Item_func_sp::is_expensive()
@note called from Item::fix_fields.
*/
-void Item_func_sp::fix_length_and_dec()
+bool Item_func_sp::fix_length_and_dec()
{
DBUG_ENTER("Item_func_sp::fix_length_and_dec");
@@ -6622,7 +6639,7 @@ void Item_func_sp::fix_length_and_dec()
Type_std_attributes::set(sp_result_field);
maybe_null= 1;
- DBUG_VOID_RETURN;
+ DBUG_RETURN(FALSE);
}
@@ -6961,11 +6978,12 @@ my_decimal *Item_func_last_value::val_decimal(my_decimal *decimal_value)
}
-void Item_func_last_value::fix_length_and_dec()
+bool Item_func_last_value::fix_length_and_dec()
{
last_value= args[arg_count -1];
Type_std_attributes::set(last_value);
maybe_null= last_value->maybe_null;
+ return FALSE;
}
diff --git a/sql/item_func.h b/sql/item_func.h
index 689bfb84034..0312b21328c 100644
--- a/sql/item_func.h
+++ b/sql/item_func.h
@@ -391,8 +391,8 @@ class Item_real_func :public Item_func
{ DBUG_ASSERT(fixed == 1); return (longlong) rint(val_real()); }
enum Item_result result_type () const { return REAL_RESULT; }
enum_field_types field_type() const { return MYSQL_TYPE_DOUBLE; }
- void fix_length_and_dec()
- { decimals= NOT_FIXED_DEC; max_length= float_length(decimals); }
+ bool fix_length_and_dec()
+ { decimals= NOT_FIXED_DEC; max_length= float_length(decimals); return FALSE; }
};
@@ -569,7 +569,7 @@ class Item_func_num1: public Item_func_numhybrid
public:
Item_func_num1(THD *thd, Item *a): Item_func_numhybrid(thd, a) {}
Item_func_num1(THD *thd, Item *a, Item *b): Item_func_numhybrid(thd, a, b) {}
- void fix_length_and_dec();
+ bool fix_length_and_dec();
};
@@ -584,7 +584,7 @@ class Item_num_op :public Item_func_numhybrid
{
print_op(str, query_type);
}
- void fix_length_and_dec();
+ bool fix_length_and_dec();
bool need_parentheses_in_default() { return true; }
};
@@ -611,7 +611,7 @@ class Item_int_func :public Item_func
String *val_str(String*str);
enum Item_result result_type () const { return INT_RESULT; }
enum_field_types field_type() const { return MYSQL_TYPE_LONGLONG; }
- void fix_length_and_dec() {}
+ bool fix_length_and_dec() { return FALSE; }
};
@@ -622,7 +622,7 @@ class Item_func_connection_id :public Item_int_func
public:
Item_func_connection_id(THD *thd): Item_int_func(thd) {}
const char *func_name() const { return "connection_id"; }
- void fix_length_and_dec();
+ bool fix_length_and_dec();
bool fix_fields(THD *thd, Item **ref);
longlong val_int() { DBUG_ASSERT(fixed == 1); return value; }
bool check_vcol_func_processor(void *arg)
@@ -648,7 +648,7 @@ class Item_func_signed :public Item_int_func
null_value= args[0]->null_value;
return value;
}
- void fix_length_and_dec()
+ bool fix_length_and_dec()
{
uint32 char_length= MY_MIN(args[0]->max_char_length(),
MY_INT64_NUM_DECIMAL_DIGITS);
@@ -659,6 +659,7 @@ class Item_func_signed :public Item_int_func
*/
set_if_bigger(char_length, 1U + (unsigned_flag ? 0 : 1));
fix_char_length(char_length);
+ return FALSE;
}
virtual void print(String *str, enum_query_type query_type);
uint decimal_precision() const { return args[0]->decimal_precision(); }
@@ -705,7 +706,7 @@ class Item_decimal_typecast :public Item_func
my_decimal *val_decimal(my_decimal*);
enum Item_result result_type () const { return DECIMAL_RESULT; }
enum_field_types field_type() const { return MYSQL_TYPE_NEWDECIMAL; }
- void fix_length_and_dec() {}
+ bool fix_length_and_dec() { return FALSE; }
const char *func_name() const { return "decimal_typecast"; }
virtual void print(String *str, enum_query_type query_type);
bool need_parentheses_in_default() { return true; }
@@ -725,7 +726,7 @@ class Item_double_typecast :public Item_real_func
}
double val_real();
enum_field_types field_type() const { return MYSQL_TYPE_DOUBLE; }
- void fix_length_and_dec() { maybe_null= 1; }
+ bool fix_length_and_dec() { maybe_null= 1; return FALSE; }
const char *func_name() const { return "double_typecast"; }
virtual void print(String *str, enum_query_type query_type);
bool need_parentheses_in_default() { return true; }
@@ -769,7 +770,7 @@ class Item_func_minus :public Item_func_additive_op
longlong int_op();
double real_op();
my_decimal *decimal_op(my_decimal *);
- void fix_length_and_dec();
+ bool fix_length_and_dec();
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
{ return get_item_copy<Item_func_minus>(thd, mem_root, this); }
};
@@ -803,7 +804,7 @@ class Item_func_div :public Item_num_op
my_decimal *decimal_op(my_decimal *);
const char *func_name() const { return "/"; }
enum precedence precedence() const { return MUL_PRECEDENCE; }
- void fix_length_and_dec();
+ bool fix_length_and_dec();
void result_precision();
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
{ return get_item_copy<Item_func_div>(thd, mem_root, this); }
@@ -818,7 +819,7 @@ class Item_func_int_div :public Item_int_func
longlong val_int();
const char *func_name() const { return "DIV"; }
enum precedence precedence() const { return MUL_PRECEDENCE; }
- void fix_length_and_dec();
+ bool fix_length_and_dec();
void print(String *str, enum_query_type query_type)
{
print_op(str, query_type);
@@ -842,7 +843,7 @@ class Item_func_mod :public Item_num_op
const char *func_name() const { return "%"; }
enum precedence precedence() const { return MUL_PRECEDENCE; }
void result_precision();
- void fix_length_and_dec();
+ bool fix_length_and_dec();
bool check_partition_func_processor(void *int_arg) {return FALSE;}
bool check_vcol_func_processor(void *arg) { return FALSE;}
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
@@ -865,7 +866,7 @@ class Item_func_neg :public Item_func_num1
str->append(func_name());
args[0]->print_parenthesised(str, query_type, precedence());
}
- void fix_length_and_dec();
+ bool fix_length_and_dec();
uint decimal_precision() const { return args[0]->decimal_precision(); }
bool check_partition_func_processor(void *int_arg) {return FALSE;}
bool check_vcol_func_processor(void *arg) { return FALSE;}
@@ -883,7 +884,7 @@ class Item_func_abs :public Item_func_num1
longlong int_op();
my_decimal *decimal_op(my_decimal *);
const char *func_name() const { return "abs"; }
- void fix_length_and_dec();
+ bool fix_length_and_dec();
bool check_partition_func_processor(void *int_arg) {return FALSE;}
bool check_vcol_func_processor(void *arg) { return FALSE;}
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
@@ -897,10 +898,11 @@ class Item_dec_func :public Item_real_func
public:
Item_dec_func(THD *thd, Item *a): Item_real_func(thd, a) {}
Item_dec_func(THD *thd, Item *a, Item *b): Item_real_func(thd, a, b) {}
- void fix_length_and_dec()
+ bool fix_length_and_dec()
{
decimals=NOT_FIXED_DEC; max_length=float_length(decimals);
maybe_null=1;
+ return FALSE;
}
};
@@ -1058,7 +1060,7 @@ class Item_func_int_val :public Item_func_num1
{
public:
Item_func_int_val(THD *thd, Item *a): Item_func_num1(thd, a) {}
- void fix_length_and_dec();
+ bool fix_length_and_dec();
};
@@ -1103,7 +1105,7 @@ class Item_func_round :public Item_func_num1
double real_op();
longlong int_op();
my_decimal *decimal_op(my_decimal *);
- void fix_length_and_dec();
+ bool fix_length_and_dec();
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
{ return get_item_copy<Item_func_round>(thd, mem_root, this); }
};
@@ -1155,8 +1157,8 @@ class Item_func_units :public Item_real_func
Item_real_func(thd, a), name(name_arg), mul(mul_arg), add(add_arg) {}
double val_real();
const char *func_name() const { return name; }
- void fix_length_and_dec()
- { decimals= NOT_FIXED_DEC; max_length= float_length(decimals); }
+ bool fix_length_and_dec()
+ { decimals= NOT_FIXED_DEC; max_length= float_length(decimals); return FALSE; }
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
{ return get_item_copy<Item_func_units>(thd, mem_root, this); }
};
@@ -1186,7 +1188,7 @@ class Item_func_min_max :public Item_hybrid_func
String *val_str(String *);
my_decimal *val_decimal(my_decimal *);
bool get_date(MYSQL_TIME *res, ulonglong fuzzy_date);
- void fix_length_and_dec();
+ bool fix_length_and_dec();
};
class Item_func_min :public Item_func_min_max
@@ -1229,13 +1231,14 @@ class Item_func_rollup_const :public Item_func
bool const_item() const { return 0; }
Item_result result_type() const { return args[0]->result_type(); }
enum_field_types field_type() const { return args[0]->field_type(); }
- void fix_length_and_dec()
+ bool fix_length_and_dec()
{
collation= args[0]->collation;
max_length= args[0]->max_length;
decimals=args[0]->decimals;
/* The item could be a NULL constant. */
null_value= args[0]->is_null();
+ return FALSE;
}
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
{ return get_item_copy<Item_func_rollup_const>(thd, mem_root, this); }
@@ -1249,7 +1252,7 @@ class Item_func_length :public Item_int_func
Item_func_length(THD *thd, Item *a): Item_int_func(thd, a) {}
longlong val_int();
const char *func_name() const { return "length"; }
- void fix_length_and_dec() { max_length=10; }
+ bool fix_length_and_dec() { max_length=10; return FALSE; }
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
{ return get_item_copy<Item_func_length>(thd, mem_root, this); }
};
@@ -1272,7 +1275,7 @@ class Item_func_char_length :public Item_int_func
Item_func_char_length(THD *thd, Item *a): Item_int_func(thd, a) {}
longlong val_int();
const char *func_name() const { return "char_length"; }
- void fix_length_and_dec() { max_length=10; }
+ bool fix_length_and_dec() { max_length=10; return FALSE; }
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
{ return get_item_copy<Item_func_char_length>(thd, mem_root, this); }
};
@@ -1283,7 +1286,7 @@ class Item_func_coercibility :public Item_int_func
Item_func_coercibility(THD *thd, Item *a): Item_int_func(thd, a) {}
longlong val_int();
const char *func_name() const { return "coercibility"; }
- void fix_length_and_dec() { max_length=10; maybe_null= 0; }
+ bool fix_length_and_dec() { max_length=10; maybe_null= 0; return FALSE; }
bool eval_not_null_tables(void *)
{
not_null_tables_cache= 0;
@@ -1305,7 +1308,7 @@ class Item_func_locate :public Item_int_func
Item_func_locate(THD *thd, Item *a, Item *b, Item *c): Item_int_func(thd, a, b, c) {}
const char *func_name() const { return "locate"; }
longlong val_int();
- void fix_length_and_dec();
+ bool fix_length_and_dec();
virtual void print(String *str, enum_query_type query_type);
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
{ return get_item_copy<Item_func_locate>(thd, mem_root, this); }
@@ -1321,7 +1324,7 @@ class Item_func_field :public Item_int_func
Item_func_field(THD *thd, List<Item> &list): Item_int_func(thd, list) {}
longlong val_int();
const char *func_name() const { return "field"; }
- void fix_length_and_dec();
+ bool fix_length_and_dec();
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
{ return get_item_copy<Item_func_field>(thd, mem_root, this); }
};
@@ -1334,7 +1337,7 @@ class Item_func_ascii :public Item_int_func
Item_func_ascii(THD *thd, Item *a): Item_int_func(thd, a) {}
longlong val_int();
const char *func_name() const { return "ascii"; }
- void fix_length_and_dec() { max_length=3; }
+ bool fix_length_and_dec() { max_length=3; return FALSE; }
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
{ return get_item_copy<Item_func_ascii>(thd, mem_root, this); }
};
@@ -1361,7 +1364,7 @@ class Item_func_find_in_set :public Item_int_func
Item_int_func(thd, a, b), enum_value(0) {}
longlong val_int();
const char *func_name() const { return "find_in_set"; }
- void fix_length_and_dec();
+ bool fix_length_and_dec();
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
{ return get_item_copy<Item_func_find_in_set>(thd, mem_root, this); }
};
@@ -1373,7 +1376,7 @@ class Item_func_bit: public Item_int_func
public:
Item_func_bit(THD *thd, Item *a, Item *b): Item_int_func(thd, a, b) {}
Item_func_bit(THD *thd, Item *a): Item_int_func(thd, a) {}
- void fix_length_and_dec() { unsigned_flag= 1; }
+ bool fix_length_and_dec() { unsigned_flag= 1; return FALSE; }
virtual inline void print(String *str, enum_query_type query_type)
{
@@ -1410,7 +1413,7 @@ class Item_func_bit_count :public Item_int_func
Item_func_bit_count(THD *thd, Item *a): Item_int_func(thd, a) {}
longlong val_int();
const char *func_name() const { return "bit_count"; }
- void fix_length_and_dec() { max_length=2; }
+ bool fix_length_and_dec() { max_length=2; return FALSE; }
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
{ return get_item_copy<Item_func_bit_count>(thd, mem_root, this); }
};
@@ -1461,12 +1464,13 @@ class Item_func_last_insert_id :public Item_int_func
Item_func_last_insert_id(THD *thd, Item *a): Item_int_func(thd, a) {}
longlong val_int();
const char *func_name() const { return "last_insert_id"; }
- void fix_length_and_dec()
+ bool fix_length_and_dec()
{
unsigned_flag= TRUE;
if (arg_count)
max_length= args[0]->max_length;
unsigned_flag=1;
+ return FALSE;
}
bool fix_fields(THD *thd, Item **ref);
bool check_vcol_func_processor(void *arg)
@@ -1486,7 +1490,7 @@ class Item_func_benchmark :public Item_int_func
{}
longlong val_int();
const char *func_name() const { return "benchmark"; }
- void fix_length_and_dec() { max_length=1; maybe_null=0; }
+ bool fix_length_and_dec() { max_length=1; maybe_null=0; return FALSE; }
virtual void print(String *str, enum_query_type query_type);
bool check_vcol_func_processor(void *arg)
{
@@ -1644,7 +1648,7 @@ class Item_func_udf_float :public Item_udf_func
double val_real();
String *val_str(String *str);
enum_field_types field_type() const { return MYSQL_TYPE_DOUBLE; }
- void fix_length_and_dec() { fix_num_length_and_dec(); }
+ bool fix_length_and_dec() { fix_num_length_and_dec(); return FALSE; }
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
{ return get_item_copy<Item_func_udf_float>(thd, mem_root, this); }
};
@@ -1663,7 +1667,7 @@ class Item_func_udf_int :public Item_udf_func
String *val_str(String *str);
enum Item_result result_type () const { return INT_RESULT; }
enum_field_types field_type() const { return MYSQL_TYPE_LONGLONG; }
- void fix_length_and_dec() { decimals= 0; max_length= 21; }
+ bool fix_length_and_dec() { decimals= 0; max_length= 21; return FALSE; }
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
{ return get_item_copy<Item_func_udf_int>(thd, mem_root, this); }
};
@@ -1682,7 +1686,7 @@ class Item_func_udf_decimal :public Item_udf_func
String *val_str(String *str);
enum Item_result result_type () const { return DECIMAL_RESULT; }
enum_field_types field_type() const { return MYSQL_TYPE_NEWDECIMAL; }
- void fix_length_and_dec() { fix_num_length_and_dec(); }
+ bool fix_length_and_dec() { fix_num_length_and_dec(); return FALSE; }
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
{ return get_item_copy<Item_func_udf_decimal>(thd, mem_root, this); }
};
@@ -1722,7 +1726,7 @@ class Item_func_udf_str :public Item_udf_func
}
enum Item_result result_type () const { return STRING_RESULT; }
enum_field_types field_type() const { return string_field_type(); }
- void fix_length_and_dec();
+ bool fix_length_and_dec();
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
{ return get_item_copy<Item_func_udf_str>(thd, mem_root, this); }
};
@@ -1774,7 +1778,7 @@ class Item_func_udf_str :public Item_func
double val_real() { DBUG_ASSERT(fixed == 1); null_value= 1; return 0.0; }
longlong val_int() { DBUG_ASSERT(fixed == 1); null_value=1; return 0; }
enum Item_result result_type () const { return STRING_RESULT; }
- void fix_length_and_dec() { maybe_null=1; max_length=0; }
+ bool fix_length_and_dec() { maybe_null=1; max_length=0; return FALSE; }
};
#endif /* HAVE_DLOPEN */
@@ -1789,7 +1793,7 @@ class Item_func_get_lock :public Item_int_func
Item_func_get_lock(THD *thd, Item *a, Item *b) :Item_int_func(thd, a, b) {}
longlong val_int();
const char *func_name() const { return "get_lock"; }
- void fix_length_and_dec() { max_length=1; maybe_null=1;}
+ bool fix_length_and_dec() { max_length=1; maybe_null=1; return FALSE; }
table_map used_tables() const
{
return used_tables_cache | RAND_TABLE_BIT;
@@ -1811,7 +1815,7 @@ class Item_func_release_lock :public Item_int_func
Item_func_release_lock(THD *thd, Item *a): Item_int_func(thd, a) {}
longlong val_int();
const char *func_name() const { return "release_lock"; }
- void fix_length_and_dec() { max_length= 1; maybe_null= 1;}
+ bool fix_length_and_dec() { max_length= 1; maybe_null= 1; return FALSE; }
table_map used_tables() const
{
return used_tables_cache | RAND_TABLE_BIT;
@@ -1839,7 +1843,7 @@ class Item_master_pos_wait :public Item_int_func
Item_int_func(thd, a, b, c, d) {}
longlong val_int();
const char *func_name() const { return "master_pos_wait"; }
- void fix_length_and_dec() { max_length=21; maybe_null=1;}
+ bool fix_length_and_dec() { max_length=21; maybe_null=1; return FALSE; }
bool check_vcol_func_processor(void *arg)
{
return mark_unsupported_function(func_name(), "()", arg, VCOL_IMPOSSIBLE);
@@ -1857,7 +1861,7 @@ class Item_master_gtid_wait :public Item_int_func
Item_master_gtid_wait(THD *thd, Item *a, Item *b): Item_int_func(thd, a, b) {}
longlong val_int();
const char *func_name() const { return "master_gtid_wait"; }
- void fix_length_and_dec() { max_length=2; }
+ bool fix_length_and_dec() { max_length=2; return FALSE; }
bool check_vcol_func_processor(void *arg)
{
return mark_unsupported_function(func_name(), "()", arg, VCOL_IMPOSSIBLE);
@@ -1948,7 +1952,7 @@ class Item_func_set_user_var :public Item_func_user_var
void save_item_result(Item *item);
bool update();
bool fix_fields(THD *thd, Item **ref);
- void fix_length_and_dec();
+ bool fix_length_and_dec();
Field *create_field_for_create_select(TABLE *table)
{
return result_type() != STRING_RESULT ?
@@ -1989,7 +1993,7 @@ class Item_func_get_user_var :public Item_func_user_var,
longlong val_int();
my_decimal *val_decimal(my_decimal*);
String *val_str(String* str);
- void fix_length_and_dec();
+ bool fix_length_and_dec();
virtual void print(String *str, enum_query_type query_type);
/*
We must always return variables as strings to guard against selects of type
@@ -2071,7 +2075,7 @@ class Item_func_get_system_var :public Item_func
size_t name_len_arg);
enum Functype functype() const { return GSYSVAR_FUNC; }
void update_null_value();
- void fix_length_and_dec();
+ bool fix_length_and_dec();
void print(String *str, enum_query_type query_type);
bool const_item() const { return true; }
table_map used_tables() const { return 0; }
@@ -2210,7 +2214,11 @@ class Item_func_is_free_lock :public Item_int_func
Item_func_is_free_lock(THD *thd, Item *a): Item_int_func(thd, a) {}
longlong val_int();
const char *func_name() const { return "is_free_lock"; }
- void fix_length_and_dec() { decimals=0; max_length=1; maybe_null=1;}
+ bool fix_length_and_dec()
+ {
+ decimals=0; max_length=1; maybe_null=1;
+ return FALSE;
+ }
bool check_vcol_func_processor(void *arg)
{
return mark_unsupported_function(func_name(), "()", arg, VCOL_IMPOSSIBLE);
@@ -2226,7 +2234,11 @@ class Item_func_is_used_lock :public Item_int_func
Item_func_is_used_lock(THD *thd, Item *a): Item_int_func(thd, a) {}
longlong val_int();
const char *func_name() const { return "is_used_lock"; }
- void fix_length_and_dec() { decimals=0; max_length=10; maybe_null=1;}
+ bool fix_length_and_dec()
+ {
+ decimals=0; max_length=10; maybe_null=1;
+ return FALSE;
+ }
bool check_vcol_func_processor(void *arg)
{
return mark_unsupported_function(func_name(), "()", arg, VCOL_IMPOSSIBLE);
@@ -2278,7 +2290,7 @@ class Item_func_row_count :public Item_int_func
Item_func_row_count(THD *thd): Item_int_func(thd) {}
longlong val_int();
const char *func_name() const { return "row_count"; }
- void fix_length_and_dec() { decimals= 0; maybe_null=0; }
+ bool fix_length_and_dec() { decimals= 0; maybe_null=0; return FALSE; }
bool check_vcol_func_processor(void *arg)
{
return mark_unsupported_function(func_name(), "()", arg, VCOL_IMPOSSIBLE);
@@ -2406,7 +2418,7 @@ class Item_func_sp :public Item_func
virtual enum Functype functype() const { return FUNC_SP; }
bool fix_fields(THD *thd, Item **ref);
- void fix_length_and_dec(void);
+ bool fix_length_and_dec(void);
bool is_expensive();
inline Field *get_sp_result_field()
@@ -2442,7 +2454,7 @@ class Item_func_found_rows :public Item_int_func
Item_func_found_rows(THD *thd): Item_int_func(thd) {}
longlong val_int();
const char *func_name() const { return "found_rows"; }
- void fix_length_and_dec() { decimals= 0; maybe_null=0; }
+ bool fix_length_and_dec() { decimals= 0; maybe_null=0; return FALSE; }
bool check_vcol_func_processor(void *arg)
{
return mark_unsupported_function(func_name(), "()", arg, VCOL_IMPOSSIBLE);
@@ -2461,8 +2473,8 @@ class Item_func_uuid_short :public Item_int_func
const char *func_name() const { return "uuid_short"; }
longlong val_int();
bool const_item() const { return false; }
- void fix_length_and_dec()
- { max_length= 21; unsigned_flag=1; }
+ bool fix_length_and_dec()
+ { max_length= 21; unsigned_flag=1; return FALSE; }
table_map used_tables() const { return RAND_TABLE_BIT; }
bool check_vcol_func_processor(void *arg)
{
@@ -2483,7 +2495,7 @@ class Item_func_last_value :public Item_func
longlong val_int();
String *val_str(String *);
my_decimal *val_decimal(my_decimal *);
- void fix_length_and_dec();
+ bool fix_length_and_dec();
enum Item_result result_type () const { return last_value->result_type(); }
const char *func_name() const { return "last_value"; }
bool eval_not_null_tables(void *)
diff --git a/sql/item_geofunc.cc b/sql/item_geofunc.cc
index 3119f5a577b..246be438e36 100644
--- a/sql/item_geofunc.cc
+++ b/sql/item_geofunc.cc
@@ -49,12 +49,13 @@ Field *Item_geometry_func::create_field_for_create_select(TABLE *t_arg)
return result;
}
-void Item_geometry_func::fix_length_and_dec()
+bool Item_geometry_func::fix_length_and_dec()
{
collation.set(&my_charset_bin);
decimals=0;
max_length= (uint32) 4294967295U;
maybe_null= 1;
+ return FALSE;
}
@@ -223,11 +224,12 @@ String *Item_func_as_wkt::val_str_ascii(String *str)
}
-void Item_func_as_wkt::fix_length_and_dec()
+bool Item_func_as_wkt::fix_length_and_dec()
{
collation.set(default_charset(), DERIVATION_COERCIBLE, MY_REPERTOIRE_ASCII);
max_length=MAX_BLOB_WIDTH;
maybe_null= 1;
+ return FALSE;
}
@@ -249,11 +251,12 @@ String *Item_func_as_wkb::val_str(String *str)
}
-void Item_func_as_geojson::fix_length_and_dec()
+bool Item_func_as_geojson::fix_length_and_dec()
{
collation.set(default_charset(), DERIVATION_COERCIBLE, MY_REPERTOIRE_ASCII);
max_length=MAX_BLOB_WIDTH;
maybe_null= 1;
+ return FALSE;
}
diff --git a/sql/item_geofunc.h b/sql/item_geofunc.h
index 199bc1f47de..acc94183d47 100644
--- a/sql/item_geofunc.h
+++ b/sql/item_geofunc.h
@@ -38,7 +38,7 @@ class Item_geometry_func: public Item_str_func
Item_geometry_func(THD *thd, Item *a, Item *b, Item *c):
Item_str_func(thd, a, b, c) {}
Item_geometry_func(THD *thd, List<Item> &list): Item_str_func(thd, list) {}
- void fix_length_and_dec();
+ bool fix_length_and_dec();
enum_field_types field_type() const { return MYSQL_TYPE_GEOMETRY; }
Field *create_field_for_create_select(TABLE *table);
};
@@ -90,7 +90,7 @@ class Item_func_as_wkt: public Item_str_ascii_func
Item_func_as_wkt(THD *thd, Item *a): Item_str_ascii_func(thd, a) {}
const char *func_name() const { return "st_astext"; }
String *val_str_ascii(String *);
- void fix_length_and_dec();
+ bool fix_length_and_dec();
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
{ return get_item_copy<Item_func_as_wkt>(thd, mem_root, this); }
};
@@ -116,7 +116,7 @@ class Item_func_as_geojson: public Item_str_ascii_func
Item_func_as_geojson(THD *thd, Item *js, Item *max_dec_digits, Item *opt):
Item_str_ascii_func(thd, js, max_dec_digits, opt) {}
const char *func_name() const { return "st_asgeojson"; }
- void fix_length_and_dec();
+ bool fix_length_and_dec();
String *val_str_ascii(String *);
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
{ return get_item_copy<Item_func_as_geojson>(thd, mem_root, this); }
@@ -129,11 +129,12 @@ class Item_func_geometry_type: public Item_str_ascii_func
Item_func_geometry_type(THD *thd, Item *a): Item_str_ascii_func(thd, a) {}
String *val_str_ascii(String *);
const char *func_name() const { return "st_geometrytype"; }
- void fix_length_and_dec()
+ bool fix_length_and_dec()
{
// "GeometryCollection" is the longest
fix_length_and_charset(20, default_charset());
maybe_null= 1;
+ return FALSE;
};
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
{ return get_item_copy<Item_func_geometry_type>(thd, mem_root, this); }
@@ -308,9 +309,10 @@ class Item_func_spatial_collection: public Item_geometry_func
item_type=it;
}
String *val_str(String *);
- void fix_length_and_dec()
+ bool fix_length_and_dec()
{
- Item_geometry_func::fix_length_and_dec();
+ if (Item_geometry_func::fix_length_and_dec())
+ return TRUE;
for (unsigned int i= 0; i < arg_count; ++i)
{
if (args[i]->fixed && args[i]->field_type() != MYSQL_TYPE_GEOMETRY)
@@ -320,8 +322,10 @@ class Item_func_spatial_collection: public Item_geometry_func
str.append('\0');
my_error(ER_ILLEGAL_VALUE_FOR_TYPE, MYF(0), "non geometric",
str.ptr());
+ return TRUE;
}
}
+ return FALSE;
}
const char *func_name() const { return "geometrycollection"; }
@@ -510,7 +514,7 @@ class Item_func_isempty: public Item_bool_func
Item_func_isempty(THD *thd, Item *a): Item_bool_func(thd, a) {}
longlong val_int();
const char *func_name() const { return "st_isempty"; }
- void fix_length_and_dec() { maybe_null= 1; }
+ bool fix_length_and_dec() { maybe_null= 1; return FALSE; }
bool need_parentheses_in_default() { return false; }
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
{ return get_item_copy<Item_func_isempty>(thd, mem_root, this); }
@@ -526,7 +530,7 @@ class Item_func_issimple: public Item_int_func
Item_func_issimple(THD *thd, Item *a): Item_int_func(thd, a) {}
longlong val_int();
const char *func_name() const { return "st_issimple"; }
- void fix_length_and_dec() { decimals=0; max_length=2; }
+ bool fix_length_and_dec() { decimals=0; max_length=2; return FALSE; }
uint decimal_precision() const { return 1; }
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
{ return get_item_copy<Item_func_issimple>(thd, mem_root, this); }
@@ -538,7 +542,7 @@ class Item_func_isclosed: public Item_int_func
Item_func_isclosed(THD *thd, Item *a): Item_int_func(thd, a) {}
longlong val_int();
const char *func_name() const { return "st_isclosed"; }
- void fix_length_and_dec() { decimals=0; max_length=2; }
+ bool fix_length_and_dec() { decimals=0; max_length=2; return FALSE; }
uint decimal_precision() const { return 1; }
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
{ return get_item_copy<Item_func_isclosed>(thd, mem_root, this); }
@@ -561,7 +565,7 @@ class Item_func_dimension: public Item_int_func
Item_func_dimension(THD *thd, Item *a): Item_int_func(thd, a) {}
longlong val_int();
const char *func_name() const { return "st_dimension"; }
- void fix_length_and_dec() { max_length= 10; maybe_null= 1; }
+ bool fix_length_and_dec() { max_length= 10; maybe_null= 1; return FALSE; }
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
{ return get_item_copy<Item_func_dimension>(thd, mem_root, this); }
};
@@ -573,10 +577,12 @@ class Item_func_x: public Item_real_func
Item_func_x(THD *thd, Item *a): Item_real_func(thd, a) {}
double val_real();
const char *func_name() const { return "st_x"; }
- void fix_length_and_dec()
- {
- Item_real_func::fix_length_and_dec();
- maybe_null= 1;
+ bool fix_length_and_dec()
+ {
+ if (Item_real_func::fix_length_and_dec())
+ return TRUE;
+ maybe_null= 1;
+ return FALSE;
}
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
{ return get_item_copy<Item_func_x>(thd, mem_root, this); }
@@ -590,10 +596,12 @@ class Item_func_y: public Item_real_func
Item_func_y(THD *thd, Item *a): Item_real_func(thd, a) {}
double val_real();
const char *func_name() const { return "st_y"; }
- void fix_length_and_dec()
- {
- Item_real_func::fix_length_and_dec();
- maybe_null= 1;
+ bool fix_length_and_dec()
+ {
+ if (Item_real_func::fix_length_and_dec())
+ return TRUE;
+ maybe_null= 1;
+ return FALSE;
}
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
{ return get_item_copy<Item_func_y>(thd, mem_root, this); }
@@ -607,7 +615,7 @@ class Item_func_numgeometries: public Item_int_func
Item_func_numgeometries(THD *thd, Item *a): Item_int_func(thd, a) {}
longlong val_int();
const char *func_name() const { return "st_numgeometries"; }
- void fix_length_and_dec() { max_length= 10; maybe_null= 1; }
+ bool fix_length_and_dec() { max_length= 10; maybe_null= 1; return FALSE; }
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
{ return get_item_copy<Item_func_numgeometries>(thd, mem_root, this); }
};
@@ -620,7 +628,7 @@ class Item_func_numinteriorring: public Item_int_func
Item_func_numinteriorring(THD *thd, Item *a): Item_int_func(thd, a) {}
longlong val_int();
const char *func_name() const { return "st_numinteriorrings"; }
- void fix_length_and_dec() { max_length= 10; maybe_null= 1; }
+ bool fix_length_and_dec() { max_length= 10; maybe_null= 1; return FALSE; }
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
{ return get_item_copy<Item_func_numinteriorring>(thd, mem_root, this); }
};
@@ -633,7 +641,7 @@ class Item_func_numpoints: public Item_int_func
Item_func_numpoints(THD *thd, Item *a): Item_int_func(thd, a) {}
longlong val_int();
const char *func_name() const { return "st_numpoints"; }
- void fix_length_and_dec() { max_length= 10; maybe_null= 1; }
+ bool fix_length_and_dec() { max_length= 10; maybe_null= 1; return FALSE; }
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
{ return get_item_copy<Item_func_numpoints>(thd, mem_root, this); }
};
@@ -646,10 +654,12 @@ class Item_func_area: public Item_real_func
Item_func_area(THD *thd, Item *a): Item_real_func(thd, a) {}
double val_real();
const char *func_name() const { return "st_area"; }
- void fix_length_and_dec()
- {
- Item_real_func::fix_length_and_dec();
- maybe_null= 1;
+ bool fix_length_and_dec()
+ {
+ if (Item_real_func::fix_length_and_dec())
+ return TRUE;
+ maybe_null= 1;
+ return FALSE;
}
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
{ return get_item_copy<Item_func_area>(thd, mem_root, this); }
@@ -663,10 +673,12 @@ class Item_func_glength: public Item_real_func
Item_func_glength(THD *thd, Item *a): Item_real_func(thd, a) {}
double val_real();
const char *func_name() const { return "st_length"; }
- void fix_length_and_dec()
- {
- Item_real_func::fix_length_and_dec();
- maybe_null= 1;
+ bool fix_length_and_dec()
+ {
+ if (Item_real_func::fix_length_and_dec())
+ return TRUE;
+ maybe_null= 1;
+ return FALSE;
}
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
{ return get_item_copy<Item_func_glength>(thd, mem_root, this); }
@@ -680,7 +692,7 @@ class Item_func_srid: public Item_int_func
Item_func_srid(THD *thd, Item *a): Item_int_func(thd, a) {}
longlong val_int();
const char *func_name() const { return "srid"; }
- void fix_length_and_dec() { max_length= 10; maybe_null= 1; }
+ bool fix_length_and_dec() { max_length= 10; maybe_null= 1; return FALSE; }
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
{ return get_item_copy<Item_func_srid>(thd, mem_root, this); }
};
diff --git a/sql/item_inetfunc.h b/sql/item_inetfunc.h
index f19749df0af..670dce3da9f 100644
--- a/sql/item_inetfunc.h
+++ b/sql/item_inetfunc.h
@@ -30,12 +30,13 @@ class Item_func_inet_aton : public Item_int_func
Item_func_inet_aton(THD *thd, Item *a): Item_int_func(thd, a) {}
longlong val_int();
const char *func_name() const { return "inet_aton"; }
- void fix_length_and_dec()
+ bool fix_length_and_dec()
{
decimals= 0;
max_length= 21;
maybe_null= 1;
unsigned_flag= 1;
+ return FALSE;
}
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
{ return get_item_copy<Item_func_inet_aton>(thd, mem_root, this); }
@@ -53,11 +54,12 @@ class Item_func_inet_ntoa : public Item_str_func
{ }
String* val_str(String* str);
const char *func_name() const { return "inet_ntoa"; }
- void fix_length_and_dec()
+ bool fix_length_and_dec()
{
decimals= 0;
fix_length_and_charset(3 * 8 + 7, default_charset());
maybe_null= 1;
+ return FALSE;
}
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
{ return get_item_copy<Item_func_inet_ntoa>(thd, mem_root, this); }
@@ -122,11 +124,12 @@ class Item_func_inet6_aton : public Item_func_inet_str_base
virtual const char *func_name() const
{ return "inet6_aton"; }
- virtual void fix_length_and_dec()
+ virtual bool fix_length_and_dec()
{
decimals= 0;
fix_length_and_charset(16, &my_charset_bin);
maybe_null= 1;
+ return FALSE;
}
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
{ return get_item_copy<Item_func_inet6_aton>(thd, mem_root, this); }
@@ -151,7 +154,7 @@ class Item_func_inet6_ntoa : public Item_func_inet_str_base
virtual const char *func_name() const
{ return "inet6_ntoa"; }
- virtual void fix_length_and_dec()
+ virtual bool fix_length_and_dec()
{
decimals= 0;
@@ -161,6 +164,7 @@ class Item_func_inet6_ntoa : public Item_func_inet_str_base
fix_length_and_charset(8 * 4 + 7, default_charset());
maybe_null= 1;
+ return FALSE;
}
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
{ return get_item_copy<Item_func_inet6_ntoa>(thd, mem_root, this); }
diff --git a/sql/item_jsonfunc.cc b/sql/item_jsonfunc.cc
index 794831ae1a5..72aeac5b930 100644
--- a/sql/item_jsonfunc.cc
+++ b/sql/item_jsonfunc.cc
@@ -388,11 +388,13 @@ longlong Item_func_json_valid::val_int()
}
-void Item_func_json_exists::fix_length_and_dec()
+bool Item_func_json_exists::fix_length_and_dec()
{
- Item_int_func::fix_length_and_dec();
+ if (Item_int_func::fix_length_and_dec())
+ return TRUE;
maybe_null= 1;
path.set_constant_flag(args[1]->const_item());
+ return FALSE;
}
@@ -439,12 +441,13 @@ longlong Item_func_json_exists::val_int()
}
-void Item_func_json_value::fix_length_and_dec()
+bool Item_func_json_value::fix_length_and_dec()
{
collation.set(args[0]->collation);
max_length= args[0]->max_length;
path.set_constant_flag(args[1]->const_item());
maybe_null= 1;
+ return FALSE;
}
@@ -546,7 +549,7 @@ bool Item_func_json_query::check_and_get_value(json_engine_t *je, String *res,
}
-void Item_func_json_quote::fix_length_and_dec()
+bool Item_func_json_quote::fix_length_and_dec()
{
collation.set(&my_charset_utf8mb4_bin);
/*
@@ -554,6 +557,7 @@ void Item_func_json_quote::fix_length_and_dec()
of the argument turn into '\uXXXX\uXXXX', which is 12.
*/
max_length= args[0]->max_length * 12 + 2;
+ return FALSE;
}
@@ -581,12 +585,13 @@ String *Item_func_json_quote::val_str(String *str)
}
-void Item_func_json_unquote::fix_length_and_dec()
+bool Item_func_json_unquote::fix_length_and_dec()
{
collation.set(&my_charset_utf8_general_ci,
DERIVATION_COERCIBLE, MY_REPERTOIRE_ASCII);
max_length= args[0]->max_length;
maybe_null= 1;
+ return FALSE;
}
@@ -702,13 +707,14 @@ void Item_json_str_multipath::cleanup()
}
-void Item_func_json_extract::fix_length_and_dec()
+bool Item_func_json_extract::fix_length_and_dec()
{
collation.set(args[0]->collation);
max_length= args[0]->max_length * (arg_count - 1);
mark_constant_paths(paths, args+1, arg_count-1);
maybe_null= 1;
+ return FALSE;
}
@@ -937,14 +943,14 @@ double Item_func_json_extract::val_real()
}
-void Item_func_json_contains::fix_length_and_dec()
+bool Item_func_json_contains::fix_length_and_dec()
{
a2_constant= args[1]->const_item();
a2_parsed= FALSE;
maybe_null= 1;
if (arg_count > 2)
path.set_constant_flag(args[2]->const_item());
- Item_int_func::fix_length_and_dec();
+ return Item_int_func::fix_length_and_dec();
}
@@ -1190,13 +1196,13 @@ bool Item_func_json_contains_path::fix_fields(THD *thd, Item **ref)
}
-void Item_func_json_contains_path::fix_length_and_dec()
+bool Item_func_json_contains_path::fix_length_and_dec()
{
ooa_constant= args[1]->const_item();
ooa_parsed= FALSE;
maybe_null= 1;
mark_constant_paths(paths, args+2, arg_count-2);
- Item_int_func::fix_length_and_dec();
+ return Item_int_func::fix_length_and_dec();
}
@@ -1454,7 +1460,7 @@ static int append_json_keyname(String *str, Item *item, String *tmp_val)
}
-void Item_func_json_array::fix_length_and_dec()
+bool Item_func_json_array::fix_length_and_dec()
{
ulonglong char_length= 2;
uint n_arg;
@@ -1467,17 +1473,18 @@ void Item_func_json_array::fix_length_and_dec()
DERIVATION_COERCIBLE, MY_REPERTOIRE_ASCII);
tmp_val.set_charset(&my_charset_utf8_general_ci);
max_length= 2;
- return;
+ return FALSE;
}
if (agg_arg_charsets_for_string_result(collation, args, arg_count))
- return;
+ return TRUE;
for (n_arg=0 ; n_arg < arg_count ; n_arg++)
char_length+= args[n_arg]->max_char_length() + 4;
fix_char_length_ulonglong(char_length);
tmp_val.set_charset(collation.collation);
+ return FALSE;
}
@@ -1521,7 +1528,7 @@ String *Item_func_json_array::val_str(String *str)
}
-void Item_func_json_array_append::fix_length_and_dec()
+bool Item_func_json_array_append::fix_length_and_dec()
{
uint n_arg;
ulonglong char_length;
@@ -1536,6 +1543,7 @@ void Item_func_json_array_append::fix_length_and_dec()
}
fix_char_length_ulonglong(char_length);
+ return FALSE;
}
@@ -2122,11 +2130,12 @@ String *Item_func_json_merge::val_str(String *str)
}
-void Item_func_json_length::fix_length_and_dec()
+bool Item_func_json_length::fix_length_and_dec()
{
if (arg_count > 1)
path.set_constant_flag(args[1]->const_item());
maybe_null= 1;
+ return FALSE;
}
@@ -2266,11 +2275,12 @@ longlong Item_func_json_depth::val_int()
}
-void Item_func_json_type::fix_length_and_dec()
+bool Item_func_json_type::fix_length_and_dec()
{
collation.set(&my_charset_utf8_general_ci);
max_length= 12;
maybe_null= 1;
+ return FALSE;
}
@@ -2323,7 +2333,7 @@ String *Item_func_json_type::val_str(String *str)
}
-void Item_func_json_insert::fix_length_and_dec()
+bool Item_func_json_insert::fix_length_and_dec()
{
uint n_arg;
ulonglong char_length;
@@ -2339,6 +2349,7 @@ void Item_func_json_insert::fix_length_and_dec()
fix_char_length_ulonglong(char_length);
maybe_null= 1;
+ return FALSE;
}
@@ -2583,13 +2594,14 @@ String *Item_func_json_insert::val_str(String *str)
}
-void Item_func_json_remove::fix_length_and_dec()
+bool Item_func_json_remove::fix_length_and_dec()
{
collation.set(args[0]->collation);
max_length= args[0]->max_length;
mark_constant_paths(paths, args+1, arg_count-1);
maybe_null= 1;
+ return FALSE;
}
@@ -2769,13 +2781,14 @@ String *Item_func_json_remove::val_str(String *str)
}
-void Item_func_json_keys::fix_length_and_dec()
+bool Item_func_json_keys::fix_length_and_dec()
{
collation.set(args[0]->collation);
max_length= args[0]->max_length;
maybe_null= 1;
if (arg_count > 1)
path.set_constant_flag(args[1]->const_item());
+ return FALSE;
}
@@ -2936,7 +2949,7 @@ bool Item_func_json_search::fix_fields(THD *thd, Item **ref)
static const uint SQR_MAX_BLOB_WIDTH= (uint) sqrt(MAX_BLOB_WIDTH);
-void Item_func_json_search::fix_length_and_dec()
+bool Item_func_json_search::fix_length_and_dec()
{
collation.set(args[0]->collation);
@@ -2958,6 +2971,7 @@ void Item_func_json_search::fix_length_and_dec()
if (arg_count > 4)
mark_constant_paths(paths, args+4, arg_count-4);
maybe_null= 1;
+ return FALSE;
}
@@ -3135,11 +3149,12 @@ const char *Item_func_json_format::func_name() const
}
-void Item_func_json_format::fix_length_and_dec()
+bool Item_func_json_format::fix_length_and_dec()
{
decimals= 0;
max_length= args[0]->max_length;
maybe_null= 1;
+ return FALSE;
}
diff --git a/sql/item_jsonfunc.h b/sql/item_jsonfunc.h
index 927b60015b8..f331ee3b582 100644
--- a/sql/item_jsonfunc.h
+++ b/sql/item_jsonfunc.h
@@ -49,10 +49,12 @@ class Item_func_json_valid: public Item_int_func
Item_func_json_valid(THD *thd, Item *json) : Item_int_func(thd, json) {}
longlong val_int();
const char *func_name() const { return "json_valid"; }
- void fix_length_and_dec()
+ bool fix_length_and_dec()
{
- Item_int_func::fix_length_and_dec();
+ if (Item_int_func::fix_length_and_dec())
+ return TRUE;
maybe_null= 1;
+ return FALSE;
}
bool is_bool_type() { return true; }
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
@@ -71,7 +73,7 @@ class Item_func_json_exists: public Item_int_func
Item_int_func(thd, js, i_path) {}
const char *func_name() const { return "json_exists"; }
bool is_bool_type() { return true; }
- void fix_length_and_dec();
+ bool fix_length_and_dec();
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
{ return get_item_copy<Item_func_json_exists>(thd, mem_root, this); }
longlong val_int();
@@ -88,7 +90,7 @@ class Item_func_json_value: public Item_str_func
Item_func_json_value(THD *thd, Item *js, Item *i_path):
Item_str_func(thd, js, i_path) {}
const char *func_name() const { return "json_value"; }
- void fix_length_and_dec();
+ bool fix_length_and_dec();
String *val_str(String *);
virtual bool check_and_get_value(json_engine_t *je, String *res, int *error);
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
@@ -117,7 +119,7 @@ class Item_func_json_quote: public Item_str_func
public:
Item_func_json_quote(THD *thd, Item *s): Item_str_func(thd, s) {}
const char *func_name() const { return "json_quote"; }
- void fix_length_and_dec();
+ bool fix_length_and_dec();
String *val_str(String *);
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
{ return get_item_copy<Item_func_json_quote>(thd, mem_root, this); }
@@ -132,7 +134,7 @@ class Item_func_json_unquote: public Item_str_func
public:
Item_func_json_unquote(THD *thd, Item *s): Item_str_func(thd, s) {}
const char *func_name() const { return "json_unquote"; }
- void fix_length_and_dec();
+ bool fix_length_and_dec();
String *val_str(String *);
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
{ return get_item_copy<Item_func_json_unquote>(thd, mem_root, this); }
@@ -165,7 +167,7 @@ class Item_func_json_extract: public Item_json_str_multipath
Item_json_str_multipath(thd, list) {}
const char *func_name() const { return "json_extract"; }
enum Functype functype() const { return JSON_EXTRACT_FUNC; }
- void fix_length_and_dec();
+ bool fix_length_and_dec();
String *val_str(String *);
longlong val_int();
double val_real();
@@ -187,7 +189,7 @@ class Item_func_json_contains: public Item_int_func
Item_func_json_contains(THD *thd, List<Item> &list):
Item_int_func(thd, list) {}
const char *func_name() const { return "json_contains"; }
- void fix_length_and_dec();
+ bool fix_length_and_dec();
longlong val_int();
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
{ return get_item_copy<Item_func_json_contains>(thd, mem_root, this); }
@@ -209,7 +211,7 @@ class Item_func_json_contains_path: public Item_int_func
Item_int_func(thd, list), tmp_paths(0) {}
const char *func_name() const { return "json_contains_path"; }
bool fix_fields(THD *thd, Item **ref);
- void fix_length_and_dec();
+ bool fix_length_and_dec();
void cleanup();
longlong val_int();
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
@@ -229,7 +231,7 @@ class Item_func_json_array: public Item_str_func
Item_str_func(thd, list) {}
String *val_str(String *);
bool is_json_type() { return true; }
- void fix_length_and_dec();
+ bool fix_length_and_dec();
const char *func_name() const { return "json_array"; }
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
{ return get_item_copy<Item_func_json_array>(thd, mem_root, this); }
@@ -244,7 +246,7 @@ class Item_func_json_array_append: public Item_json_str_multipath
public:
Item_func_json_array_append(THD *thd, List<Item> &list):
Item_json_str_multipath(thd, list) {}
- void fix_length_and_dec();
+ bool fix_length_and_dec();
String *val_str(String *);
uint get_n_paths() const { return arg_count/2; }
const char *func_name() const { return "json_array_append"; }
@@ -305,7 +307,7 @@ class Item_func_json_length: public Item_int_func
Item_func_json_length(THD *thd, List<Item> &list):
Item_int_func(thd, list) {}
const char *func_name() const { return "json_length"; }
- void fix_length_and_dec();
+ bool fix_length_and_dec();
longlong val_int();
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
{ return get_item_copy<Item_func_json_length>(thd, mem_root, this); }
@@ -332,7 +334,7 @@ class Item_func_json_type: public Item_str_func
public:
Item_func_json_type(THD *thd, Item *js): Item_str_func(thd, js) {}
const char *func_name() const { return "json_type"; }
- void fix_length_and_dec();
+ bool fix_length_and_dec();
String *val_str(String *);
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
{ return get_item_copy<Item_func_json_type>(thd, mem_root, this); }
@@ -349,7 +351,7 @@ class Item_func_json_insert: public Item_json_str_multipath
Item_func_json_insert(bool i_mode, bool r_mode, THD *thd, List<Item> &list):
Item_json_str_multipath(thd, list),
mode_insert(i_mode), mode_replace(r_mode) {}
- void fix_length_and_dec();
+ bool fix_length_and_dec();
String *val_str(String *);
uint get_n_paths() const { return arg_count/2; }
const char *func_name() const
@@ -369,7 +371,7 @@ class Item_func_json_remove: public Item_json_str_multipath
public:
Item_func_json_remove(THD *thd, List<Item> &list):
Item_json_str_multipath(thd, list) {}
- void fix_length_and_dec();
+ bool fix_length_and_dec();
String *val_str(String *);
uint get_n_paths() const { return arg_count - 1; }
const char *func_name() const { return "json_remove"; }
@@ -388,7 +390,7 @@ class Item_func_json_keys: public Item_str_func
Item_func_json_keys(THD *thd, List<Item> &list):
Item_str_func(thd, list) {}
const char *func_name() const { return "json_keys"; }
- void fix_length_and_dec();
+ bool fix_length_and_dec();
String *val_str(String *);
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
{ return get_item_copy<Item_func_json_keys>(thd, mem_root, this); }
@@ -412,7 +414,7 @@ class Item_func_json_search: public Item_json_str_multipath
Item_json_str_multipath(thd, list) {}
const char *func_name() const { return "json_search"; }
bool fix_fields(THD *thd, Item **ref);
- void fix_length_and_dec();
+ bool fix_length_and_dec();
String *val_str(String *);
uint get_n_paths() const { return arg_count > 4 ? arg_count - 4 : 0; }
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
@@ -440,7 +442,7 @@ class Item_func_json_format: public Item_str_func
Item_str_func(thd, list), fmt(DETAILED) {}
const char *func_name() const;
- void fix_length_and_dec();
+ bool fix_length_and_dec();
String *val_str(String *str);
String *val_json(String *str);
bool is_json_type() { return true; }
diff --git a/sql/item_strfunc.cc b/sql/item_strfunc.cc
index 3d543c8c390..87c766340c7 100644
--- a/sql/item_strfunc.cc
+++ b/sql/item_strfunc.cc
@@ -188,10 +188,11 @@ String *Item_func_sha::val_str_ascii(String *str)
return 0;
}
-void Item_func_sha::fix_length_and_dec()
+bool Item_func_sha::fix_length_and_dec()
{
// size of hex representation of hash
fix_length_and_charset(MY_SHA1_HASH_SIZE * 2, default_charset());
+ return FALSE;
}
String *Item_func_sha2::val_str_ascii(String *str)
@@ -267,7 +268,7 @@ String *Item_func_sha2::val_str_ascii(String *str)
}
-void Item_func_sha2::fix_length_and_dec()
+bool Item_func_sha2::fix_length_and_dec()
{
maybe_null= 1;
max_length = 0;
@@ -292,6 +293,7 @@ void Item_func_sha2::fix_length_and_dec()
ER_THD(thd, ER_WRONG_PARAMETERS_TO_NATIVE_FCT),
"sha2");
}
+ return FALSE;
}
/* Implementation of AES encryption routines */
@@ -344,23 +346,25 @@ String *Item_aes_crypt::val_str(String *str2)
return 0;
}
-void Item_func_aes_encrypt::fix_length_and_dec()
+bool Item_func_aes_encrypt::fix_length_and_dec()
{
max_length=my_aes_get_size(MY_AES_ECB, args[0]->max_length);
what= ENCRYPTION_FLAG_ENCRYPT;
+ return FALSE;
}
-void Item_func_aes_decrypt::fix_length_and_dec()
+bool Item_func_aes_decrypt::fix_length_and_dec()
{
max_length=args[0]->max_length;
maybe_null= 1;
what= ENCRYPTION_FLAG_DECRYPT;
+ return FALSE;
}
-void Item_func_to_base64::fix_length_and_dec()
+bool Item_func_to_base64::fix_length_and_dec()
{
maybe_null= args[0]->maybe_null;
collation.set(default_charset(), DERIVATION_COERCIBLE, MY_REPERTOIRE_ASCII);
@@ -375,6 +379,7 @@ void Item_func_to_base64::fix_length_and_dec()
DBUG_ASSERT(length > 0);
fix_char_length_ulonglong((ulonglong) length - 1);
}
+ return FALSE;
}
@@ -410,7 +415,7 @@ String *Item_func_to_base64::val_str_ascii(String *str)
}
-void Item_func_from_base64::fix_length_and_dec()
+bool Item_func_from_base64::fix_length_and_dec()
{
if (args[0]->max_length > (uint) my_base64_decode_max_arg_length())
{
@@ -422,6 +427,7 @@ void Item_func_from_base64::fix_length_and_dec()
fix_char_length_ulonglong((ulonglong) length);
}
maybe_null= 1; // Can be NULL, e.g. in case of badly formed input string
+ return FALSE;
}
@@ -630,17 +636,18 @@ String *Item_func_concat::val_str(String *str)
}
-void Item_func_concat::fix_length_and_dec()
+bool Item_func_concat::fix_length_and_dec()
{
ulonglong char_length= 0;
if (agg_arg_charsets_for_string_result(collation, args, arg_count))
- return;
+ return TRUE;
for (uint i=0 ; i < arg_count ; i++)
char_length+= args[i]->max_char_length();
fix_char_length_ulonglong(char_length);
+ return FALSE;
}
/**
@@ -992,12 +999,12 @@ String *Item_func_concat_ws::val_str(String *str)
}
-void Item_func_concat_ws::fix_length_and_dec()
+bool Item_func_concat_ws::fix_length_and_dec()
{
ulonglong char_length;
if (agg_arg_charsets_for_string_result(collation, args, arg_count))
- return;
+ return TRUE;
/*
arg_count cannot be less than 2,
@@ -1009,6 +1016,7 @@ void Item_func_concat_ws::fix_length_and_dec()
char_length+= args[i]->max_char_length();
fix_char_length_ulonglong(char_length);
+ return FALSE;
}
@@ -1062,11 +1070,12 @@ String *Item_func_reverse::val_str(String *str)
}
-void Item_func_reverse::fix_length_and_dec()
+bool Item_func_reverse::fix_length_and_dec()
{
agg_arg_charsets_for_string_result(collation, args, 1);
DBUG_ASSERT(collation.collation != NULL);
fix_char_length(args[0]->max_char_length());
+ return FALSE;
}
/**
@@ -1208,7 +1217,7 @@ String *Item_func_replace::val_str(String *str)
}
-void Item_func_replace::fix_length_and_dec()
+bool Item_func_replace::fix_length_and_dec()
{
ulonglong char_length= (ulonglong) args[0]->max_char_length();
int diff=(int) (args[2]->max_char_length() - args[1]->max_char_length());
@@ -1219,8 +1228,9 @@ void Item_func_replace::fix_length_and_dec()
}
if (agg_arg_charsets_for_string_result_with_comparison(collation, args, 3))
- return;
+ return TRUE;
fix_char_length_ulonglong(char_length);
+ return FALSE;
}
@@ -1232,13 +1242,14 @@ bool Item_func_regexp_replace::fix_fields(THD *thd, Item **ref)
}
-void Item_func_regexp_replace::fix_length_and_dec()
+bool Item_func_regexp_replace::fix_length_and_dec()
{
if (agg_arg_charsets_for_string_result_with_comparison(collation, args, 3))
- return;
+ return TRUE;
max_length= MAX_BLOB_WIDTH;
re.init(collation.collation, 0);
re.fix_owner(this, args[0], args[1]);
+ return FALSE;
}
@@ -1374,13 +1385,14 @@ bool Item_func_regexp_substr::fix_fields(THD *thd, Item **ref)
}
-void Item_func_regexp_substr::fix_length_and_dec()
+bool Item_func_regexp_substr::fix_length_and_dec()
{
if (agg_arg_charsets_for_string_result_with_comparison(collation, args, 2))
- return;
+ return TRUE;
fix_char_length(args[0]->max_char_length());
re.init(collation.collation, 0);
re.fix_owner(this, args[0], args[1]);
+ return FALSE;
}
@@ -1488,16 +1500,17 @@ String *Item_func_insert::val_str(String *str)
}
-void Item_func_insert::fix_length_and_dec()
+bool Item_func_insert::fix_length_and_dec()
{
ulonglong char_length;
// Handle character set for args[0] and args[3].
if (agg_arg_charsets_for_string_result(collation, args, 2, 3))
- return;
+ return TRUE;
char_length= ((ulonglong) args[0]->max_char_length() +
(ulonglong) args[3]->max_char_length());
fix_char_length_ulonglong(char_length);
+ return FALSE;
}
@@ -1534,22 +1547,26 @@ String *Item_str_conv::val_str(String *str)
}
-void Item_func_lcase::fix_length_and_dec()
+bool Item_func_lcase::fix_length_and_dec()
{
- agg_arg_charsets_for_string_result(collation, args, 1);
+ if (agg_arg_charsets_for_string_result(collation, args, 1))
+ return TRUE;
DBUG_ASSERT(collation.collation != NULL);
multiply= collation.collation->casedn_multiply;
converter= collation.collation->cset->casedn;
fix_char_length_ulonglong((ulonglong) args[0]->max_char_length() * multiply);
+ return FALSE;
}
-void Item_func_ucase::fix_length_and_dec()
+bool Item_func_ucase::fix_length_and_dec()
{
- agg_arg_charsets_for_string_result(collation, args, 1);
+ if (agg_arg_charsets_for_string_result(collation, args, 1))
+ return TRUE;
DBUG_ASSERT(collation.collation != NULL);
multiply= collation.collation->caseup_multiply;
converter= collation.collation->cset->caseup;
fix_char_length_ulonglong((ulonglong) args[0]->max_char_length() * multiply);
+ return FALSE;
}
@@ -1592,11 +1609,13 @@ void Item_str_func::left_right_max_length()
}
-void Item_func_left::fix_length_and_dec()
+bool Item_func_left::fix_length_and_dec()
{
- agg_arg_charsets_for_string_result(collation, args, 1);
+ if (agg_arg_charsets_for_string_result(collation, args, 1))
+ return TRUE;
DBUG_ASSERT(collation.collation != NULL);
left_right_max_length();
+ return FALSE;
}
@@ -1626,11 +1645,13 @@ String *Item_func_right::val_str(String *str)
}
-void Item_func_right::fix_length_and_dec()
+bool Item_func_right::fix_length_and_dec()
{
- agg_arg_charsets_for_string_result(collation, args, 1);
+ if (agg_arg_charsets_for_string_result(collation, args, 1))
+ return TRUE;
DBUG_ASSERT(collation.collation != NULL);
left_right_max_length();
+ return FALSE;
}
@@ -1681,11 +1702,12 @@ String *Item_func_substr::val_str(String *str)
}
-void Item_func_substr::fix_length_and_dec()
+bool Item_func_substr::fix_length_and_dec()
{
max_length=args[0]->max_length;
- agg_arg_charsets_for_string_result(collation, args, 1);
+ if (agg_arg_charsets_for_string_result(collation, args, 1))
+ return TRUE;
DBUG_ASSERT(collation.collation != NULL);
if (args[1]->const_item())
{
@@ -1706,14 +1728,16 @@ void Item_func_substr::fix_length_and_dec()
set_if_smaller(max_length,(uint) length);
}
max_length*= collation.collation->mbmaxlen;
+ return FALSE;
}
-void Item_func_substr_index::fix_length_and_dec()
-{
+bool Item_func_substr_index::fix_length_and_dec()
+{
if (agg_arg_charsets_for_string_result_with_comparison(collation, args, 2))
- return;
+ return TRUE;
fix_char_length(args[0]->max_char_length());
+ return FALSE;
}
@@ -2037,11 +2061,12 @@ String *Item_func_trim::val_str(String *str)
return trimmed_value(res, (uint32) (ptr - res->ptr()), (uint32) (end - ptr));
}
-void Item_func_trim::fix_length_and_dec()
+bool Item_func_trim::fix_length_and_dec()
{
if (arg_count == 1)
{
- agg_arg_charsets_for_string_result(collation, args, 1);
+ if (agg_arg_charsets_for_string_result(collation, args, 1))
+ return TRUE;
DBUG_ASSERT(collation.collation != NULL);
remove.set_charset(collation.collation);
remove.set_ascii(" ",1);
@@ -2052,9 +2077,10 @@ void Item_func_trim::fix_length_and_dec()
// Note that we pass args[1] as the first item, and args[0] as the second.
if (agg_arg_charsets_for_string_result_with_comparison(collation,
&args[1], 2, -1))
- return;
+ return TRUE;
}
fix_char_length(args[0]->max_char_length());
+ return FALSE;
}
void Item_func_trim::print(String *str, enum_query_type query_type)
@@ -2194,7 +2220,7 @@ bool Item_func_encode::seed()
return FALSE;
}
-void Item_func_encode::fix_length_and_dec()
+bool Item_func_encode::fix_length_and_dec()
{
max_length=args[0]->max_length;
maybe_null=args[0]->maybe_null || args[1]->maybe_null;
@@ -2202,6 +2228,7 @@ void Item_func_encode::fix_length_and_dec()
/* Precompute the seed state if the item is constant. */
seeded= args[1]->const_item() &&
(args[1]->result_type() == STRING_RESULT) && !seed();
+ return FALSE;
}
String *Item_func_encode::val_str(String *str)
@@ -2347,13 +2374,14 @@ bool Item_func_current_role::fix_fields(THD *thd, Item **ref)
return 0;
}
-void Item_func_soundex::fix_length_and_dec()
+bool Item_func_soundex::fix_length_and_dec()
{
uint32 char_length= args[0]->max_char_length();
agg_arg_charsets_for_string_result(collation, args, 1);
DBUG_ASSERT(collation.collation != NULL);
set_if_bigger(char_length, 4);
fix_char_length(char_length);
+ return FALSE;
}
@@ -2529,7 +2557,7 @@ MY_LOCALE *Item_func_format::get_locale(Item *item)
return lc;
}
-void Item_func_format::fix_length_and_dec()
+bool Item_func_format::fix_length_and_dec()
{
uint32 char_length= args[0]->max_char_length();
uint32 max_sep_count= (char_length / 3) + (decimals ? 1 : 0) + /*sign*/1;
@@ -2539,6 +2567,7 @@ void Item_func_format::fix_length_and_dec()
locale= args[2]->basic_const_item() ? get_locale(args[2]) : NULL;
else
locale= &my_locale_en_US; /* Two arguments */
+ return FALSE;
}
@@ -2652,13 +2681,13 @@ String *Item_func_format::val_str_ascii(String *str)
}
-void Item_func_elt::fix_length_and_dec()
+bool Item_func_elt::fix_length_and_dec()
{
uint32 char_length= 0;
decimals=0;
if (agg_arg_charsets_for_string_result(collation, args + 1, arg_count - 1))
- return;
+ return TRUE;
for (uint i= 1 ; i < arg_count ; i++)
{
@@ -2667,6 +2696,7 @@ void Item_func_elt::fix_length_and_dec()
}
fix_char_length(char_length);
maybe_null=1; // NULL if wrong first arg
+ return FALSE;
}
@@ -2713,16 +2743,17 @@ String *Item_func_elt::val_str(String *str)
}
-void Item_func_make_set::fix_length_and_dec()
+bool Item_func_make_set::fix_length_and_dec()
{
uint32 char_length= arg_count - 2; /* Separators */
if (agg_arg_charsets_for_string_result(collation, args + 1, arg_count - 1))
- return;
+ return TRUE;
for (uint i=1 ; i < arg_count ; i++)
char_length+= args[i]->max_char_length();
fix_char_length(char_length);
+ return FALSE;
}
@@ -2853,9 +2884,10 @@ inline String* alloc_buffer(String *res,String *str,String *tmp_value,
}
-void Item_func_repeat::fix_length_and_dec()
+bool Item_func_repeat::fix_length_and_dec()
{
- agg_arg_charsets_for_string_result(collation, args, 1);
+ if (agg_arg_charsets_for_string_result(collation, args, 1))
+ return TRUE;
DBUG_ASSERT(collation.collation != NULL);
if (args[1]->const_item())
{
@@ -2877,6 +2909,7 @@ void Item_func_repeat::fix_length_and_dec()
max_length= MAX_BLOB_WIDTH;
maybe_null= 1;
}
+ return FALSE;
}
/**
@@ -2938,7 +2971,7 @@ String *Item_func_repeat::val_str(String *str)
}
-void Item_func_space::fix_length_and_dec()
+bool Item_func_space::fix_length_and_dec()
{
collation.set(default_charset(), DERIVATION_COERCIBLE, MY_REPERTOIRE_ASCII);
if (args[0]->const_item())
@@ -2954,12 +2987,13 @@ void Item_func_space::fix_length_and_dec()
if (count > INT_MAX32)
count= INT_MAX32;
fix_char_length_ulonglong(count);
- return;
+ return FALSE;
}
end:
max_length= MAX_BLOB_WIDTH;
maybe_null= 1;
+ return FALSE;
}
@@ -3009,11 +3043,12 @@ String *Item_func_space::val_str(String *str)
}
-void Item_func_binlog_gtid_pos::fix_length_and_dec()
+bool Item_func_binlog_gtid_pos::fix_length_and_dec()
{
collation.set(system_charset_info);
max_length= MAX_BLOB_WIDTH;
maybe_null= 1;
+ return FALSE;
}
@@ -3049,11 +3084,11 @@ String *Item_func_binlog_gtid_pos::val_str(String *str)
}
-void Item_func_rpad::fix_length_and_dec()
+bool Item_func_rpad::fix_length_and_dec()
{
// Handle character set for args[0] and args[2].
if (agg_arg_charsets_for_string_result(collation, &args[0], 2, 2))
- return;
+ return TRUE;
if (args[1]->const_item())
{
ulonglong char_length= (ulonglong) args[1]->val_int();
@@ -3071,6 +3106,7 @@ void Item_func_rpad::fix_length_and_dec()
max_length= MAX_BLOB_WIDTH;
maybe_null= 1;
}
+ return FALSE;
}
@@ -3157,12 +3193,12 @@ String *Item_func_rpad::val_str(String *str)
}
-void Item_func_lpad::fix_length_and_dec()
+bool Item_func_lpad::fix_length_and_dec()
{
// Handle character set for args[0] and args[2].
if (agg_arg_charsets_for_string_result(collation, &args[0], 2, 2))
- return;
-
+ return TRUE;
+
if (args[1]->const_item())
{
ulonglong char_length= (ulonglong) args[1]->val_int();
@@ -3180,6 +3216,7 @@ void Item_func_lpad::fix_length_and_dec()
max_length= MAX_BLOB_WIDTH;
maybe_null= 1;
}
+ return FALSE;
}
@@ -3329,10 +3366,11 @@ String *Item_func_conv_charset::val_str(String *str)
0 : str;
}
-void Item_func_conv_charset::fix_length_and_dec()
+bool Item_func_conv_charset::fix_length_and_dec()
{
DBUG_ASSERT(collation.derivation == DERIVATION_IMPLICIT);
fix_char_length(args[0]->max_char_length());
+ return FALSE;
}
void Item_func_conv_charset::print(String *str, enum_query_type query_type)
@@ -3354,7 +3392,7 @@ String *Item_func_set_collation::val_str(String *str)
return str;
}
-void Item_func_set_collation::fix_length_and_dec()
+bool Item_func_set_collation::fix_length_and_dec()
{
CHARSET_INFO *set_collation;
const char *colname;
@@ -3365,8 +3403,8 @@ void Item_func_set_collation::fix_length_and_dec()
MY_CS_BINSORT,MYF(0));
else
{
- if (!(set_collation= mysqld_collation_get_by_name(colname)))
- return;
+ if (!(set_collation= mysqld_collation_get_by_name(colname)))
+ return TRUE;
}
if (!set_collation ||
@@ -3374,11 +3412,12 @@ void Item_func_set_collation::fix_length_and_dec()
{
my_error(ER_COLLATION_CHARSET_MISMATCH, MYF(0),
colname, args[0]->collation.collation->csname);
- return;
+ return TRUE;
}
collation.set(set_collation, DERIVATION_EXPLICIT,
args[0]->collation.repertoire);
max_length= args[0]->max_length;
+ return FALSE;
}
@@ -3437,7 +3476,7 @@ String *Item_func_collation::val_str(String *str)
}
-void Item_func_weight_string::fix_length_and_dec()
+bool Item_func_weight_string::fix_length_and_dec()
{
CHARSET_INFO *cs= args[0]->collation.collation;
collation.set(&my_charset_bin, args[0]->collation.derivation);
@@ -3455,6 +3494,7 @@ void Item_func_weight_string::fix_length_and_dec()
max_length= cs->coll->strnxfrmlen(cs, char_length * cs->mbmaxlen);
}
maybe_null= 1;
+ return FALSE;
}
@@ -3838,15 +3878,16 @@ String* Item_func_export_set::val_str(String* str)
return str;
}
-void Item_func_export_set::fix_length_and_dec()
+bool Item_func_export_set::fix_length_and_dec()
{
uint32 length= MY_MAX(args[1]->max_char_length(), args[2]->max_char_length());
uint32 sep_length= (arg_count > 3 ? args[3]->max_char_length() : 1);
if (agg_arg_charsets_for_string_result(collation,
args + 1, MY_MIN(4, arg_count) - 1))
- return;
+ return TRUE;
fix_char_length(length * 64 + sep_length * 63);
+ return FALSE;
}
@@ -4246,12 +4287,13 @@ bool Item_func_dyncol_create::fix_fields(THD *thd, Item **ref)
}
-void Item_func_dyncol_create::fix_length_and_dec()
+bool Item_func_dyncol_create::fix_length_and_dec()
{
max_length= MAX_BLOB_WIDTH;
maybe_null= TRUE;
collation.set(&my_charset_bin);
decimals= 0;
+ return FALSE;
}
bool Item_func_dyncol_create::prepare_arguments(THD *thd, bool force_names_arg)
diff --git a/sql/item_strfunc.h b/sql/item_strfunc.h
index c9956ab364e..a908aba2d2f 100644
--- a/sql/item_strfunc.h
+++ b/sql/item_strfunc.h
@@ -145,9 +145,10 @@ class Item_func_md5 :public Item_str_ascii_checksum_func
public:
Item_func_md5(THD *thd, Item *a): Item_str_ascii_checksum_func(thd, a) {}
String *val_str_ascii(String *);
- void fix_length_and_dec()
+ bool fix_length_and_dec()
{
fix_length_and_charset(32, default_charset());
+ return FALSE;
}
const char *func_name() const { return "md5"; }
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
@@ -160,7 +161,7 @@ class Item_func_sha :public Item_str_ascii_checksum_func
public:
Item_func_sha(THD *thd, Item *a): Item_str_ascii_checksum_func(thd, a) {}
String *val_str_ascii(String *);
- void fix_length_and_dec();
+ bool fix_length_and_dec();
const char *func_name() const { return "sha"; }
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
{ return get_item_copy<Item_func_sha>(thd, mem_root, this); }
@@ -172,7 +173,7 @@ class Item_func_sha2 :public Item_str_ascii_checksum_func
Item_func_sha2(THD *thd, Item *a, Item *b)
:Item_str_ascii_checksum_func(thd, a, b) {}
String *val_str_ascii(String *);
- void fix_length_and_dec();
+ bool fix_length_and_dec();
const char *func_name() const { return "sha2"; }
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
{ return get_item_copy<Item_func_sha2>(thd, mem_root, this); }
@@ -185,7 +186,7 @@ class Item_func_to_base64 :public Item_str_ascii_checksum_func
Item_func_to_base64(THD *thd, Item *a)
:Item_str_ascii_checksum_func(thd, a) {}
String *val_str_ascii(String *);
- void fix_length_and_dec();
+ bool fix_length_and_dec();
const char *func_name() const { return "to_base64"; }
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
{ return get_item_copy<Item_func_to_base64>(thd, mem_root, this); }
@@ -198,7 +199,7 @@ class Item_func_from_base64 :public Item_str_binary_checksum_func
Item_func_from_base64(THD *thd, Item *a)
:Item_str_binary_checksum_func(thd, a) { }
String *val_str(String *);
- void fix_length_and_dec();
+ bool fix_length_and_dec();
const char *func_name() const { return "from_base64"; }
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
{ return get_item_copy<Item_func_from_base64>(thd, mem_root, this); }
@@ -225,7 +226,7 @@ class Item_func_aes_encrypt :public Item_aes_crypt
public:
Item_func_aes_encrypt(THD *thd, Item *a, Item *b)
:Item_aes_crypt(thd, a, b) {}
- void fix_length_and_dec();
+ bool fix_length_and_dec();
const char *func_name() const { return "aes_encrypt"; }
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
{ return get_item_copy<Item_func_aes_encrypt>(thd, mem_root, this); }
@@ -236,7 +237,7 @@ class Item_func_aes_decrypt :public Item_aes_crypt
public:
Item_func_aes_decrypt(THD *thd, Item *a, Item *b):
Item_aes_crypt(thd, a, b) {}
- void fix_length_and_dec();
+ bool fix_length_and_dec();
const char *func_name() const { return "aes_decrypt"; }
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
{ return get_item_copy<Item_func_aes_decrypt>(thd, mem_root, this); }
@@ -251,7 +252,7 @@ class Item_func_concat :public Item_str_func
Item_func_concat(THD *thd, List<Item> &list): Item_str_func(thd, list) {}
Item_func_concat(THD *thd, Item *a, Item *b): Item_str_func(thd, a, b) {}
String *val_str(String *);
- void fix_length_and_dec();
+ bool fix_length_and_dec();
const char *func_name() const { return "concat"; }
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
{ return get_item_copy<Item_func_concat>(thd, mem_root, this); }
@@ -263,11 +264,12 @@ class Item_func_decode_histogram :public Item_str_func
Item_func_decode_histogram(THD *thd, Item *a, Item *b):
Item_str_func(thd, a, b) {}
String *val_str(String *);
- void fix_length_and_dec()
+ bool fix_length_and_dec()
{
collation.set(system_charset_info);
max_length= MAX_BLOB_WIDTH;
maybe_null= 1;
+ return FALSE;
}
const char *func_name() const { return "decode_histogram"; }
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
@@ -280,7 +282,7 @@ class Item_func_concat_ws :public Item_str_func
public:
Item_func_concat_ws(THD *thd, List<Item> &list): Item_str_func(thd, list) {}
String *val_str(String *);
- void fix_length_and_dec();
+ bool fix_length_and_dec();
const char *func_name() const { return "concat_ws"; }
table_map not_null_tables() const { return 0; }
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
@@ -293,7 +295,7 @@ class Item_func_reverse :public Item_str_func
public:
Item_func_reverse(THD *thd, Item *a): Item_str_func(thd, a) {}
String *val_str(String *);
- void fix_length_and_dec();
+ bool fix_length_and_dec();
const char *func_name() const { return "reverse"; }
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
{ return get_item_copy<Item_func_reverse>(thd, mem_root, this); }
@@ -307,7 +309,7 @@ class Item_func_replace :public Item_str_func
Item_func_replace(THD *thd, Item *org, Item *find, Item *replace):
Item_str_func(thd, org, find, replace) {}
String *val_str(String *);
- void fix_length_and_dec();
+ bool fix_length_and_dec();
const char *func_name() const { return "replace"; }
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
{ return get_item_copy<Item_func_replace>(thd, mem_root, this); }
@@ -333,7 +335,7 @@ class Item_func_regexp_replace :public Item_str_func
}
String *val_str(String *str);
bool fix_fields(THD *thd, Item **ref);
- void fix_length_and_dec();
+ bool fix_length_and_dec();
const char *func_name() const { return "regexp_replace"; }
Item *get_copy(THD *thd, MEM_ROOT *mem_root) { return 0;}
};
@@ -355,7 +357,7 @@ class Item_func_regexp_substr :public Item_str_func
}
String *val_str(String *str);
bool fix_fields(THD *thd, Item **ref);
- void fix_length_and_dec();
+ bool fix_length_and_dec();
const char *func_name() const { return "regexp_substr"; }
Item *get_copy(THD *thd, MEM_ROOT *mem_root) { return 0; }
};
@@ -369,7 +371,7 @@ class Item_func_insert :public Item_str_func
Item *new_str):
Item_str_func(thd, org, start, length, new_str) {}
String *val_str(String *);
- void fix_length_and_dec();
+ bool fix_length_and_dec();
const char *func_name() const { return "insert"; }
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
{ return get_item_copy<Item_func_insert>(thd, mem_root, this); }
@@ -393,7 +395,7 @@ class Item_func_lcase :public Item_str_conv
public:
Item_func_lcase(THD *thd, Item *item): Item_str_conv(thd, item) {}
const char *func_name() const { return "lcase"; }
- void fix_length_and_dec();
+ bool fix_length_and_dec();
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
{ return get_item_copy<Item_func_lcase>(thd, mem_root, this); }
};
@@ -403,7 +405,7 @@ class Item_func_ucase :public Item_str_conv
public:
Item_func_ucase(THD *thd, Item *item): Item_str_conv(thd, item) {}
const char *func_name() const { return "ucase"; }
- void fix_length_and_dec();
+ bool fix_length_and_dec();
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
{ return get_item_copy<Item_func_ucase>(thd, mem_root, this); }
};
@@ -415,7 +417,7 @@ class Item_func_left :public Item_str_func
public:
Item_func_left(THD *thd, Item *a, Item *b): Item_str_func(thd, a, b) {}
String *val_str(String *);
- void fix_length_and_dec();
+ bool fix_length_and_dec();
const char *func_name() const { return "left"; }
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
{ return get_item_copy<Item_func_left>(thd, mem_root, this); }
@@ -428,7 +430,7 @@ class Item_func_right :public Item_str_func
public:
Item_func_right(THD *thd, Item *a, Item *b): Item_str_func(thd, a, b) {}
String *val_str(String *);
- void fix_length_and_dec();
+ bool fix_length_and_dec();
const char *func_name() const { return "right"; }
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
{ return get_item_copy<Item_func_right>(thd, mem_root, this); }
@@ -442,7 +444,7 @@ class Item_func_substr :public Item_str_func
Item_func_substr(THD *thd, Item *a, Item *b): Item_str_func(thd, a, b) {}
Item_func_substr(THD *thd, Item *a, Item *b, Item *c): Item_str_func(thd, a, b, c) {}
String *val_str(String *);
- void fix_length_and_dec();
+ bool fix_length_and_dec();
const char *func_name() const { return "substr"; }
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
{ return get_item_copy<Item_func_substr>(thd, mem_root, this); }
@@ -456,7 +458,7 @@ class Item_func_substr_index :public Item_str_func
Item_func_substr_index(THD *thd, Item *a,Item *b,Item *c):
Item_str_func(thd, a, b, c) {}
String *val_str(String *);
- void fix_length_and_dec();
+ bool fix_length_and_dec();
const char *func_name() const { return "substring_index"; }
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
{ return get_item_copy<Item_func_substr_index>(thd, mem_root, this); }
@@ -488,7 +490,7 @@ class Item_func_trim :public Item_str_func
Item_func_trim(THD *thd, Item *a, Item *b): Item_str_func(thd, a, b) {}
Item_func_trim(THD *thd, Item *a): Item_str_func(thd, a) {}
String *val_str(String *);
- void fix_length_and_dec();
+ bool fix_length_and_dec();
const char *func_name() const { return "trim"; }
void print(String *str, enum_query_type query_type);
virtual const char *mode_name() const { return "both"; }
@@ -546,12 +548,13 @@ class Item_func_password :public Item_str_ascii_checksum_func
Item_str_ascii_checksum_func(thd, a), alg(al), deflt(0) {}
String *val_str_ascii(String *str);
bool fix_fields(THD *thd, Item **ref);
- void fix_length_and_dec()
+ bool fix_length_and_dec()
{
fix_length_and_charset((alg == 1 ?
SCRAMBLED_PASSWORD_CHAR_LENGTH :
SCRAMBLED_PASSWORD_CHAR_LENGTH_323),
default_charset());
+ return FALSE;
}
const char *func_name() const { return ((deflt || alg == 1) ?
"password" : "old_password"); }
@@ -572,11 +575,12 @@ class Item_func_des_encrypt :public Item_str_binary_checksum_func
Item_func_des_encrypt(THD *thd, Item *a, Item *b)
:Item_str_binary_checksum_func(thd, a, b) {}
String *val_str(String *);
- void fix_length_and_dec()
+ bool fix_length_and_dec()
{
maybe_null=1;
/* 9 = MAX ((8- (arg_len % 8)) + 1) */
max_length = args[0]->max_length + 9;
+ return FALSE;
}
const char *func_name() const { return "des_encrypt"; }
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
@@ -592,13 +596,14 @@ class Item_func_des_decrypt :public Item_str_binary_checksum_func
Item_func_des_decrypt(THD *thd, Item *a, Item *b)
:Item_str_binary_checksum_func(thd, a, b) {}
String *val_str(String *);
- void fix_length_and_dec()
+ bool fix_length_and_dec()
{
maybe_null=1;
/* 9 = MAX ((8- (arg_len % 8)) + 1) */
max_length= args[0]->max_length;
if (max_length >= 9U)
max_length-= 9U;
+ return FALSE;
}
const char *func_name() const { return "des_decrypt"; }
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
@@ -631,7 +636,7 @@ class Item_func_encrypt :public Item_str_binary_checksum_func
constructor_helper();
}
String *val_str(String *);
- void fix_length_and_dec() { maybe_null=1; max_length = 13; }
+ bool fix_length_and_dec() { maybe_null=1; max_length = 13; return FALSE; }
const char *func_name() const { return "encrypt"; }
bool check_vcol_func_processor(void *arg)
{
@@ -655,7 +660,7 @@ class Item_func_encode :public Item_str_binary_checksum_func
Item_func_encode(THD *thd, Item *a, Item *seed_arg):
Item_str_binary_checksum_func(thd, a, seed_arg) {}
String *val_str(String *);
- void fix_length_and_dec();
+ bool fix_length_and_dec();
const char *func_name() const { return "encode"; }
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
{ return get_item_copy<Item_func_encode>(thd, mem_root, this); }
@@ -705,10 +710,11 @@ class Item_func_database :public Item_func_sysconst
public:
Item_func_database(THD *thd): Item_func_sysconst(thd) {}
String *val_str(String *);
- void fix_length_and_dec()
+ bool fix_length_and_dec()
{
max_length= MAX_FIELD_NAME * system_charset_info->mbmaxlen;
maybe_null=1;
+ return FALSE;
}
const char *func_name() const { return "database"; }
const char *fully_qualified_func_name() const { return "database()"; }
@@ -733,10 +739,11 @@ class Item_func_user :public Item_func_sysconst
return (null_value ? 0 : &str_value);
}
bool fix_fields(THD *thd, Item **ref);
- void fix_length_and_dec()
+ bool fix_length_and_dec()
{
max_length= (uint32) (username_char_length +
HOSTNAME_LENGTH + 1) * SYSTEM_CHARSET_MBMAXLEN;
+ return FALSE;
}
const char *func_name() const { return "user"; }
const char *fully_qualified_func_name() const { return "user()"; }
@@ -776,8 +783,11 @@ class Item_func_current_role :public Item_func_sysconst
Item_func_current_role(THD *thd, Name_resolution_context *context_arg):
Item_func_sysconst(thd), context(context_arg) {}
bool fix_fields(THD *thd, Item **ref);
- void fix_length_and_dec()
- { max_length= (uint32) username_char_length * SYSTEM_CHARSET_MBMAXLEN; }
+ bool fix_length_and_dec()
+ {
+ max_length= (uint32) username_char_length * SYSTEM_CHARSET_MBMAXLEN;
+ return FALSE;
+ }
int save_in_field(Field *field, bool no_conversions)
{ return save_str_value_in_field(field, &str_value); }
const char *func_name() const { return "current_role"; }
@@ -805,7 +815,7 @@ class Item_func_soundex :public Item_str_func
public:
Item_func_soundex(THD *thd, Item *a): Item_str_func(thd, a) {}
String *val_str(String *);
- void fix_length_and_dec();
+ bool fix_length_and_dec();
const char *func_name() const { return "soundex"; }
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
{ return get_item_copy<Item_func_soundex>(thd, mem_root, this); }
@@ -819,7 +829,7 @@ class Item_func_elt :public Item_str_func
double val_real();
longlong val_int();
String *val_str(String *str);
- void fix_length_and_dec();
+ bool fix_length_and_dec();
const char *func_name() const { return "elt"; }
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
{ return get_item_copy<Item_func_elt>(thd, mem_root, this); }
@@ -833,7 +843,7 @@ class Item_func_make_set :public Item_str_func
public:
Item_func_make_set(THD *thd, List<Item> &list): Item_str_func(thd, list) {}
String *val_str(String *str);
- void fix_length_and_dec();
+ bool fix_length_and_dec();
const char *func_name() const { return "make_set"; }
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
{ return get_item_copy<Item_func_make_set>(thd, mem_root, this); }
@@ -851,7 +861,7 @@ class Item_func_format :public Item_str_ascii_func
MY_LOCALE *get_locale(Item *item);
String *val_str_ascii(String *);
- void fix_length_and_dec();
+ bool fix_length_and_dec();
const char *func_name() const { return "format"; }
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
{ return get_item_copy<Item_func_format>(thd, mem_root, this); }
@@ -867,9 +877,10 @@ class Item_func_char :public Item_str_func
Item_str_func(thd, list)
{ collation.set(cs); }
String *val_str(String *);
- void fix_length_and_dec()
+ bool fix_length_and_dec()
{
max_length= arg_count * 4;
+ return FALSE;
}
const char *func_name() const { return "char"; }
void print(String *str, enum_query_type query_type);
@@ -885,7 +896,7 @@ class Item_func_repeat :public Item_str_func
Item_func_repeat(THD *thd, Item *arg1, Item *arg2):
Item_str_func(thd, arg1, arg2) {}
String *val_str(String *);
- void fix_length_and_dec();
+ bool fix_length_and_dec();
const char *func_name() const { return "repeat"; }
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
{ return get_item_copy<Item_func_repeat>(thd, mem_root, this); }
@@ -897,7 +908,7 @@ class Item_func_space :public Item_str_func
public:
Item_func_space(THD *thd, Item *arg1): Item_str_func(thd, arg1) {}
String *val_str(String *);
- void fix_length_and_dec();
+ bool fix_length_and_dec();
const char *func_name() const { return "space"; }
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
{ return get_item_copy<Item_func_space>(thd, mem_root, this); }
@@ -910,7 +921,7 @@ class Item_func_binlog_gtid_pos :public Item_str_func
Item_func_binlog_gtid_pos(THD *thd, Item *arg1, Item *arg2):
Item_str_func(thd, arg1, arg2) {}
String *val_str(String *);
- void fix_length_and_dec();
+ bool fix_length_and_dec();
const char *func_name() const { return "binlog_gtid_pos"; }
bool check_vcol_func_processor(void *arg)
{
@@ -928,7 +939,7 @@ class Item_func_rpad :public Item_str_func
Item_func_rpad(THD *thd, Item *arg1, Item *arg2, Item *arg3):
Item_str_func(thd, arg1, arg2, arg3) {}
String *val_str(String *);
- void fix_length_and_dec();
+ bool fix_length_and_dec();
const char *func_name() const { return "rpad"; }
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
{ return get_item_copy<Item_func_rpad>(thd, mem_root, this); }
@@ -942,7 +953,7 @@ class Item_func_lpad :public Item_str_func
Item_func_lpad(THD *thd, Item *arg1, Item *arg2, Item *arg3):
Item_str_func(thd, arg1, arg2, arg3) {}
String *val_str(String *);
- void fix_length_and_dec();
+ bool fix_length_and_dec();
const char *func_name() const { return "lpad"; }
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
{ return get_item_copy<Item_func_lpad>(thd, mem_root, this); }
@@ -956,11 +967,12 @@ class Item_func_conv :public Item_str_func
Item_str_func(thd, a, b, c) {}
const char *func_name() const { return "conv"; }
String *val_str(String *);
- void fix_length_and_dec()
+ bool fix_length_and_dec()
{
collation.set(default_charset());
max_length=64;
maybe_null= 1;
+ return FALSE;
}
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
{ return get_item_copy<Item_func_conv>(thd, mem_root, this); }
@@ -975,11 +987,12 @@ class Item_func_hex :public Item_str_ascii_checksum_func
Item_str_ascii_checksum_func(thd, a) {}
const char *func_name() const { return "hex"; }
String *val_str_ascii(String *);
- void fix_length_and_dec()
+ bool fix_length_and_dec()
{
collation.set(default_charset());
decimals=0;
fix_char_length(args[0]->max_length * 2);
+ return FALSE;
}
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
{ return get_item_copy<Item_func_hex>(thd, mem_root, this); }
@@ -996,11 +1009,12 @@ class Item_func_unhex :public Item_str_func
}
const char *func_name() const { return "unhex"; }
String *val_str(String *);
- void fix_length_and_dec()
+ bool fix_length_and_dec()
{
collation.set(&my_charset_bin);
decimals=0;
max_length=(1+args[0]->max_length)/2;
+ return FALSE;
}
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
{ return get_item_copy<Item_func_unhex>(thd, mem_root, this); }
@@ -1019,11 +1033,12 @@ class Item_func_like_range :public Item_str_func
Item_str_func(thd, a, b), is_min(is_min_arg)
{ maybe_null= 1; }
String *val_str(String *);
- void fix_length_and_dec()
+ bool fix_length_and_dec()
{
collation.set(args[0]->collation);
decimals=0;
max_length= MAX_BLOB_WIDTH;
+ return FALSE;
}
};
@@ -1064,10 +1079,11 @@ class Item_func_binary :public Item_str_func
tmp->set_charset(&my_charset_bin);
return tmp;
}
- void fix_length_and_dec()
+ bool fix_length_and_dec()
{
collation.set(&my_charset_bin);
max_length=args[0]->max_length;
+ return FALSE;
}
void print(String *str, enum_query_type query_type);
const char *func_name() const { return "cast_as_binary"; }
@@ -1084,11 +1100,12 @@ class Item_load_file :public Item_str_func
Item_load_file(THD *thd, Item *a): Item_str_func(thd, a) {}
String *val_str(String *);
const char *func_name() const { return "load_file"; }
- void fix_length_and_dec()
+ bool fix_length_and_dec()
{
collation.set(&my_charset_bin, DERIVATION_COERCIBLE);
maybe_null=1;
max_length=MAX_BLOB_WIDTH;
+ return FALSE;
}
bool check_vcol_func_processor(void *arg)
{
@@ -1109,7 +1126,7 @@ class Item_func_export_set: public Item_str_func
Item_func_export_set(THD *thd, Item *a, Item *b, Item* c, Item* d, Item* e):
Item_str_func(thd, a, b, c, d, e) {}
String *val_str(String *str);
- void fix_length_and_dec();
+ bool fix_length_and_dec();
const char *func_name() const { return "export_set"; }
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
{ return get_item_copy<Item_func_export_set>(thd, mem_root, this); }
@@ -1123,12 +1140,13 @@ class Item_func_quote :public Item_str_func
Item_func_quote(THD *thd, Item *a): Item_str_func(thd, a) {}
const char *func_name() const { return "quote"; }
String *val_str(String *);
- void fix_length_and_dec()
+ bool fix_length_and_dec()
{
collation.set(args[0]->collation);
ulonglong max_result_length= (ulonglong) args[0]->max_length * 2 +
2 * collation.collation->mbmaxlen;
max_length= (uint32) MY_MIN(max_result_length, MAX_BLOB_WIDTH);
+ return FALSE;
}
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
{ return get_item_copy<Item_func_quote>(thd, mem_root, this); }
@@ -1211,7 +1229,7 @@ class Item_func_conv_charset :public Item_str_func
return 1;
return res;
}
- void fix_length_and_dec();
+ bool fix_length_and_dec();
const char *func_name() const { return "convert"; }
void print(String *str, enum_query_type query_type);
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
@@ -1224,7 +1242,7 @@ class Item_func_set_collation :public Item_str_func
Item_func_set_collation(THD *thd, Item *a, Item *b):
Item_str_func(thd, a, b) {}
String *val_str(String *);
- void fix_length_and_dec();
+ bool fix_length_and_dec();
bool eq(const Item *item, bool binary_cmp) const;
const char *func_name() const { return "collate"; }
enum precedence precedence() const { return COLLATE_PRECEDENCE; }
@@ -1245,11 +1263,12 @@ class Item_func_expr_str_metadata :public Item_str_func
{
public:
Item_func_expr_str_metadata(THD *thd, Item *a): Item_str_func(thd, a) { }
- void fix_length_and_dec()
+ bool fix_length_and_dec()
{
collation.set(system_charset_info);
max_length= 64 * collation.collation->mbmaxlen; // should be enough
maybe_null= 0;
+ return FALSE;
};
table_map not_null_tables() const { return 0; }
Item* propagate_equal_fields(THD *thd, const Context &ctx, COND_EQUAL *cond)
@@ -1299,7 +1318,7 @@ class Item_func_weight_string :public Item_str_func
}
const char *func_name() const { return "weight_string"; }
String *val_str(String *);
- void fix_length_and_dec();
+ bool fix_length_and_dec();
bool eq(const Item *item, bool binary_cmp) const
{
if (!Item_str_func::eq(item, binary_cmp))
@@ -1323,7 +1342,7 @@ class Item_func_crc32 :public Item_int_func
Item_func_crc32(THD *thd, Item *a): Item_int_func(thd, a)
{ unsigned_flag= 1; }
const char *func_name() const { return "crc32"; }
- void fix_length_and_dec() { max_length=10; }
+ bool fix_length_and_dec() { max_length=10; return FALSE; }
longlong val_int();
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
{ return get_item_copy<Item_func_crc32>(thd, mem_root, this); }
@@ -1335,7 +1354,7 @@ class Item_func_uncompressed_length : public Item_int_func
public:
Item_func_uncompressed_length(THD *thd, Item *a): Item_int_func(thd, a) {}
const char *func_name() const{return "uncompressed_length";}
- void fix_length_and_dec() { max_length=10; maybe_null= true; }
+ bool fix_length_and_dec() { max_length=10; maybe_null= true; return FALSE; }
longlong val_int();
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
{ return get_item_copy<Item_func_uncompressed_length>(thd, mem_root, this); }
@@ -1353,7 +1372,11 @@ class Item_func_compress: public Item_str_binary_checksum_func
public:
Item_func_compress(THD *thd, Item *a)
:Item_str_binary_checksum_func(thd, a) {}
- void fix_length_and_dec(){max_length= (args[0]->max_length*120)/100+12;}
+ bool fix_length_and_dec()
+ {
+ max_length= (args[0]->max_length * 120) / 100 + 12;
+ return FALSE;
+ }
const char *func_name() const{return "compress";}
String *val_str(String *) ZLIB_DEPENDED_FUNCTION
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
@@ -1366,7 +1389,11 @@ class Item_func_uncompress: public Item_str_binary_checksum_func
public:
Item_func_uncompress(THD *thd, Item *a)
:Item_str_binary_checksum_func(thd, a) {}
- void fix_length_and_dec(){ maybe_null= 1; max_length= MAX_BLOB_WIDTH; }
+ bool fix_length_and_dec()
+ {
+ maybe_null= 1; max_length= MAX_BLOB_WIDTH;
+ return FALSE;
+ }
const char *func_name() const{return "uncompress";}
String *val_str(String *) ZLIB_DEPENDED_FUNCTION
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
@@ -1378,11 +1405,12 @@ class Item_func_uuid: public Item_str_func
{
public:
Item_func_uuid(THD *thd): Item_str_func(thd) {}
- void fix_length_and_dec()
+ bool fix_length_and_dec()
{
collation.set(system_charset_info,
DERIVATION_COERCIBLE, MY_REPERTOIRE_ASCII);
fix_char_length(MY_UUID_STRING_LENGTH);
+ return FALSE;
}
bool const_item() const { return false; }
table_map used_tables() const { return RAND_TABLE_BIT; }
@@ -1410,7 +1438,7 @@ class Item_func_dyncol_create: public Item_str_func
public:
Item_func_dyncol_create(THD *thd, List<Item> &args, DYNCALL_CREATE_DEF *dfs);
bool fix_fields(THD *thd, Item **ref);
- void fix_length_and_dec();
+ bool fix_length_and_dec();
const char *func_name() const{ return "column_create"; }
String *val_str(String *);
void print(String *str, enum_query_type query_type);
@@ -1440,11 +1468,12 @@ class Item_func_dyncol_json: public Item_str_func
{collation.set(DYNCOL_UTF);}
const char *func_name() const{ return "column_json"; }
String *val_str(String *);
- void fix_length_and_dec()
+ bool fix_length_and_dec()
{
max_length= MAX_BLOB_WIDTH;
maybe_null= 1;
decimals= 0;
+ return FALSE;
}
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
{ return get_item_copy<Item_func_dyncol_json>(thd, mem_root, this); }
@@ -1459,8 +1488,8 @@ class Item_dyncol_get: public Item_str_func
public:
Item_dyncol_get(THD *thd, Item *str, Item *num): Item_str_func(thd, str, num)
{}
- void fix_length_and_dec()
- { maybe_null= 1;; max_length= MAX_BLOB_WIDTH; }
+ bool fix_length_and_dec()
+ { maybe_null= 1;; max_length= MAX_BLOB_WIDTH; return FALSE; }
/* Mark that collation can change between calls */
bool dynamic_result() { return 1; }
@@ -1498,7 +1527,8 @@ class Item_func_dyncol_list: public Item_str_func
public:
Item_func_dyncol_list(THD *thd, Item *str): Item_str_func(thd, str)
{collation.set(DYNCOL_UTF);}
- void fix_length_and_dec() { maybe_null= 1; max_length= MAX_BLOB_WIDTH; };
+ bool fix_length_and_dec()
+ { maybe_null= 1; max_length= MAX_BLOB_WIDTH; return FALSE; };
const char *func_name() const{ return "column_list"; }
String *val_str(String *);
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
diff --git a/sql/item_subselect.cc b/sql/item_subselect.cc
index 4214980c36c..ca49e06a9e7 100644
--- a/sql/item_subselect.cc
+++ b/sql/item_subselect.cc
@@ -307,7 +307,8 @@ bool Item_subselect::fix_fields(THD *thd_param, Item **ref)
goto end;
}
- fix_length_and_dec();
+ if (fix_length_and_dec())
+ goto end;
}
else
goto end;
@@ -904,9 +905,10 @@ Item::Type Item_subselect::type() const
}
-void Item_subselect::fix_length_and_dec()
+bool Item_subselect::fix_length_and_dec()
{
engine->fix_length_and_dec(0);
+ return FALSE;
}
@@ -1194,7 +1196,7 @@ enum_field_types Item_singlerow_subselect::field_type() const
return engine->field_type();
}
-void Item_singlerow_subselect::fix_length_and_dec()
+bool Item_singlerow_subselect::fix_length_and_dec()
{
if ((max_columns= engine->cols()) == 1)
{
@@ -1204,7 +1206,7 @@ void Item_singlerow_subselect::fix_length_and_dec()
{
if (!(row= (Item_cache**) current_thd->alloc(sizeof(Item_cache*) *
max_columns)))
- return;
+ return TRUE;
engine->fix_length_and_dec(row);
value= *row;
}
@@ -1221,6 +1223,7 @@ void Item_singlerow_subselect::fix_length_and_dec()
for (uint i= 0; i < max_columns; i++)
row[i]->maybe_null= TRUE;
}
+ return FALSE;
}
@@ -1505,7 +1508,7 @@ void Item_exists_subselect::init_length_and_dec()
}
-void Item_exists_subselect::fix_length_and_dec()
+bool Item_exists_subselect::fix_length_and_dec()
{
DBUG_ENTER("Item_exists_subselect::fix_length_and_dec");
init_length_and_dec();
@@ -1516,11 +1519,11 @@ void Item_exists_subselect::fix_length_and_dec()
thd->change_item_tree(&unit->global_parameters()->select_limit,
new (thd->mem_root) Item_int(thd, (int32) 1));
DBUG_PRINT("info", ("Set limit to 1"));
- DBUG_VOID_RETURN;
+ DBUG_RETURN(FALSE);
}
-void Item_in_subselect::fix_length_and_dec()
+bool Item_in_subselect::fix_length_and_dec()
{
DBUG_ENTER("Item_in_subselect::fix_length_and_dec");
init_length_and_dec();
@@ -1528,7 +1531,7 @@ void Item_in_subselect::fix_length_and_dec()
Unlike Item_exists_subselect, LIMIT 1 is set later for
Item_in_subselect, depending on the chosen strategy.
*/
- DBUG_VOID_RETURN;
+ DBUG_RETURN(FALSE);
}
diff --git a/sql/item_subselect.h b/sql/item_subselect.h
index 7e99e2c3075..f44a5c4d0ce 100644
--- a/sql/item_subselect.h
+++ b/sql/item_subselect.h
@@ -196,7 +196,7 @@ class Item_subselect :public Item_result_field,
const_item_cache= 0;
forced_const= TRUE;
}
- virtual void fix_length_and_dec();
+ virtual bool fix_length_and_dec();
table_map used_tables() const;
table_map not_null_tables() const { return 0; }
bool const_item() const;
@@ -306,7 +306,7 @@ class Item_singlerow_subselect :public Item_subselect
enum Item_result result_type() const;
enum Item_result cmp_type() const;
enum_field_types field_type() const;
- void fix_length_and_dec();
+ bool fix_length_and_dec();
uint cols();
Item* element_index(uint i) { return reinterpret_cast<Item*>(row[i]); }
@@ -403,7 +403,7 @@ class Item_exists_subselect :public Item_subselect
my_decimal *val_decimal(my_decimal *);
bool val_bool();
bool fix_fields(THD *thd, Item **ref);
- void fix_length_and_dec();
+ bool fix_length_and_dec();
void print(String *str, enum_query_type query_type);
bool select_transformer(JOIN *join);
void top_level_item() { abort_on_null=1; }
@@ -626,7 +626,7 @@ class Item_in_subselect :public Item_exists_subselect
void print(String *str, enum_query_type query_type);
enum precedence precedence() const { return CMP_PRECEDENCE; }
bool fix_fields(THD *thd, Item **ref);
- void fix_length_and_dec();
+ bool fix_length_and_dec();
void fix_after_pullout(st_select_lex *new_parent, Item **ref, bool merge);
bool const_item() const
{
diff --git a/sql/item_sum.cc b/sql/item_sum.cc
index 94569aa66c9..9da0d9acce5 100644
--- a/sql/item_sum.cc
+++ b/sql/item_sum.cc
@@ -1131,9 +1131,8 @@ Item_sum_num::fix_fields(THD *thd, Item **ref)
result_field=0;
max_length=float_length(decimals);
null_value=1;
- fix_length_and_dec();
-
- if (check_sum_func(thd, ref))
+ if (fix_length_and_dec() ||
+ check_sum_func(thd, ref))
return TRUE;
memcpy (orig_args, args, sizeof (Item *) * arg_count);
@@ -1187,9 +1186,8 @@ Item_sum_hybrid::fix_fields(THD *thd, Item **ref)
maybe_null= 1;
result_field=0;
null_value=1;
- fix_length_and_dec();
-
- if (check_sum_func(thd, ref))
+ if (fix_length_and_dec() ||
+ check_sum_func(thd, ref))
return TRUE;
orig_args[0]= args[0];
@@ -1327,7 +1325,7 @@ void Item_sum_sum::clear()
}
-void Item_sum_sum::fix_length_and_dec()
+bool Item_sum_sum::fix_length_and_dec()
{
DBUG_ENTER("Item_sum_sum::fix_length_and_dec");
maybe_null=null_value=1;
@@ -1362,7 +1360,7 @@ void Item_sum_sum::fix_length_and_dec()
"--ILLEGAL!!!--"),
max_length,
(int)decimals));
- DBUG_VOID_RETURN;
+ DBUG_RETURN(FALSE);
}
@@ -1662,9 +1660,10 @@ void Item_sum_count::cleanup()
/*
Avgerage
*/
-void Item_sum_avg::fix_length_and_dec()
+bool Item_sum_avg::fix_length_and_dec()
{
- Item_sum_sum::fix_length_and_dec();
+ if (Item_sum_sum::fix_length_and_dec())
+ return TRUE;
maybe_null=null_value=1;
prec_increment= current_thd->variables.div_precincrement;
if (Item_sum_avg::result_type() == DECIMAL_RESULT)
@@ -1684,6 +1683,7 @@ void Item_sum_avg::fix_length_and_dec()
FLOATING_POINT_DECIMALS);
max_length= MY_MIN(args[0]->max_length + prec_increment, float_length(decimals));
}
+ return FALSE;
}
@@ -1882,7 +1882,7 @@ Item_sum_variance::Item_sum_variance(THD *thd, Item_sum_variance *item):
}
-void Item_sum_variance::fix_length_and_dec()
+bool Item_sum_variance::fix_length_and_dec()
{
DBUG_ENTER("Item_sum_variance::fix_length_and_dec");
maybe_null= null_value= 1;
@@ -1917,7 +1917,7 @@ void Item_sum_variance::fix_length_and_dec()
DBUG_ASSERT(0);
}
DBUG_PRINT("info", ("Type: REAL_RESULT (%d, %d)", max_length, (int)decimals));
- DBUG_VOID_RETURN;
+ DBUG_RETURN(FALSE);
}
@@ -2987,13 +2987,13 @@ my_decimal *Item_sum_udf_int::val_decimal(my_decimal *dec)
/** Default max_length is max argument length. */
-void Item_sum_udf_str::fix_length_and_dec()
+bool Item_sum_udf_str::fix_length_and_dec()
{
DBUG_ENTER("Item_sum_udf_str::fix_length_and_dec");
max_length=0;
for (uint i = 0; i < arg_count; i++)
set_if_bigger(max_length,args[i]->max_length);
- DBUG_VOID_RETURN;
+ DBUG_RETURN(FALSE);
}
diff --git a/sql/item_sum.h b/sql/item_sum.h
index 5c446e5779d..5c8ff520259 100644
--- a/sql/item_sum.h
+++ b/sql/item_sum.h
@@ -457,7 +457,8 @@ class Item_sum :public Item_func_or_sum
*/
virtual void update_field()=0;
virtual bool keep_field_type(void) const { return 0; }
- virtual void fix_length_and_dec() { maybe_null=1; null_value=1; }
+ virtual bool fix_length_and_dec()
+ { maybe_null=1; null_value=1; return FALSE; }
virtual Item *result_item(THD *thd, Field *field);
void update_used_tables ();
@@ -752,8 +753,8 @@ class Item_sum_int :public Item_sum_num
my_decimal *val_decimal(my_decimal *);
enum Item_result result_type () const { return INT_RESULT; }
enum_field_types field_type() const { return MYSQL_TYPE_LONGLONG; }
- void fix_length_and_dec()
- { decimals=0; max_length=21; maybe_null=null_value=0; }
+ bool fix_length_and_dec()
+ { decimals=0; max_length=21; maybe_null=null_value=0; return FALSE; }
};
@@ -764,7 +765,7 @@ class Item_sum_sum :public Item_sum_num,
double sum;
my_decimal dec_buffs[2];
uint curr_dec_buff;
- void fix_length_and_dec();
+ bool fix_length_and_dec();
public:
Item_sum_sum(THD *thd, Item *item_par, bool distinct):
@@ -888,7 +889,7 @@ class Item_sum_avg :public Item_sum_sum
:Item_sum_sum(thd, item), count(item->count),
prec_increment(item->prec_increment) {}
- void fix_length_and_dec();
+ bool fix_length_and_dec();
enum Sumfunctype sum_func () const
{
return has_with_distinct() ? AVG_DISTINCT_FUNC : AVG_FUNC;
@@ -948,7 +949,7 @@ But, this falls prey to catastrophic cancellation. Instead, use the recurrence
class Item_sum_variance : public Item_sum_num
{
- void fix_length_and_dec();
+ bool fix_length_and_dec();
public:
double recurrence_m, recurrence_s; /* Used in recurrence relation. */
@@ -1110,8 +1111,11 @@ class Item_sum_bit :public Item_sum_int
longlong val_int();
void reset_field();
void update_field();
- void fix_length_and_dec()
- { decimals= 0; max_length=21; unsigned_flag= 1; maybe_null= null_value= 0; }
+ bool fix_length_and_dec()
+ {
+ decimals= 0; max_length=21; unsigned_flag= 1; maybe_null= null_value= 0;
+ return FALSE;
+ }
void cleanup()
{
bits= reset_bits;
@@ -1401,7 +1405,7 @@ class Item_sum_udf_float :public Item_udf_sum
enum Item_result result_type () const { return REAL_RESULT; }
enum Item_result cmp_type () const { return REAL_RESULT; }
enum_field_types field_type() const { return MYSQL_TYPE_DOUBLE; }
- void fix_length_and_dec() { fix_num_length_and_dec(); }
+ bool fix_length_and_dec() { fix_num_length_and_dec(); return FALSE; }
Item *copy_or_same(THD* thd);
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
{ return get_item_copy<Item_sum_udf_float>(thd, mem_root, this); }
@@ -1424,7 +1428,7 @@ class Item_sum_udf_int :public Item_udf_sum
my_decimal *val_decimal(my_decimal *);
enum Item_result result_type () const { return INT_RESULT; }
enum_field_types field_type() const { return MYSQL_TYPE_LONGLONG; }
- void fix_length_and_dec() { decimals=0; max_length=21; }
+ bool fix_length_and_dec() { decimals=0; max_length=21; return FALSE; }
Item *copy_or_same(THD* thd);
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
{ return get_item_copy<Item_sum_udf_int>(thd, mem_root, this); }
@@ -1466,7 +1470,7 @@ class Item_sum_udf_str :public Item_udf_sum
my_decimal *val_decimal(my_decimal *dec);
enum Item_result result_type () const { return STRING_RESULT; }
enum_field_types field_type() const { return string_field_type(); }
- void fix_length_and_dec();
+ bool fix_length_and_dec();
Item *copy_or_same(THD* thd);
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
{ return get_item_copy<Item_sum_udf_str>(thd, mem_root, this); }
@@ -1488,7 +1492,7 @@ class Item_sum_udf_decimal :public Item_udf_sum
my_decimal *val_decimal(my_decimal *);
enum Item_result result_type () const { return DECIMAL_RESULT; }
enum_field_types field_type() const { return MYSQL_TYPE_NEWDECIMAL; }
- void fix_length_and_dec() { fix_num_length_and_dec(); }
+ bool fix_length_and_dec() { fix_num_length_and_dec(); return FALSE; }
Item *copy_or_same(THD* thd);
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
{ return get_item_copy<Item_sum_udf_decimal>(thd, mem_root, this); }
@@ -1563,7 +1567,7 @@ class Item_sum_udf_str :public Item_sum_num
double val_real() { DBUG_ASSERT(fixed == 1); null_value=1; return 0.0; }
longlong val_int() { DBUG_ASSERT(fixed == 1); null_value=1; return 0; }
enum Item_result result_type () const { return STRING_RESULT; }
- void fix_length_and_dec() { maybe_null=1; max_length=0; }
+ bool fix_length_and_dec() { maybe_null=1; max_length=0; return FALSE; }
enum Sumfunctype sum_func () const { return UDF_SUM_FUNC; }
void clear() {}
bool add() { return 0; }
diff --git a/sql/item_timefunc.cc b/sql/item_timefunc.cc
index 87c6489189c..bb75ad7c28c 100644
--- a/sql/item_timefunc.cc
+++ b/sql/item_timefunc.cc
@@ -953,7 +953,7 @@ longlong Item_func_month::val_int()
}
-void Item_func_monthname::fix_length_and_dec()
+bool Item_func_monthname::fix_length_and_dec()
{
THD* thd= current_thd;
CHARSET_INFO *cs= thd->variables.collation_connection;
@@ -961,7 +961,8 @@ void Item_func_monthname::fix_length_and_dec()
collation.set(cs, DERIVATION_COERCIBLE, locale->repertoire());
decimals=0;
max_length= locale->max_month_name_length * collation.collation->mbmaxlen;
- maybe_null=1;
+ maybe_null=1;
+ return FALSE;
}
@@ -1101,7 +1102,7 @@ longlong Item_func_weekday::val_int()
odbc_type) + MY_TEST(odbc_type);
}
-void Item_func_dayname::fix_length_and_dec()
+bool Item_func_dayname::fix_length_and_dec()
{
THD* thd= current_thd;
CHARSET_INFO *cs= thd->variables.collation_connection;
@@ -1109,7 +1110,8 @@ void Item_func_dayname::fix_length_and_dec()
collation.set(cs, DERIVATION_COERCIBLE, locale->repertoire());
decimals=0;
max_length= locale->max_day_name_length * collation.collation->mbmaxlen;
- maybe_null=1;
+ maybe_null=1;
+ return FALSE;
}
@@ -1476,7 +1478,7 @@ bool get_interval_value(Item *args,interval_type int_type, INTERVAL *interval)
}
-void Item_temporal_func::fix_length_and_dec()
+bool Item_temporal_func::fix_length_and_dec()
{
uint char_length= mysql_temporal_int_part_length(field_type());
/*
@@ -1502,6 +1504,7 @@ void Item_temporal_func::fix_length_and_dec()
DERIVATION_COERCIBLE : DERIVATION_NUMERIC,
MY_REPERTOIRE_ASCII);
fix_char_length(char_length);
+ return FALSE;
}
String *Item_temporal_func::val_str(String *str)
@@ -1873,7 +1876,7 @@ bool Item_func_sec_to_time::get_date(MYSQL_TIME *ltime, ulonglong fuzzy_date)
return 0;
}
-void Item_func_date_format::fix_length_and_dec()
+bool Item_func_date_format::fix_length_and_dec()
{
THD* thd= current_thd;
locale= thd->variables.lc_time_names;
@@ -1904,6 +1907,7 @@ void Item_func_date_format::fix_length_and_dec()
set_if_smaller(max_length,MAX_BLOB_WIDTH);
}
maybe_null=1; // If wrong date
+ return FALSE;
}
@@ -2050,13 +2054,13 @@ String *Item_func_date_format::val_str(String *str)
}
-void Item_func_from_unixtime::fix_length_and_dec()
-{
+bool Item_func_from_unixtime::fix_length_and_dec()
+{
THD *thd= current_thd;
thd->time_zone_used= 1;
tz= thd->variables.time_zone;
decimals= args[0]->decimals;
- Item_temporal_func::fix_length_and_dec();
+ return Item_temporal_func::fix_length_and_dec();
}
@@ -2083,10 +2087,10 @@ bool Item_func_from_unixtime::get_date(MYSQL_TIME *ltime,
}
-void Item_func_convert_tz::fix_length_and_dec()
+bool Item_func_convert_tz::fix_length_and_dec()
{
decimals= args[0]->temporal_precision(MYSQL_TYPE_DATETIME);
- Item_temporal_func::fix_length_and_dec();
+ return Item_temporal_func::fix_length_and_dec();
}
@@ -2135,7 +2139,7 @@ void Item_func_convert_tz::cleanup()
}
-void Item_date_add_interval::fix_length_and_dec()
+bool Item_date_add_interval::fix_length_and_dec()
{
enum_field_types arg0_field_type;
@@ -2190,7 +2194,7 @@ void Item_date_add_interval::fix_length_and_dec()
}
else
decimals= MY_MAX(args[0]->temporal_precision(MYSQL_TYPE_DATETIME), interval_dec);
- Item_temporal_func::fix_length_and_dec();
+ return Item_temporal_func::fix_length_and_dec();
}
@@ -2261,7 +2265,7 @@ void Item_extract::print(String *str, enum_query_type query_type)
str->append(')');
}
-void Item_extract::fix_length_and_dec()
+bool Item_extract::fix_length_and_dec()
{
maybe_null=1; // If wrong date
switch (int_type) {
@@ -2287,6 +2291,7 @@ void Item_extract::fix_length_and_dec()
case INTERVAL_SECOND_MICROSECOND: set_time_length(8); break; // ssffffff
case INTERVAL_LAST: DBUG_ASSERT(0); break; /* purecov: deadcode */
}
+ return FALSE;
}
@@ -2548,7 +2553,7 @@ String *Item_char_typecast::val_str(String *str)
}
-void Item_char_typecast::fix_length_and_dec()
+bool Item_char_typecast::fix_length_and_dec()
{
uint32 char_length;
/*
@@ -2594,6 +2599,7 @@ void Item_char_typecast::fix_length_and_dec()
(cast_cs == &my_charset_bin ? 1 :
args[0]->collation.collation->mbmaxlen));
max_length= char_length * cast_cs->mbmaxlen;
+ return FALSE;
}
@@ -2682,7 +2688,7 @@ bool Item_func_makedate::get_date(MYSQL_TIME *ltime, ulonglong fuzzy_date)
}
-void Item_func_add_time::fix_length_and_dec()
+bool Item_func_add_time::fix_length_and_dec()
{
enum_field_types arg0_field_type;
decimals= MY_MAX(args[0]->decimals, args[1]->decimals);
@@ -2714,7 +2720,7 @@ void Item_func_add_time::fix_length_and_dec()
decimals= MY_MAX(args[0]->temporal_precision(MYSQL_TYPE_TIME),
args[1]->temporal_precision(MYSQL_TYPE_TIME));
}
- Item_temporal_func::fix_length_and_dec();
+ return Item_temporal_func::fix_length_and_dec();
}
/**
@@ -3203,10 +3209,10 @@ get_date_time_result_type(const char *format, uint length)
}
-void Item_func_str_to_date::fix_length_and_dec()
+bool Item_func_str_to_date::fix_length_and_dec()
{
if (agg_arg_charsets(collation, args, 2, MY_COLL_ALLOW_CONV, 1))
- return;
+ return TRUE;
if (collation.collation->mbminlen > 1)
{
#if MYSQL_VERSION_ID > 50500
@@ -3249,7 +3255,7 @@ void Item_func_str_to_date::fix_length_and_dec()
}
}
cached_timestamp_type= mysql_type_to_time_type(field_type());
- Item_temporal_func::fix_length_and_dec();
+ return Item_temporal_func::fix_length_and_dec();
}
diff --git a/sql/item_timefunc.h b/sql/item_timefunc.h
index 354a54a5c1a..c983e1a6f8a 100644
--- a/sql/item_timefunc.h
+++ b/sql/item_timefunc.h
@@ -49,9 +49,10 @@ class Item_func_period_add :public Item_int_func
Item_func_period_add(THD *thd, Item *a, Item *b): Item_int_func(thd, a, b) {}
longlong val_int();
const char *func_name() const { return "period_add"; }
- void fix_length_and_dec()
- {
+ bool fix_length_and_dec()
+ {
max_length=6*MY_CHARSET_BIN_MB_MAXLEN;
+ return FALSE;
}
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
{ return get_item_copy<Item_func_period_add>(thd, mem_root, this); }
@@ -64,10 +65,11 @@ class Item_func_period_diff :public Item_int_func
Item_func_period_diff(THD *thd, Item *a, Item *b): Item_int_func(thd, a, b) {}
longlong val_int();
const char *func_name() const { return "period_diff"; }
- void fix_length_and_dec()
- {
+ bool fix_length_and_dec()
+ {
decimals=0;
max_length=6*MY_CHARSET_BIN_MB_MAXLEN;
+ return FALSE;
}
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
{ return get_item_copy<Item_func_period_diff>(thd, mem_root, this); }
@@ -80,11 +82,12 @@ class Item_func_to_days :public Item_int_func
Item_func_to_days(THD *thd, Item *a): Item_int_func(thd, a) {}
longlong val_int();
const char *func_name() const { return "to_days"; }
- void fix_length_and_dec()
- {
+ bool fix_length_and_dec()
+ {
decimals=0;
max_length=6*MY_CHARSET_BIN_MB_MAXLEN;
- maybe_null=1;
+ maybe_null=1;
+ return FALSE;
}
enum_monotonicity_info get_monotonicity_info() const;
longlong val_int_endpoint(bool left_endp, bool *incl_endp);
@@ -105,11 +108,12 @@ class Item_func_to_seconds :public Item_int_func
Item_func_to_seconds(THD *thd, Item *a): Item_int_func(thd, a) {}
longlong val_int();
const char *func_name() const { return "to_seconds"; }
- void fix_length_and_dec()
- {
+ bool fix_length_and_dec()
+ {
decimals=0;
max_length=6*MY_CHARSET_BIN_MB_MAXLEN;
maybe_null= 1;
+ return FALSE;
}
enum_monotonicity_info get_monotonicity_info() const;
longlong val_int_endpoint(bool left_endp, bool *incl_endp);
@@ -131,11 +135,12 @@ class Item_func_dayofmonth :public Item_int_func
Item_func_dayofmonth(THD *thd, Item *a): Item_int_func(thd, a) {}
longlong val_int();
const char *func_name() const { return "dayofmonth"; }
- void fix_length_and_dec()
- {
+ bool fix_length_and_dec()
+ {
decimals=0;
max_length=2*MY_CHARSET_BIN_MB_MAXLEN;
- maybe_null=1;
+ maybe_null=1;
+ return FALSE;
}
bool check_partition_func_processor(void *int_arg) {return FALSE;}
bool check_vcol_func_processor(void *arg) { return FALSE;}
@@ -167,11 +172,12 @@ class Item_func_month :public Item_func
const char *func_name() const { return "month"; }
enum Item_result result_type () const { return INT_RESULT; }
enum_field_types field_type() const { return MYSQL_TYPE_LONGLONG; }
- void fix_length_and_dec()
- {
+ bool fix_length_and_dec()
+ {
decimals= 0;
fix_char_length(2);
maybe_null=1;
+ return FALSE;
}
bool check_partition_func_processor(void *int_arg) {return FALSE;}
bool check_vcol_func_processor(void *arg) { return FALSE;}
@@ -191,7 +197,7 @@ class Item_func_monthname :public Item_str_func
Item_func_monthname(THD *thd, Item *a): Item_str_func(thd, a) {}
const char *func_name() const { return "monthname"; }
String *val_str(String *str);
- void fix_length_and_dec();
+ bool fix_length_and_dec();
bool check_partition_func_processor(void *int_arg) {return TRUE;}
bool check_valid_arguments_processor(void *int_arg)
{
@@ -212,11 +218,12 @@ class Item_func_dayofyear :public Item_int_func
Item_func_dayofyear(THD *thd, Item *a): Item_int_func(thd, a) {}
longlong val_int();
const char *func_name() const { return "dayofyear"; }
- void fix_length_and_dec()
- {
+ bool fix_length_and_dec()
+ {
decimals= 0;
fix_char_length(3);
maybe_null=1;
+ return FALSE;
}
bool check_partition_func_processor(void *int_arg) {return FALSE;}
bool check_vcol_func_processor(void *arg) { return FALSE;}
@@ -235,11 +242,12 @@ class Item_func_hour :public Item_int_func
Item_func_hour(THD *thd, Item *a): Item_int_func(thd, a) {}
longlong val_int();
const char *func_name() const { return "hour"; }
- void fix_length_and_dec()
+ bool fix_length_and_dec()
{
decimals=0;
max_length=2*MY_CHARSET_BIN_MB_MAXLEN;
maybe_null=1;
+ return FALSE;
}
bool check_partition_func_processor(void *int_arg) {return FALSE;}
bool check_vcol_func_processor(void *arg) { return FALSE;}
@@ -258,11 +266,12 @@ class Item_func_minute :public Item_int_func
Item_func_minute(THD *thd, Item *a): Item_int_func(thd, a) {}
longlong val_int();
const char *func_name() const { return "minute"; }
- void fix_length_and_dec()
+ bool fix_length_and_dec()
{
decimals=0;
max_length=2*MY_CHARSET_BIN_MB_MAXLEN;
maybe_null=1;
+ return FALSE;
}
bool check_partition_func_processor(void *int_arg) {return FALSE;}
bool check_vcol_func_processor(void *arg) { return FALSE;}
@@ -281,11 +290,12 @@ class Item_func_quarter :public Item_int_func
Item_func_quarter(THD *thd, Item *a): Item_int_func(thd, a) {}
longlong val_int();
const char *func_name() const { return "quarter"; }
- void fix_length_and_dec()
- {
+ bool fix_length_and_dec()
+ {
decimals=0;
max_length=1*MY_CHARSET_BIN_MB_MAXLEN;
maybe_null=1;
+ return FALSE;
}
bool check_partition_func_processor(void *int_arg) {return FALSE;}
bool check_vcol_func_processor(void *arg) { return FALSE;}
@@ -304,11 +314,12 @@ class Item_func_second :public Item_int_func
Item_func_second(THD *thd, Item *a): Item_int_func(thd, a) {}
longlong val_int();
const char *func_name() const { return "second"; }
- void fix_length_and_dec()
- {
+ bool fix_length_and_dec()
+ {
decimals=0;
max_length=2*MY_CHARSET_BIN_MB_MAXLEN;
maybe_null=1;
+ return FALSE;
}
bool check_partition_func_processor(void *int_arg) {return FALSE;}
bool check_vcol_func_processor(void *arg) { return FALSE;}
@@ -328,11 +339,12 @@ class Item_func_week :public Item_int_func
Item_func_week(THD *thd, Item *a, Item *b): Item_int_func(thd, a, b) {}
longlong val_int();
const char *func_name() const { return "week"; }
- void fix_length_and_dec()
- {
+ bool fix_length_and_dec()
+ {
decimals=0;
max_length=2*MY_CHARSET_BIN_MB_MAXLEN;
maybe_null=1;
+ return FALSE;
}
bool check_vcol_func_processor(void *arg)
{
@@ -354,11 +366,12 @@ class Item_func_yearweek :public Item_int_func
Item_func_yearweek(THD *thd, Item *a, Item *b): Item_int_func(thd, a, b) {}
longlong val_int();
const char *func_name() const { return "yearweek"; }
- void fix_length_and_dec()
- {
+ bool fix_length_and_dec()
+ {
decimals=0;
max_length=6*MY_CHARSET_BIN_MB_MAXLEN;
maybe_null=1;
+ return FALSE;
}
bool check_partition_func_processor(void *int_arg) {return FALSE;}
bool check_vcol_func_processor(void *arg) { return FALSE;}
@@ -379,11 +392,12 @@ class Item_func_year :public Item_int_func
const char *func_name() const { return "year"; }
enum_monotonicity_info get_monotonicity_info() const;
longlong val_int_endpoint(bool left_endp, bool *incl_endp);
- void fix_length_and_dec()
- {
+ bool fix_length_and_dec()
+ {
decimals=0;
max_length=4*MY_CHARSET_BIN_MB_MAXLEN;
maybe_null=1;
+ return FALSE;
}
bool check_partition_func_processor(void *int_arg) {return FALSE;}
bool check_vcol_func_processor(void *arg) { return FALSE;}
@@ -416,11 +430,12 @@ class Item_func_weekday :public Item_func
}
enum Item_result result_type () const { return INT_RESULT; }
enum_field_types field_type() const { return MYSQL_TYPE_LONGLONG; }
- void fix_length_and_dec()
+ bool fix_length_and_dec()
{
decimals= 0;
fix_char_length(1);
maybe_null=1;
+ return FALSE;
}
bool check_partition_func_processor(void *int_arg) {return FALSE;}
bool check_vcol_func_processor(void *arg) { return FALSE;}
@@ -441,7 +456,7 @@ class Item_func_dayname :public Item_func_weekday
String *val_str(String *str);
enum Item_result result_type () const { return STRING_RESULT; }
enum_field_types field_type() const { return MYSQL_TYPE_VARCHAR; }
- void fix_length_and_dec();
+ bool fix_length_and_dec();
bool check_partition_func_processor(void *int_arg) {return TRUE;}
bool check_vcol_func_processor(void *arg)
{
@@ -457,7 +472,7 @@ class Item_func_seconds_hybrid: public Item_func_numhybrid
public:
Item_func_seconds_hybrid(THD *thd): Item_func_numhybrid(thd) {}
Item_func_seconds_hybrid(THD *thd, Item *a): Item_func_numhybrid(thd, a) {}
- void fix_length_and_dec()
+ bool fix_length_and_dec()
{
if (arg_count)
decimals= args[0]->temporal_precision(arg0_expected_type());
@@ -465,6 +480,7 @@ class Item_func_seconds_hybrid: public Item_func_numhybrid
max_length=17 + (decimals ? decimals + 1 : 0);
maybe_null= true;
set_handler_by_result_type(decimals ? DECIMAL_RESULT : INT_RESULT);
+ return FALSE;
}
double real_op() { DBUG_ASSERT(0); return 0; }
String *str_op(String *str) { DBUG_ASSERT(0); return 0; }
@@ -556,7 +572,7 @@ class Item_temporal_func: public Item_func
save_date_in_field(field);
}
#endif
- void fix_length_and_dec();
+ bool fix_length_and_dec();
};
@@ -834,7 +850,7 @@ class Item_func_date_format :public Item_str_func
String *val_str(String *str);
const char *func_name() const
{ return is_time_format ? "time_format" : "date_format"; }
- void fix_length_and_dec();
+ bool fix_length_and_dec();
uint format_length(const String *format);
bool eq(const Item *item, bool binary_cmp) const;
bool check_vcol_func_processor(void *arg)
@@ -854,7 +870,7 @@ class Item_func_from_unixtime :public Item_datetimefunc
public:
Item_func_from_unixtime(THD *thd, Item *a): Item_datetimefunc(thd, a) {}
const char *func_name() const { return "from_unixtime"; }
- void fix_length_and_dec();
+ bool fix_length_and_dec();
bool get_date(MYSQL_TIME *res, ulonglong fuzzy_date);
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
{ return get_item_copy<Item_func_from_unixtime>(thd, mem_root, this); }
@@ -889,7 +905,7 @@ class Item_func_convert_tz :public Item_datetimefunc
Item_func_convert_tz(THD *thd, Item *a, Item *b, Item *c):
Item_datetimefunc(thd, a, b, c), from_tz_cached(0), to_tz_cached(0) {}
const char *func_name() const { return "convert_tz"; }
- void fix_length_and_dec();
+ bool fix_length_and_dec();
bool get_date(MYSQL_TIME *res, ulonglong fuzzy_date);
void cleanup();
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
@@ -902,10 +918,10 @@ class Item_func_sec_to_time :public Item_timefunc
public:
Item_func_sec_to_time(THD *thd, Item *item): Item_timefunc(thd, item) {}
bool get_date(MYSQL_TIME *res, ulonglong fuzzy_date);
- void fix_length_and_dec()
+ bool fix_length_and_dec()
{
decimals= MY_MIN(args[0]->decimals, TIME_SECOND_PART_DIGITS);
- Item_timefunc::fix_length_and_dec();
+ return Item_timefunc::fix_length_and_dec();
}
const char *func_name() const { return "sec_to_time"; }
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
@@ -923,7 +939,7 @@ class Item_date_add_interval :public Item_temporal_hybrid_func
Item_temporal_hybrid_func(thd, a, b),int_type(type_arg),
date_sub_interval(neg_arg) {}
const char *func_name() const { return "date_add_interval"; }
- void fix_length_and_dec();
+ bool fix_length_and_dec();
bool get_date(MYSQL_TIME *res, ulonglong fuzzy_date);
bool eq(const Item *item, bool binary_cmp) const;
void print(String *str, enum_query_type query_type);
@@ -991,7 +1007,7 @@ class Item_extract :public Item_int_func
longlong val_int();
enum Functype functype() const { return EXTRACT_FUNC; }
const char *func_name() const { return "extract"; }
- void fix_length_and_dec();
+ bool fix_length_and_dec();
bool eq(const Item *item, bool binary_cmp) const;
void print(String *str, enum_query_type query_type);
bool check_partition_func_processor(void *int_arg) {return FALSE;}
@@ -1063,7 +1079,7 @@ class Item_char_typecast :public Item_str_func
bool eq(const Item *item, bool binary_cmp) const;
const char *func_name() const { return "cast_as_char"; }
String *val_str(String *a);
- void fix_length_and_dec();
+ bool fix_length_and_dec();
void print(String *str, enum_query_type query_type);
bool need_parentheses_in_default() { return true; }
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
@@ -1077,11 +1093,11 @@ class Item_temporal_typecast: public Item_temporal_func
Item_temporal_typecast(THD *thd, Item *a): Item_temporal_func(thd, a) {}
virtual const char *cast_type() const = 0;
void print(String *str, enum_query_type query_type);
- void fix_length_and_dec()
+ bool fix_length_and_dec()
{
if (decimals == NOT_FIXED_DEC)
decimals= args[0]->temporal_precision(field_type());
- Item_temporal_func::fix_length_and_dec();
+ return Item_temporal_func::fix_length_and_dec();
}
};
@@ -1148,7 +1164,7 @@ class Item_func_add_time :public Item_temporal_hybrid_func
Item_func_add_time(THD *thd, Item *a, Item *b, bool type_arg, bool neg_arg):
Item_temporal_hybrid_func(thd, a, b), is_date(type_arg)
{ sign= neg_arg ? -1 : 1; }
- void fix_length_and_dec();
+ bool fix_length_and_dec();
bool get_date(MYSQL_TIME *ltime, ulonglong fuzzy_date);
void print(String *str, enum_query_type query_type);
const char *func_name() const { return "add_time"; }
@@ -1161,11 +1177,11 @@ class Item_func_timediff :public Item_timefunc
public:
Item_func_timediff(THD *thd, Item *a, Item *b): Item_timefunc(thd, a, b) {}
const char *func_name() const { return "timediff"; }
- void fix_length_and_dec()
+ bool fix_length_and_dec()
{
decimals= MY_MAX(args[0]->temporal_precision(MYSQL_TYPE_TIME),
args[1]->temporal_precision(MYSQL_TYPE_TIME));
- Item_timefunc::fix_length_and_dec();
+ return Item_timefunc::fix_length_and_dec();
}
bool get_date(MYSQL_TIME *ltime, ulonglong fuzzy_date);
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
@@ -1178,10 +1194,10 @@ class Item_func_maketime :public Item_timefunc
Item_func_maketime(THD *thd, Item *a, Item *b, Item *c):
Item_timefunc(thd, a, b, c)
{}
- void fix_length_and_dec()
+ bool fix_length_and_dec()
{
decimals= MY_MIN(args[2]->decimals, TIME_SECOND_PART_DIGITS);
- Item_timefunc::fix_length_and_dec();
+ return Item_timefunc::fix_length_and_dec();
}
const char *func_name() const { return "maketime"; }
bool get_date(MYSQL_TIME *ltime, ulonglong fuzzy_date);
@@ -1196,10 +1212,11 @@ class Item_func_microsecond :public Item_int_func
Item_func_microsecond(THD *thd, Item *a): Item_int_func(thd, a) {}
longlong val_int();
const char *func_name() const { return "microsecond"; }
- void fix_length_and_dec()
- {
+ bool fix_length_and_dec()
+ {
decimals=0;
maybe_null=1;
+ return FALSE;
}
bool check_partition_func_processor(void *int_arg) {return FALSE;}
bool check_vcol_func_processor(void *arg) { return FALSE;}
@@ -1220,10 +1237,11 @@ class Item_func_timestamp_diff :public Item_int_func
Item_int_func(thd, a, b), int_type(type_arg) {}
const char *func_name() const { return "timestampdiff"; }
longlong val_int();
- void fix_length_and_dec()
+ bool fix_length_and_dec()
{
decimals=0;
maybe_null=1;
+ return FALSE;
}
virtual void print(String *str, enum_query_type query_type);
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
@@ -1245,11 +1263,12 @@ class Item_func_get_format :public Item_str_ascii_func
{}
String *val_str_ascii(String *str);
const char *func_name() const { return "get_format"; }
- void fix_length_and_dec()
+ bool fix_length_and_dec()
{
maybe_null= 1;
decimals=0;
fix_length_and_charset(17, default_charset());
+ return FALSE;
}
virtual void print(String *str, enum_query_type query_type);
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
@@ -1271,7 +1290,7 @@ class Item_func_str_to_date :public Item_temporal_hybrid_func
{}
bool get_date(MYSQL_TIME *ltime, ulonglong fuzzy_date);
const char *func_name() const { return "str_to_date"; }
- void fix_length_and_dec();
+ bool fix_length_and_dec();
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
{ return get_item_copy<Item_func_str_to_date>(thd, mem_root, this); }
};
diff --git a/sql/item_windowfunc.cc b/sql/item_windowfunc.cc
index 5fbfb2651af..532a351dec1 100644
--- a/sql/item_windowfunc.cc
+++ b/sql/item_windowfunc.cc
@@ -106,7 +106,8 @@ Item_window_func::fix_fields(THD *thd, Item **ref)
with_window_func= true;
with_sum_func= false;
- fix_length_and_dec();
+ if (fix_length_and_dec())
+ return TRUE;
max_length= window_func()->max_length;
maybe_null= window_func()->maybe_null;
@@ -268,7 +269,8 @@ bool Item_sum_hybrid_simple::fix_fields(THD *thd, Item **ref)
maybe_null= 1;
result_field=0;
null_value=1;
- fix_length_and_dec();
+ if (fix_length_and_dec())
+ return TRUE;
if (check_sum_func(thd, ref))
return TRUE;
diff --git a/sql/item_windowfunc.h b/sql/item_windowfunc.h
index a1ef6854288..e5afb9e1555 100644
--- a/sql/item_windowfunc.h
+++ b/sql/item_windowfunc.h
@@ -516,10 +516,11 @@ class Item_sum_percent_rank: public Item_sum_window_with_row_count
enum Item_result result_type () const { return REAL_RESULT; }
enum_field_types field_type() const { return MYSQL_TYPE_DOUBLE; }
- void fix_length_and_dec()
+ bool fix_length_and_dec()
{
decimals = 10; // TODO-cvicentiu find out how many decimals the standard
// requires.
+ return FALSE;
}
void setup_window_func(THD *thd, Window_spec *window_spec);
@@ -602,10 +603,11 @@ class Item_sum_cume_dist: public Item_sum_window_with_row_count
enum Item_result result_type () const { return REAL_RESULT; }
enum_field_types field_type() const { return MYSQL_TYPE_DOUBLE; }
- void fix_length_and_dec()
+ bool fix_length_and_dec()
{
decimals = 10; // TODO-cvicentiu find out how many decimals the standard
// requires.
+ return FALSE;
}
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
@@ -950,9 +952,10 @@ class Item_window_func : public Item_func_or_sum
void split_sum_func(THD *thd, Ref_ptr_array ref_pointer_array,
List<Item> &fields, uint flags);
- void fix_length_and_dec()
+ bool fix_length_and_dec()
{
decimals = window_func()->decimals;
+ return FALSE;
}
const char* func_name() const { return "WF"; }
diff --git a/sql/item_xmlfunc.cc b/sql/item_xmlfunc.cc
index af62a94afd0..738047fea9b 100644
--- a/sql/item_xmlfunc.cc
+++ b/sql/item_xmlfunc.cc
@@ -222,13 +222,14 @@ class Item_nodeset_func :public Item_str_func
return str;
}
enum Item_result result_type () const { return STRING_RESULT; }
- void fix_length_and_dec()
+ bool fix_length_and_dec()
{
max_length= MAX_BLOB_WIDTH;
collation.collation= pxml->charset();
// To avoid premature evaluation, mark all nodeset functions as non-const.
used_tables_cache= RAND_TABLE_BIT;
const_item_cache= false;
+ return FALSE;
}
const char *func_name() const { return "nodeset"; }
bool check_vcol_func_processor(void *arg)
@@ -456,7 +457,7 @@ class Item_nodeset_context_cache :public Item_nodeset_func
Item_nodeset_func(thd, pxml), string_cache(str_arg) { }
String *val_nodeset(String *res)
{ return string_cache; }
- void fix_length_and_dec() { max_length= MAX_BLOB_WIDTH; }
+ bool fix_length_and_dec() { max_length= MAX_BLOB_WIDTH; return FALSE; }
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
{ return get_item_copy<Item_nodeset_context_cache>(thd, mem_root, this); }
};
@@ -470,7 +471,7 @@ class Item_func_xpath_position :public Item_int_func
Item_func_xpath_position(THD *thd, Item *a, String *p):
Item_int_func(thd, a), pxml(p) {}
const char *func_name() const { return "xpath_position"; }
- void fix_length_and_dec() { max_length=10; }
+ bool fix_length_and_dec() { max_length=10; return FALSE; }
longlong val_int()
{
String *flt= args[0]->val_nodeset(&tmp_value);
@@ -491,7 +492,7 @@ class Item_func_xpath_count :public Item_int_func
Item_func_xpath_count(THD *thd, Item *a, String *p):
Item_int_func(thd, a), pxml(p) {}
const char *func_name() const { return "xpath_count"; }
- void fix_length_and_dec() { max_length=10; }
+ bool fix_length_and_dec() { max_length=10; return FALSE; }
longlong val_int()
{
uint predicate_supplied_context_size;
@@ -2709,10 +2710,10 @@ my_xpath_parse(MY_XPATH *xpath, const char *str, const char *strend)
}
-void Item_xml_str_func::fix_length_and_dec()
+bool Item_xml_str_func::fix_length_and_dec()
{
max_length= MAX_BLOB_WIDTH;
- agg_arg_charsets_for_comparison(collation, args, arg_count);
+ return agg_arg_charsets_for_comparison(collation, args, arg_count);
}
diff --git a/sql/item_xmlfunc.h b/sql/item_xmlfunc.h
index d281e076ec8..c46365ee5f0 100644
--- a/sql/item_xmlfunc.h
+++ b/sql/item_xmlfunc.h
@@ -82,7 +82,7 @@ class Item_xml_str_func: public Item_str_func
maybe_null= TRUE;
}
bool fix_fields(THD *thd, Item **ref);
- void fix_length_and_dec();
+ bool fix_length_and_dec();
bool const_item() const
{
return const_item_cache && (!nodeset_func || nodeset_func->const_item());
diff --git a/sql/sql_select.cc b/sql/sql_select.cc
index 30ef26f67e2..3fecddc6661 100644
--- a/sql/sql_select.cc
+++ b/sql/sql_select.cc
@@ -13508,7 +13508,8 @@ COND *Item_func_eq::build_equal_items(THD *thd,
List_iterator_fast<Item_equal> it(cond_equal.current_level);
while ((item_equal= it++))
{
- item_equal->fix_length_and_dec();
+ if (item_equal->fix_length_and_dec())
+ return NULL;
item_equal->update_used_tables();
set_if_bigger(thd->lex->current_select->max_equal_elems,
item_equal->n_field_items());
diff --git a/sql/sql_table.cc b/sql/sql_table.cc
index 9e7973b745c..f3cb85f01d3 100644
--- a/sql/sql_table.cc
+++ b/sql/sql_table.cc
@@ -4894,7 +4894,13 @@ int create_table_impl(THD *thd,
file= mysql_create_frm_image(thd, orig_db, orig_table_name, create_info,
alter_info, create_table_mode, key_info,
key_count, frm);
- if (!file)
+ /*
+ We have to check thd->is_error() here because it can be set by
+ Item::val* for example, and before it will be cought accidentally by
+ Item_func::fix_fields() of the next call. Now we removed the check
+ from Item_func::fix_fields()
+ */
+ if (!file || thd->is_error())
goto err;
if (rea_create_table(thd, frm, path, db, table_name, create_info,
file, frm_only))
@@ -7377,7 +7383,8 @@ static bool mysql_inplace_alter_table(THD *thd,
*/
if (mysql_rename_table(db_type, alter_ctx->new_db, alter_ctx->tmp_name,
alter_ctx->db, alter_ctx->alias,
- FN_FROM_IS_TMP | NO_HA_TABLE))
+ FN_FROM_IS_TMP | NO_HA_TABLE) ||
+ thd->is_error())
{
// Since changes were done in-place, we can't revert them.
(void) quick_rm_table(thd, db_type,
1
0