|
|
@ -142,9 +142,10 @@ public: |
|
|
|
option.min_value= min_val; |
|
|
|
option.max_value= max_val; |
|
|
|
option.block_size= block_size; |
|
|
|
option.u_max_value= (uchar**)max_var_ptr(); |
|
|
|
if (max_var_ptr()) |
|
|
|
*max_var_ptr()= max_val; |
|
|
|
if ((option.u_max_value= (uchar**) max_var_ptr())) |
|
|
|
{ |
|
|
|
*((T*) option.u_max_value)= max_val; |
|
|
|
} |
|
|
|
|
|
|
|
global_var(T)= def_val; |
|
|
|
SYSVAR_ASSERT(size == sizeof(T)); |
|
|
@ -176,8 +177,8 @@ public: |
|
|
|
var->save_result.ulonglong_value= |
|
|
|
getopt_ull_limit_value(uv, &option, &unused); |
|
|
|
|
|
|
|
if (max_var_ptr() && (T)var->save_result.ulonglong_value > *max_var_ptr()) |
|
|
|
var->save_result.ulonglong_value= *max_var_ptr(); |
|
|
|
if (max_var_ptr() && (T)var->save_result.ulonglong_value > get_max_var()) |
|
|
|
var->save_result.ulonglong_value= get_max_var(); |
|
|
|
|
|
|
|
fixed= fixed || var->save_result.ulonglong_value != uv; |
|
|
|
} |
|
|
@ -193,8 +194,8 @@ public: |
|
|
|
var->save_result.longlong_value= |
|
|
|
getopt_ll_limit_value(v, &option, &unused); |
|
|
|
|
|
|
|
if (max_var_ptr() && (T)var->save_result.longlong_value > *max_var_ptr()) |
|
|
|
var->save_result.longlong_value= *max_var_ptr(); |
|
|
|
if (max_var_ptr() && (T)var->save_result.longlong_value > get_max_var()) |
|
|
|
var->save_result.longlong_value= get_max_var(); |
|
|
|
|
|
|
|
fixed= fixed || var->save_result.longlong_value != v; |
|
|
|
} |
|
|
@ -216,11 +217,7 @@ public: |
|
|
|
void global_save_default(THD *thd, set_var *var) |
|
|
|
{ var->save_result.ulonglong_value= option.def_value; } |
|
|
|
private: |
|
|
|
T *max_var_ptr() |
|
|
|
{ |
|
|
|
return scope() == SESSION ? (T*)(((uchar*)&max_system_variables) + offset) |
|
|
|
: 0; |
|
|
|
} |
|
|
|
T get_max_var() { return *((T*) max_var_ptr()); } |
|
|
|
uchar *default_value_ptr(THD *thd) { return (uchar*) &option.def_value; } |
|
|
|
}; |
|
|
|
|
|
|
@ -264,6 +261,9 @@ class Sys_var_typelib: public sys_var |
|
|
|
{ |
|
|
|
protected: |
|
|
|
TYPELIB typelib; |
|
|
|
virtual bool check_maximum(THD *thd, set_var *var, |
|
|
|
const char *c_val, longlong i_val) |
|
|
|
{ return FALSE; } |
|
|
|
public: |
|
|
|
Sys_var_typelib(const char *name_arg, |
|
|
|
const char *comment, int flag_args, ptrdiff_t off, |
|
|
@ -299,17 +299,14 @@ public: |
|
|
|
return true; |
|
|
|
else |
|
|
|
var->save_result.ulonglong_value--; |
|
|
|
} |
|
|
|
else |
|
|
|
{ |
|
|
|
longlong tmp=var->value->val_int(); |
|
|
|
if (tmp < 0 || tmp >= typelib.count) |
|
|
|
return true; |
|
|
|
else |
|
|
|
var->save_result.ulonglong_value= tmp; |
|
|
|
return check_maximum(thd, var, res->ptr(), 0); |
|
|
|
} |
|
|
|
|
|
|
|
return false; |
|
|
|
longlong tmp=var->value->val_int(); |
|
|
|
if (tmp < 0 || tmp >= typelib.count) |
|
|
|
return true; |
|
|
|
var->save_result.ulonglong_value= tmp; |
|
|
|
return check_maximum(thd, var, 0, tmp); |
|
|
|
} |
|
|
|
}; |
|
|
|
|
|
|
@ -345,9 +342,25 @@ public: |
|
|
|
{ |
|
|
|
option.var_type|= GET_ENUM; |
|
|
|
global_var(ulong)= def_val; |
|
|
|
if ((option.u_max_value= (uchar**)max_var_ptr())) |
|
|
|
{ |
|
|
|
*((ulong *) option.u_max_value)= ULONG_MAX; |
|
|
|
} |
|
|
|
SYSVAR_ASSERT(def_val < typelib.count); |
|
|
|
SYSVAR_ASSERT(size == sizeof(ulong)); |
|
|
|
} |
|
|
|
bool check_maximum(THD *thd, set_var *var, |
|
|
|
const char *c_val, longlong i_val) |
|
|
|
{ |
|
|
|
if (!max_var_ptr() || |
|
|
|
var->save_result.ulonglong_value <= get_max_var()) |
|
|
|
return FALSE; |
|
|
|
var->save_result.ulonglong_value= get_max_var(); |
|
|
|
|
|
|
|
return c_val ? throw_bounds_warning(thd, name.str, c_val) : |
|
|
|
throw_bounds_warning(thd, name.str, TRUE, |
|
|
|
var->value->unsigned_flag, i_val); |
|
|
|
} |
|
|
|
bool session_update(THD *thd, set_var *var) |
|
|
|
{ |
|
|
|
session_var(thd, ulong)= static_cast<ulong>(var->save_result.ulonglong_value); |
|
|
@ -370,6 +383,8 @@ public: |
|
|
|
{ return valptr(thd, global_var(ulong)); } |
|
|
|
uchar *default_value_ptr(THD *thd) |
|
|
|
{ return valptr(thd, (ulong)option.def_value); } |
|
|
|
|
|
|
|
ulong get_max_var() { return *((ulong *) max_var_ptr()); } |
|
|
|
}; |
|
|
|
|
|
|
|
/** |
|
|
@ -1335,11 +1350,27 @@ public: |
|
|
|
{ |
|
|
|
option.var_type|= GET_SET; |
|
|
|
global_var(ulonglong)= def_val; |
|
|
|
if ((option.u_max_value= (uchar**)max_var_ptr())) |
|
|
|
{ |
|
|
|
*((ulonglong*) option.u_max_value)= ~0ULL; |
|
|
|
} |
|
|
|
SYSVAR_ASSERT(typelib.count > 0); |
|
|
|
SYSVAR_ASSERT(typelib.count <= 64); |
|
|
|
SYSVAR_ASSERT(def_val <= my_set_bits(typelib.count)); |
|
|
|
SYSVAR_ASSERT(size == sizeof(ulonglong)); |
|
|
|
} |
|
|
|
bool check_maximum(THD *thd, set_var *var, |
|
|
|
const char *c_val, longlong i_val) |
|
|
|
{ |
|
|
|
if (!max_var_ptr() || |
|
|
|
(var->save_result.ulonglong_value & ~(get_max_var())) == 0) |
|
|
|
return FALSE; |
|
|
|
var->save_result.ulonglong_value&= get_max_var(); |
|
|
|
|
|
|
|
return c_val ? throw_bounds_warning(thd, name.str, c_val) : |
|
|
|
throw_bounds_warning(thd, name.str, TRUE, |
|
|
|
var->value->unsigned_flag, i_val); |
|
|
|
} |
|
|
|
bool do_check(THD *thd, set_var *var) |
|
|
|
{ |
|
|
|
char buff[STRING_BUFFER_USUAL_SIZE]; |
|
|
@ -1347,41 +1378,37 @@ public: |
|
|
|
|
|
|
|
if (var->value->result_type() == STRING_RESULT) |
|
|
|
{ |
|
|
|
char *error; |
|
|
|
uint error_len; |
|
|
|
bool not_used; |
|
|
|
|
|
|
|
if (!(res=var->value->val_str_ascii(&str))) |
|
|
|
return true; |
|
|
|
else |
|
|
|
{ |
|
|
|
char *error; |
|
|
|
uint error_len; |
|
|
|
bool not_used; |
|
|
|
|
|
|
|
var->save_result.ulonglong_value= |
|
|
|
find_set(&typelib, res->ptr(), res->length(), NULL, |
|
|
|
&error, &error_len, ¬_used); |
|
|
|
/* |
|
|
|
note, we only issue an error if error_len > 0. |
|
|
|
That is even while empty (zero-length) values are considered |
|
|
|
errors by find_set(), these errors are ignored here |
|
|
|
*/ |
|
|
|
if (error_len) |
|
|
|
{ |
|
|
|
ErrConvString err(error, error_len, res->charset()); |
|
|
|
my_error(ER_WRONG_VALUE_FOR_VAR, MYF(0), name.str, err.ptr()); |
|
|
|
return true; |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
else |
|
|
|
{ |
|
|
|
longlong tmp=var->value->val_int(); |
|
|
|
if ((tmp < 0 && ! var->value->unsigned_flag) |
|
|
|
|| (ulonglong)tmp > my_set_bits(typelib.count)) |
|
|
|
var->save_result.ulonglong_value= |
|
|
|
find_set(&typelib, res->ptr(), res->length(), NULL, |
|
|
|
&error, &error_len, ¬_used); |
|
|
|
/* |
|
|
|
note, we only issue an error if error_len > 0. |
|
|
|
That is even while empty (zero-length) values are considered |
|
|
|
errors by find_set(), these errors are ignored here |
|
|
|
*/ |
|
|
|
if (error_len) |
|
|
|
{ |
|
|
|
ErrConvString err(error, error_len, res->charset()); |
|
|
|
my_error(ER_WRONG_VALUE_FOR_VAR, MYF(0), name.str, err.ptr()); |
|
|
|
return true; |
|
|
|
else |
|
|
|
var->save_result.ulonglong_value= tmp; |
|
|
|
} |
|
|
|
return check_maximum(thd, var, res->ptr(), 0); |
|
|
|
} |
|
|
|
|
|
|
|
return false; |
|
|
|
longlong tmp=var->value->val_int(); |
|
|
|
if ((tmp < 0 && ! var->value->unsigned_flag) |
|
|
|
|| (ulonglong)tmp > my_set_bits(typelib.count)) |
|
|
|
return true; |
|
|
|
|
|
|
|
var->save_result.ulonglong_value= tmp; |
|
|
|
return check_maximum(thd, var, 0, tmp); |
|
|
|
} |
|
|
|
bool session_update(THD *thd, set_var *var) |
|
|
|
{ |
|
|
@ -1405,6 +1432,8 @@ public: |
|
|
|
{ return valptr(thd, global_var(ulonglong)); } |
|
|
|
uchar *default_value_ptr(THD *thd) |
|
|
|
{ return valptr(thd, option.def_value); } |
|
|
|
|
|
|
|
ulonglong get_max_var() { return *((ulonglong*) max_var_ptr()); } |
|
|
|
}; |
|
|
|
|
|
|
|
/** |
|
|
|