diff options
author | konstantin@mysql.com <> | 2005-07-16 03:29:13 +0400 |
---|---|---|
committer | konstantin@mysql.com <> | 2005-07-16 03:29:13 +0400 |
commit | e08caeeee2b6250d4e4adfed34c99de08eaacecc (patch) | |
tree | 7b2a374b6d05a129d4b7e3e16593f7244bdccf90 /sql/item_func.cc | |
parent | 0298bc347aad0ad0ed0083781d84d412a921459d (diff) | |
download | mariadb-git-e08caeeee2b6250d4e4adfed34c99de08eaacecc.tar.gz |
A fix and a test case for Bug#9359 "Prepared statements take snapshot
of system vars at PREPARE time": implement a special Item
to handle system variables. This item substitutes itself with
a basic constant containing variable value at fix_fields.
Diffstat (limited to 'sql/item_func.cc')
-rw-r--r-- | sql/item_func.cc | 68 |
1 files changed, 38 insertions, 30 deletions
diff --git a/sql/item_func.cc b/sql/item_func.cc index 0128209cb22..c8f1d209d26 100644 --- a/sql/item_func.cc +++ b/sql/item_func.cc @@ -3031,6 +3031,36 @@ bool Item_func_get_user_var::eq(const Item *item, bool binary_cmp) const } +Item_func_get_system_var:: +Item_func_get_system_var(sys_var *var_arg, enum_var_type var_type_arg, + LEX_STRING *component_arg, const char *name_arg, + size_t name_len_arg) + :var(var_arg), var_type(var_type_arg), component(*component_arg) +{ + /* set_name() will allocate the name */ + set_name(name_arg, name_len_arg, system_charset_info); +} + + +bool +Item_func_get_system_var::fix_fields(THD *thd, TABLE_LIST *tables, Item **ref) +{ + Item *item= var->item(thd, var_type, &component); + DBUG_ENTER("Item_func_get_system_var::fix_fields"); + /* + Evaluate the system variable and substitute the result (a basic constant) + instead of this item. If the variable can not be evaluated, + the error is reported in sys_var::item(). + */ + if (item == 0) + DBUG_RETURN(1); // Impossible + item->set_name(name, 0, system_charset_info); // don't allocate a new name + thd->change_item_tree(ref, item); + + DBUG_RETURN(0); +} + + longlong Item_func_inet_aton::val_int() { DBUG_ASSERT(fixed == 1); @@ -3375,22 +3405,21 @@ longlong Item_func_bit_xor::val_int() 0 error # constant item */ - + Item *get_system_var(THD *thd, enum_var_type var_type, LEX_STRING name, LEX_STRING component) { + sys_var *var; + char buff[MAX_SYS_VAR_LENGTH*2+4+8], *pos; + LEX_STRING *base_name, *component_name; + if (component.str == 0 && !my_strcasecmp(system_charset_info, name.str, "VERSION")) return new Item_string("@@VERSION", server_version, (uint) strlen(server_version), system_charset_info, DERIVATION_SYSCONST); - Item *item; - sys_var *var; - char buff[MAX_SYS_VAR_LENGTH*2+4+8], *pos; - LEX_STRING *base_name, *component_name; - if (component.str) { base_name= &component; @@ -3412,9 +3441,8 @@ Item *get_system_var(THD *thd, enum_var_type var_type, LEX_STRING name, return 0; } } - if (!(item=var->item(thd, var_type, component_name))) - return 0; // Impossible thd->lex->uncacheable(UNCACHEABLE_SIDEEFFECT); + buff[0]='@'; buff[1]='@'; pos=buff+2; @@ -3435,28 +3463,8 @@ Item *get_system_var(THD *thd, enum_var_type var_type, LEX_STRING name, memcpy(pos, base_name->str, base_name->length); pos+= base_name->length; - // set_name() will allocate the name - item->set_name(buff,(uint) (pos-buff), system_charset_info); - return item; -} - - -Item *get_system_var(THD *thd, enum_var_type var_type, const char *var_name, - uint length, const char *item_name) -{ - Item *item; - sys_var *var; - LEX_STRING null_lex_string; - - null_lex_string.str= 0; - - var= find_sys_var(var_name, length); - DBUG_ASSERT(var != 0); - if (!(item=var->item(thd, var_type, &null_lex_string))) - return 0; // Impossible - thd->lex->uncacheable(UNCACHEABLE_SIDEEFFECT); - item->set_name(item_name, 0, system_charset_info); // Will use original name - return item; + return new Item_func_get_system_var(var, var_type, component_name, + buff, pos - buff); } |