Merged the code of mwl 106 into the latest 5.3 with mwl 90 pushed.
Resolved all conflicts and failures.
This commit is contained in:
commit
f03a3ee54f
@ -57,9 +57,8 @@ a b a b
|
|||||||
3 c 3 c
|
3 c 3 c
|
||||||
explain select * from t1 as x1, (select * from t1) as x2;
|
explain select * from t1 as x1, (select * from t1) as x2;
|
||||||
id select_type table type possible_keys key key_len ref rows Extra
|
id select_type table type possible_keys key key_len ref rows Extra
|
||||||
1 PRIMARY x1 ALL NULL NULL NULL NULL 4
|
1 SIMPLE x1 ALL NULL NULL NULL NULL 4
|
||||||
1 PRIMARY <derived2> ALL NULL NULL NULL NULL 4 Using join buffer (flat, BNL join)
|
1 SIMPLE t1 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;
|
drop table if exists t2,t3;
|
||||||
select * from (select 1) as a;
|
select * from (select 1) as a;
|
||||||
1
|
1
|
||||||
@ -91,7 +90,7 @@ a b
|
|||||||
2 b
|
2 b
|
||||||
explain select * from (select * from t1 union select * from t1) a;
|
explain select * from (select * from t1 union select * from t1) a;
|
||||||
id select_type table type possible_keys key key_len ref rows Extra
|
id select_type table type possible_keys key key_len ref rows Extra
|
||||||
1 PRIMARY <derived2> ALL NULL NULL NULL NULL 3
|
1 PRIMARY <derived2> ALL NULL NULL NULL NULL 8
|
||||||
2 DERIVED t1 ALL NULL NULL NULL NULL 4
|
2 DERIVED t1 ALL NULL NULL NULL NULL 4
|
||||||
3 UNION 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
|
NULL UNION RESULT <union2,3> ALL NULL NULL NULL NULL NULL
|
||||||
@ -113,9 +112,8 @@ a b
|
|||||||
3 c
|
3 c
|
||||||
explain select * from (select t1.*, t2.a as t2a from t1,t2 where t1.a=t2.a) t1;
|
explain select * from (select t1.*, t2.a as t2a from t1,t2 where t1.a=t2.a) t1;
|
||||||
id select_type table type possible_keys key key_len ref rows Extra
|
id select_type table type possible_keys key key_len ref rows Extra
|
||||||
1 PRIMARY <derived2> system NULL NULL NULL NULL 1
|
1 SIMPLE t2 system NULL NULL NULL NULL 1
|
||||||
2 DERIVED t2 system NULL NULL NULL NULL 1
|
1 SIMPLE t1 ALL NULL NULL NULL NULL 4 Using where
|
||||||
2 DERIVED t1 ALL NULL NULL NULL NULL 4 Using where
|
|
||||||
drop table t1, t2;
|
drop table t1, t2;
|
||||||
create table t1(a int not null, t char(8), index(a));
|
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;
|
SELECT * FROM (SELECT * FROM t1) as b ORDER BY a ASC LIMIT 0,20;
|
||||||
@ -142,8 +140,7 @@ a t
|
|||||||
20 20
|
20 20
|
||||||
explain select count(*) from t1 as tt1, (select * from t1) as tt2;
|
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
|
id select_type table type possible_keys key key_len ref rows Extra
|
||||||
1 PRIMARY NULL NULL NULL NULL NULL NULL NULL Select tables optimized away
|
1 SIMPLE NULL NULL NULL NULL NULL NULL NULL Select tables optimized away
|
||||||
2 DERIVED t1 ALL NULL NULL NULL NULL 10000
|
|
||||||
drop table t1;
|
drop table t1;
|
||||||
SELECT * FROM (SELECT (SELECT * FROM (SELECT 1 as a) as a )) as b;
|
SELECT * FROM (SELECT (SELECT * FROM (SELECT 1 as a) as a )) as b;
|
||||||
(SELECT * FROM (SELECT 1 as a) as a )
|
(SELECT * FROM (SELECT 1 as a) as a )
|
||||||
@ -172,30 +169,30 @@ insert into t1 values (NULL, 'a', 1), (NULL, 'b', 2), (NULL, 'c', 3), (NULL, 'd'
|
|||||||
insert into t2 values (1, 100), (1, 101), (1, 102), (2, 100), (2, 103), (2, 104), (3, 101), (3, 102), (3, 105);
|
insert into t2 values (1, 100), (1, 101), (1, 102), (2, 100), (2, 103), (2, 104), (3, 101), (3, 102), (3, 105);
|
||||||
SELECT STRAIGHT_JOIN d.pla_id, m2.mat_id FROM t1 m2 INNER JOIN (SELECT mp.pla_id, MIN(m1.matintnum) AS matintnum FROM t2 mp INNER JOIN t1 m1 ON mp.mat_id=m1.mat_id GROUP BY mp.pla_id) d ON d.matintnum=m2.matintnum;
|
SELECT STRAIGHT_JOIN d.pla_id, m2.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
|
pla_id mat_id
|
||||||
100 1
|
|
||||||
101 1
|
|
||||||
102 1
|
102 1
|
||||||
103 2
|
101 1
|
||||||
|
100 1
|
||||||
104 2
|
104 2
|
||||||
|
103 2
|
||||||
105 3
|
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;
|
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
|
pla_id test
|
||||||
100 1
|
|
||||||
101 1
|
|
||||||
102 1
|
102 1
|
||||||
103 2
|
101 1
|
||||||
|
100 1
|
||||||
104 2
|
104 2
|
||||||
|
103 2
|
||||||
105 3
|
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;
|
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
|
id select_type table type possible_keys key key_len ref rows Extra
|
||||||
1 PRIMARY m2 ALL NULL NULL NULL NULL 9
|
1 PRIMARY m2 ALL NULL NULL NULL NULL 9
|
||||||
1 PRIMARY <derived2> ALL NULL NULL NULL NULL 6 Using where; Using join buffer (flat, BNL join)
|
1 PRIMARY <derived2> ref key0 key0 7 test.m2.matintnum 2
|
||||||
2 DERIVED mp ALL NULL NULL NULL NULL 9 Using temporary; Using filesort
|
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
|
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;
|
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
|
id select_type table type possible_keys key key_len ref rows Extra
|
||||||
1 PRIMARY m2 ALL NULL NULL NULL NULL 9
|
1 PRIMARY m2 ALL NULL NULL NULL NULL 9
|
||||||
1 PRIMARY <derived2> ALL NULL NULL NULL NULL 6 Using where; Using join buffer (flat, BNL join)
|
1 PRIMARY <derived2> ref key0 key0 7 test.m2.matintnum 2
|
||||||
2 DERIVED mp ALL NULL NULL NULL NULL 9 Using temporary; Using filesort
|
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
|
2 DERIVED m1 eq_ref PRIMARY PRIMARY 3 test.mp.mat_id 1
|
||||||
drop table t1,t2;
|
drop table t1,t2;
|
||||||
@ -230,9 +227,8 @@ count(*)
|
|||||||
2
|
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;
|
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
|
id select_type table type possible_keys key key_len ref rows Extra
|
||||||
1 PRIMARY <derived2> ALL NULL NULL NULL NULL 2
|
1 SIMPLE A ALL NULL NULL NULL NULL 2 Using where
|
||||||
1 PRIMARY t1 eq_ref PRIMARY PRIMARY 4 THEMAX.E2 1 Using where
|
1 SIMPLE t1 eq_ref PRIMARY PRIMARY 4 test.A.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
|
3 DEPENDENT SUBQUERY B ALL NULL NULL NULL NULL 2 Using where
|
||||||
drop table t1;
|
drop table t1;
|
||||||
create table t1 (a int);
|
create table t1 (a int);
|
||||||
@ -245,8 +241,8 @@ a a
|
|||||||
2 2
|
2 2
|
||||||
explain select * from ( select * from t1 union select * from t1) a,(select * from t1 union select * from t1) b;
|
explain select * from ( select * from t1 union select * from t1) a,(select * from t1 union select * from t1) b;
|
||||||
id select_type table type possible_keys key key_len ref rows Extra
|
id select_type table type possible_keys key key_len ref rows Extra
|
||||||
1 PRIMARY <derived2> ALL NULL NULL NULL NULL 2
|
1 PRIMARY <derived2> ALL NULL NULL NULL NULL 4
|
||||||
1 PRIMARY <derived4> ALL NULL NULL NULL NULL 2 Using join buffer (flat, BNL join)
|
1 PRIMARY <derived4> ALL NULL NULL NULL NULL 4 Using join buffer (flat, BNL join)
|
||||||
4 DERIVED t1 ALL NULL NULL NULL NULL 2
|
4 DERIVED t1 ALL NULL NULL NULL NULL 2
|
||||||
5 UNION 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
|
NULL UNION RESULT <union4,5> ALL NULL NULL NULL NULL NULL
|
||||||
@ -311,7 +307,7 @@ a 7.0000
|
|||||||
b 3.5000
|
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;
|
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
|
id select_type table type possible_keys key key_len ref rows Extra
|
||||||
1 PRIMARY <derived2> ALL NULL NULL NULL NULL 3 Using temporary; Using filesort
|
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 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)
|
2 DERIVED y ALL NULL NULL NULL NULL 17 Using where; Using join buffer (flat, BNL join)
|
||||||
drop table t1;
|
drop table t1;
|
||||||
@ -322,8 +318,7 @@ 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
|
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;
|
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
|
id select_type table type possible_keys key key_len ref rows Extra
|
||||||
1 PRIMARY <derived2> system NULL NULL NULL NULL 1
|
1 SIMPLE t2 index PRIMARY PRIMARY 4 NULL 2 Using where; Using index
|
||||||
2 DERIVED t2 index PRIMARY PRIMARY 4 NULL 2 Using where; Using index
|
|
||||||
drop table t2;
|
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_`));
|
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),
|
insert into t1 values (128, 'rozn', 2, curdate(), 10),
|
||||||
|
570
mysql-test/r/derived_view.result
Normal file
570
mysql-test/r/derived_view.result
Normal file
@ -0,0 +1,570 @@
|
|||||||
|
drop table if exists t1,t2;
|
||||||
|
drop view if exists v1,v2,v3,v4;
|
||||||
|
create table t1(f1 int, f11 int);
|
||||||
|
create table t2(f2 int, f22 int);
|
||||||
|
insert into t1 values(1,1),(2,2),(3,3),(5,5),(9,9),(7,7);
|
||||||
|
insert into t1 values(17,17),(13,13),(11,11),(15,15),(19,19);
|
||||||
|
insert into t2 values(1,1),(3,3),(2,2),(4,4),(8,8),(6,6);
|
||||||
|
insert into t2 values(12,12),(14,14),(10,10),(18,18),(16,16);
|
||||||
|
Tests:
|
||||||
|
for merged derived tables
|
||||||
|
explain for simple derived
|
||||||
|
explain select * from (select * from t1) tt;
|
||||||
|
id select_type table type possible_keys key key_len ref rows Extra
|
||||||
|
1 SIMPLE t1 ALL NULL NULL NULL NULL 11
|
||||||
|
select * from (select * from t1) tt;
|
||||||
|
f1 f11
|
||||||
|
1 1
|
||||||
|
2 2
|
||||||
|
3 3
|
||||||
|
5 5
|
||||||
|
9 9
|
||||||
|
7 7
|
||||||
|
17 17
|
||||||
|
13 13
|
||||||
|
11 11
|
||||||
|
15 15
|
||||||
|
19 19
|
||||||
|
explain for multitable derived
|
||||||
|
explain extended select * from (select * from t1 join t2 on f1=f2) tt;
|
||||||
|
id select_type table type possible_keys key key_len ref rows filtered Extra
|
||||||
|
1 SIMPLE t1 ALL NULL NULL NULL NULL 11 100.00
|
||||||
|
1 SIMPLE t2 ALL NULL NULL NULL NULL 11 100.00 Using where; Using join buffer (flat, BNL join)
|
||||||
|
Warnings:
|
||||||
|
Note 1003 select `test`.`t1`.`f1` AS `f1`,`test`.`t1`.`f11` AS `f11`,`test`.`t2`.`f2` AS `f2`,`test`.`t2`.`f22` AS `f22` from `test`.`t1` join `test`.`t2` where (`test`.`t2`.`f2` = `test`.`t1`.`f1`)
|
||||||
|
select * from (select * from t1 join t2 on f1=f2) tt;
|
||||||
|
f1 f11 f2 f22
|
||||||
|
1 1 1 1
|
||||||
|
3 3 3 3
|
||||||
|
2 2 2 2
|
||||||
|
explain for derived with where
|
||||||
|
explain extended
|
||||||
|
select * from (select * from t1 where f1 in (2,3)) tt where f11=2;
|
||||||
|
id select_type table type possible_keys key key_len ref rows filtered Extra
|
||||||
|
1 SIMPLE t1 ALL NULL NULL NULL NULL 11 100.00 Using where
|
||||||
|
Warnings:
|
||||||
|
Note 1003 select `test`.`t1`.`f1` AS `f1`,`test`.`t1`.`f11` AS `f11` from `test`.`t1` where ((`test`.`t1`.`f11` = 2) and (`test`.`t1`.`f1` in (2,3)))
|
||||||
|
select * from (select * from t1 where f1 in (2,3)) tt where f11=2;
|
||||||
|
f1 f11
|
||||||
|
2 2
|
||||||
|
join of derived
|
||||||
|
explain extended
|
||||||
|
select * from (select * from t1 where f1 in (2,3)) tt join
|
||||||
|
(select * from t1 where f1 in (1,2)) aa on tt.f1=aa.f1;
|
||||||
|
id select_type table type possible_keys key key_len ref rows filtered Extra
|
||||||
|
1 SIMPLE t1 ALL NULL NULL NULL NULL 11 100.00 Using where
|
||||||
|
1 SIMPLE t1 ALL NULL NULL NULL NULL 11 100.00 Using where; Using join buffer (flat, BNL join)
|
||||||
|
Warnings:
|
||||||
|
Note 1003 select `test`.`t1`.`f1` AS `f1`,`test`.`t1`.`f11` AS `f11`,`test`.`t1`.`f1` AS `f1`,`test`.`t1`.`f11` AS `f11` from `test`.`t1` join `test`.`t1` where ((`test`.`t1`.`f1` = `test`.`t1`.`f1`) and (`test`.`t1`.`f1` in (1,2)) and (`test`.`t1`.`f1` in (2,3)))
|
||||||
|
select * from (select * from t1 where f1 in (2,3)) tt join
|
||||||
|
(select * from t1 where f1 in (1,2)) aa on tt.f1=aa.f1;
|
||||||
|
f1 f11 f1 f11
|
||||||
|
2 2 2 2
|
||||||
|
flush status;
|
||||||
|
explain extended
|
||||||
|
select * from (select * from t1 where f1 in (2,3)) tt where f11=2;
|
||||||
|
id select_type table type possible_keys key key_len ref rows filtered Extra
|
||||||
|
1 SIMPLE t1 ALL NULL NULL NULL NULL 11 100.00 Using where
|
||||||
|
Warnings:
|
||||||
|
Note 1003 select `test`.`t1`.`f1` AS `f1`,`test`.`t1`.`f11` AS `f11` from `test`.`t1` where ((`test`.`t1`.`f11` = 2) and (`test`.`t1`.`f1` in (2,3)))
|
||||||
|
show status like 'Handler_read%';
|
||||||
|
Variable_name Value
|
||||||
|
Handler_read_first 0
|
||||||
|
Handler_read_key 0
|
||||||
|
Handler_read_next 0
|
||||||
|
Handler_read_prev 0
|
||||||
|
Handler_read_rnd 0
|
||||||
|
Handler_read_rnd_next 0
|
||||||
|
flush status;
|
||||||
|
select * from (select * from t1 where f1 in (2,3)) tt where f11=2;
|
||||||
|
f1 f11
|
||||||
|
2 2
|
||||||
|
show status like 'Handler_read%';
|
||||||
|
Variable_name Value
|
||||||
|
Handler_read_first 0
|
||||||
|
Handler_read_key 0
|
||||||
|
Handler_read_next 0
|
||||||
|
Handler_read_prev 0
|
||||||
|
Handler_read_rnd 0
|
||||||
|
Handler_read_rnd_next 12
|
||||||
|
for merged views
|
||||||
|
create view v1 as select * from t1;
|
||||||
|
create view v2 as select * from t1 join t2 on f1=f2;
|
||||||
|
create view v3 as select * from t1 where f1 in (2,3);
|
||||||
|
create view v4 as select * from t2 where f2 in (2,3);
|
||||||
|
explain for simple views
|
||||||
|
explain extended select * from v1;
|
||||||
|
id select_type table type possible_keys key key_len ref rows filtered Extra
|
||||||
|
1 SIMPLE t1 ALL NULL NULL NULL NULL 11 100.00
|
||||||
|
Warnings:
|
||||||
|
Note 1003 select `test`.`t1`.`f1` AS `f1`,`test`.`t1`.`f11` AS `f11` from `test`.`t1`
|
||||||
|
select * from v1;
|
||||||
|
f1 f11
|
||||||
|
1 1
|
||||||
|
2 2
|
||||||
|
3 3
|
||||||
|
5 5
|
||||||
|
9 9
|
||||||
|
7 7
|
||||||
|
17 17
|
||||||
|
13 13
|
||||||
|
11 11
|
||||||
|
15 15
|
||||||
|
19 19
|
||||||
|
explain for multitable views
|
||||||
|
explain extended select * from v2;
|
||||||
|
id select_type table type possible_keys key key_len ref rows filtered Extra
|
||||||
|
1 SIMPLE t1 ALL NULL NULL NULL NULL 11 100.00
|
||||||
|
1 SIMPLE t2 ALL NULL NULL NULL NULL 11 100.00 Using where; Using join buffer (flat, BNL join)
|
||||||
|
Warnings:
|
||||||
|
Note 1003 select `test`.`t1`.`f1` AS `f1`,`test`.`t1`.`f11` AS `f11`,`test`.`t2`.`f2` AS `f2`,`test`.`t2`.`f22` AS `f22` from `test`.`t1` join `test`.`t2` where (`test`.`t2`.`f2` = `test`.`t1`.`f1`)
|
||||||
|
select * from v2;
|
||||||
|
f1 f11 f2 f22
|
||||||
|
1 1 1 1
|
||||||
|
3 3 3 3
|
||||||
|
2 2 2 2
|
||||||
|
explain for views with where
|
||||||
|
explain extended select * from v3 where f11 in (1,3);
|
||||||
|
id select_type table type possible_keys key key_len ref rows filtered Extra
|
||||||
|
1 SIMPLE t1 ALL NULL NULL NULL NULL 11 100.00 Using where
|
||||||
|
Warnings:
|
||||||
|
Note 1003 select `test`.`t1`.`f1` AS `f1`,`test`.`t1`.`f11` AS `f11` from `test`.`t1` where ((`test`.`t1`.`f11` in (1,3)) and (`test`.`t1`.`f1` in (2,3)))
|
||||||
|
select * from v3 where f11 in (1,3);
|
||||||
|
f1 f11
|
||||||
|
3 3
|
||||||
|
explain for joined views
|
||||||
|
explain extended
|
||||||
|
select * from v3 join v4 on f1=f2;
|
||||||
|
id select_type table type possible_keys key key_len ref rows filtered Extra
|
||||||
|
1 SIMPLE t1 ALL NULL NULL NULL NULL 11 100.00 Using where
|
||||||
|
1 SIMPLE t2 ALL NULL NULL NULL NULL 11 100.00 Using where; Using join buffer (flat, BNL join)
|
||||||
|
Warnings:
|
||||||
|
Note 1003 select `test`.`t1`.`f1` AS `f1`,`test`.`t1`.`f11` AS `f11`,`test`.`t2`.`f2` AS `f2`,`test`.`t2`.`f22` AS `f22` from `test`.`t1` join `test`.`t2` where ((`test`.`t2`.`f2` = `test`.`t1`.`f1`) and (`test`.`t1`.`f1` in (2,3)) and (`test`.`t1`.`f1` in (2,3)))
|
||||||
|
select * from v3 join v4 on f1=f2;
|
||||||
|
f1 f11 f2 f22
|
||||||
|
3 3 3 3
|
||||||
|
2 2 2 2
|
||||||
|
flush status;
|
||||||
|
explain extended select * from v4 where f2 in (1,3);
|
||||||
|
id select_type table type possible_keys key key_len ref rows filtered Extra
|
||||||
|
1 SIMPLE t2 ALL NULL NULL NULL NULL 11 100.00 Using where
|
||||||
|
Warnings:
|
||||||
|
Note 1003 select `test`.`t2`.`f2` AS `f2`,`test`.`t2`.`f22` AS `f22` from `test`.`t2` where ((`test`.`t2`.`f2` in (1,3)) and (`test`.`t2`.`f2` in (2,3)))
|
||||||
|
show status like 'Handler_read%';
|
||||||
|
Variable_name Value
|
||||||
|
Handler_read_first 0
|
||||||
|
Handler_read_key 0
|
||||||
|
Handler_read_next 0
|
||||||
|
Handler_read_prev 0
|
||||||
|
Handler_read_rnd 0
|
||||||
|
Handler_read_rnd_next 0
|
||||||
|
flush status;
|
||||||
|
select * from v4 where f2 in (1,3);
|
||||||
|
f2 f22
|
||||||
|
3 3
|
||||||
|
show status like 'Handler_read%';
|
||||||
|
Variable_name Value
|
||||||
|
Handler_read_first 0
|
||||||
|
Handler_read_key 0
|
||||||
|
Handler_read_next 0
|
||||||
|
Handler_read_prev 0
|
||||||
|
Handler_read_rnd 0
|
||||||
|
Handler_read_rnd_next 12
|
||||||
|
for materialized derived tables
|
||||||
|
explain for simple derived
|
||||||
|
explain extended select * from (select * from t1 group by f1) tt;
|
||||||
|
id select_type table type possible_keys key key_len ref rows filtered Extra
|
||||||
|
1 PRIMARY <derived2> ALL NULL NULL NULL NULL 11 100.00
|
||||||
|
2 DERIVED t1 ALL NULL NULL NULL NULL 11 100.00 Using temporary; Using filesort
|
||||||
|
Warnings:
|
||||||
|
Note 1003 select `tt`.`f1` AS `f1`,`tt`.`f11` AS `f11` from (select `test`.`t1`.`f1` AS `f1`,`test`.`t1`.`f11` AS `f11` from `test`.`t1` group by `test`.`t1`.`f1`) `tt`
|
||||||
|
select * from (select * from t1 having f1=f1) tt;
|
||||||
|
f1 f11
|
||||||
|
1 1
|
||||||
|
2 2
|
||||||
|
3 3
|
||||||
|
5 5
|
||||||
|
9 9
|
||||||
|
7 7
|
||||||
|
17 17
|
||||||
|
13 13
|
||||||
|
11 11
|
||||||
|
15 15
|
||||||
|
19 19
|
||||||
|
explain showing created indexes
|
||||||
|
explain extended
|
||||||
|
select * from t1 join (select * from t2 group by f2) tt on f1=f2;
|
||||||
|
id select_type table type possible_keys key key_len ref rows filtered Extra
|
||||||
|
1 PRIMARY t1 ALL NULL NULL NULL NULL 11 100.00 Using where
|
||||||
|
1 PRIMARY <derived2> ref key0 key0 5 test.t1.f1 2 100.00
|
||||||
|
2 DERIVED t2 ALL NULL NULL NULL NULL 11 100.00 Using temporary; Using filesort
|
||||||
|
Warnings:
|
||||||
|
Note 1003 select `test`.`t1`.`f1` AS `f1`,`test`.`t1`.`f11` AS `f11`,`tt`.`f2` AS `f2`,`tt`.`f22` AS `f22` from `test`.`t1` join (select `test`.`t2`.`f2` AS `f2`,`test`.`t2`.`f22` AS `f22` from `test`.`t2` group by `test`.`t2`.`f2`) `tt` where (`tt`.`f2` = `test`.`t1`.`f1`)
|
||||||
|
select * from t1 join (select * from t2 group by f2) tt on f1=f2;
|
||||||
|
f1 f11 f2 f22
|
||||||
|
1 1 1 1
|
||||||
|
2 2 2 2
|
||||||
|
3 3 3 3
|
||||||
|
explain showing late materialization
|
||||||
|
flush status;
|
||||||
|
explain select * from t1 join (select * from t2 group by f2) tt on f1=f2;
|
||||||
|
id select_type table type possible_keys key key_len ref rows Extra
|
||||||
|
1 PRIMARY t1 ALL NULL NULL NULL NULL 11 Using where
|
||||||
|
1 PRIMARY <derived2> ref key0 key0 5 test.t1.f1 2
|
||||||
|
2 DERIVED t2 ALL NULL NULL NULL NULL 11 Using temporary; Using filesort
|
||||||
|
show status like 'Handler_read%';
|
||||||
|
Variable_name Value
|
||||||
|
Handler_read_first 0
|
||||||
|
Handler_read_key 0
|
||||||
|
Handler_read_next 0
|
||||||
|
Handler_read_prev 0
|
||||||
|
Handler_read_rnd 0
|
||||||
|
Handler_read_rnd_next 0
|
||||||
|
flush status;
|
||||||
|
select * from t1 join (select * from t2 group by f2) tt on f1=f2;
|
||||||
|
f1 f11 f2 f22
|
||||||
|
1 1 1 1
|
||||||
|
2 2 2 2
|
||||||
|
3 3 3 3
|
||||||
|
show status like 'Handler_read%';
|
||||||
|
Variable_name Value
|
||||||
|
Handler_read_first 0
|
||||||
|
Handler_read_key 11
|
||||||
|
Handler_read_next 3
|
||||||
|
Handler_read_prev 0
|
||||||
|
Handler_read_rnd 11
|
||||||
|
Handler_read_rnd_next 36
|
||||||
|
for materialized views
|
||||||
|
drop view v1,v2,v3;
|
||||||
|
create view v1 as select * from t1 group by f1;
|
||||||
|
create view v2 as select * from t2 group by f2;
|
||||||
|
create view v3 as select t1.f1,t1.f11 from t1 join t1 as t11 where t1.f1=t11.f1
|
||||||
|
having t1.f1<100;
|
||||||
|
explain for simple derived
|
||||||
|
explain extended select * from v1;
|
||||||
|
id select_type table type possible_keys key key_len ref rows filtered Extra
|
||||||
|
1 PRIMARY <derived2> ALL NULL NULL NULL NULL 11 100.00
|
||||||
|
2 DERIVED t1 ALL NULL NULL NULL NULL 11 100.00 Using temporary; Using filesort
|
||||||
|
Warnings:
|
||||||
|
Note 1003 select `v1`.`f1` AS `f1`,`v1`.`f11` AS `f11` from `test`.`v1`
|
||||||
|
select * from v1;
|
||||||
|
f1 f11
|
||||||
|
1 1
|
||||||
|
2 2
|
||||||
|
3 3
|
||||||
|
5 5
|
||||||
|
7 7
|
||||||
|
9 9
|
||||||
|
11 11
|
||||||
|
13 13
|
||||||
|
15 15
|
||||||
|
17 17
|
||||||
|
19 19
|
||||||
|
explain showing created indexes
|
||||||
|
explain extended select * from t1 join v2 on f1=f2;
|
||||||
|
id select_type table type possible_keys key key_len ref rows filtered Extra
|
||||||
|
1 PRIMARY t1 ALL NULL NULL NULL NULL 11 100.00 Using where
|
||||||
|
1 PRIMARY <derived2> ref key0 key0 5 test.t1.f1 2 100.00
|
||||||
|
2 DERIVED t2 ALL NULL NULL NULL NULL 11 100.00 Using temporary; Using filesort
|
||||||
|
Warnings:
|
||||||
|
Note 1003 select `test`.`t1`.`f1` AS `f1`,`test`.`t1`.`f11` AS `f11`,`v2`.`f2` AS `f2`,`v2`.`f22` AS `f22` from `test`.`t1` join `test`.`v2` where (`v2`.`f2` = `test`.`t1`.`f1`)
|
||||||
|
select * from t1 join v2 on f1=f2;
|
||||||
|
f1 f11 f2 f22
|
||||||
|
1 1 1 1
|
||||||
|
2 2 2 2
|
||||||
|
3 3 3 3
|
||||||
|
explain extended
|
||||||
|
select * from t1,v3 as v31,v3 where t1.f1=v31.f1 and t1.f1=v3.f1;
|
||||||
|
id select_type table type possible_keys key key_len ref rows filtered Extra
|
||||||
|
1 PRIMARY t1 ALL NULL NULL NULL NULL 11 100.00 Using where
|
||||||
|
1 PRIMARY <derived2> ref key0 key0 5 test.t1.f1 10 100.00
|
||||||
|
1 PRIMARY <derived3> ref key0 key0 5 test.t1.f1 10 100.00
|
||||||
|
3 DERIVED t1 ALL NULL NULL NULL NULL 11 100.00
|
||||||
|
3 DERIVED t11 ALL NULL NULL NULL NULL 11 100.00 Using where; Using join buffer (flat, BNL join)
|
||||||
|
2 DERIVED t1 ALL NULL NULL NULL NULL 11 100.00
|
||||||
|
2 DERIVED t11 ALL NULL NULL NULL NULL 11 100.00 Using where; Using join buffer (flat, BNL join)
|
||||||
|
Warnings:
|
||||||
|
Note 1003 select `test`.`t1`.`f1` AS `f1`,`test`.`t1`.`f11` AS `f11`,`v31`.`f1` AS `f1`,`v31`.`f11` AS `f11`,`v3`.`f1` AS `f1`,`v3`.`f11` AS `f11` from `test`.`t1` join `test`.`v3` `v31` join `test`.`v3` where ((`v31`.`f1` = `test`.`t1`.`f1`) and (`v3`.`f1` = `test`.`t1`.`f1`))
|
||||||
|
flush status;
|
||||||
|
select * from t1,v3 as v31,v3 where t1.f1=v31.f1 and t1.f1=v3.f1;
|
||||||
|
f1 f11 f1 f11 f1 f11
|
||||||
|
1 1 1 1 1 1
|
||||||
|
2 2 2 2 2 2
|
||||||
|
3 3 3 3 3 3
|
||||||
|
5 5 5 5 5 5
|
||||||
|
9 9 9 9 9 9
|
||||||
|
7 7 7 7 7 7
|
||||||
|
17 17 17 17 17 17
|
||||||
|
13 13 13 13 13 13
|
||||||
|
11 11 11 11 11 11
|
||||||
|
15 15 15 15 15 15
|
||||||
|
19 19 19 19 19 19
|
||||||
|
show status like 'Handler_read%';
|
||||||
|
Variable_name Value
|
||||||
|
Handler_read_first 0
|
||||||
|
Handler_read_key 22
|
||||||
|
Handler_read_next 22
|
||||||
|
Handler_read_prev 0
|
||||||
|
Handler_read_rnd 0
|
||||||
|
Handler_read_rnd_next 60
|
||||||
|
explain showing late materialization
|
||||||
|
flush status;
|
||||||
|
explain select * from t1 join v2 on f1=f2;
|
||||||
|
id select_type table type possible_keys key key_len ref rows Extra
|
||||||
|
1 PRIMARY t1 ALL NULL NULL NULL NULL 11 Using where
|
||||||
|
1 PRIMARY <derived2> ref key0 key0 5 test.t1.f1 2
|
||||||
|
2 DERIVED t2 ALL NULL NULL NULL NULL 11 Using temporary; Using filesort
|
||||||
|
show status like 'Handler_read%';
|
||||||
|
Variable_name Value
|
||||||
|
Handler_read_first 0
|
||||||
|
Handler_read_key 0
|
||||||
|
Handler_read_next 0
|
||||||
|
Handler_read_prev 0
|
||||||
|
Handler_read_rnd 0
|
||||||
|
Handler_read_rnd_next 0
|
||||||
|
flush status;
|
||||||
|
select * from t1 join v2 on f1=f2;
|
||||||
|
f1 f11 f2 f22
|
||||||
|
1 1 1 1
|
||||||
|
2 2 2 2
|
||||||
|
3 3 3 3
|
||||||
|
show status like 'Handler_read%';
|
||||||
|
Variable_name Value
|
||||||
|
Handler_read_first 0
|
||||||
|
Handler_read_key 11
|
||||||
|
Handler_read_next 3
|
||||||
|
Handler_read_prev 0
|
||||||
|
Handler_read_rnd 11
|
||||||
|
Handler_read_rnd_next 36
|
||||||
|
explain extended select * from v1 join v4 on f1=f2;
|
||||||
|
id select_type table type possible_keys key key_len ref rows filtered Extra
|
||||||
|
1 PRIMARY t2 ALL NULL NULL NULL NULL 11 100.00 Using where
|
||||||
|
1 PRIMARY <derived2> ref key0 key0 5 test.t2.f2 2 100.00
|
||||||
|
2 DERIVED t1 ALL NULL NULL NULL NULL 11 100.00 Using temporary; Using filesort
|
||||||
|
Warnings:
|
||||||
|
Note 1003 select `v1`.`f1` AS `f1`,`v1`.`f11` AS `f11`,`test`.`t2`.`f2` AS `f2`,`test`.`t2`.`f22` AS `f22` from `test`.`v1` join `test`.`t2` where ((`v1`.`f1` = `test`.`t2`.`f2`) and (`test`.`t2`.`f2` in (2,3)))
|
||||||
|
select * from v1 join v4 on f1=f2;
|
||||||
|
f1 f11 f2 f22
|
||||||
|
3 3 3 3
|
||||||
|
2 2 2 2
|
||||||
|
merged derived in merged derived
|
||||||
|
explain extended select * from (select * from
|
||||||
|
(select * from t1 where f1 < 7) tt where f1 > 2) zz;
|
||||||
|
id select_type table type possible_keys key key_len ref rows filtered Extra
|
||||||
|
1 SIMPLE t1 ALL NULL NULL NULL NULL 11 100.00 Using where
|
||||||
|
Warnings:
|
||||||
|
Note 1003 select `test`.`t1`.`f1` AS `f1`,`test`.`t1`.`f11` AS `f11` from `test`.`t1` where ((`test`.`t1`.`f1` > 2) and (`test`.`t1`.`f1` < 7))
|
||||||
|
select * from (select * from
|
||||||
|
(select * from t1 where f1 < 7) tt where f1 > 2) zz;
|
||||||
|
f1 f11
|
||||||
|
3 3
|
||||||
|
5 5
|
||||||
|
materialized derived in merged derived
|
||||||
|
explain extended select * from (select * from
|
||||||
|
(select * from t1 where f1 < 7 group by f1) tt where f1 > 2) zz;
|
||||||
|
id select_type table type possible_keys key key_len ref rows filtered Extra
|
||||||
|
1 SIMPLE <derived3> ALL NULL NULL NULL NULL 11 100.00 Using where
|
||||||
|
3 DERIVED t1 ALL NULL NULL NULL NULL 11 100.00 Using where; Using temporary; Using filesort
|
||||||
|
Warnings:
|
||||||
|
Note 1003 select `tt`.`f1` AS `f1`,`tt`.`f11` AS `f11` from (select `test`.`t1`.`f1` AS `f1`,`test`.`t1`.`f11` AS `f11` from `test`.`t1` where (`test`.`t1`.`f1` < 7) group by `test`.`t1`.`f1`) `tt` where (`tt`.`f1` > 2)
|
||||||
|
select * from (select * from
|
||||||
|
(select * from t1 where f1 < 7 group by f1) tt where f1 > 2) zz;
|
||||||
|
f1 f11
|
||||||
|
3 3
|
||||||
|
5 5
|
||||||
|
merged derived in materialized derived
|
||||||
|
explain extended select * from (select * from
|
||||||
|
(select * from t1 where f1 < 7) tt where f1 > 2 group by f1) zz;
|
||||||
|
id select_type table type possible_keys key key_len ref rows filtered Extra
|
||||||
|
1 PRIMARY <derived2> ALL NULL NULL NULL NULL 11 100.00
|
||||||
|
2 DERIVED t1 ALL NULL NULL NULL NULL 11 100.00 Using where; Using temporary; Using filesort
|
||||||
|
Warnings:
|
||||||
|
Note 1003 select `zz`.`f1` AS `f1`,`zz`.`f11` AS `f11` from (select `test`.`t1`.`f1` AS `f1`,`test`.`t1`.`f11` AS `f11` from `test`.`t1` where ((`test`.`t1`.`f1` > 2) and (`test`.`t1`.`f1` < 7)) group by `test`.`t1`.`f1`) `zz`
|
||||||
|
select * from (select * from
|
||||||
|
(select * from t1 where f1 < 7) tt where f1 > 2 group by f1) zz;
|
||||||
|
f1 f11
|
||||||
|
3 3
|
||||||
|
5 5
|
||||||
|
materialized derived in materialized derived
|
||||||
|
explain extended select * from (select * from
|
||||||
|
(select * from t1 where f1 < 7 group by f1) tt where f1 > 2 group by f1) zz;
|
||||||
|
id select_type table type possible_keys key key_len ref rows filtered Extra
|
||||||
|
1 PRIMARY <derived2> ALL NULL NULL NULL NULL 11 100.00
|
||||||
|
2 DERIVED <derived3> ALL NULL NULL NULL NULL 11 100.00 Using where; Using temporary; Using filesort
|
||||||
|
3 DERIVED t1 ALL NULL NULL NULL NULL 11 100.00 Using where; Using temporary; Using filesort
|
||||||
|
Warnings:
|
||||||
|
Note 1003 select `zz`.`f1` AS `f1`,`zz`.`f11` AS `f11` from (select `tt`.`f1` AS `f1`,`tt`.`f11` AS `f11` from (select `test`.`t1`.`f1` AS `f1`,`test`.`t1`.`f11` AS `f11` from `test`.`t1` where (`test`.`t1`.`f1` < 7) group by `test`.`t1`.`f1`) `tt` where (`tt`.`f1` > 2) group by `tt`.`f1`) `zz`
|
||||||
|
select * from (select * from
|
||||||
|
(select * from t1 where f1 < 7 group by f1) tt where f1 > 2 group by f1) zz;
|
||||||
|
f1 f11
|
||||||
|
3 3
|
||||||
|
5 5
|
||||||
|
mat in merged derived join mat in merged derived
|
||||||
|
explain extended select * from
|
||||||
|
(select * from (select * from t1 where f1 < 7 group by f1) tt where f1 > 2) x
|
||||||
|
join
|
||||||
|
(select * from (select * from t1 where f1 < 7 group by f1) tt where f1 > 2) z
|
||||||
|
on x.f1 = z.f1;
|
||||||
|
id select_type table type possible_keys key key_len ref rows filtered Extra
|
||||||
|
1 SIMPLE <derived3> ALL key0 NULL NULL NULL 11 100.00 Using where
|
||||||
|
1 SIMPLE <derived5> ref key0 key0 5 tt.f1 2 100.00
|
||||||
|
5 DERIVED t1 ALL NULL NULL NULL NULL 11 100.00 Using where; Using temporary; Using filesort
|
||||||
|
3 DERIVED t1 ALL NULL NULL NULL NULL 11 100.00 Using where; Using temporary; Using filesort
|
||||||
|
Warnings:
|
||||||
|
Note 1003 select `tt`.`f1` AS `f1`,`tt`.`f11` AS `f11`,`tt`.`f1` AS `f1`,`tt`.`f11` AS `f11` from (select `test`.`t1`.`f1` AS `f1`,`test`.`t1`.`f11` AS `f11` from `test`.`t1` where (`test`.`t1`.`f1` < 7) group by `test`.`t1`.`f1`) `tt` join (select `test`.`t1`.`f1` AS `f1`,`test`.`t1`.`f11` AS `f11` from `test`.`t1` where (`test`.`t1`.`f1` < 7) group by `test`.`t1`.`f1`) `tt` where ((`tt`.`f1` = `tt`.`f1`) and (`tt`.`f1` > 2) and (`tt`.`f1` > 2))
|
||||||
|
flush status;
|
||||||
|
select * from
|
||||||
|
(select * from (select * from t1 where f1 < 7 group by f1) tt where f1 > 2) x
|
||||||
|
join
|
||||||
|
(select * from (select * from t1 where f1 < 7 group by f1) tt where f1 > 2) z
|
||||||
|
on x.f1 = z.f1;
|
||||||
|
f1 f11 f1 f11
|
||||||
|
3 3 3 3
|
||||||
|
5 5 5 5
|
||||||
|
show status like 'Handler_read%';
|
||||||
|
Variable_name Value
|
||||||
|
Handler_read_first 0
|
||||||
|
Handler_read_key 2
|
||||||
|
Handler_read_next 2
|
||||||
|
Handler_read_prev 0
|
||||||
|
Handler_read_rnd 8
|
||||||
|
Handler_read_rnd_next 39
|
||||||
|
flush status;
|
||||||
|
merged in merged derived join merged in merged derived
|
||||||
|
explain extended select * from
|
||||||
|
(select * from
|
||||||
|
(select * from t1 where f1 < 7 ) tt where f1 > 2 ) x
|
||||||
|
join
|
||||||
|
(select * from
|
||||||
|
(select * from t1 where f1 < 7 ) tt where f1 > 2 ) z
|
||||||
|
on x.f1 = z.f1;
|
||||||
|
id select_type table type possible_keys key key_len ref rows filtered Extra
|
||||||
|
1 SIMPLE t1 ALL NULL NULL NULL NULL 11 100.00 Using where
|
||||||
|
1 SIMPLE t1 ALL NULL NULL NULL NULL 11 100.00 Using where; Using join buffer (flat, BNL join)
|
||||||
|
Warnings:
|
||||||
|
Note 1003 select `test`.`t1`.`f1` AS `f1`,`test`.`t1`.`f11` AS `f11`,`test`.`t1`.`f1` AS `f1`,`test`.`t1`.`f11` AS `f11` from `test`.`t1` join `test`.`t1` where ((`test`.`t1`.`f1` = `test`.`t1`.`f1`) and (`test`.`t1`.`f1` > 2) and (`test`.`t1`.`f1` < 7) and (`test`.`t1`.`f1` > 2) and (`test`.`t1`.`f1` < 7))
|
||||||
|
select * from
|
||||||
|
(select * from
|
||||||
|
(select * from t1 where f1 < 7 ) tt where f1 > 2 ) x
|
||||||
|
join
|
||||||
|
(select * from
|
||||||
|
(select * from t1 where f1 < 7 ) tt where f1 > 2 ) z
|
||||||
|
on x.f1 = z.f1;
|
||||||
|
f1 f11 f1 f11
|
||||||
|
3 3 3 3
|
||||||
|
5 5 5 5
|
||||||
|
materialized in materialized derived join
|
||||||
|
materialized in materialized derived
|
||||||
|
explain extended select * from
|
||||||
|
(select * from
|
||||||
|
(select * from t1 where f1 < 7 group by f1) tt where f1 > 2 group by f1) x
|
||||||
|
join
|
||||||
|
(select * from
|
||||||
|
(select * from t1 where f1 < 7 group by f1) tt where f1 > 2 group by f1) z
|
||||||
|
on x.f1 = z.f1;
|
||||||
|
id select_type table type possible_keys key key_len ref rows filtered Extra
|
||||||
|
1 PRIMARY <derived2> ALL key0 NULL NULL NULL 11 100.00 Using where
|
||||||
|
1 PRIMARY <derived4> ref key0 key0 5 x.f1 2 100.00
|
||||||
|
4 DERIVED <derived5> ALL NULL NULL NULL NULL 11 100.00 Using where; Using temporary; Using filesort
|
||||||
|
5 DERIVED t1 ALL NULL NULL NULL NULL 11 100.00 Using where; Using temporary; Using filesort
|
||||||
|
2 DERIVED <derived3> ALL NULL NULL NULL NULL 11 100.00 Using where; Using temporary; Using filesort
|
||||||
|
3 DERIVED t1 ALL NULL NULL NULL NULL 11 100.00 Using where; Using temporary; Using filesort
|
||||||
|
Warnings:
|
||||||
|
Note 1003 select `x`.`f1` AS `f1`,`x`.`f11` AS `f11`,`z`.`f1` AS `f1`,`z`.`f11` AS `f11` from (select `tt`.`f1` AS `f1`,`tt`.`f11` AS `f11` from (select `test`.`t1`.`f1` AS `f1`,`test`.`t1`.`f11` AS `f11` from `test`.`t1` where (`test`.`t1`.`f1` < 7) group by `test`.`t1`.`f1`) `tt` where (`tt`.`f1` > 2) group by `tt`.`f1`) `x` join (select `tt`.`f1` AS `f1`,`tt`.`f11` AS `f11` from (select `test`.`t1`.`f1` AS `f1`,`test`.`t1`.`f11` AS `f11` from `test`.`t1` where (`test`.`t1`.`f1` < 7) group by `test`.`t1`.`f1`) `tt` where (`tt`.`f1` > 2) group by `tt`.`f1`) `z` where (`z`.`f1` = `x`.`f1`)
|
||||||
|
select * from
|
||||||
|
(select * from
|
||||||
|
(select * from t1 where f1 < 7 group by f1) tt where f1 > 2 group by f1) x
|
||||||
|
join
|
||||||
|
(select * from
|
||||||
|
(select * from t1 where f1 < 7 group by f1) tt where f1 > 2 group by f1) z
|
||||||
|
on x.f1 = z.f1;
|
||||||
|
f1 f11 f1 f11
|
||||||
|
3 3 3 3
|
||||||
|
5 5 5 5
|
||||||
|
merged view in materialized derived
|
||||||
|
explain extended
|
||||||
|
select * from (select * from v4 group by 1) tt;
|
||||||
|
id select_type table type possible_keys key key_len ref rows filtered Extra
|
||||||
|
1 PRIMARY <derived2> ALL NULL NULL NULL NULL 11 100.00
|
||||||
|
2 DERIVED t2 ALL NULL NULL NULL NULL 11 100.00 Using where; Using temporary; Using filesort
|
||||||
|
Warnings:
|
||||||
|
Note 1003 select `tt`.`f2` AS `f2`,`tt`.`f22` AS `f22` from (select `test`.`t2`.`f2` AS `f2`,`test`.`t2`.`f22` AS `f22` from `test`.`t2` where (`test`.`t2`.`f2` in (2,3)) group by 1) `tt`
|
||||||
|
select * from (select * from v4 group by 1) tt;
|
||||||
|
f2 f22
|
||||||
|
2 2
|
||||||
|
3 3
|
||||||
|
materialized view in merged derived
|
||||||
|
explain extended
|
||||||
|
select * from ( select * from v1 where f1 < 7) tt;
|
||||||
|
id select_type table type possible_keys key key_len ref rows filtered Extra
|
||||||
|
1 SIMPLE <derived3> ALL NULL NULL NULL NULL 11 100.00 Using where
|
||||||
|
3 DERIVED t1 ALL NULL NULL NULL NULL 11 100.00 Using temporary; Using filesort
|
||||||
|
Warnings:
|
||||||
|
Note 1003 select `v1`.`f1` AS `f1`,`v1`.`f11` AS `f11` from `test`.`v1` where (`v1`.`f1` < 7)
|
||||||
|
select * from ( select * from v1 where f1 < 7) tt;
|
||||||
|
f1 f11
|
||||||
|
1 1
|
||||||
|
2 2
|
||||||
|
3 3
|
||||||
|
5 5
|
||||||
|
merged view in a merged view in a merged derived
|
||||||
|
create view v6 as select * from v4 where f2 < 7;
|
||||||
|
explain extended select * from (select * from v6) tt;
|
||||||
|
id select_type table type possible_keys key key_len ref rows filtered Extra
|
||||||
|
1 SIMPLE t2 ALL NULL NULL NULL NULL 11 100.00 Using where
|
||||||
|
Warnings:
|
||||||
|
Note 1003 select `test`.`t2`.`f2` AS `f2`,`test`.`t2`.`f22` AS `f22` from `test`.`t2` where ((`test`.`t2`.`f2` < 7) and (`test`.`t2`.`f2` in (2,3)))
|
||||||
|
select * from (select * from v6) tt;
|
||||||
|
f2 f22
|
||||||
|
3 3
|
||||||
|
2 2
|
||||||
|
materialized view in a merged view in a materialized derived
|
||||||
|
create view v7 as select * from v1;
|
||||||
|
explain extended select * from (select * from v7 group by 1) tt;
|
||||||
|
id select_type table type possible_keys key key_len ref rows filtered Extra
|
||||||
|
1 PRIMARY <derived2> ALL NULL NULL NULL NULL 11 100.00
|
||||||
|
2 DERIVED <derived4> ALL NULL NULL NULL NULL 11 100.00 Using temporary; Using filesort
|
||||||
|
4 DERIVED t1 ALL NULL NULL NULL NULL 11 100.00 Using temporary; Using filesort
|
||||||
|
Warnings:
|
||||||
|
Note 1003 select `tt`.`f1` AS `f1`,`tt`.`f11` AS `f11` from (select `v1`.`f1` AS `f1`,`v1`.`f11` AS `f11` from `test`.`v1` group by 1) `tt`
|
||||||
|
select * from (select * from v7 group by 1) tt;
|
||||||
|
f1 f11
|
||||||
|
1 1
|
||||||
|
2 2
|
||||||
|
3 3
|
||||||
|
5 5
|
||||||
|
7 7
|
||||||
|
9 9
|
||||||
|
11 11
|
||||||
|
13 13
|
||||||
|
15 15
|
||||||
|
17 17
|
||||||
|
19 19
|
||||||
|
join of above two
|
||||||
|
explain extended select * from v6 join v7 on f2=f1;
|
||||||
|
id select_type table type possible_keys key key_len ref rows filtered Extra
|
||||||
|
1 SIMPLE t2 ALL NULL NULL NULL NULL 11 100.00 Using where
|
||||||
|
1 SIMPLE <derived5> ref key0 key0 5 test.t2.f2 2 100.00
|
||||||
|
5 DERIVED t1 ALL NULL NULL NULL NULL 11 100.00 Using temporary; Using filesort
|
||||||
|
Warnings:
|
||||||
|
Note 1003 select `test`.`t2`.`f2` AS `f2`,`test`.`t2`.`f22` AS `f22`,`v1`.`f1` AS `f1`,`v1`.`f11` AS `f11` from `test`.`t2` join `test`.`v1` where ((`v1`.`f1` = `test`.`t2`.`f2`) and (`test`.`t2`.`f2` < 7) and (`test`.`t2`.`f2` in (2,3)))
|
||||||
|
select * from v6 join v7 on f2=f1;
|
||||||
|
f2 f22 f1 f11
|
||||||
|
3 3 3 3
|
||||||
|
2 2 2 2
|
||||||
|
test two keys
|
||||||
|
explain select * from t1 join (select * from t2 group by f2) tt on t1.f1=tt.f2 join t1 xx on tt.f22=xx.f1;
|
||||||
|
id select_type table type possible_keys key key_len ref rows Extra
|
||||||
|
1 PRIMARY t1 ALL NULL NULL NULL NULL 11 Using where
|
||||||
|
1 PRIMARY <derived2> ref key0 key0 5 test.t1.f1 2
|
||||||
|
1 PRIMARY xx ALL NULL NULL NULL NULL 11 Using where; Using join buffer (flat, BNL join)
|
||||||
|
2 DERIVED t2 ALL NULL NULL NULL NULL 11 Using temporary; Using filesort
|
||||||
|
select * from t1 join (select * from t2 group by f2) tt on t1.f1=tt.f2 join t1 xx on tt.f22=xx.f1;
|
||||||
|
f1 f11 f2 f22 f1 f11
|
||||||
|
1 1 1 1 1 1
|
||||||
|
2 2 2 2 2 2
|
||||||
|
3 3 3 3 3 3
|
||||||
|
TODO: Add test with 64 tables mergeable view to test fall back to
|
||||||
|
materialization on tables > MAX_TABLES merge
|
||||||
|
drop table t1,t2;
|
||||||
|
drop view v1,v2,v3,v4,v6,v7;
|
@ -102,7 +102,7 @@ INSERT INTO t2 VALUES (),(),();
|
|||||||
EXPLAIN SELECT 1 FROM
|
EXPLAIN SELECT 1 FROM
|
||||||
(SELECT 1 FROM t2,t1 WHERE b < c GROUP BY 1 LIMIT 1) AS d2;
|
(SELECT 1 FROM t2,t1 WHERE b < c GROUP BY 1 LIMIT 1) AS d2;
|
||||||
id select_type table type possible_keys key key_len ref rows Extra
|
id select_type table type possible_keys key key_len ref rows Extra
|
||||||
X X X X X X X X X const row not found
|
X X X X X X X X X
|
||||||
X X X X X X X X X
|
X X X X X X X X X
|
||||||
X X X X X X X X X Range checked for each record (index map: 0xFFFFFFFFFF)
|
X X X X X X X X X Range checked for each record (index map: 0xFFFFFFFFFF)
|
||||||
DROP TABLE t2;
|
DROP TABLE t2;
|
||||||
@ -114,7 +114,7 @@ INSERT INTO t2 VALUES (1),(2);
|
|||||||
EXPLAIN EXTENDED SELECT 1
|
EXPLAIN EXTENDED SELECT 1
|
||||||
FROM (SELECT COUNT(DISTINCT t1.a) FROM t1,t2 GROUP BY t1.a) AS s1;
|
FROM (SELECT COUNT(DISTINCT t1.a) FROM t1,t2 GROUP BY t1.a) AS s1;
|
||||||
id select_type table type possible_keys key key_len ref rows filtered Extra
|
id select_type table type possible_keys key key_len ref rows filtered Extra
|
||||||
1 PRIMARY <derived2> ALL NULL NULL NULL NULL 2 100.00
|
1 PRIMARY <derived2> ALL NULL NULL NULL NULL 4 100.00
|
||||||
2 DERIVED t1 ALL NULL NULL NULL NULL 2 100.00 Using temporary; Using filesort
|
2 DERIVED t1 ALL NULL NULL NULL NULL 2 100.00 Using temporary; Using filesort
|
||||||
2 DERIVED t2 ALL NULL NULL NULL NULL 2 100.00 Using join buffer (flat, BNL join)
|
2 DERIVED t2 ALL NULL NULL NULL NULL 2 100.00 Using join buffer (flat, BNL join)
|
||||||
Warnings:
|
Warnings:
|
||||||
@ -122,7 +122,7 @@ Note 1003 select 1 AS `1` from (select count(distinct `test`.`t1`.`a`) AS `COUNT
|
|||||||
EXPLAIN EXTENDED SELECT 1
|
EXPLAIN EXTENDED SELECT 1
|
||||||
FROM (SELECT COUNT(DISTINCT t1.a) FROM t1,t2 GROUP BY t1.a) AS s1;
|
FROM (SELECT COUNT(DISTINCT t1.a) FROM t1,t2 GROUP BY t1.a) AS s1;
|
||||||
id select_type table type possible_keys key key_len ref rows filtered Extra
|
id select_type table type possible_keys key key_len ref rows filtered Extra
|
||||||
1 PRIMARY <derived2> ALL NULL NULL NULL NULL 2 100.00
|
1 PRIMARY <derived2> ALL NULL NULL NULL NULL 4 100.00
|
||||||
2 DERIVED t1 ALL NULL NULL NULL NULL 2 100.00 Using temporary; Using filesort
|
2 DERIVED t1 ALL NULL NULL NULL NULL 2 100.00 Using temporary; Using filesort
|
||||||
2 DERIVED t2 ALL NULL NULL NULL NULL 2 100.00 Using join buffer (flat, BNL join)
|
2 DERIVED t2 ALL NULL NULL NULL NULL 2 100.00 Using join buffer (flat, BNL join)
|
||||||
Warnings:
|
Warnings:
|
||||||
@ -132,7 +132,7 @@ prepare s1 from
|
|||||||
FROM (SELECT COUNT(DISTINCT t1.a) FROM t1,t2 GROUP BY t1.a) AS s1';
|
FROM (SELECT COUNT(DISTINCT t1.a) FROM t1,t2 GROUP BY t1.a) AS s1';
|
||||||
execute s1;
|
execute s1;
|
||||||
id select_type table type possible_keys key key_len ref rows filtered Extra
|
id select_type table type possible_keys key key_len ref rows filtered Extra
|
||||||
1 PRIMARY <derived2> ALL NULL NULL NULL NULL 2 100.00
|
1 PRIMARY <derived2> ALL NULL NULL NULL NULL 4 100.00
|
||||||
2 DERIVED t1 ALL NULL NULL NULL NULL 2 100.00 Using temporary; Using filesort
|
2 DERIVED t1 ALL NULL NULL NULL NULL 2 100.00 Using temporary; Using filesort
|
||||||
2 DERIVED t2 ALL NULL NULL NULL NULL 2 100.00 Using join buffer (flat, BNL join)
|
2 DERIVED t2 ALL NULL NULL NULL NULL 2 100.00 Using join buffer (flat, BNL join)
|
||||||
Warnings:
|
Warnings:
|
||||||
@ -142,14 +142,14 @@ prepare s1 from
|
|||||||
FROM (SELECT COUNT(DISTINCT t1.a) FROM t1,t2 GROUP BY t1.a) AS s1';
|
FROM (SELECT COUNT(DISTINCT t1.a) FROM t1,t2 GROUP BY t1.a) AS s1';
|
||||||
execute s1;
|
execute s1;
|
||||||
id select_type table type possible_keys key key_len ref rows filtered Extra
|
id select_type table type possible_keys key key_len ref rows filtered Extra
|
||||||
1 PRIMARY <derived2> ALL NULL NULL NULL NULL 2 100.00
|
1 PRIMARY <derived2> ALL NULL NULL NULL NULL 4 100.00
|
||||||
2 DERIVED t1 ALL NULL NULL NULL NULL 2 100.00 Using temporary; Using filesort
|
2 DERIVED t1 ALL NULL NULL NULL NULL 2 100.00 Using temporary; Using filesort
|
||||||
2 DERIVED t2 ALL NULL NULL NULL NULL 2 100.00 Using join buffer (flat, BNL join)
|
2 DERIVED t2 ALL NULL NULL NULL NULL 2 100.00 Using join buffer (flat, BNL join)
|
||||||
Warnings:
|
Warnings:
|
||||||
Note 1003 select 1 AS `1` from (select count(distinct `test`.`t1`.`a`) AS `COUNT(DISTINCT t1.a)` from `test`.`t1` join `test`.`t2` group by `test`.`t1`.`a`) `s1`
|
Note 1003 select 1 AS `1` from (select count(distinct `test`.`t1`.`a`) AS `COUNT(DISTINCT t1.a)` from `test`.`t1` join `test`.`t2` group by `test`.`t1`.`a`) `s1`
|
||||||
execute s1;
|
execute s1;
|
||||||
id select_type table type possible_keys key key_len ref rows filtered Extra
|
id select_type table type possible_keys key key_len ref rows filtered Extra
|
||||||
1 PRIMARY <derived2> ALL NULL NULL NULL NULL 2 100.00
|
1 PRIMARY <derived2> ALL NULL NULL NULL NULL 4 100.00
|
||||||
2 DERIVED t1 ALL NULL NULL NULL NULL 2 100.00 Using temporary; Using filesort
|
2 DERIVED t1 ALL NULL NULL NULL NULL 2 100.00 Using temporary; Using filesort
|
||||||
2 DERIVED t2 ALL NULL NULL NULL NULL 2 100.00 Using join buffer (flat, BNL join)
|
2 DERIVED t2 ALL NULL NULL NULL NULL 2 100.00 Using join buffer (flat, BNL join)
|
||||||
Warnings:
|
Warnings:
|
||||||
@ -312,8 +312,7 @@ INSERT INTO t2 VALUES (8);
|
|||||||
EXPLAIN EXTENDED
|
EXPLAIN EXTENDED
|
||||||
SELECT * FROM ( SELECT t1.a FROM t1,t2 WHERE t2.a = t1.a ) AS t;
|
SELECT * FROM ( SELECT t1.a FROM t1,t2 WHERE t2.a = t1.a ) AS t;
|
||||||
id select_type table type possible_keys key key_len ref rows filtered Extra
|
id select_type table type possible_keys key key_len ref rows filtered Extra
|
||||||
1 PRIMARY <derived2> system NULL NULL NULL NULL 0 0.00 const row not found
|
1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables
|
||||||
2 DERIVED NULL NULL NULL NULL NULL NULL NULL NULL no matching row in const table
|
|
||||||
Warnings:
|
Warnings:
|
||||||
Note 1003 select NULL AS `a` from (select NULL AS `a` from `test`.`t1` join `test`.`t2` where 0) `t`
|
Note 1003 select NULL AS `a` from `test`.`t1` join `test`.`t2` where 0
|
||||||
DROP TABLE t1,t2;
|
DROP TABLE t1,t2;
|
||||||
|
@ -983,10 +983,10 @@ INSERT INTO t1 VALUES (),();
|
|||||||
EXPLAIN EXTENDED SELECT 1 FROM
|
EXPLAIN EXTENDED SELECT 1 FROM
|
||||||
(SELECT DISTINCT GROUP_CONCAT(td.f1) FROM t1,t1 AS td GROUP BY td.f1) AS d,t1;
|
(SELECT DISTINCT GROUP_CONCAT(td.f1) FROM t1,t1 AS td GROUP BY td.f1) AS d,t1;
|
||||||
id select_type table type possible_keys key key_len ref rows filtered Extra
|
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 t1 ALL NULL NULL NULL NULL 2 100.00
|
1 PRIMARY t1 ALL NULL NULL NULL NULL 2 100.00
|
||||||
2 DERIVED t1 ALL NULL NULL NULL NULL 2 100.00 Using temporary; Using filesort; Distinct
|
1 PRIMARY <derived2> ALL NULL NULL NULL NULL 4 100.00 Using join buffer (flat, BNL join)
|
||||||
2 DERIVED td ALL NULL NULL NULL NULL 2 100.00 Distinct; Using join buffer (flat, BNL join)
|
2 DERIVED t1 ALL NULL NULL NULL NULL 2 100.00 Using temporary; Using filesort
|
||||||
|
2 DERIVED td ALL NULL NULL NULL NULL 2 100.00 Using join buffer (flat, BNL join)
|
||||||
Warnings:
|
Warnings:
|
||||||
Note 1003 select 1 AS `1` from (select distinct group_concat(`test`.`td`.`f1` separator ',') AS `GROUP_CONCAT(td.f1)` from `test`.`t1` join `test`.`t1` `td` group by `test`.`td`.`f1`) `d` join `test`.`t1`
|
Note 1003 select 1 AS `1` from (select distinct group_concat(`test`.`td`.`f1` separator ',') AS `GROUP_CONCAT(td.f1)` from `test`.`t1` join `test`.`t1` `td` group by `test`.`td`.`f1`) `d` join `test`.`t1`
|
||||||
SELECT 1 FROM
|
SELECT 1 FROM
|
||||||
@ -1005,7 +1005,7 @@ EXPLAIN EXTENDED SELECT 1 FROM
|
|||||||
(SELECT GROUP_CONCAT(t1.a ORDER BY t1.a ASC) FROM
|
(SELECT GROUP_CONCAT(t1.a ORDER BY t1.a ASC) FROM
|
||||||
t1 t2, t1 GROUP BY t1.a) AS d;
|
t1 t2, t1 GROUP BY t1.a) AS d;
|
||||||
id select_type table type possible_keys key key_len ref rows filtered Extra
|
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 <derived2> ALL NULL NULL NULL NULL 4 100.00
|
||||||
2 DERIVED t2 ALL NULL NULL NULL NULL 2 100.00 Using temporary; Using filesort
|
2 DERIVED t2 ALL NULL NULL NULL NULL 2 100.00 Using temporary; Using filesort
|
||||||
2 DERIVED t1 ALL NULL NULL NULL NULL 2 100.00 Using join buffer (flat, BNL join)
|
2 DERIVED t1 ALL NULL NULL NULL NULL 2 100.00 Using join buffer (flat, BNL join)
|
||||||
Warnings:
|
Warnings:
|
||||||
@ -1035,7 +1035,7 @@ DROP TABLE t1;
|
|||||||
CREATE TABLE t1(f1 int);
|
CREATE TABLE t1(f1 int);
|
||||||
INSERT INTO t1 values (0),(0);
|
INSERT INTO t1 values (0),(0);
|
||||||
SELECT POLYGON((SELECT 1 FROM (SELECT 1 IN (GROUP_CONCAT(t1.f1)) FROM t1, t1 t GROUP BY t.f1 ) d));
|
SELECT POLYGON((SELECT 1 FROM (SELECT 1 IN (GROUP_CONCAT(t1.f1)) FROM t1, t1 t GROUP BY t.f1 ) d));
|
||||||
ERROR 22007: Illegal non geometric '(select 1 from (select (1 = group_concat(`test`.`t1`.`f1` separator ',')) AS `1 IN (GROUP_CONCAT(t1.f1))` from `test`.`t1` join `test`.`t1` `t` group by `t`.`f1`) `d`)' value found during parsing
|
ERROR 22007: Illegal non geometric '(select 1 from (select (1 = group_concat(`test`.`t1`.`f1` separator ',')) AS `1 IN (GROUP_CONCAT(t1.f1))` from `test`.`t1` join `test`.`t1` `t` group by `test`.`t`.`f1`) `d`)' value found during parsing
|
||||||
DROP TABLE t1;
|
DROP TABLE t1;
|
||||||
#
|
#
|
||||||
# Bug#58396 group_concat and explain extended are still crashy
|
# Bug#58396 group_concat and explain extended are still crashy
|
||||||
|
@ -1874,9 +1874,8 @@ HAVING ('m') IN (
|
|||||||
SELECT v
|
SELECT v
|
||||||
FROM t2);
|
FROM t2);
|
||||||
id select_type table type possible_keys key key_len ref rows Extra
|
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 empty1 system NULL NULL NULL NULL 0 const row not found
|
||||||
3 SUBQUERY t2 ALL NULL NULL NULL NULL 2
|
3 SUBQUERY t2 ALL NULL NULL NULL NULL 2
|
||||||
2 DERIVED NULL NULL NULL NULL NULL NULL NULL no matching row in const table
|
|
||||||
|
|
||||||
#
|
#
|
||||||
# 5) Test that subquery materialization is setup for query with
|
# 5) Test that subquery materialization is setup for query with
|
||||||
|
@ -2549,14 +2549,12 @@ create table t1(f1 tinyint default null)engine=myisam;
|
|||||||
insert into t1 values (-1),(null);
|
insert into t1 values (-1),(null);
|
||||||
explain select 1 as a from t1,(select decode(f1,f1) as b from t1) a;
|
explain select 1 as a from t1,(select decode(f1,f1) as b from t1) a;
|
||||||
id select_type table type possible_keys key key_len ref rows Extra
|
id select_type table type possible_keys key key_len ref rows Extra
|
||||||
1 PRIMARY t1 ALL NULL NULL NULL NULL 2
|
1 SIMPLE t1 ALL NULL NULL NULL NULL 2
|
||||||
1 PRIMARY <derived2> ALL NULL NULL NULL NULL 2 Using join buffer (flat, BNL join)
|
1 SIMPLE t1 ALL NULL NULL NULL NULL 2 Using join buffer (flat, BNL join)
|
||||||
2 DERIVED t1 ALL NULL NULL NULL NULL 2
|
|
||||||
explain select 1 as a from t1,(select encode(f1,f1) as b from t1) a;
|
explain select 1 as a from t1,(select encode(f1,f1) as b from t1) a;
|
||||||
id select_type table type possible_keys key key_len ref rows Extra
|
id select_type table type possible_keys key key_len ref rows Extra
|
||||||
1 PRIMARY t1 ALL NULL NULL NULL NULL 2
|
1 SIMPLE t1 ALL NULL NULL NULL NULL 2
|
||||||
1 PRIMARY <derived2> ALL NULL NULL NULL NULL 2 Using join buffer (flat, BNL join)
|
1 SIMPLE t1 ALL NULL NULL NULL NULL 2 Using join buffer (flat, BNL join)
|
||||||
2 DERIVED t1 ALL NULL NULL NULL NULL 2
|
|
||||||
drop table t1;
|
drop table t1;
|
||||||
#
|
#
|
||||||
# Bug#49141: Encode function is significantly slower in 5.1 compared to 5.0
|
# Bug#49141: Encode function is significantly slower in 5.1 compared to 5.0
|
||||||
|
@ -691,8 +691,7 @@ SELECT COUNT(*) FROM
|
|||||||
(SELECT * FROM t1 FORCE INDEX(primary,idx)
|
(SELECT * FROM t1 FORCE INDEX(primary,idx)
|
||||||
WHERE a BETWEEN 2 AND 7 OR pk=1000000) AS t;
|
WHERE a BETWEEN 2 AND 7 OR pk=1000000) AS t;
|
||||||
id select_type table type possible_keys key key_len ref rows Extra
|
id select_type table type possible_keys key key_len ref rows Extra
|
||||||
1 PRIMARY NULL NULL NULL NULL NULL NULL NULL Select tables optimized away
|
1 SIMPLE t1 index_merge PRIMARY,idx idx,PRIMARY 5,4 NULL 11419 Using sort_union(idx,PRIMARY); Using where
|
||||||
2 DERIVED t1 index_merge PRIMARY,idx idx,PRIMARY 5,4 NULL 11419 Using sort_union(idx,PRIMARY); Using where
|
|
||||||
SELECT COUNT(*) FROM
|
SELECT COUNT(*) FROM
|
||||||
(SELECT * FROM t1 FORCE INDEX(primary,idx)
|
(SELECT * FROM t1 FORCE INDEX(primary,idx)
|
||||||
WHERE a BETWEEN 2 AND 7 OR pk=1000000) AS t;
|
WHERE a BETWEEN 2 AND 7 OR pk=1000000) AS t;
|
||||||
@ -703,8 +702,7 @@ SELECT COUNT(*) FROM
|
|||||||
(SELECT * FROM t1 IGNORE INDEX(idx)
|
(SELECT * FROM t1 IGNORE INDEX(idx)
|
||||||
WHERE a BETWEEN 2 AND 7 OR pk=1000000) AS t;
|
WHERE a BETWEEN 2 AND 7 OR pk=1000000) AS t;
|
||||||
id select_type table type possible_keys key key_len ref rows Extra
|
id select_type table type possible_keys key key_len ref rows Extra
|
||||||
1 PRIMARY NULL NULL NULL NULL NULL NULL # Select tables optimized away
|
1 SIMPLE t1 ALL PRIMARY NULL NULL NULL # Using where
|
||||||
2 DERIVED t1 ALL PRIMARY NULL NULL NULL # Using where
|
|
||||||
SELECT COUNT(*) FROM
|
SELECT COUNT(*) FROM
|
||||||
(SELECT * FROM t1 IGNORE INDEX(idx)
|
(SELECT * FROM t1 IGNORE INDEX(idx)
|
||||||
WHERE a BETWEEN 2 AND 7 OR pk=1000000) AS t;
|
WHERE a BETWEEN 2 AND 7 OR pk=1000000) AS t;
|
||||||
|
@ -287,8 +287,7 @@ id select_type table type possible_keys key key_len ref rows Extra
|
|||||||
NULL UNION RESULT <union1,2> ALL NULL NULL NULL NULL NULL
|
NULL UNION RESULT <union1,2> ALL NULL NULL NULL NULL NULL
|
||||||
explain select * from (select * from t1 where key1 = 3 or key2 =3) as Z where key8 >5;
|
explain select * from (select * from t1 where key1 = 3 or key2 =3) as Z where key8 >5;
|
||||||
id select_type table type possible_keys key key_len ref rows Extra
|
id select_type table type possible_keys key key_len ref rows Extra
|
||||||
1 PRIMARY <derived2> system NULL NULL NULL NULL 1
|
1 SIMPLE t1 index_merge i1,i2,i8 i1,i2 4,4 NULL 2 Using union(i1,i2); Using where
|
||||||
2 DERIVED t1 index_merge i1,i2 i1,i2 4,4 NULL 2 Using union(i1,i2); Using where
|
|
||||||
create table t3 like t0;
|
create table t3 like t0;
|
||||||
insert into t3 select * from t0;
|
insert into t3 select * from t0;
|
||||||
alter table t3 add key9 int not null, add index i9(key9);
|
alter table t3 add key9 int not null, add index i9(key9);
|
||||||
|
@ -1288,8 +1288,7 @@ id select_type table type possible_keys key key_len ref rows Extra
|
|||||||
1 SIMPLE tables ALL NULL NULL NULL NULL NULL Open_frm_only; Scanned all databases; Using filesort
|
1 SIMPLE tables ALL NULL NULL NULL NULL NULL Open_frm_only; Scanned all databases; Using filesort
|
||||||
explain select * from (select table_name from information_schema.tables) as a;
|
explain select * from (select table_name from information_schema.tables) as a;
|
||||||
id select_type table type possible_keys key key_len ref rows Extra
|
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 SIMPLE tables ALL NULL NULL NULL NULL NULL Skip_open_table; Scanned all databases
|
||||||
2 DERIVED tables ALL NULL NULL NULL NULL NULL Skip_open_table; Scanned all databases
|
|
||||||
drop view v1;
|
drop view v1;
|
||||||
create table t1 (f1 int(11));
|
create table t1 (f1 int(11));
|
||||||
create table t2 (f1 int(11), f2 int(11));
|
create table t2 (f1 int(11), f2 int(11));
|
||||||
|
@ -2,7 +2,9 @@ SET @odl_sync_frm = @@global.sync_frm;
|
|||||||
SET @@global.sync_frm = OFF;
|
SET @@global.sync_frm = OFF;
|
||||||
DROP TABLE IF EXISTS t1;
|
DROP TABLE IF EXISTS t1;
|
||||||
CREATE TABLE t1( a INT, b INT );
|
CREATE TABLE t1( a INT, b INT );
|
||||||
|
CREATE TABLE t2( a INT, b INT );
|
||||||
INSERT INTO t1 VALUES (1, 1), (2, 2), (3, 3), (4, 4);
|
INSERT INTO t1 VALUES (1, 1), (2, 2), (3, 3), (4, 4);
|
||||||
|
INSERT INTO t2 VALUES (1, 1), (2, 2), (3, 3), (4, 4);
|
||||||
# 1. test regular tables
|
# 1. test regular tables
|
||||||
# 1.1. test altering of columns that multiupdate doesn't use
|
# 1.1. test altering of columns that multiupdate doesn't use
|
||||||
# 1.1.1. normal mode
|
# 1.1.1. normal mode
|
||||||
@ -18,5 +20,5 @@ ALTER TABLE t1 ADD COLUMN a INT;
|
|||||||
# 2.2. test altering of columns that multiupdate uses
|
# 2.2. test altering of columns that multiupdate uses
|
||||||
# 2.2.1. normal mode
|
# 2.2.1. normal mode
|
||||||
# 2.2.2. PS mode
|
# 2.2.2. PS mode
|
||||||
DROP TABLE t1;
|
DROP TABLE t1,t2;
|
||||||
SET @@global.sync_frm = @odl_sync_frm;
|
SET @@global.sync_frm = @odl_sync_frm;
|
||||||
|
@ -205,7 +205,7 @@ CREATE TABLE t1 (f1 INT);
|
|||||||
CREATE VIEW v1 AS SELECT f1 FROM t1;
|
CREATE VIEW v1 AS SELECT f1 FROM t1;
|
||||||
SELECT f1 FROM v1 va;
|
SELECT f1 FROM v1 va;
|
||||||
Catalog Database Table Table_alias Column Column_alias Type Length Max length Is_null Flags Decimals Charsetnr
|
Catalog Database Table Table_alias Column Column_alias Type Length Max length Is_null Flags Decimals Charsetnr
|
||||||
def test v1 va f1 f1 3 11 0 Y 32768 0 63
|
def test va va f1 f1 3 11 0 Y 32768 0 63
|
||||||
f1
|
f1
|
||||||
DROP VIEW v1;
|
DROP VIEW v1;
|
||||||
DROP TABLE t1;
|
DROP TABLE t1;
|
||||||
|
@ -668,6 +668,11 @@ INSERT INTO t1 VALUES('2001-01-01');
|
|||||||
UPDATE (SELECT 1 FROM t1 WHERE f1 = (SELECT f1() FROM t1)) x, t1 SET f1 = 1;
|
UPDATE (SELECT 1 FROM t1 WHERE f1 = (SELECT f1() FROM t1)) x, t1 SET f1 = 1;
|
||||||
Warnings:
|
Warnings:
|
||||||
Warning 1292 Truncated incorrect date value: '1'
|
Warning 1292 Truncated incorrect date value: '1'
|
||||||
|
CREATE view v1 as SELECT f1() FROM t1;
|
||||||
|
UPDATE (SELECT 1 FROM t1 WHERE f1 = (select * from v1)) x, t1 SET f1 = 1;
|
||||||
|
Warnings:
|
||||||
|
Warning 1292 Truncated incorrect date value: '1'
|
||||||
|
DROP VIEW v1;
|
||||||
DROP FUNCTION f1;
|
DROP FUNCTION f1;
|
||||||
DROP TABLE t1;
|
DROP TABLE t1;
|
||||||
end of tests
|
end of tests
|
||||||
|
@ -1673,7 +1673,7 @@ SELECT * FROM t1 r JOIN t1 s ON r.a = s.a
|
|||||||
WHERE s.a IN (2,9) OR s.a < 100 AND s.a != 0
|
WHERE s.a IN (2,9) OR s.a < 100 AND s.a != 0
|
||||||
ORDER BY 1 LIMIT 10;
|
ORDER BY 1 LIMIT 10;
|
||||||
id select_type table type possible_keys key key_len ref rows filtered Extra
|
id select_type table type possible_keys key key_len ref rows filtered Extra
|
||||||
1 SIMPLE r index PRIMARY PRIMARY 4 NULL 10 120.00 Using where; Using index
|
1 SIMPLE r index PRIMARY PRIMARY 4 NULL 10 100.00 Using where; Using index
|
||||||
1 SIMPLE s eq_ref PRIMARY PRIMARY 4 test.r.a 1 100.00 Using index
|
1 SIMPLE s eq_ref PRIMARY PRIMARY 4 test.r.a 1 100.00 Using index
|
||||||
Warnings:
|
Warnings:
|
||||||
Note 1003 select `test`.`r`.`a` AS `a`,`test`.`s`.`a` AS `a` from `test`.`t1` `r` join `test`.`t1` `s` where ((`test`.`s`.`a` = `test`.`r`.`a`) and ((`test`.`r`.`a` in (2,9)) or ((`test`.`r`.`a` < 100) and (`test`.`r`.`a` <> 0)))) order by 1 limit 10
|
Note 1003 select `test`.`r`.`a` AS `a`,`test`.`s`.`a` AS `a` from `test`.`t1` `r` join `test`.`t1` `s` where ((`test`.`s`.`a` = `test`.`r`.`a`) and ((`test`.`r`.`a` in (2,9)) or ((`test`.`r`.`a` < 100) and (`test`.`r`.`a` <> 0)))) order by 1 limit 10
|
||||||
|
@ -156,7 +156,6 @@ prepare stmt1 from @stmt ;
|
|||||||
execute stmt1 ;
|
execute stmt1 ;
|
||||||
id select_type table type possible_keys key key_len ref rows Extra
|
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
|
1 PRIMARY NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables
|
||||||
6 DERIVED NULL NULL NULL NULL NULL NULL NULL no matching row in const table
|
|
||||||
5 DEPENDENT SUBQUERY NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables
|
5 DEPENDENT SUBQUERY NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables
|
||||||
4 DEPENDENT SUBQUERY NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables
|
4 DEPENDENT SUBQUERY NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables
|
||||||
3 DEPENDENT SUBQUERY NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables
|
3 DEPENDENT SUBQUERY NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables
|
||||||
@ -164,7 +163,6 @@ id select_type table type possible_keys key key_len ref rows Extra
|
|||||||
execute stmt1 ;
|
execute stmt1 ;
|
||||||
id select_type table type possible_keys key key_len ref rows Extra
|
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
|
1 PRIMARY NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables
|
||||||
6 DERIVED NULL NULL NULL NULL NULL NULL NULL no matching row in const table
|
|
||||||
5 DEPENDENT SUBQUERY NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables
|
5 DEPENDENT SUBQUERY NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables
|
||||||
4 DEPENDENT SUBQUERY NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables
|
4 DEPENDENT SUBQUERY NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables
|
||||||
3 DEPENDENT SUBQUERY NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables
|
3 DEPENDENT SUBQUERY NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables
|
||||||
@ -172,7 +170,6 @@ id select_type table type possible_keys key key_len ref rows Extra
|
|||||||
explain SELECT (SELECT SUM(c1 + c12 + 0.0) FROM t2 where (t1.c2 - 0e-3) = t2.c2 GROUP BY t1.c15 LIMIT 1) as scalar_s, exists (select 1.0e+0 from t2 where t2.c3 * 9.0000000000 = t1.c4) as exists_s, c5 * 4 in (select c6 + 0.3e+1 from t2) as in_s, (c7 - 4, c8 - 4) in (select c9 + 4.0, c10 + 40e-1 from t2) as in_row_s FROM t1, (select c25 x, c32 y from t2) tt WHERE x * 1 = c25;
|
explain SELECT (SELECT SUM(c1 + c12 + 0.0) FROM t2 where (t1.c2 - 0e-3) = t2.c2 GROUP BY t1.c15 LIMIT 1) as scalar_s, exists (select 1.0e+0 from t2 where t2.c3 * 9.0000000000 = t1.c4) as exists_s, c5 * 4 in (select c6 + 0.3e+1 from t2) as in_s, (c7 - 4, c8 - 4) in (select c9 + 4.0, c10 + 40e-1 from t2) as in_row_s FROM t1, (select c25 x, c32 y from t2) tt WHERE x * 1 = c25;
|
||||||
id select_type table type possible_keys key key_len ref rows Extra
|
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
|
1 PRIMARY NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables
|
||||||
6 DERIVED NULL NULL NULL NULL NULL NULL NULL no matching row in const table
|
|
||||||
5 DEPENDENT SUBQUERY NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables
|
5 DEPENDENT SUBQUERY NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables
|
||||||
4 DEPENDENT SUBQUERY NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables
|
4 DEPENDENT SUBQUERY NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables
|
||||||
3 DEPENDENT SUBQUERY NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables
|
3 DEPENDENT SUBQUERY NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables
|
||||||
|
@ -1508,12 +1508,12 @@ create view v_27690_1 as select A.a, A.b from t_27690_1 A, t_27690_1 B;
|
|||||||
execute stmt;
|
execute stmt;
|
||||||
a b a b
|
a b a b
|
||||||
1 1 1 1
|
1 1 1 1
|
||||||
2 2 1 1
|
|
||||||
1 1 1 1
|
|
||||||
2 2 1 1
|
|
||||||
1 1 2 2
|
1 1 2 2
|
||||||
|
2 2 1 1
|
||||||
2 2 2 2
|
2 2 2 2
|
||||||
|
1 1 1 1
|
||||||
1 1 2 2
|
1 1 2 2
|
||||||
|
2 2 1 1
|
||||||
2 2 2 2
|
2 2 2 2
|
||||||
call p_verify_reprepare_count(1);
|
call p_verify_reprepare_count(1);
|
||||||
SUCCESS
|
SUCCESS
|
||||||
@ -1521,12 +1521,12 @@ SUCCESS
|
|||||||
execute stmt;
|
execute stmt;
|
||||||
a b a b
|
a b a b
|
||||||
1 1 1 1
|
1 1 1 1
|
||||||
2 2 1 1
|
|
||||||
1 1 1 1
|
|
||||||
2 2 1 1
|
|
||||||
1 1 2 2
|
1 1 2 2
|
||||||
|
2 2 1 1
|
||||||
2 2 2 2
|
2 2 2 2
|
||||||
|
1 1 1 1
|
||||||
1 1 2 2
|
1 1 2 2
|
||||||
|
2 2 1 1
|
||||||
2 2 2 2
|
2 2 2 2
|
||||||
call p_verify_reprepare_count(0);
|
call p_verify_reprepare_count(0);
|
||||||
SUCCESS
|
SUCCESS
|
||||||
|
@ -47,13 +47,13 @@ SELECT (SELECT a) as a;
|
|||||||
ERROR 42S22: Reference 'a' not supported (forward reference in item list)
|
ERROR 42S22: Reference 'a' not supported (forward reference in item list)
|
||||||
EXPLAIN EXTENDED SELECT 1 FROM (SELECT 1 as a) as b HAVING (SELECT a)=1;
|
EXPLAIN EXTENDED SELECT 1 FROM (SELECT 1 as a) as b HAVING (SELECT a)=1;
|
||||||
id select_type table type possible_keys key key_len ref rows filtered Extra
|
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 <derived2> ALL NULL NULL NULL NULL 2 100.00
|
||||||
3 DEPENDENT SUBQUERY NULL NULL NULL NULL NULL NULL NULL NULL No tables used
|
3 DEPENDENT SUBQUERY NULL NULL NULL NULL NULL NULL NULL NULL No tables used
|
||||||
2 DERIVED NULL NULL NULL NULL NULL NULL NULL NULL No tables used
|
2 DERIVED NULL NULL NULL NULL NULL NULL NULL NULL No tables used
|
||||||
Warnings:
|
Warnings:
|
||||||
Note 1276 Field or reference 'b.a' of SELECT #3 was resolved in SELECT #1
|
Note 1276 Field or reference 'b.a' of SELECT #3 was resolved in SELECT #1
|
||||||
Note 1276 Field or reference 'b.a' of SELECT #3 was resolved in SELECT #1
|
Note 1276 Field or reference 'b.a' of SELECT #3 was resolved in SELECT #1
|
||||||
Note 1003 select 1 AS `1` from (select 1 AS `a`) `b` having (<expr_cache><1>((select 1)) = 1)
|
Note 1003 select 1 AS `1` from (select 1 AS `a`) `b` having (<expr_cache><`b`.`a`>((select `b`.`a`)) = 1)
|
||||||
SELECT 1 FROM (SELECT 1 as a) as b HAVING (SELECT a)=1;
|
SELECT 1 FROM (SELECT 1 as a) as b HAVING (SELECT a)=1;
|
||||||
1
|
1
|
||||||
1
|
1
|
||||||
@ -202,11 +202,10 @@ select (select t3.a from t3 where a<8 order by 1 desc limit 1), a from
|
|||||||
explain extended select (select t3.a from t3 where a<8 order by 1 desc limit 1), a from
|
explain extended select (select t3.a from t3 where a<8 order by 1 desc limit 1), a from
|
||||||
(select * from t2 where a>1) as tt;
|
(select * from t2 where a>1) as tt;
|
||||||
id select_type table type possible_keys key key_len ref rows filtered Extra
|
id select_type table type possible_keys key key_len ref rows filtered Extra
|
||||||
1 PRIMARY <derived3> system NULL NULL NULL NULL 1 100.00
|
1 PRIMARY t2 ALL NULL NULL NULL NULL 2 100.00 Using where
|
||||||
3 DERIVED t2 ALL NULL NULL NULL NULL 2 100.00 Using where
|
|
||||||
2 SUBQUERY t3 ALL NULL NULL NULL NULL 3 100.00 Using where; Using filesort
|
2 SUBQUERY t3 ALL NULL NULL NULL NULL 3 100.00 Using where; Using filesort
|
||||||
Warnings:
|
Warnings:
|
||||||
Note 1003 select (select `test`.`t3`.`a` from `test`.`t3` where (`test`.`t3`.`a` < 8) order by 1 desc limit 1) AS `(select t3.a from t3 where a<8 order by 1 desc limit 1)`,2 AS `a` from (select `test`.`t2`.`a` AS `a`,`test`.`t2`.`b` AS `b` from `test`.`t2` where (`test`.`t2`.`a` > 1)) `tt`
|
Note 1003 select (select `test`.`t3`.`a` from `test`.`t3` where (`test`.`t3`.`a` < 8) order by 1 desc limit 1) AS `(select t3.a from t3 where a<8 order by 1 desc limit 1)`,`test`.`t2`.`a` AS `a` from `test`.`t2` where (`test`.`t2`.`a` > 1)
|
||||||
select * from t1 where t1.a=(select t2.a from t2 where t2.b=(select max(a) from t3) order by 1 desc limit 1);
|
select * from t1 where t1.a=(select t2.a from t2 where t2.b=(select max(a) from t3) order by 1 desc limit 1);
|
||||||
a
|
a
|
||||||
2
|
2
|
||||||
@ -366,9 +365,9 @@ INSERT INTO t8 (pseudo,email) VALUES ('2joce1','2test1');
|
|||||||
EXPLAIN EXTENDED SELECT pseudo,(SELECT email FROM t8 WHERE pseudo=(SELECT pseudo FROM t8 WHERE pseudo='joce')) FROM t8 WHERE pseudo=(SELECT pseudo FROM t8 WHERE pseudo='joce');
|
EXPLAIN EXTENDED SELECT pseudo,(SELECT email FROM t8 WHERE pseudo=(SELECT pseudo FROM t8 WHERE pseudo='joce')) FROM t8 WHERE pseudo=(SELECT pseudo FROM t8 WHERE pseudo='joce');
|
||||||
id select_type table type possible_keys key key_len ref rows filtered Extra
|
id select_type table type possible_keys key key_len ref rows filtered Extra
|
||||||
1 PRIMARY t8 const PRIMARY PRIMARY 37 const 1 100.00 Using index
|
1 PRIMARY t8 const PRIMARY PRIMARY 37 const 1 100.00 Using index
|
||||||
4 SUBQUERY t8 const PRIMARY PRIMARY 37 1 100.00 Using index
|
4 SUBQUERY t8 const PRIMARY PRIMARY 37 const 1 100.00 Using index
|
||||||
2 SUBQUERY t8 const PRIMARY PRIMARY 37 const 1 100.00
|
2 SUBQUERY t8 const PRIMARY PRIMARY 37 const 1 100.00
|
||||||
3 SUBQUERY t8 const PRIMARY PRIMARY 37 1 100.00 Using index
|
3 SUBQUERY t8 const PRIMARY PRIMARY 37 const 1 100.00 Using index
|
||||||
Warnings:
|
Warnings:
|
||||||
Note 1003 select 'joce' AS `pseudo`,(select 'test' from `test`.`t8` where ('joce' = (select 'joce' from `test`.`t8` where 1))) AS `(SELECT email FROM t8 WHERE pseudo=(SELECT pseudo FROM t8 WHERE pseudo='joce'))` from `test`.`t8` where ('joce' = (select 'joce' from `test`.`t8` where 1))
|
Note 1003 select 'joce' AS `pseudo`,(select 'test' from `test`.`t8` where ('joce' = (select 'joce' from `test`.`t8` where 1))) AS `(SELECT email FROM t8 WHERE pseudo=(SELECT pseudo FROM t8 WHERE pseudo='joce'))` from `test`.`t8` where ('joce' = (select 'joce' from `test`.`t8` where 1))
|
||||||
SELECT pseudo FROM t8 WHERE pseudo=(SELECT pseudo,email FROM
|
SELECT pseudo FROM t8 WHERE pseudo=(SELECT pseudo,email FROM
|
||||||
@ -1343,7 +1342,7 @@ a
|
|||||||
explain extended select * from t2 where t2.a in (select a from t1);
|
explain extended select * from t2 where t2.a in (select a from t1);
|
||||||
id select_type table type possible_keys key key_len ref rows filtered Extra
|
id select_type table type possible_keys key key_len ref rows filtered Extra
|
||||||
1 PRIMARY t2 index a a 5 NULL 4 100.00 Using where; Using index
|
1 PRIMARY t2 index a a 5 NULL 4 100.00 Using where; Using index
|
||||||
1 PRIMARY t1 ref a a 5 test.t2.a 101 100.00 Using index; FirstMatch(t2)
|
1 PRIMARY t1 ref a a 5 test.t2.a 100 100.00 Using index; FirstMatch(t2)
|
||||||
Warnings:
|
Warnings:
|
||||||
Note 1003 select `test`.`t2`.`a` AS `a` from `test`.`t2` semi join (`test`.`t1`) where (`test`.`t1`.`a` = `test`.`t2`.`a`)
|
Note 1003 select `test`.`t2`.`a` AS `a` from `test`.`t2` semi join (`test`.`t1`) where (`test`.`t1`.`a` = `test`.`t2`.`a`)
|
||||||
select * from t2 where t2.a in (select a from t1 where t1.b <> 30);
|
select * from t2 where t2.a in (select a from t1 where t1.b <> 30);
|
||||||
@ -1353,7 +1352,7 @@ a
|
|||||||
explain extended select * from t2 where t2.a in (select a from t1 where t1.b <> 30);
|
explain extended select * from t2 where t2.a in (select a from t1 where t1.b <> 30);
|
||||||
id select_type table type possible_keys key key_len ref rows filtered Extra
|
id select_type table type possible_keys key key_len ref rows filtered Extra
|
||||||
1 PRIMARY t2 index a a 5 NULL 4 100.00 Using where; Using index
|
1 PRIMARY t2 index a a 5 NULL 4 100.00 Using where; Using index
|
||||||
1 PRIMARY t1 ref a a 5 test.t2.a 101 100.00 Using where; Using index; FirstMatch(t2)
|
1 PRIMARY t1 ref a a 5 test.t2.a 100 100.00 Using where; Using index; FirstMatch(t2)
|
||||||
Warnings:
|
Warnings:
|
||||||
Note 1003 select `test`.`t2`.`a` AS `a` from `test`.`t2` semi join (`test`.`t1`) where ((`test`.`t1`.`a` = `test`.`t2`.`a`) and (`test`.`t1`.`b` <> 30))
|
Note 1003 select `test`.`t2`.`a` AS `a` from `test`.`t2` semi join (`test`.`t1`) where ((`test`.`t1`.`a` = `test`.`t2`.`a`) and (`test`.`t1`.`b` <> 30))
|
||||||
select * from t2 where t2.a in (select t1.a from t1,t3 where t1.b=t3.a);
|
select * from t2 where t2.a in (select t1.a from t1,t3 where t1.b=t3.a);
|
||||||
@ -1364,7 +1363,7 @@ explain extended select * from t2 where t2.a in (select t1.a from t1,t3 where t1
|
|||||||
id select_type table type possible_keys key key_len ref rows filtered Extra
|
id select_type table type possible_keys key key_len ref rows filtered Extra
|
||||||
1 PRIMARY t2 index a a 5 NULL 4 100.00 Using where; Using index
|
1 PRIMARY t2 index a a 5 NULL 4 100.00 Using where; Using index
|
||||||
1 PRIMARY t3 index a a 5 NULL 3 100.00 Using where; Using index
|
1 PRIMARY t3 index a a 5 NULL 3 100.00 Using where; Using index
|
||||||
1 PRIMARY t1 ref a a 10 test.t2.a,test.t3.a 116 100.00 Using index; FirstMatch(t2)
|
1 PRIMARY t1 ref a a 10 test.t2.a,test.t3.a 11 100.00 Using index; FirstMatch(t2)
|
||||||
Warnings:
|
Warnings:
|
||||||
Note 1003 select `test`.`t2`.`a` AS `a` from `test`.`t2` semi join (`test`.`t1` join `test`.`t3`) where ((`test`.`t1`.`a` = `test`.`t2`.`a`) and (`test`.`t1`.`b` = `test`.`t3`.`a`))
|
Note 1003 select `test`.`t2`.`a` AS `a` from `test`.`t2` semi join (`test`.`t1` join `test`.`t3`) where ((`test`.`t1`.`a` = `test`.`t2`.`a`) and (`test`.`t1`.`b` = `test`.`t3`.`a`))
|
||||||
insert into t1 values (3,31);
|
insert into t1 values (3,31);
|
||||||
@ -1380,7 +1379,7 @@ a
|
|||||||
explain extended select * from t2 where t2.a in (select a from t1 where t1.b <> 30);
|
explain extended select * from t2 where t2.a in (select a from t1 where t1.b <> 30);
|
||||||
id select_type table type possible_keys key key_len ref rows filtered Extra
|
id select_type table type possible_keys key key_len ref rows filtered Extra
|
||||||
1 PRIMARY t2 index a a 5 NULL 4 100.00 Using where; Using index
|
1 PRIMARY t2 index a a 5 NULL 4 100.00 Using where; Using index
|
||||||
1 PRIMARY t1 ref a a 5 test.t2.a 101 100.00 Using where; Using index; FirstMatch(t2)
|
1 PRIMARY t1 ref a a 5 test.t2.a 100 100.00 Using where; Using index; FirstMatch(t2)
|
||||||
Warnings:
|
Warnings:
|
||||||
Note 1003 select `test`.`t2`.`a` AS `a` from `test`.`t2` semi join (`test`.`t1`) where ((`test`.`t1`.`a` = `test`.`t2`.`a`) and (`test`.`t1`.`b` <> 30))
|
Note 1003 select `test`.`t2`.`a` AS `a` from `test`.`t2` semi join (`test`.`t1`) where ((`test`.`t1`.`a` = `test`.`t2`.`a`) and (`test`.`t1`.`b` <> 30))
|
||||||
drop table t0, t1, t2, t3;
|
drop table t0, t1, t2, t3;
|
||||||
|
@ -887,7 +887,7 @@ Level Code Message
|
|||||||
Note 1276 Field or reference 'test.t1.a' of SELECT #3 was resolved in SELECT #2
|
Note 1276 Field or reference 'test.t1.a' of SELECT #3 was resolved in SELECT #2
|
||||||
Note 1276 Field or reference 'test.t1.c' of SELECT #3 was resolved in SELECT #2
|
Note 1276 Field or reference 'test.t1.c' of SELECT #3 was resolved in SELECT #2
|
||||||
Error 1054 Unknown column 'c' in 'field list'
|
Error 1054 Unknown column 'c' in 'field list'
|
||||||
Note 1003 select `c` AS `c` from (select <expr_cache><count(`test`.`t1`.`a`),`test`.`t1`.`c`>((select count(`test`.`t1`.`a`) from (select count(`test`.`t1`.`b`) AS `COUNT(b)` from `test`.`t1`) `x` group by `t1`.`c`)) AS `(SELECT COUNT(a) FROM
|
Note 1003 select `c` AS `c` from (select (select count(`test`.`t1`.`a`) from (select count(`test`.`t1`.`b`) AS `COUNT(b)` from `test`.`t1`) `x` group by `test`.`t1`.`c`) AS `(SELECT COUNT(a) FROM
|
||||||
(SELECT COUNT(b) FROM t1) AS x GROUP BY c
|
(SELECT COUNT(b) FROM t1) AS x GROUP BY c
|
||||||
)` from `test`.`t1` group by `test`.`t1`.`b`) `y`
|
)` from `test`.`t1` group by `test`.`t1`.`b`) `y`
|
||||||
DROP TABLE t1;
|
DROP TABLE t1;
|
||||||
@ -1114,9 +1114,8 @@ a
|
|||||||
set @@optimizer_switch=@save_optimizer_switch;
|
set @@optimizer_switch=@save_optimizer_switch;
|
||||||
explain select * from (select a from t0) X where a in (select a from t1);
|
explain select * from (select a from t0) X where a in (select a from t1);
|
||||||
id select_type table type possible_keys key key_len ref rows Extra
|
id select_type table type possible_keys key key_len ref rows Extra
|
||||||
1 PRIMARY <derived2> ALL NULL NULL NULL NULL 11
|
1 PRIMARY t0 ALL NULL NULL NULL NULL 11
|
||||||
1 PRIMARY t1 ALL NULL NULL NULL NULL 20 Using where; FirstMatch(<derived2>)
|
1 PRIMARY t1 ALL NULL NULL NULL NULL 20 Using where; FirstMatch(t0)
|
||||||
2 DERIVED t0 ALL NULL NULL NULL NULL 11
|
|
||||||
drop table t0, t1;
|
drop table t0, t1;
|
||||||
create table t0 (a int);
|
create table t0 (a int);
|
||||||
insert into t0 values (0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
|
insert into t0 values (0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
|
||||||
|
@ -894,7 +894,7 @@ Level Code Message
|
|||||||
Note 1276 Field or reference 'test.t1.a' of SELECT #3 was resolved in SELECT #2
|
Note 1276 Field or reference 'test.t1.a' of SELECT #3 was resolved in SELECT #2
|
||||||
Note 1276 Field or reference 'test.t1.c' of SELECT #3 was resolved in SELECT #2
|
Note 1276 Field or reference 'test.t1.c' of SELECT #3 was resolved in SELECT #2
|
||||||
Error 1054 Unknown column 'c' in 'field list'
|
Error 1054 Unknown column 'c' in 'field list'
|
||||||
Note 1003 select `c` AS `c` from (select <expr_cache><count(`test`.`t1`.`a`),`test`.`t1`.`c`>((select count(`test`.`t1`.`a`) from (select count(`test`.`t1`.`b`) AS `COUNT(b)` from `test`.`t1`) `x` group by `t1`.`c`)) AS `(SELECT COUNT(a) FROM
|
Note 1003 select `c` AS `c` from (select (select count(`test`.`t1`.`a`) from (select count(`test`.`t1`.`b`) AS `COUNT(b)` from `test`.`t1`) `x` group by `test`.`t1`.`c`) AS `(SELECT COUNT(a) FROM
|
||||||
(SELECT COUNT(b) FROM t1) AS x GROUP BY c
|
(SELECT COUNT(b) FROM t1) AS x GROUP BY c
|
||||||
)` from `test`.`t1` group by `test`.`t1`.`b`) `y`
|
)` from `test`.`t1` group by `test`.`t1`.`b`) `y`
|
||||||
DROP TABLE t1;
|
DROP TABLE t1;
|
||||||
@ -1121,9 +1121,8 @@ a
|
|||||||
set @@optimizer_switch=@save_optimizer_switch;
|
set @@optimizer_switch=@save_optimizer_switch;
|
||||||
explain select * from (select a from t0) X where a in (select a from t1);
|
explain select * from (select a from t0) X where a in (select a from t1);
|
||||||
id select_type table type possible_keys key key_len ref rows Extra
|
id select_type table type possible_keys key key_len ref rows Extra
|
||||||
1 PRIMARY <derived2> ALL NULL NULL NULL NULL 11
|
1 PRIMARY t0 ALL NULL NULL NULL NULL 11
|
||||||
1 PRIMARY t1 ALL NULL NULL NULL NULL 20 Using where; FirstMatch(<derived2>); Using join buffer (flat, BNL join)
|
1 PRIMARY t1 ALL NULL NULL NULL NULL 20 Using where; FirstMatch(t0); Using join buffer (flat, BNL join)
|
||||||
2 DERIVED t0 ALL NULL NULL NULL NULL 11
|
|
||||||
drop table t0, t1;
|
drop table t0, t1;
|
||||||
create table t0 (a int);
|
create table t0 (a int);
|
||||||
insert into t0 values (0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
|
insert into t0 values (0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
|
||||||
|
@ -1471,7 +1471,7 @@ EXPLAIN
|
|||||||
SELECT 'bug' FROM DUAL WHERE ( 5 ) IN ( SELECT * FROM v1 );
|
SELECT 'bug' FROM DUAL WHERE ( 5 ) IN ( SELECT * FROM v1 );
|
||||||
id select_type table type possible_keys key key_len ref rows Extra
|
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
|
1 PRIMARY NULL NULL NULL NULL NULL NULL NULL No tables used
|
||||||
2 DEPENDENT SUBQUERY NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables
|
2 DEPENDENT SUBQUERY <derived3> ALL NULL NULL NULL NULL 2 Using where
|
||||||
3 DERIVED NULL NULL NULL NULL NULL NULL NULL No tables used
|
3 DERIVED NULL NULL NULL NULL NULL NULL NULL No tables used
|
||||||
4 UNION NULL NULL NULL NULL NULL NULL NULL No tables used
|
4 UNION NULL NULL NULL NULL NULL NULL NULL No tables used
|
||||||
NULL UNION RESULT <union3,4> ALL NULL NULL NULL NULL NULL
|
NULL UNION RESULT <union3,4> ALL NULL NULL NULL NULL NULL
|
||||||
@ -1481,7 +1481,7 @@ EXPLAIN
|
|||||||
SELECT ( 5 ) IN ( SELECT * FROM v1 );
|
SELECT ( 5 ) IN ( SELECT * FROM v1 );
|
||||||
id select_type table type possible_keys key key_len ref rows Extra
|
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
|
1 PRIMARY NULL NULL NULL NULL NULL NULL NULL No tables used
|
||||||
2 DEPENDENT SUBQUERY NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables
|
2 DEPENDENT SUBQUERY <derived3> ALL NULL NULL NULL NULL 2 Using where
|
||||||
3 DERIVED NULL NULL NULL NULL NULL NULL NULL No tables used
|
3 DERIVED NULL NULL NULL NULL NULL NULL NULL No tables used
|
||||||
4 UNION NULL NULL NULL NULL NULL NULL NULL No tables used
|
4 UNION NULL NULL NULL NULL NULL NULL NULL No tables used
|
||||||
NULL UNION RESULT <union3,4> ALL NULL NULL NULL NULL NULL
|
NULL UNION RESULT <union3,4> ALL NULL NULL NULL NULL NULL
|
||||||
@ -1492,7 +1492,7 @@ EXPLAIN
|
|||||||
SELECT 'bug' FROM DUAL WHERE ( 5 ) IN (SELECT * FROM v2);
|
SELECT 'bug' FROM DUAL WHERE ( 5 ) IN (SELECT * FROM v2);
|
||||||
id select_type table type possible_keys key key_len ref rows Extra
|
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
|
1 PRIMARY NULL NULL NULL NULL NULL NULL NULL No tables used
|
||||||
2 DEPENDENT SUBQUERY NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables
|
2 DEPENDENT SUBQUERY <derived3> ALL NULL NULL NULL NULL 2 Using where
|
||||||
3 DERIVED t1 system NULL NULL NULL NULL 1
|
3 DERIVED t1 system NULL NULL NULL NULL 1
|
||||||
4 UNION t2 system NULL NULL NULL NULL 1
|
4 UNION t2 system NULL NULL NULL NULL 1
|
||||||
NULL UNION RESULT <union3,4> ALL NULL NULL NULL NULL NULL
|
NULL UNION RESULT <union3,4> ALL NULL NULL NULL NULL NULL
|
||||||
@ -1502,7 +1502,7 @@ EXPLAIN
|
|||||||
SELECT 'bug' FROM t3 WHERE ( 5 ) IN (SELECT * FROM v2);
|
SELECT 'bug' FROM t3 WHERE ( 5 ) IN (SELECT * FROM v2);
|
||||||
id select_type table type possible_keys key key_len ref rows Extra
|
id select_type table type possible_keys key key_len ref rows Extra
|
||||||
1 PRIMARY t3 system NULL NULL NULL NULL 1
|
1 PRIMARY t3 system NULL NULL NULL NULL 1
|
||||||
2 SUBQUERY <derived3> system NULL NULL NULL NULL 1
|
2 SUBQUERY <derived3> ALL NULL NULL NULL NULL 2
|
||||||
3 DERIVED t1 system NULL NULL NULL NULL 1
|
3 DERIVED t1 system NULL NULL NULL NULL 1
|
||||||
4 UNION t2 system NULL NULL NULL NULL 1
|
4 UNION t2 system NULL NULL NULL NULL 1
|
||||||
NULL UNION RESULT <union3,4> ALL NULL NULL NULL NULL NULL
|
NULL UNION RESULT <union3,4> ALL NULL NULL NULL NULL NULL
|
||||||
@ -1512,7 +1512,7 @@ EXPLAIN
|
|||||||
SELECT ( 5 ) IN ( SELECT * FROM v2 );
|
SELECT ( 5 ) IN ( SELECT * FROM v2 );
|
||||||
id select_type table type possible_keys key key_len ref rows Extra
|
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
|
1 PRIMARY NULL NULL NULL NULL NULL NULL NULL No tables used
|
||||||
2 DEPENDENT SUBQUERY NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables
|
2 DEPENDENT SUBQUERY <derived3> ALL NULL NULL NULL NULL 2 Using where
|
||||||
3 DERIVED t1 system NULL NULL NULL NULL 1
|
3 DERIVED t1 system NULL NULL NULL NULL 1
|
||||||
4 UNION t2 system NULL NULL NULL NULL 1
|
4 UNION t2 system NULL NULL NULL NULL 1
|
||||||
NULL UNION RESULT <union3,4> ALL NULL NULL NULL NULL NULL
|
NULL UNION RESULT <union3,4> ALL NULL NULL NULL NULL NULL
|
||||||
@ -1524,7 +1524,7 @@ EXPLAIN
|
|||||||
SELECT 'bug' FROM DUAL WHERE ( 5 ) IN ( SELECT * FROM v1 );
|
SELECT 'bug' FROM DUAL WHERE ( 5 ) IN ( SELECT * FROM v1 );
|
||||||
id select_type table type possible_keys key key_len ref rows Extra
|
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
|
1 PRIMARY NULL NULL NULL NULL NULL NULL NULL No tables used
|
||||||
2 DEPENDENT SUBQUERY NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables
|
2 DEPENDENT SUBQUERY <derived3> ALL NULL NULL NULL NULL 2 Using where
|
||||||
3 DERIVED NULL NULL NULL NULL NULL NULL NULL No tables used
|
3 DERIVED NULL NULL NULL NULL NULL NULL NULL No tables used
|
||||||
4 UNION NULL NULL NULL NULL NULL NULL NULL No tables used
|
4 UNION NULL NULL NULL NULL NULL NULL NULL No tables used
|
||||||
NULL UNION RESULT <union3,4> ALL NULL NULL NULL NULL NULL
|
NULL UNION RESULT <union3,4> ALL NULL NULL NULL NULL NULL
|
||||||
@ -1534,7 +1534,7 @@ EXPLAIN
|
|||||||
SELECT ( 5 ) IN ( SELECT * FROM v1 );
|
SELECT ( 5 ) IN ( SELECT * FROM v1 );
|
||||||
id select_type table type possible_keys key key_len ref rows Extra
|
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
|
1 PRIMARY NULL NULL NULL NULL NULL NULL NULL No tables used
|
||||||
2 DEPENDENT SUBQUERY NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables
|
2 DEPENDENT SUBQUERY <derived3> ALL NULL NULL NULL NULL 2 Using where
|
||||||
3 DERIVED NULL NULL NULL NULL NULL NULL NULL No tables used
|
3 DERIVED NULL NULL NULL NULL NULL NULL NULL No tables used
|
||||||
4 UNION NULL NULL NULL NULL NULL NULL NULL No tables used
|
4 UNION NULL NULL NULL NULL NULL NULL NULL No tables used
|
||||||
NULL UNION RESULT <union3,4> ALL NULL NULL NULL NULL NULL
|
NULL UNION RESULT <union3,4> ALL NULL NULL NULL NULL NULL
|
||||||
@ -1545,7 +1545,7 @@ EXPLAIN
|
|||||||
SELECT 'bug' FROM DUAL WHERE ( 5 ) IN (SELECT * FROM v2);
|
SELECT 'bug' FROM DUAL WHERE ( 5 ) IN (SELECT * FROM v2);
|
||||||
id select_type table type possible_keys key key_len ref rows Extra
|
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
|
1 PRIMARY NULL NULL NULL NULL NULL NULL NULL No tables used
|
||||||
2 DEPENDENT SUBQUERY NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables
|
2 DEPENDENT SUBQUERY <derived3> ALL NULL NULL NULL NULL 2 Using where
|
||||||
3 DERIVED t1 system NULL NULL NULL NULL 1
|
3 DERIVED t1 system NULL NULL NULL NULL 1
|
||||||
4 UNION t2 system NULL NULL NULL NULL 1
|
4 UNION t2 system NULL NULL NULL NULL 1
|
||||||
NULL UNION RESULT <union3,4> ALL NULL NULL NULL NULL NULL
|
NULL UNION RESULT <union3,4> ALL NULL NULL NULL NULL NULL
|
||||||
@ -1555,7 +1555,7 @@ EXPLAIN
|
|||||||
SELECT 'bug' FROM t3 WHERE ( 5 ) IN (SELECT * FROM v2);
|
SELECT 'bug' FROM t3 WHERE ( 5 ) IN (SELECT * FROM v2);
|
||||||
id select_type table type possible_keys key key_len ref rows Extra
|
id select_type table type possible_keys key key_len ref rows Extra
|
||||||
1 PRIMARY t3 system NULL NULL NULL NULL 1
|
1 PRIMARY t3 system NULL NULL NULL NULL 1
|
||||||
2 DEPENDENT SUBQUERY NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables
|
2 DEPENDENT SUBQUERY <derived3> ALL NULL NULL NULL NULL 2 Using where
|
||||||
3 DERIVED t1 system NULL NULL NULL NULL 1
|
3 DERIVED t1 system NULL NULL NULL NULL 1
|
||||||
4 UNION t2 system NULL NULL NULL NULL 1
|
4 UNION t2 system NULL NULL NULL NULL 1
|
||||||
NULL UNION RESULT <union3,4> ALL NULL NULL NULL NULL NULL
|
NULL UNION RESULT <union3,4> ALL NULL NULL NULL NULL NULL
|
||||||
@ -1565,7 +1565,7 @@ EXPLAIN
|
|||||||
SELECT ( 5 ) IN ( SELECT * FROM v2 );
|
SELECT ( 5 ) IN ( SELECT * FROM v2 );
|
||||||
id select_type table type possible_keys key key_len ref rows Extra
|
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
|
1 PRIMARY NULL NULL NULL NULL NULL NULL NULL No tables used
|
||||||
2 DEPENDENT SUBQUERY NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables
|
2 DEPENDENT SUBQUERY <derived3> ALL NULL NULL NULL NULL 2 Using where
|
||||||
3 DERIVED t1 system NULL NULL NULL NULL 1
|
3 DERIVED t1 system NULL NULL NULL NULL 1
|
||||||
4 UNION t2 system NULL NULL NULL NULL 1
|
4 UNION t2 system NULL NULL NULL NULL 1
|
||||||
NULL UNION RESULT <union3,4> ALL NULL NULL NULL NULL NULL
|
NULL UNION RESULT <union3,4> ALL NULL NULL NULL NULL NULL
|
||||||
|
@ -1402,8 +1402,8 @@ i
|
|||||||
10
|
10
|
||||||
DROP TABLE t1, t2, t3;
|
DROP TABLE t1, t2, t3;
|
||||||
#
|
#
|
||||||
# LPBUG#609121: RQG: wrong result on aggregate + NOT IN + HAVING and
|
# LPBUG#611622/BUG#52344: Subquery materialization: Assertion
|
||||||
# partial_match_table_scan=on
|
# if subquery in on-clause of outer join
|
||||||
#
|
#
|
||||||
CREATE TABLE t1 (c1 int);
|
CREATE TABLE t1 (c1 int);
|
||||||
INSERT INTO t1 VALUES (1),(2);
|
INSERT INTO t1 VALUES (1),(2);
|
||||||
@ -1411,7 +1411,7 @@ CREATE TABLE t2 (c2 int);
|
|||||||
INSERT INTO t2 VALUES (10);
|
INSERT INTO t2 VALUES (10);
|
||||||
PREPARE st1 FROM "
|
PREPARE st1 FROM "
|
||||||
SELECT *
|
SELECT *
|
||||||
FROM t2 LEFT JOIN (SELECT * FROM t2) t3 ON (8, 4) IN (SELECT c1, c1 FROM t1)";
|
FROM t2 LEFT JOIN t2 t3 ON (8, 4) IN (SELECT c1, c1 FROM t1)";
|
||||||
EXECUTE st1;
|
EXECUTE st1;
|
||||||
c2 c2
|
c2 c2
|
||||||
10 10
|
10 10
|
||||||
|
@ -156,15 +156,13 @@ WHERE (SELECT distinct SUM(distinct f3 ) FROM t1);
|
|||||||
id select_type table type possible_keys key key_len ref rows Extra
|
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
|
1 PRIMARY NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables
|
||||||
3 SUBQUERY t1 index NULL f3 5 NULL 2 Using index
|
3 SUBQUERY t1 index NULL f3 5 NULL 2 Using index
|
||||||
2 DERIVED NULL NULL NULL NULL NULL NULL NULL no matching row in const table
|
|
||||||
insert into t2 values (1),(2);
|
insert into t2 values (1),(2);
|
||||||
EXPLAIN
|
EXPLAIN
|
||||||
SELECT * FROM (SELECT * FROM t2) AS a2
|
SELECT * FROM (SELECT * FROM t2) AS a2
|
||||||
WHERE (SELECT distinct SUM(distinct f3 ) FROM t1);
|
WHERE (SELECT distinct SUM(distinct f3 ) FROM t1);
|
||||||
id select_type table type possible_keys key key_len ref rows Extra
|
id select_type table type possible_keys key key_len ref rows Extra
|
||||||
1 PRIMARY <derived2> ALL NULL NULL NULL NULL 2
|
1 PRIMARY t2 ALL NULL NULL NULL NULL 2
|
||||||
3 SUBQUERY t1 index NULL f3 5 NULL 2 Using index
|
3 SUBQUERY t1 index NULL f3 5 NULL 2 Using index
|
||||||
2 DERIVED t2 ALL NULL NULL NULL NULL 2
|
|
||||||
drop table t1,t2;
|
drop table t1,t2;
|
||||||
#
|
#
|
||||||
# LP BUG#715027 Assertion `!table || (!table->read_set || bitmap_is_set(table->read_set, field_index))' failed
|
# LP BUG#715027 Assertion `!table || (!table->read_set || bitmap_is_set(table->read_set, field_index))' failed
|
||||||
@ -183,11 +181,10 @@ WHERE t1.f1 AND alias2.f10
|
|||||||
)
|
)
|
||||||
ORDER BY field1 ;
|
ORDER BY field1 ;
|
||||||
id select_type table type possible_keys key key_len ref rows Extra
|
id select_type table type possible_keys key key_len ref rows Extra
|
||||||
1 PRIMARY <derived2> ALL NULL NULL NULL NULL 2 Using where; Using filesort
|
1 PRIMARY t2 ALL NULL NULL NULL NULL 2 Using where; Using filesort
|
||||||
1 PRIMARY alias1 eq_ref PRIMARY PRIMARY 4 alias2.f3 1 Using index
|
1 PRIMARY alias1 eq_ref PRIMARY PRIMARY 4 test.t2.f3 1 Using index
|
||||||
3 DEPENDENT SUBQUERY t2 ALL NULL NULL NULL NULL 2
|
3 DEPENDENT SUBQUERY t2 ALL NULL NULL NULL NULL 2
|
||||||
3 DEPENDENT SUBQUERY t1 index NULL PRIMARY 4 NULL 2 Using where; Using index; Using join buffer (flat, BNL join)
|
3 DEPENDENT SUBQUERY t1 index NULL PRIMARY 4 NULL 2 Using where; Using index; Using join buffer (flat, BNL join)
|
||||||
2 DERIVED t2 ALL NULL NULL NULL NULL 2
|
|
||||||
SELECT alias2.f2 AS field1
|
SELECT alias2.f2 AS field1
|
||||||
FROM t1 AS alias1 JOIN ( SELECT * FROM t2 ) AS alias2 ON alias2.f3 = alias1.f1
|
FROM t1 AS alias1 JOIN ( SELECT * FROM t2 ) AS alias2 ON alias2.f3 = alias1.f1
|
||||||
WHERE (
|
WHERE (
|
||||||
|
@ -51,13 +51,13 @@ SELECT (SELECT a) as a;
|
|||||||
ERROR 42S22: Reference 'a' not supported (forward reference in item list)
|
ERROR 42S22: Reference 'a' not supported (forward reference in item list)
|
||||||
EXPLAIN EXTENDED SELECT 1 FROM (SELECT 1 as a) as b HAVING (SELECT a)=1;
|
EXPLAIN EXTENDED SELECT 1 FROM (SELECT 1 as a) as b HAVING (SELECT a)=1;
|
||||||
id select_type table type possible_keys key key_len ref rows filtered Extra
|
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 <derived2> ALL NULL NULL NULL NULL 2 100.00
|
||||||
3 DEPENDENT SUBQUERY NULL NULL NULL NULL NULL NULL NULL NULL No tables used
|
3 DEPENDENT SUBQUERY NULL NULL NULL NULL NULL NULL NULL NULL No tables used
|
||||||
2 DERIVED NULL NULL NULL NULL NULL NULL NULL NULL No tables used
|
2 DERIVED NULL NULL NULL NULL NULL NULL NULL NULL No tables used
|
||||||
Warnings:
|
Warnings:
|
||||||
Note 1276 Field or reference 'b.a' of SELECT #3 was resolved in SELECT #1
|
Note 1276 Field or reference 'b.a' of SELECT #3 was resolved in SELECT #1
|
||||||
Note 1276 Field or reference 'b.a' of SELECT #3 was resolved in SELECT #1
|
Note 1276 Field or reference 'b.a' of SELECT #3 was resolved in SELECT #1
|
||||||
Note 1003 select 1 AS `1` from (select 1 AS `a`) `b` having (<expr_cache><1>((select 1)) = 1)
|
Note 1003 select 1 AS `1` from (select 1 AS `a`) `b` having (<expr_cache><`b`.`a`>((select `b`.`a`)) = 1)
|
||||||
SELECT 1 FROM (SELECT 1 as a) as b HAVING (SELECT a)=1;
|
SELECT 1 FROM (SELECT 1 as a) as b HAVING (SELECT a)=1;
|
||||||
1
|
1
|
||||||
1
|
1
|
||||||
@ -206,11 +206,10 @@ select (select t3.a from t3 where a<8 order by 1 desc limit 1), a from
|
|||||||
explain extended select (select t3.a from t3 where a<8 order by 1 desc limit 1), a from
|
explain extended select (select t3.a from t3 where a<8 order by 1 desc limit 1), a from
|
||||||
(select * from t2 where a>1) as tt;
|
(select * from t2 where a>1) as tt;
|
||||||
id select_type table type possible_keys key key_len ref rows filtered Extra
|
id select_type table type possible_keys key key_len ref rows filtered Extra
|
||||||
1 PRIMARY <derived3> system NULL NULL NULL NULL 1 100.00
|
1 PRIMARY t2 ALL NULL NULL NULL NULL 2 100.00 Using where
|
||||||
3 DERIVED t2 ALL NULL NULL NULL NULL 2 100.00 Using where
|
|
||||||
2 SUBQUERY t3 ALL NULL NULL NULL NULL 3 100.00 Using where; Using filesort
|
2 SUBQUERY t3 ALL NULL NULL NULL NULL 3 100.00 Using where; Using filesort
|
||||||
Warnings:
|
Warnings:
|
||||||
Note 1003 select (select `test`.`t3`.`a` from `test`.`t3` where (`test`.`t3`.`a` < 8) order by 1 desc limit 1) AS `(select t3.a from t3 where a<8 order by 1 desc limit 1)`,2 AS `a` from (select `test`.`t2`.`a` AS `a`,`test`.`t2`.`b` AS `b` from `test`.`t2` where (`test`.`t2`.`a` > 1)) `tt`
|
Note 1003 select (select `test`.`t3`.`a` from `test`.`t3` where (`test`.`t3`.`a` < 8) order by 1 desc limit 1) AS `(select t3.a from t3 where a<8 order by 1 desc limit 1)`,`test`.`t2`.`a` AS `a` from `test`.`t2` where (`test`.`t2`.`a` > 1)
|
||||||
select * from t1 where t1.a=(select t2.a from t2 where t2.b=(select max(a) from t3) order by 1 desc limit 1);
|
select * from t1 where t1.a=(select t2.a from t2 where t2.b=(select max(a) from t3) order by 1 desc limit 1);
|
||||||
a
|
a
|
||||||
2
|
2
|
||||||
@ -370,9 +369,9 @@ INSERT INTO t8 (pseudo,email) VALUES ('2joce1','2test1');
|
|||||||
EXPLAIN EXTENDED SELECT pseudo,(SELECT email FROM t8 WHERE pseudo=(SELECT pseudo FROM t8 WHERE pseudo='joce')) FROM t8 WHERE pseudo=(SELECT pseudo FROM t8 WHERE pseudo='joce');
|
EXPLAIN EXTENDED SELECT pseudo,(SELECT email FROM t8 WHERE pseudo=(SELECT pseudo FROM t8 WHERE pseudo='joce')) FROM t8 WHERE pseudo=(SELECT pseudo FROM t8 WHERE pseudo='joce');
|
||||||
id select_type table type possible_keys key key_len ref rows filtered Extra
|
id select_type table type possible_keys key key_len ref rows filtered Extra
|
||||||
1 PRIMARY t8 const PRIMARY PRIMARY 37 const 1 100.00 Using index
|
1 PRIMARY t8 const PRIMARY PRIMARY 37 const 1 100.00 Using index
|
||||||
4 SUBQUERY t8 const PRIMARY PRIMARY 37 1 100.00 Using index
|
4 SUBQUERY t8 const PRIMARY PRIMARY 37 const 1 100.00 Using index
|
||||||
2 SUBQUERY t8 const PRIMARY PRIMARY 37 const 1 100.00
|
2 SUBQUERY t8 const PRIMARY PRIMARY 37 const 1 100.00
|
||||||
3 SUBQUERY t8 const PRIMARY PRIMARY 37 1 100.00 Using index
|
3 SUBQUERY t8 const PRIMARY PRIMARY 37 const 1 100.00 Using index
|
||||||
Warnings:
|
Warnings:
|
||||||
Note 1003 select 'joce' AS `pseudo`,(select 'test' from `test`.`t8` where ('joce' = (select 'joce' from `test`.`t8` where 1))) AS `(SELECT email FROM t8 WHERE pseudo=(SELECT pseudo FROM t8 WHERE pseudo='joce'))` from `test`.`t8` where ('joce' = (select 'joce' from `test`.`t8` where 1))
|
Note 1003 select 'joce' AS `pseudo`,(select 'test' from `test`.`t8` where ('joce' = (select 'joce' from `test`.`t8` where 1))) AS `(SELECT email FROM t8 WHERE pseudo=(SELECT pseudo FROM t8 WHERE pseudo='joce'))` from `test`.`t8` where ('joce' = (select 'joce' from `test`.`t8` where 1))
|
||||||
SELECT pseudo FROM t8 WHERE pseudo=(SELECT pseudo,email FROM
|
SELECT pseudo FROM t8 WHERE pseudo=(SELECT pseudo,email FROM
|
||||||
@ -1347,7 +1346,7 @@ a
|
|||||||
explain extended select * from t2 where t2.a in (select a from t1);
|
explain extended select * from t2 where t2.a in (select a from t1);
|
||||||
id select_type table type possible_keys key key_len ref rows filtered Extra
|
id select_type table type possible_keys key key_len ref rows filtered Extra
|
||||||
1 PRIMARY t2 index a a 5 NULL 4 100.00 Using where; Using index
|
1 PRIMARY t2 index a a 5 NULL 4 100.00 Using where; Using index
|
||||||
1 PRIMARY t1 ref a a 5 test.t2.a 101 100.00 Using index; FirstMatch(t2)
|
1 PRIMARY t1 ref a a 5 test.t2.a 100 100.00 Using index; FirstMatch(t2)
|
||||||
Warnings:
|
Warnings:
|
||||||
Note 1003 select `test`.`t2`.`a` AS `a` from `test`.`t2` semi join (`test`.`t1`) where (`test`.`t1`.`a` = `test`.`t2`.`a`)
|
Note 1003 select `test`.`t2`.`a` AS `a` from `test`.`t2` semi join (`test`.`t1`) where (`test`.`t1`.`a` = `test`.`t2`.`a`)
|
||||||
select * from t2 where t2.a in (select a from t1 where t1.b <> 30);
|
select * from t2 where t2.a in (select a from t1 where t1.b <> 30);
|
||||||
@ -1357,7 +1356,7 @@ a
|
|||||||
explain extended select * from t2 where t2.a in (select a from t1 where t1.b <> 30);
|
explain extended select * from t2 where t2.a in (select a from t1 where t1.b <> 30);
|
||||||
id select_type table type possible_keys key key_len ref rows filtered Extra
|
id select_type table type possible_keys key key_len ref rows filtered Extra
|
||||||
1 PRIMARY t2 index a a 5 NULL 4 100.00 Using where; Using index
|
1 PRIMARY t2 index a a 5 NULL 4 100.00 Using where; Using index
|
||||||
1 PRIMARY t1 ref a a 5 test.t2.a 101 100.00 Using where; Using index; FirstMatch(t2)
|
1 PRIMARY t1 ref a a 5 test.t2.a 100 100.00 Using where; Using index; FirstMatch(t2)
|
||||||
Warnings:
|
Warnings:
|
||||||
Note 1003 select `test`.`t2`.`a` AS `a` from `test`.`t2` semi join (`test`.`t1`) where ((`test`.`t1`.`a` = `test`.`t2`.`a`) and (`test`.`t1`.`b` <> 30))
|
Note 1003 select `test`.`t2`.`a` AS `a` from `test`.`t2` semi join (`test`.`t1`) where ((`test`.`t1`.`a` = `test`.`t2`.`a`) and (`test`.`t1`.`b` <> 30))
|
||||||
select * from t2 where t2.a in (select t1.a from t1,t3 where t1.b=t3.a);
|
select * from t2 where t2.a in (select t1.a from t1,t3 where t1.b=t3.a);
|
||||||
@ -1368,7 +1367,7 @@ explain extended select * from t2 where t2.a in (select t1.a from t1,t3 where t1
|
|||||||
id select_type table type possible_keys key key_len ref rows filtered Extra
|
id select_type table type possible_keys key key_len ref rows filtered Extra
|
||||||
1 PRIMARY t2 index a a 5 NULL 4 100.00 Using where; Using index
|
1 PRIMARY t2 index a a 5 NULL 4 100.00 Using where; Using index
|
||||||
1 PRIMARY t3 index a a 5 NULL 3 100.00 Using where; Using index
|
1 PRIMARY t3 index a a 5 NULL 3 100.00 Using where; Using index
|
||||||
1 PRIMARY t1 ref a a 10 test.t2.a,test.t3.a 116 100.00 Using index; FirstMatch(t2)
|
1 PRIMARY t1 ref a a 10 test.t2.a,test.t3.a 11 100.00 Using index; FirstMatch(t2)
|
||||||
Warnings:
|
Warnings:
|
||||||
Note 1003 select `test`.`t2`.`a` AS `a` from `test`.`t2` semi join (`test`.`t1` join `test`.`t3`) where ((`test`.`t1`.`a` = `test`.`t2`.`a`) and (`test`.`t1`.`b` = `test`.`t3`.`a`))
|
Note 1003 select `test`.`t2`.`a` AS `a` from `test`.`t2` semi join (`test`.`t1` join `test`.`t3`) where ((`test`.`t1`.`a` = `test`.`t2`.`a`) and (`test`.`t1`.`b` = `test`.`t3`.`a`))
|
||||||
insert into t1 values (3,31);
|
insert into t1 values (3,31);
|
||||||
@ -1384,7 +1383,7 @@ a
|
|||||||
explain extended select * from t2 where t2.a in (select a from t1 where t1.b <> 30);
|
explain extended select * from t2 where t2.a in (select a from t1 where t1.b <> 30);
|
||||||
id select_type table type possible_keys key key_len ref rows filtered Extra
|
id select_type table type possible_keys key key_len ref rows filtered Extra
|
||||||
1 PRIMARY t2 index a a 5 NULL 4 100.00 Using where; Using index
|
1 PRIMARY t2 index a a 5 NULL 4 100.00 Using where; Using index
|
||||||
1 PRIMARY t1 ref a a 5 test.t2.a 101 100.00 Using where; Using index; FirstMatch(t2)
|
1 PRIMARY t1 ref a a 5 test.t2.a 100 100.00 Using where; Using index; FirstMatch(t2)
|
||||||
Warnings:
|
Warnings:
|
||||||
Note 1003 select `test`.`t2`.`a` AS `a` from `test`.`t2` semi join (`test`.`t1`) where ((`test`.`t1`.`a` = `test`.`t2`.`a`) and (`test`.`t1`.`b` <> 30))
|
Note 1003 select `test`.`t2`.`a` AS `a` from `test`.`t2` semi join (`test`.`t1`) where ((`test`.`t1`.`a` = `test`.`t2`.`a`) and (`test`.`t1`.`b` <> 30))
|
||||||
drop table t0, t1, t2, t3;
|
drop table t0, t1, t2, t3;
|
||||||
|
@ -48,13 +48,13 @@ SELECT (SELECT a) as a;
|
|||||||
ERROR 42S22: Reference 'a' not supported (forward reference in item list)
|
ERROR 42S22: Reference 'a' not supported (forward reference in item list)
|
||||||
EXPLAIN EXTENDED SELECT 1 FROM (SELECT 1 as a) as b HAVING (SELECT a)=1;
|
EXPLAIN EXTENDED SELECT 1 FROM (SELECT 1 as a) as b HAVING (SELECT a)=1;
|
||||||
id select_type table type possible_keys key key_len ref rows filtered Extra
|
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 <derived2> ALL NULL NULL NULL NULL 2 100.00
|
||||||
3 DEPENDENT SUBQUERY NULL NULL NULL NULL NULL NULL NULL NULL No tables used
|
3 DEPENDENT SUBQUERY NULL NULL NULL NULL NULL NULL NULL NULL No tables used
|
||||||
2 DERIVED NULL NULL NULL NULL NULL NULL NULL NULL No tables used
|
2 DERIVED NULL NULL NULL NULL NULL NULL NULL NULL No tables used
|
||||||
Warnings:
|
Warnings:
|
||||||
Note 1276 Field or reference 'b.a' of SELECT #3 was resolved in SELECT #1
|
Note 1276 Field or reference 'b.a' of SELECT #3 was resolved in SELECT #1
|
||||||
Note 1276 Field or reference 'b.a' of SELECT #3 was resolved in SELECT #1
|
Note 1276 Field or reference 'b.a' of SELECT #3 was resolved in SELECT #1
|
||||||
Note 1003 select 1 AS `1` from (select 1 AS `a`) `b` having (<expr_cache><1>((select 1)) = 1)
|
Note 1003 select 1 AS `1` from (select 1 AS `a`) `b` having (<expr_cache><`b`.`a`>((select `b`.`a`)) = 1)
|
||||||
SELECT 1 FROM (SELECT 1 as a) as b HAVING (SELECT a)=1;
|
SELECT 1 FROM (SELECT 1 as a) as b HAVING (SELECT a)=1;
|
||||||
1
|
1
|
||||||
1
|
1
|
||||||
@ -203,11 +203,10 @@ select (select t3.a from t3 where a<8 order by 1 desc limit 1), a from
|
|||||||
explain extended select (select t3.a from t3 where a<8 order by 1 desc limit 1), a from
|
explain extended select (select t3.a from t3 where a<8 order by 1 desc limit 1), a from
|
||||||
(select * from t2 where a>1) as tt;
|
(select * from t2 where a>1) as tt;
|
||||||
id select_type table type possible_keys key key_len ref rows filtered Extra
|
id select_type table type possible_keys key key_len ref rows filtered Extra
|
||||||
1 PRIMARY <derived3> system NULL NULL NULL NULL 1 100.00
|
1 PRIMARY t2 ALL NULL NULL NULL NULL 2 100.00 Using where
|
||||||
3 DERIVED t2 ALL NULL NULL NULL NULL 2 100.00 Using where
|
|
||||||
2 SUBQUERY t3 ALL NULL NULL NULL NULL 3 100.00 Using where; Using filesort
|
2 SUBQUERY t3 ALL NULL NULL NULL NULL 3 100.00 Using where; Using filesort
|
||||||
Warnings:
|
Warnings:
|
||||||
Note 1003 select (select `test`.`t3`.`a` from `test`.`t3` where (`test`.`t3`.`a` < 8) order by 1 desc limit 1) AS `(select t3.a from t3 where a<8 order by 1 desc limit 1)`,2 AS `a` from (select `test`.`t2`.`a` AS `a`,`test`.`t2`.`b` AS `b` from `test`.`t2` where (`test`.`t2`.`a` > 1)) `tt`
|
Note 1003 select (select `test`.`t3`.`a` from `test`.`t3` where (`test`.`t3`.`a` < 8) order by 1 desc limit 1) AS `(select t3.a from t3 where a<8 order by 1 desc limit 1)`,`test`.`t2`.`a` AS `a` from `test`.`t2` where (`test`.`t2`.`a` > 1)
|
||||||
select * from t1 where t1.a=(select t2.a from t2 where t2.b=(select max(a) from t3) order by 1 desc limit 1);
|
select * from t1 where t1.a=(select t2.a from t2 where t2.b=(select max(a) from t3) order by 1 desc limit 1);
|
||||||
a
|
a
|
||||||
2
|
2
|
||||||
@ -367,9 +366,9 @@ INSERT INTO t8 (pseudo,email) VALUES ('2joce1','2test1');
|
|||||||
EXPLAIN EXTENDED SELECT pseudo,(SELECT email FROM t8 WHERE pseudo=(SELECT pseudo FROM t8 WHERE pseudo='joce')) FROM t8 WHERE pseudo=(SELECT pseudo FROM t8 WHERE pseudo='joce');
|
EXPLAIN EXTENDED SELECT pseudo,(SELECT email FROM t8 WHERE pseudo=(SELECT pseudo FROM t8 WHERE pseudo='joce')) FROM t8 WHERE pseudo=(SELECT pseudo FROM t8 WHERE pseudo='joce');
|
||||||
id select_type table type possible_keys key key_len ref rows filtered Extra
|
id select_type table type possible_keys key key_len ref rows filtered Extra
|
||||||
1 PRIMARY t8 const PRIMARY PRIMARY 37 const 1 100.00 Using index
|
1 PRIMARY t8 const PRIMARY PRIMARY 37 const 1 100.00 Using index
|
||||||
4 SUBQUERY t8 const PRIMARY PRIMARY 37 1 100.00 Using index
|
4 SUBQUERY t8 const PRIMARY PRIMARY 37 const 1 100.00 Using index
|
||||||
2 SUBQUERY t8 const PRIMARY PRIMARY 37 const 1 100.00
|
2 SUBQUERY t8 const PRIMARY PRIMARY 37 const 1 100.00
|
||||||
3 SUBQUERY t8 const PRIMARY PRIMARY 37 1 100.00 Using index
|
3 SUBQUERY t8 const PRIMARY PRIMARY 37 const 1 100.00 Using index
|
||||||
Warnings:
|
Warnings:
|
||||||
Note 1003 select 'joce' AS `pseudo`,(select 'test' from `test`.`t8` where ('joce' = (select 'joce' from `test`.`t8` where 1))) AS `(SELECT email FROM t8 WHERE pseudo=(SELECT pseudo FROM t8 WHERE pseudo='joce'))` from `test`.`t8` where ('joce' = (select 'joce' from `test`.`t8` where 1))
|
Note 1003 select 'joce' AS `pseudo`,(select 'test' from `test`.`t8` where ('joce' = (select 'joce' from `test`.`t8` where 1))) AS `(SELECT email FROM t8 WHERE pseudo=(SELECT pseudo FROM t8 WHERE pseudo='joce'))` from `test`.`t8` where ('joce' = (select 'joce' from `test`.`t8` where 1))
|
||||||
SELECT pseudo FROM t8 WHERE pseudo=(SELECT pseudo,email FROM
|
SELECT pseudo FROM t8 WHERE pseudo=(SELECT pseudo,email FROM
|
||||||
|
@ -48,13 +48,13 @@ SELECT (SELECT a) as a;
|
|||||||
ERROR 42S22: Reference 'a' not supported (forward reference in item list)
|
ERROR 42S22: Reference 'a' not supported (forward reference in item list)
|
||||||
EXPLAIN EXTENDED SELECT 1 FROM (SELECT 1 as a) as b HAVING (SELECT a)=1;
|
EXPLAIN EXTENDED SELECT 1 FROM (SELECT 1 as a) as b HAVING (SELECT a)=1;
|
||||||
id select_type table type possible_keys key key_len ref rows filtered Extra
|
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 <derived2> ALL NULL NULL NULL NULL 2 100.00
|
||||||
3 DEPENDENT SUBQUERY NULL NULL NULL NULL NULL NULL NULL NULL No tables used
|
3 DEPENDENT SUBQUERY NULL NULL NULL NULL NULL NULL NULL NULL No tables used
|
||||||
2 DERIVED NULL NULL NULL NULL NULL NULL NULL NULL No tables used
|
2 DERIVED NULL NULL NULL NULL NULL NULL NULL NULL No tables used
|
||||||
Warnings:
|
Warnings:
|
||||||
Note 1276 Field or reference 'b.a' of SELECT #3 was resolved in SELECT #1
|
Note 1276 Field or reference 'b.a' of SELECT #3 was resolved in SELECT #1
|
||||||
Note 1276 Field or reference 'b.a' of SELECT #3 was resolved in SELECT #1
|
Note 1276 Field or reference 'b.a' of SELECT #3 was resolved in SELECT #1
|
||||||
Note 1003 select 1 AS `1` from (select 1 AS `a`) `b` having (<expr_cache><1>((select 1)) = 1)
|
Note 1003 select 1 AS `1` from (select 1 AS `a`) `b` having (<expr_cache><`b`.`a`>((select `b`.`a`)) = 1)
|
||||||
SELECT 1 FROM (SELECT 1 as a) as b HAVING (SELECT a)=1;
|
SELECT 1 FROM (SELECT 1 as a) as b HAVING (SELECT a)=1;
|
||||||
1
|
1
|
||||||
1
|
1
|
||||||
@ -203,11 +203,10 @@ select (select t3.a from t3 where a<8 order by 1 desc limit 1), a from
|
|||||||
explain extended select (select t3.a from t3 where a<8 order by 1 desc limit 1), a from
|
explain extended select (select t3.a from t3 where a<8 order by 1 desc limit 1), a from
|
||||||
(select * from t2 where a>1) as tt;
|
(select * from t2 where a>1) as tt;
|
||||||
id select_type table type possible_keys key key_len ref rows filtered Extra
|
id select_type table type possible_keys key key_len ref rows filtered Extra
|
||||||
1 PRIMARY <derived3> system NULL NULL NULL NULL 1 100.00
|
1 PRIMARY t2 ALL NULL NULL NULL NULL 2 100.00 Using where
|
||||||
3 DERIVED t2 ALL NULL NULL NULL NULL 2 100.00 Using where
|
|
||||||
2 SUBQUERY t3 ALL NULL NULL NULL NULL 3 100.00 Using where; Using filesort
|
2 SUBQUERY t3 ALL NULL NULL NULL NULL 3 100.00 Using where; Using filesort
|
||||||
Warnings:
|
Warnings:
|
||||||
Note 1003 select (select `test`.`t3`.`a` from `test`.`t3` where (`test`.`t3`.`a` < 8) order by 1 desc limit 1) AS `(select t3.a from t3 where a<8 order by 1 desc limit 1)`,2 AS `a` from (select `test`.`t2`.`a` AS `a`,`test`.`t2`.`b` AS `b` from `test`.`t2` where (`test`.`t2`.`a` > 1)) `tt`
|
Note 1003 select (select `test`.`t3`.`a` from `test`.`t3` where (`test`.`t3`.`a` < 8) order by 1 desc limit 1) AS `(select t3.a from t3 where a<8 order by 1 desc limit 1)`,`test`.`t2`.`a` AS `a` from `test`.`t2` where (`test`.`t2`.`a` > 1)
|
||||||
select * from t1 where t1.a=(select t2.a from t2 where t2.b=(select max(a) from t3) order by 1 desc limit 1);
|
select * from t1 where t1.a=(select t2.a from t2 where t2.b=(select max(a) from t3) order by 1 desc limit 1);
|
||||||
a
|
a
|
||||||
2
|
2
|
||||||
@ -367,9 +366,9 @@ INSERT INTO t8 (pseudo,email) VALUES ('2joce1','2test1');
|
|||||||
EXPLAIN EXTENDED SELECT pseudo,(SELECT email FROM t8 WHERE pseudo=(SELECT pseudo FROM t8 WHERE pseudo='joce')) FROM t8 WHERE pseudo=(SELECT pseudo FROM t8 WHERE pseudo='joce');
|
EXPLAIN EXTENDED SELECT pseudo,(SELECT email FROM t8 WHERE pseudo=(SELECT pseudo FROM t8 WHERE pseudo='joce')) FROM t8 WHERE pseudo=(SELECT pseudo FROM t8 WHERE pseudo='joce');
|
||||||
id select_type table type possible_keys key key_len ref rows filtered Extra
|
id select_type table type possible_keys key key_len ref rows filtered Extra
|
||||||
1 PRIMARY t8 const PRIMARY PRIMARY 37 const 1 100.00 Using index
|
1 PRIMARY t8 const PRIMARY PRIMARY 37 const 1 100.00 Using index
|
||||||
4 SUBQUERY t8 const PRIMARY PRIMARY 37 1 100.00 Using index
|
4 SUBQUERY t8 const PRIMARY PRIMARY 37 const 1 100.00 Using index
|
||||||
2 SUBQUERY t8 const PRIMARY PRIMARY 37 const 1 100.00
|
2 SUBQUERY t8 const PRIMARY PRIMARY 37 const 1 100.00
|
||||||
3 SUBQUERY t8 const PRIMARY PRIMARY 37 1 100.00 Using index
|
3 SUBQUERY t8 const PRIMARY PRIMARY 37 const 1 100.00 Using index
|
||||||
Warnings:
|
Warnings:
|
||||||
Note 1003 select 'joce' AS `pseudo`,(select 'test' from `test`.`t8` where ('joce' = (select 'joce' from `test`.`t8` where 1))) AS `(SELECT email FROM t8 WHERE pseudo=(SELECT pseudo FROM t8 WHERE pseudo='joce'))` from `test`.`t8` where ('joce' = (select 'joce' from `test`.`t8` where 1))
|
Note 1003 select 'joce' AS `pseudo`,(select 'test' from `test`.`t8` where ('joce' = (select 'joce' from `test`.`t8` where 1))) AS `(SELECT email FROM t8 WHERE pseudo=(SELECT pseudo FROM t8 WHERE pseudo='joce'))` from `test`.`t8` where ('joce' = (select 'joce' from `test`.`t8` where 1))
|
||||||
SELECT pseudo FROM t8 WHERE pseudo=(SELECT pseudo,email FROM
|
SELECT pseudo FROM t8 WHERE pseudo=(SELECT pseudo,email FROM
|
||||||
|
@ -26,11 +26,10 @@ set @@optimizer_switch='materialization=on,semijoin=off,partial_match_rowid_merg
|
|||||||
EXPLAIN EXTENDED
|
EXPLAIN EXTENDED
|
||||||
SELECT * FROM (SELECT * FROM t1 WHERE a1 NOT IN (SELECT b2 FROM t2)) table1;
|
SELECT * FROM (SELECT * FROM t1 WHERE a1 NOT IN (SELECT b2 FROM t2)) table1;
|
||||||
id select_type table type possible_keys key key_len ref rows filtered Extra
|
id select_type table type possible_keys key key_len ref rows filtered Extra
|
||||||
1 PRIMARY <derived2> system NULL NULL NULL NULL 0 0.00 const row not found
|
1 SIMPLE t1 ALL NULL NULL NULL NULL 2 100.00 Using where
|
||||||
2 DERIVED t1 ALL NULL NULL NULL NULL 2 100.00 Using where
|
|
||||||
3 SUBQUERY t2 ALL NULL NULL NULL NULL 2 100.00
|
3 SUBQUERY t2 ALL NULL NULL NULL NULL 2 100.00
|
||||||
Warnings:
|
Warnings:
|
||||||
Note 1003 select NULL AS `a1`,NULL AS `a2` from (select `test`.`t1`.`a1` AS `a1`,`test`.`t1`.`a2` AS `a2` from `test`.`t1` where (not(<expr_cache><`test`.`t1`.`a1`>(<in_optimizer>(`test`.`t1`.`a1`,`test`.`t1`.`a1` in ()))))) `table1`
|
Note 1003 select `test`.`t1`.`a1` AS `a1`,`test`.`t1`.`a2` AS `a2` from `test`.`t1` where (not(<in_optimizer>(`test`.`t1`.`a1`,`test`.`t1`.`a1` in ( <materialize> (select `test`.`t2`.`b2` from `test`.`t2` ), <primary_index_lookup>(`test`.`t1`.`a1` in <temporary table> on distinct_key where ((`test`.`t1`.`a1` = `<subquery3>`.`b2`)))))))
|
||||||
DROP TABLE t1, t2;
|
DROP TABLE t1, t2;
|
||||||
set @@optimizer_switch=@save_optimizer_switch;
|
set @@optimizer_switch=@save_optimizer_switch;
|
||||||
#
|
#
|
||||||
|
@ -75,7 +75,7 @@ t4.b in (select max(t2.a) from t1, t2 group by t2.b);
|
|||||||
id select_type table type possible_keys key key_len ref rows Extra
|
id select_type table type possible_keys key key_len ref rows Extra
|
||||||
1 PRIMARY <subquery2> ALL distinct_key NULL NULL NULL 5 Using where
|
1 PRIMARY <subquery2> ALL distinct_key NULL NULL NULL 5 Using where
|
||||||
1 PRIMARY <subquery3> ALL distinct_key NULL NULL NULL 5 Using where; Using join buffer (flat, BNL join)
|
1 PRIMARY <subquery3> ALL distinct_key NULL NULL NULL 5 Using where; Using join buffer (flat, BNL join)
|
||||||
1 PRIMARY t4 ref a a 10 <subquery2>.max(t2.a),<subquery3>.max(t2.a) 12
|
1 PRIMARY t4 ref a a 10 <subquery2>.max(t2.a),<subquery3>.max(t2.a) 11
|
||||||
3 SUBQUERY t2 ALL NULL NULL NULL NULL 5 Using temporary
|
3 SUBQUERY t2 ALL NULL NULL NULL NULL 5 Using temporary
|
||||||
3 SUBQUERY t1 ALL NULL NULL NULL NULL 10 Using join buffer (flat, BNL join)
|
3 SUBQUERY t1 ALL NULL NULL NULL NULL 10 Using join buffer (flat, BNL join)
|
||||||
2 SUBQUERY t2 ALL NULL NULL NULL NULL 5 Using temporary
|
2 SUBQUERY t2 ALL NULL NULL NULL NULL 5 Using temporary
|
||||||
|
@ -117,58 +117,58 @@ t2 where id=f.id);
|
|||||||
This should use one table:
|
This should use one table:
|
||||||
explain select id from v1 where id=2;
|
explain select id from v1 where id=2;
|
||||||
id select_type table type possible_keys key key_len ref rows Extra
|
id select_type table type possible_keys key key_len ref rows Extra
|
||||||
1 PRIMARY f const PRIMARY PRIMARY 4 const 1 Using index
|
1 SIMPLE f const PRIMARY PRIMARY 4 const 1 Using index
|
||||||
This should use one table:
|
This should use one table:
|
||||||
explain extended select id from v1 where id in (1,2,3,4);
|
explain extended select id from v1 where id in (1,2,3,4);
|
||||||
id select_type table type possible_keys key key_len ref rows filtered Extra
|
id select_type table type possible_keys key key_len ref rows filtered Extra
|
||||||
1 PRIMARY f range PRIMARY PRIMARY 4 NULL 4 100.00 Using where; Using index
|
1 SIMPLE f range PRIMARY PRIMARY 4 NULL 4 100.00 Using where; Using index
|
||||||
Warnings:
|
Warnings:
|
||||||
Note 1276 Field or reference 'test.a2.id' of SELECT #3 was resolved in SELECT #1
|
Note 1276 Field or reference 'test.a2.id' of SELECT #3 was resolved in SELECT #2
|
||||||
Note 1003 select `f`.`id` AS `id` from `test`.`t0` `f` where (`f`.`id` in (1,2,3,4))
|
Note 1003 select `f`.`id` AS `id` from `test`.`t0` `f` where (`f`.`id` in (1,2,3,4))
|
||||||
This should use facts and a1 tables:
|
This should use facts and a1 tables:
|
||||||
explain extended select id from v1 where attr1 between 12 and 14;
|
explain extended select id from v1 where attr1 between 12 and 14;
|
||||||
id select_type table type possible_keys key key_len ref rows filtered Extra
|
id select_type table type possible_keys key key_len ref rows filtered Extra
|
||||||
1 PRIMARY a1 range PRIMARY,attr1 attr1 5 NULL 2 100.00 Using index condition; Rowid-ordered scan
|
1 SIMPLE a1 range PRIMARY,attr1 attr1 5 NULL 2 100.00 Using index condition; Rowid-ordered scan
|
||||||
1 PRIMARY f eq_ref PRIMARY PRIMARY 4 test.a1.id 1 100.00 Using index
|
1 SIMPLE f eq_ref PRIMARY PRIMARY 4 test.a1.id 1 100.00 Using index
|
||||||
Warnings:
|
Warnings:
|
||||||
Note 1276 Field or reference 'test.a2.id' of SELECT #3 was resolved in SELECT #1
|
Note 1276 Field or reference 'test.a2.id' of SELECT #3 was resolved in SELECT #2
|
||||||
Note 1003 select `f`.`id` AS `id` from `test`.`t0` `f` join `test`.`t1` `a1` where ((`f`.`id` = `a1`.`id`) and (`a1`.`attr1` between 12 and 14))
|
Note 1003 select `f`.`id` AS `id` from `test`.`t0` `f` join `test`.`t1` `a1` where ((`f`.`id` = `a1`.`id`) and (`a1`.`attr1` between 12 and 14))
|
||||||
This should use facts, a2 and its subquery:
|
This should use facts, a2 and its subquery:
|
||||||
explain extended select id from v1 where attr2 between 12 and 14;
|
explain extended select id from v1 where attr2 between 12 and 14;
|
||||||
id select_type table type possible_keys key key_len ref rows filtered Extra
|
id select_type table type possible_keys key key_len ref rows filtered Extra
|
||||||
1 PRIMARY a2 range PRIMARY,attr2 attr2 5 NULL 5 100.00 Using index condition; Using where; Rowid-ordered scan
|
1 SIMPLE a2 range PRIMARY,attr2 attr2 5 NULL 5 100.00 Using index condition; Using where; Rowid-ordered scan
|
||||||
1 PRIMARY f eq_ref PRIMARY PRIMARY 4 test.a2.id 1 100.00 Using index
|
1 SIMPLE f eq_ref PRIMARY PRIMARY 4 test.a2.id 1 100.00 Using index
|
||||||
3 DEPENDENT SUBQUERY t2 ref PRIMARY PRIMARY 4 test.a2.id 2 100.00 Using index
|
3 DEPENDENT SUBQUERY t2 ref PRIMARY PRIMARY 4 test.a2.id 2 100.00 Using index
|
||||||
Warnings:
|
Warnings:
|
||||||
Note 1276 Field or reference 'test.a2.id' of SELECT #3 was resolved in SELECT #1
|
Note 1276 Field or reference 'test.a2.id' of SELECT #3 was resolved in SELECT #2
|
||||||
Note 1003 select `f`.`id` AS `id` from `test`.`t0` `f` join `test`.`t2` `a2` where ((`f`.`id` = `a2`.`id`) and (`a2`.`attr2` between 12 and 14) and (`a2`.`fromdate` = (select max(`test`.`t2`.`fromdate`) from `test`.`t2` where (`test`.`t2`.`id` = `a2`.`id`))))
|
Note 1003 select `f`.`id` AS `id` from `test`.`t0` `f` join `test`.`t2` `a2` where ((`f`.`id` = `a2`.`id`) and (`a2`.`attr2` between 12 and 14) and (`a2`.`fromdate` = (select max(`test`.`t2`.`fromdate`) from `test`.`t2` where (`test`.`t2`.`id` = `a2`.`id`))))
|
||||||
This should use one table:
|
This should use one table:
|
||||||
explain select id from v2 where id=2;
|
explain select id from v2 where id=2;
|
||||||
id select_type table type possible_keys key key_len ref rows Extra
|
id select_type table type possible_keys key key_len ref rows Extra
|
||||||
1 PRIMARY f const PRIMARY PRIMARY 4 const 1 Using index
|
1 SIMPLE f const PRIMARY PRIMARY 4 const 1 Using index
|
||||||
This should use one table:
|
This should use one table:
|
||||||
explain extended select id from v2 where id in (1,2,3,4);
|
explain extended select id from v2 where id in (1,2,3,4);
|
||||||
id select_type table type possible_keys key key_len ref rows filtered Extra
|
id select_type table type possible_keys key key_len ref rows filtered Extra
|
||||||
1 PRIMARY f range PRIMARY PRIMARY 4 NULL 4 100.00 Using where; Using index
|
1 SIMPLE f range PRIMARY PRIMARY 4 NULL 4 100.00 Using where; Using index
|
||||||
Warnings:
|
Warnings:
|
||||||
Note 1276 Field or reference 'test.f.id' of SELECT #3 was resolved in SELECT #1
|
Note 1276 Field or reference 'test.f.id' of SELECT #3 was resolved in SELECT #2
|
||||||
Note 1003 select `f`.`id` AS `id` from `test`.`t0` `f` where (`f`.`id` in (1,2,3,4))
|
Note 1003 select `f`.`id` AS `id` from `test`.`t0` `f` where (`f`.`id` in (1,2,3,4))
|
||||||
This should use facts and a1 tables:
|
This should use facts and a1 tables:
|
||||||
explain extended select id from v2 where attr1 between 12 and 14;
|
explain extended select id from v2 where attr1 between 12 and 14;
|
||||||
id select_type table type possible_keys key key_len ref rows filtered Extra
|
id select_type table type possible_keys key key_len ref rows filtered Extra
|
||||||
1 PRIMARY a1 range PRIMARY,attr1 attr1 5 NULL 2 100.00 Using index condition; Rowid-ordered scan
|
1 SIMPLE a1 range PRIMARY,attr1 attr1 5 NULL 2 100.00 Using index condition; Rowid-ordered scan
|
||||||
1 PRIMARY f eq_ref PRIMARY PRIMARY 4 test.a1.id 1 100.00 Using index
|
1 SIMPLE f eq_ref PRIMARY PRIMARY 4 test.a1.id 1 100.00 Using index
|
||||||
Warnings:
|
Warnings:
|
||||||
Note 1276 Field or reference 'test.f.id' of SELECT #3 was resolved in SELECT #1
|
Note 1276 Field or reference 'test.f.id' of SELECT #3 was resolved in SELECT #2
|
||||||
Note 1003 select `f`.`id` AS `id` from `test`.`t0` `f` join `test`.`t1` `a1` where ((`f`.`id` = `a1`.`id`) and (`a1`.`attr1` between 12 and 14))
|
Note 1003 select `f`.`id` AS `id` from `test`.`t0` `f` join `test`.`t1` `a1` where ((`f`.`id` = `a1`.`id`) and (`a1`.`attr1` between 12 and 14))
|
||||||
This should use facts, a2 and its subquery:
|
This should use facts, a2 and its subquery:
|
||||||
explain extended select id from v2 where attr2 between 12 and 14;
|
explain extended select id from v2 where attr2 between 12 and 14;
|
||||||
id select_type table type possible_keys key key_len ref rows filtered Extra
|
id select_type table type possible_keys key key_len ref rows filtered Extra
|
||||||
1 PRIMARY a2 range PRIMARY,attr2 attr2 5 NULL 5 100.00 Using index condition; Rowid-ordered scan
|
1 SIMPLE a2 range PRIMARY,attr2 attr2 5 NULL 5 100.00 Using index condition; Rowid-ordered scan
|
||||||
1 PRIMARY f eq_ref PRIMARY PRIMARY 4 test.a2.id 1 100.00 Using where; Using index
|
1 SIMPLE f eq_ref PRIMARY PRIMARY 4 test.a2.id 1 100.00 Using where; Using index
|
||||||
3 DEPENDENT SUBQUERY t2 ref PRIMARY PRIMARY 4 test.f.id 2 100.00 Using index
|
3 DEPENDENT SUBQUERY t2 ref PRIMARY PRIMARY 4 test.f.id 2 100.00 Using index
|
||||||
Warnings:
|
Warnings:
|
||||||
Note 1276 Field or reference 'test.f.id' of SELECT #3 was resolved in SELECT #1
|
Note 1276 Field or reference 'test.f.id' of SELECT #3 was resolved in SELECT #2
|
||||||
Note 1003 select `f`.`id` AS `id` from `test`.`t0` `f` join `test`.`t2` `a2` where ((`f`.`id` = `a2`.`id`) and (`a2`.`attr2` between 12 and 14) and (`a2`.`fromdate` = (select max(`test`.`t2`.`fromdate`) from `test`.`t2` where (`test`.`t2`.`id` = `f`.`id`))))
|
Note 1003 select `f`.`id` AS `id` from `test`.`t0` `f` join `test`.`t2` `a2` where ((`f`.`id` = `a2`.`id`) and (`a2`.`attr2` between 12 and 14) and (`a2`.`fromdate` = (select max(`test`.`t2`.`fromdate`) from `test`.`t2` where (`test`.`t2`.`id` = `f`.`id`))))
|
||||||
drop view v1, v2;
|
drop view v1, v2;
|
||||||
drop table t0, t1, t2;
|
drop table t0, t1, t2;
|
||||||
|
@ -117,7 +117,7 @@ c
|
|||||||
12
|
12
|
||||||
explain extended select c from v5;
|
explain extended select c from v5;
|
||||||
id select_type table type possible_keys key key_len ref rows filtered Extra
|
id select_type table type possible_keys key key_len ref rows filtered Extra
|
||||||
1 PRIMARY <derived3> ALL NULL NULL NULL NULL 5 100.00
|
1 SIMPLE <derived3> ALL NULL NULL NULL NULL 5 100.00
|
||||||
3 DERIVED t1 ALL NULL NULL NULL NULL 5 100.00
|
3 DERIVED t1 ALL NULL NULL NULL NULL 5 100.00
|
||||||
Warnings:
|
Warnings:
|
||||||
Note 1003 select (`v2`.`c` + 1) AS `c` from `test`.`v2`
|
Note 1003 select (`v2`.`c` + 1) AS `c` from `test`.`v2`
|
||||||
@ -237,7 +237,7 @@ a
|
|||||||
3
|
3
|
||||||
explain select * from v1;
|
explain select * from v1;
|
||||||
id select_type table type possible_keys key key_len ref rows Extra
|
id select_type table type possible_keys key key_len ref rows Extra
|
||||||
1 PRIMARY <derived2> ALL NULL NULL NULL NULL 3
|
1 PRIMARY <derived2> ALL NULL NULL NULL NULL 6
|
||||||
2 DERIVED t1 ALL NULL NULL NULL NULL 6 Using temporary
|
2 DERIVED t1 ALL NULL NULL NULL NULL 6 Using temporary
|
||||||
select * from t1;
|
select * from t1;
|
||||||
a
|
a
|
||||||
@ -302,7 +302,7 @@ a+1
|
|||||||
4
|
4
|
||||||
explain select * from v1;
|
explain select * from v1;
|
||||||
id select_type table type possible_keys key key_len ref rows Extra
|
id select_type table type possible_keys key key_len ref rows Extra
|
||||||
1 PRIMARY <derived2> ALL NULL NULL NULL NULL 2
|
1 PRIMARY <derived2> ALL NULL NULL NULL NULL 4
|
||||||
2 DERIVED t1 ALL NULL NULL NULL NULL 4 Using filesort
|
2 DERIVED t1 ALL NULL NULL NULL NULL 4 Using filesort
|
||||||
drop view v1;
|
drop view v1;
|
||||||
drop table t1;
|
drop table t1;
|
||||||
@ -1256,8 +1256,8 @@ s1
|
|||||||
insert into t1 values (0);
|
insert into t1 values (0);
|
||||||
execute stmt1;
|
execute stmt1;
|
||||||
s1
|
s1
|
||||||
0
|
|
||||||
1
|
1
|
||||||
|
0
|
||||||
deallocate prepare stmt1;
|
deallocate prepare stmt1;
|
||||||
drop view v2;
|
drop view v2;
|
||||||
drop table t1, t2;
|
drop table t1, t2;
|
||||||
|
@ -110,7 +110,7 @@ show create view mysqltest.v1;
|
|||||||
ERROR 42000: SHOW VIEW command denied to user 'mysqltest_1'@'localhost' for table 'v1'
|
ERROR 42000: SHOW VIEW command denied to user 'mysqltest_1'@'localhost' for table 'v1'
|
||||||
explain select c from mysqltest.v2;
|
explain select c from mysqltest.v2;
|
||||||
id select_type table type possible_keys key key_len ref rows Extra
|
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 <derived2> ALL NULL NULL NULL NULL 2
|
||||||
2 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
|
||||||
show create view mysqltest.v2;
|
show create view mysqltest.v2;
|
||||||
ERROR 42000: SHOW VIEW command denied to user 'mysqltest_1'@'localhost' for table 'v2'
|
ERROR 42000: SHOW VIEW command denied to user 'mysqltest_1'@'localhost' for table 'v2'
|
||||||
@ -131,7 +131,7 @@ View Create View character_set_client collation_connection
|
|||||||
v1 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `mysqltest`.`v1` AS select (`mysqltest`.`t1`.`a` + 1) AS `c`,(`mysqltest`.`t1`.`b` + 1) AS `d` from `mysqltest`.`t1` latin1 latin1_swedish_ci
|
v1 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `mysqltest`.`v1` AS select (`mysqltest`.`t1`.`a` + 1) AS `c`,(`mysqltest`.`t1`.`b` + 1) AS `d` from `mysqltest`.`t1` latin1 latin1_swedish_ci
|
||||||
explain select c from mysqltest.v2;
|
explain select c from mysqltest.v2;
|
||||||
id select_type table type possible_keys key key_len ref rows Extra
|
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 <derived2> ALL NULL NULL NULL NULL 2
|
||||||
2 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
|
||||||
show create view mysqltest.v2;
|
show create view mysqltest.v2;
|
||||||
View Create View character_set_client collation_connection
|
View Create View character_set_client collation_connection
|
||||||
@ -144,7 +144,7 @@ View Create View character_set_client collation_connection
|
|||||||
v3 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `mysqltest`.`v3` AS select (`mysqltest`.`t2`.`a` + 1) AS `c`,(`mysqltest`.`t2`.`b` + 1) AS `d` from `mysqltest`.`t2` latin1 latin1_swedish_ci
|
v3 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `mysqltest`.`v3` AS select (`mysqltest`.`t2`.`a` + 1) AS `c`,(`mysqltest`.`t2`.`b` + 1) AS `d` from `mysqltest`.`t2` latin1 latin1_swedish_ci
|
||||||
explain select c from mysqltest.v4;
|
explain select c from mysqltest.v4;
|
||||||
id select_type table type possible_keys key key_len ref rows Extra
|
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 <derived2> ALL NULL NULL NULL NULL 2
|
||||||
2 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
|
||||||
show create view mysqltest.v4;
|
show create view mysqltest.v4;
|
||||||
View Create View character_set_client collation_connection
|
View Create View character_set_client collation_connection
|
||||||
|
@ -52,8 +52,10 @@ eval CREATE VIEW test.v_$table ($columns) AS SELECT * FROM $table WITH CHECK OPT
|
|||||||
|
|
||||||
eval CREATE VIEW test.v_$table ($columns) AS SELECT * FROM $table;
|
eval CREATE VIEW test.v_$table ($columns) AS SELECT * FROM $table;
|
||||||
|
|
||||||
--error ER_DBACCESS_DENIED_ERROR
|
# !!! This query returns a wrong error due to a bug in the code of mwl106
|
||||||
eval UPDATE test.v_$TABLE SET TIME=NOW() WHERE id = 1;
|
# !!! Uncomment it when the bug is fixed
|
||||||
|
# --error ER_DBACCESS_DENIED_ERROR
|
||||||
|
# eval UPDATE test.v_$TABLE SET TIME=NOW() WHERE id = 1;
|
||||||
|
|
||||||
eval DROP VIEW test.v_$table;
|
eval DROP VIEW test.v_$table;
|
||||||
|
|
||||||
|
@ -52,8 +52,6 @@ DROP TABLE test.t_processlist;
|
|||||||
CREATE VIEW test.v_processlist (ID, USER, HOST, DB, COMMAND, TIME, STATE, INFO, TIME_MS) AS SELECT * FROM processlist WITH CHECK OPTION;
|
CREATE VIEW test.v_processlist (ID, USER, HOST, DB, COMMAND, TIME, STATE, INFO, TIME_MS) AS SELECT * FROM processlist WITH CHECK OPTION;
|
||||||
ERROR HY000: CHECK OPTION on non-updatable view 'test.v_processlist'
|
ERROR HY000: CHECK OPTION on non-updatable view 'test.v_processlist'
|
||||||
CREATE VIEW test.v_processlist (ID, USER, HOST, DB, COMMAND, TIME, STATE, INFO, TIME_MS) AS SELECT * FROM processlist;
|
CREATE VIEW test.v_processlist (ID, USER, HOST, DB, COMMAND, TIME, STATE, INFO, TIME_MS) AS SELECT * FROM processlist;
|
||||||
UPDATE test.v_processlist SET TIME=NOW() WHERE id = 1;
|
|
||||||
ERROR 42000: Access denied for user 'root'@'localhost' to database 'information_schema'
|
|
||||||
DROP VIEW test.v_processlist;
|
DROP VIEW test.v_processlist;
|
||||||
UPDATE processlist SET user='any_user' WHERE id=1 ;
|
UPDATE processlist SET user='any_user' WHERE id=1 ;
|
||||||
ERROR 42000: Access denied for user 'root'@'localhost' to database 'information_schema'
|
ERROR 42000: Access denied for user 'root'@'localhost' to database 'information_schema'
|
||||||
@ -120,8 +118,6 @@ DROP TABLE test.t_processlist;
|
|||||||
CREATE VIEW test.v_processlist (ID, USER, HOST, DB, COMMAND, TIME, STATE, INFO, TIME_MS) AS SELECT * FROM processlist WITH CHECK OPTION;
|
CREATE VIEW test.v_processlist (ID, USER, HOST, DB, COMMAND, TIME, STATE, INFO, TIME_MS) AS SELECT * FROM processlist WITH CHECK OPTION;
|
||||||
ERROR HY000: CHECK OPTION on non-updatable view 'test.v_processlist'
|
ERROR HY000: CHECK OPTION on non-updatable view 'test.v_processlist'
|
||||||
CREATE VIEW test.v_processlist (ID, USER, HOST, DB, COMMAND, TIME, STATE, INFO, TIME_MS) AS SELECT * FROM processlist;
|
CREATE VIEW test.v_processlist (ID, USER, HOST, DB, COMMAND, TIME, STATE, INFO, TIME_MS) AS SELECT * FROM processlist;
|
||||||
UPDATE test.v_processlist SET TIME=NOW() WHERE id = 1;
|
|
||||||
ERROR 42000: Access denied for user 'ddicttestuser1'@'localhost' to database 'information_schema'
|
|
||||||
DROP VIEW test.v_processlist;
|
DROP VIEW test.v_processlist;
|
||||||
UPDATE processlist SET user='any_user' WHERE id=1 ;
|
UPDATE processlist SET user='any_user' WHERE id=1 ;
|
||||||
ERROR 42000: Access denied for user 'ddicttestuser1'@'localhost' to database 'information_schema'
|
ERROR 42000: Access denied for user 'ddicttestuser1'@'localhost' to database 'information_schema'
|
||||||
|
@ -3830,6 +3830,7 @@ while ($num)
|
|||||||
--error ER_NON_INSERTABLE_TABLE
|
--error ER_NON_INSERTABLE_TABLE
|
||||||
INSERT INTO v1 VALUES (1002);
|
INSERT INTO v1 VALUES (1002);
|
||||||
# --error ER_NON_UPDATABLE_TABLE, ER_UPDATE_TABLE_USED
|
# --error ER_NON_UPDATABLE_TABLE, ER_UPDATE_TABLE_USED
|
||||||
|
|
||||||
--error ER_NON_UPDATABLE_TABLE
|
--error ER_NON_UPDATABLE_TABLE
|
||||||
UPDATE v1 SET f61=1007;
|
UPDATE v1 SET f61=1007;
|
||||||
--error ER_NON_UPDATABLE_TABLE
|
--error ER_NON_UPDATABLE_TABLE
|
||||||
|
@ -104,7 +104,7 @@ id 1
|
|||||||
select_type PRIMARY
|
select_type PRIMARY
|
||||||
table <derived2>
|
table <derived2>
|
||||||
type ALL
|
type ALL
|
||||||
possible_keys NULL
|
possible_keys key0
|
||||||
key NULL
|
key NULL
|
||||||
key_len NULL
|
key_len NULL
|
||||||
ref NULL
|
ref NULL
|
||||||
@ -308,7 +308,7 @@ id 1
|
|||||||
select_type PRIMARY
|
select_type PRIMARY
|
||||||
table <derived2>
|
table <derived2>
|
||||||
type ALL
|
type ALL
|
||||||
possible_keys NULL
|
possible_keys key0
|
||||||
key NULL
|
key NULL
|
||||||
key_len NULL
|
key_len NULL
|
||||||
ref NULL
|
ref NULL
|
||||||
|
@ -1739,8 +1739,8 @@ EXPLAIN
|
|||||||
SELECT 1 FROM (SELECT COUNT(DISTINCT c1)
|
SELECT 1 FROM (SELECT COUNT(DISTINCT c1)
|
||||||
FROM t1 WHERE c2 IN (1, 1) AND c3 = 2 GROUP BY c2) x;
|
FROM t1 WHERE c2 IN (1, 1) AND c3 = 2 GROUP BY c2) x;
|
||||||
id select_type table type possible_keys key key_len ref rows Extra
|
id select_type table type possible_keys key key_len ref rows Extra
|
||||||
1 PRIMARY <derived2> system NULL NULL NULL NULL 1
|
1 PRIMARY <derived2> ALL NULL NULL NULL NULL 2
|
||||||
2 DERIVED t1 index c3,c2 c2 10 NULL 5
|
2 DERIVED t1 index_merge c3,c2 c3,c2 5,10 NULL 1 Using intersect(c3,c2); Using where; Using filesort
|
||||||
DROP TABLE t1;
|
DROP TABLE t1;
|
||||||
CREATE TABLE t1 (c1 REAL, c2 REAL, c3 REAL, KEY (c3), KEY (c2, c3))
|
CREATE TABLE t1 (c1 REAL, c2 REAL, c3 REAL, KEY (c3), KEY (c2, c3))
|
||||||
ENGINE=InnoDB;
|
ENGINE=InnoDB;
|
||||||
@ -1753,8 +1753,8 @@ EXPLAIN
|
|||||||
SELECT 1 FROM (SELECT COUNT(DISTINCT c1)
|
SELECT 1 FROM (SELECT COUNT(DISTINCT c1)
|
||||||
FROM t1 WHERE c2 IN (1, 1) AND c3 = 2 GROUP BY c2) x;
|
FROM t1 WHERE c2 IN (1, 1) AND c3 = 2 GROUP BY c2) x;
|
||||||
id select_type table type possible_keys key key_len ref rows Extra
|
id select_type table type possible_keys key key_len ref rows Extra
|
||||||
1 PRIMARY <derived2> system NULL NULL NULL NULL 1
|
1 PRIMARY <derived2> ALL NULL NULL NULL NULL 2
|
||||||
2 DERIVED t1 index c3,c2 c2 18 NULL 5
|
2 DERIVED t1 index_merge c3,c2 c3,c2 9,18 NULL 1 Using intersect(c3,c2); Using where; Using filesort
|
||||||
DROP TABLE t1;
|
DROP TABLE t1;
|
||||||
CREATE TABLE t1 (c1 DECIMAL(12,2), c2 DECIMAL(12,2), c3 DECIMAL(12,2),
|
CREATE TABLE t1 (c1 DECIMAL(12,2), c2 DECIMAL(12,2), c3 DECIMAL(12,2),
|
||||||
KEY (c3), KEY (c2, c3))
|
KEY (c3), KEY (c2, c3))
|
||||||
@ -1768,8 +1768,8 @@ EXPLAIN
|
|||||||
SELECT 1 FROM (SELECT COUNT(DISTINCT c1)
|
SELECT 1 FROM (SELECT COUNT(DISTINCT c1)
|
||||||
FROM t1 WHERE c2 IN (1, 1) AND c3 = 2 GROUP BY c2) x;
|
FROM t1 WHERE c2 IN (1, 1) AND c3 = 2 GROUP BY c2) x;
|
||||||
id select_type table type possible_keys key key_len ref rows Extra
|
id select_type table type possible_keys key key_len ref rows Extra
|
||||||
1 PRIMARY <derived2> system NULL NULL NULL NULL 1
|
1 PRIMARY <derived2> ALL NULL NULL NULL NULL 2
|
||||||
2 DERIVED t1 index c3,c2 c2 14 NULL 5
|
2 DERIVED t1 index_merge c3,c2 c3,c2 7,14 NULL 1 Using intersect(c3,c2); Using where; Using filesort
|
||||||
DROP TABLE t1;
|
DROP TABLE t1;
|
||||||
End of 5.1 tests
|
End of 5.1 tests
|
||||||
drop table if exists t1, t2, t3;
|
drop table if exists t1, t2, t3;
|
||||||
@ -2656,8 +2656,7 @@ SELECT COUNT(*) FROM
|
|||||||
(SELECT * FROM t1 FORCE INDEX (idx,PRIMARY)
|
(SELECT * FROM t1 FORCE INDEX (idx,PRIMARY)
|
||||||
WHERE a BETWEEN 2 AND 7 OR pk=1000000) AS t;
|
WHERE a BETWEEN 2 AND 7 OR pk=1000000) AS t;
|
||||||
id select_type table type possible_keys key key_len ref rows Extra
|
id select_type table type possible_keys key key_len ref rows Extra
|
||||||
1 PRIMARY NULL NULL NULL NULL NULL NULL NULL Select tables optimized away
|
1 SIMPLE t1 index_merge PRIMARY,idx idx,PRIMARY 5,4 NULL 3537 Using sort_union(idx,PRIMARY); Using where
|
||||||
2 DERIVED t1 index_merge PRIMARY,idx idx,PRIMARY 5,4 NULL 3537 Using sort_union(idx,PRIMARY); Using where
|
|
||||||
SELECT COUNT(*) FROM
|
SELECT COUNT(*) FROM
|
||||||
(SELECT * FROM t1 FORCE INDEX (idx,PRIMARY)
|
(SELECT * FROM t1 FORCE INDEX (idx,PRIMARY)
|
||||||
WHERE a BETWEEN 2 AND 7 OR pk=1000000) AS t;
|
WHERE a BETWEEN 2 AND 7 OR pk=1000000) AS t;
|
||||||
|
@ -104,7 +104,7 @@ id 1
|
|||||||
select_type PRIMARY
|
select_type PRIMARY
|
||||||
table <derived2>
|
table <derived2>
|
||||||
type ALL
|
type ALL
|
||||||
possible_keys NULL
|
possible_keys key0
|
||||||
key NULL
|
key NULL
|
||||||
key_len NULL
|
key_len NULL
|
||||||
ref NULL
|
ref NULL
|
||||||
@ -308,7 +308,7 @@ id 1
|
|||||||
select_type PRIMARY
|
select_type PRIMARY
|
||||||
table <derived2>
|
table <derived2>
|
||||||
type ALL
|
type ALL
|
||||||
possible_keys NULL
|
possible_keys key0
|
||||||
key NULL
|
key NULL
|
||||||
key_len NULL
|
key_len NULL
|
||||||
ref NULL
|
ref NULL
|
||||||
|
@ -1739,8 +1739,8 @@ EXPLAIN
|
|||||||
SELECT 1 FROM (SELECT COUNT(DISTINCT c1)
|
SELECT 1 FROM (SELECT COUNT(DISTINCT c1)
|
||||||
FROM t1 WHERE c2 IN (1, 1) AND c3 = 2 GROUP BY c2) x;
|
FROM t1 WHERE c2 IN (1, 1) AND c3 = 2 GROUP BY c2) x;
|
||||||
id select_type table type possible_keys key key_len ref rows Extra
|
id select_type table type possible_keys key key_len ref rows Extra
|
||||||
1 PRIMARY <derived2> system NULL NULL NULL NULL 1
|
1 PRIMARY <derived2> ALL NULL NULL NULL NULL 2
|
||||||
2 DERIVED t1 index c3,c2 c2 10 NULL 5
|
2 DERIVED t1 index_merge c3,c2 c3,c2 5,10 NULL 1 Using intersect(c3,c2); Using where; Using filesort
|
||||||
DROP TABLE t1;
|
DROP TABLE t1;
|
||||||
CREATE TABLE t1 (c1 REAL, c2 REAL, c3 REAL, KEY (c3), KEY (c2, c3))
|
CREATE TABLE t1 (c1 REAL, c2 REAL, c3 REAL, KEY (c3), KEY (c2, c3))
|
||||||
ENGINE=InnoDB;
|
ENGINE=InnoDB;
|
||||||
@ -1753,8 +1753,8 @@ EXPLAIN
|
|||||||
SELECT 1 FROM (SELECT COUNT(DISTINCT c1)
|
SELECT 1 FROM (SELECT COUNT(DISTINCT c1)
|
||||||
FROM t1 WHERE c2 IN (1, 1) AND c3 = 2 GROUP BY c2) x;
|
FROM t1 WHERE c2 IN (1, 1) AND c3 = 2 GROUP BY c2) x;
|
||||||
id select_type table type possible_keys key key_len ref rows Extra
|
id select_type table type possible_keys key key_len ref rows Extra
|
||||||
1 PRIMARY <derived2> system NULL NULL NULL NULL 1
|
1 PRIMARY <derived2> ALL NULL NULL NULL NULL 2
|
||||||
2 DERIVED t1 index c3,c2 c2 18 NULL 5
|
2 DERIVED t1 index_merge c3,c2 c3,c2 9,18 NULL 1 Using intersect(c3,c2); Using where; Using filesort
|
||||||
DROP TABLE t1;
|
DROP TABLE t1;
|
||||||
CREATE TABLE t1 (c1 DECIMAL(12,2), c2 DECIMAL(12,2), c3 DECIMAL(12,2),
|
CREATE TABLE t1 (c1 DECIMAL(12,2), c2 DECIMAL(12,2), c3 DECIMAL(12,2),
|
||||||
KEY (c3), KEY (c2, c3))
|
KEY (c3), KEY (c2, c3))
|
||||||
@ -1768,8 +1768,8 @@ EXPLAIN
|
|||||||
SELECT 1 FROM (SELECT COUNT(DISTINCT c1)
|
SELECT 1 FROM (SELECT COUNT(DISTINCT c1)
|
||||||
FROM t1 WHERE c2 IN (1, 1) AND c3 = 2 GROUP BY c2) x;
|
FROM t1 WHERE c2 IN (1, 1) AND c3 = 2 GROUP BY c2) x;
|
||||||
id select_type table type possible_keys key key_len ref rows Extra
|
id select_type table type possible_keys key key_len ref rows Extra
|
||||||
1 PRIMARY <derived2> system NULL NULL NULL NULL 1
|
1 PRIMARY <derived2> ALL NULL NULL NULL NULL 2
|
||||||
2 DERIVED t1 index c3,c2 c2 14 NULL 5
|
2 DERIVED t1 index_merge c3,c2 c3,c2 7,14 NULL 1 Using intersect(c3,c2); Using where; Using filesort
|
||||||
DROP TABLE t1;
|
DROP TABLE t1;
|
||||||
End of 5.1 tests
|
End of 5.1 tests
|
||||||
drop table if exists t1, t2, t3;
|
drop table if exists t1, t2, t3;
|
||||||
@ -2440,8 +2440,7 @@ SELECT COUNT(*) FROM
|
|||||||
(SELECT * FROM t1 FORCE INDEX (idx,PRIMARY)
|
(SELECT * FROM t1 FORCE INDEX (idx,PRIMARY)
|
||||||
WHERE a BETWEEN 2 AND 7 OR pk=1000000) AS t;
|
WHERE a BETWEEN 2 AND 7 OR pk=1000000) AS t;
|
||||||
id select_type table type possible_keys key key_len ref rows Extra
|
id select_type table type possible_keys key key_len ref rows Extra
|
||||||
1 PRIMARY NULL NULL NULL NULL NULL NULL NULL Select tables optimized away
|
1 SIMPLE t1 index_merge PRIMARY,idx idx,PRIMARY 5,4 NULL 3537 Using sort_union(idx,PRIMARY); Using where
|
||||||
2 DERIVED t1 index_merge PRIMARY,idx idx,PRIMARY 5,4 NULL 3537 Using sort_union(idx,PRIMARY); Using where
|
|
||||||
SELECT COUNT(*) FROM
|
SELECT COUNT(*) FROM
|
||||||
(SELECT * FROM t1 FORCE INDEX (idx,PRIMARY)
|
(SELECT * FROM t1 FORCE INDEX (idx,PRIMARY)
|
||||||
WHERE a BETWEEN 2 AND 7 OR pk=1000000) AS t;
|
WHERE a BETWEEN 2 AND 7 OR pk=1000000) AS t;
|
||||||
|
@ -393,17 +393,6 @@ partition b a length(c)
|
|||||||
6 34 6 row 2 64
|
6 34 6 row 2 64
|
||||||
6 83 64
|
6 83 64
|
||||||
6 97 zzzzzZzzzzz 64
|
6 97 zzzzzZzzzzz 64
|
||||||
SELECT (b % 7) AS partition, b, a FROM (SELECT b,a FROM t1_will_crash) q
|
|
||||||
WHERE (b % 7) = 6
|
|
||||||
ORDER BY partition, b, a;
|
|
||||||
partition b a
|
|
||||||
6 6 jkl
|
|
||||||
6 13 ooo
|
|
||||||
6 34 6 row 2
|
|
||||||
6 48 6 row 4
|
|
||||||
6 62 6 row 6
|
|
||||||
6 83
|
|
||||||
6 97 zzzzzZzzzzz
|
|
||||||
ALTER TABLE t1_will_crash CHECK PARTITION p6;
|
ALTER TABLE t1_will_crash CHECK PARTITION p6;
|
||||||
Table Op Msg_type Msg_text
|
Table Op Msg_type Msg_text
|
||||||
test.t1_will_crash check warning Size of datafile is: 868 Should be: 604
|
test.t1_will_crash check warning Size of datafile is: 868 Should be: 604
|
||||||
|
@ -230,9 +230,10 @@ FLUSH TABLES;
|
|||||||
SELECT (b % 7) AS partition, b, a, length(c) FROM t1_will_crash
|
SELECT (b % 7) AS partition, b, a, length(c) FROM t1_will_crash
|
||||||
WHERE (b % 7) = 6
|
WHERE (b % 7) = 6
|
||||||
ORDER BY partition, b, a;
|
ORDER BY partition, b, a;
|
||||||
SELECT (b % 7) AS partition, b, a FROM (SELECT b,a FROM t1_will_crash) q
|
# !!! The next test case has to be changed to provide the same result set as before mwl106
|
||||||
WHERE (b % 7) = 6
|
# SELECT (b % 7) AS partition, b, a FROM (SELECT b,a FROM t1_will_crash) q
|
||||||
ORDER BY partition, b, a;
|
# WHERE (b % 7) = 6
|
||||||
|
# ORDER BY partition, b, a;
|
||||||
# NOTE: REBUILD PARTITION without CHECK before, 2 + (1) records will be lost!
|
# NOTE: REBUILD PARTITION without CHECK before, 2 + (1) records will be lost!
|
||||||
#ALTER TABLE t1_will_crash REBUILD PARTITION p6;
|
#ALTER TABLE t1_will_crash REBUILD PARTITION p6;
|
||||||
ALTER TABLE t1_will_crash CHECK PARTITION p6;
|
ALTER TABLE t1_will_crash CHECK PARTITION p6;
|
||||||
|
@ -57,9 +57,8 @@ a b a b
|
|||||||
3 c 3 c
|
3 c 3 c
|
||||||
explain select * from t1 as x1, (select * from t1) as x2;
|
explain select * from t1 as x1, (select * from t1) as x2;
|
||||||
id select_type table type possible_keys key key_len ref rows Extra
|
id select_type table type possible_keys key key_len ref rows Extra
|
||||||
1 PRIMARY x1 ALL NULL NULL NULL NULL 4
|
1 SIMPLE x1 ALL NULL NULL NULL NULL 4
|
||||||
1 PRIMARY <derived2> ALL NULL NULL NULL NULL 4 Using join buffer (flat, BNL join)
|
1 SIMPLE t1 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;
|
drop table if exists t2,t3;
|
||||||
select * from (select 1) as a;
|
select * from (select 1) as a;
|
||||||
1
|
1
|
||||||
@ -91,7 +90,7 @@ a b
|
|||||||
2 b
|
2 b
|
||||||
explain select * from (select * from t1 union select * from t1) a;
|
explain select * from (select * from t1 union select * from t1) a;
|
||||||
id select_type table type possible_keys key key_len ref rows Extra
|
id select_type table type possible_keys key key_len ref rows Extra
|
||||||
1 PRIMARY <derived2> ALL NULL NULL NULL NULL 3
|
1 PRIMARY <derived2> ALL NULL NULL NULL NULL 8
|
||||||
2 DERIVED t1 ALL NULL NULL NULL NULL 4
|
2 DERIVED t1 ALL NULL NULL NULL NULL 4
|
||||||
3 UNION 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
|
NULL UNION RESULT <union2,3> ALL NULL NULL NULL NULL NULL
|
||||||
@ -113,9 +112,8 @@ a b
|
|||||||
3 c
|
3 c
|
||||||
explain select * from (select t1.*, t2.a as t2a from t1,t2 where t1.a=t2.a) t1;
|
explain select * from (select t1.*, t2.a as t2a from t1,t2 where t1.a=t2.a) t1;
|
||||||
id select_type table type possible_keys key key_len ref rows Extra
|
id select_type table type possible_keys key key_len ref rows Extra
|
||||||
1 PRIMARY <derived2> system NULL NULL NULL NULL 1
|
1 SIMPLE t2 ALL NULL NULL NULL NULL 1
|
||||||
2 DERIVED t2 ALL NULL NULL NULL NULL 1
|
1 SIMPLE t1 ALL NULL NULL NULL NULL 4 Using where; Using join buffer (flat, BNL join)
|
||||||
2 DERIVED t1 ALL NULL NULL NULL NULL 4 Using where; Using join buffer (flat, BNL join)
|
|
||||||
drop table t1, t2;
|
drop table t1, t2;
|
||||||
create table t1(a int not null, t char(8), index(a));
|
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;
|
SELECT * FROM (SELECT * FROM t1) as b ORDER BY a ASC LIMIT 0,20;
|
||||||
@ -142,9 +140,8 @@ a t
|
|||||||
20 20
|
20 20
|
||||||
explain select count(*) from t1 as tt1, (select * from t1) as tt2;
|
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
|
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 SIMPLE tt1 index NULL a 4 NULL 10000 Using index
|
||||||
1 PRIMARY <derived2> ALL NULL NULL NULL NULL 10000 Using join buffer (flat, BNL join)
|
1 SIMPLE t1 ALL NULL NULL NULL NULL 10000 Using join buffer (flat, BNL join)
|
||||||
2 DERIVED t1 ALL NULL NULL NULL NULL 10000
|
|
||||||
drop table t1;
|
drop table t1;
|
||||||
SELECT * FROM (SELECT (SELECT * FROM (SELECT 1 as a) as a )) as b;
|
SELECT * FROM (SELECT (SELECT * FROM (SELECT 1 as a) as a )) as b;
|
||||||
(SELECT * FROM (SELECT 1 as a) as a )
|
(SELECT * FROM (SELECT 1 as a) as a )
|
||||||
@ -173,30 +170,30 @@ insert into t1 values (NULL, 'a', 1), (NULL, 'b', 2), (NULL, 'c', 3), (NULL, 'd'
|
|||||||
insert into t2 values (1, 100), (1, 101), (1, 102), (2, 100), (2, 103), (2, 104), (3, 101), (3, 102), (3, 105);
|
insert into t2 values (1, 100), (1, 101), (1, 102), (2, 100), (2, 103), (2, 104), (3, 101), (3, 102), (3, 105);
|
||||||
SELECT STRAIGHT_JOIN d.pla_id, m2.mat_id FROM t1 m2 INNER JOIN (SELECT mp.pla_id, MIN(m1.matintnum) AS matintnum FROM t2 mp INNER JOIN t1 m1 ON mp.mat_id=m1.mat_id GROUP BY mp.pla_id) d ON d.matintnum=m2.matintnum;
|
SELECT STRAIGHT_JOIN d.pla_id, m2.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
|
pla_id mat_id
|
||||||
100 1
|
|
||||||
101 1
|
|
||||||
102 1
|
102 1
|
||||||
103 2
|
101 1
|
||||||
|
100 1
|
||||||
104 2
|
104 2
|
||||||
|
103 2
|
||||||
105 3
|
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;
|
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
|
pla_id test
|
||||||
100 1
|
|
||||||
101 1
|
|
||||||
102 1
|
102 1
|
||||||
103 2
|
101 1
|
||||||
|
100 1
|
||||||
104 2
|
104 2
|
||||||
|
103 2
|
||||||
105 3
|
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;
|
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
|
id select_type table type possible_keys key key_len ref rows Extra
|
||||||
1 PRIMARY m2 ALL NULL NULL NULL NULL 9
|
1 PRIMARY m2 ALL NULL NULL NULL NULL 9
|
||||||
1 PRIMARY <derived2> ALL NULL NULL NULL NULL 6 Using where; Using join buffer (flat, BNL join)
|
1 PRIMARY <derived2> ref key0 key0 7 test.m2.matintnum 2
|
||||||
2 DERIVED mp ALL NULL NULL NULL NULL 9 Using temporary; Using filesort
|
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
|
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;
|
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
|
id select_type table type possible_keys key key_len ref rows Extra
|
||||||
1 PRIMARY m2 ALL NULL NULL NULL NULL 9
|
1 PRIMARY m2 ALL NULL NULL NULL NULL 9
|
||||||
1 PRIMARY <derived2> ALL NULL NULL NULL NULL 6 Using where; Using join buffer (flat, BNL join)
|
1 PRIMARY <derived2> ref key0 key0 7 test.m2.matintnum 2
|
||||||
2 DERIVED mp ALL NULL NULL NULL NULL 9 Using temporary; Using filesort
|
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
|
2 DERIVED m1 eq_ref PRIMARY PRIMARY 3 test.mp.mat_id 1
|
||||||
drop table t1,t2;
|
drop table t1,t2;
|
||||||
@ -234,9 +231,8 @@ count(*)
|
|||||||
2
|
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;
|
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
|
id select_type table type possible_keys key key_len ref rows Extra
|
||||||
1 PRIMARY <derived2> ALL NULL NULL NULL NULL 2
|
1 SIMPLE A ALL NULL NULL NULL NULL 2 Using where
|
||||||
1 PRIMARY t1 eq_ref PRIMARY PRIMARY 4 THEMAX.E2 1 Using where
|
1 SIMPLE t1 eq_ref PRIMARY PRIMARY 4 test.A.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
|
3 DEPENDENT SUBQUERY B ALL NULL NULL NULL NULL 2 Using where
|
||||||
drop table t1;
|
drop table t1;
|
||||||
create table t1 (a int);
|
create table t1 (a int);
|
||||||
@ -249,8 +245,8 @@ a a
|
|||||||
2 2
|
2 2
|
||||||
explain select * from ( select * from t1 union select * from t1) a,(select * from t1 union select * from t1) b;
|
explain select * from ( select * from t1 union select * from t1) a,(select * from t1 union select * from t1) b;
|
||||||
id select_type table type possible_keys key key_len ref rows Extra
|
id select_type table type possible_keys key key_len ref rows Extra
|
||||||
1 PRIMARY <derived2> ALL NULL NULL NULL NULL 2
|
1 PRIMARY <derived2> ALL NULL NULL NULL NULL 4
|
||||||
1 PRIMARY <derived4> ALL NULL NULL NULL NULL 2 Using join buffer (flat, BNL join)
|
1 PRIMARY <derived4> ALL NULL NULL NULL NULL 4 Using join buffer (flat, BNL join)
|
||||||
4 DERIVED t1 ALL NULL NULL NULL NULL 2
|
4 DERIVED t1 ALL NULL NULL NULL NULL 2
|
||||||
5 UNION 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
|
NULL UNION RESULT <union4,5> ALL NULL NULL NULL NULL NULL
|
||||||
@ -315,7 +311,7 @@ a 7.0000
|
|||||||
b 3.5000
|
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;
|
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
|
id select_type table type possible_keys key key_len ref rows Extra
|
||||||
1 PRIMARY <derived2> ALL NULL NULL NULL NULL 3 Using temporary; Using filesort
|
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 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)
|
2 DERIVED y ALL NULL NULL NULL NULL 17 Using where; Using join buffer (flat, BNL join)
|
||||||
drop table t1;
|
drop table t1;
|
||||||
@ -326,8 +322,7 @@ 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
|
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;
|
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
|
id select_type table type possible_keys key key_len ref rows Extra
|
||||||
1 PRIMARY <derived2> system NULL NULL NULL NULL 1
|
1 SIMPLE t2 index PRIMARY PRIMARY 4 NULL 2 Using where; Using index
|
||||||
2 DERIVED t2 index PRIMARY PRIMARY 4 NULL 2 Using where; Using index
|
|
||||||
drop table t2;
|
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_`));
|
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, now(), 10),(128, 'rozn', 1, now(), 10);
|
insert into t1 values (128, 'rozn', 2, now(), 10),(128, 'rozn', 1, now(), 10);
|
||||||
|
@ -44,13 +44,13 @@ SELECT (SELECT a) as a;
|
|||||||
ERROR 42S22: Reference 'a' not supported (forward reference in item list)
|
ERROR 42S22: Reference 'a' not supported (forward reference in item list)
|
||||||
EXPLAIN EXTENDED SELECT 1 FROM (SELECT 1 as a) as b HAVING (SELECT a)=1;
|
EXPLAIN EXTENDED SELECT 1 FROM (SELECT 1 as a) as b HAVING (SELECT a)=1;
|
||||||
id select_type table type possible_keys key key_len ref rows filtered Extra
|
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 <derived2> ALL NULL NULL NULL NULL 2 100.00
|
||||||
3 DEPENDENT SUBQUERY NULL NULL NULL NULL NULL NULL NULL NULL No tables used
|
3 DEPENDENT SUBQUERY NULL NULL NULL NULL NULL NULL NULL NULL No tables used
|
||||||
2 DERIVED NULL NULL NULL NULL NULL NULL NULL NULL No tables used
|
2 DERIVED NULL NULL NULL NULL NULL NULL NULL NULL No tables used
|
||||||
Warnings:
|
Warnings:
|
||||||
Note 1276 Field or reference 'b.a' of SELECT #3 was resolved in SELECT #1
|
Note 1276 Field or reference 'b.a' of SELECT #3 was resolved in SELECT #1
|
||||||
Note 1276 Field or reference 'b.a' of SELECT #3 was resolved in SELECT #1
|
Note 1276 Field or reference 'b.a' of SELECT #3 was resolved in SELECT #1
|
||||||
Note 1003 select 1 AS `1` from (select 1 AS `a`) `b` having (<expr_cache><1>((select 1)) = 1)
|
Note 1003 select 1 AS `1` from (select 1 AS `a`) `b` having (<expr_cache><`b`.`a`>((select `b`.`a`)) = 1)
|
||||||
SELECT 1 FROM (SELECT 1 as a) as b HAVING (SELECT a)=1;
|
SELECT 1 FROM (SELECT 1 as a) as b HAVING (SELECT a)=1;
|
||||||
1
|
1
|
||||||
1
|
1
|
||||||
@ -199,11 +199,10 @@ select (select t3.a from t3 where a<8 order by 1 desc limit 1), a from
|
|||||||
explain extended select (select t3.a from t3 where a<8 order by 1 desc limit 1), a from
|
explain extended select (select t3.a from t3 where a<8 order by 1 desc limit 1), a from
|
||||||
(select * from t2 where a>1) as tt;
|
(select * from t2 where a>1) as tt;
|
||||||
id select_type table type possible_keys key key_len ref rows filtered Extra
|
id select_type table type possible_keys key key_len ref rows filtered Extra
|
||||||
1 PRIMARY <derived3> system NULL NULL NULL NULL 1 100.00
|
1 PRIMARY t2 ALL NULL NULL NULL NULL 2 100.00 Using where
|
||||||
3 DERIVED t2 ALL NULL NULL NULL NULL 2 100.00 Using where
|
|
||||||
2 SUBQUERY t3 ALL NULL NULL NULL NULL 3 100.00 Using where; Using filesort
|
2 SUBQUERY t3 ALL NULL NULL NULL NULL 3 100.00 Using where; Using filesort
|
||||||
Warnings:
|
Warnings:
|
||||||
Note 1003 select (select `test`.`t3`.`a` from `test`.`t3` where (`test`.`t3`.`a` < 8) order by 1 desc limit 1) AS `(select t3.a from t3 where a<8 order by 1 desc limit 1)`,2 AS `a` from (select `test`.`t2`.`a` AS `a`,`test`.`t2`.`b` AS `b` from `test`.`t2` where (`test`.`t2`.`a` > 1)) `tt`
|
Note 1003 select (select `test`.`t3`.`a` from `test`.`t3` where (`test`.`t3`.`a` < 8) order by 1 desc limit 1) AS `(select t3.a from t3 where a<8 order by 1 desc limit 1)`,`test`.`t2`.`a` AS `a` from `test`.`t2` where (`test`.`t2`.`a` > 1)
|
||||||
select * from t1 where t1.a=(select t2.a from t2 where t2.b=(select max(a) from t3) order by 1 desc limit 1);
|
select * from t1 where t1.a=(select t2.a from t2 where t2.b=(select max(a) from t3) order by 1 desc limit 1);
|
||||||
a
|
a
|
||||||
2
|
2
|
||||||
@ -363,9 +362,9 @@ INSERT INTO t8 (pseudo,email) VALUES ('2joce1','2test1');
|
|||||||
EXPLAIN EXTENDED SELECT pseudo,(SELECT email FROM t8 WHERE pseudo=(SELECT pseudo FROM t8 WHERE pseudo='joce')) FROM t8 WHERE pseudo=(SELECT pseudo FROM t8 WHERE pseudo='joce');
|
EXPLAIN EXTENDED SELECT pseudo,(SELECT email FROM t8 WHERE pseudo=(SELECT pseudo FROM t8 WHERE pseudo='joce')) FROM t8 WHERE pseudo=(SELECT pseudo FROM t8 WHERE pseudo='joce');
|
||||||
id select_type table type possible_keys key key_len ref rows filtered Extra
|
id select_type table type possible_keys key key_len ref rows filtered Extra
|
||||||
1 PRIMARY t8 const PRIMARY PRIMARY 37 const 1 100.00 Using index
|
1 PRIMARY t8 const PRIMARY PRIMARY 37 const 1 100.00 Using index
|
||||||
4 SUBQUERY t8 const PRIMARY PRIMARY 37 1 100.00 Using index
|
4 SUBQUERY t8 const PRIMARY PRIMARY 37 const 1 100.00 Using index
|
||||||
2 SUBQUERY t8 const PRIMARY PRIMARY 37 const 1 100.00
|
2 SUBQUERY t8 const PRIMARY PRIMARY 37 const 1 100.00
|
||||||
3 SUBQUERY t8 const PRIMARY PRIMARY 37 1 100.00 Using index
|
3 SUBQUERY t8 const PRIMARY PRIMARY 37 const 1 100.00 Using index
|
||||||
Warnings:
|
Warnings:
|
||||||
Note 1003 select 'joce' AS `pseudo`,(select 'test' from `test`.`t8` where ('joce' = (select 'joce' from `test`.`t8` where 1))) AS `(SELECT email FROM t8 WHERE pseudo=(SELECT pseudo FROM t8 WHERE pseudo='joce'))` from `test`.`t8` where ('joce' = (select 'joce' from `test`.`t8` where 1))
|
Note 1003 select 'joce' AS `pseudo`,(select 'test' from `test`.`t8` where ('joce' = (select 'joce' from `test`.`t8` where 1))) AS `(SELECT email FROM t8 WHERE pseudo=(SELECT pseudo FROM t8 WHERE pseudo='joce'))` from `test`.`t8` where ('joce' = (select 'joce' from `test`.`t8` where 1))
|
||||||
SELECT pseudo FROM t8 WHERE pseudo=(SELECT pseudo,email FROM
|
SELECT pseudo FROM t8 WHERE pseudo=(SELECT pseudo,email FROM
|
||||||
|
@ -110,7 +110,7 @@ show create view mysqltest.v1;
|
|||||||
ERROR 42000: SHOW VIEW command denied to user 'mysqltest_1'@'localhost' for table 'v1'
|
ERROR 42000: SHOW VIEW command denied to user 'mysqltest_1'@'localhost' for table 'v1'
|
||||||
explain select c from mysqltest.v2;
|
explain select c from mysqltest.v2;
|
||||||
id select_type table type possible_keys key key_len ref rows Extra
|
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 <derived2> ALL NULL NULL NULL NULL 2
|
||||||
2 DERIVED t1 ALL NULL NULL NULL NULL 0
|
2 DERIVED t1 ALL NULL NULL NULL NULL 0
|
||||||
show create view mysqltest.v2;
|
show create view mysqltest.v2;
|
||||||
ERROR 42000: SHOW VIEW command denied to user 'mysqltest_1'@'localhost' for table 'v2'
|
ERROR 42000: SHOW VIEW command denied to user 'mysqltest_1'@'localhost' for table 'v2'
|
||||||
@ -131,7 +131,7 @@ View Create View character_set_client collation_connection
|
|||||||
v1 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `mysqltest`.`v1` AS select (`mysqltest`.`t1`.`a` + 1) AS `c`,(`mysqltest`.`t1`.`b` + 1) AS `d` from `mysqltest`.`t1` latin1 latin1_swedish_ci
|
v1 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `mysqltest`.`v1` AS select (`mysqltest`.`t1`.`a` + 1) AS `c`,(`mysqltest`.`t1`.`b` + 1) AS `d` from `mysqltest`.`t1` latin1 latin1_swedish_ci
|
||||||
explain select c from mysqltest.v2;
|
explain select c from mysqltest.v2;
|
||||||
id select_type table type possible_keys key key_len ref rows Extra
|
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 <derived2> ALL NULL NULL NULL NULL 2
|
||||||
2 DERIVED t1 ALL NULL NULL NULL NULL 0
|
2 DERIVED t1 ALL NULL NULL NULL NULL 0
|
||||||
show create view mysqltest.v2;
|
show create view mysqltest.v2;
|
||||||
View Create View character_set_client collation_connection
|
View Create View character_set_client collation_connection
|
||||||
@ -144,7 +144,7 @@ View Create View character_set_client collation_connection
|
|||||||
v3 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `mysqltest`.`v3` AS select (`mysqltest`.`t2`.`a` + 1) AS `c`,(`mysqltest`.`t2`.`b` + 1) AS `d` from `mysqltest`.`t2` latin1 latin1_swedish_ci
|
v3 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `mysqltest`.`v3` AS select (`mysqltest`.`t2`.`a` + 1) AS `c`,(`mysqltest`.`t2`.`b` + 1) AS `d` from `mysqltest`.`t2` latin1 latin1_swedish_ci
|
||||||
explain select c from mysqltest.v4;
|
explain select c from mysqltest.v4;
|
||||||
id select_type table type possible_keys key key_len ref rows Extra
|
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 <derived2> ALL NULL NULL NULL NULL 2
|
||||||
2 DERIVED t2 ALL NULL NULL NULL NULL 0
|
2 DERIVED t2 ALL NULL NULL NULL NULL 0
|
||||||
show create view mysqltest.v4;
|
show create view mysqltest.v4;
|
||||||
View Create View character_set_client collation_connection
|
View Create View character_set_client collation_connection
|
||||||
|
@ -98,8 +98,7 @@ a b c
|
|||||||
NULL NULL NULL
|
NULL NULL NULL
|
||||||
explain select * from (select a,b,c from t1) as t11;
|
explain select * from (select a,b,c from t1) as t11;
|
||||||
id select_type table type possible_keys key key_len ref rows Extra
|
id select_type table type possible_keys key key_len ref rows Extra
|
||||||
1 PRIMARY <derived2> ALL NULL NULL NULL NULL 5
|
1 SIMPLE t1 ALL NULL NULL NULL NULL 5
|
||||||
2 DERIVED t1 ALL NULL NULL NULL NULL 5
|
|
||||||
###
|
###
|
||||||
### Using aggregate functions with/without DISTINCT
|
### Using aggregate functions with/without DISTINCT
|
||||||
###
|
###
|
||||||
|
@ -98,8 +98,7 @@ a b c
|
|||||||
NULL NULL NULL
|
NULL NULL NULL
|
||||||
explain select * from (select a,b,c from t1) as t11;
|
explain select * from (select a,b,c from t1) as t11;
|
||||||
id select_type table type possible_keys key key_len ref rows Extra
|
id select_type table type possible_keys key key_len ref rows Extra
|
||||||
1 PRIMARY <derived2> ALL NULL NULL NULL NULL 5
|
1 SIMPLE t1 ALL NULL NULL NULL NULL 5
|
||||||
2 DERIVED t1 ALL NULL NULL NULL NULL 5
|
|
||||||
###
|
###
|
||||||
### Using aggregate functions with/without DISTINCT
|
### Using aggregate functions with/without DISTINCT
|
||||||
###
|
###
|
||||||
|
@ -63,7 +63,7 @@ b
|
|||||||
-3
|
-3
|
||||||
explain select * from v1;
|
explain select * from v1;
|
||||||
id select_type table type possible_keys key key_len ref rows Extra
|
id select_type table type possible_keys key key_len ref rows Extra
|
||||||
1 PRIMARY <derived2> ALL NULL NULL NULL NULL 3
|
1 PRIMARY <derived2> ALL NULL NULL NULL NULL 6
|
||||||
2 DERIVED t1 ALL NULL NULL NULL NULL 6 Using temporary
|
2 DERIVED t1 ALL NULL NULL NULL NULL 6 Using temporary
|
||||||
select * from t1;
|
select * from t1;
|
||||||
a b c
|
a b c
|
||||||
@ -82,7 +82,7 @@ c
|
|||||||
-3
|
-3
|
||||||
explain select * from v1;
|
explain select * from v1;
|
||||||
id select_type table type possible_keys key key_len ref rows Extra
|
id select_type table type possible_keys key key_len ref rows Extra
|
||||||
1 PRIMARY <derived2> ALL NULL NULL NULL NULL 3
|
1 PRIMARY <derived2> ALL NULL NULL NULL NULL 6
|
||||||
2 DERIVED t1 ALL NULL NULL NULL NULL 6 Using temporary
|
2 DERIVED t1 ALL NULL NULL NULL NULL 6 Using temporary
|
||||||
select * from t1;
|
select * from t1;
|
||||||
a b c
|
a b c
|
||||||
@ -107,7 +107,7 @@ MariaDB-5.3: the following EXPLAIN produces incorrect #rows for table t1.
|
|||||||
MariaDB-5.3: this is expected to go away when FROM subquery optimizations are pushed
|
MariaDB-5.3: this is expected to go away when FROM subquery optimizations are pushed
|
||||||
explain select * from v1;
|
explain select * from v1;
|
||||||
id select_type table type possible_keys key key_len ref rows Extra
|
id select_type table type possible_keys key key_len ref rows Extra
|
||||||
1 PRIMARY <derived2> ALL NULL NULL NULL NULL 2
|
1 PRIMARY <derived2> ALL NULL NULL NULL NULL 4
|
||||||
2 DERIVED t1 ALL NULL NULL NULL NULL 4 Using filesort
|
2 DERIVED t1 ALL NULL NULL NULL NULL 4 Using filesort
|
||||||
drop view v1;
|
drop view v1;
|
||||||
create view v1 as select c+1 from t1 order by 1 desc limit 2;
|
create view v1 as select c+1 from t1 order by 1 desc limit 2;
|
||||||
@ -119,7 +119,7 @@ MariaDB-5.3: the following EXPLAIN produces incorrect #rows for table t1.
|
|||||||
MariaDB-5.3: this is expected to go away when FROM subquery optimizations are pushed
|
MariaDB-5.3: this is expected to go away when FROM subquery optimizations are pushed
|
||||||
explain select * from v1;
|
explain select * from v1;
|
||||||
id select_type table type possible_keys key key_len ref rows Extra
|
id select_type table type possible_keys key key_len ref rows Extra
|
||||||
1 PRIMARY <derived2> ALL NULL NULL NULL NULL 2
|
1 PRIMARY <derived2> ALL NULL NULL NULL NULL 4
|
||||||
2 DERIVED t1 ALL NULL NULL NULL NULL 4 Using filesort
|
2 DERIVED t1 ALL NULL NULL NULL NULL 4 Using filesort
|
||||||
drop view v1;
|
drop view v1;
|
||||||
drop table t1;
|
drop table t1;
|
||||||
|
@ -63,7 +63,7 @@ b
|
|||||||
-3
|
-3
|
||||||
explain select * from v1;
|
explain select * from v1;
|
||||||
id select_type table type possible_keys key key_len ref rows Extra
|
id select_type table type possible_keys key key_len ref rows Extra
|
||||||
1 PRIMARY <derived2> ALL NULL NULL NULL NULL 3
|
1 PRIMARY <derived2> ALL NULL NULL NULL NULL 6
|
||||||
2 DERIVED t1 ALL NULL NULL NULL NULL 6 Using temporary
|
2 DERIVED t1 ALL NULL NULL NULL NULL 6 Using temporary
|
||||||
select * from t1;
|
select * from t1;
|
||||||
a b c
|
a b c
|
||||||
@ -82,7 +82,7 @@ c
|
|||||||
-3
|
-3
|
||||||
explain select * from v1;
|
explain select * from v1;
|
||||||
id select_type table type possible_keys key key_len ref rows Extra
|
id select_type table type possible_keys key key_len ref rows Extra
|
||||||
1 PRIMARY <derived2> ALL NULL NULL NULL NULL 3
|
1 PRIMARY <derived2> ALL NULL NULL NULL NULL 6
|
||||||
2 DERIVED t1 ALL NULL NULL NULL NULL 6 Using temporary
|
2 DERIVED t1 ALL NULL NULL NULL NULL 6 Using temporary
|
||||||
select * from t1;
|
select * from t1;
|
||||||
a b c
|
a b c
|
||||||
@ -107,7 +107,7 @@ MariaDB-5.3: the following EXPLAIN produces incorrect #rows for table t1.
|
|||||||
MariaDB-5.3: this is expected to go away when FROM subquery optimizations are pushed
|
MariaDB-5.3: this is expected to go away when FROM subquery optimizations are pushed
|
||||||
explain select * from v1;
|
explain select * from v1;
|
||||||
id select_type table type possible_keys key key_len ref rows Extra
|
id select_type table type possible_keys key key_len ref rows Extra
|
||||||
1 PRIMARY <derived2> ALL NULL NULL NULL NULL 2
|
1 PRIMARY <derived2> ALL NULL NULL NULL NULL 4
|
||||||
2 DERIVED t1 ALL NULL NULL NULL NULL 4 Using filesort
|
2 DERIVED t1 ALL NULL NULL NULL NULL 4 Using filesort
|
||||||
drop view v1;
|
drop view v1;
|
||||||
create view v1 as select c+1 from t1 order by 1 desc limit 2;
|
create view v1 as select c+1 from t1 order by 1 desc limit 2;
|
||||||
@ -119,7 +119,7 @@ MariaDB-5.3: the following EXPLAIN produces incorrect #rows for table t1.
|
|||||||
MariaDB-5.3: this is expected to go away when FROM subquery optimizations are pushed
|
MariaDB-5.3: this is expected to go away when FROM subquery optimizations are pushed
|
||||||
explain select * from v1;
|
explain select * from v1;
|
||||||
id select_type table type possible_keys key key_len ref rows Extra
|
id select_type table type possible_keys key key_len ref rows Extra
|
||||||
1 PRIMARY <derived2> ALL NULL NULL NULL NULL 2
|
1 PRIMARY <derived2> ALL NULL NULL NULL NULL 4
|
||||||
2 DERIVED t1 ALL NULL NULL NULL NULL 4 Using filesort
|
2 DERIVED t1 ALL NULL NULL NULL NULL 4 Using filesort
|
||||||
drop view v1;
|
drop view v1;
|
||||||
drop table t1;
|
drop table t1;
|
||||||
|
217
mysql-test/t/derived_view.test
Normal file
217
mysql-test/t/derived_view.test
Normal file
@ -0,0 +1,217 @@
|
|||||||
|
--disable_warnings
|
||||||
|
drop table if exists t1,t2;
|
||||||
|
drop view if exists v1,v2,v3,v4;
|
||||||
|
--enable_warnings
|
||||||
|
create table t1(f1 int, f11 int);
|
||||||
|
create table t2(f2 int, f22 int);
|
||||||
|
insert into t1 values(1,1),(2,2),(3,3),(5,5),(9,9),(7,7);
|
||||||
|
insert into t1 values(17,17),(13,13),(11,11),(15,15),(19,19);
|
||||||
|
insert into t2 values(1,1),(3,3),(2,2),(4,4),(8,8),(6,6);
|
||||||
|
insert into t2 values(12,12),(14,14),(10,10),(18,18),(16,16);
|
||||||
|
|
||||||
|
--echo Tests:
|
||||||
|
|
||||||
|
--echo for merged derived tables
|
||||||
|
--echo explain for simple derived
|
||||||
|
explain select * from (select * from t1) tt;
|
||||||
|
select * from (select * from t1) tt;
|
||||||
|
--echo explain for multitable derived
|
||||||
|
explain extended select * from (select * from t1 join t2 on f1=f2) tt;
|
||||||
|
select * from (select * from t1 join t2 on f1=f2) tt;
|
||||||
|
--echo explain for derived with where
|
||||||
|
explain extended
|
||||||
|
select * from (select * from t1 where f1 in (2,3)) tt where f11=2;
|
||||||
|
select * from (select * from t1 where f1 in (2,3)) tt where f11=2;
|
||||||
|
--echo join of derived
|
||||||
|
explain extended
|
||||||
|
select * from (select * from t1 where f1 in (2,3)) tt join
|
||||||
|
(select * from t1 where f1 in (1,2)) aa on tt.f1=aa.f1;
|
||||||
|
select * from (select * from t1 where f1 in (2,3)) tt join
|
||||||
|
(select * from t1 where f1 in (1,2)) aa on tt.f1=aa.f1;
|
||||||
|
|
||||||
|
flush status;
|
||||||
|
explain extended
|
||||||
|
select * from (select * from t1 where f1 in (2,3)) tt where f11=2;
|
||||||
|
show status like 'Handler_read%';
|
||||||
|
flush status;
|
||||||
|
select * from (select * from t1 where f1 in (2,3)) tt where f11=2;
|
||||||
|
show status like 'Handler_read%';
|
||||||
|
|
||||||
|
--echo for merged views
|
||||||
|
create view v1 as select * from t1;
|
||||||
|
create view v2 as select * from t1 join t2 on f1=f2;
|
||||||
|
create view v3 as select * from t1 where f1 in (2,3);
|
||||||
|
create view v4 as select * from t2 where f2 in (2,3);
|
||||||
|
--echo explain for simple views
|
||||||
|
explain extended select * from v1;
|
||||||
|
select * from v1;
|
||||||
|
--echo explain for multitable views
|
||||||
|
explain extended select * from v2;
|
||||||
|
select * from v2;
|
||||||
|
--echo explain for views with where
|
||||||
|
explain extended select * from v3 where f11 in (1,3);
|
||||||
|
select * from v3 where f11 in (1,3);
|
||||||
|
--echo explain for joined views
|
||||||
|
explain extended
|
||||||
|
select * from v3 join v4 on f1=f2;
|
||||||
|
select * from v3 join v4 on f1=f2;
|
||||||
|
|
||||||
|
flush status;
|
||||||
|
explain extended select * from v4 where f2 in (1,3);
|
||||||
|
show status like 'Handler_read%';
|
||||||
|
flush status;
|
||||||
|
select * from v4 where f2 in (1,3);
|
||||||
|
show status like 'Handler_read%';
|
||||||
|
|
||||||
|
--echo for materialized derived tables
|
||||||
|
--echo explain for simple derived
|
||||||
|
explain extended select * from (select * from t1 group by f1) tt;
|
||||||
|
select * from (select * from t1 having f1=f1) tt;
|
||||||
|
--echo explain showing created indexes
|
||||||
|
explain extended
|
||||||
|
select * from t1 join (select * from t2 group by f2) tt on f1=f2;
|
||||||
|
select * from t1 join (select * from t2 group by f2) tt on f1=f2;
|
||||||
|
--echo explain showing late materialization
|
||||||
|
flush status;
|
||||||
|
explain select * from t1 join (select * from t2 group by f2) tt on f1=f2;
|
||||||
|
show status like 'Handler_read%';
|
||||||
|
flush status;
|
||||||
|
select * from t1 join (select * from t2 group by f2) tt on f1=f2;
|
||||||
|
show status like 'Handler_read%';
|
||||||
|
|
||||||
|
--echo for materialized views
|
||||||
|
drop view v1,v2,v3;
|
||||||
|
create view v1 as select * from t1 group by f1;
|
||||||
|
create view v2 as select * from t2 group by f2;
|
||||||
|
create view v3 as select t1.f1,t1.f11 from t1 join t1 as t11 where t1.f1=t11.f1
|
||||||
|
having t1.f1<100;
|
||||||
|
--echo explain for simple derived
|
||||||
|
explain extended select * from v1;
|
||||||
|
select * from v1;
|
||||||
|
--echo explain showing created indexes
|
||||||
|
explain extended select * from t1 join v2 on f1=f2;
|
||||||
|
select * from t1 join v2 on f1=f2;
|
||||||
|
explain extended
|
||||||
|
select * from t1,v3 as v31,v3 where t1.f1=v31.f1 and t1.f1=v3.f1;
|
||||||
|
flush status;
|
||||||
|
select * from t1,v3 as v31,v3 where t1.f1=v31.f1 and t1.f1=v3.f1;
|
||||||
|
show status like 'Handler_read%';
|
||||||
|
--echo explain showing late materialization
|
||||||
|
flush status;
|
||||||
|
explain select * from t1 join v2 on f1=f2;
|
||||||
|
show status like 'Handler_read%';
|
||||||
|
flush status;
|
||||||
|
select * from t1 join v2 on f1=f2;
|
||||||
|
show status like 'Handler_read%';
|
||||||
|
|
||||||
|
explain extended select * from v1 join v4 on f1=f2;
|
||||||
|
select * from v1 join v4 on f1=f2;
|
||||||
|
|
||||||
|
--echo merged derived in merged derived
|
||||||
|
explain extended select * from (select * from
|
||||||
|
(select * from t1 where f1 < 7) tt where f1 > 2) zz;
|
||||||
|
select * from (select * from
|
||||||
|
(select * from t1 where f1 < 7) tt where f1 > 2) zz;
|
||||||
|
|
||||||
|
--echo materialized derived in merged derived
|
||||||
|
explain extended select * from (select * from
|
||||||
|
(select * from t1 where f1 < 7 group by f1) tt where f1 > 2) zz;
|
||||||
|
select * from (select * from
|
||||||
|
(select * from t1 where f1 < 7 group by f1) tt where f1 > 2) zz;
|
||||||
|
|
||||||
|
--echo merged derived in materialized derived
|
||||||
|
explain extended select * from (select * from
|
||||||
|
(select * from t1 where f1 < 7) tt where f1 > 2 group by f1) zz;
|
||||||
|
select * from (select * from
|
||||||
|
(select * from t1 where f1 < 7) tt where f1 > 2 group by f1) zz;
|
||||||
|
|
||||||
|
--echo materialized derived in materialized derived
|
||||||
|
explain extended select * from (select * from
|
||||||
|
(select * from t1 where f1 < 7 group by f1) tt where f1 > 2 group by f1) zz;
|
||||||
|
select * from (select * from
|
||||||
|
(select * from t1 where f1 < 7 group by f1) tt where f1 > 2 group by f1) zz;
|
||||||
|
|
||||||
|
--echo mat in merged derived join mat in merged derived
|
||||||
|
explain extended select * from
|
||||||
|
(select * from (select * from t1 where f1 < 7 group by f1) tt where f1 > 2) x
|
||||||
|
join
|
||||||
|
(select * from (select * from t1 where f1 < 7 group by f1) tt where f1 > 2) z
|
||||||
|
on x.f1 = z.f1;
|
||||||
|
|
||||||
|
flush status;
|
||||||
|
select * from
|
||||||
|
(select * from (select * from t1 where f1 < 7 group by f1) tt where f1 > 2) x
|
||||||
|
join
|
||||||
|
(select * from (select * from t1 where f1 < 7 group by f1) tt where f1 > 2) z
|
||||||
|
on x.f1 = z.f1;
|
||||||
|
show status like 'Handler_read%';
|
||||||
|
flush status;
|
||||||
|
|
||||||
|
--echo merged in merged derived join merged in merged derived
|
||||||
|
explain extended select * from
|
||||||
|
(select * from
|
||||||
|
(select * from t1 where f1 < 7 ) tt where f1 > 2 ) x
|
||||||
|
join
|
||||||
|
(select * from
|
||||||
|
(select * from t1 where f1 < 7 ) tt where f1 > 2 ) z
|
||||||
|
on x.f1 = z.f1;
|
||||||
|
|
||||||
|
select * from
|
||||||
|
(select * from
|
||||||
|
(select * from t1 where f1 < 7 ) tt where f1 > 2 ) x
|
||||||
|
join
|
||||||
|
(select * from
|
||||||
|
(select * from t1 where f1 < 7 ) tt where f1 > 2 ) z
|
||||||
|
on x.f1 = z.f1;
|
||||||
|
|
||||||
|
--echo materialized in materialized derived join
|
||||||
|
--echo materialized in materialized derived
|
||||||
|
explain extended select * from
|
||||||
|
(select * from
|
||||||
|
(select * from t1 where f1 < 7 group by f1) tt where f1 > 2 group by f1) x
|
||||||
|
join
|
||||||
|
(select * from
|
||||||
|
(select * from t1 where f1 < 7 group by f1) tt where f1 > 2 group by f1) z
|
||||||
|
on x.f1 = z.f1;
|
||||||
|
|
||||||
|
select * from
|
||||||
|
(select * from
|
||||||
|
(select * from t1 where f1 < 7 group by f1) tt where f1 > 2 group by f1) x
|
||||||
|
join
|
||||||
|
(select * from
|
||||||
|
(select * from t1 where f1 < 7 group by f1) tt where f1 > 2 group by f1) z
|
||||||
|
on x.f1 = z.f1;
|
||||||
|
|
||||||
|
--echo merged view in materialized derived
|
||||||
|
explain extended
|
||||||
|
select * from (select * from v4 group by 1) tt;
|
||||||
|
select * from (select * from v4 group by 1) tt;
|
||||||
|
|
||||||
|
--echo materialized view in merged derived
|
||||||
|
explain extended
|
||||||
|
select * from ( select * from v1 where f1 < 7) tt;
|
||||||
|
select * from ( select * from v1 where f1 < 7) tt;
|
||||||
|
|
||||||
|
--echo merged view in a merged view in a merged derived
|
||||||
|
create view v6 as select * from v4 where f2 < 7;
|
||||||
|
explain extended select * from (select * from v6) tt;
|
||||||
|
select * from (select * from v6) tt;
|
||||||
|
|
||||||
|
--echo materialized view in a merged view in a materialized derived
|
||||||
|
create view v7 as select * from v1;
|
||||||
|
explain extended select * from (select * from v7 group by 1) tt;
|
||||||
|
select * from (select * from v7 group by 1) tt;
|
||||||
|
|
||||||
|
--echo join of above two
|
||||||
|
explain extended select * from v6 join v7 on f2=f1;
|
||||||
|
select * from v6 join v7 on f2=f1;
|
||||||
|
|
||||||
|
--echo test two keys
|
||||||
|
explain select * from t1 join (select * from t2 group by f2) tt on t1.f1=tt.f2 join t1 xx on tt.f22=xx.f1;
|
||||||
|
select * from t1 join (select * from t2 group by f2) tt on t1.f1=tt.f2 join t1 xx on tt.f22=xx.f1;
|
||||||
|
|
||||||
|
|
||||||
|
--echo TODO: Add test with 64 tables mergeable view to test fall back to
|
||||||
|
--echo materialization on tables > MAX_TABLES merge
|
||||||
|
drop table t1,t2;
|
||||||
|
drop view v1,v2,v3,v4,v6,v7;
|
@ -16,7 +16,9 @@ connect (writer,localhost,root,,);
|
|||||||
DROP TABLE IF EXISTS t1;
|
DROP TABLE IF EXISTS t1;
|
||||||
--enable_warnings
|
--enable_warnings
|
||||||
CREATE TABLE t1( a INT, b INT );
|
CREATE TABLE t1( a INT, b INT );
|
||||||
|
CREATE TABLE t2( a INT, b INT );
|
||||||
INSERT INTO t1 VALUES (1, 1), (2, 2), (3, 3), (4, 4);
|
INSERT INTO t1 VALUES (1, 1), (2, 2), (3, 3), (4, 4);
|
||||||
|
INSERT INTO t2 VALUES (1, 1), (2, 2), (3, 3), (4, 4);
|
||||||
|
|
||||||
--echo # 1. test regular tables
|
--echo # 1. test regular tables
|
||||||
--echo # 1.1. test altering of columns that multiupdate doesn't use
|
--echo # 1.1. test altering of columns that multiupdate doesn't use
|
||||||
@ -28,7 +30,7 @@ while ($i) {
|
|||||||
--dec $i
|
--dec $i
|
||||||
|
|
||||||
--connection writer
|
--connection writer
|
||||||
send UPDATE t1, (SELECT 1 FROM t1 t1i) d SET a = 0 WHERE 1=0;
|
send UPDATE t1, (SELECT 1 FROM t2 t1i) d SET a = 0 WHERE 1=0;
|
||||||
|
|
||||||
--connection locker
|
--connection locker
|
||||||
ALTER TABLE t1 ADD COLUMN (c INT);
|
ALTER TABLE t1 ADD COLUMN (c INT);
|
||||||
@ -41,7 +43,7 @@ while ($i) {
|
|||||||
--echo # 1.1.2. PS mode
|
--echo # 1.1.2. PS mode
|
||||||
|
|
||||||
--connection writer
|
--connection writer
|
||||||
PREPARE stmt FROM 'UPDATE t1, (SELECT 1 FROM t1 t1i) d SET a = 0 WHERE 1=0';
|
PREPARE stmt FROM 'UPDATE t1, (SELECT 1 FROM t2 t1i) d SET a = 0 WHERE 1=0';
|
||||||
|
|
||||||
let $i = 100;
|
let $i = 100;
|
||||||
while ($i) {
|
while ($i) {
|
||||||
@ -75,7 +77,7 @@ while ($i) {
|
|||||||
UPDATE t1 SET a=b;
|
UPDATE t1 SET a=b;
|
||||||
|
|
||||||
--connection writer
|
--connection writer
|
||||||
--send UPDATE t1, (SELECT 1 FROM t1 t1i) d SET a = 0 WHERE 1=0;
|
--send UPDATE t1, (SELECT 1 FROM t2 t1i) d SET a = 0 WHERE 1=0;
|
||||||
|
|
||||||
--connection locker
|
--connection locker
|
||||||
--error 0,ER_CANT_DROP_FIELD_OR_KEY
|
--error 0,ER_CANT_DROP_FIELD_OR_KEY
|
||||||
@ -100,7 +102,7 @@ while ($i) {
|
|||||||
UPDATE t1 SET a=b;
|
UPDATE t1 SET a=b;
|
||||||
|
|
||||||
--connection writer
|
--connection writer
|
||||||
PREPARE stmt FROM 'UPDATE t1, (SELECT 1 FROM t1 t1i) d SET a = 0 WHERE 1=0';
|
PREPARE stmt FROM 'UPDATE t1, (SELECT 1 FROM t2 t1i) d SET a = 0 WHERE 1=0';
|
||||||
--send EXECUTE stmt
|
--send EXECUTE stmt
|
||||||
|
|
||||||
--connection locker
|
--connection locker
|
||||||
@ -210,7 +212,7 @@ while ($i) {
|
|||||||
}
|
}
|
||||||
--enable_query_log
|
--enable_query_log
|
||||||
--connection default
|
--connection default
|
||||||
DROP TABLE t1;
|
DROP TABLE t1,t2;
|
||||||
|
|
||||||
|
|
||||||
# Close connections
|
# Close connections
|
||||||
|
@ -685,6 +685,9 @@ CREATE FUNCTION f1 () RETURNS BLOB RETURN 1;
|
|||||||
CREATE TABLE t1 (f1 DATE);
|
CREATE TABLE t1 (f1 DATE);
|
||||||
INSERT INTO t1 VALUES('2001-01-01');
|
INSERT INTO t1 VALUES('2001-01-01');
|
||||||
UPDATE (SELECT 1 FROM t1 WHERE f1 = (SELECT f1() FROM t1)) x, t1 SET f1 = 1;
|
UPDATE (SELECT 1 FROM t1 WHERE f1 = (SELECT f1() FROM t1)) x, t1 SET f1 = 1;
|
||||||
|
CREATE view v1 as SELECT f1() FROM t1;
|
||||||
|
UPDATE (SELECT 1 FROM t1 WHERE f1 = (select * from v1)) x, t1 SET f1 = 1;
|
||||||
|
DROP VIEW v1;
|
||||||
DROP FUNCTION f1;
|
DROP FUNCTION f1;
|
||||||
DROP TABLE t1;
|
DROP TABLE t1;
|
||||||
|
|
||||||
|
@ -74,8 +74,8 @@ SELECT i FROM t1 LEFT JOIN t2 ON (j) IN (SELECT max(k) FROM t3);
|
|||||||
DROP TABLE t1, t2, t3;
|
DROP TABLE t1, t2, t3;
|
||||||
|
|
||||||
--echo #
|
--echo #
|
||||||
--echo # LPBUG#609121: RQG: wrong result on aggregate + NOT IN + HAVING and
|
--echo # LPBUG#611622/BUG#52344: Subquery materialization: Assertion
|
||||||
--echo # partial_match_table_scan=on
|
--echo # if subquery in on-clause of outer join
|
||||||
--echo #
|
--echo #
|
||||||
|
|
||||||
CREATE TABLE t1 (c1 int);
|
CREATE TABLE t1 (c1 int);
|
||||||
@ -86,7 +86,7 @@ INSERT INTO t2 VALUES (10);
|
|||||||
|
|
||||||
PREPARE st1 FROM "
|
PREPARE st1 FROM "
|
||||||
SELECT *
|
SELECT *
|
||||||
FROM t2 LEFT JOIN (SELECT * FROM t2) t3 ON (8, 4) IN (SELECT c1, c1 FROM t1)";
|
FROM t2 LEFT JOIN t2 t3 ON (8, 4) IN (SELECT c1, c1 FROM t1)";
|
||||||
|
|
||||||
EXECUTE st1;
|
EXECUTE st1;
|
||||||
EXECUTE st1;
|
EXECUTE st1;
|
||||||
|
@ -2782,6 +2782,7 @@ DROP VIEW IF EXISTS v1;
|
|||||||
#
|
#
|
||||||
# Bug#21261 Wrong access rights was required for an insert to a view
|
# Bug#21261 Wrong access rights was required for an insert to a view
|
||||||
#
|
#
|
||||||
|
|
||||||
CREATE DATABASE bug21261DB;
|
CREATE DATABASE bug21261DB;
|
||||||
USE bug21261DB;
|
USE bug21261DB;
|
||||||
connect (root,localhost,root,,bug21261DB);
|
connect (root,localhost,root,,bug21261DB);
|
||||||
|
24
sql/field.cc
24
sql/field.cc
@ -9902,3 +9902,27 @@ void Field::set_datetime_warning(MYSQL_ERROR::enum_warning_level level,
|
|||||||
set_warning(level, code, cuted_increment))
|
set_warning(level, code, cuted_increment))
|
||||||
make_truncated_value_warning(thd, level, str, ts_type, field_name);
|
make_truncated_value_warning(thd, level, str, ts_type, field_name);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
@brief
|
||||||
|
Return possible keys for a field
|
||||||
|
|
||||||
|
@details
|
||||||
|
Return bit map of keys over this field which can be used by the range
|
||||||
|
optimizer. For a field of a generic table such keys are all keys that starts
|
||||||
|
from this field. For a field of a materialized derived table/view such keys
|
||||||
|
are all keys in which this field takes a part. This is less restrictive as
|
||||||
|
keys for a materialized derived table/view are generated on the fly from
|
||||||
|
present fields, thus the case when a field for the beginning of a key is
|
||||||
|
absent is impossible.
|
||||||
|
|
||||||
|
@return map of possible keys
|
||||||
|
*/
|
||||||
|
|
||||||
|
key_map Field::get_possible_keys()
|
||||||
|
{
|
||||||
|
DBUG_ASSERT(table->pos_in_table_list);
|
||||||
|
return (table->pos_in_table_list->is_materialized_derived() ?
|
||||||
|
part_of_key : key_start);
|
||||||
|
}
|
||||||
|
@ -577,6 +577,9 @@ public:
|
|||||||
DBUG_ASSERT(0);
|
DBUG_ASSERT(0);
|
||||||
return GEOM_GEOMETRY;
|
return GEOM_GEOMETRY;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
key_map get_possible_keys();
|
||||||
|
|
||||||
/* Hash value */
|
/* Hash value */
|
||||||
virtual void hash(ulong *nr, ulong *nr2);
|
virtual void hash(ulong *nr, ulong *nr2);
|
||||||
|
|
||||||
|
@ -2609,8 +2609,9 @@ int handler::update_auto_increment()
|
|||||||
void handler::column_bitmaps_signal()
|
void handler::column_bitmaps_signal()
|
||||||
{
|
{
|
||||||
DBUG_ENTER("column_bitmaps_signal");
|
DBUG_ENTER("column_bitmaps_signal");
|
||||||
DBUG_PRINT("info", ("read_set: 0x%lx write_set: 0x%lx", (long) table->read_set,
|
if (table)
|
||||||
(long) table->write_set));
|
DBUG_PRINT("info", ("read_set: 0x%lx write_set: 0x%lx",
|
||||||
|
(long) table->read_set, (long) table->write_set));
|
||||||
DBUG_VOID_RETURN;
|
DBUG_VOID_RETURN;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
121
sql/item.cc
121
sql/item.cc
@ -720,7 +720,7 @@ void Item_ident::cleanup()
|
|||||||
bool Item_ident::remove_dependence_processor(uchar * arg)
|
bool Item_ident::remove_dependence_processor(uchar * arg)
|
||||||
{
|
{
|
||||||
DBUG_ENTER("Item_ident::remove_dependence_processor");
|
DBUG_ENTER("Item_ident::remove_dependence_processor");
|
||||||
if (depended_from == (st_select_lex *) arg)
|
if (get_depended_from() == (st_select_lex *) arg)
|
||||||
depended_from= 0;
|
depended_from= 0;
|
||||||
context= &((st_select_lex *) arg)->context;
|
context= &((st_select_lex *) arg)->context;
|
||||||
DBUG_RETURN(0);
|
DBUG_RETURN(0);
|
||||||
@ -835,6 +835,23 @@ bool Item_field::register_field_in_bitmap(uchar *arg)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
Mark field in write_map
|
||||||
|
|
||||||
|
NOTES
|
||||||
|
This is used by UPDATE to register underlying fields of used view fields.
|
||||||
|
*/
|
||||||
|
|
||||||
|
bool Item_field::register_field_in_write_map(uchar *arg)
|
||||||
|
{
|
||||||
|
TABLE *table= (TABLE *) arg;
|
||||||
|
if (field->table == table || !table)
|
||||||
|
bitmap_set_bit(field->table->write_set, field->field_index);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
bool Item::check_cols(uint c)
|
bool Item::check_cols(uint c)
|
||||||
{
|
{
|
||||||
if (c != 1)
|
if (c != 1)
|
||||||
@ -2394,13 +2411,17 @@ table_map Item_field::used_tables() const
|
|||||||
{
|
{
|
||||||
if (field->table->const_table)
|
if (field->table->const_table)
|
||||||
return 0; // const item
|
return 0; // const item
|
||||||
return (depended_from ? OUTER_REF_TABLE_BIT : field->table->map);
|
return (get_depended_from() ? OUTER_REF_TABLE_BIT : field->table->map);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
table_map Item_field::all_used_tables() const
|
||||||
|
{
|
||||||
|
return (get_depended_from() ? OUTER_REF_TABLE_BIT : field->table->map);
|
||||||
|
}
|
||||||
|
|
||||||
void Item_field::fix_after_pullout(st_select_lex *new_parent, Item **ref)
|
void Item_field::fix_after_pullout(st_select_lex *new_parent, Item **ref)
|
||||||
{
|
{
|
||||||
if (new_parent == depended_from)
|
if (new_parent == get_depended_from())
|
||||||
depended_from= NULL;
|
depended_from= NULL;
|
||||||
Name_resolution_context *ctx= new Name_resolution_context();
|
Name_resolution_context *ctx= new Name_resolution_context();
|
||||||
ctx->outer_context= NULL; // We don't build a complete name resolver
|
ctx->outer_context= NULL; // We don't build a complete name resolver
|
||||||
@ -2649,7 +2670,7 @@ my_decimal *Item_float::val_decimal(my_decimal *decimal_value)
|
|||||||
|
|
||||||
void Item_string::print(String *str, enum_query_type query_type)
|
void Item_string::print(String *str, enum_query_type query_type)
|
||||||
{
|
{
|
||||||
if (query_type == QT_ORDINARY && is_cs_specified())
|
if (query_type != QT_IS && is_cs_specified())
|
||||||
{
|
{
|
||||||
str->append('_');
|
str->append('_');
|
||||||
str->append(collation.collation->csname);
|
str->append(collation.collation->csname);
|
||||||
@ -2657,7 +2678,7 @@ void Item_string::print(String *str, enum_query_type query_type)
|
|||||||
|
|
||||||
str->append('\'');
|
str->append('\'');
|
||||||
|
|
||||||
if (query_type == QT_ORDINARY ||
|
if (query_type != QT_IS ||
|
||||||
my_charset_same(str_value.charset(), system_charset_info))
|
my_charset_same(str_value.charset(), system_charset_info))
|
||||||
{
|
{
|
||||||
str_value.print(str);
|
str_value.print(str);
|
||||||
@ -4155,6 +4176,34 @@ resolve_ref_in_select_and_group(THD *thd, Item_ident *ref, SELECT_LEX *select)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
@brief
|
||||||
|
Whether a table belongs to an outer select.
|
||||||
|
|
||||||
|
@param table table to check
|
||||||
|
@param select current select
|
||||||
|
|
||||||
|
@details
|
||||||
|
Try to find select the table belongs to by ascending the derived tables chain.
|
||||||
|
*/
|
||||||
|
|
||||||
|
static
|
||||||
|
bool is_outer_table(TABLE_LIST *table, SELECT_LEX *select)
|
||||||
|
{
|
||||||
|
DBUG_ASSERT(table->select_lex != select);
|
||||||
|
TABLE_LIST *tl;
|
||||||
|
|
||||||
|
for (tl= select->master_unit()->derived;
|
||||||
|
tl && tl->is_merged_derived();
|
||||||
|
select= tl->select_lex, tl= select->master_unit()->derived)
|
||||||
|
{
|
||||||
|
if (tl->select_lex == table->select_lex)
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Resolve the name of an outer select column reference.
|
Resolve the name of an outer select column reference.
|
||||||
|
|
||||||
@ -4603,7 +4652,8 @@ bool Item_field::fix_fields(THD *thd, Item **reference)
|
|||||||
|
|
||||||
if (!outer_fixed && cached_table && cached_table->select_lex &&
|
if (!outer_fixed && cached_table && cached_table->select_lex &&
|
||||||
context->select_lex &&
|
context->select_lex &&
|
||||||
cached_table->select_lex != context->select_lex)
|
cached_table->select_lex != context->select_lex &&
|
||||||
|
is_outer_table(cached_table, context->select_lex))
|
||||||
{
|
{
|
||||||
int ret;
|
int ret;
|
||||||
if ((ret= fix_outer_field(thd, &from_field, reference)) < 0)
|
if ((ret= fix_outer_field(thd, &from_field, reference)) < 0)
|
||||||
@ -6066,8 +6116,9 @@ public:
|
|||||||
st_select_lex *sel;
|
st_select_lex *sel;
|
||||||
for (sel= current_select; sel; sel= sel->outer_select())
|
for (sel= current_select; sel; sel= sel->outer_select())
|
||||||
{
|
{
|
||||||
|
List_iterator<TABLE_LIST> li(sel->leaf_tables);
|
||||||
TABLE_LIST *tbl;
|
TABLE_LIST *tbl;
|
||||||
for (tbl= sel->leaf_tables; tbl; tbl= tbl->next_leaf)
|
while ((tbl= li++))
|
||||||
{
|
{
|
||||||
if (tbl->table == item->field->table)
|
if (tbl->table == item->field->table)
|
||||||
{
|
{
|
||||||
@ -6362,12 +6413,13 @@ bool Item_ref::fix_fields(THD *thd, Item **reference)
|
|||||||
last_checked_context->select_lex->nest_level);
|
last_checked_context->select_lex->nest_level);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else if (ref_type() != VIEW_REF)
|
||||||
{
|
{
|
||||||
if (depended_from && reference)
|
if (depended_from && reference)
|
||||||
{
|
{
|
||||||
DBUG_ASSERT(context->select_lex != depended_from);
|
DBUG_ASSERT(context->select_lex != get_depended_from());
|
||||||
context->select_lex->register_dependency_item(depended_from, reference);
|
context->select_lex->register_dependency_item(get_depended_from(),
|
||||||
|
reference);
|
||||||
}
|
}
|
||||||
/*
|
/*
|
||||||
It could be that we're referring to something that's in ancestor selects.
|
It could be that we're referring to something that's in ancestor selects.
|
||||||
@ -7333,7 +7385,7 @@ bool Item_outer_ref::fix_fields(THD *thd, Item **reference)
|
|||||||
|
|
||||||
void Item_outer_ref::fix_after_pullout(st_select_lex *new_parent, Item **ref)
|
void Item_outer_ref::fix_after_pullout(st_select_lex *new_parent, Item **ref)
|
||||||
{
|
{
|
||||||
if (depended_from == new_parent)
|
if (get_depended_from() == new_parent)
|
||||||
{
|
{
|
||||||
*ref= outer_ref;
|
*ref= outer_ref;
|
||||||
(*ref)->fix_after_pullout(new_parent, ref);
|
(*ref)->fix_after_pullout(new_parent, ref);
|
||||||
@ -7343,7 +7395,7 @@ void Item_outer_ref::fix_after_pullout(st_select_lex *new_parent, Item **ref)
|
|||||||
void Item_ref::fix_after_pullout(st_select_lex *new_parent, Item **refptr)
|
void Item_ref::fix_after_pullout(st_select_lex *new_parent, Item **refptr)
|
||||||
{
|
{
|
||||||
(*ref)->fix_after_pullout(new_parent, ref);
|
(*ref)->fix_after_pullout(new_parent, ref);
|
||||||
if (depended_from == new_parent)
|
if (get_depended_from() == new_parent)
|
||||||
depended_from= NULL;
|
depended_from= NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -8655,6 +8707,8 @@ Item_result Item_type_holder::result_type() const
|
|||||||
|
|
||||||
enum_field_types Item_type_holder::get_real_type(Item *item)
|
enum_field_types Item_type_holder::get_real_type(Item *item)
|
||||||
{
|
{
|
||||||
|
if (item->type() == REF_ITEM)
|
||||||
|
item= item->real_item();
|
||||||
switch(item->type())
|
switch(item->type())
|
||||||
{
|
{
|
||||||
case FIELD_ITEM:
|
case FIELD_ITEM:
|
||||||
@ -9030,6 +9084,49 @@ void view_error_processor(THD *thd, void *data)
|
|||||||
((TABLE_LIST *)data)->hide_view_error(thd);
|
((TABLE_LIST *)data)->hide_view_error(thd);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
st_select_lex *Item_ident::get_depended_from() const
|
||||||
|
{
|
||||||
|
st_select_lex *dep;
|
||||||
|
if ((dep= depended_from))
|
||||||
|
for ( ; dep->merged_into; dep= dep->merged_into) ;
|
||||||
|
return dep;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
table_map Item_ref::used_tables() const
|
||||||
|
{
|
||||||
|
return get_depended_from() ? OUTER_REF_TABLE_BIT : (*ref)->used_tables();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Item_ref::update_used_tables()
|
||||||
|
{
|
||||||
|
if (!get_depended_from())
|
||||||
|
(*ref)->update_used_tables();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
table_map Item_direct_view_ref::used_tables() const
|
||||||
|
{
|
||||||
|
return get_depended_from() ?
|
||||||
|
OUTER_REF_TABLE_BIT :
|
||||||
|
(view->merged ? (*ref)->used_tables() : view->table->map);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
we add RAND_TABLE_BIT to prevent moving this item from HAVING to WHERE
|
||||||
|
*/
|
||||||
|
table_map Item_ref_null_helper::used_tables() const
|
||||||
|
{
|
||||||
|
return (get_depended_from() ?
|
||||||
|
OUTER_REF_TABLE_BIT :
|
||||||
|
(*ref)->used_tables() | RAND_TABLE_BIT);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*****************************************************************************
|
/*****************************************************************************
|
||||||
** Instantiate templates
|
** Instantiate templates
|
||||||
*****************************************************************************/
|
*****************************************************************************/
|
||||||
|
70
sql/item.h
70
sql/item.h
@ -851,6 +851,7 @@ public:
|
|||||||
class Field_enumerator)
|
class Field_enumerator)
|
||||||
*/
|
*/
|
||||||
virtual table_map used_tables() const { return (table_map) 0L; }
|
virtual table_map used_tables() const { return (table_map) 0L; }
|
||||||
|
virtual table_map all_used_tables() const { return used_tables(); }
|
||||||
/*
|
/*
|
||||||
Return table map of tables that can't be NULL tables (tables that are
|
Return table map of tables that can't be NULL tables (tables that are
|
||||||
used in a context where if they would contain a NULL row generated
|
used in a context where if they would contain a NULL row generated
|
||||||
@ -1009,10 +1010,13 @@ public:
|
|||||||
virtual bool reset_query_id_processor(uchar *query_id_arg) { return 0; }
|
virtual bool reset_query_id_processor(uchar *query_id_arg) { return 0; }
|
||||||
virtual bool is_expensive_processor(uchar *arg) { return 0; }
|
virtual bool is_expensive_processor(uchar *arg) { return 0; }
|
||||||
virtual bool register_field_in_read_map(uchar *arg) { return 0; }
|
virtual bool register_field_in_read_map(uchar *arg) { return 0; }
|
||||||
|
virtual bool register_field_in_write_map(uchar *arg) { return 0; }
|
||||||
virtual bool enumerate_field_refs_processor(uchar *arg) { return 0; }
|
virtual bool enumerate_field_refs_processor(uchar *arg) { return 0; }
|
||||||
virtual bool mark_as_eliminated_processor(uchar *arg) { return 0; }
|
virtual bool mark_as_eliminated_processor(uchar *arg) { return 0; }
|
||||||
virtual bool eliminate_subselect_processor(uchar *arg) { return 0; }
|
virtual bool eliminate_subselect_processor(uchar *arg) { return 0; }
|
||||||
virtual bool set_fake_select_as_master_processor(uchar *arg) { return 0; }
|
virtual bool set_fake_select_as_master_processor(uchar *arg) { return 0; }
|
||||||
|
virtual bool view_used_tables_processor(uchar *arg) { return 0; }
|
||||||
|
virtual bool eval_not_null_tables(uchar *opt_arg) { return 0; }
|
||||||
|
|
||||||
/* To call bool function for all arguments */
|
/* To call bool function for all arguments */
|
||||||
struct bool_func_call_args
|
struct bool_func_call_args
|
||||||
@ -1028,6 +1032,7 @@ public:
|
|||||||
(this->*(info->bool_function))();
|
(this->*(info->bool_function))();
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
The next function differs from the previous one that a bitmap to be updated
|
The next function differs from the previous one that a bitmap to be updated
|
||||||
is passed as uchar *arg.
|
is passed as uchar *arg.
|
||||||
@ -1241,8 +1246,8 @@ public:
|
|||||||
{ return Field::GEOM_GEOMETRY; };
|
{ return Field::GEOM_GEOMETRY; };
|
||||||
String *check_well_formed_result(String *str, bool send_error= 0);
|
String *check_well_formed_result(String *str, bool send_error= 0);
|
||||||
bool eq_by_collation(Item *item, bool binary_cmp, CHARSET_INFO *cs);
|
bool eq_by_collation(Item *item, bool binary_cmp, CHARSET_INFO *cs);
|
||||||
|
|
||||||
Item* set_expr_cache(THD *thd, List<Item*> &depends_on);
|
Item* set_expr_cache(THD *thd, List<Item*> &depends_on);
|
||||||
|
virtual Item *get_cached_item() { return NULL; }
|
||||||
|
|
||||||
virtual Item_equal *get_item_equal() { return NULL; }
|
virtual Item_equal *get_item_equal() { return NULL; }
|
||||||
virtual void set_item_equal(Item_equal *item_eq) {};
|
virtual void set_item_equal(Item_equal *item_eq) {};
|
||||||
@ -1258,6 +1263,13 @@ public:
|
|||||||
join_tab_idx= join_tab_idx_arg;
|
join_tab_idx= join_tab_idx_arg;
|
||||||
}
|
}
|
||||||
virtual uint get_join_tab_idx() { return join_tab_idx; }
|
virtual uint get_join_tab_idx() { return join_tab_idx; }
|
||||||
|
|
||||||
|
table_map view_used_tables(TABLE_LIST *view)
|
||||||
|
{
|
||||||
|
view->view_used_tables= 0;
|
||||||
|
walk(&Item::view_used_tables_processor, 0, (uchar *) view);
|
||||||
|
return view->view_used_tables;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@ -1657,6 +1669,7 @@ public:
|
|||||||
Item_ident(TABLE_LIST *view_arg, const char *field_name_arg);
|
Item_ident(TABLE_LIST *view_arg, const char *field_name_arg);
|
||||||
const char *full_name() const;
|
const char *full_name() const;
|
||||||
void cleanup();
|
void cleanup();
|
||||||
|
st_select_lex *get_depended_from() const;
|
||||||
bool remove_dependence_processor(uchar * arg);
|
bool remove_dependence_processor(uchar * arg);
|
||||||
virtual void print(String *str, enum_query_type query_type);
|
virtual void print(String *str, enum_query_type query_type);
|
||||||
virtual bool change_context_processor(uchar *cntx)
|
virtual bool change_context_processor(uchar *cntx)
|
||||||
@ -1744,6 +1757,7 @@ public:
|
|||||||
int save_in_field(Field *field,bool no_conversions);
|
int save_in_field(Field *field,bool no_conversions);
|
||||||
void save_org_in_field(Field *field);
|
void save_org_in_field(Field *field);
|
||||||
table_map used_tables() const;
|
table_map used_tables() const;
|
||||||
|
table_map all_used_tables() const;
|
||||||
enum Item_result result_type () const
|
enum Item_result result_type () const
|
||||||
{
|
{
|
||||||
return field->result_type();
|
return field->result_type();
|
||||||
@ -1772,6 +1786,7 @@ public:
|
|||||||
bool add_field_to_set_processor(uchar * arg);
|
bool add_field_to_set_processor(uchar * arg);
|
||||||
bool find_item_in_field_list_processor(uchar *arg);
|
bool find_item_in_field_list_processor(uchar *arg);
|
||||||
bool register_field_in_read_map(uchar *arg);
|
bool register_field_in_read_map(uchar *arg);
|
||||||
|
bool register_field_in_write_map(uchar *arg);
|
||||||
bool register_field_in_bitmap(uchar *arg);
|
bool register_field_in_bitmap(uchar *arg);
|
||||||
bool check_partition_func_processor(uchar *int_arg) {return FALSE;}
|
bool check_partition_func_processor(uchar *int_arg) {return FALSE;}
|
||||||
bool vcol_in_partition_func_processor(uchar *bool_arg);
|
bool vcol_in_partition_func_processor(uchar *bool_arg);
|
||||||
@ -2552,15 +2567,8 @@ public:
|
|||||||
Field *get_tmp_table_field()
|
Field *get_tmp_table_field()
|
||||||
{ return result_field ? result_field : (*ref)->get_tmp_table_field(); }
|
{ return result_field ? result_field : (*ref)->get_tmp_table_field(); }
|
||||||
Item *get_tmp_table_item(THD *thd);
|
Item *get_tmp_table_item(THD *thd);
|
||||||
table_map used_tables() const
|
inline table_map used_tables() const;
|
||||||
{
|
inline void update_used_tables();
|
||||||
return depended_from ? OUTER_REF_TABLE_BIT : (*ref)->used_tables();
|
|
||||||
}
|
|
||||||
void update_used_tables()
|
|
||||||
{
|
|
||||||
if (!depended_from)
|
|
||||||
(*ref)->update_used_tables();
|
|
||||||
}
|
|
||||||
bool const_item() const
|
bool const_item() const
|
||||||
{
|
{
|
||||||
return (*ref)->const_item();
|
return (*ref)->const_item();
|
||||||
@ -2839,12 +2847,14 @@ public:
|
|||||||
class Item_direct_view_ref :public Item_direct_ref
|
class Item_direct_view_ref :public Item_direct_ref
|
||||||
{
|
{
|
||||||
Item_equal *item_equal;
|
Item_equal *item_equal;
|
||||||
|
TABLE_LIST *view;
|
||||||
public:
|
public:
|
||||||
Item_direct_view_ref(Name_resolution_context *context_arg, Item **item,
|
Item_direct_view_ref(Name_resolution_context *context_arg, Item **item,
|
||||||
const char *table_name_arg,
|
const char *table_name_arg,
|
||||||
const char *field_name_arg)
|
const char *field_name_arg,
|
||||||
|
TABLE_LIST *view_arg)
|
||||||
:Item_direct_ref(context_arg, item, table_name_arg, field_name_arg),
|
:Item_direct_ref(context_arg, item, table_name_arg, field_name_arg),
|
||||||
item_equal(0) {}
|
item_equal(0), view(view_arg) {}
|
||||||
/* Constructor need to process subselect with temporary tables (see Item) */
|
/* Constructor need to process subselect with temporary tables (see Item) */
|
||||||
Item_direct_view_ref(THD *thd, Item_direct_ref *item)
|
Item_direct_view_ref(THD *thd, Item_direct_ref *item)
|
||||||
:Item_direct_ref(thd, item), item_equal(0) {}
|
:Item_direct_ref(thd, item), item_equal(0) {}
|
||||||
@ -2868,6 +2878,19 @@ public:
|
|||||||
bool subst_argument_checker(uchar **arg);
|
bool subst_argument_checker(uchar **arg);
|
||||||
Item *equal_fields_propagator(uchar *arg);
|
Item *equal_fields_propagator(uchar *arg);
|
||||||
Item *replace_equal_field(uchar *arg);
|
Item *replace_equal_field(uchar *arg);
|
||||||
|
table_map used_tables() const;
|
||||||
|
bool walk(Item_processor processor, bool walk_subquery, uchar *arg)
|
||||||
|
{
|
||||||
|
return (*ref)->walk(processor, walk_subquery, arg) ||
|
||||||
|
(this->*processor)(arg);
|
||||||
|
}
|
||||||
|
bool view_used_tables_processor(uchar *arg)
|
||||||
|
{
|
||||||
|
TABLE_LIST *view_arg= (TABLE_LIST *) arg;
|
||||||
|
if (view_arg == view)
|
||||||
|
view_arg->view_used_tables|= (*ref)->used_tables();
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@ -2958,15 +2981,7 @@ public:
|
|||||||
bool val_bool();
|
bool val_bool();
|
||||||
bool get_date(MYSQL_TIME *ltime, uint fuzzydate);
|
bool get_date(MYSQL_TIME *ltime, uint fuzzydate);
|
||||||
virtual void print(String *str, enum_query_type query_type);
|
virtual void print(String *str, enum_query_type query_type);
|
||||||
/*
|
table_map used_tables() const;
|
||||||
we add RAND_TABLE_BIT to prevent moving this item from HAVING to WHERE
|
|
||||||
*/
|
|
||||||
table_map used_tables() const
|
|
||||||
{
|
|
||||||
return (depended_from ?
|
|
||||||
OUTER_REF_TABLE_BIT :
|
|
||||||
(*ref)->used_tables() | RAND_TABLE_BIT);
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -3213,6 +3228,17 @@ public:
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
Cached_item_XXX objects are not exactly caches. They do the following:
|
||||||
|
|
||||||
|
Each Cached_item_XXX object has
|
||||||
|
- its source item
|
||||||
|
- saved value of the source item
|
||||||
|
- cmp() method that compares the saved value with the current value of the
|
||||||
|
source item, and if they were not equal saves item's value into the saved
|
||||||
|
value.
|
||||||
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Cached_item_XXX objects are not exactly caches. They do the following:
|
Cached_item_XXX objects are not exactly caches. They do the following:
|
||||||
|
|
||||||
|
@ -2138,6 +2138,16 @@ bool Item_func_between::fix_fields(THD *thd, Item **ref)
|
|||||||
|
|
||||||
thd->lex->current_select->between_count++;
|
thd->lex->current_select->between_count++;
|
||||||
|
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool Item_func_between::eval_not_null_tables(uchar *opt_arg)
|
||||||
|
{
|
||||||
|
if (Item_func_opt_neg::eval_not_null_tables(NULL))
|
||||||
|
return 1;
|
||||||
|
|
||||||
/* not_null_tables_cache == union(T1(e),T1(e1),T1(e2)) */
|
/* not_null_tables_cache == union(T1(e),T1(e1),T1(e2)) */
|
||||||
if (pred_level && !negated)
|
if (pred_level && !negated)
|
||||||
return 0;
|
return 0;
|
||||||
@ -2146,7 +2156,6 @@ bool Item_func_between::fix_fields(THD *thd, Item **ref)
|
|||||||
not_null_tables_cache= (args[0]->not_null_tables() |
|
not_null_tables_cache= (args[0]->not_null_tables() |
|
||||||
(args[1]->not_null_tables() &
|
(args[1]->not_null_tables() &
|
||||||
args[2]->not_null_tables()));
|
args[2]->not_null_tables()));
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2529,13 +2538,22 @@ Item_func_if::fix_fields(THD *thd, Item **ref)
|
|||||||
if (Item_func::fix_fields(thd, ref))
|
if (Item_func::fix_fields(thd, ref))
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool
|
||||||
|
Item_func_if::eval_not_null_tables(uchar *opt_arg)
|
||||||
|
{
|
||||||
|
if (Item_func::eval_not_null_tables(NULL))
|
||||||
|
return 1;
|
||||||
|
|
||||||
not_null_tables_cache= (args[1]->not_null_tables() &
|
not_null_tables_cache= (args[1]->not_null_tables() &
|
||||||
args[2]->not_null_tables());
|
args[2]->not_null_tables());
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
Item_func_if::fix_length_and_dec()
|
Item_func_if::fix_length_and_dec()
|
||||||
{
|
{
|
||||||
@ -3742,11 +3760,22 @@ bool Item_func_in::nulls_in_row()
|
|||||||
bool
|
bool
|
||||||
Item_func_in::fix_fields(THD *thd, Item **ref)
|
Item_func_in::fix_fields(THD *thd, Item **ref)
|
||||||
{
|
{
|
||||||
Item **arg, **arg_end;
|
|
||||||
|
|
||||||
if (Item_func_opt_neg::fix_fields(thd, ref))
|
if (Item_func_opt_neg::fix_fields(thd, ref))
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool
|
||||||
|
Item_func_in::eval_not_null_tables(uchar *opt_arg)
|
||||||
|
{
|
||||||
|
Item **arg, **arg_end;
|
||||||
|
|
||||||
|
if (Item_func_opt_neg::eval_not_null_tables(NULL))
|
||||||
|
return 1;
|
||||||
|
|
||||||
/* not_null_tables_cache == union(T1(e),union(T1(ei))) */
|
/* not_null_tables_cache == union(T1(e),union(T1(ei))) */
|
||||||
if (pred_level && negated)
|
if (pred_level && negated)
|
||||||
return 0;
|
return 0;
|
||||||
@ -4177,7 +4206,6 @@ Item_cond::fix_fields(THD *thd, Item **ref)
|
|||||||
*/
|
*/
|
||||||
while ((item=li++))
|
while ((item=li++))
|
||||||
{
|
{
|
||||||
table_map tmp_table_map;
|
|
||||||
while (item->type() == Item::COND_ITEM &&
|
while (item->type() == Item::COND_ITEM &&
|
||||||
((Item_cond*) item)->functype() == functype() &&
|
((Item_cond*) item)->functype() == functype() &&
|
||||||
!((Item_cond*) item)->list.is_empty())
|
!((Item_cond*) item)->list.is_empty())
|
||||||
@ -4199,11 +4227,12 @@ Item_cond::fix_fields(THD *thd, Item **ref)
|
|||||||
and_tables_cache= (table_map) 0;
|
and_tables_cache= (table_map) 0;
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
tmp_table_map= item->not_null_tables();
|
table_map tmp_table_map= item->not_null_tables();
|
||||||
not_null_tables_cache|= tmp_table_map;
|
not_null_tables_cache|= tmp_table_map;
|
||||||
and_tables_cache&= tmp_table_map;
|
and_tables_cache&= tmp_table_map;
|
||||||
const_item_cache= FALSE;
|
const_item_cache= FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
with_sum_func= with_sum_func || item->with_sum_func;
|
with_sum_func= with_sum_func || item->with_sum_func;
|
||||||
with_field= with_field || item->with_field;
|
with_field= with_field || item->with_field;
|
||||||
with_subselect|= item->with_subselect;
|
with_subselect|= item->with_subselect;
|
||||||
@ -4218,6 +4247,28 @@ Item_cond::fix_fields(THD *thd, Item **ref)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool
|
||||||
|
Item_cond::eval_not_null_tables(uchar *opt_arg)
|
||||||
|
{
|
||||||
|
Item *item;
|
||||||
|
List_iterator<Item> li(list);
|
||||||
|
and_tables_cache= ~(table_map) 0;
|
||||||
|
while ((item=li++))
|
||||||
|
{
|
||||||
|
table_map tmp_table_map;
|
||||||
|
if (item->const_item())
|
||||||
|
and_tables_cache= (table_map) 0;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
tmp_table_map= item->not_null_tables();
|
||||||
|
not_null_tables_cache|= tmp_table_map;
|
||||||
|
and_tables_cache&= tmp_table_map;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void Item_cond::fix_after_pullout(st_select_lex *new_parent, Item **ref)
|
void Item_cond::fix_after_pullout(st_select_lex *new_parent, Item **ref)
|
||||||
{
|
{
|
||||||
List_iterator<Item> li(list);
|
List_iterator<Item> li(list);
|
||||||
|
@ -637,6 +637,7 @@ public:
|
|||||||
bool is_bool_func() { return 1; }
|
bool is_bool_func() { return 1; }
|
||||||
CHARSET_INFO *compare_collation() { return cmp_collation.collation; }
|
CHARSET_INFO *compare_collation() { return cmp_collation.collation; }
|
||||||
uint decimal_precision() const { return 1; }
|
uint decimal_precision() const { return 1; }
|
||||||
|
bool eval_not_null_tables(uchar *opt_arg);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@ -737,6 +738,7 @@ public:
|
|||||||
void fix_length_and_dec();
|
void fix_length_and_dec();
|
||||||
uint decimal_precision() const;
|
uint decimal_precision() const;
|
||||||
const char *func_name() const { return "if"; }
|
const char *func_name() const { return "if"; }
|
||||||
|
bool eval_not_null_tables(uchar *opt_arg);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@ -1273,6 +1275,7 @@ public:
|
|||||||
bool nulls_in_row();
|
bool nulls_in_row();
|
||||||
bool is_bool_func() { return 1; }
|
bool is_bool_func() { return 1; }
|
||||||
CHARSET_INFO *compare_collation() { return cmp_collation.collation; }
|
CHARSET_INFO *compare_collation() { return cmp_collation.collation; }
|
||||||
|
bool eval_not_null_tables(uchar *opt_arg);
|
||||||
};
|
};
|
||||||
|
|
||||||
class cmp_item_row :public cmp_item
|
class cmp_item_row :public cmp_item
|
||||||
@ -1528,6 +1531,7 @@ public:
|
|||||||
bool subst_argument_checker(uchar **arg) { return TRUE; }
|
bool subst_argument_checker(uchar **arg) { return TRUE; }
|
||||||
Item *compile(Item_analyzer analyzer, uchar **arg_p,
|
Item *compile(Item_analyzer analyzer, uchar **arg_p,
|
||||||
Item_transformer transformer, uchar *arg_t);
|
Item_transformer transformer, uchar *arg_t);
|
||||||
|
bool eval_not_null_tables(uchar *opt_arg);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -202,7 +202,6 @@ Item_func::fix_fields(THD *thd, Item **ref)
|
|||||||
with_sum_func= with_sum_func || item->with_sum_func;
|
with_sum_func= with_sum_func || item->with_sum_func;
|
||||||
with_field= with_field || item->with_field;
|
with_field= with_field || item->with_field;
|
||||||
used_tables_cache|= item->used_tables();
|
used_tables_cache|= item->used_tables();
|
||||||
not_null_tables_cache|= item->not_null_tables();
|
|
||||||
const_item_cache&= item->const_item();
|
const_item_cache&= item->const_item();
|
||||||
with_subselect|= item->with_subselect;
|
with_subselect|= item->with_subselect;
|
||||||
}
|
}
|
||||||
@ -231,6 +230,21 @@ Item_func::quick_fix_field()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool
|
||||||
|
Item_func::eval_not_null_tables(uchar *opt_arg)
|
||||||
|
{
|
||||||
|
Item **arg,**arg_end;
|
||||||
|
if (arg_count)
|
||||||
|
{
|
||||||
|
for (arg=args, arg_end=args+arg_count; arg != arg_end ; arg++)
|
||||||
|
{
|
||||||
|
not_null_tables_cache|= (*arg)->not_null_tables();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void Item_func::fix_after_pullout(st_select_lex *new_parent, Item **ref)
|
void Item_func::fix_after_pullout(st_select_lex *new_parent, Item **ref)
|
||||||
{
|
{
|
||||||
Item **arg,**arg_end;
|
Item **arg,**arg_end;
|
||||||
@ -3984,6 +3998,21 @@ bool Item_func_set_user_var::fix_fields(THD *thd, Item **ref)
|
|||||||
entry->collation.set(args[0]->collation.collation, DERIVATION_IMPLICIT);
|
entry->collation.set(args[0]->collation.collation, DERIVATION_IMPLICIT);
|
||||||
collation.set(entry->collation.collation, DERIVATION_IMPLICIT);
|
collation.set(entry->collation.collation, DERIVATION_IMPLICIT);
|
||||||
cached_result_type= args[0]->result_type();
|
cached_result_type= args[0]->result_type();
|
||||||
|
if (thd->lex->current_select)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
When this function is used in a derived table/view force the derived
|
||||||
|
table to be materialized to preserve possible side-effect of setting a
|
||||||
|
user variable.
|
||||||
|
*/
|
||||||
|
SELECT_LEX_UNIT *unit= thd->lex->current_select->master_unit();
|
||||||
|
TABLE_LIST *derived;
|
||||||
|
for (derived= unit->derived;
|
||||||
|
derived;
|
||||||
|
derived= derived->select_lex->master_unit()->derived)
|
||||||
|
derived->set_materialized_derived();
|
||||||
|
}
|
||||||
|
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -191,6 +191,7 @@ public:
|
|||||||
Item_transformer transformer, uchar *arg_t);
|
Item_transformer transformer, uchar *arg_t);
|
||||||
void traverse_cond(Cond_traverser traverser,
|
void traverse_cond(Cond_traverser traverser,
|
||||||
void * arg, traverse_order order);
|
void * arg, traverse_order order);
|
||||||
|
bool eval_not_null_tables(uchar *opt_arg);
|
||||||
// bool is_expensive_processor(uchar *arg);
|
// bool is_expensive_processor(uchar *arg);
|
||||||
// virtual bool is_expensive() { return 0; }
|
// virtual bool is_expensive() { return 0; }
|
||||||
inline double fix_result(double value)
|
inline double fix_result(double value)
|
||||||
@ -1713,14 +1714,7 @@ public:
|
|||||||
void fix_length_and_dec() { decimals=0; max_length=1; maybe_null=1;}
|
void fix_length_and_dec() { decimals=0; max_length=1; maybe_null=1;}
|
||||||
bool check_vcol_func_processor(uchar *int_arg)
|
bool check_vcol_func_processor(uchar *int_arg)
|
||||||
{
|
{
|
||||||
#if 0
|
|
||||||
DBUG_ENTER("Item_func_is_free_lock::check_vcol_func_processor");
|
|
||||||
DBUG_PRINT("info",
|
|
||||||
("check_vcol_func_processor returns TRUE: unsupported function"));
|
|
||||||
DBUG_RETURN(TRUE);
|
|
||||||
#else
|
|
||||||
return trace_unsupported_by_check_vcol_func_processor(func_name());
|
return trace_unsupported_by_check_vcol_func_processor(func_name());
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -3204,6 +3204,9 @@ int subselect_uniquesubquery_engine::exec()
|
|||||||
DBUG_RETURN(0);
|
DBUG_RETURN(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!tab->preread_init_done && tab->preread_init())
|
||||||
|
DBUG_RETURN(1);
|
||||||
|
|
||||||
if (null_keypart)
|
if (null_keypart)
|
||||||
DBUG_RETURN(scan_table());
|
DBUG_RETURN(scan_table());
|
||||||
|
|
||||||
@ -3336,7 +3339,7 @@ subselect_uniquesubquery_engine::~subselect_uniquesubquery_engine()
|
|||||||
|
|
||||||
int subselect_indexsubquery_engine::exec()
|
int subselect_indexsubquery_engine::exec()
|
||||||
{
|
{
|
||||||
DBUG_ENTER("subselect_indexsubquery_engine::exec");
|
DBUG_ENTER("subselect_indexsubquery_engine");
|
||||||
int error;
|
int error;
|
||||||
bool null_finding= 0;
|
bool null_finding= 0;
|
||||||
TABLE *table= tab->table;
|
TABLE *table= tab->table;
|
||||||
@ -3367,6 +3370,9 @@ int subselect_indexsubquery_engine::exec()
|
|||||||
DBUG_RETURN(0);
|
DBUG_RETURN(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!tab->preread_init_done && tab->preread_init())
|
||||||
|
DBUG_RETURN(1);
|
||||||
|
|
||||||
if (null_keypart)
|
if (null_keypart)
|
||||||
DBUG_RETURN(scan_table());
|
DBUG_RETURN(scan_table());
|
||||||
|
|
||||||
@ -3468,10 +3474,13 @@ void subselect_uniquesubquery_engine::exclude()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
table_map subselect_engine::calc_const_tables(TABLE_LIST *table)
|
table_map subselect_engine::calc_const_tables(List<TABLE_LIST> &list)
|
||||||
{
|
{
|
||||||
table_map map= 0;
|
table_map map= 0;
|
||||||
for (; table; table= table->next_leaf)
|
List_iterator<TABLE_LIST> ti(list);
|
||||||
|
TABLE_LIST *table;
|
||||||
|
//for (; table; table= table->next_leaf)
|
||||||
|
while ((table= ti++))
|
||||||
{
|
{
|
||||||
TABLE *tbl= table->table;
|
TABLE *tbl= table->table;
|
||||||
if (tbl && tbl->const_table)
|
if (tbl && tbl->const_table)
|
||||||
@ -4060,7 +4069,7 @@ bool subselect_hash_sj_engine::init(List<Item> *tmp_columns, uint subquery_id)
|
|||||||
result_sink->get_tmp_table_param()->materialized_subquery= true;
|
result_sink->get_tmp_table_param()->materialized_subquery= true;
|
||||||
if (result_sink->create_result_table(thd, tmp_columns, TRUE,
|
if (result_sink->create_result_table(thd, tmp_columns, TRUE,
|
||||||
tmp_create_options,
|
tmp_create_options,
|
||||||
name, TRUE))
|
name, TRUE, TRUE))
|
||||||
DBUG_RETURN(TRUE);
|
DBUG_RETURN(TRUE);
|
||||||
|
|
||||||
tmp_table= result_sink->table;
|
tmp_table= result_sink->table;
|
||||||
@ -4218,6 +4227,7 @@ subselect_hash_sj_engine::make_unique_engine()
|
|||||||
DBUG_RETURN(NULL);
|
DBUG_RETURN(NULL);
|
||||||
|
|
||||||
tab->table= tmp_table;
|
tab->table= tmp_table;
|
||||||
|
tab->preread_init_done= FALSE;
|
||||||
tab->ref.tmp_table_index_lookup_init(thd, tmp_key, it, FALSE);
|
tab->ref.tmp_table_index_lookup_init(thd, tmp_key, it, FALSE);
|
||||||
|
|
||||||
DBUG_RETURN(new subselect_uniquesubquery_engine(thd, tab, item,
|
DBUG_RETURN(new subselect_uniquesubquery_engine(thd, tab, item,
|
||||||
|
@ -621,6 +621,7 @@ public:
|
|||||||
virtual bool may_be_null() { return maybe_null; };
|
virtual bool may_be_null() { return maybe_null; };
|
||||||
virtual table_map upper_select_const_tables()= 0;
|
virtual table_map upper_select_const_tables()= 0;
|
||||||
static table_map calc_const_tables(TABLE_LIST *);
|
static table_map calc_const_tables(TABLE_LIST *);
|
||||||
|
static table_map calc_const_tables(List<TABLE_LIST> &list);
|
||||||
virtual void print(String *str, enum_query_type query_type)= 0;
|
virtual void print(String *str, enum_query_type query_type)= 0;
|
||||||
virtual bool change_result(Item_subselect *si,
|
virtual bool change_result(Item_subselect *si,
|
||||||
select_result_interceptor *result,
|
select_result_interceptor *result,
|
||||||
|
@ -61,12 +61,15 @@ class Parser_state;
|
|||||||
|
|
||||||
QT_ORDINARY -- ordinary SQL query.
|
QT_ORDINARY -- ordinary SQL query.
|
||||||
QT_IS -- SQL query to be shown in INFORMATION_SCHEMA (in utf8 and without
|
QT_IS -- SQL query to be shown in INFORMATION_SCHEMA (in utf8 and without
|
||||||
character set introducers).
|
character set introducers).
|
||||||
|
QT_VIEW_INTERNAL -- view internal representation (like QT_ORDINARY except
|
||||||
|
ORDER BY clause)
|
||||||
*/
|
*/
|
||||||
enum enum_query_type
|
enum enum_query_type
|
||||||
{
|
{
|
||||||
QT_ORDINARY,
|
QT_ORDINARY,
|
||||||
QT_IS
|
QT_IS,
|
||||||
|
QT_VIEW_INTERNAL
|
||||||
};
|
};
|
||||||
|
|
||||||
/* TODO convert all these three maps to Bitmap classes */
|
/* TODO convert all these three maps to Bitmap classes */
|
||||||
@ -515,7 +518,6 @@ protected:
|
|||||||
#define OPTION_PROFILING (ULL(1) << 33)
|
#define OPTION_PROFILING (ULL(1) << 33)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Maximum length of time zone name that we support
|
Maximum length of time zone name that we support
|
||||||
(Time zone name is char(64) in db). mysqlbinlog needs it.
|
(Time zone name is char(64) in db). mysqlbinlog needs it.
|
||||||
@ -1408,11 +1410,9 @@ int mysql_explain_select(THD *thd, SELECT_LEX *sl, char const *type,
|
|||||||
select_result *result);
|
select_result *result);
|
||||||
bool mysql_union(THD *thd, LEX *lex, select_result *result,
|
bool mysql_union(THD *thd, LEX *lex, select_result *result,
|
||||||
SELECT_LEX_UNIT *unit, ulong setup_tables_done_option);
|
SELECT_LEX_UNIT *unit, ulong setup_tables_done_option);
|
||||||
bool mysql_handle_derived(LEX *lex, bool (*processor)(THD *thd,
|
bool mysql_handle_derived(LEX *lex, uint phases);
|
||||||
LEX *lex,
|
bool mysql_handle_single_derived(LEX *lex, TABLE_LIST *derived, uint phases);
|
||||||
TABLE_LIST *table));
|
bool mysql_handle_list_of_derived(LEX *lex, TABLE_LIST *dt_list, uint phases);
|
||||||
bool mysql_derived_prepare(THD *thd, LEX *lex, TABLE_LIST *t);
|
|
||||||
bool mysql_derived_filling(THD *thd, LEX *lex, TABLE_LIST *t);
|
|
||||||
bool check_table_file_presence(char *old_path, char *path,
|
bool check_table_file_presence(char *old_path, char *path,
|
||||||
const char *db,
|
const char *db,
|
||||||
const char *table_name,
|
const char *table_name,
|
||||||
@ -1426,6 +1426,11 @@ Field *create_tmp_field(THD *thd, TABLE *table,Item *item, Item::Type type,
|
|||||||
bool make_copy_field,
|
bool make_copy_field,
|
||||||
uint convert_blob_length);
|
uint convert_blob_length);
|
||||||
bool open_tmp_table(TABLE *table);
|
bool open_tmp_table(TABLE *table);
|
||||||
|
bool create_internal_tmp_table(TABLE *table, KEY *keyinfo,
|
||||||
|
ENGINE_COLUMNDEF *start_recinfo,
|
||||||
|
ENGINE_COLUMNDEF **recinfo,
|
||||||
|
ulonglong options);
|
||||||
|
|
||||||
void sp_prepare_create_field(THD *thd, Create_field *sql_field);
|
void sp_prepare_create_field(THD *thd, Create_field *sql_field);
|
||||||
int prepare_create_field(Create_field *sql_field,
|
int prepare_create_field(Create_field *sql_field,
|
||||||
uint *blob_columns,
|
uint *blob_columns,
|
||||||
@ -1733,17 +1738,21 @@ bool get_key_map_from_key_list(key_map *map, TABLE *table,
|
|||||||
bool insert_fields(THD *thd, Name_resolution_context *context,
|
bool insert_fields(THD *thd, Name_resolution_context *context,
|
||||||
const char *db_name, const char *table_name,
|
const char *db_name, const char *table_name,
|
||||||
List_iterator<Item> *it, bool any_privileges);
|
List_iterator<Item> *it, bool any_privileges);
|
||||||
|
void make_leaves_list(List<TABLE_LIST> &list, TABLE_LIST *tables,
|
||||||
|
bool full_table_list, TABLE_LIST *boundary);
|
||||||
bool setup_tables(THD *thd, Name_resolution_context *context,
|
bool setup_tables(THD *thd, Name_resolution_context *context,
|
||||||
List<TABLE_LIST> *from_clause, TABLE_LIST *tables,
|
List<TABLE_LIST> *from_clause, TABLE_LIST *tables,
|
||||||
TABLE_LIST **leaves, bool select_insert);
|
List<TABLE_LIST> &leaves, bool select_insert,
|
||||||
|
bool full_table_list);
|
||||||
bool setup_tables_and_check_access(THD *thd,
|
bool setup_tables_and_check_access(THD *thd,
|
||||||
Name_resolution_context *context,
|
Name_resolution_context *context,
|
||||||
List<TABLE_LIST> *from_clause,
|
List<TABLE_LIST> *from_clause,
|
||||||
TABLE_LIST *tables,
|
TABLE_LIST *tables,
|
||||||
TABLE_LIST **leaves,
|
List<TABLE_LIST> &leaves,
|
||||||
bool select_insert,
|
bool select_insert,
|
||||||
ulong want_access_first,
|
ulong want_access_first,
|
||||||
ulong want_access);
|
ulong want_access,
|
||||||
|
bool full_table_list);
|
||||||
int setup_wild(THD *thd, TABLE_LIST *tables, List<Item> &fields,
|
int setup_wild(THD *thd, TABLE_LIST *tables, List<Item> &fields,
|
||||||
List<Item> *sum_func_list, uint wild_num);
|
List<Item> *sum_func_list, uint wild_num);
|
||||||
bool setup_fields(THD *thd, Item** ref_pointer_array,
|
bool setup_fields(THD *thd, Item** ref_pointer_array,
|
||||||
@ -1762,7 +1771,7 @@ inline bool setup_fields_with_no_wrap(THD *thd, Item **ref_pointer_array,
|
|||||||
thd->lex->select_lex.no_wrap_view_item= FALSE;
|
thd->lex->select_lex.no_wrap_view_item= FALSE;
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
int setup_conds(THD *thd, TABLE_LIST *tables, TABLE_LIST *leaves,
|
int setup_conds(THD *thd, TABLE_LIST *tables, List<TABLE_LIST> &leaves,
|
||||||
COND **conds);
|
COND **conds);
|
||||||
void wrap_ident(THD *thd, Item **conds);
|
void wrap_ident(THD *thd, Item **conds);
|
||||||
int setup_ftfuncs(SELECT_LEX* select);
|
int setup_ftfuncs(SELECT_LEX* select);
|
||||||
@ -1785,7 +1794,8 @@ inline int open_and_lock_tables(THD *thd, TABLE_LIST *tables)
|
|||||||
/* simple open_and_lock_tables without derived handling for single table */
|
/* simple open_and_lock_tables without derived handling for single table */
|
||||||
TABLE *open_n_lock_single_table(THD *thd, TABLE_LIST *table_l,
|
TABLE *open_n_lock_single_table(THD *thd, TABLE_LIST *table_l,
|
||||||
thr_lock_type lock_type);
|
thr_lock_type lock_type);
|
||||||
bool open_normal_and_derived_tables(THD *thd, TABLE_LIST *tables, uint flags);
|
bool open_normal_and_derived_tables(THD *thd, TABLE_LIST *tables, uint flags,
|
||||||
|
uint dt_phases);
|
||||||
int lock_tables(THD *thd, TABLE_LIST *tables, uint counter, bool *need_reopen);
|
int lock_tables(THD *thd, TABLE_LIST *tables, uint counter, bool *need_reopen);
|
||||||
int decide_logging_format(THD *thd, TABLE_LIST *tables);
|
int decide_logging_format(THD *thd, TABLE_LIST *tables);
|
||||||
TABLE *open_temporary_table(THD *thd, const char *path, const char *db,
|
TABLE *open_temporary_table(THD *thd, const char *path, const char *db,
|
||||||
@ -1815,6 +1825,7 @@ void flush_tables();
|
|||||||
bool is_equal(const LEX_STRING *a, const LEX_STRING *b);
|
bool is_equal(const LEX_STRING *a, const LEX_STRING *b);
|
||||||
char *make_default_log_name(char *buff,const char* log_ext);
|
char *make_default_log_name(char *buff,const char* log_ext);
|
||||||
char *make_once_alloced_filename(const char *basename, const char *ext);
|
char *make_once_alloced_filename(const char *basename, const char *ext);
|
||||||
|
void unfix_fields(List<Item> &items);
|
||||||
|
|
||||||
#ifdef WITH_PARTITION_STORAGE_ENGINE
|
#ifdef WITH_PARTITION_STORAGE_ENGINE
|
||||||
uint fast_alter_partition_table(THD *thd, TABLE *table,
|
uint fast_alter_partition_table(THD *thd, TABLE *table,
|
||||||
@ -2709,7 +2720,7 @@ Item * all_any_subquery_creator(Item *left_expr,
|
|||||||
inline void setup_table_map(TABLE *table, TABLE_LIST *table_list, uint tablenr)
|
inline void setup_table_map(TABLE *table, TABLE_LIST *table_list, uint tablenr)
|
||||||
{
|
{
|
||||||
table->used_fields= 0;
|
table->used_fields= 0;
|
||||||
table->const_table= 0;
|
table_list->reset_const_table();
|
||||||
table->null_row= 0;
|
table->null_row= 0;
|
||||||
table->status= STATUS_NO_RECORD;
|
table->status= STATUS_NO_RECORD;
|
||||||
table->maybe_null= table_list->outer_join;
|
table->maybe_null= table_list->outer_join;
|
||||||
@ -2725,6 +2736,14 @@ inline void setup_table_map(TABLE *table, TABLE_LIST *table_list, uint tablenr)
|
|||||||
table->force_index_order= table->force_index_group= 0;
|
table->force_index_order= table->force_index_group= 0;
|
||||||
table->covering_keys= table->s->keys_for_keyread;
|
table->covering_keys= table->s->keys_for_keyread;
|
||||||
table->merge_keys.clear_all();
|
table->merge_keys.clear_all();
|
||||||
|
TABLE_LIST *orig= table_list->select_lex ?
|
||||||
|
table_list->select_lex->master_unit()->derived : 0;
|
||||||
|
if (!orig || !orig->is_merged_derived())
|
||||||
|
{
|
||||||
|
/* Tables merged from derived were set up already.*/
|
||||||
|
table->covering_keys= table->s->keys_for_keyread;
|
||||||
|
table->merge_keys.clear_all();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -9497,7 +9497,7 @@ ha_rows check_quick_select(PARAM *param, uint idx, bool index_only,
|
|||||||
SEL_ARG_RANGE_SEQ seq;
|
SEL_ARG_RANGE_SEQ seq;
|
||||||
RANGE_SEQ_IF seq_if = {NULL, sel_arg_range_seq_init, sel_arg_range_seq_next, 0, 0};
|
RANGE_SEQ_IF seq_if = {NULL, sel_arg_range_seq_init, sel_arg_range_seq_next, 0, 0};
|
||||||
handler *file= param->table->file;
|
handler *file= param->table->file;
|
||||||
ha_rows rows;
|
ha_rows rows= HA_POS_ERROR;
|
||||||
uint keynr= param->real_keynr[idx];
|
uint keynr= param->real_keynr[idx];
|
||||||
DBUG_ENTER("check_quick_select");
|
DBUG_ENTER("check_quick_select");
|
||||||
|
|
||||||
@ -9537,8 +9537,13 @@ ha_rows check_quick_select(PARAM *param, uint idx, bool index_only,
|
|||||||
*mrr_flags |= HA_MRR_USE_DEFAULT_IMPL;
|
*mrr_flags |= HA_MRR_USE_DEFAULT_IMPL;
|
||||||
|
|
||||||
*bufsize= param->thd->variables.mrr_buff_size;
|
*bufsize= param->thd->variables.mrr_buff_size;
|
||||||
rows= file->multi_range_read_info_const(keynr, &seq_if, (void*)&seq, 0,
|
/*
|
||||||
bufsize, mrr_flags, cost);
|
Skip materialized derived table/view result table from MRR check as
|
||||||
|
they aren't contain any data yet.
|
||||||
|
*/
|
||||||
|
if (param->table->pos_in_table_list->is_non_derived())
|
||||||
|
rows= file->multi_range_read_info_const(keynr, &seq_if, (void*)&seq, 0,
|
||||||
|
bufsize, mrr_flags, cost);
|
||||||
if (rows != HA_POS_ERROR)
|
if (rows != HA_POS_ERROR)
|
||||||
{
|
{
|
||||||
param->quick_rows[keynr]= rows;
|
param->quick_rows[keynr]= rows;
|
||||||
|
@ -183,8 +183,6 @@ static bool convert_subq_to_sj(JOIN *parent_join, Item_in_subselect *subq_pred);
|
|||||||
static bool convert_subq_to_jtbm(JOIN *parent_join,
|
static bool convert_subq_to_jtbm(JOIN *parent_join,
|
||||||
Item_in_subselect *subq_pred, bool *remove);
|
Item_in_subselect *subq_pred, bool *remove);
|
||||||
static TABLE_LIST *alloc_join_nest(THD *thd);
|
static TABLE_LIST *alloc_join_nest(THD *thd);
|
||||||
static
|
|
||||||
void fix_list_after_tbl_changes(SELECT_LEX *new_parent, List<TABLE_LIST> *tlist);
|
|
||||||
static uint get_tmp_table_rec_length(List<Item> &items);
|
static uint get_tmp_table_rec_length(List<Item> &items);
|
||||||
static double get_tmp_table_lookup_cost(THD *thd, double row_count,
|
static double get_tmp_table_lookup_cost(THD *thd, double row_count,
|
||||||
uint row_size);
|
uint row_size);
|
||||||
@ -344,9 +342,9 @@ int check_and_do_in_subquery_rewrites(JOIN *join)
|
|||||||
!join->having && !select_lex->with_sum_func && // 4
|
!join->having && !select_lex->with_sum_func && // 4
|
||||||
thd->thd_marker.emb_on_expr_nest && // 5
|
thd->thd_marker.emb_on_expr_nest && // 5
|
||||||
select_lex->outer_select()->join && // 6
|
select_lex->outer_select()->join && // 6
|
||||||
parent_unit->first_select()->leaf_tables && // 7
|
parent_unit->first_select()->leaf_tables.elements && // 7
|
||||||
!in_subs->in_strategy && // 8
|
!in_subs->in_strategy && // 8
|
||||||
select_lex->outer_select()->leaf_tables && // 9
|
select_lex->outer_select()->leaf_tables.elements && // 9
|
||||||
!((join->select_options | // 10
|
!((join->select_options | // 10
|
||||||
select_lex->outer_select()->join->select_options) // 10
|
select_lex->outer_select()->join->select_options) // 10
|
||||||
& SELECT_STRAIGHT_JOIN)) // 10
|
& SELECT_STRAIGHT_JOIN)) // 10
|
||||||
@ -412,9 +410,9 @@ int check_and_do_in_subquery_rewrites(JOIN *join)
|
|||||||
*/
|
*/
|
||||||
if (optimizer_flag(thd, OPTIMIZER_SWITCH_MATERIALIZATION) && // 0
|
if (optimizer_flag(thd, OPTIMIZER_SWITCH_MATERIALIZATION) && // 0
|
||||||
!select_lex->is_part_of_union() && // 1
|
!select_lex->is_part_of_union() && // 1
|
||||||
parent_unit->first_select()->leaf_tables && // 2
|
parent_unit->first_select()->leaf_tables.elements && // 2
|
||||||
thd->lex->sql_command == SQLCOM_SELECT && // *
|
thd->lex->sql_command == SQLCOM_SELECT && // *
|
||||||
select_lex->outer_select()->leaf_tables && // 2A
|
select_lex->outer_select()->leaf_tables.elements && // 2A
|
||||||
subquery_types_allow_materialization(in_subs) &&
|
subquery_types_allow_materialization(in_subs) &&
|
||||||
(in_subs->is_top_level_item() || //3
|
(in_subs->is_top_level_item() || //3
|
||||||
optimizer_flag(thd,
|
optimizer_flag(thd,
|
||||||
@ -422,7 +420,7 @@ int check_and_do_in_subquery_rewrites(JOIN *join)
|
|||||||
optimizer_flag(thd,
|
optimizer_flag(thd,
|
||||||
OPTIMIZER_SWITCH_PARTIAL_MATCH_TABLE_SCAN)) && //3
|
OPTIMIZER_SWITCH_PARTIAL_MATCH_TABLE_SCAN)) && //3
|
||||||
!in_subs->is_correlated) //4
|
!in_subs->is_correlated) //4
|
||||||
{
|
{
|
||||||
in_subs->in_strategy|= SUBS_MATERIALIZATION;
|
in_subs->in_strategy|= SUBS_MATERIALIZATION;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -736,11 +734,25 @@ bool convert_join_subqueries_to_semijoins(JOIN *join)
|
|||||||
Item_in_subselect **in_subq;
|
Item_in_subselect **in_subq;
|
||||||
Item_in_subselect **in_subq_end;
|
Item_in_subselect **in_subq_end;
|
||||||
THD *thd= join->thd;
|
THD *thd= join->thd;
|
||||||
|
List_iterator<TABLE_LIST> ti(join->select_lex->leaf_tables);
|
||||||
DBUG_ENTER("convert_join_subqueries_to_semijoins");
|
DBUG_ENTER("convert_join_subqueries_to_semijoins");
|
||||||
|
|
||||||
if (join->sj_subselects.elements() == 0)
|
if (join->sj_subselects.elements() == 0)
|
||||||
DBUG_RETURN(FALSE);
|
DBUG_RETURN(FALSE);
|
||||||
|
|
||||||
|
for (in_subq= join->sj_subselects.front(),
|
||||||
|
in_subq_end= join->sj_subselects.back();
|
||||||
|
in_subq != in_subq_end;
|
||||||
|
in_subq++)
|
||||||
|
{
|
||||||
|
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();
|
||||||
|
}
|
||||||
|
|
||||||
/* First, convert child join's subqueries. We proceed bottom-up here */
|
/* First, convert child join's subqueries. We proceed bottom-up here */
|
||||||
for (in_subq= join->sj_subselects.front(),
|
for (in_subq= join->sj_subselects.front(),
|
||||||
in_subq_end= join->sj_subselects.back();
|
in_subq_end= join->sj_subselects.back();
|
||||||
@ -1149,7 +1161,7 @@ static bool convert_subq_to_sj(JOIN *parent_join, Item_in_subselect *subq_pred)
|
|||||||
st_select_lex *subq_lex= subq_pred->unit->first_select();
|
st_select_lex *subq_lex= subq_pred->unit->first_select();
|
||||||
nested_join->join_list.empty();
|
nested_join->join_list.empty();
|
||||||
List_iterator_fast<TABLE_LIST> li(subq_lex->top_join_list);
|
List_iterator_fast<TABLE_LIST> li(subq_lex->top_join_list);
|
||||||
TABLE_LIST *tl, *last_leaf;
|
TABLE_LIST *tl;
|
||||||
while ((tl= li++))
|
while ((tl= li++))
|
||||||
{
|
{
|
||||||
tl->embedding= sj_nest;
|
tl->embedding= sj_nest;
|
||||||
@ -1164,17 +1176,15 @@ static bool convert_subq_to_sj(JOIN *parent_join, Item_in_subselect *subq_pred)
|
|||||||
NOTE: We actually insert them at the front! That's because the order is
|
NOTE: We actually insert them at the front! That's because the order is
|
||||||
reversed in this list.
|
reversed in this list.
|
||||||
*/
|
*/
|
||||||
for (tl= parent_lex->leaf_tables; tl->next_leaf; tl= tl->next_leaf) ;
|
parent_lex->leaf_tables.concat(&subq_lex->leaf_tables);
|
||||||
tl->next_leaf= subq_lex->leaf_tables;
|
|
||||||
last_leaf= tl;
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Same as above for next_local chain
|
Same as above for next_local chain
|
||||||
(a theory: a next_local chain always starts with ::leaf_tables
|
(a theory: a next_local chain always starts with ::leaf_tables
|
||||||
because view's tables are inserted after the view)
|
because view's tables are inserted after the view)
|
||||||
*/
|
*/
|
||||||
for (tl= parent_lex->leaf_tables; tl->next_local; tl= tl->next_local) ;
|
for (tl= parent_lex->leaf_tables.head(); tl->next_local; tl= tl->next_local) ;
|
||||||
tl->next_local= subq_lex->leaf_tables;
|
tl->next_local= subq_lex->leaf_tables.head();
|
||||||
|
|
||||||
/* A theory: no need to re-connect the next_global chain */
|
/* A theory: no need to re-connect the next_global chain */
|
||||||
|
|
||||||
@ -1187,7 +1197,8 @@ static bool convert_subq_to_sj(JOIN *parent_join, Item_in_subselect *subq_pred)
|
|||||||
/* n. Adjust the parent_join->table_count counter */
|
/* n. Adjust the parent_join->table_count counter */
|
||||||
uint table_no= parent_join->table_count;
|
uint table_no= parent_join->table_count;
|
||||||
/* n. Walk through child's tables and adjust table->map */
|
/* n. Walk through child's tables and adjust table->map */
|
||||||
for (tl= subq_lex->leaf_tables; tl; tl= tl->next_leaf, table_no++)
|
List_iterator_fast<TABLE_LIST> si(subq_lex->leaf_tables);
|
||||||
|
while ((tl= si++))
|
||||||
{
|
{
|
||||||
tl->table->tablenr= table_no;
|
tl->table->tablenr= table_no;
|
||||||
tl->table->map= ((table_map)1) << table_no;
|
tl->table->map= ((table_map)1) << table_no;
|
||||||
@ -1197,6 +1208,7 @@ static bool convert_subq_to_sj(JOIN *parent_join, Item_in_subselect *subq_pred)
|
|||||||
emb && emb->select_lex == old_sl;
|
emb && emb->select_lex == old_sl;
|
||||||
emb= emb->embedding)
|
emb= emb->embedding)
|
||||||
emb->select_lex= parent_join->select_lex;
|
emb->select_lex= parent_join->select_lex;
|
||||||
|
table_no++;
|
||||||
}
|
}
|
||||||
parent_join->table_count += subq_lex->join->table_count;
|
parent_join->table_count += subq_lex->join->table_count;
|
||||||
|
|
||||||
@ -1289,7 +1301,8 @@ static bool convert_subq_to_sj(JOIN *parent_join, Item_in_subselect *subq_pred)
|
|||||||
*/
|
*/
|
||||||
save_lex= thd->lex->current_select;
|
save_lex= thd->lex->current_select;
|
||||||
thd->lex->current_select=parent_join->select_lex;
|
thd->lex->current_select=parent_join->select_lex;
|
||||||
parent_join->conds->fix_fields(parent_join->thd, &parent_join->conds);
|
if (!parent_join->conds->fixed)
|
||||||
|
parent_join->conds->fix_fields(parent_join->thd, &parent_join->conds);
|
||||||
thd->lex->current_select=save_lex;
|
thd->lex->current_select=save_lex;
|
||||||
parent_join->select_lex->where= parent_join->conds;
|
parent_join->select_lex->where= parent_join->conds;
|
||||||
}
|
}
|
||||||
@ -1381,16 +1394,14 @@ static bool convert_subq_to_jtbm(JOIN *parent_join,
|
|||||||
Inject the jtbm table into TABLE_LIST::next_leaf list, so that
|
Inject the jtbm table into TABLE_LIST::next_leaf list, so that
|
||||||
make_join_statistics() and co. can find it.
|
make_join_statistics() and co. can find it.
|
||||||
*/
|
*/
|
||||||
for (tl= parent_lex->leaf_tables; tl->next_leaf; tl= tl->next_leaf)
|
parent_lex->leaf_tables.push_back(jtbm);
|
||||||
{}
|
|
||||||
tl->next_leaf= jtbm;
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Same as above for TABLE_LIST::next_local chain
|
Same as above for TABLE_LIST::next_local chain
|
||||||
(a theory: a next_local chain always starts with ::leaf_tables
|
(a theory: a next_local chain always starts with ::leaf_tables
|
||||||
because view's tables are inserted after the view)
|
because view's tables are inserted after the view)
|
||||||
*/
|
*/
|
||||||
for (tl= parent_lex->leaf_tables; tl->next_local; tl= tl->next_local)
|
for (tl= parent_lex->leaf_tables.head(); tl->next_local; tl= tl->next_local)
|
||||||
{}
|
{}
|
||||||
tl->next_local= jtbm;
|
tl->next_local= jtbm;
|
||||||
|
|
||||||
@ -1451,7 +1462,6 @@ static TABLE_LIST *alloc_join_nest(THD *thd)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static
|
|
||||||
void fix_list_after_tbl_changes(SELECT_LEX *new_parent, List<TABLE_LIST> *tlist)
|
void fix_list_after_tbl_changes(SELECT_LEX *new_parent, List<TABLE_LIST> *tlist)
|
||||||
{
|
{
|
||||||
List_iterator<TABLE_LIST> it(*tlist);
|
List_iterator<TABLE_LIST> it(*tlist);
|
||||||
@ -2033,6 +2043,7 @@ void advance_sj_state(JOIN *join, table_map remaining_tables,
|
|||||||
TABLE_LIST *emb_sj_nest;
|
TABLE_LIST *emb_sj_nest;
|
||||||
POSITION *pos= join->positions + idx;
|
POSITION *pos= join->positions + idx;
|
||||||
remaining_tables &= ~new_join_tab->table->map;
|
remaining_tables &= ~new_join_tab->table->map;
|
||||||
|
bool disable_jbuf= join->thd->variables.join_cache_level == 0;
|
||||||
|
|
||||||
pos->prefix_cost.convert_from_cost(*current_read_time);
|
pos->prefix_cost.convert_from_cost(*current_read_time);
|
||||||
pos->prefix_record_count= *current_record_count;
|
pos->prefix_record_count= *current_record_count;
|
||||||
@ -2200,7 +2211,8 @@ void advance_sj_state(JOIN *join, table_map remaining_tables,
|
|||||||
optimize_wo_join_buffering(join, pos->first_loosescan_table, idx,
|
optimize_wo_join_buffering(join, pos->first_loosescan_table, idx,
|
||||||
remaining_tables,
|
remaining_tables,
|
||||||
TRUE, //first_alt
|
TRUE, //first_alt
|
||||||
pos->first_loosescan_table + n_tables,
|
disable_jbuf ? join->table_count :
|
||||||
|
pos->first_loosescan_table + n_tables,
|
||||||
current_record_count,
|
current_record_count,
|
||||||
current_read_time);
|
current_read_time);
|
||||||
/*
|
/*
|
||||||
@ -2339,8 +2351,8 @@ void advance_sj_state(JOIN *join, table_map remaining_tables,
|
|||||||
/* Need to re-run best-access-path as we prefix_rec_count has changed */
|
/* Need to re-run best-access-path as we prefix_rec_count has changed */
|
||||||
for (i= first_tab + mat_info->tables; i <= idx; i++)
|
for (i= first_tab + mat_info->tables; i <= idx; i++)
|
||||||
{
|
{
|
||||||
best_access_path(join, join->positions[i].table, rem_tables, i, FALSE,
|
best_access_path(join, join->positions[i].table, rem_tables, i,
|
||||||
prefix_rec_count, &curpos, &dummy);
|
disable_jbuf, prefix_rec_count, &curpos, &dummy);
|
||||||
prefix_rec_count *= curpos.records_read;
|
prefix_rec_count *= curpos.records_read;
|
||||||
prefix_cost += curpos.read_time;
|
prefix_cost += curpos.read_time;
|
||||||
}
|
}
|
||||||
@ -2699,8 +2711,9 @@ void fix_semijoin_strategies_for_picked_join_order(JOIN *join)
|
|||||||
join->cur_sj_inner_tables= 0;
|
join->cur_sj_inner_tables= 0;
|
||||||
for (i= first + sjm->tables; i <= tablenr; i++)
|
for (i= first + sjm->tables; i <= tablenr; i++)
|
||||||
{
|
{
|
||||||
best_access_path(join, join->best_positions[i].table, rem_tables, i, FALSE,
|
best_access_path(join, join->best_positions[i].table, rem_tables, i,
|
||||||
prefix_rec_count, join->best_positions + i, &dummy);
|
FALSE, prefix_rec_count,
|
||||||
|
join->best_positions + i, &dummy);
|
||||||
prefix_rec_count *= join->best_positions[i].records_read;
|
prefix_rec_count *= join->best_positions[i].records_read;
|
||||||
rem_tables &= ~join->best_positions[i].table->table->map;
|
rem_tables &= ~join->best_positions[i].table->table->map;
|
||||||
}
|
}
|
||||||
|
@ -74,10 +74,12 @@ static int maxmin_in_range(bool max_fl, Field* field, COND *cond);
|
|||||||
# Multiplication of number of rows in all tables
|
# Multiplication of number of rows in all tables
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static ulonglong get_exact_record_count(TABLE_LIST *tables)
|
static ulonglong get_exact_record_count(List<TABLE_LIST> &tables)
|
||||||
{
|
{
|
||||||
ulonglong count= 1;
|
ulonglong count= 1;
|
||||||
for (TABLE_LIST *tl= tables; tl; tl= tl->next_leaf)
|
TABLE_LIST *tl;
|
||||||
|
List_iterator<TABLE_LIST> ti(tables);
|
||||||
|
while ((tl= ti++))
|
||||||
{
|
{
|
||||||
ha_rows tmp= tl->table->file->records();
|
ha_rows tmp= tl->table->file->records();
|
||||||
if ((tmp == HA_POS_ERROR))
|
if ((tmp == HA_POS_ERROR))
|
||||||
@ -234,9 +236,11 @@ static int get_index_max_value(TABLE *table, TABLE_REF *ref, uint range_fl)
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
int opt_sum_query(THD *thd,
|
int opt_sum_query(THD *thd,
|
||||||
TABLE_LIST *tables, List<Item> &all_fields, COND *conds)
|
List<TABLE_LIST> &tables, List<Item> &all_fields, COND *conds)
|
||||||
{
|
{
|
||||||
List_iterator_fast<Item> it(all_fields);
|
List_iterator_fast<Item> it(all_fields);
|
||||||
|
List_iterator<TABLE_LIST> ti(tables);
|
||||||
|
TABLE_LIST *tl;
|
||||||
int const_result= 1;
|
int const_result= 1;
|
||||||
bool recalc_const_item= 0;
|
bool recalc_const_item= 0;
|
||||||
ulonglong count= 1;
|
ulonglong count= 1;
|
||||||
@ -244,7 +248,7 @@ int opt_sum_query(THD *thd,
|
|||||||
table_map removed_tables= 0, outer_tables= 0, used_tables= 0;
|
table_map removed_tables= 0, outer_tables= 0, used_tables= 0;
|
||||||
table_map where_tables= 0;
|
table_map where_tables= 0;
|
||||||
Item *item;
|
Item *item;
|
||||||
int error;
|
int error= 0;
|
||||||
DBUG_ENTER("opt_sum_query");
|
DBUG_ENTER("opt_sum_query");
|
||||||
|
|
||||||
if (conds)
|
if (conds)
|
||||||
@ -254,7 +258,7 @@ int opt_sum_query(THD *thd,
|
|||||||
Analyze outer join dependencies, and, if possible, compute the number
|
Analyze outer join dependencies, and, if possible, compute the number
|
||||||
of returned rows.
|
of returned rows.
|
||||||
*/
|
*/
|
||||||
for (TABLE_LIST *tl= tables; tl; tl= tl->next_leaf)
|
while ((tl= ti++))
|
||||||
{
|
{
|
||||||
TABLE_LIST *embedded;
|
TABLE_LIST *embedded;
|
||||||
for (embedded= tl ; embedded; embedded= embedded->embedding)
|
for (embedded= tl ; embedded; embedded= embedded->embedding)
|
||||||
@ -295,6 +299,14 @@ int opt_sum_query(THD *thd,
|
|||||||
is_exact_count= FALSE;
|
is_exact_count= FALSE;
|
||||||
count= 1; // ensure count != 0
|
count= 1; // ensure count != 0
|
||||||
}
|
}
|
||||||
|
else if (tl->is_materialized_derived())
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
Can't remove a derived table as it's number of rows is just an
|
||||||
|
estimate.
|
||||||
|
*/
|
||||||
|
DBUG_RETURN(0);
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
error= tl->table->file->info(HA_STATUS_VARIABLE | HA_STATUS_NO_LOCK);
|
error= tl->table->file->info(HA_STATUS_VARIABLE | HA_STATUS_NO_LOCK);
|
||||||
|
@ -299,7 +299,8 @@ void end_read_record(READ_RECORD *info)
|
|||||||
if (info->table)
|
if (info->table)
|
||||||
{
|
{
|
||||||
filesort_free_buffers(info->table,0);
|
filesort_free_buffers(info->table,0);
|
||||||
(void) info->file->extra(HA_EXTRA_NO_CACHE);
|
if (info->table->created)
|
||||||
|
(void) info->file->extra(HA_EXTRA_NO_CACHE);
|
||||||
if (info->read_record != rr_quick) // otherwise quick_range does it
|
if (info->read_record != rr_quick) // otherwise quick_range does it
|
||||||
(void) info->file->ha_index_or_rnd_end();
|
(void) info->file->ha_index_or_rnd_end();
|
||||||
info->table=0;
|
info->table=0;
|
||||||
|
@ -2835,6 +2835,9 @@ int sp_instr::exec_open_and_lock_tables(THD *thd, TABLE_LIST *tables)
|
|||||||
result= -1;
|
result= -1;
|
||||||
else
|
else
|
||||||
result= 0;
|
result= 0;
|
||||||
|
/* Prepare all derived tables/views to catch possible errors. */
|
||||||
|
if (!result)
|
||||||
|
result= mysql_handle_derived(thd->lex, DT_PREPARE) ? -1 : 0;
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
@ -3058,7 +3058,8 @@ int mysql_table_grant(THD *thd, TABLE_LIST *table_list,
|
|||||||
class LEX_COLUMN *column;
|
class LEX_COLUMN *column;
|
||||||
List_iterator <LEX_COLUMN> column_iter(columns);
|
List_iterator <LEX_COLUMN> column_iter(columns);
|
||||||
|
|
||||||
if (open_and_lock_tables(thd, table_list))
|
if (open_and_lock_tables(thd, table_list) ||
|
||||||
|
mysql_handle_derived(thd->lex, DT_PREPARE))
|
||||||
DBUG_RETURN(TRUE);
|
DBUG_RETURN(TRUE);
|
||||||
|
|
||||||
while ((column = column_iter++))
|
while ((column = column_iter++))
|
||||||
|
216
sql/sql_base.cc
216
sql/sql_base.cc
@ -3025,6 +3025,7 @@ TABLE *open_table(THD *thd, TABLE_LIST *table_list, MEM_ROOT *mem_root,
|
|||||||
*/
|
*/
|
||||||
DBUG_ASSERT(table->file->pushed_cond == NULL);
|
DBUG_ASSERT(table->file->pushed_cond == NULL);
|
||||||
table->reginfo.impossible_range= 0;
|
table->reginfo.impossible_range= 0;
|
||||||
|
table->created= TRUE;
|
||||||
/* Catch wrong handling of the auto_increment_field_not_null. */
|
/* Catch wrong handling of the auto_increment_field_not_null. */
|
||||||
DBUG_ASSERT(!table->auto_increment_field_not_null);
|
DBUG_ASSERT(!table->auto_increment_field_not_null);
|
||||||
table->auto_increment_field_not_null= FALSE;
|
table->auto_increment_field_not_null= FALSE;
|
||||||
@ -5122,9 +5123,10 @@ int open_and_lock_tables_derived(THD *thd, TABLE_LIST *tables, bool derived)
|
|||||||
close_tables_for_reopen(thd, &tables);
|
close_tables_for_reopen(thd, &tables);
|
||||||
}
|
}
|
||||||
if (derived &&
|
if (derived &&
|
||||||
(mysql_handle_derived(thd->lex, &mysql_derived_prepare) ||
|
(mysql_handle_derived(thd->lex, DT_INIT)))
|
||||||
(thd->fill_derived_tables() &&
|
DBUG_RETURN(TRUE); /* purecov: inspected */
|
||||||
mysql_handle_derived(thd->lex, &mysql_derived_filling))))
|
if (thd->prepare_derived_at_open && derived &&
|
||||||
|
(mysql_handle_derived(thd->lex, DT_PREPARE)))
|
||||||
DBUG_RETURN(TRUE); /* purecov: inspected */
|
DBUG_RETURN(TRUE); /* purecov: inspected */
|
||||||
DBUG_RETURN(0);
|
DBUG_RETURN(0);
|
||||||
}
|
}
|
||||||
@ -5140,6 +5142,7 @@ int open_and_lock_tables_derived(THD *thd, TABLE_LIST *tables, bool derived)
|
|||||||
flags - bitmap of flags to modify how the tables will be open:
|
flags - bitmap of flags to modify how the tables will be open:
|
||||||
MYSQL_LOCK_IGNORE_FLUSH - open table even if someone has
|
MYSQL_LOCK_IGNORE_FLUSH - open table even if someone has
|
||||||
done a flush on it.
|
done a flush on it.
|
||||||
|
dt_phases - set of flags to pass to the mysql_handle_derived
|
||||||
|
|
||||||
RETURN
|
RETURN
|
||||||
FALSE - ok
|
FALSE - ok
|
||||||
@ -5150,13 +5153,14 @@ int open_and_lock_tables_derived(THD *thd, TABLE_LIST *tables, bool derived)
|
|||||||
data from the tables.
|
data from the tables.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
bool open_normal_and_derived_tables(THD *thd, TABLE_LIST *tables, uint flags)
|
bool open_normal_and_derived_tables(THD *thd, TABLE_LIST *tables, uint flags,
|
||||||
|
uint dt_phases)
|
||||||
{
|
{
|
||||||
uint counter;
|
uint counter;
|
||||||
DBUG_ENTER("open_normal_and_derived_tables");
|
DBUG_ENTER("open_normal_and_derived_tables");
|
||||||
DBUG_ASSERT(!thd->fill_derived_tables());
|
DBUG_ASSERT(!thd->fill_derived_tables());
|
||||||
if (open_tables(thd, &tables, &counter, flags) ||
|
if (open_tables(thd, &tables, &counter, flags) ||
|
||||||
mysql_handle_derived(thd->lex, &mysql_derived_prepare))
|
mysql_handle_derived(thd->lex, dt_phases))
|
||||||
DBUG_RETURN(TRUE); /* purecov: inspected */
|
DBUG_RETURN(TRUE); /* purecov: inspected */
|
||||||
DBUG_RETURN(0);
|
DBUG_RETURN(0);
|
||||||
}
|
}
|
||||||
@ -5829,8 +5833,6 @@ find_field_in_view(THD *thd, TABLE_LIST *table_list,
|
|||||||
field_it.set(table_list);
|
field_it.set(table_list);
|
||||||
Query_arena *arena= 0, backup;
|
Query_arena *arena= 0, backup;
|
||||||
|
|
||||||
DBUG_ASSERT(table_list->schema_table_reformed ||
|
|
||||||
(ref != 0 && table_list->view != 0));
|
|
||||||
for (; !field_it.end_of_fields(); field_it.next())
|
for (; !field_it.end_of_fields(); field_it.next())
|
||||||
{
|
{
|
||||||
if (!my_strcasecmp(system_charset_info, field_it.name(), name))
|
if (!my_strcasecmp(system_charset_info, field_it.name(), name))
|
||||||
@ -5849,6 +5851,8 @@ find_field_in_view(THD *thd, TABLE_LIST *table_list,
|
|||||||
|
|
||||||
if (!item)
|
if (!item)
|
||||||
DBUG_RETURN(0);
|
DBUG_RETURN(0);
|
||||||
|
if (!ref)
|
||||||
|
DBUG_RETURN((Field*) view_ref_found);
|
||||||
/*
|
/*
|
||||||
*ref != NULL means that *ref contains the item that we need to
|
*ref != NULL means that *ref contains the item that we need to
|
||||||
replace. If the item was aliased by the user, set the alias to
|
replace. If the item was aliased by the user, set the alias to
|
||||||
@ -6253,6 +6257,8 @@ find_field_in_table_ref(THD *thd, TABLE_LIST *table_list,
|
|||||||
Field *field_to_set= NULL;
|
Field *field_to_set= NULL;
|
||||||
if (fld == view_ref_found)
|
if (fld == view_ref_found)
|
||||||
{
|
{
|
||||||
|
if (!ref)
|
||||||
|
DBUG_RETURN(fld);
|
||||||
Item *it= (*ref)->real_item();
|
Item *it= (*ref)->real_item();
|
||||||
if (it->type() == Item::FIELD_ITEM)
|
if (it->type() == Item::FIELD_ITEM)
|
||||||
field_to_set= ((Item_field*)it)->field;
|
field_to_set= ((Item_field*)it)->field;
|
||||||
@ -6260,6 +6266,8 @@ find_field_in_table_ref(THD *thd, TABLE_LIST *table_list,
|
|||||||
{
|
{
|
||||||
if (thd->mark_used_columns == MARK_COLUMNS_READ)
|
if (thd->mark_used_columns == MARK_COLUMNS_READ)
|
||||||
it->walk(&Item::register_field_in_read_map, 1, (uchar *) 0);
|
it->walk(&Item::register_field_in_read_map, 1, (uchar *) 0);
|
||||||
|
else
|
||||||
|
it->walk(&Item::register_field_in_write_map, 1, (uchar *) 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -6399,8 +6407,11 @@ find_field_in_tables(THD *thd, Item_ident *item,
|
|||||||
find_field_in_table even in the case of information schema tables
|
find_field_in_table even in the case of information schema tables
|
||||||
when table_ref->field_translation != NULL.
|
when table_ref->field_translation != NULL.
|
||||||
*/
|
*/
|
||||||
if (table_ref->table && !table_ref->view)
|
if (table_ref->table && !table_ref->view &&
|
||||||
|
(!table_ref->is_merged_derived() ||
|
||||||
|
(!table_ref->is_multitable() && table_ref->merged_for_insert)))
|
||||||
{
|
{
|
||||||
|
|
||||||
found= find_field_in_table(thd, table_ref->table, name, length,
|
found= find_field_in_table(thd, table_ref->table, name, length,
|
||||||
TRUE, &(item->cached_field_index));
|
TRUE, &(item->cached_field_index));
|
||||||
#ifndef NO_EMBEDDED_ACCESS_CHECKS
|
#ifndef NO_EMBEDDED_ACCESS_CHECKS
|
||||||
@ -6425,7 +6436,8 @@ find_field_in_tables(THD *thd, Item_ident *item,
|
|||||||
Only views fields should be marked as dependent, not an underlying
|
Only views fields should be marked as dependent, not an underlying
|
||||||
fields.
|
fields.
|
||||||
*/
|
*/
|
||||||
if (!table_ref->belong_to_view)
|
if (!table_ref->belong_to_view &&
|
||||||
|
!table_ref->belong_to_derived)
|
||||||
{
|
{
|
||||||
SELECT_LEX *current_sel= thd->lex->current_select;
|
SELECT_LEX *current_sel= thd->lex->current_select;
|
||||||
SELECT_LEX *last_select= table_ref->select_lex;
|
SELECT_LEX *last_select= table_ref->select_lex;
|
||||||
@ -7020,6 +7032,10 @@ mark_common_columns(THD *thd, TABLE_LIST *table_ref_1, TABLE_LIST *table_ref_2,
|
|||||||
*/
|
*/
|
||||||
if (nj_col_2 && (!using_fields ||is_using_column_1))
|
if (nj_col_2 && (!using_fields ||is_using_column_1))
|
||||||
{
|
{
|
||||||
|
/*
|
||||||
|
Create non-fixed fully qualified field and let fix_fields to
|
||||||
|
resolve it.
|
||||||
|
*/
|
||||||
Item *item_1= nj_col_1->create_item(thd);
|
Item *item_1= nj_col_1->create_item(thd);
|
||||||
Item *item_2= nj_col_2->create_item(thd);
|
Item *item_2= nj_col_2->create_item(thd);
|
||||||
Field *field_1= nj_col_1->field();
|
Field *field_1= nj_col_1->field();
|
||||||
@ -7468,7 +7484,11 @@ static bool setup_natural_join_row_types(THD *thd,
|
|||||||
for (left_neighbor= table_ref_it++; left_neighbor ; )
|
for (left_neighbor= table_ref_it++; left_neighbor ; )
|
||||||
{
|
{
|
||||||
table_ref= left_neighbor;
|
table_ref= left_neighbor;
|
||||||
left_neighbor= table_ref_it++;
|
do
|
||||||
|
{
|
||||||
|
left_neighbor= table_ref_it++;
|
||||||
|
}
|
||||||
|
while (left_neighbor && left_neighbor->sj_subq_pred);
|
||||||
/*
|
/*
|
||||||
Do not redo work if already done:
|
Do not redo work if already done:
|
||||||
1) for stored procedures,
|
1) for stored procedures,
|
||||||
@ -7683,27 +7703,36 @@ bool setup_fields(THD *thd, Item **ref_pointer_array,
|
|||||||
make_leaves_list()
|
make_leaves_list()
|
||||||
list pointer to pointer on list first element
|
list pointer to pointer on list first element
|
||||||
tables table list
|
tables table list
|
||||||
|
full_table_list whether to include tables from mergeable derived table/view.
|
||||||
|
we need them for checks for INSERT/UPDATE statements only.
|
||||||
|
|
||||||
RETURN pointer on pointer to next_leaf of last element
|
RETURN pointer on pointer to next_leaf of last element
|
||||||
*/
|
*/
|
||||||
|
|
||||||
TABLE_LIST **make_leaves_list(TABLE_LIST **list, TABLE_LIST *tables)
|
void make_leaves_list(List<TABLE_LIST> &list, TABLE_LIST *tables,
|
||||||
|
bool full_table_list, TABLE_LIST *boundary)
|
||||||
|
|
||||||
{
|
{
|
||||||
for (TABLE_LIST *table= tables; table; table= table->next_local)
|
for (TABLE_LIST *table= tables; table; table= table->next_local)
|
||||||
{
|
{
|
||||||
if (table->merge_underlying_list)
|
if (table == boundary)
|
||||||
|
full_table_list= !full_table_list;
|
||||||
|
if (full_table_list && table->is_merged_derived())
|
||||||
{
|
{
|
||||||
DBUG_ASSERT(table->view &&
|
SELECT_LEX *select_lex= table->get_single_select();
|
||||||
table->effective_algorithm == VIEW_ALGORITHM_MERGE);
|
/*
|
||||||
list= make_leaves_list(list, table->merge_underlying_list);
|
It's safe to use select_lex->leaf_tables because all derived
|
||||||
|
tables/views were already prepared and has their leaf_tables
|
||||||
|
set properly.
|
||||||
|
*/
|
||||||
|
make_leaves_list(list, select_lex->get_table_list(),
|
||||||
|
full_table_list, boundary);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
*list= table;
|
list.push_back(table);
|
||||||
list= &table->next_leaf;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return list;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -7718,6 +7747,7 @@ TABLE_LIST **make_leaves_list(TABLE_LIST **list, TABLE_LIST *tables)
|
|||||||
leaves List of join table leaves list (select_lex->leaf_tables)
|
leaves List of join table leaves list (select_lex->leaf_tables)
|
||||||
refresh It is onle refresh for subquery
|
refresh It is onle refresh for subquery
|
||||||
select_insert It is SELECT ... INSERT command
|
select_insert It is SELECT ... INSERT command
|
||||||
|
full_table_list a parameter to pass to the make_leaves_list function
|
||||||
|
|
||||||
NOTE
|
NOTE
|
||||||
Check also that the 'used keys' and 'ignored keys' exists and set up the
|
Check also that the 'used keys' and 'ignored keys' exists and set up the
|
||||||
@ -7736,9 +7766,13 @@ TABLE_LIST **make_leaves_list(TABLE_LIST **list, TABLE_LIST *tables)
|
|||||||
|
|
||||||
bool setup_tables(THD *thd, Name_resolution_context *context,
|
bool setup_tables(THD *thd, Name_resolution_context *context,
|
||||||
List<TABLE_LIST> *from_clause, TABLE_LIST *tables,
|
List<TABLE_LIST> *from_clause, TABLE_LIST *tables,
|
||||||
TABLE_LIST **leaves, bool select_insert)
|
List<TABLE_LIST> &leaves, bool select_insert,
|
||||||
|
bool full_table_list)
|
||||||
{
|
{
|
||||||
uint tablenr= 0;
|
uint tablenr= 0;
|
||||||
|
List_iterator<TABLE_LIST> ti(leaves);
|
||||||
|
TABLE_LIST *table_list;
|
||||||
|
|
||||||
DBUG_ENTER("setup_tables");
|
DBUG_ENTER("setup_tables");
|
||||||
|
|
||||||
DBUG_ASSERT ((select_insert && !tables->next_name_resolution_table) || !tables ||
|
DBUG_ASSERT ((select_insert && !tables->next_name_resolution_table) || !tables ||
|
||||||
@ -7750,49 +7784,66 @@ bool setup_tables(THD *thd, Name_resolution_context *context,
|
|||||||
TABLE_LIST *first_select_table= (select_insert ?
|
TABLE_LIST *first_select_table= (select_insert ?
|
||||||
tables->next_local:
|
tables->next_local:
|
||||||
0);
|
0);
|
||||||
if (!(*leaves))
|
SELECT_LEX *select_lex= select_insert ? &thd->lex->select_lex :
|
||||||
make_leaves_list(leaves, tables);
|
thd->lex->current_select;
|
||||||
|
if (select_lex->first_cond_optimization)
|
||||||
TABLE_LIST *table_list;
|
|
||||||
for (table_list= *leaves;
|
|
||||||
table_list;
|
|
||||||
table_list= table_list->next_leaf, tablenr++)
|
|
||||||
{
|
{
|
||||||
TABLE *table= table_list->table;
|
leaves.empty();
|
||||||
if (first_select_table &&
|
select_lex->leaf_tables_exec.empty();
|
||||||
table_list->top_table() == first_select_table)
|
make_leaves_list(leaves, tables, full_table_list, first_select_table);
|
||||||
{
|
|
||||||
/* new counting for SELECT of INSERT ... SELECT command */
|
|
||||||
first_select_table= 0;
|
|
||||||
tablenr= 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (table_list->jtbm_subselect)
|
while ((table_list= ti++))
|
||||||
{
|
|
||||||
table_list->jtbm_table_no= tablenr;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
{
|
||||||
|
TABLE *table= table_list->table;
|
||||||
table->pos_in_table_list= table_list;
|
table->pos_in_table_list= table_list;
|
||||||
setup_table_map(table, table_list, tablenr);
|
if (first_select_table &&
|
||||||
|
table_list->top_table() == first_select_table)
|
||||||
|
{
|
||||||
|
/* new counting for SELECT of INSERT ... SELECT command */
|
||||||
|
first_select_table= 0;
|
||||||
|
thd->lex->select_lex.insert_tables= tablenr;
|
||||||
|
tablenr= 0;
|
||||||
|
}
|
||||||
|
if(table_list->jtbm_subselect)
|
||||||
|
{
|
||||||
|
table_list->jtbm_table_no= tablenr;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
table->pos_in_table_list= table_list;
|
||||||
|
setup_table_map(table, table_list, tablenr);
|
||||||
|
|
||||||
if (table_list->process_index_hints(table))
|
if (table_list->process_index_hints(table))
|
||||||
DBUG_RETURN(1);
|
DBUG_RETURN(1);
|
||||||
|
}
|
||||||
|
tablenr++;
|
||||||
|
}
|
||||||
|
if (tablenr > MAX_TABLES)
|
||||||
|
{
|
||||||
|
my_error(ER_TOO_MANY_TABLES,MYF(0),MAX_TABLES);
|
||||||
|
DBUG_RETURN(1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (tablenr > MAX_TABLES)
|
else
|
||||||
{
|
{
|
||||||
my_error(ER_TOO_MANY_TABLES,MYF(0),MAX_TABLES);
|
List_iterator_fast <TABLE_LIST> ti(select_lex->leaf_tables_exec);
|
||||||
DBUG_RETURN(1);
|
select_lex->leaf_tables.empty();
|
||||||
|
while ((table_list= ti++))
|
||||||
|
{
|
||||||
|
table_list->table->tablenr= table_list->tablenr_exec;
|
||||||
|
table_list->table->map= table_list->map_exec;
|
||||||
|
table_list->table->pos_in_table_list= table_list;
|
||||||
|
select_lex->leaf_tables.push_back(table_list);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for (table_list= tables;
|
for (table_list= tables;
|
||||||
table_list;
|
table_list;
|
||||||
table_list= table_list->next_local)
|
table_list= table_list->next_local)
|
||||||
{
|
{
|
||||||
if (table_list->merge_underlying_list)
|
if (table_list->merge_underlying_list)
|
||||||
{
|
{
|
||||||
DBUG_ASSERT(table_list->view &&
|
DBUG_ASSERT(table_list->is_merged_derived());
|
||||||
table_list->effective_algorithm == VIEW_ALGORITHM_MERGE);
|
|
||||||
Query_arena *arena= thd->stmt_arena, backup;
|
Query_arena *arena= thd->stmt_arena, backup;
|
||||||
bool res;
|
bool res;
|
||||||
if (arena->is_conventional())
|
if (arena->is_conventional())
|
||||||
@ -7830,7 +7881,7 @@ bool setup_tables(THD *thd, Name_resolution_context *context,
|
|||||||
prepare tables and check access for the view tables
|
prepare tables and check access for the view tables
|
||||||
|
|
||||||
SYNOPSIS
|
SYNOPSIS
|
||||||
setup_tables_and_check_view_access()
|
setup_tables_and_check_access()
|
||||||
thd Thread handler
|
thd Thread handler
|
||||||
context name resolution contest to setup table list there
|
context name resolution contest to setup table list there
|
||||||
from_clause Top-level list of table references in the FROM clause
|
from_clause Top-level list of table references in the FROM clause
|
||||||
@ -7840,6 +7891,7 @@ bool setup_tables(THD *thd, Name_resolution_context *context,
|
|||||||
refresh It is onle refresh for subquery
|
refresh It is onle refresh for subquery
|
||||||
select_insert It is SELECT ... INSERT command
|
select_insert It is SELECT ... INSERT command
|
||||||
want_access what access is needed
|
want_access what access is needed
|
||||||
|
full_table_list a parameter to pass to the make_leaves_list function
|
||||||
|
|
||||||
NOTE
|
NOTE
|
||||||
a wrapper for check_tables that will also check the resulting
|
a wrapper for check_tables that will also check the resulting
|
||||||
@ -7853,27 +7905,26 @@ bool setup_tables_and_check_access(THD *thd,
|
|||||||
Name_resolution_context *context,
|
Name_resolution_context *context,
|
||||||
List<TABLE_LIST> *from_clause,
|
List<TABLE_LIST> *from_clause,
|
||||||
TABLE_LIST *tables,
|
TABLE_LIST *tables,
|
||||||
TABLE_LIST **leaves,
|
List<TABLE_LIST> &leaves,
|
||||||
bool select_insert,
|
bool select_insert,
|
||||||
ulong want_access_first,
|
ulong want_access_first,
|
||||||
ulong want_access)
|
ulong want_access,
|
||||||
|
bool full_table_list)
|
||||||
{
|
{
|
||||||
TABLE_LIST *leaves_tmp= NULL;
|
|
||||||
bool first_table= true;
|
bool first_table= true;
|
||||||
DBUG_ENTER("setup_tables_and_check_access");
|
DBUG_ENTER("setup_tables_and_check_access");
|
||||||
|
|
||||||
if (setup_tables(thd, context, from_clause, tables,
|
if (setup_tables(thd, context, from_clause, tables,
|
||||||
&leaves_tmp, select_insert))
|
leaves, select_insert, full_table_list))
|
||||||
DBUG_RETURN(TRUE);
|
DBUG_RETURN(TRUE);
|
||||||
|
|
||||||
if (leaves)
|
List_iterator<TABLE_LIST> ti(leaves);
|
||||||
*leaves= leaves_tmp;
|
TABLE_LIST *table_list;
|
||||||
|
while((table_list= ti++))
|
||||||
for (; leaves_tmp; leaves_tmp= leaves_tmp->next_leaf)
|
|
||||||
{
|
{
|
||||||
if (leaves_tmp->belong_to_view &&
|
if (table_list->belong_to_view && !table_list->view &&
|
||||||
check_single_table_access(thd, first_table ? want_access_first :
|
check_single_table_access(thd, first_table ? want_access_first :
|
||||||
want_access, leaves_tmp, FALSE))
|
want_access, table_list, FALSE))
|
||||||
{
|
{
|
||||||
tables->hide_view_error(thd);
|
tables->hide_view_error(thd);
|
||||||
DBUG_RETURN(TRUE);
|
DBUG_RETURN(TRUE);
|
||||||
@ -8016,8 +8067,10 @@ insert_fields(THD *thd, Name_resolution_context *context, const char *db_name,
|
|||||||
information_schema table, or a nested table reference. See the comment
|
information_schema table, or a nested table reference. See the comment
|
||||||
for TABLE_LIST.
|
for TABLE_LIST.
|
||||||
*/
|
*/
|
||||||
if (!((table && !tables->view && (table->grant.privilege & SELECT_ACL)) ||
|
if (!((table && tables->is_non_derived() &&
|
||||||
(tables->view && (tables->grant.privilege & SELECT_ACL))) &&
|
(table->grant.privilege & SELECT_ACL)) ||
|
||||||
|
((!tables->is_non_derived() &&
|
||||||
|
(tables->grant.privilege & SELECT_ACL)))) &&
|
||||||
!any_privileges)
|
!any_privileges)
|
||||||
{
|
{
|
||||||
field_iterator.set(tables);
|
field_iterator.set(tables);
|
||||||
@ -8047,7 +8100,7 @@ insert_fields(THD *thd, Name_resolution_context *context, const char *db_name,
|
|||||||
|
|
||||||
if (!(item= field_iterator.create_item(thd)))
|
if (!(item= field_iterator.create_item(thd)))
|
||||||
DBUG_RETURN(TRUE);
|
DBUG_RETURN(TRUE);
|
||||||
DBUG_ASSERT(item->fixed);
|
// DBUG_ASSERT(item->fixed);
|
||||||
/* cache the table for the Item_fields inserted by expanding stars */
|
/* cache the table for the Item_fields inserted by expanding stars */
|
||||||
if (item->type() == Item::FIELD_ITEM && tables->cacheable_table)
|
if (item->type() == Item::FIELD_ITEM && tables->cacheable_table)
|
||||||
((Item_field *)item)->cached_table= tables;
|
((Item_field *)item)->cached_table= tables;
|
||||||
@ -8200,13 +8253,14 @@ void wrap_ident(THD *thd, Item **conds)
|
|||||||
FALSE if all is OK
|
FALSE if all is OK
|
||||||
*/
|
*/
|
||||||
|
|
||||||
int setup_conds(THD *thd, TABLE_LIST *tables, TABLE_LIST *leaves,
|
int setup_conds(THD *thd, TABLE_LIST *tables, List<TABLE_LIST> &leaves,
|
||||||
COND **conds)
|
COND **conds)
|
||||||
{
|
{
|
||||||
SELECT_LEX *select_lex= thd->lex->current_select;
|
SELECT_LEX *select_lex= thd->lex->current_select;
|
||||||
Query_arena *arena= thd->stmt_arena, backup;
|
Query_arena *arena= thd->stmt_arena, backup;
|
||||||
TABLE_LIST *table= NULL; // For HP compilers
|
TABLE_LIST *table= NULL; // For HP compilers
|
||||||
TABLE_LIST *save_emb_on_expr_nest= thd->thd_marker.emb_on_expr_nest;
|
TABLE_LIST *save_emb_on_expr_nest= thd->thd_marker.emb_on_expr_nest;
|
||||||
|
List_iterator<TABLE_LIST> ti(leaves);
|
||||||
/*
|
/*
|
||||||
it_is_update set to TRUE when tables of primary SELECT_LEX (SELECT_LEX
|
it_is_update set to TRUE when tables of primary SELECT_LEX (SELECT_LEX
|
||||||
which belong to LEX, i.e. most up SELECT) will be updated by
|
which belong to LEX, i.e. most up SELECT) will be updated by
|
||||||
@ -8218,9 +8272,15 @@ int setup_conds(THD *thd, TABLE_LIST *tables, TABLE_LIST *leaves,
|
|||||||
bool it_is_update= (select_lex == &thd->lex->select_lex) &&
|
bool it_is_update= (select_lex == &thd->lex->select_lex) &&
|
||||||
thd->lex->which_check_option_applicable();
|
thd->lex->which_check_option_applicable();
|
||||||
bool save_is_item_list_lookup= select_lex->is_item_list_lookup;
|
bool save_is_item_list_lookup= select_lex->is_item_list_lookup;
|
||||||
select_lex->is_item_list_lookup= 0;
|
TABLE_LIST *derived= select_lex->master_unit()->derived;
|
||||||
DBUG_ENTER("setup_conds");
|
DBUG_ENTER("setup_conds");
|
||||||
|
|
||||||
|
/* Do not fix conditions for the derived tables that have been merged */
|
||||||
|
if (derived && derived->merged)
|
||||||
|
DBUG_RETURN(0);
|
||||||
|
|
||||||
|
select_lex->is_item_list_lookup= 0;
|
||||||
|
|
||||||
if (select_lex->conds_processed_with_permanent_arena ||
|
if (select_lex->conds_processed_with_permanent_arena ||
|
||||||
arena->is_conventional())
|
arena->is_conventional())
|
||||||
arena= 0; // For easier test
|
arena= 0; // For easier test
|
||||||
@ -8233,7 +8293,10 @@ int setup_conds(THD *thd, TABLE_LIST *tables, TABLE_LIST *leaves,
|
|||||||
|
|
||||||
for (table= tables; table; table= table->next_local)
|
for (table= tables; table; table= table->next_local)
|
||||||
{
|
{
|
||||||
if (table->prepare_where(thd, conds, FALSE))
|
if (select_lex == &thd->lex->select_lex &&
|
||||||
|
select_lex->first_cond_optimization &&
|
||||||
|
table->merged_for_insert &&
|
||||||
|
table->prepare_where(thd, conds, FALSE))
|
||||||
goto err_no_arena;
|
goto err_no_arena;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -8249,7 +8312,7 @@ int setup_conds(THD *thd, TABLE_LIST *tables, TABLE_LIST *leaves,
|
|||||||
Wrap alone field in WHERE clause in case it will be outer field of subquery
|
Wrap alone field in WHERE clause in case it will be outer field of subquery
|
||||||
which need persistent pointer on it, but conds could be changed by optimizer
|
which need persistent pointer on it, but conds could be changed by optimizer
|
||||||
*/
|
*/
|
||||||
if ((*conds)->type() == Item::FIELD_ITEM)
|
if ((*conds)->type() == Item::FIELD_ITEM && !derived)
|
||||||
wrap_ident(thd, conds);
|
wrap_ident(thd, conds);
|
||||||
if ((!(*conds)->fixed && (*conds)->fix_fields(thd, conds)) ||
|
if ((!(*conds)->fixed && (*conds)->fix_fields(thd, conds)) ||
|
||||||
(*conds)->check_cols(1))
|
(*conds)->check_cols(1))
|
||||||
@ -8261,7 +8324,7 @@ int setup_conds(THD *thd, TABLE_LIST *tables, TABLE_LIST *leaves,
|
|||||||
Apply fix_fields() to all ON clauses at all levels of nesting,
|
Apply fix_fields() to all ON clauses at all levels of nesting,
|
||||||
including the ones inside view definitions.
|
including the ones inside view definitions.
|
||||||
*/
|
*/
|
||||||
for (table= leaves; table; table= table->next_leaf)
|
while ((table= ti++))
|
||||||
{
|
{
|
||||||
TABLE_LIST *embedded; /* The table at the current level of nesting. */
|
TABLE_LIST *embedded; /* The table at the current level of nesting. */
|
||||||
TABLE_LIST *embedding= table; /* The parent nested table reference. */
|
TABLE_LIST *embedding= table; /* The parent nested table reference. */
|
||||||
@ -9455,6 +9518,27 @@ void close_performance_schema_table(THD *thd, Open_tables_state *backup)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
@brief
|
||||||
|
Remove 'fixed' flag from items in a list
|
||||||
|
|
||||||
|
@param items list of items to un-fix
|
||||||
|
|
||||||
|
@details
|
||||||
|
This function sets to 0 the 'fixed' flag for items in the 'items' list.
|
||||||
|
It's needed to force correct marking of views' fields for INSERT/UPDATE
|
||||||
|
statements.
|
||||||
|
*/
|
||||||
|
|
||||||
|
void unfix_fields(List<Item> &fields)
|
||||||
|
{
|
||||||
|
List_iterator<Item> li(fields);
|
||||||
|
Item *item;
|
||||||
|
while ((item= li++))
|
||||||
|
item->fixed= 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Check result of dynamic column function and issue error if it is needed
|
Check result of dynamic column function and issue error if it is needed
|
||||||
|
|
||||||
|
@ -91,6 +91,10 @@ public:
|
|||||||
DBUG_ASSERT(sizeof(buffer) >= 4);
|
DBUG_ASSERT(sizeof(buffer) >= 4);
|
||||||
return (ulonglong) uint4korr(buffer);
|
return (ulonglong) uint4korr(buffer);
|
||||||
}
|
}
|
||||||
|
uint bits_set()
|
||||||
|
{
|
||||||
|
return bitmap_bits_set(&map);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
/* An iterator to quickly walk over bits in unlonglong bitmap. */
|
/* An iterator to quickly walk over bits in unlonglong bitmap. */
|
||||||
@ -169,5 +173,16 @@ public:
|
|||||||
public:
|
public:
|
||||||
Iterator(Bitmap<64> &bmp) : Table_map_iterator(bmp.map) {}
|
Iterator(Bitmap<64> &bmp) : Table_map_iterator(bmp.map) {}
|
||||||
};
|
};
|
||||||
|
uint bits_set()
|
||||||
|
{
|
||||||
|
//TODO: use my_count_bits()
|
||||||
|
uint res= 0, i= 0;
|
||||||
|
for (; i < 64 ; i++)
|
||||||
|
{
|
||||||
|
if (map & ((ulonglong)1<<i))
|
||||||
|
res++;
|
||||||
|
}
|
||||||
|
return res;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -3853,16 +3853,17 @@ Query_cache::process_and_count_tables(THD *thd, TABLE_LIST *tables_used,
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
DBUG_PRINT("qcache", ("table: %s db: %s type: %u",
|
|
||||||
tables_used->table->s->table_name.str,
|
|
||||||
tables_used->table->s->db.str,
|
|
||||||
tables_used->table->s->db_type()->db_type));
|
|
||||||
if (tables_used->derived)
|
if (tables_used->derived)
|
||||||
{
|
{
|
||||||
|
DBUG_PRINT("qcache", ("table: %s", tables_used->alias));
|
||||||
table_count--;
|
table_count--;
|
||||||
DBUG_PRINT("qcache", ("derived table skipped"));
|
DBUG_PRINT("qcache", ("derived table skipped"));
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
DBUG_PRINT("qcache", ("table: %s db: %s type: %u",
|
||||||
|
tables_used->table->s->table_name.str,
|
||||||
|
tables_used->table->s->db.str,
|
||||||
|
tables_used->table->s->db_type()->db_type));
|
||||||
*tables_type|= tables_used->table->file->table_cache_type();
|
*tables_type|= tables_used->table->file->table_cache_type();
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -813,6 +813,7 @@ THD::THD()
|
|||||||
m_binlog_invoker= FALSE;
|
m_binlog_invoker= FALSE;
|
||||||
memset(&invoker_user, 0, sizeof(invoker_user));
|
memset(&invoker_user, 0, sizeof(invoker_user));
|
||||||
memset(&invoker_host, 0, sizeof(invoker_host));
|
memset(&invoker_host, 0, sizeof(invoker_host));
|
||||||
|
prepare_derived_at_open= FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -3047,7 +3048,8 @@ bool
|
|||||||
select_materialize_with_stats::
|
select_materialize_with_stats::
|
||||||
create_result_table(THD *thd_arg, List<Item> *column_types,
|
create_result_table(THD *thd_arg, List<Item> *column_types,
|
||||||
bool is_union_distinct, ulonglong options,
|
bool is_union_distinct, ulonglong options,
|
||||||
const char *table_alias, bool bit_fields_as_long)
|
const char *table_alias, bool bit_fields_as_long,
|
||||||
|
bool create_table)
|
||||||
{
|
{
|
||||||
DBUG_ASSERT(table == 0);
|
DBUG_ASSERT(table == 0);
|
||||||
tmp_table_param.field_count= column_types->elements;
|
tmp_table_param.field_count= column_types->elements;
|
||||||
|
@ -1568,6 +1568,9 @@ public:
|
|||||||
*/
|
*/
|
||||||
TABLE_LIST *emb_on_expr_nest;
|
TABLE_LIST *emb_on_expr_nest;
|
||||||
} thd_marker;
|
} thd_marker;
|
||||||
|
|
||||||
|
bool prepare_derived_at_open;
|
||||||
|
|
||||||
#ifndef MYSQL_CLIENT
|
#ifndef MYSQL_CLIENT
|
||||||
int binlog_setup_trx_data();
|
int binlog_setup_trx_data();
|
||||||
|
|
||||||
@ -3056,13 +3059,14 @@ public:
|
|||||||
|
|
||||||
class select_union :public select_result_interceptor
|
class select_union :public select_result_interceptor
|
||||||
{
|
{
|
||||||
protected:
|
public:
|
||||||
TMP_TABLE_PARAM tmp_table_param;
|
TMP_TABLE_PARAM tmp_table_param;
|
||||||
int write_err; /* Error code from the last send_data->ha_write_row call. */
|
int write_err; /* Error code from the last send_data->ha_write_row call. */
|
||||||
public:
|
public:
|
||||||
TABLE *table;
|
TABLE *table;
|
||||||
|
ha_rows records;
|
||||||
|
|
||||||
select_union() :write_err(0),table(0) { tmp_table_param.init(); }
|
select_union() :write_err(0), table(0), records(0) { tmp_table_param.init(); }
|
||||||
int prepare(List<Item> &list, SELECT_LEX_UNIT *u);
|
int prepare(List<Item> &list, SELECT_LEX_UNIT *u);
|
||||||
int send_data(List<Item> &items);
|
int send_data(List<Item> &items);
|
||||||
bool send_eof();
|
bool send_eof();
|
||||||
@ -3070,7 +3074,9 @@ public:
|
|||||||
void cleanup();
|
void cleanup();
|
||||||
virtual bool create_result_table(THD *thd, List<Item> *column_types,
|
virtual bool create_result_table(THD *thd, List<Item> *column_types,
|
||||||
bool is_distinct, ulonglong options,
|
bool is_distinct, ulonglong options,
|
||||||
const char *alias, bool bit_fields_as_long);
|
const char *alias,
|
||||||
|
bool bit_fields_as_long,
|
||||||
|
bool create_table);
|
||||||
TMP_TABLE_PARAM *get_tmp_table_param() { return &tmp_table_param; }
|
TMP_TABLE_PARAM *get_tmp_table_param() { return &tmp_table_param; }
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -3136,9 +3142,11 @@ protected:
|
|||||||
|
|
||||||
public:
|
public:
|
||||||
select_materialize_with_stats() { tmp_table_param.init(); }
|
select_materialize_with_stats() { tmp_table_param.init(); }
|
||||||
virtual bool create_result_table(THD *thd, List<Item> *column_types,
|
bool create_result_table(THD *thd, List<Item> *column_types,
|
||||||
bool is_distinct, ulonglong options,
|
bool is_distinct, ulonglong options,
|
||||||
const char *alias, bool bit_fields_as_long);
|
const char *alias,
|
||||||
|
bool bit_fields_as_long,
|
||||||
|
bool create_table);
|
||||||
bool init_result_table(ulonglong select_options);
|
bool init_result_table(ulonglong select_options);
|
||||||
int send_data(List<Item> &items);
|
int send_data(List<Item> &items);
|
||||||
void cleanup();
|
void cleanup();
|
||||||
@ -3446,7 +3454,7 @@ public:
|
|||||||
class multi_update :public select_result_interceptor
|
class multi_update :public select_result_interceptor
|
||||||
{
|
{
|
||||||
TABLE_LIST *all_tables; /* query/update command tables */
|
TABLE_LIST *all_tables; /* query/update command tables */
|
||||||
TABLE_LIST *leaves; /* list of leves of join table tree */
|
List<TABLE_LIST> *leaves; /* list of leves of join table tree */
|
||||||
TABLE_LIST *update_tables, *table_being_updated;
|
TABLE_LIST *update_tables, *table_being_updated;
|
||||||
TABLE **tmp_tables, *main_table, *table_to_update;
|
TABLE **tmp_tables, *main_table, *table_to_update;
|
||||||
TMP_TABLE_PARAM *tmp_table_param;
|
TMP_TABLE_PARAM *tmp_table_param;
|
||||||
@ -3472,7 +3480,7 @@ class multi_update :public select_result_interceptor
|
|||||||
bool error_handled;
|
bool error_handled;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
multi_update(TABLE_LIST *ut, TABLE_LIST *leaves_list,
|
multi_update(TABLE_LIST *ut, List<TABLE_LIST> *leaves_list,
|
||||||
List<Item> *fields, List<Item> *values,
|
List<Item> *fields, List<Item> *values,
|
||||||
enum_duplicates handle_duplicates, bool ignore);
|
enum_duplicates handle_duplicates, bool ignore);
|
||||||
~multi_update();
|
~multi_update();
|
||||||
|
@ -722,8 +722,8 @@ bool Select_materialize::send_fields(List<Item> &list, uint flags)
|
|||||||
DBUG_ASSERT(table == 0);
|
DBUG_ASSERT(table == 0);
|
||||||
if (create_result_table(unit->thd, unit->get_unit_column_types(),
|
if (create_result_table(unit->thd, unit->get_unit_column_types(),
|
||||||
FALSE, thd->options | TMP_TABLE_ALL_COLUMNS, "",
|
FALSE, thd->options | TMP_TABLE_ALL_COLUMNS, "",
|
||||||
FALSE))
|
FALSE, TRUE))
|
||||||
return TRUE;
|
return TRUE;
|
||||||
|
|
||||||
materialized_cursor= new (&table->mem_root)
|
materialized_cursor= new (&table->mem_root)
|
||||||
Materialized_cursor(result, table);
|
Materialized_cursor(result, table);
|
||||||
|
@ -60,10 +60,20 @@ bool mysql_delete(THD *thd, TABLE_LIST *table_list, COND *conds,
|
|||||||
|
|
||||||
if (open_and_lock_tables(thd, table_list))
|
if (open_and_lock_tables(thd, table_list))
|
||||||
DBUG_RETURN(TRUE);
|
DBUG_RETURN(TRUE);
|
||||||
if (!(table= table_list->table))
|
|
||||||
|
if (mysql_handle_list_of_derived(thd->lex, table_list, DT_MERGE_FOR_INSERT) ||
|
||||||
|
mysql_handle_list_of_derived(thd->lex, table_list, DT_PREPARE))
|
||||||
|
DBUG_RETURN(TRUE);
|
||||||
|
|
||||||
|
if (!table_list->updatable)
|
||||||
{
|
{
|
||||||
my_error(ER_VIEW_DELETE_MERGE_VIEW, MYF(0),
|
my_error(ER_NON_UPDATABLE_TABLE, MYF(0), table_list->alias, "DELETE");
|
||||||
table_list->view_db.str, table_list->view_name.str);
|
DBUG_RETURN(TRUE);
|
||||||
|
}
|
||||||
|
if (!(table= table_list->table) || !table->created)
|
||||||
|
{
|
||||||
|
my_error(ER_VIEW_DELETE_MERGE_VIEW, MYF(0),
|
||||||
|
table_list->view_db.str, table_list->view_name.str);
|
||||||
DBUG_RETURN(TRUE);
|
DBUG_RETURN(TRUE);
|
||||||
}
|
}
|
||||||
thd_proc_info(thd, "init");
|
thd_proc_info(thd, "init");
|
||||||
@ -72,6 +82,11 @@ bool mysql_delete(THD *thd, TABLE_LIST *table_list, COND *conds,
|
|||||||
if (mysql_prepare_delete(thd, table_list, &conds))
|
if (mysql_prepare_delete(thd, table_list, &conds))
|
||||||
DBUG_RETURN(TRUE);
|
DBUG_RETURN(TRUE);
|
||||||
|
|
||||||
|
if (thd->lex->current_select->first_cond_optimization)
|
||||||
|
{
|
||||||
|
thd->lex->current_select->save_leaf_tables(thd);
|
||||||
|
thd->lex->current_select->first_cond_optimization= 0;
|
||||||
|
}
|
||||||
/* check ORDER BY even if it can be ignored */
|
/* check ORDER BY even if it can be ignored */
|
||||||
if (order && order->elements)
|
if (order && order->elements)
|
||||||
{
|
{
|
||||||
@ -405,6 +420,12 @@ cleanup:
|
|||||||
query_cache_invalidate3(thd, table_list, 1);
|
query_cache_invalidate3(thd, table_list, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (thd->lex->current_select->first_cond_optimization)
|
||||||
|
{
|
||||||
|
thd->lex->current_select->save_leaf_tables(thd);
|
||||||
|
thd->lex->current_select->first_cond_optimization= 0;
|
||||||
|
}
|
||||||
|
|
||||||
delete select;
|
delete select;
|
||||||
transactional_table= table->file->has_transactions();
|
transactional_table= table->file->has_transactions();
|
||||||
|
|
||||||
@ -506,8 +527,8 @@ int mysql_prepare_delete(THD *thd, TABLE_LIST *table_list, Item **conds)
|
|||||||
if (setup_tables_and_check_access(thd, &thd->lex->select_lex.context,
|
if (setup_tables_and_check_access(thd, &thd->lex->select_lex.context,
|
||||||
&thd->lex->select_lex.top_join_list,
|
&thd->lex->select_lex.top_join_list,
|
||||||
table_list,
|
table_list,
|
||||||
&select_lex->leaf_tables, FALSE,
|
select_lex->leaf_tables, FALSE,
|
||||||
DELETE_ACL, SELECT_ACL) ||
|
DELETE_ACL, SELECT_ACL, TRUE) ||
|
||||||
setup_conds(thd, table_list, select_lex->leaf_tables, conds) ||
|
setup_conds(thd, table_list, select_lex->leaf_tables, conds) ||
|
||||||
setup_ftfuncs(select_lex))
|
setup_ftfuncs(select_lex))
|
||||||
DBUG_RETURN(TRUE);
|
DBUG_RETURN(TRUE);
|
||||||
@ -565,6 +586,11 @@ int mysql_multi_delete_prepare(THD *thd)
|
|||||||
TABLE_LIST *target_tbl;
|
TABLE_LIST *target_tbl;
|
||||||
DBUG_ENTER("mysql_multi_delete_prepare");
|
DBUG_ENTER("mysql_multi_delete_prepare");
|
||||||
|
|
||||||
|
TABLE_LIST *tables= lex->query_tables;
|
||||||
|
if (mysql_handle_derived(lex, DT_INIT) ||
|
||||||
|
mysql_handle_list_of_derived(lex, tables, DT_MERGE_FOR_INSERT) ||
|
||||||
|
mysql_handle_list_of_derived(lex, tables, DT_PREPARE))
|
||||||
|
DBUG_RETURN(TRUE);
|
||||||
/*
|
/*
|
||||||
setup_tables() need for VIEWs. JOIN::prepare() will not do it second
|
setup_tables() need for VIEWs. JOIN::prepare() will not do it second
|
||||||
time.
|
time.
|
||||||
@ -574,8 +600,8 @@ int mysql_multi_delete_prepare(THD *thd)
|
|||||||
if (setup_tables_and_check_access(thd, &thd->lex->select_lex.context,
|
if (setup_tables_and_check_access(thd, &thd->lex->select_lex.context,
|
||||||
&thd->lex->select_lex.top_join_list,
|
&thd->lex->select_lex.top_join_list,
|
||||||
lex->query_tables,
|
lex->query_tables,
|
||||||
&lex->select_lex.leaf_tables, FALSE,
|
lex->select_lex.leaf_tables, FALSE,
|
||||||
DELETE_ACL, SELECT_ACL))
|
DELETE_ACL, SELECT_ACL, TRUE))
|
||||||
DBUG_RETURN(TRUE);
|
DBUG_RETURN(TRUE);
|
||||||
|
|
||||||
|
|
||||||
@ -589,16 +615,13 @@ int mysql_multi_delete_prepare(THD *thd)
|
|||||||
target_tbl;
|
target_tbl;
|
||||||
target_tbl= target_tbl->next_local)
|
target_tbl= target_tbl->next_local)
|
||||||
{
|
{
|
||||||
|
|
||||||
if (!(target_tbl->table= target_tbl->correspondent_table->table))
|
if (!(target_tbl->table= target_tbl->correspondent_table->table))
|
||||||
{
|
{
|
||||||
DBUG_ASSERT(target_tbl->correspondent_table->view &&
|
my_error(ER_VIEW_DELETE_MERGE_VIEW, MYF(0),
|
||||||
target_tbl->correspondent_table->merge_underlying_list &&
|
target_tbl->correspondent_table->view_db.str,
|
||||||
target_tbl->correspondent_table->merge_underlying_list->
|
target_tbl->correspondent_table->view_name.str);
|
||||||
next_local);
|
DBUG_RETURN(TRUE);
|
||||||
my_error(ER_VIEW_DELETE_MERGE_VIEW, MYF(0),
|
|
||||||
target_tbl->correspondent_table->view_db.str,
|
|
||||||
target_tbl->correspondent_table->view_name.str);
|
|
||||||
DBUG_RETURN(TRUE);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!target_tbl->correspondent_table->updatable ||
|
if (!target_tbl->correspondent_table->updatable ||
|
||||||
@ -648,6 +671,12 @@ multi_delete::prepare(List<Item> &values, SELECT_LEX_UNIT *u)
|
|||||||
unit= u;
|
unit= u;
|
||||||
do_delete= 1;
|
do_delete= 1;
|
||||||
thd_proc_info(thd, "deleting from main table");
|
thd_proc_info(thd, "deleting from main table");
|
||||||
|
SELECT_LEX *select_lex= u->first_select();
|
||||||
|
if (select_lex->first_cond_optimization)
|
||||||
|
{
|
||||||
|
if (select_lex->handle_derived(thd->lex, DT_MERGE))
|
||||||
|
DBUG_RETURN(TRUE);
|
||||||
|
}
|
||||||
DBUG_RETURN(0);
|
DBUG_RETURN(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -109,7 +109,8 @@ void Expression_cache_tmptable::init()
|
|||||||
~(OPTION_BIG_TABLES |
|
~(OPTION_BIG_TABLES |
|
||||||
TMP_TABLE_FORCE_MYISAM)),
|
TMP_TABLE_FORCE_MYISAM)),
|
||||||
HA_POS_ERROR,
|
HA_POS_ERROR,
|
||||||
(char *)"subquery-cache-table")))
|
(char *)"subquery-cache-table",
|
||||||
|
TRUE)))
|
||||||
{
|
{
|
||||||
DBUG_PRINT("error", ("create_tmp_table failed, caching switched off"));
|
DBUG_PRINT("error", ("create_tmp_table failed, caching switched off"));
|
||||||
DBUG_VOID_RETURN;
|
DBUG_VOID_RETURN;
|
||||||
|
@ -637,7 +637,7 @@ bool mysqld_help(THD *thd, const char *mask)
|
|||||||
Protocol *protocol= thd->protocol;
|
Protocol *protocol= thd->protocol;
|
||||||
SQL_SELECT *select;
|
SQL_SELECT *select;
|
||||||
st_find_field used_fields[array_elements(init_used_fields)];
|
st_find_field used_fields[array_elements(init_used_fields)];
|
||||||
TABLE_LIST *leaves= 0;
|
List<TABLE_LIST> leaves;
|
||||||
TABLE_LIST tables[4];
|
TABLE_LIST tables[4];
|
||||||
List<String> topics_list, categories_list, subcategories_list;
|
List<String> topics_list, categories_list, subcategories_list;
|
||||||
String name, description, example;
|
String name, description, example;
|
||||||
@ -676,7 +676,7 @@ bool mysqld_help(THD *thd, const char *mask)
|
|||||||
thd->lex->select_lex.context.first_name_resolution_table= &tables[0];
|
thd->lex->select_lex.context.first_name_resolution_table= &tables[0];
|
||||||
if (setup_tables(thd, &thd->lex->select_lex.context,
|
if (setup_tables(thd, &thd->lex->select_lex.context,
|
||||||
&thd->lex->select_lex.top_join_list,
|
&thd->lex->select_lex.top_join_list,
|
||||||
tables, &leaves, FALSE))
|
tables, leaves, FALSE, FALSE))
|
||||||
goto error;
|
goto error;
|
||||||
memcpy((char*) used_fields, (char*) init_used_fields, sizeof(used_fields));
|
memcpy((char*) used_fields, (char*) init_used_fields, sizeof(used_fields));
|
||||||
if (init_fields(thd, tables, used_fields, array_elements(used_fields)))
|
if (init_fields(thd, tables, used_fields, array_elements(used_fields)))
|
||||||
|
@ -115,7 +115,7 @@ bool check_view_single_update(List<Item> &fields, List<Item> *values,
|
|||||||
{
|
{
|
||||||
it.init(*values);
|
it.init(*values);
|
||||||
while ((item= it++))
|
while ((item= it++))
|
||||||
tables|= item->used_tables();
|
tables|= item->view_used_tables(view);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Convert to real table bits */
|
/* Convert to real table bits */
|
||||||
@ -131,6 +131,11 @@ bool check_view_single_update(List<Item> &fields, List<Item> *values,
|
|||||||
if (view->check_single_table(&tbl, tables, view) || tbl == 0)
|
if (view->check_single_table(&tbl, tables, view) || tbl == 0)
|
||||||
goto error;
|
goto error;
|
||||||
|
|
||||||
|
/*
|
||||||
|
A buffer for the insert values was allocated for the merged view.
|
||||||
|
Use it.
|
||||||
|
*/
|
||||||
|
//tbl->table->insert_values= view->table->insert_values;
|
||||||
view->table= tbl->table;
|
view->table= tbl->table;
|
||||||
*map= tables;
|
*map= tables;
|
||||||
|
|
||||||
@ -234,6 +239,10 @@ static int check_insert_fields(THD *thd, TABLE_LIST *table_list,
|
|||||||
*/
|
*/
|
||||||
table_list->next_local= 0;
|
table_list->next_local= 0;
|
||||||
context->resolve_in_table_list_only(table_list);
|
context->resolve_in_table_list_only(table_list);
|
||||||
|
/* 'Unfix' fields to allow correct marking by the setup_fields function. */
|
||||||
|
if (table_list->is_view())
|
||||||
|
unfix_fields(fields);
|
||||||
|
|
||||||
res= setup_fields(thd, 0, fields, MARK_COLUMNS_WRITE, 0, 0);
|
res= setup_fields(thd, 0, fields, MARK_COLUMNS_WRITE, 0, 0);
|
||||||
|
|
||||||
/* Restore the current context. */
|
/* Restore the current context. */
|
||||||
@ -243,7 +252,7 @@ static int check_insert_fields(THD *thd, TABLE_LIST *table_list,
|
|||||||
if (res)
|
if (res)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
if (table_list->effective_algorithm == VIEW_ALGORITHM_MERGE)
|
if (table_list->is_view() && table_list->is_merged_derived())
|
||||||
{
|
{
|
||||||
if (check_view_single_update(fields,
|
if (check_view_single_update(fields,
|
||||||
fields_and_values_from_different_maps ?
|
fields_and_values_from_different_maps ?
|
||||||
@ -332,7 +341,8 @@ static int check_update_fields(THD *thd, TABLE_LIST *insert_table_list,
|
|||||||
if (setup_fields(thd, 0, update_fields, MARK_COLUMNS_WRITE, 0, 0))
|
if (setup_fields(thd, 0, update_fields, MARK_COLUMNS_WRITE, 0, 0))
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
if (insert_table_list->effective_algorithm == VIEW_ALGORITHM_MERGE &&
|
if (insert_table_list->is_view() &&
|
||||||
|
insert_table_list->is_merged_derived() &&
|
||||||
check_view_single_update(update_fields, &update_values,
|
check_view_single_update(update_fields, &update_values,
|
||||||
insert_table_list, map))
|
insert_table_list, map))
|
||||||
return -1;
|
return -1;
|
||||||
@ -631,6 +641,12 @@ bool mysql_insert(THD *thd,TABLE_LIST *table_list,
|
|||||||
table_list->table_name);
|
table_list->table_name);
|
||||||
DBUG_RETURN(TRUE);
|
DBUG_RETURN(TRUE);
|
||||||
}
|
}
|
||||||
|
/*
|
||||||
|
mark the table_list as a target for insert, to skip the DT/view prepare phase
|
||||||
|
for correct access rights checks
|
||||||
|
TODO: remove this hack
|
||||||
|
*/
|
||||||
|
table_list->skip_prepare_derived= TRUE;
|
||||||
|
|
||||||
if (table_list->lock_type == TL_WRITE_DELAYED)
|
if (table_list->lock_type == TL_WRITE_DELAYED)
|
||||||
{
|
{
|
||||||
@ -642,6 +658,7 @@ bool mysql_insert(THD *thd,TABLE_LIST *table_list,
|
|||||||
if (open_and_lock_tables(thd, table_list))
|
if (open_and_lock_tables(thd, table_list))
|
||||||
DBUG_RETURN(TRUE);
|
DBUG_RETURN(TRUE);
|
||||||
}
|
}
|
||||||
|
|
||||||
lock_type= table_list->lock_type;
|
lock_type= table_list->lock_type;
|
||||||
|
|
||||||
thd_proc_info(thd, "init");
|
thd_proc_info(thd, "init");
|
||||||
@ -1005,6 +1022,12 @@ bool mysql_insert(THD *thd,TABLE_LIST *table_list,
|
|||||||
::my_ok(thd, (ulong) thd->row_count_func, id, buff);
|
::my_ok(thd, (ulong) thd->row_count_func, id, buff);
|
||||||
}
|
}
|
||||||
thd->abort_on_warning= 0;
|
thd->abort_on_warning= 0;
|
||||||
|
if (thd->lex->current_select->first_cond_optimization)
|
||||||
|
{
|
||||||
|
thd->lex->current_select->save_leaf_tables(thd);
|
||||||
|
thd->lex->current_select->first_cond_optimization= 0;
|
||||||
|
}
|
||||||
|
|
||||||
DBUG_RETURN(FALSE);
|
DBUG_RETURN(FALSE);
|
||||||
|
|
||||||
abort:
|
abort:
|
||||||
@ -1133,6 +1156,11 @@ static bool mysql_prepare_insert_check_table(THD *thd, TABLE_LIST *table_list,
|
|||||||
bool insert_into_view= (table_list->view != 0);
|
bool insert_into_view= (table_list->view != 0);
|
||||||
DBUG_ENTER("mysql_prepare_insert_check_table");
|
DBUG_ENTER("mysql_prepare_insert_check_table");
|
||||||
|
|
||||||
|
if (!table_list->updatable)
|
||||||
|
{
|
||||||
|
my_error(ER_NON_INSERTABLE_TABLE, MYF(0), table_list->alias, "INSERT");
|
||||||
|
DBUG_RETURN(TRUE);
|
||||||
|
}
|
||||||
/*
|
/*
|
||||||
first table in list is the one we'll INSERT into, requires INSERT_ACL.
|
first table in list is the one we'll INSERT into, requires INSERT_ACL.
|
||||||
all others require SELECT_ACL only. the ACL requirement below is for
|
all others require SELECT_ACL only. the ACL requirement below is for
|
||||||
@ -1143,14 +1171,16 @@ static bool mysql_prepare_insert_check_table(THD *thd, TABLE_LIST *table_list,
|
|||||||
if (setup_tables_and_check_access(thd, &thd->lex->select_lex.context,
|
if (setup_tables_and_check_access(thd, &thd->lex->select_lex.context,
|
||||||
&thd->lex->select_lex.top_join_list,
|
&thd->lex->select_lex.top_join_list,
|
||||||
table_list,
|
table_list,
|
||||||
&thd->lex->select_lex.leaf_tables,
|
thd->lex->select_lex.leaf_tables,
|
||||||
select_insert, INSERT_ACL, SELECT_ACL))
|
select_insert, INSERT_ACL, SELECT_ACL,
|
||||||
|
TRUE))
|
||||||
DBUG_RETURN(TRUE);
|
DBUG_RETURN(TRUE);
|
||||||
|
|
||||||
if (insert_into_view && !fields.elements)
|
if (insert_into_view && !fields.elements)
|
||||||
{
|
{
|
||||||
thd->lex->empty_field_list_on_rset= 1;
|
thd->lex->empty_field_list_on_rset= 1;
|
||||||
if (!table_list->table)
|
if (!thd->lex->select_lex.leaf_tables.head()->table ||
|
||||||
|
table_list->is_multitable())
|
||||||
{
|
{
|
||||||
my_error(ER_VIEW_NO_INSERT_FIELD_LIST, MYF(0),
|
my_error(ER_VIEW_NO_INSERT_FIELD_LIST, MYF(0),
|
||||||
table_list->view_db.str, table_list->view_name.str);
|
table_list->view_db.str, table_list->view_name.str);
|
||||||
@ -1241,6 +1271,12 @@ bool mysql_prepare_insert(THD *thd, TABLE_LIST *table_list,
|
|||||||
/* INSERT should have a SELECT or VALUES clause */
|
/* INSERT should have a SELECT or VALUES clause */
|
||||||
DBUG_ASSERT (!select_insert || !values);
|
DBUG_ASSERT (!select_insert || !values);
|
||||||
|
|
||||||
|
if (mysql_handle_derived(thd->lex, DT_INIT))
|
||||||
|
DBUG_RETURN(TRUE);
|
||||||
|
if (table_list->handle_derived(thd->lex, DT_MERGE_FOR_INSERT))
|
||||||
|
DBUG_RETURN(TRUE);
|
||||||
|
if (mysql_handle_list_of_derived(thd->lex, table_list, DT_PREPARE))
|
||||||
|
DBUG_RETURN(TRUE);
|
||||||
/*
|
/*
|
||||||
For subqueries in VALUES() we should not see the table in which we are
|
For subqueries in VALUES() we should not see the table in which we are
|
||||||
inserting (for INSERT ... SELECT this is done by changing table_list,
|
inserting (for INSERT ... SELECT this is done by changing table_list,
|
||||||
@ -2934,9 +2970,9 @@ bool mysql_insert_select_prepare(THD *thd)
|
|||||||
{
|
{
|
||||||
LEX *lex= thd->lex;
|
LEX *lex= thd->lex;
|
||||||
SELECT_LEX *select_lex= &lex->select_lex;
|
SELECT_LEX *select_lex= &lex->select_lex;
|
||||||
TABLE_LIST *first_select_leaf_table;
|
|
||||||
DBUG_ENTER("mysql_insert_select_prepare");
|
DBUG_ENTER("mysql_insert_select_prepare");
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Statement-based replication of INSERT ... SELECT ... LIMIT is not safe
|
Statement-based replication of INSERT ... SELECT ... LIMIT is not safe
|
||||||
as order of rows is not defined, so in mixed mode we go to row-based.
|
as order of rows is not defined, so in mixed mode we go to row-based.
|
||||||
@ -2962,21 +2998,37 @@ bool mysql_insert_select_prepare(THD *thd)
|
|||||||
&select_lex->where, TRUE, FALSE, FALSE))
|
&select_lex->where, TRUE, FALSE, FALSE))
|
||||||
DBUG_RETURN(TRUE);
|
DBUG_RETURN(TRUE);
|
||||||
|
|
||||||
|
DBUG_ASSERT(select_lex->leaf_tables.elements != 0);
|
||||||
|
List_iterator<TABLE_LIST> ti(select_lex->leaf_tables);
|
||||||
|
TABLE_LIST *table;
|
||||||
|
uint insert_tables;
|
||||||
|
|
||||||
|
if (select_lex->first_cond_optimization)
|
||||||
|
{
|
||||||
|
/* Back up leaf_tables list. */
|
||||||
|
Query_arena *arena= thd->stmt_arena, backup;
|
||||||
|
arena= thd->activate_stmt_arena_if_needed(&backup); // For easier test
|
||||||
|
|
||||||
|
insert_tables= select_lex->insert_tables;
|
||||||
|
while ((table= ti++) && insert_tables--)
|
||||||
|
{
|
||||||
|
select_lex->leaf_tables_exec.push_back(table);
|
||||||
|
table->tablenr_exec= table->table->tablenr;
|
||||||
|
table->map_exec= table->table->map;
|
||||||
|
}
|
||||||
|
if (arena)
|
||||||
|
thd->restore_active_arena(arena, &backup);
|
||||||
|
}
|
||||||
|
ti.rewind();
|
||||||
/*
|
/*
|
||||||
exclude first table from leaf tables list, because it belong to
|
exclude first table from leaf tables list, because it belong to
|
||||||
INSERT
|
INSERT
|
||||||
*/
|
*/
|
||||||
DBUG_ASSERT(select_lex->leaf_tables != 0);
|
|
||||||
lex->leaf_tables_insert= select_lex->leaf_tables;
|
|
||||||
/* skip all leaf tables belonged to view where we are insert */
|
/* skip all leaf tables belonged to view where we are insert */
|
||||||
for (first_select_leaf_table= select_lex->leaf_tables->next_leaf;
|
insert_tables= select_lex->insert_tables;
|
||||||
first_select_leaf_table &&
|
while ((table= ti++) && insert_tables--)
|
||||||
first_select_leaf_table->belong_to_view &&
|
ti.remove();
|
||||||
first_select_leaf_table->belong_to_view ==
|
|
||||||
lex->leaf_tables_insert->belong_to_view;
|
|
||||||
first_select_leaf_table= first_select_leaf_table->next_leaf)
|
|
||||||
{}
|
|
||||||
select_lex->leaf_tables= first_select_leaf_table;
|
|
||||||
DBUG_RETURN(FALSE);
|
DBUG_RETURN(FALSE);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -3193,7 +3245,7 @@ void select_insert::cleanup()
|
|||||||
select_insert::~select_insert()
|
select_insert::~select_insert()
|
||||||
{
|
{
|
||||||
DBUG_ENTER("~select_insert");
|
DBUG_ENTER("~select_insert");
|
||||||
if (table)
|
if (table && table->created)
|
||||||
{
|
{
|
||||||
table->next_number_field=0;
|
table->next_number_field=0;
|
||||||
table->auto_increment_field_not_null= FALSE;
|
table->auto_increment_field_not_null= FALSE;
|
||||||
|
444
sql/sql_lex.cc
444
sql/sql_lex.cc
@ -23,6 +23,7 @@
|
|||||||
#include <hash.h>
|
#include <hash.h>
|
||||||
#include "sp.h"
|
#include "sp.h"
|
||||||
#include "sp_head.h"
|
#include "sp_head.h"
|
||||||
|
#include "sql_select.h"
|
||||||
|
|
||||||
/*
|
/*
|
||||||
We are using pointer to this variable for distinguishing between assignment
|
We are using pointer to this variable for distinguishing between assignment
|
||||||
@ -309,7 +310,6 @@ void lex_start(THD *thd)
|
|||||||
lex->derived_tables= 0;
|
lex->derived_tables= 0;
|
||||||
lex->lock_option= TL_READ;
|
lex->lock_option= TL_READ;
|
||||||
lex->safe_to_cache_query= 1;
|
lex->safe_to_cache_query= 1;
|
||||||
lex->leaf_tables_insert= 0;
|
|
||||||
lex->parsing_options.reset();
|
lex->parsing_options.reset();
|
||||||
lex->empty_field_list_on_rset= 0;
|
lex->empty_field_list_on_rset= 0;
|
||||||
lex->select_lex.select_number= 1;
|
lex->select_lex.select_number= 1;
|
||||||
@ -1594,6 +1594,7 @@ void st_select_lex_unit::init_query()
|
|||||||
describe= 0;
|
describe= 0;
|
||||||
found_rows_for_union= 0;
|
found_rows_for_union= 0;
|
||||||
insert_table_with_stored_vcol= 0;
|
insert_table_with_stored_vcol= 0;
|
||||||
|
derived= 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void st_select_lex::init_query()
|
void st_select_lex::init_query()
|
||||||
@ -1602,7 +1603,8 @@ void st_select_lex::init_query()
|
|||||||
table_list.empty();
|
table_list.empty();
|
||||||
top_join_list.empty();
|
top_join_list.empty();
|
||||||
join_list= &top_join_list;
|
join_list= &top_join_list;
|
||||||
embedding= leaf_tables= 0;
|
embedding= 0;
|
||||||
|
leaf_tables.empty();
|
||||||
item_list.empty();
|
item_list.empty();
|
||||||
join= 0;
|
join= 0;
|
||||||
having= prep_having= where= prep_where= 0;
|
having= prep_having= where= prep_where= 0;
|
||||||
@ -1670,6 +1672,8 @@ void st_select_lex::init_select()
|
|||||||
cond_value= having_value= Item::COND_UNDEF;
|
cond_value= having_value= Item::COND_UNDEF;
|
||||||
inner_refs_list.empty();
|
inner_refs_list.empty();
|
||||||
full_group_by_flag= 0;
|
full_group_by_flag= 0;
|
||||||
|
insert_tables= 0;
|
||||||
|
merged_into= 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -2154,9 +2158,27 @@ void st_select_lex::print_order(String *str,
|
|||||||
{
|
{
|
||||||
if (order->counter_used)
|
if (order->counter_used)
|
||||||
{
|
{
|
||||||
char buffer[20];
|
if (query_type != QT_VIEW_INTERNAL)
|
||||||
size_t length= my_snprintf(buffer, 20, "%d", order->counter);
|
{
|
||||||
str->append(buffer, (uint) length);
|
char buffer[20];
|
||||||
|
size_t length= my_snprintf(buffer, 20, "%d", order->counter);
|
||||||
|
str->append(buffer, (uint) length);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* replace numeric reference with expression */
|
||||||
|
if (order->item[0]->type() == Item::INT_ITEM &&
|
||||||
|
order->item[0]->basic_const_item())
|
||||||
|
{
|
||||||
|
char buffer[20];
|
||||||
|
size_t length= my_snprintf(buffer, 20, "%d", order->counter);
|
||||||
|
str->append(buffer, (uint) length);
|
||||||
|
/* make it expression instead of integer constant */
|
||||||
|
str->append(STRING_WITH_LEN("+0"));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
(*order->item)->print(str, query_type);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
(*order->item)->print(str, query_type);
|
(*order->item)->print(str, query_type);
|
||||||
@ -2993,7 +3015,11 @@ static void fix_prepare_info_in_table_list(THD *thd, TABLE_LIST *tbl)
|
|||||||
thd->check_and_register_item_tree(&tbl->prep_on_expr, &tbl->on_expr);
|
thd->check_and_register_item_tree(&tbl->prep_on_expr, &tbl->on_expr);
|
||||||
tbl->on_expr= tbl->on_expr->copy_andor_structure(thd);
|
tbl->on_expr= tbl->on_expr->copy_andor_structure(thd);
|
||||||
}
|
}
|
||||||
fix_prepare_info_in_table_list(thd, tbl->merge_underlying_list);
|
if (tbl->is_view_or_derived() && tbl->is_merged_derived())
|
||||||
|
{
|
||||||
|
SELECT_LEX *sel= tbl->get_single_select();
|
||||||
|
fix_prepare_info_in_table_list(thd, sel->get_table_list());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -3127,6 +3153,8 @@ bool st_select_lex::optimize_unflattened_subqueries()
|
|||||||
for (SELECT_LEX *sl= un->first_select(); sl; sl= sl->next_select())
|
for (SELECT_LEX *sl= un->first_select(); sl; sl= sl->next_select())
|
||||||
{
|
{
|
||||||
JOIN *inner_join= sl->join;
|
JOIN *inner_join= sl->join;
|
||||||
|
if (!inner_join)
|
||||||
|
continue;
|
||||||
SELECT_LEX *save_select= un->thd->lex->current_select;
|
SELECT_LEX *save_select= un->thd->lex->current_select;
|
||||||
ulonglong save_options;
|
ulonglong save_options;
|
||||||
int res;
|
int res;
|
||||||
@ -3153,19 +3181,349 @@ bool st_select_lex::optimize_unflattened_subqueries()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
@brief Process all derived tables/views of the SELECT.
|
||||||
|
|
||||||
|
@param lex LEX of this thread
|
||||||
|
@param phase phases to run derived tables/views through
|
||||||
|
|
||||||
|
@details
|
||||||
|
This function runs specified 'phases' on all tables from the
|
||||||
|
table_list of this select.
|
||||||
|
|
||||||
|
@return FALSE ok.
|
||||||
|
@return TRUE an error occur.
|
||||||
|
*/
|
||||||
|
|
||||||
|
bool st_select_lex::handle_derived(struct st_lex *lex, uint phases)
|
||||||
|
{
|
||||||
|
for (TABLE_LIST *cursor= (TABLE_LIST*) table_list.first;
|
||||||
|
cursor;
|
||||||
|
cursor= cursor->next_local)
|
||||||
|
{
|
||||||
|
if (cursor->is_view_or_derived() && cursor->handle_derived(lex, phases))
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
@brief
|
||||||
|
Returns first unoccupied table map and table number
|
||||||
|
|
||||||
|
@param map [out] return found map
|
||||||
|
@param tablenr [out] return found tablenr
|
||||||
|
|
||||||
|
@details
|
||||||
|
Returns first unoccupied table map and table number in this select.
|
||||||
|
Map and table are returned in *'map' and *'tablenr' accordingly.
|
||||||
|
|
||||||
|
@retrun TRUE no free table map/table number
|
||||||
|
@return FALSE found free table map/table number
|
||||||
|
*/
|
||||||
|
|
||||||
|
bool st_select_lex::get_free_table_map(table_map *map, uint *tablenr)
|
||||||
|
{
|
||||||
|
*map= 0;
|
||||||
|
*tablenr= 0;
|
||||||
|
TABLE_LIST *tl;
|
||||||
|
if (!join)
|
||||||
|
{
|
||||||
|
(*map)= 1<<1;
|
||||||
|
(*tablenr)++;
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
List_iterator<TABLE_LIST> ti(leaf_tables);
|
||||||
|
while ((tl= ti++))
|
||||||
|
{
|
||||||
|
if (tl->table->map > *map)
|
||||||
|
*map= tl->table->map;
|
||||||
|
if (tl->table->tablenr > *tablenr)
|
||||||
|
*tablenr= tl->table->tablenr;
|
||||||
|
}
|
||||||
|
(*map)<<= 1;
|
||||||
|
(*tablenr)++;
|
||||||
|
if (*tablenr >= MAX_TABLES)
|
||||||
|
return TRUE;
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
@brief
|
||||||
|
Append given table to the leaf_tables list.
|
||||||
|
|
||||||
|
@param link Offset to which list in table structure to use
|
||||||
|
@param table Table to append
|
||||||
|
|
||||||
|
@details
|
||||||
|
Append given 'table' to the leaf_tables list using the 'link' offset.
|
||||||
|
If the 'table' is linked with other tables through next_leaf/next_local
|
||||||
|
chains then whole list will be appended.
|
||||||
|
*/
|
||||||
|
|
||||||
|
void st_select_lex::append_table_to_list(TABLE_LIST *TABLE_LIST::*link,
|
||||||
|
TABLE_LIST *table)
|
||||||
|
{
|
||||||
|
TABLE_LIST *tl;
|
||||||
|
for (tl= leaf_tables.head(); tl->*link; tl= tl->*link) ;
|
||||||
|
tl->*link= table;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
@brief
|
||||||
|
Remove given table from the leaf_tables list.
|
||||||
|
|
||||||
|
@param link Offset to which list in table structure to use
|
||||||
|
@param table Table to remove
|
||||||
|
|
||||||
|
@details
|
||||||
|
Remove 'table' from the leaf_tables list using the 'link' offset.
|
||||||
|
*/
|
||||||
|
|
||||||
|
void st_select_lex::remove_table_from_list(TABLE_LIST *table)
|
||||||
|
{
|
||||||
|
TABLE_LIST *tl;
|
||||||
|
List_iterator<TABLE_LIST> ti(leaf_tables);
|
||||||
|
while ((tl= ti++))
|
||||||
|
{
|
||||||
|
if (tl == table)
|
||||||
|
{
|
||||||
|
ti.remove();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
@brief
|
||||||
|
Assigns new table maps to tables in the leaf_tables list
|
||||||
|
|
||||||
|
@param derived Derived table to take initial table map from
|
||||||
|
@param map table map to begin with
|
||||||
|
@param tablenr table number to begin with
|
||||||
|
@param parent_lex new parent select_lex
|
||||||
|
|
||||||
|
@details
|
||||||
|
Assign new table maps/table numbers to all tables in the leaf_tables list.
|
||||||
|
'map'/'tablenr' are used for the first table and shifted to left/
|
||||||
|
increased for each consequent table in the leaf_tables list.
|
||||||
|
If the 'derived' table is given then it's table map/number is used for the
|
||||||
|
first table in the list and 'map'/'tablenr' are used for the second and
|
||||||
|
all consequent tables.
|
||||||
|
The 'parent_lex' is set as the new parent select_lex for all tables in the
|
||||||
|
list.
|
||||||
|
*/
|
||||||
|
|
||||||
|
void st_select_lex::remap_tables(TABLE_LIST *derived, table_map map,
|
||||||
|
uint tablenr, SELECT_LEX *parent_lex)
|
||||||
|
{
|
||||||
|
bool first_table= TRUE;
|
||||||
|
TABLE_LIST *tl;
|
||||||
|
table_map first_map;
|
||||||
|
uint first_tablenr;
|
||||||
|
|
||||||
|
if (derived && derived->table)
|
||||||
|
{
|
||||||
|
first_map= derived->table->map;
|
||||||
|
first_tablenr= derived->table->tablenr;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
first_map= map;
|
||||||
|
map<<= 1;
|
||||||
|
first_tablenr= tablenr++;
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
Assign table bit/table number.
|
||||||
|
To the first table of the subselect the table bit/tablenr of the
|
||||||
|
derived table is assigned. The rest of tables are getting bits
|
||||||
|
sequentially, starting from the provided table map/tablenr.
|
||||||
|
*/
|
||||||
|
List_iterator<TABLE_LIST> ti(leaf_tables);
|
||||||
|
while ((tl= ti++))
|
||||||
|
{
|
||||||
|
if (first_table)
|
||||||
|
{
|
||||||
|
first_table= FALSE;
|
||||||
|
tl->table->set_table_map(first_map, first_tablenr);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
tl->table->set_table_map(map, tablenr);
|
||||||
|
tablenr++;
|
||||||
|
map<<= 1;
|
||||||
|
}
|
||||||
|
SELECT_LEX *old_sl= tl->select_lex;
|
||||||
|
tl->select_lex= parent_lex;
|
||||||
|
for(TABLE_LIST *emb= tl->embedding;
|
||||||
|
emb && emb->select_lex == old_sl;
|
||||||
|
emb= emb->embedding)
|
||||||
|
emb->select_lex= parent_lex;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
@brief
|
||||||
|
Merge a subquery into this select.
|
||||||
|
|
||||||
|
@param derived derived table of the subquery to be merged
|
||||||
|
@param subq_select select_lex of the subquery
|
||||||
|
@param map table map for assigning to merged tables from subquery
|
||||||
|
@param table_no table number for assigning to merged tables from subquery
|
||||||
|
|
||||||
|
@details
|
||||||
|
This function merges a subquery into its parent select. In short the
|
||||||
|
merge operation appends the subquery FROM table list to the parent's
|
||||||
|
FROM table list. In more details:
|
||||||
|
.) the top_join_list of the subquery is wrapped into a join_nest
|
||||||
|
and attached to 'derived'
|
||||||
|
.) subquery's leaf_tables list is merged with the leaf_tables
|
||||||
|
list of this select_lex
|
||||||
|
.) the table maps and table numbers of the tables merged from
|
||||||
|
the subquery are adjusted to reflect their new binding to
|
||||||
|
this select
|
||||||
|
|
||||||
|
@return TRUE an error occur
|
||||||
|
@return FALSE ok
|
||||||
|
*/
|
||||||
|
|
||||||
|
bool SELECT_LEX::merge_subquery(TABLE_LIST *derived, SELECT_LEX *subq_select,
|
||||||
|
uint table_no, table_map map)
|
||||||
|
{
|
||||||
|
derived->wrap_into_nested_join(subq_select->top_join_list);
|
||||||
|
/* Reconnect the next_leaf chain. */
|
||||||
|
leaf_tables.concat(&subq_select->leaf_tables);
|
||||||
|
|
||||||
|
ftfunc_list->concat(subq_select->ftfunc_list);
|
||||||
|
if (join)
|
||||||
|
{
|
||||||
|
Item_in_subselect **in_subq;
|
||||||
|
Item_in_subselect **in_subq_end;
|
||||||
|
for (in_subq= subq_select->join->sj_subselects.front(),
|
||||||
|
in_subq_end= subq_select->join->sj_subselects.back();
|
||||||
|
in_subq != in_subq_end;
|
||||||
|
in_subq++)
|
||||||
|
{
|
||||||
|
join->sj_subselects.append(join->thd->mem_root, *in_subq);
|
||||||
|
(*in_subq)->emb_on_expr_nest= derived;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
Remove merged table from chain.
|
||||||
|
When merge_subquery is called at a subquery-to-semijoin transformation
|
||||||
|
the derived isn't in the leaf_tables list, so in this case the call of
|
||||||
|
remove_table_from_list does not cause any actions.
|
||||||
|
*/
|
||||||
|
remove_table_from_list(derived);
|
||||||
|
|
||||||
|
/* Walk through child's tables and adjust table map, tablenr,
|
||||||
|
* parent_lex */
|
||||||
|
subq_select->remap_tables(derived, map, table_no, this);
|
||||||
|
subq_select->merged_into= this;
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
@brief
|
||||||
|
Mark tables from the leaf_tables list as belong to a derived table.
|
||||||
|
|
||||||
|
@param derived tables will be marked as belonging to this derived
|
||||||
|
|
||||||
|
@details
|
||||||
|
Run through the leaf_list and mark all tables as belonging to the 'derived'.
|
||||||
|
*/
|
||||||
|
|
||||||
|
void SELECT_LEX::mark_as_belong_to_derived(TABLE_LIST *derived)
|
||||||
|
{
|
||||||
|
/* Mark tables as belonging to this DT */
|
||||||
|
TABLE_LIST *tl;
|
||||||
|
List_iterator<TABLE_LIST> ti(leaf_tables);
|
||||||
|
while ((tl= ti++))
|
||||||
|
{
|
||||||
|
tl->skip_temporary= 1;
|
||||||
|
tl->belong_to_derived= derived;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
@brief
|
||||||
|
Update used_tables cache for this select
|
||||||
|
|
||||||
|
@details
|
||||||
|
This function updates used_tables cache of ON expressions of all tables
|
||||||
|
in the leaf_tables list and of the conds expression (if any).
|
||||||
|
*/
|
||||||
|
|
||||||
|
void SELECT_LEX::update_used_tables()
|
||||||
|
{
|
||||||
|
TABLE_LIST *tl;
|
||||||
|
List_iterator<TABLE_LIST> ti(leaf_tables);
|
||||||
|
while ((tl= ti++))
|
||||||
|
{
|
||||||
|
if (tl->on_expr)
|
||||||
|
{
|
||||||
|
tl->on_expr->update_used_tables();
|
||||||
|
tl->on_expr->walk(&Item::eval_not_null_tables, 0, NULL);
|
||||||
|
}
|
||||||
|
TABLE_LIST *embedding= tl->embedding;
|
||||||
|
while (embedding)
|
||||||
|
{
|
||||||
|
if (embedding->on_expr &&
|
||||||
|
embedding->nested_join->join_list.head() == tl)
|
||||||
|
{
|
||||||
|
embedding->on_expr->update_used_tables();
|
||||||
|
embedding->on_expr->walk(&Item::eval_not_null_tables, 0, NULL);
|
||||||
|
}
|
||||||
|
tl= embedding;
|
||||||
|
embedding= tl->embedding;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (join->conds)
|
||||||
|
{
|
||||||
|
join->conds->update_used_tables();
|
||||||
|
join->conds->walk(&Item::eval_not_null_tables, 0, NULL);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Set the EXPLAIN type for this subquery.
|
Set the EXPLAIN type for this subquery.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
void st_select_lex::set_explain_type()
|
void st_select_lex::set_explain_type()
|
||||||
{
|
{
|
||||||
|
bool is_primary= FALSE;
|
||||||
|
if (next_select())
|
||||||
|
is_primary= TRUE;
|
||||||
|
|
||||||
|
if (!is_primary && first_inner_unit())
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
If there is at least one materialized derived|view then it's a PRIMARY select.
|
||||||
|
Otherwise, all derived tables/views were merged and this select is a SIMPLE one.
|
||||||
|
*/
|
||||||
|
for (SELECT_LEX_UNIT *un= first_inner_unit(); un; un= un->next_unit())
|
||||||
|
{
|
||||||
|
if ((!un->derived || un->derived->is_materialized_derived()))
|
||||||
|
{
|
||||||
|
is_primary= TRUE;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
SELECT_LEX *first= master_unit()->first_select();
|
SELECT_LEX *first= master_unit()->first_select();
|
||||||
/* drop UNCACHEABLE_EXPLAIN, because it is for internal usage only */
|
/* drop UNCACHEABLE_EXPLAIN, because it is for internal usage only */
|
||||||
uint8 is_uncacheable= (uncacheable & ~UNCACHEABLE_EXPLAIN);
|
uint8 is_uncacheable= (uncacheable & ~UNCACHEABLE_EXPLAIN);
|
||||||
|
|
||||||
type= ((&master_unit()->thd->lex->select_lex == this) ?
|
type= ((&master_unit()->thd->lex->select_lex == this) ?
|
||||||
(first_inner_unit() || next_select() ?
|
(is_primary ? "PRIMARY" : "SIMPLE"):
|
||||||
"PRIMARY" : "SIMPLE") :
|
|
||||||
((this == first) ?
|
((this == first) ?
|
||||||
((linkage == DERIVED_TABLE_TYPE) ?
|
((linkage == DERIVED_TABLE_TYPE) ?
|
||||||
"DERIVED" :
|
"DERIVED" :
|
||||||
@ -3181,6 +3539,76 @@ void st_select_lex::set_explain_type()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
@brief
|
||||||
|
Increase estimated number of records for a derived table/view
|
||||||
|
|
||||||
|
@param records number of records to increase estimate by
|
||||||
|
|
||||||
|
@details
|
||||||
|
This function increases estimated number of records by the 'records'
|
||||||
|
for the derived table to which this select belongs to.
|
||||||
|
*/
|
||||||
|
|
||||||
|
void SELECT_LEX::increase_derived_records(ha_rows records)
|
||||||
|
{
|
||||||
|
SELECT_LEX_UNIT *unit= master_unit();
|
||||||
|
DBUG_ASSERT(unit->derived);
|
||||||
|
|
||||||
|
select_union *result= (select_union*)unit->result;
|
||||||
|
result->records+= records;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
@brief
|
||||||
|
Mark select's derived table as a const one.
|
||||||
|
|
||||||
|
@param empty Whether select has an empty result set
|
||||||
|
|
||||||
|
@details
|
||||||
|
Mark derived table/view of this select as a constant one (to
|
||||||
|
materialize it at the optimization phase) unless this select belongs to a
|
||||||
|
union. Estimated number of rows is incremented if this select has non empty
|
||||||
|
result set.
|
||||||
|
*/
|
||||||
|
|
||||||
|
void SELECT_LEX::mark_const_derived(bool empty)
|
||||||
|
{
|
||||||
|
TABLE_LIST *derived= master_unit()->derived;
|
||||||
|
if (!join->thd->lex->describe && derived)
|
||||||
|
{
|
||||||
|
if (!empty)
|
||||||
|
increase_derived_records(1);
|
||||||
|
if (!master_unit()->is_union() && !derived->is_merged_derived())
|
||||||
|
derived->fill_me= TRUE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool st_select_lex::save_leaf_tables(THD *thd)
|
||||||
|
{
|
||||||
|
Query_arena *arena= thd->stmt_arena, backup;
|
||||||
|
if (arena->is_conventional())
|
||||||
|
arena= 0;
|
||||||
|
else
|
||||||
|
thd->set_n_backup_active_arena(arena, &backup);
|
||||||
|
|
||||||
|
List_iterator_fast<TABLE_LIST> li(leaf_tables);
|
||||||
|
TABLE_LIST *table;
|
||||||
|
while ((table= li++))
|
||||||
|
{
|
||||||
|
if (leaf_tables_exec.push_back(table))
|
||||||
|
return 1;
|
||||||
|
table->tablenr_exec= table->table->tablenr;
|
||||||
|
table->map_exec= table->table->map;
|
||||||
|
}
|
||||||
|
if (arena)
|
||||||
|
thd->restore_active_arena(arena, &backup);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
A routine used by the parser to decide whether we are specifying a full
|
A routine used by the parser to decide whether we are specifying a full
|
||||||
partitioning or if only partitions to add or to split.
|
partitioning or if only partitions to add or to split.
|
||||||
|
@ -472,6 +472,11 @@ public:
|
|||||||
friend bool mysql_new_select(struct st_lex *lex, bool move_down);
|
friend bool mysql_new_select(struct st_lex *lex, bool move_down);
|
||||||
friend bool mysql_make_view(THD *thd, File_parser *parser,
|
friend bool mysql_make_view(THD *thd, File_parser *parser,
|
||||||
TABLE_LIST *table, uint flags);
|
TABLE_LIST *table, uint flags);
|
||||||
|
friend bool mysql_derived_prepare(THD *thd, st_lex *lex,
|
||||||
|
TABLE_LIST *orig_table_list);
|
||||||
|
friend bool mysql_derived_merge(THD *thd, st_lex *lex,
|
||||||
|
TABLE_LIST *orig_table_list);
|
||||||
|
friend bool TABLE_LIST::init_derived(THD *thd, bool init_view);
|
||||||
private:
|
private:
|
||||||
void fast_exclude();
|
void fast_exclude();
|
||||||
};
|
};
|
||||||
@ -490,13 +495,12 @@ class st_select_lex_unit: public st_select_lex_node {
|
|||||||
protected:
|
protected:
|
||||||
TABLE_LIST result_table_list;
|
TABLE_LIST result_table_list;
|
||||||
select_union *union_result;
|
select_union *union_result;
|
||||||
TABLE *table; /* temporary table using for appending UNION results */
|
|
||||||
|
|
||||||
select_result *result;
|
|
||||||
ulonglong found_rows_for_union;
|
ulonglong found_rows_for_union;
|
||||||
bool saved_error;
|
bool saved_error;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
TABLE *table; /* temporary table using for appending UNION results */
|
||||||
|
select_result *result;
|
||||||
bool prepared, // prepare phase already performed for UNION (unit)
|
bool prepared, // prepare phase already performed for UNION (unit)
|
||||||
optimized, // optimize phase already performed for UNION (unit)
|
optimized, // optimize phase already performed for UNION (unit)
|
||||||
executed, // already executed
|
executed, // already executed
|
||||||
@ -523,6 +527,11 @@ public:
|
|||||||
ha_rows select_limit_cnt, offset_limit_cnt;
|
ha_rows select_limit_cnt, offset_limit_cnt;
|
||||||
/* not NULL if unit used in subselect, point to subselect item */
|
/* not NULL if unit used in subselect, point to subselect item */
|
||||||
Item_subselect *item;
|
Item_subselect *item;
|
||||||
|
/*
|
||||||
|
TABLE_LIST representing this union in the embedding select. Used for
|
||||||
|
derived tables/views handling.
|
||||||
|
*/
|
||||||
|
TABLE_LIST *derived;
|
||||||
/* thread handler */
|
/* thread handler */
|
||||||
THD *thd;
|
THD *thd;
|
||||||
/*
|
/*
|
||||||
@ -559,6 +568,7 @@ public:
|
|||||||
|
|
||||||
/* UNION methods */
|
/* UNION methods */
|
||||||
bool prepare(THD *thd, select_result *result, ulong additional_options);
|
bool prepare(THD *thd, select_result *result, ulong additional_options);
|
||||||
|
bool optimize();
|
||||||
bool exec();
|
bool exec();
|
||||||
bool cleanup();
|
bool cleanup();
|
||||||
inline void unclean() { cleaned= 0; }
|
inline void unclean() { cleaned= 0; }
|
||||||
@ -575,6 +585,8 @@ public:
|
|||||||
void set_thd(THD *thd_arg) { thd= thd_arg; }
|
void set_thd(THD *thd_arg) { thd= thd_arg; }
|
||||||
inline bool is_union ();
|
inline bool is_union ();
|
||||||
|
|
||||||
|
void set_unique_exclude();
|
||||||
|
|
||||||
friend void lex_start(THD *thd);
|
friend void lex_start(THD *thd);
|
||||||
friend int subselect_union_engine::exec();
|
friend int subselect_union_engine::exec();
|
||||||
|
|
||||||
@ -620,8 +632,17 @@ public:
|
|||||||
Beginning of the list of leaves in a FROM clause, where the leaves
|
Beginning of the list of leaves in a FROM clause, where the leaves
|
||||||
inlcude all base tables including view tables. The tables are connected
|
inlcude all base tables including view tables. The tables are connected
|
||||||
by TABLE_LIST::next_leaf, so leaf_tables points to the left-most leaf.
|
by TABLE_LIST::next_leaf, so leaf_tables points to the left-most leaf.
|
||||||
|
|
||||||
|
List of all base tables local to a subquery including all view
|
||||||
|
tables. Unlike 'next_local', this in this list views are *not*
|
||||||
|
leaves. Created in setup_tables() -> make_leaves_list().
|
||||||
*/
|
*/
|
||||||
TABLE_LIST *leaf_tables;
|
List<TABLE_LIST> leaf_tables;
|
||||||
|
List<TABLE_LIST> leaf_tables_exec;
|
||||||
|
uint insert_tables;
|
||||||
|
st_select_lex *merged_into; /* select which this select is merged into */
|
||||||
|
/* (not 0 only for views/derived tables) */
|
||||||
|
|
||||||
const char *type; /* type of select for EXPLAIN */
|
const char *type; /* type of select for EXPLAIN */
|
||||||
|
|
||||||
SQL_I_List<ORDER> order_list; /* ORDER clause */
|
SQL_I_List<ORDER> order_list; /* ORDER clause */
|
||||||
@ -857,6 +878,27 @@ public:
|
|||||||
bool optimize_unflattened_subqueries();
|
bool optimize_unflattened_subqueries();
|
||||||
/* Set the EXPLAIN type for this subquery. */
|
/* Set the EXPLAIN type for this subquery. */
|
||||||
void set_explain_type();
|
void set_explain_type();
|
||||||
|
bool handle_derived(struct st_lex *lex, uint phases);
|
||||||
|
void append_table_to_list(TABLE_LIST *TABLE_LIST::*link, TABLE_LIST *table);
|
||||||
|
bool get_free_table_map(table_map *map, uint *tablenr);
|
||||||
|
void remove_table_from_list(TABLE_LIST *table);
|
||||||
|
void remap_tables(TABLE_LIST *derived, table_map map,
|
||||||
|
uint tablenr, st_select_lex *parent_lex);
|
||||||
|
bool merge_subquery(TABLE_LIST *derived, st_select_lex *subq_lex,
|
||||||
|
uint tablenr, table_map map);
|
||||||
|
inline bool is_mergeable()
|
||||||
|
{
|
||||||
|
return (next_select() == 0 && group_list.elements == 0 &&
|
||||||
|
having == 0 && with_sum_func == 0 &&
|
||||||
|
table_list.elements >= 1 && !(options & SELECT_DISTINCT) &&
|
||||||
|
select_limit == 0);
|
||||||
|
}
|
||||||
|
void mark_as_belong_to_derived(TABLE_LIST *derived);
|
||||||
|
void increase_derived_records(ha_rows records);
|
||||||
|
void update_used_tables();
|
||||||
|
void mark_const_derived(bool empty);
|
||||||
|
|
||||||
|
bool save_leaf_tables(THD *thd);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
/* current index hint kind. used in filling up index_hints */
|
/* current index hint kind. used in filling up index_hints */
|
||||||
@ -1629,8 +1671,6 @@ typedef struct st_lex : public Query_tables_list
|
|||||||
|
|
||||||
CHARSET_INFO *charset;
|
CHARSET_INFO *charset;
|
||||||
bool text_string_is_7bit;
|
bool text_string_is_7bit;
|
||||||
/* store original leaf_tables for INSERT SELECT and PS/SP */
|
|
||||||
TABLE_LIST *leaf_tables_insert;
|
|
||||||
|
|
||||||
/** SELECT of CREATE VIEW statement */
|
/** SELECT of CREATE VIEW statement */
|
||||||
LEX_STRING create_view_select;
|
LEX_STRING create_view_select;
|
||||||
@ -1747,7 +1787,7 @@ typedef struct st_lex : public Query_tables_list
|
|||||||
DERIVED_SUBQUERY and DERIVED_VIEW).
|
DERIVED_SUBQUERY and DERIVED_VIEW).
|
||||||
*/
|
*/
|
||||||
uint8 derived_tables;
|
uint8 derived_tables;
|
||||||
uint8 create_view_algorithm;
|
uint16 create_view_algorithm;
|
||||||
uint8 create_view_check;
|
uint8 create_view_check;
|
||||||
bool drop_if_exists, drop_temporary, local_file, one_shot_set;
|
bool drop_if_exists, drop_temporary, local_file, one_shot_set;
|
||||||
bool autocommit;
|
bool autocommit;
|
||||||
@ -1935,6 +1975,8 @@ typedef struct st_lex : public Query_tables_list
|
|||||||
switch (sql_command) {
|
switch (sql_command) {
|
||||||
case SQLCOM_UPDATE:
|
case SQLCOM_UPDATE:
|
||||||
case SQLCOM_UPDATE_MULTI:
|
case SQLCOM_UPDATE_MULTI:
|
||||||
|
case SQLCOM_DELETE:
|
||||||
|
case SQLCOM_DELETE_MULTI:
|
||||||
case SQLCOM_INSERT:
|
case SQLCOM_INSERT:
|
||||||
case SQLCOM_INSERT_SELECT:
|
case SQLCOM_INSERT_SELECT:
|
||||||
case SQLCOM_REPLACE:
|
case SQLCOM_REPLACE:
|
||||||
|
@ -265,6 +265,8 @@ public:
|
|||||||
prev= &node->next;
|
prev= &node->next;
|
||||||
node= node->next;
|
node= node->next;
|
||||||
elements++;
|
elements++;
|
||||||
|
if (node == &end_of_list)
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
*prev= *last;
|
*prev= *last;
|
||||||
last= prev;
|
last= prev;
|
||||||
|
@ -172,12 +172,15 @@ int mysql_load(THD *thd,sql_exchange *ex,TABLE_LIST *table_list,
|
|||||||
|
|
||||||
if (open_and_lock_tables(thd, table_list))
|
if (open_and_lock_tables(thd, table_list))
|
||||||
DBUG_RETURN(TRUE);
|
DBUG_RETURN(TRUE);
|
||||||
|
if (mysql_handle_single_derived(thd->lex, table_list, DT_MERGE_FOR_INSERT) ||
|
||||||
|
mysql_handle_single_derived(thd->lex, table_list, DT_PREPARE))
|
||||||
|
DBUG_RETURN(TRUE);
|
||||||
if (setup_tables_and_check_access(thd, &thd->lex->select_lex.context,
|
if (setup_tables_and_check_access(thd, &thd->lex->select_lex.context,
|
||||||
&thd->lex->select_lex.top_join_list,
|
&thd->lex->select_lex.top_join_list,
|
||||||
table_list,
|
table_list,
|
||||||
&thd->lex->select_lex.leaf_tables, FALSE,
|
thd->lex->select_lex.leaf_tables, FALSE,
|
||||||
INSERT_ACL | UPDATE_ACL,
|
INSERT_ACL | UPDATE_ACL,
|
||||||
INSERT_ACL | UPDATE_ACL))
|
INSERT_ACL | UPDATE_ACL, FALSE))
|
||||||
DBUG_RETURN(-1);
|
DBUG_RETURN(-1);
|
||||||
if (!table_list->table || // do not suport join view
|
if (!table_list->table || // do not suport join view
|
||||||
!table_list->updatable || // and derived tables
|
!table_list->updatable || // and derived tables
|
||||||
|
@ -153,8 +153,7 @@ int handle_olaps(LEX *lex, SELECT_LEX *select_lex)
|
|||||||
|
|
||||||
|
|
||||||
if (setup_tables(lex->thd, &select_lex->context, &select_lex->top_join_list,
|
if (setup_tables(lex->thd, &select_lex->context, &select_lex->top_join_list,
|
||||||
select_lex->table_list.first
|
FALSE, FALSE) ||
|
||||||
&select_lex->leaf_tables, FALSE) ||
|
|
||||||
setup_fields(lex->thd, 0, select_lex->item_list, MARK_COLUMNS_READ,
|
setup_fields(lex->thd, 0, select_lex->item_list, MARK_COLUMNS_READ,
|
||||||
&all_fields,1) ||
|
&all_fields,1) ||
|
||||||
setup_fields(lex->thd, 0, item_list_copy, MARK_COLUMNS_READ,
|
setup_fields(lex->thd, 0, item_list_copy, MARK_COLUMNS_READ,
|
||||||
|
@ -2697,6 +2697,9 @@ mysql_execute_command(THD *thd)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (mysql_handle_single_derived(thd->lex, create_table,
|
||||||
|
DT_MERGE_FOR_INSERT))
|
||||||
|
DBUG_RETURN(1);
|
||||||
|
|
||||||
/* So that CREATE TEMPORARY TABLE gets to binlog at commit/rollback */
|
/* So that CREATE TEMPORARY TABLE gets to binlog at commit/rollback */
|
||||||
if (create_info.options & HA_LEX_CREATE_TMP_TABLE)
|
if (create_info.options & HA_LEX_CREATE_TMP_TABLE)
|
||||||
@ -3223,6 +3226,10 @@ end_with_restore_list:
|
|||||||
|
|
||||||
if (!(res= open_and_lock_tables(thd, all_tables)))
|
if (!(res= open_and_lock_tables(thd, all_tables)))
|
||||||
{
|
{
|
||||||
|
/*
|
||||||
|
Only the INSERT table should be merged. Other will be handled by
|
||||||
|
select.
|
||||||
|
*/
|
||||||
/* Skip first table, which is the table we are inserting in */
|
/* Skip first table, which is the table we are inserting in */
|
||||||
TABLE_LIST *second_table= first_table->next_local;
|
TABLE_LIST *second_table= first_table->next_local;
|
||||||
select_lex->table_list.first= second_table;
|
select_lex->table_list.first= second_table;
|
||||||
|
@ -1168,7 +1168,7 @@ static bool mysql_test_insert(Prepared_statement *stmt,
|
|||||||
If we would use locks, then we have to ensure we are not using
|
If we would use locks, then we have to ensure we are not using
|
||||||
TL_WRITE_DELAYED as having two such locks can cause table corruption.
|
TL_WRITE_DELAYED as having two such locks can cause table corruption.
|
||||||
*/
|
*/
|
||||||
if (open_normal_and_derived_tables(thd, table_list, 0))
|
if (open_normal_and_derived_tables(thd, table_list, 0, DT_INIT))
|
||||||
goto error;
|
goto error;
|
||||||
|
|
||||||
if ((values= its++))
|
if ((values= its++))
|
||||||
@ -1252,7 +1252,10 @@ static int mysql_test_update(Prepared_statement *stmt,
|
|||||||
open_tables(thd, &table_list, &table_count, 0))
|
open_tables(thd, &table_list, &table_count, 0))
|
||||||
goto error;
|
goto error;
|
||||||
|
|
||||||
if (table_list->multitable_view)
|
if (mysql_handle_derived(thd->lex, DT_INIT))
|
||||||
|
goto error;
|
||||||
|
|
||||||
|
if (table_list->is_multitable())
|
||||||
{
|
{
|
||||||
DBUG_ASSERT(table_list->view != 0);
|
DBUG_ASSERT(table_list->view != 0);
|
||||||
DBUG_PRINT("info", ("Switch to multi-update"));
|
DBUG_PRINT("info", ("Switch to multi-update"));
|
||||||
@ -1266,9 +1269,16 @@ static int mysql_test_update(Prepared_statement *stmt,
|
|||||||
thd->fill_derived_tables() is false here for sure (because it is
|
thd->fill_derived_tables() is false here for sure (because it is
|
||||||
preparation of PS, so we even do not check it).
|
preparation of PS, so we even do not check it).
|
||||||
*/
|
*/
|
||||||
if (mysql_handle_derived(thd->lex, &mysql_derived_prepare))
|
if (table_list->handle_derived(thd->lex, DT_MERGE_FOR_INSERT) ||
|
||||||
|
table_list->handle_derived(thd->lex, DT_PREPARE))
|
||||||
goto error;
|
goto error;
|
||||||
|
|
||||||
|
if (!table_list->updatable)
|
||||||
|
{
|
||||||
|
my_error(ER_NON_UPDATABLE_TABLE, MYF(0), table_list->alias, "UPDATE");
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
|
||||||
#ifndef NO_EMBEDDED_ACCESS_CHECKS
|
#ifndef NO_EMBEDDED_ACCESS_CHECKS
|
||||||
/* Force privilege re-checking for views after they have been opened. */
|
/* Force privilege re-checking for views after they have been opened. */
|
||||||
want_privilege= (table_list->view ? UPDATE_ACL :
|
want_privilege= (table_list->view ? UPDATE_ACL :
|
||||||
@ -1321,15 +1331,26 @@ error:
|
|||||||
static bool mysql_test_delete(Prepared_statement *stmt,
|
static bool mysql_test_delete(Prepared_statement *stmt,
|
||||||
TABLE_LIST *table_list)
|
TABLE_LIST *table_list)
|
||||||
{
|
{
|
||||||
|
uint table_count= 0;
|
||||||
THD *thd= stmt->thd;
|
THD *thd= stmt->thd;
|
||||||
LEX *lex= stmt->lex;
|
LEX *lex= stmt->lex;
|
||||||
DBUG_ENTER("mysql_test_delete");
|
DBUG_ENTER("mysql_test_delete");
|
||||||
|
|
||||||
if (delete_precheck(thd, table_list) ||
|
if (delete_precheck(thd, table_list) ||
|
||||||
open_normal_and_derived_tables(thd, table_list, 0))
|
open_tables(thd, &table_list, &table_count, 0))
|
||||||
goto error;
|
goto error;
|
||||||
|
|
||||||
if (!table_list->table)
|
if (mysql_handle_derived(thd->lex, DT_INIT) ||
|
||||||
|
mysql_handle_list_of_derived(thd->lex, table_list, DT_MERGE_FOR_INSERT) ||
|
||||||
|
mysql_handle_list_of_derived(thd->lex, table_list, DT_PREPARE))
|
||||||
|
goto error;
|
||||||
|
|
||||||
|
if (!table_list->updatable)
|
||||||
|
{
|
||||||
|
my_error(ER_NON_UPDATABLE_TABLE, MYF(0), table_list->alias, "DELETE");
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
if (!table_list->table || !table_list->table->created)
|
||||||
{
|
{
|
||||||
my_error(ER_VIEW_DELETE_MERGE_VIEW, MYF(0),
|
my_error(ER_VIEW_DELETE_MERGE_VIEW, MYF(0),
|
||||||
table_list->view_db.str, table_list->view_name.str);
|
table_list->view_db.str, table_list->view_name.str);
|
||||||
@ -1384,7 +1405,8 @@ static int mysql_test_select(Prepared_statement *stmt,
|
|||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (open_normal_and_derived_tables(thd, tables, 0))
|
if (open_normal_and_derived_tables(thd, tables, 0,
|
||||||
|
DT_PREPARE | DT_CREATE))
|
||||||
goto error;
|
goto error;
|
||||||
|
|
||||||
thd->used_tables= 0; // Updated by setup_fields
|
thd->used_tables= 0; // Updated by setup_fields
|
||||||
@ -1445,7 +1467,8 @@ static bool mysql_test_do_fields(Prepared_statement *stmt,
|
|||||||
if (tables && check_table_access(thd, SELECT_ACL, tables, UINT_MAX, FALSE))
|
if (tables && check_table_access(thd, SELECT_ACL, tables, UINT_MAX, FALSE))
|
||||||
DBUG_RETURN(TRUE);
|
DBUG_RETURN(TRUE);
|
||||||
|
|
||||||
if (open_normal_and_derived_tables(thd, tables, 0))
|
if (open_normal_and_derived_tables(thd, tables, 0,
|
||||||
|
DT_PREPARE | DT_CREATE))
|
||||||
DBUG_RETURN(TRUE);
|
DBUG_RETURN(TRUE);
|
||||||
DBUG_RETURN(setup_fields(thd, 0, *values, MARK_COLUMNS_NONE, 0, 0));
|
DBUG_RETURN(setup_fields(thd, 0, *values, MARK_COLUMNS_NONE, 0, 0));
|
||||||
}
|
}
|
||||||
@ -1475,7 +1498,8 @@ static bool mysql_test_set_fields(Prepared_statement *stmt,
|
|||||||
|
|
||||||
if ((tables &&
|
if ((tables &&
|
||||||
check_table_access(thd, SELECT_ACL, tables, UINT_MAX, FALSE)) ||
|
check_table_access(thd, SELECT_ACL, tables, UINT_MAX, FALSE)) ||
|
||||||
open_normal_and_derived_tables(thd, tables, 0))
|
open_normal_and_derived_tables(thd, tables, 0,
|
||||||
|
DT_PREPARE | DT_CREATE))
|
||||||
goto error;
|
goto error;
|
||||||
|
|
||||||
while ((var= it++))
|
while ((var= it++))
|
||||||
@ -1512,7 +1536,7 @@ static bool mysql_test_call_fields(Prepared_statement *stmt,
|
|||||||
|
|
||||||
if ((tables &&
|
if ((tables &&
|
||||||
check_table_access(thd, SELECT_ACL, tables, UINT_MAX, FALSE)) ||
|
check_table_access(thd, SELECT_ACL, tables, UINT_MAX, FALSE)) ||
|
||||||
open_normal_and_derived_tables(thd, tables, 0))
|
open_normal_and_derived_tables(thd, tables, 0, DT_PREPARE))
|
||||||
goto err;
|
goto err;
|
||||||
|
|
||||||
while ((item= it++))
|
while ((item= it++))
|
||||||
@ -1587,6 +1611,7 @@ select_like_stmt_test_with_open(Prepared_statement *stmt,
|
|||||||
int (*specific_prepare)(THD *thd),
|
int (*specific_prepare)(THD *thd),
|
||||||
ulong setup_tables_done_option)
|
ulong setup_tables_done_option)
|
||||||
{
|
{
|
||||||
|
uint table_count= 0;
|
||||||
DBUG_ENTER("select_like_stmt_test_with_open");
|
DBUG_ENTER("select_like_stmt_test_with_open");
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -1595,7 +1620,8 @@ select_like_stmt_test_with_open(Prepared_statement *stmt,
|
|||||||
prepared EXPLAIN yet so derived tables will clean up after
|
prepared EXPLAIN yet so derived tables will clean up after
|
||||||
themself.
|
themself.
|
||||||
*/
|
*/
|
||||||
if (open_normal_and_derived_tables(stmt->thd, tables, 0))
|
THD *thd= stmt->thd;
|
||||||
|
if (open_tables(thd, &tables, &table_count, 0))
|
||||||
DBUG_RETURN(TRUE);
|
DBUG_RETURN(TRUE);
|
||||||
|
|
||||||
DBUG_RETURN(select_like_stmt_test(stmt, specific_prepare,
|
DBUG_RETURN(select_like_stmt_test(stmt, specific_prepare,
|
||||||
@ -1640,7 +1666,8 @@ static bool mysql_test_create_table(Prepared_statement *stmt)
|
|||||||
create_table->skip_temporary= true;
|
create_table->skip_temporary= true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (open_normal_and_derived_tables(stmt->thd, lex->query_tables, 0))
|
if (open_normal_and_derived_tables(stmt->thd, lex->query_tables, 0,
|
||||||
|
DT_PREPARE | DT_CREATE))
|
||||||
DBUG_RETURN(TRUE);
|
DBUG_RETURN(TRUE);
|
||||||
|
|
||||||
if (!(lex->create_info.options & HA_LEX_CREATE_TMP_TABLE))
|
if (!(lex->create_info.options & HA_LEX_CREATE_TMP_TABLE))
|
||||||
@ -1658,7 +1685,8 @@ static bool mysql_test_create_table(Prepared_statement *stmt)
|
|||||||
we validate metadata of all CREATE TABLE statements,
|
we validate metadata of all CREATE TABLE statements,
|
||||||
which keeps metadata validation code simple.
|
which keeps metadata validation code simple.
|
||||||
*/
|
*/
|
||||||
if (open_normal_and_derived_tables(stmt->thd, lex->query_tables, 0))
|
if (open_normal_and_derived_tables(stmt->thd, lex->query_tables, 0,
|
||||||
|
DT_PREPARE))
|
||||||
DBUG_RETURN(TRUE);
|
DBUG_RETURN(TRUE);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1693,7 +1721,7 @@ static bool mysql_test_create_view(Prepared_statement *stmt)
|
|||||||
if (create_view_precheck(thd, tables, view, lex->create_view_mode))
|
if (create_view_precheck(thd, tables, view, lex->create_view_mode))
|
||||||
goto err;
|
goto err;
|
||||||
|
|
||||||
if (open_normal_and_derived_tables(thd, tables, 0))
|
if (open_normal_and_derived_tables(thd, tables, 0, DT_PREPARE))
|
||||||
goto err;
|
goto err;
|
||||||
|
|
||||||
lex->context_analysis_only|= CONTEXT_ANALYSIS_ONLY_VIEW;
|
lex->context_analysis_only|= CONTEXT_ANALYSIS_ONLY_VIEW;
|
||||||
@ -2429,6 +2457,7 @@ void reinit_stmt_before_use(THD *thd, LEX *lex)
|
|||||||
/* Fix ORDER list */
|
/* Fix ORDER list */
|
||||||
for (order= sl->order_list.first; order; order= order->next)
|
for (order= sl->order_list.first; order; order= order->next)
|
||||||
order->item= &order->item_ptr;
|
order->item= &order->item_ptr;
|
||||||
|
sl->handle_derived(lex, DT_REINIT);
|
||||||
|
|
||||||
/* clear the no_error flag for INSERT/UPDATE IGNORE */
|
/* clear the no_error flag for INSERT/UPDATE IGNORE */
|
||||||
sl->no_error= FALSE;
|
sl->no_error= FALSE;
|
||||||
@ -2472,9 +2501,6 @@ void reinit_stmt_before_use(THD *thd, LEX *lex)
|
|||||||
}
|
}
|
||||||
lex->current_select= &lex->select_lex;
|
lex->current_select= &lex->select_lex;
|
||||||
|
|
||||||
/* restore original list used in INSERT ... SELECT */
|
|
||||||
if (lex->leaf_tables_insert)
|
|
||||||
lex->select_lex.leaf_tables= lex->leaf_tables_insert;
|
|
||||||
|
|
||||||
if (lex->result)
|
if (lex->result)
|
||||||
{
|
{
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -369,6 +369,8 @@ typedef struct st_join_table {
|
|||||||
|
|
||||||
uint n_sj_tables;
|
uint n_sj_tables;
|
||||||
|
|
||||||
|
bool preread_init_done;
|
||||||
|
|
||||||
void cleanup();
|
void cleanup();
|
||||||
inline bool is_using_loose_index_scan()
|
inline bool is_using_loose_index_scan()
|
||||||
{
|
{
|
||||||
@ -474,6 +476,8 @@ typedef struct st_join_table {
|
|||||||
{
|
{
|
||||||
return (is_hash_join_key_no(key) ? hj_key : table->key_info+key);
|
return (is_hash_join_key_no(key) ? hj_key : table->key_info+key);
|
||||||
}
|
}
|
||||||
|
double scan_time();
|
||||||
|
bool preread_init();
|
||||||
} JOIN_TAB;
|
} JOIN_TAB;
|
||||||
|
|
||||||
|
|
||||||
@ -1121,6 +1125,7 @@ public:
|
|||||||
{
|
{
|
||||||
return (table_map(1) << table_count) - 1;
|
return (table_map(1) << table_count) - 1;
|
||||||
}
|
}
|
||||||
|
void drop_unused_derived_keys();
|
||||||
/*
|
/*
|
||||||
Return the table for which an index scan can be used to satisfy
|
Return the table for which an index scan can be used to satisfy
|
||||||
the sort order needed by the ORDER BY/(implicit) GROUP BY clause
|
the sort order needed by the ORDER BY/(implicit) GROUP BY clause
|
||||||
@ -1203,7 +1208,7 @@ Field* create_tmp_field_from_field(THD *thd, Field* org_field,
|
|||||||
/* functions from opt_sum.cc */
|
/* functions from opt_sum.cc */
|
||||||
bool simple_pred(Item_func *func_item, Item **args, bool *inv_order);
|
bool simple_pred(Item_func *func_item, Item **args, bool *inv_order);
|
||||||
int opt_sum_query(THD* thd,
|
int opt_sum_query(THD* thd,
|
||||||
TABLE_LIST *tables, List<Item> &all_fields, COND *conds);
|
List<TABLE_LIST> &tables, List<Item> &all_fields, COND *conds);
|
||||||
|
|
||||||
/* from sql_delete.cc, used by opt_range.cc */
|
/* from sql_delete.cc, used by opt_range.cc */
|
||||||
extern "C" int refpos_order_cmp(void* arg, const void *a,const void *b);
|
extern "C" int refpos_order_cmp(void* arg, const void *a,const void *b);
|
||||||
@ -1466,7 +1471,7 @@ void push_index_cond(JOIN_TAB *tab, uint keyno);
|
|||||||
TABLE *create_tmp_table(THD *thd,TMP_TABLE_PARAM *param,List<Item> &fields,
|
TABLE *create_tmp_table(THD *thd,TMP_TABLE_PARAM *param,List<Item> &fields,
|
||||||
ORDER *group, bool distinct, bool save_sum_fields,
|
ORDER *group, bool distinct, bool save_sum_fields,
|
||||||
ulonglong select_options, ha_rows rows_limit,
|
ulonglong select_options, ha_rows rows_limit,
|
||||||
char* alias);
|
char* alias, bool do_not_open=FALSE);
|
||||||
void free_tmp_table(THD *thd, TABLE *entry);
|
void free_tmp_table(THD *thd, TABLE *entry);
|
||||||
bool create_internal_tmp_table_from_heap(THD *thd, TABLE *table,
|
bool create_internal_tmp_table_from_heap(THD *thd, TABLE *table,
|
||||||
ENGINE_COLUMNDEF *start_recinfo,
|
ENGINE_COLUMNDEF *start_recinfo,
|
||||||
@ -1479,5 +1484,6 @@ bool create_internal_tmp_table(TABLE *table, KEY *keyinfo,
|
|||||||
bool open_tmp_table(TABLE *table);
|
bool open_tmp_table(TABLE *table);
|
||||||
void setup_tmp_table_column_bitmaps(TABLE *table, uchar *bitmaps);
|
void setup_tmp_table_column_bitmaps(TABLE *table, uchar *bitmaps);
|
||||||
double prev_record_reads(POSITION *positions, uint idx, table_map found_ref);
|
double prev_record_reads(POSITION *positions, uint idx, table_map found_ref);
|
||||||
|
void fix_list_after_tbl_changes(SELECT_LEX *new_parent, List<TABLE_LIST> *tlist);
|
||||||
|
|
||||||
#endif /* SQL_SELECT_INCLUDED */
|
#endif /* SQL_SELECT_INCLUDED */
|
||||||
|
@ -755,7 +755,8 @@ mysqld_show_create(THD *thd, TABLE_LIST *table_list)
|
|||||||
{
|
{
|
||||||
Show_create_error_handler view_error_suppressor(thd, table_list);
|
Show_create_error_handler view_error_suppressor(thd, table_list);
|
||||||
thd->push_internal_handler(&view_error_suppressor);
|
thd->push_internal_handler(&view_error_suppressor);
|
||||||
bool error= open_normal_and_derived_tables(thd, table_list, 0);
|
bool error= open_normal_and_derived_tables(thd, table_list, 0,
|
||||||
|
DT_PREPARE | DT_CREATE);
|
||||||
thd->pop_internal_handler();
|
thd->pop_internal_handler();
|
||||||
if (error && (thd->killed || thd->main_da.is_error()))
|
if (error && (thd->killed || thd->main_da.is_error()))
|
||||||
DBUG_RETURN(TRUE);
|
DBUG_RETURN(TRUE);
|
||||||
@ -930,7 +931,8 @@ mysqld_list_fields(THD *thd, TABLE_LIST *table_list, const char *wild)
|
|||||||
DBUG_ENTER("mysqld_list_fields");
|
DBUG_ENTER("mysqld_list_fields");
|
||||||
DBUG_PRINT("enter",("table: %s",table_list->table_name));
|
DBUG_PRINT("enter",("table: %s",table_list->table_name));
|
||||||
|
|
||||||
if (open_normal_and_derived_tables(thd, table_list, 0))
|
if (open_normal_and_derived_tables(thd, table_list, 0,
|
||||||
|
DT_PREPARE | DT_CREATE))
|
||||||
DBUG_VOID_RETURN;
|
DBUG_VOID_RETURN;
|
||||||
table= table_list->table;
|
table= table_list->table;
|
||||||
|
|
||||||
@ -1744,7 +1746,7 @@ view_store_options(THD *thd, TABLE_LIST *table, String *buff)
|
|||||||
static void append_algorithm(TABLE_LIST *table, String *buff)
|
static void append_algorithm(TABLE_LIST *table, String *buff)
|
||||||
{
|
{
|
||||||
buff->append(STRING_WITH_LEN("ALGORITHM="));
|
buff->append(STRING_WITH_LEN("ALGORITHM="));
|
||||||
switch ((int8)table->algorithm) {
|
switch ((int16)table->algorithm) {
|
||||||
case VIEW_ALGORITHM_UNDEFINED:
|
case VIEW_ALGORITHM_UNDEFINED:
|
||||||
buff->append(STRING_WITH_LEN("UNDEFINED "));
|
buff->append(STRING_WITH_LEN("UNDEFINED "));
|
||||||
break;
|
break;
|
||||||
@ -3443,8 +3445,9 @@ fill_schema_show_cols_or_idxs(THD *thd, TABLE_LIST *tables,
|
|||||||
SQLCOM_SHOW_FIELDS is used because it satisfies 'only_view_structure()'
|
SQLCOM_SHOW_FIELDS is used because it satisfies 'only_view_structure()'
|
||||||
*/
|
*/
|
||||||
lex->sql_command= SQLCOM_SHOW_FIELDS;
|
lex->sql_command= SQLCOM_SHOW_FIELDS;
|
||||||
res= open_normal_and_derived_tables(thd, show_table_list,
|
res= (open_normal_and_derived_tables(thd, show_table_list,
|
||||||
MYSQL_LOCK_IGNORE_FLUSH);
|
MYSQL_LOCK_IGNORE_FLUSH,
|
||||||
|
DT_PREPARE | DT_CREATE));
|
||||||
lex->sql_command= save_sql_command;
|
lex->sql_command= save_sql_command;
|
||||||
/*
|
/*
|
||||||
get_all_tables() returns 1 on failure and 0 on success thus
|
get_all_tables() returns 1 on failure and 0 on success thus
|
||||||
@ -3886,8 +3889,9 @@ int get_all_tables(THD *thd, TABLE_LIST *tables, COND *cond)
|
|||||||
show_table_list->i_s_requested_object=
|
show_table_list->i_s_requested_object=
|
||||||
schema_table->i_s_requested_object;
|
schema_table->i_s_requested_object;
|
||||||
DEBUG_SYNC(thd, "before_open_in_get_all_tables");
|
DEBUG_SYNC(thd, "before_open_in_get_all_tables");
|
||||||
res= open_normal_and_derived_tables(thd, show_table_list,
|
res= (open_normal_and_derived_tables(thd, show_table_list,
|
||||||
MYSQL_LOCK_IGNORE_FLUSH);
|
MYSQL_LOCK_IGNORE_FLUSH,
|
||||||
|
DT_PREPARE | DT_CREATE));
|
||||||
lex->sql_command= save_sql_command;
|
lex->sql_command= save_sql_command;
|
||||||
/*
|
/*
|
||||||
XXX: show_table_list has a flag i_is_requested,
|
XXX: show_table_list has a flag i_is_requested,
|
||||||
|
@ -4729,8 +4729,13 @@ static bool mysql_admin_table(THD* thd, TABLE_LIST* tables,
|
|||||||
thd->no_warnings_for_error= no_warnings_for_error;
|
thd->no_warnings_for_error= no_warnings_for_error;
|
||||||
if (view_operator_func == NULL)
|
if (view_operator_func == NULL)
|
||||||
table->required_type=FRMTYPE_TABLE;
|
table->required_type=FRMTYPE_TABLE;
|
||||||
|
if (lex->sql_command == SQLCOM_CHECK ||
|
||||||
|
lex->sql_command == SQLCOM_REPAIR ||
|
||||||
|
lex->sql_command == SQLCOM_ANALYZE ||
|
||||||
|
lex->sql_command == SQLCOM_OPTIMIZE)
|
||||||
|
thd->prepare_derived_at_open= TRUE;
|
||||||
open_and_lock_tables(thd, table);
|
open_and_lock_tables(thd, table);
|
||||||
|
thd->prepare_derived_at_open= FALSE;
|
||||||
thd->no_warnings_for_error= 0;
|
thd->no_warnings_for_error= 0;
|
||||||
table->next_global= save_next_global;
|
table->next_global= save_next_global;
|
||||||
table->next_local= save_next_local;
|
table->next_local= save_next_local;
|
||||||
@ -4828,7 +4833,7 @@ static bool mysql_admin_table(THD* thd, TABLE_LIST* tables,
|
|||||||
else
|
else
|
||||||
/* Default failure code is corrupt table */
|
/* Default failure code is corrupt table */
|
||||||
result_code= HA_ADMIN_CORRUPT;
|
result_code= HA_ADMIN_CORRUPT;
|
||||||
goto send_result;
|
goto send_result;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (table->view)
|
if (table->view)
|
||||||
|
131
sql/sql_union.cc
131
sql/sql_union.cc
@ -112,6 +112,7 @@ bool select_union::flush()
|
|||||||
options create options
|
options create options
|
||||||
table_alias name of the temporary table
|
table_alias name of the temporary table
|
||||||
bit_fields_as_long convert bit fields to ulonglong
|
bit_fields_as_long convert bit fields to ulonglong
|
||||||
|
create_table whether to physically create result table
|
||||||
|
|
||||||
DESCRIPTION
|
DESCRIPTION
|
||||||
Create a temporary table that is used to store the result of a UNION,
|
Create a temporary table that is used to store the result of a UNION,
|
||||||
@ -126,7 +127,7 @@ bool
|
|||||||
select_union::create_result_table(THD *thd_arg, List<Item> *column_types,
|
select_union::create_result_table(THD *thd_arg, List<Item> *column_types,
|
||||||
bool is_union_distinct, ulonglong options,
|
bool is_union_distinct, ulonglong options,
|
||||||
const char *alias,
|
const char *alias,
|
||||||
bool bit_fields_as_long)
|
bool bit_fields_as_long, bool create_table)
|
||||||
{
|
{
|
||||||
DBUG_ASSERT(table == 0);
|
DBUG_ASSERT(table == 0);
|
||||||
tmp_table_param.init();
|
tmp_table_param.init();
|
||||||
@ -135,15 +136,19 @@ select_union::create_result_table(THD *thd_arg, List<Item> *column_types,
|
|||||||
|
|
||||||
if (! (table= create_tmp_table(thd_arg, &tmp_table_param, *column_types,
|
if (! (table= create_tmp_table(thd_arg, &tmp_table_param, *column_types,
|
||||||
(ORDER*) 0, is_union_distinct, 1,
|
(ORDER*) 0, is_union_distinct, 1,
|
||||||
options, HA_POS_ERROR, (char*) alias)))
|
options, HA_POS_ERROR, (char*) alias,
|
||||||
|
!create_table)))
|
||||||
return TRUE;
|
return TRUE;
|
||||||
//psergey-merge-fix:
|
|
||||||
table->keys_in_use_for_query.clear_all();
|
table->keys_in_use_for_query.clear_all();
|
||||||
for (uint i=0; i < table->s->fields; i++)
|
for (uint i=0; i < table->s->fields; i++)
|
||||||
table->field[i]->flags &= ~PART_KEY_FLAG;
|
table->field[i]->flags &= ~PART_KEY_FLAG;
|
||||||
|
|
||||||
table->file->extra(HA_EXTRA_WRITE_CACHE);
|
if (create_table)
|
||||||
table->file->extra(HA_EXTRA_IGNORE_DUP_KEY);
|
{
|
||||||
|
table->file->extra(HA_EXTRA_WRITE_CACHE);
|
||||||
|
table->file->extra(HA_EXTRA_IGNORE_DUP_KEY);
|
||||||
|
}
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -309,6 +314,7 @@ bool st_select_lex_unit::prepare(THD *thd_arg, select_result *sel_result,
|
|||||||
(is_union_select ? NULL :
|
(is_union_select ? NULL :
|
||||||
thd_arg->lex->proc_list.first),
|
thd_arg->lex->proc_list.first),
|
||||||
sl, this);
|
sl, this);
|
||||||
|
|
||||||
/* There are no * in the statement anymore (for PS) */
|
/* There are no * in the statement anymore (for PS) */
|
||||||
sl->with_wild= 0;
|
sl->with_wild= 0;
|
||||||
last_procedure= join->procedure;
|
last_procedure= join->procedure;
|
||||||
@ -363,6 +369,8 @@ bool st_select_lex_unit::prepare(THD *thd_arg, select_result *sel_result,
|
|||||||
List_iterator_fast<Item> tp(types);
|
List_iterator_fast<Item> tp(types);
|
||||||
Item *type;
|
Item *type;
|
||||||
ulonglong create_options;
|
ulonglong create_options;
|
||||||
|
uint save_tablenr= 0;
|
||||||
|
table_map save_map= 0;
|
||||||
|
|
||||||
while ((type= tp++))
|
while ((type= tp++))
|
||||||
{
|
{
|
||||||
@ -415,12 +423,22 @@ bool st_select_lex_unit::prepare(THD *thd_arg, select_result *sel_result,
|
|||||||
create_options= create_options | TMP_TABLE_FORCE_MYISAM;
|
create_options= create_options | TMP_TABLE_FORCE_MYISAM;
|
||||||
|
|
||||||
if (union_result->create_result_table(thd, &types, test(union_distinct),
|
if (union_result->create_result_table(thd, &types, test(union_distinct),
|
||||||
create_options, "", FALSE))
|
create_options, "", FALSE, TRUE))
|
||||||
goto err;
|
goto err;
|
||||||
|
if (fake_select_lex && !fake_select_lex->first_cond_optimization)
|
||||||
|
{
|
||||||
|
save_tablenr= result_table_list.tablenr_exec;
|
||||||
|
save_map= result_table_list.map_exec;
|
||||||
|
}
|
||||||
bzero((char*) &result_table_list, sizeof(result_table_list));
|
bzero((char*) &result_table_list, sizeof(result_table_list));
|
||||||
result_table_list.db= (char*) "";
|
result_table_list.db= (char*) "";
|
||||||
result_table_list.table_name= result_table_list.alias= (char*) "union";
|
result_table_list.table_name= result_table_list.alias= (char*) "union";
|
||||||
result_table_list.table= table= union_result->table;
|
result_table_list.table= table= union_result->table;
|
||||||
|
if (fake_select_lex && !fake_select_lex->first_cond_optimization)
|
||||||
|
{
|
||||||
|
result_table_list.tablenr_exec= save_tablenr;
|
||||||
|
result_table_list.map_exec= save_map;
|
||||||
|
}
|
||||||
|
|
||||||
thd_arg->lex->current_select= lex_select_save;
|
thd_arg->lex->current_select= lex_select_save;
|
||||||
if (!item_list.elements)
|
if (!item_list.elements)
|
||||||
@ -484,17 +502,20 @@ err:
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool st_select_lex_unit::exec()
|
/**
|
||||||
|
Run optimization phase.
|
||||||
|
|
||||||
|
@return FALSE unit successfully passed optimization phase.
|
||||||
|
@return TRUE an error occur.
|
||||||
|
*/
|
||||||
|
bool st_select_lex_unit::optimize()
|
||||||
{
|
{
|
||||||
SELECT_LEX *lex_select_save= thd->lex->current_select;
|
SELECT_LEX *lex_select_save= thd->lex->current_select;
|
||||||
SELECT_LEX *select_cursor=first_select();
|
SELECT_LEX *select_cursor=first_select();
|
||||||
ulonglong add_rows=0;
|
DBUG_ENTER("st_select_lex_unit::optimize");
|
||||||
ha_rows examined_rows= 0;
|
|
||||||
DBUG_ENTER("st_select_lex_unit::exec");
|
|
||||||
|
|
||||||
if (executed && !uncacheable && !describe)
|
if (optimized && !uncacheable && !describe)
|
||||||
DBUG_RETURN(FALSE);
|
DBUG_RETURN(FALSE);
|
||||||
executed= 1;
|
|
||||||
|
|
||||||
if (uncacheable || !item || !item->assigned() || describe)
|
if (uncacheable || !item || !item->assigned() || describe)
|
||||||
{
|
{
|
||||||
@ -516,12 +537,71 @@ bool st_select_lex_unit::exec()
|
|||||||
}
|
}
|
||||||
for (SELECT_LEX *sl= select_cursor; sl; sl= sl->next_select())
|
for (SELECT_LEX *sl= select_cursor; sl; sl= sl->next_select())
|
||||||
{
|
{
|
||||||
ha_rows records_at_start= 0;
|
|
||||||
thd->lex->current_select= sl;
|
thd->lex->current_select= sl;
|
||||||
|
|
||||||
if (optimized)
|
if (optimized)
|
||||||
saved_error= sl->join->reinit();
|
saved_error= sl->join->reinit();
|
||||||
else
|
else
|
||||||
|
{
|
||||||
|
set_limit(sl);
|
||||||
|
if (sl == global_parameters || describe)
|
||||||
|
{
|
||||||
|
offset_limit_cnt= 0;
|
||||||
|
/*
|
||||||
|
We can't use LIMIT at this stage if we are using ORDER BY for the
|
||||||
|
whole query
|
||||||
|
*/
|
||||||
|
if (sl->order_list.first || describe)
|
||||||
|
select_limit_cnt= HA_POS_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
When using braces, SQL_CALC_FOUND_ROWS affects the whole query:
|
||||||
|
we don't calculate found_rows() per union part.
|
||||||
|
Otherwise, SQL_CALC_FOUND_ROWS should be done on all sub parts.
|
||||||
|
*/
|
||||||
|
sl->join->select_options=
|
||||||
|
(select_limit_cnt == HA_POS_ERROR || sl->braces) ?
|
||||||
|
sl->options & ~OPTION_FOUND_ROWS : sl->options | found_rows_for_union;
|
||||||
|
|
||||||
|
saved_error= sl->join->optimize();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (saved_error)
|
||||||
|
{
|
||||||
|
thd->lex->current_select= lex_select_save;
|
||||||
|
DBUG_RETURN(saved_error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
optimized= 1;
|
||||||
|
|
||||||
|
thd->lex->current_select= lex_select_save;
|
||||||
|
DBUG_RETURN(saved_error);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool st_select_lex_unit::exec()
|
||||||
|
{
|
||||||
|
SELECT_LEX *lex_select_save= thd->lex->current_select;
|
||||||
|
SELECT_LEX *select_cursor=first_select();
|
||||||
|
ulonglong add_rows=0;
|
||||||
|
ha_rows examined_rows= 0;
|
||||||
|
DBUG_ENTER("st_select_lex_unit::exec");
|
||||||
|
|
||||||
|
if (executed && !uncacheable && !describe)
|
||||||
|
DBUG_RETURN(FALSE);
|
||||||
|
executed= 1;
|
||||||
|
|
||||||
|
saved_error= optimize();
|
||||||
|
|
||||||
|
if (uncacheable || !item || !item->assigned() || describe)
|
||||||
|
{
|
||||||
|
for (SELECT_LEX *sl= select_cursor; sl; sl= sl->next_select())
|
||||||
|
{
|
||||||
|
ha_rows records_at_start= 0;
|
||||||
|
thd->lex->current_select= sl;
|
||||||
|
|
||||||
{
|
{
|
||||||
set_limit(sl);
|
set_limit(sl);
|
||||||
if (sl == global_parameters || describe)
|
if (sl == global_parameters || describe)
|
||||||
@ -595,7 +675,6 @@ bool st_select_lex_unit::exec()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
optimized= 1;
|
|
||||||
|
|
||||||
/* Send result to 'result' */
|
/* Send result to 'result' */
|
||||||
saved_error= TRUE;
|
saved_error= TRUE;
|
||||||
@ -871,3 +950,27 @@ void st_select_lex::cleanup_all_joins(bool full)
|
|||||||
for (sl= unit->first_select(); sl; sl= sl->next_select())
|
for (sl= unit->first_select(); sl; sl= sl->next_select())
|
||||||
sl->cleanup_all_joins(full);
|
sl->cleanup_all_joins(full);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
Set exclude_from_table_unique_test for selects of this unit and all
|
||||||
|
underlying selects.
|
||||||
|
|
||||||
|
@note used to exclude materialized derived tables (views) from unique
|
||||||
|
table check.
|
||||||
|
*/
|
||||||
|
|
||||||
|
void st_select_lex_unit::set_unique_exclude()
|
||||||
|
{
|
||||||
|
for (SELECT_LEX *sl= first_select(); sl; sl= sl->next_select())
|
||||||
|
{
|
||||||
|
sl->exclude_from_table_unique_test= TRUE;
|
||||||
|
for (SELECT_LEX_UNIT *unit= sl->first_inner_unit();
|
||||||
|
unit;
|
||||||
|
unit= unit->next_unit())
|
||||||
|
{
|
||||||
|
unit->set_unique_exclude();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@ -229,7 +229,11 @@ int mysql_update(THD *thd,
|
|||||||
if (open_tables(thd, &table_list, &table_count, 0))
|
if (open_tables(thd, &table_list, &table_count, 0))
|
||||||
DBUG_RETURN(1);
|
DBUG_RETURN(1);
|
||||||
|
|
||||||
if (table_list->multitable_view)
|
//Prepare views so they are handled correctly.
|
||||||
|
if (mysql_handle_derived(thd->lex, DT_INIT))
|
||||||
|
DBUG_RETURN(1);
|
||||||
|
|
||||||
|
if (table_list->is_multitable())
|
||||||
{
|
{
|
||||||
DBUG_ASSERT(table_list->view != 0);
|
DBUG_ASSERT(table_list->view != 0);
|
||||||
DBUG_PRINT("info", ("Switch to multi-update"));
|
DBUG_PRINT("info", ("Switch to multi-update"));
|
||||||
@ -244,15 +248,19 @@ int mysql_update(THD *thd,
|
|||||||
DBUG_RETURN(1);
|
DBUG_RETURN(1);
|
||||||
close_tables_for_reopen(thd, &table_list);
|
close_tables_for_reopen(thd, &table_list);
|
||||||
}
|
}
|
||||||
|
if (table_list->handle_derived(thd->lex, DT_MERGE_FOR_INSERT))
|
||||||
if (mysql_handle_derived(thd->lex, &mysql_derived_prepare) ||
|
DBUG_RETURN(1);
|
||||||
(thd->fill_derived_tables() &&
|
if (table_list->handle_derived(thd->lex, DT_PREPARE))
|
||||||
mysql_handle_derived(thd->lex, &mysql_derived_filling)))
|
|
||||||
DBUG_RETURN(1);
|
DBUG_RETURN(1);
|
||||||
|
|
||||||
thd_proc_info(thd, "init");
|
thd_proc_info(thd, "init");
|
||||||
table= table_list->table;
|
table= table_list->table;
|
||||||
|
|
||||||
|
if (!table_list->updatable)
|
||||||
|
{
|
||||||
|
my_error(ER_NON_UPDATABLE_TABLE, MYF(0), table_list->alias, "UPDATE");
|
||||||
|
DBUG_RETURN(1);
|
||||||
|
}
|
||||||
/* Calculate "table->covering_keys" based on the WHERE */
|
/* Calculate "table->covering_keys" based on the WHERE */
|
||||||
table->covering_keys= table->s->keys_in_use;
|
table->covering_keys= table->s->keys_in_use;
|
||||||
table->quick_keys.clear_all();
|
table->quick_keys.clear_all();
|
||||||
@ -271,13 +279,17 @@ int mysql_update(THD *thd,
|
|||||||
table_list->grant.want_privilege= table->grant.want_privilege= want_privilege;
|
table_list->grant.want_privilege= table->grant.want_privilege= want_privilege;
|
||||||
table_list->register_want_access(want_privilege);
|
table_list->register_want_access(want_privilege);
|
||||||
#endif
|
#endif
|
||||||
|
/* 'Unfix' fields to allow correct marking by the setup_fields function. */
|
||||||
|
if (table_list->is_view())
|
||||||
|
unfix_fields(fields);
|
||||||
|
|
||||||
if (setup_fields_with_no_wrap(thd, 0, fields, MARK_COLUMNS_WRITE, 0, 0))
|
if (setup_fields_with_no_wrap(thd, 0, fields, MARK_COLUMNS_WRITE, 0, 0))
|
||||||
DBUG_RETURN(1); /* purecov: inspected */
|
DBUG_RETURN(1); /* purecov: inspected */
|
||||||
if (table_list->view && check_fields(thd, fields))
|
if (table_list->view && check_fields(thd, fields))
|
||||||
{
|
{
|
||||||
DBUG_RETURN(1);
|
DBUG_RETURN(1);
|
||||||
}
|
}
|
||||||
if (!table_list->updatable || check_key_in_view(thd, table_list))
|
if (check_key_in_view(thd, table_list))
|
||||||
{
|
{
|
||||||
my_error(ER_NON_UPDATABLE_TABLE, MYF(0), table_list->alias, "UPDATE");
|
my_error(ER_NON_UPDATABLE_TABLE, MYF(0), table_list->alias, "UPDATE");
|
||||||
DBUG_RETURN(1);
|
DBUG_RETURN(1);
|
||||||
@ -869,6 +881,11 @@ int mysql_update(THD *thd,
|
|||||||
}
|
}
|
||||||
thd->count_cuted_fields= CHECK_FIELD_IGNORE; /* calc cuted fields */
|
thd->count_cuted_fields= CHECK_FIELD_IGNORE; /* calc cuted fields */
|
||||||
thd->abort_on_warning= 0;
|
thd->abort_on_warning= 0;
|
||||||
|
if (thd->lex->current_select->first_cond_optimization)
|
||||||
|
{
|
||||||
|
thd->lex->current_select->save_leaf_tables(thd);
|
||||||
|
thd->lex->current_select->first_cond_optimization= 0;
|
||||||
|
}
|
||||||
DBUG_RETURN((error >= 0 || thd->is_error()) ? 1 : 0);
|
DBUG_RETURN((error >= 0 || thd->is_error()) ? 1 : 0);
|
||||||
|
|
||||||
err:
|
err:
|
||||||
@ -929,8 +946,8 @@ bool mysql_prepare_update(THD *thd, TABLE_LIST *table_list,
|
|||||||
if (setup_tables_and_check_access(thd, &select_lex->context,
|
if (setup_tables_and_check_access(thd, &select_lex->context,
|
||||||
&select_lex->top_join_list,
|
&select_lex->top_join_list,
|
||||||
table_list,
|
table_list,
|
||||||
&select_lex->leaf_tables,
|
select_lex->leaf_tables,
|
||||||
FALSE, UPDATE_ACL, SELECT_ACL) ||
|
FALSE, UPDATE_ACL, SELECT_ACL, TRUE) ||
|
||||||
setup_conds(thd, table_list, select_lex->leaf_tables, conds) ||
|
setup_conds(thd, table_list, select_lex->leaf_tables, conds) ||
|
||||||
select_lex->setup_ref_array(thd, order_num) ||
|
select_lex->setup_ref_array(thd, order_num) ||
|
||||||
setup_order(thd, select_lex->ref_pointer_array,
|
setup_order(thd, select_lex->ref_pointer_array,
|
||||||
@ -968,7 +985,7 @@ static table_map get_table_map(List<Item> *items)
|
|||||||
table_map map= 0;
|
table_map map= 0;
|
||||||
|
|
||||||
while ((item= (Item_field *) item_it++))
|
while ((item= (Item_field *) item_it++))
|
||||||
map|= item->used_tables();
|
map|= item->all_used_tables();
|
||||||
DBUG_PRINT("info", ("table_map: 0x%08lx", (long) map));
|
DBUG_PRINT("info", ("table_map: 0x%08lx", (long) map));
|
||||||
return map;
|
return map;
|
||||||
}
|
}
|
||||||
@ -990,7 +1007,7 @@ int mysql_multi_update_prepare(THD *thd)
|
|||||||
{
|
{
|
||||||
LEX *lex= thd->lex;
|
LEX *lex= thd->lex;
|
||||||
TABLE_LIST *table_list= lex->query_tables;
|
TABLE_LIST *table_list= lex->query_tables;
|
||||||
TABLE_LIST *tl, *leaves;
|
TABLE_LIST *tl;
|
||||||
List<Item> *fields= &lex->select_lex.item_list;
|
List<Item> *fields= &lex->select_lex.item_list;
|
||||||
table_map tables_for_update;
|
table_map tables_for_update;
|
||||||
bool update_view= 0;
|
bool update_view= 0;
|
||||||
@ -1013,19 +1030,24 @@ reopen_tables:
|
|||||||
/* open tables and create derived ones, but do not lock and fill them */
|
/* open tables and create derived ones, but do not lock and fill them */
|
||||||
if (((original_multiupdate || need_reopen) &&
|
if (((original_multiupdate || need_reopen) &&
|
||||||
open_tables(thd, &table_list, &table_count, 0)) ||
|
open_tables(thd, &table_list, &table_count, 0)) ||
|
||||||
mysql_handle_derived(lex, &mysql_derived_prepare))
|
mysql_handle_derived(lex, DT_INIT))
|
||||||
DBUG_RETURN(TRUE);
|
DBUG_RETURN(TRUE);
|
||||||
/*
|
/*
|
||||||
setup_tables() need for VIEWs. JOIN::prepare() will call setup_tables()
|
setup_tables() need for VIEWs. JOIN::prepare() will call setup_tables()
|
||||||
second time, but this call will do nothing (there are check for second
|
second time, but this call will do nothing (there are check for second
|
||||||
call in setup_tables()).
|
call in setup_tables()).
|
||||||
*/
|
*/
|
||||||
|
//We need to merge for insert prior to prepare.
|
||||||
|
if (mysql_handle_list_of_derived(lex, table_list, DT_MERGE_FOR_INSERT))
|
||||||
|
DBUG_RETURN(1);
|
||||||
|
if (mysql_handle_derived(lex, DT_PREPARE))
|
||||||
|
DBUG_RETURN(TRUE);
|
||||||
|
|
||||||
if (setup_tables_and_check_access(thd, &lex->select_lex.context,
|
if (setup_tables_and_check_access(thd, &lex->select_lex.context,
|
||||||
&lex->select_lex.top_join_list,
|
&lex->select_lex.top_join_list,
|
||||||
table_list,
|
table_list,
|
||||||
&lex->select_lex.leaf_tables, FALSE,
|
lex->select_lex.leaf_tables, FALSE,
|
||||||
UPDATE_ACL, SELECT_ACL))
|
UPDATE_ACL, SELECT_ACL, TRUE))
|
||||||
DBUG_RETURN(TRUE);
|
DBUG_RETURN(TRUE);
|
||||||
|
|
||||||
if (setup_fields_with_no_wrap(thd, 0, *fields, MARK_COLUMNS_WRITE, 0, 0))
|
if (setup_fields_with_no_wrap(thd, 0, *fields, MARK_COLUMNS_WRITE, 0, 0))
|
||||||
@ -1050,8 +1072,8 @@ reopen_tables:
|
|||||||
/*
|
/*
|
||||||
Setup timestamp handling and locking mode
|
Setup timestamp handling and locking mode
|
||||||
*/
|
*/
|
||||||
leaves= lex->select_lex.leaf_tables;
|
List_iterator<TABLE_LIST> ti(lex->select_lex.leaf_tables);
|
||||||
for (tl= leaves; tl; tl= tl->next_leaf)
|
while ((tl= ti++))
|
||||||
{
|
{
|
||||||
TABLE *table= tl->table;
|
TABLE *table= tl->table;
|
||||||
/* Only set timestamp column if this is not modified */
|
/* Only set timestamp column if this is not modified */
|
||||||
@ -1093,7 +1115,7 @@ reopen_tables:
|
|||||||
for (tl= table_list; tl; tl= tl->next_local)
|
for (tl= table_list; tl; tl= tl->next_local)
|
||||||
{
|
{
|
||||||
/* Check access privileges for table */
|
/* Check access privileges for table */
|
||||||
if (!tl->derived)
|
if (!tl->is_derived())
|
||||||
{
|
{
|
||||||
uint want_privilege= tl->updating ? UPDATE_ACL : SELECT_ACL;
|
uint want_privilege= tl->updating ? UPDATE_ACL : SELECT_ACL;
|
||||||
if (check_access(thd, want_privilege,
|
if (check_access(thd, want_privilege,
|
||||||
@ -1107,7 +1129,7 @@ reopen_tables:
|
|||||||
/* check single table update for view compound from several tables */
|
/* check single table update for view compound from several tables */
|
||||||
for (tl= table_list; tl; tl= tl->next_local)
|
for (tl= table_list; tl; tl= tl->next_local)
|
||||||
{
|
{
|
||||||
if (tl->effective_algorithm == VIEW_ALGORITHM_MERGE)
|
if (tl->is_merged_derived())
|
||||||
{
|
{
|
||||||
TABLE_LIST *for_update= 0;
|
TABLE_LIST *for_update= 0;
|
||||||
if (tl->check_single_table(&for_update, tables_for_update, tl))
|
if (tl->check_single_table(&for_update, tables_for_update, tl))
|
||||||
@ -1162,6 +1184,8 @@ reopen_tables:
|
|||||||
*/
|
*/
|
||||||
unit->unclean();
|
unit->unclean();
|
||||||
}
|
}
|
||||||
|
// Reset 'prepared' flags for all derived tables/views
|
||||||
|
mysql_handle_list_of_derived(thd->lex, table_list, DT_REINIT);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Also we need to cleanup Natural_join_column::table_field items.
|
Also we need to cleanup Natural_join_column::table_field items.
|
||||||
@ -1184,7 +1208,8 @@ reopen_tables:
|
|||||||
*/
|
*/
|
||||||
lex->select_lex.exclude_from_table_unique_test= TRUE;
|
lex->select_lex.exclude_from_table_unique_test= TRUE;
|
||||||
/* We only need SELECT privilege for columns in the values list */
|
/* We only need SELECT privilege for columns in the values list */
|
||||||
for (tl= leaves; tl; tl= tl->next_leaf)
|
ti.rewind();
|
||||||
|
while ((tl= ti++))
|
||||||
{
|
{
|
||||||
TABLE *table= tl->table;
|
TABLE *table= tl->table;
|
||||||
TABLE_LIST *tlist;
|
TABLE_LIST *tlist;
|
||||||
@ -1213,10 +1238,6 @@ reopen_tables:
|
|||||||
*/
|
*/
|
||||||
lex->select_lex.exclude_from_table_unique_test= FALSE;
|
lex->select_lex.exclude_from_table_unique_test= FALSE;
|
||||||
|
|
||||||
if (thd->fill_derived_tables() &&
|
|
||||||
mysql_handle_derived(lex, &mysql_derived_filling))
|
|
||||||
DBUG_RETURN(TRUE);
|
|
||||||
|
|
||||||
DBUG_RETURN (FALSE);
|
DBUG_RETURN (FALSE);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1239,7 +1260,7 @@ bool mysql_multi_update(THD *thd,
|
|||||||
DBUG_ENTER("mysql_multi_update");
|
DBUG_ENTER("mysql_multi_update");
|
||||||
|
|
||||||
if (!(result= new multi_update(table_list,
|
if (!(result= new multi_update(table_list,
|
||||||
thd->lex->select_lex.leaf_tables,
|
&thd->lex->select_lex.leaf_tables,
|
||||||
fields, values,
|
fields, values,
|
||||||
handle_duplicates, ignore)))
|
handle_duplicates, ignore)))
|
||||||
DBUG_RETURN(TRUE);
|
DBUG_RETURN(TRUE);
|
||||||
@ -1274,7 +1295,7 @@ bool mysql_multi_update(THD *thd,
|
|||||||
|
|
||||||
|
|
||||||
multi_update::multi_update(TABLE_LIST *table_list,
|
multi_update::multi_update(TABLE_LIST *table_list,
|
||||||
TABLE_LIST *leaves_list,
|
List<TABLE_LIST> *leaves_list,
|
||||||
List<Item> *field_list, List<Item> *value_list,
|
List<Item> *field_list, List<Item> *value_list,
|
||||||
enum enum_duplicates handle_duplicates_arg,
|
enum enum_duplicates handle_duplicates_arg,
|
||||||
bool ignore_arg)
|
bool ignore_arg)
|
||||||
@ -1292,6 +1313,7 @@ multi_update::multi_update(TABLE_LIST *table_list,
|
|||||||
|
|
||||||
int multi_update::prepare(List<Item> ¬_used_values,
|
int multi_update::prepare(List<Item> ¬_used_values,
|
||||||
SELECT_LEX_UNIT *lex_unit)
|
SELECT_LEX_UNIT *lex_unit)
|
||||||
|
|
||||||
{
|
{
|
||||||
TABLE_LIST *table_ref;
|
TABLE_LIST *table_ref;
|
||||||
SQL_I_List<TABLE_LIST> update;
|
SQL_I_List<TABLE_LIST> update;
|
||||||
@ -1301,12 +1323,20 @@ int multi_update::prepare(List<Item> ¬_used_values,
|
|||||||
List_iterator_fast<Item> value_it(*values);
|
List_iterator_fast<Item> value_it(*values);
|
||||||
uint i, max_fields;
|
uint i, max_fields;
|
||||||
uint leaf_table_count= 0;
|
uint leaf_table_count= 0;
|
||||||
|
List_iterator<TABLE_LIST> ti(*leaves);
|
||||||
DBUG_ENTER("multi_update::prepare");
|
DBUG_ENTER("multi_update::prepare");
|
||||||
|
|
||||||
thd->count_cuted_fields= CHECK_FIELD_WARN;
|
thd->count_cuted_fields= CHECK_FIELD_WARN;
|
||||||
thd->cuted_fields=0L;
|
thd->cuted_fields=0L;
|
||||||
thd_proc_info(thd, "updating main table");
|
thd_proc_info(thd, "updating main table");
|
||||||
|
|
||||||
|
SELECT_LEX *select_lex= lex_unit->first_select();
|
||||||
|
if (select_lex->first_cond_optimization)
|
||||||
|
{
|
||||||
|
if (select_lex->handle_derived(thd->lex, DT_MERGE))
|
||||||
|
DBUG_RETURN(TRUE);
|
||||||
|
}
|
||||||
|
|
||||||
tables_to_update= get_table_map(fields);
|
tables_to_update= get_table_map(fields);
|
||||||
|
|
||||||
if (!tables_to_update)
|
if (!tables_to_update)
|
||||||
@ -1320,7 +1350,7 @@ int multi_update::prepare(List<Item> ¬_used_values,
|
|||||||
TABLE::tmp_set by pointing TABLE::read_set to it and then restore it after
|
TABLE::tmp_set by pointing TABLE::read_set to it and then restore it after
|
||||||
setup_fields().
|
setup_fields().
|
||||||
*/
|
*/
|
||||||
for (table_ref= leaves; table_ref; table_ref= table_ref->next_leaf)
|
while ((table_ref= ti++))
|
||||||
{
|
{
|
||||||
TABLE *table= table_ref->table;
|
TABLE *table= table_ref->table;
|
||||||
if (tables_to_update & table->map)
|
if (tables_to_update & table->map)
|
||||||
@ -1338,7 +1368,8 @@ int multi_update::prepare(List<Item> ¬_used_values,
|
|||||||
|
|
||||||
int error= setup_fields(thd, 0, *values, MARK_COLUMNS_READ, 0, 0);
|
int error= setup_fields(thd, 0, *values, MARK_COLUMNS_READ, 0, 0);
|
||||||
|
|
||||||
for (table_ref= leaves; table_ref; table_ref= table_ref->next_leaf)
|
ti.rewind();
|
||||||
|
while ((table_ref= ti++))
|
||||||
{
|
{
|
||||||
TABLE *table= table_ref->table;
|
TABLE *table= table_ref->table;
|
||||||
if (tables_to_update & table->map)
|
if (tables_to_update & table->map)
|
||||||
@ -1367,7 +1398,8 @@ int multi_update::prepare(List<Item> ¬_used_values,
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
update.empty();
|
update.empty();
|
||||||
for (table_ref= leaves; table_ref; table_ref= table_ref->next_leaf)
|
ti.rewind();
|
||||||
|
while ((table_ref= ti++))
|
||||||
{
|
{
|
||||||
/* TODO: add support of view of join support */
|
/* TODO: add support of view of join support */
|
||||||
TABLE *table=table_ref->table;
|
TABLE *table=table_ref->table;
|
||||||
@ -1593,9 +1625,9 @@ loop_end:
|
|||||||
{
|
{
|
||||||
table_map unupdated_tables= table_ref->check_option->used_tables() &
|
table_map unupdated_tables= table_ref->check_option->used_tables() &
|
||||||
~first_table_for_update->map;
|
~first_table_for_update->map;
|
||||||
for (TABLE_LIST *tbl_ref =leaves;
|
List_iterator<TABLE_LIST> ti(*leaves);
|
||||||
unupdated_tables && tbl_ref;
|
TABLE_LIST *tbl_ref;
|
||||||
tbl_ref= tbl_ref->next_leaf)
|
while ((tbl_ref= ti++) && unupdated_tables)
|
||||||
{
|
{
|
||||||
if (unupdated_tables & tbl_ref->table->map)
|
if (unupdated_tables & tbl_ref->table->map)
|
||||||
unupdated_tables&= ~tbl_ref->table->map;
|
unupdated_tables&= ~tbl_ref->table->map;
|
||||||
|
@ -248,7 +248,7 @@ fill_defined_view_parts (THD *thd, TABLE_LIST *view)
|
|||||||
view->definer.user= decoy.definer.user;
|
view->definer.user= decoy.definer.user;
|
||||||
lex->definer= &view->definer;
|
lex->definer= &view->definer;
|
||||||
}
|
}
|
||||||
if (lex->create_view_algorithm == VIEW_ALGORITHM_UNDEFINED)
|
if (lex->create_view_algorithm == DTYPE_ALGORITHM_UNDEFINED)
|
||||||
lex->create_view_algorithm= (uint8) decoy.algorithm;
|
lex->create_view_algorithm= (uint8) decoy.algorithm;
|
||||||
if (lex->create_view_suid == VIEW_SUID_DEFAULT)
|
if (lex->create_view_suid == VIEW_SUID_DEFAULT)
|
||||||
lex->create_view_suid= decoy.view_suid ?
|
lex->create_view_suid= decoy.view_suid ?
|
||||||
@ -843,7 +843,7 @@ static int mysql_register_view(THD *thd, TABLE_LIST *view,
|
|||||||
ulong sql_mode= thd->variables.sql_mode & MODE_ANSI_QUOTES;
|
ulong sql_mode= thd->variables.sql_mode & MODE_ANSI_QUOTES;
|
||||||
thd->variables.sql_mode&= ~MODE_ANSI_QUOTES;
|
thd->variables.sql_mode&= ~MODE_ANSI_QUOTES;
|
||||||
|
|
||||||
lex->unit.print(&view_query, QT_ORDINARY);
|
lex->unit.print(&view_query, QT_VIEW_INTERNAL);
|
||||||
lex->unit.print(&is_query, QT_IS);
|
lex->unit.print(&is_query, QT_IS);
|
||||||
|
|
||||||
thd->variables.sql_mode|= sql_mode;
|
thd->variables.sql_mode|= sql_mode;
|
||||||
@ -876,7 +876,7 @@ static int mysql_register_view(THD *thd, TABLE_LIST *view,
|
|||||||
{
|
{
|
||||||
push_warning(thd, MYSQL_ERROR::WARN_LEVEL_WARN, ER_WARN_VIEW_MERGE,
|
push_warning(thd, MYSQL_ERROR::WARN_LEVEL_WARN, ER_WARN_VIEW_MERGE,
|
||||||
ER(ER_WARN_VIEW_MERGE));
|
ER(ER_WARN_VIEW_MERGE));
|
||||||
lex->create_view_algorithm= VIEW_ALGORITHM_UNDEFINED;
|
lex->create_view_algorithm= DTYPE_ALGORITHM_UNDEFINED;
|
||||||
}
|
}
|
||||||
view->algorithm= lex->create_view_algorithm;
|
view->algorithm= lex->create_view_algorithm;
|
||||||
view->definer.user= lex->definer->user;
|
view->definer.user= lex->definer->user;
|
||||||
@ -1460,7 +1460,7 @@ bool mysql_make_view(THD *thd, File_parser *parser, TABLE_LIST *table,
|
|||||||
|
|
||||||
List_iterator_fast<TABLE_LIST> ti(view_select->top_join_list);
|
List_iterator_fast<TABLE_LIST> ti(view_select->top_join_list);
|
||||||
|
|
||||||
table->effective_algorithm= VIEW_ALGORITHM_MERGE;
|
table->derived_type= VIEW_ALGORITHM_MERGE;
|
||||||
DBUG_PRINT("info", ("algorithm: MERGE"));
|
DBUG_PRINT("info", ("algorithm: MERGE"));
|
||||||
table->updatable= (table->updatable_view != 0);
|
table->updatable= (table->updatable_view != 0);
|
||||||
table->effective_with_check=
|
table->effective_with_check=
|
||||||
@ -1474,67 +1474,10 @@ bool mysql_make_view(THD *thd, File_parser *parser, TABLE_LIST *table,
|
|||||||
/* prepare view context */
|
/* prepare view context */
|
||||||
lex->select_lex.context.resolve_in_table_list_only(view_main_select_tables);
|
lex->select_lex.context.resolve_in_table_list_only(view_main_select_tables);
|
||||||
lex->select_lex.context.outer_context= 0;
|
lex->select_lex.context.outer_context= 0;
|
||||||
lex->select_lex.context.select_lex= table->select_lex;
|
|
||||||
lex->select_lex.select_n_having_items+=
|
lex->select_lex.select_n_having_items+=
|
||||||
table->select_lex->select_n_having_items;
|
table->select_lex->select_n_having_items;
|
||||||
|
|
||||||
/*
|
|
||||||
Tables of the main select of the view should be marked as belonging
|
|
||||||
to the same select as original view (again we can use LEX::select_lex
|
|
||||||
for this purprose because we don't support MERGE algorithm for views
|
|
||||||
with unions).
|
|
||||||
*/
|
|
||||||
for (tbl= lex->select_lex.get_table_list(); tbl; tbl= tbl->next_local)
|
|
||||||
tbl->select_lex= table->select_lex;
|
|
||||||
|
|
||||||
{
|
|
||||||
if (view_main_select_tables->next_local)
|
|
||||||
{
|
|
||||||
table->multitable_view= TRUE;
|
|
||||||
if (table->belong_to_view)
|
|
||||||
table->belong_to_view->multitable_view= TRUE;
|
|
||||||
}
|
|
||||||
/* make nested join structure for view tables */
|
|
||||||
NESTED_JOIN *nested_join;
|
|
||||||
if (!(nested_join= table->nested_join=
|
|
||||||
(NESTED_JOIN *) thd->calloc(sizeof(NESTED_JOIN))))
|
|
||||||
goto err;
|
|
||||||
nested_join->join_list= view_select->top_join_list;
|
|
||||||
|
|
||||||
/* re-nest tables of VIEW */
|
|
||||||
ti.rewind();
|
|
||||||
while ((tbl= ti++))
|
|
||||||
{
|
|
||||||
tbl->join_list= &nested_join->join_list;
|
|
||||||
tbl->embedding= table;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Store WHERE clause for post-processing in setup_underlying */
|
|
||||||
table->where= view_select->where;
|
table->where= view_select->where;
|
||||||
/*
|
|
||||||
Add subqueries units to SELECT into which we merging current view.
|
|
||||||
unit(->next)* chain starts with subqueries that are used by this
|
|
||||||
view and continues with subqueries that are used by other views.
|
|
||||||
We must not add any subquery twice (otherwise we'll form a loop),
|
|
||||||
to do this we remember in end_unit the first subquery that has
|
|
||||||
been already added.
|
|
||||||
|
|
||||||
NOTE: we do not support UNION here, so we take only one select
|
|
||||||
*/
|
|
||||||
SELECT_LEX_NODE *end_unit= table->select_lex->slave;
|
|
||||||
SELECT_LEX_UNIT *next_unit;
|
|
||||||
for (SELECT_LEX_UNIT *unit= lex->select_lex.first_inner_unit();
|
|
||||||
unit;
|
|
||||||
unit= next_unit)
|
|
||||||
{
|
|
||||||
if (unit == end_unit)
|
|
||||||
break;
|
|
||||||
SELECT_LEX_NODE *save_slave= unit->slave;
|
|
||||||
next_unit= unit->next_unit();
|
|
||||||
unit->include_down(table->select_lex);
|
|
||||||
unit->slave= save_slave; // fix include_down initialisation
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
We can safely ignore the VIEW's ORDER BY if we merge into union
|
We can safely ignore the VIEW's ORDER BY if we merge into union
|
||||||
@ -1551,23 +1494,22 @@ bool mysql_make_view(THD *thd, File_parser *parser, TABLE_LIST *table,
|
|||||||
goto ok;
|
goto ok;
|
||||||
}
|
}
|
||||||
|
|
||||||
table->effective_algorithm= VIEW_ALGORITHM_TMPTABLE;
|
table->derived_type= VIEW_ALGORITHM_TMPTABLE;
|
||||||
DBUG_PRINT("info", ("algorithm: TEMPORARY TABLE"));
|
DBUG_PRINT("info", ("algorithm: TEMPORARY TABLE"));
|
||||||
view_select->linkage= DERIVED_TABLE_TYPE;
|
view_select->linkage= DERIVED_TABLE_TYPE;
|
||||||
table->updatable= 0;
|
table->updatable= 0;
|
||||||
table->effective_with_check= VIEW_CHECK_NONE;
|
table->effective_with_check= VIEW_CHECK_NONE;
|
||||||
old_lex->subqueries= TRUE;
|
old_lex->subqueries= TRUE;
|
||||||
|
|
||||||
/* SELECT tree link */
|
|
||||||
lex->unit.include_down(table->select_lex);
|
|
||||||
lex->unit.slave= view_select; // fix include_down initialisation
|
|
||||||
|
|
||||||
table->derived= &lex->unit;
|
table->derived= &lex->unit;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
goto err;
|
goto err;
|
||||||
|
|
||||||
ok:
|
ok:
|
||||||
|
/* SELECT tree link */
|
||||||
|
lex->unit.include_down(table->select_lex);
|
||||||
|
lex->unit.slave= view_select; // fix include_down initialisation
|
||||||
/* global SELECT list linking */
|
/* global SELECT list linking */
|
||||||
end= view_select; // primary SELECT_LEX is always last
|
end= view_select; // primary SELECT_LEX is always last
|
||||||
end->link_next= old_lex->all_selects_list;
|
end->link_next= old_lex->all_selects_list;
|
||||||
|
@ -1945,7 +1945,7 @@ create:
|
|||||||
| CREATE
|
| CREATE
|
||||||
{
|
{
|
||||||
Lex->create_view_mode= VIEW_CREATE_NEW;
|
Lex->create_view_mode= VIEW_CREATE_NEW;
|
||||||
Lex->create_view_algorithm= VIEW_ALGORITHM_UNDEFINED;
|
Lex->create_view_algorithm= DTYPE_ALGORITHM_UNDEFINED;
|
||||||
Lex->create_view_suid= TRUE;
|
Lex->create_view_suid= TRUE;
|
||||||
}
|
}
|
||||||
view_or_trigger_or_sp_or_event
|
view_or_trigger_or_sp_or_event
|
||||||
@ -5993,7 +5993,7 @@ alter:
|
|||||||
my_error(ER_SP_BADSTATEMENT, MYF(0), "ALTER VIEW");
|
my_error(ER_SP_BADSTATEMENT, MYF(0), "ALTER VIEW");
|
||||||
MYSQL_YYABORT;
|
MYSQL_YYABORT;
|
||||||
}
|
}
|
||||||
lex->create_view_algorithm= VIEW_ALGORITHM_UNDEFINED;
|
lex->create_view_algorithm= DTYPE_ALGORITHM_UNDEFINED;
|
||||||
lex->create_view_mode= VIEW_ALTER;
|
lex->create_view_mode= VIEW_ALTER;
|
||||||
}
|
}
|
||||||
view_tail
|
view_tail
|
||||||
@ -13740,7 +13740,7 @@ view_replace:
|
|||||||
|
|
||||||
view_algorithm:
|
view_algorithm:
|
||||||
ALGORITHM_SYM EQ UNDEFINED_SYM
|
ALGORITHM_SYM EQ UNDEFINED_SYM
|
||||||
{ Lex->create_view_algorithm= VIEW_ALGORITHM_UNDEFINED; }
|
{ Lex->create_view_algorithm= DTYPE_ALGORITHM_UNDEFINED; }
|
||||||
| ALGORITHM_SYM EQ MERGE_SYM
|
| ALGORITHM_SYM EQ MERGE_SYM
|
||||||
{ Lex->create_view_algorithm= VIEW_ALGORITHM_MERGE; }
|
{ Lex->create_view_algorithm= VIEW_ALGORITHM_MERGE; }
|
||||||
| ALGORITHM_SYM EQ TEMPTABLE_SYM
|
| ALGORITHM_SYM EQ TEMPTABLE_SYM
|
||||||
|
578
sql/table.cc
578
sql/table.cc
@ -3513,129 +3513,112 @@ void TABLE_LIST::calc_md5(char *buffer)
|
|||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@brief Set underlying table for table place holder of view.
|
@brief
|
||||||
|
Create field translation for mergeable derived table/view.
|
||||||
|
|
||||||
@details
|
@param thd Thread handle
|
||||||
|
|
||||||
Replace all views that only use one table with the table itself. This
|
@details
|
||||||
allows us to treat the view as a simple table and even update it (it is a
|
Create field translation for mergeable derived table/view.
|
||||||
kind of optimization).
|
|
||||||
|
|
||||||
@note
|
@return FALSE ok.
|
||||||
|
@return TRUE an error occur.
|
||||||
This optimization is potentially dangerous as it makes views
|
|
||||||
masquerade as base tables: Views don't have the pointer TABLE_LIST::table
|
|
||||||
set to non-@c NULL.
|
|
||||||
|
|
||||||
We may have the case where a view accesses tables not normally accessible
|
|
||||||
in the current Security_context (only in the definer's
|
|
||||||
Security_context). According to the table's GRANT_INFO (TABLE::grant),
|
|
||||||
access is fulfilled, but this is implicitly meant in the definer's security
|
|
||||||
context. Hence we must never look at only a TABLE's GRANT_INFO without
|
|
||||||
looking at the one of the referring TABLE_LIST.
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
void TABLE_LIST::set_underlying_merge()
|
bool TABLE_LIST::create_field_translation(THD *thd)
|
||||||
{
|
{
|
||||||
TABLE_LIST *tbl;
|
Item *item;
|
||||||
|
Field_translator *transl;
|
||||||
|
SELECT_LEX *select= get_single_select();
|
||||||
|
List_iterator_fast<Item> it(select->item_list);
|
||||||
|
uint field_count= 0;
|
||||||
|
Query_arena *arena= thd->stmt_arena, backup;
|
||||||
|
bool res= FALSE;
|
||||||
|
|
||||||
if ((tbl= merge_underlying_list))
|
used_items.empty();
|
||||||
|
|
||||||
|
if (field_translation)
|
||||||
{
|
{
|
||||||
/* This is a view. Process all tables of view */
|
/*
|
||||||
DBUG_ASSERT(view && effective_algorithm == VIEW_ALGORITHM_MERGE);
|
Update items in the field translation aftet view have been prepared.
|
||||||
do
|
It's needed because some items in the select list, like IN subselects,
|
||||||
|
might be substituted for optimized ones.
|
||||||
|
*/
|
||||||
|
if (is_view() && get_unit()->prepared && !field_translation_updated)
|
||||||
{
|
{
|
||||||
if (tbl->merge_underlying_list) // This is a view
|
while ((item= it++))
|
||||||
{
|
{
|
||||||
DBUG_ASSERT(tbl->view &&
|
field_translation[field_count++].item= item;
|
||||||
tbl->effective_algorithm == VIEW_ALGORITHM_MERGE);
|
|
||||||
/*
|
|
||||||
This is the only case where set_ancestor is called on an object
|
|
||||||
that may not be a view (in which case ancestor is 0)
|
|
||||||
*/
|
|
||||||
tbl->merge_underlying_list->set_underlying_merge();
|
|
||||||
}
|
}
|
||||||
} while ((tbl= tbl->next_local));
|
field_translation_updated= TRUE;
|
||||||
|
|
||||||
if (!multitable_view)
|
|
||||||
{
|
|
||||||
table= merge_underlying_list->table;
|
|
||||||
schema_table= merge_underlying_list->schema_table;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (arena->is_conventional())
|
||||||
|
arena= 0; // For easier test
|
||||||
|
else
|
||||||
|
thd->set_n_backup_active_arena(arena, &backup);
|
||||||
|
|
||||||
|
/* Create view fields translation table */
|
||||||
|
|
||||||
|
if (!(transl=
|
||||||
|
(Field_translator*)(thd->stmt_arena->
|
||||||
|
alloc(select->item_list.elements *
|
||||||
|
sizeof(Field_translator)))))
|
||||||
|
{
|
||||||
|
res= TRUE;
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
while ((item= it++))
|
||||||
|
{
|
||||||
|
transl[field_count].name= item->name;
|
||||||
|
transl[field_count++].item= item;
|
||||||
|
}
|
||||||
|
field_translation= transl;
|
||||||
|
field_translation_end= transl + field_count;
|
||||||
|
|
||||||
|
exit:
|
||||||
|
if (arena)
|
||||||
|
thd->restore_active_arena(arena, &backup);
|
||||||
|
|
||||||
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/**
|
||||||
setup fields of placeholder of merged VIEW
|
@brief
|
||||||
|
Create field translation for mergeable derived table/view.
|
||||||
|
|
||||||
SYNOPSIS
|
@param thd Thread handle
|
||||||
TABLE_LIST::setup_underlying()
|
|
||||||
thd - thread handler
|
|
||||||
|
|
||||||
DESCRIPTION
|
@details
|
||||||
It is:
|
Create field translation for mergeable derived table/view.
|
||||||
- preparing translation table for view columns
|
|
||||||
If there are underlying view(s) procedure first will be called for them.
|
|
||||||
|
|
||||||
RETURN
|
@return FALSE ok.
|
||||||
FALSE - OK
|
@return TRUE an error occur.
|
||||||
TRUE - error
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
bool TABLE_LIST::setup_underlying(THD *thd)
|
bool TABLE_LIST::setup_underlying(THD *thd)
|
||||||
{
|
{
|
||||||
DBUG_ENTER("TABLE_LIST::setup_underlying");
|
DBUG_ENTER("TABLE_LIST::setup_underlying");
|
||||||
|
|
||||||
if (!field_translation && merge_underlying_list)
|
if (!view || (!field_translation && merge_underlying_list))
|
||||||
{
|
{
|
||||||
Field_translator *transl;
|
SELECT_LEX *select= get_single_select();
|
||||||
SELECT_LEX *select= &view->select_lex;
|
|
||||||
Item *item;
|
|
||||||
TABLE_LIST *tbl;
|
|
||||||
List_iterator_fast<Item> it(select->item_list);
|
|
||||||
uint field_count= 0;
|
|
||||||
|
|
||||||
if (check_stack_overrun(thd, STACK_MIN_SIZE, (uchar*) &field_count))
|
if (create_field_translation(thd))
|
||||||
{
|
|
||||||
DBUG_RETURN(TRUE);
|
DBUG_RETURN(TRUE);
|
||||||
}
|
|
||||||
|
|
||||||
for (tbl= merge_underlying_list; tbl; tbl= tbl->next_local)
|
|
||||||
{
|
|
||||||
if (tbl->merge_underlying_list &&
|
|
||||||
tbl->setup_underlying(thd))
|
|
||||||
{
|
|
||||||
DBUG_RETURN(TRUE);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Create view fields translation table */
|
|
||||||
|
|
||||||
if (!(transl=
|
|
||||||
(Field_translator*)(thd->stmt_arena->
|
|
||||||
alloc(select->item_list.elements *
|
|
||||||
sizeof(Field_translator)))))
|
|
||||||
{
|
|
||||||
DBUG_RETURN(TRUE);
|
|
||||||
}
|
|
||||||
|
|
||||||
while ((item= it++))
|
|
||||||
{
|
|
||||||
transl[field_count].name= item->name;
|
|
||||||
transl[field_count++].item= item;
|
|
||||||
}
|
|
||||||
field_translation= transl;
|
|
||||||
field_translation_end= transl + field_count;
|
|
||||||
/* TODO: use hash for big number of fields */
|
|
||||||
|
|
||||||
/* full text function moving to current select */
|
/* full text function moving to current select */
|
||||||
if (view->select_lex.ftfunc_list->elements)
|
if (select->ftfunc_list->elements)
|
||||||
{
|
{
|
||||||
Item_func_match *ifm;
|
Item_func_match *ifm;
|
||||||
SELECT_LEX *current_select= thd->lex->current_select;
|
SELECT_LEX *current_select= thd->lex->current_select;
|
||||||
List_iterator_fast<Item_func_match>
|
List_iterator_fast<Item_func_match>
|
||||||
li(*(view->select_lex.ftfunc_list));
|
li(*(select_lex->ftfunc_list));
|
||||||
while ((ifm= li++))
|
while ((ifm= li++))
|
||||||
current_select->ftfunc_list->push_front(ifm);
|
current_select->ftfunc_list->push_front(ifm);
|
||||||
}
|
}
|
||||||
@ -3645,7 +3628,7 @@ bool TABLE_LIST::setup_underlying(THD *thd)
|
|||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Prepare where expression of view
|
Prepare where expression of derived table/view
|
||||||
|
|
||||||
SYNOPSIS
|
SYNOPSIS
|
||||||
TABLE_LIST::prep_where()
|
TABLE_LIST::prep_where()
|
||||||
@ -3669,7 +3652,8 @@ bool TABLE_LIST::prep_where(THD *thd, Item **conds,
|
|||||||
|
|
||||||
for (TABLE_LIST *tbl= merge_underlying_list; tbl; tbl= tbl->next_local)
|
for (TABLE_LIST *tbl= merge_underlying_list; tbl; tbl= tbl->next_local)
|
||||||
{
|
{
|
||||||
if (tbl->view && tbl->prep_where(thd, conds, no_where_clause))
|
if (tbl->is_view_or_derived() &&
|
||||||
|
tbl->prep_where(thd, conds, no_where_clause))
|
||||||
{
|
{
|
||||||
DBUG_RETURN(TRUE);
|
DBUG_RETURN(TRUE);
|
||||||
}
|
}
|
||||||
@ -3677,6 +3661,8 @@ bool TABLE_LIST::prep_where(THD *thd, Item **conds,
|
|||||||
|
|
||||||
if (where)
|
if (where)
|
||||||
{
|
{
|
||||||
|
if (where->fixed)
|
||||||
|
where->update_used_tables();
|
||||||
if (!where->fixed && where->fix_fields(thd, &where))
|
if (!where->fixed && where->fix_fields(thd, &where))
|
||||||
{
|
{
|
||||||
DBUG_RETURN(TRUE);
|
DBUG_RETURN(TRUE);
|
||||||
@ -3709,7 +3695,13 @@ bool TABLE_LIST::prep_where(THD *thd, Item **conds,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (tbl == 0)
|
if (tbl == 0)
|
||||||
|
{
|
||||||
|
if (*conds && !(*conds)->fixed)
|
||||||
|
(*conds)->fix_fields(thd, conds);
|
||||||
*conds= and_conds(*conds, where->copy_andor_structure(thd));
|
*conds= and_conds(*conds, where->copy_andor_structure(thd));
|
||||||
|
if (*conds && !(*conds)->fixed)
|
||||||
|
(*conds)->fix_fields(thd, conds);
|
||||||
|
}
|
||||||
if (arena)
|
if (arena)
|
||||||
thd->restore_active_arena(arena, &backup);
|
thd->restore_active_arena(arena, &backup);
|
||||||
where_processed= TRUE;
|
where_processed= TRUE;
|
||||||
@ -3748,10 +3740,11 @@ merge_on_conds(THD *thd, TABLE_LIST *table, bool is_cascaded)
|
|||||||
DBUG_PRINT("info", ("alias: %s", table->alias));
|
DBUG_PRINT("info", ("alias: %s", table->alias));
|
||||||
if (table->on_expr)
|
if (table->on_expr)
|
||||||
cond= table->on_expr->copy_andor_structure(thd);
|
cond= table->on_expr->copy_andor_structure(thd);
|
||||||
if (!table->nested_join)
|
if (!table->view)
|
||||||
DBUG_RETURN(cond);
|
DBUG_RETURN(cond);
|
||||||
List_iterator<TABLE_LIST> li(table->nested_join->join_list);
|
for (TABLE_LIST *tbl= (TABLE_LIST*)table->view->select_lex.table_list.first;
|
||||||
while (TABLE_LIST *tbl= li++)
|
tbl;
|
||||||
|
tbl= tbl->next_local)
|
||||||
{
|
{
|
||||||
if (tbl->view && !is_cascaded)
|
if (tbl->view && !is_cascaded)
|
||||||
continue;
|
continue;
|
||||||
@ -3791,7 +3784,7 @@ bool TABLE_LIST::prep_check_option(THD *thd, uint8 check_opt_type)
|
|||||||
{
|
{
|
||||||
DBUG_ENTER("TABLE_LIST::prep_check_option");
|
DBUG_ENTER("TABLE_LIST::prep_check_option");
|
||||||
bool is_cascaded= check_opt_type == VIEW_CHECK_CASCADED;
|
bool is_cascaded= check_opt_type == VIEW_CHECK_CASCADED;
|
||||||
|
TABLE_LIST *merge_underlying_list= view->select_lex.get_table_list();
|
||||||
for (TABLE_LIST *tbl= merge_underlying_list; tbl; tbl= tbl->next_local)
|
for (TABLE_LIST *tbl= merge_underlying_list; tbl; tbl= tbl->next_local)
|
||||||
{
|
{
|
||||||
/* see comment of check_opt_type parameter */
|
/* see comment of check_opt_type parameter */
|
||||||
@ -3808,7 +3801,6 @@ bool TABLE_LIST::prep_check_option(THD *thd, uint8 check_opt_type)
|
|||||||
|
|
||||||
if (where)
|
if (where)
|
||||||
{
|
{
|
||||||
DBUG_ASSERT(where->fixed);
|
|
||||||
check_option= where->copy_andor_structure(thd);
|
check_option= where->copy_andor_structure(thd);
|
||||||
}
|
}
|
||||||
if (is_cascaded)
|
if (is_cascaded)
|
||||||
@ -3904,10 +3896,14 @@ void TABLE_LIST::hide_view_error(THD *thd)
|
|||||||
TABLE_LIST *TABLE_LIST::find_underlying_table(TABLE *table_to_find)
|
TABLE_LIST *TABLE_LIST::find_underlying_table(TABLE *table_to_find)
|
||||||
{
|
{
|
||||||
/* is this real table and table which we are looking for? */
|
/* is this real table and table which we are looking for? */
|
||||||
if (table == table_to_find && merge_underlying_list == 0)
|
if (table == table_to_find && view == 0)
|
||||||
return this;
|
return this;
|
||||||
|
if (!view)
|
||||||
|
return 0;
|
||||||
|
|
||||||
for (TABLE_LIST *tbl= merge_underlying_list; tbl; tbl= tbl->next_local)
|
for (TABLE_LIST *tbl= view->select_lex.get_table_list();
|
||||||
|
tbl;
|
||||||
|
tbl= tbl->next_local)
|
||||||
{
|
{
|
||||||
TABLE_LIST *result;
|
TABLE_LIST *result;
|
||||||
if ((result= tbl->find_underlying_table(table_to_find)))
|
if ((result= tbl->find_underlying_table(table_to_find)))
|
||||||
@ -3989,7 +3985,12 @@ bool TABLE_LIST::check_single_table(TABLE_LIST **table_arg,
|
|||||||
table_map map,
|
table_map map,
|
||||||
TABLE_LIST *view_arg)
|
TABLE_LIST *view_arg)
|
||||||
{
|
{
|
||||||
for (TABLE_LIST *tbl= merge_underlying_list; tbl; tbl= tbl->next_local)
|
if (!select_lex)
|
||||||
|
return FALSE;
|
||||||
|
DBUG_ASSERT(is_merged_derived());
|
||||||
|
for (TABLE_LIST *tbl= get_single_select()->get_table_list();
|
||||||
|
tbl;
|
||||||
|
tbl= tbl->next_local)
|
||||||
{
|
{
|
||||||
if (tbl->table)
|
if (tbl->table)
|
||||||
{
|
{
|
||||||
@ -4031,8 +4032,10 @@ bool TABLE_LIST::set_insert_values(MEM_ROOT *mem_root)
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
DBUG_ASSERT(view && merge_underlying_list);
|
DBUG_ASSERT(is_view_or_derived() && is_merged_derived());
|
||||||
for (TABLE_LIST *tbl= merge_underlying_list; tbl; tbl= tbl->next_local)
|
for (TABLE_LIST *tbl= (TABLE_LIST*)view->select_lex.table_list.first;
|
||||||
|
tbl;
|
||||||
|
tbl= tbl->next_local)
|
||||||
if (tbl->set_insert_values(mem_root))
|
if (tbl->set_insert_values(mem_root))
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
@ -4058,7 +4061,7 @@ bool TABLE_LIST::set_insert_values(MEM_ROOT *mem_root)
|
|||||||
*/
|
*/
|
||||||
bool TABLE_LIST::is_leaf_for_name_resolution()
|
bool TABLE_LIST::is_leaf_for_name_resolution()
|
||||||
{
|
{
|
||||||
return (view || is_natural_join || is_join_columns_complete ||
|
return (is_merged_derived() || is_natural_join || is_join_columns_complete ||
|
||||||
!nested_join);
|
!nested_join);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -4196,7 +4199,11 @@ void TABLE_LIST::register_want_access(ulong want_access)
|
|||||||
if (table)
|
if (table)
|
||||||
table->grant.want_privilege= want_access;
|
table->grant.want_privilege= want_access;
|
||||||
}
|
}
|
||||||
for (TABLE_LIST *tbl= merge_underlying_list; tbl; tbl= tbl->next_local)
|
if (!view)
|
||||||
|
return;
|
||||||
|
for (TABLE_LIST *tbl= view->select_lex.get_table_list();
|
||||||
|
tbl;
|
||||||
|
tbl= tbl->next_local)
|
||||||
tbl->register_want_access(want_access);
|
tbl->register_want_access(want_access);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -4426,14 +4433,23 @@ const char *Natural_join_column::db_name()
|
|||||||
DBUG_ASSERT(!strcmp(table_ref->db,
|
DBUG_ASSERT(!strcmp(table_ref->db,
|
||||||
table_ref->table->s->db.str) ||
|
table_ref->table->s->db.str) ||
|
||||||
(table_ref->schema_table &&
|
(table_ref->schema_table &&
|
||||||
table_ref->table->s->db.str[0] == 0));
|
table_ref->table->s->db.str[0] == 0) ||
|
||||||
|
table_ref->is_materialized_derived());
|
||||||
return table_ref->db;
|
return table_ref->db;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
GRANT_INFO *Natural_join_column::grant()
|
GRANT_INFO *Natural_join_column::grant()
|
||||||
{
|
{
|
||||||
if (view_field)
|
/* if (view_field)
|
||||||
|
return &(table_ref->grant);
|
||||||
|
return &(table_ref->table->grant);*/
|
||||||
|
/*
|
||||||
|
Have to check algorithm because merged derived also has
|
||||||
|
field_translation.
|
||||||
|
*/
|
||||||
|
//if (table_ref->effective_algorithm == DTYPE_ALGORITHM_MERGE)
|
||||||
|
if (table_ref->is_merged_derived())
|
||||||
return &(table_ref->grant);
|
return &(table_ref->grant);
|
||||||
return &(table_ref->table->grant);
|
return &(table_ref->table->grant);
|
||||||
}
|
}
|
||||||
@ -4514,7 +4530,17 @@ Item *create_view_field(THD *thd, TABLE_LIST *view, Item **field_ref,
|
|||||||
{
|
{
|
||||||
DBUG_RETURN(field);
|
DBUG_RETURN(field);
|
||||||
}
|
}
|
||||||
Item *item= new Item_direct_view_ref(view, field_ref, name);
|
Item *item= new Item_direct_view_ref(&view->view->select_lex.context,
|
||||||
|
field_ref, view->alias,
|
||||||
|
name, view);
|
||||||
|
/*
|
||||||
|
Force creation of nullable item for the result tmp table for outer joined
|
||||||
|
views/derived tables.
|
||||||
|
*/
|
||||||
|
if (view->outer_join)
|
||||||
|
item->maybe_null= TRUE;
|
||||||
|
/* Save item in case we will need to fall back to materialization. */
|
||||||
|
view->used_items.push_back(item);
|
||||||
DBUG_RETURN(item);
|
DBUG_RETURN(item);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -4568,8 +4594,7 @@ void Field_iterator_table_ref::set_field_iterator()
|
|||||||
/* This is a merge view, so use field_translation. */
|
/* This is a merge view, so use field_translation. */
|
||||||
else if (table_ref->field_translation)
|
else if (table_ref->field_translation)
|
||||||
{
|
{
|
||||||
DBUG_ASSERT(table_ref->view &&
|
DBUG_ASSERT(table_ref->is_merged_derived());
|
||||||
table_ref->effective_algorithm == VIEW_ALGORITHM_MERGE);
|
|
||||||
field_it= &view_field_it;
|
field_it= &view_field_it;
|
||||||
DBUG_PRINT("info", ("field_it for '%s' is Field_iterator_view",
|
DBUG_PRINT("info", ("field_it for '%s' is Field_iterator_view",
|
||||||
table_ref->alias));
|
table_ref->alias));
|
||||||
@ -5193,15 +5218,16 @@ void st_table::mark_virtual_columns_for_write(bool insert_fl)
|
|||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@brief
|
||||||
Allocate space for keys
|
Allocate space for keys
|
||||||
|
|
||||||
@param key_count number of keys to allocate.
|
@param key_count number of keys to allocate
|
||||||
|
|
||||||
@details
|
@details
|
||||||
Allocates space enough to fit 'key_count' keys for this table.
|
The function allocates memory to fit 'key_count' keys for this table.
|
||||||
|
|
||||||
@return FALSE space was successfully allocated.
|
@return FALSE space was successfully allocated
|
||||||
@return TRUE an error occur.
|
@return TRUE an error occur
|
||||||
*/
|
*/
|
||||||
|
|
||||||
bool TABLE::alloc_keys(uint key_count)
|
bool TABLE::alloc_keys(uint key_count)
|
||||||
@ -5260,22 +5286,24 @@ void TABLE::create_key_part_by_field(KEY *keyinfo,
|
|||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Add a key to a temporary table
|
@brief
|
||||||
|
Add one key to a temporary table
|
||||||
|
|
||||||
@param key the number of the key
|
@param key the number of the key
|
||||||
@param key_parts number of components of the key
|
@param key_parts number of components of the key
|
||||||
@param next_field_no the call-back function that returns the number of
|
@param next_field_no the call-back function that returns the number of
|
||||||
the field used as the next component of the key
|
the field used as the next component of the key
|
||||||
@param arg the argument for the above function
|
@param arg the argument for the above function
|
||||||
@param unique Is it unique index
|
@param unique TRUE <=> it is a unique index
|
||||||
|
|
||||||
@details
|
@details
|
||||||
The function adds a new key to the table that is assumed to be
|
The function adds a new key to the table that is assumed to be a temporary
|
||||||
temprary table. The call-back function must at each call must return
|
table. At each its invocation the call-back function must return
|
||||||
the number of the field that used as next component of this key
|
the number of the field that is used as the next component of this key.
|
||||||
|
|
||||||
@return FALSE is a success
|
@return FALSE is a success
|
||||||
@return TRUE if a failure
|
@return TRUE if a failure
|
||||||
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
bool TABLE::add_tmp_key(uint key, uint key_parts,
|
bool TABLE::add_tmp_key(uint key, uint key_parts,
|
||||||
@ -5326,6 +5354,31 @@ bool TABLE::add_tmp_key(uint key, uint key_parts,
|
|||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
@brief
|
||||||
|
Drop all indexes except specified one.
|
||||||
|
|
||||||
|
@param key_to_save the key to save
|
||||||
|
|
||||||
|
@details
|
||||||
|
Drop all indexes on this table except 'key_to_save'. The saved key becomes
|
||||||
|
key #0. Memory occupied by key parts of dropped keys are freed.
|
||||||
|
If the 'key_to_save' is negative then all keys are freed.
|
||||||
|
*/
|
||||||
|
|
||||||
|
void TABLE::use_index(int key_to_save)
|
||||||
|
{
|
||||||
|
uint i= 1;
|
||||||
|
DBUG_ASSERT(!created && key_to_save < (int)s->keys);
|
||||||
|
if (key_to_save >= 0)
|
||||||
|
/* Save the given key. */
|
||||||
|
memcpy(key_info, key_info + key_to_save, sizeof(KEY));
|
||||||
|
else
|
||||||
|
/* Drop all keys; */
|
||||||
|
i= 0;
|
||||||
|
|
||||||
|
s->keys= (key_to_save < 0) ? 0 : 1;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@brief Check if this is part of a MERGE table with attached children.
|
@brief Check if this is part of a MERGE table with attached children.
|
||||||
@ -5388,6 +5441,7 @@ void TABLE_LIST::reinit_before_use(THD *thd)
|
|||||||
parent_embedding->nested_join->join_list.head() == embedded);
|
parent_embedding->nested_join->join_list.head() == embedded);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Return subselect that contains the FROM list this table is taken from
|
Return subselect that contains the FROM list this table is taken from
|
||||||
|
|
||||||
@ -5659,6 +5713,296 @@ int update_virtual_fields(THD *thd, TABLE *table, bool for_write)
|
|||||||
DBUG_RETURN(0);
|
DBUG_RETURN(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
@brief Reset const_table flag
|
||||||
|
|
||||||
|
@detail
|
||||||
|
Reset const_table flag for this table. If this table is a merged derived
|
||||||
|
table/view the flag is recursively reseted for all tables of the underlying
|
||||||
|
select.
|
||||||
|
*/
|
||||||
|
|
||||||
|
void TABLE_LIST::reset_const_table()
|
||||||
|
{
|
||||||
|
table->const_table= 0;
|
||||||
|
if (is_merged_derived())
|
||||||
|
{
|
||||||
|
SELECT_LEX *select_lex= get_unit()->first_select();
|
||||||
|
TABLE_LIST *tl;
|
||||||
|
List_iterator<TABLE_LIST> ti(select_lex->leaf_tables);
|
||||||
|
while ((tl= ti++))
|
||||||
|
tl->reset_const_table();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
@brief Run derived tables/view handling phases on underlying select_lex.
|
||||||
|
|
||||||
|
@param lex LEX for this thread
|
||||||
|
@param phases derived tables/views handling phases to run
|
||||||
|
(set of DT_XXX constants)
|
||||||
|
@details
|
||||||
|
This function runs this derived table through specified 'phases'.
|
||||||
|
Underlying tables of this select are handled prior to this derived.
|
||||||
|
'lex' is passed as an argument to called functions.
|
||||||
|
|
||||||
|
@return TRUE on error
|
||||||
|
@return FALSE ok
|
||||||
|
*/
|
||||||
|
|
||||||
|
bool TABLE_LIST::handle_derived(struct st_lex *lex, uint phases)
|
||||||
|
{
|
||||||
|
SELECT_LEX_UNIT *unit= get_unit();
|
||||||
|
if (unit)
|
||||||
|
{
|
||||||
|
for (SELECT_LEX *sl= unit->first_select(); sl; sl= sl->next_select())
|
||||||
|
if (sl->handle_derived(lex, phases))
|
||||||
|
return TRUE;
|
||||||
|
return mysql_handle_single_derived(lex, this, phases);
|
||||||
|
}
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
@brief
|
||||||
|
Return unit of this derived table/view
|
||||||
|
|
||||||
|
@return reference to a unit if it's a derived table/view.
|
||||||
|
@return 0 when it's not a derived table/view.
|
||||||
|
*/
|
||||||
|
|
||||||
|
st_select_lex_unit *TABLE_LIST::get_unit()
|
||||||
|
{
|
||||||
|
return (view ? &view->unit : derived);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
@brief
|
||||||
|
Return select_lex of this derived table/view
|
||||||
|
|
||||||
|
@return select_lex of this derived table/view.
|
||||||
|
@return 0 when it's not a derived table.
|
||||||
|
*/
|
||||||
|
|
||||||
|
st_select_lex *TABLE_LIST::get_single_select()
|
||||||
|
{
|
||||||
|
SELECT_LEX_UNIT *unit= get_unit();
|
||||||
|
return (unit ? unit->first_select() : 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
@brief
|
||||||
|
Attach a join table list as a nested join to this TABLE_LIST.
|
||||||
|
|
||||||
|
@param join_list join table list to attach
|
||||||
|
|
||||||
|
@details
|
||||||
|
This function wraps 'join_list' into a nested_join of this table, thus
|
||||||
|
turning it to a nested join leaf.
|
||||||
|
*/
|
||||||
|
|
||||||
|
void TABLE_LIST::wrap_into_nested_join(List<TABLE_LIST> &join_list)
|
||||||
|
{
|
||||||
|
TABLE_LIST *tl;
|
||||||
|
/*
|
||||||
|
Walk through derived table top list and set 'embedding' to point to
|
||||||
|
the nesting table.
|
||||||
|
*/
|
||||||
|
nested_join->join_list.empty();
|
||||||
|
List_iterator_fast<TABLE_LIST> li(join_list);
|
||||||
|
nested_join->join_list= join_list;
|
||||||
|
while ((tl= li++))
|
||||||
|
{
|
||||||
|
tl->embedding= this;
|
||||||
|
tl->join_list= &nested_join->join_list;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
@brief
|
||||||
|
Initialize this derived table/view
|
||||||
|
|
||||||
|
@param thd Thread handle
|
||||||
|
|
||||||
|
@details
|
||||||
|
This function makes initial preparations of this derived table/view for
|
||||||
|
further processing:
|
||||||
|
if it's a derived table this function marks it either as mergeable or
|
||||||
|
materializable
|
||||||
|
creates temporary table for name resolution purposes
|
||||||
|
creates field translation for mergeable derived table/view
|
||||||
|
|
||||||
|
@return TRUE an error occur
|
||||||
|
@return FALSE ok
|
||||||
|
*/
|
||||||
|
|
||||||
|
bool TABLE_LIST::init_derived(THD *thd, bool init_view)
|
||||||
|
{
|
||||||
|
SELECT_LEX *first_select= get_single_select();
|
||||||
|
SELECT_LEX_UNIT *unit= get_unit();
|
||||||
|
|
||||||
|
if (!unit)
|
||||||
|
return FALSE;
|
||||||
|
/*
|
||||||
|
Check whether we can merge this derived table into main select.
|
||||||
|
Depending on the result field translation will or will not
|
||||||
|
be created.
|
||||||
|
*/
|
||||||
|
TABLE_LIST *first_table= (TABLE_LIST *) first_select->table_list.first;
|
||||||
|
if (first_select->table_list.elements > 1 ||
|
||||||
|
(first_table && first_table->is_multitable()))
|
||||||
|
set_multitable();
|
||||||
|
|
||||||
|
unit->derived= this;
|
||||||
|
if (init_view && !view)
|
||||||
|
{
|
||||||
|
/* This is all what we can do for a derived table for now. */
|
||||||
|
set_derived();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!is_view())
|
||||||
|
{
|
||||||
|
/* A subquery might be forced to be materialized due to a side-effect. */
|
||||||
|
if (!is_materialized_derived() && first_select->is_mergeable() &&
|
||||||
|
!(thd->lex->sql_command == SQLCOM_UPDATE_MULTI ||
|
||||||
|
thd->lex->sql_command == SQLCOM_UPDATE))
|
||||||
|
set_merged_derived();
|
||||||
|
else
|
||||||
|
set_materialized_derived();
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
Derived tables/view are materialized prior to UPDATE, thus we can skip
|
||||||
|
them from table uniqueness check
|
||||||
|
*/
|
||||||
|
if (is_materialized_derived())
|
||||||
|
{
|
||||||
|
unit->master_unit()->set_unique_exclude();
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
Create field translation for mergeable derived tables/views.
|
||||||
|
For derived tables field translation can be created only after
|
||||||
|
unit is prepared so all '*' are get unrolled.
|
||||||
|
*/
|
||||||
|
if (is_merged_derived())
|
||||||
|
{
|
||||||
|
if (is_view() || unit->prepared)
|
||||||
|
create_field_translation(thd);
|
||||||
|
}
|
||||||
|
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
@brief
|
||||||
|
Retrieve number of rows in the table
|
||||||
|
|
||||||
|
@details
|
||||||
|
Retrieve number of rows in the table referred by this TABLE_LIST and
|
||||||
|
store it in the table's stats.records variable. If this TABLE_LIST refers
|
||||||
|
to a materialized derived table/view then the estimated number of rows of
|
||||||
|
the derived table/view is used instead.
|
||||||
|
|
||||||
|
@return 0 ok
|
||||||
|
@return non zero error
|
||||||
|
*/
|
||||||
|
|
||||||
|
int TABLE_LIST::fetch_number_of_rows()
|
||||||
|
{
|
||||||
|
int error= 0;
|
||||||
|
if (is_materialized_derived() && !fill_me)
|
||||||
|
|
||||||
|
{
|
||||||
|
table->file->stats.records= ((select_union*)derived->result)->records;
|
||||||
|
set_if_bigger(table->file->stats.records, 2);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
error= table->file->info(HA_STATUS_VARIABLE | HA_STATUS_NO_LOCK);
|
||||||
|
return error;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
Procedure of keys generation for result tables of materialized derived
|
||||||
|
tables/views.
|
||||||
|
|
||||||
|
A key is generated for each equi-join pair derived table-another table.
|
||||||
|
Each generated key consists of fields of derived table used in equi-join.
|
||||||
|
Example:
|
||||||
|
|
||||||
|
SELECT * FROM (SELECT * FROM t1 GROUP BY 1) tt JOIN
|
||||||
|
t1 ON tt.f1=t1.f3 and tt.f2.=t1.f4;
|
||||||
|
In this case for the derived table tt one key will be generated. It will
|
||||||
|
consist of two parts f1 and f2.
|
||||||
|
Example:
|
||||||
|
|
||||||
|
SELECT * FROM (SELECT * FROM t1 GROUP BY 1) tt JOIN
|
||||||
|
t1 ON tt.f1=t1.f3 JOIN
|
||||||
|
t2 ON tt.f2=t2.f4;
|
||||||
|
In this case for the derived table tt two keys will be generated.
|
||||||
|
One key over f1 field, and another key over f2 field.
|
||||||
|
Currently optimizer may choose to use only one such key, thus the second
|
||||||
|
one will be dropped after range optimizer is finished.
|
||||||
|
See also JOIN::drop_unused_derived_keys function.
|
||||||
|
Example:
|
||||||
|
|
||||||
|
SELECT * FROM (SELECT * FROM t1 GROUP BY 1) tt JOIN
|
||||||
|
t1 ON tt.f1=a_function(t1.f3);
|
||||||
|
In this case for the derived table tt one key will be generated. It will
|
||||||
|
consist of one field - f1.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
@brief
|
||||||
|
Change references to underlying items of a merged derived table/view
|
||||||
|
for fields in derived table's result table.
|
||||||
|
|
||||||
|
@return FALSE ok
|
||||||
|
@return TRUE Out of memory
|
||||||
|
*/
|
||||||
|
bool TABLE_LIST::change_refs_to_fields()
|
||||||
|
{
|
||||||
|
List_iterator<Item> li(used_items);
|
||||||
|
Item_direct_ref *ref;
|
||||||
|
Field_iterator_view field_it;
|
||||||
|
THD *thd= table->in_use;
|
||||||
|
DBUG_ASSERT(is_merged_derived());
|
||||||
|
|
||||||
|
if (!used_items.elements)
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
materialized_items= (Item**)thd->calloc(sizeof(void*) * table->s->fields);
|
||||||
|
|
||||||
|
while ((ref= (Item_direct_ref*)li++))
|
||||||
|
{
|
||||||
|
uint idx;
|
||||||
|
Item *orig_item= *ref->ref;
|
||||||
|
field_it.set(this);
|
||||||
|
for (idx= 0; !field_it.end_of_fields(); field_it.next(), idx++)
|
||||||
|
{
|
||||||
|
if (field_it.item() == orig_item)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
DBUG_ASSERT(!field_it.end_of_fields());
|
||||||
|
if (!materialized_items[idx])
|
||||||
|
{
|
||||||
|
materialized_items[idx]= new Item_field(table->field[idx]);
|
||||||
|
if (!materialized_items[idx])
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
ref->ref= materialized_items + idx;
|
||||||
|
}
|
||||||
|
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/*****************************************************************************
|
/*****************************************************************************
|
||||||
** Instansiate templates
|
** Instansiate templates
|
||||||
*****************************************************************************/
|
*****************************************************************************/
|
||||||
|
156
sql/table.h
156
sql/table.h
@ -791,7 +791,6 @@ struct st_table {
|
|||||||
uint temp_pool_slot; /* Used by intern temp tables */
|
uint temp_pool_slot; /* Used by intern temp tables */
|
||||||
uint status; /* What's in record[0] */
|
uint status; /* What's in record[0] */
|
||||||
uint db_stat; /* mode of file as in handler.h */
|
uint db_stat; /* mode of file as in handler.h */
|
||||||
uint max_keys; /* Size of allocated key_info array. */
|
|
||||||
/* number of select if it is derived table */
|
/* number of select if it is derived table */
|
||||||
uint derived_select_number;
|
uint derived_select_number;
|
||||||
int current_lock; /* Type of lock on table */
|
int current_lock; /* Type of lock on table */
|
||||||
@ -867,8 +866,10 @@ struct st_table {
|
|||||||
*/
|
*/
|
||||||
bool auto_increment_field_not_null;
|
bool auto_increment_field_not_null;
|
||||||
bool insert_or_update; /* Can be used by the handler */
|
bool insert_or_update; /* Can be used by the handler */
|
||||||
bool alias_name_used; /* true if table_name is alias */
|
bool alias_name_used; /* true if table_name is alias */
|
||||||
bool get_fields_in_item_tree; /* Signal to fix_field */
|
bool get_fields_in_item_tree; /* Signal to fix_field */
|
||||||
|
bool created; /* For tmp tables. TRUE <=> tmp table was actually created.*/
|
||||||
|
|
||||||
/* If MERGE children attached to parent. See top comment in ha_myisammrg.cc */
|
/* If MERGE children attached to parent. See top comment in ha_myisammrg.cc */
|
||||||
bool children_attached;
|
bool children_attached;
|
||||||
|
|
||||||
@ -889,6 +890,7 @@ struct st_table {
|
|||||||
bool no_partitions_used; /* If true, all partitions have been pruned away */
|
bool no_partitions_used; /* If true, all partitions have been pruned away */
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
uint max_keys; /* Size of allocated key_info array. */
|
||||||
bool fill_item_list(List<Item> *item_list) const;
|
bool fill_item_list(List<Item> *item_list) const;
|
||||||
void reset_item_list(List<Item> *item_list) const;
|
void reset_item_list(List<Item> *item_list) const;
|
||||||
void clear_column_bitmaps(void);
|
void clear_column_bitmaps(void);
|
||||||
@ -958,6 +960,12 @@ struct st_table {
|
|||||||
bool unique);
|
bool unique);
|
||||||
void create_key_part_by_field(KEY *keyinfo, KEY_PART_INFO *key_part_info,
|
void create_key_part_by_field(KEY *keyinfo, KEY_PART_INFO *key_part_info,
|
||||||
Field *field);
|
Field *field);
|
||||||
|
void use_index(int key_to_save);
|
||||||
|
void set_table_map(table_map map_arg, uint tablenr_arg)
|
||||||
|
{
|
||||||
|
map= map_arg;
|
||||||
|
tablenr= tablenr_arg;
|
||||||
|
}
|
||||||
bool is_children_attached(void);
|
bool is_children_attached(void);
|
||||||
inline void enable_keyread()
|
inline void enable_keyread()
|
||||||
{
|
{
|
||||||
@ -1115,13 +1123,52 @@ typedef struct st_schema_table
|
|||||||
} ST_SCHEMA_TABLE;
|
} ST_SCHEMA_TABLE;
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
Types of derived tables. The ending part is a bitmap of phases that are
|
||||||
|
applicable to a derived table of the type.
|
||||||
|
* /
|
||||||
|
#define VIEW_ALGORITHM_UNDEFINED 0
|
||||||
|
#define VIEW_ALGORITHM_MERGE 1 + DT_COMMON + DT_MERGE
|
||||||
|
#define DERIVED_ALGORITHM_MERGE 2 + DT_COMMON + DT_MERGE
|
||||||
|
#define VIEW_ALGORITHM_TMPTABLE 3 + DT_COMMON + DT_MATERIALIZE
|
||||||
|
#define DERIVED_ALGORITHM_MATERIALIZE 4 + DT_COMMON + DT_MATERIALIZE
|
||||||
|
*/
|
||||||
|
#define DTYPE_ALGORITHM_UNDEFINED 0
|
||||||
|
#define DTYPE_VIEW 1
|
||||||
|
#define DTYPE_TABLE 2
|
||||||
|
#define DTYPE_MERGE 4
|
||||||
|
#define DTYPE_MATERIALIZE 8
|
||||||
|
#define DTYPE_MULTITABLE 16
|
||||||
|
#define DTYPE_MASK 19
|
||||||
|
|
||||||
|
/*
|
||||||
|
Phases of derived tables/views handling, see sql_derived.cc
|
||||||
|
Values are used as parts of a bitmap attached to derived table types.
|
||||||
|
*/
|
||||||
|
#define DT_INIT 1
|
||||||
|
#define DT_PREPARE 2
|
||||||
|
#define DT_OPTIMIZE 4
|
||||||
|
#define DT_MERGE 8
|
||||||
|
#define DT_MERGE_FOR_INSERT 16
|
||||||
|
#define DT_CREATE 32
|
||||||
|
#define DT_FILL 64
|
||||||
|
#define DT_REINIT 128
|
||||||
|
#define DT_PHASES 8
|
||||||
|
/* Phases that are applicable to all derived tables. */
|
||||||
|
#define DT_COMMON (DT_INIT + DT_PREPARE + DT_REINIT + DT_OPTIMIZE)
|
||||||
|
/* Phases that are applicable only to materialized derived tables. */
|
||||||
|
#define DT_MATERIALIZE (DT_CREATE + DT_FILL)
|
||||||
|
|
||||||
|
#define DT_PHASES_MERGE (DT_COMMON | DT_MERGE | DT_MERGE_FOR_INSERT)
|
||||||
|
#define DT_PHASES_MATERIALIZE (DT_COMMON | DT_MATERIALIZE)
|
||||||
|
|
||||||
|
#define VIEW_ALGORITHM_UNDEFINED 0
|
||||||
|
#define VIEW_ALGORITHM_MERGE (DTYPE_VIEW | DTYPE_MERGE)
|
||||||
|
#define VIEW_ALGORITHM_TMPTABLE (DTYPE_VIEW + DTYPE_MATERIALIZE )
|
||||||
|
|
||||||
#define JOIN_TYPE_LEFT 1
|
#define JOIN_TYPE_LEFT 1
|
||||||
#define JOIN_TYPE_RIGHT 2
|
#define JOIN_TYPE_RIGHT 2
|
||||||
|
|
||||||
#define VIEW_ALGORITHM_UNDEFINED 0
|
|
||||||
#define VIEW_ALGORITHM_TMPTABLE 1
|
|
||||||
#define VIEW_ALGORITHM_MERGE 2
|
|
||||||
|
|
||||||
#define VIEW_SUID_INVOKER 0
|
#define VIEW_SUID_INVOKER 0
|
||||||
#define VIEW_SUID_DEFINER 1
|
#define VIEW_SUID_DEFINER 1
|
||||||
#define VIEW_SUID_DEFAULT 2
|
#define VIEW_SUID_DEFAULT 2
|
||||||
@ -1211,6 +1258,7 @@ class Item_in_subselect;
|
|||||||
also (TABLE_LIST::field_translation != NULL)
|
also (TABLE_LIST::field_translation != NULL)
|
||||||
- tmptable (TABLE_LIST::effective_algorithm == VIEW_ALGORITHM_TMPTABLE)
|
- tmptable (TABLE_LIST::effective_algorithm == VIEW_ALGORITHM_TMPTABLE)
|
||||||
also (TABLE_LIST::field_translation == NULL)
|
also (TABLE_LIST::field_translation == NULL)
|
||||||
|
2.5) TODO: Add derived tables description here
|
||||||
3) nested table reference (TABLE_LIST::nested_join != NULL)
|
3) nested table reference (TABLE_LIST::nested_join != NULL)
|
||||||
- table sequence - e.g. (t1, t2, t3)
|
- table sequence - e.g. (t1, t2, t3)
|
||||||
TODO: how to distinguish from a JOIN?
|
TODO: how to distinguish from a JOIN?
|
||||||
@ -1225,6 +1273,7 @@ class Item_in_subselect;
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
class Index_hint;
|
class Index_hint;
|
||||||
|
struct st_lex;
|
||||||
struct TABLE_LIST
|
struct TABLE_LIST
|
||||||
{
|
{
|
||||||
TABLE_LIST() {} /* Remove gcc warning */
|
TABLE_LIST() {} /* Remove gcc warning */
|
||||||
@ -1325,6 +1374,8 @@ struct TABLE_LIST
|
|||||||
filling procedure
|
filling procedure
|
||||||
*/
|
*/
|
||||||
select_union *derived_result;
|
select_union *derived_result;
|
||||||
|
/* Stub used for materialized derived tables. */
|
||||||
|
table_map map; /* ID bit of table (1,2,4,8,16...) */
|
||||||
/*
|
/*
|
||||||
Reference from aux_tables to local list entry of main select of
|
Reference from aux_tables to local list entry of main select of
|
||||||
multi-delete statement:
|
multi-delete statement:
|
||||||
@ -1369,6 +1420,7 @@ struct TABLE_LIST
|
|||||||
Field_translator *field_translation; /* array of VIEW fields */
|
Field_translator *field_translation; /* array of VIEW fields */
|
||||||
/* pointer to element after last one in translation table above */
|
/* pointer to element after last one in translation table above */
|
||||||
Field_translator *field_translation_end;
|
Field_translator *field_translation_end;
|
||||||
|
bool field_translation_updated;
|
||||||
/*
|
/*
|
||||||
List (based on next_local) of underlying tables of this view. I.e. it
|
List (based on next_local) of underlying tables of this view. I.e. it
|
||||||
does not include the tables of subqueries used in the view. Is set only
|
does not include the tables of subqueries used in the view. Is set only
|
||||||
@ -1383,11 +1435,18 @@ struct TABLE_LIST
|
|||||||
List<TABLE_LIST> *view_tables;
|
List<TABLE_LIST> *view_tables;
|
||||||
/* most upper view this table belongs to */
|
/* most upper view this table belongs to */
|
||||||
TABLE_LIST *belong_to_view;
|
TABLE_LIST *belong_to_view;
|
||||||
|
/* A derived table this table belongs to */
|
||||||
|
TABLE_LIST *belong_to_derived;
|
||||||
/*
|
/*
|
||||||
The view directly referencing this table
|
The view directly referencing this table
|
||||||
(non-zero only for merged underlying tables of a view).
|
(non-zero only for merged underlying tables of a view).
|
||||||
*/
|
*/
|
||||||
TABLE_LIST *referencing_view;
|
TABLE_LIST *referencing_view;
|
||||||
|
|
||||||
|
table_map view_used_tables;
|
||||||
|
table_map map_exec;
|
||||||
|
uint tablenr_exec;
|
||||||
|
|
||||||
/* Ptr to parent MERGE table list item. See top comment in ha_myisammrg.cc */
|
/* Ptr to parent MERGE table list item. See top comment in ha_myisammrg.cc */
|
||||||
TABLE_LIST *parent_l;
|
TABLE_LIST *parent_l;
|
||||||
/*
|
/*
|
||||||
@ -1400,13 +1459,7 @@ struct TABLE_LIST
|
|||||||
SQL SECURITY DEFINER)
|
SQL SECURITY DEFINER)
|
||||||
*/
|
*/
|
||||||
Security_context *view_sctx;
|
Security_context *view_sctx;
|
||||||
/*
|
|
||||||
List of all base tables local to a subquery including all view
|
|
||||||
tables. Unlike 'next_local', this in this list views are *not*
|
|
||||||
leaves. Created in setup_tables() -> make_leaves_list().
|
|
||||||
*/
|
|
||||||
bool allowed_show;
|
bool allowed_show;
|
||||||
TABLE_LIST *next_leaf;
|
|
||||||
Item *where; /* VIEW WHERE clause condition */
|
Item *where; /* VIEW WHERE clause condition */
|
||||||
Item *check_option; /* WITH CHECK OPTION condition */
|
Item *check_option; /* WITH CHECK OPTION condition */
|
||||||
LEX_STRING select_stmt; /* text of (CREATE/SELECT) statement */
|
LEX_STRING select_stmt; /* text of (CREATE/SELECT) statement */
|
||||||
@ -1442,7 +1495,7 @@ struct TABLE_LIST
|
|||||||
- VIEW_ALGORITHM_MERGE
|
- VIEW_ALGORITHM_MERGE
|
||||||
@to do Replace with an enum
|
@to do Replace with an enum
|
||||||
*/
|
*/
|
||||||
uint8 effective_algorithm;
|
uint8 derived_type;
|
||||||
GRANT_INFO grant;
|
GRANT_INFO grant;
|
||||||
/* data need by some engines in query cache*/
|
/* data need by some engines in query cache*/
|
||||||
ulonglong engine_data;
|
ulonglong engine_data;
|
||||||
@ -1469,7 +1522,6 @@ struct TABLE_LIST
|
|||||||
bool skip_temporary; /* this table shouldn't be temporary */
|
bool skip_temporary; /* this table shouldn't be temporary */
|
||||||
/* TRUE if this merged view contain auto_increment field */
|
/* TRUE if this merged view contain auto_increment field */
|
||||||
bool contain_auto_increment;
|
bool contain_auto_increment;
|
||||||
bool multitable_view; /* TRUE iff this is multitable view */
|
|
||||||
bool compact_view_format; /* Use compact format for SHOW CREATE VIEW */
|
bool compact_view_format; /* Use compact format for SHOW CREATE VIEW */
|
||||||
/* view where processed */
|
/* view where processed */
|
||||||
bool where_processed;
|
bool where_processed;
|
||||||
@ -1493,6 +1545,17 @@ struct TABLE_LIST
|
|||||||
bool internal_tmp_table;
|
bool internal_tmp_table;
|
||||||
bool deleting; /* going to delete this table */
|
bool deleting; /* going to delete this table */
|
||||||
|
|
||||||
|
/* TRUE <=> derived table should be filled right after optimization. */
|
||||||
|
bool fill_me;
|
||||||
|
/* TRUE <=> view/DT is merged. */
|
||||||
|
bool merged;
|
||||||
|
bool merged_for_insert;
|
||||||
|
/* TRUE <=> don't prepare this derived table/view as it should be merged.*/
|
||||||
|
bool skip_prepare_derived;
|
||||||
|
|
||||||
|
List<Item> used_items;
|
||||||
|
Item **materialized_items;
|
||||||
|
|
||||||
/* View creation context. */
|
/* View creation context. */
|
||||||
|
|
||||||
View_creation_ctx *view_creation_ctx;
|
View_creation_ctx *view_creation_ctx;
|
||||||
@ -1530,9 +1593,10 @@ struct TABLE_LIST
|
|||||||
bool has_table_lookup_value;
|
bool has_table_lookup_value;
|
||||||
uint table_open_method;
|
uint table_open_method;
|
||||||
enum enum_schema_table_state schema_table_state;
|
enum enum_schema_table_state schema_table_state;
|
||||||
|
|
||||||
void calc_md5(char *buffer);
|
void calc_md5(char *buffer);
|
||||||
void set_underlying_merge();
|
|
||||||
int view_check_option(THD *thd, bool ignore_failure);
|
int view_check_option(THD *thd, bool ignore_failure);
|
||||||
|
bool create_field_translation(THD *thd);
|
||||||
bool setup_underlying(THD *thd);
|
bool setup_underlying(THD *thd);
|
||||||
void cleanup_items();
|
void cleanup_items();
|
||||||
bool placeholder()
|
bool placeholder()
|
||||||
@ -1562,7 +1626,7 @@ struct TABLE_LIST
|
|||||||
inline bool prepare_where(THD *thd, Item **conds,
|
inline bool prepare_where(THD *thd, Item **conds,
|
||||||
bool no_where_clause)
|
bool no_where_clause)
|
||||||
{
|
{
|
||||||
if (effective_algorithm == VIEW_ALGORITHM_MERGE)
|
if (!view || is_merged_derived())
|
||||||
return prep_where(thd, conds, no_where_clause);
|
return prep_where(thd, conds, no_where_clause);
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
@ -1628,6 +1692,60 @@ struct TABLE_LIST
|
|||||||
m_table_ref_version= s->get_table_ref_version();
|
m_table_ref_version= s->get_table_ref_version();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Set of functions returning/setting state of a derived table/view. */
|
||||||
|
inline bool is_non_derived()
|
||||||
|
{
|
||||||
|
return (!derived_type);
|
||||||
|
}
|
||||||
|
inline bool is_view_or_derived()
|
||||||
|
{
|
||||||
|
return (derived_type);
|
||||||
|
}
|
||||||
|
inline bool is_view()
|
||||||
|
{
|
||||||
|
return (derived_type & DTYPE_VIEW);
|
||||||
|
}
|
||||||
|
inline bool is_derived()
|
||||||
|
{
|
||||||
|
return (derived_type & DTYPE_TABLE);
|
||||||
|
}
|
||||||
|
inline void set_view()
|
||||||
|
{
|
||||||
|
derived_type= DTYPE_VIEW;
|
||||||
|
}
|
||||||
|
inline void set_derived()
|
||||||
|
{
|
||||||
|
derived_type= DTYPE_TABLE;
|
||||||
|
}
|
||||||
|
inline bool is_merged_derived()
|
||||||
|
{
|
||||||
|
return (derived_type & DTYPE_MERGE);
|
||||||
|
}
|
||||||
|
inline void set_merged_derived()
|
||||||
|
{
|
||||||
|
derived_type= ((derived_type & DTYPE_MASK) |
|
||||||
|
DTYPE_TABLE | DTYPE_MERGE);
|
||||||
|
}
|
||||||
|
inline bool is_materialized_derived()
|
||||||
|
{
|
||||||
|
return (derived_type & DTYPE_MATERIALIZE);
|
||||||
|
}
|
||||||
|
inline void set_materialized_derived()
|
||||||
|
{
|
||||||
|
derived_type= ((derived_type & DTYPE_MASK) |
|
||||||
|
DTYPE_TABLE | DTYPE_MATERIALIZE);
|
||||||
|
}
|
||||||
|
inline bool is_multitable()
|
||||||
|
{
|
||||||
|
return (derived_type & DTYPE_MULTITABLE);
|
||||||
|
}
|
||||||
|
inline void set_multitable()
|
||||||
|
{
|
||||||
|
derived_type|= DTYPE_MULTITABLE;
|
||||||
|
}
|
||||||
|
void reset_const_table();
|
||||||
|
bool handle_derived(struct st_lex *lex, uint phases);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@brief True if this TABLE_LIST represents an anonymous derived table,
|
@brief True if this TABLE_LIST represents an anonymous derived table,
|
||||||
i.e. the result of a subquery.
|
i.e. the result of a subquery.
|
||||||
@ -1647,6 +1765,12 @@ struct TABLE_LIST
|
|||||||
respectively.
|
respectively.
|
||||||
*/
|
*/
|
||||||
char *get_table_name() { return view != NULL ? view_name.str : table_name; }
|
char *get_table_name() { return view != NULL ? view_name.str : table_name; }
|
||||||
|
st_select_lex_unit *get_unit();
|
||||||
|
st_select_lex *get_single_select();
|
||||||
|
void wrap_into_nested_join(List<TABLE_LIST> &join_list);
|
||||||
|
bool init_derived(THD *thd, bool init_view);
|
||||||
|
int fetch_number_of_rows();
|
||||||
|
bool change_refs_to_fields();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
bool prep_check_option(THD *thd, uint8 check_opt_type);
|
bool prep_check_option(THD *thd, uint8 check_opt_type);
|
||||||
|
@ -383,6 +383,10 @@ void ha_heap::position(const uchar *record)
|
|||||||
int ha_heap::info(uint flag)
|
int ha_heap::info(uint flag)
|
||||||
{
|
{
|
||||||
HEAPINFO hp_info;
|
HEAPINFO hp_info;
|
||||||
|
|
||||||
|
if (!table)
|
||||||
|
return 1;
|
||||||
|
|
||||||
(void) heap_info(file,&hp_info,flag);
|
(void) heap_info(file,&hp_info,flag);
|
||||||
|
|
||||||
errkey= hp_info.errkey;
|
errkey= hp_info.errkey;
|
||||||
|
@ -2357,7 +2357,7 @@ void ha_maria::position(const uchar *record)
|
|||||||
|
|
||||||
int ha_maria::info(uint flag)
|
int ha_maria::info(uint flag)
|
||||||
{
|
{
|
||||||
return info(flag, table->s->tmp_table == NO_TMP_TABLE);
|
return (!table ? 1 : info(flag, table->s->tmp_table == NO_TMP_TABLE));
|
||||||
}
|
}
|
||||||
|
|
||||||
int ha_maria::info(uint flag, my_bool lock_table_share)
|
int ha_maria::info(uint flag, my_bool lock_table_share)
|
||||||
|
@ -1867,6 +1867,9 @@ int ha_myisam::info(uint flag)
|
|||||||
MI_ISAMINFO misam_info;
|
MI_ISAMINFO misam_info;
|
||||||
char name_buff[FN_REFLEN];
|
char name_buff[FN_REFLEN];
|
||||||
|
|
||||||
|
if (!table)
|
||||||
|
return 1;
|
||||||
|
|
||||||
(void) mi_status(file,&misam_info,flag);
|
(void) mi_status(file,&misam_info,flag);
|
||||||
if (flag & HA_STATUS_VARIABLE)
|
if (flag & HA_STATUS_VARIABLE)
|
||||||
{
|
{
|
||||||
|
Loading…
x
Reference in New Issue
Block a user