Hi!
On Aug 29, Georgi Kodinov wrote:
> #At file:///home/kgeorge/mysql/bzr/B32124-5.0-bugteam/
>
> 2672 Georgi Kodinov 2008-08-29
> Bug #32124: crash if prepared statements refer to variables in the where
> clause
>
> The code to get read the value of a system variable was extracting its value
> on PREPARE stage and was substituting the value (as a constant) into the parse
> tree.
> Note that this must be a reversible transformation, i.e. it must be reversed
> before
> each re-execution.
> Unfortunately this cannot be reliably done using the current code, because
> there are
> other non-reversible source tree transformations that can interfere with this
> reversible transformation.
> Fixed by not resolving the value at PREPARE, but at EXECUTE (as the rest of the
>
> functions operate).
> Updated an obsolete related test suite (variables-big) and the code to test the
>
> result type of system variables (as per bug 74).
> === modified file 'sql/item_func.cc'
> --- a/sql/item_func.cc 2008-07-30 11:07:37 +0000
> +++ b/sql/item_func.cc 2008-08-29 15:16:59 +0000
...
> +void Item_func_get_system_var::print(String *str)
> +
> +{
> + str->append('(');
> + str->append(name, name_length);
> + str->append(')');
Why the parentheses ?
> +longlong Item_func_get_system_var::val_int()
> +{
> + THD *thd= current_thd;
> + switch (var->show_type())
> + {
> + case SHOW_INT:
> + {
> + uint value;
> + pthread_mutex_lock(&LOCK_global_system_variables);
> + value= *(uint*) var->value_ptr(thd, var_type, &component);
> + pthread_mutex_unlock(&LOCK_global_system_variables);
> + return (longlong)(ulonglong) value;
> + }
> + case SHOW_LONG:
> + {
> + ulong value;
> + pthread_mutex_lock(&LOCK_global_system_variables);
> + value= *(ulong*) var->value_ptr(thd, var_type, &component);
> + pthread_mutex_unlock(&LOCK_global_system_variables);
> + return (longlong)(ulonglong) value;
> + }
> + case SHOW_LONGLONG:
> + {
> + longlong value;
> + pthread_mutex_lock(&LOCK_global_system_variables);
> + value= *(longlong*) var->value_ptr(thd, var_type, &component);
> + pthread_mutex_unlock(&LOCK_global_system_variables);
> + return value;
> + }
> + case SHOW_HA_ROWS:
> + {
> + ha_rows value;
> + pthread_mutex_lock(&LOCK_global_system_variables);
> + value= *(ha_rows*) var->value_ptr(thd, var_type, &component);
> + pthread_mutex_unlock(&LOCK_global_system_variables);
> + return (longlong) value;
> + }
> + case SHOW_MY_BOOL:
> + return (longlong) (int32) *(my_bool*)
> + var->value_ptr(thd, var_type, &component);
Where's a mutex ?
> + default:
> + my_error(ER_VAR_CANT_BE_READ, MYF(0), name);
What about SELECT CONCAT(@@sort_buffer_size) ?
> + break;
> + }
> +}
I suggest to reduce copy-pasting (and simplify the code) with a macro
like
#define xxx_whatever(TYPE)
do {
TYPE value;
pthread_mutex_lock(&LOCK_global_system_variables);
value= *(TYPE*) var->value_ptr(thd, var_type, &component);
pthread_mutex_unlock(&LOCK_global_system_variables);
return (longlong)value;
} while(0)
(fixing the name and adding \'s at the end of every line is left as an
excercise for the reader :).
> +String* Item_func_get_system_var::val_str(String* str)
> +{
> + THD *thd= current_thd;
> + switch (var->show_type())
> + {
> + case SHOW_CHAR:
> + {
> + pthread_mutex_lock(&LOCK_global_system_variables);
> + char *cptr= (char*) var->value_ptr(thd, var_type, &component);
> + if (cptr)
> + {
> + if (str->copy(cptr, strlen(cptr), system_charset_info))
> + str= NULL;
> + }
> + else
> + {
> + null_value= TRUE;
> + str= NULL;
> + }
> + pthread_mutex_unlock(&LOCK_global_system_variables);
> + return str;
> + }
> + default:
> + my_error(ER_VAR_CANT_BE_READ, MYF(0), name);
Same question: SELECT LEFT("12345", @@tmpdir);
> + break;
> + }
> + return str;
> +}
And one more issue: you don't prevent a variable from modifications in
another connection. Thus, SELECT * FROM t1 where pk=@@sort_buffer_size;
may return many rows, is @@sort_buffer_size will be modified in a
concurrent connection.
Regards / Mit vielen Grüßen,
Sergei
--
__ ___ ___ ____ __
/ |/ /_ __/ __/ __ \/ / Sergei Golubchik <serg@stripped>
/ /|_/ / // /\ \/ /_/ / /__ Principal Software Engineer/Server Architect
/_/ /_/\_, /___/\___\_\___/ Sun Microsystems GmbH, HRB München 161028
<___/ Sonnenallee 1, 85551 Kirchheim-Heimstetten
Geschäftsführer: Thomas Schroeder, Wolfgang Engels, Dr. Roland Boemer
Vorsitzender des Aufsichtsrates: Martin Häring