Commit b02b6c70 authored by unknown's avatar unknown

Auto Merge


BitKeeper/etc/ignore:
  auto-union
mysql-test/r/bdb.result:
  Auto merged
mysql-test/r/func_group.result:
  Auto merged
mysql-test/r/func_test.result:
  Auto merged
mysql-test/r/heap_btree.result:
  Auto merged
mysql-test/r/index_merge.result:
  Auto merged
mysql-test/r/innodb.result:
  Auto merged
mysql-test/r/join_outer.result:
  Auto merged
mysql-test/r/range.result:
  Auto merged
mysql-test/r/select.result:
  Auto merged
mysql-test/r/subselect.result:
  Auto merged
mysql-test/t/range.test:
  Auto merged
sql/item.cc:
  Auto merged
sql/item.h:
  Auto merged
sql/item_cmpfunc.cc:
  Auto merged
sql/item_func.cc:
  Auto merged
sql/item_func.h:
  Auto merged
sql/item_strfunc.h:
  Auto merged
sql/sql_list.h:
  Auto merged
sql/sql_select.cc:
  Auto merged
sql/sql_select.h:
  Auto merged
sql/opt_range.cc:
  Merge
parents d4898d17 9c264e4a
...@@ -483,6 +483,7 @@ mysql-test/gmon.out ...@@ -483,6 +483,7 @@ mysql-test/gmon.out
mysql-test/install_test_db mysql-test/install_test_db
mysql-test/mysql-test-run mysql-test/mysql-test-run
mysql-test/r/*.reject mysql-test/r/*.reject
mysql-test/r/index_merge_load.result
mysql-test/r/rpl000001.eval mysql-test/r/rpl000001.eval
mysql-test/r/rpl000002.eval mysql-test/r/rpl000002.eval
mysql-test/r/rpl000014.eval mysql-test/r/rpl000014.eval
...@@ -493,9 +494,11 @@ mysql-test/r/slave-running.eval ...@@ -493,9 +494,11 @@ mysql-test/r/slave-running.eval
mysql-test/r/slave-stopped.eval mysql-test/r/slave-stopped.eval
mysql-test/share/mysql mysql-test/share/mysql
mysql-test/std_data/*.pem mysql-test/std_data/*.pem
mysql-test/t/index_merge.load
mysql-test/var/* mysql-test/var/*
mysql.kdevprj mysql.kdevprj
mysql.proj mysql.proj
mysql_priv.h
mysqld.S mysqld.S
mysqld.sym mysqld.sym
mysys/#mf_iocache.c# mysys/#mf_iocache.c#
...@@ -647,4 +650,3 @@ vio/test-ssl ...@@ -647,4 +650,3 @@ vio/test-ssl
vio/test-sslclient vio/test-sslclient
vio/test-sslserver vio/test-sslserver
vio/viotest-ssl vio/viotest-ssl
mysql_priv.h
...@@ -140,13 +140,13 @@ id parent_id level ...@@ -140,13 +140,13 @@ id parent_id level
1015 102 2 1015 102 2
explain select level from t1 where level=1; explain select level from t1 where level=1;
id select_type table type possible_keys key key_len ref rows Extra id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 ref level level 1 const 1 Using where; Using index 1 SIMPLE t1 ref level level 1 const 1 Using index
explain select level,id from t1 where level=1; explain select level,id from t1 where level=1;
id select_type table type possible_keys key key_len ref rows Extra id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 ref level level 1 const 1 Using where; Using index 1 SIMPLE t1 ref level level 1 const 1 Using index
explain select level,id,parent_id from t1 where level=1; explain select level,id,parent_id from t1 where level=1;
id select_type table type possible_keys key key_len ref rows Extra id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 ref level level 1 const 1 Using where 1 SIMPLE t1 ref level level 1 const 1
select level,id from t1 where level=1; select level,id from t1 where level=1;
level id level id
1 1002 1 1002
...@@ -625,7 +625,7 @@ id parent_id level ...@@ -625,7 +625,7 @@ id parent_id level
1016 102 2 1016 102 2
explain select level from t1 where level=1; explain select level from t1 where level=1;
id select_type table type possible_keys key key_len ref rows Extra id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 ref level level 1 const 1 Using where; Using index 1 SIMPLE t1 ref level level 1 const 1 Using index
select level,id from t1 where level=1; select level,id from t1 where level=1;
level id level id
1 1004 1 1004
......
...@@ -412,7 +412,7 @@ CHI Los Angeles ...@@ -412,7 +412,7 @@ CHI Los Angeles
explain explain
select max(a3) from t1 where a2 is null and a2 = 2; 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 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; select max(a3) from t1 where a2 is null and a2 = 2;
max(a3) max(a3)
NULL NULL
......
...@@ -74,9 +74,9 @@ select * from t1 where 1 xor 1; ...@@ -74,9 +74,9 @@ select * from t1 where 1 xor 1;
a a
explain extended select * from t1 where 1 xor 1; explain extended select * from t1 where 1 xor 1;
id select_type table type possible_keys key key_len ref rows Extra id select_type table type possible_keys key key_len ref rows Extra
1 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: Warnings:
Note 1003 select high_priority test.t1.a AS `a` from test.t1 where (1 xor 1) Note 1003 select high_priority test.t1.a AS `a` from test.t1
select - a from t1; select - a from t1;
- a - a
-1 -1
......
...@@ -73,7 +73,7 @@ engine=heap; ...@@ -73,7 +73,7 @@ engine=heap;
insert into t1 values (1,1),(2,2),(1,3),(2,4),(2,5),(2,6); insert into t1 values (1,1),(2,2),(1,3),(2,4),(2,5),(2,6);
explain select * from t1 where x=1; explain select * from t1 where x=1;
id select_type table type possible_keys key key_len ref rows Extra id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 ref x x 4 const 1 Using where 1 SIMPLE t1 ref x x 4 const 1
select * from t1 where x=1; select * from t1 where x=1;
x y x y
1 1 1 1
...@@ -134,7 +134,7 @@ a b ...@@ -134,7 +134,7 @@ a b
1 1 1 1
explain select * from tx where b=x; explain select * from tx where b=x;
id select_type table type possible_keys key key_len ref rows Extra id select_type table type possible_keys key key_len ref rows Extra
x SIMPLE tx ref b b x const x Using where x SIMPLE tx ref b b x const x
drop table t1; drop table t1;
create table t1 (id int unsigned not null, primary key using BTREE (id)) engine=HEAP; create table t1 (id int unsigned not null, primary key using BTREE (id)) engine=HEAP;
insert into t1 values(1); insert into t1 values(1);
......
...@@ -76,13 +76,13 @@ id select_type table type possible_keys key key_len ref rows Extra ...@@ -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 1 SIMPLE t0 ALL i1,i2 NULL NULL NULL 1024 Using where
explain select * from t0 where key2 = 45 or key1 is null; explain select * from t0 where key2 = 45 or key1 is null;
id select_type table type possible_keys key key_len ref rows Extra id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE 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; 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 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 where 1 SIMPLE t0 index_merge i2,i3,i4 i2,i3 4,4 NULL 2 Using where
explain select * from t0 where key2=10 or key3=3 or key4 is null; 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 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 where 1 SIMPLE t0 index_merge i2,i3 i2,i3 4,4 NULL 2 Using where
explain select key1 from t0 where (key1 <=> null) or (key2 < 5) or explain select key1 from t0 where (key1 <=> null) or (key2 < 5) or
(key3=10) or (key4 <=> null); (key3=10) or (key4 <=> null);
id select_type table type possible_keys key key_len ref rows Extra id select_type table type possible_keys key key_len ref rows Extra
...@@ -257,18 +257,18 @@ explain ...@@ -257,18 +257,18 @@ explain
select * from t0,t1 where (t0.key1=t1.key1) and select * from t0,t1 where (t0.key1=t1.key1) and
(t0.key1=3 or t0.key2=4) and t1.key1<200; (t0.key1=3 or t0.key2=4) and t1.key1<200;
id select_type table type possible_keys key key_len ref rows Extra id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t0 index_merge i1,i2 i1,i2 4,4 NULL 2 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 Using where 1 SIMPLE t1 ref i1 i1 4 test.t0.key1 1
explain explain
select * from t0,t1 where (t0.key1=t1.key1) and select * from t0,t1 where (t0.key1=t1.key1) and
(t0.key1=3 or t0.key2<4) and t1.key1=2; (t0.key1=3 or t0.key2<4) and t1.key1=2;
id select_type table type possible_keys key key_len ref rows Extra id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t0 ref i1,i2 i1 4 const 1 Using where 1 SIMPLE t0 ref i1,i2 i1 4 const 1 Using where
1 SIMPLE t1 ref i1 i1 4 const 1 Using where 1 SIMPLE t1 ref i1 i1 4 const 1
explain select * from t0,t1 where t0.key1 = 5 and explain select * from t0,t1 where t0.key1 = 5 and
(t1.key1 = t0.key1 or t1.key8 = t0.key1); (t1.key1 = t0.key1 or t1.key8 = t0.key1);
id select_type table type possible_keys key key_len ref rows Extra id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t0 ref i1 i1 4 const 1 Using where 1 SIMPLE t0 ref i1 i1 4 const 1
1 SIMPLE t1 index_merge i1,i8 i1,i8 4,4 NULL 2 Using where 1 SIMPLE t1 index_merge i1,i8 i1,i8 4,4 NULL 2 Using where
explain select * from t0,t1 where t0.key1 < 3 and explain select * from t0,t1 where t0.key1 < 3 and
(t1.key1 = t0.key1 or t1.key8 = t0.key1); (t1.key1 = t0.key1 or t1.key8 = t0.key1);
......
...@@ -141,13 +141,13 @@ id parent_id level ...@@ -141,13 +141,13 @@ id parent_id level
1015 102 2 1015 102 2
explain select level from t1 where level=1; explain select level from t1 where level=1;
id select_type table type possible_keys key key_len ref rows Extra id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 ref level level 1 const # Using where; Using index 1 SIMPLE t1 ref level level 1 const # Using index
explain select level,id from t1 where level=1; explain select level,id from t1 where level=1;
id select_type table type possible_keys key key_len ref rows Extra id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 ref level level 1 const # Using where; Using index 1 SIMPLE t1 ref level level 1 const # Using index
explain select level,id,parent_id from t1 where level=1; explain select level,id,parent_id from t1 where level=1;
id select_type table type possible_keys key key_len ref rows Extra id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 ref level level 1 const # Using where 1 SIMPLE t1 ref level level 1 const #
select level,id from t1 where level=1; select level,id from t1 where level=1;
level id level id
1 1002 1 1002
...@@ -609,7 +609,7 @@ id parent_id level ...@@ -609,7 +609,7 @@ id parent_id level
1016 102 2 1016 102 2
explain select level from t1 where level=1; explain select level from t1 where level=1;
id select_type table type possible_keys key key_len ref rows Extra id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 ref level level 1 const # Using where; Using index 1 SIMPLE t1 ref level level 1 const # Using index
select level,id from t1 where level=1; select level,id from t1 where level=1;
level id level id
1 1004 1 1004
......
...@@ -634,7 +634,7 @@ insert into t2 values (10,1),(20,2),(30,3); ...@@ -634,7 +634,7 @@ insert into t2 values (10,1),(20,2),(30,3);
explain select * from t2 left join t1 on t1.fooID = t2.fooID and t1.fooID = 30; explain select * from t2 left join t1 on t1.fooID = t2.fooID and t1.fooID = 30;
id select_type table type possible_keys key key_len ref rows Extra id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t2 index NULL PRIMARY 4 NULL 3 Using index 1 SIMPLE t2 index NULL PRIMARY 4 NULL 3 Using index
1 SIMPLE t1 eq_ref PRIMARY PRIMARY 2 const 1 Using where; Using index 1 SIMPLE t1 eq_ref PRIMARY PRIMARY 2 const 1 Using index
select * from t2 left join t1 on t1.fooID = t2.fooID and t1.fooID = 30; select * from t2 left join t1 on t1.fooID = t2.fooID and t1.fooID = 30;
fooID barID fooID fooID barID fooID
10 1 NULL 10 1 NULL
......
...@@ -12,5 +12,5 @@ select * from t1 where a is null; ...@@ -12,5 +12,5 @@ select * from t1 where a is null;
a b a b
explain select * from t1 where b is null; explain select * from t1 where b is null;
id select_type table type possible_keys key key_len ref rows Extra id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables 1 SIMPLE NULL NULL NULL NULL NULL NULL NULL Impossible WHERE
drop table t1; drop table t1;
...@@ -220,24 +220,22 @@ insert into t1 (x) values (1),(2),(3),(4),(5),(6),(7),(8),(9); ...@@ -220,24 +220,22 @@ insert into t1 (x) values (1),(2),(3),(4),(5),(6),(7),(8),(9);
update t1 set y=x; update t1 set y=x;
explain select * from t1, t1 t2 where t1.y = 2 and t2.x between 7 and t1.y+0; 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 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 NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables
1 SIMPLE t2 range x x 5 NULL 4 Using where
explain select * from t1, t1 t2 where t1.y = 2 and t2.x >= 7 and t2.x <= t1.y+0; 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 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 NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables
1 SIMPLE t2 range x x 5 NULL 4 Using where
explain select * from t1, t1 t2 where t1.y = 2 and t2.x between t1.y-1 and t1.y+1; 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 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 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; 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 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 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; 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 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 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; 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 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 t1 ref y y 5 const 1 Using where
...@@ -255,12 +253,12 @@ CREATE TABLE t2 (keya int(11) NOT NULL default '0', KEY j1 (keya)); ...@@ -255,12 +253,12 @@ CREATE TABLE t2 (keya int(11) NOT NULL default '0', KEY j1 (keya));
INSERT INTO t2 VALUES (0),(0),(1),(1),(2),(2); 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; 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 id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t2 ref j1 j1 4 const 1 Using where; Using index 1 SIMPLE t2 ref j1 j1 4 const 1 Using index
1 SIMPLE t1 ALL i1,i2 NULL NULL NULL 4 Range checked for each record (index map: 0x3) 1 SIMPLE t1 range i1,i2 i1 4 NULL 4 Using where; Using index
explain select * from t1 force index(i2), t2 where (t1.key1 <t2.keya + 1) and t2.keya=3; explain select * from t1 force index(i2), t2 where (t1.key1 <t2.keya + 1) and t2.keya=3;
id select_type table type possible_keys key key_len ref rows Extra id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t2 ref j1 j1 4 const 1 Using where; Using index 1 SIMPLE t2 ref j1 j1 4 const 1 Using index
1 SIMPLE t1 ALL i2 NULL NULL NULL 4 Range checked for each record (index map: 0x2) 1 SIMPLE t1 range i2 i2 4 NULL 4 Using where; Using index
DROP TABLE t1,t2; DROP TABLE t1,t2;
CREATE TABLE t1 ( CREATE TABLE t1 (
a int(11) default NULL, a int(11) default NULL,
...@@ -379,14 +377,26 @@ count(*) ...@@ -379,14 +377,26 @@ count(*)
select count(*) from t2; select count(*) from t2;
count(*) count(*)
1026 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; 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 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 t1 range uid_index uid_index 4 NULL 128 Using where
1 SIMPLE t2 ref uid_index uid_index 4 test.t1.uid 38 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; 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 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 t1 range uid_index uid_index 4 NULL 129 Using where
1 SIMPLE t2 ref uid_index uid_index 4 test.t1.uid 38 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; select * from t1, t2 where t1.uid=t2.uid AND t1.uid > 0;
id name uid id name uid id name uid id name uid
1001 A 1 1001 A 1 1001 A 1 1001 A 1
......
...@@ -1374,7 +1374,7 @@ id select_type table type possible_keys key key_len ref rows Extra ...@@ -1374,7 +1374,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; 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 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 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; 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 id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t4 ALL NULL NULL NULL NULL 12 1 SIMPLE t4 ALL NULL NULL NULL NULL 12
...@@ -1470,7 +1470,7 @@ explain extended select count(*),min(fld4),max(fld4),sum(fld1),avg(fld1),std(fld ...@@ -1470,7 +1470,7 @@ explain extended select count(*),min(fld4),max(fld4),sum(fld1),avg(fld1),std(fld
id select_type table type possible_keys key key_len ref rows Extra id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t2 ALL NULL NULL NULL NULL 1199 Using where 1 SIMPLE t2 ALL NULL NULL NULL NULL 1199 Using where
Warnings: Warnings:
Note 1003 select high_priority count(0) AS `count(*)`,min(test.t2.fld4) AS `min(fld4)`,max(test.t2.fld4) AS `max(fld4)`,sum(test.t2.fld1) AS `sum(fld1)`,avg(test.t2.fld1) AS `avg(fld1)`,std(test.t2.fld1) AS `std(fld1)`,variance(test.t2.fld1) AS `variance(fld1)` from test.t2 where ((test.t2.companynr = 34) and (test.t2.fld4 <> _latin1'')) Note 1003 select high_priority count(0) AS `count(*)`,min(test.t2.fld4) AS `min(fld4)`,max(test.t2.fld4) AS `max(fld4)`,sum(test.t2.fld1) AS `sum(fld1)`,avg(test.t2.fld1) AS `avg(fld1)`,std(test.t2.fld1) AS `std(fld1)`,variance(test.t2.fld1) AS `variance(fld1)` from test.t2 where ((test.t2.fld4 <> _latin1'') and (test.t2.companynr = 34))
select companynr,count(*),min(fld4),max(fld4),sum(fld1),avg(fld1),std(fld1),variance(fld1) from t2 group by companynr limit 3; select companynr,count(*),min(fld4),max(fld4),sum(fld1),avg(fld1),std(fld1),variance(fld1) from t2 group by companynr limit 3;
companynr count(*) min(fld4) max(fld4) sum(fld1) avg(fld1) std(fld1) variance(fld1) companynr count(*) min(fld4) max(fld4) sum(fld1) avg(fld1) std(fld1) variance(fld1)
00 82 Anthony windmills 10355753 126289.6707 115550.9757 13352027981.7087 00 82 Anthony windmills 10355753 126289.6707 115550.9757 13352027981.7087
......
...@@ -309,7 +309,7 @@ id select_type table type possible_keys key key_len ref rows Extra ...@@ -309,7 +309,7 @@ id select_type table type possible_keys key key_len ref rows Extra
Warnings: Warnings:
Note 1275 Field or reference 't2.a' of SELECT #2 was resolved in SELECT #1 Note 1275 Field or reference 't2.a' of SELECT #2 was resolved in SELECT #1
Note 1275 Field or reference 't2.a' of SELECT #3 was resolved in SELECT #1 Note 1275 Field or reference 't2.a' of SELECT #3 was resolved in SELECT #1
Note 1003 select high_priority (select test.t1.a AS `a` from test.t1 where (test.t1.a = test.t2.a) union select test.t5.a AS `a` from test.t5 where (test.t5.a = test.t2.a)) AS `(select a from t1 where t1.a=t2.a union select a from t5 where t5.a=t2.a)`,test.t2.a AS `a` from test.t2 Note 1003 select high_priority (select test.t1.a AS `a` from test.t1 where (test.t2.a = test.t1.a) union select test.t5.a AS `a` from test.t5 where (test.t2.a = test.t5.a)) AS `(select a from t1 where t1.a=t2.a union select a from t5 where t5.a=t2.a)`,test.t2.a AS `a` from test.t2
select (select a from t1 where t1.a=t2.a union all select a from t5 where t5.a=t2.a), a from t2; select (select a from t1 where t1.a=t2.a union all select a from t5 where t5.a=t2.a), a from t2;
ERROR 21000: Subquery returns more than 1 row ERROR 21000: Subquery returns more than 1 row
create table t6 (patient_uq int, clinic_uq int, index i1 (clinic_uq)); create table t6 (patient_uq int, clinic_uq int, index i1 (clinic_uq));
...@@ -327,7 +327,7 @@ id select_type table type possible_keys key key_len ref rows Extra ...@@ -327,7 +327,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 2 DEPENDENT SUBQUERY t7 eq_ref PRIMARY PRIMARY 4 test.t6.clinic_uq 1
Warnings: Warnings:
Note 1275 Field or reference 'clinic_uq' of SELECT #2 was resolved in SELECT #1 Note 1275 Field or reference 'clinic_uq' of SELECT #2 was resolved in SELECT #1
Note 1003 select high_priority test.t6.patient_uq AS `patient_uq`,test.t6.clinic_uq AS `clinic_uq` from test.t6 where exists(select test.t7.uq AS `uq`,test.t7.name AS `name` from test.t7 where (test.t7.uq = test.t6.clinic_uq) limit 1) Note 1003 select high_priority test.t6.patient_uq AS `patient_uq`,test.t6.clinic_uq AS `clinic_uq` from test.t6 where exists(select test.t7.uq AS `uq`,test.t7.name AS `name` from test.t7 where (test.t6.clinic_uq = test.t7.uq) limit 1)
select * from t1 where a= (select a from t2,t4 where t2.b=t4.b); select * from t1 where a= (select a from t2,t4 where t2.b=t4.b);
ERROR 23000: Column: 'a' in field list is ambiguous ERROR 23000: Column: 'a' in field list is ambiguous
drop table if exists t1,t2,t3; drop table if exists t1,t2,t3;
...@@ -540,7 +540,7 @@ id select_type table type possible_keys key key_len ref rows Extra ...@@ -540,7 +540,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 1 PRIMARY t1 const PRIMARY,numreponse PRIMARY 7 const,const 1
2 SUBQUERY NULL NULL NULL NULL NULL NULL NULL Select tables optimized away 2 SUBQUERY NULL NULL NULL NULL NULL NULL NULL Select tables optimized away
Warnings: Warnings:
Note 1003 select high_priority test.t1.numreponse AS `numreponse` from test.t1 where ((test.t1.numeropost = _latin1'1') and (test.t1.numreponse = 3)) Note 1003 select high_priority test.t1.numreponse AS `numreponse` from test.t1 where ((test.t1.numeropost = _latin1'1') and (test.t1.numreponse = (select max(test.t1.numreponse) AS `MAX(numreponse)` from test.t1 where (test.t1.numeropost = _latin1'1'))))
drop table t1; drop table t1;
CREATE TABLE t1 (a int(1)); CREATE TABLE t1 (a int(1));
INSERT INTO t1 VALUES (1); INSERT INTO t1 VALUES (1);
...@@ -899,7 +899,7 @@ id select_type table type possible_keys key key_len ref rows Extra ...@@ -899,7 +899,7 @@ id select_type table type possible_keys key key_len ref rows Extra
2 DEPENDENT SUBQUERY t2 ref_or_null a a 5 func 2 Using where; Using index 2 DEPENDENT SUBQUERY t2 ref_or_null a a 5 func 2 Using where; Using index
2 DEPENDENT SUBQUERY t3 ALL NULL NULL NULL NULL 3 Using where 2 DEPENDENT SUBQUERY t3 ALL NULL NULL NULL NULL 3 Using where
Warnings: Warnings:
Note 1003 select high_priority test.t1.a AS `a`,<in_optimizer>(test.t1.a,<exists>(select 1 AS `Not_used` from test.t2 join test.t3 where ((test.t3.a = test.t2.a) and ((<cache>(test.t1.a) = test.t2.a) or isnull(test.t2.a))) having <is_not_null_test>(test.t2.a) limit 1)) AS `t1.a in (select t2.a from t2,t3 where t3.a=t2.a)` from test.t1 Note 1003 select high_priority test.t1.a AS `a`,<in_optimizer>(test.t1.a,<exists>(select 1 AS `Not_used` from test.t2 join test.t3 where (((<cache>(test.t1.a) = test.t2.a) or isnull(test.t2.a)) and (test.t3.a = test.t2.a)) having <is_not_null_test>(test.t2.a) limit 1)) AS `t1.a in (select t2.a from t2,t3 where t3.a=t2.a)` from test.t1
drop table t1,t2,t3; drop table t1,t2,t3;
create table t1 (a float); create table t1 (a float);
select 10.5 IN (SELECT * from t1 LIMIT 1); select 10.5 IN (SELECT * from t1 LIMIT 1);
...@@ -1168,9 +1168,9 @@ SELECT 0 IN (SELECT 1 FROM t1 a); ...@@ -1168,9 +1168,9 @@ SELECT 0 IN (SELECT 1 FROM t1 a);
EXPLAIN EXTENDED SELECT 0 IN (SELECT 1 FROM t1 a); EXPLAIN EXTENDED SELECT 0 IN (SELECT 1 FROM t1 a);
id select_type table type possible_keys key key_len ref rows Extra id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY NULL NULL NULL NULL NULL NULL NULL No tables used 1 PRIMARY NULL NULL NULL NULL NULL NULL NULL No tables used
2 DEPENDENT SUBQUERY NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables 2 DEPENDENT SUBQUERY NULL NULL NULL NULL NULL NULL NULL Impossible WHERE
Warnings: Warnings:
Note 1003 select high_priority <in_optimizer>(0,<exists>(select 1 AS `Not_used` from test.t1 a where isnull(1) having <is_not_null_test>(1) limit 1)) AS `0 IN (SELECT 1 FROM t1 a)` Note 1003 select high_priority <in_optimizer>(0,<exists>(select 1 AS `Not_used` from test.t1 a having <is_not_null_test>(1) limit 1)) AS `0 IN (SELECT 1 FROM t1 a)`
INSERT INTO t1 (pseudo) VALUES ('test1'); INSERT INTO t1 (pseudo) VALUES ('test1');
SELECT 0 IN (SELECT 1 FROM t1 a); SELECT 0 IN (SELECT 1 FROM t1 a);
0 IN (SELECT 1 FROM t1 a) 0 IN (SELECT 1 FROM t1 a)
...@@ -1178,9 +1178,9 @@ SELECT 0 IN (SELECT 1 FROM t1 a); ...@@ -1178,9 +1178,9 @@ SELECT 0 IN (SELECT 1 FROM t1 a);
EXPLAIN EXTENDED SELECT 0 IN (SELECT 1 FROM t1 a); EXPLAIN EXTENDED SELECT 0 IN (SELECT 1 FROM t1 a);
id select_type table type possible_keys key key_len ref rows Extra id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY NULL NULL NULL NULL NULL NULL NULL No tables used 1 PRIMARY NULL NULL NULL NULL NULL NULL NULL No tables used
2 DEPENDENT SUBQUERY NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables 2 DEPENDENT SUBQUERY NULL NULL NULL NULL NULL NULL NULL Impossible WHERE
Warnings: Warnings:
Note 1003 select high_priority <in_optimizer>(0,<exists>(select 1 AS `Not_used` from test.t1 a where isnull(1) having <is_not_null_test>(1) limit 1)) AS `0 IN (SELECT 1 FROM t1 a)` Note 1003 select high_priority <in_optimizer>(0,<exists>(select 1 AS `Not_used` from test.t1 a having <is_not_null_test>(1) limit 1)) AS `0 IN (SELECT 1 FROM t1 a)`
drop table t1; drop table t1;
CREATE TABLE `t1` ( CREATE TABLE `t1` (
`i` int(11) NOT NULL default '0', `i` int(11) NOT NULL default '0',
...@@ -1312,7 +1312,7 @@ id select_type table type possible_keys key key_len ref rows Extra ...@@ -1312,7 +1312,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 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 2 DEPENDENT SUBQUERY t3 eq_ref PRIMARY PRIMARY 4 test.t1.b 1 Using where; Using index
Warnings: Warnings:
Note 1003 select high_priority 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)) limit 1)) Note 1003 select high_priority 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 ((<cache>(test.t2.a) = test.t1.a) and (test.t3.a = test.t1.b)) limit 1))
drop table t1, t2, t3; drop table t1, t2, t3;
create table t1 (a int, b int, index a (a,b)); create table t1 (a int, b int, index a (a,b));
create table t2 (a int, index a (a)); create table t2 (a int, index a (a));
...@@ -1348,10 +1348,10 @@ a ...@@ -1348,10 +1348,10 @@ a
explain extended select * from t2 where t2.a in (select t1.a from t1,t3 where t1.b=t3.a); explain extended select * from t2 where t2.a in (select t1.a from t1,t3 where t1.b=t3.a);
id select_type table type possible_keys key key_len ref rows Extra id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY t2 index NULL a 5 NULL 4 Using where; Using index 1 PRIMARY t2 index NULL a 5 NULL 4 Using where; Using index
2 DEPENDENT SUBQUERY t3 index a a 5 NULL 3 Using index 2 DEPENDENT SUBQUERY t1 ref a a 5 func 1001 Using where; Using index
2 DEPENDENT SUBQUERY t1 ref a a 10 func,test.t3.a 1000 Using where; Using index 2 DEPENDENT SUBQUERY t3 index a a 5 NULL 3 Using where; Using index
Warnings: Warnings:
Note 1003 select high_priority 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)) limit 1)) Note 1003 select high_priority 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 ((<cache>(test.t2.a) = test.t1.a) and (test.t3.a = test.t1.b)) limit 1))
insert into t1 values (3,31); insert into t1 values (3,31);
select * from t2 where t2.a in (select a from t1 where t1.b <> 30); select * from t2 where t2.a in (select a from t1 where t1.b <> 30);
a a
......
...@@ -23,7 +23,7 @@ i @vv1:=if(sv1.i,1,0) @vv2:=if(sv2.i,1,0) @vv3:=if(sv3.i,1,0) @vv1+@vv2+@vv3 ...@@ -23,7 +23,7 @@ i @vv1:=if(sv1.i,1,0) @vv2:=if(sv2.i,1,0) @vv3:=if(sv3.i,1,0) @vv1+@vv2+@vv3
2 1 0 0 1 2 1 0 0 1
explain select * from t1 where i=@vv1; explain select * from t1 where i=@vv1;
id select_type table type possible_keys key key_len ref rows Extra id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 ref i i 4 const 1 Using where 1 SIMPLE t1 ref i i 4 const 1
explain select * from t1 where @vv1:=@vv1+1 and i=@vv1; explain select * from t1 where @vv1:=@vv1+1 and i=@vv1;
id select_type table type possible_keys key key_len ref rows Extra id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 ALL NULL NULL NULL NULL 3 Using where 1 SIMPLE t1 ALL NULL NULL NULL NULL 3 Using where
...@@ -32,7 +32,7 @@ id select_type table type possible_keys key key_len ref rows Extra ...@@ -32,7 +32,7 @@ id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 index NULL i 4 NULL 3 Using where; Using index 1 SIMPLE t1 index NULL i 4 NULL 3 Using where; Using index
explain select * from t1 where i=@vv1; explain select * from t1 where i=@vv1;
id select_type table type possible_keys key key_len ref rows Extra id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 ref i i 4 const 1 Using where 1 SIMPLE t1 ref i i 4 const 1
drop table t1,t2; drop table t1,t2;
set @a=0,@b=0; set @a=0,@b=0;
select @a:=10, @b:=1, @a > @b, @a < @b; select @a:=10, @b:=1, @a > @b, @a < @b;
......
...@@ -334,8 +334,12 @@ insert into t2(id, uid, name) select id, uid, name from t1; ...@@ -334,8 +334,12 @@ insert into t2(id, uid, name) select id, uid, name from t1;
select count(*) from t1; select count(*) from t1;
select count(*) from t2; 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 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 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;
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;
......
...@@ -318,7 +318,8 @@ bool DTCollation::aggregate(DTCollation &dt) ...@@ -318,7 +318,8 @@ bool DTCollation::aggregate(DTCollation &dt)
return 0; return 0;
} }
Item_field::Item_field(Field *f) :Item_ident(NullS,f->table_name,f->field_name) Item_field::Item_field(Field *f)
:Item_ident(NullS,f->table_name,f->field_name), item_equal(0)
{ {
set_field(f); set_field(f);
collation.set(DERIVATION_IMPLICIT); collation.set(DERIVATION_IMPLICIT);
...@@ -332,6 +333,7 @@ Item_field::Item_field(THD *thd, Item_field &item) ...@@ -332,6 +333,7 @@ Item_field::Item_field(THD *thd, Item_field &item)
result_field(item.result_field) result_field(item.result_field)
{ {
collation.set(DERIVATION_IMPLICIT); collation.set(DERIVATION_IMPLICIT);
item_equal= item.item_equal;
} }
void Item_field::set_field(Field *field_par) void Item_field::set_field(Field *field_par)
...@@ -992,6 +994,49 @@ bool Item_field::fix_fields(THD *thd, TABLE_LIST *tables, Item **ref) ...@@ -992,6 +994,49 @@ bool Item_field::fix_fields(THD *thd, TABLE_LIST *tables, Item **ref)
return 0; return 0;
} }
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;
}
cond_equal= cond_equal->parent_level;
}
return item;
}
Item *Item_field::equal_fields_propagator(byte *arg)
{
COND_EQUAL *cond_equal= (COND_EQUAL *) arg;
item_equal= find_item_equal(cond_equal);
Item *item= 0;
if (item_equal)
item= item_equal->get_const();
if (item)
item->fixed= 0;
else
item= this;
return item;
}
bool Item_field::replace_equal_field_processor(byte *arg)
{
if (item_equal)
{
Item_field *subst= item_equal->get_first();
if (subst && !field->eq(subst->field))
{
field= subst->field;
return 0;
}
}
return 0;
}
void Item::init_make_field(Send_field *tmp_field, void Item::init_make_field(Send_field *tmp_field,
enum enum_field_types field_type) enum enum_field_types field_type)
......
...@@ -83,6 +83,7 @@ public: ...@@ -83,6 +83,7 @@ public:
}; };
typedef bool (Item::*Item_processor)(byte *arg); typedef bool (Item::*Item_processor)(byte *arg);
typedef Item* (Item::*Item_calculator) (byte *arg);
class Item { class Item {
Item(const Item &); /* Prevent use of these */ Item(const Item &); /* Prevent use of these */
...@@ -211,8 +212,15 @@ public: ...@@ -211,8 +212,15 @@ public:
return (this->*processor)(arg); return (this->*processor)(arg);
} }
virtual Item* traverse(Item_calculator calculator, byte *arg)
{
return (this->*calculator)(arg);
}
virtual bool remove_dependence_processor(byte * arg) { return 0; } virtual bool remove_dependence_processor(byte * arg) { return 0; }
virtual bool remove_fixed(byte * arg) { fixed= 0; return 0; } virtual bool remove_fixed(byte * arg) { fixed= 0; 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_item() { return this; } /* For SPs mostly. */
virtual Item *this_const_item() const { return const_cast<Item*>(this); } /* For SPs mostly. */ virtual Item *this_const_item() const { return const_cast<Item*>(this); } /* For SPs mostly. */
...@@ -337,17 +345,21 @@ public: ...@@ -337,17 +345,21 @@ public:
bool remove_dependence_processor(byte * arg); bool remove_dependence_processor(byte * arg);
}; };
class Item_equal;
class COND_EQUAL;
class Item_field :public Item_ident class Item_field :public Item_ident
{ {
void set_field(Field *field); void set_field(Field *field);
public: public:
Field *field,*result_field; Field *field,*result_field;
Item_equal *item_equal;
// Item_field() {} // Item_field() {}
Item_field(const char *db_par,const char *table_name_par, Item_field(const char *db_par,const char *table_name_par,
const char *field_name_par) const char *field_name_par)
:Item_ident(db_par,table_name_par,field_name_par),field(0),result_field(0) :Item_ident(db_par,table_name_par,field_name_par),field(0),result_field(0),
item_equal(0)
{ collation.set(DERIVATION_IMPLICIT); } { collation.set(DERIVATION_IMPLICIT); }
// Constructor need to process subselect with temporary tables (see Item) // Constructor need to process subselect with temporary tables (see Item)
Item_field(THD *thd, Item_field &item); Item_field(THD *thd, Item_field &item);
...@@ -381,6 +393,9 @@ public: ...@@ -381,6 +393,9 @@ public:
bool get_time(TIME *ltime); bool get_time(TIME *ltime);
bool is_null() { return field->is_null(); } bool is_null() { return field->is_null(); }
Item *get_tmp_table_item(THD *thd); Item *get_tmp_table_item(THD *thd);
Item_equal *find_item_equal(COND_EQUAL *cond_equal);
Item *equal_fields_propagator(byte *arg);
bool replace_equal_field_processor(byte *arg);
friend class Item_default_value; friend class Item_default_value;
friend class Item_insert_value; friend class Item_insert_value;
}; };
...@@ -933,6 +948,15 @@ public: ...@@ -933,6 +948,15 @@ public:
return arg->walk(processor, args) || return arg->walk(processor, args) ||
(this->*processor)(args); (this->*processor)(args);
} }
Item *traverse(Item_calculator calculator, byte *args)
{
Item *new_item= arg->traverse(calculator, args);
if (!new_item)
return 0;
arg= new_item;
return (this->*calculator)(args);
}
}; };
class Item_insert_value : public Item_field class Item_insert_value : public Item_field
......
...@@ -225,7 +225,7 @@ void Item_bool_func2::fix_length_and_dec() ...@@ -225,7 +225,7 @@ void Item_bool_func2::fix_length_and_dec()
} }
// Make a special case of compare with fields to get nicer DATE comparisons // Make a special case of compare with fields to get nicer DATE comparisons
if (args[0]->type() == FIELD_ITEM) if (args[0]->type() == FIELD_ITEM && !args[0]->const_item())
{ {
Field *field=((Item_field*) args[0])->field; Field *field=((Item_field*) args[0])->field;
if (field->store_for_compare()) if (field->store_for_compare())
...@@ -238,7 +238,7 @@ void Item_bool_func2::fix_length_and_dec() ...@@ -238,7 +238,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; Field *field=((Item_field*) args[1])->field;
if (field->store_for_compare()) if (field->store_for_compare())
...@@ -1739,6 +1739,21 @@ bool Item_cond::walk(Item_processor processor, byte *arg) ...@@ -1739,6 +1739,21 @@ bool Item_cond::walk(Item_processor processor, byte *arg)
return Item_func::walk(processor, arg); return Item_func::walk(processor, arg);
} }
Item *Item_cond::traverse(Item_calculator calculator, byte *arg)
{
List_iterator<Item> li(list);
Item *item;
while ((item= li++))
{
Item *new_item= item->traverse(calculator, arg);
if (!new_item)
return 0;
if (new_item != item)
li.replace(new_item);
}
return Item_func::traverse(calculator, arg);
}
void Item_cond::split_sum_func(Item **ref_pointer_array, List<Item> &fields) void Item_cond::split_sum_func(Item **ref_pointer_array, List<Item> &fields)
{ {
List_iterator<Item> li(list); List_iterator<Item> li(list);
...@@ -2526,3 +2541,217 @@ Item *Item_cond_or::neg_transformer() /* NOT(a OR b OR ...) -> */ ...@@ -2526,3 +2541,217 @@ Item *Item_cond_or::neg_transformer() /* NOT(a OR b OR ...) -> */
neg_arguments(); neg_arguments();
return new Item_cond_and(list); return new Item_cond_and(list);
} }
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();
cond_false = !(func->val_int());
}
void Item_equal::add(Item_field *f)
{
fields.push_back(f);
}
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;
}
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;
}
void Item_equal::sort(void *table_join_idx)
{
bool swap;
void **idx= (void **) table_join_idx;
List_iterator<Item_field> it(fields);
do
{
Item_field *item1= it++;
Item_field **ref1= it.ref();
Item_field *item2;
Item_field **ref2;
if (!item1)
break;
swap= FALSE;
while ((item2= it++))
{
ref2= it.ref();
if (idx[item1->field->table->tablenr] >
idx[item2->field->table->tablenr])
{
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;
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::traverse(Item_calculator calculator, byte *arg)
{
List_iterator<Item_field> it(fields);
Item *item;
while ((item= it++))
{
Item *new_item= item->traverse(calculator, arg);
if (!new_item)
return 0;
if (new_item != item)
it.replace((Item_field *) new_item);
}
return Item_func::traverse(calculator, arg);
}
void Item_equal::print(String *str)
{
str->append(func_name());
str->append('(');
List_iterator_fast<Item_field> it(fields);
Item *item;
if ((item= it++))
item->print(str);
while ((item= it++))
{
str->append(',');
str->append(' ');
item->print(str);
}
str->append(')');
}
...@@ -902,13 +902,76 @@ public: ...@@ -902,13 +902,76 @@ public:
void top_level_item() { abort_on_null=1; } void top_level_item() { abort_on_null=1; }
void copy_andor_arguments(THD *thd, Item_cond *item); void copy_andor_arguments(THD *thd, Item_cond *item);
bool walk(Item_processor processor, byte *arg); bool walk(Item_processor processor, byte *arg);
Item *traverse(Item_calculator calculator, byte *arg);
void neg_arguments(); void neg_arguments();
}; };
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);
bool is_false() { return cond_false; }
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(void *table_join_idx);
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 *traverse(Item_calculator calculator, byte *arg);
void print(String *str);
};
class COND_EQUAL
{
public:
COND_EQUAL *parent_level;
List<Item_equal> current_level;
COND_EQUAL() { parent_level= 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 class Item_cond_and :public Item_cond
{ {
public: public:
COND_EQUAL cond_equal;
Item_cond_and() :Item_cond() {} Item_cond_and() :Item_cond() {}
Item_cond_and(Item *i1,Item *i2) :Item_cond(i1,i2) {} Item_cond_and(Item *i1,Item *i2) :Item_cond(i1,i2) {}
Item_cond_and(THD *thd, Item_cond_and &item) :Item_cond(thd, item) {} Item_cond_and(THD *thd, Item_cond_and &item) :Item_cond(thd, item) {}
......
...@@ -242,6 +242,40 @@ bool Item_func::walk (Item_processor processor, byte *argument) ...@@ -242,6 +242,40 @@ bool Item_func::walk (Item_processor processor, byte *argument)
return (this->*processor)(argument); return (this->*processor)(argument);
} }
Item *Item_func::traverse(Item_calculator calculator, 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)->traverse(calculator, argument);
if (!new_item)
return 0;
*arg= new_item;
}
}
return (this->*calculator)(argument);
}
Item *Item_func::equal_fields_propagator(byte *argument)
{
if (arg_count)
{
Item **arg,**arg_end;
for (arg= args, arg_end= args+arg_count; arg != arg_end; arg++)
{
if (!(*arg)->fixed)
{
fix_fields(current_thd, 0, 0);
break;
}
}
}
return this;
}
void Item_func::split_sum_func(Item **ref_pointer_array, List<Item> &fields) void Item_func::split_sum_func(Item **ref_pointer_array, List<Item> &fields)
{ {
Item **arg, **arg_end; Item **arg, **arg_end;
......
...@@ -40,7 +40,8 @@ public: ...@@ -40,7 +40,8 @@ public:
enum Functype { UNKNOWN_FUNC,EQ_FUNC,EQUAL_FUNC,NE_FUNC,LT_FUNC,LE_FUNC, enum Functype { UNKNOWN_FUNC,EQ_FUNC,EQUAL_FUNC,NE_FUNC,LT_FUNC,LE_FUNC,
GE_FUNC,GT_FUNC,FT_FUNC, GE_FUNC,GT_FUNC,FT_FUNC,
LIKE_FUNC,NOTLIKE_FUNC,ISNULL_FUNC,ISNOTNULL_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, INTERVAL_FUNC, ISNOTNULLTEST_FUNC,
SP_EQUALS_FUNC, SP_DISJOINT_FUNC,SP_INTERSECTS_FUNC, SP_EQUALS_FUNC, SP_DISJOINT_FUNC,SP_INTERSECTS_FUNC,
SP_TOUCHES_FUNC,SP_CROSSES_FUNC,SP_WITHIN_FUNC, SP_TOUCHES_FUNC,SP_CROSSES_FUNC,SP_WITHIN_FUNC,
...@@ -49,7 +50,8 @@ public: ...@@ -49,7 +50,8 @@ public:
SP_POINTN,SP_GEOMETRYN,SP_INTERIORRINGN, SP_POINTN,SP_GEOMETRYN,SP_INTERIORRINGN,
NOT_FUNC, NOT_ALL_FUNC, NOT_FUNC, NOT_ALL_FUNC,
GUSERVAR_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; } enum Type type() const { return FUNC_ITEM; }
virtual enum Functype functype() const { return UNKNOWN_FUNC; } virtual enum Functype functype() const { return UNKNOWN_FUNC; }
Item_func(void): Item_func(void):
...@@ -146,6 +148,8 @@ public: ...@@ -146,6 +148,8 @@ public:
bool agg_arg_collations_for_comparison(DTCollation &c, Item **items, uint nitems); bool agg_arg_collations_for_comparison(DTCollation &c, Item **items, uint nitems);
bool walk(Item_processor processor, byte *arg); bool walk(Item_processor processor, byte *arg);
Item *traverse(Item_calculator calculator, byte *arg);
Item *equal_fields_propagator(byte *arg);
}; };
......
...@@ -140,6 +140,18 @@ bool Item_row::walk(Item_processor processor, byte *arg) ...@@ -140,6 +140,18 @@ bool Item_row::walk(Item_processor processor, byte *arg)
return (this->*processor)(arg); return (this->*processor)(arg);
} }
Item *Item_row::traverse(Item_calculator calculator, byte *arg)
{
for (uint i= 0; i < arg_count; i++)
{
Item *new_item= items[i]->traverse(calculator, arg);
if (!new_item)
return 0;
items[i]= new_item;
}
return (this->*calculator)(arg);
}
void Item_row::bring_value() void Item_row::bring_value()
{ {
for (uint i= 0; i < arg_count; i++) for (uint i= 0; i < arg_count; i++)
......
...@@ -71,6 +71,7 @@ public: ...@@ -71,6 +71,7 @@ public:
void print(String *str); void print(String *str);
bool walk(Item_processor processor, byte *arg); bool walk(Item_processor processor, byte *arg);
Item *traverse(Item_calculator calculator, byte *arg);
uint cols() { return arg_count; } uint cols() { return arg_count; }
Item* el(uint i) { return items[i]; } Item* el(uint i) { return items[i]; }
......
...@@ -427,6 +427,14 @@ public: ...@@ -427,6 +427,14 @@ public:
return item->walk(processor, arg) || return item->walk(processor, arg) ||
Item_str_func::walk(processor, arg); Item_str_func::walk(processor, arg);
} }
Item *traverse(Item_calculator calculator, byte *arg)
{
Item *new_item= item->traverse(calculator, arg);
if (!new_item)
return 0;
item= new_item;
return Item_str_func::traverse(calculator, arg);
}
void print(String *str); void print(String *str);
}; };
......
...@@ -1493,11 +1493,75 @@ static int get_quick_select_params(SEL_TREE *tree, PARAM *param, ...@@ -1493,11 +1493,75 @@ static int get_quick_select_params(SEL_TREE *tree, PARAM *param,
return result; return result;
} }
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");
if (cond_func->functype() == Item_func::NE_FUNC)
{
tree= get_mm_parts(param, field, Item_func::LT_FUNC,
value, cmp_type);
if (tree)
{
tree= tree_or(param, tree, get_mm_parts(param, field,
Item_func::GT_FUNC,
value, cmp_type));
}
}
else if (cond_func->functype() == Item_func::BETWEEN)
{
tree= get_mm_parts(param, field, Item_func::GE_FUNC,
cond_func->arguments()[1],cmp_type);
if (tree)
{
tree= tree_and(param, tree, get_mm_parts(param, field,
Item_func::LE_FUNC,
cond_func->arguments()[2],
cmp_type));
}
}
else if (cond_func->functype() == Item_func::IN_FUNC)
{
Item_func_in *func=(Item_func_in*) cond_func;
tree= get_mm_parts(param, field, Item_func::EQ_FUNC,
func->arguments()[1], cmp_type);
if (tree)
{
for (uint i =2 ; i < func->argument_count() ; i++)
{
tree= tree_or(param, tree, get_mm_parts(param, field,
Item_func::EQ_FUNC,
func->arguments()[i],
cmp_type));
}
}
}
else
{
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, field, func_type, value, cmp_type);
}
DBUG_RETURN(tree);
}
/* make a select tree of all keys in condition */ /* make a select tree of all keys in condition */
static SEL_TREE *get_mm_tree(PARAM *param,COND *cond) static SEL_TREE *get_mm_tree(PARAM *param,COND *cond)
{ {
SEL_TREE *tree=0; SEL_TREE *tree=0;
SEL_TREE *ftree= 0;
Item_field *field_item= 0;
Item *value;
DBUG_ENTER("get_mm_tree"); DBUG_ENTER("get_mm_tree");
if (cond->type() == Item::COND_ITEM) if (cond->type() == Item::COND_ITEM)
...@@ -1545,9 +1609,12 @@ static SEL_TREE *get_mm_tree(PARAM *param,COND *cond) ...@@ -1545,9 +1609,12 @@ static SEL_TREE *get_mm_tree(PARAM *param,COND *cond)
DBUG_RETURN(new SEL_TREE(SEL_TREE::IMPOSSIBLE)); 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) if (cond->type() != Item::FUNC_ITEM)
{ // Should be a field { // Should be a field
ref_tables= cond->used_tables();
if ((ref_tables & param->current_table) || if ((ref_tables & param->current_table) ||
(ref_tables & ~(param->prev_tables | param->read_tables))) (ref_tables & ~(param->prev_tables | param->read_tables)))
DBUG_RETURN(0); DBUG_RETURN(0);
...@@ -1559,76 +1626,98 @@ static SEL_TREE *get_mm_tree(PARAM *param,COND *cond) ...@@ -1559,76 +1626,98 @@ static SEL_TREE *get_mm_tree(PARAM *param,COND *cond)
DBUG_RETURN(0); // Can't be calculated DBUG_RETURN(0); // Can't be calculated
if (cond_func->functype() == Item_func::BETWEEN) if (cond_func->functype() == Item_func::BETWEEN)
{ {
if (cond_func->arguments()[0]->type() == Item::FIELD_ITEM) if (cond_func->arguments()[0]->type() == Item::FIELD_ITEM)
{ {
Field *field=((Item_field*) (cond_func->arguments()[0]))->field; field_item= (Item_field*) (cond_func->arguments()[0]);
Item_result cmp_type=field->cmp_type(); value= NULL;
DBUG_RETURN(tree_and(param,
get_mm_parts(param, field,
Item_func::GE_FUNC,
cond_func->arguments()[1], cmp_type),
get_mm_parts(param, field,
Item_func::LE_FUNC,
cond_func->arguments()[2], cmp_type)));
} }
DBUG_RETURN(0); else
DBUG_RETURN(0);
} }
if (cond_func->functype() == Item_func::IN_FUNC) else if (cond_func->functype() == Item_func::IN_FUNC)
{ // COND OR {
Item_func_in *func=(Item_func_in*) cond_func; Item_func_in *func=(Item_func_in*) cond_func;
if (func->key_item()->type() == Item::FIELD_ITEM) if (func->key_item()->type() == Item::FIELD_ITEM)
{ {
Field *field=((Item_field*) (func->key_item()))->field; field_item= (Item_field*) (func->key_item());
Item_result cmp_type=field->cmp_type(); value= NULL;
tree= get_mm_parts(param,field,Item_func::EQ_FUNC, }
func->arguments()[1],cmp_type); else
if (!tree) DBUG_RETURN(0);
DBUG_RETURN(tree); // Not key field }
for (uint i=2 ; i < func->argument_count(); i++) else if (cond_func->functype() == Item_func::MULT_EQUAL_FUNC)
{
Item_equal *item_equal= (Item_equal *) cond;
Item_equal_iterator it(*item_equal);
if (!(value= item_equal->get_const()))
value= it++;
while (value)
{
ref_tables= value->used_tables();
Item_equal_iterator li(*item_equal);
while ((field_item= li++))
{ {
SEL_TREE *new_tree=get_mm_parts(param,field,Item_func::EQ_FUNC, if (field_item != value)
func->arguments()[i],cmp_type); {
tree=tree_or(param,tree,new_tree); 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, field, Item_func::EQ_FUNC,
value,cmp_type);
ftree= !ftree ? tree : tree_and(param, ftree, tree);
}
}
} }
DBUG_RETURN(tree); if (item_equal->get_const())
} break;
DBUG_RETURN(0); // Can't optimize this IN value= it++;
} }
DBUG_RETURN(ftree);
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
/* check field op const */
/* btw, ft_func's arguments()[0] isn't FIELD_ITEM. SerG*/
if (cond_func->arguments()[0]->type() == Item::FIELD_ITEM)
{
tree= get_mm_parts(param,
((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());
}
/* check const op field */
if (!tree &&
cond_func->have_rev_func() &&
cond_func->arguments()[1]->type() == Item::FIELD_ITEM)
{
DBUG_RETURN(get_mm_parts(param,
((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()
));
} }
DBUG_RETURN(tree); else if (cond_func->arguments()[0]->type() == Item::FIELD_ITEM)
{
field_item= (Item_field*) (cond_func->arguments()[0]);
value= cond_func->arg_count > 1 ? cond_func->arguments()[1] : 0;
}
else if (cond_func->have_rev_func() &&
cond_func->arguments()[1]->type() == Item::FIELD_ITEM)
{
field_item= (Item_field*) (cond_func->arguments()[1]);
value= cond_func->arguments()[0];
}
else
DBUG_RETURN(0);
for (uint i= 0; i < cond_func->arg_count; i++)
{
Item *arg= cond_func->arguments()[i];
if (arg != field_item)
ref_tables|= arg->used_tables();
}
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)
{
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(ftree);
} }
...@@ -1636,17 +1725,10 @@ static SEL_TREE * ...@@ -1636,17 +1725,10 @@ static SEL_TREE *
get_mm_parts(PARAM *param, Field *field, Item_func::Functype type, get_mm_parts(PARAM *param, Field *field, Item_func::Functype type,
Item *value, Item_result cmp_type) Item *value, Item_result cmp_type)
{ {
bool ne_func= FALSE;
DBUG_ENTER("get_mm_parts"); DBUG_ENTER("get_mm_parts");
if (field->table != param->table) if (field->table != param->table)
DBUG_RETURN(0); 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 *key_part = param->key_parts;
KEY_PART *end = param->key_parts_end; KEY_PART *end = param->key_parts_end;
SEL_TREE *tree=0; SEL_TREE *tree=0;
...@@ -1683,14 +1765,6 @@ get_mm_parts(PARAM *param, Field *field, Item_func::Functype type, ...@@ -1683,14 +1765,6 @@ get_mm_parts(PARAM *param, Field *field, Item_func::Functype type,
} }
} }
if (ne_func)
{
SEL_TREE *tree2= get_mm_parts(param, field, Item_func::GT_FUNC,
value, cmp_type);
if (tree2)
tree= tree_or(param,tree,tree2);
}
DBUG_RETURN(tree); DBUG_RETURN(tree);
} }
......
...@@ -351,6 +351,18 @@ static bool simple_pred(Item_func *func_item, Item **args, bool *inv_order) ...@@ -351,6 +351,18 @@ static bool simple_pred(Item_func *func_item, Item **args, bool *inv_order)
Item *item; Item *item;
*inv_order= 0; *inv_order= 0;
switch (func_item->argument_count()) { 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: case 1:
/* field IS NULL */ /* field IS NULL */
item= func_item->arguments()[0]; item= func_item->arguments()[0];
...@@ -491,6 +503,9 @@ static bool matching_cond(bool max_fl, TABLE_REF *ref, KEY *keyinfo, ...@@ -491,6 +503,9 @@ static bool matching_cond(bool max_fl, TABLE_REF *ref, KEY *keyinfo,
case Item_func::BETWEEN: case Item_func::BETWEEN:
between= 1; between= 1;
break; break;
case Item_func::MULT_EQUAL_FUNC:
eq_type= 1;
break;
default: default:
return 0; // Can't optimize function return 0; // Can't optimize function
} }
......
...@@ -121,10 +121,12 @@ public: ...@@ -121,10 +121,12 @@ public:
void remove(list_node **prev) void remove(list_node **prev)
{ {
list_node *node=(*prev)->next; list_node *node=(*prev)->next;
delete *prev;
*prev=node;
if (!--elements) if (!--elements)
last= &first; last= &first;
else if (last == &(*prev)->next)
last= prev;
delete *prev;
*prev=node;
} }
inline void *pop(void) inline void *pop(void)
{ {
...@@ -137,9 +139,27 @@ public: ...@@ -137,9 +139,27 @@ public:
} }
inline void concat(base_list *list) inline void concat(base_list *list)
{ {
*last= list->first; if (!list->is_empty())
last= list->last; {
elements+= list->elements; *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 list_node* last_node() { return *last; } inline list_node* last_node() { return *last; }
inline list_node* first_node() { return first;} inline list_node* first_node() { return first;}
...@@ -251,6 +271,8 @@ public: ...@@ -251,6 +271,8 @@ public:
inline T* head() {return (T*) base_list::head(); } inline T* head() {return (T*) base_list::head(); }
inline T** head_ref() {return (T**) base_list::head_ref(); } inline T** head_ref() {return (T**) base_list::head_ref(); }
inline T* pop() {return (T*) base_list::pop(); } 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); }
void delete_elements(void) void delete_elements(void)
{ {
list_node *element,*next; list_node *element,*next;
...@@ -261,7 +283,6 @@ public: ...@@ -261,7 +283,6 @@ public:
} }
empty(); empty();
} }
inline void concat(List<T> *list) { base_list::concat(list); }
}; };
...@@ -272,6 +293,8 @@ public: ...@@ -272,6 +293,8 @@ public:
inline T* operator++(int) { return (T*) base_list_iterator::next(); } 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(T *a) { return (T*) base_list_iterator::replace(a); }
inline T *replace(List<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 void after(T *a) { base_list_iterator::after(a); }
inline T** ref(void) { return (T**) base_list_iterator::ref(); } inline T** ref(void) { return (T**) base_list_iterator::ref(); }
}; };
......
This diff is collapsed.
...@@ -196,6 +196,7 @@ class JOIN :public Sql_alloc ...@@ -196,6 +196,7 @@ class JOIN :public Sql_alloc
ORDER *order, *group_list, *proc_param; //hold parameters of mysql_select ORDER *order, *group_list, *proc_param; //hold parameters of mysql_select
COND *conds; // ---"--- COND *conds; // ---"---
Item *conds_history; // store WHERE for explain Item *conds_history; // store WHERE for explain
COND_EQUAL *cond_equal;
TABLE_LIST *tables_list; //hold 'tables' parameter of mysql_selec TABLE_LIST *tables_list; //hold 'tables' parameter of mysql_selec
SQL_SELECT *select; //created in optimisation phase SQL_SELECT *select; //created in optimisation phase
Item **ref_pointer_array; //used pointer reference for this select Item **ref_pointer_array; //used pointer reference for this select
...@@ -255,6 +256,7 @@ class JOIN :public Sql_alloc ...@@ -255,6 +256,7 @@ class JOIN :public Sql_alloc
ref_pointer_array_size= 0; ref_pointer_array_size= 0;
zero_result_cause= 0; zero_result_cause= 0;
optimized= 0; optimized= 0;
cond_equal= 0;
fields_list= fields_arg; fields_list= fields_arg;
bzero((char*) &keyuse,sizeof(keyuse)); bzero((char*) &keyuse,sizeof(keyuse));
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment