Merge dl145s.mysql.com:/data/bk/team_tree_merge/CLEAN/mysql-5.0
into dl145s.mysql.com:/data/bk/team_tree_merge/MERGE/mysql-5.0-opt
This commit is contained in:
commit
148cb4e98a
@ -773,3 +773,5 @@ Warnings:
|
|||||||
Warning 1071 Specified key was too long; max key length is 765 bytes
|
Warning 1071 Specified key was too long; max key length is 765 bytes
|
||||||
insert into t1 values('aaa');
|
insert into t1 values('aaa');
|
||||||
drop table t1;
|
drop table t1;
|
||||||
|
create table t1 (upgrade int);
|
||||||
|
drop table t1;
|
||||||
|
@ -172,6 +172,10 @@ a
|
|||||||
0
|
0
|
||||||
2
|
2
|
||||||
DROP TABLE t1;
|
DROP TABLE t1;
|
||||||
|
create table t1 (a int);
|
||||||
|
delete `4.t1` from t1 as `4.t1` where `4.t1`.a = 5;
|
||||||
|
delete FROM `4.t1` USING t1 as `4.t1` where `4.t1`.a = 5;
|
||||||
|
drop table t1;
|
||||||
CREATE TABLE t1 (a int not null,b int not null);
|
CREATE TABLE t1 (a int not null,b int not null);
|
||||||
CREATE TABLE t2 (a int not null, b int not null, primary key (a,b));
|
CREATE TABLE t2 (a int not null, b int not null, primary key (a,b));
|
||||||
CREATE TABLE t3 (a int not null, b int not null, primary key (a,b));
|
CREATE TABLE t3 (a int not null, b int not null, primary key (a,b));
|
||||||
|
@ -566,14 +566,14 @@ COUNT(*) GROUP_CONCAT(DISTINCT t2.somename SEPARATOR ' |')
|
|||||||
DROP TABLE t1,t2;
|
DROP TABLE t1,t2;
|
||||||
select * from (select group_concat('c') from DUAL) t;
|
select * from (select group_concat('c') from DUAL) t;
|
||||||
group_concat('c')
|
group_concat('c')
|
||||||
NULL
|
c
|
||||||
create table t1 ( a int not null default 0);
|
create table t1 ( a int not null default 0);
|
||||||
select * from (select group_concat(a) from t1) t2;
|
select * from (select group_concat(a) from t1) t2;
|
||||||
group_concat(a)
|
group_concat(a)
|
||||||
NULL
|
NULL
|
||||||
select group_concat('x') UNION ALL select 1;
|
select group_concat('x') UNION ALL select 1;
|
||||||
group_concat('x')
|
group_concat('x')
|
||||||
NULL
|
x
|
||||||
1
|
1
|
||||||
drop table t1;
|
drop table t1;
|
||||||
CREATE TABLE t1 (id int, a varchar(9));
|
CREATE TABLE t1 (id int, a varchar(9));
|
||||||
|
@ -856,6 +856,22 @@ EXPLAIN SELECT MAX(b) 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 SIMPLE t1 ALL NULL NULL NULL NULL 4
|
1 SIMPLE t1 ALL NULL NULL NULL NULL 4
|
||||||
DROP TABLE t1;
|
DROP TABLE t1;
|
||||||
|
CREATE TABLE t1 (a INT, b INT);
|
||||||
|
INSERT INTO t1 VALUES (1,1),(1,2),(2,3);
|
||||||
|
SELECT (SELECT COUNT(DISTINCT t1.b)) FROM t1 GROUP BY t1.a;
|
||||||
|
(SELECT COUNT(DISTINCT t1.b))
|
||||||
|
0
|
||||||
|
2
|
||||||
|
SELECT (SELECT COUNT(DISTINCT 12)) FROM t1 GROUP BY t1.a;
|
||||||
|
(SELECT COUNT(DISTINCT 12))
|
||||||
|
1
|
||||||
|
1
|
||||||
|
SELECT AVG(2), BIT_AND(2), BIT_OR(2), BIT_XOR(2), COUNT(*), COUNT(12),
|
||||||
|
COUNT(DISTINCT 12), MIN(2),MAX(2),STD(2), VARIANCE(2),SUM(2),
|
||||||
|
GROUP_CONCAT(2),GROUP_CONCAT(DISTINCT 2);
|
||||||
|
AVG(2) BIT_AND(2) BIT_OR(2) BIT_XOR(2) COUNT(*) COUNT(12) COUNT(DISTINCT 12) MIN(2) MAX(2) STD(2) VARIANCE(2) SUM(2) GROUP_CONCAT(2) GROUP_CONCAT(DISTINCT 2)
|
||||||
|
2.00000 2 2 2 1 1 1 2 2 0.00000 0.00000 2 2 2
|
||||||
|
DROP TABLE t1;
|
||||||
create table t2 (ff double);
|
create table t2 (ff double);
|
||||||
insert into t2 values (2.2);
|
insert into t2 values (2.2);
|
||||||
select cast(sum(distinct ff) as decimal(5,2)) from t2;
|
select cast(sum(distinct ff) as decimal(5,2)) from t2;
|
||||||
|
@ -1113,4 +1113,39 @@ conv("18383815659218730760",10,10) + 0
|
|||||||
select "18383815659218730760" + 0;
|
select "18383815659218730760" + 0;
|
||||||
"18383815659218730760" + 0
|
"18383815659218730760" + 0
|
||||||
1.8383815659219e+19
|
1.8383815659219e+19
|
||||||
|
CREATE TABLE t1 (code varchar(10));
|
||||||
|
INSERT INTO t1 VALUES ('a12'), ('A12'), ('a13');
|
||||||
|
SELECT ASCII(code), code FROM t1 WHERE code='A12';
|
||||||
|
ASCII(code) code
|
||||||
|
97 a12
|
||||||
|
65 A12
|
||||||
|
SELECT ASCII(code), code FROM t1 WHERE code='A12' AND ASCII(code)=65;
|
||||||
|
ASCII(code) code
|
||||||
|
65 A12
|
||||||
|
INSERT INTO t1 VALUES ('a12 '), ('A12 ');
|
||||||
|
SELECT LENGTH(code), code FROM t1 WHERE code='A12';
|
||||||
|
LENGTH(code) code
|
||||||
|
3 a12
|
||||||
|
3 A12
|
||||||
|
4 a12
|
||||||
|
5 A12
|
||||||
|
SELECT LENGTH(code), code FROM t1 WHERE code='A12' AND LENGTH(code)=5;
|
||||||
|
LENGTH(code) code
|
||||||
|
5 A12
|
||||||
|
ALTER TABLE t1 ADD INDEX (code);
|
||||||
|
CREATE TABLE t2 (id varchar(10) PRIMARY KEY);
|
||||||
|
INSERT INTO t2 VALUES ('a11'), ('a12'), ('a13'), ('a14');
|
||||||
|
SELECT * FROM t1 INNER JOIN t2 ON t1.code=t2.id
|
||||||
|
WHERE t2.id='a12' AND (LENGTH(code)=5 OR code < 'a00');
|
||||||
|
code id
|
||||||
|
A12 a12
|
||||||
|
EXPLAIN EXTENDED
|
||||||
|
SELECT * FROM t1 INNER JOIN t2 ON code=id
|
||||||
|
WHERE id='a12' AND (LENGTH(code)=5 OR code < 'a00');
|
||||||
|
id select_type table type possible_keys key key_len ref rows Extra
|
||||||
|
1 SIMPLE t1 ref code code 13 const 3 Using where; Using index
|
||||||
|
1 SIMPLE t2 ref PRIMARY PRIMARY 12 const 1 Using where; Using index
|
||||||
|
Warnings:
|
||||||
|
Note 1003 select `test`.`t1`.`code` AS `code`,`test`.`t2`.`id` AS `id` from `test`.`t1` join `test`.`t2` where ((`test`.`t1`.`code` = _latin1'a12') and (`test`.`t2`.`id` = _latin1'a12') and (length(`test`.`t1`.`code`) = 5))
|
||||||
|
DROP TABLE t1,t2;
|
||||||
End of 5.0 tests
|
End of 5.0 tests
|
||||||
|
@ -807,8 +807,8 @@ explain
|
|||||||
SELECT straight_join sql_no_cache v1.a, v1.b, v1.real_b from t2, v1
|
SELECT straight_join sql_no_cache v1.a, v1.b, v1.real_b from t2, v1
|
||||||
where t2.b=v1.a GROUP BY t2.b;
|
where t2.b=v1.a 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 t2 index b b 2 NULL 10 Using index
|
1 SIMPLE t2 index b b 2 NULL 10 Using index
|
||||||
1 PRIMARY t1 eq_ref PRIMARY PRIMARY 1 test.t2.b 1
|
1 SIMPLE t1 eq_ref PRIMARY PRIMARY 1 test.t2.b 1
|
||||||
SELECT straight_join sql_no_cache v1.a, v1.b, v1.real_b from t2, v1
|
SELECT straight_join sql_no_cache v1.a, v1.b, v1.real_b from t2, v1
|
||||||
where t2.b=v1.a GROUP BY t2.b;
|
where t2.b=v1.a GROUP BY t2.b;
|
||||||
a b real_b
|
a b real_b
|
||||||
|
@ -354,7 +354,7 @@ t3 1 a 2 b NULL 13 NULL NULL HASH
|
|||||||
explain select * from t1 ignore key(btree_idx), t3 where t1.name='matt' and t3.a = concat('',t1.name) and t3.b=t1.name;
|
explain select * from t1 ignore key(btree_idx), t3 where t1.name='matt' and t3.a = concat('',t1.name) and t3.b=t1.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 SIMPLE t1 ref heap_idx heap_idx 22 const 7 Using where
|
1 SIMPLE t1 ref heap_idx heap_idx 22 const 7 Using where
|
||||||
1 SIMPLE t3 ref a a 44 const,const 7 Using where
|
1 SIMPLE t3 ref a a 44 func,const 7 Using where
|
||||||
drop table t1, t2, t3;
|
drop table t1, t2, t3;
|
||||||
create temporary table t1 ( a int, index (a) ) engine=memory;
|
create temporary table t1 ( a int, index (a) ) engine=memory;
|
||||||
insert into t1 values (1),(2),(3),(4),(5);
|
insert into t1 values (1),(2),(3),(4),(5);
|
||||||
|
@ -337,7 +337,7 @@ mysql
|
|||||||
test
|
test
|
||||||
explain select * from v0;
|
explain select * from v0;
|
||||||
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 # ALL NULL NULL NULL NULL 2
|
1 SIMPLE # ALL NULL NULL NULL NULL 2
|
||||||
create view v1 (c) as select table_name from information_schema.tables
|
create view v1 (c) as select table_name from information_schema.tables
|
||||||
where table_name="v1";
|
where table_name="v1";
|
||||||
select * from v1;
|
select * from v1;
|
||||||
|
@ -118,7 +118,7 @@ min(7)
|
|||||||
NULL
|
NULL
|
||||||
select min(7) from DUAL;
|
select min(7) from DUAL;
|
||||||
min(7)
|
min(7)
|
||||||
NULL
|
7
|
||||||
explain select min(7) from t2m join t1m;
|
explain select min(7) from t2m join t1m;
|
||||||
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 SIMPLE NULL NULL NULL NULL NULL NULL NULL Select tables optimized away
|
1 SIMPLE NULL NULL NULL NULL NULL NULL NULL Select tables optimized away
|
||||||
@ -133,7 +133,7 @@ max(7)
|
|||||||
NULL
|
NULL
|
||||||
select max(7) from DUAL;
|
select max(7) from DUAL;
|
||||||
max(7)
|
max(7)
|
||||||
NULL
|
7
|
||||||
explain select max(7) from t2m join t1m;
|
explain select max(7) from t2m join t1m;
|
||||||
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 SIMPLE NULL NULL NULL NULL NULL NULL NULL Select tables optimized away
|
1 SIMPLE NULL NULL NULL NULL NULL NULL NULL Select tables optimized away
|
||||||
@ -172,7 +172,7 @@ min(7)
|
|||||||
NULL
|
NULL
|
||||||
select min(7) from DUAL;
|
select min(7) from DUAL;
|
||||||
min(7)
|
min(7)
|
||||||
NULL
|
7
|
||||||
explain select min(7) from t2i join t1i;
|
explain select min(7) from t2i join t1i;
|
||||||
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 SIMPLE t2i ALL NULL NULL NULL NULL 1
|
1 SIMPLE t2i ALL NULL NULL NULL NULL 1
|
||||||
@ -188,7 +188,7 @@ max(7)
|
|||||||
NULL
|
NULL
|
||||||
select max(7) from DUAL;
|
select max(7) from DUAL;
|
||||||
max(7)
|
max(7)
|
||||||
NULL
|
7
|
||||||
explain select max(7) from t2i join t1i;
|
explain select max(7) from t2i join t1i;
|
||||||
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 SIMPLE t2i ALL NULL NULL NULL NULL 1
|
1 SIMPLE t2i ALL NULL NULL NULL NULL 1
|
||||||
|
@ -1126,7 +1126,7 @@ a b a b
|
|||||||
7 8 7 5
|
7 8 7 5
|
||||||
EXPLAIN SELECT * FROM t1 LEFT JOIN t2 ON t1.a = t2.a WHERE t1.a = t2.a OR t1.a = t2.b;
|
EXPLAIN SELECT * FROM t1 LEFT JOIN t2 ON t1.a = t2.a WHERE t1.a = t2.a OR t1.a = 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 SIMPLE t2 ALL PRIMARY NULL NULL NULL 4 Using where
|
1 SIMPLE t2 ALL PRIMARY NULL NULL NULL 4
|
||||||
1 SIMPLE t1 eq_ref PRIMARY PRIMARY 4 test.t2.a 1
|
1 SIMPLE t1 eq_ref PRIMARY PRIMARY 4 test.t2.a 1
|
||||||
EXPLAIN SELECT * FROM t1 LEFT JOIN t2 ON t1.a = t2.a WHERE t1.a IN(t2.a, t2.b);
|
EXPLAIN SELECT * FROM t1 LEFT JOIN t2 ON t1.a = t2.a WHERE t1.a IN(t2.a, 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
|
||||||
|
@ -611,7 +611,7 @@ C
|
|||||||
NULL
|
NULL
|
||||||
EXPLAIN SELECT type FROM v1 GROUP BY type WITH ROLLUP;
|
EXPLAIN SELECT type FROM v1 GROUP BY type WITH ROLLUP;
|
||||||
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 10 Using filesort
|
1 SIMPLE t1 ALL NULL NULL NULL NULL 10 Using filesort
|
||||||
DROP VIEW v1;
|
DROP VIEW v1;
|
||||||
DROP TABLE t1;
|
DROP TABLE t1;
|
||||||
CREATE TABLE t1 (a int(11) NOT NULL);
|
CREATE TABLE t1 (a int(11) NOT NULL);
|
||||||
|
@ -947,18 +947,24 @@ COUNT(*)
|
|||||||
Warnings:
|
Warnings:
|
||||||
Warning 1292 Incorrect datetime value: '20050327 invalid' for column 'date' at row 1
|
Warning 1292 Incorrect datetime value: '20050327 invalid' for column 'date' at row 1
|
||||||
Warning 1292 Incorrect datetime value: '20050327 invalid' for column 'date' at row 1
|
Warning 1292 Incorrect datetime value: '20050327 invalid' for column 'date' at row 1
|
||||||
|
Warning 1292 Truncated incorrect DOUBLE value: '20050327 invalid'
|
||||||
|
Warning 1292 Truncated incorrect DOUBLE value: '20050327 invalid'
|
||||||
SELECT COUNT(*) FROM t1 WHERE date BETWEEN '20050326' AND '20050328 invalid';
|
SELECT COUNT(*) FROM t1 WHERE date BETWEEN '20050326' AND '20050328 invalid';
|
||||||
COUNT(*)
|
COUNT(*)
|
||||||
0
|
0
|
||||||
Warnings:
|
Warnings:
|
||||||
Warning 1292 Incorrect datetime value: '20050328 invalid' for column 'date' at row 1
|
Warning 1292 Incorrect datetime value: '20050328 invalid' for column 'date' at row 1
|
||||||
Warning 1292 Incorrect datetime value: '20050328 invalid' for column 'date' at row 1
|
Warning 1292 Incorrect datetime value: '20050328 invalid' for column 'date' at row 1
|
||||||
|
Warning 1292 Truncated incorrect DOUBLE value: '20050328 invalid'
|
||||||
|
Warning 1292 Truncated incorrect DOUBLE value: '20050328 invalid'
|
||||||
SELECT COUNT(*) FROM t1 WHERE date BETWEEN '20050326' AND '20050327 invalid';
|
SELECT COUNT(*) FROM t1 WHERE date BETWEEN '20050326' AND '20050327 invalid';
|
||||||
COUNT(*)
|
COUNT(*)
|
||||||
0
|
0
|
||||||
Warnings:
|
Warnings:
|
||||||
Warning 1292 Incorrect datetime value: '20050327 invalid' for column 'date' at row 1
|
Warning 1292 Incorrect datetime value: '20050327 invalid' for column 'date' at row 1
|
||||||
Warning 1292 Incorrect datetime value: '20050327 invalid' for column 'date' at row 1
|
Warning 1292 Incorrect datetime value: '20050327 invalid' for column 'date' at row 1
|
||||||
|
Warning 1292 Truncated incorrect DOUBLE value: '20050327 invalid'
|
||||||
|
Warning 1292 Truncated incorrect DOUBLE value: '20050327 invalid'
|
||||||
show status like "Qcache_queries_in_cache";
|
show status like "Qcache_queries_in_cache";
|
||||||
Variable_name Value
|
Variable_name Value
|
||||||
Qcache_queries_in_cache 0
|
Qcache_queries_in_cache 0
|
||||||
|
@ -750,13 +750,13 @@ id select_type table type possible_keys key key_len ref rows Extra
|
|||||||
1 SIMPLE t1 range PRIMARY PRIMARY 4 NULL 4 Using where; Using index
|
1 SIMPLE t1 range PRIMARY PRIMARY 4 NULL 4 Using where; Using index
|
||||||
EXPLAIN SELECT a,b FROM v1 WHERE a < 2 and b=3;
|
EXPLAIN SELECT a,b FROM v1 WHERE a < 2 and b=3;
|
||||||
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 range PRIMARY PRIMARY 4 NULL 4 Using where; Using index
|
1 SIMPLE t1 range PRIMARY PRIMARY 4 NULL 4 Using where; Using index
|
||||||
EXPLAIN SELECT a,b FROM t1 WHERE a < 2;
|
EXPLAIN SELECT a,b FROM t1 WHERE a < 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 SIMPLE t1 range PRIMARY PRIMARY 4 NULL 4 Using where; Using index
|
1 SIMPLE t1 range PRIMARY PRIMARY 4 NULL 4 Using where; Using index
|
||||||
EXPLAIN SELECT a,b FROM v1 WHERE a < 2;
|
EXPLAIN SELECT a,b FROM v1 WHERE a < 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 t1 range PRIMARY PRIMARY 4 NULL 4 Using where; Using index
|
1 SIMPLE t1 range PRIMARY PRIMARY 4 NULL 4 Using where; Using index
|
||||||
SELECT a,b FROM t1 WHERE a < 2 and b=3;
|
SELECT a,b FROM t1 WHERE a < 2 and b=3;
|
||||||
a b
|
a b
|
||||||
1 3
|
1 3
|
||||||
@ -799,13 +799,13 @@ id select_type table type possible_keys key key_len ref rows Extra
|
|||||||
1 SIMPLE t1 range PRIMARY PRIMARY 8 NULL # Using where; Using index
|
1 SIMPLE t1 range PRIMARY PRIMARY 8 NULL # Using where; Using index
|
||||||
explain select * from v1 where a in (3,4) and b in (1,2,3);
|
explain select * from v1 where a in (3,4) and b in (1,2,3);
|
||||||
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 range PRIMARY PRIMARY 8 NULL # Using where; Using index
|
1 SIMPLE t1 range PRIMARY PRIMARY 8 NULL # Using where; Using index
|
||||||
explain select * from t1 where a between 3 and 4 and b between 1 and 2;
|
explain select * from t1 where a between 3 and 4 and b between 1 and 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 SIMPLE t1 range PRIMARY PRIMARY 8 NULL # Using where; Using index
|
1 SIMPLE t1 range PRIMARY PRIMARY 8 NULL # Using where; Using index
|
||||||
explain select * from v1 where a between 3 and 4 and b between 1 and 2;
|
explain select * from v1 where a between 3 and 4 and b between 1 and 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 t1 range PRIMARY PRIMARY 8 NULL # Using where; Using index
|
1 SIMPLE t1 range PRIMARY PRIMARY 8 NULL # Using where; Using index
|
||||||
drop view v1;
|
drop view v1;
|
||||||
drop table t1;
|
drop table t1;
|
||||||
create table t3 (a int);
|
create table t3 (a int);
|
||||||
@ -896,3 +896,48 @@ EXPLAIN SELECT * FROM t1 WHERE 0 NOT BETWEEN b AND c;
|
|||||||
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 SIMPLE t1 index_merge idx1,idx2 idx1,idx2 4,4 NULL 4 Using sort_union(idx1,idx2); Using where
|
1 SIMPLE t1 index_merge idx1,idx2 idx1,idx2 4,4 NULL 4 Using sort_union(idx1,idx2); Using where
|
||||||
DROP TABLE t1;
|
DROP TABLE t1;
|
||||||
|
CREATE TABLE t1 (
|
||||||
|
item char(20) NOT NULL default '',
|
||||||
|
started datetime NOT NULL default '0000-00-00 00:00:00',
|
||||||
|
price decimal(16,3) NOT NULL default '0.000',
|
||||||
|
PRIMARY KEY (item,started)
|
||||||
|
) ENGINE=MyISAM;
|
||||||
|
INSERT INTO t1 VALUES
|
||||||
|
('A1','2005-11-01 08:00:00',1000),
|
||||||
|
('A1','2005-11-15 00:00:00',2000),
|
||||||
|
('A1','2005-12-12 08:00:00',3000),
|
||||||
|
('A2','2005-12-01 08:00:00',1000);
|
||||||
|
EXPLAIN SELECT * FROM t1 WHERE item='A1' AND started<='2005-12-01 24:00:00';
|
||||||
|
id select_type table type possible_keys key key_len ref rows Extra
|
||||||
|
1 SIMPLE t1 ref PRIMARY PRIMARY 20 const 2 Using where
|
||||||
|
Warnings:
|
||||||
|
Warning 1292 Incorrect datetime value: '2005-12-01 24:00:00' for column 'started' at row 1
|
||||||
|
Warning 1292 Incorrect datetime value: '2005-12-01 24:00:00' for column 'started' at row 1
|
||||||
|
SELECT * FROM t1 WHERE item='A1' AND started<='2005-12-01 24:00:00';
|
||||||
|
item started price
|
||||||
|
A1 2005-11-01 08:00:00 1000.000
|
||||||
|
A1 2005-11-15 00:00:00 2000.000
|
||||||
|
Warnings:
|
||||||
|
Warning 1292 Incorrect datetime value: '2005-12-01 24:00:00' for column 'started' at row 1
|
||||||
|
Warning 1292 Incorrect datetime value: '2005-12-01 24:00:00' for column 'started' at row 1
|
||||||
|
SELECT * FROM t1 WHERE item='A1' AND started<='2005-12-02 00:00:00';
|
||||||
|
item started price
|
||||||
|
A1 2005-11-01 08:00:00 1000.000
|
||||||
|
A1 2005-11-15 00:00:00 2000.000
|
||||||
|
DROP INDEX `PRIMARY` ON t1;
|
||||||
|
EXPLAIN SELECT * FROM t1 WHERE item='A1' AND started<='2005-12-01 24:00:00';
|
||||||
|
id select_type table type possible_keys key key_len ref rows Extra
|
||||||
|
1 SIMPLE t1 ALL NULL NULL NULL NULL 4 Using where
|
||||||
|
Warnings:
|
||||||
|
Warning 1292 Incorrect datetime value: '2005-12-01 24:00:00' for column 'started' at row 1
|
||||||
|
SELECT * FROM t1 WHERE item='A1' AND started<='2005-12-01 24:00:00';
|
||||||
|
item started price
|
||||||
|
A1 2005-11-01 08:00:00 1000.000
|
||||||
|
A1 2005-11-15 00:00:00 2000.000
|
||||||
|
Warnings:
|
||||||
|
Warning 1292 Incorrect datetime value: '2005-12-01 24:00:00' for column 'started' at row 1
|
||||||
|
SELECT * FROM t1 WHERE item='A1' AND started<='2005-12-02 00:00:00';
|
||||||
|
item started price
|
||||||
|
A1 2005-11-01 08:00:00 1000.000
|
||||||
|
A1 2005-11-15 00:00:00 2000.000
|
||||||
|
DROP TABLE t1;
|
||||||
|
@ -181,3 +181,128 @@ SELECT ROW(1,1,1) = ROW(1,1,1) as `1`, ROW(1,1,1) = ROW(1,2,1) as `0`, ROW(1,NUL
|
|||||||
select row(NULL,1)=(2,0);
|
select row(NULL,1)=(2,0);
|
||||||
row(NULL,1)=(2,0)
|
row(NULL,1)=(2,0)
|
||||||
0
|
0
|
||||||
|
CREATE TABLE t1 (a int, b int, PRIMARY KEY (a,b));
|
||||||
|
INSERT INTO t1 VALUES (1,1), (2,1), (3,1), (1,2), (3,2), (3,3);
|
||||||
|
EXPLAIN SELECT * FROM t1 WHERE a=3 AND b=2;
|
||||||
|
id select_type table type possible_keys key key_len ref rows Extra
|
||||||
|
1 SIMPLE t1 const PRIMARY PRIMARY 8 const,const 1 Using index
|
||||||
|
EXPLAIN SELECT * FROM t1 WHERE (a,b)=(3,2);
|
||||||
|
id select_type table type possible_keys key key_len ref rows Extra
|
||||||
|
1 SIMPLE t1 const PRIMARY PRIMARY 8 const,const 1 Using index
|
||||||
|
SELECT * FROM t1 WHERE a=3 and b=2;
|
||||||
|
a b
|
||||||
|
3 2
|
||||||
|
SELECT * FROM t1 WHERE (a,b)=(3,2);
|
||||||
|
a b
|
||||||
|
3 2
|
||||||
|
CREATE TABLE t2 (a int, b int, c int, PRIMARY KEY (a,b,c));
|
||||||
|
INSERT INTO t2 VALUES
|
||||||
|
(1,1,2), (3,1,3), (1,2,2), (4,4,2),
|
||||||
|
(1,1,1), (3,1,1), (1,2,1);
|
||||||
|
EXPLAIN SELECT * FROM t1,t2 WHERE t1.a=t2.a AND t1.b=t2.b;
|
||||||
|
id select_type table type possible_keys key key_len ref rows Extra
|
||||||
|
1 SIMPLE t1 index PRIMARY PRIMARY 8 NULL 6 Using index
|
||||||
|
1 SIMPLE t2 ref PRIMARY PRIMARY 8 test.t1.a,test.t1.b 1 Using index
|
||||||
|
EXPLAIN SELECT * FROM t1,t2 WHERE (t1.a,t1.b)=(t2.a,t2.b);
|
||||||
|
id select_type table type possible_keys key key_len ref rows Extra
|
||||||
|
1 SIMPLE t1 index PRIMARY PRIMARY 8 NULL 6 Using index
|
||||||
|
1 SIMPLE t2 ref PRIMARY PRIMARY 8 test.t1.a,test.t1.b 1 Using index
|
||||||
|
SELECT * FROM t1,t2 WHERE t1.a=t2.a and t1.b=t2.b;
|
||||||
|
a b a b c
|
||||||
|
1 1 1 1 1
|
||||||
|
1 1 1 1 2
|
||||||
|
1 2 1 2 1
|
||||||
|
1 2 1 2 2
|
||||||
|
3 1 3 1 1
|
||||||
|
3 1 3 1 3
|
||||||
|
SELECT * FROM t1,t2 WHERE (t1.a,t1.b)=(t2.a,t2.b);
|
||||||
|
a b a b c
|
||||||
|
1 1 1 1 1
|
||||||
|
1 1 1 1 2
|
||||||
|
1 2 1 2 1
|
||||||
|
1 2 1 2 2
|
||||||
|
3 1 3 1 1
|
||||||
|
3 1 3 1 3
|
||||||
|
EXPLAIN SELECT * FROM t1,t2 WHERE t1.a=t2.a AND t1.b=2;
|
||||||
|
id select_type table type possible_keys key key_len ref rows Extra
|
||||||
|
1 SIMPLE t1 index PRIMARY PRIMARY 8 NULL 5 Using where; Using index
|
||||||
|
1 SIMPLE t2 ref PRIMARY PRIMARY 4 test.t1.a 1 Using index
|
||||||
|
EXPLAIN SELECT * FROM t1,t2 WHERE (t1.a,t1.b)=(t2.a,2);
|
||||||
|
id select_type table type possible_keys key key_len ref rows Extra
|
||||||
|
1 SIMPLE t1 index PRIMARY PRIMARY 8 NULL 5 Using where; Using index
|
||||||
|
1 SIMPLE t2 ref PRIMARY PRIMARY 4 test.t1.a 1 Using index
|
||||||
|
SELECT * FROM t1,t2 WHERE t1.a=1 and t1.b=t2.b;
|
||||||
|
a b a b c
|
||||||
|
1 1 1 1 2
|
||||||
|
1 1 3 1 3
|
||||||
|
1 2 1 2 2
|
||||||
|
1 1 1 1 1
|
||||||
|
1 1 3 1 1
|
||||||
|
1 2 1 2 1
|
||||||
|
SELECT * FROM t1,t2 WHERE (t1.a,t1.b)=(t2.a,2);
|
||||||
|
a b a b c
|
||||||
|
1 2 1 1 1
|
||||||
|
1 2 1 1 2
|
||||||
|
1 2 1 2 1
|
||||||
|
1 2 1 2 2
|
||||||
|
3 2 3 1 1
|
||||||
|
3 2 3 1 3
|
||||||
|
EXPLAIN EXTENDED SELECT * FROM t1,t2 WHERE (t1.a,t1.b)=(t2.a,t2.b+1);
|
||||||
|
id select_type table type possible_keys key key_len ref rows Extra
|
||||||
|
1 SIMPLE t1 index PRIMARY PRIMARY 8 NULL 6 Using index
|
||||||
|
1 SIMPLE t2 ref PRIMARY PRIMARY 4 test.t1.a 1 Using where; Using index
|
||||||
|
Warnings:
|
||||||
|
Note 1003 select `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b`,`test`.`t2`.`a` AS `a`,`test`.`t2`.`b` AS `b`,`test`.`t2`.`c` AS `c` from `test`.`t1` join `test`.`t2` where ((`test`.`t2`.`a` = `test`.`t1`.`a`) and (`test`.`t1`.`b` = (`test`.`t2`.`b` + 1)))
|
||||||
|
SELECT * FROM t1,t2 WHERE (t1.a,t1.b)=(t2.a,t2.b+1);
|
||||||
|
a b a b c
|
||||||
|
1 2 1 1 1
|
||||||
|
1 2 1 1 2
|
||||||
|
3 2 3 1 1
|
||||||
|
3 2 3 1 3
|
||||||
|
EXPLAIN EXTENDED SELECT * FROM t1,t2 WHERE (t1.a-1,t1.b)=(t2.a-1,t2.b+1);
|
||||||
|
id select_type table type possible_keys key key_len ref rows Extra
|
||||||
|
1 SIMPLE t1 index NULL PRIMARY 8 NULL 6 Using index
|
||||||
|
1 SIMPLE t2 index NULL PRIMARY 12 NULL 7 Using where; Using index
|
||||||
|
Warnings:
|
||||||
|
Note 1003 select `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b`,`test`.`t2`.`a` AS `a`,`test`.`t2`.`b` AS `b`,`test`.`t2`.`c` AS `c` from `test`.`t1` join `test`.`t2` where (((`test`.`t1`.`a` - 1) = (`test`.`t2`.`a` - 1)) and (`test`.`t1`.`b` = (`test`.`t2`.`b` + 1)))
|
||||||
|
SELECT * FROM t1,t2 WHERE (t1.a-1,t1.b)=(t2.a-1,t2.b+1);
|
||||||
|
a b a b c
|
||||||
|
1 2 1 1 2
|
||||||
|
3 2 3 1 3
|
||||||
|
1 2 1 1 1
|
||||||
|
3 2 3 1 1
|
||||||
|
EXPLAIN SELECT * FROM t2 WHERE a=3 AND b=2;
|
||||||
|
id select_type table type possible_keys key key_len ref rows Extra
|
||||||
|
1 SIMPLE t2 ref PRIMARY PRIMARY 8 const,const 1 Using index
|
||||||
|
EXPLAIN SELECT * FROM t2 WHERE (a,b)=(3,2);
|
||||||
|
id select_type table type possible_keys key key_len ref rows Extra
|
||||||
|
1 SIMPLE t2 ref PRIMARY PRIMARY 8 const,const 1 Using index
|
||||||
|
SELECT * FROM t2 WHERE a=3 and b=2;
|
||||||
|
a b c
|
||||||
|
SELECT * FROM t2 WHERE (a,b)=(3,2);
|
||||||
|
a b c
|
||||||
|
EXPLAIN SELECT * FROM t1,t2 WHERE t2.a=t1.a AND t2.b=2 AND t2.c=1;
|
||||||
|
id select_type table type possible_keys key key_len ref rows Extra
|
||||||
|
1 SIMPLE t1 index PRIMARY PRIMARY 8 NULL 6 Using index
|
||||||
|
1 SIMPLE t2 eq_ref PRIMARY PRIMARY 12 test.t1.a,const,const 1 Using index
|
||||||
|
EXPLAIN EXTENDED SELECT * FROM t1,t2 WHERE (t2.a,(t2.b,t2.c))=(t1.a,(2,1));
|
||||||
|
id select_type table type possible_keys key key_len ref rows Extra
|
||||||
|
1 SIMPLE t1 index PRIMARY PRIMARY 8 NULL 6 Using index
|
||||||
|
1 SIMPLE t2 eq_ref PRIMARY PRIMARY 12 test.t1.a,const,const 1 Using index
|
||||||
|
Warnings:
|
||||||
|
Note 1003 select `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b`,`test`.`t2`.`a` AS `a`,`test`.`t2`.`b` AS `b`,`test`.`t2`.`c` AS `c` from `test`.`t1` join `test`.`t2` where ((`test`.`t2`.`c` = 1) and (`test`.`t2`.`b` = 2) and (`test`.`t2`.`a` = `test`.`t1`.`a`))
|
||||||
|
SELECT * FROM t1,t2 WHERE (t2.a,(t2.b,t2.c))=(t1.a,(2,1));
|
||||||
|
a b a b c
|
||||||
|
1 1 1 2 1
|
||||||
|
1 2 1 2 1
|
||||||
|
EXPLAIN EXTENDED SELECT * FROM t1,t2 WHERE t2.a=t1.a AND (t2.b,t2.c)=(2,1);
|
||||||
|
id select_type table type possible_keys key key_len ref rows Extra
|
||||||
|
1 SIMPLE t1 index PRIMARY PRIMARY 8 NULL 6 Using index
|
||||||
|
1 SIMPLE t2 eq_ref PRIMARY PRIMARY 12 test.t1.a,const,const 1 Using index
|
||||||
|
Warnings:
|
||||||
|
Note 1003 select `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b`,`test`.`t2`.`a` AS `a`,`test`.`t2`.`b` AS `b`,`test`.`t2`.`c` AS `c` from `test`.`t1` join `test`.`t2` where ((`test`.`t2`.`c` = 1) and (`test`.`t2`.`b` = 2) and (`test`.`t2`.`a` = `test`.`t1`.`a`))
|
||||||
|
SELECT * FROM t1,t2 WHERE t2.a=t1.a AND (t2.b,t2.c)=(2,1);
|
||||||
|
a b a b c
|
||||||
|
1 1 1 2 1
|
||||||
|
1 2 1 2 1
|
||||||
|
DROP TABLE t1,t2;
|
||||||
|
@ -1011,7 +1011,7 @@ INSERT INTO t1 VALUES (1);
|
|||||||
UPDATE t1 SET i=i+1 WHERE i=(SELECT MAX(i));
|
UPDATE t1 SET i=i+1 WHERE i=(SELECT MAX(i));
|
||||||
select * from t1;
|
select * from t1;
|
||||||
i
|
i
|
||||||
1
|
2
|
||||||
drop table t1;
|
drop table t1;
|
||||||
CREATE TABLE t1 (a int(1));
|
CREATE TABLE t1 (a int(1));
|
||||||
EXPLAIN EXTENDED SELECT (SELECT RAND() FROM t1) FROM t1;
|
EXPLAIN EXTENDED SELECT (SELECT RAND() FROM t1) FROM t1;
|
||||||
@ -1203,7 +1203,7 @@ UPDATE t1 SET t.i=i+(SELECT MAX(i) FROM (SELECT 1) t);
|
|||||||
ERROR 42S22: Unknown column 't.i' in 'field list'
|
ERROR 42S22: Unknown column 't.i' in 'field list'
|
||||||
select * from t1;
|
select * from t1;
|
||||||
i
|
i
|
||||||
1
|
3
|
||||||
drop table t1;
|
drop table t1;
|
||||||
CREATE TABLE t1 (
|
CREATE TABLE t1 (
|
||||||
id int(11) default NULL
|
id int(11) default NULL
|
||||||
@ -3368,3 +3368,28 @@ ORDER BY t1.t DESC LIMIT 1);
|
|||||||
i1 i2 t i1 i2 t
|
i1 i2 t i1 i2 t
|
||||||
24 1 2005-05-27 12:40:30 24 1 2006-06-20 12:29:40
|
24 1 2005-05-27 12:40:30 24 1 2006-06-20 12:29:40
|
||||||
DROP TABLE t1, t2;
|
DROP TABLE t1, t2;
|
||||||
|
CREATE TABLE t1 (i INT);
|
||||||
|
(SELECT i FROM t1) UNION (SELECT i FROM t1);
|
||||||
|
i
|
||||||
|
SELECT sql_no_cache * FROM t1 WHERE NOT EXISTS
|
||||||
|
(
|
||||||
|
(SELECT i FROM t1) UNION
|
||||||
|
(SELECT i FROM t1)
|
||||||
|
);
|
||||||
|
i
|
||||||
|
SELECT * FROM t1
|
||||||
|
WHERE NOT EXISTS (((SELECT i FROM t1) UNION (SELECT i FROM t1)));
|
||||||
|
i
|
||||||
|
explain select ((select t11.i from t1 t11) union (select t12.i from t1 t12))
|
||||||
|
from t1;
|
||||||
|
ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'union (select t12.i from t1 t12))
|
||||||
|
from t1' at line 1
|
||||||
|
explain select * from t1 where not exists
|
||||||
|
((select t11.i from t1 t11) union (select t12.i from t1 t12));
|
||||||
|
id select_type table type possible_keys key key_len ref rows Extra
|
||||||
|
1 PRIMARY t1 system NULL NULL NULL NULL 0 const row not found
|
||||||
|
2 SUBQUERY NULL NULL NULL NULL NULL NULL NULL No tables used
|
||||||
|
3 SUBQUERY NULL NULL NULL NULL NULL NULL NULL no matching row in const table
|
||||||
|
4 UNION t12 system NULL NULL NULL NULL 0 const row not found
|
||||||
|
NULL UNION RESULT <union2,4> ALL NULL NULL NULL NULL NULL
|
||||||
|
DROP TABLE t1;
|
||||||
|
@ -1365,7 +1365,7 @@ drop table t1, t2;
|
|||||||
(select avg(1)) union (select avg(1)) union (select avg(1)) union
|
(select avg(1)) union (select avg(1)) union (select avg(1)) union
|
||||||
(select avg(1)) union (select avg(1)) union (select avg(1));
|
(select avg(1)) union (select avg(1)) union (select avg(1));
|
||||||
avg(1)
|
avg(1)
|
||||||
NULL
|
1.0000
|
||||||
select _utf8'12' union select _latin1'12345';
|
select _utf8'12' union select _latin1'12345';
|
||||||
12
|
12
|
||||||
12
|
12
|
||||||
|
@ -49,7 +49,7 @@ select v1.b from v1;
|
|||||||
ERROR 42S22: Unknown column 'v1.b' in 'field list'
|
ERROR 42S22: Unknown column 'v1.b' in 'field list'
|
||||||
explain extended select c from v1;
|
explain extended select c 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 t1 ALL NULL NULL NULL NULL 5
|
1 SIMPLE t1 ALL NULL NULL NULL NULL 5
|
||||||
Warnings:
|
Warnings:
|
||||||
Note 1003 select (`test`.`t1`.`b` + 1) AS `c` from `test`.`t1`
|
Note 1003 select (`test`.`t1`.`b` + 1) AS `c` from `test`.`t1`
|
||||||
create algorithm=temptable view v2 (c) as select b+1 from t1;
|
create algorithm=temptable view v2 (c) as select b+1 from t1;
|
||||||
@ -83,7 +83,7 @@ c
|
|||||||
12
|
12
|
||||||
explain extended select c from v3;
|
explain extended select c from v3;
|
||||||
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 5
|
1 SIMPLE t1 ALL NULL NULL NULL NULL 5
|
||||||
Warnings:
|
Warnings:
|
||||||
Note 1003 select ((`test`.`t1`.`b` + 1) + 1) AS `c` from `test`.`t1`
|
Note 1003 select ((`test`.`t1`.`b` + 1) + 1) AS `c` from `test`.`t1`
|
||||||
create algorithm=temptable view v4 (c) as select c+1 from v2;
|
create algorithm=temptable view v4 (c) as select c+1 from v2;
|
||||||
@ -376,7 +376,7 @@ c
|
|||||||
30
|
30
|
||||||
explain extended select * from v1;
|
explain extended 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 t1 ALL NULL NULL NULL NULL 5 Using where
|
1 SIMPLE t1 ALL NULL NULL NULL NULL 5 Using where
|
||||||
Warnings:
|
Warnings:
|
||||||
Note 1003 select `test`.`t1`.`b` AS `c` from `test`.`t1` where (`test`.`t1`.`a` < 3)
|
Note 1003 select `test`.`t1`.`b` AS `c` from `test`.`t1` where (`test`.`t1`.`a` < 3)
|
||||||
update v1 set c=c+1;
|
update v1 set c=c+1;
|
||||||
@ -1391,9 +1391,9 @@ a a b
|
|||||||
4 NULL NULL
|
4 NULL NULL
|
||||||
explain extended select * from t3 left join v3 on (t3.a = v3.a);
|
explain extended select * from t3 left join v3 on (t3.a = v3.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 t3 ALL NULL NULL NULL NULL 3
|
1 SIMPLE t3 ALL NULL NULL NULL NULL 3
|
||||||
1 PRIMARY t1 ALL NULL NULL NULL NULL 3
|
1 SIMPLE t1 ALL NULL NULL NULL NULL 3
|
||||||
1 PRIMARY t2 ALL NULL NULL NULL NULL 2
|
1 SIMPLE t2 ALL NULL NULL NULL NULL 2
|
||||||
Warnings:
|
Warnings:
|
||||||
Note 1003 select `test`.`t3`.`a` AS `a`,`test`.`t1`.`a` AS `a`,`test`.`t2`.`a` AS `b` from `test`.`t3` left join (`test`.`t1` left join `test`.`t2` on((`test`.`t1`.`a` = `test`.`t2`.`a`))) on((`test`.`t3`.`a` = `test`.`t1`.`a`)) where 1
|
Note 1003 select `test`.`t3`.`a` AS `a`,`test`.`t1`.`a` AS `a`,`test`.`t2`.`a` AS `b` from `test`.`t3` left join (`test`.`t1` left join `test`.`t2` on((`test`.`t1`.`a` = `test`.`t2`.`a`))) on((`test`.`t3`.`a` = `test`.`t1`.`a`)) where 1
|
||||||
create view v1 (a) as select a from t1;
|
create view v1 (a) as select a from t1;
|
||||||
@ -1406,9 +1406,9 @@ a a b
|
|||||||
4 NULL NULL
|
4 NULL NULL
|
||||||
explain extended select * from t3 left join v4 on (t3.a = v4.a);
|
explain extended select * from t3 left join v4 on (t3.a = v4.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 t3 ALL NULL NULL NULL NULL 3
|
1 SIMPLE t3 ALL NULL NULL NULL NULL 3
|
||||||
1 PRIMARY t1 ALL NULL NULL NULL NULL 3
|
1 SIMPLE t1 ALL NULL NULL NULL NULL 3
|
||||||
1 PRIMARY t2 ALL NULL NULL NULL NULL 2
|
1 SIMPLE t2 ALL NULL NULL NULL NULL 2
|
||||||
Warnings:
|
Warnings:
|
||||||
Note 1003 select `test`.`t3`.`a` AS `a`,`test`.`t1`.`a` AS `a`,`test`.`t2`.`a` AS `b` from `test`.`t3` left join (`test`.`t1` left join (`test`.`t2`) on((`test`.`t1`.`a` = `test`.`t2`.`a`))) on((`test`.`t3`.`a` = `test`.`t1`.`a`)) where 1
|
Note 1003 select `test`.`t3`.`a` AS `a`,`test`.`t1`.`a` AS `a`,`test`.`t2`.`a` AS `b` from `test`.`t3` left join (`test`.`t1` left join (`test`.`t2`) on((`test`.`t1`.`a` = `test`.`t2`.`a`))) on((`test`.`t3`.`a` = `test`.`t1`.`a`)) where 1
|
||||||
prepare stmt1 from "select * from t3 left join v4 on (t3.a = v4.a);";
|
prepare stmt1 from "select * from t3 left join v4 on (t3.a = v4.a);";
|
||||||
@ -2321,12 +2321,12 @@ id select_type table type possible_keys key key_len ref rows Extra
|
|||||||
1 SIMPLE t2 ref a a 10 const,test.t1.b 2 Using where; Using index
|
1 SIMPLE t2 ref a a 10 const,test.t1.b 2 Using where; Using index
|
||||||
EXPLAIN SELECT * FROM v1 WHERE a=1;
|
EXPLAIN SELECT * FROM v1 WHERE a=1;
|
||||||
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 ref a a 5 const 1 Using where; Using index
|
1 SIMPLE t1 ref a a 5 const 1 Using where; Using index
|
||||||
1 PRIMARY t2 ref a a 10 const,test.t1.b 2 Using where; Using index
|
1 SIMPLE t2 ref a a 10 const,test.t1.b 2 Using where; Using index
|
||||||
EXPLAIN SELECT * FROM v2 WHERE a=1;
|
EXPLAIN SELECT * FROM v2 WHERE a=1;
|
||||||
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 ref a a 5 const 1 Using where; Using index
|
1 SIMPLE t1 ref a a 5 const 1 Using where; Using index
|
||||||
1 PRIMARY t3 ALL NULL NULL NULL NULL 3 Using where
|
1 SIMPLE t3 ALL NULL NULL NULL NULL 3 Using where
|
||||||
DROP VIEW v1,v2;
|
DROP VIEW v1,v2;
|
||||||
DROP TABLE t1,t2,t3;
|
DROP TABLE t1,t2,t3;
|
||||||
create table t1 (f1 int);
|
create table t1 (f1 int);
|
||||||
@ -2409,7 +2409,7 @@ insert into t1 values (1),(2);
|
|||||||
create view v1 as select * from t1;
|
create view v1 as select * from t1;
|
||||||
explain select id from v1 order by id;
|
explain select id from v1 order by id;
|
||||||
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 index NULL PRIMARY 4 NULL 2 Using index
|
1 SIMPLE t1 index NULL PRIMARY 4 NULL 2 Using index
|
||||||
drop view v1;
|
drop view v1;
|
||||||
drop table t1;
|
drop table t1;
|
||||||
create table t1(f1 int, f2 int);
|
create table t1(f1 int, f2 int);
|
||||||
@ -2480,7 +2480,7 @@ id select_type table type possible_keys key key_len ref rows Extra
|
|||||||
1 SIMPLE NULL NULL NULL NULL NULL NULL NULL Select tables optimized away
|
1 SIMPLE NULL NULL NULL NULL NULL NULL NULL Select tables optimized away
|
||||||
EXPLAIN SELECT MAX(a) FROM v1;
|
EXPLAIN SELECT MAX(a) 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 Select tables optimized away
|
1 SIMPLE NULL NULL NULL NULL NULL NULL NULL Select tables optimized away
|
||||||
SELECT MIN(a) FROM t1;
|
SELECT MIN(a) FROM t1;
|
||||||
MIN(a)
|
MIN(a)
|
||||||
0
|
0
|
||||||
@ -2492,7 +2492,7 @@ id select_type table type possible_keys key key_len ref rows Extra
|
|||||||
1 SIMPLE NULL NULL NULL NULL NULL NULL NULL Select tables optimized away
|
1 SIMPLE NULL NULL NULL NULL NULL NULL NULL Select tables optimized away
|
||||||
EXPLAIN SELECT MIN(a) FROM v1;
|
EXPLAIN SELECT MIN(a) 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 Select tables optimized away
|
1 SIMPLE NULL NULL NULL NULL NULL NULL NULL Select tables optimized away
|
||||||
DROP VIEW v1;
|
DROP VIEW v1;
|
||||||
DROP TABLE t1;
|
DROP TABLE t1;
|
||||||
CREATE TABLE t1 (x varchar(10));
|
CREATE TABLE t1 (x varchar(10));
|
||||||
@ -2879,3 +2879,22 @@ View Create View
|
|||||||
v1 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v1` AS select `t1`.`f1` AS `f1` from `t1` where (`t1`.`f1` between now() and (now() + interval 1 minute))
|
v1 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v1` AS select `t1`.`f1` AS `f1` from `t1` where (`t1`.`f1` between now() and (now() + interval 1 minute))
|
||||||
drop view v1;
|
drop view v1;
|
||||||
drop table t1;
|
drop table t1;
|
||||||
|
CREATE TABLE t1 (s1 int);
|
||||||
|
CREATE VIEW v1 AS SELECT * FROM t1;
|
||||||
|
EXPLAIN SELECT * FROM t1;
|
||||||
|
id select_type table type possible_keys key key_len ref rows Extra
|
||||||
|
1 SIMPLE t1 system NULL NULL NULL NULL 0 const row not found
|
||||||
|
EXPLAIN SELECT * FROM v1;
|
||||||
|
id select_type table type possible_keys key key_len ref rows Extra
|
||||||
|
1 SIMPLE t1 system NULL NULL NULL NULL 0 const row not found
|
||||||
|
INSERT INTO t1 VALUES (1), (3), (2);
|
||||||
|
EXPLAIN SELECT * FROM t1 t WHERE t.s1+1 < (SELECT MAX(t1.s1) FROM t1);
|
||||||
|
id select_type table type possible_keys key key_len ref rows Extra
|
||||||
|
1 PRIMARY t ALL NULL NULL NULL NULL 3 Using where
|
||||||
|
2 SUBQUERY t1 ALL NULL NULL NULL NULL 3
|
||||||
|
EXPLAIN SELECT * FROM v1 t WHERE t.s1+1 < (SELECT MAX(t1.s1) FROM t1);
|
||||||
|
id select_type table type possible_keys key key_len ref rows Extra
|
||||||
|
1 PRIMARY t1 ALL NULL NULL NULL NULL 3 Using where
|
||||||
|
2 SUBQUERY t1 ALL NULL NULL NULL NULL 3
|
||||||
|
DROP VIEW v1;
|
||||||
|
DROP TABLE t1;
|
||||||
|
@ -103,7 +103,7 @@ ERROR 42000: SHOW VIEW command denied to user 'mysqltest_1'@'localhost' for tabl
|
|||||||
grant select on mysqltest.t1 to mysqltest_1@localhost;
|
grant select on mysqltest.t1 to mysqltest_1@localhost;
|
||||||
explain select c from mysqltest.v1;
|
explain select c from mysqltest.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 t1 system NULL NULL NULL NULL 0 const row not found
|
1 SIMPLE t1 system NULL NULL NULL NULL 0 const row not found
|
||||||
show create view mysqltest.v1;
|
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;
|
||||||
@ -123,7 +123,7 @@ ERROR 42000: SHOW VIEW command denied to user 'mysqltest_1'@'localhost' for tabl
|
|||||||
grant show view on mysqltest.* to mysqltest_1@localhost;
|
grant show view on mysqltest.* to mysqltest_1@localhost;
|
||||||
explain select c from mysqltest.v1;
|
explain select c from mysqltest.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 t1 system NULL NULL NULL NULL 0 const row not found
|
1 SIMPLE t1 system NULL NULL NULL NULL 0 const row not found
|
||||||
show create view mysqltest.v1;
|
show create view mysqltest.v1;
|
||||||
View Create View
|
View Create View
|
||||||
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`
|
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`
|
||||||
@ -136,7 +136,7 @@ View Create View
|
|||||||
v2 CREATE ALGORITHM=TEMPTABLE DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `mysqltest`.`v2` AS select (`mysqltest`.`t1`.`a` + 1) AS `c`,(`mysqltest`.`t1`.`b` + 1) AS `d` from `mysqltest`.`t1`
|
v2 CREATE ALGORITHM=TEMPTABLE DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `mysqltest`.`v2` AS select (`mysqltest`.`t1`.`a` + 1) AS `c`,(`mysqltest`.`t1`.`b` + 1) AS `d` from `mysqltest`.`t1`
|
||||||
explain select c from mysqltest.v3;
|
explain select c from mysqltest.v3;
|
||||||
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 t2 system NULL NULL NULL NULL 0 const row not found
|
1 SIMPLE t2 system NULL NULL NULL NULL 0 const row not found
|
||||||
show create view mysqltest.v3;
|
show create view mysqltest.v3;
|
||||||
View Create View
|
View Create View
|
||||||
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`
|
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`
|
||||||
|
@ -674,4 +674,10 @@ create table t1(f1 varchar(800) binary not null, key(f1)) engine = innodb
|
|||||||
insert into t1 values('aaa');
|
insert into t1 values('aaa');
|
||||||
drop table t1;
|
drop table t1;
|
||||||
|
|
||||||
|
#
|
||||||
|
# Bug#21772: can not name a column 'upgrade' when create a table
|
||||||
|
#
|
||||||
|
create table t1 (upgrade int);
|
||||||
|
drop table t1;
|
||||||
|
|
||||||
# End of 5.0 tests
|
# End of 5.0 tests
|
||||||
|
@ -153,6 +153,16 @@ DELETE FROM t1 WHERE t1.a > 0 ORDER BY t1.a LIMIT 1;
|
|||||||
SELECT * FROM t1;
|
SELECT * FROM t1;
|
||||||
DROP TABLE t1;
|
DROP TABLE t1;
|
||||||
|
|
||||||
|
#
|
||||||
|
# Bug #21392: multi-table delete with alias table name fails with
|
||||||
|
# 1003: Incorrect table name
|
||||||
|
#
|
||||||
|
|
||||||
|
create table t1 (a int);
|
||||||
|
delete `4.t1` from t1 as `4.t1` where `4.t1`.a = 5;
|
||||||
|
delete FROM `4.t1` USING t1 as `4.t1` where `4.t1`.a = 5;
|
||||||
|
drop table t1;
|
||||||
|
|
||||||
# End of 4.1 tests
|
# End of 4.1 tests
|
||||||
|
|
||||||
#
|
#
|
||||||
|
@ -566,6 +566,19 @@ INSERT INTO t1 VALUES
|
|||||||
SELECT MAX(b) FROM t1;
|
SELECT MAX(b) FROM t1;
|
||||||
EXPLAIN SELECT MAX(b) FROM t1;
|
EXPLAIN SELECT MAX(b) FROM t1;
|
||||||
DROP TABLE t1;
|
DROP TABLE t1;
|
||||||
|
#
|
||||||
|
# Bug #16792 query with subselect, join, and group not returning proper values
|
||||||
|
#
|
||||||
|
CREATE TABLE t1 (a INT, b INT);
|
||||||
|
INSERT INTO t1 VALUES (1,1),(1,2),(2,3);
|
||||||
|
|
||||||
|
SELECT (SELECT COUNT(DISTINCT t1.b)) FROM t1 GROUP BY t1.a;
|
||||||
|
SELECT (SELECT COUNT(DISTINCT 12)) FROM t1 GROUP BY t1.a;
|
||||||
|
# an attempt to test all aggregate function with no table.
|
||||||
|
SELECT AVG(2), BIT_AND(2), BIT_OR(2), BIT_XOR(2), COUNT(*), COUNT(12),
|
||||||
|
COUNT(DISTINCT 12), MIN(2),MAX(2),STD(2), VARIANCE(2),SUM(2),
|
||||||
|
GROUP_CONCAT(2),GROUP_CONCAT(DISTINCT 2);
|
||||||
|
DROP TABLE t1;
|
||||||
|
|
||||||
# End of 4.1 tests
|
# End of 4.1 tests
|
||||||
|
|
||||||
|
@ -753,4 +753,31 @@ select cast(rtrim(ltrim(' 20.06 ')) as decimal(19,2));
|
|||||||
select conv("18383815659218730760",10,10) + 0;
|
select conv("18383815659218730760",10,10) + 0;
|
||||||
select "18383815659218730760" + 0;
|
select "18383815659218730760" + 0;
|
||||||
|
|
||||||
|
#
|
||||||
|
# Bug #21698: substitution of a string field for a constant under a function
|
||||||
|
#
|
||||||
|
|
||||||
|
CREATE TABLE t1 (code varchar(10));
|
||||||
|
INSERT INTO t1 VALUES ('a12'), ('A12'), ('a13');
|
||||||
|
|
||||||
|
SELECT ASCII(code), code FROM t1 WHERE code='A12';
|
||||||
|
SELECT ASCII(code), code FROM t1 WHERE code='A12' AND ASCII(code)=65;
|
||||||
|
|
||||||
|
INSERT INTO t1 VALUES ('a12 '), ('A12 ');
|
||||||
|
|
||||||
|
SELECT LENGTH(code), code FROM t1 WHERE code='A12';
|
||||||
|
SELECT LENGTH(code), code FROM t1 WHERE code='A12' AND LENGTH(code)=5;
|
||||||
|
|
||||||
|
ALTER TABLE t1 ADD INDEX (code);
|
||||||
|
CREATE TABLE t2 (id varchar(10) PRIMARY KEY);
|
||||||
|
INSERT INTO t2 VALUES ('a11'), ('a12'), ('a13'), ('a14');
|
||||||
|
|
||||||
|
SELECT * FROM t1 INNER JOIN t2 ON t1.code=t2.id
|
||||||
|
WHERE t2.id='a12' AND (LENGTH(code)=5 OR code < 'a00');
|
||||||
|
EXPLAIN EXTENDED
|
||||||
|
SELECT * FROM t1 INNER JOIN t2 ON code=id
|
||||||
|
WHERE id='a12' AND (LENGTH(code)=5 OR code < 'a00');
|
||||||
|
|
||||||
|
DROP TABLE t1,t2;
|
||||||
|
|
||||||
--echo End of 5.0 tests
|
--echo End of 5.0 tests
|
||||||
|
@ -709,5 +709,34 @@ EXPLAIN SELECT * FROM t1 WHERE 0 NOT BETWEEN b AND c;
|
|||||||
|
|
||||||
DROP TABLE t1;
|
DROP TABLE t1;
|
||||||
|
|
||||||
|
#
|
||||||
|
# Bug #16249: different results for a range with an without index
|
||||||
|
# when a range condition use an invalid datetime constant
|
||||||
|
#
|
||||||
|
|
||||||
|
CREATE TABLE t1 (
|
||||||
|
item char(20) NOT NULL default '',
|
||||||
|
started datetime NOT NULL default '0000-00-00 00:00:00',
|
||||||
|
price decimal(16,3) NOT NULL default '0.000',
|
||||||
|
PRIMARY KEY (item,started)
|
||||||
|
) ENGINE=MyISAM;
|
||||||
|
|
||||||
|
INSERT INTO t1 VALUES
|
||||||
|
('A1','2005-11-01 08:00:00',1000),
|
||||||
|
('A1','2005-11-15 00:00:00',2000),
|
||||||
|
('A1','2005-12-12 08:00:00',3000),
|
||||||
|
('A2','2005-12-01 08:00:00',1000);
|
||||||
|
|
||||||
|
EXPLAIN SELECT * FROM t1 WHERE item='A1' AND started<='2005-12-01 24:00:00';
|
||||||
|
SELECT * FROM t1 WHERE item='A1' AND started<='2005-12-01 24:00:00';
|
||||||
|
SELECT * FROM t1 WHERE item='A1' AND started<='2005-12-02 00:00:00';
|
||||||
|
|
||||||
|
DROP INDEX `PRIMARY` ON t1;
|
||||||
|
|
||||||
|
EXPLAIN SELECT * FROM t1 WHERE item='A1' AND started<='2005-12-01 24:00:00';
|
||||||
|
SELECT * FROM t1 WHERE item='A1' AND started<='2005-12-01 24:00:00';
|
||||||
|
SELECT * FROM t1 WHERE item='A1' AND started<='2005-12-02 00:00:00';
|
||||||
|
|
||||||
|
DROP TABLE t1;
|
||||||
|
|
||||||
# End of 5.0 tests
|
# End of 5.0 tests
|
||||||
|
@ -92,3 +92,50 @@ SELECT ROW(NULL,10) <=> ROW(3,NULL);
|
|||||||
#
|
#
|
||||||
SELECT ROW(1,1,1) = ROW(1,1,1) as `1`, ROW(1,1,1) = ROW(1,2,1) as `0`, ROW(1,NULL,1) = ROW(2,2,1) as `0`, ROW(1,NULL,1) = ROW(1,2,2) as `0`, ROW(1,NULL,1) = ROW(1,2,1) as `null` ;
|
SELECT ROW(1,1,1) = ROW(1,1,1) as `1`, ROW(1,1,1) = ROW(1,2,1) as `0`, ROW(1,NULL,1) = ROW(2,2,1) as `0`, ROW(1,NULL,1) = ROW(1,2,2) as `0`, ROW(1,NULL,1) = ROW(1,2,1) as `null` ;
|
||||||
select row(NULL,1)=(2,0);
|
select row(NULL,1)=(2,0);
|
||||||
|
|
||||||
|
#
|
||||||
|
# Bug #16081: row equalities are to be used for query optimizations
|
||||||
|
#
|
||||||
|
|
||||||
|
CREATE TABLE t1 (a int, b int, PRIMARY KEY (a,b));
|
||||||
|
INSERT INTO t1 VALUES (1,1), (2,1), (3,1), (1,2), (3,2), (3,3);
|
||||||
|
|
||||||
|
EXPLAIN SELECT * FROM t1 WHERE a=3 AND b=2;
|
||||||
|
EXPLAIN SELECT * FROM t1 WHERE (a,b)=(3,2);
|
||||||
|
SELECT * FROM t1 WHERE a=3 and b=2;
|
||||||
|
SELECT * FROM t1 WHERE (a,b)=(3,2);
|
||||||
|
|
||||||
|
CREATE TABLE t2 (a int, b int, c int, PRIMARY KEY (a,b,c));
|
||||||
|
INSERT INTO t2 VALUES
|
||||||
|
(1,1,2), (3,1,3), (1,2,2), (4,4,2),
|
||||||
|
(1,1,1), (3,1,1), (1,2,1);
|
||||||
|
|
||||||
|
EXPLAIN SELECT * FROM t1,t2 WHERE t1.a=t2.a AND t1.b=t2.b;
|
||||||
|
EXPLAIN SELECT * FROM t1,t2 WHERE (t1.a,t1.b)=(t2.a,t2.b);
|
||||||
|
SELECT * FROM t1,t2 WHERE t1.a=t2.a and t1.b=t2.b;
|
||||||
|
SELECT * FROM t1,t2 WHERE (t1.a,t1.b)=(t2.a,t2.b);
|
||||||
|
|
||||||
|
EXPLAIN SELECT * FROM t1,t2 WHERE t1.a=t2.a AND t1.b=2;
|
||||||
|
EXPLAIN SELECT * FROM t1,t2 WHERE (t1.a,t1.b)=(t2.a,2);
|
||||||
|
SELECT * FROM t1,t2 WHERE t1.a=1 and t1.b=t2.b;
|
||||||
|
SELECT * FROM t1,t2 WHERE (t1.a,t1.b)=(t2.a,2);
|
||||||
|
|
||||||
|
EXPLAIN EXTENDED SELECT * FROM t1,t2 WHERE (t1.a,t1.b)=(t2.a,t2.b+1);
|
||||||
|
SELECT * FROM t1,t2 WHERE (t1.a,t1.b)=(t2.a,t2.b+1);
|
||||||
|
|
||||||
|
EXPLAIN EXTENDED SELECT * FROM t1,t2 WHERE (t1.a-1,t1.b)=(t2.a-1,t2.b+1);
|
||||||
|
SELECT * FROM t1,t2 WHERE (t1.a-1,t1.b)=(t2.a-1,t2.b+1);
|
||||||
|
|
||||||
|
EXPLAIN SELECT * FROM t2 WHERE a=3 AND b=2;
|
||||||
|
EXPLAIN SELECT * FROM t2 WHERE (a,b)=(3,2);
|
||||||
|
SELECT * FROM t2 WHERE a=3 and b=2;
|
||||||
|
SELECT * FROM t2 WHERE (a,b)=(3,2);
|
||||||
|
|
||||||
|
EXPLAIN SELECT * FROM t1,t2 WHERE t2.a=t1.a AND t2.b=2 AND t2.c=1;
|
||||||
|
EXPLAIN EXTENDED SELECT * FROM t1,t2 WHERE (t2.a,(t2.b,t2.c))=(t1.a,(2,1));
|
||||||
|
SELECT * FROM t1,t2 WHERE (t2.a,(t2.b,t2.c))=(t1.a,(2,1));
|
||||||
|
|
||||||
|
EXPLAIN EXTENDED SELECT * FROM t1,t2 WHERE t2.a=t1.a AND (t2.b,t2.c)=(2,1);
|
||||||
|
SELECT * FROM t1,t2 WHERE t2.a=t1.a AND (t2.b,t2.c)=(2,1);
|
||||||
|
|
||||||
|
DROP TABLE t1,t2;
|
||||||
|
@ -2280,3 +2280,29 @@ SELECT * FROM t1,t2
|
|||||||
ORDER BY t1.t DESC LIMIT 1);
|
ORDER BY t1.t DESC LIMIT 1);
|
||||||
|
|
||||||
DROP TABLE t1, t2;
|
DROP TABLE t1, t2;
|
||||||
|
|
||||||
|
#
|
||||||
|
# Bug#14654 : Cannot select from the same table twice within a UNION
|
||||||
|
# statement
|
||||||
|
#
|
||||||
|
CREATE TABLE t1 (i INT);
|
||||||
|
|
||||||
|
(SELECT i FROM t1) UNION (SELECT i FROM t1);
|
||||||
|
SELECT sql_no_cache * FROM t1 WHERE NOT EXISTS
|
||||||
|
(
|
||||||
|
(SELECT i FROM t1) UNION
|
||||||
|
(SELECT i FROM t1)
|
||||||
|
);
|
||||||
|
|
||||||
|
SELECT * FROM t1
|
||||||
|
WHERE NOT EXISTS (((SELECT i FROM t1) UNION (SELECT i FROM t1)));
|
||||||
|
|
||||||
|
#TODO:not supported
|
||||||
|
--error 1064
|
||||||
|
explain select ((select t11.i from t1 t11) union (select t12.i from t1 t12))
|
||||||
|
from t1;
|
||||||
|
#supported
|
||||||
|
explain select * from t1 where not exists
|
||||||
|
((select t11.i from t1 t11) union (select t12.i from t1 t12));
|
||||||
|
|
||||||
|
DROP TABLE t1;
|
||||||
|
@ -2760,3 +2760,21 @@ create view v1 as select * from t1 where f1 between now() and now() + interval 1
|
|||||||
show create view v1;
|
show create view v1;
|
||||||
drop view v1;
|
drop view v1;
|
||||||
drop table t1;
|
drop table t1;
|
||||||
|
|
||||||
|
#
|
||||||
|
# Bug #5500: wrong select_type in EXPLAIN output for queries over views
|
||||||
|
#
|
||||||
|
|
||||||
|
CREATE TABLE t1 (s1 int);
|
||||||
|
CREATE VIEW v1 AS SELECT * FROM t1;
|
||||||
|
|
||||||
|
EXPLAIN SELECT * FROM t1;
|
||||||
|
EXPLAIN SELECT * FROM v1;
|
||||||
|
|
||||||
|
INSERT INTO t1 VALUES (1), (3), (2);
|
||||||
|
|
||||||
|
EXPLAIN SELECT * FROM t1 t WHERE t.s1+1 < (SELECT MAX(t1.s1) FROM t1);
|
||||||
|
EXPLAIN SELECT * FROM v1 t WHERE t.s1+1 < (SELECT MAX(t1.s1) FROM t1);
|
||||||
|
|
||||||
|
DROP VIEW v1;
|
||||||
|
DROP TABLE t1;
|
||||||
|
41
sql/item.cc
41
sql/item.cc
@ -3745,14 +3745,49 @@ Item_equal *Item_field::find_item_equal(COND_EQUAL *cond_equal)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
Check whether a field can be substituted by an equal item
|
||||||
|
|
||||||
|
SYNOPSIS
|
||||||
|
equal_fields_propagator()
|
||||||
|
arg - *arg != NULL <-> the field is in the context where
|
||||||
|
substitution for an equal item is valid
|
||||||
|
|
||||||
|
DESCRIPTION
|
||||||
|
The function checks whether a substitution of the field
|
||||||
|
occurrence for an equal item is valid.
|
||||||
|
|
||||||
|
NOTES
|
||||||
|
The following statement is not always true:
|
||||||
|
x=y => F(x)=F(x/y).
|
||||||
|
This means substitution of an item for an equal item not always
|
||||||
|
yields an equavalent condition.
|
||||||
|
Here's an example:
|
||||||
|
'a'='a '
|
||||||
|
(LENGTH('a')=1) != (LENGTH('a ')=2)
|
||||||
|
Such a substitution is surely valid if either the substituted
|
||||||
|
field is not of a STRING type or if it is an argument of
|
||||||
|
a comparison predicate.
|
||||||
|
|
||||||
|
RETURN
|
||||||
|
TRUE substitution is valid
|
||||||
|
FALSE otherwise
|
||||||
|
*/
|
||||||
|
|
||||||
|
bool Item_field::subst_argument_checker(byte **arg)
|
||||||
|
{
|
||||||
|
return (result_type() != STRING_RESULT) || (*arg);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Set a pointer to the multiple equality the field reference belongs to
|
Set a pointer to the multiple equality the field reference belongs to
|
||||||
(if any)
|
(if any)
|
||||||
|
|
||||||
SYNOPSIS
|
SYNOPSIS
|
||||||
equal_fields_propagator()
|
equal_fields_propagator()
|
||||||
arg - reference to list of multiple equalities where
|
arg - reference to list of multiple equalities where
|
||||||
the field (this object) is to be looked for
|
the field (this object) is to be looked for
|
||||||
|
|
||||||
DESCRIPTION
|
DESCRIPTION
|
||||||
The function looks for a multiple equality containing the field item
|
The function looks for a multiple equality containing the field item
|
||||||
@ -3764,7 +3799,7 @@ Item_equal *Item_field::find_item_equal(COND_EQUAL *cond_equal)
|
|||||||
|
|
||||||
NOTES
|
NOTES
|
||||||
This function is supposed to be called as a callback parameter in calls
|
This function is supposed to be called as a callback parameter in calls
|
||||||
of the transform method.
|
of the compile method.
|
||||||
|
|
||||||
RETURN VALUES
|
RETURN VALUES
|
||||||
pointer to the replacing constant item, if the field item was substituted
|
pointer to the replacing constant item, if the field item was substituted
|
||||||
|
45
sql/item.h
45
sql/item.h
@ -410,7 +410,19 @@ public:
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
typedef bool (Item::*Item_processor)(byte *arg);
|
typedef bool (Item::*Item_processor) (byte *arg);
|
||||||
|
/*
|
||||||
|
Analyzer function
|
||||||
|
SYNOPSIS
|
||||||
|
argp in/out IN: Analysis parameter
|
||||||
|
OUT: Parameter to be passed to the transformer
|
||||||
|
|
||||||
|
RETURN
|
||||||
|
TRUE Invoke the transformer
|
||||||
|
FALSE Don't do it
|
||||||
|
|
||||||
|
*/
|
||||||
|
typedef bool (Item::*Item_analyzer) (byte **argp);
|
||||||
typedef Item* (Item::*Item_transformer) (byte *arg);
|
typedef Item* (Item::*Item_transformer) (byte *arg);
|
||||||
typedef void (*Cond_traverser) (const Item *item, void *arg);
|
typedef void (*Cond_traverser) (const Item *item, void *arg);
|
||||||
|
|
||||||
@ -739,6 +751,30 @@ public:
|
|||||||
return (this->*transformer)(arg);
|
return (this->*transformer)(arg);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
This function performs a generic "compilation" of the Item tree.
|
||||||
|
The process of compilation is assumed to go as follows:
|
||||||
|
|
||||||
|
compile()
|
||||||
|
{
|
||||||
|
if (this->*some_analyzer(...))
|
||||||
|
{
|
||||||
|
compile children if any;
|
||||||
|
this->*some_transformer(...);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
i.e. analysis is performed top-down while transformation is done
|
||||||
|
bottom-up.
|
||||||
|
*/
|
||||||
|
virtual Item* compile(Item_analyzer analyzer, byte **arg_p,
|
||||||
|
Item_transformer transformer, byte *arg_t)
|
||||||
|
{
|
||||||
|
if ((this->*analyzer) (arg_p))
|
||||||
|
return ((this->*transformer) (arg_t));
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
virtual void traverse_cond(Cond_traverser traverser,
|
virtual void traverse_cond(Cond_traverser traverser,
|
||||||
void *arg, traverse_order order)
|
void *arg, traverse_order order)
|
||||||
{
|
{
|
||||||
@ -753,6 +789,12 @@ public:
|
|||||||
virtual bool change_context_processor(byte *context) { return 0; }
|
virtual bool change_context_processor(byte *context) { return 0; }
|
||||||
virtual bool reset_query_id_processor(byte *query_id) { return 0; }
|
virtual bool reset_query_id_processor(byte *query_id) { return 0; }
|
||||||
virtual bool is_expensive_processor(byte *arg) { return 0; }
|
virtual bool is_expensive_processor(byte *arg) { return 0; }
|
||||||
|
virtual bool subst_argument_checker(byte **arg)
|
||||||
|
{
|
||||||
|
if (*arg)
|
||||||
|
*arg= NULL;
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
virtual Item *equal_fields_propagator(byte * arg) { return this; }
|
virtual Item *equal_fields_propagator(byte * arg) { return this; }
|
||||||
virtual Item *set_no_const_sub(byte *arg) { return this; }
|
virtual Item *set_no_const_sub(byte *arg) { return this; }
|
||||||
@ -1254,6 +1296,7 @@ public:
|
|||||||
return field->can_be_compared_as_longlong();
|
return field->can_be_compared_as_longlong();
|
||||||
}
|
}
|
||||||
Item_equal *find_item_equal(COND_EQUAL *cond_equal);
|
Item_equal *find_item_equal(COND_EQUAL *cond_equal);
|
||||||
|
bool subst_argument_checker(byte **arg);
|
||||||
Item *equal_fields_propagator(byte *arg);
|
Item *equal_fields_propagator(byte *arg);
|
||||||
Item *set_no_const_sub(byte *arg);
|
Item *set_no_const_sub(byte *arg);
|
||||||
Item *replace_equal_field(byte *arg);
|
Item *replace_equal_field(byte *arg);
|
||||||
|
@ -2747,16 +2747,16 @@ bool Item_cond::walk(Item_processor processor, byte *arg)
|
|||||||
|
|
||||||
SYNOPSIS
|
SYNOPSIS
|
||||||
transform()
|
transform()
|
||||||
transformer the transformer callback function to be applied to the nodes
|
transformer the transformer callback function to be applied to the nodes
|
||||||
of the tree of the object
|
of the tree of the object
|
||||||
arg parameter to be passed to the transformer
|
arg parameter to be passed to the transformer
|
||||||
|
|
||||||
DESCRIPTION
|
DESCRIPTION
|
||||||
The function recursively applies the transform method with the
|
The function recursively applies the transform method to each
|
||||||
same transformer to each member item of the condition list.
|
member item of the condition list.
|
||||||
If the call of the method for a member item returns a new item
|
If the call of the method for a member item returns a new item
|
||||||
the old item is substituted for a new one.
|
the old item is substituted for a new one.
|
||||||
After this the transform method is applied to the root node
|
After this the transformer is applied to the root node
|
||||||
of the Item_cond object.
|
of the Item_cond object.
|
||||||
|
|
||||||
RETURN VALUES
|
RETURN VALUES
|
||||||
@ -2778,6 +2778,55 @@ Item *Item_cond::transform(Item_transformer transformer, byte *arg)
|
|||||||
return Item_func::transform(transformer, arg);
|
return Item_func::transform(transformer, arg);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
Compile Item_cond object with a processor and a transformer callback functions
|
||||||
|
|
||||||
|
SYNOPSIS
|
||||||
|
compile()
|
||||||
|
analyzer the analyzer callback function to be applied to the nodes
|
||||||
|
of the tree of the object
|
||||||
|
arg_p in/out parameter to be passed to the analyzer
|
||||||
|
transformer the transformer callback function to be applied to the nodes
|
||||||
|
of the tree of the object
|
||||||
|
arg_t parameter to be passed to the transformer
|
||||||
|
|
||||||
|
DESCRIPTION
|
||||||
|
First the function applies the analyzer to the root node of
|
||||||
|
the Item_func object. Then if the analyzer succeeeds (returns TRUE)
|
||||||
|
the function recursively applies the compile method to member
|
||||||
|
item of the condition list.
|
||||||
|
If the call of the method for a member item returns a new item
|
||||||
|
the old item is substituted for a new one.
|
||||||
|
After this the transformer is applied to the root node
|
||||||
|
of the Item_cond object.
|
||||||
|
|
||||||
|
RETURN VALUES
|
||||||
|
Item returned as the result of transformation of the root node
|
||||||
|
*/
|
||||||
|
|
||||||
|
Item *Item_cond::compile(Item_analyzer analyzer, byte **arg_p,
|
||||||
|
Item_transformer transformer, byte *arg_t)
|
||||||
|
{
|
||||||
|
if (!(this->*analyzer)(arg_p))
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
List_iterator<Item> li(list);
|
||||||
|
Item *item;
|
||||||
|
while ((item= li++))
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
The same parameter value of arg_p must be passed
|
||||||
|
to analyze any argument of the condition formula.
|
||||||
|
*/
|
||||||
|
byte *arg_v= *arg_p;
|
||||||
|
Item *new_item= item->compile(analyzer, &arg_v, transformer, arg_t);
|
||||||
|
if (new_item && new_item != item)
|
||||||
|
li.replace(new_item);
|
||||||
|
}
|
||||||
|
return Item_func::transform(transformer, arg_t);
|
||||||
|
}
|
||||||
|
|
||||||
void Item_cond::traverse_cond(Cond_traverser traverser,
|
void Item_cond::traverse_cond(Cond_traverser traverser,
|
||||||
void *arg, traverse_order order)
|
void *arg, traverse_order order)
|
||||||
{
|
{
|
||||||
|
@ -240,6 +240,7 @@ public:
|
|||||||
}
|
}
|
||||||
Item *neg_transformer(THD *thd);
|
Item *neg_transformer(THD *thd);
|
||||||
virtual Item *negated_item();
|
virtual Item *negated_item();
|
||||||
|
bool subst_argument_checker(byte **arg) { return TRUE; }
|
||||||
};
|
};
|
||||||
|
|
||||||
class Item_func_not :public Item_bool_func
|
class Item_func_not :public Item_bool_func
|
||||||
@ -1171,6 +1172,9 @@ public:
|
|||||||
Item *transform(Item_transformer transformer, byte *arg);
|
Item *transform(Item_transformer transformer, byte *arg);
|
||||||
void traverse_cond(Cond_traverser, void *arg, traverse_order order);
|
void traverse_cond(Cond_traverser, void *arg, traverse_order order);
|
||||||
void neg_arguments(THD *thd);
|
void neg_arguments(THD *thd);
|
||||||
|
bool subst_argument_checker(byte **arg) { return TRUE; }
|
||||||
|
Item *compile(Item_analyzer analyzer, byte **arg_p,
|
||||||
|
Item_transformer transformer, byte *arg_t);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -234,22 +234,21 @@ void Item_func::traverse_cond(Cond_traverser traverser,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Transform an Item_func object with a transformer callback function
|
Transform an Item_func object with a transformer callback function
|
||||||
|
|
||||||
SYNOPSIS
|
SYNOPSIS
|
||||||
transform()
|
transform()
|
||||||
transformer the transformer callback function to be applied to the nodes
|
transformer the transformer callback function to be applied to the nodes
|
||||||
of the tree of the object
|
of the tree of the object
|
||||||
argument parameter to be passed to the transformer
|
argument parameter to be passed to the transformer
|
||||||
|
|
||||||
DESCRIPTION
|
DESCRIPTION
|
||||||
The function recursively applies the transform method with the
|
The function recursively applies the transform method to each
|
||||||
same transformer to each argument the function.
|
argument of the Item_func node.
|
||||||
If the call of the method for a member item returns a new item
|
If the call of the method for an argument item returns a new item
|
||||||
the old item is substituted for a new one.
|
the old item is substituted for a new one.
|
||||||
After this the transform method is applied to the root node
|
After this the transformer is applied to the root node
|
||||||
of the Item_func object.
|
of the Item_func object.
|
||||||
|
|
||||||
RETURN VALUES
|
RETURN VALUES
|
||||||
@ -274,6 +273,55 @@ Item *Item_func::transform(Item_transformer transformer, byte *argument)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
Compile Item_func object with a processor and a transformer callback functions
|
||||||
|
|
||||||
|
SYNOPSIS
|
||||||
|
compile()
|
||||||
|
analyzer the analyzer callback function to be applied to the nodes
|
||||||
|
of the tree of the object
|
||||||
|
arg_p in/out parameter to be passed to the processor
|
||||||
|
transformer the transformer callback function to be applied to the nodes
|
||||||
|
of the tree of the object
|
||||||
|
arg_t parameter to be passed to the transformer
|
||||||
|
|
||||||
|
DESCRIPTION
|
||||||
|
First the function applies the analyzer to the root node of
|
||||||
|
the Item_func object. Then if the analizer succeeeds (returns TRUE)
|
||||||
|
the function recursively applies the compile method to each argument
|
||||||
|
of the Item_func node.
|
||||||
|
If the call of the method for an argument item returns a new item
|
||||||
|
the old item is substituted for a new one.
|
||||||
|
After this the transformer is applied to the root node
|
||||||
|
of the Item_func object.
|
||||||
|
|
||||||
|
RETURN VALUES
|
||||||
|
Item returned as the result of transformation of the root node
|
||||||
|
*/
|
||||||
|
|
||||||
|
Item *Item_func::compile(Item_analyzer analyzer, byte **arg_p,
|
||||||
|
Item_transformer transformer, byte *arg_t)
|
||||||
|
{
|
||||||
|
if (!(this->*analyzer)(arg_p))
|
||||||
|
return 0;
|
||||||
|
if (arg_count)
|
||||||
|
{
|
||||||
|
Item **arg,**arg_end;
|
||||||
|
for (arg= args, arg_end= args+arg_count; arg != arg_end; arg++)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
The same parameter value of arg_p must be passed
|
||||||
|
to analyze any argument of the condition formula.
|
||||||
|
*/
|
||||||
|
byte *arg_v= *arg_p;
|
||||||
|
Item *new_item= (*arg)->compile(analyzer, &arg_v, transformer, arg_t);
|
||||||
|
if (new_item && *arg != new_item)
|
||||||
|
current_thd->change_item_tree(arg, new_item);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return (this->*transformer)(arg_t);
|
||||||
|
}
|
||||||
|
|
||||||
/* See comments in Item_cmp_func::split_sum_func() */
|
/* See comments in Item_cmp_func::split_sum_func() */
|
||||||
|
|
||||||
void Item_func::split_sum_func(THD *thd, Item **ref_pointer_array,
|
void Item_func::split_sum_func(THD *thd, Item **ref_pointer_array,
|
||||||
|
@ -187,6 +187,8 @@ public:
|
|||||||
}
|
}
|
||||||
bool walk(Item_processor processor, byte *arg);
|
bool walk(Item_processor processor, byte *arg);
|
||||||
Item *transform(Item_transformer transformer, byte *arg);
|
Item *transform(Item_transformer transformer, byte *arg);
|
||||||
|
Item* compile(Item_analyzer analyzer, byte **arg_p,
|
||||||
|
Item_transformer transformer, byte *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 is_expensive_processor(byte *arg);
|
bool is_expensive_processor(byte *arg);
|
||||||
|
@ -290,7 +290,9 @@ Item_sum::Item_sum(THD *thd, Item_sum *item):
|
|||||||
|
|
||||||
void Item_sum::mark_as_sum_func()
|
void Item_sum::mark_as_sum_func()
|
||||||
{
|
{
|
||||||
current_thd->lex->current_select->with_sum_func= 1;
|
SELECT_LEX *cur_select= current_thd->lex->current_select;
|
||||||
|
cur_select->n_sum_items++;
|
||||||
|
cur_select->with_sum_func= 1;
|
||||||
with_sum_func= 1;
|
with_sum_func= 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -425,6 +425,7 @@ void view_store_options(THD *thd, st_table_list *table, String *buff);
|
|||||||
#define TL_OPTION_UPDATING 1
|
#define TL_OPTION_UPDATING 1
|
||||||
#define TL_OPTION_FORCE_INDEX 2
|
#define TL_OPTION_FORCE_INDEX 2
|
||||||
#define TL_OPTION_IGNORE_LEAVES 4
|
#define TL_OPTION_IGNORE_LEAVES 4
|
||||||
|
#define TL_OPTION_ALIAS 8
|
||||||
|
|
||||||
/* Some portable defines */
|
/* Some portable defines */
|
||||||
|
|
||||||
|
@ -4129,6 +4129,7 @@ get_mm_leaf(PARAM *param, COND *conf_func, Field *field, KEY_PART *key_part,
|
|||||||
MEM_ROOT *alloc= param->mem_root;
|
MEM_ROOT *alloc= param->mem_root;
|
||||||
char *str;
|
char *str;
|
||||||
ulong orig_sql_mode;
|
ulong orig_sql_mode;
|
||||||
|
int err;
|
||||||
DBUG_ENTER("get_mm_leaf");
|
DBUG_ENTER("get_mm_leaf");
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -4280,7 +4281,13 @@ get_mm_leaf(PARAM *param, COND *conf_func, Field *field, KEY_PART *key_part,
|
|||||||
(field->type() == FIELD_TYPE_DATE ||
|
(field->type() == FIELD_TYPE_DATE ||
|
||||||
field->type() == FIELD_TYPE_DATETIME))
|
field->type() == FIELD_TYPE_DATETIME))
|
||||||
field->table->in_use->variables.sql_mode|= MODE_INVALID_DATES;
|
field->table->in_use->variables.sql_mode|= MODE_INVALID_DATES;
|
||||||
if (value->save_in_field_no_warnings(field, 1) < 0)
|
err= value->save_in_field_no_warnings(field, 1);
|
||||||
|
if (err > 0 && field->cmp_type() != value->result_type())
|
||||||
|
{
|
||||||
|
tree= 0;
|
||||||
|
goto end;
|
||||||
|
}
|
||||||
|
if (err < 0)
|
||||||
{
|
{
|
||||||
field->table->in_use->variables.sql_mode= orig_sql_mode;
|
field->table->in_use->variables.sql_mode= orig_sql_mode;
|
||||||
/* This happens when we try to insert a NULL field in a not null column */
|
/* This happens when we try to insert a NULL field in a not null column */
|
||||||
|
@ -191,7 +191,7 @@ int opt_sum_query(TABLE_LIST *tables, List<Item> &all_fields,COND *conds)
|
|||||||
Type of range for the key part for this field will be
|
Type of range for the key part for this field will be
|
||||||
returned in range_fl.
|
returned in range_fl.
|
||||||
*/
|
*/
|
||||||
if ((outer_tables & table->map) ||
|
if (table->file->inited || (outer_tables & table->map) ||
|
||||||
!find_key_for_maxmin(0, &ref, item_field->field, conds,
|
!find_key_for_maxmin(0, &ref, item_field->field, conds,
|
||||||
&range_fl, &prefix_len))
|
&range_fl, &prefix_len))
|
||||||
{
|
{
|
||||||
@ -278,7 +278,7 @@ int opt_sum_query(TABLE_LIST *tables, List<Item> &all_fields,COND *conds)
|
|||||||
Type of range for the key part for this field will be
|
Type of range for the key part for this field will be
|
||||||
returned in range_fl.
|
returned in range_fl.
|
||||||
*/
|
*/
|
||||||
if ((outer_tables & table->map) ||
|
if (table->file->inited || (outer_tables & table->map) ||
|
||||||
!find_key_for_maxmin(1, &ref, item_field->field, conds,
|
!find_key_for_maxmin(1, &ref, item_field->field, conds,
|
||||||
&range_fl, &prefix_len))
|
&range_fl, &prefix_len))
|
||||||
{
|
{
|
||||||
|
@ -1521,10 +1521,10 @@ bool st_select_lex::setup_ref_array(THD *thd, uint order_group_num)
|
|||||||
*/
|
*/
|
||||||
Query_arena *arena= thd->stmt_arena;
|
Query_arena *arena= thd->stmt_arena;
|
||||||
return (ref_pointer_array=
|
return (ref_pointer_array=
|
||||||
(Item **)arena->alloc(sizeof(Item*) *
|
(Item **)arena->alloc(sizeof(Item*) * (n_child_sum_items +
|
||||||
(item_list.elements +
|
item_list.elements +
|
||||||
select_n_having_items +
|
select_n_having_items +
|
||||||
order_group_num)* 5)) == 0;
|
order_group_num)*5)) == 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -548,6 +548,12 @@ public:
|
|||||||
bool braces; /* SELECT ... UNION (SELECT ... ) <- this braces */
|
bool braces; /* SELECT ... UNION (SELECT ... ) <- this braces */
|
||||||
/* TRUE when having fix field called in processing of this SELECT */
|
/* TRUE when having fix field called in processing of this SELECT */
|
||||||
bool having_fix_field;
|
bool having_fix_field;
|
||||||
|
|
||||||
|
/* Number of Item_sum-derived objects in this SELECT */
|
||||||
|
uint n_sum_items;
|
||||||
|
/* Number of Item_sum-derived objects in children and descendant SELECTs */
|
||||||
|
uint n_child_sum_items;
|
||||||
|
|
||||||
/* explicit LIMIT clause was used */
|
/* explicit LIMIT clause was used */
|
||||||
bool explicit_limit;
|
bool explicit_limit;
|
||||||
/*
|
/*
|
||||||
@ -640,7 +646,7 @@ public:
|
|||||||
bool test_limit();
|
bool test_limit();
|
||||||
|
|
||||||
friend void lex_start(THD *thd, uchar *buf, uint length);
|
friend void lex_start(THD *thd, uchar *buf, uint length);
|
||||||
st_select_lex() {}
|
st_select_lex() : n_sum_items(0), n_child_sum_items(0) {}
|
||||||
void make_empty_select()
|
void make_empty_select()
|
||||||
{
|
{
|
||||||
init_query();
|
init_query();
|
||||||
|
@ -94,9 +94,9 @@ public:
|
|||||||
inline base_list() { empty(); }
|
inline base_list() { empty(); }
|
||||||
inline base_list(const base_list &tmp) :Sql_alloc()
|
inline base_list(const base_list &tmp) :Sql_alloc()
|
||||||
{
|
{
|
||||||
elements=tmp.elements;
|
elements= tmp.elements;
|
||||||
first=tmp.first;
|
first= tmp.first;
|
||||||
last=tmp.last;
|
last= elements ? tmp.last : &first;
|
||||||
}
|
}
|
||||||
inline base_list(bool error) { }
|
inline base_list(bool error) { }
|
||||||
inline bool push_back(void *info)
|
inline bool push_back(void *info)
|
||||||
|
@ -6083,6 +6083,7 @@ bool add_to_list(THD *thd, SQL_LIST &list,Item *item,bool asc)
|
|||||||
table_options A set of the following bits:
|
table_options A set of the following bits:
|
||||||
TL_OPTION_UPDATING Table will be updated
|
TL_OPTION_UPDATING Table will be updated
|
||||||
TL_OPTION_FORCE_INDEX Force usage of index
|
TL_OPTION_FORCE_INDEX Force usage of index
|
||||||
|
TL_OPTION_ALIAS an alias in multi table DELETE
|
||||||
lock_type How table should be locked
|
lock_type How table should be locked
|
||||||
use_index List of indexed used in USE INDEX
|
use_index List of indexed used in USE INDEX
|
||||||
ignore_index List of indexed used in IGNORE INDEX
|
ignore_index List of indexed used in IGNORE INDEX
|
||||||
@ -6111,7 +6112,8 @@ TABLE_LIST *st_select_lex::add_table_to_list(THD *thd,
|
|||||||
if (!table)
|
if (!table)
|
||||||
DBUG_RETURN(0); // End of memory
|
DBUG_RETURN(0); // End of memory
|
||||||
alias_str= alias ? alias->str : table->table.str;
|
alias_str= alias ? alias->str : table->table.str;
|
||||||
if (check_table_name(table->table.str, table->table.length))
|
if (!test(table_options & TL_OPTION_ALIAS) &&
|
||||||
|
check_table_name(table->table.str, table->table.length))
|
||||||
{
|
{
|
||||||
my_error(ER_WRONG_TABLE_NAME, MYF(0), table->table.str);
|
my_error(ER_WRONG_TABLE_NAME, MYF(0), table->table.str);
|
||||||
DBUG_RETURN(0);
|
DBUG_RETURN(0);
|
||||||
|
@ -1324,7 +1324,7 @@ JOIN::exec()
|
|||||||
}
|
}
|
||||||
(void) result->prepare2(); // Currently, this cannot fail.
|
(void) result->prepare2(); // Currently, this cannot fail.
|
||||||
|
|
||||||
if (!tables_list)
|
if (!tables_list && (tables || !select_lex->with_sum_func))
|
||||||
{ // Only test of functions
|
{ // Only test of functions
|
||||||
if (select_options & SELECT_DESCRIBE)
|
if (select_options & SELECT_DESCRIBE)
|
||||||
select_describe(this, FALSE, FALSE, FALSE,
|
select_describe(this, FALSE, FALSE, FALSE,
|
||||||
@ -1364,7 +1364,12 @@ JOIN::exec()
|
|||||||
thd->examined_row_count= 0;
|
thd->examined_row_count= 0;
|
||||||
DBUG_VOID_RETURN;
|
DBUG_VOID_RETURN;
|
||||||
}
|
}
|
||||||
thd->limit_found_rows= thd->examined_row_count= 0;
|
/*
|
||||||
|
don't reset the found rows count if there're no tables
|
||||||
|
as FOUND_ROWS() may be called.
|
||||||
|
*/
|
||||||
|
if (tables)
|
||||||
|
thd->limit_found_rows= thd->examined_row_count= 0;
|
||||||
|
|
||||||
if (zero_result_cause)
|
if (zero_result_cause)
|
||||||
{
|
{
|
||||||
@ -1403,7 +1408,8 @@ JOIN::exec()
|
|||||||
having= tmp_having;
|
having= tmp_having;
|
||||||
select_describe(this, need_tmp,
|
select_describe(this, need_tmp,
|
||||||
order != 0 && !skip_sort_order,
|
order != 0 && !skip_sort_order,
|
||||||
select_distinct);
|
select_distinct,
|
||||||
|
!tables ? "No tables used" : NullS);
|
||||||
DBUG_VOID_RETURN;
|
DBUG_VOID_RETURN;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -6351,29 +6357,30 @@ finish:
|
|||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Check whether an item is a simple equality predicate and if so
|
Check whether an equality can be used to build multiple equalities
|
||||||
create/find a multiple equality for this predicate
|
|
||||||
|
|
||||||
SYNOPSIS
|
SYNOPSIS
|
||||||
check_equality()
|
check_simple_equality()
|
||||||
item item to check
|
left_item left term of the quality to be checked
|
||||||
cond_equal multiple equalities that must hold together with the predicate
|
right_item right term of the equality to be checked
|
||||||
|
item equality item if the equality originates from a condition
|
||||||
|
predicate, 0 if the equality is the result of row elimination
|
||||||
|
cond_equal multiple equalities that must hold together with the equality
|
||||||
|
|
||||||
DESCRIPTION
|
DESCRIPTION
|
||||||
This function first checks whether an item is a simple equality i.e.
|
This function first checks whether the equality (left_item=right_item)
|
||||||
the one that equates a field with another field or a constant
|
is a simple equality i.e. the one that equates a field with another field
|
||||||
(item=constant_item or item=field_item).
|
or a constant (field=field_item or field=const_item).
|
||||||
If this is the case the function looks a for a multiple equality
|
If this is the case the function looks for a multiple equality
|
||||||
in the lists referenced directly or indirectly by cond_equal inferring
|
in the lists referenced directly or indirectly by cond_equal inferring
|
||||||
the given simple equality. If it doesn't find any, it builds a multiple
|
the given simple equality. If it doesn't find any, it builds a multiple
|
||||||
equality that covers the predicate, i.e. the predicate can be inferred
|
equality that covers the predicate, i.e. the predicate can be inferred
|
||||||
from it.
|
from this multiple equality.
|
||||||
The built multiple equality could be obtained in such a way:
|
The built multiple equality could be obtained in such a way:
|
||||||
create a binary multiple equality equivalent to the predicate, then
|
create a binary multiple equality equivalent to the predicate, then
|
||||||
merge it, if possible, with one of old multiple equalities.
|
merge it, if possible, with one of old multiple equalities.
|
||||||
This guarantees that the set of multiple equalities covering equality
|
This guarantees that the set of multiple equalities covering equality
|
||||||
predicates will
|
predicates will be minimal.
|
||||||
be minimal.
|
|
||||||
|
|
||||||
EXAMPLE
|
EXAMPLE
|
||||||
For the where condition
|
For the where condition
|
||||||
@ -6391,7 +6398,7 @@ finish:
|
|||||||
and will transform *cond_equal into (ptr(CE),[Item_equal(f,e)]).
|
and will transform *cond_equal into (ptr(CE),[Item_equal(f,e)]).
|
||||||
|
|
||||||
NOTES
|
NOTES
|
||||||
Now only fields that have the same type defintions (verified by
|
Now only fields that have the same type definitions (verified by
|
||||||
the Field::eq_def method) are placed to the same multiple equalities.
|
the Field::eq_def method) are placed to the same multiple equalities.
|
||||||
Because of this some equality predicates are not eliminated and
|
Because of this some equality predicates are not eliminated and
|
||||||
can be used in the constant propagation procedure.
|
can be used in the constant propagation procedure.
|
||||||
@ -6424,11 +6431,263 @@ finish:
|
|||||||
copying would be much more complicated.
|
copying would be much more complicated.
|
||||||
|
|
||||||
RETURN
|
RETURN
|
||||||
TRUE - if the predicate is a simple equality predicate
|
TRUE if the predicate is a simple equality predicate to be used
|
||||||
FALSE - otherwise
|
for building multiple equalities
|
||||||
|
FALSE otherwise
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static bool check_equality(Item *item, COND_EQUAL *cond_equal)
|
static bool check_simple_equality(Item *left_item, Item *right_item,
|
||||||
|
Item *item, COND_EQUAL *cond_equal)
|
||||||
|
{
|
||||||
|
if (left_item->type() == Item::REF_ITEM &&
|
||||||
|
((Item_ref*)left_item)->ref_type() == Item_ref::VIEW_REF)
|
||||||
|
{
|
||||||
|
if (((Item_ref*)left_item)->depended_from)
|
||||||
|
return FALSE;
|
||||||
|
left_item= left_item->real_item();
|
||||||
|
}
|
||||||
|
if (right_item->type() == Item::REF_ITEM &&
|
||||||
|
((Item_ref*)right_item)->ref_type() == Item_ref::VIEW_REF)
|
||||||
|
{
|
||||||
|
if (((Item_ref*)right_item)->depended_from)
|
||||||
|
return FALSE;
|
||||||
|
right_item= right_item->real_item();
|
||||||
|
}
|
||||||
|
if (left_item->type() == Item::FIELD_ITEM &&
|
||||||
|
right_item->type() == Item::FIELD_ITEM &&
|
||||||
|
!((Item_field*)left_item)->depended_from &&
|
||||||
|
!((Item_field*)right_item)->depended_from)
|
||||||
|
{
|
||||||
|
/* The predicate the form field1=field2 is processed */
|
||||||
|
|
||||||
|
Field *left_field= ((Item_field*) left_item)->field;
|
||||||
|
Field *right_field= ((Item_field*) right_item)->field;
|
||||||
|
|
||||||
|
if (!left_field->eq_def(right_field))
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
/* Search for multiple equalities containing field1 and/or field2 */
|
||||||
|
bool left_copyfl, right_copyfl;
|
||||||
|
Item_equal *left_item_equal=
|
||||||
|
find_item_equal(cond_equal, left_field, &left_copyfl);
|
||||||
|
Item_equal *right_item_equal=
|
||||||
|
find_item_equal(cond_equal, right_field, &right_copyfl);
|
||||||
|
|
||||||
|
/* As (NULL=NULL) != TRUE we can't just remove the predicate f=f */
|
||||||
|
if (left_field->eq(right_field)) /* f = f */
|
||||||
|
return (!(left_field->maybe_null() && !left_item_equal));
|
||||||
|
|
||||||
|
if (left_item_equal && left_item_equal == right_item_equal)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
The equality predicate is inference of one of the existing
|
||||||
|
multiple equalities, i.e the condition is already covered
|
||||||
|
by upper level equalities
|
||||||
|
*/
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Copy the found multiple equalities at the current level if needed */
|
||||||
|
if (left_copyfl)
|
||||||
|
{
|
||||||
|
/* left_item_equal of an upper level contains left_item */
|
||||||
|
left_item_equal= new Item_equal(left_item_equal);
|
||||||
|
cond_equal->current_level.push_back(left_item_equal);
|
||||||
|
}
|
||||||
|
if (right_copyfl)
|
||||||
|
{
|
||||||
|
/* right_item_equal of an upper level contains right_item */
|
||||||
|
right_item_equal= new Item_equal(right_item_equal);
|
||||||
|
cond_equal->current_level.push_back(right_item_equal);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (left_item_equal)
|
||||||
|
{
|
||||||
|
/* left item was found in the current or one of the upper levels */
|
||||||
|
if (! right_item_equal)
|
||||||
|
left_item_equal->add((Item_field *) right_item);
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* Merge two multiple equalities forming a new one */
|
||||||
|
left_item_equal->merge(right_item_equal);
|
||||||
|
/* Remove the merged multiple equality from the list */
|
||||||
|
List_iterator<Item_equal> li(cond_equal->current_level);
|
||||||
|
while ((li++) != right_item_equal);
|
||||||
|
li.remove();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* left item was not found neither the current nor in upper levels */
|
||||||
|
if (right_item_equal)
|
||||||
|
right_item_equal->add((Item_field *) left_item);
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* None of the fields was found in multiple equalities */
|
||||||
|
Item_equal *item= new Item_equal((Item_field *) left_item,
|
||||||
|
(Item_field *) right_item);
|
||||||
|
cond_equal->current_level.push_back(item);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
/* The predicate of the form field=const/const=field is processed */
|
||||||
|
Item *const_item= 0;
|
||||||
|
Item_field *field_item= 0;
|
||||||
|
if (left_item->type() == Item::FIELD_ITEM &&
|
||||||
|
!((Item_field*)left_item)->depended_from &&
|
||||||
|
right_item->const_item())
|
||||||
|
{
|
||||||
|
field_item= (Item_field*) left_item;
|
||||||
|
const_item= right_item;
|
||||||
|
}
|
||||||
|
else if (right_item->type() == Item::FIELD_ITEM &&
|
||||||
|
!((Item_field*)right_item)->depended_from &&
|
||||||
|
left_item->const_item())
|
||||||
|
{
|
||||||
|
field_item= (Item_field*) right_item;
|
||||||
|
const_item= left_item;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (const_item &&
|
||||||
|
field_item->result_type() == const_item->result_type())
|
||||||
|
{
|
||||||
|
bool copyfl;
|
||||||
|
|
||||||
|
if (field_item->result_type() == STRING_RESULT)
|
||||||
|
{
|
||||||
|
CHARSET_INFO *cs= ((Field_str*) field_item->field)->charset();
|
||||||
|
if (!item)
|
||||||
|
{
|
||||||
|
Item_func_eq *eq_item;
|
||||||
|
if ((eq_item= new Item_func_eq(left_item, right_item)))
|
||||||
|
return FALSE;
|
||||||
|
eq_item->set_cmp_func();
|
||||||
|
eq_item->quick_fix_field();
|
||||||
|
item= eq_item;
|
||||||
|
}
|
||||||
|
if ((cs != ((Item_func *) item)->compare_collation()) ||
|
||||||
|
!cs->coll->propagate(cs, 0, 0))
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
Item_equal *item_equal = find_item_equal(cond_equal,
|
||||||
|
field_item->field, ©fl);
|
||||||
|
if (copyfl)
|
||||||
|
{
|
||||||
|
item_equal= new Item_equal(item_equal);
|
||||||
|
cond_equal->current_level.push_back(item_equal);
|
||||||
|
}
|
||||||
|
if (item_equal)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
The flag cond_false will be set to 1 after this, if item_equal
|
||||||
|
already contains a constant and its value is not equal to
|
||||||
|
the value of const_item.
|
||||||
|
*/
|
||||||
|
item_equal->add(const_item);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
item_equal= new Item_equal(const_item, field_item);
|
||||||
|
cond_equal->current_level.push_back(item_equal);
|
||||||
|
}
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
Convert row equalities into a conjunction of regular equalities
|
||||||
|
|
||||||
|
SYNOPSIS
|
||||||
|
check_row_equality()
|
||||||
|
left_row left term of the row equality to be processed
|
||||||
|
right_row right term of the row equality to be processed
|
||||||
|
cond_equal multiple equalities that must hold together with the predicate
|
||||||
|
eq_list results of conversions of row equalities that are not simple
|
||||||
|
enough to form multiple equalities
|
||||||
|
|
||||||
|
DESCRIPTION
|
||||||
|
The function converts a row equality of the form (E1,...,En)=(E'1,...,E'n)
|
||||||
|
into a list of equalities E1=E'1,...,En=E'n. For each of these equalities
|
||||||
|
Ei=E'i the function checks whether it is a simple equality or a row equality.
|
||||||
|
If it is a simple equality it is used to expand multiple equalities of
|
||||||
|
cond_equal. If it is a row equality it converted to a sequence of equalities
|
||||||
|
between row elements. If Ei=E'i is neither a simple equality nor a row
|
||||||
|
equality the item for this predicate is added to eq_list.
|
||||||
|
|
||||||
|
RETURN
|
||||||
|
TRUE if conversion has succeeded (no fatal error)
|
||||||
|
FALSE otherwise
|
||||||
|
*/
|
||||||
|
|
||||||
|
static bool check_row_equality(Item *left_row, Item_row *right_row,
|
||||||
|
COND_EQUAL *cond_equal, List<Item>* eq_list)
|
||||||
|
{
|
||||||
|
uint n= left_row->cols();
|
||||||
|
for (uint i= 0 ; i < n; i++)
|
||||||
|
{
|
||||||
|
bool is_converted;
|
||||||
|
Item *left_item= left_row->el(i);
|
||||||
|
Item *right_item= right_row->el(i);
|
||||||
|
if (left_item->type() == Item::ROW_ITEM &&
|
||||||
|
right_item->type() == Item::ROW_ITEM)
|
||||||
|
is_converted= check_row_equality((Item_row *) left_item,
|
||||||
|
(Item_row *) right_item,
|
||||||
|
cond_equal, eq_list);
|
||||||
|
else
|
||||||
|
is_converted= check_simple_equality(left_item, right_item, 0, cond_equal);
|
||||||
|
|
||||||
|
if (!is_converted)
|
||||||
|
{
|
||||||
|
Item_func_eq *eq_item;
|
||||||
|
if (!(eq_item= new Item_func_eq(left_item, right_item)))
|
||||||
|
return FALSE;
|
||||||
|
eq_item->set_cmp_func();
|
||||||
|
eq_item->quick_fix_field();
|
||||||
|
eq_list->push_back(eq_item);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
Eliminate row equalities and form multiple equalities predicates
|
||||||
|
|
||||||
|
SYNOPSIS
|
||||||
|
check_equality()
|
||||||
|
item predicate to process
|
||||||
|
cond_equal multiple equalities that must hold together with the predicate
|
||||||
|
eq_list results of conversions of row equalities that are not simple
|
||||||
|
enough to form multiple equalities
|
||||||
|
|
||||||
|
DESCRIPTION
|
||||||
|
This function checks whether the item is a simple equality
|
||||||
|
i.e. the one that equates a field with another field or a constant
|
||||||
|
(field=field_item or field=constant_item), or, a row equality.
|
||||||
|
For a simple equality the function looks for a multiple equality
|
||||||
|
in the lists referenced directly or indirectly by cond_equal inferring
|
||||||
|
the given simple equality. If it doesn't find any, it builds/expands
|
||||||
|
multiple equality that covers the predicate.
|
||||||
|
Row equalities are eliminated substituted for conjunctive regular equalities
|
||||||
|
which are treated in the same way as original equality predicates.
|
||||||
|
|
||||||
|
RETURN
|
||||||
|
TRUE if re-writing rules have been applied
|
||||||
|
FALSE otherwise, i.e.
|
||||||
|
if the predicate is not an equality,
|
||||||
|
or, if the equality is neither a simple one nor a row equality,
|
||||||
|
or, if the procedure fails by a fatal error.
|
||||||
|
*/
|
||||||
|
|
||||||
|
static bool check_equality(Item *item, COND_EQUAL *cond_equal,
|
||||||
|
List<Item> *eq_list)
|
||||||
{
|
{
|
||||||
if (item->type() == Item::FUNC_ITEM &&
|
if (item->type() == Item::FUNC_ITEM &&
|
||||||
((Item_func*) item)->functype() == Item_func::EQ_FUNC)
|
((Item_func*) item)->functype() == Item_func::EQ_FUNC)
|
||||||
@ -6436,165 +6695,25 @@ static bool check_equality(Item *item, COND_EQUAL *cond_equal)
|
|||||||
Item *left_item= ((Item_func*) item)->arguments()[0];
|
Item *left_item= ((Item_func*) item)->arguments()[0];
|
||||||
Item *right_item= ((Item_func*) item)->arguments()[1];
|
Item *right_item= ((Item_func*) item)->arguments()[1];
|
||||||
|
|
||||||
if (left_item->type() == Item::REF_ITEM &&
|
if (left_item->type() == Item::ROW_ITEM &&
|
||||||
((Item_ref*)left_item)->ref_type() == Item_ref::VIEW_REF)
|
right_item->type() == Item::ROW_ITEM)
|
||||||
{
|
return check_row_equality((Item_row *) left_item,
|
||||||
if (((Item_ref*)left_item)->depended_from)
|
(Item_row *) right_item,
|
||||||
return FALSE;
|
cond_equal, eq_list);
|
||||||
left_item= left_item->real_item();
|
else
|
||||||
}
|
return check_simple_equality(left_item, right_item, item, cond_equal);
|
||||||
if (right_item->type() == Item::REF_ITEM &&
|
}
|
||||||
((Item_ref*)right_item)->ref_type() == Item_ref::VIEW_REF)
|
|
||||||
{
|
|
||||||
if (((Item_ref*)right_item)->depended_from)
|
|
||||||
return FALSE;
|
|
||||||
right_item= right_item->real_item();
|
|
||||||
}
|
|
||||||
if (left_item->type() == Item::FIELD_ITEM &&
|
|
||||||
right_item->type() == Item::FIELD_ITEM &&
|
|
||||||
!((Item_field*)left_item)->depended_from &&
|
|
||||||
!((Item_field*)right_item)->depended_from)
|
|
||||||
{
|
|
||||||
/* The predicate the form field1=field2 is processed */
|
|
||||||
|
|
||||||
Field *left_field= ((Item_field*) left_item)->field;
|
|
||||||
Field *right_field= ((Item_field*) right_item)->field;
|
|
||||||
|
|
||||||
if (!left_field->eq_def(right_field))
|
|
||||||
return FALSE;
|
|
||||||
|
|
||||||
if (left_field->eq(right_field)) /* f = f */
|
|
||||||
return TRUE;
|
|
||||||
|
|
||||||
/* Search for multiple equalities containing field1 and/or field2 */
|
|
||||||
bool left_copyfl, right_copyfl;
|
|
||||||
Item_equal *left_item_equal=
|
|
||||||
find_item_equal(cond_equal, left_field, &left_copyfl);
|
|
||||||
Item_equal *right_item_equal=
|
|
||||||
find_item_equal(cond_equal, right_field, &right_copyfl);
|
|
||||||
|
|
||||||
if (left_item_equal && left_item_equal == right_item_equal)
|
|
||||||
{
|
|
||||||
/*
|
|
||||||
The equality predicate is inference of one of the existing
|
|
||||||
multiple equalities, i.e the condition is already covered
|
|
||||||
by upper level equalities
|
|
||||||
*/
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Copy the found multiple equalities at the current level if needed */
|
|
||||||
if (left_copyfl)
|
|
||||||
{
|
|
||||||
/* left_item_equal of an upper level contains left_item */
|
|
||||||
left_item_equal= new Item_equal(left_item_equal);
|
|
||||||
cond_equal->current_level.push_back(left_item_equal);
|
|
||||||
}
|
|
||||||
if (right_copyfl)
|
|
||||||
{
|
|
||||||
/* right_item_equal of an upper level contains right_item */
|
|
||||||
right_item_equal= new Item_equal(right_item_equal);
|
|
||||||
cond_equal->current_level.push_back(right_item_equal);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (left_item_equal)
|
|
||||||
{
|
|
||||||
/* left item was found in the current or one of the upper levels */
|
|
||||||
if (! right_item_equal)
|
|
||||||
left_item_equal->add((Item_field *) right_item);
|
|
||||||
else
|
|
||||||
{
|
|
||||||
/* Merge two multiple equalities forming a new one */
|
|
||||||
left_item_equal->merge(right_item_equal);
|
|
||||||
/* Remove the merged multiple equality from the list */
|
|
||||||
List_iterator<Item_equal> li(cond_equal->current_level);
|
|
||||||
while ((li++) != right_item_equal);
|
|
||||||
li.remove();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
/* left item was not found neither the current nor in upper levels */
|
|
||||||
if (right_item_equal)
|
|
||||||
right_item_equal->add((Item_field *) left_item);
|
|
||||||
else
|
|
||||||
{
|
|
||||||
/* None of the fields was found in multiple equalities */
|
|
||||||
Item_equal *item= new Item_equal((Item_field *) left_item,
|
|
||||||
(Item_field *) right_item);
|
|
||||||
cond_equal->current_level.push_back(item);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
{
|
|
||||||
/* The predicate of the form field=const/const=field is processed */
|
|
||||||
Item *const_item= 0;
|
|
||||||
Item_field *field_item= 0;
|
|
||||||
if (left_item->type() == Item::FIELD_ITEM &&
|
|
||||||
!((Item_field*)left_item)->depended_from &&
|
|
||||||
right_item->const_item())
|
|
||||||
{
|
|
||||||
field_item= (Item_field*) left_item;
|
|
||||||
const_item= right_item;
|
|
||||||
}
|
|
||||||
else if (right_item->type() == Item::FIELD_ITEM &&
|
|
||||||
!((Item_field*)right_item)->depended_from &&
|
|
||||||
left_item->const_item())
|
|
||||||
{
|
|
||||||
field_item= (Item_field*) right_item;
|
|
||||||
const_item= left_item;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (const_item &&
|
|
||||||
field_item->result_type() == const_item->result_type())
|
|
||||||
{
|
|
||||||
bool copyfl;
|
|
||||||
|
|
||||||
if (field_item->result_type() == STRING_RESULT)
|
|
||||||
{
|
|
||||||
CHARSET_INFO *cs= ((Field_str*) field_item->field)->charset();
|
|
||||||
if ((cs != ((Item_cond *) item)->compare_collation()) ||
|
|
||||||
!cs->coll->propagate(cs, 0, 0))
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
Item_equal *item_equal = find_item_equal(cond_equal,
|
|
||||||
field_item->field, ©fl);
|
|
||||||
if (copyfl)
|
|
||||||
{
|
|
||||||
item_equal= new Item_equal(item_equal);
|
|
||||||
cond_equal->current_level.push_back(item_equal);
|
|
||||||
}
|
|
||||||
if (item_equal)
|
|
||||||
{
|
|
||||||
/*
|
|
||||||
The flag cond_false will be set to 1 after this, if item_equal
|
|
||||||
already contains a constant and its value is not equal to
|
|
||||||
the value of const_item.
|
|
||||||
*/
|
|
||||||
item_equal->add(const_item);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
item_equal= new Item_equal(const_item, field_item);
|
|
||||||
cond_equal->current_level.push_back(item_equal);
|
|
||||||
}
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Replace all equality predicates in a condition by multiple equality items
|
Replace all equality predicates in a condition by multiple equality items
|
||||||
|
|
||||||
SYNOPSIS
|
SYNOPSIS
|
||||||
build_equal_items_for_cond()
|
build_equal_items_for_cond()
|
||||||
cond condition(expression) where to make replacement
|
cond condition(expression) where to make replacement
|
||||||
inherited path to all inherited multiple equality items
|
inherited path to all inherited multiple equality items
|
||||||
|
|
||||||
DESCRIPTION
|
DESCRIPTION
|
||||||
At each 'and' level the function detects items for equality predicates
|
At each 'and' level the function detects items for equality predicates
|
||||||
@ -6608,7 +6727,9 @@ static bool check_equality(Item *item, COND_EQUAL *cond_equal)
|
|||||||
The function also traverses the cond tree and and for each field reference
|
The function also traverses the cond tree and and for each field reference
|
||||||
sets a pointer to the multiple equality item containing the field, if there
|
sets a pointer to the multiple equality item containing the field, if there
|
||||||
is any. If this multiple equality equates fields to a constant the
|
is any. If this multiple equality equates fields to a constant the
|
||||||
function replace the field reference by the constant.
|
function replaces the field reference by the constant in the cases
|
||||||
|
when the field is not of a string type or when the field reference is
|
||||||
|
just an argument of a comparison predicate.
|
||||||
The function also determines the maximum number of members in
|
The function also determines the maximum number of members in
|
||||||
equality lists of each Item_cond_and object assigning it to
|
equality lists of each Item_cond_and object assigning it to
|
||||||
cond_equal->max_members of this object and updating accordingly
|
cond_equal->max_members of this object and updating accordingly
|
||||||
@ -6659,10 +6780,12 @@ static COND *build_equal_items_for_cond(COND *cond,
|
|||||||
Item_equal *item_equal;
|
Item_equal *item_equal;
|
||||||
uint members;
|
uint members;
|
||||||
COND_EQUAL cond_equal;
|
COND_EQUAL cond_equal;
|
||||||
|
COND *new_cond;
|
||||||
cond_equal.upper_levels= inherited;
|
cond_equal.upper_levels= inherited;
|
||||||
|
|
||||||
if (cond->type() == Item::COND_ITEM)
|
if (cond->type() == Item::COND_ITEM)
|
||||||
{
|
{
|
||||||
|
List<Item> eq_list;
|
||||||
bool and_level= ((Item_cond*) cond)->functype() ==
|
bool and_level= ((Item_cond*) cond)->functype() ==
|
||||||
Item_func::COND_AND_FUNC;
|
Item_func::COND_AND_FUNC;
|
||||||
List<Item> *args= ((Item_cond*) cond)->argument_list();
|
List<Item> *args= ((Item_cond*) cond)->argument_list();
|
||||||
@ -6685,7 +6808,7 @@ static COND *build_equal_items_for_cond(COND *cond,
|
|||||||
structure here because it's restored before each
|
structure here because it's restored before each
|
||||||
re-execution of any prepared statement/stored procedure.
|
re-execution of any prepared statement/stored procedure.
|
||||||
*/
|
*/
|
||||||
if (check_equality(item, &cond_equal))
|
if (check_equality(item, &cond_equal, &eq_list))
|
||||||
li.remove();
|
li.remove();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -6732,10 +6855,14 @@ static COND *build_equal_items_for_cond(COND *cond,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (and_level)
|
if (and_level)
|
||||||
|
{
|
||||||
|
args->concat(&eq_list);
|
||||||
args->concat((List<Item> *)&cond_equal.current_level);
|
args->concat((List<Item> *)&cond_equal.current_level);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else if (cond->type() == Item::FUNC_ITEM)
|
else if (cond->type() == Item::FUNC_ITEM)
|
||||||
{
|
{
|
||||||
|
List<Item> eq_list;
|
||||||
/*
|
/*
|
||||||
If an equality predicate forms the whole and level,
|
If an equality predicate forms the whole and level,
|
||||||
we call it standalone equality and it's processed here.
|
we call it standalone equality and it's processed here.
|
||||||
@ -6746,19 +6873,57 @@ static COND *build_equal_items_for_cond(COND *cond,
|
|||||||
for WHERE a=b AND c=d AND (b=c OR d=5)
|
for WHERE a=b AND c=d AND (b=c OR d=5)
|
||||||
b=c is replaced by =(a,b,c,d).
|
b=c is replaced by =(a,b,c,d).
|
||||||
*/
|
*/
|
||||||
if (check_equality(cond, &cond_equal) &&
|
if (check_equality(cond, &cond_equal, &eq_list))
|
||||||
(item_equal= cond_equal.current_level.pop()))
|
|
||||||
{
|
{
|
||||||
item_equal->fix_length_and_dec();
|
int n= cond_equal.current_level.elements + eq_list.elements;
|
||||||
item_equal->update_used_tables();
|
if (n == 0)
|
||||||
return item_equal;
|
return new Item_int((longlong) 1,1);
|
||||||
|
else if (n == 1)
|
||||||
|
{
|
||||||
|
if ((item_equal= cond_equal.current_level.pop()))
|
||||||
|
{
|
||||||
|
item_equal->fix_length_and_dec();
|
||||||
|
item_equal->update_used_tables();
|
||||||
|
return item_equal;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
return eq_list.pop();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
Here a new AND level must be created. It can happen only
|
||||||
|
when a row equality is processed as a standalone predicate.
|
||||||
|
*/
|
||||||
|
Item_cond_and *and_cond= new Item_cond_and(eq_list);
|
||||||
|
and_cond->quick_fix_field();
|
||||||
|
List<Item> *args= and_cond->argument_list();
|
||||||
|
List_iterator_fast<Item_equal> it(cond_equal.current_level);
|
||||||
|
while ((item_equal= it++))
|
||||||
|
{
|
||||||
|
item_equal->fix_length_and_dec();
|
||||||
|
item_equal->update_used_tables();
|
||||||
|
members= item_equal->members();
|
||||||
|
if (cond_equal.max_members < members)
|
||||||
|
cond_equal.max_members= members;
|
||||||
|
}
|
||||||
|
and_cond->cond_equal= cond_equal;
|
||||||
|
args->concat((List<Item> *)&cond_equal.current_level);
|
||||||
|
|
||||||
|
return and_cond;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
/*
|
/*
|
||||||
For each field reference in cond, not from equal item predicates,
|
For each field reference in cond, not from equal item predicates,
|
||||||
set a pointer to the multiple equality it belongs to (if there is any)
|
set a pointer to the multiple equality it belongs to (if there is any)
|
||||||
|
as soon the field is not of a string type or the field reference is
|
||||||
|
an argument of a comparison predicate.
|
||||||
*/
|
*/
|
||||||
cond= cond->transform(&Item::equal_fields_propagator,
|
byte *is_subst_valid= (byte *) 1;
|
||||||
(byte *) inherited);
|
cond= cond->compile(&Item::subst_argument_checker,
|
||||||
|
&is_subst_valid,
|
||||||
|
&Item::equal_fields_propagator,
|
||||||
|
(byte *) inherited);
|
||||||
cond->update_used_tables();
|
cond->update_used_tables();
|
||||||
}
|
}
|
||||||
return cond;
|
return cond;
|
||||||
@ -7038,7 +7203,7 @@ static Item *eliminate_item_equal(COND *cond, COND_EQUAL *upper_levels,
|
|||||||
|
|
||||||
/*
|
/*
|
||||||
Substitute every field reference in a condition by the best equal field
|
Substitute every field reference in a condition by the best equal field
|
||||||
and eliminate all multiplle equality predicates
|
and eliminate all multiple equality predicates
|
||||||
|
|
||||||
SYNOPSIS
|
SYNOPSIS
|
||||||
substitute_for_best_equal_field()
|
substitute_for_best_equal_field()
|
||||||
@ -9576,9 +9741,13 @@ do_select(JOIN *join,List<Item> *fields,TABLE *table,Procedure *procedure)
|
|||||||
table->file->ha_index_init(0);
|
table->file->ha_index_init(0);
|
||||||
}
|
}
|
||||||
/* Set up select_end */
|
/* Set up select_end */
|
||||||
join->join_tab[join->tables-1].next_select= setup_end_select_func(join);
|
Next_select_func end_select= setup_end_select_func(join);
|
||||||
|
if (join->tables)
|
||||||
|
{
|
||||||
|
join->join_tab[join->tables-1].next_select= end_select;
|
||||||
|
|
||||||
join_tab=join->join_tab+join->const_tables;
|
join_tab=join->join_tab+join->const_tables;
|
||||||
|
}
|
||||||
join->send_records=0;
|
join->send_records=0;
|
||||||
if (join->tables == join->const_tables)
|
if (join->tables == join->const_tables)
|
||||||
{
|
{
|
||||||
@ -9588,7 +9757,6 @@ do_select(JOIN *join,List<Item> *fields,TABLE *table,Procedure *procedure)
|
|||||||
*/
|
*/
|
||||||
if (!join->conds || join->conds->val_int())
|
if (!join->conds || join->conds->val_int())
|
||||||
{
|
{
|
||||||
Next_select_func end_select= join->join_tab[join->tables-1].next_select;
|
|
||||||
error= (*end_select)(join,join_tab,0);
|
error= (*end_select)(join,join_tab,0);
|
||||||
if (error == NESTED_LOOP_OK || error == NESTED_LOOP_QUERY_LIMIT)
|
if (error == NESTED_LOOP_OK || error == NESTED_LOOP_QUERY_LIMIT)
|
||||||
error= (*end_select)(join,join_tab,1);
|
error= (*end_select)(join,join_tab,1);
|
||||||
@ -9602,6 +9770,8 @@ do_select(JOIN *join,List<Item> *fields,TABLE *table,Procedure *procedure)
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
DBUG_ASSERT(join->tables);
|
||||||
|
DBUG_ASSERT(join_tab);
|
||||||
error= sub_select(join,join_tab,0);
|
error= sub_select(join,join_tab,0);
|
||||||
if (error == NESTED_LOOP_OK || error == NESTED_LOOP_NO_MORE_ROWS)
|
if (error == NESTED_LOOP_OK || error == NESTED_LOOP_NO_MORE_ROWS)
|
||||||
error= sub_select(join,join_tab,1);
|
error= sub_select(join,join_tab,1);
|
||||||
@ -14221,9 +14391,12 @@ static void select_describe(JOIN *join, bool need_tmp_table, bool need_order,
|
|||||||
item_list.push_back(new Item_string(table_name_buffer, len, cs));
|
item_list.push_back(new Item_string(table_name_buffer, len, cs));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
item_list.push_back(new Item_string(table->alias,
|
{
|
||||||
strlen(table->alias),
|
TABLE_LIST *tab=table->pos_in_table_list;
|
||||||
|
item_list.push_back(new Item_string(tab->alias,
|
||||||
|
strlen(tab->alias),
|
||||||
cs));
|
cs));
|
||||||
|
}
|
||||||
/* type */
|
/* type */
|
||||||
item_list.push_back(new Item_string(join_type_str[tab->type],
|
item_list.push_back(new Item_string(join_type_str[tab->type],
|
||||||
strlen(join_type_str[tab->type]),
|
strlen(join_type_str[tab->type]),
|
||||||
@ -14410,8 +14583,8 @@ bool mysql_explain_union(THD *thd, SELECT_LEX_UNIT *unit, select_result *result)
|
|||||||
// drop UNCACHEABLE_EXPLAIN, because it is for internal usage only
|
// drop UNCACHEABLE_EXPLAIN, because it is for internal usage only
|
||||||
uint8 uncacheable= (sl->uncacheable & ~UNCACHEABLE_EXPLAIN);
|
uint8 uncacheable= (sl->uncacheable & ~UNCACHEABLE_EXPLAIN);
|
||||||
sl->type= (((&thd->lex->select_lex)==sl)?
|
sl->type= (((&thd->lex->select_lex)==sl)?
|
||||||
((thd->lex->all_selects_list != sl) ?
|
(sl->first_inner_unit() || sl->next_select() ?
|
||||||
primary_key_name : "SIMPLE"):
|
"PRIMARY" : "SIMPLE"):
|
||||||
((sl == first)?
|
((sl == first)?
|
||||||
((sl->linkage == DERIVED_TABLE_TYPE) ?
|
((sl->linkage == DERIVED_TABLE_TYPE) ?
|
||||||
"DERIVED":
|
"DERIVED":
|
||||||
|
156
sql/sql_yacc.yy
156
sql/sql_yacc.yy
@ -725,8 +725,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize);
|
|||||||
predicate bit_expr bit_term bit_factor value_expr term factor
|
predicate bit_expr bit_term bit_factor value_expr term factor
|
||||||
table_wild simple_expr udf_expr
|
table_wild simple_expr udf_expr
|
||||||
expr_or_default set_expr_or_default interval_expr
|
expr_or_default set_expr_or_default interval_expr
|
||||||
param_marker singlerow_subselect singlerow_subselect_init
|
param_marker geometry_function
|
||||||
exists_subselect exists_subselect_init geometry_function
|
|
||||||
signed_literal now_or_signed_literal opt_escape
|
signed_literal now_or_signed_literal opt_escape
|
||||||
sp_opt_default
|
sp_opt_default
|
||||||
simple_ident_nospvar simple_ident_q
|
simple_ident_nospvar simple_ident_q
|
||||||
@ -791,7 +790,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize);
|
|||||||
|
|
||||||
%type <variable> internal_variable_name
|
%type <variable> internal_variable_name
|
||||||
|
|
||||||
%type <select_lex> in_subselect in_subselect_init
|
%type <select_lex> subselect subselect_init
|
||||||
get_select_lex
|
get_select_lex
|
||||||
|
|
||||||
%type <boolfunc2creator> comp_op
|
%type <boolfunc2creator> comp_op
|
||||||
@ -3914,12 +3913,14 @@ select_paren:
|
|||||||
yyerror(ER(ER_SYNTAX_ERROR));
|
yyerror(ER(ER_SYNTAX_ERROR));
|
||||||
YYABORT;
|
YYABORT;
|
||||||
}
|
}
|
||||||
if (sel->linkage == UNION_TYPE &&
|
if (sel->linkage == UNION_TYPE &&
|
||||||
!sel->master_unit()->first_select()->braces)
|
!sel->master_unit()->first_select()->braces &&
|
||||||
{
|
sel->master_unit()->first_select()->linkage ==
|
||||||
yyerror(ER(ER_SYNTAX_ERROR));
|
UNION_TYPE)
|
||||||
YYABORT;
|
{
|
||||||
}
|
yyerror(ER(ER_SYNTAX_ERROR));
|
||||||
|
YYABORT;
|
||||||
|
}
|
||||||
/* select in braces, can't contain global parameters */
|
/* select in braces, can't contain global parameters */
|
||||||
if (sel->master_unit()->fake_select_lex)
|
if (sel->master_unit()->fake_select_lex)
|
||||||
sel->master_unit()->global_parameters=
|
sel->master_unit()->global_parameters=
|
||||||
@ -4177,37 +4178,37 @@ bool_pri:
|
|||||||
| bool_pri EQUAL_SYM predicate { $$= new Item_func_equal($1,$3); }
|
| bool_pri EQUAL_SYM predicate { $$= new Item_func_equal($1,$3); }
|
||||||
| bool_pri comp_op predicate %prec EQ
|
| bool_pri comp_op predicate %prec EQ
|
||||||
{ $$= (*$2)(0)->create($1,$3); }
|
{ $$= (*$2)(0)->create($1,$3); }
|
||||||
| bool_pri comp_op all_or_any in_subselect %prec EQ
|
| bool_pri comp_op all_or_any '(' subselect ')' %prec EQ
|
||||||
{ $$= all_any_subquery_creator($1, $2, $3, $4); }
|
{ $$= all_any_subquery_creator($1, $2, $3, $5); }
|
||||||
| predicate ;
|
| predicate ;
|
||||||
|
|
||||||
predicate:
|
predicate:
|
||||||
bit_expr IN_SYM '(' expr_list ')'
|
bit_expr IN_SYM '(' subselect ')'
|
||||||
{
|
{ $$= new Item_in_subselect($1, $4); }
|
||||||
if ($4->elements == 1)
|
| bit_expr not IN_SYM '(' subselect ')'
|
||||||
$$= new Item_func_eq($1, $4->head());
|
{ $$= negate_expression(YYTHD, new Item_in_subselect($1, $5)); }
|
||||||
else
|
| bit_expr IN_SYM '(' expr ')'
|
||||||
{
|
|
||||||
$4->push_front($1);
|
|
||||||
$$= new Item_func_in(*$4);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
| bit_expr not IN_SYM '(' expr_list ')'
|
|
||||||
{
|
{
|
||||||
if ($5->elements == 1)
|
$$= new Item_func_eq($1, $4);
|
||||||
$$= new Item_func_ne($1, $5->head());
|
}
|
||||||
else
|
| bit_expr IN_SYM '(' expr ',' expr_list ')'
|
||||||
{
|
{
|
||||||
$5->push_front($1);
|
$6->push_front($4);
|
||||||
Item_func_in *item = new Item_func_in(*$5);
|
$6->push_front($1);
|
||||||
|
$$= new Item_func_in(*$6);
|
||||||
|
}
|
||||||
|
| bit_expr not IN_SYM '(' expr ')'
|
||||||
|
{
|
||||||
|
$$= new Item_func_ne($1, $5);
|
||||||
|
}
|
||||||
|
| bit_expr not IN_SYM '(' expr ',' expr_list ')'
|
||||||
|
{
|
||||||
|
$7->push_front($5);
|
||||||
|
$7->push_front($1);
|
||||||
|
Item_func_in *item = new Item_func_in(*$7);
|
||||||
item->negate();
|
item->negate();
|
||||||
$$= item;
|
$$= item;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
| bit_expr IN_SYM in_subselect
|
|
||||||
{ $$= new Item_in_subselect($1, $3); }
|
|
||||||
| bit_expr not IN_SYM in_subselect
|
|
||||||
{ $$= negate_expression(YYTHD, new Item_in_subselect($1, $4)); }
|
|
||||||
| bit_expr BETWEEN_SYM bit_expr AND_SYM predicate
|
| bit_expr BETWEEN_SYM bit_expr AND_SYM predicate
|
||||||
{ $$= new Item_func_between($1,$3,$5); }
|
{ $$= new Item_func_between($1,$3,$5); }
|
||||||
| bit_expr not BETWEEN_SYM bit_expr AND_SYM predicate
|
| bit_expr not BETWEEN_SYM bit_expr AND_SYM predicate
|
||||||
@ -4329,6 +4330,10 @@ simple_expr:
|
|||||||
| '-' simple_expr %prec NEG { $$= new Item_func_neg($2); }
|
| '-' simple_expr %prec NEG { $$= new Item_func_neg($2); }
|
||||||
| '~' simple_expr %prec NEG { $$= new Item_func_bit_neg($2); }
|
| '~' simple_expr %prec NEG { $$= new Item_func_bit_neg($2); }
|
||||||
| not2 simple_expr %prec NEG { $$= negate_expression(YYTHD, $2); }
|
| not2 simple_expr %prec NEG { $$= negate_expression(YYTHD, $2); }
|
||||||
|
| '(' subselect ')'
|
||||||
|
{
|
||||||
|
$$= new Item_singlerow_subselect($2);
|
||||||
|
}
|
||||||
| '(' expr ')' { $$= $2; }
|
| '(' expr ')' { $$= $2; }
|
||||||
| '(' expr ',' expr_list ')'
|
| '(' expr ',' expr_list ')'
|
||||||
{
|
{
|
||||||
@ -4340,8 +4345,10 @@ simple_expr:
|
|||||||
$5->push_front($3);
|
$5->push_front($3);
|
||||||
$$= new Item_row(*$5);
|
$$= new Item_row(*$5);
|
||||||
}
|
}
|
||||||
| EXISTS exists_subselect { $$= $2; }
|
| EXISTS '(' subselect ')'
|
||||||
| singlerow_subselect { $$= $1; }
|
{
|
||||||
|
$$= new Item_exists_subselect($3);
|
||||||
|
}
|
||||||
| '{' ident expr '}' { $$= $3; }
|
| '{' ident expr '}' { $$= $3; }
|
||||||
| MATCH ident_list_arg AGAINST '(' bit_expr fulltext_options ')'
|
| MATCH ident_list_arg AGAINST '(' bit_expr fulltext_options ')'
|
||||||
{ $2->push_front($5);
|
{ $2->push_front($5);
|
||||||
@ -6319,14 +6326,17 @@ table_wild_one:
|
|||||||
ident opt_wild opt_table_alias
|
ident opt_wild opt_table_alias
|
||||||
{
|
{
|
||||||
if (!Select->add_table_to_list(YYTHD, new Table_ident($1), $3,
|
if (!Select->add_table_to_list(YYTHD, new Table_ident($1), $3,
|
||||||
TL_OPTION_UPDATING, Lex->lock_option))
|
TL_OPTION_UPDATING |
|
||||||
|
TL_OPTION_ALIAS, Lex->lock_option))
|
||||||
YYABORT;
|
YYABORT;
|
||||||
}
|
}
|
||||||
| ident '.' ident opt_wild opt_table_alias
|
| ident '.' ident opt_wild opt_table_alias
|
||||||
{
|
{
|
||||||
if (!Select->add_table_to_list(YYTHD,
|
if (!Select->add_table_to_list(YYTHD,
|
||||||
new Table_ident(YYTHD, $1, $3, 0),
|
new Table_ident(YYTHD, $1, $3, 0),
|
||||||
$5, TL_OPTION_UPDATING,
|
$5,
|
||||||
|
TL_OPTION_UPDATING |
|
||||||
|
TL_OPTION_ALIAS,
|
||||||
Lex->lock_option))
|
Lex->lock_option))
|
||||||
YYABORT;
|
YYABORT;
|
||||||
}
|
}
|
||||||
@ -7545,6 +7555,7 @@ keyword:
|
|||||||
| TRUNCATE_SYM {}
|
| TRUNCATE_SYM {}
|
||||||
| UNICODE_SYM {}
|
| UNICODE_SYM {}
|
||||||
| XA_SYM {}
|
| XA_SYM {}
|
||||||
|
| UPGRADE_SYM {}
|
||||||
;
|
;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -8867,49 +8878,38 @@ union_option:
|
|||||||
| ALL { $$=0; }
|
| ALL { $$=0; }
|
||||||
;
|
;
|
||||||
|
|
||||||
singlerow_subselect:
|
subselect:
|
||||||
subselect_start singlerow_subselect_init
|
SELECT_SYM subselect_start subselect_init subselect_end
|
||||||
subselect_end
|
{
|
||||||
{
|
$$= $3;
|
||||||
$$= $2;
|
}
|
||||||
};
|
| '(' subselect_start subselect ')'
|
||||||
|
{
|
||||||
|
LEX *lex= Lex;
|
||||||
|
THD *thd= YYTHD;
|
||||||
|
/*
|
||||||
|
note that a local variable can't be used for
|
||||||
|
$3 as it's used in local variable construction
|
||||||
|
and some compilers can't guarnatee the order
|
||||||
|
in which the local variables are initialized.
|
||||||
|
*/
|
||||||
|
List_iterator<Item> it($3->item_list);
|
||||||
|
Item *item;
|
||||||
|
/*
|
||||||
|
we must fill the items list for the "derived table".
|
||||||
|
*/
|
||||||
|
while ((item= it++))
|
||||||
|
add_item_to_list(thd, item);
|
||||||
|
}
|
||||||
|
union_clause subselect_end { $$= $3; };
|
||||||
|
|
||||||
singlerow_subselect_init:
|
subselect_init:
|
||||||
select_init2
|
|
||||||
{
|
|
||||||
$$= new Item_singlerow_subselect(Lex->current_select->
|
|
||||||
master_unit()->first_select());
|
|
||||||
};
|
|
||||||
|
|
||||||
exists_subselect:
|
|
||||||
subselect_start exists_subselect_init
|
|
||||||
subselect_end
|
|
||||||
{
|
|
||||||
$$= $2;
|
|
||||||
};
|
|
||||||
|
|
||||||
exists_subselect_init:
|
|
||||||
select_init2
|
|
||||||
{
|
|
||||||
$$= new Item_exists_subselect(Lex->current_select->master_unit()->
|
|
||||||
first_select());
|
|
||||||
};
|
|
||||||
|
|
||||||
in_subselect:
|
|
||||||
subselect_start in_subselect_init
|
|
||||||
subselect_end
|
|
||||||
{
|
|
||||||
$$= $2;
|
|
||||||
};
|
|
||||||
|
|
||||||
in_subselect_init:
|
|
||||||
select_init2
|
select_init2
|
||||||
{
|
{
|
||||||
$$= Lex->current_select->master_unit()->first_select();
|
$$= Lex->current_select->master_unit()->first_select();
|
||||||
};
|
};
|
||||||
|
|
||||||
subselect_start:
|
subselect_start:
|
||||||
'(' SELECT_SYM
|
|
||||||
{
|
{
|
||||||
LEX *lex=Lex;
|
LEX *lex=Lex;
|
||||||
if (lex->sql_command == (int)SQLCOM_HA_READ ||
|
if (lex->sql_command == (int)SQLCOM_HA_READ ||
|
||||||
@ -8918,17 +8918,25 @@ subselect_start:
|
|||||||
yyerror(ER(ER_SYNTAX_ERROR));
|
yyerror(ER(ER_SYNTAX_ERROR));
|
||||||
YYABORT;
|
YYABORT;
|
||||||
}
|
}
|
||||||
|
/*
|
||||||
|
we are making a "derived table" for the parenthesis
|
||||||
|
as we need to have a lex level to fit the union
|
||||||
|
after the parenthesis, e.g.
|
||||||
|
(SELECT .. ) UNION ... becomes
|
||||||
|
SELECT * FROM ((SELECT ...) UNION ...)
|
||||||
|
*/
|
||||||
if (mysql_new_select(Lex, 1))
|
if (mysql_new_select(Lex, 1))
|
||||||
YYABORT;
|
YYABORT;
|
||||||
};
|
};
|
||||||
|
|
||||||
subselect_end:
|
subselect_end:
|
||||||
')'
|
|
||||||
{
|
{
|
||||||
LEX *lex=Lex;
|
LEX *lex=Lex;
|
||||||
lex->pop_context();
|
lex->pop_context();
|
||||||
|
SELECT_LEX *child= lex->current_select;
|
||||||
lex->current_select = lex->current_select->return_after_parsing();
|
lex->current_select = lex->current_select->return_after_parsing();
|
||||||
lex->nest_level--;
|
lex->nest_level--;
|
||||||
|
lex->current_select->n_child_sum_items += child->n_sum_items;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**************************************************************************
|
/**************************************************************************
|
||||||
|
Loading…
x
Reference in New Issue
Block a user