From: Roy Lyseng Date: May 2 2011 10:57am Subject: bzr commit into mysql-trunk branch (roy.lyseng:3367) Bug#56881 Bug#11764086 List-Archive: http://lists.mysql.com/commits/136515 X-Bug: 56881,11764086 Message-Id: <20110502105742.899B91F4@tyr67.norway.sun.com> MIME-Version: 1.0 Content-Type: multipart/mixed; boundary="===============2678805776415724777==" --===============2678805776415724777== MIME-Version: 1.0 Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit Content-Disposition: inline #At file:///home/rl136806/mysql/repo/mysql-work3/ based on revid:tor.didriksen@stripped 3367 Roy Lyseng 2011-05-02 Bug#11764086 Bug#56881: Null left operand to NOT IN in WHERE clause behaves differently than real NULL The query that triggers this problem is an outer join query with a NOT IN subquery predicate in the WHERE clause. One of the tables in the outer join contains only one row, and because it is a MyISAM table, const table optimization is applied to it. Now the problem: not_null_tables() for the NOT IN predicate reports that we can ignore NULL-complemented rows for table child, hence the query is converted from a left join to an inner join. This leads the query executor to omit the row with id 2 from the evaluation. As for why the not_null_tables() result for NOT IN is wrong: NOT IN may return TRUE for a row, even if the left-hand expression to NOT IN is NULL (as in NULL NOT IN ()). This is what happens when the query executor evaluates the row with id 2 from the parent table: There is no corresponding row in the child table, a NULL-complemented row should be added, and the predicate NULL NOT IN ( is evaluated (and it should return TRUE). The solution to the problem is to implement not_null_tables() for Item_in_optimizer. If the Item_in_subselect member is "top level", meaning that the original query is an IN predicate, return the accumulated not-null information for the object, otherwise (the predicate is NOT IN) remove the set of tables referred from the left-hand expression from the accumulated not-null information. mysql-test/include/subquery.inc Added test case for bug#11764086. mysql-test/r/subquery_nomat_nosj.result Added test results for bug#11764086. mysql-test/r/subquery_none.result Added test results for bug#11764086. sql/item_cmpfunc.cc Added implementation for Item_in_optimizer::not_null_tables(). sql/item_cmpfunc.h Added interface for Item_in_optimizer::not_null_tables(). modified: mysql-test/include/subquery.inc mysql-test/r/subquery_all.result mysql-test/r/subquery_all_jcl6.result mysql-test/r/subquery_nomat_nosj.result mysql-test/r/subquery_nomat_nosj_jcl6.result mysql-test/r/subquery_none.result mysql-test/r/subquery_none_jcl6.result sql/item_cmpfunc.cc sql/item_cmpfunc.h sql/item_func.h === modified file 'mysql-test/include/subquery.inc' --- a/mysql-test/include/subquery.inc 2011-04-15 08:11:49 +0000 +++ b/mysql-test/include/subquery.inc 2011-05-02 10:57:09 +0000 @@ -4740,8 +4740,6 @@ CREATE VIEW v1 AS SELECT 1 LIKE ( 1 IN ( CREATE VIEW v2 AS SELECT 1 LIKE '%' ESCAPE ( 1 IN ( SELECT 1 ) ); DROP VIEW v1, v2; ---echo End of 5.1 tests. - # # Bug #47904 Incorrect results w/ table subquery, derived SQs, and LEFT JOIN on index # @@ -5101,6 +5099,66 @@ SELECT 1 FROM DROP TABLE t1; +--echo # +--echo # Bug#11764086: Null left operand to NOT IN in WHERE clause +--echo # behaves differently than real NULL +--echo # + +CREATE TABLE parent (id int); +INSERT INTO parent VALUES (1), (2); + +CREATE TABLE child (parent_id int, other int); +INSERT INTO child VALUES (1,NULL); + +--echo # Control query (c.other is always NULL) + +SELECT p.id, c.parent_id +FROM parent p +LEFT JOIN child c +ON p.id = c.parent_id +WHERE c.parent_id NOT IN ( + SELECT parent_id + FROM child + WHERE parent_id = 3 + ); + +--echo # Offending query (c.parent_id is NULL for null-complemented rows only) + +SELECT p.id, c.parent_id +FROM parent p +LEFT JOIN child c +ON p.id = c.parent_id +WHERE c.parent_id NOT IN ( + SELECT parent_id + FROM child + WHERE parent_id = 3 + ); + +--echo # Some syntactic variations with IS FALSE and IS NOT TRUE + +SELECT p.id, c.parent_id +FROM parent p +LEFT JOIN child c +ON p.id = c.parent_id +WHERE c.parent_id IN ( + SELECT parent_id + FROM child + WHERE parent_id = 3 + ) IS NOT TRUE; + +SELECT p.id, c.parent_id +FROM parent p +LEFT JOIN child c +ON p.id = c.parent_id +WHERE c.parent_id IN ( + SELECT parent_id + FROM child + WHERE parent_id = 3 + ) IS FALSE; + +DROP TABLE parent, child; + +--echo # End of test for bug#11764086. --echo End of 5.5 tests. === modified file 'mysql-test/r/subquery_all.result' --- a/mysql-test/r/subquery_all.result 2011-04-15 08:11:49 +0000 +++ b/mysql-test/r/subquery_all.result 2011-05-02 10:57:09 +0000 @@ -5900,7 +5900,6 @@ Note 1249 Select 2 was reduced during op CREATE VIEW v1 AS SELECT 1 LIKE ( 1 IN ( SELECT 1 ) ); CREATE VIEW v2 AS SELECT 1 LIKE '%' ESCAPE ( 1 IN ( SELECT 1 ) ); DROP VIEW v1, v2; -End of 5.1 tests. Set up test tables. CREATE TABLE t1 ( t1_id INT UNSIGNED, @@ -6242,6 +6241,67 @@ SELECT 1 FROM 1) FROM t1) AS e; ERROR 21000: Operand should contain 1 column(s) DROP TABLE t1; +# +# Bug#11764086: Null left operand to NOT IN in WHERE clause +# behaves differently than real NULL +# +CREATE TABLE parent (id int); +INSERT INTO parent VALUES (1), (2); +CREATE TABLE child (parent_id int, other int); +INSERT INTO child VALUES (1,NULL); +# Control query (c.other is always NULL) +SELECT p.id, c.parent_id +FROM parent p +LEFT JOIN child c +ON p.id = c.parent_id +WHERE c.parent_id NOT IN ( +SELECT parent_id +FROM child +WHERE parent_id = 3 +); +id parent_id +1 1 +2 NULL +# Offending query (c.parent_id is NULL for null-complemented rows only) +SELECT p.id, c.parent_id +FROM parent p +LEFT JOIN child c +ON p.id = c.parent_id +WHERE c.parent_id NOT IN ( +SELECT parent_id +FROM child +WHERE parent_id = 3 +); +id parent_id +1 1 +2 NULL +# Some syntactic variations with IS FALSE and IS NOT TRUE +SELECT p.id, c.parent_id +FROM parent p +LEFT JOIN child c +ON p.id = c.parent_id +WHERE c.parent_id IN ( +SELECT parent_id +FROM child +WHERE parent_id = 3 +) IS NOT TRUE; +id parent_id +1 1 +2 NULL +SELECT p.id, c.parent_id +FROM parent p +LEFT JOIN child c +ON p.id = c.parent_id +WHERE c.parent_id IN ( +SELECT parent_id +FROM child +WHERE parent_id = 3 +) IS FALSE; +id parent_id +1 1 +2 NULL +DROP TABLE parent, child; +# End of test for bug#11764086. End of 5.5 tests. # # BUG#48920: COUNT DISTINCT returns 1 for NULL values when in a subquery === modified file 'mysql-test/r/subquery_all_jcl6.result' --- a/mysql-test/r/subquery_all_jcl6.result 2011-04-28 11:53:14 +0000 +++ b/mysql-test/r/subquery_all_jcl6.result 2011-05-02 10:57:09 +0000 @@ -5904,7 +5904,6 @@ Note 1249 Select 2 was reduced during op CREATE VIEW v1 AS SELECT 1 LIKE ( 1 IN ( SELECT 1 ) ); CREATE VIEW v2 AS SELECT 1 LIKE '%' ESCAPE ( 1 IN ( SELECT 1 ) ); DROP VIEW v1, v2; -End of 5.1 tests. Set up test tables. CREATE TABLE t1 ( t1_id INT UNSIGNED, @@ -6246,6 +6245,67 @@ SELECT 1 FROM 1) FROM t1) AS e; ERROR 21000: Operand should contain 1 column(s) DROP TABLE t1; +# +# Bug#11764086: Null left operand to NOT IN in WHERE clause +# behaves differently than real NULL +# +CREATE TABLE parent (id int); +INSERT INTO parent VALUES (1), (2); +CREATE TABLE child (parent_id int, other int); +INSERT INTO child VALUES (1,NULL); +# Control query (c.other is always NULL) +SELECT p.id, c.parent_id +FROM parent p +LEFT JOIN child c +ON p.id = c.parent_id +WHERE c.parent_id NOT IN ( +SELECT parent_id +FROM child +WHERE parent_id = 3 +); +id parent_id +1 1 +2 NULL +# Offending query (c.parent_id is NULL for null-complemented rows only) +SELECT p.id, c.parent_id +FROM parent p +LEFT JOIN child c +ON p.id = c.parent_id +WHERE c.parent_id NOT IN ( +SELECT parent_id +FROM child +WHERE parent_id = 3 +); +id parent_id +1 1 +2 NULL +# Some syntactic variations with IS FALSE and IS NOT TRUE +SELECT p.id, c.parent_id +FROM parent p +LEFT JOIN child c +ON p.id = c.parent_id +WHERE c.parent_id IN ( +SELECT parent_id +FROM child +WHERE parent_id = 3 +) IS NOT TRUE; +id parent_id +1 1 +2 NULL +SELECT p.id, c.parent_id +FROM parent p +LEFT JOIN child c +ON p.id = c.parent_id +WHERE c.parent_id IN ( +SELECT parent_id +FROM child +WHERE parent_id = 3 +) IS FALSE; +id parent_id +1 1 +2 NULL +DROP TABLE parent, child; +# End of test for bug#11764086. End of 5.5 tests. # # BUG#48920: COUNT DISTINCT returns 1 for NULL values when in a subquery === modified file 'mysql-test/r/subquery_nomat_nosj.result' --- a/mysql-test/r/subquery_nomat_nosj.result 2011-04-15 08:11:49 +0000 +++ b/mysql-test/r/subquery_nomat_nosj.result 2011-05-02 10:57:09 +0000 @@ -5900,7 +5900,6 @@ Note 1249 Select 2 was reduced during op CREATE VIEW v1 AS SELECT 1 LIKE ( 1 IN ( SELECT 1 ) ); CREATE VIEW v2 AS SELECT 1 LIKE '%' ESCAPE ( 1 IN ( SELECT 1 ) ); DROP VIEW v1, v2; -End of 5.1 tests. Set up test tables. CREATE TABLE t1 ( t1_id INT UNSIGNED, @@ -6242,6 +6241,67 @@ SELECT 1 FROM 1) FROM t1) AS e; ERROR 21000: Operand should contain 1 column(s) DROP TABLE t1; +# +# Bug#11764086: Null left operand to NOT IN in WHERE clause +# behaves differently than real NULL +# +CREATE TABLE parent (id int); +INSERT INTO parent VALUES (1), (2); +CREATE TABLE child (parent_id int, other int); +INSERT INTO child VALUES (1,NULL); +# Control query (c.other is always NULL) +SELECT p.id, c.parent_id +FROM parent p +LEFT JOIN child c +ON p.id = c.parent_id +WHERE c.parent_id NOT IN ( +SELECT parent_id +FROM child +WHERE parent_id = 3 +); +id parent_id +1 1 +2 NULL +# Offending query (c.parent_id is NULL for null-complemented rows only) +SELECT p.id, c.parent_id +FROM parent p +LEFT JOIN child c +ON p.id = c.parent_id +WHERE c.parent_id NOT IN ( +SELECT parent_id +FROM child +WHERE parent_id = 3 +); +id parent_id +1 1 +2 NULL +# Some syntactic variations with IS FALSE and IS NOT TRUE +SELECT p.id, c.parent_id +FROM parent p +LEFT JOIN child c +ON p.id = c.parent_id +WHERE c.parent_id IN ( +SELECT parent_id +FROM child +WHERE parent_id = 3 +) IS NOT TRUE; +id parent_id +1 1 +2 NULL +SELECT p.id, c.parent_id +FROM parent p +LEFT JOIN child c +ON p.id = c.parent_id +WHERE c.parent_id IN ( +SELECT parent_id +FROM child +WHERE parent_id = 3 +) IS FALSE; +id parent_id +1 1 +2 NULL +DROP TABLE parent, child; +# End of test for bug#11764086. End of 5.5 tests. # # BUG#48920: COUNT DISTINCT returns 1 for NULL values when in a subquery === modified file 'mysql-test/r/subquery_nomat_nosj_jcl6.result' --- a/mysql-test/r/subquery_nomat_nosj_jcl6.result 2011-04-28 11:53:14 +0000 +++ b/mysql-test/r/subquery_nomat_nosj_jcl6.result 2011-05-02 10:57:09 +0000 @@ -5904,7 +5904,6 @@ Note 1249 Select 2 was reduced during op CREATE VIEW v1 AS SELECT 1 LIKE ( 1 IN ( SELECT 1 ) ); CREATE VIEW v2 AS SELECT 1 LIKE '%' ESCAPE ( 1 IN ( SELECT 1 ) ); DROP VIEW v1, v2; -End of 5.1 tests. Set up test tables. CREATE TABLE t1 ( t1_id INT UNSIGNED, @@ -6246,6 +6245,67 @@ SELECT 1 FROM 1) FROM t1) AS e; ERROR 21000: Operand should contain 1 column(s) DROP TABLE t1; +# +# Bug#11764086: Null left operand to NOT IN in WHERE clause +# behaves differently than real NULL +# +CREATE TABLE parent (id int); +INSERT INTO parent VALUES (1), (2); +CREATE TABLE child (parent_id int, other int); +INSERT INTO child VALUES (1,NULL); +# Control query (c.other is always NULL) +SELECT p.id, c.parent_id +FROM parent p +LEFT JOIN child c +ON p.id = c.parent_id +WHERE c.parent_id NOT IN ( +SELECT parent_id +FROM child +WHERE parent_id = 3 +); +id parent_id +1 1 +2 NULL +# Offending query (c.parent_id is NULL for null-complemented rows only) +SELECT p.id, c.parent_id +FROM parent p +LEFT JOIN child c +ON p.id = c.parent_id +WHERE c.parent_id NOT IN ( +SELECT parent_id +FROM child +WHERE parent_id = 3 +); +id parent_id +1 1 +2 NULL +# Some syntactic variations with IS FALSE and IS NOT TRUE +SELECT p.id, c.parent_id +FROM parent p +LEFT JOIN child c +ON p.id = c.parent_id +WHERE c.parent_id IN ( +SELECT parent_id +FROM child +WHERE parent_id = 3 +) IS NOT TRUE; +id parent_id +1 1 +2 NULL +SELECT p.id, c.parent_id +FROM parent p +LEFT JOIN child c +ON p.id = c.parent_id +WHERE c.parent_id IN ( +SELECT parent_id +FROM child +WHERE parent_id = 3 +) IS FALSE; +id parent_id +1 1 +2 NULL +DROP TABLE parent, child; +# End of test for bug#11764086. End of 5.5 tests. # # BUG#48920: COUNT DISTINCT returns 1 for NULL values when in a subquery === modified file 'mysql-test/r/subquery_none.result' --- a/mysql-test/r/subquery_none.result 2011-04-15 08:11:49 +0000 +++ b/mysql-test/r/subquery_none.result 2011-05-02 10:57:09 +0000 @@ -5899,7 +5899,6 @@ Note 1249 Select 2 was reduced during op CREATE VIEW v1 AS SELECT 1 LIKE ( 1 IN ( SELECT 1 ) ); CREATE VIEW v2 AS SELECT 1 LIKE '%' ESCAPE ( 1 IN ( SELECT 1 ) ); DROP VIEW v1, v2; -End of 5.1 tests. Set up test tables. CREATE TABLE t1 ( t1_id INT UNSIGNED, @@ -6241,6 +6240,67 @@ SELECT 1 FROM 1) FROM t1) AS e; ERROR 21000: Operand should contain 1 column(s) DROP TABLE t1; +# +# Bug#11764086: Null left operand to NOT IN in WHERE clause +# behaves differently than real NULL +# +CREATE TABLE parent (id int); +INSERT INTO parent VALUES (1), (2); +CREATE TABLE child (parent_id int, other int); +INSERT INTO child VALUES (1,NULL); +# Control query (c.other is always NULL) +SELECT p.id, c.parent_id +FROM parent p +LEFT JOIN child c +ON p.id = c.parent_id +WHERE c.parent_id NOT IN ( +SELECT parent_id +FROM child +WHERE parent_id = 3 +); +id parent_id +1 1 +2 NULL +# Offending query (c.parent_id is NULL for null-complemented rows only) +SELECT p.id, c.parent_id +FROM parent p +LEFT JOIN child c +ON p.id = c.parent_id +WHERE c.parent_id NOT IN ( +SELECT parent_id +FROM child +WHERE parent_id = 3 +); +id parent_id +1 1 +2 NULL +# Some syntactic variations with IS FALSE and IS NOT TRUE +SELECT p.id, c.parent_id +FROM parent p +LEFT JOIN child c +ON p.id = c.parent_id +WHERE c.parent_id IN ( +SELECT parent_id +FROM child +WHERE parent_id = 3 +) IS NOT TRUE; +id parent_id +1 1 +2 NULL +SELECT p.id, c.parent_id +FROM parent p +LEFT JOIN child c +ON p.id = c.parent_id +WHERE c.parent_id IN ( +SELECT parent_id +FROM child +WHERE parent_id = 3 +) IS FALSE; +id parent_id +1 1 +2 NULL +DROP TABLE parent, child; +# End of test for bug#11764086. End of 5.5 tests. # # BUG#48920: COUNT DISTINCT returns 1 for NULL values when in a subquery === modified file 'mysql-test/r/subquery_none_jcl6.result' --- a/mysql-test/r/subquery_none_jcl6.result 2011-04-28 11:53:14 +0000 +++ b/mysql-test/r/subquery_none_jcl6.result 2011-05-02 10:57:09 +0000 @@ -5903,7 +5903,6 @@ Note 1249 Select 2 was reduced during op CREATE VIEW v1 AS SELECT 1 LIKE ( 1 IN ( SELECT 1 ) ); CREATE VIEW v2 AS SELECT 1 LIKE '%' ESCAPE ( 1 IN ( SELECT 1 ) ); DROP VIEW v1, v2; -End of 5.1 tests. Set up test tables. CREATE TABLE t1 ( t1_id INT UNSIGNED, @@ -6245,6 +6244,67 @@ SELECT 1 FROM 1) FROM t1) AS e; ERROR 21000: Operand should contain 1 column(s) DROP TABLE t1; +# +# Bug#11764086: Null left operand to NOT IN in WHERE clause +# behaves differently than real NULL +# +CREATE TABLE parent (id int); +INSERT INTO parent VALUES (1), (2); +CREATE TABLE child (parent_id int, other int); +INSERT INTO child VALUES (1,NULL); +# Control query (c.other is always NULL) +SELECT p.id, c.parent_id +FROM parent p +LEFT JOIN child c +ON p.id = c.parent_id +WHERE c.parent_id NOT IN ( +SELECT parent_id +FROM child +WHERE parent_id = 3 +); +id parent_id +1 1 +2 NULL +# Offending query (c.parent_id is NULL for null-complemented rows only) +SELECT p.id, c.parent_id +FROM parent p +LEFT JOIN child c +ON p.id = c.parent_id +WHERE c.parent_id NOT IN ( +SELECT parent_id +FROM child +WHERE parent_id = 3 +); +id parent_id +1 1 +2 NULL +# Some syntactic variations with IS FALSE and IS NOT TRUE +SELECT p.id, c.parent_id +FROM parent p +LEFT JOIN child c +ON p.id = c.parent_id +WHERE c.parent_id IN ( +SELECT parent_id +FROM child +WHERE parent_id = 3 +) IS NOT TRUE; +id parent_id +1 1 +2 NULL +SELECT p.id, c.parent_id +FROM parent p +LEFT JOIN child c +ON p.id = c.parent_id +WHERE c.parent_id IN ( +SELECT parent_id +FROM child +WHERE parent_id = 3 +) IS FALSE; +id parent_id +1 1 +2 NULL +DROP TABLE parent, child; +# End of test for bug#11764086. End of 5.5 tests. # # BUG#48920: COUNT DISTINCT returns 1 for NULL values when in a subquery === modified file 'sql/item_cmpfunc.cc' --- a/sql/item_cmpfunc.cc 2011-04-26 08:49:10 +0000 +++ b/sql/item_cmpfunc.cc 2011-05-02 10:57:09 +0000 @@ -1791,6 +1791,24 @@ void Item_in_optimizer::fix_after_pullou const_item_cache&= args[1]->const_item(); } +table_map Item_in_optimizer::not_null_tables() const +{ + table_map not_null_tables_value= Item_bool_func::not_null_tables(); + + if (!(static_cast(args[1]))->is_top_level_item()) + { + /* + This is a NOT IN subquery predicate (or equivalent). Null values passed + from outer tables and used in the left-hand expression of the predicate + must be considered in the evaluation, hence filter out these tables + from the set of null-rejecting tables. + */ + not_null_tables_value&= ~args[0]->not_null_tables(); + } + return not_null_tables_value; +} + + /** The implementation of optimized \ [NOT] IN \ predicates. The implementation works as follows. === modified file 'sql/item_cmpfunc.h' --- a/sql/item_cmpfunc.h 2011-03-22 11:44:40 +0000 +++ b/sql/item_cmpfunc.h 2011-05-02 10:57:09 +0000 @@ -272,6 +272,7 @@ public: bool fix_left(THD *thd, Item **ref); void fix_after_pullout(st_select_lex *parent_select, st_select_lex *removed_select, Item **ref); + virtual table_map not_null_tables() const; bool is_null(); longlong val_int(); void cleanup(); === modified file 'sql/item_func.h' --- a/sql/item_func.h 2011-04-15 09:04:21 +0000 +++ b/sql/item_func.h 2011-05-02 10:57:09 +0000 @@ -37,7 +37,11 @@ protected: uint allowed_arg_cols; public: uint arg_count; - table_map used_tables_cache, not_null_tables_cache; + /// Value used in calculation of result of used_tables() + table_map used_tables_cache; + /// Value used in calculation of result of not_null_tables() + table_map not_null_tables_cache; + /// Value used in calculation of result of const_item() bool const_item_cache; enum Functype { UNKNOWN_FUNC,EQ_FUNC,EQUAL_FUNC,NE_FUNC,LT_FUNC,LE_FUNC, GE_FUNC,GT_FUNC,FT_FUNC, --===============2678805776415724777== MIME-Version: 1.0 Content-Type: text/bzr-bundle; charset="us-ascii"; name="bzr/roy.lyseng@stripped" Content-Transfer-Encoding: 7bit Content-Disposition: inline # Bazaar merge directive format 2 (Bazaar 0.90) # revision_id: roy.lyseng@stripped # target_branch: file:///home/rl136806/mysql/repo/mysql-work3/ # testament_sha1: cfba93cb9c68c1789c64afa83aa21eb6e1c25338 # timestamp: 2011-05-02 12:57:42 +0200 # base_revision_id: tor.didriksen@stripped\ # sy51s25lk29u48kg # # Begin bundle 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 8XckU4UJALl73BA= --===============2678805776415724777==--