127
126
static bookmark_unordered_map bookmark_hash;
130
sys_var class for access to all plugin variables visible to the user
132
class sys_var_pluginvar: public sys_var
135
module::Module *plugin;
136
drizzle_sys_var *plugin_var;
138
sys_var_pluginvar(const std::string name_arg,
139
drizzle_sys_var *plugin_var_arg)
140
:sys_var(name_arg), plugin_var(plugin_var_arg) {}
141
sys_var_pluginvar *cast_pluginvar() { return this; }
142
bool is_readonly() const { return plugin_var->flags & PLUGIN_VAR_READONLY; }
143
bool check_type(sql_var_t type)
144
{ return !(plugin_var->flags & PLUGIN_VAR_SessionLOCAL) && type != OPT_GLOBAL; }
145
bool check_update_type(Item_result type);
146
SHOW_TYPE show_type();
147
unsigned char* real_value_ptr(Session *session, sql_var_t type);
148
TYPELIB* plugin_var_typelib(void);
149
unsigned char* value_ptr(Session *session, sql_var_t type,
150
const LEX_STRING *base);
151
bool check(Session *session, set_var *var);
152
bool check_default(sql_var_t)
153
{ return is_readonly(); }
154
void set_default(Session *session, sql_var_t);
155
bool update(Session *session, set_var *var);
132
160
static void plugin_prune_list(vector<string> &plugin_list,
133
161
const vector<string> &plugins_to_remove);
134
162
static bool plugin_load_list(module::Registry ®istry,
135
memory::Root *tmp_root,
163
memory::Root *tmp_root, int *argc, char **argv,
136
164
const set<string> &plugin_list,
137
165
po::options_description &long_options,
138
166
bool builtin= false);
139
167
static int test_plugin_options(memory::Root *, module::Module *,
140
169
po::options_description &long_options);
141
static void unlock_variables(Session *session, drizzle_system_variables *vars);
142
static void cleanup_variables(drizzle_system_variables *vars);
170
static void unlock_variables(Session *session, struct system_variables *vars);
171
static void cleanup_variables(Session *session, struct system_variables *vars);
172
static void plugin_vars_free_values(sys_var *vars);
144
174
/* declared in set_var.cc */
145
175
extern sys_var *intern_find_sys_var(const char *str, uint32_t length, bool no_error);
176
extern bool throw_bounds_warning(Session *session, bool fixed, bool unsignd,
177
const std::string &name, int64_t val);
179
static bool throw_bounds_warning(Session *session, bool fixed, bool unsignd,
180
const char *name, int64_t val)
182
const std::string name_str(name);
183
return throw_bounds_warning(session, fixed, unsignd, name_str, val);
186
/****************************************************************************
187
Value type thunks, allows the C world to play in the C++ world
188
****************************************************************************/
190
static int item_value_type(drizzle_value *value)
192
switch (((st_item_value_holder*)value)->item->result_type()) {
194
return DRIZZLE_VALUE_TYPE_INT;
196
return DRIZZLE_VALUE_TYPE_REAL;
198
return DRIZZLE_VALUE_TYPE_STRING;
202
static const char *item_val_str(drizzle_value *value,
203
char *buffer, int *length)
205
String str(buffer, *length, system_charset_info), *res;
206
if (!(res= ((st_item_value_holder*)value)->item->val_str(&str)))
208
*length= res->length();
209
if (res->c_ptr_quick() == buffer)
213
Lets be nice and create a temporary string since the
216
return current_session->strmake(res->c_ptr_quick(), res->length());
220
static int item_val_int(drizzle_value *value, int64_t *buf)
222
Item *item= ((st_item_value_holder*)value)->item;
223
*buf= item->val_int();
230
static int item_val_real(drizzle_value *value, double *buf)
232
Item *item= ((st_item_value_holder*)value)->item;
233
*buf= item->val_real();
148
240
/****************************************************************************
494
556
global_variables_dynamic_size= 0;
559
/****************************************************************************
560
Internal type declarations for variables support
561
****************************************************************************/
563
#undef DRIZZLE_SYSVAR_NAME
564
#define DRIZZLE_SYSVAR_NAME(name) name
565
#define PLUGIN_VAR_TYPEMASK 0x007f
567
static const uint32_t EXTRA_OPTIONS= 1; /* handle the NULL option */
569
typedef DECLARE_DRIZZLE_SYSVAR_BASIC(sysvar_bool_t, bool);
570
typedef DECLARE_DRIZZLE_SessionVAR_BASIC(sessionvar_bool_t, bool);
571
typedef DECLARE_DRIZZLE_SYSVAR_BASIC(sysvar_str_t, char *);
572
typedef DECLARE_DRIZZLE_SessionVAR_BASIC(sessionvar_str_t, char *);
574
typedef DECLARE_DRIZZLE_SessionVAR_TYPELIB(sessionvar_enum_t, unsigned long);
575
typedef DECLARE_DRIZZLE_SessionVAR_TYPELIB(sessionvar_set_t, uint64_t);
577
typedef DECLARE_DRIZZLE_SYSVAR_SIMPLE(sysvar_int_t, int);
578
typedef DECLARE_DRIZZLE_SYSVAR_SIMPLE(sysvar_long_t, long);
579
typedef DECLARE_DRIZZLE_SYSVAR_SIMPLE(sysvar_int64_t_t, int64_t);
580
typedef DECLARE_DRIZZLE_SYSVAR_SIMPLE(sysvar_uint_t, uint);
581
typedef DECLARE_DRIZZLE_SYSVAR_SIMPLE(sysvar_ulong_t, ulong);
582
typedef DECLARE_DRIZZLE_SYSVAR_SIMPLE(sysvar_uint64_t_t, uint64_t);
584
typedef DECLARE_DRIZZLE_SessionVAR_SIMPLE(sessionvar_int_t, int);
585
typedef DECLARE_DRIZZLE_SessionVAR_SIMPLE(sessionvar_long_t, long);
586
typedef DECLARE_DRIZZLE_SessionVAR_SIMPLE(sessionvar_int64_t_t, int64_t);
587
typedef DECLARE_DRIZZLE_SessionVAR_SIMPLE(sessionvar_uint_t, uint);
588
typedef DECLARE_DRIZZLE_SessionVAR_SIMPLE(sessionvar_ulong_t, ulong);
589
typedef DECLARE_DRIZZLE_SessionVAR_SIMPLE(sessionvar_uint64_t_t, uint64_t);
591
typedef bool *(*mysql_sys_var_ptr_p)(Session* a_session, int offset);
594
/****************************************************************************
595
default variable data check and update functions
596
****************************************************************************/
598
static int check_func_bool(Session *, drizzle_sys_var *var,
599
void *save, drizzle_value *value)
601
char buff[STRING_BUFFER_USUAL_SIZE];
602
const char *strvalue= "NULL", *str;
606
if (value->value_type(value) == DRIZZLE_VALUE_TYPE_STRING)
608
length= sizeof(buff);
609
if (!(str= value->val_str(value, buff, &length)) ||
610
(result= find_type(&bool_typelib, str, length, 1)-1) < 0)
619
if (value->val_int(value, &tmp) < 0)
623
internal::llstr(tmp, buff);
629
*(int*)save= -result;
632
my_error(ER_WRONG_VALUE_FOR_VAR, MYF(0), var->name, strvalue);
637
static int check_func_int(Session *session, drizzle_sys_var *var,
638
void *save, drizzle_value *value)
642
struct option options;
643
value->val_int(value, &tmp);
644
plugin_opt_set_limits(&options, var);
646
if (var->flags & PLUGIN_VAR_UNSIGNED)
647
*(uint32_t *)save= (uint32_t) getopt_ull_limit_value((uint64_t) tmp, &options,
650
*(int *)save= (int) getopt_ll_limit_value(tmp, &options, &fixed);
652
return throw_bounds_warning(session, fixed, var->flags & PLUGIN_VAR_UNSIGNED,
653
var->name, (int64_t) tmp);
657
static int check_func_long(Session *session, drizzle_sys_var *var,
658
void *save, drizzle_value *value)
662
struct option options;
663
value->val_int(value, &tmp);
664
plugin_opt_set_limits(&options, var);
666
if (var->flags & PLUGIN_VAR_UNSIGNED)
667
*(ulong *)save= (ulong) getopt_ull_limit_value((uint64_t) tmp, &options,
670
*(long *)save= (long) getopt_ll_limit_value(tmp, &options, &fixed);
672
return throw_bounds_warning(session, fixed, var->flags & PLUGIN_VAR_UNSIGNED,
673
var->name, (int64_t) tmp);
677
static int check_func_int64_t(Session *session, drizzle_sys_var *var,
678
void *save, drizzle_value *value)
682
struct option options;
683
value->val_int(value, &tmp);
684
plugin_opt_set_limits(&options, var);
686
if (var->flags & PLUGIN_VAR_UNSIGNED)
687
*(uint64_t *)save= getopt_ull_limit_value((uint64_t) tmp, &options,
690
*(int64_t *)save= getopt_ll_limit_value(tmp, &options, &fixed);
692
return throw_bounds_warning(session, fixed, var->flags & PLUGIN_VAR_UNSIGNED,
693
var->name, (int64_t) tmp);
696
static int check_func_str(Session *session, drizzle_sys_var *,
697
void *save, drizzle_value *value)
699
char buff[STRING_BUFFER_USUAL_SIZE];
703
length= sizeof(buff);
704
if ((str= value->val_str(value, buff, &length)))
705
str= session->strmake(str, length);
706
*(const char**)save= str;
711
static void update_func_bool(Session *, drizzle_sys_var *,
712
void *tgt, const void *save)
714
*(bool *) tgt= *(int *) save ? 1 : 0;
718
static void update_func_int(Session *, drizzle_sys_var *,
719
void *tgt, const void *save)
721
*(int *)tgt= *(int *) save;
725
static void update_func_long(Session *, drizzle_sys_var *,
726
void *tgt, const void *save)
728
*(long *)tgt= *(long *) save;
732
static void update_func_int64_t(Session *, drizzle_sys_var *,
733
void *tgt, const void *save)
735
*(int64_t *)tgt= *(uint64_t *) save;
739
static void update_func_str(Session *, drizzle_sys_var *var,
740
void *tgt, const void *save)
742
char *old= *(char **) tgt;
743
*(char **)tgt= *(char **) save;
744
if (var->flags & PLUGIN_VAR_MEMALLOC)
746
*(char **)tgt= strdup(*(char **) save);
749
* There isn't a _really_ good thing to do here until this whole set_var
750
* mess gets redesigned
753
errmsg_printf(ERRMSG_LVL_ERROR, _("Out of memory."));
498
759
/****************************************************************************
499
760
System Variables support
500
761
****************************************************************************/
503
sys_var *find_sys_var(const char *str, uint32_t length)
505
return intern_find_sys_var(str, length, false);
764
sys_var *find_sys_var(Session *, const char *str, uint32_t length)
767
sys_var_pluginvar *pi= NULL;
768
module::Module *module;
770
if ((var= intern_find_sys_var(str, length, false)) &&
771
(pi= var->cast_pluginvar()))
773
if (!(module= pi->plugin))
774
var= NULL; /* failed to lock it, it must be uninstalling */
775
else if (module->isInited == false)
782
If the variable exists but the plugin it is associated with is not ready
783
then the intern_plugin_lock did not raise an error, so we do it here.
786
my_error(ER_UNKNOWN_SYSTEM_VARIABLE, MYF(0), (char*) str);
790
static const string make_bookmark_name(const string &plugin, const char *name)
792
string varname(plugin);
793
varname.push_back('_');
794
varname.append(name);
796
for (string::iterator p= varname.begin() + 1; p != varname.end(); ++p)
807
called by register_var, construct_options and test_plugin_options.
808
Returns the 'bookmark' for the named variable.
809
LOCK_system_variables_hash should be at least read locked
811
static Bookmark *find_bookmark(const string &plugin, const char *name, int flags)
813
if (!(flags & PLUGIN_VAR_SessionLOCAL))
816
const string varname(make_bookmark_name(plugin, name));
818
bookmark_unordered_map::iterator iter= bookmark_hash.find(varname);
819
if (iter != bookmark_hash.end())
821
return &((*iter).second);
828
returns a bookmark for session-local variables, creating if neccessary.
829
returns null for non session-local variables.
830
Requires that a write lock is obtained on LOCK_system_variables_hash
832
static Bookmark *register_var(const string &plugin, const char *name,
835
if (!(flags & PLUGIN_VAR_SessionLOCAL))
838
uint32_t size= 0, offset, new_size;
839
Bookmark *result= NULL;
841
switch (flags & PLUGIN_VAR_TYPEMASK) {
842
case PLUGIN_VAR_BOOL:
843
size= ALIGN_SIZE(sizeof(bool));
846
size= ALIGN_SIZE(sizeof(int));
848
case PLUGIN_VAR_LONG:
849
size= ALIGN_SIZE(sizeof(long));
851
case PLUGIN_VAR_LONGLONG:
852
size= ALIGN_SIZE(sizeof(uint64_t));
855
size= ALIGN_SIZE(sizeof(char*));
863
if (!(result= find_bookmark(plugin, name, flags)))
865
const string varname(make_bookmark_name(plugin, name));
867
Bookmark new_bookmark;
868
new_bookmark.key= varname;
869
new_bookmark.offset= -1;
871
assert(size && !(size & (size-1))); /* must be power of 2 */
873
offset= global_system_variables.dynamic_variables_size;
874
offset= (offset + size - 1) & ~(size - 1);
875
new_bookmark.offset= (int) offset;
877
new_size= (offset + size + 63) & ~63;
879
if (new_size > global_variables_dynamic_size)
883
(char *)realloc(global_system_variables.dynamic_variables_ptr,
886
global_system_variables.dynamic_variables_ptr= tmpptr;
889
(char *)realloc(max_system_variables.dynamic_variables_ptr,
892
max_system_variables.dynamic_variables_ptr= tmpptr;
895
Clear the new variable value space. This is required for string
896
variables. If their value is non-NULL, it must point to a valid
899
memset(global_system_variables.dynamic_variables_ptr +
900
global_variables_dynamic_size, 0,
901
new_size - global_variables_dynamic_size);
902
memset(max_system_variables.dynamic_variables_ptr +
903
global_variables_dynamic_size, 0,
904
new_size - global_variables_dynamic_size);
905
global_variables_dynamic_size= new_size;
908
global_system_variables.dynamic_variables_head= offset;
909
max_system_variables.dynamic_variables_head= offset;
910
global_system_variables.dynamic_variables_size= offset + size;
911
max_system_variables.dynamic_variables_size= offset + size;
912
global_system_variables.dynamic_variables_version++;
913
max_system_variables.dynamic_variables_version++;
915
new_bookmark.version= global_system_variables.dynamic_variables_version;
916
new_bookmark.type_code= flags;
918
/* this should succeed because we have already checked if a dup exists */
919
bookmark_hash.insert(make_pair(varname, new_bookmark));
920
result= find_bookmark(plugin, name, flags);
927
returns a pointer to the memory which holds the session-local variable or
928
a pointer to the global variable if session==null.
929
If required, will sync with global variables if the requested variable
930
has not yet been allocated in the current thread.
932
static unsigned char *intern_sys_var_ptr(Session* session, int offset, bool global_lock)
935
assert((uint32_t)offset <= global_system_variables.dynamic_variables_head);
938
return (unsigned char*) global_system_variables.dynamic_variables_ptr + offset;
941
dynamic_variables_head points to the largest valid offset
943
if (!session->variables.dynamic_variables_ptr ||
944
(uint32_t)offset > session->variables.dynamic_variables_head)
947
if (!(tmpptr= (char *)realloc(session->variables.dynamic_variables_ptr,
948
global_variables_dynamic_size)))
950
session->variables.dynamic_variables_ptr= tmpptr;
953
LOCK_global_system_variables.lock();
955
//safe_mutex_assert_owner(&LOCK_global_system_variables);
957
memcpy(session->variables.dynamic_variables_ptr +
958
session->variables.dynamic_variables_size,
959
global_system_variables.dynamic_variables_ptr +
960
session->variables.dynamic_variables_size,
961
global_system_variables.dynamic_variables_size -
962
session->variables.dynamic_variables_size);
965
now we need to iterate through any newly copied 'defaults'
966
and if it is a string type with MEMALLOC flag, we need to strdup
968
bookmark_unordered_map::iterator iter= bookmark_hash.begin();
969
for (; iter != bookmark_hash.end() ; ++iter)
971
sys_var_pluginvar *pi;
973
const Bookmark &v= (*iter).second;
974
const string var_name((*iter).first);
976
if (v.version <= session->variables.dynamic_variables_version ||
977
!(var= intern_find_sys_var(var_name.c_str(), var_name.size(), true)) ||
978
!(pi= var->cast_pluginvar()) ||
979
v.type_code != (pi->plugin_var->flags & PLUGIN_VAR_TYPEMASK))
982
/* Here we do anything special that may be required of the data types */
984
if ((pi->plugin_var->flags & PLUGIN_VAR_TYPEMASK) == PLUGIN_VAR_STR &&
985
pi->plugin_var->flags & PLUGIN_VAR_MEMALLOC)
987
char **pp= (char**) (session->variables.dynamic_variables_ptr +
988
*(int*)(pi->plugin_var + 1));
989
if ((*pp= *(char**) (global_system_variables.dynamic_variables_ptr +
990
*(int*)(pi->plugin_var + 1))))
998
LOCK_global_system_variables.unlock();
1000
session->variables.dynamic_variables_version=
1001
global_system_variables.dynamic_variables_version;
1002
session->variables.dynamic_variables_head=
1003
global_system_variables.dynamic_variables_head;
1004
session->variables.dynamic_variables_size=
1005
global_system_variables.dynamic_variables_size;
1007
return (unsigned char*)session->variables.dynamic_variables_ptr + offset;
1010
static bool *mysql_sys_var_ptr_bool(Session* a_session, int offset)
1012
return (bool *)intern_sys_var_ptr(a_session, offset, true);
1015
static int *mysql_sys_var_ptr_int(Session* a_session, int offset)
1017
return (int *)intern_sys_var_ptr(a_session, offset, true);
1020
static long *mysql_sys_var_ptr_long(Session* a_session, int offset)
1022
return (long *)intern_sys_var_ptr(a_session, offset, true);
1025
static int64_t *mysql_sys_var_ptr_int64_t(Session* a_session, int offset)
1027
return (int64_t *)intern_sys_var_ptr(a_session, offset, true);
1030
static char **mysql_sys_var_ptr_str(Session* a_session, int offset)
1032
return (char **)intern_sys_var_ptr(a_session, offset, true);
509
1035
void plugin_sessionvar_init(Session *session)
511
1037
session->variables.storage_engine= NULL;
512
cleanup_variables(&session->variables);
1038
cleanup_variables(session, &session->variables);
514
1040
session->variables= global_system_variables;
515
1041
session->variables.storage_engine= NULL;
552
1104
void plugin_sessionvar_cleanup(Session *session)
554
1106
unlock_variables(session, &session->variables);
555
cleanup_variables(&session->variables);
1107
cleanup_variables(session, &session->variables);
1112
@brief Free values of thread variables of a plugin.
1114
This must be called before a plugin is deleted. Otherwise its
1115
variables are no longer accessible and the value space is lost. Note
1116
that only string values with PLUGIN_VAR_MEMALLOC are allocated and
1119
@param[in] vars Chain of system variables of a plugin
1122
static void plugin_vars_free_values(sys_var *vars)
1125
for (sys_var *var= vars; var; var= var->getNext())
1127
sys_var_pluginvar *piv= var->cast_pluginvar();
1129
((piv->plugin_var->flags & PLUGIN_VAR_TYPEMASK) == PLUGIN_VAR_STR) &&
1130
(piv->plugin_var->flags & PLUGIN_VAR_MEMALLOC))
1132
/* Free the string from global_system_variables. */
1133
char **valptr= (char**) piv->real_value_ptr(NULL, OPT_GLOBAL);
1142
bool sys_var_pluginvar::check_update_type(Item_result type)
1146
switch (plugin_var->flags & PLUGIN_VAR_TYPEMASK) {
1147
case PLUGIN_VAR_INT:
1148
case PLUGIN_VAR_LONG:
1149
case PLUGIN_VAR_LONGLONG:
1150
return type != INT_RESULT;
1151
case PLUGIN_VAR_STR:
1152
return type != STRING_RESULT;
1159
SHOW_TYPE sys_var_pluginvar::show_type()
1161
switch (plugin_var->flags & PLUGIN_VAR_TYPEMASK) {
1162
case PLUGIN_VAR_BOOL:
1163
return SHOW_MY_BOOL;
1164
case PLUGIN_VAR_INT:
1166
case PLUGIN_VAR_LONG:
1168
case PLUGIN_VAR_LONGLONG:
1169
return SHOW_LONGLONG;
1170
case PLUGIN_VAR_STR:
1171
return SHOW_CHAR_PTR;
1179
unsigned char* sys_var_pluginvar::real_value_ptr(Session *session, sql_var_t type)
1181
assert(session || (type == OPT_GLOBAL));
1182
if (plugin_var->flags & PLUGIN_VAR_SessionLOCAL)
1184
if (type == OPT_GLOBAL)
1187
return intern_sys_var_ptr(session, *(int*) (plugin_var+1), false);
1189
return *(unsigned char**) (plugin_var+1);
1193
TYPELIB* sys_var_pluginvar::plugin_var_typelib(void)
1195
switch (plugin_var->flags & (PLUGIN_VAR_TYPEMASK | PLUGIN_VAR_SessionLOCAL)) {
1196
case PLUGIN_VAR_SessionLOCAL:
1197
return ((sessionvar_enum_t *)plugin_var)->typelib;
1205
unsigned char* sys_var_pluginvar::value_ptr(Session *session, sql_var_t type, const LEX_STRING *)
1207
unsigned char* result;
1209
result= real_value_ptr(session, type);
1215
bool sys_var_pluginvar::check(Session *session, set_var *var)
1217
st_item_value_holder value;
1218
assert(is_readonly() || plugin_var->check);
1220
value.value_type= item_value_type;
1221
value.val_str= item_val_str;
1222
value.val_int= item_val_int;
1223
value.val_real= item_val_real;
1224
value.item= var->value;
1226
return is_readonly() ||
1227
plugin_var->check(session, plugin_var, &var->save_result, &value);
1231
void sys_var_pluginvar::set_default(Session *session, sql_var_t type)
1236
assert(is_readonly() || plugin_var->update);
1241
LOCK_global_system_variables.lock();
1242
tgt= real_value_ptr(session, type);
1243
src= ((void **) (plugin_var + 1) + 1);
1245
if (plugin_var->flags & PLUGIN_VAR_SessionLOCAL)
1247
if (type != OPT_GLOBAL)
1248
src= real_value_ptr(session, OPT_GLOBAL);
1250
switch (plugin_var->flags & PLUGIN_VAR_TYPEMASK) {
1251
case PLUGIN_VAR_INT:
1252
src= &((sessionvar_uint_t*) plugin_var)->def_val;
1254
case PLUGIN_VAR_LONG:
1255
src= &((sessionvar_ulong_t*) plugin_var)->def_val;
1257
case PLUGIN_VAR_LONGLONG:
1258
src= &((sessionvar_uint64_t_t*) plugin_var)->def_val;
1260
case PLUGIN_VAR_BOOL:
1261
src= &((sessionvar_bool_t*) plugin_var)->def_val;
1263
case PLUGIN_VAR_STR:
1264
src= &((sessionvar_str_t*) plugin_var)->def_val;
1271
/* session must equal current_session if PLUGIN_VAR_SessionLOCAL flag is set */
1272
assert(!(plugin_var->flags & PLUGIN_VAR_SessionLOCAL) ||
1273
session == current_session);
1275
if (!(plugin_var->flags & PLUGIN_VAR_SessionLOCAL) || type == OPT_GLOBAL)
1277
plugin_var->update(session, plugin_var, tgt, src);
1278
LOCK_global_system_variables.unlock();
1282
LOCK_global_system_variables.unlock();
1283
plugin_var->update(session, plugin_var, tgt, src);
1288
bool sys_var_pluginvar::update(Session *session, set_var *var)
1292
assert(is_readonly() || plugin_var->update);
1294
/* session must equal current_session if PLUGIN_VAR_SessionLOCAL flag is set */
1295
assert(!(plugin_var->flags & PLUGIN_VAR_SessionLOCAL) ||
1296
session == current_session);
1301
LOCK_global_system_variables.lock();
1302
tgt= real_value_ptr(session, var->type);
1304
if (!(plugin_var->flags & PLUGIN_VAR_SessionLOCAL) || var->type == OPT_GLOBAL)
1306
/* variable we are updating has global scope, so we unlock after updating */
1307
plugin_var->update(session, plugin_var, tgt, &var->save_result);
1308
LOCK_global_system_variables.unlock();
1312
LOCK_global_system_variables.unlock();
1313
plugin_var->update(session, plugin_var, tgt, &var->save_result);
1319
#define OPTION_SET_LIMITS(type, options, opt) \
1320
options->var_type= type; \
1321
options->def_value= (opt)->def_val; \
1322
options->min_value= (opt)->min_val; \
1323
options->max_value= (opt)->max_val; \
1324
options->block_size= (long) (opt)->blk_sz
1327
void plugin_opt_set_limits(struct option *options,
1328
const drizzle_sys_var *opt)
1330
options->sub_size= 0;
1332
switch (opt->flags & (PLUGIN_VAR_TYPEMASK |
1333
PLUGIN_VAR_UNSIGNED | PLUGIN_VAR_SessionLOCAL)) {
1334
/* global system variables */
1335
case PLUGIN_VAR_INT:
1336
OPTION_SET_LIMITS(GET_INT, options, (sysvar_int_t*) opt);
1338
case PLUGIN_VAR_INT | PLUGIN_VAR_UNSIGNED:
1339
OPTION_SET_LIMITS(GET_UINT, options, (sysvar_uint_t*) opt);
1341
case PLUGIN_VAR_LONG:
1342
OPTION_SET_LIMITS(GET_LONG, options, (sysvar_long_t*) opt);
1344
case PLUGIN_VAR_LONG | PLUGIN_VAR_UNSIGNED:
1345
OPTION_SET_LIMITS(GET_ULONG_IS_FAIL, options, (sysvar_ulong_t*) opt);
1347
case PLUGIN_VAR_LONGLONG:
1348
OPTION_SET_LIMITS(GET_LL, options, (sysvar_int64_t_t*) opt);
1350
case PLUGIN_VAR_LONGLONG | PLUGIN_VAR_UNSIGNED:
1351
OPTION_SET_LIMITS(GET_ULL, options, (sysvar_uint64_t_t*) opt);
1353
case PLUGIN_VAR_BOOL:
1354
options->var_type= GET_BOOL;
1355
options->def_value= ((sysvar_bool_t*) opt)->def_val;
1357
case PLUGIN_VAR_STR:
1358
options->var_type= ((opt->flags & PLUGIN_VAR_MEMALLOC) ?
1359
GET_STR_ALLOC : GET_STR);
1360
options->def_value= (intptr_t) ((sysvar_str_t*) opt)->def_val;
1362
/* threadlocal variables */
1363
case PLUGIN_VAR_INT | PLUGIN_VAR_SessionLOCAL:
1364
OPTION_SET_LIMITS(GET_INT, options, (sessionvar_int_t*) opt);
1366
case PLUGIN_VAR_INT | PLUGIN_VAR_UNSIGNED | PLUGIN_VAR_SessionLOCAL:
1367
OPTION_SET_LIMITS(GET_UINT, options, (sessionvar_uint_t*) opt);
1369
case PLUGIN_VAR_LONG | PLUGIN_VAR_SessionLOCAL:
1370
OPTION_SET_LIMITS(GET_LONG, options, (sessionvar_long_t*) opt);
1372
case PLUGIN_VAR_LONG | PLUGIN_VAR_UNSIGNED | PLUGIN_VAR_SessionLOCAL:
1373
OPTION_SET_LIMITS(GET_ULONG_IS_FAIL, options, (sessionvar_ulong_t*) opt);
1375
case PLUGIN_VAR_LONGLONG | PLUGIN_VAR_SessionLOCAL:
1376
OPTION_SET_LIMITS(GET_LL, options, (sessionvar_int64_t_t*) opt);
1378
case PLUGIN_VAR_LONGLONG | PLUGIN_VAR_UNSIGNED | PLUGIN_VAR_SessionLOCAL:
1379
OPTION_SET_LIMITS(GET_ULL, options, (sessionvar_uint64_t_t*) opt);
1381
case PLUGIN_VAR_BOOL | PLUGIN_VAR_SessionLOCAL:
1382
options->var_type= GET_BOOL;
1383
options->def_value= ((sessionvar_bool_t*) opt)->def_val;
1385
case PLUGIN_VAR_STR | PLUGIN_VAR_SessionLOCAL:
1386
options->var_type= ((opt->flags & PLUGIN_VAR_MEMALLOC) ?
1387
GET_STR_ALLOC : GET_STR);
1388
options->def_value= (intptr_t) ((sessionvar_str_t*) opt)->def_val;
1393
options->arg_type= REQUIRED_ARG;
1394
if (opt->flags & PLUGIN_VAR_NOCMDARG)
1395
options->arg_type= NO_ARG;
1396
if (opt->flags & PLUGIN_VAR_OPCMDARG)
1397
options->arg_type= OPT_ARG;
1400
static int get_one_plugin_option(int, const struct option *, char *)
1406
static int construct_options(memory::Root *mem_root, module::Module *tmp,
1410
int localoptionid= 256;
1411
const string plugin_name(tmp->getManifest().name);
1413
size_t namelen= plugin_name.size(), optnamelen;
1416
int index= 0, offset= 0;
1417
drizzle_sys_var *opt, **plugin_option;
1420
string name(plugin_name);
1421
transform(name.begin(), name.end(), name.begin(), ::tolower);
1423
for (string::iterator iter= name.begin(); iter != name.end(); ++iter)
1430
Two passes as the 2nd pass will take pointer addresses for use
1431
by my_getopt and register_var() in the first pass uses realloc
1434
for (plugin_option= tmp->getManifest().system_vars;
1435
plugin_option && *plugin_option; plugin_option++, index++)
1437
opt= *plugin_option;
1438
if (!(opt->flags & PLUGIN_VAR_SessionLOCAL))
1440
if (!(register_var(name, opt->name, opt->flags)))
1442
switch (opt->flags & PLUGIN_VAR_TYPEMASK) {
1443
case PLUGIN_VAR_BOOL:
1444
(((sessionvar_bool_t *)opt)->resolve)= mysql_sys_var_ptr_bool;
1446
case PLUGIN_VAR_INT:
1447
(((sessionvar_int_t *)opt)->resolve)= mysql_sys_var_ptr_int;
1449
case PLUGIN_VAR_LONG:
1450
(((sessionvar_long_t *)opt)->resolve)= mysql_sys_var_ptr_long;
1452
case PLUGIN_VAR_LONGLONG:
1453
(((sessionvar_int64_t_t *)opt)->resolve)= mysql_sys_var_ptr_int64_t;
1455
case PLUGIN_VAR_STR:
1456
(((sessionvar_str_t *)opt)->resolve)= mysql_sys_var_ptr_str;
1459
errmsg_printf(ERRMSG_LVL_ERROR, _("Unknown variable type code 0x%x in plugin '%s'."),
1460
opt->flags, plugin_name.c_str());
1465
for (plugin_option= tmp->getManifest().system_vars;
1466
plugin_option && *plugin_option; plugin_option++, index++)
1468
switch ((opt= *plugin_option)->flags & PLUGIN_VAR_TYPEMASK) {
1469
case PLUGIN_VAR_BOOL:
1471
opt->check= check_func_bool;
1473
opt->update= update_func_bool;
1475
case PLUGIN_VAR_INT:
1477
opt->check= check_func_int;
1479
opt->update= update_func_int;
1481
case PLUGIN_VAR_LONG:
1483
opt->check= check_func_long;
1485
opt->update= update_func_long;
1487
case PLUGIN_VAR_LONGLONG:
1489
opt->check= check_func_int64_t;
1491
opt->update= update_func_int64_t;
1493
case PLUGIN_VAR_STR:
1495
opt->check= check_func_str;
1498
opt->update= update_func_str;
1499
if ((opt->flags & (PLUGIN_VAR_MEMALLOC | PLUGIN_VAR_READONLY)) == false)
1501
opt->flags|= PLUGIN_VAR_READONLY;
1502
errmsg_printf(ERRMSG_LVL_WARN, _("Server variable %s of plugin %s was forced "
1503
"to be read-only: string variable without "
1504
"update_func and PLUGIN_VAR_MEMALLOC flag"),
1505
opt->name, plugin_name.c_str());
1510
errmsg_printf(ERRMSG_LVL_ERROR, _("Unknown variable type code 0x%x in plugin '%s'."),
1511
opt->flags, plugin_name.c_str());
1515
if ((opt->flags & (PLUGIN_VAR_NOCMDOPT | PLUGIN_VAR_SessionLOCAL))
1516
== PLUGIN_VAR_NOCMDOPT)
1521
errmsg_printf(ERRMSG_LVL_ERROR, _("Missing variable name in plugin '%s'."),
1522
plugin_name.c_str());
1526
if (!(opt->flags & PLUGIN_VAR_SessionLOCAL))
1528
optnamelen= strlen(opt->name);
1529
optname= (char*) mem_root->alloc_root(namelen + optnamelen + 2);
1530
sprintf(optname, "%s-%s", name.c_str(), opt->name);
1531
optnamelen= namelen + optnamelen + 1;
1535
/* this should not fail because register_var should create entry */
1536
if (!(v= find_bookmark(name, opt->name, opt->flags)))
1538
errmsg_printf(ERRMSG_LVL_ERROR, _("Thread local variable '%s' not allocated "
1539
"in plugin '%s'."), opt->name, plugin_name.c_str());
1543
*(int*)(opt + 1)= offset= v->offset;
1545
if (opt->flags & PLUGIN_VAR_NOCMDOPT)
1548
optname= (char*) mem_root->memdup_root(v->key.c_str(), (optnamelen= v->key.size()) + 1);
1551
/* convert '_' to '-' */
1552
for (p= optname; *p; p++)
1556
options->name= optname;
1557
options->comment= opt->comment;
1558
options->app_type= opt;
1559
options->id= localoptionid++;
1561
plugin_opt_set_limits(options, opt);
1563
if (opt->flags & PLUGIN_VAR_SessionLOCAL)
1564
options->value= options->u_max_value= (char**)
1565
(global_system_variables.dynamic_variables_ptr + offset);
1567
options->value= options->u_max_value= *(char***) (opt + 1);
1576
static option *construct_help_options(memory::Root *mem_root, module::Module *p)
1578
drizzle_sys_var **opt;
1580
uint32_t count= EXTRA_OPTIONS;
1582
for (opt= p->getManifest().system_vars; opt && *opt; opt++, count++) {};
1584
opts= (option*)mem_root->alloc_root((sizeof(option) * count));
1588
memset(opts, 0, sizeof(option) * count);
1590
if (construct_options(mem_root, p, opts))
1596
void drizzle_add_plugin_sysvar(sys_var_pluginvar *var)
1598
plugin_sysvar_vec.push_back(var);
1601
void drizzle_del_plugin_sysvar()
1603
vector<sys_var_pluginvar *>::iterator iter= plugin_sysvar_vec.begin();
1604
while(iter != plugin_sysvar_vec.end())
1609
plugin_sysvar_vec.clear();
562
1614
test_plugin_options()
563
1615
tmp_root temporary scratch space
564
1616
plugin internal plugin structure
1617
argc user supplied arguments
1618
argv user supplied arguments
565
1619
default_enabled default plugin enable status
567
1621
0 SUCCESS - plugin should be enabled/loaded
569
1623
Requires that a write-lock is held on LOCK_system_variables_hash
571
static int test_plugin_options(memory::Root *,
1625
static int test_plugin_options(memory::Root *module_root,
572
1626
module::Module *test_module,
1627
int *argc, char **argv,
573
1628
po::options_description &long_options)
1630
struct sys_var_chain chain= { NULL, NULL };
1631
drizzle_sys_var **opt;
1636
uint32_t len, count= EXTRA_OPTIONS;
576
1638
if (test_module->getManifest().init_options != NULL)