Hello Sergei,
Thank you for review. Please read my answer below.
Sergei Golubchik wrote:
> Hi!
>
> On Aug 20, Gleb Shchepa wrote:
>> #At file:///work/bzr/5.1-bugteam-26020/
>>
>> 2688 Gleb Shchepa 2008-08-20
>> Bug#26020: User-Defined Variables are not consistent with
>> columns data types
>>
>> The "SELECT @lastId, @lastId := Id FROM t" query returns
>> different result sets depending on the type of the Id column
>> (INT or BIGINT).
>>
>> Note: this fix doesn't cover the case when a select query
>> references an user variable and stored function that
>> updates a value of that variable, in this case a result
>> is indeterminate.
>>
>> The server uses incorrect assumption about a constantness of
>> an user variable value as a select list item:
>>
>> The server caches a last query number where that variable
>> was changed and compares this number with a current query
>> number. If these numbers are different, the server guesses,
>> that the variable is not updating in the current query, so
>> a respective select list item is a constant. However, in some
>> common cases the server updates cached query number too late.
>>
>> The server has been modified to memorize user variable
>> assignments during the parse phase to take them into account
>> on the next (query preparation) phase independently of the
>> order of user variable references/assignments in a select
>> item list.
>
> Basically, ok but see below
>
>> === modified file 'sql/item_func.cc'
>> --- a/sql/item_func.cc 2008-07-31 09:50:24 +0000
>> +++ b/sql/item_func.cc 2008-08-20 16:42:15 +0000
>> @@ -3805,6 +3805,24 @@ static user_var_entry *get_variable(HASH
>> return entry;
>> }
>>
>> +
>> +bool Item_func_set_user_var::set_entry(THD *thd, bool create_if_not_exists)
>> +{
>> + if (thd == entry_thd && entry)
>> + return FALSE;
>> + entry_thd= thd;
>
> 1.
> why do you need entry_thd ?
The same parsed item tree of a trigger (that changes some user variable)
may be used from different connections. For example, see trigger.test:
#
# Bug #23651 "Server crashes when trigger which uses stored function
# invoked from different connections".
#
--disable_warnings
drop table if exists t1;
drop function if exists f1;
--enable_warnings
create table t1 (i int);
create function f1() returns int return 10;
create trigger t1_bi before insert on t1 for each row set @a:= f1() + 10;
insert into t1 values ();
^ there Item_func_set_user_var::entry is set
select @a;
connection addconroot1;
insert into t1 values ();
^ there we have to reset Item_func_set_user_var::entry because it points to
user variable entry inside "default" connection thread, not "addconroot1"
connection. To distinguish calls from different connections I use the entry_thd
variable. (The code before this patch reset the Item_func_set_user_var::entry
variably every call to fix_fields function, but now it is not necessary).
Will add detailed commentary about the entry_thd variable.
Thank you,
Gleb.