From: Tor Didriksen Date: April 14 2011 10:41am Subject: bzr commit into mysql-5.1 branch (tor.didriksen:3658) Bug#11765713 List-Archive: http://lists.mysql.com/commits/135426 X-Bug: 11765713 Message-Id: <20110414104145.A5A7537A3@atum07.norway.sun.com> MIME-Version: 1.0 Content-Type: multipart/mixed; boundary="===============6792152823373560618==" --===============6792152823373560618== MIME-Version: 1.0 Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit Content-Disposition: inline #At file:///export/home/didrik/repo/5.1-foo/ based on revid:serge.kozlov@stripped 3658 Tor Didriksen 2011-04-14 Bug#11765713 58705: OPTIMIZER LET ENGINE DEPEND ON UNINITIALIZED VALUES CREATED BY OPT_SUM_QU Valgrind warnings were caused by comparing index values to an un-initialized field. @ mysql-test/r/subselect.result New test cases. @ mysql-test/t/subselect.test New test cases. @ sql/opt_sum.cc Add thd to opt_sum_query enabling it to test for errors. If we have a non-nullable index, we cannot use it to match null values, since set_null() will be ignored, and we might compare uninitialized data. @ sql/sql_select.cc Add thd to opt_sum_query, enabling it to test for errors. @ sql/sql_select.h Add thd to opt_sum_query, enabling it to test for errors. modified: mysql-test/r/subselect.result mysql-test/t/subselect.test sql/opt_sum.cc sql/sql_select.cc sql/sql_select.h === modified file 'mysql-test/r/subselect.result' --- a/mysql-test/r/subselect.result 2010-11-08 10:55:43 +0000 +++ b/mysql-test/r/subselect.result 2011-04-14 10:41:29 +0000 @@ -4734,3 +4734,21 @@ SELECT * FROM t2 UNION SELECT * FROM t2 ORDER BY (SELECT * FROM t1 WHERE MATCH(a) AGAINST ('+abc' IN BOOLEAN MODE)); DROP TABLE t1,t2; End of 5.1 tests +# +# Bug #11765713 58705: +# OPTIMIZER LET ENGINE DEPEND ON UNINITIALIZED VALUES +# CREATED BY OPT_SUM_QUERY +# +CREATE TABLE t1(a INT NOT NULL, KEY (a)); +INSERT INTO t1 VALUES (0), (1); +SELECT 1 as foo FROM t1 WHERE a < SOME +(SELECT a FROM t1 WHERE a <=> +(SELECT a FROM t1) +); +ERROR 21000: Subquery returns more than 1 row +SELECT 1 as foo FROM t1 WHERE a < SOME +(SELECT a FROM t1 WHERE a <=> +(SELECT a FROM t1 where a is null) +); +foo +DROP TABLE t1; === modified file 'mysql-test/t/subselect.test' --- a/mysql-test/t/subselect.test 2010-11-08 10:55:43 +0000 +++ b/mysql-test/t/subselect.test 2011-04-14 10:41:29 +0000 @@ -3726,3 +3726,25 @@ DROP TABLE t1,t2; --enable_result_log --echo End of 5.1 tests + +--echo # +--echo # Bug #11765713 58705: +--echo # OPTIMIZER LET ENGINE DEPEND ON UNINITIALIZED VALUES +--echo # CREATED BY OPT_SUM_QUERY +--echo # + +CREATE TABLE t1(a INT NOT NULL, KEY (a)); +INSERT INTO t1 VALUES (0), (1); + +--error ER_SUBQUERY_NO_1_ROW +SELECT 1 as foo FROM t1 WHERE a < SOME + (SELECT a FROM t1 WHERE a <=> + (SELECT a FROM t1) + ); + +SELECT 1 as foo FROM t1 WHERE a < SOME + (SELECT a FROM t1 WHERE a <=> + (SELECT a FROM t1 where a is null) + ); + +DROP TABLE t1; === modified file 'sql/opt_sum.cc' --- a/sql/opt_sum.cc 2010-06-11 07:38:29 +0000 +++ b/sql/opt_sum.cc 2011-04-14 10:41:29 +0000 @@ -211,6 +211,7 @@ static int get_index_max_value(TABLE *ta /** Substitutes constants for some COUNT(), MIN() and MAX() functions. + @param thd thread handler @param tables list of leaves of join table tree @param all_fields All fields to be returned @param conds WHERE clause @@ -228,9 +229,12 @@ static int get_index_max_value(TABLE *ta HA_ERR_KEY_NOT_FOUND on impossible conditions @retval HA_ERR_... if a deadlock or a lock wait timeout happens, for example + @retval + ER_... e.g. ER_SUBQUERY_NO_1_ROW */ -int opt_sum_query(TABLE_LIST *tables, List &all_fields,COND *conds) +int opt_sum_query(THD *thd, + TABLE_LIST *tables, List &all_fields, COND *conds) { List_iterator_fast it(all_fields); int const_result= 1; @@ -242,6 +246,8 @@ int opt_sum_query(TABLE_LIST *tables, Li Item *item; int error; + DBUG_ENTER("opt_sum_query"); + if (conds) where_tables= conds->used_tables(); @@ -269,7 +275,7 @@ int opt_sum_query(TABLE_LIST *tables, Li WHERE t2.field IS NULL; */ if (tl->table->map & where_tables) - return 0; + DBUG_RETURN(0); } else used_tables|= tl->table->map; @@ -297,7 +303,7 @@ int opt_sum_query(TABLE_LIST *tables, Li { tl->table->file->print_error(error, MYF(0)); tl->table->in_use->fatal_error(); - return error; + DBUG_RETURN(error); } count*= tl->table->file->stats.records; } @@ -390,10 +396,10 @@ int opt_sum_query(TABLE_LIST *tables, Li if (error) { if (error == HA_ERR_KEY_NOT_FOUND || error == HA_ERR_END_OF_FILE) - return HA_ERR_KEY_NOT_FOUND; // No rows matching WHERE + DBUG_RETURN(HA_ERR_KEY_NOT_FOUND); // No rows matching WHERE /* HA_ERR_LOCK_DEADLOCK or some other error */ table->file->print_error(error, MYF(0)); - return(error); + DBUG_RETURN(error); } removed_tables|= table->map; } @@ -437,6 +443,10 @@ int opt_sum_query(TABLE_LIST *tables, Li const_result= 0; } } + + if (thd->is_error()) + DBUG_RETURN(thd->main_da.sql_errno()); + /* If we have a where clause, we can only ignore searching in the tables if MIN/MAX optimisation replaced all used tables @@ -446,7 +456,7 @@ int opt_sum_query(TABLE_LIST *tables, Li */ if (removed_tables && used_tables != removed_tables) const_result= 0; // We didn't remove all tables - return const_result; + DBUG_RETURN(const_result); } @@ -732,6 +742,12 @@ static bool matching_cond(bool max_fl, T if (is_null || (is_null_safe_eq && args[1]->is_null())) { + /* + If we have a non-nullable index, we cannot use it, + since set_null will be ignored, and we will compare uninitialized data. + */ + if (!part->field->maybe_null()) + DBUG_RETURN(false); part->field->set_null(); *key_ptr= (uchar) 1; } @@ -802,8 +818,9 @@ static bool matching_cond(bool max_fl, T @param[out] prefix_len Length of prefix for the search range @note - This function may set table->key_read to 1, which must be reset after - index is used! (This can only happen when function returns 1) + This function may set field->table->key_read to true, + which must be reset after index is used! + (This can only happen when function returns 1) @retval 0 Index can not be used to optimize MIN(field)/MAX(field) @@ -818,7 +835,9 @@ static bool find_key_for_maxmin(bool max uint *range_fl, uint *prefix_len) { if (!(field->flags & PART_KEY_FLAG)) - return 0; // Not key field + return false; // Not key field + + DBUG_ENTER("find_key_for_maxmin"); TABLE *table= field->table; uint idx= 0; @@ -843,7 +862,7 @@ static bool find_key_for_maxmin(bool max part++, jdx++, key_part_to_use= (key_part_to_use << 1) | 1) { if (!(table->file->index_flags(idx, jdx, 0) & HA_READ_ORDER)) - return 0; + DBUG_RETURN(false); /* Check whether the index component is partial */ Field *part_field= table->field[part->fieldnr-1]; @@ -892,12 +911,12 @@ static bool find_key_for_maxmin(bool max */ if (field->part_of_key.is_set(idx)) table->set_keyread(TRUE); - return 1; + DBUG_RETURN(true); } } } } - return 0; + DBUG_RETURN(false); } === modified file 'sql/sql_select.cc' --- a/sql/sql_select.cc 2011-02-22 21:03:32 +0000 +++ b/sql/sql_select.cc 2011-04-14 10:41:29 +0000 @@ -961,7 +961,7 @@ JOIN::optimize() If all items were resolved by opt_sum_query, there is no need to open any tables. */ - if ((res=opt_sum_query(select_lex->leaf_tables, all_fields, conds))) + if ((res=opt_sum_query(thd, select_lex->leaf_tables, all_fields, conds))) { if (res == HA_ERR_KEY_NOT_FOUND) { === modified file 'sql/sql_select.h' --- a/sql/sql_select.h 2011-01-07 14:06:24 +0000 +++ b/sql/sql_select.h 2011-04-14 10:41:29 +0000 @@ -612,7 +612,8 @@ Field* create_tmp_field_from_field(THD * /* functions from opt_sum.cc */ bool simple_pred(Item_func *func_item, Item **args, bool *inv_order); -int opt_sum_query(TABLE_LIST *tables, List &all_fields,COND *conds); +int opt_sum_query(THD* thd, + TABLE_LIST *tables, List &all_fields, COND *conds); /* from sql_delete.cc, used by opt_range.cc */ extern "C" int refpos_order_cmp(void* arg, const void *a,const void *b); --===============6792152823373560618== MIME-Version: 1.0 Content-Type: text/bzr-bundle; charset="us-ascii"; name="bzr/tor.didriksen@stripped" Content-Transfer-Encoding: 7bit Content-Disposition: inline # Bazaar merge directive format 2 (Bazaar 0.90) # revision_id: tor.didriksen@stripped\ # cf9a945ybblyg5w5 # target_branch: file:///export/home/didrik/repo/5.1-foo/ # testament_sha1: 025a42fe6ab89ebf1ea931002fbacd2da14aea2f # timestamp: 2011-04-14 12:41:44 +0200 # base_revision_id: serge.kozlov@stripped\ # ghrxsnitso1ogg50 # # Begin bundle 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 --===============6792152823373560618==--