← Back to team overview

maria-developers team mailing list archive

Rev 2790: Fixed sum functions dependency for subqueries in file:///home/bell/maria/bzr/work-maria-5.3-scache/

 

At file:///home/bell/maria/bzr/work-maria-5.3-scache/

------------------------------------------------------------
revno: 2790
revision-id: sanja@xxxxxxxxxxxx-20100525104536-zw06otfk8ut7fias
parent: sanja@xxxxxxxxxxxx-20100524172956-7b14x01aodizr3sq
committer: sanja@xxxxxxxxxxxx
branch nick: work-maria-5.3-scache
timestamp: Tue 2010-05-25 13:45:36 +0300
message:
  Fixed sum functions dependency for subqueries
  Forgoten files added.
=== added file 'mysql-test/r/subquery_cache.result'
--- a/mysql-test/r/subquery_cache.result	1970-01-01 00:00:00 +0000
+++ b/mysql-test/r/subquery_cache.result	2010-05-25 10:45:36 +0000
@@ -0,0 +1,555 @@
+set optimizer_switch='subquery_cache=on';
+create table t1 (a int, b int);
+insert into t1 values (1,2),(3,4),(1,2),(3,4),(3,4),(4,5),(4,5),(5,6),(5,6),(4,5);
+create table t2 (c int, d int);
+insert into t2 values (2,3),(3,4),(5,6);
+#single value subquery test
+select a, (select d from t2 where b=c) + 1 from t1;
+a	(select d from t2 where b=c) + 1
+1	4
+3	NULL
+1	4
+3	NULL
+3	NULL
+4	7
+4	7
+5	NULL
+5	NULL
+4	7
+show status like "subquery_cache%";
+Variable_name	Value
+Subquery_cache_hit	6
+Subquery_cache_miss	4
+#single value subquery test (PS)
+prepare stmt1 from 'select a, (select d from t2 where b=c) + 1 from t1';
+execute stmt1;
+a	(select d from t2 where b=c) + 1
+1	4
+3	NULL
+1	4
+3	NULL
+3	NULL
+4	7
+4	7
+5	NULL
+5	NULL
+4	7
+show status like "subquery_cache%";
+Variable_name	Value
+Subquery_cache_hit	12
+Subquery_cache_miss	8
+execute stmt1;
+a	(select d from t2 where b=c) + 1
+1	4
+3	NULL
+1	4
+3	NULL
+3	NULL
+4	7
+4	7
+5	NULL
+5	NULL
+4	7
+show status like "subquery_cache%";
+Variable_name	Value
+Subquery_cache_hit	18
+Subquery_cache_miss	12
+deallocate prepare stmt1;
+#single value subquery test (SP)
+CREATE PROCEDURE p1() select a, (select d from t2 where b=c) + 1 from t1;
+call p1;
+a	(select d from t2 where b=c) + 1
+1	4
+3	NULL
+1	4
+3	NULL
+3	NULL
+4	7
+4	7
+5	NULL
+5	NULL
+4	7
+call p1;
+a	(select d from t2 where b=c) + 1
+1	4
+3	NULL
+1	4
+3	NULL
+3	NULL
+4	7
+4	7
+5	NULL
+5	NULL
+4	7
+drop procedure p1;
+#IN subquery test
+flush status;
+show status like "subquery_cache%";
+Variable_name	Value
+Subquery_cache_hit	0
+Subquery_cache_miss	0
+select a, b , b in (select d from t2) as SUBS from t1;
+a	b	SUBS
+1	2	0
+3	4	1
+1	2	0
+3	4	1
+3	4	1
+4	5	0
+4	5	0
+5	6	1
+5	6	1
+4	5	0
+show status like "subquery_cache%";
+Variable_name	Value
+Subquery_cache_hit	6
+Subquery_cache_miss	4
+insert into t1 values (7,8),(9,NULL);
+select a, b , b in (select d from t2) as SUBS from t1;
+a	b	SUBS
+1	2	0
+3	4	1
+1	2	0
+3	4	1
+3	4	1
+4	5	0
+4	5	0
+5	6	1
+5	6	1
+4	5	0
+7	8	0
+9	NULL	NULL
+show status like "subquery_cache%";
+Variable_name	Value
+Subquery_cache_hit	12
+Subquery_cache_miss	10
+insert into t2 values (8,NULL);
+select a, b , b in (select d from t2) as SUBS from t1;
+a	b	SUBS
+1	2	NULL
+3	4	1
+1	2	NULL
+3	4	1
+3	4	1
+4	5	NULL
+4	5	NULL
+5	6	1
+5	6	1
+4	5	NULL
+7	8	NULL
+9	NULL	NULL
+show status like "subquery_cache%";
+Variable_name	Value
+Subquery_cache_hit	18
+Subquery_cache_miss	16
+#IN subquery tesy (PS)
+delete from t1 where a > 6;
+delete from t2 where c > 6;
+prepare stmt1 from 'select a, b , b in (select d from t2) as SUBS from t1';
+execute stmt1;
+a	b	SUBS
+1	2	0
+3	4	1
+1	2	0
+3	4	1
+3	4	1
+4	5	0
+4	5	0
+5	6	1
+5	6	1
+4	5	0
+show status like "subquery_cache%";
+Variable_name	Value
+Subquery_cache_hit	24
+Subquery_cache_miss	20
+execute stmt1;
+a	b	SUBS
+1	2	0
+3	4	1
+1	2	0
+3	4	1
+3	4	1
+4	5	0
+4	5	0
+5	6	1
+5	6	1
+4	5	0
+show status like "subquery_cache%";
+Variable_name	Value
+Subquery_cache_hit	30
+Subquery_cache_miss	24
+insert into t1 values (7,8),(9,NULL);
+execute stmt1;
+a	b	SUBS
+1	2	0
+3	4	1
+1	2	0
+3	4	1
+3	4	1
+4	5	0
+4	5	0
+5	6	1
+5	6	1
+4	5	0
+9	NULL	NULL
+7	8	0
+show status like "subquery_cache%";
+Variable_name	Value
+Subquery_cache_hit	36
+Subquery_cache_miss	30
+execute stmt1;
+a	b	SUBS
+1	2	0
+3	4	1
+1	2	0
+3	4	1
+3	4	1
+4	5	0
+4	5	0
+5	6	1
+5	6	1
+4	5	0
+9	NULL	NULL
+7	8	0
+show status like "subquery_cache%";
+Variable_name	Value
+Subquery_cache_hit	42
+Subquery_cache_miss	36
+insert into t2 values (8,NULL);
+execute stmt1;
+a	b	SUBS
+1	2	NULL
+3	4	1
+1	2	NULL
+3	4	1
+3	4	1
+4	5	NULL
+4	5	NULL
+5	6	1
+5	6	1
+4	5	NULL
+9	NULL	NULL
+7	8	NULL
+show status like "subquery_cache%";
+Variable_name	Value
+Subquery_cache_hit	48
+Subquery_cache_miss	42
+execute stmt1;
+a	b	SUBS
+1	2	NULL
+3	4	1
+1	2	NULL
+3	4	1
+3	4	1
+4	5	NULL
+4	5	NULL
+5	6	1
+5	6	1
+4	5	NULL
+9	NULL	NULL
+7	8	NULL
+show status like "subquery_cache%";
+Variable_name	Value
+Subquery_cache_hit	54
+Subquery_cache_miss	48
+deallocate prepare stmt1;
+#IN subquery tesy (SP)
+delete from t1 where a > 6;
+delete from t2 where c > 6;
+CREATE PROCEDURE p1() select a, b , b in (select d from t2) as SUBS from t1;
+call p1();
+a	b	SUBS
+1	2	0
+3	4	1
+1	2	0
+3	4	1
+3	4	1
+4	5	0
+4	5	0
+5	6	1
+5	6	1
+4	5	0
+show status like "subquery_cache%";
+Variable_name	Value
+Subquery_cache_hit	60
+Subquery_cache_miss	52
+call p1();
+a	b	SUBS
+1	2	0
+3	4	1
+1	2	0
+3	4	1
+3	4	1
+4	5	0
+4	5	0
+5	6	1
+5	6	1
+4	5	0
+show status like "subquery_cache%";
+Variable_name	Value
+Subquery_cache_hit	66
+Subquery_cache_miss	56
+insert into t1 values (7,8),(9,NULL);
+call p1();
+a	b	SUBS
+1	2	0
+3	4	1
+1	2	0
+3	4	1
+3	4	1
+4	5	0
+4	5	0
+5	6	1
+5	6	1
+4	5	0
+9	NULL	NULL
+7	8	0
+show status like "subquery_cache%";
+Variable_name	Value
+Subquery_cache_hit	72
+Subquery_cache_miss	62
+call p1();
+a	b	SUBS
+1	2	0
+3	4	1
+1	2	0
+3	4	1
+3	4	1
+4	5	0
+4	5	0
+5	6	1
+5	6	1
+4	5	0
+9	NULL	NULL
+7	8	0
+show status like "subquery_cache%";
+Variable_name	Value
+Subquery_cache_hit	78
+Subquery_cache_miss	68
+insert into t2 values (8,NULL);
+call p1();
+a	b	SUBS
+1	2	NULL
+3	4	1
+1	2	NULL
+3	4	1
+3	4	1
+4	5	NULL
+4	5	NULL
+5	6	1
+5	6	1
+4	5	NULL
+9	NULL	NULL
+7	8	NULL
+show status like "subquery_cache%";
+Variable_name	Value
+Subquery_cache_hit	84
+Subquery_cache_miss	74
+call p1();
+a	b	SUBS
+1	2	NULL
+3	4	1
+1	2	NULL
+3	4	1
+3	4	1
+4	5	NULL
+4	5	NULL
+5	6	1
+5	6	1
+4	5	NULL
+9	NULL	NULL
+7	8	NULL
+show status like "subquery_cache%";
+Variable_name	Value
+Subquery_cache_hit	90
+Subquery_cache_miss	80
+drop procedure p1;
+# test of simple exists
+select a, b , exists (select * from t2 where b=d) as SUBS from t1;
+a	b	SUBS
+1	2	0
+3	4	1
+1	2	0
+3	4	1
+3	4	1
+4	5	0
+4	5	0
+5	6	1
+5	6	1
+4	5	0
+9	NULL	0
+7	8	0
+# test of prepared statement exists
+show status like "subquery_cache%";
+Variable_name	Value
+Subquery_cache_hit	96
+Subquery_cache_miss	86
+prepare stmt1 from 'select a, b , exists (select * from t2 where b=d) as SUBS from t1';
+execute stmt1;
+a	b	SUBS
+1	2	0
+3	4	1
+1	2	0
+3	4	1
+3	4	1
+4	5	0
+4	5	0
+5	6	1
+5	6	1
+4	5	0
+9	NULL	0
+7	8	0
+show status like "subquery_cache%";
+Variable_name	Value
+Subquery_cache_hit	102
+Subquery_cache_miss	92
+execute stmt1;
+a	b	SUBS
+1	2	0
+3	4	1
+1	2	0
+3	4	1
+3	4	1
+4	5	0
+4	5	0
+5	6	1
+5	6	1
+4	5	0
+9	NULL	0
+7	8	0
+show status like "subquery_cache%";
+Variable_name	Value
+Subquery_cache_hit	108
+Subquery_cache_miss	98
+deallocate prepare stmt1;
+# test of stored procedure exists
+CREATE PROCEDURE p1() select a, b , exists (select * from t2 where b=d) as SUBS from t1;
+call p1;
+a	b	SUBS
+1	2	0
+3	4	1
+1	2	0
+3	4	1
+3	4	1
+4	5	0
+4	5	0
+5	6	1
+5	6	1
+4	5	0
+9	NULL	0
+7	8	0
+call p1;
+a	b	SUBS
+1	2	0
+3	4	1
+1	2	0
+3	4	1
+3	4	1
+4	5	0
+4	5	0
+5	6	1
+5	6	1
+4	5	0
+9	NULL	0
+7	8	0
+drop procedure p1;
+#clean up
+drop table t1,t2;
+test different types
+#int
+CREATE TABLE t1 ( a int, b int);
+INSERT INTO t1 VALUES(1,1),(2,2),(3,3);
+SELECT a FROM t1 WHERE NOT a IN (SELECT a FROM t1 WHERE b = 2);
+a
+1
+3
+DROP TABLE t1;
+#char
+CREATE TABLE t1 ( a char(1), b char (1));
+INSERT INTO t1 VALUES('1','1'),('2','2'),('3','3');
+SELECT a FROM t1 WHERE NOT a IN (SELECT a FROM t1 WHERE b = '2');
+a
+1
+3
+DROP TABLE t1;
+#decimal
+CREATE TABLE t1 ( a decimal(3,1), b decimal(3,1));
+INSERT INTO t1 VALUES(1,1),(2,2),(3,3);
+SELECT a FROM t1 WHERE NOT a IN (SELECT a FROM t1 WHERE b = 2);
+a
+1.0
+3.0
+DROP TABLE t1;
+#date
+CREATE TABLE t1 ( a date, b date);
+INSERT INTO t1 VALUES('1000-01-01','1000-01-01'),('2000-02-01','2000-02-01'),('3000-03-03','3000-03-03');
+SELECT a FROM t1 WHERE NOT a IN (SELECT a FROM t1 WHERE b = '2000-02-01');
+a
+1000-01-01
+3000-03-03
+DROP TABLE t1;
+#datetime
+CREATE TABLE t1 ( a datetime, b datetime);
+INSERT INTO t1 VALUES('1000-01-01 01:01:01','1000-01-01 01:01:01'),('2000-02-02  02:02:02','2000-02-02 02:02:02'),('3000-03-03 03:03:03','3000-03-03 03:03:03');
+SELECT a FROM t1 WHERE NOT a IN (SELECT a FROM t1 WHERE b = '2000-02-02 02:02:02');
+a
+1000-01-01 01:01:01
+3000-03-03 03:03:03
+DROP TABLE t1;
+#time
+CREATE TABLE t1 ( a time, b time);
+INSERT INTO t1 VALUES('01:01:01','01:01:01'),('02:02:02','02:02:02'),('03:03:03','03:03:03');
+SELECT a FROM t1 WHERE NOT a IN (SELECT a FROM t1 WHERE b = '02:02:02');
+a
+01:01:01
+03:03:03
+DROP TABLE t1;
+#timestamp
+CREATE TABLE t1 ( a timestamp, b timestamp);
+INSERT INTO t1 VALUES('2000-02-02 01:01:01','2000-02-02 01:01:01'),('2000-02-02 02:02:02','2000-02-02 02:02:02'),('2000-02-02 03:03:03','2000-02-02 03:03:03');
+SELECT a FROM t1 WHERE NOT a IN (SELECT a FROM t1 WHERE b = '2000-02-02 02:02:02');
+a
+2000-02-02 01:01:01
+2000-02-02 03:03:03
+DROP TABLE t1;
+#bit
+CREATE TABLE t1 ( a bit(20), b bit(20));
+INSERT INTO t1 VALUES(1,1),(2,2),(3,3);
+SELECT a+0 FROM t1 WHERE NOT a IN (SELECT a FROM t1 WHERE b = 2);
+a+0
+1
+3
+DROP TABLE t1;
+#enum
+CREATE TABLE t1 ( a enum('1','2','3'), b enum('1','2','3'));
+INSERT INTO t1 VALUES('1','1'),('2','2'),('3','3');
+SELECT a FROM t1 WHERE NOT a IN (SELECT a FROM t1 WHERE b = '2');
+a
+1
+3
+DROP TABLE t1;
+#set
+CREATE TABLE t1 ( a set('1','2','3'), b set('1','2','3'));
+INSERT INTO t1 VALUES('1','1'),('2','2'),('3','3');
+SELECT a FROM t1 WHERE NOT a IN (SELECT a FROM t1 WHERE b = '2');
+a
+1
+3
+DROP TABLE t1;
+#blob
+CREATE TABLE t1 ( a blob, b blob);
+INSERT INTO t1 VALUES('1','1'),('2','2'),('3','3');
+SELECT a FROM t1 WHERE NOT a IN (SELECT a FROM t1 WHERE b = '2');
+a
+1
+3
+DROP TABLE t1;
+#geometry
+CREATE TABLE t1 ( a geometry, b geometry);
+INSERT INTO t1 VALUES(POINT(1,1),POINT(1,1)),(POINT(2,2),POINT(2,2)),(POINT(3,3),POINT(3,3));
+SELECT astext(a) FROM t1 WHERE NOT a IN (SELECT a FROM t1 WHERE b = POINT(2,2));
+astext(a)
+POINT(1 1)
+POINT(3 3)
+DROP TABLE t1;
+set optimizer_switch='subquery_cache=default';

=== added file 'mysql-test/t/subquery_cache.test'
--- a/mysql-test/t/subquery_cache.test	1970-01-01 00:00:00 +0000
+++ b/mysql-test/t/subquery_cache.test	2010-05-25 10:45:36 +0000
@@ -0,0 +1,191 @@
+
+set optimizer_switch='subquery_cache=on';
+
+create table t1 (a int, b int);
+insert into t1 values (1,2),(3,4),(1,2),(3,4),(3,4),(4,5),(4,5),(5,6),(5,6),(4,5);
+create table t2 (c int, d int);
+insert into t2 values (2,3),(3,4),(5,6);
+
+--echo #single value subquery test
+select a, (select d from t2 where b=c) + 1 from t1;
+
+show status like "subquery_cache%";
+
+--echo #single value subquery test (PS)
+prepare stmt1 from 'select a, (select d from t2 where b=c) + 1 from t1';
+execute stmt1;
+show status like "subquery_cache%";
+execute stmt1;
+show status like "subquery_cache%";
+deallocate prepare stmt1;
+
+--echo #single value subquery test (SP)
+CREATE PROCEDURE p1() select a, (select d from t2 where b=c) + 1 from t1;
+
+call p1;
+call p1;
+
+drop procedure p1;
+
+--echo #IN subquery test
+flush status;
+
+show status like "subquery_cache%";
+select a, b , b in (select d from t2) as SUBS from t1;
+show status like "subquery_cache%";
+
+insert into t1 values (7,8),(9,NULL);
+select a, b , b in (select d from t2) as SUBS from t1;
+show status like "subquery_cache%";
+
+insert into t2 values (8,NULL);
+select a, b , b in (select d from t2) as SUBS from t1;
+show status like "subquery_cache%";
+
+--echo #IN subquery tesy (PS)
+delete from t1 where a > 6;
+delete from t2 where c > 6;
+
+prepare stmt1 from 'select a, b , b in (select d from t2) as SUBS from t1';
+execute stmt1;
+show status like "subquery_cache%";
+execute stmt1;
+show status like "subquery_cache%";
+
+insert into t1 values (7,8),(9,NULL);
+execute stmt1;
+show status like "subquery_cache%";
+execute stmt1;
+show status like "subquery_cache%";
+
+insert into t2 values (8,NULL);
+execute stmt1;
+show status like "subquery_cache%";
+execute stmt1;
+show status like "subquery_cache%";
+
+deallocate prepare stmt1;
+
+
+--echo #IN subquery tesy (SP)
+delete from t1 where a > 6;
+delete from t2 where c > 6;
+
+CREATE PROCEDURE p1() select a, b , b in (select d from t2) as SUBS from t1;
+
+call p1();
+show status like "subquery_cache%";
+call p1();
+show status like "subquery_cache%";
+
+insert into t1 values (7,8),(9,NULL);
+call p1();
+show status like "subquery_cache%";
+call p1();
+show status like "subquery_cache%";
+
+insert into t2 values (8,NULL);
+call p1();
+show status like "subquery_cache%";
+call p1();
+show status like "subquery_cache%";
+
+drop procedure p1;
+
+
+--echo # test of simple exists
+select a, b , exists (select * from t2 where b=d) as SUBS from t1;
+
+--echo # test of prepared statement exists
+show status like "subquery_cache%";
+prepare stmt1 from 'select a, b , exists (select * from t2 where b=d) as SUBS from t1';
+execute stmt1;
+show status like "subquery_cache%";
+execute stmt1;
+show status like "subquery_cache%";
+deallocate prepare stmt1;
+
+--echo # test of stored procedure exists
+CREATE PROCEDURE p1() select a, b , exists (select * from t2 where b=d) as SUBS from t1;
+call p1;
+call p1;
+drop procedure p1;
+
+--echo #clean up
+drop table t1,t2;
+
+--echo test different types
+--echo #int
+CREATE TABLE t1 ( a int, b int);
+INSERT INTO t1 VALUES(1,1),(2,2),(3,3);
+SELECT a FROM t1 WHERE NOT a IN (SELECT a FROM t1 WHERE b = 2);
+DROP TABLE t1;
+
+--echo #char
+CREATE TABLE t1 ( a char(1), b char (1));
+INSERT INTO t1 VALUES('1','1'),('2','2'),('3','3');
+SELECT a FROM t1 WHERE NOT a IN (SELECT a FROM t1 WHERE b = '2');
+DROP TABLE t1;
+
+--echo #decimal
+CREATE TABLE t1 ( a decimal(3,1), b decimal(3,1));
+INSERT INTO t1 VALUES(1,1),(2,2),(3,3);
+SELECT a FROM t1 WHERE NOT a IN (SELECT a FROM t1 WHERE b = 2);
+DROP TABLE t1;
+
+--echo #date
+CREATE TABLE t1 ( a date, b date);
+INSERT INTO t1 VALUES('1000-01-01','1000-01-01'),('2000-02-01','2000-02-01'),('3000-03-03','3000-03-03');
+SELECT a FROM t1 WHERE NOT a IN (SELECT a FROM t1 WHERE b = '2000-02-01');
+DROP TABLE t1;
+
+--echo #datetime
+CREATE TABLE t1 ( a datetime, b datetime);
+INSERT INTO t1 VALUES('1000-01-01 01:01:01','1000-01-01 01:01:01'),('2000-02-02  02:02:02','2000-02-02 02:02:02'),('3000-03-03 03:03:03','3000-03-03 03:03:03');
+SELECT a FROM t1 WHERE NOT a IN (SELECT a FROM t1 WHERE b = '2000-02-02 02:02:02');
+DROP TABLE t1;
+
+--echo #time
+CREATE TABLE t1 ( a time, b time);
+INSERT INTO t1 VALUES('01:01:01','01:01:01'),('02:02:02','02:02:02'),('03:03:03','03:03:03');
+SELECT a FROM t1 WHERE NOT a IN (SELECT a FROM t1 WHERE b = '02:02:02');
+DROP TABLE t1;
+
+--echo #timestamp
+CREATE TABLE t1 ( a timestamp, b timestamp);
+INSERT INTO t1 VALUES('2000-02-02 01:01:01','2000-02-02 01:01:01'),('2000-02-02 02:02:02','2000-02-02 02:02:02'),('2000-02-02 03:03:03','2000-02-02 03:03:03');
+SELECT a FROM t1 WHERE NOT a IN (SELECT a FROM t1 WHERE b = '2000-02-02 02:02:02');
+DROP TABLE t1;
+
+--echo #bit
+CREATE TABLE t1 ( a bit(20), b bit(20));
+INSERT INTO t1 VALUES(1,1),(2,2),(3,3);
+SELECT a+0 FROM t1 WHERE NOT a IN (SELECT a FROM t1 WHERE b = 2);
+DROP TABLE t1;
+
+--echo #enum
+CREATE TABLE t1 ( a enum('1','2','3'), b enum('1','2','3'));
+INSERT INTO t1 VALUES('1','1'),('2','2'),('3','3');
+SELECT a FROM t1 WHERE NOT a IN (SELECT a FROM t1 WHERE b = '2');
+DROP TABLE t1;
+
+--echo #set
+CREATE TABLE t1 ( a set('1','2','3'), b set('1','2','3'));
+INSERT INTO t1 VALUES('1','1'),('2','2'),('3','3');
+SELECT a FROM t1 WHERE NOT a IN (SELECT a FROM t1 WHERE b = '2');
+DROP TABLE t1;
+
+--echo #blob
+CREATE TABLE t1 ( a blob, b blob);
+INSERT INTO t1 VALUES('1','1'),('2','2'),('3','3');
+SELECT a FROM t1 WHERE NOT a IN (SELECT a FROM t1 WHERE b = '2');
+DROP TABLE t1;
+
+--echo #geometry
+CREATE TABLE t1 ( a geometry, b geometry);
+INSERT INTO t1 VALUES(POINT(1,1),POINT(1,1)),(POINT(2,2),POINT(2,2)),(POINT(3,3),POINT(3,3));
+SELECT astext(a) FROM t1 WHERE NOT a IN (SELECT a FROM t1 WHERE b = POINT(2,2));
+DROP TABLE t1;
+
+
+set optimizer_switch='subquery_cache=default';

=== modified file 'sql/item_sum.cc'
--- a/sql/item_sum.cc	2010-03-20 12:01:47 +0000
+++ b/sql/item_sum.cc	2010-05-25 10:45:36 +0000
@@ -319,6 +319,7 @@
   if (aggr_level >= 0)
   {
     ref_by= ref;
+    thd->lex->current_select->register_dependency_item(aggr_sel, ref);
     /* Add the object to the list of registered objects assigned to aggr_sel */
     if (!aggr_sel->inner_sum_func_list)
       next= this;

=== added file 'sql/sql_subquery_cache.cc'
--- a/sql/sql_subquery_cache.cc	1970-01-01 00:00:00 +0000
+++ b/sql/sql_subquery_cache.cc	2010-05-25 10:45:36 +0000
@@ -0,0 +1,319 @@
+
+#include "mysql_priv.h"
+#include "sql_select.h"
+
+ulonglong subquery_cache_miss, subquery_cache_hit;
+
+/**
+  Creates structures which we need for index look up
+
+  @retval FALSE OK
+  @retval TRUE  Error
+*/
+
+static my_bool createtmp_table_search_structures(THD *thd,
+                                                 TABLE *table,
+                                                 List_iterator_fast<Item> &li,
+                                                 TABLE_REF **ref)
+{
+  /*
+    Create/initialize everything we will need to index lookups into the
+    temptable.
+  */
+  TABLE_REF *tab_ref;
+  KEY       *tmp_key; /* The only index on the temporary table. */
+  Item      *item;
+  uint      tmp_key_parts; /* Number of keyparts in tmp_key. */
+  uint      i;
+
+  DBUG_ENTER("createtmp_table_search_structures");
+
+  tmp_key= table->key_info;
+  tmp_key_parts= tmp_key->key_parts;
+
+  if (!(tab_ref= (TABLE_REF*) thd->alloc(sizeof(TABLE_REF))))
+    DBUG_RETURN(TRUE);
+
+  tab_ref->key= 0; /* The only temp table index. */
+  tab_ref->key_length= tmp_key->key_length;
+  if (!(tab_ref->key_buff=
+        (uchar*) thd->calloc(ALIGN_SIZE(tmp_key->key_length) * 2)) ||
+      !(tab_ref->key_copy=
+        (store_key**) thd->alloc((sizeof(store_key*) *
+                                  (tmp_key_parts + 1)))) ||
+      !(tab_ref->items=
+        (Item**) thd->alloc(sizeof(Item*) * tmp_key_parts)))
+    DBUG_RETURN(TRUE); /* purecov: inspected */
+
+  tab_ref->key_buff2=tab_ref->key_buff+ALIGN_SIZE(tmp_key->key_length);
+  tab_ref->key_err=1;
+  tab_ref->null_rejecting= 1;
+  tab_ref->disable_cache= FALSE;
+  tab_ref->has_record= 0;
+
+  KEY_PART_INFO *cur_key_part= tmp_key->key_part;
+  store_key **ref_key= tab_ref->key_copy;
+  uchar *cur_ref_buff= tab_ref->key_buff;
+
+  for (i= 0; i < tmp_key_parts; i++, cur_key_part++, ref_key++)
+  {
+    item= li++;
+    DBUG_ASSERT(item);
+    tab_ref->items[i]= item;
+    int null_count= test(cur_key_part->field->real_maybe_null());
+    *ref_key= new store_key_item(thd, cur_key_part->field,
+                                 /* TODO:
+                                   the NULL byte is taken into account in
+                                   cur_key_part->store_length, so instead of
+                                   cur_ref_buff + test(maybe_null), we could
+                                   use that information instead.
+                                 */
+                                 cur_ref_buff + null_count,
+                                 null_count ? tab_ref->key_buff : 0,
+                                 cur_key_part->length, tab_ref->items[i]);
+    cur_ref_buff+= cur_key_part->store_length;
+  }
+  *ref_key= NULL; /* End marker. */
+  tab_ref->key_err= 1;
+  tab_ref->key_parts= tmp_key_parts;
+  *ref= tab_ref;
+
+  DBUG_RETURN(FALSE);
+}
+
+
+Subquery_cache_tmptable::Subquery_cache_tmptable(THD *thd,
+                                                 List<Item*> &dependance,
+                                                 Item *value)
+  :cache_table(NULL), table_thd(thd), list(&dependance), val(value),
+   equalities(NULL), inited (0)
+{
+  DBUG_ENTER("Subquery_cache_tmptable::Subquery_cache_tmptable");
+  DBUG_VOID_RETURN;
+};
+
+
+/**
+  Creates equalities expression.
+
+  @retval FALSE OK
+  @retval TRUE  Error
+*/
+
+bool Subquery_cache_tmptable::make_equalities()
+{
+  List<Item> args;
+  List_iterator_fast<Item*> li(*list);
+  Item **ref;
+  Name_resolution_context *cn= NULL;
+  DBUG_ENTER("Subquery_cache_tmptable::make_equalities");
+
+  for (uint i= 1 /* skip result filed */; (ref= li++); i++)
+  {
+    Field *fld= cache_table->field[i];
+    if (fld->type() == MYSQL_TYPE_VARCHAR ||
+        fld->type() == MYSQL_TYPE_TINY_BLOB ||
+        fld->type() == MYSQL_TYPE_MEDIUM_BLOB ||
+        fld->type() == MYSQL_TYPE_LONG_BLOB ||
+        fld->type() == MYSQL_TYPE_BLOB ||
+        fld->type() == MYSQL_TYPE_VAR_STRING ||
+        fld->type() == MYSQL_TYPE_STRING ||
+        fld->type() == MYSQL_TYPE_NEWDECIMAL ||
+        fld->type() == MYSQL_TYPE_DECIMAL)
+    {
+      if (!cn)
+      {
+        // dummy resolution context
+        cn= new Name_resolution_context();
+        cn->init();
+      }
+      args.push_front(new Item_func_eq(new Item_ref(cn, ref, "", "", FALSE),
+                                       new Item_field(fld)));
+    }
+  }
+  if (args.elements == 1)
+    equalities= args.head();
+  else
+    equalities= new Item_cond_and(args);
+
+  DBUG_RETURN(equalities->fix_fields(table_thd, &equalities));
+}
+
+void Subquery_cache_tmptable::init()
+{
+  ulonglong keymap;
+  List_iterator_fast<Item*> li(*list);
+  List_iterator_fast<Item> li_items(items);
+  Item **item;
+  DBUG_ENTER("Subquery_cache_tmptable::init");
+  DBUG_ASSERT(!inited);
+  inited= TRUE;
+
+  if (!(ULONGLONG_MAX >> (list->elements + 1)))
+  {
+    DBUG_PRINT("info", ("Too many dependencies"));
+    DBUG_VOID_RETURN;
+  }
+
+  cache_table= NULL;
+  while ((item= li++))
+  {
+    DBUG_ASSERT(item);
+    DBUG_ASSERT(*item);
+    DBUG_ASSERT((*item)->fixed);
+    items.push_back((*item));
+  }
+
+  cache_table_param.init();
+  /* dependance items and result */
+  cache_table_param.field_count= list->elements + 1;
+  /* postpone table creation to index description */
+  cache_table_param.skip_create_table= 1;
+
+
+  items.push_front(val);
+  if (!(cache_table= create_tmp_table(table_thd, &cache_table_param,
+                                      items, (ORDER*) NULL,
+                                      FALSE, FALSE,
+                                      (table_thd->options |
+                                       TMP_TABLE_ALL_COLUMNS),
+                                      HA_POS_ERROR,
+                                      (char *)"subquery-cache-table")))
+  {
+    DBUG_PRINT("error", ("create_tmp_table failed, caching switched off"));
+    DBUG_VOID_RETURN;
+  }
+
+  if (cache_table->s->blob_fields)
+  {
+    DBUG_PRINT("error", ("we do not need blobs"));
+    goto error;
+  }
+
+  /* makes all bits set for keys */
+  keymap= 1 << (items.elements); /* + 1 - 1 */
+  if (!keymap)
+    keymap= ULONGLONG_MAX;
+  else
+    keymap--;
+  keymap&=~1;
+
+  li_items++;
+  if (cache_table->alloc_keys(1) ||
+      (cache_table->add_tmp_key(keymap, "cache-table-key") < 0) ||
+      createtmp_table_search_structures(table_thd, cache_table, li_items,
+                                        &tab_ref) ||
+      !(tab= create_index_lookup_join_tab(cache_table)))
+  {
+    DBUG_PRINT("error", ("creating index failed"));
+    goto error;
+  }
+  cache_table->s->keys= 1;
+  cache_table->s->uniques= 1;
+
+  if (open_tmp_table(cache_table))
+  {
+    DBUG_PRINT("error", ("Opening (creating) temporary table failed"));
+    goto error;
+  }
+
+  if (!(chached_result= new Item_field(cache_table->field[0])))
+  {
+    DBUG_PRINT("error", ("Creating Item_field failed"));
+    goto error;
+  }
+  if (make_equalities())
+  {
+    DBUG_PRINT("error", ("Creating equalities failed"));
+    goto error;
+  }
+
+  DBUG_VOID_RETURN;
+
+error:
+  /* switch off cache */
+  free_tmp_table(table_thd, cache_table);
+  cache_table= NULL;
+  DBUG_VOID_RETURN;
+}
+
+
+Subquery_cache_tmptable::~Subquery_cache_tmptable()
+{
+  if (cache_table)
+    free_tmp_table(table_thd, cache_table);
+}
+
+
+Subquery_cache::result Subquery_cache_tmptable::check_value(Item **value)
+{
+  int res;
+  DBUG_ENTER("Subquery_cache_tmptable::check_value");
+
+  if (!inited)
+    init();
+
+  if (cache_table)
+  {
+    DBUG_PRINT("info", ("status: %u  has_record %u",
+                        (uint)cache_table->status, (uint)tab_ref->has_record));
+    if ((res= join_read_key2(table_thd, tab, cache_table, tab_ref)) == 1)
+      DBUG_RETURN(ERROR);
+    if (res || (equalities && !equalities->val_int()))
+    {
+      subquery_cache_miss++;
+      DBUG_RETURN(MISS);
+    }
+
+    subquery_cache_hit++;
+    *value= chached_result;
+    DBUG_RETURN(Subquery_cache::HIT);
+  }
+  DBUG_RETURN(Subquery_cache::MISS);
+}
+
+
+my_bool Subquery_cache_tmptable::put_value(Item *value)
+{
+  int error;
+  DBUG_ENTER("Subquery_cache_tmptable::put_value");
+  DBUG_ASSERT(inited);
+
+  if (!cache_table)
+  {
+    DBUG_PRINT("info", ("No table so behave as we successfully put value"));
+    DBUG_RETURN(FALSE);
+  }
+
+  *(items.head_ref())= value;
+  fill_record(table_thd, cache_table->field, items, 1);
+  if (table_thd->is_error())
+    goto err;;
+
+  if ((error= cache_table->file->ha_write_row(cache_table->record[0])))
+  {
+    /* create_myisam_from_heap will generate error if needed */
+    if (cache_table->file->is_fatal_error(error, HA_CHECK_DUP) &&
+        create_internal_tmp_table_from_heap(table_thd, cache_table,
+                                            cache_table_param.start_recinfo,
+                                            &cache_table_param.recinfo,
+                                            error, 1))
+      goto err;
+  }
+  cache_table->status= 0; /* cache_table->record contains an existed record */
+  tab_ref->has_record= TRUE; /* the same as above */
+  DBUG_PRINT("info", ("has_record: TRUE  status: 0"));
+
+  DBUG_RETURN(FALSE);
+
+err:
+  free_tmp_table(table_thd, cache_table);
+  cache_table= NULL;
+  DBUG_RETURN(TRUE);
+}
+
+
+void Subquery_cache_tmptable::cleanup()
+{
+  cache_table->file->ha_delete_all_rows();
+}

=== added file 'sql/sql_subquery_cache.h'
--- a/sql/sql_subquery_cache.h	1970-01-01 00:00:00 +0000
+++ b/sql/sql_subquery_cache.h	2010-05-25 10:45:36 +0000
@@ -0,0 +1,79 @@
+#ifndef _SQL_SUBQUERY_CACHE_H_
+#define _SQL_SUBQUERY_CACHE_H_
+
+/**
+  Interface for subquery cache
+*/
+
+extern ulonglong subquery_cache_miss, subquery_cache_hit;
+
+class Subquery_cache :public Sql_alloc
+{
+public:
+  enum result {ERROR, HIT, MISS};
+
+  Subquery_cache(){};
+  virtual ~Subquery_cache() {};
+  /**
+    Checks presence of the key (taken from cache owner) and if found return
+    it via value parameter
+  */
+  virtual result check_value(Item **value)= 0;
+  /**
+    Puts value into this cache (key should be taken from cache owner)
+  */
+  virtual my_bool put_value(Item *value)= 0;
+  /**
+    Cleans up and reset cache before reusing
+  */
+  virtual void cleanup()= 0;
+};
+
+struct st_table_ref;
+struct st_join_table;
+//class Item_cache;
+class Item_field;
+
+/**
+  Implementation of subquery cache over temporary table
+*/
+
+class Subquery_cache_tmptable :public Subquery_cache
+{
+public:
+  Subquery_cache_tmptable(THD *thd, List<Item*> &dependance, Item *value);
+  virtual ~Subquery_cache_tmptable();
+  virtual result check_value(Item **value);
+  virtual my_bool put_value(Item *value);
+  virtual void cleanup();
+  void init();
+
+private:
+  bool make_equalities();
+
+  /* tmp table parameters */
+  TMP_TABLE_PARAM cache_table_param;
+  /* temporary table to store this cache */
+  TABLE *cache_table;
+  /* Thread handler for the temporary table */
+  THD *table_thd;
+  /* tab_ref for index search */
+  struct st_table_ref *tab_ref;
+  /* cache of subquery value to avoid evaluating it twice */
+  //Item_cache *value_cache;
+  /* JOIN_TAB for index lookup */
+  st_join_table *tab;
+  /* Chached result */
+  Item_field *chached_result;
+  /* List of references to items */
+  List<Item*> *list;
+  /* List of items */
+  List<Item> items;
+  /* Value Item example */
+  Item *val;
+  /* Expression to check after index lookup */
+  Item *equalities;
+  /* set if structures are inited */
+  bool inited;
+};
+#endif