mirror of
https://github.com/MariaDB/server.git
synced 2025-07-30 16:24:05 +03:00
Merge for post-merge fixes for Item_equal patch.
BitKeeper/etc/ignore: auto-union mysql-test/r/range.result: Auto merged mysql-test/r/select.result: Auto merged mysql-test/t/range.test: Auto merged sql/item.cc: Auto merged sql/opt_range.cc: Auto merged sql/opt_sum.cc: Auto merged sql/sql_select.h: Auto merged sql/item.h: Manual merge sql/sql_select.cc: Manual merge
This commit is contained in:
@ -508,6 +508,7 @@ mysql-test/install_test_db
|
||||
mysql-test/mysql-test-run
|
||||
mysql-test/ndb/ndbcluster
|
||||
mysql-test/r/*.reject
|
||||
mysql-test/r/index_merge_load.result
|
||||
mysql-test/r/rpl000001.eval
|
||||
mysql-test/r/rpl000002.eval
|
||||
mysql-test/r/rpl000014.eval
|
||||
@ -518,6 +519,7 @@ mysql-test/r/slave-running.eval
|
||||
mysql-test/r/slave-stopped.eval
|
||||
mysql-test/share/mysql
|
||||
mysql-test/std_data/*.pem
|
||||
mysql-test/t/index_merge.load
|
||||
mysql-test/var/*
|
||||
mysql.kdevprj
|
||||
mysql.proj
|
||||
|
@ -476,7 +476,7 @@ CHI Los Angeles
|
||||
explain
|
||||
select max(a3) from t1 where a2 is null and a2 = 2;
|
||||
id select_type table type possible_keys key key_len ref rows Extra
|
||||
1 SIMPLE NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables
|
||||
1 SIMPLE NULL NULL NULL NULL NULL NULL NULL Impossible WHERE
|
||||
select max(a3) from t1 where a2 is null and a2 = 2;
|
||||
max(a3)
|
||||
NULL
|
||||
|
@ -77,9 +77,9 @@ select * from t1 where 1 xor 1;
|
||||
a
|
||||
explain extended select * from t1 where 1 xor 1;
|
||||
id select_type table type possible_keys key key_len ref rows Extra
|
||||
1 SIMPLE NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables
|
||||
1 SIMPLE NULL NULL NULL NULL NULL NULL NULL Impossible WHERE
|
||||
Warnings:
|
||||
Note 1003 select `test`.`t1`.`a` AS `a` from `test`.`t1` where (1 xor 1)
|
||||
Note 1003 select `test`.`t1`.`a` AS `a` from `test`.`t1`
|
||||
select - a from t1;
|
||||
- a
|
||||
-1
|
||||
|
@ -76,13 +76,13 @@ id select_type table type possible_keys key key_len ref rows Extra
|
||||
1 SIMPLE t0 ALL i1,i2 NULL NULL NULL 1024 Using where
|
||||
explain select * from t0 where key2 = 45 or key1 is null;
|
||||
id select_type table type possible_keys key key_len ref rows Extra
|
||||
1 SIMPLE t0 range i1,i2 i2 4 NULL 1 Using where
|
||||
1 SIMPLE t0 ref i2 i2 4 const 1
|
||||
explain select * from t0 where key2=10 or key3=3 or key4 <=> null;
|
||||
id select_type table type possible_keys key key_len ref rows Extra
|
||||
1 SIMPLE t0 index_merge i2,i3,i4 i2,i3 4,4 NULL 2 Using union(i2,i3); Using where
|
||||
explain select * from t0 where key2=10 or key3=3 or key4 is null;
|
||||
id select_type table type possible_keys key key_len ref rows Extra
|
||||
1 SIMPLE t0 index_merge i2,i3,i4 i2,i3 4,4 NULL 2 Using union(i2,i3); Using where
|
||||
1 SIMPLE t0 index_merge i2,i3 i2,i3 4,4 NULL 2 Using union(i2,i3); Using where
|
||||
explain select key1 from t0 where (key1 <=> null) or (key2 < 5) or
|
||||
(key3=10) or (key4 <=> null);
|
||||
id select_type table type possible_keys key key_len ref rows Extra
|
||||
@ -257,8 +257,8 @@ explain
|
||||
select * from t0,t1 where (t0.key1=t1.key1) and
|
||||
(t0.key1=3 or t0.key2=4) and t1.key1<200;
|
||||
id select_type table type possible_keys key key_len ref rows Extra
|
||||
1 SIMPLE t0 index_merge i1,i2 i1,i2 4,4 NULL 2 Using union(i1,i2); Using where
|
||||
1 SIMPLE t1 ref i1 i1 4 test.t0.key1 1 Using where
|
||||
1 SIMPLE t0 range i1,i2 i1 4 NULL 179 Using where
|
||||
1 SIMPLE t1 ref i1 i1 4 test.t0.key1 1
|
||||
explain
|
||||
select * from t0,t1 where (t0.key1=t1.key1) and
|
||||
(t0.key1=3 or t0.key2<4) and t1.key1=2;
|
||||
|
@ -76,7 +76,7 @@ id select_type table type possible_keys key key_len ref rows Extra
|
||||
1 SIMPLE t3 ALL NULL NULL NULL NULL 2 Using where
|
||||
1 SIMPLE t4 ALL NULL NULL NULL NULL 2
|
||||
Warnings:
|
||||
Note 1003 select `test`.`t2`.`a` AS `a`,`test`.`t2`.`b` AS `b`,`test`.`t3`.`a` AS `a`,`test`.`t3`.`b` AS `b`,`test`.`t4`.`a` AS `a`,`test`.`t4`.`b` AS `b` from `test`.`t2` left join (`test`.`t3` join `test`.`t4`) on((`test`.`t2`.`b` = `test`.`t4`.`b`)) where ((`test`.`t3`.`a` = 1) or isnull(`test`.`t3`.`c`))
|
||||
Note 1003 select `test`.`t2`.`a` AS `a`,`test`.`t2`.`b` AS `b`,`test`.`t3`.`a` AS `a`,`test`.`t3`.`b` AS `b`,`test`.`t4`.`a` AS `a`,`test`.`t4`.`b` AS `b` from `test`.`t2` left join (`test`.`t3` join `test`.`t4`) on((`test`.`t4`.`b` = `test`.`t2`.`b`)) where ((`test`.`t3`.`a` = 1) or isnull(`test`.`t3`.`c`))
|
||||
SELECT t2.a,t2.b,t3.a,t3.b,t4.a,t4.b
|
||||
FROM t2
|
||||
LEFT JOIN
|
||||
@ -153,7 +153,7 @@ id select_type table type possible_keys key key_len ref rows Extra
|
||||
1 SIMPLE t4 ALL NULL NULL NULL NULL 2
|
||||
1 SIMPLE t5 ALL NULL NULL NULL NULL 3
|
||||
Warnings:
|
||||
Note 1003 select `test`.`t2`.`a` AS `a`,`test`.`t2`.`b` AS `b`,`test`.`t3`.`a` AS `a`,`test`.`t3`.`b` AS `b`,`test`.`t4`.`a` AS `a`,`test`.`t4`.`b` AS `b`,`test`.`t5`.`a` AS `a`,`test`.`t5`.`b` AS `b` from `test`.`t2` left join (`test`.`t3` join `test`.`t4` join `test`.`t5`) on((`test`.`t2`.`b` = `test`.`t4`.`b`)) where ((`test`.`t3`.`a` > 1) or isnull(`test`.`t3`.`c`))
|
||||
Note 1003 select `test`.`t2`.`a` AS `a`,`test`.`t2`.`b` AS `b`,`test`.`t3`.`a` AS `a`,`test`.`t3`.`b` AS `b`,`test`.`t4`.`a` AS `a`,`test`.`t4`.`b` AS `b`,`test`.`t5`.`a` AS `a`,`test`.`t5`.`b` AS `b` from `test`.`t2` left join (`test`.`t3` join `test`.`t4` join `test`.`t5`) on((`test`.`t4`.`b` = `test`.`t2`.`b`)) where ((`test`.`t3`.`a` > 1) or isnull(`test`.`t3`.`c`))
|
||||
SELECT t2.a,t2.b,t3.a,t3.b,t4.a,t4.b,t5.a,t5.b
|
||||
FROM t2
|
||||
LEFT JOIN
|
||||
@ -183,7 +183,7 @@ id select_type table type possible_keys key key_len ref rows Extra
|
||||
1 SIMPLE t4 ALL NULL NULL NULL NULL 2
|
||||
1 SIMPLE t5 ALL NULL NULL NULL NULL 3 Using where
|
||||
Warnings:
|
||||
Note 1003 select `test`.`t2`.`a` AS `a`,`test`.`t2`.`b` AS `b`,`test`.`t3`.`a` AS `a`,`test`.`t3`.`b` AS `b`,`test`.`t4`.`a` AS `a`,`test`.`t4`.`b` AS `b`,`test`.`t5`.`a` AS `a`,`test`.`t5`.`b` AS `b` from `test`.`t2` left join (`test`.`t3` join `test`.`t4` join `test`.`t5`) on((`test`.`t2`.`b` = `test`.`t4`.`b`)) where (((`test`.`t3`.`a` > 1) or isnull(`test`.`t3`.`c`)) and ((`test`.`t5`.`a` < 3) or isnull(`test`.`t5`.`c`)))
|
||||
Note 1003 select `test`.`t2`.`a` AS `a`,`test`.`t2`.`b` AS `b`,`test`.`t3`.`a` AS `a`,`test`.`t3`.`b` AS `b`,`test`.`t4`.`a` AS `a`,`test`.`t4`.`b` AS `b`,`test`.`t5`.`a` AS `a`,`test`.`t5`.`b` AS `b` from `test`.`t2` left join (`test`.`t3` join `test`.`t4` join `test`.`t5`) on((`test`.`t4`.`b` = `test`.`t2`.`b`)) where (((`test`.`t3`.`a` > 1) or isnull(`test`.`t3`.`c`)) and ((`test`.`t5`.`a` < 3) or isnull(`test`.`t5`.`c`)))
|
||||
SELECT t2.a,t2.b,t3.a,t3.b,t4.a,t4.b,t5.a,t5.b
|
||||
FROM t2
|
||||
LEFT JOIN
|
||||
@ -233,7 +233,7 @@ id select_type table type possible_keys key key_len ref rows Extra
|
||||
1 SIMPLE t6 ALL NULL NULL NULL NULL 3
|
||||
1 SIMPLE t8 ALL NULL NULL NULL NULL 2
|
||||
Warnings:
|
||||
Note 1003 select `test`.`t6`.`a` AS `a`,`test`.`t6`.`b` AS `b`,`test`.`t7`.`a` AS `a`,`test`.`t7`.`b` AS `b`,`test`.`t8`.`a` AS `a`,`test`.`t8`.`b` AS `b` from `test`.`t6` join `test`.`t7` left join `test`.`t8` on(((`test`.`t7`.`b` = `test`.`t8`.`b`) and (`test`.`t6`.`b` < 10))) where 1
|
||||
Note 1003 select `test`.`t6`.`a` AS `a`,`test`.`t6`.`b` AS `b`,`test`.`t7`.`a` AS `a`,`test`.`t7`.`b` AS `b`,`test`.`t8`.`a` AS `a`,`test`.`t8`.`b` AS `b` from `test`.`t6` join `test`.`t7` left join `test`.`t8` on(((`test`.`t8`.`b` = `test`.`t7`.`b`) and (`test`.`t6`.`b` < 10))) where 1
|
||||
SELECT t6.a,t6.b,t7.a,t7.b,t8.a,t8.b
|
||||
FROM t6,
|
||||
t7
|
||||
@ -562,7 +562,7 @@ id select_type table type possible_keys key key_len ref rows Extra
|
||||
1 SIMPLE t6 ALL NULL NULL NULL NULL 3
|
||||
1 SIMPLE t8 ALL NULL NULL NULL NULL 2
|
||||
Warnings:
|
||||
Note 1003 select `test`.`t0`.`a` AS `a`,`test`.`t0`.`b` AS `b`,`test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b`,`test`.`t2`.`a` AS `a`,`test`.`t2`.`b` AS `b`,`test`.`t3`.`a` AS `a`,`test`.`t3`.`b` AS `b`,`test`.`t4`.`a` AS `a`,`test`.`t4`.`b` AS `b`,`test`.`t5`.`a` AS `a`,`test`.`t5`.`b` AS `b`,`test`.`t6`.`a` AS `a`,`test`.`t6`.`b` AS `b`,`test`.`t7`.`a` AS `a`,`test`.`t7`.`b` AS `b`,`test`.`t8`.`a` AS `a`,`test`.`t8`.`b` AS `b` from `test`.`t0` join `test`.`t1` left join (`test`.`t2` left join (`test`.`t3` join `test`.`t4`) on(((`test`.`t3`.`a` = 1) and (`test`.`t2`.`b` = `test`.`t4`.`b`))) join `test`.`t5` left join (`test`.`t6` join `test`.`t7` left join `test`.`t8` on(((`test`.`t7`.`b` = `test`.`t8`.`b`) and (`test`.`t6`.`b` < 10)))) on(((`test`.`t6`.`b` >= 2) and (`test`.`t5`.`b` = `test`.`t7`.`b`)))) on((((`test`.`t3`.`b` = 2) or isnull(`test`.`t3`.`c`)) and ((`test`.`t6`.`b` = 2) or isnull(`test`.`t6`.`c`)) and ((`test`.`t1`.`b` = `test`.`t5`.`b`) or isnull(`test`.`t3`.`c`) or isnull(`test`.`t6`.`c`) or isnull(`test`.`t8`.`c`)) and (`test`.`t1`.`a` <> 2))) where ((`test`.`t0`.`a` = 1) and (`test`.`t0`.`b` = `test`.`t1`.`b`) and ((`test`.`t2`.`a` >= 4) or isnull(`test`.`t2`.`c`)))
|
||||
Note 1003 select `test`.`t0`.`a` AS `a`,`test`.`t0`.`b` AS `b`,`test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b`,`test`.`t2`.`a` AS `a`,`test`.`t2`.`b` AS `b`,`test`.`t3`.`a` AS `a`,`test`.`t3`.`b` AS `b`,`test`.`t4`.`a` AS `a`,`test`.`t4`.`b` AS `b`,`test`.`t5`.`a` AS `a`,`test`.`t5`.`b` AS `b`,`test`.`t6`.`a` AS `a`,`test`.`t6`.`b` AS `b`,`test`.`t7`.`a` AS `a`,`test`.`t7`.`b` AS `b`,`test`.`t8`.`a` AS `a`,`test`.`t8`.`b` AS `b` from `test`.`t0` join `test`.`t1` left join (`test`.`t2` left join (`test`.`t3` join `test`.`t4`) on(((`test`.`t4`.`b` = `test`.`t2`.`b`) and (`test`.`t3`.`a` = 1))) join `test`.`t5` left join (`test`.`t6` join `test`.`t7` left join `test`.`t8` on(((`test`.`t8`.`b` = `test`.`t5`.`b`) and (`test`.`t6`.`b` < 10)))) on(((`test`.`t7`.`b` = `test`.`t5`.`b`) and (`test`.`t6`.`b` >= 2)))) on((((`test`.`t3`.`b` = 2) or isnull(`test`.`t3`.`c`)) and ((`test`.`t6`.`b` = 2) or isnull(`test`.`t6`.`c`)) and ((`test`.`t5`.`b` = `test`.`t0`.`b`) or isnull(`test`.`t3`.`c`) or isnull(`test`.`t6`.`c`) or isnull(`test`.`t8`.`c`)) and (`test`.`t1`.`a` <> 2))) where ((`test`.`t1`.`b` = `test`.`t0`.`b`) and (`test`.`t0`.`a` = 1) and ((`test`.`t2`.`a` >= 4) or isnull(`test`.`t2`.`c`)))
|
||||
SELECT t0.a,t0.b,t1.a,t1.b,t2.a,t2.b,t3.a,t3.b,t4.a,t4.b,
|
||||
t5.a,t5.b,t6.a,t6.b,t7.a,t7.b,t8.a,t8.b
|
||||
FROM t0,t1
|
||||
@ -660,7 +660,7 @@ id select_type table type possible_keys key key_len ref rows Extra
|
||||
1 SIMPLE t8 ALL NULL NULL NULL NULL 2 Using where
|
||||
1 SIMPLE t9 ALL NULL NULL NULL NULL 3 Using where
|
||||
Warnings:
|
||||
Note 1003 select `test`.`t0`.`a` AS `a`,`test`.`t0`.`b` AS `b`,`test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b`,`test`.`t2`.`a` AS `a`,`test`.`t2`.`b` AS `b`,`test`.`t3`.`a` AS `a`,`test`.`t3`.`b` AS `b`,`test`.`t4`.`a` AS `a`,`test`.`t4`.`b` AS `b`,`test`.`t5`.`a` AS `a`,`test`.`t5`.`b` AS `b`,`test`.`t6`.`a` AS `a`,`test`.`t6`.`b` AS `b`,`test`.`t7`.`a` AS `a`,`test`.`t7`.`b` AS `b`,`test`.`t8`.`a` AS `a`,`test`.`t8`.`b` AS `b`,`test`.`t9`.`a` AS `a`,`test`.`t9`.`b` AS `b` from `test`.`t0` join `test`.`t1` left join (`test`.`t2` left join (`test`.`t3` join `test`.`t4`) on(((`test`.`t3`.`a` = 1) and (`test`.`t2`.`b` = `test`.`t4`.`b`))) join `test`.`t5` left join (`test`.`t6` join `test`.`t7` left join `test`.`t8` on(((`test`.`t7`.`b` = `test`.`t8`.`b`) and (`test`.`t6`.`b` < 10)))) on(((`test`.`t6`.`b` >= 2) and (`test`.`t5`.`b` = `test`.`t7`.`b`)))) on((((`test`.`t3`.`b` = 2) or isnull(`test`.`t3`.`c`)) and ((`test`.`t6`.`b` = 2) or isnull(`test`.`t6`.`c`)) and ((`test`.`t1`.`b` = `test`.`t5`.`b`) or isnull(`test`.`t3`.`c`) or isnull(`test`.`t6`.`c`) or isnull(`test`.`t8`.`c`)) and (`test`.`t1`.`a` <> 2))) join `test`.`t9` where ((`test`.`t0`.`a` = 1) and (`test`.`t0`.`b` = `test`.`t1`.`b`) and ((`test`.`t2`.`a` >= 4) or isnull(`test`.`t2`.`c`)) and ((`test`.`t3`.`a` < 5) or isnull(`test`.`t3`.`c`)) and ((`test`.`t3`.`b` = `test`.`t4`.`b`) or isnull(`test`.`t3`.`c`) or isnull(`test`.`t4`.`c`)) and ((`test`.`t5`.`a` >= 2) or isnull(`test`.`t5`.`c`)) and ((`test`.`t6`.`a` >= 4) or isnull(`test`.`t6`.`c`)) and ((`test`.`t7`.`a` <= 2) or isnull(`test`.`t7`.`c`)) and ((`test`.`t8`.`a` < 1) or isnull(`test`.`t8`.`c`)) and ((`test`.`t8`.`b` = `test`.`t9`.`b`) or isnull(`test`.`t8`.`c`)) and (`test`.`t9`.`a` = 1))
|
||||
Note 1003 select `test`.`t0`.`a` AS `a`,`test`.`t0`.`b` AS `b`,`test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b`,`test`.`t2`.`a` AS `a`,`test`.`t2`.`b` AS `b`,`test`.`t3`.`a` AS `a`,`test`.`t3`.`b` AS `b`,`test`.`t4`.`a` AS `a`,`test`.`t4`.`b` AS `b`,`test`.`t5`.`a` AS `a`,`test`.`t5`.`b` AS `b`,`test`.`t6`.`a` AS `a`,`test`.`t6`.`b` AS `b`,`test`.`t7`.`a` AS `a`,`test`.`t7`.`b` AS `b`,`test`.`t8`.`a` AS `a`,`test`.`t8`.`b` AS `b`,`test`.`t9`.`a` AS `a`,`test`.`t9`.`b` AS `b` from `test`.`t0` join `test`.`t1` left join (`test`.`t2` left join (`test`.`t3` join `test`.`t4`) on(((`test`.`t4`.`b` = `test`.`t2`.`b`) and (`test`.`t3`.`a` = 1))) join `test`.`t5` left join (`test`.`t6` join `test`.`t7` left join `test`.`t8` on(((`test`.`t8`.`b` = `test`.`t5`.`b`) and (`test`.`t6`.`b` < 10)))) on(((`test`.`t7`.`b` = `test`.`t5`.`b`) and (`test`.`t6`.`b` >= 2)))) on((((`test`.`t3`.`b` = 2) or isnull(`test`.`t3`.`c`)) and ((`test`.`t6`.`b` = 2) or isnull(`test`.`t6`.`c`)) and ((`test`.`t5`.`b` = `test`.`t0`.`b`) or isnull(`test`.`t3`.`c`) or isnull(`test`.`t6`.`c`) or isnull(`test`.`t8`.`c`)) and (`test`.`t1`.`a` <> 2))) join `test`.`t9` where ((`test`.`t9`.`a` = 1) and (`test`.`t1`.`b` = `test`.`t0`.`b`) and (`test`.`t0`.`a` = 1) and ((`test`.`t2`.`a` >= 4) or isnull(`test`.`t2`.`c`)) and ((`test`.`t3`.`a` < 5) or isnull(`test`.`t3`.`c`)) and ((`test`.`t4`.`b` = `test`.`t3`.`b`) or isnull(`test`.`t3`.`c`) or isnull(`test`.`t4`.`c`)) and ((`test`.`t5`.`a` >= 2) or isnull(`test`.`t5`.`c`)) and ((`test`.`t6`.`a` >= 4) or isnull(`test`.`t6`.`c`)) and ((`test`.`t7`.`a` <= 2) or isnull(`test`.`t7`.`c`)) and ((`test`.`t8`.`a` < 1) or isnull(`test`.`t8`.`c`)) and ((`test`.`t9`.`b` = `test`.`t8`.`b`) or isnull(`test`.`t8`.`c`)))
|
||||
SELECT t9.a,t9.b
|
||||
FROM t9;
|
||||
a b
|
||||
@ -858,7 +858,7 @@ id select_type table type possible_keys key key_len ref rows Extra
|
||||
1 SIMPLE t2 ALL NULL NULL NULL NULL 3
|
||||
1 SIMPLE t4 ALL NULL NULL NULL NULL 2
|
||||
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`.`t3`.`a` AS `a`,`test`.`t3`.`b` AS `b`,`test`.`t4`.`a` AS `a`,`test`.`t4`.`b` AS `b` from `test`.`t1` join `test`.`t3` join `test`.`t2` left join `test`.`t4` on(((`test`.`t3`.`a` = 1) and (`test`.`t2`.`b` = `test`.`t4`.`b`))) where (`test`.`t1`.`a` <= 2)
|
||||
Note 1003 select `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b`,`test`.`t2`.`a` AS `a`,`test`.`t2`.`b` AS `b`,`test`.`t3`.`a` AS `a`,`test`.`t3`.`b` AS `b`,`test`.`t4`.`a` AS `a`,`test`.`t4`.`b` AS `b` from `test`.`t1` join `test`.`t3` join `test`.`t2` left join `test`.`t4` on(((`test`.`t4`.`b` = `test`.`t2`.`b`) and (`test`.`t3`.`a` = 1))) where (`test`.`t1`.`a` <= 2)
|
||||
CREATE INDEX idx_b ON t2(b);
|
||||
EXPLAIN EXTENDED
|
||||
SELECT t2.a,t2.b,t3.a,t3.b,t4.a,t4.b
|
||||
@ -872,7 +872,7 @@ id select_type table type possible_keys key key_len ref rows Extra
|
||||
1 SIMPLE t2 ref idx_b idx_b 5 test.t3.b 2
|
||||
1 SIMPLE t1 ALL NULL NULL NULL NULL 3
|
||||
Warnings:
|
||||
Note 1003 select `test`.`t2`.`a` AS `a`,`test`.`t2`.`b` AS `b`,`test`.`t3`.`a` AS `a`,`test`.`t3`.`b` AS `b`,`test`.`t4`.`a` AS `a`,`test`.`t4`.`b` AS `b` from `test`.`t3` join `test`.`t4` left join (`test`.`t1` join `test`.`t2`) on(((`test`.`t3`.`a` = 1) and (`test`.`t3`.`b` = `test`.`t2`.`b`) and (`test`.`t2`.`b` = `test`.`t4`.`b`))) where 1
|
||||
Note 1003 select `test`.`t2`.`a` AS `a`,`test`.`t2`.`b` AS `b`,`test`.`t3`.`a` AS `a`,`test`.`t3`.`b` AS `b`,`test`.`t4`.`a` AS `a`,`test`.`t4`.`b` AS `b` from `test`.`t3` join `test`.`t4` left join (`test`.`t1` join `test`.`t2`) on(((`test`.`t4`.`b` = `test`.`t3`.`b`) and (`test`.`t2`.`b` = `test`.`t3`.`b`) and (`test`.`t3`.`a` = 1))) where 1
|
||||
SELECT t2.a,t2.b,t3.a,t3.b,t4.a,t4.b
|
||||
FROM t3,t4
|
||||
LEFT JOIN
|
||||
@ -935,7 +935,7 @@ id select_type table type possible_keys key key_len ref rows Extra
|
||||
1 SIMPLE t8 ALL NULL NULL NULL NULL 2 Using where
|
||||
1 SIMPLE t9 ALL NULL NULL NULL NULL 3 Using where
|
||||
Warnings:
|
||||
Note 1003 select `test`.`t0`.`a` AS `a`,`test`.`t0`.`b` AS `b`,`test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b`,`test`.`t2`.`a` AS `a`,`test`.`t2`.`b` AS `b`,`test`.`t3`.`a` AS `a`,`test`.`t3`.`b` AS `b`,`test`.`t4`.`a` AS `a`,`test`.`t4`.`b` AS `b`,`test`.`t5`.`a` AS `a`,`test`.`t5`.`b` AS `b`,`test`.`t6`.`a` AS `a`,`test`.`t6`.`b` AS `b`,`test`.`t7`.`a` AS `a`,`test`.`t7`.`b` AS `b`,`test`.`t8`.`a` AS `a`,`test`.`t8`.`b` AS `b`,`test`.`t9`.`a` AS `a`,`test`.`t9`.`b` AS `b` from `test`.`t0` join `test`.`t1` left join (`test`.`t2` left join (`test`.`t3` join `test`.`t4`) on(((`test`.`t3`.`a` = 1) and (`test`.`t2`.`b` = `test`.`t4`.`b`))) join `test`.`t5` left join (`test`.`t6` join `test`.`t7` left join `test`.`t8` on(((`test`.`t7`.`b` = `test`.`t8`.`b`) and (`test`.`t6`.`b` < 10)))) on(((`test`.`t6`.`b` >= 2) and (`test`.`t5`.`b` = `test`.`t7`.`b`)))) on((((`test`.`t3`.`b` = 2) or isnull(`test`.`t3`.`c`)) and ((`test`.`t6`.`b` = 2) or isnull(`test`.`t6`.`c`)) and ((`test`.`t1`.`b` = `test`.`t5`.`b`) or isnull(`test`.`t3`.`c`) or isnull(`test`.`t6`.`c`) or isnull(`test`.`t8`.`c`)) and (`test`.`t1`.`a` <> 2))) join `test`.`t9` where ((`test`.`t0`.`a` = 1) and (`test`.`t0`.`b` = `test`.`t1`.`b`) and ((`test`.`t2`.`a` >= 4) or isnull(`test`.`t2`.`c`)) and ((`test`.`t3`.`a` < 5) or isnull(`test`.`t3`.`c`)) and ((`test`.`t3`.`b` = `test`.`t4`.`b`) or isnull(`test`.`t3`.`c`) or isnull(`test`.`t4`.`c`)) and ((`test`.`t5`.`a` >= 2) or isnull(`test`.`t5`.`c`)) and ((`test`.`t6`.`a` >= 4) or isnull(`test`.`t6`.`c`)) and ((`test`.`t7`.`a` <= 2) or isnull(`test`.`t7`.`c`)) and ((`test`.`t8`.`a` < 1) or isnull(`test`.`t8`.`c`)) and ((`test`.`t8`.`b` = `test`.`t9`.`b`) or isnull(`test`.`t8`.`c`)) and (`test`.`t9`.`a` = 1))
|
||||
Note 1003 select `test`.`t0`.`a` AS `a`,`test`.`t0`.`b` AS `b`,`test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b`,`test`.`t2`.`a` AS `a`,`test`.`t2`.`b` AS `b`,`test`.`t3`.`a` AS `a`,`test`.`t3`.`b` AS `b`,`test`.`t4`.`a` AS `a`,`test`.`t4`.`b` AS `b`,`test`.`t5`.`a` AS `a`,`test`.`t5`.`b` AS `b`,`test`.`t6`.`a` AS `a`,`test`.`t6`.`b` AS `b`,`test`.`t7`.`a` AS `a`,`test`.`t7`.`b` AS `b`,`test`.`t8`.`a` AS `a`,`test`.`t8`.`b` AS `b`,`test`.`t9`.`a` AS `a`,`test`.`t9`.`b` AS `b` from `test`.`t0` join `test`.`t1` left join (`test`.`t2` left join (`test`.`t3` join `test`.`t4`) on(((`test`.`t4`.`b` = `test`.`t2`.`b`) and (`test`.`t3`.`a` = 1))) join `test`.`t5` left join (`test`.`t6` join `test`.`t7` left join `test`.`t8` on(((`test`.`t8`.`b` = `test`.`t5`.`b`) and (`test`.`t6`.`b` < 10)))) on(((`test`.`t7`.`b` = `test`.`t5`.`b`) and (`test`.`t6`.`b` >= 2)))) on((((`test`.`t3`.`b` = 2) or isnull(`test`.`t3`.`c`)) and ((`test`.`t6`.`b` = 2) or isnull(`test`.`t6`.`c`)) and ((`test`.`t5`.`b` = `test`.`t0`.`b`) or isnull(`test`.`t3`.`c`) or isnull(`test`.`t6`.`c`) or isnull(`test`.`t8`.`c`)) and (`test`.`t1`.`a` <> 2))) join `test`.`t9` where ((`test`.`t9`.`a` = 1) and (`test`.`t1`.`b` = `test`.`t0`.`b`) and (`test`.`t0`.`a` = 1) and ((`test`.`t2`.`a` >= 4) or isnull(`test`.`t2`.`c`)) and ((`test`.`t3`.`a` < 5) or isnull(`test`.`t3`.`c`)) and ((`test`.`t4`.`b` = `test`.`t3`.`b`) or isnull(`test`.`t3`.`c`) or isnull(`test`.`t4`.`c`)) and ((`test`.`t5`.`a` >= 2) or isnull(`test`.`t5`.`c`)) and ((`test`.`t6`.`a` >= 4) or isnull(`test`.`t6`.`c`)) and ((`test`.`t7`.`a` <= 2) or isnull(`test`.`t7`.`c`)) and ((`test`.`t8`.`a` < 1) or isnull(`test`.`t8`.`c`)) and ((`test`.`t9`.`b` = `test`.`t8`.`b`) or isnull(`test`.`t8`.`c`)))
|
||||
CREATE INDEX idx_b ON t4(b);
|
||||
CREATE INDEX idx_b ON t5(b);
|
||||
EXPLAIN EXTENDED
|
||||
@ -986,7 +986,7 @@ id select_type table type possible_keys key key_len ref rows Extra
|
||||
1 SIMPLE t8 ALL NULL NULL NULL NULL 2 Using where
|
||||
1 SIMPLE t9 ALL NULL NULL NULL NULL 3 Using where
|
||||
Warnings:
|
||||
Note 1003 select `test`.`t0`.`a` AS `a`,`test`.`t0`.`b` AS `b`,`test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b`,`test`.`t2`.`a` AS `a`,`test`.`t2`.`b` AS `b`,`test`.`t3`.`a` AS `a`,`test`.`t3`.`b` AS `b`,`test`.`t4`.`a` AS `a`,`test`.`t4`.`b` AS `b`,`test`.`t5`.`a` AS `a`,`test`.`t5`.`b` AS `b`,`test`.`t6`.`a` AS `a`,`test`.`t6`.`b` AS `b`,`test`.`t7`.`a` AS `a`,`test`.`t7`.`b` AS `b`,`test`.`t8`.`a` AS `a`,`test`.`t8`.`b` AS `b`,`test`.`t9`.`a` AS `a`,`test`.`t9`.`b` AS `b` from `test`.`t0` join `test`.`t1` left join (`test`.`t2` left join (`test`.`t3` join `test`.`t4`) on(((`test`.`t3`.`a` = 1) and (`test`.`t2`.`b` = `test`.`t4`.`b`))) join `test`.`t5` left join (`test`.`t6` join `test`.`t7` left join `test`.`t8` on(((`test`.`t7`.`b` = `test`.`t8`.`b`) and (`test`.`t6`.`b` < 10)))) on(((`test`.`t6`.`b` >= 2) and (`test`.`t5`.`b` = `test`.`t7`.`b`)))) on((((`test`.`t3`.`b` = 2) or isnull(`test`.`t3`.`c`)) and ((`test`.`t6`.`b` = 2) or isnull(`test`.`t6`.`c`)) and ((`test`.`t1`.`b` = `test`.`t5`.`b`) or isnull(`test`.`t3`.`c`) or isnull(`test`.`t6`.`c`) or isnull(`test`.`t8`.`c`)) and (`test`.`t1`.`a` <> 2))) join `test`.`t9` where ((`test`.`t0`.`a` = 1) and (`test`.`t0`.`b` = `test`.`t1`.`b`) and ((`test`.`t2`.`a` >= 4) or isnull(`test`.`t2`.`c`)) and ((`test`.`t3`.`a` < 5) or isnull(`test`.`t3`.`c`)) and ((`test`.`t3`.`b` = `test`.`t4`.`b`) or isnull(`test`.`t3`.`c`) or isnull(`test`.`t4`.`c`)) and ((`test`.`t5`.`a` >= 2) or isnull(`test`.`t5`.`c`)) and ((`test`.`t6`.`a` >= 4) or isnull(`test`.`t6`.`c`)) and ((`test`.`t7`.`a` <= 2) or isnull(`test`.`t7`.`c`)) and ((`test`.`t8`.`a` < 1) or isnull(`test`.`t8`.`c`)) and ((`test`.`t8`.`b` = `test`.`t9`.`b`) or isnull(`test`.`t8`.`c`)) and (`test`.`t9`.`a` = 1))
|
||||
Note 1003 select `test`.`t0`.`a` AS `a`,`test`.`t0`.`b` AS `b`,`test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b`,`test`.`t2`.`a` AS `a`,`test`.`t2`.`b` AS `b`,`test`.`t3`.`a` AS `a`,`test`.`t3`.`b` AS `b`,`test`.`t4`.`a` AS `a`,`test`.`t4`.`b` AS `b`,`test`.`t5`.`a` AS `a`,`test`.`t5`.`b` AS `b`,`test`.`t6`.`a` AS `a`,`test`.`t6`.`b` AS `b`,`test`.`t7`.`a` AS `a`,`test`.`t7`.`b` AS `b`,`test`.`t8`.`a` AS `a`,`test`.`t8`.`b` AS `b`,`test`.`t9`.`a` AS `a`,`test`.`t9`.`b` AS `b` from `test`.`t0` join `test`.`t1` left join (`test`.`t2` left join (`test`.`t3` join `test`.`t4`) on(((`test`.`t4`.`b` = `test`.`t2`.`b`) and (`test`.`t3`.`a` = 1))) join `test`.`t5` left join (`test`.`t6` join `test`.`t7` left join `test`.`t8` on(((`test`.`t8`.`b` = `test`.`t5`.`b`) and (`test`.`t6`.`b` < 10)))) on(((`test`.`t7`.`b` = `test`.`t5`.`b`) and (`test`.`t6`.`b` >= 2)))) on((((`test`.`t3`.`b` = 2) or isnull(`test`.`t3`.`c`)) and ((`test`.`t6`.`b` = 2) or isnull(`test`.`t6`.`c`)) and ((`test`.`t5`.`b` = `test`.`t0`.`b`) or isnull(`test`.`t3`.`c`) or isnull(`test`.`t6`.`c`) or isnull(`test`.`t8`.`c`)) and (`test`.`t1`.`a` <> 2))) join `test`.`t9` where ((`test`.`t9`.`a` = 1) and (`test`.`t1`.`b` = `test`.`t0`.`b`) and (`test`.`t0`.`a` = 1) and ((`test`.`t2`.`a` >= 4) or isnull(`test`.`t2`.`c`)) and ((`test`.`t3`.`a` < 5) or isnull(`test`.`t3`.`c`)) and ((`test`.`t4`.`b` = `test`.`t3`.`b`) or isnull(`test`.`t3`.`c`) or isnull(`test`.`t4`.`c`)) and ((`test`.`t5`.`a` >= 2) or isnull(`test`.`t5`.`c`)) and ((`test`.`t6`.`a` >= 4) or isnull(`test`.`t6`.`c`)) and ((`test`.`t7`.`a` <= 2) or isnull(`test`.`t7`.`c`)) and ((`test`.`t8`.`a` < 1) or isnull(`test`.`t8`.`c`)) and ((`test`.`t9`.`b` = `test`.`t8`.`b`) or isnull(`test`.`t8`.`c`)))
|
||||
CREATE INDEX idx_b ON t8(b);
|
||||
EXPLAIN EXTENDED
|
||||
SELECT t0.a,t0.b,t1.a,t1.b,t2.a,t2.b,t3.a,t3.b,t4.a,t4.b,
|
||||
@ -1033,10 +1033,10 @@ id select_type table type possible_keys key key_len ref rows Extra
|
||||
1 SIMPLE t5 ALL NULL NULL NULL NULL 3 Using where
|
||||
1 SIMPLE t7 ALL NULL NULL NULL NULL 2 Using where
|
||||
1 SIMPLE t6 ALL NULL NULL NULL NULL 3 Using where
|
||||
1 SIMPLE t8 ref idx_b idx_b 5 test.t7.b 2 Using where
|
||||
1 SIMPLE t8 ref idx_b idx_b 5 test.t5.b 2 Using where
|
||||
1 SIMPLE t9 ALL NULL NULL NULL NULL 3 Using where
|
||||
Warnings:
|
||||
Note 1003 select `test`.`t0`.`a` AS `a`,`test`.`t0`.`b` AS `b`,`test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b`,`test`.`t2`.`a` AS `a`,`test`.`t2`.`b` AS `b`,`test`.`t3`.`a` AS `a`,`test`.`t3`.`b` AS `b`,`test`.`t4`.`a` AS `a`,`test`.`t4`.`b` AS `b`,`test`.`t5`.`a` AS `a`,`test`.`t5`.`b` AS `b`,`test`.`t6`.`a` AS `a`,`test`.`t6`.`b` AS `b`,`test`.`t7`.`a` AS `a`,`test`.`t7`.`b` AS `b`,`test`.`t8`.`a` AS `a`,`test`.`t8`.`b` AS `b`,`test`.`t9`.`a` AS `a`,`test`.`t9`.`b` AS `b` from `test`.`t0` join `test`.`t1` left join (`test`.`t2` left join (`test`.`t3` join `test`.`t4`) on(((`test`.`t3`.`a` = 1) and (`test`.`t2`.`b` = `test`.`t4`.`b`))) join `test`.`t5` left join (`test`.`t6` join `test`.`t7` left join `test`.`t8` on(((`test`.`t7`.`b` = `test`.`t8`.`b`) and (`test`.`t6`.`b` < 10)))) on(((`test`.`t6`.`b` >= 2) and (`test`.`t5`.`b` = `test`.`t7`.`b`)))) on((((`test`.`t3`.`b` = 2) or isnull(`test`.`t3`.`c`)) and ((`test`.`t6`.`b` = 2) or isnull(`test`.`t6`.`c`)) and ((`test`.`t1`.`b` = `test`.`t5`.`b`) or isnull(`test`.`t3`.`c`) or isnull(`test`.`t6`.`c`) or isnull(`test`.`t8`.`c`)) and (`test`.`t1`.`a` <> 2))) join `test`.`t9` where ((`test`.`t0`.`a` = 1) and (`test`.`t0`.`b` = `test`.`t1`.`b`) and ((`test`.`t2`.`a` >= 4) or isnull(`test`.`t2`.`c`)) and ((`test`.`t3`.`a` < 5) or isnull(`test`.`t3`.`c`)) and ((`test`.`t3`.`b` = `test`.`t4`.`b`) or isnull(`test`.`t3`.`c`) or isnull(`test`.`t4`.`c`)) and ((`test`.`t5`.`a` >= 2) or isnull(`test`.`t5`.`c`)) and ((`test`.`t6`.`a` >= 4) or isnull(`test`.`t6`.`c`)) and ((`test`.`t7`.`a` <= 2) or isnull(`test`.`t7`.`c`)) and ((`test`.`t8`.`a` < 1) or isnull(`test`.`t8`.`c`)) and ((`test`.`t8`.`b` = `test`.`t9`.`b`) or isnull(`test`.`t8`.`c`)) and (`test`.`t9`.`a` = 1))
|
||||
Note 1003 select `test`.`t0`.`a` AS `a`,`test`.`t0`.`b` AS `b`,`test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b`,`test`.`t2`.`a` AS `a`,`test`.`t2`.`b` AS `b`,`test`.`t3`.`a` AS `a`,`test`.`t3`.`b` AS `b`,`test`.`t4`.`a` AS `a`,`test`.`t4`.`b` AS `b`,`test`.`t5`.`a` AS `a`,`test`.`t5`.`b` AS `b`,`test`.`t6`.`a` AS `a`,`test`.`t6`.`b` AS `b`,`test`.`t7`.`a` AS `a`,`test`.`t7`.`b` AS `b`,`test`.`t8`.`a` AS `a`,`test`.`t8`.`b` AS `b`,`test`.`t9`.`a` AS `a`,`test`.`t9`.`b` AS `b` from `test`.`t0` join `test`.`t1` left join (`test`.`t2` left join (`test`.`t3` join `test`.`t4`) on(((`test`.`t4`.`b` = `test`.`t2`.`b`) and (`test`.`t3`.`a` = 1))) join `test`.`t5` left join (`test`.`t6` join `test`.`t7` left join `test`.`t8` on(((`test`.`t8`.`b` = `test`.`t5`.`b`) and (`test`.`t6`.`b` < 10)))) on(((`test`.`t7`.`b` = `test`.`t5`.`b`) and (`test`.`t6`.`b` >= 2)))) on((((`test`.`t3`.`b` = 2) or isnull(`test`.`t3`.`c`)) and ((`test`.`t6`.`b` = 2) or isnull(`test`.`t6`.`c`)) and ((`test`.`t5`.`b` = `test`.`t0`.`b`) or isnull(`test`.`t3`.`c`) or isnull(`test`.`t6`.`c`) or isnull(`test`.`t8`.`c`)) and (`test`.`t1`.`a` <> 2))) join `test`.`t9` where ((`test`.`t9`.`a` = 1) and (`test`.`t1`.`b` = `test`.`t0`.`b`) and (`test`.`t0`.`a` = 1) and ((`test`.`t2`.`a` >= 4) or isnull(`test`.`t2`.`c`)) and ((`test`.`t3`.`a` < 5) or isnull(`test`.`t3`.`c`)) and ((`test`.`t4`.`b` = `test`.`t3`.`b`) or isnull(`test`.`t3`.`c`) or isnull(`test`.`t4`.`c`)) and ((`test`.`t5`.`a` >= 2) or isnull(`test`.`t5`.`c`)) and ((`test`.`t6`.`a` >= 4) or isnull(`test`.`t6`.`c`)) and ((`test`.`t7`.`a` <= 2) or isnull(`test`.`t7`.`c`)) and ((`test`.`t8`.`a` < 1) or isnull(`test`.`t8`.`c`)) and ((`test`.`t9`.`b` = `test`.`t8`.`b`) or isnull(`test`.`t8`.`c`)))
|
||||
CREATE INDEX idx_b ON t1(b);
|
||||
CREATE INDEX idx_a ON t0(a);
|
||||
EXPLAIN EXTENDED
|
||||
@ -1084,10 +1084,10 @@ id select_type table type possible_keys key key_len ref rows Extra
|
||||
1 SIMPLE t5 ALL NULL NULL NULL NULL 3 Using where
|
||||
1 SIMPLE t7 ALL NULL NULL NULL NULL 2 Using where
|
||||
1 SIMPLE t6 ALL NULL NULL NULL NULL 3 Using where
|
||||
1 SIMPLE t8 ref idx_b idx_b 5 test.t7.b 2 Using where
|
||||
1 SIMPLE t8 ref idx_b idx_b 5 test.t5.b 2 Using where
|
||||
1 SIMPLE t9 ALL NULL NULL NULL NULL 3 Using where
|
||||
Warnings:
|
||||
Note 1003 select `test`.`t0`.`a` AS `a`,`test`.`t0`.`b` AS `b`,`test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b`,`test`.`t2`.`a` AS `a`,`test`.`t2`.`b` AS `b`,`test`.`t3`.`a` AS `a`,`test`.`t3`.`b` AS `b`,`test`.`t4`.`a` AS `a`,`test`.`t4`.`b` AS `b`,`test`.`t5`.`a` AS `a`,`test`.`t5`.`b` AS `b`,`test`.`t6`.`a` AS `a`,`test`.`t6`.`b` AS `b`,`test`.`t7`.`a` AS `a`,`test`.`t7`.`b` AS `b`,`test`.`t8`.`a` AS `a`,`test`.`t8`.`b` AS `b`,`test`.`t9`.`a` AS `a`,`test`.`t9`.`b` AS `b` from `test`.`t0` join `test`.`t1` left join (`test`.`t2` left join (`test`.`t3` join `test`.`t4`) on(((`test`.`t3`.`a` = 1) and (`test`.`t2`.`b` = `test`.`t4`.`b`))) join `test`.`t5` left join (`test`.`t6` join `test`.`t7` left join `test`.`t8` on(((`test`.`t7`.`b` = `test`.`t8`.`b`) and (`test`.`t6`.`b` < 10)))) on(((`test`.`t6`.`b` >= 2) and (`test`.`t5`.`b` = `test`.`t7`.`b`)))) on((((`test`.`t3`.`b` = 2) or isnull(`test`.`t3`.`c`)) and ((`test`.`t6`.`b` = 2) or isnull(`test`.`t6`.`c`)) and ((`test`.`t1`.`b` = `test`.`t5`.`b`) or isnull(`test`.`t3`.`c`) or isnull(`test`.`t6`.`c`) or isnull(`test`.`t8`.`c`)) and (`test`.`t1`.`a` <> 2))) join `test`.`t9` where ((`test`.`t0`.`a` = 1) and (`test`.`t0`.`b` = `test`.`t1`.`b`) and ((`test`.`t2`.`a` >= 4) or isnull(`test`.`t2`.`c`)) and ((`test`.`t3`.`a` < 5) or isnull(`test`.`t3`.`c`)) and ((`test`.`t3`.`b` = `test`.`t4`.`b`) or isnull(`test`.`t3`.`c`) or isnull(`test`.`t4`.`c`)) and ((`test`.`t5`.`a` >= 2) or isnull(`test`.`t5`.`c`)) and ((`test`.`t6`.`a` >= 4) or isnull(`test`.`t6`.`c`)) and ((`test`.`t7`.`a` <= 2) or isnull(`test`.`t7`.`c`)) and ((`test`.`t8`.`a` < 1) or isnull(`test`.`t8`.`c`)) and ((`test`.`t8`.`b` = `test`.`t9`.`b`) or isnull(`test`.`t8`.`c`)) and (`test`.`t9`.`a` = 1))
|
||||
Note 1003 select `test`.`t0`.`a` AS `a`,`test`.`t0`.`b` AS `b`,`test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b`,`test`.`t2`.`a` AS `a`,`test`.`t2`.`b` AS `b`,`test`.`t3`.`a` AS `a`,`test`.`t3`.`b` AS `b`,`test`.`t4`.`a` AS `a`,`test`.`t4`.`b` AS `b`,`test`.`t5`.`a` AS `a`,`test`.`t5`.`b` AS `b`,`test`.`t6`.`a` AS `a`,`test`.`t6`.`b` AS `b`,`test`.`t7`.`a` AS `a`,`test`.`t7`.`b` AS `b`,`test`.`t8`.`a` AS `a`,`test`.`t8`.`b` AS `b`,`test`.`t9`.`a` AS `a`,`test`.`t9`.`b` AS `b` from `test`.`t0` join `test`.`t1` left join (`test`.`t2` left join (`test`.`t3` join `test`.`t4`) on(((`test`.`t4`.`b` = `test`.`t2`.`b`) and (`test`.`t3`.`a` = 1))) join `test`.`t5` left join (`test`.`t6` join `test`.`t7` left join `test`.`t8` on(((`test`.`t8`.`b` = `test`.`t5`.`b`) and (`test`.`t6`.`b` < 10)))) on(((`test`.`t7`.`b` = `test`.`t5`.`b`) and (`test`.`t6`.`b` >= 2)))) on((((`test`.`t3`.`b` = 2) or isnull(`test`.`t3`.`c`)) and ((`test`.`t6`.`b` = 2) or isnull(`test`.`t6`.`c`)) and ((`test`.`t5`.`b` = `test`.`t0`.`b`) or isnull(`test`.`t3`.`c`) or isnull(`test`.`t6`.`c`) or isnull(`test`.`t8`.`c`)) and (`test`.`t1`.`a` <> 2))) join `test`.`t9` where ((`test`.`t9`.`a` = 1) and (`test`.`t1`.`b` = `test`.`t0`.`b`) and (`test`.`t0`.`a` = 1) and ((`test`.`t2`.`a` >= 4) or isnull(`test`.`t2`.`c`)) and ((`test`.`t3`.`a` < 5) or isnull(`test`.`t3`.`c`)) and ((`test`.`t4`.`b` = `test`.`t3`.`b`) or isnull(`test`.`t3`.`c`) or isnull(`test`.`t4`.`c`)) and ((`test`.`t5`.`a` >= 2) or isnull(`test`.`t5`.`c`)) and ((`test`.`t6`.`a` >= 4) or isnull(`test`.`t6`.`c`)) and ((`test`.`t7`.`a` <= 2) or isnull(`test`.`t7`.`c`)) and ((`test`.`t8`.`a` < 1) or isnull(`test`.`t8`.`c`)) and ((`test`.`t9`.`b` = `test`.`t8`.`b`) or isnull(`test`.`t8`.`c`)))
|
||||
SELECT t0.a,t0.b,t1.a,t1.b,t2.a,t2.b,t3.a,t3.b,t4.a,t4.b,
|
||||
t5.a,t5.b,t6.a,t6.b,t7.a,t7.b,t8.a,t8.b,t9.a,t9.b
|
||||
FROM t0,t1
|
||||
|
@ -12,5 +12,5 @@ select * from t1 where a is null;
|
||||
a b
|
||||
explain select * from t1 where b is null;
|
||||
id select_type table type possible_keys key key_len ref rows Extra
|
||||
1 SIMPLE NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables
|
||||
1 SIMPLE NULL NULL NULL NULL NULL NULL NULL Impossible WHERE
|
||||
drop table t1;
|
||||
|
@ -220,24 +220,22 @@ insert into t1 (x) values (1),(2),(3),(4),(5),(6),(7),(8),(9);
|
||||
update t1 set y=x;
|
||||
explain select * from t1, t1 t2 where t1.y = 2 and t2.x between 7 and t1.y+0;
|
||||
id select_type table type possible_keys key key_len ref rows Extra
|
||||
1 SIMPLE t1 ref y y 5 const 1 Using where
|
||||
1 SIMPLE t2 range x x 5 NULL 4 Using where
|
||||
1 SIMPLE NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables
|
||||
explain select * from t1, t1 t2 where t1.y = 2 and t2.x >= 7 and t2.x <= t1.y+0;
|
||||
id select_type table type possible_keys key key_len ref rows Extra
|
||||
1 SIMPLE t1 ref y y 5 const 1 Using where
|
||||
1 SIMPLE t2 range x x 5 NULL 4 Using where
|
||||
1 SIMPLE NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables
|
||||
explain select * from t1, t1 t2 where t1.y = 2 and t2.x between t1.y-1 and t1.y+1;
|
||||
id select_type table type possible_keys key key_len ref rows Extra
|
||||
1 SIMPLE t1 ref y y 5 const 1 Using where
|
||||
1 SIMPLE t2 ALL x NULL NULL NULL 9 Range checked for each record (index map: 0x1)
|
||||
1 SIMPLE t2 range x x 5 NULL 3 Using where
|
||||
explain select * from t1, t1 t2 where t1.y = 2 and t2.x >= t1.y-1 and t2.x <= t1.y+1;
|
||||
id select_type table type possible_keys key key_len ref rows Extra
|
||||
1 SIMPLE t1 ref y y 5 const 1 Using where
|
||||
1 SIMPLE t2 ALL x NULL NULL NULL 9 Range checked for each record (index map: 0x1)
|
||||
1 SIMPLE t2 range x x 5 NULL 3 Using where
|
||||
explain select * from t1, t1 t2 where t1.y = 2 and t2.x between 0 and t1.y;
|
||||
id select_type table type possible_keys key key_len ref rows Extra
|
||||
1 SIMPLE t1 ref y y 5 const 1 Using where
|
||||
1 SIMPLE t2 ALL x NULL NULL NULL 9 Using where
|
||||
1 SIMPLE t2 range x x 5 NULL 2 Using where
|
||||
explain select * from t1, t1 t2 where t1.y = 2 and t2.x >= 0 and t2.x <= t1.y;
|
||||
id select_type table type possible_keys key key_len ref rows Extra
|
||||
1 SIMPLE t1 ref y y 5 const 1 Using where
|
||||
@ -256,12 +254,12 @@ INSERT INTO t2 VALUES (0),(0),(1),(1),(2),(2);
|
||||
explain select * from t1, t2 where (t1.key1 <t2.keya + 1) and t2.keya=3;
|
||||
id select_type table type possible_keys key key_len ref rows Extra
|
||||
1 SIMPLE t2 ref j1 j1 4 const 1 Using index
|
||||
1 SIMPLE t1 ALL i1 NULL NULL NULL 4 Range checked for each record (index map: 0x1)
|
||||
1 SIMPLE t1 index i1 i1 4 NULL 4 Using where; Using index
|
||||
explain select * from t1 force index(i1), t2 force index(j1) where
|
||||
(t1.key1 <t2.keya + 1) and t2.keya=3;
|
||||
id select_type table type possible_keys key key_len ref rows Extra
|
||||
1 SIMPLE t2 ref j1 j1 4 const 1 Using index
|
||||
1 SIMPLE t1 ALL i1 NULL NULL NULL 4 Range checked for each record (index map: 0x1)
|
||||
1 SIMPLE t1 index i1 i1 4 NULL 4 Using where; Using index
|
||||
DROP TABLE t1,t2;
|
||||
CREATE TABLE t1 (
|
||||
a int(11) default NULL,
|
||||
@ -415,14 +413,26 @@ count(*)
|
||||
select count(*) from t2;
|
||||
count(*)
|
||||
1026
|
||||
analyze table t1,t2;
|
||||
Table Op Msg_type Msg_text
|
||||
test.t1 analyze status OK
|
||||
test.t2 analyze status Table is already up to date
|
||||
explain select * from t1, t2 where t1.uid=t2.uid AND t1.uid > 0;
|
||||
id select_type table type possible_keys key key_len ref rows Extra
|
||||
1 SIMPLE t1 range uid_index uid_index 4 NULL 128 Using where
|
||||
1 SIMPLE t2 ref uid_index uid_index 4 test.t1.uid 38
|
||||
explain select * from t1, t2 where t1.uid=t2.uid AND t2.uid > 0;
|
||||
id select_type table type possible_keys key key_len ref rows Extra
|
||||
1 SIMPLE t1 range uid_index uid_index 4 NULL 128 Using where
|
||||
1 SIMPLE t2 ref uid_index uid_index 4 test.t1.uid 38
|
||||
explain select * from t1, t2 where t1.uid=t2.uid AND t1.uid != 0;
|
||||
id select_type table type possible_keys key key_len ref rows Extra
|
||||
1 SIMPLE t1 range uid_index uid_index 4 NULL 129 Using where
|
||||
1 SIMPLE t2 ref uid_index uid_index 4 test.t1.uid 38
|
||||
explain select * from t1, t2 where t1.uid=t2.uid AND t2.uid != 0;
|
||||
id select_type table type possible_keys key key_len ref rows Extra
|
||||
1 SIMPLE t1 range uid_index uid_index 4 NULL 129 Using where
|
||||
1 SIMPLE t2 ref uid_index uid_index 4 test.t1.uid 38
|
||||
select * from t1, t2 where t1.uid=t2.uid AND t1.uid > 0;
|
||||
id name uid id name uid
|
||||
1001 A 1 1001 A 1
|
||||
|
@ -1375,7 +1375,7 @@ id select_type table type possible_keys key key_len ref rows Extra
|
||||
explain select t2.companynr,companyname from t4 left join t2 using (companynr) where t2.companynr > 0 and t4.companynr > 0;
|
||||
id select_type table type possible_keys key key_len ref rows Extra
|
||||
1 SIMPLE t2 ALL NULL NULL NULL NULL 1199 Using where
|
||||
1 SIMPLE t4 eq_ref PRIMARY PRIMARY 1 test.t2.companynr 1 Using where
|
||||
1 SIMPLE t4 eq_ref PRIMARY PRIMARY 1 test.t2.companynr 1
|
||||
explain select t2.companynr,companyname from t4 left join t2 using (companynr) where t2.companynr > 0 or t2.companynr is null;
|
||||
id select_type table type possible_keys key key_len ref rows Extra
|
||||
1 SIMPLE t4 ALL NULL NULL NULL NULL 12
|
||||
|
@ -331,7 +331,7 @@ id select_type table type possible_keys key key_len ref rows Extra
|
||||
2 DEPENDENT SUBQUERY t7 eq_ref PRIMARY PRIMARY 4 test.t6.clinic_uq 1 Using index
|
||||
Warnings:
|
||||
Note 1276 Field or reference 'clinic_uq' of SELECT #2 was resolved in SELECT #1
|
||||
Note 1003 select `test`.`t6`.`patient_uq` AS `patient_uq`,`test`.`t6`.`clinic_uq` AS `clinic_uq` from `test`.`t6` where exists(select 1 AS `Not_used` from `test`.`t7` where (`test`.`t7`.`uq` = `test`.`t6`.`clinic_uq`))
|
||||
Note 1003 select `test`.`t6`.`patient_uq` AS `patient_uq`,`test`.`t6`.`clinic_uq` AS `clinic_uq` from `test`.`t6` where exists(select 1 AS `Not_used` from `test`.`t7` where (`test`.`t6`.`clinic_uq` = `test`.`t7`.`uq`))
|
||||
select * from t1 where a= (select a from t2,t4 where t2.b=t4.b);
|
||||
ERROR 23000: Column 'a' in field list is ambiguous
|
||||
drop table t1,t2,t3;
|
||||
@ -545,7 +545,7 @@ id select_type table type possible_keys key key_len ref rows Extra
|
||||
1 PRIMARY t1 const PRIMARY,numreponse PRIMARY 7 const,const 1 Using index
|
||||
2 SUBQUERY NULL NULL NULL NULL NULL NULL NULL Select tables optimized away
|
||||
Warnings:
|
||||
Note 1003 select `test`.`t1`.`numreponse` AS `numreponse` from `test`.`t1` where ((`test`.`t1`.`numeropost` = _latin1'1') and (`test`.`t1`.`numreponse` = 3))
|
||||
Note 1003 select `test`.`t1`.`numreponse` AS `numreponse` from `test`.`t1` where ((`test`.`t1`.`numreponse` = (select max(`test`.`t1`.`numreponse`) AS `MAX(numreponse)` from `test`.`t1` where (`test`.`t1`.`numeropost` = _latin1'1'))) and (`test`.`t1`.`numeropost` = _latin1'1'))
|
||||
drop table t1;
|
||||
CREATE TABLE t1 (a int(1));
|
||||
INSERT INTO t1 VALUES (1);
|
||||
@ -1313,7 +1313,7 @@ id select_type table type possible_keys key key_len ref rows Extra
|
||||
2 DEPENDENT SUBQUERY t1 eq_ref PRIMARY PRIMARY 4 func 1 Using where
|
||||
2 DEPENDENT SUBQUERY t3 eq_ref PRIMARY PRIMARY 4 test.t1.b 1 Using where; Using index
|
||||
Warnings:
|
||||
Note 1003 select `test`.`t2`.`a` AS `a` from `test`.`t2` where <in_optimizer>(`test`.`t2`.`a`,<exists>(select 1 AS `Not_used` from `test`.`t1` join `test`.`t3` where ((`test`.`t1`.`b` = `test`.`t3`.`a`) and (<cache>(`test`.`t2`.`a`) = `test`.`t1`.`a`))))
|
||||
Note 1003 select `test`.`t2`.`a` AS `a` from `test`.`t2` where <in_optimizer>(`test`.`t2`.`a`,<exists>(select 1 AS `Not_used` from `test`.`t1` join `test`.`t3` where ((`test`.`t3`.`a` = `test`.`t1`.`b`) and (<cache>(`test`.`t2`.`a`) = `test`.`t1`.`a`))))
|
||||
drop table t1, t2, t3;
|
||||
create table t1 (a int, b int, index a (a,b));
|
||||
create table t2 (a int, index a (a));
|
||||
@ -1675,10 +1675,10 @@ Note 1003 select `test`.`t1`.`id` AS `id`,`test`.`t1`.`text` AS `text` from `tes
|
||||
explain extended select * from t1 as tt where not exists (select id from t1 where id < 8 and (id = tt.id or id is null) having id is not null);
|
||||
id select_type table type possible_keys key key_len ref rows Extra
|
||||
1 PRIMARY tt ALL NULL NULL NULL NULL 12 Using where
|
||||
2 DEPENDENT SUBQUERY t1 eq_ref PRIMARY PRIMARY 4 test.tt.id 7 Using where; Using index
|
||||
2 DEPENDENT SUBQUERY t1 eq_ref PRIMARY PRIMARY 4 test.tt.id 1 Using where; Using index
|
||||
Warnings:
|
||||
Note 1276 Field or reference 'tt.id' of SELECT #2 was resolved in SELECT #1
|
||||
Note 1003 select `test`.`tt`.`id` AS `id`,`test`.`tt`.`text` AS `text` from `test`.`t1` `tt` where not(exists(select `test`.`t1`.`id` AS `id` from `test`.`t1` where ((`test`.`t1`.`id` < 8) and ((`test`.`t1`.`id` = `test`.`tt`.`id`) or isnull(`test`.`t1`.`id`))) having (`test`.`t1`.`id` is not null)))
|
||||
Note 1003 select `test`.`tt`.`id` AS `id`,`test`.`tt`.`text` AS `text` from `test`.`t1` `tt` where not(exists(select `test`.`t1`.`id` AS `id` from `test`.`t1` where ((`test`.`t1`.`id` < 8) and (`test`.`tt`.`id` = `test`.`t1`.`id`)) having (`test`.`t1`.`id` is not null)))
|
||||
insert into t1 (id, text) values (1000, 'text1000'), (1001, 'text1001');
|
||||
create table t2 (id int not null, text varchar(20) not null default '', primary key (id));
|
||||
insert into t2 (id, text) values (1, 'text1'), (2, 'text2'), (3, 'text3'), (4, 'text4'), (5, 'text5'), (6, 'text6'), (7, 'text7'), (8, 'text8'), (9, 'text9'), (10, 'text10'), (11, 'text1'), (12, 'text2'), (13, 'text3'), (14, 'text4'), (15, 'text5'), (16, 'text6'), (17, 'text7'), (18, 'text8'), (19, 'text9'), (20, 'text10'),(21, 'text1'), (22, 'text2'), (23, 'text3'), (24, 'text4'), (25, 'text5'), (26, 'text6'), (27, 'text7'), (28, 'text8'), (29, 'text9'), (30, 'text10'), (31, 'text1'), (32, 'text2'), (33, 'text3'), (34, 'text4'), (35, 'text5'), (36, 'text6'), (37, 'text7'), (38, 'text8'), (39, 'text9'), (40, 'text10'), (41, 'text1'), (42, 'text2'), (43, 'text3'), (44, 'text4'), (45, 'text5'), (46, 'text6'), (47, 'text7'), (48, 'text8'), (49, 'text9'), (50, 'text10');
|
||||
@ -1704,7 +1704,7 @@ id select_type table type possible_keys key key_len ref rows Extra
|
||||
1 SIMPLE b eq_ref PRIMARY PRIMARY 4 test.a.id 2
|
||||
1 SIMPLE c eq_ref PRIMARY PRIMARY 4 func 1 Using where
|
||||
Warnings:
|
||||
Note 1003 select `test`.`a`.`id` AS `id`,`test`.`a`.`text` AS `text`,`test`.`b`.`id` AS `id`,`test`.`b`.`text` AS `text`,`test`.`c`.`id` AS `id`,`test`.`c`.`text` AS `text` from `test`.`t1` `a` left join `test`.`t2` `b` on(((`test`.`a`.`id` = `test`.`b`.`id`) or isnull(`test`.`b`.`id`))) join `test`.`t1` `c` where (if(isnull(`test`.`b`.`id`),1000,`test`.`b`.`id`) = `test`.`c`.`id`)
|
||||
Note 1003 select `test`.`a`.`id` AS `id`,`test`.`a`.`text` AS `text`,`test`.`b`.`id` AS `id`,`test`.`b`.`text` AS `text`,`test`.`c`.`id` AS `id`,`test`.`c`.`text` AS `text` from `test`.`t1` `a` left join `test`.`t2` `b` on(((`test`.`b`.`id` = `test`.`a`.`id`) or isnull(`test`.`b`.`id`))) join `test`.`t1` `c` where (if(isnull(`test`.`b`.`id`),1000,`test`.`b`.`id`) = `test`.`c`.`id`)
|
||||
drop table t1,t2;
|
||||
create table t1 (a int);
|
||||
insert into t1 values (1);
|
||||
@ -1832,7 +1832,7 @@ id select_type table type possible_keys key key_len ref rows Extra
|
||||
2 DEPENDENT SUBQUERY t1 ALL NULL NULL NULL NULL 2 Using where
|
||||
Warnings:
|
||||
Note 1276 Field or reference 'up.a' of SELECT #2 was resolved in SELECT #1
|
||||
Note 1003 select `test`.`up`.`a` AS `a`,`test`.`up`.`b` AS `b` from `test`.`t1` `up` where exists(select 1 AS `Not_used` from `test`.`t1` where (`test`.`t1`.`a` = `test`.`up`.`a`))
|
||||
Note 1003 select `test`.`up`.`a` AS `a`,`test`.`up`.`b` AS `b` from `test`.`t1` `up` where exists(select 1 AS `Not_used` from `test`.`t1` where (`test`.`up`.`a` = `test`.`t1`.`a`))
|
||||
drop table t1;
|
||||
CREATE TABLE t1 (t1_a int);
|
||||
INSERT INTO t1 VALUES (1);
|
||||
|
@ -378,8 +378,12 @@ insert into t2(id, uid, name) select id, uid, name from t1;
|
||||
select count(*) from t1;
|
||||
select count(*) from t2;
|
||||
|
||||
analyze table t1,t2;
|
||||
|
||||
explain select * from t1, t2 where t1.uid=t2.uid AND t1.uid > 0;
|
||||
explain select * from t1, t2 where t1.uid=t2.uid AND t2.uid > 0;
|
||||
explain select * from t1, t2 where t1.uid=t2.uid AND t1.uid != 0;
|
||||
explain select * from t1, t2 where t1.uid=t2.uid AND t2.uid != 0;
|
||||
|
||||
select * from t1, t2 where t1.uid=t2.uid AND t1.uid > 0;
|
||||
select * from t1, t2 where t1.uid=t2.uid AND t1.uid != 0;
|
||||
|
122
sql/item.cc
122
sql/item.cc
@ -447,6 +447,7 @@ bool DTCollation::aggregate(DTCollation &dt, bool superset_conversion)
|
||||
|
||||
Item_field::Item_field(Field *f)
|
||||
:Item_ident(NullS, f->table_name, f->field_name),
|
||||
item_equal(0), no_const_subst(0),
|
||||
have_privileges(0), any_privileges(0)
|
||||
{
|
||||
set_field(f);
|
||||
@ -457,6 +458,7 @@ Item_field::Item_field(Field *f)
|
||||
Item_field::Item_field(THD *thd, Field *f)
|
||||
:Item_ident(NullS, thd->strdup(f->table_name),
|
||||
thd->strdup(f->field_name)),
|
||||
item_equal(0), no_const_subst(0),
|
||||
have_privileges(0), any_privileges(0)
|
||||
{
|
||||
set_field(f);
|
||||
@ -469,6 +471,8 @@ Item_field::Item_field(THD *thd, Item_field *item)
|
||||
:Item_ident(thd, item),
|
||||
field(item->field),
|
||||
result_field(item->result_field),
|
||||
item_equal(item->item_equal),
|
||||
no_const_subst(item->no_const_subst),
|
||||
have_privileges(item->have_privileges),
|
||||
any_privileges(item->any_privileges)
|
||||
{
|
||||
@ -1621,7 +1625,123 @@ void Item_field::cleanup()
|
||||
I.e. we can drop 'field'.
|
||||
*/
|
||||
field= result_field= 0;
|
||||
DBUG_VOID_RETURN;
|
||||
}
|
||||
|
||||
/*
|
||||
Find a field among specified multiple equalities
|
||||
|
||||
SYNOPSIS
|
||||
find_item_equal()
|
||||
cond_equal reference to list of multiple equalities where
|
||||
the field (this object) is to be looked for
|
||||
|
||||
DESCRIPTION
|
||||
The function first searches the field among multiple equalities
|
||||
of the current level (in the cond_equal->current_level list).
|
||||
If it fails, it continues searching in upper levels accessed
|
||||
through a pointer cond_equal->upper_levels.
|
||||
The search terminates as soon as a multiple equality containing
|
||||
the field is found.
|
||||
|
||||
RETURN VALUES
|
||||
First Item_equal containing the field, if success
|
||||
0, otherwise
|
||||
*/
|
||||
Item_equal *Item_field::find_item_equal(COND_EQUAL *cond_equal)
|
||||
{
|
||||
Item_equal *item= 0;
|
||||
while (cond_equal)
|
||||
{
|
||||
List_iterator_fast<Item_equal> li(cond_equal->current_level);
|
||||
while ((item= li++))
|
||||
{
|
||||
if (item->contains(field))
|
||||
return item;
|
||||
}
|
||||
/*
|
||||
The field is not found in any of the multiple equalities
|
||||
of the current level. Look for it in upper levels
|
||||
*/
|
||||
cond_equal= cond_equal->upper_levels;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
Set a pointer to the multiple equality the field reference belongs to (if any)
|
||||
|
||||
SYNOPSIS
|
||||
equal_fields_propagator()
|
||||
arg - reference to list of multiple equalities where
|
||||
the field (this object) is to be looked for
|
||||
|
||||
DESCRIPTION
|
||||
The function looks for a multiple equality containing the field item
|
||||
among those referenced by arg.
|
||||
In the case such equality exists the function does the following.
|
||||
If the found multiple equality contains a constant, then the field
|
||||
reference is substituted for this constant, otherwise it sets a pointer
|
||||
to the multiple equality in the field item.
|
||||
|
||||
NOTES
|
||||
This function is supposed to be called as a callback parameter in calls
|
||||
of the transform method.
|
||||
|
||||
RETURN VALUES
|
||||
pointer to the replacing constant item, if the field item was substituted
|
||||
pointer to the field item, otherwise.
|
||||
*/
|
||||
|
||||
Item *Item_field::equal_fields_propagator(byte *arg)
|
||||
{
|
||||
if (no_const_subst)
|
||||
return this;
|
||||
item_equal= find_item_equal((COND_EQUAL *) arg);
|
||||
Item *item= 0;
|
||||
if (item_equal)
|
||||
item= item_equal->get_const();
|
||||
if (!item)
|
||||
item= this;
|
||||
return item;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
Set a pointer to the multiple equality the field reference belongs to (if any)
|
||||
|
||||
SYNOPSIS
|
||||
replace_equal_field_processor()
|
||||
arg - a dummy parameter, is not used here
|
||||
|
||||
DESCRIPTION
|
||||
The function replaces a pointer to a field in the Item_field object
|
||||
by a pointer to another field.
|
||||
The replacement field is taken from the very beginning of
|
||||
the item_equal list which the Item_field object refers to (belongs to)
|
||||
If the Item_field object does not refer any Item_equal object,
|
||||
nothing is done.
|
||||
|
||||
NOTES
|
||||
This function is supposed to be called as a callback parameter in calls
|
||||
of the walk method.
|
||||
|
||||
RETURN VALUES
|
||||
0
|
||||
*/
|
||||
|
||||
bool Item_field::replace_equal_field_processor(byte *arg)
|
||||
{
|
||||
if (item_equal)
|
||||
{
|
||||
Item_field *subst= item_equal->get_first();
|
||||
if (!field->eq(subst->field))
|
||||
{
|
||||
field= subst->field;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void Item::init_make_field(Send_field *tmp_field,
|
||||
|
31
sql/item.h
31
sql/item.h
@ -90,6 +90,7 @@ public:
|
||||
};
|
||||
|
||||
typedef bool (Item::*Item_processor)(byte *arg);
|
||||
typedef Item* (Item::*Item_transformer) (byte *arg);
|
||||
|
||||
class Item {
|
||||
Item(const Item &); /* Prevent use of these */
|
||||
@ -261,9 +262,16 @@ public:
|
||||
return (this->*processor)(arg);
|
||||
}
|
||||
|
||||
virtual Item* transform(Item_transformer transformer, byte *arg)
|
||||
{
|
||||
return (this->*transformer)(arg);
|
||||
}
|
||||
|
||||
virtual bool remove_dependence_processor(byte * arg) { return 0; }
|
||||
virtual bool remove_fixed(byte * arg) { fixed= 0; return 0; }
|
||||
virtual bool collect_item_field_processor(byte * arg) { return 0; }
|
||||
virtual Item *equal_fields_propagator(byte * arg) { return this; }
|
||||
virtual bool replace_equal_field_processor(byte * arg) { return 0; }
|
||||
|
||||
virtual Item *this_item() { return this; } /* For SPs mostly. */
|
||||
virtual Item *this_const_item() const { return const_cast<Item*>(this); } /* For SPs mostly. */
|
||||
@ -441,6 +449,8 @@ public:
|
||||
bool any_privileges, bool allocate_view_names);
|
||||
};
|
||||
|
||||
class Item_equal;
|
||||
class COND_EQUAL;
|
||||
|
||||
class Item_field :public Item_ident
|
||||
{
|
||||
@ -448,6 +458,8 @@ protected:
|
||||
void set_field(Field *field);
|
||||
public:
|
||||
Field *field,*result_field;
|
||||
Item_equal *item_equal;
|
||||
bool no_const_subst;
|
||||
/*
|
||||
if any_privileges set to TRUE then here real effective privileges will
|
||||
be stored
|
||||
@ -459,7 +471,8 @@ public:
|
||||
Item_field(const char *db_par,const char *table_name_par,
|
||||
const char *field_name_par)
|
||||
:Item_ident(db_par,table_name_par,field_name_par),
|
||||
field(0), result_field(0), have_privileges(0), any_privileges(0)
|
||||
field(0), result_field(0), item_equal(0), no_const_subst(0),
|
||||
have_privileges(0), any_privileges(0)
|
||||
{ collation.set(DERIVATION_IMPLICIT); }
|
||||
// Constructor need to process subselect with temporary tables (see Item)
|
||||
Item_field(THD *thd, Item_field *item);
|
||||
@ -500,6 +513,9 @@ public:
|
||||
Item *get_tmp_table_item(THD *thd);
|
||||
bool collect_item_field_processor(byte * arg);
|
||||
void cleanup();
|
||||
Item_equal *find_item_equal(COND_EQUAL *cond_equal);
|
||||
Item *equal_fields_propagator(byte *arg);
|
||||
bool replace_equal_field_processor(byte *arg);
|
||||
inline uint32 max_disp_length() { return field->max_length(); }
|
||||
Item_field *filed_for_view_update() { return this; }
|
||||
friend class Item_default_value;
|
||||
@ -1177,6 +1193,19 @@ public:
|
||||
return arg->walk(processor, args) ||
|
||||
(this->*processor)(args);
|
||||
}
|
||||
|
||||
/*
|
||||
This method like the walk method traverses the item tree, but
|
||||
at the same time it can replace some nodes in the tree
|
||||
*/
|
||||
Item *transform(Item_transformer transformer, byte *args)
|
||||
{
|
||||
Item *new_item= arg->transform(transformer, args);
|
||||
if (!new_item)
|
||||
return 0;
|
||||
arg= new_item;
|
||||
return (this->*transformer)(args);
|
||||
}
|
||||
};
|
||||
|
||||
class Item_insert_value : public Item_field
|
||||
|
@ -231,6 +231,8 @@ void Item_bool_func2::fix_length_and_dec()
|
||||
conv->collation.set(args[weak]->collation.derivation);
|
||||
conv->fix_fields(thd, 0, &conv);
|
||||
}
|
||||
if (args[weak]->type() == FIELD_ITEM)
|
||||
((Item_field *)args[weak])->no_const_subst= 1;
|
||||
args[weak]= conv ? conv : args[weak];
|
||||
}
|
||||
}
|
||||
@ -256,7 +258,7 @@ void Item_bool_func2::fix_length_and_dec()
|
||||
}
|
||||
}
|
||||
}
|
||||
if (args[1]->type() == FIELD_ITEM)
|
||||
if (args[1]->type() == FIELD_ITEM /* && !args[1]->const_item() */)
|
||||
{
|
||||
Field *field=((Item_field*) args[1])->field;
|
||||
if (field->store_for_compare())
|
||||
@ -1956,7 +1958,7 @@ Item_cond::fix_fields(THD *thd, TABLE_LIST *tables, Item **ref)
|
||||
char buff[sizeof(char*)]; // Max local vars in function
|
||||
#endif
|
||||
not_null_tables_cache= used_tables_cache= 0;
|
||||
const_item_cache= 0;
|
||||
const_item_cache= 1;
|
||||
/*
|
||||
and_table_cache is the value that Item_cond_or() returns for
|
||||
not_null_tables()
|
||||
@ -1987,7 +1989,7 @@ Item_cond::fix_fields(THD *thd, TABLE_LIST *tables, Item **ref)
|
||||
tmp_table_map= item->not_null_tables();
|
||||
not_null_tables_cache|= tmp_table_map;
|
||||
and_tables_cache&= tmp_table_map;
|
||||
const_item_cache&= item->const_item();
|
||||
const_item_cache&= item->const_item();
|
||||
with_sum_func= with_sum_func || item->with_sum_func;
|
||||
if (item->maybe_null)
|
||||
maybe_null=1;
|
||||
@ -2008,12 +2010,50 @@ bool Item_cond::walk(Item_processor processor, byte *arg)
|
||||
return Item_func::walk(processor, arg);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
Transform an Item_cond object with a transformer callback function
|
||||
|
||||
SYNOPSIS
|
||||
transform()
|
||||
transformer the transformer callback function to be applied to the nodes
|
||||
of the tree of the object
|
||||
arg parameter to be passed to the transformer
|
||||
|
||||
DESCRIPTION
|
||||
The function recursively applies the transform method with the
|
||||
same transformer to each member item of the codition 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 transform method 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::transform(Item_transformer transformer, byte *arg)
|
||||
{
|
||||
List_iterator<Item> li(list);
|
||||
Item *item;
|
||||
while ((item= li++))
|
||||
{
|
||||
Item *new_item= item->transform(transformer, arg);
|
||||
if (!new_item)
|
||||
return 0;
|
||||
if (new_item != item)
|
||||
li.replace(new_item);
|
||||
}
|
||||
return Item_func::transform(transformer, arg);
|
||||
}
|
||||
|
||||
|
||||
void Item_cond::split_sum_func(Item **ref_pointer_array, List<Item> &fields)
|
||||
{
|
||||
List_iterator<Item> li(list);
|
||||
Item *item;
|
||||
used_tables_cache=0;
|
||||
const_item_cache=0;
|
||||
const_item_cache=1;
|
||||
while ((item=li++))
|
||||
{
|
||||
if (item->with_sum_func && item->type() != SUM_FUNC_ITEM)
|
||||
@ -2050,7 +2090,7 @@ void Item_cond::update_used_tables()
|
||||
{
|
||||
item->update_used_tables();
|
||||
used_tables_cache|= item->used_tables();
|
||||
const_item_cache&= item->const_item();
|
||||
const_item_cache&= item->const_item();
|
||||
}
|
||||
}
|
||||
|
||||
@ -2854,3 +2894,290 @@ Item *Item_bool_rowready_func2::negated_item()
|
||||
DBUG_ASSERT(0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
Item_equal::Item_equal(Item_field *f1, Item_field *f2)
|
||||
: Item_bool_func(), const_item(0), eval_item(0), cond_false(0)
|
||||
{
|
||||
const_item_cache= 0;
|
||||
fields.push_back(f1);
|
||||
fields.push_back(f2);
|
||||
}
|
||||
|
||||
Item_equal::Item_equal(Item *c, Item_field *f)
|
||||
: Item_bool_func(), eval_item(0), cond_false(0)
|
||||
{
|
||||
const_item_cache= 0;
|
||||
fields.push_back(f);
|
||||
const_item= c;
|
||||
}
|
||||
|
||||
Item_equal::Item_equal(Item_equal *item_equal)
|
||||
: Item_bool_func(), eval_item(0), cond_false(0)
|
||||
{
|
||||
const_item_cache= 0;
|
||||
List_iterator_fast<Item_field> li(item_equal->fields);
|
||||
Item_field *item;
|
||||
while ((item= li++))
|
||||
{
|
||||
fields.push_back(item);
|
||||
}
|
||||
const_item= item_equal->const_item;
|
||||
cond_false= item_equal->cond_false;
|
||||
}
|
||||
|
||||
void Item_equal::add(Item *c)
|
||||
{
|
||||
if (cond_false)
|
||||
return;
|
||||
if (!const_item)
|
||||
{
|
||||
const_item= c;
|
||||
return;
|
||||
}
|
||||
Item_func_eq *func= new Item_func_eq(c, const_item);
|
||||
func->set_cmp_func();
|
||||
func->quick_fix_field();
|
||||
cond_false = !(func->val_int());
|
||||
}
|
||||
|
||||
void Item_equal::add(Item_field *f)
|
||||
{
|
||||
fields.push_back(f);
|
||||
}
|
||||
|
||||
uint Item_equal::members()
|
||||
{
|
||||
uint count= 0;
|
||||
List_iterator_fast<Item_field> li(fields);
|
||||
Item_field *item;
|
||||
while ((item= li++))
|
||||
count++;
|
||||
return count;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
Check whether a field is referred in the multiple equality
|
||||
|
||||
SYNOPSIS
|
||||
contains()
|
||||
field field whose occurence is to be checked
|
||||
|
||||
DESCRIPTION
|
||||
The function checks whether field is occured in the Item_equal object
|
||||
|
||||
RETURN VALUES
|
||||
1 if nultiple equality contains a reference to field
|
||||
0 otherwise
|
||||
*/
|
||||
|
||||
bool Item_equal::contains(Field *field)
|
||||
{
|
||||
List_iterator_fast<Item_field> it(fields);
|
||||
Item_field *item;
|
||||
while ((item= it++))
|
||||
{
|
||||
if (field->eq(item->field))
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
Join members of another Item_equal object
|
||||
|
||||
SYNOPSIS
|
||||
merge()
|
||||
item multiple equality whose members are to be joined
|
||||
|
||||
DESCRIPTION
|
||||
The function actually merges two multiple equalitis.
|
||||
After this operation the Item_equal object additionally contains
|
||||
the field items of another item of the type Item_equal.
|
||||
If the optional constant items are not equal the cond_false flag is
|
||||
set to 1.
|
||||
|
||||
RETURN VALUES
|
||||
none
|
||||
*/
|
||||
|
||||
void Item_equal::merge(Item_equal *item)
|
||||
{
|
||||
fields.concat(&item->fields);
|
||||
Item *c= item->const_item;
|
||||
if (c)
|
||||
{
|
||||
/*
|
||||
The flag cond_false will be set to 1 after this, if
|
||||
the multiple equality already contains a constant and its
|
||||
value is not equal to the value of c.
|
||||
*/
|
||||
add(const_item);
|
||||
}
|
||||
cond_false|= item->cond_false;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
Order field items in multiple equality according to a sorting criteria
|
||||
|
||||
SYNOPSIS
|
||||
sort()
|
||||
cmp function to compare field item
|
||||
arg context extra parameter for the cmp function
|
||||
|
||||
DESCRIPTION
|
||||
The function perform ordering of the field items in the Item_equal
|
||||
object according to the criteria determined by the cmp callback parameter.
|
||||
If cmp(item_field1,item_field2,arg)<0 than item_field1 must be
|
||||
placed after item_fiel2.
|
||||
|
||||
IMPLEMENTATION
|
||||
The function sorts field items by the exchange sort algorithm.
|
||||
The list of field items is looked through and whenever two neighboring
|
||||
members follow in a wrong order they are swapped. This is performed
|
||||
again and again until we get all members in a right order.
|
||||
|
||||
RETURN VALUES
|
||||
None
|
||||
*/
|
||||
|
||||
void Item_equal::sort(Item_field_cmpfunc cmp, void *arg)
|
||||
{
|
||||
bool swap;
|
||||
List_iterator<Item_field> it(fields);
|
||||
do
|
||||
{
|
||||
Item_field *item1= it++;
|
||||
Item_field **ref1= it.ref();
|
||||
Item_field *item2;
|
||||
|
||||
swap= FALSE;
|
||||
while ((item2= it++))
|
||||
{
|
||||
Item_field **ref2= it.ref();
|
||||
if (cmp(item1, item2, arg) < 0)
|
||||
{
|
||||
Item_field *item= *ref1;
|
||||
*ref1= *ref2;
|
||||
*ref2= item;
|
||||
swap= TRUE;
|
||||
}
|
||||
else
|
||||
{
|
||||
item1= item2;
|
||||
ref1= ref2;
|
||||
}
|
||||
}
|
||||
it.rewind();
|
||||
} while (swap);
|
||||
}
|
||||
|
||||
bool Item_equal::fix_fields(THD *thd, TABLE_LIST *tables, Item **ref)
|
||||
{
|
||||
List_iterator_fast<Item_field> li(fields);
|
||||
Item *item;
|
||||
not_null_tables_cache= used_tables_cache= 0;
|
||||
const_item_cache= 0;
|
||||
while ((item=li++))
|
||||
{
|
||||
table_map tmp_table_map;
|
||||
used_tables_cache|= item->used_tables();
|
||||
tmp_table_map= item->not_null_tables();
|
||||
not_null_tables_cache|= tmp_table_map;
|
||||
if (item->maybe_null)
|
||||
maybe_null=1;
|
||||
}
|
||||
fix_length_and_dec();
|
||||
fixed= 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
void Item_equal::update_used_tables()
|
||||
{
|
||||
List_iterator_fast<Item_field> li(fields);
|
||||
Item *item;
|
||||
not_null_tables_cache= used_tables_cache= 0;
|
||||
if ((const_item_cache= cond_false))
|
||||
return;
|
||||
while ((item=li++))
|
||||
{
|
||||
item->update_used_tables();
|
||||
used_tables_cache|= item->used_tables();
|
||||
const_item_cache&= item->const_item();
|
||||
}
|
||||
}
|
||||
|
||||
longlong Item_equal::val_int()
|
||||
{
|
||||
if (cond_false)
|
||||
return 0;
|
||||
List_iterator_fast<Item_field> it(fields);
|
||||
Item *item= const_item ? const_item : it++;
|
||||
if ((null_value= item->null_value))
|
||||
return 0;
|
||||
eval_item->store_value(item);
|
||||
while ((item= it++))
|
||||
{
|
||||
if ((null_value= item->null_value) || eval_item->cmp(item))
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
void Item_equal::fix_length_and_dec()
|
||||
{
|
||||
Item *item= const_item ? const_item : get_first();
|
||||
eval_item= cmp_item::get_comparator(item);
|
||||
if (item->result_type() == STRING_RESULT)
|
||||
eval_item->cmp_charset= cmp_collation.collation;
|
||||
}
|
||||
|
||||
bool Item_equal::walk(Item_processor processor, byte *arg)
|
||||
{
|
||||
List_iterator_fast<Item_field> it(fields);
|
||||
Item *item;
|
||||
while ((item= it++))
|
||||
if (item->walk(processor, arg))
|
||||
return 1;
|
||||
return Item_func::walk(processor, arg);
|
||||
}
|
||||
|
||||
Item *Item_equal::transform(Item_transformer transformer, byte *arg)
|
||||
{
|
||||
List_iterator<Item_field> it(fields);
|
||||
Item *item;
|
||||
while ((item= it++))
|
||||
{
|
||||
Item *new_item= item->transform(transformer, arg);
|
||||
if (!new_item)
|
||||
return 0;
|
||||
if (new_item != item)
|
||||
it.replace((Item_field *) new_item);
|
||||
}
|
||||
return Item_func::transform(transformer, arg);
|
||||
}
|
||||
|
||||
void Item_equal::print(String *str)
|
||||
{
|
||||
str->append(func_name());
|
||||
str->append('(');
|
||||
List_iterator_fast<Item_field> it(fields);
|
||||
Item *item;
|
||||
if (const_item)
|
||||
const_item->print(str);
|
||||
else
|
||||
{
|
||||
item= it++;
|
||||
item->print(str);
|
||||
}
|
||||
while ((item= it++))
|
||||
{
|
||||
str->append(',');
|
||||
str->append(' ');
|
||||
item->print(str);
|
||||
}
|
||||
str->append(')');
|
||||
}
|
||||
|
||||
|
@ -20,6 +20,9 @@
|
||||
#ifdef __GNUC__
|
||||
#pragma interface /* gcc class implementation */
|
||||
#endif
|
||||
#ifdef __GNUC__
|
||||
template class List_iterator_fast<Item_field>;
|
||||
#endif
|
||||
|
||||
extern Item_result item_cmp_type(Item_result a,Item_result b);
|
||||
class Item_bool_func2;
|
||||
@ -27,6 +30,8 @@ class Arg_comparator;
|
||||
|
||||
typedef int (Arg_comparator::*arg_cmp_func)();
|
||||
|
||||
typedef int (*Item_field_cmpfunc)(Item_field *f1, Item_field *f2, void *arg);
|
||||
|
||||
class Arg_comparator: public Sql_alloc
|
||||
{
|
||||
Item **a, **b;
|
||||
@ -957,6 +962,7 @@ public:
|
||||
Item_cond(List<Item> &nlist)
|
||||
:Item_bool_func(), list(nlist), abort_on_null(0) {}
|
||||
bool add(Item *item) { return list.push_back(item); }
|
||||
void add_at_head(List<Item> *nlist) { list.prepand(nlist); }
|
||||
bool fix_fields(THD *, struct st_table_list *, Item **ref);
|
||||
|
||||
enum Type type() const { return COND_ITEM; }
|
||||
@ -969,13 +975,151 @@ public:
|
||||
void top_level_item() { abort_on_null=1; }
|
||||
void copy_andor_arguments(THD *thd, Item_cond *item);
|
||||
bool walk(Item_processor processor, byte *arg);
|
||||
Item *transform(Item_transformer transformer, byte *arg);
|
||||
void neg_arguments(THD *thd);
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
The class Item_equal is used to represent conjuctions of equality
|
||||
predicates of the form field1 = field2, and field=const in where
|
||||
conditions and on expressions.
|
||||
|
||||
All equality predicates of the form field1=field2 contained in a
|
||||
conjuction are substituted for a sequence of items of this class.
|
||||
An item of this class Item_equal(f1,f2,...fk) respresents a
|
||||
multiple equality f1=f2=...=fk.
|
||||
|
||||
If a conjuction contains predicates f1=f2 and f2=f3, a new item of
|
||||
this class is created Item_equal(f1,f2,f3) representing the multiple
|
||||
equality f1=f2=f3 that substitutes the above equality predicates in
|
||||
the conjuction.
|
||||
A conjuction of the predicates f2=f1 and f3=f1 and f3=f2 will be
|
||||
substituted for the item representing the same multiple equality
|
||||
f1=f2=f3.
|
||||
An item Item_equal(f1,f2) can appear instead of a conjuction of
|
||||
f2=f1 and f1=f2, or instead of just the predicate f1=f2.
|
||||
|
||||
An item of the class Item_equal inherites equalities from outer
|
||||
conjunctive levels.
|
||||
|
||||
Suppose we have a where condition of the following form:
|
||||
WHERE f1=f2 AND f3=f4 AND f3=f5 AND ... AND (...OR (f1=f3 AND ...)).
|
||||
In this case:
|
||||
f1=f2 will be substituted for Item_equal(f1,f2);
|
||||
f3=f4 and f3=f5 will be substituted for Item_equal(f3,f4,f5);
|
||||
f1=f3 will be substituted for Item_equal(f1,f2,f3,f4,f5);
|
||||
|
||||
An object of the class Item_equal can contain an optional constant
|
||||
item c. Thenit represents a multiple equality of the form
|
||||
c=f1=...=fk.
|
||||
|
||||
Objects of the class Item_equal are used for the following:
|
||||
|
||||
1. An object Item_equal(t1.f1,...,tk.fk) allows us to consider any
|
||||
pair of tables ti and tj as joined by an equi-condition.
|
||||
Thus it provide us with additional access paths from table to table.
|
||||
|
||||
2. An object Item_equal(t1.f1,...,tk.fk) is applied to deduce new
|
||||
SARGable predicates:
|
||||
f1=...=fk AND P(fi) => f1=...=fk AND P(fi) AND P(fj).
|
||||
It also can give us additional index scans and can allow us to
|
||||
improve selectivity estimates.
|
||||
|
||||
3. An object Item_equal(t1.f1,...,tk.fk) is used to optimize the
|
||||
selected execution plan for the query: if table ti is accessed
|
||||
before the table tj then in any predicate P in the where condition
|
||||
the occurence of tj.fj is substituted for ti.fi. This can allow
|
||||
an evaluation of the predicate at an earlier step.
|
||||
|
||||
When feature 1 is supported they say that join transitive closure
|
||||
is employed.
|
||||
When feature 2 is supported they say that search argument transitive
|
||||
closure is employed.
|
||||
Both features are usually supported by preprocessing original query and
|
||||
adding additional predicates.
|
||||
We do not just add predicates, we rather dynamically replace some
|
||||
predicates that can not be used to access tables in the investigated
|
||||
plan for those, obtained by substitution of some fields for equal fields,
|
||||
that can be used.
|
||||
*/
|
||||
|
||||
class Item_equal: public Item_bool_func
|
||||
{
|
||||
List<Item_field> fields; /* list of equal field items */
|
||||
Item *const_item; /* optional constant item equal to fields items */
|
||||
cmp_item *eval_item;
|
||||
bool cond_false;
|
||||
DTCollation cmp_collation;
|
||||
public:
|
||||
inline Item_equal()
|
||||
: Item_bool_func(), const_item(0), eval_item(0), cond_false(0)
|
||||
{ const_item_cache=0 ;}
|
||||
Item_equal(Item_field *f1, Item_field *f2);
|
||||
Item_equal(Item *c, Item_field *f);
|
||||
Item_equal(Item_equal *item_equal);
|
||||
inline Item* get_const() { return const_item; }
|
||||
void add(Item *c);
|
||||
void add(Item_field *f);
|
||||
uint members();
|
||||
bool contains(Field *field);
|
||||
Item_field* get_first() { return fields.head(); }
|
||||
void merge(Item_equal *item);
|
||||
enum Functype functype() const { return MULT_EQUAL_FUNC; }
|
||||
longlong val_int();
|
||||
const char *func_name() const { return "multiple equal"; }
|
||||
optimize_type select_optimize() const { return OPTIMIZE_EQUAL; }
|
||||
void sort(Item_field_cmpfunc cmp, void *arg);
|
||||
friend class Item_equal_iterator;
|
||||
void fix_length_and_dec();
|
||||
bool fix_fields(THD *thd, TABLE_LIST *tables, Item **ref);
|
||||
void update_used_tables();
|
||||
bool walk(Item_processor processor, byte *arg);
|
||||
Item *transform(Item_transformer transformer, byte *arg);
|
||||
void print(String *str);
|
||||
CHARSET_INFO *compare_collation()
|
||||
{ return fields.head()->collation.collation; }
|
||||
};
|
||||
|
||||
class COND_EQUAL
|
||||
{
|
||||
public:
|
||||
uint max_members; /* max number of members the current level
|
||||
list and all lower level lists */
|
||||
COND_EQUAL *upper_levels; /* multiple equalities of upper and levels */
|
||||
List<Item_equal> current_level; /* list of multiple equalities of
|
||||
the current and level */
|
||||
COND_EQUAL()
|
||||
{
|
||||
max_members= 0;
|
||||
upper_levels= 0;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
class Item_equal_iterator :List_iterator_fast<Item_field>
|
||||
{
|
||||
public:
|
||||
inline Item_equal_iterator(Item_equal &item_equal)
|
||||
:List_iterator_fast<Item_field> (item_equal.fields)
|
||||
{}
|
||||
inline Item_field* operator++(int)
|
||||
{
|
||||
Item_field *item= (*(List_iterator_fast<Item_field> *) this)++;
|
||||
return item;
|
||||
}
|
||||
inline void rewind(void)
|
||||
{
|
||||
List_iterator_fast<Item_field>::rewind();
|
||||
}
|
||||
};
|
||||
|
||||
class Item_cond_and :public Item_cond
|
||||
{
|
||||
public:
|
||||
COND_EQUAL cond_equal; /* contains list of Item_equal objects for
|
||||
the current and level and reference
|
||||
to multiple equalities of upper and levels */
|
||||
Item_cond_and() :Item_cond() {}
|
||||
Item_cond_and(Item *i1,Item *i2) :Item_cond(i1,i2) {}
|
||||
Item_cond_and(THD *thd, Item_cond_and *item) :Item_cond(thd, item) {}
|
||||
|
@ -260,6 +260,45 @@ bool Item_func::walk (Item_processor processor, byte *argument)
|
||||
return (this->*processor)(argument);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
Transform an Item_func object with a transformer callback function
|
||||
|
||||
SYNOPSIS
|
||||
transform()
|
||||
transformer the transformer callback function to be applied to the nodes
|
||||
of the tree of the object
|
||||
argument parameter to be passed to the transformer
|
||||
|
||||
DESCRIPTION
|
||||
The function recursively applies the transform method with the
|
||||
same transformer to each argument the function.
|
||||
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 transform method 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::transform(Item_transformer transformer, byte *argument)
|
||||
{
|
||||
if (arg_count)
|
||||
{
|
||||
Item **arg,**arg_end;
|
||||
for (arg= args, arg_end= args+arg_count; arg != arg_end; arg++)
|
||||
{
|
||||
Item *new_item= (*arg)->transform(transformer, argument);
|
||||
if (!new_item)
|
||||
return 0;
|
||||
*arg= new_item;
|
||||
}
|
||||
}
|
||||
return (this->*transformer)(argument);
|
||||
}
|
||||
|
||||
|
||||
void Item_func::split_sum_func(Item **ref_pointer_array, List<Item> &fields)
|
||||
{
|
||||
Item **arg, **arg_end;
|
||||
|
@ -40,7 +40,8 @@ public:
|
||||
enum Functype { UNKNOWN_FUNC,EQ_FUNC,EQUAL_FUNC,NE_FUNC,LT_FUNC,LE_FUNC,
|
||||
GE_FUNC,GT_FUNC,FT_FUNC,
|
||||
LIKE_FUNC,NOTLIKE_FUNC,ISNULL_FUNC,ISNOTNULL_FUNC,
|
||||
COND_AND_FUNC, COND_OR_FUNC, COND_XOR_FUNC, BETWEEN, IN_FUNC,
|
||||
COND_AND_FUNC, COND_OR_FUNC, COND_XOR_FUNC,
|
||||
BETWEEN, IN_FUNC, MULT_EQUAL_FUNC,
|
||||
INTERVAL_FUNC, ISNOTNULLTEST_FUNC,
|
||||
SP_EQUALS_FUNC, SP_DISJOINT_FUNC,SP_INTERSECTS_FUNC,
|
||||
SP_TOUCHES_FUNC,SP_CROSSES_FUNC,SP_WITHIN_FUNC,
|
||||
@ -50,7 +51,8 @@ public:
|
||||
NOT_FUNC, NOT_ALL_FUNC,
|
||||
NOW_FUNC, TRIG_COND_FUNC,
|
||||
GUSERVAR_FUNC};
|
||||
enum optimize_type { OPTIMIZE_NONE,OPTIMIZE_KEY,OPTIMIZE_OP, OPTIMIZE_NULL };
|
||||
enum optimize_type { OPTIMIZE_NONE,OPTIMIZE_KEY,OPTIMIZE_OP, OPTIMIZE_NULL,
|
||||
OPTIMIZE_EQUAL };
|
||||
enum Type type() const { return FUNC_ITEM; }
|
||||
virtual enum Functype functype() const { return UNKNOWN_FUNC; }
|
||||
Item_func(void):
|
||||
@ -150,6 +152,7 @@ public:
|
||||
bool allow_superset_comversion= FALSE);
|
||||
|
||||
bool walk(Item_processor processor, byte *arg);
|
||||
Item *transform(Item_transformer transformer, byte *arg);
|
||||
};
|
||||
|
||||
|
||||
|
@ -145,6 +145,18 @@ bool Item_row::walk(Item_processor processor, byte *arg)
|
||||
return (this->*processor)(arg);
|
||||
}
|
||||
|
||||
Item *Item_row::transform(Item_transformer transformer, byte *arg)
|
||||
{
|
||||
for (uint i= 0; i < arg_count; i++)
|
||||
{
|
||||
Item *new_item= items[i]->transform(transformer, arg);
|
||||
if (!new_item)
|
||||
return 0;
|
||||
items[i]= new_item;
|
||||
}
|
||||
return (this->*transformer)(arg);
|
||||
}
|
||||
|
||||
void Item_row::bring_value()
|
||||
{
|
||||
for (uint i= 0; i < arg_count; i++)
|
||||
|
@ -65,6 +65,7 @@ public:
|
||||
void print(String *str);
|
||||
|
||||
bool walk(Item_processor processor, byte *arg);
|
||||
Item *transform(Item_transformer transformer, byte *arg);
|
||||
|
||||
uint cols() { return arg_count; }
|
||||
Item* el(uint i) { return items[i]; }
|
||||
|
@ -428,6 +428,14 @@ public:
|
||||
return item->walk(processor, arg) ||
|
||||
Item_str_func::walk(processor, arg);
|
||||
}
|
||||
Item *transform(Item_transformer transformer, byte *arg)
|
||||
{
|
||||
Item *new_item= item->transform(transformer, arg);
|
||||
if (!new_item)
|
||||
return 0;
|
||||
item= new_item;
|
||||
return Item_str_func::transform(transformer, arg);
|
||||
}
|
||||
void print(String *str);
|
||||
};
|
||||
|
||||
|
250
sql/opt_range.cc
250
sql/opt_range.cc
@ -3233,12 +3233,98 @@ QUICK_SELECT_I *TRP_ROR_UNION::make_quick(PARAM *param,
|
||||
DBUG_RETURN(quick_roru);
|
||||
}
|
||||
|
||||
/****************************************************************************/
|
||||
|
||||
/*
|
||||
Build a SEL_TREE for a simple predicate
|
||||
|
||||
SYNOPSIS
|
||||
get_func_mm_tree()
|
||||
param PARAM from SQL_SELECT::test_quick_select
|
||||
cond_func item for the predicate
|
||||
field field in the predicate
|
||||
value constant in the predicate
|
||||
cmp_type compare type for the field
|
||||
|
||||
RETURN
|
||||
Pointer to thre built tree
|
||||
*/
|
||||
|
||||
static SEL_TREE *get_func_mm_tree(PARAM *param, Item_func *cond_func,
|
||||
Field *field, Item *value,
|
||||
Item_result cmp_type)
|
||||
{
|
||||
SEL_TREE *tree= 0;
|
||||
DBUG_ENTER("get_func_mm_tree");
|
||||
|
||||
switch (cond_func->functype()) {
|
||||
case Item_func::NE_FUNC:
|
||||
tree= get_mm_parts(param, cond_func, field, Item_func::LT_FUNC,
|
||||
value, cmp_type);
|
||||
if (tree)
|
||||
{
|
||||
tree= tree_or(param, tree, get_mm_parts(param, cond_func, field,
|
||||
Item_func::GT_FUNC,
|
||||
value, cmp_type));
|
||||
}
|
||||
break;
|
||||
case Item_func::BETWEEN:
|
||||
tree= get_mm_parts(param, cond_func, field, Item_func::GE_FUNC,
|
||||
cond_func->arguments()[1],cmp_type);
|
||||
if (tree)
|
||||
{
|
||||
tree= tree_and(param, tree, get_mm_parts(param, cond_func, field,
|
||||
Item_func::LE_FUNC,
|
||||
cond_func->arguments()[2],
|
||||
cmp_type));
|
||||
}
|
||||
break;
|
||||
case Item_func::IN_FUNC:
|
||||
{
|
||||
Item_func_in *func=(Item_func_in*) cond_func;
|
||||
tree= get_mm_parts(param, cond_func, field, Item_func::EQ_FUNC,
|
||||
func->arguments()[1], cmp_type);
|
||||
if (tree)
|
||||
{
|
||||
Item **arg, **end;
|
||||
for (arg= func->arguments()+2, end= arg+func->argument_count()-2;
|
||||
arg < end ; arg++)
|
||||
{
|
||||
tree= tree_or(param, tree, get_mm_parts(param, cond_func, field,
|
||||
Item_func::EQ_FUNC,
|
||||
*arg,
|
||||
cmp_type));
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
/*
|
||||
Here the function for the following predicates are processed:
|
||||
<, <=, =, >=, >, LIKE, IS NULL, IS NOT NULL.
|
||||
If the predicate is of the form (value op field) it is handled
|
||||
as the equivalent predicate (field rev_op value), e.g.
|
||||
2 <= a is handled as a >= 2.
|
||||
*/
|
||||
Item_func::Functype func_type=
|
||||
(value != cond_func->arguments()[0]) ? cond_func->functype() :
|
||||
((Item_bool_func2*) cond_func)->rev_functype();
|
||||
tree= get_mm_parts(param, cond_func, field, func_type, value, cmp_type);
|
||||
}
|
||||
}
|
||||
|
||||
DBUG_RETURN(tree);
|
||||
|
||||
}
|
||||
|
||||
/* make a select tree of all keys in condition */
|
||||
|
||||
static SEL_TREE *get_mm_tree(PARAM *param,COND *cond)
|
||||
{
|
||||
SEL_TREE *tree=0;
|
||||
SEL_TREE *ftree= 0;
|
||||
Item_field *field_item= 0;
|
||||
Item *value;
|
||||
DBUG_ENTER("get_mm_tree");
|
||||
|
||||
if (cond->type() == Item::COND_ITEM)
|
||||
@ -3286,9 +3372,12 @@ static SEL_TREE *get_mm_tree(PARAM *param,COND *cond)
|
||||
DBUG_RETURN(new SEL_TREE(SEL_TREE::IMPOSSIBLE));
|
||||
}
|
||||
|
||||
table_map ref_tables=cond->used_tables();
|
||||
table_map ref_tables= 0;
|
||||
table_map param_comp= ~(param->prev_tables | param->read_tables |
|
||||
param->current_table);
|
||||
if (cond->type() != Item::FUNC_ITEM)
|
||||
{ // Should be a field
|
||||
ref_tables= cond->used_tables();
|
||||
if ((ref_tables & param->current_table) ||
|
||||
(ref_tables & ~(param->prev_tables | param->read_tables)))
|
||||
DBUG_RETURN(0);
|
||||
@ -3299,80 +3388,99 @@ static SEL_TREE *get_mm_tree(PARAM *param,COND *cond)
|
||||
if (cond_func->select_optimize() == Item_func::OPTIMIZE_NONE)
|
||||
DBUG_RETURN(0); // Can't be calculated
|
||||
|
||||
param->cond= cond;
|
||||
|
||||
if (cond_func->functype() == Item_func::BETWEEN)
|
||||
switch (cond_func->functype()) {
|
||||
case Item_func::BETWEEN:
|
||||
if (cond_func->arguments()[0]->type() != Item::FIELD_ITEM)
|
||||
DBUG_RETURN(0);
|
||||
field_item= (Item_field*) (cond_func->arguments()[0]);
|
||||
value= NULL;
|
||||
break;
|
||||
case Item_func::IN_FUNC:
|
||||
{
|
||||
Item_func_in *func=(Item_func_in*) cond_func;
|
||||
if (func->key_item()->type() != Item::FIELD_ITEM)
|
||||
DBUG_RETURN(0);
|
||||
field_item= (Item_field*) (func->key_item());
|
||||
value= NULL;
|
||||
break;
|
||||
}
|
||||
case Item_func::MULT_EQUAL_FUNC:
|
||||
{
|
||||
Item_equal *item_equal= (Item_equal *) cond;
|
||||
if (!(value= item_equal->get_const()))
|
||||
DBUG_RETURN(0);
|
||||
Item_equal_iterator it(*item_equal);
|
||||
ref_tables= value->used_tables();
|
||||
while ((field_item= it++))
|
||||
{
|
||||
Field *field= field_item->field;
|
||||
Item_result cmp_type= field->cmp_type();
|
||||
if (!((ref_tables | field->table->map) & param_comp))
|
||||
{
|
||||
tree= get_mm_parts(param, cond, field, Item_func::EQ_FUNC,
|
||||
value,cmp_type);
|
||||
ftree= !ftree ? tree : tree_and(param, ftree, tree);
|
||||
}
|
||||
}
|
||||
|
||||
DBUG_RETURN(ftree);
|
||||
}
|
||||
default:
|
||||
if (cond_func->arguments()[0]->type() == Item::FIELD_ITEM)
|
||||
{
|
||||
Field *field=((Item_field*) (cond_func->arguments()[0]))->field;
|
||||
Item_result cmp_type=field->cmp_type();
|
||||
DBUG_RETURN(tree_and(param,
|
||||
get_mm_parts(param, cond_func, field,
|
||||
Item_func::GE_FUNC,
|
||||
cond_func->arguments()[1], cmp_type),
|
||||
get_mm_parts(param, cond_func, field,
|
||||
Item_func::LE_FUNC,
|
||||
cond_func->arguments()[2], cmp_type)));
|
||||
field_item= (Item_field*) (cond_func->arguments()[0]);
|
||||
value= cond_func->arg_count > 1 ? cond_func->arguments()[1] : 0;
|
||||
}
|
||||
DBUG_RETURN(0);
|
||||
}
|
||||
if (cond_func->functype() == Item_func::IN_FUNC)
|
||||
{ // COND OR
|
||||
Item_func_in *func=(Item_func_in*) cond_func;
|
||||
if (func->key_item()->type() == Item::FIELD_ITEM)
|
||||
else if (cond_func->have_rev_func() &&
|
||||
cond_func->arguments()[1]->type() == Item::FIELD_ITEM)
|
||||
{
|
||||
Field *field=((Item_field*) (func->key_item()))->field;
|
||||
Item_result cmp_type=field->cmp_type();
|
||||
tree= get_mm_parts(param,cond_func,field,Item_func::EQ_FUNC,
|
||||
func->arguments()[1],cmp_type);
|
||||
if (!tree)
|
||||
DBUG_RETURN(tree); // Not key field
|
||||
for (uint i=2 ; i < func->argument_count(); i++)
|
||||
{
|
||||
SEL_TREE *new_tree=get_mm_parts(param,cond_func,field,
|
||||
Item_func::EQ_FUNC,
|
||||
func->arguments()[i],cmp_type);
|
||||
tree=tree_or(param,tree,new_tree);
|
||||
}
|
||||
DBUG_RETURN(tree);
|
||||
field_item= (Item_field*) (cond_func->arguments()[1]);
|
||||
value= cond_func->arguments()[0];
|
||||
}
|
||||
DBUG_RETURN(0); // Can't optimize this IN
|
||||
else
|
||||
DBUG_RETURN(0);
|
||||
}
|
||||
|
||||
if (ref_tables & ~(param->prev_tables | param->read_tables |
|
||||
param->current_table))
|
||||
DBUG_RETURN(0); // Can't be calculated yet
|
||||
if (!(ref_tables & param->current_table))
|
||||
DBUG_RETURN(new SEL_TREE(SEL_TREE::MAYBE)); // This may be FALSE or TRUE
|
||||
/*
|
||||
If the where condition contains a predicate (ti.field op const),
|
||||
then not only SELL_TREE for this predicate is built, but
|
||||
the trees for the results of substitution of ti.field for
|
||||
each tj.field belonging to the same multiple equality as ti.field
|
||||
are built as well.
|
||||
E.g. for WHERE t1.a=t2.a AND t2.a > 10
|
||||
a SEL_TREE for t2.a > 10 will be built for quick select from t2
|
||||
and
|
||||
a SEL_TREE for t1.a > 10 will be built for quick select from t1.
|
||||
*/
|
||||
|
||||
/* check field op const */
|
||||
/* btw, ft_func's arguments()[0] isn't FIELD_ITEM. SerG*/
|
||||
if (cond_func->arguments()[0]->type() == Item::FIELD_ITEM)
|
||||
for (uint i= 0; i < cond_func->arg_count; i++)
|
||||
{
|
||||
tree= get_mm_parts(param, cond_func,
|
||||
((Item_field*) (cond_func->arguments()[0]))->field,
|
||||
cond_func->functype(),
|
||||
cond_func->arg_count > 1 ? cond_func->arguments()[1] :
|
||||
0,
|
||||
((Item_field*) (cond_func->arguments()[0]))->field->
|
||||
cmp_type());
|
||||
Item *arg= cond_func->arguments()[i];
|
||||
if (arg != field_item)
|
||||
ref_tables|= arg->used_tables();
|
||||
}
|
||||
/* check const op field */
|
||||
if (!tree &&
|
||||
cond_func->have_rev_func() &&
|
||||
cond_func->arguments()[1]->type() == Item::FIELD_ITEM)
|
||||
Field *field= field_item->field;
|
||||
Item_result cmp_type= field->cmp_type();
|
||||
if (!((ref_tables | field->table->map) & param_comp))
|
||||
ftree= get_func_mm_tree(param, cond_func, field, value, cmp_type);
|
||||
Item_equal *item_equal= field_item->item_equal;
|
||||
if (item_equal)
|
||||
{
|
||||
DBUG_RETURN(get_mm_parts(param, cond_func,
|
||||
((Item_field*)
|
||||
(cond_func->arguments()[1]))->field,
|
||||
((Item_bool_func2*) cond_func)->rev_functype(),
|
||||
cond_func->arguments()[0],
|
||||
((Item_field*)
|
||||
(cond_func->arguments()[1]))->field->cmp_type()
|
||||
));
|
||||
Item_equal_iterator it(*item_equal);
|
||||
Item_field *item;
|
||||
while ((item= it++))
|
||||
{
|
||||
Field *f= item->field;
|
||||
if (field->eq(f))
|
||||
continue;
|
||||
if (!((ref_tables | f->table->map) & param_comp))
|
||||
{
|
||||
tree= get_func_mm_tree(param, cond_func, f, value, cmp_type);
|
||||
ftree= !ftree ? tree : tree_and(param, ftree, tree);
|
||||
}
|
||||
}
|
||||
}
|
||||
DBUG_RETURN(tree);
|
||||
DBUG_RETURN(ftree);
|
||||
}
|
||||
|
||||
|
||||
@ -3381,17 +3489,10 @@ get_mm_parts(PARAM *param, COND *cond_func, Field *field,
|
||||
Item_func::Functype type,
|
||||
Item *value, Item_result cmp_type)
|
||||
{
|
||||
bool ne_func= FALSE;
|
||||
DBUG_ENTER("get_mm_parts");
|
||||
if (field->table != param->table)
|
||||
DBUG_RETURN(0);
|
||||
|
||||
if (type == Item_func::NE_FUNC)
|
||||
{
|
||||
ne_func= TRUE;
|
||||
type= Item_func::LT_FUNC;
|
||||
}
|
||||
|
||||
KEY_PART *key_part = param->key_parts;
|
||||
KEY_PART *end = param->key_parts_end;
|
||||
SEL_TREE *tree=0;
|
||||
@ -3429,15 +3530,6 @@ get_mm_parts(PARAM *param, COND *cond_func, Field *field,
|
||||
}
|
||||
}
|
||||
|
||||
if (ne_func)
|
||||
{
|
||||
SEL_TREE *tree2= get_mm_parts(param, cond_func,
|
||||
field, Item_func::GT_FUNC,
|
||||
value, cmp_type);
|
||||
if (tree2)
|
||||
tree= tree_or(param,tree,tree2);
|
||||
}
|
||||
|
||||
DBUG_RETURN(tree);
|
||||
}
|
||||
|
||||
|
@ -341,6 +341,18 @@ bool simple_pred(Item_func *func_item, Item **args, bool *inv_order)
|
||||
Item *item;
|
||||
*inv_order= 0;
|
||||
switch (func_item->argument_count()) {
|
||||
case 0:
|
||||
/* MULT_EQUAL_FUNC */
|
||||
{
|
||||
Item_equal *item_equal= (Item_equal *) func_item;
|
||||
Item_equal_iterator it(*item_equal);
|
||||
args[0]= it++;
|
||||
if (it++)
|
||||
return 0;
|
||||
if (!(args[1]= item_equal->get_const()))
|
||||
return 0;
|
||||
}
|
||||
break;
|
||||
case 1:
|
||||
/* field IS NULL */
|
||||
item= func_item->arguments()[0];
|
||||
@ -481,6 +493,9 @@ static bool matching_cond(bool max_fl, TABLE_REF *ref, KEY *keyinfo,
|
||||
case Item_func::BETWEEN:
|
||||
between= 1;
|
||||
break;
|
||||
case Item_func::MULT_EQUAL_FUNC:
|
||||
eq_type= 1;
|
||||
break;
|
||||
default:
|
||||
return 0; // Can't optimize function
|
||||
}
|
||||
|
@ -127,10 +127,12 @@ public:
|
||||
void remove(list_node **prev)
|
||||
{
|
||||
list_node *node=(*prev)->next;
|
||||
delete *prev;
|
||||
*prev=node;
|
||||
if (!--elements)
|
||||
last= &first;
|
||||
else if (last == &(*prev)->next)
|
||||
last= prev;
|
||||
delete *prev;
|
||||
*prev=node;
|
||||
}
|
||||
inline void *pop(void)
|
||||
{
|
||||
@ -143,9 +145,36 @@ public:
|
||||
}
|
||||
inline void concat(base_list *list)
|
||||
{
|
||||
*last= list->first;
|
||||
last= list->last;
|
||||
elements+= list->elements;
|
||||
if (!list->is_empty())
|
||||
{
|
||||
*last= list->first;
|
||||
last= list->last;
|
||||
elements+= list->elements;
|
||||
}
|
||||
}
|
||||
inline void disjoin(base_list *list)
|
||||
{
|
||||
list_node **prev= &first;
|
||||
list_node *node= first;
|
||||
list_node *list_first= list->first;
|
||||
elements=0;
|
||||
while (node && node != list_first)
|
||||
{
|
||||
prev= &node->next;
|
||||
node= node->next;
|
||||
elements++;
|
||||
}
|
||||
*prev= *last;
|
||||
last= prev;
|
||||
}
|
||||
inline void prepand(base_list *list)
|
||||
{
|
||||
if (!list->is_empty())
|
||||
{
|
||||
*list->last= first;
|
||||
first= list->first;
|
||||
elements+= list->elements;
|
||||
}
|
||||
}
|
||||
inline list_node* last_node() { return *last; }
|
||||
inline list_node* first_node() { return first;}
|
||||
@ -257,6 +286,9 @@ public:
|
||||
inline T* head() {return (T*) base_list::head(); }
|
||||
inline T** head_ref() {return (T**) base_list::head_ref(); }
|
||||
inline T* pop() {return (T*) base_list::pop(); }
|
||||
inline void concat(List<T> *list) { base_list::concat(list); }
|
||||
inline void disjoin(List<T> *list) { base_list::disjoin(list); }
|
||||
inline void prepand(List<T> *list) { base_list::prepand(list); }
|
||||
void delete_elements(void)
|
||||
{
|
||||
list_node *element,*next;
|
||||
@ -267,7 +299,6 @@ public:
|
||||
}
|
||||
empty();
|
||||
}
|
||||
inline void concat(List<T> *list) { base_list::concat(list); }
|
||||
};
|
||||
|
||||
|
||||
@ -278,6 +309,8 @@ public:
|
||||
inline T* operator++(int) { return (T*) base_list_iterator::next(); }
|
||||
inline T *replace(T *a) { return (T*) base_list_iterator::replace(a); }
|
||||
inline T *replace(List<T> &a) { return (T*) base_list_iterator::replace(a); }
|
||||
inline void rewind(void) { base_list_iterator::rewind(); }
|
||||
inline void remove() { base_list_iterator::remove(); }
|
||||
inline void after(T *a) { base_list_iterator::after(a); }
|
||||
inline T** ref(void) { return (T**) base_list_iterator::ref(); }
|
||||
};
|
||||
|
1101
sql/sql_select.cc
1101
sql/sql_select.cc
File diff suppressed because it is too large
Load Diff
@ -91,7 +91,8 @@ typedef struct st_join_table {
|
||||
SQL_SELECT *select;
|
||||
COND *select_cond;
|
||||
QUICK_SELECT_I *quick;
|
||||
Item *on_expr; /* associated on expression */
|
||||
Item **on_expr_ref; /* pointer to the associated on expression */
|
||||
COND_EQUAL *cond_equal; /* multiple equalities for the on expression */
|
||||
st_join_table *first_inner; /* first inner table for including outerjoin */
|
||||
bool found; /* true after all matches or null complement */
|
||||
bool not_null_compl;/* true before null complement is added */
|
||||
@ -222,6 +223,7 @@ class JOIN :public Sql_alloc
|
||||
Item *conds_history; // store WHERE for explain
|
||||
TABLE_LIST *tables_list; //hold 'tables' parameter of mysql_select
|
||||
List<TABLE_LIST> *join_list; // list of joined tables in reverse order
|
||||
COND_EQUAL *cond_equal;
|
||||
SQL_SELECT *select; //created in optimisation phase
|
||||
JOIN_TAB *return_tab; //used only for outer joins
|
||||
Item **ref_pointer_array; //used pointer reference for this select
|
||||
@ -284,6 +286,7 @@ class JOIN :public Sql_alloc
|
||||
ref_pointer_array_size= 0;
|
||||
zero_result_cause= 0;
|
||||
optimized= 0;
|
||||
cond_equal= 0;
|
||||
|
||||
fields_list= fields_arg;
|
||||
bzero((char*) &keyuse,sizeof(keyuse));
|
||||
|
@ -21,6 +21,7 @@ class Item; /* Needed by ORDER */
|
||||
class GRANT_TABLE;
|
||||
class st_select_lex_unit;
|
||||
class st_select_lex;
|
||||
class COND_EQUAL;
|
||||
|
||||
/* Order clause list element */
|
||||
|
||||
@ -209,6 +210,7 @@ typedef struct st_table_list
|
||||
char *db, *alias, *real_name;
|
||||
char *option; /* Used by cache index */
|
||||
Item *on_expr; /* Used with outer join */
|
||||
COND_EQUAL *cond_equal; /* Used with outer join */
|
||||
struct st_table_list *natural_join; /* natural join on this table*/
|
||||
/* ... join ... USE INDEX ... IGNORE INDEX */
|
||||
List<String> *use_index, *ignore_index;
|
||||
|
Reference in New Issue
Block a user