Commit 7d328812 authored by Sergei Golubchik's avatar Sergei Golubchik

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!)
parent eda4c512
......@@ -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
#
......
......@@ -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 #
......
......@@ -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 #
......
......@@ -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();
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_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;
cached_null_value= null_value;
return cached_llval;
}
default:
my_error(ER_VAR_CANT_BE_READ, MYF(0), var->name.str);
return 0; // keep the compiler happy
}
}
......@@ -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);
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;
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;
}
}
......
......@@ -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)
......
......@@ -108,6 +108,10 @@ class sys_var
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);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment