Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

Support for floating-point system variables using the plugin interface.

Augment the server plugin interface to allow plugins to define and
expose floating-point system variables of type double. The convenience
macros MYSQL_SYSVAR_DOUBLE and MYSQL_THDVAR_DOUBLE are introduced and
can be used by plugins to declare system variables of type double.
  • Loading branch information...
commit 9cca1d8bdb5283e5bb5a5aa3fa7cf23d4ccb3266 1 parent a54c930
Davi Arnaut authored
View
11 include/mysql/plugin.h
@@ -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_ENUM 0x0006
#define PLUGIN_VAR_SET 0x0007
+#define PLUGIN_VAR_DOUBLE 0x0008
#define PLUGIN_VAR_UNSIGNED 0x0080
#define PLUGIN_VAR_THDLOCAL 0x0100 /* Variable is per-connection */
#define PLUGIN_VAR_READONLY 0x0200 /* Server variable is read only */
@@ -345,6 +346,11 @@ DECLARE_MYSQL_SYSVAR_TYPELIB(name, unsigned long long) = { \
PLUGIN_VAR_SET | ((opt) & PLUGIN_VAR_MASK), \
#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) \
DECLARE_MYSQL_THDVAR_BASIC(name, char) = { \
PLUGIN_VAR_BOOL | PLUGIN_VAR_THDLOCAL | ((opt) & PLUGIN_VAR_MASK), \
@@ -395,6 +401,11 @@ DECLARE_MYSQL_THDVAR_TYPELIB(name, unsigned long long) = { \
PLUGIN_VAR_SET | PLUGIN_VAR_THDLOCAL | ((opt) & PLUGIN_VAR_MASK), \
#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 */
#define SYSVAR(name) \
View
32 mysql-test/r/plugin.result
@@ -16,9 +16,10 @@ set global example_ulong_var=500;
set global example_enum_var= e1;
show status like 'example%';
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.000000, really
show variables like 'example%';
Variable_name Value
+example_double_var 8.000000
example_enum_var e1
example_ulong_var 500
UNINSTALL PLUGIN example;
@@ -62,4 +63,33 @@ select @@global.example_ulong_var;
set session sql_mode=@old_sql_mode;
set session old=bla;
ERROR HY000: Variable 'old' is a read only variable
+# Floating-point plugin system variables.
+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.000000
+SET GLOBAL example_double_var = 0.000001;
+SELECT @@GLOBAL.example_double_var;
+@@GLOBAL.example_double_var
+0.000001
+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.1;
+Warnings:
+Warning 1292 Truncated incorrect example_double_var value: '1000.1'
+SELECT @@GLOBAL.example_double_var;
+@@GLOBAL.example_double_var
+1000.000000
UNINSTALL PLUGIN example;
View
19 mysql-test/t/plugin.test
@@ -84,4 +84,23 @@ set session sql_mode=@old_sql_mode;
--error ER_INCORRECT_GLOBAL_LOCAL_VAR
set session old=bla;
+--echo # Floating-point plugin system variables.
+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 = 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.1;
+SELECT @@GLOBAL.example_double_var;
+
UNINSTALL PLUGIN example;
View
58 sql/sql_plugin.cc
@@ -2066,6 +2066,8 @@ typedef DECLARE_MYSQL_THDVAR_SIMPLE(thdvar_uint_t, uint);
typedef DECLARE_MYSQL_THDVAR_SIMPLE(thdvar_ulong_t, ulong);
typedef DECLARE_MYSQL_THDVAR_SIMPLE(thdvar_ulonglong_t, ulonglong);
+typedef DECLARE_MYSQL_SYSVAR_SIMPLE(sysvar_double_t, double);
+typedef DECLARE_MYSQL_THDVAR_SIMPLE(thdvar_double_t, double);
/****************************************************************************
default variable data check and update functions
@@ -2187,6 +2189,22 @@ static int check_func_longlong(THD *thd, struct st_mysql_sys_var *var,
value->is_unsigned(value), (longlong) orig);
}
+
+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 int check_func_str(THD *thd, struct st_mysql_sys_var *var,
void *save, st_mysql_value *value)
{
@@ -2316,6 +2334,13 @@ static void update_func_str(THD *thd, struct st_mysql_sys_var *var,
}
+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
****************************************************************************/
@@ -2429,6 +2454,9 @@ static st_bookmark *register_var(const char *plugin, const char *name,
case PLUGIN_VAR_STR:
size= sizeof(char*);
break;
+ case PLUGIN_VAR_DOUBLE:
+ size= sizeof(double);
+ break;
default:
DBUG_ASSERT(0);
return NULL;
@@ -2640,6 +2668,11 @@ static char **mysql_sys_var_str(THD* thd, int offset)
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)
{
plugin_ref old_table_plugin= thd->variables.table_plugin;
@@ -2772,6 +2805,8 @@ static SHOW_TYPE pluginvar_show_type(st_mysql_sys_var *plugin_var)
case PLUGIN_VAR_ENUM:
case PLUGIN_VAR_SET:
return SHOW_CHAR;
+ case PLUGIN_VAR_DOUBLE:
+ return SHOW_DOUBLE;
default:
DBUG_ASSERT(0);
return SHOW_UNDEF;
@@ -2922,6 +2957,8 @@ bool sys_var_pluginvar::check_update_type(Item_result type)
case PLUGIN_VAR_BOOL:
case PLUGIN_VAR_SET:
return type != STRING_RESULT && type != INT_RESULT;
+ case PLUGIN_VAR_DOUBLE:
+ return type != INT_RESULT && type != REAL_RESULT && type != DECIMAL_RESULT;
default:
return true;
}
@@ -3047,6 +3084,9 @@ bool sys_var_pluginvar::global_update(THD *thd, set_var *var)
case PLUGIN_VAR_STR:
src= &((sysvar_str_t*) plugin_var)->def_val;
break;
+ case PLUGIN_VAR_DOUBLE:
+ src= &((sysvar_double_t*) plugin_var)->def_val;
+ break;
case PLUGIN_VAR_INT | PLUGIN_VAR_THDLOCAL:
src= &((thdvar_uint_t*) plugin_var)->def_val;
break;
@@ -3068,6 +3108,9 @@ bool sys_var_pluginvar::global_update(THD *thd, set_var *var)
case PLUGIN_VAR_STR | PLUGIN_VAR_THDLOCAL:
src= &((thdvar_str_t*) plugin_var)->def_val;
break;
+ case PLUGIN_VAR_DOUBLE | PLUGIN_VAR_THDLOCAL:
+ src= &((thdvar_double_t*) plugin_var)->def_val;
+ break;
default:
DBUG_ASSERT(0);
}
@@ -3118,6 +3161,9 @@ static void plugin_opt_set_limits(struct my_option *options,
case PLUGIN_VAR_LONGLONG | PLUGIN_VAR_UNSIGNED:
OPTION_SET_LIMITS(GET_ULL, options, (sysvar_ulonglong_t*) opt);
break;
+ case PLUGIN_VAR_DOUBLE:
+ OPTION_SET_LIMITS(GET_DOUBLE, options, (sysvar_double_t*) opt);
+ break;
case PLUGIN_VAR_ENUM:
options->var_type= GET_ENUM;
options->typelib= ((sysvar_enum_t*) opt)->typelib;
@@ -3160,6 +3206,9 @@ static void plugin_opt_set_limits(struct my_option *options,
case PLUGIN_VAR_LONGLONG | PLUGIN_VAR_UNSIGNED | PLUGIN_VAR_THDLOCAL:
OPTION_SET_LIMITS(GET_ULL, options, (thdvar_ulonglong_t*) opt);
break;
+ case PLUGIN_VAR_DOUBLE | PLUGIN_VAR_THDLOCAL:
+ OPTION_SET_LIMITS(GET_DOUBLE, options, (thdvar_double_t*) opt);
+ break;
case PLUGIN_VAR_ENUM | PLUGIN_VAR_THDLOCAL:
options->var_type= GET_ENUM;
options->typelib= ((thdvar_enum_t*) opt)->typelib;
@@ -3322,6 +3371,9 @@ static int construct_options(MEM_ROOT *mem_root, struct st_plugin_int *tmp,
case PLUGIN_VAR_SET:
((thdvar_set_t *) opt)->resolve= mysql_sys_var_ulonglong;
break;
+ case PLUGIN_VAR_DOUBLE:
+ ((thdvar_double_t *) opt)->resolve= mysql_sys_var_double;
+ break;
default:
sql_print_error("Unknown variable type code 0x%x in plugin '%s'.",
opt->flags, plugin_name);
@@ -3385,6 +3437,12 @@ static int construct_options(MEM_ROOT *mem_root, struct st_plugin_int *tmp,
if (!opt->update)
opt->update= update_func_longlong;
break;
+ case PLUGIN_VAR_DOUBLE:
+ if (!opt->check)
+ opt->check= check_func_double;
+ if (!opt->update)
+ opt->update= update_func_double;
+ break;
default:
sql_print_error("Unknown variable type code 0x%x in plugin '%s'.",
opt->flags, plugin_name);
View
19 storage/example/ha_example.cc
@@ -1004,6 +1004,7 @@ struct st_mysql_storage_engine example_storage_engine=
static ulong srv_enum_var= 0;
static ulong srv_ulong_var= 0;
+static double srv_double_var= 0;
const char *enum_var_names[]=
{
@@ -1038,9 +1039,22 @@ static MYSQL_SYSVAR_ULONG(
1000,
0);
+static MYSQL_SYSVAR_DOUBLE(
+ double_var,
+ srv_double_var,
+ PLUGIN_VAR_RQCMDARG,
+ "0.0..1000.0",
+ NULL,
+ NULL,
+ 8.0,
+ 0.0,
+ 1000.0,
+ 0);
+
static struct st_mysql_sys_var* example_system_variables[]= {
MYSQL_SYSVAR(enum_var),
MYSQL_SYSVAR(ulong_var),
+ MYSQL_SYSVAR(double_var),
NULL
};
@@ -1051,8 +1065,9 @@ static int show_func_example(MYSQL_THD thd, struct st_mysql_show_var *var,
var->type= SHOW_CHAR;
var->value= buf; // it's of SHOW_VAR_FUNC_BUFF_SIZE bytes
my_snprintf(buf, SHOW_VAR_FUNC_BUFF_SIZE,
- "enum_var is %lu, ulong_var is %lu, %.6b", // %b is MySQL extension
- srv_enum_var, srv_ulong_var, "really");
+ "enum_var is %lu, ulong_var is %lu, "
+ "double_var is %f, %.6b", // %b is a MySQL extension
+ srv_enum_var, srv_ulong_var, srv_double_var, "really");
return 0;
}
Please sign in to comment.
Something went wrong with that request. Please try again.