diff options
author | Sergei Golubchik <sergii@pisem.net> | 2013-04-09 23:27:19 +0200 |
---|---|---|
committer | Sergei Golubchik <sergii@pisem.net> | 2013-04-09 23:27:19 +0200 |
commit | 7d3288129f6e5b52c7377ff68295f51606c7f002 (patch) | |
tree | 9f844bb427f6f945e97d54d3e4fb9f44bd181186 | |
parent | eda4c51241b647094b727643e1aad4153c45d647 (diff) | |
download | mariadb-git-7d3288129f6e5b52c7377ff68295f51606c7f002.tar.gz |
create sys_var::val_str(), sys_var::val_int(), sys_var::val_real().
Change Item_func_get_system_var::val_xxx functions to use that.
mysql-test/t/variables.test:
@@GLOBAL.INIT_CONNECT is never NULL anymore. Nor it ever was.
It was a bug that empty string system variables appeared as NULL
in the *integer context* (but not in a string, real, or decimal context!)
-rw-r--r-- | mysql-test/r/variables.result | 10 | ||||
-rw-r--r-- | mysql-test/t/func_time.test | 2 | ||||
-rw-r--r-- | mysql-test/t/variables.test | 16 | ||||
-rw-r--r-- | sql/item_func.cc | 180 | ||||
-rw-r--r-- | sql/set_var.cc | 111 | ||||
-rw-r--r-- | sql/set_var.h | 4 |
6 files changed, 127 insertions, 196 deletions
diff --git a/mysql-test/r/variables.result b/mysql-test/r/variables.result index 6ec9d77230b..f280fce08d3 100644 --- a/mysql-test/r/variables.result +++ b/mysql-test/r/variables.result @@ -1479,16 +1479,6 @@ SELECT @@GLOBAL.server_id; @@GLOBAL.server_id 0 SET GLOBAL server_id = @old_server_id; -SELECT @@GLOBAL.INIT_CONNECT, @@GLOBAL.INIT_CONNECT IS NULL; -@@GLOBAL.INIT_CONNECT @@GLOBAL.INIT_CONNECT IS NULL - 1 -CREATE TABLE t1 (a INT); -INSERT INTO t1 VALUES (); -SET @bug42778= @@sql_safe_updates; -SET @@sql_safe_updates= 0; -DELETE FROM t1 ORDER BY (@@GLOBAL.INIT_CONNECT) ASC LIMIT 10; -SET @@sql_safe_updates= @bug42778; -DROP TABLE t1; # # BUG#10206 - InnoDB: Transaction requiring Max_BinLog_Cache_size > 4GB always rollsback # diff --git a/mysql-test/t/func_time.test b/mysql-test/t/func_time.test index f65681a6c5b..7a72c21d0ff 100644 --- a/mysql-test/t/func_time.test +++ b/mysql-test/t/func_time.test @@ -883,7 +883,9 @@ SELECT STR_TO_DATE(SPACE(2),'1'); --echo # SET GLOBAL SQL_MODE=''; +--disable_warnings DO STR_TO_DATE((''), FROM_DAYS(@@GLOBAL.SQL_MODE)); +--enable_warnings SET GLOBAL SQL_MODE=DEFAULT; --echo # diff --git a/mysql-test/t/variables.test b/mysql-test/t/variables.test index 792859386e9..08e7e68c225 100644 --- a/mysql-test/t/variables.test +++ b/mysql-test/t/variables.test @@ -1206,22 +1206,6 @@ SET GLOBAL server_id = -1; SELECT @@GLOBAL.server_id; SET GLOBAL server_id = @old_server_id; -# -# Bug #42778: delete order by null global variable causes -# assertion .\filesort.cc, line 797 -# - -SELECT @@GLOBAL.INIT_CONNECT, @@GLOBAL.INIT_CONNECT IS NULL; - -CREATE TABLE t1 (a INT); -INSERT INTO t1 VALUES (); -SET @bug42778= @@sql_safe_updates; -SET @@sql_safe_updates= 0; -DELETE FROM t1 ORDER BY (@@GLOBAL.INIT_CONNECT) ASC LIMIT 10; -SET @@sql_safe_updates= @bug42778; - -DROP TABLE t1; - --echo # --echo # BUG#10206 - InnoDB: Transaction requiring Max_BinLog_Cache_size > 4GB always rollsback --echo # diff --git a/sql/item_func.cc b/sql/item_func.cc index 2d27876df0b..5316f89e730 100644 --- a/sql/item_func.cc +++ b/sql/item_func.cc @@ -5668,24 +5668,6 @@ enum_field_types Item_func_get_system_var::field_type() const } -/* - Uses var, var_type, component, cache_present, used_query_id, thd, - cached_llval, null_value, cached_null_value -*/ -#define get_sys_var_safe(type) \ -do { \ - type value; \ - mysql_mutex_lock(&LOCK_global_system_variables); \ - value= *(type*) var->value_ptr(thd, var_type, &component); \ - mysql_mutex_unlock(&LOCK_global_system_variables); \ - cache_present |= GET_SYS_VAR_CACHE_LONG; \ - used_query_id= thd->query_id; \ - cached_llval= null_value ? 0 : (longlong) value; \ - cached_null_value= null_value; \ - return cached_llval; \ -} while (0) - - longlong Item_func_get_system_var::val_int() { THD *thd= current_thd; @@ -5719,51 +5701,11 @@ longlong Item_func_get_system_var::val_int() } } - switch (var->show_type()) - { - case SHOW_SINT: get_sys_var_safe (int); - case SHOW_SLONG: get_sys_var_safe (long); - case SHOW_SLONGLONG:get_sys_var_safe (longlong); - case SHOW_UINT: get_sys_var_safe (uint); - case SHOW_ULONG: get_sys_var_safe (ulong); - case SHOW_ULONGLONG:get_sys_var_safe (ulonglong); - case SHOW_HA_ROWS: get_sys_var_safe (ha_rows); - case SHOW_BOOL: get_sys_var_safe (bool); - case SHOW_MY_BOOL: get_sys_var_safe (my_bool); - case SHOW_DOUBLE: - { - double dval= val_real(); - - used_query_id= thd->query_id; - cached_llval= (longlong) dval; - cache_present|= GET_SYS_VAR_CACHE_LONG; - return cached_llval; - } - case SHOW_CHAR: - case SHOW_CHAR_PTR: - case SHOW_LEX_STRING: - { - String *str_val= val_str(NULL); - - if (str_val && str_val->length()) - cached_llval= longlong_from_string_with_check (system_charset_info, - str_val->c_ptr(), - str_val->c_ptr() + - str_val->length()); - else - { - null_value= TRUE; - cached_llval= 0; - } - - cache_present|= GET_SYS_VAR_CACHE_LONG; - return cached_llval; - } - - default: - my_error(ER_VAR_CANT_BE_READ, MYF(0), var->name.str); - return 0; // keep the compiler happy - } + cached_llval= var->val_int(&null_value, thd, var_type, &component); + cache_present |= GET_SYS_VAR_CACHE_LONG; + used_query_id= thd->query_id; + cached_null_value= null_value; + return cached_llval; } @@ -5796,61 +5738,10 @@ String* Item_func_get_system_var::val_str(String* str) } } - str= &cached_strval; - switch (var->show_type()) - { - case SHOW_CHAR: - case SHOW_CHAR_PTR: - case SHOW_LEX_STRING: - { - mysql_mutex_lock(&LOCK_global_system_variables); - char *cptr= var->show_type() == SHOW_CHAR ? - (char*) var->value_ptr(thd, var_type, &component) : - *(char**) var->value_ptr(thd, var_type, &component); - if (cptr) - { - size_t len= var->show_type() == SHOW_LEX_STRING ? - ((LEX_STRING*)(var->value_ptr(thd, var_type, &component)))->length : - strlen(cptr); - if (str->copy(cptr, len, collation.collation)) - { - null_value= TRUE; - str= NULL; - } - } - else - { - null_value= TRUE; - str= NULL; - } - mysql_mutex_unlock(&LOCK_global_system_variables); - break; - } - - case SHOW_SINT: - case SHOW_SLONG: - case SHOW_SLONGLONG: - case SHOW_UINT: - case SHOW_ULONG: - case SHOW_ULONGLONG: - case SHOW_HA_ROWS: - case SHOW_BOOL: - case SHOW_MY_BOOL: - str->set (val_int(), collation.collation); - break; - case SHOW_DOUBLE: - str->set_real (val_real(), decimals, collation.collation); - break; - - default: - my_error(ER_VAR_CANT_BE_READ, MYF(0), var->name.str); - str= NULL; - break; - } - + str= var->val_str(&cached_strval, thd, var_type, &component); cache_present|= GET_SYS_VAR_CACHE_STRING; used_query_id= thd->query_id; - cached_null_value= null_value; + cached_null_value= null_value= !str; return str; } @@ -5888,58 +5779,11 @@ double Item_func_get_system_var::val_real() } } - switch (var->show_type()) - { - case SHOW_DOUBLE: - mysql_mutex_lock(&LOCK_global_system_variables); - cached_dval= *(double*) var->value_ptr(thd, var_type, &component); - mysql_mutex_unlock(&LOCK_global_system_variables); - used_query_id= thd->query_id; - cached_null_value= null_value; - if (null_value) - cached_dval= 0; - cache_present|= GET_SYS_VAR_CACHE_DOUBLE; - return cached_dval; - case SHOW_CHAR: - case SHOW_LEX_STRING: - case SHOW_CHAR_PTR: - { - mysql_mutex_lock(&LOCK_global_system_variables); - char *cptr= var->show_type() == SHOW_CHAR ? - (char*) var->value_ptr(thd, var_type, &component) : - *(char**) var->value_ptr(thd, var_type, &component); - if (cptr) - cached_dval= double_from_string_with_check (system_charset_info, - cptr, cptr + strlen (cptr)); - else - { - null_value= TRUE; - cached_dval= 0; - } - mysql_mutex_unlock(&LOCK_global_system_variables); - used_query_id= thd->query_id; - cached_null_value= null_value; - cache_present|= GET_SYS_VAR_CACHE_DOUBLE; - return cached_dval; - } - case SHOW_SINT: - case SHOW_SLONG: - case SHOW_SLONGLONG: - case SHOW_UINT: - case SHOW_ULONG: - case SHOW_ULONGLONG: - case SHOW_HA_ROWS: - case SHOW_BOOL: - case SHOW_MY_BOOL: - cached_dval= (double) val_int(); - cache_present|= GET_SYS_VAR_CACHE_DOUBLE; - used_query_id= thd->query_id; - cached_null_value= null_value; - return cached_dval; - default: - my_error(ER_VAR_CANT_BE_READ, MYF(0), var->name.str); - return 0; - } + cached_dval= var->val_real(&null_value, thd, var_type, &component); + cache_present |= GET_SYS_VAR_CACHE_DOUBLE; + used_query_id= thd->query_id; + cached_null_value= null_value; + return cached_dval; } diff --git a/sql/set_var.cc b/sql/set_var.cc index 2d3e0b7fec4..48f7cc7a054 100644 --- a/sql/set_var.cc +++ b/sql/set_var.cc @@ -257,8 +257,7 @@ uchar *sys_var::value_ptr(THD *thd, enum_var_type type, LEX_STRING *base) bool sys_var::set_default(THD *thd, enum_var_type type) { - LEX_STRING empty={0,0}; - set_var var(type, this, &empty, 0); + set_var var(type, this, &null_lex_str, 0); if (type == OPT_GLOBAL || scope() == GLOBAL) global_save_default(thd, &var); @@ -268,6 +267,114 @@ bool sys_var::set_default(THD *thd, enum_var_type type) return check(thd, &var) || update(thd, &var); } + +#define do_num_val(T,CMD) \ +do { \ + mysql_mutex_lock(&LOCK_global_system_variables); \ + T val= *(T*) value_ptr(thd, type, base); \ + mysql_mutex_unlock(&LOCK_global_system_variables); \ + CMD; \ +} while (0) + +#define case_for_integers(CMD) \ + case SHOW_SINT: do_num_val (int,CMD); \ + case SHOW_SLONG: do_num_val (long,CMD); \ + case SHOW_SLONGLONG:do_num_val (longlong,CMD); \ + case SHOW_UINT: do_num_val (uint,CMD); \ + case SHOW_ULONG: do_num_val (ulong,CMD); \ + case SHOW_ULONGLONG:do_num_val (ulonglong,CMD); \ + case SHOW_HA_ROWS: do_num_val (ha_rows,CMD); \ + case SHOW_BOOL: do_num_val (bool,CMD); \ + case SHOW_MY_BOOL: do_num_val (my_bool,CMD) + +#define case_for_double(CMD) \ + case SHOW_DOUBLE: do_num_val (double,CMD) + +#define case_get_string_as_lex_string \ + case SHOW_CHAR: \ + mysql_mutex_lock(&LOCK_global_system_variables); \ + sval.str= (char*) value_ptr(thd, type, base); \ + sval.length= sval.str ? strlen(sval.str) : 0; \ + break; \ + case SHOW_CHAR_PTR: \ + mysql_mutex_lock(&LOCK_global_system_variables); \ + sval.str= *(char**) value_ptr(thd, type, base); \ + sval.length= sval.str ? strlen(sval.str) : 0; \ + break; \ + case SHOW_LEX_STRING: \ + mysql_mutex_lock(&LOCK_global_system_variables); \ + sval= *(LEX_STRING *) value_ptr(thd, type, base); \ + break + +longlong sys_var::val_int(bool *is_null, + THD *thd, enum_var_type type, LEX_STRING *base) +{ + LEX_STRING sval; + *is_null= false; + switch (show_type()) + { + case_get_string_as_lex_string; + case_for_integers(return val); + case_for_double(return val); + default: + my_error(ER_VAR_CANT_BE_READ, MYF(0), name.str); + return 0; + } + + longlong ret= 0; + if (!(*is_null= !sval.str)) + ret= longlong_from_string_with_check(system_charset_info, + sval.str, sval.str + sval.length); + mysql_mutex_unlock(&LOCK_global_system_variables); + return ret; +} + + +String *sys_var::val_str(String *str, + THD *thd, enum_var_type type, LEX_STRING *base) +{ + LEX_STRING sval; + switch (show_type()) + { + case_get_string_as_lex_string; + case_for_integers(return str->set((ulonglong)val, system_charset_info) ? 0 : str); + case_for_double(return str->set_real(val, 6, system_charset_info) ? 0 : str); + default: + my_error(ER_VAR_CANT_BE_READ, MYF(0), name.str); + return 0; + } + + if (!sval.str || str->copy(sval.str, sval.length, system_charset_info)) + str= NULL; + mysql_mutex_unlock(&LOCK_global_system_variables); + return str; +} + + +double sys_var::val_real(bool *is_null, + THD *thd, enum_var_type type, LEX_STRING *base) +{ + LEX_STRING sval; + *is_null= false; + switch (show_type()) + { + case_get_string_as_lex_string; + case_for_integers(return val); + case_for_double(return val); + default: + my_error(ER_VAR_CANT_BE_READ, MYF(0), name.str); + return 0; + } + + double ret= 0; + if (!(*is_null= !sval.str)) + ret= double_from_string_with_check(system_charset_info, + sval.str, sval.str + sval.length); + mysql_mutex_unlock(&LOCK_global_system_variables); + return ret; +} + + void sys_var::do_deprecated_warning(THD *thd) { if (deprecation_substitute != NULL) diff --git a/sql/set_var.h b/sql/set_var.h index f912c9fffad..6cb0cd33f87 100644 --- a/sql/set_var.h +++ b/sql/set_var.h @@ -108,6 +108,10 @@ public: bool set_default(THD *thd, enum_var_type type); bool update(THD *thd, set_var *var); + longlong val_int(bool *is_null, THD *thd, enum_var_type type, LEX_STRING *base); + String *val_str(String *str, THD *thd, enum_var_type type, LEX_STRING *base); + double val_real(bool *is_null, THD *thd, enum_var_type type, LEX_STRING *base); + SHOW_TYPE show_type() { return show_val_type; } int scope() const { return flags & SCOPE_MASK; } CHARSET_INFO *charset(THD *thd); |