From: Date: May 17 2007 9:09pm Subject: bk commit into 5.0 tree (evgen:1.2490) BUG#28261 List-Archive: http://lists.mysql.com/commits/26922 X-Bug: 28261 Message-Id: <20070517190949.4921D22CB9F@moonbone.moonbone.local> Below is the list of changes that have just been committed into a local 5.0 repository of evgen. When evgen does a push these changes will be propagated to the main repository and, within 24 hours after the push, to the public repository. For information on how to access the public repository see http://dev.mysql.com/doc/mysql/en/installing-source-tree.html ChangeSet@stripped, 2007-05-17 23:09:45+04:00, evgen@stripped +3 -0 Bug#28261: Wrong DATETIME comparison result when the GET_USER_VAR function is involved. The Arg_comparator::compare_datetime() comparator caches its arguments if they are constants i.e. const_item() returns true. The Item_func_get_user_var::const_item() returns true or false based on the current query_id and the query_id where the variable was created. Thus even if a query can change its value its const_item() still will return true. All this leads to a wrong comparison result when an object of the Item_func_get_user_var class is involved. Now the Arg_comparator::can_compare_as_dates() and the get_datetime_value() functions never cache result of the GET_USER_VAR() function (the Item_func_get_user_var class). mysql-test/r/type_datetime.result@stripped, 2007-05-17 23:08:24+04:00, evgen@stripped +24 -0 A test case is added for the bug#28261: Wrong DATETIME comparison result when the GET_USER_VAR function is involved. mysql-test/t/type_datetime.test@stripped, 2007-05-17 23:07:55+04:00, evgen@stripped +12 -0 A test case is added for the bug#28261: Wrong DATETIME comparison result when the GET_USER_VAR function is involved. sql/item_cmpfunc.cc@stripped, 2007-05-17 23:08:45+04:00, evgen@stripped +13 -2 Bug#28261: Wrong DATETIME comparison result when the GET_USER_VAR function is involved. Now the Arg_comparator::can_compare_as_dates() and the get_datetime_value() functions never cache result of the GET_USER_VAR() function (the Item_func_get_user_var class). # This is a BitKeeper patch. What follows are the unified diffs for the # set of deltas contained in the patch. The rest of the patch, the part # that BitKeeper cares about, is below these diffs. # User: evgen # Host: moonbone.local # Root: /mnt/gentoo64/work/28261-bug-5.0-opt-mysql --- 1.251/sql/item_cmpfunc.cc 2007-05-16 00:29:50.000000000 +0400 +++ 1.252/sql/item_cmpfunc.cc 2007-05-17 23:08:45.000000000 +0400 @@ -633,7 +633,13 @@ if (cmp_type != CMP_DATE_DFLT) { - if (cmp_type != CMP_DATE_WITH_DATE && str_arg->const_item()) + /* + Do not cache GET_USER_VAR() function as its const_item() may return TRUE + for the current thread but it still may change during the execution. + */ + if (cmp_type != CMP_DATE_WITH_DATE && str_arg->const_item() && + (str_arg->type() != Item::FUNC_ITEM || + ((Item_func*)str_arg)->functype() != Item_func::GUSERVAR_FUNC)) { THD *thd= current_thd; ulonglong value; @@ -780,7 +786,12 @@ MYSQL_TYPE_DATE ? MYSQL_TIMESTAMP_DATE : MYSQL_TIMESTAMP_DATETIME; value= get_date_from_str(thd, str, t_type, warn_item->name, &error); } - if (item->const_item() && cache_arg) + /* + Do not cache GET_USER_VAR() function as its const_item() may return TRUE + for the current thread but it still may change during the execution. + */ + if (item->const_item() && cache_arg && (item->type() != Item::FUNC_ITEM || + ((Item_func*)item)->functype() != Item_func::GUSERVAR_FUNC)) { Item_cache_int *cache= new Item_cache_int(); /* Mark the cache as non-const to prevent re-caching. */ --- 1.43/mysql-test/r/type_datetime.result 2007-05-16 00:29:50.000000000 +0400 +++ 1.44/mysql-test/r/type_datetime.result 2007-05-17 23:08:24.000000000 +0400 @@ -352,3 +352,27 @@ left(f1,10) = curdate() 1 drop table t1; +create table t1(f1 date); +insert into t1 values('01-01-01'),('02-02-02'),('01-01-01'),('02-02-02'); +set @bug28261=''; +select if(@bug28261 = f1, '', @bug28261:= f1) from t1; +if(@bug28261 = f1, '', @bug28261:= f1) +2001-01-01 +2002-02-02 +2001-01-01 +2002-02-02 +Warnings: +Warning 1292 Incorrect date value: '' for column 'f1' at row 1 +select if(@bug28261 = f1, '', @bug28261:= f1) from t1; +if(@bug28261 = f1, '', @bug28261:= f1) +2001-01-01 +2002-02-02 +2001-01-01 +2002-02-02 +select if(@bug28261 = f1, '', @bug28261:= f1) from t1; +if(@bug28261 = f1, '', @bug28261:= f1) +2001-01-01 +2002-02-02 +2001-01-01 +2002-02-02 +drop table t1; --- 1.29/mysql-test/t/type_datetime.test 2007-05-16 00:29:48.000000000 +0400 +++ 1.30/mysql-test/t/type_datetime.test 2007-05-17 23:07:55.000000000 +0400 @@ -234,3 +234,15 @@ insert into t1 values (curdate()); select left(f1,10) = curdate() from t1; drop table t1; + +# +# Bug#28261: Wrong DATETIME comparison result when the GET_USER_VAR function +# is involved. +# +create table t1(f1 date); +insert into t1 values('01-01-01'),('02-02-02'),('01-01-01'),('02-02-02'); +set @bug28261=''; +select if(@bug28261 = f1, '', @bug28261:= f1) from t1; +select if(@bug28261 = f1, '', @bug28261:= f1) from t1; +select if(@bug28261 = f1, '', @bug28261:= f1) from t1; +drop table t1;