From: Ole John Aske Date: January 17 2011 12:53pm Subject: bzr commit into mysql-trunk branch (ole.john.aske:3504) Bug#56690 List-Archive: http://lists.mysql.com/commits/128960 X-Bug: 56690 Message-Id: <20110117125335.8C3AE223@fimafeng09.norway.sun.com> MIME-Version: 1.0 Content-Type: multipart/mixed; boundary="===============4334103493024927536==" --===============4334103493024927536== MIME-Version: 1.0 Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit Content-Disposition: inline #At file:///net/fimafeng09/export/home/tmp/oleja/mysql/mysql-trunk/ based on revid:ole.john.aske@stripped 3504 Ole John Aske 2011-01-17 Updated fix for bug#56690 'Wrong results with subquery with GROUP BY inside < ANY clause' Addition testcases has been added according to suggestion from Evgeny P. A subquery of the form : 1) SELECT ... WHERE < ANY(select ...) Is transformed into the form by the optimizer: 2) SELECT ... WHERE < (select MAX()...) The Min/Max aggregation of subquery columns is implemented in 'class select_max_min_finder_subselect'. The handling of NULL values in this implementation was incorrect as they was interpreted as a NULL-value being '>' than any other value being compared. This is incorrect wrt. SQL semantics which specifies that NULL values are 'undefined' and should be removed as soon as a non-NULL value is encountered. This fix changes implementation of all select_max_min_finder_subselect::cmp_() methods to follow the correct SQL semantics as described above. (Which also simplifies the logic IMHO) It also changes the methods to be 'private' within class select_max_min_finder_subselect. modified: mysql-test/include/subquery.inc mysql-test/r/subquery_nomat_nosj.result mysql-test/r/subquery_none.result sql/sql_class.cc sql/sql_class.h === modified file 'mysql-test/include/subquery.inc' --- a/mysql-test/include/subquery.inc 2011-01-12 12:21:16 +0000 +++ b/mysql-test/include/subquery.inc 2011-01-17 12:53:26 +0000 @@ -4999,6 +4999,76 @@ SELECT * FROM t1 DROP TABLE t1,t1s,t2s; +--echo # +--echo # Bug #56690 Wrong results with subquery with +--echo # GROUP BY inside < ANY clause +--echo # + +CREATE TABLE t1 ( + pk INT NOT NULL PRIMARY KEY, + number INT, + KEY key_number (number) +); +INSERT INTO t1 VALUES (8,8); + +CREATE TABLE t2 ( + pk INT NOT NULL PRIMARY KEY, + number INT, + KEY key_number (number) +); + +INSERT INTO t2 VALUES (1,2); +INSERT INTO t2 VALUES (2,8); +INSERT INTO t2 VALUES (3,NULL); +INSERT INTO t2 VALUES (4,166); + +SELECT * FROM t1 WHERE t1.number < ANY(SELECT number FROM t2 GROUP BY number); +SELECT * FROM t1 WHERE t1.number < ANY(SELECT number FROM t2); + +DROP TABLE t1,t2; + +# More testing as suggested by Evgeny P. +CREATE TABLE t1 ( + pk INT NOT NULL PRIMARY KEY, + number INT, + KEY key_number (number) +); +INSERT INTO t1 VALUES (8,8),(1,null); + +CREATE TABLE t2 ( + pk INT NOT NULL PRIMARY KEY, + number INT, + KEY key_number (number) +); + +SELECT * FROM t1 WHERE t1.number< ANY(SELECT number FROM t2 GROUP BY number); +SELECT * FROM t1 WHERE t1.number< ANY(SELECT number FROM t2); + +SELECT * FROM t1 WHERE t1.number> ANY(SELECT number FROM t2 GROUP BY number); +SELECT * FROM t1 WHERE t1.number> ANY(SELECT number FROM t2); + +INSERT INTO t2 VALUES (3,NULL); +INSERT INTO t2 VALUES (4,166); + +SELECT * FROM t1 WHERE t1.number< ANY(SELECT number FROM t2 GROUP BY number); +SELECT * FROM t1 WHERE t1.number< ANY(SELECT number FROM t2); + +SELECT * FROM t1 WHERE t1.number> ANY(SELECT number FROM t2 GROUP BY number); +SELECT * FROM t1 WHERE t1.number> ANY(SELECT number FROM t2); + +DELETE FROM t2; +INSERT INTO t2 VALUES (1,2); +INSERT INTO t2 VALUES (3,NULL); +INSERT INTO t2 VALUES (2,8); + +SELECT * FROM t1 WHERE t1.number< ANY(SELECT number FROM t2 GROUP BY number); +SELECT * FROM t1 WHERE t1.number< ANY(SELECT number FROM t2); + +SELECT * FROM t1 WHERE t1.number> ANY(SELECT number FROM t2 GROUP BY number); +SELECT * FROM t1 WHERE t1.number> ANY(SELECT number FROM t2); + +DROP TABLE t1,t2; + --echo End of 5.1 tests --echo # === modified file 'mysql-test/r/subquery_nomat_nosj.result' --- a/mysql-test/r/subquery_nomat_nosj.result 2011-01-12 12:21:16 +0000 +++ b/mysql-test/r/subquery_nomat_nosj.result 2011-01-17 12:53:26 +0000 @@ -6152,6 +6152,78 @@ HAVING t2s.i = 999 ) IS UNKNOWN; i DROP TABLE t1,t1s,t2s; +# +# Bug #56690 Wrong results with subquery with +# GROUP BY inside < ANY clause +# +CREATE TABLE t1 ( +pk INT NOT NULL PRIMARY KEY, +number INT, +KEY key_number (number) +); +INSERT INTO t1 VALUES (8,8); +CREATE TABLE t2 ( +pk INT NOT NULL PRIMARY KEY, +number INT, +KEY key_number (number) +); +INSERT INTO t2 VALUES (1,2); +INSERT INTO t2 VALUES (2,8); +INSERT INTO t2 VALUES (3,NULL); +INSERT INTO t2 VALUES (4,166); +SELECT * FROM t1 WHERE t1.number < ANY(SELECT number FROM t2 GROUP BY number); +pk number +8 8 +SELECT * FROM t1 WHERE t1.number < ANY(SELECT number FROM t2); +pk number +8 8 +DROP TABLE t1,t2; +CREATE TABLE t1 ( +pk INT NOT NULL PRIMARY KEY, +number INT, +KEY key_number (number) +); +INSERT INTO t1 VALUES (8,8),(1,null); +CREATE TABLE t2 ( +pk INT NOT NULL PRIMARY KEY, +number INT, +KEY key_number (number) +); +SELECT * FROM t1 WHERE t1.number< ANY(SELECT number FROM t2 GROUP BY number); +pk number +SELECT * FROM t1 WHERE t1.number< ANY(SELECT number FROM t2); +pk number +SELECT * FROM t1 WHERE t1.number> ANY(SELECT number FROM t2 GROUP BY number); +pk number +SELECT * FROM t1 WHERE t1.number> ANY(SELECT number FROM t2); +pk number +INSERT INTO t2 VALUES (3,NULL); +INSERT INTO t2 VALUES (4,166); +SELECT * FROM t1 WHERE t1.number< ANY(SELECT number FROM t2 GROUP BY number); +pk number +8 8 +SELECT * FROM t1 WHERE t1.number< ANY(SELECT number FROM t2); +pk number +8 8 +SELECT * FROM t1 WHERE t1.number> ANY(SELECT number FROM t2 GROUP BY number); +pk number +SELECT * FROM t1 WHERE t1.number> ANY(SELECT number FROM t2); +pk number +DELETE FROM t2; +INSERT INTO t2 VALUES (1,2); +INSERT INTO t2 VALUES (3,NULL); +INSERT INTO t2 VALUES (2,8); +SELECT * FROM t1 WHERE t1.number< ANY(SELECT number FROM t2 GROUP BY number); +pk number +SELECT * FROM t1 WHERE t1.number< ANY(SELECT number FROM t2); +pk number +SELECT * FROM t1 WHERE t1.number> ANY(SELECT number FROM t2 GROUP BY number); +pk number +8 8 +SELECT * FROM t1 WHERE t1.number> ANY(SELECT number FROM t2); +pk number +8 8 +DROP TABLE t1,t2; End of 5.1 tests # # BUG#50257: Missing info in REF column of the EXPLAIN === modified file 'mysql-test/r/subquery_none.result' --- a/mysql-test/r/subquery_none.result 2011-01-12 12:21:16 +0000 +++ b/mysql-test/r/subquery_none.result 2011-01-17 12:53:26 +0000 @@ -6151,6 +6151,78 @@ HAVING t2s.i = 999 ) IS UNKNOWN; i DROP TABLE t1,t1s,t2s; +# +# Bug #56690 Wrong results with subquery with +# GROUP BY inside < ANY clause +# +CREATE TABLE t1 ( +pk INT NOT NULL PRIMARY KEY, +number INT, +KEY key_number (number) +); +INSERT INTO t1 VALUES (8,8); +CREATE TABLE t2 ( +pk INT NOT NULL PRIMARY KEY, +number INT, +KEY key_number (number) +); +INSERT INTO t2 VALUES (1,2); +INSERT INTO t2 VALUES (2,8); +INSERT INTO t2 VALUES (3,NULL); +INSERT INTO t2 VALUES (4,166); +SELECT * FROM t1 WHERE t1.number < ANY(SELECT number FROM t2 GROUP BY number); +pk number +8 8 +SELECT * FROM t1 WHERE t1.number < ANY(SELECT number FROM t2); +pk number +8 8 +DROP TABLE t1,t2; +CREATE TABLE t1 ( +pk INT NOT NULL PRIMARY KEY, +number INT, +KEY key_number (number) +); +INSERT INTO t1 VALUES (8,8),(1,null); +CREATE TABLE t2 ( +pk INT NOT NULL PRIMARY KEY, +number INT, +KEY key_number (number) +); +SELECT * FROM t1 WHERE t1.number< ANY(SELECT number FROM t2 GROUP BY number); +pk number +SELECT * FROM t1 WHERE t1.number< ANY(SELECT number FROM t2); +pk number +SELECT * FROM t1 WHERE t1.number> ANY(SELECT number FROM t2 GROUP BY number); +pk number +SELECT * FROM t1 WHERE t1.number> ANY(SELECT number FROM t2); +pk number +INSERT INTO t2 VALUES (3,NULL); +INSERT INTO t2 VALUES (4,166); +SELECT * FROM t1 WHERE t1.number< ANY(SELECT number FROM t2 GROUP BY number); +pk number +8 8 +SELECT * FROM t1 WHERE t1.number< ANY(SELECT number FROM t2); +pk number +8 8 +SELECT * FROM t1 WHERE t1.number> ANY(SELECT number FROM t2 GROUP BY number); +pk number +SELECT * FROM t1 WHERE t1.number> ANY(SELECT number FROM t2); +pk number +DELETE FROM t2; +INSERT INTO t2 VALUES (1,2); +INSERT INTO t2 VALUES (3,NULL); +INSERT INTO t2 VALUES (2,8); +SELECT * FROM t1 WHERE t1.number< ANY(SELECT number FROM t2 GROUP BY number); +pk number +SELECT * FROM t1 WHERE t1.number< ANY(SELECT number FROM t2); +pk number +SELECT * FROM t1 WHERE t1.number> ANY(SELECT number FROM t2 GROUP BY number); +pk number +8 8 +SELECT * FROM t1 WHERE t1.number> ANY(SELECT number FROM t2); +pk number +8 8 +DROP TABLE t1,t2; End of 5.1 tests # # BUG#50257: Missing info in REF column of the EXPLAIN === modified file 'sql/sql_class.cc' --- a/sql/sql_class.cc 2010-12-17 16:14:15 +0000 +++ b/sql/sql_class.cc 2011-01-17 12:53:26 +0000 @@ -2514,26 +2514,24 @@ bool select_max_min_finder_subselect::cm { Item *maxmin= ((Item_singlerow_subselect *)item)->element_index(0); double val1= cache->val_real(), val2= maxmin->val_real(); - if (fmax) - return (cache->null_value && !maxmin->null_value) || - (!cache->null_value && !maxmin->null_value && - val1 > val2); - return (maxmin->null_value && !cache->null_value) || - (!cache->null_value && !maxmin->null_value && - val1 < val2); + if (cache->null_value) + return false; + else if (maxmin->null_value) + return true; + else + return (fmax) ? (val1 > val2) : (val1 < val2); } bool select_max_min_finder_subselect::cmp_int() { Item *maxmin= ((Item_singlerow_subselect *)item)->element_index(0); longlong val1= cache->val_int(), val2= maxmin->val_int(); - if (fmax) - return (cache->null_value && !maxmin->null_value) || - (!cache->null_value && !maxmin->null_value && - val1 > val2); - return (maxmin->null_value && !cache->null_value) || - (!cache->null_value && !maxmin->null_value && - val1 < val2); + if (cache->null_value) + return false; + else if (maxmin->null_value) + return true; + else + return (fmax) ? (val1 > val2) : (val1 < val2); } bool select_max_min_finder_subselect::cmp_decimal() @@ -2541,13 +2539,14 @@ bool select_max_min_finder_subselect::cm Item *maxmin= ((Item_singlerow_subselect *)item)->element_index(0); my_decimal cval, *cvalue= cache->val_decimal(&cval); my_decimal mval, *mvalue= maxmin->val_decimal(&mval); - if (fmax) - return (cache->null_value && !maxmin->null_value) || - (!cache->null_value && !maxmin->null_value && - my_decimal_cmp(cvalue, mvalue) > 0) ; - return (maxmin->null_value && !cache->null_value) || - (!cache->null_value && !maxmin->null_value && - my_decimal_cmp(cvalue,mvalue) < 0); + if (cache->null_value) + return false; + else if (maxmin->null_value) + return true; + else + return (fmax) + ? (my_decimal_cmp(cvalue,mvalue) > 0) + : (my_decimal_cmp(cvalue,mvalue) < 0); } bool select_max_min_finder_subselect::cmp_str() @@ -2560,13 +2559,14 @@ bool select_max_min_finder_subselect::cm */ val1= cache->val_str(&buf1); val2= maxmin->val_str(&buf1); - if (fmax) - return (cache->null_value && !maxmin->null_value) || - (!cache->null_value && !maxmin->null_value && - sortcmp(val1, val2, cache->collation.collation) > 0) ; - return (maxmin->null_value && !cache->null_value) || - (!cache->null_value && !maxmin->null_value && - sortcmp(val1, val2, cache->collation.collation) < 0); + if (cache->null_value) + return false; + else if (maxmin->null_value) + return true; + else + return (fmax) + ? (sortcmp(val1, val2, cache->collation.collation) > 0) + : (sortcmp(val1, val2, cache->collation.collation) < 0); } bool select_exists_subselect::send_data(List &items) === modified file 'sql/sql_class.h' --- a/sql/sql_class.h 2010-12-29 00:38:59 +0000 +++ b/sql/sql_class.h 2011-01-17 12:53:26 +0000 @@ -3353,6 +3353,7 @@ public: {} void cleanup(); bool send_data(List &items); +private: bool cmp_real(); bool cmp_int(); bool cmp_decimal(); --===============4334103493024927536== MIME-Version: 1.0 Content-Type: text/bzr-bundle; charset="us-ascii"; name="bzr/ole.john.aske@stripped" Content-Transfer-Encoding: 7bit Content-Disposition: inline # Bazaar merge directive format 2 (Bazaar 0.90) # revision_id: ole.john.aske@stripped\ # 9f9dls9nx1lu2m9f # target_branch: file:///net/fimafeng09/export/home/tmp/oleja/mysql\ # /mysql-trunk/ # testament_sha1: b59355f340dfa2ca491aae986091984a37b1dc99 # timestamp: 2011-01-17 13:53:35 +0100 # source_branch: file:///net/fimafeng09/export/home/tmp/oleja/mysql\ # /mysql-5.5/ # base_revision_id: ole.john.aske@stripped\ # 77kfco4xs4geosam # # Begin bundle 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 MvtRuk2vRln2P7i7kinChIb82Tjg --===============4334103493024927536==--