Commit 918b6a3e authored by Ashish Agarwal's avatar Ashish Agarwal

Bug#16194302: SUPPORT FOR FLOATING-POINT SYSTEM VARIABLES

              USING THE PLUGIN INTERFACE.

ISSUE: No support for floating-point plugin
       system variables.

SOLUTION: Allowing plugins to define and expose floating-point
          system variables of type double. MYSQL_SYSVAR_DOUBLE
          and MYSQL_THDVAR_DOUBLE are added.

ISSUE: Fractional part of the def, min, max values of system
       variables are ignored.

SOLUTION: Adding functions that are used to store the raw
          representation of a double in the raw bits of unsigned
          longlong in a way that the binary representation
          remains the same.
parent 00cf6212
...@@ -120,6 +120,9 @@ double getopt_double_limit_value(double num, const struct my_option *optp, ...@@ -120,6 +120,9 @@ double getopt_double_limit_value(double num, const struct my_option *optp,
my_bool *fix); my_bool *fix);
my_bool getopt_compare_strings(const char *s, const char *t, uint length); my_bool getopt_compare_strings(const char *s, const char *t, uint length);
ulonglong getopt_double2ulonglong(double);
double getopt_ulonglong2double(ulonglong);
C_MODE_END C_MODE_END
#endif /* _my_getopt_h */ #endif /* _my_getopt_h */
......
...@@ -163,6 +163,7 @@ typedef int (*mysql_show_var_func)(MYSQL_THD, struct st_mysql_show_var*, char *) ...@@ -163,6 +163,7 @@ typedef int (*mysql_show_var_func)(MYSQL_THD, struct st_mysql_show_var*, char *)
#define PLUGIN_VAR_STR 0x0005 #define PLUGIN_VAR_STR 0x0005
#define PLUGIN_VAR_ENUM 0x0006 #define PLUGIN_VAR_ENUM 0x0006
#define PLUGIN_VAR_SET 0x0007 #define PLUGIN_VAR_SET 0x0007
#define PLUGIN_VAR_DOUBLE 0x0008
#define PLUGIN_VAR_UNSIGNED 0x0080 #define PLUGIN_VAR_UNSIGNED 0x0080
#define PLUGIN_VAR_THDLOCAL 0x0100 /* Variable is per-connection */ #define PLUGIN_VAR_THDLOCAL 0x0100 /* Variable is per-connection */
#define PLUGIN_VAR_READONLY 0x0200 /* Server variable is read only */ #define PLUGIN_VAR_READONLY 0x0200 /* Server variable is read only */
...@@ -345,6 +346,11 @@ DECLARE_MYSQL_SYSVAR_TYPELIB(name, unsigned long long) = { \ ...@@ -345,6 +346,11 @@ DECLARE_MYSQL_SYSVAR_TYPELIB(name, unsigned long long) = { \
PLUGIN_VAR_SET | ((opt) & PLUGIN_VAR_MASK), \ PLUGIN_VAR_SET | ((opt) & PLUGIN_VAR_MASK), \
#name, comment, check, update, &varname, def, typelib } #name, comment, check, update, &varname, def, typelib }
#define MYSQL_SYSVAR_DOUBLE(name, varname, opt, comment, check, update, def, min, max, blk) \
DECLARE_MYSQL_SYSVAR_SIMPLE(name, double) = { \
PLUGIN_VAR_DOUBLE | ((opt) & PLUGIN_VAR_MASK), \
#name, comment, check, update, &varname, def, min, max, blk }
#define MYSQL_THDVAR_BOOL(name, opt, comment, check, update, def) \ #define MYSQL_THDVAR_BOOL(name, opt, comment, check, update, def) \
DECLARE_MYSQL_THDVAR_BASIC(name, char) = { \ DECLARE_MYSQL_THDVAR_BASIC(name, char) = { \
PLUGIN_VAR_BOOL | PLUGIN_VAR_THDLOCAL | ((opt) & PLUGIN_VAR_MASK), \ PLUGIN_VAR_BOOL | PLUGIN_VAR_THDLOCAL | ((opt) & PLUGIN_VAR_MASK), \
...@@ -395,6 +401,11 @@ DECLARE_MYSQL_THDVAR_TYPELIB(name, unsigned long long) = { \ ...@@ -395,6 +401,11 @@ DECLARE_MYSQL_THDVAR_TYPELIB(name, unsigned long long) = { \
PLUGIN_VAR_SET | PLUGIN_VAR_THDLOCAL | ((opt) & PLUGIN_VAR_MASK), \ PLUGIN_VAR_SET | PLUGIN_VAR_THDLOCAL | ((opt) & PLUGIN_VAR_MASK), \
#name, comment, check, update, -1, def, NULL, typelib } #name, comment, check, update, -1, def, NULL, typelib }
#define MYSQL_THDVAR_DOUBLE(name, opt, comment, check, update, def, min, max, blk) \
DECLARE_MYSQL_THDVAR_SIMPLE(name, double) = { \
PLUGIN_VAR_DOUBLE | PLUGIN_VAR_THDLOCAL | ((opt) & PLUGIN_VAR_MASK), \
#name, comment, check, update, -1, def, min, max, blk, NULL }
/* accessor macros */ /* accessor macros */
#define SYSVAR(name) \ #define SYSVAR(name) \
......
...@@ -16,9 +16,11 @@ set global example_ulong_var=500; ...@@ -16,9 +16,11 @@ set global example_ulong_var=500;
set global example_enum_var= e1; set global example_enum_var= e1;
show status like 'example%'; show status like 'example%';
Variable_name Value Variable_name Value
example_func_example enum_var is 0, ulong_var is 500, really example_func_example enum_var is 0, ulong_var is 500, double_var is 8.500000, really
show variables like 'example%'; show variables like 'example%';
Variable_name Value Variable_name Value
example_double_thdvar 8.500000
example_double_var 8.500000
example_enum_var e1 example_enum_var e1
example_ulong_var 500 example_ulong_var 500
UNINSTALL PLUGIN example; UNINSTALL PLUGIN example;
...@@ -63,3 +65,81 @@ set session sql_mode=@old_sql_mode; ...@@ -63,3 +65,81 @@ set session sql_mode=@old_sql_mode;
set session old=bla; set session old=bla;
ERROR HY000: Variable 'old' is a read only variable ERROR HY000: Variable 'old' is a read only variable
UNINSTALL PLUGIN example; UNINSTALL PLUGIN example;
#
# Bug #16194302 SUPPORT FOR FLOATING-POINT SYSTEM
# VARIABLES USING THE PLUGIN INTERFACE.
#
INSTALL PLUGIN example SONAME 'ha_example.so';
SET GLOBAL example_double_var = -0.1;
Warnings:
Warning 1292 Truncated incorrect example_double_var value: '-0.1'
SELECT @@GLOBAL.example_double_var;
@@GLOBAL.example_double_var
0.500000
SET GLOBAL example_double_var = 0.000001;
Warnings:
Warning 1292 Truncated incorrect example_double_var value: '0.000001'
SELECT @@GLOBAL.example_double_var;
@@GLOBAL.example_double_var
0.500000
SET GLOBAL example_double_var = 0.4;
Warnings:
Warning 1292 Truncated incorrect example_double_var value: '0.4'
SELECT @@GLOBAL.example_double_var;
@@GLOBAL.example_double_var
0.500000
SET GLOBAL example_double_var = 123.456789;
SELECT @@GLOBAL.example_double_var;
@@GLOBAL.example_double_var
123.456789
SET GLOBAL example_double_var = 500;
SELECT @@GLOBAL.example_double_var;
@@GLOBAL.example_double_var
500.000000
SET GLOBAL example_double_var = 999.999999;
SELECT @@GLOBAL.example_double_var;
@@GLOBAL.example_double_var
999.999999
SET GLOBAL example_double_var = 1000.51;
Warnings:
Warning 1292 Truncated incorrect example_double_var value: '1000.51'
SELECT @@GLOBAL.example_double_var;
@@GLOBAL.example_double_var
1000.500000
SET SESSION example_double_thdvar = -0.1;
Warnings:
Warning 1292 Truncated incorrect example_double_thdvar value: '-0.1'
SELECT @@SESSION.example_double_thdvar;
@@SESSION.example_double_thdvar
0.500000
SET SESSION example_double_thdvar = 0.000001;
Warnings:
Warning 1292 Truncated incorrect example_double_thdvar value: '0.000001'
SELECT @@SESSION.example_double_thdvar;
@@SESSION.example_double_thdvar
0.500000
SET SESSION example_double_thdvar = 0.4;
Warnings:
Warning 1292 Truncated incorrect example_double_thdvar value: '0.4'
SELECT @@SESSION.example_double_thdvar;
@@SESSION.example_double_thdvar
0.500000
SET SESSION example_double_thdvar = 123.456789;
SELECT @@SESSION.example_double_thdvar;
@@SESSION.example_double_thdvar
123.456789
SET SESSION example_double_thdvar = 500;
SELECT @@SESSION.example_double_thdvar;
@@SESSION.example_double_thdvar
500.000000
SET SESSION example_double_thdvar = 999.999999;
SELECT @@SESSION.example_double_thdvar;
@@SESSION.example_double_thdvar
999.999999
SET SESSION example_double_thdvar = 1000.51;
Warnings:
Warning 1292 Truncated incorrect example_double_thdvar value: '1000.51'
SELECT @@SESSION.example_double_thdvar;
@@SESSION.example_double_thdvar
1000.500000
UNINSTALL PLUGIN example;
...@@ -85,3 +85,55 @@ set session sql_mode=@old_sql_mode; ...@@ -85,3 +85,55 @@ set session sql_mode=@old_sql_mode;
set session old=bla; set session old=bla;
UNINSTALL PLUGIN example; UNINSTALL PLUGIN example;
--echo #
--echo # Bug #16194302 SUPPORT FOR FLOATING-POINT SYSTEM
--echo # VARIABLES USING THE PLUGIN INTERFACE.
--echo #
--replace_regex /\.dll/.so/
eval INSTALL PLUGIN example SONAME '$EXAMPLE_PLUGIN';
SET GLOBAL example_double_var = -0.1;
SELECT @@GLOBAL.example_double_var;
SET GLOBAL example_double_var = 0.000001;
SELECT @@GLOBAL.example_double_var;
SET GLOBAL example_double_var = 0.4;
SELECT @@GLOBAL.example_double_var;
SET GLOBAL example_double_var = 123.456789;
SELECT @@GLOBAL.example_double_var;
SET GLOBAL example_double_var = 500;
SELECT @@GLOBAL.example_double_var;
SET GLOBAL example_double_var = 999.999999;
SELECT @@GLOBAL.example_double_var;
SET GLOBAL example_double_var = 1000.51;
SELECT @@GLOBAL.example_double_var;
SET SESSION example_double_thdvar = -0.1;
SELECT @@SESSION.example_double_thdvar;
SET SESSION example_double_thdvar = 0.000001;
SELECT @@SESSION.example_double_thdvar;
SET SESSION example_double_thdvar = 0.4;
SELECT @@SESSION.example_double_thdvar;
SET SESSION example_double_thdvar = 123.456789;
SELECT @@SESSION.example_double_thdvar;
SET SESSION example_double_thdvar = 500;
SELECT @@SESSION.example_double_thdvar;
SET SESSION example_double_thdvar = 999.999999;
SELECT @@SESSION.example_double_thdvar;
SET SESSION example_double_thdvar = 1000.51;
SELECT @@SESSION.example_double_thdvar;
UNINSTALL PLUGIN example;
...@@ -90,6 +90,35 @@ void my_getopt_register_get_addr(my_getopt_value func_addr) ...@@ -90,6 +90,35 @@ void my_getopt_register_get_addr(my_getopt_value func_addr)
getopt_get_addr= func_addr; getopt_get_addr= func_addr;
} }
union ull_dbl
{
ulonglong ull;
double dbl;
};
/**
Returns an ulonglong value containing a raw
representation of the given double value.
*/
ulonglong getopt_double2ulonglong(double v)
{
union ull_dbl u;
u.dbl= v;
compile_time_assert(sizeof(ulonglong) >= sizeof(double));
return u.ull;
}
/**
Returns the double value which corresponds to
the given raw representation.
*/
double getopt_ulonglong2double(ulonglong v)
{
union ull_dbl u;
u.ull= v;
return u.dbl;
}
/** /**
Handle command line options. Handle command line options.
Sort options. Sort options.
...@@ -1044,14 +1073,18 @@ double getopt_double_limit_value(double num, const struct my_option *optp, ...@@ -1044,14 +1073,18 @@ double getopt_double_limit_value(double num, const struct my_option *optp,
{ {
my_bool adjusted= FALSE; my_bool adjusted= FALSE;
double old= num; double old= num;
if (optp->max_value && num > (double) optp->max_value) double min, max;
max= getopt_ulonglong2double(optp->max_value);
min= getopt_ulonglong2double(optp->min_value);
if (max && num > max)
{ {
num= (double) optp->max_value; num= max;
adjusted= TRUE; adjusted= TRUE;
} }
if (num < (double) optp->min_value) if (num < min)
{ {
num= (double) optp->min_value; num= min;
adjusted= TRUE; adjusted= TRUE;
} }
if (fix) if (fix)
...@@ -1134,7 +1167,7 @@ static void init_one_value(const struct my_option *option, void *variable, ...@@ -1134,7 +1167,7 @@ static void init_one_value(const struct my_option *option, void *variable,
*((ulonglong*) variable)= (ulonglong) value; *((ulonglong*) variable)= (ulonglong) value;
break; break;
case GET_DOUBLE: case GET_DOUBLE:
*((double*) variable)= ulonglong2double(value); *((double*) variable)= getopt_ulonglong2double(value);
break; break;
case GET_STR: case GET_STR:
/* /*
......
...@@ -2059,6 +2059,7 @@ typedef DECLARE_MYSQL_SYSVAR_SIMPLE(sysvar_longlong_t, longlong); ...@@ -2059,6 +2059,7 @@ typedef DECLARE_MYSQL_SYSVAR_SIMPLE(sysvar_longlong_t, longlong);
typedef DECLARE_MYSQL_SYSVAR_SIMPLE(sysvar_uint_t, uint); typedef DECLARE_MYSQL_SYSVAR_SIMPLE(sysvar_uint_t, uint);
typedef DECLARE_MYSQL_SYSVAR_SIMPLE(sysvar_ulong_t, ulong); typedef DECLARE_MYSQL_SYSVAR_SIMPLE(sysvar_ulong_t, ulong);
typedef DECLARE_MYSQL_SYSVAR_SIMPLE(sysvar_ulonglong_t, ulonglong); typedef DECLARE_MYSQL_SYSVAR_SIMPLE(sysvar_ulonglong_t, ulonglong);
typedef DECLARE_MYSQL_SYSVAR_SIMPLE(sysvar_double_t, double);
typedef DECLARE_MYSQL_THDVAR_SIMPLE(thdvar_int_t, int); typedef DECLARE_MYSQL_THDVAR_SIMPLE(thdvar_int_t, int);
typedef DECLARE_MYSQL_THDVAR_SIMPLE(thdvar_long_t, long); typedef DECLARE_MYSQL_THDVAR_SIMPLE(thdvar_long_t, long);
...@@ -2066,6 +2067,7 @@ typedef DECLARE_MYSQL_THDVAR_SIMPLE(thdvar_longlong_t, longlong); ...@@ -2066,6 +2067,7 @@ typedef DECLARE_MYSQL_THDVAR_SIMPLE(thdvar_longlong_t, longlong);
typedef DECLARE_MYSQL_THDVAR_SIMPLE(thdvar_uint_t, uint); typedef DECLARE_MYSQL_THDVAR_SIMPLE(thdvar_uint_t, uint);
typedef DECLARE_MYSQL_THDVAR_SIMPLE(thdvar_ulong_t, ulong); typedef DECLARE_MYSQL_THDVAR_SIMPLE(thdvar_ulong_t, ulong);
typedef DECLARE_MYSQL_THDVAR_SIMPLE(thdvar_ulonglong_t, ulonglong); typedef DECLARE_MYSQL_THDVAR_SIMPLE(thdvar_ulonglong_t, ulonglong);
typedef DECLARE_MYSQL_THDVAR_SIMPLE(thdvar_double_t, double);
/**************************************************************************** /****************************************************************************
...@@ -2281,6 +2283,20 @@ err: ...@@ -2281,6 +2283,20 @@ err:
return 1; return 1;
} }
static int check_func_double(THD *thd, struct st_mysql_sys_var *var,
void *save, st_mysql_value *value)
{
double v;
my_bool fixed;
struct my_option option;
value->val_real(value, &v);
plugin_opt_set_limits(&option, var);
*(double *) save= getopt_double_limit_value(v, &option, &fixed);
return throw_bounds_warning(thd, var->name, fixed, v);
}
static void update_func_bool(THD *thd, struct st_mysql_sys_var *var, static void update_func_bool(THD *thd, struct st_mysql_sys_var *var,
void *tgt, const void *save) void *tgt, const void *save)
...@@ -2316,6 +2332,11 @@ static void update_func_str(THD *thd, struct st_mysql_sys_var *var, ...@@ -2316,6 +2332,11 @@ static void update_func_str(THD *thd, struct st_mysql_sys_var *var,
*(char **) tgt= *(char **) save; *(char **) tgt= *(char **) save;
} }
static void update_func_double(THD *thd, struct st_mysql_sys_var *var,
void *tgt, const void *save)
{
*(double *) tgt= *(double *) save;
}
/**************************************************************************** /****************************************************************************
System Variables support System Variables support
...@@ -2430,6 +2451,9 @@ static st_bookmark *register_var(const char *plugin, const char *name, ...@@ -2430,6 +2451,9 @@ static st_bookmark *register_var(const char *plugin, const char *name,
case PLUGIN_VAR_STR: case PLUGIN_VAR_STR:
size= sizeof(char*); size= sizeof(char*);
break; break;
case PLUGIN_VAR_DOUBLE:
size= sizeof(double);
break;
default: default:
DBUG_ASSERT(0); DBUG_ASSERT(0);
return NULL; return NULL;
...@@ -2641,6 +2665,11 @@ static char **mysql_sys_var_str(THD* thd, int offset) ...@@ -2641,6 +2665,11 @@ static char **mysql_sys_var_str(THD* thd, int offset)
return (char **) intern_sys_var_ptr(thd, offset, true); return (char **) intern_sys_var_ptr(thd, offset, true);
} }
static double *mysql_sys_var_double(THD* thd, int offset)
{
return (double *) intern_sys_var_ptr(thd, offset, true);
}
void plugin_thdvar_init(THD *thd) void plugin_thdvar_init(THD *thd)
{ {
plugin_ref old_table_plugin= thd->variables.table_plugin; plugin_ref old_table_plugin= thd->variables.table_plugin;
...@@ -2773,6 +2802,8 @@ static SHOW_TYPE pluginvar_show_type(st_mysql_sys_var *plugin_var) ...@@ -2773,6 +2802,8 @@ static SHOW_TYPE pluginvar_show_type(st_mysql_sys_var *plugin_var)
case PLUGIN_VAR_ENUM: case PLUGIN_VAR_ENUM:
case PLUGIN_VAR_SET: case PLUGIN_VAR_SET:
return SHOW_CHAR; return SHOW_CHAR;
case PLUGIN_VAR_DOUBLE:
return SHOW_DOUBLE;
default: default:
DBUG_ASSERT(0); DBUG_ASSERT(0);
return SHOW_UNDEF; return SHOW_UNDEF;
...@@ -2923,6 +2954,8 @@ bool sys_var_pluginvar::check_update_type(Item_result type) ...@@ -2923,6 +2954,8 @@ bool sys_var_pluginvar::check_update_type(Item_result type)
case PLUGIN_VAR_BOOL: case PLUGIN_VAR_BOOL:
case PLUGIN_VAR_SET: case PLUGIN_VAR_SET:
return type != STRING_RESULT && type != INT_RESULT; return type != STRING_RESULT && type != INT_RESULT;
case PLUGIN_VAR_DOUBLE:
return type != INT_RESULT && type != REAL_RESULT && type != DECIMAL_RESULT;
default: default:
return true; return true;
} }
...@@ -3048,6 +3081,9 @@ bool sys_var_pluginvar::global_update(THD *thd, set_var *var) ...@@ -3048,6 +3081,9 @@ bool sys_var_pluginvar::global_update(THD *thd, set_var *var)
case PLUGIN_VAR_STR: case PLUGIN_VAR_STR:
src= &((sysvar_str_t*) plugin_var)->def_val; src= &((sysvar_str_t*) plugin_var)->def_val;
break; break;
case PLUGIN_VAR_DOUBLE:
src= &((sysvar_double_t*) plugin_var)->def_val;
break;
case PLUGIN_VAR_INT | PLUGIN_VAR_THDLOCAL: case PLUGIN_VAR_INT | PLUGIN_VAR_THDLOCAL:
src= &((thdvar_uint_t*) plugin_var)->def_val; src= &((thdvar_uint_t*) plugin_var)->def_val;
break; break;
...@@ -3069,6 +3105,9 @@ bool sys_var_pluginvar::global_update(THD *thd, set_var *var) ...@@ -3069,6 +3105,9 @@ bool sys_var_pluginvar::global_update(THD *thd, set_var *var)
case PLUGIN_VAR_STR | PLUGIN_VAR_THDLOCAL: case PLUGIN_VAR_STR | PLUGIN_VAR_THDLOCAL:
src= &((thdvar_str_t*) plugin_var)->def_val; src= &((thdvar_str_t*) plugin_var)->def_val;
break; break;
case PLUGIN_VAR_DOUBLE | PLUGIN_VAR_THDLOCAL:
src= &((thdvar_double_t*) plugin_var)->def_val;
break;
default: default:
DBUG_ASSERT(0); DBUG_ASSERT(0);
} }
...@@ -3092,6 +3131,13 @@ bool sys_var_pluginvar::global_update(THD *thd, set_var *var) ...@@ -3092,6 +3131,13 @@ bool sys_var_pluginvar::global_update(THD *thd, set_var *var)
options->max_value= (opt)->max_val; \ options->max_value= (opt)->max_val; \
options->block_size= (long) (opt)->blk_sz options->block_size= (long) (opt)->blk_sz
#define OPTION_SET_LIMITS_DOUBLE(options, opt) \
options->var_type= GET_DOUBLE; \
options->def_value= (longlong) getopt_double2ulonglong((opt)->def_val); \
options->min_value= (longlong) getopt_double2ulonglong((opt)->min_val); \
options->max_value= getopt_double2ulonglong((opt)->max_val); \
options->block_size= (long) (opt)->blk_sz;
static void plugin_opt_set_limits(struct my_option *options, static void plugin_opt_set_limits(struct my_option *options,
const struct st_mysql_sys_var *opt) const struct st_mysql_sys_var *opt)
...@@ -3142,6 +3188,9 @@ static void plugin_opt_set_limits(struct my_option *options, ...@@ -3142,6 +3188,9 @@ static void plugin_opt_set_limits(struct my_option *options,
GET_STR_ALLOC : GET_STR); GET_STR_ALLOC : GET_STR);
options->def_value= (intptr) ((sysvar_str_t*) opt)->def_val; options->def_value= (intptr) ((sysvar_str_t*) opt)->def_val;
break; break;
case PLUGIN_VAR_DOUBLE:
OPTION_SET_LIMITS_DOUBLE(options, (sysvar_double_t*) opt);
break;
/* threadlocal variables */ /* threadlocal variables */
case PLUGIN_VAR_INT | PLUGIN_VAR_THDLOCAL: case PLUGIN_VAR_INT | PLUGIN_VAR_THDLOCAL:
OPTION_SET_LIMITS(GET_INT, options, (thdvar_int_t*) opt); OPTION_SET_LIMITS(GET_INT, options, (thdvar_int_t*) opt);
...@@ -3161,6 +3210,9 @@ static void plugin_opt_set_limits(struct my_option *options, ...@@ -3161,6 +3210,9 @@ static void plugin_opt_set_limits(struct my_option *options,
case PLUGIN_VAR_LONGLONG | PLUGIN_VAR_UNSIGNED | PLUGIN_VAR_THDLOCAL: case PLUGIN_VAR_LONGLONG | PLUGIN_VAR_UNSIGNED | PLUGIN_VAR_THDLOCAL:
OPTION_SET_LIMITS(GET_ULL, options, (thdvar_ulonglong_t*) opt); OPTION_SET_LIMITS(GET_ULL, options, (thdvar_ulonglong_t*) opt);
break; break;
case PLUGIN_VAR_DOUBLE | PLUGIN_VAR_THDLOCAL:
OPTION_SET_LIMITS_DOUBLE(options, (thdvar_double_t*) opt);
break;
case PLUGIN_VAR_ENUM | PLUGIN_VAR_THDLOCAL: case PLUGIN_VAR_ENUM | PLUGIN_VAR_THDLOCAL:
options->var_type= GET_ENUM; options->var_type= GET_ENUM;
options->typelib= ((thdvar_enum_t*) opt)->typelib; options->typelib= ((thdvar_enum_t*) opt)->typelib;
...@@ -3323,6 +3375,9 @@ static int construct_options(MEM_ROOT *mem_root, struct st_plugin_int *tmp, ...@@ -3323,6 +3375,9 @@ static int construct_options(MEM_ROOT *mem_root, struct st_plugin_int *tmp,
case PLUGIN_VAR_SET: case PLUGIN_VAR_SET:
((thdvar_set_t *) opt)->resolve= mysql_sys_var_ulonglong; ((thdvar_set_t *) opt)->resolve= mysql_sys_var_ulonglong;
break; break;
case PLUGIN_VAR_DOUBLE:
((thdvar_double_t *) opt)->resolve= mysql_sys_var_double;
break;
default: default:
sql_print_error("Unknown variable type code 0x%x in plugin '%s'.", sql_print_error("Unknown variable type code 0x%x in plugin '%s'.",
opt->flags, plugin_name); opt->flags, plugin_name);
...@@ -3386,6 +3441,12 @@ static int construct_options(MEM_ROOT *mem_root, struct st_plugin_int *tmp, ...@@ -3386,6 +3441,12 @@ static int construct_options(MEM_ROOT *mem_root, struct st_plugin_int *tmp,
if (!opt->update) if (!opt->update)
opt->update= update_func_longlong; opt->update= update_func_longlong;
break; break;
case PLUGIN_VAR_DOUBLE:
if (!opt->check)
opt->check= check_func_double;
if (!opt->update)
opt->update= update_func_double;
break;
default: default:
sql_print_error("Unknown variable type code 0x%x in plugin '%s'.", sql_print_error("Unknown variable type code 0x%x in plugin '%s'.",
opt->flags, plugin_name); opt->flags, plugin_name);
......
...@@ -729,13 +729,14 @@ public: ...@@ -729,13 +729,14 @@ public:
const char *substitute=0, const char *substitute=0,
int parse_flag= PARSE_NORMAL) int parse_flag= PARSE_NORMAL)
: sys_var(&all_sys_vars, name_arg, comment, flag_args, off, getopt.id, : sys_var(&all_sys_vars, name_arg, comment, flag_args, off, getopt.id,
getopt.arg_type, SHOW_DOUBLE, (longlong) double2ulonglong(def_val), getopt.arg_type, SHOW_DOUBLE,
(longlong) getopt_double2ulonglong(def_val),
lock, binlog_status_arg, on_check_func, on_update_func, lock, binlog_status_arg, on_check_func, on_update_func,
substitute, parse_flag) substitute, parse_flag)
{ {
option.var_type= GET_DOUBLE; option.var_type= GET_DOUBLE;
option.min_value= (longlong) double2ulonglong(min_val); option.min_value= (longlong) getopt_double2ulonglong(min_val);
option.max_value= (longlong) double2ulonglong(max_val); option.max_value= (longlong) getopt_double2ulonglong(max_val);
global_var(double)= (double)option.def_value; global_var(double)= (double)option.def_value;
DBUG_ASSERT(min_val < max_val); DBUG_ASSERT(min_val < max_val);
DBUG_ASSERT(min_val <= def_val); DBUG_ASSERT(min_val <= def_val);
...@@ -767,7 +768,7 @@ public: ...@@ -767,7 +768,7 @@ public:
void session_save_default(THD *thd, set_var *var) void session_save_default(THD *thd, set_var *var)
{ var->save_result.double_value= global_var(double); } { var->save_result.double_value= global_var(double); }
void global_save_default(THD *thd, set_var *var) void global_save_default(THD *thd, set_var *var)
{ var->save_result.double_value= (double)option.def_value; } { var->save_result.double_value= getopt_ulonglong2double(option.def_value); }
}; };
/** /**
......
...@@ -1004,6 +1004,7 @@ struct st_mysql_storage_engine example_storage_engine= ...@@ -1004,6 +1004,7 @@ struct st_mysql_storage_engine example_storage_engine=
static ulong srv_enum_var= 0; static ulong srv_enum_var= 0;
static ulong srv_ulong_var= 0; static ulong srv_ulong_var= 0;
static double srv_double_var= 0;
const char *enum_var_names[]= const char *enum_var_names[]=
{ {
...@@ -1038,9 +1039,34 @@ static MYSQL_SYSVAR_ULONG( ...@@ -1038,9 +1039,34 @@ static MYSQL_SYSVAR_ULONG(
1000, 1000,
0); 0);
static MYSQL_SYSVAR_DOUBLE(
double_var,
srv_double_var,
PLUGIN_VAR_RQCMDARG,
"0.500000..1000.500000",
NULL,
NULL,
8.5,
0.5,
1000.5,
0); // reserved always 0
static MYSQL_THDVAR_DOUBLE(
double_thdvar,
PLUGIN_VAR_RQCMDARG,
"0.500000..1000.500000",
NULL,
NULL,
8.5,
0.5,
1000.5,
0);
static struct st_mysql_sys_var* example_system_variables[]= { static struct st_mysql_sys_var* example_system_variables[]= {
MYSQL_SYSVAR(enum_var), MYSQL_SYSVAR(enum_var),
MYSQL_SYSVAR(ulong_var), MYSQL_SYSVAR(ulong_var),
MYSQL_SYSVAR(double_var),
MYSQL_SYSVAR(double_thdvar),
NULL NULL
}; };
...@@ -1051,8 +1077,9 @@ static int show_func_example(MYSQL_THD thd, struct st_mysql_show_var *var, ...@@ -1051,8 +1077,9 @@ static int show_func_example(MYSQL_THD thd, struct st_mysql_show_var *var,
var->type= SHOW_CHAR; var->type= SHOW_CHAR;
var->value= buf; // it's of SHOW_VAR_FUNC_BUFF_SIZE bytes var->value= buf; // it's of SHOW_VAR_FUNC_BUFF_SIZE bytes
my_snprintf(buf, SHOW_VAR_FUNC_BUFF_SIZE, my_snprintf(buf, SHOW_VAR_FUNC_BUFF_SIZE,
"enum_var is %lu, ulong_var is %lu, %.6b", // %b is MySQL extension "enum_var is %lu, ulong_var is %lu, "
srv_enum_var, srv_ulong_var, "really"); "double_var is %f, %.6b", // %b is a MySQL extension
srv_enum_var, srv_ulong_var, srv_double_var, "really");
return 0; return 0;
} }
......
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