From: Martin Hansson Date: October 5 2009 8:39am Subject: bzr commit into mysql-5.1-bugteam branch (martin.hansson:3154) Bug#42846 List-Archive: http://lists.mysql.com/commits/85709 X-Bug: 42846 Message-Id: <20091005083946.6312C53126F@Martins-MacBook.local> MIME-Version: 1.0 Content-Type: multipart/mixed; boundary="Boundary_(ID_FFcgJg9Ud/CU8zxPTtpv0A)" --Boundary_(ID_FFcgJg9Ud/CU8zxPTtpv0A) MIME-version: 1.0 Content-type: text/plain; CHARSET=US-ASCII Content-transfer-encoding: 7BIT Content-disposition: inline #At file:///Users/martinhansson/bzr/bug42846/5.1bt/ based on revid:martin.hansson@stripped 3154 Martin Hansson 2009-10-05 [merge] Merge of Bug#42846 modified: mysql-test/r/func_in.result mysql-test/t/func_in.test sql/item_cmpfunc.cc === modified file 'mysql-test/r/func_in.result' --- a/mysql-test/r/func_in.result 2009-05-25 08:00:40 +0000 +++ b/mysql-test/r/func_in.result 2009-10-05 05:27:36 +0000 @@ -608,4 +608,146 @@ SELECT SUM( DISTINCT e ) FROM t1 GROUP B ((AVG( 1 ), 1 + c, 1 + d), (AVG( 1 ), 2 + c, 2 + d)); SUM( DISTINCT e ) DROP TABLE t1; +# +# Bug #44139: Table scan when NULL appears in IN clause +# +CREATE TABLE t1 ( +c_int INT NOT NULL, +c_decimal DECIMAL(5,2) NOT NULL, +c_float FLOAT(5, 2) NOT NULL, +c_bit BIT(10) NOT NULL, +c_date DATE NOT NULL, +c_datetime DATETIME NOT NULL, +c_timestamp TIMESTAMP NOT NULL, +c_time TIME NOT NULL, +c_year YEAR NOT NULL, +c_char CHAR(10) NOT NULL, +INDEX(c_int), INDEX(c_decimal), INDEX(c_float), INDEX(c_bit), INDEX(c_date), +INDEX(c_datetime), INDEX(c_timestamp), INDEX(c_time), INDEX(c_year), +INDEX(c_char)); +INSERT INTO t1 (c_int) VALUES (1), (2), (3), (4), (5); +INSERT INTO t1 (c_int) SELECT 0 FROM t1; +INSERT INTO t1 (c_int) SELECT 0 FROM t1; +EXPLAIN SELECT * FROM t1 WHERE c_int IN (1, 2, 3); +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 range c_int c_int 4 NULL 3 Using where +EXPLAIN SELECT * FROM t1 WHERE c_int IN (NULL, 1, 2, 3); +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 range c_int c_int 4 NULL 3 Using where +EXPLAIN SELECT * FROM t1 WHERE c_int IN (1, 2, 3); +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 range c_int c_int 4 NULL 3 Using where +EXPLAIN SELECT * FROM t1 WHERE c_int IN (1, NULL, 2, NULL, 3, NULL); +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 range c_int c_int 4 NULL 3 Using where +EXPLAIN SELECT * FROM t1 WHERE c_int IN (NULL); +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables +EXPLAIN SELECT * FROM t1 WHERE c_int IN (NULL, NULL); +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables +EXPLAIN SELECT * FROM t1 WHERE c_decimal IN (1, 2, 3); +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 range c_decimal c_decimal 3 NULL 3 Using where +EXPLAIN SELECT * FROM t1 WHERE c_decimal IN (NULL, 1, 2, 3); +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 range c_decimal c_decimal 3 NULL 3 Using where +EXPLAIN SELECT * FROM t1 WHERE c_decimal IN (NULL); +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables +EXPLAIN SELECT * FROM t1 WHERE c_decimal IN (NULL, NULL); +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables +EXPLAIN SELECT * FROM t1 WHERE c_float IN (1, 2, 3); +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 range c_float c_float 4 NULL 3 Using where +EXPLAIN SELECT * FROM t1 WHERE c_float IN (NULL, 1, 2, 3); +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 range c_float c_float 4 NULL 3 Using where +EXPLAIN SELECT * FROM t1 WHERE c_float IN (NULL); +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables +EXPLAIN SELECT * FROM t1 WHERE c_float IN (NULL, NULL); +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables +EXPLAIN SELECT * FROM t1 WHERE c_bit IN (1, 2, 3); +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 range c_bit c_bit 2 NULL 3 Using where +EXPLAIN SELECT * FROM t1 WHERE c_bit IN (NULL, 1, 2, 3); +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 range c_bit c_bit 2 NULL 3 Using where +EXPLAIN SELECT * FROM t1 WHERE c_bit IN (NULL); +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables +EXPLAIN SELECT * FROM t1 WHERE c_bit IN (NULL, NULL); +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables +EXPLAIN SELECT * FROM t1 WHERE c_date +IN ('2009-09-01', '2009-09-02', '2009-09-03'); +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 range c_date c_date 3 NULL 3 Using where +EXPLAIN SELECT * FROM t1 WHERE c_date +IN (NULL, '2009-09-01', '2009-09-02', '2009-09-03'); +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 range c_date c_date 3 NULL 3 Using where +EXPLAIN SELECT * FROM t1 WHERE c_date IN (NULL); +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables +EXPLAIN SELECT * FROM t1 WHERE c_date IN (NULL, NULL); +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables +EXPLAIN SELECT * FROM t1 WHERE c_datetime +IN ('2009-09-01 00:00:01', '2009-09-02 00:00:01', '2009-09-03 00:00:01'); +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 range c_datetime c_datetime 8 NULL 3 Using where +EXPLAIN SELECT * FROM t1 WHERE c_datetime +IN (NULL, '2009-09-01 00:00:01', '2009-09-02 00:00:01', '2009-09-03 00:00:01'); +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 range c_datetime c_datetime 8 NULL 3 Using where +EXPLAIN SELECT * FROM t1 WHERE c_datetime IN (NULL); +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables +EXPLAIN SELECT * FROM t1 WHERE c_datetime IN (NULL, NULL); +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables +EXPLAIN SELECT * FROM t1 WHERE c_timestamp +IN ('2009-09-01 00:00:01', '2009-09-01 00:00:02', '2009-09-01 00:00:03'); +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 range c_timestamp c_timestamp 4 NULL 3 Using where +EXPLAIN SELECT * FROM t1 WHERE c_timestamp +IN (NULL, '2009-09-01 00:00:01', '2009-09-01 00:00:02', '2009-09-01 00:00:03'); +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 range c_timestamp c_timestamp 4 NULL 3 Using where +EXPLAIN SELECT * FROM t1 WHERE c_timestamp IN (NULL); +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables +EXPLAIN SELECT * FROM t1 WHERE c_timestamp IN (NULL, NULL); +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables +EXPLAIN SELECT * FROM t1 WHERE c_year IN (1, 2, 3); +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 range c_year c_year 1 NULL 3 Using where +EXPLAIN SELECT * FROM t1 WHERE c_year IN (NULL, 1, 2, 3); +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 range c_year c_year 1 NULL 3 Using where +EXPLAIN SELECT * FROM t1 WHERE c_year IN (NULL); +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables +EXPLAIN SELECT * FROM t1 WHERE c_year IN (NULL, NULL); +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables +EXPLAIN SELECT * FROM t1 WHERE c_char IN ('1', '2', '3'); +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 range c_char c_char 10 NULL 3 Using where +EXPLAIN SELECT * FROM t1 WHERE c_char IN (NULL, '1', '2', '3'); +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 range c_char c_char 10 NULL 3 Using where +EXPLAIN SELECT * FROM t1 WHERE c_char IN (NULL); +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables +EXPLAIN SELECT * FROM t1 WHERE c_char IN (NULL, NULL); +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables +DROP TABLE t1; +# End of 5.1 tests === modified file 'mysql-test/t/func_in.test' --- a/mysql-test/t/func_in.test 2009-05-25 08:00:40 +0000 +++ b/mysql-test/t/func_in.test 2009-10-05 05:27:36 +0000 @@ -456,4 +456,89 @@ SELECT SUM( DISTINCT e ) FROM t1 GROUP B ((AVG( 1 ), 1 + c, 1 + d), (AVG( 1 ), 2 + c, 2 + d)); DROP TABLE t1; +--echo # +--echo # Bug #44139: Table scan when NULL appears in IN clause +--echo # + +--disable_warnings + +CREATE TABLE t1 ( + c_int INT NOT NULL, + c_decimal DECIMAL(5,2) NOT NULL, + c_float FLOAT(5, 2) NOT NULL, + c_bit BIT(10) NOT NULL, + c_date DATE NOT NULL, + c_datetime DATETIME NOT NULL, + c_timestamp TIMESTAMP NOT NULL, + c_time TIME NOT NULL, + c_year YEAR NOT NULL, + c_char CHAR(10) NOT NULL, + INDEX(c_int), INDEX(c_decimal), INDEX(c_float), INDEX(c_bit), INDEX(c_date), + INDEX(c_datetime), INDEX(c_timestamp), INDEX(c_time), INDEX(c_year), + INDEX(c_char)); + +INSERT INTO t1 (c_int) VALUES (1), (2), (3), (4), (5); +INSERT INTO t1 (c_int) SELECT 0 FROM t1; +INSERT INTO t1 (c_int) SELECT 0 FROM t1; + +--enable_warnings + +EXPLAIN SELECT * FROM t1 WHERE c_int IN (1, 2, 3); +EXPLAIN SELECT * FROM t1 WHERE c_int IN (NULL, 1, 2, 3); + +EXPLAIN SELECT * FROM t1 WHERE c_int IN (1, 2, 3); +EXPLAIN SELECT * FROM t1 WHERE c_int IN (1, NULL, 2, NULL, 3, NULL); +EXPLAIN SELECT * FROM t1 WHERE c_int IN (NULL); +EXPLAIN SELECT * FROM t1 WHERE c_int IN (NULL, NULL); + +EXPLAIN SELECT * FROM t1 WHERE c_decimal IN (1, 2, 3); +EXPLAIN SELECT * FROM t1 WHERE c_decimal IN (NULL, 1, 2, 3); +EXPLAIN SELECT * FROM t1 WHERE c_decimal IN (NULL); +EXPLAIN SELECT * FROM t1 WHERE c_decimal IN (NULL, NULL); + +EXPLAIN SELECT * FROM t1 WHERE c_float IN (1, 2, 3); +EXPLAIN SELECT * FROM t1 WHERE c_float IN (NULL, 1, 2, 3); +EXPLAIN SELECT * FROM t1 WHERE c_float IN (NULL); +EXPLAIN SELECT * FROM t1 WHERE c_float IN (NULL, NULL); + +EXPLAIN SELECT * FROM t1 WHERE c_bit IN (1, 2, 3); +EXPLAIN SELECT * FROM t1 WHERE c_bit IN (NULL, 1, 2, 3); +EXPLAIN SELECT * FROM t1 WHERE c_bit IN (NULL); +EXPLAIN SELECT * FROM t1 WHERE c_bit IN (NULL, NULL); + +EXPLAIN SELECT * FROM t1 WHERE c_date + IN ('2009-09-01', '2009-09-02', '2009-09-03'); +EXPLAIN SELECT * FROM t1 WHERE c_date + IN (NULL, '2009-09-01', '2009-09-02', '2009-09-03'); +EXPLAIN SELECT * FROM t1 WHERE c_date IN (NULL); +EXPLAIN SELECT * FROM t1 WHERE c_date IN (NULL, NULL); + +EXPLAIN SELECT * FROM t1 WHERE c_datetime + IN ('2009-09-01 00:00:01', '2009-09-02 00:00:01', '2009-09-03 00:00:01'); +EXPLAIN SELECT * FROM t1 WHERE c_datetime + IN (NULL, '2009-09-01 00:00:01', '2009-09-02 00:00:01', '2009-09-03 00:00:01'); +EXPLAIN SELECT * FROM t1 WHERE c_datetime IN (NULL); +EXPLAIN SELECT * FROM t1 WHERE c_datetime IN (NULL, NULL); + +EXPLAIN SELECT * FROM t1 WHERE c_timestamp + IN ('2009-09-01 00:00:01', '2009-09-01 00:00:02', '2009-09-01 00:00:03'); +EXPLAIN SELECT * FROM t1 WHERE c_timestamp + IN (NULL, '2009-09-01 00:00:01', '2009-09-01 00:00:02', '2009-09-01 00:00:03'); +EXPLAIN SELECT * FROM t1 WHERE c_timestamp IN (NULL); +EXPLAIN SELECT * FROM t1 WHERE c_timestamp IN (NULL, NULL); + +EXPLAIN SELECT * FROM t1 WHERE c_year IN (1, 2, 3); +EXPLAIN SELECT * FROM t1 WHERE c_year IN (NULL, 1, 2, 3); +EXPLAIN SELECT * FROM t1 WHERE c_year IN (NULL); +EXPLAIN SELECT * FROM t1 WHERE c_year IN (NULL, NULL); + +EXPLAIN SELECT * FROM t1 WHERE c_char IN ('1', '2', '3'); +EXPLAIN SELECT * FROM t1 WHERE c_char IN (NULL, '1', '2', '3'); +EXPLAIN SELECT * FROM t1 WHERE c_char IN (NULL); +EXPLAIN SELECT * FROM t1 WHERE c_char IN (NULL, NULL); + +DROP TABLE t1; + +--echo # + --echo End of 5.1 tests === modified file 'sql/item_cmpfunc.cc' --- a/sql/item_cmpfunc.cc 2009-08-28 16:21:54 +0000 +++ b/sql/item_cmpfunc.cc 2009-10-05 05:27:36 +0000 @@ -189,6 +189,7 @@ enum_field_types agg_field_type(Item **i collect_cmp_types() items Array of items to collect types from nitems Number of items in the array + skip_nulls Don't collect types of NULL items if TRUE DESCRIPTION This function collects different result types for comparison of the first @@ -199,7 +200,7 @@ enum_field_types agg_field_type(Item **i Bitmap of collected types - otherwise */ -static uint collect_cmp_types(Item **items, uint nitems) +static uint collect_cmp_types(Item **items, uint nitems, bool skip_nulls= FALSE) { uint i; uint found_types; @@ -208,6 +209,8 @@ static uint collect_cmp_types(Item **ite found_types= 0; for (i= 1; i < nitems ; i++) { + if (skip_nulls && items[i]->type() == Item::NULL_ITEM) + continue; // Skip NULL constant items if ((left_result == ROW_RESULT || items[i]->result_type() == ROW_RESULT) && cmp_row_type(items[0], items[i])) @@ -215,6 +218,12 @@ static uint collect_cmp_types(Item **ite found_types|= 1<< (uint)item_cmp_type(left_result, items[i]->result_type()); } + /* + Even if all right-hand items are NULLs and we are skipping them all, we need + at least one type bit in the found_type bitmask. + */ + if (skip_nulls && !found_types) + found_types= 1 << (uint)left_result; return found_types; } @@ -3515,7 +3524,7 @@ void Item_func_in::fix_length_and_dec() uint type_cnt= 0, i; Item_result cmp_type= STRING_RESULT; left_result_type= args[0]->result_type(); - if (!(found_types= collect_cmp_types(args, arg_count))) + if (!(found_types= collect_cmp_types(args, arg_count, true))) return; for (arg= args + 1, arg_end= args + arg_count; arg != arg_end ; arg++) @@ -3693,9 +3702,11 @@ void Item_func_in::fix_length_and_dec() uint j=0; for (uint i=1 ; i < arg_count ; i++) { - array->set(j,args[i]); if (!args[i]->null_value) // Skip NULL values + { + array->set(j,args[i]); j++; + } else have_null= 1; } --Boundary_(ID_FFcgJg9Ud/CU8zxPTtpv0A) MIME-version: 1.0 Content-type: text/bzr-bundle; CHARSET=US-ASCII; name="bzr/martin.hansson@stripped" Content-transfer-encoding: 7BIT Content-disposition: inline; filename="bzr/martin.hansson@stripped" # Bazaar merge directive format 2 (Bazaar 0.90) # revision_id: martin.hansson@stripped # target_branch: file:///Users/martinhansson/bzr/bug42846/5.1bt/ # testament_sha1: 0027e0ef5a60bcdf70de5ad3e9406680402b5535 # timestamp: 2009-10-05 10:39:46 +0200 # source_branch: bzr+ssh://martin@stripped/data0/martin/bzr\ # /bug42846/5.1bt/ # base_revision_id: martin.hansson@stripped\ # abwe8oj5soqlxiee # # Begin bundle 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 --Boundary_(ID_FFcgJg9Ud/CU8zxPTtpv0A)--