Merge 5.3->5.5.
In particular: Merged the patch for bug mdev-4418 from 5.3 into 5.5. Fixed a bug in the patch that should be backported to 5.3.
This commit is contained in:
commit
4eddb2c221
@ -1930,7 +1930,7 @@ id select_type table type possible_keys key key_len ref rows filtered Extra
|
||||
1 PRIMARY t2 system NULL NULL NULL NULL 1 100.00
|
||||
2 SUBQUERY t3 ALL NULL NULL NULL NULL 2 100.00 Using where
|
||||
Warnings:
|
||||
Note 1003 select NULL AS `a` from `test`.`t2` where 1
|
||||
Note 1003 select NULL AS `a` from `test`.`t2`
|
||||
DROP TABLE t1,t2,t3;
|
||||
#
|
||||
# LP bug #817384 Wrong result with outer join + subquery in ON
|
||||
|
@ -1941,7 +1941,7 @@ id select_type table type possible_keys key key_len ref rows filtered Extra
|
||||
1 PRIMARY t2 system NULL NULL NULL NULL 1 100.00
|
||||
2 SUBQUERY t3 ALL NULL NULL NULL NULL 2 100.00 Using where
|
||||
Warnings:
|
||||
Note 1003 select NULL AS `a` from `test`.`t2` where 1
|
||||
Note 1003 select NULL AS `a` from `test`.`t2`
|
||||
DROP TABLE t1,t2,t3;
|
||||
#
|
||||
# LP bug #817384 Wrong result with outer join + subquery in ON
|
||||
|
@ -712,14 +712,14 @@ INSERT INTO t1 VALUES
|
||||
'd8c4177d09f8b11f5.52725522');
|
||||
EXPLAIN
|
||||
SELECT s.oxid FROM t1 v, t1 s
|
||||
WHERE s.oxrootid = 'd8c4177d09f8b11f5.52725521' AND
|
||||
WHERE
|
||||
v.oxrootid ='d8c4177d09f8b11f5.52725521' AND
|
||||
s.oxleft > v.oxleft AND s.oxleft < v.oxright;
|
||||
id select_type table type possible_keys key key_len ref rows Extra
|
||||
1 SIMPLE v ref OXLEFT,OXRIGHT,OXROOTID OXROOTID 34 const 5 Using index condition
|
||||
1 SIMPLE s ALL OXLEFT NULL NULL NULL 12 Range checked for each record (index map: 0x4)
|
||||
SELECT s.oxid FROM t1 v, t1 s
|
||||
WHERE s.oxrootid = 'd8c4177d09f8b11f5.52725521' AND
|
||||
WHERE
|
||||
v.oxrootid ='d8c4177d09f8b11f5.52725521' AND
|
||||
s.oxleft > v.oxleft AND s.oxleft < v.oxright;
|
||||
oxid
|
||||
@ -728,6 +728,11 @@ d8c4177d206a333d2.74422679
|
||||
d8c4177d225791924.30714720
|
||||
d8c4177d2380fc201.39666693
|
||||
d8c4177d24ccef970.14957924
|
||||
d8c4177d151affab2.81582771
|
||||
d8c4177d206a333d2.74422678
|
||||
d8c4177d225791924.30714721
|
||||
d8c4177d2380fc201.39666694
|
||||
d8c4177d24ccef970.14957925
|
||||
DROP TABLE t1;
|
||||
create table t1 (
|
||||
c1 char(10), c2 char(10), c3 char(10), c4 char(10),
|
||||
@ -1887,6 +1892,46 @@ AAA AAA AAA
|
||||
AAAA AAAA AAAA
|
||||
AAAAA AAAAA AAAAA
|
||||
DROP TABLE t1;
|
||||
#
|
||||
# mdev-4894: Poor performance with unnecessary
|
||||
# (bug#70021) 'Range checked for each record'
|
||||
#
|
||||
create table t1( key1 int not null, INDEX i1(key1) );
|
||||
insert into t1 values (1),(2),(3),(4),(5),(6),(7),(8);
|
||||
insert into t1 select key1+8 from t1;
|
||||
insert into t1 select key1+16 from t1;
|
||||
insert into t1 select key1+32 from t1;
|
||||
insert into t1 select key1+64 from t1;
|
||||
insert into t1 select key1+128 from t1;
|
||||
insert into t1 select key1+256 from t1;
|
||||
insert into t1 select key1+512 from t1;
|
||||
alter table t1 add key2 int not null, add index i2(key2);
|
||||
update t1 set key2=key1;
|
||||
analyze table t1;
|
||||
Table Op Msg_type Msg_text
|
||||
test.t1 analyze status OK
|
||||
create table t2 (a int);
|
||||
insert into t2 values (1),(2),(3),(4),(5),(6),(7),(8);
|
||||
insert into t2 select a+16 from t2;
|
||||
insert into t2 select a+32 from t2;
|
||||
insert into t2 select a+64 from t2;
|
||||
explain
|
||||
select count(*) from t2 left join t1 on (t1.key1 < 3 or t1.key1 > 1020) and t1.key2 < 1000;
|
||||
id select_type table type possible_keys key key_len ref rows Extra
|
||||
1 SIMPLE t2 ALL NULL NULL NULL NULL 64
|
||||
1 SIMPLE t1 range i1,i2 i1 4 NULL 78 Using where; Using join buffer (flat, BNL join)
|
||||
select count(*) from t2 left join t1 on (t1.key1 < 3 or t1.key1 > 1020) and t1.key2 < 1000;
|
||||
count(*)
|
||||
128
|
||||
explain
|
||||
select count(*) from t2 left join t1 on (t1.key1 < 3 or t1.key1 > 1020) and t1.key2 < t2.a;
|
||||
id select_type table type possible_keys key key_len ref rows Extra
|
||||
1 SIMPLE t2 ALL NULL NULL NULL NULL 64
|
||||
1 SIMPLE t1 range i1,i2 i1 4 NULL 78 Using where; Using join buffer (flat, BNL join)
|
||||
select count(*) from t2 left join t1 on (t1.key1 < 3 or t1.key1 > 1020) and t1.key2 < t2.a;
|
||||
count(*)
|
||||
126
|
||||
drop table t1,t2;
|
||||
End of 5.1 tests
|
||||
#
|
||||
# LP Bug #533117: Wrong use_count in SEL_ARG trees
|
||||
|
@ -714,14 +714,14 @@ INSERT INTO t1 VALUES
|
||||
'd8c4177d09f8b11f5.52725522');
|
||||
EXPLAIN
|
||||
SELECT s.oxid FROM t1 v, t1 s
|
||||
WHERE s.oxrootid = 'd8c4177d09f8b11f5.52725521' AND
|
||||
WHERE
|
||||
v.oxrootid ='d8c4177d09f8b11f5.52725521' AND
|
||||
s.oxleft > v.oxleft AND s.oxleft < v.oxright;
|
||||
id select_type table type possible_keys key key_len ref rows Extra
|
||||
1 SIMPLE v ref OXLEFT,OXRIGHT,OXROOTID OXROOTID 34 const 5 Using index condition
|
||||
1 SIMPLE s ALL OXLEFT NULL NULL NULL 12 Range checked for each record (index map: 0x4)
|
||||
SELECT s.oxid FROM t1 v, t1 s
|
||||
WHERE s.oxrootid = 'd8c4177d09f8b11f5.52725521' AND
|
||||
WHERE
|
||||
v.oxrootid ='d8c4177d09f8b11f5.52725521' AND
|
||||
s.oxleft > v.oxleft AND s.oxleft < v.oxright;
|
||||
oxid
|
||||
@ -730,6 +730,11 @@ d8c4177d206a333d2.74422679
|
||||
d8c4177d225791924.30714720
|
||||
d8c4177d2380fc201.39666693
|
||||
d8c4177d24ccef970.14957924
|
||||
d8c4177d151affab2.81582771
|
||||
d8c4177d206a333d2.74422678
|
||||
d8c4177d225791924.30714721
|
||||
d8c4177d2380fc201.39666694
|
||||
d8c4177d24ccef970.14957925
|
||||
DROP TABLE t1;
|
||||
create table t1 (
|
||||
c1 char(10), c2 char(10), c3 char(10), c4 char(10),
|
||||
@ -1889,6 +1894,46 @@ AAA AAA AAA
|
||||
AAAA AAAA AAAA
|
||||
AAAAA AAAAA AAAAA
|
||||
DROP TABLE t1;
|
||||
#
|
||||
# mdev-4894: Poor performance with unnecessary
|
||||
# (bug#70021) 'Range checked for each record'
|
||||
#
|
||||
create table t1( key1 int not null, INDEX i1(key1) );
|
||||
insert into t1 values (1),(2),(3),(4),(5),(6),(7),(8);
|
||||
insert into t1 select key1+8 from t1;
|
||||
insert into t1 select key1+16 from t1;
|
||||
insert into t1 select key1+32 from t1;
|
||||
insert into t1 select key1+64 from t1;
|
||||
insert into t1 select key1+128 from t1;
|
||||
insert into t1 select key1+256 from t1;
|
||||
insert into t1 select key1+512 from t1;
|
||||
alter table t1 add key2 int not null, add index i2(key2);
|
||||
update t1 set key2=key1;
|
||||
analyze table t1;
|
||||
Table Op Msg_type Msg_text
|
||||
test.t1 analyze status OK
|
||||
create table t2 (a int);
|
||||
insert into t2 values (1),(2),(3),(4),(5),(6),(7),(8);
|
||||
insert into t2 select a+16 from t2;
|
||||
insert into t2 select a+32 from t2;
|
||||
insert into t2 select a+64 from t2;
|
||||
explain
|
||||
select count(*) from t2 left join t1 on (t1.key1 < 3 or t1.key1 > 1020) and t1.key2 < 1000;
|
||||
id select_type table type possible_keys key key_len ref rows Extra
|
||||
1 SIMPLE t2 ALL NULL NULL NULL NULL 64
|
||||
1 SIMPLE t1 range i1,i2 i1 4 NULL 78 Using where; Rowid-ordered scan; Using join buffer (flat, BNL join)
|
||||
select count(*) from t2 left join t1 on (t1.key1 < 3 or t1.key1 > 1020) and t1.key2 < 1000;
|
||||
count(*)
|
||||
128
|
||||
explain
|
||||
select count(*) from t2 left join t1 on (t1.key1 < 3 or t1.key1 > 1020) and t1.key2 < t2.a;
|
||||
id select_type table type possible_keys key key_len ref rows Extra
|
||||
1 SIMPLE t2 ALL NULL NULL NULL NULL 64
|
||||
1 SIMPLE t1 range i1,i2 i1 4 NULL 78 Using where; Rowid-ordered scan; Using join buffer (flat, BNL join)
|
||||
select count(*) from t2 left join t1 on (t1.key1 < 3 or t1.key1 > 1020) and t1.key2 < t2.a;
|
||||
count(*)
|
||||
126
|
||||
drop table t1,t2;
|
||||
End of 5.1 tests
|
||||
#
|
||||
# LP Bug #533117: Wrong use_count in SEL_ARG trees
|
||||
|
@ -4786,7 +4786,7 @@ id select_type table type possible_keys key key_len ref rows filtered Extra
|
||||
1 SIMPLE t2 system NULL NULL NULL NULL 1 100.00
|
||||
1 SIMPLE t1 ALL NULL NULL NULL NULL 10 100.00 Using where
|
||||
Warnings:
|
||||
Note 1003 select 2 AS `b`,`test`.`t1`.`a` AS `a` from `test`.`t1` where 1
|
||||
Note 1003 select 2 AS `b`,`test`.`t1`.`a` AS `a` from `test`.`t1`
|
||||
EXPLAIN EXTENDED SELECT * FROM t1 WHERE a > UNIX_TIMESTAMP('2009-03-10 00:00:00');
|
||||
id select_type table type possible_keys key key_len ref rows filtered Extra
|
||||
1 SIMPLE t1 ALL NULL NULL NULL NULL 10 100.00 Using where
|
||||
@ -5345,7 +5345,7 @@ a b c
|
||||
8 8 8
|
||||
DROP TABLE t1,t2;
|
||||
#
|
||||
# Bug mdev-4413: another manifestations of bug mdev-2474
|
||||
# Bug mdev-4413: another manifestations of bug mdev-4274
|
||||
# (valgrind complains)
|
||||
#
|
||||
CREATE TABLE t1 (a int, b int) ENGINE=MyISAM;
|
||||
@ -5357,4 +5357,72 @@ WHERE c = a AND
|
||||
( 0 OR ( b BETWEEN 45 AND 300 OR a > 45 AND a < 100 ) AND b = c );
|
||||
a b c
|
||||
DROP TABLE t1, t2;
|
||||
#
|
||||
# Bug mdev-4355: equalities from the result of simplification of OR
|
||||
# are not propagated to lower AND levels
|
||||
#
|
||||
CREATE TABLE t1 (a INT, b INT) ENGINE=MyISAM;
|
||||
INSERT INTO t1 VALUES (1,101),(2,102),(3,103),(4,104),(5,11);
|
||||
EXPLAIN EXTENDED
|
||||
SELECT * FROM t1 WHERE (1 != 1 OR a = 5) AND (b != 1 OR a = 1);
|
||||
id select_type table type possible_keys key key_len ref rows filtered Extra
|
||||
1 SIMPLE t1 ALL NULL NULL NULL NULL 5 100.00 Using where
|
||||
Warnings:
|
||||
Note 1003 select `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b` from `test`.`t1` where ((`test`.`t1`.`a` = 5) and (`test`.`t1`.`b` <> 1))
|
||||
SELECT * FROM t1 WHERE (1 != 1 OR a = 5) AND (b != 1 OR a = 1);
|
||||
a b
|
||||
5 11
|
||||
EXPLAIN EXTENDED
|
||||
SELECT * FROM t1 WHERE (b != 1 OR a = 1) AND (1 != 1 OR a = 5);
|
||||
id select_type table type possible_keys key key_len ref rows filtered Extra
|
||||
1 SIMPLE t1 ALL NULL NULL NULL NULL 5 100.00 Using where
|
||||
Warnings:
|
||||
Note 1003 select `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b` from `test`.`t1` where ((`test`.`t1`.`a` = 5) and (`test`.`t1`.`b` <> 1))
|
||||
SELECT * FROM t1 WHERE (b != 1 OR a = 1) AND (1 != 1 OR a = 5);
|
||||
a b
|
||||
5 11
|
||||
EXPLAIN EXTENDED
|
||||
SELECT * FROM t1 WHERE (b != 1 OR a = 1) AND (a = 5 OR 1 != 1);
|
||||
id select_type table type possible_keys key key_len ref rows filtered Extra
|
||||
1 SIMPLE t1 ALL NULL NULL NULL NULL 5 100.00 Using where
|
||||
Warnings:
|
||||
Note 1003 select `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b` from `test`.`t1` where ((`test`.`t1`.`a` = 5) and (`test`.`t1`.`b` <> 1))
|
||||
SELECT * FROM t1 WHERE (b != 1 OR a = 1) AND (a = 5 OR 1 != 1);
|
||||
a b
|
||||
5 11
|
||||
EXPLAIN EXTENDED
|
||||
SELECT * FROM t1 WHERE (b = 1 OR a = 1) AND (b = 5 AND a = 5 OR 1 != 1);
|
||||
id select_type table type possible_keys key key_len ref rows filtered Extra
|
||||
1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL Impossible WHERE
|
||||
Warnings:
|
||||
Note 1003 select `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b` from `test`.`t1` where 0
|
||||
SELECT * FROM t1 WHERE (b = 1 OR a = 1) AND (b = 5 AND a = 5 OR 1 != 1);
|
||||
a b
|
||||
EXPLAIN EXTENDED
|
||||
SELECT * FROM t1 WHERE (b = 1 OR a = 5) AND (b = 5 AND a = 5 OR 1 != 1);
|
||||
id select_type table type possible_keys key key_len ref rows filtered Extra
|
||||
1 SIMPLE t1 ALL NULL NULL NULL NULL 5 100.00 Using where
|
||||
Warnings:
|
||||
Note 1003 select `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b` from `test`.`t1` where ((`test`.`t1`.`b` = 5) and (`test`.`t1`.`a` = 5))
|
||||
SELECT * FROM t1 WHERE (b = 1 OR a = 5) AND (b = 5 AND a = 5 OR 1 != 1);
|
||||
a b
|
||||
DROP TABLE t1;
|
||||
#
|
||||
# Bug mdev-4418: impossible multiple equality in OR formula
|
||||
# after row substitution
|
||||
#
|
||||
CREATE TABLE t1 (a int, b varchar(1)) ENGINE=MyISAM;
|
||||
INSERT INTO t1 VALUES (0,'j'), (8,'v');
|
||||
CREATE TABLE t2 (c varchar(1), d varchar(1)) ENGINE=MyISAM;
|
||||
INSERT INTO t2 VALUES ('k','k');
|
||||
EXPLAIN EXTENDED
|
||||
SELECT * FROM t1, t2 WHERE c=b AND (1=2 OR ((b='h' OR a=136) AND d=b));
|
||||
id select_type table type possible_keys key key_len ref rows filtered Extra
|
||||
1 SIMPLE t2 system NULL NULL NULL NULL 1 100.00
|
||||
1 SIMPLE t1 ALL NULL NULL NULL NULL 2 100.00 Using where
|
||||
Warnings:
|
||||
Note 1003 select `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b`,'k' AS `c`,'k' AS `d` from `test`.`t1` where ((`test`.`t1`.`b` = 'k') and (`test`.`t1`.`a` = 136))
|
||||
SELECT * FROM t1, t2 WHERE c=b AND (1=2 OR ((b='h' OR a=136) AND d=b));
|
||||
a b c d
|
||||
DROP TABLE t1,t2;
|
||||
End of 5.3 tests
|
||||
|
@ -4797,7 +4797,7 @@ id select_type table type possible_keys key key_len ref rows filtered Extra
|
||||
1 SIMPLE t2 system NULL NULL NULL NULL 1 100.00
|
||||
1 SIMPLE t1 ALL NULL NULL NULL NULL 10 100.00 Using where
|
||||
Warnings:
|
||||
Note 1003 select 2 AS `b`,`test`.`t1`.`a` AS `a` from `test`.`t1` where 1
|
||||
Note 1003 select 2 AS `b`,`test`.`t1`.`a` AS `a` from `test`.`t1`
|
||||
EXPLAIN EXTENDED SELECT * FROM t1 WHERE a > UNIX_TIMESTAMP('2009-03-10 00:00:00');
|
||||
id select_type table type possible_keys key key_len ref rows filtered Extra
|
||||
1 SIMPLE t1 ALL NULL NULL NULL NULL 10 100.00 Using where
|
||||
@ -5356,7 +5356,7 @@ a b c
|
||||
8 8 8
|
||||
DROP TABLE t1,t2;
|
||||
#
|
||||
# Bug mdev-4413: another manifestations of bug mdev-2474
|
||||
# Bug mdev-4413: another manifestations of bug mdev-4274
|
||||
# (valgrind complains)
|
||||
#
|
||||
CREATE TABLE t1 (a int, b int) ENGINE=MyISAM;
|
||||
@ -5368,6 +5368,74 @@ WHERE c = a AND
|
||||
( 0 OR ( b BETWEEN 45 AND 300 OR a > 45 AND a < 100 ) AND b = c );
|
||||
a b c
|
||||
DROP TABLE t1, t2;
|
||||
#
|
||||
# Bug mdev-4355: equalities from the result of simplification of OR
|
||||
# are not propagated to lower AND levels
|
||||
#
|
||||
CREATE TABLE t1 (a INT, b INT) ENGINE=MyISAM;
|
||||
INSERT INTO t1 VALUES (1,101),(2,102),(3,103),(4,104),(5,11);
|
||||
EXPLAIN EXTENDED
|
||||
SELECT * FROM t1 WHERE (1 != 1 OR a = 5) AND (b != 1 OR a = 1);
|
||||
id select_type table type possible_keys key key_len ref rows filtered Extra
|
||||
1 SIMPLE t1 ALL NULL NULL NULL NULL 5 100.00 Using where
|
||||
Warnings:
|
||||
Note 1003 select `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b` from `test`.`t1` where ((`test`.`t1`.`a` = 5) and (`test`.`t1`.`b` <> 1))
|
||||
SELECT * FROM t1 WHERE (1 != 1 OR a = 5) AND (b != 1 OR a = 1);
|
||||
a b
|
||||
5 11
|
||||
EXPLAIN EXTENDED
|
||||
SELECT * FROM t1 WHERE (b != 1 OR a = 1) AND (1 != 1 OR a = 5);
|
||||
id select_type table type possible_keys key key_len ref rows filtered Extra
|
||||
1 SIMPLE t1 ALL NULL NULL NULL NULL 5 100.00 Using where
|
||||
Warnings:
|
||||
Note 1003 select `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b` from `test`.`t1` where ((`test`.`t1`.`a` = 5) and (`test`.`t1`.`b` <> 1))
|
||||
SELECT * FROM t1 WHERE (b != 1 OR a = 1) AND (1 != 1 OR a = 5);
|
||||
a b
|
||||
5 11
|
||||
EXPLAIN EXTENDED
|
||||
SELECT * FROM t1 WHERE (b != 1 OR a = 1) AND (a = 5 OR 1 != 1);
|
||||
id select_type table type possible_keys key key_len ref rows filtered Extra
|
||||
1 SIMPLE t1 ALL NULL NULL NULL NULL 5 100.00 Using where
|
||||
Warnings:
|
||||
Note 1003 select `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b` from `test`.`t1` where ((`test`.`t1`.`a` = 5) and (`test`.`t1`.`b` <> 1))
|
||||
SELECT * FROM t1 WHERE (b != 1 OR a = 1) AND (a = 5 OR 1 != 1);
|
||||
a b
|
||||
5 11
|
||||
EXPLAIN EXTENDED
|
||||
SELECT * FROM t1 WHERE (b = 1 OR a = 1) AND (b = 5 AND a = 5 OR 1 != 1);
|
||||
id select_type table type possible_keys key key_len ref rows filtered Extra
|
||||
1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL Impossible WHERE
|
||||
Warnings:
|
||||
Note 1003 select `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b` from `test`.`t1` where 0
|
||||
SELECT * FROM t1 WHERE (b = 1 OR a = 1) AND (b = 5 AND a = 5 OR 1 != 1);
|
||||
a b
|
||||
EXPLAIN EXTENDED
|
||||
SELECT * FROM t1 WHERE (b = 1 OR a = 5) AND (b = 5 AND a = 5 OR 1 != 1);
|
||||
id select_type table type possible_keys key key_len ref rows filtered Extra
|
||||
1 SIMPLE t1 ALL NULL NULL NULL NULL 5 100.00 Using where
|
||||
Warnings:
|
||||
Note 1003 select `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b` from `test`.`t1` where ((`test`.`t1`.`b` = 5) and (`test`.`t1`.`a` = 5))
|
||||
SELECT * FROM t1 WHERE (b = 1 OR a = 5) AND (b = 5 AND a = 5 OR 1 != 1);
|
||||
a b
|
||||
DROP TABLE t1;
|
||||
#
|
||||
# Bug mdev-4418: impossible multiple equality in OR formula
|
||||
# after row substitution
|
||||
#
|
||||
CREATE TABLE t1 (a int, b varchar(1)) ENGINE=MyISAM;
|
||||
INSERT INTO t1 VALUES (0,'j'), (8,'v');
|
||||
CREATE TABLE t2 (c varchar(1), d varchar(1)) ENGINE=MyISAM;
|
||||
INSERT INTO t2 VALUES ('k','k');
|
||||
EXPLAIN EXTENDED
|
||||
SELECT * FROM t1, t2 WHERE c=b AND (1=2 OR ((b='h' OR a=136) AND d=b));
|
||||
id select_type table type possible_keys key key_len ref rows filtered Extra
|
||||
1 SIMPLE t2 system NULL NULL NULL NULL 1 100.00
|
||||
1 SIMPLE t1 ALL NULL NULL NULL NULL 2 100.00 Using where
|
||||
Warnings:
|
||||
Note 1003 select `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b`,'k' AS `c`,'k' AS `d` from `test`.`t1` where ((`test`.`t1`.`b` = 'k') and (`test`.`t1`.`a` = 136))
|
||||
SELECT * FROM t1, t2 WHERE c=b AND (1=2 OR ((b='h' OR a=136) AND d=b));
|
||||
a b c d
|
||||
DROP TABLE t1,t2;
|
||||
End of 5.3 tests
|
||||
set join_cache_level=default;
|
||||
show variables like 'join_cache_level';
|
||||
|
@ -4786,7 +4786,7 @@ id select_type table type possible_keys key key_len ref rows filtered Extra
|
||||
1 SIMPLE t2 system NULL NULL NULL NULL 1 100.00
|
||||
1 SIMPLE t1 ALL NULL NULL NULL NULL 10 100.00 Using where
|
||||
Warnings:
|
||||
Note 1003 select 2 AS `b`,`test`.`t1`.`a` AS `a` from `test`.`t1` where 1
|
||||
Note 1003 select 2 AS `b`,`test`.`t1`.`a` AS `a` from `test`.`t1`
|
||||
EXPLAIN EXTENDED SELECT * FROM t1 WHERE a > UNIX_TIMESTAMP('2009-03-10 00:00:00');
|
||||
id select_type table type possible_keys key key_len ref rows filtered Extra
|
||||
1 SIMPLE t1 ALL NULL NULL NULL NULL 10 100.00 Using where
|
||||
@ -5345,7 +5345,7 @@ a b c
|
||||
8 8 8
|
||||
DROP TABLE t1,t2;
|
||||
#
|
||||
# Bug mdev-4413: another manifestations of bug mdev-2474
|
||||
# Bug mdev-4413: another manifestations of bug mdev-4274
|
||||
# (valgrind complains)
|
||||
#
|
||||
CREATE TABLE t1 (a int, b int) ENGINE=MyISAM;
|
||||
@ -5357,4 +5357,72 @@ WHERE c = a AND
|
||||
( 0 OR ( b BETWEEN 45 AND 300 OR a > 45 AND a < 100 ) AND b = c );
|
||||
a b c
|
||||
DROP TABLE t1, t2;
|
||||
#
|
||||
# Bug mdev-4355: equalities from the result of simplification of OR
|
||||
# are not propagated to lower AND levels
|
||||
#
|
||||
CREATE TABLE t1 (a INT, b INT) ENGINE=MyISAM;
|
||||
INSERT INTO t1 VALUES (1,101),(2,102),(3,103),(4,104),(5,11);
|
||||
EXPLAIN EXTENDED
|
||||
SELECT * FROM t1 WHERE (1 != 1 OR a = 5) AND (b != 1 OR a = 1);
|
||||
id select_type table type possible_keys key key_len ref rows filtered Extra
|
||||
1 SIMPLE t1 ALL NULL NULL NULL NULL 5 100.00 Using where
|
||||
Warnings:
|
||||
Note 1003 select `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b` from `test`.`t1` where ((`test`.`t1`.`a` = 5) and (`test`.`t1`.`b` <> 1))
|
||||
SELECT * FROM t1 WHERE (1 != 1 OR a = 5) AND (b != 1 OR a = 1);
|
||||
a b
|
||||
5 11
|
||||
EXPLAIN EXTENDED
|
||||
SELECT * FROM t1 WHERE (b != 1 OR a = 1) AND (1 != 1 OR a = 5);
|
||||
id select_type table type possible_keys key key_len ref rows filtered Extra
|
||||
1 SIMPLE t1 ALL NULL NULL NULL NULL 5 100.00 Using where
|
||||
Warnings:
|
||||
Note 1003 select `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b` from `test`.`t1` where ((`test`.`t1`.`a` = 5) and (`test`.`t1`.`b` <> 1))
|
||||
SELECT * FROM t1 WHERE (b != 1 OR a = 1) AND (1 != 1 OR a = 5);
|
||||
a b
|
||||
5 11
|
||||
EXPLAIN EXTENDED
|
||||
SELECT * FROM t1 WHERE (b != 1 OR a = 1) AND (a = 5 OR 1 != 1);
|
||||
id select_type table type possible_keys key key_len ref rows filtered Extra
|
||||
1 SIMPLE t1 ALL NULL NULL NULL NULL 5 100.00 Using where
|
||||
Warnings:
|
||||
Note 1003 select `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b` from `test`.`t1` where ((`test`.`t1`.`a` = 5) and (`test`.`t1`.`b` <> 1))
|
||||
SELECT * FROM t1 WHERE (b != 1 OR a = 1) AND (a = 5 OR 1 != 1);
|
||||
a b
|
||||
5 11
|
||||
EXPLAIN EXTENDED
|
||||
SELECT * FROM t1 WHERE (b = 1 OR a = 1) AND (b = 5 AND a = 5 OR 1 != 1);
|
||||
id select_type table type possible_keys key key_len ref rows filtered Extra
|
||||
1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL Impossible WHERE
|
||||
Warnings:
|
||||
Note 1003 select `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b` from `test`.`t1` where 0
|
||||
SELECT * FROM t1 WHERE (b = 1 OR a = 1) AND (b = 5 AND a = 5 OR 1 != 1);
|
||||
a b
|
||||
EXPLAIN EXTENDED
|
||||
SELECT * FROM t1 WHERE (b = 1 OR a = 5) AND (b = 5 AND a = 5 OR 1 != 1);
|
||||
id select_type table type possible_keys key key_len ref rows filtered Extra
|
||||
1 SIMPLE t1 ALL NULL NULL NULL NULL 5 100.00 Using where
|
||||
Warnings:
|
||||
Note 1003 select `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b` from `test`.`t1` where ((`test`.`t1`.`b` = 5) and (`test`.`t1`.`a` = 5))
|
||||
SELECT * FROM t1 WHERE (b = 1 OR a = 5) AND (b = 5 AND a = 5 OR 1 != 1);
|
||||
a b
|
||||
DROP TABLE t1;
|
||||
#
|
||||
# Bug mdev-4418: impossible multiple equality in OR formula
|
||||
# after row substitution
|
||||
#
|
||||
CREATE TABLE t1 (a int, b varchar(1)) ENGINE=MyISAM;
|
||||
INSERT INTO t1 VALUES (0,'j'), (8,'v');
|
||||
CREATE TABLE t2 (c varchar(1), d varchar(1)) ENGINE=MyISAM;
|
||||
INSERT INTO t2 VALUES ('k','k');
|
||||
EXPLAIN EXTENDED
|
||||
SELECT * FROM t1, t2 WHERE c=b AND (1=2 OR ((b='h' OR a=136) AND d=b));
|
||||
id select_type table type possible_keys key key_len ref rows filtered Extra
|
||||
1 SIMPLE t2 system NULL NULL NULL NULL 1 100.00
|
||||
1 SIMPLE t1 ALL NULL NULL NULL NULL 2 100.00 Using where
|
||||
Warnings:
|
||||
Note 1003 select `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b`,'k' AS `c`,'k' AS `d` from `test`.`t1` where ((`test`.`t1`.`b` = 'k') and (`test`.`t1`.`a` = 136))
|
||||
SELECT * FROM t1, t2 WHERE c=b AND (1=2 OR ((b='h' OR a=136) AND d=b));
|
||||
a b c d
|
||||
DROP TABLE t1,t2;
|
||||
End of 5.3 tests
|
||||
|
@ -1319,7 +1319,7 @@ id select_type table type possible_keys key key_len ref rows filtered Extra
|
||||
1 PRIMARY NULL NULL NULL NULL NULL NULL NULL NULL No tables used
|
||||
2 SUBQUERY NULL NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables
|
||||
Warnings:
|
||||
Note 1003 select <in_optimizer>(0,<exists>(select 1 from dual where (0 = 1))) AS `0 IN (SELECT 1 FROM t1 a)`
|
||||
Note 1003 select <in_optimizer>(0,<exists>(select 1 from dual where 0)) AS `0 IN (SELECT 1 FROM t1 a)`
|
||||
INSERT INTO t1 (pseudo) VALUES ('test1');
|
||||
SELECT 0 IN (SELECT 1 FROM t1 a);
|
||||
0 IN (SELECT 1 FROM t1 a)
|
||||
|
@ -1750,7 +1750,7 @@ SET @@optimizer_switch = 'in_to_exists=on,materialization=off,semijoin=off';
|
||||
EXPLAIN SELECT * FROM t1 WHERE a1 IN (SELECT b1 FROM t2 WHERE b1 = b2);
|
||||
id select_type table type possible_keys key key_len ref rows Extra
|
||||
1 PRIMARY t1 ALL NULL NULL NULL NULL 2 Using where
|
||||
2 DEPENDENT SUBQUERY NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables
|
||||
2 SUBQUERY NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables
|
||||
SELECT * FROM t1 WHERE a1 IN (SELECT b1 FROM t2 WHERE b1 = b2);
|
||||
a1 a2
|
||||
set @@optimizer_switch=@save_optimizer_switch;
|
||||
|
@ -1326,7 +1326,7 @@ id select_type table type possible_keys key key_len ref rows filtered Extra
|
||||
1 PRIMARY NULL NULL NULL NULL NULL NULL NULL NULL No tables used
|
||||
2 SUBQUERY NULL NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables
|
||||
Warnings:
|
||||
Note 1003 select <in_optimizer>(0,<exists>(select 1 from dual where (0 = 1))) AS `0 IN (SELECT 1 FROM t1 a)`
|
||||
Note 1003 select <in_optimizer>(0,<exists>(select 1 from dual where 0)) AS `0 IN (SELECT 1 FROM t1 a)`
|
||||
INSERT INTO t1 (pseudo) VALUES ('test1');
|
||||
SELECT 0 IN (SELECT 1 FROM t1 a);
|
||||
0 IN (SELECT 1 FROM t1 a)
|
||||
|
@ -1322,7 +1322,7 @@ id select_type table type possible_keys key key_len ref rows filtered Extra
|
||||
1 PRIMARY NULL NULL NULL NULL NULL NULL NULL NULL No tables used
|
||||
2 SUBQUERY NULL NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables
|
||||
Warnings:
|
||||
Note 1003 select <in_optimizer>(0,<exists>(select 1 from dual where (0 = 1))) AS `0 IN (SELECT 1 FROM t1 a)`
|
||||
Note 1003 select <in_optimizer>(0,<exists>(select 1 from dual where 0)) AS `0 IN (SELECT 1 FROM t1 a)`
|
||||
INSERT INTO t1 (pseudo) VALUES ('test1');
|
||||
SELECT 0 IN (SELECT 1 FROM t1 a);
|
||||
0 IN (SELECT 1 FROM t1 a)
|
||||
|
@ -1325,7 +1325,7 @@ id select_type table type possible_keys key key_len ref rows filtered Extra
|
||||
1 PRIMARY NULL NULL NULL NULL NULL NULL NULL NULL No tables used
|
||||
2 SUBQUERY NULL NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables
|
||||
Warnings:
|
||||
Note 1003 select <in_optimizer>(0,<exists>(select 1 from dual where (0 = 1))) AS `0 IN (SELECT 1 FROM t1 a)`
|
||||
Note 1003 select <in_optimizer>(0,<exists>(select 1 from dual where 0)) AS `0 IN (SELECT 1 FROM t1 a)`
|
||||
INSERT INTO t1 (pseudo) VALUES ('test1');
|
||||
SELECT 0 IN (SELECT 1 FROM t1 a);
|
||||
0 IN (SELECT 1 FROM t1 a)
|
||||
|
@ -1322,7 +1322,7 @@ id select_type table type possible_keys key key_len ref rows filtered Extra
|
||||
1 PRIMARY NULL NULL NULL NULL NULL NULL NULL NULL No tables used
|
||||
2 SUBQUERY NULL NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables
|
||||
Warnings:
|
||||
Note 1003 select <in_optimizer>(0,<exists>(select 1 from dual where (0 = 1))) AS `0 IN (SELECT 1 FROM t1 a)`
|
||||
Note 1003 select <in_optimizer>(0,<exists>(select 1 from dual where 0)) AS `0 IN (SELECT 1 FROM t1 a)`
|
||||
INSERT INTO t1 (pseudo) VALUES ('test1');
|
||||
SELECT 0 IN (SELECT 1 FROM t1 a);
|
||||
0 IN (SELECT 1 FROM t1 a)
|
||||
|
@ -1399,7 +1399,7 @@ id select_type table type possible_keys key key_len ref rows filtered Extra
|
||||
2 MATERIALIZED t2 ALL NULL NULL NULL NULL 2 100.00 Using where
|
||||
2 MATERIALIZED t3 hash_ALL NULL #hash#$hj 5 test.t2.i2 3 100.00 Using where; Using join buffer (flat, BNLH join)
|
||||
Warnings:
|
||||
Note 1003 select `test`.`t1`.`i1` AS `i1` from `test`.`t1` semi join (`test`.`t2` join `test`.`t3`) where ((`test`.`t3`.`i3` = `test`.`t2`.`i2`) and (`test`.`t1`.`i1` = `test`.`t2`.`i2`) and (`test`.`t2`.`i2` > 0))
|
||||
Note 1003 select `test`.`t1`.`i1` AS `i1` from `test`.`t1` semi join (`test`.`t2` join `test`.`t3`) where ((`test`.`t3`.`i3` = `test`.`t2`.`i2`) and (`test`.`t1`.`i1` = `test`.`t2`.`i2`) and (`test`.`t3`.`i3` > 0))
|
||||
SELECT * FROM t1
|
||||
WHERE i1 IN (SELECT i3 FROM t2, t3 WHERE i3 > 0 AND i3 = i2 OR 1=2);
|
||||
i1
|
||||
|
@ -17,7 +17,7 @@ explain extended select t1.a from t1 left join t2 on t2.a=t1.a;
|
||||
id select_type table type possible_keys key key_len ref rows filtered Extra
|
||||
1 SIMPLE t1 ALL NULL NULL NULL NULL 4 100.00
|
||||
Warnings:
|
||||
Note 1003 select `test`.`t1`.`a` AS `a` from `test`.`t1` where 1
|
||||
Note 1003 select `test`.`t1`.`a` AS `a` from `test`.`t1`
|
||||
select t1.a from t1 left join t2 on t2.a=t1.a;
|
||||
a
|
||||
0
|
||||
@ -62,7 +62,7 @@ id select_type table type possible_keys key key_len ref rows filtered Extra
|
||||
1 SIMPLE t0 ALL NULL NULL NULL NULL 4 100.00
|
||||
1 SIMPLE t1 ALL NULL NULL NULL NULL 4 100.00 Using where
|
||||
Warnings:
|
||||
Note 1003 select `test`.`t0`.`a` AS `a` from `test`.`t0` left join (`test`.`t1`) on((`test`.`t1`.`a` = `test`.`t0`.`a`)) where 1
|
||||
Note 1003 select `test`.`t0`.`a` AS `a` from `test`.`t0` left join (`test`.`t1`) on((`test`.`t1`.`a` = `test`.`t0`.`a`))
|
||||
# Elimination with aggregate functions
|
||||
explain select count(*) from t1 left join t2 on t2.a=t1.a;
|
||||
id select_type table type possible_keys key key_len ref rows Extra
|
||||
@ -626,6 +626,6 @@ id select_type table type possible_keys key key_len ref rows filtered Extra
|
||||
1 PRIMARY t2 index NULL b 5 NULL 2 100.00 Using where; Using index
|
||||
2 DEPENDENT SUBQUERY t1 system NULL NULL NULL NULL 1 100.00
|
||||
Warnings:
|
||||
Note 1003 select `test`.`t2`.`b` AS `b` from `test`.`t2` where <expr_cache><`test`.`t2`.`b`>(<in_optimizer>(`test`.`t2`.`b`,<exists>(select sum(1) from dual where 1 having (<cache>(`test`.`t2`.`b`) = <ref_null_helper>(sum(1))))))
|
||||
Note 1003 select `test`.`t2`.`b` AS `b` from `test`.`t2` where <expr_cache><`test`.`t2`.`b`>(<in_optimizer>(`test`.`t2`.`b`,<exists>(select sum(1) from dual having (<cache>(`test`.`t2`.`b`) = <ref_null_helper>(sum(1))))))
|
||||
DROP TABLE t1,t2;
|
||||
SET optimizer_switch=@save_optimizer_switch;
|
||||
|
@ -4417,7 +4417,7 @@ WHERE f1<>0 OR f2<>0 AND f4='v' AND (f2<>0 OR f3<>0 AND f5<>0 OR f4 LIKE '%b%');
|
||||
id select_type table type possible_keys key key_len ref rows filtered Extra
|
||||
1 SIMPLE t1 system NULL NULL NULL NULL 1 100.00
|
||||
Warnings:
|
||||
Note 1003 select 'r' AS `f4` from dual where ((20 <> 0) or 0)
|
||||
Note 1003 select 'r' AS `f4` from dual where (20 <> 0)
|
||||
DROP VIEW v1;
|
||||
DROP TABLE t1;
|
||||
#
|
||||
|
@ -197,6 +197,13 @@ SELECT COUNT(*) FROM t1;
|
||||
COUNT(*)
|
||||
2
|
||||
DROP TABLE t1;
|
||||
#
|
||||
# MDEV-4823 Server crashes in Item_func_not::fix_fields on
|
||||
# creating a table with a virtual column using NOT
|
||||
#
|
||||
CREATE TABLE t1 ( f1 INT, v4 INT AS ( NOT f1 ) VIRTUAL );
|
||||
drop table t1;
|
||||
# end of 5.2 tests
|
||||
create table t1 (a int, b int);
|
||||
insert into t1 values (3, 30), (4, 20), (1, 20);
|
||||
create table t2 (c int, d int, v int as (d+1), index idx(c));
|
||||
@ -309,3 +316,4 @@ ERROR HY000: The value specified for computed column 'd' in table 't1' ignored
|
||||
INSERT INTO `test`.`t1`(`a`,`b`,`c`,`d`) VALUES ( '1','a',NULL,'a');
|
||||
ERROR HY000: The value specified for computed column 'd' in table 't1' ignored
|
||||
drop table t1;
|
||||
# end of 5.3 tests
|
||||
|
@ -197,6 +197,15 @@ SELECT COUNT(*) FROM t1;
|
||||
|
||||
DROP TABLE t1;
|
||||
|
||||
--echo #
|
||||
--echo # MDEV-4823 Server crashes in Item_func_not::fix_fields on
|
||||
--echo # creating a table with a virtual column using NOT
|
||||
--echo #
|
||||
CREATE TABLE t1 ( f1 INT, v4 INT AS ( NOT f1 ) VIRTUAL );
|
||||
drop table t1;
|
||||
|
||||
--echo # end of 5.2 tests
|
||||
|
||||
#
|
||||
# SELECT that uses a virtual column and executed with BKA
|
||||
#
|
||||
@ -265,3 +274,5 @@ UPDATE `test`.`t1` SET `d`='b' WHERE `a`='1' AND `b`='a' AND `c`='1' AND `d`='a
|
||||
--error ER_WARNING_NON_DEFAULT_VALUE_FOR_VIRTUAL_COLUMN
|
||||
INSERT INTO `test`.`t1`(`a`,`b`,`c`,`d`) VALUES ( '1','a',NULL,'a');
|
||||
drop table t1;
|
||||
|
||||
--echo # end of 5.3 tests
|
||||
|
@ -570,12 +570,12 @@ INSERT INTO t1 VALUES
|
||||
|
||||
EXPLAIN
|
||||
SELECT s.oxid FROM t1 v, t1 s
|
||||
WHERE s.oxrootid = 'd8c4177d09f8b11f5.52725521' AND
|
||||
WHERE
|
||||
v.oxrootid ='d8c4177d09f8b11f5.52725521' AND
|
||||
s.oxleft > v.oxleft AND s.oxleft < v.oxright;
|
||||
|
||||
SELECT s.oxid FROM t1 v, t1 s
|
||||
WHERE s.oxrootid = 'd8c4177d09f8b11f5.52725521' AND
|
||||
WHERE
|
||||
v.oxrootid ='d8c4177d09f8b11f5.52725521' AND
|
||||
s.oxleft > v.oxleft AND s.oxleft < v.oxright;
|
||||
|
||||
@ -1481,6 +1481,40 @@ SELECT * FROM t1 IGNORE INDEX(PRIMARY) WHERE F1 BETWEEN 'A ' AND
|
||||
|
||||
DROP TABLE t1;
|
||||
|
||||
--echo #
|
||||
--echo # mdev-4894: Poor performance with unnecessary
|
||||
--echo # (bug#70021) 'Range checked for each record'
|
||||
--echo #
|
||||
|
||||
create table t1( key1 int not null, INDEX i1(key1) );
|
||||
insert into t1 values (1),(2),(3),(4),(5),(6),(7),(8);
|
||||
insert into t1 select key1+8 from t1;
|
||||
insert into t1 select key1+16 from t1;
|
||||
insert into t1 select key1+32 from t1;
|
||||
insert into t1 select key1+64 from t1;
|
||||
insert into t1 select key1+128 from t1;
|
||||
insert into t1 select key1+256 from t1;
|
||||
insert into t1 select key1+512 from t1;
|
||||
|
||||
alter table t1 add key2 int not null, add index i2(key2);
|
||||
update t1 set key2=key1;
|
||||
analyze table t1;
|
||||
|
||||
create table t2 (a int);
|
||||
insert into t2 values (1),(2),(3),(4),(5),(6),(7),(8);
|
||||
insert into t2 select a+16 from t2;
|
||||
insert into t2 select a+32 from t2;
|
||||
insert into t2 select a+64 from t2;
|
||||
|
||||
explain
|
||||
select count(*) from t2 left join t1 on (t1.key1 < 3 or t1.key1 > 1020) and t1.key2 < 1000;
|
||||
select count(*) from t2 left join t1 on (t1.key1 < 3 or t1.key1 > 1020) and t1.key2 < 1000;
|
||||
explain
|
||||
select count(*) from t2 left join t1 on (t1.key1 < 3 or t1.key1 > 1020) and t1.key2 < t2.a;
|
||||
select count(*) from t2 left join t1 on (t1.key1 < 3 or t1.key1 > 1020) and t1.key2 < t2.a;
|
||||
|
||||
drop table t1,t2;
|
||||
|
||||
--echo End of 5.1 tests
|
||||
|
||||
--echo #
|
||||
|
@ -4500,7 +4500,7 @@ SELECT * FROM t1 INNER JOIN t2 ON ( c = a )
|
||||
DROP TABLE t1,t2;
|
||||
|
||||
--echo #
|
||||
--echo # Bug mdev-4413: another manifestations of bug mdev-2474
|
||||
--echo # Bug mdev-4413: another manifestations of bug mdev-4274
|
||||
--echo # (valgrind complains)
|
||||
--echo #
|
||||
|
||||
@ -4516,5 +4516,52 @@ SELECT * FROM t1, t2
|
||||
|
||||
DROP TABLE t1, t2;
|
||||
|
||||
--echo #
|
||||
--echo # Bug mdev-4355: equalities from the result of simplification of OR
|
||||
--echo # are not propagated to lower AND levels
|
||||
--echo #
|
||||
|
||||
CREATE TABLE t1 (a INT, b INT) ENGINE=MyISAM;
|
||||
INSERT INTO t1 VALUES (1,101),(2,102),(3,103),(4,104),(5,11);
|
||||
|
||||
EXPLAIN EXTENDED
|
||||
SELECT * FROM t1 WHERE (1 != 1 OR a = 5) AND (b != 1 OR a = 1);
|
||||
SELECT * FROM t1 WHERE (1 != 1 OR a = 5) AND (b != 1 OR a = 1);
|
||||
|
||||
EXPLAIN EXTENDED
|
||||
SELECT * FROM t1 WHERE (b != 1 OR a = 1) AND (1 != 1 OR a = 5);
|
||||
SELECT * FROM t1 WHERE (b != 1 OR a = 1) AND (1 != 1 OR a = 5);
|
||||
|
||||
EXPLAIN EXTENDED
|
||||
SELECT * FROM t1 WHERE (b != 1 OR a = 1) AND (a = 5 OR 1 != 1);
|
||||
SELECT * FROM t1 WHERE (b != 1 OR a = 1) AND (a = 5 OR 1 != 1);
|
||||
|
||||
EXPLAIN EXTENDED
|
||||
SELECT * FROM t1 WHERE (b = 1 OR a = 1) AND (b = 5 AND a = 5 OR 1 != 1);
|
||||
SELECT * FROM t1 WHERE (b = 1 OR a = 1) AND (b = 5 AND a = 5 OR 1 != 1);
|
||||
|
||||
EXPLAIN EXTENDED
|
||||
SELECT * FROM t1 WHERE (b = 1 OR a = 5) AND (b = 5 AND a = 5 OR 1 != 1);
|
||||
SELECT * FROM t1 WHERE (b = 1 OR a = 5) AND (b = 5 AND a = 5 OR 1 != 1);
|
||||
|
||||
DROP TABLE t1;
|
||||
|
||||
--echo #
|
||||
--echo # Bug mdev-4418: impossible multiple equality in OR formula
|
||||
--echo # after row substitution
|
||||
--echo #
|
||||
|
||||
CREATE TABLE t1 (a int, b varchar(1)) ENGINE=MyISAM;
|
||||
INSERT INTO t1 VALUES (0,'j'), (8,'v');
|
||||
|
||||
CREATE TABLE t2 (c varchar(1), d varchar(1)) ENGINE=MyISAM;
|
||||
INSERT INTO t2 VALUES ('k','k');
|
||||
|
||||
EXPLAIN EXTENDED
|
||||
SELECT * FROM t1, t2 WHERE c=b AND (1=2 OR ((b='h' OR a=136) AND d=b));
|
||||
SELECT * FROM t1, t2 WHERE c=b AND (1=2 OR ((b='h' OR a=136) AND d=b));
|
||||
|
||||
DROP TABLE t1,t2;
|
||||
|
||||
--echo End of 5.3 tests
|
||||
|
||||
|
@ -5739,9 +5739,11 @@ void Item_equal::merge(Item_equal *item)
|
||||
Merge members of another Item_equal object into this one
|
||||
|
||||
@param item multiple equality whose members are to be merged
|
||||
@param save_merged keep the list of equalities in 'item' intact
|
||||
(e.g. for other merges)
|
||||
|
||||
@details
|
||||
If the Item_equal 'item' happened to have some elements of the list
|
||||
If the Item_equal 'item' happens to have some elements of the list
|
||||
of equal items belonging to 'this' object then the function merges
|
||||
the equal items from 'item' into this list.
|
||||
If both lists contains constants and they are different then
|
||||
@ -5756,24 +5758,45 @@ void Item_equal::merge(Item_equal *item)
|
||||
The method 'merge' just joins the list of equal items belonging to 'item'
|
||||
to the list of equal items belonging to this object assuming that the lists
|
||||
are disjoint. It would be more correct to call the method 'join'.
|
||||
The method 'merge_with_check' really merges two lists of equal items if they
|
||||
have common members.
|
||||
The method 'merge_into_with_check' really merges two lists of equal items if
|
||||
they have common members.
|
||||
*/
|
||||
|
||||
bool Item_equal::merge_with_check(Item_equal *item)
|
||||
bool Item_equal::merge_with_check(Item_equal *item, bool save_merged)
|
||||
{
|
||||
bool intersected= FALSE;
|
||||
Item_equal_fields_iterator_slow fi(*this);
|
||||
Item_equal_fields_iterator_slow fi(*item);
|
||||
|
||||
while (fi++)
|
||||
{
|
||||
if (item->contains(fi.get_curr_field()))
|
||||
if (contains(fi.get_curr_field()))
|
||||
{
|
||||
fi.remove();
|
||||
intersected= TRUE;
|
||||
if (!save_merged)
|
||||
fi.remove();
|
||||
}
|
||||
}
|
||||
if (intersected)
|
||||
item->merge(this);
|
||||
{
|
||||
if (!save_merged)
|
||||
merge(item);
|
||||
else
|
||||
{
|
||||
Item *c= item->get_const();
|
||||
if (c)
|
||||
add_const(c);
|
||||
if (!cond_false)
|
||||
{
|
||||
Item *item;
|
||||
fi.rewind();
|
||||
while ((item= fi++))
|
||||
{
|
||||
if (!contains(fi.get_curr_field()))
|
||||
add(item);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return intersected;
|
||||
}
|
||||
|
||||
@ -5783,16 +5806,24 @@ bool Item_equal::merge_with_check(Item_equal *item)
|
||||
Merge this object into a list of Item_equal objects
|
||||
|
||||
@param list the list of Item_equal objects to merge into
|
||||
@param save_merged keep the list of equalities in 'this' intact
|
||||
(e.g. for other merges)
|
||||
@param only_intersected do not merge if there are no common members
|
||||
in any of Item_equal objects from the list
|
||||
and this Item_equal
|
||||
|
||||
@details
|
||||
If the list of equal items from 'this' object contains common members
|
||||
with the lists of equal items belonging to Item_equal objects from 'list'
|
||||
then all involved Item_equal objects e1,...,ek are merged into one
|
||||
Item equal that replaces e1,...,ek in the 'list'. Otherwise this
|
||||
Item equal that replaces e1,...,ek in the 'list'. Otherwise, in the case
|
||||
when the value of the parameter only_if_intersected is false, this
|
||||
Item_equal is joined to the 'list'.
|
||||
*/
|
||||
|
||||
void Item_equal::merge_into_list(List<Item_equal> *list)
|
||||
void Item_equal::merge_into_list(List<Item_equal> *list,
|
||||
bool save_merged,
|
||||
bool only_intersected)
|
||||
{
|
||||
Item_equal *item;
|
||||
List_iterator<Item_equal> it(*list);
|
||||
@ -5801,16 +5832,16 @@ void Item_equal::merge_into_list(List<Item_equal> *list)
|
||||
{
|
||||
if (!merge_into)
|
||||
{
|
||||
if (merge_with_check(item))
|
||||
if (item->merge_with_check(this, save_merged))
|
||||
merge_into= item;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (item->merge_with_check(merge_into))
|
||||
if (merge_into->merge_with_check(item, false))
|
||||
it.remove();
|
||||
}
|
||||
}
|
||||
if (!merge_into)
|
||||
if (!only_intersected && !merge_into)
|
||||
list->push_back(this);
|
||||
}
|
||||
|
||||
|
@ -1754,8 +1754,9 @@ public:
|
||||
/** Get number of field items / references to field items in this object */
|
||||
uint n_field_items() { return equal_items.elements-test(with_const); }
|
||||
void merge(Item_equal *item);
|
||||
bool merge_with_check(Item_equal *equal_item);
|
||||
void merge_into_list(List<Item_equal> *list);
|
||||
bool merge_with_check(Item_equal *equal_item, bool save_merged);
|
||||
void merge_into_list(List<Item_equal> *list, bool save_merged,
|
||||
bool only_intersected);
|
||||
void update_const();
|
||||
enum Functype functype() const { return MULT_EQUAL_FUNC; }
|
||||
longlong val_int();
|
||||
|
@ -447,19 +447,18 @@ const char *Geometry::append_points(String *txt, uint32 n_points,
|
||||
const char *Geometry::get_mbr_for_points(MBR *mbr, const char *data,
|
||||
uint offset) const
|
||||
{
|
||||
uint32 n_points;
|
||||
uint32 points;
|
||||
/* read number of points */
|
||||
if (no_data(data, 4))
|
||||
return 0;
|
||||
n_points= uint4korr(data);
|
||||
points= uint4korr(data);
|
||||
data+= 4;
|
||||
|
||||
if (n_points > max_n_points ||
|
||||
no_data(data, (POINT_DATA_SIZE + offset) * n_points))
|
||||
if (not_enough_points(data, points, offset))
|
||||
return 0;
|
||||
|
||||
/* Calculate MBR for points */
|
||||
while (n_points--)
|
||||
while (points--)
|
||||
{
|
||||
data+= offset;
|
||||
mbr->add_xy(data, data + SIZEOF_STORED_DOUBLE);
|
||||
@ -563,12 +562,16 @@ const Geometry::Class_info *Gis_point::get_class_info() const
|
||||
|
||||
uint32 Gis_line_string::get_data_size() const
|
||||
{
|
||||
uint32 n_points, size;
|
||||
if (no_data(m_data, 4) ||
|
||||
(n_points= uint4korr(m_data)) > max_n_points ||
|
||||
no_data(m_data, (size= 4 + n_points * POINT_DATA_SIZE)))
|
||||
uint32 n_points;
|
||||
if (no_data(m_data, 4))
|
||||
return GET_SIZE_ERROR;
|
||||
return size;
|
||||
|
||||
n_points= uint4korr(m_data);
|
||||
|
||||
if (not_enough_points(m_data + 4, n_points))
|
||||
return GET_SIZE_ERROR;
|
||||
|
||||
return 4 + n_points * POINT_DATA_SIZE;
|
||||
}
|
||||
|
||||
|
||||
@ -607,9 +610,8 @@ uint Gis_line_string::init_from_wkb(const char *wkb, uint len,
|
||||
const char *wkb_end;
|
||||
Gis_point p;
|
||||
|
||||
if (len < 4 ||
|
||||
(n_points= wkb_get_uint(wkb, bo)) < 1 ||
|
||||
n_points > max_n_points)
|
||||
if (len < 4 || (n_points= wkb_get_uint(wkb, bo)) < 1 ||
|
||||
((len - 4) / POINT_DATA_SIZE) < n_points)
|
||||
return 0;
|
||||
proper_length= 4 + n_points * POINT_DATA_SIZE;
|
||||
|
||||
@ -638,8 +640,8 @@ bool Gis_line_string::get_data_as_wkt(String *txt, const char **end) const
|
||||
n_points= uint4korr(data);
|
||||
data += 4;
|
||||
|
||||
if (n_points < 1 || n_points > max_n_points ||
|
||||
no_data(data, POINT_DATA_SIZE * n_points) ||
|
||||
if (n_points < 1 ||
|
||||
not_enough_points(data, n_points) ||
|
||||
txt->reserve(((MAX_DIGITS_IN_DOUBLE + 1)*2 + 1) * n_points))
|
||||
return 1;
|
||||
|
||||
@ -676,8 +678,7 @@ int Gis_line_string::geom_length(double *len, const char **end) const
|
||||
return 1;
|
||||
n_points= uint4korr(data);
|
||||
data+= 4;
|
||||
if (n_points < 1 || n_points > max_n_points ||
|
||||
no_data(data, POINT_DATA_SIZE * n_points))
|
||||
if (n_points < 1 || not_enough_points(data, n_points))
|
||||
return 1;
|
||||
|
||||
get_point(&prev_x, &prev_y, data);
|
||||
@ -725,8 +726,7 @@ int Gis_line_string::is_closed(int *closed) const
|
||||
return 0;
|
||||
}
|
||||
data+= 4;
|
||||
if (n_points == 0 || n_points > max_n_points ||
|
||||
no_data(data, POINT_DATA_SIZE * n_points))
|
||||
if (n_points == 0 || not_enough_points(data, n_points))
|
||||
return 1;
|
||||
|
||||
/* Get first point */
|
||||
@ -761,8 +761,7 @@ int Gis_line_string::end_point(String *result) const
|
||||
if (no_data(m_data, 4))
|
||||
return 1;
|
||||
n_points= uint4korr(m_data);
|
||||
if (n_points == 0 || n_points > max_n_points ||
|
||||
no_data(m_data, POINT_DATA_SIZE * n_points))
|
||||
if (n_points == 0 || not_enough_points(m_data+4, n_points))
|
||||
return 1;
|
||||
return create_point(result, m_data + 4 + (n_points - 1) * POINT_DATA_SIZE);
|
||||
}
|
||||
@ -775,9 +774,7 @@ int Gis_line_string::point_n(uint32 num, String *result) const
|
||||
return 1;
|
||||
num--;
|
||||
n_points= uint4korr(m_data);
|
||||
if (num >= n_points ||
|
||||
num > max_n_points || // means (num > n_points || num < 1)
|
||||
no_data(m_data, num * POINT_DATA_SIZE))
|
||||
if (num >= n_points || not_enough_points(m_data+4, n_points))
|
||||
return 1;
|
||||
|
||||
return create_point(result, m_data + 4 + num*POINT_DATA_SIZE);
|
||||
@ -796,8 +793,7 @@ int Gis_line_string::store_shapes(Gcalc_shape_transporter *trn) const
|
||||
return 1;
|
||||
n_points= uint4korr(data);
|
||||
data+= 4;
|
||||
if (n_points < 1 || n_points > max_n_points ||
|
||||
no_data(data, POINT_DATA_SIZE * n_points))
|
||||
if (n_points < 1 || no_data(data, POINT_DATA_SIZE * n_points))
|
||||
return 1;
|
||||
|
||||
trn->start_line();
|
||||
@ -840,7 +836,7 @@ uint32 Gis_polygon::get_data_size() const
|
||||
while (n_linear_rings--)
|
||||
{
|
||||
if (no_data(data, 4) ||
|
||||
(n_points= uint4korr(data)) > max_n_points)
|
||||
not_enough_points(data+4, n_points= uint4korr(data)))
|
||||
return GET_SIZE_ERROR;
|
||||
data+= 4 + n_points*POINT_DATA_SIZE;
|
||||
}
|
||||
@ -986,7 +982,7 @@ bool Gis_polygon::get_data_as_wkt(String *txt, const char **end) const
|
||||
return 1;
|
||||
n_points= uint4korr(data);
|
||||
data+= 4;
|
||||
if (n_points > max_n_points || no_data(data, POINT_DATA_SIZE * n_points) ||
|
||||
if (not_enough_points(data, n_points) ||
|
||||
txt->reserve(2 + ((MAX_DIGITS_IN_DOUBLE + 1) * 2 + 1) * n_points))
|
||||
return 1;
|
||||
txt->qs_append('(');
|
||||
@ -1040,8 +1036,8 @@ int Gis_polygon::area(double *ar, const char **end_of_data) const
|
||||
if (no_data(data, 4))
|
||||
return 1;
|
||||
n_points= uint4korr(data);
|
||||
if (n_points == 0 || n_points > max_n_points ||
|
||||
no_data(data, POINT_DATA_SIZE * n_points))
|
||||
if (n_points == 0 ||
|
||||
not_enough_points(data, n_points))
|
||||
return 1;
|
||||
get_point(&prev_x, &prev_y, data+4);
|
||||
data+= (4+POINT_DATA_SIZE);
|
||||
@ -1077,8 +1073,7 @@ int Gis_polygon::exterior_ring(String *result) const
|
||||
n_points= uint4korr(data);
|
||||
data+= 4;
|
||||
length= n_points * POINT_DATA_SIZE;
|
||||
if (n_points > max_n_points ||
|
||||
no_data(data, length) || result->reserve(1 + 4 + 4 + length))
|
||||
if (not_enough_points(data, n_points) || result->reserve(1+4+4+ length))
|
||||
return 1;
|
||||
|
||||
result->q_append((char) wkb_ndr);
|
||||
@ -1124,8 +1119,7 @@ int Gis_polygon::interior_ring_n(uint32 num, String *result) const
|
||||
n_points= uint4korr(data);
|
||||
points_size= n_points * POINT_DATA_SIZE;
|
||||
data+= 4;
|
||||
if (n_points > max_n_points ||
|
||||
no_data(data, points_size) || result->reserve(1 + 4 + 4 + points_size))
|
||||
if (not_enough_points(data, n_points) || result->reserve(1+4+4+ points_size))
|
||||
return 1;
|
||||
|
||||
result->q_append((char) wkb_ndr);
|
||||
@ -1162,8 +1156,7 @@ int Gis_polygon::centroid_xy(double *x, double *y) const
|
||||
return 1;
|
||||
org_n_points= n_points= uint4korr(data);
|
||||
data+= 4;
|
||||
if (n_points == 0 || n_points > max_n_points ||
|
||||
no_data(data, POINT_DATA_SIZE * n_points))
|
||||
if (n_points == 0 || not_enough_points(data, n_points))
|
||||
return 1;
|
||||
get_point(&prev_x, &prev_y, data);
|
||||
data+= POINT_DATA_SIZE;
|
||||
@ -1237,8 +1230,7 @@ int Gis_polygon::store_shapes(Gcalc_shape_transporter *trn) const
|
||||
return 1;
|
||||
n_points= uint4korr(data);
|
||||
data+= 4;
|
||||
if (!n_points || n_points > max_n_points ||
|
||||
no_data(data, POINT_DATA_SIZE * n_points))
|
||||
if (!n_points || no_data(data, POINT_DATA_SIZE * n_points))
|
||||
return 1;
|
||||
|
||||
trn->start_ring();
|
||||
@ -1292,13 +1284,12 @@ const Geometry::Class_info *Gis_polygon::get_class_info() const
|
||||
uint32 Gis_multi_point::get_data_size() const
|
||||
{
|
||||
uint32 n_points;
|
||||
uint32 size;
|
||||
|
||||
if (no_data(m_data, 4) ||
|
||||
(n_points= uint4korr(m_data)) > max_n_points ||
|
||||
no_data(m_data, (size= 4 + n_points*(POINT_DATA_SIZE + WKB_HEADER_SIZE))))
|
||||
not_enough_points(m_data+4, (n_points= uint4korr(m_data)),
|
||||
WKB_HEADER_SIZE))
|
||||
return GET_SIZE_ERROR;
|
||||
return size;
|
||||
return 4 + n_points * (POINT_DATA_SIZE + WKB_HEADER_SIZE);
|
||||
}
|
||||
|
||||
|
||||
@ -1393,7 +1384,7 @@ bool Gis_multi_point::get_data_as_wkt(String *txt, const char **end) const
|
||||
|
||||
n_points= uint4korr(m_data);
|
||||
if (n_points > max_n_points ||
|
||||
no_data(m_data+4, n_points * (POINT_DATA_SIZE + WKB_HEADER_SIZE)) ||
|
||||
not_enough_points(m_data+4, n_points, WKB_HEADER_SIZE) ||
|
||||
txt->reserve(((MAX_DIGITS_IN_DOUBLE + 1) * 2 + 1) * n_points))
|
||||
return 1;
|
||||
*end= append_points(txt, n_points, m_data+4, WKB_HEADER_SIZE);
|
||||
@ -1485,7 +1476,8 @@ uint32 Gis_multi_line_string::get_data_size() const
|
||||
while (n_line_strings--)
|
||||
{
|
||||
if (no_data(data, WKB_HEADER_SIZE + 4) ||
|
||||
(n_points= uint4korr(data + WKB_HEADER_SIZE)) > max_n_points)
|
||||
not_enough_points(data + WKB_HEADER_SIZE+4,
|
||||
(n_points= uint4korr(data + WKB_HEADER_SIZE))))
|
||||
return GET_SIZE_ERROR;
|
||||
data+= (WKB_HEADER_SIZE + 4 + n_points*POINT_DATA_SIZE);
|
||||
}
|
||||
@ -1614,7 +1606,7 @@ bool Gis_multi_line_string::get_data_as_wkt(String *txt,
|
||||
return 1;
|
||||
n_points= uint4korr(data + WKB_HEADER_SIZE);
|
||||
data+= WKB_HEADER_SIZE + 4;
|
||||
if (n_points > max_n_points || no_data(data, n_points * POINT_DATA_SIZE) ||
|
||||
if (not_enough_points(data, n_points) ||
|
||||
txt->reserve(2 + ((MAX_DIGITS_IN_DOUBLE + 1) * 2 + 1) * n_points))
|
||||
return 1;
|
||||
txt->qs_append('(');
|
||||
@ -1675,7 +1667,7 @@ int Gis_multi_line_string::geometry_n(uint32 num, String *result) const
|
||||
return 1;
|
||||
n_points= uint4korr(data + WKB_HEADER_SIZE);
|
||||
length= WKB_HEADER_SIZE + 4+ POINT_DATA_SIZE * n_points;
|
||||
if (n_points > max_n_points || no_data(data, length))
|
||||
if (not_enough_points(data+WKB_HEADER_SIZE+4, n_points))
|
||||
return 1;
|
||||
if (!--num)
|
||||
break;
|
||||
@ -1806,7 +1798,7 @@ uint32 Gis_multi_polygon::get_data_size() const
|
||||
while (n_linear_rings--)
|
||||
{
|
||||
if (no_data(data, 4) ||
|
||||
(n_points= uint4korr(data)) > max_n_points)
|
||||
not_enough_points(data+4, (n_points= uint4korr(data))))
|
||||
return GET_SIZE_ERROR;
|
||||
data+= 4 + n_points * POINT_DATA_SIZE;
|
||||
}
|
||||
@ -1940,8 +1932,7 @@ bool Gis_multi_polygon::get_data_as_wkt(String *txt, const char **end) const
|
||||
return 1;
|
||||
uint32 n_points= uint4korr(data);
|
||||
data+= 4;
|
||||
if (n_points > max_n_points ||
|
||||
no_data(data, POINT_DATA_SIZE * n_points) ||
|
||||
if (not_enough_points(data, n_points) ||
|
||||
txt->reserve(2 + ((MAX_DIGITS_IN_DOUBLE + 1) * 2 + 1) * n_points,
|
||||
512))
|
||||
return 1;
|
||||
@ -2024,7 +2015,7 @@ int Gis_multi_polygon::geometry_n(uint32 num, String *result) const
|
||||
if (no_data(data, 4))
|
||||
return 1;
|
||||
n_points= uint4korr(data);
|
||||
if (n_points > max_n_points)
|
||||
if (not_enough_points(data + 4, n_points))
|
||||
return 1;
|
||||
data+= 4 + POINT_DATA_SIZE * n_points;
|
||||
}
|
||||
|
@ -214,11 +214,6 @@ struct Geometry_buffer;
|
||||
class Geometry
|
||||
{
|
||||
public:
|
||||
// Maximum number of points in feature that can fit into String
|
||||
static const uint32 max_n_points=
|
||||
(uint32) (INT_MAX32 - WKB_HEADER_SIZE - 4 /* n_points */) /
|
||||
POINT_DATA_SIZE;
|
||||
|
||||
Geometry() {} /* Remove gcc warning */
|
||||
virtual ~Geometry() {} /* Remove gcc warning */
|
||||
static void *operator new(size_t size, void *buffer)
|
||||
|
@ -1261,6 +1261,20 @@ JOIN::optimize()
|
||||
/* Handle the case where we have an OUTER JOIN without a WHERE */
|
||||
conds=new Item_int((longlong) 1,1); // Always true
|
||||
}
|
||||
|
||||
if (const_tables && conds)
|
||||
{
|
||||
conds= remove_eq_conds(thd, conds, &cond_value);
|
||||
if (cond_value == Item::COND_FALSE)
|
||||
{
|
||||
zero_result_cause=
|
||||
"Impossible WHERE noticed after reading const tables";
|
||||
select_lex->mark_const_derived(zero_result_cause);
|
||||
conds=new Item_int((longlong) 0,1);
|
||||
goto setup_subq_exit;
|
||||
}
|
||||
}
|
||||
|
||||
select= make_select(*table, const_table_map,
|
||||
const_table_map, conds, 1, &error);
|
||||
if (error)
|
||||
@ -8827,19 +8841,18 @@ make_join_select(JOIN *join,SQL_SELECT *select,COND *cond)
|
||||
else
|
||||
{
|
||||
sel->needed_reg=tab->needed_reg;
|
||||
sel->quick_keys.clear_all();
|
||||
}
|
||||
sel->quick_keys= tab->table->quick_keys;
|
||||
if (!sel->quick_keys.is_subset(tab->checked_keys) ||
|
||||
!sel->needed_reg.is_subset(tab->checked_keys))
|
||||
{
|
||||
tab->keys=sel->quick_keys;
|
||||
tab->keys.merge(sel->needed_reg);
|
||||
tab->use_quick= (!sel->needed_reg.is_clear_all() &&
|
||||
(select->quick_keys.is_clear_all() ||
|
||||
(select->quick &&
|
||||
(select->quick->records >= 100L)))) ?
|
||||
(sel->quick_keys.is_clear_all() ||
|
||||
(sel->quick &&
|
||||
(sel->quick->records >= 100L)))) ?
|
||||
2 : 1;
|
||||
sel->read_tables= used_tables & ~current_map;
|
||||
sel->quick_keys.clear_all();
|
||||
}
|
||||
if (i != join->const_tables && tab->use_quick != 2 &&
|
||||
!tab->first_inner)
|
||||
@ -13422,22 +13435,175 @@ optimize_cond(JOIN *join, COND *conds,
|
||||
|
||||
|
||||
/**
|
||||
Handles the recursive job remove_eq_conds()
|
||||
@brief
|
||||
Propagate multiple equalities to the sub-expressions of a condition
|
||||
|
||||
Remove const and eq items. Return new item, or NULL if no condition
|
||||
cond_value is set to according:
|
||||
COND_OK query is possible (field = constant)
|
||||
COND_TRUE always true ( 1 = 1 )
|
||||
COND_FALSE always false ( 1 = 2 )
|
||||
@param thd thread handle
|
||||
@param cond the condition where equalities are to be propagated
|
||||
@param *new_equalities the multiple equalities to be propagated
|
||||
@param inherited path to all inherited multiple equality items
|
||||
@param[out] is_simplifiable_cond 'cond' may be simplified after the
|
||||
propagation of the equalities
|
||||
|
||||
SYNOPSIS
|
||||
internal_remove_eq_conds()
|
||||
thd THD environment
|
||||
cond the condition to handle
|
||||
cond_value the resulting value of the condition
|
||||
@details
|
||||
The function recursively traverses the tree of the condition 'cond' and
|
||||
for each its AND sub-level of any depth the function merges the multiple
|
||||
equalities from the list 'new_equalities' into the multiple equalities
|
||||
attached to the AND item created for this sub-level.
|
||||
The function also [re]sets references to the equalities formed by the
|
||||
merges of multiple equalities in all field items occurred in 'cond'
|
||||
that are encountered in the equalities.
|
||||
If the result of any merge of multiple equalities is an impossible
|
||||
condition the function returns TRUE in the parameter is_simplifiable_cond.
|
||||
*/
|
||||
|
||||
RETURN
|
||||
*COND with the simplified condition
|
||||
void propagate_new_equalities(THD *thd, Item *cond,
|
||||
List<Item_equal> *new_equalities,
|
||||
COND_EQUAL *inherited,
|
||||
bool *is_simplifiable_cond)
|
||||
{
|
||||
if (cond->type() == Item::COND_ITEM)
|
||||
{
|
||||
bool and_level= ((Item_cond*) cond)->functype() == Item_func::COND_AND_FUNC;
|
||||
if (and_level)
|
||||
{
|
||||
Item_cond_and *cond_and= (Item_cond_and *) cond;
|
||||
List<Item_equal> *cond_equalities= &cond_and->cond_equal.current_level;
|
||||
inherited= cond_and->cond_equal.upper_levels;
|
||||
if (!cond_equalities->is_empty() && cond_equalities != new_equalities)
|
||||
{
|
||||
Item_equal *equal_item;
|
||||
List_iterator<Item_equal> it(*new_equalities);
|
||||
while ((equal_item= it++))
|
||||
{
|
||||
equal_item->merge_into_list(cond_equalities, true, true);
|
||||
}
|
||||
List_iterator<Item_equal> ei(*cond_equalities);
|
||||
while ((equal_item= ei++))
|
||||
{
|
||||
if (equal_item->const_item() && !equal_item->val_int())
|
||||
{
|
||||
*is_simplifiable_cond= true;
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Item *item;
|
||||
List_iterator<Item> li(*((Item_cond*) cond)->argument_list());
|
||||
while ((item= li++))
|
||||
{
|
||||
propagate_new_equalities(thd, item, new_equalities, inherited,
|
||||
is_simplifiable_cond);
|
||||
}
|
||||
}
|
||||
else if (cond->type() == Item::FUNC_ITEM &&
|
||||
((Item_cond*) cond)->functype() == Item_func::MULT_EQUAL_FUNC)
|
||||
{
|
||||
Item_equal *equal_item;
|
||||
List_iterator<Item_equal> it(*new_equalities);
|
||||
Item_equal *equality= (Item_equal *) cond;
|
||||
while ((equal_item= it++))
|
||||
{
|
||||
equality->merge_with_check(equal_item, true);
|
||||
}
|
||||
if (equality->const_item() && !equality->val_int())
|
||||
*is_simplifiable_cond= true;
|
||||
}
|
||||
else
|
||||
{
|
||||
uchar* is_subst_valid= (uchar *) Item::ANY_SUBST;
|
||||
cond= cond->compile(&Item::subst_argument_checker,
|
||||
&is_subst_valid,
|
||||
&Item::equal_fields_propagator,
|
||||
(uchar *) inherited);
|
||||
cond->update_used_tables();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
@brief
|
||||
Evaluate all constant boolean sub-expressions in a condition
|
||||
|
||||
@param thd thread handle
|
||||
@param cond condition where where to evaluate constant sub-expressions
|
||||
@param[out] cond_value : the returned value of the condition
|
||||
(TRUE/FALSE/UNKNOWN:
|
||||
Item::COND_TRUE/Item::COND_FALSE/Item::COND_OK)
|
||||
@return
|
||||
the item that is the result of the substitution of all inexpensive constant
|
||||
boolean sub-expressions into cond, or,
|
||||
NULL if the condition is constant and is evaluated to FALSE.
|
||||
|
||||
@details
|
||||
This function looks for all inexpensive constant boolean sub-expressions in
|
||||
the given condition 'cond' and substitutes them for their values.
|
||||
For example, the condition 2 > (5 + 1) or a < (10 / 2)
|
||||
will be transformed to the condition a < (10 / 2).
|
||||
Note that a constant sub-expression is evaluated only if it is constant and
|
||||
inexpensive. A sub-expression with an uncorrelated subquery may be evaluated
|
||||
only if the subquery is considered as inexpensive.
|
||||
The function does not evaluate a constant sub-expression if it is not on one
|
||||
of AND/OR levels of the condition 'cond'. For example, the subquery in the
|
||||
condition a > (select max(b) from t1 where b > 5) will never be evaluated
|
||||
by this function.
|
||||
If a constant boolean sub-expression is evaluated to TRUE then:
|
||||
- when the sub-expression is a conjunct of an AND formula it is simply
|
||||
removed from this formula
|
||||
- when the sub-expression is a disjunct of an OR formula the whole OR
|
||||
formula is converted to TRUE
|
||||
If a constant boolean sub-expression is evaluated to FALSE then:
|
||||
- when the sub-expression is a disjunct of an OR formula it is simply
|
||||
removed from this formula
|
||||
- when the sub-expression is a conjuct of an AND formula the whole AND
|
||||
formula is converted to FALSE
|
||||
When a disjunct/conjunct is removed from an OR/AND formula it might happen
|
||||
that there is only one conjunct/disjunct remaining. In this case this
|
||||
remaining disjunct/conjunct must be merged into underlying AND/OR formula,
|
||||
because AND/OR levels must alternate in the same way as they alternate
|
||||
after fix_fields() is called for the original condition.
|
||||
The specifics of merging a formula f into an AND formula A appears
|
||||
when A contains multiple equalities and f contains multiple equalities.
|
||||
In this case the multiple equalities from f and A have to be merged.
|
||||
After this the resulting multiple equalities have to be propagated into
|
||||
the all AND/OR levels of the formula A (see propagate_new_equalities()).
|
||||
The propagation of multiple equalities might result in forming multiple
|
||||
equalities that are always FALSE. This, in its turn, might trigger further
|
||||
simplification of the condition.
|
||||
|
||||
@note
|
||||
EXAMPLE 1:
|
||||
SELECT * FROM t1 WHERE (b = 1 OR a = 1) AND (b = 5 AND a = 5 OR 1 != 1);
|
||||
First 1 != 1 will be removed from the second conjunct:
|
||||
=> SELECT * FROM t1 WHERE (b = 1 OR a = 1) AND (b = 5 AND a = 5);
|
||||
Then (b = 5 AND a = 5) will be merged into the top level condition:
|
||||
=> SELECT * FROM t1 WHERE (b = 1 OR a = 1) AND (b = 5) AND (a = 5);
|
||||
Then (b = 5), (a = 5) will be propagated into the disjuncs of
|
||||
(b = 1 OR a = 1):
|
||||
=> SELECT * FROM t1 WHERE ((b = 1) AND (b = 5) AND (a = 5) OR
|
||||
(a = 1) AND (b = 5) AND (a = 5)) AND
|
||||
(b = 5) AND (a = 5)
|
||||
=> SELECT * FROM t1 WHERE ((FALSE AND (a = 5)) OR
|
||||
(FALSE AND (b = 5))) AND
|
||||
(b = 5) AND (a = 5)
|
||||
After this an additional call of remove_eq_conds() converts it
|
||||
to FALSE
|
||||
|
||||
EXAMPLE 2:
|
||||
SELECT * FROM t1 WHERE (b = 1 OR a = 5) AND (b = 5 AND a = 5 OR 1 != 1);
|
||||
=> SELECT * FROM t1 WHERE (b = 1 OR a = 5) AND (b = 5 AND a = 5);
|
||||
=> SELECT * FROM t1 WHERE (b = 1 OR a = 5) AND (b = 5) AND (a = 5);
|
||||
=> SELECT * FROM t1 WHERE ((b = 1) AND (b = 5) AND (a = 5) OR
|
||||
(a = 5) AND (b = 5) AND (a = 5)) AND
|
||||
(b = 5) AND (a = 5)
|
||||
=> SELECT * FROM t1 WHERE ((FALSE AND (a = 5)) OR
|
||||
((b = 5) AND (a = 5))) AND
|
||||
(b = 5) AND (a = 5)
|
||||
After this an additional call of remove_eq_conds() converts it to
|
||||
=> SELECT * FROM t1 WHERE (b = 5) AND (a = 5)
|
||||
*/
|
||||
|
||||
static COND *
|
||||
@ -13445,9 +13611,11 @@ internal_remove_eq_conds(THD *thd, COND *cond, Item::cond_result *cond_value)
|
||||
{
|
||||
if (cond->type() == Item::COND_ITEM)
|
||||
{
|
||||
List<Item_equal> new_equalities;
|
||||
bool and_level= ((Item_cond*) cond)->functype()
|
||||
== Item_func::COND_AND_FUNC;
|
||||
List_iterator<Item> li(*((Item_cond*) cond)->argument_list());
|
||||
List<Item> *cond_arg_list= ((Item_cond*) cond)->argument_list();
|
||||
List_iterator<Item> li(*cond_arg_list);
|
||||
Item::cond_result tmp_cond_value;
|
||||
bool should_fix_fields=0;
|
||||
|
||||
@ -13457,91 +13625,71 @@ internal_remove_eq_conds(THD *thd, COND *cond, Item::cond_result *cond_value)
|
||||
{
|
||||
Item *new_item=internal_remove_eq_conds(thd, item, &tmp_cond_value);
|
||||
if (!new_item)
|
||||
{
|
||||
/* This can happen only when item is converted to TRUE or FALSE */
|
||||
li.remove();
|
||||
}
|
||||
else if (item != new_item)
|
||||
{
|
||||
/*
|
||||
This can happen when:
|
||||
- item was an OR formula converted to one disjunct
|
||||
- item was an AND formula converted to one conjunct
|
||||
In these cases the disjunct/conjunct must be merged into the
|
||||
argument list of cond.
|
||||
*/
|
||||
if (new_item->type() == Item::COND_ITEM)
|
||||
{
|
||||
DBUG_ASSERT(((Item_cond *) cond)->functype() ==
|
||||
((Item_cond *) new_item)->functype());
|
||||
List<Item> *new_item_arg_list=
|
||||
((Item_cond *) new_item)->argument_list();
|
||||
if (and_level)
|
||||
{
|
||||
/*
|
||||
Take a special care of multiple equality predicates
|
||||
that may be part of 'cond' and 'new_item'.
|
||||
Those multiple equalities that have common members
|
||||
must be merged.
|
||||
If new_item is an AND formula then multiple equalities
|
||||
of new_item_arg_list must merged into multiple equalities
|
||||
of cond_arg_list.
|
||||
*/
|
||||
Item_cond_and *cond_and= (Item_cond_and *) cond;
|
||||
List<Item_equal> *cond_equal_items=
|
||||
&cond_and->cond_equal.current_level;
|
||||
List<Item> *cond_and_list= cond_and->argument_list();
|
||||
|
||||
if (new_item->type() == Item::COND_ITEM &&
|
||||
((Item_cond*) new_item)->functype() == Item_func::COND_AND_FUNC)
|
||||
List<Item_equal> *new_item_equalities=
|
||||
&((Item_cond_and *) new_item)->cond_equal.current_level;
|
||||
if (!new_item_equalities->is_empty())
|
||||
{
|
||||
Item_cond_and *new_item_and= (Item_cond_and *) new_item;
|
||||
List<Item_equal> *new_item_equal_items=
|
||||
&new_item_and->cond_equal.current_level;
|
||||
List<Item> *new_item_and_list= new_item_and->argument_list();
|
||||
cond_and_list->disjoin((List<Item>*) cond_equal_items);
|
||||
new_item_and_list->disjoin((List<Item>*) new_item_equal_items);
|
||||
Item_equal *equal_item;
|
||||
List_iterator<Item_equal> it(*new_item_equal_items);
|
||||
while ((equal_item= it++))
|
||||
{
|
||||
equal_item->merge_into_list(cond_equal_items);
|
||||
/*
|
||||
Cut the multiple equalities from the new_item_arg_list and
|
||||
append them on the list new_equalities. Later the equalities
|
||||
from this list will be merged into the multiple equalities
|
||||
of cond_arg_list all together.
|
||||
*/
|
||||
new_item_arg_list->disjoin((List<Item> *) new_item_equalities);
|
||||
new_equalities.concat(new_item_equalities);
|
||||
}
|
||||
if (new_item_and_list->is_empty())
|
||||
}
|
||||
if (new_item_arg_list->is_empty())
|
||||
li.remove();
|
||||
else
|
||||
{
|
||||
Item *list_item;
|
||||
Item *new_list_item;
|
||||
uint cnt= new_item_and_list->elements;
|
||||
List_iterator<Item> it(*new_item_and_list);
|
||||
while ((list_item= it++))
|
||||
{
|
||||
uchar* is_subst_valid= (uchar *) Item::ANY_SUBST;
|
||||
new_list_item=
|
||||
list_item->compile(&Item::subst_argument_checker,
|
||||
&is_subst_valid,
|
||||
&Item::equal_fields_propagator,
|
||||
(uchar *) &cond_and->cond_equal);
|
||||
if (new_list_item != list_item)
|
||||
it.replace(new_list_item);
|
||||
new_list_item->update_used_tables();
|
||||
}
|
||||
li.replace(*new_item_and_list);
|
||||
uint cnt= new_item_arg_list->elements;
|
||||
li.replace(*new_item_arg_list);
|
||||
/* Make iterator li ignore new items */
|
||||
for (cnt--; cnt; cnt--)
|
||||
item= li++;
|
||||
li++;
|
||||
should_fix_fields= 1;
|
||||
}
|
||||
cond_and_list->concat((List<Item>*) cond_equal_items);
|
||||
}
|
||||
else if (new_item->type() == Item::FUNC_ITEM &&
|
||||
else if (and_level &&
|
||||
new_item->type() == Item::FUNC_ITEM &&
|
||||
((Item_cond*) new_item)->functype() ==
|
||||
Item_func::MULT_EQUAL_FUNC)
|
||||
{
|
||||
cond_and_list->disjoin((List<Item>*) cond_equal_items);
|
||||
((Item_equal *) new_item)->merge_into_list(cond_equal_items);
|
||||
li.remove();
|
||||
cond_and_list->concat((List<Item>*) cond_equal_items);
|
||||
}
|
||||
else
|
||||
li.replace(new_item);
|
||||
new_equalities.push_back((Item_equal *) new_item);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (new_item->type() == Item::COND_ITEM &&
|
||||
((Item_cond*) new_item)->functype() ==
|
||||
((Item_cond*) cond)->functype())
|
||||
{
|
||||
List<Item> *arg_list= ((Item_cond*) new_item)->argument_list();
|
||||
uint cnt= arg_list->elements;
|
||||
li.replace(*arg_list);
|
||||
for ( cnt--; cnt; cnt--)
|
||||
item= li++;
|
||||
}
|
||||
else
|
||||
li.replace(new_item);
|
||||
should_fix_fields= 1;
|
||||
}
|
||||
should_fix_fields=1;
|
||||
}
|
||||
if (*cond_value == Item::COND_UNDEF)
|
||||
*cond_value=tmp_cond_value;
|
||||
@ -13568,6 +13716,53 @@ internal_remove_eq_conds(THD *thd, COND *cond, Item::cond_result *cond_value)
|
||||
break; /* purecov: deadcode */
|
||||
}
|
||||
}
|
||||
if (!new_equalities.is_empty())
|
||||
{
|
||||
DBUG_ASSERT(and_level);
|
||||
/*
|
||||
Merge multiple equalities that were cut from the results of
|
||||
simplification of OR formulas converted into AND formulas.
|
||||
These multiple equalities are to be merged into the
|
||||
multiple equalities of cond_arg_list.
|
||||
*/
|
||||
COND_EQUAL *cond_equal= &((Item_cond_and *) cond)->cond_equal;
|
||||
List<Item_equal> *cond_equalities= &cond_equal->current_level;
|
||||
cond_arg_list->disjoin((List<Item> *) cond_equalities);
|
||||
Item_equal *equality;
|
||||
List_iterator_fast<Item_equal> it(new_equalities);
|
||||
while ((equality= it++))
|
||||
{
|
||||
equality->merge_into_list(cond_equalities, false, false);
|
||||
List_iterator_fast<Item_equal> ei(*cond_equalities);
|
||||
while ((equality= ei++))
|
||||
{
|
||||
if (equality->const_item() && !equality->val_int())
|
||||
{
|
||||
*cond_value= Item::COND_FALSE;
|
||||
return (COND*) 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
cond_arg_list->concat((List<Item> *) cond_equalities);
|
||||
/*
|
||||
Propagate the newly formed multiple equalities to
|
||||
the all AND/OR levels of cond
|
||||
*/
|
||||
bool is_simplifiable_cond= true;
|
||||
propagate_new_equalities(thd, cond, cond_equalities,
|
||||
cond_equal->upper_levels,
|
||||
&is_simplifiable_cond);
|
||||
/*
|
||||
If the above propagation of multiple equalities brings us
|
||||
to multiple equalities that are always FALSE then try to
|
||||
simplify the condition with remove_eq_cond() again.
|
||||
*/
|
||||
if (is_simplifiable_cond)
|
||||
{
|
||||
if (!(cond= remove_eq_conds(thd, cond, cond_value)))
|
||||
return cond;
|
||||
}
|
||||
}
|
||||
if (should_fix_fields)
|
||||
cond->update_used_tables();
|
||||
|
||||
@ -13732,7 +13927,7 @@ remove_eq_conds(THD *thd, COND *cond, Item::cond_result *cond_value)
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
/**
|
||||
Check if equality can be used in removing components of GROUP BY/DISTINCT
|
||||
|
||||
@param l the left comparison argument (a field if any)
|
||||
|
@ -2070,7 +2070,7 @@ bool fix_vcol_expr(THD *thd,
|
||||
Item* func_expr= vcol_info->expr_item;
|
||||
bool result= TRUE;
|
||||
TABLE_LIST tables;
|
||||
int error;
|
||||
int error= 0;
|
||||
const char *save_where;
|
||||
Field **ptr, *field;
|
||||
enum_mark_columns save_mark_used_columns= thd->mark_used_columns;
|
||||
@ -2083,7 +2083,11 @@ bool fix_vcol_expr(THD *thd,
|
||||
thd->where= "virtual column function";
|
||||
|
||||
/* Fix fields referenced to by the virtual column function */
|
||||
error= func_expr->fix_fields(thd, (Item**)0);
|
||||
if (!func_expr->fixed)
|
||||
error= func_expr->fix_fields(thd, &vcol_info->expr_item);
|
||||
/* fix_fields could change the expression */
|
||||
func_expr= vcol_info->expr_item;
|
||||
/* Number of columns will be checked later */
|
||||
|
||||
if (unlikely(error))
|
||||
{
|
||||
|
Loading…
x
Reference in New Issue
Block a user