developers
Threads by month
- ----- 2025 -----
- January
- ----- 2024 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2023 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2022 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2021 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2020 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2019 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2018 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2017 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2016 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2015 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2014 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2013 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2012 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2011 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2010 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2009 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- 9 participants
- 6826 discussions
Re: [Maria-developers] [Commits] Rev 2988: Added directories with .dylib files to DYLD_LYBRARY_PATH to allow plugin to use them. in file:///Users/bell/maria/bzr/work-maria-5.3-machandlersocket/
by Kristian Nielsen 13 May '11
by Kristian Nielsen 13 May '11
13 May '11
Oleksandr Byelkin <sanja(a)askmonty.org> writes:
> At file:///Users/bell/maria/bzr/work-maria-5.3-machandlersocket/
>
> ------------------------------------------------------------
> revno: 2988
> revision-id: sanja(a)askmonty.org-20110513135817-kspibqh2830aj5tk
> parent: sanja(a)askmonty.org-20110512150136-5yzagaev1ssohykp
> committer: Oleksandr Byelkin <sanja(a)askmonty.org>
> branch nick: work-maria-5.3-machandlersocket
> timestamp: Fri 2011-05-13 16:58:17 +0300
> message:
> Added directories with .dylib files to DYLD_LYBRARY_PATH to allow plugin to use them.
> === modified file 'mysql-test/mysql-test-run.pl'
> --- a/mysql-test/mysql-test-run.pl 2011-04-19 12:34:40 +0000
> +++ b/mysql-test/mysql-test-run.pl 2011-05-13 13:58:17 +0000
> @@ -2051,6 +2051,16 @@
> push(@ld_library_paths, "$basedir/libmysql/.libs/",
> "$basedir/libmysql_r/.libs/",
> "$basedir/zlib/.libs/");
> + if ($^O eq "darwin")
> + {
> + my %dirs= ();
> + # it is MAC OS and we have to add dynamic libraries paths
> + for (<$bindir/storage/*/.libs/*.dylib>,<$bindir/plugin/*/.libs/*.dylib>,<$bindir/plugin/*/*/.libs/*.dylib>,<$bindir/sql/.libs/*.dylib>)
> + {
> + $dirs{dirname($_)}= 1;
> + }
> + push @ld_library_paths, keys(%dirs);
> + }
> }
> else
> {
>
> === modified file 'plugin/handler_socket/libhsclient/Makefile.am'
> --- a/plugin/handler_socket/libhsclient/Makefile.am 2011-05-12 15:01:36 +0000
> +++ b/plugin/handler_socket/libhsclient/Makefile.am 2011-05-13 13:58:17 +0000
> @@ -8,6 +8,5 @@
> lib_LTLIBRARIES = libhsclient.la
> libhsclient_la_SOURCES = config.cpp escape.cpp fatal.cpp hstcpcli.cpp \
> socket.cpp string_util.cpp
> -libhsclient_la_LDFLAGS = -static
> libhsclient_la_CFLAGS = $(AM_CFLAGS)
> libhsclient_la_CXXFLAGS = $(AM_CXXFLAGS)
Ok to push from me.
- Kristian.
1
0
=== modified file 'mysql-test/r/explain.result'
--- mysql-test/r/explain.result 2011-05-10 15:28:05 +0000
+++ mysql-test/r/explain.result 2011-05-10 20:17:04 +0000
@@ -176,11 +176,15 @@
SET SESSION sql_mode='ONLY_FULL_GROUP_BY';
EXPLAIN EXTENDED SELECT 1 FROM t1
WHERE f1 > ALL( SELECT t.f1 FROM t1,t1 AS t );
-ERROR 42000: Mixing of GROUP columns (MIN(),MAX(),COUNT(),...) with no
GROUP columns is illegal if there is no GROUP BY clause
+id select_type table type possible_keys key key_len
ref rows filtered Extra
+1 PRIMARY NULL NULL NULL NULL NULL NULL NULL
NULL Impossible WHERE noticed after reading const tables
+2 SUBQUERY t1 system NULL NULL NULL NULL 0
0.00 const row not found
+2 SUBQUERY t system NULL NULL NULL NULL 0
0.00 const row not found
+Warnings:
+Note 1003 select 1 AS `1` from `test`.`t1` where 0
SHOW WARNINGS;
Level Code Message
-Error 1140 Mixing of GROUP columns (MIN(),MAX(),COUNT(),...) with
no GROUP columns is illegal if there is no GROUP BY clause
-Note 1003 select 1 AS `1` from `test`.`t1` where <not>(<exists>(...))
+Note 1003 select 1 AS `1` from `test`.`t1` where 0
SET SESSION sql_mode=@old_sql_mode;
DROP TABLE t1;
End of 5.0 tests.
@@ -272,12 +276,12 @@
EXECUTE stmt;
id select_type table type possible_keys key
key_len ref rows Extra
1 PRIMARY t1 system NULL NULL NULL NULL 1
-2 SUBQUERY a system NULL NULL NULL NULL 1
Using filesort
+2 SUBQUERY a system NULL NULL NULL NULL 1
2 SUBQUERY t1 fulltext f1 f1 0 1 Using where
EXECUTE stmt;
id select_type table type possible_keys key
key_len ref rows Extra
1 PRIMARY t1 system NULL NULL NULL NULL 1
-2 SUBQUERY a system NULL NULL NULL NULL 1
Using filesort
+2 SUBQUERY a system NULL NULL NULL NULL 1
2 SUBQUERY t1 fulltext f1 f1 0 1 Using where
DEALLOCATE PREPARE stmt;
PREPARE stmt FROM
@@ -288,12 +292,12 @@
EXECUTE stmt;
id select_type table type possible_keys key
key_len ref rows Extra
1 PRIMARY t1 system NULL NULL NULL NULL 1
-2 SUBQUERY a system NULL NULL NULL NULL 1
Using filesort
+2 SUBQUERY a system NULL NULL NULL NULL 1
2 SUBQUERY t1 fulltext f1 f1 0 1 Using where
EXECUTE stmt;
id select_type table type possible_keys key
key_len ref rows Extra
1 PRIMARY t1 system NULL NULL NULL NULL 1
-2 SUBQUERY a system NULL NULL NULL NULL 1
Using filesort
+2 SUBQUERY a system NULL NULL NULL NULL 1
2 SUBQUERY t1 fulltext f1 f1 0 1 Using where
DEALLOCATE PREPARE stmt;
DROP TABLE t1;
=== modified file 'mysql-test/r/subselect.result'
--- mysql-test/r/subselect.result 2011-05-04 22:35:03 +0000
+++ mysql-test/r/subselect.result 2011-05-10 20:17:04 +0000
@@ -273,7 +273,7 @@
1 PRIMARY t3 ALL NULL NULL NULL NULL 3
100.00 Using where
2 SUBQUERY t2 ALL NULL NULL NULL NULL 3 100.00
Warnings:
-Note 1003 select `test`.`t3`.`a` AS `a` from `test`.`t3` where
<nop>((`test`.`t3`.`a` >= (select min(`test`.`t2`.`b`) from `test`.`t2`)))
+Note 1003 select `test`.`t3`.`a` AS `a` from `test`.`t3` where
<nop>(<in_optimizer>(`test`.`t3`.`a`,(`test`.`t3`.`a` >= (select
min(`test`.`t2`.`b`) from `test`.`t2`))))
select * from t3 where a >= all (select b from t2);
a
7
@@ -1503,7 +1503,7 @@
1 PRIMARY t3 ALL NULL NULL NULL NULL 3
100.00 Using where
2 SUBQUERY t2 system NULL NULL NULL NULL 0
0.00 const row not found
Warnings:
-Note 1003 select `test`.`t3`.`a` AS `a` from `test`.`t3` where
<not>((`test`.`t3`.`a` < (select max(NULL) from `test`.`t2`)))
+Note 1003 select `test`.`t3`.`a` AS `a` from `test`.`t3` where
<not>(<in_optimizer>(`test`.`t3`.`a`,(`test`.`t3`.`a` < (select
max(NULL) from `test`.`t2`))))
select * from t3 where a >= some (select b from t2);
a
explain extended select * from t3 where a >= some (select b from t2);
@@ -1511,7 +1511,7 @@
1 PRIMARY t3 ALL NULL NULL NULL NULL 3
100.00 Using where
2 SUBQUERY t2 system NULL NULL NULL NULL 0
0.00 const row not found
Warnings:
-Note 1003 select `test`.`t3`.`a` AS `a` from `test`.`t3` where
<nop>((`test`.`t3`.`a` >= (select min(NULL) from `test`.`t2`)))
+Note 1003 select `test`.`t3`.`a` AS `a` from `test`.`t3` where
<nop>(<in_optimizer>(`test`.`t3`.`a`,(`test`.`t3`.`a` >= (select
min(NULL) from `test`.`t2`))))
select * from t3 where a >= all (select b from t2 group by 1);
a
6
@@ -1522,7 +1522,7 @@
1 PRIMARY t3 ALL NULL NULL NULL NULL 3
100.00 Using where
2 SUBQUERY t2 system NULL NULL NULL NULL 0
0.00 const row not found
Warnings:
-Note 1003 select `test`.`t3`.`a` AS `a` from `test`.`t3` where
<not>((`test`.`t3`.`a` < <max>(select NULL from `test`.`t2` group by 1)))
+Note 1003 select `test`.`t3`.`a` AS `a` from `test`.`t3` where
<not>(<in_optimizer>(`test`.`t3`.`a`,(`test`.`t3`.`a` < <max>(select
NULL from `test`.`t2` group by 1))))
select * from t3 where a >= some (select b from t2 group by 1);
a
explain extended select * from t3 where a >= some (select b from t2
group by 1);
@@ -1530,7 +1530,7 @@
1 PRIMARY t3 ALL NULL NULL NULL NULL 3
100.00 Using where
2 SUBQUERY t2 system NULL NULL NULL NULL 0
0.00 const row not found
Warnings:
-Note 1003 select `test`.`t3`.`a` AS `a` from `test`.`t3` where
<nop>((`test`.`t3`.`a` >= <min>(select NULL from `test`.`t2` group by 1)))
+Note 1003 select `test`.`t3`.`a` AS `a` from `test`.`t3` where
<nop>(<in_optimizer>(`test`.`t3`.`a`,(`test`.`t3`.`a` >= <min>(select
NULL from `test`.`t2` group by 1))))
select * from t3 where NULL >= any (select b from t2);
a
explain extended select * from t3 where NULL >= any (select b from t2);
@@ -1538,7 +1538,7 @@
1 PRIMARY t3 ALL NULL NULL NULL NULL 3 100.00
2 SUBQUERY t2 system NULL NULL NULL NULL 0
0.00 const row not found
Warnings:
-Note 1003 select `test`.`t3`.`a` AS `a` from `test`.`t3` where
<nop>((NULL >= (select min(NULL) from `test`.`t2`)))
+Note 1003 select `test`.`t3`.`a` AS `a` from `test`.`t3` where
<nop>(<in_optimizer>(NULL,(NULL >= (select min(NULL) from `test`.`t2`))))
select * from t3 where NULL >= any (select b from t2 group by 1);
a
explain extended select * from t3 where NULL >= any (select b from t2
group by 1);
@@ -1546,7 +1546,7 @@
1 PRIMARY t3 ALL NULL NULL NULL NULL 3 100.00
2 SUBQUERY t2 system NULL NULL NULL NULL 0
0.00 const row not found
Warnings:
-Note 1003 select `test`.`t3`.`a` AS `a` from `test`.`t3` where
<nop>((NULL >= <min>(select NULL from `test`.`t2` group by 1)))
+Note 1003 select `test`.`t3`.`a` AS `a` from `test`.`t3` where
<nop>(<in_optimizer>(NULL,(NULL >= <min>(select NULL from `test`.`t2`
group by 1))))
select * from t3 where NULL >= some (select b from t2);
a
explain extended select * from t3 where NULL >= some (select b from t2);
@@ -1554,7 +1554,7 @@
1 PRIMARY t3 ALL NULL NULL NULL NULL 3 100.00
2 SUBQUERY t2 system NULL NULL NULL NULL 0
0.00 const row not found
Warnings:
-Note 1003 select `test`.`t3`.`a` AS `a` from `test`.`t3` where
<nop>((NULL >= (select min(NULL) from `test`.`t2`)))
+Note 1003 select `test`.`t3`.`a` AS `a` from `test`.`t3` where
<nop>(<in_optimizer>(NULL,(NULL >= (select min(NULL) from `test`.`t2`))))
select * from t3 where NULL >= some (select b from t2 group by 1);
a
explain extended select * from t3 where NULL >= some (select b from t2
group by 1);
@@ -1562,7 +1562,7 @@
1 PRIMARY t3 ALL NULL NULL NULL NULL 3 100.00
2 SUBQUERY t2 system NULL NULL NULL NULL 0
0.00 const row not found
Warnings:
-Note 1003 select `test`.`t3`.`a` AS `a` from `test`.`t3` where
<nop>((NULL >= <min>(select NULL from `test`.`t2` group by 1)))
+Note 1003 select `test`.`t3`.`a` AS `a` from `test`.`t3` where
<nop>(<in_optimizer>(NULL,(NULL >= <min>(select NULL from `test`.`t2`
group by 1))))
insert into t2 values (2,2), (2,1), (3,3), (3,1);
select * from t3 where a > all (select max(b) from t2 group by a);
a
@@ -1573,7 +1573,7 @@
1 PRIMARY t3 ALL NULL NULL NULL NULL 3
100.00 Using where
2 SUBQUERY t2 ALL NULL NULL NULL NULL 4
100.00 Using temporary
Warnings:
-Note 1003 select `test`.`t3`.`a` AS `a` from `test`.`t3` where
<not>((`test`.`t3`.`a` <= <max>(select max(`test`.`t2`.`b`) from
`test`.`t2` group by `test`.`t2`.`a`)))
+Note 1003 select `test`.`t3`.`a` AS `a` from `test`.`t3` where
<not>(<in_optimizer>(`test`.`t3`.`a`,(`test`.`t3`.`a` <= <max>(select
max(`test`.`t2`.`b`) from `test`.`t2` group by `test`.`t2`.`a`))))
drop table t2, t3;
CREATE TABLE `t1` ( `id` mediumint(9) NOT NULL auto_increment,
`taskid` bigint(20) NOT NULL default '0', `dbid` int(11) NOT NULL
default '0', `create_date` datetime NOT NULL default '0000-00-00
00:00:00', `last_update` datetime NOT NULL default '0000-00-00
00:00:00', PRIMARY KEY (`id`)) ENGINE=MyISAM CHARSET=latin1
AUTO_INCREMENT=3 ;
INSERT INTO `t1` (`id`, `taskid`, `dbid`, `create_date`,`last_update`)
VALUES (1, 1, 15, '2003-09-29 10:31:36', '2003-09-29 10:31:36'), (2, 1,
21, now(), now());
@@ -1624,7 +1624,7 @@
3 UNION t1 system NULL NULL NULL NULL 1 100.00
NULL UNION RESULT <union2,3> ALL NULL NULL NULL
NULL NULL NULL
Warnings:
-Note 1003 select 'e' AS `s1` from `test`.`t1` where <nop>(('f' >
<min>(select 'e' from `test`.`t1` union select 'e' from `test`.`t1`)))
+Note 1003 select 'e' AS `s1` from `test`.`t1` where
<nop>(<in_optimizer>('f',('f' > <min>(select 'e' from `test`.`t1` union
select 'e' from `test`.`t1`))))
drop table t1;
CREATE TABLE t1 (number char(11) NOT NULL default '') ENGINE=MyISAM
CHARSET=latin1;
INSERT INTO t1 VALUES
('69294728265'),('18621828126'),('89356874041'),('95895001874');
=== modified file 'mysql-test/r/subselect_no_mat.result'
--- mysql-test/r/subselect_no_mat.result 2011-05-04 22:35:03 +0000
+++ mysql-test/r/subselect_no_mat.result 2011-05-10 20:17:04 +0000
@@ -277,7 +277,7 @@
1 PRIMARY t3 ALL NULL NULL NULL NULL 3
100.00 Using where
2 SUBQUERY t2 ALL NULL NULL NULL NULL 3 100.00
Warnings:
-Note 1003 select `test`.`t3`.`a` AS `a` from `test`.`t3` where
<nop>((`test`.`t3`.`a` >= (select min(`test`.`t2`.`b`) from `test`.`t2`)))
+Note 1003 select `test`.`t3`.`a` AS `a` from `test`.`t3` where
<nop>(<in_optimizer>(`test`.`t3`.`a`,(`test`.`t3`.`a` >= (select
min(`test`.`t2`.`b`) from `test`.`t2`))))
select * from t3 where a >= all (select b from t2);
a
7
@@ -1507,7 +1507,7 @@
1 PRIMARY t3 ALL NULL NULL NULL NULL 3
100.00 Using where
2 SUBQUERY t2 system NULL NULL NULL NULL 0
0.00 const row not found
Warnings:
-Note 1003 select `test`.`t3`.`a` AS `a` from `test`.`t3` where
<not>((`test`.`t3`.`a` < (select max(NULL) from `test`.`t2`)))
+Note 1003 select `test`.`t3`.`a` AS `a` from `test`.`t3` where
<not>(<in_optimizer>(`test`.`t3`.`a`,(`test`.`t3`.`a` < (select
max(NULL) from `test`.`t2`))))
select * from t3 where a >= some (select b from t2);
a
explain extended select * from t3 where a >= some (select b from t2);
@@ -1515,7 +1515,7 @@
1 PRIMARY t3 ALL NULL NULL NULL NULL 3
100.00 Using where
2 SUBQUERY t2 system NULL NULL NULL NULL 0
0.00 const row not found
Warnings:
-Note 1003 select `test`.`t3`.`a` AS `a` from `test`.`t3` where
<nop>((`test`.`t3`.`a` >= (select min(NULL) from `test`.`t2`)))
+Note 1003 select `test`.`t3`.`a` AS `a` from `test`.`t3` where
<nop>(<in_optimizer>(`test`.`t3`.`a`,(`test`.`t3`.`a` >= (select
min(NULL) from `test`.`t2`))))
select * from t3 where a >= all (select b from t2 group by 1);
a
6
@@ -1526,7 +1526,7 @@
1 PRIMARY t3 ALL NULL NULL NULL NULL 3
100.00 Using where
2 SUBQUERY t2 system NULL NULL NULL NULL 0
0.00 const row not found
Warnings:
-Note 1003 select `test`.`t3`.`a` AS `a` from `test`.`t3` where
<not>((`test`.`t3`.`a` < <max>(select NULL from `test`.`t2` group by 1)))
+Note 1003 select `test`.`t3`.`a` AS `a` from `test`.`t3` where
<not>(<in_optimizer>(`test`.`t3`.`a`,(`test`.`t3`.`a` < <max>(select
NULL from `test`.`t2` group by 1))))
select * from t3 where a >= some (select b from t2 group by 1);
a
explain extended select * from t3 where a >= some (select b from t2
group by 1);
@@ -1534,7 +1534,7 @@
1 PRIMARY t3 ALL NULL NULL NULL NULL 3
100.00 Using where
2 SUBQUERY t2 system NULL NULL NULL NULL 0
0.00 const row not found
Warnings:
-Note 1003 select `test`.`t3`.`a` AS `a` from `test`.`t3` where
<nop>((`test`.`t3`.`a` >= <min>(select NULL from `test`.`t2` group by 1)))
+Note 1003 select `test`.`t3`.`a` AS `a` from `test`.`t3` where
<nop>(<in_optimizer>(`test`.`t3`.`a`,(`test`.`t3`.`a` >= <min>(select
NULL from `test`.`t2` group by 1))))
select * from t3 where NULL >= any (select b from t2);
a
explain extended select * from t3 where NULL >= any (select b from t2);
@@ -1542,7 +1542,7 @@
1 PRIMARY t3 ALL NULL NULL NULL NULL 3 100.00
2 SUBQUERY t2 system NULL NULL NULL NULL 0
0.00 const row not found
Warnings:
-Note 1003 select `test`.`t3`.`a` AS `a` from `test`.`t3` where
<nop>((NULL >= (select min(NULL) from `test`.`t2`)))
+Note 1003 select `test`.`t3`.`a` AS `a` from `test`.`t3` where
<nop>(<in_optimizer>(NULL,(NULL >= (select min(NULL) from `test`.`t2`))))
select * from t3 where NULL >= any (select b from t2 group by 1);
a
explain extended select * from t3 where NULL >= any (select b from t2
group by 1);
@@ -1550,7 +1550,7 @@
1 PRIMARY t3 ALL NULL NULL NULL NULL 3 100.00
2 SUBQUERY t2 system NULL NULL NULL NULL 0
0.00 const row not found
Warnings:
-Note 1003 select `test`.`t3`.`a` AS `a` from `test`.`t3` where
<nop>((NULL >= <min>(select NULL from `test`.`t2` group by 1)))
+Note 1003 select `test`.`t3`.`a` AS `a` from `test`.`t3` where
<nop>(<in_optimizer>(NULL,(NULL >= <min>(select NULL from `test`.`t2`
group by 1))))
select * from t3 where NULL >= some (select b from t2);
a
explain extended select * from t3 where NULL >= some (select b from t2);
@@ -1558,7 +1558,7 @@
1 PRIMARY t3 ALL NULL NULL NULL NULL 3 100.00
2 SUBQUERY t2 system NULL NULL NULL NULL 0
0.00 const row not found
Warnings:
-Note 1003 select `test`.`t3`.`a` AS `a` from `test`.`t3` where
<nop>((NULL >= (select min(NULL) from `test`.`t2`)))
+Note 1003 select `test`.`t3`.`a` AS `a` from `test`.`t3` where
<nop>(<in_optimizer>(NULL,(NULL >= (select min(NULL) from `test`.`t2`))))
select * from t3 where NULL >= some (select b from t2 group by 1);
a
explain extended select * from t3 where NULL >= some (select b from t2
group by 1);
@@ -1566,7 +1566,7 @@
1 PRIMARY t3 ALL NULL NULL NULL NULL 3 100.00
2 SUBQUERY t2 system NULL NULL NULL NULL 0
0.00 const row not found
Warnings:
-Note 1003 select `test`.`t3`.`a` AS `a` from `test`.`t3` where
<nop>((NULL >= <min>(select NULL from `test`.`t2` group by 1)))
+Note 1003 select `test`.`t3`.`a` AS `a` from `test`.`t3` where
<nop>(<in_optimizer>(NULL,(NULL >= <min>(select NULL from `test`.`t2`
group by 1))))
insert into t2 values (2,2), (2,1), (3,3), (3,1);
select * from t3 where a > all (select max(b) from t2 group by a);
a
@@ -1577,7 +1577,7 @@
1 PRIMARY t3 ALL NULL NULL NULL NULL 3
100.00 Using where
2 SUBQUERY t2 ALL NULL NULL NULL NULL 4
100.00 Using temporary
Warnings:
-Note 1003 select `test`.`t3`.`a` AS `a` from `test`.`t3` where
<not>((`test`.`t3`.`a` <= <max>(select max(`test`.`t2`.`b`) from
`test`.`t2` group by `test`.`t2`.`a`)))
+Note 1003 select `test`.`t3`.`a` AS `a` from `test`.`t3` where
<not>(<in_optimizer>(`test`.`t3`.`a`,(`test`.`t3`.`a` <= <max>(select
max(`test`.`t2`.`b`) from `test`.`t2` group by `test`.`t2`.`a`))))
drop table t2, t3;
CREATE TABLE `t1` ( `id` mediumint(9) NOT NULL auto_increment,
`taskid` bigint(20) NOT NULL default '0', `dbid` int(11) NOT NULL
default '0', `create_date` datetime NOT NULL default '0000-00-00
00:00:00', `last_update` datetime NOT NULL default '0000-00-00
00:00:00', PRIMARY KEY (`id`)) ENGINE=MyISAM CHARSET=latin1
AUTO_INCREMENT=3 ;
INSERT INTO `t1` (`id`, `taskid`, `dbid`, `create_date`,`last_update`)
VALUES (1, 1, 15, '2003-09-29 10:31:36', '2003-09-29 10:31:36'), (2, 1,
21, now(), now());
@@ -1628,7 +1628,7 @@
3 UNION t1 system NULL NULL NULL NULL 1 100.00
NULL UNION RESULT <union2,3> ALL NULL NULL NULL
NULL NULL NULL
Warnings:
-Note 1003 select 'e' AS `s1` from `test`.`t1` where <nop>(('f' >
<min>(select 'e' from `test`.`t1` union select 'e' from `test`.`t1`)))
+Note 1003 select 'e' AS `s1` from `test`.`t1` where
<nop>(<in_optimizer>('f',('f' > <min>(select 'e' from `test`.`t1` union
select 'e' from `test`.`t1`))))
drop table t1;
CREATE TABLE t1 (number char(11) NOT NULL default '') ENGINE=MyISAM
CHARSET=latin1;
INSERT INTO t1 VALUES
('69294728265'),('18621828126'),('89356874041'),('95895001874');
=== modified file 'mysql-test/r/subselect_no_opts.result'
--- mysql-test/r/subselect_no_opts.result 2011-05-04 22:35:03 +0000
+++ mysql-test/r/subselect_no_opts.result 2011-05-10 20:17:04 +0000
@@ -274,7 +274,7 @@
1 PRIMARY t3 ALL NULL NULL NULL NULL 3
100.00 Using where
2 SUBQUERY t2 ALL NULL NULL NULL NULL 3 100.00
Warnings:
-Note 1003 select `test`.`t3`.`a` AS `a` from `test`.`t3` where
<nop>((`test`.`t3`.`a` >= (select min(`test`.`t2`.`b`) from `test`.`t2`)))
+Note 1003 select `test`.`t3`.`a` AS `a` from `test`.`t3` where
<nop>(<in_optimizer>(`test`.`t3`.`a`,(`test`.`t3`.`a` >= (select
min(`test`.`t2`.`b`) from `test`.`t2`))))
select * from t3 where a >= all (select b from t2);
a
7
@@ -1504,7 +1504,7 @@
1 PRIMARY t3 ALL NULL NULL NULL NULL 3
100.00 Using where
2 SUBQUERY t2 system NULL NULL NULL NULL 0
0.00 const row not found
Warnings:
-Note 1003 select `test`.`t3`.`a` AS `a` from `test`.`t3` where
<not>((`test`.`t3`.`a` < (select max(NULL) from `test`.`t2`)))
+Note 1003 select `test`.`t3`.`a` AS `a` from `test`.`t3` where
<not>(<in_optimizer>(`test`.`t3`.`a`,(`test`.`t3`.`a` < (select
max(NULL) from `test`.`t2`))))
select * from t3 where a >= some (select b from t2);
a
explain extended select * from t3 where a >= some (select b from t2);
@@ -1512,7 +1512,7 @@
1 PRIMARY t3 ALL NULL NULL NULL NULL 3
100.00 Using where
2 SUBQUERY t2 system NULL NULL NULL NULL 0
0.00 const row not found
Warnings:
-Note 1003 select `test`.`t3`.`a` AS `a` from `test`.`t3` where
<nop>((`test`.`t3`.`a` >= (select min(NULL) from `test`.`t2`)))
+Note 1003 select `test`.`t3`.`a` AS `a` from `test`.`t3` where
<nop>(<in_optimizer>(`test`.`t3`.`a`,(`test`.`t3`.`a` >= (select
min(NULL) from `test`.`t2`))))
select * from t3 where a >= all (select b from t2 group by 1);
a
6
@@ -1523,7 +1523,7 @@
1 PRIMARY t3 ALL NULL NULL NULL NULL 3
100.00 Using where
2 SUBQUERY t2 system NULL NULL NULL NULL 0
0.00 const row not found
Warnings:
-Note 1003 select `test`.`t3`.`a` AS `a` from `test`.`t3` where
<not>((`test`.`t3`.`a` < <max>(select NULL from `test`.`t2` group by 1)))
+Note 1003 select `test`.`t3`.`a` AS `a` from `test`.`t3` where
<not>(<in_optimizer>(`test`.`t3`.`a`,(`test`.`t3`.`a` < <max>(select
NULL from `test`.`t2` group by 1))))
select * from t3 where a >= some (select b from t2 group by 1);
a
explain extended select * from t3 where a >= some (select b from t2
group by 1);
@@ -1531,7 +1531,7 @@
1 PRIMARY t3 ALL NULL NULL NULL NULL 3
100.00 Using where
2 SUBQUERY t2 system NULL NULL NULL NULL 0
0.00 const row not found
Warnings:
-Note 1003 select `test`.`t3`.`a` AS `a` from `test`.`t3` where
<nop>((`test`.`t3`.`a` >= <min>(select NULL from `test`.`t2` group by 1)))
+Note 1003 select `test`.`t3`.`a` AS `a` from `test`.`t3` where
<nop>(<in_optimizer>(`test`.`t3`.`a`,(`test`.`t3`.`a` >= <min>(select
NULL from `test`.`t2` group by 1))))
select * from t3 where NULL >= any (select b from t2);
a
explain extended select * from t3 where NULL >= any (select b from t2);
@@ -1539,7 +1539,7 @@
1 PRIMARY t3 ALL NULL NULL NULL NULL 3 100.00
2 SUBQUERY t2 system NULL NULL NULL NULL 0
0.00 const row not found
Warnings:
-Note 1003 select `test`.`t3`.`a` AS `a` from `test`.`t3` where
<nop>((NULL >= (select min(NULL) from `test`.`t2`)))
+Note 1003 select `test`.`t3`.`a` AS `a` from `test`.`t3` where
<nop>(<in_optimizer>(NULL,(NULL >= (select min(NULL) from `test`.`t2`))))
select * from t3 where NULL >= any (select b from t2 group by 1);
a
explain extended select * from t3 where NULL >= any (select b from t2
group by 1);
@@ -1547,7 +1547,7 @@
1 PRIMARY t3 ALL NULL NULL NULL NULL 3 100.00
2 SUBQUERY t2 system NULL NULL NULL NULL 0
0.00 const row not found
Warnings:
-Note 1003 select `test`.`t3`.`a` AS `a` from `test`.`t3` where
<nop>((NULL >= <min>(select NULL from `test`.`t2` group by 1)))
+Note 1003 select `test`.`t3`.`a` AS `a` from `test`.`t3` where
<nop>(<in_optimizer>(NULL,(NULL >= <min>(select NULL from `test`.`t2`
group by 1))))
select * from t3 where NULL >= some (select b from t2);
a
explain extended select * from t3 where NULL >= some (select b from t2);
@@ -1555,7 +1555,7 @@
1 PRIMARY t3 ALL NULL NULL NULL NULL 3 100.00
2 SUBQUERY t2 system NULL NULL NULL NULL 0
0.00 const row not found
Warnings:
-Note 1003 select `test`.`t3`.`a` AS `a` from `test`.`t3` where
<nop>((NULL >= (select min(NULL) from `test`.`t2`)))
+Note 1003 select `test`.`t3`.`a` AS `a` from `test`.`t3` where
<nop>(<in_optimizer>(NULL,(NULL >= (select min(NULL) from `test`.`t2`))))
select * from t3 where NULL >= some (select b from t2 group by 1);
a
explain extended select * from t3 where NULL >= some (select b from t2
group by 1);
@@ -1563,7 +1563,7 @@
1 PRIMARY t3 ALL NULL NULL NULL NULL 3 100.00
2 SUBQUERY t2 system NULL NULL NULL NULL 0
0.00 const row not found
Warnings:
-Note 1003 select `test`.`t3`.`a` AS `a` from `test`.`t3` where
<nop>((NULL >= <min>(select NULL from `test`.`t2` group by 1)))
+Note 1003 select `test`.`t3`.`a` AS `a` from `test`.`t3` where
<nop>(<in_optimizer>(NULL,(NULL >= <min>(select NULL from `test`.`t2`
group by 1))))
insert into t2 values (2,2), (2,1), (3,3), (3,1);
select * from t3 where a > all (select max(b) from t2 group by a);
a
@@ -1574,7 +1574,7 @@
1 PRIMARY t3 ALL NULL NULL NULL NULL 3
100.00 Using where
2 SUBQUERY t2 ALL NULL NULL NULL NULL 4
100.00 Using temporary
Warnings:
-Note 1003 select `test`.`t3`.`a` AS `a` from `test`.`t3` where
<not>((`test`.`t3`.`a` <= <max>(select max(`test`.`t2`.`b`) from
`test`.`t2` group by `test`.`t2`.`a`)))
+Note 1003 select `test`.`t3`.`a` AS `a` from `test`.`t3` where
<not>(<in_optimizer>(`test`.`t3`.`a`,(`test`.`t3`.`a` <= <max>(select
max(`test`.`t2`.`b`) from `test`.`t2` group by `test`.`t2`.`a`))))
drop table t2, t3;
CREATE TABLE `t1` ( `id` mediumint(9) NOT NULL auto_increment,
`taskid` bigint(20) NOT NULL default '0', `dbid` int(11) NOT NULL
default '0', `create_date` datetime NOT NULL default '0000-00-00
00:00:00', `last_update` datetime NOT NULL default '0000-00-00
00:00:00', PRIMARY KEY (`id`)) ENGINE=MyISAM CHARSET=latin1
AUTO_INCREMENT=3 ;
INSERT INTO `t1` (`id`, `taskid`, `dbid`, `create_date`,`last_update`)
VALUES (1, 1, 15, '2003-09-29 10:31:36', '2003-09-29 10:31:36'), (2, 1,
21, now(), now());
@@ -1625,7 +1625,7 @@
3 UNION t1 system NULL NULL NULL NULL 1 100.00
NULL UNION RESULT <union2,3> ALL NULL NULL NULL
NULL NULL NULL
Warnings:
-Note 1003 select 'e' AS `s1` from `test`.`t1` where <nop>(('f' >
<min>(select 'e' from `test`.`t1` union select 'e' from `test`.`t1`)))
+Note 1003 select 'e' AS `s1` from `test`.`t1` where
<nop>(<in_optimizer>('f',('f' > <min>(select 'e' from `test`.`t1` union
select 'e' from `test`.`t1`))))
drop table t1;
CREATE TABLE t1 (number char(11) NOT NULL default '') ENGINE=MyISAM
CHARSET=latin1;
INSERT INTO t1 VALUES
('69294728265'),('18621828126'),('89356874041'),('95895001874');
=== modified file 'mysql-test/r/subselect_no_semijoin.result'
--- mysql-test/r/subselect_no_semijoin.result 2011-05-04 22:35:03 +0000
+++ mysql-test/r/subselect_no_semijoin.result 2011-05-10 20:17:04 +0000
@@ -274,7 +274,7 @@
1 PRIMARY t3 ALL NULL NULL NULL NULL 3
100.00 Using where
2 SUBQUERY t2 ALL NULL NULL NULL NULL 3 100.00
Warnings:
-Note 1003 select `test`.`t3`.`a` AS `a` from `test`.`t3` where
<nop>((`test`.`t3`.`a` >= (select min(`test`.`t2`.`b`) from `test`.`t2`)))
+Note 1003 select `test`.`t3`.`a` AS `a` from `test`.`t3` where
<nop>(<in_optimizer>(`test`.`t3`.`a`,(`test`.`t3`.`a` >= (select
min(`test`.`t2`.`b`) from `test`.`t2`))))
select * from t3 where a >= all (select b from t2);
a
7
@@ -1504,7 +1504,7 @@
1 PRIMARY t3 ALL NULL NULL NULL NULL 3
100.00 Using where
2 SUBQUERY t2 system NULL NULL NULL NULL 0
0.00 const row not found
Warnings:
-Note 1003 select `test`.`t3`.`a` AS `a` from `test`.`t3` where
<not>((`test`.`t3`.`a` < (select max(NULL) from `test`.`t2`)))
+Note 1003 select `test`.`t3`.`a` AS `a` from `test`.`t3` where
<not>(<in_optimizer>(`test`.`t3`.`a`,(`test`.`t3`.`a` < (select
max(NULL) from `test`.`t2`))))
select * from t3 where a >= some (select b from t2);
a
explain extended select * from t3 where a >= some (select b from t2);
@@ -1512,7 +1512,7 @@
1 PRIMARY t3 ALL NULL NULL NULL NULL 3
100.00 Using where
2 SUBQUERY t2 system NULL NULL NULL NULL 0
0.00 const row not found
Warnings:
-Note 1003 select `test`.`t3`.`a` AS `a` from `test`.`t3` where
<nop>((`test`.`t3`.`a` >= (select min(NULL) from `test`.`t2`)))
+Note 1003 select `test`.`t3`.`a` AS `a` from `test`.`t3` where
<nop>(<in_optimizer>(`test`.`t3`.`a`,(`test`.`t3`.`a` >= (select
min(NULL) from `test`.`t2`))))
select * from t3 where a >= all (select b from t2 group by 1);
a
6
@@ -1523,7 +1523,7 @@
1 PRIMARY t3 ALL NULL NULL NULL NULL 3
100.00 Using where
2 SUBQUERY t2 system NULL NULL NULL NULL 0
0.00 const row not found
Warnings:
-Note 1003 select `test`.`t3`.`a` AS `a` from `test`.`t3` where
<not>((`test`.`t3`.`a` < <max>(select NULL from `test`.`t2` group by 1)))
+Note 1003 select `test`.`t3`.`a` AS `a` from `test`.`t3` where
<not>(<in_optimizer>(`test`.`t3`.`a`,(`test`.`t3`.`a` < <max>(select
NULL from `test`.`t2` group by 1))))
select * from t3 where a >= some (select b from t2 group by 1);
a
explain extended select * from t3 where a >= some (select b from t2
group by 1);
@@ -1531,7 +1531,7 @@
1 PRIMARY t3 ALL NULL NULL NULL NULL 3
100.00 Using where
2 SUBQUERY t2 system NULL NULL NULL NULL 0
0.00 const row not found
Warnings:
-Note 1003 select `test`.`t3`.`a` AS `a` from `test`.`t3` where
<nop>((`test`.`t3`.`a` >= <min>(select NULL from `test`.`t2` group by 1)))
+Note 1003 select `test`.`t3`.`a` AS `a` from `test`.`t3` where
<nop>(<in_optimizer>(`test`.`t3`.`a`,(`test`.`t3`.`a` >= <min>(select
NULL from `test`.`t2` group by 1))))
select * from t3 where NULL >= any (select b from t2);
a
explain extended select * from t3 where NULL >= any (select b from t2);
@@ -1539,7 +1539,7 @@
1 PRIMARY t3 ALL NULL NULL NULL NULL 3 100.00
2 SUBQUERY t2 system NULL NULL NULL NULL 0
0.00 const row not found
Warnings:
-Note 1003 select `test`.`t3`.`a` AS `a` from `test`.`t3` where
<nop>((NULL >= (select min(NULL) from `test`.`t2`)))
+Note 1003 select `test`.`t3`.`a` AS `a` from `test`.`t3` where
<nop>(<in_optimizer>(NULL,(NULL >= (select min(NULL) from `test`.`t2`))))
select * from t3 where NULL >= any (select b from t2 group by 1);
a
explain extended select * from t3 where NULL >= any (select b from t2
group by 1);
@@ -1547,7 +1547,7 @@
1 PRIMARY t3 ALL NULL NULL NULL NULL 3 100.00
2 SUBQUERY t2 system NULL NULL NULL NULL 0
0.00 const row not found
Warnings:
-Note 1003 select `test`.`t3`.`a` AS `a` from `test`.`t3` where
<nop>((NULL >= <min>(select NULL from `test`.`t2` group by 1)))
+Note 1003 select `test`.`t3`.`a` AS `a` from `test`.`t3` where
<nop>(<in_optimizer>(NULL,(NULL >= <min>(select NULL from `test`.`t2`
group by 1))))
select * from t3 where NULL >= some (select b from t2);
a
explain extended select * from t3 where NULL >= some (select b from t2);
@@ -1555,7 +1555,7 @@
1 PRIMARY t3 ALL NULL NULL NULL NULL 3 100.00
2 SUBQUERY t2 system NULL NULL NULL NULL 0
0.00 const row not found
Warnings:
-Note 1003 select `test`.`t3`.`a` AS `a` from `test`.`t3` where
<nop>((NULL >= (select min(NULL) from `test`.`t2`)))
+Note 1003 select `test`.`t3`.`a` AS `a` from `test`.`t3` where
<nop>(<in_optimizer>(NULL,(NULL >= (select min(NULL) from `test`.`t2`))))
select * from t3 where NULL >= some (select b from t2 group by 1);
a
explain extended select * from t3 where NULL >= some (select b from t2
group by 1);
@@ -1563,7 +1563,7 @@
1 PRIMARY t3 ALL NULL NULL NULL NULL 3 100.00
2 SUBQUERY t2 system NULL NULL NULL NULL 0
0.00 const row not found
Warnings:
-Note 1003 select `test`.`t3`.`a` AS `a` from `test`.`t3` where
<nop>((NULL >= <min>(select NULL from `test`.`t2` group by 1)))
+Note 1003 select `test`.`t3`.`a` AS `a` from `test`.`t3` where
<nop>(<in_optimizer>(NULL,(NULL >= <min>(select NULL from `test`.`t2`
group by 1))))
insert into t2 values (2,2), (2,1), (3,3), (3,1);
select * from t3 where a > all (select max(b) from t2 group by a);
a
@@ -1574,7 +1574,7 @@
1 PRIMARY t3 ALL NULL NULL NULL NULL 3
100.00 Using where
2 SUBQUERY t2 ALL NULL NULL NULL NULL 4
100.00 Using temporary
Warnings:
-Note 1003 select `test`.`t3`.`a` AS `a` from `test`.`t3` where
<not>((`test`.`t3`.`a` <= <max>(select max(`test`.`t2`.`b`) from
`test`.`t2` group by `test`.`t2`.`a`)))
+Note 1003 select `test`.`t3`.`a` AS `a` from `test`.`t3` where
<not>(<in_optimizer>(`test`.`t3`.`a`,(`test`.`t3`.`a` <= <max>(select
max(`test`.`t2`.`b`) from `test`.`t2` group by `test`.`t2`.`a`))))
drop table t2, t3;
CREATE TABLE `t1` ( `id` mediumint(9) NOT NULL auto_increment,
`taskid` bigint(20) NOT NULL default '0', `dbid` int(11) NOT NULL
default '0', `create_date` datetime NOT NULL default '0000-00-00
00:00:00', `last_update` datetime NOT NULL default '0000-00-00
00:00:00', PRIMARY KEY (`id`)) ENGINE=MyISAM CHARSET=latin1
AUTO_INCREMENT=3 ;
INSERT INTO `t1` (`id`, `taskid`, `dbid`, `create_date`,`last_update`)
VALUES (1, 1, 15, '2003-09-29 10:31:36', '2003-09-29 10:31:36'), (2, 1,
21, now(), now());
@@ -1625,7 +1625,7 @@
3 UNION t1 system NULL NULL NULL NULL 1 100.00
NULL UNION RESULT <union2,3> ALL NULL NULL NULL
NULL NULL NULL
Warnings:
-Note 1003 select 'e' AS `s1` from `test`.`t1` where <nop>(('f' >
<min>(select 'e' from `test`.`t1` union select 'e' from `test`.`t1`)))
+Note 1003 select 'e' AS `s1` from `test`.`t1` where
<nop>(<in_optimizer>('f',('f' > <min>(select 'e' from `test`.`t1` union
select 'e' from `test`.`t1`))))
drop table t1;
CREATE TABLE t1 (number char(11) NOT NULL default '') ENGINE=MyISAM
CHARSET=latin1;
INSERT INTO t1 VALUES
('69294728265'),('18621828126'),('89356874041'),('95895001874');
=== modified file 'mysql-test/suite/pbxt/r/subselect.result'
--- mysql-test/suite/pbxt/r/subselect.result 2011-04-20 19:55:29 +0000
+++ mysql-test/suite/pbxt/r/subselect.result 2011-05-10 20:17:04 +0000
@@ -270,7 +270,7 @@
1 PRIMARY t3 ALL NULL NULL NULL NULL 3
100.00 Using where
2 SUBQUERY t2 ALL NULL NULL NULL NULL 3 100.00
Warnings:
-Note 1003 select `test`.`t3`.`a` AS `a` from `test`.`t3` where
<nop>((`test`.`t3`.`a` >= (select min(`test`.`t2`.`b`) from `test`.`t2`)))
+Note 1003 select `test`.`t3`.`a` AS `a` from `test`.`t3` where
<nop>(<in_optimizer>(`test`.`t3`.`a`,(`test`.`t3`.`a` >= (select
min(`test`.`t2`.`b`) from `test`.`t2`))))
select * from t3 where a >= all (select b from t2);
a
7
@@ -1498,7 +1498,7 @@
1 PRIMARY t3 ALL NULL NULL NULL NULL 3
100.00 Using where
2 SUBQUERY t2 ALL NULL NULL NULL NULL 0 0.00
Warnings:
-Note 1003 select `test`.`t3`.`a` AS `a` from `test`.`t3` where
<not>((`test`.`t3`.`a` < (select max(`test`.`t2`.`b`) from `test`.`t2`)))
+Note 1003 select `test`.`t3`.`a` AS `a` from `test`.`t3` where
<not>(<in_optimizer>(`test`.`t3`.`a`,(`test`.`t3`.`a` < (select
max(`test`.`t2`.`b`) from `test`.`t2`))))
select * from t3 where a >= some (select b from t2);
a
explain extended select * from t3 where a >= some (select b from t2);
@@ -1506,7 +1506,7 @@
1 PRIMARY t3 ALL NULL NULL NULL NULL 3
100.00 Using where
2 SUBQUERY t2 ALL NULL NULL NULL NULL 0 0.00
Warnings:
-Note 1003 select `test`.`t3`.`a` AS `a` from `test`.`t3` where
<nop>((`test`.`t3`.`a` >= (select min(`test`.`t2`.`b`) from `test`.`t2`)))
+Note 1003 select `test`.`t3`.`a` AS `a` from `test`.`t3` where
<nop>(<in_optimizer>(`test`.`t3`.`a`,(`test`.`t3`.`a` >= (select
min(`test`.`t2`.`b`) from `test`.`t2`))))
select * from t3 where a >= all (select b from t2 group by 1);
a
6
@@ -1517,7 +1517,7 @@
1 PRIMARY t3 ALL NULL NULL NULL NULL 3
100.00 Using where
2 SUBQUERY t2 ALL NULL NULL NULL NULL 0
0.00 Using temporary
Warnings:
-Note 1003 select `test`.`t3`.`a` AS `a` from `test`.`t3` where
<not>((`test`.`t3`.`a` < <max>(select `test`.`t2`.`b` from `test`.`t2`
group by 1)))
+Note 1003 select `test`.`t3`.`a` AS `a` from `test`.`t3` where
<not>(<in_optimizer>(`test`.`t3`.`a`,(`test`.`t3`.`a` < <max>(select
`test`.`t2`.`b` from `test`.`t2` group by 1))))
select * from t3 where a >= some (select b from t2 group by 1);
a
explain extended select * from t3 where a >= some (select b from t2
group by 1);
@@ -1525,7 +1525,7 @@
1 PRIMARY t3 ALL NULL NULL NULL NULL 3
100.00 Using where
2 SUBQUERY t2 ALL NULL NULL NULL NULL 0
0.00 Using temporary
Warnings:
-Note 1003 select `test`.`t3`.`a` AS `a` from `test`.`t3` where
<nop>((`test`.`t3`.`a` >= <min>(select `test`.`t2`.`b` from `test`.`t2`
group by 1)))
+Note 1003 select `test`.`t3`.`a` AS `a` from `test`.`t3` where
<nop>(<in_optimizer>(`test`.`t3`.`a`,(`test`.`t3`.`a` >= <min>(select
`test`.`t2`.`b` from `test`.`t2` group by 1))))
select * from t3 where NULL >= any (select b from t2);
a
explain extended select * from t3 where NULL >= any (select b from t2);
@@ -1533,7 +1533,7 @@
1 PRIMARY t3 ALL NULL NULL NULL NULL 3 100.00
2 SUBQUERY t2 ALL NULL NULL NULL NULL 0 0.00
Warnings:
-Note 1003 select `test`.`t3`.`a` AS `a` from `test`.`t3` where
<nop>((NULL >= (select min(`test`.`t2`.`b`) from `test`.`t2`)))
+Note 1003 select `test`.`t3`.`a` AS `a` from `test`.`t3` where
<nop>(<in_optimizer>(NULL,(NULL >= (select min(`test`.`t2`.`b`) from
`test`.`t2`))))
select * from t3 where NULL >= any (select b from t2 group by 1);
a
explain extended select * from t3 where NULL >= any (select b from t2
group by 1);
@@ -1541,7 +1541,7 @@
1 PRIMARY t3 ALL NULL NULL NULL NULL 3 100.00
2 SUBQUERY t2 ALL NULL NULL NULL NULL 0
0.00 Using temporary
Warnings:
-Note 1003 select `test`.`t3`.`a` AS `a` from `test`.`t3` where
<nop>((NULL >= <min>(select `test`.`t2`.`b` from `test`.`t2` group by 1)))
+Note 1003 select `test`.`t3`.`a` AS `a` from `test`.`t3` where
<nop>(<in_optimizer>(NULL,(NULL >= <min>(select `test`.`t2`.`b` from
`test`.`t2` group by 1))))
select * from t3 where NULL >= some (select b from t2);
a
explain extended select * from t3 where NULL >= some (select b from t2);
@@ -1549,7 +1549,7 @@
1 PRIMARY t3 ALL NULL NULL NULL NULL 3 100.00
2 SUBQUERY t2 ALL NULL NULL NULL NULL 0 0.00
Warnings:
-Note 1003 select `test`.`t3`.`a` AS `a` from `test`.`t3` where
<nop>((NULL >= (select min(`test`.`t2`.`b`) from `test`.`t2`)))
+Note 1003 select `test`.`t3`.`a` AS `a` from `test`.`t3` where
<nop>(<in_optimizer>(NULL,(NULL >= (select min(`test`.`t2`.`b`) from
`test`.`t2`))))
select * from t3 where NULL >= some (select b from t2 group by 1);
a
explain extended select * from t3 where NULL >= some (select b from t2
group by 1);
@@ -1557,7 +1557,7 @@
1 PRIMARY t3 ALL NULL NULL NULL NULL 3 100.00
2 SUBQUERY t2 ALL NULL NULL NULL NULL 0
0.00 Using temporary
Warnings:
-Note 1003 select `test`.`t3`.`a` AS `a` from `test`.`t3` where
<nop>((NULL >= <min>(select `test`.`t2`.`b` from `test`.`t2` group by 1)))
+Note 1003 select `test`.`t3`.`a` AS `a` from `test`.`t3` where
<nop>(<in_optimizer>(NULL,(NULL >= <min>(select `test`.`t2`.`b` from
`test`.`t2` group by 1))))
insert into t2 values (2,2), (2,1), (3,3), (3,1);
select * from t3 where a > all (select max(b) from t2 group by a);
a
@@ -1568,7 +1568,7 @@
1 PRIMARY t3 ALL NULL NULL NULL NULL 3
100.00 Using where
2 SUBQUERY t2 ALL NULL NULL NULL NULL 4
100.00 Using temporary
Warnings:
-Note 1003 select `test`.`t3`.`a` AS `a` from `test`.`t3` where
<not>((`test`.`t3`.`a` <= <max>(select max(`test`.`t2`.`b`) from
`test`.`t2` group by `test`.`t2`.`a`)))
+Note 1003 select `test`.`t3`.`a` AS `a` from `test`.`t3` where
<not>(<in_optimizer>(`test`.`t3`.`a`,(`test`.`t3`.`a` <= <max>(select
max(`test`.`t2`.`b`) from `test`.`t2` group by `test`.`t2`.`a`))))
drop table t2, t3;
CREATE TABLE `t1` ( `id` mediumint(9) NOT NULL auto_increment,
`taskid` bigint(20) NOT NULL default '0', `dbid` int(11) NOT NULL
default '0', `create_date` datetime NOT NULL default '0000-00-00
00:00:00', `last_update` datetime NOT NULL default '0000-00-00
00:00:00', PRIMARY KEY (`id`)) ENGINE=MyISAM CHARSET=latin1
AUTO_INCREMENT=3 ;
INSERT INTO `t1` (`id`, `taskid`, `dbid`, `create_date`,`last_update`)
VALUES (1, 1, 15, '2003-09-29 10:31:36', '2003-09-29 10:31:36'), (2, 1,
21, now(), now());
@@ -1619,7 +1619,7 @@
3 UNION t1 ALL NULL NULL NULL NULL 1 100.00
NULL UNION RESULT <union2,3> ALL NULL NULL NULL
NULL NULL NULL
Warnings:
-Note 1003 select `test`.`t1`.`s1` AS `s1` from `test`.`t1` where
<nop>(('f' > <min>(select `test`.`t1`.`s1` from `test`.`t1` union select
`test`.`t1`.`s1` from `test`.`t1`)))
+Note 1003 select `test`.`t1`.`s1` AS `s1` from `test`.`t1` where
<nop>(<in_optimizer>('f',('f' > <min>(select `test`.`t1`.`s1` from
`test`.`t1` union select `test`.`t1`.`s1` from `test`.`t1`))))
drop table t1;
CREATE TABLE t1 (number char(11) NOT NULL default '') ENGINE=MyISAM
CHARSET=latin1;
INSERT INTO t1 VALUES
('69294728265'),('18621828126'),('89356874041'),('95895001874');
=== modified file 'mysql-test/t/explain.test'
--- mysql-test/t/explain.test 2011-05-05 01:08:44 +0000
+++ mysql-test/t/explain.test 2011-05-10 20:17:04 +0000
@@ -158,7 +158,10 @@
SET SESSION sql_mode='ONLY_FULL_GROUP_BY';
# EXPLAIN EXTENDED (with subselect). used to crash. should give NOTICE.
---error ER_MIX_OF_GROUP_FUNC_AND_FIELDS
+# Before moving max/min optimization to optimize phase this statement
+# generated error, but as far as original query do not contain aggregate
+# function user should not see error
+# --error ER_MIX_OF_GROUP_FUNC_AND_FIELDS
EXPLAIN EXTENDED SELECT 1 FROM t1
WHERE f1 > ALL( SELECT t.f1 FROM t1,t1 AS t );
SHOW WARNINGS;
=== modified file 'sql/item_cmpfunc.cc'
--- sql/item_cmpfunc.cc 2011-05-10 15:28:05 +0000
+++ sql/item_cmpfunc.cc 2011-05-10 20:17:04 +0000
@@ -1798,6 +1798,8 @@
{
THD *thd= (THD*) thd_arg;
DBUG_ENTER("Item_in_optimizer::expr_cache_insert_transformer");
+ if (args[1]->type() != Item::SUBSELECT_ITEM)
+ DBUG_RETURN(this); // MAX/MIN transformed => do nothing
List<Item*> &depends_on= ((Item_subselect *)args[1])->depends_on;
if (expr_cache)
@@ -1901,7 +1903,15 @@
DBUG_ASSERT(fixed == 1);
cache->store(args[0]);
cache->cache_value();
-
+
+ if (args[1]->type() != Item::SUBSELECT_ITEM)
+ {
+ /* MAX/MIN transformed => pass through */
+ longlong res= args[1]->val_int();
+ null_value= args[1]->null_value;
+ return (res);
+ }
+
if (cache->null_value)
{
/*
@@ -2050,24 +2060,35 @@
if ((*args) != new_item)
current_thd->change_item_tree(args, new_item);
- /*
- Transform the right IN operand which should be an Item_in_subselect
or a
- subclass of it. The left operand of the IN must be the same as the left
- operand of this Item_in_optimizer, so in this case there is no further
- transformation, we only make both operands the same.
- TODO: is it the way it should be?
- */
- DBUG_ASSERT((args[1])->type() == Item::SUBSELECT_ITEM &&
- (((Item_subselect*)(args[1]))->substype() ==
- Item_subselect::IN_SUBS ||
- ((Item_subselect*)(args[1]))->substype() ==
- Item_subselect::ALL_SUBS ||
- ((Item_subselect*)(args[1]))->substype() ==
- Item_subselect::ANY_SUBS));
-
- Item_in_subselect *in_arg= (Item_in_subselect*)args[1];
- in_arg->left_expr= args[0];
-
+ if (args[1]->type() != Item::SUBSELECT_ITEM)
+ {
+ /* MAX/MIN transformed => pass through */
+ new_item= args[1]->transform(transformer, argument);
+ if (!new_item)
+ return 0;
+ if (args[1] != new_item)
+ current_thd->change_item_tree(args, new_item);
+ }
+ else
+ {
+ /*
+ Transform the right IN operand which should be an
Item_in_subselect or a
+ subclass of it. The left operand of the IN must be the same as
the left
+ operand of this Item_in_optimizer, so in this case there is no
further
+ transformation, we only make both operands the same.
+ TODO: is it the way it should be?
+ */
+ DBUG_ASSERT((args[1])->type() == Item::SUBSELECT_ITEM &&
+ (((Item_subselect*)(args[1]))->substype() ==
+ Item_subselect::IN_SUBS ||
+ ((Item_subselect*)(args[1]))->substype() ==
+ Item_subselect::ALL_SUBS ||
+ ((Item_subselect*)(args[1]))->substype() ==
+ Item_subselect::ANY_SUBS));
+
+ Item_in_subselect *in_arg= (Item_in_subselect*)args[1];
+ in_arg->left_expr= args[0];
+ }
return (this->*transformer)(argument);
}
=== modified file 'sql/item_subselect.cc'
--- sql/item_subselect.cc 2011-04-28 14:15:05 +0000
+++ sql/item_subselect.cc 2011-05-10 20:17:04 +0000
@@ -33,12 +33,14 @@
Item_subselect::Item_subselect():
- Item_result_field(), value_assigned(0), thd(0), substitution(0),
+ Item_result_field(), value_assigned(0), thd(0), substitution(0),
expr_cache(0), engine(0), old_engine(0), used_tables_cache(0),
have_to_be_excluded(0), const_item_cache(1), inside_first_fix_fields(0),
done_first_fix_fields(FALSE), forced_const(FALSE), eliminated(FALSE),
engine_changed(0), changed(0), is_correlated(FALSE)
{
+ DBUG_ENTER("Item_subselect::Item_subselect");
+ DBUG_PRINT("enter", ("this: 0x%lx", (ulong) this));
with_subselect= 1;
reset();
/*
@@ -46,6 +48,7 @@
(i.e. some rows will be found returned)
*/
null_value= TRUE;
+ DBUG_VOID_RETURN;
}
@@ -58,7 +61,8 @@
*/
DBUG_ENTER("Item_subselect::init");
- DBUG_PRINT("enter", ("select_lex: 0x%lx", (long) select_lex));
+ DBUG_PRINT("enter", ("select_lex: 0x%lx this: 0x%lx",
+ (ulong) select_lex, (ulong) this));
unit= select_lex->master_unit();
thd= unit->thd;
@@ -69,10 +73,12 @@
=> we do not copy old_engine here
*/
engine= unit->item->engine;
+ borrowed_engine= TRUE;
parsing_place= unit->item->parsing_place;
- unit->item->engine= 0;
- unit->item= this;
- engine->change_result(this, result);
+ //unit->item->engine= 0;
+ thd->change_item_tree((Item**)&unit->item, this);
+ //unit->item= this;
+ engine->change_result(this, result, TRUE);
}
else
{
@@ -97,6 +103,7 @@
/* The subquery is an expression cache candidate */
upper->expr_cache_may_be_used[upper->parsing_place]= TRUE;
}
+ DBUG_PRINT("info", ("engine: 0x%lx", (ulong)engine));
DBUG_VOID_RETURN;
}
@@ -156,8 +163,14 @@
Item_subselect::~Item_subselect()
{
- delete engine;
+ DBUG_ENTER("Item_subselect::~Item_subselect");
+ DBUG_PRINT("enter", ("this: 0x%lx", (ulong) this));
+ if (!borrowed_engine)
+ delete engine;
+ else
+ engine->cleanup();
engine= NULL;
+ DBUG_VOID_RETURN;
}
bool
@@ -1119,11 +1132,23 @@
void Item_exists_subselect::fix_length_and_dec()
{
- decimals= 0;
- max_length= 1;
- max_columns= engine->cols();
+ DBUG_ENTER("Item_exists_subselect::fix_length_and_dec");
+ decimals= 0;
+ max_length= 1;
+ max_columns= engine->cols();
/* We need only 1 row to determine existence */
unit->global_parameters->select_limit= new Item_int((int32) 1);
+ DBUG_PRINT("info", ("Set limit to 1"));
+ DBUG_VOID_RETURN;
+}
+
+void Item_in_subselect::fix_length_and_dec()
+{
+ DBUG_ENTER("Item_in_subselect::fix_length_and_dec");
+ decimals= 0;
+ max_length= 1;
+ max_columns= engine->cols();
+ DBUG_VOID_RETURN;
}
@@ -1388,88 +1413,6 @@
DBUG_RETURN(true);
}
- /*
- If this is an ALL/ANY single-value subselect, try to rewrite it with
- a MIN/MAX subselect. We can do that if a possible NULL result of the
- subselect can be ignored.
- E.g. SELECT * FROM t1 WHERE b > ANY (SELECT a FROM t2) can be rewritten
- with SELECT * FROM t1 WHERE b > (SELECT MAX(a) FROM t2).
- We can't check that this optimization is safe if it's not a top-level
- item of the WHERE clause (e.g. because the WHERE clause can contain IS
- NULL/IS NOT NULL functions). If so, we rewrite ALL/ANY with NOT EXISTS
- later in this method.
- */
- if ((abort_on_null || (upper_item && upper_item->top_level())) &&
- !select_lex->master_unit()->uncacheable && !func->eqne_op())
- {
- if (substitution)
- {
- /* It is second (third, ...) SELECT of UNION => All is done */
- DBUG_RETURN(false);
- }
-
- Item *subs;
- if (!select_lex->group_list.elements &&
- !select_lex->having &&
- !select_lex->with_sum_func &&
- !(select_lex->next_select()) &&
- select_lex->table_list.elements)
- {
- Item_sum_hybrid *item;
- nesting_map save_allow_sum_func;
- if (func->l_op())
- {
- /*
- (ALL && (> || =>)) || (ANY && (< || =<))
- for ALL condition is inverted
- */
- item= new Item_sum_max(*select_lex->ref_pointer_array);
- }
- else
- {
- /*
- (ALL && (< || =<)) || (ANY && (> || =>))
- for ALL condition is inverted
- */
- item= new Item_sum_min(*select_lex->ref_pointer_array);
- }
- if (upper_item)
- upper_item->set_sum_test(item);
- *select_lex->ref_pointer_array= item;
- {
- List_iterator<Item> it(select_lex->item_list);
- it++;
- it.replace(item);
- }
-
- save_allow_sum_func= thd->lex->allow_sum_func;
- thd->lex->allow_sum_func|= 1 << thd->lex->current_select->nest_level;
- /*
- Item_sum_(max|min) can't substitute other item => we can use 0 as
- reference, also Item_sum_(max|min) can't be fixed after
creation, so
- we do not check item->fixed
- */
- if (item->fix_fields(thd, 0))
- DBUG_RETURN(true);
- thd->lex->allow_sum_func= save_allow_sum_func;
- /* we added aggregate function => we have to change statistic */
- count_field_types(select_lex, &join->tmp_table_param,
join->all_fields,
- 0);
-
- subs= new Item_singlerow_subselect(select_lex);
- }
- else
- {
- Item_maxmin_subselect *item;
- subs= item= new Item_maxmin_subselect(thd, this, select_lex,
func->l_op());
- if (upper_item)
- upper_item->set_sub_test(item);
- }
- /* fix fields is already called for left expression */
- substitution= func->create(left_expr, subs);
- DBUG_RETURN(false);
- }
-
Item* join_having= join->having ? join->having : join->tmp_having;
if (!(join_having || select_lex->with_sum_func ||
select_lex->group_list.elements) &&
@@ -1503,7 +1446,6 @@
if (!substitution)
{
/* We're invoked for the 1st (or the only) SELECT in the subquery
UNION */
- SELECT_LEX_UNIT *master_unit= select_lex->master_unit();
substitution= optimizer;
SELECT_LEX *current= thd->lex->current_select;
@@ -1529,16 +1471,102 @@
(char *)"<no matter>",
(char *)in_left_expr_name);
+ }
+
+ DBUG_RETURN(false);
+}
+
+bool Item_allany_subselect::transform_allany(JOIN *join)
+{
+ DBUG_ENTER("Item_allany_subselect::transform_allany");
+ if (!(in_strategy & SUBS_MAXMIN))
+ DBUG_RETURN(0);
+ Item **place= optimizer->arguments() + 1;
+ THD *thd= join->thd;
+ SELECT_LEX *select_lex= join->select_lex;
+ Item *subs;
+
+ /*
+ If this is an ALL/ANY single-value subselect, try to rewrite it with
+ a MIN/MAX subselect. We can do that if a possible NULL result of the
+ subselect can be ignored.
+ E.g. SELECT * FROM t1 WHERE b > ANY (SELECT a FROM t2) can be rewritten
+ with SELECT * FROM t1 WHERE b > (SELECT MAX(a) FROM t2).
+ We can't check that this optimization is safe if it's not a top-level
+ item of the WHERE clause (e.g. because the WHERE clause can contain IS
+ NULL/IS NOT NULL functions). If so, we rewrite ALL/ANY with NOT EXISTS
+ later in this method.
+ */
+ DBUG_ASSERT(!substitution);
+
+ if (!select_lex->group_list.elements &&
+ !select_lex->having &&
+ !select_lex->with_sum_func &&
+ !(select_lex->next_select()) &&
+ select_lex->table_list.elements)
+ {
+ Item_sum_hybrid *item;
+ nesting_map save_allow_sum_func;
+ if (func->l_op())
+ {
+ /*
+ (ALL && (> || =>)) || (ANY && (< || =<))
+ for ALL condition is inverted
+ */
+ item= new Item_sum_max(*select_lex->ref_pointer_array);
+ }
+ else
+ {
+ /*
+ (ALL && (< || =<)) || (ANY && (> || =>))
+ for ALL condition is inverted
+ */
+ item= new Item_sum_min(*select_lex->ref_pointer_array);
+ }
+ if (upper_item)
+ upper_item->set_sum_test(item);
+ thd->change_item_tree(select_lex->ref_pointer_array, item);
+ {
+ List_iterator<Item> it(select_lex->item_list);
+ it++;
+ thd->change_item_tree(it.ref(), item);
+ }
+
+ save_allow_sum_func= thd->lex->allow_sum_func;
+ thd->lex->allow_sum_func|= 1 << thd->lex->current_select->nest_level;
/*
- The uncacheable property controls a number of actions, e.g.
whether to
- save/restore (via init_save_join_tab/restore_tmp) the original
JOIN for
- plans with a temp table where the original JOIN was overriden by
- make_simple_join. The UNCACHEABLE_EXPLAIN is ignored by EXPLAIN, thus
- non-correlated subqueries will not appear as such to EXPLAIN.
+ Item_sum_(max|min) can't substitute other item => we can use 0 as
+ reference, also Item_sum_(max|min) can't be fixed after creation, so
+ we do not check item->fixed
*/
- master_unit->uncacheable|= UNCACHEABLE_EXPLAIN;
- select_lex->uncacheable|= UNCACHEABLE_EXPLAIN;
- }
+ if (item->fix_fields(thd, 0))
+ DBUG_RETURN(true);
+ thd->lex->allow_sum_func= save_allow_sum_func;
+ /* we added aggregate function => we have to change statistic */
+ count_field_types(select_lex, &join->tmp_table_param,
join->all_fields,
+ 0);
+ if (join->prepare_stage2())
+ DBUG_RETURN(true);
+ subs= new Item_singlerow_subselect(select_lex);
+ }
+ else
+ {
+ Item_maxmin_subselect *item;
+ subs= item= new Item_maxmin_subselect(thd, this, select_lex,
func->l_op());
+ if (upper_item)
+ upper_item->set_sub_test(item);
+ }
+ /* fix fields is already called for left expression */
+ subs= func->create(left_expr, subs);
+ thd->change_item_tree(place, subs);
+ if (subs->fix_fields(thd, &subs))
+ DBUG_RETURN(1);
+ DBUG_ASSERT(subs == (*place)); // There was no substitutions
+
+ select_lex->master_unit()->uncacheable&= ~UNCACHEABLE_DEPENDENT_INJECTED;
+ select_lex->uncacheable&= ~UNCACHEABLE_DEPENDENT_INJECTED;
+ /* remove other strategies if there was (just to be safe) */
+ in_strategy= SUBS_MAXMIN;
DBUG_RETURN(false);
}
@@ -1556,6 +1584,16 @@
return fix_res;
}
+bool Item_allany_subselect::is_maxmin_applicable(JOIN *join)
+{
+ /*
+ Check if max/min optimization applicable: It is top item of
+ WHERE condition.
+ */
+ return (abort_on_null || (upper_item && upper_item->top_level())) &&
+ !join->select_lex->master_unit()->uncacheable && !func->eqne_op();
+}
+
/**
Create the predicates needed to transform a single-column IN/ALL/ANY
@@ -2028,7 +2066,7 @@
/*
The IN=>EXISTS transformation makes non-correlated subqueries
correlated.
*/
- join_arg->select_lex->uncacheable|= UNCACHEABLE_DEPENDENT;
+ join_arg->select_lex->uncacheable|= UNCACHEABLE_DEPENDENT_INJECTED;
if (left_expr->cols() == 1)
res= create_single_in_to_exists_cond(join_arg,
&(join_arg->in_to_exists_where),
@@ -2037,6 +2075,16 @@
res= create_row_in_to_exists_cond(join_arg,
&(join_arg->in_to_exists_where),
&(join_arg->in_to_exists_having));
+
+ /*
+ The uncacheable property controls a number of actions, e.g. whether to
+ save/restore (via init_save_join_tab/restore_tmp) the original JOIN for
+ plans with a temp table where the original JOIN was overriden by
+ make_simple_join. The UNCACHEABLE_EXPLAIN is ignored by EXPLAIN, thus
+ non-correlated subqueries will not appear as such to EXPLAIN.
+ */
+ join_arg->select_lex->master_unit()->uncacheable|= UNCACHEABLE_EXPLAIN;
+ join_arg->select_lex->uncacheable|= UNCACHEABLE_EXPLAIN;
return (res);
}
@@ -2107,6 +2155,9 @@
select_lex->having->top_level_item();
join_arg->having= select_lex->having;
}
+ join_arg->thd->change_item_tree(&unit->global_parameters->select_limit,
+ new Item_int((int32) 1));
+ unit->select_limit_cnt= 1;
DBUG_RETURN(false);
}
@@ -2407,7 +2458,8 @@
Item_allany_subselect::select_transformer(JOIN *join)
{
DBUG_ENTER("Item_allany_subselect::select_transformer");
- in_strategy= SUBS_IN_TO_EXISTS;
+ DBUG_ASSERT((in_strategy & ~(SUBS_MAXMIN | SUBS_IN_TO_EXISTS)) == 0);
+ in_strategy|= SUBS_IN_TO_EXISTS;
if (upper_item)
upper_item->show= 1;
DBUG_RETURN(select_in_like_transformer(join));
@@ -2458,6 +2510,7 @@
prepared= executed= 0;
join= 0;
result->cleanup();
+ select_lex->uncacheable&= ~UNCACHEABLE_DEPENDENT_INJECTED;
DBUG_VOID_RETURN;
}
@@ -2467,6 +2520,9 @@
DBUG_ENTER("subselect_union_engine::cleanup");
unit->reinit_exec_mechanism();
result->cleanup();
+ unit->uncacheable&= ~UNCACHEABLE_DEPENDENT_INJECTED;
+ for (SELECT_LEX *sl= unit->first_select(); sl; sl= sl->next_select())
+ sl->uncacheable&= ~UNCACHEABLE_DEPENDENT_INJECTED;
DBUG_VOID_RETURN;
}
@@ -3466,11 +3522,16 @@
TRUE error
*/
-bool subselect_single_select_engine::change_result(Item_subselect *si,
-
select_result_interceptor *res)
+bool
+subselect_single_select_engine::change_result(Item_subselect *si,
+ select_result_interceptor
*res,
+ bool temp)
{
item= si;
- result= res;
+ if (temp)
+ thd->change_item_tree((Item**) &result, (Item*)res);
+ else
+ result= res;
return select_lex->join->change_result(result);
}
@@ -3488,11 +3549,15 @@
*/
bool subselect_union_engine::change_result(Item_subselect *si,
- select_result_interceptor *res)
+ select_result_interceptor *res,
+ bool temp)
{
item= si;
int rc= unit->change_result(res, result);
- result= res;
+ if (temp)
+ thd->change_item_tree((Item**) &result, (Item*)res);
+ else
+ result= res;
return rc;
}
@@ -3509,8 +3574,11 @@
TRUE error
*/
-bool subselect_uniquesubquery_engine::change_result(Item_subselect *si,
-
select_result_interceptor *res)
+bool
+subselect_uniquesubquery_engine::change_result(Item_subselect *si,
+
select_result_interceptor *res,
+ bool temp
+ __attribute__((unused)))
{
DBUG_ASSERT(0);
return TRUE;
@@ -4301,7 +4369,8 @@
}
bool subselect_hash_sj_engine::change_result(Item_subselect *si,
- select_result_interceptor
*res)
+ select_result_interceptor
*res,
+ bool temp
__attribute__((unused)))
{
DBUG_ASSERT(FALSE);
return TRUE;
=== modified file 'sql/item_subselect.h'
--- sql/item_subselect.h 2011-03-30 07:10:59 +0000
+++ sql/item_subselect.h 2011-05-10 20:17:04 +0000
@@ -32,7 +32,8 @@
class Item_subselect :public Item_result_field
{
- bool value_assigned; /* value already assigned to subselect */
+ bool value_assigned; /* value already assigned to subselect */
+ bool borrowed_engine; /* the engine was taken from other
Item_subselect */
protected:
/* thread handler, will be assigned in fix_fields only */
THD *thd;
@@ -356,6 +357,9 @@
/* Partial matching substrategies of MATERIALIZATION. */
#define SUBS_PARTIAL_MATCH_ROWID_MERGE 8
#define SUBS_PARTIAL_MATCH_TABLE_SCAN 16
+/* ALL/ANY will be transformed with max/min optimization */
+#define SUBS_MAXMIN 32
+
/**
Representation of IN subquery predicates of the form
@@ -486,6 +490,7 @@
bool test_limit(st_select_lex_unit *unit);
virtual void print(String *str, enum_query_type query_type);
bool fix_fields(THD *thd, Item **ref);
+ void fix_length_and_dec();
void fix_after_pullout(st_select_lex *new_parent, Item **ref);
void update_used_tables();
bool setup_mat_engine();
@@ -523,6 +528,8 @@
bool select_transformer(JOIN *join);
void create_comp_func(bool invert) { func= func_creator(invert); }
virtual void print(String *str, enum_query_type query_type);
+ bool is_maxmin_applicable(JOIN *join);
+ bool transform_allany(JOIN *join);
};
@@ -594,7 +601,8 @@
static table_map calc_const_tables(TABLE_LIST *);
virtual void print(String *str, enum_query_type query_type)= 0;
virtual bool change_result(Item_subselect *si,
- select_result_interceptor *result)= 0;
+ select_result_interceptor *result,
+ bool temp= FALSE)= 0;
virtual bool no_tables()= 0;
virtual bool is_executed() const { return FALSE; }
/* Check if subquery produced any rows during last query execution */
@@ -626,7 +634,9 @@
void exclude();
table_map upper_select_const_tables();
virtual void print (String *str, enum_query_type query_type);
- bool change_result(Item_subselect *si, select_result_interceptor
*result);
+ bool change_result(Item_subselect *si,
+ select_result_interceptor *result,
+ bool temp);
bool no_tables();
bool may_be_null();
bool is_executed() const { return executed; }
@@ -655,7 +665,9 @@
void exclude();
table_map upper_select_const_tables();
virtual void print (String *str, enum_query_type query_type);
- bool change_result(Item_subselect *si, select_result_interceptor
*result);
+ bool change_result(Item_subselect *si,
+ select_result_interceptor *result,
+ bool temp= FALSE);
bool no_tables();
bool is_executed() const;
bool no_rows();
@@ -707,11 +719,13 @@
void fix_length_and_dec(Item_cache** row);
int exec();
uint cols() { return 1; }
- uint8 uncacheable() { return UNCACHEABLE_DEPENDENT; }
+ uint8 uncacheable() { return UNCACHEABLE_DEPENDENT_INJECTED; }
void exclude();
table_map upper_select_const_tables() { return 0; }
virtual void print (String *str, enum_query_type query_type);
- bool change_result(Item_subselect *si, select_result_interceptor
*result);
+ bool change_result(Item_subselect *si,
+ select_result_interceptor *result,
+ bool temp= FALSE);
bool no_tables();
int index_lookup(); /* TIMOUR: this method needs refactoring. */
int scan_table();
@@ -879,7 +893,9 @@
void fix_length_and_dec(Item_cache** row);//=>base class
void exclude(); //=>base class
//=>base class
- bool change_result(Item_subselect *si, select_result_interceptor
*result);
+ bool change_result(Item_subselect *si,
+ select_result_interceptor *result,
+ bool temp= FALSE);
bool no_tables();//=>base class
};
@@ -1106,7 +1122,9 @@
uint8 uncacheable() { return UNCACHEABLE_DEPENDENT; }
void exclude() {}
table_map upper_select_const_tables() { return 0; }
- bool change_result(Item_subselect*, select_result_interceptor*)
+ bool change_result(Item_subselect*,
+ select_result_interceptor*,
+ bool temp= FALSE)
{ DBUG_ASSERT(FALSE); return false; }
bool no_tables() { return false; }
bool no_rows()
=== modified file 'sql/mysql_priv.h'
--- sql/mysql_priv.h 2011-05-10 15:28:05 +0000
+++ sql/mysql_priv.h 2011-05-10 20:17:04 +0000
@@ -679,14 +679,18 @@
#define CONTEXT_ANALYSIS_ONLY_DERIVED 4
// uncachable cause
-#define UNCACHEABLE_DEPENDENT 1
-#define UNCACHEABLE_RAND 2
-#define UNCACHEABLE_SIDEEFFECT 4
+#define UNCACHEABLE_DEPENDENT_GENERATED 1
+#define UNCACHEABLE_RAND 2
+#define UNCACHEABLE_SIDEEFFECT 4
/// forcing to save JOIN for explain
-#define UNCACHEABLE_EXPLAIN 8
+#define UNCACHEABLE_EXPLAIN 8
/* For uncorrelated SELECT in an UNION with some correlated SELECTs */
-#define UNCACHEABLE_UNITED 16
-#define UNCACHEABLE_CHECKOPTION 32
+#define UNCACHEABLE_UNITED 16
+#define UNCACHEABLE_CHECKOPTION 32
+#define UNCACHEABLE_DEPENDENT_INJECTED 64
+
+#define UNCACHEABLE_DEPENDENT (UNCACHEABLE_DEPENDENT_GENERATED | \
+ UNCACHEABLE_DEPENDENT_INJECTED)
/* Used to check GROUP BY list in the MODE_ONLY_FULL_GROUP_BY mode */
#define UNDEF_POS (-1)
=== modified file 'sql/opt_subselect.cc'
--- sql/opt_subselect.cc 2011-05-02 18:59:16 +0000
+++ sql/opt_subselect.cc 2011-05-10 20:17:04 +0000
@@ -93,8 +93,19 @@
(subselect=
parent_unit->item)) // (2)
{
Item_in_subselect *in_subs= NULL;
- if (subselect->substype() == Item_subselect::IN_SUBS)
- in_subs= (Item_in_subselect*)subselect;
+ Item_allany_subselect *allany_subs= NULL;
+ switch (subselect->substype()) {
+ case Item_subselect::IN_SUBS:
+ in_subs= (Item_in_subselect *)subselect;
+ break;
+ case Item_subselect::ALL_SUBS:
+ case Item_subselect::ANY_SUBS:
+ allany_subs= (Item_allany_subselect *)subselect;
+ break;
+ default:
+ break;
+ }
+
/* Resolve expressions and perform semantic analysis for IN query */
if (in_subs != NULL)
@@ -257,12 +268,18 @@
}
}
+ /* Check if max/min optimization applicable */
+ if (allany_subs)
+ allany_subs->in_strategy|=
(allany_subs->is_maxmin_applicable(join) ?
+ SUBS_MAXMIN :
+ SUBS_IN_TO_EXISTS);
+
/*
Transform each subquery predicate according to its overloaded
transformer.
*/
if (subselect->select_transformer(join))
- DBUG_RETURN(-11);
+ DBUG_RETURN(-1);
}
}
DBUG_RETURN(0);
@@ -369,6 +386,21 @@
}
+/**
+ Apply max min optimization of all/any subselect
+*/
+
+bool convert_max_min_subquery(JOIN *join)
+{
+ DBUG_ENTER("convert_max_min_subquery");
+ Item_subselect *subselect= join->unit->item;
+ if (!subselect || (subselect->substype() != Item_subselect::ALL_SUBS &&
+ subselect->substype() != Item_subselect::ANY_SUBS))
+ DBUG_RETURN(0);
+ DBUG_RETURN(((Item_allany_subselect *)
subselect)->transform_allany(join));
+}
+
+
/*
Convert semi-join subquery predicates into semi-join join nests
@@ -3843,8 +3875,8 @@
restore_query_plan(&save_qep);
/* TODO: should we set/unset this flag for both select_lex and its
unit? */
- in_subs->unit->uncacheable&= ~UNCACHEABLE_DEPENDENT;
- select_lex->uncacheable&= ~UNCACHEABLE_DEPENDENT;
+ in_subs->unit->uncacheable&= ~UNCACHEABLE_DEPENDENT_INJECTED;
+ select_lex->uncacheable&= ~UNCACHEABLE_DEPENDENT_INJECTED;
/*
Reset the "LIMIT 1" set in
Item_exists_subselect::fix_length_and_dec.
@@ -3884,6 +3916,9 @@
if (in_subs->inject_in_to_exists_cond(this))
return TRUE;
+ in_subs->unit->uncacheable|= UNCACHEABLE_DEPENDENT_INJECTED;
+ select_lex->uncacheable|= UNCACHEABLE_DEPENDENT_INJECTED;
+ select_limit= 1;
}
else
DBUG_ASSERT(FALSE);
=== modified file 'sql/opt_subselect.h'
--- sql/opt_subselect.h 2010-12-11 07:23:34 +0000
+++ sql/opt_subselect.h 2011-05-10 20:17:04 +0000
@@ -6,6 +6,7 @@
int check_and_do_in_subquery_rewrites(JOIN *join);
bool convert_join_subqueries_to_semijoins(JOIN *join);
+bool convert_max_min_subquery(JOIN *join);
int pull_out_semijoin_tables(JOIN *join);
bool optimize_semijoin_nests(JOIN *join, table_map all_table_map);
=== modified file 'sql/sql_class.h'
--- sql/sql_class.h 2011-05-10 15:28:05 +0000
+++ sql/sql_class.h 2011-05-10 20:17:04 +0000
@@ -2727,7 +2727,12 @@
class select_result_interceptor: public select_result
{
public:
- select_result_interceptor() {} /* Remove gcc warning */
+ select_result_interceptor()
+ {
+ DBUG_ENTER("select_result_interceptor::select_result_interceptor");
+ DBUG_PRINT("enter", ("this 0x%lx", (ulong) this));
+ DBUG_VOID_RETURN;
+ } /* Remove gcc warning */
uint field_count(List<Item> &fields) const { return 0; }
bool send_fields(List<Item> &fields, uint flag) { return FALSE; }
};
=== modified file 'sql/sql_lex.cc'
--- sql/sql_lex.cc 2011-05-05 12:24:28 +0000
+++ sql/sql_lex.cc 2011-05-10 20:17:04 +0000
@@ -1942,18 +1942,19 @@
SELECT_LEX *s= this;
do
{
- if (!(s->uncacheable & UNCACHEABLE_DEPENDENT))
+ if (!(s->uncacheable & UNCACHEABLE_DEPENDENT_GENERATED))
{
// Select is dependent of outer select
s->uncacheable= (s->uncacheable & ~UNCACHEABLE_UNITED) |
- UNCACHEABLE_DEPENDENT;
+ UNCACHEABLE_DEPENDENT_GENERATED;
SELECT_LEX_UNIT *munit= s->master_unit();
munit->uncacheable= (munit->uncacheable & ~UNCACHEABLE_UNITED) |
- UNCACHEABLE_DEPENDENT;
+ UNCACHEABLE_DEPENDENT_GENERATED;
for (SELECT_LEX *sl= munit->first_select(); sl ; sl=
sl->next_select())
{
if (sl != s &&
- !(sl->uncacheable & (UNCACHEABLE_DEPENDENT |
UNCACHEABLE_UNITED)))
+ !(sl->uncacheable & (UNCACHEABLE_DEPENDENT_GENERATED |
+ UNCACHEABLE_UNITED)))
sl->uncacheable|= UNCACHEABLE_UNITED;
}
}
@@ -2178,17 +2179,6 @@
subs_type == Item_subselect::IN_SUBS ||
subs_type == Item_subselect::ALL_SUBS)
{
- DBUG_ASSERT(!item->fixed ||
- /*
- If not using materialization both:
- select_limit == 1, and there should be no offset_limit.
- */
- (((subs_type == Item_subselect::IN_SUBS) &&
- ((Item_in_subselect*)item)->in_strategy &
- SUBS_MATERIALIZATION) ?
- TRUE :
- (select_limit->val_int() == 1LL) &&
- offset_limit == 0));
return;
}
}
=== modified file 'sql/sql_lex.h'
--- sql/sql_lex.h 2011-05-02 18:59:16 +0000
+++ sql/sql_lex.h 2011-05-10 20:17:04 +0000
@@ -417,7 +417,8 @@
/*
result of this query can't be cached, bit field, can be :
- UNCACHEABLE_DEPENDENT
+ UNCACHEABLE_DEPENDENT_GENERATED
+ UNCACHEABLE_DEPENDENT_INJECTED
UNCACHEABLE_RAND
UNCACHEABLE_SIDEEFFECT
UNCACHEABLE_EXPLAIN
=== modified file 'sql/sql_select.cc'
--- sql/sql_select.cc 2011-05-05 12:24:28 +0000
+++ sql/sql_select.cc 2011-05-10 20:17:04 +0000
@@ -736,11 +736,28 @@
if (!procedure && result && result->prepare(fields_list, unit_arg))
goto err; /* purecov: inspected */
+ unit= unit_arg;
+ if (prepare_stage2())
+ goto err;
+
+ DBUG_RETURN(0); // All OK
+
+err:
+ delete procedure; /* purecov: inspected */
+ procedure= 0;
+ DBUG_RETURN(-1); /* purecov: inspected */
+}
+
+
+bool JOIN::prepare_stage2()
+{
+ bool res= TRUE;
+ DBUG_ENTER("JOIN::prepare_stage2");
+
/* Init join struct */
count_field_types(select_lex, &tmp_table_param, all_fields, 0);
ref_pointer_array_size= all_fields.elements*sizeof(Item*);
this->group= group_list != 0;
- unit= unit_arg;
if (tmp_table_param.sum_func_count && !group_list)
implicit_grouping= TRUE;
@@ -757,12 +774,9 @@
if (alloc_func_list())
goto err;
- DBUG_RETURN(0); // All OK
-
+ res= FALSE;
err:
- delete procedure; /* purecov: inspected */
- procedure= 0;
- DBUG_RETURN(-1); /* purecov: inspected */
+ DBUG_RETURN(res); /* purecov: inspected */
}
@@ -795,7 +809,8 @@
set_allowed_join_cache_types();
/* dump_TABLE_LIST_graph(select_lex, select_lex->leaf_tables); */
- if (convert_join_subqueries_to_semijoins(this))
+ if (convert_max_min_subquery(this) ||
+ convert_join_subqueries_to_semijoins(this))
DBUG_RETURN(1); /* purecov: inspected */
/* dump_TABLE_LIST_graph(select_lex, select_lex->leaf_tables); */
@@ -8599,6 +8614,10 @@
void JOIN_TAB::cleanup()
{
+ DBUG_ENTER("JOIN_TAB::cleanup");
+ DBUG_PRINT("enter", ("table %s.%s",
+ (table ? table->s->db.str : "?"),
+ (table ? table->s->table_name.str : "?")));
delete select;
select= 0;
delete quick;
@@ -8620,6 +8639,7 @@
table->reginfo.join_tab= 0;
}
end_read_record(&read_record);
+ DBUG_VOID_RETURN;
}
@@ -8740,7 +8760,8 @@
Optimization: if not EXPLAIN and we are done with the JOIN,
free all tables.
*/
- bool full= (!select_lex->uncacheable && !thd->lex->describe);
+ bool full= (!(select_lex->uncacheable) &&
+ !thd->lex->describe);
bool can_unlock= full;
DBUG_ENTER("JOIN::join_free");
@@ -8804,6 +8825,7 @@
void JOIN::cleanup(bool full)
{
DBUG_ENTER("JOIN::cleanup");
+ DBUG_PRINT("enter", ("full %u", (uint) full));
if (table)
{
@@ -8829,7 +8851,11 @@
for (tab= join_tab, end= tab+tables; tab != end; tab++)
{
if (tab->table)
+ {
+ DBUG_PRINT("info", ("close index: %s.%s", tab->table->s->db.str,
+ tab->table->s->table_name.str));
tab->table->file->ha_index_or_rnd_end();
+ }
}
}
}
@@ -20307,6 +20333,7 @@
change select_result object of JOIN.
@param res new select_result object
+ @param temp temporary assignment
@retval
FALSE OK
=== modified file 'sql/sql_select.h'
--- sql/sql_select.h 2011-05-02 18:59:16 +0000
+++ sql/sql_select.h 2011-05-10 20:17:04 +0000
@@ -999,6 +999,7 @@
COND *conds, uint og_num, ORDER *order, ORDER *group,
Item *having, ORDER *proc_param, SELECT_LEX *select,
SELECT_LEX_UNIT *unit);
+ bool prepare_stage2();
int optimize();
int reinit();
int init_execution();
2
1
IMO, the Knowledgbase entry for the virtual columns
http://kb.askmonty.org/v/virtual-columns
is among the best and most useful entries we have. It describes the
feature, suggests use cases and demonstrates functionality in a
straightforward manner.
I'd like to see equal care taken to provide the same information for
all user-facing features implemented in MariaDB. If developers can
devote a little time to ensuring such documentation is started, the
community (myself included) will be happy to expand the articles to
usable states. Just ask on -discuss or IRC.
I think KB articles can be started in the feature planning phase, and
updated as the feature is implemented. I imagine the KB acting as an
ongoing feature implementation and use log is more likely to maintain
quality developer input than is asking an entire document be written
from scratch after the feature is merged.
Thoughts?
--
./k
Kurt von Finck
Chief Community And Communications Officer
Monty Program
http://montyprogram.com
2
1
Kristian, Serg, Colin
Thanks for showing an interest in my work with the MariaDB buildsystem
and bakery scripts. During Open DB camp I finally managed to finish
the last pending task and published a blog post about it. So in this
mail I'll summarize once more what was done and highlight how it may
be relevant to MariaDB, so you can pick enhancements that you find
useful.
This blog post has links to the series published in February:
http://openlife.cc/blogs/2011/march/overview-and-archeological-exploration-…
It links to posts 1-7.
And this is the new one:
http://openlife.cc/blogs/2011/may/easy-way-manage-virtualcloud-images-outsi…
let's call it number 8.
So the high level of what I've done is this:
5) http://openlife.cc/blogs/2011/february/mariadb-and-mepsql-buildbot-setups
Instead of the standard BuildSlave class, use my own subclass of
EC2LatentBuildSlave. This allows migrating the buildbot configuration
to EC2 cloud.
Relevance to MariaDB: If you don't want to use a cloud service (faster
turnaround times due to more servers in parallel, but costs more than
what you do now) not much.
However, there is a small value in the refactoring effort itself. Now
you have the runvm stuff hardwired into the test cases. The approach
used with EC2LatentBuildSlave abstracts the handling of virtual
instances into python code, and the test cases are identical whether
you have the classic physical slaves or virtual/cloud slaves. They are
cleaner to read and can be moved between classic slave and virtual
slave without modifications. Unfortunately, to do this, you'd need to
both a) write a subclass of AbstractLatentBuildSlave that does what
runvm does for you today, and b) clean up the runvm parts from your
builds/tests, since I only did so for a small part and we have
probably diverged since then anyway.
As part of (5), I also produced an apt repository, not just standalone
deb packages. But you have implemented that separately too. I advised
you to use something else than ~ for the separator in filename.
6) http://openlife.cc/blogs/2011/february/dealing-cambrian-explosion-12-how-pa…
7) http://openlife.cc/blogs/2011/february/dealing-cambrian-explosion-22-parame…
Parameterize the package name (mysql, mariadb, percona-server,
mepsql...) in the scripts that build packages (with sed and other
shell magic).
See http://bazaar.launchpad.net/~mepsql-committers/mepsql-bakery/trunk/view/hea…
Relevance to MariaDB: Nothing as such, however, if you adopted these
changes, it would enable you to share the packaging scripts and even
buildbot setup with Percona. Possibly also with Linux distributions
that are packaging multiple MySQL forks now, although their problem is
not quite the same. (you produce a fork for many distros, they package
many forks for one distro)
Personally, I like this enhancement both because it centralizes all
the variables that end up in package names and version strings, and
because it would enable all forks (including, theoretically, Oracle
MySQL) to share the same packaging script. This is not at all possible
with how things are packaged traditionally, where you assume the
package name to be constant and it is used as a hardwired value around
all scripts and filenames.
I didn't yet do this for RPMs and don't know when, if ever, I will.
8) http://openlife.cc/blogs/2011/may/easy-way-manage-virtualcloud-images-outsi…
Instead of configuring a vm image and saving it, only use generic
images and run external script on boot.
Relevance to MariaDB: high. I know you complained about this in your
otherwise perfectly automated build system. Even in my small project I
experienced huge gains during development thanks to this approach. You
can use this technique even with your current runvm setup. (You just
need to edit your images one last time to enable fetching of the
remote configuration script.)
That's all. I hope some of this is seen useful.
henrik
--
henrik.ingo(a)avoinelama.fi
+358-40-8211286 skype: henrik.ingo irc: hingo
www.openlife.cc
My LinkedIn profile: http://www.linkedin.com/profile/view?id=9522559
1
0
[Maria-developers] WL#199 New (by Monty): Change Item:name to LEX_STRING
by worklog-noreplyï¼ askmonty.org 02 May '11
by worklog-noreplyï¼ askmonty.org 02 May '11
02 May '11
-----------------------------------------------------------------------
WORKLOG TASK
-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
TASK...........: Change Item:name to LEX_STRING
CREATION DATE..: Mon, 02 May 2011, 15:04
SUPERVISOR.....:
IMPLEMENTOR....:
COPIES TO......:
CATEGORY.......: Server-BackLog
TASK ID........: 199 (http://askmonty.org/worklog/?tid=199)
VERSION........: Server-5.3
STATUS.........: Un-Assigned
PRIORITY.......: 60
WORKED HOURS...: 0
ESTIMATE.......: 6 (hours remain)
ORIG. ESTIMATE.: 6
PROGRESS NOTES:
DESCRIPTION:
Change Item::name, Item::org_name to LEX_STRING objects (from char*)
This allows us to remove Item::max_length and some calls to strlen(Item->name).
Reasons:
- Simpler and faster code
- Allow us to remove calls to strlen()
- Fixes some known bugs where Item->max_length and Item::name is not kept in sync.
ESTIMATED WORK TIME
ESTIMATED COMPLETION DATE
-----------------------------------------------------------------------
WorkLog (v4.0.0)
1
0
Hi!
Here is 2 patches: one cut version - to review, other one full version.
1
0
Re: [Maria-developers] [Commits] Rev 2908: Fixed LP bugs #717577, #724942. in file:///home/igor/maria/maria-5.3-bug717577/
by Sergey Petrunya 25 Apr '11
by Sergey Petrunya 25 Apr '11
25 Apr '11
Hello Igor,
First, an overall comment: there are lots of typos/coding style violations in
the patch. To reduce amount of effort spent on such things, I was just fixing
them as I saw them and I'm attaching the patch with all the fixes (i.e. this
patch should be applied on top of the patch that I was reviewing).
More important comments are bellow, marked with 'psergey:'
On Fri, Mar 25, 2011 at 10:31:19PM -0700, Igor Babaev wrote:
> At file:///home/igor/maria/maria-5.3-bug717577/
>
> ------------------------------------------------------------
> revno: 2908
> revision-id: igor(a)askmonty.org-20110326053117-x50cah9krd4f1345
> parent: wlad(a)montyprogram.com-20110212174322-f7ptnc0u32vasdwy
> committer: Igor Babaev <igor(a)askmonty.org>
> branch nick: maria-5.3-bug717577
> timestamp: Fri 2011-03-25 22:31:17 -0700
> message:
> Fixed LP bugs #717577, #724942.
>
> Both these two bugs happened due to the following problem.
> When a view column is referenced in the query an Item_direct_view_ref
> object is created that is refers to the Item_field for the column.
> All references to the same view column refer to the same Item_field.
> Different references can belong to different AND/OR levels and,
> as a result, can be included in different Item_equal object.
> These Item_equal objects may include different constant objects.
> If these constant objects are substituted for the Item_field created
> for a view column we have a conflict situation when the second
> substitution annuls the first substitution. This leads to
> wrong result sets returned by the query. Bug #724942 demonstrates
> such an erroneous behaviour.
> Test case of the bug #717577 produces wrong result sets because best
> equal fields of the multiple equalities built for different OR levels
> of the WHERE condition differs. The subsitution for the best equal field
> in the second OR branch overwrites the the substitution made for the
> first branch.
>
> To avoid such conflicts we have to substitute for the references
> to the view columns rather than for the underlying field items.
> To make such substitutions possible we have to include into
> multiple equalities references to view columns rather than
> field items created for such columns.
>
> This patch modifies the Item_equal class to include references
> to view columns into multiple equality objects. It also performs
> a clean up of the class methods and adds more comments. The methods
> of the Item_direct_view_ref class that assist substitutions for
> references to view columns has been also added by this patch.
> === modified file 'sql/item.cc'
> --- a/sql/item.cc 2011-02-01 03:33:32 +0000
> +++ b/sql/item.cc 2011-03-26 05:31:17 +0000
> @@ -7226,6 +7233,129 @@
> return FALSE;
> }
>
> +
> +Item_equal *Item_direct_view_ref::find_item_equal(COND_EQUAL *cond_equal)
> +{
> + Item* field_item= real_item();
> + if (field_item->type() != FIELD_ITEM)
> + return NULL;
> + return ((Item_field *) field_item)->find_item_equal(cond_equal);
> +}
> +
> +
> +/**
> + Check whether a reference to field item can be substituted b an equal item
> +
> + @details
> + The function checks whether a substitution of a reference to field item for
> + an equal item is valid.
> +
> + @param arg *arg != NULL && **arg <-> the reference is in the context
> + where substitution for an equal item is valid
> +
> + @note
> + See also the note for Item_field::subst_argument_checker
> +
> + @retval
> + TRUE substitution is valid
> + @retval
> + FALSE otherwise
> +*/
> +bool Item_direct_view_ref::subst_argument_checker(uchar **arg)
> +{
> + bool res= (!(*arg) && (result_type() != STRING_RESULT)) ||
> + ((*arg) && (**arg));
> + if (*arg)
> + **arg= (uchar) 0;
psergey: What is the above for? Do I understand it correctly that this is needed so
that Item_field that this item is wrapping is not substituted?
Please add a comment.
> + return res;
> +}
> +
> +
> +/**
> + Set a pointer to the multiple equality the view field reference belongs to
> + (if any).
> +
> + @details
> + The function looks for a multiple equality containing this item of the type
> + Item_direct_view_ref among those referenced by arg.
> + In the case such equality exists the function does the following.
> + If the found multiple equality contains a constant, then the item
> + is substituted for this constant, otherwise the function sets a pointer
> + to the multiple equality in the item.
> +
> + @param arg reference to list of multiple equalities where
> + the item (this object) is to be looked for
> +
> + @note
> + This function is supposed to be called as a callback parameter in calls
> + of the compile method.
> +
> + @note
> + The function calls Item_field::equal_fields_propagator for the field item
> + this->real_item() to do the job. Then it takes the pointer to equal_item
> + from this field item and assigns it to this->item_equal.
> +
> + @return
> + - pointer to the replacing constant item, if the field item was substituted
> + - pointer to the field item, otherwise.
> +*/
> +
> +Item *Item_direct_view_ref::equal_fields_propagator(uchar *arg)
> +{
> + Item *field_item= real_item();
> + if (field_item->type() != FIELD_ITEM)
> + return this;
> + Item *item= field_item->equal_fields_propagator(arg);
> + set_item_equal(field_item->get_item_equal());
> + field_item->set_item_equal(0);
psergey: Please use NULL here, we use that for pointers.
> + if (item != field_item)
> + return item;
> + return this;
> +}
> +
...
> === modified file 'sql/item_cmpfunc.cc'
> --- a/sql/item_cmpfunc.cc 2011-02-06 04:57:03 +0000
> +++ b/sql/item_cmpfunc.cc 2011-03-26 05:31:17 +0000
> @@ -5516,43 +5516,93 @@
> return 0;
> }
>
> -Item_equal::Item_equal(Item_field *f1, Item_field *f2)
> - : Item_bool_func(), const_item(0), eval_item(0), cond_false(0),
> - compare_as_dates(FALSE)
> -{
> - const_item_cache= 0;
> - fields.push_back(f1);
> - fields.push_back(f2);
> -}
> -
> -Item_equal::Item_equal(Item *c, Item_field *f)
> +
> +/**
> + Construct a minimal multiple equality item
> +
> + @param f1 the first equal item
> + @param f2 the second equal item
> + @param with_const_item TRUE if the first item is constant
> +
> + @details
> + The constructor builds a new item equal object for the equality f1=f2.
> + One if the equal items can be constant. If this is the case it is passed
> + always as the first parameter and the parameter with_const_item serves
> + as an indicator of this case.
> + Currently any non-constant parameter items must refer to an item of the
> + of the type FIELD_ITEM.
psergey:
The above is still true for the case where passed item is an
Item_direct_view_ref which refers to an Item_field. The wording may be
confusing for the new readers, though. Please change to explicitly indicate
that f1 and f2 may point to Item_field or Item_direct_view_ref(Item_field)
> +*/
> +
> +Item_equal::Item_equal(Item *f1, Item *f2, bool with_const_item)
> : Item_bool_func(), eval_item(0), cond_false(0)
> {
> const_item_cache= 0;
> - fields.push_back(f);
> - const_item= c;
> - compare_as_dates= f->is_datetime();
> + with_const= with_const_item;
> + compare_as_dates= with_const_item && f2->is_datetime();
> + equal_items.push_back(f1);
> + equal_items.push_back(f2);
> }
>
>
> +/**
> + Copy constructor for a multiple equality
> +
> + @param item_equal source item for the constructor
> +
> + @details
> + The function creates a copy of an Item_equal object.
> + This constructor is used when an item belongs to a multiple equality
> + of an upper level (an upper AND/OR level or an upper level of a nested
> + outer join).
> +*/
> +
> 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;
> + List_iterator_fast<Item> li(item_equal->equal_items);
> + Item *item;
> while ((item= li++))
> {
> - fields.push_back(item);
> + equal_items.push_back(item);
> }
> - const_item= item_equal->const_item;
> + with_const= item_equal->with_const;
> compare_as_dates= item_equal->compare_as_dates;
> cond_false= item_equal->cond_false;
> }
>
>
> -void Item_equal::compare_const(Item *c)
> +/*
> + @brief
> + Add a constant item to the Item_equal object
> +
> + @param[in] c the constant to add
> + @param[in] f item from the list equal_items the item c is equal to
> + (this parameter is optional)
> +
> + @details
> + The method adds the constant item c to the list equal_items. If the list
> + hasn't not contained any constant item yet the item c is just added
> + to the very beginning of the list. Otherwise the value of c is compared
> + with the value of the constant item from equal_items. If they are not
> + equal cond_false is set to TRUE. This serves as an indicator that this
> + Item_equal is always FALSE.
psergey:
Does function comment really need to duplicate the function body? In my
opinion, the above should be split into multiple comments inside the function
body.
> + The optional parameter f is used to adjust the flag compare_as_dates.
> +*/
> +
> +void Item_equal::add_const(Item *c, Item *f)
> {
> + if (cond_false)
> + return;
> + if (!with_const)
> + {
> + with_const= TRUE;
> + if (f)
> + compare_as_dates= f->is_datetime();
> + equal_items.push_front(c);
> + return;
> + }
> + Item *const_item= get_const();
> if (compare_as_dates)
> {
> cmp.set_datetime_cmp_func(this, &c, &const_item);
...
> @@ -5811,19 +5911,15 @@
> return Item_func::transform(transformer, arg);
> }
>
> +
> void Item_equal::print(String *str, enum_query_type query_type)
> {
> str->append(func_name());
> str->append('(');
> - List_iterator_fast<Item_field> it(fields);
> + List_iterator_fast<Item> it(equal_items);
> Item *item;
> - if (const_item)
> - const_item->print(str, query_type);
> - else
> - {
> - item= it++;
> - item->print(str, query_type);
> - }
> + item= it++;
> + item->print(str, query_type);
> while ((item= it++))
> {
> str->append(',');
> @@ -5834,6 +5930,14 @@
> }
>
>
> +CHARSET_INFO *Item_equal::compare_collation()
psergey: One expects compare_xxx() functions to compare something,
in particular this function looks like it's going to compare some collation.
Could you please rename it to e.g. comparison_collation()?
> +{
> + Item_equal_fields_iterator it(*this);
> + Item *item= it++;
> + return item->collation.collation;
> +}
> +
> +
> /*
> @brief Get the first equal field of multiple equality.
> @param[in] field the field to get equal field to
...
> === modified file 'sql/item_cmpfunc.h'
> --- a/sql/item_cmpfunc.h 2010-10-10 14:18:11 +0000
> +++ b/sql/item_cmpfunc.h 2011-03-26 05:31:17 +0000
> @@ -1672,23 +1707,47 @@
> };
>
>
psergey: Please add a one-line comment describing what this class does.
> -class Item_equal_iterator : public List_iterator_fast<Item_field>
> +class Item_equal_fields_iterator : public List_iterator_fast<Item>
> {
> + Item_equal *item_equal;
> + Item *curr_item;
> 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();
> - }
> + Item_equal_fields_iterator(Item_equal &item_eq)
> + :List_iterator_fast<Item> (item_eq.equal_items)
> + {
> + curr_item= NULL;
> + item_equal= &item_eq;
> + if (item_eq.with_const)
> + {
> + List_iterator_fast<Item> *list_it= (List_iterator_fast<Item> *) this;
psergey: Why do redundant explicit typecasting?
> + curr_item= (*list_it)++;
> + }
> + }
> + Item* operator++(int)
> + {
> + List_iterator_fast<Item> *list_it= (List_iterator_fast<Item> *) this;
psergey: Why do redundant explicit typecasting?
> + curr_item= (*list_it)++;
> + return curr_item;
> + }
> + Item ** ref()
> + {
> + return List_iterator_fast<Item>::ref();
> + }
> + void rewind(void)
> + {
> + List_iterator_fast<Item> *list_it= (List_iterator_fast<Item> *) this;
> + list_it->rewind();
> + if (item_equal->with_const)
> + curr_item= (*list_it)++;
> + }
> + Field *get_curr_field()
> + {
> + Item_field *item= (Item_field *) (curr_item->real_item());
> + return item->field;
> + }
> };
>
> +
> class Item_cond_and :public Item_cond
> {
> public:
>
> === modified file 'sql/sql_select.cc'
> --- a/sql/sql_select.cc 2011-02-11 10:27:35 +0000
> +++ b/sql/sql_select.cc 2011-03-26 05:31:17 +0000
> @@ -9623,7 +9630,8 @@
> args->concat((List<Item> *)&cond_equal.current_level);
> }
> }
> - else if (cond->type() == Item::FUNC_ITEM)
> + else if (cond->type() == Item::FUNC_ITEM ||
> + cond->real_item()->type() == Item::FIELD_ITEM)
psergey:
As far as I understand the last part of the condition is there so
that direct references like
... AND view.column AND ...
are processed with subst_argument_checker/equal_fields_propagator.
Is it intentional that direct references like
... AND base_table.column AND ...
are now processed with subst_argument_checker/equal_fields_propagator as well?
> {
> List<Item> eq_list;
> /*
--
BR
Sergey
--
Sergey Petrunia, Software Developer
Monty Program AB, http://askmonty.org
Blog: http://s.petrunia.net/blog
2
3
Hi, Igor!
On Apr 24, Igor Babaev wrote:
>
> When debugging I discovered the following bad code in sql_select.cc of
> the current 5.3 tree:
> tmp= table->file->read_time(key, 1,
> min(tmp,s->worst_seeks)-1); <= !!!!! ?
> tmp*= record_count;
>
> gannotate says that it appeared in the code after your merge with 5.2.
>
> The fact is that 5.2 contains the correct expression here
> min(tmp,s->worst_seeks)
> not
> min(tmp,s->worst_seeks)-1
>
> As a result if the number of records is 1 then min(tmp,s->worst_seeks)-1
> is equal to 0 and we pass 0 as the last parameter to
> table->file->read_time. Naturally it returns 0.
>
> Will you fix this problem or you'd rather want me to do it?
In 5.2 it is
tmp= record_count*min(tmp,s->worst_seeks);
In 5.3, record_count* is moved to a separate line, so it should just be
tmp= min(tmp,s->worst_seeks);
But it uses table->file->read_time(). Which is defined as
virtual double read_time(uint index, uint ranges, ha_rows rows)
{ return rows2double(ranges+rows); }
so, when ranges=1 and we pass rows=min(tmp,s->worst_seeks)-1, we get the
same value of min(tmp,s->worst_seeks) as the result.
This was the change of introducing handler::keyread_time(), and at the
same time using handler::read_time() where appropriate, to have all
values comparable.
Regards,
Sergei
2
2
Hi,
For merging MySQL into MariaDB, we need to work out what to do about error
code.
The problem occurs as (different) new error messages are added in both MySQL
and MariaDB. When we then merge from MySQL, we get conflicts between the error
numbers.
If we do not handle this somehow, it means that error numbers for a given
error message will be different, either between MySQL and MariaDB, or
alternatively between one version of MariaDB and another (depending on how
conflicts are resolved).
The problem with error code changing is that this makes it much harder for
applications to check error codes and handle errors as it want in a portable
way between MySQL and MariaDB.
I think we have these options:
1. Cooperate with MySQL@Oracle, so that whenever we add an error code in
MariaDB, the corresponding code is also reserved in MySQL (even if not used),
and vice versa.
2. Create different "namespaces" for error codes added to MariaDB and MySQL,
eg. new MariaDB codes are assigned with some offset to MySQL codes, so we
avoid conflicts.
3. Keep MariaDB error code numbers stable, re-assign MySQL error code numbers
when merging from MySQL (I rather dislike this as well because it introduces
incompatibility with MySQL).
4. Keep MySQL error code numbers when merging from MySQL, so that MariaDB-only
errors will fluctuate between releases (I really dislike this option).
It seems option (4) is the best option. Is someone from MySQL/Oracle willing
to work on getting such a procedure running?
Failing that, it seems (3) is the best option. In this case, we need (at
least) to assign a suitable error code range to new MariaDB errors and change
the source code to be able to handle this (eg. maybe we need a
sql/share/errmsg-mariadb.txt or something).
We will also need to handle the error codes already assigned to virtual
columns, which I think already conflict with new MySQL error codes. I would
suggest doing a one-time incompatible change to map them into the MariaDB
range.
So, any hope for getting solution (4) working with MySQL@Oracle? And failing
that, any opinions on how to proceed?
Thanks,
- Kristian.
4
6
19 Apr '11
-----------------------------------------------------------------------
WORKLOG TASK
-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
TASK...........: Roles
CREATION DATE..: Tue, 19 Apr 2011, 10:01
SUPERVISOR.....:
IMPLEMENTOR....:
COPIES TO......:
CATEGORY.......: Server-RawIdeaBin
TASK ID........: 198 (http://askmonty.org/worklog/?tid=198)
VERSION........: WorkLog-4.0
STATUS.........: Un-Assigned
PRIORITY.......: 60
WORKED HOURS...: 0
ESTIMATE.......: 250 (hours remain)
ORIG. ESTIMATE.: 250
PROGRESS NOTES:
DESCRIPTION:
Roles, as defined by the SQL standard.
See also http://forge.mysql.com/worklog/task.php?id=988
ESTIMATED WORK TIME
ESTIMATED COMPLETION DATE
-----------------------------------------------------------------------
WorkLog (v4.0.0)
1
0