From: Roy Lyseng Date: May 5 2011 7:42am Subject: bzr commit into mysql-trunk branch (roy.lyseng:3368) Bug#56881 Bug#11764086 List-Archive: http://lists.mysql.com/commits/136714 X-Bug: 56881,11764086 Message-Id: <20110505074229.2611A1F4@tyr67.norway.sun.com> MIME-Version: 1.0 Content-Type: multipart/mixed; boundary="===============8140244042925005365==" --===============8140244042925005365== 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:roy.lyseng@stripped 3368 Roy Lyseng 2011-05-05 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 adjust the value of not_null_tables_cache for Item_in_optimizer::fix_fields(). If the Item_in_subselect member is "top level", meaning that the original query is an IN predicate, use 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_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 Added test results for bug#11764086. sql/item_cmpfunc.cc Adjusted implementation of not_null_tables_cache in Item_in_optimizer::fix_fields(). sql/item_func.h Added some comments for relevant Item members. 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_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-05 07:41:53 +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,54 @@ 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 # 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-05 07:41:53 +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,54 @@ 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); +# 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-05 07:41:53 +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,54 @@ 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); +# 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-05 07:41:53 +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,54 @@ 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); +# 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-05 07:41:53 +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,54 @@ 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); +# 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-05 07:41:53 +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,54 @@ 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); +# 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-05 07:41:53 +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,54 @@ 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); +# 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-05 07:41:53 +0000 @@ -1764,6 +1764,17 @@ bool Item_in_optimizer::fix_fields(THD * with_sum_func= with_sum_func || args[1]->with_sum_func; used_tables_cache|= args[1]->used_tables(); not_null_tables_cache|= args[1]->not_null_tables(); + + if (!sub->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_cache&= ~args[0]->not_null_tables(); + } const_item_cache&= args[1]->const_item(); fixed= 1; return FALSE; @@ -1791,6 +1802,7 @@ void Item_in_optimizer::fix_after_pullou const_item_cache&= args[1]->const_item(); } + /** The implementation of optimized \ [NOT] IN \ predicates. The implementation works as follows. === 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-05 07:41:53 +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, --===============8140244042925005365== 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: 35ef247d8fe7a52abccb23cd631f0c748f85c8da # timestamp: 2011-05-05 09:42:29 +0200 # base_revision_id: roy.lyseng@stripped\ # p0aanleg1clco1zj # # Begin bundle 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 --===============8140244042925005365==--